788 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Clock driver for DA8xx/AM17xx/AM18xx/OMAP-L13x CFGCHIP4 *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 * __init87da8xx_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 else111 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 __init168of_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 * __init238da8xx_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 else316 dev_warn(dev, "Failed to find async3 parent clock\n");317 318 return 0;319}320 321static int __init322of_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.0361 * PHY clock enable, but since clk_prepare() can't be called in an362 * 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 enabled381 * 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.1386 * 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 clock576 * @dev: The device577 * @regmap: The CFGCHIP regmap578 */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 boards620 * 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 else626 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 boards634 * 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 else640 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);788