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