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

Merge tag 'mediatek-drm-next-5.5' of https://github.com/ckhu-mediatek/linux.git-tags into drm-next

Mediatek DRM next for Linux 5.5

This include mipi_tx, dsi, and partial crtc for MT8183 SoC.

Signed-off-by: Dave Airlie <airlied@redhat.com>

From: CK Hu <ck.hu@mediatek.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1571103548.4416.6.camel@mtksdaap41

+974 -436
+17 -13
Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
··· 27 27 28 28 Required properties (all function blocks): 29 29 - compatible: "mediatek,<chip>-disp-<function>", one of 30 - "mediatek,<chip>-disp-ovl" - overlay (4 layers, blending, csc) 31 - "mediatek,<chip>-disp-rdma" - read DMA / line buffer 32 - "mediatek,<chip>-disp-wdma" - write DMA 33 - "mediatek,<chip>-disp-color" - color processor 34 - "mediatek,<chip>-disp-aal" - adaptive ambient light controller 35 - "mediatek,<chip>-disp-gamma" - gamma correction 36 - "mediatek,<chip>-disp-merge" - merge streams from two RDMA sources 37 - "mediatek,<chip>-disp-split" - split stream to two encoders 38 - "mediatek,<chip>-disp-ufoe" - data compression engine 39 - "mediatek,<chip>-dsi" - DSI controller, see mediatek,dsi.txt 40 - "mediatek,<chip>-dpi" - DPI controller, see mediatek,dpi.txt 41 - "mediatek,<chip>-disp-mutex" - display mutex 42 - "mediatek,<chip>-disp-od" - overdrive 30 + "mediatek,<chip>-disp-ovl" - overlay (4 layers, blending, csc) 31 + "mediatek,<chip>-disp-ovl-2l" - overlay (2 layers, blending, csc) 32 + "mediatek,<chip>-disp-rdma" - read DMA / line buffer 33 + "mediatek,<chip>-disp-wdma" - write DMA 34 + "mediatek,<chip>-disp-ccorr" - color correction 35 + "mediatek,<chip>-disp-color" - color processor 36 + "mediatek,<chip>-disp-dither" - dither 37 + "mediatek,<chip>-disp-aal" - adaptive ambient light controller 38 + "mediatek,<chip>-disp-gamma" - gamma correction 39 + "mediatek,<chip>-disp-merge" - merge streams from two RDMA sources 40 + "mediatek,<chip>-disp-split" - split stream to two encoders 41 + "mediatek,<chip>-disp-ufoe" - data compression engine 42 + "mediatek,<chip>-dsi" - DSI controller, see mediatek,dsi.txt 43 + "mediatek,<chip>-dpi" - DPI controller, see mediatek,dpi.txt 44 + "mediatek,<chip>-disp-mutex" - display mutex 45 + "mediatek,<chip>-disp-od" - overdrive 43 46 the supported chips are mt2701, mt2712 and mt8173. 44 47 - reg: Physical base address and length of the function block register space 45 48 - interrupts: The interrupt signal from the function block (required, except for ··· 52 49 For most function blocks this is just a single clock input. Only the DSI and 53 50 DPI controller nodes have multiple clock inputs. These are documented in 54 51 mediatek,dsi.txt and mediatek,dpi.txt, respectively. 52 + An exception is that the mt8183 mutex is always free running with no clocks property. 55 53 56 54 Required properties (DMA function blocks): 57 55 - compatible: Should be one of
+2 -2
Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt
··· 7 7 8 8 Required properties: 9 9 - compatible: "mediatek,<chip>-dsi" 10 - the supported chips are mt2701 and mt8173. 10 + the supported chips are mt2701, mt8173 and mt8183. 11 11 - reg: Physical base address and length of the controller's registers 12 12 - interrupts: The interrupt signal from the function block. 13 13 - clocks: device clocks ··· 26 26 27 27 Required properties: 28 28 - compatible: "mediatek,<chip>-mipi-tx" 29 - the supported chips are mt2701 and mt8173. 29 + the supported chips are mt2701, mt8173 and mt8183. 30 30 - reg: Physical base address and length of the controller's registers 31 31 - clocks: PLL reference clock 32 32 - clock-output-names: name of the output clock line to the DSI encoder
+2
drivers/gpu/drm/mediatek/Makefile
··· 12 12 mtk_drm_plane.o \ 13 13 mtk_dsi.o \ 14 14 mtk_mipi_tx.o \ 15 + mtk_mt8173_mipi_tx.o \ 16 + mtk_mt8183_mipi_tx.o \ 15 17 mtk_dpi.o 16 18 17 19 obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o
+55 -6
drivers/gpu/drm/mediatek/mtk_disp_ovl.c
··· 19 19 #define DISP_REG_OVL_EN 0x000c 20 20 #define DISP_REG_OVL_RST 0x0014 21 21 #define DISP_REG_OVL_ROI_SIZE 0x0020 22 + #define DISP_REG_OVL_DATAPATH_CON 0x0024 23 + #define OVL_BGCLR_SEL_IN BIT(2) 22 24 #define DISP_REG_OVL_ROI_BGCLR 0x0028 23 25 #define DISP_REG_OVL_SRC_CON 0x002c 24 26 #define DISP_REG_OVL_CON(n) (0x0030 + 0x20 * (n)) ··· 33 31 #define DISP_REG_OVL_ADDR_MT8173 0x0f40 34 32 #define DISP_REG_OVL_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n)) 35 33 36 - #define OVL_RDMA_MEM_GMC 0x40402020 34 + #define GMC_THRESHOLD_BITS 16 35 + #define GMC_THRESHOLD_HIGH ((1 << GMC_THRESHOLD_BITS) / 4) 36 + #define GMC_THRESHOLD_LOW ((1 << GMC_THRESHOLD_BITS) / 8) 37 37 38 38 #define OVL_CON_BYTE_SWAP BIT(24) 39 39 #define OVL_CON_MTX_YUV_TO_RGB (6 << 16) ··· 53 49 54 50 struct mtk_disp_ovl_data { 55 51 unsigned int addr; 52 + unsigned int gmc_bits; 53 + unsigned int layer_nr; 56 54 bool fmt_rgb565_is_0; 57 55 }; 58 56 ··· 132 126 133 127 static unsigned int mtk_ovl_layer_nr(struct mtk_ddp_comp *comp) 134 128 { 135 - return 4; 129 + struct mtk_disp_ovl *ovl = comp_to_ovl(comp); 130 + 131 + return ovl->data->layer_nr; 136 132 } 137 133 138 134 static void mtk_ovl_layer_on(struct mtk_ddp_comp *comp, unsigned int idx) 139 135 { 140 136 unsigned int reg; 137 + unsigned int gmc_thrshd_l; 138 + unsigned int gmc_thrshd_h; 139 + unsigned int gmc_value; 140 + struct mtk_disp_ovl *ovl = comp_to_ovl(comp); 141 141 142 142 writel(0x1, comp->regs + DISP_REG_OVL_RDMA_CTRL(idx)); 143 - writel(OVL_RDMA_MEM_GMC, comp->regs + DISP_REG_OVL_RDMA_GMC(idx)); 143 + 144 + gmc_thrshd_l = GMC_THRESHOLD_LOW >> 145 + (GMC_THRESHOLD_BITS - ovl->data->gmc_bits); 146 + gmc_thrshd_h = GMC_THRESHOLD_HIGH >> 147 + (GMC_THRESHOLD_BITS - ovl->data->gmc_bits); 148 + if (ovl->data->gmc_bits == 10) 149 + gmc_value = gmc_thrshd_h | gmc_thrshd_h << 16; 150 + else 151 + gmc_value = gmc_thrshd_l | gmc_thrshd_l << 8 | 152 + gmc_thrshd_h << 16 | gmc_thrshd_h << 24; 153 + writel(gmc_value, comp->regs + DISP_REG_OVL_RDMA_GMC(idx)); 144 154 145 155 reg = readl(comp->regs + DISP_REG_OVL_SRC_CON); 146 156 reg = reg | BIT(idx); ··· 239 217 mtk_ovl_layer_on(comp, idx); 240 218 } 241 219 220 + static void mtk_ovl_bgclr_in_on(struct mtk_ddp_comp *comp) 221 + { 222 + unsigned int reg; 223 + 224 + reg = readl(comp->regs + DISP_REG_OVL_DATAPATH_CON); 225 + reg = reg | OVL_BGCLR_SEL_IN; 226 + writel(reg, comp->regs + DISP_REG_OVL_DATAPATH_CON); 227 + } 228 + 229 + static void mtk_ovl_bgclr_in_off(struct mtk_ddp_comp *comp) 230 + { 231 + unsigned int reg; 232 + 233 + reg = readl(comp->regs + DISP_REG_OVL_DATAPATH_CON); 234 + reg = reg & ~OVL_BGCLR_SEL_IN; 235 + writel(reg, comp->regs + DISP_REG_OVL_DATAPATH_CON); 236 + } 237 + 242 238 static const struct mtk_ddp_comp_funcs mtk_disp_ovl_funcs = { 243 239 .config = mtk_ovl_config, 244 240 .start = mtk_ovl_start, ··· 267 227 .layer_on = mtk_ovl_layer_on, 268 228 .layer_off = mtk_ovl_layer_off, 269 229 .layer_config = mtk_ovl_layer_config, 230 + .bgclr_in_on = mtk_ovl_bgclr_in_on, 231 + .bgclr_in_off = mtk_ovl_bgclr_in_off, 270 232 }; 271 233 272 234 static int mtk_disp_ovl_bind(struct device *dev, struct device *master, ··· 318 276 if (irq < 0) 319 277 return irq; 320 278 321 - comp_id = mtk_ddp_comp_get_id(dev->of_node, MTK_DISP_OVL); 279 + priv->data = of_device_get_match_data(dev); 280 + 281 + comp_id = mtk_ddp_comp_get_id(dev->of_node, 282 + priv->data->layer_nr == 4 ? 283 + MTK_DISP_OVL : 284 + MTK_DISP_OVL_2L); 322 285 if (comp_id < 0) { 323 286 dev_err(dev, "Failed to identify by alias: %d\n", comp_id); 324 287 return comp_id; ··· 335 288 dev_err(dev, "Failed to initialize component: %d\n", ret); 336 289 return ret; 337 290 } 338 - 339 - priv->data = of_device_get_match_data(dev); 340 291 341 292 platform_set_drvdata(pdev, priv); 342 293 ··· 361 316 362 317 static const struct mtk_disp_ovl_data mt2701_ovl_driver_data = { 363 318 .addr = DISP_REG_OVL_ADDR_MT2701, 319 + .gmc_bits = 8, 320 + .layer_nr = 4, 364 321 .fmt_rgb565_is_0 = false, 365 322 }; 366 323 367 324 static const struct mtk_disp_ovl_data mt8173_ovl_driver_data = { 368 325 .addr = DISP_REG_OVL_ADDR_MT8173, 326 + .gmc_bits = 8, 327 + .layer_nr = 4, 369 328 .fmt_rgb565_is_0 = true, 370 329 }; 371 330
+34 -3
drivers/gpu/drm/mediatek/mtk_drm_crtc.c
··· 272 272 for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) { 273 273 struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[i]; 274 274 275 + if (i == 1) 276 + mtk_ddp_comp_bgclr_in_on(comp); 277 + 275 278 mtk_ddp_comp_config(comp, width, height, vrefresh, bpc); 276 279 mtk_ddp_comp_start(comp); 277 280 } ··· 283 280 for (i = 0; i < mtk_crtc->layer_nr; i++) { 284 281 struct drm_plane *plane = &mtk_crtc->planes[i]; 285 282 struct mtk_plane_state *plane_state; 283 + struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0]; 284 + unsigned int comp_layer_nr = mtk_ddp_comp_layer_nr(comp); 285 + unsigned int local_layer; 286 286 287 287 plane_state = to_mtk_plane_state(plane->state); 288 - mtk_ddp_comp_layer_config(mtk_crtc->ddp_comp[0], i, 288 + 289 + if (i >= comp_layer_nr) { 290 + comp = mtk_crtc->ddp_comp[1]; 291 + local_layer = i - comp_layer_nr; 292 + } else 293 + local_layer = i; 294 + mtk_ddp_comp_layer_config(comp, local_layer, 289 295 plane_state); 290 296 } 291 297 ··· 313 301 int i; 314 302 315 303 DRM_DEBUG_DRIVER("%s\n", __func__); 316 - for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) 304 + for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) { 317 305 mtk_ddp_comp_stop(mtk_crtc->ddp_comp[i]); 306 + if (i == 1) 307 + mtk_ddp_comp_bgclr_in_off(mtk_crtc->ddp_comp[i]); 308 + } 309 + 318 310 for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) 319 311 mtk_disp_mutex_remove_comp(mtk_crtc->mutex, 320 312 mtk_crtc->ddp_comp[i]->id); ··· 343 327 struct mtk_crtc_state *state = to_mtk_crtc_state(mtk_crtc->base.state); 344 328 struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0]; 345 329 unsigned int i; 330 + unsigned int comp_layer_nr = mtk_ddp_comp_layer_nr(comp); 331 + unsigned int local_layer; 346 332 347 333 /* 348 334 * TODO: instead of updating the registers here, we should prepare ··· 367 349 plane_state = to_mtk_plane_state(plane->state); 368 350 369 351 if (plane_state->pending.config) { 370 - mtk_ddp_comp_layer_config(comp, i, plane_state); 352 + if (i >= comp_layer_nr) { 353 + comp = mtk_crtc->ddp_comp[1]; 354 + local_layer = i - comp_layer_nr; 355 + } else 356 + local_layer = i; 357 + 358 + mtk_ddp_comp_layer_config(comp, local_layer, 359 + plane_state); 371 360 plane_state->pending.config = false; 372 361 } 373 362 } ··· 607 582 } 608 583 609 584 mtk_crtc->layer_nr = mtk_ddp_comp_layer_nr(mtk_crtc->ddp_comp[0]); 585 + if (mtk_crtc->ddp_comp_nr > 1) { 586 + struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[1]; 587 + 588 + if (comp->funcs->bgclr_in_on) 589 + mtk_crtc->layer_nr += mtk_ddp_comp_layer_nr(comp); 590 + } 610 591 mtk_crtc->planes = devm_kcalloc(dev, mtk_crtc->layer_nr, 611 592 sizeof(struct drm_plane), 612 593 GFP_KERNEL);
+96 -32
drivers/gpu/drm/mediatek/mtk_drm_ddp.c
··· 33 33 #define DISP_REG_CONFIG_DSI_SEL 0x050 34 34 #define DISP_REG_CONFIG_DPI_SEL 0x064 35 35 36 - #define DISP_REG_MUTEX_EN(n) (0x20 + 0x20 * (n)) 37 - #define DISP_REG_MUTEX(n) (0x24 + 0x20 * (n)) 38 - #define DISP_REG_MUTEX_RST(n) (0x28 + 0x20 * (n)) 39 - #define DISP_REG_MUTEX_MOD(n) (0x2c + 0x20 * (n)) 40 - #define DISP_REG_MUTEX_SOF(n) (0x30 + 0x20 * (n)) 41 - #define DISP_REG_MUTEX_MOD2(n) (0x34 + 0x20 * (n)) 36 + #define MT2701_DISP_MUTEX0_MOD0 0x2c 37 + #define MT2701_DISP_MUTEX0_SOF0 0x30 38 + 39 + #define DISP_REG_MUTEX_EN(n) (0x20 + 0x20 * (n)) 40 + #define DISP_REG_MUTEX(n) (0x24 + 0x20 * (n)) 41 + #define DISP_REG_MUTEX_RST(n) (0x28 + 0x20 * (n)) 42 + #define DISP_REG_MUTEX_MOD(mutex_mod_reg, n) (mutex_mod_reg + 0x20 * (n)) 43 + #define DISP_REG_MUTEX_SOF(mutex_sof_reg, n) (mutex_sof_reg + 0x20 * (n)) 44 + #define DISP_REG_MUTEX_MOD2(n) (0x34 + 0x20 * (n)) 42 45 43 46 #define INT_MUTEX BIT(1) 44 47 ··· 142 139 bool claimed; 143 140 }; 144 141 142 + enum mtk_ddp_mutex_sof_id { 143 + DDP_MUTEX_SOF_SINGLE_MODE, 144 + DDP_MUTEX_SOF_DSI0, 145 + DDP_MUTEX_SOF_DSI1, 146 + DDP_MUTEX_SOF_DPI0, 147 + DDP_MUTEX_SOF_DPI1, 148 + DDP_MUTEX_SOF_DSI2, 149 + DDP_MUTEX_SOF_DSI3, 150 + }; 151 + 152 + struct mtk_ddp_data { 153 + const unsigned int *mutex_mod; 154 + const unsigned int *mutex_sof; 155 + const unsigned int mutex_mod_reg; 156 + const unsigned int mutex_sof_reg; 157 + const bool no_clk; 158 + }; 159 + 145 160 struct mtk_ddp { 146 161 struct device *dev; 147 162 struct clk *clk; 148 163 void __iomem *regs; 149 164 struct mtk_disp_mutex mutex[10]; 150 - const unsigned int *mutex_mod; 165 + const struct mtk_ddp_data *data; 151 166 }; 152 167 153 168 static const unsigned int mt2701_mutex_mod[DDP_COMPONENT_ID_MAX] = { ··· 213 192 [DDP_COMPONENT_UFOE] = MT8173_MUTEX_MOD_DISP_UFOE, 214 193 [DDP_COMPONENT_WDMA0] = MT8173_MUTEX_MOD_DISP_WDMA0, 215 194 [DDP_COMPONENT_WDMA1] = MT8173_MUTEX_MOD_DISP_WDMA1, 195 + }; 196 + 197 + static const unsigned int mt2712_mutex_sof[DDP_MUTEX_SOF_DSI3 + 1] = { 198 + [DDP_MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE, 199 + [DDP_MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0, 200 + [DDP_MUTEX_SOF_DSI1] = MUTEX_SOF_DSI1, 201 + [DDP_MUTEX_SOF_DPI0] = MUTEX_SOF_DPI0, 202 + [DDP_MUTEX_SOF_DPI1] = MUTEX_SOF_DPI1, 203 + [DDP_MUTEX_SOF_DSI2] = MUTEX_SOF_DSI2, 204 + [DDP_MUTEX_SOF_DSI3] = MUTEX_SOF_DSI3, 205 + }; 206 + 207 + static const struct mtk_ddp_data mt2701_ddp_driver_data = { 208 + .mutex_mod = mt2701_mutex_mod, 209 + .mutex_sof = mt2712_mutex_sof, 210 + .mutex_mod_reg = MT2701_DISP_MUTEX0_MOD0, 211 + .mutex_sof_reg = MT2701_DISP_MUTEX0_SOF0, 212 + }; 213 + 214 + static const struct mtk_ddp_data mt2712_ddp_driver_data = { 215 + .mutex_mod = mt2712_mutex_mod, 216 + .mutex_sof = mt2712_mutex_sof, 217 + .mutex_mod_reg = MT2701_DISP_MUTEX0_MOD0, 218 + .mutex_sof_reg = MT2701_DISP_MUTEX0_SOF0, 219 + }; 220 + 221 + static const struct mtk_ddp_data mt8173_ddp_driver_data = { 222 + .mutex_mod = mt8173_mutex_mod, 223 + .mutex_sof = mt2712_mutex_sof, 224 + .mutex_mod_reg = MT2701_DISP_MUTEX0_MOD0, 225 + .mutex_sof_reg = MT2701_DISP_MUTEX0_SOF0, 216 226 }; 217 227 218 228 static unsigned int mtk_ddp_mout_en(enum mtk_ddp_comp_id cur, ··· 484 432 struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp, 485 433 mutex[mutex->id]); 486 434 unsigned int reg; 435 + unsigned int sof_id; 487 436 unsigned int offset; 488 437 489 438 WARN_ON(&ddp->mutex[mutex->id] != mutex); 490 439 491 440 switch (id) { 492 441 case DDP_COMPONENT_DSI0: 493 - reg = MUTEX_SOF_DSI0; 442 + sof_id = DDP_MUTEX_SOF_DSI0; 494 443 break; 495 444 case DDP_COMPONENT_DSI1: 496 - reg = MUTEX_SOF_DSI0; 445 + sof_id = DDP_MUTEX_SOF_DSI0; 497 446 break; 498 447 case DDP_COMPONENT_DSI2: 499 - reg = MUTEX_SOF_DSI2; 448 + sof_id = DDP_MUTEX_SOF_DSI2; 500 449 break; 501 450 case DDP_COMPONENT_DSI3: 502 - reg = MUTEX_SOF_DSI3; 451 + sof_id = DDP_MUTEX_SOF_DSI3; 503 452 break; 504 453 case DDP_COMPONENT_DPI0: 505 - reg = MUTEX_SOF_DPI0; 454 + sof_id = DDP_MUTEX_SOF_DPI0; 506 455 break; 507 456 case DDP_COMPONENT_DPI1: 508 - reg = MUTEX_SOF_DPI1; 457 + sof_id = DDP_MUTEX_SOF_DPI1; 509 458 break; 510 459 default: 511 - if (ddp->mutex_mod[id] < 32) { 512 - offset = DISP_REG_MUTEX_MOD(mutex->id); 460 + if (ddp->data->mutex_mod[id] < 32) { 461 + offset = DISP_REG_MUTEX_MOD(ddp->data->mutex_mod_reg, 462 + mutex->id); 513 463 reg = readl_relaxed(ddp->regs + offset); 514 - reg |= 1 << ddp->mutex_mod[id]; 464 + reg |= 1 << ddp->data->mutex_mod[id]; 515 465 writel_relaxed(reg, ddp->regs + offset); 516 466 } else { 517 467 offset = DISP_REG_MUTEX_MOD2(mutex->id); 518 468 reg = readl_relaxed(ddp->regs + offset); 519 - reg |= 1 << (ddp->mutex_mod[id] - 32); 469 + reg |= 1 << (ddp->data->mutex_mod[id] - 32); 520 470 writel_relaxed(reg, ddp->regs + offset); 521 471 } 522 472 return; 523 473 } 524 474 525 - writel_relaxed(reg, ddp->regs + DISP_REG_MUTEX_SOF(mutex->id)); 475 + writel_relaxed(ddp->data->mutex_sof[sof_id], 476 + ddp->regs + 477 + DISP_REG_MUTEX_SOF(ddp->data->mutex_sof_reg, mutex->id)); 526 478 } 527 479 528 480 void mtk_disp_mutex_remove_comp(struct mtk_disp_mutex *mutex, ··· 547 491 case DDP_COMPONENT_DPI0: 548 492 case DDP_COMPONENT_DPI1: 549 493 writel_relaxed(MUTEX_SOF_SINGLE_MODE, 550 - ddp->regs + DISP_REG_MUTEX_SOF(mutex->id)); 494 + ddp->regs + 495 + DISP_REG_MUTEX_SOF(ddp->data->mutex_sof_reg, 496 + mutex->id)); 551 497 break; 552 498 default: 553 - if (ddp->mutex_mod[id] < 32) { 554 - offset = DISP_REG_MUTEX_MOD(mutex->id); 499 + if (ddp->data->mutex_mod[id] < 32) { 500 + offset = DISP_REG_MUTEX_MOD(ddp->data->mutex_mod_reg, 501 + mutex->id); 555 502 reg = readl_relaxed(ddp->regs + offset); 556 - reg &= ~(1 << ddp->mutex_mod[id]); 503 + reg &= ~(1 << ddp->data->mutex_mod[id]); 557 504 writel_relaxed(reg, ddp->regs + offset); 558 505 } else { 559 506 offset = DISP_REG_MUTEX_MOD2(mutex->id); 560 507 reg = readl_relaxed(ddp->regs + offset); 561 - reg &= ~(1 << (ddp->mutex_mod[id] - 32)); 508 + reg &= ~(1 << (ddp->data->mutex_mod[id] - 32)); 562 509 writel_relaxed(reg, ddp->regs + offset); 563 510 } 564 511 break; ··· 623 564 for (i = 0; i < 10; i++) 624 565 ddp->mutex[i].id = i; 625 566 626 - ddp->clk = devm_clk_get(dev, NULL); 627 - if (IS_ERR(ddp->clk)) { 628 - dev_err(dev, "Failed to get clock\n"); 629 - return PTR_ERR(ddp->clk); 567 + ddp->data = of_device_get_match_data(dev); 568 + 569 + if (!ddp->data->no_clk) { 570 + ddp->clk = devm_clk_get(dev, NULL); 571 + if (IS_ERR(ddp->clk)) { 572 + dev_err(dev, "Failed to get clock\n"); 573 + return PTR_ERR(ddp->clk); 574 + } 630 575 } 631 576 632 577 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); ··· 639 576 dev_err(dev, "Failed to map mutex registers\n"); 640 577 return PTR_ERR(ddp->regs); 641 578 } 642 - 643 - ddp->mutex_mod = of_device_get_match_data(dev); 644 579 645 580 platform_set_drvdata(pdev, ddp); 646 581 ··· 651 590 } 652 591 653 592 static const struct of_device_id ddp_driver_dt_match[] = { 654 - { .compatible = "mediatek,mt2701-disp-mutex", .data = mt2701_mutex_mod}, 655 - { .compatible = "mediatek,mt2712-disp-mutex", .data = mt2712_mutex_mod}, 656 - { .compatible = "mediatek,mt8173-disp-mutex", .data = mt8173_mutex_mod}, 593 + { .compatible = "mediatek,mt2701-disp-mutex", 594 + .data = &mt2701_ddp_driver_data}, 595 + { .compatible = "mediatek,mt2712-disp-mutex", 596 + .data = &mt2712_ddp_driver_data}, 597 + { .compatible = "mediatek,mt8173-disp-mutex", 598 + .data = &mt8173_ddp_driver_data}, 657 599 {}, 658 600 }; 659 601 MODULE_DEVICE_TABLE(of, ddp_driver_dt_match);
+67
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
··· 33 33 #define DISP_AAL_EN 0x0000 34 34 #define DISP_AAL_SIZE 0x0030 35 35 36 + #define DISP_CCORR_EN 0x0000 37 + #define CCORR_EN BIT(0) 38 + #define DISP_CCORR_CFG 0x0020 39 + #define CCORR_RELAY_MODE BIT(0) 40 + #define DISP_CCORR_SIZE 0x0030 41 + 42 + #define DISP_DITHER_EN 0x0000 43 + #define DITHER_EN BIT(0) 44 + #define DISP_DITHER_CFG 0x0020 45 + #define DITHER_RELAY_MODE BIT(0) 46 + #define DISP_DITHER_SIZE 0x0030 47 + 36 48 #define DISP_GAMMA_EN 0x0000 37 49 #define DISP_GAMMA_CFG 0x0020 38 50 #define DISP_GAMMA_SIZE 0x0030 ··· 135 123 writel_relaxed(0x0, comp->regs + DISP_AAL_EN); 136 124 } 137 125 126 + static void mtk_ccorr_config(struct mtk_ddp_comp *comp, unsigned int w, 127 + unsigned int h, unsigned int vrefresh, 128 + unsigned int bpc) 129 + { 130 + writel(h << 16 | w, comp->regs + DISP_CCORR_SIZE); 131 + writel(CCORR_RELAY_MODE, comp->regs + DISP_CCORR_CFG); 132 + } 133 + 134 + static void mtk_ccorr_start(struct mtk_ddp_comp *comp) 135 + { 136 + writel(CCORR_EN, comp->regs + DISP_CCORR_EN); 137 + } 138 + 139 + static void mtk_ccorr_stop(struct mtk_ddp_comp *comp) 140 + { 141 + writel_relaxed(0x0, comp->regs + DISP_CCORR_EN); 142 + } 143 + 144 + static void mtk_dither_config(struct mtk_ddp_comp *comp, unsigned int w, 145 + unsigned int h, unsigned int vrefresh, 146 + unsigned int bpc) 147 + { 148 + writel(h << 16 | w, comp->regs + DISP_DITHER_SIZE); 149 + writel(DITHER_RELAY_MODE, comp->regs + DISP_DITHER_CFG); 150 + } 151 + 152 + static void mtk_dither_start(struct mtk_ddp_comp *comp) 153 + { 154 + writel(DITHER_EN, comp->regs + DISP_DITHER_EN); 155 + } 156 + 157 + static void mtk_dither_stop(struct mtk_ddp_comp *comp) 158 + { 159 + writel_relaxed(0x0, comp->regs + DISP_DITHER_EN); 160 + } 161 + 138 162 static void mtk_gamma_config(struct mtk_ddp_comp *comp, unsigned int w, 139 163 unsigned int h, unsigned int vrefresh, 140 164 unsigned int bpc) ··· 219 171 .stop = mtk_aal_stop, 220 172 }; 221 173 174 + static const struct mtk_ddp_comp_funcs ddp_ccorr = { 175 + .config = mtk_ccorr_config, 176 + .start = mtk_ccorr_start, 177 + .stop = mtk_ccorr_stop, 178 + }; 179 + 180 + static const struct mtk_ddp_comp_funcs ddp_dither = { 181 + .config = mtk_dither_config, 182 + .start = mtk_dither_start, 183 + .stop = mtk_dither_stop, 184 + }; 185 + 222 186 static const struct mtk_ddp_comp_funcs ddp_gamma = { 223 187 .gamma_set = mtk_gamma_set, 224 188 .config = mtk_gamma_config, ··· 249 189 250 190 static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = { 251 191 [MTK_DISP_OVL] = "ovl", 192 + [MTK_DISP_OVL_2L] = "ovl_2l", 252 193 [MTK_DISP_RDMA] = "rdma", 253 194 [MTK_DISP_WDMA] = "wdma", 254 195 [MTK_DISP_COLOR] = "color", 196 + [MTK_DISP_CCORR] = "ccorr", 255 197 [MTK_DISP_AAL] = "aal", 256 198 [MTK_DISP_GAMMA] = "gamma", 199 + [MTK_DISP_DITHER] = "dither", 257 200 [MTK_DISP_UFOE] = "ufoe", 258 201 [MTK_DSI] = "dsi", 259 202 [MTK_DPI] = "dpi", ··· 276 213 [DDP_COMPONENT_AAL0] = { MTK_DISP_AAL, 0, &ddp_aal }, 277 214 [DDP_COMPONENT_AAL1] = { MTK_DISP_AAL, 1, &ddp_aal }, 278 215 [DDP_COMPONENT_BLS] = { MTK_DISP_BLS, 0, NULL }, 216 + [DDP_COMPONENT_CCORR] = { MTK_DISP_CCORR, 0, &ddp_ccorr }, 279 217 [DDP_COMPONENT_COLOR0] = { MTK_DISP_COLOR, 0, NULL }, 280 218 [DDP_COMPONENT_COLOR1] = { MTK_DISP_COLOR, 1, NULL }, 219 + [DDP_COMPONENT_DITHER] = { MTK_DISP_DITHER, 0, &ddp_dither }, 281 220 [DDP_COMPONENT_DPI0] = { MTK_DPI, 0, NULL }, 282 221 [DDP_COMPONENT_DPI1] = { MTK_DPI, 1, NULL }, 283 222 [DDP_COMPONENT_DSI0] = { MTK_DSI, 0, NULL }, ··· 291 226 [DDP_COMPONENT_OD1] = { MTK_DISP_OD, 1, &ddp_od }, 292 227 [DDP_COMPONENT_OVL0] = { MTK_DISP_OVL, 0, NULL }, 293 228 [DDP_COMPONENT_OVL1] = { MTK_DISP_OVL, 1, NULL }, 229 + [DDP_COMPONENT_OVL_2L0] = { MTK_DISP_OVL_2L, 0, NULL }, 230 + [DDP_COMPONENT_OVL_2L1] = { MTK_DISP_OVL_2L, 1, NULL }, 294 231 [DDP_COMPONENT_PWM0] = { MTK_DISP_PWM, 0, NULL }, 295 232 [DDP_COMPONENT_PWM1] = { MTK_DISP_PWM, 1, NULL }, 296 233 [DDP_COMPONENT_PWM2] = { MTK_DISP_PWM, 2, NULL },
+21
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
··· 17 17 18 18 enum mtk_ddp_comp_type { 19 19 MTK_DISP_OVL, 20 + MTK_DISP_OVL_2L, 20 21 MTK_DISP_RDMA, 21 22 MTK_DISP_WDMA, 22 23 MTK_DISP_COLOR, 24 + MTK_DISP_CCORR, 25 + MTK_DISP_DITHER, 23 26 MTK_DISP_AAL, 24 27 MTK_DISP_GAMMA, 25 28 MTK_DISP_UFOE, ··· 39 36 DDP_COMPONENT_AAL0, 40 37 DDP_COMPONENT_AAL1, 41 38 DDP_COMPONENT_BLS, 39 + DDP_COMPONENT_CCORR, 42 40 DDP_COMPONENT_COLOR0, 43 41 DDP_COMPONENT_COLOR1, 42 + DDP_COMPONENT_DITHER, 44 43 DDP_COMPONENT_DPI0, 45 44 DDP_COMPONENT_DPI1, 46 45 DDP_COMPONENT_DSI0, ··· 53 48 DDP_COMPONENT_OD0, 54 49 DDP_COMPONENT_OD1, 55 50 DDP_COMPONENT_OVL0, 51 + DDP_COMPONENT_OVL_2L0, 52 + DDP_COMPONENT_OVL_2L1, 56 53 DDP_COMPONENT_OVL1, 57 54 DDP_COMPONENT_PWM0, 58 55 DDP_COMPONENT_PWM1, ··· 84 77 struct mtk_plane_state *state); 85 78 void (*gamma_set)(struct mtk_ddp_comp *comp, 86 79 struct drm_crtc_state *state); 80 + void (*bgclr_in_on)(struct mtk_ddp_comp *comp); 81 + void (*bgclr_in_off)(struct mtk_ddp_comp *comp); 87 82 }; 88 83 89 84 struct mtk_ddp_comp { ··· 165 156 { 166 157 if (comp->funcs && comp->funcs->gamma_set) 167 158 comp->funcs->gamma_set(comp, state); 159 + } 160 + 161 + static inline void mtk_ddp_comp_bgclr_in_on(struct mtk_ddp_comp *comp) 162 + { 163 + if (comp->funcs && comp->funcs->bgclr_in_on) 164 + comp->funcs->bgclr_in_on(comp); 165 + } 166 + 167 + static inline void mtk_ddp_comp_bgclr_in_off(struct mtk_ddp_comp *comp) 168 + { 169 + if (comp->funcs && comp->funcs->bgclr_in_off) 170 + comp->funcs->bgclr_in_off(comp); 168 171 } 169 172 170 173 int mtk_ddp_comp_get_id(struct device_node *node,
+2 -1
drivers/gpu/drm/mediatek/mtk_drm_drv.c
··· 547 547 */ 548 548 if (comp_type == MTK_DISP_COLOR || 549 549 comp_type == MTK_DISP_OVL || 550 + comp_type == MTK_DISP_OVL_2L || 550 551 comp_type == MTK_DISP_RDMA || 551 552 comp_type == MTK_DSI || 552 553 comp_type == MTK_DPI) { ··· 670 669 &mtk_disp_rdma_driver, 671 670 &mtk_dpi_driver, 672 671 &mtk_drm_platform_driver, 673 - &mtk_dsi_driver, 674 672 &mtk_mipi_tx_driver, 673 + &mtk_dsi_driver, 675 674 }; 676 675 677 676 static int __init mtk_drm_init(void)
+169 -64
drivers/gpu/drm/mediatek/mtk_dsi.c
··· 40 40 #define DSI_CON_CTRL 0x10 41 41 #define DSI_RESET BIT(0) 42 42 #define DSI_EN BIT(1) 43 + #define DPHY_RESET BIT(2) 43 44 44 45 #define DSI_MODE_CTRL 0x14 45 46 #define MODE (3) ··· 74 73 #define DSI_VBP_NL 0x24 75 74 #define DSI_VFP_NL 0x28 76 75 #define DSI_VACT_NL 0x2C 76 + #define DSI_SIZE_CON 0x38 77 77 #define DSI_HSA_WC 0x50 78 78 #define DSI_HBP_WC 0x54 79 79 #define DSI_HFP_WC 0x58 ··· 128 126 #define VM_CMD_EN BIT(0) 129 127 #define TS_VFP_EN BIT(5) 130 128 131 - #define DSI_CMDQ0 0x180 129 + #define DSI_SHADOW_DEBUG 0x190U 130 + #define FORCE_COMMIT BIT(0) 131 + #define BYPASS_SHADOW BIT(1) 132 + 132 133 #define CONFIG (0xff << 0) 133 134 #define SHORT_PACKET 0 134 135 #define LONG_PACKET 2 ··· 139 134 #define DATA_ID (0xff << 8) 140 135 #define DATA_0 (0xff << 16) 141 136 #define DATA_1 (0xff << 24) 142 - 143 - #define T_LPX 5 144 - #define T_HS_PREP 6 145 - #define T_HS_TRAIL 8 146 - #define T_HS_EXIT 7 147 - #define T_HS_ZERO 10 148 137 149 138 #define NS_TO_CYCLE(n, c) ((n) / (c) + (((n) % (c)) ? 1 : 0)) 150 139 ··· 148 149 (type == MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM) || \ 149 150 (type == MIPI_DSI_DCS_READ)) 150 151 152 + struct mtk_phy_timing { 153 + u32 lpx; 154 + u32 da_hs_prepare; 155 + u32 da_hs_zero; 156 + u32 da_hs_trail; 157 + 158 + u32 ta_go; 159 + u32 ta_sure; 160 + u32 ta_get; 161 + u32 da_hs_exit; 162 + 163 + u32 clk_hs_zero; 164 + u32 clk_hs_trail; 165 + 166 + u32 clk_hs_prepare; 167 + u32 clk_hs_post; 168 + u32 clk_hs_exit; 169 + }; 170 + 151 171 struct phy; 172 + 173 + struct mtk_dsi_driver_data { 174 + const u32 reg_cmdq_off; 175 + bool has_shadow_ctl; 176 + bool has_size_ctl; 177 + }; 152 178 153 179 struct mtk_dsi { 154 180 struct mtk_ddp_comp ddp_comp; ··· 197 173 enum mipi_dsi_pixel_format format; 198 174 unsigned int lanes; 199 175 struct videomode vm; 176 + struct mtk_phy_timing phy_timing; 200 177 int refcount; 201 178 bool enabled; 202 179 u32 irq_data; 203 180 wait_queue_head_t irq_wait_queue; 181 + const struct mtk_dsi_driver_data *driver_data; 204 182 }; 205 183 206 184 static inline struct mtk_dsi *encoder_to_dsi(struct drm_encoder *e) ··· 231 205 { 232 206 u32 timcon0, timcon1, timcon2, timcon3; 233 207 u32 ui, cycle_time; 208 + struct mtk_phy_timing *timing = &dsi->phy_timing; 234 209 235 - ui = 1000 / dsi->data_rate + 0x01; 236 - cycle_time = 8000 / dsi->data_rate + 0x01; 210 + ui = DIV_ROUND_UP(1000000000, dsi->data_rate); 211 + cycle_time = div_u64(8000000000ULL, dsi->data_rate); 237 212 238 - timcon0 = T_LPX | T_HS_PREP << 8 | T_HS_ZERO << 16 | T_HS_TRAIL << 24; 239 - timcon1 = 4 * T_LPX | (3 * T_LPX / 2) << 8 | 5 * T_LPX << 16 | 240 - T_HS_EXIT << 24; 241 - timcon2 = ((NS_TO_CYCLE(0x64, cycle_time) + 0xa) << 24) | 242 - (NS_TO_CYCLE(0x150, cycle_time) << 16); 243 - timcon3 = NS_TO_CYCLE(0x40, cycle_time) | (2 * T_LPX) << 16 | 244 - NS_TO_CYCLE(80 + 52 * ui, cycle_time) << 8; 213 + timing->lpx = NS_TO_CYCLE(60, cycle_time); 214 + timing->da_hs_prepare = NS_TO_CYCLE(50 + 5 * ui, cycle_time); 215 + timing->da_hs_zero = NS_TO_CYCLE(110 + 6 * ui, cycle_time); 216 + timing->da_hs_trail = NS_TO_CYCLE(77 + 4 * ui, cycle_time); 217 + 218 + timing->ta_go = 4 * timing->lpx; 219 + timing->ta_sure = 3 * timing->lpx / 2; 220 + timing->ta_get = 5 * timing->lpx; 221 + timing->da_hs_exit = 2 * timing->lpx; 222 + 223 + timing->clk_hs_zero = NS_TO_CYCLE(336, cycle_time); 224 + timing->clk_hs_trail = NS_TO_CYCLE(100, cycle_time) + 10; 225 + 226 + timing->clk_hs_prepare = NS_TO_CYCLE(64, cycle_time); 227 + timing->clk_hs_post = NS_TO_CYCLE(80 + 52 * ui, cycle_time); 228 + timing->clk_hs_exit = 2 * timing->lpx; 229 + 230 + timcon0 = timing->lpx | timing->da_hs_prepare << 8 | 231 + timing->da_hs_zero << 16 | timing->da_hs_trail << 24; 232 + timcon1 = timing->ta_go | timing->ta_sure << 8 | 233 + timing->ta_get << 16 | timing->da_hs_exit << 24; 234 + timcon2 = 1 << 8 | timing->clk_hs_zero << 16 | 235 + timing->clk_hs_trail << 24; 236 + timcon3 = timing->clk_hs_prepare | timing->clk_hs_post << 8 | 237 + timing->clk_hs_exit << 16; 245 238 246 239 writel(timcon0, dsi->regs + DSI_PHY_TIMECON0); 247 240 writel(timcon1, dsi->regs + DSI_PHY_TIMECON1); ··· 282 237 { 283 238 mtk_dsi_mask(dsi, DSI_CON_CTRL, DSI_RESET, DSI_RESET); 284 239 mtk_dsi_mask(dsi, DSI_CON_CTRL, DSI_RESET, 0); 240 + } 241 + 242 + static void mtk_dsi_reset_dphy(struct mtk_dsi *dsi) 243 + { 244 + mtk_dsi_mask(dsi, DSI_CON_CTRL, DPHY_RESET, DPHY_RESET); 245 + mtk_dsi_mask(dsi, DSI_CON_CTRL, DPHY_RESET, 0); 285 246 } 286 247 287 248 static void mtk_dsi_clk_ulp_mode_enter(struct mtk_dsi *dsi) ··· 453 402 u32 horizontal_sync_active_byte; 454 403 u32 horizontal_backporch_byte; 455 404 u32 horizontal_frontporch_byte; 456 - u32 dsi_tmp_buf_bpp; 405 + u32 dsi_tmp_buf_bpp, data_phy_cycles; 406 + struct mtk_phy_timing *timing = &dsi->phy_timing; 457 407 458 408 struct videomode *vm = &dsi->vm; 459 409 ··· 468 416 writel(vm->vfront_porch, dsi->regs + DSI_VFP_NL); 469 417 writel(vm->vactive, dsi->regs + DSI_VACT_NL); 470 418 419 + if (dsi->driver_data->has_size_ctl) 420 + writel(vm->vactive << 16 | vm->hactive, 421 + dsi->regs + DSI_SIZE_CON); 422 + 471 423 horizontal_sync_active_byte = (vm->hsync_len * dsi_tmp_buf_bpp - 10); 472 424 473 425 if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) ··· 481 425 horizontal_backporch_byte = ((vm->hback_porch + vm->hsync_len) * 482 426 dsi_tmp_buf_bpp - 10); 483 427 484 - horizontal_frontporch_byte = (vm->hfront_porch * dsi_tmp_buf_bpp - 12); 428 + data_phy_cycles = timing->lpx + timing->da_hs_prepare + 429 + timing->da_hs_zero + timing->da_hs_exit + 2; 430 + 431 + if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST) { 432 + if (vm->hfront_porch * dsi_tmp_buf_bpp > 433 + data_phy_cycles * dsi->lanes + 18) { 434 + horizontal_frontporch_byte = vm->hfront_porch * 435 + dsi_tmp_buf_bpp - 436 + data_phy_cycles * 437 + dsi->lanes - 18; 438 + } else { 439 + DRM_WARN("HFP less than d-phy, FPS will under 60Hz\n"); 440 + horizontal_frontporch_byte = vm->hfront_porch * 441 + dsi_tmp_buf_bpp; 442 + } 443 + } else { 444 + if (vm->hfront_porch * dsi_tmp_buf_bpp > 445 + data_phy_cycles * dsi->lanes + 12) { 446 + horizontal_frontporch_byte = vm->hfront_porch * 447 + dsi_tmp_buf_bpp - 448 + data_phy_cycles * 449 + dsi->lanes - 12; 450 + } else { 451 + DRM_WARN("HFP less than d-phy, FPS will under 60Hz\n"); 452 + horizontal_frontporch_byte = vm->hfront_porch * 453 + dsi_tmp_buf_bpp; 454 + } 455 + } 485 456 486 457 writel(horizontal_sync_active_byte, dsi->regs + DSI_HSA_WC); 487 458 writel(horizontal_backporch_byte, dsi->regs + DSI_HBP_WC); ··· 606 523 607 524 static int mtk_dsi_poweron(struct mtk_dsi *dsi) 608 525 { 609 - struct device *dev = dsi->dev; 526 + struct device *dev = dsi->host.dev; 610 527 int ret; 611 - u64 pixel_clock, total_bits; 612 - u32 htotal, htotal_bits, bit_per_pixel, overhead_cycles, overhead_bits; 528 + u32 bit_per_pixel; 613 529 614 530 if (++dsi->refcount != 1) 615 531 return 0; ··· 627 545 break; 628 546 } 629 547 630 - /** 631 - * htotal_time = htotal * byte_per_pixel / num_lanes 632 - * overhead_time = lpx + hs_prepare + hs_zero + hs_trail + hs_exit 633 - * mipi_ratio = (htotal_time + overhead_time) / htotal_time 634 - * data_rate = pixel_clock * bit_per_pixel * mipi_ratio / num_lanes; 635 - */ 636 - pixel_clock = dsi->vm.pixelclock; 637 - htotal = dsi->vm.hactive + dsi->vm.hback_porch + dsi->vm.hfront_porch + 638 - dsi->vm.hsync_len; 639 - htotal_bits = htotal * bit_per_pixel; 640 - 641 - overhead_cycles = T_LPX + T_HS_PREP + T_HS_ZERO + T_HS_TRAIL + 642 - T_HS_EXIT; 643 - overhead_bits = overhead_cycles * dsi->lanes * 8; 644 - total_bits = htotal_bits + overhead_bits; 645 - 646 - dsi->data_rate = DIV_ROUND_UP_ULL(pixel_clock * total_bits, 647 - htotal * dsi->lanes); 548 + dsi->data_rate = DIV_ROUND_UP_ULL(dsi->vm.pixelclock * bit_per_pixel, 549 + dsi->lanes); 648 550 649 551 ret = clk_set_rate(dsi->hs_clk, dsi->data_rate); 650 552 if (ret < 0) { ··· 651 585 } 652 586 653 587 mtk_dsi_enable(dsi); 588 + 589 + if (dsi->driver_data->has_shadow_ctl) 590 + writel(FORCE_COMMIT | BYPASS_SHADOW, 591 + dsi->regs + DSI_SHADOW_DEBUG); 592 + 654 593 mtk_dsi_reset_engine(dsi); 655 594 mtk_dsi_phy_timconfig(dsi); 656 595 657 596 mtk_dsi_rxtx_control(dsi); 597 + usleep_range(30, 100); 598 + mtk_dsi_reset_dphy(dsi); 658 599 mtk_dsi_ps_control_vact(dsi); 659 600 mtk_dsi_set_vm_cmd(dsi); 660 601 mtk_dsi_config_vdo_timing(dsi); ··· 1012 939 const char *tx_buf = msg->tx_buf; 1013 940 u8 config, cmdq_size, cmdq_off, type = msg->type; 1014 941 u32 reg_val, cmdq_mask, i; 942 + u32 reg_cmdq_off = dsi->driver_data->reg_cmdq_off; 1015 943 1016 944 if (MTK_DSI_HOST_IS_READ(type)) 1017 945 config = BTA; ··· 1032 958 } 1033 959 1034 960 for (i = 0; i < msg->tx_len; i++) 1035 - writeb(tx_buf[i], dsi->regs + DSI_CMDQ0 + cmdq_off + i); 961 + mtk_dsi_mask(dsi, (reg_cmdq_off + cmdq_off + i) & (~0x3U), 962 + (0xffUL << (((i + cmdq_off) & 3U) * 8U)), 963 + tx_buf[i] << (((i + cmdq_off) & 3U) * 8U)); 1036 964 1037 - mtk_dsi_mask(dsi, DSI_CMDQ0, cmdq_mask, reg_val); 965 + mtk_dsi_mask(dsi, reg_cmdq_off, cmdq_mask, reg_val); 1038 966 mtk_dsi_mask(dsi, DSI_CMDQ_SIZE, CMDQ_SIZE, cmdq_size); 1039 967 } 1040 968 ··· 1126 1050 return ret; 1127 1051 } 1128 1052 1129 - ret = mipi_dsi_host_register(&dsi->host); 1130 - if (ret < 0) { 1131 - dev_err(dev, "failed to register DSI host: %d\n", ret); 1132 - goto err_ddp_comp_unregister; 1133 - } 1134 - 1135 1053 ret = mtk_dsi_create_conn_enc(drm, dsi); 1136 1054 if (ret) { 1137 1055 DRM_ERROR("Encoder create failed with %d\n", ret); ··· 1135 1065 return 0; 1136 1066 1137 1067 err_unregister: 1138 - mipi_dsi_host_unregister(&dsi->host); 1139 - err_ddp_comp_unregister: 1140 1068 mtk_ddp_comp_unregister(drm, &dsi->ddp_comp); 1141 1069 return ret; 1142 1070 } ··· 1146 1078 struct mtk_dsi *dsi = dev_get_drvdata(dev); 1147 1079 1148 1080 mtk_dsi_destroy_conn_enc(dsi); 1149 - mipi_dsi_host_unregister(&dsi->host); 1150 1081 mtk_ddp_comp_unregister(drm, &dsi->ddp_comp); 1151 1082 } 1152 1083 ··· 1169 1102 1170 1103 dsi->host.ops = &mtk_dsi_ops; 1171 1104 dsi->host.dev = dev; 1105 + ret = mipi_dsi_host_register(&dsi->host); 1106 + if (ret < 0) { 1107 + dev_err(dev, "failed to register DSI host: %d\n", ret); 1108 + return ret; 1109 + } 1172 1110 1173 1111 ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0, 1174 1112 &dsi->panel, &dsi->bridge); 1175 1113 if (ret) 1176 - return ret; 1114 + goto err_unregister_host; 1115 + 1116 + dsi->driver_data = of_device_get_match_data(dev); 1177 1117 1178 1118 dsi->engine_clk = devm_clk_get(dev, "engine"); 1179 1119 if (IS_ERR(dsi->engine_clk)) { 1180 1120 ret = PTR_ERR(dsi->engine_clk); 1181 1121 dev_err(dev, "Failed to get engine clock: %d\n", ret); 1182 - return ret; 1122 + goto err_unregister_host; 1183 1123 } 1184 1124 1185 1125 dsi->digital_clk = devm_clk_get(dev, "digital"); 1186 1126 if (IS_ERR(dsi->digital_clk)) { 1187 1127 ret = PTR_ERR(dsi->digital_clk); 1188 1128 dev_err(dev, "Failed to get digital clock: %d\n", ret); 1189 - return ret; 1129 + goto err_unregister_host; 1190 1130 } 1191 1131 1192 1132 dsi->hs_clk = devm_clk_get(dev, "hs"); 1193 1133 if (IS_ERR(dsi->hs_clk)) { 1194 1134 ret = PTR_ERR(dsi->hs_clk); 1195 1135 dev_err(dev, "Failed to get hs clock: %d\n", ret); 1196 - return ret; 1136 + goto err_unregister_host; 1197 1137 } 1198 1138 1199 1139 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); ··· 1208 1134 if (IS_ERR(dsi->regs)) { 1209 1135 ret = PTR_ERR(dsi->regs); 1210 1136 dev_err(dev, "Failed to ioremap memory: %d\n", ret); 1211 - return ret; 1137 + goto err_unregister_host; 1212 1138 } 1213 1139 1214 1140 dsi->phy = devm_phy_get(dev, "dphy"); 1215 1141 if (IS_ERR(dsi->phy)) { 1216 1142 ret = PTR_ERR(dsi->phy); 1217 1143 dev_err(dev, "Failed to get MIPI-DPHY: %d\n", ret); 1218 - return ret; 1144 + goto err_unregister_host; 1219 1145 } 1220 1146 1221 1147 comp_id = mtk_ddp_comp_get_id(dev->of_node, MTK_DSI); 1222 1148 if (comp_id < 0) { 1223 1149 dev_err(dev, "Failed to identify by alias: %d\n", comp_id); 1224 - return comp_id; 1150 + ret = comp_id; 1151 + goto err_unregister_host; 1225 1152 } 1226 1153 1227 1154 ret = mtk_ddp_comp_init(dev, dev->of_node, &dsi->ddp_comp, comp_id, 1228 1155 &mtk_dsi_funcs); 1229 1156 if (ret) { 1230 1157 dev_err(dev, "Failed to initialize component: %d\n", ret); 1231 - return ret; 1158 + goto err_unregister_host; 1232 1159 } 1233 1160 1234 1161 irq_num = platform_get_irq(pdev, 0); 1235 1162 if (irq_num < 0) { 1236 - dev_err(&pdev->dev, "failed to request dsi irq resource\n"); 1237 - return -EPROBE_DEFER; 1163 + dev_err(&pdev->dev, "failed to get dsi irq_num: %d\n", irq_num); 1164 + ret = irq_num; 1165 + goto err_unregister_host; 1238 1166 } 1239 1167 1240 1168 irq_set_status_flags(irq_num, IRQ_TYPE_LEVEL_LOW); ··· 1244 1168 IRQF_TRIGGER_LOW, dev_name(&pdev->dev), dsi); 1245 1169 if (ret) { 1246 1170 dev_err(&pdev->dev, "failed to request mediatek dsi irq\n"); 1247 - return -EPROBE_DEFER; 1171 + goto err_unregister_host; 1248 1172 } 1249 1173 1250 1174 init_waitqueue_head(&dsi->irq_wait_queue); 1251 1175 1252 1176 platform_set_drvdata(pdev, dsi); 1253 1177 1254 - return component_add(&pdev->dev, &mtk_dsi_component_ops); 1178 + ret = component_add(&pdev->dev, &mtk_dsi_component_ops); 1179 + if (ret) { 1180 + dev_err(&pdev->dev, "failed to add component: %d\n", ret); 1181 + goto err_unregister_host; 1182 + } 1183 + 1184 + return 0; 1185 + 1186 + err_unregister_host: 1187 + mipi_dsi_host_unregister(&dsi->host); 1188 + return ret; 1255 1189 } 1256 1190 1257 1191 static int mtk_dsi_remove(struct platform_device *pdev) ··· 1270 1184 1271 1185 mtk_output_dsi_disable(dsi); 1272 1186 component_del(&pdev->dev, &mtk_dsi_component_ops); 1187 + mipi_dsi_host_unregister(&dsi->host); 1273 1188 1274 1189 return 0; 1275 1190 } 1276 1191 1192 + static const struct mtk_dsi_driver_data mt8173_dsi_driver_data = { 1193 + .reg_cmdq_off = 0x200, 1194 + }; 1195 + 1196 + static const struct mtk_dsi_driver_data mt2701_dsi_driver_data = { 1197 + .reg_cmdq_off = 0x180, 1198 + }; 1199 + 1200 + static const struct mtk_dsi_driver_data mt8183_dsi_driver_data = { 1201 + .reg_cmdq_off = 0x200, 1202 + .has_shadow_ctl = true, 1203 + .has_size_ctl = true, 1204 + }; 1205 + 1277 1206 static const struct of_device_id mtk_dsi_of_match[] = { 1278 - { .compatible = "mediatek,mt2701-dsi" }, 1279 - { .compatible = "mediatek,mt8173-dsi" }, 1207 + { .compatible = "mediatek,mt2701-dsi", 1208 + .data = &mt2701_dsi_driver_data }, 1209 + { .compatible = "mediatek,mt8173-dsi", 1210 + .data = &mt8173_dsi_driver_data }, 1211 + { .compatible = "mediatek,mt8183-dsi", 1212 + .data = &mt8183_dsi_driver_data }, 1280 1213 { }, 1281 1214 }; 1282 1215
+23 -315
drivers/gpu/drm/mediatek/mtk_mipi_tx.c
··· 3 3 * Copyright (c) 2015 MediaTek Inc. 4 4 */ 5 5 6 - #include <linux/clk.h> 7 - #include <linux/clk-provider.h> 8 - #include <linux/delay.h> 9 - #include <linux/io.h> 10 - #include <linux/module.h> 11 - #include <linux/of_device.h> 12 - #include <linux/platform_device.h> 13 - #include <linux/phy/phy.h> 6 + #include "mtk_mipi_tx.h" 14 7 15 - #define MIPITX_DSI_CON 0x00 16 - #define RG_DSI_LDOCORE_EN BIT(0) 17 - #define RG_DSI_CKG_LDOOUT_EN BIT(1) 18 - #define RG_DSI_BCLK_SEL (3 << 2) 19 - #define RG_DSI_LD_IDX_SEL (7 << 4) 20 - #define RG_DSI_PHYCLK_SEL (2 << 8) 21 - #define RG_DSI_DSICLK_FREQ_SEL BIT(10) 22 - #define RG_DSI_LPTX_CLMP_EN BIT(11) 23 - 24 - #define MIPITX_DSI_CLOCK_LANE 0x04 25 - #define MIPITX_DSI_DATA_LANE0 0x08 26 - #define MIPITX_DSI_DATA_LANE1 0x0c 27 - #define MIPITX_DSI_DATA_LANE2 0x10 28 - #define MIPITX_DSI_DATA_LANE3 0x14 29 - #define RG_DSI_LNTx_LDOOUT_EN BIT(0) 30 - #define RG_DSI_LNTx_CKLANE_EN BIT(1) 31 - #define RG_DSI_LNTx_LPTX_IPLUS1 BIT(2) 32 - #define RG_DSI_LNTx_LPTX_IPLUS2 BIT(3) 33 - #define RG_DSI_LNTx_LPTX_IMINUS BIT(4) 34 - #define RG_DSI_LNTx_LPCD_IPLUS BIT(5) 35 - #define RG_DSI_LNTx_LPCD_IMINUS BIT(6) 36 - #define RG_DSI_LNTx_RT_CODE (0xf << 8) 37 - 38 - #define MIPITX_DSI_TOP_CON 0x40 39 - #define RG_DSI_LNT_INTR_EN BIT(0) 40 - #define RG_DSI_LNT_HS_BIAS_EN BIT(1) 41 - #define RG_DSI_LNT_IMP_CAL_EN BIT(2) 42 - #define RG_DSI_LNT_TESTMODE_EN BIT(3) 43 - #define RG_DSI_LNT_IMP_CAL_CODE (0xf << 4) 44 - #define RG_DSI_LNT_AIO_SEL (7 << 8) 45 - #define RG_DSI_PAD_TIE_LOW_EN BIT(11) 46 - #define RG_DSI_DEBUG_INPUT_EN BIT(12) 47 - #define RG_DSI_PRESERVE (7 << 13) 48 - 49 - #define MIPITX_DSI_BG_CON 0x44 50 - #define RG_DSI_BG_CORE_EN BIT(0) 51 - #define RG_DSI_BG_CKEN BIT(1) 52 - #define RG_DSI_BG_DIV (0x3 << 2) 53 - #define RG_DSI_BG_FAST_CHARGE BIT(4) 54 - #define RG_DSI_VOUT_MSK (0x3ffff << 5) 55 - #define RG_DSI_V12_SEL (7 << 5) 56 - #define RG_DSI_V10_SEL (7 << 8) 57 - #define RG_DSI_V072_SEL (7 << 11) 58 - #define RG_DSI_V04_SEL (7 << 14) 59 - #define RG_DSI_V032_SEL (7 << 17) 60 - #define RG_DSI_V02_SEL (7 << 20) 61 - #define RG_DSI_BG_R1_TRIM (0xf << 24) 62 - #define RG_DSI_BG_R2_TRIM (0xf << 28) 63 - 64 - #define MIPITX_DSI_PLL_CON0 0x50 65 - #define RG_DSI_MPPLL_PLL_EN BIT(0) 66 - #define RG_DSI_MPPLL_DIV_MSK (0x1ff << 1) 67 - #define RG_DSI_MPPLL_PREDIV (3 << 1) 68 - #define RG_DSI_MPPLL_TXDIV0 (3 << 3) 69 - #define RG_DSI_MPPLL_TXDIV1 (3 << 5) 70 - #define RG_DSI_MPPLL_POSDIV (7 << 7) 71 - #define RG_DSI_MPPLL_MONVC_EN BIT(10) 72 - #define RG_DSI_MPPLL_MONREF_EN BIT(11) 73 - #define RG_DSI_MPPLL_VOD_EN BIT(12) 74 - 75 - #define MIPITX_DSI_PLL_CON1 0x54 76 - #define RG_DSI_MPPLL_SDM_FRA_EN BIT(0) 77 - #define RG_DSI_MPPLL_SDM_SSC_PH_INIT BIT(1) 78 - #define RG_DSI_MPPLL_SDM_SSC_EN BIT(2) 79 - #define RG_DSI_MPPLL_SDM_SSC_PRD (0xffff << 16) 80 - 81 - #define MIPITX_DSI_PLL_CON2 0x58 82 - 83 - #define MIPITX_DSI_PLL_TOP 0x64 84 - #define RG_DSI_MPPLL_PRESERVE (0xff << 8) 85 - 86 - #define MIPITX_DSI_PLL_PWR 0x68 87 - #define RG_DSI_MPPLL_SDM_PWR_ON BIT(0) 88 - #define RG_DSI_MPPLL_SDM_ISO_EN BIT(1) 89 - #define RG_DSI_MPPLL_SDM_PWR_ACK BIT(8) 90 - 91 - #define MIPITX_DSI_SW_CTRL 0x80 92 - #define SW_CTRL_EN BIT(0) 93 - 94 - #define MIPITX_DSI_SW_CTRL_CON0 0x84 95 - #define SW_LNTC_LPTX_PRE_OE BIT(0) 96 - #define SW_LNTC_LPTX_OE BIT(1) 97 - #define SW_LNTC_LPTX_P BIT(2) 98 - #define SW_LNTC_LPTX_N BIT(3) 99 - #define SW_LNTC_HSTX_PRE_OE BIT(4) 100 - #define SW_LNTC_HSTX_OE BIT(5) 101 - #define SW_LNTC_HSTX_ZEROCLK BIT(6) 102 - #define SW_LNT0_LPTX_PRE_OE BIT(7) 103 - #define SW_LNT0_LPTX_OE BIT(8) 104 - #define SW_LNT0_LPTX_P BIT(9) 105 - #define SW_LNT0_LPTX_N BIT(10) 106 - #define SW_LNT0_HSTX_PRE_OE BIT(11) 107 - #define SW_LNT0_HSTX_OE BIT(12) 108 - #define SW_LNT0_LPRX_EN BIT(13) 109 - #define SW_LNT1_LPTX_PRE_OE BIT(14) 110 - #define SW_LNT1_LPTX_OE BIT(15) 111 - #define SW_LNT1_LPTX_P BIT(16) 112 - #define SW_LNT1_LPTX_N BIT(17) 113 - #define SW_LNT1_HSTX_PRE_OE BIT(18) 114 - #define SW_LNT1_HSTX_OE BIT(19) 115 - #define SW_LNT2_LPTX_PRE_OE BIT(20) 116 - #define SW_LNT2_LPTX_OE BIT(21) 117 - #define SW_LNT2_LPTX_P BIT(22) 118 - #define SW_LNT2_LPTX_N BIT(23) 119 - #define SW_LNT2_HSTX_PRE_OE BIT(24) 120 - #define SW_LNT2_HSTX_OE BIT(25) 121 - 122 - struct mtk_mipitx_data { 123 - const u32 mppll_preserve; 124 - }; 125 - 126 - struct mtk_mipi_tx { 127 - struct device *dev; 128 - void __iomem *regs; 129 - u32 data_rate; 130 - const struct mtk_mipitx_data *driver_data; 131 - struct clk_hw pll_hw; 132 - struct clk *pll; 133 - }; 134 - 135 - static inline struct mtk_mipi_tx *mtk_mipi_tx_from_clk_hw(struct clk_hw *hw) 8 + inline struct mtk_mipi_tx *mtk_mipi_tx_from_clk_hw(struct clk_hw *hw) 136 9 { 137 10 return container_of(hw, struct mtk_mipi_tx, pll_hw); 138 11 } 139 12 140 - static void mtk_mipi_tx_clear_bits(struct mtk_mipi_tx *mipi_tx, u32 offset, 141 - u32 bits) 13 + void mtk_mipi_tx_clear_bits(struct mtk_mipi_tx *mipi_tx, u32 offset, 14 + u32 bits) 142 15 { 143 16 u32 temp = readl(mipi_tx->regs + offset); 144 17 145 18 writel(temp & ~bits, mipi_tx->regs + offset); 146 19 } 147 20 148 - static void mtk_mipi_tx_set_bits(struct mtk_mipi_tx *mipi_tx, u32 offset, 149 - u32 bits) 21 + void mtk_mipi_tx_set_bits(struct mtk_mipi_tx *mipi_tx, u32 offset, 22 + u32 bits) 150 23 { 151 24 u32 temp = readl(mipi_tx->regs + offset); 152 25 153 26 writel(temp | bits, mipi_tx->regs + offset); 154 27 } 155 28 156 - static void mtk_mipi_tx_update_bits(struct mtk_mipi_tx *mipi_tx, u32 offset, 157 - u32 mask, u32 data) 29 + void mtk_mipi_tx_update_bits(struct mtk_mipi_tx *mipi_tx, u32 offset, 30 + u32 mask, u32 data) 158 31 { 159 32 u32 temp = readl(mipi_tx->regs + offset); 160 33 161 34 writel((temp & ~mask) | (data & mask), mipi_tx->regs + offset); 162 35 } 163 36 164 - static int mtk_mipi_tx_pll_prepare(struct clk_hw *hw) 165 - { 166 - struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw); 167 - u8 txdiv, txdiv0, txdiv1; 168 - u64 pcw; 169 - 170 - dev_dbg(mipi_tx->dev, "prepare: %u Hz\n", mipi_tx->data_rate); 171 - 172 - if (mipi_tx->data_rate >= 500000000) { 173 - txdiv = 1; 174 - txdiv0 = 0; 175 - txdiv1 = 0; 176 - } else if (mipi_tx->data_rate >= 250000000) { 177 - txdiv = 2; 178 - txdiv0 = 1; 179 - txdiv1 = 0; 180 - } else if (mipi_tx->data_rate >= 125000000) { 181 - txdiv = 4; 182 - txdiv0 = 2; 183 - txdiv1 = 0; 184 - } else if (mipi_tx->data_rate > 62000000) { 185 - txdiv = 8; 186 - txdiv0 = 2; 187 - txdiv1 = 1; 188 - } else if (mipi_tx->data_rate >= 50000000) { 189 - txdiv = 16; 190 - txdiv0 = 2; 191 - txdiv1 = 2; 192 - } else { 193 - return -EINVAL; 194 - } 195 - 196 - mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_BG_CON, 197 - RG_DSI_VOUT_MSK | 198 - RG_DSI_BG_CKEN | RG_DSI_BG_CORE_EN, 199 - (4 << 20) | (4 << 17) | (4 << 14) | 200 - (4 << 11) | (4 << 8) | (4 << 5) | 201 - RG_DSI_BG_CKEN | RG_DSI_BG_CORE_EN); 202 - 203 - usleep_range(30, 100); 204 - 205 - mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_TOP_CON, 206 - RG_DSI_LNT_IMP_CAL_CODE | RG_DSI_LNT_HS_BIAS_EN, 207 - (8 << 4) | RG_DSI_LNT_HS_BIAS_EN); 208 - 209 - mtk_mipi_tx_set_bits(mipi_tx, MIPITX_DSI_CON, 210 - RG_DSI_CKG_LDOOUT_EN | RG_DSI_LDOCORE_EN); 211 - 212 - mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_PWR, 213 - RG_DSI_MPPLL_SDM_PWR_ON | 214 - RG_DSI_MPPLL_SDM_ISO_EN, 215 - RG_DSI_MPPLL_SDM_PWR_ON); 216 - 217 - mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_PLL_CON0, 218 - RG_DSI_MPPLL_PLL_EN); 219 - 220 - mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_CON0, 221 - RG_DSI_MPPLL_TXDIV0 | RG_DSI_MPPLL_TXDIV1 | 222 - RG_DSI_MPPLL_PREDIV, 223 - (txdiv0 << 3) | (txdiv1 << 5)); 224 - 225 - /* 226 - * PLL PCW config 227 - * PCW bit 24~30 = integer part of pcw 228 - * PCW bit 0~23 = fractional part of pcw 229 - * pcw = data_Rate*4*txdiv/(Ref_clk*2); 230 - * Post DIV =4, so need data_Rate*4 231 - * Ref_clk is 26MHz 232 - */ 233 - pcw = div_u64(((u64)mipi_tx->data_rate * 2 * txdiv) << 24, 234 - 26000000); 235 - writel(pcw, mipi_tx->regs + MIPITX_DSI_PLL_CON2); 236 - 237 - mtk_mipi_tx_set_bits(mipi_tx, MIPITX_DSI_PLL_CON1, 238 - RG_DSI_MPPLL_SDM_FRA_EN); 239 - 240 - mtk_mipi_tx_set_bits(mipi_tx, MIPITX_DSI_PLL_CON0, RG_DSI_MPPLL_PLL_EN); 241 - 242 - usleep_range(20, 100); 243 - 244 - mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_PLL_CON1, 245 - RG_DSI_MPPLL_SDM_SSC_EN); 246 - 247 - mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_TOP, 248 - RG_DSI_MPPLL_PRESERVE, 249 - mipi_tx->driver_data->mppll_preserve); 250 - 251 - return 0; 252 - } 253 - 254 - static void mtk_mipi_tx_pll_unprepare(struct clk_hw *hw) 255 - { 256 - struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw); 257 - 258 - dev_dbg(mipi_tx->dev, "unprepare\n"); 259 - 260 - mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_PLL_CON0, 261 - RG_DSI_MPPLL_PLL_EN); 262 - 263 - mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_TOP, 264 - RG_DSI_MPPLL_PRESERVE, 0); 265 - 266 - mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_PWR, 267 - RG_DSI_MPPLL_SDM_ISO_EN | 268 - RG_DSI_MPPLL_SDM_PWR_ON, 269 - RG_DSI_MPPLL_SDM_ISO_EN); 270 - 271 - mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_TOP_CON, 272 - RG_DSI_LNT_HS_BIAS_EN); 273 - 274 - mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_CON, 275 - RG_DSI_CKG_LDOOUT_EN | RG_DSI_LDOCORE_EN); 276 - 277 - mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_BG_CON, 278 - RG_DSI_BG_CKEN | RG_DSI_BG_CORE_EN); 279 - 280 - mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_PLL_CON0, 281 - RG_DSI_MPPLL_DIV_MSK); 282 - } 283 - 284 - static long mtk_mipi_tx_pll_round_rate(struct clk_hw *hw, unsigned long rate, 285 - unsigned long *prate) 286 - { 287 - return clamp_val(rate, 50000000, 1250000000); 288 - } 289 - 290 - static int mtk_mipi_tx_pll_set_rate(struct clk_hw *hw, unsigned long rate, 291 - unsigned long parent_rate) 37 + int mtk_mipi_tx_pll_set_rate(struct clk_hw *hw, unsigned long rate, 38 + unsigned long parent_rate) 292 39 { 293 40 struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw); 294 41 ··· 46 299 return 0; 47 300 } 48 301 49 - static unsigned long mtk_mipi_tx_pll_recalc_rate(struct clk_hw *hw, 50 - unsigned long parent_rate) 302 + unsigned long mtk_mipi_tx_pll_recalc_rate(struct clk_hw *hw, 303 + unsigned long parent_rate) 51 304 { 52 305 struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw); 53 306 54 307 return mipi_tx->data_rate; 55 - } 56 - 57 - static const struct clk_ops mtk_mipi_tx_pll_ops = { 58 - .prepare = mtk_mipi_tx_pll_prepare, 59 - .unprepare = mtk_mipi_tx_pll_unprepare, 60 - .round_rate = mtk_mipi_tx_pll_round_rate, 61 - .set_rate = mtk_mipi_tx_pll_set_rate, 62 - .recalc_rate = mtk_mipi_tx_pll_recalc_rate, 63 - }; 64 - 65 - static int mtk_mipi_tx_power_on_signal(struct phy *phy) 66 - { 67 - struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy); 68 - u32 reg; 69 - 70 - for (reg = MIPITX_DSI_CLOCK_LANE; 71 - reg <= MIPITX_DSI_DATA_LANE3; reg += 4) 72 - mtk_mipi_tx_set_bits(mipi_tx, reg, RG_DSI_LNTx_LDOOUT_EN); 73 - 74 - mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_TOP_CON, 75 - RG_DSI_PAD_TIE_LOW_EN); 76 - 77 - return 0; 78 308 } 79 309 80 310 static int mtk_mipi_tx_power_on(struct phy *phy) ··· 65 341 return ret; 66 342 67 343 /* Enable DSI Lane LDO outputs, disable pad tie low */ 68 - mtk_mipi_tx_power_on_signal(phy); 69 - 344 + mipi_tx->driver_data->mipi_tx_enable_signal(phy); 70 345 return 0; 71 - } 72 - 73 - static void mtk_mipi_tx_power_off_signal(struct phy *phy) 74 - { 75 - struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy); 76 - u32 reg; 77 - 78 - mtk_mipi_tx_set_bits(mipi_tx, MIPITX_DSI_TOP_CON, 79 - RG_DSI_PAD_TIE_LOW_EN); 80 - 81 - for (reg = MIPITX_DSI_CLOCK_LANE; 82 - reg <= MIPITX_DSI_DATA_LANE3; reg += 4) 83 - mtk_mipi_tx_clear_bits(mipi_tx, reg, RG_DSI_LNTx_LDOOUT_EN); 84 346 } 85 347 86 348 static int mtk_mipi_tx_power_off(struct phy *phy) ··· 74 364 struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy); 75 365 76 366 /* Enable pad tie low, disable DSI Lane LDO outputs */ 77 - mtk_mipi_tx_power_off_signal(phy); 367 + mipi_tx->driver_data->mipi_tx_disable_signal(phy); 78 368 79 369 /* Disable PLL and power down core */ 80 370 clk_disable_unprepare(mipi_tx->pll); ··· 93 383 struct device *dev = &pdev->dev; 94 384 struct mtk_mipi_tx *mipi_tx; 95 385 struct resource *mem; 96 - struct clk *ref_clk; 97 386 const char *ref_clk_name; 387 + struct clk *ref_clk; 98 388 struct clk_init_data clk_init = { 99 - .ops = &mtk_mipi_tx_pll_ops, 100 389 .num_parents = 1, 101 390 .parent_names = (const char * const *)&ref_clk_name, 102 391 .flags = CLK_SET_RATE_GATE, ··· 109 400 return -ENOMEM; 110 401 111 402 mipi_tx->driver_data = of_device_get_match_data(dev); 403 + 112 404 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 113 405 mipi_tx->regs = devm_ioremap_resource(dev, mem); 114 406 if (IS_ERR(mipi_tx->regs)) { ··· 124 414 dev_err(dev, "Failed to get reference clock: %d\n", ret); 125 415 return ret; 126 416 } 417 + 127 418 ref_clk_name = __clk_get_name(ref_clk); 128 419 129 420 ret = of_property_read_string(dev->of_node, "clock-output-names", ··· 133 422 dev_err(dev, "Failed to read clock-output-names: %d\n", ret); 134 423 return ret; 135 424 } 425 + 426 + clk_init.ops = mipi_tx->driver_data->mipi_tx_clk_ops; 136 427 137 428 mipi_tx->pll_hw.init = &clk_init; 138 429 mipi_tx->pll = devm_clk_register(dev, &mipi_tx->pll_hw); ··· 170 457 return 0; 171 458 } 172 459 173 - static const struct mtk_mipitx_data mt2701_mipitx_data = { 174 - .mppll_preserve = (3 << 8) 175 - }; 176 - 177 - static const struct mtk_mipitx_data mt8173_mipitx_data = { 178 - .mppll_preserve = (0 << 8) 179 - }; 180 - 181 460 static const struct of_device_id mtk_mipi_tx_match[] = { 182 461 { .compatible = "mediatek,mt2701-mipi-tx", 183 462 .data = &mt2701_mipitx_data }, 184 463 { .compatible = "mediatek,mt8173-mipi-tx", 185 464 .data = &mt8173_mipitx_data }, 186 - {}, 465 + { .compatible = "mediatek,mt8183-mipi-tx", 466 + .data = &mt8183_mipitx_data }, 467 + { }, 187 468 }; 188 469 189 470 struct platform_driver mtk_mipi_tx_driver = { ··· 188 481 .of_match_table = mtk_mipi_tx_match, 189 482 }, 190 483 }; 484 +
+49
drivers/gpu/drm/mediatek/mtk_mipi_tx.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (c) 2019 MediaTek Inc. 4 + * Author: Jitao Shi <jitao.shi@mediatek.com> 5 + */ 6 + 7 + #ifndef _MTK_MIPI_TX_H 8 + #define _MTK_MIPI_TX_H 9 + 10 + #include <linux/clk.h> 11 + #include <linux/clk-provider.h> 12 + #include <linux/delay.h> 13 + #include <linux/io.h> 14 + #include <linux/module.h> 15 + #include <linux/of_device.h> 16 + #include <linux/platform_device.h> 17 + #include <linux/phy/phy.h> 18 + 19 + struct mtk_mipitx_data { 20 + const u32 mppll_preserve; 21 + const struct clk_ops *mipi_tx_clk_ops; 22 + void (*mipi_tx_enable_signal)(struct phy *phy); 23 + void (*mipi_tx_disable_signal)(struct phy *phy); 24 + }; 25 + 26 + struct mtk_mipi_tx { 27 + struct device *dev; 28 + void __iomem *regs; 29 + u32 data_rate; 30 + const struct mtk_mipitx_data *driver_data; 31 + struct clk_hw pll_hw; 32 + struct clk *pll; 33 + }; 34 + 35 + struct mtk_mipi_tx *mtk_mipi_tx_from_clk_hw(struct clk_hw *hw); 36 + void mtk_mipi_tx_clear_bits(struct mtk_mipi_tx *mipi_tx, u32 offset, u32 bits); 37 + void mtk_mipi_tx_set_bits(struct mtk_mipi_tx *mipi_tx, u32 offset, u32 bits); 38 + void mtk_mipi_tx_update_bits(struct mtk_mipi_tx *mipi_tx, u32 offset, u32 mask, 39 + u32 data); 40 + int mtk_mipi_tx_pll_set_rate(struct clk_hw *hw, unsigned long rate, 41 + unsigned long parent_rate); 42 + unsigned long mtk_mipi_tx_pll_recalc_rate(struct clk_hw *hw, 43 + unsigned long parent_rate); 44 + 45 + extern const struct mtk_mipitx_data mt2701_mipitx_data; 46 + extern const struct mtk_mipitx_data mt8173_mipitx_data; 47 + extern const struct mtk_mipitx_data mt8183_mipitx_data; 48 + 49 + #endif
+288
drivers/gpu/drm/mediatek/mtk_mt8173_mipi_tx.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (c) 2019 MediaTek Inc. 4 + * Author: jitao.shi <jitao.shi@mediatek.com> 5 + */ 6 + 7 + #include "mtk_mipi_tx.h" 8 + 9 + #define MIPITX_DSI_CON 0x00 10 + #define RG_DSI_LDOCORE_EN BIT(0) 11 + #define RG_DSI_CKG_LDOOUT_EN BIT(1) 12 + #define RG_DSI_BCLK_SEL (3 << 2) 13 + #define RG_DSI_LD_IDX_SEL (7 << 4) 14 + #define RG_DSI_PHYCLK_SEL (2 << 8) 15 + #define RG_DSI_DSICLK_FREQ_SEL BIT(10) 16 + #define RG_DSI_LPTX_CLMP_EN BIT(11) 17 + 18 + #define MIPITX_DSI_CLOCK_LANE 0x04 19 + #define MIPITX_DSI_DATA_LANE0 0x08 20 + #define MIPITX_DSI_DATA_LANE1 0x0c 21 + #define MIPITX_DSI_DATA_LANE2 0x10 22 + #define MIPITX_DSI_DATA_LANE3 0x14 23 + #define RG_DSI_LNTx_LDOOUT_EN BIT(0) 24 + #define RG_DSI_LNTx_CKLANE_EN BIT(1) 25 + #define RG_DSI_LNTx_LPTX_IPLUS1 BIT(2) 26 + #define RG_DSI_LNTx_LPTX_IPLUS2 BIT(3) 27 + #define RG_DSI_LNTx_LPTX_IMINUS BIT(4) 28 + #define RG_DSI_LNTx_LPCD_IPLUS BIT(5) 29 + #define RG_DSI_LNTx_LPCD_IMINUS BIT(6) 30 + #define RG_DSI_LNTx_RT_CODE (0xf << 8) 31 + 32 + #define MIPITX_DSI_TOP_CON 0x40 33 + #define RG_DSI_LNT_INTR_EN BIT(0) 34 + #define RG_DSI_LNT_HS_BIAS_EN BIT(1) 35 + #define RG_DSI_LNT_IMP_CAL_EN BIT(2) 36 + #define RG_DSI_LNT_TESTMODE_EN BIT(3) 37 + #define RG_DSI_LNT_IMP_CAL_CODE (0xf << 4) 38 + #define RG_DSI_LNT_AIO_SEL (7 << 8) 39 + #define RG_DSI_PAD_TIE_LOW_EN BIT(11) 40 + #define RG_DSI_DEBUG_INPUT_EN BIT(12) 41 + #define RG_DSI_PRESERVE (7 << 13) 42 + 43 + #define MIPITX_DSI_BG_CON 0x44 44 + #define RG_DSI_BG_CORE_EN BIT(0) 45 + #define RG_DSI_BG_CKEN BIT(1) 46 + #define RG_DSI_BG_DIV (0x3 << 2) 47 + #define RG_DSI_BG_FAST_CHARGE BIT(4) 48 + #define RG_DSI_VOUT_MSK (0x3ffff << 5) 49 + #define RG_DSI_V12_SEL (7 << 5) 50 + #define RG_DSI_V10_SEL (7 << 8) 51 + #define RG_DSI_V072_SEL (7 << 11) 52 + #define RG_DSI_V04_SEL (7 << 14) 53 + #define RG_DSI_V032_SEL (7 << 17) 54 + #define RG_DSI_V02_SEL (7 << 20) 55 + #define RG_DSI_BG_R1_TRIM (0xf << 24) 56 + #define RG_DSI_BG_R2_TRIM (0xf << 28) 57 + 58 + #define MIPITX_DSI_PLL_CON0 0x50 59 + #define RG_DSI_MPPLL_PLL_EN BIT(0) 60 + #define RG_DSI_MPPLL_DIV_MSK (0x1ff << 1) 61 + #define RG_DSI_MPPLL_PREDIV (3 << 1) 62 + #define RG_DSI_MPPLL_TXDIV0 (3 << 3) 63 + #define RG_DSI_MPPLL_TXDIV1 (3 << 5) 64 + #define RG_DSI_MPPLL_POSDIV (7 << 7) 65 + #define RG_DSI_MPPLL_MONVC_EN BIT(10) 66 + #define RG_DSI_MPPLL_MONREF_EN BIT(11) 67 + #define RG_DSI_MPPLL_VOD_EN BIT(12) 68 + 69 + #define MIPITX_DSI_PLL_CON1 0x54 70 + #define RG_DSI_MPPLL_SDM_FRA_EN BIT(0) 71 + #define RG_DSI_MPPLL_SDM_SSC_PH_INIT BIT(1) 72 + #define RG_DSI_MPPLL_SDM_SSC_EN BIT(2) 73 + #define RG_DSI_MPPLL_SDM_SSC_PRD (0xffff << 16) 74 + 75 + #define MIPITX_DSI_PLL_CON2 0x58 76 + 77 + #define MIPITX_DSI_PLL_TOP 0x64 78 + #define RG_DSI_MPPLL_PRESERVE (0xff << 8) 79 + 80 + #define MIPITX_DSI_PLL_PWR 0x68 81 + #define RG_DSI_MPPLL_SDM_PWR_ON BIT(0) 82 + #define RG_DSI_MPPLL_SDM_ISO_EN BIT(1) 83 + #define RG_DSI_MPPLL_SDM_PWR_ACK BIT(8) 84 + 85 + #define MIPITX_DSI_SW_CTRL 0x80 86 + #define SW_CTRL_EN BIT(0) 87 + 88 + #define MIPITX_DSI_SW_CTRL_CON0 0x84 89 + #define SW_LNTC_LPTX_PRE_OE BIT(0) 90 + #define SW_LNTC_LPTX_OE BIT(1) 91 + #define SW_LNTC_LPTX_P BIT(2) 92 + #define SW_LNTC_LPTX_N BIT(3) 93 + #define SW_LNTC_HSTX_PRE_OE BIT(4) 94 + #define SW_LNTC_HSTX_OE BIT(5) 95 + #define SW_LNTC_HSTX_ZEROCLK BIT(6) 96 + #define SW_LNT0_LPTX_PRE_OE BIT(7) 97 + #define SW_LNT0_LPTX_OE BIT(8) 98 + #define SW_LNT0_LPTX_P BIT(9) 99 + #define SW_LNT0_LPTX_N BIT(10) 100 + #define SW_LNT0_HSTX_PRE_OE BIT(11) 101 + #define SW_LNT0_HSTX_OE BIT(12) 102 + #define SW_LNT0_LPRX_EN BIT(13) 103 + #define SW_LNT1_LPTX_PRE_OE BIT(14) 104 + #define SW_LNT1_LPTX_OE BIT(15) 105 + #define SW_LNT1_LPTX_P BIT(16) 106 + #define SW_LNT1_LPTX_N BIT(17) 107 + #define SW_LNT1_HSTX_PRE_OE BIT(18) 108 + #define SW_LNT1_HSTX_OE BIT(19) 109 + #define SW_LNT2_LPTX_PRE_OE BIT(20) 110 + #define SW_LNT2_LPTX_OE BIT(21) 111 + #define SW_LNT2_LPTX_P BIT(22) 112 + #define SW_LNT2_LPTX_N BIT(23) 113 + #define SW_LNT2_HSTX_PRE_OE BIT(24) 114 + #define SW_LNT2_HSTX_OE BIT(25) 115 + 116 + static int mtk_mipi_tx_pll_prepare(struct clk_hw *hw) 117 + { 118 + struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw); 119 + u8 txdiv, txdiv0, txdiv1; 120 + u64 pcw; 121 + 122 + dev_dbg(mipi_tx->dev, "prepare: %u Hz\n", mipi_tx->data_rate); 123 + 124 + if (mipi_tx->data_rate >= 500000000) { 125 + txdiv = 1; 126 + txdiv0 = 0; 127 + txdiv1 = 0; 128 + } else if (mipi_tx->data_rate >= 250000000) { 129 + txdiv = 2; 130 + txdiv0 = 1; 131 + txdiv1 = 0; 132 + } else if (mipi_tx->data_rate >= 125000000) { 133 + txdiv = 4; 134 + txdiv0 = 2; 135 + txdiv1 = 0; 136 + } else if (mipi_tx->data_rate > 62000000) { 137 + txdiv = 8; 138 + txdiv0 = 2; 139 + txdiv1 = 1; 140 + } else if (mipi_tx->data_rate >= 50000000) { 141 + txdiv = 16; 142 + txdiv0 = 2; 143 + txdiv1 = 2; 144 + } else { 145 + return -EINVAL; 146 + } 147 + 148 + mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_BG_CON, 149 + RG_DSI_VOUT_MSK | 150 + RG_DSI_BG_CKEN | RG_DSI_BG_CORE_EN, 151 + (4 << 20) | (4 << 17) | (4 << 14) | 152 + (4 << 11) | (4 << 8) | (4 << 5) | 153 + RG_DSI_BG_CKEN | RG_DSI_BG_CORE_EN); 154 + 155 + usleep_range(30, 100); 156 + 157 + mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_TOP_CON, 158 + RG_DSI_LNT_IMP_CAL_CODE | RG_DSI_LNT_HS_BIAS_EN, 159 + (8 << 4) | RG_DSI_LNT_HS_BIAS_EN); 160 + 161 + mtk_mipi_tx_set_bits(mipi_tx, MIPITX_DSI_CON, 162 + RG_DSI_CKG_LDOOUT_EN | RG_DSI_LDOCORE_EN); 163 + 164 + mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_PWR, 165 + RG_DSI_MPPLL_SDM_PWR_ON | 166 + RG_DSI_MPPLL_SDM_ISO_EN, 167 + RG_DSI_MPPLL_SDM_PWR_ON); 168 + 169 + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_PLL_CON0, 170 + RG_DSI_MPPLL_PLL_EN); 171 + 172 + mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_CON0, 173 + RG_DSI_MPPLL_TXDIV0 | RG_DSI_MPPLL_TXDIV1 | 174 + RG_DSI_MPPLL_PREDIV, 175 + (txdiv0 << 3) | (txdiv1 << 5)); 176 + 177 + /* 178 + * PLL PCW config 179 + * PCW bit 24~30 = integer part of pcw 180 + * PCW bit 0~23 = fractional part of pcw 181 + * pcw = data_Rate*4*txdiv/(Ref_clk*2); 182 + * Post DIV =4, so need data_Rate*4 183 + * Ref_clk is 26MHz 184 + */ 185 + pcw = div_u64(((u64)mipi_tx->data_rate * 2 * txdiv) << 24, 186 + 26000000); 187 + writel(pcw, mipi_tx->regs + MIPITX_DSI_PLL_CON2); 188 + 189 + mtk_mipi_tx_set_bits(mipi_tx, MIPITX_DSI_PLL_CON1, 190 + RG_DSI_MPPLL_SDM_FRA_EN); 191 + 192 + mtk_mipi_tx_set_bits(mipi_tx, MIPITX_DSI_PLL_CON0, RG_DSI_MPPLL_PLL_EN); 193 + 194 + usleep_range(20, 100); 195 + 196 + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_PLL_CON1, 197 + RG_DSI_MPPLL_SDM_SSC_EN); 198 + 199 + mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_TOP, 200 + RG_DSI_MPPLL_PRESERVE, 201 + mipi_tx->driver_data->mppll_preserve); 202 + 203 + return 0; 204 + } 205 + 206 + static void mtk_mipi_tx_pll_unprepare(struct clk_hw *hw) 207 + { 208 + struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw); 209 + 210 + dev_dbg(mipi_tx->dev, "unprepare\n"); 211 + 212 + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_PLL_CON0, 213 + RG_DSI_MPPLL_PLL_EN); 214 + 215 + mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_TOP, 216 + RG_DSI_MPPLL_PRESERVE, 0); 217 + 218 + mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_PWR, 219 + RG_DSI_MPPLL_SDM_ISO_EN | 220 + RG_DSI_MPPLL_SDM_PWR_ON, 221 + RG_DSI_MPPLL_SDM_ISO_EN); 222 + 223 + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_TOP_CON, 224 + RG_DSI_LNT_HS_BIAS_EN); 225 + 226 + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_CON, 227 + RG_DSI_CKG_LDOOUT_EN | RG_DSI_LDOCORE_EN); 228 + 229 + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_BG_CON, 230 + RG_DSI_BG_CKEN | RG_DSI_BG_CORE_EN); 231 + 232 + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_PLL_CON0, 233 + RG_DSI_MPPLL_DIV_MSK); 234 + } 235 + 236 + static long mtk_mipi_tx_pll_round_rate(struct clk_hw *hw, unsigned long rate, 237 + unsigned long *prate) 238 + { 239 + return clamp_val(rate, 50000000, 1250000000); 240 + } 241 + 242 + static const struct clk_ops mtk_mipi_tx_pll_ops = { 243 + .prepare = mtk_mipi_tx_pll_prepare, 244 + .unprepare = mtk_mipi_tx_pll_unprepare, 245 + .round_rate = mtk_mipi_tx_pll_round_rate, 246 + .set_rate = mtk_mipi_tx_pll_set_rate, 247 + .recalc_rate = mtk_mipi_tx_pll_recalc_rate, 248 + }; 249 + 250 + static void mtk_mipi_tx_power_on_signal(struct phy *phy) 251 + { 252 + struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy); 253 + u32 reg; 254 + 255 + for (reg = MIPITX_DSI_CLOCK_LANE; 256 + reg <= MIPITX_DSI_DATA_LANE3; reg += 4) 257 + mtk_mipi_tx_set_bits(mipi_tx, reg, RG_DSI_LNTx_LDOOUT_EN); 258 + 259 + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_TOP_CON, 260 + RG_DSI_PAD_TIE_LOW_EN); 261 + } 262 + 263 + static void mtk_mipi_tx_power_off_signal(struct phy *phy) 264 + { 265 + struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy); 266 + u32 reg; 267 + 268 + mtk_mipi_tx_set_bits(mipi_tx, MIPITX_DSI_TOP_CON, 269 + RG_DSI_PAD_TIE_LOW_EN); 270 + 271 + for (reg = MIPITX_DSI_CLOCK_LANE; 272 + reg <= MIPITX_DSI_DATA_LANE3; reg += 4) 273 + mtk_mipi_tx_clear_bits(mipi_tx, reg, RG_DSI_LNTx_LDOOUT_EN); 274 + } 275 + 276 + const struct mtk_mipitx_data mt2701_mipitx_data = { 277 + .mppll_preserve = (3 << 8), 278 + .mipi_tx_clk_ops = &mtk_mipi_tx_pll_ops, 279 + .mipi_tx_enable_signal = mtk_mipi_tx_power_on_signal, 280 + .mipi_tx_disable_signal = mtk_mipi_tx_power_off_signal, 281 + }; 282 + 283 + const struct mtk_mipitx_data mt8173_mipitx_data = { 284 + .mppll_preserve = (0 << 8), 285 + .mipi_tx_clk_ops = &mtk_mipi_tx_pll_ops, 286 + .mipi_tx_enable_signal = mtk_mipi_tx_power_on_signal, 287 + .mipi_tx_disable_signal = mtk_mipi_tx_power_off_signal, 288 + };
+149
drivers/gpu/drm/mediatek/mtk_mt8183_mipi_tx.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (c) 2019 MediaTek Inc. 4 + * Author: jitao.shi <jitao.shi@mediatek.com> 5 + */ 6 + 7 + #include "mtk_mipi_tx.h" 8 + 9 + #define MIPITX_LANE_CON 0x000c 10 + #define RG_DSI_CPHY_T1DRV_EN BIT(0) 11 + #define RG_DSI_ANA_CK_SEL BIT(1) 12 + #define RG_DSI_PHY_CK_SEL BIT(2) 13 + #define RG_DSI_CPHY_EN BIT(3) 14 + #define RG_DSI_PHYCK_INV_EN BIT(4) 15 + #define RG_DSI_PWR04_EN BIT(5) 16 + #define RG_DSI_BG_LPF_EN BIT(6) 17 + #define RG_DSI_BG_CORE_EN BIT(7) 18 + #define RG_DSI_PAD_TIEL_SEL BIT(8) 19 + 20 + #define MIPITX_PLL_PWR 0x0028 21 + #define MIPITX_PLL_CON0 0x002c 22 + #define MIPITX_PLL_CON1 0x0030 23 + #define MIPITX_PLL_CON2 0x0034 24 + #define MIPITX_PLL_CON3 0x0038 25 + #define MIPITX_PLL_CON4 0x003c 26 + #define RG_DSI_PLL_IBIAS (3 << 10) 27 + 28 + #define MIPITX_D2_SW_CTL_EN 0x0144 29 + #define MIPITX_D0_SW_CTL_EN 0x0244 30 + #define MIPITX_CK_CKMODE_EN 0x0328 31 + #define DSI_CK_CKMODE_EN BIT(0) 32 + #define MIPITX_CK_SW_CTL_EN 0x0344 33 + #define MIPITX_D1_SW_CTL_EN 0x0444 34 + #define MIPITX_D3_SW_CTL_EN 0x0544 35 + #define DSI_SW_CTL_EN BIT(0) 36 + #define AD_DSI_PLL_SDM_PWR_ON BIT(0) 37 + #define AD_DSI_PLL_SDM_ISO_EN BIT(1) 38 + 39 + #define RG_DSI_PLL_EN BIT(4) 40 + #define RG_DSI_PLL_POSDIV (0x7 << 8) 41 + 42 + static int mtk_mipi_tx_pll_enable(struct clk_hw *hw) 43 + { 44 + struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw); 45 + unsigned int txdiv, txdiv0; 46 + u64 pcw; 47 + 48 + dev_dbg(mipi_tx->dev, "enable: %u bps\n", mipi_tx->data_rate); 49 + 50 + if (mipi_tx->data_rate >= 2000000000) { 51 + txdiv = 1; 52 + txdiv0 = 0; 53 + } else if (mipi_tx->data_rate >= 1000000000) { 54 + txdiv = 2; 55 + txdiv0 = 1; 56 + } else if (mipi_tx->data_rate >= 500000000) { 57 + txdiv = 4; 58 + txdiv0 = 2; 59 + } else if (mipi_tx->data_rate > 250000000) { 60 + txdiv = 8; 61 + txdiv0 = 3; 62 + } else if (mipi_tx->data_rate >= 125000000) { 63 + txdiv = 16; 64 + txdiv0 = 4; 65 + } else { 66 + return -EINVAL; 67 + } 68 + 69 + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_CON4, RG_DSI_PLL_IBIAS); 70 + 71 + mtk_mipi_tx_set_bits(mipi_tx, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_PWR_ON); 72 + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_CON1, RG_DSI_PLL_EN); 73 + udelay(1); 74 + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_ISO_EN); 75 + pcw = div_u64(((u64)mipi_tx->data_rate * txdiv) << 24, 26000000); 76 + writel(pcw, mipi_tx->regs + MIPITX_PLL_CON0); 77 + mtk_mipi_tx_update_bits(mipi_tx, MIPITX_PLL_CON1, RG_DSI_PLL_POSDIV, 78 + txdiv0 << 8); 79 + mtk_mipi_tx_set_bits(mipi_tx, MIPITX_PLL_CON1, RG_DSI_PLL_EN); 80 + 81 + return 0; 82 + } 83 + 84 + static void mtk_mipi_tx_pll_disable(struct clk_hw *hw) 85 + { 86 + struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw); 87 + 88 + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_CON1, RG_DSI_PLL_EN); 89 + 90 + mtk_mipi_tx_set_bits(mipi_tx, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_ISO_EN); 91 + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_PWR_ON); 92 + } 93 + 94 + static long mtk_mipi_tx_pll_round_rate(struct clk_hw *hw, unsigned long rate, 95 + unsigned long *prate) 96 + { 97 + return clamp_val(rate, 50000000, 1600000000); 98 + } 99 + 100 + static const struct clk_ops mtk_mipi_tx_pll_ops = { 101 + .enable = mtk_mipi_tx_pll_enable, 102 + .disable = mtk_mipi_tx_pll_disable, 103 + .round_rate = mtk_mipi_tx_pll_round_rate, 104 + .set_rate = mtk_mipi_tx_pll_set_rate, 105 + .recalc_rate = mtk_mipi_tx_pll_recalc_rate, 106 + }; 107 + 108 + static void mtk_mipi_tx_power_on_signal(struct phy *phy) 109 + { 110 + struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy); 111 + 112 + /* BG_LPF_EN / BG_CORE_EN */ 113 + writel(RG_DSI_PAD_TIEL_SEL | RG_DSI_BG_CORE_EN, 114 + mipi_tx->regs + MIPITX_LANE_CON); 115 + usleep_range(30, 100); 116 + writel(RG_DSI_BG_CORE_EN | RG_DSI_BG_LPF_EN, 117 + mipi_tx->regs + MIPITX_LANE_CON); 118 + 119 + /* Switch OFF each Lane */ 120 + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_D0_SW_CTL_EN, DSI_SW_CTL_EN); 121 + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_D1_SW_CTL_EN, DSI_SW_CTL_EN); 122 + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_D2_SW_CTL_EN, DSI_SW_CTL_EN); 123 + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_D3_SW_CTL_EN, DSI_SW_CTL_EN); 124 + mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_CK_SW_CTL_EN, DSI_SW_CTL_EN); 125 + 126 + mtk_mipi_tx_set_bits(mipi_tx, MIPITX_CK_CKMODE_EN, DSI_CK_CKMODE_EN); 127 + } 128 + 129 + static void mtk_mipi_tx_power_off_signal(struct phy *phy) 130 + { 131 + struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy); 132 + 133 + /* Switch ON each Lane */ 134 + mtk_mipi_tx_set_bits(mipi_tx, MIPITX_D0_SW_CTL_EN, DSI_SW_CTL_EN); 135 + mtk_mipi_tx_set_bits(mipi_tx, MIPITX_D1_SW_CTL_EN, DSI_SW_CTL_EN); 136 + mtk_mipi_tx_set_bits(mipi_tx, MIPITX_D2_SW_CTL_EN, DSI_SW_CTL_EN); 137 + mtk_mipi_tx_set_bits(mipi_tx, MIPITX_D3_SW_CTL_EN, DSI_SW_CTL_EN); 138 + mtk_mipi_tx_set_bits(mipi_tx, MIPITX_CK_SW_CTL_EN, DSI_SW_CTL_EN); 139 + 140 + writel(RG_DSI_PAD_TIEL_SEL | RG_DSI_BG_CORE_EN, 141 + mipi_tx->regs + MIPITX_LANE_CON); 142 + writel(RG_DSI_PAD_TIEL_SEL, mipi_tx->regs + MIPITX_LANE_CON); 143 + } 144 + 145 + const struct mtk_mipitx_data mt8183_mipitx_data = { 146 + .mipi_tx_clk_ops = &mtk_mipi_tx_pll_ops, 147 + .mipi_tx_enable_signal = mtk_mipi_tx_power_on_signal, 148 + .mipi_tx_disable_signal = mtk_mipi_tx_power_off_signal, 149 + };