| 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 mdp0_cg_regs = { |
| 19 | .set_ofs = 0x104, |
| 20 | .clr_ofs = 0x108, |
| 21 | .sta_ofs = 0x100, |
| 22 | }; |
| 23 | |
| 24 | static const struct mtk_gate_regs mdp1_cg_regs = { |
| 25 | .set_ofs = 0x114, |
| 26 | .clr_ofs = 0x118, |
| 27 | .sta_ofs = 0x110, |
| 28 | }; |
| 29 | |
| 30 | static const struct mtk_gate_regs mdp2_cg_regs = { |
| 31 | .set_ofs = 0x124, |
| 32 | .clr_ofs = 0x128, |
| 33 | .sta_ofs = 0x120, |
| 34 | }; |
| 35 | |
| 36 | #define GATE_MDP0(_id, _name, _parent, _shift) { \ |
| 37 | .id = _id, \ |
| 38 | .name = _name, \ |
| 39 | .parent_name = _parent, \ |
| 40 | .regs = &mdp0_cg_regs, \ |
| 41 | .shift = _shift, \ |
| 42 | .flags = CLK_OPS_PARENT_ENABLE, \ |
| 43 | .ops = &mtk_clk_gate_ops_setclr, \ |
| 44 | } |
| 45 | |
| 46 | #define GATE_MDP1(_id, _name, _parent, _shift) { \ |
| 47 | .id = _id, \ |
| 48 | .name = _name, \ |
| 49 | .parent_name = _parent, \ |
| 50 | .regs = &mdp1_cg_regs, \ |
| 51 | .shift = _shift, \ |
| 52 | .ops = &mtk_clk_gate_ops_setclr, \ |
| 53 | } |
| 54 | |
| 55 | #define GATE_MDP2(_id, _name, _parent, _shift) { \ |
| 56 | .id = _id, \ |
| 57 | .name = _name, \ |
| 58 | .parent_name = _parent, \ |
| 59 | .regs = &mdp2_cg_regs, \ |
| 60 | .shift = _shift, \ |
| 61 | .flags = CLK_OPS_PARENT_ENABLE, \ |
| 62 | .ops = &mtk_clk_gate_ops_setclr, \ |
| 63 | } |
| 64 | |
| 65 | static const struct mtk_gate mdp1_clks[] = { |
| 66 | /* MDP1-0 */ |
| 67 | GATE_MDP0(CLK_MDP1_MDP_MUTEX0, "mdp1_mdp_mutex0" , "mdp" , 0), |
| 68 | GATE_MDP0(CLK_MDP1_SMI0, "mdp1_smi0" , "mdp" , 1), |
| 69 | GATE_MDP0(CLK_MDP1_APB_BUS, "mdp1_apb_bus" , "mdp" , 2), |
| 70 | GATE_MDP0(CLK_MDP1_MDP_RDMA0, "mdp1_mdp_rdma0" , "mdp" , 3), |
| 71 | GATE_MDP0(CLK_MDP1_MDP_RDMA1, "mdp1_mdp_rdma1" , "mdp" , 4), |
| 72 | GATE_MDP0(CLK_MDP1_MDP_RDMA2, "mdp1_mdp_rdma2" , "mdp" , 5), |
| 73 | GATE_MDP0(CLK_MDP1_MDP_BIRSZ0, "mdp1_mdp_birsz0" , "mdp" , 6), |
| 74 | GATE_MDP0(CLK_MDP1_MDP_HDR0, "mdp1_mdp_hdr0" , "mdp" , 7), |
| 75 | GATE_MDP0(CLK_MDP1_MDP_AAL0, "mdp1_mdp_aal0" , "mdp" , 8), |
| 76 | GATE_MDP0(CLK_MDP1_MDP_RSZ0, "mdp1_mdp_rsz0" , "mdp" , 9), |
| 77 | GATE_MDP0(CLK_MDP1_MDP_RSZ2, "mdp1_mdp_rsz2" , "mdp" , 10), |
| 78 | GATE_MDP0(CLK_MDP1_MDP_TDSHP0, "mdp1_mdp_tdshp0" , "mdp" , 11), |
| 79 | GATE_MDP0(CLK_MDP1_MDP_COLOR0, "mdp1_mdp_color0" , "mdp" , 12), |
| 80 | GATE_MDP0(CLK_MDP1_MDP_WROT0, "mdp1_mdp_wrot0" , "mdp" , 13), |
| 81 | GATE_MDP0(CLK_MDP1_MDP_WROT1, "mdp1_mdp_wrot1" , "mdp" , 14), |
| 82 | GATE_MDP0(CLK_MDP1_MDP_WROT2, "mdp1_mdp_wrot2" , "mdp" , 15), |
| 83 | GATE_MDP0(CLK_MDP1_MDP_FAKE_ENG0, "mdp1_mdp_fake_eng0" , "mdp" , 16), |
| 84 | GATE_MDP0(CLK_MDP1_APB_DB, "mdp1_apb_db" , "mdp" , 17), |
| 85 | GATE_MDP0(CLK_MDP1_MDP_DLI_ASYNC0, "mdp1_mdp_dli_async0" , "mdp" , 18), |
| 86 | GATE_MDP0(CLK_MDP1_MDP_DLI_ASYNC1, "mdp1_mdp_dli_async1" , "mdp" , 19), |
| 87 | GATE_MDP0(CLK_MDP1_MDP_DLO_ASYNC0, "mdp1_mdp_dlo_async0" , "mdp" , 20), |
| 88 | GATE_MDP0(CLK_MDP1_MDP_DLO_ASYNC1, "mdp1_mdp_dlo_async1" , "mdp" , 21), |
| 89 | GATE_MDP0(CLK_MDP1_MDP_DLI_ASYNC2, "mdp1_mdp_dli_async2" , "mdp" , 22), |
| 90 | GATE_MDP0(CLK_MDP1_MDP_DLO_ASYNC2, "mdp1_mdp_dlo_async2" , "mdp" , 23), |
| 91 | GATE_MDP0(CLK_MDP1_MDP_DLO_ASYNC3, "mdp1_mdp_dlo_async3" , "mdp" , 24), |
| 92 | GATE_MDP0(CLK_MDP1_IMG_DL_ASYNC0, "mdp1_img_dl_async0" , "mdp" , 25), |
| 93 | GATE_MDP0(CLK_MDP1_MDP_RROT0, "mdp1_mdp_rrot0" , "mdp" , 26), |
| 94 | GATE_MDP0(CLK_MDP1_MDP_MERGE0, "mdp1_mdp_merge0" , "mdp" , 27), |
| 95 | GATE_MDP0(CLK_MDP1_MDP_C3D0, "mdp1_mdp_c3d0" , "mdp" , 28), |
| 96 | GATE_MDP0(CLK_MDP1_MDP_FG0, "mdp1_mdp_fg0" , "mdp" , 29), |
| 97 | GATE_MDP0(CLK_MDP1_MDP_CLA2, "mdp1_mdp_cla2" , "mdp" , 30), |
| 98 | GATE_MDP0(CLK_MDP1_MDP_DLO_ASYNC4, "mdp1_mdp_dlo_async4" , "mdp" , 31), |
| 99 | /* MDP1-1 */ |
| 100 | GATE_MDP1(CLK_MDP1_VPP_RSZ0, "mdp1_vpp_rsz0" , "mdp" , 0), |
| 101 | GATE_MDP1(CLK_MDP1_VPP_RSZ1, "mdp1_vpp_rsz1" , "mdp" , 1), |
| 102 | GATE_MDP1(CLK_MDP1_MDP_DLO_ASYNC5, "mdp1_mdp_dlo_async5" , "mdp" , 2), |
| 103 | GATE_MDP1(CLK_MDP1_IMG0, "mdp1_img0" , "mdp" , 3), |
| 104 | GATE_MDP1(CLK_MDP1_F26M, "mdp1_f26m" , "clk26m" , 27), |
| 105 | /* MDP1-2 */ |
| 106 | GATE_MDP2(CLK_MDP1_IMG_DL_RELAY0, "mdp1_img_dl_relay0" , "mdp" , 0), |
| 107 | GATE_MDP2(CLK_MDP1_IMG_DL_RELAY1, "mdp1_img_dl_relay1" , "mdp" , 8), |
| 108 | }; |
| 109 | |
| 110 | static const struct mtk_clk_desc mdp1_mcd = { |
| 111 | .clks = mdp1_clks, |
| 112 | .num_clks = ARRAY_SIZE(mdp1_clks), |
| 113 | .need_runtime_pm = true, |
| 114 | }; |
| 115 | |
| 116 | |
| 117 | static const struct mtk_gate mdp_clks[] = { |
| 118 | /* MDP0 */ |
| 119 | GATE_MDP0(CLK_MDP_MDP_MUTEX0, "mdp_mdp_mutex0" , "mdp" , 0), |
| 120 | GATE_MDP0(CLK_MDP_SMI0, "mdp_smi0" , "mdp" , 1), |
| 121 | GATE_MDP0(CLK_MDP_APB_BUS, "mdp_apb_bus" , "mdp" , 2), |
| 122 | GATE_MDP0(CLK_MDP_MDP_RDMA0, "mdp_mdp_rdma0" , "mdp" , 3), |
| 123 | GATE_MDP0(CLK_MDP_MDP_RDMA1, "mdp_mdp_rdma1" , "mdp" , 4), |
| 124 | GATE_MDP0(CLK_MDP_MDP_RDMA2, "mdp_mdp_rdma2" , "mdp" , 5), |
| 125 | GATE_MDP0(CLK_MDP_MDP_BIRSZ0, "mdp_mdp_birsz0" , "mdp" , 6), |
| 126 | GATE_MDP0(CLK_MDP_MDP_HDR0, "mdp_mdp_hdr0" , "mdp" , 7), |
| 127 | GATE_MDP0(CLK_MDP_MDP_AAL0, "mdp_mdp_aal0" , "mdp" , 8), |
| 128 | GATE_MDP0(CLK_MDP_MDP_RSZ0, "mdp_mdp_rsz0" , "mdp" , 9), |
| 129 | GATE_MDP0(CLK_MDP_MDP_RSZ2, "mdp_mdp_rsz2" , "mdp" , 10), |
| 130 | GATE_MDP0(CLK_MDP_MDP_TDSHP0, "mdp_mdp_tdshp0" , "mdp" , 11), |
| 131 | GATE_MDP0(CLK_MDP_MDP_COLOR0, "mdp_mdp_color0" , "mdp" , 12), |
| 132 | GATE_MDP0(CLK_MDP_MDP_WROT0, "mdp_mdp_wrot0" , "mdp" , 13), |
| 133 | GATE_MDP0(CLK_MDP_MDP_WROT1, "mdp_mdp_wrot1" , "mdp" , 14), |
| 134 | GATE_MDP0(CLK_MDP_MDP_WROT2, "mdp_mdp_wrot2" , "mdp" , 15), |
| 135 | GATE_MDP0(CLK_MDP_MDP_FAKE_ENG0, "mdp_mdp_fake_eng0" , "mdp" , 16), |
| 136 | GATE_MDP0(CLK_MDP_APB_DB, "mdp_apb_db" , "mdp" , 17), |
| 137 | GATE_MDP0(CLK_MDP_MDP_DLI_ASYNC0, "mdp_mdp_dli_async0" , "mdp" , 18), |
| 138 | GATE_MDP0(CLK_MDP_MDP_DLI_ASYNC1, "mdp_mdp_dli_async1" , "mdp" , 19), |
| 139 | GATE_MDP0(CLK_MDP_MDP_DLO_ASYNC0, "mdp_mdp_dlo_async0" , "mdp" , 20), |
| 140 | GATE_MDP0(CLK_MDP_MDP_DLO_ASYNC1, "mdp_mdp_dlo_async1" , "mdp" , 21), |
| 141 | GATE_MDP0(CLK_MDP_MDP_DLI_ASYNC2, "mdp_mdp_dli_async2" , "mdp" , 22), |
| 142 | GATE_MDP0(CLK_MDP_MDP_DLO_ASYNC2, "mdp_mdp_dlo_async2" , "mdp" , 23), |
| 143 | GATE_MDP0(CLK_MDP_MDP_DLO_ASYNC3, "mdp_mdp_dlo_async3" , "mdp" , 24), |
| 144 | GATE_MDP0(CLK_MDP_IMG_DL_ASYNC0, "mdp_img_dl_async0" , "mdp" , 25), |
| 145 | GATE_MDP0(CLK_MDP_MDP_RROT0, "mdp_mdp_rrot0" , "mdp" , 26), |
| 146 | GATE_MDP0(CLK_MDP_MDP_MERGE0, "mdp_mdp_merge0" , "mdp" , 27), |
| 147 | GATE_MDP0(CLK_MDP_MDP_C3D0, "mdp_mdp_c3d0" , "mdp" , 28), |
| 148 | GATE_MDP0(CLK_MDP_MDP_FG0, "mdp_mdp_fg0" , "mdp" , 29), |
| 149 | GATE_MDP0(CLK_MDP_MDP_CLA2, "mdp_mdp_cla2" , "mdp" , 30), |
| 150 | GATE_MDP0(CLK_MDP_MDP_DLO_ASYNC4, "mdp_mdp_dlo_async4" , "mdp" , 31), |
| 151 | /* MDP1 */ |
| 152 | GATE_MDP1(CLK_MDP_VPP_RSZ0, "mdp_vpp_rsz0" , "mdp" , 0), |
| 153 | GATE_MDP1(CLK_MDP_VPP_RSZ1, "mdp_vpp_rsz1" , "mdp" , 1), |
| 154 | GATE_MDP1(CLK_MDP_MDP_DLO_ASYNC5, "mdp_mdp_dlo_async5" , "mdp" , 2), |
| 155 | GATE_MDP1(CLK_MDP_IMG0, "mdp_img0" , "mdp" , 3), |
| 156 | GATE_MDP1(CLK_MDP_F26M, "mdp_f26m" , "clk26m" , 27), |
| 157 | /* MDP2 */ |
| 158 | GATE_MDP2(CLK_MDP_IMG_DL_RELAY0, "mdp_img_dl_relay0" , "mdp" , 0), |
| 159 | GATE_MDP2(CLK_MDP_IMG_DL_RELAY1, "mdp_img_dl_relay1" , "mdp" , 8), |
| 160 | }; |
| 161 | |
| 162 | static const struct mtk_clk_desc mdp_mcd = { |
| 163 | .clks = mdp_clks, |
| 164 | .num_clks = ARRAY_SIZE(mdp_clks), |
| 165 | .need_runtime_pm = true, |
| 166 | }; |
| 167 | |
| 168 | static const struct of_device_id of_match_clk_mt8196_mdpsys[] = { |
| 169 | { .compatible = "mediatek,mt8196-mdpsys0" , .data = &mdp_mcd }, |
| 170 | { .compatible = "mediatek,mt8196-mdpsys1" , .data = &mdp1_mcd }, |
| 171 | { /* sentinel */ } |
| 172 | }; |
| 173 | MODULE_DEVICE_TABLE(of, of_match_clk_mt8196_mdpsys); |
| 174 | |
| 175 | static struct platform_driver clk_mt8196_mdpsys_drv = { |
| 176 | .probe = mtk_clk_simple_probe, |
| 177 | .remove = mtk_clk_simple_remove, |
| 178 | .driver = { |
| 179 | .name = "clk-mt8196-mdpsys" , |
| 180 | .of_match_table = of_match_clk_mt8196_mdpsys, |
| 181 | }, |
| 182 | }; |
| 183 | module_platform_driver(clk_mt8196_mdpsys_drv); |
| 184 | |
| 185 | MODULE_DESCRIPTION("MediaTek MT8196 Multimedia Data Path clocks driver" ); |
| 186 | MODULE_LICENSE("GPL" ); |
| 187 | |