Commit adb395df0de3176dad44ffe822e1d07da0f0542d

Authored by Tero Kristo
Committed by Lokesh Vutla
1 parent f89aaafdc0

ARM: AM43xx: Add support for RTC only mode

Kernel stores information to the RTC_SCRATCH0 and RTC_SCRATCH1 registers
for wakeup from RTC-only mode. Parse these registers during SPL boot and
jump to the kernel resume vector if the device is waking up from RTC-only
mode.

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 patch 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.

Tested-by: Dave Gerlach <d-gerlach@ti.com>
Signed-off-by: Tero Kristo <t-kristo@ti.com>
[j-keerthy@ti.com Ported to 2017.01 branch]
Signed-off-by: Keerthy <j-keerthy@ti.com>

Showing 8 changed files with 275 additions and 8 deletions Side-by-side Diff

arch/arm/include/asm/arch-am33xx/clock.h
... ... @@ -114,6 +114,12 @@
114 114 void do_setup_dpll(const struct dpll_regs *, const struct dpll_params *);
115 115 void prcm_init(void);
116 116 void enable_basic_clocks(void);
  117 +
  118 +void rtc_only_update_board_type(u32 btype);
  119 +u32 rtc_only_get_board_type(void);
  120 +void rtc_only_prcm_init(void);
  121 +void rtc_only_enable_basic_clocks(void);
  122 +
117 123 void do_enable_clocks(u32 *const *, u32 *const *, u8);
118 124 void do_disable_clocks(u32 *const *, u32 *const *, u8);
119 125  
arch/arm/mach-omap2/am33xx/Kconfig
... ... @@ -94,6 +94,13 @@
94 94 config SPL_I2C_SUPPORT
95 95 default y
96 96  
  97 +config SPL_RTC_ONLY_SUPPORT
  98 + bool
  99 + depends on SPL
  100 + prompt "Enable RTC ONLY Support"
  101 + help
  102 + If you want RTC ONLY Support, say Y.
  103 +
97 104 config TARGET_AM43XX_EVM
98 105 bool "Support am43xx_evm"
99 106 select TI_I2C_BOARD_DETECT
arch/arm/mach-omap2/am33xx/board.c
... ... @@ -118,6 +118,15 @@
118 118 }
119 119 #endif
120 120  
  121 +/*
  122 + * RTC only mode magic value, checked against during boot to see if we have
  123 + * a valid config
  124 + */
  125 +#define RTC_MAGIC_VAL 0x8cd0
  126 +
  127 +/* Board type field bit shift for RTC only mode */
  128 +#define RTC_BOARD_TYPE_SHIFT 16
  129 +
121 130 /* AM33XX has two MUSB controllers which can be host or gadget */
122 131 #if (defined(CONFIG_USB_MUSB_GADGET) || defined(CONFIG_USB_MUSB_HOST)) && \
123 132 (defined(CONFIG_AM335X_USB0) || defined(CONFIG_AM335X_USB1)) && \
124 133  
... ... @@ -209,7 +218,49 @@
209 218 }
210 219  
211 220 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
  221 +
  222 +#if defined(CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC) || \
  223 + (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_RTC_ONLY_SUPPORT))
  224 +static void rtc32k_unlock(struct davinci_rtc *rtc)
  225 +{
  226 + /*
  227 + * Unlock the RTC's registers. For more details please see the
  228 + * RTC_SS section of the TRM. In order to unlock we need to
  229 + * write these specific values (keys) in this order.
  230 + */
  231 + writel(RTC_KICK0R_WE, &rtc->kick0r);
  232 + writel(RTC_KICK1R_WE, &rtc->kick1r);
  233 +}
  234 +#endif
  235 +
  236 +#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_RTC_ONLY_SUPPORT)
