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

Merge branches 'clk-qcom-rpm8974', 'clk-stm32f4', 'clk-ipq4019' and 'clk-fixes' into clk-next

* clk-qcom-rpm8974:
clk: qcom: smd-rpmcc: Add msm8974 clocks

* clk-stm32f4:
clk: stm32f4: SDIO & 48Mhz clock management for STM32F469 board
clk: stm32f4: Add SAI clocks
clk: stm32f4: Add I2S clock
clk: stm32f4: Add lcd-tft clock
clk: stm32f4: Add post divisor for I2S & SAI PLLs
clk: stm32f4: Add PLL_I2S & PLL_SAI for STM32F429/469 boards
clk: stm32f4: Update DT bindings documentation

* clk-ipq4019:
clk: qcom: ipq4019: Add the cpu clock frequency change notifier
clk: qcom: ipq4019: Add all the frequencies for apss cpu
clk: qcom: ipq4019: correct sdcc frequency and parent name
clk: qcom: ipq4019: Add the nodes for pcnoc
clk: qcom: ipq4019: Add the apss cpu pll divider clock node
clk: qcom: ipq4019: remove fixed clocks and add pll clocks

* clk-fixes:
clk: stm32f4: Use CLK_OF_DECLARE_DRIVER initialization method
clk: renesas: mstp: Support 8-bit registers for r7s72100

