Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / drivers / clk / qcom / lcc-mdm9615.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2014, The Linux Foundation. All rights reserved.
4  * Copyright (c) BayLibre, SAS.
5  * Author : Neil Armstrong <narmstrong@baylibre.com>
6  */
7
8 #include <linux/kernel.h>
9 #include <linux/bitops.h>
10 #include <linux/err.h>
11 #include <linux/platform_device.h>
12 #include <linux/module.h>
13 #include <linux/of.h>
14 #include <linux/of_device.h>
15 #include <linux/clk-provider.h>
16 #include <linux/regmap.h>
17
18 #include <dt-bindings/clock/qcom,lcc-mdm9615.h>
19
20 #include "common.h"
21 #include "clk-regmap.h"
22 #include "clk-pll.h"
23 #include "clk-rcg.h"
24 #include "clk-branch.h"
25 #include "clk-regmap-divider.h"
26 #include "clk-regmap-mux.h"
27
28 static struct clk_pll pll4 = {
29         .l_reg = 0x4,
30         .m_reg = 0x8,
31         .n_reg = 0xc,
32         .config_reg = 0x14,
33         .mode_reg = 0x0,
34         .status_reg = 0x18,
35         .status_bit = 16,
36         .clkr.hw.init = &(struct clk_init_data){
37                 .name = "pll4",
38                 .parent_names = (const char *[]){ "cxo" },
39                 .num_parents = 1,
40                 .ops = &clk_pll_ops,
41         },
42 };
43
44 enum {
45         P_CXO,
46         P_PLL4,
47 };
48
49 static const struct parent_map lcc_cxo_pll4_map[] = {
50         { P_CXO, 0 },
51         { P_PLL4, 2 }
52 };
53
54 static const char * const lcc_cxo_pll4[] = {
55         "cxo",
56         "pll4_vote",
57 };
58
59 static struct freq_tbl clk_tbl_aif_osr_492[] = {
60         {   512000, P_PLL4, 4, 1, 240 },
61         {   768000, P_PLL4, 4, 1, 160 },
62         {  1024000, P_PLL4, 4, 1, 120 },
63         {  1536000, P_PLL4, 4, 1,  80 },
64         {  2048000, P_PLL4, 4, 1,  60 },
65         {  3072000, P_PLL4, 4, 1,  40 },
66         {  4096000, P_PLL4, 4, 1,  30 },
67         {  6144000, P_PLL4, 4, 1,  20 },
68         {  8192000, P_PLL4, 4, 1,  15 },
69         { 12288000, P_PLL4, 4, 1,  10 },
70         { 24576000, P_PLL4, 4, 1,   5 },
71         { 27000000, P_CXO,  1, 0,   0 },
72         { }
73 };
74
75 static struct freq_tbl clk_tbl_aif_osr_393[] = {
76         {   512000, P_PLL4, 4, 1, 192 },
77         {   768000, P_PLL4, 4, 1, 128 },
78         {  1024000, P_PLL4, 4, 1,  96 },
79         {  1536000, P_PLL4, 4, 1,  64 },
80         {  2048000, P_PLL4, 4, 1,  48 },
81         {  3072000, P_PLL4, 4, 1,  32 },
82         {  4096000, P_PLL4, 4, 1,  24 },
83         {  6144000, P_PLL4, 4, 1,  16 },
84         {  8192000, P_PLL4, 4, 1,  12 },
85         { 12288000, P_PLL4, 4, 1,   8 },
86         { 24576000, P_PLL4, 4, 1,   4 },
87         { 27000000, P_CXO,  1, 0,   0 },
88         { }
89 };
90
91 static struct clk_rcg mi2s_osr_src = {
92         .ns_reg = 0x48,
93         .md_reg = 0x4c,
94         .mn = {
95                 .mnctr_en_bit = 8,
96                 .mnctr_reset_bit = 7,
97                 .mnctr_mode_shift = 5,
98                 .n_val_shift = 24,
99                 .m_val_shift = 8,
100                 .width = 8,
101         },
102         .p = {
103                 .pre_div_shift = 3,
104                 .pre_div_width = 2,
105         },
106         .s = {
107                 .src_sel_shift = 0,
108                 .parent_map = lcc_cxo_pll4_map,
109         },
110         .freq_tbl = clk_tbl_aif_osr_393,
111         .clkr = {
112                 .enable_reg = 0x48,
113                 .enable_mask = BIT(9),
114                 .hw.init = &(struct clk_init_data){
115                         .name = "mi2s_osr_src",
116                         .parent_names = lcc_cxo_pll4,
117                         .num_parents = 2,
118                         .ops = &clk_rcg_ops,
119                         .flags = CLK_SET_RATE_GATE,
120                 },
121         },
122 };
123
124 static const char * const lcc_mi2s_parents[] = {
125         "mi2s_osr_src",
126 };
127
128 static struct clk_branch mi2s_osr_clk = {
129         .halt_reg = 0x50,
130         .halt_bit = 1,
131         .halt_check = BRANCH_HALT_ENABLE,
132         .clkr = {
133                 .enable_reg = 0x48,
134                 .enable_mask = BIT(17),
135                 .hw.init = &(struct clk_init_data){
136                         .name = "mi2s_osr_clk",
137                         .parent_names = lcc_mi2s_parents,
138                         .num_parents = 1,
139                         .ops = &clk_branch_ops,
140                         .flags = CLK_SET_RATE_PARENT,
141                 },
142         },
143 };
144
145 static struct clk_regmap_div mi2s_div_clk = {
146         .reg = 0x48,
147         .shift = 10,
148         .width = 4,
149         .clkr = {
150                 .enable_reg = 0x48,
151                 .enable_mask = BIT(15),
152                 .hw.init = &(struct clk_init_data){
153                         .name = "mi2s_div_clk",
154                         .parent_names = lcc_mi2s_parents,
155                         .num_parents = 1,
156                         .ops = &clk_regmap_div_ops,
157                 },
158         },
159 };
160
161 static struct clk_branch mi2s_bit_div_clk = {
162         .halt_reg = 0x50,
163         .halt_bit = 0,
164         .halt_check = BRANCH_HALT_ENABLE,
165         .clkr = {
166                 .enable_reg = 0x48,
167                 .enable_mask = BIT(15),
168                 .hw.init = &(struct clk_init_data){
169                         .name = "mi2s_bit_div_clk",
170                         .parent_names = (const char *[]){ "mi2s_div_clk" },
171                         .num_parents = 1,
172                         .ops = &clk_branch_ops,
173                         .flags = CLK_SET_RATE_PARENT,
174                 },
175         },
176 };
177
178 static struct clk_regmap_mux mi2s_bit_clk = {
179         .reg = 0x48,
180         .shift = 14,
181         .width = 1,
182         .clkr = {
183                 .hw.init = &(struct clk_init_data){
184                         .name = "mi2s_bit_clk",
185                         .parent_names = (const char *[]){
186                                 "mi2s_bit_div_clk",
187                                 "mi2s_codec_clk",
188                         },
189                         .num_parents = 2,
190                         .ops = &clk_regmap_mux_closest_ops,
191                         .flags = CLK_SET_RATE_PARENT,
192                 },
193         },
194 };
195
196 #define CLK_AIF_OSR_DIV(prefix, _ns, _md, hr)                   \
197 static struct clk_rcg prefix##_osr_src = {                      \
198         .ns_reg = _ns,                                          \
199         .md_reg = _md,                                          \
200         .mn = {                                                 \
201                 .mnctr_en_bit = 8,                              \
202                 .mnctr_reset_bit = 7,                           \
203                 .mnctr_mode_shift = 5,                          \
204                 .n_val_shift = 24,                              \
205                 .m_val_shift = 8,                               \
206                 .width = 8,                                     \
207         },                                                      \
208         .p = {                                                  \
209                 .pre_div_shift = 3,                             \
210                 .pre_div_width = 2,                             \
211         },                                                      \
212         .s = {                                                  \
213                 .src_sel_shift = 0,                             \
214                 .parent_map = lcc_cxo_pll4_map,                 \
215         },                                                      \
216         .freq_tbl = clk_tbl_aif_osr_393,                        \
217         .clkr = {                                               \
218                 .enable_reg = _ns,                              \
219                 .enable_mask = BIT(9),                          \
220                 .hw.init = &(struct clk_init_data){             \
221                         .name = #prefix "_osr_src",             \
222                         .parent_names = lcc_cxo_pll4,           \
223                         .num_parents = 2,                       \
224                         .ops = &clk_rcg_ops,                    \
225                         .flags = CLK_SET_RATE_GATE,             \
226                 },                                              \
227         },                                                      \
228 };                                                              \
229                                                                 \
230 static const char * const lcc_##prefix##_parents[] = {          \
231         #prefix "_osr_src",                                     \
232 };                                                              \
233                                                                 \
234 static struct clk_branch prefix##_osr_clk = {                   \
235         .halt_reg = hr,                                         \
236         .halt_bit = 1,                                          \
237         .halt_check = BRANCH_HALT_ENABLE,                       \
238         .clkr = {                                               \
239                 .enable_reg = _ns,                              \
240                 .enable_mask = BIT(21),                         \
241                 .hw.init = &(struct clk_init_data){             \
242                         .name = #prefix "_osr_clk",             \
243                         .parent_names = lcc_##prefix##_parents, \
244                         .num_parents = 1,                       \
245                         .ops = &clk_branch_ops,                 \
246                         .flags = CLK_SET_RATE_PARENT,           \
247                 },                                              \
248         },                                                      \
249 };                                                              \
250                                                                 \
251 static struct clk_regmap_div prefix##_div_clk = {               \
252         .reg = _ns,                                             \
253         .shift = 10,                                            \
254         .width = 8,                                             \
255         .clkr = {                                               \
256                 .hw.init = &(struct clk_init_data){             \
257                         .name = #prefix "_div_clk",             \
258                         .parent_names = lcc_##prefix##_parents, \
259                         .num_parents = 1,                       \
260                         .ops = &clk_regmap_div_ops,             \
261                 },                                              \
262         },                                                      \
263 };                                                              \
264                                                                 \
265 static struct clk_branch prefix##_bit_div_clk = {               \
266         .halt_reg = hr,                                         \
267         .halt_bit = 0,                                          \
268         .halt_check = BRANCH_HALT_ENABLE,                       \
269         .clkr = {                                               \
270                 .enable_reg = _ns,                              \
271                 .enable_mask = BIT(19),                         \
272                 .hw.init = &(struct clk_init_data){             \
273                         .name = #prefix "_bit_div_clk",         \
274                         .parent_names = (const char *[]){       \
275                                 #prefix "_div_clk"              \
276                         },                                      \
277                         .num_parents = 1,                       \
278                         .ops = &clk_branch_ops,                 \
279                         .flags = CLK_SET_RATE_PARENT,           \
280                 },                                              \
281         },                                                      \
282 };                                                              \
283                                                                 \
284 static struct clk_regmap_mux prefix##_bit_clk = {               \
285         .reg = _ns,                                             \
286         .shift = 18,                                            \
287         .width = 1,                                             \
288         .clkr = {                                               \
289                 .hw.init = &(struct clk_init_data){             \
290                         .name = #prefix "_bit_clk",             \
291                         .parent_names = (const char *[]){       \
292                                 #prefix "_bit_div_clk",         \
293                                 #prefix "_codec_clk",           \
294                         },                                      \
295                         .num_parents = 2,                       \
296                         .ops = &clk_regmap_mux_closest_ops,     \
297                         .flags = CLK_SET_RATE_PARENT,           \
298                 },                                              \
299         },                                                      \
300 }
301
302 CLK_AIF_OSR_DIV(codec_i2s_mic, 0x60, 0x64, 0x68);
303 CLK_AIF_OSR_DIV(spare_i2s_mic, 0x78, 0x7c, 0x80);
304 CLK_AIF_OSR_DIV(codec_i2s_spkr, 0x6c, 0x70, 0x74);
305 CLK_AIF_OSR_DIV(spare_i2s_spkr, 0x84, 0x88, 0x8c);
306
307 static struct freq_tbl clk_tbl_pcm_492[] = {
308         {   256000, P_PLL4, 4, 1, 480 },
309         {   512000, P_PLL4, 4, 1, 240 },
310         {   768000, P_PLL4, 4, 1, 160 },
311         {  1024000, P_PLL4, 4, 1, 120 },
312         {  1536000, P_PLL4, 4, 1,  80 },
313         {  2048000, P_PLL4, 4, 1,  60 },
314         {  3072000, P_PLL4, 4, 1,  40 },
315         {  4096000, P_PLL4, 4, 1,  30 },
316         {  6144000, P_PLL4, 4, 1,  20 },
317         {  8192000, P_PLL4, 4, 1,  15 },
318         { 12288000, P_PLL4, 4, 1,  10 },
319         { 24576000, P_PLL4, 4, 1,   5 },
320         { 27000000, P_CXO,  1, 0,   0 },
321         { }
322 };
323
324 static struct freq_tbl clk_tbl_pcm_393[] = {
325         {   256000, P_PLL4, 4, 1, 384 },
326         {   512000, P_PLL4, 4, 1, 192 },
327         {   768000, P_PLL4, 4, 1, 128 },
328         {  1024000, P_PLL4, 4, 1,  96 },
329         {  1536000, P_PLL4, 4, 1,  64 },
330         {  2048000, P_PLL4, 4, 1,  48 },
331         {  3072000, P_PLL4, 4, 1,  32 },
332         {  4096000, P_PLL4, 4, 1,  24 },
333         {  6144000, P_PLL4, 4, 1,  16 },
334         {  8192000, P_PLL4, 4, 1,  12 },
335         { 12288000, P_PLL4, 4, 1,   8 },
336         { 24576000, P_PLL4, 4, 1,   4 },
337         { 27000000, P_CXO,  1, 0,   0 },
338         { }
339 };
340
341 static struct clk_rcg pcm_src = {
342         .ns_reg = 0x54,
343         .md_reg = 0x58,
344         .mn = {
345                 .mnctr_en_bit = 8,
346                 .mnctr_reset_bit = 7,
347                 .mnctr_mode_shift = 5,
348                 .n_val_shift = 16,
349                 .m_val_shift = 16,
350                 .width = 16,
351         },
352         .p = {
353                 .pre_div_shift = 3,
354                 .pre_div_width = 2,
355         },
356         .s = {
357                 .src_sel_shift = 0,
358                 .parent_map = lcc_cxo_pll4_map,
359         },
360         .freq_tbl = clk_tbl_pcm_393,
361         .clkr = {
362                 .enable_reg = 0x54,
363                 .enable_mask = BIT(9),
364                 .hw.init = &(struct clk_init_data){
365                         .name = "pcm_src",
366                         .parent_names = lcc_cxo_pll4,
367                         .num_parents = 2,
368                         .ops = &clk_rcg_ops,
369                         .flags = CLK_SET_RATE_GATE,
370                 },
371         },
372 };
373
374 static struct clk_branch pcm_clk_out = {
375         .halt_reg = 0x5c,
376         .halt_bit = 0,
377         .halt_check = BRANCH_HALT_ENABLE,
378         .clkr = {
379                 .enable_reg = 0x54,
380                 .enable_mask = BIT(11),
381                 .hw.init = &(struct clk_init_data){
382                         .name = "pcm_clk_out",
383                         .parent_names = (const char *[]){ "pcm_src" },
384                         .num_parents = 1,
385                         .ops = &clk_branch_ops,
386                         .flags = CLK_SET_RATE_PARENT,
387                 },
388         },
389 };
390
391 static struct clk_regmap_mux pcm_clk = {
392         .reg = 0x54,
393         .shift = 10,
394         .width = 1,
395         .clkr = {
396                 .hw.init = &(struct clk_init_data){
397                         .name = "pcm_clk",
398                         .parent_names = (const char *[]){
399                                 "pcm_clk_out",
400                                 "pcm_codec_clk",
401                         },
402                         .num_parents = 2,
403                         .ops = &clk_regmap_mux_closest_ops,
404                         .flags = CLK_SET_RATE_PARENT,
405                 },
406         },
407 };
408
409 static struct clk_rcg slimbus_src = {
410         .ns_reg = 0xcc,
411         .md_reg = 0xd0,
412         .mn = {
413                 .mnctr_en_bit = 8,
414                 .mnctr_reset_bit = 7,
415                 .mnctr_mode_shift = 5,
416                 .n_val_shift = 24,
417                 .m_val_shift = 8,
418                 .width = 8,
419         },
420         .p = {
421                 .pre_div_shift = 3,
422                 .pre_div_width = 2,
423         },
424         .s = {
425                 .src_sel_shift = 0,
426                 .parent_map = lcc_cxo_pll4_map,
427         },
428         .freq_tbl = clk_tbl_aif_osr_393,
429         .clkr = {
430                 .enable_reg = 0xcc,
431                 .enable_mask = BIT(9),
432                 .hw.init = &(struct clk_init_data){
433                         .name = "slimbus_src",
434                         .parent_names = lcc_cxo_pll4,
435                         .num_parents = 2,
436                         .ops = &clk_rcg_ops,
437                         .flags = CLK_SET_RATE_GATE,
438                 },
439         },
440 };
441
442 static const char * const lcc_slimbus_parents[] = {
443         "slimbus_src",
444 };
445
446 static struct clk_branch audio_slimbus_clk = {
447         .halt_reg = 0xd4,
448         .halt_bit = 0,
449         .halt_check = BRANCH_HALT_ENABLE,
450         .clkr = {
451                 .enable_reg = 0xcc,
452                 .enable_mask = BIT(10),
453                 .hw.init = &(struct clk_init_data){
454                         .name = "audio_slimbus_clk",
455                         .parent_names = lcc_slimbus_parents,
456                         .num_parents = 1,
457                         .ops = &clk_branch_ops,
458                         .flags = CLK_SET_RATE_PARENT,
459                 },
460         },
461 };
462
463 static struct clk_branch sps_slimbus_clk = {
464         .halt_reg = 0xd4,
465         .halt_bit = 1,
466         .halt_check = BRANCH_HALT_ENABLE,
467         .clkr = {
468                 .enable_reg = 0xcc,
469                 .enable_mask = BIT(12),
470                 .hw.init = &(struct clk_init_data){
471                         .name = "sps_slimbus_clk",
472                         .parent_names = lcc_slimbus_parents,
473                         .num_parents = 1,
474                         .ops = &clk_branch_ops,
475                         .flags = CLK_SET_RATE_PARENT,
476                 },
477         },
478 };
479
480 static struct clk_regmap *lcc_mdm9615_clks[] = {
481         [PLL4] = &pll4.clkr,
482         [MI2S_OSR_SRC] = &mi2s_osr_src.clkr,
483         [MI2S_OSR_CLK] = &mi2s_osr_clk.clkr,
484         [MI2S_DIV_CLK] = &mi2s_div_clk.clkr,
485         [MI2S_BIT_DIV_CLK] = &mi2s_bit_div_clk.clkr,
486         [MI2S_BIT_CLK] = &mi2s_bit_clk.clkr,
487         [PCM_SRC] = &pcm_src.clkr,
488         [PCM_CLK_OUT] = &pcm_clk_out.clkr,
489         [PCM_CLK] = &pcm_clk.clkr,
490         [SLIMBUS_SRC] = &slimbus_src.clkr,
491         [AUDIO_SLIMBUS_CLK] = &audio_slimbus_clk.clkr,
492         [SPS_SLIMBUS_CLK] = &sps_slimbus_clk.clkr,
493         [CODEC_I2S_MIC_OSR_SRC] = &codec_i2s_mic_osr_src.clkr,
494         [CODEC_I2S_MIC_OSR_CLK] = &codec_i2s_mic_osr_clk.clkr,
495         [CODEC_I2S_MIC_DIV_CLK] = &codec_i2s_mic_div_clk.clkr,
496         [CODEC_I2S_MIC_BIT_DIV_CLK] = &codec_i2s_mic_bit_div_clk.clkr,
497         [CODEC_I2S_MIC_BIT_CLK] = &codec_i2s_mic_bit_clk.clkr,
498         [SPARE_I2S_MIC_OSR_SRC] = &spare_i2s_mic_osr_src.clkr,
499         [SPARE_I2S_MIC_OSR_CLK] = &spare_i2s_mic_osr_clk.clkr,
500         [SPARE_I2S_MIC_DIV_CLK] = &spare_i2s_mic_div_clk.clkr,
501         [SPARE_I2S_MIC_BIT_DIV_CLK] = &spare_i2s_mic_bit_div_clk.clkr,
502         [SPARE_I2S_MIC_BIT_CLK] = &spare_i2s_mic_bit_clk.clkr,
503         [CODEC_I2S_SPKR_OSR_SRC] = &codec_i2s_spkr_osr_src.clkr,
504         [CODEC_I2S_SPKR_OSR_CLK] = &codec_i2s_spkr_osr_clk.clkr,
505         [CODEC_I2S_SPKR_DIV_CLK] = &codec_i2s_spkr_div_clk.clkr,
506         [CODEC_I2S_SPKR_BIT_DIV_CLK] = &codec_i2s_spkr_bit_div_clk.clkr,
507         [CODEC_I2S_SPKR_BIT_CLK] = &codec_i2s_spkr_bit_clk.clkr,
508         [SPARE_I2S_SPKR_OSR_SRC] = &spare_i2s_spkr_osr_src.clkr,
509         [SPARE_I2S_SPKR_OSR_CLK] = &spare_i2s_spkr_osr_clk.clkr,
510         [SPARE_I2S_SPKR_DIV_CLK] = &spare_i2s_spkr_div_clk.clkr,
511         [SPARE_I2S_SPKR_BIT_DIV_CLK] = &spare_i2s_spkr_bit_div_clk.clkr,
512         [SPARE_I2S_SPKR_BIT_CLK] = &spare_i2s_spkr_bit_clk.clkr,
513 };
514
515 static const struct regmap_config lcc_mdm9615_regmap_config = {
516         .reg_bits       = 32,
517         .reg_stride     = 4,
518         .val_bits       = 32,
519         .max_register   = 0xfc,
520         .fast_io        = true,
521 };
522
523 static const struct qcom_cc_desc lcc_mdm9615_desc = {
524         .config = &lcc_mdm9615_regmap_config,
525         .clks = lcc_mdm9615_clks,
526         .num_clks = ARRAY_SIZE(lcc_mdm9615_clks),
527 };
528
529 static const struct of_device_id lcc_mdm9615_match_table[] = {
530         { .compatible = "qcom,lcc-mdm9615" },
531         { }
532 };
533 MODULE_DEVICE_TABLE(of, lcc_mdm9615_match_table);
534
535 static int lcc_mdm9615_probe(struct platform_device *pdev)
536 {
537         u32 val;
538         struct regmap *regmap;
539
540         regmap = qcom_cc_map(pdev, &lcc_mdm9615_desc);
541         if (IS_ERR(regmap))
542                 return PTR_ERR(regmap);
543
544         /* Use the correct frequency plan depending on speed of PLL4 */
545         regmap_read(regmap, 0x4, &val);
546         if (val == 0x12) {
547                 slimbus_src.freq_tbl = clk_tbl_aif_osr_492;
548                 mi2s_osr_src.freq_tbl = clk_tbl_aif_osr_492;
549                 codec_i2s_mic_osr_src.freq_tbl = clk_tbl_aif_osr_492;
550                 spare_i2s_mic_osr_src.freq_tbl = clk_tbl_aif_osr_492;
551                 codec_i2s_spkr_osr_src.freq_tbl = clk_tbl_aif_osr_492;
552                 spare_i2s_spkr_osr_src.freq_tbl = clk_tbl_aif_osr_492;
553                 pcm_src.freq_tbl = clk_tbl_pcm_492;
554         }
555         /* Enable PLL4 source on the LPASS Primary PLL Mux */
556         regmap_write(regmap, 0xc4, 0x1);
557
558         return qcom_cc_really_probe(pdev, &lcc_mdm9615_desc, regmap);
559 }
560
561 static struct platform_driver lcc_mdm9615_driver = {
562         .probe          = lcc_mdm9615_probe,
563         .driver         = {
564                 .name   = "lcc-mdm9615",
565                 .of_match_table = lcc_mdm9615_match_table,
566         },
567 };
568 module_platform_driver(lcc_mdm9615_driver);
569
570 MODULE_DESCRIPTION("QCOM LCC MDM9615 Driver");
571 MODULE_LICENSE("GPL v2");
572 MODULE_ALIAS("platform:lcc-mdm9615");