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 #include <dt-bindings/reset/mediatek,mt8196-resets.h> 10 11 #include <linux/clk-provider.h> 12 #include <linux/module.h> 13 #include <linux/of_device.h> 14 #include <linux/platform_device.h> 15 16 #include "clk-gate.h" 17 #include "clk-mtk.h" 18 #include "reset.h" 19 20 #define MT8196_PEXTP_RST0_SET_OFFSET 0x8 21 22 static const struct mtk_gate_regs pext_cg_regs = { 23 .set_ofs = 0x18, 24 .clr_ofs = 0x1c, 25 .sta_ofs = 0x14, 26 }; 27 28 #define GATE_PEXT(_id, _name, _parent, _shift) {\ 29 .id = _id, \ 30 .name = _name, \ 31 .parent_name = _parent, \ 32 .regs = &pext_cg_regs, \ 33 .shift = _shift, \ 34 .ops = &mtk_clk_gate_ops_setclr,\ 35 } 36 37 static const struct mtk_gate pext_clks[] = { 38 GATE_PEXT(CLK_PEXT_PEXTP_MAC_P0_TL, "pext_pm0_tl", "tl", 0), 39 GATE_PEXT(CLK_PEXT_PEXTP_MAC_P0_REF, "pext_pm0_ref", "clk26m", 1), 40 GATE_PEXT(CLK_PEXT_PEXTP_PHY_P0_MCU_BUS, "pext_pp0_mcu_bus", "clk26m", 6), 41 GATE_PEXT(CLK_PEXT_PEXTP_PHY_P0_PEXTP_REF, "pext_pp0_pextp_ref", "clk26m", 7), 42 GATE_PEXT(CLK_PEXT_PEXTP_MAC_P0_AXI_250, "pext_pm0_axi_250", "ufs_pexpt0_mem_sub", 12), 43 GATE_PEXT(CLK_PEXT_PEXTP_MAC_P0_AHB_APB, "pext_pm0_ahb_apb", "ufs_pextp0_axi", 13), 44 GATE_PEXT(CLK_PEXT_PEXTP_MAC_P0_PL_P, "pext_pm0_pl_p", "clk26m", 14), 45 GATE_PEXT(CLK_PEXT_PEXTP_VLP_AO_P0_LP, "pext_pextp_vlp_ao_p0_lp", "clk26m", 19), 46 }; 47 48 static u16 pext_rst_ofs[] = { MT8196_PEXTP_RST0_SET_OFFSET }; 49 50 static u16 pext_rst_idx_map[] = { 51 [MT8196_PEXTP0_RST0_PCIE0_MAC] = 0, 52 [MT8196_PEXTP0_RST0_PCIE0_PHY] = 1, 53 }; 54 55 static const struct mtk_clk_rst_desc pext_rst_desc = { 56 .version = MTK_RST_SET_CLR, 57 .rst_bank_ofs = pext_rst_ofs, 58 .rst_bank_nr = ARRAY_SIZE(pext_rst_ofs), 59 .rst_idx_map = pext_rst_idx_map, 60 .rst_idx_map_nr = ARRAY_SIZE(pext_rst_idx_map), 61 }; 62 63 static const struct mtk_clk_desc pext_mcd = { 64 .clks = pext_clks, 65 .num_clks = ARRAY_SIZE(pext_clks), 66 .rst_desc = &pext_rst_desc, 67 }; 68 69 static const struct mtk_gate pext1_clks[] = { 70 GATE_PEXT(CLK_PEXT1_PEXTP_MAC_P1_TL, "pext1_pm1_tl", "tl_p1", 0), 71 GATE_PEXT(CLK_PEXT1_PEXTP_MAC_P1_REF, "pext1_pm1_ref", "clk26m", 1), 72 GATE_PEXT(CLK_PEXT1_PEXTP_MAC_P2_TL, "pext1_pm2_tl", "tl_p2", 2), 73 GATE_PEXT(CLK_PEXT1_PEXTP_MAC_P2_REF, "pext1_pm2_ref", "clk26m", 3), 74 GATE_PEXT(CLK_PEXT1_PEXTP_PHY_P1_MCU_BUS, "pext1_pp1_mcu_bus", "clk26m", 8), 75 GATE_PEXT(CLK_PEXT1_PEXTP_PHY_P1_PEXTP_REF, "pext1_pp1_pextp_ref", "clk26m", 9), 76 GATE_PEXT(CLK_PEXT1_PEXTP_PHY_P2_MCU_BUS, "pext1_pp2_mcu_bus", "clk26m", 10), 77 GATE_PEXT(CLK_PEXT1_PEXTP_PHY_P2_PEXTP_REF, "pext1_pp2_pextp_ref", "clk26m", 11), 78 GATE_PEXT(CLK_PEXT1_PEXTP_MAC_P1_AXI_250, "pext1_pm1_axi_250", 79 "pextp1_usb_axi", 16), 80 GATE_PEXT(CLK_PEXT1_PEXTP_MAC_P1_AHB_APB, "pext1_pm1_ahb_apb", 81 "pextp1_usb_mem_sub", 17), 82 GATE_PEXT(CLK_PEXT1_PEXTP_MAC_P1_PL_P, "pext1_pm1_pl_p", "clk26m", 18), 83 GATE_PEXT(CLK_PEXT1_PEXTP_MAC_P2_AXI_250, "pext1_pm2_axi_250", 84 "pextp1_usb_axi", 19), 85 GATE_PEXT(CLK_PEXT1_PEXTP_MAC_P2_AHB_APB, "pext1_pm2_ahb_apb", 86 "pextp1_usb_mem_sub", 20), 87 GATE_PEXT(CLK_PEXT1_PEXTP_MAC_P2_PL_P, "pext1_pm2_pl_p", "clk26m", 21), 88 GATE_PEXT(CLK_PEXT1_PEXTP_VLP_AO_P1_LP, "pext1_pextp_vlp_ao_p1_lp", "clk26m", 26), 89 GATE_PEXT(CLK_PEXT1_PEXTP_VLP_AO_P2_LP, "pext1_pextp_vlp_ao_p2_lp", "clk26m", 27), 90 }; 91 92 static u16 pext1_rst_idx_map[] = { 93 [MT8196_PEXTP1_RST0_PCIE1_MAC] = 0, 94 [MT8196_PEXTP1_RST0_PCIE1_PHY] = 1, 95 [MT8196_PEXTP1_RST0_PCIE2_MAC] = 8, 96 [MT8196_PEXTP1_RST0_PCIE2_PHY] = 9, 97 }; 98 99 static const struct mtk_clk_rst_desc pext1_rst_desc = { 100 .version = MTK_RST_SET_CLR, 101 .rst_bank_ofs = pext_rst_ofs, 102 .rst_bank_nr = ARRAY_SIZE(pext_rst_ofs), 103 .rst_idx_map = pext1_rst_idx_map, 104 .rst_idx_map_nr = ARRAY_SIZE(pext1_rst_idx_map), 105 }; 106 107 static const struct mtk_clk_desc pext1_mcd = { 108 .clks = pext1_clks, 109 .num_clks = ARRAY_SIZE(pext1_clks), 110 .rst_desc = &pext1_rst_desc, 111 }; 112 113 static const struct of_device_id of_match_clk_mt8196_pextp[] = { 114 { .compatible = "mediatek,mt8196-pextp0cfg-ao", .data = &pext_mcd }, 115 { .compatible = "mediatek,mt8196-pextp1cfg-ao", .data = &pext1_mcd }, 116 { /* sentinel */ } 117 }; 118 MODULE_DEVICE_TABLE(of, of_match_clk_mt8196_pextp); 119 120 static struct platform_driver clk_mt8196_pextp_drv = { 121 .probe = mtk_clk_simple_probe, 122 .remove = mtk_clk_simple_remove, 123 .driver = { 124 .name = "clk-mt8196-pextp", 125 .of_match_table = of_match_clk_mt8196_pextp, 126 }, 127 }; 128 129 module_platform_driver(clk_mt8196_pextp_drv); 130 MODULE_DESCRIPTION("MediaTek MT8196 PCIe transmit phy clocks driver"); 131 MODULE_LICENSE("GPL"); 132