Other Parts Discussed in Thread: TPS65217
Tool/software: Linux
We have custom board based on AM3351 and TPS65217 along with battery. Our requirement is the board should boot if the power button pressed down and hold it for more than 3 seconds, otherwise the PMIC will enter into sleep mode(To maintain RTC time) after shutdown the processor. If power button is not pressed for continuously 3 seconds, we are configuring the RTC alarm2 register to shutdown the processor after 1 second and then PMIC will enter into sleep mode. But we are facing below problem.
After configuring alarm2 register, the PMIC takes approximately 3 second to shutdown the processor instead of 1 second. I have attached the part of code where we putting PMIC into sleep mode in SPL. Below is the log.
U-Boot SPL 2015.07-g46c915c963 (Jan 21 2017 - 16:56:16)
RTC doesn't run. Restart RTC
RTC: Status reg: 0x02 ctrl reg: 0x01
Preparing pmic sleep mode
RTC Status reg: 0x02 ctrl reg: 0x01
Get RTC year: 17 mon/cent: 01 mday: 21 wday: 00 hr: 11 min: 45 sec: 18
Set Alarm at DATE: 2017-01-21 (wday=6) TIME: 11:45:19
Read back Alarm2 reg DATE: 0017-01-21 TIME: 11:45:19
PMIC will go to sleep in 1 second
RTC Status reg: 0x82 ctrl reg: 0x01
Get RTC year: 17 mon/cent: 01 mday: 21 wday: 00 hr: 11 min: 45 sec: 19
RTC Status reg: 0x02 ctrl reg: 0x01
Get RTC year: 17 mon/cent: 01 mday: 21 wday: 00 hr: 11 min: 45 sec: 19
RTC Status reg: 0x02 ctrl reg: 0x01
Get RTC year: 17 mon/cent: 01 mday: 21 wday: 00 hr: 11 min: 45 sec: 19
RTC Status reg: 0x02 ctrl reg: 0x01
Get RTC year: 17 mon/cent: 01 mday: 21 wday: 00 hr: 11 min: 45 sec: 19
RTC Status reg: 0x02 ctrl reg: 0x01
Get RTC year: 17 mon/cent: 01 mday: 21 wday: 00 hr: 11 min: 45 sec: 19
RTC Status reg: 0x02 ctrl reg: 0x01
Get RTC year: 17 mon/cent: 01 mday: 21 wday: 00 hr: 11 min: 45 sec: 19
RTC Status reg: 0x02 ctrl reg: 0x01
Get RTC year: 17 mon/cent: 01 mday: 21 wday: 00 hr: 11 min: 45 sec: 19
RTC Status reg: 0x02 ctrl reg: 0x01
Get RTC year: 17 mon/cent: 01 mday: 21 wday: 00 hr: 11 min: 45 sec: 19
RTC Status reg: 0x02 ctrl reg: 0x01
Get RTC year: 17 mon/cent: 01 mday: 21 wday: 00 hr: 11 min: 45 sec: 20
RTC Status reg: 0x02 ctrl reg: 0x01
Get RTC year: 17 mon/cent: 01 mday: 21 wday: 00 hr: 11 min: 45 sec: 20
RTC Status reg: 0x02 ctrl reg: 0x01
Get RTC year: 17 mon/cent: 01 mday: 21 wday: 00 hr: 11 min: 45 sec: 20
RTC Status reg: 0x02 ctrl reg: 0x01
Get RTC year: 17 mon/cent: 01 mday: 21 wday: 00 hr: 11 min: 45 sec: 20
RTC Status reg: 0x02 ctrl reg: 0x01
Get RTC year: 17 mon/cent: 01 mday: 21 wday: 00 hr: 11 min: 45 sec: 20
RTC Status reg: 0x02 ctrl reg: 0x01
Get RTC year: 17 mon/cent: 01 mday: 21 wday: 00 hr: 11 min: 45 sec: 20
RTC Status reg: 0x02 ctrl reg: 0x01
Get RTC year: 17 mon/cent: 01 mday: 21 wday: 00 hr: 11 min: 45 sec: 20
RTC Status reg: 0x02 ctrl reg: 0x01
Get RTC year: 17 mon/cent: 01 mday: 21 wday: 00 hr: 11 min: 45 sec: 20
RTC Status reg: 0x02 ctrl reg: 0x01
Get RTC year: 17 mon/cent: 01 mday: 21 wday: 00 hr: 11 min: 45 sec: 21
RTC Status reg: 0x02 ctrl reg: 0x01
Get RTC year: 17 mon/cent: 01 mday: 21 wday: 00 hr: 11 min: 45 sec: 21
RTC Status reg: 0x02 ctrl reg: 0x01
Get RTC year: 17 mon/cent: 01 mday: 21 wday: 00 hr: 11 min: 45 sec: 21
RTC Status reg: 0x02 ctrl reg: 0x01
Get RTC year: 17 mon/cent: 01 mday: 21 wday: 00 hr: 11 min: 45 sec: 21
RTC Status reg: 0x02 ctrl reg: 0x01
Get RTC year: 17 mon/cent: 01 mday: 21 wday: 00 hr: 11 min: 45 sec: 21
RTC Status reg: 0x02 ctrl reg: 0x01
Get RTC year: 17 mon/cent: 01 mday: 21 wday: 00 hr: 11 min: 45 sec: 21
RTC Status reg: 0x02 ctrl reg: 0x01
Get RTC year: 17 mon/cent: 01 mday: 21 wday: 00 hr: 11 min: 45 sec: 21
RTC Status reg: 0x02 ctrl reg: 0x01
Get RTC year: 17 mon/cent: 01 mday: 21 wday: 00 hr: 11 min: 45 sec: 21
RTC Status reg: 0x02 ctrl reg: 0x01
Get RTC year: 17 mon/cent: 01 mday: 21 wday: 00 hr: 11 min: 45 sec: 21
RTC Status reg: 0x02 ctrl reg: 0x01 (processor is powered off)
The above log is eMMC boot. But the same SPL binary if you boot it through UART, it is working properly (i.e) PMIC enter sleep after 1 second.
CCCCCCCCCCCCCCCCC
U-Boot SPL 2015.07-g46c915c963 (Jan 21 2017 - 16:56:16)
RTC doesn't run. Restart RTC
RTC: Status reg: 0x82 ctrl reg: 0x01
Preparing pmic sleep mode
RTC Status reg: 0x02 ctrl reg: 0x01
Get RTC year: 17 mon/cent: 01 mday: 21 wday: 00 hr: 11 min: 52 sec: 15
Set Alarm at DATE: 2017-01-21 (wday=6) TIME: 11:52:16
Read back Alarm2 reg DATE: 0017-01-21 TIME: 11:52:16
PMIC will go to sleep in 1 second(processor is powered off)
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; }