Message ID | 1521192578-12504-2-git-send-email-j-keerthy@ti.com |
---|---|
State | Superseded |
Delegated to: | Tom Rini |
Headers | show |
Series | ARM: AM43xx: Add support for RTC only mode | expand |
Hi Keerthy, I think you should replace all the references in this patch for RTC only mode to RTC-only + DDR; that is more valid term of the mode implemented. For u-boot, pure rtc-only mode is a don't care, it is visible as just a normal boot-up with RTC being the boot source. In the case handled by this patch, the power mode of the SoC itself is RTC-only which is documented in TRM. DDR is programmed to self-refresh and held there with support of some external components (basically a pull on CKE line.) Dave, any thoughts on that? -Tero On 16/03/18 11:29, Keerthy wrote: > 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 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-kristo@ti.com> > [j-keerthy@ti.com Rebased to latest u-boot master branch] > Signed-off-by: Keerthy <j-keerthy@ti.com> > --- > > 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..b970a2b 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 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 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 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 > + * 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..3a6cc05 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 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 program > + * the 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 > -- Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
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..b970a2b 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 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 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 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 + * 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..3a6cc05 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 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 program + * the 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