ARM i.MX6: Fix ethernet PLL clocks
authorSascha Hauer <s.hauer@pengutronix.de>
Wed, 21 Nov 2012 13:42:31 +0000 (14:42 +0100)
committerSascha Hauer <s.hauer@pengutronix.de>
Thu, 22 Nov 2012 14:32:33 +0000 (15:32 +0100)
In current code the ethernet PLL is not handled correctly. The PLL runs at 500MHz
and has different outputs. Only the enet reference clock is implemented. This
patch changes the PLL so that it outputs 500MHz and adds the additional outputs
as dividers. This now matches the datasheet which says:

> This PLL synthesizes a low jitter clock from 24 MHz reference clock.
> The PLL outputs a 500 MHz clock. The reference clocks generated by this PLL are:
>  • Ref_PCIe = 125 MHz
>  • Ref_SATA = 100 MHz
>  • Ref_ethernet, which is configurable based on the PLL_ENET[1:0] register field.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Acked-by: Shawn Guo <shawn.guo@linaro.org>
Documentation/devicetree/bindings/clock/imx6q-clock.txt
arch/arm/mach-imx/clk-imx6q.c
arch/arm/mach-imx/clk-pllv3.c

index bb71d4f8004b456e9ca1460317b7706ccdcbba19..d77b4e68dc42b306f22a472c5216623be0ed9a3d 100644 (file)
@@ -198,6 +198,11 @@ clocks and IDs.
        usbphy2                 183
        ldb_di0_div_3_5         184
        ldb_di1_div_3_5         185
+       sata_ref                186
+       sata_ref_100m           187
+       pcie_ref                188
+       pcie_ref_125m           189
+       enet_ref                190
 
 Examples:
 
index 0d60cb0e30fb041829349eac9f93831c2b2365f1..d8049d3f9801f3ebce5db8eee0a78a78b0efdfca 100644 (file)
@@ -154,6 +154,7 @@ enum mx6q_clks {
        usdhc4, vdo_axi, vpu_axi, cko1, pll1_sys, pll2_bus, pll3_usb_otg,
        pll4_audio, pll5_video, pll8_mlb, pll7_usb_host, pll6_enet, ssi1_ipg,
        ssi2_ipg, ssi3_ipg, rom, usbphy1, usbphy2, ldb_di0_div_3_5, ldb_di1_div_3_5,
+       sata_ref, sata_ref_100m, pcie_ref, pcie_ref_125m, enet_ref,
        clk_max
 };
 
@@ -164,6 +165,13 @@ static enum mx6q_clks const clks_init_on[] __initconst = {
        mmdc_ch0_axi, rom,
 };
 
