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 vde20_cg_regs = { 19 .set_ofs = 0x0, 20 .clr_ofs = 0x4, 21 .sta_ofs = 0x0, 22 }; 23 24 static const struct mtk_gate_regs vde20_hwv_regs = { 25 .set_ofs = 0x0088, 26 .clr_ofs = 0x008c, 27 .sta_ofs = 0x2c44, 28 }; 29 30 static const struct mtk_gate_regs vde21_cg_regs = { 31 .set_ofs = 0x200, 32 .clr_ofs = 0x204, 33 .sta_ofs = 0x200, 34 }; 35 36 static const struct mtk_gate_regs vde21_hwv_regs = { 37 .set_ofs = 0x0080, 38 .clr_ofs = 0x0084, 39 .sta_ofs = 0x2c40, 40 }; 41 42 static const struct mtk_gate_regs vde22_cg_regs = { 43 .set_ofs = 0x8, 44 .clr_ofs = 0xc, 45 .sta_ofs = 0x8, 46 }; 47 48 static const struct mtk_gate_regs vde22_hwv_regs = { 49 .set_ofs = 0x0078, 50 .clr_ofs = 0x007c, 51 .sta_ofs = 0x2c3c, 52 }; 53 54 #define GATE_HWV_VDE20(_id, _name, _parent, _shift) { \ 55 .id = _id, \ 56 .name = _name, \ 57 .parent_name = _parent, \ 58 .regs = &vde20_cg_regs, \ 59 .hwv_regs = &vde20_hwv_regs, \ 60 .shift = _shift, \ 61 .ops = &mtk_clk_gate_hwv_ops_setclr_inv,\ 62 .flags = CLK_OPS_PARENT_ENABLE, \ 63 } 64 65 #define GATE_HWV_VDE21(_id, _name, _parent, _shift) { \ 66 .id = _id, \ 67 .name = _name, \ 68 .parent_name = _parent, \ 69 .regs = &vde21_cg_regs, \ 70 .hwv_regs = &vde21_hwv_regs, \ 71 .shift = _shift, \ 72 .ops = &mtk_clk_gate_hwv_ops_setclr_inv,\ 73 .flags = CLK_OPS_PARENT_ENABLE, \ 74 } 75 76 #define GATE_HWV_VDE22(_id, _name, _parent, _shift) { \ 77 .id = _id, \ 78 .name = _name, \ 79 .parent_name = _parent, \ 80 .regs = &vde22_cg_regs, \ 81 .hwv_regs = &vde22_hwv_regs, \ 82 .shift = _shift, \ 83 .ops = &mtk_clk_gate_hwv_ops_setclr_inv,\ 84 .flags = CLK_OPS_PARENT_ENABLE | \ 85 CLK_IGNORE_UNUSED, \ 86 } 87 88 static const struct mtk_gate vde2_clks[] = { 89 /* VDE20 */ 90 GATE_HWV_VDE20(CLK_VDE2_VDEC_CKEN, "vde2_vdec_cken", "vdec", 0), 91 GATE_HWV_VDE20(CLK_VDE2_VDEC_ACTIVE, "vde2_vdec_active", "vdec", 4), 92 GATE_HWV_VDE20(CLK_VDE2_VDEC_CKEN_ENG, "vde2_vdec_cken_eng", "vdec", 8), 93 /* VDE21 */ 94 GATE_HWV_VDE21(CLK_VDE2_LAT_CKEN, "vde2_lat_cken", "vdec", 0), 95 GATE_HWV_VDE21(CLK_VDE2_LAT_ACTIVE, "vde2_lat_active", "vdec", 4), 96 GATE_HWV_VDE21(CLK_VDE2_LAT_CKEN_ENG, "vde2_lat_cken_eng", "vdec", 8), 97 /* VDE22 */ 98 GATE_HWV_VDE22(CLK_VDE2_LARB1_CKEN, "vde2_larb1_cken", "vdec", 0), 99 }; 100 101 static const struct mtk_clk_desc vde2_mcd = { 102 .clks = vde2_clks, 103 .num_clks = ARRAY_SIZE(vde2_clks), 104 .need_runtime_pm = true, 105 }; 106 107 static const struct mtk_gate_regs vde10_hwv_regs = { 108 .set_ofs = 0x00a0, 109 .clr_ofs = 0x00a4, 110 .sta_ofs = 0x2c50, 111 }; 112 113 static const struct mtk_gate_regs vde11_cg_regs = { 114 .set_ofs = 0x1e0, 115 .clr_ofs = 0x1e0, 116 .sta_ofs = 0x1e0, 117 }; 118 119 static const struct mtk_gate_regs vde11_hwv_regs = { 120 .set_ofs = 0x00b0, 121 .clr_ofs = 0x00b4, 122 .sta_ofs = 0x2c58, 123 }; 124 125 static const struct mtk_gate_regs vde12_cg_regs = { 126 .set_ofs = 0x1ec, 127 .clr_ofs = 0x1ec, 128 .sta_ofs = 0x1ec, 129 }; 130 131 static const struct mtk_gate_regs vde12_hwv_regs = { 132 .set_ofs = 0x00a8, 133 .clr_ofs = 0x00ac, 134 .sta_ofs = 0x2c54, 135 }; 136 137 static const struct mtk_gate_regs vde13_cg_regs = { 138 .set_ofs = 0x200, 139 .clr_ofs = 0x204, 140 .sta_ofs = 0x200, 141 }; 142 143 static const struct mtk_gate_regs vde13_hwv_regs = { 144 .set_ofs = 0x0098, 145 .clr_ofs = 0x009c, 146 .sta_ofs = 0x2c4c, 147 }; 148 149 static const struct mtk_gate_regs vde14_hwv_regs = { 150 .set_ofs = 0x0090, 151 .clr_ofs = 0x0094, 152 .sta_ofs = 0x2c48, 153 }; 154 155 #define GATE_HWV_VDE10(_id, _name, _parent, _shift) { \ 156 .id = _id, \ 157 .name = _name, \ 158 .parent_name = _parent, \ 159 .regs = &vde20_cg_regs, \ 160 .hwv_regs = &vde10_hwv_regs, \ 161 .shift = _shift, \ 162 .ops = &mtk_clk_gate_hwv_ops_setclr_inv,\ 163 .flags = CLK_OPS_PARENT_ENABLE, \ 164 } 165 166 #define GATE_HWV_VDE11(_id, _name, _parent, _shift) { \ 167 .id = _id, \ 168 .name = _name, \ 169 .parent_name = _parent, \ 170 .regs = &vde11_cg_regs, \ 171 .hwv_regs = &vde11_hwv_regs, \ 172 .shift = _shift, \ 173 .ops = &mtk_clk_gate_hwv_ops_setclr_inv, \ 174 .flags = CLK_OPS_PARENT_ENABLE, \ 175 } 176 177 #define GATE_HWV_VDE12(_id, _name, _parent, _shift) { \ 178 .id = _id, \ 179 .name = _name, \ 180 .parent_name = _parent, \ 181 .regs = &vde12_cg_regs, \ 182 .hwv_regs = &vde12_hwv_regs, \ 183 .shift = _shift, \ 184 .ops = &mtk_clk_gate_hwv_ops_setclr_inv, \ 185 .flags = CLK_OPS_PARENT_ENABLE \ 186 } 187 188 #define GATE_HWV_VDE13(_id, _name, _parent, _shift) { \ 189 .id = _id, \ 190 .name = _name, \ 191 .parent_name = _parent, \ 192 .regs = &vde13_cg_regs, \ 193 .hwv_regs = &vde13_hwv_regs, \ 194 .shift = _shift, \ 195 .ops = &mtk_clk_gate_hwv_ops_setclr_inv,\ 196 .flags = CLK_OPS_PARENT_ENABLE, \ 197 } 198 199 #define GATE_HWV_VDE14(_id, _name, _parent, _shift) { \ 200 .id = _id, \ 201 .name = _name, \ 202 .parent_name = _parent, \ 203 .regs = &vde22_cg_regs, \ 204 .hwv_regs = &vde14_hwv_regs, \ 205 .shift = _shift, \ 206 .ops = &mtk_clk_gate_hwv_ops_setclr_inv,\ 207 .flags = CLK_OPS_PARENT_ENABLE | \ 208 CLK_IGNORE_UNUSED, \ 209 } 210 211 static const struct mtk_gate vde1_clks[] = { 212 /* VDE10 */ 213 GATE_HWV_VDE10(CLK_VDE1_VDEC_CKEN, "vde1_vdec_cken", "vdec", 0), 214 GATE_HWV_VDE10(CLK_VDE1_VDEC_ACTIVE, "vde1_vdec_active", "vdec", 4), 215 GATE_HWV_VDE10(CLK_VDE1_VDEC_CKEN_ENG, "vde1_vdec_cken_eng", "vdec", 8), 216 /* VDE11 */ 217 GATE_HWV_VDE11(CLK_VDE1_VDEC_SOC_IPS_EN, "vde1_vdec_soc_ips_en", "vdec", 0), 218 /* VDE12 */ 219 GATE_HWV_VDE12(CLK_VDE1_VDEC_SOC_APTV_EN, "vde1_aptv_en", "ck_tck_26m_mx9_ck", 0), 220 GATE_HWV_VDE12(CLK_VDE1_VDEC_SOC_APTV_TOP_EN, "vde1_aptv_topen", "ck_tck_26m_mx9_ck", 1), 221 /* VDE13 */ 222 GATE_HWV_VDE13(CLK_VDE1_LAT_CKEN, "vde1_lat_cken", "vdec", 0), 223 GATE_HWV_VDE13(CLK_VDE1_LAT_ACTIVE, "vde1_lat_active", "vdec", 4), 224 GATE_HWV_VDE13(CLK_VDE1_LAT_CKEN_ENG, "vde1_lat_cken_eng", "vdec", 8), 225 /* VDE14 */ 226 GATE_HWV_VDE14(CLK_VDE1_LARB1_CKEN, "vde1_larb1_cken", "vdec", 0), 227 }; 228 229 static const struct mtk_clk_desc vde1_mcd = { 230 .clks = vde1_clks, 231 .num_clks = ARRAY_SIZE(vde1_clks), 232 .need_runtime_pm = true, 233 }; 234 235 static const struct of_device_id of_match_clk_mt8196_vdec[] = { 236 { .compatible = "mediatek,mt8196-vdecsys", .data = &vde2_mcd }, 237 { .compatible = "mediatek,mt8196-vdecsys-soc", .data = &vde1_mcd }, 238 { /* sentinel */ } 239 }; 240 MODULE_DEVICE_TABLE(of, of_match_clk_mt8196_vdec); 241 242 static struct platform_driver clk_mt8196_vdec_drv = { 243 .probe = mtk_clk_simple_probe, 244 .remove = mtk_clk_simple_remove, 245 .driver = { 246 .name = "clk-mt8196-vdec", 247 .of_match_table = of_match_clk_mt8196_vdec, 248 }, 249 }; 250 module_platform_driver(clk_mt8196_vdec_drv); 251 252 MODULE_DESCRIPTION("MediaTek MT8196 Video Decoders clocks driver"); 253 MODULE_LICENSE("GPL"); 254