1*2f66f069SLaura Nao // SPDX-License-Identifier: GPL-2.0-only 2*2f66f069SLaura Nao /* 3*2f66f069SLaura Nao * Copyright (c) 2025 MediaTek Inc. 4*2f66f069SLaura Nao * Guangjie Song <guangjie.song@mediatek.com> 5*2f66f069SLaura Nao * Copyright (c) 2025 Collabora Ltd. 6*2f66f069SLaura Nao * Laura Nao <laura.nao@collabora.com> 7*2f66f069SLaura Nao */ 8*2f66f069SLaura Nao #include <dt-bindings/clock/mediatek,mt8196-clock.h> 9*2f66f069SLaura Nao 10*2f66f069SLaura Nao #include <linux/clk-provider.h> 11*2f66f069SLaura Nao #include <linux/module.h> 12*2f66f069SLaura Nao #include <linux/of_device.h> 13*2f66f069SLaura Nao #include <linux/platform_device.h> 14*2f66f069SLaura Nao 15*2f66f069SLaura Nao #include "clk-gate.h" 16*2f66f069SLaura Nao #include "clk-mtk.h" 17*2f66f069SLaura Nao 18*2f66f069SLaura Nao static const struct mtk_gate_regs ven10_cg_regs = { 19*2f66f069SLaura Nao .set_ofs = 0x4, 20*2f66f069SLaura Nao .clr_ofs = 0x8, 21*2f66f069SLaura Nao .sta_ofs = 0x0, 22*2f66f069SLaura Nao }; 23*2f66f069SLaura Nao 24*2f66f069SLaura Nao static const struct mtk_gate_regs ven10_hwv_regs = { 25*2f66f069SLaura Nao .set_ofs = 0x00b8, 26*2f66f069SLaura Nao .clr_ofs = 0x00bc, 27*2f66f069SLaura Nao .sta_ofs = 0x2c5c, 28*2f66f069SLaura Nao }; 29*2f66f069SLaura Nao 30*2f66f069SLaura Nao static const struct mtk_gate_regs ven11_cg_regs = { 31*2f66f069SLaura Nao .set_ofs = 0x10, 32*2f66f069SLaura Nao .clr_ofs = 0x14, 33*2f66f069SLaura Nao .sta_ofs = 0x10, 34*2f66f069SLaura Nao }; 35*2f66f069SLaura Nao 36*2f66f069SLaura Nao static const struct mtk_gate_regs ven11_hwv_regs = { 37*2f66f069SLaura Nao .set_ofs = 0x00c0, 38*2f66f069SLaura Nao .clr_ofs = 0x00c4, 39*2f66f069SLaura Nao .sta_ofs = 0x2c60, 40*2f66f069SLaura Nao }; 41*2f66f069SLaura Nao 42*2f66f069SLaura Nao #define GATE_VEN10(_id, _name, _parent, _shift) { \ 43*2f66f069SLaura Nao .id = _id, \ 44*2f66f069SLaura Nao .name = _name, \ 45*2f66f069SLaura Nao .parent_name = _parent, \ 46*2f66f069SLaura Nao .regs = &ven10_cg_regs, \ 47*2f66f069SLaura Nao .shift = _shift, \ 48*2f66f069SLaura Nao .flags = CLK_OPS_PARENT_ENABLE, \ 49*2f66f069SLaura Nao .ops = &mtk_clk_gate_ops_setclr_inv, \ 50*2f66f069SLaura Nao } 51*2f66f069SLaura Nao 52*2f66f069SLaura Nao #define GATE_HWV_VEN10_FLAGS(_id, _name, _parent, _shift, _flags) { \ 53*2f66f069SLaura Nao .id = _id, \ 54*2f66f069SLaura Nao .name = _name, \ 55*2f66f069SLaura Nao .parent_name = _parent, \ 56*2f66f069SLaura Nao .regs = &ven10_cg_regs, \ 57*2f66f069SLaura Nao .hwv_regs = &ven10_hwv_regs, \ 58*2f66f069SLaura Nao .shift = _shift, \ 59*2f66f069SLaura Nao .ops = &mtk_clk_gate_hwv_ops_setclr_inv, \ 60*2f66f069SLaura Nao .flags = (_flags) | \ 61*2f66f069SLaura Nao CLK_OPS_PARENT_ENABLE, \ 62*2f66f069SLaura Nao } 63*2f66f069SLaura Nao 64*2f66f069SLaura Nao #define GATE_HWV_VEN10(_id, _name, _parent, _shift) \ 65*2f66f069SLaura Nao GATE_HWV_VEN10_FLAGS(_id, _name, _parent, _shift, 0) 66*2f66f069SLaura Nao 67*2f66f069SLaura Nao #define GATE_HWV_VEN11(_id, _name, _parent, _shift) { \ 68*2f66f069SLaura Nao .id = _id, \ 69*2f66f069SLaura Nao .name = _name, \ 70*2f66f069SLaura Nao .parent_name = _parent, \ 71*2f66f069SLaura Nao .regs = &ven11_cg_regs, \ 72*2f66f069SLaura Nao .hwv_regs = &ven11_hwv_regs, \ 73*2f66f069SLaura Nao .shift = _shift, \ 74*2f66f069SLaura Nao .ops = &mtk_clk_gate_hwv_ops_setclr_inv,\ 75*2f66f069SLaura Nao .flags = CLK_OPS_PARENT_ENABLE \ 76*2f66f069SLaura Nao } 77*2f66f069SLaura Nao 78*2f66f069SLaura Nao static const struct mtk_gate ven1_clks[] = { 79*2f66f069SLaura Nao /* VEN10 */ 80*2f66f069SLaura Nao GATE_HWV_VEN10(CLK_VEN1_CKE0_LARB, "ven1_larb", "venc", 0), 81*2f66f069SLaura Nao GATE_HWV_VEN10(CLK_VEN1_CKE1_VENC, "ven1_venc", "venc", 4), 82*2f66f069SLaura Nao GATE_VEN10(CLK_VEN1_CKE2_JPGENC, "ven1_jpgenc", "venc", 8), 83*2f66f069SLaura Nao GATE_VEN10(CLK_VEN1_CKE3_JPGDEC, "ven1_jpgdec", "venc", 12), 84*2f66f069SLaura Nao GATE_VEN10(CLK_VEN1_CKE4_JPGDEC_C1, "ven1_jpgdec_c1", "venc", 16), 85*2f66f069SLaura Nao GATE_HWV_VEN10(CLK_VEN1_CKE5_GALS, "ven1_gals", "venc", 28), 86*2f66f069SLaura Nao GATE_HWV_VEN10(CLK_VEN1_CKE29_VENC_ADAB_CTRL, "ven1_venc_adab_ctrl", 87*2f66f069SLaura Nao "venc", 29), 88*2f66f069SLaura Nao GATE_HWV_VEN10_FLAGS(CLK_VEN1_CKE29_VENC_XPC_CTRL, 89*2f66f069SLaura Nao "ven1_venc_xpc_ctrl", "venc", 30, 90*2f66f069SLaura Nao CLK_IGNORE_UNUSED), 91*2f66f069SLaura Nao GATE_HWV_VEN10(CLK_VEN1_CKE6_GALS_SRAM, "ven1_gals_sram", "venc", 31), 92*2f66f069SLaura Nao /* VEN11 */ 93*2f66f069SLaura Nao GATE_HWV_VEN11(CLK_VEN1_RES_FLAT, "ven1_res_flat", "venc", 0), 94*2f66f069SLaura Nao }; 95*2f66f069SLaura Nao 96*2f66f069SLaura Nao static const struct mtk_clk_desc ven1_mcd = { 97*2f66f069SLaura Nao .clks = ven1_clks, 98*2f66f069SLaura Nao .num_clks = ARRAY_SIZE(ven1_clks), 99*2f66f069SLaura Nao .need_runtime_pm = true, 100*2f66f069SLaura Nao }; 101*2f66f069SLaura Nao 102*2f66f069SLaura Nao static const struct mtk_gate_regs ven20_hwv_regs = { 103*2f66f069SLaura Nao .set_ofs = 0x00c8, 104*2f66f069SLaura Nao .clr_ofs = 0x00cc, 105*2f66f069SLaura Nao .sta_ofs = 0x2c64, 106*2f66f069SLaura Nao }; 107*2f66f069SLaura Nao 108*2f66f069SLaura Nao static const struct mtk_gate_regs ven21_hwv_regs = { 109*2f66f069SLaura Nao .set_ofs = 0x00d0, 110*2f66f069SLaura Nao .clr_ofs = 0x00d4, 111*2f66f069SLaura Nao .sta_ofs = 0x2c68, 112*2f66f069SLaura Nao }; 113*2f66f069SLaura Nao 114*2f66f069SLaura Nao #define GATE_VEN20(_id, _name, _parent, _shift) { \ 115*2f66f069SLaura Nao .id = _id, \ 116*2f66f069SLaura Nao .name = _name, \ 117*2f66f069SLaura Nao .parent_name = _parent, \ 118*2f66f069SLaura Nao .regs = &ven10_cg_regs, \ 119*2f66f069SLaura Nao .shift = _shift, \ 120*2f66f069SLaura Nao .flags = CLK_OPS_PARENT_ENABLE, \ 121*2f66f069SLaura Nao .ops = &mtk_clk_gate_ops_setclr_inv, \ 122*2f66f069SLaura Nao } 123*2f66f069SLaura Nao 124*2f66f069SLaura Nao #define GATE_HWV_VEN20(_id, _name, _parent, _shift) { \ 125*2f66f069SLaura Nao .id = _id, \ 126*2f66f069SLaura Nao .name = _name, \ 127*2f66f069SLaura Nao .parent_name = _parent, \ 128*2f66f069SLaura Nao .regs = &ven10_cg_regs, \ 129*2f66f069SLaura Nao .hwv_regs = &ven20_hwv_regs, \ 130*2f66f069SLaura Nao .shift = _shift, \ 131*2f66f069SLaura Nao .ops = &mtk_clk_gate_hwv_ops_setclr_inv,\ 132*2f66f069SLaura Nao .flags = CLK_OPS_PARENT_ENABLE, \ 133*2f66f069SLaura Nao } 134*2f66f069SLaura Nao 135*2f66f069SLaura Nao #define GATE_HWV_VEN21(_id, _name, _parent, _shift) { \ 136*2f66f069SLaura Nao .id = _id, \ 137*2f66f069SLaura Nao .name = _name, \ 138*2f66f069SLaura Nao .parent_name = _parent, \ 139*2f66f069SLaura Nao .regs = &ven11_cg_regs, \ 140*2f66f069SLaura Nao .hwv_regs = &ven21_hwv_regs, \ 141*2f66f069SLaura Nao .shift = _shift, \ 142*2f66f069SLaura Nao .ops = &mtk_clk_gate_hwv_ops_setclr, \ 143*2f66f069SLaura Nao .flags = CLK_OPS_PARENT_ENABLE \ 144*2f66f069SLaura Nao } 145*2f66f069SLaura Nao 146*2f66f069SLaura Nao static const struct mtk_gate ven2_clks[] = { 147*2f66f069SLaura Nao /* VEN20 */ 148*2f66f069SLaura Nao GATE_HWV_VEN20(CLK_VEN2_CKE0_LARB, "ven2_larb", "venc", 0), 149*2f66f069SLaura Nao GATE_HWV_VEN20(CLK_VEN2_CKE1_VENC, "ven2_venc", "venc", 4), 150*2f66f069SLaura Nao GATE_VEN20(CLK_VEN2_CKE2_JPGENC, "ven2_jpgenc", "venc", 8), 151*2f66f069SLaura Nao GATE_VEN20(CLK_VEN2_CKE3_JPGDEC, "ven2_jpgdec", "venc", 12), 152*2f66f069SLaura Nao GATE_HWV_VEN20(CLK_VEN2_CKE5_GALS, "ven2_gals", "venc", 28), 153*2f66f069SLaura Nao GATE_HWV_VEN20(CLK_VEN2_CKE29_VENC_XPC_CTRL, "ven2_venc_xpc_ctrl", "venc", 30), 154*2f66f069SLaura Nao GATE_HWV_VEN20(CLK_VEN2_CKE6_GALS_SRAM, "ven2_gals_sram", "venc", 31), 155*2f66f069SLaura Nao /* VEN21 */ 156*2f66f069SLaura Nao GATE_HWV_VEN21(CLK_VEN2_RES_FLAT, "ven2_res_flat", "venc", 0), 157*2f66f069SLaura Nao }; 158*2f66f069SLaura Nao 159*2f66f069SLaura Nao static const struct mtk_clk_desc ven2_mcd = { 160*2f66f069SLaura Nao .clks = ven2_clks, 161*2f66f069SLaura Nao .num_clks = ARRAY_SIZE(ven2_clks), 162*2f66f069SLaura Nao .need_runtime_pm = true, 163*2f66f069SLaura Nao }; 164*2f66f069SLaura Nao 165*2f66f069SLaura Nao static const struct mtk_gate_regs ven_c20_hwv_regs = { 166*2f66f069SLaura Nao .set_ofs = 0x00d8, 167*2f66f069SLaura Nao .clr_ofs = 0x00dc, 168*2f66f069SLaura Nao .sta_ofs = 0x2c6c, 169*2f66f069SLaura Nao }; 170*2f66f069SLaura Nao 171*2f66f069SLaura Nao static const struct mtk_gate_regs ven_c21_hwv_regs = { 172*2f66f069SLaura Nao .set_ofs = 0x00e0, 173*2f66f069SLaura Nao .clr_ofs = 0x00e4, 174*2f66f069SLaura Nao .sta_ofs = 0x2c70, 175*2f66f069SLaura Nao }; 176*2f66f069SLaura Nao 177*2f66f069SLaura Nao #define GATE_HWV_VEN_C20(_id, _name, _parent, _shift) {\ 178*2f66f069SLaura Nao .id = _id, \ 179*2f66f069SLaura Nao .name = _name, \ 180*2f66f069SLaura Nao .parent_name = _parent, \ 181*2f66f069SLaura Nao .regs = &ven10_cg_regs, \ 182*2f66f069SLaura Nao .hwv_regs = &ven_c20_hwv_regs, \ 183*2f66f069SLaura Nao .shift = _shift, \ 184*2f66f069SLaura Nao .ops = &mtk_clk_gate_hwv_ops_setclr_inv,\ 185*2f66f069SLaura Nao .flags = CLK_OPS_PARENT_ENABLE, \ 186*2f66f069SLaura Nao } 187*2f66f069SLaura Nao 188*2f66f069SLaura Nao #define GATE_HWV_VEN_C21(_id, _name, _parent, _shift) {\ 189*2f66f069SLaura Nao .id = _id, \ 190*2f66f069SLaura Nao .name = _name, \ 191*2f66f069SLaura Nao .parent_name = _parent, \ 192*2f66f069SLaura Nao .regs = &ven11_cg_regs, \ 193*2f66f069SLaura Nao .hwv_regs = &ven_c21_hwv_regs, \ 194*2f66f069SLaura Nao .shift = _shift, \ 195*2f66f069SLaura Nao .ops = &mtk_clk_gate_hwv_ops_setclr, \ 196*2f66f069SLaura Nao .flags = CLK_OPS_PARENT_ENABLE, \ 197*2f66f069SLaura Nao } 198*2f66f069SLaura Nao 199*2f66f069SLaura Nao static const struct mtk_gate ven_c2_clks[] = { 200*2f66f069SLaura Nao /* VEN_C20 */ 201*2f66f069SLaura Nao GATE_HWV_VEN_C20(CLK_VEN_C2_CKE0_LARB, "ven_c2_larb", "venc", 0), 202*2f66f069SLaura Nao GATE_HWV_VEN_C20(CLK_VEN_C2_CKE1_VENC, "ven_c2_venc", "venc", 4), 203*2f66f069SLaura Nao GATE_HWV_VEN_C20(CLK_VEN_C2_CKE5_GALS, "ven_c2_gals", "venc", 28), 204*2f66f069SLaura Nao GATE_HWV_VEN_C20(CLK_VEN_C2_CKE29_VENC_XPC_CTRL, "ven_c2_venc_xpc_ctrl", 205*2f66f069SLaura Nao "venc", 30), 206*2f66f069SLaura Nao GATE_HWV_VEN_C20(CLK_VEN_C2_CKE6_GALS_SRAM, "ven_c2_gals_sram", "venc", 31), 207*2f66f069SLaura Nao /* VEN_C21 */ 208*2f66f069SLaura Nao GATE_HWV_VEN_C21(CLK_VEN_C2_RES_FLAT, "ven_c2_res_flat", "venc", 0), 209*2f66f069SLaura Nao }; 210*2f66f069SLaura Nao 211*2f66f069SLaura Nao static const struct mtk_clk_desc ven_c2_mcd = { 212*2f66f069SLaura Nao .clks = ven_c2_clks, 213*2f66f069SLaura Nao .num_clks = ARRAY_SIZE(ven_c2_clks), 214*2f66f069SLaura Nao .need_runtime_pm = true, 215*2f66f069SLaura Nao }; 216*2f66f069SLaura Nao 217*2f66f069SLaura Nao static const struct of_device_id of_match_clk_mt8196_venc[] = { 218*2f66f069SLaura Nao { .compatible = "mediatek,mt8196-vencsys", .data = &ven1_mcd }, 219*2f66f069SLaura Nao { .compatible = "mediatek,mt8196-vencsys-c1", .data = &ven2_mcd }, 220*2f66f069SLaura Nao { .compatible = "mediatek,mt8196-vencsys-c2", .data = &ven_c2_mcd }, 221*2f66f069SLaura Nao { /* sentinel */ } 222*2f66f069SLaura Nao }; 223*2f66f069SLaura Nao MODULE_DEVICE_TABLE(of, of_match_clk_mt8196_venc); 224*2f66f069SLaura Nao 225*2f66f069SLaura Nao static struct platform_driver clk_mt8196_venc_drv = { 226*2f66f069SLaura Nao .probe = mtk_clk_simple_probe, 227*2f66f069SLaura Nao .remove = mtk_clk_simple_remove, 228*2f66f069SLaura Nao .driver = { 229*2f66f069SLaura Nao .name = "clk-mt8196-venc", 230*2f66f069SLaura Nao .of_match_table = of_match_clk_mt8196_venc, 231*2f66f069SLaura Nao }, 232*2f66f069SLaura Nao }; 233*2f66f069SLaura Nao module_platform_driver(clk_mt8196_venc_drv); 234*2f66f069SLaura Nao 235*2f66f069SLaura Nao MODULE_DESCRIPTION("MediaTek MT8196 Video Encoders clocks driver"); 236*2f66f069SLaura Nao MODULE_LICENSE("GPL"); 237