On Saturday 17 March 2018 01:24 PM, Keerthy wrote: > Kernel stores information to the RTC_SCRATCH0 and RTC_SCRATCH1 registers > for wakeup from RTC-only mode with DDR in self-refresh. Parse these > registers during SPL boot and jump to the kernel resume vector if the > device is waking up from RTC-only modewith DDR in Self-refresh. >
Missed adding Tero's Authorship on this one. I will send v4 of this patch alone with Author corrected. > The RTC scratch register layout used is: > > SCRATCH0 : bits00-31 : kernel resume address > SCRATCH1 : bits00-15 : RTC magic value used to detect valid config > SCRATCH1 : bits16-31 : board type information populated by bootloader > > During the normal boot path the SCRATCH1 : bits16-31 are updated with > the eeprom read board type data. In the rtc_only boot path the rtc > scratchpad register is read and the board type is determined and > correspondingly ddr dpll parameters are set. This is done so as to avoid > costly i2c read to eeprom. > > RTC-only +DRR in self-refresh mode support is currently only enabled for > am43xx_evm_rtconly_config. > This is not to be used with epos evm builds. > > Signed-off-by: Tero Kristo <t-kri...@ti.com> > [j-keer...@ti.com Rebased to latest u-boot master branch] > Signed-off-by: Keerthy <j-keer...@ti.com> > --- > > Changes in v3: > > * Replaced all RTC Only references with RTC Only plus DDR. > > Changes in v2: > > * Added more description to CONFIG Option. > * Renamed CONFIG_SPL_RTC_ONLY_SUPPORT to CONFIG_SPL_RTC_DDR_SUPPORT > * Added the probable kernel file where RTC Magic value will need to be > matched. > > arch/arm/include/asm/arch-am33xx/clock.h | 6 ++ > arch/arm/mach-omap2/am33xx/Kconfig | 14 ++++ > arch/arm/mach-omap2/am33xx/board.c | 110 > +++++++++++++++++++++++++++--- > arch/arm/mach-omap2/am33xx/clock.c | 10 +++ > arch/arm/mach-omap2/am33xx/clock_am43xx.c | 21 ++++++ > board/ti/am43xx/MAINTAINERS | 1 + > board/ti/am43xx/board.c | 56 +++++++++++++++ > configs/am43xx_evm_rtconly_defconfig | 59 ++++++++++++++++ > 8 files changed, 269 insertions(+), 8 deletions(-) > create mode 100644 configs/am43xx_evm_rtconly_defconfig > > diff --git a/arch/arm/include/asm/arch-am33xx/clock.h > b/arch/arm/include/asm/arch-am33xx/clock.h > index 9dbcd3a..eeebf16 100644 > --- a/arch/arm/include/asm/arch-am33xx/clock.h > +++ b/arch/arm/include/asm/arch-am33xx/clock.h > @@ -122,6 +122,12 @@ void scale_vcores(void); > void do_setup_dpll(const struct dpll_regs *, const struct dpll_params *); > void prcm_init(void); > void enable_basic_clocks(void); > + > +void rtc_only_update_board_type(u32 btype); > +u32 rtc_only_get_board_type(void); > +void rtc_only_prcm_init(void); > +void rtc_only_enable_basic_clocks(void); > + > void do_enable_clocks(u32 *const *, u32 *const *, u8); > void do_disable_clocks(u32 *const *, u32 *const *, u8); > > diff --git a/arch/arm/mach-omap2/am33xx/Kconfig > b/arch/arm/mach-omap2/am33xx/Kconfig > index 9a9ccd7..76da6d9 100644 > --- a/arch/arm/mach-omap2/am33xx/Kconfig > +++ b/arch/arm/mach-omap2/am33xx/Kconfig > @@ -239,6 +239,20 @@ config TARGET_CM_T43 > > endchoice > > +config SPL_RTC_DDR_SUPPORT > + bool > + depends on SPL > + prompt "Enable RTC-DDR ONLY Support" > + help > + If you want RTC-DDR ONLY Support, say Y. RTC Only with DDR in > + self-refresh mode is a special power saving mode where in all > + the other voltages are turned off apart from the RTC domain and DDR. > + So only RTC is alive and ticking and one can program it to wake > + up after a predetermined period. Once RTC alarm fires, the PMIC > + powers up all the voltage domains. U-Boot takes a special path > + as the DDR has contents is in self-refresh and restore path is > + followed. > + > endif > > if AM43XX || AM33XX > diff --git a/arch/arm/mach-omap2/am33xx/board.c > b/arch/arm/mach-omap2/am33xx/board.c > index ea0caba..ef1de1a 100644 > --- a/arch/arm/mach-omap2/am33xx/board.c > +++ b/arch/arm/mach-omap2/am33xx/board.c > @@ -147,6 +147,16 @@ int cpu_mmc_init(bd_t *bis) > } > #endif > > +/* > + * RTC only with DDR in self-refresh mode magic value, checked against during > + * boot to see if we have a valid config. This should be in sync with the > value > + * that will be in drivers/soc/ti/pm33xx.c. > + */ > +#define RTC_MAGIC_VAL 0x8cd0 > + > +/* Board type field bit shift for RTC only with DDR in self-refresh mode */ > +#define RTC_BOARD_TYPE_SHIFT 16 > + > /* AM33XX has two MUSB controllers which can be host or gadget */ > #if (defined(CONFIG_USB_MUSB_GADGET) || defined(CONFIG_USB_MUSB_HOST)) && \ > (defined(CONFIG_AM335X_USB0) || defined(CONFIG_AM335X_USB1)) && \ > @@ -252,6 +262,48 @@ int arch_misc_init(void) > #endif /* CONFIG_USB_MUSB_* && CONFIG_AM335X_USB* && !CONFIG_DM_USB */ > > #ifndef CONFIG_SKIP_LOWLEVEL_INIT > + > +#if defined(CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC) || \ > + (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_RTC_DDR_SUPPORT)) > +static void rtc32k_unlock(struct davinci_rtc *rtc) > +{ > + /* > + * Unlock the RTC's registers. For more details please see the > + * RTC_SS section of the TRM. In order to unlock we need to > + * write these specific values (keys) in this order. > + */ > + writel(RTC_KICK0R_WE, &rtc->kick0r); > + writel(RTC_KICK1R_WE, &rtc->kick1r); > +} > +#endif > + > +#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_RTC_DDR_SUPPORT) > +/* > + * Write contents of the RTC_SCRATCH1 register based on board type > + * Two things are passed > + * on. First 16 bits (0:15) are written with RTC_MAGIC value. Once the > + * control gets to kernel, kernel reads the scratchpad register and gets to > + * know that bootloader has rtc_only support. > + * > + * Second important thing is the board type (16:31). This is needed in the > + * rtc_only boot where in we want to avoid costly i2c reads to eeprom to > + * identify the board type and we go ahead and copy the board strings to > + * am43xx_board_name. > + */ > +void update_rtc_magic(void) > +{ > + struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE; > + u32 magic = RTC_MAGIC_VAL; > + > + magic |= (rtc_only_get_board_type() << RTC_BOARD_TYPE_SHIFT); > + > + rtc32k_unlock(rtc); > + > + /* write magic */ > + writel(magic, &rtc->scratch1); > +} > +#endif > + > /* > * In the case of non-SPL based booting we'll want to call these > * functions a tiny bit later as it will require gd to be set and cleared > @@ -261,7 +313,9 @@ int board_early_init_f(void) > { > prcm_init(); > set_mux_conf_regs(); > - > +#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_RTC_DDR_SUPPORT) > + update_rtc_magic(); > +#endif > return 0; > } > > @@ -278,13 +332,7 @@ static void rtc32k_enable(void) > { > struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE; > > - /* > - * Unlock the RTC's registers. For more details please see the > - * RTC_SS section of the TRM. In order to unlock we need to > - * write these specific values (keys) in this order. > - */ > - writel(RTC_KICK0R_WE, &rtc->kick0r); > - writel(RTC_KICK1R_WE, &rtc->kick1r); > + rtc32k_unlock(rtc); > > /* Enable the RTC 32K OSC by setting bits 3 and 6. */ > writel((1 << 3) | (1 << 6), &rtc->osc); > @@ -321,8 +369,54 @@ static void watchdog_disable(void) > ; > } > > +#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_RTC_DDR_SUPPORT) > +/* > + * Check if we are executing rtc-only + DDR mode, and resume from it if > needed > + */ > +static void rtc_only(void) > +{ > + struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE; > + u32 scratch1; > + void (*resume_func)(void); > + > + scratch1 = readl(&rtc->scratch1); > + > + /* > + * Check RTC scratch against RTC_MAGIC_VAL, RTC_MAGIC_VAL is only > + * written to this register when we want to wake up from RTC only > + * with DDR in self-refresh mode. Contents of the RTC_SCRATCH1: > + * bits 0-15: RTC_MAGIC_VAL > + * bits 16-31: board type (needed for sdram_init) > + */ > + if ((scratch1 & 0xffff) != RTC_MAGIC_VAL) > + return; > + > + rtc32k_unlock(rtc); > + > + /* Clear RTC magic */ > + writel(0, &rtc->scratch1); > + > + /* > + * Update board type based on value stored on RTC_SCRATCH1, this > + * is done so that we don't need to read the board type from eeprom > + * over i2c bus which is expensive > + */ > + rtc_only_update_board_type(scratch1 >> RTC_BOARD_TYPE_SHIFT); > + > + rtc_only_prcm_init(); > + sdram_init(); > + > + resume_func = (void *)readl(&rtc->scratch0); > + if (resume_func) > + resume_func(); > +} > +#endif > + > void s_init(void) > { > +#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_RTC_DDR_SUPPORT) > + rtc_only(); > +#endif > } > > void early_system_init(void) > diff --git a/arch/arm/mach-omap2/am33xx/clock.c > b/arch/arm/mach-omap2/am33xx/clock.c > index 3d17698..ad28d20 100644 > --- a/arch/arm/mach-omap2/am33xx/clock.c > +++ b/arch/arm/mach-omap2/am33xx/clock.c > @@ -244,3 +244,13 @@ void prcm_init(void) > scale_vcores(); > setup_dplls(); > } > + > +void rtc_only_prcm_init(void) > +{ > + const struct dpll_params *params; > + > + rtc_only_enable_basic_clocks(); > + > + params = get_dpll_ddr_params(); > + do_setup_dpll(&dpll_ddr_regs, params); > +} > diff --git a/arch/arm/mach-omap2/am33xx/clock_am43xx.c > b/arch/arm/mach-omap2/am33xx/clock_am43xx.c > index 73ea955..117a63e 100644 > --- a/arch/arm/mach-omap2/am33xx/clock_am43xx.c > +++ b/arch/arm/mach-omap2/am33xx/clock_am43xx.c > @@ -124,6 +124,27 @@ void enable_basic_clocks(void) > writel(0x4, &cmdpll->clkselmacclk); > } > > +void rtc_only_enable_basic_clocks(void) > +{ > + u32 *const clk_domains[] = { > + &cmper->emifclkstctrl, > + 0 > + }; > + > + u32 *const clk_modules_explicit_en[] = { > + &cmper->gpio5clkctrl, > + &cmper->emiffwclkctrl, > + &cmper->emifclkctrl, > + &cmper->otfaemifclkctrl, > + 0 > + }; > + > + do_enable_clocks(clk_domains, clk_modules_explicit_en, 1); > + > + /* Select the Master osc clk as Timer2 clock source */ > + writel(0x1, &cmdpll->clktimer2clk); > +} > + > #ifdef CONFIG_TI_EDMA3 > void enable_edma3_clocks(void) > { > diff --git a/board/ti/am43xx/MAINTAINERS b/board/ti/am43xx/MAINTAINERS > index 83645ac..bf09806 100644 > --- a/board/ti/am43xx/MAINTAINERS > +++ b/board/ti/am43xx/MAINTAINERS > @@ -7,4 +7,5 @@ F: configs/am43xx_evm_defconfig > F: configs/am43xx_evm_ethboot_defconfig > F: configs/am43xx_evm_qspiboot_defconfig > F: configs/am43xx_evm_usbhost_boot_defconfig > +F: configs/am43xx_evm_rtconly_defconfig > F: configs/am43xx_hs_evm_defconfig > diff --git a/board/ti/am43xx/board.c b/board/ti/am43xx/board.c > index 715960a..d8944ea 100644 > --- a/board/ti/am43xx/board.c > +++ b/board/ti/am43xx/board.c > @@ -520,6 +520,62 @@ static void enable_vtt_regulator(void) > writel(temp, AM33XX_GPIO5_BASE + OMAP_GPIO_OE); > } > > +enum { > + RTC_BOARD_EPOS = 1, > + RTC_BOARD_EVM14, > + RTC_BOARD_EVM12, > + RTC_BOARD_GPEVM, > + RTC_BOARD_SK, > +}; > + > +/* > + * In the rtc_only+DRR in self-refresh boot path we have the board type info > + * in the rtc scratch pad register hence we bypass the costly i2c reads to > + * eeprom and directly programthe board name string > + */ > +void rtc_only_update_board_type(u32 btype) > +{ > + const char *name = ""; > + const char *rev = "1.0"; > + > + switch (btype) { > + case RTC_BOARD_EPOS: > + name = "AM43EPOS"; > + break; > + case RTC_BOARD_EVM14: > + name = "AM43__GP"; > + rev = "1.4"; > + break; > + case RTC_BOARD_EVM12: > + name = "AM43__GP"; > + rev = "1.2"; > + break; > + case RTC_BOARD_GPEVM: > + name = "AM43__GP"; > + break; > + case RTC_BOARD_SK: > + name = "AM43__SK"; > + break; > + } > + ti_i2c_eeprom_am_set(name, rev); > +} > + > +u32 rtc_only_get_board_type(void) > +{ > + if (board_is_eposevm()) > + return RTC_BOARD_EPOS; > + else if (board_is_evm_14_or_later()) > + return RTC_BOARD_EVM14; > + else if (board_is_evm_12_or_later()) > + return RTC_BOARD_EVM12; > + else if (board_is_gpevm()) > + return RTC_BOARD_GPEVM; > + else if (board_is_sk()) > + return RTC_BOARD_SK; > + > + return 0; > +} > + > void sdram_init(void) > { > /* > diff --git a/configs/am43xx_evm_rtconly_defconfig > b/configs/am43xx_evm_rtconly_defconfig > new file mode 100644 > index 0000000..ab0be10 > --- /dev/null > +++ b/configs/am43xx_evm_rtconly_defconfig > @@ -0,0 +1,59 @@ > +CONFIG_ARM=y > +CONFIG_ARCH_OMAP2PLUS=y > +CONFIG_TI_COMMON_CMD_OPTIONS=y > +CONFIG_SYS_MALLOC_F_LEN=0x2000 > +CONFIG_AM43XX=y > +CONFIG_DEFAULT_DEVICE_TREE="am437x-gp-evm" > +CONFIG_DISTRO_DEFAULTS=y > +CONFIG_SPL_LOAD_FIT=y > +CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=1" > +# CONFIG_USE_BOOTCOMMAND is not set > +CONFIG_SYS_CONSOLE_INFO_QUIET=y > +CONFIG_VERSION_VARIABLE=y > +CONFIG_SPL=y > +CONFIG_SPL_RTC_DDR_SUPPORT=y > +CONFIG_SPL_MTD_SUPPORT=y > +CONFIG_SPL_OS_BOOT=y > +CONFIG_CMD_SPL=y > +CONFIG_CMD_SPL_NAND_OFS=0x00100000 > +CONFIG_CMD_SPL_WRITE_SIZE=0x40000 > +# CONFIG_CMD_FLASH is not set > +CONFIG_CMD_NAND=y > +# CONFIG_CMD_SETEXPR is not set > +CONFIG_CMD_MTDPARTS=y > +CONFIG_MTDIDS_DEFAULT="nand0=nand.0" > +CONFIG_MTDPARTS_DEFAULT="mtdparts=nand.0:256k(NAND.SPL),256k(NAND.SPL.backup1),256k(NAND.SPL.backup2),256k(NAND.SPL.backup3),512k(NAND.u-boot-spl-os),1m(NAND.u-boot),256k(NAND.u-boot-env),256k(NAND.u-boot-env.backup1),7m(NAND.kernel),-(NAND.file-system)" > +CONFIG_OF_CONTROL=y > +CONFIG_OF_LIST="am437x-gp-evm am437x-sk-evm am43x-epos-evm am437x-idk-evm" > +CONFIG_DM=y > +# CONFIG_BLK is not set > +CONFIG_DFU_MMC=y > +CONFIG_DFU_RAM=y > +CONFIG_DFU_SF=y > +CONFIG_DM_GPIO=y > +CONFIG_DM_MMC=y > +CONFIG_MMC_OMAP_HS=y > +CONFIG_NAND=y > +CONFIG_SPI_FLASH=y > +CONFIG_SPI_FLASH_MACRONIX=y > +CONFIG_PHYLIB=y > +CONFIG_PHY_GIGE=y > +CONFIG_DM_SERIAL=y > +CONFIG_SYS_NS16550=y > +CONFIG_TI_QSPI=y > +CONFIG_TIMER=y > +CONFIG_OMAP_TIMER=y > +CONFIG_USB=y > +CONFIG_USB_XHCI_HCD=y > +CONFIG_USB_XHCI_DWC3=y > +CONFIG_USB_DWC3=y > +CONFIG_USB_DWC3_GADGET=y > +CONFIG_USB_DWC3_OMAP=y > +CONFIG_USB_DWC3_PHY_OMAP=y > +CONFIG_OMAP_USB_PHY=y > +CONFIG_USB_STORAGE=y > +CONFIG_USB_GADGET=y > +CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments" > +CONFIG_USB_GADGET_VENDOR_NUM=0x0403 > +CONFIG_USB_GADGET_PRODUCT_NUM=0xbd00 > +CONFIG_USB_GADGET_DOWNLOAD=y > _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot