^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2014 MediaTek Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Author: James Liao <jamesjj.liao@mediatek.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/clkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "clk-mtk.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define REG_CON0 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define REG_CON1 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define CON0_BASE_EN BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define CON0_PWR_ON BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define CON0_ISO_EN BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define PCW_CHG_MASK BIT(31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define AUDPLL_TUNER_EN BIT(31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define POSTDIV_MASK 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /* default 7 bits integer, can be overridden with pcwibits. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define INTEGER_BITS 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * MediaTek PLLs are configured through their pcw value. The pcw value describes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * a divider in the PLL feedback loop which consists of 7 bits for the integer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * part and the remaining bits (if present) for the fractional part. Also they
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * have a 3 bit power-of-two post divider.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct mtk_clk_pll {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct clk_hw hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) void __iomem *base_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) void __iomem *pd_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) void __iomem *pwr_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) void __iomem *tuner_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) void __iomem *tuner_en_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) void __iomem *pcw_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) void __iomem *pcw_chg_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) const struct mtk_pll_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static inline struct mtk_clk_pll *to_mtk_clk_pll(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) return container_of(hw, struct mtk_clk_pll, hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static int mtk_pll_is_prepared(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) return (readl(pll->base_addr + REG_CON0) & CON0_BASE_EN) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static unsigned long __mtk_pll_recalc_rate(struct mtk_clk_pll *pll, u32 fin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) u32 pcw, int postdiv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) int pcwbits = pll->data->pcwbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) int pcwfbits = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) int ibits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) u64 vco;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) u8 c = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /* The fractional part of the PLL divider. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) ibits = pll->data->pcwibits ? pll->data->pcwibits : INTEGER_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (pcwbits > ibits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) pcwfbits = pcwbits - ibits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) vco = (u64)fin * pcw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if (pcwfbits && (vco & GENMASK(pcwfbits - 1, 0)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) c = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) vco >>= pcwfbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) vco++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) return ((unsigned long)vco + postdiv - 1) / postdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static void __mtk_pll_tuner_enable(struct mtk_clk_pll *pll)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) u32 r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (pll->tuner_en_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) r = readl(pll->tuner_en_addr) | BIT(pll->data->tuner_en_bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) writel(r, pll->tuner_en_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) } else if (pll->tuner_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) r = readl(pll->tuner_addr) | AUDPLL_TUNER_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) writel(r, pll->tuner_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static void __mtk_pll_tuner_disable(struct mtk_clk_pll *pll)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) u32 r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (pll->tuner_en_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) r = readl(pll->tuner_en_addr) & ~BIT(pll->data->tuner_en_bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) writel(r, pll->tuner_en_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) } else if (pll->tuner_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) r = readl(pll->tuner_addr) & ~AUDPLL_TUNER_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) writel(r, pll->tuner_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static void mtk_pll_set_rate_regs(struct mtk_clk_pll *pll, u32 pcw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) int postdiv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) u32 chg, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /* disable tuner */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) __mtk_pll_tuner_disable(pll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /* set postdiv */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) val = readl(pll->pd_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) val &= ~(POSTDIV_MASK << pll->data->pd_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) val |= (ffs(postdiv) - 1) << pll->data->pd_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /* postdiv and pcw need to set at the same time if on same register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) if (pll->pd_addr != pll->pcw_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) writel(val, pll->pd_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) val = readl(pll->pcw_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) /* set pcw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) val &= ~GENMASK(pll->data->pcw_shift + pll->data->pcwbits - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) pll->data->pcw_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) val |= pcw << pll->data->pcw_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) writel(val, pll->pcw_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) chg = readl(pll->pcw_chg_addr) | PCW_CHG_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) writel(chg, pll->pcw_chg_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (pll->tuner_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) writel(val + 1, pll->tuner_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /* restore tuner_en */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) __mtk_pll_tuner_enable(pll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) udelay(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * mtk_pll_calc_values - calculate good values for a given input frequency.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * @pll: The pll
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * @pcw: The pcw value (output)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * @postdiv: The post divider (output)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * @freq: The desired target frequency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * @fin: The input frequency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) static void mtk_pll_calc_values(struct mtk_clk_pll *pll, u32 *pcw, u32 *postdiv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) u32 freq, u32 fin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) unsigned long fmin = pll->data->fmin ? pll->data->fmin : (1000 * MHZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) const struct mtk_pll_div_table *div_table = pll->data->div_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) u64 _pcw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) int ibits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (freq > pll->data->fmax)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) freq = pll->data->fmax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (div_table) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (freq > div_table[0].freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) freq = div_table[0].freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) for (val = 0; div_table[val + 1].freq != 0; val++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) if (freq > div_table[val + 1].freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) *postdiv = 1 << val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) for (val = 0; val < 5; val++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) *postdiv = 1 << val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if ((u64)freq * *postdiv >= fmin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /* _pcw = freq * postdiv / fin * 2^pcwfbits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) ibits = pll->data->pcwibits ? pll->data->pcwibits : INTEGER_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) _pcw = ((u64)freq << val) << (pll->data->pcwbits - ibits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) do_div(_pcw, fin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) *pcw = (u32)_pcw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) static int mtk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) u32 pcw = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) u32 postdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) mtk_pll_calc_values(pll, &pcw, &postdiv, rate, parent_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) mtk_pll_set_rate_regs(pll, pcw, postdiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) static unsigned long mtk_pll_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) u32 postdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) u32 pcw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) postdiv = (readl(pll->pd_addr) >> pll->data->pd_shift) & POSTDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) postdiv = 1 << postdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) pcw = readl(pll->pcw_addr) >> pll->data->pcw_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) pcw &= GENMASK(pll->data->pcwbits - 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return __mtk_pll_recalc_rate(pll, parent_rate, pcw, postdiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) static long mtk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) unsigned long *prate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) u32 pcw = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) int postdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) mtk_pll_calc_values(pll, &pcw, &postdiv, rate, *prate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) return __mtk_pll_recalc_rate(pll, *prate, pcw, postdiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static int mtk_pll_prepare(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) u32 r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) r = readl(pll->pwr_addr) | CON0_PWR_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) writel(r, pll->pwr_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) r = readl(pll->pwr_addr) & ~CON0_ISO_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) writel(r, pll->pwr_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) r = readl(pll->base_addr + REG_CON0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) r |= pll->data->en_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) writel(r, pll->base_addr + REG_CON0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) __mtk_pll_tuner_enable(pll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) udelay(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (pll->data->flags & HAVE_RST_BAR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) r = readl(pll->base_addr + REG_CON0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) r |= pll->data->rst_bar_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) writel(r, pll->base_addr + REG_CON0);
^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) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) static void mtk_pll_unprepare(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) u32 r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (pll->data->flags & HAVE_RST_BAR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) r = readl(pll->base_addr + REG_CON0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) r &= ~pll->data->rst_bar_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) writel(r, pll->base_addr + REG_CON0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) __mtk_pll_tuner_disable(pll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) r = readl(pll->base_addr + REG_CON0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) r &= ~CON0_BASE_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) writel(r, pll->base_addr + REG_CON0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) r = readl(pll->pwr_addr) | CON0_ISO_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) writel(r, pll->pwr_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) r = readl(pll->pwr_addr) & ~CON0_PWR_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) writel(r, pll->pwr_addr);
^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 const struct clk_ops mtk_pll_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) .is_prepared = mtk_pll_is_prepared,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) .prepare = mtk_pll_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) .unprepare = mtk_pll_unprepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) .recalc_rate = mtk_pll_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) .round_rate = mtk_pll_round_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) .set_rate = mtk_pll_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) static struct clk *mtk_clk_register_pll(const struct mtk_pll_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) void __iomem *base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) struct mtk_clk_pll *pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) struct clk_init_data init = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) const char *parent_name = "clk26m";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) pll = kzalloc(sizeof(*pll), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if (!pll)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) pll->base_addr = base + data->reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) pll->pwr_addr = base + data->pwr_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) pll->pd_addr = base + data->pd_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) pll->pcw_addr = base + data->pcw_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (data->pcw_chg_reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) pll->pcw_chg_addr = base + data->pcw_chg_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) pll->pcw_chg_addr = pll->base_addr + REG_CON1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (data->tuner_reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) pll->tuner_addr = base + data->tuner_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (data->tuner_en_reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) pll->tuner_en_addr = base + data->tuner_en_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) pll->hw.init = &init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) pll->data = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) init.name = data->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) init.flags = (data->flags & PLL_AO) ? CLK_IS_CRITICAL : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) init.ops = &mtk_pll_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (data->parent_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) init.parent_names = &data->parent_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) init.parent_names = &parent_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) init.num_parents = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) clk = clk_register(NULL, &pll->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (IS_ERR(clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) kfree(pll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) return clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) void mtk_clk_register_plls(struct device_node *node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) const struct mtk_pll_data *plls, int num_plls, struct clk_onecell_data *clk_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) base = of_iomap(node, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (!base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) pr_err("%s(): ioremap failed\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) for (i = 0; i < num_plls; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) const struct mtk_pll_data *pll = &plls[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) clk = mtk_clk_register_pll(pll, base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) if (IS_ERR(clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) pr_err("Failed to register clk %s: %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) pll->name, PTR_ERR(clk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) clk_data->clks[pll->id] = clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }