1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2025 MediaTek Inc. 4 * Guangjie Song <guangjie.song@mediatek.com> 5 * Copyright (c) 2025 Collabora Ltd. 6 * Laura Nao <laura.nao@collabora.com> 7 */ 8 #include <dt-bindings/clock/mediatek,mt8196-clock.h> 9 10 #include <linux/clk-provider.h> 11 #include <linux/module.h> 12 #include <linux/of_device.h> 13 #include <linux/platform_device.h> 14 15 #include "clk-gate.h" 16 #include "clk-mtk.h" 17 18 static const struct mtk_gate_regs peri_ao0_cg_regs = { 19 .set_ofs = 0x24, 20 .clr_ofs = 0x28, 21 .sta_ofs = 0x10, 22 }; 23 24 static const struct mtk_gate_regs peri_ao1_cg_regs = { 25 .set_ofs = 0x2c, 26 .clr_ofs = 0x30, 27 .sta_ofs = 0x14, 28 }; 29 30 static const struct mtk_gate_regs peri_ao1_hwv_regs = { 31 .set_ofs = 0x0008, 32 .clr_ofs = 0x000c, 33 .sta_ofs = 0x2c04, 34 }; 35 36 static const struct mtk_gate_regs peri_ao2_cg_regs = { 37 .set_ofs = 0x34, 38 .clr_ofs = 0x38, 39 .sta_ofs = 0x18, 40 }; 41 42 #define GATE_PERI_AO0(_id, _name, _parent, _shift) { \ 43 .id = _id, \ 44 .name = _name, \ 45 .parent_name = _parent, \ 46 .regs = &peri_ao0_cg_regs, \ 47 .shift = _shift, \ 48 .ops = &mtk_clk_gate_ops_setclr, \ 49 } 50 51 #define GATE_PERI_AO1(_id, _name, _parent, _shift) { \ 52 .id = _id, \ 53 .name = _name, \ 54 .parent_name = _parent, \ 55 .regs = &peri_ao1_cg_regs, \ 56 .shift = _shift, \ 57 .ops = &mtk_clk_gate_ops_setclr, \ 58 } 59 60 #define GATE_HWV_PERI_AO1(_id, _name, _parent, _shift) {\ 61 .id = _id, \ 62 .name = _name, \ 63 .parent_name = _parent, \ 64 .regs = &peri_ao1_cg_regs, \ 65 .hwv_regs = &peri_ao1_hwv_regs, \ 66 .shift = _shift, \ 67 .ops = &mtk_clk_gate_hwv_ops_setclr, \ 68 } 69 70 #define GATE_PERI_AO2(_id, _name, _parent, _shift) { \ 71 .id = _id, \ 72 .name = _name, \ 73 .parent_name = _parent, \ 74 .regs = &peri_ao2_cg_regs, \ 75 .shift = _shift, \ 76 .ops = &mtk_clk_gate_ops_setclr, \ 77 } 78 79 static const struct mtk_gate peri_ao_clks[] = { 80 /* PERI_AO0 */ 81 GATE_PERI_AO0(CLK_PERI_AO_UART0_BCLK, "peri_ao_uart0_bclk", "uart", 0), 82 GATE_PERI_AO0(CLK_PERI_AO_UART1_BCLK, "peri_ao_uart1_bclk", "uart", 1), 83 GATE_PERI_AO0(CLK_PERI_AO_UART2_BCLK, "peri_ao_uart2_bclk", "uart", 2), 84 GATE_PERI_AO0(CLK_PERI_AO_UART3_BCLK, "peri_ao_uart3_bclk", "uart", 3), 85 GATE_PERI_AO0(CLK_PERI_AO_UART4_BCLK, "peri_ao_uart4_bclk", "uart", 4), 86 GATE_PERI_AO0(CLK_PERI_AO_UART5_BCLK, "peri_ao_uart5_bclk", "uart", 5), 87 GATE_PERI_AO0(CLK_PERI_AO_PWM_X16W_HCLK, "peri_ao_pwm_x16w", "p_axi", 12), 88 GATE_PERI_AO0(CLK_PERI_AO_PWM_X16W_BCLK, "peri_ao_pwm_x16w_bclk", "pwm", 13), 89 GATE_PERI_AO0(CLK_PERI_AO_PWM_PWM_BCLK0, "peri_ao_pwm_pwm_bclk0", "pwm", 14), 90 GATE_PERI_AO0(CLK_PERI_AO_PWM_PWM_BCLK1, "peri_ao_pwm_pwm_bclk1", "pwm", 15), 91 GATE_PERI_AO0(CLK_PERI_AO_PWM_PWM_BCLK2, "peri_ao_pwm_pwm_bclk2", "pwm", 16), 92 GATE_PERI_AO0(CLK_PERI_AO_PWM_PWM_BCLK3, "peri_ao_pwm_pwm_bclk3", "pwm", 17), 93 /* PERI_AO1 */ 94 GATE_HWV_PERI_AO1(CLK_PERI_AO_SPI0_BCLK, "peri_ao_spi0_bclk", "spi0_b", 0), 95 GATE_HWV_PERI_AO1(CLK_PERI_AO_SPI1_BCLK, "peri_ao_spi1_bclk", "spi1_b", 2), 96 GATE_HWV_PERI_AO1(CLK_PERI_AO_SPI2_BCLK, "peri_ao_spi2_bclk", "spi2_b", 3), 97 GATE_HWV_PERI_AO1(CLK_PERI_AO_SPI3_BCLK, "peri_ao_spi3_bclk", "spi3_b", 4), 98 GATE_HWV_PERI_AO1(CLK_PERI_AO_SPI4_BCLK, "peri_ao_spi4_bclk", "spi4_b", 5), 99 GATE_HWV_PERI_AO1(CLK_PERI_AO_SPI5_BCLK, "peri_ao_spi5_bclk", "spi5_b", 6), 100 GATE_HWV_PERI_AO1(CLK_PERI_AO_SPI6_BCLK, "peri_ao_spi6_bclk", "spi6_b", 7), 101 GATE_HWV_PERI_AO1(CLK_PERI_AO_SPI7_BCLK, "peri_ao_spi7_bclk", "spi7_b", 8), 102 GATE_PERI_AO1(CLK_PERI_AO_FLASHIF_FLASH, "peri_ao_flashif_flash", "peri_ao_flashif_27m", 103 18), 104 GATE_PERI_AO1(CLK_PERI_AO_FLASHIF_27M, "peri_ao_flashif_27m", "sflash", 19), 105 GATE_PERI_AO1(CLK_PERI_AO_FLASHIF_DRAM, "peri_ao_flashif_dram", "p_axi", 20), 106 GATE_PERI_AO1(CLK_PERI_AO_FLASHIF_AXI, "peri_ao_flashif_axi", "peri_ao_flashif_dram", 21), 107 GATE_PERI_AO1(CLK_PERI_AO_FLASHIF_BCLK, "peri_ao_flashif_bclk", "p_axi", 22), 108 GATE_PERI_AO1(CLK_PERI_AO_AP_DMA_X32W_BCLK, "peri_ao_ap_dma_x32w_bclk", "p_axi", 26), 109 /* PERI_AO2 */ 110 GATE_PERI_AO2(CLK_PERI_AO_MSDC1_MSDC_SRC, "peri_ao_msdc1_msdc_src", "msdc30_1", 1), 111 GATE_PERI_AO2(CLK_PERI_AO_MSDC1_HCLK, "peri_ao_msdc1", "peri_ao_msdc1_axi", 2), 112 GATE_PERI_AO2(CLK_PERI_AO_MSDC1_AXI, "peri_ao_msdc1_axi", "p_axi", 3), 113 GATE_PERI_AO2(CLK_PERI_AO_MSDC1_HCLK_WRAP, "peri_ao_msdc1_h_wrap", "peri_ao_msdc1", 4), 114 GATE_PERI_AO2(CLK_PERI_AO_MSDC2_MSDC_SRC, "peri_ao_msdc2_msdc_src", "msdc30_2", 10), 115 GATE_PERI_AO2(CLK_PERI_AO_MSDC2_HCLK, "peri_ao_msdc2", "peri_ao_msdc2_axi", 11), 116 GATE_PERI_AO2(CLK_PERI_AO_MSDC2_AXI, "peri_ao_msdc2_axi", "p_axi", 12), 117 GATE_PERI_AO2(CLK_PERI_AO_MSDC2_HCLK_WRAP, "peri_ao_msdc2_h_wrap", "peri_ao_msdc2", 13), 118 }; 119 120 static const struct mtk_clk_desc peri_ao_mcd = { 121 .clks = peri_ao_clks, 122 .num_clks = ARRAY_SIZE(peri_ao_clks), 123 }; 124 125 static const struct of_device_id of_match_clk_mt8196_peri_ao[] = { 126 { .compatible = "mediatek,mt8196-pericfg-ao", .data = &peri_ao_mcd }, 127 { /* sentinel */ } 128 }; 129 MODULE_DEVICE_TABLE(of, of_match_clk_mt8196_peri_ao); 130 131 static struct platform_driver clk_mt8196_peri_ao_drv = { 132 .probe = mtk_clk_simple_probe, 133 .remove = mtk_clk_simple_remove, 134 .driver = { 135 .name = "clk-mt8196-peri-ao", 136 .of_match_table = of_match_clk_mt8196_peri_ao, 137 }, 138 }; 139 140 MODULE_DESCRIPTION("MediaTek MT8196 pericfg_ao clock controller driver"); 141 module_platform_driver(clk_mt8196_peri_ao_drv); 142 MODULE_LICENSE("GPL"); 143