Hi everyone,
This is v4 of the sun8i clock series, which adds basic clock
support for the A23 SoC. It is based on my initial sun8i bring
up series [1]. This series was split up from the original A23
series [2]. Yet to come are more clocks, reset controllers,
prcm, pinctrl, and mmc.
The first patch fixes the reworked clock protection code merged in
3.16-rc1, which unintentionally made clock gates unprotectable.
The second patch moves the remaining "ahb_sdram" clock to the
protected clock list, now that it works.
The third patch adds support for factor clocks that have an N factor
not starting from 0. This is found on some PLLs in A31/A23.
The fourth patch adds table-based dividers for div clocks, as some
clocks, such as apb0 divider on sun4/5/7i, apb1 on sun6/8i and axi
on sun8i.
The fifth patch adds support for the basic clocks in the A23, just
PLL1 for cpus, and the system bus clocks and gates.
The last patch adds the DT nodes for the newly added clocks, and
updates clock phandles for existing peripherals, the uarts.
Originally I intended for patch 1 to be merged as a fix for 3.16.
However, the only user of the affected code, sun6i's "ahb1_sdram"
clock, doesn't seem to result in any runtime issues. So this whole
series can go into 3.17.
Related changes since v3:
- Dropped fields with default values from sun8i_a23_axi_div_data
- Added Maxime's Acked-by
- Fixed incorrect compatible string for axi clock node
- Updated clock phandles for uarts in dtsi
Related changes since v2:
- Rewrote factor clocks to support any (0~255) N factor starting value
Related changes since v1:
- Added "clk: sunxi: Add support for table-based divider clocks"
- Added table-based divider axi clock
- Fixed incorrectly squashed fixups
Cheers
ChenYu
[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2014-June/265211.html
[2] http://lists.infradead.org/pipermail/linux-arm-kernel/2014-May/259097.html
Chen-Yu Tsai (6):
clk: sunxi: register clock gates with clkdev
clk: sunxi: move "ahb_sdram" to protected clock list
clk: sunxi: Support factor clocks with N factor starting not from 0
clk: sunxi: Add support for table-based divider clocks
clk: sunxi: Add A23 clocks support
ARM: sun8i: Add basic clock nodes to the DTSI
Documentation/devicetree/bindings/clock/sunxi.txt | 5 +
arch/arm/boot/dts/sun8i-a23.dtsi | 125 +++++++++++++++++++++-
drivers/clk/sunxi/clk-factors.c | 2 +-
drivers/clk/sunxi/clk-factors.h | 1 +
drivers/clk/sunxi/clk-sunxi.c | 119 ++++++++++++++++++--
5 files changed, 237 insertions(+), 15 deletions(-)
--
2.0.0
The new important clock protect code requires the clocks be
registered with clkdev. This was missing for sunxi_gates
type clocks.
Signed-off-by: Chen-Yu Tsai <[email protected]>
Acked-by: Maxime Ripard <[email protected]>
---
drivers/clk/sunxi/clk-sunxi.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index fb2ce84..e43ed6a 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -899,6 +899,7 @@ static void __init sunxi_gates_clk_setup(struct device_node *node,
reg + 4 * (i/32), i % 32,
0, &clk_lock);
WARN_ON(IS_ERR(clk_data->clks[i]));
+ clk_register_clkdev(clk_data->clks[i], clk_name, NULL);
j++;
}
--
2.0.0
A few of the clock modules have odd dividers, such as
the 2 lowest dividers being the same (2), or have the
same divider when the highest bit is set.
This patch adds support for optional divider tables,
so the clock framework will know about the odd values.
Signed-off-by: Chen-Yu Tsai <[email protected]>
Acked-by: Maxime Ripard <[email protected]>
---
drivers/clk/sunxi/clk-sunxi.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index a38c799..6fe9492 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -664,6 +664,7 @@ struct div_data {
u8 shift;
u8 pow;
u8 width;
+ const struct clk_div_table *table;
};
static const struct div_data sun4i_axi_data __initconst = {
@@ -704,10 +705,10 @@ static void __init sunxi_divider_clk_setup(struct device_node *node,
of_property_read_string(node, "clock-output-names", &clk_name);
- clk = clk_register_divider(NULL, clk_name, clk_parent, 0,
- reg, data->shift, data->width,
- data->pow ? CLK_DIVIDER_POWER_OF_TWO : 0,
- &clk_lock);
+ 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);
clk_register_clkdev(clk, clk_name, NULL);
--
2.0.0
Now that we have support for sun8i specific clocks in the driver,
add the corresponding clock nodes to the DTSI. Also update the
existing peripherals with the correct clocks.
Signed-off-by: Chen-Yu Tsai <[email protected]>
---
arch/arm/boot/dts/sun8i-a23.dtsi | 125 +++++++++++++++++++++++++++++++++++++--
1 file changed, 120 insertions(+), 5 deletions(-)
diff --git a/arch/arm/boot/dts/sun8i-a23.dtsi b/arch/arm/boot/dts/sun8i-a23.dtsi
index ac5f69a..79c4083 100644
--- a/arch/arm/boot/dts/sun8i-a23.dtsi
+++ b/arch/arm/boot/dts/sun8i-a23.dtsi
@@ -64,6 +64,121 @@
clock-frequency = <32768>;
clock-output-names = "osc32k";
};
+
+ pll1: clk@01c20000 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun8i-a23-pll1-clk";
+ reg = <0x01c20000 0x4>;
+ clocks = <&osc24M>;
+ clock-output-names = "pll1";
+ };
+
+ /* dummy clock until actually implemented */
+ pll6: pll6_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <600000000>;
+ clock-output-names = "pll6";
+ };
+
+ cpu: cpu_clk@01c20050 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-cpu-clk";
+ reg = <0x01c20050 0x4>;
+
+ /*
+ * PLL1 is listed twice here.
+ * While it looks suspicious, it's actually documented
+ * that way both in the datasheet and in the code from
+ * Allwinner.
+ */
+ clocks = <&osc32k>, <&osc24M>, <&pll1>, <&pll1>;
+ clock-output-names = "cpu";
+ };
+
+ axi: axi_clk@01c20050 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun8i-a23-axi-clk";
+ reg = <0x01c20050 0x4>;
+ clocks = <&cpu>;
+ clock-output-names = "axi";
+ };
+
+ ahb1_mux: ahb1_mux_clk@01c20054 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun6i-a31-ahb1-mux-clk";
+ reg = <0x01c20054 0x4>;
+ clocks = <&osc32k>, <&osc24M>, <&axi>, <&pll6>;
+ clock-output-names = "ahb1_mux";
+ };
+
+ ahb1: ahb1_clk@01c20054 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-ahb-clk";
+ reg = <0x01c20054 0x4>;
+ clocks = <&ahb1_mux>;
+ clock-output-names = "ahb1";
+ };
+
+ apb1: apb1_clk@01c20054 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-apb0-clk";
+ reg = <0x01c20054 0x4>;
+ clocks = <&ahb1>;
+ clock-output-names = "apb1";
+ };
+
+ ahb1_gates: clk@01c20060 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun8i-a23-ahb1-gates-clk";
+ reg = <0x01c20060 0x8>;
+ clocks = <&ahb1>;
+ clock-output-names = "ahb1_mipidsi", "ahb1_dma",
+ "ahb1_mmc0", "ahb1_mmc1", "ahb1_mmc2",
+ "ahb1_nand", "ahb1_sdram",
+ "ahb1_hstimer", "ahb1_spi0",
+ "ahb1_spi1", "ahb1_otg", "ahb1_ehci",
+ "ahb1_ohci", "ahb1_ve", "ahb1_lcd",
+ "ahb1_csi", "ahb1_be", "ahb1_fe",
+ "ahb1_gpu", "ahb1_spinlock",
+ "ahb1_drc";
+ };
+
+ apb1_gates: clk@01c20068 {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun8i-a23-apb1-gates-clk";
+ reg = <0x01c20068 0x4>;
+ clocks = <&apb1>;
+ clock-output-names = "apb1_codec", "apb1_pio",
+ "apb1_daudio0", "apb1_daudio1";
+ };
+
+ apb2_mux: apb2_mux_clk@01c20058 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun4i-a10-apb1-mux-clk";
+ reg = <0x01c20058 0x4>;
+ clocks = <&osc32k>, <&osc24M>, <&pll6>, <&pll6>;
+ clock-output-names = "apb2_mux";
+ };
+
+ apb2: apb2_clk@01c20058 {
+ #clock-cells = <0>;
+ compatible = "allwinner,sun6i-a31-apb2-div-clk";
+ reg = <0x01c20058 0x4>;
+ clocks = <&apb2_mux>;
+ clock-output-names = "apb2";
+ };
+
+ apb2_gates: clk@01c2006c {
+ #clock-cells = <1>;
+ compatible = "allwinner,sun8i-a23-apb2-gates-clk";
+ reg = <0x01c2006c 0x4>;
+ clocks = <&apb2>;
+ clock-output-names = "apb2_i2c0", "apb2_i2c1",
+ "apb2_i2c2", "apb2_uart0",
+ "apb2_uart1", "apb2_uart2",
+ "apb2_uart3", "apb2_uart4";
+ };
};
soc@01c00000 {
@@ -92,7 +207,7 @@
interrupts = <0 0 4>;
reg-shift = <2>;
reg-io-width = <4>;
- clocks = <&osc24M>;
+ clocks = <&apb2_gates 16>;
status = "disabled";
};
@@ -102,7 +217,7 @@
interrupts = <0 1 4>;
reg-shift = <2>;
reg-io-width = <4>;
- clocks = <&osc24M>;
+ clocks = <&apb2_gates 17>;
status = "disabled";
};
@@ -112,7 +227,7 @@
interrupts = <0 2 4>;
reg-shift = <2>;
reg-io-width = <4>;
- clocks = <&osc24M>;
+ clocks = <&apb2_gates 18>;
status = "disabled";
};
@@ -122,7 +237,7 @@
interrupts = <0 3 4>;
reg-shift = <2>;
reg-io-width = <4>;
- clocks = <&osc24M>;
+ clocks = <&apb2_gates 19>;
status = "disabled";
};
@@ -132,7 +247,7 @@
interrupts = <0 4 4>;
reg-shift = <2>;
reg-io-width = <4>;
- clocks = <&osc24M>;
+ clocks = <&apb2_gates 20>;
status = "disabled";
};
--
2.0.0
The clock control unit on the A23 is similar to the one found on the A31.
The AHB1, APB1, APB2 gates on the A23 are almost identical to the ones
on the A31, but some outputs are missing.
The main CPU PLL (PLL1) however is like that on older Allwinner SoCs,
such as the A10 or A20, but the N factor starts from 1 instead of 0.
This patch adds support for PLL1 and all the basic clock muxes and gates.
Signed-off-by: Chen-Yu Tsai <[email protected]>
Acked-by: Maxime Ripard <[email protected]>
---
Documentation/devicetree/bindings/clock/sunxi.txt | 5 ++
drivers/clk/sunxi/clk-sunxi.c | 101 ++++++++++++++++++++++
2 files changed, 106 insertions(+)
diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
index b9ec668..18030ce 100644
--- a/Documentation/devicetree/bindings/clock/sunxi.txt
+++ b/Documentation/devicetree/bindings/clock/sunxi.txt
@@ -9,11 +9,13 @@ Required properties:
"allwinner,sun4i-a10-osc-clk" - for a gatable oscillator
"allwinner,sun4i-a10-pll1-clk" - for the main PLL clock and PLL4
"allwinner,sun6i-a31-pll1-clk" - for the main PLL clock on A31
+ "allwinner,sun8i-a23-pll1-clk" - for the main PLL clock on A23
"allwinner,sun4i-a10-pll5-clk" - for the PLL5 clock
"allwinner,sun4i-a10-pll6-clk" - for the PLL6 clock
"allwinner,sun6i-a31-pll6-clk" - for the PLL6 clock on A31
"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-axi-gates-clk" - for the AXI gates
"allwinner,sun4i-a10-ahb-clk" - for the AHB clock
"allwinner,sun4i-a10-ahb-gates-clk" - for the AHB gates on A10
@@ -23,6 +25,7 @@ Required properties:
"allwinner,sun6i-a31-ar100-clk" - for the AR100 on A31
"allwinner,sun6i-a31-ahb1-mux-clk" - for the AHB1 multiplexer on A31
"allwinner,sun6i-a31-ahb1-gates-clk" - for the AHB1 gates on A31
+ "allwinner,sun8i-a23-ahb1-gates-clk" - for the AHB1 gates on A23
"allwinner,sun4i-a10-apb0-clk" - for the APB0 clock
"allwinner,sun6i-a31-apb0-clk" - for the APB0 clock on A31
"allwinner,sun4i-a10-apb0-gates-clk" - for the APB0 gates on A10
@@ -37,8 +40,10 @@ Required properties:
"allwinner,sun5i-a10s-apb1-gates-clk" - for the APB1 gates on A10s
"allwinner,sun6i-a31-apb1-gates-clk" - for the APB1 gates on A31
"allwinner,sun7i-a20-apb1-gates-clk" - for the APB1 gates on A20
+ "allwinner,sun8i-a23-apb1-gates-clk" - for the APB1 gates on A23
"allwinner,sun6i-a31-apb2-div-clk" - for the APB2 gates on A31
"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,sun4i-a10-mod0-clk" - for the module 0 family of clocks
"allwinner,sun7i-a20-out-clk" - for the external output clocks
"allwinner,sun7i-a20-gmac-clk" - for the GMAC clock module on A20/A31
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 6fe9492..8975972 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -164,6 +164,54 @@ static void sun6i_a31_get_pll1_factors(u32 *freq, u32 parent_rate,
}
/**
+ * sun8i_a23_get_pll1_factors() - calculates n, k, m, p factors for PLL1
+ * PLL1 rate is calculated as follows
+ * rate = (parent_rate * (n + 1) * (k + 1) >> p) / (m + 1);
+ * 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)
+{
+ 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;
+
+ /* m is always zero for pll1 */
+ *m = 0;
+
+ /* k is 1 only on these cases */
+ if (*freq >= 768000000 || *freq == 42000000 || *freq == 54000000)
+ *k = 1;
+ else
+ *k = 0;
+
+ /* p will be 2 for divs under 20 and odd divs under 32 */
+ if (div < 20 || (div < 32 && (div & 1)))
+ *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;
+
+ /* any other entries have p = 0 */
+ else
+ *p = 0;
+
+ /* calculate a suitable n based on k and p */
+ div <<= *p;
+ div /= (*k + 1);
+ *n = div / 4 - 1;
+}
+
+/**
* sun4i_get_pll5_factors() - calculates n, k factors for PLL5
* PLL5 rate is calculated as follows
* rate = parent_rate * n * (k + 1)
@@ -422,6 +470,18 @@ static struct clk_factors_config sun6i_a31_pll1_config = {
.mwidth = 2,
};
+static struct clk_factors_config sun8i_a23_pll1_config = {
+ .nshift = 8,
+ .nwidth = 5,
+ .kshift = 4,
+ .kwidth = 2,
+ .mshift = 0,
+ .mwidth = 2,
+ .pshift = 16,
+ .pwidth = 2,
+ .n_start = 1,
+};
+
static struct clk_factors_config sun4i_pll5_config = {
.nshift = 8,
.nwidth = 5,
@@ -471,6 +531,12 @@ static const struct factors_data sun6i_a31_pll1_data __initconst = {
.getter = sun6i_a31_get_pll1_factors,
};
+static const struct factors_data sun8i_a23_pll1_data __initconst = {
+ .enable = 31,
+ .table = &sun8i_a23_pll1_config,
+ .getter = sun8i_a23_get_pll1_factors,
+};
+
static const struct factors_data sun7i_a20_pll4_data __initconst = {
.enable = 31,
.table = &sun4i_pll5_config,
@@ -673,6 +739,23 @@ static const struct div_data sun4i_axi_data __initconst = {
.width = 2,
};
+static const struct clk_div_table sun8i_a23_axi_table[] __initconst = {
+ { .val = 0, .div = 1 },
+ { .val = 1, .div = 2 },
+ { .val = 2, .div = 3 },
+ { .val = 3, .div = 4 },
+ { .val = 4, .div = 4 },
+ { .val = 5, .div = 4 },
+ { .val = 6, .div = 4 },
+ { .val = 7, .div = 4 },
+ { } /* sentinel */
+};
+
+static const struct div_data sun8i_a23_axi_data __initconst = {
+ .width = 3,
+ .table = sun8i_a23_axi_table,
+};
+
static const struct div_data sun4i_ahb_data __initconst = {
.shift = 4,
.pow = 1,
@@ -805,6 +888,10 @@ static const struct gates_data sun7i_a20_ahb_gates_data __initconst = {
.mask = { 0x12f77fff, 0x16ff3f },
};
+static const struct gates_data sun8i_a23_ahb1_gates_data __initconst = {
+ .mask = {0x25386742, 0x2505111},
+};
+
static const struct gates_data sun4i_apb0_gates_data __initconst = {
.mask = {0x4EF},
};
@@ -837,6 +924,10 @@ static const struct gates_data sun6i_a31_apb1_gates_data __initconst = {
.mask = {0x3031},
};
+static const struct gates_data sun8i_a23_apb1_gates_data __initconst = {
+ .mask = {0x3021},
+};
+
static const struct gates_data sun6i_a31_apb2_gates_data __initconst = {
.mask = {0x3F000F},
};
@@ -845,6 +936,10 @@ static const struct gates_data sun7i_a20_apb1_gates_data __initconst = {
.mask = { 0xff80ff },
};
+static const struct gates_data sun8i_a23_apb2_gates_data __initconst = {
+ .mask = {0x1F0007},
+};
+
static const struct gates_data sun4i_a10_usb_gates_data __initconst = {
.mask = {0x1C0},
.reset_mask = 0x07,
@@ -1100,6 +1195,7 @@ free_clkdata:
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,sun6i-a31-pll6-clk", .data = &sun6i_a31_pll6_data,},
{.compatible = "allwinner,sun4i-a10-apb1-clk", .data = &sun4i_apb1_data,},
@@ -1111,6 +1207,7 @@ static const struct of_device_id clk_factors_match[] __initconst = {
/* 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,},
{.compatible = "allwinner,sun6i-a31-apb2-div-clk", .data = &sun6i_a31_apb2_div_data,},
@@ -1140,6 +1237,7 @@ static const struct of_device_id clk_gates_match[] __initconst = {
{.compatible = "allwinner,sun5i-a13-ahb-gates-clk", .data = &sun5i_a13_ahb_gates_data,},
{.compatible = "allwinner,sun6i-a31-ahb1-gates-clk", .data = &sun6i_a31_ahb1_gates_data,},
{.compatible = "allwinner,sun7i-a20-ahb-gates-clk", .data = &sun7i_a20_ahb_gates_data,},
+ {.compatible = "allwinner,sun8i-a23-ahb1-gates-clk", .data = &sun8i_a23_ahb1_gates_data,},
{.compatible = "allwinner,sun4i-a10-apb0-gates-clk", .data = &sun4i_apb0_gates_data,},
{.compatible = "allwinner,sun5i-a10s-apb0-gates-clk", .data = &sun5i_a10s_apb0_gates_data,},
{.compatible = "allwinner,sun5i-a13-apb0-gates-clk", .data = &sun5i_a13_apb0_gates_data,},
@@ -1149,7 +1247,9 @@ static const struct of_device_id clk_gates_match[] __initconst = {
{.compatible = "allwinner,sun5i-a13-apb1-gates-clk", .data = &sun5i_a13_apb1_gates_data,},
{.compatible = "allwinner,sun6i-a31-apb1-gates-clk", .data = &sun6i_a31_apb1_gates_data,},
{.compatible = "allwinner,sun7i-a20-apb1-gates-clk", .data = &sun7i_a20_apb1_gates_data,},
+ {.compatible = "allwinner,sun8i-a23-apb1-gates-clk", .data = &sun8i_a23_apb1_gates_data,},
{.compatible = "allwinner,sun6i-a31-apb2-gates-clk", .data = &sun6i_a31_apb2_gates_data,},
+ {.compatible = "allwinner,sun8i-a23-apb2-gates-clk", .data = &sun8i_a23_apb2_gates_data,},
{.compatible = "allwinner,sun4i-a10-usb-clk", .data = &sun4i_a10_usb_gates_data,},
{.compatible = "allwinner,sun5i-a13-usb-clk", .data = &sun5i_a13_usb_gates_data,},
{.compatible = "allwinner,sun6i-a31-usb-clk", .data = &sun6i_a31_usb_gates_data,},
@@ -1236,3 +1336,4 @@ static void __init sun6i_init_clocks(struct device_node *node)
ARRAY_SIZE(sun6i_critical_clocks));
}
CLK_OF_DECLARE(sun6i_a31_clk_init, "allwinner,sun6i-a31", sun6i_init_clocks);
+CLK_OF_DECLARE(sun8i_a23_clk_init, "allwinner,sun8i-a23", sun6i_init_clocks);
--
2.0.0
The PLLs on newer Allwinner SoC's, such as the A31 and A23, have a
N multiplier factor that starts from 1, not 0.
This patch adds an option to the factor clk driver's config data
structures to specify the base value of N.
Signed-off-by: Chen-Yu Tsai <[email protected]>
Acked-by: Maxime Ripard <[email protected]>
---
drivers/clk/sunxi/clk-factors.c | 2 +-
drivers/clk/sunxi/clk-factors.h | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c
index 3806d97..2057c8a 100644
--- a/drivers/clk/sunxi/clk-factors.c
+++ b/drivers/clk/sunxi/clk-factors.c
@@ -62,7 +62,7 @@ static unsigned long clk_factors_recalc_rate(struct clk_hw *hw,
p = FACTOR_GET(config->pshift, config->pwidth, reg);
/* Calculate the rate */
- rate = (parent_rate * n * (k + 1) >> p) / (m + 1);
+ rate = (parent_rate * (n + config->n_start) * (k + 1) >> p) / (m + 1);
return rate;
}
diff --git a/drivers/clk/sunxi/clk-factors.h b/drivers/clk/sunxi/clk-factors.h
index 02e1a43..d2d0efa 100644
--- a/drivers/clk/sunxi/clk-factors.h
+++ b/drivers/clk/sunxi/clk-factors.h
@@ -15,6 +15,7 @@ struct clk_factors_config {
u8 mwidth;
u8 pshift;
u8 pwidth;
+ u8 n_start;
};
struct clk_factors {
--
2.0.0
With sunxi_gates clocks registered with clkdev, we can use the
protected clocks list to enable the "ahb_sdram" clock, instead
of looking for it and adding CLK_IGNORE_UNUSED inline in the
clock setup code.
Signed-off-by: Chen-Yu Tsai <[email protected]>
Acked-by: Maxime Ripard <[email protected]>
---
drivers/clk/sunxi/clk-sunxi.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index e43ed6a..a38c799 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -870,7 +870,6 @@ static void __init sunxi_gates_clk_setup(struct device_node *node,
int qty;
int i = 0;
int j = 0;
- int ignore;
reg = of_iomap(node, 0);
@@ -891,11 +890,8 @@ static void __init sunxi_gates_clk_setup(struct device_node *node,
of_property_read_string_index(node, "clock-output-names",
j, &clk_name);
- /* No driver claims this clock, but it should remain gated */
- ignore = !strcmp("ahb_sdram", clk_name) ? CLK_IGNORE_UNUSED : 0;
-
clk_data->clks[i] = clk_register_gate(NULL, clk_name,
- clk_parent, ignore,
+ clk_parent, 0,
reg + 4 * (i/32), i % 32,
0, &clk_lock);
WARN_ON(IS_ERR(clk_data->clks[i]));
@@ -1203,6 +1199,7 @@ static void __init sunxi_init_clocks(const char *clocks[], int nclocks)
static const char *sun4i_a10_critical_clocks[] __initdata = {
"pll5_ddr",
+ "ahb_sdram",
};
static void __init sun4i_a10_init_clocks(struct device_node *node)
@@ -1215,6 +1212,7 @@ CLK_OF_DECLARE(sun4i_a10_clk_init, "allwinner,sun4i-a10", sun4i_a10_init_clocks)
static const char *sun5i_critical_clocks[] __initdata = {
"mbus",
"pll5_ddr",
+ "ahb_sdram",
};
static void __init sun5i_init_clocks(struct device_node *node)
--
2.0.0
Quoting Chen-Yu Tsai (2014-06-26 08:55:38)
> Hi everyone,
>
> This is v4 of the sun8i clock series, which adds basic clock
> support for the A23 SoC. It is based on my initial sun8i bring
> up series [1]. This series was split up from the original A23
> series [2]. Yet to come are more clocks, reset controllers,
> prcm, pinctrl, and mmc.
Hello Chen-Yu,
This series looks good to me.
Maxime,
I see that you Acked it already. Are you planning to roll this into a
pull request later on?
Regards,
Mike
>
> The first patch fixes the reworked clock protection code merged in
> 3.16-rc1, which unintentionally made clock gates unprotectable.
>
> The second patch moves the remaining "ahb_sdram" clock to the
> protected clock list, now that it works.
>
> The third patch adds support for factor clocks that have an N factor
> not starting from 0. This is found on some PLLs in A31/A23.
>
> The fourth patch adds table-based dividers for div clocks, as some
> clocks, such as apb0 divider on sun4/5/7i, apb1 on sun6/8i and axi
> on sun8i.
>
> The fifth patch adds support for the basic clocks in the A23, just
> PLL1 for cpus, and the system bus clocks and gates.
>
> The last patch adds the DT nodes for the newly added clocks, and
> updates clock phandles for existing peripherals, the uarts.
>
> Originally I intended for patch 1 to be merged as a fix for 3.16.
> However, the only user of the affected code, sun6i's "ahb1_sdram"
> clock, doesn't seem to result in any runtime issues. So this whole
> series can go into 3.17.
>
>
> Related changes since v3:
>
> - Dropped fields with default values from sun8i_a23_axi_div_data
> - Added Maxime's Acked-by
> - Fixed incorrect compatible string for axi clock node
> - Updated clock phandles for uarts in dtsi
>
> Related changes since v2:
>
> - Rewrote factor clocks to support any (0~255) N factor starting value
>
> Related changes since v1:
>
> - Added "clk: sunxi: Add support for table-based divider clocks"
> - Added table-based divider axi clock
> - Fixed incorrectly squashed fixups
>
>
> Cheers
> ChenYu
>
>
> [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2014-June/265211.html
> [2] http://lists.infradead.org/pipermail/linux-arm-kernel/2014-May/259097.html
>
> Chen-Yu Tsai (6):
> clk: sunxi: register clock gates with clkdev
> clk: sunxi: move "ahb_sdram" to protected clock list
> clk: sunxi: Support factor clocks with N factor starting not from 0
> clk: sunxi: Add support for table-based divider clocks
> clk: sunxi: Add A23 clocks support
> ARM: sun8i: Add basic clock nodes to the DTSI
>
> Documentation/devicetree/bindings/clock/sunxi.txt | 5 +
> arch/arm/boot/dts/sun8i-a23.dtsi | 125 +++++++++++++++++++++-
> drivers/clk/sunxi/clk-factors.c | 2 +-
> drivers/clk/sunxi/clk-factors.h | 1 +
> drivers/clk/sunxi/clk-sunxi.c | 119 ++++++++++++++++++--
> 5 files changed, 237 insertions(+), 15 deletions(-)
>
> --
> 2.0.0
>
Hi Mike,
On Wed, Jul 02, 2014 at 03:35:52PM -0700, Mike Turquette wrote:
> Quoting Chen-Yu Tsai (2014-06-26 08:55:38)
> > Hi everyone,
> >
> > This is v4 of the sun8i clock series, which adds basic clock
> > support for the A23 SoC. It is based on my initial sun8i bring
> > up series [1]. This series was split up from the original A23
> > series [2]. Yet to come are more clocks, reset controllers,
> > prcm, pinctrl, and mmc.
>
> Hello Chen-Yu,
>
> This series looks good to me.
>
> Maxime,
>
> I see that you Acked it already. Are you planning to roll this into a
> pull request later on?
I think that was an question Emilio asked a few days ago :)
It would probably be easier if we just handle all the sunxi clocks
ourselves, so I guess Emilio can just send you a pull request later
on.
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
On Thu, Jul 3, 2014 at 6:35 AM, Mike Turquette <[email protected]> wrote:
> Quoting Chen-Yu Tsai (2014-06-26 08:55:38)
>> Hi everyone,
>>
>> This is v4 of the sun8i clock series, which adds basic clock
>> support for the A23 SoC. It is based on my initial sun8i bring
>> up series [1]. This series was split up from the original A23
>> series [2]. Yet to come are more clocks, reset controllers,
>> prcm, pinctrl, and mmc.
>
> Hello Chen-Yu,
>
> This series looks good to me.
Thanks. Assuming no one else raises any issues, I consider this
series merged. I'll send the next sun8i series later today.
The remaining series still have some clock patches, so thanks
in advance.
Cheers
ChenYu
> Maxime,
>
> I see that you Acked it already. Are you planning to roll this into a
> pull request later on?
>
> Regards,
> Mike
>
>>
>> The first patch fixes the reworked clock protection code merged in
>> 3.16-rc1, which unintentionally made clock gates unprotectable.
>>
>> The second patch moves the remaining "ahb_sdram" clock to the
>> protected clock list, now that it works.
>>
>> The third patch adds support for factor clocks that have an N factor
>> not starting from 0. This is found on some PLLs in A31/A23.
>>
>> The fourth patch adds table-based dividers for div clocks, as some
>> clocks, such as apb0 divider on sun4/5/7i, apb1 on sun6/8i and axi
>> on sun8i.
>>
>> The fifth patch adds support for the basic clocks in the A23, just
>> PLL1 for cpus, and the system bus clocks and gates.
>>
>> The last patch adds the DT nodes for the newly added clocks, and
>> updates clock phandles for existing peripherals, the uarts.
>>
>> Originally I intended for patch 1 to be merged as a fix for 3.16.
>> However, the only user of the affected code, sun6i's "ahb1_sdram"
>> clock, doesn't seem to result in any runtime issues. So this whole
>> series can go into 3.17.
>>
>>
>> Related changes since v3:
>>
>> - Dropped fields with default values from sun8i_a23_axi_div_data
>> - Added Maxime's Acked-by
>> - Fixed incorrect compatible string for axi clock node
>> - Updated clock phandles for uarts in dtsi
>>
>> Related changes since v2:
>>
>> - Rewrote factor clocks to support any (0~255) N factor starting value
>>
>> Related changes since v1:
>>
>> - Added "clk: sunxi: Add support for table-based divider clocks"
>> - Added table-based divider axi clock
>> - Fixed incorrectly squashed fixups
>>
>>
>> Cheers
>> ChenYu
>>
>>
>> [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2014-June/265211.html
>> [2] http://lists.infradead.org/pipermail/linux-arm-kernel/2014-May/259097.html
>>
>> Chen-Yu Tsai (6):
>> clk: sunxi: register clock gates with clkdev
>> clk: sunxi: move "ahb_sdram" to protected clock list
>> clk: sunxi: Support factor clocks with N factor starting not from 0
>> clk: sunxi: Add support for table-based divider clocks
>> clk: sunxi: Add A23 clocks support
>> ARM: sun8i: Add basic clock nodes to the DTSI
>>
>> Documentation/devicetree/bindings/clock/sunxi.txt | 5 +
>> arch/arm/boot/dts/sun8i-a23.dtsi | 125 +++++++++++++++++++++-
>> drivers/clk/sunxi/clk-factors.c | 2 +-
>> drivers/clk/sunxi/clk-factors.h | 1 +
>> drivers/clk/sunxi/clk-sunxi.c | 119 ++++++++++++++++++--
>> 5 files changed, 237 insertions(+), 15 deletions(-)
>>
>> --
>> 2.0.0
>>
On Thu, Jul 03, 2014 at 03:37:36PM +0800, Chen-Yu Tsai wrote:
> On Thu, Jul 3, 2014 at 6:35 AM, Mike Turquette <[email protected]> wrote:
> > Quoting Chen-Yu Tsai (2014-06-26 08:55:38)
> >> Hi everyone,
> >>
> >> This is v4 of the sun8i clock series, which adds basic clock
> >> support for the A23 SoC. It is based on my initial sun8i bring
> >> up series [1]. This series was split up from the original A23
> >> series [2]. Yet to come are more clocks, reset controllers,
> >> prcm, pinctrl, and mmc.
> >
> > Hello Chen-Yu,
> >
> > This series looks good to me.
>
> Thanks. Assuming no one else raises any issues, I consider this
> series merged. I'll send the next sun8i series later today.
>
> The remaining series still have some clock patches, so thanks
> in advance.
I just merged it all in sunxi/dt-for-3.17 and sunxi/clocks-for-3.17.
Thanks!
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com