1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2022 Collabora Ltd. 4 * Author: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> 5 */ 6 7 #include <dt-bindings/clock/mt8173-clk.h> 8 #include <linux/module.h> 9 #include <linux/platform_device.h> 10 #include "clk-gate.h" 11 #include "clk-mtk.h" 12 #include "reset.h" 13 14 #define GATE_PERI0(_id, _name, _parent, _shift) \ 15 GATE_MTK(_id, _name, _parent, &peri0_cg_regs, \ 16 _shift, &mtk_clk_gate_ops_setclr) 17 18 #define GATE_PERI1(_id, _name, _parent, _shift) \ 19 GATE_MTK(_id, _name, _parent, &peri1_cg_regs, \ 20 _shift, &mtk_clk_gate_ops_setclr) 21 22 static DEFINE_SPINLOCK(mt8173_clk_lock); 23 24 static const struct mtk_gate_regs peri0_cg_regs = { 25 .set_ofs = 0x0008, 26 .clr_ofs = 0x0010, 27 .sta_ofs = 0x0018, 28 }; 29 30 static const struct mtk_gate_regs peri1_cg_regs = { 31 .set_ofs = 0x000c, 32 .clr_ofs = 0x0014, 33 .sta_ofs = 0x001c, 34 }; 35 36 static const char * const uart_ck_sel_parents[] = { 37 "clk26m", 38 "uart_sel", 39 }; 40 41 static const struct mtk_composite peri_clks[] = { 42 MUX(CLK_PERI_UART0_SEL, "uart0_ck_sel", uart_ck_sel_parents, 0x40c, 0, 1), 43 MUX(CLK_PERI_UART1_SEL, "uart1_ck_sel", uart_ck_sel_parents, 0x40c, 1, 1), 44 MUX(CLK_PERI_UART2_SEL, "uart2_ck_sel", uart_ck_sel_parents, 0x40c, 2, 1), 45 MUX(CLK_PERI_UART3_SEL, "uart3_ck_sel", uart_ck_sel_parents, 0x40c, 3, 1), 46 }; 47 48 static const struct mtk_gate peri_gates[] = { 49 GATE_DUMMY(CLK_DUMMY, "peri_gate_dummy"), 50 /* PERI0 */ 51 GATE_PERI0(CLK_PERI_NFI, "peri_nfi", "axi_sel", 0), 52 GATE_PERI0(CLK_PERI_THERM, "peri_therm", "axi_sel", 1), 53 GATE_PERI0(CLK_PERI_PWM1, "peri_pwm1", "axi_sel", 2), 54 GATE_PERI0(CLK_PERI_PWM2, "peri_pwm2", "axi_sel", 3), 55 GATE_PERI0(CLK_PERI_PWM3, "peri_pwm3", "axi_sel", 4), 56 GATE_PERI0(CLK_PERI_PWM4, "peri_pwm4", "axi_sel", 5), 57 GATE_PERI0(CLK_PERI_PWM5, "peri_pwm5", "axi_sel", 6), 58 GATE_PERI0(CLK_PERI_PWM6, "peri_pwm6", "axi_sel", 7), 59 GATE_PERI0(CLK_PERI_PWM7, "peri_pwm7", "axi_sel", 8), 60 GATE_PERI0(CLK_PERI_PWM, "peri_pwm", "axi_sel", 9), 61 GATE_PERI0(CLK_PERI_USB0, "peri_usb0", "usb20_sel", 10), 62 GATE_PERI0(CLK_PERI_USB1, "peri_usb1", "usb20_sel", 11), 63 GATE_PERI0(CLK_PERI_AP_DMA, "peri_ap_dma", "axi_sel", 12), 64 GATE_PERI0(CLK_PERI_MSDC30_0, "peri_msdc30_0", "msdc50_0_sel", 13), 65 GATE_PERI0(CLK_PERI_MSDC30_1, "peri_msdc30_1", "msdc30_1_sel", 14), 66 GATE_PERI0(CLK_PERI_MSDC30_2, "peri_msdc30_2", "msdc30_2_sel", 15), 67 GATE_PERI0(CLK_PERI_MSDC30_3, "peri_msdc30_3", "msdc30_3_sel", 16), 68 GATE_PERI0(CLK_PERI_NLI_ARB, "peri_nli_arb", "axi_sel", 17), 69 GATE_PERI0(CLK_PERI_IRDA, "peri_irda", "irda_sel", 18), 70 GATE_PERI0(CLK_PERI_UART0, "peri_uart0", "axi_sel", 19), 71 GATE_PERI0(CLK_PERI_UART1, "peri_uart1", "axi_sel", 20), 72 GATE_PERI0(CLK_PERI_UART2, "peri_uart2", "axi_sel", 21), 73 GATE_PERI0(CLK_PERI_UART3, "peri_uart3", "axi_sel", 22), 74 GATE_PERI0(CLK_PERI_I2C0, "peri_i2c0", "axi_sel", 23), 75 GATE_PERI0(CLK_PERI_I2C1, "peri_i2c1", "axi_sel", 24), 76 GATE_PERI0(CLK_PERI_I2C2, "peri_i2c2", "axi_sel", 25), 77 GATE_PERI0(CLK_PERI_I2C3, "peri_i2c3", "axi_sel", 26), 78 GATE_PERI0(CLK_PERI_I2C4, "peri_i2c4", "axi_sel", 27), 79 GATE_PERI0(CLK_PERI_AUXADC, "peri_auxadc", "clk26m", 28), 80 GATE_PERI0(CLK_PERI_SPI0, "peri_spi0", "spi_sel", 29), 81 GATE_PERI0(CLK_PERI_I2C5, "peri_i2c5", "axi_sel", 30), 82 GATE_PERI0(CLK_PERI_NFIECC, "peri_nfiecc", "axi_sel", 31), 83 /* PERI1 */ 84 GATE_PERI1(CLK_PERI_SPI, "peri_spi", "spi_sel", 0), 85 GATE_PERI1(CLK_PERI_IRRX, "peri_irrx", "spi_sel", 1), 86 GATE_PERI1(CLK_PERI_I2C6, "peri_i2c6", "axi_sel", 2), 87 }; 88 89 static u16 pericfg_rst_ofs[] = { 0x0, 0x4 }; 90 91 static const struct mtk_clk_rst_desc clk_rst_desc = { 92 .version = MTK_RST_SIMPLE, 93 .rst_bank_ofs = pericfg_rst_ofs, 94 .rst_bank_nr = ARRAY_SIZE(pericfg_rst_ofs), 95 }; 96 97 static const struct mtk_clk_desc peri_desc = { 98 .clks = peri_gates, 99 .num_clks = ARRAY_SIZE(peri_gates), 100 .composite_clks = peri_clks, 101 .num_composite_clks = ARRAY_SIZE(peri_clks), 102 .clk_lock = &mt8173_clk_lock, 103 .rst_desc = &clk_rst_desc, 104 }; 105 106 static const struct of_device_id of_match_clk_mt8173_pericfg[] = { 107 { .compatible = "mediatek,mt8173-pericfg", .data = &peri_desc }, 108 { /* sentinel */ } 109 }; 110 111 static struct platform_driver clk_mt8173_pericfg_drv = { 112 .driver = { 113 .name = "clk-mt8173-pericfg", 114 .of_match_table = of_match_clk_mt8173_pericfg, 115 }, 116 .probe = mtk_clk_simple_probe, 117 .remove = mtk_clk_simple_remove, 118 }; 119 module_platform_driver(clk_mt8173_pericfg_drv); 120 121 MODULE_DESCRIPTION("MediaTek MT8173 pericfg clocks driver"); 122 MODULE_LICENSE("GPL"); 123