1 /* 2 * Copyright (c) 2014 MediaTek Inc. 3 * Author: Jie Qiu <jie.qiu@mediatek.com> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 */ 14 #include <drm/drmP.h> 15 #include <drm/drm_crtc.h> 16 #include <drm/drm_crtc_helper.h> 17 #include <linux/kernel.h> 18 #include <linux/component.h> 19 #include <linux/platform_device.h> 20 #include <linux/of.h> 21 #include <linux/of_graph.h> 22 #include <linux/interrupt.h> 23 #include <linux/types.h> 24 #include <linux/clk.h> 25 26 #include "mtk_dpi_regs.h" 27 #include "mtk_drm_ddp_comp.h" 28 29 enum mtk_dpi_out_bit_num { 30 MTK_DPI_OUT_BIT_NUM_8BITS, 31 MTK_DPI_OUT_BIT_NUM_10BITS, 32 MTK_DPI_OUT_BIT_NUM_12BITS, 33 MTK_DPI_OUT_BIT_NUM_16BITS 34 }; 35 36 enum mtk_dpi_out_yc_map { 37 MTK_DPI_OUT_YC_MAP_RGB, 38 MTK_DPI_OUT_YC_MAP_CYCY, 39 MTK_DPI_OUT_YC_MAP_YCYC, 40 MTK_DPI_OUT_YC_MAP_CY, 41 MTK_DPI_OUT_YC_MAP_YC 42 }; 43 44 enum mtk_dpi_out_channel_swap { 45 MTK_DPI_OUT_CHANNEL_SWAP_RGB, 46 MTK_DPI_OUT_CHANNEL_SWAP_GBR, 47 MTK_DPI_OUT_CHANNEL_SWAP_BRG, 48 MTK_DPI_OUT_CHANNEL_SWAP_RBG, 49 MTK_DPI_OUT_CHANNEL_SWAP_GRB, 50 MTK_DPI_OUT_CHANNEL_SWAP_BGR 51 }; 52 53 enum mtk_dpi_out_color_format { 54 MTK_DPI_COLOR_FORMAT_RGB, 55 MTK_DPI_COLOR_FORMAT_RGB_FULL, 56 MTK_DPI_COLOR_FORMAT_YCBCR_444, 57 MTK_DPI_COLOR_FORMAT_YCBCR_422, 58 MTK_DPI_COLOR_FORMAT_XV_YCC, 59 MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL, 60 MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL 61 }; 62 63 struct mtk_dpi { 64 struct mtk_ddp_comp ddp_comp; 65 struct drm_encoder encoder; 66 void __iomem *regs; 67 struct device *dev; 68 struct clk *engine_clk; 69 struct clk *pixel_clk; 70 struct clk *tvd_clk; 71 int irq; 72 struct drm_display_mode mode; 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 bool power_sta; 78 u8 power_ctl; 79 }; 80 81 static inline struct mtk_dpi *mtk_dpi_from_encoder(struct drm_encoder *e) 82 { 83 return container_of(e, struct mtk_dpi, encoder); 84 } 85 86 enum mtk_dpi_polarity { 87 MTK_DPI_POLARITY_RISING, 88 MTK_DPI_POLARITY_FALLING, 89 }; 90 91 enum mtk_dpi_power_ctl { 92 DPI_POWER_START = BIT(0), 93 DPI_POWER_ENABLE = BIT(1), 94 }; 95 96 struct mtk_dpi_polarities { 97 enum mtk_dpi_polarity de_pol; 98 enum mtk_dpi_polarity ck_pol; 99 enum mtk_dpi_polarity hsync_pol; 100 enum mtk_dpi_polarity vsync_pol; 101 }; 102 103 struct mtk_dpi_sync_param { 104 u32 sync_width; 105 u32 front_porch; 106 u32 back_porch; 107 bool shift_half_line; 108 }; 109 110 struct mtk_dpi_yc_limit { 111 u16 y_top; 112 u16 y_bottom; 113 u16 c_top; 114 u16 c_bottom; 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_H_FRE_CON, H_FRE_2N, H_FRE_2N); 343 } 344 345 static void mtk_dpi_config_color_format(struct mtk_dpi *dpi, 346 enum mtk_dpi_out_color_format format) 347 { 348 if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_444) || 349 (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) { 350 mtk_dpi_config_yuv422_enable(dpi, false); 351 mtk_dpi_config_csc_enable(dpi, true); 352 mtk_dpi_config_swap_input(dpi, false); 353 mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_BGR); 354 } else if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_422) || 355 (format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) { 356 mtk_dpi_config_yuv422_enable(dpi, true); 357 mtk_dpi_config_csc_enable(dpi, true); 358 mtk_dpi_config_swap_input(dpi, true); 359 mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB); 360 } else { 361 mtk_dpi_config_yuv422_enable(dpi, false); 362 mtk_dpi_config_csc_enable(dpi, false); 363 mtk_dpi_config_swap_input(dpi, false); 364 mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB); 365 } 366 } 367 368 static void mtk_dpi_power_off(struct mtk_dpi *dpi, enum mtk_dpi_power_ctl pctl) 369 { 370 dpi->power_ctl &= ~pctl; 371 372 if ((dpi->power_ctl & DPI_POWER_START) || 373 (dpi->power_ctl & DPI_POWER_ENABLE)) 374 return; 375 376 if (!dpi->power_sta) 377 return; 378 379 mtk_dpi_disable(dpi); 380 clk_disable_unprepare(dpi->pixel_clk); 381 clk_disable_unprepare(dpi->engine_clk); 382 dpi->power_sta = false; 383 } 384 385 static int mtk_dpi_power_on(struct mtk_dpi *dpi, enum mtk_dpi_power_ctl pctl) 386 { 387 int ret; 388 389 dpi->power_ctl |= pctl; 390 391 if (!(dpi->power_ctl & DPI_POWER_START) && 392 !(dpi->power_ctl & DPI_POWER_ENABLE)) 393 return 0; 394 395 if (dpi->power_sta) 396 return 0; 397 398 ret = clk_prepare_enable(dpi->engine_clk); 399 if (ret) { 400 dev_err(dpi->dev, "Failed to enable engine clock: %d\n", ret); 401 goto err_eng; 402 } 403 404 ret = clk_prepare_enable(dpi->pixel_clk); 405 if (ret) { 406 dev_err(dpi->dev, "Failed to enable pixel clock: %d\n", ret); 407 goto err_pixel; 408 } 409 410 mtk_dpi_enable(dpi); 411 dpi->power_sta = true; 412 return 0; 413 414 err_pixel: 415 clk_disable_unprepare(dpi->engine_clk); 416 err_eng: 417 dpi->power_ctl &= ~pctl; 418 return ret; 419 } 420 421 static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi, 422 struct drm_display_mode *mode) 423 { 424 struct mtk_dpi_yc_limit limit; 425 struct mtk_dpi_polarities dpi_pol; 426 struct mtk_dpi_sync_param hsync; 427 struct mtk_dpi_sync_param vsync_lodd = { 0 }; 428 struct mtk_dpi_sync_param vsync_leven = { 0 }; 429 struct mtk_dpi_sync_param vsync_rodd = { 0 }; 430 struct mtk_dpi_sync_param vsync_reven = { 0 }; 431 unsigned long pix_rate; 432 unsigned long pll_rate; 433 unsigned int factor; 434 435 pix_rate = 1000UL * mode->clock; 436 if (mode->clock <= 74000) 437 factor = 8 * 3; 438 else 439 factor = 4 * 3; 440 pll_rate = pix_rate * factor; 441 442 dev_dbg(dpi->dev, "Want PLL %lu Hz, pixel clock %lu Hz\n", 443 pll_rate, pix_rate); 444 445 clk_set_rate(dpi->tvd_clk, pll_rate); 446 pll_rate = clk_get_rate(dpi->tvd_clk); 447 448 pix_rate = pll_rate / factor; 449 clk_set_rate(dpi->pixel_clk, pix_rate); 450 pix_rate = clk_get_rate(dpi->pixel_clk); 451 452 dev_dbg(dpi->dev, "Got PLL %lu Hz, pixel clock %lu Hz\n", 453 pll_rate, pix_rate); 454 455 limit.c_bottom = 0x0010; 456 limit.c_top = 0x0FE0; 457 limit.y_bottom = 0x0010; 458 limit.y_top = 0x0FE0; 459 460 dpi_pol.ck_pol = MTK_DPI_POLARITY_FALLING; 461 dpi_pol.de_pol = MTK_DPI_POLARITY_RISING; 462 dpi_pol.hsync_pol = mode->flags & DRM_MODE_FLAG_PHSYNC ? 463 MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING; 464 dpi_pol.vsync_pol = mode->flags & DRM_MODE_FLAG_PVSYNC ? 465 MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING; 466 467 hsync.sync_width = mode->hsync_end - mode->hsync_start; 468 hsync.back_porch = mode->htotal - mode->hsync_end; 469 hsync.front_porch = mode->hsync_start - mode->hdisplay; 470 hsync.shift_half_line = false; 471 472 vsync_lodd.sync_width = mode->vsync_end - mode->vsync_start; 473 vsync_lodd.back_porch = mode->vtotal - mode->vsync_end; 474 vsync_lodd.front_porch = mode->vsync_start - mode->vdisplay; 475 vsync_lodd.shift_half_line = false; 476 477 if (mode->flags & DRM_MODE_FLAG_INTERLACE && 478 mode->flags & DRM_MODE_FLAG_3D_MASK) { 479 vsync_leven = vsync_lodd; 480 vsync_rodd = vsync_lodd; 481 vsync_reven = vsync_lodd; 482 vsync_leven.shift_half_line = true; 483 vsync_reven.shift_half_line = true; 484 } else if (mode->flags & DRM_MODE_FLAG_INTERLACE && 485 !(mode->flags & DRM_MODE_FLAG_3D_MASK)) { 486 vsync_leven = vsync_lodd; 487 vsync_leven.shift_half_line = true; 488 } else if (!(mode->flags & DRM_MODE_FLAG_INTERLACE) && 489 mode->flags & DRM_MODE_FLAG_3D_MASK) { 490 vsync_rodd = vsync_lodd; 491 } 492 mtk_dpi_sw_reset(dpi, true); 493 mtk_dpi_config_pol(dpi, &dpi_pol); 494 495 mtk_dpi_config_hsync(dpi, &hsync); 496 mtk_dpi_config_vsync_lodd(dpi, &vsync_lodd); 497 mtk_dpi_config_vsync_rodd(dpi, &vsync_rodd); 498 mtk_dpi_config_vsync_leven(dpi, &vsync_leven); 499 mtk_dpi_config_vsync_reven(dpi, &vsync_reven); 500 501 mtk_dpi_config_3d(dpi, !!(mode->flags & DRM_MODE_FLAG_3D_MASK)); 502 mtk_dpi_config_interface(dpi, !!(mode->flags & 503 DRM_MODE_FLAG_INTERLACE)); 504 if (mode->flags & DRM_MODE_FLAG_INTERLACE) 505 mtk_dpi_config_fb_size(dpi, mode->hdisplay, mode->vdisplay / 2); 506 else 507 mtk_dpi_config_fb_size(dpi, mode->hdisplay, mode->vdisplay); 508 509 mtk_dpi_config_channel_limit(dpi, &limit); 510 mtk_dpi_config_bit_num(dpi, dpi->bit_num); 511 mtk_dpi_config_channel_swap(dpi, dpi->channel_swap); 512 mtk_dpi_config_yc_map(dpi, dpi->yc_map); 513 mtk_dpi_config_color_format(dpi, dpi->color_format); 514 mtk_dpi_config_2n_h_fre(dpi); 515 mtk_dpi_sw_reset(dpi, false); 516 517 return 0; 518 } 519 520 static void mtk_dpi_encoder_destroy(struct drm_encoder *encoder) 521 { 522 drm_encoder_cleanup(encoder); 523 } 524 525 static const struct drm_encoder_funcs mtk_dpi_encoder_funcs = { 526 .destroy = mtk_dpi_encoder_destroy, 527 }; 528 529 static bool mtk_dpi_encoder_mode_fixup(struct drm_encoder *encoder, 530 const struct drm_display_mode *mode, 531 struct drm_display_mode *adjusted_mode) 532 { 533 return true; 534 } 535 536 static void mtk_dpi_encoder_mode_set(struct drm_encoder *encoder, 537 struct drm_display_mode *mode, 538 struct drm_display_mode *adjusted_mode) 539 { 540 struct mtk_dpi *dpi = mtk_dpi_from_encoder(encoder); 541 542 drm_mode_copy(&dpi->mode, adjusted_mode); 543 } 544 545 static void mtk_dpi_encoder_disable(struct drm_encoder *encoder) 546 { 547 struct mtk_dpi *dpi = mtk_dpi_from_encoder(encoder); 548 549 mtk_dpi_power_off(dpi, DPI_POWER_ENABLE); 550 } 551 552 static void mtk_dpi_encoder_enable(struct drm_encoder *encoder) 553 { 554 struct mtk_dpi *dpi = mtk_dpi_from_encoder(encoder); 555 556 mtk_dpi_power_on(dpi, DPI_POWER_ENABLE); 557 mtk_dpi_set_display_mode(dpi, &dpi->mode); 558 } 559 560 static int mtk_dpi_atomic_check(struct drm_encoder *encoder, 561 struct drm_crtc_state *crtc_state, 562 struct drm_connector_state *conn_state) 563 { 564 return 0; 565 } 566 567 static const struct drm_encoder_helper_funcs mtk_dpi_encoder_helper_funcs = { 568 .mode_fixup = mtk_dpi_encoder_mode_fixup, 569 .mode_set = mtk_dpi_encoder_mode_set, 570 .disable = mtk_dpi_encoder_disable, 571 .enable = mtk_dpi_encoder_enable, 572 .atomic_check = mtk_dpi_atomic_check, 573 }; 574 575 static void mtk_dpi_start(struct mtk_ddp_comp *comp) 576 { 577 struct mtk_dpi *dpi = container_of(comp, struct mtk_dpi, ddp_comp); 578 579 mtk_dpi_power_on(dpi, DPI_POWER_START); 580 } 581 582 static void mtk_dpi_stop(struct mtk_ddp_comp *comp) 583 { 584 struct mtk_dpi *dpi = container_of(comp, struct mtk_dpi, ddp_comp); 585 586 mtk_dpi_power_off(dpi, DPI_POWER_START); 587 } 588 589 static const struct mtk_ddp_comp_funcs mtk_dpi_funcs = { 590 .start = mtk_dpi_start, 591 .stop = mtk_dpi_stop, 592 }; 593 594 static int mtk_dpi_bind(struct device *dev, struct device *master, void *data) 595 { 596 struct mtk_dpi *dpi = dev_get_drvdata(dev); 597 struct drm_device *drm_dev = data; 598 int ret; 599 600 ret = mtk_ddp_comp_register(drm_dev, &dpi->ddp_comp); 601 if (ret < 0) { 602 dev_err(dev, "Failed to register component %s: %d\n", 603 dev->of_node->full_name, ret); 604 return ret; 605 } 606 607 ret = drm_encoder_init(drm_dev, &dpi->encoder, &mtk_dpi_encoder_funcs, 608 DRM_MODE_ENCODER_TMDS, NULL); 609 if (ret) { 610 dev_err(dev, "Failed to initialize decoder: %d\n", ret); 611 goto err_unregister; 612 } 613 drm_encoder_helper_add(&dpi->encoder, &mtk_dpi_encoder_helper_funcs); 614 615 /* Currently DPI0 is fixed to be driven by OVL1 */ 616 dpi->encoder.possible_crtcs = BIT(1); 617 618 dpi->encoder.bridge->encoder = &dpi->encoder; 619 ret = drm_bridge_attach(dpi->encoder.dev, dpi->encoder.bridge); 620 if (ret) { 621 dev_err(dev, "Failed to attach bridge: %d\n", ret); 622 goto err_cleanup; 623 } 624 625 dpi->bit_num = MTK_DPI_OUT_BIT_NUM_8BITS; 626 dpi->channel_swap = MTK_DPI_OUT_CHANNEL_SWAP_RGB; 627 dpi->yc_map = MTK_DPI_OUT_YC_MAP_RGB; 628 dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB; 629 630 return 0; 631 632 err_cleanup: 633 drm_encoder_cleanup(&dpi->encoder); 634 err_unregister: 635 mtk_ddp_comp_unregister(drm_dev, &dpi->ddp_comp); 636 return ret; 637 } 638 639 static void mtk_dpi_unbind(struct device *dev, struct device *master, 640 void *data) 641 { 642 struct mtk_dpi *dpi = dev_get_drvdata(dev); 643 struct drm_device *drm_dev = data; 644 645 drm_encoder_cleanup(&dpi->encoder); 646 mtk_ddp_comp_unregister(drm_dev, &dpi->ddp_comp); 647 } 648 649 static const struct component_ops mtk_dpi_component_ops = { 650 .bind = mtk_dpi_bind, 651 .unbind = mtk_dpi_unbind, 652 }; 653 654 static int mtk_dpi_probe(struct platform_device *pdev) 655 { 656 struct device *dev = &pdev->dev; 657 struct mtk_dpi *dpi; 658 struct resource *mem; 659 struct device_node *ep, *bridge_node = NULL; 660 int comp_id; 661 int ret; 662 663 dpi = devm_kzalloc(dev, sizeof(*dpi), GFP_KERNEL); 664 if (!dpi) 665 return -ENOMEM; 666 667 dpi->dev = dev; 668 669 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 670 dpi->regs = devm_ioremap_resource(dev, mem); 671 if (IS_ERR(dpi->regs)) { 672 ret = PTR_ERR(dpi->regs); 673 dev_err(dev, "Failed to ioremap mem resource: %d\n", ret); 674 return ret; 675 } 676 677 dpi->engine_clk = devm_clk_get(dev, "engine"); 678 if (IS_ERR(dpi->engine_clk)) { 679 ret = PTR_ERR(dpi->engine_clk); 680 dev_err(dev, "Failed to get engine clock: %d\n", ret); 681 return ret; 682 } 683 684 dpi->pixel_clk = devm_clk_get(dev, "pixel"); 685 if (IS_ERR(dpi->pixel_clk)) { 686 ret = PTR_ERR(dpi->pixel_clk); 687 dev_err(dev, "Failed to get pixel clock: %d\n", ret); 688 return ret; 689 } 690 691 dpi->tvd_clk = devm_clk_get(dev, "pll"); 692 if (IS_ERR(dpi->tvd_clk)) { 693 ret = PTR_ERR(dpi->tvd_clk); 694 dev_err(dev, "Failed to get tvdpll clock: %d\n", ret); 695 return ret; 696 } 697 698 dpi->irq = platform_get_irq(pdev, 0); 699 if (dpi->irq <= 0) { 700 dev_err(dev, "Failed to get irq: %d\n", dpi->irq); 701 return -EINVAL; 702 } 703 704 ep = of_graph_get_next_endpoint(dev->of_node, NULL); 705 if (ep) { 706 bridge_node = of_graph_get_remote_port_parent(ep); 707 of_node_put(ep); 708 } 709 if (!bridge_node) { 710 dev_err(dev, "Failed to find bridge node\n"); 711 return -ENODEV; 712 } 713 714 dev_info(dev, "Found bridge node: %s\n", bridge_node->full_name); 715 716 dpi->encoder.bridge = of_drm_find_bridge(bridge_node); 717 of_node_put(bridge_node); 718 if (!dpi->encoder.bridge) 719 return -EPROBE_DEFER; 720 721 comp_id = mtk_ddp_comp_get_id(dev->of_node, MTK_DPI); 722 if (comp_id < 0) { 723 dev_err(dev, "Failed to identify by alias: %d\n", comp_id); 724 return comp_id; 725 } 726 727 ret = mtk_ddp_comp_init(dev, dev->of_node, &dpi->ddp_comp, comp_id, 728 &mtk_dpi_funcs); 729 if (ret) { 730 dev_err(dev, "Failed to initialize component: %d\n", ret); 731 return ret; 732 } 733 734 platform_set_drvdata(pdev, dpi); 735 736 ret = component_add(dev, &mtk_dpi_component_ops); 737 if (ret) { 738 dev_err(dev, "Failed to add component: %d\n", ret); 739 return ret; 740 } 741 742 return 0; 743 } 744 745 static int mtk_dpi_remove(struct platform_device *pdev) 746 { 747 component_del(&pdev->dev, &mtk_dpi_component_ops); 748 749 return 0; 750 } 751 752 static const struct of_device_id mtk_dpi_of_ids[] = { 753 { .compatible = "mediatek,mt8173-dpi", }, 754 {} 755 }; 756 757 struct platform_driver mtk_dpi_driver = { 758 .probe = mtk_dpi_probe, 759 .remove = mtk_dpi_remove, 760 .driver = { 761 .name = "mediatek-dpi", 762 .of_match_table = mtk_dpi_of_ids, 763 }, 764 }; 765