File Index
Files and directories
Sign in
FILE

da8xx-cfgchip.c

File preview with syntax highlighting.

linux-6.19.14/drivers/clk/davinci/da8xx-cfgchip.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Clock driver for DA8xx/AM17xx/AM18xx/OMAP-L13x CFGCHIP
  4 *
  5 * Copyright (C) 2018 David Lechner <david@lechnology.com>
  6 */
  7
  8#include <linux/clk-provider.h>
  9#include <linux/clk.h>
 10#include <linux/clkdev.h>
 11#include <linux/init.h>
 12#include <linux/mfd/da8xx-cfgchip.h>
 13#include <linux/mfd/syscon.h>
 14#include <linux/of.h>
 15#include <linux/platform_data/clk-da8xx-cfgchip.h>
 16#include <linux/platform_device.h>
 17#include <linux/property.h>
 18#include <linux/regmap.h>
 19#include <linux/slab.h>
 20
 21/* --- Gate clocks --- */
 22
 23#define DA8XX_GATE_CLOCK_IS_DIV4P5	BIT(1)
 24
 25struct da8xx_cfgchip_gate_clk_info {
 26	const char *name;
 27	u32 cfgchip;
 28	u32 bit;
 29	u32 flags;
 30};
 31
 32struct da8xx_cfgchip_gate_clk {
 33	struct clk_hw hw;
 34	struct regmap *regmap;
 35	u32 reg;
 36	u32 mask;
 37};
 38
 39#define to_da8xx_cfgchip_gate_clk(_hw) \
 40	container_of((_hw), struct da8xx_cfgchip_gate_clk, hw)
 41
 42static int da8xx_cfgchip_gate_clk_enable(struct clk_hw *hw)
 43{
 44	struct da8xx_cfgchip_gate_clk *clk = to_da8xx_cfgchip_gate_clk(hw);
 45
 46	return regmap_write_bits(clk->regmap, clk->reg, clk->mask, clk->mask);
 47}
 48
 49static void da8xx_cfgchip_gate_clk_disable(struct clk_hw *hw)
 50{
 51	struct da8xx_cfgchip_gate_clk *clk = to_da8xx_cfgchip_gate_clk(hw);
 52
 53	regmap_write_bits(clk->regmap, clk->reg, clk->mask, 0);
 54}
 55
 56static int da8xx_cfgchip_gate_clk_is_enabled(struct clk_hw *hw)
 57{
 58	struct da8xx_cfgchip_gate_clk *clk = to_da8xx_cfgchip_gate_clk(hw);
 59	unsigned int val;
 60
 61	regmap_read(clk->regmap, clk->reg, &val);
 62
 63	return !!(val & clk->mask);
 64}
 65
 66static unsigned long da8xx_cfgchip_div4p5_recalc_rate(struct clk_hw *hw,
 67						      unsigned long parent_rate)
 68{
 69	/* this clock divides by 4.5 */
 70	return parent_rate * 2 / 9;
 71}
 72
 73static const struct clk_ops da8xx_cfgchip_gate_clk_ops = {
 74	.enable		= da8xx_cfgchip_gate_clk_enable,
 75	.disable	= da8xx_cfgchip_gate_clk_disable,
 76	.is_enabled	= da8xx_cfgchip_gate_clk_is_enabled,
 77};
 78
 79static const struct clk_ops da8xx_cfgchip_div4p5_clk_ops = {
 80	.enable		= da8xx_cfgchip_gate_clk_enable,
 81	.disable	= da8xx_cfgchip_gate_clk_disable,
 82	.is_enabled	= da8xx_cfgchip_gate_clk_is_enabled,
 83	.recalc_rate	= da8xx_cfgchip_div4p5_recalc_rate,
 84};
 85
 86static struct da8xx_cfgchip_gate_clk * __init
 87da8xx_cfgchip_gate_clk_register(struct device *dev,
 88				const struct da8xx_cfgchip_gate_clk_info *info,
 89				struct regmap *regmap)
 90{
 91	struct clk *parent;
 92	const char *parent_name;
 93	struct da8xx_cfgchip_gate_clk *gate;
 94	struct clk_init_data init;
 95	int ret;
 96
 97	parent = devm_clk_get(dev, NULL);
 98	if (IS_ERR(parent))
 99		return ERR_CAST(parent);
100
101	parent_name = __clk_get_name(parent);
102
103	gate = devm_kzalloc(dev, sizeof(*gate), GFP_KERNEL);
104	if (!gate)
105		return ERR_PTR(-ENOMEM);
106
107	init.name = info->name;
108	if (info->flags & DA8XX_GATE_CLOCK_IS_DIV4P5)
109		init.ops = &da8xx_cfgchip_div4p5_clk_ops;
110	else
111		init.ops = &da8xx_cfgchip_gate_clk_ops;
112	init.parent_names = &parent_name;
113	init.num_parents = 1;
114	init.flags = 0;
115
116	gate->hw.init = &init;
117	gate->regmap = regmap;
118	gate->reg = info->cfgchip;
119	gate->mask = info->bit;
120
121	ret = devm_clk_hw_register(dev, &gate->hw);
122	if (ret < 0)
123		return ERR_PTR(ret);
124
125	return gate;
126}
127
128static const struct da8xx_cfgchip_gate_clk_info da8xx_tbclksync_info __initconst = {
129	.name = "ehrpwm_tbclk",
130	.cfgchip = CFGCHIP(1),
131	.bit = CFGCHIP1_TBCLKSYNC,
132};
133
134static int __init da8xx_cfgchip_register_tbclk(struct device *dev,
135					       struct regmap *regmap)
136{
137	struct da8xx_cfgchip_gate_clk *gate;
138
139	gate = da8xx_cfgchip_gate_clk_register(dev, &da8xx_tbclksync_info,
140					       regmap);
141	if (IS_ERR(gate))
142		return PTR_ERR(gate);
143
144	clk_hw_register_clkdev(&gate->hw, "tbclk", "ehrpwm.0");
145	clk_hw_register_clkdev(&gate->hw, "tbclk", "ehrpwm.1");
146
147	return 0;
148}
149
150static const struct da8xx_cfgchip_gate_clk_info da8xx_div4p5ena_info __initconst = {
151	.name = "div4.5",
152	.cfgchip = CFGCHIP(3),
153	.bit = CFGCHIP3_DIV45PENA,
154	.flags = DA8XX_GATE_CLOCK_IS_DIV4P5,
155};
156
157static int __init da8xx_cfgchip_register_div4p5(struct device *dev,
158						struct regmap *regmap)
159{
160	struct da8xx_cfgchip_gate_clk *gate;
161
162	gate = da8xx_cfgchip_gate_clk_register(dev, &da8xx_div4p5ena_info, regmap);
163
164	return PTR_ERR_OR_ZERO(gate);
165}
166
167static int __init
168of_da8xx_cfgchip_gate_clk_init(struct device *dev,
169			       const struct da8xx_cfgchip_gate_clk_info *info,
170			       struct regmap *regmap)
171{
172	struct da8xx_cfgchip_gate_clk *gate;
173
174	gate = da8xx_cfgchip_gate_clk_register(dev, info, regmap);
175	if (IS_ERR(gate))
176		return PTR_ERR(gate);
177
178	return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, gate);
179}
180
181static int __init of_da8xx_tbclksync_init(struct device *dev,
182					  struct regmap *regmap)
183{
184	return of_da8xx_cfgchip_gate_clk_init(dev, &da8xx_tbclksync_info, regmap);
185}
186
187static int __init of_da8xx_div4p5ena_init(struct device *dev,
188					  struct regmap *regmap)
189{
190	return of_da8xx_cfgchip_gate_clk_init(dev, &da8xx_div4p5ena_info, regmap);
191}
192
193/* --- MUX clocks --- */
194
195struct da8xx_cfgchip_mux_clk_info {
196	const char *name;
197	const char *parent0;
198	const char *parent1;
199	u32 cfgchip;
200	u32 bit;
201};
202
203struct da8xx_cfgchip_mux_clk {
204	struct clk_hw hw;
205	struct regmap *regmap;
206	u32 reg;
207	u32 mask;
208};
209
210#define to_da8xx_cfgchip_mux_clk(_hw) \
211	container_of((_hw), struct da8xx_cfgchip_mux_clk, hw)
212
213static int da8xx_cfgchip_mux_clk_set_parent(struct clk_hw *hw, u8 index)
214{
215	struct da8xx_cfgchip_mux_clk *clk = to_da8xx_cfgchip_mux_clk(hw);
216	unsigned int val = index ? clk->mask : 0;
217
218	return regmap_write_bits(clk->regmap, clk->reg, clk->mask, val);
219}
220
221static u8 da8xx_cfgchip_mux_clk_get_parent(struct clk_hw *hw)
222{
223	struct da8xx_cfgchip_mux_clk *clk = to_da8xx_cfgchip_mux_clk(hw);
224	unsigned int val;
225
226	regmap_read(clk->regmap, clk->reg, &val);
227
228	return (val & clk->mask) ? 1 : 0;
229}
230
231static const struct clk_ops da8xx_cfgchip_mux_clk_ops = {
232	.determine_rate	= clk_hw_determine_rate_no_reparent,
233	.set_parent	= da8xx_cfgchip_mux_clk_set_parent,
234	.get_parent	= da8xx_cfgchip_mux_clk_get_parent,
235};
236
237static struct da8xx_cfgchip_mux_clk * __init
238da8xx_cfgchip_mux_clk_register(struct device *dev,
239			       const struct da8xx_cfgchip_mux_clk_info *info,
240			       struct regmap *regmap)
241{
242	const char * const parent_names[] = { info->parent0, info->parent1 };
243	struct da8xx_cfgchip_mux_clk *mux;
244	struct clk_init_data init;
245	int ret;
246
247	mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
248	if (!mux)
249		return ERR_PTR(-ENOMEM);
250
251	init.name = info->name;
252	init.ops = &da8xx_cfgchip_mux_clk_ops;
253	init.parent_names = parent_names;
254	init.num_parents = 2;
255	init.flags = 0;
256
257	mux->hw.init = &init;
258	mux->regmap = regmap;
259	mux->reg = info->cfgchip;
260	mux->mask = info->bit;
261
262	ret = devm_clk_hw_register(dev, &mux->hw);
263	if (ret < 0)
264		return ERR_PTR(ret);
265
266	return mux;
267}
268
269static const struct da8xx_cfgchip_mux_clk_info da850_async1_info __initconst = {
270	.name = "async1",
271	.parent0 = "pll0_sysclk3",
272	.parent1 = "div4.5",
273	.cfgchip = CFGCHIP(3),
274	.bit = CFGCHIP3_EMA_CLKSRC,
275};
276
277static int __init da8xx_cfgchip_register_async1(struct device *dev,
278						struct regmap *regmap)
279{
280	struct da8xx_cfgchip_mux_clk *mux;
281
282	mux = da8xx_cfgchip_mux_clk_register(dev, &da850_async1_info, regmap);
283	if (IS_ERR(mux))
284		return PTR_ERR(mux);
285
286	clk_hw_register_clkdev(&mux->hw, "async1", "da850-psc0");
287
288	return 0;
289}
290
291static const struct da8xx_cfgchip_mux_clk_info da850_async3_info __initconst = {
292	.name = "async3",
293	.parent0 = "pll0_sysclk2",
294	.parent1 = "pll1_sysclk2",
295	.cfgchip = CFGCHIP(3),
296	.bit = CFGCHIP3_ASYNC3_CLKSRC,
297};
298
299static int __init da850_cfgchip_register_async3(struct device *dev,
300						struct regmap *regmap)
301{
302	struct da8xx_cfgchip_mux_clk *mux;
303	struct clk_hw *parent;
304
305	mux = da8xx_cfgchip_mux_clk_register(dev, &da850_async3_info, regmap);
306	if (IS_ERR(mux))
307		return PTR_ERR(mux);
308
309	clk_hw_register_clkdev(&mux->hw, "async3", "da850-psc1");
310
311	/* pll1_sysclk2 is not affected by CPU scaling, so use it for async3 */
312	parent = clk_hw_get_parent_by_index(&mux->hw, 1);
313	if (parent)
314		clk_set_parent(mux->hw.clk, parent->clk);
315	else
316		dev_warn(dev, "Failed to find async3 parent clock\n");
317
318	return 0;
319}
320
321static int __init
322of_da8xx_cfgchip_init_mux_clock(struct device *dev,
323				const struct da8xx_cfgchip_mux_clk_info *info,
324				struct regmap *regmap)
325{
326	struct da8xx_cfgchip_mux_clk *mux;
327
328	mux = da8xx_cfgchip_mux_clk_register(dev, info, regmap);
329	if (IS_ERR(mux))
330		return PTR_ERR(mux);
331
332	return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, &mux->hw);
333}
334
335static int __init of_da850_async1_init(struct device *dev, struct regmap *regmap)
336{
337	return of_da8xx_cfgchip_init_mux_clock(dev, &da850_async1_info, regmap);
338}
339
340static int __init of_da850_async3_init(struct device *dev, struct regmap *regmap)
341{
342	return of_da8xx_cfgchip_init_mux_clock(dev, &da850_async3_info, regmap);
343}
344
345/* --- USB 2.0 PHY clock --- */
346
347struct da8xx_usb0_clk48 {
348	struct clk_hw hw;
349	struct clk *fck;
350	struct regmap *regmap;
351};
352
353#define to_da8xx_usb0_clk48(_hw) \
354	container_of((_hw), struct da8xx_usb0_clk48, hw)
355
356static int da8xx_usb0_clk48_prepare(struct clk_hw *hw)
357{
358	struct da8xx_usb0_clk48 *usb0 = to_da8xx_usb0_clk48(hw);
359
360	/* The USB 2.0 PSC clock is only needed temporarily during the USB 2.0
361	 * PHY clock enable, but since clk_prepare() can't be called in an
362	 * atomic context (i.e. in clk_enable()), we have to prepare it here.
363	 */
364	return clk_prepare(usb0->fck);
365}
366
367static void da8xx_usb0_clk48_unprepare(struct clk_hw *hw)
368{
369	struct da8xx_usb0_clk48 *usb0 = to_da8xx_usb0_clk48(hw);
370
371	clk_unprepare(usb0->fck);
372}
373
374static int da8xx_usb0_clk48_enable(struct clk_hw *hw)
375{
376	struct da8xx_usb0_clk48 *usb0 = to_da8xx_usb0_clk48(hw);
377	unsigned int mask, val;
378	int ret;
379
380	/* Locking the USB 2.O PLL requires that the USB 2.O PSC is enabled
381	 * temporaily. It can be turned back off once the PLL is locked.
382	 */
383	clk_enable(usb0->fck);
384
385	/* Turn on the USB 2.0 PHY, but just the PLL, and not OTG. The USB 1.1
386	 * PHY may use the USB 2.0 PLL clock without USB 2.0 OTG being used.
387	 */
388	mask = CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN | CFGCHIP2_PHY_PLLON;
389	val = CFGCHIP2_PHY_PLLON;
390
391	regmap_write_bits(usb0->regmap, CFGCHIP(2), mask, val);
392	ret = regmap_read_poll_timeout(usb0->regmap, CFGCHIP(2), val,
393				       val & CFGCHIP2_PHYCLKGD, 0, 500000);
394
395	clk_disable(usb0->fck);
396
397	return ret;
398}
399
400static void da8xx_usb0_clk48_disable(struct clk_hw *hw)
401{
402	struct da8xx_usb0_clk48 *usb0 = to_da8xx_usb0_clk48(hw);
403	unsigned int val;
404
405	val = CFGCHIP2_PHYPWRDN;
406	regmap_write_bits(usb0->regmap, CFGCHIP(2), val, val);
407}
408
409static int da8xx_usb0_clk48_is_enabled(struct clk_hw *hw)
410{
411	struct da8xx_usb0_clk48 *usb0 = to_da8xx_usb0_clk48(hw);
412	unsigned int val;
413
414	regmap_read(usb0->regmap, CFGCHIP(2), &val);
415
416	return !!(val & CFGCHIP2_PHYCLKGD);
417}
418
419static unsigned long da8xx_usb0_clk48_recalc_rate(struct clk_hw *hw,
420						  unsigned long parent_rate)
421{
422	struct da8xx_usb0_clk48 *usb0 = to_da8xx_usb0_clk48(hw);
423	unsigned int mask, val;
424
425	/* The parent clock rate must be one of the following */
426	mask = CFGCHIP2_REFFREQ_MASK;
427	switch (parent_rate) {
428	case 12000000:
429		val = CFGCHIP2_REFFREQ_12MHZ;
430		break;
431	case 13000000:
432		val = CFGCHIP2_REFFREQ_13MHZ;
433		break;
434	case 19200000:
435		val = CFGCHIP2_REFFREQ_19_2MHZ;
436		break;
437	case 20000000:
438		val = CFGCHIP2_REFFREQ_20MHZ;
439		break;
440	case 24000000:
441		val = CFGCHIP2_REFFREQ_24MHZ;
442		break;
443	case 26000000:
444		val = CFGCHIP2_REFFREQ_26MHZ;
445		break;
446	case 38400000:
447		val = CFGCHIP2_REFFREQ_38_4MHZ;
448		break;
449	case 40000000:
450		val = CFGCHIP2_REFFREQ_40MHZ;
451		break;
452	case 48000000:
453		val = CFGCHIP2_REFFREQ_48MHZ;
454		break;
455	default:
456		return 0;
457	}
458
459	regmap_write_bits(usb0->regmap, CFGCHIP(2), mask, val);
460
461	/* USB 2.0 PLL always supplies 48MHz */
462	return 48000000;
463}
464
465static int da8xx_usb0_clk48_determine_rate(struct clk_hw *hw,
466					   struct clk_rate_request *req)
467{
468	req->rate = 48000000;
469
470	return 0;
471}
472
473static int da8xx_usb0_clk48_set_parent(struct clk_hw *hw, u8 index)
474{
475	struct da8xx_usb0_clk48 *usb0 = to_da8xx_usb0_clk48(hw);
476
477	return regmap_write_bits(usb0->regmap, CFGCHIP(2),
478				 CFGCHIP2_USB2PHYCLKMUX,
479				 index ? CFGCHIP2_USB2PHYCLKMUX : 0);
480}
481
482static u8 da8xx_usb0_clk48_get_parent(struct clk_hw *hw)
483{
484	struct da8xx_usb0_clk48 *usb0 = to_da8xx_usb0_clk48(hw);
485	unsigned int val;
486
487	regmap_read(usb0->regmap, CFGCHIP(2), &val);
488
489	return (val & CFGCHIP2_USB2PHYCLKMUX) ? 1 : 0;
490}
491
492static const struct clk_ops da8xx_usb0_clk48_ops = {
493	.prepare	= da8xx_usb0_clk48_prepare,
494	.unprepare	= da8xx_usb0_clk48_unprepare,
495	.enable		= da8xx_usb0_clk48_enable,
496	.disable	= da8xx_usb0_clk48_disable,
497	.is_enabled	= da8xx_usb0_clk48_is_enabled,
498	.recalc_rate	= da8xx_usb0_clk48_recalc_rate,
499	.determine_rate	= da8xx_usb0_clk48_determine_rate,
500	.set_parent	= da8xx_usb0_clk48_set_parent,
501	.get_parent	= da8xx_usb0_clk48_get_parent,
502};
503
504static struct da8xx_usb0_clk48 *
505da8xx_cfgchip_register_usb0_clk48(struct device *dev,
506				  struct regmap *regmap)
507{
508	const char * const parent_names[] = { "usb_refclkin", "pll0_auxclk" };
509	struct clk *fck_clk;
510	struct da8xx_usb0_clk48 *usb0;
511	struct clk_init_data init = {};
512	int ret;
513
514	fck_clk = devm_clk_get(dev, "fck");
515	if (IS_ERR(fck_clk)) {
516		return dev_err_cast_probe(dev, fck_clk, "Missing fck clock\n");
517	}
518
519	usb0 = devm_kzalloc(dev, sizeof(*usb0), GFP_KERNEL);
520	if (!usb0)
521		return ERR_PTR(-ENOMEM);
522
523	init.name = "usb0_clk48";
524	init.ops = &da8xx_usb0_clk48_ops;
525	init.parent_names = parent_names;
526	init.num_parents = 2;
527
528	usb0->hw.init = &init;
529	usb0->fck = fck_clk;
530	usb0->regmap = regmap;
531
532	ret = devm_clk_hw_register(dev, &usb0->hw);
533	if (ret < 0)
534		return ERR_PTR(ret);
535
536	return usb0;
537}
538
539/* --- USB 1.1 PHY clock --- */
540
541struct da8xx_usb1_clk48 {
542	struct clk_hw hw;
543	struct regmap *regmap;
544};
545
546#define to_da8xx_usb1_clk48(_hw) \
547	container_of((_hw), struct da8xx_usb1_clk48, hw)
548
549static int da8xx_usb1_clk48_set_parent(struct clk_hw *hw, u8 index)
550{
551	struct da8xx_usb1_clk48 *usb1 = to_da8xx_usb1_clk48(hw);
552
553	return regmap_write_bits(usb1->regmap, CFGCHIP(2),
554				 CFGCHIP2_USB1PHYCLKMUX,
555				 index ? CFGCHIP2_USB1PHYCLKMUX : 0);
556}
557
558static u8 da8xx_usb1_clk48_get_parent(struct clk_hw *hw)
559{
560	struct da8xx_usb1_clk48 *usb1 = to_da8xx_usb1_clk48(hw);
561	unsigned int val;
562
563	regmap_read(usb1->regmap, CFGCHIP(2), &val);
564
565	return (val & CFGCHIP2_USB1PHYCLKMUX) ? 1 : 0;
566}
567
568static const struct clk_ops da8xx_usb1_clk48_ops = {
569	.determine_rate	= clk_hw_determine_rate_no_reparent,
570	.set_parent	= da8xx_usb1_clk48_set_parent,
571	.get_parent	= da8xx_usb1_clk48_get_parent,
572};
573
574/**
575 * da8xx_cfgchip_register_usb1_clk48 - Register a new USB 1.1 PHY clock
576 * @dev: The device
577 * @regmap: The CFGCHIP regmap
578 */
579static struct da8xx_usb1_clk48 *
580da8xx_cfgchip_register_usb1_clk48(struct device *dev,
581				  struct regmap *regmap)
582{
583	const char * const parent_names[] = { "usb0_clk48", "usb_refclkin" };
584	struct da8xx_usb1_clk48 *usb1;
585	struct clk_init_data init = {};
586	int ret;
587
588	usb1 = devm_kzalloc(dev, sizeof(*usb1), GFP_KERNEL);
589	if (!usb1)
590		return ERR_PTR(-ENOMEM);
591
592	init.name = "usb1_clk48";
593	init.ops = &da8xx_usb1_clk48_ops;
594	init.parent_names = parent_names;
595	init.num_parents = 2;
596
597	usb1->hw.init = &init;
598	usb1->regmap = regmap;
599
600	ret = devm_clk_hw_register(dev, &usb1->hw);
601	if (ret < 0)
602		return ERR_PTR(ret);
603
604	return usb1;
605}
606
607static int da8xx_cfgchip_register_usb_phy_clk(struct device *dev,
608					      struct regmap *regmap)
609{
610	struct da8xx_usb0_clk48 *usb0;
611	struct da8xx_usb1_clk48 *usb1;
612	struct clk_hw *parent;
613
614	usb0 = da8xx_cfgchip_register_usb0_clk48(dev, regmap);
615	if (IS_ERR(usb0))
616		return PTR_ERR(usb0);
617
618	/*
619	 * All existing boards use pll0_auxclk as the parent and new boards
620	 * should use device tree, so hard-coding the value (1) here.
621	 */
622	parent = clk_hw_get_parent_by_index(&usb0->hw, 1);
623	if (parent)
624		clk_set_parent(usb0->hw.clk, parent->clk);
625	else
626		dev_warn(dev, "Failed to find usb0 parent clock\n");
627
628	usb1 = da8xx_cfgchip_register_usb1_clk48(dev, regmap);
629	if (IS_ERR(usb1))
630		return PTR_ERR(usb1);
631
632	/*
633	 * All existing boards use usb0_clk48 as the parent and new boards
634	 * should use device tree, so hard-coding the value (0) here.
635	 */
636	parent = clk_hw_get_parent_by_index(&usb1->hw, 0);
637	if (parent)
638		clk_set_parent(usb1->hw.clk, parent->clk);
639	else
640		dev_warn(dev, "Failed to find usb1 parent clock\n");
641
642	clk_hw_register_clkdev(&usb0->hw, "usb0_clk48", "da8xx-usb-phy");
643	clk_hw_register_clkdev(&usb1->hw, "usb1_clk48", "da8xx-usb-phy");
644
645	return 0;
646}
647
648static int of_da8xx_usb_phy_clk_init(struct device *dev, struct regmap *regmap)
649{
650	struct clk_hw_onecell_data *clk_data;
651	struct da8xx_usb0_clk48 *usb0;
652	struct da8xx_usb1_clk48 *usb1;
653
654	clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, 2),
655				GFP_KERNEL);
656	if (!clk_data)
657		return -ENOMEM;
658
659	clk_data->num = 2;
660
661	usb0 = da8xx_cfgchip_register_usb0_clk48(dev, regmap);
662	if (IS_ERR(usb0)) {
663		if (PTR_ERR(usb0) == -EPROBE_DEFER)
664			return -EPROBE_DEFER;
665
666		dev_warn(dev, "Failed to register usb0_clk48 (%ld)\n",
667			 PTR_ERR(usb0));
668
669		clk_data->hws[0] = ERR_PTR(-ENOENT);
670	} else {
671		clk_data->hws[0] = &usb0->hw;
672	}
673
674	usb1 = da8xx_cfgchip_register_usb1_clk48(dev, regmap);
675	if (IS_ERR(usb1)) {
676		if (PTR_ERR(usb1) == -EPROBE_DEFER)
677			return -EPROBE_DEFER;
678
679		dev_warn(dev, "Failed to register usb1_clk48 (%ld)\n",
680			 PTR_ERR(usb1));
681
682		clk_data->hws[1] = ERR_PTR(-ENOENT);
683	} else {
684		clk_data->hws[1] = &usb1->hw;
685	}
686
687	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
688}
689
690/* --- platform device --- */
691
692static const struct of_device_id da8xx_cfgchip_of_match[] = {
693	{
694		.compatible = "ti,da830-tbclksync",
695		.data = of_da8xx_tbclksync_init,
696	},
697	{
698		.compatible = "ti,da830-div4p5ena",
699		.data = of_da8xx_div4p5ena_init,
700	},
701	{
702		.compatible = "ti,da850-async1-clksrc",
703		.data = of_da850_async1_init,
704	},
705	{
706		.compatible = "ti,da850-async3-clksrc",
707		.data = of_da850_async3_init,
708	},
709	{
710		.compatible = "ti,da830-usb-phy-clocks",
711		.data = of_da8xx_usb_phy_clk_init,
712	},
713	{ }
714};
715
716static const struct platform_device_id da8xx_cfgchip_id_table[] = {
717	{
718		.name = "da830-tbclksync",
719		.driver_data = (kernel_ulong_t)da8xx_cfgchip_register_tbclk,
720	},
721	{
722		.name = "da830-div4p5ena",
723		.driver_data = (kernel_ulong_t)da8xx_cfgchip_register_div4p5,
724	},
725	{
726		.name = "da850-async1-clksrc",
727		.driver_data = (kernel_ulong_t)da8xx_cfgchip_register_async1,
728	},
729	{
730		.name = "da850-async3-clksrc",
731		.driver_data = (kernel_ulong_t)da850_cfgchip_register_async3,
732	},
733	{
734		.name = "da830-usb-phy-clks",
735		.driver_data = (kernel_ulong_t)da8xx_cfgchip_register_usb_phy_clk,
736	},
737	{ }
738};
739
740typedef int (*da8xx_cfgchip_init)(struct device *dev, struct regmap *regmap);
741
742static int da8xx_cfgchip_probe(struct platform_device *pdev)
743{
744	struct device *dev = &pdev->dev;
745	struct da8xx_cfgchip_clk_platform_data *pdata = dev->platform_data;
746	da8xx_cfgchip_init clk_init = NULL;
747	struct regmap *regmap = NULL;
748
749	clk_init = device_get_match_data(dev);
750	if (clk_init) {
751		struct device_node *parent __free(device_node) = of_get_parent(dev->of_node);
752
753		regmap = syscon_node_to_regmap(parent);
754	} else if (pdev->id_entry && pdata) {
755		clk_init = (void *)pdev->id_entry->driver_data;
756		regmap = pdata->cfgchip;
757	}
758
759	if (!clk_init) {
760		dev_err(dev, "unable to find driver data\n");
761		return -EINVAL;
762	}
763
764	if (IS_ERR_OR_NULL(regmap)) {
765		dev_err(dev, "no regmap for CFGCHIP syscon\n");
766		return regmap ? PTR_ERR(regmap) : -ENOENT;
767	}
768
769	return clk_init(dev, regmap);
770}
771
772static struct platform_driver da8xx_cfgchip_driver = {
773	.probe		= da8xx_cfgchip_probe,
774	.driver		= {
775		.name		= "da8xx-cfgchip-clk",
776		.of_match_table	= da8xx_cfgchip_of_match,
777	},
778	.id_table	= da8xx_cfgchip_id_table,
779};
780
781static int __init da8xx_cfgchip_driver_init(void)
782{
783	return platform_driver_register(&da8xx_cfgchip_driver);
784}
785
786/* has to be postcore_initcall because PSC devices depend on the async3 clock */
787postcore_initcall(da8xx_cfgchip_driver_init);
~/ Read-only file preview.