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