arm: socfpga: clock: Sync with reference code
authorMarek Vasut <marex@denx.de>
Tue, 16 Sep 2014 17:54:32 +0000 (19:54 +0200)
committerMarek Vasut <marex@denx.de>
Mon, 6 Oct 2014 15:46:49 +0000 (17:46 +0200)
Add the missing pieces from the reference clock code from Altera. This
puts the code on par with the Altera U-Boot fork for all but the SDRAM
self-refresh bits, which are not part of this patch.

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Chin Liang See <clsee@altera.com>
Cc: Dinh Nguyen <dinguyen@altera.com>
Cc: Albert Aribaud <albert.u.boot@aribaud.net>
Cc: Tom Rini <trini@ti.com>
Cc: Wolfgang Denk <wd@denx.de>
Cc: Pavel Machek <pavel@denx.de>
Acked-by: Pavel Machek <pavel@denx.de>
arch/arm/cpu/armv7/socfpga/clock_manager.c
arch/arm/include/asm/arch-socfpga/clock_manager.h

index 1cf0d77fb56a4e15075453bc8cbe78ec7087e38d..d869f47c88caab3aa3c06c48732f7f6cff5e646b 100644 (file)
@@ -16,9 +16,16 @@ static const struct socfpga_clock_manager *clock_manager_base =
 static void cm_wait_for_lock(uint32_t mask)
 {
        register uint32_t inter_val;
+       uint32_t retry = 0;
        do {
                inter_val = readl(&clock_manager_base->inter) & mask;
-       } while (inter_val != mask);
+               if (inter_val == mask)
+                       retry++;
+               else
+                       retry = 0;
+               if (retry >= 10)
+                       break;
+       } while (1);
 }
 
 /* function to poll in the fsm busy bit */
@@ -114,15 +121,15 @@ void cm_basic_init(const cm_config_t *cfg)
        cm_write_bypass(CLKMGR_BYPASS_PERPLL | CLKMGR_BYPASS_SDRPLL |
                        CLKMGR_BYPASS_MAINPLL);
 
-       /*
-        * Put all plls VCO registers back to reset value.
-        * Some code might have messed with them.
-        */
-       writel(CLKMGR_MAINPLLGRP_VCO_RESET_VALUE,
+       /* Put all plls VCO registers back to reset value. */
+       writel(CLKMGR_MAINPLLGRP_VCO_RESET_VALUE &
+              ~CLKMGR_MAINPLLGRP_VCO_REGEXTSEL_MASK,
               &clock_manager_base->main_pll.vco);
-       writel(CLKMGR_PERPLLGRP_VCO_RESET_VALUE,
+       writel(CLKMGR_PERPLLGRP_VCO_RESET_VALUE &
+              ~CLKMGR_PERPLLGRP_VCO_REGEXTSEL_MASK,
               &clock_manager_base->per_pll.vco);
-       writel(CLKMGR_SDRPLLGRP_VCO_RESET_VALUE,
+       writel(CLKMGR_SDRPLLGRP_VCO_RESET_VALUE &
+              ~CLKMGR_SDRPLLGRP_VCO_REGEXTSEL_MASK,
               &clock_manager_base->sdr_pll.vco);
 
        /*
@@ -147,14 +154,9 @@ void cm_basic_init(const cm_config_t *cfg)
         * We made sure bgpwr down was assert for 5 us. Now deassert BG PWR DN
         * with numerator and denominator.
         */
-       writel(cfg->main_vco_base | CLKMGR_MAINPLLGRP_VCO_REGEXTSEL_MASK,
-              &clock_manager_base->main_pll.vco);
-
-       writel(cfg->peri_vco_base | CLKMGR_PERPLLGRP_VCO_REGEXTSEL_MASK,
-              &clock_manager_base->per_pll.vco);
-
-       writel(cfg->sdram_vco_base | CLKMGR_SDRPLLGRP_VCO_REGEXTSEL_MASK,
-              &clock_manager_base->sdr_pll.vco);
+       writel(cfg->main_vco_base, &clock_manager_base->main_pll.vco);
+       writel(cfg->peri_vco_base, &clock_manager_base->per_pll.vco);
+       writel(cfg->sdram_vco_base, &clock_manager_base->sdr_pll.vco);
 
        /*
         * Time starts here
@@ -189,6 +191,9 @@ void cm_basic_init(const cm_config_t *cfg)
        writel(cfg->perqspiclk, &clock_manager_base->per_pll.perqspiclk);
 
        /* Peri pernandsdmmcclk */
+       writel(cfg->mainnandsdmmcclk,
+              &clock_manager_base->main_pll.mainnandsdmmcclk);
+
        writel(cfg->pernandsdmmcclk,
               &clock_manager_base->per_pll.pernandsdmmcclk);
 
@@ -318,6 +323,11 @@ void cm_basic_init(const cm_config_t *cfg)
        writel(~0, &clock_manager_base->main_pll.en);
        writel(~0, &clock_manager_base->per_pll.en);
        writel(~0, &clock_manager_base->sdr_pll.en);
+
+       /* Clear the loss of lock bits (write 1 to clear) */
+       writel(CLKMGR_INTER_SDRPLLLOST_MASK | CLKMGR_INTER_PERPLLLOST_MASK |
+              CLKMGR_INTER_MAINPLLLOST_MASK,
+              &clock_manager_base->inter);
 }
 
 static unsigned int cm_get_main_vco_clk_hz(void)
index bc916623632fba866ad9863fb6f5b0f719228a65..fa49f6a998785cd60428a69bd9109d6205dae468 100644 (file)
@@ -135,6 +135,9 @@ struct socfpga_clock_manager {
 #define CLKMGR_INTER_SDRPLLLOCKED_MASK                 0x00000100
 #define CLKMGR_INTER_PERPLLLOCKED_MASK                 0x00000080
 #define CLKMGR_INTER_MAINPLLLOCKED_MASK                        0x00000040
+#define CLKMGR_INTER_PERPLLLOST_MASK                   0x00000010
+#define CLKMGR_INTER_SDRPLLLOST_MASK                   0x00000020
+#define CLKMGR_INTER_MAINPLLLOST_MASK                  0x00000008
 
 #define CLKMGR_STAT_BUSY                               (1 << 0)