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

Reply via email to