| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (c) 2014 MundoReader S.L. |
|---|
| 3 | 4 | * Author: Heiko Stuebner <heiko@sntech.de> |
|---|
| 4 | | - * |
|---|
| 5 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 6 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 7 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 8 | | - * (at your option) any later version. |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 11 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 12 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 13 | | - * GNU General Public License for more details. |
|---|
| 14 | 5 | */ |
|---|
| 15 | 6 | |
|---|
| 16 | 7 | #include <linux/clk.h> |
|---|
| 8 | +#include <linux/module.h> |
|---|
| 17 | 9 | #include <linux/clk-provider.h> |
|---|
| 10 | +#include <linux/io.h> |
|---|
| 18 | 11 | #include <linux/of.h> |
|---|
| 19 | 12 | #include <linux/of_address.h> |
|---|
| 13 | +#include <linux/of_device.h> |
|---|
| 20 | 14 | #include <dt-bindings/clock/rk3188-cru-common.h> |
|---|
| 21 | 15 | #include "clk.h" |
|---|
| 22 | 16 | |
|---|
| 23 | 17 | #define RK3066_GRF_SOC_STATUS 0x15c |
|---|
| 24 | 18 | #define RK3188_GRF_SOC_STATUS 0xac |
|---|
| 25 | | -#define RK3188_UART_FRAC_MAX_PRATE 600000000 |
|---|
| 26 | | -#define RK3188_I2S_FRAC_MAX_PRATE 600000000 |
|---|
| 27 | | -#define RK3188_SPDIF_FRAC_MAX_PRATE 600000000 |
|---|
| 28 | | -#define RK3188_HSADC_FRAC_MAX_PRATE 300000000 |
|---|
| 29 | 19 | |
|---|
| 30 | 20 | enum rk3188_plls { |
|---|
| 31 | 21 | apll, cpll, dpll, gpll, |
|---|
| .. | .. |
|---|
| 208 | 198 | }; |
|---|
| 209 | 199 | |
|---|
| 210 | 200 | PNAME(mux_pll_p) = { "xin24m", "xin32k" }; |
|---|
| 211 | | -PNAME(mux_armclk_p) = { "apll", "gpll_armclk" }; |
|---|
| 212 | 201 | PNAME(mux_ddrphy_p) = { "dpll", "gpll_ddr" }; |
|---|
| 213 | 202 | PNAME(mux_pll_src_gpll_cpll_p) = { "gpll", "cpll" }; |
|---|
| 214 | 203 | PNAME(mux_pll_src_cpll_gpll_p) = { "cpll", "gpll" }; |
|---|
| .. | .. |
|---|
| 313 | 302 | RK2928_CLKSEL_CON(26), 8, 1, MFLAGS, 0, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, |
|---|
| 314 | 303 | RK2928_CLKGATE_CON(0), 2, GFLAGS), |
|---|
| 315 | 304 | |
|---|
| 316 | | - GATE(ACLK_CPU, "aclk_cpu", "aclk_cpu_pre", 0, |
|---|
| 305 | + GATE(ACLK_CPU, "aclk_cpu", "aclk_cpu_pre", CLK_IS_CRITICAL, |
|---|
| 317 | 306 | RK2928_CLKGATE_CON(0), 3, GFLAGS), |
|---|
| 318 | 307 | |
|---|
| 319 | 308 | GATE(0, "atclk_cpu", "pclk_cpu_pre", 0, |
|---|
| 320 | 309 | RK2928_CLKGATE_CON(0), 6, GFLAGS), |
|---|
| 321 | | - GATE(PCLK_CPU, "pclk_cpu", "pclk_cpu_pre", 0, |
|---|
| 310 | + GATE(PCLK_CPU, "pclk_cpu", "pclk_cpu_pre", CLK_IS_CRITICAL, |
|---|
| 322 | 311 | RK2928_CLKGATE_CON(0), 5, GFLAGS), |
|---|
| 323 | | - GATE(HCLK_CPU, "hclk_cpu", "hclk_cpu_pre", CLK_IGNORE_UNUSED, |
|---|
| 312 | + GATE(HCLK_CPU, "hclk_cpu", "hclk_cpu_pre", CLK_IS_CRITICAL, |
|---|
| 324 | 313 | RK2928_CLKGATE_CON(0), 4, GFLAGS), |
|---|
| 325 | 314 | |
|---|
| 326 | 315 | COMPOSITE(0, "aclk_lcdc0_pre", mux_pll_src_cpll_gpll_p, CLK_IGNORE_UNUSED, |
|---|
| .. | .. |
|---|
| 330 | 319 | RK2928_CLKSEL_CON(31), 15, 1, MFLAGS, 8, 5, DFLAGS, |
|---|
| 331 | 320 | RK2928_CLKGATE_CON(1), 4, GFLAGS), |
|---|
| 332 | 321 | |
|---|
| 333 | | - GATE(ACLK_PERI, "aclk_peri", "aclk_peri_pre", 0, |
|---|
| 322 | + GATE(ACLK_PERI, "aclk_peri", "aclk_peri_pre", CLK_IS_CRITICAL, |
|---|
| 334 | 323 | RK2928_CLKGATE_CON(2), 1, GFLAGS), |
|---|
| 335 | | - COMPOSITE_NOMUX(HCLK_PERI, "hclk_peri", "aclk_peri_pre", 0, |
|---|
| 324 | + COMPOSITE_NOMUX(HCLK_PERI, "hclk_peri", "aclk_peri_pre", CLK_IS_CRITICAL, |
|---|
| 336 | 325 | RK2928_CLKSEL_CON(10), 8, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, |
|---|
| 337 | 326 | RK2928_CLKGATE_CON(2), 2, GFLAGS), |
|---|
| 338 | | - COMPOSITE_NOMUX(PCLK_PERI, "pclk_peri", "aclk_peri_pre", 0, |
|---|
| 327 | + COMPOSITE_NOMUX(PCLK_PERI, "pclk_peri", "aclk_peri_pre", CLK_IS_CRITICAL, |
|---|
| 339 | 328 | RK2928_CLKSEL_CON(10), 12, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, |
|---|
| 340 | 329 | RK2928_CLKGATE_CON(2), 3, GFLAGS), |
|---|
| 341 | 330 | |
|---|
| .. | .. |
|---|
| 349 | 338 | |
|---|
| 350 | 339 | GATE(0, "pclkin_cif0", "ext_cif0", 0, |
|---|
| 351 | 340 | RK2928_CLKGATE_CON(3), 3, GFLAGS), |
|---|
| 352 | | - INVERTER(PCLK_CIF0, "pclk_cif0", "pclkin_cif0", |
|---|
| 341 | + INVERTER(0, "pclk_cif0", "pclkin_cif0", |
|---|
| 353 | 342 | RK2928_CLKSEL_CON(30), 8, IFLAGS), |
|---|
| 354 | 343 | |
|---|
| 355 | 344 | FACTOR(0, "xin12m", "xin24m", 0, 1, 2), |
|---|
| .. | .. |
|---|
| 368 | 357 | RK2928_CLKGATE_CON(2), 5, GFLAGS), |
|---|
| 369 | 358 | MUX(SCLK_MAC, "sclk_macref", mux_sclk_macref_p, CLK_SET_RATE_PARENT, |
|---|
| 370 | 359 | RK2928_CLKSEL_CON(21), 4, 1, MFLAGS), |
|---|
| 371 | | - GATE(0, "sclk_mac_lbtest", "sclk_macref", 0, |
|---|
| 360 | + GATE(0, "sclk_mac_lbtest", "sclk_macref", CLK_IS_CRITICAL, |
|---|
| 372 | 361 | RK2928_CLKGATE_CON(2), 12, GFLAGS), |
|---|
| 373 | 362 | |
|---|
| 374 | 363 | COMPOSITE(0, "hsadc_src", mux_pll_src_gpll_cpll_p, 0, |
|---|
| .. | .. |
|---|
| 377 | 366 | COMPOSITE_FRACMUX(0, "hsadc_frac", "hsadc_src", 0, |
|---|
| 378 | 367 | RK2928_CLKSEL_CON(23), 0, |
|---|
| 379 | 368 | RK2928_CLKGATE_CON(2), 7, GFLAGS, |
|---|
| 380 | | - &common_hsadc_out_fracmux, RK3188_HSADC_FRAC_MAX_PRATE), |
|---|
| 369 | + &common_hsadc_out_fracmux), |
|---|
| 381 | 370 | INVERTER(SCLK_HSADC, "sclk_hsadc", "sclk_hsadc_out", |
|---|
| 382 | 371 | RK2928_CLKSEL_CON(22), 7, IFLAGS), |
|---|
| 383 | 372 | |
|---|
| .. | .. |
|---|
| 391 | 380 | COMPOSITE_FRACMUX(0, "spdif_frac", "spdif_pre", CLK_SET_RATE_PARENT, |
|---|
| 392 | 381 | RK2928_CLKSEL_CON(9), 0, |
|---|
| 393 | 382 | RK2928_CLKGATE_CON(0), 14, GFLAGS, |
|---|
| 394 | | - &common_spdif_fracmux, RK3188_SPDIF_FRAC_MAX_PRATE), |
|---|
| 383 | + &common_spdif_fracmux), |
|---|
| 395 | 384 | |
|---|
| 396 | 385 | /* |
|---|
| 397 | 386 | * Clock-Architecture Diagram 4 |
|---|
| .. | .. |
|---|
| 425 | 414 | COMPOSITE_FRACMUX(0, "uart0_frac", "uart0_pre", 0, |
|---|
| 426 | 415 | RK2928_CLKSEL_CON(17), 0, |
|---|
| 427 | 416 | RK2928_CLKGATE_CON(1), 9, GFLAGS, |
|---|
| 428 | | - &common_uart0_fracmux, RK3188_UART_FRAC_MAX_PRATE), |
|---|
| 417 | + &common_uart0_fracmux), |
|---|
| 429 | 418 | COMPOSITE_NOMUX(0, "uart1_pre", "uart_src", 0, |
|---|
| 430 | 419 | RK2928_CLKSEL_CON(14), 0, 7, DFLAGS, |
|---|
| 431 | 420 | RK2928_CLKGATE_CON(1), 10, GFLAGS), |
|---|
| 432 | 421 | COMPOSITE_FRACMUX(0, "uart1_frac", "uart1_pre", 0, |
|---|
| 433 | 422 | RK2928_CLKSEL_CON(18), 0, |
|---|
| 434 | 423 | RK2928_CLKGATE_CON(1), 11, GFLAGS, |
|---|
| 435 | | - &common_uart1_fracmux, RK3188_UART_FRAC_MAX_PRATE), |
|---|
| 424 | + &common_uart1_fracmux), |
|---|
| 436 | 425 | COMPOSITE_NOMUX(0, "uart2_pre", "uart_src", 0, |
|---|
| 437 | 426 | RK2928_CLKSEL_CON(15), 0, 7, DFLAGS, |
|---|
| 438 | 427 | RK2928_CLKGATE_CON(1), 12, GFLAGS), |
|---|
| 439 | 428 | COMPOSITE_FRACMUX(0, "uart2_frac", "uart2_pre", 0, |
|---|
| 440 | 429 | RK2928_CLKSEL_CON(19), 0, |
|---|
| 441 | 430 | RK2928_CLKGATE_CON(1), 13, GFLAGS, |
|---|
| 442 | | - &common_uart2_fracmux, RK3188_UART_FRAC_MAX_PRATE), |
|---|
| 431 | + &common_uart2_fracmux), |
|---|
| 443 | 432 | COMPOSITE_NOMUX(0, "uart3_pre", "uart_src", 0, |
|---|
| 444 | 433 | RK2928_CLKSEL_CON(16), 0, 7, DFLAGS, |
|---|
| 445 | 434 | RK2928_CLKGATE_CON(1), 14, GFLAGS), |
|---|
| 446 | 435 | COMPOSITE_FRACMUX(0, "uart3_frac", "uart3_pre", 0, |
|---|
| 447 | 436 | RK2928_CLKSEL_CON(20), 0, |
|---|
| 448 | 437 | RK2928_CLKGATE_CON(1), 15, GFLAGS, |
|---|
| 449 | | - &common_uart3_fracmux, RK3188_UART_FRAC_MAX_PRATE), |
|---|
| 438 | + &common_uart3_fracmux), |
|---|
| 450 | 439 | |
|---|
| 451 | 440 | GATE(SCLK_JTAG, "jtag", "ext_jtag", 0, RK2928_CLKGATE_CON(1), 3, GFLAGS), |
|---|
| 452 | 441 | |
|---|
| .. | .. |
|---|
| 465 | 454 | GATE(HCLK_ROM, "hclk_rom", "hclk_cpu", 0, RK2928_CLKGATE_CON(5), 6, GFLAGS), |
|---|
| 466 | 455 | GATE(HCLK_I2S0_2CH, "hclk_i2s0_2ch", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 2, GFLAGS), |
|---|
| 467 | 456 | GATE(HCLK_SPDIF, "hclk_spdif", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 1, GFLAGS), |
|---|
| 468 | | - GATE(0, "hclk_cpubus", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 8, GFLAGS), |
|---|
| 457 | + GATE(0, "hclk_cpubus", "hclk_cpu", CLK_IS_CRITICAL, RK2928_CLKGATE_CON(4), 8, GFLAGS), |
|---|
| 469 | 458 | /* hclk_ahb2apb is part of a clk branch */ |
|---|
| 470 | | - GATE(0, "hclk_vio_bus", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 12, GFLAGS), |
|---|
| 459 | + GATE(0, "hclk_vio_bus", "hclk_cpu", CLK_IS_CRITICAL, RK2928_CLKGATE_CON(6), 12, GFLAGS), |
|---|
| 471 | 460 | GATE(HCLK_LCDC0, "hclk_lcdc0", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 1, GFLAGS), |
|---|
| 472 | 461 | GATE(HCLK_LCDC1, "hclk_lcdc1", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 2, GFLAGS), |
|---|
| 473 | 462 | GATE(HCLK_CIF0, "hclk_cif0", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 4, GFLAGS), |
|---|
| .. | .. |
|---|
| 585 | 574 | GATE(CORE_L2C, "core_l2c", "aclk_cpu", CLK_IGNORE_UNUSED, |
|---|
| 586 | 575 | RK2928_CLKGATE_CON(9), 4, GFLAGS), |
|---|
| 587 | 576 | |
|---|
| 588 | | - COMPOSITE(0, "aclk_peri_pre", mux_pll_src_gpll_cpll_p, 0, |
|---|
| 577 | + COMPOSITE(0, "aclk_peri_pre", mux_pll_src_gpll_cpll_p, CLK_IS_CRITICAL, |
|---|
| 589 | 578 | RK2928_CLKSEL_CON(10), 15, 1, MFLAGS, 0, 5, DFLAGS, |
|---|
| 590 | 579 | RK2928_CLKGATE_CON(2), 0, GFLAGS), |
|---|
| 591 | 580 | |
|---|
| .. | .. |
|---|
| 608 | 597 | |
|---|
| 609 | 598 | GATE(0, "pclkin_cif1", "ext_cif1", 0, |
|---|
| 610 | 599 | RK2928_CLKGATE_CON(3), 4, GFLAGS), |
|---|
| 611 | | - INVERTER(PCLK_CIF1, "pclk_cif1", "pclkin_cif1", |
|---|
| 600 | + INVERTER(0, "pclk_cif1", "pclkin_cif1", |
|---|
| 612 | 601 | RK2928_CLKSEL_CON(30), 12, IFLAGS), |
|---|
| 613 | 602 | |
|---|
| 614 | 603 | COMPOSITE(0, "aclk_gpu_src", mux_pll_src_cpll_gpll_p, 0, |
|---|
| .. | .. |
|---|
| 632 | 621 | COMPOSITE_FRACMUX(0, "i2s0_frac", "i2s0_pre", 0, |
|---|
| 633 | 622 | RK2928_CLKSEL_CON(6), 0, |
|---|
| 634 | 623 | RK2928_CLKGATE_CON(0), 8, GFLAGS, |
|---|
| 635 | | - &rk3066a_i2s0_fracmux, RK3188_I2S_FRAC_MAX_PRATE), |
|---|
| 624 | + &rk3066a_i2s0_fracmux), |
|---|
| 636 | 625 | COMPOSITE_NOMUX(0, "i2s1_pre", "i2s_src", 0, |
|---|
| 637 | 626 | RK2928_CLKSEL_CON(3), 0, 7, DFLAGS, |
|---|
| 638 | 627 | RK2928_CLKGATE_CON(0), 9, GFLAGS), |
|---|
| 639 | 628 | COMPOSITE_FRACMUX(0, "i2s1_frac", "i2s1_pre", 0, |
|---|
| 640 | 629 | RK2928_CLKSEL_CON(7), 0, |
|---|
| 641 | 630 | RK2928_CLKGATE_CON(0), 10, GFLAGS, |
|---|
| 642 | | - &rk3066a_i2s1_fracmux, RK3188_I2S_FRAC_MAX_PRATE), |
|---|
| 631 | + &rk3066a_i2s1_fracmux), |
|---|
| 643 | 632 | COMPOSITE_NOMUX(0, "i2s2_pre", "i2s_src", 0, |
|---|
| 644 | 633 | RK2928_CLKSEL_CON(4), 0, 7, DFLAGS, |
|---|
| 645 | 634 | RK2928_CLKGATE_CON(0), 11, GFLAGS), |
|---|
| 646 | 635 | COMPOSITE_FRACMUX(0, "i2s2_frac", "i2s2_pre", 0, |
|---|
| 647 | 636 | RK2928_CLKSEL_CON(8), 0, |
|---|
| 648 | 637 | RK2928_CLKGATE_CON(0), 12, GFLAGS, |
|---|
| 649 | | - &rk3066a_i2s2_fracmux, RK3188_I2S_FRAC_MAX_PRATE), |
|---|
| 638 | + &rk3066a_i2s2_fracmux), |
|---|
| 650 | 639 | |
|---|
| 651 | 640 | GATE(HCLK_I2S1_2CH, "hclk_i2s1_2ch", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 3, GFLAGS), |
|---|
| 652 | 641 | GATE(HCLK_I2S_8CH, "hclk_i2s_8ch", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS), |
|---|
| .. | .. |
|---|
| 690 | 679 | div_rk3188_aclk_core_t, RK2928_CLKGATE_CON(0), 7, GFLAGS), |
|---|
| 691 | 680 | |
|---|
| 692 | 681 | /* do not source aclk_cpu_pre from the apll, to keep complexity down */ |
|---|
| 693 | | - COMPOSITE_NOGATE(0, "aclk_cpu_pre", mux_aclk_cpu_p, CLK_SET_RATE_NO_REPARENT, |
|---|
| 682 | + COMPOSITE_NOGATE(ACLK_CPU_PRE, "aclk_cpu_pre", mux_aclk_cpu_p, CLK_SET_RATE_NO_REPARENT, |
|---|
| 694 | 683 | RK2928_CLKSEL_CON(0), 5, 1, MFLAGS, 0, 5, DFLAGS), |
|---|
| 695 | 684 | DIV(0, "pclk_cpu_pre", "aclk_cpu_pre", 0, |
|---|
| 696 | 685 | RK2928_CLKSEL_CON(1), 12, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO), |
|---|
| .. | .. |
|---|
| 703 | 692 | GATE(CORE_L2C, "core_l2c", "armclk", CLK_IGNORE_UNUSED, |
|---|
| 704 | 693 | RK2928_CLKGATE_CON(9), 4, GFLAGS), |
|---|
| 705 | 694 | |
|---|
| 706 | | - COMPOSITE(0, "aclk_peri_pre", mux_pll_src_cpll_gpll_p, 0, |
|---|
| 695 | + COMPOSITE(0, "aclk_peri_pre", mux_pll_src_cpll_gpll_p, CLK_IS_CRITICAL, |
|---|
| 707 | 696 | RK2928_CLKSEL_CON(10), 15, 1, MFLAGS, 0, 5, DFLAGS, |
|---|
| 708 | 697 | RK2928_CLKGATE_CON(2), 0, GFLAGS), |
|---|
| 709 | 698 | |
|---|
| .. | .. |
|---|
| 740 | 729 | COMPOSITE_FRACMUX(0, "i2s0_frac", "i2s0_pre", CLK_SET_RATE_PARENT, |
|---|
| 741 | 730 | RK2928_CLKSEL_CON(7), 0, |
|---|
| 742 | 731 | RK2928_CLKGATE_CON(0), 10, GFLAGS, |
|---|
| 743 | | - &rk3188_i2s0_fracmux, RK3188_I2S_FRAC_MAX_PRATE), |
|---|
| 732 | + &rk3188_i2s0_fracmux), |
|---|
| 744 | 733 | |
|---|
| 745 | 734 | GATE(0, "hclk_imem0", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS), |
|---|
| 746 | 735 | GATE(0, "hclk_imem1", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 15, GFLAGS), |
|---|
| .. | .. |
|---|
| 755 | 744 | GATE(PCLK_UART1, "pclk_uart1", "hclk_ahb2apb", 0, RK2928_CLKGATE_CON(8), 1, GFLAGS), |
|---|
| 756 | 745 | |
|---|
| 757 | 746 | GATE(ACLK_GPS, "aclk_gps", "aclk_peri", 0, RK2928_CLKGATE_CON(8), 13, GFLAGS), |
|---|
| 758 | | -}; |
|---|
| 759 | | - |
|---|
| 760 | | -static const char *const rk3188_critical_clocks[] __initconst = { |
|---|
| 761 | | - "aclk_cpu", |
|---|
| 762 | | - "aclk_peri", |
|---|
| 763 | | - "hclk_peri", |
|---|
| 764 | | - "pclk_cpu", |
|---|
| 765 | | - "pclk_peri", |
|---|
| 766 | | - "hclk_cpubus", |
|---|
| 767 | | - "hclk_vio_bus", |
|---|
| 768 | | - "hclk_ahb2apb", |
|---|
| 769 | 747 | }; |
|---|
| 770 | 748 | |
|---|
| 771 | 749 | static struct rockchip_clk_provider *__init rk3188_common_clk_init(struct device_node *np) |
|---|
| .. | .. |
|---|
| 800 | 778 | static void __init rk3066a_clk_init(struct device_node *np) |
|---|
| 801 | 779 | { |
|---|
| 802 | 780 | struct rockchip_clk_provider *ctx; |
|---|
| 781 | + struct clk **clks; |
|---|
| 803 | 782 | |
|---|
| 804 | 783 | ctx = rk3188_common_clk_init(np); |
|---|
| 805 | 784 | if (IS_ERR(ctx)) |
|---|
| 806 | 785 | return; |
|---|
| 786 | + clks = ctx->clk_data.clks; |
|---|
| 807 | 787 | |
|---|
| 808 | 788 | rockchip_clk_register_plls(ctx, rk3066_pll_clks, |
|---|
| 809 | 789 | ARRAY_SIZE(rk3066_pll_clks), |
|---|
| .. | .. |
|---|
| 811 | 791 | rockchip_clk_register_branches(ctx, rk3066a_clk_branches, |
|---|
| 812 | 792 | ARRAY_SIZE(rk3066a_clk_branches)); |
|---|
| 813 | 793 | rockchip_clk_register_armclk(ctx, ARMCLK, "armclk", |
|---|
| 814 | | - mux_armclk_p, ARRAY_SIZE(mux_armclk_p), |
|---|
| 794 | + 2, clks[PLL_APLL], clks[PLL_GPLL], |
|---|
| 815 | 795 | &rk3066_cpuclk_data, rk3066_cpuclk_rates, |
|---|
| 816 | 796 | ARRAY_SIZE(rk3066_cpuclk_rates)); |
|---|
| 817 | | - rockchip_clk_protect_critical(rk3188_critical_clocks, |
|---|
| 818 | | - ARRAY_SIZE(rk3188_critical_clocks)); |
|---|
| 819 | 797 | rockchip_clk_of_add_provider(np, ctx); |
|---|
| 820 | 798 | } |
|---|
| 821 | 799 | CLK_OF_DECLARE(rk3066a_cru, "rockchip,rk3066a-cru", rk3066a_clk_init); |
|---|
| .. | .. |
|---|
| 823 | 801 | static void __init rk3188a_clk_init(struct device_node *np) |
|---|
| 824 | 802 | { |
|---|
| 825 | 803 | struct rockchip_clk_provider *ctx; |
|---|
| 826 | | - struct clk *clk1, *clk2; |
|---|
| 804 | + struct clk **clks; |
|---|
| 827 | 805 | unsigned long rate; |
|---|
| 828 | 806 | int ret; |
|---|
| 829 | 807 | |
|---|
| 830 | 808 | ctx = rk3188_common_clk_init(np); |
|---|
| 831 | 809 | if (IS_ERR(ctx)) |
|---|
| 832 | 810 | return; |
|---|
| 811 | + clks = ctx->clk_data.clks; |
|---|
| 833 | 812 | |
|---|
| 834 | 813 | rockchip_clk_register_plls(ctx, rk3188_pll_clks, |
|---|
| 835 | 814 | ARRAY_SIZE(rk3188_pll_clks), |
|---|
| .. | .. |
|---|
| 837 | 816 | rockchip_clk_register_branches(ctx, rk3188_clk_branches, |
|---|
| 838 | 817 | ARRAY_SIZE(rk3188_clk_branches)); |
|---|
| 839 | 818 | rockchip_clk_register_armclk(ctx, ARMCLK, "armclk", |
|---|
| 840 | | - mux_armclk_p, ARRAY_SIZE(mux_armclk_p), |
|---|
| 819 | + 2, clks[PLL_APLL], clks[PLL_GPLL], |
|---|
| 841 | 820 | &rk3188_cpuclk_data, rk3188_cpuclk_rates, |
|---|
| 842 | 821 | ARRAY_SIZE(rk3188_cpuclk_rates)); |
|---|
| 843 | 822 | |
|---|
| 844 | 823 | /* reparent aclk_cpu_pre from apll */ |
|---|
| 845 | | - clk1 = __clk_lookup("aclk_cpu_pre"); |
|---|
| 846 | | - clk2 = __clk_lookup("gpll"); |
|---|
| 847 | | - if (clk1 && clk2) { |
|---|
| 848 | | - rate = clk_get_rate(clk1); |
|---|
| 824 | + if (clks[ACLK_CPU_PRE] && clks[PLL_GPLL]) { |
|---|
| 825 | + rate = clk_get_rate(clks[ACLK_CPU_PRE]); |
|---|
| 849 | 826 | |
|---|
| 850 | | - ret = clk_set_parent(clk1, clk2); |
|---|
| 827 | + ret = clk_set_parent(clks[ACLK_CPU_PRE], clks[PLL_GPLL]); |
|---|
| 851 | 828 | if (ret < 0) |
|---|
| 852 | 829 | pr_warn("%s: could not reparent aclk_cpu_pre to gpll\n", |
|---|
| 853 | 830 | __func__); |
|---|
| 854 | 831 | |
|---|
| 855 | | - clk_set_rate(clk1, rate); |
|---|
| 832 | + clk_set_rate(clks[ACLK_CPU_PRE], rate); |
|---|
| 856 | 833 | } else { |
|---|
| 857 | 834 | pr_warn("%s: missing clocks to reparent aclk_cpu_pre to gpll\n", |
|---|
| 858 | 835 | __func__); |
|---|
| 859 | 836 | } |
|---|
| 860 | 837 | |
|---|
| 861 | | - rockchip_clk_protect_critical(rk3188_critical_clocks, |
|---|
| 862 | | - ARRAY_SIZE(rk3188_critical_clocks)); |
|---|
| 863 | 838 | rockchip_clk_of_add_provider(np, ctx); |
|---|
| 864 | 839 | } |
|---|
| 865 | 840 | CLK_OF_DECLARE(rk3188a_cru, "rockchip,rk3188a-cru", rk3188a_clk_init); |
|---|
| .. | .. |
|---|
| 885 | 860 | rk3188a_clk_init(np); |
|---|
| 886 | 861 | } |
|---|
| 887 | 862 | CLK_OF_DECLARE(rk3188_cru, "rockchip,rk3188-cru", rk3188_clk_init); |
|---|
| 863 | + |
|---|
| 864 | +struct clk_rk3188_inits { |
|---|
| 865 | + void (*inits)(struct device_node *np); |
|---|
| 866 | +}; |
|---|
| 867 | + |
|---|
| 868 | +static const struct clk_rk3188_inits clk_rk3066a_init = { |
|---|
| 869 | + .inits = rk3066a_clk_init, |
|---|
| 870 | +}; |
|---|
| 871 | + |
|---|
| 872 | +static const struct clk_rk3188_inits clk_rk3188a_init = { |
|---|
| 873 | + .inits = rk3188a_clk_init, |
|---|
| 874 | +}; |
|---|
| 875 | + |
|---|
| 876 | +static const struct clk_rk3188_inits clk_rk3188_init = { |
|---|
| 877 | + .inits = rk3188_clk_init, |
|---|
| 878 | +}; |
|---|
| 879 | + |
|---|
| 880 | +static const struct of_device_id clk_rk3188_match_table[] = { |
|---|
| 881 | + { |
|---|
| 882 | + .compatible = "rockchip,rk3066a-cru", |
|---|
| 883 | + .data = &clk_rk3066a_init, |
|---|
| 884 | + }, { |
|---|
| 885 | + .compatible = "rockchip,rk3188a-cru", |
|---|
| 886 | + .data = &clk_rk3188a_init, |
|---|
| 887 | + }, { |
|---|
| 888 | + .compatible = "rockchip,rk3188-cru", |
|---|
| 889 | + .data = &rk3188_clk_init, |
|---|
| 890 | + }, |
|---|
| 891 | + { } |
|---|
| 892 | +}; |
|---|
| 893 | +MODULE_DEVICE_TABLE(of, clk_rk3188_match_table); |
|---|
| 894 | + |
|---|
| 895 | +static int __init clk_rk3188_probe(struct platform_device *pdev) |
|---|
| 896 | +{ |
|---|
| 897 | + struct device_node *np = pdev->dev.of_node; |
|---|
| 898 | + const struct of_device_id *match; |
|---|
| 899 | + const struct clk_rk3188_inits *init_data; |
|---|
| 900 | + |
|---|
| 901 | + match = of_match_device(clk_rk3188_match_table, &pdev->dev); |
|---|
| 902 | + if (!match || !match->data) |
|---|
| 903 | + return -EINVAL; |
|---|
| 904 | + |
|---|
| 905 | + init_data = match->data; |
|---|
| 906 | + if (init_data->inits) |
|---|
| 907 | + init_data->inits(np); |
|---|
| 908 | + |
|---|
| 909 | + return 0; |
|---|
| 910 | +} |
|---|
| 911 | + |
|---|
| 912 | +static struct platform_driver clk_rk3188_driver = { |
|---|
| 913 | + .driver = { |
|---|
| 914 | + .name = "clk-rk3188", |
|---|
| 915 | + .of_match_table = clk_rk3188_match_table, |
|---|
| 916 | + }, |
|---|
| 917 | +}; |
|---|
| 918 | +builtin_platform_driver_probe(clk_rk3188_driver, clk_rk3188_probe); |
|---|
| 919 | + |
|---|
| 920 | +MODULE_DESCRIPTION("Rockchip RK3188 Clock Driver"); |
|---|
| 921 | +MODULE_LICENSE("GPL"); |
|---|