tegra: Correct logic for reading pll_misc in clock_start_pll()
authorSimon Glass <sjg@chromium.org>
Mon, 10 Aug 2015 13:14:36 +0000 (07:14 -0600)
committerTom Warren <twarren@nvidia.com>
Thu, 13 Aug 2015 20:06:04 +0000 (13:06 -0700)
The logic for simple PLLs on T124 was broken by this commit:

  722e000c Tegra: PLL: use per-SoC pllinfo table instead of PLL_DIVM/N/P, etc.

Correct it by reading from the same pll_misc register that it writes to and
adding an entry for the DP PLL in the pllinfo table.

Signed-off-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Tom Warren <twarren@nvidia.com>
arch/arm/mach-tegra/clock.c
arch/arm/mach-tegra/tegra124/clock.c
arch/arm/mach-tegra/tegra210/clock.c

index 3b2b4ffd2a72b4804742cdd961c8d73b91cc53c4..f014434d8cc3f8ac28f7a5aef3117a3c9ee586c3 100644 (file)
@@ -126,19 +126,34 @@ unsigned long clock_start_pll(enum clock_id clkid, u32 divm, u32 divn,
 {
        struct clk_pll *pll = NULL;
        struct clk_pll_info *pllinfo = &tegra_pll_info_table[clkid];
+       struct clk_pll_simple *simple_pll = NULL;
        u32 misc_data, data;
 
-       if (clkid < (enum clock_id)TEGRA_CLK_PLLS)
+       if (clkid < (enum clock_id)TEGRA_CLK_PLLS) {
                pll = get_pll(clkid);
+       } else {
+               simple_pll = clock_get_simple_pll(clkid);
+               if (!simple_pll) {
+                       debug("%s: Uknown simple PLL %d\n", __func__, clkid);
+                       return 0;
+               }
+       }
 
        /*
         * pllinfo has the m/n/p and kcp/kvco mask and shift
         * values for all of the PLLs used in U-Boot, with any
         * SoC differences accounted for.
+        *
+        * Preserve EN_LOCKDET, etc.
         */
-       misc_data = readl(&pll->pll_misc);      /* preserve EN_LOCKDET, etc. */
-       misc_data &= ~(pllinfo->kcp_mask << pllinfo->kcp_shift) | (cpcon << pllinfo->kcp_shift);
-       misc_data &= ~(pllinfo->kvco_mask << pllinfo->kvco_shift) | (lfcon << pllinfo->kvco_shift);
+       if (pll)
+               misc_data = readl(&pll->pll_misc);
+       else
+               misc_data = readl(&simple_pll->pll_misc);
+       misc_data &= ~(pllinfo->kcp_mask << pllinfo->kcp_shift);
+       misc_data |= cpcon << pllinfo->kcp_shift;
+       misc_data &= ~(pllinfo->kvco_mask << pllinfo->kvco_shift);
+       misc_data |= lfcon << pllinfo->kvco_shift;
 
        data = (divm << pllinfo->m_shift) | (divn << pllinfo->n_shift);
        data |= divp << pllinfo->p_shift;
@@ -148,14 +163,8 @@ unsigned long clock_start_pll(enum clock_id clkid, u32 divm, u32 divn,
                writel(misc_data, &pll->pll_misc);
                writel(data, &pll->pll_base);
        } else {
-               struct clk_pll_simple *pll = clock_get_simple_pll(clkid);
-
-               if (!pll) {
-                       debug("%s: Uknown simple PLL %d\n", __func__, clkid);
-                       return 0;
-               }
-               writel(misc_data, &pll->pll_misc);
-               writel(data, &pll->pll_base);
+               writel(misc_data, &simple_pll->pll_misc);
+               writel(data, &simple_pll->pll_base);
        }
 
        /* calculate the stable time */
index 912621863a206f8ebaf670b4ea4e04d2263be770..291b75276c5e845a636008f65b7ac774389f3332 100644 (file)
@@ -570,7 +570,7 @@ static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = {
  */
 struct clk_pll_info tegra_pll_info_table[CLOCK_ID_PLL_COUNT] = {
        /*
-        * T124: same as T114, some deviations from T2x/T30.
+        * T124: same as T114, some deviations from T2x/T30. Adds PLLDP.
         * NOTE: If kcp_mask/kvco_mask == 0, they're not used in that PLL (PLLX, etc.)
         *       If lock_ena or lock_det are >31, they're not used in that PLL.
         */
@@ -593,6 +593,8 @@ struct clk_pll_info tegra_pll_info_table[CLOCK_ID_PLL_COUNT] = {
          .lock_ena = 9,  .lock_det = 11, .kcp_shift = 6, .kcp_mask = 3, .kvco_shift = 0, .kvco_mask = 1 },     /* PLLE */
        { .m_shift = 0, .m_mask = 0x0F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07,
          .lock_ena = 18, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF }, /* PLLS (RESERVED) */
+       { .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0xFF,  .p_shift = 20,  .p_mask = 0xF,
+         .lock_ena = 30, .lock_det = 27, .kcp_shift = 25, .kcp_mask = 3, .kvco_shift = 24, .kvco_mask = 1 },   /* PLLDP */
 };
 
 /*
index a7b3a949fc34606ba8d8bf2d97f4b68a2452a42e..830a33ffc9385196da9d1f451219ef291e824640 100644 (file)
@@ -42,6 +42,7 @@ enum clock_type_id {
        CLOCK_TYPE_ASPTE,
        CLOCK_TYPE_PMDACD2T,
        CLOCK_TYPE_PCST,
+       CLOCK_TYPE_DP,
 
        CLOCK_TYPE_PC2CC3M,
        CLOCK_TYPE_PC2CC3S_T,
@@ -102,6 +103,10 @@ static enum clock_id clock_source[CLOCK_TYPE_COUNT][CLOCK_MAX_MUX+1] = {
        { CLK(PERIPH),  CLK(CGENERAL),  CLK(SFROM32KHZ),        CLK(OSC),
                CLK(NONE),      CLK(NONE),      CLK(NONE),      CLK(NONE),
                MASK_BITS_31_28},
+       /* CLOCK_TYPE_DP */
+       { CLK(NONE),    CLK(NONE),      CLK(NONE),      CLK(NONE),
+               CLK(NONE),      CLK(NONE),      CLK(NONE),      CLK(NONE),
+               MASK_BITS_31_28},
 
        /* Additional clock types on Tegra114+ */
        /* CLOCK_TYPE_PC2CC3M */
@@ -656,6 +661,8 @@ struct clk_pll_info tegra_pll_info_table[CLOCK_ID_PLL_COUNT] = {
          .lock_ena = 9,  .lock_det = 11, .kcp_shift = 6, .kcp_mask = 3, .kvco_shift = 0, .kvco_mask = 1 },     /* PLLE */
        { .m_shift = 0, .m_mask = 0, .n_shift = 0, .n_mask = 0, .p_shift = 0, .p_mask = 0,
          .lock_ena = 0, .lock_det = 0, .kcp_shift = 0, .kcp_mask = 0, .kvco_shift = 0, .kvco_mask = 0 },       /* PLLS (gone)*/
+       { .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0xFF,  .p_shift = 19,  .p_mask = 0x1F,
+         .lock_ena = 30, .lock_det = 27, .kcp_shift = 25, .kcp_mask = 3, .kvco_shift = 24, .kvco_mask = 1 },   /* PLLDP */
 };
 
 /*