212 237 /*
  238 + * Write contents of the RTC_SCRATCH1 register based on board type
  239 + * Two things are passed
  240 + * on. First 16 bits (0:15) are written with RTC_MAGIC value. Once the
  241 + * control gets to kernel, kernel reads the scratchpad register and gets to
  242 + * know that bootloader has rtc_only support.
  243 + *
  244 + * Second important thing is the board type (16:31). This is needed in the
  245 + * rtc_only boot where in we want to avoid costly i2c reads to eeprom to
  246 + * identify the board type and we go ahead and copy the board strings to
  247 + * am43xx_board_name.
  248 + */
  249 +void update_rtc_magic(void)
  250 +{
  251 + struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE;
  252 + u32 magic = RTC_MAGIC_VAL;
  253 +
  254 + magic |= (rtc_only_get_board_type() << RTC_BOARD_TYPE_SHIFT);
  255 +
  256 + rtc32k_unlock(rtc);
  257 +
  258 + /* write magic */
  259 + writel(magic, &rtc->scratch1);
  260 +}
  261 +#endif
  262 +
  263 +/*
213 264 * In the case of non-SPL based booting we'll want to call these
214 265 * functions a tiny bit later as it will require gd to be set and cleared
215 266 * and that's not true in s_init in this case so we cannot do it there.
... ... @@ -218,7 +269,9 @@
218 269 {
219 270 prcm_init();
220 271 set_mux_conf_regs();
221   -
  272 +#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_RTC_ONLY_SUPPORT)
  273 + update_rtc_magic();
  274 +#endif
222 275 return 0;
223 276 }
224 277  
... ... @@ -237,13 +290,7 @@
237 290 {
238 291 struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE;
239 292  
240   - /*
241   - * Unlock the RTC's registers. For more details please see the
242   - * RTC_SS section of the TRM. In order to unlock we need to
243   - * write these specific values (keys) in this order.
244   - */
245   - writel(RTC_KICK0R_WE, &rtc->kick0r);
246   - writel(RTC_KICK1R_WE, &rtc->kick1r);
  293 + rtc32k_unlock(rtc);
247 294  
248 295 /* Enable the RTC 32K OSC by setting bits 3 and 6. */
249 296 writel((1 << 3) | (1 << 6), &rtc->osc);
250 297  
... ... @@ -280,8 +327,54 @@
280 327 ;
281 328 }
282 329  
  330 +#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_RTC_ONLY_SUPPORT)
  331 +/*
  332 + * Check if we are executing rtc-only mode, and resume from it if needed
  333 + */
  334 +static void rtc_only(void)
  335 +{
  336 + struct davinci_rtc *rtc = (struct davinci_rtc *)RTC_BASE;
  337 + u32 scratch1;
  338 + void (*resume_func)(void);
  339 +
  340 + scratch1 = readl(&rtc->scratch1);
  341 +
  342 + /*
  343 + * Check RTC scratch against RTC_MAGIC_VAL, RTC_MAGIC_VAL is only
  344 + * written to this register when we want to wake up from RTC only
  345 + * mode. Contents of the RTC_SCRATCH1:
  346 + * bits 0-15: RTC_MAGIC_VAL
  347 + * bits 16-31: board type (needed for sdram_init)
  348 + */
  349 + if ((scratch1 & 0xffff) != RTC_MAGIC_VAL)
  350 + return;
  351 +
  352 + rtc32k_unlock(rtc);
  353 +
  354 + /* Clear RTC magic */
  355 + writel(0, &rtc->scratch1);
  356 +
  357 + /*
  358 + * Update board type based on value stored on RTC_SCRATCH1, this
  359 + * is done so that we don't need to read the board type from eeprom
  360 + * over i2c bus which is expensive
  361 + */
  362 + rtc_only_update_board_type(scratch1 >> RTC_BOARD_TYPE_SHIFT);
  363 +
  364 + rtc_only_prcm_init();
  365 + sdram_init();
  366 +
  367 + resume_func = (void *)readl(&rtc->scratch0);
  368 + if (resume_func)
  369 + resume_func();
  370 +}
  371 +#endif
  372 +
283 373 void s_init(void)
284 374 {
  375 +#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_RTC_ONLY_SUPPORT)
  376 + rtc_only();
  377 +#endif
285 378 }
286 379  
287 380 void early_system_init(void)
arch/arm/mach-omap2/am33xx/clock.c
... ... @@ -244,4 +244,14 @@
244 244 scale_vcores();
245 245 setup_dplls();
246 246 }
  247 +
  248 +void rtc_only_prcm_init(void)
  249 +{
  250 + const struct dpll_params *params;
  251 +
  252 + rtc_only_enable_basic_clocks();
  253 +
  254 + params = get_dpll_ddr_params();
  255 + do_setup_dpll(&dpll_ddr_regs, params);
  256 +}
