Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.11-rc4 464 lines 14 kB view raw
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 13#include "mtk_drm_ddp.h" 14#include "mtk_drm_ddp_comp.h" 15 16#define MT2701_DISP_MUTEX0_MOD0 0x2c 17#define MT2701_DISP_MUTEX0_SOF0 0x30 18 19#define DISP_REG_MUTEX_EN(n) (0x20 + 0x20 * (n)) 20#define DISP_REG_MUTEX(n) (0x24 + 0x20 * (n)) 21#define DISP_REG_MUTEX_RST(n) (0x28 + 0x20 * (n)) 22#define DISP_REG_MUTEX_MOD(mutex_mod_reg, n) (mutex_mod_reg + 0x20 * (n)) 23#define DISP_REG_MUTEX_SOF(mutex_sof_reg, n) (mutex_sof_reg + 0x20 * (n)) 24#define DISP_REG_MUTEX_MOD2(n) (0x34 + 0x20 * (n)) 25 26#define INT_MUTEX BIT(1) 27 28#define MT8167_MUTEX_MOD_DISP_PWM 1 29#define MT8167_MUTEX_MOD_DISP_OVL0 6 30#define MT8167_MUTEX_MOD_DISP_OVL1 7 31#define MT8167_MUTEX_MOD_DISP_RDMA0 8 32#define MT8167_MUTEX_MOD_DISP_RDMA1 9 33#define MT8167_MUTEX_MOD_DISP_WDMA0 10 34#define MT8167_MUTEX_MOD_DISP_CCORR 11 35#define MT8167_MUTEX_MOD_DISP_COLOR 12 36#define MT8167_MUTEX_MOD_DISP_AAL 13 37#define MT8167_MUTEX_MOD_DISP_GAMMA 14 38#define MT8167_MUTEX_MOD_DISP_DITHER 15 39#define MT8167_MUTEX_MOD_DISP_UFOE 16 40 41#define MT8173_MUTEX_MOD_DISP_OVL0 11 42#define MT8173_MUTEX_MOD_DISP_OVL1 12 43#define MT8173_MUTEX_MOD_DISP_RDMA0 13 44#define MT8173_MUTEX_MOD_DISP_RDMA1 14 45#define MT8173_MUTEX_MOD_DISP_RDMA2 15 46#define MT8173_MUTEX_MOD_DISP_WDMA0 16 47#define MT8173_MUTEX_MOD_DISP_WDMA1 17 48#define MT8173_MUTEX_MOD_DISP_COLOR0 18 49#define MT8173_MUTEX_MOD_DISP_COLOR1 19 50#define MT8173_MUTEX_MOD_DISP_AAL 20 51#define MT8173_MUTEX_MOD_DISP_GAMMA 21 52#define MT8173_MUTEX_MOD_DISP_UFOE 22 53#define MT8173_MUTEX_MOD_DISP_PWM0 23 54#define MT8173_MUTEX_MOD_DISP_PWM1 24 55#define MT8173_MUTEX_MOD_DISP_OD 25 56 57#define MT2712_MUTEX_MOD_DISP_PWM2 10 58#define MT2712_MUTEX_MOD_DISP_OVL0 11 59#define MT2712_MUTEX_MOD_DISP_OVL1 12 60#define MT2712_MUTEX_MOD_DISP_RDMA0 13 61#define MT2712_MUTEX_MOD_DISP_RDMA1 14 62#define MT2712_MUTEX_MOD_DISP_RDMA2 15 63#define MT2712_MUTEX_MOD_DISP_WDMA0 16 64#define MT2712_MUTEX_MOD_DISP_WDMA1 17 65#define MT2712_MUTEX_MOD_DISP_COLOR0 18 66#define MT2712_MUTEX_MOD_DISP_COLOR1 19 67#define MT2712_MUTEX_MOD_DISP_AAL0 20 68#define MT2712_MUTEX_MOD_DISP_UFOE 22 69#define MT2712_MUTEX_MOD_DISP_PWM0 23 70#define MT2712_MUTEX_MOD_DISP_PWM1 24 71#define MT2712_MUTEX_MOD_DISP_OD0 25 72#define MT2712_MUTEX_MOD2_DISP_AAL1 33 73#define MT2712_MUTEX_MOD2_DISP_OD1 34 74 75#define MT2701_MUTEX_MOD_DISP_OVL 3 76#define MT2701_MUTEX_MOD_DISP_WDMA 6 77#define MT2701_MUTEX_MOD_DISP_COLOR 7 78#define MT2701_MUTEX_MOD_DISP_BLS 9 79#define MT2701_MUTEX_MOD_DISP_RDMA0 10 80#define MT2701_MUTEX_MOD_DISP_RDMA1 12 81 82#define MUTEX_SOF_SINGLE_MODE 0 83#define MUTEX_SOF_DSI0 1 84#define MUTEX_SOF_DSI1 2 85#define MUTEX_SOF_DPI0 3 86#define MUTEX_SOF_DPI1 4 87#define MUTEX_SOF_DSI2 5 88#define MUTEX_SOF_DSI3 6 89#define MT8167_MUTEX_SOF_DPI0 2 90#define MT8167_MUTEX_SOF_DPI1 3 91 92 93struct mtk_disp_mutex { 94 int id; 95 bool claimed; 96}; 97 98enum mtk_ddp_mutex_sof_id { 99 DDP_MUTEX_SOF_SINGLE_MODE, 100 DDP_MUTEX_SOF_DSI0, 101 DDP_MUTEX_SOF_DSI1, 102 DDP_MUTEX_SOF_DPI0, 103 DDP_MUTEX_SOF_DPI1, 104 DDP_MUTEX_SOF_DSI2, 105 DDP_MUTEX_SOF_DSI3, 106}; 107 108struct mtk_ddp_data { 109 const unsigned int *mutex_mod; 110 const unsigned int *mutex_sof; 111 const unsigned int mutex_mod_reg; 112 const unsigned int mutex_sof_reg; 113 const bool no_clk; 114}; 115 116struct mtk_ddp { 117 struct device *dev; 118 struct clk *clk; 119 void __iomem *regs; 120 struct mtk_disp_mutex mutex[10]; 121 const struct mtk_ddp_data *data; 122}; 123 124static const unsigned int mt2701_mutex_mod[DDP_COMPONENT_ID_MAX] = { 125 [DDP_COMPONENT_BLS] = MT2701_MUTEX_MOD_DISP_BLS, 126 [DDP_COMPONENT_COLOR0] = MT2701_MUTEX_MOD_DISP_COLOR, 127 [DDP_COMPONENT_OVL0] = MT2701_MUTEX_MOD_DISP_OVL, 128 [DDP_COMPONENT_RDMA0] = MT2701_MUTEX_MOD_DISP_RDMA0, 129 [DDP_COMPONENT_RDMA1] = MT2701_MUTEX_MOD_DISP_RDMA1, 130 [DDP_COMPONENT_WDMA0] = MT2701_MUTEX_MOD_DISP_WDMA, 131}; 132 133static const unsigned int mt2712_mutex_mod[DDP_COMPONENT_ID_MAX] = { 134 [DDP_COMPONENT_AAL0] = MT2712_MUTEX_MOD_DISP_AAL0, 135 [DDP_COMPONENT_AAL1] = MT2712_MUTEX_MOD2_DISP_AAL1, 136 [DDP_COMPONENT_COLOR0] = MT2712_MUTEX_MOD_DISP_COLOR0, 137 [DDP_COMPONENT_COLOR1] = MT2712_MUTEX_MOD_DISP_COLOR1, 138 [DDP_COMPONENT_OD0] = MT2712_MUTEX_MOD_DISP_OD0, 139 [DDP_COMPONENT_OD1] = MT2712_MUTEX_MOD2_DISP_OD1, 140 [DDP_COMPONENT_OVL0] = MT2712_MUTEX_MOD_DISP_OVL0, 141 [DDP_COMPONENT_OVL1] = MT2712_MUTEX_MOD_DISP_OVL1, 142 [DDP_COMPONENT_PWM0] = MT2712_MUTEX_MOD_DISP_PWM0, 143 [DDP_COMPONENT_PWM1] = MT2712_MUTEX_MOD_DISP_PWM1, 144 [DDP_COMPONENT_PWM2] = MT2712_MUTEX_MOD_DISP_PWM2, 145 [DDP_COMPONENT_RDMA0] = MT2712_MUTEX_MOD_DISP_RDMA0, 146 [DDP_COMPONENT_RDMA1] = MT2712_MUTEX_MOD_DISP_RDMA1, 147 [DDP_COMPONENT_RDMA2] = MT2712_MUTEX_MOD_DISP_RDMA2, 148 [DDP_COMPONENT_UFOE] = MT2712_MUTEX_MOD_DISP_UFOE, 149 [DDP_COMPONENT_WDMA0] = MT2712_MUTEX_MOD_DISP_WDMA0, 150 [DDP_COMPONENT_WDMA1] = MT2712_MUTEX_MOD_DISP_WDMA1, 151}; 152 153static const unsigned int mt8167_mutex_mod[DDP_COMPONENT_ID_MAX] = { 154 [DDP_COMPONENT_AAL0] = MT8167_MUTEX_MOD_DISP_AAL, 155 [DDP_COMPONENT_CCORR] = MT8167_MUTEX_MOD_DISP_CCORR, 156 [DDP_COMPONENT_COLOR0] = MT8167_MUTEX_MOD_DISP_COLOR, 157 [DDP_COMPONENT_DITHER] = MT8167_MUTEX_MOD_DISP_DITHER, 158 [DDP_COMPONENT_GAMMA] = MT8167_MUTEX_MOD_DISP_GAMMA, 159 [DDP_COMPONENT_OVL0] = MT8167_MUTEX_MOD_DISP_OVL0, 160 [DDP_COMPONENT_OVL1] = MT8167_MUTEX_MOD_DISP_OVL1, 161 [DDP_COMPONENT_PWM0] = MT8167_MUTEX_MOD_DISP_PWM, 162 [DDP_COMPONENT_RDMA0] = MT8167_MUTEX_MOD_DISP_RDMA0, 163 [DDP_COMPONENT_RDMA1] = MT8167_MUTEX_MOD_DISP_RDMA1, 164 [DDP_COMPONENT_UFOE] = MT8167_MUTEX_MOD_DISP_UFOE, 165 [DDP_COMPONENT_WDMA0] = MT8167_MUTEX_MOD_DISP_WDMA0, 166}; 167 168static const unsigned int mt8173_mutex_mod[DDP_COMPONENT_ID_MAX] = { 169 [DDP_COMPONENT_AAL0] = MT8173_MUTEX_MOD_DISP_AAL, 170 [DDP_COMPONENT_COLOR0] = MT8173_MUTEX_MOD_DISP_COLOR0, 171 [DDP_COMPONENT_COLOR1] = MT8173_MUTEX_MOD_DISP_COLOR1, 172 [DDP_COMPONENT_GAMMA] = MT8173_MUTEX_MOD_DISP_GAMMA, 173 [DDP_COMPONENT_OD0] = MT8173_MUTEX_MOD_DISP_OD, 174 [DDP_COMPONENT_OVL0] = MT8173_MUTEX_MOD_DISP_OVL0, 175 [DDP_COMPONENT_OVL1] = MT8173_MUTEX_MOD_DISP_OVL1, 176 [DDP_COMPONENT_PWM0] = MT8173_MUTEX_MOD_DISP_PWM0, 177 [DDP_COMPONENT_PWM1] = MT8173_MUTEX_MOD_DISP_PWM1, 178 [DDP_COMPONENT_RDMA0] = MT8173_MUTEX_MOD_DISP_RDMA0, 179 [DDP_COMPONENT_RDMA1] = MT8173_MUTEX_MOD_DISP_RDMA1, 180 [DDP_COMPONENT_RDMA2] = MT8173_MUTEX_MOD_DISP_RDMA2, 181 [DDP_COMPONENT_UFOE] = MT8173_MUTEX_MOD_DISP_UFOE, 182 [DDP_COMPONENT_WDMA0] = MT8173_MUTEX_MOD_DISP_WDMA0, 183 [DDP_COMPONENT_WDMA1] = MT8173_MUTEX_MOD_DISP_WDMA1, 184}; 185 186static const unsigned int mt2712_mutex_sof[DDP_MUTEX_SOF_DSI3 + 1] = { 187 [DDP_MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE, 188 [DDP_MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0, 189 [DDP_MUTEX_SOF_DSI1] = MUTEX_SOF_DSI1, 190 [DDP_MUTEX_SOF_DPI0] = MUTEX_SOF_DPI0, 191 [DDP_MUTEX_SOF_DPI1] = MUTEX_SOF_DPI1, 192 [DDP_MUTEX_SOF_DSI2] = MUTEX_SOF_DSI2, 193 [DDP_MUTEX_SOF_DSI3] = MUTEX_SOF_DSI3, 194}; 195 196static const unsigned int mt8167_mutex_sof[DDP_MUTEX_SOF_DSI3 + 1] = { 197 [DDP_MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE, 198 [DDP_MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0, 199 [DDP_MUTEX_SOF_DPI0] = MT8167_MUTEX_SOF_DPI0, 200 [DDP_MUTEX_SOF_DPI1] = MT8167_MUTEX_SOF_DPI1, 201}; 202 203static const struct mtk_ddp_data mt2701_ddp_driver_data = { 204 .mutex_mod = mt2701_mutex_mod, 205 .mutex_sof = mt2712_mutex_sof, 206 .mutex_mod_reg = MT2701_DISP_MUTEX0_MOD0, 207 .mutex_sof_reg = MT2701_DISP_MUTEX0_SOF0, 208}; 209 210static const struct mtk_ddp_data mt2712_ddp_driver_data = { 211 .mutex_mod = mt2712_mutex_mod, 212 .mutex_sof = mt2712_mutex_sof, 213 .mutex_mod_reg = MT2701_DISP_MUTEX0_MOD0, 214 .mutex_sof_reg = MT2701_DISP_MUTEX0_SOF0, 215}; 216 217static const struct mtk_ddp_data mt8167_ddp_driver_data = { 218 .mutex_mod = mt8167_mutex_mod, 219 .mutex_sof = mt8167_mutex_sof, 220 .mutex_mod_reg = MT2701_DISP_MUTEX0_MOD0, 221 .mutex_sof_reg = MT2701_DISP_MUTEX0_SOF0, 222 .no_clk = true, 223}; 224 225static const struct mtk_ddp_data mt8173_ddp_driver_data = { 226 .mutex_mod = mt8173_mutex_mod, 227 .mutex_sof = mt2712_mutex_sof, 228 .mutex_mod_reg = MT2701_DISP_MUTEX0_MOD0, 229 .mutex_sof_reg = MT2701_DISP_MUTEX0_SOF0, 230}; 231 232struct mtk_disp_mutex *mtk_disp_mutex_get(struct device *dev, unsigned int id) 233{ 234 struct mtk_ddp *ddp = dev_get_drvdata(dev); 235 236 if (id >= 10) 237 return ERR_PTR(-EINVAL); 238 if (ddp->mutex[id].claimed) 239 return ERR_PTR(-EBUSY); 240 241 ddp->mutex[id].claimed = true; 242 243 return &ddp->mutex[id]; 244} 245 246void mtk_disp_mutex_put(struct mtk_disp_mutex *mutex) 247{ 248 struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp, 249 mutex[mutex->id]); 250 251 WARN_ON(&ddp->mutex[mutex->id] != mutex); 252 253 mutex->claimed = false; 254} 255 256int mtk_disp_mutex_prepare(struct mtk_disp_mutex *mutex) 257{ 258 struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp, 259 mutex[mutex->id]); 260 return clk_prepare_enable(ddp->clk); 261} 262 263void mtk_disp_mutex_unprepare(struct mtk_disp_mutex *mutex) 264{ 265 struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp, 266 mutex[mutex->id]); 267 clk_disable_unprepare(ddp->clk); 268} 269 270void mtk_disp_mutex_add_comp(struct mtk_disp_mutex *mutex, 271 enum mtk_ddp_comp_id id) 272{ 273 struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp, 274 mutex[mutex->id]); 275 unsigned int reg; 276 unsigned int sof_id; 277 unsigned int offset; 278 279 WARN_ON(&ddp->mutex[mutex->id] != mutex); 280 281 switch (id) { 282 case DDP_COMPONENT_DSI0: 283 sof_id = DDP_MUTEX_SOF_DSI0; 284 break; 285 case DDP_COMPONENT_DSI1: 286 sof_id = DDP_MUTEX_SOF_DSI0; 287 break; 288 case DDP_COMPONENT_DSI2: 289 sof_id = DDP_MUTEX_SOF_DSI2; 290 break; 291 case DDP_COMPONENT_DSI3: 292 sof_id = DDP_MUTEX_SOF_DSI3; 293 break; 294 case DDP_COMPONENT_DPI0: 295 sof_id = DDP_MUTEX_SOF_DPI0; 296 break; 297 case DDP_COMPONENT_DPI1: 298 sof_id = DDP_MUTEX_SOF_DPI1; 299 break; 300 default: 301 if (ddp->data->mutex_mod[id] < 32) { 302 offset = DISP_REG_MUTEX_MOD(ddp->data->mutex_mod_reg, 303 mutex->id); 304 reg = readl_relaxed(ddp->regs + offset); 305 reg |= 1 << ddp->data->mutex_mod[id]; 306 writel_relaxed(reg, ddp->regs + offset); 307 } else { 308 offset = DISP_REG_MUTEX_MOD2(mutex->id); 309 reg = readl_relaxed(ddp->regs + offset); 310 reg |= 1 << (ddp->data->mutex_mod[id] - 32); 311 writel_relaxed(reg, ddp->regs + offset); 312 } 313 return; 314 } 315 316 writel_relaxed(ddp->data->mutex_sof[sof_id], 317 ddp->regs + 318 DISP_REG_MUTEX_SOF(ddp->data->mutex_sof_reg, mutex->id)); 319} 320 321void mtk_disp_mutex_remove_comp(struct mtk_disp_mutex *mutex, 322 enum mtk_ddp_comp_id id) 323{ 324 struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp, 325 mutex[mutex->id]); 326 unsigned int reg; 327 unsigned int offset; 328 329 WARN_ON(&ddp->mutex[mutex->id] != mutex); 330 331 switch (id) { 332 case DDP_COMPONENT_DSI0: 333 case DDP_COMPONENT_DSI1: 334 case DDP_COMPONENT_DSI2: 335 case DDP_COMPONENT_DSI3: 336 case DDP_COMPONENT_DPI0: 337 case DDP_COMPONENT_DPI1: 338 writel_relaxed(MUTEX_SOF_SINGLE_MODE, 339 ddp->regs + 340 DISP_REG_MUTEX_SOF(ddp->data->mutex_sof_reg, 341 mutex->id)); 342 break; 343 default: 344 if (ddp->data->mutex_mod[id] < 32) { 345 offset = DISP_REG_MUTEX_MOD(ddp->data->mutex_mod_reg, 346 mutex->id); 347 reg = readl_relaxed(ddp->regs + offset); 348 reg &= ~(1 << ddp->data->mutex_mod[id]); 349 writel_relaxed(reg, ddp->regs + offset); 350 } else { 351 offset = DISP_REG_MUTEX_MOD2(mutex->id); 352 reg = readl_relaxed(ddp->regs + offset); 353 reg &= ~(1 << (ddp->data->mutex_mod[id] - 32)); 354 writel_relaxed(reg, ddp->regs + offset); 355 } 356 break; 357 } 358} 359 360void mtk_disp_mutex_enable(struct mtk_disp_mutex *mutex) 361{ 362 struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp, 363 mutex[mutex->id]); 364 365 WARN_ON(&ddp->mutex[mutex->id] != mutex); 366 367 writel(1, ddp->regs + DISP_REG_MUTEX_EN(mutex->id)); 368} 369 370void mtk_disp_mutex_disable(struct mtk_disp_mutex *mutex) 371{ 372 struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp, 373 mutex[mutex->id]); 374 375 WARN_ON(&ddp->mutex[mutex->id] != mutex); 376 377 writel(0, ddp->regs + DISP_REG_MUTEX_EN(mutex->id)); 378} 379 380void mtk_disp_mutex_acquire(struct mtk_disp_mutex *mutex) 381{ 382 struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp, 383 mutex[mutex->id]); 384 u32 tmp; 385 386 writel(1, ddp->regs + DISP_REG_MUTEX_EN(mutex->id)); 387 writel(1, ddp->regs + DISP_REG_MUTEX(mutex->id)); 388 if (readl_poll_timeout_atomic(ddp->regs + DISP_REG_MUTEX(mutex->id), 389 tmp, tmp & INT_MUTEX, 1, 10000)) 390 pr_err("could not acquire mutex %d\n", mutex->id); 391} 392 393void mtk_disp_mutex_release(struct mtk_disp_mutex *mutex) 394{ 395 struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp, 396 mutex[mutex->id]); 397 398 writel(0, ddp->regs + DISP_REG_MUTEX(mutex->id)); 399} 400 401static int mtk_ddp_probe(struct platform_device *pdev) 402{ 403 struct device *dev = &pdev->dev; 404 struct mtk_ddp *ddp; 405 struct resource *regs; 406 int i; 407 408 ddp = devm_kzalloc(dev, sizeof(*ddp), GFP_KERNEL); 409 if (!ddp) 410 return -ENOMEM; 411 412 for (i = 0; i < 10; i++) 413 ddp->mutex[i].id = i; 414 415 ddp->data = of_device_get_match_data(dev); 416 417 if (!ddp->data->no_clk) { 418 ddp->clk = devm_clk_get(dev, NULL); 419 if (IS_ERR(ddp->clk)) { 420 if (PTR_ERR(ddp->clk) != -EPROBE_DEFER) 421 dev_err(dev, "Failed to get clock\n"); 422 return PTR_ERR(ddp->clk); 423 } 424 } 425 426 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); 427 ddp->regs = devm_ioremap_resource(dev, regs); 428 if (IS_ERR(ddp->regs)) { 429 dev_err(dev, "Failed to map mutex registers\n"); 430 return PTR_ERR(ddp->regs); 431 } 432 433 platform_set_drvdata(pdev, ddp); 434 435 return 0; 436} 437 438static int mtk_ddp_remove(struct platform_device *pdev) 439{ 440 return 0; 441} 442 443static const struct of_device_id ddp_driver_dt_match[] = { 444 { .compatible = "mediatek,mt2701-disp-mutex", 445 .data = &mt2701_ddp_driver_data}, 446 { .compatible = "mediatek,mt2712-disp-mutex", 447 .data = &mt2712_ddp_driver_data}, 448 { .compatible = "mediatek,mt8167-disp-mutex", 449 .data = &mt8167_ddp_driver_data}, 450 { .compatible = "mediatek,mt8173-disp-mutex", 451 .data = &mt8173_ddp_driver_data}, 452 {}, 453}; 454MODULE_DEVICE_TABLE(of, ddp_driver_dt_match); 455 456struct platform_driver mtk_ddp_driver = { 457 .probe = mtk_ddp_probe, 458 .remove = mtk_ddp_remove, 459 .driver = { 460 .name = "mediatek-ddp", 461 .owner = THIS_MODULE, 462 .of_match_table = ddp_driver_dt_match, 463 }, 464};