1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (C) 2019 DENX Software Engineering 4 * Lukasz Majewski, DENX Software Engineering, lukma@denx.de 5 */ 6 7#include <common.h> 8#include <asm/io.h> 9#include <div64.h> 10#include <malloc.h> 11#include <clk-uclass.h> 12#include <dm/device.h> 13#include <dm/devres.h> 14#include <dm/uclass.h> 15#include <clk.h> 16#include "clk.h" 17#include <linux/err.h> 18 19#define UBOOT_DM_CLK_IMX_PLLV3_GENERIC "imx_clk_pllv3_generic" 20#define UBOOT_DM_CLK_IMX_PLLV3_SYS "imx_clk_pllv3_sys" 21#define UBOOT_DM_CLK_IMX_PLLV3_USB "imx_clk_pllv3_usb" 22#define UBOOT_DM_CLK_IMX_PLLV3_AV "imx_clk_pllv3_av" 23#define UBOOT_DM_CLK_IMX_PLLV3_ENET "imx_clk_pllv3_enet" 24#define UBOOT_DM_CLK_IMX_PLLV3_GENV2 "imx_clk_pllv3_genericv2" 25 26#define PLL_NUM_OFFSET 0x10 27#define PLL_DENOM_OFFSET 0x20 28 29#define BM_PLL_POWER (0x1 << 12) 30#define BM_PLL_POWER_V2 (0x1 << 21) 31#define BM_PLL_ENABLE (0x1 << 13) 32#define BM_PLL_LOCK (0x1 << 31) 33#define BM_PLL_LOCK_V2 (0x1 << 29) 34 35struct clk_pllv3 { 36 struct clk clk; 37 void __iomem *base; 38 u32 power_bit; 39 bool powerup_set; 40 u32 lock_bit; 41 u32 enable_bit; 42 u32 div_mask; 43 u32 div_shift; 44 unsigned long ref_clock; 45}; 46 47#define to_clk_pllv3(_clk) container_of(_clk, struct clk_pllv3, clk) 48 49static ulong clk_pllv3_genericv2_get_rate(struct clk *clk) 50{ 51 struct clk_pllv3 *pll = to_clk_pllv3(dev_get_clk_ptr(clk->dev)); 52 unsigned long parent_rate = clk_get_parent_rate(clk); 53 54 u32 div = (readl(pll->base) >> pll->div_shift) & pll->div_mask; 55 56 return (div == 0) ? parent_rate * 22 : parent_rate * 20; 57} 58 59static ulong clk_pllv3_genericv2_set_rate(struct clk *clk, ulong rate) 60{ 61 struct clk_pllv3 *pll = to_clk_pllv3(clk); 62 unsigned long parent_rate = clk_get_parent_rate(clk); 63 64 u32 div = (readl(pll->base) >> pll->div_shift) & pll->div_mask; 65 u32 val = (div == 0) ? parent_rate * 22 : parent_rate * 20; 66 67 if (rate == val) 68 return 0; 69 70 return -EINVAL; 71} 72 73static ulong clk_pllv3_generic_get_rate(struct clk *clk) 74{ 75 struct clk_pllv3 *pll = to_clk_pllv3(dev_get_clk_ptr(clk->dev)); 76 unsigned long parent_rate = clk_get_parent_rate(clk); 77 78 u32 div = (readl(pll->base) >> pll->div_shift) & pll->div_mask; 79 80 return (div == 1) ? parent_rate * 22 : parent_rate * 20; 81} 82 83static ulong clk_pllv3_generic_set_rate(struct clk *clk, ulong rate) 84{ 85 struct clk_pllv3 *pll = to_clk_pllv3(clk); 86 unsigned long parent_rate = clk_get_parent_rate(clk); 87 u32 val, div; 88 89 if (rate == parent_rate * 22) 90 div = 1; 91 else if (rate == parent_rate * 20) 92 div = 0; 93 else 94 return -EINVAL; 95 96 val = readl(pll->base); 97 val &= ~(pll->div_mask << pll->div_shift); 98 val |= (div << pll->div_shift); 99 writel(val, pll->base); 100 101 /* Wait for PLL to lock */ 102 while (!(readl(pll->base) & pll->lock_bit)) 103 ; 104 105 return 0; 106} 107 108static int clk_pllv3_generic_enable(struct clk *clk) 109{ 110 struct clk_pllv3 *pll = to_clk_pllv3(clk); 111 u32 val; 112 113 val = readl(pll->base); 114 if (pll->powerup_set) 115 val |= pll->power_bit; 116 else 117 val &= ~pll->power_bit; 118 119 val |= pll->enable_bit; 120 121 writel(val, pll->base); 122 123 return 0; 124} 125 126static int clk_pllv3_generic_disable(struct clk *clk) 127{ 128 struct clk_pllv3 *pll = to_clk_pllv3(clk); 129 u32 val; 130 131 val = readl(pll->base); 132 if (pll->powerup_set) 133 val &= ~pll->power_bit; 134 else 135 val |= pll->power_bit; 136 137 val &= ~pll->enable_bit; 138 139 writel(val, pll->base); 140 141 return 0; 142} 143 144static const struct clk_ops clk_pllv3_generic_ops = { 145 .get_rate = clk_pllv3_generic_get_rate, 146 .enable = clk_pllv3_generic_enable, 147 .disable = clk_pllv3_generic_disable, 148 .set_rate = clk_pllv3_generic_set_rate, 149}; 150 151static const struct clk_ops clk_pllv3_genericv2_ops = { 152 .get_rate = clk_pllv3_genericv2_get_rate, 153 .enable = clk_pllv3_generic_enable, 154 .disable = clk_pllv3_generic_disable, 155 .set_rate = clk_pllv3_genericv2_set_rate, 156}; 157 158static ulong clk_pllv3_sys_get_rate(struct clk *clk) 159{ 160 struct clk_pllv3 *pll = to_clk_pllv3(clk); 161 unsigned long parent_rate = clk_get_parent_rate(clk); 162 u32 div = readl(pll->base) & pll->div_mask; 163 164 return parent_rate * div / 2; 165} 166 167static ulong clk_pllv3_sys_set_rate(struct clk *clk, ulong rate) 168{ 169 struct clk_pllv3 *pll = to_clk_pllv3(clk); 170 unsigned long parent_rate = clk_get_parent_rate(clk); 171 unsigned long min_rate; 172 unsigned long max_rate; 173 u32 val, div; 174 175 if (parent_rate == 0) 176 return -EINVAL; 177 178 min_rate = parent_rate * 54 / 2; 179 max_rate = parent_rate * 108 / 2; 180 181 if (rate < min_rate || rate > max_rate) 182 return -EINVAL; 183 184 div = rate * 2 / parent_rate; 185 val = readl(pll->base); 186 val &= ~pll->div_mask; 187 val |= div; 188 writel(val, pll->base); 189 190 /* Wait for PLL to lock */ 191 while (!(readl(pll->base) & pll->lock_bit)) 192 ; 193 194 return 0; 195} 196 197static const struct clk_ops clk_pllv3_sys_ops = { 198 .enable = clk_pllv3_generic_enable, 199 .disable = clk_pllv3_generic_disable, 200 .get_rate = clk_pllv3_sys_get_rate, 201 .set_rate = clk_pllv3_sys_set_rate, 202}; 203 204static ulong clk_pllv3_av_get_rate(struct clk *clk) 205{ 206 struct clk_pllv3 *pll = to_clk_pllv3(clk); 207 unsigned long parent_rate = clk_get_parent_rate(clk); 208 u32 mfn = readl(pll->base + PLL_NUM_OFFSET); 209 u32 mfd = readl(pll->base + PLL_DENOM_OFFSET); 210 u32 div = readl(pll->base) & pll->div_mask; 211 u64 temp64 = (u64)parent_rate; 212 213 if (mfd == 0) 214 return -EIO; 215 216 temp64 *= mfn; 217 do_div(temp64, mfd); 218 219 return parent_rate * div + (unsigned long)temp64; 220} 221 222static ulong clk_pllv3_av_set_rate(struct clk *clk, ulong rate) 223{ 224 struct clk_pllv3 *pll = to_clk_pllv3(clk); 225 unsigned long parent_rate = clk_get_parent_rate(clk); 226 unsigned long min_rate; 227 unsigned long max_rate; 228 u32 val, div; 229 u32 mfn, mfd = 1000000; 230 u32 max_mfd = 0x3FFFFFFF; 231 u64 temp64; 232 233 if (parent_rate == 0) 234 return -EINVAL; 235 236 min_rate = parent_rate * 27; 237 max_rate = parent_rate * 54; 238 239 if (rate < min_rate || rate > max_rate) 240 return -EINVAL; 241 242 if (parent_rate <= max_mfd) 243 mfd = parent_rate; 244 245 div = rate / parent_rate; 246 temp64 = (u64)(rate - div * parent_rate); 247 temp64 *= mfd; 248 do_div(temp64, parent_rate); 249 mfn = temp64; 250 251 val = readl(pll->base); 252 val &= ~pll->div_mask; 253 val |= div; 254 writel(val, pll->base); 255 writel(mfn, pll->base + PLL_NUM_OFFSET); 256 writel(mfd, pll->base + PLL_DENOM_OFFSET); 257 258 /* Wait for PLL to lock */ 259 while (!(readl(pll->base) & pll->lock_bit)) 260 ; 261 262 return 0; 263} 264 265static const struct clk_ops clk_pllv3_av_ops = { 266 .enable = clk_pllv3_generic_enable, 267 .disable = clk_pllv3_generic_disable, 268 .get_rate = clk_pllv3_av_get_rate, 269 .set_rate = clk_pllv3_av_set_rate, 270}; 271 272static ulong clk_pllv3_enet_get_rate(struct clk *clk) 273{ 274 struct clk_pllv3 *pll = to_clk_pllv3(clk); 275 276 return pll->ref_clock; 277} 278 279static const struct clk_ops clk_pllv3_enet_ops = { 280 .enable = clk_pllv3_generic_enable, 281 .disable = clk_pllv3_generic_disable, 282 .get_rate = clk_pllv3_enet_get_rate, 283}; 284 285struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name, 286 const char *parent_name, void __iomem *base, 287 u32 div_mask) 288{ 289 struct clk_pllv3 *pll; 290 struct clk *clk; 291 char *drv_name; 292 int ret; 293 294 pll = kzalloc(sizeof(*pll), GFP_KERNEL); 295 if (!pll) 296 return ERR_PTR(-ENOMEM); 297 298 pll->power_bit = BM_PLL_POWER; 299 pll->enable_bit = BM_PLL_ENABLE; 300 pll->lock_bit = BM_PLL_LOCK; 301 302 switch (type) { 303 case IMX_PLLV3_GENERIC: 304 drv_name = UBOOT_DM_CLK_IMX_PLLV3_GENERIC; 305 pll->div_shift = 0; 306 pll->powerup_set = false; 307 break; 308 case IMX_PLLV3_GENERICV2: 309 pll->power_bit = BM_PLL_POWER_V2; 310 pll->lock_bit = BM_PLL_LOCK_V2; 311 drv_name = UBOOT_DM_CLK_IMX_PLLV3_GENV2; 312 pll->div_shift = 0; 313 pll->powerup_set = false; 314 break; 315 case IMX_PLLV3_SYS: 316 drv_name = UBOOT_DM_CLK_IMX_PLLV3_SYS; 317 pll->div_shift = 0; 318 pll->powerup_set = false; 319 break; 320 case IMX_PLLV3_USB: 321 drv_name = UBOOT_DM_CLK_IMX_PLLV3_USB; 322 pll->div_shift = 1; 323 pll->powerup_set = true; 324 break; 325 case IMX_PLLV3_AV: 326 drv_name = UBOOT_DM_CLK_IMX_PLLV3_AV; 327 pll->div_shift = 0; 328 pll->powerup_set = false; 329 break; 330 case IMX_PLLV3_ENET: 331 drv_name = UBOOT_DM_CLK_IMX_PLLV3_ENET; 332 pll->ref_clock = 500000000; 333 break; 334 default: 335 kfree(pll); 336 return ERR_PTR(-EINVAL); 337 } 338 339 pll->base = base; 340 pll->div_mask = div_mask; 341 clk = &pll->clk; 342 343 ret = clk_register(clk, drv_name, name, parent_name); 344 if (ret) { 345 kfree(pll); 346 return ERR_PTR(ret); 347 } 348 349 return clk; 350} 351 352U_BOOT_DRIVER(clk_pllv3_generic) = { 353 .name = UBOOT_DM_CLK_IMX_PLLV3_GENERIC, 354 .id = UCLASS_CLK, 355 .ops = &clk_pllv3_generic_ops, 356 .flags = DM_FLAG_PRE_RELOC, 357}; 358 359U_BOOT_DRIVER(clk_pllv3_genericv2) = { 360 .name = UBOOT_DM_CLK_IMX_PLLV3_GENV2, 361 .id = UCLASS_CLK, 362 .ops = &clk_pllv3_genericv2_ops, 363 .flags = DM_FLAG_PRE_RELOC, 364}; 365 366U_BOOT_DRIVER(clk_pllv3_sys) = { 367 .name = UBOOT_DM_CLK_IMX_PLLV3_SYS, 368 .id = UCLASS_CLK, 369 .ops = &clk_pllv3_sys_ops, 370 .flags = DM_FLAG_PRE_RELOC, 371}; 372 373U_BOOT_DRIVER(clk_pllv3_usb) = { 374 .name = UBOOT_DM_CLK_IMX_PLLV3_USB, 375 .id = UCLASS_CLK, 376 .ops = &clk_pllv3_generic_ops, 377 .flags = DM_FLAG_PRE_RELOC, 378}; 379 380U_BOOT_DRIVER(clk_pllv3_av) = { 381 .name = UBOOT_DM_CLK_IMX_PLLV3_AV, 382 .id = UCLASS_CLK, 383 .ops = &clk_pllv3_av_ops, 384 .flags = DM_FLAG_PRE_RELOC, 385}; 386 387U_BOOT_DRIVER(clk_pllv3_enet) = { 388 .name = UBOOT_DM_CLK_IMX_PLLV3_ENET, 389 .id = UCLASS_CLK, 390 .ops = &clk_pllv3_enet_ops, 391}; 392