File Index
Files and directories
Sign in
FILE

c3-pll.c

File preview with syntax highlighting.

linux-6.19.14/drivers/clk/meson/c3-pll.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Amlogic C3 PLL Controller Driver
  4 *
  5 * Copyright (c) 2023 Amlogic, inc.
  6 * Author: Chuan Liu <chuan.liu@amlogic.com>
  7 */
  8
  9#include <linux/clk-provider.h>
 10#include <linux/platform_device.h>
 11#include "clk-regmap.h"
 12#include "clk-pll.h"
 13#include "meson-clkc-utils.h"
 14#include <dt-bindings/clock/amlogic,c3-pll-clkc.h>
 15
 16#define ANACTRL_FIXPLL_CTRL4			0x50
 17#define ANACTRL_GP0PLL_CTRL0			0x80
 18#define ANACTRL_GP0PLL_CTRL1			0x84
 19#define ANACTRL_GP0PLL_CTRL2			0x88
 20#define ANACTRL_GP0PLL_CTRL3			0x8c
 21#define ANACTRL_GP0PLL_CTRL4			0x90
 22#define ANACTRL_GP0PLL_CTRL5			0x94
 23#define ANACTRL_GP0PLL_CTRL6			0x98
 24#define ANACTRL_HIFIPLL_CTRL0			0x100
 25#define ANACTRL_HIFIPLL_CTRL1			0x104
 26#define ANACTRL_HIFIPLL_CTRL2			0x108
 27#define ANACTRL_HIFIPLL_CTRL3			0x10c
 28#define ANACTRL_HIFIPLL_CTRL4			0x110
 29#define ANACTRL_HIFIPLL_CTRL5			0x114
 30#define ANACTRL_HIFIPLL_CTRL6			0x118
 31#define ANACTRL_MPLL_CTRL0			0x180
 32#define ANACTRL_MPLL_CTRL1			0x184
 33#define ANACTRL_MPLL_CTRL2			0x188
 34#define ANACTRL_MPLL_CTRL3			0x18c
 35#define ANACTRL_MPLL_CTRL4			0x190
 36
 37static struct clk_regmap c3_fclk_50m_en = {
 38	.data = &(struct clk_regmap_gate_data) {
 39		.offset = ANACTRL_FIXPLL_CTRL4,
 40		.bit_idx = 0,
 41	},
 42	.hw.init = &(struct clk_init_data) {
 43		.name = "fclk_50m_en",
 44		.ops = &clk_regmap_gate_ro_ops,
 45		.parent_data = &(const struct clk_parent_data) {
 46			.fw_name = "fix"
 47		},
 48		.num_parents = 1,
 49	},
 50};
 51
 52static struct clk_fixed_factor c3_fclk_50m = {
 53	.mult = 1,
 54	.div = 40,
 55	.hw.init = &(struct clk_init_data) {
 56		.name = "fclk_50m",
 57		.ops = &clk_fixed_factor_ops,
 58		.parent_hws = (const struct clk_hw *[]) {
 59			&c3_fclk_50m_en.hw
 60		},
 61		.num_parents = 1,
 62	},
 63};
 64
 65static struct clk_fixed_factor c3_fclk_div2_div = {
 66	.mult = 1,
 67	.div = 2,
 68	.hw.init = &(struct clk_init_data) {
 69		.name = "fclk_div2_div",
 70		.ops = &clk_fixed_factor_ops,
 71		.parent_data = &(const struct clk_parent_data) {
 72			.fw_name = "fix"
 73		},
 74		.num_parents = 1,
 75	},
 76};
 77
 78static struct clk_regmap c3_fclk_div2 = {
 79	.data = &(struct clk_regmap_gate_data) {
 80		.offset = ANACTRL_FIXPLL_CTRL4,
 81		.bit_idx = 24,
 82	},
 83	.hw.init = &(struct clk_init_data) {
 84		.name = "fclk_div2",
 85		.ops = &clk_regmap_gate_ro_ops,
 86		.parent_hws = (const struct clk_hw *[]) {
 87			&c3_fclk_div2_div.hw
 88		},
 89		.num_parents = 1,
 90	},
 91};
 92
 93static struct clk_fixed_factor c3_fclk_div2p5_div = {
 94	.mult = 2,
 95	.div = 5,
 96	.hw.init = &(struct clk_init_data) {
 97		.name = "fclk_div2p5_div",
 98		.ops = &clk_fixed_factor_ops,
 99		.parent_data = &(const struct clk_parent_data) {
100			.fw_name = "fix"
101		},
102		.num_parents = 1,
103	},
104};
105
106static struct clk_regmap c3_fclk_div2p5 = {
107	.data = &(struct clk_regmap_gate_data) {
108		.offset = ANACTRL_FIXPLL_CTRL4,
109		.bit_idx = 4,
110	},
111	.hw.init = &(struct clk_init_data) {
112		.name = "fclk_div2p5",
113		.ops = &clk_regmap_gate_ro_ops,
114		.parent_hws = (const struct clk_hw *[]) {
115			&c3_fclk_div2p5_div.hw
116		},
117		.num_parents = 1,
118	},
119};
120
121static struct clk_fixed_factor c3_fclk_div3_div = {
122	.mult = 1,
123	.div = 3,
124	.hw.init = &(struct clk_init_data) {
125		.name = "fclk_div3_div",
126		.ops = &clk_fixed_factor_ops,
127		.parent_data = &(const struct clk_parent_data) {
128			.fw_name = "fix"
129		},
130		.num_parents = 1,
131	},
132};
133
134static struct clk_regmap c3_fclk_div3 = {
135	.data = &(struct clk_regmap_gate_data) {
136		.offset = ANACTRL_FIXPLL_CTRL4,
137		.bit_idx = 20,
138	},
139	.hw.init = &(struct clk_init_data) {
140		.name = "fclk_div3",
141		.ops = &clk_regmap_gate_ro_ops,
142		.parent_hws = (const struct clk_hw *[]) {
143			&c3_fclk_div3_div.hw
144		},
145		.num_parents = 1,
146	},
147};
148
149static struct clk_fixed_factor c3_fclk_div4_div = {
150	.mult = 1,
151	.div = 4,
152	.hw.init = &(struct clk_init_data) {
153		.name = "fclk_div4_div",
154		.ops = &clk_fixed_factor_ops,
155		.parent_data = &(const struct clk_parent_data) {
156			.fw_name = "fix"
157		},
158		.num_parents = 1,
159	},
160};
161
162static struct clk_regmap c3_fclk_div4 = {
163	.data = &(struct clk_regmap_gate_data) {
164		.offset = ANACTRL_FIXPLL_CTRL4,
165		.bit_idx = 21,
166	},
167	.hw.init = &(struct clk_init_data) {
168		.name = "fclk_div4",
169		.ops = &clk_regmap_gate_ro_ops,
170		.parent_hws = (const struct clk_hw *[]) {
171			&c3_fclk_div4_div.hw
172		},
173		.num_parents = 1,
174	},
175};
176
177static struct clk_fixed_factor c3_fclk_div5_div = {
178	.mult = 1,
179	.div = 5,
180	.hw.init = &(struct clk_init_data) {
181		.name = "fclk_div5_div",
182		.ops = &clk_fixed_factor_ops,
183		.parent_data = &(const struct clk_parent_data) {
184			.fw_name = "fix"
185		},
186		.num_parents = 1,
187	},
188};
189
190static struct clk_regmap c3_fclk_div5 = {
191	.data = &(struct clk_regmap_gate_data) {
192		.offset = ANACTRL_FIXPLL_CTRL4,
193		.bit_idx = 22,
194	},
195	.hw.init = &(struct clk_init_data) {
196		.name = "fclk_div5",
197		.ops = &clk_regmap_gate_ro_ops,
198		.parent_hws = (const struct clk_hw *[]) {
199			&c3_fclk_div5_div.hw
200		},
201		.num_parents = 1,
202	},
203};
204
205static struct clk_fixed_factor c3_fclk_div7_div = {
206	.mult = 1,
207	.div = 7,
208	.hw.init = &(struct clk_init_data) {
209		.name = "fclk_div7_div",
210		.ops = &clk_fixed_factor_ops,
211		.parent_data = &(const struct clk_parent_data) {
212			.fw_name = "fix"
213		},
214		.num_parents = 1,
215	},
216};
217
218static struct clk_regmap c3_fclk_div7 = {
219	.data = &(struct clk_regmap_gate_data) {
220		.offset = ANACTRL_FIXPLL_CTRL4,
221		.bit_idx = 23,
222	},
223	.hw.init = &(struct clk_init_data) {
224		.name = "fclk_div7",
225		.ops = &clk_regmap_gate_ro_ops,
226		.parent_hws = (const struct clk_hw *[]) {
227			&c3_fclk_div7_div.hw
228		},
229		.num_parents = 1,
230	},
231};
232
233static const struct reg_sequence c3_gp0_pll_init_regs[] = {
234	{ .reg = ANACTRL_GP0PLL_CTRL2,	.def = 0x0 },
235	{ .reg = ANACTRL_GP0PLL_CTRL3,	.def = 0x48681c00 },
236	{ .reg = ANACTRL_GP0PLL_CTRL4,  .def = 0x88770290 },
237	{ .reg = ANACTRL_GP0PLL_CTRL5,  .def = 0x3927200a },
238	{ .reg = ANACTRL_GP0PLL_CTRL6,	.def = 0x56540000 },
239};
240
241static const struct pll_mult_range c3_gp0_pll_mult_range = {
242	.min = 125,
243	.max = 250,
244};
245
246static struct clk_regmap c3_gp0_pll_dco = {
247	.data = &(struct meson_clk_pll_data) {
248		.en = {
249			.reg_off = ANACTRL_GP0PLL_CTRL0,
250			.shift   = 28,
251			.width   = 1,
252		},
253		.m = {
254			.reg_off = ANACTRL_GP0PLL_CTRL0,
255			.shift   = 0,
256			.width   = 9,
257		},
258		.frac = {
259			.reg_off = ANACTRL_GP0PLL_CTRL1,
260			.shift   = 0,
261			.width   = 19,
262		},
263		.n = {
264			.reg_off = ANACTRL_GP0PLL_CTRL0,
265			.shift   = 10,
266			.width   = 5,
267		},
268		.l = {
269			.reg_off = ANACTRL_GP0PLL_CTRL0,
270			.shift   = 31,
271			.width   = 1,
272		},
273		.rst = {
274			.reg_off = ANACTRL_GP0PLL_CTRL0,
275			.shift   = 29,
276			.width   = 1,
277		},
278		.range = &c3_gp0_pll_mult_range,
279		.init_regs = c3_gp0_pll_init_regs,
280		.init_count = ARRAY_SIZE(c3_gp0_pll_init_regs),
281	},
282	.hw.init = &(struct clk_init_data) {
283		.name = "gp0_pll_dco",
284		.ops = &meson_clk_pll_ops,
285		.parent_data = &(const struct clk_parent_data) {
286			.fw_name = "top",
287		},
288		.num_parents = 1,
289	},
290};
291
292/* The maximum frequency divider supports is 32, not 128(2^7) */
293static const struct clk_div_table c3_gp0_pll_od_table[] = {
294	{ 0,  1 },
295	{ 1,  2 },
296	{ 2,  4 },
297	{ 3,  8 },
298	{ 4, 16 },
299	{ 5, 32 },
300	{ /* sentinel */ }
301};
302
303static struct clk_regmap c3_gp0_pll = {
304	.data = &(struct clk_regmap_div_data) {
305		.offset = ANACTRL_GP0PLL_CTRL0,
306		.shift = 16,
307		.width = 3,
308		.table = c3_gp0_pll_od_table,
309	},
310	.hw.init = &(struct clk_init_data) {
311		.name = "gp0_pll",
312		.ops = &clk_regmap_divider_ops,
313		.parent_hws = (const struct clk_hw *[]) {
314			&c3_gp0_pll_dco.hw
315		},
316		.num_parents = 1,
317		.flags = CLK_SET_RATE_PARENT,
318	},
319};
320
321static const struct reg_sequence c3_hifi_pll_init_regs[] = {
322	{ .reg = ANACTRL_HIFIPLL_CTRL2,	.def = 0x0 },
323	{ .reg = ANACTRL_HIFIPLL_CTRL3,	.def = 0x6a285c00 },
324	{ .reg = ANACTRL_HIFIPLL_CTRL4, .def = 0x65771290 },
325	{ .reg = ANACTRL_HIFIPLL_CTRL5, .def = 0x3927200a },
326	{ .reg = ANACTRL_HIFIPLL_CTRL6,	.def = 0x56540000 },
327};
328
329static struct clk_regmap c3_hifi_pll_dco = {
330	.data = &(struct meson_clk_pll_data) {
331		.en = {
332			.reg_off = ANACTRL_HIFIPLL_CTRL0,
333			.shift   = 28,
334			.width   = 1,
335		},
336		.m = {
337			.reg_off = ANACTRL_HIFIPLL_CTRL0,
338			.shift   = 0,
339			.width   = 8,
340		},
341		.frac = {
342			.reg_off = ANACTRL_HIFIPLL_CTRL1,
343			.shift   = 0,
344			.width   = 19,
345		},
346		.n = {
347			.reg_off = ANACTRL_HIFIPLL_CTRL0,
348			.shift   = 10,
349			.width   = 5,
350		},
351		.l = {
352			.reg_off = ANACTRL_HIFIPLL_CTRL0,
353			.shift   = 31,
354			.width   = 1,
355		},
356		.rst = {
357			.reg_off = ANACTRL_HIFIPLL_CTRL0,
358			.shift   = 29,
359			.width   = 1,
360		},
361		.range = &c3_gp0_pll_mult_range,
362		.init_regs = c3_hifi_pll_init_regs,
363		.init_count = ARRAY_SIZE(c3_hifi_pll_init_regs),
364		.frac_max = 100000,
365	},
366	.hw.init = &(struct clk_init_data) {
367		.name = "hifi_pll_dco",
368		.ops = &meson_clk_pll_ops,
369		.parent_data = &(const struct clk_parent_data) {
370			.fw_name = "top",
371		},
372		.num_parents = 1,
373	},
374};
375
376static struct clk_regmap c3_hifi_pll = {
377	.data = &(struct clk_regmap_div_data) {
378		.offset = ANACTRL_HIFIPLL_CTRL0,
379		.shift = 16,
380		.width = 2,
381		.flags = CLK_DIVIDER_POWER_OF_TWO,
382	},
383	.hw.init = &(struct clk_init_data) {
384		.name = "hifi_pll",
385		.ops = &clk_regmap_divider_ops,
386		.parent_hws = (const struct clk_hw *[]) {
387			&c3_hifi_pll_dco.hw
388		},
389		.num_parents = 1,
390		.flags = CLK_SET_RATE_PARENT,
391	},
392};
393
394static const struct reg_sequence c3_mclk_pll_init_regs[] = {
395	{ .reg = ANACTRL_MPLL_CTRL1,	.def = 0x1420500f },
396	{ .reg = ANACTRL_MPLL_CTRL2,	.def = 0x00023041 },
397	{ .reg = ANACTRL_MPLL_CTRL3,	.def = 0x18180000 },
398	{ .reg = ANACTRL_MPLL_CTRL2,	.def = 0x00023001 }
399};
400
401static const struct pll_mult_range c3_mclk_pll_mult_range = {
402	.min = 67,
403	.max = 133,
404};
405
406static struct clk_regmap c3_mclk_pll_dco = {
407	.data = &(struct meson_clk_pll_data) {
408		.en = {
409			.reg_off = ANACTRL_MPLL_CTRL0,
410			.shift   = 28,
411			.width   = 1,
412		},
413		.m = {
414			.reg_off = ANACTRL_MPLL_CTRL0,
415			.shift   = 0,
416			.width   = 8,
417		},
418		.n = {
419			.reg_off = ANACTRL_MPLL_CTRL0,
420			.shift   = 16,
421			.width   = 5,
422		},
423		.l = {
424			.reg_off = ANACTRL_MPLL_CTRL0,
425			.shift   = 31,
426			.width   = 1,
427		},
428		.rst = {
429			.reg_off = ANACTRL_MPLL_CTRL0,
430			.shift   = 29,
431			.width   = 1,
432		},
433		.range = &c3_mclk_pll_mult_range,
434		.init_regs = c3_mclk_pll_init_regs,
435		.init_count = ARRAY_SIZE(c3_mclk_pll_init_regs),
436	},
437	.hw.init = &(struct clk_init_data) {
438		.name = "mclk_pll_dco",
439		.ops = &meson_clk_pll_ops,
440		.parent_data = &(const struct clk_parent_data) {
441			.fw_name = "mclk",
442		},
443		.num_parents = 1,
444	},
445};
446
447static const struct clk_div_table c3_mpll_pll_od_table[] = {
448	{ 0,  1 },
449	{ 1,  2 },
450	{ 2,  4 },
451	{ 3,  8 },
452	{ 4, 16 },
453	{ /* sentinel */ }
454};
455
456static struct clk_regmap c3_mclk_pll_od = {
457	.data = &(struct clk_regmap_div_data) {
458		.offset = ANACTRL_MPLL_CTRL0,
459		.shift = 12,
460		.width = 3,
461		.table = c3_mpll_pll_od_table,
462	},
463	.hw.init = &(struct clk_init_data) {
464		.name = "mclk_pll_od",
465		.ops = &clk_regmap_divider_ops,
466		.parent_hws = (const struct clk_hw *[]) {
467			&c3_mclk_pll_dco.hw },
468		.num_parents = 1,
469		.flags = CLK_SET_RATE_PARENT,
470	},
471};
472
473/* both value 0 and 1 gives divide the input rate by one */
474static struct clk_regmap c3_mclk_pll = {
475	.data = &(struct clk_regmap_div_data) {
476		.offset = ANACTRL_MPLL_CTRL4,
477		.shift = 16,
478		.width = 5,
479		.flags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
480	},
481	.hw.init = &(struct clk_init_data) {
482		.name = "mclk_pll",
483		.ops = &clk_regmap_divider_ops,
484		.parent_hws = (const struct clk_hw *[]) {
485			&c3_mclk_pll_od.hw
486		},
487		.num_parents = 1,
488		.flags = CLK_SET_RATE_PARENT,
489	},
490};
491
492static const struct clk_parent_data c3_mclk_parents[] = {
493	{ .hw = &c3_mclk_pll.hw },
494	{ .fw_name = "mclk" },
495	{ .hw = &c3_fclk_50m.hw }
496};
497
498static struct clk_regmap c3_mclk0_sel = {
499	.data = &(struct clk_regmap_mux_data) {
500		.offset = ANACTRL_MPLL_CTRL4,
501		.mask = 0x3,
502		.shift = 4,
503	},
504	.hw.init = &(struct clk_init_data) {
505		.name = "mclk0_sel",
506		.ops = &clk_regmap_mux_ops,
507		.parent_data = c3_mclk_parents,
508		.num_parents = ARRAY_SIZE(c3_mclk_parents),
509	},
510};
511
512static struct clk_regmap c3_mclk0_div_en = {
513	.data = &(struct clk_regmap_gate_data) {
514		.offset = ANACTRL_MPLL_CTRL4,
515		.bit_idx = 1,
516	},
517	.hw.init = &(struct clk_init_data) {
518		.name = "mclk0_div_en",
519		.ops = &clk_regmap_gate_ops,
520		.parent_hws = (const struct clk_hw *[]) {
521			&c3_mclk0_sel.hw
522		},
523		.num_parents = 1,
524		.flags = CLK_SET_RATE_PARENT,
525	},
526};
527
528static struct clk_regmap c3_mclk0_div = {
529	.data = &(struct clk_regmap_div_data) {
530		.offset = ANACTRL_MPLL_CTRL4,
531		.shift = 2,
532		.width = 1,
533	},
534	.hw.init = &(struct clk_init_data) {
535		.name = "mclk0_div",
536		.ops = &clk_regmap_divider_ops,
537		.parent_hws = (const struct clk_hw *[]) {
538			&c3_mclk0_div_en.hw
539		},
540		.num_parents = 1,
541		.flags = CLK_SET_RATE_PARENT,
542	},
543};
544
545static struct clk_regmap c3_mclk0 = {
546	.data = &(struct clk_regmap_gate_data) {
547		.offset = ANACTRL_MPLL_CTRL4,
548		.bit_idx = 0,
549	},
550	.hw.init = &(struct clk_init_data) {
551		.name = "mclk0",
552		.ops = &clk_regmap_gate_ops,
553		.parent_hws = (const struct clk_hw *[]) {
554			&c3_mclk0_div.hw
555		},
556		.num_parents = 1,
557		.flags = CLK_SET_RATE_PARENT,
558	},
559};
560
561static struct clk_regmap c3_mclk1_sel = {
562	.data = &(struct clk_regmap_mux_data) {
563		.offset = ANACTRL_MPLL_CTRL4,
564		.mask = 0x3,
565		.shift = 12,
566	},
567	.hw.init = &(struct clk_init_data) {
568		.name = "mclk1_sel",
569		.ops = &clk_regmap_mux_ops,
570		.parent_data = c3_mclk_parents,
571		.num_parents = ARRAY_SIZE(c3_mclk_parents),
572	},
573};
574
575static struct clk_regmap c3_mclk1_div_en = {
576	.data = &(struct clk_regmap_gate_data) {
577		.offset = ANACTRL_MPLL_CTRL4,
578		.bit_idx = 9,
579	},
580	.hw.init = &(struct clk_init_data) {
581		.name = "mclk1_div_en",
582		.ops = &clk_regmap_gate_ops,
583		.parent_hws = (const struct clk_hw *[]) {
584			&c3_mclk1_sel.hw
585		},
586		.num_parents = 1,
587		.flags = CLK_SET_RATE_PARENT,
588	},
589};
590
591static struct clk_regmap c3_mclk1_div = {
592	.data = &(struct clk_regmap_div_data) {
593		.offset = ANACTRL_MPLL_CTRL4,
594		.shift = 10,
595		.width = 1,
596	},
597	.hw.init = &(struct clk_init_data) {
598		.name = "mclk1_div",
599		.ops = &clk_regmap_divider_ops,
600		.parent_hws = (const struct clk_hw *[]) {
601			&c3_mclk1_div_en.hw
602		},
603		.num_parents = 1,
604		.flags = CLK_SET_RATE_PARENT,
605	},
606};
607
608static struct clk_regmap c3_mclk1 = {
609	.data = &(struct clk_regmap_gate_data) {
610		.offset = ANACTRL_MPLL_CTRL4,
611		.bit_idx = 8,
612	},
613	.hw.init = &(struct clk_init_data) {
614		.name = "mclk1",
615		.ops = &clk_regmap_gate_ops,
616		.parent_hws = (const struct clk_hw *[]) {
617			&c3_mclk1_div.hw
618		},
619		.num_parents = 1,
620		.flags = CLK_SET_RATE_PARENT,
621	},
622};
623
624static struct clk_hw *c3_pll_hw_clks[] = {
625	[CLKID_FCLK_50M_EN]	= &c3_fclk_50m_en.hw,
626	[CLKID_FCLK_50M]	= &c3_fclk_50m.hw,
627	[CLKID_FCLK_DIV2_DIV]	= &c3_fclk_div2_div.hw,
628	[CLKID_FCLK_DIV2]	= &c3_fclk_div2.hw,
629	[CLKID_FCLK_DIV2P5_DIV]	= &c3_fclk_div2p5_div.hw,
630	[CLKID_FCLK_DIV2P5]	= &c3_fclk_div2p5.hw,
631	[CLKID_FCLK_DIV3_DIV]	= &c3_fclk_div3_div.hw,
632	[CLKID_FCLK_DIV3]	= &c3_fclk_div3.hw,
633	[CLKID_FCLK_DIV4_DIV]	= &c3_fclk_div4_div.hw,
634	[CLKID_FCLK_DIV4]	= &c3_fclk_div4.hw,
635	[CLKID_FCLK_DIV5_DIV]	= &c3_fclk_div5_div.hw,
636	[CLKID_FCLK_DIV5]	= &c3_fclk_div5.hw,
637	[CLKID_FCLK_DIV7_DIV]	= &c3_fclk_div7_div.hw,
638	[CLKID_FCLK_DIV7]	= &c3_fclk_div7.hw,
639	[CLKID_GP0_PLL_DCO]	= &c3_gp0_pll_dco.hw,
640	[CLKID_GP0_PLL]		= &c3_gp0_pll.hw,
641	[CLKID_HIFI_PLL_DCO]	= &c3_hifi_pll_dco.hw,
642	[CLKID_HIFI_PLL]	= &c3_hifi_pll.hw,
643	[CLKID_MCLK_PLL_DCO]	= &c3_mclk_pll_dco.hw,
644	[CLKID_MCLK_PLL_OD]	= &c3_mclk_pll_od.hw,
645	[CLKID_MCLK_PLL]	= &c3_mclk_pll.hw,
646	[CLKID_MCLK0_SEL]	= &c3_mclk0_sel.hw,
647	[CLKID_MCLK0_SEL_EN]	= &c3_mclk0_div_en.hw,
648	[CLKID_MCLK0_DIV]	= &c3_mclk0_div.hw,
649	[CLKID_MCLK0]		= &c3_mclk0.hw,
650	[CLKID_MCLK1_SEL]	= &c3_mclk1_sel.hw,
651	[CLKID_MCLK1_SEL_EN]	= &c3_mclk1_div_en.hw,
652	[CLKID_MCLK1_DIV]	= &c3_mclk1_div.hw,
653	[CLKID_MCLK1]		= &c3_mclk1.hw
654};
655
656static const struct meson_clkc_data c3_pll_clkc_data = {
657	.hw_clks = {
658		.hws = c3_pll_hw_clks,
659		.num = ARRAY_SIZE(c3_pll_hw_clks),
660	},
661};
662
663static const struct of_device_id c3_pll_clkc_match_table[] = {
664	{
665		.compatible = "amlogic,c3-pll-clkc",
666		.data = &c3_pll_clkc_data,
667	},
668	{}
669};
670MODULE_DEVICE_TABLE(of, c3_pll_clkc_match_table);
671
672static struct platform_driver c3_pll_clkc_driver = {
673	.probe		= meson_clkc_mmio_probe,
674	.driver		= {
675		.name	= "c3-pll-clkc",
676		.of_match_table = c3_pll_clkc_match_table,
677	},
678};
679module_platform_driver(c3_pll_clkc_driver);
680
681MODULE_DESCRIPTION("Amlogic C3 PLL Clock Controller driver");
682MODULE_AUTHOR("Chuan Liu <chuan.liu@amlogic.com>");
683MODULE_LICENSE("GPL");
684MODULE_IMPORT_NS("CLK_MESON");
~/ Read-only file preview.