1934 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * RZ/G2L Clock Pulse Generator4 *5 * Copyright (C) 2021 Renesas Electronics Corp.6 *7 * Based on renesas-cpg-mssr.c8 *9 * Copyright (C) 2015 Glider bvba10 * Copyright (C) 2013 Ideas On Board SPRL11 * Copyright (C) 2015 Renesas Electronics Corp.12 */13 14#include <linux/bitfield.h>15#include <linux/clk.h>16#include <linux/clk-provider.h>17#include <linux/clk/renesas.h>18#include <linux/delay.h>19#include <linux/device.h>20#include <linux/init.h>21#include <linux/iopoll.h>22#include <linux/mod_devicetable.h>23#include <linux/module.h>24#include <linux/of.h>25#include <linux/platform_device.h>26#include <linux/pm_clock.h>27#include <linux/pm_domain.h>28#include <linux/reset-controller.h>29#include <linux/slab.h>30#include <linux/units.h>31 32#include <dt-bindings/clock/renesas-cpg-mssr.h>33 34#include "rzg2l-cpg.h"35 36#ifdef DEBUG37#define WARN_DEBUG(x) WARN_ON(x)38#else39#define WARN_DEBUG(x) do { } while (0)40#endif41 42#define GET_SHIFT(val) ((val >> 12) & 0xff)43#define GET_WIDTH(val) ((val >> 8) & 0xf)44 45#define KDIV(val) ((s16)FIELD_GET(GENMASK(31, 16), val))46#define MDIV(val) FIELD_GET(GENMASK(15, 6), val)47#define PDIV(val) FIELD_GET(GENMASK(5, 0), val)48#define SDIV(val) FIELD_GET(GENMASK(2, 0), val)49 50#define RZG3S_DIV_P GENMASK(28, 26)51#define RZG3S_DIV_M GENMASK(25, 22)52#define RZG3S_DIV_NI GENMASK(21, 13)53#define RZG3S_DIV_NF GENMASK(12, 1)54 55#define CLK_ON_R(reg) (reg)56#define CLK_MON_R(reg) (0x180 + (reg))57#define CLK_RST_R(reg) (reg)58#define CLK_MRST_R(reg) (0x180 + (reg))59 60#define GET_REG_OFFSET(val) ((val >> 20) & 0xfff)61#define GET_REG_SAMPLL_CLK1(val) ((val >> 22) & 0xfff)62#define GET_REG_SAMPLL_CLK2(val) ((val >> 12) & 0xfff)63 64#define CPG_WEN_BIT BIT(16)65 66#define MAX_VCLK_FREQ (148500000)67 68/**69 * struct clk_hw_data - clock hardware data70 * @hw: clock hw71 * @conf: clock configuration (register offset, shift, width)72 * @sconf: clock status configuration (register offset, shift, width)73 * @priv: CPG private data structure74 */75struct clk_hw_data {76 struct clk_hw hw;77 u32 conf;78 u32 sconf;79 struct rzg2l_cpg_priv *priv;80};81 82#define to_clk_hw_data(_hw) container_of(_hw, struct clk_hw_data, hw)83 84/**85 * struct sd_mux_hw_data - SD MUX clock hardware data86 * @hw_data: clock hw data87 * @mtable: clock mux table88 */89struct sd_mux_hw_data {90 struct clk_hw_data hw_data;91 const u32 *mtable;92};93 94#define to_sd_mux_hw_data(_hw) container_of(_hw, struct sd_mux_hw_data, hw_data)95 96/**97 * struct div_hw_data - divider clock hardware data98 * @hw_data: clock hw data99 * @dtable: pointer to divider table100 * @invalid_rate: invalid rate for divider101 * @max_rate: maximum rate for divider102 * @width: divider width103 */104struct div_hw_data {105 struct clk_hw_data hw_data;106 const struct clk_div_table *dtable;107 unsigned long invalid_rate;108 unsigned long max_rate;109 u32 width;110};111 112#define to_div_hw_data(_hw) container_of(_hw, struct div_hw_data, hw_data)113 114struct rzg2l_pll5_param {115 u32 pl5_fracin;116 u8 pl5_refdiv;117 u8 pl5_intin;118 u8 pl5_postdiv1;119 u8 pl5_postdiv2;120 u8 pl5_spread;121};122 123struct rzg2l_pll5_mux_dsi_div_param {124 u8 clksrc;125 u8 dsi_div_a;126 u8 dsi_div_b;127};128 129/**130 * struct rzg2l_cpg_priv - Clock Pulse Generator Private Data131 *132 * @rcdev: Reset controller entity133 * @dev: CPG device134 * @base: CPG register block base address135 * @rmw_lock: protects register accesses136 * @clks: Array containing all Core and Module Clocks137 * @num_core_clks: Number of Core Clocks in clks[]138 * @num_mod_clks: Number of Module Clocks in clks[]139 * @num_resets: Number of Module Resets in info->resets[]140 * @last_dt_core_clk: ID of the last Core Clock exported to DT141 * @info: Pointer to platform data142 * @mux_dsi_div_params: pll5 mux and dsi div parameters143 */144struct rzg2l_cpg_priv {145 struct reset_controller_dev rcdev;146 struct device *dev;147 void __iomem *base;148 spinlock_t rmw_lock;149 150 struct clk **clks;151 unsigned int num_core_clks;152 unsigned int num_mod_clks;153 unsigned int num_resets;154 unsigned int last_dt_core_clk;155 156 const struct rzg2l_cpg_info *info;157 158 struct rzg2l_pll5_mux_dsi_div_param mux_dsi_div_params;159};160 161static void rzg2l_cpg_del_clk_provider(void *data)162{163 of_clk_del_provider(data);164}165 166/* Must be called in atomic context. */167static int rzg2l_cpg_wait_clk_update_done(void __iomem *base, u32 conf)168{169 u32 bitmask = GENMASK(GET_WIDTH(conf) - 1, 0) << GET_SHIFT(conf);170 u32 off = GET_REG_OFFSET(conf);171 u32 val;172 173 return readl_poll_timeout_atomic(base + off, val, !(val & bitmask), 10, 200);174}175 176int rzg2l_cpg_sd_clk_mux_notifier(struct notifier_block *nb, unsigned long event,177 void *data)178{179 struct clk_notifier_data *cnd = data;180 struct clk_hw *hw = __clk_get_hw(cnd->clk);181 struct clk_hw_data *clk_hw_data = to_clk_hw_data(hw);182 struct rzg2l_cpg_priv *priv = clk_hw_data->priv;183 u32 off = GET_REG_OFFSET(clk_hw_data->conf);184 u32 shift = GET_SHIFT(clk_hw_data->conf);185 const u32 clk_src_266 = 3;186 unsigned long flags;187 int ret;188 189 if (event != PRE_RATE_CHANGE || (cnd->new_rate / MEGA == 266))190 return NOTIFY_DONE;191 192 spin_lock_irqsave(&priv->rmw_lock, flags);193 194 /*195 * As per the HW manual, we should not directly switch from 533 MHz to196 * 400 MHz and vice versa. To change the setting from 2’b01 (533 MHz)197 * to 2’b10 (400 MHz) or vice versa, Switch to 2’b11 (266 MHz) first,198 * and then switch to the target setting (2’b01 (533 MHz) or 2’b10199 * (400 MHz)).200 * Setting a value of '0' to the SEL_SDHI0_SET or SEL_SDHI1_SET clock201 * switching register is prohibited.202 * The clock mux has 3 input clocks(533 MHz, 400 MHz, and 266 MHz), and203 * the index to value mapping is done by adding 1 to the index.204 */205 206 writel((CPG_WEN_BIT | clk_src_266) << shift, priv->base + off);207 208 /* Wait for the update done. */209 ret = rzg2l_cpg_wait_clk_update_done(priv->base, clk_hw_data->sconf);210 211 spin_unlock_irqrestore(&priv->rmw_lock, flags);212 213 if (ret)214 dev_err(priv->dev, "failed to switch to safe clk source\n");215 216 return notifier_from_errno(ret);217}218 219int rzg3s_cpg_div_clk_notifier(struct notifier_block *nb, unsigned long event,220 void *data)221{222 struct clk_notifier_data *cnd = data;223 struct clk_hw *hw = __clk_get_hw(cnd->clk);224 struct clk_hw_data *clk_hw_data = to_clk_hw_data(hw);225 struct div_hw_data *div_hw_data = to_div_hw_data(clk_hw_data);226 struct rzg2l_cpg_priv *priv = clk_hw_data->priv;227 u32 off = GET_REG_OFFSET(clk_hw_data->conf);228 u32 shift = GET_SHIFT(clk_hw_data->conf);229 unsigned long flags;230 int ret = 0;231 u32 val;232 233 if (event != PRE_RATE_CHANGE || !div_hw_data->invalid_rate ||234 div_hw_data->invalid_rate % cnd->new_rate)235 return NOTIFY_DONE;236 237 spin_lock_irqsave(&priv->rmw_lock, flags);238 239 val = readl(priv->base + off);240 val >>= shift;241 val &= GENMASK(GET_WIDTH(clk_hw_data->conf) - 1, 0);242 243 /*244 * There are different constraints for the user of this notifiers as follows:245 * 1/ SD div cannot be 1 (val == 0) if parent rate is 800MHz246 * 2/ OCTA / SPI div cannot be 1 (val == 0) if parent rate is 400MHz247 * As SD can have only one parent having 800MHz and OCTA div can have248 * only one parent having 400MHz we took into account the parent rate249 * at the beginning of function (by checking invalid_rate % new_rate).250 * Now it is time to check the hardware divider and update it accordingly.251 */252 if (!val) {253 writel((CPG_WEN_BIT | 1) << shift, priv->base + off);254 /* Wait for the update done. */255 ret = rzg2l_cpg_wait_clk_update_done(priv->base, clk_hw_data->sconf);256 }257 258 spin_unlock_irqrestore(&priv->rmw_lock, flags);259 260 if (ret)261 dev_err(priv->dev, "Failed to downgrade the div\n");262 263 return notifier_from_errno(ret);264}265 266static int rzg2l_register_notifier(struct clk_hw *hw, const struct cpg_core_clk *core,267 struct rzg2l_cpg_priv *priv)268{269 struct notifier_block *nb;270 271 if (!core->notifier)272 return 0;273 274 nb = devm_kzalloc(priv->dev, sizeof(*nb), GFP_KERNEL);275 if (!nb)276 return -ENOMEM;277 278 nb->notifier_call = core->notifier;279 280 return clk_notifier_register(hw->clk, nb);281}282 283static unsigned long rzg3s_div_clk_recalc_rate(struct clk_hw *hw,284 unsigned long parent_rate)285{286 struct clk_hw_data *clk_hw_data = to_clk_hw_data(hw);287 struct div_hw_data *div_hw_data = to_div_hw_data(clk_hw_data);288 struct rzg2l_cpg_priv *priv = clk_hw_data->priv;289 u32 val;290 291 val = readl(priv->base + GET_REG_OFFSET(clk_hw_data->conf));292 val >>= GET_SHIFT(clk_hw_data->conf);293 val &= GENMASK(GET_WIDTH(clk_hw_data->conf) - 1, 0);294 295 return divider_recalc_rate(hw, parent_rate, val, div_hw_data->dtable,296 CLK_DIVIDER_ROUND_CLOSEST, div_hw_data->width);297}298 299static int rzg3s_div_clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)300{301 struct clk_hw_data *clk_hw_data = to_clk_hw_data(hw);302 struct div_hw_data *div_hw_data = to_div_hw_data(clk_hw_data);303 304 if (div_hw_data->max_rate && req->rate > div_hw_data->max_rate)305 req->rate = div_hw_data->max_rate;306 307 return divider_determine_rate(hw, req, div_hw_data->dtable, div_hw_data->width,308 CLK_DIVIDER_ROUND_CLOSEST);309}310 311static int rzg3s_div_clk_set_rate(struct clk_hw *hw, unsigned long rate,312 unsigned long parent_rate)313{314 struct clk_hw_data *clk_hw_data = to_clk_hw_data(hw);315 struct div_hw_data *div_hw_data = to_div_hw_data(clk_hw_data);316 struct rzg2l_cpg_priv *priv = clk_hw_data->priv;317 u32 off = GET_REG_OFFSET(clk_hw_data->conf);318 u32 shift = GET_SHIFT(clk_hw_data->conf);319 unsigned long flags;320 u32 val;321 int ret;322 323 val = divider_get_val(rate, parent_rate, div_hw_data->dtable, div_hw_data->width,324 CLK_DIVIDER_ROUND_CLOSEST);325 326 spin_lock_irqsave(&priv->rmw_lock, flags);327 writel((CPG_WEN_BIT | val) << shift, priv->base + off);328 /* Wait for the update done. */329 ret = rzg2l_cpg_wait_clk_update_done(priv->base, clk_hw_data->sconf);330 spin_unlock_irqrestore(&priv->rmw_lock, flags);331 332 return ret;333}334 335static const struct clk_ops rzg3s_div_clk_ops = {336 .recalc_rate = rzg3s_div_clk_recalc_rate,337 .determine_rate = rzg3s_div_clk_determine_rate,338 .set_rate = rzg3s_div_clk_set_rate,339};340 341static struct clk * __init342rzg3s_cpg_div_clk_register(const struct cpg_core_clk *core, struct rzg2l_cpg_priv *priv)343{344 struct div_hw_data *div_hw_data;345 struct clk_init_data init = {};346 const struct clk_div_table *clkt;347 struct clk_hw *clk_hw;348 const struct clk *parent;349 const char *parent_name;350 u32 max = 0;351 int ret;352 353 parent = priv->clks[core->parent];354 if (IS_ERR(parent))355 return ERR_CAST(parent);356 357 parent_name = __clk_get_name(parent);358 359 div_hw_data = devm_kzalloc(priv->dev, sizeof(*div_hw_data), GFP_KERNEL);360 if (!div_hw_data)361 return ERR_PTR(-ENOMEM);362 363 init.name = core->name;364 init.flags = core->flag;365 init.ops = &rzg3s_div_clk_ops;366 init.parent_names = &parent_name;367 init.num_parents = 1;368 369 /* Get the maximum divider to retrieve div width. */370 for (clkt = core->dtable; clkt->div; clkt++) {371 if (max < clkt->div)372 max = clkt->div;373 }374 375 div_hw_data->hw_data.priv = priv;376 div_hw_data->hw_data.conf = core->conf;377 div_hw_data->hw_data.sconf = core->sconf;378 div_hw_data->dtable = core->dtable;379 div_hw_data->invalid_rate = core->invalid_rate;380 div_hw_data->max_rate = core->max_rate;381 div_hw_data->width = fls(max) - 1;382 383 clk_hw = &div_hw_data->hw_data.hw;384 clk_hw->init = &init;385 386 ret = devm_clk_hw_register(priv->dev, clk_hw);387 if (ret)388 return ERR_PTR(ret);389 390 ret = rzg2l_register_notifier(clk_hw, core, priv);391 if (ret) {392 dev_err(priv->dev, "Failed to register notifier for %s\n",393 core->name);394 return ERR_PTR(ret);395 }396 397 return clk_hw->clk;398}399 400static struct clk * __init401rzg2l_cpg_div_clk_register(const struct cpg_core_clk *core,402 struct rzg2l_cpg_priv *priv)403{404 void __iomem *base = priv->base;405 struct device *dev = priv->dev;406 const struct clk *parent;407 const char *parent_name;408 struct clk_hw *clk_hw;409 410 parent = priv->clks[core->parent];411 if (IS_ERR(parent))412 return ERR_CAST(parent);413 414 parent_name = __clk_get_name(parent);415 416 if (core->dtable)417 clk_hw = clk_hw_register_divider_table(dev, core->name,418 parent_name, 0,419 base + GET_REG_OFFSET(core->conf),420 GET_SHIFT(core->conf),421 GET_WIDTH(core->conf),422 core->flag,423 core->dtable,424 &priv->rmw_lock);425 else426 clk_hw = clk_hw_register_divider(dev, core->name,427 parent_name, 0,428 base + GET_REG_OFFSET(core->conf),429 GET_SHIFT(core->conf),430 GET_WIDTH(core->conf),431 core->flag, &priv->rmw_lock);432 433 if (IS_ERR(clk_hw))434 return ERR_CAST(clk_hw);435 436 return clk_hw->clk;437}438 439static struct clk * __init440rzg2l_cpg_mux_clk_register(const struct cpg_core_clk *core,441 struct rzg2l_cpg_priv *priv)442{443 const struct clk_hw *clk_hw;444 445 clk_hw = devm_clk_hw_register_mux(priv->dev, core->name,446 core->parent_names, core->num_parents,447 core->flag,448 priv->base + GET_REG_OFFSET(core->conf),449 GET_SHIFT(core->conf),450 GET_WIDTH(core->conf),451 core->mux_flags, &priv->rmw_lock);452 if (IS_ERR(clk_hw))453 return ERR_CAST(clk_hw);454 455 return clk_hw->clk;456}457 458static int rzg2l_cpg_sd_clk_mux_set_parent(struct clk_hw *hw, u8 index)459{460 struct clk_hw_data *clk_hw_data = to_clk_hw_data(hw);461 struct sd_mux_hw_data *sd_mux_hw_data = to_sd_mux_hw_data(clk_hw_data);462 struct rzg2l_cpg_priv *priv = clk_hw_data->priv;463 u32 off = GET_REG_OFFSET(clk_hw_data->conf);464 u32 shift = GET_SHIFT(clk_hw_data->conf);465 unsigned long flags;466 u32 val;467 int ret;468 469 val = clk_mux_index_to_val(sd_mux_hw_data->mtable, CLK_MUX_ROUND_CLOSEST, index);470 471 spin_lock_irqsave(&priv->rmw_lock, flags);472 473 writel((CPG_WEN_BIT | val) << shift, priv->base + off);474 475 /* Wait for the update done. */476 ret = rzg2l_cpg_wait_clk_update_done(priv->base, clk_hw_data->sconf);477 478 spin_unlock_irqrestore(&priv->rmw_lock, flags);479 480 if (ret)481 dev_err(priv->dev, "Failed to switch parent\n");482 483 return ret;484}485 486static u8 rzg2l_cpg_sd_clk_mux_get_parent(struct clk_hw *hw)487{488 struct clk_hw_data *clk_hw_data = to_clk_hw_data(hw);489 struct sd_mux_hw_data *sd_mux_hw_data = to_sd_mux_hw_data(clk_hw_data);490 struct rzg2l_cpg_priv *priv = clk_hw_data->priv;491 u32 val;492 493 val = readl(priv->base + GET_REG_OFFSET(clk_hw_data->conf));494 val >>= GET_SHIFT(clk_hw_data->conf);495 val &= GENMASK(GET_WIDTH(clk_hw_data->conf) - 1, 0);496 497 return clk_mux_val_to_index(hw, sd_mux_hw_data->mtable, CLK_MUX_ROUND_CLOSEST, val);498}499 500static const struct clk_ops rzg2l_cpg_sd_clk_mux_ops = {501 .determine_rate = __clk_mux_determine_rate_closest,502 .set_parent = rzg2l_cpg_sd_clk_mux_set_parent,503 .get_parent = rzg2l_cpg_sd_clk_mux_get_parent,504};505 506static struct clk * __init507rzg2l_cpg_sd_mux_clk_register(const struct cpg_core_clk *core,508 struct rzg2l_cpg_priv *priv)509{510 struct sd_mux_hw_data *sd_mux_hw_data;511 struct clk_init_data init;512 struct clk_hw *clk_hw;513 int ret;514 515 sd_mux_hw_data = devm_kzalloc(priv->dev, sizeof(*sd_mux_hw_data), GFP_KERNEL);516 if (!sd_mux_hw_data)517 return ERR_PTR(-ENOMEM);518 519 sd_mux_hw_data->hw_data.priv = priv;520 sd_mux_hw_data->hw_data.conf = core->conf;521 sd_mux_hw_data->hw_data.sconf = core->sconf;522 sd_mux_hw_data->mtable = core->mtable;523 524 init.name = core->name;525 init.ops = &rzg2l_cpg_sd_clk_mux_ops;526 init.flags = core->flag;527 init.num_parents = core->num_parents;528 init.parent_names = core->parent_names;529 530 clk_hw = &sd_mux_hw_data->hw_data.hw;531 clk_hw->init = &init;532 533 ret = devm_clk_hw_register(priv->dev, clk_hw);534 if (ret)535 return ERR_PTR(ret);536 537 ret = rzg2l_register_notifier(clk_hw, core, priv);538 if (ret) {539 dev_err(priv->dev, "Failed to register notifier for %s\n",540 core->name);541 return ERR_PTR(ret);542 }543 544 return clk_hw->clk;545}546 547static unsigned long548rzg2l_cpg_get_foutpostdiv_rate(struct rzg2l_pll5_param *params,549 unsigned long rate)550{551 unsigned long foutpostdiv_rate;552 553 params->pl5_intin = rate / MEGA;554 params->pl5_fracin = div_u64(((u64)rate % MEGA) << 24, MEGA);555 params->pl5_refdiv = 2;556 params->pl5_postdiv1 = 1;557 params->pl5_postdiv2 = 1;558 params->pl5_spread = 0x16;559 560 foutpostdiv_rate =561 EXTAL_FREQ_IN_MEGA_HZ * MEGA / params->pl5_refdiv *562 ((((params->pl5_intin << 24) + params->pl5_fracin)) >> 24) /563 (params->pl5_postdiv1 * params->pl5_postdiv2);564 565 return foutpostdiv_rate;566}567 568struct dsi_div_hw_data {569 struct clk_hw hw;570 u32 conf;571 unsigned long rate;572 struct rzg2l_cpg_priv *priv;573};574 575#define to_dsi_div_hw_data(_hw) container_of(_hw, struct dsi_div_hw_data, hw)576 577static unsigned long rzg2l_cpg_dsi_div_recalc_rate(struct clk_hw *hw,578 unsigned long parent_rate)579{580 struct dsi_div_hw_data *dsi_div = to_dsi_div_hw_data(hw);581 unsigned long rate = dsi_div->rate;582 583 if (!rate)584 rate = parent_rate;585 586 return rate;587}588 589static unsigned long rzg2l_cpg_get_vclk_parent_rate(struct clk_hw *hw,590 unsigned long rate)591{592 struct dsi_div_hw_data *dsi_div = to_dsi_div_hw_data(hw);593 struct rzg2l_cpg_priv *priv = dsi_div->priv;594 struct rzg2l_pll5_param params;595 unsigned long parent_rate;596 597 parent_rate = rzg2l_cpg_get_foutpostdiv_rate(¶ms, rate);598 599 if (priv->mux_dsi_div_params.clksrc)600 parent_rate /= 2;601 602 return parent_rate;603}604 605static int rzg2l_cpg_dsi_div_determine_rate(struct clk_hw *hw,606 struct clk_rate_request *req)607{608 if (req->rate > MAX_VCLK_FREQ)609 req->rate = MAX_VCLK_FREQ;610 611 req->best_parent_rate = rzg2l_cpg_get_vclk_parent_rate(hw, req->rate);612 613 return 0;614}615 616static int rzg2l_cpg_dsi_div_set_rate(struct clk_hw *hw,617 unsigned long rate,618 unsigned long parent_rate)619{620 struct dsi_div_hw_data *dsi_div = to_dsi_div_hw_data(hw);621 struct rzg2l_cpg_priv *priv = dsi_div->priv;622 623 /*624 * MUX -->DIV_DSI_{A,B} -->M3 -->VCLK625 *626 * Based on the dot clock, the DSI divider clock sets the divider value,627 * calculates the pll parameters for generating FOUTPOSTDIV and the clk628 * source for the MUX and propagates that info to the parents.629 */630 631 if (!rate || rate > MAX_VCLK_FREQ)632 return -EINVAL;633 634 dsi_div->rate = rate;635 writel(CPG_PL5_SDIV_DIV_DSI_A_WEN | CPG_PL5_SDIV_DIV_DSI_B_WEN |636 (priv->mux_dsi_div_params.dsi_div_a << 0) |637 (priv->mux_dsi_div_params.dsi_div_b << 8),638 priv->base + CPG_PL5_SDIV);639 640 return 0;641}642 643static const struct clk_ops rzg2l_cpg_dsi_div_ops = {644 .recalc_rate = rzg2l_cpg_dsi_div_recalc_rate,645 .determine_rate = rzg2l_cpg_dsi_div_determine_rate,646 .set_rate = rzg2l_cpg_dsi_div_set_rate,647};648 649static struct clk * __init650rzg2l_cpg_dsi_div_clk_register(const struct cpg_core_clk *core,651 struct rzg2l_cpg_priv *priv)652{653 struct dsi_div_hw_data *clk_hw_data;654 const struct clk *parent;655 const char *parent_name;656 struct clk_init_data init;657 struct clk_hw *clk_hw;658 int ret;659 660 parent = priv->clks[core->parent];661 if (IS_ERR(parent))662 return ERR_CAST(parent);663 664 clk_hw_data = devm_kzalloc(priv->dev, sizeof(*clk_hw_data), GFP_KERNEL);665 if (!clk_hw_data)666 return ERR_PTR(-ENOMEM);667 668 clk_hw_data->priv = priv;669 670 parent_name = __clk_get_name(parent);671 init.name = core->name;672 init.ops = &rzg2l_cpg_dsi_div_ops;673 init.flags = CLK_SET_RATE_PARENT;674 init.parent_names = &parent_name;675 init.num_parents = 1;676 677 clk_hw = &clk_hw_data->hw;678 clk_hw->init = &init;679 680 ret = devm_clk_hw_register(priv->dev, clk_hw);681 if (ret)682 return ERR_PTR(ret);683 684 return clk_hw->clk;685}686 687struct pll5_mux_hw_data {688 struct clk_hw hw;689 u32 conf;690 unsigned long rate;691 struct rzg2l_cpg_priv *priv;692};693 694#define to_pll5_mux_hw_data(_hw) container_of(_hw, struct pll5_mux_hw_data, hw)695 696static int rzg2l_cpg_pll5_4_clk_mux_determine_rate(struct clk_hw *hw,697 struct clk_rate_request *req)698{699 struct clk_hw *parent;700 struct pll5_mux_hw_data *hwdata = to_pll5_mux_hw_data(hw);701 struct rzg2l_cpg_priv *priv = hwdata->priv;702 703 parent = clk_hw_get_parent_by_index(hw, priv->mux_dsi_div_params.clksrc);704 req->best_parent_hw = parent;705 req->best_parent_rate = req->rate;706 707 return 0;708}709 710static int rzg2l_cpg_pll5_4_clk_mux_set_parent(struct clk_hw *hw, u8 index)711{712 struct pll5_mux_hw_data *hwdata = to_pll5_mux_hw_data(hw);713 struct rzg2l_cpg_priv *priv = hwdata->priv;714 715 /*716 * FOUTPOSTDIV--->|717 * | | -->MUX -->DIV_DSIA_B -->M3 -->VCLK718 * |--FOUT1PH0-->|719 *720 * Based on the dot clock, the DSI divider clock calculates the parent721 * rate and clk source for the MUX. It propagates that info to722 * pll5_4_clk_mux which sets the clock source for DSI divider clock.723 */724 725 writel(CPG_OTHERFUNC1_REG_RES0_ON_WEN | index,726 priv->base + CPG_OTHERFUNC1_REG);727 728 return 0;729}730 731static u8 rzg2l_cpg_pll5_4_clk_mux_get_parent(struct clk_hw *hw)732{733 struct pll5_mux_hw_data *hwdata = to_pll5_mux_hw_data(hw);734 struct rzg2l_cpg_priv *priv = hwdata->priv;735 736 return readl(priv->base + GET_REG_OFFSET(hwdata->conf));737}738 739static const struct clk_ops rzg2l_cpg_pll5_4_clk_mux_ops = {740 .determine_rate = rzg2l_cpg_pll5_4_clk_mux_determine_rate,741 .set_parent = rzg2l_cpg_pll5_4_clk_mux_set_parent,742 .get_parent = rzg2l_cpg_pll5_4_clk_mux_get_parent,743};744 745static struct clk * __init746rzg2l_cpg_pll5_4_mux_clk_register(const struct cpg_core_clk *core,747 struct rzg2l_cpg_priv *priv)748{749 struct pll5_mux_hw_data *clk_hw_data;750 struct clk_init_data init;751 struct clk_hw *clk_hw;752 int ret;753 754 clk_hw_data = devm_kzalloc(priv->dev, sizeof(*clk_hw_data), GFP_KERNEL);755 if (!clk_hw_data)756 return ERR_PTR(-ENOMEM);757 758 clk_hw_data->priv = priv;759 clk_hw_data->conf = core->conf;760 761 init.name = core->name;762 init.ops = &rzg2l_cpg_pll5_4_clk_mux_ops;763 init.flags = CLK_SET_RATE_PARENT;764 init.num_parents = core->num_parents;765 init.parent_names = core->parent_names;766 767 clk_hw = &clk_hw_data->hw;768 clk_hw->init = &init;769 770 ret = devm_clk_hw_register(priv->dev, clk_hw);771 if (ret)772 return ERR_PTR(ret);773 774 return clk_hw->clk;775}776 777struct sipll5 {778 struct clk_hw hw;779 u32 conf;780 unsigned long foutpostdiv_rate;781 struct rzg2l_cpg_priv *priv;782};783 784#define to_sipll5(_hw) container_of(_hw, struct sipll5, hw)785 786static unsigned long rzg2l_cpg_get_vclk_rate(struct clk_hw *hw,787 unsigned long rate)788{789 struct sipll5 *sipll5 = to_sipll5(hw);790 struct rzg2l_cpg_priv *priv = sipll5->priv;791 unsigned long vclk;792 793 vclk = rate / ((1 << priv->mux_dsi_div_params.dsi_div_a) *794 (priv->mux_dsi_div_params.dsi_div_b + 1));795 796 if (priv->mux_dsi_div_params.clksrc)797 vclk /= 2;798 799 return vclk;800}801 802static unsigned long rzg2l_cpg_sipll5_recalc_rate(struct clk_hw *hw,803 unsigned long parent_rate)804{805 struct sipll5 *sipll5 = to_sipll5(hw);806 unsigned long pll5_rate = sipll5->foutpostdiv_rate;807 808 if (!pll5_rate)809 pll5_rate = parent_rate;810 811 return pll5_rate;812}813 814static long rzg2l_cpg_sipll5_round_rate(struct clk_hw *hw,815 unsigned long rate,816 unsigned long *parent_rate)817{818 return rate;819}820 821static int rzg2l_cpg_sipll5_set_rate(struct clk_hw *hw,822 unsigned long rate,823 unsigned long parent_rate)824{825 struct sipll5 *sipll5 = to_sipll5(hw);826 struct rzg2l_cpg_priv *priv = sipll5->priv;827 struct rzg2l_pll5_param params;828 unsigned long vclk_rate;829 int ret;830 u32 val;831 832 /*833 * OSC --> PLL5 --> FOUTPOSTDIV-->|834 * | | -->MUX -->DIV_DSIA_B -->M3 -->VCLK835 * |--FOUT1PH0-->|836 *837 * Based on the dot clock, the DSI divider clock calculates the parent838 * rate and the pll5 parameters for generating FOUTPOSTDIV. It propagates839 * that info to sipll5 which sets parameters for generating FOUTPOSTDIV.840 *841 * OSC --> PLL5 --> FOUTPOSTDIV842 */843 844 if (!rate)845 return -EINVAL;846 847 vclk_rate = rzg2l_cpg_get_vclk_rate(hw, rate);848 sipll5->foutpostdiv_rate =849 rzg2l_cpg_get_foutpostdiv_rate(¶ms, vclk_rate);850 851 /* Put PLL5 into standby mode */852 writel(CPG_SIPLL5_STBY_RESETB_WEN, priv->base + CPG_SIPLL5_STBY);853 ret = readl_poll_timeout(priv->base + CPG_SIPLL5_MON, val,854 !(val & CPG_SIPLL5_MON_PLL5_LOCK), 100, 250000);855 if (ret) {856 dev_err(priv->dev, "failed to release pll5 lock");857 return ret;858 }859 860 /* Output clock setting 1 */861 writel((params.pl5_postdiv1 << 0) | (params.pl5_postdiv2 << 4) |862 (params.pl5_refdiv << 8), priv->base + CPG_SIPLL5_CLK1);863 864 /* Output clock setting, SSCG modulation value setting 3 */865 writel((params.pl5_fracin << 8), priv->base + CPG_SIPLL5_CLK3);866 867 /* Output clock setting 4 */868 writel(CPG_SIPLL5_CLK4_RESV_LSB | (params.pl5_intin << 16),869 priv->base + CPG_SIPLL5_CLK4);870 871 /* Output clock setting 5 */872 writel(params.pl5_spread, priv->base + CPG_SIPLL5_CLK5);873 874 /* PLL normal mode setting */875 writel(CPG_SIPLL5_STBY_DOWNSPREAD_WEN | CPG_SIPLL5_STBY_SSCG_EN_WEN |876 CPG_SIPLL5_STBY_RESETB_WEN | CPG_SIPLL5_STBY_RESETB,877 priv->base + CPG_SIPLL5_STBY);878 879 /* PLL normal mode transition, output clock stability check */880 ret = readl_poll_timeout(priv->base + CPG_SIPLL5_MON, val,881 (val & CPG_SIPLL5_MON_PLL5_LOCK), 100, 250000);882 if (ret) {883 dev_err(priv->dev, "failed to lock pll5");884 return ret;885 }886 887 return 0;888}889 890static const struct clk_ops rzg2l_cpg_sipll5_ops = {891 .recalc_rate = rzg2l_cpg_sipll5_recalc_rate,892 .round_rate = rzg2l_cpg_sipll5_round_rate,893 .set_rate = rzg2l_cpg_sipll5_set_rate,894};895 896static struct clk * __init897rzg2l_cpg_sipll5_register(const struct cpg_core_clk *core,898 struct rzg2l_cpg_priv *priv)899{900 const struct clk *parent;901 struct clk_init_data init;902 const char *parent_name;903 struct sipll5 *sipll5;904 struct clk_hw *clk_hw;905 int ret;906 907 parent = priv->clks[core->parent];908 if (IS_ERR(parent))909 return ERR_CAST(parent);910 911 sipll5 = devm_kzalloc(priv->dev, sizeof(*sipll5), GFP_KERNEL);912 if (!sipll5)913 return ERR_PTR(-ENOMEM);914 915 init.name = core->name;916 parent_name = __clk_get_name(parent);917 init.ops = &rzg2l_cpg_sipll5_ops;918 init.flags = 0;919 init.parent_names = &parent_name;920 init.num_parents = 1;921 922 sipll5->hw.init = &init;923 sipll5->conf = core->conf;924 sipll5->priv = priv;925 926 writel(CPG_SIPLL5_STBY_SSCG_EN_WEN | CPG_SIPLL5_STBY_RESETB_WEN |927 CPG_SIPLL5_STBY_RESETB, priv->base + CPG_SIPLL5_STBY);928 929 clk_hw = &sipll5->hw;930 clk_hw->init = &init;931 932 ret = devm_clk_hw_register(priv->dev, clk_hw);933 if (ret)934 return ERR_PTR(ret);935 936 priv->mux_dsi_div_params.clksrc = 1; /* Use clk src 1 for DSI */937 priv->mux_dsi_div_params.dsi_div_a = 1; /* Divided by 2 */938 priv->mux_dsi_div_params.dsi_div_b = 2; /* Divided by 3 */939 940 return clk_hw->clk;941}942 943struct pll_clk {944 struct clk_hw hw;945 unsigned int conf;946 unsigned int type;947 void __iomem *base;948 struct rzg2l_cpg_priv *priv;949};950 951#define to_pll(_hw) container_of(_hw, struct pll_clk, hw)952 953static unsigned long rzg2l_cpg_pll_clk_recalc_rate(struct clk_hw *hw,954 unsigned long parent_rate)955{956 struct pll_clk *pll_clk = to_pll(hw);957 struct rzg2l_cpg_priv *priv = pll_clk->priv;958 unsigned int val1, val2;959 u64 rate;960 961 if (pll_clk->type != CLK_TYPE_SAM_PLL)962 return parent_rate;963 964 val1 = readl(priv->base + GET_REG_SAMPLL_CLK1(pll_clk->conf));965 val2 = readl(priv->base + GET_REG_SAMPLL_CLK2(pll_clk->conf));966 967 rate = mul_u64_u32_shr(parent_rate, (MDIV(val1) << 16) + KDIV(val1),968 16 + SDIV(val2));969 970 return DIV_ROUND_CLOSEST_ULL(rate, PDIV(val1));971}972 973static const struct clk_ops rzg2l_cpg_pll_ops = {974 .recalc_rate = rzg2l_cpg_pll_clk_recalc_rate,975};976 977static unsigned long rzg3s_cpg_pll_clk_recalc_rate(struct clk_hw *hw,978 unsigned long parent_rate)979{980 struct pll_clk *pll_clk = to_pll(hw);981 struct rzg2l_cpg_priv *priv = pll_clk->priv;982 u32 nir, nfr, mr, pr, val;983 u64 rate;984 985 if (pll_clk->type != CLK_TYPE_G3S_PLL)986 return parent_rate;987 988 val = readl(priv->base + GET_REG_SAMPLL_CLK1(pll_clk->conf));989 990 pr = 1 << FIELD_GET(RZG3S_DIV_P, val);991 /* Hardware interprets values higher than 8 as p = 16. */992 if (pr > 8)993 pr = 16;994 995 mr = FIELD_GET(RZG3S_DIV_M, val) + 1;996 nir = FIELD_GET(RZG3S_DIV_NI, val) + 1;997 nfr = FIELD_GET(RZG3S_DIV_NF, val);998 999 rate = mul_u64_u32_shr(parent_rate, 4096 * nir + nfr, 12);1000 1001 return DIV_ROUND_CLOSEST_ULL(rate, (mr * pr));1002}1003 1004static const struct clk_ops rzg3s_cpg_pll_ops = {1005 .recalc_rate = rzg3s_cpg_pll_clk_recalc_rate,1006};1007 1008static struct clk * __init1009rzg2l_cpg_pll_clk_register(const struct cpg_core_clk *core,1010 struct rzg2l_cpg_priv *priv,1011 const struct clk_ops *ops)1012{1013 struct device *dev = priv->dev;1014 const struct clk *parent;1015 struct clk_init_data init;1016 const char *parent_name;1017 struct pll_clk *pll_clk;1018 int ret;1019 1020 parent = priv->clks[core->parent];1021 if (IS_ERR(parent))1022 return ERR_CAST(parent);1023 1024 pll_clk = devm_kzalloc(dev, sizeof(*pll_clk), GFP_KERNEL);1025 if (!pll_clk)1026 return ERR_PTR(-ENOMEM);1027 1028 parent_name = __clk_get_name(parent);1029 init.name = core->name;1030 init.ops = ops;1031 init.flags = 0;1032 init.parent_names = &parent_name;1033 init.num_parents = 1;1034 1035 pll_clk->hw.init = &init;1036 pll_clk->conf = core->conf;1037 pll_clk->base = priv->base;1038 pll_clk->priv = priv;1039 pll_clk->type = core->type;1040 1041 ret = devm_clk_hw_register(dev, &pll_clk->hw);1042 if (ret)1043 return ERR_PTR(ret);1044 1045 return pll_clk->hw.clk;1046}1047 1048static struct clk1049*rzg2l_cpg_clk_src_twocell_get(struct of_phandle_args *clkspec,1050 void *data)1051{1052 unsigned int clkidx = clkspec->args[1];1053 struct rzg2l_cpg_priv *priv = data;1054 struct device *dev = priv->dev;1055 const char *type;1056 struct clk *clk;1057 1058 switch (clkspec->args[0]) {1059 case CPG_CORE:1060 type = "core";1061 if (clkidx > priv->last_dt_core_clk) {1062 dev_err(dev, "Invalid %s clock index %u\n", type, clkidx);1063 return ERR_PTR(-EINVAL);1064 }1065 clk = priv->clks[clkidx];1066 break;1067 1068 case CPG_MOD:1069 type = "module";1070 if (clkidx >= priv->num_mod_clks) {1071 dev_err(dev, "Invalid %s clock index %u\n", type,1072 clkidx);1073 return ERR_PTR(-EINVAL);1074 }1075 clk = priv->clks[priv->num_core_clks + clkidx];1076 break;1077 1078 default:1079 dev_err(dev, "Invalid CPG clock type %u\n", clkspec->args[0]);1080 return ERR_PTR(-EINVAL);1081 }1082 1083 if (IS_ERR(clk))1084 dev_err(dev, "Cannot get %s clock %u: %ld", type, clkidx,1085 PTR_ERR(clk));1086 else1087 dev_dbg(dev, "clock (%u, %u) is %pC at %lu Hz\n",1088 clkspec->args[0], clkspec->args[1], clk,1089 clk_get_rate(clk));1090 return clk;1091}1092 1093static void __init1094rzg2l_cpg_register_core_clk(const struct cpg_core_clk *core,1095 const struct rzg2l_cpg_info *info,1096 struct rzg2l_cpg_priv *priv)1097{1098 struct clk *clk = ERR_PTR(-EOPNOTSUPP), *parent;1099 struct device *dev = priv->dev;1100 unsigned int id = core->id, div = core->div;1101 const char *parent_name;1102 struct clk_hw *clk_hw;1103 1104 WARN_DEBUG(id >= priv->num_core_clks);1105 WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT);1106 1107 if (!core->name) {1108 /* Skip NULLified clock */1109 return;1110 }1111 1112 switch (core->type) {1113 case CLK_TYPE_IN:1114 clk = of_clk_get_by_name(priv->dev->of_node, core->name);1115 break;1116 case CLK_TYPE_FF:1117 WARN_DEBUG(core->parent >= priv->num_core_clks);1118 parent = priv->clks[core->parent];1119 if (IS_ERR(parent)) {1120 clk = parent;1121 goto fail;1122 }1123 1124 parent_name = __clk_get_name(parent);1125 clk_hw = devm_clk_hw_register_fixed_factor(dev, core->name, parent_name,1126 CLK_SET_RATE_PARENT,1127 core->mult, div);1128 if (IS_ERR(clk_hw))1129 clk = ERR_CAST(clk_hw);1130 else1131 clk = clk_hw->clk;1132 break;1133 case CLK_TYPE_SAM_PLL:1134 clk = rzg2l_cpg_pll_clk_register(core, priv, &rzg2l_cpg_pll_ops);1135 break;1136 case CLK_TYPE_G3S_PLL:1137 clk = rzg2l_cpg_pll_clk_register(core, priv, &rzg3s_cpg_pll_ops);1138 break;1139 case CLK_TYPE_SIPLL5:1140 clk = rzg2l_cpg_sipll5_register(core, priv);1141 break;1142 case CLK_TYPE_DIV:1143 clk = rzg2l_cpg_div_clk_register(core, priv);1144 break;1145 case CLK_TYPE_G3S_DIV:1146 clk = rzg3s_cpg_div_clk_register(core, priv);1147 break;1148 case CLK_TYPE_MUX:1149 clk = rzg2l_cpg_mux_clk_register(core, priv);1150 break;1151 case CLK_TYPE_SD_MUX:1152 clk = rzg2l_cpg_sd_mux_clk_register(core, priv);1153 break;1154 case CLK_TYPE_PLL5_4_MUX:1155 clk = rzg2l_cpg_pll5_4_mux_clk_register(core, priv);1156 break;1157 case CLK_TYPE_DSI_DIV:1158 clk = rzg2l_cpg_dsi_div_clk_register(core, priv);1159 break;1160 default:1161 goto fail;1162 }1163 1164 if (IS_ERR_OR_NULL(clk))1165 goto fail;1166 1167 dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk));1168 priv->clks[id] = clk;1169 return;1170 1171fail:1172 dev_err(dev, "Failed to register %s clock %s: %ld\n", "core",1173 core->name, PTR_ERR(clk));1174}1175 1176/**1177 * struct mstp_clock - MSTP gating clock1178 *1179 * @hw: handle between common and hardware-specific interfaces1180 * @off: register offset1181 * @bit: ON/MON bit1182 * @enabled: soft state of the clock, if it is coupled with another clock1183 * @priv: CPG/MSTP private data1184 * @sibling: pointer to the other coupled clock1185 */1186struct mstp_clock {1187 struct clk_hw hw;1188 u16 off;1189 u8 bit;1190 bool enabled;1191 struct rzg2l_cpg_priv *priv;1192 struct mstp_clock *sibling;1193};1194 1195#define to_mod_clock(_hw) container_of(_hw, struct mstp_clock, hw)1196 1197static int rzg2l_mod_clock_endisable(struct clk_hw *hw, bool enable)1198{1199 struct mstp_clock *clock = to_mod_clock(hw);1200 struct rzg2l_cpg_priv *priv = clock->priv;1201 unsigned int reg = clock->off;1202 struct device *dev = priv->dev;1203 u32 bitmask = BIT(clock->bit);1204 u32 value;1205 int error;1206 1207 if (!clock->off) {1208 dev_dbg(dev, "%pC does not support ON/OFF\n", hw->clk);1209 return 0;1210 }1211 1212 dev_dbg(dev, "CLK_ON 0x%x/%pC %s\n", CLK_ON_R(reg), hw->clk,1213 enable ? "ON" : "OFF");1214 1215 value = bitmask << 16;1216 if (enable)1217 value |= bitmask;1218 1219 writel(value, priv->base + CLK_ON_R(reg));1220 1221 if (!enable)1222 return 0;1223 1224 if (!priv->info->has_clk_mon_regs)1225 return 0;1226 1227 error = readl_poll_timeout_atomic(priv->base + CLK_MON_R(reg), value,1228 value & bitmask, 0, 10);1229 if (error)1230 dev_err(dev, "Failed to enable CLK_ON %p\n",1231 priv->base + CLK_ON_R(reg));1232 1233 return error;1234}1235 1236static int rzg2l_mod_clock_enable(struct clk_hw *hw)1237{1238 struct mstp_clock *clock = to_mod_clock(hw);1239 1240 if (clock->sibling) {1241 struct rzg2l_cpg_priv *priv = clock->priv;1242 unsigned long flags;1243 bool enabled;1244 1245 spin_lock_irqsave(&priv->rmw_lock, flags);1246 enabled = clock->sibling->enabled;1247 clock->enabled = true;1248 spin_unlock_irqrestore(&priv->rmw_lock, flags);1249 if (enabled)1250 return 0;1251 }1252 1253 return rzg2l_mod_clock_endisable(hw, true);1254}1255 1256static void rzg2l_mod_clock_disable(struct clk_hw *hw)1257{1258 struct mstp_clock *clock = to_mod_clock(hw);1259 1260 if (clock->sibling) {1261 struct rzg2l_cpg_priv *priv = clock->priv;1262 unsigned long flags;1263 bool enabled;1264 1265 spin_lock_irqsave(&priv->rmw_lock, flags);1266 enabled = clock->sibling->enabled;1267 clock->enabled = false;1268 spin_unlock_irqrestore(&priv->rmw_lock, flags);1269 if (enabled)1270 return;1271 }1272 1273 rzg2l_mod_clock_endisable(hw, false);1274}1275 1276static int rzg2l_mod_clock_is_enabled(struct clk_hw *hw)1277{1278 struct mstp_clock *clock = to_mod_clock(hw);1279 struct rzg2l_cpg_priv *priv = clock->priv;1280 u32 bitmask = BIT(clock->bit);1281 u32 value;1282 1283 if (!clock->off) {1284 dev_dbg(priv->dev, "%pC does not support ON/OFF\n", hw->clk);1285 return 1;1286 }1287 1288 if (clock->sibling)1289 return clock->enabled;1290 1291 if (priv->info->has_clk_mon_regs)1292 value = readl(priv->base + CLK_MON_R(clock->off));1293 else1294 value = readl(priv->base + clock->off);1295 1296 return value & bitmask;1297}1298 1299static const struct clk_ops rzg2l_mod_clock_ops = {1300 .enable = rzg2l_mod_clock_enable,1301 .disable = rzg2l_mod_clock_disable,1302 .is_enabled = rzg2l_mod_clock_is_enabled,1303};1304 1305static struct mstp_clock1306*rzg2l_mod_clock_get_sibling(struct mstp_clock *clock,1307 struct rzg2l_cpg_priv *priv)1308{1309 struct clk_hw *hw;1310 unsigned int i;1311 1312 for (i = 0; i < priv->num_mod_clks; i++) {1313 struct mstp_clock *clk;1314 1315 if (priv->clks[priv->num_core_clks + i] == ERR_PTR(-ENOENT))1316 continue;1317 1318 hw = __clk_get_hw(priv->clks[priv->num_core_clks + i]);1319 clk = to_mod_clock(hw);1320 if (clock->off == clk->off && clock->bit == clk->bit)1321 return clk;1322 }1323 1324 return NULL;1325}1326 1327static void __init1328rzg2l_cpg_register_mod_clk(const struct rzg2l_mod_clk *mod,1329 const struct rzg2l_cpg_info *info,1330 struct rzg2l_cpg_priv *priv)1331{1332 struct mstp_clock *clock = NULL;1333 struct device *dev = priv->dev;1334 unsigned int id = mod->id;1335 struct clk_init_data init;1336 struct clk *parent, *clk;1337 const char *parent_name;1338 unsigned int i;1339 int ret;1340 1341 WARN_DEBUG(id < priv->num_core_clks);1342 WARN_DEBUG(id >= priv->num_core_clks + priv->num_mod_clks);1343 WARN_DEBUG(mod->parent >= priv->num_core_clks + priv->num_mod_clks);1344 WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT);1345 1346 if (!mod->name) {1347 /* Skip NULLified clock */1348 return;1349 }1350 1351 parent = priv->clks[mod->parent];1352 if (IS_ERR(parent)) {1353 clk = parent;1354 goto fail;1355 }1356 1357 clock = devm_kzalloc(dev, sizeof(*clock), GFP_KERNEL);1358 if (!clock) {1359 clk = ERR_PTR(-ENOMEM);1360 goto fail;1361 }1362 1363 init.name = mod->name;1364 init.ops = &rzg2l_mod_clock_ops;1365 init.flags = CLK_SET_RATE_PARENT;1366 for (i = 0; i < info->num_crit_mod_clks; i++)1367 if (id == info->crit_mod_clks[i]) {1368 dev_dbg(dev, "CPG %s setting CLK_IS_CRITICAL\n",1369 mod->name);1370 init.flags |= CLK_IS_CRITICAL;1371 break;1372 }1373 1374 parent_name = __clk_get_name(parent);1375 init.parent_names = &parent_name;1376 init.num_parents = 1;1377 1378 clock->off = mod->off;1379 clock->bit = mod->bit;1380 clock->priv = priv;1381 clock->hw.init = &init;1382 1383 ret = devm_clk_hw_register(dev, &clock->hw);1384 if (ret) {1385 clk = ERR_PTR(ret);1386 goto fail;1387 }1388 1389 clk = clock->hw.clk;1390 dev_dbg(dev, "Module clock %pC at %lu Hz\n", clk, clk_get_rate(clk));1391 priv->clks[id] = clk;1392 1393 if (mod->is_coupled) {1394 struct mstp_clock *sibling;1395 1396 clock->enabled = rzg2l_mod_clock_is_enabled(&clock->hw);1397 sibling = rzg2l_mod_clock_get_sibling(clock, priv);1398 if (sibling) {1399 clock->sibling = sibling;1400 sibling->sibling = clock;1401 }1402 }1403 1404 return;1405 1406fail:1407 dev_err(dev, "Failed to register %s clock %s: %ld\n", "module",1408 mod->name, PTR_ERR(clk));1409}1410 1411#define rcdev_to_priv(x) container_of(x, struct rzg2l_cpg_priv, rcdev)1412 1413static int rzg2l_cpg_assert(struct reset_controller_dev *rcdev,1414 unsigned long id)1415{1416 struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev);1417 const struct rzg2l_cpg_info *info = priv->info;1418 unsigned int reg = info->resets[id].off;1419 u32 mask = BIT(info->resets[id].bit);1420 s8 monbit = info->resets[id].monbit;1421 u32 value = mask << 16;1422 1423 dev_dbg(rcdev->dev, "assert id:%ld offset:0x%x\n", id, CLK_RST_R(reg));1424 1425 writel(value, priv->base + CLK_RST_R(reg));1426 1427 if (info->has_clk_mon_regs) {1428 reg = CLK_MRST_R(reg);1429 } else if (monbit >= 0) {1430 reg = CPG_RST_MON;1431 mask = BIT(monbit);1432 } else {1433 /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */1434 udelay(35);1435 return 0;1436 }1437 1438 return readl_poll_timeout_atomic(priv->base + reg, value,1439 value & mask, 10, 200);1440}1441 1442static int rzg2l_cpg_deassert(struct reset_controller_dev *rcdev,1443 unsigned long id)1444{1445 struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev);1446 const struct rzg2l_cpg_info *info = priv->info;1447 unsigned int reg = info->resets[id].off;1448 u32 mask = BIT(info->resets[id].bit);1449 s8 monbit = info->resets[id].monbit;1450 u32 value = (mask << 16) | mask;1451 1452 dev_dbg(rcdev->dev, "deassert id:%ld offset:0x%x\n", id,1453 CLK_RST_R(reg));1454 1455 writel(value, priv->base + CLK_RST_R(reg));1456 1457 if (info->has_clk_mon_regs) {1458 reg = CLK_MRST_R(reg);1459 } else if (monbit >= 0) {1460 reg = CPG_RST_MON;1461 mask = BIT(monbit);1462 } else {1463 /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */1464 udelay(35);1465 return 0;1466 }1467 1468 return readl_poll_timeout_atomic(priv->base + reg, value,1469 !(value & mask), 10, 200);1470}1471 1472static int rzg2l_cpg_reset(struct reset_controller_dev *rcdev,1473 unsigned long id)1474{1475 int ret;1476 1477 ret = rzg2l_cpg_assert(rcdev, id);1478 if (ret)1479 return ret;1480 1481 return rzg2l_cpg_deassert(rcdev, id);1482}1483 1484static int rzg2l_cpg_status(struct reset_controller_dev *rcdev,1485 unsigned long id)1486{1487 struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev);1488 const struct rzg2l_cpg_info *info = priv->info;1489 s8 monbit = info->resets[id].monbit;1490 unsigned int reg;1491 u32 bitmask;1492 1493 if (info->has_clk_mon_regs) {1494 reg = CLK_MRST_R(info->resets[id].off);1495 bitmask = BIT(info->resets[id].bit);1496 } else if (monbit >= 0) {1497 reg = CPG_RST_MON;1498 bitmask = BIT(monbit);1499 } else {1500 return -ENOTSUPP;1501 }1502 1503 return !!(readl(priv->base + reg) & bitmask);1504}1505 1506static const struct reset_control_ops rzg2l_cpg_reset_ops = {1507 .reset = rzg2l_cpg_reset,1508 .assert = rzg2l_cpg_assert,1509 .deassert = rzg2l_cpg_deassert,1510 .status = rzg2l_cpg_status,1511};1512 1513static int rzg2l_cpg_reset_xlate(struct reset_controller_dev *rcdev,1514 const struct of_phandle_args *reset_spec)1515{1516 struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev);1517 const struct rzg2l_cpg_info *info = priv->info;1518 unsigned int id = reset_spec->args[0];1519 1520 if (id >= rcdev->nr_resets || !info->resets[id].off) {1521 dev_err(rcdev->dev, "Invalid reset index %u\n", id);1522 return -EINVAL;1523 }1524 1525 return id;1526}1527 1528static int rzg2l_cpg_reset_controller_register(struct rzg2l_cpg_priv *priv)1529{1530 priv->rcdev.ops = &rzg2l_cpg_reset_ops;1531 priv->rcdev.of_node = priv->dev->of_node;1532 priv->rcdev.dev = priv->dev;1533 priv->rcdev.of_reset_n_cells = 1;1534 priv->rcdev.of_xlate = rzg2l_cpg_reset_xlate;1535 priv->rcdev.nr_resets = priv->num_resets;1536 1537 return devm_reset_controller_register(priv->dev, &priv->rcdev);1538}1539 1540static bool rzg2l_cpg_is_pm_clk(struct rzg2l_cpg_priv *priv,1541 const struct of_phandle_args *clkspec)1542{1543 const struct rzg2l_cpg_info *info = priv->info;1544 unsigned int id;1545 unsigned int i;1546 1547 if (clkspec->args_count != 2)1548 return false;1549 1550 if (clkspec->args[0] != CPG_MOD)1551 return false;1552 1553 id = clkspec->args[1] + info->num_total_core_clks;1554 for (i = 0; i < info->num_no_pm_mod_clks; i++) {1555 if (info->no_pm_mod_clks[i] == id)1556 return false;1557 }1558 1559 return true;1560}1561 1562/**1563 * struct rzg2l_cpg_pm_domains - RZ/G2L PM domains data structure1564 * @onecell_data: cell data1565 * @domains: generic PM domains1566 */1567struct rzg2l_cpg_pm_domains {1568 struct genpd_onecell_data onecell_data;1569 struct generic_pm_domain *domains[];1570};1571 1572/**1573 * struct rzg2l_cpg_pd - RZ/G2L power domain data structure1574 * @genpd: generic PM domain1575 * @priv: pointer to CPG private data structure1576 * @conf: CPG PM domain configuration info1577 * @id: RZ/G2L power domain ID1578 */1579struct rzg2l_cpg_pd {1580 struct generic_pm_domain genpd;1581 struct rzg2l_cpg_priv *priv;1582 struct rzg2l_cpg_pm_domain_conf conf;1583 u16 id;1584};1585 1586static int rzg2l_cpg_attach_dev(struct generic_pm_domain *domain, struct device *dev)1587{1588 struct rzg2l_cpg_pd *pd = container_of(domain, struct rzg2l_cpg_pd, genpd);1589 struct rzg2l_cpg_priv *priv = pd->priv;1590 struct device_node *np = dev->of_node;1591 struct of_phandle_args clkspec;1592 bool once = true;1593 struct clk *clk;1594 int error;1595 int i = 0;1596 1597 while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i,1598 &clkspec)) {1599 if (rzg2l_cpg_is_pm_clk(priv, &clkspec)) {1600 if (once) {1601 once = false;1602 error = pm_clk_create(dev);1603 if (error) {1604 of_node_put(clkspec.np);1605 goto err;1606 }1607 }1608 clk = of_clk_get_from_provider(&clkspec);1609 of_node_put(clkspec.np);1610 if (IS_ERR(clk)) {1611 error = PTR_ERR(clk);1612 goto fail_destroy;1613 }1614 1615 error = pm_clk_add_clk(dev, clk);1616 if (error) {1617 dev_err(dev, "pm_clk_add_clk failed %d\n",1618 error);1619 goto fail_put;1620 }1621 } else {1622 of_node_put(clkspec.np);1623 }1624 i++;1625 }1626 1627 return 0;1628 1629fail_put:1630 clk_put(clk);1631 1632fail_destroy:1633 pm_clk_destroy(dev);1634err:1635 return error;1636}1637 1638static void rzg2l_cpg_detach_dev(struct generic_pm_domain *unused, struct device *dev)1639{1640 if (!pm_clk_no_clocks(dev))1641 pm_clk_destroy(dev);1642}1643 1644static void rzg2l_cpg_genpd_remove(void *data)1645{1646 struct genpd_onecell_data *celldata = data;1647 1648 for (unsigned int i = 0; i < celldata->num_domains; i++)1649 pm_genpd_remove(celldata->domains[i]);1650}1651 1652static void rzg2l_cpg_genpd_remove_simple(void *data)1653{1654 pm_genpd_remove(data);1655}1656 1657static int rzg2l_cpg_power_on(struct generic_pm_domain *domain)1658{1659 struct rzg2l_cpg_pd *pd = container_of(domain, struct rzg2l_cpg_pd, genpd);1660 struct rzg2l_cpg_reg_conf mstop = pd->conf.mstop;1661 struct rzg2l_cpg_priv *priv = pd->priv;1662 1663 /* Set MSTOP. */1664 if (mstop.mask)1665 writel(mstop.mask << 16, priv->base + mstop.off);1666 1667 return 0;1668}1669 1670static int rzg2l_cpg_power_off(struct generic_pm_domain *domain)1671{1672 struct rzg2l_cpg_pd *pd = container_of(domain, struct rzg2l_cpg_pd, genpd);1673 struct rzg2l_cpg_reg_conf mstop = pd->conf.mstop;1674 struct rzg2l_cpg_priv *priv = pd->priv;1675 1676 /* Set MSTOP. */1677 if (mstop.mask)1678 writel(mstop.mask | (mstop.mask << 16), priv->base + mstop.off);1679 1680 return 0;1681}1682 1683static int __init rzg2l_cpg_pd_setup(struct rzg2l_cpg_pd *pd, bool always_on)1684{1685 struct dev_power_governor *governor;1686 1687 pd->genpd.flags |= GENPD_FLAG_PM_CLK | GENPD_FLAG_ACTIVE_WAKEUP;1688 pd->genpd.attach_dev = rzg2l_cpg_attach_dev;1689 pd->genpd.detach_dev = rzg2l_cpg_detach_dev;1690 if (always_on) {1691 pd->genpd.flags |= GENPD_FLAG_ALWAYS_ON;1692 governor = &pm_domain_always_on_gov;1693 } else {1694 pd->genpd.power_on = rzg2l_cpg_power_on;1695 pd->genpd.power_off = rzg2l_cpg_power_off;1696 governor = &simple_qos_governor;1697 }1698 1699 return pm_genpd_init(&pd->genpd, governor, !always_on);1700}1701 1702static int __init rzg2l_cpg_add_clk_domain(struct rzg2l_cpg_priv *priv)1703{1704 struct device *dev = priv->dev;1705 struct device_node *np = dev->of_node;1706 struct rzg2l_cpg_pd *pd;1707 int ret;1708 1709 pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);1710 if (!pd)1711 return -ENOMEM;1712 1713 pd->genpd.name = np->name;1714 pd->priv = priv;1715 ret = rzg2l_cpg_pd_setup(pd, true);1716 if (ret)1717 return ret;1718 1719 ret = devm_add_action_or_reset(dev, rzg2l_cpg_genpd_remove_simple, &pd->genpd);1720 if (ret)1721 return ret;1722 1723 return of_genpd_add_provider_simple(np, &pd->genpd);1724}1725 1726static struct generic_pm_domain *1727rzg2l_cpg_pm_domain_xlate(const struct of_phandle_args *spec, void *data)1728{1729 struct generic_pm_domain *domain = ERR_PTR(-ENOENT);1730 struct genpd_onecell_data *genpd = data;1731 1732 if (spec->args_count != 1)1733 return ERR_PTR(-EINVAL);1734 1735 for (unsigned int i = 0; i < genpd->num_domains; i++) {1736 struct rzg2l_cpg_pd *pd = container_of(genpd->domains[i], struct rzg2l_cpg_pd,1737 genpd);1738 1739 if (pd->id == spec->args[0]) {1740 domain = &pd->genpd;1741 break;1742 }1743 }1744 1745 return domain;1746}1747 1748static int __init rzg2l_cpg_add_pm_domains(struct rzg2l_cpg_priv *priv)1749{1750 const struct rzg2l_cpg_info *info = priv->info;1751 struct device *dev = priv->dev;1752 struct device_node *np = dev->of_node;1753 struct rzg2l_cpg_pm_domains *domains;1754 struct generic_pm_domain *parent;1755 u32 ncells;1756 int ret;1757 1758 ret = of_property_read_u32(np, "#power-domain-cells", &ncells);1759 if (ret)1760 return ret;1761 1762 /* For backward compatibility. */1763 if (!ncells)1764 return rzg2l_cpg_add_clk_domain(priv);1765 1766 domains = devm_kzalloc(dev, struct_size(domains, domains, info->num_pm_domains),1767 GFP_KERNEL);1768 if (!domains)1769 return -ENOMEM;1770 1771 domains->onecell_data.domains = domains->domains;1772 domains->onecell_data.num_domains = info->num_pm_domains;1773 domains->onecell_data.xlate = rzg2l_cpg_pm_domain_xlate;1774 1775 ret = devm_add_action_or_reset(dev, rzg2l_cpg_genpd_remove, &domains->onecell_data);1776 if (ret)1777 return ret;1778 1779 for (unsigned int i = 0; i < info->num_pm_domains; i++) {1780 bool always_on = !!(info->pm_domains[i].flags & RZG2L_PD_F_ALWAYS_ON);1781 struct rzg2l_cpg_pd *pd;1782 1783 pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);1784 if (!pd)1785 return -ENOMEM;1786 1787 pd->genpd.name = info->pm_domains[i].name;1788 pd->conf = info->pm_domains[i].conf;1789 pd->id = info->pm_domains[i].id;1790 pd->priv = priv;1791 1792 ret = rzg2l_cpg_pd_setup(pd, always_on);1793 if (ret)1794 return ret;1795 1796 if (always_on) {1797 ret = rzg2l_cpg_power_on(&pd->genpd);1798 if (ret)1799 return ret;1800 }1801 1802 domains->domains[i] = &pd->genpd;1803 /* Parent should be on the very first entry of info->pm_domains[]. */1804 if (!i) {1805 parent = &pd->genpd;1806 continue;1807 }1808 1809 ret = pm_genpd_add_subdomain(parent, &pd->genpd);1810 if (ret)1811 return ret;1812 }1813 1814 ret = of_genpd_add_provider_onecell(np, &domains->onecell_data);1815 if (ret)1816 return ret;1817 1818 return 0;1819}1820 1821static int __init rzg2l_cpg_probe(struct platform_device *pdev)1822{1823 struct device *dev = &pdev->dev;1824 struct device_node *np = dev->of_node;1825 const struct rzg2l_cpg_info *info;1826 struct rzg2l_cpg_priv *priv;1827 unsigned int nclks, i;1828 struct clk **clks;1829 int error;1830 1831 info = of_device_get_match_data(dev);1832 1833 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);1834 if (!priv)1835 return -ENOMEM;1836 1837 priv->dev = dev;1838 priv->info = info;1839 spin_lock_init(&priv->rmw_lock);1840 1841 priv->base = devm_platform_ioremap_resource(pdev, 0);1842 if (IS_ERR(priv->base))1843 return PTR_ERR(priv->base);1844 1845 nclks = info->num_total_core_clks + info->num_hw_mod_clks;1846 clks = devm_kmalloc_array(dev, nclks, sizeof(*clks), GFP_KERNEL);1847 if (!clks)1848 return -ENOMEM;1849 1850 dev_set_drvdata(dev, priv);1851 priv->clks = clks;1852 priv->num_core_clks = info->num_total_core_clks;1853 priv->num_mod_clks = info->num_hw_mod_clks;1854 priv->num_resets = info->num_resets;1855 priv->last_dt_core_clk = info->last_dt_core_clk;1856 1857 for (i = 0; i < nclks; i++)1858 clks[i] = ERR_PTR(-ENOENT);1859 1860 for (i = 0; i < info->num_core_clks; i++)1861 rzg2l_cpg_register_core_clk(&info->core_clks[i], info, priv);1862 1863 for (i = 0; i < info->num_mod_clks; i++)1864 rzg2l_cpg_register_mod_clk(&info->mod_clks[i], info, priv);1865 1866 error = of_clk_add_provider(np, rzg2l_cpg_clk_src_twocell_get, priv);1867 if (error)1868 return error;1869 1870 error = devm_add_action_or_reset(dev, rzg2l_cpg_del_clk_provider, np);1871 if (error)1872 return error;1873 1874 error = rzg2l_cpg_add_pm_domains(priv);1875 if (error)1876 return error;1877 1878 error = rzg2l_cpg_reset_controller_register(priv);1879 if (error)1880 return error;1881 1882 return 0;1883}1884 1885static const struct of_device_id rzg2l_cpg_match[] = {1886#ifdef CONFIG_CLK_R9A07G0431887 {1888 .compatible = "renesas,r9a07g043-cpg",1889 .data = &r9a07g043_cpg_info,1890 },1891#endif1892#ifdef CONFIG_CLK_R9A07G0441893 {1894 .compatible = "renesas,r9a07g044-cpg",1895 .data = &r9a07g044_cpg_info,1896 },1897#endif1898#ifdef CONFIG_CLK_R9A07G0541899 {1900 .compatible = "renesas,r9a07g054-cpg",1901 .data = &r9a07g054_cpg_info,1902 },1903#endif1904#ifdef CONFIG_CLK_R9A08G0451905 {1906 .compatible = "renesas,r9a08g045-cpg",1907 .data = &r9a08g045_cpg_info,1908 },1909#endif1910#ifdef CONFIG_CLK_R9A09G0111911 {1912 .compatible = "renesas,r9a09g011-cpg",1913 .data = &r9a09g011_cpg_info,1914 },1915#endif1916 { /* sentinel */ }1917};1918 1919static struct platform_driver rzg2l_cpg_driver = {1920 .driver = {1921 .name = "rzg2l-cpg",1922 .of_match_table = rzg2l_cpg_match,1923 },1924};1925 1926static int __init rzg2l_cpg_init(void)1927{1928 return platform_driver_probe(&rzg2l_cpg_driver, rzg2l_cpg_probe);1929}1930 1931subsys_initcall(rzg2l_cpg_init);1932 1933MODULE_DESCRIPTION("Renesas RZ/G2L CPG Driver");1934