.. | .. |
---|
| 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) |
---|