am335x: Enable RTC 32K OSC clock
authorVaibhav Hiremath <hvaibhav@ti.com>
Thu, 8 Mar 2012 11:45:47 +0000 (17:15 +0530)
committerTom Rini <trini@ti.com>
Thu, 25 Oct 2012 18:30:22 +0000 (11:30 -0700)
In order to support low power state, you must source kernel system
timers to persistent clock, available across suspend/resume.  In case of
AM335x device, the only source we have is, RTC32K, available in
wakeup/always-on domain.  Having said that, during validation it has
been observed that, RTC clock need couple of seconds delay to stabilize
the RTC OSC clock; and such a huge delay is not acceptable in kernel
especially during early init and also it will impact quick/fast boot
use-cases.

So, RTC32k OSC enable dependency has been shifted to
SPL/first-bootloader.

Signed-off-by: Vaibhav Hiremath <hvaibhav@ti.com>
Signed-off-by: Tom Rini <trini@ti.com>
arch/arm/cpu/armv7/am33xx/board.c
arch/arm/cpu/armv7/am33xx/clock.c
arch/arm/include/asm/arch-am33xx/cpu.h
arch/arm/include/asm/arch-am33xx/hardware.h

index 6de03fd6578175a45633135df2c752a52689edc0..772203fe5b128bc7e6a929adbff7f7005c85f239 100644 (file)
@@ -116,11 +116,27 @@ static int read_eeprom(void)
        return 0;
 }
 
-/* UART Defines */
 #ifdef CONFIG_SPL_BUILD
+/* UART Defines */
 #define UART_RESET             (0x1 << 1)
 #define UART_CLK_RUNNING_MASK  0x1
 #define UART_SMART_IDLE_EN     (0x1 << 0x3)
+
+static void rtc32k_enable(void)
+{
+       struct rtc_regs *rtc = (struct rtc_regs *)AM335X_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(0x83e70b13, &rtc->kick0r);
+       writel(0x95a4f1e0, &rtc->kick1r);
+
+       /* Enable the RTC 32K OSC by setting bits 3 and 6. */
+       writel((1 << 3) | (1 << 6), &rtc->osc);
+}
 #endif
 
 /*
@@ -154,6 +170,9 @@ void s_init(void)
        /* Setup the PLLs and the clocks for the peripherals */
        pll_init();
 
+       /* Enable RTC32K clock */
+       rtc32k_enable();
+
        /* UART softreset */
        u32 regVal;
 
index 2b19506a341c01a39a5347aba4a76f865829689e..f870859414440628536554d6fba47918a087f428 100644 (file)
@@ -44,6 +44,7 @@
 const struct cm_perpll *cmper = (struct cm_perpll *)CM_PER;
 const struct cm_wkuppll *cmwkup = (struct cm_wkuppll *)CM_WKUP;
 const struct cm_dpll *cmdpll = (struct cm_dpll *)CM_DPLL;
+const struct cm_rtc *cmrtc = (struct cm_rtc *)CM_RTC;
 
 static void enable_interface_clocks(void)
 {
@@ -153,6 +154,11 @@ static void enable_per_clocks(void)
        writel(PRCM_MOD_EN, &cmper->spi0clkctrl);
        while (readl(&cmper->spi0clkctrl) != PRCM_MOD_EN)
                ;
+
+       /* RTC */
+       writel(PRCM_MOD_EN, &cmrtc->rtcclkctrl);
+       while (readl(&cmrtc->rtcclkctrl) != PRCM_MOD_EN)
+               ;
 }
 
 static void mpu_pll_config(void)
index 6cfbef76a79236130add2df5de3aa5f8a662e4e2..819fd2f026900bf82491035b4e513fc9b84f8e46 100644 (file)
@@ -169,6 +169,12 @@ struct cm_dpll {
        unsigned int clktimer2clk;      /* offset 0x08 */
 };
 
+/* Control Module RTC registers */
+struct cm_rtc {
+       unsigned int rtcclkctrl;        /* offset 0x0 */
+       unsigned int clkstctrl;         /* offset 0x4 */
+};
+
 /* Watchdog timer registers */
 struct wd_timer {
        unsigned int resv1[4];
@@ -218,6 +224,15 @@ struct gptimer {
        unsigned int tcar2;             /* offset 0x58 */
 };
 
+/* RTC Registers */
+struct rtc_regs {
+       unsigned int res[21];
+       unsigned int osc;               /* offset 0x54 */
+       unsigned int res2[5];
+       unsigned int kick0r;            /* offset 0x6c */
+       unsigned int kick1r;            /* offset 0x70 */
+};
+
 /* UART Registers */
 struct uart_sys {
        unsigned int resv1[21];
index 62332f2ded54dcb70e362025b4c22253a86df00f..5bd4bc8722016e04c86fe0e4b33daeafaa1d9454 100644 (file)
@@ -61,6 +61,7 @@
 #define CM_WKUP                                0x44E00400
 #define CM_DPLL                                0x44E00500
 #define CM_DEVICE                      0x44E00700
+#define CM_RTC                         0x44E00800
 #define CM_CEFUSE                      0x44E00A00
 #define PRM_DEVICE                     0x44E00F00
 
@@ -83,4 +84,7 @@
 #define AM335X_CPSW_BASE               0x4A100000
 #define AM335X_CPSW_MDIO_BASE          0x4A101000
 
+/* RTC base address */
+#define AM335X_RTC_BASE                        0x44E3E000
+
 #endif /* __AM33XX_HARDWARE_H */