cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

da8xx-cfgchip.c (19716B)


      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_device.h>
     15#include <linux/of.h>
     16#include <linux/platform_data/clk-da8xx-cfgchip.h>
     17#include <linux/platform_device.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	.set_parent	= da8xx_cfgchip_mux_clk_set_parent,
    233	.get_parent	= da8xx_cfgchip_mux_clk_get_parent,
    234};
    235
    236static struct da8xx_cfgchip_mux_clk * __init
    237da8xx_cfgchip_mux_clk_register(struct device *dev,
    238			       const struct da8xx_cfgchip_mux_clk_info *info,
    239			       struct regmap *regmap)
    240{
    241	const char * const parent_names[] = { info->parent0, info->parent1 };
    242	struct da8xx_cfgchip_mux_clk *mux;
    243	struct clk_init_data init;
    244	int ret;
    245
    246	mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
    247	if (!mux)
    248		return ERR_PTR(-ENOMEM);
    249
    250	init.name = info->name;
    251	init.ops = &da8xx_cfgchip_mux_clk_ops;
    252	init.parent_names = parent_names;
    253	init.num_parents = 2;
    254	init.flags = 0;
    255
    256	mux->hw.init = &init;
    257	mux->regmap = regmap;
    258	mux->reg = info->cfgchip;
    259	mux->mask = info->bit;
    260
    261	ret = devm_clk_hw_register(dev, &mux->hw);
    262	if (ret < 0)
    263		return ERR_PTR(ret);
    264
    265	return mux;
    266}
    267
    268static const struct da8xx_cfgchip_mux_clk_info da850_async1_info __initconst = {
    269	.name = "async1",
    270	.parent0 = "pll0_sysclk3",
    271	.parent1 = "div4.5",
    272	.cfgchip = CFGCHIP(3),
    273	.bit = CFGCHIP3_EMA_CLKSRC,
    274};
    275
    276static int __init da8xx_cfgchip_register_async1(struct device *dev,
    277						struct regmap *regmap)
    278{
    279	struct da8xx_cfgchip_mux_clk *mux;
    280
    281	mux = da8xx_cfgchip_mux_clk_register(dev, &da850_async1_info, regmap);
    282	if (IS_ERR(mux))
    283		return PTR_ERR(mux);
    284
    285	clk_hw_register_clkdev(&mux->hw, "async1", "da850-psc0");
    286
    287	return 0;
    288}
    289
    290static const struct da8xx_cfgchip_mux_clk_info da850_async3_info __initconst = {
    291	.name = "async3",
    292	.parent0 = "pll0_sysclk2",
    293	.parent1 = "pll1_sysclk2",
    294	.cfgchip = CFGCHIP(3),
    295	.bit = CFGCHIP3_ASYNC3_CLKSRC,
    296};
    297
    298static int __init da850_cfgchip_register_async3(struct device *dev,
    299						struct regmap *regmap)
    300{
    301	struct da8xx_cfgchip_mux_clk *mux;
    302	struct clk_hw *parent;
    303
    304	mux = da8xx_cfgchip_mux_clk_register(dev, &da850_async3_info, regmap);
    305	if (IS_ERR(mux))
    306		return PTR_ERR(mux);
    307
    308	clk_hw_register_clkdev(&mux->hw, "async3", "da850-psc1");
    309
    310	/* pll1_sysclk2 is not affected by CPU scaling, so use it for async3 */
    311	parent = clk_hw_get_parent_by_index(&mux->hw, 1);
    312	if (parent)
    313		clk_set_parent(mux->hw.clk, parent->clk);
    314	else
    315		dev_warn(dev, "Failed to find async3 parent clock\n");
    316
    317	return 0;
    318}
    319
    320static int __init
    321of_da8xx_cfgchip_init_mux_clock(struct device *dev,
    322				const struct da8xx_cfgchip_mux_clk_info *info,
    323				struct regmap *regmap)
    324{
    325	struct da8xx_cfgchip_mux_clk *mux;
    326
    327	mux = da8xx_cfgchip_mux_clk_register(dev, info, regmap);
    328	if (IS_ERR(mux))
    329		return PTR_ERR(mux);
    330
    331	return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, &mux->hw);
    332}
    333
    334static int __init of_da850_async1_init(struct device *dev, struct regmap *regmap)
    335{
    336	return of_da8xx_cfgchip_init_mux_clock(dev, &da850_async1_info, regmap);
    337}
    338
    339static int __init of_da850_async3_init(struct device *dev, struct regmap *regmap)
    340{
    341	return of_da8xx_cfgchip_init_mux_clock(dev, &da850_async3_info, regmap);
    342}
    343
    344/* --- USB 2.0 PHY clock --- */
    345
    346struct da8xx_usb0_clk48 {
    347	struct clk_hw hw;
    348	struct clk *fck;
    349	struct regmap *regmap;
    350};
    351
    352#define to_da8xx_usb0_clk48(_hw) \
    353	container_of((_hw), struct da8xx_usb0_clk48, hw)
    354
    355static int da8xx_usb0_clk48_prepare(struct clk_hw *hw)
    356{
    357	struct da8xx_usb0_clk48 *usb0 = to_da8xx_usb0_clk48(hw);
    358
    359	/* The USB 2.0 PSC clock is only needed temporarily during the USB 2.0
    360	 * PHY clock enable, but since clk_prepare() can't be called in an
    361	 * atomic context (i.e. in clk_enable()), we have to prepare it here.
    362	 */
    363	return clk_prepare(usb0->fck);
    364}
    365
    366static void da8xx_usb0_clk48_unprepare(struct clk_hw *hw)
    367{
    368	struct da8xx_usb0_clk48 *usb0 = to_da8xx_usb0_clk48(hw);
    369
    370	clk_unprepare(usb0->fck);
    371}
    372
    373static int da8xx_usb0_clk48_enable(struct clk_hw *hw)
    374{
    375	struct da8xx_usb0_clk48 *usb0 = to_da8xx_usb0_clk48(hw);
    376	unsigned int mask, val;
    377	int ret;
    378
    379	/* Locking the USB 2.O PLL requires that the USB 2.O PSC is enabled
    380	 * temporaily. It can be turned back off once the PLL is locked.
    381	 */
    382	clk_enable(usb0->fck);
    383
    384	/* Turn on the USB 2.0 PHY, but just the PLL, and not OTG. The USB 1.1
    385	 * PHY may use the USB 2.0 PLL clock without USB 2.0 OTG being used.
    386	 */
    387	mask = CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN | CFGCHIP2_PHY_PLLON;
    388	val = CFGCHIP2_PHY_PLLON;
    389
    390	regmap_write_bits(usb0->regmap, CFGCHIP(2), mask, val);
    391	ret = regmap_read_poll_timeout(usb0->regmap, CFGCHIP(2), val,
    392				       val & CFGCHIP2_PHYCLKGD, 0, 500000);
    393
    394	clk_disable(usb0->fck);
    395
    396	return ret;
    397}
    398
    399static void da8xx_usb0_clk48_disable(struct clk_hw *hw)
    400{
    401	struct da8xx_usb0_clk48 *usb0 = to_da8xx_usb0_clk48(hw);
    402	unsigned int val;
    403
    404	val = CFGCHIP2_PHYPWRDN;
    405	regmap_write_bits(usb0->regmap, CFGCHIP(2), val, val);
    406}
    407
    408static int da8xx_usb0_clk48_is_enabled(struct clk_hw *hw)
    409{
    410	struct da8xx_usb0_clk48 *usb0 = to_da8xx_usb0_clk48(hw);
    411	unsigned int val;
    412
    413	regmap_read(usb0->regmap, CFGCHIP(2), &val);
    414
    415	return !!(val & CFGCHIP2_PHYCLKGD);
    416}
    417
    418static unsigned long da8xx_usb0_clk48_recalc_rate(struct clk_hw *hw,
    419						  unsigned long parent_rate)
    420{
    421	struct da8xx_usb0_clk48 *usb0 = to_da8xx_usb0_clk48(hw);
    422	unsigned int mask, val;
    423
    424	/* The parent clock rate must be one of the following */
    425	mask = CFGCHIP2_REFFREQ_MASK;
    426	switch (parent_rate) {
    427	case 12000000:
    428		val = CFGCHIP2_REFFREQ_12MHZ;
    429		break;
    430	case 13000000:
    431		val = CFGCHIP2_REFFREQ_13MHZ;
    432		break;
    433	case 19200000:
    434		val = CFGCHIP2_REFFREQ_19_2MHZ;
    435		break;
    436	case 20000000:
    437		val = CFGCHIP2_REFFREQ_20MHZ;
    438		break;
    439	case 24000000:
    440		val = CFGCHIP2_REFFREQ_24MHZ;
    441		break;
    442	case 26000000:
    443		val = CFGCHIP2_REFFREQ_26MHZ;
    444		break;
    445	case 38400000:
    446		val = CFGCHIP2_REFFREQ_38_4MHZ;
    447		break;
    448	case 40000000:
    449		val = CFGCHIP2_REFFREQ_40MHZ;
    450		break;
    451	case 48000000:
    452		val = CFGCHIP2_REFFREQ_48MHZ;
    453		break;
    454	default:
    455		return 0;
    456	}
    457
    458	regmap_write_bits(usb0->regmap, CFGCHIP(2), mask, val);
    459
    460	/* USB 2.0 PLL always supplies 48MHz */
    461	return 48000000;
    462}
    463
    464static long da8xx_usb0_clk48_round_rate(struct clk_hw *hw, unsigned long rate,
    465					unsigned long *parent_rate)
    466{
    467	return 48000000;
    468}
    469
    470static int da8xx_usb0_clk48_set_parent(struct clk_hw *hw, u8 index)
    471{
    472	struct da8xx_usb0_clk48 *usb0 = to_da8xx_usb0_clk48(hw);
    473
    474	return regmap_write_bits(usb0->regmap, CFGCHIP(2),
    475				 CFGCHIP2_USB2PHYCLKMUX,
    476				 index ? CFGCHIP2_USB2PHYCLKMUX : 0);
    477}
    478
    479static u8 da8xx_usb0_clk48_get_parent(struct clk_hw *hw)
    480{
    481	struct da8xx_usb0_clk48 *usb0 = to_da8xx_usb0_clk48(hw);
    482	unsigned int val;
    483
    484	regmap_read(usb0->regmap, CFGCHIP(2), &val);
    485
    486	return (val & CFGCHIP2_USB2PHYCLKMUX) ? 1 : 0;
    487}
    488
    489static const struct clk_ops da8xx_usb0_clk48_ops = {
    490	.prepare	= da8xx_usb0_clk48_prepare,
    491	.unprepare	= da8xx_usb0_clk48_unprepare,
    492	.enable		= da8xx_usb0_clk48_enable,
    493	.disable	= da8xx_usb0_clk48_disable,
    494	.is_enabled	= da8xx_usb0_clk48_is_enabled,
    495	.recalc_rate	= da8xx_usb0_clk48_recalc_rate,
    496	.round_rate	= da8xx_usb0_clk48_round_rate,
    497	.set_parent	= da8xx_usb0_clk48_set_parent,
    498	.get_parent	= da8xx_usb0_clk48_get_parent,
    499};
    500
    501static struct da8xx_usb0_clk48 *
    502da8xx_cfgchip_register_usb0_clk48(struct device *dev,
    503				  struct regmap *regmap)
    504{
    505	const char * const parent_names[] = { "usb_refclkin", "pll0_auxclk" };
    506	struct clk *fck_clk;
    507	struct da8xx_usb0_clk48 *usb0;
    508	struct clk_init_data init;
    509	int ret;
    510
    511	fck_clk = devm_clk_get(dev, "fck");
    512	if (IS_ERR(fck_clk)) {
    513		if (PTR_ERR(fck_clk) != -EPROBE_DEFER)
    514			dev_err(dev, "Missing fck clock\n");
    515		return ERR_CAST(fck_clk);
    516	}
    517
    518	usb0 = devm_kzalloc(dev, sizeof(*usb0), GFP_KERNEL);
    519	if (!usb0)
    520		return ERR_PTR(-ENOMEM);
    521
    522	init.name = "usb0_clk48";
    523	init.ops = &da8xx_usb0_clk48_ops;
    524	init.parent_names = parent_names;
    525	init.num_parents = 2;
    526
    527	usb0->hw.init = &init;
    528	usb0->fck = fck_clk;
    529	usb0->regmap = regmap;
    530
    531	ret = devm_clk_hw_register(dev, &usb0->hw);
    532	if (ret < 0)
    533		return ERR_PTR(ret);
    534
    535	return usb0;
    536}
    537
    538/* --- USB 1.1 PHY clock --- */
    539
    540struct da8xx_usb1_clk48 {
    541	struct clk_hw hw;
    542	struct regmap *regmap;
    543};
    544
    545#define to_da8xx_usb1_clk48(_hw) \
    546	container_of((_hw), struct da8xx_usb1_clk48, hw)
    547
    548static int da8xx_usb1_clk48_set_parent(struct clk_hw *hw, u8 index)
    549{
    550	struct da8xx_usb1_clk48 *usb1 = to_da8xx_usb1_clk48(hw);
    551
    552	return regmap_write_bits(usb1->regmap, CFGCHIP(2),
    553				 CFGCHIP2_USB1PHYCLKMUX,
    554				 index ? CFGCHIP2_USB1PHYCLKMUX : 0);
    555}
    556
    557static u8 da8xx_usb1_clk48_get_parent(struct clk_hw *hw)
    558{
    559	struct da8xx_usb1_clk48 *usb1 = to_da8xx_usb1_clk48(hw);
    560	unsigned int val;
    561
    562	regmap_read(usb1->regmap, CFGCHIP(2), &val);
    563
    564	return (val & CFGCHIP2_USB1PHYCLKMUX) ? 1 : 0;
    565}
    566
    567static const struct clk_ops da8xx_usb1_clk48_ops = {
    568	.set_parent	= da8xx_usb1_clk48_set_parent,
    569	.get_parent	= da8xx_usb1_clk48_get_parent,
    570};
    571
    572/**
    573 * da8xx_cfgchip_register_usb1_clk48 - Register a new USB 1.1 PHY clock
    574 * @dev: The device
    575 * @regmap: The CFGCHIP regmap
    576 */
    577static struct da8xx_usb1_clk48 *
    578da8xx_cfgchip_register_usb1_clk48(struct device *dev,
    579				  struct regmap *regmap)
    580{
    581	const char * const parent_names[] = { "usb0_clk48", "usb_refclkin" };
    582	struct da8xx_usb1_clk48 *usb1;
    583	struct clk_init_data init;
    584	int ret;
    585
    586	usb1 = devm_kzalloc(dev, sizeof(*usb1), GFP_KERNEL);
    587	if (!usb1)
    588		return ERR_PTR(-ENOMEM);
    589
    590	init.name = "usb1_clk48";
    591	init.ops = &da8xx_usb1_clk48_ops;
    592	init.parent_names = parent_names;
    593	init.num_parents = 2;
    594
    595	usb1->hw.init = &init;
    596	usb1->regmap = regmap;
    597
    598	ret = devm_clk_hw_register(dev, &usb1->hw);
    599	if (ret < 0)
    600		return ERR_PTR(ret);
    601
    602	return usb1;
    603}
    604
    605static int da8xx_cfgchip_register_usb_phy_clk(struct device *dev,
    606					      struct regmap *regmap)
    607{
    608	struct da8xx_usb0_clk48 *usb0;
    609	struct da8xx_usb1_clk48 *usb1;
    610	struct clk_hw *parent;
    611
    612	usb0 = da8xx_cfgchip_register_usb0_clk48(dev, regmap);
    613	if (IS_ERR(usb0))
    614		return PTR_ERR(usb0);
    615
    616	/*
    617	 * All existing boards use pll0_auxclk as the parent and new boards
    618	 * should use device tree, so hard-coding the value (1) here.
    619	 */
    620	parent = clk_hw_get_parent_by_index(&usb0->hw, 1);
    621	if (parent)
    622		clk_set_parent(usb0->hw.clk, parent->clk);
    623	else
    624		dev_warn(dev, "Failed to find usb0 parent clock\n");
    625
    626	usb1 = da8xx_cfgchip_register_usb1_clk48(dev, regmap);
    627	if (IS_ERR(usb1))
    628		return PTR_ERR(usb1);
    629
    630	/*
    631	 * All existing boards use usb0_clk48 as the parent and new boards
    632	 * should use device tree, so hard-coding the value (0) here.
    633	 */
    634	parent = clk_hw_get_parent_by_index(&usb1->hw, 0);
    635	if (parent)
    636		clk_set_parent(usb1->hw.clk, parent->clk);
    637	else
    638		dev_warn(dev, "Failed to find usb1 parent clock\n");
    639
    640	clk_hw_register_clkdev(&usb0->hw, "usb0_clk48", "da8xx-usb-phy");
    641	clk_hw_register_clkdev(&usb1->hw, "usb1_clk48", "da8xx-usb-phy");
    642
    643	return 0;
    644}
    645
    646static int of_da8xx_usb_phy_clk_init(struct device *dev, struct regmap *regmap)
    647{
    648	struct clk_hw_onecell_data *clk_data;
    649	struct da8xx_usb0_clk48 *usb0;
    650	struct da8xx_usb1_clk48 *usb1;
    651
    652	clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, 2),
    653				GFP_KERNEL);
    654	if (!clk_data)
    655		return -ENOMEM;
    656
    657	clk_data->num = 2;
    658
    659	usb0 = da8xx_cfgchip_register_usb0_clk48(dev, regmap);
    660	if (IS_ERR(usb0)) {
    661		if (PTR_ERR(usb0) == -EPROBE_DEFER)
    662			return -EPROBE_DEFER;
    663
    664		dev_warn(dev, "Failed to register usb0_clk48 (%ld)\n",
    665			 PTR_ERR(usb0));
    666
    667		clk_data->hws[0] = ERR_PTR(-ENOENT);
    668	} else {
    669		clk_data->hws[0] = &usb0->hw;
    670	}
    671
    672	usb1 = da8xx_cfgchip_register_usb1_clk48(dev, regmap);
    673	if (IS_ERR(usb1)) {
    674		if (PTR_ERR(usb1) == -EPROBE_DEFER)
    675			return -EPROBE_DEFER;
    676
    677		dev_warn(dev, "Failed to register usb1_clk48 (%ld)\n",
    678			 PTR_ERR(usb1));
    679
    680		clk_data->hws[1] = ERR_PTR(-ENOENT);
    681	} else {
    682		clk_data->hws[1] = &usb1->hw;
    683	}
    684
    685	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
    686}
    687
    688/* --- platform device --- */
    689
    690static const struct of_device_id da8xx_cfgchip_of_match[] = {
    691	{
    692		.compatible = "ti,da830-tbclksync",
    693		.data = of_da8xx_tbclksync_init,
    694	},
    695	{
    696		.compatible = "ti,da830-div4p5ena",
    697		.data = of_da8xx_div4p5ena_init,
    698	},
    699	{
    700		.compatible = "ti,da850-async1-clksrc",
    701		.data = of_da850_async1_init,
    702	},
    703	{
    704		.compatible = "ti,da850-async3-clksrc",
    705		.data = of_da850_async3_init,
    706	},
    707	{
    708		.compatible = "ti,da830-usb-phy-clocks",
    709		.data = of_da8xx_usb_phy_clk_init,
    710	},
    711	{ }
    712};
    713
    714static const struct platform_device_id da8xx_cfgchip_id_table[] = {
    715	{
    716		.name = "da830-tbclksync",
    717		.driver_data = (kernel_ulong_t)da8xx_cfgchip_register_tbclk,
    718	},
    719	{
    720		.name = "da830-div4p5ena",
    721		.driver_data = (kernel_ulong_t)da8xx_cfgchip_register_div4p5,
    722	},
    723	{
    724		.name = "da850-async1-clksrc",
    725		.driver_data = (kernel_ulong_t)da8xx_cfgchip_register_async1,
    726	},
    727	{
    728		.name = "da850-async3-clksrc",
    729		.driver_data = (kernel_ulong_t)da850_cfgchip_register_async3,
    730	},
    731	{
    732		.name = "da830-usb-phy-clks",
    733		.driver_data = (kernel_ulong_t)da8xx_cfgchip_register_usb_phy_clk,
    734	},
    735	{ }
    736};
    737
    738typedef int (*da8xx_cfgchip_init)(struct device *dev, struct regmap *regmap);
    739
    740static int da8xx_cfgchip_probe(struct platform_device *pdev)
    741{
    742	struct device *dev = &pdev->dev;
    743	struct da8xx_cfgchip_clk_platform_data *pdata = dev->platform_data;
    744	const struct of_device_id *of_id;
    745	da8xx_cfgchip_init clk_init = NULL;
    746	struct regmap *regmap = NULL;
    747
    748	of_id = of_match_device(da8xx_cfgchip_of_match, dev);
    749	if (of_id) {
    750		struct device_node *parent;
    751
    752		clk_init = of_id->data;
    753		parent = of_get_parent(dev->of_node);
    754		regmap = syscon_node_to_regmap(parent);
    755		of_node_put(parent);
    756	} else if (pdev->id_entry && pdata) {
    757		clk_init = (void *)pdev->id_entry->driver_data;
    758		regmap = pdata->cfgchip;
    759	}
    760
    761	if (!clk_init) {
    762		dev_err(dev, "unable to find driver data\n");
    763		return -EINVAL;
    764	}
    765
    766	if (IS_ERR_OR_NULL(regmap)) {
    767		dev_err(dev, "no regmap for CFGCHIP syscon\n");
    768		return regmap ? PTR_ERR(regmap) : -ENOENT;
    769	}
    770
    771	return clk_init(dev, regmap);
    772}
    773
    774static struct platform_driver da8xx_cfgchip_driver = {
    775	.probe		= da8xx_cfgchip_probe,
    776	.driver		= {
    777		.name		= "da8xx-cfgchip-clk",
    778		.of_match_table	= da8xx_cfgchip_of_match,
    779	},
    780	.id_table	= da8xx_cfgchip_id_table,
    781};
    782
    783static int __init da8xx_cfgchip_driver_init(void)
    784{
    785	return platform_driver_register(&da8xx_cfgchip_driver);
    786}
    787
    788/* has to be postcore_initcall because PSC devices depend on the async3 clock */
    789postcore_initcall(da8xx_cfgchip_driver_init);