From ee16bbd289a63e3036d31dcd809e411e9a5dbd5d Mon Sep 17 00:00:00 2001 From: Yakir Yang Date: Fri, 15 Jan 2016 19:54:14 +0800 Subject: clk: rockchip: rk3036: enable the CLK_IGNORE_UNUSED flag for hclk_vio_bus HCLK_VIO_BUS is the noc bus controller clock for display module, due to it shouldn't belong to any driver, but we need it enabled, so just mark it as the CLK_IGNORE_UNUSED flag. Signed-off-by: Yakir Yang Signed-off-by: Heiko Stuebner diff --git a/drivers/clk/rockchip/clk-rk3036.c b/drivers/clk/rockchip/clk-rk3036.c index ebce980..9c317a3 100644 --- a/drivers/clk/rockchip/clk-rk3036.c +++ b/drivers/clk/rockchip/clk-rk3036.c @@ -376,7 +376,7 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { GATE(ACLK_VIO, "aclk_vio", "aclk_disp1_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(6), 13, GFLAGS), GATE(ACLK_LCDC, "aclk_lcdc", "aclk_disp1_pre", 0, RK2928_CLKGATE_CON(9), 6, GFLAGS), - GATE(HCLK_VIO_BUS, "hclk_vio_bus", "hclk_disp_pre", 0, RK2928_CLKGATE_CON(6), 12, GFLAGS), + GATE(HCLK_VIO_BUS, "hclk_vio_bus", "hclk_disp_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(6), 12, GFLAGS), GATE(HCLK_LCDC, "hclk_lcdc", "hclk_disp_pre", 0, RK2928_CLKGATE_CON(9), 5, GFLAGS), /* hclk_video gates */ -- cgit v0.10.2 From 535ebd428aeb07c3327947281306f2943f2c9faa Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Tue, 19 Jan 2016 10:01:08 +0100 Subject: clk: rockchip: rk3368: fix cpuclk mux bit of big cpu-cluster Both clusters have their mux bit in bit 7 of their respective register. For whatever reason the big cluster currently lists bit 15 which is definitly wrong. Fixes: 3536c97a52db ("clk: rockchip: add rk3368 clock controller") Reported-by: Zhang Qing Signed-off-by: Heiko Stuebner Reviewed-by: zhangqing Cc: stable@vger.kernel.org diff --git a/drivers/clk/rockchip/clk-rk3368.c b/drivers/clk/rockchip/clk-rk3368.c index be0ede5..473b36f 100644 --- a/drivers/clk/rockchip/clk-rk3368.c +++ b/drivers/clk/rockchip/clk-rk3368.c @@ -165,7 +165,7 @@ static const struct rockchip_cpuclk_reg_data rk3368_cpuclkb_data = { .core_reg = RK3368_CLKSEL_CON(0), .div_core_shift = 0, .div_core_mask = 0x1f, - .mux_core_shift = 15, + .mux_core_shift = 7, }; static const struct rockchip_cpuclk_reg_data rk3368_cpuclkl_data = { -- cgit v0.10.2 From c6d5fe2ca8286f35a79f7345c9378c39d48a1527 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Tue, 19 Jan 2016 10:09:22 +0100 Subject: clk: rockchip: rk3368: fix cpuclk core dividers Similar to commit 9880d4277f6a ("clk: rockchip: fix rk3288 cpuclk core dividers") it seems the cpuclk dividers are one to high on the rk3368 as well. And again similar to the previous fix, we opt to make the divider list contain the values to be written to use the same paradigm for them on all supported socs. Fixes: 3536c97a52db ("clk: rockchip: add rk3368 clock controller") Reported-by: Zhang Qing Signed-off-by: Heiko Stuebner Reviewed-by: zhangqing Cc: stable@vger.kernel.org diff --git a/drivers/clk/rockchip/clk-rk3368.c b/drivers/clk/rockchip/clk-rk3368.c index 473b36f..82a0c3e 100644 --- a/drivers/clk/rockchip/clk-rk3368.c +++ b/drivers/clk/rockchip/clk-rk3368.c @@ -218,29 +218,29 @@ static const struct rockchip_cpuclk_reg_data rk3368_cpuclkl_data = { } static struct rockchip_cpuclk_rate_table rk3368_cpuclkb_rates[] __initdata = { - RK3368_CPUCLKB_RATE(1512000000, 2, 6, 6), - RK3368_CPUCLKB_RATE(1488000000, 2, 5, 5), - RK3368_CPUCLKB_RATE(1416000000, 2, 5, 5), - RK3368_CPUCLKB_RATE(1200000000, 2, 4, 4), - RK3368_CPUCLKB_RATE(1008000000, 2, 4, 4), - RK3368_CPUCLKB_RATE( 816000000, 2, 3, 3), - RK3368_CPUCLKB_RATE( 696000000, 2, 3, 3), - RK3368_CPUCLKB_RATE( 600000000, 2, 2, 2), - RK3368_CPUCLKB_RATE( 408000000, 2, 2, 2), - RK3368_CPUCLKB_RATE( 312000000, 2, 2, 2), + RK3368_CPUCLKB_RATE(1512000000, 1, 5, 5), + RK3368_CPUCLKB_RATE(1488000000, 1, 4, 4), + RK3368_CPUCLKB_RATE(1416000000, 1, 4, 4), + RK3368_CPUCLKB_RATE(1200000000, 1, 3, 3), + RK3368_CPUCLKB_RATE(1008000000, 1, 3, 3), + RK3368_CPUCLKB_RATE( 816000000, 1, 2, 2), + RK3368_CPUCLKB_RATE( 696000000, 1, 2, 2), + RK3368_CPUCLKB_RATE( 600000000, 1, 1, 1), + RK3368_CPUCLKB_RATE( 408000000, 1, 1, 1), + RK3368_CPUCLKB_RATE( 312000000, 1, 1, 1), }; static struct rockchip_cpuclk_rate_table rk3368_cpuclkl_rates[] __initdata = { - RK3368_CPUCLKL_RATE(1512000000, 2, 7, 7), - RK3368_CPUCLKL_RATE(1488000000, 2, 6, 6), - RK3368_CPUCLKL_RATE(1416000000, 2, 6, 6), - RK3368_CPUCLKL_RATE(1200000000, 2, 5, 5), - RK3368_CPUCLKL_RATE(1008000000, 2, 5, 5), - RK3368_CPUCLKL_RATE( 816000000, 2, 4, 4), - RK3368_CPUCLKL_RATE( 696000000, 2, 3, 3), - RK3368_CPUCLKL_RATE( 600000000, 2, 3, 3), - RK3368_CPUCLKL_RATE( 408000000, 2, 2, 2), - RK3368_CPUCLKL_RATE( 312000000, 2, 2, 2), + RK3368_CPUCLKL_RATE(1512000000, 1, 6, 6), + RK3368_CPUCLKL_RATE(1488000000, 1, 5, 5), + RK3368_CPUCLKL_RATE(1416000000, 1, 5, 5), + RK3368_CPUCLKL_RATE(1200000000, 1, 4, 4), + RK3368_CPUCLKL_RATE(1008000000, 1, 4, 4), + RK3368_CPUCLKL_RATE( 816000000, 1, 3, 3), + RK3368_CPUCLKL_RATE( 696000000, 1, 2, 2), + RK3368_CPUCLKL_RATE( 600000000, 1, 2, 2), + RK3368_CPUCLKL_RATE( 408000000, 1, 1, 1), + RK3368_CPUCLKL_RATE( 312000000, 1, 1, 1), }; static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { -- cgit v0.10.2 From 0f28d98463498c61c61a38aacbf9f69e92e85e9d Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Wed, 20 Jan 2016 19:22:38 +0100 Subject: clk: rockchip: rk3368: fix parents of video encoder/decoder The vdpu and vepu clocks can also be parented to the npll and current parent list also is wrong as it would use the npll as "usbphy" source, so adapt the parent to the correct one. Fixes: 3536c97a52db ("clk: rockchip: add rk3368 clock controller") Signed-off-by: Heiko Stuebner Reviewed-by: zhangqing Cc: stable@vger.kernel.org diff --git a/drivers/clk/rockchip/clk-rk3368.c b/drivers/clk/rockchip/clk-rk3368.c index 82a0c3e..990e1dc 100644 --- a/drivers/clk/rockchip/clk-rk3368.c +++ b/drivers/clk/rockchip/clk-rk3368.c @@ -384,10 +384,10 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { * Clock-Architecture Diagram 3 */ - COMPOSITE(0, "aclk_vepu", mux_pll_src_cpll_gpll_usb_p, 0, + COMPOSITE(0, "aclk_vepu", mux_pll_src_cpll_gpll_npll_usb_p, 0, RK3368_CLKSEL_CON(15), 6, 2, MFLAGS, 0, 5, DFLAGS, RK3368_CLKGATE_CON(4), 6, GFLAGS), - COMPOSITE(0, "aclk_vdpu", mux_pll_src_cpll_gpll_usb_p, 0, + COMPOSITE(0, "aclk_vdpu", mux_pll_src_cpll_gpll_npll_usb_p, 0, RK3368_CLKSEL_CON(15), 14, 2, MFLAGS, 8, 5, DFLAGS, RK3368_CLKGATE_CON(4), 7, GFLAGS), -- cgit v0.10.2 From fd0c0740fac17a014704ef89d8c8b1768711ca59 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Wed, 20 Jan 2016 21:47:57 +0100 Subject: clk: rockchip: rk3368: fix hdmi_cec gate-register Fix a typo making the sclk_hdmi_cec access a wrong register to handle its gate. Fixes: 3536c97a52db ("clk: rockchip: add rk3368 clock controller") Signed-off-by: Heiko Stuebner Reviewed-by: zhangqing Cc: stable@vger.kernel.org diff --git a/drivers/clk/rockchip/clk-rk3368.c b/drivers/clk/rockchip/clk-rk3368.c index 990e1dc..7016ed2 100644 --- a/drivers/clk/rockchip/clk-rk3368.c +++ b/drivers/clk/rockchip/clk-rk3368.c @@ -442,7 +442,7 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { GATE(SCLK_HDMI_HDCP, "sclk_hdmi_hdcp", "xin24m", 0, RK3368_CLKGATE_CON(4), 13, GFLAGS), GATE(SCLK_HDMI_CEC, "sclk_hdmi_cec", "xin32k", 0, - RK3368_CLKGATE_CON(5), 12, GFLAGS), + RK3368_CLKGATE_CON(4), 12, GFLAGS), COMPOSITE_NODIV(0, "vip_src", mux_pll_src_cpll_gpll_p, 0, RK3368_CLKSEL_CON(21), 15, 1, MFLAGS, -- cgit v0.10.2 From 6f31ef2c5c3487fc69c2a34573db88b2f46498ba Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Fri, 8 Jan 2016 17:14:42 -0800 Subject: clk: sunxi: Drop clk.h include This file is a clock provider, not a clk consumer. Drop the clk.h include. Cc: Jens Kuske Cc: Maxime Ripard Signed-off-by: Stephen Boyd Signed-off-by: Maxime Ripard diff --git a/drivers/clk/sunxi/clk-sun8i-bus-gates.c b/drivers/clk/sunxi/clk-sun8i-bus-gates.c index e32d18b..1113eb9 100644 --- a/drivers/clk/sunxi/clk-sun8i-bus-gates.c +++ b/drivers/clk/sunxi/clk-sun8i-bus-gates.c @@ -17,7 +17,6 @@ * GNU General Public License for more details. */ -#include #include #include #include -- cgit v0.10.2 From 63d8c7b9c32004506516f498fa05881c8d258442 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 25 Jan 2016 13:55:00 +0800 Subject: clk: sunxi: usb: Sort clk providers by chip family and name The latest addition of H3 USB clocks placed them at the bottom. Move it before A80 (sun9i), so they are sorted by SoC family then name. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard diff --git a/drivers/clk/sunxi/clk-usb.c b/drivers/clk/sunxi/clk-usb.c index 67b8e38..5432b1c 100644 --- a/drivers/clk/sunxi/clk-usb.c +++ b/drivers/clk/sunxi/clk-usb.c @@ -216,6 +216,18 @@ static void __init sun8i_a23_usb_setup(struct device_node *node) } CLK_OF_DECLARE(sun8i_a23_usb, "allwinner,sun8i-a23-usb-clk", sun8i_a23_usb_setup); +static const struct usb_clk_data sun8i_h3_usb_clk_data __initconst = { + .clk_mask = BIT(19) | BIT(18) | BIT(17) | BIT(16) | + BIT(11) | BIT(10) | BIT(9) | BIT(8), + .reset_mask = BIT(3) | BIT(2) | BIT(1) | BIT(0), +}; + +static void __init sun8i_h3_usb_setup(struct device_node *node) +{ + sunxi_usb_clk_setup(node, &sun8i_h3_usb_clk_data, &sun4i_a10_usb_lock); +} +CLK_OF_DECLARE(sun8i_h3_usb, "allwinner,sun8i-h3-usb-clk", sun8i_h3_usb_setup); + static const struct usb_clk_data sun9i_a80_usb_mod_data __initconst = { .clk_mask = BIT(6) | BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1), .reset_mask = BIT(19) | BIT(18) | BIT(17), @@ -243,15 +255,3 @@ static void __init sun9i_a80_usb_phy_setup(struct device_node *node) sunxi_usb_clk_setup(node, &sun9i_a80_usb_phy_data, &a80_usb_phy_lock); } CLK_OF_DECLARE(sun9i_a80_usb_phy, "allwinner,sun9i-a80-usb-phy-clk", sun9i_a80_usb_phy_setup); - -static const struct usb_clk_data sun8i_h3_usb_clk_data __initconst = { - .clk_mask = BIT(19) | BIT(18) | BIT(17) | BIT(16) | - BIT(11) | BIT(10) | BIT(9) | BIT(8), - .reset_mask = BIT(3) | BIT(2) | BIT(1) | BIT(0), -}; - -static void __init sun8i_h3_usb_setup(struct device_node *node) -{ - sunxi_usb_clk_setup(node, &sun8i_h3_usb_clk_data, &sun4i_a10_usb_lock); -} -CLK_OF_DECLARE(sun8i_h3_usb, "allwinner,sun8i-h3-usb-clk", sun8i_h3_usb_setup); -- cgit v0.10.2 From b7c9b91db202452ed91b0620b80a516093f71715 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Fri, 22 Jan 2016 19:02:29 +0900 Subject: clk: shmobile: r8a7795: Add USB3.0 clocks Signed-off-by: Yoshihiro Shimoda Signed-off-by: Geert Uytterhoeven diff --git a/drivers/clk/shmobile/r8a7795-cpg-mssr.c b/drivers/clk/shmobile/r8a7795-cpg-mssr.c index 13e9947..fc260b3 100644 --- a/drivers/clk/shmobile/r8a7795-cpg-mssr.c +++ b/drivers/clk/shmobile/r8a7795-cpg-mssr.c @@ -122,6 +122,8 @@ static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = { DEF_MOD("scif2", 310, R8A7795_CLK_S3D4), DEF_MOD("pcie1", 318, R8A7795_CLK_S3D1), DEF_MOD("pcie0", 319, R8A7795_CLK_S3D1), + DEF_MOD("usb3-if1", 327, R8A7795_CLK_S3D1), + DEF_MOD("usb3-if0", 328, R8A7795_CLK_S3D1), DEF_MOD("intc-ap", 408, R8A7795_CLK_S3D1), DEF_MOD("audmac0", 502, R8A7795_CLK_S3D4), DEF_MOD("audmac1", 501, R8A7795_CLK_S3D4), -- cgit v0.10.2 From d566ebc3c06c17b108b5b844f9d08259e3b7ba84 Mon Sep 17 00:00:00 2001 From: zhangqing Date: Mon, 25 Jan 2016 08:56:00 -0800 Subject: clk: rockchip: rk3368: fix edp_24m parent The edp_24m parent select bit define is: 1'b0:xin24m 1'b1:1'b0(dummy) so adapt the parent sel bit to the currect one. Signed-off-by: zhangqing Signed-off-by: Heiko Stuebner diff --git a/drivers/clk/rockchip/clk-rk3368.c b/drivers/clk/rockchip/clk-rk3368.c index 7016ed2..dab759b 100644 --- a/drivers/clk/rockchip/clk-rk3368.c +++ b/drivers/clk/rockchip/clk-rk3368.c @@ -121,7 +121,7 @@ PNAME(mux_i2s_2ch_p) = { "i2s_2ch_src", "i2s_2ch_frac", "dummy", "xin12m" }; PNAME(mux_spdif_8ch_p) = { "spdif_8ch_pre", "spdif_8ch_frac", "ext_i2s", "xin12m" }; -PNAME(mux_edp_24m_p) = { "dummy", "xin24m" }; +PNAME(mux_edp_24m_p) = { "xin24m", "dummy" }; PNAME(mux_vip_out_p) = { "vip_src", "xin24m" }; PNAME(mux_usbphy480m_p) = { "usbotg_out", "xin24m" }; PNAME(mux_hsic_usbphy480m_p) = { "usbotg_out", "dummy" }; -- cgit v0.10.2 From 0bbe62eb92755ff7c16c859e96a3877de56e32c9 Mon Sep 17 00:00:00 2001 From: zhangqing Date: Mon, 25 Jan 2016 08:56:01 -0800 Subject: clk: rockchip: rk3368: enable the CLK_SET_RATE_PARENT flag for spdif_8ch SPDIF_8CH set freq need to select parent and calculate parent freq. so just mark it as the CLK_SET_RATE_PARENT flag. Signed-off-by: zhangqing Signed-off-by: Heiko Stuebner diff --git a/drivers/clk/rockchip/clk-rk3368.c b/drivers/clk/rockchip/clk-rk3368.c index dab759b..caf0b94 100644 --- a/drivers/clk/rockchip/clk-rk3368.c +++ b/drivers/clk/rockchip/clk-rk3368.c @@ -353,7 +353,7 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { COMPOSITE_FRAC(0, "spdif_8ch_frac", "spdif_8ch_src", CLK_SET_RATE_PARENT, RK3368_CLKSEL_CON(32), 0, RK3368_CLKGATE_CON(6), 5, GFLAGS), - COMPOSITE_NODIV(SCLK_SPDIF_8CH, "sclk_spdif_8ch", mux_spdif_8ch_p, 0, + COMPOSITE_NODIV(SCLK_SPDIF_8CH, "sclk_spdif_8ch", mux_spdif_8ch_p, CLK_SET_RATE_PARENT, RK3368_CLKSEL_CON(31), 8, 2, MFLAGS, RK3368_CLKGATE_CON(6), 6, GFLAGS), COMPOSITE(0, "i2s_2ch_src", mux_pll_src_cpll_gpll_p, 0, -- cgit v0.10.2 From e8099067de751106d82333e29ce5b6a76ba653f6 Mon Sep 17 00:00:00 2001 From: zhangqing Date: Mon, 25 Jan 2016 08:56:02 -0800 Subject: clk: rockchip: rk3368: enable the CLK_SET_RATE_PARENT flag for i2s_2ch I2S_2CH set freq need to select parent and calculate parent freq. so just mark it as the CLK_SET_RATE_PARENT flag. Signed-off-by: zhangqing Signed-off-by: Heiko Stuebner diff --git a/drivers/clk/rockchip/clk-rk3368.c b/drivers/clk/rockchip/clk-rk3368.c index caf0b94..e90abe8 100644 --- a/drivers/clk/rockchip/clk-rk3368.c +++ b/drivers/clk/rockchip/clk-rk3368.c @@ -362,7 +362,7 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { COMPOSITE_FRAC(0, "i2s_2ch_frac", "i2s_2ch_src", CLK_SET_RATE_PARENT, RK3368_CLKSEL_CON(54), 0, RK3368_CLKGATE_CON(5), 14, GFLAGS), - COMPOSITE_NODIV(SCLK_I2S_2CH, "sclk_i2s_2ch", mux_i2s_2ch_p, 0, + COMPOSITE_NODIV(SCLK_I2S_2CH, "sclk_i2s_2ch", mux_i2s_2ch_p, CLK_SET_RATE_PARENT, RK3368_CLKSEL_CON(53), 8, 2, MFLAGS, RK3368_CLKGATE_CON(5), 15, GFLAGS), -- cgit v0.10.2 From 219a5859c855b1e6e2663eb63a7f942a6bbdfb52 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Thu, 19 Nov 2015 22:22:28 +0100 Subject: clk: rockchip: fix usbphy-related clocks The otgphy clocks really only drive the phy blocks. These in turn contain plls that then generate the 480m clocks the clock controller uses to supply some other clocks like uart0, gpu or the video-codec. So fix this structure to actually respect that hirarchy and removed that usb480m fixed-rate clock working as a placeholder till now, as this wouldn't even work if the supplying phy gets turned off while its pll-output gets used elsewhere. Signed-off-by: Heiko Stuebner Reviewed-by: Douglas Anderson Acked-by: Michael Turquette diff --git a/arch/arm/boot/dts/rk3288-veyron.dtsi b/arch/arm/boot/dts/rk3288-veyron.dtsi index 9fce91f..cb27a8f 100644 --- a/arch/arm/boot/dts/rk3288-veyron.dtsi +++ b/arch/arm/boot/dts/rk3288-veyron.dtsi @@ -421,7 +421,7 @@ status = "okay"; assigned-clocks = <&cru SCLK_USBPHY480M_SRC>; - assigned-clock-parents = <&cru SCLK_OTGPHY0>; + assigned-clock-parents = <&usbphy0>; dr_mode = "host"; }; diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c index 7f7444c..7395490 100644 --- a/drivers/clk/rockchip/clk-rk3188.c +++ b/drivers/clk/rockchip/clk-rk3188.c @@ -343,9 +343,9 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { * the 480m are generated inside the usb block from these clocks, * but they are also a source for the hsicphy clock. */ - GATE(SCLK_OTGPHY0, "sclk_otgphy0", "usb480m", CLK_IGNORE_UNUSED, + GATE(SCLK_OTGPHY0, "sclk_otgphy0", "xin24m", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(1), 5, GFLAGS), - GATE(SCLK_OTGPHY1, "sclk_otgphy1", "usb480m", CLK_IGNORE_UNUSED, + GATE(SCLK_OTGPHY1, "sclk_otgphy1", "xin24m", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(1), 6, GFLAGS), COMPOSITE(0, "mac_src", mux_mac_p, 0, @@ -662,7 +662,7 @@ static struct clk_div_table div_rk3188_aclk_core_t[] = { { /* sentinel */ }, }; -PNAME(mux_hsicphy_p) = { "sclk_otgphy0", "sclk_otgphy1", +PNAME(mux_hsicphy_p) = { "sclk_otgphy0_480m", "sclk_otgphy1_480m", "gpll", "cpll" }; static struct rockchip_clk_branch rk3188_i2s0_fracmux __initdata = @@ -769,11 +769,6 @@ static void __init rk3188_common_clk_init(struct device_node *np) pr_warn("%s: could not register clock xin12m: %ld\n", __func__, PTR_ERR(clk)); - clk = clk_register_fixed_factor(NULL, "usb480m", "xin24m", 0, 20, 1); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock usb480m: %ld\n", - __func__, PTR_ERR(clk)); - rockchip_clk_register_branches(common_clk_branches, ARRAY_SIZE(common_clk_branches)); diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index 984fc18..0d23937 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -195,8 +195,8 @@ PNAME(mux_hsadcout_p) = { "hsadc_src", "ext_hsadc" }; PNAME(mux_edp_24m_p) = { "ext_edp_24m", "xin24m" }; PNAME(mux_tspout_p) = { "cpll", "gpll", "npll", "xin27m" }; -PNAME(mux_usbphy480m_p) = { "sclk_otgphy1", "sclk_otgphy2", - "sclk_otgphy0" }; +PNAME(mux_usbphy480m_p) = { "sclk_otgphy1_480m", "sclk_otgphy2_480m", + "sclk_otgphy0_480m" }; PNAME(mux_hsicphy480m_p) = { "cpll", "gpll", "usbphy480m_src" }; PNAME(mux_hsicphy12m_p) = { "hsicphy12m_xin12m", "hsicphy12m_usbphy" }; @@ -537,11 +537,11 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { RK3288_CLKSEL_CON(35), 6, 2, MFLAGS, 0, 5, DFLAGS, RK3288_CLKGATE_CON(4), 10, GFLAGS), - GATE(SCLK_OTGPHY0, "sclk_otgphy0", "usb480m", CLK_IGNORE_UNUSED, + GATE(SCLK_OTGPHY0, "sclk_otgphy0", "xin24m", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(13), 4, GFLAGS), - GATE(SCLK_OTGPHY1, "sclk_otgphy1", "usb480m", CLK_IGNORE_UNUSED, + GATE(SCLK_OTGPHY1, "sclk_otgphy1", "xin24m", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(13), 5, GFLAGS), - GATE(SCLK_OTGPHY2, "sclk_otgphy2", "usb480m", CLK_IGNORE_UNUSED, + GATE(SCLK_OTGPHY2, "sclk_otgphy2", "xin24m", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(13), 6, GFLAGS), GATE(SCLK_OTG_ADP, "sclk_otg_adp", "xin32k", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(13), 7, GFLAGS), @@ -894,12 +894,6 @@ static void __init rk3288_clk_init(struct device_node *np) pr_warn("%s: could not register clock xin12m: %ld\n", __func__, PTR_ERR(clk)); - - clk = clk_register_fixed_factor(NULL, "usb480m", "xin24m", 0, 20, 1); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock usb480m: %ld\n", - __func__, PTR_ERR(clk)); - clk = clk_register_fixed_factor(NULL, "hclk_vcodec_pre", "hclk_vcodec_pre_v", 0, 1, 4); if (IS_ERR(clk)) -- cgit v0.10.2 From 2c41b5a775dc2a9d04b56ca6b2827025b8bddeb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jarosz?= Date: Tue, 19 Jan 2016 13:09:20 +0100 Subject: clk: rockchip: add tsadc clock on rk3066 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Set clock id for sclk_tsadc gating clock of tsadc in rk3066 Signed-off-by: PaweÅ‚ Jarosz Signed-off-by: Heiko Stuebner diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c index 7395490..3d4f2c6 100644 --- a/drivers/clk/rockchip/clk-rk3188.c +++ b/drivers/clk/rockchip/clk-rk3188.c @@ -605,7 +605,7 @@ static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = { GATE(SCLK_TIMER2, "timer2", "xin24m", 0, RK2928_CLKGATE_CON(3), 2, GFLAGS), - COMPOSITE_NOMUX(0, "sclk_tsadc", "xin24m", 0, + COMPOSITE_NOMUX(SCLK_TSADC, "sclk_tsadc", "xin24m", 0, RK2928_CLKSEL_CON(34), 0, 16, DFLAGS, RK2928_CLKGATE_CON(2), 15, GFLAGS), -- cgit v0.10.2 From e8b63288b37dbb8457b510c9d96f6006da4653f6 Mon Sep 17 00:00:00 2001 From: Alexander Kochetkov Date: Tue, 26 Jan 2016 16:34:00 +0300 Subject: clk: rockchip: add hclk_cpubus to the list of rk3188 critical clocks hclk_cpubus needs to keep running because it is needed for devices like the rom, i2s0 or spdif to be accessible via cpu. Without that all accesses to devices (readl/writel) return wrong data. So add it to the list of critical clocks. Fixes: 78eaf6095cc763c ("clk: rockchip: disable unused clocks") Signed-off-by: Alexander Kochetkov Cc: stable@vger.kernel.org # 4.1.x- Signed-off-by: Heiko Stuebner diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c index 3d4f2c6..cc1d09d 100644 --- a/drivers/clk/rockchip/clk-rk3188.c +++ b/drivers/clk/rockchip/clk-rk3188.c @@ -748,6 +748,7 @@ static const char *const rk3188_critical_clocks[] __initconst = { "hclk_peri", "pclk_cpu", "pclk_peri", + "hclk_cpubus" }; static void __init rk3188_common_clk_init(struct device_node *np) -- cgit v0.10.2 From b3e919e03ce84d9768c0e1c12066f502c5bbd485 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 25 Jan 2016 21:15:38 +0800 Subject: clk: sunxi: factors: Make struct clk_factors_config table const struct clk_factors_config contains shifts/widths for the factors of the factors clk. This is used to read out the factors from the register value. In no case is it written to, so make it const. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c index 59428db..928c079 100644 --- a/drivers/clk/sunxi/clk-factors.c +++ b/drivers/clk/sunxi/clk-factors.c @@ -48,7 +48,7 @@ static unsigned long clk_factors_recalc_rate(struct clk_hw *hw, u32 reg; unsigned long rate; struct clk_factors *factors = to_clk_factors(hw); - struct clk_factors_config *config = factors->config; + const struct clk_factors_config *config = factors->config; /* Fetch the register value */ reg = readl(factors->reg); @@ -123,7 +123,7 @@ static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate, u8 n = 0, k = 0, m = 0, p = 0; u32 reg; struct clk_factors *factors = to_clk_factors(hw); - struct clk_factors_config *config = factors->config; + const struct clk_factors_config *config = factors->config; unsigned long flags = 0; factors->get_factors((u32 *)&rate, (u32)parent_rate, &n, &k, &m, &p); diff --git a/drivers/clk/sunxi/clk-factors.h b/drivers/clk/sunxi/clk-factors.h index 171085a..060319b 100644 --- a/drivers/clk/sunxi/clk-factors.h +++ b/drivers/clk/sunxi/clk-factors.h @@ -23,7 +23,7 @@ struct factors_data { int enable; int mux; int muxmask; - struct clk_factors_config *table; + const struct clk_factors_config *table; void (*getter) (u32 *rate, u32 parent_rate, u8 *n, u8 *k, u8 *m, u8 *p); const char *name; }; @@ -31,7 +31,7 @@ struct factors_data { struct clk_factors { struct clk_hw hw; void __iomem *reg; - struct clk_factors_config *config; + const struct clk_factors_config *config; void (*get_factors) (u32 *rate, u32 parent, u8 *n, u8 *k, u8 *m, u8 *p); spinlock_t *lock; }; diff --git a/drivers/clk/sunxi/clk-mod0.c b/drivers/clk/sunxi/clk-mod0.c index d167e1e..c67fea1 100644 --- a/drivers/clk/sunxi/clk-mod0.c +++ b/drivers/clk/sunxi/clk-mod0.c @@ -62,7 +62,7 @@ static void sun4i_a10_get_mod0_factors(u32 *freq, u32 parent_rate, } /* user manual says "n" but it's really "p" */ -static struct clk_factors_config sun4i_a10_mod0_config = { +static const struct clk_factors_config sun4i_a10_mod0_config = { .mshift = 0, .mwidth = 4, .pshift = 16, diff --git a/drivers/clk/sunxi/clk-sun9i-core.c b/drivers/clk/sunxi/clk-sun9i-core.c index 6c4c983..37c85ca 100644 --- a/drivers/clk/sunxi/clk-sun9i-core.c +++ b/drivers/clk/sunxi/clk-sun9i-core.c @@ -71,7 +71,7 @@ static void sun9i_a80_get_pll4_factors(u32 *freq, u32 parent_rate, *p_ret = p; } -static struct clk_factors_config sun9i_a80_pll4_config = { +static const struct clk_factors_config sun9i_a80_pll4_config = { .mshift = 18, .mwidth = 1, .nshift = 8, @@ -134,7 +134,7 @@ static void sun9i_a80_get_gt_factors(u32 *freq, u32 parent_rate, *m = div; } -static struct clk_factors_config sun9i_a80_gt_config = { +static const struct clk_factors_config sun9i_a80_gt_config = { .mshift = 0, .mwidth = 2, }; @@ -199,7 +199,7 @@ static void sun9i_a80_get_ahb_factors(u32 *freq, u32 parent_rate, *p = _p; } -static struct clk_factors_config sun9i_a80_ahb_config = { +static const struct clk_factors_config sun9i_a80_ahb_config = { .pshift = 0, .pwidth = 2, }; @@ -289,7 +289,7 @@ static void sun9i_a80_get_apb1_factors(u32 *freq, u32 parent_rate, *p = calcp; } -static struct clk_factors_config sun9i_a80_apb1_config = { +static const struct clk_factors_config sun9i_a80_apb1_config = { .mshift = 0, .mwidth = 5, .pshift = 16, diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index 5ba2188..3609f08 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -608,7 +608,7 @@ static void sun7i_a20_get_out_factors(u32 *freq, u32 parent_rate, * sunxi_factors_clk_setup() - Setup function for factor clocks */ -static struct clk_factors_config sun4i_pll1_config = { +static const struct clk_factors_config sun4i_pll1_config = { .nshift = 8, .nwidth = 5, .kshift = 4, @@ -619,7 +619,7 @@ static struct clk_factors_config sun4i_pll1_config = { .pwidth = 2, }; -static struct clk_factors_config sun6i_a31_pll1_config = { +static const struct clk_factors_config sun6i_a31_pll1_config = { .nshift = 8, .nwidth = 5, .kshift = 4, @@ -629,7 +629,7 @@ static struct clk_factors_config sun6i_a31_pll1_config = { .n_start = 1, }; -static struct clk_factors_config sun8i_a23_pll1_config = { +static const struct clk_factors_config sun8i_a23_pll1_config = { .nshift = 8, .nwidth = 5, .kshift = 4, @@ -641,14 +641,14 @@ static struct clk_factors_config sun8i_a23_pll1_config = { .n_start = 1, }; -static struct clk_factors_config sun4i_pll5_config = { +static const struct clk_factors_config sun4i_pll5_config = { .nshift = 8, .nwidth = 5, .kshift = 4, .kwidth = 2, }; -static struct clk_factors_config sun6i_a31_pll6_config = { +static const struct clk_factors_config sun6i_a31_pll6_config = { .nshift = 8, .nwidth = 5, .kshift = 4, @@ -656,12 +656,12 @@ static struct clk_factors_config sun6i_a31_pll6_config = { .n_start = 1, }; -static struct clk_factors_config sun5i_a13_ahb_config = { +static const struct clk_factors_config sun5i_a13_ahb_config = { .pshift = 4, .pwidth = 2, }; -static struct clk_factors_config sun4i_apb1_config = { +static const struct clk_factors_config sun4i_apb1_config = { .mshift = 0, .mwidth = 5, .pshift = 16, @@ -669,7 +669,7 @@ static struct clk_factors_config sun4i_apb1_config = { }; /* user manual says "n" but it's really "p" */ -static struct clk_factors_config sun7i_a20_out_config = { +static const struct clk_factors_config sun7i_a20_out_config = { .mshift = 8, .mwidth = 5, .pshift = 20, -- cgit v0.10.2 From 78ca95c76900e7587d6e076f8162a440f19431ae Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 25 Jan 2016 21:15:39 +0800 Subject: clk: sunxi: factors: Add clk cleanup in sunxi_factors_register() error path sunxi_factors_register() does not check for failures or cleanup after clk_register_composite() or other clk-related calls. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c index 928c079..3a18abf 100644 --- a/drivers/clk/sunxi/clk-factors.c +++ b/drivers/clk/sunxi/clk-factors.c @@ -172,7 +172,7 @@ struct clk *sunxi_factors_register(struct device_node *node, struct clk_hw *mux_hw = NULL; const char *clk_name = node->name; const char *parents[FACTORS_MAX_PARENTS]; - int i = 0; + int ret, i = 0; /* if we have a mux, we will have >1 parents */ i = of_clk_parent_fill(node, parents, FACTORS_MAX_PARENTS); @@ -188,7 +188,7 @@ struct clk *sunxi_factors_register(struct device_node *node, factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL); if (!factors) - return NULL; + goto err_factors; /* set up factors properties */ factors->reg = reg; @@ -199,10 +199,8 @@ struct clk *sunxi_factors_register(struct device_node *node, /* Add a gate if this factor clock can be gated */ if (data->enable) { gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); - if (!gate) { - kfree(factors); - return NULL; - } + if (!gate) + goto err_gate; /* set up gate properties */ gate->reg = reg; @@ -214,11 +212,8 @@ struct clk *sunxi_factors_register(struct device_node *node, /* Add a mux if this factor clock can be muxed */ if (data->mux) { mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL); - if (!mux) { - kfree(factors); - kfree(gate); - return NULL; - } + if (!mux) + goto err_mux; /* set up gate properties */ mux->reg = reg; @@ -233,11 +228,30 @@ struct clk *sunxi_factors_register(struct device_node *node, mux_hw, &clk_mux_ops, &factors->hw, &clk_factors_ops, gate_hw, &clk_gate_ops, 0); + if (IS_ERR(clk)) + goto err_register; - if (!IS_ERR(clk)) { - of_clk_add_provider(node, of_clk_src_simple_get, clk); - clk_register_clkdev(clk, clk_name, NULL); - } + ret = of_clk_add_provider(node, of_clk_src_simple_get, clk); + if (ret) + goto err_provider; + + ret = clk_register_clkdev(clk, clk_name, NULL); + if (ret) + goto err_clkdev; return clk; + +err_clkdev: + of_clk_del_provider(node); +err_provider: + /* TODO: The composite clock stuff will leak a bit here. */ + clk_unregister(clk); +err_register: + kfree(mux); +err_mux: + kfree(gate); +err_gate: + kfree(factors); +err_factors: + return NULL; } -- cgit v0.10.2 From 4cbeaebb8af1c86691d1a2d3328d82a01f4380a5 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 25 Jan 2016 21:15:40 +0800 Subject: clk: sunxi: factors: Add unregister function sunxi's factors clk did not have an unregister function. This means multiple structs were leaked whenever a factors clk was unregistered. Add an unregister function for it. Also keep pointers to the mux and gate structs so they can be freed. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c index 3a18abf..a657117 100644 --- a/drivers/clk/sunxi/clk-factors.c +++ b/drivers/clk/sunxi/clk-factors.c @@ -202,6 +202,8 @@ struct clk *sunxi_factors_register(struct device_node *node, if (!gate) goto err_gate; + factors->gate = gate; + /* set up gate properties */ gate->reg = reg; gate->bit_idx = data->enable; @@ -215,6 +217,8 @@ struct clk *sunxi_factors_register(struct device_node *node, if (!mux) goto err_mux; + factors->mux = mux; + /* set up gate properties */ mux->reg = reg; mux->shift = data->mux; @@ -255,3 +259,24 @@ err_gate: err_factors: return NULL; } + +void sunxi_factors_unregister(struct device_node *node, struct clk *clk) +{ + struct clk_hw *hw = __clk_get_hw(clk); + struct clk_factors *factors; + const char *name; + + if (!hw) + return; + + factors = to_clk_factors(hw); + name = clk_hw_get_name(hw); + + /* No unregister call for clkdev_* */ + of_clk_del_provider(node); + /* TODO: The composite clock stuff will leak a bit here. */ + clk_unregister(clk); + kfree(factors->mux); + kfree(factors->gate); + kfree(factors); +} diff --git a/drivers/clk/sunxi/clk-factors.h b/drivers/clk/sunxi/clk-factors.h index 060319b..7ea1379 100644 --- a/drivers/clk/sunxi/clk-factors.h +++ b/drivers/clk/sunxi/clk-factors.h @@ -34,6 +34,9 @@ struct clk_factors { const struct clk_factors_config *config; void (*get_factors) (u32 *rate, u32 parent, u8 *n, u8 *k, u8 *m, u8 *p); spinlock_t *lock; + /* for cleanup */ + struct clk_mux *mux; + struct clk_gate *gate; }; struct clk *sunxi_factors_register(struct device_node *node, @@ -41,4 +44,6 @@ struct clk *sunxi_factors_register(struct device_node *node, spinlock_t *lock, void __iomem *reg); +void sunxi_factors_unregister(struct device_node *node, struct clk *clk); + #endif -- cgit v0.10.2 From cfa63688603398e8de4315cd626f81516c88a4c4 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 25 Jan 2016 21:15:42 +0800 Subject: clk: sunxi: factors: Consolidate get_factors parameters into a struct The .get_factors callback of factors_clk has 6 parameters. To extend factors_clk in any way that requires adding parameters to .get_factors would make that list even longer, not to mention changing all the function declarations. Do this once now and consolidate all the parameters into a struct. Also drop the space before function pointer arguments, since checkpatch complains. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c index a657117..4a8e36a 100644 --- a/drivers/clk/sunxi/clk-factors.c +++ b/drivers/clk/sunxi/clk-factors.c @@ -73,8 +73,13 @@ static long clk_factors_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *parent_rate) { struct clk_factors *factors = to_clk_factors(hw); - factors->get_factors((u32 *)&rate, (u32)*parent_rate, - NULL, NULL, NULL, NULL); + struct factors_request req = { + .rate = rate, + .parent_rate = *parent_rate, + }; + + factors->get_factors(&req); + return rate; } @@ -120,13 +125,16 @@ static int clk_factors_determine_rate(struct clk_hw *hw, static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { - u8 n = 0, k = 0, m = 0, p = 0; + struct factors_request req = { + .rate = rate, + .parent_rate = parent_rate, + }; u32 reg; struct clk_factors *factors = to_clk_factors(hw); const struct clk_factors_config *config = factors->config; unsigned long flags = 0; - factors->get_factors((u32 *)&rate, (u32)parent_rate, &n, &k, &m, &p); + factors->get_factors(&req); if (factors->lock) spin_lock_irqsave(factors->lock, flags); @@ -135,10 +143,10 @@ static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate, reg = readl(factors->reg); /* Set up the new factors - macros do not do anything if width is 0 */ - reg = FACTOR_SET(config->nshift, config->nwidth, reg, n); - reg = FACTOR_SET(config->kshift, config->kwidth, reg, k); - reg = FACTOR_SET(config->mshift, config->mwidth, reg, m); - reg = FACTOR_SET(config->pshift, config->pwidth, reg, p); + reg = FACTOR_SET(config->nshift, config->nwidth, reg, req.n); + reg = FACTOR_SET(config->kshift, config->kwidth, reg, req.k); + reg = FACTOR_SET(config->mshift, config->mwidth, reg, req.m); + reg = FACTOR_SET(config->pshift, config->pwidth, reg, req.p); /* Apply them now */ writel(reg, factors->reg); diff --git a/drivers/clk/sunxi/clk-factors.h b/drivers/clk/sunxi/clk-factors.h index 7ea1379..f09d7c2 100644 --- a/drivers/clk/sunxi/clk-factors.h +++ b/drivers/clk/sunxi/clk-factors.h @@ -19,12 +19,21 @@ struct clk_factors_config { u8 n_start; }; +struct factors_request { + unsigned long rate; + unsigned long parent_rate; + u8 n; + u8 k; + u8 m; + u8 p; +}; + struct factors_data { int enable; int mux; int muxmask; const struct clk_factors_config *table; - void (*getter) (u32 *rate, u32 parent_rate, u8 *n, u8 *k, u8 *m, u8 *p); + void (*getter)(struct factors_request *req); const char *name; }; @@ -32,7 +41,7 @@ struct clk_factors { struct clk_hw hw; void __iomem *reg; const struct clk_factors_config *config; - void (*get_factors) (u32 *rate, u32 parent, u8 *n, u8 *k, u8 *m, u8 *p); + void (*get_factors)(struct factors_request *req); spinlock_t *lock; /* for cleanup */ struct clk_mux *mux; diff --git a/drivers/clk/sunxi/clk-mod0.c b/drivers/clk/sunxi/clk-mod0.c index c67fea1..578bff0 100644 --- a/drivers/clk/sunxi/clk-mod0.c +++ b/drivers/clk/sunxi/clk-mod0.c @@ -28,17 +28,16 @@ * rate = (parent_rate >> p) / (m + 1); */ -static void sun4i_a10_get_mod0_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun4i_a10_get_mod0_factors(struct factors_request *req) { u8 div, calcm, calcp; /* These clocks can only divide, so we will never be able to achieve * frequencies higher than the parent frequency */ - if (*freq > parent_rate) - *freq = parent_rate; + if (req->rate > req->parent_rate) + req->rate = req->parent_rate; - div = DIV_ROUND_UP(parent_rate, *freq); + div = DIV_ROUND_UP(req->parent_rate, req->rate); if (div < 16) calcp = 0; @@ -51,14 +50,9 @@ static void sun4i_a10_get_mod0_factors(u32 *freq, u32 parent_rate, calcm = DIV_ROUND_UP(div, 1 << calcp); - *freq = (parent_rate >> calcp) / calcm; - - /* we were called to round the frequency, we can now return */ - if (n == NULL) - return; - - *m = calcm - 1; - *p = calcp; + req->rate = (req->parent_rate >> calcp) / calcm; + req->m = calcm - 1; + req->p = calcp; } /* user manual says "n" but it's really "p" */ diff --git a/drivers/clk/sunxi/clk-sun8i-mbus.c b/drivers/clk/sunxi/clk-sun8i-mbus.c index bf117a6..78683f0 100644 --- a/drivers/clk/sunxi/clk-sun8i-mbus.c +++ b/drivers/clk/sunxi/clk-sun8i-mbus.c @@ -26,8 +26,7 @@ * rate = parent_rate / (m + 1); */ -static void sun8i_a23_get_mbus_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun8i_a23_get_mbus_factors(struct factors_request *req) { u8 div; @@ -35,21 +34,16 @@ static void sun8i_a23_get_mbus_factors(u32 *freq, u32 parent_rate, * These clocks can only divide, so we will never be able to * achieve frequencies higher than the parent frequency */ - if (*freq > parent_rate) - *freq = parent_rate; + if (req->rate > req->parent_rate) + req->rate = req->parent_rate; - div = DIV_ROUND_UP(parent_rate, *freq); + div = DIV_ROUND_UP(req->parent_rate, req->rate); if (div > 8) div = 8; - *freq = parent_rate / div; - - /* we were called to round the frequency, we can now return */ - if (m == NULL) - return; - - *m = div - 1; + req->rate = req->parent_rate / div; + req->m = div - 1; } static struct clk_factors_config sun8i_a23_mbus_config = { diff --git a/drivers/clk/sunxi/clk-sun9i-core.c b/drivers/clk/sunxi/clk-sun9i-core.c index 37c85ca..a812110 100644 --- a/drivers/clk/sunxi/clk-sun9i-core.c +++ b/drivers/clk/sunxi/clk-sun9i-core.c @@ -32,15 +32,14 @@ * p and m are named div1 and div2 in Allwinner's SDK */ -static void sun9i_a80_get_pll4_factors(u32 *freq, u32 parent_rate, - u8 *n_ret, u8 *k, u8 *m_ret, u8 *p_ret) +static void sun9i_a80_get_pll4_factors(struct factors_request *req) { int n; int m = 1; int p = 1; /* Normalize value to a 6 MHz multiple (24 MHz / 4) */ - n = DIV_ROUND_UP(*freq, 6000000); + n = DIV_ROUND_UP(req->rate, 6000000); /* If n is too large switch to steps of 12 MHz */ if (n > 255) { @@ -60,15 +59,10 @@ static void sun9i_a80_get_pll4_factors(u32 *freq, u32 parent_rate, else if (n < 12) n = 12; - *freq = ((24000000 * n) >> p) / (m + 1); - - /* we were called to round the frequency, we can now return */ - if (n_ret == NULL) - return; - - *n_ret = n; - *m_ret = m; - *p_ret = p; + req->rate = ((24000000 * n) >> p) / (m + 1); + req->n = n; + req->m = m; + req->p = p; } static const struct clk_factors_config sun9i_a80_pll4_config = { @@ -111,27 +105,21 @@ CLK_OF_DECLARE(sun9i_a80_pll4, "allwinner,sun9i-a80-pll4-clk", sun9i_a80_pll4_se * rate = parent_rate / (m + 1); */ -static void sun9i_a80_get_gt_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun9i_a80_get_gt_factors(struct factors_request *req) { u32 div; - if (parent_rate < *freq) - *freq = parent_rate; + if (req->parent_rate < req->rate) + req->rate = req->parent_rate; - div = DIV_ROUND_UP(parent_rate, *freq); + div = DIV_ROUND_UP(req->parent_rate, req->rate); /* maximum divider is 4 */ if (div > 4) div = 4; - *freq = parent_rate / div; - - /* we were called to round the frequency, we can now return */ - if (!m) - return; - - *m = div; + req->rate = req->parent_rate / div; + req->m = div; } static const struct clk_factors_config sun9i_a80_gt_config = { @@ -176,27 +164,21 @@ CLK_OF_DECLARE(sun9i_a80_gt, "allwinner,sun9i-a80-gt-clk", sun9i_a80_gt_setup); * rate = parent_rate >> p; */ -static void sun9i_a80_get_ahb_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun9i_a80_get_ahb_factors(struct factors_request *req) { u32 _p; - if (parent_rate < *freq) - *freq = parent_rate; + if (req->parent_rate < req->rate) + req->rate = req->parent_rate; - _p = order_base_2(DIV_ROUND_UP(parent_rate, *freq)); + _p = order_base_2(DIV_ROUND_UP(req->parent_rate, req->rate)); /* maximum p is 3 */ if (_p > 3) _p = 3; - *freq = parent_rate >> _p; - - /* we were called to round the frequency, we can now return */ - if (!p) - return; - - *p = _p; + req->rate = req->parent_rate >> _p; + req->p = _p; } static const struct clk_factors_config sun9i_a80_ahb_config = { @@ -262,31 +244,22 @@ CLK_OF_DECLARE(sun9i_a80_apb0, "allwinner,sun9i-a80-apb0-clk", sun9i_a80_apb0_se * rate = (parent_rate >> p) / (m + 1); */ -static void sun9i_a80_get_apb1_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun9i_a80_get_apb1_factors(struct factors_request *req) { u32 div; - u8 calcm, calcp; - if (parent_rate < *freq) - *freq = parent_rate; + if (req->parent_rate < req->rate) + req->rate = req->parent_rate; - div = DIV_ROUND_UP(parent_rate, *freq); + div = DIV_ROUND_UP(req->parent_rate, req->rate); /* Highest possible divider is 256 (p = 3, m = 31) */ if (div > 256) div = 256; - calcp = order_base_2(div); - calcm = (parent_rate >> calcp) - 1; - *freq = (parent_rate >> calcp) / (calcm + 1); - - /* we were called to round the frequency, we can now return */ - if (n == NULL) - return; - - *m = calcm; - *p = calcp; + req->p = order_base_2(div); + req->m = (req->parent_rate >> req->p) - 1; + req->rate = (req->parent_rate >> req->p) / (req->m + 1); } static const struct clk_factors_config sun9i_a80_apb1_config = { diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index 3609f08..a57c36c 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -246,49 +246,45 @@ CLK_OF_DECLARE(sun6i_a31_ahb1, "allwinner,sun6i-a31-ahb1-clk", sun6i_ahb1_clk_se * parent_rate is always 24Mhz */ -static void sun4i_get_pll1_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun4i_get_pll1_factors(struct factors_request *req) { u8 div; /* Normalize value to a 6M multiple */ - div = *freq / 6000000; - *freq = 6000000 * div; - - /* we were called to round the frequency, we can now return */ - if (n == NULL) - return; + div = req->rate / 6000000; + req->rate = 6000000 * div; /* m is always zero for pll1 */ - *m = 0; + req->m = 0; /* k is 1 only on these cases */ - if (*freq >= 768000000 || *freq == 42000000 || *freq == 54000000) - *k = 1; + if (req->rate >= 768000000 || req->rate == 42000000 || + req->rate == 54000000) + req->k = 1; else - *k = 0; + req->k = 0; /* p will be 3 for divs under 10 */ if (div < 10) - *p = 3; + req->p = 3; /* p will be 2 for divs between 10 - 20 and odd divs under 32 */ else if (div < 20 || (div < 32 && (div & 1))) - *p = 2; + req->p = 2; /* p will be 1 for even divs under 32, divs under 40 and odd pairs * of divs between 40-62 */ else if (div < 40 || (div < 64 && (div & 2))) - *p = 1; + req->p = 1; /* any other entries have p = 0 */ else - *p = 0; + req->p = 0; /* calculate a suitable n based on k and p */ - div <<= *p; - div /= (*k + 1); - *n = div / 4; + div <<= req->p; + div /= (req->k + 1); + req->n = div / 4; } /** @@ -297,15 +293,14 @@ static void sun4i_get_pll1_factors(u32 *freq, u32 parent_rate, * rate = parent_rate * (n + 1) * (k + 1) / (m + 1); * parent_rate should always be 24MHz */ -static void sun6i_a31_get_pll1_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun6i_a31_get_pll1_factors(struct factors_request *req) { /* * We can operate only on MHz, this will make our life easier * later. */ - u32 freq_mhz = *freq / 1000000; - u32 parent_freq_mhz = parent_rate / 1000000; + u32 freq_mhz = req->rate / 1000000; + u32 parent_freq_mhz = req->parent_rate / 1000000; /* * Round down the frequency to the closest multiple of either @@ -319,28 +314,20 @@ static void sun6i_a31_get_pll1_factors(u32 *freq, u32 parent_rate, else freq_mhz = round_freq_16; - *freq = freq_mhz * 1000000; - - /* - * If the factors pointer are null, we were just called to - * round down the frequency. - * Exit. - */ - if (n == NULL) - return; + req->rate = freq_mhz * 1000000; /* If the frequency is a multiple of 32 MHz, k is always 3 */ if (!(freq_mhz % 32)) - *k = 3; + req->k = 3; /* If the frequency is a multiple of 9 MHz, k is always 2 */ else if (!(freq_mhz % 9)) - *k = 2; + req->k = 2; /* If the frequency is a multiple of 8 MHz, k is always 1 */ else if (!(freq_mhz % 8)) - *k = 1; + req->k = 1; /* Otherwise, we don't use the k factor */ else - *k = 0; + req->k = 0; /* * If the frequency is a multiple of 2 but not a multiple of @@ -351,27 +338,28 @@ static void sun6i_a31_get_pll1_factors(u32 *freq, u32 parent_rate, * somehow relates to this frequency. */ if ((freq_mhz % 6) == 2 || (freq_mhz % 6) == 4) - *m = 2; + req->m = 2; /* * If the frequency is a multiple of 6MHz, but the factor is * odd, m will be 3 */ else if ((freq_mhz / 6) & 1) - *m = 3; + req->m = 3; /* Otherwise, we end up with m = 1 */ else - *m = 1; + req->m = 1; /* Calculate n thanks to the above factors we already got */ - *n = freq_mhz * (*m + 1) / ((*k + 1) * parent_freq_mhz) - 1; + req->n = freq_mhz * (req->m + 1) / ((req->k + 1) * parent_freq_mhz) + - 1; /* * If n end up being outbound, and that we can still decrease * m, do it. */ - if ((*n + 1) > 31 && (*m + 1) > 1) { - *n = (*n + 1) / 2 - 1; - *m = (*m + 1) / 2 - 1; + if ((req->n + 1) > 31 && (req->m + 1) > 1) { + req->n = (req->n + 1) / 2 - 1; + req->m = (req->m + 1) / 2 - 1; } } @@ -382,45 +370,41 @@ static void sun6i_a31_get_pll1_factors(u32 *freq, u32 parent_rate, * parent_rate is always 24Mhz */ -static void sun8i_a23_get_pll1_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun8i_a23_get_pll1_factors(struct factors_request *req) { u8 div; /* Normalize value to a 6M multiple */ - div = *freq / 6000000; - *freq = 6000000 * div; - - /* we were called to round the frequency, we can now return */ - if (n == NULL) - return; + div = req->rate / 6000000; + req->rate = 6000000 * div; /* m is always zero for pll1 */ - *m = 0; + req->m = 0; /* k is 1 only on these cases */ - if (*freq >= 768000000 || *freq == 42000000 || *freq == 54000000) - *k = 1; + if (req->rate >= 768000000 || req->rate == 42000000 || + req->rate == 54000000) + req->k = 1; else - *k = 0; + req->k = 0; /* p will be 2 for divs under 20 and odd divs under 32 */ if (div < 20 || (div < 32 && (div & 1))) - *p = 2; + req->p = 2; /* p will be 1 for even divs under 32, divs under 40 and odd pairs * of divs between 40-62 */ else if (div < 40 || (div < 64 && (div & 2))) - *p = 1; + req->p = 1; /* any other entries have p = 0 */ else - *p = 0; + req->p = 0; /* calculate a suitable n based on k and p */ - div <<= *p; - div /= (*k + 1); - *n = div / 4 - 1; + div <<= req->p; + div /= (req->k + 1); + req->n = div / 4 - 1; } /** @@ -430,29 +414,24 @@ static void sun8i_a23_get_pll1_factors(u32 *freq, u32 parent_rate, * parent_rate is always 24Mhz */ -static void sun4i_get_pll5_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun4i_get_pll5_factors(struct factors_request *req) { u8 div; /* Normalize value to a parent_rate multiple (24M) */ - div = *freq / parent_rate; - *freq = parent_rate * div; - - /* we were called to round the frequency, we can now return */ - if (n == NULL) - return; + div = req->rate / req->parent_rate; + req->rate = req->parent_rate * div; if (div < 31) - *k = 0; + req->k = 0; else if (div / 2 < 31) - *k = 1; + req->k = 1; else if (div / 3 < 31) - *k = 2; + req->k = 2; else - *k = 3; + req->k = 3; - *n = DIV_ROUND_UP(div, (*k+1)); + req->n = DIV_ROUND_UP(div, (req->k + 1)); } /** @@ -462,24 +441,19 @@ static void sun4i_get_pll5_factors(u32 *freq, u32 parent_rate, * parent_rate is always 24Mhz */ -static void sun6i_a31_get_pll6_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun6i_a31_get_pll6_factors(struct factors_request *req) { u8 div; /* Normalize value to a parent_rate multiple (24M) */ - div = *freq / parent_rate; - *freq = parent_rate * div; + div = req->rate / req->parent_rate; + req->rate = req->parent_rate * div; - /* we were called to round the frequency, we can now return */ - if (n == NULL) - return; - - *k = div / 32; - if (*k > 3) - *k = 3; + req->k = div / 32; + if (req->k > 3) + req->k = 3; - *n = DIV_ROUND_UP(div, (*k+1)) - 1; + req->n = DIV_ROUND_UP(div, (req->k + 1)) - 1; } /** @@ -488,37 +462,32 @@ static void sun6i_a31_get_pll6_factors(u32 *freq, u32 parent_rate, * rate = parent_rate >> p */ -static void sun5i_a13_get_ahb_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun5i_a13_get_ahb_factors(struct factors_request *req) { u32 div; /* divide only */ - if (parent_rate < *freq) - *freq = parent_rate; + if (req->parent_rate < req->rate) + req->rate = req->parent_rate; /* * user manual says valid speed is 8k ~ 276M, but tests show it * can work at speeds up to 300M, just after reparenting to pll6 */ - if (*freq < 8000) - *freq = 8000; - if (*freq > 300000000) - *freq = 300000000; + if (req->rate < 8000) + req->rate = 8000; + if (req->rate > 300000000) + req->rate = 300000000; - div = order_base_2(DIV_ROUND_UP(parent_rate, *freq)); + div = order_base_2(DIV_ROUND_UP(req->parent_rate, req->rate)); /* p = 0 ~ 3 */ if (div > 3) div = 3; - *freq = parent_rate >> div; + req->rate = req->parent_rate >> div; - /* we were called to round the frequency, we can now return */ - if (p == NULL) - return; - - *p = div; + req->p = div; } /** @@ -527,39 +496,34 @@ static void sun5i_a13_get_ahb_factors(u32 *freq, u32 parent_rate, * rate = (parent_rate >> p) / (m + 1); */ -static void sun4i_get_apb1_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun4i_get_apb1_factors(struct factors_request *req) { u8 calcm, calcp; + int div; - if (parent_rate < *freq) - *freq = parent_rate; + if (req->parent_rate < req->rate) + req->rate = req->parent_rate; - parent_rate = DIV_ROUND_UP(parent_rate, *freq); + div = DIV_ROUND_UP(req->parent_rate, req->rate); /* Invalid rate! */ - if (parent_rate > 32) + if (div > 32) return; - if (parent_rate <= 4) + if (div <= 4) calcp = 0; - else if (parent_rate <= 8) + else if (div <= 8) calcp = 1; - else if (parent_rate <= 16) + else if (div <= 16) calcp = 2; else calcp = 3; - calcm = (parent_rate >> calcp) - 1; - - *freq = (parent_rate >> calcp) / (calcm + 1); + calcm = (req->parent_rate >> calcp) - 1; - /* we were called to round the frequency, we can now return */ - if (n == NULL) - return; - - *m = calcm; - *p = calcp; + req->rate = (req->parent_rate >> calcp) / (calcm + 1); + req->m = calcm; + req->p = calcp; } @@ -571,17 +535,16 @@ static void sun4i_get_apb1_factors(u32 *freq, u32 parent_rate, * rate = (parent_rate >> p) / (m + 1); */ -static void sun7i_a20_get_out_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun7i_a20_get_out_factors(struct factors_request *req) { u8 div, calcm, calcp; /* These clocks can only divide, so we will never be able to achieve * frequencies higher than the parent frequency */ - if (*freq > parent_rate) - *freq = parent_rate; + if (req->rate > req->parent_rate) + req->rate = req->parent_rate; - div = DIV_ROUND_UP(parent_rate, *freq); + div = DIV_ROUND_UP(req->parent_rate, req->rate); if (div < 32) calcp = 0; @@ -594,14 +557,9 @@ static void sun7i_a20_get_out_factors(u32 *freq, u32 parent_rate, calcm = DIV_ROUND_UP(div, 1 << calcp); - *freq = (parent_rate >> calcp) / calcm; - - /* we were called to round the frequency, we can now return */ - if (n == NULL) - return; - - *m = calcm - 1; - *p = calcp; + req->rate = (req->parent_rate >> calcp) / calcm; + req->m = calcm - 1; + req->p = calcp; } /** -- cgit v0.10.2 From bb07698fc8d13ec74f4f5bd87b04953777ee6982 Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Tue, 26 Jan 2016 11:30:18 +0800 Subject: clk: rockchip: fix wrong mmc phase shift for rk3228 mmc sample shift is 0 for rk3228 refer to user manaul. So it's broken if we enable mmc tuning for rk3228. Fixes: 307a2e9ac ("clk: rockchip: add clock controller for rk3228") Signed-off-by: Shawn Lin Reviewed-by: Xing Zheng Signed-off-by: Heiko Stuebner diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c index 981a502..97f49aa 100644 --- a/drivers/clk/rockchip/clk-rk3228.c +++ b/drivers/clk/rockchip/clk-rk3228.c @@ -605,13 +605,13 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { /* PD_MMC */ MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "sclk_sdmmc", RK3228_SDMMC_CON0, 1), - MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "sclk_sdmmc", RK3228_SDMMC_CON1, 1), + MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "sclk_sdmmc", RK3228_SDMMC_CON1, 0), MMC(SCLK_SDIO_DRV, "sdio_drv", "sclk_sdio", RK3228_SDIO_CON0, 1), - MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "sclk_sdio", RK3228_SDIO_CON1, 1), + MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "sclk_sdio", RK3228_SDIO_CON1, 0), MMC(SCLK_EMMC_DRV, "emmc_drv", "sclk_emmc", RK3228_EMMC_CON0, 1), - MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "sclk_emmc", RK3228_EMMC_CON1, 1), + MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "sclk_emmc", RK3228_EMMC_CON1, 0), }; static const char *const rk3228_critical_clocks[] __initconst = { -- cgit v0.10.2 From 89aa027e6019d6e631a6c18c877e01f890a1800f Mon Sep 17 00:00:00 2001 From: Alexander Kochetkov Date: Fri, 29 Jan 2016 10:58:02 +0300 Subject: clk: rockchip: Allow sclk_i2s0 and i2s0_frac to change their parents rate on rk3188 Allow sclk_i2s0 and i2s0_frac to change their parents rate as that the upstream dividers are purely there to feed sclk_i2s0 Tested on radxarock-lite. Signed-off-by: Alexander Kochetkov Signed-off-by: Heiko Stuebner diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c index cc1d09d..629c65d 100644 --- a/drivers/clk/rockchip/clk-rk3188.c +++ b/drivers/clk/rockchip/clk-rk3188.c @@ -666,7 +666,7 @@ PNAME(mux_hsicphy_p) = { "sclk_otgphy0_480m", "sclk_otgphy1_480m", "gpll", "cpll" }; static struct rockchip_clk_branch rk3188_i2s0_fracmux __initdata = - MUX(SCLK_I2S0, "sclk_i2s0", mux_sclk_i2s0_p, 0, + MUX(SCLK_I2S0, "sclk_i2s0", mux_sclk_i2s0_p, CLK_SET_RATE_PARENT, RK2928_CLKSEL_CON(3), 8, 2, MFLAGS); static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = { @@ -722,7 +722,7 @@ static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = { COMPOSITE_NOMUX(0, "i2s0_pre", "i2s_src", 0, RK2928_CLKSEL_CON(3), 0, 7, DFLAGS, RK2928_CLKGATE_CON(0), 9, GFLAGS), - COMPOSITE_FRACMUX(0, "i2s0_frac", "i2s0_pre", 0, + COMPOSITE_FRACMUX(0, "i2s0_frac", "i2s0_pre", CLK_SET_RATE_PARENT, RK2928_CLKSEL_CON(7), 0, RK2928_CLKGATE_CON(0), 10, GFLAGS, &rk3188_i2s0_fracmux), -- cgit v0.10.2 From 435b7be1d812cdbbad997f5279293770dff21abb Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 25 Jan 2016 21:15:43 +0800 Subject: clk: sunxi: factors: Support custom formulas Some clocks cannot be modelled using the standard factors clk formula, such as clocks with special pre-dividers on one parent, or clocks with all power-of-two dividers. Add support for a custom .recalc callback for factors clk. Also pass the current parent index to the .get_factor and .recalc callbacks. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c index 4a8e36a..2927b09 100644 --- a/drivers/clk/sunxi/clk-factors.c +++ b/drivers/clk/sunxi/clk-factors.c @@ -63,6 +63,26 @@ static unsigned long clk_factors_recalc_rate(struct clk_hw *hw, if (config->pwidth != SUNXI_FACTORS_NOT_APPLICABLE) p = FACTOR_GET(config->pshift, config->pwidth, reg); + if (factors->recalc) { + struct factors_request factors_req = { + .parent_rate = parent_rate, + .n = n, + .k = k, + .m = m, + .p = p, + }; + + /* get mux details from mux clk structure */ + if (factors->mux) + factors_req.parent_index = + (reg >> factors->mux->shift) & + factors->mux->mask; + + factors->recalc(&factors_req); + + return factors_req.rate; + } + /* Calculate the rate */ rate = (parent_rate * (n + config->n_start) * (k + 1) >> p) / (m + 1); @@ -87,6 +107,7 @@ static long clk_factors_round_rate(struct clk_hw *hw, unsigned long rate, static int clk_factors_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { + struct clk_factors *factors = to_clk_factors(hw); struct clk_hw *parent, *best_parent = NULL; int i, num_parents; unsigned long parent_rate, best = 0, child_rate, best_child_rate = 0; @@ -94,6 +115,10 @@ static int clk_factors_determine_rate(struct clk_hw *hw, /* find the parent that can help provide the fastest rate <= rate */ num_parents = clk_hw_get_num_parents(hw); for (i = 0; i < num_parents; i++) { + struct factors_request factors_req = { + .rate = req->rate, + .parent_index = i, + }; parent = clk_hw_get_parent_by_index(hw, i); if (!parent) continue; @@ -102,8 +127,9 @@ static int clk_factors_determine_rate(struct clk_hw *hw, else parent_rate = clk_hw_get_rate(parent); - child_rate = clk_factors_round_rate(hw, req->rate, - &parent_rate); + factors_req.parent_rate = parent_rate; + factors->get_factors(&factors_req); + child_rate = factors_req.rate; if (child_rate <= req->rate && child_rate > best_child_rate) { best_parent = parent; @@ -202,6 +228,7 @@ struct clk *sunxi_factors_register(struct device_node *node, factors->reg = reg; factors->config = data->table; factors->get_factors = data->getter; + factors->recalc = data->recalc; factors->lock = lock; /* Add a gate if this factor clock can be gated */ diff --git a/drivers/clk/sunxi/clk-factors.h b/drivers/clk/sunxi/clk-factors.h index f09d7c2..a44a865 100644 --- a/drivers/clk/sunxi/clk-factors.h +++ b/drivers/clk/sunxi/clk-factors.h @@ -22,6 +22,7 @@ struct clk_factors_config { struct factors_request { unsigned long rate; unsigned long parent_rate; + u8 parent_index; u8 n; u8 k; u8 m; @@ -34,6 +35,7 @@ struct factors_data { int muxmask; const struct clk_factors_config *table; void (*getter)(struct factors_request *req); + void (*recalc)(struct factors_request *req); const char *name; }; @@ -42,6 +44,7 @@ struct clk_factors { void __iomem *reg; const struct clk_factors_config *config; void (*get_factors)(struct factors_request *req); + void (*recalc)(struct factors_request *req); spinlock_t *lock; /* for cleanup */ struct clk_mux *mux; -- cgit v0.10.2 From 50d6ea47bab46645f28c439d9d8fb4840e10b486 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 25 Jan 2016 21:15:44 +0800 Subject: clk: sunxi: factors: Drop round_rate from clk ops The common clock framework requires either determine_rate or round_rate to be implemented. We use determine_rate so we can pass the parent index to the get_factors callback. This cannot be done easily with round_rate, so just drop it. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c index 2927b09..6e97f46 100644 --- a/drivers/clk/sunxi/clk-factors.c +++ b/drivers/clk/sunxi/clk-factors.c @@ -89,21 +89,6 @@ static unsigned long clk_factors_recalc_rate(struct clk_hw *hw, return rate; } -static long clk_factors_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) -{ - struct clk_factors *factors = to_clk_factors(hw); - struct factors_request req = { - .rate = rate, - .parent_rate = *parent_rate, - }; - - factors->get_factors(&req); - - - return rate; -} - static int clk_factors_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { @@ -189,7 +174,6 @@ static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops clk_factors_ops = { .determine_rate = clk_factors_determine_rate, .recalc_rate = clk_factors_recalc_rate, - .round_rate = clk_factors_round_rate, .set_rate = clk_factors_set_rate, }; -- cgit v0.10.2 From a78bb35552a800949b2bf68f372d3d6ccabdd790 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 25 Jan 2016 21:15:45 +0800 Subject: clk: sunxi: rewrite sun6i-a31-ahb1-clk using factors clk with custom recalc The factors clk implementation has been extended to support custom recalc callbacks to support clocks that use one factor for certain parents only, like a pre-divider. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index a57c36c..da15f2b 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -28,214 +28,6 @@ static DEFINE_SPINLOCK(clk_lock); -/** - * sun6i_a31_ahb1_clk_setup() - Setup function for a31 ahb1 composite clk - */ - -#define SUN6I_AHB1_MAX_PARENTS 4 -#define SUN6I_AHB1_MUX_PARENT_PLL6 3 -#define SUN6I_AHB1_MUX_SHIFT 12 -/* un-shifted mask is what mux_clk expects */ -#define SUN6I_AHB1_MUX_MASK 0x3 -#define SUN6I_AHB1_MUX_GET_PARENT(reg) ((reg >> SUN6I_AHB1_MUX_SHIFT) & \ - SUN6I_AHB1_MUX_MASK) - -#define SUN6I_AHB1_DIV_SHIFT 4 -#define SUN6I_AHB1_DIV_MASK (0x3 << SUN6I_AHB1_DIV_SHIFT) -#define SUN6I_AHB1_DIV_GET(reg) ((reg & SUN6I_AHB1_DIV_MASK) >> \ - SUN6I_AHB1_DIV_SHIFT) -#define SUN6I_AHB1_DIV_SET(reg, div) ((reg & ~SUN6I_AHB1_DIV_MASK) | \ - (div << SUN6I_AHB1_DIV_SHIFT)) -#define SUN6I_AHB1_PLL6_DIV_SHIFT 6 -#define SUN6I_AHB1_PLL6_DIV_MASK (0x3 << SUN6I_AHB1_PLL6_DIV_SHIFT) -#define SUN6I_AHB1_PLL6_DIV_GET(reg) ((reg & SUN6I_AHB1_PLL6_DIV_MASK) >> \ - SUN6I_AHB1_PLL6_DIV_SHIFT) -#define SUN6I_AHB1_PLL6_DIV_SET(reg, div) ((reg & ~SUN6I_AHB1_PLL6_DIV_MASK) | \ - (div << SUN6I_AHB1_PLL6_DIV_SHIFT)) - -struct sun6i_ahb1_clk { - struct clk_hw hw; - void __iomem *reg; -}; - -#define to_sun6i_ahb1_clk(_hw) container_of(_hw, struct sun6i_ahb1_clk, hw) - -static unsigned long sun6i_ahb1_clk_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct sun6i_ahb1_clk *ahb1 = to_sun6i_ahb1_clk(hw); - unsigned long rate; - u32 reg; - - /* Fetch the register value */ - reg = readl(ahb1->reg); - - /* apply pre-divider first if parent is pll6 */ - if (SUN6I_AHB1_MUX_GET_PARENT(reg) == SUN6I_AHB1_MUX_PARENT_PLL6) - parent_rate /= SUN6I_AHB1_PLL6_DIV_GET(reg) + 1; - - /* clk divider */ - rate = parent_rate >> SUN6I_AHB1_DIV_GET(reg); - - return rate; -} - -static long sun6i_ahb1_clk_round(unsigned long rate, u8 *divp, u8 *pre_divp, - u8 parent, unsigned long parent_rate) -{ - u8 div, calcp, calcm = 1; - - /* - * clock can only divide, so we will never be able to achieve - * frequencies higher than the parent frequency - */ - if (parent_rate && rate > parent_rate) - rate = parent_rate; - - div = DIV_ROUND_UP(parent_rate, rate); - - /* calculate pre-divider if parent is pll6 */ - if (parent == SUN6I_AHB1_MUX_PARENT_PLL6) { - if (div < 4) - calcp = 0; - else if (div / 2 < 4) - calcp = 1; - else if (div / 4 < 4) - calcp = 2; - else - calcp = 3; - - calcm = DIV_ROUND_UP(div, 1 << calcp); - } else { - calcp = __roundup_pow_of_two(div); - calcp = calcp > 3 ? 3 : calcp; - } - - /* we were asked to pass back divider values */ - if (divp) { - *divp = calcp; - *pre_divp = calcm - 1; - } - - return (parent_rate / calcm) >> calcp; -} - -static int sun6i_ahb1_clk_determine_rate(struct clk_hw *hw, - struct clk_rate_request *req) -{ - struct clk_hw *parent, *best_parent = NULL; - int i, num_parents; - unsigned long parent_rate, best = 0, child_rate, best_child_rate = 0; - - /* find the parent that can help provide the fastest rate <= rate */ - num_parents = clk_hw_get_num_parents(hw); - for (i = 0; i < num_parents; i++) { - parent = clk_hw_get_parent_by_index(hw, i); - if (!parent) - continue; - if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) - parent_rate = clk_hw_round_rate(parent, req->rate); - else - parent_rate = clk_hw_get_rate(parent); - - child_rate = sun6i_ahb1_clk_round(req->rate, NULL, NULL, i, - parent_rate); - - if (child_rate <= req->rate && child_rate > best_child_rate) { - best_parent = parent; - best = parent_rate; - best_child_rate = child_rate; - } - } - - if (!best_parent) - return -EINVAL; - - req->best_parent_hw = best_parent; - req->best_parent_rate = best; - req->rate = best_child_rate; - - return 0; -} - -static int sun6i_ahb1_clk_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct sun6i_ahb1_clk *ahb1 = to_sun6i_ahb1_clk(hw); - unsigned long flags; - u8 div, pre_div, parent; - u32 reg; - - spin_lock_irqsave(&clk_lock, flags); - - reg = readl(ahb1->reg); - - /* need to know which parent is used to apply pre-divider */ - parent = SUN6I_AHB1_MUX_GET_PARENT(reg); - sun6i_ahb1_clk_round(rate, &div, &pre_div, parent, parent_rate); - - reg = SUN6I_AHB1_DIV_SET(reg, div); - reg = SUN6I_AHB1_PLL6_DIV_SET(reg, pre_div); - writel(reg, ahb1->reg); - - spin_unlock_irqrestore(&clk_lock, flags); - - return 0; -} - -static const struct clk_ops sun6i_ahb1_clk_ops = { - .determine_rate = sun6i_ahb1_clk_determine_rate, - .recalc_rate = sun6i_ahb1_clk_recalc_rate, - .set_rate = sun6i_ahb1_clk_set_rate, -}; - -static void __init sun6i_ahb1_clk_setup(struct device_node *node) -{ - struct clk *clk; - struct sun6i_ahb1_clk *ahb1; - struct clk_mux *mux; - const char *clk_name = node->name; - const char *parents[SUN6I_AHB1_MAX_PARENTS]; - void __iomem *reg; - int i; - - reg = of_io_request_and_map(node, 0, of_node_full_name(node)); - if (IS_ERR(reg)) - return; - - /* we have a mux, we will have >1 parents */ - i = of_clk_parent_fill(node, parents, SUN6I_AHB1_MAX_PARENTS); - of_property_read_string(node, "clock-output-names", &clk_name); - - ahb1 = kzalloc(sizeof(struct sun6i_ahb1_clk), GFP_KERNEL); - if (!ahb1) - return; - - mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL); - if (!mux) { - kfree(ahb1); - return; - } - - /* set up clock properties */ - mux->reg = reg; - mux->shift = SUN6I_AHB1_MUX_SHIFT; - mux->mask = SUN6I_AHB1_MUX_MASK; - mux->lock = &clk_lock; - ahb1->reg = reg; - - clk = clk_register_composite(NULL, clk_name, parents, i, - &mux->hw, &clk_mux_ops, - &ahb1->hw, &sun6i_ahb1_clk_ops, - NULL, NULL, 0); - - if (!IS_ERR(clk)) { - of_clk_add_provider(node, of_clk_src_simple_get, clk); - clk_register_clkdev(clk, clk_name, NULL); - } -} -CLK_OF_DECLARE(sun6i_a31_ahb1, "allwinner,sun6i-a31-ahb1-clk", sun6i_ahb1_clk_setup); - /* Maximum number of parents our clocks have */ #define SUNXI_MAX_PARENTS 5 @@ -490,6 +282,68 @@ static void sun5i_a13_get_ahb_factors(struct factors_request *req) req->p = div; } +#define SUN6I_AHB1_PARENT_PLL6 3 + +/** + * sun6i_a31_get_ahb_factors() - calculates m, p factors for AHB + * AHB rate is calculated as follows + * rate = parent_rate >> p + * + * if parent is pll6, then + * parent_rate = pll6 rate / (m + 1) + */ + +static void sun6i_get_ahb1_factors(struct factors_request *req) +{ + u8 div, calcp, calcm = 1; + + /* + * clock can only divide, so we will never be able to achieve + * frequencies higher than the parent frequency + */ + if (req->parent_rate && req->rate > req->parent_rate) + req->rate = req->parent_rate; + + div = DIV_ROUND_UP(req->parent_rate, req->rate); + + /* calculate pre-divider if parent is pll6 */ + if (req->parent_index == SUN6I_AHB1_PARENT_PLL6) { + if (div < 4) + calcp = 0; + else if (div / 2 < 4) + calcp = 1; + else if (div / 4 < 4) + calcp = 2; + else + calcp = 3; + + calcm = DIV_ROUND_UP(div, 1 << calcp); + } else { + calcp = __roundup_pow_of_two(div); + calcp = calcp > 3 ? 3 : calcp; + } + + req->rate = (req->parent_rate / calcm) >> calcp; + req->p = calcp; + req->m = calcm - 1; +} + +/** + * sun6i_ahb1_recalc() - calculates AHB clock rate from m, p factors and + * parent index + */ +static void sun6i_ahb1_recalc(struct factors_request *req) +{ + req->rate = req->parent_rate; + + /* apply pre-divider first if parent is pll6 */ + if (req->parent_index == SUN6I_AHB1_PARENT_PLL6) + req->rate /= req->m + 1; + + /* clk divider */ + req->rate >>= req->p; +} + /** * sun4i_get_apb1_factors() - calculates m, p factors for APB1 * APB1 rate is calculated as follows @@ -619,6 +473,13 @@ static const struct clk_factors_config sun5i_a13_ahb_config = { .pwidth = 2, }; +static const struct clk_factors_config sun6i_ahb1_config = { + .mshift = 6, + .mwidth = 2, + .pshift = 4, + .pwidth = 2, +}; + static const struct clk_factors_config sun4i_apb1_config = { .mshift = 0, .mwidth = 5, @@ -686,6 +547,14 @@ static const struct factors_data sun5i_a13_ahb_data __initconst = { .getter = sun5i_a13_get_ahb_factors, }; +static const struct factors_data sun6i_ahb1_data __initconst = { + .mux = 12, + .muxmask = BIT(1) | BIT(0), + .table = &sun6i_ahb1_config, + .getter = sun6i_get_ahb1_factors, + .recalc = sun6i_ahb1_recalc, +}; + static const struct factors_data sun4i_apb1_data __initconst = { .mux = 24, .muxmask = BIT(1) | BIT(0), @@ -716,6 +585,12 @@ static struct clk * __init sunxi_factors_clk_setup(struct device_node *node, return sunxi_factors_register(node, data, &clk_lock, reg); } +static void __init sun6i_ahb1_clk_setup(struct device_node *node) +{ + sunxi_factors_clk_setup(node, &sun6i_ahb1_data); +} +CLK_OF_DECLARE(sun6i_a31_ahb1, "allwinner,sun6i-a31-ahb1-clk", + sun6i_ahb1_clk_setup); /** -- cgit v0.10.2 From 3ca2377b6fed7c3db0c064ea73327cc6895e175d Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 25 Jan 2016 21:15:46 +0800 Subject: clk: sunxi: rewrite sun6i-ar100 using factors clk sun6i's AR100 clock is a classic factors clk case: AR100 = ((parent mux) >> p) / (m + 1) Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard diff --git a/drivers/clk/sunxi/clk-sun6i-ar100.c b/drivers/clk/sunxi/clk-sun6i-ar100.c index 2088768..a7f5777 100644 --- a/drivers/clk/sunxi/clk-sun6i-ar100.c +++ b/drivers/clk/sunxi/clk-sun6i-ar100.c @@ -8,211 +8,97 @@ * */ +#include #include #include #include #include +#include -#define SUN6I_AR100_MAX_PARENTS 4 -#define SUN6I_AR100_SHIFT_MASK 0x3 -#define SUN6I_AR100_SHIFT_MAX SUN6I_AR100_SHIFT_MASK -#define SUN6I_AR100_SHIFT_SHIFT 4 -#define SUN6I_AR100_DIV_MASK 0x1f -#define SUN6I_AR100_DIV_MAX (SUN6I_AR100_DIV_MASK + 1) -#define SUN6I_AR100_DIV_SHIFT 8 -#define SUN6I_AR100_MUX_MASK 0x3 -#define SUN6I_AR100_MUX_SHIFT 16 - -struct ar100_clk { - struct clk_hw hw; - void __iomem *reg; -}; - -static inline struct ar100_clk *to_ar100_clk(struct clk_hw *hw) -{ - return container_of(hw, struct ar100_clk, hw); -} - -static unsigned long ar100_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct ar100_clk *clk = to_ar100_clk(hw); - u32 val = readl(clk->reg); - int shift = (val >> SUN6I_AR100_SHIFT_SHIFT) & SUN6I_AR100_SHIFT_MASK; - int div = (val >> SUN6I_AR100_DIV_SHIFT) & SUN6I_AR100_DIV_MASK; - - return (parent_rate >> shift) / (div + 1); -} - -static int ar100_determine_rate(struct clk_hw *hw, - struct clk_rate_request *req) -{ - int nparents = clk_hw_get_num_parents(hw); - long best_rate = -EINVAL; - int i; - - req->best_parent_hw = NULL; - - for (i = 0; i < nparents; i++) { - unsigned long parent_rate; - unsigned long tmp_rate; - struct clk_hw *parent; - unsigned long div; - int shift; - - parent = clk_hw_get_parent_by_index(hw, i); - parent_rate = clk_hw_get_rate(parent); - div = DIV_ROUND_UP(parent_rate, req->rate); - - /* - * The AR100 clk contains 2 divisors: - * - one power of 2 divisor - * - one regular divisor - * - * First check if we can safely shift (or divide by a power - * of 2) without losing precision on the requested rate. - */ - shift = ffs(div) - 1; - if (shift > SUN6I_AR100_SHIFT_MAX) - shift = SUN6I_AR100_SHIFT_MAX; - - div >>= shift; - - /* - * Then if the divisor is still bigger than what the HW - * actually supports, use a bigger shift (or power of 2 - * divider) value and accept to lose some precision. - */ - while (div > SUN6I_AR100_DIV_MAX) { - shift++; - div >>= 1; - if (shift > SUN6I_AR100_SHIFT_MAX) - break; - } - - /* - * If the shift value (or power of 2 divider) is bigger - * than what the HW actually support, skip this parent. - */ - if (shift > SUN6I_AR100_SHIFT_MAX) - continue; - - tmp_rate = (parent_rate >> shift) / div; - if (!req->best_parent_hw || tmp_rate > best_rate) { - req->best_parent_hw = parent; - req->best_parent_rate = parent_rate; - best_rate = tmp_rate; - } - } - - if (best_rate < 0) - return best_rate; - - req->rate = best_rate; - - return 0; -} - -static int ar100_set_parent(struct clk_hw *hw, u8 index) -{ - struct ar100_clk *clk = to_ar100_clk(hw); - u32 val = readl(clk->reg); - - if (index >= SUN6I_AR100_MAX_PARENTS) - return -EINVAL; - - val &= ~(SUN6I_AR100_MUX_MASK << SUN6I_AR100_MUX_SHIFT); - val |= (index << SUN6I_AR100_MUX_SHIFT); - writel(val, clk->reg); - - return 0; -} +#include "clk-factors.h" -static u8 ar100_get_parent(struct clk_hw *hw) -{ - struct ar100_clk *clk = to_ar100_clk(hw); - return (readl(clk->reg) >> SUN6I_AR100_MUX_SHIFT) & - SUN6I_AR100_MUX_MASK; -} - -static int ar100_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) +/** + * sun6i_get_ar100_factors - Calculates factors p, m for AR100 + * + * AR100 rate is calculated as follows + * rate = (parent_rate >> p) / (m + 1); + */ +static void sun6i_get_ar100_factors(struct factors_request *req) { - unsigned long div = parent_rate / rate; - struct ar100_clk *clk = to_ar100_clk(hw); - u32 val = readl(clk->reg); + unsigned long div; int shift; - if (parent_rate % rate) - return -EINVAL; + /* clock only divides */ + if (req->rate > req->parent_rate) + req->rate = req->parent_rate; - shift = ffs(div) - 1; - if (shift > SUN6I_AR100_SHIFT_MAX) - shift = SUN6I_AR100_SHIFT_MAX; + div = DIV_ROUND_UP(req->parent_rate, req->rate); - div >>= shift; + if (div < 32) + shift = 0; + else if (div >> 1 < 32) + shift = 1; + else if (div >> 2 < 32) + shift = 2; + else + shift = 3; - if (div > SUN6I_AR100_DIV_MAX) - return -EINVAL; + div >>= shift; - val &= ~((SUN6I_AR100_SHIFT_MASK << SUN6I_AR100_SHIFT_SHIFT) | - (SUN6I_AR100_DIV_MASK << SUN6I_AR100_DIV_SHIFT)); - val |= (shift << SUN6I_AR100_SHIFT_SHIFT) | - (div << SUN6I_AR100_DIV_SHIFT); - writel(val, clk->reg); + if (div > 32) + div = 32; - return 0; + req->rate = (req->parent_rate >> shift) / div; + req->m = div - 1; + req->p = shift; } -static struct clk_ops ar100_ops = { - .recalc_rate = ar100_recalc_rate, - .determine_rate = ar100_determine_rate, - .set_parent = ar100_set_parent, - .get_parent = ar100_get_parent, - .set_rate = ar100_set_rate, +static const struct clk_factors_config sun6i_ar100_config = { + .mwidth = 5, + .mshift = 8, + .pwidth = 2, + .pshift = 4, }; +static const struct factors_data sun6i_ar100_data __initconst = { + .mux = 16, + .muxmask = GENMASK(1, 0), + .table = &sun6i_ar100_config, + .getter = sun6i_get_ar100_factors, +}; + +static DEFINE_SPINLOCK(sun6i_ar100_lock); + static int sun6i_a31_ar100_clk_probe(struct platform_device *pdev) { - const char *parents[SUN6I_AR100_MAX_PARENTS]; struct device_node *np = pdev->dev.of_node; - const char *clk_name = np->name; - struct clk_init_data init; - struct ar100_clk *ar100; struct resource *r; + void __iomem *reg; struct clk *clk; - int nparents; - - ar100 = devm_kzalloc(&pdev->dev, sizeof(*ar100), GFP_KERNEL); - if (!ar100) - return -ENOMEM; r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - ar100->reg = devm_ioremap_resource(&pdev->dev, r); - if (IS_ERR(ar100->reg)) - return PTR_ERR(ar100->reg); + reg = devm_ioremap_resource(&pdev->dev, r); + if (IS_ERR(reg)) + return PTR_ERR(reg); - nparents = of_clk_get_parent_count(np); - if (nparents > SUN6I_AR100_MAX_PARENTS) - nparents = SUN6I_AR100_MAX_PARENTS; - - of_clk_parent_fill(np, parents, nparents); + clk = sunxi_factors_register(np, &sun6i_ar100_data, &sun6i_ar100_lock, + reg); + if (!clk) + return -ENOMEM; - of_property_read_string(np, "clock-output-names", &clk_name); + platform_set_drvdata(pdev, clk); - init.name = clk_name; - init.ops = &ar100_ops; - init.parent_names = parents; - init.num_parents = nparents; - init.flags = 0; + return 0; +} - ar100->hw.init = &init; +static int sun6i_a31_ar100_clk_remove(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct clk *clk = platform_get_drvdata(pdev); - clk = clk_register(&pdev->dev, &ar100->hw); - if (IS_ERR(clk)) - return PTR_ERR(clk); + sunxi_factors_unregister(np, clk); - return of_clk_add_provider(np, of_clk_src_simple_get, clk); + return 0; } static const struct of_device_id sun6i_a31_ar100_clk_dt_ids[] = { @@ -227,6 +113,7 @@ static struct platform_driver sun6i_a31_ar100_clk_driver = { .of_match_table = sun6i_a31_ar100_clk_dt_ids, }, .probe = sun6i_a31_ar100_clk_probe, + .remove = sun6i_a31_ar100_clk_remove, }; module_platform_driver(sun6i_a31_ar100_clk_driver); -- cgit v0.10.2 From 8f2bf2ad9673e187b5c2956497003f60e0885e5d Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 25 Jan 2016 21:15:47 +0800 Subject: clk: sunxi: rewrite sun8i-a23-mbus-clk using the simpler composite clk sun8i-a23-mbus-clk used sunxi's factors clk, which is nice for very complicated clocks, but is not really needed here. Convert sun8i-a23-mbus-clk to use clk_composite, as it is a gate + mux + divider. This makes the code easier to understand. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard diff --git a/drivers/clk/sunxi/clk-sun8i-mbus.c b/drivers/clk/sunxi/clk-sun8i-mbus.c index 78683f0..3aaa9cb 100644 --- a/drivers/clk/sunxi/clk-sun8i-mbus.c +++ b/drivers/clk/sunxi/clk-sun8i-mbus.c @@ -15,68 +15,99 @@ */ #include +#include #include +#include +#include #include -#include "clk-factors.h" +#define SUN8I_MBUS_ENABLE 31 +#define SUN8I_MBUS_MUX_SHIFT 24 +#define SUN8I_MBUS_MUX_MASK 0x3 +#define SUN8I_MBUS_DIV_SHIFT 0 +#define SUN8I_MBUS_DIV_WIDTH 3 +#define SUN8I_MBUS_MAX_PARENTS 4 -/** - * sun8i_a23_get_mbus_factors() - calculates m factor for MBUS clocks - * MBUS rate is calculated as follows - * rate = parent_rate / (m + 1); - */ +static DEFINE_SPINLOCK(sun8i_a23_mbus_lock); -static void sun8i_a23_get_mbus_factors(struct factors_request *req) +static void __init sun8i_a23_mbus_setup(struct device_node *node) { - u8 div; + int num_parents = of_clk_get_parent_count(node); + const char *parents[num_parents]; + const char *clk_name = node->name; + struct resource res; + struct clk_divider *div; + struct clk_gate *gate; + struct clk_mux *mux; + struct clk *clk; + void __iomem *reg; + int err; - /* - * These clocks can only divide, so we will never be able to - * achieve frequencies higher than the parent frequency - */ - if (req->rate > req->parent_rate) - req->rate = req->parent_rate; + reg = of_io_request_and_map(node, 0, of_node_full_name(node)); + if (!reg) { + pr_err("Could not get registers for sun8i-mbus-clk\n"); + return; + } - div = DIV_ROUND_UP(req->parent_rate, req->rate); + div = kzalloc(sizeof(*div), GFP_KERNEL); + if (!div) + goto err_unmap; - if (div > 8) - div = 8; + mux = kzalloc(sizeof(*mux), GFP_KERNEL); + if (!mux) + goto err_free_div; - req->rate = req->parent_rate / div; - req->m = div - 1; -} + gate = kzalloc(sizeof(*gate), GFP_KERNEL); + if (!gate) + goto err_free_mux; -static struct clk_factors_config sun8i_a23_mbus_config = { - .mshift = 0, - .mwidth = 3, -}; + of_property_read_string(node, "clock-output-names", &clk_name); + of_clk_parent_fill(node, parents, num_parents); -static const struct factors_data sun8i_a23_mbus_data __initconst = { - .enable = 31, - .mux = 24, - .muxmask = BIT(1) | BIT(0), - .table = &sun8i_a23_mbus_config, - .getter = sun8i_a23_get_mbus_factors, -}; + gate->reg = reg; + gate->bit_idx = SUN8I_MBUS_ENABLE; + gate->lock = &sun8i_a23_mbus_lock; -static DEFINE_SPINLOCK(sun8i_a23_mbus_lock); + div->reg = reg; + div->shift = SUN8I_MBUS_DIV_SHIFT; + div->width = SUN8I_MBUS_DIV_WIDTH; + div->lock = &sun8i_a23_mbus_lock; -static void __init sun8i_a23_mbus_setup(struct device_node *node) -{ - struct clk *mbus; - void __iomem *reg; + mux->reg = reg; + mux->shift = SUN8I_MBUS_MUX_SHIFT; + mux->mask = SUN8I_MBUS_MUX_MASK; + mux->lock = &sun8i_a23_mbus_lock; - reg = of_iomap(node, 0); - if (!reg) { - pr_err("Could not get registers for a23-mbus-clk\n"); - return; - } + clk = clk_register_composite(NULL, clk_name, parents, num_parents, + &mux->hw, &clk_mux_ops, + &div->hw, &clk_divider_ops, + &gate->hw, &clk_gate_ops, + 0); + if (IS_ERR(clk)) + goto err_free_gate; - mbus = sunxi_factors_register(node, &sun8i_a23_mbus_data, - &sun8i_a23_mbus_lock, reg); + err = of_clk_add_provider(node, of_clk_src_simple_get, clk); + if (err) + goto err_unregister_clk; /* The MBUS clocks needs to be always enabled */ - __clk_get(mbus); - clk_prepare_enable(mbus); + __clk_get(clk); + clk_prepare_enable(clk); + + return; + +err_unregister_clk: + /* TODO: The composite clock stuff will leak a bit here. */ + clk_unregister(clk); +err_free_gate: + kfree(gate); +err_free_mux: + kfree(mux); +err_free_div: + kfree(div); +err_unmap: + iounmap(reg); + of_address_to_resource(node, 0, &res); + release_mem_region(res.start, resource_size(&res)); } CLK_OF_DECLARE(sun8i_a23_mbus, "allwinner,sun8i-a23-mbus-clk", sun8i_a23_mbus_setup); -- cgit v0.10.2 From 7eb24279d2094eda074527762629d8146b148a22 Mon Sep 17 00:00:00 2001 From: Simran Rai Date: Tue, 26 Jan 2016 17:18:38 -0800 Subject: Documentation: dt-bindings: Add DT bindings for Cygnus audio clock This patch adds audio clock device tree binding documentation to an existing Cygnus clock DT bindings document. Signed-off-by: Simran Rai Reviewed-by: Ray Jui Reviewed-by: Lori Hikichi Reviewed-by: Scott Branden Signed-off-by: Stephen Boyd diff --git a/Documentation/devicetree/bindings/clock/brcm,iproc-clocks.txt b/Documentation/devicetree/bindings/clock/brcm,iproc-clocks.txt index 0b35e71..6f66e9a 100644 --- a/Documentation/devicetree/bindings/clock/brcm,iproc-clocks.txt +++ b/Documentation/devicetree/bindings/clock/brcm,iproc-clocks.txt @@ -92,6 +92,7 @@ PLL and leaf clock compatible strings for Cygnus are: "brcm,cygnus-lcpll0" "brcm,cygnus-mipipll" "brcm,cygnus-asiu-clk" + "brcm,cygnus-audiopll" The following table defines the set of PLL/clock index and ID for Cygnus. These clock IDs are defined in: @@ -131,6 +132,11 @@ These clock IDs are defined in: ch4_unused mipipll 5 BCM_CYGNUS_MIPIPLL_CH4_UNUSED ch5_unused mipipll 6 BCM_CYGNUS_MIPIPLL_CH5_UNUSED + audiopll crystal 0 BCM_CYGNUS_AUDIOPLL + ch0_audio audiopll 1 BCM_CYGNUS_AUDIOPLL_CH0 + ch1_audio audiopll 2 BCM_CYGNUS_AUDIOPLL_CH1 + ch2_audio audiopll 3 BCM_CYGNUS_AUDIOPLL_CH2 + Northstar and Northstar Plus ------ PLL and leaf clock compatible strings for Northstar and Northstar Plus are: -- cgit v0.10.2 From bcd8be139803f51834347840349c150bf0e4eb96 Mon Sep 17 00:00:00 2001 From: Simran Rai Date: Tue, 26 Jan 2016 17:18:39 -0800 Subject: clk: iproc: Add support for Cygnus audio clocks This patch adds support for Broadcom Cygnus audio PLL and leaf clocks Signed-off-by: Simran Rai Reviewed-by: Scott Branden Signed-off-by: Ray Jui Signed-off-by: Stephen Boyd diff --git a/drivers/clk/bcm/clk-cygnus.c b/drivers/clk/bcm/clk-cygnus.c index 3a228b6..464fdc4 100644 --- a/drivers/clk/bcm/clk-cygnus.c +++ b/drivers/clk/bcm/clk-cygnus.c @@ -268,3 +268,62 @@ static void __init cygnus_asiu_init(struct device_node *node) iproc_asiu_setup(node, asiu_div, asiu_gate, ARRAY_SIZE(asiu_div)); } CLK_OF_DECLARE(cygnus_asiu_clk, "brcm,cygnus-asiu-clk", cygnus_asiu_init); + +/* + * AUDIO PLL VCO frequency parameter table + * + * PLL output frequency = ((ndiv_int + ndiv_frac / 2^20) * + * (parent clock rate / pdiv) + * + * On Cygnus, parent is the 25MHz oscillator + */ +static const struct iproc_pll_vco_param audiopll_vco_params[] = { + /* rate (Hz) ndiv_int ndiv_frac pdiv */ + { 1354750204UL, 54, 199238, 1 }, + { 1769470191UL, 70, 816639, 1 }, +}; + +static const struct iproc_pll_ctrl audiopll = { + .flags = IPROC_CLK_PLL_NEEDS_SW_CFG | IPROC_CLK_PLL_HAS_NDIV_FRAC | + IPROC_CLK_PLL_USER_MODE_ON | IPROC_CLK_PLL_RESET_ACTIVE_LOW, + .reset = RESET_VAL(0x5c, 0, 1), + .dig_filter = DF_VAL(0x48, 0, 3, 6, 4, 3, 3), + .sw_ctrl = SW_CTRL_VAL(0x4, 0), + .ndiv_int = REG_VAL(0x8, 0, 10), + .ndiv_frac = REG_VAL(0x8, 10, 20), + .pdiv = REG_VAL(0x44, 0, 4), + .vco_ctrl = VCO_CTRL_VAL(0x0c, 0x10), + .status = REG_VAL(0x54, 0, 1), + .macro_mode = REG_VAL(0x0, 0, 3), +}; + +static const struct iproc_clk_ctrl audiopll_clk[] = { + [BCM_CYGNUS_AUDIOPLL_CH0] = { + .channel = BCM_CYGNUS_AUDIOPLL_CH0, + .flags = IPROC_CLK_AON | + IPROC_CLK_MCLK_DIV_BY_2, + .enable = ENABLE_VAL(0x14, 8, 10, 9), + .mdiv = REG_VAL(0x14, 0, 8), + }, + [BCM_CYGNUS_AUDIOPLL_CH1] = { + .channel = BCM_CYGNUS_AUDIOPLL_CH1, + .flags = IPROC_CLK_AON, + .enable = ENABLE_VAL(0x18, 8, 10, 9), + .mdiv = REG_VAL(0x18, 0, 8), + }, + [BCM_CYGNUS_AUDIOPLL_CH2] = { + .channel = BCM_CYGNUS_AUDIOPLL_CH2, + .flags = IPROC_CLK_AON, + .enable = ENABLE_VAL(0x1c, 8, 10, 9), + .mdiv = REG_VAL(0x1c, 0, 8), + }, +}; + +static void __init cygnus_audiopll_clk_init(struct device_node *node) +{ + iproc_pll_clk_setup(node, &audiopll, audiopll_vco_params, + ARRAY_SIZE(audiopll_vco_params), audiopll_clk, + ARRAY_SIZE(audiopll_clk)); +} +CLK_OF_DECLARE(cygnus_audiopll, "brcm,cygnus-audiopll", + cygnus_audiopll_clk_init); diff --git a/drivers/clk/bcm/clk-iproc-pll.c b/drivers/clk/bcm/clk-iproc-pll.c index afd5891..fd492a5 100644 --- a/drivers/clk/bcm/clk-iproc-pll.c +++ b/drivers/clk/bcm/clk-iproc-pll.c @@ -25,6 +25,12 @@ #define PLL_VCO_HIGH_SHIFT 19 #define PLL_VCO_LOW_SHIFT 30 +/* + * PLL MACRO_SELECT modes 0 to 5 choose pre-calculated PLL output frequencies + * from a look-up table. Mode 7 allows user to manipulate PLL clock dividers + */ +#define PLL_USER_MODE 7 + /* number of delay loops waiting for PLL to lock */ #define LOCK_DELAY 100 @@ -215,7 +221,10 @@ static void __pll_put_in_reset(struct iproc_pll *pll) const struct iproc_pll_reset_ctrl *reset = &ctrl->reset; val = readl(pll->control_base + reset->offset); - val &= ~(1 << reset->reset_shift | 1 << reset->p_reset_shift); + if (ctrl->flags & IPROC_CLK_PLL_RESET_ACTIVE_LOW) + val |= BIT(reset->reset_shift) | BIT(reset->p_reset_shift); + else + val &= ~(BIT(reset->reset_shift) | BIT(reset->p_reset_shift)); iproc_pll_write(pll, pll->control_base, reset->offset, val); } @@ -236,7 +245,10 @@ static void __pll_bring_out_reset(struct iproc_pll *pll, unsigned int kp, iproc_pll_write(pll, pll->control_base, dig_filter->offset, val); val = readl(pll->control_base + reset->offset); - val |= 1 << reset->reset_shift | 1 << reset->p_reset_shift; + if (ctrl->flags & IPROC_CLK_PLL_RESET_ACTIVE_LOW) + val &= ~(BIT(reset->reset_shift) | BIT(reset->p_reset_shift)); + else + val |= BIT(reset->reset_shift) | BIT(reset->p_reset_shift); iproc_pll_write(pll, pll->control_base, reset->offset, val); } @@ -292,6 +304,16 @@ static int pll_set_rate(struct iproc_clk *clk, unsigned int rate_index, /* put PLL in reset */ __pll_put_in_reset(pll); + /* set PLL in user mode before modifying PLL controls */ + if (ctrl->flags & IPROC_CLK_PLL_USER_MODE_ON) { + val = readl(pll->control_base + ctrl->macro_mode.offset); + val &= ~(bit_mask(ctrl->macro_mode.width) << + ctrl->macro_mode.shift); + val |= PLL_USER_MODE << ctrl->macro_mode.shift; + iproc_pll_write(pll, pll->control_base, + ctrl->macro_mode.offset, val); + } + iproc_pll_write(pll, pll->control_base, ctrl->vco_ctrl.u_offset, 0); val = readl(pll->control_base + ctrl->vco_ctrl.l_offset); @@ -505,7 +527,10 @@ static unsigned long iproc_clk_recalc_rate(struct clk_hw *hw, if (mdiv == 0) mdiv = 256; - clk->rate = parent_rate / mdiv; + if (ctrl->flags & IPROC_CLK_MCLK_DIV_BY_2) + clk->rate = parent_rate / (mdiv * 2); + else + clk->rate = parent_rate / mdiv; return clk->rate; } @@ -543,7 +568,10 @@ static int iproc_clk_set_rate(struct clk_hw *hw, unsigned long rate, if (rate == 0 || parent_rate == 0) return -EINVAL; - div = DIV_ROUND_UP(parent_rate, rate); + if (ctrl->flags & IPROC_CLK_MCLK_DIV_BY_2) + div = DIV_ROUND_UP(parent_rate, rate * 2); + else + div = DIV_ROUND_UP(parent_rate, rate); if (div > 256) return -EINVAL; @@ -555,7 +583,10 @@ static int iproc_clk_set_rate(struct clk_hw *hw, unsigned long rate, val |= div << ctrl->mdiv.shift; } iproc_pll_write(pll, pll->control_base, ctrl->mdiv.offset, val); - clk->rate = parent_rate / div; + if (ctrl->flags & IPROC_CLK_MCLK_DIV_BY_2) + clk->rate = parent_rate / (div * 2); + else + clk->rate = parent_rate / div; return 0; } diff --git a/drivers/clk/bcm/clk-iproc.h b/drivers/clk/bcm/clk-iproc.h index 8988de7..febae11 100644 --- a/drivers/clk/bcm/clk-iproc.h +++ b/drivers/clk/bcm/clk-iproc.h @@ -61,6 +61,26 @@ #define IPROC_CLK_PLL_SPLIT_STAT_CTRL BIT(6) /* + * Some PLLs have an additional divide by 2 in master clock calculation; + * MCLK = VCO_freq / (Mdiv * 2). Identify this to let the driver know + * of modified calculations + */ +#define IPROC_CLK_MCLK_DIV_BY_2 BIT(7) + +/* + * Some PLLs provide a look up table for the leaf clock frequencies and + * auto calculates VCO frequency parameters based on the provided leaf + * clock frequencies. They have a user mode that allows the divider + * controls to be determined by the user + */ +#define IPROC_CLK_PLL_USER_MODE_ON BIT(8) + +/* + * Some PLLs have an active low reset + */ +#define IPROC_CLK_PLL_RESET_ACTIVE_LOW BIT(9) + +/* * Parameters for VCO frequency configuration * * VCO frequency = @@ -149,6 +169,7 @@ struct iproc_pll_ctrl { struct iproc_clk_reg_op pdiv; struct iproc_pll_vco_ctrl vco_ctrl; struct iproc_clk_reg_op status; + struct iproc_clk_reg_op macro_mode; }; /* diff --git a/include/dt-bindings/clock/bcm-cygnus.h b/include/dt-bindings/clock/bcm-cygnus.h index 32fbc47..62ac5d7 100644 --- a/include/dt-bindings/clock/bcm-cygnus.h +++ b/include/dt-bindings/clock/bcm-cygnus.h @@ -65,4 +65,10 @@ #define BCM_CYGNUS_ASIU_ADC_CLK 1 #define BCM_CYGNUS_ASIU_PWM_CLK 2 +/* AUDIO clock ID */ +#define BCM_CYGNUS_AUDIOPLL 0 +#define BCM_CYGNUS_AUDIOPLL_CH0 1 +#define BCM_CYGNUS_AUDIOPLL_CH1 2 +#define BCM_CYGNUS_AUDIOPLL_CH2 3 + #endif /* _CLOCK_BCM_CYGNUS_H */ -- cgit v0.10.2 From df416e565d6e1d18cfa3b5e016a667bf51ce6aac Mon Sep 17 00:00:00 2001 From: Ray Jui Date: Tue, 26 Jan 2016 17:18:40 -0800 Subject: clk: iproc: Remove __init from header Remove __init macro from all function prototypes in clk-iproc.h Signed-off-by: Ray Jui Signed-off-by: Stephen Boyd diff --git a/drivers/clk/bcm/clk-iproc.h b/drivers/clk/bcm/clk-iproc.h index febae11..2148b4e 100644 --- a/drivers/clk/bcm/clk-iproc.h +++ b/drivers/clk/bcm/clk-iproc.h @@ -204,16 +204,16 @@ struct iproc_asiu_div { unsigned int low_width; }; -void __init iproc_armpll_setup(struct device_node *node); -void __init iproc_pll_clk_setup(struct device_node *node, - const struct iproc_pll_ctrl *pll_ctrl, - const struct iproc_pll_vco_param *vco, - unsigned int num_vco_entries, - const struct iproc_clk_ctrl *clk_ctrl, - unsigned int num_clks); -void __init iproc_asiu_setup(struct device_node *node, - const struct iproc_asiu_div *div, - const struct iproc_asiu_gate *gate, - unsigned int num_clks); +void iproc_armpll_setup(struct device_node *node); +void iproc_pll_clk_setup(struct device_node *node, + const struct iproc_pll_ctrl *pll_ctrl, + const struct iproc_pll_vco_param *vco, + unsigned int num_vco_entries, + const struct iproc_clk_ctrl *clk_ctrl, + unsigned int num_clks); +void iproc_asiu_setup(struct device_node *node, + const struct iproc_asiu_div *div, + const struct iproc_asiu_gate *gate, + unsigned int num_clks); #endif /* _CLK_IPROC_H */ -- cgit v0.10.2 From 5540ac8da18789e567f6d16582f76de7ab196eab Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Mon, 4 Jan 2016 11:01:53 +0000 Subject: clk:gcc-msm8916: add missing mss_q6_bimc_axi clock This clock is required for loading the qdsp firmware. Signed-off-by: Srinivas Kandagatla Signed-off-by: Stephen Boyd diff --git a/drivers/clk/qcom/gcc-msm8916.c b/drivers/clk/qcom/gcc-msm8916.c index e3bf09d..899349b 100644 --- a/drivers/clk/qcom/gcc-msm8916.c +++ b/drivers/clk/qcom/gcc-msm8916.c @@ -2590,6 +2590,23 @@ static struct clk_branch gcc_mss_cfg_ahb_clk = { }, }; +static struct clk_branch gcc_mss_q6_bimc_axi_clk = { + .halt_reg = 0x49004, + .clkr = { + .enable_reg = 0x49004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_q6_bimc_axi_clk", + .parent_names = (const char *[]){ + "bimc_ddr_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch gcc_oxili_ahb_clk = { .halt_reg = 0x59028, .clkr = { @@ -3227,6 +3244,7 @@ static struct clk_regmap *gcc_msm8916_clocks[] = { [GCC_ULTAUDIO_LPAIF_SEC_I2S_CLK] = &gcc_ultaudio_lpaif_sec_i2s_clk.clkr, [GCC_ULTAUDIO_LPAIF_AUX_I2S_CLK] = &gcc_ultaudio_lpaif_aux_i2s_clk.clkr, [GCC_CODEC_DIGCODEC_CLK] = &gcc_codec_digcodec_clk.clkr, + [GCC_MSS_Q6_BIMC_AXI_CLK] = &gcc_mss_q6_bimc_axi_clk.clkr, }; static struct gdsc *gcc_msm8916_gdscs[] = { diff --git a/include/dt-bindings/clock/qcom,gcc-msm8916.h b/include/dt-bindings/clock/qcom,gcc-msm8916.h index 257e2fb..28a27a4 100644 --- a/include/dt-bindings/clock/qcom,gcc-msm8916.h +++ b/include/dt-bindings/clock/qcom,gcc-msm8916.h @@ -174,6 +174,7 @@ #define GCC_ULTAUDIO_LPAIF_SEC_I2S_CLK 157 #define GCC_ULTAUDIO_LPAIF_AUX_I2S_CLK 158 #define GCC_CODEC_DIGCODEC_CLK 159 +#define GCC_MSS_Q6_BIMC_AXI_CLK 160 /* Indexes for GDSCs */ #define BIMC_GDSC 0 -- cgit v0.10.2 From cbf9591f665d44f40795afe2eee4fcbcd32575d6 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 6 Jan 2016 13:25:09 +0900 Subject: clk: add clk_unregister_fixed_factor() Allow to unregister fixed factor clock. Signed-off-by: Masahiro Yamada Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c index f0ddf37..053448e 100644 --- a/drivers/clk/clk-fixed-factor.c +++ b/drivers/clk/clk-fixed-factor.c @@ -100,6 +100,19 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name, } EXPORT_SYMBOL_GPL(clk_register_fixed_factor); +void clk_unregister_fixed_factor(struct clk *clk) +{ + struct clk_hw *hw; + + hw = __clk_get_hw(clk); + if (!hw) + return; + + clk_unregister(clk); + kfree(to_clk_fixed_factor(hw)); +} +EXPORT_SYMBOL_GPL(clk_unregister_fixed_factor); + #ifdef CONFIG_OF /** * of_fixed_factor_clk_setup() - Setup function for simple fixed factor clock diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 33dc814..3641eec 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -498,6 +498,7 @@ extern const struct clk_ops clk_fixed_factor_ops; struct clk *clk_register_fixed_factor(struct device *dev, const char *name, const char *parent_name, unsigned long flags, unsigned int mult, unsigned int div); +void clk_unregister_fixed_factor(struct clk *clk); /** * struct clk_fractional_divider - adjustable fractional divider clock -- cgit v0.10.2 From 0b225e41e369a7e03411bb67988513302a10382f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 6 Jan 2016 13:25:10 +0900 Subject: clk: add clk_unregister_fixed_rate() Allow to unregister fixed rate clock. Signed-off-by: Masahiro Yamada Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk-fixed-rate.c b/drivers/clk/clk-fixed-rate.c index e156beb..6858bfc 100644 --- a/drivers/clk/clk-fixed-rate.c +++ b/drivers/clk/clk-fixed-rate.c @@ -104,6 +104,19 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name, } EXPORT_SYMBOL_GPL(clk_register_fixed_rate); +void clk_unregister_fixed_rate(struct clk *clk) +{ + struct clk_hw *hw; + + hw = __clk_get_hw(clk); + if (!hw) + return; + + clk_unregister(clk); + kfree(to_clk_fixed_rate(hw)); +} +EXPORT_SYMBOL_GPL(clk_unregister_fixed_rate); + #ifdef CONFIG_OF /** * of_fixed_clk_setup() - Setup function for simple fixed rate clock diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 3641eec..fabe5be 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -285,7 +285,7 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name, struct clk *clk_register_fixed_rate_with_accuracy(struct device *dev, const char *name, const char *parent_name, unsigned long flags, unsigned long fixed_rate, unsigned long fixed_accuracy); - +void clk_unregister_fixed_rate(struct clk *clk); void of_fixed_clk_setup(struct device_node *np); /** -- cgit v0.10.2 From 090341b0a95d1f6d762915a75c13b393366f4ab3 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Fri, 2 Oct 2015 06:49:53 +0200 Subject: clk: vt8500: fix sign of possible PLL values With unsigned values underflow in loops can occur resulting in theoretically infinite loops. The problem has been detected using proposed semantic patch scripts/coccinelle/tests/unsigned_lesser_than_zero.cocci [1]. [1]: http://permalink.gmane.org/gmane.linux.kernel/2038576 Signed-off-by: Andrzej Hajda Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk-vt8500.c b/drivers/clk/clk-vt8500.c index 37e9288..98c4492 100644 --- a/drivers/clk/clk-vt8500.c +++ b/drivers/clk/clk-vt8500.c @@ -384,7 +384,8 @@ static void vt8500_find_pll_bits(unsigned long rate, unsigned long parent_rate, static void wm8650_find_pll_bits(unsigned long rate, unsigned long parent_rate, u32 *multiplier, u32 *divisor1, u32 *divisor2) { - u32 mul, div1, div2; + u32 mul, div1; + int div2; u32 best_mul, best_div1, best_div2; unsigned long tclk, rate_err, best_err; @@ -452,7 +453,8 @@ static u32 wm8750_get_filter(u32 parent_rate, u32 divisor1) static void wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate, u32 *filter, u32 *multiplier, u32 *divisor1, u32 *divisor2) { - u32 mul, div1, div2; + u32 mul; + int div1, div2; u32 best_mul, best_div1, best_div2; unsigned long tclk, rate_err, best_err; @@ -496,7 +498,8 @@ static void wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate, static void wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate, u32 *multiplier, u32 *divisor1, u32 *divisor2) { - u32 mul, div1, div2; + u32 mul; + int div1, div2; u32 best_mul, best_div1, best_div2; unsigned long tclk, rate_err, best_err; -- cgit v0.10.2 From 653d1452b452207999b67ab943c27cd80b7bd430 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 5 Jan 2016 12:43:41 +0900 Subject: clk: optimize the divider walk in clk_divider_bestdiv() Because _next_div() returns a valid divider, there is no need to consult _is_valid_div() for the validity of the divider in every iteration. Signed-off-by: Masahiro Yamada Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index 7d62dc3..00e035b 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c @@ -303,9 +303,8 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate, */ maxdiv = min(ULONG_MAX / rate, maxdiv); - for (i = 1; i <= maxdiv; i = _next_div(table, i, flags)) { - if (!_is_valid_div(table, i, flags)) - continue; + for (i = _next_div(table, 0, flags); i <= maxdiv; + i = _next_div(table, i, flags)) { if (rate * i == parent_rate_saved) { /* * It's the most ideal case if the requested rate can be -- cgit v0.10.2 From 93fffbbee11af1ff9658c2822cfd355b4f16243d Mon Sep 17 00:00:00 2001 From: LABBE Corentin Date: Wed, 25 Nov 2015 13:52:01 +0100 Subject: clk: palmas: constify the palmas_clks_of_match_data structure The palmas_clks_of_match_data structures are never modified. This patch constify them. Signed-off-by: LABBE Corentin Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk-palmas.c b/drivers/clk/clk-palmas.c index 8e3039f..c55e774 100644 --- a/drivers/clk/clk-palmas.c +++ b/drivers/clk/clk-palmas.c @@ -44,7 +44,7 @@ struct palmas_clock_info { struct clk *clk; struct clk_hw hw; struct palmas *palmas; - struct palmas_clk32k_desc *clk_desc; + const struct palmas_clk32k_desc *clk_desc; int ext_control_pin; }; @@ -125,10 +125,10 @@ static struct clk_ops palmas_clks_ops = { struct palmas_clks_of_match_data { struct clk_init_data init; - struct palmas_clk32k_desc desc; + const struct palmas_clk32k_desc desc; }; -static struct palmas_clks_of_match_data palmas_of_clk32kg = { +static const struct palmas_clks_of_match_data palmas_of_clk32kg = { .init = { .name = "clk32kg", .ops = &palmas_clks_ops, @@ -144,7 +144,7 @@ static struct palmas_clks_of_match_data palmas_of_clk32kg = { }, }; -static struct palmas_clks_of_match_data palmas_of_clk32kgaudio = { +static const struct palmas_clks_of_match_data palmas_of_clk32kgaudio = { .init = { .name = "clk32kgaudio", .ops = &palmas_clks_ops, @@ -240,14 +240,14 @@ static int palmas_clks_probe(struct platform_device *pdev) { struct palmas *palmas = dev_get_drvdata(pdev->dev.parent); struct device_node *node = pdev->dev.of_node; - struct palmas_clks_of_match_data *match_data; + const struct palmas_clks_of_match_data *match_data; const struct of_device_id *match; struct palmas_clock_info *cinfo; struct clk *clk; int ret; match = of_match_device(palmas_clks_of_match, &pdev->dev); - match_data = (struct palmas_clks_of_match_data *)match->data; + match_data = match->data; cinfo = devm_kzalloc(&pdev->dev, sizeof(*cinfo), GFP_KERNEL); if (!cinfo) -- cgit v0.10.2 From 8d0a69d735318cbd99c1376d16ed7ff82a7a678e Mon Sep 17 00:00:00 2001 From: LABBE Corentin Date: Wed, 25 Nov 2015 13:52:02 +0100 Subject: clk: palmas: fix a possible NULL dereference of_match_device could return NULL, and so cause a NULL pointer dereference later. Even if the probability of this case is very low, fixing it made static analyzers happy. Solving this with of_device_get_match_data made also code simplier. Reported-by: coverity (CID 1324137) Signed-off-by: LABBE Corentin Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk-palmas.c b/drivers/clk/clk-palmas.c index c55e774..9c0b8e6 100644 --- a/drivers/clk/clk-palmas.c +++ b/drivers/clk/clk-palmas.c @@ -241,13 +241,13 @@ static int palmas_clks_probe(struct platform_device *pdev) struct palmas *palmas = dev_get_drvdata(pdev->dev.parent); struct device_node *node = pdev->dev.of_node; const struct palmas_clks_of_match_data *match_data; - const struct of_device_id *match; struct palmas_clock_info *cinfo; struct clk *clk; int ret; - match = of_match_device(palmas_clks_of_match, &pdev->dev); - match_data = match->data; + match_data = of_device_get_match_data(&pdev->dev); + if (!match_data) + return 1; cinfo = devm_kzalloc(&pdev->dev, sizeof(*cinfo), GFP_KERNEL); if (!cinfo) -- cgit v0.10.2 From d95b599c0395c0aa831c6199f2e7b404d33841a2 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 30 Nov 2015 17:54:55 +0100 Subject: clk: axi-clkgen: Remove version 1 support Version 1 of the axi-clkgen core has not been used in new designs for over two years now. This is a soft peripheral used in FPGAs and anybody who has updated their kernel to the latest version will also have updated the bitstream containing the clock generator. So it should be safe to drop support for this now. Signed-off-by: Lars-Peter Clausen Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk-axi-clkgen.c b/drivers/clk/clk-axi-clkgen.c index 3bcd42f..8dedc60 100644 --- a/drivers/clk/clk-axi-clkgen.c +++ b/drivers/clk/clk-axi-clkgen.c @@ -16,18 +16,6 @@ #include #include -#define AXI_CLKGEN_V1_REG_UPDATE_ENABLE 0x04 -#define AXI_CLKGEN_V1_REG_CLK_OUT1 0x08 -#define AXI_CLKGEN_V1_REG_CLK_OUT2 0x0c -#define AXI_CLKGEN_V1_REG_CLK_DIV 0x10 -#define AXI_CLKGEN_V1_REG_CLK_FB1 0x14 -#define AXI_CLKGEN_V1_REG_CLK_FB2 0x18 -#define AXI_CLKGEN_V1_REG_LOCK1 0x1c -#define AXI_CLKGEN_V1_REG_LOCK2 0x20 -#define AXI_CLKGEN_V1_REG_LOCK3 0x24 -#define AXI_CLKGEN_V1_REG_FILTER1 0x28 -#define AXI_CLKGEN_V1_REG_FILTER2 0x2c - #define AXI_CLKGEN_V2_REG_RESET 0x40 #define AXI_CLKGEN_V2_REG_DRP_CNTRL 0x70 #define AXI_CLKGEN_V2_REG_DRP_STATUS 0x74 @@ -51,40 +39,11 @@ #define MMCM_REG_FILTER1 0x4e #define MMCM_REG_FILTER2 0x4f -struct axi_clkgen; - -struct axi_clkgen_mmcm_ops { - void (*enable)(struct axi_clkgen *axi_clkgen, bool enable); - int (*write)(struct axi_clkgen *axi_clkgen, unsigned int reg, - unsigned int val, unsigned int mask); - int (*read)(struct axi_clkgen *axi_clkgen, unsigned int reg, - unsigned int *val); -}; - struct axi_clkgen { void __iomem *base; - const struct axi_clkgen_mmcm_ops *mmcm_ops; struct clk_hw clk_hw; }; -static void axi_clkgen_mmcm_enable(struct axi_clkgen *axi_clkgen, - bool enable) -{ - axi_clkgen->mmcm_ops->enable(axi_clkgen, enable); -} - -static int axi_clkgen_mmcm_write(struct axi_clkgen *axi_clkgen, - unsigned int reg, unsigned int val, unsigned int mask) -{ - return axi_clkgen->mmcm_ops->write(axi_clkgen, reg, val, mask); -} - -static int axi_clkgen_mmcm_read(struct axi_clkgen *axi_clkgen, - unsigned int reg, unsigned int *val) -{ - return axi_clkgen->mmcm_ops->read(axi_clkgen, reg, val); -} - static uint32_t axi_clkgen_lookup_filter(unsigned int m) { switch (m) { @@ -207,70 +166,6 @@ static void axi_clkgen_read(struct axi_clkgen *axi_clkgen, *val = readl(axi_clkgen->base + reg); } -static unsigned int axi_clkgen_v1_map_mmcm_reg(unsigned int reg) -{ - switch (reg) { - case MMCM_REG_CLKOUT0_1: - return AXI_CLKGEN_V1_REG_CLK_OUT1; - case MMCM_REG_CLKOUT0_2: - return AXI_CLKGEN_V1_REG_CLK_OUT2; - case MMCM_REG_CLK_FB1: - return AXI_CLKGEN_V1_REG_CLK_FB1; - case MMCM_REG_CLK_FB2: - return AXI_CLKGEN_V1_REG_CLK_FB2; - case MMCM_REG_CLK_DIV: - return AXI_CLKGEN_V1_REG_CLK_DIV; - case MMCM_REG_LOCK1: - return AXI_CLKGEN_V1_REG_LOCK1; - case MMCM_REG_LOCK2: - return AXI_CLKGEN_V1_REG_LOCK2; - case MMCM_REG_LOCK3: - return AXI_CLKGEN_V1_REG_LOCK3; - case MMCM_REG_FILTER1: - return AXI_CLKGEN_V1_REG_FILTER1; - case MMCM_REG_FILTER2: - return AXI_CLKGEN_V1_REG_FILTER2; - default: - return 0; - } -} - -static int axi_clkgen_v1_mmcm_write(struct axi_clkgen *axi_clkgen, - unsigned int reg, unsigned int val, unsigned int mask) -{ - reg = axi_clkgen_v1_map_mmcm_reg(reg); - if (reg == 0) - return -EINVAL; - - axi_clkgen_write(axi_clkgen, reg, val); - - return 0; -} - -static int axi_clkgen_v1_mmcm_read(struct axi_clkgen *axi_clkgen, - unsigned int reg, unsigned int *val) -{ - reg = axi_clkgen_v1_map_mmcm_reg(reg); - if (reg == 0) - return -EINVAL; - - axi_clkgen_read(axi_clkgen, reg, val); - - return 0; -} - -static void axi_clkgen_v1_mmcm_enable(struct axi_clkgen *axi_clkgen, - bool enable) -{ - axi_clkgen_write(axi_clkgen, AXI_CLKGEN_V1_REG_UPDATE_ENABLE, enable); -} - -static const struct axi_clkgen_mmcm_ops axi_clkgen_v1_mmcm_ops = { - .write = axi_clkgen_v1_mmcm_write, - .read = axi_clkgen_v1_mmcm_read, - .enable = axi_clkgen_v1_mmcm_enable, -}; - static int axi_clkgen_wait_non_busy(struct axi_clkgen *axi_clkgen) { unsigned int timeout = 10000; @@ -286,7 +181,7 @@ static int axi_clkgen_wait_non_busy(struct axi_clkgen *axi_clkgen) return val & 0xffff; } -static int axi_clkgen_v2_mmcm_read(struct axi_clkgen *axi_clkgen, +static int axi_clkgen_mmcm_read(struct axi_clkgen *axi_clkgen, unsigned int reg, unsigned int *val) { unsigned int reg_val; @@ -310,7 +205,7 @@ static int axi_clkgen_v2_mmcm_read(struct axi_clkgen *axi_clkgen, return 0; } -static int axi_clkgen_v2_mmcm_write(struct axi_clkgen *axi_clkgen, +static int axi_clkgen_mmcm_write(struct axi_clkgen *axi_clkgen, unsigned int reg, unsigned int val, unsigned int mask) { unsigned int reg_val = 0; @@ -321,7 +216,7 @@ static int axi_clkgen_v2_mmcm_write(struct axi_clkgen *axi_clkgen, return ret; if (mask != 0xffff) { - axi_clkgen_v2_mmcm_read(axi_clkgen, reg, ®_val); + axi_clkgen_mmcm_read(axi_clkgen, reg, ®_val); reg_val &= ~mask; } @@ -332,7 +227,7 @@ static int axi_clkgen_v2_mmcm_write(struct axi_clkgen *axi_clkgen, return 0; } -static void axi_clkgen_v2_mmcm_enable(struct axi_clkgen *axi_clkgen, +static void axi_clkgen_mmcm_enable(struct axi_clkgen *axi_clkgen, bool enable) { unsigned int val = AXI_CLKGEN_V2_RESET_ENABLE; @@ -343,12 +238,6 @@ static void axi_clkgen_v2_mmcm_enable(struct axi_clkgen *axi_clkgen, axi_clkgen_write(axi_clkgen, AXI_CLKGEN_V2_REG_RESET, val); } -static const struct axi_clkgen_mmcm_ops axi_clkgen_v2_mmcm_ops = { - .write = axi_clkgen_v2_mmcm_write, - .read = axi_clkgen_v2_mmcm_read, - .enable = axi_clkgen_v2_mmcm_enable, -}; - static struct axi_clkgen *clk_hw_to_axi_clkgen(struct clk_hw *clk_hw) { return container_of(clk_hw, struct axi_clkgen, clk_hw); @@ -470,11 +359,7 @@ static const struct clk_ops axi_clkgen_ops = { static const struct of_device_id axi_clkgen_ids[] = { { - .compatible = "adi,axi-clkgen-1.00.a", - .data = &axi_clkgen_v1_mmcm_ops - }, { .compatible = "adi,axi-clkgen-2.00.a", - .data = &axi_clkgen_v2_mmcm_ops, }, { }, }; @@ -501,8 +386,6 @@ static int axi_clkgen_probe(struct platform_device *pdev) if (!axi_clkgen) return -ENOMEM; - axi_clkgen->mmcm_ops = id->data; - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); axi_clkgen->base = devm_ioremap_resource(&pdev->dev, mem); if (IS_ERR(axi_clkgen->base)) -- cgit v0.10.2 From 62d1e7823d9c3b454dcbffd58f35c5fa96172644 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 30 Nov 2015 17:54:56 +0100 Subject: clk: axi-clkgen: Add multi-parent support The clock generator has two clock inputs that can be used as the reference clock. Add support for switching between them at runtime. Signed-off-by: Lars-Peter Clausen Signed-off-by: Stephen Boyd diff --git a/Documentation/devicetree/bindings/clock/axi-clkgen.txt b/Documentation/devicetree/bindings/clock/axi-clkgen.txt index 20e1704..fb40da3 100644 --- a/Documentation/devicetree/bindings/clock/axi-clkgen.txt +++ b/Documentation/devicetree/bindings/clock/axi-clkgen.txt @@ -8,7 +8,10 @@ Required properties: - compatible : shall be "adi,axi-clkgen-1.00.a" or "adi,axi-clkgen-2.00.a". - #clock-cells : from common clock binding; Should always be set to 0. - reg : Address and length of the axi-clkgen register set. -- clocks : Phandle and clock specifier for the parent clock. +- clocks : Phandle and clock specifier for the parent clock(s). This must + either reference one clock if only the first clock input is connected or two + if both clock inputs are connected. For the later case the clock connected + to the first input must be specified first. Optional properties: - clock-output-names : From common clock binding. diff --git a/drivers/clk/clk-axi-clkgen.c b/drivers/clk/clk-axi-clkgen.c index 8dedc60..9a0744c 100644 --- a/drivers/clk/clk-axi-clkgen.c +++ b/drivers/clk/clk-axi-clkgen.c @@ -17,6 +17,7 @@ #include #define AXI_CLKGEN_V2_REG_RESET 0x40 +#define AXI_CLKGEN_V2_REG_CLKSEL 0x44 #define AXI_CLKGEN_V2_REG_DRP_CNTRL 0x70 #define AXI_CLKGEN_V2_REG_DRP_STATUS 0x74 @@ -349,12 +350,33 @@ static void axi_clkgen_disable(struct clk_hw *clk_hw) axi_clkgen_mmcm_enable(axi_clkgen, false); } +static int axi_clkgen_set_parent(struct clk_hw *clk_hw, u8 index) +{ + struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw); + + axi_clkgen_write(axi_clkgen, AXI_CLKGEN_V2_REG_CLKSEL, index); + + return 0; +} + +static u8 axi_clkgen_get_parent(struct clk_hw *clk_hw) +{ + struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw); + unsigned int parent; + + axi_clkgen_read(axi_clkgen, AXI_CLKGEN_V2_REG_CLKSEL, &parent); + + return parent; +} + static const struct clk_ops axi_clkgen_ops = { .recalc_rate = axi_clkgen_recalc_rate, .round_rate = axi_clkgen_round_rate, .set_rate = axi_clkgen_set_rate, .enable = axi_clkgen_enable, .disable = axi_clkgen_disable, + .set_parent = axi_clkgen_set_parent, + .get_parent = axi_clkgen_get_parent, }; static const struct of_device_id axi_clkgen_ids[] = { @@ -370,10 +392,11 @@ static int axi_clkgen_probe(struct platform_device *pdev) const struct of_device_id *id; struct axi_clkgen *axi_clkgen; struct clk_init_data init; - const char *parent_name; + const char *parent_names[2]; const char *clk_name; struct resource *mem; struct clk *clk; + unsigned int i; if (!pdev->dev.of_node) return -ENODEV; @@ -391,19 +414,24 @@ static int axi_clkgen_probe(struct platform_device *pdev) if (IS_ERR(axi_clkgen->base)) return PTR_ERR(axi_clkgen->base); - parent_name = of_clk_get_parent_name(pdev->dev.of_node, 0); - if (!parent_name) + init.num_parents = of_clk_get_parent_count(pdev->dev.of_node); + if (init.num_parents < 1 || init.num_parents > 2) return -EINVAL; + for (i = 0; i < init.num_parents; i++) { + parent_names[i] = of_clk_get_parent_name(pdev->dev.of_node, i); + if (!parent_names[i]) + return -EINVAL; + } + clk_name = pdev->dev.of_node->name; of_property_read_string(pdev->dev.of_node, "clock-output-names", &clk_name); init.name = clk_name; init.ops = &axi_clkgen_ops; - init.flags = CLK_SET_RATE_GATE; - init.parent_names = &parent_name; - init.num_parents = 1; + init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE; + init.parent_names = parent_names; axi_clkgen_mmcm_enable(axi_clkgen, false); -- cgit v0.10.2 From 3d6f1c7212d0823cbc056b1c184c7fe0cfef553a Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Fri, 29 Jan 2016 17:09:01 -0800 Subject: clk: axi-clkgen: Remove sometimes impossible check The size of unsigned long on 64-bit architectures is equal to the size of u64, so this check is impossible there. This throws off static checkers: drivers/clk/clk-axi-clkgen.c:331 axi_clkgen_recalc_rate() warn: impossible condition '(tmp > (~0)) => (0-u64max > u64max)' Let's change this code to use min_t() instead so that we get the same effect on architectures where sizeof(unsigned long) doesn't equal sizeof(u64). Cc: Lars-Peter Clausen Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk-axi-clkgen.c b/drivers/clk/clk-axi-clkgen.c index 9a0744c..3294db3 100644 --- a/drivers/clk/clk-axi-clkgen.c +++ b/drivers/clk/clk-axi-clkgen.c @@ -328,10 +328,7 @@ static unsigned long axi_clkgen_recalc_rate(struct clk_hw *clk_hw, tmp = (unsigned long long)(parent_rate / d) * m; do_div(tmp, dout); - if (tmp > ULONG_MAX) - return ULONG_MAX; - - return tmp; + return min_t(unsigned long long, tmp, ULONG_MAX); } static int axi_clkgen_enable(struct clk_hw *clk_hw) -- cgit v0.10.2 From 9849fadfc07eeb2a3699f1ccb7b61f59d2c3c6b8 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 25 Jan 2016 16:54:04 +0100 Subject: clk: st: avoid uninitialized variable use My previous patch fixed some warnings about printing a couple of variables that are always uninitialized in quadfs_pll_fs660c32_set_rate(), but I now got a warning that only shows up in some configurations (i.e. without gcc -Os) about the params.ndiv being used uninitialized in the error case: drivers/clk/st/clkgen-fsyn.c: In function 'quadfs_pll_fs660c32_set_rate': drivers/clk/st/clkgen-fsyn.c:584:75: warning: 'params.ndiv' may be used uninitialized in this function [-Wmaybe-uninitialized] drivers/clk/st/clkgen-fsyn.c:574:16: note: 'params.ndiv' was declared here This changes the error handling so we bail for invalid arguments rather than continuing with uninitialized data. Signed-off-by: Arnd Bergmann Signed-off-by: Stephen Boyd diff --git a/drivers/clk/st/clkgen-fsyn.c b/drivers/clk/st/clkgen-fsyn.c index ccb324d..dec4eaa 100644 --- a/drivers/clk/st/clkgen-fsyn.c +++ b/drivers/clk/st/clkgen-fsyn.c @@ -574,12 +574,16 @@ static int quadfs_pll_fs660c32_set_rate(struct clk_hw *hw, unsigned long rate, struct stm_fs params; long hwrate = 0; unsigned long flags = 0; + int ret; if (!rate || !parent_rate) return -EINVAL; - if (!clk_fs660c32_vco_get_params(parent_rate, rate, ¶ms)) - clk_fs660c32_vco_get_rate(parent_rate, ¶ms, &hwrate); + ret = clk_fs660c32_vco_get_params(parent_rate, rate, ¶ms); + if (ret) + return ret; + + clk_fs660c32_vco_get_rate(parent_rate, ¶ms, &hwrate); pr_debug("%s: %s new rate %ld [ndiv=0x%x]\n", __func__, clk_hw_get_name(hw), -- cgit v0.10.2 From d9e743408ecd468974cd233623ed19253fa2a7b0 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 28 Dec 2015 19:22:55 +0900 Subject: clk: remove unused first argument of __clk_init() The "struct device *dev" is not used at all in this function. Signed-off-by: Masahiro Yamada Reviewed-by: Vladimir Zapolskiy Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index b4db67a..4bb7d09 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -2304,13 +2304,12 @@ static inline void clk_debug_unregister(struct clk_core *core) /** * __clk_init - initialize the data structures in a struct clk - * @dev: device initializing this clk, placeholder for now * @clk: clk being initialized * * Initializes the lists in struct clk_core, queries the hardware for the * parent and rate and sets them both. */ -static int __clk_init(struct device *dev, struct clk *clk_user) +static int __clk_init(struct clk *clk_user) { int i, ret = 0; struct clk_core *orphan; @@ -2593,7 +2592,7 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw) goto fail_parent_names_copy; } - ret = __clk_init(dev, hw->clk); + ret = __clk_init(hw->clk); if (!ret) return hw->clk; -- cgit v0.10.2 From d35c80c248c7a97458b075225b1bf3e41c8a6d50 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 28 Dec 2015 19:22:56 +0900 Subject: clk: change the argument of __clk_init() into pointer to clk_core The argument clk_user is used only for the clk_user->core. The rest of this function only takes care of clk_core. Signed-off-by: Masahiro Yamada Reviewed-by: Vladimir Zapolskiy Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 4bb7d09..b8cd6bb 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -2303,25 +2303,22 @@ static inline void clk_debug_unregister(struct clk_core *core) #endif /** - * __clk_init - initialize the data structures in a struct clk - * @clk: clk being initialized + * __clk_init - initialize the data structures in a struct clk_core + * @core: clk_core being initialized * * Initializes the lists in struct clk_core, queries the hardware for the * parent and rate and sets them both. */ -static int __clk_init(struct clk *clk_user) +static int __clk_init(struct clk_core *core) { int i, ret = 0; struct clk_core *orphan; struct hlist_node *tmp2; - struct clk_core *core; unsigned long rate; - if (!clk_user) + if (!core) return -EINVAL; - core = clk_user->core; - clk_prepare_lock(); /* check to see if a clock with this name is already registered */ @@ -2592,7 +2589,7 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw) goto fail_parent_names_copy; } - ret = __clk_init(hw->clk); + ret = __clk_init(core); if (!ret) return hw->clk; -- cgit v0.10.2 From be45ebf25fc8866675f4822c74c9d0eb3dd96103 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 28 Dec 2015 19:22:57 +0900 Subject: clk: rename __clk_init() into __clk_core_init() Now this function takes clk_core as its argument. __clk_core_init() would be more suitable for the name of this function. Signed-off-by: Masahiro Yamada Reviewed-by: Vladimir Zapolskiy Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index b8cd6bb..e7701d6 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -2303,13 +2303,13 @@ static inline void clk_debug_unregister(struct clk_core *core) #endif /** - * __clk_init - initialize the data structures in a struct clk_core + * __clk_core_init - initialize the data structures in a struct clk_core * @core: clk_core being initialized * * Initializes the lists in struct clk_core, queries the hardware for the * parent and rate and sets them both. */ -static int __clk_init(struct clk_core *core) +static int __clk_core_init(struct clk_core *core) { int i, ret = 0; struct clk_core *orphan; @@ -2589,7 +2589,7 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw) goto fail_parent_names_copy; } - ret = __clk_init(core); + ret = __clk_core_init(core); if (!ret) return hw->clk; -- cgit v0.10.2 From 027f942ce44131bc3a11aaae6dbb227f461845b6 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 28 Dec 2015 19:22:58 +0900 Subject: clk: remove unnecessary !core->parents conditional This if-block has been here since the introduction of the common clock framework. Now no clock drivers are statically initialized. core->parent is always NULL at this point. Drop the redundant check and the confusing comment. Signed-off-by: Masahiro Yamada Reviewed-by: Vladimir Zapolskiy Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index e7701d6..735828d 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -2366,11 +2366,8 @@ static int __clk_core_init(struct clk_core *core) * in to clk_init during early boot; thus any access to core->parents[] * must always check for a NULL pointer and try to populate it if * necessary. - * - * If core->parents is not NULL we skip this entire block. This allows - * for clock drivers to statically initialize core->parents. */ - if (core->num_parents > 1 && !core->parents) { + if (core->num_parents > 1) { core->parents = kcalloc(core->num_parents, sizeof(struct clk *), GFP_KERNEL); /* -- cgit v0.10.2 From 3a6e84545129913613dc1a97bbe8e4f2378696ee Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 28 Dec 2015 19:22:59 +0900 Subject: clk: change sizeof(struct clk *) to sizeof(*core->parents) Now, the clock parent is not "struct clk *", but "struct clk_core *". Of course, the size of a pointer is always same, but strictly speaking, sizeof(struct clk *) should be sizeof(struct clk_core *) here. This mismatch happened when we split the structure into struct clk and struct clk_core. For the potential possibility of future renaming, sizeof(*core->parents) would be better. Signed-off-by: Masahiro Yamada Reviewed-by: Vladimir Zapolskiy Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 735828d..f9cab09 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1069,7 +1069,7 @@ static int clk_fetch_parent_index(struct clk_core *core, if (!core->parents) { core->parents = kcalloc(core->num_parents, - sizeof(struct clk *), GFP_KERNEL); + sizeof(*core->parents), GFP_KERNEL); if (!core->parents) return -ENOMEM; } @@ -1720,7 +1720,7 @@ static struct clk_core *__clk_init_parent(struct clk_core *core) if (!core->parents) core->parents = - kcalloc(core->num_parents, sizeof(struct clk *), + kcalloc(core->num_parents, sizeof(*core->parents), GFP_KERNEL); ret = clk_core_get_parent_by_index(core, index); @@ -2368,8 +2368,8 @@ static int __clk_core_init(struct clk_core *core) * necessary. */ if (core->num_parents > 1) { - core->parents = kcalloc(core->num_parents, sizeof(struct clk *), - GFP_KERNEL); + core->parents = kcalloc(core->num_parents, + sizeof(*core->parents), GFP_KERNEL); /* * clk_core_lookup returns NULL for parents that have not been * clk_init'd; thus any access to clk->parents[] must check -- cgit v0.10.2 From 176d11690ba2c8ad59f99734d692f19f451c408b Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 28 Dec 2015 19:23:00 +0900 Subject: clk: move core->parents allocation to clk_register() Currently, __clk_core_init() allows failure of the kcalloc() for the core->parents. So, clk_fetch_parent_index() and __clk_init_parent() also try to allocate core->parents in case it has not been allocated yet. Scattering memory allocation here and there makes things complicated. Like other clk_core members, allocate core->parents in clk_register() and let it fail in case of memory shortage. If we cannot allocate such a small piece of memory, the system is already insane. There is no point to postpone the memory allocation. Also, allocate core->parents regardless of core->num_parents. We want it even if core->num_parents == 1 because clk_fetch_parent_index() might be called against the clk_core with a single parent. If core->num_parents == 0, core->parents is set to ZERO_SIZE_PTR. It is harmless because no access happens to core->parents in such a case. Signed-off-by: Masahiro Yamada Reviewed-by: Vladimir Zapolskiy Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index f9cab09..a92feed 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1067,13 +1067,6 @@ static int clk_fetch_parent_index(struct clk_core *core, { int i; - if (!core->parents) { - core->parents = kcalloc(core->num_parents, - sizeof(*core->parents), GFP_KERNEL); - if (!core->parents) - return -ENOMEM; - } - /* * find index of new parent clock using cached parent ptrs, * or if not yet cached, use string name comparison and cache @@ -1718,11 +1711,6 @@ static struct clk_core *__clk_init_parent(struct clk_core *core) index = core->ops->get_parent(core->hw); - if (!core->parents) - core->parents = - kcalloc(core->num_parents, sizeof(*core->parents), - GFP_KERNEL); - ret = clk_core_get_parent_by_index(core, index); out: @@ -2361,26 +2349,15 @@ static int __clk_core_init(struct clk_core *core) __func__, core->name); /* - * Allocate an array of struct clk *'s to avoid unnecessary string - * look-ups of clk's possible parents. This can fail for clocks passed - * in to clk_init during early boot; thus any access to core->parents[] - * must always check for a NULL pointer and try to populate it if - * necessary. + * clk_core_lookup returns NULL for parents that have not been + * clk_init'd; thus any access to clk->parents[] must check + * for a NULL pointer. We can always perform lazy lookups for + * missing parents later on. */ - if (core->num_parents > 1) { - core->parents = kcalloc(core->num_parents, - sizeof(*core->parents), GFP_KERNEL); - /* - * clk_core_lookup returns NULL for parents that have not been - * clk_init'd; thus any access to clk->parents[] must check - * for a NULL pointer. We can always perform lazy lookups for - * missing parents later on. - */ - if (core->parents) - for (i = 0; i < core->num_parents; i++) - core->parents[i] = - clk_core_lookup(core->parent_names[i]); - } + if (core->parents) + for (i = 0; i < core->num_parents; i++) + core->parents[i] = + clk_core_lookup(core->parent_names[i]); core->parent = __clk_init_parent(core); @@ -2578,12 +2555,20 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw) } } + /* avoid unnecessary string look-ups of clk_core's possible parents. */ + core->parents = kcalloc(core->num_parents, sizeof(*core->parents), + GFP_KERNEL); + if (!core->parents) { + ret = -ENOMEM; + goto fail_parents; + }; + INIT_HLIST_HEAD(&core->clks); hw->clk = __clk_create_clk(hw, NULL, NULL); if (IS_ERR(hw->clk)) { ret = PTR_ERR(hw->clk); - goto fail_parent_names_copy; + goto fail_parents; } ret = __clk_core_init(core); @@ -2593,6 +2578,8 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw) __clk_free_clk(hw->clk); hw->clk = NULL; +fail_parents: + kfree(core->parents); fail_parent_names_copy: while (--i >= 0) kfree_const(core->parent_names[i]); -- cgit v0.10.2 From 88cfbef2acd38443c3eed780263b5f5e95a8dc1f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 28 Dec 2015 19:23:01 +0900 Subject: clk: simplify clk_core_get_parent_by_index() Drop the "if (!core->parents)" case and refactor the function a bit because core->parents is always allocated. (Strictly speaking, it is ZERO_SIZE_PTR if core->num_parents == 0, but such a case is omitted by the if-conditional above.) Signed-off-by: Masahiro Yamada Reviewed-by: Vladimir Zapolskiy Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index a92feed..c2e993d 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -350,13 +350,12 @@ static struct clk_core *clk_core_get_parent_by_index(struct clk_core *core, { if (!core || index >= core->num_parents) return NULL; - else if (!core->parents) - return clk_core_lookup(core->parent_names[index]); - else if (!core->parents[index]) - return core->parents[index] = - clk_core_lookup(core->parent_names[index]); - else - return core->parents[index]; + + if (!core->parents[index]) + core->parents[index] = + clk_core_lookup(core->parent_names[index]); + + return core->parents[index]; } struct clk_hw * -- cgit v0.10.2 From 3c436bf95a1df22fa501be7134bccd29f8387dfe Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 28 Dec 2015 19:23:02 +0900 Subject: clk: drop the initial core->parents look-ups from __clk_core_init() The core->parents is a cache to save expensive clock parent look-ups. It will be filled as needed later. We do not have to do it here. Signed-off-by: Masahiro Yamada Reviewed-by: Vladimir Zapolskiy Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index c2e993d..98c68e9 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -2347,17 +2347,6 @@ static int __clk_core_init(struct clk_core *core) "%s: invalid NULL in %s's .parent_names\n", __func__, core->name); - /* - * clk_core_lookup returns NULL for parents that have not been - * clk_init'd; thus any access to clk->parents[] must check - * for a NULL pointer. We can always perform lazy lookups for - * missing parents later on. - */ - if (core->parents) - for (i = 0; i < core->num_parents; i++) - core->parents[i] = - clk_core_lookup(core->parent_names[i]); - core->parent = __clk_init_parent(core); /* -- cgit v0.10.2 From c44fccb5f7b071d36cac3962799ba5a571429c28 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 28 Dec 2015 19:23:03 +0900 Subject: clk: replace pr_warn() with pr_err() for fatal cases These three cases let clk_register() fail. They should be considered as error messages. Signed-off-by: Masahiro Yamada Reviewed-by: Vladimir Zapolskiy Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 98c68e9..09d8445 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -2320,22 +2320,22 @@ static int __clk_core_init(struct clk_core *core) if (core->ops->set_rate && !((core->ops->round_rate || core->ops->determine_rate) && core->ops->recalc_rate)) { - pr_warning("%s: %s must implement .round_rate or .determine_rate in addition to .recalc_rate\n", - __func__, core->name); + pr_err("%s: %s must implement .round_rate or .determine_rate in addition to .recalc_rate\n", + __func__, core->name); ret = -EINVAL; goto out; } if (core->ops->set_parent && !core->ops->get_parent) { - pr_warning("%s: %s must implement .get_parent & .set_parent\n", - __func__, core->name); + pr_err("%s: %s must implement .get_parent & .set_parent\n", + __func__, core->name); ret = -EINVAL; goto out; } if (core->ops->set_rate_and_parent && !(core->ops->set_parent && core->ops->set_rate)) { - pr_warn("%s: %s must implement .set_parent & .set_rate\n", + pr_err("%s: %s must implement .set_parent & .set_rate\n", __func__, core->name); ret = -EINVAL; goto out; -- cgit v0.10.2 From 2d6f5f0cf6bfb17b8f0102cabe0665098ce0a865 Mon Sep 17 00:00:00 2001 From: Vishnu Patekar Date: Sun, 31 Jan 2016 09:20:54 +0800 Subject: clk: sunxi: Add apb0 gates for A83T APB0 is part of PRCM, and is compatible with earlier SOCs. apb0 gates controls R_PIO, R_UART, R_RSB, etc clocks. This patch adds support for APB0 gates for A83T. Signed-off-by: Vishnu Patekar Acked-by: Rob Herring Acked-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt index e59f57b..7f19ef5 100644 --- a/Documentation/devicetree/bindings/clock/sunxi.txt +++ b/Documentation/devicetree/bindings/clock/sunxi.txt @@ -39,6 +39,7 @@ Required properties: "allwinner,sun6i-a31-apb0-clk" - for the APB0 clock on A31 "allwinner,sun8i-a23-apb0-clk" - for the APB0 clock on A23 "allwinner,sun9i-a80-apb0-clk" - for the APB0 bus clock on A80 + "allwinner,sun8i-a83t-apb0-gates-clk" - for the APB0 gates on A83T "allwinner,sun4i-a10-apb0-gates-clk" - for the APB0 gates on A10 "allwinner,sun5i-a13-apb0-gates-clk" - for the APB0 gates on A13 "allwinner,sun5i-a10s-apb0-gates-clk" - for the APB0 gates on A10s diff --git a/drivers/clk/sunxi/clk-simple-gates.c b/drivers/clk/sunxi/clk-simple-gates.c index f4da52b..2cfc5a8 100644 --- a/drivers/clk/sunxi/clk-simple-gates.c +++ b/drivers/clk/sunxi/clk-simple-gates.c @@ -130,6 +130,8 @@ CLK_OF_DECLARE(sun8i_a23_apb2, "allwinner,sun8i-a23-apb2-gates-clk", sunxi_simple_gates_init); CLK_OF_DECLARE(sun8i_a33_ahb1, "allwinner,sun8i-a33-ahb1-gates-clk", sunxi_simple_gates_init); +CLK_OF_DECLARE(sun8i_a83t_apb0, "allwinner,sun8i-a83t-apb0-gates-clk", + sunxi_simple_gates_init); CLK_OF_DECLARE(sun9i_a80_ahb0, "allwinner,sun9i-a80-ahb0-gates-clk", sunxi_simple_gates_init); CLK_OF_DECLARE(sun9i_a80_ahb1, "allwinner,sun9i-a80-ahb1-gates-clk", -- cgit v0.10.2 From be338e4c589935a95f09022566ec6c511c07bb8c Mon Sep 17 00:00:00 2001 From: Vishnu Patekar Date: Sun, 31 Jan 2016 09:20:55 +0800 Subject: clk: sunxi: add bus gates for A83T A83T has similar bus gates that of H3, including single gating register has different clock parent. As per H3 and A83T datasheet, usbhost is under AHB2. However,below shows allwinner source code assignment: bits: 26 (ehci0), 27 (ehci1), 29 (ohci0) => AHB1 for A83T. bits: 26 (ehci0), 27 (ehci1) => AHB1 for H3 bits 29, 30, 31(ohci0,1,2) => AHB2 for H3. until, this confusion is cleared keep it H3 way. Signed-off-by: Vishnu Patekar Acked-by: Rob Herring Acked-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt index 7f19ef5..c09f59b 100644 --- a/Documentation/devicetree/bindings/clock/sunxi.txt +++ b/Documentation/devicetree/bindings/clock/sunxi.txt @@ -58,6 +58,7 @@ Required properties: "allwinner,sun9i-a80-apb1-gates-clk" - for the APB1 gates on A80 "allwinner,sun6i-a31-apb2-gates-clk" - for the APB2 gates on A31 "allwinner,sun8i-a23-apb2-gates-clk" - for the APB2 gates on A23 + "allwinner,sun8i-a83t-bus-gates-clk" - for the bus gates on A83T "allwinner,sun8i-h3-bus-gates-clk" - for the bus gates on H3 "allwinner,sun9i-a80-apbs-gates-clk" - for the APBS gates on A80 "allwinner,sun4i-a10-dram-gates-clk" - for the DRAM gates on A10 diff --git a/drivers/clk/sunxi/clk-sun8i-bus-gates.c b/drivers/clk/sunxi/clk-sun8i-bus-gates.c index 1113eb9..63fdb79 100644 --- a/drivers/clk/sunxi/clk-sun8i-bus-gates.c +++ b/drivers/clk/sunxi/clk-sun8i-bus-gates.c @@ -109,3 +109,5 @@ err_unmap: CLK_OF_DECLARE(sun8i_h3_bus_gates, "allwinner,sun8i-h3-bus-gates-clk", sun8i_h3_bus_gates_init); +CLK_OF_DECLARE(sun8i_a83t_bus_gates, "allwinner,sun8i-a83t-bus-gates-clk", + sun8i_h3_bus_gates_init); -- cgit v0.10.2 From 14b5a4bf7acd3c803c9bde857ae054ba19c4a04c Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 2 Feb 2016 16:55:30 +0100 Subject: clk: sunxi: don't mark sun6i_ar100_data __initconst The clk-sun6i-ar100 clk driver is a platform driver that may use deferred probing, so its probe function must not access __init symbols. Kbuild warns about this: WARNING: drivers/clk/sunxi/built-in.o(.text+0x15f0): Section mismatch in reference from the function sun6i_a31_ar100_clk_probe() to the (unknown reference) .init.rodata:(unknown) The function sun6i_a31_ar100_clk_probe() references the (unknown reference) __initconst (unknown). This is often because sun6i_a31_ar100_clk_probe lacks a __initconst annotation or the annotation of (unknown) is wrong. Removing the __initconst annotation avoids the warning and makes deferred probing work. Signed-off-by: Arnd Bergmann Fixes: 3ca2377b6fed ("clk: sunxi: rewrite sun6i-ar100 using factors clk") Signed-off-by: Maxime Ripard diff --git a/drivers/clk/sunxi/clk-sun6i-ar100.c b/drivers/clk/sunxi/clk-sun6i-ar100.c index a7f5777..84a187e 100644 --- a/drivers/clk/sunxi/clk-sun6i-ar100.c +++ b/drivers/clk/sunxi/clk-sun6i-ar100.c @@ -60,7 +60,7 @@ static const struct clk_factors_config sun6i_ar100_config = { .pshift = 4, }; -static const struct factors_data sun6i_ar100_data __initconst = { +static const struct factors_data sun6i_ar100_data = { .mux = 16, .muxmask = GENMASK(1, 0), .table = &sun6i_ar100_config, -- cgit v0.10.2 From d221b7a8781ce594249cb44644ec9fecd893957d Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 1 Feb 2016 17:39:27 +0000 Subject: clk: sunxi: improve error reporting for the mux clock clk_register_mux returns a pointer wrapped error value in case of failure, so a simple NULL check is not sufficient to catch errors. Fix that and elaborate on the failure reason on the way. The whole function does not return any error value, so silently failing may leave users scratching their heads because the kernel does not provide any clues on what's wrong. Signed-off-by: Andre Przywara Signed-off-by: Maxime Ripard diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index da15f2b..2524d6f 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -627,17 +627,29 @@ static void __init sunxi_mux_clk_setup(struct device_node *node, reg = of_iomap(node, 0); i = of_clk_parent_fill(node, parents, SUNXI_MAX_PARENTS); - of_property_read_string(node, "clock-output-names", &clk_name); + if (of_property_read_string(node, "clock-output-names", &clk_name)) { + pr_warn("%s: could not read clock-output-names for \"%s\"\n", + __func__, clk_name); + goto out_unmap; + } clk = clk_register_mux(NULL, clk_name, parents, i, CLK_SET_RATE_PARENT, reg, data->shift, SUNXI_MUX_GATE_WIDTH, 0, &clk_lock); - if (clk) { - of_clk_add_provider(node, of_clk_src_simple_get, clk); - clk_register_clkdev(clk, clk_name, NULL); + if (IS_ERR(clk)) { + pr_warn("%s: failed to register mux clock %s: %ld\n", __func__, + clk_name, PTR_ERR(clk)); + goto out_unmap; } + + of_clk_add_provider(node, of_clk_src_simple_get, clk); + clk_register_clkdev(clk, clk_name, NULL); + return; + +out_unmap: + iounmap(reg); } -- cgit v0.10.2 From 3c8e77dd20ab733f855e66bb6197ce84eb33e480 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 28 Dec 2015 19:23:04 +0900 Subject: clk: move checking .get_parent to __clk_core_init() The .get_parent is mandatory for multi-parent clocks. Move the check to __clk_core_init(), like other callback checkings. Signed-off-by: Masahiro Yamada Reviewed-by: Vladimir Zapolskiy [sboyd@codeaurora.org: Squashed in error path handling, fix typos in commit message] Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 09d8445..7fe94a5 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1695,13 +1695,6 @@ static struct clk_core *__clk_init_parent(struct clk_core *core) goto out; } - if (!core->ops->get_parent) { - WARN(!core->ops->get_parent, - "%s: multi-parent clocks must implement .get_parent\n", - __func__); - goto out; - } - /* * Do our best to cache parent clocks in core->parents. This prevents * unnecessary and expensive lookups. We don't set core->parent here; @@ -2333,6 +2326,13 @@ static int __clk_core_init(struct clk_core *core) goto out; } + if (core->num_parents > 1 && !core->ops->get_parent) { + pr_err("%s: %s must implement .get_parent as it has multi parents\n", + __func__, core->name); + ret = -EINVAL; + goto out; + } + if (core->ops->set_rate_and_parent && !(core->ops->set_parent && core->ops->set_rate)) { pr_err("%s: %s must implement .set_parent & .set_rate\n", -- cgit v0.10.2 From 5146e0b05963f75347c9f4e18996da245f859e32 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 28 Dec 2015 19:23:04 +0900 Subject: clk: simplify __clk_init_parent() The translation from the index into clk_core is done by clk_core_get_parent_by_index(). The if-block for num_parents == 1 case is duplicating the code in the clk_core_get_parent_by_index(). Drop the "if (num_parents == 1)" from the special case. Instead, set the index to zero if .get_parent() is missing. Signed-off-by: Masahiro Yamada Reviewed-by: Vladimir Zapolskiy Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 7fe94a5..dee9c52 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1669,44 +1669,14 @@ struct clk *clk_get_parent(struct clk *clk) } EXPORT_SYMBOL_GPL(clk_get_parent); -/* - * .get_parent is mandatory for clocks with multiple possible parents. It is - * optional for single-parent clocks. Always call .get_parent if it is - * available and WARN if it is missing for multi-parent clocks. - * - * For single-parent clocks without .get_parent, first check to see if the - * .parents array exists, and if so use it to avoid an expensive tree - * traversal. If .parents does not exist then walk the tree. - */ static struct clk_core *__clk_init_parent(struct clk_core *core) { - struct clk_core *ret = NULL; - u8 index; - - /* handle the trivial cases */ + u8 index = 0; - if (!core->num_parents) - goto out; - - if (core->num_parents == 1) { - if (IS_ERR_OR_NULL(core->parent)) - core->parent = clk_core_lookup(core->parent_names[0]); - ret = core->parent; - goto out; - } + if (core->ops->get_parent) + index = core->ops->get_parent(core->hw); - /* - * Do our best to cache parent clocks in core->parents. This prevents - * unnecessary and expensive lookups. We don't set core->parent here; - * that is done by the calling function. - */ - - index = core->ops->get_parent(core->hw); - - ret = clk_core_get_parent_by_index(core, index); - -out: - return ret; + return clk_core_get_parent_by_index(core, index); } static void clk_core_reparent(struct clk_core *core, -- cgit v0.10.2 From 858d5881564026cbc4e6f5e25ae878a27df5d4c9 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 28 Dec 2015 19:23:06 +0900 Subject: clk: avoid circular clock topology Currently, clk_register() never checks a circular parent looping, but clock providers could register such an insane clock topology. For example, "clk_a" could have "clk_b" as a parent, and vice versa. In this case, clk_core_reparent() creates a circular parent list and __clk_recalc_accuracies() calls itself recursively forever. The core infrastructure should be kind enough to bail out, showing an appropriate error message in such a case. This helps to easily find a bug in clock providers. (uh, I made such a silly mistake when I was implementing my clock providers first. I was upset because the kernel did not respond, without any error message.) This commit adds a new helper function, __clk_is_ancestor(). It returns true if the second argument is a possible ancestor of the first one. If a clock core is a possible ancestor of itself, it would make a loop when it were registered. That should be detected as an error. Signed-off-by: Masahiro Yamada Reviewed-by: Vladimir Zapolskiy Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index dee9c52..5a15074 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -2253,6 +2253,38 @@ static inline void clk_debug_unregister(struct clk_core *core) #endif /** + * __clk_is_ancestor - check if a clk_core is a possible ancestor of another + * @core: clock core + * @ancestor: ancestor clock core + * + * Returns true if there is a possibility that @ancestor can be an ancestor + * of @core, false otherwise. + * + * This function can be used against @core or @ancestor that has not been + * registered yet. + */ +static bool __clk_is_ancestor(struct clk_core *core, struct clk_core *ancestor) +{ + struct clk_core *parent; + int i; + + for (i = 0; i < core->num_parents; i++) { + parent = clk_core_get_parent_by_index(core, i); + /* + * If ancestor has not been added to clk_{root,orphan}_list + * yet, clk_core_lookup() cannot find it. If parent is NULL, + * compare the name strings, too. + */ + if ((parent && (parent == ancestor || + __clk_is_ancestor(parent, ancestor))) || + (!parent && !strcmp(core->parent_names[i], ancestor->name))) + return true; + } + + return false; +} + +/** * __clk_core_init - initialize the data structures in a struct clk_core * @core: clk_core being initialized * @@ -2317,6 +2349,14 @@ static int __clk_core_init(struct clk_core *core) "%s: invalid NULL in %s's .parent_names\n", __func__, core->name); + /* If core is an ancestor of itself, it would make a loop. */ + if (__clk_is_ancestor(core, core)) { + pr_err("%s: %s would create circular parent\n", __func__, + core->name); + ret = -EINVAL; + goto out; + } + core->parent = __clk_init_parent(core); /* -- cgit v0.10.2 From 0e8f6e499ebfd3617c81a89778f55fa6c54623e8 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 28 Dec 2015 19:23:07 +0900 Subject: clk: walk the orphan clock list more simply This loop can be much simpler. If a new parent is available for orphan clocks, __clk_init_parent(orphan) can detect it. Signed-off-by: Masahiro Yamada Reviewed-by: Vladimir Zapolskiy Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 5a15074..0382046 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -2422,24 +2422,15 @@ static int __clk_core_init(struct clk_core *core) core->rate = core->req_rate = rate; /* - * walk the list of orphan clocks and reparent any that are children of - * this clock + * walk the list of orphan clocks and reparent any that newly finds a + * parent. */ hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) { - if (orphan->num_parents && orphan->ops->get_parent) { - i = orphan->ops->get_parent(orphan->hw); - if (i >= 0 && i < orphan->num_parents && - !strcmp(core->name, orphan->parent_names[i])) - clk_core_reparent(orphan, core); - continue; - } + struct clk_core *parent = __clk_init_parent(orphan); - for (i = 0; i < orphan->num_parents; i++) - if (!strcmp(core->name, orphan->parent_names[i])) { - clk_core_reparent(orphan, core); - break; - } - } + if (parent) + clk_core_reparent(orphan, parent); + } /* * optional platform-specific magic -- cgit v0.10.2 From 508f884a66abb61f22fcc2b36ab1e68492f1d295 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 28 Dec 2015 19:23:08 +0900 Subject: clk: make sure parent is not NULL in clk_fetch_parent_index() If parent is given with NULL, clk_fetch_parent_index() could return a positive index value. Currently, parent is checked by the callers of this function, but it would be safer to do it in this function. Signed-off-by: Masahiro Yamada Reviewed-by: Vladimir Zapolskiy Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 0382046..da7c9a5 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1066,6 +1066,9 @@ static int clk_fetch_parent_index(struct clk_core *core, { int i; + if (!parent) + return -EINVAL; + /* * find index of new parent clock using cached parent ptrs, * or if not yet cached, use string name comparison and cache -- cgit v0.10.2 From 470b5e2f97cf8fb6a8375cc59e86314c9dd354c2 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 28 Dec 2015 19:23:09 +0900 Subject: clk: simplify clk_fetch_parent_index() function The clk_core_get_parent_by_index can be used as a helper function to simplify the implementation of clk_fetch_parent_index(). Signed-off-by: Masahiro Yamada Reviewed-by: Vladimir Zapolskiy Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index da7c9a5..82b79a6 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1069,23 +1069,9 @@ static int clk_fetch_parent_index(struct clk_core *core, if (!parent) return -EINVAL; - /* - * find index of new parent clock using cached parent ptrs, - * or if not yet cached, use string name comparison and cache - * them now to avoid future calls to clk_core_lookup. - */ - for (i = 0; i < core->num_parents; i++) { - if (core->parents[i] == parent) - return i; - - if (core->parents[i]) - continue; - - if (!strcmp(core->parent_names[i], parent->name)) { - core->parents[i] = clk_core_lookup(parent->name); + for (i = 0; i < core->num_parents; i++) + if (clk_core_get_parent_by_index(core, i) == parent) return i; - } - } return -EINVAL; } -- cgit v0.10.2 From e8f0e68ec0802dc840e29e0fabdcfdc39aa2a8fb Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 28 Dec 2015 19:23:10 +0900 Subject: clk: slightly optimize clk_core_set_parent() If clk_fetch_parent_index() fails, p_rate is unused. Move the assignment after the error checking. Signed-off-by: Masahiro Yamada Reviewed-by: Vladimir Zapolskiy Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 82b79a6..d31ed95 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1748,13 +1748,13 @@ static int clk_core_set_parent(struct clk_core *core, struct clk_core *parent) /* try finding the new parent index */ if (parent) { p_index = clk_fetch_parent_index(core, parent); - p_rate = parent->rate; if (p_index < 0) { pr_debug("%s: clk %s can not be parent of clk %s\n", __func__, parent->name, core->name); ret = p_index; goto out; } + p_rate = parent->rate; } /* propagate PRE_RATE_CHANGE notifications */ -- cgit v0.10.2 From 7001ec560a82d1cc2ba5c0c9ac1f7fcca820b27e Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 1 Feb 2016 11:19:10 +0100 Subject: clk: vt8500: don't return possibly uninitialized data The clk-vt8500.c driver would previously enter an endless loop when invalid settings got requested, this was now fixed. However, the driver will now return uninitialized data for a subset of those cases instead, as the gcc correctly warns: clk/clk-vt8500.c: In function 'wm8650_find_pll_bits': clk/clk-vt8500.c:423:12: error: 'best_div2' may be used uninitialized in this function [-Werror=maybe-uninitialized] *divisor2 = best_div2; ^ clk/clk-vt8500.c:422:12: error: 'best_div1' may be used uninitialized in this function [-Werror=maybe-uninitialized] *divisor1 = best_div1; ^ clk/clk-vt8500.c:421:14: error: 'best_mul' may be used uninitialized in this function [-Werror=maybe-uninitialized] *multiplier = best_mul; This reworks the error handling in the driver so we now return -EINVAL from clk_round_rate() and clk_set_rate() when we get impossible inputs. Signed-off-by: Arnd Bergmann Fixes: 090341b0a95d ("clk: vt8500: fix sign of possible PLL values") Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk-vt8500.c b/drivers/clk/clk-vt8500.c index 98c4492..b0f76a8 100644 --- a/drivers/clk/clk-vt8500.c +++ b/drivers/clk/clk-vt8500.c @@ -355,7 +355,7 @@ CLK_OF_DECLARE(vt8500_device, "via,vt8500-device-clock", vtwm_device_clk_init); #define WM8850_BITS_TO_VAL(m, d1, d2) \ ((((m / 2) - 1) << 16) | ((d1 - 1) << 8) | d2) -static void vt8500_find_pll_bits(unsigned long rate, unsigned long parent_rate, +static int vt8500_find_pll_bits(unsigned long rate, unsigned long parent_rate, u32 *multiplier, u32 *prediv) { unsigned long tclk; @@ -365,7 +365,7 @@ static void vt8500_find_pll_bits(unsigned long rate, unsigned long parent_rate, pr_err("%s: requested rate out of range\n", __func__); *multiplier = 0; *prediv = 1; - return; + return -EINVAL; } if (rate <= parent_rate * 31) /* use the prediv to double the resolution */ @@ -379,9 +379,11 @@ static void vt8500_find_pll_bits(unsigned long rate, unsigned long parent_rate, if (tclk != rate) pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, rate, tclk); + + return 0; } -static void wm8650_find_pll_bits(unsigned long rate, unsigned long parent_rate, +static int wm8650_find_pll_bits(unsigned long rate, unsigned long parent_rate, u32 *multiplier, u32 *divisor1, u32 *divisor2) { u32 mul, div1; @@ -404,7 +406,7 @@ static void wm8650_find_pll_bits(unsigned long rate, unsigned long parent_rate, *multiplier = mul; *divisor1 = div1; *divisor2 = div2; - return; + return 0; } if (rate_err < best_err) { @@ -415,12 +417,19 @@ static void wm8650_find_pll_bits(unsigned long rate, unsigned long parent_rate, } } + if (best_err == (unsigned long)-1) { + pr_warn("%s: impossible rate %lu\n", __func__, rate); + return -EINVAL; + } + /* if we got here, it wasn't an exact match */ pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, rate, rate - best_err); *multiplier = best_mul; *divisor1 = best_div1; *divisor2 = best_div2; + + return 0; } static u32 wm8750_get_filter(u32 parent_rate, u32 divisor1) @@ -450,7 +459,7 @@ static u32 wm8750_get_filter(u32 parent_rate, u32 divisor1) return 0; } -static void wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate, +static int wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate, u32 *filter, u32 *multiplier, u32 *divisor1, u32 *divisor2) { u32 mul; @@ -474,7 +483,7 @@ static void wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate, *multiplier = mul; *divisor1 = div1; *divisor2 = div2; - return; + return 0; } if (rate_err < best_err) { @@ -485,6 +494,11 @@ static void wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate, } } + if (best_err == (unsigned long)-1) { + pr_warn("%s: impossible rate %lu\n", __func__, rate); + return -EINVAL; + } + /* if we got here, it wasn't an exact match */ pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, rate, rate - best_err); @@ -493,9 +507,11 @@ static void wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate, *multiplier = best_mul; *divisor1 = best_div1; *divisor2 = best_div2; + + return 0; } -static void wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate, +static int wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate, u32 *multiplier, u32 *divisor1, u32 *divisor2) { u32 mul; @@ -519,7 +535,7 @@ static void wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate, *multiplier = mul; *divisor1 = div1; *divisor2 = div2; - return; + return 0; } if (rate_err < best_err) { @@ -530,6 +546,11 @@ static void wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate, } } + if (best_err == (unsigned long)-1) { + pr_warn("%s: impossible rate %lu\n", __func__, rate); + return -EINVAL; + } + /* if we got here, it wasn't an exact match */ pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, rate, rate - best_err); @@ -537,6 +558,8 @@ static void wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate, *multiplier = best_mul; *divisor1 = best_div1; *divisor2 = best_div2; + + return 0; } static int vtwm_pll_set_rate(struct clk_hw *hw, unsigned long rate, @@ -546,31 +569,39 @@ static int vtwm_pll_set_rate(struct clk_hw *hw, unsigned long rate, u32 filter, mul, div1, div2; u32 pll_val; unsigned long flags = 0; + int ret; /* sanity check */ switch (pll->type) { case PLL_TYPE_VT8500: - vt8500_find_pll_bits(rate, parent_rate, &mul, &div1); - pll_val = VT8500_BITS_TO_VAL(mul, div1); + ret = vt8500_find_pll_bits(rate, parent_rate, &mul, &div1); + if (!ret) + pll_val = VT8500_BITS_TO_VAL(mul, div1); break; case PLL_TYPE_WM8650: - wm8650_find_pll_bits(rate, parent_rate, &mul, &div1, &div2); - pll_val = WM8650_BITS_TO_VAL(mul, div1, div2); + ret = wm8650_find_pll_bits(rate, parent_rate, &mul, &div1, &div2); + if (!ret) + pll_val = WM8650_BITS_TO_VAL(mul, div1, div2); break; case PLL_TYPE_WM8750: - wm8750_find_pll_bits(rate, parent_rate, &filter, &mul, &div1, &div2); - pll_val = WM8750_BITS_TO_VAL(filter, mul, div1, div2); + ret = wm8750_find_pll_bits(rate, parent_rate, &filter, &mul, &div1, &div2); + if (!ret) + pll_val = WM8750_BITS_TO_VAL(filter, mul, div1, div2); break; case PLL_TYPE_WM8850: - wm8850_find_pll_bits(rate, parent_rate, &mul, &div1, &div2); - pll_val = WM8850_BITS_TO_VAL(mul, div1, div2); + ret = wm8850_find_pll_bits(rate, parent_rate, &mul, &div1, &div2); + if (!ret) + pll_val = WM8850_BITS_TO_VAL(mul, div1, div2); break; default: pr_err("%s: invalid pll type\n", __func__); - return 0; + ret = -EINVAL; } + if (ret) + return ret; + spin_lock_irqsave(pll->lock, flags); vt8500_pmc_wait_busy(); @@ -588,28 +619,36 @@ static long vtwm_pll_round_rate(struct clk_hw *hw, unsigned long rate, struct clk_pll *pll = to_clk_pll(hw); u32 filter, mul, div1, div2; long round_rate; + int ret; switch (pll->type) { case PLL_TYPE_VT8500: - vt8500_find_pll_bits(rate, *prate, &mul, &div1); - round_rate = VT8500_BITS_TO_FREQ(*prate, mul, div1); + ret = vt8500_find_pll_bits(rate, *prate, &mul, &div1); + if (!ret) + round_rate = VT8500_BITS_TO_FREQ(*prate, mul, div1); break; case PLL_TYPE_WM8650: - wm8650_find_pll_bits(rate, *prate, &mul, &div1, &div2); - round_rate = WM8650_BITS_TO_FREQ(*prate, mul, div1, div2); + ret = wm8650_find_pll_bits(rate, *prate, &mul, &div1, &div2); + if (!ret) + round_rate = WM8650_BITS_TO_FREQ(*prate, mul, div1, div2); break; case PLL_TYPE_WM8750: - wm8750_find_pll_bits(rate, *prate, &filter, &mul, &div1, &div2); - round_rate = WM8750_BITS_TO_FREQ(*prate, mul, div1, div2); + ret = wm8750_find_pll_bits(rate, *prate, &filter, &mul, &div1, &div2); + if (!ret) + round_rate = WM8750_BITS_TO_FREQ(*prate, mul, div1, div2); break; case PLL_TYPE_WM8850: - wm8850_find_pll_bits(rate, *prate, &mul, &div1, &div2); - round_rate = WM8850_BITS_TO_FREQ(*prate, mul, div1, div2); + ret = wm8850_find_pll_bits(rate, *prate, &mul, &div1, &div2); + if (!ret) + round_rate = WM8850_BITS_TO_FREQ(*prate, mul, div1, div2); break; default: - round_rate = 0; + ret = -EINVAL; } + if (ret) + return ret; + return round_rate; } -- cgit v0.10.2 From 4106a3d9ebb9839a8e93b0116c0f94dc4f10e4b2 Mon Sep 17 00:00:00 2001 From: Insu Yun Date: Sat, 30 Jan 2016 10:12:04 -0500 Subject: clk: unlock for handling unregistered clock If clock is already unregistered, it returns with holding lock. It needs to be unlocked. Signed-off-by: Insu Yun [sboyd@codeaurora.org: Use goto instead] Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index d31ed95..bb01ed6 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -2641,7 +2641,7 @@ void clk_unregister(struct clk *clk) if (clk->core->ops == &clk_nodrv_ops) { pr_err("%s: unregistered clock: %s\n", __func__, clk->core->name); - return; + goto unlock; } /* * Assign empty clock ops for consumers that might still hold @@ -2667,7 +2667,7 @@ void clk_unregister(struct clk *clk) pr_warn("%s: unregistering prepared clock: %s\n", __func__, clk->core->name); kref_put(&clk->core->ref, __clk_release); - +unlock: clk_prepare_unlock(); } EXPORT_SYMBOL_GPL(clk_unregister); -- cgit v0.10.2 From 2467b6745e0ae9c6cdccff24c4cceeb14b1cce3f Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Tue, 2 Feb 2016 11:37:50 +0800 Subject: clk: rockchip: free memory in error cases when registering clock branches Add free memeory if rockchip_clk_register_branch fails. Fixes: a245fecbb806 ("clk: rockchip: add basic infrastructure...") Signed-off-by: Shawn Lin Signed-off-by: Heiko Stuebner diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c index d9a0b5d..62fbe2c 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c @@ -70,7 +70,7 @@ static struct clk *rockchip_clk_register_branch(const char *name, if (gate_offset >= 0) { gate = kzalloc(sizeof(*gate), GFP_KERNEL); if (!gate) - return ERR_PTR(-ENOMEM); + goto err_gate; gate->flags = gate_flags; gate->reg = base + gate_offset; @@ -82,7 +82,7 @@ static struct clk *rockchip_clk_register_branch(const char *name, if (div_width > 0) { div = kzalloc(sizeof(*div), GFP_KERNEL); if (!div) - return ERR_PTR(-ENOMEM); + goto err_div; div->flags = div_flags; div->reg = base + muxdiv_offset; @@ -100,6 +100,11 @@ static struct clk *rockchip_clk_register_branch(const char *name, flags); return clk; +err_div: + kfree(gate); +err_gate: + kfree(mux); + return ERR_PTR(-ENOMEM); } struct rockchip_clk_frac { -- cgit v0.10.2 From 68b2206a57c22d5b7c5bb16308a4afafe04d416d Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Tue, 20 Oct 2015 11:22:32 +0200 Subject: clk/samsung: exynos5433: add definitions of HDMI-PHY output clocks HDMI driver must re-parent respective muxes during HDMI-PHY on/off to HDMI-PHY output clocks. To reference those clocks their definitions should be added. Signed-off-by: Andrzej Hajda Signed-off-by: Sylwester Nawrocki diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index cee062c..5530014 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -2614,8 +2614,10 @@ static struct samsung_fixed_rate_clock disp_fixed_clks[] __initdata = { FRATE(0, "phyclk_mipidphy0_rxclkesc0_phy", NULL, CLK_IS_ROOT, 100000000), /* PHY clocks from HDMI_PHY */ - FRATE(0, "phyclk_hdmiphy_tmds_clko_phy", NULL, CLK_IS_ROOT, 300000000), - FRATE(0, "phyclk_hdmiphy_pixel_clko_phy", NULL, CLK_IS_ROOT, 166000000), + FRATE(CLK_PHYCLK_HDMIPHY_TMDS_CLKO_PHY, "phyclk_hdmiphy_tmds_clko_phy", + NULL, CLK_IS_ROOT, 300000000), + FRATE(CLK_PHYCLK_HDMIPHY_PIXEL_CLKO_PHY, "phyclk_hdmiphy_pixel_clko_phy", + NULL, CLK_IS_ROOT, 166000000), }; static struct samsung_mux_clock disp_mux_clks[] __initdata = { diff --git a/include/dt-bindings/clock/exynos5433.h b/include/dt-bindings/clock/exynos5433.h index 5bd80d5..4f0d566 100644 --- a/include/dt-bindings/clock/exynos5433.h +++ b/include/dt-bindings/clock/exynos5433.h @@ -765,7 +765,10 @@ #define CLK_SCLK_RGB_VCLK 109 #define CLK_SCLK_RGB_TV_VCLK 110 -#define DISP_NR_CLK 111 +#define CLK_PHYCLK_HDMIPHY_PIXEL_CLKO_PHY 111 +#define CLK_PHYCLK_HDMIPHY_TMDS_CLKO_PHY 112 + +#define DISP_NR_CLK 113 /* CMU_AUD */ #define CLK_MOUT_AUD_PLL_USER 1 -- cgit v0.10.2 From 02ed910cb4e1c3d03ef70efa94c08f5f580c7ff8 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Tue, 20 Oct 2015 11:22:33 +0200 Subject: clk/samsung: exynos5433: add pclk_decon clock This undocumented gate clock is used by DECON IP. Signed-off-by: Andrzej Hajda Signed-off-by: Sylwester Nawrocki diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index 5530014..b7f1fb7 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -2822,6 +2822,8 @@ static struct samsung_gate_clock disp_gate_clks[] __initdata = { ENABLE_PCLK_DISP, 2, 0, 0), GATE(CLK_PCLK_DECON_TV, "pclk_decon_tv", "div_pclk_disp", ENABLE_PCLK_DISP, 1, 0, 0), + GATE(CLK_PCLK_DECON, "pclk_decon", "div_pclk_disp", + ENABLE_PCLK_DISP, 0, 0, 0), /* ENABLE_SCLK_DISP */ GATE(CLK_PHYCLK_MIPIDPHY1_BITCLKDIV8, "phyclk_mipidphy1_bitclkdiv8", diff --git a/include/dt-bindings/clock/exynos5433.h b/include/dt-bindings/clock/exynos5433.h index 4f0d566..5c2636c 100644 --- a/include/dt-bindings/clock/exynos5433.h +++ b/include/dt-bindings/clock/exynos5433.h @@ -768,7 +768,9 @@ #define CLK_PHYCLK_HDMIPHY_PIXEL_CLKO_PHY 111 #define CLK_PHYCLK_HDMIPHY_TMDS_CLKO_PHY 112 -#define DISP_NR_CLK 113 +#define CLK_PCLK_DECON 113 + +#define DISP_NR_CLK 114 /* CMU_AUD */ #define CLK_MOUT_AUD_PLL_USER 1 -- cgit v0.10.2 From aebe3ad801ebbcd90b3649c24ae0e90d2db8bde8 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Wed, 27 Jan 2016 21:38:37 +0100 Subject: clk: rockchip: fix parent of hclk_vcodec on rk3036 hclk_vcodec is a child of aclk_vcodec with the fixed factor clock hclk_vcodec_pre in between and not a child of hclk_disp_pre. Signed-off-by: Heiko Stuebner diff --git a/drivers/clk/rockchip/clk-rk3036.c b/drivers/clk/rockchip/clk-rk3036.c index 9c317a3..38139dc 100644 --- a/drivers/clk/rockchip/clk-rk3036.c +++ b/drivers/clk/rockchip/clk-rk3036.c @@ -380,7 +380,7 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { GATE(HCLK_LCDC, "hclk_lcdc", "hclk_disp_pre", 0, RK2928_CLKGATE_CON(9), 5, GFLAGS), /* hclk_video gates */ - GATE(HCLK_VCODEC, "hclk_vcodec", "hclk_disp_pre", 0, RK2928_CLKGATE_CON(3), 12, GFLAGS), + GATE(HCLK_VCODEC, "hclk_vcodec", "hclk_vcodec_pre", 0, RK2928_CLKGATE_CON(3), 12, GFLAGS), /* xin24m gates */ GATE(SCLK_PVTM_CORE, "sclk_pvtm_core", "xin24m", 0, RK2928_CLKGATE_CON(10), 0, GFLAGS), -- cgit v0.10.2 From 29a30c269aba4223e2a8b443f443d7def1e43fea Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Sat, 20 Jun 2015 13:08:57 +0200 Subject: clk: rockchip: add a factor clock type Add a clock type for fixed factor clocks. This allows us to define fixed factor clocks where they appear in the clock hierarchy instead of in the init function. The additional factor_gate type, finally allows us to model some last parts of the clock tree correctly. Signed-off-by: Heiko Stuebner diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c index 62fbe2c..ab50524 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c @@ -265,6 +265,53 @@ static struct clk *rockchip_clk_register_frac_branch(const char *name, return clk; } +static struct clk *rockchip_clk_register_factor_branch(const char *name, + const char *const *parent_names, u8 num_parents, + void __iomem *base, unsigned int mult, unsigned int div, + int gate_offset, u8 gate_shift, u8 gate_flags, + unsigned long flags, spinlock_t *lock) +{ + struct clk *clk; + struct clk_gate *gate = NULL; + struct clk_fixed_factor *fix = NULL; + + /* without gate, register a simple factor clock */ + if (gate_offset == 0) { + return clk_register_fixed_factor(NULL, name, + parent_names[0], flags, mult, + div); + } + + gate = kzalloc(sizeof(*gate), GFP_KERNEL); + if (!gate) + return ERR_PTR(-ENOMEM); + + gate->flags = gate_flags; + gate->reg = base + gate_offset; + gate->bit_idx = gate_shift; + gate->lock = lock; + + fix = kzalloc(sizeof(*fix), GFP_KERNEL); + if (!fix) { + kfree(gate); + return ERR_PTR(-ENOMEM); + } + + fix->mult = mult; + fix->div = div; + + clk = clk_register_composite(NULL, name, parent_names, num_parents, + NULL, NULL, + &fix->hw, &clk_fixed_factor_ops, + &gate->hw, &clk_gate_ops, flags); + if (IS_ERR(clk)) { + kfree(fix); + kfree(gate); + } + + return clk; +} + static DEFINE_SPINLOCK(clk_lock); static struct clk **clk_table; static void __iomem *reg_base; @@ -400,6 +447,14 @@ void __init rockchip_clk_register_branches( reg_base + list->muxdiv_offset, list->div_shift, list->div_flags, &clk_lock); break; + case branch_factor: + clk = rockchip_clk_register_factor_branch( + list->name, list->parent_names, + list->num_parents, reg_base, + list->div_shift, list->div_width, + list->gate_offset, list->gate_shift, + list->gate_flags, flags, &clk_lock); + break; } /* none of the cases above matched */ diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h index ff8bd23..39c198b 100644 --- a/drivers/clk/rockchip/clk.h +++ b/drivers/clk/rockchip/clk.h @@ -254,6 +254,7 @@ enum rockchip_clk_branch_type { branch_gate, branch_mmc, branch_inverter, + branch_factor, }; struct rockchip_clk_branch { @@ -508,6 +509,33 @@ struct rockchip_clk_branch { .div_flags = if, \ } +#define FACTOR(_id, cname, pname, f, fm, fd) \ + { \ + .id = _id, \ + .branch_type = branch_factor, \ + .name = cname, \ + .parent_names = (const char *[]){ pname }, \ + .num_parents = 1, \ + .flags = f, \ + .div_shift = fm, \ + .div_width = fd, \ + } + +#define FACTOR_GATE(_id, cname, pname, f, fm, fd, go, gb, gf) \ + { \ + .id = _id, \ + .branch_type = branch_factor, \ + .name = cname, \ + .parent_names = (const char *[]){ pname }, \ + .num_parents = 1, \ + .flags = f, \ + .div_shift = fm, \ + .div_width = fd, \ + .gate_offset = go, \ + .gate_shift = gb, \ + .gate_flags = gf, \ + } + void rockchip_clk_init(struct device_node *np, void __iomem *base, unsigned long nr_clks); struct regmap *rockchip_clk_get_grf(void); -- cgit v0.10.2 From 36714529f8bbd4f8eaf93b50f4a64c52a24879aa Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Sat, 20 Jun 2015 16:06:02 +0200 Subject: clk: rockchip: convert manually created factor clocks to the new type Clean up the init code and move the creation of factor clocks to the appropriate positions coming from the clock architecture diagrams. This also unifies the artificial separation of the hclk_vcodec etc clocks again. We do keep the separate definition of some watchdog and usb480m pseudo clocks for now, as they're not real factor clocks from the clock-tree but placeholders for fixes to come (usb480m gets supplied by the missing driver for the new usbphy type and the watchdog-gate is sitting somewhere else together which we cannot model currently). Signed-off-by: Heiko Stuebner diff --git a/drivers/clk/rockchip/clk-rk3036.c b/drivers/clk/rockchip/clk-rk3036.c index 38139dc..5759d75 100644 --- a/drivers/clk/rockchip/clk-rk3036.c +++ b/drivers/clk/rockchip/clk-rk3036.c @@ -177,6 +177,8 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { GATE(0, "gpll_armclk", "gpll", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(0), 6, GFLAGS), + FACTOR(0, "xin12m", "xin24m", 0, 1, 2), + /* * Clock-Architecture Diagram 2 */ @@ -187,6 +189,7 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { RK2928_CLKGATE_CON(0), 8, GFLAGS), COMPOSITE_NOGATE(0, "ddrphy2x", mux_ddrphy_p, CLK_IGNORE_UNUSED, RK2928_CLKSEL_CON(26), 8, 1, MFLAGS, 0, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO), + FACTOR(0, "ddrphy", "ddrphy2x", 0, 1, 2), COMPOSITE_NOMUX(0, "pclk_dbg", "armclk", CLK_IGNORE_UNUSED, RK2928_CLKSEL_CON(1), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, @@ -263,6 +266,8 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { COMPOSITE(0, "aclk_vcodec", mux_pll_src_3plls_p, 0, RK2928_CLKSEL_CON(32), 14, 2, MFLAGS, 8, 5, DFLAGS, RK2928_CLKGATE_CON(3), 11, GFLAGS), + FACTOR_GATE(HCLK_VCODEC, "hclk_vcodec", "aclk_vcodec", 0, 1, 4, + RK2928_CLKGATE_CON(3), 12, GFLAGS), COMPOSITE(0, "aclk_hvec", mux_pll_src_3plls_p, 0, RK2928_CLKSEL_CON(20), 0, 2, MFLAGS, 2, 5, DFLAGS, @@ -351,6 +356,7 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { COMPOSITE_NOMUX(SCLK_MAC, "mac_clk", "mac_clk_ref", 0, RK2928_CLKSEL_CON(21), 9, 5, DFLAGS, RK2928_CLKGATE_CON(2), 6, GFLAGS), + FACTOR(0, "sclk_macref_out", "hclk_peri_src", 0, 1, 2), MUX(SCLK_HDMI, "dclk_hdmi", mux_dclk_p, 0, RK2928_CLKSEL_CON(31), 0, 1, MFLAGS), @@ -379,8 +385,6 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { GATE(HCLK_VIO_BUS, "hclk_vio_bus", "hclk_disp_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(6), 12, GFLAGS), GATE(HCLK_LCDC, "hclk_lcdc", "hclk_disp_pre", 0, RK2928_CLKGATE_CON(9), 5, GFLAGS), - /* hclk_video gates */ - GATE(HCLK_VCODEC, "hclk_vcodec", "hclk_vcodec_pre", 0, RK2928_CLKGATE_CON(3), 12, GFLAGS), /* xin24m gates */ GATE(SCLK_PVTM_CORE, "sclk_pvtm_core", "xin24m", 0, RK2928_CLKGATE_CON(10), 0, GFLAGS), @@ -444,34 +448,11 @@ static void __init rk3036_clk_init(struct device_node *np) rockchip_clk_init(np, reg_base, CLK_NR_CLKS); - /* xin12m is created by an cru-internal divider */ - clk = clk_register_fixed_factor(NULL, "xin12m", "xin24m", 0, 1, 2); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock xin12m: %ld\n", - __func__, PTR_ERR(clk)); - clk = clk_register_fixed_factor(NULL, "usb480m", "xin24m", 0, 20, 1); if (IS_ERR(clk)) pr_warn("%s: could not register clock usb480m: %ld\n", __func__, PTR_ERR(clk)); - clk = clk_register_fixed_factor(NULL, "ddrphy", "ddrphy2x", 0, 1, 2); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock ddrphy: %ld\n", - __func__, PTR_ERR(clk)); - - clk = clk_register_fixed_factor(NULL, "hclk_vcodec_pre", - "aclk_vcodec", 0, 1, 4); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock hclk_vcodec_pre: %ld\n", - __func__, PTR_ERR(clk)); - - clk = clk_register_fixed_factor(NULL, "sclk_macref_out", - "hclk_peri_src", 0, 1, 2); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock sclk_macref_out: %ld\n", - __func__, PTR_ERR(clk)); - rockchip_clk_register_plls(rk3036_pll_clks, ARRAY_SIZE(rk3036_pll_clks), RK3036_GRF_SOC_STATUS0); diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c index 629c65d..40bab39 100644 --- a/drivers/clk/rockchip/clk-rk3188.c +++ b/drivers/clk/rockchip/clk-rk3188.c @@ -339,6 +339,8 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { INVERTER(0, "pclk_cif0", "pclkin_cif0", RK2928_CLKSEL_CON(30), 8, IFLAGS), + FACTOR(0, "xin12m", "xin24m", 0, 1, 2), + /* * the 480m are generated inside the usb block from these clocks, * but they are also a source for the hsicphy clock. @@ -754,7 +756,6 @@ static const char *const rk3188_critical_clocks[] __initconst = { static void __init rk3188_common_clk_init(struct device_node *np) { void __iomem *reg_base; - struct clk *clk; reg_base = of_iomap(np, 0); if (!reg_base) { @@ -764,12 +765,6 @@ static void __init rk3188_common_clk_init(struct device_node *np) rockchip_clk_init(np, reg_base, CLK_NR_CLKS); - /* xin12m is created by an cru-internal divider */ - clk = clk_register_fixed_factor(NULL, "xin12m", "xin24m", 0, 1, 2); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock xin12m: %ld\n", - __func__, PTR_ERR(clk)); - rockchip_clk_register_branches(common_clk_branches, ARRAY_SIZE(common_clk_branches)); diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c index 97f49aa..c515915 100644 --- a/drivers/clk/rockchip/clk-rk3228.c +++ b/drivers/clk/rockchip/clk-rk3228.c @@ -187,7 +187,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { RK2928_CLKGATE_CON(7), 1, GFLAGS), GATE(0, "ddrc", "ddrphy_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(8), 5, GFLAGS), - GATE(0, "ddrphy", "ddrphy_pre", CLK_IGNORE_UNUSED, + FACTOR_GATE(0, "ddrphy", "ddrphy4x", CLK_IGNORE_UNUSED, 1, 4, RK2928_CLKGATE_CON(7), 0, GFLAGS), /* PD_CORE */ @@ -240,13 +240,13 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { COMPOSITE(0, "aclk_vpu_pre", mux_pll_src_4plls_p, 0, RK2928_CLKSEL_CON(32), 5, 2, MFLAGS, 0, 5, DFLAGS, RK2928_CLKGATE_CON(3), 11, GFLAGS), - GATE(0, "hclk_vpu_src", "aclk_vpu_pre", 0, + FACTOR_GATE(0, "hclk_vpu_pre", "aclk_vpu_pre", 0, 1, 4, RK2928_CLKGATE_CON(4), 4, GFLAGS), COMPOSITE(0, "aclk_rkvdec_pre", mux_pll_src_4plls_p, 0, RK2928_CLKSEL_CON(28), 6, 2, MFLAGS, 0, 5, DFLAGS, RK2928_CLKGATE_CON(3), 2, GFLAGS), - GATE(0, "hclk_rkvdec_src", "aclk_rkvdec_pre", 0, + FACTOR_GATE(0, "hclk_rkvdec_pre", "aclk_rkvdec_pre", 0, 1, 4, RK2928_CLKGATE_CON(4), 5, GFLAGS), COMPOSITE(0, "sclk_vdec_cabac", mux_pll_src_4plls_p, 0, @@ -371,6 +371,8 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { MUX(0, "dclk_vop", mux_dclk_vop_p, 0, RK2928_CLKSEL_CON(27), 1, 1, MFLAGS), + FACTOR(0, "xin12m", "xin24m", 0, 1, 2), + COMPOSITE(0, "i2s0_src", mux_pll_src_2plls_p, 0, RK2928_CLKSEL_CON(9), 15, 1, MFLAGS, 0, 7, DFLAGS, RK2928_CLKGATE_CON(0), 3, GFLAGS), @@ -624,7 +626,6 @@ static const char *const rk3228_critical_clocks[] __initconst = { static void __init rk3228_clk_init(struct device_node *np) { void __iomem *reg_base; - struct clk *clk; reg_base = of_iomap(np, 0); if (!reg_base) { @@ -634,29 +635,6 @@ static void __init rk3228_clk_init(struct device_node *np) rockchip_clk_init(np, reg_base, CLK_NR_CLKS); - /* xin12m is created by an cru-internal divider */ - clk = clk_register_fixed_factor(NULL, "xin12m", "xin24m", 0, 1, 2); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock xin12m: %ld\n", - __func__, PTR_ERR(clk)); - - clk = clk_register_fixed_factor(NULL, "ddrphy_pre", "ddrphy4x", 0, 1, 4); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock ddrphy_pre: %ld\n", - __func__, PTR_ERR(clk)); - - clk = clk_register_fixed_factor(NULL, "hclk_vpu_pre", - "hclk_vpu_src", 0, 1, 4); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock hclk_vpu_pre: %ld\n", - __func__, PTR_ERR(clk)); - - clk = clk_register_fixed_factor(NULL, "hclk_rkvdec_pre", - "hclk_rkvdec_src", 0, 1, 4); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock hclk_rkvdec_pre: %ld\n", - __func__, PTR_ERR(clk)); - rockchip_clk_register_plls(rk3228_pll_clks, ARRAY_SIZE(rk3228_pll_clks), RK3228_GRF_SOC_STATUS0); diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index 0d23937..3cb7216 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -333,6 +333,8 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { GATE(0, "aclk_bus_2pmu", "aclk_cpu_pre", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(0), 7, GFLAGS), + FACTOR(0, "xin12m", "xin24m", 0, 1, 2), + COMPOSITE(0, "i2s_src", mux_pll_src_cpll_gpll_p, 0, RK3288_CLKSEL_CON(4), 15, 1, MFLAGS, 0, 7, DFLAGS, RK3288_CLKGATE_CON(4), 1, GFLAGS), @@ -399,12 +401,10 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { */ GATE(ACLK_VCODEC, "aclk_vcodec", "aclk_vdpu", 0, RK3288_CLKGATE_CON(9), 0, GFLAGS), - /* - * We introduce a virtul node of hclk_vodec_pre_v to split one clock - * struct with a gate and a fix divider into two node in software. - */ - GATE(0, "hclk_vcodec_pre_v", "aclk_vdpu", 0, + + FACTOR_GATE(0, "hclk_vcodec_pre", "aclk_vdpu", 0, 1, 4, RK3288_CLKGATE_CON(3), 10, GFLAGS), + GATE(HCLK_VCODEC, "hclk_vcodec", "hclk_vcodec_pre", 0, RK3288_CLKGATE_CON(9), 1, GFLAGS), @@ -888,18 +888,6 @@ static void __init rk3288_clk_init(struct device_node *np) rockchip_clk_init(np, rk3288_cru_base, CLK_NR_CLKS); - /* xin12m is created by an cru-internal divider */ - clk = clk_register_fixed_factor(NULL, "xin12m", "xin24m", 0, 1, 2); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock xin12m: %ld\n", - __func__, PTR_ERR(clk)); - - clk = clk_register_fixed_factor(NULL, "hclk_vcodec_pre", - "hclk_vcodec_pre_v", 0, 1, 4); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock hclk_vcodec_pre: %ld\n", - __func__, PTR_ERR(clk)); - /* Watchdog pclk is controlled by RK3288_SGRF_SOC_CON0[1]. */ clk = clk_register_fixed_factor(NULL, "pclk_wdt", "pclk_pd_alive", 0, 1, 1); if (IS_ERR(clk)) diff --git a/drivers/clk/rockchip/clk-rk3368.c b/drivers/clk/rockchip/clk-rk3368.c index e90abe8..31facd8 100644 --- a/drivers/clk/rockchip/clk-rk3368.c +++ b/drivers/clk/rockchip/clk-rk3368.c @@ -248,6 +248,8 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { * Clock-Architecture Diagram 2 */ + FACTOR(0, "xin12m", "xin24m", 0, 1, 2), + MUX(SCLK_USBPHY480M, "usbphy_480m", mux_usbphy480m_p, CLK_SET_RATE_PARENT, RK3368_CLKSEL_CON(13), 8, 1, MFLAGS), @@ -299,7 +301,7 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { COMPOSITE_NOGATE_DIVTBL(0, "ddrphy_src", mux_ddrphy_p, CLK_IGNORE_UNUSED, RK3368_CLKSEL_CON(13), 4, 1, MFLAGS, 0, 2, DFLAGS, div_ddrphy_t), - GATE(0, "sclk_ddr", "ddrphy_div4", CLK_IGNORE_UNUSED, + FACTOR_GATE(0, "sclk_ddr", "ddrphy_src", CLK_IGNORE_UNUSED, 1, 4, RK3368_CLKGATE_CON(6), 14, GFLAGS), GATE(0, "sclk_ddr4x", "ddrphy_src", CLK_IGNORE_UNUSED, RK3368_CLKGATE_CON(6), 15, GFLAGS), @@ -392,10 +394,10 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { RK3368_CLKGATE_CON(4), 7, GFLAGS), /* - * We introduce a virtual node of hclk_vodec_pre_v to split one clock - * struct with a gate and a fix divider into two node in software. + * We use aclk_vdpu by default ---GRF_SOC_CON0[7] setting in system, + * so we ignore the mux and make clocks nodes as following, */ - GATE(0, "hclk_video_pre_v", "aclk_vdpu", 0, + FACTOR_GATE(0, "hclk_video_pre", "aclk_vdpu", 0, 1, 4, RK3368_CLKGATE_CON(4), 8, GFLAGS), COMPOSITE(0, "sclk_hevc_cabac_src", mux_pll_src_cpll_gpll_npll_usb_p, 0, @@ -842,24 +844,6 @@ static void __init rk3368_clk_init(struct device_node *np) rockchip_clk_init(np, reg_base, CLK_NR_CLKS); - /* xin12m is created by a cru-internal divider */ - clk = clk_register_fixed_factor(NULL, "xin12m", "xin24m", 0, 1, 2); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock xin12m: %ld\n", - __func__, PTR_ERR(clk)); - - /* ddrphy_div4 is created by a cru-internal divider */ - clk = clk_register_fixed_factor(NULL, "ddrphy_div4", "ddrphy_src", 0, 1, 4); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock xin12m: %ld\n", - __func__, PTR_ERR(clk)); - - clk = clk_register_fixed_factor(NULL, "hclk_video_pre", - "hclk_video_pre_v", 0, 1, 4); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock hclk_vcodec_pre: %ld\n", - __func__, PTR_ERR(clk)); - /* Watchdog pclk is controlled by sgrf_soc_con3[7]. */ clk = clk_register_fixed_factor(NULL, "pclk_wdt", "pclk_pd_alive", 0, 1, 1); if (IS_ERR(clk)) -- cgit v0.10.2 From 14b04f28a0a1a5903221fc55c61d231b76abd440 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 2 Feb 2016 17:09:26 -0800 Subject: clk: gpio: Make into a platform driver clk_get() for DT based clks already returns EPROBE_DEFER when the OF clk provider is not present. So having all this code in the clk provider to return EPROBE_DEFER when the gpio isn't ready yet can be replaced with a platform driver that doesn't add the clk provider until the gpio can be requested. Get rid of the OF_CLK_DECLARE and convert this to a platform driver instead. Tested-by: Jyri Sarha Cc: Sergej Sawazki Cc: Russell King Cc: Fabio Estevam Cc: Jon Nettleton Cc: Shawn Guo Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c index cbbea29..fb32a73 100644 --- a/drivers/clk/clk-gpio.c +++ b/drivers/clk/clk-gpio.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include /** * DOC: basic gpio gated clock which can be enabled and disabled @@ -199,134 +201,71 @@ struct clk *clk_register_gpio_mux(struct device *dev, const char *name, } EXPORT_SYMBOL_GPL(clk_register_gpio_mux); -#ifdef CONFIG_OF -/** - * clk_register_get() has to be delayed, because -EPROBE_DEFER - * can not be handled properly at of_clk_init() call time. - */ - -struct clk_gpio_delayed_register_data { - const char *gpio_name; - int num_parents; - const char **parent_names; - struct device_node *node; - struct mutex lock; - struct clk *clk; - struct clk *(*clk_register_get)(const char *name, - const char * const *parent_names, u8 num_parents, - unsigned gpio, bool active_low); -}; - -static struct clk *of_clk_gpio_delayed_register_get( - struct of_phandle_args *clkspec, void *_data) +static int gpio_clk_driver_probe(struct platform_device *pdev) { - struct clk_gpio_delayed_register_data *data = _data; - struct clk *clk; - int gpio; + struct device_node *node = pdev->dev.of_node; + const char **parent_names, *gpio_name; + int num_parents, gpio; enum of_gpio_flags of_flags; + struct clk *clk; + bool active_low, is_mux; + + num_parents = of_clk_get_parent_count(node); + if (num_parents < 0) + return -EINVAL; - mutex_lock(&data->lock); + if (num_parents) { + parent_names = devm_kcalloc(&pdev->dev, num_parents, + sizeof(char *), GFP_KERNEL); + if (!parent_names) + return -ENOMEM; - if (data->clk) { - mutex_unlock(&data->lock); - return data->clk; + of_clk_parent_fill(node, parent_names, num_parents); + } else { + parent_names = NULL; } - gpio = of_get_named_gpio_flags(data->node, data->gpio_name, 0, - &of_flags); + is_mux = of_device_is_compatible(node, "gpio-mux-clock"); + + gpio_name = is_mux ? "select-gpios" : "enable-gpios"; + gpio = of_get_named_gpio_flags(node, gpio_name, 0, &of_flags); if (gpio < 0) { - mutex_unlock(&data->lock); if (gpio == -EPROBE_DEFER) pr_debug("%s: %s: GPIOs not yet available, retry later\n", - data->node->name, __func__); + node->name, __func__); else pr_err("%s: %s: Can't get '%s' DT property\n", - data->node->name, __func__, - data->gpio_name); - return ERR_PTR(gpio); + node->name, __func__, + gpio_name); + return gpio; } - clk = data->clk_register_get(data->node->name, data->parent_names, - data->num_parents, gpio, of_flags & OF_GPIO_ACTIVE_LOW); - if (IS_ERR(clk)) - goto out; - - data->clk = clk; -out: - mutex_unlock(&data->lock); - - return clk; -} - -static struct clk *of_clk_gpio_gate_delayed_register_get(const char *name, - const char * const *parent_names, u8 num_parents, - unsigned gpio, bool active_low) -{ - return clk_register_gpio_gate(NULL, name, parent_names ? - parent_names[0] : NULL, gpio, active_low, 0); -} - -static struct clk *of_clk_gpio_mux_delayed_register_get(const char *name, - const char * const *parent_names, u8 num_parents, unsigned gpio, - bool active_low) -{ - return clk_register_gpio_mux(NULL, name, parent_names, num_parents, - gpio, active_low, 0); -} - -static void __init of_gpio_clk_setup(struct device_node *node, - const char *gpio_name, - struct clk *(*clk_register_get)(const char *name, - const char * const *parent_names, - u8 num_parents, - unsigned gpio, bool active_low)) -{ - struct clk_gpio_delayed_register_data *data; - const char **parent_names; - int i, num_parents; - - num_parents = of_clk_get_parent_count(node); - if (num_parents < 0) - return; - - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) - return; + active_low = of_flags & OF_GPIO_ACTIVE_LOW; - if (num_parents) { - parent_names = kcalloc(num_parents, sizeof(char *), GFP_KERNEL); - if (!parent_names) { - kfree(data); - return; - } - - for (i = 0; i < num_parents; i++) - parent_names[i] = of_clk_get_parent_name(node, i); - } else { - parent_names = NULL; - } - - data->num_parents = num_parents; - data->parent_names = parent_names; - data->node = node; - data->gpio_name = gpio_name; - data->clk_register_get = clk_register_get; - mutex_init(&data->lock); + if (is_mux) + clk = clk_register_gpio_mux(&pdev->dev, node->name, + parent_names, num_parents, gpio, active_low, 0); + else + clk = clk_register_gpio_gate(&pdev->dev, node->name, + parent_names ? parent_names[0] : NULL, gpio, + active_low, 0); + if (IS_ERR(clk)) + return PTR_ERR(clk); - of_clk_add_provider(node, of_clk_gpio_delayed_register_get, data); + return of_clk_add_provider(node, of_clk_src_simple_get, clk); } -static void __init of_gpio_gate_clk_setup(struct device_node *node) -{ - of_gpio_clk_setup(node, "enable-gpios", - of_clk_gpio_gate_delayed_register_get); -} -CLK_OF_DECLARE(gpio_gate_clk, "gpio-gate-clock", of_gpio_gate_clk_setup); +static const struct of_device_id gpio_clk_match_table[] = { + { .compatible = "gpio-mux-clock" }, + { .compatible = "gpio-gate-clock" }, + { } +}; -void __init of_gpio_mux_clk_setup(struct device_node *node) -{ - of_gpio_clk_setup(node, "select-gpios", - of_clk_gpio_mux_delayed_register_get); -} -CLK_OF_DECLARE(gpio_mux_clk, "gpio-mux-clock", of_gpio_mux_clk_setup); -#endif +static struct platform_driver gpio_clk_driver = { + .probe = gpio_clk_driver_probe, + .driver = { + .name = "gpio-clk", + .of_match_table = gpio_clk_match_table, + }, +}; +builtin_platform_driver(gpio_clk_driver); -- cgit v0.10.2 From 47b0eeb3dc8a01848ad62908000b1051d1833eaf Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 2 Feb 2016 17:24:56 -0800 Subject: clk: Deprecate CLK_IS_ROOT We don't use CLK_IS_ROOT but in a few places in the common clk framework core. Let's replace those checks with a check for the number of parents a clk has instead of the flag, freeing up one flag for something else. We don't remove the flag yet so that things keep building, but we'll remove it once all drivers have removed their flag usage. Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index bb01ed6..cd8382c 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -385,7 +385,7 @@ static unsigned long clk_core_get_rate_nolock(struct clk_core *core) ret = core->rate; - if (core->flags & CLK_IS_ROOT) + if (!core->num_parents) goto out; if (!core->parent) @@ -2351,7 +2351,7 @@ static int __clk_core_init(struct clk_core *core) /* * Populate core->parent if parent has already been __clk_init'd. If * parent has not yet been __clk_init'd then place clk in the orphan - * list. If clk has set the CLK_IS_ROOT flag then place it in the root + * list. If clk doesn't have any parents then place it in the root * clk list. * * Every time a new clk is clk_init'd then we walk the list of orphan @@ -2362,7 +2362,7 @@ static int __clk_core_init(struct clk_core *core) hlist_add_head(&core->child_node, &core->parent->children); core->orphan = core->parent->orphan; - } else if (core->flags & CLK_IS_ROOT) { + } else if (!core->num_parents) { hlist_add_head(&core->child_node, &clk_root_list); core->orphan = false; } else { diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index fabe5be..9c3a18c 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -25,7 +25,7 @@ #define CLK_SET_PARENT_GATE BIT(1) /* must be gated across re-parent */ #define CLK_SET_RATE_PARENT BIT(2) /* propagate rate change up one level */ #define CLK_IGNORE_UNUSED BIT(3) /* do not gate even if unused */ -#define CLK_IS_ROOT BIT(4) /* root clk, has no parent */ +#define CLK_IS_ROOT BIT(4) /* Deprecated: Don't use */ #define CLK_IS_BASIC BIT(5) /* Basic clk, can't do a to_clk_foo() */ #define CLK_GET_RATE_NOCACHE BIT(6) /* do not use the cached clk rate */ #define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate change */ -- cgit v0.10.2 From 1e42754eacdb1c8632c3af47263c56967e04cbd1 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Sat, 6 Feb 2016 23:34:55 -0800 Subject: clk: provider: Remove of_gpio_{gate,mux}_clk_setup() prototypes These functions either never existed or were only used in OF_CLK_DECLARE() macros. Remove the dead prototypes. Cc: Jyri Sarha Signed-off-by: Stephen Boyd diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 9c3a18c..fce7f02 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -626,8 +626,6 @@ struct clk *clk_register_gpio_gate(struct device *dev, const char *name, const char *parent_name, unsigned gpio, bool active_low, unsigned long flags); -void of_gpio_clk_gate_setup(struct device_node *node); - /** * struct clk_gpio_mux - gpio controlled clock multiplexer * @@ -643,8 +641,6 @@ struct clk *clk_register_gpio_mux(struct device *dev, const char *name, const char * const *parent_names, u8 num_parents, unsigned gpio, bool active_low, unsigned long flags); -void of_gpio_mux_clk_setup(struct device_node *node); - /** * clk_register - allocate a new clock, register it and return an opaque cookie * @dev: device that is registering this clock -- cgit v0.10.2 From 90c073e53909da856f9d3d05dc7e6b93ed05232d Mon Sep 17 00:00:00 2001 From: Dirk Behme Date: Sat, 30 Jan 2016 07:33:59 +0100 Subject: clk: shmobile: r8a7795: Add SD divider support This patch adds SD[0..3] clock divider support for R-Car Gen3 SoC. Signed-off-by: Takeshi Kihara Signed-off-by: Dirk Behme Tested-by: Wolfram Sang Signed-off-by: Geert Uytterhoeven diff --git a/drivers/clk/shmobile/r8a7795-cpg-mssr.c b/drivers/clk/shmobile/r8a7795-cpg-mssr.c index fc260b3..0ff3b25 100644 --- a/drivers/clk/shmobile/r8a7795-cpg-mssr.c +++ b/drivers/clk/shmobile/r8a7795-cpg-mssr.c @@ -20,6 +20,7 @@ #include #include #include +#include #include @@ -61,6 +62,7 @@ enum r8a7795_clk_types { CLK_TYPE_GEN3_PLL2, CLK_TYPE_GEN3_PLL3, CLK_TYPE_GEN3_PLL4, + CLK_TYPE_GEN3_SD, }; static const struct cpg_core_clk r8a7795_core_clks[] __initconst = { @@ -99,6 +101,12 @@ static const struct cpg_core_clk r8a7795_core_clks[] __initconst = { DEF_FIXED("s3d1", R8A7795_CLK_S3D1, CLK_S3, 1, 1), DEF_FIXED("s3d2", R8A7795_CLK_S3D2, CLK_S3, 2, 1), DEF_FIXED("s3d4", R8A7795_CLK_S3D4, CLK_S3, 4, 1), + + DEF_SD("sd0", R8A7795_CLK_SD0, CLK_PLL1_DIV2, 0x0074), + DEF_SD("sd1", R8A7795_CLK_SD1, CLK_PLL1_DIV2, 0x0078), + DEF_SD("sd2", R8A7795_CLK_SD2, CLK_PLL1_DIV2, 0x0268), + DEF_SD("sd3", R8A7795_CLK_SD3, CLK_PLL1_DIV2, 0x026c), + DEF_FIXED("cl", R8A7795_CLK_CL, CLK_PLL1_DIV2, 48, 1), DEF_FIXED("cp", R8A7795_CLK_CP, CLK_EXTAL, 2, 1), @@ -120,6 +128,10 @@ static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = { DEF_MOD("sys-dmac1", 218, R8A7795_CLK_S3D1), DEF_MOD("sys-dmac0", 219, R8A7795_CLK_S3D1), DEF_MOD("scif2", 310, R8A7795_CLK_S3D4), + DEF_MOD("sdif3", 311, R8A7795_CLK_SD3), + DEF_MOD("sdif2", 312, R8A7795_CLK_SD2), + DEF_MOD("sdif1", 313, R8A7795_CLK_SD1), + DEF_MOD("sdif0", 314, R8A7795_CLK_SD0), DEF_MOD("pcie1", 318, R8A7795_CLK_S3D1), DEF_MOD("pcie0", 319, R8A7795_CLK_S3D1), DEF_MOD("usb3-if1", 327, R8A7795_CLK_S3D1), @@ -200,6 +212,221 @@ static const unsigned int r8a7795_crit_mod_clks[] __initconst = { MOD_CLK_ID(408), /* INTC-AP (GIC) */ }; +/* ----------------------------------------------------------------------------- + * SDn Clock + * + */ +#define CPG_SD_STP_HCK BIT(9) +#define CPG_SD_STP_CK BIT(8) + +#define CPG_SD_STP_MASK (CPG_SD_STP_HCK | CPG_SD_STP_CK) +#define CPG_SD_FC_MASK (0x7 << 2 | 0x3 << 0) + +#define CPG_SD_DIV_TABLE_DATA(stp_hck, stp_ck, sd_srcfc, sd_fc, sd_div) \ +{ \ + .val = ((stp_hck) ? CPG_SD_STP_HCK : 0) | \ + ((stp_ck) ? CPG_SD_STP_CK : 0) | \ + ((sd_srcfc) << 2) | \ + ((sd_fc) << 0), \ + .div = (sd_div), \ +} + +struct sd_div_table { + u32 val; + unsigned int div; +}; + +struct sd_clock { + struct clk_hw hw; + void __iomem *reg; + const struct sd_div_table *div_table; + unsigned int div_num; + unsigned int div_min; + unsigned int div_max; +}; + +/* SDn divider + * sd_srcfc sd_fc div + * stp_hck stp_ck (div) (div) = sd_srcfc x sd_fc + *------------------------------------------------------------------- + * 0 0 0 (1) 1 (4) 4 + * 0 0 1 (2) 1 (4) 8 + * 1 0 2 (4) 1 (4) 16 + * 1 0 3 (8) 1 (4) 32 + * 1 0 4 (16) 1 (4) 64 + * 0 0 0 (1) 0 (2) 2 + * 0 0 1 (2) 0 (2) 4 + * 1 0 2 (4) 0 (2) 8 + * 1 0 3 (8) 0 (2) 16 + * 1 0 4 (16) 0 (2) 32 + */ +static const struct sd_div_table cpg_sd_div_table[] = { +/* CPG_SD_DIV_TABLE_DATA(stp_hck, stp_ck, sd_srcfc, sd_fc, sd_div) */ + CPG_SD_DIV_TABLE_DATA(0, 0, 0, 1, 4), + CPG_SD_DIV_TABLE_DATA(0, 0, 1, 1, 8), + CPG_SD_DIV_TABLE_DATA(1, 0, 2, 1, 16), + CPG_SD_DIV_TABLE_DATA(1, 0, 3, 1, 32), + CPG_SD_DIV_TABLE_DATA(1, 0, 4, 1, 64), + CPG_SD_DIV_TABLE_DATA(0, 0, 0, 0, 2), + CPG_SD_DIV_TABLE_DATA(0, 0, 1, 0, 4), + CPG_SD_DIV_TABLE_DATA(1, 0, 2, 0, 8), + CPG_SD_DIV_TABLE_DATA(1, 0, 3, 0, 16), + CPG_SD_DIV_TABLE_DATA(1, 0, 4, 0, 32), +}; + +#define to_sd_clock(_hw) container_of(_hw, struct sd_clock, hw) + +static int cpg_sd_clock_enable(struct clk_hw *hw) +{ + struct sd_clock *clock = to_sd_clock(hw); + u32 val, sd_fc; + unsigned int i; + + val = clk_readl(clock->reg); + + sd_fc = val & CPG_SD_FC_MASK; + for (i = 0; i < clock->div_num; i++) + if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK)) + break; + + if (i >= clock->div_num) + return -EINVAL; + + val &= ~(CPG_SD_STP_MASK); + val |= clock->div_table[i].val & CPG_SD_STP_MASK; + + clk_writel(val, clock->reg); + + return 0; +} + +static void cpg_sd_clock_disable(struct clk_hw *hw) +{ + struct sd_clock *clock = to_sd_clock(hw); + + clk_writel(clk_readl(clock->reg) | CPG_SD_STP_MASK, clock->reg); +} + +static int cpg_sd_clock_is_enabled(struct clk_hw *hw) +{ + struct sd_clock *clock = to_sd_clock(hw); + + return !(clk_readl(clock->reg) & CPG_SD_STP_MASK); +} + +static unsigned long cpg_sd_clock_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct sd_clock *clock = to_sd_clock(hw); + unsigned long rate = parent_rate; + u32 val, sd_fc; + unsigned int i; + + val = clk_readl(clock->reg); + + sd_fc = val & CPG_SD_FC_MASK; + for (i = 0; i < clock->div_num; i++) + if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK)) + break; + + if (i >= clock->div_num) + return -EINVAL; + + return DIV_ROUND_CLOSEST(rate, clock->div_table[i].div); +} + +static unsigned int cpg_sd_clock_calc_div(struct sd_clock *clock, + unsigned long rate, + unsigned long parent_rate) +{ + unsigned int div; + + if (!rate) + rate = 1; + + div = DIV_ROUND_CLOSEST(parent_rate, rate); + + return clamp_t(unsigned int, div, clock->div_min, clock->div_max); +} + +static long cpg_sd_clock_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + struct sd_clock *clock = to_sd_clock(hw); + unsigned int div = cpg_sd_clock_calc_div(clock, rate, *parent_rate); + + return DIV_ROUND_CLOSEST(*parent_rate, div); +} + +static int cpg_sd_clock_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct sd_clock *clock = to_sd_clock(hw); + unsigned int div = cpg_sd_clock_calc_div(clock, rate, parent_rate); + u32 val; + unsigned int i; + + for (i = 0; i < clock->div_num; i++) + if (div == clock->div_table[i].div) + break; + + if (i >= clock->div_num) + return -EINVAL; + + val = clk_readl(clock->reg); + val &= ~(CPG_SD_STP_MASK | CPG_SD_FC_MASK); + val |= clock->div_table[i].val & (CPG_SD_STP_MASK | CPG_SD_FC_MASK); + clk_writel(val, clock->reg); + + return 0; +} + +static const struct clk_ops cpg_sd_clock_ops = { + .enable = cpg_sd_clock_enable, + .disable = cpg_sd_clock_disable, + .is_enabled = cpg_sd_clock_is_enabled, + .recalc_rate = cpg_sd_clock_recalc_rate, + .round_rate = cpg_sd_clock_round_rate, + .set_rate = cpg_sd_clock_set_rate, +}; + +static struct clk * __init cpg_sd_clk_register(const struct cpg_core_clk *core, + void __iomem *base, + const char *parent_name) +{ + struct clk_init_data init; + struct sd_clock *clock; + struct clk *clk; + unsigned int i; + + clock = kzalloc(sizeof(*clock), GFP_KERNEL); + if (!clock) + return ERR_PTR(-ENOMEM); + + init.name = core->name; + init.ops = &cpg_sd_clock_ops; + init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; + init.parent_names = &parent_name; + init.num_parents = 1; + + clock->reg = base + core->offset; + clock->hw.init = &init; + clock->div_table = cpg_sd_div_table; + clock->div_num = ARRAY_SIZE(cpg_sd_div_table); + + clock->div_max = clock->div_table[0].div; + clock->div_min = clock->div_max; + for (i = 1; i < clock->div_num; i++) { + clock->div_max = max(clock->div_max, clock->div_table[i].div); + clock->div_min = min(clock->div_min, clock->div_table[i].div); + } + + clk = clk_register(NULL, &clock->hw); + if (IS_ERR(clk)) + kfree(clock); + + return clk; +} #define CPG_PLL0CR 0x00d8 #define CPG_PLL2CR 0x002c @@ -325,6 +552,9 @@ struct clk * __init r8a7795_cpg_clk_register(struct device *dev, mult = (((value >> 24) & 0x7f) + 1) * 2; break; + case CLK_TYPE_GEN3_SD: + return cpg_sd_clk_register(core, base, __clk_get_name(parent)); + default: return ERR_PTR(-EINVAL); } diff --git a/drivers/clk/shmobile/renesas-cpg-mssr.h b/drivers/clk/shmobile/renesas-cpg-mssr.h index e09f03c..952b695 100644 --- a/drivers/clk/shmobile/renesas-cpg-mssr.h +++ b/drivers/clk/shmobile/renesas-cpg-mssr.h @@ -53,6 +53,8 @@ enum clk_types { DEF_BASE(_name, _id, CLK_TYPE_FF, _parent, .div = _div, .mult = _mult) #define DEF_DIV6P1(_name, _id, _parent, _offset) \ DEF_BASE(_name, _id, CLK_TYPE_DIV6P1, _parent, .offset = _offset) +#define DEF_SD(_name, _id, _parent, _offset) \ + DEF_BASE(_name, _id, CLK_TYPE_GEN3_SD, _parent, .offset = _offset) /* -- cgit v0.10.2 From 7826c61138ef7dbc4ab0c3053003ef4988fd01e3 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Mon, 1 Feb 2016 20:29:05 +0900 Subject: clk: shmobile: r8a7795: Add USB-DMAC clocks Signed-off-by: Yoshihiro Shimoda Signed-off-by: Geert Uytterhoeven diff --git a/drivers/clk/shmobile/r8a7795-cpg-mssr.c b/drivers/clk/shmobile/r8a7795-cpg-mssr.c index 0ff3b25..24ff38c 100644 --- a/drivers/clk/shmobile/r8a7795-cpg-mssr.c +++ b/drivers/clk/shmobile/r8a7795-cpg-mssr.c @@ -136,6 +136,8 @@ static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = { DEF_MOD("pcie0", 319, R8A7795_CLK_S3D1), DEF_MOD("usb3-if1", 327, R8A7795_CLK_S3D1), DEF_MOD("usb3-if0", 328, R8A7795_CLK_S3D1), + DEF_MOD("usb-dmac0", 330, R8A7795_CLK_S3D1), + DEF_MOD("usb-dmac1", 331, R8A7795_CLK_S3D1), DEF_MOD("intc-ap", 408, R8A7795_CLK_S3D1), DEF_MOD("audmac0", 502, R8A7795_CLK_S3D4), DEF_MOD("audmac1", 501, R8A7795_CLK_S3D4), -- cgit v0.10.2 From 048c58b4e167b1cdd766ddc32c68f4a154fcbbad Mon Sep 17 00:00:00 2001 From: Mike Looijmans Date: Tue, 3 Nov 2015 12:55:53 +0100 Subject: drivers/clk/Kconfig: Fix typo "Sypport" instead of "Support" Simple cosmetic fix. Signed-off-by: Mike Looijmans Signed-off-by: Stephen Boyd diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index de707b2..8401b7e 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -190,7 +190,7 @@ config COMMON_CLK_PWM config COMMON_CLK_PXA def_bool COMMON_CLK && ARCH_PXA ---help--- - Sypport for the Marvell PXA SoC. + Support for the Marvell PXA SoC. config COMMON_CLK_CDCE706 tristate "Clock driver for TI CDCE706 clock synthesizer" -- cgit v0.10.2 From c7d5a46b10012e897b6b5a86fddf31674b32d081 Mon Sep 17 00:00:00 2001 From: Mike Looijmans Date: Tue, 3 Nov 2015 12:55:54 +0100 Subject: drivers/clk/Kconfig: Move the TI CDCE chips close together There are two TI CDCE clock chips in this file. Move them close together so they're easier to find. No functional change, just cosmetic. Signed-off-by: Mike Looijmans [sboyd@codeaurora.org: Alphabetize] Signed-off-by: Stephen Boyd diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 8401b7e..a8c2c88 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -99,6 +99,14 @@ config COMMON_CLK_SI570 This driver supports Silicon Labs 570/571/598/599 programmable clock generators. +config COMMON_CLK_CDCE706 + tristate "Clock driver for TI CDCE706 clock synthesizer" + depends on I2C + select REGMAP_I2C + select RATIONAL + ---help--- + This driver supports TI CDCE706 programmable 3-PLL clock synthesizer. + config COMMON_CLK_CDCE925 tristate "Clock driver for TI CDCE925 devices" depends on I2C @@ -192,14 +200,6 @@ config COMMON_CLK_PXA ---help--- Support for the Marvell PXA SoC. -config COMMON_CLK_CDCE706 - tristate "Clock driver for TI CDCE706 clock synthesizer" - depends on I2C - select REGMAP_I2C - select RATIONAL - ---help--- - This driver supports TI CDCE706 programmable 3-PLL clock synthesizer. - source "drivers/clk/bcm/Kconfig" source "drivers/clk/hisilicon/Kconfig" source "drivers/clk/mvebu/Kconfig" -- cgit v0.10.2 From 60ea57a4338e9a43741e8136510f63cdb3b8a678 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 8 Feb 2016 15:39:09 +0100 Subject: clk: socfpga: fix __init annotation clang found a bug with the __socfpga_pll_init definition: drivers/clk/socfpga/clk-pll-a10.c:77:15: error: '__section__' attribute only applies to functions and global variables This moves the __init annotation to the right place so the function actually gets discarded. Signed-off-by: Arnd Bergmann Signed-off-by: Stephen Boyd diff --git a/drivers/clk/socfpga/clk-pll-a10.c b/drivers/clk/socfpga/clk-pll-a10.c index 402d630..35fabe1 100644 --- a/drivers/clk/socfpga/clk-pll-a10.c +++ b/drivers/clk/socfpga/clk-pll-a10.c @@ -74,7 +74,7 @@ static struct clk_ops clk_pll_ops = { .get_parent = clk_pll_get_parent, }; -static struct __init clk * __socfpga_pll_init(struct device_node *node, +static struct clk * __init __socfpga_pll_init(struct device_node *node, const struct clk_ops *ops) { u32 reg; -- cgit v0.10.2 From bb473593c8099302bfd7befc23de67df907e3a99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 7 Feb 2016 22:13:03 +0100 Subject: clk: meson: Fix meson_clk_register_clks() signature type mismatch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As preparation for arm64 based mesongxbb, which pulls in this code once enabling ARCH_MESON, fix a size_t vs. unsigned int type mismatch. The loop uses a local unsigned int variable, so adopt that type, matching the header. Fixes: 7a29a869434e ("clk: meson: Add support for Meson clock controller") Signed-off-by: Andreas Färber Acked-by: Carlo Caione Signed-off-by: Stephen Boyd diff --git a/drivers/clk/meson/clkc.c b/drivers/clk/meson/clkc.c index c83ae13..d920d41 100644 --- a/drivers/clk/meson/clkc.c +++ b/drivers/clk/meson/clkc.c @@ -198,7 +198,7 @@ meson_clk_register_fixed_rate(const struct clk_conf *clk_conf, } void __init meson_clk_register_clks(const struct clk_conf *clk_confs, - size_t nr_confs, + unsigned int nr_confs, void __iomem *clk_base) { unsigned int i; -- cgit v0.10.2 From a3499e9bf0feeea593a9daae855986c685561893 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Wed, 23 Dec 2015 17:57:19 +0530 Subject: devm: add helper devm_add_action_or_reset() Add a helper function devm_add_action_or_reset() which will internally call devm_add_action(). But if devm_add_action() fails then it will execute the action mentioned and return the error code. Signed-off-by: Sudip Mukherjee Acked-by: Greg Kroah-Hartman Signed-off-by: Stephen Boyd diff --git a/include/linux/device.h b/include/linux/device.h index 6d6f1fe..74674e0 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -682,6 +682,18 @@ void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res); int devm_add_action(struct device *dev, void (*action)(void *), void *data); void devm_remove_action(struct device *dev, void (*action)(void *), void *data); +static inline int devm_add_action_or_reset(struct device *dev, + void (*action)(void *), void *data) +{ + int ret; + + ret = devm_add_action(dev, action, data); + if (ret) + action(data); + + return ret; +} + struct device_dma_parameters { /* * a low level driver may set these to teach IOMMU code about -- cgit v0.10.2 From 66f5ce2538e06dd6d628e37bbd38c79631274c9f Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Wed, 23 Dec 2015 17:57:20 +0530 Subject: clk: qcom: common: check for failure We were not checking the return from devm_add_action() which can fail. Start using the helper and devm_add_action_or_reset() and return directly as we know that the cleanup has been done by this helper. Signed-off-by: Sudip Mukherjee Signed-off-by: Stephen Boyd diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c index c112eba..65809f1 100644 --- a/drivers/clk/qcom/common.c +++ b/drivers/clk/qcom/common.c @@ -213,7 +213,11 @@ int qcom_cc_really_probe(struct platform_device *pdev, if (ret) return ret; - devm_add_action(dev, qcom_cc_del_clk_provider, pdev->dev.of_node); + ret = devm_add_action_or_reset(dev, qcom_cc_del_clk_provider, + pdev->dev.of_node); + + if (ret) + return ret; reset = &cc->reset; reset->rcdev.of_node = dev->of_node; @@ -227,7 +231,11 @@ int qcom_cc_really_probe(struct platform_device *pdev, if (ret) return ret; - devm_add_action(dev, qcom_cc_reset_unregister, &reset->rcdev); + ret = devm_add_action_or_reset(dev, qcom_cc_reset_unregister, + &reset->rcdev); + + if (ret) + return ret; if (desc->gdscs && desc->num_gdscs) { ret = gdsc_register(dev, desc->gdscs, desc->num_gdscs, @@ -236,10 +244,7 @@ int qcom_cc_really_probe(struct platform_device *pdev, return ret; } - devm_add_action(dev, qcom_cc_gdsc_unregister, dev); - - - return 0; + return devm_add_action_or_reset(dev, qcom_cc_gdsc_unregister, dev); } EXPORT_SYMBOL_GPL(qcom_cc_really_probe); -- cgit v0.10.2 From 2430a94d1e719b7b4af2a65b781a4c036eb22e64 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 9 Feb 2016 20:19:14 +0900 Subject: clk: fix __clk_init_parent() for single parent clocks Before commit b3d192d5121f ("clk: simplify __clk_init_parent()"), __clk_init_parent() called .get_parent() only for multi-parent clocks. That commit changed the behavior to call .get_parent() if available even for single-parent clocks and root clocks. It turned out a problem because there are some single-parent clocks that implement .get_parent() callback and return non-zero index. The SOCFPGA clock is the case; the commit broke the SOCFPGA boards. To keep the original behavior, invoke .get_parent() only when num_parents is greater than 1. Fixes: b3d192d5121f ("clk: simplify __clk_init_parent()") Signed-off-by: Masahiro Yamada Reported-by: Dinh Nguyen Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index cd8382c..67cd2f1 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1662,7 +1662,7 @@ static struct clk_core *__clk_init_parent(struct clk_core *core) { u8 index = 0; - if (core->ops->get_parent) + if (core->num_parents > 1 && core->ops->get_parent) index = core->ops->get_parent(core->hw); return clk_core_get_parent_by_index(core, index); -- cgit v0.10.2 From 4db9a9ba602b38bd1fd80c4b3851dd15740a4fad Mon Sep 17 00:00:00 2001 From: Sylvain Lemieux Date: Tue, 9 Feb 2016 13:29:10 -0500 Subject: clk: lpc32xx: do not register clock "0" The following errors are display in the console during the power-on: [ 0.000000] lpc32xx_usb_clk_init: failed to register (null) clock: -12 [ 0.000000] lpc32xx_clk_init: failed to register (null) clock: -12 There is no need to register clock "0"; the first clock used is 1; Signed-off-by: Sylvain Lemieux Acked-by: Vladimir Zapolskiy [sboyd@codeaurora.org: s/prepare/register/] Signed-off-by: Stephen Boyd diff --git a/drivers/clk/nxp/clk-lpc32xx.c b/drivers/clk/nxp/clk-lpc32xx.c index 10dd0fd..981ff0d 100644 --- a/drivers/clk/nxp/clk-lpc32xx.c +++ b/drivers/clk/nxp/clk-lpc32xx.c @@ -1515,7 +1515,7 @@ static void __init lpc32xx_clk_init(struct device_node *np) return; } - for (i = 0; i < LPC32XX_CLK_MAX; i++) { + for (i = 1; i < LPC32XX_CLK_MAX; i++) { clk[i] = lpc32xx_clk_register(i); if (IS_ERR(clk[i])) { pr_err("failed to register %s clock: %ld\n", @@ -1555,7 +1555,7 @@ static void __init lpc32xx_usb_clk_init(struct device_node *np) return; } - for (i = 0; i < LPC32XX_USB_CLK_MAX; i++) { + for (i = 1; i < LPC32XX_USB_CLK_MAX; i++) { usb_clk[i] = lpc32xx_clk_register(i + LPC32XX_CLK_USB_OFFSET); if (IS_ERR(usb_clk[i])) { pr_err("failed to register %s clock: %ld\n", -- cgit v0.10.2 From 7e0810c9485ce696df3813574bca44139f6eb0c8 Mon Sep 17 00:00:00 2001 From: Sylvain Lemieux Date: Wed, 10 Feb 2016 13:52:32 -0500 Subject: clk: lpc32xx: add HCLK PLL output configuration This patch add the support to setup the HCLK PLL output using the "assigned-clock-rates" parameter in the device tree. If the option is not use, the clock setup by the kickstart and/or bootloader remain unchanged. The previous kernel version did not change the clock frequency output setup by the kickstart and/or bootloader; this version always setup the clock frequency output to 208MHz. Signed-off-by: Sylvain Lemieux Signed-off-by: Stephen Boyd diff --git a/drivers/clk/nxp/clk-lpc32xx.c b/drivers/clk/nxp/clk-lpc32xx.c index 981ff0d..48b3a11 100644 --- a/drivers/clk/nxp/clk-lpc32xx.c +++ b/drivers/clk/nxp/clk-lpc32xx.c @@ -87,7 +87,7 @@ enum { enum { /* Start from the last defined clock in dt bindings */ - LPC32XX_CLK_ADC_DIV = LPC32XX_CLK_ADC + 1, + LPC32XX_CLK_ADC_DIV = LPC32XX_CLK_HCLK_PLL + 1, LPC32XX_CLK_ADC_RTC, LPC32XX_CLK_TEST1, LPC32XX_CLK_TEST2, @@ -96,7 +96,6 @@ enum { LPC32XX_CLK_OSC, LPC32XX_CLK_SYS, LPC32XX_CLK_PLL397X, - LPC32XX_CLK_HCLK_PLL, LPC32XX_CLK_HCLK_DIV_PERIPH, LPC32XX_CLK_HCLK_DIV, LPC32XX_CLK_HCLK, @@ -1526,9 +1525,6 @@ static void __init lpc32xx_clk_init(struct device_node *np) of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); - /* For 13MHz osc valid output range of PLL is from 156MHz to 266.5MHz */ - clk_set_rate(clk[LPC32XX_CLK_HCLK_PLL], 208000000); - /* Set 48MHz rate of USB PLL clock */ clk_set_rate(clk[LPC32XX_CLK_USB_PLL], 48000000); diff --git a/include/dt-bindings/clock/lpc32xx-clock.h b/include/dt-bindings/clock/lpc32xx-clock.h index bcb1c9a..d41b6fe 100644 --- a/include/dt-bindings/clock/lpc32xx-clock.h +++ b/include/dt-bindings/clock/lpc32xx-clock.h @@ -47,6 +47,7 @@ #define LPC32XX_CLK_PWM1 32 #define LPC32XX_CLK_PWM2 33 #define LPC32XX_CLK_ADC 34 +#define LPC32XX_CLK_HCLK_PLL 35 /* LPC32XX USB clocks */ #define LPC32XX_USB_CLK_I2C 1 -- cgit v0.10.2 From 96f185ac9a90264463254366f45d7b46482eec96 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Tue, 2 Feb 2016 09:47:10 +0100 Subject: clk: sunxi: Make clocks setup functions return their clock The clocks registration code in clk-sunxi was most of the time not returning the struct clk (or struct clk array) that was registered, preventing the users of such functions to manipulate it, for example to protect it. Make them return it so that we can start using it. Signed-off-by: Maxime Ripard diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index 2524d6f..f777b4f 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -615,8 +615,8 @@ static const struct mux_data sun8i_h3_ahb2_mux_data __initconst = { .shift = 0, }; -static void __init sunxi_mux_clk_setup(struct device_node *node, - struct mux_data *data) +static struct clk * __init sunxi_mux_clk_setup(struct device_node *node, + struct mux_data *data) { struct clk *clk; const char *clk_name = node->name; @@ -646,10 +646,12 @@ static void __init sunxi_mux_clk_setup(struct device_node *node, of_clk_add_provider(node, of_clk_src_simple_get, clk); clk_register_clkdev(clk, clk_name, NULL); - return; + + return clk; out_unmap: iounmap(reg); + return NULL; } @@ -820,8 +822,8 @@ static const struct divs_data sun6i_a31_pll6_divs_data __initconst = { * |________________________| */ -static void __init sunxi_divs_clk_setup(struct device_node *node, - struct divs_data *data) +static struct clk ** __init sunxi_divs_clk_setup(struct device_node *node, + struct divs_data *data) { struct clk_onecell_data *clk_data; const char *parent; @@ -848,7 +850,7 @@ static void __init sunxi_divs_clk_setup(struct device_node *node, clk_data = kmalloc(sizeof(struct clk_onecell_data), GFP_KERNEL); if (!clk_data) - return; + return NULL; clks = kcalloc(ndivs, sizeof(*clks), GFP_KERNEL); if (!clks) @@ -934,7 +936,7 @@ static void __init sunxi_divs_clk_setup(struct device_node *node, of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); - return; + return clks; free_gate: kfree(gate); @@ -942,6 +944,7 @@ free_clks: kfree(clks); free_clkdata: kfree(clk_data); + return NULL; } -- cgit v0.10.2 From 5b5226d17df6175f1f0dd1a1a37e36770ed00116 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Tue, 2 Feb 2016 09:47:11 +0100 Subject: clk: sunxi: Make clocks setup functions take const pointer All the data structure that we pass to the clocks setup functions are declared const, while our setup functions expects a regular pointer. This was hidden by the fact that we cast a void * pointer back to these structures, which made it go unnoticed. Fix the functions prototype. Acked-by: Chen-Yu Tsai Reviewed-by: Andre Przywara Signed-off-by: Maxime Ripard diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index f777b4f..77d91e3 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -616,7 +616,7 @@ static const struct mux_data sun8i_h3_ahb2_mux_data __initconst = { }; static struct clk * __init sunxi_mux_clk_setup(struct device_node *node, - struct mux_data *data) + const struct mux_data *data) { struct clk *clk; const char *clk_name = node->name; @@ -712,7 +712,7 @@ static const struct div_data sun4i_apb0_data __initconst = { }; static void __init sunxi_divider_clk_setup(struct device_node *node, - struct div_data *data) + const struct div_data *data) { struct clk *clk; const char *clk_name = node->name; @@ -823,7 +823,7 @@ static const struct divs_data sun6i_a31_pll6_divs_data __initconst = { */ static struct clk ** __init sunxi_divs_clk_setup(struct device_node *node, - struct divs_data *data) + const struct divs_data *data) { struct clk_onecell_data *clk_data; const char *parent; -- cgit v0.10.2 From c0872308752df85d817a730d6d5b2d7175c2305b Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Tue, 2 Feb 2016 09:07:22 +0100 Subject: clk: sunxi: convert current clocks registration to CLK_OF_DECLARE The current clock registration and protection code has a few drawbacks, the two main ones being that we create a lot of orphans clock in the registration phase, which will be troublesome when we will start being less relaxed about them. The protection code also relies on clkdev, which we don't really use but for this particular case. Fix both at the same time by moving everyone to the CLK_OF_DECLARE that will probe our clock tree in the right and thus avoid orphans, and by protecting directly the clock returned by our registration function. Reviewed-by: Andre Przywara Signed-off-by: Maxime Ripard diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index 77d91e3..bbed4e9 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -585,6 +585,41 @@ static struct clk * __init sunxi_factors_clk_setup(struct device_node *node, return sunxi_factors_register(node, data, &clk_lock, reg); } +static void __init sun4i_pll1_clk_setup(struct device_node *node) +{ + sunxi_factors_clk_setup(node, &sun4i_pll1_data); +} +CLK_OF_DECLARE(sun4i_pll1, "allwinner,sun4i-a10-pll1-clk", + sun4i_pll1_clk_setup); + +static void __init sun6i_pll1_clk_setup(struct device_node *node) +{ + sunxi_factors_clk_setup(node, &sun6i_a31_pll1_data); +} +CLK_OF_DECLARE(sun6i_pll1, "allwinner,sun6i-a31-pll1-clk", + sun6i_pll1_clk_setup); + +static void __init sun8i_pll1_clk_setup(struct device_node *node) +{ + sunxi_factors_clk_setup(node, &sun8i_a23_pll1_data); +} +CLK_OF_DECLARE(sun8i_pll1, "allwinner,sun8i-a23-pll1-clk", + sun8i_pll1_clk_setup); + +static void __init sun7i_pll4_clk_setup(struct device_node *node) +{ + sunxi_factors_clk_setup(node, &sun7i_a20_pll4_data); +} +CLK_OF_DECLARE(sun7i_pll4, "allwinner,sun7i-a20-pll4-clk", + sun7i_pll4_clk_setup); + +static void __init sun5i_ahb_clk_setup(struct device_node *node) +{ + sunxi_factors_clk_setup(node, &sun5i_a13_ahb_data); +} +CLK_OF_DECLARE(sun5i_ahb, "allwinner,sun5i-a13-ahb-clk", + sun5i_ahb_clk_setup); + static void __init sun6i_ahb1_clk_setup(struct device_node *node) { sunxi_factors_clk_setup(node, &sun6i_ahb1_data); @@ -592,6 +627,20 @@ static void __init sun6i_ahb1_clk_setup(struct device_node *node) CLK_OF_DECLARE(sun6i_a31_ahb1, "allwinner,sun6i-a31-ahb1-clk", sun6i_ahb1_clk_setup); +static void __init sun4i_apb1_clk_setup(struct device_node *node) +{ + sunxi_factors_clk_setup(node, &sun4i_apb1_data); +} +CLK_OF_DECLARE(sun4i_apb1, "allwinner,sun4i-a10-apb1-clk", + sun4i_apb1_clk_setup); + +static void __init sun7i_out_clk_setup(struct device_node *node) +{ + sunxi_factors_clk_setup(node, &sun7i_a20_out_data); +} +CLK_OF_DECLARE(sun7i_out, "allwinner,sun7i-a20-out-clk", + sun7i_out_clk_setup); + /** * sunxi_mux_clk_setup() - Setup function for muxes @@ -654,6 +703,34 @@ out_unmap: return NULL; } +static void __init sun4i_cpu_clk_setup(struct device_node *node) +{ + struct clk *clk; + + clk = sunxi_mux_clk_setup(node, &sun4i_cpu_mux_data); + if (!clk) + return; + + /* Protect CPU clock */ + __clk_get(clk); + clk_prepare_enable(clk); +} +CLK_OF_DECLARE(sun4i_cpu, "allwinner,sun4i-a10-cpu-clk", + sun4i_cpu_clk_setup); + +static void __init sun6i_ahb1_mux_clk_setup(struct device_node *node) +{ + sunxi_mux_clk_setup(node, &sun6i_a31_ahb1_mux_data); +} +CLK_OF_DECLARE(sun6i_ahb1_mux, "allwinner,sun6i-a31-ahb1-mux-clk", + sun6i_ahb1_mux_clk_setup); + +static void __init sun8i_ahb2_clk_setup(struct device_node *node) +{ + sunxi_mux_clk_setup(node, &sun8i_h3_ahb2_mux_data); +} +CLK_OF_DECLARE(sun8i_ahb2, "allwinner,sun8i-h3-ahb2-clk", + sun8i_ahb2_clk_setup); /** @@ -735,6 +812,34 @@ static void __init sunxi_divider_clk_setup(struct device_node *node, } } +static void __init sun4i_ahb_clk_setup(struct device_node *node) +{ + sunxi_divider_clk_setup(node, &sun4i_ahb_data); +} +CLK_OF_DECLARE(sun4i_ahb, "allwinner,sun4i-a10-ahb-clk", + sun4i_ahb_clk_setup); + +static void __init sun4i_apb0_clk_setup(struct device_node *node) +{ + sunxi_divider_clk_setup(node, &sun4i_apb0_data); +} +CLK_OF_DECLARE(sun4i_apb0, "allwinner,sun4i-a10-apb0-clk", + sun4i_apb0_clk_setup); + +static void __init sun4i_axi_clk_setup(struct device_node *node) +{ + sunxi_divider_clk_setup(node, &sun4i_axi_data); +} +CLK_OF_DECLARE(sun4i_axi, "allwinner,sun4i-a10-axi-clk", + sun4i_axi_clk_setup); + +static void __init sun8i_axi_clk_setup(struct device_node *node) +{ + sunxi_divider_clk_setup(node, &sun8i_a23_axi_data); +} +CLK_OF_DECLARE(sun8i_axi, "allwinner,sun8i-a23-axi-clk", + sun8i_axi_clk_setup); + /** @@ -947,42 +1052,53 @@ free_clkdata: return NULL; } +static void __init sun4i_pll5_clk_setup(struct device_node *node) +{ + struct clk **clks; + + clks = sunxi_divs_clk_setup(node, &pll5_divs_data); + if (!clks) + return; + + /* Protect PLL5_DDR */ + __clk_get(clks[0]); + clk_prepare_enable(clks[0]); +} +CLK_OF_DECLARE(sun4i_pll5, "allwinner,sun4i-a10-pll5-clk", + sun4i_pll5_clk_setup); + +static void __init sun4i_pll6_clk_setup(struct device_node *node) +{ + sunxi_divs_clk_setup(node, &pll6_divs_data); +} +CLK_OF_DECLARE(sun4i_pll6, "allwinner,sun4i-a10-pll6-clk", + sun4i_pll6_clk_setup); + +static void __init sun6i_pll6_clk_setup(struct device_node *node) +{ + sunxi_divs_clk_setup(node, &sun6i_a31_pll6_divs_data); +} +CLK_OF_DECLARE(sun6i_pll6, "allwinner,sun6i-a31-pll6-clk", + sun6i_pll6_clk_setup); /* Matches for factors clocks */ static const struct of_device_id clk_factors_match[] __initconst = { - {.compatible = "allwinner,sun4i-a10-pll1-clk", .data = &sun4i_pll1_data,}, - {.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,}, - {.compatible = "allwinner,sun8i-a23-pll1-clk", .data = &sun8i_a23_pll1_data,}, - {.compatible = "allwinner,sun7i-a20-pll4-clk", .data = &sun7i_a20_pll4_data,}, - {.compatible = "allwinner,sun5i-a13-ahb-clk", .data = &sun5i_a13_ahb_data,}, - {.compatible = "allwinner,sun4i-a10-apb1-clk", .data = &sun4i_apb1_data,}, - {.compatible = "allwinner,sun7i-a20-out-clk", .data = &sun7i_a20_out_data,}, {} }; /* Matches for divider clocks */ static const struct of_device_id clk_div_match[] __initconst = { - {.compatible = "allwinner,sun4i-a10-axi-clk", .data = &sun4i_axi_data,}, - {.compatible = "allwinner,sun8i-a23-axi-clk", .data = &sun8i_a23_axi_data,}, - {.compatible = "allwinner,sun4i-a10-ahb-clk", .data = &sun4i_ahb_data,}, - {.compatible = "allwinner,sun4i-a10-apb0-clk", .data = &sun4i_apb0_data,}, {} }; /* Matches for divided outputs */ static const struct of_device_id clk_divs_match[] __initconst = { - {.compatible = "allwinner,sun4i-a10-pll5-clk", .data = &pll5_divs_data,}, - {.compatible = "allwinner,sun4i-a10-pll6-clk", .data = &pll6_divs_data,}, - {.compatible = "allwinner,sun6i-a31-pll6-clk", .data = &sun6i_a31_pll6_divs_data,}, {} }; /* Matches for mux clocks */ static const struct of_device_id clk_mux_match[] __initconst = { - {.compatible = "allwinner,sun4i-a10-cpu-clk", .data = &sun4i_cpu_mux_data,}, - {.compatible = "allwinner,sun6i-a31-ahb1-mux-clk", .data = &sun6i_a31_ahb1_mux_data,}, - {.compatible = "allwinner,sun8i-h3-ahb2-clk", .data = &sun8i_h3_ahb2_mux_data,}, {} }; -- cgit v0.10.2 From 3a4d9af48a947b6605fb3a17505da94d70d05de4 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Tue, 2 Feb 2016 09:07:37 +0100 Subject: clk: sunxi: Remove old probe and protection code Now that we don't have any user left for the old registration code, we can remove it. Signed-off-by: Maxime Ripard diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index bbed4e9..6c5b104 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -1080,111 +1080,3 @@ static void __init sun6i_pll6_clk_setup(struct device_node *node) } CLK_OF_DECLARE(sun6i_pll6, "allwinner,sun6i-a31-pll6-clk", sun6i_pll6_clk_setup); - - -/* Matches for factors clocks */ -static const struct of_device_id clk_factors_match[] __initconst = { - {} -}; - -/* Matches for divider clocks */ -static const struct of_device_id clk_div_match[] __initconst = { - {} -}; - -/* Matches for divided outputs */ -static const struct of_device_id clk_divs_match[] __initconst = { - {} -}; - -/* Matches for mux clocks */ -static const struct of_device_id clk_mux_match[] __initconst = { - {} -}; - - -static void __init of_sunxi_table_clock_setup(const struct of_device_id *clk_match, - void *function) -{ - struct device_node *np; - const struct div_data *data; - const struct of_device_id *match; - void (*setup_function)(struct device_node *, const void *) = function; - - for_each_matching_node_and_match(np, clk_match, &match) { - data = match->data; - setup_function(np, data); - } -} - -static void __init sunxi_init_clocks(const char *clocks[], int nclocks) -{ - unsigned int i; - - /* Register divided output clocks */ - of_sunxi_table_clock_setup(clk_divs_match, sunxi_divs_clk_setup); - - /* Register factor clocks */ - of_sunxi_table_clock_setup(clk_factors_match, sunxi_factors_clk_setup); - - /* Register divider clocks */ - of_sunxi_table_clock_setup(clk_div_match, sunxi_divider_clk_setup); - - /* Register mux clocks */ - of_sunxi_table_clock_setup(clk_mux_match, sunxi_mux_clk_setup); - - /* Protect the clocks that needs to stay on */ - for (i = 0; i < nclocks; i++) { - struct clk *clk = clk_get(NULL, clocks[i]); - - if (!IS_ERR(clk)) - clk_prepare_enable(clk); - } -} - -static const char *sun4i_a10_critical_clocks[] __initdata = { - "pll5_ddr", -}; - -static void __init sun4i_a10_init_clocks(struct device_node *node) -{ - sunxi_init_clocks(sun4i_a10_critical_clocks, - ARRAY_SIZE(sun4i_a10_critical_clocks)); -} -CLK_OF_DECLARE(sun4i_a10_clk_init, "allwinner,sun4i-a10", sun4i_a10_init_clocks); - -static const char *sun5i_critical_clocks[] __initdata = { - "cpu", - "pll5_ddr", -}; - -static void __init sun5i_init_clocks(struct device_node *node) -{ - sunxi_init_clocks(sun5i_critical_clocks, - ARRAY_SIZE(sun5i_critical_clocks)); -} -CLK_OF_DECLARE(sun5i_a10s_clk_init, "allwinner,sun5i-a10s", sun5i_init_clocks); -CLK_OF_DECLARE(sun5i_a13_clk_init, "allwinner,sun5i-a13", sun5i_init_clocks); -CLK_OF_DECLARE(sun5i_r8_clk_init, "allwinner,sun5i-r8", sun5i_init_clocks); -CLK_OF_DECLARE(sun7i_a20_clk_init, "allwinner,sun7i-a20", sun5i_init_clocks); - -static const char *sun6i_critical_clocks[] __initdata = { - "cpu", -}; - -static void __init sun6i_init_clocks(struct device_node *node) -{ - sunxi_init_clocks(sun6i_critical_clocks, - ARRAY_SIZE(sun6i_critical_clocks)); -} -CLK_OF_DECLARE(sun6i_a31_clk_init, "allwinner,sun6i-a31", sun6i_init_clocks); -CLK_OF_DECLARE(sun6i_a31s_clk_init, "allwinner,sun6i-a31s", sun6i_init_clocks); -CLK_OF_DECLARE(sun8i_a23_clk_init, "allwinner,sun8i-a23", sun6i_init_clocks); -CLK_OF_DECLARE(sun8i_a33_clk_init, "allwinner,sun8i-a33", sun6i_init_clocks); -CLK_OF_DECLARE(sun8i_h3_clk_init, "allwinner,sun8i-h3", sun6i_init_clocks); - -static void __init sun9i_init_clocks(struct device_node *node) -{ - sunxi_init_clocks(NULL, 0); -} -CLK_OF_DECLARE(sun9i_a80_clk_init, "allwinner,sun9i-a80", sun9i_init_clocks); -- cgit v0.10.2 From b0b6413f0dc8d1faba98745cf3a008ed9493df59 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Tue, 2 Feb 2016 09:37:15 +0100 Subject: clk: sunxi: Remove clk_register_clkdev calls Now that our protection code doesn't use the global name lookup anymore, we can remove the clkdev registrations. Signed-off-by: Maxime Ripard diff --git a/drivers/clk/sunxi/clk-a10-hosc.c b/drivers/clk/sunxi/clk-a10-hosc.c index 0481d5d..6b598c6 100644 --- a/drivers/clk/sunxi/clk-a10-hosc.c +++ b/drivers/clk/sunxi/clk-a10-hosc.c @@ -15,9 +15,9 @@ */ #include -#include #include #include +#include #define SUNXI_OSC24M_GATE 0 @@ -61,7 +61,6 @@ static void __init sun4i_osc_clk_setup(struct device_node *node) goto err_free_gate; of_clk_add_provider(node, of_clk_src_simple_get, clk); - clk_register_clkdev(clk, clk_name, NULL); return; diff --git a/drivers/clk/sunxi/clk-a20-gmac.c b/drivers/clk/sunxi/clk-a20-gmac.c index 1611b03..3437f73 100644 --- a/drivers/clk/sunxi/clk-a20-gmac.c +++ b/drivers/clk/sunxi/clk-a20-gmac.c @@ -17,7 +17,6 @@ */ #include -#include #include #include #include @@ -107,7 +106,6 @@ static void __init sun7i_a20_gmac_clk_setup(struct device_node *node) goto iounmap_reg; of_clk_add_provider(node, of_clk_src_simple_get, clk); - clk_register_clkdev(clk, clk_name, NULL); return; diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c index 6e97f46..ddefe96 100644 --- a/drivers/clk/sunxi/clk-factors.c +++ b/drivers/clk/sunxi/clk-factors.c @@ -258,14 +258,8 @@ struct clk *sunxi_factors_register(struct device_node *node, if (ret) goto err_provider; - ret = clk_register_clkdev(clk, clk_name, NULL); - if (ret) - goto err_clkdev; - return clk; -err_clkdev: - of_clk_del_provider(node); err_provider: /* TODO: The composite clock stuff will leak a bit here. */ clk_unregister(clk); @@ -291,7 +285,6 @@ void sunxi_factors_unregister(struct device_node *node, struct clk *clk) factors = to_clk_factors(hw); name = clk_hw_get_name(hw); - /* No unregister call for clkdev_* */ of_clk_del_provider(node); /* TODO: The composite clock stuff will leak a bit here. */ clk_unregister(clk); diff --git a/drivers/clk/sunxi/clk-factors.h b/drivers/clk/sunxi/clk-factors.h index a44a865..1e63c5b 100644 --- a/drivers/clk/sunxi/clk-factors.h +++ b/drivers/clk/sunxi/clk-factors.h @@ -2,7 +2,6 @@ #define __MACH_SUNXI_CLK_FACTORS_H #include -#include #include #define SUNXI_FACTORS_NOT_APPLICABLE (0) diff --git a/drivers/clk/sunxi/clk-mod0.c b/drivers/clk/sunxi/clk-mod0.c index 578bff0..b38d71c 100644 --- a/drivers/clk/sunxi/clk-mod0.c +++ b/drivers/clk/sunxi/clk-mod0.c @@ -15,6 +15,7 @@ */ #include +#include #include #include #include diff --git a/drivers/clk/sunxi/clk-sun6i-apb0-gates.c b/drivers/clk/sunxi/clk-sun6i-apb0-gates.c index 23d042a..68021fa 100644 --- a/drivers/clk/sunxi/clk-sun6i-apb0-gates.c +++ b/drivers/clk/sunxi/clk-sun6i-apb0-gates.c @@ -9,7 +9,6 @@ */ #include -#include #include #include #include @@ -87,7 +86,6 @@ static int sun6i_a31_apb0_gates_clk_probe(struct platform_device *pdev) clk_parent, 0, reg, i, 0, NULL); WARN_ON(IS_ERR(clk_data->clks[i])); - clk_register_clkdev(clk_data->clks[i], clk_name, NULL); j++; } diff --git a/drivers/clk/sunxi/clk-sun9i-core.c b/drivers/clk/sunxi/clk-sun9i-core.c index a812110..43f014f 100644 --- a/drivers/clk/sunxi/clk-sun9i-core.c +++ b/drivers/clk/sunxi/clk-sun9i-core.c @@ -15,6 +15,7 @@ */ #include +#include #include #include #include diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index 6c5b104..99f60ef 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -694,7 +694,6 @@ static struct clk * __init sunxi_mux_clk_setup(struct device_node *node, } of_clk_add_provider(node, of_clk_src_simple_get, clk); - clk_register_clkdev(clk, clk_name, NULL); return clk; @@ -806,10 +805,8 @@ static void __init sunxi_divider_clk_setup(struct device_node *node, reg, data->shift, data->width, data->pow ? CLK_DIVIDER_POWER_OF_TWO : 0, data->table, &clk_lock); - if (clk) { + if (clk) of_clk_add_provider(node, of_clk_src_simple_get, clk); - clk_register_clkdev(clk, clk_name, NULL); - } } static void __init sun4i_ahb_clk_setup(struct device_node *node) @@ -1033,7 +1030,6 @@ static struct clk ** __init sunxi_divs_clk_setup(struct device_node *node, clkflags); WARN_ON(IS_ERR(clk_data->clks[i])); - clk_register_clkdev(clks[i], clk_name, NULL); } /* Adjust to the real max */ -- cgit v0.10.2 From c2c7f0a47493ae23f9a76fabdbdd4f25e1de0925 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Tue, 1 Dec 2015 21:42:11 +0530 Subject: clk: qcom: gdsc: Add support for hierarchical power domains Some qcom SoCs' can have hierarchical power domains. Let the gdsc structs specify the parents (if any) and the driver add genpd subdomains for them. Signed-off-by: Rajendra Nayak Signed-off-by: Stephen Boyd diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c index 65809f1..cc8a065 100644 --- a/drivers/clk/qcom/common.c +++ b/drivers/clk/qcom/common.c @@ -185,6 +185,7 @@ int qcom_cc_really_probe(struct platform_device *pdev, struct clk **clks; struct qcom_reset_controller *reset; struct qcom_cc *cc; + struct gdsc_desc *scd; size_t num_clks = desc->num_clks; struct clk_regmap **rclks = desc->clks; @@ -238,13 +239,22 @@ int qcom_cc_really_probe(struct platform_device *pdev, return ret; if (desc->gdscs && desc->num_gdscs) { - ret = gdsc_register(dev, desc->gdscs, desc->num_gdscs, - &reset->rcdev, regmap); + scd = devm_kzalloc(dev, sizeof(*scd), GFP_KERNEL); + if (!scd) + return -ENOMEM; + scd->dev = dev; + scd->scs = desc->gdscs; + scd->num = desc->num_gdscs; + ret = gdsc_register(scd, &reset->rcdev, regmap); + if (ret) + return ret; + ret = devm_add_action_or_reset(dev, qcom_cc_gdsc_unregister, + scd); if (ret) return ret; } - return devm_add_action_or_reset(dev, qcom_cc_gdsc_unregister, dev); + return 0; } EXPORT_SYMBOL_GPL(qcom_cc_really_probe); diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index da9fad8..bfab75b 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c @@ -201,11 +201,14 @@ static int gdsc_init(struct gdsc *sc) return 0; } -int gdsc_register(struct device *dev, struct gdsc **scs, size_t num, +int gdsc_register(struct gdsc_desc *desc, struct reset_controller_dev *rcdev, struct regmap *regmap) { int i, ret; struct genpd_onecell_data *data; + struct device *dev = desc->dev; + struct gdsc **scs = desc->scs; + size_t num = desc->num; data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); if (!data) @@ -228,10 +231,30 @@ int gdsc_register(struct device *dev, struct gdsc **scs, size_t num, data->domains[i] = &scs[i]->pd; } + /* Add subdomains */ + for (i = 0; i < num; i++) { + if (!scs[i]) + continue; + if (scs[i]->parent) + pm_genpd_add_subdomain(scs[i]->parent, &scs[i]->pd); + } + return of_genpd_add_provider_onecell(dev->of_node, data); } -void gdsc_unregister(struct device *dev) +void gdsc_unregister(struct gdsc_desc *desc) { + int i; + struct device *dev = desc->dev; + struct gdsc **scs = desc->scs; + size_t num = desc->num; + + /* Remove subdomains */ + for (i = 0; i < num; i++) { + if (!scs[i]) + continue; + if (scs[i]->parent) + pm_genpd_remove_subdomain(scs[i]->parent, &scs[i]->pd); + } of_genpd_del_provider(dev->of_node); } diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h index 5ded268..4e9dfc1 100644 --- a/drivers/clk/qcom/gdsc.h +++ b/drivers/clk/qcom/gdsc.h @@ -41,6 +41,7 @@ struct reset_controller_dev; */ struct gdsc { struct generic_pm_domain pd; + struct generic_pm_domain *parent; struct regmap *regmap; unsigned int gdscr; unsigned int *cxcs; @@ -51,18 +52,24 @@ struct gdsc { unsigned int reset_count; }; +struct gdsc_desc { + struct device *dev; + struct gdsc **scs; + size_t num; +}; + #ifdef CONFIG_QCOM_GDSC -int gdsc_register(struct device *, struct gdsc **, size_t n, - struct reset_controller_dev *, struct regmap *); -void gdsc_unregister(struct device *); +int gdsc_register(struct gdsc_desc *desc, struct reset_controller_dev *, + struct regmap *); +void gdsc_unregister(struct gdsc_desc *desc); #else -static inline int gdsc_register(struct device *d, struct gdsc **g, size_t n, +static inline int gdsc_register(struct gdsc_desc *desc, struct reset_controller_dev *rcdev, struct regmap *r) { return -ENOSYS; } -static inline void gdsc_unregister(struct device *d) {}; +static inline void gdsc_unregister(struct gdsc_desc *desc) {}; #endif /* CONFIG_QCOM_GDSC */ #endif /* __QCOM_GDSC_H__ */ -- cgit v0.10.2 From 77b1067a19b4986b009f3279cc6b8ad1d29ff51c Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Tue, 1 Dec 2015 21:42:12 +0530 Subject: clk: qcom: gdsc: Add support for gdscs with gds hw controller Some gdsc power domains can have a gds_hw_controller block inside to help ensure all slave devices within the power domain are idle before the gdsc is actually switched off. This is mainly useful in power domains which host a MMU, in which case its necessary to make sure there are no outstanding MMU operations or pending bus transactions before the power domain is turned off. In gdscs with gds_hw_controller block, its necessary to check the gds_hw_ctrl status bits instead of the ones in gdscr, to determine the state of the powerdomain. While at it, also move away from using jiffies and use ktime APIs instead for busy looping on status bits. Signed-off-by: Rajendra Nayak Signed-off-by: Stephen Boyd diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index bfab75b..9f530b7 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -42,12 +43,12 @@ #define domain_to_gdsc(domain) container_of(domain, struct gdsc, pd) -static int gdsc_is_enabled(struct gdsc *sc) +static int gdsc_is_enabled(struct gdsc *sc, unsigned int reg) { u32 val; int ret; - ret = regmap_read(sc->regmap, sc->gdscr, &val); + ret = regmap_read(sc->regmap, reg, &val); if (ret) return ret; @@ -58,28 +59,35 @@ static int gdsc_toggle_logic(struct gdsc *sc, bool en) { int ret; u32 val = en ? 0 : SW_COLLAPSE_MASK; - u32 check = en ? PWR_ON_MASK : 0; - unsigned long timeout; + ktime_t start; + unsigned int status_reg = sc->gdscr; ret = regmap_update_bits(sc->regmap, sc->gdscr, SW_COLLAPSE_MASK, val); if (ret) return ret; - timeout = jiffies + usecs_to_jiffies(TIMEOUT_US); - do { - ret = regmap_read(sc->regmap, sc->gdscr, &val); - if (ret) - return ret; + if (sc->gds_hw_ctrl) { + status_reg = sc->gds_hw_ctrl; + /* + * The gds hw controller asserts/de-asserts the status bit soon + * after it receives a power on/off request from a master. + * The controller then takes around 8 xo cycles to start its + * internal state machine and update the status bit. During + * this time, the status bit does not reflect the true status + * of the core. + * Add a delay of 1 us between writing to the SW_COLLAPSE bit + * and polling the status bit. + */ + udelay(1); + } - if ((val & PWR_ON_MASK) == check) + start = ktime_get(); + do { + if (gdsc_is_enabled(sc, status_reg) == en) return 0; - } while (time_before(jiffies, timeout)); - - ret = regmap_read(sc->regmap, sc->gdscr, &val); - if (ret) - return ret; + } while (ktime_us_delta(ktime_get(), start) < TIMEOUT_US); - if ((val & PWR_ON_MASK) == check) + if (gdsc_is_enabled(sc, status_reg) == en) return 0; return -ETIMEDOUT; @@ -165,6 +173,7 @@ static int gdsc_init(struct gdsc *sc) { u32 mask, val; int on, ret; + unsigned int reg; /* * Disable HW trigger: collapse/restore occur based on registers writes. @@ -185,7 +194,8 @@ static int gdsc_init(struct gdsc *sc) return ret; } - on = gdsc_is_enabled(sc); + reg = sc->gds_hw_ctrl ? sc->gds_hw_ctrl : sc->gdscr; + on = gdsc_is_enabled(sc, reg); if (on < 0) return on; diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h index 4e9dfc1..66a43be 100644 --- a/drivers/clk/qcom/gdsc.h +++ b/drivers/clk/qcom/gdsc.h @@ -32,6 +32,7 @@ struct reset_controller_dev; * @pd: generic power domain * @regmap: regmap for MMIO accesses * @gdscr: gsdc control register + * @gds_hw_ctrl: gds_hw_ctrl register * @cxcs: offsets of branch registers to toggle mem/periph bits in * @cxc_count: number of @cxcs * @pwrsts: Possible powerdomain power states @@ -44,6 +45,7 @@ struct gdsc { struct generic_pm_domain *parent; struct regmap *regmap; unsigned int gdscr; + unsigned int gds_hw_ctrl; unsigned int *cxcs; unsigned int cxc_count; const u8 pwrsts; -- cgit v0.10.2 From a823bb9fbefbac8d8bf37d5b4879ee876f2356c5 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Tue, 1 Dec 2015 21:42:13 +0530 Subject: clk: qcom: gdsc: Add support for votable gdscs Some gdscs might be controlled via voting registers and might not really disable when the kernel intends to disable them (due to other votes keeping them enabled) Mark these gdscs with a flag for we do not check/wait on a disable status for these gdscs within the kernel disable callback. Also at boot, if these GDSCs are found to be ON, we make sure we vote for them before we inform the genpd framework about their status. If genpd gets no users, it then disables (removes the vote) them as part of genpd_poweroff_unused() Signed-off-by: Rajendra Nayak Signed-off-by: Stephen Boyd diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index 9f530b7..f12d7b2 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c @@ -66,6 +66,17 @@ static int gdsc_toggle_logic(struct gdsc *sc, bool en) if (ret) return ret; + /* If disabling votable gdscs, don't poll on status */ + if ((sc->flags & VOTABLE) && !en) { + /* + * Add a short delay here to ensure that an enable + * right after it was disabled does not put it in an + * unknown state + */ + udelay(TIMEOUT_US); + return 0; + } + if (sc->gds_hw_ctrl) { status_reg = sc->gds_hw_ctrl; /* @@ -199,6 +210,13 @@ static int gdsc_init(struct gdsc *sc) if (on < 0) return on; + /* + * Votable GDSCs can be ON due to Vote from other masters. + * If a Votable GDSC is ON, make sure we have a Vote. + */ + if ((sc->flags & VOTABLE) && on) + gdsc_enable(&sc->pd); + if (on || (sc->pwrsts & PWRSTS_RET)) gdsc_force_mem_on(sc); else diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h index 66a43be..3bf497c 100644 --- a/drivers/clk/qcom/gdsc.h +++ b/drivers/clk/qcom/gdsc.h @@ -20,13 +20,6 @@ struct regmap; struct reset_controller_dev; -/* Powerdomain allowable state bitfields */ -#define PWRSTS_OFF BIT(0) -#define PWRSTS_RET BIT(1) -#define PWRSTS_ON BIT(2) -#define PWRSTS_OFF_ON (PWRSTS_OFF | PWRSTS_ON) -#define PWRSTS_RET_ON (PWRSTS_RET | PWRSTS_ON) - /** * struct gdsc - Globally Distributed Switch Controller * @pd: generic power domain @@ -49,6 +42,14 @@ struct gdsc { unsigned int *cxcs; unsigned int cxc_count; const u8 pwrsts; +/* Powerdomain allowable state bitfields */ +#define PWRSTS_OFF BIT(0) +#define PWRSTS_RET BIT(1) +#define PWRSTS_ON BIT(2) +#define PWRSTS_OFF_ON (PWRSTS_OFF | PWRSTS_ON) +#define PWRSTS_RET_ON (PWRSTS_RET | PWRSTS_ON) + const u8 flags; +#define VOTABLE BIT(0) struct reset_controller_dev *rcdev; unsigned int *resets; unsigned int reset_count; -- cgit v0.10.2 From 52111672f7916537c8f50857088aaa4e709324e7 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Tue, 1 Dec 2015 21:42:14 +0530 Subject: clk: qcom: gdsc: Add GDSCs in msm8996 GCC Add all data for the GDSCs which are part of msm8996 GCC block Signed-off-by: Rajendra Nayak Signed-off-by: Stephen Boyd diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c index 16d7c32..bb8c61f 100644 --- a/drivers/clk/qcom/gcc-msm8996.c +++ b/drivers/clk/qcom/gcc-msm8996.c @@ -30,6 +30,7 @@ #include "clk-rcg.h" #include "clk-branch.h" #include "reset.h" +#include "gdsc.h" #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } @@ -3059,6 +3060,83 @@ static struct clk_hw *gcc_msm8996_hws[] = { &ufs_ice_core_postdiv_clk_src.hw, }; +static struct gdsc aggre0_noc_gdsc = { + .gdscr = 0x81004, + .gds_hw_ctrl = 0x81028, + .pd = { + .name = "aggre0_noc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc hlos1_vote_aggre0_noc_gdsc = { + .gdscr = 0x7d024, + .pd = { + .name = "hlos1_vote_aggre0_noc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc hlos1_vote_lpass_adsp_gdsc = { + .gdscr = 0x7d034, + .pd = { + .name = "hlos1_vote_lpass_adsp", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc hlos1_vote_lpass_core_gdsc = { + .gdscr = 0x7d038, + .pd = { + .name = "hlos1_vote_lpass_core", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc usb30_gdsc = { + .gdscr = 0xf004, + .pd = { + .name = "usb30", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc pcie0_gdsc = { + .gdscr = 0x6b004, + .pd = { + .name = "pcie0", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc pcie1_gdsc = { + .gdscr = 0x6d004, + .pd = { + .name = "pcie1", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc pcie2_gdsc = { + .gdscr = 0x6e004, + .pd = { + .name = "pcie2", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc ufs_gdsc = { + .gdscr = 0x75004, + .pd = { + .name = "ufs", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + static struct clk_regmap *gcc_msm8996_clocks[] = { [GPLL0_EARLY] = &gpll0_early.clkr, [GPLL0] = &gpll0.clkr, @@ -3245,6 +3323,18 @@ static struct clk_regmap *gcc_msm8996_clocks[] = { [GCC_RX1_USB2_CLKREF_CLK] = &gcc_rx1_usb2_clkref_clk.clkr, }; +static struct gdsc *gcc_msm8996_gdscs[] = { + [AGGRE0_NOC_GDSC] = &aggre0_noc_gdsc, + [HLOS1_VOTE_AGGRE0_NOC_GDSC] = &hlos1_vote_aggre0_noc_gdsc, + [HLOS1_VOTE_LPASS_ADSP_GDSC] = &hlos1_vote_lpass_adsp_gdsc, + [HLOS1_VOTE_LPASS_CORE_GDSC] = &hlos1_vote_lpass_core_gdsc, + [USB30_GDSC] = &usb30_gdsc, + [PCIE0_GDSC] = &pcie0_gdsc, + [PCIE1_GDSC] = &pcie1_gdsc, + [PCIE2_GDSC] = &pcie2_gdsc, + [UFS_GDSC] = &ufs_gdsc, +}; + static const struct qcom_reset_map gcc_msm8996_resets[] = { [GCC_SYSTEM_NOC_BCR] = { 0x4000 }, [GCC_CONFIG_NOC_BCR] = { 0x5000 }, @@ -3363,6 +3453,8 @@ static const struct qcom_cc_desc gcc_msm8996_desc = { .num_clks = ARRAY_SIZE(gcc_msm8996_clocks), .resets = gcc_msm8996_resets, .num_resets = ARRAY_SIZE(gcc_msm8996_resets), + .gdscs = gcc_msm8996_gdscs, + .num_gdscs = ARRAY_SIZE(gcc_msm8996_gdscs), }; static const struct of_device_id gcc_msm8996_match_table[] = { diff --git a/include/dt-bindings/clock/qcom,gcc-msm8996.h b/include/dt-bindings/clock/qcom,gcc-msm8996.h index 888e75c..6f814db 100644 --- a/include/dt-bindings/clock/qcom,gcc-msm8996.h +++ b/include/dt-bindings/clock/qcom,gcc-msm8996.h @@ -336,4 +336,15 @@ #define GCC_MSS_Q6_BCR 99 #define GCC_QREFS_VBG_CAL_BCR 100 +/* Indexes for GDSCs */ +#define AGGRE0_NOC_GDSC 0 +#define HLOS1_VOTE_AGGRE0_NOC_GDSC 1 +#define HLOS1_VOTE_LPASS_ADSP_GDSC 2 +#define HLOS1_VOTE_LPASS_CORE_GDSC 3 +#define USB30_GDSC 4 +#define PCIE0_GDSC 5 +#define PCIE1_GDSC 6 +#define PCIE2_GDSC 7 +#define UFS_GDSC 8 + #endif -- cgit v0.10.2 From 7e824d507909e3683699dfc0bba14a5c971984f9 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Tue, 1 Dec 2015 21:42:15 +0530 Subject: clk: qcom: gdsc: Add mmcc gdscs for msm8996 family Add all gdsc data which are part of mmcc on msm8996 family Signed-off-by: Rajendra Nayak Signed-off-by: Stephen Boyd diff --git a/drivers/clk/qcom/mmcc-msm8996.c b/drivers/clk/qcom/mmcc-msm8996.c index 064f3ea..6df7ff3 100644 --- a/drivers/clk/qcom/mmcc-msm8996.c +++ b/drivers/clk/qcom/mmcc-msm8996.c @@ -32,6 +32,7 @@ #include "clk-rcg.h" #include "clk-branch.h" #include "reset.h" +#include "gdsc.h" #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } @@ -2917,6 +2918,144 @@ static struct clk_hw *mmcc_msm8996_hws[] = { &gpll0_div.hw, }; +static struct gdsc mmagic_video_gdsc = { + .gdscr = 0x119c, + .gds_hw_ctrl = 0x120c, + .pd = { + .name = "mmagic_video", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc mmagic_mdss_gdsc = { + .gdscr = 0x247c, + .gds_hw_ctrl = 0x2480, + .pd = { + .name = "mmagic_mdss", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc mmagic_camss_gdsc = { + .gdscr = 0x3c4c, + .gds_hw_ctrl = 0x3c50, + .pd = { + .name = "mmagic_camss", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc venus_gdsc = { + .gdscr = 0x1024, + .cxcs = (unsigned int []){ 0x1028, 0x1034, 0x1038 }, + .cxc_count = 3, + .pd = { + .name = "venus", + }, + .parent = &mmagic_video_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc venus_core0_gdsc = { + .gdscr = 0x1040, + .cxcs = (unsigned int []){ 0x1048 }, + .cxc_count = 1, + .pd = { + .name = "venus_core0", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc venus_core1_gdsc = { + .gdscr = 0x1044, + .cxcs = (unsigned int []){ 0x104c }, + .cxc_count = 1, + .pd = { + .name = "venus_core1", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc camss_gdsc = { + .gdscr = 0x34a0, + .cxcs = (unsigned int []){ 0x36bc, 0x36c4 }, + .cxc_count = 2, + .pd = { + .name = "camss", + }, + .parent = &mmagic_camss_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc vfe0_gdsc = { + .gdscr = 0x3664, + .cxcs = (unsigned int []){ 0x36a8 }, + .cxc_count = 1, + .pd = { + .name = "vfe0", + }, + .parent = &camss_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc vfe1_gdsc = { + .gdscr = 0x3674, + .cxcs = (unsigned int []){ 0x36ac }, + .cxc_count = 1, + .pd = { + .name = "vfe0", + }, + .parent = &camss_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc jpeg_gdsc = { + .gdscr = 0x35a4, + .cxcs = (unsigned int []){ 0x35a8, 0x35b0, 0x35c0, 0x35b8 }, + .cxc_count = 4, + .pd = { + .name = "jpeg", + }, + .parent = &camss_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc cpp_gdsc = { + .gdscr = 0x36d4, + .cxcs = (unsigned int []){ 0x36b0 }, + .cxc_count = 1, + .pd = { + .name = "cpp", + }, + .parent = &camss_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc fd_gdsc = { + .gdscr = 0x3b64, + .cxcs = (unsigned int []){ 0x3b68, 0x3b6c }, + .cxc_count = 2, + .pd = { + .name = "fd", + }, + .parent = &camss_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc mdss_gdsc = { + .gdscr = 0x2304, + .cxcs = (unsigned int []){ 0x2310, 0x231c }, + .cxc_count = 2, + .pd = { + .name = "mdss", + }, + .parent = &mmagic_mdss_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, +}; + static struct clk_regmap *mmcc_msm8996_clocks[] = { [MMPLL0_EARLY] = &mmpll0_early.clkr, [MMPLL0_PLL] = &mmpll0.clkr, @@ -3093,6 +3232,22 @@ static struct clk_regmap *mmcc_msm8996_clocks[] = { [FD_AHB_CLK] = &fd_ahb_clk.clkr, }; +static struct gdsc *mmcc_msm8996_gdscs[] = { + [MMAGIC_VIDEO_GDSC] = &mmagic_video_gdsc, + [MMAGIC_MDSS_GDSC] = &mmagic_mdss_gdsc, + [MMAGIC_CAMSS_GDSC] = &mmagic_camss_gdsc, + [VENUS_GDSC] = &venus_gdsc, + [VENUS_CORE0_GDSC] = &venus_core0_gdsc, + [VENUS_CORE1_GDSC] = &venus_core1_gdsc, + [CAMSS_GDSC] = &camss_gdsc, + [VFE0_GDSC] = &vfe0_gdsc, + [VFE1_GDSC] = &vfe1_gdsc, + [JPEG_GDSC] = &jpeg_gdsc, + [CPP_GDSC] = &cpp_gdsc, + [FD_GDSC] = &fd_gdsc, + [MDSS_GDSC] = &mdss_gdsc, +}; + static const struct qcom_reset_map mmcc_msm8996_resets[] = { [MMAGICAHB_BCR] = { 0x5020 }, [MMAGIC_CFG_BCR] = { 0x5050 }, @@ -3170,6 +3325,8 @@ static const struct qcom_cc_desc mmcc_msm8996_desc = { .num_clks = ARRAY_SIZE(mmcc_msm8996_clocks), .resets = mmcc_msm8996_resets, .num_resets = ARRAY_SIZE(mmcc_msm8996_resets), + .gdscs = mmcc_msm8996_gdscs, + .num_gdscs = ARRAY_SIZE(mmcc_msm8996_gdscs), }; static const struct of_device_id mmcc_msm8996_match_table[] = { diff --git a/include/dt-bindings/clock/qcom,mmcc-msm8996.h b/include/dt-bindings/clock/qcom,mmcc-msm8996.h index 9b81ca6..7d3a7fa 100644 --- a/include/dt-bindings/clock/qcom,mmcc-msm8996.h +++ b/include/dt-bindings/clock/qcom,mmcc-msm8996.h @@ -282,4 +282,21 @@ #define FD_BCR 58 #define MMSS_SPDM_RM_BCR 59 +/* Indexes for GDSCs */ +#define MMAGIC_VIDEO_GDSC 0 +#define MMAGIC_MDSS_GDSC 1 +#define MMAGIC_CAMSS_GDSC 2 +#define GPU_GDSC 3 +#define VENUS_GDSC 4 +#define VENUS_CORE0_GDSC 5 +#define VENUS_CORE1_GDSC 6 +#define CAMSS_GDSC 7 +#define VFE0_GDSC 8 +#define VFE1_GDSC 9 +#define JPEG_GDSC 10 +#define CPP_GDSC 11 +#define FD_GDSC 12 +#define MDSS_GDSC 13 +#define GPU_GX_GDSC 14 + #endif -- cgit v0.10.2 From 7208d1d9c568de02ca89cc976d206e4196803140 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Tue, 1 Dec 2015 21:42:16 +0530 Subject: clk: qcom: mmcc8974: Use gdscs .parent and remove genpd calls With gdsc driver capable of handling hierarchical power domains, specify oxili_gdsc as parent of oxilicx_gdsc. Remove all direct calls to genpd from the mmcc clock driver. The adding and removing of subdomains is now handled from within the gdsc driver. Signed-off-by: Rajendra Nayak Signed-off-by: Stephen Boyd diff --git a/drivers/clk/qcom/mmcc-msm8974.c b/drivers/clk/qcom/mmcc-msm8974.c index bbe28ed..bcda56e 100644 --- a/drivers/clk/qcom/mmcc-msm8974.c +++ b/drivers/clk/qcom/mmcc-msm8974.c @@ -2400,6 +2400,7 @@ static struct gdsc oxilicx_gdsc = { .pd = { .name = "oxilicx", }, + .parent = &oxili_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, }; @@ -2616,7 +2617,6 @@ MODULE_DEVICE_TABLE(of, mmcc_msm8974_match_table); static int mmcc_msm8974_probe(struct platform_device *pdev) { struct regmap *regmap; - int ret; regmap = qcom_cc_map(pdev, &mmcc_msm8974_desc); if (IS_ERR(regmap)) @@ -2625,22 +2625,11 @@ static int mmcc_msm8974_probe(struct platform_device *pdev) clk_pll_configure_sr_hpm_lp(&mmpll1, regmap, &mmpll1_config, true); clk_pll_configure_sr_hpm_lp(&mmpll3, regmap, &mmpll3_config, false); - ret = qcom_cc_really_probe(pdev, &mmcc_msm8974_desc, regmap); - if (ret) - return ret; - - return pm_genpd_add_subdomain(&oxili_gdsc.pd, &oxilicx_gdsc.pd); -} - -static int mmcc_msm8974_remove(struct platform_device *pdev) -{ - pm_genpd_remove_subdomain(&oxili_gdsc.pd, &oxilicx_gdsc.pd); - return 0; + return qcom_cc_really_probe(pdev, &mmcc_msm8974_desc, regmap); } static struct platform_driver mmcc_msm8974_driver = { .probe = mmcc_msm8974_probe, - .remove = mmcc_msm8974_remove, .driver = { .name = "mmcc-msm8974", .of_match_table = mmcc_msm8974_match_table, -- cgit v0.10.2 From ee36027427c769b0b9e5e205fe43aced93d6aa66 Mon Sep 17 00:00:00 2001 From: Bai Ping Date: Tue, 2 Feb 2016 18:01:34 +0800 Subject: clk: imx: Add clock support for imx6qp most of the clock tree structures on i.MX6 Quad Plus are same as on i.MX6Q. there still some differences between these two SOCs. compared to the i.XM6Q, the differents of clocks on i.MX6QP is mainly on: 1. New clock gate added to support the PRE and PRG modules 2. 24MHz OSC clock option added to the UART, IPG, ECSPI, and CAN clock roots. 3. MMDC channel 1 clock gate is now controllable. 4. clock gating added to the LDB_DIx_IPU clocks on i.MX6QP 5. EMI clock root divider fix 6. other updates fo CSCMRx, CSCDRx and CS2CDR registers. detailed infomation, please refer to the i.MX6QP RM. Signed-off-by: Bai Ping Signed-off-by: Shawn Guo diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c index f0efc6f..02e1818 100644 --- a/drivers/clk/imx/clk-imx6q.c +++ b/drivers/clk/imx/clk-imx6q.c @@ -34,7 +34,9 @@ static const char *periph2_sels[] = { "periph2_pre", "periph2_clk2", }; static const char *axi_sels[] = { "periph", "pll2_pfd2_396m", "periph", "pll3_pfd1_540m", }; static const char *audio_sels[] = { "pll4_audio_div", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", }; static const char *gpu_axi_sels[] = { "axi", "ahb", }; +static const char *pre_axi_sels[] = { "axi", "ahb", }; static const char *gpu2d_core_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", }; +static const char *gpu2d_core_sels_2[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll3_pfd0_720m",}; static const char *gpu3d_core_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", }; static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll3_pfd0_720m", }; static const char *ipu_sels[] = { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", }; @@ -44,15 +46,24 @@ static const char *ipu1_di0_sels[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di static const char *ipu1_di1_sels[] = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; static const char *ipu2_di0_sels[] = { "ipu2_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; static const char *ipu2_di1_sels[] = { "ipu2_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; +static const char *ipu1_di0_sels_2[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0_podf", "ldb_di1_podf", }; +static const char *ipu1_di1_sels_2[] = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0_podf", "ldb_di1_podf", }; +static const char *ipu2_di0_sels_2[] = { "ipu2_di0_pre", "dummy", "dummy", "ldb_di0_podf", "ldb_di1_podf", }; +static const char *ipu2_di1_sels_2[] = { "ipu2_di1_pre", "dummy", "dummy", "ldb_di0_podf", "ldb_di1_podf", }; static const char *hsi_tx_sels[] = { "pll3_120m", "pll2_pfd2_396m", }; static const char *pcie_axi_sels[] = { "axi", "ahb", }; static const char *ssi_sels[] = { "pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_audio_div", }; static const char *usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", }; static const char *enfc_sels[] = { "pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", }; +static const char *enfc_sels_2[] = {"pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", "pll3_pfd3_454m", "dummy", }; static const char *eim_sels[] = { "pll2_pfd2_396m", "pll3_usb_otg", "axi", "pll2_pfd0_352m", }; static const char *eim_slow_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd2_396m", "pll2_pfd0_352m", }; static const char *vdo_axi_sels[] = { "axi", "ahb", }; static const char *vpu_axi_sels[] = { "axi", "pll2_pfd2_396m", "pll2_pfd0_352m", }; +static const char *uart_sels[] = { "pll3_80m", "osc", }; +static const char *ipg_per_sels[] = { "ipg", "osc", }; +static const char *ecspi_sels[] = { "pll3_60m", "osc", }; +static const char *can_sels[] = { "pll3_60m", "osc", "pll3_80m", }; static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video_div", "dummy", "axi", "enfc", "ipu1_di0", "ipu1_di1", "ipu2_di0", "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_audio_div", }; @@ -121,12 +132,19 @@ static unsigned int share_count_ssi2; static unsigned int share_count_ssi3; static unsigned int share_count_mipi_core_cfg; static unsigned int share_count_spdif; +static unsigned int share_count_prg0; +static unsigned int share_count_prg1; static inline int clk_on_imx6q(void) { return of_machine_is_compatible("fsl,imx6q"); } +static inline int clk_on_imx6qp(void) +{ + return of_machine_is_compatible("fsl,imx6qp"); +} + static inline int clk_on_imx6dl(void) { return of_machine_is_compatible("fsl,imx6dl"); @@ -265,7 +283,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[IMX6QDL_CLK_TWD] = imx_clk_fixed_factor("twd", "arm", 1, 2); clk[IMX6QDL_CLK_GPT_3M] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8); clk[IMX6QDL_CLK_VIDEO_27M] = imx_clk_fixed_factor("video_27m", "pll3_pfd1_540m", 1, 20); - if (clk_on_imx6dl()) { + if (clk_on_imx6dl() || clk_on_imx6qp()) { clk[IMX6QDL_CLK_GPU2D_AXI] = imx_clk_fixed_factor("gpu2d_axi", "mmdc_ch0_axi_podf", 1, 1); clk[IMX6QDL_CLK_GPU3D_AXI] = imx_clk_fixed_factor("gpu3d_axi", "mmdc_ch0_axi_podf", 1, 1); } @@ -294,7 +312,15 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[IMX6QDL_CLK_GPU2D_AXI] = imx_clk_mux("gpu2d_axi", base + 0x18, 0, 1, gpu_axi_sels, ARRAY_SIZE(gpu_axi_sels)); clk[IMX6QDL_CLK_GPU3D_AXI] = imx_clk_mux("gpu3d_axi", base + 0x18, 1, 1, gpu_axi_sels, ARRAY_SIZE(gpu_axi_sels)); } - clk[IMX6QDL_CLK_GPU2D_CORE_SEL] = imx_clk_mux("gpu2d_core_sel", base + 0x18, 16, 2, gpu2d_core_sels, ARRAY_SIZE(gpu2d_core_sels)); + if (clk_on_imx6qp()) { + clk[IMX6QDL_CLK_CAN_SEL] = imx_clk_mux("can_sel", base + 0x20, 8, 2, can_sels, ARRAY_SIZE(can_sels)); + clk[IMX6QDL_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels)); + clk[IMX6QDL_CLK_IPG_PER_SEL] = imx_clk_mux("ipg_per_sel", base + 0x1c, 6, 1, ipg_per_sels, ARRAY_SIZE(ipg_per_sels)); + clk[IMX6QDL_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels)); + clk[IMX6QDL_CLK_GPU2D_CORE_SEL] = imx_clk_mux("gpu2d_core_sel", base + 0x18, 16, 2, gpu2d_core_sels_2, ARRAY_SIZE(gpu2d_core_sels_2)); + } else { + clk[IMX6QDL_CLK_GPU2D_CORE_SEL] = imx_clk_mux("gpu2d_core_sel", base + 0x18, 16, 2, gpu2d_core_sels, ARRAY_SIZE(gpu2d_core_sels)); + } clk[IMX6QDL_CLK_GPU3D_CORE_SEL] = imx_clk_mux("gpu3d_core_sel", base + 0x18, 4, 2, gpu3d_core_sels, ARRAY_SIZE(gpu3d_core_sels)); clk[IMX6QDL_CLK_GPU3D_SHADER_SEL] = imx_clk_mux("gpu3d_shader_sel", base + 0x18, 8, 2, gpu3d_shader_sels, ARRAY_SIZE(gpu3d_shader_sels)); clk[IMX6QDL_CLK_IPU1_SEL] = imx_clk_mux("ipu1_sel", base + 0x3c, 9, 2, ipu_sels, ARRAY_SIZE(ipu_sels)); @@ -305,22 +331,40 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[IMX6QDL_CLK_IPU1_DI1_PRE_SEL] = imx_clk_mux_flags("ipu1_di1_pre_sel", base + 0x34, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT); clk[IMX6QDL_CLK_IPU2_DI0_PRE_SEL] = imx_clk_mux_flags("ipu2_di0_pre_sel", base + 0x38, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT); clk[IMX6QDL_CLK_IPU2_DI1_PRE_SEL] = imx_clk_mux_flags("ipu2_di1_pre_sel", base + 0x38, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT); - clk[IMX6QDL_CLK_IPU1_DI0_SEL] = imx_clk_mux_flags("ipu1_di0_sel", base + 0x34, 0, 3, ipu1_di0_sels, ARRAY_SIZE(ipu1_di0_sels), CLK_SET_RATE_PARENT); - clk[IMX6QDL_CLK_IPU1_DI1_SEL] = imx_clk_mux_flags("ipu1_di1_sel", base + 0x34, 9, 3, ipu1_di1_sels, ARRAY_SIZE(ipu1_di1_sels), CLK_SET_RATE_PARENT); - clk[IMX6QDL_CLK_IPU2_DI0_SEL] = imx_clk_mux_flags("ipu2_di0_sel", base + 0x38, 0, 3, ipu2_di0_sels, ARRAY_SIZE(ipu2_di0_sels), CLK_SET_RATE_PARENT); - clk[IMX6QDL_CLK_IPU2_DI1_SEL] = imx_clk_mux_flags("ipu2_di1_sel", base + 0x38, 9, 3, ipu2_di1_sels, ARRAY_SIZE(ipu2_di1_sels), CLK_SET_RATE_PARENT); clk[IMX6QDL_CLK_HSI_TX_SEL] = imx_clk_mux("hsi_tx_sel", base + 0x30, 28, 1, hsi_tx_sels, ARRAY_SIZE(hsi_tx_sels)); clk[IMX6QDL_CLK_PCIE_AXI_SEL] = imx_clk_mux("pcie_axi_sel", base + 0x18, 10, 1, pcie_axi_sels, ARRAY_SIZE(pcie_axi_sels)); - clk[IMX6QDL_CLK_SSI1_SEL] = imx_clk_fixup_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup); - clk[IMX6QDL_CLK_SSI2_SEL] = imx_clk_fixup_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup); - clk[IMX6QDL_CLK_SSI3_SEL] = imx_clk_fixup_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup); - clk[IMX6QDL_CLK_USDHC1_SEL] = imx_clk_fixup_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); - clk[IMX6QDL_CLK_USDHC2_SEL] = imx_clk_fixup_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); - clk[IMX6QDL_CLK_USDHC3_SEL] = imx_clk_fixup_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); - clk[IMX6QDL_CLK_USDHC4_SEL] = imx_clk_fixup_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); - clk[IMX6QDL_CLK_ENFC_SEL] = imx_clk_mux("enfc_sel", base + 0x2c, 16, 2, enfc_sels, ARRAY_SIZE(enfc_sels)); - clk[IMX6QDL_CLK_EIM_SEL] = imx_clk_fixup_mux("eim_sel", base + 0x1c, 27, 2, eim_sels, ARRAY_SIZE(eim_sels), imx_cscmr1_fixup); - clk[IMX6QDL_CLK_EIM_SLOW_SEL] = imx_clk_fixup_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels, ARRAY_SIZE(eim_slow_sels), imx_cscmr1_fixup); + if (clk_on_imx6qp()) { + clk[IMX6QDL_CLK_IPU1_DI0_SEL] = imx_clk_mux_flags("ipu1_di0_sel", base + 0x34, 0, 3, ipu1_di0_sels_2, ARRAY_SIZE(ipu1_di0_sels_2), CLK_SET_RATE_PARENT); + clk[IMX6QDL_CLK_IPU1_DI1_SEL] = imx_clk_mux_flags("ipu1_di1_sel", base + 0x34, 9, 3, ipu1_di1_sels_2, ARRAY_SIZE(ipu1_di1_sels_2), CLK_SET_RATE_PARENT); + clk[IMX6QDL_CLK_IPU2_DI0_SEL] = imx_clk_mux_flags("ipu2_di0_sel", base + 0x38, 0, 3, ipu2_di0_sels_2, ARRAY_SIZE(ipu2_di0_sels_2), CLK_SET_RATE_PARENT); + clk[IMX6QDL_CLK_IPU2_DI1_SEL] = imx_clk_mux_flags("ipu2_di1_sel", base + 0x38, 9, 3, ipu2_di1_sels_2, ARRAY_SIZE(ipu2_di1_sels_2), CLK_SET_RATE_PARENT); + clk[IMX6QDL_CLK_SSI1_SEL] = imx_clk_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); + clk[IMX6QDL_CLK_SSI2_SEL] = imx_clk_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); + clk[IMX6QDL_CLK_SSI3_SEL] = imx_clk_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); + clk[IMX6QDL_CLK_USDHC1_SEL] = imx_clk_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); + clk[IMX6QDL_CLK_USDHC2_SEL] = imx_clk_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); + clk[IMX6QDL_CLK_USDHC3_SEL] = imx_clk_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); + clk[IMX6QDL_CLK_USDHC4_SEL] = imx_clk_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); + clk[IMX6QDL_CLK_ENFC_SEL] = imx_clk_mux("enfc_sel", base + 0x2c, 15, 3, enfc_sels_2, ARRAY_SIZE(enfc_sels_2)); + clk[IMX6QDL_CLK_EIM_SEL] = imx_clk_mux("eim_sel", base + 0x1c, 27, 2, eim_sels, ARRAY_SIZE(eim_sels)); + clk[IMX6QDL_CLK_EIM_SLOW_SEL] = imx_clk_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels, ARRAY_SIZE(eim_slow_sels)); + clk[IMX6QDL_CLK_PRE_AXI] = imx_clk_mux("pre_axi", base + 0x18, 1, 1, pre_axi_sels, ARRAY_SIZE(pre_axi_sels)); + } else { + clk[IMX6QDL_CLK_IPU1_DI0_SEL] = imx_clk_mux_flags("ipu1_di0_sel", base + 0x34, 0, 3, ipu1_di0_sels, ARRAY_SIZE(ipu1_di0_sels), CLK_SET_RATE_PARENT); + clk[IMX6QDL_CLK_IPU1_DI1_SEL] = imx_clk_mux_flags("ipu1_di1_sel", base + 0x34, 9, 3, ipu1_di1_sels, ARRAY_SIZE(ipu1_di1_sels), CLK_SET_RATE_PARENT); + clk[IMX6QDL_CLK_IPU2_DI0_SEL] = imx_clk_mux_flags("ipu2_di0_sel", base + 0x38, 0, 3, ipu2_di0_sels, ARRAY_SIZE(ipu2_di0_sels), CLK_SET_RATE_PARENT); + clk[IMX6QDL_CLK_IPU2_DI1_SEL] = imx_clk_mux_flags("ipu2_di1_sel", base + 0x38, 9, 3, ipu2_di1_sels, ARRAY_SIZE(ipu2_di1_sels), CLK_SET_RATE_PARENT); + clk[IMX6QDL_CLK_SSI1_SEL] = imx_clk_fixup_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup); + clk[IMX6QDL_CLK_SSI2_SEL] = imx_clk_fixup_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup); + clk[IMX6QDL_CLK_SSI3_SEL] = imx_clk_fixup_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup); + clk[IMX6QDL_CLK_USDHC1_SEL] = imx_clk_fixup_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); + clk[IMX6QDL_CLK_USDHC2_SEL] = imx_clk_fixup_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); + clk[IMX6QDL_CLK_USDHC3_SEL] = imx_clk_fixup_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); + clk[IMX6QDL_CLK_USDHC4_SEL] = imx_clk_fixup_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); + clk[IMX6QDL_CLK_ENFC_SEL] = imx_clk_mux("enfc_sel", base + 0x2c, 16, 2, enfc_sels, ARRAY_SIZE(enfc_sels)); + clk[IMX6QDL_CLK_EIM_SEL] = imx_clk_fixup_mux("eim_sel", base + 0x1c, 27, 2, eim_sels, ARRAY_SIZE(eim_sels), imx_cscmr1_fixup); + clk[IMX6QDL_CLK_EIM_SLOW_SEL] = imx_clk_fixup_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels, ARRAY_SIZE(eim_slow_sels), imx_cscmr1_fixup); + } clk[IMX6QDL_CLK_VDO_AXI_SEL] = imx_clk_mux("vdo_axi_sel", base + 0x18, 11, 1, vdo_axi_sels, ARRAY_SIZE(vdo_axi_sels)); clk[IMX6QDL_CLK_VPU_AXI_SEL] = imx_clk_mux("vpu_axi_sel", base + 0x18, 14, 2, vpu_axi_sels, ARRAY_SIZE(vpu_axi_sels)); clk[IMX6QDL_CLK_CKO1_SEL] = imx_clk_mux("cko1_sel", base + 0x60, 0, 4, cko1_sels, ARRAY_SIZE(cko1_sels)); @@ -335,23 +379,33 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[IMX6QDL_CLK_PERIPH_CLK2] = imx_clk_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3); clk[IMX6QDL_CLK_PERIPH2_CLK2] = imx_clk_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3); clk[IMX6QDL_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2); - clk[IMX6QDL_CLK_IPG_PER] = imx_clk_fixup_divider("ipg_per", "ipg", base + 0x1c, 0, 6, imx_cscmr1_fixup); clk[IMX6QDL_CLK_ESAI_PRED] = imx_clk_divider("esai_pred", "esai_sel", base + 0x28, 9, 3); clk[IMX6QDL_CLK_ESAI_PODF] = imx_clk_divider("esai_podf", "esai_pred", base + 0x28, 25, 3); clk[IMX6QDL_CLK_ASRC_PRED] = imx_clk_divider("asrc_pred", "asrc_sel", base + 0x30, 12, 3); clk[IMX6QDL_CLK_ASRC_PODF] = imx_clk_divider("asrc_podf", "asrc_pred", base + 0x30, 9, 3); clk[IMX6QDL_CLK_SPDIF_PRED] = imx_clk_divider("spdif_pred", "spdif_sel", base + 0x30, 25, 3); clk[IMX6QDL_CLK_SPDIF_PODF] = imx_clk_divider("spdif_podf", "spdif_pred", base + 0x30, 22, 3); - clk[IMX6QDL_CLK_CAN_ROOT] = imx_clk_divider("can_root", "pll3_60m", base + 0x20, 2, 6); - clk[IMX6QDL_CLK_ECSPI_ROOT] = imx_clk_divider("ecspi_root", "pll3_60m", base + 0x38, 19, 6); + if (clk_on_imx6qp()) { + clk[IMX6QDL_CLK_IPG_PER] = imx_clk_divider("ipg_per", "ipg_per_sel", base + 0x1c, 0, 6); + clk[IMX6QDL_CLK_ECSPI_ROOT] = imx_clk_divider("ecspi_root", "ecspi_sel", base + 0x38, 19, 6); + clk[IMX6QDL_CLK_CAN_ROOT] = imx_clk_divider("can_root", "can_sel", base + 0x20, 2, 6); + clk[IMX6QDL_CLK_UART_SERIAL_PODF] = imx_clk_divider("uart_serial_podf", "uart_sel", base + 0x24, 0, 6); + clk[IMX6QDL_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0", 2, 7); + clk[IMX6QDL_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1", 2, 7); + } else { + clk[IMX6QDL_CLK_ECSPI_ROOT] = imx_clk_divider("ecspi_root", "pll3_60m", base + 0x38, 19, 6); + clk[IMX6QDL_CLK_CAN_ROOT] = imx_clk_divider("can_root", "pll3_60", base + 0x20, 2, 6); + clk[IMX6QDL_CLK_IPG_PER] = imx_clk_fixup_divider("ipg_per", "ipg", base + 0x1c, 0, 6, imx_cscmr1_fixup); + clk[IMX6QDL_CLK_UART_SERIAL_PODF] = imx_clk_divider("uart_serial_podf", "pll3_80m", base + 0x24, 0, 6); + clk[IMX6QDL_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); + clk[IMX6QDL_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7); + } clk[IMX6QDL_CLK_GPU2D_CORE_PODF] = imx_clk_divider("gpu2d_core_podf", "gpu2d_core_sel", base + 0x18, 23, 3); clk[IMX6QDL_CLK_GPU3D_CORE_PODF] = imx_clk_divider("gpu3d_core_podf", "gpu3d_core_sel", base + 0x18, 26, 3); clk[IMX6QDL_CLK_GPU3D_SHADER] = imx_clk_divider("gpu3d_shader", "gpu3d_shader_sel", base + 0x18, 29, 3); clk[IMX6QDL_CLK_IPU1_PODF] = imx_clk_divider("ipu1_podf", "ipu1_sel", base + 0x3c, 11, 3); clk[IMX6QDL_CLK_IPU2_PODF] = imx_clk_divider("ipu2_podf", "ipu2_sel", base + 0x3c, 16, 3); - clk[IMX6QDL_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); clk[IMX6QDL_CLK_LDB_DI0_PODF] = imx_clk_divider_flags("ldb_di0_podf", "ldb_di0_div_3_5", base + 0x20, 10, 1, 0); - clk[IMX6QDL_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7); clk[IMX6QDL_CLK_LDB_DI1_PODF] = imx_clk_divider_flags("ldb_di1_podf", "ldb_di1_div_3_5", base + 0x20, 11, 1, 0); clk[IMX6QDL_CLK_IPU1_DI0_PRE] = imx_clk_divider("ipu1_di0_pre", "ipu1_di0_pre_sel", base + 0x34, 3, 3); clk[IMX6QDL_CLK_IPU1_DI1_PRE] = imx_clk_divider("ipu1_di1_pre", "ipu1_di1_pre_sel", base + 0x34, 12, 3); @@ -364,15 +418,19 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[IMX6QDL_CLK_SSI2_PODF] = imx_clk_divider("ssi2_podf", "ssi2_pred", base + 0x2c, 0, 6); clk[IMX6QDL_CLK_SSI3_PRED] = imx_clk_divider("ssi3_pred", "ssi3_sel", base + 0x28, 22, 3); clk[IMX6QDL_CLK_SSI3_PODF] = imx_clk_divider("ssi3_podf", "ssi3_pred", base + 0x28, 16, 6); - clk[IMX6QDL_CLK_UART_SERIAL_PODF] = imx_clk_divider("uart_serial_podf", "pll3_80m", base + 0x24, 0, 6); clk[IMX6QDL_CLK_USDHC1_PODF] = imx_clk_divider("usdhc1_podf", "usdhc1_sel", base + 0x24, 11, 3); clk[IMX6QDL_CLK_USDHC2_PODF] = imx_clk_divider("usdhc2_podf", "usdhc2_sel", base + 0x24, 16, 3); clk[IMX6QDL_CLK_USDHC3_PODF] = imx_clk_divider("usdhc3_podf", "usdhc3_sel", base + 0x24, 19, 3); clk[IMX6QDL_CLK_USDHC4_PODF] = imx_clk_divider("usdhc4_podf", "usdhc4_sel", base + 0x24, 22, 3); clk[IMX6QDL_CLK_ENFC_PRED] = imx_clk_divider("enfc_pred", "enfc_sel", base + 0x2c, 18, 3); clk[IMX6QDL_CLK_ENFC_PODF] = imx_clk_divider("enfc_podf", "enfc_pred", base + 0x2c, 21, 6); - clk[IMX6QDL_CLK_EIM_PODF] = imx_clk_fixup_divider("eim_podf", "eim_sel", base + 0x1c, 20, 3, imx_cscmr1_fixup); - clk[IMX6QDL_CLK_EIM_SLOW_PODF] = imx_clk_fixup_divider("eim_slow_podf", "eim_slow_sel", base + 0x1c, 23, 3, imx_cscmr1_fixup); + if (clk_on_imx6qp()) { + clk[IMX6QDL_CLK_EIM_PODF] = imx_clk_divider("eim_podf", "eim_sel", base + 0x1c, 20, 3); + clk[IMX6QDL_CLK_EIM_SLOW_PODF] = imx_clk_divider("eim_slow_podf", "eim_slow_sel", base + 0x1c, 23, 3); + } else { + clk[IMX6QDL_CLK_EIM_PODF] = imx_clk_fixup_divider("eim_podf", "eim_sel", base + 0x1c, 20, 3, imx_cscmr1_fixup); + clk[IMX6QDL_CLK_EIM_SLOW_PODF] = imx_clk_fixup_divider("eim_slow_podf", "eim_slow_sel", base + 0x1c, 23, 3, imx_cscmr1_fixup); + } clk[IMX6QDL_CLK_VPU_AXI_PODF] = imx_clk_divider("vpu_axi_podf", "vpu_axi_sel", base + 0x24, 25, 3); clk[IMX6QDL_CLK_CKO1_PODF] = imx_clk_divider("cko1_podf", "cko1_sel", base + 0x60, 4, 3); clk[IMX6QDL_CLK_CKO2_PODF] = imx_clk_divider("cko2_podf", "cko2_sel", base + 0x60, 21, 3); @@ -380,7 +438,12 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) /* name parent_name reg shift width busy: reg, shift */ clk[IMX6QDL_CLK_AXI] = imx_clk_busy_divider("axi", "axi_sel", base + 0x14, 16, 3, base + 0x48, 0); clk[IMX6QDL_CLK_MMDC_CH0_AXI_PODF] = imx_clk_busy_divider("mmdc_ch0_axi_podf", "periph", base + 0x14, 19, 3, base + 0x48, 4); - clk[IMX6QDL_CLK_MMDC_CH1_AXI_PODF] = imx_clk_busy_divider("mmdc_ch1_axi_podf", "periph2", base + 0x14, 3, 3, base + 0x48, 2); + if (clk_on_imx6qp()) { + clk[IMX6QDL_CLK_MMDC_CH1_AXI_CG] = imx_clk_gate("mmdc_ch1_axi_cg", "periph2", base + 0x4, 18); + clk[IMX6QDL_CLK_MMDC_CH1_AXI_PODF] = imx_clk_busy_divider("mmdc_ch1_axi_podf", "mmdc_ch1_axi_cg", base + 0x14, 3, 3, base + 0x48, 2); + } else { + clk[IMX6QDL_CLK_MMDC_CH1_AXI_PODF] = imx_clk_busy_divider("mmdc_ch1_axi_podf", "periph2", base + 0x14, 3, 3, base + 0x48, 2); + } clk[IMX6QDL_CLK_ARM] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16); clk[IMX6QDL_CLK_AHB] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1); @@ -432,8 +495,13 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[IMX6QDL_CLK_IPU1_DI1] = imx_clk_gate2("ipu1_di1", "ipu1_di1_sel", base + 0x74, 4); clk[IMX6QDL_CLK_IPU2] = imx_clk_gate2("ipu2", "ipu2_podf", base + 0x74, 6); clk[IMX6QDL_CLK_IPU2_DI0] = imx_clk_gate2("ipu2_di0", "ipu2_di0_sel", base + 0x74, 8); - clk[IMX6QDL_CLK_LDB_DI0] = imx_clk_gate2("ldb_di0", "ldb_di0_podf", base + 0x74, 12); - clk[IMX6QDL_CLK_LDB_DI1] = imx_clk_gate2("ldb_di1", "ldb_di1_podf", base + 0x74, 14); + if (clk_on_imx6qp()) { + clk[IMX6QDL_CLK_LDB_DI0] = imx_clk_gate2("ldb_di0", "ldb_di0_sel", base + 0x74, 12); + clk[IMX6QDL_CLK_LDB_DI1] = imx_clk_gate2("ldb_di1", "ldb_di1_sel", base + 0x74, 14); + } else { + clk[IMX6QDL_CLK_LDB_DI0] = imx_clk_gate2("ldb_di0", "ldb_di0_podf", base + 0x74, 12); + clk[IMX6QDL_CLK_LDB_DI1] = imx_clk_gate2("ldb_di1", "ldb_di1_podf", base + 0x74, 14); + } clk[IMX6QDL_CLK_IPU2_DI1] = imx_clk_gate2("ipu2_di1", "ipu2_di1_sel", base + 0x74, 10); clk[IMX6QDL_CLK_HSI_TX] = imx_clk_gate2_shared("hsi_tx", "hsi_tx_podf", base + 0x74, 16, &share_count_mipi_core_cfg); clk[IMX6QDL_CLK_MIPI_CORE_CFG] = imx_clk_gate2_shared("mipi_core_cfg", "video_27m", base + 0x74, 16, &share_count_mipi_core_cfg); @@ -482,6 +550,16 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[IMX6QDL_CLK_EIM_SLOW] = imx_clk_gate2("eim_slow", "eim_slow_podf", base + 0x80, 10); clk[IMX6QDL_CLK_VDO_AXI] = imx_clk_gate2("vdo_axi", "vdo_axi_sel", base + 0x80, 12); clk[IMX6QDL_CLK_VPU_AXI] = imx_clk_gate2("vpu_axi", "vpu_axi_podf", base + 0x80, 14); + if (clk_on_imx6qp()) { + clk[IMX6QDL_CLK_PRE0] = imx_clk_gate2("pre0", "pre_axi", base + 0x80, 16); + clk[IMX6QDL_CLK_PRE1] = imx_clk_gate2("pre1", "pre_axi", base + 0x80, 18); + clk[IMX6QDL_CLK_PRE2] = imx_clk_gate2("pre2", "pre_axi", base + 0x80, 20); + clk[IMX6QDL_CLK_PRE3] = imx_clk_gate2("pre3", "pre_axi", base + 0x80, 22); + clk[IMX6QDL_CLK_PRG0_AXI] = imx_clk_gate2_shared("prg0_axi", "ipu1_podf", base + 0x80, 24, &share_count_prg0); + clk[IMX6QDL_CLK_PRG1_AXI] = imx_clk_gate2_shared("prg1_axi", "ipu2_podf", base + 0x80, 26, &share_count_prg1); + clk[IMX6QDL_CLK_PRG0_APB] = imx_clk_gate2_shared("prg0_apb", "ipg", base + 0x80, 24, &share_count_prg0); + clk[IMX6QDL_CLK_PRG1_APB] = imx_clk_gate2_shared("prg1_apb", "ipg", base + 0x80, 26, &share_count_prg1); + } clk[IMX6QDL_CLK_CKO1] = imx_clk_gate("cko1", "cko1_podf", base + 0x60, 7); clk[IMX6QDL_CLK_CKO2] = imx_clk_gate("cko2", "cko2_podf", base + 0x60, 24); diff --git a/include/dt-bindings/clock/imx6qdl-clock.h b/include/dt-bindings/clock/imx6qdl-clock.h index 77985cc..2905033 100644 --- a/include/dt-bindings/clock/imx6qdl-clock.h +++ b/include/dt-bindings/clock/imx6qdl-clock.h @@ -255,6 +255,20 @@ #define IMX6QDL_CLK_CAAM_ACLK 242 #define IMX6QDL_CLK_CAAM_IPG 243 #define IMX6QDL_CLK_SPDIF_GCLK 244 -#define IMX6QDL_CLK_END 245 +#define IMX6QDL_CLK_UART_SEL 245 +#define IMX6QDL_CLK_IPG_PER_SEL 246 +#define IMX6QDL_CLK_ECSPI_SEL 247 +#define IMX6QDL_CLK_CAN_SEL 248 +#define IMX6QDL_CLK_MMDC_CH1_AXI_CG 249 +#define IMX6QDL_CLK_PRE0 250 +#define IMX6QDL_CLK_PRE1 251 +#define IMX6QDL_CLK_PRE2 252 +#define IMX6QDL_CLK_PRE3 253 +#define IMX6QDL_CLK_PRG0_AXI 254 +#define IMX6QDL_CLK_PRG1_AXI 255 +#define IMX6QDL_CLK_PRG0_APB 256 +#define IMX6QDL_CLK_PRG1_APB 257 +#define IMX6QDL_CLK_PRE_AXI 258 +#define IMX6QDL_CLK_END 259 #endif /* __DT_BINDINGS_CLOCK_IMX6QDL_H */ -- cgit v0.10.2 From 282312d1ac8aad4947a01c2caf79c9c0299fb495 Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Mon, 15 Feb 2016 11:33:15 +0800 Subject: clk: rockchip: disable alt_parent clk in err cases when registering cpuclk Add clk_disable_unprepare to handle cpuclk->alt_parent if rockchip_clk_register_cpuclk fails. Signed-off-by: Shawn Lin Signed-off-by: Heiko Stuebner diff --git a/drivers/clk/rockchip/clk-cpu.c b/drivers/clk/rockchip/clk-cpu.c index d07374f..68a2a87 100644 --- a/drivers/clk/rockchip/clk-cpu.c +++ b/drivers/clk/rockchip/clk-cpu.c @@ -290,14 +290,14 @@ struct clk *rockchip_clk_register_cpuclk(const char *name, pr_err("%s: could not lookup parent clock %s\n", __func__, parent_names[0]); ret = -EINVAL; - goto free_cpuclk; + goto free_alt_parent; } ret = clk_notifier_register(clk, &cpuclk->clk_nb); if (ret) { pr_err("%s: failed to register clock notifier for %s\n", __func__, name); - goto free_cpuclk; + goto free_alt_parent; } if (nrates > 0) { @@ -326,6 +326,8 @@ free_rate_table: kfree(cpuclk->rate_table); unregister_notifier: clk_notifier_unregister(clk, &cpuclk->clk_nb); +free_alt_parent: + clk_disable_unprepare(cpuclk->alt_parent); free_cpuclk: kfree(cpuclk); return ERR_PTR(ret); -- cgit v0.10.2 From eb4e10c61ddb513dae6508a16eedd2da59effb98 Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Mon, 15 Feb 2016 11:33:25 +0800 Subject: clk: rockchip: check grf when waiting pll lock rockchip_clk_get_grf pass on return value from syscon_regmap_lookup_by_phandle, so we check grf to make sure whether to do the following things or not. Signed-off-by: Shawn Lin Signed-off-by: Heiko Stuebner diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c index b7e66c9..5de797e 100644 --- a/drivers/clk/rockchip/clk-pll.c +++ b/drivers/clk/rockchip/clk-pll.c @@ -94,6 +94,11 @@ static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll) unsigned int val; int delay = 24000000, ret; + if (IS_ERR(grf)) { + pr_err("%s: grf regmap not available\n", __func__); + return PTR_ERR(grf); + } + while (delay > 0) { ret = regmap_read(grf, pll->lock_offset, &val); if (ret) { -- cgit v0.10.2 From ddd02e145611d1689e5014e79d7f37dcd323b70b Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Mon, 15 Feb 2016 11:33:33 +0800 Subject: clk: rockchip: don't return NULL when registering inverter fails Avoid return NULL if rockchip_clk_register_inverter fails, otherwise rockchip_clk_register_branches print "unknown clock type". The acutal case is that it's a known clock type but we fail to regiser it, which may makes user confuse the reason of failure. Signed-off-by: Shawn Lin Signed-off-by: Heiko Stuebner diff --git a/drivers/clk/rockchip/clk-inverter.c b/drivers/clk/rockchip/clk-inverter.c index 7cbf43b..dcb6e37 100644 --- a/drivers/clk/rockchip/clk-inverter.c +++ b/drivers/clk/rockchip/clk-inverter.c @@ -90,7 +90,7 @@ struct clk *rockchip_clk_register_inverter(const char *name, inv_clock = kmalloc(sizeof(*inv_clock), GFP_KERNEL); if (!inv_clock) - return NULL; + return ERR_PTR(-ENOMEM); init.name = name; init.num_parents = num_parents; @@ -106,11 +106,7 @@ struct clk *rockchip_clk_register_inverter(const char *name, clk = clk_register(NULL, &inv_clock->hw); if (IS_ERR(clk)) - goto err_free; + kfree(inv_clock); return clk; - -err_free: - kfree(inv_clock); - return NULL; } -- cgit v0.10.2 From 022dce0bd03905251de6cdd491a292818eaf3b89 Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Mon, 15 Feb 2016 11:33:41 +0800 Subject: clk: rockchip: don't return NULL when registering mmc branch fails Avoid return NULL if rockchip_clk_register_mmc fails, otherwise rockchip_clk_register_branches print "unknown clock type". The acutal case is that it's a known clock type but we fail to regiser it, which may makes user confuse the reason of failure. Signed-off-by: Shawn Lin Signed-off-by: Heiko Stuebner diff --git a/drivers/clk/rockchip/clk-mmc-phase.c b/drivers/clk/rockchip/clk-mmc-phase.c index 2685644..e0dc7e8 100644 --- a/drivers/clk/rockchip/clk-mmc-phase.c +++ b/drivers/clk/rockchip/clk-mmc-phase.c @@ -150,7 +150,7 @@ struct clk *rockchip_clk_register_mmc(const char *name, mmc_clock = kmalloc(sizeof(*mmc_clock), GFP_KERNEL); if (!mmc_clock) - return NULL; + return ERR_PTR(-ENOMEM); init.name = name; init.num_parents = num_parents; @@ -172,11 +172,7 @@ struct clk *rockchip_clk_register_mmc(const char *name, clk = clk_register(NULL, &mmc_clock->hw); if (IS_ERR(clk)) - goto err_free; + kfree(mmc_clock); return clk; - -err_free: - kfree(mmc_clock); - return NULL; } -- cgit v0.10.2 From fc6d875ecb83cd03afad4486c97a9355e00c8944 Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Mon, 15 Feb 2016 11:33:50 +0800 Subject: clk: rockchip: fix coding style for clk-cpu.c Fix the issue reported by checkpatch: ERROR: space prohibited before that ',' (ctx:WxW) + writel(clksel->val , cpuclk->reg_base + clksel->reg); Signed-off-by: Shawn Lin Signed-off-by: Heiko Stuebner diff --git a/drivers/clk/rockchip/clk-cpu.c b/drivers/clk/rockchip/clk-cpu.c index 68a2a87..4e73ed5 100644 --- a/drivers/clk/rockchip/clk-cpu.c +++ b/drivers/clk/rockchip/clk-cpu.c @@ -116,7 +116,7 @@ static void rockchip_cpuclk_set_dividers(struct rockchip_cpuclk *cpuclk, pr_debug("%s: setting reg 0x%x to 0x%x\n", __func__, clksel->reg, clksel->val); - writel(clksel->val , cpuclk->reg_base + clksel->reg); + writel(clksel->val, cpuclk->reg_base + clksel->reg); } } -- cgit v0.10.2 From ca00c382bf1b40a73c27aeb2bb271376cc9c8812 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 20 Oct 2015 10:21:49 +0200 Subject: clk: shmobile: cpg-mssr: Update serial port clock in example Cfr. commit a9ec81f4ed5c05db ("serial: sh-sci: Drop the interface clock"). Signed-off-by: Geert Uytterhoeven Acked-by: Michael Turquette diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt index 59297d3..fefb802 100644 --- a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt @@ -61,7 +61,7 @@ Examples reg = <0 0xe6e88000 0 64>; interrupts = ; clocks = <&cpg CPG_MOD 310>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac1 0x13>, <&dmac1 0x12>; dma-names = "tx", "rx"; power-domains = <&cpg>; -- cgit v0.10.2 From 33f60d02605a3a604e56b07a78d80d7d801b2843 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 15 Feb 2016 17:40:19 +0800 Subject: clk: sunxi: Fix sun8i-a23-apb0-clk divider flags The APB0 clock on A23 is a zero-based divider, not a power-of-two based divider. Note that this patch does not apply cleanly to kernels before 4.5-rc1, which added CLK_OF_DECLARE support to this driver. Fixes: 57a1fbf28424 ("clk: sunxi: Add A23 APB0 divider clock support") Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard diff --git a/drivers/clk/sunxi/clk-sun8i-apb0.c b/drivers/clk/sunxi/clk-sun8i-apb0.c index 7ba6110..2ea61de 100644 --- a/drivers/clk/sunxi/clk-sun8i-apb0.c +++ b/drivers/clk/sunxi/clk-sun8i-apb0.c @@ -36,7 +36,7 @@ static struct clk *sun8i_a23_apb0_register(struct device_node *node, /* The A23 APB0 clock is a standard 2 bit wide divider clock */ clk = clk_register_divider(NULL, clk_name, clk_parent, 0, reg, - 0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL); + 0, 2, 0, NULL); if (IS_ERR(clk)) return clk; -- cgit v0.10.2 From 773b3966dd3cdaeb68e7f2edfe5656abac1dc411 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 15 Feb 2016 19:03:57 -0800 Subject: clk: bcm2835: Fix setting of PLL divider clock rates Our dividers weren't being set successfully because CM_PASSWORD wasn't included in the register write. It looks easier to just compute the divider to write ourselves than to update clk-divider for the ability to OR in some arbitrary bits on write. Fixes about half of the video modes on my HDMI monitor (everything except 720x400). Cc: stable@vger.kernel.org Signed-off-by: Eric Anholt Signed-off-by: Michael Turquette diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 015e687..9f4df8f 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -1107,13 +1107,15 @@ static int bcm2835_pll_divider_set_rate(struct clk_hw *hw, struct bcm2835_pll_divider *divider = bcm2835_pll_divider_from_hw(hw); struct bcm2835_cprman *cprman = divider->cprman; const struct bcm2835_pll_divider_data *data = divider->data; - u32 cm; - int ret; + u32 cm, div, max_div = 1 << A2W_PLL_DIV_BITS; - ret = clk_divider_ops.set_rate(hw, rate, parent_rate); - if (ret) - return ret; + div = DIV_ROUND_UP_ULL(parent_rate, rate); + + div = min(div, max_div); + if (div == max_div) + div = 0; + cprman_write(cprman, data->a2w_reg, div); cm = cprman_read(cprman, data->cm_reg); cprman_write(cprman, data->cm_reg, cm | data->load_mask); cprman_write(cprman, data->cm_reg, cm & ~data->load_mask); -- cgit v0.10.2 From 79c1e2fc2c0e0243d6ecaacfb650cf0ad5ad4aa5 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 15 Feb 2016 19:03:58 -0800 Subject: clk: bcm2835: Reuse CLK_DIVIDER_MAX_AT_ZERO for recalc_rate() We were rolling this ourselves, but clk-divider can do it now. Signed-off-by: Eric Anholt Signed-off-by: Michael Turquette diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 9f4df8f..353e438 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -1060,16 +1060,7 @@ static long bcm2835_pll_divider_round_rate(struct clk_hw *hw, static unsigned long bcm2835_pll_divider_get_rate(struct clk_hw *hw, unsigned long parent_rate) { - struct bcm2835_pll_divider *divider = bcm2835_pll_divider_from_hw(hw); - struct bcm2835_cprman *cprman = divider->cprman; - const struct bcm2835_pll_divider_data *data = divider->data; - u32 div = cprman_read(cprman, data->a2w_reg); - - div &= (1 << A2W_PLL_DIV_BITS) - 1; - if (div == 0) - div = 256; - - return parent_rate / div; + return clk_divider_ops.recalc_rate(hw, parent_rate); } static void bcm2835_pll_divider_off(struct clk_hw *hw) @@ -1430,7 +1421,7 @@ bcm2835_register_pll_divider(struct bcm2835_cprman *cprman, divider->div.reg = cprman->regs + data->a2w_reg; divider->div.shift = A2W_PLL_DIV_SHIFT; divider->div.width = A2W_PLL_DIV_BITS; - divider->div.flags = 0; + divider->div.flags = CLK_DIVIDER_MAX_AT_ZERO; divider->div.lock = &cprman->regs_lock; divider->div.hw.init = &init; divider->div.table = NULL; -- cgit v0.10.2 From fb4dd22203e03087c71e5c8757ed14fc122bc9ea Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Fri, 12 Feb 2016 12:50:16 -0600 Subject: clk: Make of_clk_get_from_provider() available to modules Export symbol of_clk_get_from_provider so it can be used in loadable kernel modules Signed-off-by: Andrew F. Davis Signed-off-by: Michael Turquette diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 67cd2f1..58ef3da 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -3019,6 +3019,7 @@ struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec) { return __of_clk_get_from_provider(clkspec, NULL, __func__); } +EXPORT_SYMBOL_GPL(of_clk_get_from_provider); int of_clk_get_parent_count(struct device_node *np) { -- cgit v0.10.2 From f099aa075749c6fadb79554ce175fbdc31c45d7a Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 18 Feb 2016 16:14:03 +0900 Subject: clk: shmobile: r8a7795: Add INTC-EX clock Add the "intc-ex" clock to the r8a7795 CPG MSSR driver. According to information from the hardware team the INTC-EX parent clock is CP. The next data sheet version will include this information. Signed-off-by: Magnus Damm Signed-off-by: Geert Uytterhoeven diff --git a/drivers/clk/shmobile/r8a7795-cpg-mssr.c b/drivers/clk/shmobile/r8a7795-cpg-mssr.c index 24ff38c..1f4b21a 100644 --- a/drivers/clk/shmobile/r8a7795-cpg-mssr.c +++ b/drivers/clk/shmobile/r8a7795-cpg-mssr.c @@ -138,6 +138,7 @@ static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = { DEF_MOD("usb3-if0", 328, R8A7795_CLK_S3D1), DEF_MOD("usb-dmac0", 330, R8A7795_CLK_S3D1), DEF_MOD("usb-dmac1", 331, R8A7795_CLK_S3D1), + DEF_MOD("intc-ex", 407, R8A7795_CLK_CP), DEF_MOD("intc-ap", 408, R8A7795_CLK_S3D1), DEF_MOD("audmac0", 502, R8A7795_CLK_S3D4), DEF_MOD("audmac1", 501, R8A7795_CLK_S3D4), -- cgit v0.10.2 From 81a467efe32a95825062b799521f98bb8273ec84 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Wed, 17 Feb 2016 19:48:19 +0100 Subject: clk: imx: correct pwm7 clock name in driver for i.MX6UL Don't capitalize p in the pwm7 clock name. Signed-off-by: Anatolij Gustschin Reviewed-by: Fabio Estevam Signed-off-by: Shawn Guo diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c index 08692d7..79f6f20 100644 --- a/drivers/clk/imx/clk-imx6ul.c +++ b/drivers/clk/imx/clk-imx6ul.c @@ -394,7 +394,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) clks[IMX6UL_CLK_I2C4] = imx_clk_gate2("i2c4", "perclk", base + 0x80, 24); clks[IMX6UL_CLK_PWM5] = imx_clk_gate2("pwm5", "perclk", base + 0x80, 26); clks[IMX6UL_CLK_PWM6] = imx_clk_gate2("pwm6", "perclk", base + 0x80, 28); - clks[IMX6UL_CLK_PWM7] = imx_clk_gate2("Pwm7", "perclk", base + 0x80, 30); + clks[IMX6UL_CLK_PWM7] = imx_clk_gate2("pwm7", "perclk", base + 0x80, 30); /* mask handshake of mmdc */ writel_relaxed(BM_CCM_CCDR_MMDC_CH0_MASK, base + CCDR); -- cgit v0.10.2 From 72360b91164aa35753942e5310ae1e1d16e28611 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Tue, 16 Feb 2016 10:46:06 +0000 Subject: clk: sunxi: improve mux_clk error handling and reporting We now catch and report a failing ioremap, also a failure in the final step of the clock registration is now handled and reported. Also warnings are turned into errors. Signed-off-by: Andre Przywara Signed-off-by: Maxime Ripard diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index 99f60ef..775e137 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -674,11 +674,16 @@ static struct clk * __init sunxi_mux_clk_setup(struct device_node *node, int i; reg = of_iomap(node, 0); + if (!reg) { + pr_err("Could not map registers for mux-clk: %s\n", + of_node_full_name(node)); + return NULL; + } i = of_clk_parent_fill(node, parents, SUNXI_MAX_PARENTS); if (of_property_read_string(node, "clock-output-names", &clk_name)) { - pr_warn("%s: could not read clock-output-names for \"%s\"\n", - __func__, clk_name); + pr_err("%s: could not read clock-output-names from \"%s\"\n", + __func__, of_node_full_name(node)); goto out_unmap; } @@ -688,15 +693,19 @@ static struct clk * __init sunxi_mux_clk_setup(struct device_node *node, 0, &clk_lock); if (IS_ERR(clk)) { - pr_warn("%s: failed to register mux clock %s: %ld\n", __func__, - clk_name, PTR_ERR(clk)); + pr_err("%s: failed to register mux clock %s: %ld\n", __func__, + clk_name, PTR_ERR(clk)); goto out_unmap; } - of_clk_add_provider(node, of_clk_src_simple_get, clk); + if (of_clk_add_provider(node, of_clk_src_simple_get, clk)) { + pr_err("%s: failed to add clock provider for %s\n", + __func__, clk_name); + clk_unregister_divider(clk); + goto out_unmap; + } return clk; - out_unmap: iounmap(reg); return NULL; -- cgit v0.10.2 From b26803ebfba8d81e2e8fb392c1248df2ebd1ba83 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Tue, 16 Feb 2016 10:46:07 +0000 Subject: clk: sunxi: improve divider_clk error handling and reporting We now report a failing ioremap, failing output names parsing, failures in table registration and in the final step. Also there was a bug where clk_register_divider_table() would return an ERR_PTR value instead of NULL, which we were checking for. We now implement proper rollback in case of an error. Signed-off-by: Andre Przywara Signed-off-by: Maxime Ripard diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index 775e137..4bd0917 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -805,17 +805,47 @@ static void __init sunxi_divider_clk_setup(struct device_node *node, void __iomem *reg; reg = of_iomap(node, 0); + if (!reg) { + pr_err("Could not map registers for mux-clk: %s\n", + of_node_full_name(node)); + return; + } clk_parent = of_clk_get_parent_name(node, 0); - of_property_read_string(node, "clock-output-names", &clk_name); + if (of_property_read_string(node, "clock-output-names", &clk_name)) { + pr_err("%s: could not read clock-output-names from \"%s\"\n", + __func__, of_node_full_name(node)); + goto out_unmap; + } clk = clk_register_divider_table(NULL, clk_name, clk_parent, 0, reg, data->shift, data->width, data->pow ? CLK_DIVIDER_POWER_OF_TWO : 0, data->table, &clk_lock); - if (clk) - of_clk_add_provider(node, of_clk_src_simple_get, clk); + if (IS_ERR(clk)) { + pr_err("%s: failed to register divider clock %s: %ld\n", + __func__, clk_name, PTR_ERR(clk)); + goto out_unmap; + } + + if (of_clk_add_provider(node, of_clk_src_simple_get, clk)) { + pr_err("%s: failed to add clock provider for %s\n", + __func__, clk_name); + goto out_unregister; + } + + if (clk_register_clkdev(clk, clk_name, NULL)) { + of_clk_del_provider(node); + goto out_unregister; + } + + return; +out_unregister: + clk_unregister_divider(clk); + +out_unmap: + iounmap(reg); } static void __init sun4i_ahb_clk_setup(struct device_node *node) -- cgit v0.10.2 From d331328da6b719e4ffb3b43125bbe540755239ad Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Tue, 16 Feb 2016 10:46:08 +0000 Subject: clk: sunxi: Improve divs_clk error handling and reporting We catch errors in the base clock registration, failure to ioremap and failures in the final of_clk_add_provider() call. Also we unmap the registers when we need to rollback. Signed-off-by: Andre Przywara Signed-off-by: Maxime Ripard diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index 4bd0917..91de0a0 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -985,13 +985,20 @@ static struct clk ** __init sunxi_divs_clk_setup(struct device_node *node, /* Set up factor clock that we will be dividing */ pclk = sunxi_factors_clk_setup(node, data->factors); + if (!pclk) + return NULL; parent = __clk_get_name(pclk); reg = of_iomap(node, 0); + if (!reg) { + pr_err("Could not map registers for divs-clk: %s\n", + of_node_full_name(node)); + return NULL; + } clk_data = kmalloc(sizeof(struct clk_onecell_data), GFP_KERNEL); if (!clk_data) - return NULL; + goto out_unmap; clks = kcalloc(ndivs, sizeof(*clks), GFP_KERNEL); if (!clks) @@ -1074,16 +1081,21 @@ static struct clk ** __init sunxi_divs_clk_setup(struct device_node *node, /* Adjust to the real max */ clk_data->clk_num = i; - of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); + if (of_clk_add_provider(node, of_clk_src_onecell_get, clk_data)) { + pr_err("%s: failed to add clock provider for %s\n", + __func__, clk_name); + goto free_gate; + } return clks; - free_gate: kfree(gate); free_clks: kfree(clks); free_clkdata: kfree(clk_data); +out_unmap: + iounmap(reg); return NULL; } -- cgit v0.10.2 From 732d6913691848db9fabaa6a25b4d6fad10ddccf Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Mon, 22 Feb 2016 11:43:39 +0000 Subject: clk: qcom: msm8960: fix ce3_core clk enable register This patch corrects the enable register offset which is actually 0x36cc instead of 0x36c4 Signed-off-by: Srinivas Kandagatla Fixes: 5f775498bdc4 ("clk: qcom: Fully support apq8064 global clock control") Signed-off-by: Stephen Boyd diff --git a/drivers/clk/qcom/gcc-msm8960.c b/drivers/clk/qcom/gcc-msm8960.c index 983dd7d..63ecd97 100644 --- a/drivers/clk/qcom/gcc-msm8960.c +++ b/drivers/clk/qcom/gcc-msm8960.c @@ -2769,7 +2769,7 @@ static struct clk_branch ce3_core_clk = { .halt_reg = 0x2fdc, .halt_bit = 5, .clkr = { - .enable_reg = 0x36c4, + .enable_reg = 0x36cc, .enable_mask = BIT(4), .hw.init = &(struct clk_init_data){ .name = "ce3_core_clk", -- cgit v0.10.2 From b6f5128459a40410f9afefddc0ad688ea5b22c28 Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Sat, 20 Feb 2016 13:24:26 +0200 Subject: clk: ti: dpll: convert DPLL support code to use clk_hw instead of clk ptrs Convert DPLL support code to use clk_hw pointers for reference and bypass clocks. This allows us to use clk_hw_* APIs for accessing any required parameters for these clocks, avoiding some locking problems at least with DPLL enable code; this used clk_get_rate which uses mutex but isn't good under clk_enable / clk_disable. Signed-off-by: Tero Kristo Acked-by: Tony Lindgren Signed-off-by: Stephen Boyd diff --git a/drivers/clk/ti/apll.c b/drivers/clk/ti/apll.c index b336a8c..6411e13 100644 --- a/drivers/clk/ti/apll.c +++ b/drivers/clk/ti/apll.c @@ -140,11 +140,21 @@ static void __init omap_clk_register_apll(struct clk_hw *hw, struct dpll_data *ad = clk_hw->dpll_data; struct clk *clk; - ad->clk_ref = of_clk_get(node, 0); - ad->clk_bypass = of_clk_get(node, 1); + clk = of_clk_get(node, 0); + if (IS_ERR(clk)) { + pr_debug("clk-ref for %s not ready, retry\n", + node->name); + if (!ti_clk_retry_init(node, hw, omap_clk_register_apll)) + return; + + goto cleanup; + } - if (IS_ERR(ad->clk_ref) || IS_ERR(ad->clk_bypass)) { - pr_debug("clk-ref or clk-bypass for %s not ready, retry\n", + ad->clk_ref = __clk_get_hw(clk); + + clk = of_clk_get(node, 1); + if (IS_ERR(clk)) { + pr_debug("clk-bypass for %s not ready, retry\n", node->name); if (!ti_clk_retry_init(node, hw, omap_clk_register_apll)) return; @@ -152,6 +162,8 @@ static void __init omap_clk_register_apll(struct clk_hw *hw, goto cleanup; } + ad->clk_bypass = __clk_get_hw(clk); + clk = clk_register(NULL, &clk_hw->hw); if (!IS_ERR(clk)) { of_clk_add_provider(node, of_clk_src_simple_get, clk); diff --git a/drivers/clk/ti/clkt_dpll.c b/drivers/clk/ti/clkt_dpll.c index b5cc6f6..032c658 100644 --- a/drivers/clk/ti/clkt_dpll.c +++ b/drivers/clk/ti/clkt_dpll.c @@ -254,7 +254,7 @@ unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk) v >>= __ffs(dd->enable_mask); if (_omap2_dpll_is_in_bypass(v)) - return clk_get_rate(dd->clk_bypass); + return clk_hw_get_rate(dd->clk_bypass); v = ti_clk_ll_ops->clk_readl(dd->mult_div1_reg); dpll_mult = v & dd->mult_mask; @@ -262,7 +262,7 @@ unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk) dpll_div = v & dd->div1_mask; dpll_div >>= __ffs(dd->div1_mask); - dpll_clk = (u64)clk_get_rate(dd->clk_ref) * dpll_mult; + dpll_clk = (u64)clk_hw_get_rate(dd->clk_ref) * dpll_mult; do_div(dpll_clk, dpll_div + 1); return dpll_clk; @@ -301,7 +301,7 @@ long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate, dd = clk->dpll_data; - ref_rate = clk_get_rate(dd->clk_ref); + ref_rate = clk_hw_get_rate(dd->clk_ref); clk_name = clk_hw_get_name(hw); pr_debug("clock: %s: starting DPLL round_rate, target rate %lu\n", clk_name, target_rate); diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c index 5519b38..f8306f1 100644 --- a/drivers/clk/ti/dpll.c +++ b/drivers/clk/ti/dpll.c @@ -147,11 +147,22 @@ static void __init _register_dpll(struct clk_hw *hw, struct dpll_data *dd = clk_hw->dpll_data; struct clk *clk; - dd->clk_ref = of_clk_get(node, 0); - dd->clk_bypass = of_clk_get(node, 1); + clk = of_clk_get(node, 0); + if (IS_ERR(clk)) { + pr_debug("clk-ref missing for %s, retry later\n", + node->name); + if (!ti_clk_retry_init(node, hw, _register_dpll)) + return; - if (IS_ERR(dd->clk_ref) || IS_ERR(dd->clk_bypass)) { - pr_debug("clk-ref or clk-bypass missing for %s, retry later\n", + goto cleanup; + } + + dd->clk_ref = __clk_get_hw(clk); + + clk = of_clk_get(node, 1); + + if (IS_ERR(clk)) { + pr_debug("clk-bypass missing for %s, retry later\n", node->name); if (!ti_clk_retry_init(node, hw, _register_dpll)) return; @@ -159,6 +170,8 @@ static void __init _register_dpll(struct clk_hw *hw, goto cleanup; } + dd->clk_bypass = __clk_get_hw(clk); + /* register the clock */ clk = clk_register(NULL, &clk_hw->hw); @@ -251,8 +264,8 @@ struct clk *ti_clk_register_dpll(struct ti_clk *setup) dd->recal_en_bit = dpll->recal_en_bit; dd->recal_st_bit = dpll->recal_st_bit; - dd->clk_ref = clk_ref; - dd->clk_bypass = clk_bypass; + dd->clk_ref = __clk_get_hw(clk_ref); + dd->clk_bypass = __clk_get_hw(clk_bypass); if (dpll->flags & CLKF_CORE) ops = &omap3_dpll_core_ck_ops; diff --git a/drivers/clk/ti/dpll3xxx.c b/drivers/clk/ti/dpll3xxx.c index cc73929..88f2ce8 100644 --- a/drivers/clk/ti/dpll3xxx.c +++ b/drivers/clk/ti/dpll3xxx.c @@ -98,7 +98,7 @@ static u16 _omap3_dpll_compute_freqsel(struct clk_hw_omap *clk, u8 n) unsigned long fint; u16 f = 0; - fint = clk_get_rate(clk->dpll_data->clk_ref) / n; + fint = clk_hw_get_rate(clk->dpll_data->clk_ref) / n; pr_debug("clock: fint is %lu\n", fint); @@ -460,12 +460,11 @@ int omap3_noncore_dpll_enable(struct clk_hw *hw) parent = clk_hw_get_parent(hw); - if (clk_hw_get_rate(hw) == - clk_hw_get_rate(__clk_get_hw(dd->clk_bypass))) { - WARN_ON(parent != __clk_get_hw(dd->clk_bypass)); + if (clk_hw_get_rate(hw) == clk_hw_get_rate(dd->clk_bypass)) { + WARN_ON(parent != dd->clk_bypass); r = _omap3_noncore_dpll_bypass(clk); } else { - WARN_ON(parent != __clk_get_hw(dd->clk_ref)); + WARN_ON(parent != dd->clk_ref); r = _omap3_noncore_dpll_lock(clk); } @@ -513,13 +512,13 @@ int omap3_noncore_dpll_determine_rate(struct clk_hw *hw, if (!dd) return -EINVAL; - if (clk_get_rate(dd->clk_bypass) == req->rate && + if (clk_hw_get_rate(dd->clk_bypass) == req->rate && (dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) { - req->best_parent_hw = __clk_get_hw(dd->clk_bypass); + req->best_parent_hw = dd->clk_bypass; } else { req->rate = omap2_dpll_round_rate(hw, req->rate, &req->best_parent_rate); - req->best_parent_hw = __clk_get_hw(dd->clk_ref); + req->best_parent_hw = dd->clk_ref; } req->best_parent_rate = req->rate; @@ -577,7 +576,7 @@ int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate, if (!dd) return -EINVAL; - if (clk_hw_get_parent(hw) != __clk_get_hw(dd->clk_ref)) + if (clk_hw_get_parent(hw) != dd->clk_ref) return -EINVAL; if (dd->last_rounded_rate == 0) diff --git a/drivers/clk/ti/dpll44xx.c b/drivers/clk/ti/dpll44xx.c index 660d743..82c05b5 100644 --- a/drivers/clk/ti/dpll44xx.c +++ b/drivers/clk/ti/dpll44xx.c @@ -94,7 +94,7 @@ static void omap4_dpll_lpmode_recalc(struct dpll_data *dd) { long fint, fout; - fint = clk_get_rate(dd->clk_ref) / (dd->last_rounded_n + 1); + fint = clk_hw_get_rate(dd->clk_ref) / (dd->last_rounded_n + 1); fout = fint * dd->last_rounded_m; if ((fint < OMAP4_DPLL_LP_FINT_MAX) && (fout < OMAP4_DPLL_LP_FOUT_MAX)) @@ -212,13 +212,13 @@ int omap4_dpll_regm4xen_determine_rate(struct clk_hw *hw, if (!dd) return -EINVAL; - if (clk_get_rate(dd->clk_bypass) == req->rate && + if (clk_hw_get_rate(dd->clk_bypass) == req->rate && (dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) { - req->best_parent_hw = __clk_get_hw(dd->clk_bypass); + req->best_parent_hw = dd->clk_bypass; } else { req->rate = omap4_dpll_regm4xen_round_rate(hw, req->rate, &req->best_parent_rate); - req->best_parent_hw = __clk_get_hw(dd->clk_ref); + req->best_parent_hw = dd->clk_ref; } req->best_parent_rate = req->rate; diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h index 9a63860..dc5164a 100644 --- a/include/linux/clk/ti.h +++ b/include/linux/clk/ti.h @@ -23,8 +23,8 @@ * @mult_div1_reg: register containing the DPLL M and N bitfields * @mult_mask: mask of the DPLL M bitfield in @mult_div1_reg * @div1_mask: mask of the DPLL N bitfield in @mult_div1_reg - * @clk_bypass: struct clk pointer to the clock's bypass clock input - * @clk_ref: struct clk pointer to the clock's reference clock input + * @clk_bypass: struct clk_hw pointer to the clock's bypass clock input + * @clk_ref: struct clk_hw pointer to the clock's reference clock input * @control_reg: register containing the DPLL mode bitfield * @enable_mask: mask of the DPLL mode bitfield in @control_reg * @last_rounded_rate: cache of the last rate result of omap2_dpll_round_rate() @@ -69,8 +69,8 @@ struct dpll_data { void __iomem *mult_div1_reg; u32 mult_mask; u32 div1_mask; - struct clk *clk_bypass; - struct clk *clk_ref; + struct clk_hw *clk_bypass; + struct clk_hw *clk_ref; void __iomem *control_reg; u32 enable_mask; unsigned long last_rounded_rate; -- cgit v0.10.2 From 56713da3ee5c6b0cf5b1881973b939250766a91b Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Mon, 22 Feb 2016 15:52:46 -0600 Subject: clk: socfpga: allow for multiple parents on Arria10 periph clocks There are some Arria10 clocks of type "altr,socfpga-a10-perip-clk" that can have multiple parents. Fix up the __socfpga_periph_init() to call of_clk_parent_fill() that will return the appropriate number of parents. Also, update __socfpga_gate_init() to call of_clk_parent_fill() helper function. Signed-off-by: Dinh Nguyen Signed-off-by: Stephen Boyd diff --git a/drivers/clk/socfpga/clk-gate-a10.c b/drivers/clk/socfpga/clk-gate-a10.c index 1cebf25..c2d5727 100644 --- a/drivers/clk/socfpga/clk-gate-a10.c +++ b/drivers/clk/socfpga/clk-gate-a10.c @@ -115,7 +115,6 @@ static void __init __socfpga_gate_init(struct device_node *node, const char *parent_name[SOCFPGA_MAX_PARENTS]; struct clk_init_data init; int rc; - int i = 0; socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL); if (WARN_ON(!socfpga_clk)) @@ -167,12 +166,9 @@ static void __init __socfpga_gate_init(struct device_node *node, init.name = clk_name; init.ops = ops; init.flags = 0; - while (i < SOCFPGA_MAX_PARENTS && (parent_name[i] = - of_clk_get_parent_name(node, i)) != NULL) - i++; + init.num_parents = of_clk_parent_fill(node, parent_name, SOCFPGA_MAX_PARENTS); init.parent_names = parent_name; - init.num_parents = i; socfpga_clk->hw.hw.init = &init; clk = clk_register(NULL, &socfpga_clk->hw.hw); diff --git a/drivers/clk/socfpga/clk-periph-a10.c b/drivers/clk/socfpga/clk-periph-a10.c index 1f397cb..70993f1 100644 --- a/drivers/clk/socfpga/clk-periph-a10.c +++ b/drivers/clk/socfpga/clk-periph-a10.c @@ -74,7 +74,7 @@ static __init void __socfpga_periph_init(struct device_node *node, struct clk *clk; struct socfpga_periph_clk *periph_clk; const char *clk_name = node->name; - const char *parent_name; + const char *parent_name[SOCFPGA_MAX_PARENTS]; struct clk_init_data init; int rc; u32 fixed_div; @@ -109,9 +109,8 @@ static __init void __socfpga_periph_init(struct device_node *node, init.ops = ops; init.flags = 0; - parent_name = of_clk_get_parent_name(node, 0); - init.num_parents = 1; - init.parent_names = &parent_name; + init.num_parents = of_clk_parent_fill(node, parent_name, SOCFPGA_MAX_PARENTS); + init.parent_names = parent_name; periph_clk->hw.hw.init = &init; -- cgit v0.10.2 From fa459711a0b8fb190a12fe86b03d910c252a7f5c Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Mon, 22 Feb 2016 15:01:39 -0800 Subject: Revert "clk: avoid circular clock topology" This reverts commit 858d5881564026cbc4e6f5e25ae878a27df5d4c9. Joachim reports that this commit breaks lpc18xx boot. This is because the hardware has circular clk topology where PLLs can feed into dividers and the same dividers can feed into the PLLs. The hardware is designed this way so that you can choose to put the divider before the PLL or after the PLL depending on what you configure to be the parent of the divider and what you configure to be the parent of the PLL. So let's drop this patch for now because we have hardware that actually has loops. A future patch could check for circular parents when we change parents and fail the switch, but that's probably best left to some debugging Kconfig option so that we don't suffer the sanity checking cost all the time. Reported-by: Joachim Eastwood Cc: Masahiro Yamada Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 58ef3da..51d6733 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -2242,38 +2242,6 @@ static inline void clk_debug_unregister(struct clk_core *core) #endif /** - * __clk_is_ancestor - check if a clk_core is a possible ancestor of another - * @core: clock core - * @ancestor: ancestor clock core - * - * Returns true if there is a possibility that @ancestor can be an ancestor - * of @core, false otherwise. - * - * This function can be used against @core or @ancestor that has not been - * registered yet. - */ -static bool __clk_is_ancestor(struct clk_core *core, struct clk_core *ancestor) -{ - struct clk_core *parent; - int i; - - for (i = 0; i < core->num_parents; i++) { - parent = clk_core_get_parent_by_index(core, i); - /* - * If ancestor has not been added to clk_{root,orphan}_list - * yet, clk_core_lookup() cannot find it. If parent is NULL, - * compare the name strings, too. - */ - if ((parent && (parent == ancestor || - __clk_is_ancestor(parent, ancestor))) || - (!parent && !strcmp(core->parent_names[i], ancestor->name))) - return true; - } - - return false; -} - -/** * __clk_core_init - initialize the data structures in a struct clk_core * @core: clk_core being initialized * @@ -2338,14 +2306,6 @@ static int __clk_core_init(struct clk_core *core) "%s: invalid NULL in %s's .parent_names\n", __func__, core->name); - /* If core is an ancestor of itself, it would make a loop. */ - if (__clk_is_ancestor(core, core)) { - pr_err("%s: %s would create circular parent\n", __func__, - core->name); - ret = -EINVAL; - goto out; - } - core->parent = __clk_init_parent(core); /* -- cgit v0.10.2 From 706d5c73e3367e2b866a211d1bff2cedab772146 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Mon, 22 Feb 2016 15:43:41 -0800 Subject: clk: Update some outdated comments __clk_init() was renamed to __clk_core_init() but these comments weren't updated. Cc: Masahiro Yamada Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 51d6733..d95d6f9 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -2157,7 +2157,7 @@ unlock: * * Dynamically removes a clk and all its child nodes from the * debugfs clk directory if clk->dentry points to debugfs created by - * clk_debug_register in __clk_init. + * clk_debug_register in __clk_core_init. */ static void clk_debug_unregister(struct clk_core *core) { @@ -2309,8 +2309,8 @@ static int __clk_core_init(struct clk_core *core) core->parent = __clk_init_parent(core); /* - * Populate core->parent if parent has already been __clk_init'd. If - * parent has not yet been __clk_init'd then place clk in the orphan + * Populate core->parent if parent has already been clk_core_init'd. If + * parent has not yet been clk_core_init'd then place clk in the orphan * list. If clk doesn't have any parents then place it in the root * clk list. * -- cgit v0.10.2 From 3c30e382ae55f6e124f6b3d9701e200dd33fdc84 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Wed, 18 Feb 2015 17:31:35 +0100 Subject: clk: samsung: exynos5433: Fix typos in *_ISP_MPWM clock names This fixes "MPWM" -> "WPWM" typo in 3 *ISP_MWPM clock definitions. Signed-off-by: Sylwester Nawrocki diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index b7f1fb7..982abb7 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -5165,7 +5165,7 @@ static struct samsung_mux_clock cam1_mux_clks[] __initdata = { static struct samsung_div_clock cam1_div_clks[] __initdata = { /* DIV_CAM10 */ - DIV(CLK_DIV_SCLK_ISP_WPWM, "div_sclk_isp_wpwm", + DIV(CLK_DIV_SCLK_ISP_MPWM, "div_sclk_isp_mpwm", "div_pclk_cam1_83", DIV_CAM10, 16, 2), DIV(CLK_DIV_PCLK_CAM1_83, "div_pclk_cam1_83", "mout_aclk_cam1_333_user", DIV_CAM10, 12, 2), @@ -5359,7 +5359,7 @@ static struct samsung_gate_clock cam1_gate_clks[] __initdata = { ENABLE_PCLK_CAM1, 5, CLK_IGNORE_UNUSED, 0), GATE(CLK_PCLK_ISP_I2C0, "pclk_isp_i2c0", "div_pclk_cam1_83", ENABLE_PCLK_CAM1, 4, CLK_IGNORE_UNUSED, 0), - GATE(CLK_PCLK_ISP_MPWM, "pclk_isp_wpwm", "div_pclk_cam1_83", + GATE(CLK_PCLK_ISP_MPWM, "pclk_isp_mpwm", "div_pclk_cam1_83", ENABLE_PCLK_CAM1, 3, CLK_IGNORE_UNUSED, 0), GATE(CLK_PCLK_FD, "pclk_fd", "div_pclk_fd", ENABLE_PCLK_CAM1, 3, CLK_IGNORE_UNUSED, 0), @@ -5392,7 +5392,7 @@ static struct samsung_gate_clock cam1_gate_clks[] __initdata = { ENABLE_SCLK_CAM1, 5, 0, 0), GATE(CLK_SCLK_ISP_SPI0, "sclk_isp_spi0", "mout_sclk_isp_spi0_user", ENABLE_SCLK_CAM1, 4, 0, 0), - GATE(CLK_SCLK_ISP_MPWM, "sclk_isp_wpwm", "div_sclk_isp_wpwm", + GATE(CLK_SCLK_ISP_MPWM, "sclk_isp_mpwm", "div_sclk_isp_mpwm", ENABLE_SCLK_CAM1, 3, 0, 0), GATE(CLK_PCLK_DBG_ISP, "sclk_dbg_isp", "div_pclk_dbg_cam1", ENABLE_SCLK_CAM1, 2, 0, 0), diff --git a/include/dt-bindings/clock/exynos5433.h b/include/dt-bindings/clock/exynos5433.h index 5c2636c..8e024fe 100644 --- a/include/dt-bindings/clock/exynos5433.h +++ b/include/dt-bindings/clock/exynos5433.h @@ -1303,7 +1303,7 @@ #define CLK_MOUT_ACLK_LITE_C_B 13 #define CLK_MOUT_ACLK_LITE_C_A 14 -#define CLK_DIV_SCLK_ISP_WPWM 15 +#define CLK_DIV_SCLK_ISP_MPWM 15 #define CLK_DIV_PCLK_CAM1_83 16 #define CLK_DIV_PCLK_CAM1_166 17 #define CLK_DIV_PCLK_DBG_CAM1 18 -- cgit v0.10.2 From c7f23180c6025fc93d1b743a49a97c4bb0c26f19 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 23 Feb 2016 15:00:03 +0530 Subject: clk: shmobile: check for failure We were not checking the return from devm_add_action() which can fail. Start using the helper devm_add_action_or_reset() and return directly as we know that the cleanup has been done by this helper. Signed-off-by: Sudip Mukherjee Signed-off-by: Stephen Boyd diff --git a/drivers/clk/shmobile/renesas-cpg-mssr.c b/drivers/clk/shmobile/renesas-cpg-mssr.c index 9a4d888..925b600 100644 --- a/drivers/clk/shmobile/renesas-cpg-mssr.c +++ b/drivers/clk/shmobile/renesas-cpg-mssr.c @@ -568,7 +568,11 @@ static int __init cpg_mssr_probe(struct platform_device *pdev) if (error) return error; - devm_add_action(dev, cpg_mssr_del_clk_provider, np); + error = devm_add_action_or_reset(dev, + cpg_mssr_del_clk_provider, + np); + if (error) + return error; error = cpg_mssr_add_clk_domain(dev, info->core_pm_clks, info->num_core_pm_clks); -- cgit v0.10.2 From a665d30f1f2575df864e706dc8209458b8f4cf88 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Wed, 27 May 2015 15:04:43 +0200 Subject: clk: samsung: exynos5433: Fix definitions of MUX_SEL_CAM04 clocks This corrects assignment of bit offsets of the MUX_SEL_CAM04 register to the respective mux clocks. Signed-off-by: Sylwester Nawrocki diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index 982abb7..cf096f9 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -4753,21 +4753,21 @@ static struct samsung_mux_clock cam0_mux_clks[] __initdata = { MUX(CLK_MOUT_SCLK_LITE_FREECNT_C, "mout_sclk_lite_freecnt_c", mout_sclk_lite_freecnt_c_p, MUX_SEL_CAM04, 24, 1), MUX(CLK_MOUT_SCLK_LITE_FREECNT_B, "mout_sclk_lite_freecnt_b", - mout_sclk_lite_freecnt_b_p, MUX_SEL_CAM04, 24, 1), + mout_sclk_lite_freecnt_b_p, MUX_SEL_CAM04, 20, 1), MUX(CLK_MOUT_SCLK_LITE_FREECNT_A, "mout_sclk_lite_freecnt_a", - mout_sclk_lite_freecnt_a_p, MUX_SEL_CAM04, 24, 1), + mout_sclk_lite_freecnt_a_p, MUX_SEL_CAM04, 16, 1), MUX(CLK_MOUT_SCLK_PIXELASYNC_LITE_C_B, "mout_sclk_pixelasync_lite_c_b", - mout_sclk_pixelasync_lite_c_b_p, MUX_SEL_CAM04, 24, 1), + mout_sclk_pixelasync_lite_c_b_p, MUX_SEL_CAM04, 12, 1), MUX(CLK_MOUT_SCLK_PIXELASYNC_LITE_C_A, "mout_sclk_pixelasync_lite_c_a", - mout_sclk_pixelasync_lite_c_a_p, MUX_SEL_CAM04, 24, 1), + mout_sclk_pixelasync_lite_c_a_p, MUX_SEL_CAM04, 8, 1), MUX(CLK_MOUT_SCLK_PIXELASYNC_LITE_C_INIT_B, "mout_sclk_pixelasync_lite_c_init_b", mout_sclk_pixelasync_lite_c_init_b_p, - MUX_SEL_CAM04, 24, 1), + MUX_SEL_CAM04, 4, 1), MUX(CLK_MOUT_SCLK_PIXELASYNC_LITE_C_INIT_A, "mout_sclk_pixelasync_lite_c_init_a", mout_sclk_pixelasync_lite_c_init_a_p, - MUX_SEL_CAM04, 24, 1), + MUX_SEL_CAM04, 0, 1), }; static struct samsung_div_clock cam0_div_clks[] __initdata = { -- cgit v0.10.2 From f190a87e27aeb21b230bfb9eb5da2775bfdfb7e4 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Tue, 21 Jul 2015 14:37:57 +0200 Subject: clk: samsung: exynos5433: Fix definitions of SCLK ISP SENSOR0 clocks This fixes bit field offsets in the CMU_TOP CLK_DIV_SCLK_ISP_SENSOR_{A,B} clock definitions. Signed-off-by: Marek Szyprowski Signed-off-by: Sylwester Nawrocki diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index cf096f9..a1dfcb8 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -490,9 +490,9 @@ static struct samsung_div_clock top_div_clks[] __initdata = { DIV(CLK_DIV_SCLK_ISP_SENSOR1_A, "div_sclk_isp_sensor1_a", "mout_sclk_isp_sensor1", DIV_TOP_CAM11, 8, 4), DIV(CLK_DIV_SCLK_ISP_SENSOR0_B, "div_sclk_isp_sensor0_b", - "div_sclk_isp_sensor0_a", DIV_TOP_CAM11, 12, 4), + "div_sclk_isp_sensor0_a", DIV_TOP_CAM11, 4, 4), DIV(CLK_DIV_SCLK_ISP_SENSOR0_A, "div_sclk_isp_sensor0_a", - "mout_sclk_isp_sensor0", DIV_TOP_CAM11, 8, 4), + "mout_sclk_isp_sensor0", DIV_TOP_CAM11, 0, 4), /* DIV_TOP_FSYS0 */ DIV(CLK_DIV_SCLK_MMC1_B, "div_sclk_mmc1_b", "div_sclk_mmc1_a", -- cgit v0.10.2 From f0abd93125df647eabad6953b14ee9ac2acecca5 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Tue, 26 May 2015 12:55:50 +0200 Subject: clk: samsung: exynos5433: Drop RO registers from the save/restore lists Restoring read-only registers is of not much effect, drop them from the respective lists. Signed-off-by: Sylwester Nawrocki diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index a1dfcb8..eb4d141 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -142,17 +142,6 @@ static unsigned long top_clk_regs[] __initdata = { MUX_ENABLE_TOP_FSYS1, MUX_ENABLE_TOP_PERIC0, MUX_ENABLE_TOP_PERIC1, - MUX_STAT_TOP0, - MUX_STAT_TOP1, - MUX_STAT_TOP2, - MUX_STAT_TOP3, - MUX_STAT_TOP4, - MUX_STAT_TOP_MSCL, - MUX_STAT_TOP_CAM1, - MUX_STAT_TOP_FSYS0, - MUX_STAT_TOP_FSYS1, - MUX_STAT_TOP_PERIC0, - MUX_STAT_TOP_PERIC1, DIV_TOP0, DIV_TOP1, DIV_TOP2, @@ -170,22 +159,6 @@ static unsigned long top_clk_regs[] __initdata = { DIV_TOP_PERIC3, DIV_TOP_PERIC4, DIV_TOP_PLL_FREQ_DET, - DIV_STAT_TOP0, - DIV_STAT_TOP1, - DIV_STAT_TOP2, - DIV_STAT_TOP3, - DIV_STAT_TOP4, - DIV_STAT_TOP_MSCL, - DIV_STAT_TOP_CAM10, - DIV_STAT_TOP_CAM11, - DIV_STAT_TOP_FSYS0, - DIV_STAT_TOP_FSYS1, - DIV_STAT_TOP_FSYS2, - DIV_STAT_TOP_PERIC0, - DIV_STAT_TOP_PERIC1, - DIV_STAT_TOP_PERIC2, - DIV_STAT_TOP_PERIC3, - DIV_STAT_TOP_PLL_FREQ_DET, ENABLE_ACLK_TOP, ENABLE_SCLK_TOP, ENABLE_SCLK_TOP_MSCL, @@ -999,26 +972,12 @@ static unsigned long mif_clk_regs[] __initdata = { MUX_ENABLE_MIF5, MUX_ENABLE_MIF6, MUX_ENABLE_MIF7, - MUX_STAT_MIF0, - MUX_STAT_MIF1, - MUX_STAT_MIF2, - MUX_STAT_MIF3, - MUX_STAT_MIF4, - MUX_STAT_MIF5, - MUX_STAT_MIF6, - MUX_STAT_MIF7, DIV_MIF1, DIV_MIF2, DIV_MIF3, DIV_MIF4, DIV_MIF5, DIV_MIF_PLL_FREQ_DET, - DIV_STAT_MIF1, - DIV_STAT_MIF2, - DIV_STAT_MIF3, - DIV_STAT_MIF4, - DIV_STAT_MIF5, - DIV_STAT_MIF_PLL_FREQ_DET, ENABLE_ACLK_MIF0, ENABLE_ACLK_MIF1, ENABLE_ACLK_MIF2, @@ -1565,7 +1524,6 @@ CLK_OF_DECLARE(exynos5433_cmu_mif, "samsung,exynos5433-cmu-mif", static unsigned long peric_clk_regs[] __initdata = { DIV_PERIC, - DIV_STAT_PERIC, ENABLE_ACLK_PERIC, ENABLE_PCLK_PERIC0, ENABLE_PCLK_PERIC1, @@ -2012,11 +1970,6 @@ static unsigned long fsys_clk_regs[] __initdata = { MUX_ENABLE_FSYS2, MUX_ENABLE_FSYS3, MUX_ENABLE_FSYS4, - MUX_STAT_FSYS0, - MUX_STAT_FSYS1, - MUX_STAT_FSYS2, - MUX_STAT_FSYS3, - MUX_STAT_FSYS4, MUX_IGNORE_FSYS2, MUX_IGNORE_FSYS3, ENABLE_ACLK_FSYS0, @@ -2362,9 +2315,7 @@ CLK_OF_DECLARE(exynos5433_cmu_fsys, "samsung,exynos5433-cmu-fsys", static unsigned long g2d_clk_regs[] __initdata = { MUX_SEL_G2D0, MUX_SEL_ENABLE_G2D0, - MUX_SEL_STAT_G2D0, DIV_G2D, - DIV_STAT_G2D, DIV_ENABLE_ACLK_G2D, DIV_ENABLE_ACLK_G2D_SECURE_SMMU_G2D, DIV_ENABLE_PCLK_G2D, @@ -2520,16 +2471,9 @@ static unsigned long disp_clk_regs[] __initdata = { MUX_ENABLE_DISP2, MUX_ENABLE_DISP3, MUX_ENABLE_DISP4, - MUX_STAT_DISP0, - MUX_STAT_DISP1, - MUX_STAT_DISP2, - MUX_STAT_DISP3, - MUX_STAT_DISP4, MUX_IGNORE_DISP2, DIV_DISP, DIV_DISP_PLL_FREQ_DET, - DIV_STAT_DISP, - DIV_STAT_DISP_PLL_FREQ_DET, ENABLE_ACLK_DISP0, ENABLE_ACLK_DISP1, ENABLE_PCLK_DISP, @@ -2923,11 +2867,8 @@ static unsigned long aud_clk_regs[] __initdata = { MUX_SEL_AUD1, MUX_ENABLE_AUD0, MUX_ENABLE_AUD1, - MUX_STAT_AUD0, DIV_AUD0, DIV_AUD1, - DIV_STAT_AUD0, - DIV_STAT_AUD1, ENABLE_ACLK_AUD, ENABLE_PCLK_AUD, ENABLE_SCLK_AUD0, @@ -3091,7 +3032,6 @@ PNAME(mout_aclk_bus2_400_p) = { "oscclk", "aclk_bus2_400", }; #define CMU_BUS_COMMON_CLK_REGS \ DIV_BUS, \ - DIV_STAT_BUS, \ ENABLE_ACLK_BUS, \ ENABLE_PCLK_BUS, \ ENABLE_IP_BUS0, \ @@ -3104,7 +3044,6 @@ static unsigned long bus01_clk_regs[] __initdata = { static unsigned long bus2_clk_regs[] __initdata = { MUX_SEL_BUS2, MUX_ENABLE_BUS2, - MUX_STAT_BUS2, CMU_BUS_COMMON_CLK_REGS, }; @@ -3263,11 +3202,8 @@ static unsigned long g3d_clk_regs[] __initdata = { G3D_PLL_FREQ_DET, MUX_SEL_G3D, MUX_ENABLE_G3D, - MUX_STAT_G3D, DIV_G3D, DIV_G3D_PLL_FREQ_DET, - DIV_STAT_G3D, - DIV_STAT_G3D_PLL_FREQ_DET, ENABLE_ACLK_G3D, ENABLE_PCLK_G3D, ENABLE_SCLK_G3D, @@ -3383,7 +3319,6 @@ CLK_OF_DECLARE(exynos5433_cmu_g3d, "samsung,exynos5433-cmu-g3d", static unsigned long gscl_clk_regs[] __initdata = { MUX_SEL_GSCL, MUX_ENABLE_GSCL, - MUX_STAT_GSCL, ENABLE_ACLK_GSCL, ENABLE_ACLK_GSCL_SECURE_SMMU_GSCL0, ENABLE_ACLK_GSCL_SECURE_SMMU_GSCL1, @@ -3547,15 +3482,9 @@ static unsigned long apollo_clk_regs[] __initdata = { MUX_ENABLE_APOLLO0, MUX_ENABLE_APOLLO1, MUX_ENABLE_APOLLO2, - MUX_STAT_APOLLO0, - MUX_STAT_APOLLO1, - MUX_STAT_APOLLO2, DIV_APOLLO0, DIV_APOLLO1, DIV_APOLLO_PLL_FREQ_DET, - DIV_STAT_APOLLO0, - DIV_STAT_APOLLO1, - DIV_STAT_APOLLO_PLL_FREQ_DET, ENABLE_ACLK_APOLLO, ENABLE_PCLK_APOLLO, ENABLE_SCLK_APOLLO, @@ -3739,15 +3668,9 @@ static unsigned long atlas_clk_regs[] __initdata = { MUX_ENABLE_ATLAS0, MUX_ENABLE_ATLAS1, MUX_ENABLE_ATLAS2, - MUX_STAT_ATLAS0, - MUX_STAT_ATLAS1, - MUX_STAT_ATLAS2, DIV_ATLAS0, DIV_ATLAS1, DIV_ATLAS_PLL_FREQ_DET, - DIV_STAT_ATLAS0, - DIV_STAT_ATLAS1, - DIV_STAT_ATLAS_PLL_FREQ_DET, ENABLE_ACLK_ATLAS, ENABLE_PCLK_ATLAS, ENABLE_SCLK_ATLAS, @@ -3941,10 +3864,7 @@ static unsigned long mscl_clk_regs[] __initdata = { MUX_SEL_MSCL1, MUX_ENABLE_MSCL0, MUX_ENABLE_MSCL1, - MUX_STAT_MSCL0, - MUX_STAT_MSCL1, DIV_MSCL, - DIV_STAT_MSCL, ENABLE_ACLK_MSCL, ENABLE_ACLK_MSCL_SECURE_SMMU_M2MSCALER0, ENABLE_ACLK_MSCL_SECURE_SMMU_M2MSCALER1, @@ -4101,9 +4021,7 @@ CLK_OF_DECLARE(exynos5433_cmu_mscl, "samsung,exynos5433-cmu-mscl", static unsigned long mfc_clk_regs[] __initdata = { MUX_SEL_MFC, MUX_ENABLE_MFC, - MUX_STAT_MFC, DIV_MFC, - DIV_STAT_MFC, ENABLE_ACLK_MFC, ENABLE_ACLK_MFC_SECURE_SMMU_MFC, ENABLE_PCLK_MFC, @@ -4211,9 +4129,7 @@ CLK_OF_DECLARE(exynos5433_cmu_mfc, "samsung,exynos5433-cmu-mfc", static unsigned long hevc_clk_regs[] __initdata = { MUX_SEL_HEVC, MUX_ENABLE_HEVC, - MUX_STAT_HEVC, DIV_HEVC, - DIV_STAT_HEVC, ENABLE_ACLK_HEVC, ENABLE_ACLK_HEVC_SECURE_SMMU_HEVC, ENABLE_PCLK_HEVC, @@ -4325,9 +4241,7 @@ CLK_OF_DECLARE(exynos5433_cmu_hevc, "samsung,exynos5433-cmu-hevc", static unsigned long isp_clk_regs[] __initdata = { MUX_SEL_ISP, MUX_ENABLE_ISP, - MUX_STAT_ISP, DIV_ISP, - DIV_STAT_ISP, ENABLE_ACLK_ISP0, ENABLE_ACLK_ISP1, ENABLE_ACLK_ISP2, @@ -4607,20 +4521,11 @@ static unsigned long cam0_clk_regs[] __initdata = { MUX_ENABLE_CAM02, MUX_ENABLE_CAM03, MUX_ENABLE_CAM04, - MUX_STAT_CAM00, - MUX_STAT_CAM01, - MUX_STAT_CAM02, - MUX_STAT_CAM03, - MUX_STAT_CAM04, MUX_IGNORE_CAM01, DIV_CAM00, DIV_CAM01, DIV_CAM02, DIV_CAM03, - DIV_STAT_CAM00, - DIV_STAT_CAM01, - DIV_STAT_CAM02, - DIV_STAT_CAM03, ENABLE_ACLK_CAM00, ENABLE_ACLK_CAM01, ENABLE_ACLK_CAM02, @@ -5078,14 +4983,9 @@ static unsigned long cam1_clk_regs[] __initdata = { MUX_ENABLE_CAM10, MUX_ENABLE_CAM11, MUX_ENABLE_CAM12, - MUX_STAT_CAM10, - MUX_STAT_CAM11, - MUX_STAT_CAM12, MUX_IGNORE_CAM11, DIV_CAM10, DIV_CAM11, - DIV_STAT_CAM10, - DIV_STAT_CAM11, ENABLE_ACLK_CAM10, ENABLE_ACLK_CAM11, ENABLE_ACLK_CAM12, -- cgit v0.10.2 From 3795e0f6e484ec735f750dc3c39295138e98fba2 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Fri, 6 Nov 2015 12:55:30 +0100 Subject: clk: samsung: exynos5433: Fix mout_aclk_cam1*_user clocks definition Control bits for the ACLK_CAM1_552_USER and ACLK_CAM1_400_USER mux clocks are in MUX_SEL_CAM10, not MUX_SEL_CAM01 register. Signed-off-by: Sylwester Nawrocki diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index eb4d141..23dd651 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -5038,9 +5038,9 @@ static struct samsung_mux_clock cam1_mux_clks[] __initdata = { MUX(CLK_MOUT_ACLK_CAM1_333_USER, "mout_aclk_cam1_333_user", mout_aclk_cam1_333_user_p, MUX_SEL_CAM10, 8, 1), MUX(CLK_MOUT_ACLK_CAM1_400_USER, "mout_aclk_cam1_400_user", - mout_aclk_cam1_400_user_p, MUX_SEL_CAM01, 4, 1), + mout_aclk_cam1_400_user_p, MUX_SEL_CAM10, 4, 1), MUX(CLK_MOUT_ACLK_CAM1_552_USER, "mout_aclk_cam1_552_user", - mout_aclk_cam1_552_user_p, MUX_SEL_CAM01, 0, 1), + mout_aclk_cam1_552_user_p, MUX_SEL_CAM10, 0, 1), /* MUX_SEL_CAM11 */ MUX(CLK_MOUT_PHYCLK_RXBYTECLKHS0_S2B_USER, -- cgit v0.10.2 From a6cb74cbc927af04af827ef590082f9717ffad51 Mon Sep 17 00:00:00 2001 From: Jonghwa Lee Date: Wed, 6 May 2015 21:24:20 +0900 Subject: clk: samsung: exynos5433: Fix wrong registers of PCLK_GSCL_SMMU clocks This fixes register assignment in the CLK_PCLK_SMMU_GSCL{1,2} clocks definition. Signed-off-by: Jonghwa Lee Signed-off-by: Sylwester Nawrocki diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index 23dd651..707a814 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -3411,11 +3411,11 @@ static struct samsung_gate_clock gscl_gate_clks[] __initdata = { /* ENABLE_PCLK_GSCL_SECURE_SMMU_GSCL1 */ GATE(CLK_PCLK_SMMU_GSCL1, "pclk_smmu_gscl1", "mout_aclk_gscl_111_user", - ENABLE_PCLK_GSCL_SECURE_SMMU_GSCL0, 0, 0, 0), + ENABLE_PCLK_GSCL_SECURE_SMMU_GSCL1, 0, 0, 0), /* ENABLE_PCLK_GSCL_SECURE_SMMU_GSCL2 */ GATE(CLK_PCLK_SMMU_GSCL2, "pclk_smmu_gscl2", "mout_aclk_gscl_111_user", - ENABLE_PCLK_GSCL_SECURE_SMMU_GSCL0, 0, 0, 0), + ENABLE_PCLK_GSCL_SECURE_SMMU_GSCL2, 0, 0, 0), }; static struct samsung_cmu_info gscl_cmu_info __initdata = { -- cgit v0.10.2 From 6e17b4181603d183d20c73f4535529ddf2a2a020 Mon Sep 17 00:00:00 2001 From: Krzysztof Adamski Date: Mon, 22 Feb 2016 14:03:25 +0100 Subject: clk: sunxi: Add apb0 gates for H3 This patch adds support for APB0 in H3. It seems to be compatible with earlier SOCs. apb0 gates controls R_ block peripherals (R_PIO, R_IR, etc). Since this gates behave just like any Allwinner clock gate, add a generic compatible that can be reused if we don't have any clock to protect. Signed-off-by: Krzysztof Adamski [Maxime: Removed the H3 compatible from the simple-gates driver, reworked the commit log a bit] Signed-off-by: Maxime Ripard diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt index c09f59b..834436f 100644 --- a/Documentation/devicetree/bindings/clock/sunxi.txt +++ b/Documentation/devicetree/bindings/clock/sunxi.txt @@ -18,6 +18,7 @@ Required properties: "allwinner,sun4i-a10-cpu-clk" - for the CPU multiplexer clock "allwinner,sun4i-a10-axi-clk" - for the AXI clock "allwinner,sun8i-a23-axi-clk" - for the AXI clock on A23 + "allwinner,sun4i-a10-gates-clk" - for generic gates on all compatible SoCs "allwinner,sun4i-a10-axi-gates-clk" - for the AXI gates "allwinner,sun4i-a10-ahb-clk" - for the AHB clock "allwinner,sun5i-a13-ahb-clk" - for the AHB clock on A13 @@ -46,6 +47,7 @@ Required properties: "allwinner,sun6i-a31-apb0-gates-clk" - for the APB0 gates on A31 "allwinner,sun7i-a20-apb0-gates-clk" - for the APB0 gates on A20 "allwinner,sun8i-a23-apb0-gates-clk" - for the APB0 gates on A23 + "allwinner,sun8i-h3-apb0-gates-clk" - for the APB0 gates on H3 "allwinner,sun9i-a80-apb0-gates-clk" - for the APB0 gates on A80 "allwinner,sun4i-a10-apb1-clk" - for the APB1 clock "allwinner,sun9i-a80-apb1-clk" - for the APB1 bus clock on A80 diff --git a/drivers/clk/sunxi/clk-simple-gates.c b/drivers/clk/sunxi/clk-simple-gates.c index 2cfc5a8..a085c3b 100644 --- a/drivers/clk/sunxi/clk-simple-gates.c +++ b/drivers/clk/sunxi/clk-simple-gates.c @@ -98,6 +98,8 @@ static void __init sunxi_simple_gates_init(struct device_node *node) sunxi_simple_gates_setup(node, NULL, 0); } +CLK_OF_DECLARE(sun4i_a10_gates, "allwinner,sun4i-a10-gates-clk", + sunxi_simple_gates_init); CLK_OF_DECLARE(sun4i_a10_apb0, "allwinner,sun4i-a10-apb0-gates-clk", sunxi_simple_gates_init); CLK_OF_DECLARE(sun4i_a10_apb1, "allwinner,sun4i-a10-apb1-gates-clk", -- cgit v0.10.2 From 73f3f1382501a260a88801e3322ae6f3cf45c2fe Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Thu, 25 Feb 2016 12:18:25 -0800 Subject: clk: shmobile: Free 'clock' on error path We forgot to free this clock when we return early in this code. Cc: Geert Uytterhoeven Signed-off-by: Stephen Boyd diff --git a/drivers/clk/shmobile/renesas-cpg-mssr.c b/drivers/clk/shmobile/renesas-cpg-mssr.c index 925b600..58e24b3 100644 --- a/drivers/clk/shmobile/renesas-cpg-mssr.c +++ b/drivers/clk/shmobile/renesas-cpg-mssr.c @@ -348,6 +348,7 @@ static void __init cpg_mssr_register_mod_clk(const struct mssr_mod_clk *mod, #else dev_dbg(dev, "Ignoring MSTP %s to prevent disabling\n", mod->name); + kfree(clock); return; #endif } -- cgit v0.10.2 From 6971e863990b2514ae76a7bb245b1c33959c129a Mon Sep 17 00:00:00 2001 From: Varadarajan Narayanan Date: Thu, 19 Nov 2015 17:19:29 -0600 Subject: clk: qcom: Add IPQ4019 Global Clock Controller support This patch adds support for the global clock controller found on the IPQ4019 based devices. This includes UART, I2C, SPI etc. Signed-off-by: Pradeep Banavathi Signed-off-by: Senthilkumar N L Signed-off-by: Varadarajan Narayanan Signed-off-by: Matthew McClintock Acked-by: Andy Gross [sboyd@codeaurora.org: Drop 0x16024 enable_reg in crypto_ahb] Signed-off-by: Stephen Boyd diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc.txt b/Documentation/devicetree/bindings/clock/qcom,gcc.txt index 72f82f4..9a60fde 100644 --- a/Documentation/devicetree/bindings/clock/qcom,gcc.txt +++ b/Documentation/devicetree/bindings/clock/qcom,gcc.txt @@ -7,6 +7,7 @@ Required properties : "qcom,gcc-apq8064" "qcom,gcc-apq8084" "qcom,gcc-ipq8064" + "qcom,gcc-ipq4019" "qcom,gcc-msm8660" "qcom,gcc-msm8916" "qcom,gcc-msm8960" diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index b552ece..95e3b3e 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -28,6 +28,14 @@ config APQ_MMCC_8084 Say Y if you want to support multimedia devices such as display, graphics, video encode/decode, camera, etc. +config IPQ_GCC_4019 + tristate "IPQ4019 Global Clock Controller" + depends on COMMON_CLK_QCOM + help + Support for the global clock controller on ipq4019 devices. + Say Y if you want to use peripheral devices such as UART, SPI, + i2c, USB, SD/eMMC, etc. + config IPQ_GCC_806X tristate "IPQ806x Global Clock Controller" depends on COMMON_CLK_QCOM diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index dc4280b..2a25f4e 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -14,6 +14,7 @@ clk-qcom-$(CONFIG_QCOM_GDSC) += gdsc.o obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o obj-$(CONFIG_APQ_MMCC_8084) += mmcc-apq8084.o +obj-$(CONFIG_IPQ_GCC_4019) += gcc-ipq4019.o obj-$(CONFIG_IPQ_GCC_806X) += gcc-ipq806x.o obj-$(CONFIG_IPQ_LCC_806X) += lcc-ipq806x.o obj-$(CONFIG_MSM_GCC_8660) += gcc-msm8660.o diff --git a/drivers/clk/qcom/gcc-ipq4019.c b/drivers/clk/qcom/gcc-ipq4019.c new file mode 100644 index 0000000..5428efb --- /dev/null +++ b/drivers/clk/qcom/gcc-ipq4019.c @@ -0,0 +1,1354 @@ +/* + * Copyright (c) 2015 The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "common.h" +#include "clk-regmap.h" +#include "clk-rcg.h" +#include "clk-branch.h" +#include "reset.h" + +enum { + P_XO, + P_FEPLL200, + P_FEPLL500, + P_DDRPLL, + P_FEPLLWCSS2G, + P_FEPLLWCSS5G, + P_FEPLL125DLY, + P_DDRPLLAPSS, +}; + +static struct parent_map gcc_xo_200_500_map[] = { + { P_XO, 0 }, + { P_FEPLL200, 1 }, + { P_FEPLL500, 2 }, +}; + +static const char * const gcc_xo_200_500[] = { + "xo", + "fepll200", + "fepll500", +}; + +static struct parent_map gcc_xo_200_map[] = { + { P_XO, 0 }, + { P_FEPLL200, 1 }, +}; + +static const char * const gcc_xo_200[] = { + "xo", + "fepll200", +}; + +static struct parent_map gcc_xo_200_spi_map[] = { + { P_XO, 0 }, + { P_FEPLL200, 2 }, +}; + +static const char * const gcc_xo_200_spi[] = { + "xo", + "fepll200", +}; + +static struct parent_map gcc_xo_sdcc1_500_map[] = { + { P_XO, 0 }, + { P_DDRPLL, 1 }, + { P_FEPLL500, 2 }, +}; + +static const char * const gcc_xo_sdcc1_500[] = { + "xo", + "ddrpll", + "fepll500", +}; + +static struct parent_map gcc_xo_wcss2g_map[] = { + { P_XO, 0 }, + { P_FEPLLWCSS2G, 1 }, +}; + +static const char * const gcc_xo_wcss2g[] = { + "xo", + "fepllwcss2g", +}; + +static struct parent_map gcc_xo_wcss5g_map[] = { + { P_XO, 0 }, + { P_FEPLLWCSS5G, 1 }, +}; + +static const char * const gcc_xo_wcss5g[] = { + "xo", + "fepllwcss5g", +}; + +static struct parent_map gcc_xo_125_dly_map[] = { + { P_XO, 0 }, + { P_FEPLL125DLY, 1 }, +}; + +static const char * const gcc_xo_125_dly[] = { + "xo", + "fepll125dly", +}; + +static struct parent_map gcc_xo_ddr_500_200_map[] = { + { P_XO, 0 }, + { P_FEPLL200, 3 }, + { P_FEPLL500, 2 }, + { P_DDRPLLAPSS, 1 }, +}; + +static const char * const gcc_xo_ddr_500_200[] = { + "xo", + "fepll200", + "fepll500", + "ddrpllapss", +}; + +#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } +#define P_XO 0 +#define FE_PLL_200 1 +#define FE_PLL_500 2 +#define DDRC_PLL_666 3 + +#define DDRC_PLL_666_SDCC 1 +#define FE_PLL_125_DLY 1 + +#define FE_PLL_WCSS2G 1 +#define FE_PLL_WCSS5G 1 + +static const struct freq_tbl ftbl_gcc_audio_pwm_clk[] = { + F(48000000, P_XO, 1, 0, 0), + F(200000000, FE_PLL_200, 1, 0, 0), + { } +}; + +static struct clk_rcg2 audio_clk_src = { + .cmd_rcgr = 0x1b000, + .hid_width = 5, + .parent_map = gcc_xo_200_map, + .freq_tbl = ftbl_gcc_audio_pwm_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "audio_clk_src", + .parent_names = gcc_xo_200, + .num_parents = 2, + .ops = &clk_rcg2_ops, + + }, +}; + +static struct clk_branch gcc_audio_ahb_clk = { + .halt_reg = 0x1b010, + .clkr = { + .enable_reg = 0x1b010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_audio_ahb_clk", + .parent_names = (const char *[]){ + "pcnoc_clk_src", + }, + .flags = CLK_SET_RATE_PARENT, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_audio_pwm_clk = { + .halt_reg = 0x1b00C, + .clkr = { + .enable_reg = 0x1b00C, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_audio_pwm_clk", + .parent_names = (const char *[]){ + "audio_clk_src", + }, + .flags = CLK_SET_RATE_PARENT, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_gcc_blsp1_qup1_2_i2c_apps_clk[] = { + F(19200000, P_XO, 1, 2, 5), + F(24000000, P_XO, 1, 1, 2), + { } +}; + +static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = { + .cmd_rcgr = 0x200c, + .hid_width = 5, + .parent_map = gcc_xo_200_map, + .freq_tbl = ftbl_gcc_blsp1_qup1_2_i2c_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup1_i2c_apps_clk_src", + .parent_names = gcc_xo_200, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = { + .halt_reg = 0x2008, + .clkr = { + .enable_reg = 0x2008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup1_i2c_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup1_i2c_apps_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = { + .cmd_rcgr = 0x3000, + .hid_width = 5, + .parent_map = gcc_xo_200_map, + .freq_tbl = ftbl_gcc_blsp1_qup1_2_i2c_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup2_i2c_apps_clk_src", + .parent_names = gcc_xo_200, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = { + .halt_reg = 0x3010, + .clkr = { + .enable_reg = 0x3010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup2_i2c_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup2_i2c_apps_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static const struct freq_tbl ftbl_gcc_blsp1_qup1_2_spi_apps_clk[] = { + F(960000, P_XO, 12, 1, 4), + F(4800000, P_XO, 1, 1, 10), + F(9600000, P_XO, 1, 1, 5), + F(15000000, P_XO, 1, 1, 3), + F(19200000, P_XO, 1, 2, 5), + F(24000000, P_XO, 1, 1, 2), + F(48000000, P_XO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = { + .cmd_rcgr = 0x2024, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_200_spi_map, + .freq_tbl = ftbl_gcc_blsp1_qup1_2_spi_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup1_spi_apps_clk_src", + .parent_names = gcc_xo_200_spi, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = { + .halt_reg = 0x2004, + .clkr = { + .enable_reg = 0x2004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup1_spi_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup1_spi_apps_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = { + .cmd_rcgr = 0x3014, + .mnd_width = 8, + .hid_width = 5, + .freq_tbl = ftbl_gcc_blsp1_qup1_2_spi_apps_clk, + .parent_map = gcc_xo_200_spi_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup2_spi_apps_clk_src", + .parent_names = gcc_xo_200_spi, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = { + .halt_reg = 0x300c, + .clkr = { + .enable_reg = 0x300c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup2_spi_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup2_spi_apps_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static const struct freq_tbl ftbl_gcc_blsp1_uart1_2_apps_clk[] = { + F(1843200, FE_PLL_200, 1, 144, 15625), + F(3686400, FE_PLL_200, 1, 288, 15625), + F(7372800, FE_PLL_200, 1, 576, 15625), + F(14745600, FE_PLL_200, 1, 1152, 15625), + F(16000000, FE_PLL_200, 1, 2, 25), + F(24000000, P_XO, 1, 1, 2), + F(32000000, FE_PLL_200, 1, 4, 25), + F(40000000, FE_PLL_200, 1, 1, 5), + F(46400000, FE_PLL_200, 1, 29, 125), + F(48000000, P_XO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 blsp1_uart1_apps_clk_src = { + .cmd_rcgr = 0x2044, + .mnd_width = 16, + .hid_width = 5, + .freq_tbl = ftbl_gcc_blsp1_uart1_2_apps_clk, + .parent_map = gcc_xo_200_spi_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart1_apps_clk_src", + .parent_names = gcc_xo_200_spi, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_blsp1_uart1_apps_clk = { + .halt_reg = 0x203c, + .clkr = { + .enable_reg = 0x203c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart1_apps_clk", + .parent_names = (const char *[]){ + "blsp1_uart1_apps_clk_src", + }, + .flags = CLK_SET_RATE_PARENT, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_rcg2 blsp1_uart2_apps_clk_src = { + .cmd_rcgr = 0x3034, + .mnd_width = 16, + .hid_width = 5, + .freq_tbl = ftbl_gcc_blsp1_uart1_2_apps_clk, + .parent_map = gcc_xo_200_spi_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart2_apps_clk_src", + .parent_names = gcc_xo_200_spi, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_blsp1_uart2_apps_clk = { + .halt_reg = 0x302c, + .clkr = { + .enable_reg = 0x302c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart2_apps_clk", + .parent_names = (const char *[]){ + "blsp1_uart2_apps_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static const struct freq_tbl ftbl_gcc_gp_clk[] = { + F(1250000, FE_PLL_200, 1, 16, 0), + F(2500000, FE_PLL_200, 1, 8, 0), + F(5000000, FE_PLL_200, 1, 4, 0), + { } +}; + +static struct clk_rcg2 gp1_clk_src = { + .cmd_rcgr = 0x8004, + .mnd_width = 8, + .hid_width = 5, + .freq_tbl = ftbl_gcc_gp_clk, + .parent_map = gcc_xo_200_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp1_clk_src", + .parent_names = gcc_xo_200, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_gp1_clk = { + .halt_reg = 0x8000, + .clkr = { + .enable_reg = 0x8000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp1_clk", + .parent_names = (const char *[]){ + "gp1_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg2 gp2_clk_src = { + .cmd_rcgr = 0x9004, + .mnd_width = 8, + .hid_width = 5, + .freq_tbl = ftbl_gcc_gp_clk, + .parent_map = gcc_xo_200_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp2_clk_src", + .parent_names = gcc_xo_200, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_gp2_clk = { + .halt_reg = 0x9000, + .clkr = { + .enable_reg = 0x9000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp2_clk", + .parent_names = (const char *[]){ + "gp2_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg2 gp3_clk_src = { + .cmd_rcgr = 0xa004, + .mnd_width = 8, + .hid_width = 5, + .freq_tbl = ftbl_gcc_gp_clk, + .parent_map = gcc_xo_200_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp3_clk_src", + .parent_names = gcc_xo_200, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_gp3_clk = { + .halt_reg = 0xa000, + .clkr = { + .enable_reg = 0xa000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp3_clk", + .parent_names = (const char *[]){ + "gp3_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static const struct freq_tbl ftbl_gcc_sdcc1_apps_clk[] = { + F(144000, P_XO, 1, 3, 240), + F(400000, P_XO, 1, 1, 0), + F(20000000, FE_PLL_500, 1, 1, 25), + F(25000000, FE_PLL_500, 1, 1, 20), + F(50000000, FE_PLL_500, 1, 1, 10), + F(100000000, FE_PLL_500, 1, 1, 5), + F(193000000, DDRC_PLL_666_SDCC, 1, 0, 0), + { } +}; + +static struct clk_rcg2 sdcc1_apps_clk_src = { + .cmd_rcgr = 0x18004, + .hid_width = 5, + .freq_tbl = ftbl_gcc_sdcc1_apps_clk, + .parent_map = gcc_xo_sdcc1_500_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "sdcc1_apps_clk_src", + .parent_names = gcc_xo_sdcc1_500, + .num_parents = 3, + .ops = &clk_rcg2_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct freq_tbl ftbl_gcc_apps_clk[] = { + F(48000000, P_XO, 1, 0, 0), + F(200000000, FE_PLL_200, 1, 0, 0), + F(500000000, FE_PLL_500, 1, 0, 0), + F(626000000, DDRC_PLL_666, 1, 0, 0), + { } +}; + +static struct clk_rcg2 apps_clk_src = { + .cmd_rcgr = 0x1900c, + .hid_width = 5, + .freq_tbl = ftbl_gcc_apps_clk, + .parent_map = gcc_xo_ddr_500_200_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "apps_clk_src", + .parent_names = gcc_xo_ddr_500_200, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_apps_ahb_clk[] = { + F(48000000, P_XO, 1, 0, 0), + F(100000000, FE_PLL_200, 2, 0, 0), + { } +}; + +static struct clk_rcg2 apps_ahb_clk_src = { + .cmd_rcgr = 0x19014, + .hid_width = 5, + .parent_map = gcc_xo_200_500_map, + .freq_tbl = ftbl_gcc_apps_ahb_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "apps_ahb_clk_src", + .parent_names = gcc_xo_200_500, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_apss_ahb_clk = { + .halt_reg = 0x19004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x6000, + .enable_mask = BIT(14), + .hw.init = &(struct clk_init_data){ + .name = "gcc_apss_ahb_clk", + .parent_names = (const char *[]){ + "apps_ahb_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch gcc_blsp1_ahb_clk = { + .halt_reg = 0x1008, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x6000, + .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_ahb_clk", + .parent_names = (const char *[]){ + "pcnoc_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_dcd_xo_clk = { + .halt_reg = 0x2103c, + .clkr = { + .enable_reg = 0x2103c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_dcd_xo_clk", + .parent_names = (const char *[]){ + "xo", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_boot_rom_ahb_clk = { + .halt_reg = 0x1300c, + .clkr = { + .enable_reg = 0x1300c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_boot_rom_ahb_clk", + .parent_names = (const char *[]){ + "pcnoc_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch gcc_crypto_ahb_clk = { + .halt_reg = 0x16024, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x6000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_crypto_ahb_clk", + .parent_names = (const char *[]){ + "pcnoc_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_crypto_axi_clk = { + .halt_reg = 0x16020, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x6000, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gcc_crypto_axi_clk", + .parent_names = (const char *[]){ + "fepll125", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_crypto_clk = { + .halt_reg = 0x1601c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x6000, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "gcc_crypto_clk", + .parent_names = (const char *[]){ + "fepll125", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ess_clk = { + .halt_reg = 0x12010, + .clkr = { + .enable_reg = 0x12010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ess_clk", + .parent_names = (const char *[]){ + "fephy_125m_dly_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch gcc_imem_axi_clk = { + .halt_reg = 0xe004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x6000, + .enable_mask = BIT(17), + .hw.init = &(struct clk_init_data){ + .name = "gcc_imem_axi_clk", + .parent_names = (const char *[]){ + "fepll200", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_imem_cfg_ahb_clk = { + .halt_reg = 0xe008, + .clkr = { + .enable_reg = 0xe008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_imem_cfg_ahb_clk", + .parent_names = (const char *[]){ + "pcnoc_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_ahb_clk = { + .halt_reg = 0x1d00c, + .clkr = { + .enable_reg = 0x1d00c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_ahb_clk", + .parent_names = (const char *[]){ + "pcnoc_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_axi_m_clk = { + .halt_reg = 0x1d004, + .clkr = { + .enable_reg = 0x1d004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_axi_m_clk", + .parent_names = (const char *[]){ + "fepll200", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_axi_s_clk = { + .halt_reg = 0x1d008, + .clkr = { + .enable_reg = 0x1d008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_axi_s_clk", + .parent_names = (const char *[]){ + "fepll200", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_prng_ahb_clk = { + .halt_reg = 0x13004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x6000, + .enable_mask = BIT(8), + .hw.init = &(struct clk_init_data){ + .name = "gcc_prng_ahb_clk", + .parent_names = (const char *[]){ + "pcnoc_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qpic_ahb_clk = { + .halt_reg = 0x1c008, + .clkr = { + .enable_reg = 0x1c008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qpic_ahb_clk", + .parent_names = (const char *[]){ + "pcnoc_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qpic_clk = { + .halt_reg = 0x1c004, + .clkr = { + .enable_reg = 0x1c004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qpic_clk", + .parent_names = (const char *[]){ + "pcnoc_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_ahb_clk = { + .halt_reg = 0x18010, + .clkr = { + .enable_reg = 0x18010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_ahb_clk", + .parent_names = (const char *[]){ + "pcnoc_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_apps_clk = { + .halt_reg = 0x1800c, + .clkr = { + .enable_reg = 0x1800c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_apps_clk", + .parent_names = (const char *[]){ + "sdcc1_apps_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch gcc_tlmm_ahb_clk = { + .halt_reg = 0x5004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x6000, + .enable_mask = BIT(5), + .hw.init = &(struct clk_init_data){ + .name = "gcc_tlmm_ahb_clk", + .parent_names = (const char *[]){ + "pcnoc_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb2_master_clk = { + .halt_reg = 0x1e00c, + .clkr = { + .enable_reg = 0x1e00c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb2_master_clk", + .parent_names = (const char *[]){ + "pcnoc_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb2_sleep_clk = { + .halt_reg = 0x1e010, + .clkr = { + .enable_reg = 0x1e010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb2_sleep_clk", + .parent_names = (const char *[]){ + "gcc_sleep_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb2_mock_utmi_clk = { + .halt_reg = 0x1e014, + .clkr = { + .enable_reg = 0x1e014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb2_mock_utmi_clk", + .parent_names = (const char *[]){ + "usb30_mock_utmi_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb30_mock_utmi_clk[] = { + F(2000000, FE_PLL_200, 10, 0, 0), + { } +}; + +static struct clk_rcg2 usb30_mock_utmi_clk_src = { + .cmd_rcgr = 0x1e000, + .hid_width = 5, + .parent_map = gcc_xo_200_map, + .freq_tbl = ftbl_gcc_usb30_mock_utmi_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb30_mock_utmi_clk_src", + .parent_names = gcc_xo_200, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_usb3_master_clk = { + .halt_reg = 0x1e028, + .clkr = { + .enable_reg = 0x1e028, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_master_clk", + .parent_names = (const char *[]){ + "fepll125", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_sleep_clk = { + .halt_reg = 0x1e02C, + .clkr = { + .enable_reg = 0x1e02C, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_sleep_clk", + .parent_names = (const char *[]){ + "gcc_sleep_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_mock_utmi_clk = { + .halt_reg = 0x1e030, + .clkr = { + .enable_reg = 0x1e030, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_mock_utmi_clk", + .parent_names = (const char *[]){ + "usb30_mock_utmi_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static const struct freq_tbl ftbl_gcc_fephy_dly_clk[] = { + F(125000000, FE_PLL_125_DLY, 1, 0, 0), + { } +}; + +static struct clk_rcg2 fephy_125m_dly_clk_src = { + .cmd_rcgr = 0x12000, + .hid_width = 5, + .parent_map = gcc_xo_125_dly_map, + .freq_tbl = ftbl_gcc_fephy_dly_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "fephy_125m_dly_clk_src", + .parent_names = gcc_xo_125_dly, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + + +static const struct freq_tbl ftbl_gcc_wcss2g_clk[] = { + F(48000000, P_XO, 1, 0, 0), + F(250000000, FE_PLL_WCSS2G, 1, 0, 0), + { } +}; + +static struct clk_rcg2 wcss2g_clk_src = { + .cmd_rcgr = 0x1f000, + .hid_width = 5, + .freq_tbl = ftbl_gcc_wcss2g_clk, + .parent_map = gcc_xo_wcss2g_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "wcss2g_clk_src", + .parent_names = gcc_xo_wcss2g, + .num_parents = 2, + .ops = &clk_rcg2_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_branch gcc_wcss2g_clk = { + .halt_reg = 0x1f00C, + .clkr = { + .enable_reg = 0x1f00C, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_wcss2g_clk", + .parent_names = (const char *[]){ + "wcss2g_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch gcc_wcss2g_ref_clk = { + .halt_reg = 0x1f00C, + .clkr = { + .enable_reg = 0x1f00C, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_wcss2g_ref_clk", + .parent_names = (const char *[]){ + "xo", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch gcc_wcss2g_rtc_clk = { + .halt_reg = 0x1f010, + .clkr = { + .enable_reg = 0x1f010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_wcss2g_rtc_clk", + .parent_names = (const char *[]){ + "gcc_sleep_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_gcc_wcss5g_clk[] = { + F(48000000, P_XO, 1, 0, 0), + F(250000000, FE_PLL_WCSS5G, 1, 0, 0), + { } +}; + +static struct clk_rcg2 wcss5g_clk_src = { + .cmd_rcgr = 0x20000, + .hid_width = 5, + .parent_map = gcc_xo_wcss5g_map, + .freq_tbl = ftbl_gcc_wcss5g_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "wcss5g_clk_src", + .parent_names = gcc_xo_wcss5g, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_wcss5g_clk = { + .halt_reg = 0x2000c, + .clkr = { + .enable_reg = 0x2000c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_wcss5g_clk", + .parent_names = (const char *[]){ + "wcss5g_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch gcc_wcss5g_ref_clk = { + .halt_reg = 0x2000c, + .clkr = { + .enable_reg = 0x2000c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_wcss5g_ref_clk", + .parent_names = (const char *[]){ + "xo", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch gcc_wcss5g_rtc_clk = { + .halt_reg = 0x20010, + .clkr = { + .enable_reg = 0x20010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_wcss5g_rtc_clk", + .parent_names = (const char *[]){ + "gcc_sleep_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_regmap *gcc_ipq4019_clocks[] = { + [AUDIO_CLK_SRC] = &audio_clk_src.clkr, + [BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr, + [BLSP1_QUP1_SPI_APPS_CLK_SRC] = &blsp1_qup1_spi_apps_clk_src.clkr, + [BLSP1_QUP2_I2C_APPS_CLK_SRC] = &blsp1_qup2_i2c_apps_clk_src.clkr, + [BLSP1_QUP2_SPI_APPS_CLK_SRC] = &blsp1_qup2_spi_apps_clk_src.clkr, + [BLSP1_UART1_APPS_CLK_SRC] = &blsp1_uart1_apps_clk_src.clkr, + [BLSP1_UART2_APPS_CLK_SRC] = &blsp1_uart2_apps_clk_src.clkr, + [GCC_USB3_MOCK_UTMI_CLK_SRC] = &usb30_mock_utmi_clk_src.clkr, + [GCC_APPS_CLK_SRC] = &apps_clk_src.clkr, + [GCC_APPS_AHB_CLK_SRC] = &apps_ahb_clk_src.clkr, + [GP1_CLK_SRC] = &gp1_clk_src.clkr, + [GP2_CLK_SRC] = &gp2_clk_src.clkr, + [GP3_CLK_SRC] = &gp3_clk_src.clkr, + [SDCC1_APPS_CLK_SRC] = &sdcc1_apps_clk_src.clkr, + [FEPHY_125M_DLY_CLK_SRC] = &fephy_125m_dly_clk_src.clkr, + [WCSS2G_CLK_SRC] = &wcss2g_clk_src.clkr, + [WCSS5G_CLK_SRC] = &wcss5g_clk_src.clkr, + [GCC_APSS_AHB_CLK] = &gcc_apss_ahb_clk.clkr, + [GCC_AUDIO_AHB_CLK] = &gcc_audio_ahb_clk.clkr, + [GCC_AUDIO_PWM_CLK] = &gcc_audio_pwm_clk.clkr, + [GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr, + [GCC_BLSP1_QUP1_I2C_APPS_CLK] = &gcc_blsp1_qup1_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP1_SPI_APPS_CLK] = &gcc_blsp1_qup1_spi_apps_clk.clkr, + [GCC_BLSP1_QUP2_I2C_APPS_CLK] = &gcc_blsp1_qup2_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP2_SPI_APPS_CLK] = &gcc_blsp1_qup2_spi_apps_clk.clkr, + [GCC_BLSP1_UART1_APPS_CLK] = &gcc_blsp1_uart1_apps_clk.clkr, + [GCC_BLSP1_UART2_APPS_CLK] = &gcc_blsp1_uart2_apps_clk.clkr, + [GCC_DCD_XO_CLK] = &gcc_dcd_xo_clk.clkr, + [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, + [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, + [GCC_GP3_CLK] = &gcc_gp3_clk.clkr, + [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, + [GCC_CRYPTO_AHB_CLK] = &gcc_crypto_ahb_clk.clkr, + [GCC_CRYPTO_AXI_CLK] = &gcc_crypto_axi_clk.clkr, + [GCC_CRYPTO_CLK] = &gcc_crypto_clk.clkr, + [GCC_ESS_CLK] = &gcc_ess_clk.clkr, + [GCC_IMEM_AXI_CLK] = &gcc_imem_axi_clk.clkr, + [GCC_IMEM_CFG_AHB_CLK] = &gcc_imem_cfg_ahb_clk.clkr, + [GCC_PCIE_AHB_CLK] = &gcc_pcie_ahb_clk.clkr, + [GCC_PCIE_AXI_M_CLK] = &gcc_pcie_axi_m_clk.clkr, + [GCC_PCIE_AXI_S_CLK] = &gcc_pcie_axi_s_clk.clkr, + [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr, + [GCC_QPIC_AHB_CLK] = &gcc_qpic_ahb_clk.clkr, + [GCC_QPIC_CLK] = &gcc_qpic_clk.clkr, + [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr, + [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr, + [GCC_TLMM_AHB_CLK] = &gcc_tlmm_ahb_clk.clkr, + [GCC_USB2_MASTER_CLK] = &gcc_usb2_master_clk.clkr, + [GCC_USB2_SLEEP_CLK] = &gcc_usb2_sleep_clk.clkr, + [GCC_USB2_MOCK_UTMI_CLK] = &gcc_usb2_mock_utmi_clk.clkr, + [GCC_USB3_MASTER_CLK] = &gcc_usb3_master_clk.clkr, + [GCC_USB3_SLEEP_CLK] = &gcc_usb3_sleep_clk.clkr, + [GCC_USB3_MOCK_UTMI_CLK] = &gcc_usb3_mock_utmi_clk.clkr, + [GCC_WCSS2G_CLK] = &gcc_wcss2g_clk.clkr, + [GCC_WCSS2G_REF_CLK] = &gcc_wcss2g_ref_clk.clkr, + [GCC_WCSS2G_RTC_CLK] = &gcc_wcss2g_rtc_clk.clkr, + [GCC_WCSS5G_CLK] = &gcc_wcss5g_clk.clkr, + [GCC_WCSS5G_REF_CLK] = &gcc_wcss5g_ref_clk.clkr, + [GCC_WCSS5G_RTC_CLK] = &gcc_wcss5g_rtc_clk.clkr, +}; + +static const struct qcom_reset_map gcc_ipq4019_resets[] = { + [WIFI0_CPU_INIT_RESET] = { 0x1f008, 5 }, + [WIFI0_RADIO_SRIF_RESET] = { 0x1f008, 4 }, + [WIFI0_RADIO_WARM_RESET] = { 0x1f008, 3 }, + [WIFI0_RADIO_COLD_RESET] = { 0x1f008, 2 }, + [WIFI0_CORE_WARM_RESET] = { 0x1f008, 1 }, + [WIFI0_CORE_COLD_RESET] = { 0x1f008, 0 }, + [WIFI1_CPU_INIT_RESET] = { 0x20008, 5 }, + [WIFI1_RADIO_SRIF_RESET] = { 0x20008, 4 }, + [WIFI1_RADIO_WARM_RESET] = { 0x20008, 3 }, + [WIFI1_RADIO_COLD_RESET] = { 0x20008, 2 }, + [WIFI1_CORE_WARM_RESET] = { 0x20008, 1 }, + [WIFI1_CORE_COLD_RESET] = { 0x20008, 0 }, + [USB3_UNIPHY_PHY_ARES] = { 0x1e038, 5 }, + [USB3_HSPHY_POR_ARES] = { 0x1e038, 4 }, + [USB3_HSPHY_S_ARES] = { 0x1e038, 2 }, + [USB2_HSPHY_POR_ARES] = { 0x1e01c, 4 }, + [USB2_HSPHY_S_ARES] = { 0x1e01c, 2 }, + [PCIE_PHY_AHB_ARES] = { 0x1d010, 11 }, + [PCIE_AHB_ARES] = { 0x1d010, 10 }, + [PCIE_PWR_ARES] = { 0x1d010, 9 }, + [PCIE_PIPE_STICKY_ARES] = { 0x1d010, 8 }, + [PCIE_AXI_M_STICKY_ARES] = { 0x1d010, 7 }, + [PCIE_PHY_ARES] = { 0x1d010, 6 }, + [PCIE_PARF_XPU_ARES] = { 0x1d010, 5 }, + [PCIE_AXI_S_XPU_ARES] = { 0x1d010, 4 }, + [PCIE_AXI_M_VMIDMT_ARES] = { 0x1d010, 3 }, + [PCIE_PIPE_ARES] = { 0x1d010, 2 }, + [PCIE_AXI_S_ARES] = { 0x1d010, 1 }, + [PCIE_AXI_M_ARES] = { 0x1d010, 0 }, + [ESS_RESET] = { 0x12008, 0}, + [GCC_BLSP1_BCR] = {0x01000, 0}, + [GCC_BLSP1_QUP1_BCR] = {0x02000, 0}, + [GCC_BLSP1_UART1_BCR] = {0x02038, 0}, + [GCC_BLSP1_QUP2_BCR] = {0x03008, 0}, + [GCC_BLSP1_UART2_BCR] = {0x03028, 0}, + [GCC_BIMC_BCR] = {0x04000, 0}, + [GCC_TLMM_BCR] = {0x05000, 0}, + [GCC_IMEM_BCR] = {0x0E000, 0}, + [GCC_ESS_BCR] = {0x12008, 0}, + [GCC_PRNG_BCR] = {0x13000, 0}, + [GCC_BOOT_ROM_BCR] = {0x13008, 0}, + [GCC_CRYPTO_BCR] = {0x16000, 0}, + [GCC_SDCC1_BCR] = {0x18000, 0}, + [GCC_SEC_CTRL_BCR] = {0x1A000, 0}, + [GCC_AUDIO_BCR] = {0x1B008, 0}, + [GCC_QPIC_BCR] = {0x1C000, 0}, + [GCC_PCIE_BCR] = {0x1D000, 0}, + [GCC_USB2_BCR] = {0x1E008, 0}, + [GCC_USB2_PHY_BCR] = {0x1E018, 0}, + [GCC_USB3_BCR] = {0x1E024, 0}, + [GCC_USB3_PHY_BCR] = {0x1E034, 0}, + [GCC_SYSTEM_NOC_BCR] = {0x21000, 0}, + [GCC_PCNOC_BCR] = {0x2102C, 0}, + [GCC_DCD_BCR] = {0x21038, 0}, + [GCC_SNOC_BUS_TIMEOUT0_BCR] = {0x21064, 0}, + [GCC_SNOC_BUS_TIMEOUT1_BCR] = {0x2106C, 0}, + [GCC_SNOC_BUS_TIMEOUT2_BCR] = {0x21074, 0}, + [GCC_SNOC_BUS_TIMEOUT3_BCR] = {0x2107C, 0}, + [GCC_PCNOC_BUS_TIMEOUT0_BCR] = {0x21084, 0}, + [GCC_PCNOC_BUS_TIMEOUT1_BCR] = {0x2108C, 0}, + [GCC_PCNOC_BUS_TIMEOUT2_BCR] = {0x21094, 0}, + [GCC_PCNOC_BUS_TIMEOUT3_BCR] = {0x2109C, 0}, + [GCC_PCNOC_BUS_TIMEOUT4_BCR] = {0x210A4, 0}, + [GCC_PCNOC_BUS_TIMEOUT5_BCR] = {0x210AC, 0}, + [GCC_PCNOC_BUS_TIMEOUT6_BCR] = {0x210B4, 0}, + [GCC_PCNOC_BUS_TIMEOUT7_BCR] = {0x210BC, 0}, + [GCC_PCNOC_BUS_TIMEOUT8_BCR] = {0x210C4, 0}, + [GCC_PCNOC_BUS_TIMEOUT9_BCR] = {0x210CC, 0}, + [GCC_TCSR_BCR] = {0x22000, 0}, + [GCC_MPM_BCR] = {0x24000, 0}, + [GCC_SPDM_BCR] = {0x25000, 0}, +}; + +static const struct regmap_config gcc_ipq4019_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x2dfff, + .fast_io = true, +}; + +static const struct qcom_cc_desc gcc_ipq4019_desc = { + .config = &gcc_ipq4019_regmap_config, + .clks = gcc_ipq4019_clocks, + .num_clks = ARRAY_SIZE(gcc_ipq4019_clocks), + .resets = gcc_ipq4019_resets, + .num_resets = ARRAY_SIZE(gcc_ipq4019_resets), +}; + +static const struct of_device_id gcc_ipq4019_match_table[] = { + { .compatible = "qcom,gcc-ipq4019" }, + { } +}; +MODULE_DEVICE_TABLE(of, gcc_ipq4019_match_table); + +static int gcc_ipq4019_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &gcc_ipq4019_desc); +} + +static struct platform_driver gcc_ipq4019_driver = { + .probe = gcc_ipq4019_probe, + .driver = { + .name = "qcom,gcc-ipq4019", + .owner = THIS_MODULE, + .of_match_table = gcc_ipq4019_match_table, + }, +}; + +static int __init gcc_ipq4019_init(void) +{ + return platform_driver_register(&gcc_ipq4019_driver); +} +core_initcall(gcc_ipq4019_init); + +static void __exit gcc_ipq4019_exit(void) +{ + platform_driver_unregister(&gcc_ipq4019_driver); +} +module_exit(gcc_ipq4019_exit); + +MODULE_ALIAS("platform:gcc-ipq4019"); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("QCOM GCC IPQ4019 driver"); diff --git a/include/dt-bindings/clock/qcom,gcc-ipq4019.h b/include/dt-bindings/clock/qcom,gcc-ipq4019.h new file mode 100644 index 0000000..6240e5b --- /dev/null +++ b/include/dt-bindings/clock/qcom,gcc-ipq4019.h @@ -0,0 +1,158 @@ +/* Copyright (c) 2015 The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ +#ifndef __QCOM_CLK_IPQ4019_H__ +#define __QCOM_CLK_IPQ4019_H__ + +#define GCC_DUMMY_CLK 0 +#define AUDIO_CLK_SRC 1 +#define BLSP1_QUP1_I2C_APPS_CLK_SRC 2 +#define BLSP1_QUP1_SPI_APPS_CLK_SRC 3 +#define BLSP1_QUP2_I2C_APPS_CLK_SRC 4 +#define BLSP1_QUP2_SPI_APPS_CLK_SRC 5 +#define BLSP1_UART1_APPS_CLK_SRC 6 +#define BLSP1_UART2_APPS_CLK_SRC 7 +#define GCC_USB3_MOCK_UTMI_CLK_SRC 8 +#define GCC_APPS_CLK_SRC 9 +#define GCC_APPS_AHB_CLK_SRC 10 +#define GP1_CLK_SRC 11 +#define GP2_CLK_SRC 12 +#define GP3_CLK_SRC 13 +#define SDCC1_APPS_CLK_SRC 14 +#define FEPHY_125M_DLY_CLK_SRC 15 +#define WCSS2G_CLK_SRC 16 +#define WCSS5G_CLK_SRC 17 +#define GCC_APSS_AHB_CLK 18 +#define GCC_AUDIO_AHB_CLK 19 +#define GCC_AUDIO_PWM_CLK 20 +#define GCC_BLSP1_AHB_CLK 21 +#define GCC_BLSP1_QUP1_I2C_APPS_CLK 22 +#define GCC_BLSP1_QUP1_SPI_APPS_CLK 23 +#define GCC_BLSP1_QUP2_I2C_APPS_CLK 24 +#define GCC_BLSP1_QUP2_SPI_APPS_CLK 25 +#define GCC_BLSP1_UART1_APPS_CLK 26 +#define GCC_BLSP1_UART2_APPS_CLK 27 +#define GCC_DCD_XO_CLK 28 +#define GCC_GP1_CLK 29 +#define GCC_GP2_CLK 30 +#define GCC_GP3_CLK 31 +#define GCC_BOOT_ROM_AHB_CLK 32 +#define GCC_CRYPTO_AHB_CLK 33 +#define GCC_CRYPTO_AXI_CLK 34 +#define GCC_CRYPTO_CLK 35 +#define GCC_ESS_CLK 36 +#define GCC_IMEM_AXI_CLK 37 +#define GCC_IMEM_CFG_AHB_CLK 38 +#define GCC_PCIE_AHB_CLK 39 +#define GCC_PCIE_AXI_M_CLK 40 +#define GCC_PCIE_AXI_S_CLK 41 +#define GCC_PCNOC_AHB_CLK 42 +#define GCC_PRNG_AHB_CLK 43 +#define GCC_QPIC_AHB_CLK 44 +#define GCC_QPIC_CLK 45 +#define GCC_SDCC1_AHB_CLK 46 +#define GCC_SDCC1_APPS_CLK 47 +#define GCC_SNOC_PCNOC_AHB_CLK 48 +#define GCC_SYS_NOC_125M_CLK 49 +#define GCC_SYS_NOC_AXI_CLK 50 +#define GCC_TCSR_AHB_CLK 51 +#define GCC_TLMM_AHB_CLK 52 +#define GCC_USB2_MASTER_CLK 53 +#define GCC_USB2_SLEEP_CLK 54 +#define GCC_USB2_MOCK_UTMI_CLK 55 +#define GCC_USB3_MASTER_CLK 56 +#define GCC_USB3_SLEEP_CLK 57 +#define GCC_USB3_MOCK_UTMI_CLK 58 +#define GCC_WCSS2G_CLK 59 +#define GCC_WCSS2G_REF_CLK 60 +#define GCC_WCSS2G_RTC_CLK 61 +#define GCC_WCSS5G_CLK 62 +#define GCC_WCSS5G_REF_CLK 63 +#define GCC_WCSS5G_RTC_CLK 64 + +#define WIFI0_CPU_INIT_RESET 0 +#define WIFI0_RADIO_SRIF_RESET 1 +#define WIFI0_RADIO_WARM_RESET 2 +#define WIFI0_RADIO_COLD_RESET 3 +#define WIFI0_CORE_WARM_RESET 4 +#define WIFI0_CORE_COLD_RESET 5 +#define WIFI1_CPU_INIT_RESET 6 +#define WIFI1_RADIO_SRIF_RESET 7 +#define WIFI1_RADIO_WARM_RESET 8 +#define WIFI1_RADIO_COLD_RESET 9 +#define WIFI1_CORE_WARM_RESET 10 +#define WIFI1_CORE_COLD_RESET 11 +#define USB3_UNIPHY_PHY_ARES 12 +#define USB3_HSPHY_POR_ARES 13 +#define USB3_HSPHY_S_ARES 14 +#define USB2_HSPHY_POR_ARES 15 +#define USB2_HSPHY_S_ARES 16 +#define PCIE_PHY_AHB_ARES 17 +#define PCIE_AHB_ARES 18 +#define PCIE_PWR_ARES 19 +#define PCIE_PIPE_STICKY_ARES 20 +#define PCIE_AXI_M_STICKY_ARES 21 +#define PCIE_PHY_ARES 22 +#define PCIE_PARF_XPU_ARES 23 +#define PCIE_AXI_S_XPU_ARES 24 +#define PCIE_AXI_M_VMIDMT_ARES 25 +#define PCIE_PIPE_ARES 26 +#define PCIE_AXI_S_ARES 27 +#define PCIE_AXI_M_ARES 28 +#define ESS_RESET 29 +#define GCC_BLSP1_BCR 30 +#define GCC_BLSP1_QUP1_BCR 31 +#define GCC_BLSP1_UART1_BCR 32 +#define GCC_BLSP1_QUP2_BCR 33 +#define GCC_BLSP1_UART2_BCR 34 +#define GCC_BIMC_BCR 35 +#define GCC_TLMM_BCR 36 +#define GCC_IMEM_BCR 37 +#define GCC_ESS_BCR 38 +#define GCC_PRNG_BCR 39 +#define GCC_BOOT_ROM_BCR 40 +#define GCC_CRYPTO_BCR 41 +#define GCC_SDCC1_BCR 42 +#define GCC_SEC_CTRL_BCR 43 +#define GCC_AUDIO_BCR 44 +#define GCC_QPIC_BCR 45 +#define GCC_PCIE_BCR 46 +#define GCC_USB2_BCR 47 +#define GCC_USB2_PHY_BCR 48 +#define GCC_USB3_BCR 49 +#define GCC_USB3_PHY_BCR 50 +#define GCC_SYSTEM_NOC_BCR 51 +#define GCC_PCNOC_BCR 52 +#define GCC_DCD_BCR 53 +#define GCC_SNOC_BUS_TIMEOUT0_BCR 54 +#define GCC_SNOC_BUS_TIMEOUT1_BCR 55 +#define GCC_SNOC_BUS_TIMEOUT2_BCR 56 +#define GCC_SNOC_BUS_TIMEOUT3_BCR 57 +#define GCC_PCNOC_BUS_TIMEOUT0_BCR 58 +#define GCC_PCNOC_BUS_TIMEOUT1_BCR 59 +#define GCC_PCNOC_BUS_TIMEOUT2_BCR 60 +#define GCC_PCNOC_BUS_TIMEOUT3_BCR 61 +#define GCC_PCNOC_BUS_TIMEOUT4_BCR 62 +#define GCC_PCNOC_BUS_TIMEOUT5_BCR 63 +#define GCC_PCNOC_BUS_TIMEOUT6_BCR 64 +#define GCC_PCNOC_BUS_TIMEOUT7_BCR 65 +#define GCC_PCNOC_BUS_TIMEOUT8_BCR 66 +#define GCC_PCNOC_BUS_TIMEOUT9_BCR 67 +#define GCC_TCSR_BCR 68 +#define GCC_QDSS_BCR 69 +#define GCC_MPM_BCR 70 +#define GCC_SPDM_BCR 71 + +#endif -- cgit v0.10.2 From 2da5f5db39010da29efded0f3cf1b7799564d63c Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Wed, 27 Jan 2016 14:17:00 -0800 Subject: clk: Get rid of HAVE_MACH_CLKDEV This config was used for the ARM port so that it could use a machine specific clkdev.h include, but those are all gone now. The MIPS architecture is the last user, and from what I can tell it doesn't actually use it anyway, so let's remove the config all together. Cc: Ralf Baechle Cc: Signed-off-by: Stephen Boyd Reviewed-by: Joshua Henderson diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 57a945e..0d5d785 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -327,7 +327,6 @@ config LANTIQ select ARCH_REQUIRE_GPIOLIB select SWAP_IO_SPACE select BOOT_RAW - select HAVE_MACH_CLKDEV select CLKDEV_LOOKUP select USE_OF select PINCTRL @@ -589,7 +588,6 @@ config RALINK select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_SUPPORTS_MIPS16 select SYS_HAS_EARLY_PRINTK - select HAVE_MACH_CLKDEV select CLKDEV_LOOKUP select ARCH_HAS_RESET_CONTROLLER select RESET_CONTROLLER diff --git a/arch/mips/pic32/Kconfig b/arch/mips/pic32/Kconfig index fde56a8..1985971 100644 --- a/arch/mips/pic32/Kconfig +++ b/arch/mips/pic32/Kconfig @@ -15,7 +15,6 @@ config PIC32MZDA select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN select ARCH_REQUIRE_GPIOLIB - select HAVE_MACH_CLKDEV select COMMON_CLK select CLKDEV_LOOKUP select LIBFDT diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index a8c2c88..15f548a 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -6,9 +6,6 @@ config CLKDEV_LOOKUP config HAVE_CLK_PREPARE bool -config HAVE_MACH_CLKDEV - bool - config COMMON_CLK bool select HAVE_CLK_PREPARE -- cgit v0.10.2 From ec7957a6aa0aaf981fb8356dc47a2cdd01cde03c Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 24 Feb 2016 09:39:11 +0100 Subject: clk: versatile: sp810: support reentrance Despite care take to allocate clocks state containers the SP810 driver actually just supports creating one instance: all clocks registered for every instance will end up with the exact same name and __clk_init() will fail. Rename the timclken<0> .. timclken to sp810__ so every clock on every instance gets a unique name. This is necessary for the RealView PBA8 which has two SP810 blocks: the second block will not register its clocks unless every clock on every instance is unique and results in boot logs like this: ------------[ cut here ]------------ WARNING: CPU: 0 PID: 0 at ../drivers/clk/versatile/clk-sp810.c:137 clk_sp810_of_setup+0x110/0x154() Modules linked in: CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.5.0-rc2-00030-g352718fc39f6-dirty #225 Hardware name: ARM RealView Machine (Device Tree Support) [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [] (show_stack) from [] (dump_stack+0x84/0x9c) [] (dump_stack) from [] (warn_slowpath_common+0x74/0xb0) [] (warn_slowpath_common) from [] (warn_slowpath_null+0x1c/0x24) [] (warn_slowpath_null) from [] (clk_sp810_of_setup+0x110/0x154) [] (clk_sp810_of_setup) from [] (of_clk_init+0x12c/0x1c8) [] (of_clk_init) from [] (time_init+0x20/0x2c) [] (time_init) from [] (start_kernel+0x244/0x3c4) [] (start_kernel) from [<7000807c>] (0x7000807c) ---[ end trace cb88537fdc8fa200 ]--- Cc: Michael Turquette Cc: Pawel Moll Fixes: 6e973d2c4385 "clk: vexpress: Add separate SP810 driver" Signed-off-by: Linus Walleij Signed-off-by: Stephen Boyd diff --git a/drivers/clk/versatile/clk-sp810.c b/drivers/clk/versatile/clk-sp810.c index e78755e..1fe1e8d 100644 --- a/drivers/clk/versatile/clk-sp810.c +++ b/drivers/clk/versatile/clk-sp810.c @@ -92,6 +92,7 @@ static void __init clk_sp810_of_setup(struct device_node *node) int num = ARRAY_SIZE(parent_names); char name[12]; struct clk_init_data init; + static int instance; int i; bool deprecated; @@ -117,7 +118,7 @@ static void __init clk_sp810_of_setup(struct device_node *node) deprecated = !of_find_property(node, "assigned-clock-parents", NULL); for (i = 0; i < ARRAY_SIZE(sp810->timerclken); i++) { - snprintf(name, ARRAY_SIZE(name), "timerclken%d", i); + snprintf(name, sizeof(name), "sp810_%d_%d", instance, i); sp810->timerclken[i].sp810 = sp810; sp810->timerclken[i].channel = i; @@ -138,5 +139,6 @@ static void __init clk_sp810_of_setup(struct device_node *node) } of_clk_add_provider(node, clk_sp810_timerclken_of_get, sp810); + instance++; } CLK_OF_DECLARE(sp810, "arm,sp810", clk_sp810_of_setup); -- cgit v0.10.2 From bd3677ff31a3e9530219da02f6de147ae5f61861 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Thu, 11 Feb 2016 16:53:52 +0000 Subject: clk: mvebu: Remove corediv clock from Armada XP There is no corediv clock on Armada XP, so this is unnecessary. Signed-off-by: Kevin Smith Acked-by: Michael Turquette Acked-by: Gregory CLEMENT Cc: Thomas Petazzoni Signed-off-by: Stephen Boyd diff --git a/drivers/clk/mvebu/Kconfig b/drivers/clk/mvebu/Kconfig index 2769625..e1bc567 100644 --- a/drivers/clk/mvebu/Kconfig +++ b/drivers/clk/mvebu/Kconfig @@ -29,7 +29,6 @@ config ARMADA_XP_CLK bool select MVEBU_CLK_COMMON select MVEBU_CLK_CPU - select MVEBU_CLK_COREDIV config DOVE_CLK bool -- cgit v0.10.2 From 1594d568c6e32f10b00ac2a23c6d506a66a09607 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Thu, 11 Feb 2016 16:54:00 +0000 Subject: clk: mvebu: Move corediv config to mvebu config The core clock does not depend on corediv, so enabling corediv based on the clock is not really correct. Move the corediv config option from the clock driver Kconfig to the mvebu Kconfig so that it can be enabled by the MACH option instead. This also enables corediv on Armada 375 and 38X, which was previously missing. Signed-off-by: Kevin Smith Cc: Michael Turquette Cc: Stephen Boyd Cc: Gregory CLEMENT Cc: Thomas Petazzoni Signed-off-by: Stephen Boyd diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index 64e3d2c..71e97da 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -32,6 +32,7 @@ config MACH_ARMADA_370 select CPU_PJ4B select MACH_MVEBU_V7 select PINCTRL_ARMADA_370 + select MVEBU_CLK_COREDIV help Say 'Y' here if you want your kernel to support boards based on the Marvell Armada 370 SoC with device tree. @@ -48,6 +49,7 @@ config MACH_ARMADA_375 select HAVE_SMP select MACH_MVEBU_V7 select PINCTRL_ARMADA_375 + select MVEBU_CLK_COREDIV help Say 'Y' here if you want your kernel to support boards based on the Marvell Armada 375 SoC with device tree. @@ -64,6 +66,7 @@ config MACH_ARMADA_38X select HAVE_SMP select MACH_MVEBU_V7 select PINCTRL_ARMADA_38X + select MVEBU_CLK_COREDIV help Say 'Y' here if you want your kernel to support boards based on the Marvell Armada 380/385 SoC with device tree. diff --git a/drivers/clk/mvebu/Kconfig b/drivers/clk/mvebu/Kconfig index e1bc567..eaee8f0 100644 --- a/drivers/clk/mvebu/Kconfig +++ b/drivers/clk/mvebu/Kconfig @@ -11,7 +11,6 @@ config ARMADA_370_CLK bool select MVEBU_CLK_COMMON select MVEBU_CLK_CPU - select MVEBU_CLK_COREDIV config ARMADA_375_CLK bool -- cgit v0.10.2 From 57130e643489615a807b2dc9c58b7a4efe24d302 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Tue, 23 Feb 2016 09:57:31 +0900 Subject: clk: shmobile: Remove ARCH_SHMOBILE_MULTI As of 9b5ba0df4ea4 ("ARM: shmobile: Introduce ARCH_RENESAS") all platforms that use Renesas clock drivers now select ARCH_RENESAS. As it is present in drivers/clk/Makefile ARCH_SHMOBILE_MULTI may now be removed. This is part of an ongoing process to migrate from ARCH_SHMOBILE to ARCH_RENESAS the motivation for which being that RENESAS seems to be a more appropriate name than SHMOBILE for the majority of Renesas ARM based SoCs. Signed-off-by: Simon Horman Acked-by: Geert Uytterhoeven Signed-off-by: Stephen Boyd diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index bae4be6..b19af44 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -70,7 +70,6 @@ obj-$(CONFIG_COMMON_CLK_PXA) += pxa/ obj-$(CONFIG_COMMON_CLK_QCOM) += qcom/ obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ obj-$(CONFIG_COMMON_CLK_SAMSUNG) += samsung/ -obj-$(CONFIG_ARCH_SHMOBILE_MULTI) += shmobile/ obj-$(CONFIG_ARCH_RENESAS) += shmobile/ obj-$(CONFIG_ARCH_SIRF) += sirf/ obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/ -- cgit v0.10.2 From 2103a2156119b30f5924af2a1094227954be4617 Mon Sep 17 00:00:00 2001 From: Martin Sperl Date: Tue, 22 Dec 2015 20:13:08 +0000 Subject: clk: bcm2835: added missing clock register definitions Added missing CTRL and DIV clock register definitions for: PCM, SLIM, TCNT, TEC, TD0, TD1 Register information taken from: https://rawgit.com/msperl/rpi-registers/master/rpi-registers.html#CM which extracted the information from the header files shared by Broadcom/rpi foundation in this file: http://www.broadcom.com/docs/support/videocore/Brcm_Android_ICS_Graphics_Stack.tar.gz Signed-off-by: Martin Sperl Reviewed-by: Eric Anholt Signed-off-by: Stephen Boyd diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 353e438..5747a9d 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -88,10 +88,23 @@ #define CM_HSMDIV 0x08c #define CM_OTPCTL 0x090 #define CM_OTPDIV 0x094 +#define CM_PCMCTL 0x098 +#define CM_PCMDIV 0x09c #define CM_PWMCTL 0x0a0 #define CM_PWMDIV 0x0a4 +#define CM_SLIMCTL 0x0a8 +#define CM_SLIMDIV 0x0ac #define CM_SMICTL 0x0b0 #define CM_SMIDIV 0x0b4 +/* no definition for 0x0b8 and 0x0bc */ +#define CM_TCNTCTL 0x0c0 +#define CM_TCNTDIV 0x0c4 +#define CM_TECCTL 0x0c8 +#define CM_TECDIV 0x0cc +#define CM_TD0CTL 0x0d0 +#define CM_TD0DIV 0x0d4 +#define CM_TD1CTL 0x0d8 +#define CM_TD1DIV 0x0dc #define CM_TSENSCTL 0x0e0 #define CM_TSENSDIV 0x0e4 #define CM_TIMERCTL 0x0e8 -- cgit v0.10.2 From 3629e70b8c78ec7a40d5c4fd1356b9dc1937d326 Mon Sep 17 00:00:00 2001 From: Caesar Wang Date: Mon, 15 Feb 2016 15:33:26 +0800 Subject: clk: rockchip: add id of the tsadc clock found on rk3228 SoCs This patch adds 'SCLK_TSADC' and 'PCLK_TSADC' id found on rk3228 SoCs. That will be needed by TSADC controller. Signed-off-by: Caesar Wang Acked-by: Michael Turquette Signed-off-by: Heiko Stuebner diff --git a/include/dt-bindings/clock/rk3228-cru.h b/include/dt-bindings/clock/rk3228-cru.h index a78dd89..cd2e06b 100644 --- a/include/dt-bindings/clock/rk3228-cru.h +++ b/include/dt-bindings/clock/rk3228-cru.h @@ -29,6 +29,7 @@ #define SCLK_SDMMC 68 #define SCLK_SDIO 69 #define SCLK_EMMC 71 +#define SCLK_TSADC 72 #define SCLK_UART0 77 #define SCLK_UART1 78 #define SCLK_UART2 79 @@ -68,6 +69,7 @@ #define PCLK_UART0 341 #define PCLK_UART1 342 #define PCLK_UART2 343 +#define PCLK_TSADC 344 #define PCLK_PWM 350 #define PCLK_TIMER 353 #define PCLK_PERI 363 -- cgit v0.10.2 From 31b1fed36eb56ae8bd25af42ad1625c4110615eb Mon Sep 17 00:00:00 2001 From: Yakir Yang Date: Wed, 24 Feb 2016 18:08:20 +0800 Subject: clk: rockchip: add the new clock ids for RK3228 VOP There are four clocks that vop module would need to operate: DCLK_VOP, HCLK_VOP, SCLK_VOP, ACLK_VOP, Signed-off-by: Yakir Yang Signed-off-by: Heiko Stuebner diff --git a/include/dt-bindings/clock/rk3228-cru.h b/include/dt-bindings/clock/rk3228-cru.h index cd2e06b..9ce3da8 100644 --- a/include/dt-bindings/clock/rk3228-cru.h +++ b/include/dt-bindings/clock/rk3228-cru.h @@ -50,10 +50,15 @@ #define SCLK_SDMMC_SAMPLE 118 #define SCLK_SDIO_SAMPLE 119 #define SCLK_EMMC_SAMPLE 121 +#define SCLK_VOP 122 + +/* dclk gates */ +#define DCLK_VOP 190 /* aclk gates */ #define ACLK_DMAC 194 #define ACLK_PERI 210 +#define ACLK_VOP 211 /* pclk gates */ #define PCLK_GPIO0 320 @@ -75,6 +80,7 @@ #define PCLK_PERI 363 /* hclk gates */ +#define HCLK_VOP 452 #define HCLK_NANDC 453 #define HCLK_SDMMC 456 #define HCLK_SDIO 457 -- cgit v0.10.2 From 2d2671ea4b35454b30a69744ce258489920e4d2b Mon Sep 17 00:00:00 2001 From: Yakir Yang Date: Wed, 24 Feb 2016 18:14:25 +0800 Subject: clk: rockchip: add the new clock ids for RK3228 HDMI Signed-off-by: Yakir Yang Signed-off-by: Heiko Stuebner diff --git a/include/dt-bindings/clock/rk3228-cru.h b/include/dt-bindings/clock/rk3228-cru.h index 9ce3da8..5d43ed9 100644 --- a/include/dt-bindings/clock/rk3228-cru.h +++ b/include/dt-bindings/clock/rk3228-cru.h @@ -51,9 +51,11 @@ #define SCLK_SDIO_SAMPLE 119 #define SCLK_EMMC_SAMPLE 121 #define SCLK_VOP 122 +#define SCLK_HDMI_HDCP 123 /* dclk gates */ #define DCLK_VOP 190 +#define DCLK_HDMI_PHY 191 /* aclk gates */ #define ACLK_DMAC 194 @@ -78,6 +80,8 @@ #define PCLK_PWM 350 #define PCLK_TIMER 353 #define PCLK_PERI 363 +#define PCLK_HDMI_CTRL 364 +#define PCLK_HDMI_PHY 365 /* hclk gates */ #define HCLK_VOP 452 -- cgit v0.10.2 From a3cb9aa4bad3392e23c48e186714a1c96c7d0d6b Mon Sep 17 00:00:00 2001 From: Caesar Wang Date: Mon, 15 Feb 2016 15:33:27 +0800 Subject: clk: rockchip: add the tsadc clocks found on rk3228 SoCs This patch adds the needed clocks for rk3228 tsadc. Signed-off-by: Caesar Wang Acked-by: Michael Turquette Signed-off-by: Heiko Stuebner diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c index c515915..ac014b9 100644 --- a/drivers/clk/rockchip/clk-rk3228.c +++ b/drivers/clk/rockchip/clk-rk3228.c @@ -424,7 +424,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { GATE(0, "sclk_otgphy1", "xin24m", 0, RK2928_CLKGATE_CON(1), 6, GFLAGS), - COMPOSITE_NOMUX(0, "sclk_tsadc", "xin24m", 0, + COMPOSITE_NOMUX(SCLK_TSADC, "sclk_tsadc", "xin24m", 0, RK2928_CLKSEL_CON(24), 6, 10, DFLAGS, RK2928_CLKGATE_CON(2), 8, GFLAGS), @@ -584,7 +584,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { GATE(PCLK_UART0, "pclk_uart0", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 12, GFLAGS), GATE(PCLK_UART1, "pclk_uart1", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 13, GFLAGS), GATE(PCLK_UART2, "pclk_uart2", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 14, GFLAGS), - GATE(0, "pclk_tsadc", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 15, GFLAGS), + GATE(PCLK_TSADC, "pclk_tsadc", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 15, GFLAGS), GATE(PCLK_GRF, "pclk_grf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(10), 0, GFLAGS), GATE(0, "pclk_cru", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(10), 1, GFLAGS), GATE(0, "pclk_sgrf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(10), 2, GFLAGS), -- cgit v0.10.2 From 0a9d4ac08ebc6bddc97228600c4d7e247d9d7a36 Mon Sep 17 00:00:00 2001 From: Yakir Yang Date: Wed, 24 Feb 2016 18:54:18 +0800 Subject: clk: rockchip: set the clock ids for RK3228 VOP Signed-off-by: Yakir Yang Signed-off-by: Heiko Stuebner diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c index ac014b9..01dcb4c 100644 --- a/drivers/clk/rockchip/clk-rk3228.c +++ b/drivers/clk/rockchip/clk-rk3228.c @@ -368,7 +368,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { RK2928_CLKSEL_CON(29), 0, 3, DFLAGS), DIV(0, "sclk_vop_pre", "sclk_vop_src", 0, RK2928_CLKSEL_CON(27), 8, 8, DFLAGS), - MUX(0, "dclk_vop", mux_dclk_vop_p, 0, + MUX(DCLK_VOP, "dclk_vop", mux_dclk_vop_p, 0, RK2928_CLKSEL_CON(27), 1, 1, MFLAGS), FACTOR(0, "xin12m", "xin24m", 0, 1, 2), @@ -505,7 +505,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { GATE(0, "aclk_iep", "aclk_iep_pre", 0, RK2928_CLKGATE_CON(13), 2, GFLAGS), GATE(0, "aclk_iep_noc", "aclk_iep_pre", 0, RK2928_CLKGATE_CON(13), 9, GFLAGS), - GATE(0, "aclk_vop", "aclk_vop_pre", 0, RK2928_CLKGATE_CON(13), 5, GFLAGS), + GATE(ACLK_VOP, "aclk_vop", "aclk_vop_pre", 0, RK2928_CLKGATE_CON(13), 5, GFLAGS), GATE(0, "aclk_vop_noc", "aclk_vop_pre", 0, RK2928_CLKGATE_CON(13), 12, GFLAGS), GATE(0, "aclk_hdcp", "aclk_hdcp_pre", 0, RK2928_CLKGATE_CON(14), 10, GFLAGS), @@ -513,7 +513,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { GATE(0, "hclk_rga", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 1, GFLAGS), GATE(0, "hclk_iep", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 3, GFLAGS), - GATE(0, "hclk_vop", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 6, GFLAGS), + GATE(HCLK_VOP, "hclk_vop", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 6, GFLAGS), GATE(0, "hclk_vio_ahb_arbi", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 7, GFLAGS), GATE(0, "hclk_vio_noc", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 8, GFLAGS), GATE(0, "hclk_vop_noc", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 13, GFLAGS), -- cgit v0.10.2 From bdc7deec2fe86555ab0039ba52bcf35721dc1577 Mon Sep 17 00:00:00 2001 From: Yakir Yang Date: Wed, 24 Feb 2016 18:16:28 +0800 Subject: clk: rockchip: set the clock ids for RK3228 HDMI Signed-off-by: Yakir Yang Signed-off-by: Heiko Stuebner diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c index 01dcb4c..7702d28 100644 --- a/drivers/clk/rockchip/clk-rk3228.c +++ b/drivers/clk/rockchip/clk-rk3228.c @@ -285,7 +285,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { RK2928_CLKSEL_CON(23), 14, 2, MFLAGS, 8, 6, DFLAGS, RK2928_CLKGATE_CON(3), 5, GFLAGS), - GATE(0, "sclk_hdmi_hdcp", "xin24m", 0, + GATE(SCLK_HDMI_HDCP, "sclk_hdmi_hdcp", "xin24m", 0, RK2928_CLKGATE_CON(3), 7, GFLAGS), COMPOSITE(0, "sclk_hdmi_cec", mux_sclk_hdmi_cec_p, 0, @@ -364,7 +364,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { RK2928_CLKGATE_CON(3), 1, GFLAGS), MUX(0, "sclk_vop_src", mux_sclk_vop_src_p, 0, RK2928_CLKSEL_CON(27), 0, 1, MFLAGS), - DIV(0, "dclk_hdmiphy", "sclk_vop_src", 0, + DIV(DCLK_HDMI_PHY, "dclk_hdmiphy", "sclk_vop_src", 0, RK2928_CLKSEL_CON(29), 0, 3, DFLAGS), DIV(0, "sclk_vop_pre", "sclk_vop_src", 0, RK2928_CLKSEL_CON(27), 8, 8, DFLAGS), @@ -519,7 +519,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { GATE(0, "hclk_vop_noc", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 13, GFLAGS), GATE(0, "hclk_vio_h2p", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 7, GFLAGS), GATE(0, "hclk_hdcp_mmu", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 12, GFLAGS), - GATE(0, "pclk_hdmi_ctrl", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 6, GFLAGS), + GATE(PCLK_HDMI_CTRL, "pclk_hdmi_ctrl", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 6, GFLAGS), GATE(0, "pclk_vio_h2p", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 8, GFLAGS), GATE(0, "pclk_hdcp", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 11, GFLAGS), @@ -592,7 +592,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { GATE(0, "pclk_ddrphy", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 3, GFLAGS), GATE(0, "pclk_acodecphy", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 5, GFLAGS), - GATE(0, "pclk_hdmiphy", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 7, GFLAGS), + GATE(PCLK_HDMI_PHY, "pclk_hdmiphy", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 7, GFLAGS), GATE(0, "pclk_vdacphy", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 8, GFLAGS), GATE(0, "pclk_phy_noc", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 9, GFLAGS), -- cgit v0.10.2 From 7af8a26ce7055dd74853ea7c2b9752961e3491da Mon Sep 17 00:00:00 2001 From: Elaine Zhang Date: Wed, 24 Feb 2016 08:44:11 +0800 Subject: clk: rockchip: include downstream muxes into fractional dividers on rk3368 During the initial conversion to the newly introduced combined fractional dividers+muxes the rk3368 clocks were left out, so convert them now. Signed-off-by: Elaine Zhang Signed-off-by: Heiko Stuebner diff --git a/drivers/clk/rockchip/clk-rk3368.c b/drivers/clk/rockchip/clk-rk3368.c index 31facd8..3cc0368 100644 --- a/drivers/clk/rockchip/clk-rk3368.c +++ b/drivers/clk/rockchip/clk-rk3368.c @@ -243,6 +243,34 @@ static struct rockchip_cpuclk_rate_table rk3368_cpuclkl_rates[] __initdata = { RK3368_CPUCLKL_RATE( 312000000, 1, 1, 1), }; +static struct rockchip_clk_branch rk3368_i2s_8ch_fracmux __initdata = + MUX(0, "i2s_8ch_pre", mux_i2s_8ch_pre_p, CLK_SET_RATE_PARENT, + RK3368_CLKSEL_CON(27), 8, 2, MFLAGS); + +static struct rockchip_clk_branch rk3368_spdif_8ch_fracmux __initdata = + MUX(0, "spdif_8ch_pre", mux_spdif_8ch_p, CLK_SET_RATE_PARENT, + RK3368_CLKSEL_CON(31), 8, 2, MFLAGS); + +static struct rockchip_clk_branch rk3368_i2s_2ch_fracmux __initdata = + MUX(0, "i2s_2ch_pre", mux_i2s_2ch_p, CLK_SET_RATE_PARENT, + RK3368_CLKSEL_CON(53), 8, 2, MFLAGS); + +static struct rockchip_clk_branch rk3368_uart0_fracmux __initdata = + MUX(SCLK_UART0, "sclk_uart0", mux_uart0_p, CLK_SET_RATE_PARENT, + RK3368_CLKSEL_CON(33), 8, 2, MFLAGS); + +static struct rockchip_clk_branch rk3368_uart1_fracmux __initdata = + MUX(SCLK_UART1, "sclk_uart1", mux_uart1_p, CLK_SET_RATE_PARENT, + RK3368_CLKSEL_CON(35), 8, 2, MFLAGS); + +static struct rockchip_clk_branch rk3368_uart3_fracmux __initdata = + MUX(SCLK_UART3, "sclk_uart3", mux_uart3_p, CLK_SET_RATE_PARENT, + RK3368_CLKSEL_CON(39), 8, 2, MFLAGS); + +static struct rockchip_clk_branch rk3368_uart4_fracmux __initdata = + MUX(SCLK_UART4, "sclk_uart4", mux_uart4_p, CLK_SET_RATE_PARENT, + RK3368_CLKSEL_CON(41), 8, 2, MFLAGS); + static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { /* * Clock-Architecture Diagram 2 @@ -339,11 +367,10 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { COMPOSITE(0, "i2s_8ch_src", mux_pll_src_cpll_gpll_p, 0, RK3368_CLKSEL_CON(27), 12, 1, MFLAGS, 0, 7, DFLAGS, RK3368_CLKGATE_CON(6), 1, GFLAGS), - COMPOSITE_FRAC(0, "i2s_8ch_frac", "i2s_8ch_src", CLK_SET_RATE_PARENT, - RK3368_CLKSEL_CON(28), 0, - RK3368_CLKGATE_CON(6), 2, GFLAGS), - MUX(0, "i2s_8ch_pre", mux_i2s_8ch_pre_p, CLK_SET_RATE_PARENT, - RK3368_CLKSEL_CON(27), 8, 2, MFLAGS), + COMPOSITE_FRACMUX(0, "i2s_8ch_frac", "i2s_8ch_src", CLK_SET_RATE_PARENT, + RK3368_CLKSEL_CON(28), 0, + RK3368_CLKGATE_CON(6), 2, GFLAGS, + &rk3368_i2s_8ch_fracmux), COMPOSITE_NODIV(SCLK_I2S_8CH_OUT, "i2s_8ch_clkout", mux_i2s_8ch_clkout_p, 0, RK3368_CLKSEL_CON(27), 15, 1, MFLAGS, RK3368_CLKGATE_CON(6), 0, GFLAGS), @@ -352,21 +379,21 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { COMPOSITE(0, "spdif_8ch_src", mux_pll_src_cpll_gpll_p, 0, RK3368_CLKSEL_CON(31), 12, 1, MFLAGS, 0, 7, DFLAGS, RK3368_CLKGATE_CON(6), 4, GFLAGS), - COMPOSITE_FRAC(0, "spdif_8ch_frac", "spdif_8ch_src", CLK_SET_RATE_PARENT, - RK3368_CLKSEL_CON(32), 0, - RK3368_CLKGATE_CON(6), 5, GFLAGS), - COMPOSITE_NODIV(SCLK_SPDIF_8CH, "sclk_spdif_8ch", mux_spdif_8ch_p, CLK_SET_RATE_PARENT, - RK3368_CLKSEL_CON(31), 8, 2, MFLAGS, - RK3368_CLKGATE_CON(6), 6, GFLAGS), + COMPOSITE_FRACMUX(0, "spdif_8ch_frac", "spdif_8ch_src", CLK_SET_RATE_PARENT, + RK3368_CLKSEL_CON(32), 0, + RK3368_CLKGATE_CON(6), 5, GFLAGS, + &rk3368_spdif_8ch_fracmux), + GATE(SCLK_SPDIF_8CH, "sclk_spdif_8ch", "spdif_8ch_pre", CLK_SET_RATE_PARENT, + RK3368_CLKGATE_CON(6), 6, GFLAGS), COMPOSITE(0, "i2s_2ch_src", mux_pll_src_cpll_gpll_p, 0, RK3368_CLKSEL_CON(53), 12, 1, MFLAGS, 0, 7, DFLAGS, RK3368_CLKGATE_CON(5), 13, GFLAGS), - COMPOSITE_FRAC(0, "i2s_2ch_frac", "i2s_2ch_src", CLK_SET_RATE_PARENT, - RK3368_CLKSEL_CON(54), 0, - RK3368_CLKGATE_CON(5), 14, GFLAGS), - COMPOSITE_NODIV(SCLK_I2S_2CH, "sclk_i2s_2ch", mux_i2s_2ch_p, CLK_SET_RATE_PARENT, - RK3368_CLKSEL_CON(53), 8, 2, MFLAGS, - RK3368_CLKGATE_CON(5), 15, GFLAGS), + COMPOSITE_FRACMUX(0, "i2s_2ch_frac", "i2s_2ch_src", CLK_SET_RATE_PARENT, + RK3368_CLKSEL_CON(54), 0, + RK3368_CLKGATE_CON(5), 14, GFLAGS, + &rk3368_i2s_2ch_fracmux), + GATE(SCLK_I2S_2CH, "sclk_i2s_2ch", "i2s_2ch_pre", CLK_SET_RATE_PARENT, + RK3368_CLKGATE_CON(5), 15, GFLAGS), COMPOSITE(0, "sclk_tsp", mux_pll_src_cpll_gpll_npll_p, 0, RK3368_CLKSEL_CON(46), 6, 2, MFLAGS, 0, 5, DFLAGS, @@ -562,38 +589,34 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { COMPOSITE(0, "uart0_src", mux_pll_src_cpll_gpll_usb_usb_p, 0, RK3368_CLKSEL_CON(33), 12, 2, MFLAGS, 0, 7, DFLAGS, RK3368_CLKGATE_CON(2), 0, GFLAGS), - COMPOSITE_FRAC(0, "uart0_frac", "uart0_src", CLK_SET_RATE_PARENT, - RK3368_CLKSEL_CON(34), 0, - RK3368_CLKGATE_CON(2), 1, GFLAGS), - MUX(SCLK_UART0, "sclk_uart0", mux_uart0_p, CLK_SET_RATE_PARENT, - RK3368_CLKSEL_CON(33), 8, 2, MFLAGS), + COMPOSITE_FRACMUX(0, "uart0_frac", "uart0_src", CLK_SET_RATE_PARENT, + RK3368_CLKSEL_CON(34), 0, + RK3368_CLKGATE_CON(2), 1, GFLAGS, + &rk3368_uart0_fracmux), COMPOSITE_NOMUX(0, "uart1_src", "uart_src", 0, RK3368_CLKSEL_CON(35), 0, 7, DFLAGS, RK3368_CLKGATE_CON(2), 2, GFLAGS), - COMPOSITE_FRAC(0, "uart1_frac", "uart1_src", CLK_SET_RATE_PARENT, - RK3368_CLKSEL_CON(36), 0, - RK3368_CLKGATE_CON(2), 3, GFLAGS), - MUX(SCLK_UART1, "sclk_uart1", mux_uart1_p, CLK_SET_RATE_PARENT, - RK3368_CLKSEL_CON(35), 8, 2, MFLAGS), + COMPOSITE_FRACMUX(0, "uart1_frac", "uart1_src", CLK_SET_RATE_PARENT, + RK3368_CLKSEL_CON(36), 0, + RK3368_CLKGATE_CON(2), 3, GFLAGS, + &rk3368_uart1_fracmux), COMPOSITE_NOMUX(0, "uart3_src", "uart_src", 0, RK3368_CLKSEL_CON(39), 0, 7, DFLAGS, RK3368_CLKGATE_CON(2), 6, GFLAGS), - COMPOSITE_FRAC(0, "uart3_frac", "uart3_src", CLK_SET_RATE_PARENT, - RK3368_CLKSEL_CON(40), 0, - RK3368_CLKGATE_CON(2), 7, GFLAGS), - MUX(SCLK_UART3, "sclk_uart3", mux_uart3_p, CLK_SET_RATE_PARENT, - RK3368_CLKSEL_CON(39), 8, 2, MFLAGS), + COMPOSITE_FRACMUX(0, "uart3_frac", "uart3_src", CLK_SET_RATE_PARENT, + RK3368_CLKSEL_CON(40), 0, + RK3368_CLKGATE_CON(2), 7, GFLAGS, + &rk3368_uart3_fracmux), COMPOSITE_NOMUX(0, "uart4_src", "uart_src", 0, RK3368_CLKSEL_CON(41), 0, 7, DFLAGS, RK3368_CLKGATE_CON(2), 8, GFLAGS), - COMPOSITE_FRAC(0, "uart4_frac", "uart4_src", CLK_SET_RATE_PARENT, - RK3368_CLKSEL_CON(42), 0, - RK3368_CLKGATE_CON(2), 9, GFLAGS), - MUX(SCLK_UART4, "sclk_uart4", mux_uart4_p, CLK_SET_RATE_PARENT, - RK3368_CLKSEL_CON(41), 8, 2, MFLAGS), + COMPOSITE_FRACMUX(0, "uart4_frac", "uart4_src", CLK_SET_RATE_PARENT, + RK3368_CLKSEL_CON(42), 0, + RK3368_CLKGATE_CON(2), 9, GFLAGS, + &rk3368_uart4_fracmux), COMPOSITE(0, "mac_pll_src", mux_pll_src_npll_cpll_gpll_p, 0, RK3368_CLKSEL_CON(43), 6, 2, MFLAGS, 0, 5, DFLAGS, -- cgit v0.10.2 From 023bd7166be0595d18220dfd5c9765b3970f6ef3 Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Fri, 26 Feb 2016 09:25:52 +0800 Subject: clk: skip unnecessary set_phase if nothing to do Let's compare the degrees from clk_set_rate with clk->core->phase. If the requested degrees is already there, skip the following steps. Signed-off-by: Shawn Lin [sboyd@codeaurora.org: s/drgrees/degrees/ in commit text] Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index d95d6f9..437eebf8 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1841,6 +1841,10 @@ int clk_set_phase(struct clk *clk, int degrees) clk_prepare_lock(); + /* bail early if nothing to do */ + if (degrees == clk->core->phase) + goto out; + trace_clk_set_phase(clk->core, degrees); if (clk->core->ops->set_phase) @@ -1851,6 +1855,7 @@ int clk_set_phase(struct clk *clk, int degrees) if (!ret) clk->core->phase = degrees; +out: clk_prepare_unlock(); return ret; -- cgit v0.10.2 From c5f80c5f6e2f4961284c29e1c5f3bf42034b7323 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 12 Feb 2016 04:00:42 +0200 Subject: clk: shmobile: r8a7795: Add FCP clocks The parent clock isn't documented in the datasheet, use S2D1 as a best guess for now. Signed-off-by: Laurent Pinchart Signed-off-by: Geert Uytterhoeven diff --git a/drivers/clk/shmobile/r8a7795-cpg-mssr.c b/drivers/clk/shmobile/r8a7795-cpg-mssr.c index 1f4b21a..d971db9 100644 --- a/drivers/clk/shmobile/r8a7795-cpg-mssr.c +++ b/drivers/clk/shmobile/r8a7795-cpg-mssr.c @@ -147,6 +147,21 @@ static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = { DEF_MOD("hscif2", 518, R8A7795_CLK_S3D1), DEF_MOD("hscif1", 519, R8A7795_CLK_S3D1), DEF_MOD("hscif0", 520, R8A7795_CLK_S3D1), + DEF_MOD("fcpvd3", 600, R8A7795_CLK_S2D1), + DEF_MOD("fcpvd2", 601, R8A7795_CLK_S2D1), + DEF_MOD("fcpvd1", 602, R8A7795_CLK_S2D1), + DEF_MOD("fcpvd0", 603, R8A7795_CLK_S2D1), + DEF_MOD("fcpvb1", 606, R8A7795_CLK_S2D1), + DEF_MOD("fcpvb0", 607, R8A7795_CLK_S2D1), + DEF_MOD("fcpvi2", 609, R8A7795_CLK_S2D1), + DEF_MOD("fcpvi1", 610, R8A7795_CLK_S2D1), + DEF_MOD("fcpvi0", 611, R8A7795_CLK_S2D1), + DEF_MOD("fcpf2", 613, R8A7795_CLK_S2D1), + DEF_MOD("fcpf1", 614, R8A7795_CLK_S2D1), + DEF_MOD("fcpf0", 615, R8A7795_CLK_S2D1), + DEF_MOD("fcpci1", 616, R8A7795_CLK_S2D1), + DEF_MOD("fcpci0", 617, R8A7795_CLK_S2D1), + DEF_MOD("fcpcs", 619, R8A7795_CLK_S2D1), DEF_MOD("vspd3", 620, R8A7795_CLK_S2D1), DEF_MOD("vspd2", 621, R8A7795_CLK_S2D1), DEF_MOD("vspd1", 622, R8A7795_CLK_S2D1), -- cgit v0.10.2 From 31aeb5a523b0f6c1b7cc4f802e6f925168f7d60d Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 12 Feb 2016 04:00:43 +0200 Subject: clk: shmobile: r8a7795: Add LVDS module clock The parent clock hasn't been validated yet. Signed-off-by: Laurent Pinchart Signed-off-by: Geert Uytterhoeven diff --git a/drivers/clk/shmobile/r8a7795-cpg-mssr.c b/drivers/clk/shmobile/r8a7795-cpg-mssr.c index d971db9..79acdd0 100644 --- a/drivers/clk/shmobile/r8a7795-cpg-mssr.c +++ b/drivers/clk/shmobile/r8a7795-cpg-mssr.c @@ -179,6 +179,7 @@ static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = { DEF_MOD("du2", 722, R8A7795_CLK_S2D1), DEF_MOD("du1", 723, R8A7795_CLK_S2D1), DEF_MOD("du0", 724, R8A7795_CLK_S2D1), + DEF_MOD("lvds", 727, R8A7795_CLK_S2D1), DEF_MOD("hdmi1", 728, R8A7795_CLK_HDMI), DEF_MOD("hdmi0", 729, R8A7795_CLK_HDMI), DEF_MOD("etheravb", 812, R8A7795_CLK_S3D2), -- cgit v0.10.2 From 3092d3b8e56e09ff74d7ef9f1c34a4c358e9f0fe Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 18 Feb 2016 15:16:02 +0100 Subject: clk: shmobile: div6: Fix .recalc_rate() using a stale divisor cpg_div6_clock_set_rate() only programs the new divisor if the clock isn't stopped. If the clock is stopped, it will update the cached divisor value only, which will be programmed into the clock registers when enabling the clock later. However, cpg_div6_clock_recalc_rate() reads the divisor from the clock registers instead of using the cached value, leading to an incorrect result if the clock is currently stopped. Make cpg_div6_clock_recalc_rate() use the cached value to fix this. Reported-by: Ramesh Shanmugasundaram Suggested-by: Laurent Pinchart Signed-off-by: Geert Uytterhoeven Reviewed-by: Laurent Pinchart Tested-by: Ramesh Shanmugasundaram diff --git a/drivers/clk/shmobile/clk-div6.c b/drivers/clk/shmobile/clk-div6.c index 9999947..0627860 100644 --- a/drivers/clk/shmobile/clk-div6.c +++ b/drivers/clk/shmobile/clk-div6.c @@ -82,9 +82,8 @@ static unsigned long cpg_div6_clock_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct div6_clock *clock = to_div6_clock(hw); - unsigned int div = (clk_readl(clock->reg) & CPG_DIV6_DIV_MASK) + 1; - return parent_rate / div; + return parent_rate / clock->div; } static unsigned int cpg_div6_clock_calc_div(unsigned long rate, -- cgit v0.10.2 From 11c6fb783256d016295db241ce5e16f65a4da97c Mon Sep 17 00:00:00 2001 From: Ramesh Shanmugasundaram Date: Thu, 25 Feb 2016 17:05:24 +0000 Subject: clk: shmobile: r8a7795: Add CAN peripheral clock Signed-off-by: Ramesh Shanmugasundaram Signed-off-by: Geert Uytterhoeven diff --git a/drivers/clk/shmobile/r8a7795-cpg-mssr.c b/drivers/clk/shmobile/r8a7795-cpg-mssr.c index 79acdd0..958043e 100644 --- a/drivers/clk/shmobile/r8a7795-cpg-mssr.c +++ b/drivers/clk/shmobile/r8a7795-cpg-mssr.c @@ -192,6 +192,8 @@ static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = { DEF_MOD("gpio2", 910, R8A7795_CLK_CP), DEF_MOD("gpio1", 911, R8A7795_CLK_CP), DEF_MOD("gpio0", 912, R8A7795_CLK_CP), + DEF_MOD("can-if1", 915, R8A7795_CLK_S3D4), + DEF_MOD("can-if0", 916, R8A7795_CLK_S3D4), DEF_MOD("i2c6", 918, R8A7795_CLK_S3D2), DEF_MOD("i2c5", 919, R8A7795_CLK_S3D2), DEF_MOD("i2c4", 927, R8A7795_CLK_S3D2), -- cgit v0.10.2 From 7e00d63199f580bd58cf40f4d48787d0cdd983c0 Mon Sep 17 00:00:00 2001 From: Ramesh Shanmugasundaram Date: Thu, 25 Feb 2016 17:05:25 +0000 Subject: clk: shmobile: r8a7795: Add CANFD clock Signed-off-by: Ramesh Shanmugasundaram Signed-off-by: Geert Uytterhoeven diff --git a/drivers/clk/shmobile/r8a7795-cpg-mssr.c b/drivers/clk/shmobile/r8a7795-cpg-mssr.c index 958043e..26af939 100644 --- a/drivers/clk/shmobile/r8a7795-cpg-mssr.c +++ b/drivers/clk/shmobile/r8a7795-cpg-mssr.c @@ -112,6 +112,7 @@ static const struct cpg_core_clk r8a7795_core_clks[] __initconst = { DEF_DIV6P1("mso", R8A7795_CLK_MSO, CLK_PLL1_DIV4, 0x014), DEF_DIV6P1("hdmi", R8A7795_CLK_HDMI, CLK_PLL1_DIV2, 0x250), + DEF_DIV6P1("canfd", R8A7795_CLK_CANFD, CLK_PLL1_DIV4, 0x244), }; static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = { -- cgit v0.10.2 From a080c8c346d650c84adfd5ff16ac2160b646d73e Mon Sep 17 00:00:00 2001 From: Ramesh Shanmugasundaram Date: Thu, 25 Feb 2016 17:05:26 +0000 Subject: clk: shmobile: r8a7795: Add CAN FD peripheral clock Signed-off-by: Ramesh Shanmugasundaram Signed-off-by: Geert Uytterhoeven diff --git a/drivers/clk/shmobile/r8a7795-cpg-mssr.c b/drivers/clk/shmobile/r8a7795-cpg-mssr.c index 26af939..b2198aef 100644 --- a/drivers/clk/shmobile/r8a7795-cpg-mssr.c +++ b/drivers/clk/shmobile/r8a7795-cpg-mssr.c @@ -193,6 +193,7 @@ static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = { DEF_MOD("gpio2", 910, R8A7795_CLK_CP), DEF_MOD("gpio1", 911, R8A7795_CLK_CP), DEF_MOD("gpio0", 912, R8A7795_CLK_CP), + DEF_MOD("can-fd", 914, R8A7795_CLK_S3D2), DEF_MOD("can-if1", 915, R8A7795_CLK_S3D4), DEF_MOD("can-if0", 916, R8A7795_CLK_S3D4), DEF_MOD("i2c6", 918, R8A7795_CLK_S3D2), -- cgit v0.10.2 From 3e5dd6f6e690048d0fd1c913397506648724474e Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 26 Feb 2016 16:54:31 +0100 Subject: clk: Ignore disabled DT clock providers of_clk_init() uses for_each_matching_node_and_match() to find clock providers, which returns all matching device nodes, whether they are enabled or not. Hence clock providers that are disabled explicitly in DT using e.g. "status = "disabled"; are still activated. Add a check to ignore device nodes that are not enabled, like of_irq_init() does. Reported-by: Ramesh Shanmugasundaram Signed-off-by: Geert Uytterhoeven Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 437eebf8..b775c88 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -3138,6 +3138,9 @@ void __init of_clk_init(const struct of_device_id *matches) for_each_matching_node_and_match(np, matches, &match) { struct clock_provider *parent; + if (!of_device_is_available(np)) + continue; + parent = kzalloc(sizeof(*parent), GFP_KERNEL); if (!parent) { list_for_each_entry_safe(clk_provider, next, -- cgit v0.10.2 From 929e7f3bc7b82fb3e72392dec6a1df334cff6313 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Fri, 19 Feb 2016 15:52:32 -0800 Subject: clk: Make of_clk_get_parent_count() return unsigned ints Russell King recently pointed out a bug in the clk-gpio code where it fails to register the clk if of_clk_get_parent_count() returns an error because the "clocks" property isn't present in the DT node. If we're trying to count parents from DT we'd like to know the count, not if there is a "clocks" property or not. Furthermore, some drivers are assigning the return value to their clk_init_data::num_parents member which is unsigned, leading to potentially large numbers of parents when the property isn't present. Let's change the API to return an unsigned int instead of an int. All the callers just want to know the count anyway, and this avoids the bug that was in the clk-gpio driver. Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index b775c88..fb74dc1 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -2986,9 +2986,21 @@ struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec) } EXPORT_SYMBOL_GPL(of_clk_get_from_provider); -int of_clk_get_parent_count(struct device_node *np) +/** + * of_clk_get_parent_count() - Count the number of clocks a device node has + * @np: device node to count + * + * Returns: The number of clocks that are possible parents of this node + */ +unsigned int of_clk_get_parent_count(struct device_node *np) { - return of_count_phandle_with_args(np, "clocks", "#clock-cells"); + int count; + + count = of_count_phandle_with_args(np, "clocks", "#clock-cells"); + if (count < 0) + return 0; + + return count; } EXPORT_SYMBOL_GPL(of_clk_get_parent_count); diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index fce7f02..da95258 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -716,7 +716,7 @@ void of_clk_del_provider(struct device_node *np); struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec, void *data); struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data); -int of_clk_get_parent_count(struct device_node *np); +unsigned int of_clk_get_parent_count(struct device_node *np); int of_clk_parent_fill(struct device_node *np, const char **parents, unsigned int size); const char *of_clk_get_parent_name(struct device_node *np, int index); -- cgit v0.10.2 From 8c1b1e54faed690261752afcba27c79ce4d3fa10 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Fri, 19 Feb 2016 17:29:17 -0800 Subject: clk: at91: Remove impossible checks for of_clk_get_parent_count() These checks for < 0 are impossible now that of_clk_get_parent_count() returns an unsigned int. Change the checks for == 0 and update the type. Cc: Boris Brezillon Signed-off-by: Stephen Boyd diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c index abc8094..f82b16a 100644 --- a/drivers/clk/at91/clk-generated.c +++ b/drivers/clk/at91/clk-generated.c @@ -268,13 +268,13 @@ void __init of_sama5d2_clk_generated_setup(struct device_node *np, u32 id; const char *name; struct clk *clk; - int num_parents; + unsigned int num_parents; const char *parent_names[GENERATED_SOURCE_MAX]; struct device_node *gcknp; struct clk_range range = CLK_RANGE(0, 0); num_parents = of_clk_get_parent_count(np); - if (num_parents <= 0 || num_parents > GENERATED_SOURCE_MAX) + if (num_parents == 0 || num_parents > GENERATED_SOURCE_MAX) return; of_clk_parent_fill(np, parent_names, num_parents); diff --git a/drivers/clk/at91/clk-main.c b/drivers/clk/at91/clk-main.c index fd7247d..b85f435 100644 --- a/drivers/clk/at91/clk-main.c +++ b/drivers/clk/at91/clk-main.c @@ -611,12 +611,12 @@ void __init of_at91sam9x5_clk_main_setup(struct device_node *np, { struct clk *clk; const char *parent_names[2]; - int num_parents; + unsigned int num_parents; unsigned int irq; const char *name = np->name; num_parents = of_clk_get_parent_count(np); - if (num_parents <= 0 || num_parents > 2) + if (num_parents == 0 || num_parents > 2) return; of_clk_parent_fill(np, parent_names, num_parents); diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c index 620ea32..016fe11 100644 --- a/drivers/clk/at91/clk-master.c +++ b/drivers/clk/at91/clk-master.c @@ -221,14 +221,14 @@ of_at91_clk_master_setup(struct device_node *np, struct at91_pmc *pmc, const struct clk_master_layout *layout) { struct clk *clk; - int num_parents; + unsigned int num_parents; unsigned int irq; const char *parent_names[MASTER_SOURCE_MAX]; const char *name = np->name; struct clk_master_characteristics *characteristics; num_parents = of_clk_get_parent_count(np); - if (num_parents <= 0 || num_parents > MASTER_SOURCE_MAX) + if (num_parents == 0 || num_parents > MASTER_SOURCE_MAX) return; of_clk_parent_fill(np, parent_names, num_parents); diff --git a/drivers/clk/at91/clk-programmable.c b/drivers/clk/at91/clk-programmable.c index 14b270b..b955fb81 100644 --- a/drivers/clk/at91/clk-programmable.c +++ b/drivers/clk/at91/clk-programmable.c @@ -232,13 +232,13 @@ of_at91_clk_prog_setup(struct device_node *np, struct at91_pmc *pmc, int num; u32 id; struct clk *clk; - int num_parents; + unsigned int num_parents; const char *parent_names[PROG_SOURCE_MAX]; const char *name; struct device_node *progclknp; num_parents = of_clk_get_parent_count(np); - if (num_parents <= 0 || num_parents > PROG_SOURCE_MAX) + if (num_parents == 0 || num_parents > PROG_SOURCE_MAX) return; of_clk_parent_fill(np, parent_names, num_parents); diff --git a/drivers/clk/at91/clk-slow.c b/drivers/clk/at91/clk-slow.c index 6f99a53..67b3047 100644 --- a/drivers/clk/at91/clk-slow.c +++ b/drivers/clk/at91/clk-slow.c @@ -366,11 +366,11 @@ void __init of_at91sam9x5_clk_slow_setup(struct device_node *np, { struct clk *clk; const char *parent_names[2]; - int num_parents; + unsigned int num_parents; const char *name = np->name; num_parents = of_clk_get_parent_count(np); - if (num_parents <= 0 || num_parents > 2) + if (num_parents == 0 || num_parents > 2) return; of_clk_parent_fill(np, parent_names, num_parents); @@ -437,7 +437,7 @@ void __init of_at91sam9260_clk_slow_setup(struct device_node *np, { struct clk *clk; const char *parent_names[2]; - int num_parents; + unsigned int num_parents; const char *name = np->name; num_parents = of_clk_get_parent_count(np); diff --git a/drivers/clk/at91/clk-smd.c b/drivers/clk/at91/clk-smd.c index a7f8501..f525830 100644 --- a/drivers/clk/at91/clk-smd.c +++ b/drivers/clk/at91/clk-smd.c @@ -145,12 +145,12 @@ void __init of_at91sam9x5_clk_smd_setup(struct device_node *np, struct at91_pmc *pmc) { struct clk *clk; - int num_parents; + unsigned int num_parents; const char *parent_names[SMD_SOURCE_MAX]; const char *name = np->name; num_parents = of_clk_get_parent_count(np); - if (num_parents <= 0 || num_parents > SMD_SOURCE_MAX) + if (num_parents == 0 || num_parents > SMD_SOURCE_MAX) return; of_clk_parent_fill(np, parent_names, num_parents); diff --git a/drivers/clk/at91/clk-usb.c b/drivers/clk/at91/clk-usb.c index 8ab8502..be1c7f5 100644 --- a/drivers/clk/at91/clk-usb.c +++ b/drivers/clk/at91/clk-usb.c @@ -373,12 +373,12 @@ void __init of_at91sam9x5_clk_usb_setup(struct device_node *np, struct at91_pmc *pmc) { struct clk *clk; - int num_parents; + unsigned int num_parents; const char *parent_names[USB_SOURCE_MAX]; const char *name = np->name; num_parents = of_clk_get_parent_count(np); - if (num_parents <= 0 || num_parents > USB_SOURCE_MAX) + if (num_parents == 0 || num_parents > USB_SOURCE_MAX) return; of_clk_parent_fill(np, parent_names, num_parents); -- cgit v0.10.2 From 0985df89537e7fd5ec963c760f7860b5718510ce Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Fri, 19 Feb 2016 17:31:52 -0800 Subject: clk: gpio: Remove impossible check for of_clk_get_parent_count() < 0 The check for < 0 is impossible now that of_clk_get_parent_count() returns an unsigned int. Simplify the code and update the type here. Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c index 522bffd..08f65ac 100644 --- a/drivers/clk/clk-gpio.c +++ b/drivers/clk/clk-gpio.c @@ -205,15 +205,13 @@ static int gpio_clk_driver_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; const char **parent_names, *gpio_name; - int num_parents, gpio; + unsigned int num_parents; + int gpio; enum of_gpio_flags of_flags; struct clk *clk; bool active_low, is_mux; num_parents = of_clk_get_parent_count(node); - if (num_parents < 0) - num_parents = 0; - if (num_parents) { parent_names = devm_kcalloc(&pdev->dev, num_parents, sizeof(char *), GFP_KERNEL); -- cgit v0.10.2 From ebf3f9a9234211ea9de186402b53389de676f1d5 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Fri, 19 Feb 2016 17:36:51 -0800 Subject: clk: h8300: Remove impossible check for of_clk_get_parent_count() The checks for < 1 can be simplified now that of_clk_get_parent_count() returns an unsigned int. Update the code to reflect the int to unsigned int change. Cc: Yoshinori Sato Cc: Signed-off-by: Stephen Boyd diff --git a/drivers/clk/h8300/clk-div.c b/drivers/clk/h8300/clk-div.c index d71d011..5ecc066 100644 --- a/drivers/clk/h8300/clk-div.c +++ b/drivers/clk/h8300/clk-div.c @@ -13,7 +13,7 @@ static DEFINE_SPINLOCK(clklock); static void __init h8300_div_clk_setup(struct device_node *node) { - int num_parents; + unsigned int num_parents; struct clk *clk; const char *clk_name = node->name; const char *parent_name; @@ -22,7 +22,7 @@ static void __init h8300_div_clk_setup(struct device_node *node) int offset; num_parents = of_clk_get_parent_count(node); - if (num_parents < 1) { + if (!num_parents) { pr_err("%s: no parent found", clk_name); return; } diff --git a/drivers/clk/h8300/clk-h8s2678.c b/drivers/clk/h8300/clk-h8s2678.c index 6cf38dc..c9c2fd5 100644 --- a/drivers/clk/h8300/clk-h8s2678.c +++ b/drivers/clk/h8300/clk-h8s2678.c @@ -83,7 +83,7 @@ static const struct clk_ops pll_ops = { static void __init h8s2678_pll_clk_setup(struct device_node *node) { - int num_parents; + unsigned int num_parents; struct clk *clk; const char *clk_name = node->name; const char *parent_name; @@ -91,7 +91,7 @@ static void __init h8s2678_pll_clk_setup(struct device_node *node) struct clk_init_data init; num_parents = of_clk_get_parent_count(node); - if (num_parents < 1) { + if (!num_parents) { pr_err("%s: no parent found", clk_name); return; } -- cgit v0.10.2 From caeb057cd30412b85e69f663a43f55a29666c79b Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Fri, 19 Feb 2016 17:43:30 -0800 Subject: clk: st: Remove impossible check for of_clk_get_parent_count() < 0 The checks for < 0 are impossible now that of_clk_get_parent_count() returns an unsigned int. Simplify the code and update the types. Cc: Gabriel Fernandez Signed-off-by: Stephen Boyd diff --git a/drivers/clk/st/clk-flexgen.c b/drivers/clk/st/clk-flexgen.c index 24d9959..627267c 100644 --- a/drivers/clk/st/clk-flexgen.c +++ b/drivers/clk/st/clk-flexgen.c @@ -244,10 +244,10 @@ static const char ** __init flexgen_get_parents(struct device_node *np, int *num_parents) { const char **parents; - int nparents; + unsigned int nparents; nparents = of_clk_get_parent_count(np); - if (WARN_ON(nparents <= 0)) + if (WARN_ON(!nparents)) return NULL; parents = kcalloc(nparents, sizeof(const char *), GFP_KERNEL); diff --git a/drivers/clk/st/clkgen-mux.c b/drivers/clk/st/clkgen-mux.c index 0d9a74b..b1e10ff 100644 --- a/drivers/clk/st/clkgen-mux.c +++ b/drivers/clk/st/clkgen-mux.c @@ -26,10 +26,10 @@ static const char ** __init clkgen_mux_get_parents(struct device_node *np, int *num_parents) { const char **parents; - int nparents; + unsigned int nparents; nparents = of_clk_get_parent_count(np); - if (WARN_ON(nparents <= 0)) + if (WARN_ON(!nparents)) return ERR_PTR(-EINVAL); parents = kcalloc(nparents, sizeof(const char *), GFP_KERNEL); -- cgit v0.10.2 From 36bf2811416c7ac79260e0a3b1bb0648559e443b Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Fri, 19 Feb 2016 17:44:27 -0800 Subject: clk: sunxi: Use proper type for of_clk_get_parent_count() return value The return type of of_clk_get_parent_count() is an unsigned int now, so let's update the code here to be more explicit about the range of values we can test for. Cc: Maxime Ripard Cc: Chen-Yu Tsai Signed-off-by: Stephen Boyd diff --git a/drivers/clk/sunxi/clk-sun6i-ar100.c b/drivers/clk/sunxi/clk-sun6i-ar100.c index 2088768..c903705 100644 --- a/drivers/clk/sunxi/clk-sun6i-ar100.c +++ b/drivers/clk/sunxi/clk-sun6i-ar100.c @@ -181,7 +181,7 @@ static int sun6i_a31_ar100_clk_probe(struct platform_device *pdev) struct ar100_clk *ar100; struct resource *r; struct clk *clk; - int nparents; + unsigned int nparents; ar100 = devm_kzalloc(&pdev->dev, sizeof(*ar100), GFP_KERNEL); if (!ar100) -- cgit v0.10.2 From 921bacfa34d48c019bb068257c0947d728662bf3 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Fri, 19 Feb 2016 17:49:23 -0800 Subject: clk: ti: Update for of_clk_get_parent_count() returning unsigned int Change the types here to unsigned int instead of int and update the checks for == 0 instead < 1 to be more explicit about what's going on now that of_clk_get_parent_count() has changed return types. Cc: Tero Kristo Signed-off-by: Stephen Boyd diff --git a/drivers/clk/ti/clockdomain.c b/drivers/clk/ti/clockdomain.c index b9bc3b8..6cf9dd1 100644 --- a/drivers/clk/ti/clockdomain.c +++ b/drivers/clk/ti/clockdomain.c @@ -109,7 +109,7 @@ static void __init of_ti_clockdomain_setup(struct device_node *node) struct clk_hw *clk_hw; const char *clkdm_name = node->name; int i; - int num_clks; + unsigned int num_clks; num_clks = of_clk_get_parent_count(node); diff --git a/drivers/clk/ti/composite.c b/drivers/clk/ti/composite.c index 43345c4..1cf70f4 100644 --- a/drivers/clk/ti/composite.c +++ b/drivers/clk/ti/composite.c @@ -234,14 +234,14 @@ cleanup: static void __init of_ti_composite_clk_setup(struct device_node *node) { - int num_clks; + unsigned int num_clks; int i; struct clk_hw_omap_comp *cclk; /* Number of component clocks to be put inside this clock */ num_clks = of_clk_get_parent_count(node); - if (num_clks < 1) { + if (!num_clks) { pr_err("composite clk %s must have component(s)\n", node->name); return; } @@ -271,13 +271,13 @@ CLK_OF_DECLARE(ti_composite_clock, "ti,composite-clock", int __init ti_clk_add_component(struct device_node *node, struct clk_hw *hw, int type) { - int num_parents; + unsigned int num_parents; const char **parent_names; struct component_clk *clk; num_parents = of_clk_get_parent_count(node); - if (num_parents < 1) { + if (!num_parents) { pr_err("component-clock %s must have parent(s)\n", node->name); return -EINVAL; } diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c index f8306f1..3bc9959 100644 --- a/drivers/clk/ti/dpll.c +++ b/drivers/clk/ti/dpll.c @@ -374,7 +374,7 @@ static void __init of_ti_dpll_setup(struct device_node *node, init->ops = ops; init->num_parents = of_clk_get_parent_count(node); - if (init->num_parents < 1) { + if (!init->num_parents) { pr_err("%s must have parent(s)\n", node->name); goto cleanup; } diff --git a/drivers/clk/ti/mux.c b/drivers/clk/ti/mux.c index 618ded9..44777ab 100644 --- a/drivers/clk/ti/mux.c +++ b/drivers/clk/ti/mux.c @@ -178,7 +178,7 @@ static void of_mux_clk_setup(struct device_node *node) { struct clk *clk; void __iomem *reg; - int num_parents; + unsigned int num_parents; const char **parent_names; u8 clk_mux_flags = 0; u32 mask = 0; @@ -261,7 +261,7 @@ struct clk_hw *ti_clk_build_component_mux(struct ti_clk_mux *setup) static void __init of_ti_composite_mux_clk_setup(struct device_node *node) { struct clk_mux *mux; - int num_parents; + unsigned int num_parents; u32 val; mux = kzalloc(sizeof(*mux), GFP_KERNEL); -- cgit v0.10.2 From 3d755dcc20dd452b52532eca17da40ebbd12aee9 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Mon, 22 Feb 2016 11:12:47 -0800 Subject: usb: dwc3: Remove impossible check for of_clk_get_parent_count() < 0 The check for < 0 is impossible now that of_clk_get_parent_count() returns an unsigned int. Simplify the code and update the types. Acked-by: Felipe Balbi Cc: Signed-off-by: Stephen Boyd diff --git a/drivers/usb/dwc3/dwc3-of-simple.c b/drivers/usb/dwc3/dwc3-of-simple.c index 9c9f741..9743353 100644 --- a/drivers/usb/dwc3/dwc3-of-simple.c +++ b/drivers/usb/dwc3/dwc3-of-simple.c @@ -42,6 +42,7 @@ static int dwc3_of_simple_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; + unsigned int count; int ret; int i; @@ -49,11 +50,11 @@ static int dwc3_of_simple_probe(struct platform_device *pdev) if (!simple) return -ENOMEM; - ret = of_clk_get_parent_count(np); - if (ret < 0) - return ret; + count = of_clk_get_parent_count(np); + if (!count) + return -ENOENT; - simple->num_clocks = ret; + simple->num_clocks = count; simple->clks = devm_kcalloc(dev, simple->num_clocks, sizeof(struct clk *), GFP_KERNEL); -- cgit v0.10.2 From 2cd82d06e4c62f927ede33e62f9f0507d64903c9 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Mon, 22 Feb 2016 11:14:25 -0800 Subject: simplefb: Remove impossible check for of_clk_get_parent_count() < 0 The check for < 0 is impossible now that of_clk_get_parent_count() returns an unsigned int. Simplify the code and update the types. Cc: Hans de Goede Cc: Jean-Christophe Plagniol-Villard Acked-by: Tomi Valkeinen Cc: Signed-off-by: Stephen Boyd diff --git a/drivers/video/fbdev/simplefb.c b/drivers/video/fbdev/simplefb.c index 48ccf6d..e9cf199 100644 --- a/drivers/video/fbdev/simplefb.c +++ b/drivers/video/fbdev/simplefb.c @@ -174,7 +174,7 @@ static int simplefb_parse_pd(struct platform_device *pdev, struct simplefb_par { u32 palette[PSEUDO_PALETTE_SIZE]; #if defined CONFIG_OF && defined CONFIG_COMMON_CLK - int clk_count; + unsigned int clk_count; struct clk **clks; #endif #if defined CONFIG_OF && defined CONFIG_REGULATOR @@ -213,7 +213,7 @@ static int simplefb_clocks_init(struct simplefb_par *par, return 0; par->clk_count = of_clk_get_parent_count(np); - if (par->clk_count <= 0) + if (!par->clk_count) return 0; par->clks = kcalloc(par->clk_count, sizeof(struct clk *), GFP_KERNEL); -- cgit v0.10.2 From d3622b5885dc424cfb5e27ff7a3c79d942b2acb4 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Mon, 22 Feb 2016 12:36:15 -0800 Subject: clk: h8300: Properly cast to __iomem pointer Sparse complains here because we dropped the __iomem annotation when casting the aligned address. Add __iomem back so that sparse stops complaining. Cc: Yoshinori Sato Cc: Signed-off-by: Stephen Boyd diff --git a/drivers/clk/h8300/clk-div.c b/drivers/clk/h8300/clk-div.c index 5ecc066..4bf44a2 100644 --- a/drivers/clk/h8300/clk-div.c +++ b/drivers/clk/h8300/clk-div.c @@ -34,7 +34,7 @@ static void __init h8300_div_clk_setup(struct device_node *node) } offset = (unsigned long)divcr & 3; offset = (3 - offset) * 8; - divcr = (void *)((unsigned long)divcr & ~3); + divcr = (void __iomem *)((unsigned long)divcr & ~3); parent_name = of_clk_get_parent_name(node, 0); of_property_read_u32(node, "renesas,width", &width); -- cgit v0.10.2 From 9797d81936d0dc2074f3de1a0458113e1e5ac99f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lothar=20Wa=C3=9Fmann?= Date: Tue, 12 Jan 2016 18:29:18 +0100 Subject: clk: imx: whitespace cleanup; no functional change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit remove whitespace before TAB. Signed-off-by: Lothar Waßmann Acked-by: Stephen Boyd Signed-off-by: Shawn Guo diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c index 79f6f20..af28b2b 100644 --- a/drivers/clk/imx/clk-imx6ul.c +++ b/drivers/clk/imx/clk-imx6ul.c @@ -157,9 +157,9 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) clk_set_parent(clks[IMX6UL_PLL7_BYPASS], clks[IMX6UL_CLK_PLL7]); clks[IMX6UL_CLK_PLL1_SYS] = imx_clk_fixed_factor("pll1_sys", "pll1_bypass", 1, 1); - clks[IMX6UL_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13); - clks[IMX6UL_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13); - clks[IMX6UL_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13); + clks[IMX6UL_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13); + clks[IMX6UL_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13); + clks[IMX6UL_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13); clks[IMX6UL_CLK_PLL5_VIDEO] = imx_clk_gate("pll5_video", "pll5_bypass", base + 0xa0, 13); clks[IMX6UL_CLK_PLL6_ENET] = imx_clk_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13); clks[IMX6UL_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13); @@ -196,8 +196,8 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) base + 0xe0, 2, 2, 0, clk_enet_ref_table, &imx_ccm_lock); clks[IMX6UL_CLK_ENET2_REF_125M] = imx_clk_gate("enet_ref_125m", "enet2_ref", base + 0xe0, 20); - clks[IMX6UL_CLK_ENET_PTP_REF] = imx_clk_fixed_factor("enet_ptp_ref", "pll6_enet", 1, 20); - clks[IMX6UL_CLK_ENET_PTP] = imx_clk_gate("enet_ptp", "enet_ptp_ref", base + 0xe0, 21); + clks[IMX6UL_CLK_ENET_PTP_REF] = imx_clk_fixed_factor("enet_ptp_ref", "pll6_enet", 1, 20); + clks[IMX6UL_CLK_ENET_PTP] = imx_clk_gate("enet_ptp", "enet_ptp_ref", base + 0xe0, 21); clks[IMX6UL_CLK_PLL4_POST_DIV] = clk_register_divider_table(NULL, "pll4_post_div", "pll4_audio", CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock); @@ -210,8 +210,8 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) /* name parent_name mult div */ clks[IMX6UL_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2_396m", 1, 2); - clks[IMX6UL_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6); - clks[IMX6UL_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8); + clks[IMX6UL_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6); + clks[IMX6UL_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8); clks[IMX6UL_CLK_GPT_3M] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8); np = ccm_node; @@ -219,34 +219,34 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) WARN_ON(!base); clks[IMX6UL_CA7_SECONDARY_SEL] = imx_clk_mux("ca7_secondary_sel", base + 0xc, 3, 1, ca7_secondary_sels, ARRAY_SIZE(ca7_secondary_sels)); - clks[IMX6UL_CLK_STEP] = imx_clk_mux("step", base + 0x0c, 8, 1, step_sels, ARRAY_SIZE(step_sels)); - clks[IMX6UL_CLK_PLL1_SW] = imx_clk_mux_flags("pll1_sw", base + 0x0c, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels), 0); + clks[IMX6UL_CLK_STEP] = imx_clk_mux("step", base + 0x0c, 8, 1, step_sels, ARRAY_SIZE(step_sels)); + clks[IMX6UL_CLK_PLL1_SW] = imx_clk_mux_flags("pll1_sw", base + 0x0c, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels), 0); clks[IMX6UL_CLK_AXI_ALT_SEL] = imx_clk_mux("axi_alt_sel", base + 0x14, 7, 1, axi_alt_sels, ARRAY_SIZE(axi_alt_sels)); - clks[IMX6UL_CLK_AXI_SEL] = imx_clk_mux_flags("axi_sel", base + 0x14, 6, 1, axi_sels, ARRAY_SIZE(axi_sels), 0); - clks[IMX6UL_CLK_PERIPH_PRE] = imx_clk_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels)); - clks[IMX6UL_CLK_PERIPH2_PRE] = imx_clk_mux("periph2_pre", base + 0x18, 21, 2, periph2_pre_sels, ARRAY_SIZE(periph2_pre_sels)); + clks[IMX6UL_CLK_AXI_SEL] = imx_clk_mux_flags("axi_sel", base + 0x14, 6, 1, axi_sels, ARRAY_SIZE(axi_sels), 0); + clks[IMX6UL_CLK_PERIPH_PRE] = imx_clk_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels)); + clks[IMX6UL_CLK_PERIPH2_PRE] = imx_clk_mux("periph2_pre", base + 0x18, 21, 2, periph2_pre_sels, ARRAY_SIZE(periph2_pre_sels)); clks[IMX6UL_CLK_PERIPH_CLK2_SEL] = imx_clk_mux("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels)); clks[IMX6UL_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels)); - clks[IMX6UL_CLK_EIM_SLOW_SEL] = imx_clk_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels, ARRAY_SIZE(eim_slow_sels)); + clks[IMX6UL_CLK_EIM_SLOW_SEL] = imx_clk_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels, ARRAY_SIZE(eim_slow_sels)); clks[IMX6UL_CLK_GPMI_SEL] = imx_clk_mux("gpmi_sel", base + 0x1c, 19, 1, gpmi_sels, ARRAY_SIZE(gpmi_sels)); - clks[IMX6UL_CLK_BCH_SEL] = imx_clk_mux("bch_sel", base + 0x1c, 18, 1, bch_sels, ARRAY_SIZE(bch_sels)); + clks[IMX6UL_CLK_BCH_SEL] = imx_clk_mux("bch_sel", base + 0x1c, 18, 1, bch_sels, ARRAY_SIZE(bch_sels)); clks[IMX6UL_CLK_USDHC2_SEL] = imx_clk_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); clks[IMX6UL_CLK_USDHC1_SEL] = imx_clk_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); - clks[IMX6UL_CLK_SAI3_SEL] = imx_clk_mux("sai3_sel", base + 0x1c, 14, 2, sai_sels, ARRAY_SIZE(sai_sels)); + clks[IMX6UL_CLK_SAI3_SEL] = imx_clk_mux("sai3_sel", base + 0x1c, 14, 2, sai_sels, ARRAY_SIZE(sai_sels)); clks[IMX6UL_CLK_SAI2_SEL] = imx_clk_mux("sai2_sel", base + 0x1c, 12, 2, sai_sels, ARRAY_SIZE(sai_sels)); - clks[IMX6UL_CLK_SAI1_SEL] = imx_clk_mux("sai1_sel", base + 0x1c, 10, 2, sai_sels, ARRAY_SIZE(sai_sels)); - clks[IMX6UL_CLK_QSPI1_SEL] = imx_clk_mux("qspi1_sel", base + 0x1c, 7, 3, qspi1_sels, ARRAY_SIZE(qspi1_sels)); - clks[IMX6UL_CLK_PERCLK_SEL] = imx_clk_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels)); - clks[IMX6UL_CLK_CAN_SEL] = imx_clk_mux("can_sel", base + 0x20, 8, 2, can_sels, ARRAY_SIZE(can_sels)); + clks[IMX6UL_CLK_SAI1_SEL] = imx_clk_mux("sai1_sel", base + 0x1c, 10, 2, sai_sels, ARRAY_SIZE(sai_sels)); + clks[IMX6UL_CLK_QSPI1_SEL] = imx_clk_mux("qspi1_sel", base + 0x1c, 7, 3, qspi1_sels, ARRAY_SIZE(qspi1_sels)); + clks[IMX6UL_CLK_PERCLK_SEL] = imx_clk_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels)); + clks[IMX6UL_CLK_CAN_SEL] = imx_clk_mux("can_sel", base + 0x20, 8, 2, can_sels, ARRAY_SIZE(can_sels)); clks[IMX6UL_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels)); clks[IMX6UL_CLK_ENFC_SEL] = imx_clk_mux("enfc_sel", base + 0x2c, 15, 3, enfc_sels, ARRAY_SIZE(enfc_sels)); clks[IMX6UL_CLK_LDB_DI0_SEL] = imx_clk_mux("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di0_sels, ARRAY_SIZE(ldb_di0_sels)); clks[IMX6UL_CLK_SPDIF_SEL] = imx_clk_mux("spdif_sel", base + 0x30, 20, 2, spdif_sels, ARRAY_SIZE(spdif_sels)); - clks[IMX6UL_CLK_SIM_PRE_SEL] = imx_clk_mux("sim_pre_sel", base + 0x34, 15, 3, sim_pre_sels, ARRAY_SIZE(sim_pre_sels)); - clks[IMX6UL_CLK_SIM_SEL] = imx_clk_mux("sim_sel", base + 0x34, 9, 3, sim_sels, ARRAY_SIZE(sim_sels)); + clks[IMX6UL_CLK_SIM_PRE_SEL] = imx_clk_mux("sim_pre_sel", base + 0x34, 15, 3, sim_pre_sels, ARRAY_SIZE(sim_pre_sels)); + clks[IMX6UL_CLK_SIM_SEL] = imx_clk_mux("sim_sel", base + 0x34, 9, 3, sim_sels, ARRAY_SIZE(sim_sels)); clks[IMX6UL_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels)); clks[IMX6UL_CLK_LCDIF_PRE_SEL] = imx_clk_mux("lcdif_pre_sel", base + 0x38, 15, 3, lcdif_pre_sels, ARRAY_SIZE(lcdif_pre_sels)); - clks[IMX6UL_CLK_LCDIF_SEL] = imx_clk_mux("lcdif_sel", base + 0x38, 9, 3, lcdif_sels, ARRAY_SIZE(lcdif_sels)); + clks[IMX6UL_CLK_LCDIF_SEL] = imx_clk_mux("lcdif_sel", base + 0x38, 9, 3, lcdif_sels, ARRAY_SIZE(lcdif_sels)); clks[IMX6UL_CLK_LDB_DI0_DIV_SEL] = imx_clk_mux("ldb_di0", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels)); clks[IMX6UL_CLK_LDB_DI1_DIV_SEL] = imx_clk_mux("ldb_di1", base + 0x20, 11, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels)); @@ -259,11 +259,11 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) clks[IMX6UL_CLK_PERIPH] = imx_clk_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels)); clks[IMX6UL_CLK_PERIPH2] = imx_clk_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels)); - clks[IMX6UL_CLK_PERIPH_CLK2] = imx_clk_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3); - clks[IMX6UL_CLK_PERIPH2_CLK2] = imx_clk_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3); + clks[IMX6UL_CLK_PERIPH_CLK2] = imx_clk_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3); + clks[IMX6UL_CLK_PERIPH2_CLK2] = imx_clk_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3); clks[IMX6UL_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2); clks[IMX6UL_CLK_LCDIF_PODF] = imx_clk_divider("lcdif_podf", "lcdif_pred", base + 0x18, 23, 3); - clks[IMX6UL_CLK_QSPI1_PDOF] = imx_clk_divider("qspi1_podf", "qspi1_sel", base + 0x1c, 26, 3); + clks[IMX6UL_CLK_QSPI1_PDOF] = imx_clk_divider("qspi1_podf", "qspi1_sel", base + 0x1c, 26, 3); clks[IMX6UL_CLK_EIM_SLOW_PODF] = imx_clk_divider("eim_slow_podf", "eim_slow_sel", base + 0x1c, 23, 3); clks[IMX6UL_CLK_PERCLK] = imx_clk_divider("perclk", "perclk_sel", base + 0x1c, 0, 6); clks[IMX6UL_CLK_CAN_PODF] = imx_clk_divider("can_podf", "can_sel", base + 0x20, 2, 6); @@ -287,14 +287,14 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) clks[IMX6UL_CLK_LCDIF_PRED] = imx_clk_divider("lcdif_pred", "lcdif_pre_sel", base + 0x38, 12, 3); clks[IMX6UL_CLK_CSI_PODF] = imx_clk_divider("csi_podf", "csi_sel", base + 0x3c, 11, 3); - clks[IMX6UL_CLK_ARM] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16); + clks[IMX6UL_CLK_ARM] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16); clks[IMX6UL_CLK_MMDC_PODF] = imx_clk_busy_divider("mmdc_podf", "periph2", base + 0x14, 3, 3, base + 0x48, 2); clks[IMX6UL_CLK_AXI_PODF] = imx_clk_busy_divider("axi_podf", "axi_sel", base + 0x14, 16, 3, base + 0x48, 0); clks[IMX6UL_CLK_AHB] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1); /* CCGR0 */ - clks[IMX6UL_CLK_AIPSTZ1] = imx_clk_gate2("aips_tz1", "ahb", base + 0x68, 0); - clks[IMX6UL_CLK_AIPSTZ2] = imx_clk_gate2("aips_tz2", "ahb", base + 0x68, 2); + clks[IMX6UL_CLK_AIPSTZ1] = imx_clk_gate2("aips_tz1", "ahb", base + 0x68, 0); + clks[IMX6UL_CLK_AIPSTZ2] = imx_clk_gate2("aips_tz2", "ahb", base + 0x68, 2); clks[IMX6UL_CLK_APBHDMA] = imx_clk_gate2("apbh_dma", "bch_podf", base + 0x68, 4); clks[IMX6UL_CLK_ASRC_IPG] = imx_clk_gate2_shared("asrc_ipg", "ahb", base + 0x68, 6, &share_count_asrc); clks[IMX6UL_CLK_ASRC_MEM] = imx_clk_gate2_shared("asrc_mem", "ahb", base + 0x68, 6, &share_count_asrc); @@ -302,7 +302,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) clks[IMX6UL_CLK_CAAM_ACLK] = imx_clk_gate2("caam_aclk", "ahb", base + 0x68, 10); clks[IMX6UL_CLK_CAAM_IPG] = imx_clk_gate2("caam_ipg", "ipg", base + 0x68, 12); clks[IMX6UL_CLK_CAN1_IPG] = imx_clk_gate2("can1_ipg", "ipg", base + 0x68, 14); - clks[IMX6UL_CLK_CAN1_SERIAL] = imx_clk_gate2("can1_serial", "can_podf", base + 0x68, 16); + clks[IMX6UL_CLK_CAN1_SERIAL] = imx_clk_gate2("can1_serial", "can_podf", base + 0x68, 16); clks[IMX6UL_CLK_CAN2_IPG] = imx_clk_gate2("can2_ipg", "ipg", base + 0x68, 18); clks[IMX6UL_CLK_CAN2_SERIAL] = imx_clk_gate2("can2_serial", "can_podf", base + 0x68, 20); clks[IMX6UL_CLK_GPT2_BUS] = imx_clk_gate2("gpt_bus", "perclk", base + 0x68, 24); @@ -331,7 +331,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) clks[IMX6UL_CLK_CSI] = imx_clk_gate2("csi", "csi_podf", base + 0x70, 2); clks[IMX6UL_CLK_I2C1] = imx_clk_gate2("i2c1", "perclk", base + 0x70, 6); clks[IMX6UL_CLK_I2C2] = imx_clk_gate2("i2c2", "perclk", base + 0x70, 8); - clks[IMX6UL_CLK_I2C3] = imx_clk_gate2("i2c3", "perclk", base + 0x70, 10); + clks[IMX6UL_CLK_I2C3] = imx_clk_gate2("i2c3", "perclk", base + 0x70, 10); clks[IMX6UL_CLK_OCOTP] = imx_clk_gate2("ocotp", "ipg", base + 0x70, 12); clks[IMX6UL_CLK_IOMUXC] = imx_clk_gate2("iomuxc", "lcdif_podf", base + 0x70, 14); clks[IMX6UL_CLK_LCDIF_APB] = imx_clk_gate2("lcdif_apb", "axi", base + 0x70, 28); @@ -391,7 +391,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) clks[IMX6UL_CLK_UART8_IPG] = imx_clk_gate2("uart8_ipg", "ipg", base + 0x80, 14); clks[IMX6UL_CLK_UART8_SERIAL] = imx_clk_gate2("uart8_serial", "uart_podf", base + 0x80, 14); clks[IMX6UL_CLK_WDOG3] = imx_clk_gate2("wdog3", "ipg", base + 0x80, 20); - clks[IMX6UL_CLK_I2C4] = imx_clk_gate2("i2c4", "perclk", base + 0x80, 24); + clks[IMX6UL_CLK_I2C4] = imx_clk_gate2("i2c4", "perclk", base + 0x80, 24); clks[IMX6UL_CLK_PWM5] = imx_clk_gate2("pwm5", "perclk", base + 0x80, 26); clks[IMX6UL_CLK_PWM6] = imx_clk_gate2("pwm6", "perclk", base + 0x80, 28); clks[IMX6UL_CLK_PWM7] = imx_clk_gate2("pwm7", "perclk", base + 0x80, 30); diff --git a/include/dt-bindings/clock/imx6ul-clock.h b/include/dt-bindings/clock/imx6ul-clock.h index c343894..08ce4a7 100644 --- a/include/dt-bindings/clock/imx6ul-clock.h +++ b/include/dt-bindings/clock/imx6ul-clock.h @@ -21,13 +21,13 @@ #define IMX6UL_PLL5_BYPASS_SRC 8 #define IMX6UL_PLL6_BYPASS_SRC 9 #define IMX6UL_PLL7_BYPASS_SRC 10 -#define IMX6UL_CLK_PLL1 11 -#define IMX6UL_CLK_PLL2 12 -#define IMX6UL_CLK_PLL3 13 -#define IMX6UL_CLK_PLL4 14 -#define IMX6UL_CLK_PLL5 15 -#define IMX6UL_CLK_PLL6 16 -#define IMX6UL_CLK_PLL7 17 +#define IMX6UL_CLK_PLL1 11 +#define IMX6UL_CLK_PLL2 12 +#define IMX6UL_CLK_PLL3 13 +#define IMX6UL_CLK_PLL4 14 +#define IMX6UL_CLK_PLL5 15 +#define IMX6UL_CLK_PLL6 16 +#define IMX6UL_CLK_PLL7 17 #define IMX6UL_PLL1_BYPASS 18 #define IMX6UL_PLL2_BYPASS 19 #define IMX6UL_PLL3_BYPASS 20 @@ -37,7 +37,7 @@ #define IMX6UL_PLL7_BYPASS 24 #define IMX6UL_CLK_PLL1_SYS 25 #define IMX6UL_CLK_PLL2_BUS 26 -#define IMX6UL_CLK_PLL3_USB_OTG 27 +#define IMX6UL_CLK_PLL3_USB_OTG 27 #define IMX6UL_CLK_PLL4_AUDIO 28 #define IMX6UL_CLK_PLL5_VIDEO 29 #define IMX6UL_CLK_PLL6_ENET 30 @@ -66,7 +66,7 @@ #define IMX6UL_CLK_PLL2_198M 53 #define IMX6UL_CLK_PLL3_80M 54 #define IMX6UL_CLK_PLL3_60M 55 -#define IMX6UL_CLK_STEP 56 +#define IMX6UL_CLK_STEP 56 #define IMX6UL_CLK_PLL1_SW 57 #define IMX6UL_CLK_AXI_ALT_SEL 58 #define IMX6UL_CLK_AXI_SEL 59 @@ -78,7 +78,7 @@ #define IMX6UL_CLK_USDHC2_SEL 65 #define IMX6UL_CLK_BCH_SEL 66 #define IMX6UL_CLK_GPMI_SEL 67 -#define IMX6UL_CLK_EIM_SLOW_SEL 68 +#define IMX6UL_CLK_EIM_SLOW_SEL 68 #define IMX6UL_CLK_SPDIF_SEL 69 #define IMX6UL_CLK_SAI1_SEL 70 #define IMX6UL_CLK_SAI2_SEL 71 @@ -105,9 +105,9 @@ #define IMX6UL_CLK_LDB_DI1_DIV_SEL 92 #define IMX6UL_CLK_ARM 93 #define IMX6UL_CLK_PERIPH_CLK2 94 -#define IMX6UL_CLK_PERIPH2_CLK2 95 +#define IMX6UL_CLK_PERIPH2_CLK2 95 #define IMX6UL_CLK_AHB 96 -#define IMX6UL_CLK_MMDC_PODF 97 +#define IMX6UL_CLK_MMDC_PODF 97 #define IMX6UL_CLK_AXI_PODF 98 #define IMX6UL_CLK_PERCLK 99 #define IMX6UL_CLK_IPG 100 @@ -133,16 +133,16 @@ #define IMX6UL_CLK_CAN_PODF 120 #define IMX6UL_CLK_ECSPI_PODF 121 #define IMX6UL_CLK_UART_PODF 122 -#define IMX6UL_CLK_ADC1 123 -#define IMX6UL_CLK_ADC2 124 +#define IMX6UL_CLK_ADC1 123 +#define IMX6UL_CLK_ADC2 124 #define IMX6UL_CLK_AIPSTZ1 125 #define IMX6UL_CLK_AIPSTZ2 126 #define IMX6UL_CLK_AIPSTZ3 127 #define IMX6UL_CLK_APBHDMA 128 #define IMX6UL_CLK_ASRC_IPG 129 #define IMX6UL_CLK_ASRC_MEM 130 -#define IMX6UL_CLK_GPMI_BCH_APB 131 -#define IMX6UL_CLK_GPMI_BCH 132 +#define IMX6UL_CLK_GPMI_BCH_APB 131 +#define IMX6UL_CLK_GPMI_BCH 132 #define IMX6UL_CLK_GPMI_IO 133 #define IMX6UL_CLK_GPMI_APB 134 #define IMX6UL_CLK_CAAM_MEM 135 @@ -154,7 +154,7 @@ #define IMX6UL_CLK_ECSPI3 141 #define IMX6UL_CLK_ECSPI4 142 #define IMX6UL_CLK_EIM 143 -#define IMX6UL_CLK_ENET 144 +#define IMX6UL_CLK_ENET 144 #define IMX6UL_CLK_ENET_AHB 145 #define IMX6UL_CLK_EPIT1 146 #define IMX6UL_CLK_EPIT2 147 @@ -166,63 +166,63 @@ #define IMX6UL_CLK_GPT1_SERIAL 153 #define IMX6UL_CLK_GPT2_BUS 154 #define IMX6UL_CLK_GPT2_SERIAL 155 -#define IMX6UL_CLK_I2C1 156 -#define IMX6UL_CLK_I2C2 157 -#define IMX6UL_CLK_I2C3 158 -#define IMX6UL_CLK_I2C4 159 -#define IMX6UL_CLK_IOMUXC 160 -#define IMX6UL_CLK_LCDIF_APB 161 -#define IMX6UL_CLK_LCDIF_PIX 162 -#define IMX6UL_CLK_MMDC_P0_FAST 163 -#define IMX6UL_CLK_MMDC_P0_IPG 164 -#define IMX6UL_CLK_OCOTP 165 -#define IMX6UL_CLK_OCRAM 166 -#define IMX6UL_CLK_PWM1 167 -#define IMX6UL_CLK_PWM2 168 -#define IMX6UL_CLK_PWM3 169 -#define IMX6UL_CLK_PWM4 170 -#define IMX6UL_CLK_PWM5 171 -#define IMX6UL_CLK_PWM6 172 -#define IMX6UL_CLK_PWM7 173 -#define IMX6UL_CLK_PWM8 174 -#define IMX6UL_CLK_PXP 175 -#define IMX6UL_CLK_QSPI 176 -#define IMX6UL_CLK_ROM 177 -#define IMX6UL_CLK_SAI1 178 -#define IMX6UL_CLK_SAI1_IPG 179 -#define IMX6UL_CLK_SAI2 180 -#define IMX6UL_CLK_SAI2_IPG 181 -#define IMX6UL_CLK_SAI3 182 -#define IMX6UL_CLK_SAI3_IPG 183 -#define IMX6UL_CLK_SDMA 184 -#define IMX6UL_CLK_SIM 185 -#define IMX6UL_CLK_SIM_S 186 -#define IMX6UL_CLK_SPBA 187 -#define IMX6UL_CLK_SPDIF 188 -#define IMX6UL_CLK_UART1_IPG 189 -#define IMX6UL_CLK_UART1_SERIAL 190 -#define IMX6UL_CLK_UART2_IPG 191 -#define IMX6UL_CLK_UART2_SERIAL 192 -#define IMX6UL_CLK_UART3_IPG 193 -#define IMX6UL_CLK_UART3_SERIAL 194 -#define IMX6UL_CLK_UART4_IPG 195 -#define IMX6UL_CLK_UART4_SERIAL 196 -#define IMX6UL_CLK_UART5_IPG 197 -#define IMX6UL_CLK_UART5_SERIAL 198 -#define IMX6UL_CLK_UART6_IPG 199 -#define IMX6UL_CLK_UART6_SERIAL 200 -#define IMX6UL_CLK_UART7_IPG 201 -#define IMX6UL_CLK_UART7_SERIAL 202 -#define IMX6UL_CLK_UART8_IPG 203 -#define IMX6UL_CLK_UART8_SERIAL 204 -#define IMX6UL_CLK_USBOH3 205 -#define IMX6UL_CLK_USDHC1 206 -#define IMX6UL_CLK_USDHC2 207 -#define IMX6UL_CLK_WDOG1 208 -#define IMX6UL_CLK_WDOG2 209 -#define IMX6UL_CLK_WDOG3 210 +#define IMX6UL_CLK_I2C1 156 +#define IMX6UL_CLK_I2C2 157 +#define IMX6UL_CLK_I2C3 158 +#define IMX6UL_CLK_I2C4 159 +#define IMX6UL_CLK_IOMUXC 160 +#define IMX6UL_CLK_LCDIF_APB 161 +#define IMX6UL_CLK_LCDIF_PIX 162 +#define IMX6UL_CLK_MMDC_P0_FAST 163 +#define IMX6UL_CLK_MMDC_P0_IPG 164 +#define IMX6UL_CLK_OCOTP 165 +#define IMX6UL_CLK_OCRAM 166 +#define IMX6UL_CLK_PWM1 167 +#define IMX6UL_CLK_PWM2 168 +#define IMX6UL_CLK_PWM3 169 +#define IMX6UL_CLK_PWM4 170 +#define IMX6UL_CLK_PWM5 171 +#define IMX6UL_CLK_PWM6 172 +#define IMX6UL_CLK_PWM7 173 +#define IMX6UL_CLK_PWM8 174 +#define IMX6UL_CLK_PXP 175 +#define IMX6UL_CLK_QSPI 176 +#define IMX6UL_CLK_ROM 177 +#define IMX6UL_CLK_SAI1 178 +#define IMX6UL_CLK_SAI1_IPG 179 +#define IMX6UL_CLK_SAI2 180 +#define IMX6UL_CLK_SAI2_IPG 181 +#define IMX6UL_CLK_SAI3 182 +#define IMX6UL_CLK_SAI3_IPG 183 +#define IMX6UL_CLK_SDMA 184 +#define IMX6UL_CLK_SIM 185 +#define IMX6UL_CLK_SIM_S 186 +#define IMX6UL_CLK_SPBA 187 +#define IMX6UL_CLK_SPDIF 188 +#define IMX6UL_CLK_UART1_IPG 189 +#define IMX6UL_CLK_UART1_SERIAL 190 +#define IMX6UL_CLK_UART2_IPG 191 +#define IMX6UL_CLK_UART2_SERIAL 192 +#define IMX6UL_CLK_UART3_IPG 193 +#define IMX6UL_CLK_UART3_SERIAL 194 +#define IMX6UL_CLK_UART4_IPG 195 +#define IMX6UL_CLK_UART4_SERIAL 196 +#define IMX6UL_CLK_UART5_IPG 197 +#define IMX6UL_CLK_UART5_SERIAL 198 +#define IMX6UL_CLK_UART6_IPG 199 +#define IMX6UL_CLK_UART6_SERIAL 200 +#define IMX6UL_CLK_UART7_IPG 201 +#define IMX6UL_CLK_UART7_SERIAL 202 +#define IMX6UL_CLK_UART8_IPG 203 +#define IMX6UL_CLK_UART8_SERIAL 204 +#define IMX6UL_CLK_USBOH3 205 +#define IMX6UL_CLK_USDHC1 206 +#define IMX6UL_CLK_USDHC2 207 +#define IMX6UL_CLK_WDOG1 208 +#define IMX6UL_CLK_WDOG2 209 +#define IMX6UL_CLK_WDOG3 210 #define IMX6UL_CLK_LDB_DI0 211 -#define IMX6UL_CLK_AXI 212 +#define IMX6UL_CLK_AXI 212 #define IMX6UL_CLK_SPDIF_GCLK 213 #define IMX6UL_CLK_GPT_3M 214 #define IMX6UL_CLK_SIM2 215 -- cgit v0.10.2 From f6c3aec2f7a218abec9e5c00353abc02224be49e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lothar=20Wa=C3=9Fmann?= Date: Tue, 12 Jan 2016 18:29:19 +0100 Subject: clk: imx: add kpp clock for i.MX6UL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the necessary clock to use the KPP interface on i.MX6UL. Signed-off-by: Lothar Waßmann Acked-by: Stephen Boyd Signed-off-by: Shawn Guo diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c index af28b2b..0f1f17a 100644 --- a/drivers/clk/imx/clk-imx6ul.c +++ b/drivers/clk/imx/clk-imx6ul.c @@ -365,6 +365,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) /* CCGR5 */ clks[IMX6UL_CLK_ROM] = imx_clk_gate2("rom", "ahb", base + 0x7c, 0); clks[IMX6UL_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6); + clks[IMX6UL_CLK_KPP] = imx_clk_gate2("kpp", "ipg", base + 0x7c, 8); clks[IMX6UL_CLK_WDOG2] = imx_clk_gate2("wdog2", "ipg", base + 0x7c, 10); clks[IMX6UL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); clks[IMX6UL_CLK_SPDIF] = imx_clk_gate2_shared("spdif", "spdif_podf", base + 0x7c, 14, &share_count_audio); diff --git a/include/dt-bindings/clock/imx6ul-clock.h b/include/dt-bindings/clock/imx6ul-clock.h index 08ce4a7..fd8aee8 100644 --- a/include/dt-bindings/clock/imx6ul-clock.h +++ b/include/dt-bindings/clock/imx6ul-clock.h @@ -234,7 +234,8 @@ #define IMX6UL_CLK_CSI_SEL 221 #define IMX6UL_CLK_CSI_PODF 222 #define IMX6UL_CLK_PLL3_120M 223 +#define IMX6UL_CLK_KPP 224 -#define IMX6UL_CLK_END 224 +#define IMX6UL_CLK_END 225 #endif /* __DT_BINDINGS_CLOCK_IMX6UL_H */ -- cgit v0.10.2 From 811a498e5e9ab802cbd23a8ef9c844ec92450fa4 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Sun, 28 Feb 2016 15:37:17 +0530 Subject: clk: qcom: Fix pre-divider usage for pixel RCG The clk_rcg_pixel_set_rate clk_op sets up the pre-divider by reading its current value from the NS register. Using the pre-divider wasn't really intended when creating these ops. The pixel RCG was only intended to achieve fractional multiplication provided in the pixel_table array. Leaving the pre-divider to the existing register value results in a wrong pixel clock when the bootloader sets up the display. This was left unidentified because the IFC6410 Plus board on which this was verified didn't have a bootloader that configured the display. Don't set the RCG pre-divider in freq_tbl to the existing NS register value. Force it to 1 and only use the M/N counter to achieve the desired fractional multiplication. Cc: Vinay Simha Signed-off-by: Archit Taneja Tested-by: John Stultz Signed-off-by: Stephen Boyd diff --git a/drivers/clk/qcom/clk-rcg.c b/drivers/clk/qcom/clk-rcg.c index bfbb28f..67ce7c1 100644 --- a/drivers/clk/qcom/clk-rcg.c +++ b/drivers/clk/qcom/clk-rcg.c @@ -638,7 +638,6 @@ static int clk_rcg_pixel_set_rate(struct clk_hw *hw, unsigned long rate, return ret; src = ns_to_src(&rcg->s, ns); - f.pre_div = ns_to_pre_div(&rcg->p, ns) + 1; for (i = 0; i < num_parents; i++) { if (src == rcg->s.parent_map[i].cfg) { @@ -647,6 +646,9 @@ static int clk_rcg_pixel_set_rate(struct clk_hw *hw, unsigned long rate, } } + /* bypass the pre divider */ + f.pre_div = 1; + /* let us find appropriate m/n values for this */ for (; frac->num; frac++) { request = (rate * frac->den) / frac->num; -- cgit v0.10.2 From 21330497f303c55fd6a34d511a98eb0a31aa1bd7 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Fri, 26 Feb 2016 09:35:05 -0800 Subject: clk: ti: Add support for dm814x ADPLL On dm814x we have 13 ADPLLs with 3 to 4 outputs on each. The ADPLLs have several dividers and muxes controlled by a shared control register for each PLL. Note that for the clocks to work as device drivers for booting on dm814x, this patch depends on "ARM: OMAP2+: Change core_initcall levels to postcore_initcall" that has already been merged. Also note that this patch does not implement clk_set_rate for the PLL, that will be posted later on when available. Cc: Stephen Boyd Acked-by: Tero Kristo Signed-off-by: Tony Lindgren Signed-off-by: Michael Turquette diff --git a/Documentation/devicetree/bindings/clock/ti/adpll.txt b/Documentation/devicetree/bindings/clock/ti/adpll.txt new file mode 100644 index 0000000..4c8a2ce --- /dev/null +++ b/Documentation/devicetree/bindings/clock/ti/adpll.txt @@ -0,0 +1,41 @@ +Binding for Texas Instruments ADPLL clock. + +Binding status: Unstable - ABI compatibility may be broken in the future + +This binding uses the common clock binding[1]. It assumes a +register-mapped ADPLL with two to three selectable input clocks +and three to four children. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt + +Required properties: +- compatible : shall be one of "ti,dm814-adpll-s-clock" or + "ti,dm814-adpll-lj-clock" depending on the type of the ADPLL +- #clock-cells : from common clock binding; shall be set to 1. +- clocks : link phandles of parent clocks clkinp and clkinpulow, note + that the adpll-s-clock also has an optional clkinphif +- reg : address and length of the register set for controlling the ADPLL. + +Examples: + adpll_mpu_ck: adpll@40 { + #clock-cells = <1>; + compatible = "ti,dm814-adpll-s-clock"; + reg = <0x40 0x40>; + clocks = <&devosc_ck &devosc_ck &devosc_ck>; + clock-names = "clkinp", "clkinpulow", "clkinphif"; + clock-output-names = "481c5040.adpll.dcoclkldo", + "481c5040.adpll.clkout", + "481c5040.adpll.clkoutx2", + "481c5040.adpll.clkouthif"; + }; + + adpll_dsp_ck: adpll@80 { + #clock-cells = <1>; + compatible = "ti,dm814-adpll-lj-clock"; + reg = <0x80 0x30>; + clocks = <&devosc_ck &devosc_ck>; + clock-names = "clkinp", "clkinpulow"; + clock-output-names = "481c5080.adpll.dcoclkldo", + "481c5080.adpll.clkout", + "481c5080.adpll.clkoutldo"; + }; diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index eca8e01..5bf16cc 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -203,6 +203,7 @@ config COMMON_CLK_CDCE706 source "drivers/clk/bcm/Kconfig" source "drivers/clk/hisilicon/Kconfig" source "drivers/clk/qcom/Kconfig" +source "drivers/clk/ti/Kconfig" endmenu diff --git a/drivers/clk/ti/Kconfig b/drivers/clk/ti/Kconfig new file mode 100644 index 0000000..2713417 --- /dev/null +++ b/drivers/clk/ti/Kconfig @@ -0,0 +1,6 @@ +config COMMON_CLK_TI_ADPLL + tristate "Clock driver for dm814x ADPLL" + depends on ARCH_OMAP2PLUS || COMPILE_TEST + default y if SOC_TI81XX + ---help--- + ADPLL clock driver for the dm814x SoC using common clock framework. diff --git a/drivers/clk/ti/Makefile b/drivers/clk/ti/Makefile index d4ac960..dfe91d7 100644 --- a/drivers/clk/ti/Makefile +++ b/drivers/clk/ti/Makefile @@ -18,3 +18,5 @@ obj-$(CONFIG_SOC_AM43XX) += $(clk-common) dpll3xxx.o clk-43xx.o ifdef CONFIG_ATAGS obj-$(CONFIG_ARCH_OMAP3) += clk-3xxx-legacy.o endif + +obj-$(CONFIG_COMMON_CLK_TI_ADPLL) += adpll.o diff --git a/drivers/clk/ti/adpll.c b/drivers/clk/ti/adpll.c new file mode 100644 index 0000000..f741d79 --- /dev/null +++ b/drivers/clk/ti/adpll.c @@ -0,0 +1,983 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ADPLL_PLLSS_MMR_LOCK_OFFSET 0x00 /* Managed by MPPULL */ +#define ADPLL_PLLSS_MMR_LOCK_ENABLED 0x1f125B64 +#define ADPLL_PLLSS_MMR_UNLOCK_MAGIC 0x1eda4c3d + +#define ADPLL_PWRCTRL_OFFSET 0x00 +#define ADPLL_PWRCTRL_PONIN 5 +#define ADPLL_PWRCTRL_PGOODIN 4 +#define ADPLL_PWRCTRL_RET 3 +#define ADPLL_PWRCTRL_ISORET 2 +#define ADPLL_PWRCTRL_ISOSCAN 1 +#define ADPLL_PWRCTRL_OFFMODE 0 + +#define ADPLL_CLKCTRL_OFFSET 0x04 +#define ADPLL_CLKCTRL_CLKDCOLDOEN 29 +#define ADPLL_CLKCTRL_IDLE 23 +#define ADPLL_CLKCTRL_CLKOUTEN 20 +#define ADPLL_CLKINPHIFSEL_ADPLL_S 19 /* REVISIT: which bit? */ +#define ADPLL_CLKCTRL_CLKOUTLDOEN_ADPLL_LJ 19 +#define ADPLL_CLKCTRL_ULOWCLKEN 18 +#define ADPLL_CLKCTRL_CLKDCOLDOPWDNZ 17 +#define ADPLL_CLKCTRL_M2PWDNZ 16 +#define ADPLL_CLKCTRL_M3PWDNZ_ADPLL_S 15 +#define ADPLL_CLKCTRL_LOWCURRSTDBY_ADPLL_S 13 +#define ADPLL_CLKCTRL_LPMODE_ADPLL_S 12 +#define ADPLL_CLKCTRL_REGM4XEN_ADPLL_S 10 +#define ADPLL_CLKCTRL_SELFREQDCO_ADPLL_LJ 10 +#define ADPLL_CLKCTRL_TINITZ 0 + +#define ADPLL_TENABLE_OFFSET 0x08 +#define ADPLL_TENABLEDIV_OFFSET 0x8c + +#define ADPLL_M2NDIV_OFFSET 0x10 +#define ADPLL_M2NDIV_M2 16 +#define ADPLL_M2NDIV_M2_ADPLL_S_WIDTH 5 +#define ADPLL_M2NDIV_M2_ADPLL_LJ_WIDTH 7 + +#define ADPLL_MN2DIV_OFFSET 0x14 +#define ADPLL_MN2DIV_N2 16 + +#define ADPLL_FRACDIV_OFFSET 0x18 +#define ADPLL_FRACDIV_REGSD 24 +#define ADPLL_FRACDIV_FRACTIONALM 0 +#define ADPLL_FRACDIV_FRACTIONALM_MASK 0x3ffff + +#define ADPLL_BWCTRL_OFFSET 0x1c +#define ADPLL_BWCTRL_BWCONTROL 1 +#define ADPLL_BWCTRL_BW_INCR_DECRZ 0 + +#define ADPLL_RESERVED_OFFSET 0x20 + +#define ADPLL_STATUS_OFFSET 0x24 +#define ADPLL_STATUS_PONOUT 31 +#define ADPLL_STATUS_PGOODOUT 30 +#define ADPLL_STATUS_LDOPWDN 29 +#define ADPLL_STATUS_RECAL_BSTATUS3 28 +#define ADPLL_STATUS_RECAL_OPPIN 27 +#define ADPLL_STATUS_PHASELOCK 10 +#define ADPLL_STATUS_FREQLOCK 9 +#define ADPLL_STATUS_BYPASSACK 8 +#define ADPLL_STATUS_LOSSREF 6 +#define ADPLL_STATUS_CLKOUTENACK 5 +#define ADPLL_STATUS_LOCK2 4 +#define ADPLL_STATUS_M2CHANGEACK 3 +#define ADPLL_STATUS_HIGHJITTER 1 +#define ADPLL_STATUS_BYPASS 0 +#define ADPLL_STATUS_PREPARED_MASK (BIT(ADPLL_STATUS_PHASELOCK) | \ + BIT(ADPLL_STATUS_FREQLOCK)) + +#define ADPLL_M3DIV_OFFSET 0x28 /* Only on MPUPLL */ +#define ADPLL_M3DIV_M3 0 +#define ADPLL_M3DIV_M3_WIDTH 5 +#define ADPLL_M3DIV_M3_MASK 0x1f + +#define ADPLL_RAMPCTRL_OFFSET 0x2c /* Only on MPUPLL */ +#define ADPLL_RAMPCTRL_CLKRAMPLEVEL 19 +#define ADPLL_RAMPCTRL_CLKRAMPRATE 16 +#define ADPLL_RAMPCTRL_RELOCK_RAMP_EN 0 + +#define MAX_ADPLL_INPUTS 3 +#define MAX_ADPLL_OUTPUTS 4 +#define ADPLL_MAX_RETRIES 5 + +#define to_dco(_hw) container_of(_hw, struct ti_adpll_dco_data, hw) +#define to_adpll(_hw) container_of(_hw, struct ti_adpll_data, dco) +#define to_clkout(_hw) container_of(_hw, struct ti_adpll_clkout_data, hw) + +enum ti_adpll_clocks { + TI_ADPLL_DCO, + TI_ADPLL_DCO_GATE, + TI_ADPLL_N2, + TI_ADPLL_M2, + TI_ADPLL_M2_GATE, + TI_ADPLL_BYPASS, + TI_ADPLL_HIF, + TI_ADPLL_DIV2, + TI_ADPLL_CLKOUT, + TI_ADPLL_CLKOUT2, + TI_ADPLL_M3, +}; + +#define TI_ADPLL_NR_CLOCKS (TI_ADPLL_M3 + 1) + +enum ti_adpll_inputs { + TI_ADPLL_CLKINP, + TI_ADPLL_CLKINPULOW, + TI_ADPLL_CLKINPHIF, +}; + +enum ti_adpll_s_outputs { + TI_ADPLL_S_DCOCLKLDO, + TI_ADPLL_S_CLKOUT, + TI_ADPLL_S_CLKOUTX2, + TI_ADPLL_S_CLKOUTHIF, +}; + +enum ti_adpll_lj_outputs { + TI_ADPLL_LJ_CLKDCOLDO, + TI_ADPLL_LJ_CLKOUT, + TI_ADPLL_LJ_CLKOUTLDO, +}; + +struct ti_adpll_platform_data { + const bool is_type_s; + const int nr_max_inputs; + const int nr_max_outputs; + const int output_index; +}; + +struct ti_adpll_clock { + struct clk *clk; + struct clk_lookup *cl; + void (*unregister)(struct clk *clk); +}; + +struct ti_adpll_dco_data { + struct clk_hw hw; +}; + +struct ti_adpll_clkout_data { + struct ti_adpll_data *adpll; + struct clk_gate gate; + struct clk_hw hw; +}; + +struct ti_adpll_data { + struct device *dev; + const struct ti_adpll_platform_data *c; + struct device_node *np; + unsigned long pa; + void __iomem *iobase; + void __iomem *regs; + spinlock_t lock; /* For ADPLL shared register access */ + const char *parent_names[MAX_ADPLL_INPUTS]; + struct clk *parent_clocks[MAX_ADPLL_INPUTS]; + struct ti_adpll_clock *clocks; + struct clk_onecell_data outputs; + struct ti_adpll_dco_data dco; +}; + +static const char *ti_adpll_clk_get_name(struct ti_adpll_data *d, + int output_index, + const char *postfix) +{ + const char *name; + int err; + + if (output_index >= 0) { + err = of_property_read_string_index(d->np, + "clock-output-names", + output_index, + &name); + if (err) + return NULL; + } else { + const char *base_name = "adpll"; + char *buf; + + buf = devm_kzalloc(d->dev, 8 + 1 + strlen(base_name) + 1 + + strlen(postfix), GFP_KERNEL); + if (!buf) + return NULL; + sprintf(buf, "%08lx.%s.%s", d->pa, base_name, postfix); + name = buf; + } + + return name; +} + +#define ADPLL_MAX_CON_ID 16 /* See MAX_CON_ID */ + +static int ti_adpll_setup_clock(struct ti_adpll_data *d, struct clk *clock, + int index, int output_index, const char *name, + void (*unregister)(struct clk *clk)) +{ + struct clk_lookup *cl; + const char *postfix = NULL; + char con_id[ADPLL_MAX_CON_ID]; + + d->clocks[index].clk = clock; + d->clocks[index].unregister = unregister; + + /* Separate con_id in format "pll040dcoclkldo" to fit MAX_CON_ID */ + postfix = strrchr(name, '.'); + if (strlen(postfix) > 1) { + if (strlen(postfix) > ADPLL_MAX_CON_ID) + dev_warn(d->dev, "clock %s con_id lookup may fail\n", + name); + snprintf(con_id, 16, "pll%03lx%s", d->pa & 0xfff, postfix + 1); + cl = clkdev_create(clock, con_id, NULL); + if (!cl) + return -ENOMEM; + d->clocks[index].cl = cl; + } else { + dev_warn(d->dev, "no con_id for clock %s\n", name); + } + + if (output_index < 0) + return 0; + + d->outputs.clks[output_index] = clock; + d->outputs.clk_num++; + + return 0; +} + +static int ti_adpll_init_divider(struct ti_adpll_data *d, + enum ti_adpll_clocks index, + int output_index, char *name, + struct clk *parent_clock, + void __iomem *reg, + u8 shift, u8 width, + u8 clk_divider_flags) +{ + const char *child_name; + const char *parent_name; + struct clk *clock; + + child_name = ti_adpll_clk_get_name(d, output_index, name); + if (!child_name) + return -EINVAL; + + parent_name = __clk_get_name(parent_clock); + clock = clk_register_divider(d->dev, child_name, parent_name, 0, + reg, shift, width, clk_divider_flags, + &d->lock); + if (IS_ERR(clock)) { + dev_err(d->dev, "failed to register divider %s: %li\n", + name, PTR_ERR(clock)); + return PTR_ERR(clock); + } + + return ti_adpll_setup_clock(d, clock, index, output_index, child_name, + clk_unregister_divider); +} + +static int ti_adpll_init_mux(struct ti_adpll_data *d, + enum ti_adpll_clocks index, + char *name, struct clk *clk0, + struct clk *clk1, + void __iomem *reg, + u8 shift) +{ + const char *child_name; + const char *parents[2]; + struct clk *clock; + + child_name = ti_adpll_clk_get_name(d, -ENODEV, name); + if (!child_name) + return -ENOMEM; + parents[0] = __clk_get_name(clk0); + parents[1] = __clk_get_name(clk1); + clock = clk_register_mux(d->dev, child_name, parents, 2, 0, + reg, shift, 1, 0, &d->lock); + if (IS_ERR(clock)) { + dev_err(d->dev, "failed to register mux %s: %li\n", + name, PTR_ERR(clock)); + return PTR_ERR(clock); + } + + return ti_adpll_setup_clock(d, clock, index, -ENODEV, child_name, + clk_unregister_mux); +} + +static int ti_adpll_init_gate(struct ti_adpll_data *d, + enum ti_adpll_clocks index, + int output_index, char *name, + struct clk *parent_clock, + void __iomem *reg, + u8 bit_idx, + u8 clk_gate_flags) +{ + const char *child_name; + const char *parent_name; + struct clk *clock; + + child_name = ti_adpll_clk_get_name(d, output_index, name); + if (!child_name) + return -EINVAL; + + parent_name = __clk_get_name(parent_clock); + clock = clk_register_gate(d->dev, child_name, parent_name, 0, + reg, bit_idx, clk_gate_flags, + &d->lock); + if (IS_ERR(clock)) { + dev_err(d->dev, "failed to register gate %s: %li\n", + name, PTR_ERR(clock)); + return PTR_ERR(clock); + } + + return ti_adpll_setup_clock(d, clock, index, output_index, child_name, + clk_unregister_gate); +} + +static int ti_adpll_init_fixed_factor(struct ti_adpll_data *d, + enum ti_adpll_clocks index, + char *name, + struct clk *parent_clock, + unsigned int mult, + unsigned int div) +{ + const char *child_name; + const char *parent_name; + struct clk *clock; + + child_name = ti_adpll_clk_get_name(d, -ENODEV, name); + if (!child_name) + return -ENOMEM; + + parent_name = __clk_get_name(parent_clock); + clock = clk_register_fixed_factor(d->dev, child_name, parent_name, + 0, mult, div); + if (IS_ERR(clock)) + return PTR_ERR(clock); + + return ti_adpll_setup_clock(d, clock, index, -ENODEV, child_name, + clk_unregister); +} + +static void ti_adpll_set_idle_bypass(struct ti_adpll_data *d) +{ + unsigned long flags; + u32 v; + + spin_lock_irqsave(&d->lock, flags); + v = readl_relaxed(d->regs + ADPLL_CLKCTRL_OFFSET); + v |= BIT(ADPLL_CLKCTRL_IDLE); + writel_relaxed(v, d->regs + ADPLL_CLKCTRL_OFFSET); + spin_unlock_irqrestore(&d->lock, flags); +} + +static void ti_adpll_clear_idle_bypass(struct ti_adpll_data *d) +{ + unsigned long flags; + u32 v; + + spin_lock_irqsave(&d->lock, flags); + v = readl_relaxed(d->regs + ADPLL_CLKCTRL_OFFSET); + v &= ~BIT(ADPLL_CLKCTRL_IDLE); + writel_relaxed(v, d->regs + ADPLL_CLKCTRL_OFFSET); + spin_unlock_irqrestore(&d->lock, flags); +} + +static bool ti_adpll_clock_is_bypass(struct ti_adpll_data *d) +{ + u32 v; + + v = readl_relaxed(d->regs + ADPLL_STATUS_OFFSET); + + return v & BIT(ADPLL_STATUS_BYPASS); +} + +/* + * Locked and bypass are not actually mutually exclusive: if you only care + * about the DCO clock and not CLKOUT you can clear M2PWDNZ before enabling + * the PLL, resulting in status (FREQLOCK | PHASELOCK | BYPASS) after lock. + */ +static bool ti_adpll_is_locked(struct ti_adpll_data *d) +{ + u32 v = readl_relaxed(d->regs + ADPLL_STATUS_OFFSET); + + return (v & ADPLL_STATUS_PREPARED_MASK) == ADPLL_STATUS_PREPARED_MASK; +} + +static int ti_adpll_wait_lock(struct ti_adpll_data *d) +{ + int retries = ADPLL_MAX_RETRIES; + + do { + if (ti_adpll_is_locked(d)) + return 0; + usleep_range(200, 300); + } while (retries--); + + dev_err(d->dev, "pll failed to lock\n"); + return -ETIMEDOUT; +} + +static int ti_adpll_prepare(struct clk_hw *hw) +{ + struct ti_adpll_dco_data *dco = to_dco(hw); + struct ti_adpll_data *d = to_adpll(dco); + + ti_adpll_clear_idle_bypass(d); + ti_adpll_wait_lock(d); + + return 0; +} + +static void ti_adpll_unprepare(struct clk_hw *hw) +{ + struct ti_adpll_dco_data *dco = to_dco(hw); + struct ti_adpll_data *d = to_adpll(dco); + + ti_adpll_set_idle_bypass(d); +} + +static int ti_adpll_is_prepared(struct clk_hw *hw) +{ + struct ti_adpll_dco_data *dco = to_dco(hw); + struct ti_adpll_data *d = to_adpll(dco); + + return ti_adpll_is_locked(d); +} + +/* + * Note that the DCO clock is never subject to bypass: if the PLL is off, + * dcoclk is low. + */ +static unsigned long ti_adpll_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct ti_adpll_dco_data *dco = to_dco(hw); + struct ti_adpll_data *d = to_adpll(dco); + u32 frac_m, divider, v; + u64 rate; + unsigned long flags; + + if (ti_adpll_clock_is_bypass(d)) + return 0; + + spin_lock_irqsave(&d->lock, flags); + frac_m = readl_relaxed(d->regs + ADPLL_FRACDIV_OFFSET); + frac_m &= ADPLL_FRACDIV_FRACTIONALM_MASK; + rate = readw_relaxed(d->regs + ADPLL_MN2DIV_OFFSET) << 18; + rate += frac_m; + rate *= parent_rate; + divider = (readw_relaxed(d->regs + ADPLL_M2NDIV_OFFSET) + 1) << 18; + spin_unlock_irqrestore(&d->lock, flags); + + do_div(rate, divider); + + if (d->c->is_type_s) { + v = readl_relaxed(d->regs + ADPLL_CLKCTRL_OFFSET); + if (v & BIT(ADPLL_CLKCTRL_REGM4XEN_ADPLL_S)) + rate *= 4; + rate *= 2; + } + + return rate; +} + +/* PLL parent is always clkinp, bypass only affects the children */ +static u8 ti_adpll_get_parent(struct clk_hw *hw) +{ + return 0; +} + +static struct clk_ops ti_adpll_ops = { + .prepare = ti_adpll_prepare, + .unprepare = ti_adpll_unprepare, + .is_prepared = ti_adpll_is_prepared, + .recalc_rate = ti_adpll_recalc_rate, + .get_parent = ti_adpll_get_parent, +}; + +static int ti_adpll_init_dco(struct ti_adpll_data *d) +{ + struct clk_init_data init; + struct clk *clock; + const char *postfix; + int width, err; + + d->outputs.clks = devm_kzalloc(d->dev, sizeof(struct clk *) * + MAX_ADPLL_OUTPUTS, + GFP_KERNEL); + if (!d->outputs.clks) + return -ENOMEM; + + if (d->c->output_index < 0) + postfix = "dco"; + else + postfix = NULL; + + init.name = ti_adpll_clk_get_name(d, d->c->output_index, postfix); + if (!init.name) + return -EINVAL; + + init.parent_names = d->parent_names; + init.num_parents = d->c->nr_max_inputs; + init.ops = &ti_adpll_ops; + init.flags = CLK_GET_RATE_NOCACHE; + d->dco.hw.init = &init; + + if (d->c->is_type_s) + width = 5; + else + width = 4; + + /* Internal input clock divider N2 */ + err = ti_adpll_init_divider(d, TI_ADPLL_N2, -ENODEV, "n2", + d->parent_clocks[TI_ADPLL_CLKINP], + d->regs + ADPLL_MN2DIV_OFFSET, + ADPLL_MN2DIV_N2, width, 0); + if (err) + return err; + + clock = devm_clk_register(d->dev, &d->dco.hw); + if (IS_ERR(clock)) + return PTR_ERR(clock); + + return ti_adpll_setup_clock(d, clock, TI_ADPLL_DCO, d->c->output_index, + init.name, NULL); +} + +static int ti_adpll_clkout_enable(struct clk_hw *hw) +{ + struct ti_adpll_clkout_data *co = to_clkout(hw); + struct clk_hw *gate_hw = &co->gate.hw; + + __clk_hw_set_clk(gate_hw, hw); + + return clk_gate_ops.enable(gate_hw); +} + +static void ti_adpll_clkout_disable(struct clk_hw *hw) +{ + struct ti_adpll_clkout_data *co = to_clkout(hw); + struct clk_hw *gate_hw = &co->gate.hw; + + __clk_hw_set_clk(gate_hw, hw); + clk_gate_ops.disable(gate_hw); +} + +static int ti_adpll_clkout_is_enabled(struct clk_hw *hw) +{ + struct ti_adpll_clkout_data *co = to_clkout(hw); + struct clk_hw *gate_hw = &co->gate.hw; + + __clk_hw_set_clk(gate_hw, hw); + + return clk_gate_ops.is_enabled(gate_hw); +} + +/* Setting PLL bypass puts clkout and clkoutx2 into bypass */ +static u8 ti_adpll_clkout_get_parent(struct clk_hw *hw) +{ + struct ti_adpll_clkout_data *co = to_clkout(hw); + struct ti_adpll_data *d = co->adpll; + + return ti_adpll_clock_is_bypass(d); +} + +static int ti_adpll_init_clkout(struct ti_adpll_data *d, + enum ti_adpll_clocks index, + int output_index, int gate_bit, + char *name, struct clk *clk0, + struct clk *clk1) +{ + struct ti_adpll_clkout_data *co; + struct clk_init_data init; + struct clk_ops *ops; + const char *parent_names[2]; + const char *child_name; + struct clk *clock; + int err; + + co = devm_kzalloc(d->dev, sizeof(*co), GFP_KERNEL); + if (!co) + return -ENOMEM; + co->adpll = d; + + err = of_property_read_string_index(d->np, + "clock-output-names", + output_index, + &child_name); + if (err) + return err; + + ops = devm_kzalloc(d->dev, sizeof(*ops), GFP_KERNEL); + if (!ops) + return -ENOMEM; + + init.name = child_name; + init.ops = ops; + init.flags = CLK_IS_BASIC; + co->hw.init = &init; + parent_names[0] = __clk_get_name(clk0); + parent_names[1] = __clk_get_name(clk1); + init.parent_names = parent_names; + init.num_parents = 2; + + ops->get_parent = ti_adpll_clkout_get_parent; + ops->determine_rate = __clk_mux_determine_rate; + if (gate_bit) { + co->gate.lock = &d->lock; + co->gate.reg = d->regs + ADPLL_CLKCTRL_OFFSET; + co->gate.bit_idx = gate_bit; + ops->enable = ti_adpll_clkout_enable; + ops->disable = ti_adpll_clkout_disable; + ops->is_enabled = ti_adpll_clkout_is_enabled; + } + + clock = devm_clk_register(d->dev, &co->hw); + if (IS_ERR(clock)) { + dev_err(d->dev, "failed to register output %s: %li\n", + name, PTR_ERR(clock)); + return PTR_ERR(clock); + } + + return ti_adpll_setup_clock(d, clock, index, output_index, child_name, + NULL); +} + +static int ti_adpll_init_children_adpll_s(struct ti_adpll_data *d) +{ + int err; + + if (!d->c->is_type_s) + return 0; + + /* Internal mux, sources from divider N2 or clkinpulow */ + err = ti_adpll_init_mux(d, TI_ADPLL_BYPASS, "bypass", + d->clocks[TI_ADPLL_N2].clk, + d->parent_clocks[TI_ADPLL_CLKINPULOW], + d->regs + ADPLL_CLKCTRL_OFFSET, + ADPLL_CLKCTRL_ULOWCLKEN); + if (err) + return err; + + /* Internal divider M2, sources DCO */ + err = ti_adpll_init_divider(d, TI_ADPLL_M2, -ENODEV, "m2", + d->clocks[TI_ADPLL_DCO].clk, + d->regs + ADPLL_M2NDIV_OFFSET, + ADPLL_M2NDIV_M2, + ADPLL_M2NDIV_M2_ADPLL_S_WIDTH, + CLK_DIVIDER_ONE_BASED); + if (err) + return err; + + /* Internal fixed divider, after M2 before clkout */ + err = ti_adpll_init_fixed_factor(d, TI_ADPLL_DIV2, "div2", + d->clocks[TI_ADPLL_M2].clk, + 1, 2); + if (err) + return err; + + /* Output clkout with a mux and gate, sources from div2 or bypass */ + err = ti_adpll_init_clkout(d, TI_ADPLL_CLKOUT, TI_ADPLL_S_CLKOUT, + ADPLL_CLKCTRL_CLKOUTEN, "clkout", + d->clocks[TI_ADPLL_DIV2].clk, + d->clocks[TI_ADPLL_BYPASS].clk); + if (err) + return err; + + /* Output clkoutx2 with a mux and gate, sources from M2 or bypass */ + err = ti_adpll_init_clkout(d, TI_ADPLL_CLKOUT2, TI_ADPLL_S_CLKOUTX2, 0, + "clkout2", d->clocks[TI_ADPLL_M2].clk, + d->clocks[TI_ADPLL_BYPASS].clk); + if (err) + return err; + + /* Internal mux, sources from DCO and clkinphif */ + if (d->parent_clocks[TI_ADPLL_CLKINPHIF]) { + err = ti_adpll_init_mux(d, TI_ADPLL_HIF, "hif", + d->clocks[TI_ADPLL_DCO].clk, + d->parent_clocks[TI_ADPLL_CLKINPHIF], + d->regs + ADPLL_CLKCTRL_OFFSET, + ADPLL_CLKINPHIFSEL_ADPLL_S); + if (err) + return err; + } + + /* Output clkouthif with a divider M3, sources from hif */ + err = ti_adpll_init_divider(d, TI_ADPLL_M3, TI_ADPLL_S_CLKOUTHIF, "m3", + d->clocks[TI_ADPLL_HIF].clk, + d->regs + ADPLL_M3DIV_OFFSET, + ADPLL_M3DIV_M3, + ADPLL_M3DIV_M3_WIDTH, + CLK_DIVIDER_ONE_BASED); + if (err) + return err; + + /* Output clock dcoclkldo is the DCO */ + + return 0; +} + +static int ti_adpll_init_children_adpll_lj(struct ti_adpll_data *d) +{ + int err; + + if (d->c->is_type_s) + return 0; + + /* Output clkdcoldo, gated output of DCO */ + err = ti_adpll_init_gate(d, TI_ADPLL_DCO_GATE, TI_ADPLL_LJ_CLKDCOLDO, + "clkdcoldo", d->clocks[TI_ADPLL_DCO].clk, + d->regs + ADPLL_CLKCTRL_OFFSET, + ADPLL_CLKCTRL_CLKDCOLDOEN, 0); + if (err) + return err; + + /* Internal divider M2, sources from DCO */ + err = ti_adpll_init_divider(d, TI_ADPLL_M2, -ENODEV, + "m2", d->clocks[TI_ADPLL_DCO].clk, + d->regs + ADPLL_M2NDIV_OFFSET, + ADPLL_M2NDIV_M2, + ADPLL_M2NDIV_M2_ADPLL_LJ_WIDTH, + CLK_DIVIDER_ONE_BASED); + if (err) + return err; + + /* Output clkoutldo, gated output of M2 */ + err = ti_adpll_init_gate(d, TI_ADPLL_M2_GATE, TI_ADPLL_LJ_CLKOUTLDO, + "clkoutldo", d->clocks[TI_ADPLL_M2].clk, + d->regs + ADPLL_CLKCTRL_OFFSET, + ADPLL_CLKCTRL_CLKOUTLDOEN_ADPLL_LJ, + 0); + if (err) + return err; + + /* Internal mux, sources from divider N2 or clkinpulow */ + err = ti_adpll_init_mux(d, TI_ADPLL_BYPASS, "bypass", + d->clocks[TI_ADPLL_N2].clk, + d->parent_clocks[TI_ADPLL_CLKINPULOW], + d->regs + ADPLL_CLKCTRL_OFFSET, + ADPLL_CLKCTRL_ULOWCLKEN); + if (err) + return err; + + /* Output clkout, sources M2 or bypass */ + err = ti_adpll_init_clkout(d, TI_ADPLL_CLKOUT, TI_ADPLL_S_CLKOUT, + ADPLL_CLKCTRL_CLKOUTEN, "clkout", + d->clocks[TI_ADPLL_M2].clk, + d->clocks[TI_ADPLL_BYPASS].clk); + if (err) + return err; + + return 0; +} + +static void ti_adpll_free_resources(struct ti_adpll_data *d) +{ + int i; + + for (i = TI_ADPLL_M3; i >= 0; i--) { + struct ti_adpll_clock *ac = &d->clocks[i]; + + if (!ac || IS_ERR_OR_NULL(ac->clk)) + continue; + if (ac->cl) + clkdev_drop(ac->cl); + if (ac->unregister) + ac->unregister(ac->clk); + } +} + +/* MPU PLL manages the lock register for all PLLs */ +static void ti_adpll_unlock_all(void __iomem *reg) +{ + u32 v; + + v = readl_relaxed(reg); + if (v == ADPLL_PLLSS_MMR_LOCK_ENABLED) + writel_relaxed(ADPLL_PLLSS_MMR_UNLOCK_MAGIC, reg); +} + +static int ti_adpll_init_registers(struct ti_adpll_data *d) +{ + int register_offset = 0; + + if (d->c->is_type_s) { + register_offset = 8; + ti_adpll_unlock_all(d->iobase + ADPLL_PLLSS_MMR_LOCK_OFFSET); + } + + d->regs = d->iobase + register_offset + ADPLL_PWRCTRL_OFFSET; + + return 0; +} + +static int ti_adpll_init_inputs(struct ti_adpll_data *d) +{ + const char *error = "need at least %i inputs"; + struct clk *clock; + int nr_inputs; + + nr_inputs = of_clk_get_parent_count(d->np); + if (nr_inputs < d->c->nr_max_inputs) { + dev_err(d->dev, error, nr_inputs); + return -EINVAL; + } + of_clk_parent_fill(d->np, d->parent_names, nr_inputs); + + clock = devm_clk_get(d->dev, d->parent_names[0]); + if (IS_ERR(clock)) { + dev_err(d->dev, "could not get clkinp\n"); + return PTR_ERR(clock); + } + d->parent_clocks[TI_ADPLL_CLKINP] = clock; + + clock = devm_clk_get(d->dev, d->parent_names[1]); + if (IS_ERR(clock)) { + dev_err(d->dev, "could not get clkinpulow clock\n"); + return PTR_ERR(clock); + } + d->parent_clocks[TI_ADPLL_CLKINPULOW] = clock; + + if (d->c->is_type_s) { + clock = devm_clk_get(d->dev, d->parent_names[2]); + if (IS_ERR(clock)) { + dev_err(d->dev, "could not get clkinphif clock\n"); + return PTR_ERR(clock); + } + d->parent_clocks[TI_ADPLL_CLKINPHIF] = clock; + } + + return 0; +} + +static const struct ti_adpll_platform_data ti_adpll_type_s = { + .is_type_s = true, + .nr_max_inputs = MAX_ADPLL_INPUTS, + .nr_max_outputs = MAX_ADPLL_OUTPUTS, + .output_index = TI_ADPLL_S_DCOCLKLDO, +}; + +static const struct ti_adpll_platform_data ti_adpll_type_lj = { + .is_type_s = false, + .nr_max_inputs = MAX_ADPLL_INPUTS - 1, + .nr_max_outputs = MAX_ADPLL_OUTPUTS - 1, + .output_index = -EINVAL, +}; + +static const struct of_device_id ti_adpll_match[] = { + { .compatible = "ti,dm814-adpll-s-clock", &ti_adpll_type_s }, + { .compatible = "ti,dm814-adpll-lj-clock", &ti_adpll_type_lj }, + {}, +}; +MODULE_DEVICE_TABLE(of, ti_adpll_match); + +static int ti_adpll_probe(struct platform_device *pdev) +{ + struct device_node *node = pdev->dev.of_node; + struct device *dev = &pdev->dev; + const struct of_device_id *match; + const struct ti_adpll_platform_data *pdata; + struct ti_adpll_data *d; + struct resource *res; + int err; + + match = of_match_device(ti_adpll_match, dev); + if (match) + pdata = match->data; + else + return -ENODEV; + + d = devm_kzalloc(dev, sizeof(*d), GFP_KERNEL); + if (!d) + return -ENOMEM; + d->dev = dev; + d->np = node; + d->c = pdata; + dev_set_drvdata(d->dev, d); + spin_lock_init(&d->lock); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + d->pa = res->start; + + d->iobase = devm_ioremap_resource(dev, res); + if (IS_ERR(d->iobase)) { + dev_err(dev, "could not get IO base: %li\n", + PTR_ERR(d->iobase)); + return PTR_ERR(d->iobase); + } + + err = ti_adpll_init_registers(d); + if (err) + return err; + + err = ti_adpll_init_inputs(d); + if (err) + return err; + + d->clocks = devm_kzalloc(d->dev, sizeof(struct ti_adpll_clock) * + TI_ADPLL_NR_CLOCKS, + GFP_KERNEL); + if (!d->clocks) + goto free; + + err = ti_adpll_init_dco(d); + if (err) { + dev_err(dev, "could not register dco: %i\n", err); + goto free; + } + + err = ti_adpll_init_children_adpll_s(d); + if (err) + goto free; + err = ti_adpll_init_children_adpll_lj(d); + if (err) + goto free; + + err = of_clk_add_provider(d->np, of_clk_src_onecell_get, &d->outputs); + if (err) + goto free; + + return 0; + +free: + WARN_ON(1); + ti_adpll_free_resources(d); + + return err; +} + +static int ti_adpll_remove(struct platform_device *pdev) +{ + struct ti_adpll_data *d = dev_get_drvdata(&pdev->dev); + + ti_adpll_free_resources(d); + + return 0; +} + +static struct platform_driver ti_adpll_driver = { + .driver = { + .name = "ti-adpll", + .of_match_table = ti_adpll_match, + }, + .probe = ti_adpll_probe, + .remove = ti_adpll_remove, +}; + +static int __init ti_adpll_init(void) +{ + return platform_driver_register(&ti_adpll_driver); +} +core_initcall(ti_adpll_init); + +static void __exit ti_adpll_exit(void) +{ + platform_driver_unregister(&ti_adpll_driver); +} +module_exit(ti_adpll_exit); + +MODULE_DESCRIPTION("Clock driver for dm814x ADPLL"); +MODULE_ALIAS("platform:dm814-adpll-clock"); +MODULE_AUTHOR("Tony LIndgren "); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/ti/clk-814x.c b/drivers/clk/ti/clk-814x.c index 9e85fcc..2323643 100644 --- a/drivers/clk/ti/clk-814x.c +++ b/drivers/clk/ti/clk-814x.c @@ -5,8 +5,10 @@ */ #include +#include #include #include +#include #include "clock.h" @@ -27,11 +29,62 @@ static struct ti_dt_clk dm814_clks[] = { { .node_name = NULL }, }; +static bool timer_clocks_initialized; + +int __init dm814x_adpll_early_init(void) +{ + struct device_node *np; + + if (!timer_clocks_initialized) + return -ENODEV; + + np = of_find_node_by_name(NULL, "pllss"); + if (!np) { + pr_err("Could not find node for plls\n"); + return -ENODEV; + } + + of_platform_populate(np, NULL, NULL, NULL); + + return 0; +} +core_initcall(dm814x_adpll_early_init); + +static const char * const init_clocks[] = { + "pll040clkout", /* MPU 481c5040.adpll.clkout */ + "pll290clkout", /* DDR 481c5290.adpll.clkout */ +}; + +int __init dm814x_adpll_enable_init_clocks(void) +{ + int i, err; + + if (!timer_clocks_initialized) + return -ENODEV; + + for (i = 0; i < ARRAY_SIZE(init_clocks); i++) { + struct clk *clock; + + clock = clk_get(NULL, init_clocks[i]); + if (WARN(IS_ERR(clock), "could not find init clock %s\n", + init_clocks[i])) + continue; + err = clk_prepare_enable(clock); + if (WARN(err, "could not enable init clock %s\n", + init_clocks[i])) + continue; + } + + return 0; +} +postcore_initcall(dm814x_adpll_enable_init_clocks); + int __init dm814x_dt_clk_init(void) { ti_dt_clocks_register(dm814_clks); omap2_clk_disable_autoidle_all(); omap2_clk_enable_init_clocks(NULL, 0); + timer_clocks_initialized = true; return 0; } -- cgit v0.10.2 From c2ee9bdc852dcd1f2f3a6adaa986f14441a673f3 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Fri, 26 Feb 2016 09:45:03 -0800 Subject: clk: ti: Allow COMPILE_TEST to build selected drivers The arch independent drivers can be build testeed with COMPILE_TEST. Let's allow that for drivers/clk/ti. Signed-off-by: Tony Lindgren Signed-off-by: Michael Turquette diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index b038e36..45939a1 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -78,7 +78,7 @@ obj-$(CONFIG_PLAT_SPEAR) += spear/ obj-$(CONFIG_ARCH_STI) += st/ obj-$(CONFIG_ARCH_SUNXI) += sunxi/ obj-$(CONFIG_ARCH_TEGRA) += tegra/ -obj-$(CONFIG_ARCH_OMAP2PLUS) += ti/ +obj-y += ti/ obj-$(CONFIG_ARCH_U8500) += ux500/ obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/ obj-$(CONFIG_X86) += x86/ diff --git a/drivers/clk/ti/Makefile b/drivers/clk/ti/Makefile index dfe91d7..0deac98 100644 --- a/drivers/clk/ti/Makefile +++ b/drivers/clk/ti/Makefile @@ -1,3 +1,5 @@ +ifeq ($(CONFIG_ARCH_OMAP2PLUS), y) + obj-y += clk.o autoidle.o clockdomain.o clk-common = dpll.o composite.o divider.o gate.o \ fixed-factor.o mux.o apll.o \ @@ -19,4 +21,6 @@ ifdef CONFIG_ATAGS obj-$(CONFIG_ARCH_OMAP3) += clk-3xxx-legacy.o endif +endif # CONFIG_ARCH_OMAP2PLUS + obj-$(CONFIG_COMMON_CLK_TI_ADPLL) += adpll.o -- cgit v0.10.2 From 8a8b6eb7a87f12804f44128d6e4c59b19f224308 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 1 Mar 2016 10:51:42 -0800 Subject: clk: ti: Fix some errors found by static checkers drivers/clk/ti/clk-814x.c:34:12: warning: symbol 'dm814x_adpll_early_init' was not declared. Should it be static? drivers/clk/ti/clk-814x.c:58:12: warning: symbol 'dm814x_adpll_enable_init_clocks' was not declared. Should it be static? drivers/clk/ti/adpll.c:465 ti_adpll_recalc_rate() warn: should '__readw(d->regs + 20) << 18' be a 64 bit type? drivers/clk/ti/adpll.c:945 ti_adpll_probe() error: we previously assumed 'd->clocks' could be null (see line 921) The last one looks like a real bug because we don't return an error on allocation failure. Cc: Tero Kristo Tested-by: Tony Lindgren Signed-off-by: Stephen Boyd diff --git a/drivers/clk/ti/adpll.c b/drivers/clk/ti/adpll.c index f741d79..255cafb 100644 --- a/drivers/clk/ti/adpll.c +++ b/drivers/clk/ti/adpll.c @@ -462,7 +462,7 @@ static unsigned long ti_adpll_recalc_rate(struct clk_hw *hw, spin_lock_irqsave(&d->lock, flags); frac_m = readl_relaxed(d->regs + ADPLL_FRACDIV_OFFSET); frac_m &= ADPLL_FRACDIV_FRACTIONALM_MASK; - rate = readw_relaxed(d->regs + ADPLL_MN2DIV_OFFSET) << 18; + rate = (u64)readw_relaxed(d->regs + ADPLL_MN2DIV_OFFSET) << 18; rate += frac_m; rate *= parent_rate; divider = (readw_relaxed(d->regs + ADPLL_M2NDIV_OFFSET) + 1) << 18; @@ -919,7 +919,7 @@ static int ti_adpll_probe(struct platform_device *pdev) TI_ADPLL_NR_CLOCKS, GFP_KERNEL); if (!d->clocks) - goto free; + return -ENOMEM; err = ti_adpll_init_dco(d); if (err) { diff --git a/drivers/clk/ti/clk-814x.c b/drivers/clk/ti/clk-814x.c index 2323643..52c6efc 100644 --- a/drivers/clk/ti/clk-814x.c +++ b/drivers/clk/ti/clk-814x.c @@ -31,7 +31,7 @@ static struct ti_dt_clk dm814_clks[] = { static bool timer_clocks_initialized; -int __init dm814x_adpll_early_init(void) +static int __init dm814x_adpll_early_init(void) { struct device_node *np; @@ -55,7 +55,7 @@ static const char * const init_clocks[] = { "pll290clkout", /* DDR 481c5290.adpll.clkout */ }; -int __init dm814x_adpll_enable_init_clocks(void) +static int __init dm814x_adpll_enable_init_clocks(void) { int i, err; -- cgit v0.10.2 From 0f75e1a370fd843c9e508fc1ccf0662833034827 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 1 Mar 2016 17:26:48 -0800 Subject: clk: qcom: msm8960: Fix ce3_src register offset The offset seems to have been copied from the sata clk. Fix it so that enabling the crypto engine source clk works. Tested-by: Srinivas Kandagatla Tested-by: Bjorn Andersson Fixes: 5f775498bdc4 ("clk: qcom: Fully support apq8064 global clock control") Signed-off-by: Stephen Boyd diff --git a/drivers/clk/qcom/gcc-msm8960.c b/drivers/clk/qcom/gcc-msm8960.c index 63ecd97..0a0c1f5 100644 --- a/drivers/clk/qcom/gcc-msm8960.c +++ b/drivers/clk/qcom/gcc-msm8960.c @@ -2753,7 +2753,7 @@ static struct clk_rcg ce3_src = { }, .freq_tbl = clk_tbl_ce3, .clkr = { - .enable_reg = 0x2c08, + .enable_reg = 0x36c0, .enable_mask = BIT(7), .hw.init = &(struct clk_init_data){ .name = "ce3_src", -- cgit v0.10.2 From bd41aa677314f08693c50e6746d1e23c7722bb61 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 1 Mar 2016 10:59:47 -0800 Subject: clk: bcm: Remove CLK_IS_ROOT This flag is a no-op now. Remove usage of the flag. Cc: Lee Jones Reviewed-by: Eric Anholt Signed-off-by: Stephen Boyd diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 5747a9d..c74ed3f 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -324,21 +324,18 @@ void __init bcm2835_init_clocks(void) struct clk *clk; int ret; - clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, - 126000000); + clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, 0, 126000000); if (IS_ERR(clk)) pr_err("apb_pclk not registered\n"); - clk = clk_register_fixed_rate(NULL, "uart0_pclk", NULL, CLK_IS_ROOT, - 3000000); + clk = clk_register_fixed_rate(NULL, "uart0_pclk", NULL, 0, 3000000); if (IS_ERR(clk)) pr_err("uart0_pclk not registered\n"); ret = clk_register_clkdev(clk, NULL, "20201000.uart"); if (ret) pr_err("uart0_pclk alias not registered\n"); - clk = clk_register_fixed_rate(NULL, "uart1_pclk", NULL, CLK_IS_ROOT, - 125000000); + clk = clk_register_fixed_rate(NULL, "uart1_pclk", NULL, 0, 125000000); if (IS_ERR(clk)) pr_err("uart1_pclk not registered\n"); ret = clk_register_clkdev(clk, NULL, "20215000.uart"); -- cgit v0.10.2 From a9bb2ef7c3f4a72f6ac707f7306cfcfd4f2b6b5e Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 1 Mar 2016 10:59:46 -0800 Subject: clk: at91: Remove CLK_IS_ROOT This flag is a no-op now. Remove usage of the flag. Acked-by: Boris Brezillon Signed-off-by: Stephen Boyd diff --git a/drivers/clk/at91/clk-main.c b/drivers/clk/at91/clk-main.c index b85f435..b9bdfd8 100644 --- a/drivers/clk/at91/clk-main.c +++ b/drivers/clk/at91/clk-main.c @@ -315,7 +315,7 @@ at91_clk_register_main_rc_osc(struct at91_pmc *pmc, init.ops = &main_rc_osc_ops; init.parent_names = NULL; init.num_parents = 0; - init.flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED; + init.flags = CLK_IGNORE_UNUSED; osc->hw.init = &init; osc->pmc = pmc; diff --git a/drivers/clk/at91/clk-slow.c b/drivers/clk/at91/clk-slow.c index 67b3047..402b45d 100644 --- a/drivers/clk/at91/clk-slow.c +++ b/drivers/clk/at91/clk-slow.c @@ -251,7 +251,7 @@ at91_clk_register_slow_rc_osc(void __iomem *sckcr, init.ops = &slow_rc_osc_ops; init.parent_names = NULL; init.num_parents = 0; - init.flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED; + init.flags = CLK_IGNORE_UNUSED; osc->hw.init = &init; osc->sckcr = sckcr; -- cgit v0.10.2 From f61990f3c58bf067a95b90d3beb495e08e9e88b1 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 1 Mar 2016 10:59:48 -0800 Subject: clk: hisilicon: Remove CLK_IS_ROOT This flag is a no-op now. Remove usage of the flag. Tested-by: Leo Yan Cc: Bintian Wang Cc: Zhangfei Gao Cc: Haojian Zhuang Signed-off-by: Stephen Boyd diff --git a/drivers/clk/hisilicon/clk-hi3620.c b/drivers/clk/hisilicon/clk-hi3620.c index 7d03fe1..d04a104 100644 --- a/drivers/clk/hisilicon/clk-hi3620.c +++ b/drivers/clk/hisilicon/clk-hi3620.c @@ -78,15 +78,15 @@ static const char *const mmc3_mux_p[] __initconst = { "armpll2", "armpll3", }; /* fixed rate clocks */ static struct hisi_fixed_rate_clock hi3620_fixed_rate_clks[] __initdata = { - { HI3620_OSC32K, "osc32k", NULL, CLK_IS_ROOT, 32768, }, - { HI3620_OSC26M, "osc26m", NULL, CLK_IS_ROOT, 26000000, }, - { HI3620_PCLK, "pclk", NULL, CLK_IS_ROOT, 26000000, }, - { HI3620_PLL_ARM0, "armpll0", NULL, CLK_IS_ROOT, 1600000000, }, - { HI3620_PLL_ARM1, "armpll1", NULL, CLK_IS_ROOT, 1600000000, }, - { HI3620_PLL_PERI, "armpll2", NULL, CLK_IS_ROOT, 1440000000, }, - { HI3620_PLL_USB, "armpll3", NULL, CLK_IS_ROOT, 1440000000, }, - { HI3620_PLL_HDMI, "armpll4", NULL, CLK_IS_ROOT, 1188000000, }, - { HI3620_PLL_GPU, "armpll5", NULL, CLK_IS_ROOT, 1300000000, }, + { HI3620_OSC32K, "osc32k", NULL, 0, 32768, }, + { HI3620_OSC26M, "osc26m", NULL, 0, 26000000, }, + { HI3620_PCLK, "pclk", NULL, 0, 26000000, }, + { HI3620_PLL_ARM0, "armpll0", NULL, 0, 1600000000, }, + { HI3620_PLL_ARM1, "armpll1", NULL, 0, 1600000000, }, + { HI3620_PLL_PERI, "armpll2", NULL, 0, 1440000000, }, + { HI3620_PLL_USB, "armpll3", NULL, 0, 1440000000, }, + { HI3620_PLL_HDMI, "armpll4", NULL, 0, 1188000000, }, + { HI3620_PLL_GPU, "armpll5", NULL, 0, 1300000000, }, }; /* fixed factor clocks */ diff --git a/drivers/clk/hisilicon/clk-hi6220-stub.c b/drivers/clk/hisilicon/clk-hi6220-stub.c index 8afb40e..329a092 100644 --- a/drivers/clk/hisilicon/clk-hi6220-stub.c +++ b/drivers/clk/hisilicon/clk-hi6220-stub.c @@ -235,7 +235,7 @@ static int hi6220_stub_clk_probe(struct platform_device *pdev) init.name = "acpu0"; init.ops = &hi6220_stub_clk_ops; init.num_parents = 0; - init.flags = CLK_IS_ROOT; + init.flags = 0; clk = devm_clk_register(dev, &stub_clk->hw); if (IS_ERR(clk)) diff --git a/drivers/clk/hisilicon/clk-hi6220.c b/drivers/clk/hisilicon/clk-hi6220.c index 4563343..f02cb41 100644 --- a/drivers/clk/hisilicon/clk-hi6220.c +++ b/drivers/clk/hisilicon/clk-hi6220.c @@ -26,19 +26,19 @@ /* clocks in AO (always on) controller */ static struct hisi_fixed_rate_clock hi6220_fixed_rate_clks[] __initdata = { - { HI6220_REF32K, "ref32k", NULL, CLK_IS_ROOT, 32764, }, - { HI6220_CLK_TCXO, "clk_tcxo", NULL, CLK_IS_ROOT, 19200000, }, - { HI6220_MMC1_PAD, "mmc1_pad", NULL, CLK_IS_ROOT, 100000000, }, - { HI6220_MMC2_PAD, "mmc2_pad", NULL, CLK_IS_ROOT, 100000000, }, - { HI6220_MMC0_PAD, "mmc0_pad", NULL, CLK_IS_ROOT, 200000000, }, - { HI6220_PLL_BBP, "bbppll0", NULL, CLK_IS_ROOT, 245760000, }, - { HI6220_PLL_GPU, "gpupll", NULL, CLK_IS_ROOT, 1000000000,}, - { HI6220_PLL1_DDR, "ddrpll1", NULL, CLK_IS_ROOT, 1066000000,}, - { HI6220_PLL_SYS, "syspll", NULL, CLK_IS_ROOT, 1200000000,}, - { HI6220_PLL_SYS_MEDIA, "media_syspll", NULL, CLK_IS_ROOT, 1200000000,}, - { HI6220_DDR_SRC, "ddr_sel_src", NULL, CLK_IS_ROOT, 1200000000,}, - { HI6220_PLL_MEDIA, "media_pll", NULL, CLK_IS_ROOT, 1440000000,}, - { HI6220_PLL_DDR, "ddrpll0", NULL, CLK_IS_ROOT, 1600000000,}, + { HI6220_REF32K, "ref32k", NULL, 0, 32764, }, + { HI6220_CLK_TCXO, "clk_tcxo", NULL, 0, 19200000, }, + { HI6220_MMC1_PAD, "mmc1_pad", NULL, 0, 100000000, }, + { HI6220_MMC2_PAD, "mmc2_pad", NULL, 0, 100000000, }, + { HI6220_MMC0_PAD, "mmc0_pad", NULL, 0, 200000000, }, + { HI6220_PLL_BBP, "bbppll0", NULL, 0, 245760000, }, + { HI6220_PLL_GPU, "gpupll", NULL, 0, 1000000000,}, + { HI6220_PLL1_DDR, "ddrpll1", NULL, 0, 1066000000,}, + { HI6220_PLL_SYS, "syspll", NULL, 0, 1200000000,}, + { HI6220_PLL_SYS_MEDIA, "media_syspll", NULL, 0, 1200000000,}, + { HI6220_DDR_SRC, "ddr_sel_src", NULL, 0, 1200000000,}, + { HI6220_PLL_MEDIA, "media_pll", NULL, 0, 1440000000,}, + { HI6220_PLL_DDR, "ddrpll0", NULL, 0, 1600000000,}, }; static struct hisi_fixed_factor_clock hi6220_fixed_factor_clks[] __initdata = { diff --git a/drivers/clk/hisilicon/clk-hip04.c b/drivers/clk/hisilicon/clk-hip04.c index 8ca9673..b38e03d 100644 --- a/drivers/clk/hisilicon/clk-hip04.c +++ b/drivers/clk/hisilicon/clk-hip04.c @@ -36,9 +36,9 @@ /* fixed rate clocks */ static struct hisi_fixed_rate_clock hip04_fixed_rate_clks[] __initdata = { - { HIP04_OSC50M, "osc50m", NULL, CLK_IS_ROOT, 50000000, }, - { HIP04_CLK_50M, "clk50m", NULL, CLK_IS_ROOT, 50000000, }, - { HIP04_CLK_168M, "clk168m", NULL, CLK_IS_ROOT, 168750000, }, + { HIP04_OSC50M, "osc50m", NULL, 0, 50000000, }, + { HIP04_CLK_50M, "clk50m", NULL, 0, 50000000, }, + { HIP04_CLK_168M, "clk168m", NULL, 0, 168750000, }, }; static void __init hip04_clk_init(struct device_node *np) diff --git a/drivers/clk/hisilicon/clk-hix5hd2.c b/drivers/clk/hisilicon/clk-hix5hd2.c index 0aaf29d..14b05ef 100644 --- a/drivers/clk/hisilicon/clk-hix5hd2.c +++ b/drivers/clk/hisilicon/clk-hix5hd2.c @@ -14,36 +14,36 @@ #include "clk.h" static struct hisi_fixed_rate_clock hix5hd2_fixed_rate_clks[] __initdata = { - { HIX5HD2_FIXED_1200M, "1200m", NULL, CLK_IS_ROOT, 1200000000, }, - { HIX5HD2_FIXED_400M, "400m", NULL, CLK_IS_ROOT, 400000000, }, - { HIX5HD2_FIXED_48M, "48m", NULL, CLK_IS_ROOT, 48000000, }, - { HIX5HD2_FIXED_24M, "24m", NULL, CLK_IS_ROOT, 24000000, }, - { HIX5HD2_FIXED_600M, "600m", NULL, CLK_IS_ROOT, 600000000, }, - { HIX5HD2_FIXED_300M, "300m", NULL, CLK_IS_ROOT, 300000000, }, - { HIX5HD2_FIXED_75M, "75m", NULL, CLK_IS_ROOT, 75000000, }, - { HIX5HD2_FIXED_200M, "200m", NULL, CLK_IS_ROOT, 200000000, }, - { HIX5HD2_FIXED_100M, "100m", NULL, CLK_IS_ROOT, 100000000, }, - { HIX5HD2_FIXED_40M, "40m", NULL, CLK_IS_ROOT, 40000000, }, - { HIX5HD2_FIXED_150M, "150m", NULL, CLK_IS_ROOT, 150000000, }, - { HIX5HD2_FIXED_1728M, "1728m", NULL, CLK_IS_ROOT, 1728000000, }, - { HIX5HD2_FIXED_28P8M, "28p8m", NULL, CLK_IS_ROOT, 28000000, }, - { HIX5HD2_FIXED_432M, "432m", NULL, CLK_IS_ROOT, 432000000, }, - { HIX5HD2_FIXED_345P6M, "345p6m", NULL, CLK_IS_ROOT, 345000000, }, - { HIX5HD2_FIXED_288M, "288m", NULL, CLK_IS_ROOT, 288000000, }, - { HIX5HD2_FIXED_60M, "60m", NULL, CLK_IS_ROOT, 60000000, }, - { HIX5HD2_FIXED_750M, "750m", NULL, CLK_IS_ROOT, 750000000, }, - { HIX5HD2_FIXED_500M, "500m", NULL, CLK_IS_ROOT, 500000000, }, - { HIX5HD2_FIXED_54M, "54m", NULL, CLK_IS_ROOT, 54000000, }, - { HIX5HD2_FIXED_27M, "27m", NULL, CLK_IS_ROOT, 27000000, }, - { HIX5HD2_FIXED_1500M, "1500m", NULL, CLK_IS_ROOT, 1500000000, }, - { HIX5HD2_FIXED_375M, "375m", NULL, CLK_IS_ROOT, 375000000, }, - { HIX5HD2_FIXED_187M, "187m", NULL, CLK_IS_ROOT, 187000000, }, - { HIX5HD2_FIXED_250M, "250m", NULL, CLK_IS_ROOT, 250000000, }, - { HIX5HD2_FIXED_125M, "125m", NULL, CLK_IS_ROOT, 125000000, }, - { HIX5HD2_FIXED_2P02M, "2m", NULL, CLK_IS_ROOT, 2000000, }, - { HIX5HD2_FIXED_50M, "50m", NULL, CLK_IS_ROOT, 50000000, }, - { HIX5HD2_FIXED_25M, "25m", NULL, CLK_IS_ROOT, 25000000, }, - { HIX5HD2_FIXED_83M, "83m", NULL, CLK_IS_ROOT, 83333333, }, + { HIX5HD2_FIXED_1200M, "1200m", NULL, 0, 1200000000, }, + { HIX5HD2_FIXED_400M, "400m", NULL, 0, 400000000, }, + { HIX5HD2_FIXED_48M, "48m", NULL, 0, 48000000, }, + { HIX5HD2_FIXED_24M, "24m", NULL, 0, 24000000, }, + { HIX5HD2_FIXED_600M, "600m", NULL, 0, 600000000, }, + { HIX5HD2_FIXED_300M, "300m", NULL, 0, 300000000, }, + { HIX5HD2_FIXED_75M, "75m", NULL, 0, 75000000, }, + { HIX5HD2_FIXED_200M, "200m", NULL, 0, 200000000, }, + { HIX5HD2_FIXED_100M, "100m", NULL, 0, 100000000, }, + { HIX5HD2_FIXED_40M, "40m", NULL, 0, 40000000, }, + { HIX5HD2_FIXED_150M, "150m", NULL, 0, 150000000, }, + { HIX5HD2_FIXED_1728M, "1728m", NULL, 0, 1728000000, }, + { HIX5HD2_FIXED_28P8M, "28p8m", NULL, 0, 28000000, }, + { HIX5HD2_FIXED_432M, "432m", NULL, 0, 432000000, }, + { HIX5HD2_FIXED_345P6M, "345p6m", NULL, 0, 345000000, }, + { HIX5HD2_FIXED_288M, "288m", NULL, 0, 288000000, }, + { HIX5HD2_FIXED_60M, "60m", NULL, 0, 60000000, }, + { HIX5HD2_FIXED_750M, "750m", NULL, 0, 750000000, }, + { HIX5HD2_FIXED_500M, "500m", NULL, 0, 500000000, }, + { HIX5HD2_FIXED_54M, "54m", NULL, 0, 54000000, }, + { HIX5HD2_FIXED_27M, "27m", NULL, 0, 27000000, }, + { HIX5HD2_FIXED_1500M, "1500m", NULL, 0, 1500000000, }, + { HIX5HD2_FIXED_375M, "375m", NULL, 0, 375000000, }, + { HIX5HD2_FIXED_187M, "187m", NULL, 0, 187000000, }, + { HIX5HD2_FIXED_250M, "250m", NULL, 0, 250000000, }, + { HIX5HD2_FIXED_125M, "125m", NULL, 0, 125000000, }, + { HIX5HD2_FIXED_2P02M, "2m", NULL, 0, 2000000, }, + { HIX5HD2_FIXED_50M, "50m", NULL, 0, 50000000, }, + { HIX5HD2_FIXED_25M, "25m", NULL, 0, 25000000, }, + { HIX5HD2_FIXED_83M, "83m", NULL, 0, 83333333, }, }; static const char *const sfc_mux_p[] __initconst = { -- cgit v0.10.2 From 3d08f1564b169114b6f3d8ee6586acf8e4e54db5 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 1 Mar 2016 10:59:50 -0800 Subject: clk: mediatek: Remove CLK_IS_ROOT This flag is a no-op now. Remove usage of the flag. Acked-by: James Liao Signed-off-by: Stephen Boyd diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c index 3528303..5ada644 100644 --- a/drivers/clk/mediatek/clk-mtk.c +++ b/drivers/clk/mediatek/clk-mtk.c @@ -58,8 +58,8 @@ void __init mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks, for (i = 0; i < num; i++) { const struct mtk_fixed_clk *rc = &clks[i]; - clk = clk_register_fixed_rate(NULL, rc->name, rc->parent, - rc->parent ? 0 : CLK_IS_ROOT, rc->rate); + clk = clk_register_fixed_rate(NULL, rc->name, rc->parent, 0, + rc->rate); if (IS_ERR(clk)) { pr_err("Failed to register clk %s: %ld\n", -- cgit v0.10.2 From 38c7035f9cfdbf2787ee93cc1278ddc67190b279 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 1 Mar 2016 10:59:49 -0800 Subject: clk: imx: Remove CLK_IS_ROOT This flag is a no-op now. Remove usage of the flag. Acked-by: Shawn Guo Signed-off-by: Stephen Boyd diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h index c94ac5c..d942f57 100644 --- a/drivers/clk/imx/clk.h +++ b/drivers/clk/imx/clk.h @@ -87,7 +87,7 @@ struct clk *imx_clk_fixup_mux(const char *name, void __iomem *reg, static inline struct clk *imx_clk_fixed(const char *name, int rate) { - return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate); + return clk_register_fixed_rate(NULL, name, NULL, 0, rate); } static inline struct clk *imx_clk_divider(const char *name, const char *parent, -- cgit v0.10.2 From 0f4207f3d86a45d0a50454e277625c9311b510fc Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 1 Mar 2016 10:59:54 -0800 Subject: clk: mxs: Remove CLK_IS_ROOT This flag is a no-op now. Remove usage of the flag. Acked-by: Shawn Guo Signed-off-by: Stephen Boyd diff --git a/drivers/clk/mxs/clk.h b/drivers/clk/mxs/clk.h index a459095..5a264a4 100644 --- a/drivers/clk/mxs/clk.h +++ b/drivers/clk/mxs/clk.h @@ -38,7 +38,7 @@ struct clk *mxs_clk_frac(const char *name, const char *parent_name, static inline struct clk *mxs_clk_fixed(const char *name, int rate) { - return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate); + return clk_register_fixed_rate(NULL, name, NULL, 0, rate); } static inline struct clk *mxs_clk_gate(const char *name, -- cgit v0.10.2 From 615b34de1fc81527bee357aba2effd6632dfe5f8 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 1 Mar 2016 10:59:55 -0800 Subject: clk: nxp: Remove CLK_IS_ROOT This flag is a no-op now. Remove usage of the flag. Acked-by: Joachim Eastwood Signed-off-by: Stephen Boyd diff --git a/drivers/clk/nxp/clk-lpc18xx-cgu.c b/drivers/clk/nxp/clk-lpc18xx-cgu.c index c924572..2531174 100644 --- a/drivers/clk/nxp/clk-lpc18xx-cgu.c +++ b/drivers/clk/nxp/clk-lpc18xx-cgu.c @@ -605,7 +605,7 @@ static void __init lpc18xx_cgu_register_source_clks(struct device_node *np, /* Register the internal 12 MHz RC oscillator (IRC) */ clk = clk_register_fixed_rate(NULL, clk_src_names[CLK_SRC_IRC], - NULL, CLK_IS_ROOT, 12000000); + NULL, 0, 12000000); if (IS_ERR(clk)) pr_warn("%s: failed to register irc clk\n", __func__); -- cgit v0.10.2 From 2c63935dd634df2d9790adff71876d7140470b70 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 1 Mar 2016 10:59:56 -0800 Subject: clk: pxa: Remove CLK_IS_ROOT This flag is a no-op now. Remove usage of the flag. Acked-by: Robert Jarzmik Signed-off-by: Stephen Boyd diff --git a/drivers/clk/pxa/clk-pxa25x.c b/drivers/clk/pxa/clk-pxa25x.c index b774722..48b8b64 100644 --- a/drivers/clk/pxa/clk-pxa25x.c +++ b/drivers/clk/pxa/clk-pxa25x.c @@ -200,12 +200,10 @@ static void __init pxa25x_register_core(void) static void __init pxa25x_register_plls(void) { clk_register_fixed_rate(NULL, "osc_3_6864mhz", NULL, - CLK_GET_RATE_NOCACHE | CLK_IS_ROOT, - 3686400); + CLK_GET_RATE_NOCACHE, 3686400); clk_register_fixed_rate(NULL, "osc_32_768khz", NULL, - CLK_GET_RATE_NOCACHE | CLK_IS_ROOT, - 32768); - clk_register_fixed_rate(NULL, "clk_dummy", NULL, CLK_IS_ROOT, 0); + CLK_GET_RATE_NOCACHE, 32768); + clk_register_fixed_rate(NULL, "clk_dummy", NULL, 0, 0); clk_register_fixed_factor(NULL, "ppll_95_85mhz", "osc_3_6864mhz", 0, 26, 1); clk_register_fixed_factor(NULL, "ppll_147_46mhz", "osc_3_6864mhz", diff --git a/drivers/clk/pxa/clk-pxa27x.c b/drivers/clk/pxa/clk-pxa27x.c index 5b82d30..e86cd5f 100644 --- a/drivers/clk/pxa/clk-pxa27x.c +++ b/drivers/clk/pxa/clk-pxa27x.c @@ -208,12 +208,12 @@ MUX_RO_RATE_RO_OPS(clk_pxa27x_lcd_base, "lcd_base"); static void __init pxa27x_register_plls(void) { clk_register_fixed_rate(NULL, "osc_13mhz", NULL, - CLK_GET_RATE_NOCACHE | CLK_IS_ROOT, + CLK_GET_RATE_NOCACHE, 13 * MHz); clk_register_fixed_rate(NULL, "osc_32_768khz", NULL, - CLK_GET_RATE_NOCACHE | CLK_IS_ROOT, + CLK_GET_RATE_NOCACHE, 32768 * KHz); - clk_register_fixed_rate(NULL, "clk_dummy", NULL, CLK_IS_ROOT, 0); + clk_register_fixed_rate(NULL, "clk_dummy", NULL, 0, 0); clk_register_fixed_factor(NULL, "ppll_312mhz", "osc_13mhz", 0, 24, 1); } diff --git a/drivers/clk/pxa/clk-pxa3xx.c b/drivers/clk/pxa/clk-pxa3xx.c index 4af4eed..9238d5f 100644 --- a/drivers/clk/pxa/clk-pxa3xx.c +++ b/drivers/clk/pxa/clk-pxa3xx.c @@ -284,15 +284,15 @@ static void __init pxa3xx_register_core(void) static void __init pxa3xx_register_plls(void) { clk_register_fixed_rate(NULL, "osc_13mhz", NULL, - CLK_GET_RATE_NOCACHE | CLK_IS_ROOT, + CLK_GET_RATE_NOCACHE, 13 * MHz); clk_register_fixed_rate(NULL, "osc_32_768khz", NULL, - CLK_GET_RATE_NOCACHE | CLK_IS_ROOT, + CLK_GET_RATE_NOCACHE, 32768); clk_register_fixed_rate(NULL, "ring_osc_120mhz", NULL, - CLK_GET_RATE_NOCACHE | CLK_IS_ROOT, + CLK_GET_RATE_NOCACHE, 120 * MHz); - clk_register_fixed_rate(NULL, "clk_dummy", NULL, CLK_IS_ROOT, 0); + clk_register_fixed_rate(NULL, "clk_dummy", NULL, 0, 0); clk_register_fixed_factor(NULL, "spll_624mhz", "osc_13mhz", 0, 48, 1); clk_register_fixed_factor(NULL, "ring_osc_60mhz", "ring_osc_120mhz", 0, 1, 2); -- cgit v0.10.2 From 728f288d2aed7def19a3105ffee3875280a2be2a Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 1 Mar 2016 10:59:58 -0800 Subject: clk: samsung: Remove CLK_IS_ROOT This flag is a no-op now. Remove usage of the flag. Acked-by: Sylwester Nawrocki Signed-off-by: Stephen Boyd diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index ac03e4f..7b3d0f9 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -500,19 +500,19 @@ PNAME(clkout_cpu_p4x12) = { "fout_apll_div_2", "none", "none", "none", /* fixed rate clocks generated outside the soc */ static struct samsung_fixed_rate_clock exynos4_fixed_rate_ext_clks[] __initdata = { - FRATE(CLK_XXTI, "xxti", NULL, CLK_IS_ROOT, 0), - FRATE(CLK_XUSBXTI, "xusbxti", NULL, CLK_IS_ROOT, 0), + FRATE(CLK_XXTI, "xxti", NULL, 0, 0), + FRATE(CLK_XUSBXTI, "xusbxti", NULL, 0, 0), }; /* fixed rate clocks generated inside the soc */ static struct samsung_fixed_rate_clock exynos4_fixed_rate_clks[] __initdata = { - FRATE(0, "sclk_hdmi24m", NULL, CLK_IS_ROOT, 24000000), + FRATE(0, "sclk_hdmi24m", NULL, 0, 24000000), FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy", "hdmi", 0, 27000000), - FRATE(0, "sclk_usbphy0", NULL, CLK_IS_ROOT, 48000000), + FRATE(0, "sclk_usbphy0", NULL, 0, 48000000), }; static struct samsung_fixed_rate_clock exynos4210_fixed_rate_clks[] __initdata = { - FRATE(0, "sclk_usbphy1", NULL, CLK_IS_ROOT, 48000000), + FRATE(0, "sclk_usbphy1", NULL, 0, 48000000), }; static struct samsung_fixed_factor_clock exynos4_fixed_factor_clks[] __initdata = { @@ -1251,7 +1251,7 @@ static void __init exynos4_clk_register_finpll(struct samsung_clk_provider *ctx) fclk.id = CLK_FIN_PLL; fclk.name = "fin_pll"; fclk.parent_name = NULL; - fclk.flags = CLK_IS_ROOT; + fclk.flags = 0; fclk.fixed_rate = finpll_f; samsung_clk_register_fixed_rate(ctx, &fclk, 1); diff --git a/drivers/clk/samsung/clk-exynos4415.c b/drivers/clk/samsung/clk-exynos4415.c index 92c39f6e..86ee06b 100644 --- a/drivers/clk/samsung/clk-exynos4415.c +++ b/drivers/clk/samsung/clk-exynos4415.c @@ -274,7 +274,7 @@ static struct samsung_fixed_factor_clock exynos4415_fixed_factor_clks[] __initda }; static struct samsung_fixed_rate_clock exynos4415_fixed_rate_clks[] __initdata = { - FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 27000000), + FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy", NULL, 0, 27000000), }; static struct samsung_mux_clock exynos4415_mux_clks[] __initdata = { diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c index 5bebf8c..837197d 100644 --- a/drivers/clk/samsung/clk-exynos5250.c +++ b/drivers/clk/samsung/clk-exynos5250.c @@ -262,15 +262,15 @@ PNAME(mout_spdif_p) = { "sclk_audio0", "sclk_audio1", "sclk_audio2", /* fixed rate clocks generated outside the soc */ static struct samsung_fixed_rate_clock exynos5250_fixed_rate_ext_clks[] __initdata = { - FRATE(CLK_FIN_PLL, "fin_pll", NULL, CLK_IS_ROOT, 0), + FRATE(CLK_FIN_PLL, "fin_pll", NULL, 0, 0), }; /* fixed rate clocks generated inside the soc */ static struct samsung_fixed_rate_clock exynos5250_fixed_rate_clks[] __initdata = { - FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 24000000), - FRATE(0, "sclk_hdmi27m", NULL, CLK_IS_ROOT, 27000000), - FRATE(0, "sclk_dptxphy", NULL, CLK_IS_ROOT, 24000000), - FRATE(0, "sclk_uhostphy", NULL, CLK_IS_ROOT, 48000000), + FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy", NULL, 0, 24000000), + FRATE(0, "sclk_hdmi27m", NULL, 0, 27000000), + FRATE(0, "sclk_dptxphy", NULL, 0, 24000000), + FRATE(0, "sclk_uhostphy", NULL, 0, 48000000), }; static struct samsung_fixed_factor_clock exynos5250_fixed_factor_clks[] __initdata = { diff --git a/drivers/clk/samsung/clk-exynos5260.c b/drivers/clk/samsung/clk-exynos5260.c index d1a29f6..7a7ed07 100644 --- a/drivers/clk/samsung/clk-exynos5260.c +++ b/drivers/clk/samsung/clk-exynos5260.c @@ -1432,42 +1432,38 @@ static unsigned long top_clk_regs[] __initdata = { /* fixed rate clocks generated inside the soc */ static struct samsung_fixed_rate_clock fixed_rate_clks[] __initdata = { FRATE(PHYCLK_DPTX_PHY_CH3_TXD_CLK, "phyclk_dptx_phy_ch3_txd_clk", NULL, - CLK_IS_ROOT, 270000000), + 0, 270000000), FRATE(PHYCLK_DPTX_PHY_CH2_TXD_CLK, "phyclk_dptx_phy_ch2_txd_clk", NULL, - CLK_IS_ROOT, 270000000), + 0, 270000000), FRATE(PHYCLK_DPTX_PHY_CH1_TXD_CLK, "phyclk_dptx_phy_ch1_txd_clk", NULL, - CLK_IS_ROOT, 270000000), + 0, 270000000), FRATE(PHYCLK_DPTX_PHY_CH0_TXD_CLK, "phyclk_dptx_phy_ch0_txd_clk", NULL, - CLK_IS_ROOT, 270000000), + 0, 270000000), FRATE(phyclk_hdmi_phy_tmds_clko, "phyclk_hdmi_phy_tmds_clko", NULL, - CLK_IS_ROOT, 250000000), + 0, 250000000), FRATE(PHYCLK_HDMI_PHY_PIXEL_CLKO, "phyclk_hdmi_phy_pixel_clko", NULL, - CLK_IS_ROOT, 1660000000), + 0, 1660000000), FRATE(PHYCLK_HDMI_LINK_O_TMDS_CLKHI, "phyclk_hdmi_link_o_tmds_clkhi", - NULL, CLK_IS_ROOT, 125000000), + NULL, 0, 125000000), FRATE(PHYCLK_MIPI_DPHY_4L_M_TXBYTECLKHS, "phyclk_mipi_dphy_4l_m_txbyte_clkhs" , NULL, - CLK_IS_ROOT, 187500000), + 0, 187500000), FRATE(PHYCLK_DPTX_PHY_O_REF_CLK_24M, "phyclk_dptx_phy_o_ref_clk_24m", - NULL, CLK_IS_ROOT, 24000000), + NULL, 0, 24000000), FRATE(PHYCLK_DPTX_PHY_CLK_DIV2, "phyclk_dptx_phy_clk_div2", NULL, - CLK_IS_ROOT, 135000000), + 0, 135000000), FRATE(PHYCLK_MIPI_DPHY_4L_M_RXCLKESC0, - "phyclk_mipi_dphy_4l_m_rxclkesc0", NULL, - CLK_IS_ROOT, 20000000), + "phyclk_mipi_dphy_4l_m_rxclkesc0", NULL, 0, 20000000), FRATE(PHYCLK_USBHOST20_PHY_PHYCLOCK, "phyclk_usbhost20_phy_phyclock", - NULL, CLK_IS_ROOT, 60000000), + NULL, 0, 60000000), FRATE(PHYCLK_USBHOST20_PHY_FREECLK, "phyclk_usbhost20_phy_freeclk", - NULL, CLK_IS_ROOT, 60000000), + NULL, 0, 60000000), FRATE(PHYCLK_USBHOST20_PHY_CLK48MOHCI, - "phyclk_usbhost20_phy_clk48mohci", - NULL, CLK_IS_ROOT, 48000000), + "phyclk_usbhost20_phy_clk48mohci", NULL, 0, 48000000), FRATE(PHYCLK_USBDRD30_UDRD30_PIPE_PCLK, - "phyclk_usbdrd30_udrd30_pipe_pclk", NULL, - CLK_IS_ROOT, 125000000), + "phyclk_usbdrd30_udrd30_pipe_pclk", NULL, 0, 125000000), FRATE(PHYCLK_USBDRD30_UDRD30_PHYCLOCK, - "phyclk_usbdrd30_udrd30_phyclock", NULL, - CLK_IS_ROOT, 60000000), + "phyclk_usbdrd30_udrd30_phyclock", NULL, 0, 60000000), }; PNAME(mout_memtop_pll_user_p) = {"fin_pll", "dout_mem_pll"}; diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index d048ded..be03ed0 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -480,16 +480,16 @@ PNAME(mout_group15_5800_p) = { "dout_osc_div", "mout_sw_aclk550_cam" }; /* fixed rate clocks generated outside the soc */ static struct samsung_fixed_rate_clock exynos5x_fixed_rate_ext_clks[] __initdata = { - FRATE(CLK_FIN_PLL, "fin_pll", NULL, CLK_IS_ROOT, 0), + FRATE(CLK_FIN_PLL, "fin_pll", NULL, 0, 0), }; /* fixed rate clocks generated inside the soc */ static struct samsung_fixed_rate_clock exynos5x_fixed_rate_clks[] __initdata = { - FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 24000000), - FRATE(0, "sclk_pwi", NULL, CLK_IS_ROOT, 24000000), - FRATE(0, "sclk_usbh20", NULL, CLK_IS_ROOT, 48000000), - FRATE(0, "mphy_refclk_ixtal24", NULL, CLK_IS_ROOT, 48000000), - FRATE(0, "sclk_usbh20_scan_clk", NULL, CLK_IS_ROOT, 480000000), + FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy", NULL, 0, 24000000), + FRATE(0, "sclk_pwi", NULL, 0, 24000000), + FRATE(0, "sclk_usbh20", NULL, 0, 48000000), + FRATE(0, "mphy_refclk_ixtal24", NULL, 0, 48000000), + FRATE(0, "sclk_usbh20_scan_clk", NULL, 0, 480000000), }; static struct samsung_fixed_factor_clock diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index 707a814..128527b 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -224,18 +224,18 @@ static struct samsung_fixed_factor_clock top_fixed_factor_clks[] __initdata = { static struct samsung_fixed_rate_clock top_fixed_clks[] __initdata = { /* Xi2s{0|1}CDCLK input clock for I2S/PCM */ - FRATE(0, "ioclk_audiocdclk1", NULL, CLK_IS_ROOT, 100000000), - FRATE(0, "ioclk_audiocdclk0", NULL, CLK_IS_ROOT, 100000000), + FRATE(0, "ioclk_audiocdclk1", NULL, 0, 100000000), + FRATE(0, "ioclk_audiocdclk0", NULL, 0, 100000000), /* Xi2s1SDI input clock for SPDIF */ - FRATE(0, "ioclk_spdif_extclk", NULL, CLK_IS_ROOT, 100000000), + FRATE(0, "ioclk_spdif_extclk", NULL, 0, 100000000), /* XspiCLK[4:0] input clock for SPI */ - FRATE(0, "ioclk_spi4_clk_in", NULL, CLK_IS_ROOT, 50000000), - FRATE(0, "ioclk_spi3_clk_in", NULL, CLK_IS_ROOT, 50000000), - FRATE(0, "ioclk_spi2_clk_in", NULL, CLK_IS_ROOT, 50000000), - FRATE(0, "ioclk_spi1_clk_in", NULL, CLK_IS_ROOT, 50000000), - FRATE(0, "ioclk_spi0_clk_in", NULL, CLK_IS_ROOT, 50000000), + FRATE(0, "ioclk_spi4_clk_in", NULL, 0, 50000000), + FRATE(0, "ioclk_spi3_clk_in", NULL, 0, 50000000), + FRATE(0, "ioclk_spi2_clk_in", NULL, 0, 50000000), + FRATE(0, "ioclk_spi1_clk_in", NULL, 0, 50000000), + FRATE(0, "ioclk_spi0_clk_in", NULL, 0, 50000000), /* Xi2s1SCLK input clock for I2S1_BCLK */ - FRATE(0, "ioclk_i2s1_bclk_in", NULL, CLK_IS_ROOT, 12288000), + FRATE(0, "ioclk_i2s1_bclk_in", NULL, 0, 12288000), }; static struct samsung_mux_clock top_mux_clks[] __initdata = { @@ -1984,42 +1984,40 @@ static struct samsung_fixed_rate_clock fsys_fixed_clks[] __initdata = { /* PHY clocks from USBDRD30_PHY */ FRATE(CLK_PHYCLK_USBDRD30_UDRD30_PHYCLOCK_PHY, "phyclk_usbdrd30_udrd30_phyclock_phy", NULL, - CLK_IS_ROOT, 60000000), + 0, 60000000), FRATE(CLK_PHYCLK_USBDRD30_UDRD30_PIPE_PCLK_PHY, "phyclk_usbdrd30_udrd30_pipe_pclk_phy", NULL, - CLK_IS_ROOT, 125000000), + 0, 125000000), /* PHY clocks from USBHOST30_PHY */ FRATE(CLK_PHYCLK_USBHOST30_UHOST30_PHYCLOCK_PHY, "phyclk_usbhost30_uhost30_phyclock_phy", NULL, - CLK_IS_ROOT, 60000000), + 0, 60000000), FRATE(CLK_PHYCLK_USBHOST30_UHOST30_PIPE_PCLK_PHY, "phyclk_usbhost30_uhost30_pipe_pclk_phy", NULL, - CLK_IS_ROOT, 125000000), + 0, 125000000), /* PHY clocks from USBHOST20_PHY */ FRATE(CLK_PHYCLK_USBHOST20_PHY_FREECLK_PHY, - "phyclk_usbhost20_phy_freeclk_phy", NULL, CLK_IS_ROOT, - 60000000), + "phyclk_usbhost20_phy_freeclk_phy", NULL, 0, 60000000), FRATE(CLK_PHYCLK_USBHOST20_PHY_PHYCLOCK_PHY, - "phyclk_usbhost20_phy_phyclock_phy", NULL, CLK_IS_ROOT, - 60000000), + "phyclk_usbhost20_phy_phyclock_phy", NULL, 0, 60000000), FRATE(CLK_PHYCLK_USBHOST20_PHY_CLK48MOHCI_PHY, "phyclk_usbhost20_phy_clk48mohci_phy", NULL, - CLK_IS_ROOT, 48000000), + 0, 48000000), FRATE(CLK_PHYCLK_USBHOST20_PHY_HSIC1_PHY, - "phyclk_usbhost20_phy_hsic1_phy", NULL, CLK_IS_ROOT, + "phyclk_usbhost20_phy_hsic1_phy", NULL, 0, 60000000), /* PHY clocks from UFS_PHY */ FRATE(CLK_PHYCLK_UFS_TX0_SYMBOL_PHY, "phyclk_ufs_tx0_symbol_phy", - NULL, CLK_IS_ROOT, 300000000), + NULL, 0, 300000000), FRATE(CLK_PHYCLK_UFS_RX0_SYMBOL_PHY, "phyclk_ufs_rx0_symbol_phy", - NULL, CLK_IS_ROOT, 300000000), + NULL, 0, 300000000), FRATE(CLK_PHYCLK_UFS_TX1_SYMBOL_PHY, "phyclk_ufs_tx1_symbol_phy", - NULL, CLK_IS_ROOT, 300000000), + NULL, 0, 300000000), FRATE(CLK_PHYCLK_UFS_RX1_SYMBOL_PHY, "phyclk_ufs_rx1_symbol_phy", - NULL, CLK_IS_ROOT, 300000000), + NULL, 0, 300000000), /* PHY clocks from LLI_PHY */ FRATE(CLK_PHYCLK_LLI_MPHY_TO_UFS_PHY, "phyclk_lli_mphy_to_ufs_phy", - NULL, CLK_IS_ROOT, 26000000), + NULL, 0, 26000000), }; static struct samsung_mux_clock fsys_mux_clks[] __initdata = { @@ -2548,20 +2546,16 @@ static struct samsung_fixed_factor_clock disp_fixed_factor_clks[] __initdata = { static struct samsung_fixed_rate_clock disp_fixed_clks[] __initdata = { /* PHY clocks from MIPI_DPHY1 */ - FRATE(0, "phyclk_mipidphy1_bitclkdiv8_phy", NULL, CLK_IS_ROOT, - 188000000), - FRATE(0, "phyclk_mipidphy1_rxclkesc0_phy", NULL, CLK_IS_ROOT, - 100000000), + FRATE(0, "phyclk_mipidphy1_bitclkdiv8_phy", NULL, 0, 188000000), + FRATE(0, "phyclk_mipidphy1_rxclkesc0_phy", NULL, 0, 100000000), /* PHY clocks from MIPI_DPHY0 */ - FRATE(0, "phyclk_mipidphy0_bitclkdiv8_phy", NULL, CLK_IS_ROOT, - 188000000), - FRATE(0, "phyclk_mipidphy0_rxclkesc0_phy", NULL, CLK_IS_ROOT, - 100000000), + FRATE(0, "phyclk_mipidphy0_bitclkdiv8_phy", NULL, 0, 188000000), + FRATE(0, "phyclk_mipidphy0_rxclkesc0_phy", NULL, 0, 100000000), /* PHY clocks from HDMI_PHY */ FRATE(CLK_PHYCLK_HDMIPHY_TMDS_CLKO_PHY, "phyclk_hdmiphy_tmds_clko_phy", - NULL, CLK_IS_ROOT, 300000000), + NULL, 0, 300000000), FRATE(CLK_PHYCLK_HDMIPHY_PIXEL_CLKO_PHY, "phyclk_hdmiphy_pixel_clko_phy", - NULL, CLK_IS_ROOT, 166000000), + NULL, 0, 166000000), }; static struct samsung_mux_clock disp_mux_clks[] __initdata = { @@ -2882,9 +2876,9 @@ PNAME(mout_aud_pll_user_aud_p) = { "oscclk", "fout_aud_pll", }; PNAME(mout_sclk_aud_pcm_p) = { "mout_aud_pll_user", "ioclk_audiocdclk0",}; static struct samsung_fixed_rate_clock aud_fixed_clks[] __initdata = { - FRATE(0, "ioclk_jtag_tclk", NULL, CLK_IS_ROOT, 33000000), - FRATE(0, "ioclk_slimbus_clk", NULL, CLK_IS_ROOT, 25000000), - FRATE(0, "ioclk_i2s_bclk", NULL, CLK_IS_ROOT, 50000000), + FRATE(0, "ioclk_jtag_tclk", NULL, 0, 33000000), + FRATE(0, "ioclk_slimbus_clk", NULL, 0, 25000000), + FRATE(0, "ioclk_i2s_bclk", NULL, 0, 50000000), }; static struct samsung_mux_clock aud_mux_clks[] __initdata = { @@ -4596,9 +4590,9 @@ PNAME(mout_sclk_pixelasync_lite_c_init_a_p) = { static struct samsung_fixed_rate_clock cam0_fixed_clks[] __initdata = { FRATE(CLK_PHYCLK_RXBYTEECLKHS0_S4_PHY, "phyclk_rxbyteclkhs0_s4_phy", - NULL, CLK_IS_ROOT, 100000000), + NULL, 0, 100000000), FRATE(CLK_PHYCLK_RXBYTEECLKHS0_S2A_PHY, "phyclk_rxbyteclkhs0_s2a_phy", - NULL, CLK_IS_ROOT, 100000000), + NULL, 0, 100000000), }; static struct samsung_mux_clock cam0_mux_clks[] __initdata = { @@ -5024,7 +5018,7 @@ PNAME(mout_aclk_lite_c_a_p) = { "mout_aclk_cam1_552_user", static struct samsung_fixed_rate_clock cam1_fixed_clks[] __initdata = { FRATE(CLK_PHYCLK_RXBYTEECLKHS0_S2B, "phyclk_rxbyteclkhs0_s2b_phy", NULL, - CLK_IS_ROOT, 100000000), + 0, 100000000), }; static struct samsung_mux_clock cam1_mux_clks[] __initdata = { diff --git a/drivers/clk/samsung/clk-exynos5440.c b/drivers/clk/samsung/clk-exynos5440.c index 5908138..c57cff1 100644 --- a/drivers/clk/samsung/clk-exynos5440.c +++ b/drivers/clk/samsung/clk-exynos5440.c @@ -31,16 +31,16 @@ PNAME(mout_spi_p) = { "div125", "div200" }; /* fixed rate clocks generated outside the soc */ static struct samsung_fixed_rate_clock exynos5440_fixed_rate_ext_clks[] __initdata = { - FRATE(0, "xtal", NULL, CLK_IS_ROOT, 0), + FRATE(0, "xtal", NULL, 0, 0), }; /* fixed rate clocks */ static struct samsung_fixed_rate_clock exynos5440_fixed_rate_clks[] __initdata = { - FRATE(0, "ppll", NULL, CLK_IS_ROOT, 1000000000), - FRATE(0, "usb_phy0", NULL, CLK_IS_ROOT, 60000000), - FRATE(0, "usb_phy1", NULL, CLK_IS_ROOT, 60000000), - FRATE(0, "usb_ohci12", NULL, CLK_IS_ROOT, 12000000), - FRATE(0, "usb_ohci48", NULL, CLK_IS_ROOT, 48000000), + FRATE(0, "ppll", NULL, 0, 1000000000), + FRATE(0, "usb_phy0", NULL, 0, 60000000), + FRATE(0, "usb_phy1", NULL, 0, 60000000), + FRATE(0, "usb_ohci12", NULL, 0, 12000000), + FRATE(0, "usb_ohci48", NULL, 0, 48000000), }; /* fixed factor clocks */ diff --git a/drivers/clk/samsung/clk-exynos7.c b/drivers/clk/samsung/clk-exynos7.c index 55f8e2e..ad68d46 100644 --- a/drivers/clk/samsung/clk-exynos7.c +++ b/drivers/clk/samsung/clk-exynos7.c @@ -894,10 +894,8 @@ PNAME(mout_phyclk_usbdrd300_udrd30_pipe_pclk_user_p) = { "fin_pll", /* fixed rate clocks used in the FSYS0 block */ static struct samsung_fixed_rate_clock fixed_rate_clks_fsys0[] __initdata = { - FRATE(0, "phyclk_usbdrd300_udrd30_phyclock", NULL, - CLK_IS_ROOT, 60000000), - FRATE(0, "phyclk_usbdrd300_udrd30_pipe_pclk", NULL, - CLK_IS_ROOT, 125000000), + FRATE(0, "phyclk_usbdrd300_udrd30_phyclock", NULL, 0, 60000000), + FRATE(0, "phyclk_usbdrd300_udrd30_pipe_pclk", NULL, 0, 125000000), }; static unsigned long fsys0_clk_regs[] __initdata = { @@ -1009,11 +1007,11 @@ PNAME(mout_phyclk_ufs20_rx1_user_p) = { "fin_pll", "phyclk_ufs20_rx1_symbol" }; /* fixed rate clocks used in the FSYS1 block */ static struct samsung_fixed_rate_clock fixed_rate_clks_fsys1[] __initdata = { FRATE(PHYCLK_UFS20_TX0_SYMBOL, "phyclk_ufs20_tx0_symbol", NULL, - CLK_IS_ROOT, 300000000), + 0, 300000000), FRATE(PHYCLK_UFS20_RX0_SYMBOL, "phyclk_ufs20_rx0_symbol", NULL, - CLK_IS_ROOT, 300000000), + 0, 300000000), FRATE(PHYCLK_UFS20_RX1_SYMBOL, "phyclk_ufs20_rx1_symbol", NULL, - CLK_IS_ROOT, 300000000), + 0, 300000000), }; static unsigned long fsys1_clk_regs[] __initdata = { diff --git a/drivers/clk/samsung/clk-s3c2410.c b/drivers/clk/samsung/clk-s3c2410.c index 0945a88..d7b011c 100644 --- a/drivers/clk/samsung/clk-s3c2410.c +++ b/drivers/clk/samsung/clk-s3c2410.c @@ -344,7 +344,7 @@ struct samsung_mux_clock s3c2442_muxes[] __initdata = { */ #define XTI 1 struct samsung_fixed_rate_clock s3c2410_common_frate_clks[] __initdata = { - FRATE(XTI, "xti", NULL, CLK_IS_ROOT, 0), + FRATE(XTI, "xti", NULL, 0, 0), }; static void __init s3c2410_common_clk_register_fixed_ext( diff --git a/drivers/clk/samsung/clk-s3c2412.c b/drivers/clk/samsung/clk-s3c2412.c index 44d6a9f..effe373 100644 --- a/drivers/clk/samsung/clk-s3c2412.c +++ b/drivers/clk/samsung/clk-s3c2412.c @@ -232,8 +232,8 @@ static struct notifier_block s3c2412_restart_handler = { */ #define XTI 1 struct samsung_fixed_rate_clock s3c2412_common_frate_clks[] __initdata = { - FRATE(XTI, "xti", NULL, CLK_IS_ROOT, 0), - FRATE(0, "ext", NULL, CLK_IS_ROOT, 0), + FRATE(XTI, "xti", NULL, 0, 0), + FRATE(0, "ext", NULL, 0, 0), }; static void __init s3c2412_common_clk_register_fixed_ext( diff --git a/drivers/clk/samsung/clk-s3c2443.c b/drivers/clk/samsung/clk-s3c2443.c index 2c0a1ea..3756278 100644 --- a/drivers/clk/samsung/clk-s3c2443.c +++ b/drivers/clk/samsung/clk-s3c2443.c @@ -371,10 +371,10 @@ static struct notifier_block s3c2443_restart_handler = { * Only necessary until the devicetree-move is complete */ struct samsung_fixed_rate_clock s3c2443_common_frate_clks[] __initdata = { - FRATE(0, "xti", NULL, CLK_IS_ROOT, 0), - FRATE(0, "ext", NULL, CLK_IS_ROOT, 0), - FRATE(0, "ext_i2s", NULL, CLK_IS_ROOT, 0), - FRATE(0, "ext_uart", NULL, CLK_IS_ROOT, 0), + FRATE(0, "xti", NULL, 0, 0), + FRATE(0, "ext", NULL, 0, 0), + FRATE(0, "ext_i2s", NULL, 0, 0), + FRATE(0, "ext_uart", NULL, 0, 0), }; static void __init s3c2443_common_clk_register_fixed_ext( diff --git a/drivers/clk/samsung/clk-s3c64xx.c b/drivers/clk/samsung/clk-s3c64xx.c index d325ed1..60aa775 100644 --- a/drivers/clk/samsung/clk-s3c64xx.c +++ b/drivers/clk/samsung/clk-s3c64xx.c @@ -176,14 +176,14 @@ PNAME(audio2_p6410) = { "mout_epll", "dout_mpll", "fin_pll", "iiscdclk2", /* Fixed rate clocks generated outside the SoC. */ FIXED_RATE_CLOCKS(s3c64xx_fixed_rate_ext_clks) __initdata = { - FRATE(0, "fin_pll", NULL, CLK_IS_ROOT, 0), - FRATE(0, "xusbxti", NULL, CLK_IS_ROOT, 0), + FRATE(0, "fin_pll", NULL, 0, 0), + FRATE(0, "xusbxti", NULL, 0, 0), }; /* Fixed rate clocks generated inside the SoC. */ FIXED_RATE_CLOCKS(s3c64xx_fixed_rate_clks) __initdata = { - FRATE(CLK27M, "clk27m", NULL, CLK_IS_ROOT, 27000000), - FRATE(CLK48M, "clk48m", NULL, CLK_IS_ROOT, 48000000), + FRATE(CLK27M, "clk27m", NULL, 0, 27000000), + FRATE(CLK48M, "clk48m", NULL, 0, 48000000), }; /* List of clock muxes present on all S3C64xx SoCs. */ diff --git a/drivers/clk/samsung/clk-s5pv210.c b/drivers/clk/samsung/clk-s5pv210.c index 759aaf3..5230226 100644 --- a/drivers/clk/samsung/clk-s5pv210.c +++ b/drivers/clk/samsung/clk-s5pv210.c @@ -503,15 +503,15 @@ static const struct samsung_mux_clock s5p6442_mux_clks[] __initconst = { /* S5PV210-specific fixed rate clocks generated inside the SoC. */ static const struct samsung_fixed_rate_clock s5pv210_frate_clks[] __initconst = { - FRATE(SCLK_HDMI27M, "sclk_hdmi27m", NULL, CLK_IS_ROOT, 27000000), - FRATE(SCLK_HDMIPHY, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 27000000), - FRATE(SCLK_USBPHY0, "sclk_usbphy0", NULL, CLK_IS_ROOT, 48000000), - FRATE(SCLK_USBPHY1, "sclk_usbphy1", NULL, CLK_IS_ROOT, 48000000), + FRATE(SCLK_HDMI27M, "sclk_hdmi27m", NULL, 0, 27000000), + FRATE(SCLK_HDMIPHY, "sclk_hdmiphy", NULL, 0, 27000000), + FRATE(SCLK_USBPHY0, "sclk_usbphy0", NULL, 0, 48000000), + FRATE(SCLK_USBPHY1, "sclk_usbphy1", NULL, 0, 48000000), }; /* S5P6442-specific fixed rate clocks generated inside the SoC. */ static const struct samsung_fixed_rate_clock s5p6442_frate_clks[] __initconst = { - FRATE(SCLK_USBPHY0, "sclk_usbphy0", NULL, CLK_IS_ROOT, 30000000), + FRATE(SCLK_USBPHY0, "sclk_usbphy0", NULL, 0, 30000000), }; /* Common clock dividers. */ -- cgit v0.10.2 From afb4bdc9d8987eb570ef0e9e608459d9fc016de5 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 1 Mar 2016 11:00:00 -0800 Subject: clk: spear: Remove CLK_IS_ROOT This flag is a no-op now. Remove usage of the flag. Acked-by: Viresh Kumar Signed-off-by: Stephen Boyd diff --git a/drivers/clk/spear/spear1310_clock.c b/drivers/clk/spear/spear1310_clock.c index 009bd14..2f86e3f 100644 --- a/drivers/clk/spear/spear1310_clock.c +++ b/drivers/clk/spear/spear1310_clock.c @@ -386,24 +386,20 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base) { struct clk *clk, *clk1; - clk = clk_register_fixed_rate(NULL, "osc_32k_clk", NULL, CLK_IS_ROOT, - 32000); + clk = clk_register_fixed_rate(NULL, "osc_32k_clk", NULL, 0, 32000); clk_register_clkdev(clk, "osc_32k_clk", NULL); - clk = clk_register_fixed_rate(NULL, "osc_24m_clk", NULL, CLK_IS_ROOT, - 24000000); + clk = clk_register_fixed_rate(NULL, "osc_24m_clk", NULL, 0, 24000000); clk_register_clkdev(clk, "osc_24m_clk", NULL); - clk = clk_register_fixed_rate(NULL, "osc_25m_clk", NULL, CLK_IS_ROOT, - 25000000); + clk = clk_register_fixed_rate(NULL, "osc_25m_clk", NULL, 0, 25000000); clk_register_clkdev(clk, "osc_25m_clk", NULL); - clk = clk_register_fixed_rate(NULL, "gmii_pad_clk", NULL, CLK_IS_ROOT, - 125000000); + clk = clk_register_fixed_rate(NULL, "gmii_pad_clk", NULL, 0, 125000000); clk_register_clkdev(clk, "gmii_pad_clk", NULL); - clk = clk_register_fixed_rate(NULL, "i2s_src_pad_clk", NULL, - CLK_IS_ROOT, 12288000); + clk = clk_register_fixed_rate(NULL, "i2s_src_pad_clk", NULL, 0, + 12288000); clk_register_clkdev(clk, "i2s_src_pad_clk", NULL); /* clock derived from 32 KHz osc clk */ @@ -897,11 +893,10 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base) &_lock); clk_register_clkdev(clk, "ras_apb_clk", NULL); - clk = clk_register_fixed_rate(NULL, "ras_plclk0_clk", NULL, CLK_IS_ROOT, + clk = clk_register_fixed_rate(NULL, "ras_plclk0_clk", NULL, 0, 50000000); - clk = clk_register_fixed_rate(NULL, "ras_tx50_clk", NULL, CLK_IS_ROOT, - 50000000); + clk = clk_register_fixed_rate(NULL, "ras_tx50_clk", NULL, 0, 50000000); clk = clk_register_gate(NULL, "can0_clk", "apb_clk", 0, SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_CAN0_CLK_ENB, 0, diff --git a/drivers/clk/spear/spear1340_clock.c b/drivers/clk/spear/spear1340_clock.c index 9c7abfd..cbb19a9 100644 --- a/drivers/clk/spear/spear1340_clock.c +++ b/drivers/clk/spear/spear1340_clock.c @@ -443,24 +443,20 @@ void __init spear1340_clk_init(void __iomem *misc_base) { struct clk *clk, *clk1; - clk = clk_register_fixed_rate(NULL, "osc_32k_clk", NULL, CLK_IS_ROOT, - 32000); + clk = clk_register_fixed_rate(NULL, "osc_32k_clk", NULL, 0, 32000); clk_register_clkdev(clk, "osc_32k_clk", NULL); - clk = clk_register_fixed_rate(NULL, "osc_24m_clk", NULL, CLK_IS_ROOT, - 24000000); + clk = clk_register_fixed_rate(NULL, "osc_24m_clk", NULL, 0, 24000000); clk_register_clkdev(clk, "osc_24m_clk", NULL); - clk = clk_register_fixed_rate(NULL, "osc_25m_clk", NULL, CLK_IS_ROOT, - 25000000); + clk = clk_register_fixed_rate(NULL, "osc_25m_clk", NULL, 0, 25000000); clk_register_clkdev(clk, "osc_25m_clk", NULL); - clk = clk_register_fixed_rate(NULL, "gmii_pad_clk", NULL, CLK_IS_ROOT, - 125000000); + clk = clk_register_fixed_rate(NULL, "gmii_pad_clk", NULL, 0, 125000000); clk_register_clkdev(clk, "gmii_pad_clk", NULL); - clk = clk_register_fixed_rate(NULL, "i2s_src_pad_clk", NULL, - CLK_IS_ROOT, 12288000); + clk = clk_register_fixed_rate(NULL, "i2s_src_pad_clk", NULL, 0, + 12288000); clk_register_clkdev(clk, "i2s_src_pad_clk", NULL); /* clock derived from 32 KHz osc clk */ diff --git a/drivers/clk/spear/spear3xx_clock.c b/drivers/clk/spear/spear3xx_clock.c index 404a55e..c403c66 100644 --- a/drivers/clk/spear/spear3xx_clock.c +++ b/drivers/clk/spear/spear3xx_clock.c @@ -251,7 +251,7 @@ static void __init spear320_clk_init(void __iomem *soc_config_base, struct clk *clk; clk = clk_register_fixed_rate(NULL, "smii_125m_pad_clk", NULL, - CLK_IS_ROOT, 125000000); + 0, 125000000); clk_register_clkdev(clk, "smii_125m_pad", NULL); clk = clk_register_fixed_factor(NULL, "clcd_clk", "ras_pll3_clk", 0, @@ -391,12 +391,10 @@ void __init spear3xx_clk_init(void __iomem *misc_base, void __iomem *soc_config_ { struct clk *clk, *clk1, *ras_apb_clk; - clk = clk_register_fixed_rate(NULL, "osc_32k_clk", NULL, CLK_IS_ROOT, - 32000); + clk = clk_register_fixed_rate(NULL, "osc_32k_clk", NULL, 0, 32000); clk_register_clkdev(clk, "osc_32k_clk", NULL); - clk = clk_register_fixed_rate(NULL, "osc_24m_clk", NULL, CLK_IS_ROOT, - 24000000); + clk = clk_register_fixed_rate(NULL, "osc_24m_clk", NULL, 0, 24000000); clk_register_clkdev(clk, "osc_24m_clk", NULL); /* clock derived from 32 KHz osc clk */ diff --git a/drivers/clk/spear/spear6xx_clock.c b/drivers/clk/spear/spear6xx_clock.c index e24f85c..7c9383c 100644 --- a/drivers/clk/spear/spear6xx_clock.c +++ b/drivers/clk/spear/spear6xx_clock.c @@ -117,12 +117,10 @@ void __init spear6xx_clk_init(void __iomem *misc_base) { struct clk *clk, *clk1; - clk = clk_register_fixed_rate(NULL, "osc_32k_clk", NULL, CLK_IS_ROOT, - 32000); + clk = clk_register_fixed_rate(NULL, "osc_32k_clk", NULL, 0, 32000); clk_register_clkdev(clk, "osc_32k_clk", NULL); - clk = clk_register_fixed_rate(NULL, "osc_30m_clk", NULL, CLK_IS_ROOT, - 30000000); + clk = clk_register_fixed_rate(NULL, "osc_30m_clk", NULL, 0, 30000000); clk_register_clkdev(clk, "osc_30m_clk", NULL); /* clock derived from 32 KHz osc clk */ -- cgit v0.10.2 From f6da46a3074722feb9b4069cf032b924c7251860 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 1 Mar 2016 11:00:02 -0800 Subject: clk: tegra: Remove CLK_IS_ROOT This flag is a no-op now. Remove usage of the flag. Acked-by: Rhyland Klein Acked-by: Thierry Reding Signed-off-by: Stephen Boyd diff --git a/drivers/clk/tegra/clk-audio-sync.c b/drivers/clk/tegra/clk-audio-sync.c index c0f7843..92d04ce 100644 --- a/drivers/clk/tegra/clk-audio-sync.c +++ b/drivers/clk/tegra/clk-audio-sync.c @@ -72,7 +72,7 @@ struct clk *tegra_clk_register_sync_source(const char *name, init.ops = &tegra_clk_sync_source_ops; init.name = name; - init.flags = CLK_IS_ROOT; + init.flags = 0; init.parent_names = NULL; init.num_parents = 0; diff --git a/drivers/clk/tegra/clk-dfll.c b/drivers/clk/tegra/clk-dfll.c index 86a307b..19bfa07 100644 --- a/drivers/clk/tegra/clk-dfll.c +++ b/drivers/clk/tegra/clk-dfll.c @@ -995,7 +995,6 @@ static const struct clk_ops dfll_clk_ops = { }; static struct clk_init_data dfll_clk_init_data = { - .flags = CLK_IS_ROOT, .ops = &dfll_clk_ops, .num_parents = 0, }; diff --git a/drivers/clk/tegra/clk-tegra-fixed.c b/drivers/clk/tegra/clk-tegra-fixed.c index da0b594..d64ec7a 100644 --- a/drivers/clk/tegra/clk-tegra-fixed.c +++ b/drivers/clk/tegra/clk-tegra-fixed.c @@ -52,8 +52,7 @@ int __init tegra_osc_clk_init(void __iomem *clk_base, struct tegra_clk *clks, return -EINVAL; } - osc = clk_register_fixed_rate(NULL, "osc", NULL, CLK_IS_ROOT, - *osc_freq); + osc = clk_register_fixed_rate(NULL, "osc", NULL, 0, *osc_freq); dt_clk = tegra_lookup_dt_id(tegra_clk_clk_m, clks); if (!dt_clk) @@ -88,8 +87,7 @@ void __init tegra_fixed_clk_init(struct tegra_clk *tegra_clks) /* clk_32k */ dt_clk = tegra_lookup_dt_id(tegra_clk_clk_32k, tegra_clks); if (dt_clk) { - clk = clk_register_fixed_rate(NULL, "clk_32k", NULL, - CLK_IS_ROOT, 32768); + clk = clk_register_fixed_rate(NULL, "clk_32k", NULL, 0, 32768); *dt_clk = clk; } diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 4a24aa4..df47ec3 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -972,8 +972,7 @@ static void __init tegra114_fixed_clk_init(void __iomem *clk_base) struct clk *clk; /* clk_32k */ - clk = clk_register_fixed_rate(NULL, "clk_32k", NULL, CLK_IS_ROOT, - 32768); + clk = clk_register_fixed_rate(NULL, "clk_32k", NULL, 0, 32768); clks[TEGRA114_CLK_CLK_32K] = clk; /* clk_m_div2 */ diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index 7a48e98..7ad6383 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -837,15 +837,13 @@ static void __init tegra20_periph_clk_init(void) clks[TEGRA20_CLK_PEX] = clk; /* cdev1 */ - clk = clk_register_fixed_rate(NULL, "cdev1_fixed", NULL, CLK_IS_ROOT, - 26000000); + clk = clk_register_fixed_rate(NULL, "cdev1_fixed", NULL, 0, 26000000); clk = tegra_clk_register_periph_gate("cdev1", "cdev1_fixed", 0, clk_base, 0, 94, periph_clk_enb_refcnt); clks[TEGRA20_CLK_CDEV1] = clk; /* cdev2 */ - clk = clk_register_fixed_rate(NULL, "cdev2_fixed", NULL, CLK_IS_ROOT, - 26000000); + clk = clk_register_fixed_rate(NULL, "cdev2_fixed", NULL, 0, 26000000); clk = tegra_clk_register_periph_gate("cdev2", "cdev2_fixed", 0, clk_base, 0, 93, periph_clk_enb_refcnt); clks[TEGRA20_CLK_CDEV2] = clk; @@ -879,8 +877,8 @@ static void __init tegra20_osc_clk_init(void) input_freq = tegra20_clk_measure_input_freq(); /* clk_m */ - clk = clk_register_fixed_rate(NULL, "clk_m", NULL, CLK_IS_ROOT | - CLK_IGNORE_UNUSED, input_freq); + clk = clk_register_fixed_rate(NULL, "clk_m", NULL, CLK_IGNORE_UNUSED, + input_freq); clks[TEGRA20_CLK_CLK_M] = clk; /* pll_ref */ -- cgit v0.10.2 From 45e21151a2bcddebf7f4d5a8e41a8ca82a5fbb42 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 1 Mar 2016 11:00:03 -0800 Subject: clk: ti: Remove CLK_IS_ROOT This flag is a no-op now. Remove usage of the flag. Acked-by: Tero Kristo Signed-off-by: Stephen Boyd diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c index b5bcd77..5fcf247 100644 --- a/drivers/clk/ti/clk.c +++ b/drivers/clk/ti/clk.c @@ -305,8 +305,8 @@ struct clk __init *ti_clk_register_clk(struct ti_clk *setup) case TI_CLK_FIXED: fixed = setup->data; - clk = clk_register_fixed_rate(NULL, setup->name, NULL, - CLK_IS_ROOT, fixed->frequency); + clk = clk_register_fixed_rate(NULL, setup->name, NULL, 0, + fixed->frequency); break; case TI_CLK_MUX: clk = ti_clk_register_mux(setup); -- cgit v0.10.2 From 66f4ae777d0c2c29e4a937c3c88ddd24b67c4a9a Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 1 Mar 2016 11:00:04 -0800 Subject: clk: ux500: Remove CLK_IS_ROOT This flag is a no-op now. Remove usage of the flag. Acked-by: Ulf Hansson Cc: Linus Walleij Signed-off-by: Stephen Boyd diff --git a/drivers/clk/ux500/abx500-clk.c b/drivers/clk/ux500/abx500-clk.c index 222425d..a07c31e6 100644 --- a/drivers/clk/ux500/abx500-clk.c +++ b/drivers/clk/ux500/abx500-clk.c @@ -40,8 +40,7 @@ static int ab8500_reg_clks(struct device *dev) return ret; /* ab8500_sysclk */ - clk = clk_reg_prcmu_gate("ab8500_sysclk", NULL, PRCMU_SYSCLK, - CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("ab8500_sysclk", NULL, PRCMU_SYSCLK, 0); clk_register_clkdev(clk, "sysclk", "ab8500-usb.0"); clk_register_clkdev(clk, "sysclk", "ab-iddet.0"); clk_register_clkdev(clk, "sysclk", "snd-soc-mop500.0"); @@ -68,7 +67,7 @@ static int ab8500_reg_clks(struct device *dev) clk = clk_reg_sysctrl_gate_fixed_rate(dev, "ulpclk", NULL, AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_ULPCLKREQ, AB8500_SYSULPCLKCTRL1_ULPCLKREQ, - 38400000, 9000, CLK_IS_ROOT); + 38400000, 9000, 0); clk_register_clkdev(clk, "ulpclk", "snd-soc-mop500.0"); /* ab8500_intclk */ diff --git a/drivers/clk/ux500/u8500_of_clk.c b/drivers/clk/ux500/u8500_of_clk.c index 271c096..9a736d9 100644 --- a/drivers/clk/ux500/u8500_of_clk.c +++ b/drivers/clk/ux500/u8500_of_clk.c @@ -91,21 +91,21 @@ void u8500_clk_init(void) /* Clock sources */ clk = clk_reg_prcmu_gate("soc0_pll", NULL, PRCMU_PLLSOC0, - CLK_IS_ROOT|CLK_IGNORE_UNUSED); + CLK_IGNORE_UNUSED); prcmu_clk[PRCMU_PLLSOC0] = clk; clk = clk_reg_prcmu_gate("soc1_pll", NULL, PRCMU_PLLSOC1, - CLK_IS_ROOT|CLK_IGNORE_UNUSED); + CLK_IGNORE_UNUSED); prcmu_clk[PRCMU_PLLSOC1] = clk; clk = clk_reg_prcmu_gate("ddr_pll", NULL, PRCMU_PLLDDR, - CLK_IS_ROOT|CLK_IGNORE_UNUSED); + CLK_IGNORE_UNUSED); prcmu_clk[PRCMU_PLLDDR] = clk; /* FIXME: Add sys, ulp and int clocks here. */ rtc_clk = clk_register_fixed_rate(NULL, "rtc32k", "NULL", - CLK_IS_ROOT|CLK_IGNORE_UNUSED, + CLK_IGNORE_UNUSED, 32768); /* PRCMU clocks */ @@ -126,105 +126,101 @@ void u8500_clk_init(void) clk = clk_reg_prcmu_gate("sgclk", sgaclk_parent, PRCMU_SGACLK, 0); else - clk = clk_reg_prcmu_gate("sgclk", NULL, - PRCMU_SGACLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("sgclk", NULL, PRCMU_SGACLK, 0); prcmu_clk[PRCMU_SGACLK] = clk; - clk = clk_reg_prcmu_gate("uartclk", NULL, PRCMU_UARTCLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("uartclk", NULL, PRCMU_UARTCLK, 0); prcmu_clk[PRCMU_UARTCLK] = clk; - clk = clk_reg_prcmu_gate("msp02clk", NULL, PRCMU_MSP02CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("msp02clk", NULL, PRCMU_MSP02CLK, 0); prcmu_clk[PRCMU_MSP02CLK] = clk; - clk = clk_reg_prcmu_gate("msp1clk", NULL, PRCMU_MSP1CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("msp1clk", NULL, PRCMU_MSP1CLK, 0); prcmu_clk[PRCMU_MSP1CLK] = clk; - clk = clk_reg_prcmu_gate("i2cclk", NULL, PRCMU_I2CCLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("i2cclk", NULL, PRCMU_I2CCLK, 0); prcmu_clk[PRCMU_I2CCLK] = clk; - clk = clk_reg_prcmu_gate("slimclk", NULL, PRCMU_SLIMCLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("slimclk", NULL, PRCMU_SLIMCLK, 0); prcmu_clk[PRCMU_SLIMCLK] = clk; - clk = clk_reg_prcmu_gate("per1clk", NULL, PRCMU_PER1CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("per1clk", NULL, PRCMU_PER1CLK, 0); prcmu_clk[PRCMU_PER1CLK] = clk; - clk = clk_reg_prcmu_gate("per2clk", NULL, PRCMU_PER2CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("per2clk", NULL, PRCMU_PER2CLK, 0); prcmu_clk[PRCMU_PER2CLK] = clk; - clk = clk_reg_prcmu_gate("per3clk", NULL, PRCMU_PER3CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("per3clk", NULL, PRCMU_PER3CLK, 0); prcmu_clk[PRCMU_PER3CLK] = clk; - clk = clk_reg_prcmu_gate("per5clk", NULL, PRCMU_PER5CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("per5clk", NULL, PRCMU_PER5CLK, 0); prcmu_clk[PRCMU_PER5CLK] = clk; - clk = clk_reg_prcmu_gate("per6clk", NULL, PRCMU_PER6CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("per6clk", NULL, PRCMU_PER6CLK, 0); prcmu_clk[PRCMU_PER6CLK] = clk; - clk = clk_reg_prcmu_gate("per7clk", NULL, PRCMU_PER7CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("per7clk", NULL, PRCMU_PER7CLK, 0); prcmu_clk[PRCMU_PER7CLK] = clk; clk = clk_reg_prcmu_scalable("lcdclk", NULL, PRCMU_LCDCLK, 0, - CLK_IS_ROOT|CLK_SET_RATE_GATE); + CLK_SET_RATE_GATE); prcmu_clk[PRCMU_LCDCLK] = clk; - clk = clk_reg_prcmu_opp_gate("bmlclk", NULL, PRCMU_BMLCLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_opp_gate("bmlclk", NULL, PRCMU_BMLCLK, 0); prcmu_clk[PRCMU_BMLCLK] = clk; clk = clk_reg_prcmu_scalable("hsitxclk", NULL, PRCMU_HSITXCLK, 0, - CLK_IS_ROOT|CLK_SET_RATE_GATE); + CLK_SET_RATE_GATE); prcmu_clk[PRCMU_HSITXCLK] = clk; clk = clk_reg_prcmu_scalable("hsirxclk", NULL, PRCMU_HSIRXCLK, 0, - CLK_IS_ROOT|CLK_SET_RATE_GATE); + CLK_SET_RATE_GATE); prcmu_clk[PRCMU_HSIRXCLK] = clk; clk = clk_reg_prcmu_scalable("hdmiclk", NULL, PRCMU_HDMICLK, 0, - CLK_IS_ROOT|CLK_SET_RATE_GATE); + CLK_SET_RATE_GATE); prcmu_clk[PRCMU_HDMICLK] = clk; - clk = clk_reg_prcmu_gate("apeatclk", NULL, PRCMU_APEATCLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("apeatclk", NULL, PRCMU_APEATCLK, 0); prcmu_clk[PRCMU_APEATCLK] = clk; clk = clk_reg_prcmu_scalable("apetraceclk", NULL, PRCMU_APETRACECLK, 0, - CLK_IS_ROOT|CLK_SET_RATE_GATE); + CLK_SET_RATE_GATE); prcmu_clk[PRCMU_APETRACECLK] = clk; - clk = clk_reg_prcmu_gate("mcdeclk", NULL, PRCMU_MCDECLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("mcdeclk", NULL, PRCMU_MCDECLK, 0); prcmu_clk[PRCMU_MCDECLK] = clk; - clk = clk_reg_prcmu_opp_gate("ipi2cclk", NULL, PRCMU_IPI2CCLK, - CLK_IS_ROOT); + clk = clk_reg_prcmu_opp_gate("ipi2cclk", NULL, PRCMU_IPI2CCLK, 0); prcmu_clk[PRCMU_IPI2CCLK] = clk; - clk = clk_reg_prcmu_gate("dsialtclk", NULL, PRCMU_DSIALTCLK, - CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("dsialtclk", NULL, PRCMU_DSIALTCLK, 0); prcmu_clk[PRCMU_DSIALTCLK] = clk; - clk = clk_reg_prcmu_gate("dmaclk", NULL, PRCMU_DMACLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("dmaclk", NULL, PRCMU_DMACLK, 0); prcmu_clk[PRCMU_DMACLK] = clk; - clk = clk_reg_prcmu_gate("b2r2clk", NULL, PRCMU_B2R2CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("b2r2clk", NULL, PRCMU_B2R2CLK, 0); prcmu_clk[PRCMU_B2R2CLK] = clk; clk = clk_reg_prcmu_scalable("tvclk", NULL, PRCMU_TVCLK, 0, - CLK_IS_ROOT|CLK_SET_RATE_GATE); + CLK_SET_RATE_GATE); prcmu_clk[PRCMU_TVCLK] = clk; - clk = clk_reg_prcmu_gate("sspclk", NULL, PRCMU_SSPCLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("sspclk", NULL, PRCMU_SSPCLK, 0); prcmu_clk[PRCMU_SSPCLK] = clk; - clk = clk_reg_prcmu_gate("rngclk", NULL, PRCMU_RNGCLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("rngclk", NULL, PRCMU_RNGCLK, 0); prcmu_clk[PRCMU_RNGCLK] = clk; - clk = clk_reg_prcmu_gate("uiccclk", NULL, PRCMU_UICCCLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("uiccclk", NULL, PRCMU_UICCCLK, 0); prcmu_clk[PRCMU_UICCCLK] = clk; - clk = clk_reg_prcmu_gate("timclk", NULL, PRCMU_TIMCLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("timclk", NULL, PRCMU_TIMCLK, 0); prcmu_clk[PRCMU_TIMCLK] = clk; clk = clk_reg_prcmu_opp_volt_scalable("sdmmcclk", NULL, PRCMU_SDMMCCLK, - 100000000, - CLK_IS_ROOT|CLK_SET_RATE_GATE); + 100000000, CLK_SET_RATE_GATE); prcmu_clk[PRCMU_SDMMCCLK] = clk; clk = clk_reg_prcmu_scalable("dsi_pll", "hdmiclk", @@ -252,7 +248,7 @@ void u8500_clk_init(void) prcmu_clk[PRCMU_DSI2ESCCLK] = clk; clk = clk_reg_prcmu_scalable_rate("armss", NULL, - PRCMU_ARMSS, 0, CLK_IS_ROOT|CLK_IGNORE_UNUSED); + PRCMU_ARMSS, 0, CLK_IGNORE_UNUSED); prcmu_clk[PRCMU_ARMSS] = clk; twd_clk = clk_register_fixed_factor(NULL, "smp_twd", "armss", diff --git a/drivers/clk/ux500/u8540_clk.c b/drivers/clk/ux500/u8540_clk.c index d7bcb7a..86549e5 100644 --- a/drivers/clk/ux500/u8540_clk.c +++ b/drivers/clk/ux500/u8540_clk.c @@ -56,28 +56,28 @@ void u8540_clk_init(void) /* Clock sources. */ /* Fixed ClockGen */ clk = clk_reg_prcmu_gate("soc0_pll", NULL, PRCMU_PLLSOC0, - CLK_IS_ROOT|CLK_IGNORE_UNUSED); + CLK_IGNORE_UNUSED); clk_register_clkdev(clk, "soc0_pll", NULL); clk = clk_reg_prcmu_gate("soc1_pll", NULL, PRCMU_PLLSOC1, - CLK_IS_ROOT|CLK_IGNORE_UNUSED); + CLK_IGNORE_UNUSED); clk_register_clkdev(clk, "soc1_pll", NULL); clk = clk_reg_prcmu_gate("ddr_pll", NULL, PRCMU_PLLDDR, - CLK_IS_ROOT|CLK_IGNORE_UNUSED); + CLK_IGNORE_UNUSED); clk_register_clkdev(clk, "ddr_pll", NULL); clk = clk_register_fixed_rate(NULL, "rtc32k", NULL, - CLK_IS_ROOT|CLK_IGNORE_UNUSED, + CLK_IGNORE_UNUSED, 32768); clk_register_clkdev(clk, "clk32k", NULL); clk_register_clkdev(clk, "apb_pclk", "rtc-pl031"); clk = clk_register_fixed_rate(NULL, "ulp38m4", NULL, - CLK_IS_ROOT|CLK_IGNORE_UNUSED, + CLK_IGNORE_UNUSED, 38400000); - clk = clk_reg_prcmu_gate("uartclk", NULL, PRCMU_UARTCLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("uartclk", NULL, PRCMU_UARTCLK, 0); clk_register_clkdev(clk, NULL, "UART"); /* msp02clk needs a abx500 clk as parent. Handle by abx500 clk driver */ @@ -85,120 +85,116 @@ void u8540_clk_init(void) PRCMU_MSP02CLK, 0); clk_register_clkdev(clk, NULL, "MSP02"); - clk = clk_reg_prcmu_gate("msp1clk", NULL, PRCMU_MSP1CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("msp1clk", NULL, PRCMU_MSP1CLK, 0); clk_register_clkdev(clk, NULL, "MSP1"); - clk = clk_reg_prcmu_gate("i2cclk", NULL, PRCMU_I2CCLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("i2cclk", NULL, PRCMU_I2CCLK, 0); clk_register_clkdev(clk, NULL, "I2C"); - clk = clk_reg_prcmu_gate("slimclk", NULL, PRCMU_SLIMCLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("slimclk", NULL, PRCMU_SLIMCLK, 0); clk_register_clkdev(clk, NULL, "slim"); - clk = clk_reg_prcmu_gate("per1clk", NULL, PRCMU_PER1CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("per1clk", NULL, PRCMU_PER1CLK, 0); clk_register_clkdev(clk, NULL, "PERIPH1"); - clk = clk_reg_prcmu_gate("per2clk", NULL, PRCMU_PER2CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("per2clk", NULL, PRCMU_PER2CLK, 0); clk_register_clkdev(clk, NULL, "PERIPH2"); - clk = clk_reg_prcmu_gate("per3clk", NULL, PRCMU_PER3CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("per3clk", NULL, PRCMU_PER3CLK, 0); clk_register_clkdev(clk, NULL, "PERIPH3"); - clk = clk_reg_prcmu_gate("per5clk", NULL, PRCMU_PER5CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("per5clk", NULL, PRCMU_PER5CLK, 0); clk_register_clkdev(clk, NULL, "PERIPH5"); - clk = clk_reg_prcmu_gate("per6clk", NULL, PRCMU_PER6CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("per6clk", NULL, PRCMU_PER6CLK, 0); clk_register_clkdev(clk, NULL, "PERIPH6"); - clk = clk_reg_prcmu_gate("per7clk", NULL, PRCMU_PER7CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("per7clk", NULL, PRCMU_PER7CLK, 0); clk_register_clkdev(clk, NULL, "PERIPH7"); clk = clk_reg_prcmu_scalable("lcdclk", NULL, PRCMU_LCDCLK, 0, - CLK_IS_ROOT|CLK_SET_RATE_GATE); + CLK_SET_RATE_GATE); clk_register_clkdev(clk, NULL, "lcd"); clk_register_clkdev(clk, "lcd", "mcde"); - clk = clk_reg_prcmu_opp_gate("bmlclk", NULL, PRCMU_BMLCLK, - CLK_IS_ROOT); + clk = clk_reg_prcmu_opp_gate("bmlclk", NULL, PRCMU_BMLCLK, 0); clk_register_clkdev(clk, NULL, "bml"); clk = clk_reg_prcmu_scalable("hsitxclk", NULL, PRCMU_HSITXCLK, 0, - CLK_IS_ROOT|CLK_SET_RATE_GATE); + CLK_SET_RATE_GATE); clk = clk_reg_prcmu_scalable("hsirxclk", NULL, PRCMU_HSIRXCLK, 0, - CLK_IS_ROOT|CLK_SET_RATE_GATE); + CLK_SET_RATE_GATE); clk = clk_reg_prcmu_scalable("hdmiclk", NULL, PRCMU_HDMICLK, 0, - CLK_IS_ROOT|CLK_SET_RATE_GATE); + CLK_SET_RATE_GATE); clk_register_clkdev(clk, NULL, "hdmi"); clk_register_clkdev(clk, "hdmi", "mcde"); - clk = clk_reg_prcmu_gate("apeatclk", NULL, PRCMU_APEATCLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("apeatclk", NULL, PRCMU_APEATCLK, 0); clk_register_clkdev(clk, NULL, "apeat"); - clk = clk_reg_prcmu_gate("apetraceclk", NULL, PRCMU_APETRACECLK, - CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("apetraceclk", NULL, PRCMU_APETRACECLK, 0); clk_register_clkdev(clk, NULL, "apetrace"); - clk = clk_reg_prcmu_gate("mcdeclk", NULL, PRCMU_MCDECLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("mcdeclk", NULL, PRCMU_MCDECLK, 0); clk_register_clkdev(clk, NULL, "mcde"); clk_register_clkdev(clk, "mcde", "mcde"); clk_register_clkdev(clk, NULL, "dsilink.0"); clk_register_clkdev(clk, NULL, "dsilink.1"); clk_register_clkdev(clk, NULL, "dsilink.2"); - clk = clk_reg_prcmu_opp_gate("ipi2cclk", NULL, PRCMU_IPI2CCLK, - CLK_IS_ROOT); + clk = clk_reg_prcmu_opp_gate("ipi2cclk", NULL, PRCMU_IPI2CCLK, 0); clk_register_clkdev(clk, NULL, "ipi2"); - clk = clk_reg_prcmu_gate("dsialtclk", NULL, PRCMU_DSIALTCLK, - CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("dsialtclk", NULL, PRCMU_DSIALTCLK, 0); clk_register_clkdev(clk, NULL, "dsialt"); - clk = clk_reg_prcmu_gate("dmaclk", NULL, PRCMU_DMACLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("dmaclk", NULL, PRCMU_DMACLK, 0); clk_register_clkdev(clk, NULL, "dma40.0"); - clk = clk_reg_prcmu_gate("b2r2clk", NULL, PRCMU_B2R2CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("b2r2clk", NULL, PRCMU_B2R2CLK, 0); clk_register_clkdev(clk, NULL, "b2r2"); clk_register_clkdev(clk, NULL, "b2r2_core"); clk_register_clkdev(clk, NULL, "U8500-B2R2.0"); clk_register_clkdev(clk, NULL, "b2r2_1_core"); clk = clk_reg_prcmu_scalable("tvclk", NULL, PRCMU_TVCLK, 0, - CLK_IS_ROOT|CLK_SET_RATE_GATE); + CLK_SET_RATE_GATE); clk_register_clkdev(clk, NULL, "tv"); clk_register_clkdev(clk, "tv", "mcde"); - clk = clk_reg_prcmu_gate("sspclk", NULL, PRCMU_SSPCLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("sspclk", NULL, PRCMU_SSPCLK, 0); clk_register_clkdev(clk, NULL, "SSP"); - clk = clk_reg_prcmu_gate("rngclk", NULL, PRCMU_RNGCLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("rngclk", NULL, PRCMU_RNGCLK, 0); clk_register_clkdev(clk, NULL, "rngclk"); - clk = clk_reg_prcmu_gate("uiccclk", NULL, PRCMU_UICCCLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("uiccclk", NULL, PRCMU_UICCCLK, 0); clk_register_clkdev(clk, NULL, "uicc"); - clk = clk_reg_prcmu_gate("timclk", NULL, PRCMU_TIMCLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("timclk", NULL, PRCMU_TIMCLK, 0); clk_register_clkdev(clk, NULL, "mtu0"); clk_register_clkdev(clk, NULL, "mtu1"); clk = clk_reg_prcmu_opp_volt_scalable("sdmmcclk", NULL, PRCMU_SDMMCCLK, 100000000, - CLK_IS_ROOT|CLK_SET_RATE_GATE); + CLK_SET_RATE_GATE); clk_register_clkdev(clk, NULL, "sdmmc"); clk = clk_reg_prcmu_opp_volt_scalable("sdmmchclk", NULL, PRCMU_SDMMCHCLK, 400000000, - CLK_IS_ROOT|CLK_SET_RATE_GATE); + CLK_SET_RATE_GATE); clk_register_clkdev(clk, NULL, "sdmmchclk"); - clk = clk_reg_prcmu_gate("hvaclk", NULL, PRCMU_HVACLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("hvaclk", NULL, PRCMU_HVACLK, 0); clk_register_clkdev(clk, NULL, "hva"); - clk = clk_reg_prcmu_gate("g1clk", NULL, PRCMU_G1CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("g1clk", NULL, PRCMU_G1CLK, 0); clk_register_clkdev(clk, NULL, "g1"); clk = clk_reg_prcmu_scalable("spare1clk", NULL, PRCMU_SPARE1CLK, 0, - CLK_IS_ROOT|CLK_SET_RATE_GATE); + CLK_SET_RATE_GATE); clk_register_clkdev(clk, "dsilcd", "mcde"); clk = clk_reg_prcmu_scalable("dsi_pll", "hdmiclk", @@ -244,7 +240,7 @@ void u8540_clk_init(void) clk_register_clkdev(clk, "dsilp2", "mcde"); clk = clk_reg_prcmu_scalable_rate("armss", NULL, - PRCMU_ARMSS, 0, CLK_IS_ROOT|CLK_IGNORE_UNUSED); + PRCMU_ARMSS, 0, CLK_IGNORE_UNUSED); clk_register_clkdev(clk, "armss", NULL); clk = clk_register_fixed_factor(NULL, "smp_twd", "armss", -- cgit v0.10.2 From 0b4d613a71decf62fc15aad03a5f0d740b80713e Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 1 Mar 2016 11:00:09 -0800 Subject: clk: zynq: Remove CLK_IS_ROOT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This flag is a no-op now. Remove usage of the flag. Reviewed-by: Sören Brinkmann Signed-off-by: Stephen Boyd diff --git a/drivers/clk/zynq/clkc.c b/drivers/clk/zynq/clkc.c index 38a65c3..88a2cab 100644 --- a/drivers/clk/zynq/clkc.c +++ b/drivers/clk/zynq/clkc.c @@ -265,8 +265,7 @@ static void __init zynq_clk_setup(struct device_node *np) pr_warn("ps_clk frequency not specified, using 33 MHz.\n"); tmp = 33333333; } - ps_clk = clk_register_fixed_rate(NULL, "ps_clk", NULL, CLK_IS_ROOT, - tmp); + ps_clk = clk_register_fixed_rate(NULL, "ps_clk", NULL, 0, tmp); /* PLLs */ clk = clk_register_zynq_pll("armpll_int", "ps_clk", SLCR_ARMPLL_CTRL, -- cgit v0.10.2 From 124603990d903f867e66504c658cab9de4fc05e2 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 1 Mar 2016 11:00:11 -0800 Subject: clk: efm32gg: Remove CLK_IS_ROOT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This flag is a no-op now. Remove usage of the flag. Acked-by: Uwe Kleine-König Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk-efm32gg.c b/drivers/clk/clk-efm32gg.c index bac4553..22e4c65 100644 --- a/drivers/clk/clk-efm32gg.c +++ b/drivers/clk/clk-efm32gg.c @@ -36,7 +36,7 @@ static void __init efm32gg_cmu_init(struct device_node *np) } clk[clk_HFXO] = clk_register_fixed_rate(NULL, "HFXO", NULL, - CLK_IS_ROOT, 48000000); + 0, 48000000); clk[clk_HFPERCLKUSART0] = clk_register_gate(NULL, "HFPERCLK.USART0", "HFXO", 0, base + CMU_HFPERCLKEN0, 0, 0, NULL); -- cgit v0.10.2 From 1edfc1e700c09714b170664da93a081c596b94bf Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 1 Mar 2016 11:00:18 -0800 Subject: clk: pwm: Remove CLK_IS_ROOT This flag is a no-op now. Remove usage of the flag. Acked-by: Philipp Zabel Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk-pwm.c b/drivers/clk/clk-pwm.c index 328fcfc..8830458 100644 --- a/drivers/clk/clk-pwm.c +++ b/drivers/clk/clk-pwm.c @@ -95,7 +95,7 @@ static int clk_pwm_probe(struct platform_device *pdev) init.name = clk_name; init.ops = &clk_pwm_ops; - init.flags = CLK_IS_BASIC | CLK_IS_ROOT; + init.flags = CLK_IS_BASIC; init.num_parents = 0; clk_pwm->pwm = pwm; -- cgit v0.10.2 From 86209252315ccede613914b55e9e2af8015da509 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 1 Mar 2016 11:00:21 -0800 Subject: clk: s2mps11: Remove CLK_IS_ROOT This flag is a no-op now. Remove usage of the flag. Acked-by: Andi Shyti Cc: Krzysztof Kozlowski Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk-s2mps11.c b/drivers/clk/clk-s2mps11.c index 371150a..f8c8397 100644 --- a/drivers/clk/clk-s2mps11.c +++ b/drivers/clk/clk-s2mps11.c @@ -99,17 +99,14 @@ static struct clk_init_data s2mps11_clks_init[S2MPS11_CLKS_NUM] = { [S2MPS11_CLK_AP] = { .name = "s2mps11_ap", .ops = &s2mps11_clk_ops, - .flags = CLK_IS_ROOT, }, [S2MPS11_CLK_CP] = { .name = "s2mps11_cp", .ops = &s2mps11_clk_ops, - .flags = CLK_IS_ROOT, }, [S2MPS11_CLK_BT] = { .name = "s2mps11_bt", .ops = &s2mps11_clk_ops, - .flags = CLK_IS_ROOT, }, }; -- cgit v0.10.2 From 905936823ec56c451357f4ca75ceff8092bea2f0 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 1 Mar 2016 11:00:22 -0800 Subject: clk: scpi: Remove CLK_IS_ROOT This flag is a no-op now. Remove usage of the flag. Acked-by: Sudeep Holla Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk-scpi.c b/drivers/clk/clk-scpi.c index 89e9ca7..6962ee5 100644 --- a/drivers/clk/clk-scpi.c +++ b/drivers/clk/clk-scpi.c @@ -155,7 +155,7 @@ scpi_clk_ops_init(struct device *dev, const struct of_device_id *match, unsigned long min = 0, max = 0; init.name = name; - init.flags = CLK_IS_ROOT; + init.flags = 0; init.num_parents = 0; init.ops = match->data; sclk->hw.init = &init; -- cgit v0.10.2 From 803c43311fcc7e4ff4f01814a663dee9497d34f5 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 1 Mar 2016 11:00:23 -0800 Subject: clk: si5{14,351,70}: Remove CLK_IS_ROOT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This flag is a no-op now. Remove usage of the flag. Cc: Sebastian Hesselbarth Cc: Guenter Roeck Reviewed-by: Sören Brinkmann Cc: Mike Looijmans Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk-si514.c b/drivers/clk/clk-si514.c index 6af7dce..ceef25b 100644 --- a/drivers/clk/clk-si514.c +++ b/drivers/clk/clk-si514.c @@ -313,7 +313,7 @@ static int si514_probe(struct i2c_client *client, return -ENOMEM; init.ops = &si514_clk_ops; - init.flags = CLK_IS_ROOT; + init.flags = 0; init.num_parents = 0; data->hw.init = &init; data->i2c_client = client; diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c index 850316a..b1bc12c 100644 --- a/drivers/clk/clk-si5351.c +++ b/drivers/clk/clk-si5351.c @@ -1495,7 +1495,7 @@ static int si5351_i2c_probe(struct i2c_client *client, if (drvdata->variant == SI5351_VARIANT_B) { init.name = si5351_pll_names[2]; init.ops = &si5351_vxco_ops; - init.flags = CLK_IS_ROOT; + init.flags = 0; init.parent_names = NULL; init.num_parents = 0; } else { diff --git a/drivers/clk/clk-si570.c b/drivers/clk/clk-si570.c index cf478aa..d566485 100644 --- a/drivers/clk/clk-si570.c +++ b/drivers/clk/clk-si570.c @@ -418,7 +418,7 @@ static int si570_probe(struct i2c_client *client, return -ENOMEM; init.ops = &si570_clk_ops; - init.flags = CLK_IS_ROOT; + init.flags = 0; init.num_parents = 0; data->hw.init = &init; data->i2c_client = client; -- cgit v0.10.2 From b3a33077c0ddb9819398091c70e5999afa8a4526 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Thu, 3 Mar 2016 11:18:06 +0900 Subject: clk: renesas: move drivers to renesas directory This is part of an ongoing process to migrate from ARCH_SHMOBILE to ARCH_RENESAS the motivation for which being that RENESAS seems to be a more appropriate name than SHMOBILE for the majority of Renesas ARM based SoCs. Along with the above mentioned Kconfig changes it seems appropriate to also rename directories that only hold drivers for such SoCs. Signed-off-by: Simon Horman Acked-by: Geert Uytterhoeven Signed-off-by: Stephen Boyd diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 08c0003..46869d6 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -70,7 +70,7 @@ obj-$(CONFIG_COMMON_CLK_PXA) += pxa/ obj-$(CONFIG_COMMON_CLK_QCOM) += qcom/ obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ obj-$(CONFIG_COMMON_CLK_SAMSUNG) += samsung/ -obj-$(CONFIG_ARCH_RENESAS) += shmobile/ +obj-$(CONFIG_ARCH_RENESAS) += renesas/ obj-$(CONFIG_ARCH_SIRF) += sirf/ obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/ obj-$(CONFIG_PLAT_SPEAR) += spear/ diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile new file mode 100644 index 0000000..7e2579b --- /dev/null +++ b/drivers/clk/renesas/Makefile @@ -0,0 +1,13 @@ +obj-$(CONFIG_ARCH_EMEV2) += clk-emev2.o +obj-$(CONFIG_ARCH_R7S72100) += clk-rz.o clk-mstp.o +obj-$(CONFIG_ARCH_R8A73A4) += clk-r8a73a4.o clk-mstp.o clk-div6.o +obj-$(CONFIG_ARCH_R8A7740) += clk-r8a7740.o clk-mstp.o clk-div6.o +obj-$(CONFIG_ARCH_R8A7778) += clk-r8a7778.o clk-mstp.o +obj-$(CONFIG_ARCH_R8A7779) += clk-r8a7779.o clk-mstp.o +obj-$(CONFIG_ARCH_R8A7790) += clk-rcar-gen2.o clk-mstp.o clk-div6.o +obj-$(CONFIG_ARCH_R8A7791) += clk-rcar-gen2.o clk-mstp.o clk-div6.o +obj-$(CONFIG_ARCH_R8A7793) += clk-rcar-gen2.o clk-mstp.o clk-div6.o +obj-$(CONFIG_ARCH_R8A7794) += clk-rcar-gen2.o clk-mstp.o clk-div6.o +obj-$(CONFIG_ARCH_R8A7795) += renesas-cpg-mssr.o \ + r8a7795-cpg-mssr.o clk-div6.o +obj-$(CONFIG_ARCH_SH73A0) += clk-sh73a0.o clk-mstp.o clk-div6.o diff --git a/drivers/clk/renesas/clk-div6.c b/drivers/clk/renesas/clk-div6.c new file mode 100644 index 0000000..0627860 --- /dev/null +++ b/drivers/clk/renesas/clk-div6.c @@ -0,0 +1,318 @@ +/* + * r8a7790 Common Clock Framework support + * + * Copyright (C) 2013 Renesas Solutions Corp. + * + * Contact: Laurent Pinchart + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "clk-div6.h" + +#define CPG_DIV6_CKSTP BIT(8) +#define CPG_DIV6_DIV(d) ((d) & 0x3f) +#define CPG_DIV6_DIV_MASK 0x3f + +/** + * struct div6_clock - CPG 6 bit divider clock + * @hw: handle between common and hardware-specific interfaces + * @reg: IO-remapped register + * @div: divisor value (1-64) + */ +struct div6_clock { + struct clk_hw hw; + void __iomem *reg; + unsigned int div; + u32 src_shift; + u32 src_width; + u8 *parents; +}; + +#define to_div6_clock(_hw) container_of(_hw, struct div6_clock, hw) + +static int cpg_div6_clock_enable(struct clk_hw *hw) +{ + struct div6_clock *clock = to_div6_clock(hw); + u32 val; + + val = (clk_readl(clock->reg) & ~(CPG_DIV6_DIV_MASK | CPG_DIV6_CKSTP)) + | CPG_DIV6_DIV(clock->div - 1); + clk_writel(val, clock->reg); + + return 0; +} + +static void cpg_div6_clock_disable(struct clk_hw *hw) +{ + struct div6_clock *clock = to_div6_clock(hw); + u32 val; + + val = clk_readl(clock->reg); + val |= CPG_DIV6_CKSTP; + /* + * DIV6 clocks require the divisor field to be non-zero when stopping + * the clock. However, some clocks (e.g. ZB on sh73a0) fail to be + * re-enabled later if the divisor field is changed when stopping the + * clock + */ + if (!(val & CPG_DIV6_DIV_MASK)) + val |= CPG_DIV6_DIV_MASK; + clk_writel(val, clock->reg); +} + +static int cpg_div6_clock_is_enabled(struct clk_hw *hw) +{ + struct div6_clock *clock = to_div6_clock(hw); + + return !(clk_readl(clock->reg) & CPG_DIV6_CKSTP); +} + +static unsigned long cpg_div6_clock_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct div6_clock *clock = to_div6_clock(hw); + + return parent_rate / clock->div; +} + +static unsigned int cpg_div6_clock_calc_div(unsigned long rate, + unsigned long parent_rate) +{ + unsigned int div; + + if (!rate) + rate = 1; + + div = DIV_ROUND_CLOSEST(parent_rate, rate); + return clamp_t(unsigned int, div, 1, 64); +} + +static long cpg_div6_clock_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + unsigned int div = cpg_div6_clock_calc_div(rate, *parent_rate); + + return *parent_rate / div; +} + +static int cpg_div6_clock_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct div6_clock *clock = to_div6_clock(hw); + unsigned int div = cpg_div6_clock_calc_div(rate, parent_rate); + u32 val; + + clock->div = div; + + val = clk_readl(clock->reg) & ~CPG_DIV6_DIV_MASK; + /* Only program the new divisor if the clock isn't stopped. */ + if (!(val & CPG_DIV6_CKSTP)) + clk_writel(val | CPG_DIV6_DIV(clock->div - 1), clock->reg); + + return 0; +} + +static u8 cpg_div6_clock_get_parent(struct clk_hw *hw) +{ + struct div6_clock *clock = to_div6_clock(hw); + unsigned int i; + u8 hw_index; + + if (clock->src_width == 0) + return 0; + + hw_index = (clk_readl(clock->reg) >> clock->src_shift) & + (BIT(clock->src_width) - 1); + for (i = 0; i < clk_hw_get_num_parents(hw); i++) { + if (clock->parents[i] == hw_index) + return i; + } + + pr_err("%s: %s DIV6 clock set to invalid parent %u\n", + __func__, clk_hw_get_name(hw), hw_index); + return 0; +} + +static int cpg_div6_clock_set_parent(struct clk_hw *hw, u8 index) +{ + struct div6_clock *clock = to_div6_clock(hw); + u8 hw_index; + u32 mask; + + if (index >= clk_hw_get_num_parents(hw)) + return -EINVAL; + + mask = ~((BIT(clock->src_width) - 1) << clock->src_shift); + hw_index = clock->parents[index]; + + clk_writel((clk_readl(clock->reg) & mask) | + (hw_index << clock->src_shift), clock->reg); + + return 0; +} + +static const struct clk_ops cpg_div6_clock_ops = { + .enable = cpg_div6_clock_enable, + .disable = cpg_div6_clock_disable, + .is_enabled = cpg_div6_clock_is_enabled, + .get_parent = cpg_div6_clock_get_parent, + .set_parent = cpg_div6_clock_set_parent, + .recalc_rate = cpg_div6_clock_recalc_rate, + .round_rate = cpg_div6_clock_round_rate, + .set_rate = cpg_div6_clock_set_rate, +}; + + +/** + * cpg_div6_register - Register a DIV6 clock + * @name: Name of the DIV6 clock + * @num_parents: Number of parent clocks of the DIV6 clock (1, 4, or 8) + * @parent_names: Array containing the names of the parent clocks + * @reg: Mapped register used to control the DIV6 clock + */ +struct clk * __init cpg_div6_register(const char *name, + unsigned int num_parents, + const char **parent_names, + void __iomem *reg) +{ + unsigned int valid_parents; + struct clk_init_data init; + struct div6_clock *clock; + struct clk *clk; + unsigned int i; + + clock = kzalloc(sizeof(*clock), GFP_KERNEL); + if (!clock) + return ERR_PTR(-ENOMEM); + + clock->parents = kmalloc_array(num_parents, sizeof(*clock->parents), + GFP_KERNEL); + if (!clock->parents) { + clk = ERR_PTR(-ENOMEM); + goto free_clock; + } + + clock->reg = reg; + + /* + * Read the divisor. Disabling the clock overwrites the divisor, so we + * need to cache its value for the enable operation. + */ + clock->div = (clk_readl(clock->reg) & CPG_DIV6_DIV_MASK) + 1; + + switch (num_parents) { + case 1: + /* fixed parent clock */ + clock->src_shift = clock->src_width = 0; + break; + case 4: + /* clock with EXSRC bits 6-7 */ + clock->src_shift = 6; + clock->src_width = 2; + break; + case 8: + /* VCLK with EXSRC bits 12-14 */ + clock->src_shift = 12; + clock->src_width = 3; + break; + default: + pr_err("%s: invalid number of parents for DIV6 clock %s\n", + __func__, name); + clk = ERR_PTR(-EINVAL); + goto free_parents; + } + + /* Filter out invalid parents */ + for (i = 0, valid_parents = 0; i < num_parents; i++) { + if (parent_names[i]) { + parent_names[valid_parents] = parent_names[i]; + clock->parents[valid_parents] = i; + valid_parents++; + } + } + + /* Register the clock. */ + init.name = name; + init.ops = &cpg_div6_clock_ops; + init.flags = CLK_IS_BASIC; + init.parent_names = parent_names; + init.num_parents = valid_parents; + + clock->hw.init = &init; + + clk = clk_register(NULL, &clock->hw); + if (IS_ERR(clk)) + goto free_parents; + + return clk; + +free_parents: + kfree(clock->parents); +free_clock: + kfree(clock); + return clk; +} + +static void __init cpg_div6_clock_init(struct device_node *np) +{ + unsigned int num_parents; + const char **parent_names; + const char *clk_name = np->name; + void __iomem *reg; + struct clk *clk; + unsigned int i; + + num_parents = of_clk_get_parent_count(np); + if (num_parents < 1) { + pr_err("%s: no parent found for %s DIV6 clock\n", + __func__, np->name); + return; + } + + parent_names = kmalloc_array(num_parents, sizeof(*parent_names), + GFP_KERNEL); + if (!parent_names) + return; + + reg = of_iomap(np, 0); + if (reg == NULL) { + pr_err("%s: failed to map %s DIV6 clock register\n", + __func__, np->name); + goto error; + } + + /* Parse the DT properties. */ + of_property_read_string(np, "clock-output-names", &clk_name); + + for (i = 0; i < num_parents; i++) + parent_names[i] = of_clk_get_parent_name(np, i); + + clk = cpg_div6_register(clk_name, num_parents, parent_names, reg); + if (IS_ERR(clk)) { + pr_err("%s: failed to register %s DIV6 clock (%ld)\n", + __func__, np->name, PTR_ERR(clk)); + goto error; + } + + of_clk_add_provider(np, of_clk_src_simple_get, clk); + + kfree(parent_names); + return; + +error: + if (reg) + iounmap(reg); + kfree(parent_names); +} +CLK_OF_DECLARE(cpg_div6_clk, "renesas,cpg-div6-clock", cpg_div6_clock_init); diff --git a/drivers/clk/renesas/clk-div6.h b/drivers/clk/renesas/clk-div6.h new file mode 100644 index 0000000..9a85a95 --- /dev/null +++ b/drivers/clk/renesas/clk-div6.h @@ -0,0 +1,7 @@ +#ifndef __SHMOBILE_CLK_DIV6_H__ +#define __SHMOBILE_CLK_DIV6_H__ + +struct clk *cpg_div6_register(const char *name, unsigned int num_parents, + const char **parent_names, void __iomem *reg); + +#endif diff --git a/drivers/clk/renesas/clk-emev2.c b/drivers/clk/renesas/clk-emev2.c new file mode 100644 index 0000000..a918254 --- /dev/null +++ b/drivers/clk/renesas/clk-emev2.c @@ -0,0 +1,110 @@ +/* + * EMMA Mobile EV2 common clock framework support + * + * Copyright (C) 2013 Takashi Yoshii + * Copyright (C) 2012 Magnus Damm + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include +#include +#include +#include +#include + +/* EMEV2 SMU registers */ +#define USIAU0_RSTCTRL 0x094 +#define USIBU1_RSTCTRL 0x0ac +#define USIBU2_RSTCTRL 0x0b0 +#define USIBU3_RSTCTRL 0x0b4 +#define IIC0_RSTCTRL 0x0dc +#define IIC1_RSTCTRL 0x0e0 +#define STI_RSTCTRL 0x124 +#define STI_CLKSEL 0x688 + +static DEFINE_SPINLOCK(lock); + +/* not pretty, but hey */ +static void __iomem *smu_base; + +static void __init emev2_smu_write(unsigned long value, int offs) +{ + BUG_ON(!smu_base || (offs >= PAGE_SIZE)); + writel_relaxed(value, smu_base + offs); +} + +static const struct of_device_id smu_id[] __initconst = { + { .compatible = "renesas,emev2-smu", }, + {}, +}; + +static void __init emev2_smu_init(void) +{ + struct device_node *np; + + np = of_find_matching_node(NULL, smu_id); + BUG_ON(!np); + smu_base = of_iomap(np, 0); + BUG_ON(!smu_base); + of_node_put(np); + + /* setup STI timer to run on 32.768 kHz and deassert reset */ + emev2_smu_write(0, STI_CLKSEL); + emev2_smu_write(1, STI_RSTCTRL); + + /* deassert reset for UART0->UART3 */ + emev2_smu_write(2, USIAU0_RSTCTRL); + emev2_smu_write(2, USIBU1_RSTCTRL); + emev2_smu_write(2, USIBU2_RSTCTRL); + emev2_smu_write(2, USIBU3_RSTCTRL); + + /* deassert reset for IIC0->IIC1 */ + emev2_smu_write(1, IIC0_RSTCTRL); + emev2_smu_write(1, IIC1_RSTCTRL); +} + +static void __init emev2_smu_clkdiv_init(struct device_node *np) +{ + u32 reg[2]; + struct clk *clk; + const char *parent_name = of_clk_get_parent_name(np, 0); + if (WARN_ON(of_property_read_u32_array(np, "reg", reg, 2))) + return; + if (!smu_base) + emev2_smu_init(); + clk = clk_register_divider(NULL, np->name, parent_name, 0, + smu_base + reg[0], reg[1], 8, 0, &lock); + of_clk_add_provider(np, of_clk_src_simple_get, clk); + clk_register_clkdev(clk, np->name, NULL); + pr_debug("## %s %s %p\n", __func__, np->name, clk); +} +CLK_OF_DECLARE(emev2_smu_clkdiv, "renesas,emev2-smu-clkdiv", + emev2_smu_clkdiv_init); + +static void __init emev2_smu_gclk_init(struct device_node *np) +{ + u32 reg[2]; + struct clk *clk; + const char *parent_name = of_clk_get_parent_name(np, 0); + if (WARN_ON(of_property_read_u32_array(np, "reg", reg, 2))) + return; + if (!smu_base) + emev2_smu_init(); + clk = clk_register_gate(NULL, np->name, parent_name, 0, + smu_base + reg[0], reg[1], 0, &lock); + of_clk_add_provider(np, of_clk_src_simple_get, clk); + clk_register_clkdev(clk, np->name, NULL); + pr_debug("## %s %s %p\n", __func__, np->name, clk); +} +CLK_OF_DECLARE(emev2_smu_gclk, "renesas,emev2-smu-gclk", emev2_smu_gclk_init); diff --git a/drivers/clk/renesas/clk-mstp.c b/drivers/clk/renesas/clk-mstp.c new file mode 100644 index 0000000..3b09716 --- /dev/null +++ b/drivers/clk/renesas/clk-mstp.c @@ -0,0 +1,329 @@ +/* + * R-Car MSTP clocks + * + * Copyright (C) 2013 Ideas On Board SPRL + * Copyright (C) 2015 Glider bvba + * + * Contact: Laurent Pinchart + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * MSTP clocks. We can't use standard gate clocks as we need to poll on the + * status register when enabling the clock. + */ + +#define MSTP_MAX_CLOCKS 32 + +/** + * struct mstp_clock_group - MSTP gating clocks group + * + * @data: clocks in this group + * @smstpcr: module stop control register + * @mstpsr: module stop status register (optional) + * @lock: protects writes to SMSTPCR + */ +struct mstp_clock_group { + struct clk_onecell_data data; + void __iomem *smstpcr; + void __iomem *mstpsr; + spinlock_t lock; +}; + +/** + * struct mstp_clock - MSTP gating clock + * @hw: handle between common and hardware-specific interfaces + * @bit_index: control bit index + * @group: MSTP clocks group + */ +struct mstp_clock { + struct clk_hw hw; + u32 bit_index; + struct mstp_clock_group *group; +}; + +#define to_mstp_clock(_hw) container_of(_hw, struct mstp_clock, hw) + +static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable) +{ + struct mstp_clock *clock = to_mstp_clock(hw); + struct mstp_clock_group *group = clock->group; + u32 bitmask = BIT(clock->bit_index); + unsigned long flags; + unsigned int i; + u32 value; + + spin_lock_irqsave(&group->lock, flags); + + value = clk_readl(group->smstpcr); + if (enable) + value &= ~bitmask; + else + value |= bitmask; + clk_writel(value, group->smstpcr); + + spin_unlock_irqrestore(&group->lock, flags); + + if (!enable || !group->mstpsr) + return 0; + + for (i = 1000; i > 0; --i) { + if (!(clk_readl(group->mstpsr) & bitmask)) + break; + cpu_relax(); + } + + if (!i) { + pr_err("%s: failed to enable %p[%d]\n", __func__, + group->smstpcr, clock->bit_index); + return -ETIMEDOUT; + } + + return 0; +} + +static int cpg_mstp_clock_enable(struct clk_hw *hw) +{ + return cpg_mstp_clock_endisable(hw, true); +} + +static void cpg_mstp_clock_disable(struct clk_hw *hw) +{ + cpg_mstp_clock_endisable(hw, false); +} + +static int cpg_mstp_clock_is_enabled(struct clk_hw *hw) +{ + struct mstp_clock *clock = to_mstp_clock(hw); + struct mstp_clock_group *group = clock->group; + u32 value; + + if (group->mstpsr) + value = clk_readl(group->mstpsr); + else + value = clk_readl(group->smstpcr); + + return !(value & BIT(clock->bit_index)); +} + +static const struct clk_ops cpg_mstp_clock_ops = { + .enable = cpg_mstp_clock_enable, + .disable = cpg_mstp_clock_disable, + .is_enabled = cpg_mstp_clock_is_enabled, +}; + +static struct clk * __init +cpg_mstp_clock_register(const char *name, const char *parent_name, + unsigned int index, struct mstp_clock_group *group) +{ + struct clk_init_data init; + struct mstp_clock *clock; + struct clk *clk; + + clock = kzalloc(sizeof(*clock), GFP_KERNEL); + if (!clock) { + pr_err("%s: failed to allocate MSTP clock.\n", __func__); + return ERR_PTR(-ENOMEM); + } + + init.name = name; + init.ops = &cpg_mstp_clock_ops; + init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; + init.parent_names = &parent_name; + init.num_parents = 1; + + clock->bit_index = index; + clock->group = group; + clock->hw.init = &init; + + clk = clk_register(NULL, &clock->hw); + + if (IS_ERR(clk)) + kfree(clock); + + return clk; +} + +static void __init cpg_mstp_clocks_init(struct device_node *np) +{ + struct mstp_clock_group *group; + const char *idxname; + struct clk **clks; + unsigned int i; + + group = kzalloc(sizeof(*group), GFP_KERNEL); + clks = kmalloc(MSTP_MAX_CLOCKS * sizeof(*clks), GFP_KERNEL); + if (group == NULL || clks == NULL) { + kfree(group); + kfree(clks); + pr_err("%s: failed to allocate group\n", __func__); + return; + } + + spin_lock_init(&group->lock); + group->data.clks = clks; + + group->smstpcr = of_iomap(np, 0); + group->mstpsr = of_iomap(np, 1); + + if (group->smstpcr == NULL) { + pr_err("%s: failed to remap SMSTPCR\n", __func__); + kfree(group); + kfree(clks); + return; + } + + for (i = 0; i < MSTP_MAX_CLOCKS; ++i) + clks[i] = ERR_PTR(-ENOENT); + + if (of_find_property(np, "clock-indices", &i)) + idxname = "clock-indices"; + else + idxname = "renesas,clock-indices"; + + for (i = 0; i < MSTP_MAX_CLOCKS; ++i) { + const char *parent_name; + const char *name; + u32 clkidx; + int ret; + + /* Skip clocks with no name. */ + ret = of_property_read_string_index(np, "clock-output-names", + i, &name); + if (ret < 0 || strlen(name) == 0) + continue; + + parent_name = of_clk_get_parent_name(np, i); + ret = of_property_read_u32_index(np, idxname, i, &clkidx); + if (parent_name == NULL || ret < 0) + break; + + if (clkidx >= MSTP_MAX_CLOCKS) { + pr_err("%s: invalid clock %s %s index %u\n", + __func__, np->name, name, clkidx); + continue; + } + + clks[clkidx] = cpg_mstp_clock_register(name, parent_name, + clkidx, group); + if (!IS_ERR(clks[clkidx])) { + group->data.clk_num = max(group->data.clk_num, + clkidx + 1); + /* + * Register a clkdev to let board code retrieve the + * clock by name and register aliases for non-DT + * devices. + * + * FIXME: Remove this when all devices that require a + * clock will be instantiated from DT. + */ + clk_register_clkdev(clks[clkidx], name, NULL); + } else { + pr_err("%s: failed to register %s %s clock (%ld)\n", + __func__, np->name, name, PTR_ERR(clks[clkidx])); + } + } + + of_clk_add_provider(np, of_clk_src_onecell_get, &group->data); +} +CLK_OF_DECLARE(cpg_mstp_clks, "renesas,cpg-mstp-clocks", cpg_mstp_clocks_init); + + +#ifdef CONFIG_PM_GENERIC_DOMAINS_OF +int cpg_mstp_attach_dev(struct generic_pm_domain *domain, struct device *dev) +{ + struct device_node *np = dev->of_node; + struct of_phandle_args clkspec; + struct clk *clk; + int i = 0; + int error; + + while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i, + &clkspec)) { + if (of_device_is_compatible(clkspec.np, + "renesas,cpg-mstp-clocks")) + goto found; + + /* BSC on r8a73a4/sh73a0 uses zb_clk instead of an mstp clock */ + if (!strcmp(clkspec.np->name, "zb_clk")) + goto found; + + of_node_put(clkspec.np); + i++; + } + + return 0; + +found: + clk = of_clk_get_from_provider(&clkspec); + of_node_put(clkspec.np); + + if (IS_ERR(clk)) + return PTR_ERR(clk); + + error = pm_clk_create(dev); + if (error) { + dev_err(dev, "pm_clk_create failed %d\n", error); + goto fail_put; + } + + error = pm_clk_add_clk(dev, clk); + if (error) { + dev_err(dev, "pm_clk_add_clk %pC failed %d\n", clk, error); + goto fail_destroy; + } + + return 0; + +fail_destroy: + pm_clk_destroy(dev); +fail_put: + clk_put(clk); + return error; +} + +void cpg_mstp_detach_dev(struct generic_pm_domain *domain, struct device *dev) +{ + if (!list_empty(&dev->power.subsys_data->clock_list)) + pm_clk_destroy(dev); +} + +void __init cpg_mstp_add_clk_domain(struct device_node *np) +{ + struct generic_pm_domain *pd; + u32 ncells; + + if (of_property_read_u32(np, "#power-domain-cells", &ncells)) { + pr_warn("%s lacks #power-domain-cells\n", np->full_name); + return; + } + + pd = kzalloc(sizeof(*pd), GFP_KERNEL); + if (!pd) + return; + + pd->name = np->name; + + pd->flags = GENPD_FLAG_PM_CLK; + pm_genpd_init(pd, &simple_qos_governor, false); + pd->attach_dev = cpg_mstp_attach_dev; + pd->detach_dev = cpg_mstp_detach_dev; + + of_genpd_add_provider_simple(np, pd); +} +#endif /* !CONFIG_PM_GENERIC_DOMAINS_OF */ diff --git a/drivers/clk/renesas/clk-r8a73a4.c b/drivers/clk/renesas/clk-r8a73a4.c new file mode 100644 index 0000000..9326204 --- /dev/null +++ b/drivers/clk/renesas/clk-r8a73a4.c @@ -0,0 +1,241 @@ +/* + * r8a73a4 Core CPG Clocks + * + * Copyright (C) 2014 Ulrich Hecht + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct r8a73a4_cpg { + struct clk_onecell_data data; + spinlock_t lock; + void __iomem *reg; +}; + +#define CPG_CKSCR 0xc0 +#define CPG_FRQCRA 0x00 +#define CPG_FRQCRB 0x04 +#define CPG_FRQCRC 0xe0 +#define CPG_PLL0CR 0xd8 +#define CPG_PLL1CR 0x28 +#define CPG_PLL2CR 0x2c +#define CPG_PLL2HCR 0xe4 +#define CPG_PLL2SCR 0xf4 + +#define CLK_ENABLE_ON_INIT BIT(0) + +struct div4_clk { + const char *name; + unsigned int reg; + unsigned int shift; +}; + +static struct div4_clk div4_clks[] = { + { "i", CPG_FRQCRA, 20 }, + { "m3", CPG_FRQCRA, 12 }, + { "b", CPG_FRQCRA, 8 }, + { "m1", CPG_FRQCRA, 4 }, + { "m2", CPG_FRQCRA, 0 }, + { "zx", CPG_FRQCRB, 12 }, + { "zs", CPG_FRQCRB, 8 }, + { "hp", CPG_FRQCRB, 4 }, + { NULL, 0, 0 }, +}; + +static const struct clk_div_table div4_div_table[] = { + { 0, 2 }, { 1, 3 }, { 2, 4 }, { 3, 6 }, { 4, 8 }, { 5, 12 }, + { 6, 16 }, { 7, 18 }, { 8, 24 }, { 10, 36 }, { 11, 48 }, + { 12, 10 }, { 0, 0 } +}; + +static struct clk * __init +r8a73a4_cpg_register_clock(struct device_node *np, struct r8a73a4_cpg *cpg, + const char *name) +{ + const struct clk_div_table *table = NULL; + const char *parent_name; + unsigned int shift, reg; + unsigned int mult = 1; + unsigned int div = 1; + + + if (!strcmp(name, "main")) { + u32 ckscr = clk_readl(cpg->reg + CPG_CKSCR); + + switch ((ckscr >> 28) & 3) { + case 0: /* extal1 */ + parent_name = of_clk_get_parent_name(np, 0); + break; + case 1: /* extal1 / 2 */ + parent_name = of_clk_get_parent_name(np, 0); + div = 2; + break; + case 2: /* extal2 */ + parent_name = of_clk_get_parent_name(np, 1); + break; + case 3: /* extal2 / 2 */ + parent_name = of_clk_get_parent_name(np, 1); + div = 2; + break; + } + } else if (!strcmp(name, "pll0")) { + /* PLL0/1 are configurable multiplier clocks. Register them as + * fixed factor clocks for now as there's no generic multiplier + * clock implementation and we currently have no need to change + * the multiplier value. + */ + u32 value = clk_readl(cpg->reg + CPG_PLL0CR); + + parent_name = "main"; + mult = ((value >> 24) & 0x7f) + 1; + if (value & BIT(20)) + div = 2; + } else if (!strcmp(name, "pll1")) { + u32 value = clk_readl(cpg->reg + CPG_PLL1CR); + + parent_name = "main"; + /* XXX: enable bit? */ + mult = ((value >> 24) & 0x7f) + 1; + if (value & BIT(7)) + div = 2; + } else if (!strncmp(name, "pll2", 4)) { + u32 value, cr; + + switch (name[4]) { + case 0: + cr = CPG_PLL2CR; + break; + case 's': + cr = CPG_PLL2SCR; + break; + case 'h': + cr = CPG_PLL2HCR; + break; + default: + return ERR_PTR(-EINVAL); + } + value = clk_readl(cpg->reg + cr); + switch ((value >> 5) & 7) { + case 0: + parent_name = "main"; + div = 2; + break; + case 1: + parent_name = "extal2"; + div = 2; + break; + case 3: + parent_name = "extal2"; + div = 4; + break; + case 4: + parent_name = "main"; + break; + case 5: + parent_name = "extal2"; + break; + default: + pr_warn("%s: unexpected parent of %s\n", __func__, + name); + return ERR_PTR(-EINVAL); + } + /* XXX: enable bit? */ + mult = ((value >> 24) & 0x7f) + 1; + } else if (!strcmp(name, "z") || !strcmp(name, "z2")) { + u32 shift = 8; + + parent_name = "pll0"; + if (name[1] == '2') { + div = 2; + shift = 0; + } + div *= 32; + mult = 0x20 - ((clk_readl(cpg->reg + CPG_FRQCRC) >> shift) + & 0x1f); + } else { + struct div4_clk *c; + + for (c = div4_clks; c->name; c++) { + if (!strcmp(name, c->name)) + break; + } + if (!c->name) + return ERR_PTR(-EINVAL); + + parent_name = "pll1"; + table = div4_div_table; + reg = c->reg; + shift = c->shift; + } + + if (!table) { + return clk_register_fixed_factor(NULL, name, parent_name, 0, + mult, div); + } else { + return clk_register_divider_table(NULL, name, parent_name, 0, + cpg->reg + reg, shift, 4, 0, + table, &cpg->lock); + } +} + +static void __init r8a73a4_cpg_clocks_init(struct device_node *np) +{ + struct r8a73a4_cpg *cpg; + struct clk **clks; + unsigned int i; + int num_clks; + + num_clks = of_property_count_strings(np, "clock-output-names"); + if (num_clks < 0) { + pr_err("%s: failed to count clocks\n", __func__); + return; + } + + cpg = kzalloc(sizeof(*cpg), GFP_KERNEL); + clks = kcalloc(num_clks, sizeof(*clks), GFP_KERNEL); + if (cpg == NULL || clks == NULL) { + /* We're leaking memory on purpose, there's no point in cleaning + * up as the system won't boot anyway. + */ + return; + } + + spin_lock_init(&cpg->lock); + + cpg->data.clks = clks; + cpg->data.clk_num = num_clks; + + cpg->reg = of_iomap(np, 0); + if (WARN_ON(cpg->reg == NULL)) + return; + + for (i = 0; i < num_clks; ++i) { + const char *name; + struct clk *clk; + + of_property_read_string_index(np, "clock-output-names", i, + &name); + + clk = r8a73a4_cpg_register_clock(np, cpg, name); + if (IS_ERR(clk)) + pr_err("%s: failed to register %s %s clock (%ld)\n", + __func__, np->name, name, PTR_ERR(clk)); + else + cpg->data.clks[i] = clk; + } + + of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data); +} +CLK_OF_DECLARE(r8a73a4_cpg_clks, "renesas,r8a73a4-cpg-clocks", + r8a73a4_cpg_clocks_init); diff --git a/drivers/clk/renesas/clk-r8a7740.c b/drivers/clk/renesas/clk-r8a7740.c new file mode 100644 index 0000000..1e6b1da --- /dev/null +++ b/drivers/clk/renesas/clk-r8a7740.c @@ -0,0 +1,199 @@ +/* + * r8a7740 Core CPG Clocks + * + * Copyright (C) 2014 Ulrich Hecht + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct r8a7740_cpg { + struct clk_onecell_data data; + spinlock_t lock; + void __iomem *reg; +}; + +#define CPG_FRQCRA 0x00 +#define CPG_FRQCRB 0x04 +#define CPG_PLLC2CR 0x2c +#define CPG_USBCKCR 0x8c +#define CPG_FRQCRC 0xe0 + +#define CLK_ENABLE_ON_INIT BIT(0) + +struct div4_clk { + const char *name; + unsigned int reg; + unsigned int shift; + int flags; +}; + +static struct div4_clk div4_clks[] = { + { "i", CPG_FRQCRA, 20, CLK_ENABLE_ON_INIT }, + { "zg", CPG_FRQCRA, 16, CLK_ENABLE_ON_INIT }, + { "b", CPG_FRQCRA, 8, CLK_ENABLE_ON_INIT }, + { "m1", CPG_FRQCRA, 4, CLK_ENABLE_ON_INIT }, + { "hp", CPG_FRQCRB, 4, 0 }, + { "hpp", CPG_FRQCRC, 20, 0 }, + { "usbp", CPG_FRQCRC, 16, 0 }, + { "s", CPG_FRQCRC, 12, 0 }, + { "zb", CPG_FRQCRC, 8, 0 }, + { "m3", CPG_FRQCRC, 4, 0 }, + { "cp", CPG_FRQCRC, 0, 0 }, + { NULL, 0, 0, 0 }, +}; + +static const struct clk_div_table div4_div_table[] = { + { 0, 2 }, { 1, 3 }, { 2, 4 }, { 3, 6 }, { 4, 8 }, { 5, 12 }, + { 6, 16 }, { 7, 18 }, { 8, 24 }, { 9, 32 }, { 10, 36 }, { 11, 48 }, + { 13, 72 }, { 14, 96 }, { 0, 0 } +}; + +static u32 cpg_mode __initdata; + +static struct clk * __init +r8a7740_cpg_register_clock(struct device_node *np, struct r8a7740_cpg *cpg, + const char *name) +{ + const struct clk_div_table *table = NULL; + const char *parent_name; + unsigned int shift, reg; + unsigned int mult = 1; + unsigned int div = 1; + + if (!strcmp(name, "r")) { + switch (cpg_mode & (BIT(2) | BIT(1))) { + case BIT(1) | BIT(2): + /* extal1 */ + parent_name = of_clk_get_parent_name(np, 0); + div = 2048; + break; + case BIT(2): + /* extal1 */ + parent_name = of_clk_get_parent_name(np, 0); + div = 1024; + break; + default: + /* extalr */ + parent_name = of_clk_get_parent_name(np, 2); + break; + } + } else if (!strcmp(name, "system")) { + parent_name = of_clk_get_parent_name(np, 0); + if (cpg_mode & BIT(1)) + div = 2; + } else if (!strcmp(name, "pllc0")) { + /* PLLC0/1 are configurable multiplier clocks. Register them as + * fixed factor clocks for now as there's no generic multiplier + * clock implementation and we currently have no need to change + * the multiplier value. + */ + u32 value = clk_readl(cpg->reg + CPG_FRQCRC); + parent_name = "system"; + mult = ((value >> 24) & 0x7f) + 1; + } else if (!strcmp(name, "pllc1")) { + u32 value = clk_readl(cpg->reg + CPG_FRQCRA); + parent_name = "system"; + mult = ((value >> 24) & 0x7f) + 1; + div = 2; + } else if (!strcmp(name, "pllc2")) { + u32 value = clk_readl(cpg->reg + CPG_PLLC2CR); + parent_name = "system"; + mult = ((value >> 24) & 0x3f) + 1; + } else if (!strcmp(name, "usb24s")) { + u32 value = clk_readl(cpg->reg + CPG_USBCKCR); + if (value & BIT(7)) + /* extal2 */ + parent_name = of_clk_get_parent_name(np, 1); + else + parent_name = "system"; + if (!(value & BIT(6))) + div = 2; + } else { + struct div4_clk *c; + for (c = div4_clks; c->name; c++) { + if (!strcmp(name, c->name)) { + parent_name = "pllc1"; + table = div4_div_table; + reg = c->reg; + shift = c->shift; + break; + } + } + if (!c->name) + return ERR_PTR(-EINVAL); + } + + if (!table) { + return clk_register_fixed_factor(NULL, name, parent_name, 0, + mult, div); + } else { + return clk_register_divider_table(NULL, name, parent_name, 0, + cpg->reg + reg, shift, 4, 0, + table, &cpg->lock); + } +} + +static void __init r8a7740_cpg_clocks_init(struct device_node *np) +{ + struct r8a7740_cpg *cpg; + struct clk **clks; + unsigned int i; + int num_clks; + + if (of_property_read_u32(np, "renesas,mode", &cpg_mode)) + pr_warn("%s: missing renesas,mode property\n", __func__); + + num_clks = of_property_count_strings(np, "clock-output-names"); + if (num_clks < 0) { + pr_err("%s: failed to count clocks\n", __func__); + return; + } + + cpg = kzalloc(sizeof(*cpg), GFP_KERNEL); + clks = kzalloc(num_clks * sizeof(*clks), GFP_KERNEL); + if (cpg == NULL || clks == NULL) { + /* We're leaking memory on purpose, there's no point in cleaning + * up as the system won't boot anyway. + */ + return; + } + + spin_lock_init(&cpg->lock); + + cpg->data.clks = clks; + cpg->data.clk_num = num_clks; + + cpg->reg = of_iomap(np, 0); + if (WARN_ON(cpg->reg == NULL)) + return; + + for (i = 0; i < num_clks; ++i) { + const char *name; + struct clk *clk; + + of_property_read_string_index(np, "clock-output-names", i, + &name); + + clk = r8a7740_cpg_register_clock(np, cpg, name); + if (IS_ERR(clk)) + pr_err("%s: failed to register %s %s clock (%ld)\n", + __func__, np->name, name, PTR_ERR(clk)); + else + cpg->data.clks[i] = clk; + } + + of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data); +} +CLK_OF_DECLARE(r8a7740_cpg_clks, "renesas,r8a7740-cpg-clocks", + r8a7740_cpg_clocks_init); diff --git a/drivers/clk/renesas/clk-r8a7778.c b/drivers/clk/renesas/clk-r8a7778.c new file mode 100644 index 0000000..b174155 --- /dev/null +++ b/drivers/clk/renesas/clk-r8a7778.c @@ -0,0 +1,145 @@ +/* + * r8a7778 Core CPG Clocks + * + * Copyright (C) 2014 Ulrich Hecht + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + */ + +#include +#include +#include +#include + +struct r8a7778_cpg { + struct clk_onecell_data data; + spinlock_t lock; + void __iomem *reg; +}; + +/* PLL multipliers per bits 11, 12, and 18 of MODEMR */ +static const struct { + unsigned long plla_mult; + unsigned long pllb_mult; +} r8a7778_rates[] __initconst = { + [0] = { 21, 21 }, + [1] = { 24, 24 }, + [2] = { 28, 28 }, + [3] = { 32, 32 }, + [5] = { 24, 21 }, + [6] = { 28, 21 }, + [7] = { 32, 24 }, +}; + +/* Clock dividers per bits 1 and 2 of MODEMR */ +static const struct { + const char *name; + unsigned int div[4]; +} r8a7778_divs[6] __initconst = { + { "b", { 12, 12, 16, 18 } }, + { "out", { 12, 12, 16, 18 } }, + { "p", { 16, 12, 16, 12 } }, + { "s", { 4, 3, 4, 3 } }, + { "s1", { 8, 6, 8, 6 } }, +}; + +static u32 cpg_mode_rates __initdata; +static u32 cpg_mode_divs __initdata; + +static struct clk * __init +r8a7778_cpg_register_clock(struct device_node *np, struct r8a7778_cpg *cpg, + const char *name) +{ + if (!strcmp(name, "plla")) { + return clk_register_fixed_factor(NULL, "plla", + of_clk_get_parent_name(np, 0), 0, + r8a7778_rates[cpg_mode_rates].plla_mult, 1); + } else if (!strcmp(name, "pllb")) { + return clk_register_fixed_factor(NULL, "pllb", + of_clk_get_parent_name(np, 0), 0, + r8a7778_rates[cpg_mode_rates].pllb_mult, 1); + } else { + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(r8a7778_divs); i++) { + if (!strcmp(name, r8a7778_divs[i].name)) { + return clk_register_fixed_factor(NULL, + r8a7778_divs[i].name, + "plla", 0, 1, + r8a7778_divs[i].div[cpg_mode_divs]); + } + } + } + + return ERR_PTR(-EINVAL); +} + + +static void __init r8a7778_cpg_clocks_init(struct device_node *np) +{ + struct r8a7778_cpg *cpg; + struct clk **clks; + unsigned int i; + int num_clks; + + num_clks = of_property_count_strings(np, "clock-output-names"); + if (num_clks < 0) { + pr_err("%s: failed to count clocks\n", __func__); + return; + } + + cpg = kzalloc(sizeof(*cpg), GFP_KERNEL); + clks = kcalloc(num_clks, sizeof(*clks), GFP_KERNEL); + if (cpg == NULL || clks == NULL) { + /* We're leaking memory on purpose, there's no point in cleaning + * up as the system won't boot anyway. + */ + return; + } + + spin_lock_init(&cpg->lock); + + cpg->data.clks = clks; + cpg->data.clk_num = num_clks; + + cpg->reg = of_iomap(np, 0); + if (WARN_ON(cpg->reg == NULL)) + return; + + for (i = 0; i < num_clks; ++i) { + const char *name; + struct clk *clk; + + of_property_read_string_index(np, "clock-output-names", i, + &name); + + clk = r8a7778_cpg_register_clock(np, cpg, name); + if (IS_ERR(clk)) + pr_err("%s: failed to register %s %s clock (%ld)\n", + __func__, np->name, name, PTR_ERR(clk)); + else + cpg->data.clks[i] = clk; + } + + of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data); + + cpg_mstp_add_clk_domain(np); +} + +CLK_OF_DECLARE(r8a7778_cpg_clks, "renesas,r8a7778-cpg-clocks", + r8a7778_cpg_clocks_init); + +void __init r8a7778_clocks_init(u32 mode) +{ + BUG_ON(!(mode & BIT(19))); + + cpg_mode_rates = (!!(mode & BIT(18)) << 2) | + (!!(mode & BIT(12)) << 1) | + (!!(mode & BIT(11))); + cpg_mode_divs = (!!(mode & BIT(2)) << 1) | + (!!(mode & BIT(1))); + + of_clk_init(NULL); +} diff --git a/drivers/clk/renesas/clk-r8a7779.c b/drivers/clk/renesas/clk-r8a7779.c new file mode 100644 index 0000000..92275c5f --- /dev/null +++ b/drivers/clk/renesas/clk-r8a7779.c @@ -0,0 +1,182 @@ +/* + * r8a7779 Core CPG Clocks + * + * Copyright (C) 2013, 2014 Horms Solutions Ltd. + * + * Contact: Simon Horman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define CPG_NUM_CLOCKS (R8A7779_CLK_OUT + 1) + +struct r8a7779_cpg { + struct clk_onecell_data data; + spinlock_t lock; + void __iomem *reg; +}; + +/* ----------------------------------------------------------------------------- + * CPG Clock Data + */ + +/* + * MD1 = 1 MD1 = 0 + * (PLLA = 1500) (PLLA = 1600) + * (MHz) (MHz) + *------------------------------------------------+-------------------- + * clkz 1000 (2/3) 800 (1/2) + * clkzs 250 (1/6) 200 (1/8) + * clki 750 (1/2) 800 (1/2) + * clks 250 (1/6) 200 (1/8) + * clks1 125 (1/12) 100 (1/16) + * clks3 187.5 (1/8) 200 (1/8) + * clks4 93.7 (1/16) 100 (1/16) + * clkp 62.5 (1/24) 50 (1/32) + * clkg 62.5 (1/24) 66.6 (1/24) + * clkb, CLKOUT + * (MD2 = 0) 62.5 (1/24) 66.6 (1/24) + * (MD2 = 1) 41.6 (1/36) 50 (1/32) + */ + +#define CPG_CLK_CONFIG_INDEX(md) (((md) & (BIT(2)|BIT(1))) >> 1) + +struct cpg_clk_config { + unsigned int z_mult; + unsigned int z_div; + unsigned int zs_and_s_div; + unsigned int s1_div; + unsigned int p_div; + unsigned int b_and_out_div; +}; + +static const struct cpg_clk_config cpg_clk_configs[4] __initconst = { + { 1, 2, 8, 16, 32, 24 }, + { 2, 3, 6, 12, 24, 24 }, + { 1, 2, 8, 16, 32, 32 }, + { 2, 3, 6, 12, 24, 36 }, +}; + +/* + * MD PLLA Ratio + * 12 11 + *------------------------ + * 0 0 x42 + * 0 1 x48 + * 1 0 x56 + * 1 1 x64 + */ + +#define CPG_PLLA_MULT_INDEX(md) (((md) & (BIT(12)|BIT(11))) >> 11) + +static const unsigned int cpg_plla_mult[4] __initconst = { 42, 48, 56, 64 }; + +/* ----------------------------------------------------------------------------- + * Initialization + */ + +static u32 cpg_mode __initdata; + +static struct clk * __init +r8a7779_cpg_register_clock(struct device_node *np, struct r8a7779_cpg *cpg, + const struct cpg_clk_config *config, + unsigned int plla_mult, const char *name) +{ + const char *parent_name = "plla"; + unsigned int mult = 1; + unsigned int div = 1; + + if (!strcmp(name, "plla")) { + parent_name = of_clk_get_parent_name(np, 0); + mult = plla_mult; + } else if (!strcmp(name, "z")) { + div = config->z_div; + mult = config->z_mult; + } else if (!strcmp(name, "zs") || !strcmp(name, "s")) { + div = config->zs_and_s_div; + } else if (!strcmp(name, "s1")) { + div = config->s1_div; + } else if (!strcmp(name, "p")) { + div = config->p_div; + } else if (!strcmp(name, "b") || !strcmp(name, "out")) { + div = config->b_and_out_div; + } else { + return ERR_PTR(-EINVAL); + } + + return clk_register_fixed_factor(NULL, name, parent_name, 0, mult, div); +} + +static void __init r8a7779_cpg_clocks_init(struct device_node *np) +{ + const struct cpg_clk_config *config; + struct r8a7779_cpg *cpg; + struct clk **clks; + unsigned int i, plla_mult; + int num_clks; + + num_clks = of_property_count_strings(np, "clock-output-names"); + if (num_clks < 0) { + pr_err("%s: failed to count clocks\n", __func__); + return; + } + + cpg = kzalloc(sizeof(*cpg), GFP_KERNEL); + clks = kzalloc(CPG_NUM_CLOCKS * sizeof(*clks), GFP_KERNEL); + if (cpg == NULL || clks == NULL) { + /* We're leaking memory on purpose, there's no point in cleaning + * up as the system won't boot anyway. + */ + return; + } + + spin_lock_init(&cpg->lock); + + cpg->data.clks = clks; + cpg->data.clk_num = num_clks; + + config = &cpg_clk_configs[CPG_CLK_CONFIG_INDEX(cpg_mode)]; + plla_mult = cpg_plla_mult[CPG_PLLA_MULT_INDEX(cpg_mode)]; + + for (i = 0; i < num_clks; ++i) { + const char *name; + struct clk *clk; + + of_property_read_string_index(np, "clock-output-names", i, + &name); + + clk = r8a7779_cpg_register_clock(np, cpg, config, + plla_mult, name); + if (IS_ERR(clk)) + pr_err("%s: failed to register %s %s clock (%ld)\n", + __func__, np->name, name, PTR_ERR(clk)); + else + cpg->data.clks[i] = clk; + } + + of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data); + + cpg_mstp_add_clk_domain(np); +} +CLK_OF_DECLARE(r8a7779_cpg_clks, "renesas,r8a7779-cpg-clocks", + r8a7779_cpg_clocks_init); + +void __init r8a7779_clocks_init(u32 mode) +{ + cpg_mode = mode; + + of_clk_init(NULL); +} diff --git a/drivers/clk/renesas/clk-rcar-gen2.c b/drivers/clk/renesas/clk-rcar-gen2.c new file mode 100644 index 0000000..8419772 --- /dev/null +++ b/drivers/clk/renesas/clk-rcar-gen2.c @@ -0,0 +1,429 @@ +/* + * rcar_gen2 Core CPG Clocks + * + * Copyright (C) 2013 Ideas On Board SPRL + * + * Contact: Laurent Pinchart + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct rcar_gen2_cpg { + struct clk_onecell_data data; + spinlock_t lock; + void __iomem *reg; +}; + +#define CPG_FRQCRB 0x00000004 +#define CPG_FRQCRB_KICK BIT(31) +#define CPG_SDCKCR 0x00000074 +#define CPG_PLL0CR 0x000000d8 +#define CPG_FRQCRC 0x000000e0 +#define CPG_FRQCRC_ZFC_MASK (0x1f << 8) +#define CPG_FRQCRC_ZFC_SHIFT 8 +#define CPG_ADSPCKCR 0x0000025c +#define CPG_RCANCKCR 0x00000270 + +/* ----------------------------------------------------------------------------- + * Z Clock + * + * Traits of this clock: + * prepare - clk_prepare only ensures that parents are prepared + * enable - clk_enable only ensures that parents are enabled + * rate - rate is adjustable. clk->rate = parent->rate * mult / 32 + * parent - fixed parent. No clk_set_parent support + */ + +struct cpg_z_clk { + struct clk_hw hw; + void __iomem *reg; + void __iomem *kick_reg; +}; + +#define to_z_clk(_hw) container_of(_hw, struct cpg_z_clk, hw) + +static unsigned long cpg_z_clk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct cpg_z_clk *zclk = to_z_clk(hw); + unsigned int mult; + unsigned int val; + + val = (clk_readl(zclk->reg) & CPG_FRQCRC_ZFC_MASK) + >> CPG_FRQCRC_ZFC_SHIFT; + mult = 32 - val; + + return div_u64((u64)parent_rate * mult, 32); +} + +static long cpg_z_clk_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + unsigned long prate = *parent_rate; + unsigned int mult; + + if (!prate) + prate = 1; + + mult = div_u64((u64)rate * 32, prate); + mult = clamp(mult, 1U, 32U); + + return *parent_rate / 32 * mult; +} + +static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct cpg_z_clk *zclk = to_z_clk(hw); + unsigned int mult; + u32 val, kick; + unsigned int i; + + mult = div_u64((u64)rate * 32, parent_rate); + mult = clamp(mult, 1U, 32U); + + if (clk_readl(zclk->kick_reg) & CPG_FRQCRB_KICK) + return -EBUSY; + + val = clk_readl(zclk->reg); + val &= ~CPG_FRQCRC_ZFC_MASK; + val |= (32 - mult) << CPG_FRQCRC_ZFC_SHIFT; + clk_writel(val, zclk->reg); + + /* + * Set KICK bit in FRQCRB to update hardware setting and wait for + * clock change completion. + */ + kick = clk_readl(zclk->kick_reg); + kick |= CPG_FRQCRB_KICK; + clk_writel(kick, zclk->kick_reg); + + /* + * Note: There is no HW information about the worst case latency. + * + * Using experimental measurements, it seems that no more than + * ~10 iterations are needed, independently of the CPU rate. + * Since this value might be dependent on external xtal rate, pll1 + * rate or even the other emulation clocks rate, use 1000 as a + * "super" safe value. + */ + for (i = 1000; i; i--) { + if (!(clk_readl(zclk->kick_reg) & CPG_FRQCRB_KICK)) + return 0; + + cpu_relax(); + } + + return -ETIMEDOUT; +} + +static const struct clk_ops cpg_z_clk_ops = { + .recalc_rate = cpg_z_clk_recalc_rate, + .round_rate = cpg_z_clk_round_rate, + .set_rate = cpg_z_clk_set_rate, +}; + +static struct clk * __init cpg_z_clk_register(struct rcar_gen2_cpg *cpg) +{ + static const char *parent_name = "pll0"; + struct clk_init_data init; + struct cpg_z_clk *zclk; + struct clk *clk; + + zclk = kzalloc(sizeof(*zclk), GFP_KERNEL); + if (!zclk) + return ERR_PTR(-ENOMEM); + + init.name = "z"; + init.ops = &cpg_z_clk_ops; + init.flags = 0; + init.parent_names = &parent_name; + init.num_parents = 1; + + zclk->reg = cpg->reg + CPG_FRQCRC; + zclk->kick_reg = cpg->reg + CPG_FRQCRB; + zclk->hw.init = &init; + + clk = clk_register(NULL, &zclk->hw); + if (IS_ERR(clk)) + kfree(zclk); + + return clk; +} + +static struct clk * __init cpg_rcan_clk_register(struct rcar_gen2_cpg *cpg, + struct device_node *np) +{ + const char *parent_name = of_clk_get_parent_name(np, 1); + struct clk_fixed_factor *fixed; + struct clk_gate *gate; + struct clk *clk; + + fixed = kzalloc(sizeof(*fixed), GFP_KERNEL); + if (!fixed) + return ERR_PTR(-ENOMEM); + + fixed->mult = 1; + fixed->div = 6; + + gate = kzalloc(sizeof(*gate), GFP_KERNEL); + if (!gate) { + kfree(fixed); + return ERR_PTR(-ENOMEM); + } + + gate->reg = cpg->reg + CPG_RCANCKCR; + gate->bit_idx = 8; + gate->flags = CLK_GATE_SET_TO_DISABLE; + gate->lock = &cpg->lock; + + clk = clk_register_composite(NULL, "rcan", &parent_name, 1, NULL, NULL, + &fixed->hw, &clk_fixed_factor_ops, + &gate->hw, &clk_gate_ops, 0); + if (IS_ERR(clk)) { + kfree(gate); + kfree(fixed); + } + + return clk; +} + +/* ADSP divisors */ +static const struct clk_div_table cpg_adsp_div_table[] = { + { 1, 3 }, { 2, 4 }, { 3, 6 }, { 4, 8 }, + { 5, 12 }, { 6, 16 }, { 7, 18 }, { 8, 24 }, + { 10, 36 }, { 11, 48 }, { 0, 0 }, +}; + +static struct clk * __init cpg_adsp_clk_register(struct rcar_gen2_cpg *cpg) +{ + const char *parent_name = "pll1"; + struct clk_divider *div; + struct clk_gate *gate; + struct clk *clk; + + div = kzalloc(sizeof(*div), GFP_KERNEL); + if (!div) + return ERR_PTR(-ENOMEM); + + div->reg = cpg->reg + CPG_ADSPCKCR; + div->width = 4; + div->table = cpg_adsp_div_table; + div->lock = &cpg->lock; + + gate = kzalloc(sizeof(*gate), GFP_KERNEL); + if (!gate) { + kfree(div); + return ERR_PTR(-ENOMEM); + } + + gate->reg = cpg->reg + CPG_ADSPCKCR; + gate->bit_idx = 8; + gate->flags = CLK_GATE_SET_TO_DISABLE; + gate->lock = &cpg->lock; + + clk = clk_register_composite(NULL, "adsp", &parent_name, 1, NULL, NULL, + &div->hw, &clk_divider_ops, + &gate->hw, &clk_gate_ops, 0); + if (IS_ERR(clk)) { + kfree(gate); + kfree(div); + } + + return clk; +} + +/* ----------------------------------------------------------------------------- + * CPG Clock Data + */ + +/* + * MD EXTAL PLL0 PLL1 PLL3 + * 14 13 19 (MHz) *1 *1 + *--------------------------------------------------- + * 0 0 0 15 x 1 x172/2 x208/2 x106 + * 0 0 1 15 x 1 x172/2 x208/2 x88 + * 0 1 0 20 x 1 x130/2 x156/2 x80 + * 0 1 1 20 x 1 x130/2 x156/2 x66 + * 1 0 0 26 / 2 x200/2 x240/2 x122 + * 1 0 1 26 / 2 x200/2 x240/2 x102 + * 1 1 0 30 / 2 x172/2 x208/2 x106 + * 1 1 1 30 / 2 x172/2 x208/2 x88 + * + * *1 : Table 7.6 indicates VCO output (PLLx = VCO/2) + */ +#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 12) | \ + (((md) & BIT(13)) >> 12) | \ + (((md) & BIT(19)) >> 19)) +struct cpg_pll_config { + unsigned int extal_div; + unsigned int pll1_mult; + unsigned int pll3_mult; +}; + +static const struct cpg_pll_config cpg_pll_configs[8] __initconst = { + { 1, 208, 106 }, { 1, 208, 88 }, { 1, 156, 80 }, { 1, 156, 66 }, + { 2, 240, 122 }, { 2, 240, 102 }, { 2, 208, 106 }, { 2, 208, 88 }, +}; + +/* SDHI divisors */ +static const struct clk_div_table cpg_sdh_div_table[] = { + { 0, 2 }, { 1, 3 }, { 2, 4 }, { 3, 6 }, + { 4, 8 }, { 5, 12 }, { 6, 16 }, { 7, 18 }, + { 8, 24 }, { 10, 36 }, { 11, 48 }, { 0, 0 }, +}; + +static const struct clk_div_table cpg_sd01_div_table[] = { + { 4, 8 }, + { 5, 12 }, { 6, 16 }, { 7, 18 }, { 8, 24 }, + { 10, 36 }, { 11, 48 }, { 12, 10 }, { 0, 0 }, +}; + +/* ----------------------------------------------------------------------------- + * Initialization + */ + +static u32 cpg_mode __initdata; + +static struct clk * __init +rcar_gen2_cpg_register_clock(struct device_node *np, struct rcar_gen2_cpg *cpg, + const struct cpg_pll_config *config, + const char *name) +{ + const struct clk_div_table *table = NULL; + const char *parent_name; + unsigned int shift; + unsigned int mult = 1; + unsigned int div = 1; + + if (!strcmp(name, "main")) { + parent_name = of_clk_get_parent_name(np, 0); + div = config->extal_div; + } else if (!strcmp(name, "pll0")) { + /* PLL0 is a configurable multiplier clock. Register it as a + * fixed factor clock for now as there's no generic multiplier + * clock implementation and we currently have no need to change + * the multiplier value. + */ + u32 value = clk_readl(cpg->reg + CPG_PLL0CR); + parent_name = "main"; + mult = ((value >> 24) & ((1 << 7) - 1)) + 1; + } else if (!strcmp(name, "pll1")) { + parent_name = "main"; + mult = config->pll1_mult / 2; + } else if (!strcmp(name, "pll3")) { + parent_name = "main"; + mult = config->pll3_mult; + } else if (!strcmp(name, "lb")) { + parent_name = "pll1"; + div = cpg_mode & BIT(18) ? 36 : 24; + } else if (!strcmp(name, "qspi")) { + parent_name = "pll1_div2"; + div = (cpg_mode & (BIT(3) | BIT(2) | BIT(1))) == BIT(2) + ? 8 : 10; + } else if (!strcmp(name, "sdh")) { + parent_name = "pll1"; + table = cpg_sdh_div_table; + shift = 8; + } else if (!strcmp(name, "sd0")) { + parent_name = "pll1"; + table = cpg_sd01_div_table; + shift = 4; + } else if (!strcmp(name, "sd1")) { + parent_name = "pll1"; + table = cpg_sd01_div_table; + shift = 0; + } else if (!strcmp(name, "z")) { + return cpg_z_clk_register(cpg); + } else if (!strcmp(name, "rcan")) { + return cpg_rcan_clk_register(cpg, np); + } else if (!strcmp(name, "adsp")) { + return cpg_adsp_clk_register(cpg); + } else { + return ERR_PTR(-EINVAL); + } + + if (!table) + return clk_register_fixed_factor(NULL, name, parent_name, 0, + mult, div); + else + return clk_register_divider_table(NULL, name, parent_name, 0, + cpg->reg + CPG_SDCKCR, shift, + 4, 0, table, &cpg->lock); +} + +static void __init rcar_gen2_cpg_clocks_init(struct device_node *np) +{ + const struct cpg_pll_config *config; + struct rcar_gen2_cpg *cpg; + struct clk **clks; + unsigned int i; + int num_clks; + + num_clks = of_property_count_strings(np, "clock-output-names"); + if (num_clks < 0) { + pr_err("%s: failed to count clocks\n", __func__); + return; + } + + cpg = kzalloc(sizeof(*cpg), GFP_KERNEL); + clks = kzalloc(num_clks * sizeof(*clks), GFP_KERNEL); + if (cpg == NULL || clks == NULL) { + /* We're leaking memory on purpose, there's no point in cleaning + * up as the system won't boot anyway. + */ + pr_err("%s: failed to allocate cpg\n", __func__); + return; + } + + spin_lock_init(&cpg->lock); + + cpg->data.clks = clks; + cpg->data.clk_num = num_clks; + + cpg->reg = of_iomap(np, 0); + if (WARN_ON(cpg->reg == NULL)) + return; + + config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)]; + + for (i = 0; i < num_clks; ++i) { + const char *name; + struct clk *clk; + + of_property_read_string_index(np, "clock-output-names", i, + &name); + + clk = rcar_gen2_cpg_register_clock(np, cpg, config, name); + if (IS_ERR(clk)) + pr_err("%s: failed to register %s %s clock (%ld)\n", + __func__, np->name, name, PTR_ERR(clk)); + else + cpg->data.clks[i] = clk; + } + + of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data); + + cpg_mstp_add_clk_domain(np); +} +CLK_OF_DECLARE(rcar_gen2_cpg_clks, "renesas,rcar-gen2-cpg-clocks", + rcar_gen2_cpg_clocks_init); + +void __init rcar_gen2_clocks_init(u32 mode) +{ + cpg_mode = mode; + + of_clk_init(NULL); +} diff --git a/drivers/clk/renesas/clk-rz.c b/drivers/clk/renesas/clk-rz.c new file mode 100644 index 0000000..9766e3c --- /dev/null +++ b/drivers/clk/renesas/clk-rz.c @@ -0,0 +1,106 @@ +/* + * rz Core CPG Clocks + * + * Copyright (C) 2013 Ideas On Board SPRL + * Copyright (C) 2014 Wolfram Sang, Sang Engineering + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +struct rz_cpg { + struct clk_onecell_data data; + void __iomem *reg; +}; + +#define CPG_FRQCR 0x10 +#define CPG_FRQCR2 0x14 + +/* ----------------------------------------------------------------------------- + * Initialization + */ + +static struct clk * __init +rz_cpg_register_clock(struct device_node *np, struct rz_cpg *cpg, const char *name) +{ + u32 val; + unsigned mult; + static const unsigned frqcr_tab[4] = { 3, 2, 0, 1 }; + + if (strcmp(name, "pll") == 0) { + /* FIXME: cpg_mode should be read from GPIO. But no GPIO support yet */ + unsigned cpg_mode = 0; /* hardcoded to EXTAL for now */ + const char *parent_name = of_clk_get_parent_name(np, cpg_mode); + + mult = cpg_mode ? (32 / 4) : 30; + + return clk_register_fixed_factor(NULL, name, parent_name, 0, mult, 1); + } + + /* If mapping regs failed, skip non-pll clocks. System will boot anyhow */ + if (!cpg->reg) + return ERR_PTR(-ENXIO); + + /* FIXME:"i" and "g" are variable clocks with non-integer dividers (e.g. 2/3) + * and the constraint that always g <= i. To get the rz platform started, + * let them run at fixed current speed and implement the details later. + */ + if (strcmp(name, "i") == 0) + val = (clk_readl(cpg->reg + CPG_FRQCR) >> 8) & 3; + else if (strcmp(name, "g") == 0) + val = clk_readl(cpg->reg + CPG_FRQCR2) & 3; + else + return ERR_PTR(-EINVAL); + + mult = frqcr_tab[val]; + return clk_register_fixed_factor(NULL, name, "pll", 0, mult, 3); +} + +static void __init rz_cpg_clocks_init(struct device_node *np) +{ + struct rz_cpg *cpg; + struct clk **clks; + unsigned i; + int num_clks; + + num_clks = of_property_count_strings(np, "clock-output-names"); + if (WARN(num_clks <= 0, "can't count CPG clocks\n")) + return; + + cpg = kzalloc(sizeof(*cpg), GFP_KERNEL); + clks = kzalloc(num_clks * sizeof(*clks), GFP_KERNEL); + BUG_ON(!cpg || !clks); + + cpg->data.clks = clks; + cpg->data.clk_num = num_clks; + + cpg->reg = of_iomap(np, 0); + + for (i = 0; i < num_clks; ++i) { + const char *name; + struct clk *clk; + + of_property_read_string_index(np, "clock-output-names", i, &name); + + clk = rz_cpg_register_clock(np, cpg, name); + if (IS_ERR(clk)) + pr_err("%s: failed to register %s %s clock (%ld)\n", + __func__, np->name, name, PTR_ERR(clk)); + else + cpg->data.clks[i] = clk; + } + + of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data); + + cpg_mstp_add_clk_domain(np); +} +CLK_OF_DECLARE(rz_cpg_clks, "renesas,rz-cpg-clocks", rz_cpg_clocks_init); diff --git a/drivers/clk/renesas/clk-sh73a0.c b/drivers/clk/renesas/clk-sh73a0.c new file mode 100644 index 0000000..8966f8b --- /dev/null +++ b/drivers/clk/renesas/clk-sh73a0.c @@ -0,0 +1,218 @@ +/* + * sh73a0 Core CPG Clocks + * + * Copyright (C) 2014 Ulrich Hecht + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct sh73a0_cpg { + struct clk_onecell_data data; + spinlock_t lock; + void __iomem *reg; +}; + +#define CPG_FRQCRA 0x00 +#define CPG_FRQCRB 0x04 +#define CPG_SD0CKCR 0x74 +#define CPG_SD1CKCR 0x78 +#define CPG_SD2CKCR 0x7c +#define CPG_PLLECR 0xd0 +#define CPG_PLL0CR 0xd8 +#define CPG_PLL1CR 0x28 +#define CPG_PLL2CR 0x2c +#define CPG_PLL3CR 0xdc +#define CPG_CKSCR 0xc0 +#define CPG_DSI0PHYCR 0x6c +#define CPG_DSI1PHYCR 0x70 + +#define CLK_ENABLE_ON_INIT BIT(0) + +struct div4_clk { + const char *name; + const char *parent; + unsigned int reg; + unsigned int shift; +}; + +static struct div4_clk div4_clks[] = { + { "zg", "pll0", CPG_FRQCRA, 16 }, + { "m3", "pll1", CPG_FRQCRA, 12 }, + { "b", "pll1", CPG_FRQCRA, 8 }, + { "m1", "pll1", CPG_FRQCRA, 4 }, + { "m2", "pll1", CPG_FRQCRA, 0 }, + { "zx", "pll1", CPG_FRQCRB, 12 }, + { "hp", "pll1", CPG_FRQCRB, 4 }, + { NULL, NULL, 0, 0 }, +}; + +static const struct clk_div_table div4_div_table[] = { + { 0, 2 }, { 1, 3 }, { 2, 4 }, { 3, 6 }, { 4, 8 }, { 5, 12 }, + { 6, 16 }, { 7, 18 }, { 8, 24 }, { 10, 36 }, { 11, 48 }, + { 12, 7 }, { 0, 0 } +}; + +static const struct clk_div_table z_div_table[] = { + /* ZSEL == 0 */ + { 0, 1 }, { 1, 1 }, { 2, 1 }, { 3, 1 }, { 4, 1 }, { 5, 1 }, + { 6, 1 }, { 7, 1 }, { 8, 1 }, { 9, 1 }, { 10, 1 }, { 11, 1 }, + { 12, 1 }, { 13, 1 }, { 14, 1 }, { 15, 1 }, + /* ZSEL == 1 */ + { 16, 2 }, { 17, 3 }, { 18, 4 }, { 19, 6 }, { 20, 8 }, { 21, 12 }, + { 22, 16 }, { 24, 24 }, { 27, 48 }, { 0, 0 } +}; + +static struct clk * __init +sh73a0_cpg_register_clock(struct device_node *np, struct sh73a0_cpg *cpg, + const char *name) +{ + const struct clk_div_table *table = NULL; + unsigned int shift, reg, width; + const char *parent_name; + unsigned int mult = 1; + unsigned int div = 1; + + if (!strcmp(name, "main")) { + /* extal1, extal1_div2, extal2, extal2_div2 */ + u32 parent_idx = (clk_readl(cpg->reg + CPG_CKSCR) >> 28) & 3; + + parent_name = of_clk_get_parent_name(np, parent_idx >> 1); + div = (parent_idx & 1) + 1; + } else if (!strncmp(name, "pll", 3)) { + void __iomem *enable_reg = cpg->reg; + u32 enable_bit = name[3] - '0'; + + parent_name = "main"; + switch (enable_bit) { + case 0: + enable_reg += CPG_PLL0CR; + break; + case 1: + enable_reg += CPG_PLL1CR; + break; + case 2: + enable_reg += CPG_PLL2CR; + break; + case 3: + enable_reg += CPG_PLL3CR; + break; + default: + return ERR_PTR(-EINVAL); + } + if (clk_readl(cpg->reg + CPG_PLLECR) & BIT(enable_bit)) { + mult = ((clk_readl(enable_reg) >> 24) & 0x3f) + 1; + /* handle CFG bit for PLL1 and PLL2 */ + if (enable_bit == 1 || enable_bit == 2) + if (clk_readl(enable_reg) & BIT(20)) + mult *= 2; + } + } else if (!strcmp(name, "dsi0phy") || !strcmp(name, "dsi1phy")) { + u32 phy_no = name[3] - '0'; + void __iomem *dsi_reg = cpg->reg + + (phy_no ? CPG_DSI1PHYCR : CPG_DSI0PHYCR); + + parent_name = phy_no ? "dsi1pck" : "dsi0pck"; + mult = __raw_readl(dsi_reg); + if (!(mult & 0x8000)) + mult = 1; + else + mult = (mult & 0x3f) + 1; + } else if (!strcmp(name, "z")) { + parent_name = "pll0"; + table = z_div_table; + reg = CPG_FRQCRB; + shift = 24; + width = 5; + } else { + struct div4_clk *c; + + for (c = div4_clks; c->name; c++) { + if (!strcmp(name, c->name)) { + parent_name = c->parent; + table = div4_div_table; + reg = c->reg; + shift = c->shift; + width = 4; + break; + } + } + if (!c->name) + return ERR_PTR(-EINVAL); + } + + if (!table) { + return clk_register_fixed_factor(NULL, name, parent_name, 0, + mult, div); + } else { + return clk_register_divider_table(NULL, name, parent_name, 0, + cpg->reg + reg, shift, width, 0, + table, &cpg->lock); + } +} + +static void __init sh73a0_cpg_clocks_init(struct device_node *np) +{ + struct sh73a0_cpg *cpg; + struct clk **clks; + unsigned int i; + int num_clks; + + num_clks = of_property_count_strings(np, "clock-output-names"); + if (num_clks < 0) { + pr_err("%s: failed to count clocks\n", __func__); + return; + } + + cpg = kzalloc(sizeof(*cpg), GFP_KERNEL); + clks = kcalloc(num_clks, sizeof(*clks), GFP_KERNEL); + if (cpg == NULL || clks == NULL) { + /* We're leaking memory on purpose, there's no point in cleaning + * up as the system won't boot anyway. + */ + return; + } + + spin_lock_init(&cpg->lock); + + cpg->data.clks = clks; + cpg->data.clk_num = num_clks; + + cpg->reg = of_iomap(np, 0); + if (WARN_ON(cpg->reg == NULL)) + return; + + /* Set SDHI clocks to a known state */ + clk_writel(0x108, cpg->reg + CPG_SD0CKCR); + clk_writel(0x108, cpg->reg + CPG_SD1CKCR); + clk_writel(0x108, cpg->reg + CPG_SD2CKCR); + + for (i = 0; i < num_clks; ++i) { + const char *name; + struct clk *clk; + + of_property_read_string_index(np, "clock-output-names", i, + &name); + + clk = sh73a0_cpg_register_clock(np, cpg, name); + if (IS_ERR(clk)) + pr_err("%s: failed to register %s %s clock (%ld)\n", + __func__, np->name, name, PTR_ERR(clk)); + else + cpg->data.clks[i] = clk; + } + + of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data); +} +CLK_OF_DECLARE(sh73a0_cpg_clks, "renesas,sh73a0-cpg-clocks", + sh73a0_cpg_clocks_init); diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c new file mode 100644 index 0000000..b2198aef --- /dev/null +++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c @@ -0,0 +1,638 @@ +/* + * r8a7795 Clock Pulse Generator / Module Standby and Software Reset + * + * Copyright (C) 2015 Glider bvba + * + * Based on clk-rcar-gen3.c + * + * Copyright (C) 2015 Renesas Electronics Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "renesas-cpg-mssr.h" + + +enum clk_ids { + /* Core Clock Outputs exported to DT */ + LAST_DT_CORE_CLK = R8A7795_CLK_OSC, + + /* External Input Clocks */ + CLK_EXTAL, + CLK_EXTALR, + + /* Internal Core Clocks */ + CLK_MAIN, + CLK_PLL0, + CLK_PLL1, + CLK_PLL2, + CLK_PLL3, + CLK_PLL4, + CLK_PLL1_DIV2, + CLK_PLL1_DIV4, + CLK_S0, + CLK_S1, + CLK_S2, + CLK_S3, + CLK_SDSRC, + CLK_SSPSRC, + + /* Module Clocks */ + MOD_CLK_BASE +}; + +enum r8a7795_clk_types { + CLK_TYPE_GEN3_MAIN = CLK_TYPE_CUSTOM, + CLK_TYPE_GEN3_PLL0, + CLK_TYPE_GEN3_PLL1, + CLK_TYPE_GEN3_PLL2, + CLK_TYPE_GEN3_PLL3, + CLK_TYPE_GEN3_PLL4, + CLK_TYPE_GEN3_SD, +}; + +static const struct cpg_core_clk r8a7795_core_clks[] __initconst = { + /* External Clock Inputs */ + DEF_INPUT("extal", CLK_EXTAL), + DEF_INPUT("extalr", CLK_EXTALR), + + /* Internal Core Clocks */ + DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN3_MAIN, CLK_EXTAL), + DEF_BASE(".pll0", CLK_PLL0, CLK_TYPE_GEN3_PLL0, CLK_MAIN), + DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN3_PLL1, CLK_MAIN), + DEF_BASE(".pll2", CLK_PLL2, CLK_TYPE_GEN3_PLL2, CLK_MAIN), + DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN3_PLL3, CLK_MAIN), + DEF_BASE(".pll4", CLK_PLL4, CLK_TYPE_GEN3_PLL4, CLK_MAIN), + + DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1), + DEF_FIXED(".pll1_div4", CLK_PLL1_DIV4, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED(".s0", CLK_S0, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED(".s1", CLK_S1, CLK_PLL1_DIV2, 3, 1), + DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1), + DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1), + + /* Core Clock Outputs */ + DEF_FIXED("ztr", R8A7795_CLK_ZTR, CLK_PLL1_DIV2, 6, 1), + DEF_FIXED("ztrd2", R8A7795_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1), + DEF_FIXED("zt", R8A7795_CLK_ZT, CLK_PLL1_DIV2, 4, 1), + DEF_FIXED("zx", R8A7795_CLK_ZX, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED("s0d1", R8A7795_CLK_S0D1, CLK_S0, 1, 1), + DEF_FIXED("s0d4", R8A7795_CLK_S0D4, CLK_S0, 4, 1), + DEF_FIXED("s1d1", R8A7795_CLK_S1D1, CLK_S1, 1, 1), + DEF_FIXED("s1d2", R8A7795_CLK_S1D2, CLK_S1, 2, 1), + DEF_FIXED("s1d4", R8A7795_CLK_S1D4, CLK_S1, 4, 1), + DEF_FIXED("s2d1", R8A7795_CLK_S2D1, CLK_S2, 1, 1), + DEF_FIXED("s2d2", R8A7795_CLK_S2D2, CLK_S2, 2, 1), + DEF_FIXED("s2d4", R8A7795_CLK_S2D4, CLK_S2, 4, 1), + DEF_FIXED("s3d1", R8A7795_CLK_S3D1, CLK_S3, 1, 1), + DEF_FIXED("s3d2", R8A7795_CLK_S3D2, CLK_S3, 2, 1), + DEF_FIXED("s3d4", R8A7795_CLK_S3D4, CLK_S3, 4, 1), + + DEF_SD("sd0", R8A7795_CLK_SD0, CLK_PLL1_DIV2, 0x0074), + DEF_SD("sd1", R8A7795_CLK_SD1, CLK_PLL1_DIV2, 0x0078), + DEF_SD("sd2", R8A7795_CLK_SD2, CLK_PLL1_DIV2, 0x0268), + DEF_SD("sd3", R8A7795_CLK_SD3, CLK_PLL1_DIV2, 0x026c), + + DEF_FIXED("cl", R8A7795_CLK_CL, CLK_PLL1_DIV2, 48, 1), + DEF_FIXED("cp", R8A7795_CLK_CP, CLK_EXTAL, 2, 1), + + DEF_DIV6P1("mso", R8A7795_CLK_MSO, CLK_PLL1_DIV4, 0x014), + DEF_DIV6P1("hdmi", R8A7795_CLK_HDMI, CLK_PLL1_DIV2, 0x250), + DEF_DIV6P1("canfd", R8A7795_CLK_CANFD, CLK_PLL1_DIV4, 0x244), +}; + +static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = { + DEF_MOD("scif5", 202, R8A7795_CLK_S3D4), + DEF_MOD("scif4", 203, R8A7795_CLK_S3D4), + DEF_MOD("scif3", 204, R8A7795_CLK_S3D4), + DEF_MOD("scif1", 206, R8A7795_CLK_S3D4), + DEF_MOD("scif0", 207, R8A7795_CLK_S3D4), + DEF_MOD("msiof3", 208, R8A7795_CLK_MSO), + DEF_MOD("msiof2", 209, R8A7795_CLK_MSO), + DEF_MOD("msiof1", 210, R8A7795_CLK_MSO), + DEF_MOD("msiof0", 211, R8A7795_CLK_MSO), + DEF_MOD("sys-dmac2", 217, R8A7795_CLK_S3D1), + DEF_MOD("sys-dmac1", 218, R8A7795_CLK_S3D1), + DEF_MOD("sys-dmac0", 219, R8A7795_CLK_S3D1), + DEF_MOD("scif2", 310, R8A7795_CLK_S3D4), + DEF_MOD("sdif3", 311, R8A7795_CLK_SD3), + DEF_MOD("sdif2", 312, R8A7795_CLK_SD2), + DEF_MOD("sdif1", 313, R8A7795_CLK_SD1), + DEF_MOD("sdif0", 314, R8A7795_CLK_SD0), + DEF_MOD("pcie1", 318, R8A7795_CLK_S3D1), + DEF_MOD("pcie0", 319, R8A7795_CLK_S3D1), + DEF_MOD("usb3-if1", 327, R8A7795_CLK_S3D1), + DEF_MOD("usb3-if0", 328, R8A7795_CLK_S3D1), + DEF_MOD("usb-dmac0", 330, R8A7795_CLK_S3D1), + DEF_MOD("usb-dmac1", 331, R8A7795_CLK_S3D1), + DEF_MOD("intc-ex", 407, R8A7795_CLK_CP), + DEF_MOD("intc-ap", 408, R8A7795_CLK_S3D1), + DEF_MOD("audmac0", 502, R8A7795_CLK_S3D4), + DEF_MOD("audmac1", 501, R8A7795_CLK_S3D4), + DEF_MOD("hscif4", 516, R8A7795_CLK_S3D1), + DEF_MOD("hscif3", 517, R8A7795_CLK_S3D1), + DEF_MOD("hscif2", 518, R8A7795_CLK_S3D1), + DEF_MOD("hscif1", 519, R8A7795_CLK_S3D1), + DEF_MOD("hscif0", 520, R8A7795_CLK_S3D1), + DEF_MOD("fcpvd3", 600, R8A7795_CLK_S2D1), + DEF_MOD("fcpvd2", 601, R8A7795_CLK_S2D1), + DEF_MOD("fcpvd1", 602, R8A7795_CLK_S2D1), + DEF_MOD("fcpvd0", 603, R8A7795_CLK_S2D1), + DEF_MOD("fcpvb1", 606, R8A7795_CLK_S2D1), + DEF_MOD("fcpvb0", 607, R8A7795_CLK_S2D1), + DEF_MOD("fcpvi2", 609, R8A7795_CLK_S2D1), + DEF_MOD("fcpvi1", 610, R8A7795_CLK_S2D1), + DEF_MOD("fcpvi0", 611, R8A7795_CLK_S2D1), + DEF_MOD("fcpf2", 613, R8A7795_CLK_S2D1), + DEF_MOD("fcpf1", 614, R8A7795_CLK_S2D1), + DEF_MOD("fcpf0", 615, R8A7795_CLK_S2D1), + DEF_MOD("fcpci1", 616, R8A7795_CLK_S2D1), + DEF_MOD("fcpci0", 617, R8A7795_CLK_S2D1), + DEF_MOD("fcpcs", 619, R8A7795_CLK_S2D1), + DEF_MOD("vspd3", 620, R8A7795_CLK_S2D1), + DEF_MOD("vspd2", 621, R8A7795_CLK_S2D1), + DEF_MOD("vspd1", 622, R8A7795_CLK_S2D1), + DEF_MOD("vspd0", 623, R8A7795_CLK_S2D1), + DEF_MOD("vspbc", 624, R8A7795_CLK_S2D1), + DEF_MOD("vspbd", 626, R8A7795_CLK_S2D1), + DEF_MOD("vspi2", 629, R8A7795_CLK_S2D1), + DEF_MOD("vspi1", 630, R8A7795_CLK_S2D1), + DEF_MOD("vspi0", 631, R8A7795_CLK_S2D1), + DEF_MOD("ehci2", 701, R8A7795_CLK_S3D4), + DEF_MOD("ehci1", 702, R8A7795_CLK_S3D4), + DEF_MOD("ehci0", 703, R8A7795_CLK_S3D4), + DEF_MOD("hsusb", 704, R8A7795_CLK_S3D4), + DEF_MOD("du3", 721, R8A7795_CLK_S2D1), + DEF_MOD("du2", 722, R8A7795_CLK_S2D1), + DEF_MOD("du1", 723, R8A7795_CLK_S2D1), + DEF_MOD("du0", 724, R8A7795_CLK_S2D1), + DEF_MOD("lvds", 727, R8A7795_CLK_S2D1), + DEF_MOD("hdmi1", 728, R8A7795_CLK_HDMI), + DEF_MOD("hdmi0", 729, R8A7795_CLK_HDMI), + DEF_MOD("etheravb", 812, R8A7795_CLK_S3D2), + DEF_MOD("sata0", 815, R8A7795_CLK_S3D2), + DEF_MOD("gpio7", 905, R8A7795_CLK_CP), + DEF_MOD("gpio6", 906, R8A7795_CLK_CP), + DEF_MOD("gpio5", 907, R8A7795_CLK_CP), + DEF_MOD("gpio4", 908, R8A7795_CLK_CP), + DEF_MOD("gpio3", 909, R8A7795_CLK_CP), + DEF_MOD("gpio2", 910, R8A7795_CLK_CP), + DEF_MOD("gpio1", 911, R8A7795_CLK_CP), + DEF_MOD("gpio0", 912, R8A7795_CLK_CP), + DEF_MOD("can-fd", 914, R8A7795_CLK_S3D2), + DEF_MOD("can-if1", 915, R8A7795_CLK_S3D4), + DEF_MOD("can-if0", 916, R8A7795_CLK_S3D4), + DEF_MOD("i2c6", 918, R8A7795_CLK_S3D2), + DEF_MOD("i2c5", 919, R8A7795_CLK_S3D2), + DEF_MOD("i2c4", 927, R8A7795_CLK_S3D2), + DEF_MOD("i2c3", 928, R8A7795_CLK_S3D2), + DEF_MOD("i2c2", 929, R8A7795_CLK_S3D2), + DEF_MOD("i2c1", 930, R8A7795_CLK_S3D2), + DEF_MOD("i2c0", 931, R8A7795_CLK_S3D2), + DEF_MOD("ssi-all", 1005, R8A7795_CLK_S3D4), + DEF_MOD("ssi9", 1006, MOD_CLK_ID(1005)), + DEF_MOD("ssi8", 1007, MOD_CLK_ID(1005)), + DEF_MOD("ssi7", 1008, MOD_CLK_ID(1005)), + DEF_MOD("ssi6", 1009, MOD_CLK_ID(1005)), + DEF_MOD("ssi5", 1010, MOD_CLK_ID(1005)), + DEF_MOD("ssi4", 1011, MOD_CLK_ID(1005)), + DEF_MOD("ssi3", 1012, MOD_CLK_ID(1005)), + DEF_MOD("ssi2", 1013, MOD_CLK_ID(1005)), + DEF_MOD("ssi1", 1014, MOD_CLK_ID(1005)), + DEF_MOD("ssi0", 1015, MOD_CLK_ID(1005)), + DEF_MOD("scu-all", 1017, R8A7795_CLK_S3D4), + DEF_MOD("scu-dvc1", 1018, MOD_CLK_ID(1017)), + DEF_MOD("scu-dvc0", 1019, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu1-mix1", 1020, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu0-mix0", 1021, MOD_CLK_ID(1017)), + DEF_MOD("scu-src9", 1022, MOD_CLK_ID(1017)), + DEF_MOD("scu-src8", 1023, MOD_CLK_ID(1017)), + DEF_MOD("scu-src7", 1024, MOD_CLK_ID(1017)), + DEF_MOD("scu-src6", 1025, MOD_CLK_ID(1017)), + DEF_MOD("scu-src5", 1026, MOD_CLK_ID(1017)), + DEF_MOD("scu-src4", 1027, MOD_CLK_ID(1017)), + DEF_MOD("scu-src3", 1028, MOD_CLK_ID(1017)), + DEF_MOD("scu-src2", 1029, MOD_CLK_ID(1017)), + DEF_MOD("scu-src1", 1030, MOD_CLK_ID(1017)), + DEF_MOD("scu-src0", 1031, MOD_CLK_ID(1017)), +}; + +static const unsigned int r8a7795_crit_mod_clks[] __initconst = { + MOD_CLK_ID(408), /* INTC-AP (GIC) */ +}; + +/* ----------------------------------------------------------------------------- + * SDn Clock + * + */ +#define CPG_SD_STP_HCK BIT(9) +#define CPG_SD_STP_CK BIT(8) + +#define CPG_SD_STP_MASK (CPG_SD_STP_HCK | CPG_SD_STP_CK) +#define CPG_SD_FC_MASK (0x7 << 2 | 0x3 << 0) + +#define CPG_SD_DIV_TABLE_DATA(stp_hck, stp_ck, sd_srcfc, sd_fc, sd_div) \ +{ \ + .val = ((stp_hck) ? CPG_SD_STP_HCK : 0) | \ + ((stp_ck) ? CPG_SD_STP_CK : 0) | \ + ((sd_srcfc) << 2) | \ + ((sd_fc) << 0), \ + .div = (sd_div), \ +} + +struct sd_div_table { + u32 val; + unsigned int div; +}; + +struct sd_clock { + struct clk_hw hw; + void __iomem *reg; + const struct sd_div_table *div_table; + unsigned int div_num; + unsigned int div_min; + unsigned int div_max; +}; + +/* SDn divider + * sd_srcfc sd_fc div + * stp_hck stp_ck (div) (div) = sd_srcfc x sd_fc + *------------------------------------------------------------------- + * 0 0 0 (1) 1 (4) 4 + * 0 0 1 (2) 1 (4) 8 + * 1 0 2 (4) 1 (4) 16 + * 1 0 3 (8) 1 (4) 32 + * 1 0 4 (16) 1 (4) 64 + * 0 0 0 (1) 0 (2) 2 + * 0 0 1 (2) 0 (2) 4 + * 1 0 2 (4) 0 (2) 8 + * 1 0 3 (8) 0 (2) 16 + * 1 0 4 (16) 0 (2) 32 + */ +static const struct sd_div_table cpg_sd_div_table[] = { +/* CPG_SD_DIV_TABLE_DATA(stp_hck, stp_ck, sd_srcfc, sd_fc, sd_div) */ + CPG_SD_DIV_TABLE_DATA(0, 0, 0, 1, 4), + CPG_SD_DIV_TABLE_DATA(0, 0, 1, 1, 8), + CPG_SD_DIV_TABLE_DATA(1, 0, 2, 1, 16), + CPG_SD_DIV_TABLE_DATA(1, 0, 3, 1, 32), + CPG_SD_DIV_TABLE_DATA(1, 0, 4, 1, 64), + CPG_SD_DIV_TABLE_DATA(0, 0, 0, 0, 2), + CPG_SD_DIV_TABLE_DATA(0, 0, 1, 0, 4), + CPG_SD_DIV_TABLE_DATA(1, 0, 2, 0, 8), + CPG_SD_DIV_TABLE_DATA(1, 0, 3, 0, 16), + CPG_SD_DIV_TABLE_DATA(1, 0, 4, 0, 32), +}; + +#define to_sd_clock(_hw) container_of(_hw, struct sd_clock, hw) + +static int cpg_sd_clock_enable(struct clk_hw *hw) +{ + struct sd_clock *clock = to_sd_clock(hw); + u32 val, sd_fc; + unsigned int i; + + val = clk_readl(clock->reg); + + sd_fc = val & CPG_SD_FC_MASK; + for (i = 0; i < clock->div_num; i++) + if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK)) + break; + + if (i >= clock->div_num) + return -EINVAL; + + val &= ~(CPG_SD_STP_MASK); + val |= clock->div_table[i].val & CPG_SD_STP_MASK; + + clk_writel(val, clock->reg); + + return 0; +} + +static void cpg_sd_clock_disable(struct clk_hw *hw) +{ + struct sd_clock *clock = to_sd_clock(hw); + + clk_writel(clk_readl(clock->reg) | CPG_SD_STP_MASK, clock->reg); +} + +static int cpg_sd_clock_is_enabled(struct clk_hw *hw) +{ + struct sd_clock *clock = to_sd_clock(hw); + + return !(clk_readl(clock->reg) & CPG_SD_STP_MASK); +} + +static unsigned long cpg_sd_clock_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct sd_clock *clock = to_sd_clock(hw); + unsigned long rate = parent_rate; + u32 val, sd_fc; + unsigned int i; + + val = clk_readl(clock->reg); + + sd_fc = val & CPG_SD_FC_MASK; + for (i = 0; i < clock->div_num; i++) + if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK)) + break; + + if (i >= clock->div_num) + return -EINVAL; + + return DIV_ROUND_CLOSEST(rate, clock->div_table[i].div); +} + +static unsigned int cpg_sd_clock_calc_div(struct sd_clock *clock, + unsigned long rate, + unsigned long parent_rate) +{ + unsigned int div; + + if (!rate) + rate = 1; + + div = DIV_ROUND_CLOSEST(parent_rate, rate); + + return clamp_t(unsigned int, div, clock->div_min, clock->div_max); +} + +static long cpg_sd_clock_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + struct sd_clock *clock = to_sd_clock(hw); + unsigned int div = cpg_sd_clock_calc_div(clock, rate, *parent_rate); + + return DIV_ROUND_CLOSEST(*parent_rate, div); +} + +static int cpg_sd_clock_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct sd_clock *clock = to_sd_clock(hw); + unsigned int div = cpg_sd_clock_calc_div(clock, rate, parent_rate); + u32 val; + unsigned int i; + + for (i = 0; i < clock->div_num; i++) + if (div == clock->div_table[i].div) + break; + + if (i >= clock->div_num) + return -EINVAL; + + val = clk_readl(clock->reg); + val &= ~(CPG_SD_STP_MASK | CPG_SD_FC_MASK); + val |= clock->div_table[i].val & (CPG_SD_STP_MASK | CPG_SD_FC_MASK); + clk_writel(val, clock->reg); + + return 0; +} + +static const struct clk_ops cpg_sd_clock_ops = { + .enable = cpg_sd_clock_enable, + .disable = cpg_sd_clock_disable, + .is_enabled = cpg_sd_clock_is_enabled, + .recalc_rate = cpg_sd_clock_recalc_rate, + .round_rate = cpg_sd_clock_round_rate, + .set_rate = cpg_sd_clock_set_rate, +}; + +static struct clk * __init cpg_sd_clk_register(const struct cpg_core_clk *core, + void __iomem *base, + const char *parent_name) +{ + struct clk_init_data init; + struct sd_clock *clock; + struct clk *clk; + unsigned int i; + + clock = kzalloc(sizeof(*clock), GFP_KERNEL); + if (!clock) + return ERR_PTR(-ENOMEM); + + init.name = core->name; + init.ops = &cpg_sd_clock_ops; + init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; + init.parent_names = &parent_name; + init.num_parents = 1; + + clock->reg = base + core->offset; + clock->hw.init = &init; + clock->div_table = cpg_sd_div_table; + clock->div_num = ARRAY_SIZE(cpg_sd_div_table); + + clock->div_max = clock->div_table[0].div; + clock->div_min = clock->div_max; + for (i = 1; i < clock->div_num; i++) { + clock->div_max = max(clock->div_max, clock->div_table[i].div); + clock->div_min = min(clock->div_min, clock->div_table[i].div); + } + + clk = clk_register(NULL, &clock->hw); + if (IS_ERR(clk)) + kfree(clock); + + return clk; +} + +#define CPG_PLL0CR 0x00d8 +#define CPG_PLL2CR 0x002c +#define CPG_PLL4CR 0x01f4 + +/* + * CPG Clock Data + */ + +/* + * MD EXTAL PLL0 PLL1 PLL2 PLL3 PLL4 + * 14 13 19 17 (MHz) + *------------------------------------------------------------------- + * 0 0 0 0 16.66 x 1 x180 x192 x144 x192 x144 + * 0 0 0 1 16.66 x 1 x180 x192 x144 x128 x144 + * 0 0 1 0 Prohibited setting + * 0 0 1 1 16.66 x 1 x180 x192 x144 x192 x144 + * 0 1 0 0 20 x 1 x150 x160 x120 x160 x120 + * 0 1 0 1 20 x 1 x150 x160 x120 x106 x120 + * 0 1 1 0 Prohibited setting + * 0 1 1 1 20 x 1 x150 x160 x120 x160 x120 + * 1 0 0 0 25 x 1 x120 x128 x96 x128 x96 + * 1 0 0 1 25 x 1 x120 x128 x96 x84 x96 + * 1 0 1 0 Prohibited setting + * 1 0 1 1 25 x 1 x120 x128 x96 x128 x96 + * 1 1 0 0 33.33 / 2 x180 x192 x144 x192 x144 + * 1 1 0 1 33.33 / 2 x180 x192 x144 x128 x144 + * 1 1 1 0 Prohibited setting + * 1 1 1 1 33.33 / 2 x180 x192 x144 x192 x144 + */ +#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 11) | \ + (((md) & BIT(13)) >> 11) | \ + (((md) & BIT(19)) >> 18) | \ + (((md) & BIT(17)) >> 17)) + +struct cpg_pll_config { + unsigned int extal_div; + unsigned int pll1_mult; + unsigned int pll3_mult; +}; + +static const struct cpg_pll_config cpg_pll_configs[16] __initconst = { + /* EXTAL div PLL1 mult PLL3 mult */ + { 1, 192, 192, }, + { 1, 192, 128, }, + { 0, /* Prohibited setting */ }, + { 1, 192, 192, }, + { 1, 160, 160, }, + { 1, 160, 106, }, + { 0, /* Prohibited setting */ }, + { 1, 160, 160, }, + { 1, 128, 128, }, + { 1, 128, 84, }, + { 0, /* Prohibited setting */ }, + { 1, 128, 128, }, + { 2, 192, 192, }, + { 2, 192, 128, }, + { 0, /* Prohibited setting */ }, + { 2, 192, 192, }, +}; + +static const struct cpg_pll_config *cpg_pll_config __initdata; + +static +struct clk * __init r8a7795_cpg_clk_register(struct device *dev, + const struct cpg_core_clk *core, + const struct cpg_mssr_info *info, + struct clk **clks, + void __iomem *base) +{ + const struct clk *parent; + unsigned int mult = 1; + unsigned int div = 1; + u32 value; + + parent = clks[core->parent]; + if (IS_ERR(parent)) + return ERR_CAST(parent); + + switch (core->type) { + case CLK_TYPE_GEN3_MAIN: + div = cpg_pll_config->extal_div; + break; + + case CLK_TYPE_GEN3_PLL0: + /* + * PLL0 is a configurable multiplier clock. Register it as a + * fixed factor clock for now as there's no generic multiplier + * clock implementation and we currently have no need to change + * the multiplier value. + */ + value = readl(base + CPG_PLL0CR); + mult = (((value >> 24) & 0x7f) + 1) * 2; + break; + + case CLK_TYPE_GEN3_PLL1: + mult = cpg_pll_config->pll1_mult; + break; + + case CLK_TYPE_GEN3_PLL2: + /* + * PLL2 is a configurable multiplier clock. Register it as a + * fixed factor clock for now as there's no generic multiplier + * clock implementation and we currently have no need to change + * the multiplier value. + */ + value = readl(base + CPG_PLL2CR); + mult = (((value >> 24) & 0x7f) + 1) * 2; + break; + + case CLK_TYPE_GEN3_PLL3: + mult = cpg_pll_config->pll3_mult; + break; + + case CLK_TYPE_GEN3_PLL4: + /* + * PLL4 is a configurable multiplier clock. Register it as a + * fixed factor clock for now as there's no generic multiplier + * clock implementation and we currently have no need to change + * the multiplier value. + */ + value = readl(base + CPG_PLL4CR); + mult = (((value >> 24) & 0x7f) + 1) * 2; + break; + + case CLK_TYPE_GEN3_SD: + return cpg_sd_clk_register(core, base, __clk_get_name(parent)); + + default: + return ERR_PTR(-EINVAL); + } + + return clk_register_fixed_factor(NULL, core->name, + __clk_get_name(parent), 0, mult, div); +} + +/* + * Reset register definitions. + */ +#define MODEMR 0xe6160060 + +static u32 rcar_gen3_read_mode_pins(void) +{ + void __iomem *modemr = ioremap_nocache(MODEMR, 4); + u32 mode; + + BUG_ON(!modemr); + mode = ioread32(modemr); + iounmap(modemr); + + return mode; +} + +static int __init r8a7795_cpg_mssr_init(struct device *dev) +{ + u32 cpg_mode = rcar_gen3_read_mode_pins(); + + cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)]; + if (!cpg_pll_config->extal_div) { + dev_err(dev, "Prohibited setting (cpg_mode=0x%x)\n", cpg_mode); + return -EINVAL; + } + + return 0; +} + +const struct cpg_mssr_info r8a7795_cpg_mssr_info __initconst = { + /* Core Clocks */ + .core_clks = r8a7795_core_clks, + .num_core_clks = ARRAY_SIZE(r8a7795_core_clks), + .last_dt_core_clk = LAST_DT_CORE_CLK, + .num_total_core_clks = MOD_CLK_BASE, + + /* Module Clocks */ + .mod_clks = r8a7795_mod_clks, + .num_mod_clks = ARRAY_SIZE(r8a7795_mod_clks), + .num_hw_mod_clks = 12 * 32, + + /* Critical Module Clocks */ + .crit_mod_clks = r8a7795_crit_mod_clks, + .num_crit_mod_clks = ARRAY_SIZE(r8a7795_crit_mod_clks), + + /* Callbacks */ + .init = r8a7795_cpg_mssr_init, + .cpg_clk_register = r8a7795_cpg_clk_register, +}; diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c new file mode 100644 index 0000000..58e24b3 --- /dev/null +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -0,0 +1,601 @@ +/* + * Renesas Clock Pulse Generator / Module Standby and Software Reset + * + * Copyright (C) 2015 Glider bvba + * + * Based on clk-mstp.c, clk-rcar-gen2.c, and clk-rcar-gen3.c + * + * Copyright (C) 2013 Ideas On Board SPRL + * Copyright (C) 2015 Renesas Electronics Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "renesas-cpg-mssr.h" +#include "clk-div6.h" + +#ifdef DEBUG +#define WARN_DEBUG(x) do { } while (0) +#else +#define WARN_DEBUG(x) WARN_ON(x) +#endif + + +/* + * Module Standby and Software Reset register offets. + * + * If the registers exist, these are valid for SH-Mobile, R-Mobile, + * R-Car Gen 2, and R-Car Gen 3. + * These are NOT valid for R-Car Gen1 and RZ/A1! + */ + +/* + * Module Stop Status Register offsets + */ + +static const u16 mstpsr[] = { + 0x030, 0x038, 0x040, 0x048, 0x04C, 0x03C, 0x1C0, 0x1C4, + 0x9A0, 0x9A4, 0x9A8, 0x9AC, +}; + +#define MSTPSR(i) mstpsr[i] + + +/* + * System Module Stop Control Register offsets + */ + +static const u16 smstpcr[] = { + 0x130, 0x134, 0x138, 0x13C, 0x140, 0x144, 0x148, 0x14C, + 0x990, 0x994, 0x998, 0x99C, +}; + +#define SMSTPCR(i) smstpcr[i] + + +/* + * Software Reset Register offsets + */ + +static const u16 srcr[] = { + 0x0A0, 0x0A8, 0x0B0, 0x0B8, 0x0BC, 0x0C4, 0x1C8, 0x1CC, + 0x920, 0x924, 0x928, 0x92C, +}; + +#define SRCR(i) srcr[i] + + +/* Realtime Module Stop Control Register offsets */ +#define RMSTPCR(i) (smstpcr[i] - 0x20) + +/* Modem Module Stop Control Register offsets (r8a73a4) */ +#define MMSTPCR(i) (smstpcr[i] + 0x20) + +/* Software Reset Clearing Register offsets */ +#define SRSTCLR(i) (0x940 + (i) * 4) + + +/** + * Clock Pulse Generator / Module Standby and Software Reset Private Data + * + * @dev: CPG/MSSR device + * @base: CPG/MSSR register block base address + * @mstp_lock: protects writes to SMSTPCR + * @clks: Array containing all Core and Module Clocks + * @num_core_clks: Number of Core Clocks in clks[] + * @num_mod_clks: Number of Module Clocks in clks[] + * @last_dt_core_clk: ID of the last Core Clock exported to DT + */ +struct cpg_mssr_priv { + struct device *dev; + void __iomem *base; + spinlock_t mstp_lock; + + struct clk **clks; + unsigned int num_core_clks; + unsigned int num_mod_clks; + unsigned int last_dt_core_clk; +}; + + +/** + * struct mstp_clock - MSTP gating clock + * @hw: handle between common and hardware-specific interfaces + * @index: MSTP clock number + * @priv: CPG/MSSR private data + */ +struct mstp_clock { + struct clk_hw hw; + u32 index; + struct cpg_mssr_priv *priv; +}; + +#define to_mstp_clock(_hw) container_of(_hw, struct mstp_clock, hw) + +static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable) +{ + struct mstp_clock *clock = to_mstp_clock(hw); + struct cpg_mssr_priv *priv = clock->priv; + unsigned int reg = clock->index / 32; + unsigned int bit = clock->index % 32; + struct device *dev = priv->dev; + u32 bitmask = BIT(bit); + unsigned long flags; + unsigned int i; + u32 value; + + dev_dbg(dev, "MSTP %u%02u/%pC %s\n", reg, bit, hw->clk, + enable ? "ON" : "OFF"); + spin_lock_irqsave(&priv->mstp_lock, flags); + + value = clk_readl(priv->base + SMSTPCR(reg)); + if (enable) + value &= ~bitmask; + else + value |= bitmask; + clk_writel(value, priv->base + SMSTPCR(reg)); + + spin_unlock_irqrestore(&priv->mstp_lock, flags); + + if (!enable) + return 0; + + for (i = 1000; i > 0; --i) { + if (!(clk_readl(priv->base + MSTPSR(reg)) & + bitmask)) + break; + cpu_relax(); + } + + if (!i) { + dev_err(dev, "Failed to enable SMSTP %p[%d]\n", + priv->base + SMSTPCR(reg), bit); + return -ETIMEDOUT; + } + + return 0; +} + +static int cpg_mstp_clock_enable(struct clk_hw *hw) +{ + return cpg_mstp_clock_endisable(hw, true); +} + +static void cpg_mstp_clock_disable(struct clk_hw *hw) +{ + cpg_mstp_clock_endisable(hw, false); +} + +static int cpg_mstp_clock_is_enabled(struct clk_hw *hw) +{ + struct mstp_clock *clock = to_mstp_clock(hw); + struct cpg_mssr_priv *priv = clock->priv; + u32 value; + + value = clk_readl(priv->base + MSTPSR(clock->index / 32)); + + return !(value & BIT(clock->index % 32)); +} + +static const struct clk_ops cpg_mstp_clock_ops = { + .enable = cpg_mstp_clock_enable, + .disable = cpg_mstp_clock_disable, + .is_enabled = cpg_mstp_clock_is_enabled, +}; + +static +struct clk *cpg_mssr_clk_src_twocell_get(struct of_phandle_args *clkspec, + void *data) +{ + unsigned int clkidx = clkspec->args[1]; + struct cpg_mssr_priv *priv = data; + struct device *dev = priv->dev; + unsigned int idx; + const char *type; + struct clk *clk; + + switch (clkspec->args[0]) { + case CPG_CORE: + type = "core"; + if (clkidx > priv->last_dt_core_clk) { + dev_err(dev, "Invalid %s clock index %u\n", type, + clkidx); + return ERR_PTR(-EINVAL); + } + clk = priv->clks[clkidx]; + break; + + case CPG_MOD: + type = "module"; + idx = MOD_CLK_PACK(clkidx); + if (clkidx % 100 > 31 || idx >= priv->num_mod_clks) { + dev_err(dev, "Invalid %s clock index %u\n", type, + clkidx); + return ERR_PTR(-EINVAL); + } + clk = priv->clks[priv->num_core_clks + idx]; + break; + + default: + dev_err(dev, "Invalid CPG clock type %u\n", clkspec->args[0]); + return ERR_PTR(-EINVAL); + } + + if (IS_ERR(clk)) + dev_err(dev, "Cannot get %s clock %u: %ld", type, clkidx, + PTR_ERR(clk)); + else + dev_dbg(dev, "clock (%u, %u) is %pC at %pCr Hz\n", + clkspec->args[0], clkspec->args[1], clk, clk); + return clk; +} + +static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core, + const struct cpg_mssr_info *info, + struct cpg_mssr_priv *priv) +{ + struct clk *clk = NULL, *parent; + struct device *dev = priv->dev; + unsigned int id = core->id; + const char *parent_name; + + WARN_DEBUG(id >= priv->num_core_clks); + WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT); + + switch (core->type) { + case CLK_TYPE_IN: + clk = of_clk_get_by_name(priv->dev->of_node, core->name); + break; + + case CLK_TYPE_FF: + case CLK_TYPE_DIV6P1: + WARN_DEBUG(core->parent >= priv->num_core_clks); + parent = priv->clks[core->parent]; + if (IS_ERR(parent)) { + clk = parent; + goto fail; + } + + parent_name = __clk_get_name(parent); + if (core->type == CLK_TYPE_FF) { + clk = clk_register_fixed_factor(NULL, core->name, + parent_name, 0, + core->mult, core->div); + } else { + clk = cpg_div6_register(core->name, 1, &parent_name, + priv->base + core->offset); + } + break; + + default: + if (info->cpg_clk_register) + clk = info->cpg_clk_register(dev, core, info, + priv->clks, priv->base); + else + dev_err(dev, "%s has unsupported core clock type %u\n", + core->name, core->type); + break; + } + + if (IS_ERR_OR_NULL(clk)) + goto fail; + + dev_dbg(dev, "Core clock %pC at %pCr Hz\n", clk, clk); + priv->clks[id] = clk; + return; + +fail: + dev_err(dev, "Failed to register %s clock %s: %ld\n", "core,", + core->name, PTR_ERR(clk)); +} + +static void __init cpg_mssr_register_mod_clk(const struct mssr_mod_clk *mod, + const struct cpg_mssr_info *info, + struct cpg_mssr_priv *priv) +{ + struct mstp_clock *clock = NULL; + struct device *dev = priv->dev; + unsigned int id = mod->id; + struct clk_init_data init; + struct clk *parent, *clk; + const char *parent_name; + unsigned int i; + + WARN_DEBUG(id < priv->num_core_clks); + WARN_DEBUG(id >= priv->num_core_clks + priv->num_mod_clks); + WARN_DEBUG(mod->parent >= priv->num_core_clks + priv->num_mod_clks); + WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT); + + parent = priv->clks[mod->parent]; + if (IS_ERR(parent)) { + clk = parent; + goto fail; + } + + clock = kzalloc(sizeof(*clock), GFP_KERNEL); + if (!clock) { + clk = ERR_PTR(-ENOMEM); + goto fail; + } + + init.name = mod->name; + init.ops = &cpg_mstp_clock_ops; + init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; + for (i = 0; i < info->num_crit_mod_clks; i++) + if (id == info->crit_mod_clks[i]) { +#ifdef CLK_ENABLE_HAND_OFF + dev_dbg(dev, "MSTP %s setting CLK_ENABLE_HAND_OFF\n", + mod->name); + init.flags |= CLK_ENABLE_HAND_OFF; + break; +#else + dev_dbg(dev, "Ignoring MSTP %s to prevent disabling\n", + mod->name); + kfree(clock); + return; +#endif + } + + parent_name = __clk_get_name(parent); + init.parent_names = &parent_name; + init.num_parents = 1; + + clock->index = id - priv->num_core_clks; + clock->priv = priv; + clock->hw.init = &init; + + clk = clk_register(NULL, &clock->hw); + if (IS_ERR(clk)) + goto fail; + + dev_dbg(dev, "Module clock %pC at %pCr Hz\n", clk, clk); + priv->clks[id] = clk; + return; + +fail: + dev_err(dev, "Failed to register %s clock %s: %ld\n", "module,", + mod->name, PTR_ERR(clk)); + kfree(clock); +} + + +#ifdef CONFIG_PM_GENERIC_DOMAINS_OF +struct cpg_mssr_clk_domain { + struct generic_pm_domain genpd; + struct device_node *np; + unsigned int num_core_pm_clks; + unsigned int core_pm_clks[0]; +}; + +static bool cpg_mssr_is_pm_clk(const struct of_phandle_args *clkspec, + struct cpg_mssr_clk_domain *pd) +{ + unsigned int i; + + if (clkspec->np != pd->np || clkspec->args_count != 2) + return false; + + switch (clkspec->args[0]) { + case CPG_CORE: + for (i = 0; i < pd->num_core_pm_clks; i++) + if (clkspec->args[1] == pd->core_pm_clks[i]) + return true; + return false; + + case CPG_MOD: + return true; + + default: + return false; + } +} + +static int cpg_mssr_attach_dev(struct generic_pm_domain *genpd, + struct device *dev) +{ + struct cpg_mssr_clk_domain *pd = + container_of(genpd, struct cpg_mssr_clk_domain, genpd); + struct device_node *np = dev->of_node; + struct of_phandle_args clkspec; + struct clk *clk; + int i = 0; + int error; + + while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i, + &clkspec)) { + if (cpg_mssr_is_pm_clk(&clkspec, pd)) + goto found; + + of_node_put(clkspec.np); + i++; + } + + return 0; + +found: + clk = of_clk_get_from_provider(&clkspec); + of_node_put(clkspec.np); + + if (IS_ERR(clk)) + return PTR_ERR(clk); + + error = pm_clk_create(dev); + if (error) { + dev_err(dev, "pm_clk_create failed %d\n", error); + goto fail_put; + } + + error = pm_clk_add_clk(dev, clk); + if (error) { + dev_err(dev, "pm_clk_add_clk %pC failed %d\n", clk, error); + goto fail_destroy; + } + + return 0; + +fail_destroy: + pm_clk_destroy(dev); +fail_put: + clk_put(clk); + return error; +} + +static void cpg_mssr_detach_dev(struct generic_pm_domain *genpd, + struct device *dev) +{ + if (!list_empty(&dev->power.subsys_data->clock_list)) + pm_clk_destroy(dev); +} + +static int __init cpg_mssr_add_clk_domain(struct device *dev, + const unsigned int *core_pm_clks, + unsigned int num_core_pm_clks) +{ + struct device_node *np = dev->of_node; + struct generic_pm_domain *genpd; + struct cpg_mssr_clk_domain *pd; + size_t pm_size = num_core_pm_clks * sizeof(core_pm_clks[0]); + + pd = devm_kzalloc(dev, sizeof(*pd) + pm_size, GFP_KERNEL); + if (!pd) + return -ENOMEM; + + pd->np = np; + pd->num_core_pm_clks = num_core_pm_clks; + memcpy(pd->core_pm_clks, core_pm_clks, pm_size); + + genpd = &pd->genpd; + genpd->name = np->name; + genpd->flags = GENPD_FLAG_PM_CLK; + pm_genpd_init(genpd, &simple_qos_governor, false); + genpd->attach_dev = cpg_mssr_attach_dev; + genpd->detach_dev = cpg_mssr_detach_dev; + + of_genpd_add_provider_simple(np, genpd); + return 0; +} +#else +static inline int cpg_mssr_add_clk_domain(struct device *dev, + const unsigned int *core_pm_clks, + unsigned int num_core_pm_clks) +{ + return 0; +} +#endif /* !CONFIG_PM_GENERIC_DOMAINS_OF */ + + +static const struct of_device_id cpg_mssr_match[] = { +#ifdef CONFIG_ARCH_R8A7795 + { + .compatible = "renesas,r8a7795-cpg-mssr", + .data = &r8a7795_cpg_mssr_info, + }, +#endif + { /* sentinel */ } +}; + +static void cpg_mssr_del_clk_provider(void *data) +{ + of_clk_del_provider(data); +} + +static int __init cpg_mssr_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + const struct cpg_mssr_info *info; + struct cpg_mssr_priv *priv; + unsigned int nclks, i; + struct resource *res; + struct clk **clks; + int error; + + info = of_match_node(cpg_mssr_match, np)->data; + if (info->init) { + error = info->init(dev); + if (error) + return error; + } + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->dev = dev; + spin_lock_init(&priv->mstp_lock); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + priv->base = devm_ioremap_resource(dev, res); + if (IS_ERR(priv->base)) + return PTR_ERR(priv->base); + + nclks = info->num_total_core_clks + info->num_hw_mod_clks; + clks = devm_kmalloc_array(dev, nclks, sizeof(*clks), GFP_KERNEL); + if (!clks) + return -ENOMEM; + + priv->clks = clks; + priv->num_core_clks = info->num_total_core_clks; + priv->num_mod_clks = info->num_hw_mod_clks; + priv->last_dt_core_clk = info->last_dt_core_clk; + + for (i = 0; i < nclks; i++) + clks[i] = ERR_PTR(-ENOENT); + + for (i = 0; i < info->num_core_clks; i++) + cpg_mssr_register_core_clk(&info->core_clks[i], info, priv); + + for (i = 0; i < info->num_mod_clks; i++) + cpg_mssr_register_mod_clk(&info->mod_clks[i], info, priv); + + error = of_clk_add_provider(np, cpg_mssr_clk_src_twocell_get, priv); + if (error) + return error; + + error = devm_add_action_or_reset(dev, + cpg_mssr_del_clk_provider, + np); + if (error) + return error; + + error = cpg_mssr_add_clk_domain(dev, info->core_pm_clks, + info->num_core_pm_clks); + if (error) + return error; + + return 0; +} + +static struct platform_driver cpg_mssr_driver = { + .driver = { + .name = "renesas-cpg-mssr", + .of_match_table = cpg_mssr_match, + }, +}; + +static int __init cpg_mssr_init(void) +{ + return platform_driver_probe(&cpg_mssr_driver, cpg_mssr_probe); +} + +subsys_initcall(cpg_mssr_init); + +MODULE_DESCRIPTION("Renesas CPG/MSSR Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h new file mode 100644 index 0000000..952b695 --- /dev/null +++ b/drivers/clk/renesas/renesas-cpg-mssr.h @@ -0,0 +1,134 @@ +/* + * Renesas Clock Pulse Generator / Module Standby and Software Reset + * + * Copyright (C) 2015 Glider bvba + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + */ + +#ifndef __CLK_RENESAS_CPG_MSSR_H__ +#define __CLK_RENESAS_CPG_MSSR_H__ + + /* + * Definitions of CPG Core Clocks + * + * These include: + * - Clock outputs exported to DT + * - External input clocks + * - Internal CPG clocks + */ + +struct cpg_core_clk { + /* Common */ + const char *name; + unsigned int id; + unsigned int type; + /* Depending on type */ + unsigned int parent; /* Core Clocks only */ + unsigned int div; + unsigned int mult; + unsigned int offset; +}; + +enum clk_types { + /* Generic */ + CLK_TYPE_IN, /* External Clock Input */ + CLK_TYPE_FF, /* Fixed Factor Clock */ + CLK_TYPE_DIV6P1, /* DIV6 Clock with 1 parent clock */ + + /* Custom definitions start here */ + CLK_TYPE_CUSTOM, +}; + +#define DEF_TYPE(_name, _id, _type...) \ + { .name = _name, .id = _id, .type = _type } +#define DEF_BASE(_name, _id, _type, _parent...) \ + DEF_TYPE(_name, _id, _type, .parent = _parent) + +#define DEF_INPUT(_name, _id) \ + DEF_TYPE(_name, _id, CLK_TYPE_IN) +#define DEF_FIXED(_name, _id, _parent, _div, _mult) \ + DEF_BASE(_name, _id, CLK_TYPE_FF, _parent, .div = _div, .mult = _mult) +#define DEF_DIV6P1(_name, _id, _parent, _offset) \ + DEF_BASE(_name, _id, CLK_TYPE_DIV6P1, _parent, .offset = _offset) +#define DEF_SD(_name, _id, _parent, _offset) \ + DEF_BASE(_name, _id, CLK_TYPE_GEN3_SD, _parent, .offset = _offset) + + + /* + * Definitions of Module Clocks + */ + +struct mssr_mod_clk { + const char *name; + unsigned int id; + unsigned int parent; /* Add MOD_CLK_BASE for Module Clocks */ +}; + +/* Convert from sparse base-100 to packed index space */ +#define MOD_CLK_PACK(x) ((x) - ((x) / 100) * (100 - 32)) + +#define MOD_CLK_ID(x) (MOD_CLK_BASE + MOD_CLK_PACK(x)) + +#define DEF_MOD(_name, _mod, _parent...) \ + { .name = _name, .id = MOD_CLK_ID(_mod), .parent = _parent } + + +struct device_node; + + /** + * SoC-specific CPG/MSSR Description + * + * @core_clks: Array of Core Clock definitions + * @num_core_clks: Number of entries in core_clks[] + * @last_dt_core_clk: ID of the last Core Clock exported to DT + * @num_total_core_clks: Total number of Core Clocks (exported + internal) + * + * @mod_clks: Array of Module Clock definitions + * @num_mod_clks: Number of entries in mod_clks[] + * @num_hw_mod_clks: Number of Module Clocks supported by the hardware + * + * @crit_mod_clks: Array with Module Clock IDs of critical clocks that + * should not be disabled without a knowledgeable driver + * @num_crit_mod_clks: Number of entries in crit_mod_clks[] + * + * @core_pm_clks: Array with IDs of Core Clocks that are suitable for Power + * Management, in addition to Module Clocks + * @num_core_pm_clks: Number of entries in core_pm_clks[] + * + * @init: Optional callback to perform SoC-specific initialization + * @cpg_clk_register: Optional callback to handle special Core Clock types + */ + +struct cpg_mssr_info { + /* Core Clocks */ + const struct cpg_core_clk *core_clks; + unsigned int num_core_clks; + unsigned int last_dt_core_clk; + unsigned int num_total_core_clks; + + /* Module Clocks */ + const struct mssr_mod_clk *mod_clks; + unsigned int num_mod_clks; + unsigned int num_hw_mod_clks; + + /* Critical Module Clocks that should not be disabled */ + const unsigned int *crit_mod_clks; + unsigned int num_crit_mod_clks; + + /* Core Clocks suitable for PM, in addition to the Module Clocks */ + const unsigned int *core_pm_clks; + unsigned int num_core_pm_clks; + + /* Callbacks */ + int (*init)(struct device *dev); + struct clk *(*cpg_clk_register)(struct device *dev, + const struct cpg_core_clk *core, + const struct cpg_mssr_info *info, + struct clk **clks, void __iomem *base); +}; + +extern const struct cpg_mssr_info r8a7795_cpg_mssr_info; +#endif diff --git a/drivers/clk/shmobile/Makefile b/drivers/clk/shmobile/Makefile deleted file mode 100644 index 7e2579b..0000000 --- a/drivers/clk/shmobile/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -obj-$(CONFIG_ARCH_EMEV2) += clk-emev2.o -obj-$(CONFIG_ARCH_R7S72100) += clk-rz.o clk-mstp.o -obj-$(CONFIG_ARCH_R8A73A4) += clk-r8a73a4.o clk-mstp.o clk-div6.o -obj-$(CONFIG_ARCH_R8A7740) += clk-r8a7740.o clk-mstp.o clk-div6.o -obj-$(CONFIG_ARCH_R8A7778) += clk-r8a7778.o clk-mstp.o -obj-$(CONFIG_ARCH_R8A7779) += clk-r8a7779.o clk-mstp.o -obj-$(CONFIG_ARCH_R8A7790) += clk-rcar-gen2.o clk-mstp.o clk-div6.o -obj-$(CONFIG_ARCH_R8A7791) += clk-rcar-gen2.o clk-mstp.o clk-div6.o -obj-$(CONFIG_ARCH_R8A7793) += clk-rcar-gen2.o clk-mstp.o clk-div6.o -obj-$(CONFIG_ARCH_R8A7794) += clk-rcar-gen2.o clk-mstp.o clk-div6.o -obj-$(CONFIG_ARCH_R8A7795) += renesas-cpg-mssr.o \ - r8a7795-cpg-mssr.o clk-div6.o -obj-$(CONFIG_ARCH_SH73A0) += clk-sh73a0.o clk-mstp.o clk-div6.o diff --git a/drivers/clk/shmobile/clk-div6.c b/drivers/clk/shmobile/clk-div6.c deleted file mode 100644 index 0627860..0000000 --- a/drivers/clk/shmobile/clk-div6.c +++ /dev/null @@ -1,318 +0,0 @@ -/* - * r8a7790 Common Clock Framework support - * - * Copyright (C) 2013 Renesas Solutions Corp. - * - * Contact: Laurent Pinchart - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "clk-div6.h" - -#define CPG_DIV6_CKSTP BIT(8) -#define CPG_DIV6_DIV(d) ((d) & 0x3f) -#define CPG_DIV6_DIV_MASK 0x3f - -/** - * struct div6_clock - CPG 6 bit divider clock - * @hw: handle between common and hardware-specific interfaces - * @reg: IO-remapped register - * @div: divisor value (1-64) - */ -struct div6_clock { - struct clk_hw hw; - void __iomem *reg; - unsigned int div; - u32 src_shift; - u32 src_width; - u8 *parents; -}; - -#define to_div6_clock(_hw) container_of(_hw, struct div6_clock, hw) - -static int cpg_div6_clock_enable(struct clk_hw *hw) -{ - struct div6_clock *clock = to_div6_clock(hw); - u32 val; - - val = (clk_readl(clock->reg) & ~(CPG_DIV6_DIV_MASK | CPG_DIV6_CKSTP)) - | CPG_DIV6_DIV(clock->div - 1); - clk_writel(val, clock->reg); - - return 0; -} - -static void cpg_div6_clock_disable(struct clk_hw *hw) -{ - struct div6_clock *clock = to_div6_clock(hw); - u32 val; - - val = clk_readl(clock->reg); - val |= CPG_DIV6_CKSTP; - /* - * DIV6 clocks require the divisor field to be non-zero when stopping - * the clock. However, some clocks (e.g. ZB on sh73a0) fail to be - * re-enabled later if the divisor field is changed when stopping the - * clock - */ - if (!(val & CPG_DIV6_DIV_MASK)) - val |= CPG_DIV6_DIV_MASK; - clk_writel(val, clock->reg); -} - -static int cpg_div6_clock_is_enabled(struct clk_hw *hw) -{ - struct div6_clock *clock = to_div6_clock(hw); - - return !(clk_readl(clock->reg) & CPG_DIV6_CKSTP); -} - -static unsigned long cpg_div6_clock_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct div6_clock *clock = to_div6_clock(hw); - - return parent_rate / clock->div; -} - -static unsigned int cpg_div6_clock_calc_div(unsigned long rate, - unsigned long parent_rate) -{ - unsigned int div; - - if (!rate) - rate = 1; - - div = DIV_ROUND_CLOSEST(parent_rate, rate); - return clamp_t(unsigned int, div, 1, 64); -} - -static long cpg_div6_clock_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) -{ - unsigned int div = cpg_div6_clock_calc_div(rate, *parent_rate); - - return *parent_rate / div; -} - -static int cpg_div6_clock_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct div6_clock *clock = to_div6_clock(hw); - unsigned int div = cpg_div6_clock_calc_div(rate, parent_rate); - u32 val; - - clock->div = div; - - val = clk_readl(clock->reg) & ~CPG_DIV6_DIV_MASK; - /* Only program the new divisor if the clock isn't stopped. */ - if (!(val & CPG_DIV6_CKSTP)) - clk_writel(val | CPG_DIV6_DIV(clock->div - 1), clock->reg); - - return 0; -} - -static u8 cpg_div6_clock_get_parent(struct clk_hw *hw) -{ - struct div6_clock *clock = to_div6_clock(hw); - unsigned int i; - u8 hw_index; - - if (clock->src_width == 0) - return 0; - - hw_index = (clk_readl(clock->reg) >> clock->src_shift) & - (BIT(clock->src_width) - 1); - for (i = 0; i < clk_hw_get_num_parents(hw); i++) { - if (clock->parents[i] == hw_index) - return i; - } - - pr_err("%s: %s DIV6 clock set to invalid parent %u\n", - __func__, clk_hw_get_name(hw), hw_index); - return 0; -} - -static int cpg_div6_clock_set_parent(struct clk_hw *hw, u8 index) -{ - struct div6_clock *clock = to_div6_clock(hw); - u8 hw_index; - u32 mask; - - if (index >= clk_hw_get_num_parents(hw)) - return -EINVAL; - - mask = ~((BIT(clock->src_width) - 1) << clock->src_shift); - hw_index = clock->parents[index]; - - clk_writel((clk_readl(clock->reg) & mask) | - (hw_index << clock->src_shift), clock->reg); - - return 0; -} - -static const struct clk_ops cpg_div6_clock_ops = { - .enable = cpg_div6_clock_enable, - .disable = cpg_div6_clock_disable, - .is_enabled = cpg_div6_clock_is_enabled, - .get_parent = cpg_div6_clock_get_parent, - .set_parent = cpg_div6_clock_set_parent, - .recalc_rate = cpg_div6_clock_recalc_rate, - .round_rate = cpg_div6_clock_round_rate, - .set_rate = cpg_div6_clock_set_rate, -}; - - -/** - * cpg_div6_register - Register a DIV6 clock - * @name: Name of the DIV6 clock - * @num_parents: Number of parent clocks of the DIV6 clock (1, 4, or 8) - * @parent_names: Array containing the names of the parent clocks - * @reg: Mapped register used to control the DIV6 clock - */ -struct clk * __init cpg_div6_register(const char *name, - unsigned int num_parents, - const char **parent_names, - void __iomem *reg) -{ - unsigned int valid_parents; - struct clk_init_data init; - struct div6_clock *clock; - struct clk *clk; - unsigned int i; - - clock = kzalloc(sizeof(*clock), GFP_KERNEL); - if (!clock) - return ERR_PTR(-ENOMEM); - - clock->parents = kmalloc_array(num_parents, sizeof(*clock->parents), - GFP_KERNEL); - if (!clock->parents) { - clk = ERR_PTR(-ENOMEM); - goto free_clock; - } - - clock->reg = reg; - - /* - * Read the divisor. Disabling the clock overwrites the divisor, so we - * need to cache its value for the enable operation. - */ - clock->div = (clk_readl(clock->reg) & CPG_DIV6_DIV_MASK) + 1; - - switch (num_parents) { - case 1: - /* fixed parent clock */ - clock->src_shift = clock->src_width = 0; - break; - case 4: - /* clock with EXSRC bits 6-7 */ - clock->src_shift = 6; - clock->src_width = 2; - break; - case 8: - /* VCLK with EXSRC bits 12-14 */ - clock->src_shift = 12; - clock->src_width = 3; - break; - default: - pr_err("%s: invalid number of parents for DIV6 clock %s\n", - __func__, name); - clk = ERR_PTR(-EINVAL); - goto free_parents; - } - - /* Filter out invalid parents */ - for (i = 0, valid_parents = 0; i < num_parents; i++) { - if (parent_names[i]) { - parent_names[valid_parents] = parent_names[i]; - clock->parents[valid_parents] = i; - valid_parents++; - } - } - - /* Register the clock. */ - init.name = name; - init.ops = &cpg_div6_clock_ops; - init.flags = CLK_IS_BASIC; - init.parent_names = parent_names; - init.num_parents = valid_parents; - - clock->hw.init = &init; - - clk = clk_register(NULL, &clock->hw); - if (IS_ERR(clk)) - goto free_parents; - - return clk; - -free_parents: - kfree(clock->parents); -free_clock: - kfree(clock); - return clk; -} - -static void __init cpg_div6_clock_init(struct device_node *np) -{ - unsigned int num_parents; - const char **parent_names; - const char *clk_name = np->name; - void __iomem *reg; - struct clk *clk; - unsigned int i; - - num_parents = of_clk_get_parent_count(np); - if (num_parents < 1) { - pr_err("%s: no parent found for %s DIV6 clock\n", - __func__, np->name); - return; - } - - parent_names = kmalloc_array(num_parents, sizeof(*parent_names), - GFP_KERNEL); - if (!parent_names) - return; - - reg = of_iomap(np, 0); - if (reg == NULL) { - pr_err("%s: failed to map %s DIV6 clock register\n", - __func__, np->name); - goto error; - } - - /* Parse the DT properties. */ - of_property_read_string(np, "clock-output-names", &clk_name); - - for (i = 0; i < num_parents; i++) - parent_names[i] = of_clk_get_parent_name(np, i); - - clk = cpg_div6_register(clk_name, num_parents, parent_names, reg); - if (IS_ERR(clk)) { - pr_err("%s: failed to register %s DIV6 clock (%ld)\n", - __func__, np->name, PTR_ERR(clk)); - goto error; - } - - of_clk_add_provider(np, of_clk_src_simple_get, clk); - - kfree(parent_names); - return; - -error: - if (reg) - iounmap(reg); - kfree(parent_names); -} -CLK_OF_DECLARE(cpg_div6_clk, "renesas,cpg-div6-clock", cpg_div6_clock_init); diff --git a/drivers/clk/shmobile/clk-div6.h b/drivers/clk/shmobile/clk-div6.h deleted file mode 100644 index 9a85a95..0000000 --- a/drivers/clk/shmobile/clk-div6.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __SHMOBILE_CLK_DIV6_H__ -#define __SHMOBILE_CLK_DIV6_H__ - -struct clk *cpg_div6_register(const char *name, unsigned int num_parents, - const char **parent_names, void __iomem *reg); - -#endif diff --git a/drivers/clk/shmobile/clk-emev2.c b/drivers/clk/shmobile/clk-emev2.c deleted file mode 100644 index a918254..0000000 --- a/drivers/clk/shmobile/clk-emev2.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * EMMA Mobile EV2 common clock framework support - * - * Copyright (C) 2013 Takashi Yoshii - * Copyright (C) 2012 Magnus Damm - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include -#include -#include -#include -#include - -/* EMEV2 SMU registers */ -#define USIAU0_RSTCTRL 0x094 -#define USIBU1_RSTCTRL 0x0ac -#define USIBU2_RSTCTRL 0x0b0 -#define USIBU3_RSTCTRL 0x0b4 -#define IIC0_RSTCTRL 0x0dc -#define IIC1_RSTCTRL 0x0e0 -#define STI_RSTCTRL 0x124 -#define STI_CLKSEL 0x688 - -static DEFINE_SPINLOCK(lock); - -/* not pretty, but hey */ -static void __iomem *smu_base; - -static void __init emev2_smu_write(unsigned long value, int offs) -{ - BUG_ON(!smu_base || (offs >= PAGE_SIZE)); - writel_relaxed(value, smu_base + offs); -} - -static const struct of_device_id smu_id[] __initconst = { - { .compatible = "renesas,emev2-smu", }, - {}, -}; - -static void __init emev2_smu_init(void) -{ - struct device_node *np; - - np = of_find_matching_node(NULL, smu_id); - BUG_ON(!np); - smu_base = of_iomap(np, 0); - BUG_ON(!smu_base); - of_node_put(np); - - /* setup STI timer to run on 32.768 kHz and deassert reset */ - emev2_smu_write(0, STI_CLKSEL); - emev2_smu_write(1, STI_RSTCTRL); - - /* deassert reset for UART0->UART3 */ - emev2_smu_write(2, USIAU0_RSTCTRL); - emev2_smu_write(2, USIBU1_RSTCTRL); - emev2_smu_write(2, USIBU2_RSTCTRL); - emev2_smu_write(2, USIBU3_RSTCTRL); - - /* deassert reset for IIC0->IIC1 */ - emev2_smu_write(1, IIC0_RSTCTRL); - emev2_smu_write(1, IIC1_RSTCTRL); -} - -static void __init emev2_smu_clkdiv_init(struct device_node *np) -{ - u32 reg[2]; - struct clk *clk; - const char *parent_name = of_clk_get_parent_name(np, 0); - if (WARN_ON(of_property_read_u32_array(np, "reg", reg, 2))) - return; - if (!smu_base) - emev2_smu_init(); - clk = clk_register_divider(NULL, np->name, parent_name, 0, - smu_base + reg[0], reg[1], 8, 0, &lock); - of_clk_add_provider(np, of_clk_src_simple_get, clk); - clk_register_clkdev(clk, np->name, NULL); - pr_debug("## %s %s %p\n", __func__, np->name, clk); -} -CLK_OF_DECLARE(emev2_smu_clkdiv, "renesas,emev2-smu-clkdiv", - emev2_smu_clkdiv_init); - -static void __init emev2_smu_gclk_init(struct device_node *np) -{ - u32 reg[2]; - struct clk *clk; - const char *parent_name = of_clk_get_parent_name(np, 0); - if (WARN_ON(of_property_read_u32_array(np, "reg", reg, 2))) - return; - if (!smu_base) - emev2_smu_init(); - clk = clk_register_gate(NULL, np->name, parent_name, 0, - smu_base + reg[0], reg[1], 0, &lock); - of_clk_add_provider(np, of_clk_src_simple_get, clk); - clk_register_clkdev(clk, np->name, NULL); - pr_debug("## %s %s %p\n", __func__, np->name, clk); -} -CLK_OF_DECLARE(emev2_smu_gclk, "renesas,emev2-smu-gclk", emev2_smu_gclk_init); diff --git a/drivers/clk/shmobile/clk-mstp.c b/drivers/clk/shmobile/clk-mstp.c deleted file mode 100644 index 3b09716..0000000 --- a/drivers/clk/shmobile/clk-mstp.c +++ /dev/null @@ -1,329 +0,0 @@ -/* - * R-Car MSTP clocks - * - * Copyright (C) 2013 Ideas On Board SPRL - * Copyright (C) 2015 Glider bvba - * - * Contact: Laurent Pinchart - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * MSTP clocks. We can't use standard gate clocks as we need to poll on the - * status register when enabling the clock. - */ - -#define MSTP_MAX_CLOCKS 32 - -/** - * struct mstp_clock_group - MSTP gating clocks group - * - * @data: clocks in this group - * @smstpcr: module stop control register - * @mstpsr: module stop status register (optional) - * @lock: protects writes to SMSTPCR - */ -struct mstp_clock_group { - struct clk_onecell_data data; - void __iomem *smstpcr; - void __iomem *mstpsr; - spinlock_t lock; -}; - -/** - * struct mstp_clock - MSTP gating clock - * @hw: handle between common and hardware-specific interfaces - * @bit_index: control bit index - * @group: MSTP clocks group - */ -struct mstp_clock { - struct clk_hw hw; - u32 bit_index; - struct mstp_clock_group *group; -}; - -#define to_mstp_clock(_hw) container_of(_hw, struct mstp_clock, hw) - -static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable) -{ - struct mstp_clock *clock = to_mstp_clock(hw); - struct mstp_clock_group *group = clock->group; - u32 bitmask = BIT(clock->bit_index); - unsigned long flags; - unsigned int i; - u32 value; - - spin_lock_irqsave(&group->lock, flags); - - value = clk_readl(group->smstpcr); - if (enable) - value &= ~bitmask; - else - value |= bitmask; - clk_writel(value, group->smstpcr); - - spin_unlock_irqrestore(&group->lock, flags); - - if (!enable || !group->mstpsr) - return 0; - - for (i = 1000; i > 0; --i) { - if (!(clk_readl(group->mstpsr) & bitmask)) - break; - cpu_relax(); - } - - if (!i) { - pr_err("%s: failed to enable %p[%d]\n", __func__, - group->smstpcr, clock->bit_index); - return -ETIMEDOUT; - } - - return 0; -} - -static int cpg_mstp_clock_enable(struct clk_hw *hw) -{ - return cpg_mstp_clock_endisable(hw, true); -} - -static void cpg_mstp_clock_disable(struct clk_hw *hw) -{ - cpg_mstp_clock_endisable(hw, false); -} - -static int cpg_mstp_clock_is_enabled(struct clk_hw *hw) -{ - struct mstp_clock *clock = to_mstp_clock(hw); - struct mstp_clock_group *group = clock->group; - u32 value; - - if (group->mstpsr) - value = clk_readl(group->mstpsr); - else - value = clk_readl(group->smstpcr); - - return !(value & BIT(clock->bit_index)); -} - -static const struct clk_ops cpg_mstp_clock_ops = { - .enable = cpg_mstp_clock_enable, - .disable = cpg_mstp_clock_disable, - .is_enabled = cpg_mstp_clock_is_enabled, -}; - -static struct clk * __init -cpg_mstp_clock_register(const char *name, const char *parent_name, - unsigned int index, struct mstp_clock_group *group) -{ - struct clk_init_data init; - struct mstp_clock *clock; - struct clk *clk; - - clock = kzalloc(sizeof(*clock), GFP_KERNEL); - if (!clock) { - pr_err("%s: failed to allocate MSTP clock.\n", __func__); - return ERR_PTR(-ENOMEM); - } - - init.name = name; - init.ops = &cpg_mstp_clock_ops; - init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; - init.parent_names = &parent_name; - init.num_parents = 1; - - clock->bit_index = index; - clock->group = group; - clock->hw.init = &init; - - clk = clk_register(NULL, &clock->hw); - - if (IS_ERR(clk)) - kfree(clock); - - return clk; -} - -static void __init cpg_mstp_clocks_init(struct device_node *np) -{ - struct mstp_clock_group *group; - const char *idxname; - struct clk **clks; - unsigned int i; - - group = kzalloc(sizeof(*group), GFP_KERNEL); - clks = kmalloc(MSTP_MAX_CLOCKS * sizeof(*clks), GFP_KERNEL); - if (group == NULL || clks == NULL) { - kfree(group); - kfree(clks); - pr_err("%s: failed to allocate group\n", __func__); - return; - } - - spin_lock_init(&group->lock); - group->data.clks = clks; - - group->smstpcr = of_iomap(np, 0); - group->mstpsr = of_iomap(np, 1); - - if (group->smstpcr == NULL) { - pr_err("%s: failed to remap SMSTPCR\n", __func__); - kfree(group); - kfree(clks); - return; - } - - for (i = 0; i < MSTP_MAX_CLOCKS; ++i) - clks[i] = ERR_PTR(-ENOENT); - - if (of_find_property(np, "clock-indices", &i)) - idxname = "clock-indices"; - else - idxname = "renesas,clock-indices"; - - for (i = 0; i < MSTP_MAX_CLOCKS; ++i) { - const char *parent_name; - const char *name; - u32 clkidx; - int ret; - - /* Skip clocks with no name. */ - ret = of_property_read_string_index(np, "clock-output-names", - i, &name); - if (ret < 0 || strlen(name) == 0) - continue; - - parent_name = of_clk_get_parent_name(np, i); - ret = of_property_read_u32_index(np, idxname, i, &clkidx); - if (parent_name == NULL || ret < 0) - break; - - if (clkidx >= MSTP_MAX_CLOCKS) { - pr_err("%s: invalid clock %s %s index %u\n", - __func__, np->name, name, clkidx); - continue; - } - - clks[clkidx] = cpg_mstp_clock_register(name, parent_name, - clkidx, group); - if (!IS_ERR(clks[clkidx])) { - group->data.clk_num = max(group->data.clk_num, - clkidx + 1); - /* - * Register a clkdev to let board code retrieve the - * clock by name and register aliases for non-DT - * devices. - * - * FIXME: Remove this when all devices that require a - * clock will be instantiated from DT. - */ - clk_register_clkdev(clks[clkidx], name, NULL); - } else { - pr_err("%s: failed to register %s %s clock (%ld)\n", - __func__, np->name, name, PTR_ERR(clks[clkidx])); - } - } - - of_clk_add_provider(np, of_clk_src_onecell_get, &group->data); -} -CLK_OF_DECLARE(cpg_mstp_clks, "renesas,cpg-mstp-clocks", cpg_mstp_clocks_init); - - -#ifdef CONFIG_PM_GENERIC_DOMAINS_OF -int cpg_mstp_attach_dev(struct generic_pm_domain *domain, struct device *dev) -{ - struct device_node *np = dev->of_node; - struct of_phandle_args clkspec; - struct clk *clk; - int i = 0; - int error; - - while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i, - &clkspec)) { - if (of_device_is_compatible(clkspec.np, - "renesas,cpg-mstp-clocks")) - goto found; - - /* BSC on r8a73a4/sh73a0 uses zb_clk instead of an mstp clock */ - if (!strcmp(clkspec.np->name, "zb_clk")) - goto found; - - of_node_put(clkspec.np); - i++; - } - - return 0; - -found: - clk = of_clk_get_from_provider(&clkspec); - of_node_put(clkspec.np); - - if (IS_ERR(clk)) - return PTR_ERR(clk); - - error = pm_clk_create(dev); - if (error) { - dev_err(dev, "pm_clk_create failed %d\n", error); - goto fail_put; - } - - error = pm_clk_add_clk(dev, clk); - if (error) { - dev_err(dev, "pm_clk_add_clk %pC failed %d\n", clk, error); - goto fail_destroy; - } - - return 0; - -fail_destroy: - pm_clk_destroy(dev); -fail_put: - clk_put(clk); - return error; -} - -void cpg_mstp_detach_dev(struct generic_pm_domain *domain, struct device *dev) -{ - if (!list_empty(&dev->power.subsys_data->clock_list)) - pm_clk_destroy(dev); -} - -void __init cpg_mstp_add_clk_domain(struct device_node *np) -{ - struct generic_pm_domain *pd; - u32 ncells; - - if (of_property_read_u32(np, "#power-domain-cells", &ncells)) { - pr_warn("%s lacks #power-domain-cells\n", np->full_name); - return; - } - - pd = kzalloc(sizeof(*pd), GFP_KERNEL); - if (!pd) - return; - - pd->name = np->name; - - pd->flags = GENPD_FLAG_PM_CLK; - pm_genpd_init(pd, &simple_qos_governor, false); - pd->attach_dev = cpg_mstp_attach_dev; - pd->detach_dev = cpg_mstp_detach_dev; - - of_genpd_add_provider_simple(np, pd); -} -#endif /* !CONFIG_PM_GENERIC_DOMAINS_OF */ diff --git a/drivers/clk/shmobile/clk-r8a73a4.c b/drivers/clk/shmobile/clk-r8a73a4.c deleted file mode 100644 index 9326204..0000000 --- a/drivers/clk/shmobile/clk-r8a73a4.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * r8a73a4 Core CPG Clocks - * - * Copyright (C) 2014 Ulrich Hecht - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -struct r8a73a4_cpg { - struct clk_onecell_data data; - spinlock_t lock; - void __iomem *reg; -}; - -#define CPG_CKSCR 0xc0 -#define CPG_FRQCRA 0x00 -#define CPG_FRQCRB 0x04 -#define CPG_FRQCRC 0xe0 -#define CPG_PLL0CR 0xd8 -#define CPG_PLL1CR 0x28 -#define CPG_PLL2CR 0x2c -#define CPG_PLL2HCR 0xe4 -#define CPG_PLL2SCR 0xf4 - -#define CLK_ENABLE_ON_INIT BIT(0) - -struct div4_clk { - const char *name; - unsigned int reg; - unsigned int shift; -}; - -static struct div4_clk div4_clks[] = { - { "i", CPG_FRQCRA, 20 }, - { "m3", CPG_FRQCRA, 12 }, - { "b", CPG_FRQCRA, 8 }, - { "m1", CPG_FRQCRA, 4 }, - { "m2", CPG_FRQCRA, 0 }, - { "zx", CPG_FRQCRB, 12 }, - { "zs", CPG_FRQCRB, 8 }, - { "hp", CPG_FRQCRB, 4 }, - { NULL, 0, 0 }, -}; - -static const struct clk_div_table div4_div_table[] = { - { 0, 2 }, { 1, 3 }, { 2, 4 }, { 3, 6 }, { 4, 8 }, { 5, 12 }, - { 6, 16 }, { 7, 18 }, { 8, 24 }, { 10, 36 }, { 11, 48 }, - { 12, 10 }, { 0, 0 } -}; - -static struct clk * __init -r8a73a4_cpg_register_clock(struct device_node *np, struct r8a73a4_cpg *cpg, - const char *name) -{ - const struct clk_div_table *table = NULL; - const char *parent_name; - unsigned int shift, reg; - unsigned int mult = 1; - unsigned int div = 1; - - - if (!strcmp(name, "main")) { - u32 ckscr = clk_readl(cpg->reg + CPG_CKSCR); - - switch ((ckscr >> 28) & 3) { - case 0: /* extal1 */ - parent_name = of_clk_get_parent_name(np, 0); - break; - case 1: /* extal1 / 2 */ - parent_name = of_clk_get_parent_name(np, 0); - div = 2; - break; - case 2: /* extal2 */ - parent_name = of_clk_get_parent_name(np, 1); - break; - case 3: /* extal2 / 2 */ - parent_name = of_clk_get_parent_name(np, 1); - div = 2; - break; - } - } else if (!strcmp(name, "pll0")) { - /* PLL0/1 are configurable multiplier clocks. Register them as - * fixed factor clocks for now as there's no generic multiplier - * clock implementation and we currently have no need to change - * the multiplier value. - */ - u32 value = clk_readl(cpg->reg + CPG_PLL0CR); - - parent_name = "main"; - mult = ((value >> 24) & 0x7f) + 1; - if (value & BIT(20)) - div = 2; - } else if (!strcmp(name, "pll1")) { - u32 value = clk_readl(cpg->reg + CPG_PLL1CR); - - parent_name = "main"; - /* XXX: enable bit? */ - mult = ((value >> 24) & 0x7f) + 1; - if (value & BIT(7)) - div = 2; - } else if (!strncmp(name, "pll2", 4)) { - u32 value, cr; - - switch (name[4]) { - case 0: - cr = CPG_PLL2CR; - break; - case 's': - cr = CPG_PLL2SCR; - break; - case 'h': - cr = CPG_PLL2HCR; - break; - default: - return ERR_PTR(-EINVAL); - } - value = clk_readl(cpg->reg + cr); - switch ((value >> 5) & 7) { - case 0: - parent_name = "main"; - div = 2; - break; - case 1: - parent_name = "extal2"; - div = 2; - break; - case 3: - parent_name = "extal2"; - div = 4; - break; - case 4: - parent_name = "main"; - break; - case 5: - parent_name = "extal2"; - break; - default: - pr_warn("%s: unexpected parent of %s\n", __func__, - name); - return ERR_PTR(-EINVAL); - } - /* XXX: enable bit? */ - mult = ((value >> 24) & 0x7f) + 1; - } else if (!strcmp(name, "z") || !strcmp(name, "z2")) { - u32 shift = 8; - - parent_name = "pll0"; - if (name[1] == '2') { - div = 2; - shift = 0; - } - div *= 32; - mult = 0x20 - ((clk_readl(cpg->reg + CPG_FRQCRC) >> shift) - & 0x1f); - } else { - struct div4_clk *c; - - for (c = div4_clks; c->name; c++) { - if (!strcmp(name, c->name)) - break; - } - if (!c->name) - return ERR_PTR(-EINVAL); - - parent_name = "pll1"; - table = div4_div_table; - reg = c->reg; - shift = c->shift; - } - - if (!table) { - return clk_register_fixed_factor(NULL, name, parent_name, 0, - mult, div); - } else { - return clk_register_divider_table(NULL, name, parent_name, 0, - cpg->reg + reg, shift, 4, 0, - table, &cpg->lock); - } -} - -static void __init r8a73a4_cpg_clocks_init(struct device_node *np) -{ - struct r8a73a4_cpg *cpg; - struct clk **clks; - unsigned int i; - int num_clks; - - num_clks = of_property_count_strings(np, "clock-output-names"); - if (num_clks < 0) { - pr_err("%s: failed to count clocks\n", __func__); - return; - } - - cpg = kzalloc(sizeof(*cpg), GFP_KERNEL); - clks = kcalloc(num_clks, sizeof(*clks), GFP_KERNEL); - if (cpg == NULL || clks == NULL) { - /* We're leaking memory on purpose, there's no point in cleaning - * up as the system won't boot anyway. - */ - return; - } - - spin_lock_init(&cpg->lock); - - cpg->data.clks = clks; - cpg->data.clk_num = num_clks; - - cpg->reg = of_iomap(np, 0); - if (WARN_ON(cpg->reg == NULL)) - return; - - for (i = 0; i < num_clks; ++i) { - const char *name; - struct clk *clk; - - of_property_read_string_index(np, "clock-output-names", i, - &name); - - clk = r8a73a4_cpg_register_clock(np, cpg, name); - if (IS_ERR(clk)) - pr_err("%s: failed to register %s %s clock (%ld)\n", - __func__, np->name, name, PTR_ERR(clk)); - else - cpg->data.clks[i] = clk; - } - - of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data); -} -CLK_OF_DECLARE(r8a73a4_cpg_clks, "renesas,r8a73a4-cpg-clocks", - r8a73a4_cpg_clocks_init); diff --git a/drivers/clk/shmobile/clk-r8a7740.c b/drivers/clk/shmobile/clk-r8a7740.c deleted file mode 100644 index 1e6b1da..0000000 --- a/drivers/clk/shmobile/clk-r8a7740.c +++ /dev/null @@ -1,199 +0,0 @@ -/* - * r8a7740 Core CPG Clocks - * - * Copyright (C) 2014 Ulrich Hecht - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -struct r8a7740_cpg { - struct clk_onecell_data data; - spinlock_t lock; - void __iomem *reg; -}; - -#define CPG_FRQCRA 0x00 -#define CPG_FRQCRB 0x04 -#define CPG_PLLC2CR 0x2c -#define CPG_USBCKCR 0x8c -#define CPG_FRQCRC 0xe0 - -#define CLK_ENABLE_ON_INIT BIT(0) - -struct div4_clk { - const char *name; - unsigned int reg; - unsigned int shift; - int flags; -}; - -static struct div4_clk div4_clks[] = { - { "i", CPG_FRQCRA, 20, CLK_ENABLE_ON_INIT }, - { "zg", CPG_FRQCRA, 16, CLK_ENABLE_ON_INIT }, - { "b", CPG_FRQCRA, 8, CLK_ENABLE_ON_INIT }, - { "m1", CPG_FRQCRA, 4, CLK_ENABLE_ON_INIT }, - { "hp", CPG_FRQCRB, 4, 0 }, - { "hpp", CPG_FRQCRC, 20, 0 }, - { "usbp", CPG_FRQCRC, 16, 0 }, - { "s", CPG_FRQCRC, 12, 0 }, - { "zb", CPG_FRQCRC, 8, 0 }, - { "m3", CPG_FRQCRC, 4, 0 }, - { "cp", CPG_FRQCRC, 0, 0 }, - { NULL, 0, 0, 0 }, -}; - -static const struct clk_div_table div4_div_table[] = { - { 0, 2 }, { 1, 3 }, { 2, 4 }, { 3, 6 }, { 4, 8 }, { 5, 12 }, - { 6, 16 }, { 7, 18 }, { 8, 24 }, { 9, 32 }, { 10, 36 }, { 11, 48 }, - { 13, 72 }, { 14, 96 }, { 0, 0 } -}; - -static u32 cpg_mode __initdata; - -static struct clk * __init -r8a7740_cpg_register_clock(struct device_node *np, struct r8a7740_cpg *cpg, - const char *name) -{ - const struct clk_div_table *table = NULL; - const char *parent_name; - unsigned int shift, reg; - unsigned int mult = 1; - unsigned int div = 1; - - if (!strcmp(name, "r")) { - switch (cpg_mode & (BIT(2) | BIT(1))) { - case BIT(1) | BIT(2): - /* extal1 */ - parent_name = of_clk_get_parent_name(np, 0); - div = 2048; - break; - case BIT(2): - /* extal1 */ - parent_name = of_clk_get_parent_name(np, 0); - div = 1024; - break; - default: - /* extalr */ - parent_name = of_clk_get_parent_name(np, 2); - break; - } - } else if (!strcmp(name, "system")) { - parent_name = of_clk_get_parent_name(np, 0); - if (cpg_mode & BIT(1)) - div = 2; - } else if (!strcmp(name, "pllc0")) { - /* PLLC0/1 are configurable multiplier clocks. Register them as - * fixed factor clocks for now as there's no generic multiplier - * clock implementation and we currently have no need to change - * the multiplier value. - */ - u32 value = clk_readl(cpg->reg + CPG_FRQCRC); - parent_name = "system"; - mult = ((value >> 24) & 0x7f) + 1; - } else if (!strcmp(name, "pllc1")) { - u32 value = clk_readl(cpg->reg + CPG_FRQCRA); - parent_name = "system"; - mult = ((value >> 24) & 0x7f) + 1; - div = 2; - } else if (!strcmp(name, "pllc2")) { - u32 value = clk_readl(cpg->reg + CPG_PLLC2CR); - parent_name = "system"; - mult = ((value >> 24) & 0x3f) + 1; - } else if (!strcmp(name, "usb24s")) { - u32 value = clk_readl(cpg->reg + CPG_USBCKCR); - if (value & BIT(7)) - /* extal2 */ - parent_name = of_clk_get_parent_name(np, 1); - else - parent_name = "system"; - if (!(value & BIT(6))) - div = 2; - } else { - struct div4_clk *c; - for (c = div4_clks; c->name; c++) { - if (!strcmp(name, c->name)) { - parent_name = "pllc1"; - table = div4_div_table; - reg = c->reg; - shift = c->shift; - break; - } - } - if (!c->name) - return ERR_PTR(-EINVAL); - } - - if (!table) { - return clk_register_fixed_factor(NULL, name, parent_name, 0, - mult, div); - } else { - return clk_register_divider_table(NULL, name, parent_name, 0, - cpg->reg + reg, shift, 4, 0, - table, &cpg->lock); - } -} - -static void __init r8a7740_cpg_clocks_init(struct device_node *np) -{ - struct r8a7740_cpg *cpg; - struct clk **clks; - unsigned int i; - int num_clks; - - if (of_property_read_u32(np, "renesas,mode", &cpg_mode)) - pr_warn("%s: missing renesas,mode property\n", __func__); - - num_clks = of_property_count_strings(np, "clock-output-names"); - if (num_clks < 0) { - pr_err("%s: failed to count clocks\n", __func__); - return; - } - - cpg = kzalloc(sizeof(*cpg), GFP_KERNEL); - clks = kzalloc(num_clks * sizeof(*clks), GFP_KERNEL); - if (cpg == NULL || clks == NULL) { - /* We're leaking memory on purpose, there's no point in cleaning - * up as the system won't boot anyway. - */ - return; - } - - spin_lock_init(&cpg->lock); - - cpg->data.clks = clks; - cpg->data.clk_num = num_clks; - - cpg->reg = of_iomap(np, 0); - if (WARN_ON(cpg->reg == NULL)) - return; - - for (i = 0; i < num_clks; ++i) { - const char *name; - struct clk *clk; - - of_property_read_string_index(np, "clock-output-names", i, - &name); - - clk = r8a7740_cpg_register_clock(np, cpg, name); - if (IS_ERR(clk)) - pr_err("%s: failed to register %s %s clock (%ld)\n", - __func__, np->name, name, PTR_ERR(clk)); - else - cpg->data.clks[i] = clk; - } - - of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data); -} -CLK_OF_DECLARE(r8a7740_cpg_clks, "renesas,r8a7740-cpg-clocks", - r8a7740_cpg_clocks_init); diff --git a/drivers/clk/shmobile/clk-r8a7778.c b/drivers/clk/shmobile/clk-r8a7778.c deleted file mode 100644 index b174155..0000000 --- a/drivers/clk/shmobile/clk-r8a7778.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * r8a7778 Core CPG Clocks - * - * Copyright (C) 2014 Ulrich Hecht - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - */ - -#include -#include -#include -#include - -struct r8a7778_cpg { - struct clk_onecell_data data; - spinlock_t lock; - void __iomem *reg; -}; - -/* PLL multipliers per bits 11, 12, and 18 of MODEMR */ -static const struct { - unsigned long plla_mult; - unsigned long pllb_mult; -} r8a7778_rates[] __initconst = { - [0] = { 21, 21 }, - [1] = { 24, 24 }, - [2] = { 28, 28 }, - [3] = { 32, 32 }, - [5] = { 24, 21 }, - [6] = { 28, 21 }, - [7] = { 32, 24 }, -}; - -/* Clock dividers per bits 1 and 2 of MODEMR */ -static const struct { - const char *name; - unsigned int div[4]; -} r8a7778_divs[6] __initconst = { - { "b", { 12, 12, 16, 18 } }, - { "out", { 12, 12, 16, 18 } }, - { "p", { 16, 12, 16, 12 } }, - { "s", { 4, 3, 4, 3 } }, - { "s1", { 8, 6, 8, 6 } }, -}; - -static u32 cpg_mode_rates __initdata; -static u32 cpg_mode_divs __initdata; - -static struct clk * __init -r8a7778_cpg_register_clock(struct device_node *np, struct r8a7778_cpg *cpg, - const char *name) -{ - if (!strcmp(name, "plla")) { - return clk_register_fixed_factor(NULL, "plla", - of_clk_get_parent_name(np, 0), 0, - r8a7778_rates[cpg_mode_rates].plla_mult, 1); - } else if (!strcmp(name, "pllb")) { - return clk_register_fixed_factor(NULL, "pllb", - of_clk_get_parent_name(np, 0), 0, - r8a7778_rates[cpg_mode_rates].pllb_mult, 1); - } else { - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(r8a7778_divs); i++) { - if (!strcmp(name, r8a7778_divs[i].name)) { - return clk_register_fixed_factor(NULL, - r8a7778_divs[i].name, - "plla", 0, 1, - r8a7778_divs[i].div[cpg_mode_divs]); - } - } - } - - return ERR_PTR(-EINVAL); -} - - -static void __init r8a7778_cpg_clocks_init(struct device_node *np) -{ - struct r8a7778_cpg *cpg; - struct clk **clks; - unsigned int i; - int num_clks; - - num_clks = of_property_count_strings(np, "clock-output-names"); - if (num_clks < 0) { - pr_err("%s: failed to count clocks\n", __func__); - return; - } - - cpg = kzalloc(sizeof(*cpg), GFP_KERNEL); - clks = kcalloc(num_clks, sizeof(*clks), GFP_KERNEL); - if (cpg == NULL || clks == NULL) { - /* We're leaking memory on purpose, there's no point in cleaning - * up as the system won't boot anyway. - */ - return; - } - - spin_lock_init(&cpg->lock); - - cpg->data.clks = clks; - cpg->data.clk_num = num_clks; - - cpg->reg = of_iomap(np, 0); - if (WARN_ON(cpg->reg == NULL)) - return; - - for (i = 0; i < num_clks; ++i) { - const char *name; - struct clk *clk; - - of_property_read_string_index(np, "clock-output-names", i, - &name); - - clk = r8a7778_cpg_register_clock(np, cpg, name); - if (IS_ERR(clk)) - pr_err("%s: failed to register %s %s clock (%ld)\n", - __func__, np->name, name, PTR_ERR(clk)); - else - cpg->data.clks[i] = clk; - } - - of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data); - - cpg_mstp_add_clk_domain(np); -} - -CLK_OF_DECLARE(r8a7778_cpg_clks, "renesas,r8a7778-cpg-clocks", - r8a7778_cpg_clocks_init); - -void __init r8a7778_clocks_init(u32 mode) -{ - BUG_ON(!(mode & BIT(19))); - - cpg_mode_rates = (!!(mode & BIT(18)) << 2) | - (!!(mode & BIT(12)) << 1) | - (!!(mode & BIT(11))); - cpg_mode_divs = (!!(mode & BIT(2)) << 1) | - (!!(mode & BIT(1))); - - of_clk_init(NULL); -} diff --git a/drivers/clk/shmobile/clk-r8a7779.c b/drivers/clk/shmobile/clk-r8a7779.c deleted file mode 100644 index 92275c5f..0000000 --- a/drivers/clk/shmobile/clk-r8a7779.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * r8a7779 Core CPG Clocks - * - * Copyright (C) 2013, 2014 Horms Solutions Ltd. - * - * Contact: Simon Horman - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define CPG_NUM_CLOCKS (R8A7779_CLK_OUT + 1) - -struct r8a7779_cpg { - struct clk_onecell_data data; - spinlock_t lock; - void __iomem *reg; -}; - -/* ----------------------------------------------------------------------------- - * CPG Clock Data - */ - -/* - * MD1 = 1 MD1 = 0 - * (PLLA = 1500) (PLLA = 1600) - * (MHz) (MHz) - *------------------------------------------------+-------------------- - * clkz 1000 (2/3) 800 (1/2) - * clkzs 250 (1/6) 200 (1/8) - * clki 750 (1/2) 800 (1/2) - * clks 250 (1/6) 200 (1/8) - * clks1 125 (1/12) 100 (1/16) - * clks3 187.5 (1/8) 200 (1/8) - * clks4 93.7 (1/16) 100 (1/16) - * clkp 62.5 (1/24) 50 (1/32) - * clkg 62.5 (1/24) 66.6 (1/24) - * clkb, CLKOUT - * (MD2 = 0) 62.5 (1/24) 66.6 (1/24) - * (MD2 = 1) 41.6 (1/36) 50 (1/32) - */ - -#define CPG_CLK_CONFIG_INDEX(md) (((md) & (BIT(2)|BIT(1))) >> 1) - -struct cpg_clk_config { - unsigned int z_mult; - unsigned int z_div; - unsigned int zs_and_s_div; - unsigned int s1_div; - unsigned int p_div; - unsigned int b_and_out_div; -}; - -static const struct cpg_clk_config cpg_clk_configs[4] __initconst = { - { 1, 2, 8, 16, 32, 24 }, - { 2, 3, 6, 12, 24, 24 }, - { 1, 2, 8, 16, 32, 32 }, - { 2, 3, 6, 12, 24, 36 }, -}; - -/* - * MD PLLA Ratio - * 12 11 - *------------------------ - * 0 0 x42 - * 0 1 x48 - * 1 0 x56 - * 1 1 x64 - */ - -#define CPG_PLLA_MULT_INDEX(md) (((md) & (BIT(12)|BIT(11))) >> 11) - -static const unsigned int cpg_plla_mult[4] __initconst = { 42, 48, 56, 64 }; - -/* ----------------------------------------------------------------------------- - * Initialization - */ - -static u32 cpg_mode __initdata; - -static struct clk * __init -r8a7779_cpg_register_clock(struct device_node *np, struct r8a7779_cpg *cpg, - const struct cpg_clk_config *config, - unsigned int plla_mult, const char *name) -{ - const char *parent_name = "plla"; - unsigned int mult = 1; - unsigned int div = 1; - - if (!strcmp(name, "plla")) { - parent_name = of_clk_get_parent_name(np, 0); - mult = plla_mult; - } else if (!strcmp(name, "z")) { - div = config->z_div; - mult = config->z_mult; - } else if (!strcmp(name, "zs") || !strcmp(name, "s")) { - div = config->zs_and_s_div; - } else if (!strcmp(name, "s1")) { - div = config->s1_div; - } else if (!strcmp(name, "p")) { - div = config->p_div; - } else if (!strcmp(name, "b") || !strcmp(name, "out")) { - div = config->b_and_out_div; - } else { - return ERR_PTR(-EINVAL); - } - - return clk_register_fixed_factor(NULL, name, parent_name, 0, mult, div); -} - -static void __init r8a7779_cpg_clocks_init(struct device_node *np) -{ - const struct cpg_clk_config *config; - struct r8a7779_cpg *cpg; - struct clk **clks; - unsigned int i, plla_mult; - int num_clks; - - num_clks = of_property_count_strings(np, "clock-output-names"); - if (num_clks < 0) { - pr_err("%s: failed to count clocks\n", __func__); - return; - } - - cpg = kzalloc(sizeof(*cpg), GFP_KERNEL); - clks = kzalloc(CPG_NUM_CLOCKS * sizeof(*clks), GFP_KERNEL); - if (cpg == NULL || clks == NULL) { - /* We're leaking memory on purpose, there's no point in cleaning - * up as the system won't boot anyway. - */ - return; - } - - spin_lock_init(&cpg->lock); - - cpg->data.clks = clks; - cpg->data.clk_num = num_clks; - - config = &cpg_clk_configs[CPG_CLK_CONFIG_INDEX(cpg_mode)]; - plla_mult = cpg_plla_mult[CPG_PLLA_MULT_INDEX(cpg_mode)]; - - for (i = 0; i < num_clks; ++i) { - const char *name; - struct clk *clk; - - of_property_read_string_index(np, "clock-output-names", i, - &name); - - clk = r8a7779_cpg_register_clock(np, cpg, config, - plla_mult, name); - if (IS_ERR(clk)) - pr_err("%s: failed to register %s %s clock (%ld)\n", - __func__, np->name, name, PTR_ERR(clk)); - else - cpg->data.clks[i] = clk; - } - - of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data); - - cpg_mstp_add_clk_domain(np); -} -CLK_OF_DECLARE(r8a7779_cpg_clks, "renesas,r8a7779-cpg-clocks", - r8a7779_cpg_clocks_init); - -void __init r8a7779_clocks_init(u32 mode) -{ - cpg_mode = mode; - - of_clk_init(NULL); -} diff --git a/drivers/clk/shmobile/clk-rcar-gen2.c b/drivers/clk/shmobile/clk-rcar-gen2.c deleted file mode 100644 index 8419772..0000000 --- a/drivers/clk/shmobile/clk-rcar-gen2.c +++ /dev/null @@ -1,429 +0,0 @@ -/* - * rcar_gen2 Core CPG Clocks - * - * Copyright (C) 2013 Ideas On Board SPRL - * - * Contact: Laurent Pinchart - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct rcar_gen2_cpg { - struct clk_onecell_data data; - spinlock_t lock; - void __iomem *reg; -}; - -#define CPG_FRQCRB 0x00000004 -#define CPG_FRQCRB_KICK BIT(31) -#define CPG_SDCKCR 0x00000074 -#define CPG_PLL0CR 0x000000d8 -#define CPG_FRQCRC 0x000000e0 -#define CPG_FRQCRC_ZFC_MASK (0x1f << 8) -#define CPG_FRQCRC_ZFC_SHIFT 8 -#define CPG_ADSPCKCR 0x0000025c -#define CPG_RCANCKCR 0x00000270 - -/* ----------------------------------------------------------------------------- - * Z Clock - * - * Traits of this clock: - * prepare - clk_prepare only ensures that parents are prepared - * enable - clk_enable only ensures that parents are enabled - * rate - rate is adjustable. clk->rate = parent->rate * mult / 32 - * parent - fixed parent. No clk_set_parent support - */ - -struct cpg_z_clk { - struct clk_hw hw; - void __iomem *reg; - void __iomem *kick_reg; -}; - -#define to_z_clk(_hw) container_of(_hw, struct cpg_z_clk, hw) - -static unsigned long cpg_z_clk_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct cpg_z_clk *zclk = to_z_clk(hw); - unsigned int mult; - unsigned int val; - - val = (clk_readl(zclk->reg) & CPG_FRQCRC_ZFC_MASK) - >> CPG_FRQCRC_ZFC_SHIFT; - mult = 32 - val; - - return div_u64((u64)parent_rate * mult, 32); -} - -static long cpg_z_clk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) -{ - unsigned long prate = *parent_rate; - unsigned int mult; - - if (!prate) - prate = 1; - - mult = div_u64((u64)rate * 32, prate); - mult = clamp(mult, 1U, 32U); - - return *parent_rate / 32 * mult; -} - -static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct cpg_z_clk *zclk = to_z_clk(hw); - unsigned int mult; - u32 val, kick; - unsigned int i; - - mult = div_u64((u64)rate * 32, parent_rate); - mult = clamp(mult, 1U, 32U); - - if (clk_readl(zclk->kick_reg) & CPG_FRQCRB_KICK) - return -EBUSY; - - val = clk_readl(zclk->reg); - val &= ~CPG_FRQCRC_ZFC_MASK; - val |= (32 - mult) << CPG_FRQCRC_ZFC_SHIFT; - clk_writel(val, zclk->reg); - - /* - * Set KICK bit in FRQCRB to update hardware setting and wait for - * clock change completion. - */ - kick = clk_readl(zclk->kick_reg); - kick |= CPG_FRQCRB_KICK; - clk_writel(kick, zclk->kick_reg); - - /* - * Note: There is no HW information about the worst case latency. - * - * Using experimental measurements, it seems that no more than - * ~10 iterations are needed, independently of the CPU rate. - * Since this value might be dependent on external xtal rate, pll1 - * rate or even the other emulation clocks rate, use 1000 as a - * "super" safe value. - */ - for (i = 1000; i; i--) { - if (!(clk_readl(zclk->kick_reg) & CPG_FRQCRB_KICK)) - return 0; - - cpu_relax(); - } - - return -ETIMEDOUT; -} - -static const struct clk_ops cpg_z_clk_ops = { - .recalc_rate = cpg_z_clk_recalc_rate, - .round_rate = cpg_z_clk_round_rate, - .set_rate = cpg_z_clk_set_rate, -}; - -static struct clk * __init cpg_z_clk_register(struct rcar_gen2_cpg *cpg) -{ - static const char *parent_name = "pll0"; - struct clk_init_data init; - struct cpg_z_clk *zclk; - struct clk *clk; - - zclk = kzalloc(sizeof(*zclk), GFP_KERNEL); - if (!zclk) - return ERR_PTR(-ENOMEM); - - init.name = "z"; - init.ops = &cpg_z_clk_ops; - init.flags = 0; - init.parent_names = &parent_name; - init.num_parents = 1; - - zclk->reg = cpg->reg + CPG_FRQCRC; - zclk->kick_reg = cpg->reg + CPG_FRQCRB; - zclk->hw.init = &init; - - clk = clk_register(NULL, &zclk->hw); - if (IS_ERR(clk)) - kfree(zclk); - - return clk; -} - -static struct clk * __init cpg_rcan_clk_register(struct rcar_gen2_cpg *cpg, - struct device_node *np) -{ - const char *parent_name = of_clk_get_parent_name(np, 1); - struct clk_fixed_factor *fixed; - struct clk_gate *gate; - struct clk *clk; - - fixed = kzalloc(sizeof(*fixed), GFP_KERNEL); - if (!fixed) - return ERR_PTR(-ENOMEM); - - fixed->mult = 1; - fixed->div = 6; - - gate = kzalloc(sizeof(*gate), GFP_KERNEL); - if (!gate) { - kfree(fixed); - return ERR_PTR(-ENOMEM); - } - - gate->reg = cpg->reg + CPG_RCANCKCR; - gate->bit_idx = 8; - gate->flags = CLK_GATE_SET_TO_DISABLE; - gate->lock = &cpg->lock; - - clk = clk_register_composite(NULL, "rcan", &parent_name, 1, NULL, NULL, - &fixed->hw, &clk_fixed_factor_ops, - &gate->hw, &clk_gate_ops, 0); - if (IS_ERR(clk)) { - kfree(gate); - kfree(fixed); - } - - return clk; -} - -/* ADSP divisors */ -static const struct clk_div_table cpg_adsp_div_table[] = { - { 1, 3 }, { 2, 4 }, { 3, 6 }, { 4, 8 }, - { 5, 12 }, { 6, 16 }, { 7, 18 }, { 8, 24 }, - { 10, 36 }, { 11, 48 }, { 0, 0 }, -}; - -static struct clk * __init cpg_adsp_clk_register(struct rcar_gen2_cpg *cpg) -{ - const char *parent_name = "pll1"; - struct clk_divider *div; - struct clk_gate *gate; - struct clk *clk; - - div = kzalloc(sizeof(*div), GFP_KERNEL); - if (!div) - return ERR_PTR(-ENOMEM); - - div->reg = cpg->reg + CPG_ADSPCKCR; - div->width = 4; - div->table = cpg_adsp_div_table; - div->lock = &cpg->lock; - - gate = kzalloc(sizeof(*gate), GFP_KERNEL); - if (!gate) { - kfree(div); - return ERR_PTR(-ENOMEM); - } - - gate->reg = cpg->reg + CPG_ADSPCKCR; - gate->bit_idx = 8; - gate->flags = CLK_GATE_SET_TO_DISABLE; - gate->lock = &cpg->lock; - - clk = clk_register_composite(NULL, "adsp", &parent_name, 1, NULL, NULL, - &div->hw, &clk_divider_ops, - &gate->hw, &clk_gate_ops, 0); - if (IS_ERR(clk)) { - kfree(gate); - kfree(div); - } - - return clk; -} - -/* ----------------------------------------------------------------------------- - * CPG Clock Data - */ - -/* - * MD EXTAL PLL0 PLL1 PLL3 - * 14 13 19 (MHz) *1 *1 - *--------------------------------------------------- - * 0 0 0 15 x 1 x172/2 x208/2 x106 - * 0 0 1 15 x 1 x172/2 x208/2 x88 - * 0 1 0 20 x 1 x130/2 x156/2 x80 - * 0 1 1 20 x 1 x130/2 x156/2 x66 - * 1 0 0 26 / 2 x200/2 x240/2 x122 - * 1 0 1 26 / 2 x200/2 x240/2 x102 - * 1 1 0 30 / 2 x172/2 x208/2 x106 - * 1 1 1 30 / 2 x172/2 x208/2 x88 - * - * *1 : Table 7.6 indicates VCO output (PLLx = VCO/2) - */ -#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 12) | \ - (((md) & BIT(13)) >> 12) | \ - (((md) & BIT(19)) >> 19)) -struct cpg_pll_config { - unsigned int extal_div; - unsigned int pll1_mult; - unsigned int pll3_mult; -}; - -static const struct cpg_pll_config cpg_pll_configs[8] __initconst = { - { 1, 208, 106 }, { 1, 208, 88 }, { 1, 156, 80 }, { 1, 156, 66 }, - { 2, 240, 122 }, { 2, 240, 102 }, { 2, 208, 106 }, { 2, 208, 88 }, -}; - -/* SDHI divisors */ -static const struct clk_div_table cpg_sdh_div_table[] = { - { 0, 2 }, { 1, 3 }, { 2, 4 }, { 3, 6 }, - { 4, 8 }, { 5, 12 }, { 6, 16 }, { 7, 18 }, - { 8, 24 }, { 10, 36 }, { 11, 48 }, { 0, 0 }, -}; - -static const struct clk_div_table cpg_sd01_div_table[] = { - { 4, 8 }, - { 5, 12 }, { 6, 16 }, { 7, 18 }, { 8, 24 }, - { 10, 36 }, { 11, 48 }, { 12, 10 }, { 0, 0 }, -}; - -/* ----------------------------------------------------------------------------- - * Initialization - */ - -static u32 cpg_mode __initdata; - -static struct clk * __init -rcar_gen2_cpg_register_clock(struct device_node *np, struct rcar_gen2_cpg *cpg, - const struct cpg_pll_config *config, - const char *name) -{ - const struct clk_div_table *table = NULL; - const char *parent_name; - unsigned int shift; - unsigned int mult = 1; - unsigned int div = 1; - - if (!strcmp(name, "main")) { - parent_name = of_clk_get_parent_name(np, 0); - div = config->extal_div; - } else if (!strcmp(name, "pll0")) { - /* PLL0 is a configurable multiplier clock. Register it as a - * fixed factor clock for now as there's no generic multiplier - * clock implementation and we currently have no need to change - * the multiplier value. - */ - u32 value = clk_readl(cpg->reg + CPG_PLL0CR); - parent_name = "main"; - mult = ((value >> 24) & ((1 << 7) - 1)) + 1; - } else if (!strcmp(name, "pll1")) { - parent_name = "main"; - mult = config->pll1_mult / 2; - } else if (!strcmp(name, "pll3")) { - parent_name = "main"; - mult = config->pll3_mult; - } else if (!strcmp(name, "lb")) { - parent_name = "pll1"; - div = cpg_mode & BIT(18) ? 36 : 24; - } else if (!strcmp(name, "qspi")) { - parent_name = "pll1_div2"; - div = (cpg_mode & (BIT(3) | BIT(2) | BIT(1))) == BIT(2) - ? 8 : 10; - } else if (!strcmp(name, "sdh")) { - parent_name = "pll1"; - table = cpg_sdh_div_table; - shift = 8; - } else if (!strcmp(name, "sd0")) { - parent_name = "pll1"; - table = cpg_sd01_div_table; - shift = 4; - } else if (!strcmp(name, "sd1")) { - parent_name = "pll1"; - table = cpg_sd01_div_table; - shift = 0; - } else if (!strcmp(name, "z")) { - return cpg_z_clk_register(cpg); - } else if (!strcmp(name, "rcan")) { - return cpg_rcan_clk_register(cpg, np); - } else if (!strcmp(name, "adsp")) { - return cpg_adsp_clk_register(cpg); - } else { - return ERR_PTR(-EINVAL); - } - - if (!table) - return clk_register_fixed_factor(NULL, name, parent_name, 0, - mult, div); - else - return clk_register_divider_table(NULL, name, parent_name, 0, - cpg->reg + CPG_SDCKCR, shift, - 4, 0, table, &cpg->lock); -} - -static void __init rcar_gen2_cpg_clocks_init(struct device_node *np) -{ - const struct cpg_pll_config *config; - struct rcar_gen2_cpg *cpg; - struct clk **clks; - unsigned int i; - int num_clks; - - num_clks = of_property_count_strings(np, "clock-output-names"); - if (num_clks < 0) { - pr_err("%s: failed to count clocks\n", __func__); - return; - } - - cpg = kzalloc(sizeof(*cpg), GFP_KERNEL); - clks = kzalloc(num_clks * sizeof(*clks), GFP_KERNEL); - if (cpg == NULL || clks == NULL) { - /* We're leaking memory on purpose, there's no point in cleaning - * up as the system won't boot anyway. - */ - pr_err("%s: failed to allocate cpg\n", __func__); - return; - } - - spin_lock_init(&cpg->lock); - - cpg->data.clks = clks; - cpg->data.clk_num = num_clks; - - cpg->reg = of_iomap(np, 0); - if (WARN_ON(cpg->reg == NULL)) - return; - - config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)]; - - for (i = 0; i < num_clks; ++i) { - const char *name; - struct clk *clk; - - of_property_read_string_index(np, "clock-output-names", i, - &name); - - clk = rcar_gen2_cpg_register_clock(np, cpg, config, name); - if (IS_ERR(clk)) - pr_err("%s: failed to register %s %s clock (%ld)\n", - __func__, np->name, name, PTR_ERR(clk)); - else - cpg->data.clks[i] = clk; - } - - of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data); - - cpg_mstp_add_clk_domain(np); -} -CLK_OF_DECLARE(rcar_gen2_cpg_clks, "renesas,rcar-gen2-cpg-clocks", - rcar_gen2_cpg_clocks_init); - -void __init rcar_gen2_clocks_init(u32 mode) -{ - cpg_mode = mode; - - of_clk_init(NULL); -} diff --git a/drivers/clk/shmobile/clk-rz.c b/drivers/clk/shmobile/clk-rz.c deleted file mode 100644 index 9766e3c..0000000 --- a/drivers/clk/shmobile/clk-rz.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * rz Core CPG Clocks - * - * Copyright (C) 2013 Ideas On Board SPRL - * Copyright (C) 2014 Wolfram Sang, Sang Engineering - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - */ - -#include -#include -#include -#include -#include -#include -#include - -struct rz_cpg { - struct clk_onecell_data data; - void __iomem *reg; -}; - -#define CPG_FRQCR 0x10 -#define CPG_FRQCR2 0x14 - -/* ----------------------------------------------------------------------------- - * Initialization - */ - -static struct clk * __init -rz_cpg_register_clock(struct device_node *np, struct rz_cpg *cpg, const char *name) -{ - u32 val; - unsigned mult; - static const unsigned frqcr_tab[4] = { 3, 2, 0, 1 }; - - if (strcmp(name, "pll") == 0) { - /* FIXME: cpg_mode should be read from GPIO. But no GPIO support yet */ - unsigned cpg_mode = 0; /* hardcoded to EXTAL for now */ - const char *parent_name = of_clk_get_parent_name(np, cpg_mode); - - mult = cpg_mode ? (32 / 4) : 30; - - return clk_register_fixed_factor(NULL, name, parent_name, 0, mult, 1); - } - - /* If mapping regs failed, skip non-pll clocks. System will boot anyhow */ - if (!cpg->reg) - return ERR_PTR(-ENXIO); - - /* FIXME:"i" and "g" are variable clocks with non-integer dividers (e.g. 2/3) - * and the constraint that always g <= i. To get the rz platform started, - * let them run at fixed current speed and implement the details later. - */ - if (strcmp(name, "i") == 0) - val = (clk_readl(cpg->reg + CPG_FRQCR) >> 8) & 3; - else if (strcmp(name, "g") == 0) - val = clk_readl(cpg->reg + CPG_FRQCR2) & 3; - else - return ERR_PTR(-EINVAL); - - mult = frqcr_tab[val]; - return clk_register_fixed_factor(NULL, name, "pll", 0, mult, 3); -} - -static void __init rz_cpg_clocks_init(struct device_node *np) -{ - struct rz_cpg *cpg; - struct clk **clks; - unsigned i; - int num_clks; - - num_clks = of_property_count_strings(np, "clock-output-names"); - if (WARN(num_clks <= 0, "can't count CPG clocks\n")) - return; - - cpg = kzalloc(sizeof(*cpg), GFP_KERNEL); - clks = kzalloc(num_clks * sizeof(*clks), GFP_KERNEL); - BUG_ON(!cpg || !clks); - - cpg->data.clks = clks; - cpg->data.clk_num = num_clks; - - cpg->reg = of_iomap(np, 0); - - for (i = 0; i < num_clks; ++i) { - const char *name; - struct clk *clk; - - of_property_read_string_index(np, "clock-output-names", i, &name); - - clk = rz_cpg_register_clock(np, cpg, name); - if (IS_ERR(clk)) - pr_err("%s: failed to register %s %s clock (%ld)\n", - __func__, np->name, name, PTR_ERR(clk)); - else - cpg->data.clks[i] = clk; - } - - of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data); - - cpg_mstp_add_clk_domain(np); -} -CLK_OF_DECLARE(rz_cpg_clks, "renesas,rz-cpg-clocks", rz_cpg_clocks_init); diff --git a/drivers/clk/shmobile/clk-sh73a0.c b/drivers/clk/shmobile/clk-sh73a0.c deleted file mode 100644 index 8966f8b..0000000 --- a/drivers/clk/shmobile/clk-sh73a0.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - * sh73a0 Core CPG Clocks - * - * Copyright (C) 2014 Ulrich Hecht - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -struct sh73a0_cpg { - struct clk_onecell_data data; - spinlock_t lock; - void __iomem *reg; -}; - -#define CPG_FRQCRA 0x00 -#define CPG_FRQCRB 0x04 -#define CPG_SD0CKCR 0x74 -#define CPG_SD1CKCR 0x78 -#define CPG_SD2CKCR 0x7c -#define CPG_PLLECR 0xd0 -#define CPG_PLL0CR 0xd8 -#define CPG_PLL1CR 0x28 -#define CPG_PLL2CR 0x2c -#define CPG_PLL3CR 0xdc -#define CPG_CKSCR 0xc0 -#define CPG_DSI0PHYCR 0x6c -#define CPG_DSI1PHYCR 0x70 - -#define CLK_ENABLE_ON_INIT BIT(0) - -struct div4_clk { - const char *name; - const char *parent; - unsigned int reg; - unsigned int shift; -}; - -static struct div4_clk div4_clks[] = { - { "zg", "pll0", CPG_FRQCRA, 16 }, - { "m3", "pll1", CPG_FRQCRA, 12 }, - { "b", "pll1", CPG_FRQCRA, 8 }, - { "m1", "pll1", CPG_FRQCRA, 4 }, - { "m2", "pll1", CPG_FRQCRA, 0 }, - { "zx", "pll1", CPG_FRQCRB, 12 }, - { "hp", "pll1", CPG_FRQCRB, 4 }, - { NULL, NULL, 0, 0 }, -}; - -static const struct clk_div_table div4_div_table[] = { - { 0, 2 }, { 1, 3 }, { 2, 4 }, { 3, 6 }, { 4, 8 }, { 5, 12 }, - { 6, 16 }, { 7, 18 }, { 8, 24 }, { 10, 36 }, { 11, 48 }, - { 12, 7 }, { 0, 0 } -}; - -static const struct clk_div_table z_div_table[] = { - /* ZSEL == 0 */ - { 0, 1 }, { 1, 1 }, { 2, 1 }, { 3, 1 }, { 4, 1 }, { 5, 1 }, - { 6, 1 }, { 7, 1 }, { 8, 1 }, { 9, 1 }, { 10, 1 }, { 11, 1 }, - { 12, 1 }, { 13, 1 }, { 14, 1 }, { 15, 1 }, - /* ZSEL == 1 */ - { 16, 2 }, { 17, 3 }, { 18, 4 }, { 19, 6 }, { 20, 8 }, { 21, 12 }, - { 22, 16 }, { 24, 24 }, { 27, 48 }, { 0, 0 } -}; - -static struct clk * __init -sh73a0_cpg_register_clock(struct device_node *np, struct sh73a0_cpg *cpg, - const char *name) -{ - const struct clk_div_table *table = NULL; - unsigned int shift, reg, width; - const char *parent_name; - unsigned int mult = 1; - unsigned int div = 1; - - if (!strcmp(name, "main")) { - /* extal1, extal1_div2, extal2, extal2_div2 */ - u32 parent_idx = (clk_readl(cpg->reg + CPG_CKSCR) >> 28) & 3; - - parent_name = of_clk_get_parent_name(np, parent_idx >> 1); - div = (parent_idx & 1) + 1; - } else if (!strncmp(name, "pll", 3)) { - void __iomem *enable_reg = cpg->reg; - u32 enable_bit = name[3] - '0'; - - parent_name = "main"; - switch (enable_bit) { - case 0: - enable_reg += CPG_PLL0CR; - break; - case 1: - enable_reg += CPG_PLL1CR; - break; - case 2: - enable_reg += CPG_PLL2CR; - break; - case 3: - enable_reg += CPG_PLL3CR; - break; - default: - return ERR_PTR(-EINVAL); - } - if (clk_readl(cpg->reg + CPG_PLLECR) & BIT(enable_bit)) { - mult = ((clk_readl(enable_reg) >> 24) & 0x3f) + 1; - /* handle CFG bit for PLL1 and PLL2 */ - if (enable_bit == 1 || enable_bit == 2) - if (clk_readl(enable_reg) & BIT(20)) - mult *= 2; - } - } else if (!strcmp(name, "dsi0phy") || !strcmp(name, "dsi1phy")) { - u32 phy_no = name[3] - '0'; - void __iomem *dsi_reg = cpg->reg + - (phy_no ? CPG_DSI1PHYCR : CPG_DSI0PHYCR); - - parent_name = phy_no ? "dsi1pck" : "dsi0pck"; - mult = __raw_readl(dsi_reg); - if (!(mult & 0x8000)) - mult = 1; - else - mult = (mult & 0x3f) + 1; - } else if (!strcmp(name, "z")) { - parent_name = "pll0"; - table = z_div_table; - reg = CPG_FRQCRB; - shift = 24; - width = 5; - } else { - struct div4_clk *c; - - for (c = div4_clks; c->name; c++) { - if (!strcmp(name, c->name)) { - parent_name = c->parent; - table = div4_div_table; - reg = c->reg; - shift = c->shift; - width = 4; - break; - } - } - if (!c->name) - return ERR_PTR(-EINVAL); - } - - if (!table) { - return clk_register_fixed_factor(NULL, name, parent_name, 0, - mult, div); - } else { - return clk_register_divider_table(NULL, name, parent_name, 0, - cpg->reg + reg, shift, width, 0, - table, &cpg->lock); - } -} - -static void __init sh73a0_cpg_clocks_init(struct device_node *np) -{ - struct sh73a0_cpg *cpg; - struct clk **clks; - unsigned int i; - int num_clks; - - num_clks = of_property_count_strings(np, "clock-output-names"); - if (num_clks < 0) { - pr_err("%s: failed to count clocks\n", __func__); - return; - } - - cpg = kzalloc(sizeof(*cpg), GFP_KERNEL); - clks = kcalloc(num_clks, sizeof(*clks), GFP_KERNEL); - if (cpg == NULL || clks == NULL) { - /* We're leaking memory on purpose, there's no point in cleaning - * up as the system won't boot anyway. - */ - return; - } - - spin_lock_init(&cpg->lock); - - cpg->data.clks = clks; - cpg->data.clk_num = num_clks; - - cpg->reg = of_iomap(np, 0); - if (WARN_ON(cpg->reg == NULL)) - return; - - /* Set SDHI clocks to a known state */ - clk_writel(0x108, cpg->reg + CPG_SD0CKCR); - clk_writel(0x108, cpg->reg + CPG_SD1CKCR); - clk_writel(0x108, cpg->reg + CPG_SD2CKCR); - - for (i = 0; i < num_clks; ++i) { - const char *name; - struct clk *clk; - - of_property_read_string_index(np, "clock-output-names", i, - &name); - - clk = sh73a0_cpg_register_clock(np, cpg, name); - if (IS_ERR(clk)) - pr_err("%s: failed to register %s %s clock (%ld)\n", - __func__, np->name, name, PTR_ERR(clk)); - else - cpg->data.clks[i] = clk; - } - - of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data); -} -CLK_OF_DECLARE(sh73a0_cpg_clks, "renesas,sh73a0-cpg-clocks", - sh73a0_cpg_clocks_init); diff --git a/drivers/clk/shmobile/r8a7795-cpg-mssr.c b/drivers/clk/shmobile/r8a7795-cpg-mssr.c deleted file mode 100644 index b2198aef..0000000 --- a/drivers/clk/shmobile/r8a7795-cpg-mssr.c +++ /dev/null @@ -1,638 +0,0 @@ -/* - * r8a7795 Clock Pulse Generator / Module Standby and Software Reset - * - * Copyright (C) 2015 Glider bvba - * - * Based on clk-rcar-gen3.c - * - * Copyright (C) 2015 Renesas Electronics Corp. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "renesas-cpg-mssr.h" - - -enum clk_ids { - /* Core Clock Outputs exported to DT */ - LAST_DT_CORE_CLK = R8A7795_CLK_OSC, - - /* External Input Clocks */ - CLK_EXTAL, - CLK_EXTALR, - - /* Internal Core Clocks */ - CLK_MAIN, - CLK_PLL0, - CLK_PLL1, - CLK_PLL2, - CLK_PLL3, - CLK_PLL4, - CLK_PLL1_DIV2, - CLK_PLL1_DIV4, - CLK_S0, - CLK_S1, - CLK_S2, - CLK_S3, - CLK_SDSRC, - CLK_SSPSRC, - - /* Module Clocks */ - MOD_CLK_BASE -}; - -enum r8a7795_clk_types { - CLK_TYPE_GEN3_MAIN = CLK_TYPE_CUSTOM, - CLK_TYPE_GEN3_PLL0, - CLK_TYPE_GEN3_PLL1, - CLK_TYPE_GEN3_PLL2, - CLK_TYPE_GEN3_PLL3, - CLK_TYPE_GEN3_PLL4, - CLK_TYPE_GEN3_SD, -}; - -static const struct cpg_core_clk r8a7795_core_clks[] __initconst = { - /* External Clock Inputs */ - DEF_INPUT("extal", CLK_EXTAL), - DEF_INPUT("extalr", CLK_EXTALR), - - /* Internal Core Clocks */ - DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN3_MAIN, CLK_EXTAL), - DEF_BASE(".pll0", CLK_PLL0, CLK_TYPE_GEN3_PLL0, CLK_MAIN), - DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN3_PLL1, CLK_MAIN), - DEF_BASE(".pll2", CLK_PLL2, CLK_TYPE_GEN3_PLL2, CLK_MAIN), - DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN3_PLL3, CLK_MAIN), - DEF_BASE(".pll4", CLK_PLL4, CLK_TYPE_GEN3_PLL4, CLK_MAIN), - - DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1), - DEF_FIXED(".pll1_div4", CLK_PLL1_DIV4, CLK_PLL1_DIV2, 2, 1), - DEF_FIXED(".s0", CLK_S0, CLK_PLL1_DIV2, 2, 1), - DEF_FIXED(".s1", CLK_S1, CLK_PLL1_DIV2, 3, 1), - DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1), - DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1), - - /* Core Clock Outputs */ - DEF_FIXED("ztr", R8A7795_CLK_ZTR, CLK_PLL1_DIV2, 6, 1), - DEF_FIXED("ztrd2", R8A7795_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1), - DEF_FIXED("zt", R8A7795_CLK_ZT, CLK_PLL1_DIV2, 4, 1), - DEF_FIXED("zx", R8A7795_CLK_ZX, CLK_PLL1_DIV2, 2, 1), - DEF_FIXED("s0d1", R8A7795_CLK_S0D1, CLK_S0, 1, 1), - DEF_FIXED("s0d4", R8A7795_CLK_S0D4, CLK_S0, 4, 1), - DEF_FIXED("s1d1", R8A7795_CLK_S1D1, CLK_S1, 1, 1), - DEF_FIXED("s1d2", R8A7795_CLK_S1D2, CLK_S1, 2, 1), - DEF_FIXED("s1d4", R8A7795_CLK_S1D4, CLK_S1, 4, 1), - DEF_FIXED("s2d1", R8A7795_CLK_S2D1, CLK_S2, 1, 1), - DEF_FIXED("s2d2", R8A7795_CLK_S2D2, CLK_S2, 2, 1), - DEF_FIXED("s2d4", R8A7795_CLK_S2D4, CLK_S2, 4, 1), - DEF_FIXED("s3d1", R8A7795_CLK_S3D1, CLK_S3, 1, 1), - DEF_FIXED("s3d2", R8A7795_CLK_S3D2, CLK_S3, 2, 1), - DEF_FIXED("s3d4", R8A7795_CLK_S3D4, CLK_S3, 4, 1), - - DEF_SD("sd0", R8A7795_CLK_SD0, CLK_PLL1_DIV2, 0x0074), - DEF_SD("sd1", R8A7795_CLK_SD1, CLK_PLL1_DIV2, 0x0078), - DEF_SD("sd2", R8A7795_CLK_SD2, CLK_PLL1_DIV2, 0x0268), - DEF_SD("sd3", R8A7795_CLK_SD3, CLK_PLL1_DIV2, 0x026c), - - DEF_FIXED("cl", R8A7795_CLK_CL, CLK_PLL1_DIV2, 48, 1), - DEF_FIXED("cp", R8A7795_CLK_CP, CLK_EXTAL, 2, 1), - - DEF_DIV6P1("mso", R8A7795_CLK_MSO, CLK_PLL1_DIV4, 0x014), - DEF_DIV6P1("hdmi", R8A7795_CLK_HDMI, CLK_PLL1_DIV2, 0x250), - DEF_DIV6P1("canfd", R8A7795_CLK_CANFD, CLK_PLL1_DIV4, 0x244), -}; - -static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = { - DEF_MOD("scif5", 202, R8A7795_CLK_S3D4), - DEF_MOD("scif4", 203, R8A7795_CLK_S3D4), - DEF_MOD("scif3", 204, R8A7795_CLK_S3D4), - DEF_MOD("scif1", 206, R8A7795_CLK_S3D4), - DEF_MOD("scif0", 207, R8A7795_CLK_S3D4), - DEF_MOD("msiof3", 208, R8A7795_CLK_MSO), - DEF_MOD("msiof2", 209, R8A7795_CLK_MSO), - DEF_MOD("msiof1", 210, R8A7795_CLK_MSO), - DEF_MOD("msiof0", 211, R8A7795_CLK_MSO), - DEF_MOD("sys-dmac2", 217, R8A7795_CLK_S3D1), - DEF_MOD("sys-dmac1", 218, R8A7795_CLK_S3D1), - DEF_MOD("sys-dmac0", 219, R8A7795_CLK_S3D1), - DEF_MOD("scif2", 310, R8A7795_CLK_S3D4), - DEF_MOD("sdif3", 311, R8A7795_CLK_SD3), - DEF_MOD("sdif2", 312, R8A7795_CLK_SD2), - DEF_MOD("sdif1", 313, R8A7795_CLK_SD1), - DEF_MOD("sdif0", 314, R8A7795_CLK_SD0), - DEF_MOD("pcie1", 318, R8A7795_CLK_S3D1), - DEF_MOD("pcie0", 319, R8A7795_CLK_S3D1), - DEF_MOD("usb3-if1", 327, R8A7795_CLK_S3D1), - DEF_MOD("usb3-if0", 328, R8A7795_CLK_S3D1), - DEF_MOD("usb-dmac0", 330, R8A7795_CLK_S3D1), - DEF_MOD("usb-dmac1", 331, R8A7795_CLK_S3D1), - DEF_MOD("intc-ex", 407, R8A7795_CLK_CP), - DEF_MOD("intc-ap", 408, R8A7795_CLK_S3D1), - DEF_MOD("audmac0", 502, R8A7795_CLK_S3D4), - DEF_MOD("audmac1", 501, R8A7795_CLK_S3D4), - DEF_MOD("hscif4", 516, R8A7795_CLK_S3D1), - DEF_MOD("hscif3", 517, R8A7795_CLK_S3D1), - DEF_MOD("hscif2", 518, R8A7795_CLK_S3D1), - DEF_MOD("hscif1", 519, R8A7795_CLK_S3D1), - DEF_MOD("hscif0", 520, R8A7795_CLK_S3D1), - DEF_MOD("fcpvd3", 600, R8A7795_CLK_S2D1), - DEF_MOD("fcpvd2", 601, R8A7795_CLK_S2D1), - DEF_MOD("fcpvd1", 602, R8A7795_CLK_S2D1), - DEF_MOD("fcpvd0", 603, R8A7795_CLK_S2D1), - DEF_MOD("fcpvb1", 606, R8A7795_CLK_S2D1), - DEF_MOD("fcpvb0", 607, R8A7795_CLK_S2D1), - DEF_MOD("fcpvi2", 609, R8A7795_CLK_S2D1), - DEF_MOD("fcpvi1", 610, R8A7795_CLK_S2D1), - DEF_MOD("fcpvi0", 611, R8A7795_CLK_S2D1), - DEF_MOD("fcpf2", 613, R8A7795_CLK_S2D1), - DEF_MOD("fcpf1", 614, R8A7795_CLK_S2D1), - DEF_MOD("fcpf0", 615, R8A7795_CLK_S2D1), - DEF_MOD("fcpci1", 616, R8A7795_CLK_S2D1), - DEF_MOD("fcpci0", 617, R8A7795_CLK_S2D1), - DEF_MOD("fcpcs", 619, R8A7795_CLK_S2D1), - DEF_MOD("vspd3", 620, R8A7795_CLK_S2D1), - DEF_MOD("vspd2", 621, R8A7795_CLK_S2D1), - DEF_MOD("vspd1", 622, R8A7795_CLK_S2D1), - DEF_MOD("vspd0", 623, R8A7795_CLK_S2D1), - DEF_MOD("vspbc", 624, R8A7795_CLK_S2D1), - DEF_MOD("vspbd", 626, R8A7795_CLK_S2D1), - DEF_MOD("vspi2", 629, R8A7795_CLK_S2D1), - DEF_MOD("vspi1", 630, R8A7795_CLK_S2D1), - DEF_MOD("vspi0", 631, R8A7795_CLK_S2D1), - DEF_MOD("ehci2", 701, R8A7795_CLK_S3D4), - DEF_MOD("ehci1", 702, R8A7795_CLK_S3D4), - DEF_MOD("ehci0", 703, R8A7795_CLK_S3D4), - DEF_MOD("hsusb", 704, R8A7795_CLK_S3D4), - DEF_MOD("du3", 721, R8A7795_CLK_S2D1), - DEF_MOD("du2", 722, R8A7795_CLK_S2D1), - DEF_MOD("du1", 723, R8A7795_CLK_S2D1), - DEF_MOD("du0", 724, R8A7795_CLK_S2D1), - DEF_MOD("lvds", 727, R8A7795_CLK_S2D1), - DEF_MOD("hdmi1", 728, R8A7795_CLK_HDMI), - DEF_MOD("hdmi0", 729, R8A7795_CLK_HDMI), - DEF_MOD("etheravb", 812, R8A7795_CLK_S3D2), - DEF_MOD("sata0", 815, R8A7795_CLK_S3D2), - DEF_MOD("gpio7", 905, R8A7795_CLK_CP), - DEF_MOD("gpio6", 906, R8A7795_CLK_CP), - DEF_MOD("gpio5", 907, R8A7795_CLK_CP), - DEF_MOD("gpio4", 908, R8A7795_CLK_CP), - DEF_MOD("gpio3", 909, R8A7795_CLK_CP), - DEF_MOD("gpio2", 910, R8A7795_CLK_CP), - DEF_MOD("gpio1", 911, R8A7795_CLK_CP), - DEF_MOD("gpio0", 912, R8A7795_CLK_CP), - DEF_MOD("can-fd", 914, R8A7795_CLK_S3D2), - DEF_MOD("can-if1", 915, R8A7795_CLK_S3D4), - DEF_MOD("can-if0", 916, R8A7795_CLK_S3D4), - DEF_MOD("i2c6", 918, R8A7795_CLK_S3D2), - DEF_MOD("i2c5", 919, R8A7795_CLK_S3D2), - DEF_MOD("i2c4", 927, R8A7795_CLK_S3D2), - DEF_MOD("i2c3", 928, R8A7795_CLK_S3D2), - DEF_MOD("i2c2", 929, R8A7795_CLK_S3D2), - DEF_MOD("i2c1", 930, R8A7795_CLK_S3D2), - DEF_MOD("i2c0", 931, R8A7795_CLK_S3D2), - DEF_MOD("ssi-all", 1005, R8A7795_CLK_S3D4), - DEF_MOD("ssi9", 1006, MOD_CLK_ID(1005)), - DEF_MOD("ssi8", 1007, MOD_CLK_ID(1005)), - DEF_MOD("ssi7", 1008, MOD_CLK_ID(1005)), - DEF_MOD("ssi6", 1009, MOD_CLK_ID(1005)), - DEF_MOD("ssi5", 1010, MOD_CLK_ID(1005)), - DEF_MOD("ssi4", 1011, MOD_CLK_ID(1005)), - DEF_MOD("ssi3", 1012, MOD_CLK_ID(1005)), - DEF_MOD("ssi2", 1013, MOD_CLK_ID(1005)), - DEF_MOD("ssi1", 1014, MOD_CLK_ID(1005)), - DEF_MOD("ssi0", 1015, MOD_CLK_ID(1005)), - DEF_MOD("scu-all", 1017, R8A7795_CLK_S3D4), - DEF_MOD("scu-dvc1", 1018, MOD_CLK_ID(1017)), - DEF_MOD("scu-dvc0", 1019, MOD_CLK_ID(1017)), - DEF_MOD("scu-ctu1-mix1", 1020, MOD_CLK_ID(1017)), - DEF_MOD("scu-ctu0-mix0", 1021, MOD_CLK_ID(1017)), - DEF_MOD("scu-src9", 1022, MOD_CLK_ID(1017)), - DEF_MOD("scu-src8", 1023, MOD_CLK_ID(1017)), - DEF_MOD("scu-src7", 1024, MOD_CLK_ID(1017)), - DEF_MOD("scu-src6", 1025, MOD_CLK_ID(1017)), - DEF_MOD("scu-src5", 1026, MOD_CLK_ID(1017)), - DEF_MOD("scu-src4", 1027, MOD_CLK_ID(1017)), - DEF_MOD("scu-src3", 1028, MOD_CLK_ID(1017)), - DEF_MOD("scu-src2", 1029, MOD_CLK_ID(1017)), - DEF_MOD("scu-src1", 1030, MOD_CLK_ID(1017)), - DEF_MOD("scu-src0", 1031, MOD_CLK_ID(1017)), -}; - -static const unsigned int r8a7795_crit_mod_clks[] __initconst = { - MOD_CLK_ID(408), /* INTC-AP (GIC) */ -}; - -/* ----------------------------------------------------------------------------- - * SDn Clock - * - */ -#define CPG_SD_STP_HCK BIT(9) -#define CPG_SD_STP_CK BIT(8) - -#define CPG_SD_STP_MASK (CPG_SD_STP_HCK | CPG_SD_STP_CK) -#define CPG_SD_FC_MASK (0x7 << 2 | 0x3 << 0) - -#define CPG_SD_DIV_TABLE_DATA(stp_hck, stp_ck, sd_srcfc, sd_fc, sd_div) \ -{ \ - .val = ((stp_hck) ? CPG_SD_STP_HCK : 0) | \ - ((stp_ck) ? CPG_SD_STP_CK : 0) | \ - ((sd_srcfc) << 2) | \ - ((sd_fc) << 0), \ - .div = (sd_div), \ -} - -struct sd_div_table { - u32 val; - unsigned int div; -}; - -struct sd_clock { - struct clk_hw hw; - void __iomem *reg; - const struct sd_div_table *div_table; - unsigned int div_num; - unsigned int div_min; - unsigned int div_max; -}; - -/* SDn divider - * sd_srcfc sd_fc div - * stp_hck stp_ck (div) (div) = sd_srcfc x sd_fc - *------------------------------------------------------------------- - * 0 0 0 (1) 1 (4) 4 - * 0 0 1 (2) 1 (4) 8 - * 1 0 2 (4) 1 (4) 16 - * 1 0 3 (8) 1 (4) 32 - * 1 0 4 (16) 1 (4) 64 - * 0 0 0 (1) 0 (2) 2 - * 0 0 1 (2) 0 (2) 4 - * 1 0 2 (4) 0 (2) 8 - * 1 0 3 (8) 0 (2) 16 - * 1 0 4 (16) 0 (2) 32 - */ -static const struct sd_div_table cpg_sd_div_table[] = { -/* CPG_SD_DIV_TABLE_DATA(stp_hck, stp_ck, sd_srcfc, sd_fc, sd_div) */ - CPG_SD_DIV_TABLE_DATA(0, 0, 0, 1, 4), - CPG_SD_DIV_TABLE_DATA(0, 0, 1, 1, 8), - CPG_SD_DIV_TABLE_DATA(1, 0, 2, 1, 16), - CPG_SD_DIV_TABLE_DATA(1, 0, 3, 1, 32), - CPG_SD_DIV_TABLE_DATA(1, 0, 4, 1, 64), - CPG_SD_DIV_TABLE_DATA(0, 0, 0, 0, 2), - CPG_SD_DIV_TABLE_DATA(0, 0, 1, 0, 4), - CPG_SD_DIV_TABLE_DATA(1, 0, 2, 0, 8), - CPG_SD_DIV_TABLE_DATA(1, 0, 3, 0, 16), - CPG_SD_DIV_TABLE_DATA(1, 0, 4, 0, 32), -}; - -#define to_sd_clock(_hw) container_of(_hw, struct sd_clock, hw) - -static int cpg_sd_clock_enable(struct clk_hw *hw) -{ - struct sd_clock *clock = to_sd_clock(hw); - u32 val, sd_fc; - unsigned int i; - - val = clk_readl(clock->reg); - - sd_fc = val & CPG_SD_FC_MASK; - for (i = 0; i < clock->div_num; i++) - if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK)) - break; - - if (i >= clock->div_num) - return -EINVAL; - - val &= ~(CPG_SD_STP_MASK); - val |= clock->div_table[i].val & CPG_SD_STP_MASK; - - clk_writel(val, clock->reg); - - return 0; -} - -static void cpg_sd_clock_disable(struct clk_hw *hw) -{ - struct sd_clock *clock = to_sd_clock(hw); - - clk_writel(clk_readl(clock->reg) | CPG_SD_STP_MASK, clock->reg); -} - -static int cpg_sd_clock_is_enabled(struct clk_hw *hw) -{ - struct sd_clock *clock = to_sd_clock(hw); - - return !(clk_readl(clock->reg) & CPG_SD_STP_MASK); -} - -static unsigned long cpg_sd_clock_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct sd_clock *clock = to_sd_clock(hw); - unsigned long rate = parent_rate; - u32 val, sd_fc; - unsigned int i; - - val = clk_readl(clock->reg); - - sd_fc = val & CPG_SD_FC_MASK; - for (i = 0; i < clock->div_num; i++) - if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK)) - break; - - if (i >= clock->div_num) - return -EINVAL; - - return DIV_ROUND_CLOSEST(rate, clock->div_table[i].div); -} - -static unsigned int cpg_sd_clock_calc_div(struct sd_clock *clock, - unsigned long rate, - unsigned long parent_rate) -{ - unsigned int div; - - if (!rate) - rate = 1; - - div = DIV_ROUND_CLOSEST(parent_rate, rate); - - return clamp_t(unsigned int, div, clock->div_min, clock->div_max); -} - -static long cpg_sd_clock_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) -{ - struct sd_clock *clock = to_sd_clock(hw); - unsigned int div = cpg_sd_clock_calc_div(clock, rate, *parent_rate); - - return DIV_ROUND_CLOSEST(*parent_rate, div); -} - -static int cpg_sd_clock_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct sd_clock *clock = to_sd_clock(hw); - unsigned int div = cpg_sd_clock_calc_div(clock, rate, parent_rate); - u32 val; - unsigned int i; - - for (i = 0; i < clock->div_num; i++) - if (div == clock->div_table[i].div) - break; - - if (i >= clock->div_num) - return -EINVAL; - - val = clk_readl(clock->reg); - val &= ~(CPG_SD_STP_MASK | CPG_SD_FC_MASK); - val |= clock->div_table[i].val & (CPG_SD_STP_MASK | CPG_SD_FC_MASK); - clk_writel(val, clock->reg); - - return 0; -} - -static const struct clk_ops cpg_sd_clock_ops = { - .enable = cpg_sd_clock_enable, - .disable = cpg_sd_clock_disable, - .is_enabled = cpg_sd_clock_is_enabled, - .recalc_rate = cpg_sd_clock_recalc_rate, - .round_rate = cpg_sd_clock_round_rate, - .set_rate = cpg_sd_clock_set_rate, -}; - -static struct clk * __init cpg_sd_clk_register(const struct cpg_core_clk *core, - void __iomem *base, - const char *parent_name) -{ - struct clk_init_data init; - struct sd_clock *clock; - struct clk *clk; - unsigned int i; - - clock = kzalloc(sizeof(*clock), GFP_KERNEL); - if (!clock) - return ERR_PTR(-ENOMEM); - - init.name = core->name; - init.ops = &cpg_sd_clock_ops; - init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; - init.parent_names = &parent_name; - init.num_parents = 1; - - clock->reg = base + core->offset; - clock->hw.init = &init; - clock->div_table = cpg_sd_div_table; - clock->div_num = ARRAY_SIZE(cpg_sd_div_table); - - clock->div_max = clock->div_table[0].div; - clock->div_min = clock->div_max; - for (i = 1; i < clock->div_num; i++) { - clock->div_max = max(clock->div_max, clock->div_table[i].div); - clock->div_min = min(clock->div_min, clock->div_table[i].div); - } - - clk = clk_register(NULL, &clock->hw); - if (IS_ERR(clk)) - kfree(clock); - - return clk; -} - -#define CPG_PLL0CR 0x00d8 -#define CPG_PLL2CR 0x002c -#define CPG_PLL4CR 0x01f4 - -/* - * CPG Clock Data - */ - -/* - * MD EXTAL PLL0 PLL1 PLL2 PLL3 PLL4 - * 14 13 19 17 (MHz) - *------------------------------------------------------------------- - * 0 0 0 0 16.66 x 1 x180 x192 x144 x192 x144 - * 0 0 0 1 16.66 x 1 x180 x192 x144 x128 x144 - * 0 0 1 0 Prohibited setting - * 0 0 1 1 16.66 x 1 x180 x192 x144 x192 x144 - * 0 1 0 0 20 x 1 x150 x160 x120 x160 x120 - * 0 1 0 1 20 x 1 x150 x160 x120 x106 x120 - * 0 1 1 0 Prohibited setting - * 0 1 1 1 20 x 1 x150 x160 x120 x160 x120 - * 1 0 0 0 25 x 1 x120 x128 x96 x128 x96 - * 1 0 0 1 25 x 1 x120 x128 x96 x84 x96 - * 1 0 1 0 Prohibited setting - * 1 0 1 1 25 x 1 x120 x128 x96 x128 x96 - * 1 1 0 0 33.33 / 2 x180 x192 x144 x192 x144 - * 1 1 0 1 33.33 / 2 x180 x192 x144 x128 x144 - * 1 1 1 0 Prohibited setting - * 1 1 1 1 33.33 / 2 x180 x192 x144 x192 x144 - */ -#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 11) | \ - (((md) & BIT(13)) >> 11) | \ - (((md) & BIT(19)) >> 18) | \ - (((md) & BIT(17)) >> 17)) - -struct cpg_pll_config { - unsigned int extal_div; - unsigned int pll1_mult; - unsigned int pll3_mult; -}; - -static const struct cpg_pll_config cpg_pll_configs[16] __initconst = { - /* EXTAL div PLL1 mult PLL3 mult */ - { 1, 192, 192, }, - { 1, 192, 128, }, - { 0, /* Prohibited setting */ }, - { 1, 192, 192, }, - { 1, 160, 160, }, - { 1, 160, 106, }, - { 0, /* Prohibited setting */ }, - { 1, 160, 160, }, - { 1, 128, 128, }, - { 1, 128, 84, }, - { 0, /* Prohibited setting */ }, - { 1, 128, 128, }, - { 2, 192, 192, }, - { 2, 192, 128, }, - { 0, /* Prohibited setting */ }, - { 2, 192, 192, }, -}; - -static const struct cpg_pll_config *cpg_pll_config __initdata; - -static -struct clk * __init r8a7795_cpg_clk_register(struct device *dev, - const struct cpg_core_clk *core, - const struct cpg_mssr_info *info, - struct clk **clks, - void __iomem *base) -{ - const struct clk *parent; - unsigned int mult = 1; - unsigned int div = 1; - u32 value; - - parent = clks[core->parent]; - if (IS_ERR(parent)) - return ERR_CAST(parent); - - switch (core->type) { - case CLK_TYPE_GEN3_MAIN: - div = cpg_pll_config->extal_div; - break; - - case CLK_TYPE_GEN3_PLL0: - /* - * PLL0 is a configurable multiplier clock. Register it as a - * fixed factor clock for now as there's no generic multiplier - * clock implementation and we currently have no need to change - * the multiplier value. - */ - value = readl(base + CPG_PLL0CR); - mult = (((value >> 24) & 0x7f) + 1) * 2; - break; - - case CLK_TYPE_GEN3_PLL1: - mult = cpg_pll_config->pll1_mult; - break; - - case CLK_TYPE_GEN3_PLL2: - /* - * PLL2 is a configurable multiplier clock. Register it as a - * fixed factor clock for now as there's no generic multiplier - * clock implementation and we currently have no need to change - * the multiplier value. - */ - value = readl(base + CPG_PLL2CR); - mult = (((value >> 24) & 0x7f) + 1) * 2; - break; - - case CLK_TYPE_GEN3_PLL3: - mult = cpg_pll_config->pll3_mult; - break; - - case CLK_TYPE_GEN3_PLL4: - /* - * PLL4 is a configurable multiplier clock. Register it as a - * fixed factor clock for now as there's no generic multiplier - * clock implementation and we currently have no need to change - * the multiplier value. - */ - value = readl(base + CPG_PLL4CR); - mult = (((value >> 24) & 0x7f) + 1) * 2; - break; - - case CLK_TYPE_GEN3_SD: - return cpg_sd_clk_register(core, base, __clk_get_name(parent)); - - default: - return ERR_PTR(-EINVAL); - } - - return clk_register_fixed_factor(NULL, core->name, - __clk_get_name(parent), 0, mult, div); -} - -/* - * Reset register definitions. - */ -#define MODEMR 0xe6160060 - -static u32 rcar_gen3_read_mode_pins(void) -{ - void __iomem *modemr = ioremap_nocache(MODEMR, 4); - u32 mode; - - BUG_ON(!modemr); - mode = ioread32(modemr); - iounmap(modemr); - - return mode; -} - -static int __init r8a7795_cpg_mssr_init(struct device *dev) -{ - u32 cpg_mode = rcar_gen3_read_mode_pins(); - - cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)]; - if (!cpg_pll_config->extal_div) { - dev_err(dev, "Prohibited setting (cpg_mode=0x%x)\n", cpg_mode); - return -EINVAL; - } - - return 0; -} - -const struct cpg_mssr_info r8a7795_cpg_mssr_info __initconst = { - /* Core Clocks */ - .core_clks = r8a7795_core_clks, - .num_core_clks = ARRAY_SIZE(r8a7795_core_clks), - .last_dt_core_clk = LAST_DT_CORE_CLK, - .num_total_core_clks = MOD_CLK_BASE, - - /* Module Clocks */ - .mod_clks = r8a7795_mod_clks, - .num_mod_clks = ARRAY_SIZE(r8a7795_mod_clks), - .num_hw_mod_clks = 12 * 32, - - /* Critical Module Clocks */ - .crit_mod_clks = r8a7795_crit_mod_clks, - .num_crit_mod_clks = ARRAY_SIZE(r8a7795_crit_mod_clks), - - /* Callbacks */ - .init = r8a7795_cpg_mssr_init, - .cpg_clk_register = r8a7795_cpg_clk_register, -}; diff --git a/drivers/clk/shmobile/renesas-cpg-mssr.c b/drivers/clk/shmobile/renesas-cpg-mssr.c deleted file mode 100644 index 58e24b3..0000000 --- a/drivers/clk/shmobile/renesas-cpg-mssr.c +++ /dev/null @@ -1,601 +0,0 @@ -/* - * Renesas Clock Pulse Generator / Module Standby and Software Reset - * - * Copyright (C) 2015 Glider bvba - * - * Based on clk-mstp.c, clk-rcar-gen2.c, and clk-rcar-gen3.c - * - * Copyright (C) 2013 Ideas On Board SPRL - * Copyright (C) 2015 Renesas Electronics Corp. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "renesas-cpg-mssr.h" -#include "clk-div6.h" - -#ifdef DEBUG -#define WARN_DEBUG(x) do { } while (0) -#else -#define WARN_DEBUG(x) WARN_ON(x) -#endif - - -/* - * Module Standby and Software Reset register offets. - * - * If the registers exist, these are valid for SH-Mobile, R-Mobile, - * R-Car Gen 2, and R-Car Gen 3. - * These are NOT valid for R-Car Gen1 and RZ/A1! - */ - -/* - * Module Stop Status Register offsets - */ - -static const u16 mstpsr[] = { - 0x030, 0x038, 0x040, 0x048, 0x04C, 0x03C, 0x1C0, 0x1C4, - 0x9A0, 0x9A4, 0x9A8, 0x9AC, -}; - -#define MSTPSR(i) mstpsr[i] - - -/* - * System Module Stop Control Register offsets - */ - -static const u16 smstpcr[] = { - 0x130, 0x134, 0x138, 0x13C, 0x140, 0x144, 0x148, 0x14C, - 0x990, 0x994, 0x998, 0x99C, -}; - -#define SMSTPCR(i) smstpcr[i] - - -/* - * Software Reset Register offsets - */ - -static const u16 srcr[] = { - 0x0A0, 0x0A8, 0x0B0, 0x0B8, 0x0BC, 0x0C4, 0x1C8, 0x1CC, - 0x920, 0x924, 0x928, 0x92C, -}; - -#define SRCR(i) srcr[i] - - -/* Realtime Module Stop Control Register offsets */ -#define RMSTPCR(i) (smstpcr[i] - 0x20) - -/* Modem Module Stop Control Register offsets (r8a73a4) */ -#define MMSTPCR(i) (smstpcr[i] + 0x20) - -/* Software Reset Clearing Register offsets */ -#define SRSTCLR(i) (0x940 + (i) * 4) - - -/** - * Clock Pulse Generator / Module Standby and Software Reset Private Data - * - * @dev: CPG/MSSR device - * @base: CPG/MSSR register block base address - * @mstp_lock: protects writes to SMSTPCR - * @clks: Array containing all Core and Module Clocks - * @num_core_clks: Number of Core Clocks in clks[] - * @num_mod_clks: Number of Module Clocks in clks[] - * @last_dt_core_clk: ID of the last Core Clock exported to DT - */ -struct cpg_mssr_priv { - struct device *dev; - void __iomem *base; - spinlock_t mstp_lock; - - struct clk **clks; - unsigned int num_core_clks; - unsigned int num_mod_clks; - unsigned int last_dt_core_clk; -}; - - -/** - * struct mstp_clock - MSTP gating clock - * @hw: handle between common and hardware-specific interfaces - * @index: MSTP clock number - * @priv: CPG/MSSR private data - */ -struct mstp_clock { - struct clk_hw hw; - u32 index; - struct cpg_mssr_priv *priv; -}; - -#define to_mstp_clock(_hw) container_of(_hw, struct mstp_clock, hw) - -static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable) -{ - struct mstp_clock *clock = to_mstp_clock(hw); - struct cpg_mssr_priv *priv = clock->priv; - unsigned int reg = clock->index / 32; - unsigned int bit = clock->index % 32; - struct device *dev = priv->dev; - u32 bitmask = BIT(bit); - unsigned long flags; - unsigned int i; - u32 value; - - dev_dbg(dev, "MSTP %u%02u/%pC %s\n", reg, bit, hw->clk, - enable ? "ON" : "OFF"); - spin_lock_irqsave(&priv->mstp_lock, flags); - - value = clk_readl(priv->base + SMSTPCR(reg)); - if (enable) - value &= ~bitmask; - else - value |= bitmask; - clk_writel(value, priv->base + SMSTPCR(reg)); - - spin_unlock_irqrestore(&priv->mstp_lock, flags); - - if (!enable) - return 0; - - for (i = 1000; i > 0; --i) { - if (!(clk_readl(priv->base + MSTPSR(reg)) & - bitmask)) - break; - cpu_relax(); - } - - if (!i) { - dev_err(dev, "Failed to enable SMSTP %p[%d]\n", - priv->base + SMSTPCR(reg), bit); - return -ETIMEDOUT; - } - - return 0; -} - -static int cpg_mstp_clock_enable(struct clk_hw *hw) -{ - return cpg_mstp_clock_endisable(hw, true); -} - -static void cpg_mstp_clock_disable(struct clk_hw *hw) -{ - cpg_mstp_clock_endisable(hw, false); -} - -static int cpg_mstp_clock_is_enabled(struct clk_hw *hw) -{ - struct mstp_clock *clock = to_mstp_clock(hw); - struct cpg_mssr_priv *priv = clock->priv; - u32 value; - - value = clk_readl(priv->base + MSTPSR(clock->index / 32)); - - return !(value & BIT(clock->index % 32)); -} - -static const struct clk_ops cpg_mstp_clock_ops = { - .enable = cpg_mstp_clock_enable, - .disable = cpg_mstp_clock_disable, - .is_enabled = cpg_mstp_clock_is_enabled, -}; - -static -struct clk *cpg_mssr_clk_src_twocell_get(struct of_phandle_args *clkspec, - void *data) -{ - unsigned int clkidx = clkspec->args[1]; - struct cpg_mssr_priv *priv = data; - struct device *dev = priv->dev; - unsigned int idx; - const char *type; - struct clk *clk; - - switch (clkspec->args[0]) { - case CPG_CORE: - type = "core"; - if (clkidx > priv->last_dt_core_clk) { - dev_err(dev, "Invalid %s clock index %u\n", type, - clkidx); - return ERR_PTR(-EINVAL); - } - clk = priv->clks[clkidx]; - break; - - case CPG_MOD: - type = "module"; - idx = MOD_CLK_PACK(clkidx); - if (clkidx % 100 > 31 || idx >= priv->num_mod_clks) { - dev_err(dev, "Invalid %s clock index %u\n", type, - clkidx); - return ERR_PTR(-EINVAL); - } - clk = priv->clks[priv->num_core_clks + idx]; - break; - - default: - dev_err(dev, "Invalid CPG clock type %u\n", clkspec->args[0]); - return ERR_PTR(-EINVAL); - } - - if (IS_ERR(clk)) - dev_err(dev, "Cannot get %s clock %u: %ld", type, clkidx, - PTR_ERR(clk)); - else - dev_dbg(dev, "clock (%u, %u) is %pC at %pCr Hz\n", - clkspec->args[0], clkspec->args[1], clk, clk); - return clk; -} - -static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core, - const struct cpg_mssr_info *info, - struct cpg_mssr_priv *priv) -{ - struct clk *clk = NULL, *parent; - struct device *dev = priv->dev; - unsigned int id = core->id; - const char *parent_name; - - WARN_DEBUG(id >= priv->num_core_clks); - WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT); - - switch (core->type) { - case CLK_TYPE_IN: - clk = of_clk_get_by_name(priv->dev->of_node, core->name); - break; - - case CLK_TYPE_FF: - case CLK_TYPE_DIV6P1: - WARN_DEBUG(core->parent >= priv->num_core_clks); - parent = priv->clks[core->parent]; - if (IS_ERR(parent)) { - clk = parent; - goto fail; - } - - parent_name = __clk_get_name(parent); - if (core->type == CLK_TYPE_FF) { - clk = clk_register_fixed_factor(NULL, core->name, - parent_name, 0, - core->mult, core->div); - } else { - clk = cpg_div6_register(core->name, 1, &parent_name, - priv->base + core->offset); - } - break; - - default: - if (info->cpg_clk_register) - clk = info->cpg_clk_register(dev, core, info, - priv->clks, priv->base); - else - dev_err(dev, "%s has unsupported core clock type %u\n", - core->name, core->type); - break; - } - - if (IS_ERR_OR_NULL(clk)) - goto fail; - - dev_dbg(dev, "Core clock %pC at %pCr Hz\n", clk, clk); - priv->clks[id] = clk; - return; - -fail: - dev_err(dev, "Failed to register %s clock %s: %ld\n", "core,", - core->name, PTR_ERR(clk)); -} - -static void __init cpg_mssr_register_mod_clk(const struct mssr_mod_clk *mod, - const struct cpg_mssr_info *info, - struct cpg_mssr_priv *priv) -{ - struct mstp_clock *clock = NULL; - struct device *dev = priv->dev; - unsigned int id = mod->id; - struct clk_init_data init; - struct clk *parent, *clk; - const char *parent_name; - unsigned int i; - - WARN_DEBUG(id < priv->num_core_clks); - WARN_DEBUG(id >= priv->num_core_clks + priv->num_mod_clks); - WARN_DEBUG(mod->parent >= priv->num_core_clks + priv->num_mod_clks); - WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT); - - parent = priv->clks[mod->parent]; - if (IS_ERR(parent)) { - clk = parent; - goto fail; - } - - clock = kzalloc(sizeof(*clock), GFP_KERNEL); - if (!clock) { - clk = ERR_PTR(-ENOMEM); - goto fail; - } - - init.name = mod->name; - init.ops = &cpg_mstp_clock_ops; - init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; - for (i = 0; i < info->num_crit_mod_clks; i++) - if (id == info->crit_mod_clks[i]) { -#ifdef CLK_ENABLE_HAND_OFF - dev_dbg(dev, "MSTP %s setting CLK_ENABLE_HAND_OFF\n", - mod->name); - init.flags |= CLK_ENABLE_HAND_OFF; - break; -#else - dev_dbg(dev, "Ignoring MSTP %s to prevent disabling\n", - mod->name); - kfree(clock); - return; -#endif - } - - parent_name = __clk_get_name(parent); - init.parent_names = &parent_name; - init.num_parents = 1; - - clock->index = id - priv->num_core_clks; - clock->priv = priv; - clock->hw.init = &init; - - clk = clk_register(NULL, &clock->hw); - if (IS_ERR(clk)) - goto fail; - - dev_dbg(dev, "Module clock %pC at %pCr Hz\n", clk, clk); - priv->clks[id] = clk; - return; - -fail: - dev_err(dev, "Failed to register %s clock %s: %ld\n", "module,", - mod->name, PTR_ERR(clk)); - kfree(clock); -} - - -#ifdef CONFIG_PM_GENERIC_DOMAINS_OF -struct cpg_mssr_clk_domain { - struct generic_pm_domain genpd; - struct device_node *np; - unsigned int num_core_pm_clks; - unsigned int core_pm_clks[0]; -}; - -static bool cpg_mssr_is_pm_clk(const struct of_phandle_args *clkspec, - struct cpg_mssr_clk_domain *pd) -{ - unsigned int i; - - if (clkspec->np != pd->np || clkspec->args_count != 2) - return false; - - switch (clkspec->args[0]) { - case CPG_CORE: - for (i = 0; i < pd->num_core_pm_clks; i++) - if (clkspec->args[1] == pd->core_pm_clks[i]) - return true; - return false; - - case CPG_MOD: - return true; - - default: - return false; - } -} - -static int cpg_mssr_attach_dev(struct generic_pm_domain *genpd, - struct device *dev) -{ - struct cpg_mssr_clk_domain *pd = - container_of(genpd, struct cpg_mssr_clk_domain, genpd); - struct device_node *np = dev->of_node; - struct of_phandle_args clkspec; - struct clk *clk; - int i = 0; - int error; - - while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i, - &clkspec)) { - if (cpg_mssr_is_pm_clk(&clkspec, pd)) - goto found; - - of_node_put(clkspec.np); - i++; - } - - return 0; - -found: - clk = of_clk_get_from_provider(&clkspec); - of_node_put(clkspec.np); - - if (IS_ERR(clk)) - return PTR_ERR(clk); - - error = pm_clk_create(dev); - if (error) { - dev_err(dev, "pm_clk_create failed %d\n", error); - goto fail_put; - } - - error = pm_clk_add_clk(dev, clk); - if (error) { - dev_err(dev, "pm_clk_add_clk %pC failed %d\n", clk, error); - goto fail_destroy; - } - - return 0; - -fail_destroy: - pm_clk_destroy(dev); -fail_put: - clk_put(clk); - return error; -} - -static void cpg_mssr_detach_dev(struct generic_pm_domain *genpd, - struct device *dev) -{ - if (!list_empty(&dev->power.subsys_data->clock_list)) - pm_clk_destroy(dev); -} - -static int __init cpg_mssr_add_clk_domain(struct device *dev, - const unsigned int *core_pm_clks, - unsigned int num_core_pm_clks) -{ - struct device_node *np = dev->of_node; - struct generic_pm_domain *genpd; - struct cpg_mssr_clk_domain *pd; - size_t pm_size = num_core_pm_clks * sizeof(core_pm_clks[0]); - - pd = devm_kzalloc(dev, sizeof(*pd) + pm_size, GFP_KERNEL); - if (!pd) - return -ENOMEM; - - pd->np = np; - pd->num_core_pm_clks = num_core_pm_clks; - memcpy(pd->core_pm_clks, core_pm_clks, pm_size); - - genpd = &pd->genpd; - genpd->name = np->name; - genpd->flags = GENPD_FLAG_PM_CLK; - pm_genpd_init(genpd, &simple_qos_governor, false); - genpd->attach_dev = cpg_mssr_attach_dev; - genpd->detach_dev = cpg_mssr_detach_dev; - - of_genpd_add_provider_simple(np, genpd); - return 0; -} -#else -static inline int cpg_mssr_add_clk_domain(struct device *dev, - const unsigned int *core_pm_clks, - unsigned int num_core_pm_clks) -{ - return 0; -} -#endif /* !CONFIG_PM_GENERIC_DOMAINS_OF */ - - -static const struct of_device_id cpg_mssr_match[] = { -#ifdef CONFIG_ARCH_R8A7795 - { - .compatible = "renesas,r8a7795-cpg-mssr", - .data = &r8a7795_cpg_mssr_info, - }, -#endif - { /* sentinel */ } -}; - -static void cpg_mssr_del_clk_provider(void *data) -{ - of_clk_del_provider(data); -} - -static int __init cpg_mssr_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; - const struct cpg_mssr_info *info; - struct cpg_mssr_priv *priv; - unsigned int nclks, i; - struct resource *res; - struct clk **clks; - int error; - - info = of_match_node(cpg_mssr_match, np)->data; - if (info->init) { - error = info->init(dev); - if (error) - return error; - } - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - priv->dev = dev; - spin_lock_init(&priv->mstp_lock); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - priv->base = devm_ioremap_resource(dev, res); - if (IS_ERR(priv->base)) - return PTR_ERR(priv->base); - - nclks = info->num_total_core_clks + info->num_hw_mod_clks; - clks = devm_kmalloc_array(dev, nclks, sizeof(*clks), GFP_KERNEL); - if (!clks) - return -ENOMEM; - - priv->clks = clks; - priv->num_core_clks = info->num_total_core_clks; - priv->num_mod_clks = info->num_hw_mod_clks; - priv->last_dt_core_clk = info->last_dt_core_clk; - - for (i = 0; i < nclks; i++) - clks[i] = ERR_PTR(-ENOENT); - - for (i = 0; i < info->num_core_clks; i++) - cpg_mssr_register_core_clk(&info->core_clks[i], info, priv); - - for (i = 0; i < info->num_mod_clks; i++) - cpg_mssr_register_mod_clk(&info->mod_clks[i], info, priv); - - error = of_clk_add_provider(np, cpg_mssr_clk_src_twocell_get, priv); - if (error) - return error; - - error = devm_add_action_or_reset(dev, - cpg_mssr_del_clk_provider, - np); - if (error) - return error; - - error = cpg_mssr_add_clk_domain(dev, info->core_pm_clks, - info->num_core_pm_clks); - if (error) - return error; - - return 0; -} - -static struct platform_driver cpg_mssr_driver = { - .driver = { - .name = "renesas-cpg-mssr", - .of_match_table = cpg_mssr_match, - }, -}; - -static int __init cpg_mssr_init(void) -{ - return platform_driver_probe(&cpg_mssr_driver, cpg_mssr_probe); -} - -subsys_initcall(cpg_mssr_init); - -MODULE_DESCRIPTION("Renesas CPG/MSSR Driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/shmobile/renesas-cpg-mssr.h b/drivers/clk/shmobile/renesas-cpg-mssr.h deleted file mode 100644 index 952b695..0000000 --- a/drivers/clk/shmobile/renesas-cpg-mssr.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Renesas Clock Pulse Generator / Module Standby and Software Reset - * - * Copyright (C) 2015 Glider bvba - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - */ - -#ifndef __CLK_RENESAS_CPG_MSSR_H__ -#define __CLK_RENESAS_CPG_MSSR_H__ - - /* - * Definitions of CPG Core Clocks - * - * These include: - * - Clock outputs exported to DT - * - External input clocks - * - Internal CPG clocks - */ - -struct cpg_core_clk { - /* Common */ - const char *name; - unsigned int id; - unsigned int type; - /* Depending on type */ - unsigned int parent; /* Core Clocks only */ - unsigned int div; - unsigned int mult; - unsigned int offset; -}; - -enum clk_types { - /* Generic */ - CLK_TYPE_IN, /* External Clock Input */ - CLK_TYPE_FF, /* Fixed Factor Clock */ - CLK_TYPE_DIV6P1, /* DIV6 Clock with 1 parent clock */ - - /* Custom definitions start here */ - CLK_TYPE_CUSTOM, -}; - -#define DEF_TYPE(_name, _id, _type...) \ - { .name = _name, .id = _id, .type = _type } -#define DEF_BASE(_name, _id, _type, _parent...) \ - DEF_TYPE(_name, _id, _type, .parent = _parent) - -#define DEF_INPUT(_name, _id) \ - DEF_TYPE(_name, _id, CLK_TYPE_IN) -#define DEF_FIXED(_name, _id, _parent, _div, _mult) \ - DEF_BASE(_name, _id, CLK_TYPE_FF, _parent, .div = _div, .mult = _mult) -#define DEF_DIV6P1(_name, _id, _parent, _offset) \ - DEF_BASE(_name, _id, CLK_TYPE_DIV6P1, _parent, .offset = _offset) -#define DEF_SD(_name, _id, _parent, _offset) \ - DEF_BASE(_name, _id, CLK_TYPE_GEN3_SD, _parent, .offset = _offset) - - - /* - * Definitions of Module Clocks - */ - -struct mssr_mod_clk { - const char *name; - unsigned int id; - unsigned int parent; /* Add MOD_CLK_BASE for Module Clocks */ -}; - -/* Convert from sparse base-100 to packed index space */ -#define MOD_CLK_PACK(x) ((x) - ((x) / 100) * (100 - 32)) - -#define MOD_CLK_ID(x) (MOD_CLK_BASE + MOD_CLK_PACK(x)) - -#define DEF_MOD(_name, _mod, _parent...) \ - { .name = _name, .id = MOD_CLK_ID(_mod), .parent = _parent } - - -struct device_node; - - /** - * SoC-specific CPG/MSSR Description - * - * @core_clks: Array of Core Clock definitions - * @num_core_clks: Number of entries in core_clks[] - * @last_dt_core_clk: ID of the last Core Clock exported to DT - * @num_total_core_clks: Total number of Core Clocks (exported + internal) - * - * @mod_clks: Array of Module Clock definitions - * @num_mod_clks: Number of entries in mod_clks[] - * @num_hw_mod_clks: Number of Module Clocks supported by the hardware - * - * @crit_mod_clks: Array with Module Clock IDs of critical clocks that - * should not be disabled without a knowledgeable driver - * @num_crit_mod_clks: Number of entries in crit_mod_clks[] - * - * @core_pm_clks: Array with IDs of Core Clocks that are suitable for Power - * Management, in addition to Module Clocks - * @num_core_pm_clks: Number of entries in core_pm_clks[] - * - * @init: Optional callback to perform SoC-specific initialization - * @cpg_clk_register: Optional callback to handle special Core Clock types - */ - -struct cpg_mssr_info { - /* Core Clocks */ - const struct cpg_core_clk *core_clks; - unsigned int num_core_clks; - unsigned int last_dt_core_clk; - unsigned int num_total_core_clks; - - /* Module Clocks */ - const struct mssr_mod_clk *mod_clks; - unsigned int num_mod_clks; - unsigned int num_hw_mod_clks; - - /* Critical Module Clocks that should not be disabled */ - const unsigned int *crit_mod_clks; - unsigned int num_crit_mod_clks; - - /* Core Clocks suitable for PM, in addition to the Module Clocks */ - const unsigned int *core_pm_clks; - unsigned int num_core_pm_clks; - - /* Callbacks */ - int (*init)(struct device *dev); - struct clk *(*cpg_clk_register)(struct device *dev, - const struct cpg_core_clk *core, - const struct cpg_mssr_info *info, - struct clk **clks, void __iomem *base); -}; - -extern const struct cpg_mssr_info r8a7795_cpg_mssr_info; -#endif -- cgit v0.10.2 From 2969f6ee37d1cb10a5be2f8d4621e979652448da Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 1 Mar 2016 10:59:53 -0800 Subject: clk: mvebu: Remove CLK_IS_ROOT This flag is a no-op now. Remove usage of the flag. Acked-by: Gregory CLEMENT Signed-off-by: Stephen Boyd diff --git a/drivers/clk/mvebu/common.c b/drivers/clk/mvebu/common.c index daa6ebd..66be2e0 100644 --- a/drivers/clk/mvebu/common.c +++ b/drivers/clk/mvebu/common.c @@ -137,8 +137,8 @@ void __init mvebu_coreclk_setup(struct device_node *np, of_property_read_string_index(np, "clock-output-names", 0, &tclk_name); rate = desc->get_tclk_freq(base); - clk_data.clks[0] = clk_register_fixed_rate(NULL, tclk_name, NULL, - CLK_IS_ROOT, rate); + clk_data.clks[0] = clk_register_fixed_rate(NULL, tclk_name, NULL, 0, + rate); WARN_ON(IS_ERR(clk_data.clks[0])); /* Register CPU clock */ @@ -150,8 +150,8 @@ void __init mvebu_coreclk_setup(struct device_node *np, && desc->is_sscg_enabled(base)) rate = desc->fix_sscg_deviation(rate); - clk_data.clks[1] = clk_register_fixed_rate(NULL, cpuclk_name, NULL, - CLK_IS_ROOT, rate); + clk_data.clks[1] = clk_register_fixed_rate(NULL, cpuclk_name, NULL, 0, + rate); WARN_ON(IS_ERR(clk_data.clks[1])); /* Register fixed-factor clocks derived from CPU clock */ @@ -174,8 +174,7 @@ void __init mvebu_coreclk_setup(struct device_node *np, 2 + desc->num_ratios, &name); rate = desc->get_refclk_freq(base); clk_data.clks[2 + desc->num_ratios] = - clk_register_fixed_rate(NULL, name, NULL, - CLK_IS_ROOT, rate); + clk_register_fixed_rate(NULL, name, NULL, 0, rate); WARN_ON(IS_ERR(clk_data.clks[2 + desc->num_ratios])); } diff --git a/drivers/clk/mvebu/dove-divider.c b/drivers/clk/mvebu/dove-divider.c index 3e0b52d..4091f3c 100644 --- a/drivers/clk/mvebu/dove-divider.c +++ b/drivers/clk/mvebu/dove-divider.c @@ -225,8 +225,7 @@ static int dove_divider_init(struct device *dev, void __iomem *base, * Create the core PLL clock. We treat this as a fixed rate * clock as we don't know any better, and documentation is sparse. */ - clk = clk_register_fixed_rate(dev, core_pll[0], NULL, CLK_IS_ROOT, - 2000000000UL); + clk = clk_register_fixed_rate(dev, core_pll[0], NULL, 0, 2000000000UL); if (IS_ERR(clk)) return PTR_ERR(clk); -- cgit v0.10.2 From 553b4858177d62a4969925ade1ea894c2a07b235 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 1 Mar 2016 11:00:06 -0800 Subject: clk: x86: Remove CLK_IS_ROOT This flag is a no-op now. Remove usage of the flag. Acked-by: Mika Westerberg Signed-off-by: Stephen Boyd diff --git a/drivers/clk/x86/clk-lpt.c b/drivers/clk/x86/clk-lpt.c index f827083..54e0cf9 100644 --- a/drivers/clk/x86/clk-lpt.c +++ b/drivers/clk/x86/clk-lpt.c @@ -30,7 +30,7 @@ static int lpt_clk_probe(struct platform_device *pdev) /* LPSS free running clock */ drvdata->name = "lpss_clk"; clk = clk_register_fixed_rate(&pdev->dev, drvdata->name, NULL, - CLK_IS_ROOT, 100000000); + 0, 100000000); if (IS_ERR(clk)) return PTR_ERR(clk); -- cgit v0.10.2 From 4106684e114d07cdb0d7803963fa6e45aedc0ff4 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 1 Mar 2016 11:00:07 -0800 Subject: clk: x86: Remove clkdev.h and clk.h includes This driver is a clk provider and not a clk consumer, so remove the clk.h include. Also, drop clkdev.h because there's not clkdev usage here either. Acked-by: Mika Westerberg Signed-off-by: Stephen Boyd diff --git a/drivers/clk/x86/clk-lpt.c b/drivers/clk/x86/clk-lpt.c index 54e0cf9..6b40eb8 100644 --- a/drivers/clk/x86/clk-lpt.c +++ b/drivers/clk/x86/clk-lpt.c @@ -10,8 +10,6 @@ * published by the Free Software Foundation. */ -#include -#include #include #include #include -- cgit v0.10.2 From 0d9967fe4ba6fc3a57d946a54bcba2d0b3ef8e0b Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 1 Mar 2016 11:00:15 -0800 Subject: clk: mb86s7x: Remove CLK_IS_ROOT This flag is a no-op now. Remove usage of the flag. Acked-by: Jassi Brar Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk-mb86s7x.c b/drivers/clk/clk-mb86s7x.c index f39c25a..e081775 100644 --- a/drivers/clk/clk-mb86s7x.c +++ b/drivers/clk/clk-mb86s7x.c @@ -217,7 +217,7 @@ static struct clk *crg11_get(struct of_phandle_args *clkspec, void *data) init.name = clkp; init.num_parents = 0; init.ops = &crg_port_ops; - init.flags = CLK_IS_ROOT; + init.flags = 0; crgclk->hw.init = &init; crgclk->cntrlr = cntrlr; crgclk->domain = domain; @@ -341,7 +341,7 @@ struct clk *mb86s7x_clclk_register(struct device *cpu_dev) init.name = dev_name(cpu_dev); init.ops = &clk_clc_ops; - init.flags = CLK_IS_ROOT | CLK_GET_RATE_NOCACHE; + init.flags = CLK_GET_RATE_NOCACHE; init.num_parents = 0; return devm_clk_register(cpu_dev, &clc->hw); -- cgit v0.10.2 From 0f4c7a138dfefb0ebdbaf56e3ba2acd2958a6605 Mon Sep 17 00:00:00 2001 From: Loc Ho Date: Mon, 29 Feb 2016 14:15:43 -0700 Subject: clk: xgene: Add missing parenthesis when clearing divider value In the initial fix for non-zero divider shift value, the parenthesis was missing after the negate operation. This patch adds the required parenthesis. Otherwise, lower bits may be cleared unintentionally. Signed-off-by: Loc Ho Acked-by: Toan Le Fixes: 1382ea631ddd ("clk: xgene: Fix divider with non-zero shift value") Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk-xgene.c b/drivers/clk/clk-xgene.c index bd7156b..d73450b 100644 --- a/drivers/clk/clk-xgene.c +++ b/drivers/clk/clk-xgene.c @@ -376,8 +376,8 @@ static int xgene_clk_set_rate(struct clk_hw *hw, unsigned long rate, /* Set new divider */ data = xgene_clk_read(pclk->param.divider_reg + pclk->param.reg_divider_offset); - data &= ~((1 << pclk->param.reg_divider_width) - 1) - << pclk->param.reg_divider_shift; + data &= ~(((1 << pclk->param.reg_divider_width) - 1) + << pclk->param.reg_divider_shift); data |= divider; xgene_clk_write(data, pclk->param.divider_reg + pclk->param.reg_divider_offset); -- cgit v0.10.2 From 8626556f259331aac23c0e274aed24420f0e5403 Mon Sep 17 00:00:00 2001 From: Sylvain Lemieux Date: Tue, 23 Feb 2016 14:56:09 -0500 Subject: clk: lpc32xx: fix compilation warning Remove the following false positives compilation warning: - drivers/clk/nxp/clk-lpc32xx.c: In function 'lpc32xx_clk_register': warning: 'hw' may be used uninitialized in this function [-Wmaybe-uninitialized] - drivers/clk/nxp/clk-lpc32xx.c: In function 'clk_hclk_pll_round_rate': warning: 'p' may be used uninitialized in this function [-Wmaybe-uninitialized] warning: 'n' may be used uninitialized in this function [-Wmaybe-uninitialized] warning: 'm' may be used uninitialized in this function [-Wmaybe-uninitialized] Tested using gcc version 4.7.3. Signed-off-by: Sylvain Lemieux [sboyd@codeaurora.org: Drop assignment of hw to NULL as return silences it and is less likely to lead to hiding problems later] Signed-off-by: Stephen Boyd diff --git a/drivers/clk/nxp/clk-lpc32xx.c b/drivers/clk/nxp/clk-lpc32xx.c index 48b3a11..481b264 100644 --- a/drivers/clk/nxp/clk-lpc32xx.c +++ b/drivers/clk/nxp/clk-lpc32xx.c @@ -588,7 +588,8 @@ static long clk_hclk_pll_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *parent_rate) { struct lpc32xx_pll_clk *clk = to_lpc32xx_pll_clk(hw); - u64 m_i, m, n, p, o = rate, i = *parent_rate, d = (u64)rate << 6; + u64 m_i, o = rate, i = *parent_rate, d = (u64)rate << 6; + u64 m = 0, n = 0, p = 0; int p_i, n_i; pr_debug("%s: %lu/%lu\n", clk_hw_get_name(hw), *parent_rate, rate); @@ -1428,6 +1429,8 @@ static struct clk * __init lpc32xx_clk_register(u32 id) hw = &clk_hw->hw0.div.hw; else if (clk_hw->type == CLK_GATE) hw = &clk_hw->hw0.gate.hw; + else + return ERR_PTR(-EINVAL); hw->init = &clk_init; clk = clk_register(NULL, hw); -- cgit v0.10.2 From 378523d1500314637ae07bb604475a98f01bfa4c Mon Sep 17 00:00:00 2001 From: Joachim Eastwood Date: Thu, 3 Mar 2016 22:47:04 +0100 Subject: clk: add lpc18xx creg clk driver The CREG block on lpc18xx contains configuration register for two low power clocks. Support enabling of these two clocks with a clk driver that access CREG trough the syscon regmap interface. These clocks are needed to support peripherals like the internal RTC on lpc18xx. Signed-off-by: Joachim Eastwood Signed-off-by: Stephen Boyd diff --git a/drivers/clk/nxp/Makefile b/drivers/clk/nxp/Makefile index 607bd48..d456ee6 100644 --- a/drivers/clk/nxp/Makefile +++ b/drivers/clk/nxp/Makefile @@ -1,3 +1,4 @@ obj-$(CONFIG_ARCH_LPC18XX) += clk-lpc18xx-cgu.o obj-$(CONFIG_ARCH_LPC18XX) += clk-lpc18xx-ccu.o +obj-$(CONFIG_ARCH_LPC18XX) += clk-lpc18xx-creg.o obj-$(CONFIG_ARCH_LPC32XX) += clk-lpc32xx.o diff --git a/drivers/clk/nxp/clk-lpc18xx-creg.c b/drivers/clk/nxp/clk-lpc18xx-creg.c new file mode 100644 index 0000000..d44b61a --- /dev/null +++ b/drivers/clk/nxp/clk-lpc18xx-creg.c @@ -0,0 +1,226 @@ +/* + * Clk driver for NXP LPC18xx/43xx Configuration Registers (CREG) + * + * Copyright (C) 2015 Joachim Eastwood + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define LPC18XX_CREG_CREG0 0x004 +#define LPC18XX_CREG_CREG0_EN1KHZ BIT(0) +#define LPC18XX_CREG_CREG0_EN32KHZ BIT(1) +#define LPC18XX_CREG_CREG0_RESET32KHZ BIT(2) +#define LPC18XX_CREG_CREG0_PD32KHZ BIT(3) + +#define to_clk_creg(_hw) container_of(_hw, struct clk_creg_data, hw) + +enum { + CREG_CLK_1KHZ, + CREG_CLK_32KHZ, + CREG_CLK_MAX, +}; + +struct clk_creg_data { + struct clk_hw hw; + const char *name; + struct regmap *reg; + unsigned int en_mask; + const struct clk_ops *ops; +}; + +#define CREG_CLK(_name, _emask, _ops) \ +{ \ + .name = _name, \ + .en_mask = LPC18XX_CREG_CREG0_##_emask, \ + .ops = &_ops, \ +} + +static int clk_creg_32k_prepare(struct clk_hw *hw) +{ + struct clk_creg_data *creg = to_clk_creg(hw); + int ret; + + ret = regmap_update_bits(creg->reg, LPC18XX_CREG_CREG0, + LPC18XX_CREG_CREG0_PD32KHZ | + LPC18XX_CREG_CREG0_RESET32KHZ, 0); + + /* + * Powering up the 32k oscillator takes a long while + * and sadly there aren't any status bit to poll. + */ + msleep(2500); + + return ret; +} + +static void clk_creg_32k_unprepare(struct clk_hw *hw) +{ + struct clk_creg_data *creg = to_clk_creg(hw); + + regmap_update_bits(creg->reg, LPC18XX_CREG_CREG0, + LPC18XX_CREG_CREG0_PD32KHZ, + LPC18XX_CREG_CREG0_PD32KHZ); +} + +static int clk_creg_32k_is_prepared(struct clk_hw *hw) +{ + struct clk_creg_data *creg = to_clk_creg(hw); + u32 reg; + + regmap_read(creg->reg, LPC18XX_CREG_CREG0, ®); + + return !(reg & LPC18XX_CREG_CREG0_PD32KHZ) && + !(reg & LPC18XX_CREG_CREG0_RESET32KHZ); +} + +static unsigned long clk_creg_1k_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + return parent_rate / 32; +} + +static int clk_creg_enable(struct clk_hw *hw) +{ + struct clk_creg_data *creg = to_clk_creg(hw); + + return regmap_update_bits(creg->reg, LPC18XX_CREG_CREG0, + creg->en_mask, creg->en_mask); +} + +static void clk_creg_disable(struct clk_hw *hw) +{ + struct clk_creg_data *creg = to_clk_creg(hw); + + regmap_update_bits(creg->reg, LPC18XX_CREG_CREG0, + creg->en_mask, 0); +} + +static int clk_creg_is_enabled(struct clk_hw *hw) +{ + struct clk_creg_data *creg = to_clk_creg(hw); + u32 reg; + + regmap_read(creg->reg, LPC18XX_CREG_CREG0, ®); + + return !!(reg & creg->en_mask); +} + +static const struct clk_ops clk_creg_32k = { + .enable = clk_creg_enable, + .disable = clk_creg_disable, + .is_enabled = clk_creg_is_enabled, + .prepare = clk_creg_32k_prepare, + .unprepare = clk_creg_32k_unprepare, + .is_prepared = clk_creg_32k_is_prepared, +}; + +static const struct clk_ops clk_creg_1k = { + .enable = clk_creg_enable, + .disable = clk_creg_disable, + .is_enabled = clk_creg_is_enabled, + .recalc_rate = clk_creg_1k_recalc_rate, +}; + +static struct clk_creg_data clk_creg_clocks[] = { + [CREG_CLK_1KHZ] = CREG_CLK("1khz_clk", EN1KHZ, clk_creg_1k), + [CREG_CLK_32KHZ] = CREG_CLK("32khz_clk", EN32KHZ, clk_creg_32k), +}; + +static struct clk *clk_register_creg_clk(struct device *dev, + struct clk_creg_data *creg_clk, + const char **parent_name, + struct regmap *syscon) +{ + struct clk_init_data init; + + init.ops = creg_clk->ops; + init.name = creg_clk->name; + init.parent_names = parent_name; + init.num_parents = 1; + + creg_clk->reg = syscon; + creg_clk->hw.init = &init; + + if (dev) + return devm_clk_register(dev, &creg_clk->hw); + + return clk_register(NULL, &creg_clk->hw); +} + +static struct clk *clk_creg_early[CREG_CLK_MAX]; +static struct clk_onecell_data clk_creg_early_data = { + .clks = clk_creg_early, + .clk_num = CREG_CLK_MAX, +}; + +static void __init lpc18xx_creg_clk_init(struct device_node *np) +{ + const char *clk_32khz_parent; + struct regmap *syscon; + + syscon = syscon_node_to_regmap(np->parent); + if (IS_ERR(syscon)) { + pr_err("%s: syscon lookup failed\n", __func__); + return; + } + + clk_32khz_parent = of_clk_get_parent_name(np, 0); + + clk_creg_early[CREG_CLK_32KHZ] = + clk_register_creg_clk(NULL, &clk_creg_clocks[CREG_CLK_32KHZ], + &clk_32khz_parent, syscon); + clk_creg_early[CREG_CLK_1KHZ] = ERR_PTR(-EPROBE_DEFER); + + of_clk_add_provider(np, of_clk_src_onecell_get, &clk_creg_early_data); +} +CLK_OF_DECLARE(lpc18xx_creg_clk, "nxp,lpc1850-creg-clk", lpc18xx_creg_clk_init); + +static struct clk *clk_creg[CREG_CLK_MAX]; +static struct clk_onecell_data clk_creg_data = { + .clks = clk_creg, + .clk_num = CREG_CLK_MAX, +}; + +static int lpc18xx_creg_clk_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct regmap *syscon; + + syscon = syscon_node_to_regmap(np->parent); + if (IS_ERR(syscon)) { + dev_err(&pdev->dev, "syscon lookup failed\n"); + return PTR_ERR(syscon); + } + + clk_creg[CREG_CLK_32KHZ] = clk_creg_early[CREG_CLK_32KHZ]; + clk_creg[CREG_CLK_1KHZ] = + clk_register_creg_clk(NULL, &clk_creg_clocks[CREG_CLK_1KHZ], + &clk_creg_clocks[CREG_CLK_32KHZ].name, + syscon); + + return of_clk_add_provider(np, of_clk_src_onecell_get, &clk_creg_data); +} + +static const struct of_device_id lpc18xx_creg_clk_of_match[] = { + { .compatible = "nxp,lpc1850-creg-clk" }, + {}, +}; + +static struct platform_driver lpc18xx_creg_clk_driver = { + .probe = lpc18xx_creg_clk_probe, + .driver = { + .name = "lpc18xx-creg-clk", + .of_match_table = lpc18xx_creg_clk_of_match, + }, +}; +builtin_platform_driver(lpc18xx_creg_clk_driver); -- cgit v0.10.2 From 782fa5201a660874951a515190530c1b200ca904 Mon Sep 17 00:00:00 2001 From: Joachim Eastwood Date: Thu, 3 Mar 2016 22:47:05 +0100 Subject: doc: dt: add documentation for lpc1850-creg-clk driver Add DT binding documentation for lpc1850-creg-clk driver. Signed-off-by: Joachim Eastwood Acked-by: Rob Herring Signed-off-by: Stephen Boyd diff --git a/Documentation/devicetree/bindings/clock/lpc1850-creg-clk.txt b/Documentation/devicetree/bindings/clock/lpc1850-creg-clk.txt new file mode 100644 index 0000000..6f1c7b4 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/lpc1850-creg-clk.txt @@ -0,0 +1,52 @@ +* NXP LPC1850 CREG clocks + +The NXP LPC18xx/43xx CREG (Configuration Registers) block contains +control registers for two low speed clocks. One of the clocks is a +32 kHz oscillator driver with power up/down and clock gating. Next +is a fixed divider that creates a 1 kHz clock from the 32 kHz osc. + +These clocks are used by the RTC and the Event Router peripherials. +The 32 kHz can also be routed to other peripherials to enable low +power modes. + +This binding uses the common clock binding: + Documentation/devicetree/bindings/clock/clock-bindings.txt + +Required properties: +- compatible: + Should be "nxp,lpc1850-creg-clk" +- #clock-cells: + Shall have value <1>. +- clocks: + Shall contain a phandle to the fixed 32 kHz crystal. + +The creg-clk node must be a child of the creg syscon node. + +The following clocks are available from the clock node. + +Clock ID Name + 0 1 kHz clock + 1 32 kHz Oscillator + +Example: +soc { + creg: syscon@40043000 { + compatible = "nxp,lpc1850-creg", "syscon", "simple-mfd"; + reg = <0x40043000 0x1000>; + + creg_clk: clock-controller { + compatible = "nxp,lpc1850-creg-clk"; + clocks = <&xtal32>; + #clock-cells = <1>; + }; + + ... + }; + + rtc: rtc@40046000 { + ... + clocks = <&creg_clk 0>, <&ccu1 CLK_CPU_BUS>; + clock-names = "rtc", "reg"; + ... + }; +}; -- cgit v0.10.2 From 81925c5eaad1c9eb33f0a0458612dcdfd05379bb Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 1 Mar 2016 10:59:57 -0800 Subject: clk: qcom: Remove CLK_IS_ROOT This flag is a no-op now. Remove usage of the flag. Signed-off-by: Stephen Boyd diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c index cc8a065..f7c226a 100644 --- a/drivers/clk/qcom/common.c +++ b/drivers/clk/qcom/common.c @@ -119,7 +119,6 @@ static int _qcom_cc_register_board_clk(struct device *dev, const char *path, fixed->hw.init = &init_data; init_data.name = path; - init_data.flags = CLK_IS_ROOT; init_data.ops = &clk_fixed_rate_ops; clk = devm_clk_register(dev, &fixed->hw); diff --git a/drivers/clk/qcom/gcc-ipq806x.c b/drivers/clk/qcom/gcc-ipq806x.c index dd5402b..52a7d39 100644 --- a/drivers/clk/qcom/gcc-ipq806x.c +++ b/drivers/clk/qcom/gcc-ipq806x.c @@ -890,7 +890,6 @@ static struct clk_branch gsbi1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -906,7 +905,6 @@ static struct clk_branch gsbi2_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi2_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -922,7 +920,6 @@ static struct clk_branch gsbi4_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi4_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -938,7 +935,6 @@ static struct clk_branch gsbi5_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi5_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -954,7 +950,6 @@ static struct clk_branch gsbi6_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi6_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -970,7 +965,6 @@ static struct clk_branch gsbi7_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi7_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1144,7 +1138,6 @@ static struct clk_branch pmem_clk = { .hw.init = &(struct clk_init_data){ .name = "pmem_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1308,7 +1301,6 @@ static struct clk_branch sdc1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "sdc1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1324,7 +1316,6 @@ static struct clk_branch sdc3_h_clk = { .hw.init = &(struct clk_init_data){ .name = "sdc3_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1394,7 +1385,6 @@ static struct clk_branch tsif_h_clk = { .hw.init = &(struct clk_init_data){ .name = "tsif_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1410,7 +1400,6 @@ static struct clk_branch dma_bam_h_clk = { .hw.init = &(struct clk_init_data){ .name = "dma_bam_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1425,7 +1414,6 @@ static struct clk_branch adm0_clk = { .hw.init = &(struct clk_init_data){ .name = "adm0_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1442,7 +1430,6 @@ static struct clk_branch adm0_pbus_clk = { .hw.init = &(struct clk_init_data){ .name = "adm0_pbus_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1457,7 +1444,6 @@ static struct clk_branch pmic_arb0_h_clk = { .hw.init = &(struct clk_init_data){ .name = "pmic_arb0_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1472,7 +1458,6 @@ static struct clk_branch pmic_arb1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "pmic_arb1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1487,7 +1472,6 @@ static struct clk_branch pmic_ssbi2_clk = { .hw.init = &(struct clk_init_data){ .name = "pmic_ssbi2_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1504,7 +1488,6 @@ static struct clk_branch rpm_msg_ram_h_clk = { .hw.init = &(struct clk_init_data){ .name = "rpm_msg_ram_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1563,7 +1546,6 @@ static struct clk_branch pcie_a_clk = { .hw.init = &(struct clk_init_data){ .name = "pcie_a_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1577,7 +1559,6 @@ static struct clk_branch pcie_aux_clk = { .hw.init = &(struct clk_init_data){ .name = "pcie_aux_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1591,7 +1572,6 @@ static struct clk_branch pcie_h_clk = { .hw.init = &(struct clk_init_data){ .name = "pcie_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1605,7 +1585,6 @@ static struct clk_branch pcie_phy_clk = { .hw.init = &(struct clk_init_data){ .name = "pcie_phy_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1659,7 +1638,6 @@ static struct clk_branch pcie1_a_clk = { .hw.init = &(struct clk_init_data){ .name = "pcie1_a_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1673,7 +1651,6 @@ static struct clk_branch pcie1_aux_clk = { .hw.init = &(struct clk_init_data){ .name = "pcie1_aux_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1687,7 +1664,6 @@ static struct clk_branch pcie1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "pcie1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1701,7 +1677,6 @@ static struct clk_branch pcie1_phy_clk = { .hw.init = &(struct clk_init_data){ .name = "pcie1_phy_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1755,7 +1730,6 @@ static struct clk_branch pcie2_a_clk = { .hw.init = &(struct clk_init_data){ .name = "pcie2_a_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1769,7 +1743,6 @@ static struct clk_branch pcie2_aux_clk = { .hw.init = &(struct clk_init_data){ .name = "pcie2_aux_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1783,7 +1756,6 @@ static struct clk_branch pcie2_h_clk = { .hw.init = &(struct clk_init_data){ .name = "pcie2_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1797,7 +1769,6 @@ static struct clk_branch pcie2_phy_clk = { .hw.init = &(struct clk_init_data){ .name = "pcie2_phy_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1887,7 +1858,6 @@ static struct clk_branch sata_a_clk = { .hw.init = &(struct clk_init_data){ .name = "sata_a_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1901,7 +1871,6 @@ static struct clk_branch sata_h_clk = { .hw.init = &(struct clk_init_data){ .name = "sata_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1915,7 +1884,6 @@ static struct clk_branch sfab_sata_s_h_clk = { .hw.init = &(struct clk_init_data){ .name = "sfab_sata_s_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1929,7 +1897,6 @@ static struct clk_branch sata_phy_cfg_clk = { .hw.init = &(struct clk_init_data){ .name = "sata_phy_cfg_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2139,7 +2106,6 @@ static struct clk_branch usb_hs1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "usb_hs1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2218,7 +2184,6 @@ static struct clk_branch usb_fs1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "usb_fs1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2234,7 +2199,6 @@ static struct clk_branch ebi2_clk = { .hw.init = &(struct clk_init_data){ .name = "ebi2_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2248,7 +2212,6 @@ static struct clk_branch ebi2_aon_clk = { .hw.init = &(struct clk_init_data){ .name = "ebi2_always_on_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; diff --git a/drivers/clk/qcom/gcc-msm8660.c b/drivers/clk/qcom/gcc-msm8660.c index ad41303..6dc5586 100644 --- a/drivers/clk/qcom/gcc-msm8660.c +++ b/drivers/clk/qcom/gcc-msm8660.c @@ -1479,7 +1479,6 @@ static struct clk_branch pmem_clk = { .hw.init = &(struct clk_init_data){ .name = "pmem_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2027,7 +2026,6 @@ static struct clk_branch gsbi1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2041,7 +2039,6 @@ static struct clk_branch gsbi2_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi2_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2055,7 +2052,6 @@ static struct clk_branch gsbi3_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi3_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2069,7 +2065,6 @@ static struct clk_branch gsbi4_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi4_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2083,7 +2078,6 @@ static struct clk_branch gsbi5_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi5_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2097,7 +2091,6 @@ static struct clk_branch gsbi6_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi6_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2111,7 +2104,6 @@ static struct clk_branch gsbi7_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi7_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2125,7 +2117,6 @@ static struct clk_branch gsbi8_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi8_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2139,7 +2130,6 @@ static struct clk_branch gsbi9_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi9_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2153,7 +2143,6 @@ static struct clk_branch gsbi10_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi10_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2167,7 +2156,6 @@ static struct clk_branch gsbi11_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi11_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2181,7 +2169,6 @@ static struct clk_branch gsbi12_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi12_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2195,7 +2182,6 @@ static struct clk_branch tsif_h_clk = { .hw.init = &(struct clk_init_data){ .name = "tsif_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2209,7 +2195,6 @@ static struct clk_branch usb_fs1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "usb_fs1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2223,7 +2208,6 @@ static struct clk_branch usb_fs2_h_clk = { .hw.init = &(struct clk_init_data){ .name = "usb_fs2_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2237,7 +2221,6 @@ static struct clk_branch usb_hs1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "usb_hs1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2251,7 +2234,6 @@ static struct clk_branch sdc1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "sdc1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2265,7 +2247,6 @@ static struct clk_branch sdc2_h_clk = { .hw.init = &(struct clk_init_data){ .name = "sdc2_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2279,7 +2260,6 @@ static struct clk_branch sdc3_h_clk = { .hw.init = &(struct clk_init_data){ .name = "sdc3_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2293,7 +2273,6 @@ static struct clk_branch sdc4_h_clk = { .hw.init = &(struct clk_init_data){ .name = "sdc4_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2307,7 +2286,6 @@ static struct clk_branch sdc5_h_clk = { .hw.init = &(struct clk_init_data){ .name = "sdc5_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2322,7 +2300,6 @@ static struct clk_branch adm0_clk = { .hw.init = &(struct clk_init_data){ .name = "adm0_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2337,7 +2314,6 @@ static struct clk_branch adm0_pbus_clk = { .hw.init = &(struct clk_init_data){ .name = "adm0_pbus_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2352,7 +2328,6 @@ static struct clk_branch adm1_clk = { .hw.init = &(struct clk_init_data){ .name = "adm1_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2367,7 +2342,6 @@ static struct clk_branch adm1_pbus_clk = { .hw.init = &(struct clk_init_data){ .name = "adm1_pbus_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2382,7 +2356,6 @@ static struct clk_branch modem_ahb1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "modem_ahb1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2397,7 +2370,6 @@ static struct clk_branch modem_ahb2_h_clk = { .hw.init = &(struct clk_init_data){ .name = "modem_ahb2_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2412,7 +2384,6 @@ static struct clk_branch pmic_arb0_h_clk = { .hw.init = &(struct clk_init_data){ .name = "pmic_arb0_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2427,7 +2398,6 @@ static struct clk_branch pmic_arb1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "pmic_arb1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2442,7 +2412,6 @@ static struct clk_branch pmic_ssbi2_clk = { .hw.init = &(struct clk_init_data){ .name = "pmic_ssbi2_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2459,7 +2428,6 @@ static struct clk_branch rpm_msg_ram_h_clk = { .hw.init = &(struct clk_init_data){ .name = "rpm_msg_ram_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; diff --git a/drivers/clk/qcom/gcc-msm8960.c b/drivers/clk/qcom/gcc-msm8960.c index 0a0c1f5..eb551c7 100644 --- a/drivers/clk/qcom/gcc-msm8960.c +++ b/drivers/clk/qcom/gcc-msm8960.c @@ -1546,7 +1546,6 @@ static struct clk_branch pmem_clk = { .hw.init = &(struct clk_init_data){ .name = "pmem_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2143,7 +2142,6 @@ static struct clk_branch usb_hsic_hsio_cal_clk = { .hw.init = &(struct clk_init_data){ .name = "usb_hsic_hsio_cal_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2293,7 +2291,6 @@ static struct clk_branch ce1_core_clk = { .hw.init = &(struct clk_init_data){ .name = "ce1_core_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2307,7 +2304,6 @@ static struct clk_branch ce1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "ce1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2323,7 +2319,6 @@ static struct clk_branch dma_bam_h_clk = { .hw.init = &(struct clk_init_data){ .name = "dma_bam_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2339,7 +2334,6 @@ static struct clk_branch gsbi1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2355,7 +2349,6 @@ static struct clk_branch gsbi2_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi2_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2371,7 +2364,6 @@ static struct clk_branch gsbi3_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi3_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2387,7 +2379,6 @@ static struct clk_branch gsbi4_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi4_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2403,7 +2394,6 @@ static struct clk_branch gsbi5_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi5_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2419,7 +2409,6 @@ static struct clk_branch gsbi6_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi6_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2435,7 +2424,6 @@ static struct clk_branch gsbi7_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi7_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2451,7 +2439,6 @@ static struct clk_branch gsbi8_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi8_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2467,7 +2454,6 @@ static struct clk_branch gsbi9_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi9_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2483,7 +2469,6 @@ static struct clk_branch gsbi10_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi10_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2499,7 +2484,6 @@ static struct clk_branch gsbi11_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi11_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2515,7 +2499,6 @@ static struct clk_branch gsbi12_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi12_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2531,7 +2514,6 @@ static struct clk_branch tsif_h_clk = { .hw.init = &(struct clk_init_data){ .name = "tsif_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2545,7 +2527,6 @@ static struct clk_branch usb_fs1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "usb_fs1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2559,7 +2540,6 @@ static struct clk_branch usb_fs2_h_clk = { .hw.init = &(struct clk_init_data){ .name = "usb_fs2_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2575,7 +2555,6 @@ static struct clk_branch usb_hs1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "usb_hs1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2589,7 +2568,6 @@ static struct clk_branch usb_hs3_h_clk = { .hw.init = &(struct clk_init_data){ .name = "usb_hs3_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2603,7 +2581,6 @@ static struct clk_branch usb_hs4_h_clk = { .hw.init = &(struct clk_init_data){ .name = "usb_hs4_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2617,7 +2594,6 @@ static struct clk_branch usb_hsic_h_clk = { .hw.init = &(struct clk_init_data){ .name = "usb_hsic_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2633,7 +2609,6 @@ static struct clk_branch sdc1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "sdc1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2649,7 +2624,6 @@ static struct clk_branch sdc2_h_clk = { .hw.init = &(struct clk_init_data){ .name = "sdc2_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2665,7 +2639,6 @@ static struct clk_branch sdc3_h_clk = { .hw.init = &(struct clk_init_data){ .name = "sdc3_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2681,7 +2654,6 @@ static struct clk_branch sdc4_h_clk = { .hw.init = &(struct clk_init_data){ .name = "sdc4_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2697,7 +2669,6 @@ static struct clk_branch sdc5_h_clk = { .hw.init = &(struct clk_init_data){ .name = "sdc5_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2712,7 +2683,6 @@ static struct clk_branch adm0_clk = { .hw.init = &(struct clk_init_data){ .name = "adm0_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2729,7 +2699,6 @@ static struct clk_branch adm0_pbus_clk = { .hw.init = &(struct clk_init_data){ .name = "adm0_pbus_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2883,7 +2852,6 @@ static struct clk_branch sata_a_clk = { .hw.init = &(struct clk_init_data){ .name = "sata_a_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2897,7 +2865,6 @@ static struct clk_branch sata_h_clk = { .hw.init = &(struct clk_init_data){ .name = "sata_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2911,7 +2878,6 @@ static struct clk_branch sfab_sata_s_h_clk = { .hw.init = &(struct clk_init_data){ .name = "sfab_sata_s_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2925,7 +2891,6 @@ static struct clk_branch sata_phy_cfg_clk = { .hw.init = &(struct clk_init_data){ .name = "sata_phy_cfg_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2939,7 +2904,6 @@ static struct clk_branch pcie_phy_ref_clk = { .hw.init = &(struct clk_init_data){ .name = "pcie_phy_ref_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2953,7 +2917,6 @@ static struct clk_branch pcie_h_clk = { .hw.init = &(struct clk_init_data){ .name = "pcie_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2967,7 +2930,6 @@ static struct clk_branch pcie_a_clk = { .hw.init = &(struct clk_init_data){ .name = "pcie_a_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2982,7 +2944,6 @@ static struct clk_branch pmic_arb0_h_clk = { .hw.init = &(struct clk_init_data){ .name = "pmic_arb0_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2997,7 +2958,6 @@ static struct clk_branch pmic_arb1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "pmic_arb1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -3012,7 +2972,6 @@ static struct clk_branch pmic_ssbi2_clk = { .hw.init = &(struct clk_init_data){ .name = "pmic_ssbi2_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -3029,7 +2988,6 @@ static struct clk_branch rpm_msg_ram_h_clk = { .hw.init = &(struct clk_init_data){ .name = "rpm_msg_ram_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; diff --git a/drivers/clk/qcom/gcc-msm8974.c b/drivers/clk/qcom/gcc-msm8974.c index 335952d..0091520 100644 --- a/drivers/clk/qcom/gcc-msm8974.c +++ b/drivers/clk/qcom/gcc-msm8974.c @@ -1965,7 +1965,6 @@ static struct clk_branch gcc_mss_q6_bimc_axi_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_mss_q6_bimc_axi_clk", - .flags = CLK_IS_ROOT, .ops = &clk_branch2_ops, }, }, diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c index bb8c61f..c9b96f3 100644 --- a/drivers/clk/qcom/gcc-msm8996.c +++ b/drivers/clk/qcom/gcc-msm8996.c @@ -1321,7 +1321,7 @@ static struct clk_branch gcc_mmss_bimc_gfx_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_mmss_bimc_gfx_clk", - .flags = CLK_SET_RATE_PARENT | CLK_IS_ROOT, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -2315,7 +2315,7 @@ static struct clk_branch gcc_bimc_gfx_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_bimc_gfx_clk", - .flags = CLK_SET_RATE_PARENT | CLK_IS_ROOT, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -2815,7 +2815,6 @@ static struct clk_branch gcc_ufs_sys_clk_core_clk = { .hw.init = &(struct clk_init_data){ .name = "gcc_ufs_sys_clk_core_clk", .ops = &clk_branch2_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2828,7 +2827,6 @@ static struct clk_branch gcc_ufs_tx_symbol_clk_core_clk = { .hw.init = &(struct clk_init_data){ .name = "gcc_ufs_tx_symbol_clk_core_clk", .ops = &clk_branch2_ops, - .flags = CLK_IS_ROOT, }, }, }; diff --git a/drivers/clk/qcom/mmcc-msm8960.c b/drivers/clk/qcom/mmcc-msm8960.c index 00e3619..7f21421 100644 --- a/drivers/clk/qcom/mmcc-msm8960.c +++ b/drivers/clk/qcom/mmcc-msm8960.c @@ -1789,7 +1789,6 @@ static struct clk_branch gmem_axi_clk = { .hw.init = &(struct clk_init_data){ .name = "gmem_axi_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1805,7 +1804,6 @@ static struct clk_branch ijpeg_axi_clk = { .hw.init = &(struct clk_init_data){ .name = "ijpeg_axi_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1821,7 +1819,6 @@ static struct clk_branch mmss_imem_axi_clk = { .hw.init = &(struct clk_init_data){ .name = "mmss_imem_axi_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1835,7 +1832,6 @@ static struct clk_branch jpegd_axi_clk = { .hw.init = &(struct clk_init_data){ .name = "jpegd_axi_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1851,7 +1847,6 @@ static struct clk_branch vcodec_axi_b_clk = { .hw.init = &(struct clk_init_data){ .name = "vcodec_axi_b_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1867,7 +1862,6 @@ static struct clk_branch vcodec_axi_a_clk = { .hw.init = &(struct clk_init_data){ .name = "vcodec_axi_a_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1883,7 +1877,6 @@ static struct clk_branch vcodec_axi_clk = { .hw.init = &(struct clk_init_data){ .name = "vcodec_axi_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1897,7 +1890,6 @@ static struct clk_branch vfe_axi_clk = { .hw.init = &(struct clk_init_data){ .name = "vfe_axi_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1913,7 +1905,6 @@ static struct clk_branch mdp_axi_clk = { .hw.init = &(struct clk_init_data){ .name = "mdp_axi_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1929,7 +1920,6 @@ static struct clk_branch rot_axi_clk = { .hw.init = &(struct clk_init_data){ .name = "rot_axi_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1945,7 +1935,6 @@ static struct clk_branch vcap_axi_clk = { .hw.init = &(struct clk_init_data){ .name = "vcap_axi_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1961,7 +1950,6 @@ static struct clk_branch vpe_axi_clk = { .hw.init = &(struct clk_init_data){ .name = "vpe_axi_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1977,7 +1965,6 @@ static struct clk_branch gfx3d_axi_clk = { .hw.init = &(struct clk_init_data){ .name = "gfx3d_axi_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1991,7 +1978,6 @@ static struct clk_branch amp_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "amp_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2005,7 +1991,6 @@ static struct clk_branch csi_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "csi_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT }, }, }; @@ -2019,7 +2004,6 @@ static struct clk_branch dsi_m_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "dsi_m_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2035,7 +2019,6 @@ static struct clk_branch dsi_s_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "dsi_s_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2049,7 +2032,6 @@ static struct clk_branch dsi2_m_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "dsi2_m_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT }, }, }; @@ -2065,7 +2047,6 @@ static struct clk_branch dsi2_s_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "dsi2_s_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2425,7 +2406,6 @@ static struct clk_branch gfx2d0_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "gfx2d0_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2441,7 +2421,6 @@ static struct clk_branch gfx2d1_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "gfx2d1_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2457,7 +2436,6 @@ static struct clk_branch gfx3d_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "gfx3d_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2473,7 +2451,6 @@ static struct clk_branch hdmi_m_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "hdmi_m_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2489,7 +2466,6 @@ static struct clk_branch hdmi_s_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "hdmi_s_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2503,7 +2479,6 @@ static struct clk_branch ijpeg_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "ijpeg_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT }, }, }; @@ -2519,7 +2494,6 @@ static struct clk_branch mmss_imem_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "mmss_imem_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT }, }, }; @@ -2533,7 +2507,6 @@ static struct clk_branch jpegd_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "jpegd_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2547,7 +2520,6 @@ static struct clk_branch mdp_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "mdp_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2561,7 +2533,6 @@ static struct clk_branch rot_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "rot_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT }, }, }; @@ -2577,7 +2548,6 @@ static struct clk_branch smmu_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "smmu_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2591,7 +2561,6 @@ static struct clk_branch tv_enc_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "tv_enc_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2605,7 +2574,6 @@ static struct clk_branch vcap_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "vcap_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2621,7 +2589,6 @@ static struct clk_branch vcodec_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "vcodec_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2635,7 +2602,6 @@ static struct clk_branch vfe_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "vfe_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2649,7 +2615,6 @@ static struct clk_branch vpe_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "vpe_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; -- cgit v0.10.2 From d3781a74bcc98c9c833d181676975075a50eb946 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 1 Mar 2016 11:00:12 -0800 Subject: clk: fixed-rate: Remove CLK_IS_ROOT This flag is a no-op now. Remove usage of the flag. Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk-fixed-rate.c b/drivers/clk/clk-fixed-rate.c index 6858bfc..cd9dc92 100644 --- a/drivers/clk/clk-fixed-rate.c +++ b/drivers/clk/clk-fixed-rate.c @@ -136,8 +136,7 @@ void of_fixed_clk_setup(struct device_node *node) of_property_read_string(node, "clock-output-names", &clk_name); clk = clk_register_fixed_rate_with_accuracy(NULL, clk_name, NULL, - CLK_IS_ROOT, rate, - accuracy); + 0, rate, accuracy); if (!IS_ERR(clk)) of_clk_add_provider(node, of_clk_src_simple_get, clk); } -- cgit v0.10.2 From 1295e36a488efdad9b21eb0aeabfd0b23a87a313 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Fri, 4 Mar 2016 09:18:41 -0800 Subject: clk: sunxi: Remove use of variable length array Using an array allocated on the stack may lead to stack overflows and other problems so let's move the allocation to the heap instead. This silences the following checker warning as well. drivers/clk/sunxi/clk-sun8i-mbus.c:36:29: warning: Variable length array is used Cc: Chen-Yu Tsai Acked-by: Maxime Ripard Signed-off-by: Stephen Boyd diff --git a/drivers/clk/sunxi/clk-sun8i-mbus.c b/drivers/clk/sunxi/clk-sun8i-mbus.c index 3aaa9cb..411d303 100644 --- a/drivers/clk/sunxi/clk-sun8i-mbus.c +++ b/drivers/clk/sunxi/clk-sun8i-mbus.c @@ -33,7 +33,7 @@ static DEFINE_SPINLOCK(sun8i_a23_mbus_lock); static void __init sun8i_a23_mbus_setup(struct device_node *node) { int num_parents = of_clk_get_parent_count(node); - const char *parents[num_parents]; + const char **parents; const char *clk_name = node->name; struct resource res; struct clk_divider *div; @@ -43,10 +43,14 @@ static void __init sun8i_a23_mbus_setup(struct device_node *node) void __iomem *reg; int err; + parents = kcalloc(num_parents, sizeof(*parents), GFP_KERNEL); + if (!parents) + return; + reg = of_io_request_and_map(node, 0, of_node_full_name(node)); if (!reg) { pr_err("Could not get registers for sun8i-mbus-clk\n"); - return; + goto err_free_parents; } div = kzalloc(sizeof(*div), GFP_KERNEL); @@ -90,6 +94,7 @@ static void __init sun8i_a23_mbus_setup(struct device_node *node) if (err) goto err_unregister_clk; + kfree(parents); /* parents is deep copied */ /* The MBUS clocks needs to be always enabled */ __clk_get(clk); clk_prepare_enable(clk); @@ -109,5 +114,7 @@ err_unmap: iounmap(reg); of_address_to_resource(node, 0, &res); release_mem_region(res.start, resource_size(&res)); +err_free_parents: + kfree(parents); } CLK_OF_DECLARE(sun8i_a23_mbus, "allwinner,sun8i-a23-mbus-clk", sun8i_a23_mbus_setup); -- cgit v0.10.2 From ac82a8b5073631940b989c973f77fbaddd2526d0 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 1 Mar 2016 11:00:05 -0800 Subject: clk: versatile: Remove CLK_IS_ROOT This flag is a no-op now. Remove usage of the flag. Cc: Pawel Moll Acked-by: Linus Walleij Signed-off-by: Stephen Boyd diff --git a/drivers/clk/versatile/clk-icst.c b/drivers/clk/versatile/clk-icst.c index 3bca438..5e9b652 100644 --- a/drivers/clk/versatile/clk-icst.c +++ b/drivers/clk/versatile/clk-icst.c @@ -170,7 +170,7 @@ static struct clk *icst_clk_setup(struct device *dev, init.name = name; init.ops = &icst_ops; - init.flags = CLK_IS_ROOT; + init.flags = 0; init.parent_names = (parent_name ? &parent_name : NULL); init.num_parents = (parent_name ? 1 : 0); icst->map = map; diff --git a/drivers/clk/versatile/clk-impd1.c b/drivers/clk/versatile/clk-impd1.c index 65c842a..74c3216 100644 --- a/drivers/clk/versatile/clk-impd1.c +++ b/drivers/clk/versatile/clk-impd1.c @@ -98,8 +98,7 @@ void integrator_impd1_clk_init(void __iomem *base, unsigned int id) /* Register the fixed rate PCLK */ imc->pclkname = kasprintf(GFP_KERNEL, "lm%x-pclk", id); - pclk = clk_register_fixed_rate(NULL, imc->pclkname, NULL, - CLK_IS_ROOT, 0); + pclk = clk_register_fixed_rate(NULL, imc->pclkname, NULL, 0, 0); imc->pclk = pclk; imc->vco1name = kasprintf(GFP_KERNEL, "lm%x-vco1", id); diff --git a/drivers/clk/versatile/clk-realview.c b/drivers/clk/versatile/clk-realview.c index bd4dd24..c56efc7 100644 --- a/drivers/clk/versatile/clk-realview.c +++ b/drivers/clk/versatile/clk-realview.c @@ -56,12 +56,11 @@ void __init realview_clk_init(void __iomem *sysbase, bool is_pb1176) struct clk *clk; /* APB clock dummy */ - clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, 0); + clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, 0, 0); clk_register_clkdev(clk, "apb_pclk", NULL); /* 24 MHz clock */ - clk = clk_register_fixed_rate(NULL, "clk24mhz", NULL, CLK_IS_ROOT, - 24000000); + clk = clk_register_fixed_rate(NULL, "clk24mhz", NULL, 0, 24000000); clk_register_clkdev(clk, NULL, "dev:uart0"); clk_register_clkdev(clk, NULL, "dev:uart1"); clk_register_clkdev(clk, NULL, "dev:uart2"); @@ -81,8 +80,7 @@ void __init realview_clk_init(void __iomem *sysbase, bool is_pb1176) /* 1 MHz clock */ - clk = clk_register_fixed_rate(NULL, "clk1mhz", NULL, CLK_IS_ROOT, - 1000000); + clk = clk_register_fixed_rate(NULL, "clk1mhz", NULL, 0, 1000000); clk_register_clkdev(clk, NULL, "sp804"); /* ICST VCO clock */ diff --git a/drivers/clk/versatile/clk-vexpress-osc.c b/drivers/clk/versatile/clk-vexpress-osc.c index 89c0609..7e5add7 100644 --- a/drivers/clk/versatile/clk-vexpress-osc.c +++ b/drivers/clk/versatile/clk-vexpress-osc.c @@ -94,7 +94,7 @@ static int vexpress_osc_probe(struct platform_device *pdev) init.name = dev_name(&pdev->dev); init.ops = &vexpress_osc_ops; - init.flags = CLK_IS_ROOT; + init.flags = 0; init.num_parents = 0; osc->hw.init = &init; -- cgit v0.10.2 From 4c9462b434f299097ac49ef2bf1f7321699fe109 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 1 Mar 2016 11:00:14 -0800 Subject: clk: max77{686,802}: Remove CLK_IS_ROOT This flag is a no-op now. Remove usage of the flag. Reviewed-by: Javier Martinez Canillas Signed-off-by: Stephen Boyd diff --git a/drivers/clk/clk-max77686.c b/drivers/clk/clk-max77686.c index 446c2fe..9b6f277 100644 --- a/drivers/clk/clk-max77686.c +++ b/drivers/clk/clk-max77686.c @@ -38,17 +38,14 @@ static struct clk_init_data max77686_clks_init[MAX77686_CLKS_NUM] = { [MAX77686_CLK_AP] = { .name = "32khz_ap", .ops = &max_gen_clk_ops, - .flags = CLK_IS_ROOT, }, [MAX77686_CLK_CP] = { .name = "32khz_cp", .ops = &max_gen_clk_ops, - .flags = CLK_IS_ROOT, }, [MAX77686_CLK_PMIC] = { .name = "32khz_pmic", .ops = &max_gen_clk_ops, - .flags = CLK_IS_ROOT, }, }; diff --git a/drivers/clk/clk-max77802.c b/drivers/clk/clk-max77802.c index 4a89f79..355dd2e 100644 --- a/drivers/clk/clk-max77802.c +++ b/drivers/clk/clk-max77802.c @@ -39,12 +39,10 @@ static struct clk_init_data max77802_clks_init[MAX77802_CLKS_NUM] = { [MAX77802_CLK_32K_AP] = { .name = "32khz_ap", .ops = &max_gen_clk_ops, - .flags = CLK_IS_ROOT, }, [MAX77802_CLK_32K_CP] = { .name = "32khz_cp", .ops = &max_gen_clk_ops, - .flags = CLK_IS_ROOT, }, }; -- cgit v0.10.2 From 09c32427c9e9e861e5aeaf9e08ba0b4a3cfca917 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Tue, 8 Mar 2016 09:42:07 +0900 Subject: clk: renesas: Rename header file renesas.h This is part of an ongoing process to migrate from ARCH_SHMOBILE to ARCH_RENESAS the motivation for which being that RENESAS seems to be a more appropriate name than SHMOBILE for the majority of Renesas ARM based SoCs. Along with the above mentioned Kconfig changes it seems appropriate to also rename files. Signed-off-by: Simon Horman Acked-by: Geert Uytterhoeven Signed-off-by: Stephen Boyd diff --git a/arch/arm/mach-shmobile/pm-rmobile.c b/arch/arm/mach-shmobile/pm-rmobile.c index 46d0a1d..c0b05e9 100644 --- a/arch/arm/mach-shmobile/pm-rmobile.c +++ b/arch/arm/mach-shmobile/pm-rmobile.c @@ -12,7 +12,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. */ -#include +#include #include #include #include diff --git a/arch/arm/mach-shmobile/setup-r8a7778.c b/arch/arm/mach-shmobile/setup-r8a7778.c index fab95d1..cf236db 100644 --- a/arch/arm/mach-shmobile/setup-r8a7778.c +++ b/arch/arm/mach-shmobile/setup-r8a7778.c @@ -15,7 +15,7 @@ * GNU General Public License for more details. */ -#include +#include #include #include diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c index 1e572a9..0007ff5 100644 --- a/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/arch/arm/mach-shmobile/setup-r8a7779.c @@ -14,7 +14,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ -#include +#include #include #include #include diff --git a/arch/arm/mach-shmobile/setup-rcar-gen2.c b/arch/arm/mach-shmobile/setup-rcar-gen2.c index 9eccde3..949b402 100644 --- a/arch/arm/mach-shmobile/setup-rcar-gen2.c +++ b/arch/arm/mach-shmobile/setup-rcar-gen2.c @@ -15,7 +15,7 @@ * GNU General Public License for more details. */ -#include +#include #include #include #include diff --git a/drivers/clk/renesas/clk-mstp.c b/drivers/clk/renesas/clk-mstp.c index 3b09716..3d44e18 100644 --- a/drivers/clk/renesas/clk-mstp.c +++ b/drivers/clk/renesas/clk-mstp.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/clk/renesas/clk-r8a73a4.c b/drivers/clk/renesas/clk-r8a73a4.c index 9326204..28d204b 100644 --- a/drivers/clk/renesas/clk-r8a73a4.c +++ b/drivers/clk/renesas/clk-r8a73a4.c @@ -9,7 +9,7 @@ */ #include -#include +#include #include #include #include diff --git a/drivers/clk/renesas/clk-r8a7740.c b/drivers/clk/renesas/clk-r8a7740.c index 1e6b1da..2f7ce66 100644 --- a/drivers/clk/renesas/clk-r8a7740.c +++ b/drivers/clk/renesas/clk-r8a7740.c @@ -9,7 +9,7 @@ */ #include -#include +#include #include #include #include diff --git a/drivers/clk/renesas/clk-r8a7778.c b/drivers/clk/renesas/clk-r8a7778.c index b174155..40e3a50 100644 --- a/drivers/clk/renesas/clk-r8a7778.c +++ b/drivers/clk/renesas/clk-r8a7778.c @@ -9,7 +9,7 @@ */ #include -#include +#include #include #include diff --git a/drivers/clk/renesas/clk-r8a7779.c b/drivers/clk/renesas/clk-r8a7779.c index 92275c5f..cf2a37d 100644 --- a/drivers/clk/renesas/clk-r8a7779.c +++ b/drivers/clk/renesas/clk-r8a7779.c @@ -11,7 +11,7 @@ */ #include -#include +#include #include #include #include diff --git a/drivers/clk/renesas/clk-rcar-gen2.c b/drivers/clk/renesas/clk-rcar-gen2.c index 8419772..00e6aba 100644 --- a/drivers/clk/renesas/clk-rcar-gen2.c +++ b/drivers/clk/renesas/clk-rcar-gen2.c @@ -11,7 +11,7 @@ */ #include -#include +#include #include #include #include diff --git a/drivers/clk/renesas/clk-rz.c b/drivers/clk/renesas/clk-rz.c index 9766e3c..f6312c6 100644 --- a/drivers/clk/renesas/clk-rz.c +++ b/drivers/clk/renesas/clk-rz.c @@ -10,7 +10,7 @@ */ #include -#include +#include #include #include #include diff --git a/drivers/clk/renesas/clk-sh73a0.c b/drivers/clk/renesas/clk-sh73a0.c index 8966f8b..eea38f6 100644 --- a/drivers/clk/renesas/clk-sh73a0.c +++ b/drivers/clk/renesas/clk-sh73a0.c @@ -9,7 +9,7 @@ */ #include -#include +#include #include #include #include diff --git a/include/linux/clk/renesas.h b/include/linux/clk/renesas.h new file mode 100644 index 0000000..7adfd80 --- /dev/null +++ b/include/linux/clk/renesas.h @@ -0,0 +1,35 @@ +/* + * Copyright 2013 Ideas On Board SPRL + * Copyright 2013, 2014 Horms Solutions Ltd. + * + * Contact: Laurent Pinchart + * Contact: Simon Horman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __LINUX_CLK_RENESAS_H_ +#define __LINUX_CLK_RENESAS_H_ + +#include + +struct device; +struct device_node; +struct generic_pm_domain; + +void r8a7778_clocks_init(u32 mode); +void r8a7779_clocks_init(u32 mode); +void rcar_gen2_clocks_init(u32 mode); + +#ifdef CONFIG_PM_GENERIC_DOMAINS_OF +void cpg_mstp_add_clk_domain(struct device_node *np); +int cpg_mstp_attach_dev(struct generic_pm_domain *domain, struct device *dev); +void cpg_mstp_detach_dev(struct generic_pm_domain *domain, struct device *dev); +#else +static inline void cpg_mstp_add_clk_domain(struct device_node *np) {} +#endif + +#endif diff --git a/include/linux/clk/shmobile.h b/include/linux/clk/shmobile.h deleted file mode 100644 index cb19cc1..0000000 --- a/include/linux/clk/shmobile.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2013 Ideas On Board SPRL - * Copyright 2013, 2014 Horms Solutions Ltd. - * - * Contact: Laurent Pinchart - * Contact: Simon Horman - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#ifndef __LINUX_CLK_SHMOBILE_H_ -#define __LINUX_CLK_SHMOBILE_H_ - -#include - -struct device; -struct device_node; -struct generic_pm_domain; - -void r8a7778_clocks_init(u32 mode); -void r8a7779_clocks_init(u32 mode); -void rcar_gen2_clocks_init(u32 mode); - -#ifdef CONFIG_PM_GENERIC_DOMAINS_OF -void cpg_mstp_add_clk_domain(struct device_node *np); -int cpg_mstp_attach_dev(struct generic_pm_domain *domain, struct device *dev); -void cpg_mstp_detach_dev(struct generic_pm_domain *domain, struct device *dev); -#else -static inline void cpg_mstp_add_clk_domain(struct device_node *np) {} -#endif - -#endif -- cgit v0.10.2 From e8087b5b90b2aa0a307e57e1a209a91d60da268b Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Tue, 8 Mar 2016 09:48:55 +0900 Subject: clk: renesas: div6: use RENESAS for #define Name the #define guarding compilation of this header __RENESAS_CLK_DIV6_H__ rather than __SHMOBILE_CLK_DIV6_H__. This is a follow-up to renaming the directory in which this file lives from shmobile to renesas which is in turn part of an ongoing process to migrate from ARCH_SHMOBILE to ARCH_RENESAS the motivation for which being that RENESAS seems to be a more appropriate name than SHMOBILE for the majority of Renesas ARM based SoCs. Signed-off-by: Simon Horman Acked-by: Geert Uytterhoeven Signed-off-by: Stephen Boyd diff --git a/drivers/clk/renesas/clk-div6.h b/drivers/clk/renesas/clk-div6.h index 9a85a95..567b31d 100644 --- a/drivers/clk/renesas/clk-div6.h +++ b/drivers/clk/renesas/clk-div6.h @@ -1,5 +1,5 @@ -#ifndef __SHMOBILE_CLK_DIV6_H__ -#define __SHMOBILE_CLK_DIV6_H__ +#ifndef __RENESAS_CLK_DIV6_H__ +#define __RENESAS_CLK_DIV6_H__ struct clk *cpg_div6_register(const char *name, unsigned int num_parents, const char **parent_names, void __iomem *reg); -- cgit v0.10.2 From 4d3ac6662452060721599a3392bc2f524af984cb Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Sun, 6 Mar 2016 03:21:35 +0200 Subject: clk: bcm2835: fix check of error code returned by devm_ioremap_resource() The change fixes potential oops while accessing iomem on invalid address, if devm_ioremap_resource() fails due to some reason. The devm_ioremap_resource() function returns ERR_PTR() and never returns NULL, which makes useless a following check for NULL. Signed-off-by: Vladimir Zapolskiy Fixes: 5e63dcc74b30 ("clk: bcm2835: Add a driver for the auxiliary peripheral clock gates") Reviewed-by: Eric Anholt Signed-off-by: Stephen Boyd diff --git a/drivers/clk/bcm/clk-bcm2835-aux.c b/drivers/clk/bcm/clk-bcm2835-aux.c index e4f89e2..3a177ad 100644 --- a/drivers/clk/bcm/clk-bcm2835-aux.c +++ b/drivers/clk/bcm/clk-bcm2835-aux.c @@ -38,8 +38,8 @@ static int bcm2835_aux_clk_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); reg = devm_ioremap_resource(dev, res); - if (!reg) - return -ENODEV; + if (IS_ERR(reg)) + return PTR_ERR(reg); onecell = devm_kmalloc(dev, sizeof(*onecell), GFP_KERNEL); if (!onecell) -- cgit v0.10.2