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