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