* [PATCH] i.MX6 clock @ 2012-11-22 9:59 Sascha Hauer 2012-11-22 9:59 ` [PATCH 1/3] ARM i.MX6: rename PLLs according to datasheet Sascha Hauer ` (2 more replies) 0 siblings, 3 replies; 9+ messages in thread From: Sascha Hauer @ 2012-11-22 9:59 UTC (permalink / raw) To: linux-arm-kernel The following contains fixes/cleanups for the i.MX6 clock support, mostly driven by the missing SATA clock support. ---------------------------------------------------------------- Sascha Hauer (3): ARM i.MX6: rename PLLs according to datasheet ARM i.MX6: Fix ethernet PLL clocks ARM i.MX6: remove gate_mask from pllv3 .../devicetree/bindings/clock/imx6q-clock.txt | 9 ++- arch/arm/mach-imx/clk-imx6q.c | 39 ++++++++--- arch/arm/mach-imx/clk-pllv3.c | 72 ++------------------ arch/arm/mach-imx/clk.h | 3 +- 4 files changed, 40 insertions(+), 83 deletions(-) ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/3] ARM i.MX6: rename PLLs according to datasheet 2012-11-22 9:59 [PATCH] i.MX6 clock Sascha Hauer @ 2012-11-22 9:59 ` Sascha Hauer 2012-11-22 9:59 ` [PATCH 2/3] ARM i.MX6: Fix ethernet PLL clocks Sascha Hauer 2012-11-22 9:59 ` [PATCH 3/3] ARM i.MX6: remove gate_mask from pllv3 Sascha Hauer 2 siblings, 0 replies; 9+ messages in thread From: Sascha Hauer @ 2012-11-22 9:59 UTC (permalink / raw) To: linux-arm-kernel In recent reference manuals the PLLs were renumbered. PLL8 now is PLL6 and vice versa. Change the code according to the reference manual to avoid confusion. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- Documentation/devicetree/bindings/clock/imx6q-clock.txt | 4 ++-- arch/arm/mach-imx/clk-imx6q.c | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/imx6q-clock.txt b/Documentation/devicetree/bindings/clock/imx6q-clock.txt index 492bd99..bb71d4f 100644 --- a/Documentation/devicetree/bindings/clock/imx6q-clock.txt +++ b/Documentation/devicetree/bindings/clock/imx6q-clock.txt @@ -187,9 +187,9 @@ clocks and IDs. pll3_usb_otg 172 pll4_audio 173 pll5_video 174 - pll6_mlb 175 + pll8_mlb 175 pll7_usb_host 176 - pll8_enet 177 + pll6_enet 177 ssi1_ipg 178 ssi2_ipg 179 ssi3_ipg 180 diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 3ec242f..4066365 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -151,7 +151,7 @@ enum mx6q_clks { gpmi_bch_apb, gpmi_bch, gpmi_io, gpmi_apb, sata, sdma, spba, ssi1, ssi2, ssi3, uart_ipg, uart_serial, usboh3, usdhc1, usdhc2, usdhc3, usdhc4, vdo_axi, vpu_axi, cko1, pll1_sys, pll2_bus, pll3_usb_otg, - pll4_audio, pll5_video, pll6_mlb, pll7_usb_host, pll8_enet, ssi1_ipg, + 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, clk_max }; @@ -195,9 +195,9 @@ 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_mlb] = imx_clk_pllv3(IMX_PLLV3_MLB, "pll6_mlb", "osc", base + 0xd0, 0x2000, 0x0); + clk[pll6_enet] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6_enet", "osc", base + 0xe0, 0x182000, 0x3); clk[pll7_usb_host] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host","osc", base + 0x20, 0x2000, 0x3); - clk[pll8_enet] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll8_enet", "osc", base + 0xe0, 0x182000, 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); @@ -357,7 +357,7 @@ int __init mx6q_clocks_init(void) clk[ldb_di1] = imx_clk_gate2("ldb_di1", "ldb_di1_podf", base + 0x74, 14); clk[ipu2_di1] = imx_clk_gate2("ipu2_di1", "ipu2_di1_sel", base + 0x74, 10); clk[hsi_tx] = imx_clk_gate2("hsi_tx", "hsi_tx_podf", base + 0x74, 16); - clk[mlb] = imx_clk_gate2("mlb", "pll6_mlb", base + 0x74, 18); + clk[mlb] = imx_clk_gate2("mlb", "pll8_mlb", base + 0x74, 18); clk[mmdc_ch0_axi] = imx_clk_gate2("mmdc_ch0_axi", "mmdc_ch0_axi_podf", base + 0x74, 20); clk[mmdc_ch1_axi] = imx_clk_gate2("mmdc_ch1_axi", "mmdc_ch1_axi_podf", base + 0x74, 22); clk[ocram] = imx_clk_gate2("ocram", "ahb", base + 0x74, 28); -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/3] ARM i.MX6: Fix ethernet PLL clocks 2012-11-22 9:59 [PATCH] i.MX6 clock Sascha Hauer 2012-11-22 9:59 ` [PATCH 1/3] ARM i.MX6: rename PLLs according to datasheet Sascha Hauer @ 2012-11-22 9:59 ` Sascha Hauer 2012-11-22 11:32 ` Shawn Guo 2012-11-22 9:59 ` [PATCH 3/3] ARM i.MX6: remove gate_mask from pllv3 Sascha Hauer 2 siblings, 1 reply; 9+ messages in thread From: Sascha Hauer @ 2012-11-22 9:59 UTC (permalink / raw) To: linux-arm-kernel 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> --- .../devicetree/bindings/clock/imx6q-clock.txt | 5 ++ arch/arm/mach-imx/clk-imx6q.c | 21 ++++++- arch/arm/mach-imx/clk-pllv3.c | 63 +------------------- 3 files changed, 25 insertions(+), 64 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/imx6q-clock.txt b/Documentation/devicetree/bindings/clock/imx6q-clock.txt index bb71d4f..d77b4e6 100644 --- a/Documentation/devicetree/bindings/clock/imx6q-clock.txt +++ b/Documentation/devicetree/bindings/clock/imx6q-clock.txt @@ -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: diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 4066365..622a299 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -153,6 +153,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 }; @@ -163,6 +164,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; @@ -195,13 +203,22 @@ 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); diff --git a/arch/arm/mach-imx/clk-pllv3.c b/arch/arm/mach-imx/clk-pllv3.c index 36aac94..59e7433 100644 --- a/arch/arm/mach-imx/clk-pllv3.c +++ b/arch/arm/mach-imx/clk-pllv3.c @@ -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 = { -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/3] ARM i.MX6: Fix ethernet PLL clocks 2012-11-22 9:59 ` [PATCH 2/3] ARM i.MX6: Fix ethernet PLL clocks Sascha Hauer @ 2012-11-22 11:32 ` Shawn Guo 2012-11-22 12:35 ` Sascha Hauer 0 siblings, 1 reply; 9+ messages in thread From: Shawn Guo @ 2012-11-22 11:32 UTC (permalink / raw) To: linux-arm-kernel On Thu, Nov 22, 2012 at 10:59:17AM +0100, Sascha Hauer wrote: > 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> > --- > .../devicetree/bindings/clock/imx6q-clock.txt | 5 ++ > arch/arm/mach-imx/clk-imx6q.c | 21 ++++++- > arch/arm/mach-imx/clk-pllv3.c | 63 +------------------- > 3 files changed, 25 insertions(+), 64 deletions(-) > > diff --git a/Documentation/devicetree/bindings/clock/imx6q-clock.txt b/Documentation/devicetree/bindings/clock/imx6q-clock.txt > index bb71d4f..d77b4e6 100644 > --- a/Documentation/devicetree/bindings/clock/imx6q-clock.txt > +++ b/Documentation/devicetree/bindings/clock/imx6q-clock.txt > @@ -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: > > diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c > index 4066365..622a299 100644 > --- a/arch/arm/mach-imx/clk-imx6q.c > +++ b/arch/arm/mach-imx/clk-imx6q.c > @@ -153,6 +153,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 > }; > > @@ -163,6 +164,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; > @@ -195,13 +203,22 @@ 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); It gets removed by accident? Otherwise, for the series: Acked-by: Shawn Guo <shawn.guo@linaro.org> > > 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); > diff --git a/arch/arm/mach-imx/clk-pllv3.c b/arch/arm/mach-imx/clk-pllv3.c > index 36aac94..59e7433 100644 > --- a/arch/arm/mach-imx/clk-pllv3.c > +++ b/arch/arm/mach-imx/clk-pllv3.c > @@ -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 = { > -- > 1.7.10.4 > ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/3] ARM i.MX6: Fix ethernet PLL clocks 2012-11-22 11:32 ` Shawn Guo @ 2012-11-22 12:35 ` Sascha Hauer 2014-04-08 11:44 ` Dirk Behme 0 siblings, 1 reply; 9+ messages in thread From: Sascha Hauer @ 2012-11-22 12:35 UTC (permalink / raw) To: linux-arm-kernel On Thu, Nov 22, 2012 at 07:32:28PM +0800, Shawn Guo wrote: > On Thu, Nov 22, 2012 at 10:59:17AM +0100, Sascha Hauer wrote: > > 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> > > --- > > .../devicetree/bindings/clock/imx6q-clock.txt | 5 ++ > > arch/arm/mach-imx/clk-imx6q.c | 21 ++++++- > > arch/arm/mach-imx/clk-pllv3.c | 63 +------------------- > > 3 files changed, 25 insertions(+), 64 deletions(-) > > > > diff --git a/Documentation/devicetree/bindings/clock/imx6q-clock.txt b/Documentation/devicetree/bindings/clock/imx6q-clock.txt > > index bb71d4f..d77b4e6 100644 > > --- a/Documentation/devicetree/bindings/clock/imx6q-clock.txt > > +++ b/Documentation/devicetree/bindings/clock/imx6q-clock.txt > > @@ -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: > > > > diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c > > index 4066365..622a299 100644 > > --- a/arch/arm/mach-imx/clk-imx6q.c > > +++ b/arch/arm/mach-imx/clk-imx6q.c > > @@ -153,6 +153,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 > > }; > > > > @@ -163,6 +164,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; > > @@ -195,13 +203,22 @@ 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); > > It gets removed by accident? Yes, I screwed it up while rebasing. Find an updated version attached. > > Otherwise, for the series: > > Acked-by: Shawn Guo <shawn.guo@linaro.org> Thanks. Sascha 8<---------------------------------------------------- >From 4de7de851c6666c4dca4f36acbc7f9b802ea7d7f Mon Sep 17 00:00:00 2001 From: Sascha Hauer <s.hauer@pengutronix.de> Date: Wed, 21 Nov 2012 14:42:31 +0100 Subject: [PATCH 2/3] ARM i.MX6: Fix ethernet PLL clocks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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> --- .../devicetree/bindings/clock/imx6q-clock.txt | 5 ++ arch/arm/mach-imx/clk-imx6q.c | 20 ++++++- arch/arm/mach-imx/clk-pllv3.c | 63 +------------------- 3 files changed, 25 insertions(+), 63 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/imx6q-clock.txt b/Documentation/devicetree/bindings/clock/imx6q-clock.txt index bb71d4f..d77b4e6 100644 --- a/Documentation/devicetree/bindings/clock/imx6q-clock.txt +++ b/Documentation/devicetree/bindings/clock/imx6q-clock.txt @@ -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: diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 4066365..a579a1c 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -153,6 +153,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 }; @@ -163,6 +164,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; @@ -195,13 +203,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); diff --git a/arch/arm/mach-imx/clk-pllv3.c b/arch/arm/mach-imx/clk-pllv3.c index 36aac94..59e7433 100644 --- a/arch/arm/mach-imx/clk-pllv3.c +++ b/arch/arm/mach-imx/clk-pllv3.c @@ -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 = { -- 1.7.10.4 -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/3] ARM i.MX6: Fix ethernet PLL clocks 2012-11-22 12:35 ` Sascha Hauer @ 2014-04-08 11:44 ` Dirk Behme 2014-04-09 6:59 ` Shawn Guo 0 siblings, 1 reply; 9+ messages in thread From: Dirk Behme @ 2014-04-08 11:44 UTC (permalink / raw) To: linux-arm-kernel Hi Sascha and Shawn, On 22.11.2012 13:35, Sascha Hauer wrote: > On Thu, Nov 22, 2012 at 07:32:28PM +0800, Shawn Guo wrote: >> On Thu, Nov 22, 2012 at 10:59:17AM +0100, Sascha Hauer wrote: >>> 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> >>> --- >>> .../devicetree/bindings/clock/imx6q-clock.txt | 5 ++ >>> arch/arm/mach-imx/clk-imx6q.c | 21 ++++++- >>> arch/arm/mach-imx/clk-pllv3.c | 63 +------------------- >>> 3 files changed, 25 insertions(+), 64 deletions(-) >>> >>> diff --git a/Documentation/devicetree/bindings/clock/imx6q-clock.txt b/Documentation/devicetree/bindings/clock/imx6q-clock.txt >>> index bb71d4f..d77b4e6 100644 >>> --- a/Documentation/devicetree/bindings/clock/imx6q-clock.txt >>> +++ b/Documentation/devicetree/bindings/clock/imx6q-clock.txt >>> @@ -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: >>> >>> diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c >>> index 4066365..622a299 100644 >>> --- a/arch/arm/mach-imx/clk-imx6q.c >>> +++ b/arch/arm/mach-imx/clk-imx6q.c >>> @@ -153,6 +153,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 >>> }; >>> >>> @@ -163,6 +164,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; >>> @@ -195,13 +203,22 @@ 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); >> >> It gets removed by accident? > > Yes, I screwed it up while rebasing. Find an updated version attached. > >> >> Otherwise, for the series: >> >> Acked-by: Shawn Guo <shawn.guo@linaro.org> > > Thanks. > > Sascha > > 8<---------------------------------------------------- > > From 4de7de851c6666c4dca4f36acbc7f9b802ea7d7f Mon Sep 17 00:00:00 2001 > From: Sascha Hauer <s.hauer@pengutronix.de> > Date: Wed, 21 Nov 2012 14:42:31 +0100 > Subject: [PATCH 2/3] ARM i.MX6: Fix ethernet PLL clocks > MIME-Version: 1.0 > Content-Type: text/plain; charset=UTF-8 > Content-Transfer-Encoding: 8bit > > 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> > --- > .../devicetree/bindings/clock/imx6q-clock.txt | 5 ++ > arch/arm/mach-imx/clk-imx6q.c | 20 ++++++- > arch/arm/mach-imx/clk-pllv3.c | 63 +------------------- > 3 files changed, 25 insertions(+), 63 deletions(-) > > diff --git a/Documentation/devicetree/bindings/clock/imx6q-clock.txt b/Documentation/devicetree/bindings/clock/imx6q-clock.txt > index bb71d4f..d77b4e6 100644 > --- a/Documentation/devicetree/bindings/clock/imx6q-clock.txt > +++ b/Documentation/devicetree/bindings/clock/imx6q-clock.txt > @@ -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: > > diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c > index 4066365..a579a1c 100644 > --- a/arch/arm/mach-imx/clk-imx6q.c > +++ b/arch/arm/mach-imx/clk-imx6q.c > @@ -153,6 +153,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 > }; > > @@ -163,6 +164,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; > @@ -195,13 +203,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); > diff --git a/arch/arm/mach-imx/clk-pllv3.c b/arch/arm/mach-imx/clk-pllv3.c > index 36aac94..59e7433 100644 > --- a/arch/arm/mach-imx/clk-pllv3.c > +++ b/arch/arm/mach-imx/clk-pllv3.c > @@ -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; I'm no expert on this, but it seems to be able to use 100MHz or 125Mhz enet clock, you additionally have to set the ENABLE_100M (CCM_ANALOG_PLL_ENET[20]) or ENABLE_125M (CCM_ANALOG_PLL_ENET[19]) bits. Which isn't done by above change, and even worse, it's not possible with switching from dedicated clk_pllv3_enet_set_rate() to the generic ones using the clk_enet_ref_table. Therefore, I've seen people doing 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, phase_shift_flag = 0; switch (rate) { case 25000000: div = 0; break; case 50000000: div = 1; break; case 100000000: div = 2; phase_shift_flag = 0x1 << 20; break; case 125000000: div = 3; phase_shift_flag = 0x1 << 19; break; default: return -EINVAL; } val = readl_relaxed(pll->base); val &= ~pll->div_mask; val |= div; val |= phase_shift_flag; writel_relaxed(val, pll->base); return 0; } again (note the additional phase_shift_flag). What do you think? Best regards Dirk ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/3] ARM i.MX6: Fix ethernet PLL clocks 2014-04-08 11:44 ` Dirk Behme @ 2014-04-09 6:59 ` Shawn Guo 2014-04-09 7:11 ` Dirk Behme 0 siblings, 1 reply; 9+ messages in thread From: Shawn Guo @ 2014-04-09 6:59 UTC (permalink / raw) To: linux-arm-kernel On Tue, Apr 08, 2014 at 01:44:06PM +0200, Dirk Behme wrote: > I'm no expert on this, but it seems to be able to use 100MHz or > 125Mhz enet clock, you additionally have to set the ENABLE_100M > (CCM_ANALOG_PLL_ENET[20]) or ENABLE_125M (CCM_ANALOG_PLL_ENET[19]) > bits. Which isn't done by above change, The following two lines added by the patch should just do. 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); > and even worse, it's not > possible with switching from dedicated clk_pllv3_enet_set_rate() to > the generic ones using the clk_enet_ref_table. Hmm, I'm not sure I understand it. But why not possible? Shawn ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/3] ARM i.MX6: Fix ethernet PLL clocks 2014-04-09 6:59 ` Shawn Guo @ 2014-04-09 7:11 ` Dirk Behme 0 siblings, 0 replies; 9+ messages in thread From: Dirk Behme @ 2014-04-09 7:11 UTC (permalink / raw) To: linux-arm-kernel On 09.04.2014 08:59, Shawn Guo wrote: > On Tue, Apr 08, 2014 at 01:44:06PM +0200, Dirk Behme wrote: >> I'm no expert on this, but it seems to be able to use 100MHz or >> 125Mhz enet clock, you additionally have to set the ENABLE_100M >> (CCM_ANALOG_PLL_ENET[20]) or ENABLE_125M (CCM_ANALOG_PLL_ENET[19]) >> bits. Which isn't done by above change, > > The following two lines added by the patch should just do. > > 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); Many thanks, we'll test that :) It seems that it's unsure at the moment if ENABLE_100M (CCM_ANALOG_PLL_ENET[20]) or ENABLE_125M (CCM_ANALOG_PLL_ENET[19]) are really needed, though ... Many thanks and best regards Dirk ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 3/3] ARM i.MX6: remove gate_mask from pllv3 2012-11-22 9:59 [PATCH] i.MX6 clock Sascha Hauer 2012-11-22 9:59 ` [PATCH 1/3] ARM i.MX6: rename PLLs according to datasheet Sascha Hauer 2012-11-22 9:59 ` [PATCH 2/3] ARM i.MX6: Fix ethernet PLL clocks Sascha Hauer @ 2012-11-22 9:59 ` Sascha Hauer 2 siblings, 0 replies; 9+ messages in thread From: Sascha Hauer @ 2012-11-22 9:59 UTC (permalink / raw) To: linux-arm-kernel Now that the additional enable bits in the enet PLL are handled as gates, the gate_mask is identical for all plls. Remove the gate_mask from the code and use the BM_PLL_ENABLE bit for enabling/disabling the PLL. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- arch/arm/mach-imx/clk-imx6q.c | 16 ++++++++-------- arch/arm/mach-imx/clk-pllv3.c | 9 +++------ arch/arm/mach-imx/clk.h | 3 +-- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 622a299..b7c7ff3 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -197,14 +197,14 @@ int __init mx6q_clocks_init(void) base = of_iomap(np, 0); WARN_ON(!base); - /* type name parent_name base gate_mask div_mask */ - clk[pll1_sys] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x2000, 0x7f); - clk[pll2_bus] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x2000, 0x1); - 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, 0x2000, 0x3); - clk[pll7_usb_host] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host","osc", base + 0x20, 0x2000, 0x3); + /* type name parent_name base div_mask */ + clk[pll1_sys] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x7f); + clk[pll2_bus] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x1); + clk[pll3_usb_otg] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3_usb_otg", "osc", base + 0x10, 0x3); + clk[pll4_audio] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4_audio", "osc", base + 0x70, 0x7f); + clk[pll5_video] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5_video", "osc", base + 0xa0, 0x7f); + clk[pll6_enet] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6_enet", "osc", base + 0xe0, 0x3); + clk[pll7_usb_host] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host","osc", base + 0x20, 0x3); clk[usbphy1] = imx_clk_gate("usbphy1", "pll3_usb_otg", base + 0x10, 6); clk[usbphy2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 6); diff --git a/arch/arm/mach-imx/clk-pllv3.c b/arch/arm/mach-imx/clk-pllv3.c index 59e7433..d09bc3d 100644 --- a/arch/arm/mach-imx/clk-pllv3.c +++ b/arch/arm/mach-imx/clk-pllv3.c @@ -31,7 +31,6 @@ * @clk_hw: clock source * @base: base address of PLL registers * @powerup_set: set POWER bit to power up the PLL - * @gate_mask: mask of gate bits * @div_mask: mask of divider bits * * IMX PLL clock version 3, found on i.MX6 series. Divider for pllv3 @@ -41,7 +40,6 @@ struct clk_pllv3 { struct clk_hw hw; void __iomem *base; bool powerup_set; - u32 gate_mask; u32 div_mask; }; @@ -89,7 +87,7 @@ static int clk_pllv3_enable(struct clk_hw *hw) u32 val; val = readl_relaxed(pll->base); - val |= pll->gate_mask; + val |= BM_PLL_ENABLE; writel_relaxed(val, pll->base); return 0; @@ -101,7 +99,7 @@ static void clk_pllv3_disable(struct clk_hw *hw) u32 val; val = readl_relaxed(pll->base); - val &= ~pll->gate_mask; + val &= ~BM_PLL_ENABLE; writel_relaxed(val, pll->base); } @@ -307,7 +305,7 @@ static const struct clk_ops clk_pllv3_mlb_ops = { struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name, const char *parent_name, void __iomem *base, - u32 gate_mask, u32 div_mask) + u32 div_mask) { struct clk_pllv3 *pll; const struct clk_ops *ops; @@ -339,7 +337,6 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name, ops = &clk_pllv3_ops; } pll->base = base; - pll->gate_mask = gate_mask; pll->div_mask = div_mask; init.name = name; diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h index 5f2d8ac..9d1f3b9 100644 --- a/arch/arm/mach-imx/clk.h +++ b/arch/arm/mach-imx/clk.h @@ -22,8 +22,7 @@ enum imx_pllv3_type { }; struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name, - const char *parent_name, void __iomem *base, u32 gate_mask, - u32 div_mask); + const char *parent_name, void __iomem *base, u32 div_mask); struct clk *clk_register_gate2(struct device *dev, const char *name, const char *parent_name, unsigned long flags, -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 9+ messages in thread
end of thread, other threads:[~2014-04-09 7:11 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-11-22 9:59 [PATCH] i.MX6 clock Sascha Hauer 2012-11-22 9:59 ` [PATCH 1/3] ARM i.MX6: rename PLLs according to datasheet Sascha Hauer 2012-11-22 9:59 ` [PATCH 2/3] ARM i.MX6: Fix ethernet PLL clocks Sascha Hauer 2012-11-22 11:32 ` Shawn Guo 2012-11-22 12:35 ` Sascha Hauer 2014-04-08 11:44 ` Dirk Behme 2014-04-09 6:59 ` Shawn Guo 2014-04-09 7:11 ` Dirk Behme 2012-11-22 9:59 ` [PATCH 3/3] ARM i.MX6: remove gate_mask from pllv3 Sascha Hauer
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).