arch/arm/mach-omap2/am33xx/clock_am43xx.c
... ... @@ -124,6 +124,27 @@
124 124 writel(0x4, &cmdpll->clkselmacclk);
125 125 }
126 126  
  127 +void rtc_only_enable_basic_clocks(void)
  128 +{
  129 + u32 *const clk_domains[] = {
  130 + &cmper->emifclkstctrl,
  131 + 0
  132 + };
  133 +
  134 + u32 *const clk_modules_explicit_en[] = {
  135 + &cmper->gpio5clkctrl,
  136 + &cmper->emiffwclkctrl,
  137 + &cmper->emifclkctrl,
  138 + &cmper->otfaemifclkctrl,
  139 + 0
  140 + };
  141 +
  142 + do_enable_clocks(clk_domains, clk_modules_explicit_en, 1);
  143 +
  144 + /* Select the Master osc clk as Timer2 clock source */
  145 + writel(0x1, &cmdpll->clktimer2clk);
  146 +}
  147 +
127 148 #ifdef CONFIG_TI_EDMA3
128 149 void enable_edma3_clocks(void)
129 150 {
board/ti/am43xx/MAINTAINERS
... ... @@ -7,5 +7,6 @@
7 7 F: configs/am43xx_evm_ethboot_defconfig
8 8 F: configs/am43xx_evm_qspiboot_defconfig
9 9 F: configs/am43xx_evm_usbhost_boot_defconfig
  10 +F: configs/am43xx_evm_rtconly_defconfig
10 11 F: configs/am43xx_hs_evm_defconfig
board/ti/am43xx/board.c
... ... @@ -532,6 +532,62 @@
532 532 writel(temp, AM33XX_GPIO5_BASE + OMAP_GPIO_OE);
533 533 }
534 534  
  535 +enum {
  536 + RTC_BOARD_EPOS = 1,
  537 + RTC_BOARD_EVM14,
  538 + RTC_BOARD_EVM12,
  539 + RTC_BOARD_GPEVM,
  540 + RTC_BOARD_SK,
  541 +};
  542 +
  543 +/*
  544 + * In the rtc_only boot path we have the board type info in the rtc scratch pad
  545 + * register hence we bypass the costly i2c reads to eeprom and directly program
  546 + * the board name string
  547 + */
  548 +void rtc_only_update_board_type(u32 btype)
  549 +{
  550 + const char *name = "";
  551 + const char *rev = "1.0";
  552 +
  553 + switch (btype) {
  554 + case RTC_BOARD_EPOS:
  555 + name = "AM43EPOS";
  556 + break;
  557 + case RTC_BOARD_EVM14:
  558 + name = "AM43__GP";
  559 + rev = "1.4";
  560 + break;
  561 + case RTC_BOARD_EVM12:
  562 + name = "AM43__GP";
  563 + rev = "1.2";
  564 + break;
  565 + case RTC_BOARD_GPEVM:
  566 + name = "AM43__GP";
  567 + break;
  568 + case RTC_BOARD_SK:
  569 + name = "AM43__SK";
  570 + break;
  571 + }
  572 + ti_i2c_eeprom_am_set(name, rev);
  573 +}
  574 +
  575 +u32 rtc_only_get_board_type(void)
  576 +{
  577 + if (board_is_eposevm())
  578 + return RTC_BOARD_EPOS;
  579 + else if (board_is_evm_14_or_later())
  580 + return RTC_BOARD_EVM14;
  581 + else if (board_is_evm_12_or_later())
  582 + return RTC_BOARD_EVM12;
  583 + else if (board_is_gpevm())
  584 + return RTC_BOARD_GPEVM;
  585 + else if (board_is_sk())
  586 + return RTC_BOARD_SK;
  587 +
  588 + return 0;
  589 +}
  590 +
