aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Turquette <mturquette@linaro.org>2015-03-25 17:51:40 -0400
committerMichael Turquette <mturquette@linaro.org>2015-03-25 17:51:40 -0400
commitfe15dedc02e4ee29edfc84bbbf5ee42827e36ac7 (patch)
treeb64f9ceebdbf3019f3d10ecb404f6fc002223113
parentc77662a4df847e7b75ff8c5f2314dd4f022377e3 (diff)
parentf1017969661dd33ead5ba7c3f4a0793c6611441a (diff)
Merge tag 'sunxi-clocks-for-4.1' of https://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux into clk-next
Allwinner clocks changes for 4.1 The usual round of clock changes for the Allwinner SoCs. There is nothing really standing out here, but a few changes and fixes, most notably to allow the AHB clock to be parented to a PLL, instead of the CPU clock to avoid any AHB rate change due to cpufreq.
-rw-r--r--Documentation/devicetree/bindings/clock/sunxi.txt3
-rw-r--r--drivers/clk/sunxi/Makefile1
-rw-r--r--drivers/clk/sunxi/clk-sunxi.c185
-rw-r--r--drivers/clk/sunxi/clk-usb.c233
4 files changed, 319 insertions, 103 deletions
diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
index 60b44285250d..4fa11af3d378 100644
--- a/Documentation/devicetree/bindings/clock/sunxi.txt
+++ b/Documentation/devicetree/bindings/clock/sunxi.txt
@@ -20,6 +20,7 @@ Required properties:
20 "allwinner,sun8i-a23-axi-clk" - for the AXI clock on A23 20 "allwinner,sun8i-a23-axi-clk" - for the AXI clock on A23
21 "allwinner,sun4i-a10-axi-gates-clk" - for the AXI gates 21 "allwinner,sun4i-a10-axi-gates-clk" - for the AXI gates
22 "allwinner,sun4i-a10-ahb-clk" - for the AHB clock 22 "allwinner,sun4i-a10-ahb-clk" - for the AHB clock
23 "allwinner,sun5i-a13-ahb-clk" - for the AHB clock on A13
23 "allwinner,sun9i-a80-ahb-clk" - for the AHB bus clocks on A80 24 "allwinner,sun9i-a80-ahb-clk" - for the AHB bus clocks on A80
24 "allwinner,sun4i-a10-ahb-gates-clk" - for the AHB gates on A10 25 "allwinner,sun4i-a10-ahb-gates-clk" - for the AHB gates on A10
25 "allwinner,sun5i-a13-ahb-gates-clk" - for the AHB gates on A13 26 "allwinner,sun5i-a13-ahb-gates-clk" - for the AHB gates on A13
@@ -66,6 +67,8 @@ Required properties:
66 "allwinner,sun4i-a10-usb-clk" - for usb gates + resets on A10 / A20 67 "allwinner,sun4i-a10-usb-clk" - for usb gates + resets on A10 / A20
67 "allwinner,sun5i-a13-usb-clk" - for usb gates + resets on A13 68 "allwinner,sun5i-a13-usb-clk" - for usb gates + resets on A13
68 "allwinner,sun6i-a31-usb-clk" - for usb gates + resets on A31 69 "allwinner,sun6i-a31-usb-clk" - for usb gates + resets on A31
70 "allwinner,sun9i-a80-usb-mod-clk" - for usb gates + resets on A80
71 "allwinner,sun9i-a80-usb-phy-clk" - for usb phy gates + resets on A80
69 72
70Required properties for all clocks: 73Required properties for all clocks:
71- reg : shall be the control register address for the clock. 74- reg : shall be the control register address for the clock.
diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile
index 3a5292e3fcf8..058f273d6154 100644
--- a/drivers/clk/sunxi/Makefile
+++ b/drivers/clk/sunxi/Makefile
@@ -9,6 +9,7 @@ obj-y += clk-mod0.o
9obj-y += clk-sun8i-mbus.o 9obj-y += clk-sun8i-mbus.o
10obj-y += clk-sun9i-core.o 10obj-y += clk-sun9i-core.o
11obj-y += clk-sun9i-mmc.o 11obj-y += clk-sun9i-mmc.o
12obj-y += clk-usb.o
12 13
13obj-$(CONFIG_MFD_SUN6I_PRCM) += \ 14obj-$(CONFIG_MFD_SUN6I_PRCM) += \
14 clk-sun6i-ar100.o clk-sun6i-apb0.o clk-sun6i-apb0-gates.o \ 15 clk-sun6i-ar100.o clk-sun6i-apb0.o clk-sun6i-apb0-gates.o \
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
index 379324eb5486..7e1e2bd189b6 100644
--- a/drivers/clk/sunxi/clk-sunxi.c
+++ b/drivers/clk/sunxi/clk-sunxi.c
@@ -482,6 +482,45 @@ static void sun6i_a31_get_pll6_factors(u32 *freq, u32 parent_rate,
482} 482}
483 483
484/** 484/**
485 * sun5i_a13_get_ahb_factors() - calculates m, p factors for AHB
486 * AHB rate is calculated as follows
487 * rate = parent_rate >> p
488 */
489
490static void sun5i_a13_get_ahb_factors(u32 *freq, u32 parent_rate,
491 u8 *n, u8 *k, u8 *m, u8 *p)
492{
493 u32 div;
494
495 /* divide only */
496 if (parent_rate < *freq)
497 *freq = parent_rate;
498
499 /*
500 * user manual says valid speed is 8k ~ 276M, but tests show it
501 * can work at speeds up to 300M, just after reparenting to pll6
502 */
503 if (*freq < 8000)
504 *freq = 8000;
505 if (*freq > 300000000)
506 *freq = 300000000;
507
508 div = order_base_2(DIV_ROUND_UP(parent_rate, *freq));
509
510 /* p = 0 ~ 3 */
511 if (div > 3)
512 div = 3;
513
514 *freq = parent_rate >> div;
515
516 /* we were called to round the frequency, we can now return */
517 if (p == NULL)
518 return;
519
520 *p = div;
521}
522
523/**
485 * sun4i_get_apb1_factors() - calculates m, p factors for APB1 524 * sun4i_get_apb1_factors() - calculates m, p factors for APB1
486 * APB1 rate is calculated as follows 525 * APB1 rate is calculated as follows
487 * rate = (parent_rate >> p) / (m + 1); 526 * rate = (parent_rate >> p) / (m + 1);
@@ -616,6 +655,11 @@ static struct clk_factors_config sun6i_a31_pll6_config = {
616 .n_start = 1, 655 .n_start = 1,
617}; 656};
618 657
658static struct clk_factors_config sun5i_a13_ahb_config = {
659 .pshift = 4,
660 .pwidth = 2,
661};
662
619static struct clk_factors_config sun4i_apb1_config = { 663static struct clk_factors_config sun4i_apb1_config = {
620 .mshift = 0, 664 .mshift = 0,
621 .mwidth = 5, 665 .mwidth = 5,
@@ -676,6 +720,13 @@ static const struct factors_data sun6i_a31_pll6_data __initconst = {
676 .name = "pll6x2", 720 .name = "pll6x2",
677}; 721};
678 722
723static const struct factors_data sun5i_a13_ahb_data __initconst = {
724 .mux = 6,
725 .muxmask = BIT(1) | BIT(0),
726 .table = &sun5i_a13_ahb_config,
727 .getter = sun5i_a13_get_ahb_factors,
728};
729
679static const struct factors_data sun4i_apb1_data __initconst = { 730static const struct factors_data sun4i_apb1_data __initconst = {
680 .mux = 24, 731 .mux = 24,
681 .muxmask = BIT(1) | BIT(0), 732 .muxmask = BIT(1) | BIT(0),
@@ -838,59 +889,6 @@ static void __init sunxi_divider_clk_setup(struct device_node *node,
838 889
839 890
840/** 891/**
841 * sunxi_gates_reset... - reset bits in leaf gate clk registers handling
842 */
843
844struct gates_reset_data {
845 void __iomem *reg;
846 spinlock_t *lock;
847 struct reset_controller_dev rcdev;
848};
849
850static int sunxi_gates_reset_assert(struct reset_controller_dev *rcdev,
851 unsigned long id)
852{
853 struct gates_reset_data *data = container_of(rcdev,
854 struct gates_reset_data,
855 rcdev);
856 unsigned long flags;
857 u32 reg;
858
859 spin_lock_irqsave(data->lock, flags);
860
861 reg = readl(data->reg);
862 writel(reg & ~BIT(id), data->reg);
863
864 spin_unlock_irqrestore(data->lock, flags);
865
866 return 0;
867}
868
869static int sunxi_gates_reset_deassert(struct reset_controller_dev *rcdev,
870 unsigned long id)
871{
872 struct gates_reset_data *data = container_of(rcdev,
873 struct gates_reset_data,
874 rcdev);
875 unsigned long flags;
876 u32 reg;
877
878 spin_lock_irqsave(data->lock, flags);
879
880 reg = readl(data->reg);
881 writel(reg | BIT(id), data->reg);
882
883 spin_unlock_irqrestore(data->lock, flags);
884
885 return 0;
886}
887
888static struct reset_control_ops sunxi_gates_reset_ops = {
889 .assert = sunxi_gates_reset_assert,
890 .deassert = sunxi_gates_reset_deassert,
891};
892
893/**
894 * sunxi_gates_clk_setup() - Setup function for leaf gates on clocks 892 * sunxi_gates_clk_setup() - Setup function for leaf gates on clocks
895 */ 893 */
896 894
@@ -898,7 +896,6 @@ static struct reset_control_ops sunxi_gates_reset_ops = {
898 896
899struct gates_data { 897struct gates_data {
900 DECLARE_BITMAP(mask, SUNXI_GATES_MAX_SIZE); 898 DECLARE_BITMAP(mask, SUNXI_GATES_MAX_SIZE);
901 u32 reset_mask;
902};