1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * PLL clock driver for the Mobileye EyeQ5, EyeQ6L and EyeQ6H platforms. 4 * 5 * This controller handles: 6 * - Read-only PLLs, all derived from the same main crystal clock. 7 * - It also exposes divider clocks, those are children to PLLs. 8 * - Fixed factor clocks, children to PLLs. 9 * 10 * Parent clock is expected to be constant. This driver's registers live in a 11 * shared region called OLB. Some PLLs and fixed-factors are initialised early 12 * by of_clk_init(); if so, two clk providers are registered. 13 * 14 * We use eqc_ as prefix, as-in "EyeQ Clock", but way shorter. 15 * 16 * Copyright (C) 2024 Mobileye Vision Technologies Ltd. 17 */ 18 19 /* 20 * Set pr_fmt() for printing from eqc_early_init(). 21 * It is called at of_clk_init() stage (read: really early). 22 */ 23 #define pr_fmt(fmt) "clk-eyeq: " fmt 24 25 #include <linux/array_size.h> 26 #include <linux/auxiliary_bus.h> 27 #include <linux/bitfield.h> 28 #include <linux/bits.h> 29 #include <linux/clk-provider.h> 30 #include <linux/device.h> 31 #include <linux/err.h> 32 #include <linux/errno.h> 33 #include <linux/init.h> 34 #include <linux/io-64-nonatomic-hi-lo.h> 35 #include <linux/io.h> 36 #include <linux/mod_devicetable.h> 37 #include <linux/module.h> 38 #include <linux/of.h> 39 #include <linux/of_address.h> 40 #include <linux/overflow.h> 41 #include <linux/platform_device.h> 42 #include <linux/printk.h> 43 #include <linux/slab.h> 44 #include <linux/spinlock.h> 45 #include <linux/types.h> 46 47 #include <dt-bindings/clock/mobileye,eyeq5-clk.h> 48 #include <dt-bindings/clock/mobileye,eyeq6lplus-clk.h> 49 50 /* In frac mode, it enables fractional noise canceling DAC. Else, no function. */ 51 #define PCSR0_DAC_EN BIT(0) 52 /* Fractional or integer mode */ 53 #define PCSR0_DSM_EN BIT(1) 54 #define PCSR0_PLL_EN BIT(2) 55 /* All clocks output held at 0 */ 56 #define PCSR0_FOUTPOSTDIV_EN BIT(3) 57 #define PCSR0_POST_DIV1 GENMASK(6, 4) 58 #define PCSR0_POST_DIV2 GENMASK(9, 7) 59 #define PCSR0_REF_DIV GENMASK(15, 10) 60 #define PCSR0_INTIN GENMASK(27, 16) 61 #define PCSR0_BYPASS BIT(28) 62 /* Bits 30..29 are reserved */ 63 #define PCSR0_PLL_LOCKED BIT(31) 64 65 #define PCSR1_RESET BIT(0) 66 #define PCSR1_SSGC_DIV GENMASK(4, 1) 67 /* Spread amplitude (% = 0.1 * SPREAD[4:0]) */ 68 #define PCSR1_SPREAD GENMASK(9, 5) 69 #define PCSR1_DIS_SSCG BIT(10) 70 /* Down-spread or center-spread */ 71 #define PCSR1_DOWN_SPREAD BIT(11) 72 #define PCSR1_FRAC_IN GENMASK(31, 12) 73 74 struct eqc_pll { 75 unsigned int index; 76 const char *name; 77 unsigned int reg64; 78 }; 79 80 /* 81 * Divider clock. Divider is 2*(v+1), with v the register value. 82 * Min divider is 2, max is 2*(2^width). 83 */ 84 struct eqc_div { 85 unsigned int index; 86 const char *name; 87 unsigned int parent; 88 unsigned int reg; 89 u8 shift; 90 u8 width; 91 }; 92 93 struct eqc_fixed_factor { 94 unsigned int index; 95 const char *name; 96 unsigned int mult; 97 unsigned int div; 98 unsigned int parent; 99 }; 100 101 struct eqc_match_data { 102 unsigned int pll_count; 103 const struct eqc_pll *plls; 104 105 unsigned int div_count; 106 const struct eqc_div *divs; 107 108 unsigned int fixed_factor_count; 109 const struct eqc_fixed_factor *fixed_factors; 110 111 const char *reset_auxdev_name; 112 const char *pinctrl_auxdev_name; 113 const char *eth_phy_auxdev_name; 114 115 unsigned int early_clk_count; 116 }; 117 118 struct eqc_early_match_data { 119 unsigned int early_pll_count; 120 const struct eqc_pll *early_plls; 121 122 unsigned int early_fixed_factor_count; 123 const struct eqc_fixed_factor *early_fixed_factors; 124 125 /* 126 * We want our of_xlate callback to EPROBE_DEFER instead of dev_err() 127 * and EINVAL. For that, we must know the total clock count. 128 */ 129 unsigned int late_clk_count; 130 }; 131 132 /* 133 * Both factors (mult and div) must fit in 32 bits. When an operation overflows, 134 * this function throws away low bits so that factors still fit in 32 bits. 135 * 136 * Precision loss depends on amplitude of mult and div. Worst theoretical 137 * loss is: (UINT_MAX+1) / UINT_MAX - 1 = 2.3e-10. 138 * This is 1Hz every 4.3GHz. 139 */ 140 static void eqc_pll_downshift_factors(unsigned long *mult, unsigned long *div) 141 { 142 unsigned long biggest; 143 unsigned int shift; 144 145 /* This function can be removed if mult/div switch to unsigned long. */ 146 static_assert(sizeof_field(struct clk_fixed_factor, mult) == sizeof(unsigned int)); 147 static_assert(sizeof_field(struct clk_fixed_factor, div) == sizeof(unsigned int)); 148 149 /* No overflow, nothing to be done. */ 150 if (*mult <= UINT_MAX && *div <= UINT_MAX) 151 return; 152 153 /* 154 * Compute the shift required to bring the biggest factor into unsigned 155 * int range. That is, shift its highest set bit to the unsigned int 156 * most significant bit. 157 */ 158 biggest = max(*mult, *div); 159 shift = __fls(biggest) - (BITS_PER_BYTE * sizeof(unsigned int)) + 1; 160 161 *mult >>= shift; 162 *div >>= shift; 163 } 164 165 static int eqc_pll_parse_registers(u32 r0, u32 r1, unsigned long *mult, 166 unsigned long *div, unsigned long *acc) 167 { 168 unsigned long spread; 169 170 if (r0 & PCSR0_BYPASS) { 171 *mult = 1; 172 *div = 1; 173 *acc = 0; 174 return 0; 175 } 176 177 if (!(r0 & PCSR0_PLL_LOCKED)) 178 return -EINVAL; 179 180 *mult = FIELD_GET(PCSR0_INTIN, r0); 181 *div = FIELD_GET(PCSR0_REF_DIV, r0); 182 183 /* Fractional mode, in 2^20 (0x100000) parts. */ 184 if (r0 & PCSR0_DSM_EN) { 185 *div *= (1ULL << 20); 186 *mult = *mult * (1ULL << 20) + FIELD_GET(PCSR1_FRAC_IN, r1); 187 } 188 189 if (!*mult || !*div) 190 return -EINVAL; 191 192 if (r1 & (PCSR1_RESET | PCSR1_DIS_SSCG)) { 193 *acc = 0; 194 return 0; 195 } 196 197 /* 198 * Spread spectrum. 199 * 200 * Spread is in 1/1024 parts of frequency. Clock accuracy 201 * is half the spread value expressed in parts per billion. 202 * 203 * accuracy = (spread * 1e9) / (1024 * 2) 204 * 205 * Care is taken to avoid overflowing or losing precision. 206 */ 207 spread = FIELD_GET(PCSR1_SPREAD, r1); 208 *acc = DIV_ROUND_CLOSEST(spread * 1000000000, 1024 * 2); 209 210 if (r1 & PCSR1_DOWN_SPREAD) { 211 /* 212 * Downspreading: the central frequency is half a 213 * spread lower. 214 */ 215 *mult *= 2048 - spread; 216 *div *= 2048; 217 218 /* 219 * Previous operation might overflow 32 bits. If it 220 * does, throw away the least amount of low bits. 221 */ 222 eqc_pll_downshift_factors(mult, div); 223 } 224 225 return 0; 226 } 227 228 static void eqc_probe_init_plls(struct device *dev, const struct eqc_match_data *data, 229 void __iomem *base, struct clk_hw_onecell_data *cells) 230 { 231 unsigned long mult, div, acc; 232 const struct eqc_pll *pll; 233 struct clk_hw *hw; 234 unsigned int i; 235 u32 r0, r1; 236 u64 val; 237 int ret; 238 239 for (i = 0; i < data->pll_count; i++) { 240 pll = &data->plls[i]; 241 242 val = readq(base + pll->reg64); 243 r0 = val; 244 r1 = val >> 32; 245 246 ret = eqc_pll_parse_registers(r0, r1, &mult, &div, &acc); 247 if (ret) { 248 dev_warn(dev, "failed parsing state of %s\n", pll->name); 249 cells->hws[pll->index] = ERR_PTR(ret); 250 continue; 251 } 252 253 hw = clk_hw_register_fixed_factor_with_accuracy_fwname(dev, 254 dev->of_node, pll->name, "ref", 0, mult, div, acc); 255 cells->hws[pll->index] = hw; 256 if (IS_ERR(hw)) 257 dev_warn(dev, "failed registering %s: %pe\n", pll->name, hw); 258 } 259 } 260 261 static void eqc_probe_init_divs(struct device *dev, const struct eqc_match_data *data, 262 void __iomem *base, struct clk_hw_onecell_data *cells) 263 { 264 struct clk_parent_data parent_data = { }; 265 const struct eqc_div *div; 266 struct clk_hw *parent; 267 void __iomem *reg; 268 struct clk_hw *hw; 269 unsigned int i; 270 271 for (i = 0; i < data->div_count; i++) { 272 div = &data->divs[i]; 273 reg = base + div->reg; 274 parent = cells->hws[div->parent]; 275 276 if (IS_ERR(parent)) { 277 /* Parent is in early clk provider. */ 278 parent_data.index = div->parent; 279 parent_data.hw = NULL; 280 } else { 281 /* Avoid clock lookup when we already have the hw reference. */ 282 parent_data.index = 0; 283 parent_data.hw = parent; 284 } 285 286 hw = clk_hw_register_divider_table_parent_data(dev, div->name, 287 &parent_data, 0, reg, div->shift, div->width, 288 CLK_DIVIDER_EVEN_INTEGERS, NULL, NULL); 289 cells->hws[div->index] = hw; 290 if (IS_ERR(hw)) 291 dev_warn(dev, "failed registering %s: %pe\n", 292 div->name, hw); 293 } 294 } 295 296 static void eqc_probe_init_fixed_factors(struct device *dev, 297 const struct eqc_match_data *data, 298 struct clk_hw_onecell_data *cells) 299 { 300 const struct eqc_fixed_factor *ff; 301 struct clk_hw *hw, *parent_hw; 302 unsigned int i; 303 304 for (i = 0; i < data->fixed_factor_count; i++) { 305 ff = &data->fixed_factors[i]; 306 parent_hw = cells->hws[ff->parent]; 307 308 if (IS_ERR(parent_hw)) { 309 /* Parent is in early clk provider. */ 310 hw = clk_hw_register_fixed_factor_index(dev, ff->name, 311 ff->parent, 0, ff->mult, ff->div); 312 } else { 313 /* Avoid clock lookup when we already have the hw reference. */ 314 hw = clk_hw_register_fixed_factor_parent_hw(dev, ff->name, 315 parent_hw, 0, ff->mult, ff->div); 316 } 317 318 cells->hws[ff->index] = hw; 319 if (IS_ERR(hw)) 320 dev_warn(dev, "failed registering %s: %pe\n", 321 ff->name, hw); 322 } 323 } 324 325 static void eqc_auxdev_create_optional(struct device *dev, void __iomem *base, 326 const char *name) 327 { 328 struct auxiliary_device *adev; 329 330 if (name) { 331 adev = devm_auxiliary_device_create(dev, name, 332 (void __force *)base); 333 if (!adev) 334 dev_warn(dev, "failed creating auxiliary device %s.%s\n", 335 KBUILD_MODNAME, name); 336 } 337 } 338 339 static int eqc_probe(struct platform_device *pdev) 340 { 341 struct device *dev = &pdev->dev; 342 struct device_node *np = dev->of_node; 343 const struct eqc_match_data *data; 344 struct clk_hw_onecell_data *cells; 345 unsigned int i, clk_count; 346 struct resource *res; 347 void __iomem *base; 348 349 data = device_get_match_data(dev); 350 if (!data) 351 return 0; /* No clocks nor auxdevs, we are done. */ 352 353 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 354 if (!res) 355 return -ENODEV; 356 357 base = ioremap(res->start, resource_size(res)); 358 if (!base) 359 return -ENOMEM; 360 361 /* Init optional auxiliary devices. */ 362 eqc_auxdev_create_optional(dev, base, data->reset_auxdev_name); 363 eqc_auxdev_create_optional(dev, base, data->pinctrl_auxdev_name); 364 eqc_auxdev_create_optional(dev, base, data->eth_phy_auxdev_name); 365 366 if (data->pll_count + data->div_count + data->fixed_factor_count == 0) 367 return 0; /* Zero clocks, we are done. */ 368 369 clk_count = data->pll_count + data->div_count + 370 data->fixed_factor_count + data->early_clk_count; 371 cells = kzalloc_flex(*cells, hws, clk_count); 372 if (!cells) 373 return -ENOMEM; 374 375 cells->num = clk_count; 376 377 /* Early PLLs are marked as errors: the early provider will get queried. */ 378 for (i = 0; i < clk_count; i++) 379 cells->hws[i] = ERR_PTR(-EINVAL); 380 381 eqc_probe_init_plls(dev, data, base, cells); 382 383 eqc_probe_init_divs(dev, data, base, cells); 384 385 eqc_probe_init_fixed_factors(dev, data, cells); 386 387 return of_clk_add_hw_provider(np, of_clk_hw_onecell_get, cells); 388 } 389 390 /* Required early for GIC timer (pll-cpu) and UARTs (pll-per). */ 391 static const struct eqc_pll eqc_eyeq5_early_plls[] = { 392 { .index = EQ5C_PLL_CPU, .name = "pll-cpu", .reg64 = 0x02C }, 393 { .index = EQ5C_PLL_PER, .name = "pll-per", .reg64 = 0x05C }, 394 }; 395 396 static const struct eqc_pll eqc_eyeq5_plls[] = { 397 { .index = EQ5C_PLL_VMP, .name = "pll-vmp", .reg64 = 0x034 }, 398 { .index = EQ5C_PLL_PMA, .name = "pll-pma", .reg64 = 0x03C }, 399 { .index = EQ5C_PLL_VDI, .name = "pll-vdi", .reg64 = 0x044 }, 400 { .index = EQ5C_PLL_DDR0, .name = "pll-ddr0", .reg64 = 0x04C }, 401 { .index = EQ5C_PLL_PCI, .name = "pll-pci", .reg64 = 0x054 }, 402 { .index = EQ5C_PLL_PMAC, .name = "pll-pmac", .reg64 = 0x064 }, 403 { .index = EQ5C_PLL_MPC, .name = "pll-mpc", .reg64 = 0x06C }, 404 { .index = EQ5C_PLL_DDR1, .name = "pll-ddr1", .reg64 = 0x074 }, 405 }; 406 407 enum { 408 /* 409 * EQ5C_PLL_CPU children. 410 * EQ5C_PER_OCC_PCI is the last clock exposed in dt-bindings. 411 */ 412 EQ5C_CPU_OCC = EQ5C_PER_OCC_PCI + 1, 413 EQ5C_CPU_SI_CSS0, 414 EQ5C_CPU_CPC, 415 EQ5C_CPU_CM, 416 EQ5C_CPU_MEM, 417 EQ5C_CPU_OCC_ISRAM, 418 EQ5C_CPU_ISRAM, 419 EQ5C_CPU_OCC_DBU, 420 EQ5C_CPU_SI_DBU_TP, 421 422 /* 423 * EQ5C_PLL_VDI children. 424 */ 425 EQ5C_VDI_OCC_VDI, 426 EQ5C_VDI_VDI, 427 EQ5C_VDI_OCC_CAN_SER, 428 EQ5C_VDI_CAN_SER, 429 EQ5C_VDI_I2C_SER, 430 431 /* 432 * EQ5C_PLL_PER children. 433 */ 434 EQ5C_PER_PERIPH, 435 EQ5C_PER_CAN, 436 EQ5C_PER_TIMER, 437 EQ5C_PER_CCF, 438 EQ5C_PER_OCC_MJPEG, 439 EQ5C_PER_HSM, 440 EQ5C_PER_MJPEG, 441 EQ5C_PER_FCMU_A, 442 }; 443 444 static const struct eqc_fixed_factor eqc_eyeq5_early_fixed_factors[] = { 445 /* EQ5C_PLL_CPU children */ 446 { EQ5C_CPU_OCC, "occ-cpu", 1, 1, EQ5C_PLL_CPU }, 447 { EQ5C_CPU_SI_CSS0, "si-css0", 1, 1, EQ5C_CPU_OCC }, 448 { EQ5C_CPU_CORE0, "core0", 1, 1, EQ5C_CPU_SI_CSS0 }, 449 { EQ5C_CPU_CORE1, "core1", 1, 1, EQ5C_CPU_SI_CSS0 }, 450 { EQ5C_CPU_CORE2, "core2", 1, 1, EQ5C_CPU_SI_CSS0 }, 451 { EQ5C_CPU_CORE3, "core3", 1, 1, EQ5C_CPU_SI_CSS0 }, 452 453 /* EQ5C_PLL_PER children */ 454 { EQ5C_PER_OCC, "occ-periph", 1, 16, EQ5C_PLL_PER }, 455 { EQ5C_PER_UART, "uart", 1, 1, EQ5C_PER_OCC }, 456 }; 457 458 static const struct eqc_fixed_factor eqc_eyeq5_fixed_factors[] = { 459 /* EQ5C_PLL_CPU children */ 460 { EQ5C_CPU_CPC, "cpc", 1, 1, EQ5C_CPU_SI_CSS0 }, 461 { EQ5C_CPU_CM, "cm", 1, 1, EQ5C_CPU_SI_CSS0 }, 462 { EQ5C_CPU_MEM, "mem", 1, 1, EQ5C_CPU_SI_CSS0 }, 463 { EQ5C_CPU_OCC_ISRAM, "occ-isram", 1, 2, EQ5C_PLL_CPU }, 464 { EQ5C_CPU_ISRAM, "isram", 1, 1, EQ5C_CPU_OCC_ISRAM }, 465 { EQ5C_CPU_OCC_DBU, "occ-dbu", 1, 10, EQ5C_PLL_CPU }, 466 { EQ5C_CPU_SI_DBU_TP, "si-dbu-tp", 1, 1, EQ5C_CPU_OCC_DBU }, 467 468 /* EQ5C_PLL_VDI children */ 469 { EQ5C_VDI_OCC_VDI, "occ-vdi", 1, 2, EQ5C_PLL_VDI }, 470 { EQ5C_VDI_VDI, "vdi", 1, 1, EQ5C_VDI_OCC_VDI }, 471 { EQ5C_VDI_OCC_CAN_SER, "occ-can-ser", 1, 16, EQ5C_PLL_VDI }, 472 { EQ5C_VDI_CAN_SER, "can-ser", 1, 1, EQ5C_VDI_OCC_CAN_SER }, 473 { EQ5C_VDI_I2C_SER, "i2c-ser", 1, 20, EQ5C_PLL_VDI }, 474 475 /* EQ5C_PLL_PER children */ 476 { EQ5C_PER_PERIPH, "periph", 1, 1, EQ5C_PER_OCC }, 477 { EQ5C_PER_CAN, "can", 1, 1, EQ5C_PER_OCC }, 478 { EQ5C_PER_SPI, "spi", 1, 1, EQ5C_PER_OCC }, 479 { EQ5C_PER_I2C, "i2c", 1, 1, EQ5C_PER_OCC }, 480 { EQ5C_PER_TIMER, "timer", 1, 1, EQ5C_PER_OCC }, 481 { EQ5C_PER_GPIO, "gpio", 1, 1, EQ5C_PER_OCC }, 482 { EQ5C_PER_EMMC, "emmc-sys", 1, 10, EQ5C_PLL_PER }, 483 { EQ5C_PER_CCF, "ccf-ctrl", 1, 4, EQ5C_PLL_PER }, 484 { EQ5C_PER_OCC_MJPEG, "occ-mjpeg", 1, 2, EQ5C_PLL_PER }, 485 { EQ5C_PER_HSM, "hsm", 1, 1, EQ5C_PER_OCC_MJPEG }, 486 { EQ5C_PER_MJPEG, "mjpeg", 1, 1, EQ5C_PER_OCC_MJPEG }, 487 { EQ5C_PER_FCMU_A, "fcmu-a", 1, 20, EQ5C_PLL_PER }, 488 { EQ5C_PER_OCC_PCI, "occ-pci-sys", 1, 8, EQ5C_PLL_PER }, 489 }; 490 491 static const struct eqc_div eqc_eyeq5_divs[] = { 492 { 493 .index = EQ5C_DIV_OSPI, 494 .name = "div-ospi", 495 .parent = EQ5C_PLL_PER, 496 .reg = 0x11C, 497 .shift = 0, 498 .width = 4, 499 }, 500 }; 501 502 static const struct eqc_early_match_data eqc_eyeq5_early_match_data __initconst = { 503 .early_pll_count = ARRAY_SIZE(eqc_eyeq5_early_plls), 504 .early_plls = eqc_eyeq5_early_plls, 505 506 .early_fixed_factor_count = ARRAY_SIZE(eqc_eyeq5_early_fixed_factors), 507 .early_fixed_factors = eqc_eyeq5_early_fixed_factors, 508 509 .late_clk_count = ARRAY_SIZE(eqc_eyeq5_plls) + ARRAY_SIZE(eqc_eyeq5_divs) + 510 ARRAY_SIZE(eqc_eyeq5_fixed_factors), 511 }; 512 513 static const struct eqc_match_data eqc_eyeq5_match_data = { 514 .pll_count = ARRAY_SIZE(eqc_eyeq5_plls), 515 .plls = eqc_eyeq5_plls, 516 517 .div_count = ARRAY_SIZE(eqc_eyeq5_divs), 518 .divs = eqc_eyeq5_divs, 519 520 .fixed_factor_count = ARRAY_SIZE(eqc_eyeq5_fixed_factors), 521 .fixed_factors = eqc_eyeq5_fixed_factors, 522 523 .reset_auxdev_name = "reset", 524 .pinctrl_auxdev_name = "pinctrl", 525 .eth_phy_auxdev_name = "phy", 526 527 .early_clk_count = ARRAY_SIZE(eqc_eyeq5_early_plls) + 528 ARRAY_SIZE(eqc_eyeq5_early_fixed_factors), 529 }; 530 531 static const struct eqc_pll eqc_eyeq6l_plls[] = { 532 { .index = EQ6LC_PLL_DDR, .name = "pll-ddr", .reg64 = 0x02C }, 533 { .index = EQ6LC_PLL_CPU, .name = "pll-cpu", .reg64 = 0x034 }, /* also acc */ 534 { .index = EQ6LC_PLL_PER, .name = "pll-per", .reg64 = 0x03C }, 535 { .index = EQ6LC_PLL_VDI, .name = "pll-vdi", .reg64 = 0x044 }, 536 }; 537 538 static const struct eqc_match_data eqc_eyeq6l_match_data = { 539 .pll_count = ARRAY_SIZE(eqc_eyeq6l_plls), 540 .plls = eqc_eyeq6l_plls, 541 542 .reset_auxdev_name = "reset", 543 }; 544 545 static const struct eqc_pll eqc_eyeq6lplus_early_plls[] = { 546 { .index = EQ6LPC_PLL_CPU, .name = "pll-cpu", .reg64 = 0x058 }, 547 }; 548 549 static const struct eqc_pll eqc_eyeq6lplus_plls[] = { 550 { .index = EQ6LPC_PLL_DDR, .name = "pll-ddr", .reg64 = 0x02C }, 551 { .index = EQ6LPC_PLL_ACC, .name = "pll-acc", .reg64 = 0x034 }, 552 { .index = EQ6LPC_PLL_PER, .name = "pll-per", .reg64 = 0x03C }, 553 { .index = EQ6LPC_PLL_VDI, .name = "pll-vdi", .reg64 = 0x044 }, 554 }; 555 556 static const struct eqc_fixed_factor eqc_eyeq6lplus_early_fixed_factors[] = { 557 { EQ6LPC_CPU_OCC, "occ-cpu", 1, 1, EQ6LPC_PLL_CPU }, 558 }; 559 560 static const struct eqc_fixed_factor eqc_eyeq6lplus_fixed_factors[] = { 561 { EQ6LPC_DDR_OCC, "occ-ddr", 1, 1, EQ6LPC_PLL_DDR }, 562 563 { EQ6LPC_ACC_VDI, "vdi-div", 1, 10, EQ6LPC_PLL_ACC }, 564 { EQ6LPC_ACC_OCC, "occ-acc", 1, 1, EQ6LPC_PLL_ACC }, 565 { EQ6LPC_ACC_FCMU, "fcmu-a-clk", 1, 10, EQ6LPC_ACC_OCC }, 566 567 { EQ6LPC_PER_OCC, "occ-per", 1, 1, EQ6LPC_PLL_PER }, 568 { EQ6LPC_PER_I2C_SER, "i2c-ser-clk", 1, 10, EQ6LPC_PER_OCC }, 569 { EQ6LPC_PER_PCLK, "pclk", 1, 4, EQ6LPC_PER_OCC }, 570 { EQ6LPC_PER_TSU, "tsu-clk", 1, 8, EQ6LPC_PER_OCC }, 571 { EQ6LPC_PER_OSPI, "ospi-ref-clk", 1, 10, EQ6LPC_PER_OCC }, 572 { EQ6LPC_PER_GPIO, "gpio-clk", 1, 4, EQ6LPC_PER_OCC }, 573 { EQ6LPC_PER_TIMER, "timer-clk", 1, 4, EQ6LPC_PER_OCC }, 574 { EQ6LPC_PER_I2C, "i2c-clk", 1, 4, EQ6LPC_PER_OCC }, 575 { EQ6LPC_PER_UART, "uart-clk", 1, 4, EQ6LPC_PER_OCC }, 576 { EQ6LPC_PER_SPI, "spi-clk", 1, 4, EQ6LPC_PER_OCC }, 577 { EQ6LPC_PER_PERIPH, "periph-clk", 1, 1, EQ6LPC_PER_OCC }, 578 579 { EQ6LPC_VDI_OCC, "occ-vdi", 1, 1, EQ6LPC_PLL_VDI }, 580 }; 581 582 static const struct eqc_early_match_data eqc_eyeq6lplus_early_match_data __initconst = { 583 .early_pll_count = ARRAY_SIZE(eqc_eyeq6lplus_early_plls), 584 .early_plls = eqc_eyeq6lplus_early_plls, 585 586 .early_fixed_factor_count = ARRAY_SIZE(eqc_eyeq6lplus_early_fixed_factors), 587 .early_fixed_factors = eqc_eyeq6lplus_early_fixed_factors, 588 589 .late_clk_count = ARRAY_SIZE(eqc_eyeq6lplus_plls) + 590 ARRAY_SIZE(eqc_eyeq6lplus_fixed_factors), 591 }; 592 593 static const struct eqc_match_data eqc_eyeq6lplus_match_data = { 594 .pll_count = ARRAY_SIZE(eqc_eyeq6lplus_plls), 595 .plls = eqc_eyeq6lplus_plls, 596 597 .fixed_factor_count = ARRAY_SIZE(eqc_eyeq6lplus_fixed_factors), 598 .fixed_factors = eqc_eyeq6lplus_fixed_factors, 599 600 .reset_auxdev_name = "reset", 601 .pinctrl_auxdev_name = "pinctrl", 602 603 .early_clk_count = ARRAY_SIZE(eqc_eyeq6lplus_early_plls) + 604 ARRAY_SIZE(eqc_eyeq6lplus_early_fixed_factors), 605 }; 606 607 static const struct eqc_match_data eqc_eyeq6h_west_match_data = { 608 .reset_auxdev_name = "reset_west", 609 }; 610 611 static const struct eqc_pll eqc_eyeq6h_east_plls[] = { 612 { .index = 0, .name = "pll-east", .reg64 = 0x074 }, 613 }; 614 615 static const struct eqc_match_data eqc_eyeq6h_east_match_data = { 616 .pll_count = ARRAY_SIZE(eqc_eyeq6h_east_plls), 617 .plls = eqc_eyeq6h_east_plls, 618 619 .reset_auxdev_name = "reset_east", 620 }; 621 622 static const struct eqc_pll eqc_eyeq6h_south_plls[] = { 623 { .index = EQ6HC_SOUTH_PLL_VDI, .name = "pll-vdi", .reg64 = 0x000 }, 624 { .index = EQ6HC_SOUTH_PLL_PCIE, .name = "pll-pcie", .reg64 = 0x008 }, 625 { .index = EQ6HC_SOUTH_PLL_PER, .name = "pll-per", .reg64 = 0x010 }, 626 { .index = EQ6HC_SOUTH_PLL_ISP, .name = "pll-isp", .reg64 = 0x018 }, 627 }; 628 629 static const struct eqc_div eqc_eyeq6h_south_divs[] = { 630 { 631 .index = EQ6HC_SOUTH_DIV_EMMC, 632 .name = "div-emmc", 633 .parent = EQ6HC_SOUTH_PLL_PER, 634 .reg = 0x070, 635 .shift = 4, 636 .width = 4, 637 }, 638 { 639 .index = EQ6HC_SOUTH_DIV_OSPI_REF, 640 .name = "div-ospi-ref", 641 .parent = EQ6HC_SOUTH_PLL_PER, 642 .reg = 0x090, 643 .shift = 4, 644 .width = 4, 645 }, 646 { 647 .index = EQ6HC_SOUTH_DIV_OSPI_SYS, 648 .name = "div-ospi-sys", 649 .parent = EQ6HC_SOUTH_PLL_PER, 650 .reg = 0x090, 651 .shift = 8, 652 .width = 1, 653 }, 654 { 655 .index = EQ6HC_SOUTH_DIV_TSU, 656 .name = "div-tsu", 657 .parent = EQ6HC_SOUTH_PLL_PCIE, 658 .reg = 0x098, 659 .shift = 4, 660 .width = 8, 661 }, 662 }; 663 664 static const struct eqc_match_data eqc_eyeq6h_south_match_data = { 665 .pll_count = ARRAY_SIZE(eqc_eyeq6h_south_plls), 666 .plls = eqc_eyeq6h_south_plls, 667 668 .div_count = ARRAY_SIZE(eqc_eyeq6h_south_divs), 669 .divs = eqc_eyeq6h_south_divs, 670 }; 671 672 static const struct eqc_pll eqc_eyeq6h_ddr0_plls[] = { 673 { .index = 0, .name = "pll-ddr0", .reg64 = 0x074 }, 674 }; 675 676 static const struct eqc_match_data eqc_eyeq6h_ddr0_match_data = { 677 .pll_count = ARRAY_SIZE(eqc_eyeq6h_ddr0_plls), 678 .plls = eqc_eyeq6h_ddr0_plls, 679 }; 680 681 static const struct eqc_pll eqc_eyeq6h_ddr1_plls[] = { 682 { .index = 0, .name = "pll-ddr1", .reg64 = 0x074 }, 683 }; 684 685 static const struct eqc_match_data eqc_eyeq6h_ddr1_match_data = { 686 .pll_count = ARRAY_SIZE(eqc_eyeq6h_ddr1_plls), 687 .plls = eqc_eyeq6h_ddr1_plls, 688 }; 689 690 static const struct eqc_pll eqc_eyeq6h_acc_plls[] = { 691 { .index = EQ6HC_ACC_PLL_XNN, .name = "pll-xnn", .reg64 = 0x040 }, 692 { .index = EQ6HC_ACC_PLL_VMP, .name = "pll-vmp", .reg64 = 0x050 }, 693 { .index = EQ6HC_ACC_PLL_PMA, .name = "pll-pma", .reg64 = 0x05C }, 694 { .index = EQ6HC_ACC_PLL_MPC, .name = "pll-mpc", .reg64 = 0x068 }, 695 { .index = EQ6HC_ACC_PLL_NOC, .name = "pll-noc", .reg64 = 0x070 }, 696 }; 697 698 static const struct eqc_match_data eqc_eyeq6h_acc_match_data = { 699 .pll_count = ARRAY_SIZE(eqc_eyeq6h_acc_plls), 700 .plls = eqc_eyeq6h_acc_plls, 701 702 .reset_auxdev_name = "reset_acc", 703 }; 704 705 static const struct of_device_id eqc_match_table[] = { 706 { .compatible = "mobileye,eyeq5-olb", .data = &eqc_eyeq5_match_data }, 707 { .compatible = "mobileye,eyeq6l-olb", .data = &eqc_eyeq6l_match_data }, 708 { .compatible = "mobileye,eyeq6lplus-olb", .data = &eqc_eyeq6lplus_match_data }, 709 { .compatible = "mobileye,eyeq6h-west-olb", .data = &eqc_eyeq6h_west_match_data }, 710 { .compatible = "mobileye,eyeq6h-east-olb", .data = &eqc_eyeq6h_east_match_data }, 711 { .compatible = "mobileye,eyeq6h-south-olb", .data = &eqc_eyeq6h_south_match_data }, 712 { .compatible = "mobileye,eyeq6h-ddr0-olb", .data = &eqc_eyeq6h_ddr0_match_data }, 713 { .compatible = "mobileye,eyeq6h-ddr1-olb", .data = &eqc_eyeq6h_ddr1_match_data }, 714 { .compatible = "mobileye,eyeq6h-acc-olb", .data = &eqc_eyeq6h_acc_match_data }, 715 {} 716 }; 717 718 static struct platform_driver eqc_driver = { 719 .probe = eqc_probe, 720 .driver = { 721 .name = "clk-eyeq", 722 .of_match_table = eqc_match_table, 723 .suppress_bind_attrs = true, 724 }, 725 }; 726 builtin_platform_driver(eqc_driver); 727 728 /* Required early for GIC timer. */ 729 static const struct eqc_pll eqc_eyeq6h_central_early_plls[] = { 730 { .index = EQ6HC_CENTRAL_PLL_CPU, .name = "pll-cpu", .reg64 = 0x02C }, 731 }; 732 733 static const struct eqc_fixed_factor eqc_eyeq6h_central_early_fixed_factors[] = { 734 { EQ6HC_CENTRAL_CPU_OCC, "occ-cpu", 1, 1, EQ6HC_CENTRAL_PLL_CPU }, 735 }; 736 737 static const struct eqc_early_match_data eqc_eyeq6h_central_early_match_data __initconst = { 738 .early_pll_count = ARRAY_SIZE(eqc_eyeq6h_central_early_plls), 739 .early_plls = eqc_eyeq6h_central_early_plls, 740 741 .early_fixed_factor_count = ARRAY_SIZE(eqc_eyeq6h_central_early_fixed_factors), 742 .early_fixed_factors = eqc_eyeq6h_central_early_fixed_factors, 743 }; 744 745 /* Required early for UART. */ 746 static const struct eqc_pll eqc_eyeq6h_west_early_plls[] = { 747 { .index = EQ6HC_WEST_PLL_PER, .name = "pll-west", .reg64 = 0x074 }, 748 }; 749 750 static const struct eqc_fixed_factor eqc_eyeq6h_west_early_fixed_factors[] = { 751 { EQ6HC_WEST_PER_OCC, "west-per-occ", 1, 10, EQ6HC_WEST_PLL_PER }, 752 { EQ6HC_WEST_PER_UART, "west-per-uart", 1, 1, EQ6HC_WEST_PER_OCC }, 753 }; 754 755 static const struct eqc_early_match_data eqc_eyeq6h_west_early_match_data __initconst = { 756 .early_pll_count = ARRAY_SIZE(eqc_eyeq6h_west_early_plls), 757 .early_plls = eqc_eyeq6h_west_early_plls, 758 759 .early_fixed_factor_count = ARRAY_SIZE(eqc_eyeq6h_west_early_fixed_factors), 760 .early_fixed_factors = eqc_eyeq6h_west_early_fixed_factors, 761 }; 762 763 static void __init eqc_early_init(struct device_node *np, 764 const struct eqc_early_match_data *early_data) 765 { 766 struct clk_hw_onecell_data *cells; 767 unsigned int i, clk_count; 768 void __iomem *base; 769 int ret; 770 771 clk_count = early_data->early_pll_count + early_data->early_fixed_factor_count + 772 early_data->late_clk_count; 773 cells = kzalloc_flex(*cells, hws, clk_count); 774 if (!cells) { 775 ret = -ENOMEM; 776 goto err; 777 } 778 779 cells->num = clk_count; 780 781 /* 782 * Mark all clocks as deferred; some are registered here, the rest at 783 * platform device probe. 784 * 785 * Once the platform device is probed, its provider will take priority 786 * when looking up clocks. 787 */ 788 for (i = 0; i < clk_count; i++) 789 cells->hws[i] = ERR_PTR(-EPROBE_DEFER); 790 791 /* Offsets (reg64) of early PLLs are relative to OLB block. */ 792 base = of_iomap(np, 0); 793 if (!base) { 794 ret = -ENODEV; 795 goto err; 796 } 797 798 for (i = 0; i < early_data->early_pll_count; i++) { 799 const struct eqc_pll *pll = &early_data->early_plls[i]; 800 unsigned long mult, div, acc; 801 struct clk_hw *hw; 802 u32 r0, r1; 803 u64 val; 804 805 val = readq(base + pll->reg64); 806 r0 = val; 807 r1 = val >> 32; 808 809 ret = eqc_pll_parse_registers(r0, r1, &mult, &div, &acc); 810 if (ret) { 811 pr_err("failed parsing state of %s\n", pll->name); 812 goto err; 813 } 814 815 hw = clk_hw_register_fixed_factor_with_accuracy_fwname(NULL, 816 np, pll->name, "ref", 0, mult, div, acc); 817 cells->hws[pll->index] = hw; 818 if (IS_ERR(hw)) { 819 pr_err("failed registering %s: %pe\n", pll->name, hw); 820 ret = PTR_ERR(hw); 821 goto err; 822 } 823 } 824 825 for (i = 0; i < early_data->early_fixed_factor_count; i++) { 826 const struct eqc_fixed_factor *ff = &early_data->early_fixed_factors[i]; 827 struct clk_hw *parent_hw = cells->hws[ff->parent]; 828 struct clk_hw *hw; 829 830 hw = clk_hw_register_fixed_factor_parent_hw(NULL, ff->name, 831 parent_hw, 0, ff->mult, ff->div); 832 cells->hws[ff->index] = hw; 833 if (IS_ERR(hw)) { 834 pr_err("failed registering %s: %pe\n", ff->name, hw); 835 ret = PTR_ERR(hw); 836 goto err; 837 } 838 } 839 840 ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, cells); 841 if (ret) { 842 pr_err("failed registering clk provider: %d\n", ret); 843 goto err; 844 } 845 846 return; 847 848 err: 849 /* 850 * We are doomed. The system will not be able to boot. 851 * 852 * Let's still try to be good citizens by freeing resources and print 853 * a last error message that might help debugging. 854 */ 855 856 pr_err("failed clk init: %d\n", ret); 857 858 if (cells) { 859 of_clk_del_provider(np); 860 861 for (i = 0; i < early_data->early_pll_count; i++) { 862 const struct eqc_pll *pll = &early_data->early_plls[i]; 863 struct clk_hw *hw = cells->hws[pll->index]; 864 865 if (!IS_ERR_OR_NULL(hw)) 866 clk_hw_unregister_fixed_factor(hw); 867 } 868 869 kfree(cells); 870 } 871 } 872 873 static void __init eqc_eyeq5_early_init(struct device_node *np) 874 { 875 eqc_early_init(np, &eqc_eyeq5_early_match_data); 876 } 877 CLK_OF_DECLARE_DRIVER(eqc_eyeq5, "mobileye,eyeq5-olb", eqc_eyeq5_early_init); 878 879 static void __init eqc_eyeq6h_central_early_init(struct device_node *np) 880 { 881 eqc_early_init(np, &eqc_eyeq6h_central_early_match_data); 882 } 883 CLK_OF_DECLARE_DRIVER(eqc_eyeq6h_central, "mobileye,eyeq6h-central-olb", 884 eqc_eyeq6h_central_early_init); 885 886 static void __init eqc_eyeq6h_west_early_init(struct device_node *np) 887 { 888 eqc_early_init(np, &eqc_eyeq6h_west_early_match_data); 889 } 890 CLK_OF_DECLARE_DRIVER(eqc_eyeq6h_west, "mobileye,eyeq6h-west-olb", 891 eqc_eyeq6h_west_early_init); 892 893 static void __init eqc_eyeq6lplus_early_init(struct device_node *np) 894 { 895 eqc_early_init(np, &eqc_eyeq6lplus_early_match_data); 896 } 897 CLK_OF_DECLARE_DRIVER(eqc_eyeq6lplus, "mobileye,eyeq6lplus-olb", eqc_eyeq6lplus_early_init); 898