1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2015 MediaTek Inc. 4 */ 5 6 #include <linux/clk.h> 7 #include <linux/iopoll.h> 8 #include <linux/module.h> 9 #include <linux/of_device.h> 10 #include <linux/platform_device.h> 11 #include <linux/regmap.h> 12 #include <linux/soc/mediatek/mtk-mmsys.h> 13 #include <linux/soc/mediatek/mtk-mutex.h> 14 15 #define MT2701_MUTEX0_MOD0 0x2c 16 #define MT2701_MUTEX0_SOF0 0x30 17 #define MT8183_MUTEX0_MOD0 0x30 18 #define MT8183_MUTEX0_SOF0 0x2c 19 20 #define DISP_REG_MUTEX_EN(n) (0x20 + 0x20 * (n)) 21 #define DISP_REG_MUTEX(n) (0x24 + 0x20 * (n)) 22 #define DISP_REG_MUTEX_RST(n) (0x28 + 0x20 * (n)) 23 #define DISP_REG_MUTEX_MOD(mutex_mod_reg, n) (mutex_mod_reg + 0x20 * (n)) 24 #define DISP_REG_MUTEX_SOF(mutex_sof_reg, n) (mutex_sof_reg + 0x20 * (n)) 25 #define DISP_REG_MUTEX_MOD2(n) (0x34 + 0x20 * (n)) 26 27 #define INT_MUTEX BIT(1) 28 29 #define MT8186_MUTEX_MOD_DISP_OVL0 0 30 #define MT8186_MUTEX_MOD_DISP_OVL0_2L 1 31 #define MT8186_MUTEX_MOD_DISP_RDMA0 2 32 #define MT8186_MUTEX_MOD_DISP_COLOR0 4 33 #define MT8186_MUTEX_MOD_DISP_CCORR0 5 34 #define MT8186_MUTEX_MOD_DISP_AAL0 7 35 #define MT8186_MUTEX_MOD_DISP_GAMMA0 8 36 #define MT8186_MUTEX_MOD_DISP_POSTMASK0 9 37 #define MT8186_MUTEX_MOD_DISP_DITHER0 10 38 #define MT8186_MUTEX_MOD_DISP_RDMA1 17 39 40 #define MT8186_MUTEX_SOF_SINGLE_MODE 0 41 #define MT8186_MUTEX_SOF_DSI0 1 42 #define MT8186_MUTEX_SOF_DPI0 2 43 #define MT8186_MUTEX_EOF_DSI0 (MT8186_MUTEX_SOF_DSI0 << 6) 44 #define MT8186_MUTEX_EOF_DPI0 (MT8186_MUTEX_SOF_DPI0 << 6) 45 46 #define MT8167_MUTEX_MOD_DISP_PWM 1 47 #define MT8167_MUTEX_MOD_DISP_OVL0 6 48 #define MT8167_MUTEX_MOD_DISP_OVL1 7 49 #define MT8167_MUTEX_MOD_DISP_RDMA0 8 50 #define MT8167_MUTEX_MOD_DISP_RDMA1 9 51 #define MT8167_MUTEX_MOD_DISP_WDMA0 10 52 #define MT8167_MUTEX_MOD_DISP_CCORR 11 53 #define MT8167_MUTEX_MOD_DISP_COLOR 12 54 #define MT8167_MUTEX_MOD_DISP_AAL 13 55 #define MT8167_MUTEX_MOD_DISP_GAMMA 14 56 #define MT8167_MUTEX_MOD_DISP_DITHER 15 57 #define MT8167_MUTEX_MOD_DISP_UFOE 16 58 59 #define MT8192_MUTEX_MOD_DISP_OVL0 0 60 #define MT8192_MUTEX_MOD_DISP_OVL0_2L 1 61 #define MT8192_MUTEX_MOD_DISP_RDMA0 2 62 #define MT8192_MUTEX_MOD_DISP_COLOR0 4 63 #define MT8192_MUTEX_MOD_DISP_CCORR0 5 64 #define MT8192_MUTEX_MOD_DISP_AAL0 6 65 #define MT8192_MUTEX_MOD_DISP_GAMMA0 7 66 #define MT8192_MUTEX_MOD_DISP_POSTMASK0 8 67 #define MT8192_MUTEX_MOD_DISP_DITHER0 9 68 #define MT8192_MUTEX_MOD_DISP_OVL2_2L 16 69 #define MT8192_MUTEX_MOD_DISP_RDMA4 17 70 71 #define MT8183_MUTEX_MOD_DISP_RDMA0 0 72 #define MT8183_MUTEX_MOD_DISP_RDMA1 1 73 #define MT8183_MUTEX_MOD_DISP_OVL0 9 74 #define MT8183_MUTEX_MOD_DISP_OVL0_2L 10 75 #define MT8183_MUTEX_MOD_DISP_OVL1_2L 11 76 #define MT8183_MUTEX_MOD_DISP_WDMA0 12 77 #define MT8183_MUTEX_MOD_DISP_COLOR0 13 78 #define MT8183_MUTEX_MOD_DISP_CCORR0 14 79 #define MT8183_MUTEX_MOD_DISP_AAL0 15 80 #define MT8183_MUTEX_MOD_DISP_GAMMA0 16 81 #define MT8183_MUTEX_MOD_DISP_DITHER0 17 82 83 #define MT8173_MUTEX_MOD_DISP_OVL0 11 84 #define MT8173_MUTEX_MOD_DISP_OVL1 12 85 #define MT8173_MUTEX_MOD_DISP_RDMA0 13 86 #define MT8173_MUTEX_MOD_DISP_RDMA1 14 87 #define MT8173_MUTEX_MOD_DISP_RDMA2 15 88 #define MT8173_MUTEX_MOD_DISP_WDMA0 16 89 #define MT8173_MUTEX_MOD_DISP_WDMA1 17 90 #define MT8173_MUTEX_MOD_DISP_COLOR0 18 91 #define MT8173_MUTEX_MOD_DISP_COLOR1 19 92 #define MT8173_MUTEX_MOD_DISP_AAL 20 93 #define MT8173_MUTEX_MOD_DISP_GAMMA 21 94 #define MT8173_MUTEX_MOD_DISP_UFOE 22 95 #define MT8173_MUTEX_MOD_DISP_PWM0 23 96 #define MT8173_MUTEX_MOD_DISP_PWM1 24 97 #define MT8173_MUTEX_MOD_DISP_OD 25 98 99 #define MT2712_MUTEX_MOD_DISP_PWM2 10 100 #define MT2712_MUTEX_MOD_DISP_OVL0 11 101 #define MT2712_MUTEX_MOD_DISP_OVL1 12 102 #define MT2712_MUTEX_MOD_DISP_RDMA0 13 103 #define MT2712_MUTEX_MOD_DISP_RDMA1 14 104 #define MT2712_MUTEX_MOD_DISP_RDMA2 15 105 #define MT2712_MUTEX_MOD_DISP_WDMA0 16 106 #define MT2712_MUTEX_MOD_DISP_WDMA1 17 107 #define MT2712_MUTEX_MOD_DISP_COLOR0 18 108 #define MT2712_MUTEX_MOD_DISP_COLOR1 19 109 #define MT2712_MUTEX_MOD_DISP_AAL0 20 110 #define MT2712_MUTEX_MOD_DISP_UFOE 22 111 #define MT2712_MUTEX_MOD_DISP_PWM0 23 112 #define MT2712_MUTEX_MOD_DISP_PWM1 24 113 #define MT2712_MUTEX_MOD_DISP_OD0 25 114 #define MT2712_MUTEX_MOD2_DISP_AAL1 33 115 #define MT2712_MUTEX_MOD2_DISP_OD1 34 116 117 #define MT2701_MUTEX_MOD_DISP_OVL 3 118 #define MT2701_MUTEX_MOD_DISP_WDMA 6 119 #define MT2701_MUTEX_MOD_DISP_COLOR 7 120 #define MT2701_MUTEX_MOD_DISP_BLS 9 121 #define MT2701_MUTEX_MOD_DISP_RDMA0 10 122 #define MT2701_MUTEX_MOD_DISP_RDMA1 12 123 124 #define MT2712_MUTEX_SOF_SINGLE_MODE 0 125 #define MT2712_MUTEX_SOF_DSI0 1 126 #define MT2712_MUTEX_SOF_DSI1 2 127 #define MT2712_MUTEX_SOF_DPI0 3 128 #define MT2712_MUTEX_SOF_DPI1 4 129 #define MT2712_MUTEX_SOF_DSI2 5 130 #define MT2712_MUTEX_SOF_DSI3 6 131 #define MT8167_MUTEX_SOF_DPI0 2 132 #define MT8167_MUTEX_SOF_DPI1 3 133 #define MT8183_MUTEX_SOF_DSI0 1 134 #define MT8183_MUTEX_SOF_DPI0 2 135 136 #define MT8183_MUTEX_EOF_DSI0 (MT8183_MUTEX_SOF_DSI0 << 6) 137 #define MT8183_MUTEX_EOF_DPI0 (MT8183_MUTEX_SOF_DPI0 << 6) 138 139 struct mtk_mutex { 140 int id; 141 bool claimed; 142 }; 143 144 enum mtk_mutex_sof_id { 145 MUTEX_SOF_SINGLE_MODE, 146 MUTEX_SOF_DSI0, 147 MUTEX_SOF_DSI1, 148 MUTEX_SOF_DPI0, 149 MUTEX_SOF_DPI1, 150 MUTEX_SOF_DSI2, 151 MUTEX_SOF_DSI3, 152 }; 153 154 struct mtk_mutex_data { 155 const unsigned int *mutex_mod; 156 const unsigned int *mutex_sof; 157 const unsigned int mutex_mod_reg; 158 const unsigned int mutex_sof_reg; 159 const bool no_clk; 160 }; 161 162 struct mtk_mutex_ctx { 163 struct device *dev; 164 struct clk *clk; 165 void __iomem *regs; 166 struct mtk_mutex mutex[10]; 167 const struct mtk_mutex_data *data; 168 }; 169 170 static const unsigned int mt2701_mutex_mod[DDP_COMPONENT_ID_MAX] = { 171 [DDP_COMPONENT_BLS] = MT2701_MUTEX_MOD_DISP_BLS, 172 [DDP_COMPONENT_COLOR0] = MT2701_MUTEX_MOD_DISP_COLOR, 173 [DDP_COMPONENT_OVL0] = MT2701_MUTEX_MOD_DISP_OVL, 174 [DDP_COMPONENT_RDMA0] = MT2701_MUTEX_MOD_DISP_RDMA0, 175 [DDP_COMPONENT_RDMA1] = MT2701_MUTEX_MOD_DISP_RDMA1, 176 [DDP_COMPONENT_WDMA0] = MT2701_MUTEX_MOD_DISP_WDMA, 177 }; 178 179 static const unsigned int mt2712_mutex_mod[DDP_COMPONENT_ID_MAX] = { 180 [DDP_COMPONENT_AAL0] = MT2712_MUTEX_MOD_DISP_AAL0, 181 [DDP_COMPONENT_AAL1] = MT2712_MUTEX_MOD2_DISP_AAL1, 182 [DDP_COMPONENT_COLOR0] = MT2712_MUTEX_MOD_DISP_COLOR0, 183 [DDP_COMPONENT_COLOR1] = MT2712_MUTEX_MOD_DISP_COLOR1, 184 [DDP_COMPONENT_OD0] = MT2712_MUTEX_MOD_DISP_OD0, 185 [DDP_COMPONENT_OD1] = MT2712_MUTEX_MOD2_DISP_OD1, 186 [DDP_COMPONENT_OVL0] = MT2712_MUTEX_MOD_DISP_OVL0, 187 [DDP_COMPONENT_OVL1] = MT2712_MUTEX_MOD_DISP_OVL1, 188 [DDP_COMPONENT_PWM0] = MT2712_MUTEX_MOD_DISP_PWM0, 189 [DDP_COMPONENT_PWM1] = MT2712_MUTEX_MOD_DISP_PWM1, 190 [DDP_COMPONENT_PWM2] = MT2712_MUTEX_MOD_DISP_PWM2, 191 [DDP_COMPONENT_RDMA0] = MT2712_MUTEX_MOD_DISP_RDMA0, 192 [DDP_COMPONENT_RDMA1] = MT2712_MUTEX_MOD_DISP_RDMA1, 193 [DDP_COMPONENT_RDMA2] = MT2712_MUTEX_MOD_DISP_RDMA2, 194 [DDP_COMPONENT_UFOE] = MT2712_MUTEX_MOD_DISP_UFOE, 195 [DDP_COMPONENT_WDMA0] = MT2712_MUTEX_MOD_DISP_WDMA0, 196 [DDP_COMPONENT_WDMA1] = MT2712_MUTEX_MOD_DISP_WDMA1, 197 }; 198 199 static const unsigned int mt8167_mutex_mod[DDP_COMPONENT_ID_MAX] = { 200 [DDP_COMPONENT_AAL0] = MT8167_MUTEX_MOD_DISP_AAL, 201 [DDP_COMPONENT_CCORR] = MT8167_MUTEX_MOD_DISP_CCORR, 202 [DDP_COMPONENT_COLOR0] = MT8167_MUTEX_MOD_DISP_COLOR, 203 [DDP_COMPONENT_DITHER] = MT8167_MUTEX_MOD_DISP_DITHER, 204 [DDP_COMPONENT_GAMMA] = MT8167_MUTEX_MOD_DISP_GAMMA, 205 [DDP_COMPONENT_OVL0] = MT8167_MUTEX_MOD_DISP_OVL0, 206 [DDP_COMPONENT_OVL1] = MT8167_MUTEX_MOD_DISP_OVL1, 207 [DDP_COMPONENT_PWM0] = MT8167_MUTEX_MOD_DISP_PWM, 208 [DDP_COMPONENT_RDMA0] = MT8167_MUTEX_MOD_DISP_RDMA0, 209 [DDP_COMPONENT_RDMA1] = MT8167_MUTEX_MOD_DISP_RDMA1, 210 [DDP_COMPONENT_UFOE] = MT8167_MUTEX_MOD_DISP_UFOE, 211 [DDP_COMPONENT_WDMA0] = MT8167_MUTEX_MOD_DISP_WDMA0, 212 }; 213 214 static const unsigned int mt8173_mutex_mod[DDP_COMPONENT_ID_MAX] = { 215 [DDP_COMPONENT_AAL0] = MT8173_MUTEX_MOD_DISP_AAL, 216 [DDP_COMPONENT_COLOR0] = MT8173_MUTEX_MOD_DISP_COLOR0, 217 [DDP_COMPONENT_COLOR1] = MT8173_MUTEX_MOD_DISP_COLOR1, 218 [DDP_COMPONENT_GAMMA] = MT8173_MUTEX_MOD_DISP_GAMMA, 219 [DDP_COMPONENT_OD0] = MT8173_MUTEX_MOD_DISP_OD, 220 [DDP_COMPONENT_OVL0] = MT8173_MUTEX_MOD_DISP_OVL0, 221 [DDP_COMPONENT_OVL1] = MT8173_MUTEX_MOD_DISP_OVL1, 222 [DDP_COMPONENT_PWM0] = MT8173_MUTEX_MOD_DISP_PWM0, 223 [DDP_COMPONENT_PWM1] = MT8173_MUTEX_MOD_DISP_PWM1, 224 [DDP_COMPONENT_RDMA0] = MT8173_MUTEX_MOD_DISP_RDMA0, 225 [DDP_COMPONENT_RDMA1] = MT8173_MUTEX_MOD_DISP_RDMA1, 226 [DDP_COMPONENT_RDMA2] = MT8173_MUTEX_MOD_DISP_RDMA2, 227 [DDP_COMPONENT_UFOE] = MT8173_MUTEX_MOD_DISP_UFOE, 228 [DDP_COMPONENT_WDMA0] = MT8173_MUTEX_MOD_DISP_WDMA0, 229 [DDP_COMPONENT_WDMA1] = MT8173_MUTEX_MOD_DISP_WDMA1, 230 }; 231 232 static const unsigned int mt8183_mutex_mod[DDP_COMPONENT_ID_MAX] = { 233 [DDP_COMPONENT_AAL0] = MT8183_MUTEX_MOD_DISP_AAL0, 234 [DDP_COMPONENT_CCORR] = MT8183_MUTEX_MOD_DISP_CCORR0, 235 [DDP_COMPONENT_COLOR0] = MT8183_MUTEX_MOD_DISP_COLOR0, 236 [DDP_COMPONENT_DITHER] = MT8183_MUTEX_MOD_DISP_DITHER0, 237 [DDP_COMPONENT_GAMMA] = MT8183_MUTEX_MOD_DISP_GAMMA0, 238 [DDP_COMPONENT_OVL0] = MT8183_MUTEX_MOD_DISP_OVL0, 239 [DDP_COMPONENT_OVL_2L0] = MT8183_MUTEX_MOD_DISP_OVL0_2L, 240 [DDP_COMPONENT_OVL_2L1] = MT8183_MUTEX_MOD_DISP_OVL1_2L, 241 [DDP_COMPONENT_RDMA0] = MT8183_MUTEX_MOD_DISP_RDMA0, 242 [DDP_COMPONENT_RDMA1] = MT8183_MUTEX_MOD_DISP_RDMA1, 243 [DDP_COMPONENT_WDMA0] = MT8183_MUTEX_MOD_DISP_WDMA0, 244 }; 245 246 static const unsigned int mt8186_mutex_mod[DDP_COMPONENT_ID_MAX] = { 247 [DDP_COMPONENT_AAL0] = MT8186_MUTEX_MOD_DISP_AAL0, 248 [DDP_COMPONENT_CCORR] = MT8186_MUTEX_MOD_DISP_CCORR0, 249 [DDP_COMPONENT_COLOR0] = MT8186_MUTEX_MOD_DISP_COLOR0, 250 [DDP_COMPONENT_DITHER] = MT8186_MUTEX_MOD_DISP_DITHER0, 251 [DDP_COMPONENT_GAMMA] = MT8186_MUTEX_MOD_DISP_GAMMA0, 252 [DDP_COMPONENT_OVL0] = MT8186_MUTEX_MOD_DISP_OVL0, 253 [DDP_COMPONENT_OVL_2L0] = MT8186_MUTEX_MOD_DISP_OVL0_2L, 254 [DDP_COMPONENT_POSTMASK0] = MT8186_MUTEX_MOD_DISP_POSTMASK0, 255 [DDP_COMPONENT_RDMA0] = MT8186_MUTEX_MOD_DISP_RDMA0, 256 [DDP_COMPONENT_RDMA1] = MT8186_MUTEX_MOD_DISP_RDMA1, 257 }; 258 259 static const unsigned int mt8192_mutex_mod[DDP_COMPONENT_ID_MAX] = { 260 [DDP_COMPONENT_AAL0] = MT8192_MUTEX_MOD_DISP_AAL0, 261 [DDP_COMPONENT_CCORR] = MT8192_MUTEX_MOD_DISP_CCORR0, 262 [DDP_COMPONENT_COLOR0] = MT8192_MUTEX_MOD_DISP_COLOR0, 263 [DDP_COMPONENT_DITHER] = MT8192_MUTEX_MOD_DISP_DITHER0, 264 [DDP_COMPONENT_GAMMA] = MT8192_MUTEX_MOD_DISP_GAMMA0, 265 [DDP_COMPONENT_POSTMASK0] = MT8192_MUTEX_MOD_DISP_POSTMASK0, 266 [DDP_COMPONENT_OVL0] = MT8192_MUTEX_MOD_DISP_OVL0, 267 [DDP_COMPONENT_OVL_2L0] = MT8192_MUTEX_MOD_DISP_OVL0_2L, 268 [DDP_COMPONENT_OVL_2L2] = MT8192_MUTEX_MOD_DISP_OVL2_2L, 269 [DDP_COMPONENT_RDMA0] = MT8192_MUTEX_MOD_DISP_RDMA0, 270 [DDP_COMPONENT_RDMA4] = MT8192_MUTEX_MOD_DISP_RDMA4, 271 }; 272 273 static const unsigned int mt2712_mutex_sof[MUTEX_SOF_DSI3 + 1] = { 274 [MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE, 275 [MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0, 276 [MUTEX_SOF_DSI1] = MUTEX_SOF_DSI1, 277 [MUTEX_SOF_DPI0] = MUTEX_SOF_DPI0, 278 [MUTEX_SOF_DPI1] = MUTEX_SOF_DPI1, 279 [MUTEX_SOF_DSI2] = MUTEX_SOF_DSI2, 280 [MUTEX_SOF_DSI3] = MUTEX_SOF_DSI3, 281 }; 282 283 static const unsigned int mt8167_mutex_sof[MUTEX_SOF_DSI3 + 1] = { 284 [MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE, 285 [MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0, 286 [MUTEX_SOF_DPI0] = MT8167_MUTEX_SOF_DPI0, 287 [MUTEX_SOF_DPI1] = MT8167_MUTEX_SOF_DPI1, 288 }; 289 290 /* Add EOF setting so overlay hardware can receive frame done irq */ 291 static const unsigned int mt8183_mutex_sof[MUTEX_SOF_DSI3 + 1] = { 292 [MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE, 293 [MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0 | MT8183_MUTEX_EOF_DSI0, 294 [MUTEX_SOF_DPI0] = MT8183_MUTEX_SOF_DPI0 | MT8183_MUTEX_EOF_DPI0, 295 }; 296 297 static const unsigned int mt8186_mutex_sof[MUTEX_SOF_DSI3 + 1] = { 298 [MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE, 299 [MUTEX_SOF_DSI0] = MT8186_MUTEX_SOF_DSI0 | MT8186_MUTEX_EOF_DSI0, 300 [MUTEX_SOF_DPI0] = MT8186_MUTEX_SOF_DPI0 | MT8186_MUTEX_EOF_DPI0, 301 }; 302 303 static const struct mtk_mutex_data mt2701_mutex_driver_data = { 304 .mutex_mod = mt2701_mutex_mod, 305 .mutex_sof = mt2712_mutex_sof, 306 .mutex_mod_reg = MT2701_MUTEX0_MOD0, 307 .mutex_sof_reg = MT2701_MUTEX0_SOF0, 308 }; 309 310 static const struct mtk_mutex_data mt2712_mutex_driver_data = { 311 .mutex_mod = mt2712_mutex_mod, 312 .mutex_sof = mt2712_mutex_sof, 313 .mutex_mod_reg = MT2701_MUTEX0_MOD0, 314 .mutex_sof_reg = MT2701_MUTEX0_SOF0, 315 }; 316 317 static const struct mtk_mutex_data mt8167_mutex_driver_data = { 318 .mutex_mod = mt8167_mutex_mod, 319 .mutex_sof = mt8167_mutex_sof, 320 .mutex_mod_reg = MT2701_MUTEX0_MOD0, 321 .mutex_sof_reg = MT2701_MUTEX0_SOF0, 322 .no_clk = true, 323 }; 324 325 static const struct mtk_mutex_data mt8173_mutex_driver_data = { 326 .mutex_mod = mt8173_mutex_mod, 327 .mutex_sof = mt2712_mutex_sof, 328 .mutex_mod_reg = MT2701_MUTEX0_MOD0, 329 .mutex_sof_reg = MT2701_MUTEX0_SOF0, 330 }; 331 332 static const struct mtk_mutex_data mt8183_mutex_driver_data = { 333 .mutex_mod = mt8183_mutex_mod, 334 .mutex_sof = mt8183_mutex_sof, 335 .mutex_mod_reg = MT8183_MUTEX0_MOD0, 336 .mutex_sof_reg = MT8183_MUTEX0_SOF0, 337 .no_clk = true, 338 }; 339 340 static const struct mtk_mutex_data mt8186_mutex_driver_data = { 341 .mutex_mod = mt8186_mutex_mod, 342 .mutex_sof = mt8186_mutex_sof, 343 .mutex_mod_reg = MT8183_MUTEX0_MOD0, 344 .mutex_sof_reg = MT8183_MUTEX0_SOF0, 345 }; 346 347 static const struct mtk_mutex_data mt8192_mutex_driver_data = { 348 .mutex_mod = mt8192_mutex_mod, 349 .mutex_sof = mt8183_mutex_sof, 350 .mutex_mod_reg = MT8183_MUTEX0_MOD0, 351 .mutex_sof_reg = MT8183_MUTEX0_SOF0, 352 }; 353 354 struct mtk_mutex *mtk_mutex_get(struct device *dev) 355 { 356 struct mtk_mutex_ctx *mtx = dev_get_drvdata(dev); 357 int i; 358 359 for (i = 0; i < 10; i++) 360 if (!mtx->mutex[i].claimed) { 361 mtx->mutex[i].claimed = true; 362 return &mtx->mutex[i]; 363 } 364 365 return ERR_PTR(-EBUSY); 366 } 367 EXPORT_SYMBOL_GPL(mtk_mutex_get); 368 369 void mtk_mutex_put(struct mtk_mutex *mutex) 370 { 371 struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx, 372 mutex[mutex->id]); 373 374 WARN_ON(&mtx->mutex[mutex->id] != mutex); 375 376 mutex->claimed = false; 377 } 378 EXPORT_SYMBOL_GPL(mtk_mutex_put); 379 380 int mtk_mutex_prepare(struct mtk_mutex *mutex) 381 { 382 struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx, 383 mutex[mutex->id]); 384 return clk_prepare_enable(mtx->clk); 385 } 386 EXPORT_SYMBOL_GPL(mtk_mutex_prepare); 387 388 void mtk_mutex_unprepare(struct mtk_mutex *mutex) 389 { 390 struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx, 391 mutex[mutex->id]); 392 clk_disable_unprepare(mtx->clk); 393 } 394 EXPORT_SYMBOL_GPL(mtk_mutex_unprepare); 395 396 void mtk_mutex_add_comp(struct mtk_mutex *mutex, 397 enum mtk_ddp_comp_id id) 398 { 399 struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx, 400 mutex[mutex->id]); 401 unsigned int reg; 402 unsigned int sof_id; 403 unsigned int offset; 404 405 WARN_ON(&mtx->mutex[mutex->id] != mutex); 406 407 switch (id) { 408 case DDP_COMPONENT_DSI0: 409 sof_id = MUTEX_SOF_DSI0; 410 break; 411 case DDP_COMPONENT_DSI1: 412 sof_id = MUTEX_SOF_DSI0; 413 break; 414 case DDP_COMPONENT_DSI2: 415 sof_id = MUTEX_SOF_DSI2; 416 break; 417 case DDP_COMPONENT_DSI3: 418 sof_id = MUTEX_SOF_DSI3; 419 break; 420 case DDP_COMPONENT_DPI0: 421 sof_id = MUTEX_SOF_DPI0; 422 break; 423 case DDP_COMPONENT_DPI1: 424 sof_id = MUTEX_SOF_DPI1; 425 break; 426 default: 427 if (mtx->data->mutex_mod[id] < 32) { 428 offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg, 429 mutex->id); 430 reg = readl_relaxed(mtx->regs + offset); 431 reg |= 1 << mtx->data->mutex_mod[id]; 432 writel_relaxed(reg, mtx->regs + offset); 433 } else { 434 offset = DISP_REG_MUTEX_MOD2(mutex->id); 435 reg = readl_relaxed(mtx->regs + offset); 436 reg |= 1 << (mtx->data->mutex_mod[id] - 32); 437 writel_relaxed(reg, mtx->regs + offset); 438 } 439 return; 440 } 441 442 writel_relaxed(mtx->data->mutex_sof[sof_id], 443 mtx->regs + 444 DISP_REG_MUTEX_SOF(mtx->data->mutex_sof_reg, mutex->id)); 445 } 446 EXPORT_SYMBOL_GPL(mtk_mutex_add_comp); 447 448 void mtk_mutex_remove_comp(struct mtk_mutex *mutex, 449 enum mtk_ddp_comp_id id) 450 { 451 struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx, 452 mutex[mutex->id]); 453 unsigned int reg; 454 unsigned int offset; 455 456 WARN_ON(&mtx->mutex[mutex->id] != mutex); 457 458 switch (id) { 459 case DDP_COMPONENT_DSI0: 460 case DDP_COMPONENT_DSI1: 461 case DDP_COMPONENT_DSI2: 462 case DDP_COMPONENT_DSI3: 463 case DDP_COMPONENT_DPI0: 464 case DDP_COMPONENT_DPI1: 465 writel_relaxed(MUTEX_SOF_SINGLE_MODE, 466 mtx->regs + 467 DISP_REG_MUTEX_SOF(mtx->data->mutex_sof_reg, 468 mutex->id)); 469 break; 470 default: 471 if (mtx->data->mutex_mod[id] < 32) { 472 offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg, 473 mutex->id); 474 reg = readl_relaxed(mtx->regs + offset); 475 reg &= ~(1 << mtx->data->mutex_mod[id]); 476 writel_relaxed(reg, mtx->regs + offset); 477 } else { 478 offset = DISP_REG_MUTEX_MOD2(mutex->id); 479 reg = readl_relaxed(mtx->regs + offset); 480 reg &= ~(1 << (mtx->data->mutex_mod[id] - 32)); 481 writel_relaxed(reg, mtx->regs + offset); 482 } 483 break; 484 } 485 } 486 EXPORT_SYMBOL_GPL(mtk_mutex_remove_comp); 487 488 void mtk_mutex_enable(struct mtk_mutex *mutex) 489 { 490 struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx, 491 mutex[mutex->id]); 492 493 WARN_ON(&mtx->mutex[mutex->id] != mutex); 494 495 writel(1, mtx->regs + DISP_REG_MUTEX_EN(mutex->id)); 496 } 497 EXPORT_SYMBOL_GPL(mtk_mutex_enable); 498 499 void mtk_mutex_disable(struct mtk_mutex *mutex) 500 { 501 struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx, 502 mutex[mutex->id]); 503 504 WARN_ON(&mtx->mutex[mutex->id] != mutex); 505 506 writel(0, mtx->regs + DISP_REG_MUTEX_EN(mutex->id)); 507 } 508 EXPORT_SYMBOL_GPL(mtk_mutex_disable); 509 510 void mtk_mutex_acquire(struct mtk_mutex *mutex) 511 { 512 struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx, 513 mutex[mutex->id]); 514 u32 tmp; 515 516 writel(1, mtx->regs + DISP_REG_MUTEX_EN(mutex->id)); 517 writel(1, mtx->regs + DISP_REG_MUTEX(mutex->id)); 518 if (readl_poll_timeout_atomic(mtx->regs + DISP_REG_MUTEX(mutex->id), 519 tmp, tmp & INT_MUTEX, 1, 10000)) 520 pr_err("could not acquire mutex %d\n", mutex->id); 521 } 522 EXPORT_SYMBOL_GPL(mtk_mutex_acquire); 523 524 void mtk_mutex_release(struct mtk_mutex *mutex) 525 { 526 struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx, 527 mutex[mutex->id]); 528 529 writel(0, mtx->regs + DISP_REG_MUTEX(mutex->id)); 530 } 531 EXPORT_SYMBOL_GPL(mtk_mutex_release); 532 533 static int mtk_mutex_probe(struct platform_device *pdev) 534 { 535 struct device *dev = &pdev->dev; 536 struct mtk_mutex_ctx *mtx; 537 struct resource *regs; 538 int i; 539 540 mtx = devm_kzalloc(dev, sizeof(*mtx), GFP_KERNEL); 541 if (!mtx) 542 return -ENOMEM; 543 544 for (i = 0; i < 10; i++) 545 mtx->mutex[i].id = i; 546 547 mtx->data = of_device_get_match_data(dev); 548 549 if (!mtx->data->no_clk) { 550 mtx->clk = devm_clk_get(dev, NULL); 551 if (IS_ERR(mtx->clk)) { 552 if (PTR_ERR(mtx->clk) != -EPROBE_DEFER) 553 dev_err(dev, "Failed to get clock\n"); 554 return PTR_ERR(mtx->clk); 555 } 556 } 557 558 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); 559 mtx->regs = devm_ioremap_resource(dev, regs); 560 if (IS_ERR(mtx->regs)) { 561 dev_err(dev, "Failed to map mutex registers\n"); 562 return PTR_ERR(mtx->regs); 563 } 564 565 platform_set_drvdata(pdev, mtx); 566 567 return 0; 568 } 569 570 static int mtk_mutex_remove(struct platform_device *pdev) 571 { 572 return 0; 573 } 574 575 static const struct of_device_id mutex_driver_dt_match[] = { 576 { .compatible = "mediatek,mt2701-disp-mutex", 577 .data = &mt2701_mutex_driver_data}, 578 { .compatible = "mediatek,mt2712-disp-mutex", 579 .data = &mt2712_mutex_driver_data}, 580 { .compatible = "mediatek,mt8167-disp-mutex", 581 .data = &mt8167_mutex_driver_data}, 582 { .compatible = "mediatek,mt8173-disp-mutex", 583 .data = &mt8173_mutex_driver_data}, 584 { .compatible = "mediatek,mt8183-disp-mutex", 585 .data = &mt8183_mutex_driver_data}, 586 { .compatible = "mediatek,mt8186-disp-mutex", 587 .data = &mt8186_mutex_driver_data}, 588 { .compatible = "mediatek,mt8192-disp-mutex", 589 .data = &mt8192_mutex_driver_data}, 590 {}, 591 }; 592 MODULE_DEVICE_TABLE(of, mutex_driver_dt_match); 593 594 static struct platform_driver mtk_mutex_driver = { 595 .probe = mtk_mutex_probe, 596 .remove = mtk_mutex_remove, 597 .driver = { 598 .name = "mediatek-mutex", 599 .owner = THIS_MODULE, 600 .of_match_table = mutex_driver_dt_match, 601 }, 602 }; 603 604 builtin_platform_driver(mtk_mutex_driver); 605