^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 Google, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #define pr_fmt(fmt) "%s: " fmt, __func__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/clk-provider.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/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/printk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "clk.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define PLL_STATUS 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define PLL_STATUS_LOCK BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define PLL_CTRL1 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define PLL_CTRL1_REFDIV_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define PLL_CTRL1_REFDIV_MASK 0x3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define PLL_CTRL1_FBDIV_SHIFT 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define PLL_CTRL1_FBDIV_MASK 0xfff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define PLL_INT_CTRL1_POSTDIV1_SHIFT 18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define PLL_INT_CTRL1_POSTDIV1_MASK 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define PLL_INT_CTRL1_POSTDIV2_SHIFT 21
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define PLL_INT_CTRL1_POSTDIV2_MASK 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define PLL_INT_CTRL1_PD BIT(24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define PLL_INT_CTRL1_DSMPD BIT(25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define PLL_INT_CTRL1_FOUTPOSTDIVPD BIT(26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define PLL_INT_CTRL1_FOUTVCOPD BIT(27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define PLL_CTRL2 0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define PLL_FRAC_CTRL2_FRAC_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define PLL_FRAC_CTRL2_FRAC_MASK 0xffffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define PLL_FRAC_CTRL2_POSTDIV1_SHIFT 24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define PLL_FRAC_CTRL2_POSTDIV1_MASK 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define PLL_FRAC_CTRL2_POSTDIV2_SHIFT 27
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define PLL_FRAC_CTRL2_POSTDIV2_MASK 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define PLL_INT_CTRL2_BYPASS BIT(28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define PLL_CTRL3 0xc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define PLL_FRAC_CTRL3_PD BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define PLL_FRAC_CTRL3_DACPD BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define PLL_FRAC_CTRL3_DSMPD BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define PLL_FRAC_CTRL3_FOUTPOSTDIVPD BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define PLL_FRAC_CTRL3_FOUT4PHASEPD BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define PLL_FRAC_CTRL3_FOUTVCOPD BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define PLL_CTRL4 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define PLL_FRAC_CTRL4_BYPASS BIT(28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define MIN_PFD 9600000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define MIN_VCO_LA 400000000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define MAX_VCO_LA 1600000000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define MIN_VCO_FRAC_INT 600000000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define MAX_VCO_FRAC_INT 1600000000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define MIN_VCO_FRAC_FRAC 600000000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define MAX_VCO_FRAC_FRAC 2400000000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define MIN_OUTPUT_LA 8000000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define MAX_OUTPUT_LA 1600000000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define MIN_OUTPUT_FRAC 12000000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define MAX_OUTPUT_FRAC 1600000000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /* Fractional PLL operating modes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) enum pll_mode {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) PLL_MODE_FRAC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) PLL_MODE_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct pistachio_clk_pll {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct clk_hw hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) struct pistachio_pll_rate_table *rates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) unsigned int nr_rates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static inline u32 pll_readl(struct pistachio_clk_pll *pll, u32 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return readl(pll->base + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static inline void pll_writel(struct pistachio_clk_pll *pll, u32 val, u32 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) writel(val, pll->base + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) static inline void pll_lock(struct pistachio_clk_pll *pll)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) while (!(pll_readl(pll, PLL_STATUS) & PLL_STATUS_LOCK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static inline u64 do_div_round_closest(u64 dividend, u64 divisor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) dividend += divisor / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return div64_u64(dividend, divisor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static inline struct pistachio_clk_pll *to_pistachio_pll(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return container_of(hw, struct pistachio_clk_pll, hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static inline enum pll_mode pll_frac_get_mode(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) val = pll_readl(pll, PLL_CTRL3) & PLL_FRAC_CTRL3_DSMPD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return val ? PLL_MODE_INT : PLL_MODE_FRAC;
^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) static inline void pll_frac_set_mode(struct clk_hw *hw, enum pll_mode mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) val = pll_readl(pll, PLL_CTRL3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (mode == PLL_MODE_INT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) val |= PLL_FRAC_CTRL3_DSMPD | PLL_FRAC_CTRL3_DACPD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) val &= ~(PLL_FRAC_CTRL3_DSMPD | PLL_FRAC_CTRL3_DACPD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) pll_writel(pll, val, PLL_CTRL3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static struct pistachio_pll_rate_table *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) pll_get_params(struct pistachio_clk_pll *pll, unsigned long fref,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) unsigned long fout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) for (i = 0; i < pll->nr_rates; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (pll->rates[i].fref == fref && pll->rates[i].fout == fout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return &pll->rates[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static long pll_round_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) unsigned long *parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) for (i = 0; i < pll->nr_rates; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (i > 0 && pll->rates[i].fref == *parent_rate &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) pll->rates[i].fout <= rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return pll->rates[i - 1].fout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) return pll->rates[0].fout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static int pll_gf40lp_frac_enable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) val = pll_readl(pll, PLL_CTRL3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) val &= ~(PLL_FRAC_CTRL3_PD | PLL_FRAC_CTRL3_FOUTPOSTDIVPD |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) PLL_FRAC_CTRL3_FOUT4PHASEPD | PLL_FRAC_CTRL3_FOUTVCOPD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) pll_writel(pll, val, PLL_CTRL3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) val = pll_readl(pll, PLL_CTRL4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) val &= ~PLL_FRAC_CTRL4_BYPASS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) pll_writel(pll, val, PLL_CTRL4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) pll_lock(pll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) static void pll_gf40lp_frac_disable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) val = pll_readl(pll, PLL_CTRL3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) val |= PLL_FRAC_CTRL3_PD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) pll_writel(pll, val, PLL_CTRL3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) static int pll_gf40lp_frac_is_enabled(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return !(pll_readl(pll, PLL_CTRL3) & PLL_FRAC_CTRL3_PD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) static int pll_gf40lp_frac_set_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct pistachio_pll_rate_table *params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) int enabled = pll_gf40lp_frac_is_enabled(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) u64 val, vco, old_postdiv1, old_postdiv2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) const char *name = clk_hw_get_name(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (rate < MIN_OUTPUT_FRAC || rate > MAX_OUTPUT_FRAC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) params = pll_get_params(pll, parent_rate, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if (!params || !params->refdiv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) /* calculate vco */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) vco = params->fref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) vco *= (params->fbdiv << 24) + params->frac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) vco = div64_u64(vco, params->refdiv << 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (vco < MIN_VCO_FRAC_FRAC || vco > MAX_VCO_FRAC_FRAC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) pr_warn("%s: VCO %llu is out of range %lu..%lu\n", name, vco,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) MIN_VCO_FRAC_FRAC, MAX_VCO_FRAC_FRAC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) val = div64_u64(params->fref, params->refdiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (val < MIN_PFD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) pr_warn("%s: PFD %llu is too low (min %lu)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) name, val, MIN_PFD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) if (val > vco / 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) pr_warn("%s: PFD %llu is too high (max %llu)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) name, val, vco / 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) val = pll_readl(pll, PLL_CTRL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) val &= ~((PLL_CTRL1_REFDIV_MASK << PLL_CTRL1_REFDIV_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) (PLL_CTRL1_FBDIV_MASK << PLL_CTRL1_FBDIV_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) val |= (params->refdiv << PLL_CTRL1_REFDIV_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) (params->fbdiv << PLL_CTRL1_FBDIV_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) pll_writel(pll, val, PLL_CTRL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) val = pll_readl(pll, PLL_CTRL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) old_postdiv1 = (val >> PLL_FRAC_CTRL2_POSTDIV1_SHIFT) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) PLL_FRAC_CTRL2_POSTDIV1_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) old_postdiv2 = (val >> PLL_FRAC_CTRL2_POSTDIV2_SHIFT) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) PLL_FRAC_CTRL2_POSTDIV2_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (enabled &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) (params->postdiv1 != old_postdiv1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) params->postdiv2 != old_postdiv2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) pr_warn("%s: changing postdiv while PLL is enabled\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (params->postdiv2 > params->postdiv1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) pr_warn("%s: postdiv2 should not exceed postdiv1\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) val &= ~((PLL_FRAC_CTRL2_FRAC_MASK << PLL_FRAC_CTRL2_FRAC_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) (PLL_FRAC_CTRL2_POSTDIV1_MASK <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) PLL_FRAC_CTRL2_POSTDIV1_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) (PLL_FRAC_CTRL2_POSTDIV2_MASK <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) PLL_FRAC_CTRL2_POSTDIV2_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) val |= (params->frac << PLL_FRAC_CTRL2_FRAC_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) (params->postdiv1 << PLL_FRAC_CTRL2_POSTDIV1_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) (params->postdiv2 << PLL_FRAC_CTRL2_POSTDIV2_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) pll_writel(pll, val, PLL_CTRL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) /* set operating mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (params->frac)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) pll_frac_set_mode(hw, PLL_MODE_FRAC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) pll_frac_set_mode(hw, PLL_MODE_INT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) pll_lock(pll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) static unsigned long pll_gf40lp_frac_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) u64 val, prediv, fbdiv, frac, postdiv1, postdiv2, rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) val = pll_readl(pll, PLL_CTRL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) prediv = (val >> PLL_CTRL1_REFDIV_SHIFT) & PLL_CTRL1_REFDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) fbdiv = (val >> PLL_CTRL1_FBDIV_SHIFT) & PLL_CTRL1_FBDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) val = pll_readl(pll, PLL_CTRL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) postdiv1 = (val >> PLL_FRAC_CTRL2_POSTDIV1_SHIFT) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) PLL_FRAC_CTRL2_POSTDIV1_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) postdiv2 = (val >> PLL_FRAC_CTRL2_POSTDIV2_SHIFT) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) PLL_FRAC_CTRL2_POSTDIV2_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) frac = (val >> PLL_FRAC_CTRL2_FRAC_SHIFT) & PLL_FRAC_CTRL2_FRAC_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /* get operating mode (int/frac) and calculate rate accordingly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) rate = parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (pll_frac_get_mode(hw) == PLL_MODE_FRAC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) rate *= (fbdiv << 24) + frac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) rate *= (fbdiv << 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) rate = do_div_round_closest(rate, (prediv * postdiv1 * postdiv2) << 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) static const struct clk_ops pll_gf40lp_frac_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) .enable = pll_gf40lp_frac_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) .disable = pll_gf40lp_frac_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) .is_enabled = pll_gf40lp_frac_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) .recalc_rate = pll_gf40lp_frac_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) .round_rate = pll_round_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) .set_rate = pll_gf40lp_frac_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) static const struct clk_ops pll_gf40lp_frac_fixed_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) .enable = pll_gf40lp_frac_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) .disable = pll_gf40lp_frac_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) .is_enabled = pll_gf40lp_frac_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) .recalc_rate = pll_gf40lp_frac_recalc_rate,
^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) static int pll_gf40lp_laint_enable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) val = pll_readl(pll, PLL_CTRL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) val &= ~(PLL_INT_CTRL1_PD |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) PLL_INT_CTRL1_FOUTPOSTDIVPD | PLL_INT_CTRL1_FOUTVCOPD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) pll_writel(pll, val, PLL_CTRL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) val = pll_readl(pll, PLL_CTRL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) val &= ~PLL_INT_CTRL2_BYPASS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) pll_writel(pll, val, PLL_CTRL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) pll_lock(pll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) static void pll_gf40lp_laint_disable(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) val = pll_readl(pll, PLL_CTRL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) val |= PLL_INT_CTRL1_PD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) pll_writel(pll, val, PLL_CTRL1);
^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) static int pll_gf40lp_laint_is_enabled(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) return !(pll_readl(pll, PLL_CTRL1) & PLL_INT_CTRL1_PD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) static int pll_gf40lp_laint_set_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) struct pistachio_pll_rate_table *params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) int enabled = pll_gf40lp_laint_is_enabled(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) u32 val, vco, old_postdiv1, old_postdiv2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) const char *name = clk_hw_get_name(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (rate < MIN_OUTPUT_LA || rate > MAX_OUTPUT_LA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) params = pll_get_params(pll, parent_rate, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (!params || !params->refdiv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) vco = div_u64(params->fref * params->fbdiv, params->refdiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (vco < MIN_VCO_LA || vco > MAX_VCO_LA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) pr_warn("%s: VCO %u is out of range %lu..%lu\n", name, vco,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) MIN_VCO_LA, MAX_VCO_LA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) val = div_u64(params->fref, params->refdiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (val < MIN_PFD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) pr_warn("%s: PFD %u is too low (min %lu)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) name, val, MIN_PFD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (val > vco / 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) pr_warn("%s: PFD %u is too high (max %u)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) name, val, vco / 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) val = pll_readl(pll, PLL_CTRL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) old_postdiv1 = (val >> PLL_INT_CTRL1_POSTDIV1_SHIFT) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) PLL_INT_CTRL1_POSTDIV1_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) old_postdiv2 = (val >> PLL_INT_CTRL1_POSTDIV2_SHIFT) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) PLL_INT_CTRL1_POSTDIV2_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (enabled &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) (params->postdiv1 != old_postdiv1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) params->postdiv2 != old_postdiv2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) pr_warn("%s: changing postdiv while PLL is enabled\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (params->postdiv2 > params->postdiv1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) pr_warn("%s: postdiv2 should not exceed postdiv1\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) val &= ~((PLL_CTRL1_REFDIV_MASK << PLL_CTRL1_REFDIV_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) (PLL_CTRL1_FBDIV_MASK << PLL_CTRL1_FBDIV_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) (PLL_INT_CTRL1_POSTDIV1_MASK << PLL_INT_CTRL1_POSTDIV1_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) (PLL_INT_CTRL1_POSTDIV2_MASK << PLL_INT_CTRL1_POSTDIV2_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) val |= (params->refdiv << PLL_CTRL1_REFDIV_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) (params->fbdiv << PLL_CTRL1_FBDIV_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) (params->postdiv1 << PLL_INT_CTRL1_POSTDIV1_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) (params->postdiv2 << PLL_INT_CTRL1_POSTDIV2_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) pll_writel(pll, val, PLL_CTRL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) pll_lock(pll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) return 0;
^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) static unsigned long pll_gf40lp_laint_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) u32 val, prediv, fbdiv, postdiv1, postdiv2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) u64 rate = parent_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) val = pll_readl(pll, PLL_CTRL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) prediv = (val >> PLL_CTRL1_REFDIV_SHIFT) & PLL_CTRL1_REFDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) fbdiv = (val >> PLL_CTRL1_FBDIV_SHIFT) & PLL_CTRL1_FBDIV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) postdiv1 = (val >> PLL_INT_CTRL1_POSTDIV1_SHIFT) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) PLL_INT_CTRL1_POSTDIV1_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) postdiv2 = (val >> PLL_INT_CTRL1_POSTDIV2_SHIFT) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) PLL_INT_CTRL1_POSTDIV2_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) rate *= fbdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) rate = do_div_round_closest(rate, prediv * postdiv1 * postdiv2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) static const struct clk_ops pll_gf40lp_laint_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) .enable = pll_gf40lp_laint_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) .disable = pll_gf40lp_laint_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) .is_enabled = pll_gf40lp_laint_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) .recalc_rate = pll_gf40lp_laint_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) .round_rate = pll_round_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) .set_rate = pll_gf40lp_laint_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) static const struct clk_ops pll_gf40lp_laint_fixed_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) .enable = pll_gf40lp_laint_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) .disable = pll_gf40lp_laint_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) .is_enabled = pll_gf40lp_laint_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) .recalc_rate = pll_gf40lp_laint_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) static struct clk *pll_register(const char *name, const char *parent_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) unsigned long flags, void __iomem *base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) enum pistachio_pll_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) struct pistachio_pll_rate_table *rates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) unsigned int nr_rates)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) struct pistachio_clk_pll *pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) struct clk_init_data init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) pll = kzalloc(sizeof(*pll), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (!pll)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) init.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) init.flags = flags | CLK_GET_RATE_NOCACHE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) init.parent_names = &parent_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) init.num_parents = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) case PLL_GF40LP_FRAC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (rates)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) init.ops = &pll_gf40lp_frac_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) init.ops = &pll_gf40lp_frac_fixed_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) case PLL_GF40LP_LAINT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (rates)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) init.ops = &pll_gf40lp_laint_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) init.ops = &pll_gf40lp_laint_fixed_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) pr_err("Unrecognized PLL type %u\n", type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) kfree(pll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) pll->hw.init = &init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) pll->base = base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) pll->rates = rates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) pll->nr_rates = nr_rates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) clk = clk_register(NULL, &pll->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (IS_ERR(clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) kfree(pll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) return clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) void pistachio_clk_register_pll(struct pistachio_clk_provider *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) struct pistachio_pll *pll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) unsigned int num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) for (i = 0; i < num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) clk = pll_register(pll[i].name, pll[i].parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 0, p->base + pll[i].reg_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) pll[i].type, pll[i].rates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) pll[i].nr_rates);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) p->clk_data.clks[pll[i].id] = clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }