ipq806x: Add support for IPQ806x chip family
[openwrt/openwrt.git] / target / linux / ipq806x / patches / 0107-clk-qcom-Support-msm8974pro-global-clock-control-har.patch
1 From a740d2b024c5b71c6f9989976049f03b634bb13d Mon Sep 17 00:00:00 2001
2 From: Stephen Boyd <sboyd@codeaurora.org>
3 Date: Fri, 16 May 2014 16:07:13 -0700
4 Subject: [PATCH 107/182] clk: qcom: Support msm8974pro global clock control
5 hardware
6
7 A new PLL (gpll4) is added on msm8974 PRO devices to support a
8 faster sdc1 clock rate. Add support for this and the two new sdcc
9 cal clocks.
10
11 Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
12 Signed-off-by: Mike Turquette <mturquette@linaro.org>
13 ---
14 .../devicetree/bindings/clock/qcom,gcc.txt | 2 +
15 drivers/clk/qcom/gcc-msm8974.c | 130 +++++++++++++++++++-
16 include/dt-bindings/clock/qcom,gcc-msm8974.h | 4 +
17 3 files changed, 130 insertions(+), 6 deletions(-)
18
19 diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc.txt b/Documentation/devicetree/bindings/clock/qcom,gcc.txt
20 index 7b7104e..9cfcb4f 100644
21 --- a/Documentation/devicetree/bindings/clock/qcom,gcc.txt
22 +++ b/Documentation/devicetree/bindings/clock/qcom,gcc.txt
23 @@ -8,6 +8,8 @@ Required properties :
24 "qcom,gcc-msm8660"
25 "qcom,gcc-msm8960"
26 "qcom,gcc-msm8974"
27 + "qcom,gcc-msm8974pro"
28 + "qcom,gcc-msm8974pro-ac"
29
30 - reg : shall contain base register location and length
31 - #clock-cells : shall contain 1
32 diff --git a/drivers/clk/qcom/gcc-msm8974.c b/drivers/clk/qcom/gcc-msm8974.c
33 index 7a420fc..7af7c18 100644
34 --- a/drivers/clk/qcom/gcc-msm8974.c
35 +++ b/drivers/clk/qcom/gcc-msm8974.c
36 @@ -35,6 +35,7 @@
37 #define P_XO 0
38 #define P_GPLL0 1
39 #define P_GPLL1 1
40 +#define P_GPLL4 2
41
42 static const u8 gcc_xo_gpll0_map[] = {
43 [P_XO] = 0,
44 @@ -46,6 +47,18 @@ static const char *gcc_xo_gpll0[] = {
45 "gpll0_vote",
46 };
47
48 +static const u8 gcc_xo_gpll0_gpll4_map[] = {
49 + [P_XO] = 0,
50 + [P_GPLL0] = 1,
51 + [P_GPLL4] = 5,
52 +};
53 +
54 +static const char *gcc_xo_gpll0_gpll4[] = {
55 + "xo",
56 + "gpll0_vote",
57 + "gpll4_vote",
58 +};
59 +
60 #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
61
62 static struct clk_pll gpll0 = {
63 @@ -138,6 +151,33 @@ static struct clk_regmap gpll1_vote = {
64 },
65 };
66
67 +static struct clk_pll gpll4 = {
68 + .l_reg = 0x1dc4,
69 + .m_reg = 0x1dc8,
70 + .n_reg = 0x1dcc,
71 + .config_reg = 0x1dd4,
72 + .mode_reg = 0x1dc0,
73 + .status_reg = 0x1ddc,
74 + .status_bit = 17,
75 + .clkr.hw.init = &(struct clk_init_data){
76 + .name = "gpll4",
77 + .parent_names = (const char *[]){ "xo" },
78 + .num_parents = 1,
79 + .ops = &clk_pll_ops,
80 + },
81 +};
82 +
83 +static struct clk_regmap gpll4_vote = {
84 + .enable_reg = 0x1480,
85 + .enable_mask = BIT(4),
86 + .hw.init = &(struct clk_init_data){
87 + .name = "gpll4_vote",
88 + .parent_names = (const char *[]){ "gpll4" },
89 + .num_parents = 1,
90 + .ops = &clk_pll_vote_ops,
91 + },
92 +};
93 +
94 static const struct freq_tbl ftbl_gcc_usb30_master_clk[] = {
95 F(125000000, P_GPLL0, 1, 5, 24),
96 { }
97 @@ -812,18 +852,33 @@ static const struct freq_tbl ftbl_gcc_sdcc1_4_apps_clk[] = {
98 { }
99 };
100
101 +static const struct freq_tbl ftbl_gcc_sdcc1_apps_clk_pro[] = {
102 + F(144000, P_XO, 16, 3, 25),
103 + F(400000, P_XO, 12, 1, 4),
104 + F(20000000, P_GPLL0, 15, 1, 2),
105 + F(25000000, P_GPLL0, 12, 1, 2),
106 + F(50000000, P_GPLL0, 12, 0, 0),
107 + F(100000000, P_GPLL0, 6, 0, 0),
108 + F(192000000, P_GPLL4, 4, 0, 0),
109 + F(200000000, P_GPLL0, 3, 0, 0),
110 + F(384000000, P_GPLL4, 2, 0, 0),
111 + { }
112 +};
113 +
114 +static struct clk_init_data sdcc1_apps_clk_src_init = {
115 + .name = "sdcc1_apps_clk_src",
116 + .parent_names = gcc_xo_gpll0,
117 + .num_parents = 2,
118 + .ops = &clk_rcg2_ops,
119 +};
120 +
121 static struct clk_rcg2 sdcc1_apps_clk_src = {
122 .cmd_rcgr = 0x04d0,
123 .mnd_width = 8,
124 .hid_width = 5,
125 .parent_map = gcc_xo_gpll0_map,
126 .freq_tbl = ftbl_gcc_sdcc1_4_apps_clk,
127 - .clkr.hw.init = &(struct clk_init_data){
128 - .name = "sdcc1_apps_clk_src",
129 - .parent_names = gcc_xo_gpll0,
130 - .num_parents = 2,
131 - .ops = &clk_rcg2_ops,
132 - },
133 + .clkr.hw.init = &sdcc1_apps_clk_src_init,
134 };
135
136 static struct clk_rcg2 sdcc2_apps_clk_src = {
137 @@ -1995,6 +2050,38 @@ static struct clk_branch gcc_sdcc1_apps_clk = {
138 },
139 };
140
141 +static struct clk_branch gcc_sdcc1_cdccal_ff_clk = {
142 + .halt_reg = 0x04e8,
143 + .clkr = {
144 + .enable_reg = 0x04e8,
145 + .enable_mask = BIT(0),
146 + .hw.init = &(struct clk_init_data){
147 + .name = "gcc_sdcc1_cdccal_ff_clk",
148 + .parent_names = (const char *[]){
149 + "xo"
150 + },
151 + .num_parents = 1,
152 + .ops = &clk_branch2_ops,
153 + },
154 + },
155 +};
156 +
157 +static struct clk_branch gcc_sdcc1_cdccal_sleep_clk = {
158 + .halt_reg = 0x04e4,
159 + .clkr = {
160 + .enable_reg = 0x04e4,
161 + .enable_mask = BIT(0),
162 + .hw.init = &(struct clk_init_data){
163 + .name = "gcc_sdcc1_cdccal_sleep_clk",
164 + .parent_names = (const char *[]){
165 + "sleep_clk_src"
166 + },
167 + .num_parents = 1,
168 + .ops = &clk_branch2_ops,
169 + },
170 + },
171 +};
172 +
173 static struct clk_branch gcc_sdcc2_ahb_clk = {
174 .halt_reg = 0x0508,
175 .clkr = {
176 @@ -2484,6 +2571,10 @@ static struct clk_regmap *gcc_msm8974_clocks[] = {
177 [GCC_USB_HSIC_IO_CAL_SLEEP_CLK] = &gcc_usb_hsic_io_cal_sleep_clk.clkr,
178 [GCC_USB_HSIC_SYSTEM_CLK] = &gcc_usb_hsic_system_clk.clkr,
179 [GCC_MMSS_GPLL0_CLK_SRC] = &gcc_mmss_gpll0_clk_src,
180 + [GPLL4] = NULL,
181 + [GPLL4_VOTE] = NULL,
182 + [GCC_SDCC1_CDCCAL_SLEEP_CLK] = NULL,
183 + [GCC_SDCC1_CDCCAL_FF_CLK] = NULL,
184 };
185
186 static const struct qcom_reset_map gcc_msm8974_resets[] = {
187 @@ -2585,14 +2676,41 @@ static const struct qcom_cc_desc gcc_msm8974_desc = {
188
189 static const struct of_device_id gcc_msm8974_match_table[] = {
190 { .compatible = "qcom,gcc-msm8974" },
191 + { .compatible = "qcom,gcc-msm8974pro" , .data = (void *)1UL },
192 + { .compatible = "qcom,gcc-msm8974pro-ac", .data = (void *)1UL },
193 { }
194 };
195 MODULE_DEVICE_TABLE(of, gcc_msm8974_match_table);
196
197 +static void msm8974_pro_clock_override(void)
198 +{
199 + sdcc1_apps_clk_src_init.parent_names = gcc_xo_gpll0_gpll4;
200 + sdcc1_apps_clk_src_init.num_parents = 3;
201 + sdcc1_apps_clk_src.freq_tbl = ftbl_gcc_sdcc1_apps_clk_pro;
202 + sdcc1_apps_clk_src.parent_map = gcc_xo_gpll0_gpll4_map;
203 +
204 + gcc_msm8974_clocks[GPLL4] = &gpll4.clkr;
205 + gcc_msm8974_clocks[GPLL4_VOTE] = &gpll4_vote;
206 + gcc_msm8974_clocks[GCC_SDCC1_CDCCAL_SLEEP_CLK] =
207 + &gcc_sdcc1_cdccal_sleep_clk.clkr;
208 + gcc_msm8974_clocks[GCC_SDCC1_CDCCAL_FF_CLK] =
209 + &gcc_sdcc1_cdccal_ff_clk.clkr;
210 +}
211 +
212 static int gcc_msm8974_probe(struct platform_device *pdev)
213 {
214 struct clk *clk;
215 struct device *dev = &pdev->dev;
216 + bool pro;
217 + const struct of_device_id *id;
218 +
219 + id = of_match_device(gcc_msm8974_match_table, dev);
220 + if (!id)
221 + return -ENODEV;
222 + pro = !!(id->data);
223 +
224 + if (pro)
225 + msm8974_pro_clock_override();
226
227 /* Temporary until RPM clocks supported */
228 clk = clk_register_fixed_rate(dev, "xo", NULL, CLK_IS_ROOT, 19200000);
229 diff --git a/include/dt-bindings/clock/qcom,gcc-msm8974.h b/include/dt-bindings/clock/qcom,gcc-msm8974.h
230 index 223ca17..51e51c8 100644
231 --- a/include/dt-bindings/clock/qcom,gcc-msm8974.h
232 +++ b/include/dt-bindings/clock/qcom,gcc-msm8974.h
233 @@ -316,5 +316,9 @@
234 #define GCC_CE2_CLK_SLEEP_ENA 299
235 #define GCC_CE2_AXI_CLK_SLEEP_ENA 300
236 #define GCC_CE2_AHB_CLK_SLEEP_ENA 301
237 +#define GPLL4 302
238 +#define GPLL4_VOTE 303
239 +#define GCC_SDCC1_CDCCAL_SLEEP_CLK 304
240 +#define GCC_SDCC1_CDCCAL_FF_CLK 305
241
242 #endif
243 --
244 1.7.10.4
245