root/drivers/clk/ingenic/cgu.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ingenic_cgu_gate_get
  2. ingenic_cgu_gate_set
  3. ingenic_pll_recalc_rate
  4. ingenic_pll_calc
  5. to_clk_info
  6. ingenic_pll_round_rate
  7. ingenic_pll_set_rate
  8. ingenic_pll_enable
  9. ingenic_pll_disable
  10. ingenic_pll_is_enabled
  11. ingenic_clk_get_parent
  12. ingenic_clk_set_parent
  13. ingenic_clk_recalc_rate
  14. ingenic_clk_calc_hw_div
  15. ingenic_clk_calc_div
  16. ingenic_clk_round_rate
  17. ingenic_clk_set_rate
  18. ingenic_clk_enable
  19. ingenic_clk_disable
  20. ingenic_clk_is_enabled
  21. ingenic_register_clock
  22. ingenic_cgu_new
  23. ingenic_cgu_register_clocks

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

/* [<][>][^][v][top][bottom][index][help] */