+1242 -42
+1
Documentation/devicetree/bindings/clock/qcom,rpmcc.txt
··· 11 11 compatible "qcom,rpmcc" should be also included. 12 12 13 13 "qcom,rpmcc-msm8916", "qcom,rpmcc" 14 + "qcom,rpmcc-msm8974", "qcom,rpmcc" 14 15 "qcom,rpmcc-apq8064", "qcom,rpmcc" 15 16 16 17 - #clock-cells : shall contain 1
+17
Documentation/devicetree/bindings/clock/st,stm32-rcc.txt
··· 17 17 property, containing a phandle to the clock device node, an index selecting 18 18 between gated clocks and other clocks and an index specifying the clock to 19 19 use. 20 + - clocks: External oscillator clock phandle 21 + - high speed external clock signal (HSE) 22 + - external I2S clock (I2S_CKIN) 20 23 21 24 Example: 22 25 ··· 28 25 #clock-cells = <2> 29 26 compatible = "st,stm32f42xx-rcc", "st,stm32-rcc"; 30 27 reg = <0x40023800 0x400>; 28 + clocks = <&clk_hse>, <&clk_i2s_ckin>; 31 29 }; 32 30 33 31 Specifying gated clocks ··· 70 66 71 67 0 SYSTICK 72 68 1 FCLK 69 + 2 CLK_LSI (low-power clock source) 70 + 3 CLK_LSE (generated from a 32.768 kHz low-speed external 71 + crystal or ceramic resonator) 72 + 4 CLK_HSE_RTC (HSE division factor for RTC clock) 73 + 5 CLK_RTC (real-time clock) 74 + 6 PLL_VCO_I2S (vco frequency of I2S pll) 75 + 7 PLL_VCO_SAI (vco frequency of SAI pll) 76 + 8 CLK_LCD (LCD-TFT) 77 + 9 CLK_I2S (I2S clocks) 78 + 10 CLK_SAI1 (audio clocks) 79 + 11 CLK_SAI2 80 + 12 CLK_I2SQ_PDIV (post divisor of pll i2s q divisor) 81 + 13 CLK_SAIQ_PDIV (post divisor of pll sai q divisor) 73 82 74 83 Example: 75 84
+578 -21
drivers/clk/clk-stm32f4.c
··· 28 28 #include <linux/regmap.h> 29 29 #include <linux/mfd/syscon.h> 30 30 31 + /* 32 + * Include list of clocks wich are not derived from system clock (SYSCLOCK) 33 + * The index of these clocks is the secondary index of DT bindings 34 + * 35 + */ 36 + #include <dt-bindings/clock/stm32fx-clock.h> 37 + 38 + #define STM32F4_RCC_CR 0x00 31 39 #define STM32F4_RCC_PLLCFGR 0x04 32 40 #define STM32F4_RCC_CFGR 0x08 33 41 #define STM32F4_RCC_AHB1ENR 0x30 ··· 45 37 #define STM32F4_RCC_APB2ENR 0x44 46 38 #define STM32F4_RCC_BDCR 0x70 47 39 #define STM32F4_RCC_CSR 0x74 40 + #define STM32F4_RCC_PLLI2SCFGR 0x84 41 + #define STM32F4_RCC_PLLSAICFGR 0x88 42 + #define STM32F4_RCC_DCKCFGR 0x8c 43 + 44 + #define NONE -1 45 + #define NO_IDX NONE 46 + #define NO_MUX NONE 47 + #define NO_GATE NONE 48 48 49 49 struct stm32f4_gate_data { 50 50 u8 offset; ··· 211 195 { STM32F4_RCC_APB2ENR, 8, "adc1", "apb2_div" }, 212 196 { STM32F4_RCC_APB2ENR, 9, "adc2", "apb2_div" }, 213 197 { STM32F4_RCC_APB2ENR, 10, "adc3", "apb2_div" }, 214 - { STM32F4_RCC_APB2ENR, 11, "sdio", "pll48" }, 198 + { STM32F4_RCC_APB2ENR, 11, "sdio", "sdmux" }, 215 199 { STM32F4_RCC_APB2ENR, 12, "spi1", "apb2_div" }, 216 200 { STM32F4_RCC_APB2ENR, 13, "spi4", "apb2_div" }, 217 201 { STM32F4_RCC_APB2ENR, 14, "syscfg", "apb2_div" }, ··· 223 207 { STM32F4_RCC_APB2ENR, 22, "sai1", "apb2_div" }, 224 208 { STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" }, 225 209 }; 226 - 227 - enum { SYSTICK, FCLK, CLK_LSI, CLK_LSE, CLK_HSE_RTC, CLK_RTC, END_PRIMARY_CLK }; 228 210 229 211 /* 230 212 * This bitmask tells us which bit offsets (0..192) on STM32F4[23]xxx ··· 338 324 return clk; 339 325 } 340 326 341 - /* 342 - * Decode current PLL state and (statically) model the state we inherit from 343 - * the bootloader. 344 - */ 345 - static void stm32f4_rcc_register_pll(const char *hse_clk, const char *hsi_clk) 327 + enum { 328 + PLL, 329 + PLL_I2S, 330 + PLL_SAI, 331 + }; 332 + 333 + static const struct clk_div_table pll_divp_table[] = { 334 + { 0, 2 }, { 1, 4 }, { 2, 6 }, { 3, 8 }, { 0 } 335 + }; 336 + 337 + static const struct clk_div_table pll_divr_table[] = { 338 + { 2, 2 }, { 3, 3 }, { 4, 4 }, { 5, 5 }, { 6, 6 }, { 7, 7 }, { 0 } 339 + }; 340 + 341 + struct stm32f4_pll { 342 + spinlock_t *lock; 343 + struct clk_gate gate; 344 + u8 offset; 345 + u8 bit_rdy_idx; 346 + u8 status; 347 + u8 n_start; 348 + }; 349 + 350 + #define to_stm32f4_pll(_gate) container_of(_gate, struct stm32f4_pll, gate) 351 + 352 + struct stm32f4_pll_post_div_data { 353 + int idx; 354 + u8 pll_num; 355 + const char *name; 356 + const char *parent; 357 + u8 flag; 358 + u8 offset; 359 + u8 shift; 360 + u8 width; 361 + u8 flag_div; 362 + const struct clk_div_table *div_table; 363 + }; 364 + 365 + struct stm32f4_vco_data { 366 + const char *vco_name; 367 + u8 offset; 368 + u8 bit_idx; 369 + u8 bit_rdy_idx; 370 + }; 371 + 372 + static const struct stm32f4_vco_data vco_data[] = { 373 + { "vco", STM32F4_RCC_PLLCFGR, 24, 25 }, 374 + { "vco-i2s", STM32F4_RCC_PLLI2SCFGR, 26, 27 }, 375 + { "vco-sai", STM32F4_RCC_PLLSAICFGR, 28, 29 }, 376 + }; 377 + 378 + 379 + static const struct clk_div_table post_divr_table[] = { 380 + { 0, 2 }, { 1, 4 }, { 2, 8 }, { 3, 16 }, { 0 } 381 + }; 382 + 383 + #define MAX_POST_DIV 3 384 + static const struct stm32f4_pll_post_div_data post_div_data[MAX_POST_DIV] = { 385 + { CLK_I2SQ_PDIV, PLL_I2S, "plli2s-q-div", "plli2s-q", 386 + CLK_SET_RATE_PARENT, STM32F4_RCC_DCKCFGR, 0, 5, 0, NULL}, 387 + 388 + { CLK_SAIQ_PDIV, PLL_SAI, "pllsai-q-div", "pllsai-q", 389 + CLK_SET_RATE_PARENT, STM32F4_RCC_DCKCFGR, 8, 5, 0, NULL }, 390 + 391 + { NO_IDX, PLL_SAI, "pllsai-r-div", "pllsai-r", CLK_SET_RATE_PARENT, 392 + STM32F4_RCC_DCKCFGR, 16, 2, 0, post_divr_table }, 393 + }; 394 + 395 + struct stm32f4_div_data { 396 + u8 shift; 397 + u8 width; 398 + u8 flag_div; 399 + const struct clk_div_table *div_table; 400 + }; 401 + 402 + #define MAX_PLL_DIV 3 403 + static const struct stm32f4_div_data div_data[MAX_PLL_DIV] = { 404 + { 16, 2, 0, pll_divp_table }, 405 + { 24, 4, CLK_DIVIDER_ONE_BASED, NULL }, 406 + { 28, 3, 0, pll_divr_table }, 407 + }; 408 + 409 + struct stm32f4_pll_data { 410 + u8 pll_num; 411 + u8 n_start; 412 + const char *div_name[MAX_PLL_DIV]; 413 + }; 414 + 415 + static const struct stm32f4_pll_data stm32f429_pll[MAX_PLL_DIV] = { 416 + { PLL, 192, { "pll", "pll48", NULL } }, 417 + { PLL_I2S, 192, { NULL, "plli2s-q", "plli2s-r" } }, 418 + { PLL_SAI, 49, { NULL, "pllsai-q", "pllsai-r" } }, 419 + }; 420 + 421 + static const struct stm32f4_pll_data stm32f469_pll[MAX_PLL_DIV] = { 422 + { PLL, 50, { "pll", "pll-q", NULL } }, 423 + { PLL_I2S, 50, { "plli2s-p", "plli2s-q", "plli2s-r" } }, 424 + { PLL_SAI, 50, { "pllsai-p", "pllsai-q", "pllsai-r" } }, 425 + }; 426 + 427 + static int stm32f4_pll_is_enabled(struct clk_hw *hw) 346 428 { 347 - unsigned long pllcfgr = readl(base + STM32F4_RCC_PLLCFGR); 429 + return clk_gate_ops.is_enabled(hw); 430 + } 348 431 349 - unsigned long pllm = pllcfgr & 0x3f; 350 - unsigned long plln = (pllcfgr >> 6) & 0x1ff; 351 - unsigned long pllp = BIT(((pllcfgr >> 16) & 3) + 1); 352 - const char *pllsrc = pllcfgr & BIT(22) ? hse_clk : hsi_clk; 353 - unsigned long pllq = (pllcfgr >> 24) & 0xf; 432 + static int stm32f4_pll_enable(struct clk_hw *hw) 433 + { 434 + struct clk_gate *gate = to_clk_gate(hw); 435 + struct stm32f4_pll *pll = to_stm32f4_pll(gate); 436 + int ret = 0; 437 + unsigned long reg; 354 438 355 - clk_register_fixed_factor(NULL, "vco", pllsrc, 0, plln, pllm); 356 - clk_register_fixed_factor(NULL, "pll", "vco", 0, 1, pllp); 357 - clk_register_fixed_factor(NULL, "pll48", "vco", 0, 1, pllq); 439 + ret = clk_gate_ops.enable(hw); 440 + 441 + ret = readl_relaxed_poll_timeout_atomic(base + STM32F4_RCC_CR, reg, 442 + reg & (1 << pll->bit_rdy_idx), 0, 10000); 443 + 444 + return ret; 445 + } 446 + 447 + static void stm32f4_pll_disable(struct clk_hw *hw) 448 + { 449 + clk_gate_ops.disable(hw); 450 + } 451 + 452 + static unsigned long stm32f4_pll_recalc(struct clk_hw *hw, 453 + unsigned long parent_rate) 454 + { 455 + struct clk_gate *gate = to_clk_gate(hw); 456 + struct stm32f4_pll *pll = to_stm32f4_pll(gate); 457 + unsigned long n; 458 + 459 + n = (readl(base + pll->offset) >> 6) & 0x1ff; 460 + 461 + return parent_rate * n; 462 + } 463 + 464 + static long stm32f4_pll_round_rate(struct clk_hw *hw, unsigned long rate, 465 + unsigned long *prate) 466 + { 467 + struct clk_gate *gate = to_clk_gate(hw); 468 + struct stm32f4_pll *pll = to_stm32f4_pll(gate); 469 + unsigned long n; 470 + 471 + n = rate / *prate; 472 + 473 + if (n < pll->n_start) 474 + n = pll->n_start; 475 + else if (n > 432) 476 + n = 432; 477 + 478 + return *prate * n; 479 + } 480 + 481 + static int stm32f4_pll_set_rate(struct clk_hw *hw, unsigned long rate, 482 + unsigned long parent_rate) 483 + { 484 + struct clk_gate *gate = to_clk_gate(hw); 485 + struct stm32f4_pll *pll = to_stm32f4_pll(gate); 486 + 487 + unsigned long n; 488 + unsigned long val; 489 + int pll_state; 490 + 491 + pll_state = stm32f4_pll_is_enabled(hw); 492 + 493 + if (pll_state) 494 + stm32f4_pll_disable(hw); 495 + 496 + n = rate / parent_rate; 497 + 498 + val = readl(base + pll->offset) & ~(0x1ff << 6); 499 + 500 + writel(val | ((n & 0x1ff) << 6), base + pll->offset); 501 + 502 + if (pll_state) 503 + stm32f4_pll_enable(hw); 504 + 505 + return 0; 506 + } 507 + 508 + static const struct clk_ops stm32f4_pll_gate_ops = { 509 + .enable = stm32f4_pll_enable, 510 + .disable = stm32f4_pll_disable, 511 + .is_enabled = stm32f4_pll_is_enabled, 512 + .recalc_rate = stm32f4_pll_recalc, 513 + .round_rate = stm32f4_pll_round_rate, 514 + .set_rate = stm32f4_pll_set_rate, 515 + }; 516 + 517 + struct stm32f4_pll_div { 518 + struct clk_divider div; 519 + struct clk_hw *hw_pll; 520 + }; 521 + 522 + #define to_pll_div_clk(_div) container_of(_div, struct stm32f4_pll_div, div) 523 + 524 + static unsigned long stm32f4_pll_div_recalc_rate(struct clk_hw *hw, 525 + unsigned long parent_rate) 526 + { 527 + return clk_divider_ops.recalc_rate(hw, parent_rate); 528 + } 529 + 530 + static long stm32f4_pll_div_round_rate(struct clk_hw *hw, unsigned long rate, 531 + unsigned long *prate) 532 + { 533 + return clk_divider_ops.round_rate(hw, rate, prate); 534 + } 535 + 536 + static int stm32f4_pll_div_set_rate(struct clk_hw *hw, unsigned long rate, 537 + unsigned long parent_rate) 538 + { 539 + int pll_state, ret; 540 + 541 + struct clk_divider *div = to_clk_divider(hw); 542 + struct stm32f4_pll_div *pll_div = to_pll_div_clk(div); 543 + 544 + pll_state = stm32f4_pll_is_enabled(pll_div->hw_pll); 545 + 546 + if (pll_state) 547 + stm32f4_pll_disable(pll_div->hw_pll); 548 + 549 + ret = clk_divider_ops.set_rate(hw, rate, parent_rate); 550 + 551 + if (pll_state) 552 + stm32f4_pll_enable(pll_div->hw_pll); 553 + 554 + return ret; 555 + } 556 + 557 + static const struct clk_ops stm32f4_pll_div_ops = { 558 + .recalc_rate = stm32f4_pll_div_recalc_rate, 559 + .round_rate = stm32f4_pll_div_round_rate, 560 + .set_rate = stm32f4_pll_div_set_rate, 561 + }; 562 + 563 + static struct clk_hw *clk_register_pll_div(const char *name, 564 + const char *parent_name, unsigned long flags, 565 + void __iomem *reg, u8 shift, u8 width, 566 + u8 clk_divider_flags, const struct clk_div_table *table, 567 + struct clk_hw *pll_hw, spinlock_t *lock) 568 + { 569 + struct stm32f4_pll_div *pll_div; 570 + struct clk_hw *hw; 571 + struct clk_init_data init; 572 + int ret; 573 + 574 + /* allocate the divider */ 575 + pll_div = kzalloc(sizeof(*pll_div), GFP_KERNEL); 576 + if (!pll_div) 577 + return ERR_PTR(-ENOMEM); 578 + 579 + init.name = name; 580 + init.ops = &stm32f4_pll_div_ops; 581 + init.flags = flags; 582 + init.parent_names = (parent_name ? &parent_name : NULL); 583 + init.num_parents = (parent_name ? 1 : 0); 584 + 585 + /* struct clk_divider assignments */ 586 + pll_div->div.reg = reg; 587 + pll_div->div.shift = shift; 588 + pll_div->div.width = width; 589 + pll_div->div.flags = clk_divider_flags; 590 + pll_div->div.lock = lock; 591 + pll_div->div.table = table; 592 + pll_div->div.hw.init = &init; 593 + 594 + pll_div->hw_pll = pll_hw; 595 + 596 + /* register the clock */ 597 + hw = &pll_div->div.hw; 598 + ret = clk_hw_register(NULL, hw); 599 + if (ret) { 600 + kfree(pll_div); 601 + hw = ERR_PTR(ret); 602 + } 603 + 604 + return hw; 605 + } 606 + 607 + static struct clk_hw *stm32f4_rcc_register_pll(const char *pllsrc, 608 + const struct stm32f4_pll_data *data, spinlock_t *lock) 609 + { 610 + struct stm32f4_pll *pll; 611 + struct clk_init_data init = { NULL }; 612 + void __iomem *reg; 613 + struct clk_hw *pll_hw; 614 + int ret; 615 + int i; 616 + const struct stm32f4_vco_data *vco; 617 + 618 + 619 + pll = kzalloc(sizeof(*pll), GFP_KERNEL); 620 + if (!pll) 621 + return ERR_PTR(-ENOMEM); 622 + 623 + vco = &vco_data[data->pll_num]; 624 + 625 + init.name = vco->vco_name; 626 + init.ops = &stm32f4_pll_gate_ops; 627 + init.flags = CLK_SET_RATE_GATE; 628 + init.parent_names = &pllsrc; 629 + init.num_parents = 1; 630 + 631 + pll->gate.lock = lock; 632 + pll->gate.reg = base + STM32F4_RCC_CR; 633 + pll->gate.bit_idx = vco->bit_idx; 634 + pll->gate.hw.init = &init; 635 + 636 + pll->offset = vco->offset; 637 + pll->n_start = data->n_start; 638 + pll->bit_rdy_idx = vco->bit_rdy_idx; 639 + pll->status = (readl(base + STM32F4_RCC_CR) >> vco->bit_idx) & 0x1; 640 + 641 + reg = base + pll->offset; 642 + 643 + pll_hw = &pll->gate.hw; 644 + ret = clk_hw_register(NULL, pll_hw); 645 + if (ret) { 646 + kfree(pll); 647 + return ERR_PTR(ret); 648 + } 649 + 650 + for (i = 0; i < MAX_PLL_DIV; i++) 651 + if (data->div_name[i]) 652 + clk_register_pll_div(data->div_name[i], 653 + vco->vco_name, 654 + 0, 655 + reg, 656 + div_data[i].shift, 657 + div_data[i].width, 658 + div_data[i].flag_div, 659 + div_data[i].div_table, 660 + pll_hw, 661 + lock); 662 + return pll_hw; 358 663 } 359 664 360 665 /* ··· 944 611 "no-clock", "lse", "lsi", "hse-rtc" 945 612 }; 946 613 614 + static const char *lcd_parent[1] = { "pllsai-r-div" }; 615 + 616 + static const char *i2s_parents[2] = { "plli2s-r", NULL }; 617 + 618 + static const char *sai_parents[4] = { "pllsai-q-div", "plli2s-q-div", NULL, 619 + "no-clock" }; 620 + 621 + static const char *pll48_parents[2] = { "pll-q", "pllsai-p" }; 622 + 623 + static const char *sdmux_parents[2] = { "pll48", "sys" }; 624 + 625 + struct stm32_aux_clk { 626 + int idx; 627 + const char *name; 628 + const char * const *parent_names; 629 + int num_parents; 630 + int offset_mux; 631 + u8 shift; 632 + u8 mask; 633 + int offset_gate; 634 + u8 bit_idx; 635 + unsigned long flags; 636 + }; 637 + 947 638 struct stm32f4_clk_data { 948 639 const struct stm32f4_gate_data *gates_data; 949 640 const u64 *gates_map; 950 641 int gates_num; 642 + const struct stm32f4_pll_data *pll_data; 643 + const struct stm32_aux_clk *aux_clk; 644 + int aux_clk_num; 645 + }; 646 + 647 + static const struct stm32_aux_clk stm32f429_aux_clk[] = { 648 + { 649 + CLK_LCD, "lcd-tft", lcd_parent, ARRAY_SIZE(lcd_parent), 650 + NO_MUX, 0, 0, 651 + STM32F4_RCC_APB2ENR, 26, 652 + CLK_SET_RATE_PARENT 653 + }, 654 + { 655 + CLK_I2S, "i2s", i2s_parents, ARRAY_SIZE(i2s_parents), 656 + STM32F4_RCC_CFGR, 23, 1, 657 + NO_GATE, 0, 658 + CLK_SET_RATE_PARENT 659 + }, 660 + { 661 + CLK_SAI1, "sai1-a", sai_parents, ARRAY_SIZE(sai_parents), 662 + STM32F4_RCC_DCKCFGR, 20, 3, 663 + STM32F4_RCC_APB2ENR, 22, 664 + CLK_SET_RATE_PARENT 665 + }, 666 + { 667 + CLK_SAI2, "sai1-b", sai_parents, ARRAY_SIZE(sai_parents), 668 + STM32F4_RCC_DCKCFGR, 22, 3, 669 + STM32F4_RCC_APB2ENR, 22, 670 + CLK_SET_RATE_PARENT 671 + }, 672 + }; 673 + 674 + static const struct stm32_aux_clk stm32f469_aux_clk[] = { 675 + { 676 + CLK_LCD, "lcd-tft", lcd_parent, ARRAY_SIZE(lcd_parent), 677 + NO_MUX, 0, 0, 678 + STM32F4_RCC_APB2ENR, 26, 679 + CLK_SET_RATE_PARENT 680 + }, 681 + { 682 + CLK_I2S, "i2s", i2s_parents, ARRAY_SIZE(i2s_parents), 683 + STM32F4_RCC_CFGR, 23, 1, 684 + NO_GATE, 0, 685 + CLK_SET_RATE_PARENT 686 + }, 687 + { 688 + CLK_SAI1, "sai1-a", sai_parents, ARRAY_SIZE(sai_parents), 689 + STM32F4_RCC_DCKCFGR, 20, 3, 690 + STM32F4_RCC_APB2ENR, 22, 691 + CLK_SET_RATE_PARENT 692 + }, 693 + { 694 + CLK_SAI2, "sai1-b", sai_parents, ARRAY_SIZE(sai_parents), 695 + STM32F4_RCC_DCKCFGR, 22, 3, 696 + STM32F4_RCC_APB2ENR, 22, 697 + CLK_SET_RATE_PARENT 698 + }, 699 + { 700 + NO_IDX, "pll48", pll48_parents, ARRAY_SIZE(pll48_parents), 701 + STM32F4_RCC_DCKCFGR, 27, 1, 702 + NO_GATE, 0, 703 + 0 704 + }, 705 + { 706 + NO_IDX, "sdmux", sdmux_parents, ARRAY_SIZE(sdmux_parents), 707 + STM32F4_RCC_DCKCFGR, 28, 1, 708 + NO_GATE, 0, 709 + 0 710 + }, 951 711 }; 952 712 953 713 static const struct stm32f4_clk_data stm32f429_clk_data = { 954 714 .gates_data = stm32f429_gates, 955 715 .gates_map = stm32f42xx_gate_map, 956 716 .gates_num = ARRAY_SIZE(stm32f429_gates), 717 + .pll_data = stm32f429_pll, 718 + .aux_clk = stm32f429_aux_clk, 719 + .aux_clk_num = ARRAY_SIZE(stm32f429_aux_clk), 957 720 }; 958 721 959 722 static const struct stm32f4_clk_data stm32f469_clk_data = { 960 723 .gates_data = stm32f469_gates, 961 724 .gates_map = stm32f46xx_gate_map, 962 725 .gates_num = ARRAY_SIZE(stm32f469_gates), 726 + .pll_data = stm32f469_pll, 727 + .aux_clk = stm32f469_aux_clk, 728 + .aux_clk_num = ARRAY_SIZE(stm32f469_aux_clk), 963 729 }; 964 730 965 731 static const struct of_device_id stm32f4_of_match[] = { ··· 1073 641 {} 1074 642 }; 1075 643 644 + static struct clk_hw *stm32_register_aux_clk(const char *name, 645 + const char * const *parent_names, int num_parents, 646 + int offset_mux, u8 shift, u8 mask, 647 + int offset_gate, u8 bit_idx, 648 + unsigned long flags, spinlock_t *lock) 649 + { 650 + struct clk_hw *hw; 651 + struct clk_gate *gate; 652 + struct clk_mux *mux = NULL; 653 + struct clk_hw *mux_hw = NULL, *gate_hw = NULL; 654 + const struct clk_ops *mux_ops = NULL, *gate_ops = NULL; 655 + 656 + if (offset_gate != NO_GATE) { 657 + gate = kzalloc(sizeof(*gate), GFP_KERNEL); 658 + if (!gate) { 659 + hw = ERR_PTR(-EINVAL); 660 + goto fail; 661 + } 662 + 663 + gate->reg = base + offset_gate; 664 + gate->bit_idx = bit_idx; 665 + gate->flags = 0; 666 + gate->lock = lock; 667 + gate_hw = &gate->hw; 668 + gate_ops = &clk_gate_ops; 669 + } 670 + 671 + if (offset_mux != NO_MUX) { 672 + mux = kzalloc(sizeof(*mux), GFP_KERNEL); 673 + if (!mux) { 674 + kfree(gate); 675 + hw = ERR_PTR(-EINVAL); 676 + goto fail; 677 + } 678 + 679 + mux->reg = base + offset_mux; 680 + mux->shift = shift; 681 + mux->mask = mask; 682 + mux->flags = 0; 683 + mux_hw = &mux->hw; 684 + mux_ops = &clk_mux_ops; 685 + } 686 + 687 + if (mux_hw == NULL && gate_hw == NULL) 688 + return ERR_PTR(-EINVAL); 689 + 690 + hw = clk_hw_register_composite(NULL, name, parent_names, num_parents, 691 + mux_hw, mux_ops, 692 + NULL, NULL, 693 + gate_hw, gate_ops, 694 + flags); 695 + 696 + if (IS_ERR(hw)) { 697 + kfree(gate); 698 + kfree(mux); 699 + } 700 + fail: 701 + return hw; 702 + } 703 + 1076 704 static void __init stm32f4_rcc_init(struct device_node *np) 1077 705 { 1078 - const char *hse_clk; 706 + const char *hse_clk, *i2s_in_clk; 1079 707 int n; 1080 708 const struct of_device_id *match; 1081 709 const struct stm32f4_clk_data *data; 710 + unsigned long pllcfgr; 711 + const char *pllsrc; 712 + unsigned long pllm; 1082 713 1083 714 base = of_iomap(np, 0); 1084 715 if (!base) { ··· 1170 675 1171 676 hse_clk = of_clk_get_parent_name(np, 0); 1172 677 678 + i2s_in_clk = of_clk_get_parent_name(np, 1); 679 + 680 + i2s_parents[1] = i2s_in_clk; 681 + sai_parents[2] = i2s_in_clk; 682 + 1173 683 clk_register_fixed_rate_with_accuracy(NULL, "hsi", NULL, 0, 1174 684 16000000, 160000); 1175 - stm32f4_rcc_register_pll(hse_clk, "hsi"); 685 + pllcfgr = readl(base + STM32F4_RCC_PLLCFGR); 686 + pllsrc = pllcfgr & BIT(22) ? hse_clk : "hsi"; 687 + pllm = pllcfgr & 0x3f; 688 + 689 + clk_hw_register_fixed_factor(NULL, "vco_in", pllsrc, 690 + 0, 1, pllm); 691 + 692 + stm32f4_rcc_register_pll("vco_in", &data->pll_data[0], 693 + &stm32f4_clk_lock); 694 + 695 + clks[PLL_VCO_I2S] = stm32f4_rcc_register_pll("vco_in", 696 + &data->pll_data[1], &stm32f4_clk_lock); 697 + 698 + clks[PLL_VCO_SAI] = stm32f4_rcc_register_pll("vco_in", 699 + &data->pll_data[2], &stm32f4_clk_lock); 700 + 701 + for (n = 0; n < MAX_POST_DIV; n++) { 702 + const struct stm32f4_pll_post_div_data *post_div; 703 + struct clk_hw *hw; 704 + 705 + post_div = &post_div_data[n]; 706 + 707 + hw = clk_register_pll_div(post_div->name, 708 + post_div->parent, 709 + post_div->flag, 710 + base + post_div->offset, 711 + post_div->shift, 712 + post_div->width, 713 + post_div->flag_div, 714 + post_div->div_table, 715 + clks[post_div->pll_num], 716 + &stm32f4_clk_lock); 717 + 718 + if (post_div->idx != NO_IDX) 719 + clks[post_div->idx] = hw; 720 + } 1176 721 1177 722 sys_parents[1] = hse_clk; 1178 723 clk_register_mux_table( ··· 1297 762 goto fail; 1298 763 } 1299 764 765 + for (n = 0; n < data->aux_clk_num; n++) { 766 + const struct stm32_aux_clk *aux_clk; 767 + struct clk_hw *hw; 768 + 769 + aux_clk = &data->aux_clk[n]; 770 + 771 + hw = stm32_register_aux_clk(aux_clk->name, 772 + aux_clk->parent_names, aux_clk->num_parents, 773 + aux_clk->offset_mux, aux_clk->shift, 774 + aux_clk->mask, aux_clk->offset_gate, 775 + aux_clk->bit_idx, aux_clk->flags, 776 + &stm32f4_clk_lock); 777 + 778 + if (IS_ERR(hw)) { 779 + pr_warn("Unable to register %s clk\n", aux_clk->name); 780 + continue; 781 + } 782 + 783 + if (aux_clk->idx != NO_IDX) 784 + clks[aux_clk->idx] = hw; 785 + } 786 + 1300 787 of_clk_add_hw_provider(np, stm32f4_rcc_lookup_clk, NULL); 1301 788 return; 1302 789 fail: 1303 790 kfree(clks); 1304 791 iounmap(base); 1305 792 } 1306 - CLK_OF_DECLARE(stm32f42xx_rcc, "st,stm32f42xx-rcc", stm32f4_rcc_init); 1307 - CLK_OF_DECLARE(stm32f46xx_rcc, "st,stm32f469-rcc", stm32f4_rcc_init); 793 + CLK_OF_DECLARE_DRIVER(stm32f42xx_rcc, "st,stm32f42xx-rcc", stm32f4_rcc_init); 794 + CLK_OF_DECLARE_DRIVER(stm32f46xx_rcc, "st,stm32f469-rcc", stm32f4_rcc_init);
+71
drivers/clk/qcom/clk-smd-rpm.c
··· 462 462 .num_clks = ARRAY_SIZE(msm8916_clks), 463 463 }; 464 464 465 + /* msm8974 */ 466 + DEFINE_CLK_SMD_RPM(msm8974, pnoc_clk, pnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0); 467 + DEFINE_CLK_SMD_RPM(msm8974, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1); 468 + DEFINE_CLK_SMD_RPM(msm8974, cnoc_clk, cnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 2); 469 + DEFINE_CLK_SMD_RPM(msm8974, mmssnoc_ahb_clk, mmssnoc_ahb_a_clk, QCOM_SMD_RPM_BUS_CLK, 3); 470 + DEFINE_CLK_SMD_RPM(msm8974, bimc_clk, bimc_a_clk, QCOM_SMD_RPM_MEM_CLK, 0); 471 + DEFINE_CLK_SMD_RPM(msm8974, gfx3d_clk_src, gfx3d_a_clk_src, QCOM_SMD_RPM_MEM_CLK, 1); 472 + DEFINE_CLK_SMD_RPM(msm8974, ocmemgx_clk, ocmemgx_a_clk, QCOM_SMD_RPM_MEM_CLK, 2); 473 + DEFINE_CLK_SMD_RPM_QDSS(msm8974, qdss_clk, qdss_a_clk, QCOM_SMD_RPM_MISC_CLK, 1); 474 + DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, cxo_d0, cxo_d0_a, 1); 475 + DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, cxo_d1, cxo_d1_a, 2); 476 + DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, cxo_a0, cxo_a0_a, 4); 477 + DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, cxo_a1, cxo_a1_a, 5); 478 + DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, cxo_a2, cxo_a2_a, 6); 479 + DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, diff_clk, diff_a_clk, 7); 480 + DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, div_clk1, div_a_clk1, 11); 481 + DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, div_clk2, div_a_clk2, 12); 482 + DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8974, cxo_d0_pin, cxo_d0_a_pin, 1); 483 + DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8974, cxo_d1_pin, cxo_d1_a_pin, 2); 484 + DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8974, cxo_a0_pin, cxo_a0_a_pin, 4); 485 + DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8974, cxo_a1_pin, cxo_a1_a_pin, 5); 486 + DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8974, cxo_a2_pin, cxo_a2_a_pin, 6); 487 + 488 + static struct clk_smd_rpm *msm8974_clks[] = { 489 + [RPM_SMD_PNOC_CLK] = &msm8974_pnoc_clk, 490 + [RPM_SMD_PNOC_A_CLK] = &msm8974_pnoc_a_clk, 491 + [RPM_SMD_SNOC_CLK] = &msm8974_snoc_clk, 492 + [RPM_SMD_SNOC_A_CLK] = &msm8974_snoc_a_clk, 493 + [RPM_SMD_CNOC_CLK] = &msm8974_cnoc_clk, 494 + [RPM_SMD_CNOC_A_CLK] = &msm8974_cnoc_a_clk, 495 + [RPM_SMD_MMSSNOC_AHB_CLK] = &msm8974_mmssnoc_ahb_clk, 496 + [RPM_SMD_MMSSNOC_AHB_A_CLK] = &msm8974_mmssnoc_ahb_a_clk, 497 + [RPM_SMD_BIMC_CLK] = &msm8974_bimc_clk, 498 + [RPM_SMD_BIMC_A_CLK] = &msm8974_bimc_a_clk, 499 + [RPM_SMD_OCMEMGX_CLK] = &msm8974_ocmemgx_clk, 500 + [RPM_SMD_OCMEMGX_A_CLK] = &msm8974_ocmemgx_a_clk, 501 + [RPM_SMD_QDSS_CLK] = &msm8974_qdss_clk, 502 + [RPM_SMD_QDSS_A_CLK] = &msm8974_qdss_a_clk, 503 + [RPM_SMD_CXO_D0] = &msm8974_cxo_d0, 504 + [RPM_SMD_CXO_D0_A] = &msm8974_cxo_d0_a, 505 + [RPM_SMD_CXO_D1] = &msm8974_cxo_d1, 506 + [RPM_SMD_CXO_D1_A] = &msm8974_cxo_d1_a, 507 + [RPM_SMD_CXO_A0] = &msm8974_cxo_a0, 508 + [RPM_SMD_CXO_A0_A] = &msm8974_cxo_a0_a, 509 + [RPM_SMD_CXO_A1] = &msm8974_cxo_a1, 510 + [RPM_SMD_CXO_A1_A] = &msm8974_cxo_a1_a, 511 + [RPM_SMD_CXO_A2] = &msm8974_cxo_a2, 512 + [RPM_SMD_CXO_A2_A] = &msm8974_cxo_a2_a, 513 + [RPM_SMD_DIFF_CLK] = &msm8974_diff_clk, 514 + [RPM_SMD_DIFF_A_CLK] = &msm8974_diff_a_clk, 515 + [RPM_SMD_DIV_CLK1] = &msm8974_div_clk1, 516 + [RPM_SMD_DIV_A_CLK1] = &msm8974_div_a_clk1, 517 + [RPM_SMD_DIV_CLK2] = &msm8974_div_clk2, 518 + [RPM_SMD_DIV_A_CLK2] = &msm8974_div_a_clk2, 519 + [RPM_SMD_CXO_D0_PIN] = &msm8974_cxo_d0_pin, 520 + [RPM_SMD_CXO_D0_A_PIN] = &msm8974_cxo_d0_a_pin, 521 + [RPM_SMD_CXO_D1_PIN] = &msm8974_cxo_d1_pin, 522 + [RPM_SMD_CXO_D1_A_PIN] = &msm8974_cxo_d1_a_pin, 523 + [RPM_SMD_CXO_A0_PIN] = &msm8974_cxo_a0_pin, 524 + [RPM_SMD_CXO_A0_A_PIN] = &msm8974_cxo_a0_a_pin, 525 + [RPM_SMD_CXO_A1_PIN] = &msm8974_cxo_a1_pin, 526 + [RPM_SMD_CXO_A1_A_PIN] = &msm8974_cxo_a1_a_pin, 527 + [RPM_SMD_CXO_A2_PIN] = &msm8974_cxo_a2_pin, 528 + [RPM_SMD_CXO_A2_A_PIN] = &msm8974_cxo_a2_a_pin, 529 + }; 530 + 531 + static const struct rpm_smd_clk_desc rpm_clk_msm8974 = { 532 + .clks = msm8974_clks, 533 + .num_clks = ARRAY_SIZE(msm8974_clks), 534 + }; 465 535 static const struct of_device_id rpm_smd_clk_match_table[] = { 466 536 { .compatible = "qcom,rpmcc-msm8916", .data = &rpm_clk_msm8916 }, 537 + { .compatible = "qcom,rpmcc-msm8974", .data = &rpm_clk_msm8974 }, 467 538 { } 468 539 }; 469 540 MODULE_DEVICE_TABLE(of, rpm_smd_clk_match_table);
+465 -14
drivers/clk/qcom/gcc-ipq4019.c
··· 20 20 #include <linux/clk-provider.h> 21 21 #include <linux/regmap.h> 22 22 #include <linux/reset-controller.h> 23 + #include <linux/math64.h> 24 + #include <linux/delay.h> 25 + #include <linux/clk.h> 23 26 24 27 #include <dt-bindings/clock/qcom,gcc-ipq4019.h> 25 28 ··· 31 28 #include "clk-rcg.h" 32 29 #include "clk-branch.h" 33 30 #include "reset.h" 31 + #include "clk-regmap-divider.h" 32 + 33 + #define to_clk_regmap_div(_hw) container_of(to_clk_regmap(_hw),\ 34 + struct clk_regmap_div, clkr) 35 + 36 + #define to_clk_fepll(_hw) container_of(to_clk_regmap_div(_hw),\ 37 + struct clk_fepll, cdiv) 34 38 35 39 enum { 36 40 P_XO, ··· 48 38 P_FEPLLWCSS5G, 49 39 P_FEPLL125DLY, 50 40 P_DDRPLLAPSS, 41 + }; 42 + 43 + /* 44 + * struct clk_fepll_vco - vco feedback divider corresponds for FEPLL clocks 45 + * @fdbkdiv_shift: lowest bit for FDBKDIV 46 + * @fdbkdiv_width: number of bits in FDBKDIV 47 + * @refclkdiv_shift: lowest bit for REFCLKDIV 48 + * @refclkdiv_width: number of bits in REFCLKDIV 49 + * @reg: PLL_DIV register address 50 + */ 51 + struct clk_fepll_vco { 52 + u32 fdbkdiv_shift; 53 + u32 fdbkdiv_width; 54 + u32 refclkdiv_shift; 55 + u32 refclkdiv_width; 56 + u32 reg; 57 + }; 58 + 59 + /* 60 + * struct clk_fepll - clk divider corresponds to FEPLL clocks 61 + * @fixed_div: fixed divider value if divider is fixed 62 + * @parent_map: map from software's parent index to hardware's src_sel field 63 + * @cdiv: divider values for PLL_DIV 64 + * @pll_vco: vco feedback divider 65 + * @div_table: mapping for actual divider value to register divider value 66 + * in case of non fixed divider 67 + * @freq_tbl: frequency table 68 + */ 69 + struct clk_fepll { 70 + u32 fixed_div; 71 + const u8 *parent_map; 72 + struct clk_regmap_div cdiv; 73 + const struct clk_fepll_vco *pll_vco; 74 + const struct clk_div_table *div_table; 75 + const struct freq_tbl *freq_tbl; 51 76 }; 52 77 53 78 static struct parent_map gcc_xo_200_500_map[] = { ··· 125 80 126 81 static const char * const gcc_xo_sdcc1_500[] = { 127 82 "xo", 128 - "ddrpll", 83 + "ddrpllsdcc", 129 84 "fepll500", 130 85 }; 131 86 ··· 166 121 { P_DDRPLLAPSS, 1 }, 167 122 }; 168 123 124 + /* 125 + * Contains index for safe clock during APSS freq change. 126 + * fepll500 is being used as safe clock so initialize it 127 + * with its index in parents list gcc_xo_ddr_500_200. 128 + */ 129 + static const int gcc_ipq4019_cpu_safe_parent = 2; 169 130 static const char * const gcc_xo_ddr_500_200[] = { 170 131 "xo", 171 132 "fepll200", ··· 556 505 F(25000000, P_FEPLL500, 1, 1, 20), 557 506 F(50000000, P_FEPLL500, 1, 1, 10), 558 507 F(100000000, P_FEPLL500, 1, 1, 5), 559 - F(193000000, P_DDRPLL, 1, 0, 0), 508 + F(192000000, P_DDRPLL, 1, 0, 0), 560 509 { } 561 510 }; 562 511 ··· 575 524 }; 576 525 577 526 static const struct freq_tbl ftbl_gcc_apps_clk[] = { 578 - F(48000000, P_XO, 1, 0, 0), 527 + F(48000000, P_XO, 1, 0, 0), 579 528 F(200000000, P_FEPLL200, 1, 0, 0), 529 + F(384000000, P_DDRPLLAPSS, 1, 0, 0), 530 + F(413000000, P_DDRPLLAPSS, 1, 0, 0), 531 + F(448000000, P_DDRPLLAPSS, 1, 0, 0), 532 + F(488000000, P_DDRPLLAPSS, 1, 0, 0), 580 533 F(500000000, P_FEPLL500, 1, 0, 0), 581 - F(626000000, P_DDRPLLAPSS, 1, 0, 0), 534 + F(512000000, P_DDRPLLAPSS, 1, 0, 0), 535 + F(537000000, P_DDRPLLAPSS, 1, 0, 0), 536 + F(565000000, P_DDRPLLAPSS, 1, 0, 0), 537 + F(597000000, P_DDRPLLAPSS, 1, 0, 0), 538 + F(632000000, P_DDRPLLAPSS, 1, 0, 0), 539 + F(672000000, P_DDRPLLAPSS, 1, 0, 0), 540 + F(716000000, P_DDRPLLAPSS, 1, 0, 0), 582 541 { } 583 542 }; 584 543 ··· 602 541 .parent_names = gcc_xo_ddr_500_200, 603 542 .num_parents = 4, 604 543 .ops = &clk_rcg2_ops, 544 + .flags = CLK_SET_RATE_PARENT, 605 545 }, 606 546 }; 607 547 ··· 1216 1154 }, 1217 1155 }; 1218 1156 1157 + /* Calculates the VCO rate for FEPLL. */ 1158 + static u64 clk_fepll_vco_calc_rate(struct clk_fepll *pll_div, 1159 + unsigned long parent_rate) 1160 + { 1161 + const struct clk_fepll_vco *pll_vco = pll_div->pll_vco; 1162 + u32 fdbkdiv, refclkdiv, cdiv; 1163 + u64 vco; 1164 + 1165 + regmap_read(pll_div->cdiv.clkr.regmap, pll_vco->reg, &cdiv); 1166 + refclkdiv = (cdiv >> pll_vco->refclkdiv_shift) & 1167 + (BIT(pll_vco->refclkdiv_width) - 1); 1168 + fdbkdiv = (cdiv >> pll_vco->fdbkdiv_shift) & 1169 + (BIT(pll_vco->fdbkdiv_width) - 1); 1170 + 1171 + vco = parent_rate / refclkdiv; 1172 + vco *= 2; 1173 + vco *= fdbkdiv; 1174 + 1175 + return vco; 1176 + } 1177 + 1178 + static const struct clk_fepll_vco gcc_apss_ddrpll_vco = { 1179 + .fdbkdiv_shift = 16, 1180 + .fdbkdiv_width = 8, 1181 + .refclkdiv_shift = 24, 1182 + .refclkdiv_width = 5, 1183 + .reg = 0x2e020, 1184 + }; 1185 + 1186 + static const struct clk_fepll_vco gcc_fepll_vco = { 1187 + .fdbkdiv_shift = 16, 1188 + .fdbkdiv_width = 8, 1189 + .refclkdiv_shift = 24, 1190 + .refclkdiv_width = 5, 1191 + .reg = 0x2f020, 1192 + }; 1193 + 1194 + /* 1195 + * Round rate function for APSS CPU PLL Clock divider. 1196 + * It looks up the frequency table and returns the next higher frequency 1197 + * supported in hardware. 1198 + */ 1199 + static long clk_cpu_div_round_rate(struct clk_hw *hw, unsigned long rate, 1200 + unsigned long *p_rate) 1201 + { 1202 + struct clk_fepll *pll = to_clk_fepll(hw); 1203 + struct clk_hw *p_hw; 1204 + const struct freq_tbl *f; 1205 + 1206 + f = qcom_find_freq(pll->freq_tbl, rate); 1207 + if (!f) 1208 + return -EINVAL; 1209 + 1210 + p_hw = clk_hw_get_parent_by_index(hw, f->src); 1211 + *p_rate = clk_hw_get_rate(p_hw); 1212 + 1213 + return f->freq; 1214 + }; 1215 + 1216 + /* 1217 + * Clock set rate function for APSS CPU PLL Clock divider. 1218 + * It looks up the frequency table and updates the PLL divider to corresponding 1219 + * divider value. 1220 + */ 1221 + static int clk_cpu_div_set_rate(struct clk_hw *hw, unsigned long rate, 1222 + unsigned long parent_rate) 1223 + { 1224 + struct clk_fepll *pll = to_clk_fepll(hw); 1225 + const struct freq_tbl *f; 1226 + u32 mask; 1227 + int ret; 1228 + 1229 + f = qcom_find_freq(pll->freq_tbl, rate); 1230 + if (!f) 1231 + return -EINVAL; 1232 + 1233 + mask = (BIT(pll->cdiv.width) - 1) << pll->cdiv.shift; 1234 + ret = regmap_update_bits(pll->cdiv.clkr.regmap, 1235 + pll->cdiv.reg, mask, 1236 + f->pre_div << pll->cdiv.shift); 1237 + /* 1238 + * There is no status bit which can be checked for successful CPU 1239 + * divider update operation so using delay for the same. 1240 + */ 1241 + udelay(1); 1242 + 1243 + return 0; 1244 + }; 1245 + 1246 + /* 1247 + * Clock frequency calculation function for APSS CPU PLL Clock divider. 1248 + * This clock divider is nonlinear so this function calculates the actual 1249 + * divider and returns the output frequency by dividing VCO Frequency 1250 + * with this actual divider value. 1251 + */ 1252 + static unsigned long 1253 + clk_cpu_div_recalc_rate(struct clk_hw *hw, 1254 + unsigned long parent_rate) 1255 + { 1256 + struct clk_fepll *pll = to_clk_fepll(hw); 1257 + u32 cdiv, pre_div; 1258 + u64 rate; 1259 + 1260 + regmap_read(pll->cdiv.clkr.regmap, pll->cdiv.reg, &cdiv); 1261 + cdiv = (cdiv >> pll->cdiv.shift) & (BIT(pll->cdiv.width) - 1); 1262 + 1263 + /* 1264 + * Some dividers have value in 0.5 fraction so multiply both VCO 1265 + * frequency(parent_rate) and pre_div with 2 to make integer 1266 + * calculation. 1267 + */ 1268 + if (cdiv > 10) 1269 + pre_div = (cdiv + 1) * 2; 1270 + else 1271 + pre_div = cdiv + 12; 1272 + 1273 + rate = clk_fepll_vco_calc_rate(pll, parent_rate) * 2; 1274 + do_div(rate, pre_div); 1275 + 1276 + return rate; 1277 + }; 1278 + 1279 + static const struct clk_ops clk_regmap_cpu_div_ops = { 1280 + .round_rate = clk_cpu_div_round_rate, 1281 + .set_rate = clk_cpu_div_set_rate, 1282 + .recalc_rate = clk_cpu_div_recalc_rate, 1283 + }; 1284 + 1285 + static const struct freq_tbl ftbl_apss_ddr_pll[] = { 1286 + { 384000000, P_XO, 0xd, 0, 0 }, 1287 + { 413000000, P_XO, 0xc, 0, 0 }, 1288 + { 448000000, P_XO, 0xb, 0, 0 }, 1289 + { 488000000, P_XO, 0xa, 0, 0 }, 1290 + { 512000000, P_XO, 0x9, 0, 0 }, 1291 + { 537000000, P_XO, 0x8, 0, 0 }, 1292 + { 565000000, P_XO, 0x7, 0, 0 }, 1293 + { 597000000, P_XO, 0x6, 0, 0 }, 1294 + { 632000000, P_XO, 0x5, 0, 0 }, 1295 + { 672000000, P_XO, 0x4, 0, 0 }, 1296 + { 716000000, P_XO, 0x3, 0, 0 }, 1297 + { 768000000, P_XO, 0x2, 0, 0 }, 1298 + { 823000000, P_XO, 0x1, 0, 0 }, 1299 + { 896000000, P_XO, 0x0, 0, 0 }, 1300 + { } 1301 + }; 1302 + 1303 + static struct clk_fepll gcc_apss_cpu_plldiv_clk = { 1304 + .cdiv.reg = 0x2e020, 1305 + .cdiv.shift = 4, 1306 + .cdiv.width = 4, 1307 + .cdiv.clkr = { 1308 + .enable_reg = 0x2e000, 1309 + .enable_mask = BIT(0), 1310 + .hw.init = &(struct clk_init_data){ 1311 + .name = "ddrpllapss", 1312 + .parent_names = (const char *[]){ 1313 + "xo", 1314 + }, 1315 + .num_parents = 1, 1316 + .ops = &clk_regmap_cpu_div_ops, 1317 + }, 1318 + }, 1319 + .freq_tbl = ftbl_apss_ddr_pll, 1320 + .pll_vco = &gcc_apss_ddrpll_vco, 1321 + }; 1322 + 1323 + /* Calculates the rate for PLL divider. 1324 + * If the divider value is not fixed then it gets the actual divider value 1325 + * from divider table. Then, it calculate the clock rate by dividing the 1326 + * parent rate with actual divider value. 1327 + */ 1328 + static unsigned long 1329 + clk_regmap_clk_div_recalc_rate(struct clk_hw *hw, 1330 + unsigned long parent_rate) 1331 + { 1332 + struct clk_fepll *pll = to_clk_fepll(hw); 1333 + u32 cdiv, pre_div = 1; 1334 + u64 rate; 1335 + const struct clk_div_table *clkt; 1336 + 1337 + if (pll->fixed_div) { 1338 + pre_div = pll->fixed_div; 1339 + } else { 1340 + regmap_read(pll->cdiv.clkr.regmap, pll->cdiv.reg, &cdiv); 1341 + cdiv = (cdiv >> pll->cdiv.shift) & (BIT(pll->cdiv.width) - 1); 1342 + 1343 + for (clkt = pll->div_table; clkt->div; clkt++) { 1344 + if (clkt->val == cdiv) 1345 + pre_div = clkt->div; 1346 + } 1347 + } 1348 + 1349 + rate = clk_fepll_vco_calc_rate(pll, parent_rate); 1350 + do_div(rate, pre_div); 1351 + 1352 + return rate; 1353 + }; 1354 + 1355 + static const struct clk_ops clk_fepll_div_ops = { 1356 + .recalc_rate = clk_regmap_clk_div_recalc_rate, 1357 + }; 1358 + 1359 + static struct clk_fepll gcc_apss_sdcc_clk = { 1360 + .fixed_div = 28, 1361 + .cdiv.clkr = { 1362 + .hw.init = &(struct clk_init_data){ 1363 + .name = "ddrpllsdcc", 1364 + .parent_names = (const char *[]){ 1365 + "xo", 1366 + }, 1367 + .num_parents = 1, 1368 + .ops = &clk_fepll_div_ops, 1369 + }, 1370 + }, 1371 + .pll_vco = &gcc_apss_ddrpll_vco, 1372 + }; 1373 + 1374 + static struct clk_fepll gcc_fepll125_clk = { 1375 + .fixed_div = 32, 1376 + .cdiv.clkr = { 1377 + .hw.init = &(struct clk_init_data){ 1378 + .name = "fepll125", 1379 + .parent_names = (const char *[]){ 1380 + "xo", 1381 + }, 1382 + .num_parents = 1, 1383 + .ops = &clk_fepll_div_ops, 1384 + }, 1385 + }, 1386 + .pll_vco = &gcc_fepll_vco, 1387 + }; 1388 + 1389 + static struct clk_fepll gcc_fepll125dly_clk = { 1390 + .fixed_div = 32, 1391 + .cdiv.clkr = { 1392 + .hw.init = &(struct clk_init_data){ 1393 + .name = "fepll125dly", 1394 + .parent_names = (const char *[]){ 1395 + "xo", 1396 + }, 1397 + .num_parents = 1, 1398 + .ops = &clk_fepll_div_ops, 1399 + }, 1400 + }, 1401 + .pll_vco = &gcc_fepll_vco, 1402 + }; 1403 + 1404 + static struct clk_fepll gcc_fepll200_clk = { 1405 + .fixed_div = 20, 1406 + .cdiv.clkr = { 1407 + .hw.init = &(struct clk_init_data){ 1408 + .name = "fepll200", 1409 + .parent_names = (const char *[]){ 1410 + "xo", 1411 + }, 1412 + .num_parents = 1, 1413 + .ops = &clk_fepll_div_ops, 1414 + }, 1415 + }, 1416 + .pll_vco = &gcc_fepll_vco, 1417 + }; 1418 + 1419 + static struct clk_fepll gcc_fepll500_clk = { 1420 + .fixed_div = 8, 1421 + .cdiv.clkr = { 1422 + .hw.init = &(struct clk_init_data){ 1423 + .name = "fepll500", 1424 + .parent_names = (const char *[]){ 1425 + "xo", 1426 + }, 1427 + .num_parents = 1, 1428 + .ops = &clk_fepll_div_ops, 1429 + }, 1430 + }, 1431 + .pll_vco = &gcc_fepll_vco, 1432 + }; 1433 + 1434 + static const struct clk_div_table fepllwcss_clk_div_table[] = { 1435 + { 0, 15 }, 1436 + { 1, 16 }, 1437 + { 2, 18 }, 1438 + { 3, 20 }, 1439 + { }, 1440 + }; 1441 + 1442 + static struct clk_fepll gcc_fepllwcss2g_clk = { 1443 + .cdiv.reg = 0x2f020, 1444 + .cdiv.shift = 8, 1445 + .cdiv.width = 2, 1446 + .cdiv.clkr = { 1447 + .hw.init = &(struct clk_init_data){ 1448 + .name = "fepllwcss2g", 1449 + .parent_names = (const char *[]){ 1450 + "xo", 1451 + }, 1452 + .num_parents = 1, 1453 + .ops = &clk_fepll_div_ops, 1454 + }, 1455 + }, 1456 + .div_table = fepllwcss_clk_div_table, 1457 + .pll_vco = &gcc_fepll_vco, 1458 + }; 1459 + 1460 + static struct clk_fepll gcc_fepllwcss5g_clk = { 1461 + .cdiv.reg = 0x2f020, 1462 + .cdiv.shift = 12, 1463 + .cdiv.width = 2, 1464 + .cdiv.clkr = { 1465 + .hw.init = &(struct clk_init_data){ 1466 + .name = "fepllwcss5g", 1467 + .parent_names = (const char *[]){ 1468 + "xo", 1469 + }, 1470 + .num_parents = 1, 1471 + .ops = &clk_fepll_div_ops, 1472 + }, 1473 + }, 1474 + .div_table = fepllwcss_clk_div_table, 1475 + .pll_vco = &gcc_fepll_vco, 1476 + }; 1477 + 1478 + static const struct freq_tbl ftbl_gcc_pcnoc_ahb_clk[] = { 1479 + F(48000000, P_XO, 1, 0, 0), 1480 + F(100000000, P_FEPLL200, 2, 0, 0), 1481 + { } 1482 + }; 1483 + 1484 + static struct clk_rcg2 gcc_pcnoc_ahb_clk_src = { 1485 + .cmd_rcgr = 0x21024, 1486 + .hid_width = 5, 1487 + .parent_map = gcc_xo_200_500_map, 1488 + .freq_tbl = ftbl_gcc_pcnoc_ahb_clk, 1489 + .clkr.hw.init = &(struct clk_init_data){ 1490 + .name = "gcc_pcnoc_ahb_clk_src", 1491 + .parent_names = gcc_xo_200_500, 1492 + .num_parents = 3, 1493 + .ops = &clk_rcg2_ops, 1494 + }, 1495 + }; 1496 + 1497 + static struct clk_branch pcnoc_clk_src = { 1498 + .halt_reg = 0x21030, 1499 + .clkr = { 1500 + .enable_reg = 0x21030, 1501 + .enable_mask = BIT(0), 1502 + .hw.init = &(struct clk_init_data){ 1503 + .name = "pcnoc_clk_src", 1504 + .parent_names = (const char *[]){ 1505 + "gcc_pcnoc_ahb_clk_src", 1506 + }, 1507 + .num_parents = 1, 1508 + .ops = &clk_branch2_ops, 1509 + .flags = CLK_SET_RATE_PARENT | 1510 + CLK_IS_CRITICAL, 1511 + }, 1512 + }, 1513 + }; 1514 + 1219 1515 static struct clk_regmap *gcc_ipq4019_clocks[] = { 1220 1516 [AUDIO_CLK_SRC] = &audio_clk_src.clkr, 1221 1517 [BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr, ··· 1634 1214 [GCC_WCSS5G_CLK] = &gcc_wcss5g_clk.clkr, 1635 1215 [GCC_WCSS5G_REF_CLK] = &gcc_wcss5g_ref_clk.clkr, 1636 1216 [GCC_WCSS5G_RTC_CLK] = &gcc_wcss5g_rtc_clk.clkr, 1217 + [GCC_SDCC_PLLDIV_CLK] = &gcc_apss_sdcc_clk.cdiv.clkr, 1218 + [GCC_FEPLL125_CLK] = &gcc_fepll125_clk.cdiv.clkr, 1219 + [GCC_FEPLL125DLY_CLK] = &gcc_fepll125dly_clk.cdiv.clkr, 1220 + [GCC_FEPLL200_CLK] = &gcc_fepll200_clk.cdiv.clkr, 1221 + [GCC_FEPLL500_CLK] = &gcc_fepll500_clk.cdiv.clkr, 1222 + [GCC_FEPLL_WCSS2G_CLK] = &gcc_fepllwcss2g_clk.cdiv.clkr, 1223 + [GCC_FEPLL_WCSS5G_CLK] = &gcc_fepllwcss5g_clk.cdiv.clkr, 1224 + [GCC_APSS_CPU_PLLDIV_CLK] = &gcc_apss_cpu_plldiv_clk.cdiv.clkr, 1225 + [GCC_PCNOC_AHB_CLK_SRC] = &gcc_pcnoc_ahb_clk_src.clkr, 1226 + [GCC_PCNOC_AHB_CLK] = &pcnoc_clk_src.clkr, 1637 1227 }; 1638 1228 1639 1229 static const struct qcom_reset_map gcc_ipq4019_resets[] = { ··· 1724 1294 .reg_bits = 32, 1725 1295 .reg_stride = 4, 1726 1296 .val_bits = 32, 1727 - .max_register = 0x2dfff, 1297 + .max_register = 0x2ffff, 1728 1298 .fast_io = true, 1729 1299 }; 1730 1300 ··· 1742 1312 }; 1743 1313 MODULE_DEVICE_TABLE(of, gcc_ipq4019_match_table); 1744 1314 1315 + static int 1316 + gcc_ipq4019_cpu_clk_notifier_fn(struct notifier_block *nb, 1317 + unsigned long action, void *data) 1318 + { 1319 + int err = 0; 1320 + 1321 + if (action == PRE_RATE_CHANGE) 1322 + err = clk_rcg2_ops.set_parent(&apps_clk_src.clkr.hw, 1323 + gcc_ipq4019_cpu_safe_parent); 1324 + 1325 + return notifier_from_errno(err); 1326 + } 1327 + 1328 + static struct notifier_block gcc_ipq4019_cpu_clk_notifier = { 1329 + .notifier_call = gcc_ipq4019_cpu_clk_notifier_fn, 1330 + }; 1331 + 1745 1332 static int gcc_ipq4019_probe(struct platform_device *pdev) 1746 1333 { 1747 - struct device *dev = &pdev->dev; 1334 + int err; 1748 1335 1749 - clk_register_fixed_rate(dev, "fepll125", "xo", 0, 200000000); 1750 - clk_register_fixed_rate(dev, "fepll125dly", "xo", 0, 200000000); 1751 - clk_register_fixed_rate(dev, "fepllwcss2g", "xo", 0, 200000000); 1752 - clk_register_fixed_rate(dev, "fepllwcss5g", "xo", 0, 200000000); 1753 - clk_register_fixed_rate(dev, "fepll200", "xo", 0, 200000000); 1754 - clk_register_fixed_rate(dev, "fepll500", "xo", 0, 200000000); 1755 - clk_register_fixed_rate(dev, "ddrpllapss", "xo", 0, 666000000); 1336 + err = qcom_cc_probe(pdev, &gcc_ipq4019_desc); 1337 + if (err) 1338 + return err; 1756 1339 1757 - return qcom_cc_probe(pdev, &gcc_ipq4019_desc); 1340 + return clk_notifier_register(apps_clk_src.clkr.hw.clk, 1341 + &gcc_ipq4019_cpu_clk_notifier); 1342 + } 1343 + 1344 + static int gcc_ipq4019_remove(struct platform_device *pdev) 1345 + { 1346 + return clk_notifier_unregister(apps_clk_src.clkr.hw.clk, 1347 + &gcc_ipq4019_cpu_clk_notifier); 1758 1348 } 1759 1349 1760 1350 static struct platform_driver gcc_ipq4019_driver = { 1761 1351 .probe = gcc_ipq4019_probe, 1352 + .remove = gcc_ipq4019_remove, 1762 1353 .driver = { 1763 1354 .name = "qcom,gcc-ipq4019", 1764 1355 .of_match_table = gcc_ipq4019_match_table,
+22 -5
drivers/clk/renesas/clk-mstp.c
··· 37 37 * @smstpcr: module stop control register 38 38 * @mstpsr: module stop status register (optional) 39 39 * @lock: protects writes to SMSTPCR 40 + * @width_8bit: registers are 8-bit, not 32-bit 40 41 */ 41 42 struct mstp_clock_group { 42 43 struct clk_onecell_data data; 43 44 void __iomem *smstpcr; 44 45 void __iomem *mstpsr; 45 46 spinlock_t lock; 47 + bool width_8bit; 46 48 }; 47 49 48 50 /** ··· 61 59 62 60 #define to_mstp_clock(_hw) container_of(_hw, struct mstp_clock, hw) 63 61 62 + static inline u32 cpg_mstp_read(struct mstp_clock_group *group, 63 + u32 __iomem *reg) 64 + { 65 + return group->width_8bit ? readb(reg) : clk_readl(reg); 66 + } 67 + 68 + static inline void cpg_mstp_write(struct mstp_clock_group *group, u32 val, 69 + u32 __iomem *reg) 70 + { 71 + group->width_8bit ? writeb(val, reg) : clk_writel(val, reg); 72 + } 73 + 64 74 static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable) 65 75 { 66 76 struct mstp_clock *clock = to_mstp_clock(hw); ··· 84 70 85 71 spin_lock_irqsave(&group->lock, flags); 86 72 87 - value = clk_readl(group->smstpcr); 73 + value = cpg_mstp_read(group, group->smstpcr); 88 74 if (enable) 89 75 value &= ~bitmask; 90 76 else 91 77 value |= bitmask; 92 - clk_writel(value, group->smstpcr); 78 + cpg_mstp_write(group, value, group->smstpcr); 93 79 94 80 spin_unlock_irqrestore(&group->lock, flags); 95 81 ··· 97 83 return 0; 98 84 99 85 for (i = 1000; i > 0; --i) { 100 - if (!(clk_readl(group->mstpsr) & bitmask)) 86 + if (!(cpg_mstp_read(group, group->mstpsr) & bitmask)) 101 87 break; 102 88 cpu_relax(); 103 89 } ··· 128 114 u32 value; 129 115 130 116 if (group->mstpsr) 131 - value = clk_readl(group->mstpsr); 117 + value = cpg_mstp_read(group, group->mstpsr); 132 118 else 133 - value = clk_readl(group->smstpcr); 119 + value = cpg_mstp_read(group, group->smstpcr); 134 120 135 121 return !(value & BIT(clock->bit_index)); 136 122 } ··· 201 187 kfree(clks); 202 188 return; 203 189 } 190 + 191 + if (of_device_is_compatible(np, "renesas,r7s72100-mstp-clocks")) 192 + group->width_8bit = true; 204 193 205 194 for (i = 0; i < MSTP_MAX_CLOCKS; ++i) 206 195 clks[i] = ERR_PTR(-ENOENT);
+11
include/dt-bindings/clock/qcom,gcc-ipq4019.h
··· 81 81 #define GCC_WCSS5G_CLK 62 82 82 #define GCC_WCSS5G_REF_CLK 63 83 83 #define GCC_WCSS5G_RTC_CLK 64 84 + #define GCC_APSS_DDRPLL_VCO 65 85 + #define GCC_SDCC_PLLDIV_CLK 66 86 + #define GCC_FEPLL_VCO 67 87 + #define GCC_FEPLL125_CLK 68 88 + #define GCC_FEPLL125DLY_CLK 69 89 + #define GCC_FEPLL200_CLK 70 90 + #define GCC_FEPLL500_CLK 71 91 + #define GCC_FEPLL_WCSS2G_CLK 72 92 + #define GCC_FEPLL_WCSS5G_CLK 73 93 + #define GCC_APSS_CPU_PLLDIV_CLK 74 94 + #define GCC_PCNOC_AHB_CLK_SRC 75 84 95 85 96 #define WIFI0_CPU_INIT_RESET 0 86 97 #define WIFI0_RADIO_SRIF_RESET 1
+38 -2
include/dt-bindings/clock/qcom,rpmcc.h
··· 14 14 #ifndef _DT_BINDINGS_CLK_MSM_RPMCC_H 15 15 #define _DT_BINDINGS_CLK_MSM_RPMCC_H 16 16 17 - /* apq8064 */ 17 + /* RPM clocks */ 18 18 #define RPM_PXO_CLK 0 19 19 #define RPM_PXO_A_CLK 1 20 20 #define RPM_CXO_CLK 2 ··· 38 38 #define RPM_SFPB_CLK 20 39 39 #define RPM_SFPB_A_CLK 21 40 40 41 - /* msm8916 */ 41 + /* SMD RPM clocks */ 42 42 #define RPM_SMD_XO_CLK_SRC 0 43 43 #define RPM_SMD_XO_A_CLK_SRC 1 44 44 #define RPM_SMD_PCNOC_CLK 2 ··· 65 65 #define RPM_SMD_RF_CLK1_A_PIN 23 66 66 #define RPM_SMD_RF_CLK2_PIN 24 67 67 #define RPM_SMD_RF_CLK2_A_PIN 25 68 + #define RPM_SMD_PNOC_CLK 26 69 + #define RPM_SMD_PNOC_A_CLK 27 70 + #define RPM_SMD_CNOC_CLK 28 71 + #define RPM_SMD_CNOC_A_CLK 29 72 + #define RPM_SMD_MMSSNOC_AHB_CLK 30 73 + #define RPM_SMD_MMSSNOC_AHB_A_CLK 31 74 + #define RPM_SMD_GFX3D_CLK_SRC 32 75 + #define RPM_SMD_GFX3D_A_CLK_SRC 33 76 + #define RPM_SMD_OCMEMGX_CLK 34 77 + #define RPM_SMD_OCMEMGX_A_CLK 35 78 + #define RPM_SMD_CXO_D0 36 79 + #define RPM_SMD_CXO_D0_A 37 80 + #define RPM_SMD_CXO_D1 38 81 + #define RPM_SMD_CXO_D1_A 39 82 + #define RPM_SMD_CXO_A0 40 83 + #define RPM_SMD_CXO_A0_A 41 84 + #define RPM_SMD_CXO_A1 42 85 + #define RPM_SMD_CXO_A1_A 43 86 + #define RPM_SMD_CXO_A2 44 87 + #define RPM_SMD_CXO_A2_A 45 88 + #define RPM_SMD_DIV_CLK1 46 89 + #define RPM_SMD_DIV_A_CLK1 47 90 + #define RPM_SMD_DIV_CLK2 48 91 + #define RPM_SMD_DIV_A_CLK2 49 92 + #define RPM_SMD_DIFF_CLK 50 93 + #define RPM_SMD_DIFF_A_CLK 51 94 + #define RPM_SMD_CXO_D0_PIN 52 95 + #define RPM_SMD_CXO_D0_A_PIN 53 96 + #define RPM_SMD_CXO_D1_PIN 54 97 + #define RPM_SMD_CXO_D1_A_PIN 55 98 + #define RPM_SMD_CXO_A0_PIN 56 99 + #define RPM_SMD_CXO_A0_A_PIN 57 100 + #define RPM_SMD_CXO_A1_PIN 58 101 + #define RPM_SMD_CXO_A1_A_PIN 59 102 + #define RPM_SMD_CXO_A2_PIN 60 103 + #define RPM_SMD_CXO_A2_A_PIN 61 68 104 69 105 #endif
+39
include/dt-bindings/clock/stm32fx-clock.h
··· 1 + /* 2 + * stm32fx-clock.h 3 + * 4 + * Copyright (C) 2016 STMicroelectronics 5 + * Author: Gabriel Fernandez for STMicroelectronics. 6 + * License terms: GNU General Public License (GPL), version 2 7 + */ 8 + 9 + /* 10 + * List of clocks wich are not derived from system clock (SYSCLOCK) 11 + * 12 + * The index of these clocks is the secondary index of DT bindings 13 + * (see Documentatoin/devicetree/bindings/clock/st,stm32-rcc.txt) 14 + * 15 + * e.g: 16 + <assigned-clocks = <&rcc 1 CLK_LSE>; 17 + */ 18 + 19 + #ifndef _DT_BINDINGS_CLK_STMFX_H 20 + #define _DT_BINDINGS_CLK_STMFX_H 21 + 22 + #define SYSTICK 0 23 + #define FCLK 1 24 + #define CLK_LSI 2 25 + #define CLK_LSE 3 26 + #define CLK_HSE_RTC 4 27 + #define CLK_RTC 5 28 + #define PLL_VCO_I2S 6 29 + #define PLL_VCO_SAI 7 30 + #define CLK_LCD 8 31 + #define CLK_I2S 9 32 + #define CLK_SAI1 10 33 + #define CLK_SAI2 11 34 + #define CLK_I2SQ_PDIV 12 35 + #define CLK_SAIQ_PDIV 13 36 + 37 + #define END_PRIMARY_CLK 14 38 + 39 + #endif