sunxi: fix led on bananapi
[openwrt.git] / target / linux / sunxi / patches-3.14 / 185-clk-sunxi-add-a20-a31-gmac-clock.patch
1 From dd91dc4b9c55c8fa24738249214274442e2fcbd3 Mon Sep 17 00:00:00 2001
2 From: Chen-Yu Tsai <wens@csie.org>
3 Date: Mon, 10 Feb 2014 18:35:47 +0800
4 Subject: [PATCH] clk: sunxi: Add Allwinner A20/A31 GMAC clock unit
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 The Allwinner A20/A31 clock module controls the transmit clock source
10 and interface type of the GMAC ethernet controller. Model this as
11 a single clock for GMAC drivers to use.
12
13 Signed-off-by: Chen-Yu Tsai <wens@csie.org>
14 Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
15 Signed-off-by: Emilio López <emilio@elopez.com.ar>
16 ---
17  Documentation/devicetree/bindings/clock/sunxi.txt | 30 +++++++
18  drivers/clk/sunxi/clk-sunxi.c                     | 96 +++++++++++++++++++++++
19  2 files changed, 126 insertions(+)
20
21 --- a/Documentation/devicetree/bindings/clock/sunxi.txt
22 +++ b/Documentation/devicetree/bindings/clock/sunxi.txt
23 @@ -38,6 +38,7 @@ Required properties:
24         "allwinner,sun6i-a31-apb2-gates-clk" - for the APB2 gates on A31
25         "allwinner,sun4i-mod0-clk" - for the module 0 family of clocks
26         "allwinner,sun7i-a20-out-clk" - for the external output clocks
27 +       "allwinner,sun7i-a20-gmac-clk" - for the GMAC clock module on A20/A31
28         "allwinner,sun4i-a10-usb-clk" - for usb gates + resets on A10 / A20
29         "allwinner,sun5i-a13-usb-clk" - for usb gates + resets on A13
30  
31 @@ -55,6 +56,9 @@ Additionally, "allwinner,*-gates-clk" cl
32  And "allwinner,*-usb-clk" clocks also require:
33  - reset-cells : shall be set to 1
34  
35 +For "allwinner,sun7i-a20-gmac-clk", the parent clocks shall be fixed rate
36 +dummy clocks at 25 MHz and 125 MHz, respectively. See example.
37 +
38  Clock consumers should specify the desired clocks they use with a
39  "clocks" phandle cell. Consumers that are using a gated clock should
40  provide an additional ID in their clock property. This ID is the
41 @@ -82,3 +86,29 @@ cpu: cpu@01c20054 {
42         reg = <0x01c20054 0x4>;
43         clocks = <&osc32k>, <&osc24M>, <&pll1>;
44  };
45 +
46 +mii_phy_tx_clk: clk@2 {
47 +       #clock-cells = <0>;
48 +       compatible = "fixed-clock";
49 +       clock-frequency = <25000000>;
50 +       clock-output-names = "mii_phy_tx";
51 +};
52 +
53 +gmac_int_tx_clk: clk@3 {
54 +       #clock-cells = <0>;
55 +       compatible = "fixed-clock";
56 +       clock-frequency = <125000000>;
57 +       clock-output-names = "gmac_int_tx";
58 +};
59 +
60 +gmac_clk: clk@01c20164 {
61 +       #clock-cells = <0>;
62 +       compatible = "allwinner,sun7i-a20-gmac-clk";
63 +       reg = <0x01c20164 0x4>;
64 +       /*
65 +        * The first clock must be fixed at 25MHz;
66 +        * the second clock must be fixed at 125MHz
67 +        */
68 +       clocks = <&mii_phy_tx_clk>, <&gmac_int_tx_clk>;
69 +       clock-output-names = "gmac";
70 +};
71 --- a/drivers/clk/sunxi/clk-sunxi.c
72 +++ b/drivers/clk/sunxi/clk-sunxi.c
73 @@ -411,6 +411,102 @@ static void sun7i_a20_get_out_factors(u3
74  
75  
76  /**
77 + * sun7i_a20_gmac_clk_setup - Setup function for A20/A31 GMAC clock module
78 + *
79 + * This clock looks something like this
80 + *                               ________________________
81 + *  MII TX clock from PHY >-----|___________    _________|----> to GMAC core
82 + *  GMAC Int. RGMII TX clk >----|___________\__/__gate---|----> to PHY
83 + *  Ext. 125MHz RGMII TX clk >--|__divider__/            |
84 + *                              |________________________|
85 + *
86 + * The external 125 MHz reference is optional, i.e. GMAC can use its
87 + * internal TX clock just fine. The A31 GMAC clock module does not have
88 + * the divider controls for the external reference.
89 + *
90 + * To keep it simple, let the GMAC use either the MII TX clock for MII mode,
91 + * and its internal TX clock for GMII and RGMII modes. The GMAC driver should
92 + * select the appropriate source and gate/ungate the output to the PHY.
93 + *
94 + * Only the GMAC should use this clock. Altering the clock so that it doesn't
95 + * match the GMAC's operation parameters will result in the GMAC not being
96 + * able to send traffic out. The GMAC driver should set the clock rate and
97 + * enable/disable this clock to configure the required state. The clock
98 + * driver then responds by auto-reparenting the clock.
99 + */
100 +
101 +#define SUN7I_A20_GMAC_GPIT    2
102 +#define SUN7I_A20_GMAC_MASK    0x3
103 +#define SUN7I_A20_GMAC_PARENTS 2
104 +
105 +static void __init sun7i_a20_gmac_clk_setup(struct device_node *node)
106 +{
107 +       struct clk *clk;
108 +       struct clk_mux *mux;
109 +       struct clk_gate *gate;
110 +       const char *clk_name = node->name;
111 +       const char *parents[SUN7I_A20_GMAC_PARENTS];
112 +       void *reg;
113 +
114 +       if (of_property_read_string(node, "clock-output-names", &clk_name))
115 +               return;
116 +
117 +       /* allocate mux and gate clock structs */
118 +       mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL);
119 +       if (!mux)
120 +               return;
121 +
122 +       gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL);
123 +       if (!gate)
124 +               goto free_mux;
125 +
126 +       /* gmac clock requires exactly 2 parents */
127 +       parents[0] = of_clk_get_parent_name(node, 0);
128 +       parents[1] = of_clk_get_parent_name(node, 1);
129 +       if (!parents[0] || !parents[1])
130 +               goto free_gate;
131 +
132 +       reg = of_iomap(node, 0);
133 +       if (!reg)
134 +               goto free_gate;
135 +
136 +       /* set up gate and fixed rate properties */
137 +       gate->reg = reg;
138 +       gate->bit_idx = SUN7I_A20_GMAC_GPIT;
139 +       gate->lock = &clk_lock;
140 +       mux->reg = reg;
141 +       mux->mask = SUN7I_A20_GMAC_MASK;
142 +       mux->flags = CLK_MUX_INDEX_BIT;
143 +       mux->lock = &clk_lock;
144 +
145 +       clk = clk_register_composite(NULL, clk_name,
146 +                       parents, SUN7I_A20_GMAC_PARENTS,
147 +                       &mux->hw, &clk_mux_ops,
148 +                       NULL, NULL,
149 +                       &gate->hw, &clk_gate_ops,
150 +                       0);
151 +
152 +       if (IS_ERR(clk))
153 +               goto iounmap_reg;
154 +
155 +       of_clk_add_provider(node, of_clk_src_simple_get, clk);
156 +       clk_register_clkdev(clk, clk_name, NULL);
157 +
158 +       return;
159 +
160 +iounmap_reg:
161 +       iounmap(reg);
162 +free_gate:
163 +       kfree(gate);
164 +free_mux:
165 +       kfree(mux);
166 +}
167 +CLK_OF_DECLARE(sun7i_a20_gmac, "allwinner,sun7i-a20-gmac-clk",
168 +               sun7i_a20_gmac_clk_setup);
169 +
170 +
171 +
172 +/**
173   * sunxi_factors_clk_setup() - Setup function for factor clocks
174   */
175