1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2014 MediaTek Inc. 4 * Author: Jie Qiu <jie.qiu@mediatek.com> 5 */ 6 7 #include <linux/clk.h> 8 #include <linux/component.h> 9 #include <linux/interrupt.h> 10 #include <linux/kernel.h> 11 #include <linux/of.h> 12 #include <linux/of_device.h> 13 #include <linux/of_graph.h> 14 #include <linux/platform_device.h> 15 #include <linux/types.h> 16 17 #include <video/videomode.h> 18 19 #include <drm/drm_atomic_helper.h> 20 #include <drm/drm_bridge.h> 21 #include <drm/drm_crtc.h> 22 #include <drm/drm_of.h> 23 24 #include "mtk_dpi_regs.h" 25 #include "mtk_drm_ddp_comp.h" 26 27 enum mtk_dpi_out_bit_num { 28 MTK_DPI_OUT_BIT_NUM_8BITS, 29 MTK_DPI_OUT_BIT_NUM_10BITS, 30 MTK_DPI_OUT_BIT_NUM_12BITS, 31 MTK_DPI_OUT_BIT_NUM_16BITS 32 }; 33 34 enum mtk_dpi_out_yc_map { 35 MTK_DPI_OUT_YC_MAP_RGB, 36 MTK_DPI_OUT_YC_MAP_CYCY, 37 MTK_DPI_OUT_YC_MAP_YCYC, 38 MTK_DPI_OUT_YC_MAP_CY, 39 MTK_DPI_OUT_YC_MAP_YC 40 }; 41 42 enum mtk_dpi_out_channel_swap { 43 MTK_DPI_OUT_CHANNEL_SWAP_RGB, 44 MTK_DPI_OUT_CHANNEL_SWAP_GBR, 45 MTK_DPI_OUT_CHANNEL_SWAP_BRG, 46 MTK_DPI_OUT_CHANNEL_SWAP_RBG, 47 MTK_DPI_OUT_CHANNEL_SWAP_GRB, 48 MTK_DPI_OUT_CHANNEL_SWAP_BGR 49 }; 50 51 enum mtk_dpi_out_color_format { 52 MTK_DPI_COLOR_FORMAT_RGB, 53 MTK_DPI_COLOR_FORMAT_RGB_FULL, 54 MTK_DPI_COLOR_FORMAT_YCBCR_444, 55 MTK_DPI_COLOR_FORMAT_YCBCR_422, 56 MTK_DPI_COLOR_FORMAT_XV_YCC, 57 MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL, 58 MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL 59 }; 60 61 struct mtk_dpi { 62 struct mtk_ddp_comp ddp_comp; 63 struct drm_encoder encoder; 64 struct drm_bridge *bridge; 65 void __iomem *regs; 66 struct device *dev; 67 struct clk *engine_clk; 68 struct clk *pixel_clk; 69 struct clk *tvd_clk; 70 int irq; 71 struct drm_display_mode mode; 72 const struct mtk_dpi_conf *conf; 73 enum mtk_dpi_out_color_format color_format; 74 enum mtk_dpi_out_yc_map yc_map; 75 enum mtk_dpi_out_bit_num bit_num; 76 enum mtk_dpi_out_channel_swap channel_swap; 77 int refcount; 78 }; 79 80 static inline struct mtk_dpi *mtk_dpi_from_encoder(struct drm_encoder *e) 81 { 82 return container_of(e, struct mtk_dpi, encoder); 83 } 84 85 enum mtk_dpi_polarity { 86 MTK_DPI_POLARITY_RISING, 87 MTK_DPI_POLARITY_FALLING, 88 }; 89 90 struct mtk_dpi_polarities { 91 enum mtk_dpi_polarity de_pol; 92 enum mtk_dpi_polarity ck_pol; 93 enum mtk_dpi_polarity hsync_pol; 94 enum mtk_dpi_polarity vsync_pol; 95 }; 96 97 struct mtk_dpi_sync_param { 98 u32 sync_width; 99 u32 front_porch; 100 u32 back_porch; 101 bool shift_half_line; 102 }; 103 104 struct mtk_dpi_yc_limit { 105 u16 y_top; 106 u16 y_bottom; 107 u16 c_top; 108 u16 c_bottom; 109 }; 110 111 struct mtk_dpi_conf { 112 unsigned int (*cal_factor)(int clock); 113 u32 reg_h_fre_con; 114 bool edge_sel_en; 115 }; 116 117 static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask) 118 { 119 u32 tmp = readl(dpi->regs + offset) & ~mask; 120 121 tmp |= (val & mask); 122 writel(tmp, dpi->regs + offset); 123 } 124 125 static void mtk_dpi_sw_reset(struct mtk_dpi *dpi, bool reset) 126 { 127 mtk_dpi_mask(dpi, DPI_RET, reset ? RST : 0, RST); 128 } 129 130 static void mtk_dpi_enable(struct mtk_dpi *dpi) 131 { 132 mtk_dpi_mask(dpi, DPI_EN, EN, EN); 133 } 134 135 static void mtk_dpi_disable(struct mtk_dpi *dpi) 136 { 137 mtk_dpi_mask(dpi, DPI_EN, 0, EN); 138 } 139 140 static void mtk_dpi_config_hsync(struct mtk_dpi *dpi, 141 struct mtk_dpi_sync_param *sync) 142 { 143 mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH, 144 sync->sync_width << HPW, HPW_MASK); 145 mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, 146 sync->back_porch << HBP, HBP_MASK); 147 mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP, 148 HFP_MASK); 149 } 150 151 static void mtk_dpi_config_vsync(struct mtk_dpi *dpi, 152 struct mtk_dpi_sync_param *sync, 153 u32 width_addr, u32 porch_addr) 154 { 155 mtk_dpi_mask(dpi, width_addr, 156 sync->sync_width << VSYNC_WIDTH_SHIFT, 157 VSYNC_WIDTH_MASK); 158 mtk_dpi_mask(dpi, width_addr, 159 sync->shift_half_line << VSYNC_HALF_LINE_SHIFT, 160 VSYNC_HALF_LINE_MASK); 161 mtk_dpi_mask(dpi, porch_addr, 162 sync->back_porch << VSYNC_BACK_PORCH_SHIFT, 163 VSYNC_BACK_PORCH_MASK); 164 mtk_dpi_mask(dpi, porch_addr, 165 sync->front_porch << VSYNC_FRONT_PORCH_SHIFT, 166 VSYNC_FRONT_PORCH_MASK); 167 } 168 169 static void mtk_dpi_config_vsync_lodd(struct mtk_dpi *dpi, 170 struct mtk_dpi_sync_param *sync) 171 { 172 mtk_dpi_config_vsync(dpi, sync, DPI_TGEN_VWIDTH, DPI_TGEN_VPORCH); 173 } 174 175 static void mtk_dpi_config_vsync_leven(struct mtk_dpi *dpi, 176 struct mtk_dpi_sync_param *sync) 177 { 178 mtk_dpi_config_vsync(dpi, sync, DPI_TGEN_VWIDTH_LEVEN, 179 DPI_TGEN_VPORCH_LEVEN); 180 } 181 182 static void mtk_dpi_config_vsync_rodd(struct mtk_dpi *dpi, 183 struct mtk_dpi_sync_param *sync) 184 { 185 mtk_dpi_config_vsync(dpi, sync, DPI_TGEN_VWIDTH_RODD, 186 DPI_TGEN_VPORCH_RODD); 187 } 188 189 static void mtk_dpi_config_vsync_reven(struct mtk_dpi *dpi, 190 struct mtk_dpi_sync_param *sync) 191 { 192 mtk_dpi_config_vsync(dpi, sync, DPI_TGEN_VWIDTH_REVEN, 193 DPI_TGEN_VPORCH_REVEN); 194 } 195 196 static void mtk_dpi_config_pol(struct mtk_dpi *dpi, 197 struct mtk_dpi_polarities *dpi_pol) 198 { 199 unsigned int pol; 200 201 pol = (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ? 0 : CK_POL) | 202 (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ? 0 : DE_POL) | 203 (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 : HSYNC_POL) | 204 (dpi_pol->vsync_pol == MTK_DPI_POLARITY_RISING ? 0 : VSYNC_POL); 205 mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol, 206 CK_POL | DE_POL | HSYNC_POL | VSYNC_POL); 207 } 208 209 static void mtk_dpi_config_3d(struct mtk_dpi *dpi, bool en_3d) 210 { 211 mtk_dpi_mask(dpi, DPI_CON, en_3d ? TDFP_EN : 0, TDFP_EN); 212 } 213 214 static void mtk_dpi_config_interface(struct mtk_dpi *dpi, bool inter) 215 { 216 mtk_dpi_mask(dpi, DPI_CON, inter ? INTL_EN : 0, INTL_EN); 217 } 218 219 static void mtk_dpi_config_fb_size(struct mtk_dpi *dpi, u32 width, u32 height) 220 { 221 mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE, HSIZE_MASK); 222 mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE, VSIZE_MASK); 223 } 224 225 static void mtk_dpi_config_channel_limit(struct mtk_dpi *dpi, 226 struct mtk_dpi_yc_limit *limit) 227 { 228 mtk_dpi_mask(dpi, DPI_Y_LIMIT, limit->y_bottom << Y_LIMINT_BOT, 229 Y_LIMINT_BOT_MASK); 230 mtk_dpi_mask(dpi, DPI_Y_LIMIT, limit->y_top << Y_LIMINT_TOP, 231 Y_LIMINT_TOP_MASK); 232 mtk_dpi_mask(dpi, DPI_C_LIMIT, limit->c_bottom << C_LIMIT_BOT, 233 C_LIMIT_BOT_MASK); 234 mtk_dpi_mask(dpi, DPI_C_LIMIT, limit->c_top << C_LIMIT_TOP, 235 C_LIMIT_TOP_MASK); 236 } 237 238 static void mtk_dpi_config_bit_num(struct mtk_dpi *dpi, 239 enum mtk_dpi_out_bit_num num) 240 { 241 u32 val; 242 243 switch (num) { 244 case MTK_DPI_OUT_BIT_NUM_8BITS: 245 val = OUT_BIT_8; 246 break; 247 case MTK_DPI_OUT_BIT_NUM_10BITS: 248 val = OUT_BIT_10; 249 break; 250 case MTK_DPI_OUT_BIT_NUM_12BITS: 251 val = OUT_BIT_12; 252 break; 253 case MTK_DPI_OUT_BIT_NUM_16BITS: 254 val = OUT_BIT_16; 255 break; 256 default: 257 val = OUT_BIT_8; 258 break; 259 } 260 mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << OUT_BIT, 261 OUT_BIT_MASK); 262 } 263 264 static void mtk_dpi_config_yc_map(struct mtk_dpi *dpi, 265 enum mtk_dpi_out_yc_map map) 266 { 267 u32 val; 268 269 switch (map) { 270 case MTK_DPI_OUT_YC_MAP_RGB: 271 val = YC_MAP_RGB; 272 break; 273 case MTK_DPI_OUT_YC_MAP_CYCY: 274 val = YC_MAP_CYCY; 275 break; 276 case MTK_DPI_OUT_YC_MAP_YCYC: 277 val = YC_MAP_YCYC; 278 break; 279 case MTK_DPI_OUT_YC_MAP_CY: 280 val = YC_MAP_CY; 281 break; 282 case MTK_DPI_OUT_YC_MAP_YC: 283 val = YC_MAP_YC; 284 break; 285 default: 286 val = YC_MAP_RGB; 287 break; 288 } 289 290 mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << YC_MAP, YC_MAP_MASK); 291 } 292 293 static void mtk_dpi_config_channel_swap(struct mtk_dpi *dpi, 294 enum mtk_dpi_out_channel_swap swap) 295 { 296 u32 val; 297 298 switch (swap) { 299 case MTK_DPI_OUT_CHANNEL_SWAP_RGB: 300 val = SWAP_RGB; 301 break; 302 case MTK_DPI_OUT_CHANNEL_SWAP_GBR: 303 val = SWAP_GBR; 304 break; 305 case MTK_DPI_OUT_CHANNEL_SWAP_BRG: 306 val = SWAP_BRG; 307 break; 308 case MTK_DPI_OUT_CHANNEL_SWAP_RBG: 309 val = SWAP_RBG; 310 break; 311 case MTK_DPI_OUT_CHANNEL_SWAP_GRB: 312 val = SWAP_GRB; 313 break; 314 case MTK_DPI_OUT_CHANNEL_SWAP_BGR: 315 val = SWAP_BGR; 316 break; 317 default: 318 val = SWAP_RGB; 319 break; 320 } 321 322 mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << CH_SWAP, CH_SWAP_MASK); 323 } 324 325 static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool enable) 326 { 327 mtk_dpi_mask(dpi, DPI_CON, enable ? YUV422_EN : 0, YUV422_EN); 328 } 329 330 static void mtk_dpi_config_csc_enable(struct mtk_dpi *dpi, bool enable) 331 { 332 mtk_dpi_mask(dpi, DPI_CON, enable ? CSC_ENABLE : 0, CSC_ENABLE); 333 } 334 335 static void mtk_dpi_config_swap_input(struct mtk_dpi *dpi, bool enable) 336 { 337 mtk_dpi_mask(dpi, DPI_CON, enable ? IN_RB_SWAP : 0, IN_RB_SWAP); 338 } 339 340 static void mtk_dpi_config_2n_h_fre(struct mtk_dpi *dpi) 341 { 342 mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, H_FRE_2N, H_FRE_2N); 343 } 344 345 static void mtk_dpi_config_disable_edge(struct mtk_dpi *dpi) 346 { 347 if (dpi->conf->edge_sel_en) 348 mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, 0, EDGE_SEL_EN); 349 } 350 351 static void mtk_dpi_config_color_format(struct mtk_dpi *dpi, 352 enum mtk_dpi_out_color_format format) 353 { 354 if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_444) || 355 (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) { 356 mtk_dpi_config_yuv422_enable(dpi, false); 357 mtk_dpi_config_csc_enable(dpi, true); 358 mtk_dpi_config_swap_input(dpi, false); 359 mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_BGR); 360 } else if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_422) || 361 (format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) { 362 mtk_dpi_config_yuv422_enable(dpi, true); 363 mtk_dpi_config_csc_enable(dpi, true); 364 mtk_dpi_config_swap_input(dpi, true); 365 mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB); 366 } else { 367 mtk_dpi_config_yuv422_enable(dpi, false); 368 mtk_dpi_config_csc_enable(dpi, false); 369 mtk_dpi_config_swap_input(dpi, false); 370 mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB); 371 } 372 } 373 374 static void mtk_dpi_power_off(struct mtk_dpi *dpi) 375 { 376 if (WARN_ON(dpi->refcount == 0)) 377 return; 378 379 if (--dpi->refcount != 0) 380 return; 381 382 mtk_dpi_disable(dpi); 383 clk_disable_unprepare(dpi->pixel_clk); 384 clk_disable_unprepare(dpi->engine_clk); 385 } 386 387 static int mtk_dpi_power_on(struct mtk_dpi *dpi) 388 { 389 int ret; 390 391 if (++dpi->refcount != 1) 392 return 0; 393 394 ret = clk_prepare_enable(dpi->engine_clk); 395 if (ret) { 396 dev_err(dpi->dev, "Failed to enable engine clock: %d\n", ret); 397 goto err_refcount; 398 } 399 400 ret = clk_prepare_enable(dpi->pixel_clk); 401 if (ret) { 402 dev_err(dpi->dev, "Failed to enable pixel clock: %d\n", ret); 403 goto err_pixel; 404 } 405 406 mtk_dpi_enable(dpi); 407 return 0; 408 409 err_pixel: 410 clk_disable_unprepare(dpi->engine_clk); 411 err_refcount: 412 dpi->refcount--; 413 return ret; 414 } 415 416 static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi, 417 struct drm_display_mode *mode) 418 { 419 struct mtk_dpi_yc_limit limit; 420 struct mtk_dpi_polarities dpi_pol; 421 struct mtk_dpi_sync_param hsync; 422 struct mtk_dpi_sync_param vsync_lodd = { 0 }; 423 struct mtk_dpi_sync_param vsync_leven = { 0 }; 424 struct mtk_dpi_sync_param vsync_rodd = { 0 }; 425 struct mtk_dpi_sync_param vsync_reven = { 0 }; 426 struct videomode vm = { 0 }; 427 unsigned long pll_rate; 428 unsigned int factor; 429 430 /* let pll_rate can fix the valid range of tvdpll (1G~2GHz) */ 431 factor = dpi->conf->cal_factor(mode->clock); 432 drm_display_mode_to_videomode(mode, &vm); 433 pll_rate = vm.pixelclock * factor; 434 435 dev_dbg(dpi->dev, "Want PLL %lu Hz, pixel clock %lu Hz\n", 436 pll_rate, vm.pixelclock); 437 438 clk_set_rate(dpi->tvd_clk, pll_rate); 439 pll_rate = clk_get_rate(dpi->tvd_clk); 440 441 vm.pixelclock = pll_rate / factor; 442 clk_set_rate(dpi->pixel_clk, vm.pixelclock); 443 vm.pixelclock = clk_get_rate(dpi->pixel_clk); 444 445 dev_dbg(dpi->dev, "Got PLL %lu Hz, pixel clock %lu Hz\n", 446 pll_rate, vm.pixelclock); 447 448 limit.c_bottom = 0x0010; 449 limit.c_top = 0x0FE0; 450 limit.y_bottom = 0x0010; 451 limit.y_top = 0x0FE0; 452 453 dpi_pol.ck_pol = MTK_DPI_POLARITY_FALLING; 454 dpi_pol.de_pol = MTK_DPI_POLARITY_RISING; 455 dpi_pol.hsync_pol = vm.flags & DISPLAY_FLAGS_HSYNC_HIGH ? 456 MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING; 457 dpi_pol.vsync_pol = vm.flags & DISPLAY_FLAGS_VSYNC_HIGH ? 458 MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING; 459 hsync.sync_width = vm.hsync_len; 460 hsync.back_porch = vm.hback_porch; 461 hsync.front_porch = vm.hfront_porch; 462 hsync.shift_half_line = false; 463 vsync_lodd.sync_width = vm.vsync_len; 464 vsync_lodd.back_porch = vm.vback_porch; 465 vsync_lodd.front_porch = vm.vfront_porch; 466 vsync_lodd.shift_half_line = false; 467 468 if (vm.flags & DISPLAY_FLAGS_INTERLACED && 469 mode->flags & DRM_MODE_FLAG_3D_MASK) { 470 vsync_leven = vsync_lodd; 471 vsync_rodd = vsync_lodd; 472 vsync_reven = vsync_lodd; 473 vsync_leven.shift_half_line = true; 474 vsync_reven.shift_half_line = true; 475 } else if (vm.flags & DISPLAY_FLAGS_INTERLACED && 476 !(mode->flags & DRM_MODE_FLAG_3D_MASK)) { 477 vsync_leven = vsync_lodd; 478 vsync_leven.shift_half_line = true; 479 } else if (!(vm.flags & DISPLAY_FLAGS_INTERLACED) && 480 mode->flags & DRM_MODE_FLAG_3D_MASK) { 481 vsync_rodd = vsync_lodd; 482 } 483 mtk_dpi_sw_reset(dpi, true); 484 mtk_dpi_config_pol(dpi, &dpi_pol); 485 486 mtk_dpi_config_hsync(dpi, &hsync); 487 mtk_dpi_config_vsync_lodd(dpi, &vsync_lodd); 488 mtk_dpi_config_vsync_rodd(dpi, &vsync_rodd); 489 mtk_dpi_config_vsync_leven(dpi, &vsync_leven); 490 mtk_dpi_config_vsync_reven(dpi, &vsync_reven); 491 492 mtk_dpi_config_3d(dpi, !!(mode->flags & DRM_MODE_FLAG_3D_MASK)); 493 mtk_dpi_config_interface(dpi, !!(vm.flags & 494 DISPLAY_FLAGS_INTERLACED)); 495 if (vm.flags & DISPLAY_FLAGS_INTERLACED) 496 mtk_dpi_config_fb_size(dpi, vm.hactive, vm.vactive >> 1); 497 else 498 mtk_dpi_config_fb_size(dpi, vm.hactive, vm.vactive); 499 500 mtk_dpi_config_channel_limit(dpi, &limit); 501 mtk_dpi_config_bit_num(dpi, dpi->bit_num); 502 mtk_dpi_config_channel_swap(dpi, dpi->channel_swap); 503 mtk_dpi_config_yc_map(dpi, dpi->yc_map); 504 mtk_dpi_config_color_format(dpi, dpi->color_format); 505 mtk_dpi_config_2n_h_fre(dpi); 506 mtk_dpi_config_disable_edge(dpi); 507 mtk_dpi_sw_reset(dpi, false); 508 509 return 0; 510 } 511 512 static void mtk_dpi_encoder_destroy(struct drm_encoder *encoder) 513 { 514 drm_encoder_cleanup(encoder); 515 } 516 517 static const struct drm_encoder_funcs mtk_dpi_encoder_funcs = { 518 .destroy = mtk_dpi_encoder_destroy, 519 }; 520 521 static bool mtk_dpi_encoder_mode_fixup(struct drm_encoder *encoder, 522 const struct drm_display_mode *mode, 523 struct drm_display_mode *adjusted_mode) 524 { 525 return true; 526 } 527 528 static void mtk_dpi_encoder_mode_set(struct drm_encoder *encoder, 529 struct drm_display_mode *mode, 530 struct drm_display_mode *adjusted_mode) 531 { 532 struct mtk_dpi *dpi = mtk_dpi_from_encoder(encoder); 533 534 drm_mode_copy(&dpi->mode, adjusted_mode); 535 } 536 537 static void mtk_dpi_encoder_disable(struct drm_encoder *encoder) 538 { 539 struct mtk_dpi *dpi = mtk_dpi_from_encoder(encoder); 540 541 mtk_dpi_power_off(dpi); 542 } 543 544 static void mtk_dpi_encoder_enable(struct drm_encoder *encoder) 545 { 546 struct mtk_dpi *dpi = mtk_dpi_from_encoder(encoder); 547 548 mtk_dpi_power_on(dpi); 549 mtk_dpi_set_display_mode(dpi, &dpi->mode); 550 } 551 552 static int mtk_dpi_atomic_check(struct drm_encoder *encoder, 553 struct drm_crtc_state *crtc_state, 554 struct drm_connector_state *conn_state) 555 { 556 return 0; 557 } 558 559 static const struct drm_encoder_helper_funcs mtk_dpi_encoder_helper_funcs = { 560 .mode_fixup = mtk_dpi_encoder_mode_fixup, 561 .mode_set = mtk_dpi_encoder_mode_set, 562 .disable = mtk_dpi_encoder_disable, 563 .enable = mtk_dpi_encoder_enable, 564 .atomic_check = mtk_dpi_atomic_check, 565 }; 566 567 static void mtk_dpi_start(struct mtk_ddp_comp *comp) 568 { 569 struct mtk_dpi *dpi = container_of(comp, struct mtk_dpi, ddp_comp); 570 571 mtk_dpi_power_on(dpi); 572 } 573 574 static void mtk_dpi_stop(struct mtk_ddp_comp *comp) 575 { 576 struct mtk_dpi *dpi = container_of(comp, struct mtk_dpi, ddp_comp); 577 578 mtk_dpi_power_off(dpi); 579 } 580 581 static const struct mtk_ddp_comp_funcs mtk_dpi_funcs = { 582 .start = mtk_dpi_start, 583 .stop = mtk_dpi_stop, 584 }; 585 586 static int mtk_dpi_bind(struct device *dev, struct device *master, void *data) 587 { 588 struct mtk_dpi *dpi = dev_get_drvdata(dev); 589 struct drm_device *drm_dev = data; 590 int ret; 591 592 ret = mtk_ddp_comp_register(drm_dev, &dpi->ddp_comp); 593 if (ret < 0) { 594 dev_err(dev, "Failed to register component %pOF: %d\n", 595 dev->of_node, ret); 596 return ret; 597 } 598 599 ret = drm_encoder_init(drm_dev, &dpi->encoder, &mtk_dpi_encoder_funcs, 600 DRM_MODE_ENCODER_TMDS, NULL); 601 if (ret) { 602 dev_err(dev, "Failed to initialize decoder: %d\n", ret); 603 goto err_unregister; 604 } 605 drm_encoder_helper_add(&dpi->encoder, &mtk_dpi_encoder_helper_funcs); 606 607 /* Currently DPI0 is fixed to be driven by OVL1 */ 608 dpi->encoder.possible_crtcs = BIT(1); 609 610 ret = drm_bridge_attach(&dpi->encoder, dpi->bridge, NULL, 0); 611 if (ret) { 612 dev_err(dev, "Failed to attach bridge: %d\n", ret); 613 goto err_cleanup; 614 } 615 616 dpi->bit_num = MTK_DPI_OUT_BIT_NUM_8BITS; 617 dpi->channel_swap = MTK_DPI_OUT_CHANNEL_SWAP_RGB; 618 dpi->yc_map = MTK_DPI_OUT_YC_MAP_RGB; 619 dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB; 620 621 return 0; 622 623 err_cleanup: 624 drm_encoder_cleanup(&dpi->encoder); 625 err_unregister: 626 mtk_ddp_comp_unregister(drm_dev, &dpi->ddp_comp); 627 return ret; 628 } 629 630 static void mtk_dpi_unbind(struct device *dev, struct device *master, 631 void *data) 632 { 633 struct mtk_dpi *dpi = dev_get_drvdata(dev); 634 struct drm_device *drm_dev = data; 635 636 drm_encoder_cleanup(&dpi->encoder); 637 mtk_ddp_comp_unregister(drm_dev, &dpi->ddp_comp); 638 } 639 640 static const struct component_ops mtk_dpi_component_ops = { 641 .bind = mtk_dpi_bind, 642 .unbind = mtk_dpi_unbind, 643 }; 644 645 static unsigned int mt8173_calculate_factor(int clock) 646 { 647 if (clock <= 27000) 648 return 3 << 4; 649 else if (clock <= 84000) 650 return 3 << 3; 651 else if (clock <= 167000) 652 return 3 << 2; 653 else 654 return 3 << 1; 655 } 656 657 static unsigned int mt2701_calculate_factor(int clock) 658 { 659 if (clock <= 64000) 660 return 4; 661 else if (clock <= 128000) 662 return 2; 663 else 664 return 1; 665 } 666 667 static unsigned int mt8183_calculate_factor(int clock) 668 { 669 if (clock <= 27000) 670 return 8; 671 else if (clock <= 167000) 672 return 4; 673 else 674 return 2; 675 } 676 677 static const struct mtk_dpi_conf mt8173_conf = { 678 .cal_factor = mt8173_calculate_factor, 679 .reg_h_fre_con = 0xe0, 680 }; 681 682 static const struct mtk_dpi_conf mt2701_conf = { 683 .cal_factor = mt2701_calculate_factor, 684 .reg_h_fre_con = 0xb0, 685 .edge_sel_en = true, 686 }; 687 688 static const struct mtk_dpi_conf mt8183_conf = { 689 .cal_factor = mt8183_calculate_factor, 690 .reg_h_fre_con = 0xe0, 691 }; 692 693 static int mtk_dpi_probe(struct platform_device *pdev) 694 { 695 struct device *dev = &pdev->dev; 696 struct mtk_dpi *dpi; 697 struct resource *mem; 698 int comp_id; 699 int ret; 700 701 dpi = devm_kzalloc(dev, sizeof(*dpi), GFP_KERNEL); 702 if (!dpi) 703 return -ENOMEM; 704 705 dpi->dev = dev; 706 dpi->conf = (struct mtk_dpi_conf *)of_device_get_match_data(dev); 707 708 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 709 dpi->regs = devm_ioremap_resource(dev, mem); 710 if (IS_ERR(dpi->regs)) { 711 ret = PTR_ERR(dpi->regs); 712 dev_err(dev, "Failed to ioremap mem resource: %d\n", ret); 713 return ret; 714 } 715 716 dpi->engine_clk = devm_clk_get(dev, "engine"); 717 if (IS_ERR(dpi->engine_clk)) { 718 ret = PTR_ERR(dpi->engine_clk); 719 dev_err(dev, "Failed to get engine clock: %d\n", ret); 720 return ret; 721 } 722 723 dpi->pixel_clk = devm_clk_get(dev, "pixel"); 724 if (IS_ERR(dpi->pixel_clk)) { 725 ret = PTR_ERR(dpi->pixel_clk); 726 dev_err(dev, "Failed to get pixel clock: %d\n", ret); 727 return ret; 728 } 729 730 dpi->tvd_clk = devm_clk_get(dev, "pll"); 731 if (IS_ERR(dpi->tvd_clk)) { 732 ret = PTR_ERR(dpi->tvd_clk); 733 dev_err(dev, "Failed to get tvdpll clock: %d\n", ret); 734 return ret; 735 } 736 737 dpi->irq = platform_get_irq(pdev, 0); 738 if (dpi->irq <= 0) { 739 dev_err(dev, "Failed to get irq: %d\n", dpi->irq); 740 return -EINVAL; 741 } 742 743 ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0, 744 NULL, &dpi->bridge); 745 if (ret) 746 return ret; 747 748 dev_info(dev, "Found bridge node: %pOF\n", dpi->bridge->of_node); 749 750 comp_id = mtk_ddp_comp_get_id(dev->of_node, MTK_DPI); 751 if (comp_id < 0) { 752 dev_err(dev, "Failed to identify by alias: %d\n", comp_id); 753 return comp_id; 754 } 755 756 ret = mtk_ddp_comp_init(dev, dev->of_node, &dpi->ddp_comp, comp_id, 757 &mtk_dpi_funcs); 758 if (ret) { 759 dev_err(dev, "Failed to initialize component: %d\n", ret); 760 return ret; 761 } 762 763 platform_set_drvdata(pdev, dpi); 764 765 ret = component_add(dev, &mtk_dpi_component_ops); 766 if (ret) { 767 dev_err(dev, "Failed to add component: %d\n", ret); 768 return ret; 769 } 770 771 return 0; 772 } 773 774 static int mtk_dpi_remove(struct platform_device *pdev) 775 { 776 component_del(&pdev->dev, &mtk_dpi_component_ops); 777 778 return 0; 779 } 780 781 static const struct of_device_id mtk_dpi_of_ids[] = { 782 { .compatible = "mediatek,mt2701-dpi", 783 .data = &mt2701_conf, 784 }, 785 { .compatible = "mediatek,mt8173-dpi", 786 .data = &mt8173_conf, 787 }, 788 { .compatible = "mediatek,mt8183-dpi", 789 .data = &mt8183_conf, 790 }, 791 { }, 792 }; 793 794 struct platform_driver mtk_dpi_driver = { 795 .probe = mtk_dpi_probe, 796 .remove = mtk_dpi_remove, 797 .driver = { 798 .name = "mediatek-dpi", 799 .of_match_table = mtk_dpi_of_ids, 800 }, 801 }; 802