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