+static struct clk_div_table clk_enet_ref_table[] = {
+       { .val = 0, .div = 20, },
+       { .val = 1, .div = 10, },
+       { .val = 2, .div = 5, },
+       { .val = 3, .div = 4, },
+};
+
 int __init mx6q_clocks_init(void)
 {
        struct device_node *np;
@@ -196,13 +204,23 @@ int __init mx6q_clocks_init(void)
        clk[pll3_usb_otg]  = imx_clk_pllv3(IMX_PLLV3_USB,       "pll3_usb_otg", "osc", base + 0x10, 0x2000,   0x3);
        clk[pll4_audio]    = imx_clk_pllv3(IMX_PLLV3_AV,        "pll4_audio",   "osc", base + 0x70, 0x2000,   0x7f);
        clk[pll5_video]    = imx_clk_pllv3(IMX_PLLV3_AV,        "pll5_video",   "osc", base + 0xa0, 0x2000,   0x7f);
-       clk[pll6_enet]     = imx_clk_pllv3(IMX_PLLV3_ENET,      "pll6_enet",    "osc", base + 0xe0, 0x182000, 0x3);
+       clk[pll6_enet]     = imx_clk_pllv3(IMX_PLLV3_ENET,      "pll6_enet",    "osc", base + 0xe0, 0x2000,   0x3);
        clk[pll7_usb_host] = imx_clk_pllv3(IMX_PLLV3_USB,       "pll7_usb_host","osc", base + 0x20, 0x2000,   0x3);
        clk[pll8_mlb]      = imx_clk_pllv3(IMX_PLLV3_MLB,       "pll8_mlb",     "osc", base + 0xd0, 0x2000,   0x0);
 
        clk[usbphy1] = imx_clk_gate("usbphy1", "pll3_usb_otg", base + 0x10, 6);
        clk[usbphy2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 6);
 
+       clk[sata_ref] = imx_clk_fixed_factor("sata_ref", "pll6_enet", 1, 5);
+       clk[pcie_ref] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 4);
+
+       clk[sata_ref_100m] = imx_clk_gate("sata_ref_100m", "sata_ref", base + 0xe0, 20);
+       clk[pcie_ref_125m] = imx_clk_gate("pcie_ref_125m", "pcie_ref", base + 0xe0, 19);
+
+       clk[enet_ref] = clk_register_divider_table(NULL, "enet_ref", "pll6_enet", 0,
+                       base + 0xe0, 0, 2, 0, clk_enet_ref_table,
+                       &imx_ccm_lock);
+
        /*                                name              parent_name        reg       idx */
        clk[pll2_pfd0_352m] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus",     base + 0x100, 0);
        clk[pll2_pfd1_594m] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus",     base + 0x100, 1);
index 36aac947bce1a072da9c2d8a9a38ea503e55193e..59e74339ab08f728dcdbfa54471dbd49f66fbd4d 100644 (file)
@@ -287,66 +287,7 @@ static const struct clk_ops clk_pllv3_av_ops = {
 static unsigned long clk_pllv3_enet_recalc_rate(struct clk_hw *hw,
                                                unsigned long parent_rate)
 {
-       struct clk_pllv3 *pll = to_clk_pllv3(hw);
-       u32 div = readl_relaxed(pll->base) & pll->div_mask;
-
-       switch (div) {
-       case 0:
-               return 25000000;
-       case 1:
-               return 50000000;
-       case 2:
-               return 100000000;
-       case 3:
-               return 125000000;
-       }
-
-       return 0;
-}
-
-static long clk_pllv3_enet_round_rate(struct clk_hw *hw, unsigned long rate,
-                                     unsigned long *prate)
-{
-       if (rate >= 125000000)
-               rate = 125000000;
-       else if (rate >= 100000000)
-               rate = 100000000;
-       else if (rate >= 50000000)
-               rate = 50000000;
-       else
-               rate = 25000000;
-       return rate;
-}
-
-static int clk_pllv3_enet_set_rate(struct clk_hw *hw, unsigned long rate,
-               unsigned long parent_rate)
-{
-       struct clk_pllv3 *pll = to_clk_pllv3(hw);
-       u32 val, div;
-
-       switch (rate) {
-       case 25000000:
-               div = 0;
-               break;
-       case 50000000:
-               div = 1;
-               break;
-       case 100000000:
-               div = 2;
-               break;
-       case 125000000:
-               div = 3;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       val = readl_relaxed(pll->base);
-       val &= ~pll->div_mask;
-       val |= div;
-       writel_relaxed(val, pll->base);
-
-       return 0;
+       return 500000000;
 }
 
 static const struct clk_ops clk_pllv3_enet_ops = {
@@ -355,8 +296,6 @@ static const struct clk_ops clk_pllv3_enet_ops = {
        .enable         = clk_pllv3_enable,
        .disable        = clk_pllv3_disable,
        .recalc_rate    = clk_pllv3_enet_recalc_rate,
-       .round_rate     = clk_pllv3_enet_round_rate,
-       .set_rate       = clk_pllv3_enet_set_rate,
 };
 
 static const struct clk_ops clk_pllv3_mlb_ops = {
This page took 0.027734 seconds and 5 git commands to generate.