853 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Ingenic SoC CGU driver4 *5 * Copyright (c) 2013-2015 Imagination Technologies6 * Author: Paul Burton <paul.burton@mips.com>7 */8 9#include <linux/bitops.h>10#include <linux/clk.h>11#include <linux/clk-provider.h>12#include <linux/clkdev.h>13#include <linux/delay.h>14#include <linux/io.h>15#include <linux/iopoll.h>16#include <linux/math64.h>17#include <linux/of.h>18#include <linux/of_address.h>19#include <linux/slab.h>20#include <linux/spinlock.h>21#include <linux/time.h>22 23#include "cgu.h"24 25#define MHZ (1000 * 1000)26 27static inline const struct ingenic_cgu_clk_info *28to_clk_info(struct ingenic_clk *clk)29{30 return &clk->cgu->clock_info[clk->idx];31}32 33/**34 * ingenic_cgu_gate_get() - get the value of clock gate register bit35 * @cgu: reference to the CGU whose registers should be read36 * @info: info struct describing the gate bit37 *38 * Retrieves the state of the clock gate bit described by info. The39 * caller must hold cgu->lock.40 *41 * Return: true if the gate bit is set, else false.42 */43static inline bool44ingenic_cgu_gate_get(struct ingenic_cgu *cgu,45 const struct ingenic_cgu_gate_info *info)46{47 return !!(readl(cgu->base + info->reg) & BIT(info->bit))48 ^ info->clear_to_gate;49}50 51/**52 * ingenic_cgu_gate_set() - set the value of clock gate register bit53 * @cgu: reference to the CGU whose registers should be modified54 * @info: info struct describing the gate bit55 * @val: non-zero to gate a clock, otherwise zero56 *57 * Sets the given gate bit in order to gate or ungate a clock.58 *59 * The caller must hold cgu->lock.60 */61static inline void62ingenic_cgu_gate_set(struct ingenic_cgu *cgu,63 const struct ingenic_cgu_gate_info *info, bool val)64{65 u32 clkgr = readl(cgu->base + info->reg);66 67 if (val ^ info->clear_to_gate)68 clkgr |= BIT(info->bit);69 else70 clkgr &= ~BIT(info->bit);71 72 writel(clkgr, cgu->base + info->reg);73}74 75/*76 * PLL operations77 */78 79static unsigned long80ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)81{82 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);83 const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);84 struct ingenic_cgu *cgu = ingenic_clk->cgu;85 const struct ingenic_cgu_pll_info *pll_info;86 unsigned m, n, od, od_enc = 0;87 bool bypass;88 u32 ctl;89 90 BUG_ON(clk_info->type != CGU_CLK_PLL);91 pll_info = &clk_info->pll;92 93 ctl = readl(cgu->base + pll_info->reg);94 95 m = (ctl >> pll_info->m_shift) & GENMASK(pll_info->m_bits - 1, 0);96 m += pll_info->m_offset;97 n = (ctl >> pll_info->n_shift) & GENMASK(pll_info->n_bits - 1, 0);98 n += pll_info->n_offset;99 100 if (pll_info->od_bits > 0) {101 od_enc = ctl >> pll_info->od_shift;102 od_enc &= GENMASK(pll_info->od_bits - 1, 0);103 }104 105 if (pll_info->bypass_bit >= 0) {106 ctl = readl(cgu->base + pll_info->bypass_reg);107 108 bypass = !!(ctl & BIT(pll_info->bypass_bit));109 110 if (bypass)111 return parent_rate;112 }113 114 for (od = 0; od < pll_info->od_max; od++)115 if (pll_info->od_encoding[od] == od_enc)116 break;117 118 /* if od_max = 0, od_bits should be 0 and od is fixed to 1. */119 if (pll_info->od_max == 0)120 BUG_ON(pll_info->od_bits != 0);121 else122 BUG_ON(od == pll_info->od_max);123 od++;124 125 return div_u64((u64)parent_rate * m * pll_info->rate_multiplier,126 n * od);127}128 129static void130ingenic_pll_calc_m_n_od(const struct ingenic_cgu_pll_info *pll_info,131 unsigned long rate, unsigned long parent_rate,132 unsigned int *pm, unsigned int *pn, unsigned int *pod)133{134 unsigned int m, n, od = 1;135 136 /*137 * The frequency after the input divider must be between 10 and 50 MHz.138 * The highest divider yields the best resolution.139 */140 n = parent_rate / (10 * MHZ);141 n = min_t(unsigned int, n, 1 << pll_info->n_bits);142 n = max_t(unsigned int, n, pll_info->n_offset);143 144 m = (rate / MHZ) * od * n / (parent_rate / MHZ);145 m = min_t(unsigned int, m, 1 << pll_info->m_bits);146 m = max_t(unsigned int, m, pll_info->m_offset);147 148 *pm = m;149 *pn = n;150 *pod = od;151}152 153static unsigned long154ingenic_pll_calc(const struct ingenic_cgu_clk_info *clk_info,155 unsigned long rate, unsigned long parent_rate,156 unsigned int *pm, unsigned int *pn, unsigned int *pod)157{158 const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll;159 unsigned int m, n, od;160 161 if (pll_info->calc_m_n_od)162 (*pll_info->calc_m_n_od)(pll_info, rate, parent_rate, &m, &n, &od);163 else164 ingenic_pll_calc_m_n_od(pll_info, rate, parent_rate, &m, &n, &od);165 166 if (pm)167 *pm = m;168 if (pn)169 *pn = n;170 if (pod)171 *pod = od;172 173 return div_u64((u64)parent_rate * m * pll_info->rate_multiplier,174 n * od);175}176 177static long178ingenic_pll_round_rate(struct clk_hw *hw, unsigned long req_rate,179 unsigned long *prate)180{181 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);182 const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);183 184 return ingenic_pll_calc(clk_info, req_rate, *prate, NULL, NULL, NULL);185}186 187static inline int ingenic_pll_check_stable(struct ingenic_cgu *cgu,188 const struct ingenic_cgu_pll_info *pll_info)189{190 u32 ctl;191 192 if (pll_info->stable_bit < 0)193 return 0;194 195 return readl_poll_timeout(cgu->base + pll_info->reg, ctl,196 ctl & BIT(pll_info->stable_bit),197 0, 100 * USEC_PER_MSEC);198}199 200static int201ingenic_pll_set_rate(struct clk_hw *hw, unsigned long req_rate,202 unsigned long parent_rate)203{204 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);205 struct ingenic_cgu *cgu = ingenic_clk->cgu;206 const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);207 const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll;208 unsigned long rate, flags;209 unsigned int m, n, od;210 int ret = 0;211 u32 ctl;212 213 rate = ingenic_pll_calc(clk_info, req_rate, parent_rate,214 &m, &n, &od);215 if (rate != req_rate)216 pr_info("ingenic-cgu: request '%s' rate %luHz, actual %luHz\n",217 clk_info->name, req_rate, rate);218 219 spin_lock_irqsave(&cgu->lock, flags);220 ctl = readl(cgu->base + pll_info->reg);221 222 ctl &= ~(GENMASK(pll_info->m_bits - 1, 0) << pll_info->m_shift);223 ctl |= (m - pll_info->m_offset) << pll_info->m_shift;224 225 ctl &= ~(GENMASK(pll_info->n_bits - 1, 0) << pll_info->n_shift);226 ctl |= (n - pll_info->n_offset) << pll_info->n_shift;227 228 if (pll_info->od_bits > 0) {229 ctl &= ~(GENMASK(pll_info->od_bits - 1, 0) << pll_info->od_shift);230 ctl |= pll_info->od_encoding[od - 1] << pll_info->od_shift;231 }232 233 writel(ctl, cgu->base + pll_info->reg);234 235 if (pll_info->set_rate_hook)236 pll_info->set_rate_hook(pll_info, rate, parent_rate);237 238 /* If the PLL is enabled, verify that it's stable */239 if (pll_info->enable_bit >= 0 && (ctl & BIT(pll_info->enable_bit)))240 ret = ingenic_pll_check_stable(cgu, pll_info);241 242 spin_unlock_irqrestore(&cgu->lock, flags);243 244 return ret;245}246 247static int ingenic_pll_enable(struct clk_hw *hw)248{249 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);250 struct ingenic_cgu *cgu = ingenic_clk->cgu;251 const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);252 const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll;253 unsigned long flags;254 int ret;255 u32 ctl;256 257 if (pll_info->enable_bit < 0)258 return 0;259 260 spin_lock_irqsave(&cgu->lock, flags);261 if (pll_info->bypass_bit >= 0) {262 ctl = readl(cgu->base + pll_info->bypass_reg);263 264 ctl &= ~BIT(pll_info->bypass_bit);265 266 writel(ctl, cgu->base + pll_info->bypass_reg);267 }268 269 ctl = readl(cgu->base + pll_info->reg);270 271 ctl |= BIT(pll_info->enable_bit);272 273 writel(ctl, cgu->base + pll_info->reg);274 275 ret = ingenic_pll_check_stable(cgu, pll_info);276 spin_unlock_irqrestore(&cgu->lock, flags);277 278 return ret;279}280 281static void ingenic_pll_disable(struct clk_hw *hw)282{283 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);284 struct ingenic_cgu *cgu = ingenic_clk->cgu;285 const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);286 const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll;287 unsigned long flags;288 u32 ctl;289 290 if (pll_info->enable_bit < 0)291 return;292 293 spin_lock_irqsave(&cgu->lock, flags);294 ctl = readl(cgu->base + pll_info->reg);295 296 ctl &= ~BIT(pll_info->enable_bit);297 298 writel(ctl, cgu->base + pll_info->reg);299 spin_unlock_irqrestore(&cgu->lock, flags);300}301 302static int ingenic_pll_is_enabled(struct clk_hw *hw)303{304 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);305 struct ingenic_cgu *cgu = ingenic_clk->cgu;306 const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);307 const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll;308 u32 ctl;309 310 if (pll_info->enable_bit < 0)311 return true;312 313 ctl = readl(cgu->base + pll_info->reg);314 315 return !!(ctl & BIT(pll_info->enable_bit));316}317 318static const struct clk_ops ingenic_pll_ops = {319 .recalc_rate = ingenic_pll_recalc_rate,320 .round_rate = ingenic_pll_round_rate,321 .set_rate = ingenic_pll_set_rate,322 323 .enable = ingenic_pll_enable,324 .disable = ingenic_pll_disable,325 .is_enabled = ingenic_pll_is_enabled,326};327 328/*329 * Operations for all non-PLL clocks330 */331 332static u8 ingenic_clk_get_parent(struct clk_hw *hw)333{334 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);335 const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);336 struct ingenic_cgu *cgu = ingenic_clk->cgu;337 u32 reg;338 u8 i, hw_idx, idx = 0;339 340 if (clk_info->type & CGU_CLK_MUX) {341 reg = readl(cgu->base + clk_info->mux.reg);342 hw_idx = (reg >> clk_info->mux.shift) &343 GENMASK(clk_info->mux.bits - 1, 0);344 345 /*346 * Convert the hardware index to the parent index by skipping347 * over any -1's in the parents array.348 */349 for (i = 0; i < hw_idx; i++) {350 if (clk_info->parents[i] != -1)351 idx++;352 }353 }354 355 return idx;356}357 358static int ingenic_clk_set_parent(struct clk_hw *hw, u8 idx)359{360 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);361 const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);362 struct ingenic_cgu *cgu = ingenic_clk->cgu;363 unsigned long flags;364 u8 curr_idx, hw_idx, num_poss;365 u32 reg, mask;366 367 if (clk_info->type & CGU_CLK_MUX) {368 /*369 * Convert the parent index to the hardware index by adding370 * 1 for any -1 in the parents array preceding the given371 * index. That is, we want the index of idx'th entry in372 * clk_info->parents which does not equal -1.373 */374 hw_idx = curr_idx = 0;375 num_poss = 1 << clk_info->mux.bits;376 for (; hw_idx < num_poss; hw_idx++) {377 if (clk_info->parents[hw_idx] == -1)378 continue;379 if (curr_idx == idx)380 break;381 curr_idx++;382 }383 384 /* idx should always be a valid parent */385 BUG_ON(curr_idx != idx);386 387 mask = GENMASK(clk_info->mux.bits - 1, 0);388 mask <<= clk_info->mux.shift;389 390 spin_lock_irqsave(&cgu->lock, flags);391 392 /* write the register */393 reg = readl(cgu->base + clk_info->mux.reg);394 reg &= ~mask;395 reg |= hw_idx << clk_info->mux.shift;396 writel(reg, cgu->base + clk_info->mux.reg);397 398 spin_unlock_irqrestore(&cgu->lock, flags);399 return 0;400 }401 402 return idx ? -EINVAL : 0;403}404 405static unsigned long406ingenic_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)407{408 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);409 const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);410 struct ingenic_cgu *cgu = ingenic_clk->cgu;411 unsigned long rate = parent_rate;412 u32 div_reg, div;413 u8 parent;414 415 if (clk_info->type & CGU_CLK_DIV) {416 parent = ingenic_clk_get_parent(hw);417 418 if (!(clk_info->div.bypass_mask & BIT(parent))) {419 div_reg = readl(cgu->base + clk_info->div.reg);420 div = (div_reg >> clk_info->div.shift) &421 GENMASK(clk_info->div.bits - 1, 0);422 423 if (clk_info->div.div_table)424 div = clk_info->div.div_table[div];425 else426 div = (div + 1) * clk_info->div.div;427 428 rate /= div;429 }430 } else if (clk_info->type & CGU_CLK_FIXDIV) {431 rate /= clk_info->fixdiv.div;432 }433 434 return rate;435}436 437static unsigned int438ingenic_clk_calc_hw_div(const struct ingenic_cgu_clk_info *clk_info,439 unsigned int div)440{441 unsigned int i, best_i = 0, best = (unsigned int)-1;442 443 for (i = 0; i < (1 << clk_info->div.bits)444 && clk_info->div.div_table[i]; i++) {445 if (clk_info->div.div_table[i] >= div &&446 clk_info->div.div_table[i] < best) {447 best = clk_info->div.div_table[i];448 best_i = i;449 450 if (div == best)451 break;452 }453 }454 455 return best_i;456}457 458static unsigned459ingenic_clk_calc_div(struct clk_hw *hw,460 const struct ingenic_cgu_clk_info *clk_info,461 unsigned long parent_rate, unsigned long req_rate)462{463 unsigned int div, hw_div;464 u8 parent;465 466 parent = ingenic_clk_get_parent(hw);467 if (clk_info->div.bypass_mask & BIT(parent))468 return 1;469 470 /* calculate the divide */471 div = DIV_ROUND_UP(parent_rate, req_rate);472 473 if (clk_info->div.div_table) {474 hw_div = ingenic_clk_calc_hw_div(clk_info, div);475 476 return clk_info->div.div_table[hw_div];477 }478 479 /* Impose hardware constraints */480 div = clamp_t(unsigned int, div, clk_info->div.div,481 clk_info->div.div << clk_info->div.bits);482 483 /*484 * If the divider value itself must be divided before being written to485 * the divider register, we must ensure we don't have any bits set that486 * would be lost as a result of doing so.487 */488 div = DIV_ROUND_UP(div, clk_info->div.div);489 div *= clk_info->div.div;490 491 return div;492}493 494static int ingenic_clk_determine_rate(struct clk_hw *hw,495 struct clk_rate_request *req)496{497 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);498 const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);499 unsigned int div = 1;500 501 if (clk_info->type & CGU_CLK_DIV)502 div = ingenic_clk_calc_div(hw, clk_info, req->best_parent_rate,503 req->rate);504 else if (clk_info->type & CGU_CLK_FIXDIV)505 div = clk_info->fixdiv.div;506 else if (clk_hw_can_set_rate_parent(hw))507 req->best_parent_rate = req->rate;508 509 req->rate = DIV_ROUND_UP(req->best_parent_rate, div);510 return 0;511}512 513static inline int ingenic_clk_check_stable(struct ingenic_cgu *cgu,514 const struct ingenic_cgu_clk_info *clk_info)515{516 u32 reg;517 518 return readl_poll_timeout(cgu->base + clk_info->div.reg, reg,519 !(reg & BIT(clk_info->div.busy_bit)),520 0, 100 * USEC_PER_MSEC);521}522 523static int524ingenic_clk_set_rate(struct clk_hw *hw, unsigned long req_rate,525 unsigned long parent_rate)526{527 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);528 const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);529 struct ingenic_cgu *cgu = ingenic_clk->cgu;530 unsigned long rate, flags;531 unsigned int hw_div, div;532 u32 reg, mask;533 int ret = 0;534 535 if (clk_info->type & CGU_CLK_DIV) {536 div = ingenic_clk_calc_div(hw, clk_info, parent_rate, req_rate);537 rate = DIV_ROUND_UP(parent_rate, div);538 539 if (rate != req_rate)540 return -EINVAL;541 542 if (clk_info->div.div_table)543 hw_div = ingenic_clk_calc_hw_div(clk_info, div);544 else545 hw_div = ((div / clk_info->div.div) - 1);546 547 spin_lock_irqsave(&cgu->lock, flags);548 reg = readl(cgu->base + clk_info->div.reg);549 550 /* update the divide */551 mask = GENMASK(clk_info->div.bits - 1, 0);552 reg &= ~(mask << clk_info->div.shift);553 reg |= hw_div << clk_info->div.shift;554 555 /* clear the stop bit */556 if (clk_info->div.stop_bit != -1)557 reg &= ~BIT(clk_info->div.stop_bit);558 559 /* set the change enable bit */560 if (clk_info->div.ce_bit != -1)561 reg |= BIT(clk_info->div.ce_bit);562 563 /* update the hardware */564 writel(reg, cgu->base + clk_info->div.reg);565 566 /* wait for the change to take effect */567 if (clk_info->div.busy_bit != -1)568 ret = ingenic_clk_check_stable(cgu, clk_info);569 570 spin_unlock_irqrestore(&cgu->lock, flags);571 return ret;572 }573 574 return -EINVAL;575}576 577static int ingenic_clk_enable(struct clk_hw *hw)578{579 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);580 const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);581 struct ingenic_cgu *cgu = ingenic_clk->cgu;582 unsigned long flags;583 584 if (clk_info->type & CGU_CLK_GATE) {585 /* ungate the clock */586 spin_lock_irqsave(&cgu->lock, flags);587 ingenic_cgu_gate_set(cgu, &clk_info->gate, false);588 spin_unlock_irqrestore(&cgu->lock, flags);589 590 if (clk_info->gate.delay_us)591 udelay(clk_info->gate.delay_us);592 }593 594 return 0;595}596 597static void ingenic_clk_disable(struct clk_hw *hw)598{599 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);600 const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);601 struct ingenic_cgu *cgu = ingenic_clk->cgu;602 unsigned long flags;603 604 if (clk_info->type & CGU_CLK_GATE) {605 /* gate the clock */606 spin_lock_irqsave(&cgu->lock, flags);607 ingenic_cgu_gate_set(cgu, &clk_info->gate, true);608 spin_unlock_irqrestore(&cgu->lock, flags);609 }610}611 612static int ingenic_clk_is_enabled(struct clk_hw *hw)613{614 struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);615 const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);616 struct ingenic_cgu *cgu = ingenic_clk->cgu;617 int enabled = 1;618 619 if (clk_info->type & CGU_CLK_GATE)620 enabled = !ingenic_cgu_gate_get(cgu, &clk_info->gate);621 622 return enabled;623}624 625static const struct clk_ops ingenic_clk_ops = {626 .get_parent = ingenic_clk_get_parent,627 .set_parent = ingenic_clk_set_parent,628 629 .recalc_rate = ingenic_clk_recalc_rate,630 .determine_rate = ingenic_clk_determine_rate,631 .set_rate = ingenic_clk_set_rate,632 633 .enable = ingenic_clk_enable,634 .disable = ingenic_clk_disable,635 .is_enabled = ingenic_clk_is_enabled,636};637 638/*639 * Setup functions.640 */641 642static int ingenic_register_clock(struct ingenic_cgu *cgu, unsigned idx)643{644 const struct ingenic_cgu_clk_info *clk_info = &cgu->clock_info[idx];645 struct clk_init_data clk_init;646 struct ingenic_clk *ingenic_clk = NULL;647 struct clk *clk, *parent;648 const char *parent_names[4];649 unsigned caps, i, num_possible;650 int err = -EINVAL;651 652 BUILD_BUG_ON(ARRAY_SIZE(clk_info->parents) > ARRAY_SIZE(parent_names));653 654 if (clk_info->type == CGU_CLK_EXT) {655 clk = of_clk_get_by_name(cgu->np, clk_info->name);656 if (IS_ERR(clk)) {657 pr_err("%s: no external clock '%s' provided\n",658 __func__, clk_info->name);659 err = -ENODEV;660 goto out;661 }662 err = clk_register_clkdev(clk, clk_info->name, NULL);663 if (err) {664 clk_put(clk);665 goto out;666 }667 cgu->clocks.clks[idx] = clk;668 return 0;669 }670 671 if (!clk_info->type) {672 pr_err("%s: no clock type specified for '%s'\n", __func__,673 clk_info->name);674 goto out;675 }676 677 ingenic_clk = kzalloc(sizeof(*ingenic_clk), GFP_KERNEL);678 if (!ingenic_clk) {679 err = -ENOMEM;680 goto out;681 }682 683 ingenic_clk->hw.init = &clk_init;684 ingenic_clk->cgu = cgu;685 ingenic_clk->idx = idx;686 687 clk_init.name = clk_info->name;688 clk_init.flags = clk_info->flags;689 clk_init.parent_names = parent_names;690 691 caps = clk_info->type;692 693 if (caps & CGU_CLK_DIV) {694 caps &= ~CGU_CLK_DIV;695 } else if (!(caps & CGU_CLK_CUSTOM)) {696 /* pass rate changes to the parent clock */697 clk_init.flags |= CLK_SET_RATE_PARENT;698 }699 700 if (caps & (CGU_CLK_MUX | CGU_CLK_CUSTOM)) {701 clk_init.num_parents = 0;702 703 if (caps & CGU_CLK_MUX)704 num_possible = 1 << clk_info->mux.bits;705 else706 num_possible = ARRAY_SIZE(clk_info->parents);707 708 for (i = 0; i < num_possible; i++) {709 if (clk_info->parents[i] == -1)710 continue;711 712 parent = cgu->clocks.clks[clk_info->parents[i]];713 parent_names[clk_init.num_parents] =714 __clk_get_name(parent);715 clk_init.num_parents++;716 }717 718 BUG_ON(!clk_init.num_parents);719 BUG_ON(clk_init.num_parents > ARRAY_SIZE(parent_names));720 } else {721 BUG_ON(clk_info->parents[0] == -1);722 clk_init.num_parents = 1;723 parent = cgu->clocks.clks[clk_info->parents[0]];724 parent_names[0] = __clk_get_name(parent);725 }726 727 if (caps & CGU_CLK_CUSTOM) {728 clk_init.ops = clk_info->custom.clk_ops;729 730 caps &= ~CGU_CLK_CUSTOM;731 732 if (caps) {733 pr_err("%s: custom clock may not be combined with type 0x%x\n",734 __func__, caps);735 goto out;736 }737 } else if (caps & CGU_CLK_PLL) {738 clk_init.ops = &ingenic_pll_ops;739 740 caps &= ~CGU_CLK_PLL;741 742 if (caps) {743 pr_err("%s: PLL may not be combined with type 0x%x\n",744 __func__, caps);745 goto out;746 }747 } else {748 clk_init.ops = &ingenic_clk_ops;749 }750 751 /* nothing to do for gates or fixed dividers */752 caps &= ~(CGU_CLK_GATE | CGU_CLK_FIXDIV);753 754 if (caps & CGU_CLK_MUX) {755 if (!(caps & CGU_CLK_MUX_GLITCHFREE))756 clk_init.flags |= CLK_SET_PARENT_GATE;757 758 caps &= ~(CGU_CLK_MUX | CGU_CLK_MUX_GLITCHFREE);759 }760 761 if (caps) {762 pr_err("%s: unknown clock type 0x%x\n", __func__, caps);763 goto out;764 }765 766 clk = clk_register(NULL, &ingenic_clk->hw);767 if (IS_ERR(clk)) {768 pr_err("%s: failed to register clock '%s'\n", __func__,769 clk_info->name);770 err = PTR_ERR(clk);771 goto out;772 }773 774 err = clk_register_clkdev(clk, clk_info->name, NULL);775 if (err)776 goto out;777 778 cgu->clocks.clks[idx] = clk;779out:780 if (err)781 kfree(ingenic_clk);782 return err;783}784 785struct ingenic_cgu *786ingenic_cgu_new(const struct ingenic_cgu_clk_info *clock_info,787 unsigned num_clocks, struct device_node *np)788{789 struct ingenic_cgu *cgu;790 791 cgu = kzalloc(sizeof(*cgu), GFP_KERNEL);792 if (!cgu)793 goto err_out;794 795 cgu->base = of_iomap(np, 0);796 if (!cgu->base) {797 pr_err("%s: failed to map CGU registers\n", __func__);798 goto err_out_free;799 }800 801 cgu->np = np;802 cgu->clock_info = clock_info;803 cgu->clocks.clk_num = num_clocks;804 805 spin_lock_init(&cgu->lock);806 807 return cgu;808 809err_out_free:810 kfree(cgu);811err_out:812 return NULL;813}814 815int ingenic_cgu_register_clocks(struct ingenic_cgu *cgu)816{817 unsigned i;818 int err;819 820 cgu->clocks.clks = kcalloc(cgu->clocks.clk_num, sizeof(struct clk *),821 GFP_KERNEL);822 if (!cgu->clocks.clks) {823 err = -ENOMEM;824 goto err_out;825 }826 827 for (i = 0; i < cgu->clocks.clk_num; i++) {828 err = ingenic_register_clock(cgu, i);829 if (err)830 goto err_out_unregister;831 }832 833 err = of_clk_add_provider(cgu->np, of_clk_src_onecell_get,834 &cgu->clocks);835 if (err)836 goto err_out_unregister;837 838 return 0;839 840err_out_unregister:841 for (i = 0; i < cgu->clocks.clk_num; i++) {842 if (!cgu->clocks.clks[i])843 continue;844 if (cgu->clock_info[i].type & CGU_CLK_EXT)845 clk_put(cgu->clocks.clks[i]);846 else847 clk_unregister(cgu->clocks.clks[i]);848 }849 kfree(cgu->clocks.clks);850err_out:851 return err;852}853