1/*
2 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * GNU General Public License for more details.
12 */
13
14#include <linux/kernel.h>
15#include <linux/bitops.h>
16#include <linux/err.h>
17#include <linux/platform_device.h>
18#include <linux/module.h>
19#include <linux/of.h>
20#include <linux/of_device.h>
21#include <linux/clk-provider.h>
22#include <linux/regmap.h>
23
24#include <dt-bindings/clock/qcom,lcc-ipq806x.h>
25
26#include "common.h"
27#include "clk-regmap.h"
28#include "clk-pll.h"
29#include "clk-rcg.h"
30#include "clk-branch.h"
31#include "clk-regmap-divider.h"
32#include "clk-regmap-mux.h"
33
34static struct clk_pll pll4 = {
35	.l_reg = 0x4,
36	.m_reg = 0x8,
37	.n_reg = 0xc,
38	.config_reg = 0x14,
39	.mode_reg = 0x0,
40	.status_reg = 0x18,
41	.status_bit = 16,
42	.clkr.hw.init = &(struct clk_init_data){
43		.name = "pll4",
44		.parent_names = (const char *[]){ "pxo" },
45		.num_parents = 1,
46		.ops = &clk_pll_ops,
47	},
48};
49
50static const struct pll_config pll4_config = {
51	.l = 0xf,
52	.m = 0x91,
53	.n = 0xc7,
54	.vco_val = 0x0,
55	.vco_mask = BIT(17) | BIT(16),
56	.pre_div_val = 0x0,
57	.pre_div_mask = BIT(19),
58	.post_div_val = 0x0,
59	.post_div_mask = BIT(21) | BIT(20),
60	.mn_ena_mask = BIT(22),
61	.main_output_mask = BIT(23),
62};
63
64enum {
65	P_PXO,
66	P_PLL4,
67};
68
69static const struct parent_map lcc_pxo_pll4_map[] = {
70	{ P_PXO, 0 },
71	{ P_PLL4, 2 }
72};
73
74static const char * const lcc_pxo_pll4[] = {
75	"pxo",
76	"pll4_vote",
77};
78
79static struct freq_tbl clk_tbl_aif_mi2s[] = {
80	{  1024000, P_PLL4, 4,  1,  96 },
81	{  1411200, P_PLL4, 4,  2, 139 },
82	{  1536000, P_PLL4, 4,  1,  64 },
83	{  2048000, P_PLL4, 4,  1,  48 },
84	{  2116800, P_PLL4, 4,  2,  93 },
85	{  2304000, P_PLL4, 4,  2,  85 },
86	{  2822400, P_PLL4, 4,  6, 209 },
87	{  3072000, P_PLL4, 4,  1,  32 },
88	{  3175200, P_PLL4, 4,  1,  31 },
89	{  4096000, P_PLL4, 4,  1,  24 },
90	{  4233600, P_PLL4, 4,  9, 209 },
91	{  4608000, P_PLL4, 4,  3,  64 },
92	{  5644800, P_PLL4, 4, 12, 209 },
93	{  6144000, P_PLL4, 4,  1,  16 },
94	{  6350400, P_PLL4, 4,  2,  31 },
95	{  8192000, P_PLL4, 4,  1,  12 },
96	{  8467200, P_PLL4, 4, 18, 209 },
97	{  9216000, P_PLL4, 4,  3,  32 },
98	{ 11289600, P_PLL4, 4, 24, 209 },
99	{ 12288000, P_PLL4, 4,  1,   8 },
100	{ 12700800, P_PLL4, 4, 27, 209 },
101	{ 13824000, P_PLL4, 4,  9,  64 },
102	{ 16384000, P_PLL4, 4,  1,   6 },
103	{ 16934400, P_PLL4, 4, 41, 238 },
104	{ 18432000, P_PLL4, 4,  3,  16 },
105	{ 22579200, P_PLL4, 2, 24, 209 },
106	{ 24576000, P_PLL4, 4,  1,   4 },
107	{ 27648000, P_PLL4, 4,  9,  32 },
108	{ 33868800, P_PLL4, 4, 41, 119 },
109	{ 36864000, P_PLL4, 4,  3,   8 },
110	{ 45158400, P_PLL4, 1, 24, 209 },
111	{ 49152000, P_PLL4, 4,  1,   2 },
112	{ 50803200, P_PLL4, 1, 27, 209 },
113	{ }
114};
115
116static struct clk_rcg mi2s_osr_src = {
117	.ns_reg = 0x48,
118	.md_reg = 0x4c,
119	.mn = {
120		.mnctr_en_bit = 8,
121		.mnctr_reset_bit = 7,
122		.mnctr_mode_shift = 5,
123		.n_val_shift = 24,
124		.m_val_shift = 8,
125		.width = 8,
126	},
127	.p = {
128		.pre_div_shift = 3,
129		.pre_div_width = 2,
130	},
131	.s = {
132		.src_sel_shift = 0,
133		.parent_map = lcc_pxo_pll4_map,
134	},
135	.freq_tbl = clk_tbl_aif_mi2s,
136	.clkr = {
137		.enable_reg = 0x48,
138		.enable_mask = BIT(9),
139		.hw.init = &(struct clk_init_data){
140			.name = "mi2s_osr_src",
141			.parent_names = lcc_pxo_pll4,
142			.num_parents = 2,
143			.ops = &clk_rcg_ops,
144			.flags = CLK_SET_RATE_GATE,
145		},
146	},
147};
148
149static const char * const lcc_mi2s_parents[] = {
150	"mi2s_osr_src",
151};
152
153static struct clk_branch mi2s_osr_clk = {
154	.halt_reg = 0x50,
155	.halt_bit = 1,
156	.halt_check = BRANCH_HALT_ENABLE,
157	.clkr = {
158		.enable_reg = 0x48,
159		.enable_mask = BIT(17),
160		.hw.init = &(struct clk_init_data){
161			.name = "mi2s_osr_clk",
162			.parent_names = lcc_mi2s_parents,
163			.num_parents = 1,
164			.ops = &clk_branch_ops,
165			.flags = CLK_SET_RATE_PARENT,
166		},
167	},
168};
169
170static struct clk_regmap_div mi2s_div_clk = {
171	.reg = 0x48,
172	.shift = 10,
173	.width = 4,
174	.clkr = {
175		.hw.init = &(struct clk_init_data){
176			.name = "mi2s_div_clk",
177			.parent_names = lcc_mi2s_parents,
178			.num_parents = 1,
179			.ops = &clk_regmap_div_ops,
180		},
181	},
182};
183
184static struct clk_branch mi2s_bit_div_clk = {
185	.halt_reg = 0x50,
186	.halt_bit = 0,
187	.halt_check = BRANCH_HALT_ENABLE,
188	.clkr = {
189		.enable_reg = 0x48,
190		.enable_mask = BIT(15),
191		.hw.init = &(struct clk_init_data){
192			.name = "mi2s_bit_div_clk",
193			.parent_names = (const char *[]){ "mi2s_div_clk" },
194			.num_parents = 1,
195			.ops = &clk_branch_ops,
196			.flags = CLK_SET_RATE_PARENT,
197		},
198	},
199};
200
201
202static struct clk_regmap_mux mi2s_bit_clk = {
203	.reg = 0x48,
204	.shift = 14,
205	.width = 1,
206	.clkr = {
207		.hw.init = &(struct clk_init_data){
208			.name = "mi2s_bit_clk",
209			.parent_names = (const char *[]){
210				"mi2s_bit_div_clk",
211				"mi2s_codec_clk",
212			},
213			.num_parents = 2,
214			.ops = &clk_regmap_mux_closest_ops,
215			.flags = CLK_SET_RATE_PARENT,
216		},
217	},
218};
219
220static struct freq_tbl clk_tbl_pcm[] = {
221	{   64000, P_PLL4, 4, 1, 1536 },
222	{  128000, P_PLL4, 4, 1,  768 },
223	{  256000, P_PLL4, 4, 1,  384 },
224	{  512000, P_PLL4, 4, 1,  192 },
225	{ 1024000, P_PLL4, 4, 1,   96 },
226	{ 2048000, P_PLL4, 4, 1,   48 },
227	{ },
228};
229
230static struct clk_rcg pcm_src = {
231	.ns_reg = 0x54,
232	.md_reg = 0x58,
233	.mn = {
234		.mnctr_en_bit = 8,
235		.mnctr_reset_bit = 7,
236		.mnctr_mode_shift = 5,
237		.n_val_shift = 16,
238		.m_val_shift = 16,
239		.width = 16,
240	},
241	.p = {
242		.pre_div_shift = 3,
243		.pre_div_width = 2,
244	},
245	.s = {
246		.src_sel_shift = 0,
247		.parent_map = lcc_pxo_pll4_map,
248	},
249	.freq_tbl = clk_tbl_pcm,
250	.clkr = {
251		.enable_reg = 0x54,
252		.enable_mask = BIT(9),
253		.hw.init = &(struct clk_init_data){
254			.name = "pcm_src",
255			.parent_names = lcc_pxo_pll4,
256			.num_parents = 2,
257			.ops = &clk_rcg_ops,
258			.flags = CLK_SET_RATE_GATE,
259		},
260	},
261};
262
263static struct clk_branch pcm_clk_out = {
264	.halt_reg = 0x5c,
265	.halt_bit = 0,
266	.halt_check = BRANCH_HALT_ENABLE,
267	.clkr = {
268		.enable_reg = 0x54,
269		.enable_mask = BIT(11),
270		.hw.init = &(struct clk_init_data){
271			.name = "pcm_clk_out",
272			.parent_names = (const char *[]){ "pcm_src" },
273			.num_parents = 1,
274			.ops = &clk_branch_ops,
275			.flags = CLK_SET_RATE_PARENT,
276		},
277	},
278};
279
280static struct clk_regmap_mux pcm_clk = {
281	.reg = 0x54,
282	.shift = 10,
283	.width = 1,
284	.clkr = {
285		.hw.init = &(struct clk_init_data){
286			.name = "pcm_clk",
287			.parent_names = (const char *[]){
288				"pcm_clk_out",
289				"pcm_codec_clk",
290			},
291			.num_parents = 2,
292			.ops = &clk_regmap_mux_closest_ops,
293			.flags = CLK_SET_RATE_PARENT,
294		},
295	},
296};
297
298static struct freq_tbl clk_tbl_aif_osr[] = {
299	{  2822400, P_PLL4, 1, 147, 20480 },
300	{  4096000, P_PLL4, 1,   1,    96 },
301	{  5644800, P_PLL4, 1, 147, 10240 },
302	{  6144000, P_PLL4, 1,   1,    64 },
303	{ 11289600, P_PLL4, 1, 147,  5120 },
304	{ 12288000, P_PLL4, 1,   1,    32 },
305	{ 22579200, P_PLL4, 1, 147,  2560 },
306	{ 24576000, P_PLL4, 1,   1,    16 },
307	{ },
308};
309
310static struct clk_rcg spdif_src = {
311	.ns_reg = 0xcc,
312	.md_reg = 0xd0,
313	.mn = {
314		.mnctr_en_bit = 8,
315		.mnctr_reset_bit = 7,
316		.mnctr_mode_shift = 5,
317		.n_val_shift = 16,
318		.m_val_shift = 16,
319		.width = 8,
320	},
321	.p = {
322		.pre_div_shift = 3,
323		.pre_div_width = 2,
324	},
325	.s = {
326		.src_sel_shift = 0,
327		.parent_map = lcc_pxo_pll4_map,
328	},
329	.freq_tbl = clk_tbl_aif_osr,
330	.clkr = {
331		.enable_reg = 0xcc,
332		.enable_mask = BIT(9),
333		.hw.init = &(struct clk_init_data){
334			.name = "spdif_src",
335			.parent_names = lcc_pxo_pll4,
336			.num_parents = 2,
337			.ops = &clk_rcg_ops,
338			.flags = CLK_SET_RATE_GATE,
339		},
340	},
341};
342
343static const char * const lcc_spdif_parents[] = {
344	"spdif_src",
345};
346
347static struct clk_branch spdif_clk = {
348	.halt_reg = 0xd4,
349	.halt_bit = 1,
350	.halt_check = BRANCH_HALT_ENABLE,
351	.clkr = {
352		.enable_reg = 0xcc,
353		.enable_mask = BIT(12),
354		.hw.init = &(struct clk_init_data){
355			.name = "spdif_clk",
356			.parent_names = lcc_spdif_parents,
357			.num_parents = 1,
358			.ops = &clk_branch_ops,
359			.flags = CLK_SET_RATE_PARENT,
360		},
361	},
362};
363
364static struct freq_tbl clk_tbl_ahbix[] = {
365	{ 131072000, P_PLL4, 1, 1, 3 },
366	{ },
367};
368
369static struct clk_rcg ahbix_clk = {
370	.ns_reg = 0x38,
371	.md_reg = 0x3c,
372	.mn = {
373		.mnctr_en_bit = 8,
374		.mnctr_reset_bit = 7,
375		.mnctr_mode_shift = 5,
376		.n_val_shift = 24,
377		.m_val_shift = 8,
378		.width = 8,
379	},
380	.p = {
381		.pre_div_shift = 3,
382		.pre_div_width = 2,
383	},
384	.s = {
385		.src_sel_shift = 0,
386		.parent_map = lcc_pxo_pll4_map,
387	},
388	.freq_tbl = clk_tbl_ahbix,
389	.clkr = {
390		.enable_reg = 0x38,
391		.enable_mask = BIT(11),
392		.hw.init = &(struct clk_init_data){
393			.name = "ahbix",
394			.parent_names = lcc_pxo_pll4,
395			.num_parents = 2,
396			.ops = &clk_rcg_lcc_ops,
397		},
398	},
399};
400
401static struct clk_regmap *lcc_ipq806x_clks[] = {
402	[PLL4] = &pll4.clkr,
403	[MI2S_OSR_SRC] = &mi2s_osr_src.clkr,
404	[MI2S_OSR_CLK] = &mi2s_osr_clk.clkr,
405	[MI2S_DIV_CLK] = &mi2s_div_clk.clkr,
406	[MI2S_BIT_DIV_CLK] = &mi2s_bit_div_clk.clkr,
407	[MI2S_BIT_CLK] = &mi2s_bit_clk.clkr,
408	[PCM_SRC] = &pcm_src.clkr,
409	[PCM_CLK_OUT] = &pcm_clk_out.clkr,
410	[PCM_CLK] = &pcm_clk.clkr,
411	[SPDIF_SRC] = &spdif_src.clkr,
412	[SPDIF_CLK] = &spdif_clk.clkr,
413	[AHBIX_CLK] = &ahbix_clk.clkr,
414};
415
416static const struct regmap_config lcc_ipq806x_regmap_config = {
417	.reg_bits	= 32,
418	.reg_stride	= 4,
419	.val_bits	= 32,
420	.max_register	= 0xfc,
421	.fast_io	= true,
422};
423
424static const struct qcom_cc_desc lcc_ipq806x_desc = {
425	.config = &lcc_ipq806x_regmap_config,
426	.clks = lcc_ipq806x_clks,
427	.num_clks = ARRAY_SIZE(lcc_ipq806x_clks),
428};
429
430static const struct of_device_id lcc_ipq806x_match_table[] = {
431	{ .compatible = "qcom,lcc-ipq8064" },
432	{ }
433};
434MODULE_DEVICE_TABLE(of, lcc_ipq806x_match_table);
435
436static int lcc_ipq806x_probe(struct platform_device *pdev)
437{
438	u32 val;
439	struct regmap *regmap;
440
441	regmap = qcom_cc_map(pdev, &lcc_ipq806x_desc);
442	if (IS_ERR(regmap))
443		return PTR_ERR(regmap);
444
445	/* Configure the rate of PLL4 if the bootloader hasn't already */
446	val = regmap_read(regmap, 0x0, &val);
447	if (!val)
448		clk_pll_configure_sr(&pll4, regmap, &pll4_config, true);
449	/* Enable PLL4 source on the LPASS Primary PLL Mux */
450	regmap_write(regmap, 0xc4, 0x1);
451
452	return qcom_cc_really_probe(pdev, &lcc_ipq806x_desc, regmap);
453}
454
455static struct platform_driver lcc_ipq806x_driver = {
456	.probe		= lcc_ipq806x_probe,
457	.driver		= {
458		.name	= "lcc-ipq806x",
459		.of_match_table = lcc_ipq806x_match_table,
460	},
461};
462module_platform_driver(lcc_ipq806x_driver);
463
464MODULE_DESCRIPTION("QCOM LCC IPQ806x Driver");
465MODULE_LICENSE("GPL v2");
466MODULE_ALIAS("platform:lcc-ipq806x");
467