535 591 void sdram_init(void)
536 592 {
537 593 /*
configs/am43xx_evm_rtconly_defconfig
  1 +CONFIG_ARM=y
  2 +CONFIG_AM43XX=y
  3 +CONFIG_TARGET_AM43XX_EVM=y
  4 +CONFIG_SPL_STACK_R_ADDR=0x82000000
  5 +CONFIG_SPL_YMODEM_SUPPORT=y
  6 +CONFIG_DEFAULT_DEVICE_TREE="am437x-gp-evm"
  7 +CONFIG_FIT=y
  8 +CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=1,NAND"
  9 +CONFIG_SPL_LOAD_FIT=y
  10 +CONFIG_SYS_CONSOLE_INFO_QUIET=y
  11 +CONFIG_VERSION_VARIABLE=y
  12 +CONFIG_SPL=y
  13 +CONFIG_SPL_STACK_R=y
  14 +CONFIG_SPL_RTC_ONLY_SUPPORT=y
  15 +CONFIG_SPL_MTD_SUPPORT=y
  16 +CONFIG_SPL_OS_BOOT=y
  17 +CONFIG_HUSH_PARSER=y
  18 +CONFIG_CMD_BOOTZ=y
  19 +# CONFIG_CMD_IMLS is not set
  20 +CONFIG_CMD_ASKENV=y
  21 +# CONFIG_CMD_FLASH is not set
  22 +CONFIG_CMD_MMC=y
  23 +CONFIG_CMD_SF=y
  24 +CONFIG_CMD_SPI=y
  25 +CONFIG_CMD_I2C=y
  26 +CONFIG_CMD_USB=y
  27 +CONFIG_CMD_DFU=y
  28 +CONFIG_CMD_GPIO=y
  29 +# CONFIG_CMD_SETEXPR is not set
  30 +CONFIG_CMD_DHCP=y
  31 +CONFIG_CMD_MII=y
  32 +CONFIG_CMD_PING=y
  33 +CONFIG_CMD_EXT2=y
  34 +CONFIG_CMD_EXT4=y
  35 +CONFIG_CMD_EXT4_WRITE=y
  36 +CONFIG_CMD_FAT=y
  37 +CONFIG_CMD_FS_GENERIC=y
  38 +CONFIG_OF_CONTROL=y
  39 +CONFIG_OF_LIST="am437x-gp-evm am437x-sk-evm am43x-epos-evm am437x-idk-evm"
  40 +CONFIG_DM=y
  41 +# CONFIG_BLK is not set
  42 +CONFIG_DFU_MMC=y
  43 +CONFIG_DFU_RAM=y
  44 +CONFIG_DFU_SF=y
  45 +CONFIG_DM_GPIO=y
  46 +CONFIG_DM_I2C=y
  47 +CONFIG_DM_MMC=y
  48 +# CONFIG_DM_MMC_OPS is not set
  49 +CONFIG_DM_SPI_FLASH=y
  50 +CONFIG_SPI_FLASH=y
  51 +CONFIG_SPI_FLASH_BAR=y
  52 +CONFIG_SPI_FLASH_MACRONIX=y
  53 +CONFIG_DM_ETH=y
  54 +CONFIG_DM_SERIAL=y
  55 +CONFIG_SYS_NS16550=y
  56 +CONFIG_DM_SPI=y
  57 +CONFIG_TI_QSPI=y
  58 +CONFIG_TIMER=y
  59 +CONFIG_OMAP_TIMER=y
  60 +CONFIG_USB=y
  61 +CONFIG_USB_XHCI_HCD=y
  62 +CONFIG_USB_XHCI_DWC3=y
  63 +CONFIG_USB_DWC3=y
  64 +CONFIG_USB_DWC3_GADGET=y
  65 +CONFIG_USB_DWC3_OMAP=y
  66 +CONFIG_USB_DWC3_PHY_OMAP=y
  67 +CONFIG_USB_STORAGE=y
  68 +CONFIG_USB_GADGET=y
  69 +CONFIG_USB_GADGET_DOWNLOAD=y
  70 +CONFIG_G_DNL_MANUFACTURER="Texas Instruments"
  71 +CONFIG_G_DNL_VENDOR_NUM=0x0403
  72 +CONFIG_G_DNL_PRODUCT_NUM=0xbd00
  73 +CONFIG_SPL_OF_LIBFDT=y