1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright 2018-2021 NXP 4 * Dong Aisheng <aisheng.dong@nxp.com> 5 */ 6 7 #include <dt-bindings/firmware/imx/rsrc.h> 8 #include <linux/arm-smccc.h> 9 #include <linux/bsearch.h> 10 #include <linux/clk-provider.h> 11 #include <linux/err.h> 12 #include <linux/of.h> 13 #include <linux/firmware/imx/svc/rm.h> 14 #include <linux/platform_device.h> 15 #include <linux/pm_domain.h> 16 #include <linux/pm_runtime.h> 17 #include <linux/slab.h> 18 #include <xen/xen.h> 19 20 #include "clk-scu.h" 21 22 #define IMX_SIP_CPUFREQ 0xC2000001 23 #define IMX_SIP_SET_CPUFREQ 0x00 24 25 static struct imx_sc_ipc *ccm_ipc_handle; 26 static struct device_node *pd_np; 27 static struct platform_driver imx_clk_scu_driver; 28 static const struct imx_clk_scu_rsrc_table *rsrc_table; 29 30 struct imx_scu_clk_node { 31 const char *name; 32 u32 rsrc; 33 u8 clk_type; 34 const char * const *parents; 35 int num_parents; 36 37 struct clk_hw *hw; 38 struct list_head node; 39 }; 40 41 struct list_head imx_scu_clks[IMX_SC_R_LAST]; 42 43 /* 44 * struct clk_scu - Description of one SCU clock 45 * @hw: the common clk_hw 46 * @rsrc_id: resource ID of this SCU clock 47 * @clk_type: type of this clock resource 48 */ 49 struct clk_scu { 50 struct clk_hw hw; 51 u16 rsrc_id; 52 u8 clk_type; 53 54 /* for state save&restore */ 55 struct clk_hw *parent; 56 u8 parent_index; 57 bool is_enabled; 58 u32 rate; 59 }; 60 61 /* 62 * struct clk_gpr_scu - Description of one SCU GPR clock 63 * @hw: the common clk_hw 64 * @rsrc_id: resource ID of this SCU clock 65 * @gpr_id: GPR ID index to control the divider 66 */ 67 struct clk_gpr_scu { 68 struct clk_hw hw; 69 u16 rsrc_id; 70 u8 gpr_id; 71 u8 flags; 72 bool gate_invert; 73 }; 74 75 #define to_clk_gpr_scu(_hw) container_of(_hw, struct clk_gpr_scu, hw) 76 77 /* 78 * struct imx_sc_msg_req_set_clock_rate - clock set rate protocol 79 * @hdr: SCU protocol header 80 * @rate: rate to set 81 * @resource: clock resource to set rate 82 * @clk: clk type of this resource 83 * 84 * This structure describes the SCU protocol of clock rate set 85 */ 86 struct imx_sc_msg_req_set_clock_rate { 87 struct imx_sc_rpc_msg hdr; 88 __le32 rate; 89 __le16 resource; 90 u8 clk; 91 } __packed __aligned(4); 92 93 struct req_get_clock_rate { 94 __le16 resource; 95 u8 clk; 96 } __packed __aligned(4); 97 98 struct resp_get_clock_rate { 99 __le32 rate; 100 }; 101 102 /* 103 * struct imx_sc_msg_get_clock_rate - clock get rate protocol 104 * @hdr: SCU protocol header 105 * @req: get rate request protocol 106 * @resp: get rate response protocol 107 * 108 * This structure describes the SCU protocol of clock rate get 109 */ 110 struct imx_sc_msg_get_clock_rate { 111 struct imx_sc_rpc_msg hdr; 112 union { 113 struct req_get_clock_rate req; 114 struct resp_get_clock_rate resp; 115 } data; 116 }; 117 118 /* 119 * struct imx_sc_msg_get_clock_parent - clock get parent protocol 120 * @hdr: SCU protocol header 121 * @req: get parent request protocol 122 * @resp: get parent response protocol 123 * 124 * This structure describes the SCU protocol of clock get parent 125 */ 126 struct imx_sc_msg_get_clock_parent { 127 struct imx_sc_rpc_msg hdr; 128 union { 129 struct req_get_clock_parent { 130 __le16 resource; 131 u8 clk; 132 } __packed __aligned(4) req; 133 struct resp_get_clock_parent { 134 u8 parent; 135 } resp; 136 } data; 137 }; 138 139 /* 140 * struct imx_sc_msg_set_clock_parent - clock set parent protocol 141 * @hdr: SCU protocol header 142 * @req: set parent request protocol 143 * 144 * This structure describes the SCU protocol of clock set parent 145 */ 146 struct imx_sc_msg_set_clock_parent { 147 struct imx_sc_rpc_msg hdr; 148 __le16 resource; 149 u8 clk; 150 u8 parent; 151 } __packed; 152 153 /* 154 * struct imx_sc_msg_req_clock_enable - clock gate protocol 155 * @hdr: SCU protocol header 156 * @resource: clock resource to gate 157 * @clk: clk type of this resource 158 * @enable: whether gate off the clock 159 * @autog: HW auto gate enable 160 * 161 * This structure describes the SCU protocol of clock gate 162 */ 163 struct imx_sc_msg_req_clock_enable { 164 struct imx_sc_rpc_msg hdr; 165 __le16 resource; 166 u8 clk; 167 u8 enable; 168 u8 autog; 169 } __packed __aligned(4); 170 171 static inline struct clk_scu *to_clk_scu(struct clk_hw *hw) 172 { 173 return container_of(hw, struct clk_scu, hw); 174 } 175 176 static inline int imx_scu_clk_search_cmp(const void *rsrc, const void *rsrc_p) 177 { 178 return *(u32 *)rsrc - *(u32 *)rsrc_p; 179 } 180 181 static bool imx_scu_clk_is_valid(u32 rsrc_id) 182 { 183 void *p; 184 185 if (!rsrc_table) 186 return true; 187 188 p = bsearch(&rsrc_id, rsrc_table->rsrc, rsrc_table->num, 189 sizeof(rsrc_table->rsrc[0]), imx_scu_clk_search_cmp); 190 191 return p != NULL; 192 } 193 194 int __init imx_clk_scu_module_init(void) 195 { 196 return platform_driver_register(&imx_clk_scu_driver); 197 } 198 199 void __exit imx_clk_scu_module_exit(void) 200 { 201 return platform_driver_unregister(&imx_clk_scu_driver); 202 } 203 204 int imx_clk_scu_init(struct device_node *np, 205 const struct imx_clk_scu_rsrc_table *data) 206 { 207 u32 clk_cells; 208 int ret, i; 209 210 ret = imx_scu_get_handle(&ccm_ipc_handle); 211 if (ret) 212 return ret; 213 214 of_property_read_u32(np, "#clock-cells", &clk_cells); 215 216 if (clk_cells == 2) { 217 for (i = 0; i < IMX_SC_R_LAST; i++) 218 INIT_LIST_HEAD(&imx_scu_clks[i]); 219 220 /* pd_np will be used to attach power domains later */ 221 pd_np = of_find_compatible_node(NULL, NULL, "fsl,scu-pd"); 222 if (!pd_np) 223 return -EINVAL; 224 225 rsrc_table = data; 226 } 227 228 return 0; 229 } 230 231 /* 232 * clk_scu_recalc_rate - Get clock rate for a SCU clock 233 * @hw: clock to get rate for 234 * @parent_rate: parent rate provided by common clock framework, not used 235 * 236 * Gets the current clock rate of a SCU clock. Returns the current 237 * clock rate, or zero in failure. 238 */ 239 static unsigned long clk_scu_recalc_rate(struct clk_hw *hw, 240 unsigned long parent_rate) 241 { 242 struct clk_scu *clk = to_clk_scu(hw); 243 struct imx_sc_msg_get_clock_rate msg; 244 struct imx_sc_rpc_msg *hdr = &msg.hdr; 245 int ret; 246 247 hdr->ver = IMX_SC_RPC_VERSION; 248 hdr->svc = IMX_SC_RPC_SVC_PM; 249 hdr->func = IMX_SC_PM_FUNC_GET_CLOCK_RATE; 250 hdr->size = 2; 251 252 msg.data.req.resource = cpu_to_le16(clk->rsrc_id); 253 msg.data.req.clk = clk->clk_type; 254 255 ret = imx_scu_call_rpc(ccm_ipc_handle, &msg, true); 256 if (ret) { 257 pr_err("%s: failed to get clock rate %d\n", 258 clk_hw_get_name(hw), ret); 259 return 0; 260 } 261 262 return le32_to_cpu(msg.data.resp.rate); 263 } 264 265 /* 266 * clk_scu_determine_rate - Returns the closest rate for a SCU clock 267 * @hw: clock to round rate for 268 * @req: clock rate request 269 * 270 * Returns 0 on success, a negative error on failure 271 */ 272 static int clk_scu_determine_rate(struct clk_hw *hw, 273 struct clk_rate_request *req) 274 { 275 /* 276 * Assume we support all the requested rate and let the SCU firmware 277 * to handle the left work 278 */ 279 return 0; 280 } 281 282 static int clk_scu_atf_set_cpu_rate(struct clk_hw *hw, unsigned long rate, 283 unsigned long parent_rate) 284 { 285 struct clk_scu *clk = to_clk_scu(hw); 286 struct arm_smccc_res res; 287 unsigned long cluster_id; 288 289 if (clk->rsrc_id == IMX_SC_R_A35 || clk->rsrc_id == IMX_SC_R_A53) 290 cluster_id = 0; 291 else if (clk->rsrc_id == IMX_SC_R_A72) 292 cluster_id = 1; 293 else 294 return -EINVAL; 295 296 /* CPU frequency scaling can ONLY be done by ARM-Trusted-Firmware */ 297 arm_smccc_smc(IMX_SIP_CPUFREQ, IMX_SIP_SET_CPUFREQ, 298 cluster_id, rate, 0, 0, 0, 0, &res); 299 300 return 0; 301 } 302 303 /* 304 * clk_scu_set_rate - Set rate for a SCU clock 305 * @hw: clock to change rate for 306 * @rate: target rate for the clock 307 * @parent_rate: rate of the clock parent, not used for SCU clocks 308 * 309 * Sets a clock frequency for a SCU clock. Returns the SCU 310 * protocol status. 311 */ 312 static int clk_scu_set_rate(struct clk_hw *hw, unsigned long rate, 313 unsigned long parent_rate) 314 { 315 struct clk_scu *clk = to_clk_scu(hw); 316 struct imx_sc_msg_req_set_clock_rate msg; 317 struct imx_sc_rpc_msg *hdr = &msg.hdr; 318 319 hdr->ver = IMX_SC_RPC_VERSION; 320 hdr->svc = IMX_SC_RPC_SVC_PM; 321 hdr->func = IMX_SC_PM_FUNC_SET_CLOCK_RATE; 322 hdr->size = 3; 323 324 msg.rate = cpu_to_le32(rate); 325 msg.resource = cpu_to_le16(clk->rsrc_id); 326 msg.clk = clk->clk_type; 327 328 return imx_scu_call_rpc(ccm_ipc_handle, &msg, true); 329 } 330 331 static u8 clk_scu_get_parent(struct clk_hw *hw) 332 { 333 struct clk_scu *clk = to_clk_scu(hw); 334 struct imx_sc_msg_get_clock_parent msg; 335 struct imx_sc_rpc_msg *hdr = &msg.hdr; 336 int ret; 337 338 hdr->ver = IMX_SC_RPC_VERSION; 339 hdr->svc = IMX_SC_RPC_SVC_PM; 340 hdr->func = IMX_SC_PM_FUNC_GET_CLOCK_PARENT; 341 hdr->size = 2; 342 343 msg.data.req.resource = cpu_to_le16(clk->rsrc_id); 344 msg.data.req.clk = clk->clk_type; 345 346 ret = imx_scu_call_rpc(ccm_ipc_handle, &msg, true); 347 if (ret) { 348 pr_err("%s: failed to get clock parent %d\n", 349 clk_hw_get_name(hw), ret); 350 return 0; 351 } 352 353 clk->parent_index = msg.data.resp.parent; 354 355 return msg.data.resp.parent; 356 } 357 358 static int clk_scu_set_parent(struct clk_hw *hw, u8 index) 359 { 360 struct clk_scu *clk = to_clk_scu(hw); 361 struct imx_sc_msg_set_clock_parent msg; 362 struct imx_sc_rpc_msg *hdr = &msg.hdr; 363 int ret; 364 365 hdr->ver = IMX_SC_RPC_VERSION; 366 hdr->svc = IMX_SC_RPC_SVC_PM; 367 hdr->func = IMX_SC_PM_FUNC_SET_CLOCK_PARENT; 368 hdr->size = 2; 369 370 msg.resource = cpu_to_le16(clk->rsrc_id); 371 msg.clk = clk->clk_type; 372 msg.parent = index; 373 374 ret = imx_scu_call_rpc(ccm_ipc_handle, &msg, true); 375 if (ret) { 376 pr_err("%s: failed to set clock parent %d\n", 377 clk_hw_get_name(hw), ret); 378 return ret; 379 } 380 381 clk->parent_index = index; 382 383 return 0; 384 } 385 386 static int sc_pm_clock_enable(struct imx_sc_ipc *ipc, u16 resource, 387 u8 clk, bool enable, bool autog) 388 { 389 struct imx_sc_msg_req_clock_enable msg; 390 struct imx_sc_rpc_msg *hdr = &msg.hdr; 391 392 hdr->ver = IMX_SC_RPC_VERSION; 393 hdr->svc = IMX_SC_RPC_SVC_PM; 394 hdr->func = IMX_SC_PM_FUNC_CLOCK_ENABLE; 395 hdr->size = 3; 396 397 msg.resource = cpu_to_le16(resource); 398 msg.clk = clk; 399 msg.enable = enable; 400 msg.autog = autog; 401 402 return imx_scu_call_rpc(ccm_ipc_handle, &msg, true); 403 } 404 405 /* 406 * clk_scu_prepare - Enable a SCU clock 407 * @hw: clock to enable 408 * 409 * Enable the clock at the DSC slice level 410 */ 411 static int clk_scu_prepare(struct clk_hw *hw) 412 { 413 struct clk_scu *clk = to_clk_scu(hw); 414 415 return sc_pm_clock_enable(ccm_ipc_handle, clk->rsrc_id, 416 clk->clk_type, true, false); 417 } 418 419 /* 420 * clk_scu_unprepare - Disable a SCU clock 421 * @hw: clock to enable 422 * 423 * Disable the clock at the DSC slice level 424 */ 425 static void clk_scu_unprepare(struct clk_hw *hw) 426 { 427 struct clk_scu *clk = to_clk_scu(hw); 428 int ret; 429 430 ret = sc_pm_clock_enable(ccm_ipc_handle, clk->rsrc_id, 431 clk->clk_type, false, false); 432 if (ret) 433 pr_warn("%s: clk unprepare failed %d\n", clk_hw_get_name(hw), 434 ret); 435 } 436 437 static const struct clk_ops clk_scu_ops = { 438 .recalc_rate = clk_scu_recalc_rate, 439 .determine_rate = clk_scu_determine_rate, 440 .set_rate = clk_scu_set_rate, 441 .get_parent = clk_scu_get_parent, 442 .set_parent = clk_scu_set_parent, 443 .prepare = clk_scu_prepare, 444 .unprepare = clk_scu_unprepare, 445 }; 446 447 static const struct clk_ops clk_scu_cpu_ops = { 448 .recalc_rate = clk_scu_recalc_rate, 449 .determine_rate = clk_scu_determine_rate, 450 .set_rate = clk_scu_atf_set_cpu_rate, 451 .prepare = clk_scu_prepare, 452 .unprepare = clk_scu_unprepare, 453 }; 454 455 static const struct clk_ops clk_scu_pi_ops = { 456 .recalc_rate = clk_scu_recalc_rate, 457 .determine_rate = clk_scu_determine_rate, 458 .set_rate = clk_scu_set_rate, 459 }; 460 461 struct clk_hw *__imx_clk_scu(struct device *dev, const char *name, 462 const char * const *parents, int num_parents, 463 u32 rsrc_id, u8 clk_type) 464 { 465 struct clk_init_data init; 466 struct clk_scu *clk; 467 struct clk_hw *hw; 468 int ret; 469 470 clk = kzalloc_obj(*clk); 471 if (!clk) 472 return ERR_PTR(-ENOMEM); 473 474 clk->rsrc_id = rsrc_id; 475 clk->clk_type = clk_type; 476 477 init.name = name; 478 init.ops = &clk_scu_ops; 479 if (rsrc_id == IMX_SC_R_A35 || rsrc_id == IMX_SC_R_A53 || rsrc_id == IMX_SC_R_A72) 480 init.ops = &clk_scu_cpu_ops; 481 else if (rsrc_id == IMX_SC_R_PI_0_PLL) 482 init.ops = &clk_scu_pi_ops; 483 else 484 init.ops = &clk_scu_ops; 485 init.parent_names = parents; 486 init.num_parents = num_parents; 487 488 /* 489 * Note on MX8, the clocks are tightly coupled with power domain 490 * that once the power domain is off, the clock status may be 491 * lost. So we make it NOCACHE to let user to retrieve the real 492 * clock status from HW instead of using the possible invalid 493 * cached rate. 494 */ 495 init.flags = CLK_GET_RATE_NOCACHE; 496 clk->hw.init = &init; 497 498 hw = &clk->hw; 499 ret = clk_hw_register(dev, hw); 500 if (ret) { 501 kfree(clk); 502 hw = ERR_PTR(ret); 503 return hw; 504 } 505 506 if (dev) 507 dev_set_drvdata(dev, clk); 508 509 return hw; 510 } 511 512 struct clk_hw *imx_scu_of_clk_src_get(struct of_phandle_args *clkspec, 513 void *data) 514 { 515 unsigned int rsrc = clkspec->args[0]; 516 unsigned int idx = clkspec->args[1]; 517 struct list_head *scu_clks = data; 518 struct imx_scu_clk_node *clk; 519 520 list_for_each_entry(clk, &scu_clks[rsrc], node) { 521 if (clk->clk_type == idx) 522 return clk->hw; 523 } 524 525 return ERR_PTR(-ENODEV); 526 } 527 528 static int imx_clk_scu_probe(struct platform_device *pdev) 529 { 530 struct device *dev = &pdev->dev; 531 struct imx_scu_clk_node *clk = dev_get_platdata(dev); 532 struct clk_hw *hw; 533 int ret; 534 535 if (!((clk->rsrc == IMX_SC_R_A35) || (clk->rsrc == IMX_SC_R_A53) || 536 (clk->rsrc == IMX_SC_R_A72))) { 537 pm_runtime_set_suspended(dev); 538 pm_runtime_set_autosuspend_delay(dev, 50); 539 pm_runtime_use_autosuspend(&pdev->dev); 540 pm_runtime_enable(dev); 541 542 ret = pm_runtime_resume_and_get(dev); 543 if (ret) { 544 pm_genpd_remove_device(dev); 545 pm_runtime_disable(dev); 546 return ret; 547 } 548 } 549 550 hw = __imx_clk_scu(dev, clk->name, clk->parents, clk->num_parents, 551 clk->rsrc, clk->clk_type); 552 if (IS_ERR(hw)) { 553 pm_runtime_disable(dev); 554 return PTR_ERR(hw); 555 } 556 557 clk->hw = hw; 558 list_add_tail(&clk->node, &imx_scu_clks[clk->rsrc]); 559 560 if (!((clk->rsrc == IMX_SC_R_A35) || (clk->rsrc == IMX_SC_R_A53) || 561 (clk->rsrc == IMX_SC_R_A72))) { 562 pm_runtime_put_autosuspend(&pdev->dev); 563 } 564 565 dev_dbg(dev, "register SCU clock rsrc:%d type:%d\n", clk->rsrc, 566 clk->clk_type); 567 568 return 0; 569 } 570 571 static int __maybe_unused imx_clk_scu_suspend(struct device *dev) 572 { 573 struct clk_scu *clk = dev_get_drvdata(dev); 574 u32 rsrc_id = clk->rsrc_id; 575 576 if ((rsrc_id == IMX_SC_R_A35) || (rsrc_id == IMX_SC_R_A53) || 577 (rsrc_id == IMX_SC_R_A72)) 578 return 0; 579 580 clk->parent = clk_hw_get_parent(&clk->hw); 581 582 /* DC SS needs to handle bypass clock using non-cached clock rate */ 583 if (clk->rsrc_id == IMX_SC_R_DC_0_VIDEO0 || 584 clk->rsrc_id == IMX_SC_R_DC_0_VIDEO1 || 585 clk->rsrc_id == IMX_SC_R_DC_1_VIDEO0 || 586 clk->rsrc_id == IMX_SC_R_DC_1_VIDEO1) 587 clk->rate = clk_scu_recalc_rate(&clk->hw, 0); 588 else 589 clk->rate = clk_hw_get_rate(&clk->hw); 590 clk->is_enabled = clk_hw_is_prepared(&clk->hw); 591 592 if (clk->parent) 593 dev_dbg(dev, "save parent %s idx %u\n", clk_hw_get_name(clk->parent), 594 clk->parent_index); 595 596 if (clk->rate) 597 dev_dbg(dev, "save rate %d\n", clk->rate); 598 599 if (clk->is_enabled) 600 dev_dbg(dev, "save enabled state\n"); 601 602 return 0; 603 } 604 605 static int __maybe_unused imx_clk_scu_resume(struct device *dev) 606 { 607 struct clk_scu *clk = dev_get_drvdata(dev); 608 u32 rsrc_id = clk->rsrc_id; 609 int ret = 0; 610 611 if ((rsrc_id == IMX_SC_R_A35) || (rsrc_id == IMX_SC_R_A53) || 612 (rsrc_id == IMX_SC_R_A72)) 613 return 0; 614 615 if (clk->parent) { 616 ret = clk_scu_set_parent(&clk->hw, clk->parent_index); 617 dev_dbg(dev, "restore parent %s idx %u %s\n", 618 clk_hw_get_name(clk->parent), 619 clk->parent_index, !ret ? "success" : "failed"); 620 } 621 622 if (clk->rate) { 623 ret = clk_scu_set_rate(&clk->hw, clk->rate, 0); 624 dev_dbg(dev, "restore rate %d %s\n", clk->rate, 625 !ret ? "success" : "failed"); 626 } 627 628 if (clk->is_enabled && rsrc_id != IMX_SC_R_PI_0_PLL) { 629 ret = clk_scu_prepare(&clk->hw); 630 dev_dbg(dev, "restore enabled state %s\n", 631 !ret ? "success" : "failed"); 632 } 633 634 return ret; 635 } 636 637 static const struct dev_pm_ops imx_clk_scu_pm_ops = { 638 SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(imx_clk_scu_suspend, 639 imx_clk_scu_resume) 640 }; 641 642 static struct platform_driver imx_clk_scu_driver = { 643 .driver = { 644 .name = "imx-scu-clk", 645 .suppress_bind_attrs = true, 646 .pm = &imx_clk_scu_pm_ops, 647 }, 648 .probe = imx_clk_scu_probe, 649 }; 650 651 static int imx_clk_scu_attach_pd(struct device *dev, u32 rsrc_id) 652 { 653 struct of_phandle_args genpdspec = { 654 .np = pd_np, 655 .args_count = 1, 656 .args[0] = rsrc_id, 657 }; 658 659 if (rsrc_id == IMX_SC_R_A35 || rsrc_id == IMX_SC_R_A53 || 660 rsrc_id == IMX_SC_R_A72) 661 return 0; 662 663 return of_genpd_add_device(&genpdspec, dev); 664 } 665 666 static bool imx_clk_is_resource_owned(u32 rsrc) 667 { 668 /* 669 * A-core resources are special. SCFW reports they are not "owned" by 670 * current partition but linux can still adjust them for cpufreq. 671 */ 672 if (rsrc == IMX_SC_R_A53 || rsrc == IMX_SC_R_A72 || rsrc == IMX_SC_R_A35) 673 return true; 674 675 return imx_sc_rm_is_resource_owned(ccm_ipc_handle, rsrc); 676 } 677 678 struct clk_hw *imx_clk_scu_alloc_dev(const char *name, 679 const char * const *parents, 680 int num_parents, u32 rsrc_id, u8 clk_type) 681 { 682 struct imx_scu_clk_node clk = { 683 .name = name, 684 .rsrc = rsrc_id, 685 .clk_type = clk_type, 686 .parents = parents, 687 .num_parents = num_parents, 688 }; 689 struct platform_device *pdev; 690 int ret; 691 692 if (!imx_scu_clk_is_valid(rsrc_id)) 693 return ERR_PTR(-EINVAL); 694 695 if (!imx_clk_is_resource_owned(rsrc_id)) 696 return NULL; 697 698 pdev = platform_device_alloc(name, PLATFORM_DEVID_NONE); 699 if (!pdev) { 700 pr_err("%s: failed to allocate scu clk dev rsrc %d type %d\n", 701 name, rsrc_id, clk_type); 702 return ERR_PTR(-ENOMEM); 703 } 704 705 ret = platform_device_add_data(pdev, &clk, sizeof(clk)); 706 if (ret) 707 goto put_device; 708 709 ret = driver_set_override(&pdev->dev, &pdev->driver_override, 710 "imx-scu-clk", strlen("imx-scu-clk")); 711 if (ret) 712 goto put_device; 713 714 ret = imx_clk_scu_attach_pd(&pdev->dev, rsrc_id); 715 if (ret) 716 pr_warn("%s: failed to attached the power domain %d\n", 717 name, ret); 718 719 ret = platform_device_add(pdev); 720 if (ret) 721 goto put_device; 722 723 /* For API backwards compatibility, simply return NULL for success */ 724 return NULL; 725 726 put_device: 727 platform_device_put(pdev); 728 return ERR_PTR(ret); 729 } 730 731 void imx_clk_scu_unregister(void) 732 { 733 struct imx_scu_clk_node *clk, *n; 734 int i; 735 736 for (i = 0; i < IMX_SC_R_LAST; i++) { 737 list_for_each_entry_safe(clk, n, &imx_scu_clks[i], node) { 738 clk_hw_unregister(clk->hw); 739 kfree(clk); 740 } 741 } 742 } 743 744 static unsigned long clk_gpr_div_scu_recalc_rate(struct clk_hw *hw, 745 unsigned long parent_rate) 746 { 747 struct clk_gpr_scu *clk = to_clk_gpr_scu(hw); 748 unsigned long rate = 0; 749 u32 val; 750 int err; 751 752 err = imx_sc_misc_get_control(ccm_ipc_handle, clk->rsrc_id, 753 clk->gpr_id, &val); 754 755 rate = val ? parent_rate / 2 : parent_rate; 756 757 return err ? 0 : rate; 758 } 759 760 static int clk_gpr_div_scu_determine_rate(struct clk_hw *hw, 761 struct clk_rate_request *req) 762 { 763 if (req->rate < req->best_parent_rate) 764 req->rate = req->best_parent_rate / 2; 765 else 766 req->rate = req->best_parent_rate; 767 768 return 0; 769 } 770 771 static int clk_gpr_div_scu_set_rate(struct clk_hw *hw, unsigned long rate, 772 unsigned long parent_rate) 773 { 774 struct clk_gpr_scu *clk = to_clk_gpr_scu(hw); 775 uint32_t val; 776 int err; 777 778 val = (rate < parent_rate) ? 1 : 0; 779 err = imx_sc_misc_set_control(ccm_ipc_handle, clk->rsrc_id, 780 clk->gpr_id, val); 781 782 return err ? -EINVAL : 0; 783 } 784 785 static const struct clk_ops clk_gpr_div_scu_ops = { 786 .recalc_rate = clk_gpr_div_scu_recalc_rate, 787 .determine_rate = clk_gpr_div_scu_determine_rate, 788 .set_rate = clk_gpr_div_scu_set_rate, 789 }; 790 791 static u8 clk_gpr_mux_scu_get_parent(struct clk_hw *hw) 792 { 793 struct clk_gpr_scu *clk = to_clk_gpr_scu(hw); 794 u32 val = 0; 795 796 imx_sc_misc_get_control(ccm_ipc_handle, clk->rsrc_id, 797 clk->gpr_id, &val); 798 799 return (u8)val; 800 } 801 802 static int clk_gpr_mux_scu_set_parent(struct clk_hw *hw, u8 index) 803 { 804 struct clk_gpr_scu *clk = to_clk_gpr_scu(hw); 805 806 return imx_sc_misc_set_control(ccm_ipc_handle, clk->rsrc_id, 807 clk->gpr_id, index); 808 } 809 810 static const struct clk_ops clk_gpr_mux_scu_ops = { 811 .determine_rate = clk_hw_determine_rate_no_reparent, 812 .get_parent = clk_gpr_mux_scu_get_parent, 813 .set_parent = clk_gpr_mux_scu_set_parent, 814 }; 815 816 static int clk_gpr_gate_scu_prepare(struct clk_hw *hw) 817 { 818 struct clk_gpr_scu *clk = to_clk_gpr_scu(hw); 819 820 return imx_sc_misc_set_control(ccm_ipc_handle, clk->rsrc_id, 821 clk->gpr_id, !clk->gate_invert); 822 } 823 824 static void clk_gpr_gate_scu_unprepare(struct clk_hw *hw) 825 { 826 struct clk_gpr_scu *clk = to_clk_gpr_scu(hw); 827 int ret; 828 829 ret = imx_sc_misc_set_control(ccm_ipc_handle, clk->rsrc_id, 830 clk->gpr_id, clk->gate_invert); 831 if (ret) 832 pr_err("%s: clk unprepare failed %d\n", clk_hw_get_name(hw), 833 ret); 834 } 835 836 static int clk_gpr_gate_scu_is_prepared(struct clk_hw *hw) 837 { 838 struct clk_gpr_scu *clk = to_clk_gpr_scu(hw); 839 int ret; 840 u32 val; 841 842 ret = imx_sc_misc_get_control(ccm_ipc_handle, clk->rsrc_id, 843 clk->gpr_id, &val); 844 if (ret) 845 return ret; 846 847 return clk->gate_invert ? !val : val; 848 } 849 850 static const struct clk_ops clk_gpr_gate_scu_ops = { 851 .prepare = clk_gpr_gate_scu_prepare, 852 .unprepare = clk_gpr_gate_scu_unprepare, 853 .is_prepared = clk_gpr_gate_scu_is_prepared, 854 }; 855 856 struct clk_hw *__imx_clk_gpr_scu(const char *name, const char * const *parent_name, 857 int num_parents, u32 rsrc_id, u8 gpr_id, u8 flags, 858 bool invert) 859 { 860 struct imx_scu_clk_node *clk_node; 861 struct clk_gpr_scu *clk; 862 struct clk_hw *hw; 863 struct clk_init_data init; 864 int ret; 865 866 if (rsrc_id >= IMX_SC_R_LAST || gpr_id >= IMX_SC_C_LAST) 867 return ERR_PTR(-EINVAL); 868 869 clk_node = kzalloc_obj(*clk_node); 870 if (!clk_node) 871 return ERR_PTR(-ENOMEM); 872 873 if (!imx_scu_clk_is_valid(rsrc_id)) { 874 kfree(clk_node); 875 return ERR_PTR(-EINVAL); 876 } 877 878 if (!imx_clk_is_resource_owned(rsrc_id)) { 879 kfree(clk_node); 880 return NULL; 881 } 882 883 clk = kzalloc_obj(*clk); 884 if (!clk) { 885 kfree(clk_node); 886 return ERR_PTR(-ENOMEM); 887 } 888 889 clk->rsrc_id = rsrc_id; 890 clk->gpr_id = gpr_id; 891 clk->flags = flags; 892 clk->gate_invert = invert; 893 894 if (flags & IMX_SCU_GPR_CLK_GATE) 895 init.ops = &clk_gpr_gate_scu_ops; 896 897 if (flags & IMX_SCU_GPR_CLK_DIV) 898 init.ops = &clk_gpr_div_scu_ops; 899 900 if (flags & IMX_SCU_GPR_CLK_MUX) 901 init.ops = &clk_gpr_mux_scu_ops; 902 903 init.flags = 0; 904 init.name = name; 905 init.parent_names = parent_name; 906 init.num_parents = num_parents; 907 908 clk->hw.init = &init; 909 910 hw = &clk->hw; 911 ret = clk_hw_register(NULL, hw); 912 if (ret) { 913 kfree(clk); 914 kfree(clk_node); 915 hw = ERR_PTR(ret); 916 } else { 917 clk_node->hw = hw; 918 clk_node->clk_type = gpr_id; 919 list_add_tail(&clk_node->node, &imx_scu_clks[rsrc_id]); 920 } 921 922 return hw; 923 } 924