1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Toshiba Visconti PLL driver 4 * 5 * Copyright (c) 2021 TOSHIBA CORPORATION 6 * Copyright (c) 2021 Toshiba Electronic Devices & Storage Corporation 7 * 8 * Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp> 9 */ 10 11 #include <linux/bitfield.h> 12 #include <linux/clk-provider.h> 13 #include <linux/delay.h> 14 #include <linux/slab.h> 15 #include <linux/io.h> 16 17 #include "pll.h" 18 19 struct visconti_pll { 20 struct clk_hw hw; 21 void __iomem *pll_base; 22 spinlock_t *lock; 23 unsigned long flags; 24 const struct visconti_pll_rate_table *rate_table; 25 size_t rate_count; 26 struct visconti_pll_provider *ctx; 27 }; 28 29 #define PLL_CONF_REG 0x0000 30 #define PLL_CTRL_REG 0x0004 31 #define PLL_FRACMODE_REG 0x0010 32 #define PLL_INTIN_REG 0x0014 33 #define PLL_FRACIN_REG 0x0018 34 #define PLL_REFDIV_REG 0x001c 35 #define PLL_POSTDIV_REG 0x0020 36 37 #define PLL_CONFIG_SEL BIT(0) 38 #define PLL_PLLEN BIT(4) 39 #define PLL_BYPASS BIT(16) 40 #define PLL_INTIN_MASK GENMASK(11, 0) 41 #define PLL_FRACIN_MASK GENMASK(23, 0) 42 #define PLL_REFDIV_MASK GENMASK(5, 0) 43 #define PLL_POSTDIV_MASK GENMASK(2, 0) 44 45 #define PLL0_FRACMODE_DACEN BIT(4) 46 #define PLL0_FRACMODE_DSMEN BIT(0) 47 48 #define PLL_CREATE_FRACMODE(table) (table->dacen << 4 | table->dsmen) 49 #define PLL_CREATE_OSTDIV(table) (table->postdiv2 << 4 | table->postdiv1) 50 51 static inline struct visconti_pll *to_visconti_pll(struct clk_hw *hw) 52 { 53 return container_of(hw, struct visconti_pll, hw); 54 } 55 56 static void visconti_pll_get_params(struct visconti_pll *pll, 57 struct visconti_pll_rate_table *rate_table) 58 { 59 u32 postdiv, val; 60 61 val = readl(pll->pll_base + PLL_FRACMODE_REG); 62 63 rate_table->dacen = FIELD_GET(PLL0_FRACMODE_DACEN, val); 64 rate_table->dsmen = FIELD_GET(PLL0_FRACMODE_DSMEN, val); 65 66 rate_table->fracin = readl(pll->pll_base + PLL_FRACIN_REG) & PLL_FRACIN_MASK; 67 rate_table->intin = readl(pll->pll_base + PLL_INTIN_REG) & PLL_INTIN_MASK; 68 rate_table->refdiv = readl(pll->pll_base + PLL_REFDIV_REG) & PLL_REFDIV_MASK; 69 70 postdiv = readl(pll->pll_base + PLL_POSTDIV_REG); 71 rate_table->postdiv1 = postdiv & PLL_POSTDIV_MASK; 72 rate_table->postdiv2 = (postdiv >> 4) & PLL_POSTDIV_MASK; 73 } 74 75 static const struct visconti_pll_rate_table *visconti_get_pll_settings(struct visconti_pll *pll, 76 unsigned long rate) 77 { 78 const struct visconti_pll_rate_table *rate_table = pll->rate_table; 79 int i; 80 81 for (i = 0; i < pll->rate_count; i++) 82 if (rate == rate_table[i].rate) 83 return &rate_table[i]; 84 85 return NULL; 86 } 87 88 static unsigned long visconti_get_pll_rate_from_data(struct visconti_pll *pll, 89 const struct visconti_pll_rate_table *rate) 90 { 91 const struct visconti_pll_rate_table *rate_table = pll->rate_table; 92 int i; 93 94 for (i = 0; i < pll->rate_count; i++) 95 if (memcmp(&rate_table[i].dacen, &rate->dacen, 96 sizeof(*rate) - sizeof(unsigned long)) == 0) 97 return rate_table[i].rate; 98 99 /* set default */ 100 return rate_table[0].rate; 101 } 102 103 static long visconti_pll_round_rate(struct clk_hw *hw, 104 unsigned long rate, unsigned long *prate) 105 { 106 struct visconti_pll *pll = to_visconti_pll(hw); 107 const struct visconti_pll_rate_table *rate_table = pll->rate_table; 108 int i; 109 110 /* Assumming rate_table is in descending order */ 111 for (i = 0; i < pll->rate_count; i++) 112 if (rate >= rate_table[i].rate) 113 return rate_table[i].rate; 114 115 /* return minimum supported value */ 116 return rate_table[i - 1].rate; 117 } 118 119 static unsigned long visconti_pll_recalc_rate(struct clk_hw *hw, 120 unsigned long parent_rate) 121 { 122 struct visconti_pll *pll = to_visconti_pll(hw); 123 struct visconti_pll_rate_table rate_table; 124 125 memset(&rate_table, 0, sizeof(rate_table)); 126 visconti_pll_get_params(pll, &rate_table); 127 128 return visconti_get_pll_rate_from_data(pll, &rate_table); 129 } 130 131 static int visconti_pll_set_params(struct visconti_pll *pll, 132 const struct visconti_pll_rate_table *rate_table) 133 { 134 writel(PLL_CREATE_FRACMODE(rate_table), pll->pll_base + PLL_FRACMODE_REG); 135 writel(PLL_CREATE_OSTDIV(rate_table), pll->pll_base + PLL_POSTDIV_REG); 136 writel(rate_table->intin, pll->pll_base + PLL_INTIN_REG); 137 writel(rate_table->fracin, pll->pll_base + PLL_FRACIN_REG); 138 writel(rate_table->refdiv, pll->pll_base + PLL_REFDIV_REG); 139 140 return 0; 141 } 142 143 static int visconti_pll_set_rate(struct clk_hw *hw, unsigned long rate, 144 unsigned long parent_rate) 145 { 146 struct visconti_pll *pll = to_visconti_pll(hw); 147 const struct visconti_pll_rate_table *rate_table; 148 149 rate_table = visconti_get_pll_settings(pll, rate); 150 if (!rate_table) 151 return -EINVAL; 152 153 return visconti_pll_set_params(pll, rate_table); 154 } 155 156 static int visconti_pll_is_enabled(struct clk_hw *hw) 157 { 158 struct visconti_pll *pll = to_visconti_pll(hw); 159 u32 reg; 160 161 reg = readl(pll->pll_base + PLL_CTRL_REG); 162 163 return (reg & PLL_PLLEN); 164 } 165 166 static int visconti_pll_enable(struct clk_hw *hw) 167 { 168 struct visconti_pll *pll = to_visconti_pll(hw); 169 const struct visconti_pll_rate_table *rate_table = pll->rate_table; 170 unsigned long flags; 171 u32 reg; 172 173 if (visconti_pll_is_enabled(hw)) 174 return 0; 175 176 spin_lock_irqsave(pll->lock, flags); 177 178 writel(PLL_CONFIG_SEL, pll->pll_base + PLL_CONF_REG); 179 180 reg = readl(pll->pll_base + PLL_CTRL_REG); 181 reg |= PLL_BYPASS; 182 writel(reg, pll->pll_base + PLL_CTRL_REG); 183 184 visconti_pll_set_params(pll, &rate_table[0]); 185 186 reg = readl(pll->pll_base + PLL_CTRL_REG); 187 reg &= ~PLL_PLLEN; 188 writel(reg, pll->pll_base + PLL_CTRL_REG); 189 190 udelay(1); 191 192 reg = readl(pll->pll_base + PLL_CTRL_REG); 193 reg |= PLL_PLLEN; 194 writel(reg, pll->pll_base + PLL_CTRL_REG); 195 196 udelay(40); 197 198 reg = readl(pll->pll_base + PLL_CTRL_REG); 199 reg &= ~PLL_BYPASS; 200 writel(reg, pll->pll_base + PLL_CTRL_REG); 201 202 spin_unlock_irqrestore(pll->lock, flags); 203 204 return 0; 205 } 206 207 static void visconti_pll_disable(struct clk_hw *hw) 208 { 209 struct visconti_pll *pll = to_visconti_pll(hw); 210 unsigned long flags; 211 u32 reg; 212 213 if (!visconti_pll_is_enabled(hw)) 214 return; 215 216 spin_lock_irqsave(pll->lock, flags); 217 218 writel(PLL_CONFIG_SEL, pll->pll_base + PLL_CONF_REG); 219 220 reg = readl(pll->pll_base + PLL_CTRL_REG); 221 reg |= PLL_BYPASS; 222 writel(reg, pll->pll_base + PLL_CTRL_REG); 223 224 reg = readl(pll->pll_base + PLL_CTRL_REG); 225 reg &= ~PLL_PLLEN; 226 writel(reg, pll->pll_base + PLL_CTRL_REG); 227 228 spin_unlock_irqrestore(pll->lock, flags); 229 } 230 231 static const struct clk_ops visconti_pll_ops = { 232 .enable = visconti_pll_enable, 233 .disable = visconti_pll_disable, 234 .is_enabled = visconti_pll_is_enabled, 235 .round_rate = visconti_pll_round_rate, 236 .recalc_rate = visconti_pll_recalc_rate, 237 .set_rate = visconti_pll_set_rate, 238 }; 239 240 static struct clk_hw *visconti_register_pll(struct visconti_pll_provider *ctx, 241 const char *name, 242 const char *parent_name, 243 int offset, 244 const struct visconti_pll_rate_table *rate_table, 245 spinlock_t *lock) 246 { 247 struct clk_init_data init; 248 struct visconti_pll *pll; 249 struct clk_hw *pll_hw_clk; 250 size_t len; 251 int ret; 252 253 pll = kzalloc(sizeof(*pll), GFP_KERNEL); 254 if (!pll) 255 return ERR_PTR(-ENOMEM); 256 257 init.name = name; 258 init.flags = CLK_IGNORE_UNUSED; 259 init.parent_names = &parent_name; 260 init.num_parents = 1; 261 262 for (len = 0; rate_table[len].rate != 0; ) 263 len++; 264 pll->rate_count = len; 265 pll->rate_table = kmemdup(rate_table, 266 pll->rate_count * sizeof(struct visconti_pll_rate_table), 267 GFP_KERNEL); 268 WARN(!pll->rate_table, "%s: could not allocate rate table for %s\n", __func__, name); 269 270 init.ops = &visconti_pll_ops; 271 pll->hw.init = &init; 272 pll->pll_base = ctx->reg_base + offset; 273 pll->lock = lock; 274 pll->ctx = ctx; 275 276 pll_hw_clk = &pll->hw; 277 ret = clk_hw_register(NULL, &pll->hw); 278 if (ret) { 279 pr_err("failed to register pll clock %s : %d\n", name, ret); 280 kfree(pll->rate_table); 281 kfree(pll); 282 pll_hw_clk = ERR_PTR(ret); 283 } 284 285 return pll_hw_clk; 286 } 287 288 static void visconti_pll_add_lookup(struct visconti_pll_provider *ctx, 289 struct clk_hw *hw_clk, 290 unsigned int id) 291 { 292 if (id) 293 ctx->clk_data.hws[id] = hw_clk; 294 } 295 296 void __init visconti_register_plls(struct visconti_pll_provider *ctx, 297 const struct visconti_pll_info *list, 298 unsigned int nr_plls, 299 spinlock_t *lock) 300 { 301 int idx; 302 303 for (idx = 0; idx < nr_plls; idx++, list++) { 304 struct clk_hw *clk; 305 306 clk = visconti_register_pll(ctx, 307 list->name, 308 list->parent, 309 list->base_reg, 310 list->rate_table, 311 lock); 312 if (IS_ERR(clk)) { 313 pr_err("failed to register clock %s\n", list->name); 314 continue; 315 } 316 317 visconti_pll_add_lookup(ctx, clk, list->id); 318 } 319 } 320 321 struct visconti_pll_provider * __init visconti_init_pll(struct device_node *np, 322 void __iomem *base, 323 unsigned long nr_plls) 324 { 325 struct visconti_pll_provider *ctx; 326 int i; 327 328 ctx = kzalloc(struct_size(ctx, clk_data.hws, nr_plls), GFP_KERNEL); 329 if (!ctx) 330 return ERR_PTR(-ENOMEM); 331 332 ctx->node = np; 333 ctx->reg_base = base; 334 ctx->clk_data.num = nr_plls; 335 336 for (i = 0; i < nr_plls; ++i) 337 ctx->clk_data.hws[i] = ERR_PTR(-ENOENT); 338 339 return ctx; 340 } 341