Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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