| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (c) 2016 MediaTek Inc. |
|---|
| 3 | 4 | * Author: Kevin Chen <kevin-cw.chen@mediatek.com> |
|---|
| 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 version 2 as |
|---|
| 7 | | - * published by the Free Software Foundation. |
|---|
| 8 | | - * |
|---|
| 9 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 10 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 11 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 12 | | - * GNU General Public License for more details. |
|---|
| 13 | 5 | */ |
|---|
| 14 | 6 | |
|---|
| 15 | 7 | #include <linux/of.h> |
|---|
| .. | .. |
|---|
| 324 | 316 | "univpll_d5", |
|---|
| 325 | 317 | }; |
|---|
| 326 | 318 | |
|---|
| 319 | +/* |
|---|
| 320 | + * Clock mux ddrphycfg is needed by the DRAM controller. We mark it as |
|---|
| 321 | + * critical as otherwise the system will hang after boot. |
|---|
| 322 | + */ |
|---|
| 327 | 323 | static const struct mtk_composite top_muxes[] = { |
|---|
| 328 | 324 | MUX(CLK_TOP_MUX_ULPOSC_AXI_CK_MUX_PRE, "ulposc_axi_ck_mux_pre", |
|---|
| 329 | 325 | ulposc_axi_ck_mux_pre_parents, 0x0040, 3, 1), |
|---|
| .. | .. |
|---|
| 331 | 327 | ulposc_axi_ck_mux_parents, 0x0040, 2, 1), |
|---|
| 332 | 328 | MUX(CLK_TOP_MUX_AXI, "axi_sel", axi_parents, |
|---|
| 333 | 329 | 0x0040, 0, 2), |
|---|
| 334 | | - MUX(CLK_TOP_MUX_DDRPHYCFG, "ddrphycfg_sel", ddrphycfg_parents, |
|---|
| 335 | | - 0x0040, 16, 2), |
|---|
| 330 | + MUX_FLAGS(CLK_TOP_MUX_DDRPHYCFG, "ddrphycfg_sel", ddrphycfg_parents, |
|---|
| 331 | + 0x0040, 16, 2, CLK_IS_CRITICAL | CLK_SET_RATE_PARENT), |
|---|
| 336 | 332 | MUX(CLK_TOP_MUX_MM, "mm_sel", mm_parents, |
|---|
| 337 | 333 | 0x0040, 24, 2), |
|---|
| 338 | 334 | MUX_GATE(CLK_TOP_MUX_PWM, "pwm_sel", pwm_parents, 0x0050, 0, 3, 7), |
|---|
| .. | .. |
|---|
| 389 | 385 | struct clk_onecell_data *clk_data; |
|---|
| 390 | 386 | void __iomem *base; |
|---|
| 391 | 387 | struct device_node *node = pdev->dev.of_node; |
|---|
| 392 | | - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
|---|
| 393 | 388 | |
|---|
| 394 | | - base = devm_ioremap_resource(&pdev->dev, res); |
|---|
| 389 | + base = devm_platform_ioremap_resource(pdev, 0); |
|---|
| 395 | 390 | if (IS_ERR(base)) |
|---|
| 396 | 391 | return PTR_ERR(base); |
|---|
| 397 | 392 | |
|---|
| .. | .. |
|---|
| 424 | 419 | .sta_ofs = 0x00b0, |
|---|
| 425 | 420 | }; |
|---|
| 426 | 421 | |
|---|
| 427 | | -#define GATE_ICG0(_id, _name, _parent, _shift) { \ |
|---|
| 428 | | - .id = _id, \ |
|---|
| 429 | | - .name = _name, \ |
|---|
| 430 | | - .parent_name = _parent, \ |
|---|
| 431 | | - .regs = &infra0_cg_regs, \ |
|---|
| 432 | | - .shift = _shift, \ |
|---|
| 433 | | - .ops = &mtk_clk_gate_ops_setclr, \ |
|---|
| 422 | +#define GATE_ICG0(_id, _name, _parent, _shift) { \ |
|---|
| 423 | + .id = _id, \ |
|---|
| 424 | + .name = _name, \ |
|---|
| 425 | + .parent_name = _parent, \ |
|---|
| 426 | + .regs = &infra0_cg_regs, \ |
|---|
| 427 | + .shift = _shift, \ |
|---|
| 428 | + .ops = &mtk_clk_gate_ops_setclr, \ |
|---|
| 434 | 429 | } |
|---|
| 435 | 430 | |
|---|
| 436 | | -#define GATE_ICG1(_id, _name, _parent, _shift) { \ |
|---|
| 437 | | - .id = _id, \ |
|---|
| 438 | | - .name = _name, \ |
|---|
| 439 | | - .parent_name = _parent, \ |
|---|
| 440 | | - .regs = &infra1_cg_regs, \ |
|---|
| 441 | | - .shift = _shift, \ |
|---|
| 442 | | - .ops = &mtk_clk_gate_ops_setclr, \ |
|---|
| 431 | +#define GATE_ICG1(_id, _name, _parent, _shift) \ |
|---|
| 432 | + GATE_ICG1_FLAGS(_id, _name, _parent, _shift, 0) |
|---|
| 433 | + |
|---|
| 434 | +#define GATE_ICG1_FLAGS(_id, _name, _parent, _shift, _flags) { \ |
|---|
| 435 | + .id = _id, \ |
|---|
| 436 | + .name = _name, \ |
|---|
| 437 | + .parent_name = _parent, \ |
|---|
| 438 | + .regs = &infra1_cg_regs, \ |
|---|
| 439 | + .shift = _shift, \ |
|---|
| 440 | + .ops = &mtk_clk_gate_ops_setclr, \ |
|---|
| 441 | + .flags = _flags, \ |
|---|
| 443 | 442 | } |
|---|
| 444 | 443 | |
|---|
| 445 | | -#define GATE_ICG2(_id, _name, _parent, _shift) { \ |
|---|
| 446 | | - .id = _id, \ |
|---|
| 447 | | - .name = _name, \ |
|---|
| 448 | | - .parent_name = _parent, \ |
|---|
| 449 | | - .regs = &infra2_cg_regs, \ |
|---|
| 450 | | - .shift = _shift, \ |
|---|
| 451 | | - .ops = &mtk_clk_gate_ops_setclr, \ |
|---|
| 444 | +#define GATE_ICG2(_id, _name, _parent, _shift) \ |
|---|
| 445 | + GATE_ICG2_FLAGS(_id, _name, _parent, _shift, 0) |
|---|
| 446 | + |
|---|
| 447 | +#define GATE_ICG2_FLAGS(_id, _name, _parent, _shift, _flags) { \ |
|---|
| 448 | + .id = _id, \ |
|---|
| 449 | + .name = _name, \ |
|---|
| 450 | + .parent_name = _parent, \ |
|---|
| 451 | + .regs = &infra2_cg_regs, \ |
|---|
| 452 | + .shift = _shift, \ |
|---|
| 453 | + .ops = &mtk_clk_gate_ops_setclr, \ |
|---|
| 454 | + .flags = _flags, \ |
|---|
| 452 | 455 | } |
|---|
| 453 | 456 | |
|---|
| 457 | +/* |
|---|
| 458 | + * Clock gates dramc and dramc_b are needed by the DRAM controller. |
|---|
| 459 | + * We mark them as critical as otherwise the system will hang after boot. |
|---|
| 460 | + */ |
|---|
| 454 | 461 | static const struct mtk_gate infra_clks[] = { |
|---|
| 455 | 462 | GATE_ICG0(CLK_INFRA_PMIC_TMR, "infra_pmic_tmr", "ulposc", 0), |
|---|
| 456 | 463 | GATE_ICG0(CLK_INFRA_PMIC_AP, "infra_pmic_ap", "pmicspi_sel", 1), |
|---|
| .. | .. |
|---|
| 505 | 512 | GATE_ICG1(CLK_INFRA_CCIF_AP, "infra_ccif_ap", "axi_sel", 23), |
|---|
| 506 | 513 | GATE_ICG1(CLK_INFRA_AUDIO, "infra_audio", "axi_sel", 25), |
|---|
| 507 | 514 | GATE_ICG1(CLK_INFRA_CCIF_MD, "infra_ccif_md", "axi_sel", 26), |
|---|
| 508 | | - GATE_ICG1(CLK_INFRA_DRAMC_F26M, "infra_dramc_f26m", "clk26m", 31), |
|---|
| 515 | + GATE_ICG1_FLAGS(CLK_INFRA_DRAMC_F26M, "infra_dramc_f26m", |
|---|
| 516 | + "clk26m", 31, CLK_IS_CRITICAL), |
|---|
| 509 | 517 | GATE_ICG2(CLK_INFRA_I2C4, "infra_i2c4", "axi_sel", 0), |
|---|
| 510 | 518 | GATE_ICG2(CLK_INFRA_I2C_APPM, "infra_i2c_appm", "axi_sel", 1), |
|---|
| 511 | 519 | GATE_ICG2(CLK_INFRA_I2C_GPUPM, "infra_i2c_gpupm", "axi_sel", 2), |
|---|
| .. | .. |
|---|
| 516 | 524 | GATE_ICG2(CLK_INFRA_I2C5, "infra_i2c5", "axi_sel", 7), |
|---|
| 517 | 525 | GATE_ICG2(CLK_INFRA_SYS_CIRQ, "infra_sys_cirq", "axi_sel", 8), |
|---|
| 518 | 526 | GATE_ICG2(CLK_INFRA_SPI1, "infra_spi1", "spi_sel", 10), |
|---|
| 519 | | - GATE_ICG2(CLK_INFRA_DRAMC_B_F26M, "infra_dramc_b_f26m", "clk26m", 11), |
|---|
| 527 | + GATE_ICG2_FLAGS(CLK_INFRA_DRAMC_B_F26M, "infra_dramc_b_f26m", |
|---|
| 528 | + "clk26m", 11, CLK_IS_CRITICAL), |
|---|
| 520 | 529 | GATE_ICG2(CLK_INFRA_ANC_MD32, "infra_anc_md32", "anc_md32_sel", 12), |
|---|
| 521 | 530 | GATE_ICG2(CLK_INFRA_ANC_MD32_32K, "infra_anc_md32_32k", "clk26m", 13), |
|---|
| 522 | 531 | GATE_ICG2(CLK_INFRA_DVFS_SPM1, "infra_dvfs_spm1", "axi_sel", 15), |
|---|
| .. | .. |
|---|
| 573 | 582 | |
|---|
| 574 | 583 | static int mtk_infrasys_init(struct platform_device *pdev) |
|---|
| 575 | 584 | { |
|---|
| 576 | | - int r, i; |
|---|
| 585 | + int i; |
|---|
| 577 | 586 | struct device_node *node = pdev->dev.of_node; |
|---|
| 578 | 587 | |
|---|
| 579 | 588 | if (!infra_clk_data) { |
|---|
| .. | .. |
|---|
| 590 | 599 | mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs), |
|---|
| 591 | 600 | infra_clk_data); |
|---|
| 592 | 601 | |
|---|
| 593 | | - r = of_clk_add_provider(node, of_clk_src_onecell_get, infra_clk_data); |
|---|
| 594 | | - if (r) |
|---|
| 595 | | - return r; |
|---|
| 596 | | - |
|---|
| 597 | | - return 0; |
|---|
| 602 | + return of_clk_add_provider(node, of_clk_src_onecell_get, infra_clk_data); |
|---|
| 598 | 603 | } |
|---|
| 599 | 604 | |
|---|
| 600 | 605 | #define MT6797_PLL_FMAX (3000UL * MHZ) |
|---|