void am33xx_spl_board_init(void) { int mpu_vdd; unsigned long status, reg; struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE; struct rtc_time tm; unsigned long time; char index=0; /* BeagleBone PMIC Code */ int usb_cur_lim; if (i2c_probe(TPS65217_CHIP_PM)) return; /* * AM3351 supports 300MHz. */ dpll_mpu_opp100.m = MPUPLL_M_300; /* * Increase USB current limit to 1300mA and set * the MPU(Same as VDD CORE in AM3351) voltage * controller as needed. */ /* Set UVLO to 2.89V */ if (tps65217_reg_write(TPS65217_PROT_LEVEL_1, TPS65217_DEFUVLO, TPS65217_DEFUVLO_2_89, TPS65217_DEFUVLO_MASK)) puts("tps65217_reg_write failure\n"); usb_cur_lim = TPS65217_USB_INPUT_CUR_LIMIT_1300MA; mpu_vdd = TPS65217_DCDC_VOLT_SEL_1125MV; if (tps65217_reg_write(TPS65217_PROT_LEVEL_NONE, TPS65217_POWER_PATH, usb_cur_lim, TPS65217_USB_INPUT_CUR_LIMIT_MASK)) puts("tps65217_reg_write failure\n"); /* Set DCDC3 (CORE) voltage to 1.125V */ if (tps65217_voltage_update(TPS65217_DEFDCDC3, TPS65217_DCDC_VOLT_SEL_1800MV)) { puts("tps65217_voltage_update failure\n"); return; } /* Set CORE Frequencies to OPP100 */ do_setup_dpll(&dpll_core_regs, &dpll_core_opp100); /* Set DCDC2 (MPU) voltage */ if (tps65217_voltage_update(TPS65217_DEFDCDC2, mpu_vdd)) { puts("tps65217_voltage_update failure\n"); return; } /* Set LDO2 to 2.75V */ if (tps65217_reg_write(TPS65217_PROT_LEVEL_2, TPS65217_DEFLDO2, TPS65217_LDO2_VOLTAGE_OUT_2_85, TPS65217_LDO2_MASK)) puts("tps65217_reg_write failure\n"); /* * Set LDO3 to 1.8V and LDO4 to 3.3V */ if (tps65217_reg_write(TPS65217_PROT_LEVEL_2, TPS65217_DEFLS1, TPS65217_LDO_VOLTAGE_OUT_1_8, TPS65217_LDO_MASK)) puts("tps65217_reg_write failure\n"); if (tps65217_reg_write(TPS65217_PROT_LEVEL_2, TPS65217_DEFLS2, TPS65217_LDO_VOLTAGE_OUT_2_85, TPS65217_LDO_MASK)) puts("tps65217_reg_write failure\n"); /* Set PMIC sleep during shutdown in Status Register */ tps65217_reg_write(TPS65217_PROT_LEVEL_NONE, TPS65217_STATUS, ~TPS65217_PWR_OFF, 0xFF); tps65217_reg_write(TPS65217_PROT_LEVEL_NONE, TPS65217_CHGCONFIG1, 0x30, 0xFF); /* charge voltage selection 4.25V */ tps65217_reg_write(TPS65217_PROT_LEVEL_NONE, TPS65217_CHGCONFIG2, 0xB0, 0xFF); /* Termination current factor 2.5 % */ tps65217_reg_write(TPS65217_PROT_LEVEL_NONE, TPS65217_CHGCONFIG3, 0x30, 0xFF); /* charger enabled */ tps65217_reg_write(TPS65217_PROT_LEVEL_NONE, TPS65217_CHGCONFIG1, 0x31, 0xFF); /* Set MPU Frequency to what we detected now that voltages are set */ do_setup_dpll(&dpll_mpu_regs, &dpll_mpu_opp100); /* Check RTC is running */ if ((status & RTC_STATE_RUN) != RTC_STATE_RUN) { puts("RTC doesn't run. Restart RTC \n"); /* run RTC counter */ writel(0x01, RTC_BASE + 0x40); mdelay(10); status = readl(&rtc->status); /* Check again RTC running or not */ if ((status & RTC_STATE_RUN) != RTC_STATE_RUN) puts("RTC doesn't run after restart \n"); printf("RTC: Status reg: 0x%02x ctrl reg: 0x%02x\r\n",readl(&rtc->status), readl(&rtc->ctrl)); } puts("Preparing pmic sleep mode \n"); /* Clear previous ALARM2 interuppt */ writel(0x80, RTC_BASE + 0x44); /* Read Current RTC time */ rtc_get_time(&tm); /* Convert Gregorian date to seconds since 01-01-1970 00:00:00 */ time = rtc_maketime(&tm); /* Convert seconds since 01-01-1970 00:00:00 to Gregorian date */ if((readl(AM33XX_GPIO0_BASE + 0x138) & 0x00001000)) rtc_to_time(time + 1, &tm); else rtc_to_time(time + 2 , &tm); writel(0x04400000, AM33XX_GPIO0_BASE + 0x13C); rtc_wait_not_busy(); /* Set alarm 2 event */ rtc_set_alarm(&tm); if(!(readl(AM33XX_GPIO0_BASE + 0x138) & 0x00001000)){ do{ mdelay(100); index ++; /* Check keys are pressed continuously for 3 seconds */ if(index == 10) break; }while(!(readl(AM33XX_GPIO0_BASE + 0x138) & 0x00001000)); } if(index != 10){ puts("PMIC will go to sleep in 1 second\r\n"); writel(0x00C00000, AM33XX_GPIO0_BASE + 0x13C); while(1){ mdelay(100); rtc_get_time(&tm); } /* Wait in loop until pmic goes to sleep */ while(1); } puts("Booting........\r\n"); writel(0, RTC_BASE + 0x48); writel(0xFB3FFFFF, AM33XX_GPIO0_BASE + 0x134); writel(0, AM33XX_GPIO0_BASE + 0x13C); } void rtc_wait_not_busy(void) { struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE; unsigned long status; char count; for (count = 0; count < 50; count++) { status = readl(&rtc->status); if (!(status & RTC_STATE_BUSY)) break; udelay(1); } } static int rtc_get_time(struct rtc_time *tmp) { struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE; unsigned long sec, min, hour, mday, wday, mon_cent, year; unsigned long status; printf("RTC Status reg: 0x%02x ctrl reg: 0x%02x\r\n",readl(&rtc->status), readl(&rtc->ctrl)); status = readl(&rtc->status); if ((status & RTC_STATE_RUN) != RTC_STATE_RUN) { puts("RTC doesn't run \n"); return -1; } if ((status & RTC_STATE_BUSY) == RTC_STATE_BUSY) udelay(20); writel(OMAP_RTC_STATUS_ALARM2, RTC_BASE + 0x44); udelay(35); sec = readl(&rtc->second); min = readl(&rtc->minutes); hour = readl(&rtc->hours); mday = readl(&rtc->day); wday = readl(&rtc->dotw); mon_cent = readl(&rtc->month); year = readl(&rtc->year); printf("Get RTC year: %02lx mon/cent: %02lx mday: %02lx wday: %02lx " "hr: %02lx min: %02lx sec: %02lx\n", year, mon_cent, mday, wday, hour, min, sec); tmp->tm_sec = bcd2bin(sec & 0x7F); tmp->tm_min = bcd2bin(min & 0x7F); tmp->tm_hour = bcd2bin(hour & 0x3F); tmp->tm_mday = bcd2bin(mday & 0x3F); tmp->tm_mon = bcd2bin(mon_cent & 0x1F); tmp->tm_year = bcd2bin(year) + 2000; tmp->tm_wday = bcd2bin(wday & 0x07); tmp->tm_yday = 0; tmp->tm_isdst = 0; return 0; } static int rtc_set_alarm(struct rtc_time *tmp) { unsigned long val; struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE; printf("Set Alarm at DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); writel(bin2bcd(tmp->tm_year % 100), RTC_BASE + 0x94); writel(bin2bcd(tmp->tm_mon), RTC_BASE + 0x90); writel(bin2bcd(tmp->tm_mday), RTC_BASE + 0x8C); writel(bin2bcd(tmp->tm_hour), RTC_BASE + 0x88); writel(bin2bcd(tmp->tm_min), RTC_BASE + 0x84); writel(bin2bcd(tmp->tm_sec), RTC_BASE + 0x80); val = readl(RTC_BASE + 0x48); writel((val | OMAP_RTC_INTERRUPTS_IT_ALARM2), RTC_BASE + 0x48); val = readl(RTC_BASE+OMAP_RTC_PMIC_REG); val = val | OMAP_RTC_PMIC_POWER_EN_EN | OMAP_RTC_PMIC_EXT_WAKEUP_EN | OMAP_RTC_PMIC_EXT_WAKEUP_POL; printf("Read back Alarm2 reg DATE: %04lx-%02lx-%02lx TIME: %2lx:%02lx:%02lx\n", readl(RTC_BASE + 0x94), readl(RTC_BASE + 0x90), readl(RTC_BASE + 0x8C), readl(RTC_BASE + 0x88), readl(RTC_BASE + 0x84), readl(RTC_BASE + 0x80)); writel(val, RTC_BASE+OMAP_RTC_PMIC_REG); return 0; }