1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2025 Collabora Ltd. 4 * AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> 5 */ 6 7 #include <linux/device.h> 8 #include <linux/interconnect.h> 9 #include <linux/interconnect-provider.h> 10 #include <linux/mod_devicetable.h> 11 #include <linux/module.h> 12 #include <linux/platform_device.h> 13 #include <dt-bindings/interconnect/mediatek,mt8196.h> 14 15 #include "icc-emi.h" 16 17 static struct mtk_icc_node ddr_emi = { 18 .name = "ddr-emi", 19 .id = SLAVE_DDR_EMI, 20 .ep = 1, 21 }; 22 23 static struct mtk_icc_node mcusys = { 24 .name = "mcusys", 25 .id = MASTER_MCUSYS, 26 .ep = 0, 27 .num_links = 1, 28 .links = { SLAVE_DDR_EMI } 29 }; 30 31 static struct mtk_icc_node mcu_port0 = { 32 .name = "mcu-port0", 33 .id = MASTER_MCU_0, 34 .ep = 0, 35 .num_links = 1, 36 .links = { SLAVE_DDR_EMI } 37 }; 38 39 static struct mtk_icc_node mcu_port1 = { 40 .name = "mcu-port1", 41 .id = MASTER_MCU_1, 42 .ep = 0, 43 .num_links = 1, 44 .links = { SLAVE_DDR_EMI } 45 }; 46 47 static struct mtk_icc_node mcu_port2 = { 48 .name = "mcu-port2", 49 .id = MASTER_MCU_2, 50 .ep = 0, 51 .num_links = 1, 52 .links = { SLAVE_DDR_EMI } 53 }; 54 55 static struct mtk_icc_node mcu_port3 = { 56 .name = "mcu-port3", 57 .id = MASTER_MCU_3, 58 .ep = 0, 59 .num_links = 1, 60 .links = { SLAVE_DDR_EMI } 61 }; 62 63 static struct mtk_icc_node mcu_port4 = { 64 .name = "mcu-port4", 65 .id = MASTER_MCU_4, 66 .ep = 0, 67 .num_links = 1, 68 .links = { SLAVE_DDR_EMI } 69 }; 70 71 static struct mtk_icc_node gpu = { 72 .name = "gpu", 73 .id = MASTER_GPUSYS, 74 .ep = 0, 75 .num_links = 1, 76 .links = { SLAVE_DDR_EMI } 77 }; 78 79 static struct mtk_icc_node mmsys = { 80 .name = "mmsys", 81 .id = MASTER_MMSYS, 82 .ep = 0, 83 .num_links = 1, 84 .links = { SLAVE_DDR_EMI } 85 }; 86 87 static struct mtk_icc_node mm_vpu = { 88 .name = "mm-vpu", 89 .id = MASTER_MM_VPU, 90 .ep = 0, 91 .num_links = 1, 92 .links = { MASTER_MMSYS } 93 }; 94 95 static struct mtk_icc_node mm_disp = { 96 .name = "mm-disp", 97 .id = MASTER_MM_DISP, 98 .ep = 0, 99 .num_links = 1, 100 .links = { MASTER_MMSYS } 101 }; 102 103 static struct mtk_icc_node mm_vdec = { 104 .name = "mm-vdec", 105 .id = MASTER_MM_VDEC, 106 .ep = 0, 107 .num_links = 1, 108 .links = { MASTER_MMSYS } 109 }; 110 111 static struct mtk_icc_node mm_venc = { 112 .name = "mm-venc", 113 .id = MASTER_MM_VENC, 114 .ep = 0, 115 .num_links = 1, 116 .links = { MASTER_MMSYS } 117 }; 118 119 static struct mtk_icc_node mm_cam = { 120 .name = "mm-cam", 121 .id = MASTER_MM_CAM, 122 .ep = 0, 123 .num_links = 1, 124 .links = { MASTER_MMSYS } 125 }; 126 127 static struct mtk_icc_node mm_img = { 128 .name = "mm-img", 129 .id = MASTER_MM_IMG, 130 .ep = 0, 131 .num_links = 1, 132 .links = { MASTER_MMSYS } 133 }; 134 135 static struct mtk_icc_node mm_mdp = { 136 .name = "mm-mdp", 137 .id = MASTER_MM_MDP, 138 .ep = 0, 139 .num_links = 1, 140 .links = { MASTER_MMSYS } 141 }; 142 143 static struct mtk_icc_node vpusys = { 144 .name = "vpusys", 145 .id = MASTER_VPUSYS, 146 .ep = 0, 147 .num_links = 1, 148 .links = { SLAVE_DDR_EMI } 149 }; 150 151 static struct mtk_icc_node vpu_port0 = { 152 .name = "vpu-port0", 153 .id = MASTER_VPU_0, 154 .ep = 0, 155 .num_links = 1, 156 .links = { MASTER_VPUSYS } 157 }; 158 159 static struct mtk_icc_node vpu_port1 = { 160 .name = "vpu-port1", 161 .id = MASTER_VPU_1, 162 .ep = 0, 163 .num_links = 1, 164 .links = { MASTER_VPUSYS } 165 }; 166 167 static struct mtk_icc_node mdlasys = { 168 .name = "mdlasys", 169 .id = MASTER_MDLASYS, 170 .ep = 0, 171 .num_links = 1, 172 .links = { SLAVE_DDR_EMI } 173 }; 174 175 static struct mtk_icc_node mdla_port0 = { 176 .name = "mdla-port0", 177 .id = MASTER_MDLA_0, 178 .ep = 0, 179 .num_links = 1, 180 .links = { MASTER_MDLASYS } 181 }; 182 183 static struct mtk_icc_node ufs = { 184 .name = "ufs", 185 .id = MASTER_UFS, 186 .ep = 0, 187 .num_links = 1, 188 .links = { SLAVE_DDR_EMI } 189 }; 190 191 static struct mtk_icc_node pcie = { 192 .name = "pcie", 193 .id = MASTER_PCIE, 194 .ep = 0, 195 .num_links = 1, 196 .links = { SLAVE_DDR_EMI } 197 }; 198 199 static struct mtk_icc_node usb = { 200 .name = "usb", 201 .id = MASTER_USB, 202 .ep = 0, 203 .num_links = 1, 204 .links = { SLAVE_DDR_EMI } 205 }; 206 207 static struct mtk_icc_node wifi = { 208 .name = "wifi", 209 .id = MASTER_WIFI, 210 .ep = 0, 211 .num_links = 1, 212 .links = { SLAVE_DDR_EMI } 213 }; 214 215 static struct mtk_icc_node bt = { 216 .name = "bt", 217 .id = MASTER_BT, 218 .ep = 0, 219 .num_links = 1, 220 .links = { SLAVE_DDR_EMI } 221 }; 222 223 static struct mtk_icc_node netsys = { 224 .name = "netsys", 225 .id = MASTER_NETSYS, 226 .ep = 0, 227 .num_links = 1, 228 .links = { SLAVE_DDR_EMI } 229 }; 230 231 static struct mtk_icc_node dbgif = { 232 .name = "dbgif", 233 .id = MASTER_DBGIF, 234 .ep = 0, 235 .num_links = 1, 236 .links = { SLAVE_DDR_EMI } 237 }; 238 239 static struct mtk_icc_node hrt_ddr_emi = { 240 .name = "hrt-ddr-emi", 241 .id = SLAVE_HRT_DDR_EMI, 242 .ep = 2, 243 }; 244 245 static struct mtk_icc_node hrt_mmsys = { 246 .name = "hrt-mmsys", 247 .id = MASTER_HRT_MMSYS, 248 .ep = 0, 249 .num_links = 1, 250 .links = { SLAVE_HRT_DDR_EMI } 251 }; 252 253 static struct mtk_icc_node hrt_mm_disp = { 254 .name = "hrt-mm-disp", 255 .id = MASTER_HRT_MM_DISP, 256 .ep = 0, 257 .num_links = 1, 258 .links = { MASTER_HRT_MMSYS } 259 }; 260 261 static struct mtk_icc_node hrt_mm_vdec = { 262 .name = "hrt-mm-vdec", 263 .id = MASTER_HRT_MM_VDEC, 264 .ep = 0, 265 .num_links = 1, 266 .links = { MASTER_HRT_MMSYS } 267 }; 268 269 static struct mtk_icc_node hrt_mm_venc = { 270 .name = "hrt-mm-venc", 271 .id = MASTER_HRT_MM_VENC, 272 .ep = 0, 273 .num_links = 1, 274 .links = { MASTER_HRT_MMSYS } 275 }; 276 277 static struct mtk_icc_node hrt_mm_cam = { 278 .name = "hrt-mm-cam", 279 .id = MASTER_HRT_MM_CAM, 280 .ep = 0, 281 .num_links = 1, 282 .links = { MASTER_HRT_MMSYS } 283 }; 284 285 static struct mtk_icc_node hrt_mm_img = { 286 .name = "hrt-mm-img", 287 .id = MASTER_HRT_MM_IMG, 288 .ep = 0, 289 .num_links = 1, 290 .links = { MASTER_HRT_MMSYS } 291 }; 292 293 static struct mtk_icc_node hrt_mm_mdp = { 294 .name = "hrt-mm-mdp", 295 .id = MASTER_HRT_MM_MDP, 296 .ep = 0, 297 .num_links = 1, 298 .links = { MASTER_HRT_MMSYS } 299 }; 300 301 static struct mtk_icc_node hrt_adsp = { 302 .name = "hrt-adsp", 303 .id = MASTER_HRT_ADSP, 304 .ep = 0, 305 .num_links = 1, 306 .links = { SLAVE_HRT_DDR_EMI } 307 }; 308 309 static struct mtk_icc_node hrt_dbgif = { 310 .name = "hrt-dbgif", 311 .id = MASTER_HRT_DBGIF, 312 .ep = 0, 313 .num_links = 1, 314 .links = { SLAVE_HRT_DDR_EMI } 315 }; 316 317 static struct mtk_icc_node *mt8196_emi_icc_nodes[] = { 318 [SLAVE_DDR_EMI] = &ddr_emi, 319 [MASTER_MCUSYS] = &mcusys, 320 [MASTER_MCU_0] = &mcu_port0, 321 [MASTER_MCU_1] = &mcu_port1, 322 [MASTER_MCU_2] = &mcu_port2, 323 [MASTER_MCU_3] = &mcu_port3, 324 [MASTER_MCU_4] = &mcu_port4, 325 [MASTER_GPUSYS] = &gpu, 326 [MASTER_MMSYS] = &mmsys, 327 [MASTER_MM_VPU] = &mm_vpu, 328 [MASTER_MM_DISP] = &mm_disp, 329 [MASTER_MM_VDEC] = &mm_vdec, 330 [MASTER_MM_VENC] = &mm_venc, 331 [MASTER_MM_CAM] = &mm_cam, 332 [MASTER_MM_IMG] = &mm_img, 333 [MASTER_MM_MDP] = &mm_mdp, 334 [MASTER_VPUSYS] = &vpusys, 335 [MASTER_VPU_0] = &vpu_port0, 336 [MASTER_VPU_1] = &vpu_port1, 337 [MASTER_MDLASYS] = &mdlasys, 338 [MASTER_MDLA_0] = &mdla_port0, 339 [MASTER_UFS] = &ufs, 340 [MASTER_PCIE] = &pcie, 341 [MASTER_USB] = &usb, 342 [MASTER_WIFI] = &wifi, 343 [MASTER_BT] = &bt, 344 [MASTER_NETSYS] = &netsys, 345 [MASTER_DBGIF] = &dbgif, 346 [SLAVE_HRT_DDR_EMI] = &hrt_ddr_emi, 347 [MASTER_HRT_MMSYS] = &hrt_mmsys, 348 [MASTER_HRT_MM_DISP] = &hrt_mm_disp, 349 [MASTER_HRT_MM_VDEC] = &hrt_mm_vdec, 350 [MASTER_HRT_MM_VENC] = &hrt_mm_venc, 351 [MASTER_HRT_MM_CAM] = &hrt_mm_cam, 352 [MASTER_HRT_MM_IMG] = &hrt_mm_img, 353 [MASTER_HRT_MM_MDP] = &hrt_mm_mdp, 354 [MASTER_HRT_ADSP] = &hrt_adsp, 355 [MASTER_HRT_DBGIF] = &hrt_dbgif 356 }; 357 358 static struct mtk_icc_desc mt8196_emi_icc = { 359 .nodes = mt8196_emi_icc_nodes, 360 .num_nodes = ARRAY_SIZE(mt8196_emi_icc_nodes), 361 }; 362 363 static const struct of_device_id mtk_mt8196_emi_icc_of_match[] = { 364 { .compatible = "mediatek,mt8196-emi", .data = &mt8196_emi_icc }, 365 { /* sentinel */ }, 366 }; 367 MODULE_DEVICE_TABLE(of, mtk_mt8196_emi_icc_of_match); 368 369 static struct platform_driver mtk_emi_icc_mt8196_driver = { 370 .driver = { 371 .name = "emi-icc-mt8196", 372 .of_match_table = mtk_mt8196_emi_icc_of_match, 373 .sync_state = icc_sync_state, 374 }, 375 .probe = mtk_emi_icc_probe, 376 .remove = mtk_emi_icc_remove, 377 378 }; 379 module_platform_driver(mtk_emi_icc_mt8196_driver); 380 381 MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>"); 382 MODULE_DESCRIPTION("MediaTek MT8196 EMI ICC driver"); 383 MODULE_LICENSE("GPL"); 384