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 /* let pll_rate can fix the valid range of tvdpll (1G~2GHz) */ 436 pix_rate = 1000UL * mode->clock; 437 if (mode->clock <= 27000) 438 factor = 16 * 3; 439 else if (mode->clock <= 84000) 440 factor = 8 * 3; 441 else if (mode->clock <= 167000) 442 factor = 4 * 3; 443 else 444 factor = 2 * 3; 445 pll_rate = pix_rate * factor; 446 447 dev_dbg(dpi->dev, "Want PLL %lu Hz, pixel clock %lu Hz\n", 448 pll_rate, pix_rate); 449 450 clk_set_rate(dpi->tvd_clk, pll_rate); 451 pll_rate = clk_get_rate(dpi->tvd_clk); 452 453 pix_rate = pll_rate / factor; 454 clk_set_rate(dpi->pixel_clk, pix_rate); 455 pix_rate = clk_get_rate(dpi->pixel_clk); 456 457 dev_dbg(dpi->dev, "Got PLL %lu Hz, pixel clock %lu Hz\n", 458 pll_rate, pix_rate); 459 460 limit.c_bottom = 0x0010; 461 limit.c_top = 0x0FE0; 462 limit.y_bottom = 0x0010; 463 limit.y_top = 0x0FE0; 464 465 dpi_pol.ck_pol = MTK_DPI_POLARITY_FALLING; 466 dpi_pol.de_pol = MTK_DPI_POLARITY_RISING; 467 dpi_pol.hsync_pol = mode->flags & DRM_MODE_FLAG_PHSYNC ? 468 MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING; 469 dpi_pol.vsync_pol = mode->flags & DRM_MODE_FLAG_PVSYNC ? 470 MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING; 471 472 hsync.sync_width = mode->hsync_end - mode->hsync_start; 473 hsync.back_porch = mode->htotal - mode->hsync_end; 474 hsync.front_porch = mode->hsync_start - mode->hdisplay; 475 hsync.shift_half_line = false; 476 477 vsync_lodd.sync_width = mode->vsync_end - mode->vsync_start; 478 vsync_lodd.back_porch = mode->vtotal - mode->vsync_end; 479 vsync_lodd.front_porch = mode->vsync_start - mode->vdisplay; 480 vsync_lodd.shift_half_line = false; 481 482 if (mode->flags & DRM_MODE_FLAG_INTERLACE && 483 mode->flags & DRM_MODE_FLAG_3D_MASK) { 484 vsync_leven = vsync_lodd; 485 vsync_rodd = vsync_lodd; 486 vsync_reven = vsync_lodd; 487 vsync_leven.shift_half_line = true; 488 vsync_reven.shift_half_line = true; 489 } else if (mode->flags & DRM_MODE_FLAG_INTERLACE && 490 !(mode->flags & DRM_MODE_FLAG_3D_MASK)) { 491 vsync_leven = vsync_lodd; 492 vsync_leven.shift_half_line = true; 493 } else if (!(mode->flags & DRM_MODE_FLAG_INTERLACE) && 494 mode->flags & DRM_MODE_FLAG_3D_MASK) { 495 vsync_rodd = vsync_lodd; 496 } 497 mtk_dpi_sw_reset(dpi, true); 498 mtk_dpi_config_pol(dpi, &dpi_pol); 499 500 mtk_dpi_config_hsync(dpi, &hsync); 501 mtk_dpi_config_vsync_lodd(dpi, &vsync_lodd); 502 mtk_dpi_config_vsync_rodd(dpi, &vsync_rodd); 503 mtk_dpi_config_vsync_leven(dpi, &vsync_leven); 504 mtk_dpi_config_vsync_reven(dpi, &vsync_reven); 505 506 mtk_dpi_config_3d(dpi, !!(mode->flags & DRM_MODE_FLAG_3D_MASK)); 507 mtk_dpi_config_interface(dpi, !!(mode->flags & 508 DRM_MODE_FLAG_INTERLACE)); 509 if (mode->flags & DRM_MODE_FLAG_INTERLACE) 510 mtk_dpi_config_fb_size(dpi, mode->hdisplay, mode->vdisplay / 2); 511 else 512 mtk_dpi_config_fb_size(dpi, mode->hdisplay, mode->vdisplay); 513 514 mtk_dpi_config_channel_limit(dpi, &limit); 515 mtk_dpi_config_bit_num(dpi, dpi->bit_num); 516 mtk_dpi_config_channel_swap(dpi, dpi->channel_swap); 517 mtk_dpi_config_yc_map(dpi, dpi->yc_map); 518 mtk_dpi_config_color_format(dpi, dpi->color_format); 519 mtk_dpi_config_2n_h_fre(dpi); 520 mtk_dpi_sw_reset(dpi, false); 521 522 return 0; 523 } 524 525 static void mtk_dpi_encoder_destroy(struct drm_encoder *encoder) 526 { 527 drm_encoder_cleanup(encoder); 528 } 529 530 static const struct drm_encoder_funcs mtk_dpi_encoder_funcs = { 531 .destroy = mtk_dpi_encoder_destroy, 532 }; 533 534 static bool mtk_dpi_encoder_mode_fixup(struct drm_encoder *encoder, 535 const struct drm_display_mode *mode, 536 struct drm_display_mode *adjusted_mode) 537 { 538 return true; 539 } 540 541 static void mtk_dpi_encoder_mode_set(struct drm_encoder *encoder, 542 struct drm_display_mode *mode, 543 struct drm_display_mode *adjusted_mode) 544 { 545 struct mtk_dpi *dpi = mtk_dpi_from_encoder(encoder); 546 547 drm_mode_copy(&dpi->mode, adjusted_mode); 548 } 549 550 static void mtk_dpi_encoder_disable(struct drm_encoder *encoder) 551 { 552 struct mtk_dpi *dpi = mtk_dpi_from_encoder(encoder); 553 554 mtk_dpi_power_off(dpi, DPI_POWER_ENABLE); 555 } 556 557 static void mtk_dpi_encoder_enable(struct drm_encoder *encoder) 558 { 559 struct mtk_dpi *dpi = mtk_dpi_from_encoder(encoder); 560 561 mtk_dpi_power_on(dpi, DPI_POWER_ENABLE); 562 mtk_dpi_set_display_mode(dpi, &dpi->mode); 563 } 564 565 static int mtk_dpi_atomic_check(struct drm_encoder *encoder, 566 struct drm_crtc_state *crtc_state, 567 struct drm_connector_state *conn_state) 568 { 569 return 0; 570 } 571 572 static const struct drm_encoder_helper_funcs mtk_dpi_encoder_helper_funcs = { 573 .mode_fixup = mtk_dpi_encoder_mode_fixup, 574 .mode_set = mtk_dpi_encoder_mode_set, 575 .disable = mtk_dpi_encoder_disable, 576 .enable = mtk_dpi_encoder_enable, 577 .atomic_check = mtk_dpi_atomic_check, 578 }; 579 580 static void mtk_dpi_start(struct mtk_ddp_comp *comp) 581 { 582 struct mtk_dpi *dpi = container_of(comp, struct mtk_dpi, ddp_comp); 583 584 mtk_dpi_power_on(dpi, DPI_POWER_START); 585 } 586 587 static void mtk_dpi_stop(struct mtk_ddp_comp *comp) 588 { 589 struct mtk_dpi *dpi = container_of(comp, struct mtk_dpi, ddp_comp); 590 591 mtk_dpi_power_off(dpi, DPI_POWER_START); 592 } 593 594 static const struct mtk_ddp_comp_funcs mtk_dpi_funcs = { 595 .start = mtk_dpi_start, 596 .stop = mtk_dpi_stop, 597 }; 598 599 static int mtk_dpi_bind(struct device *dev, struct device *master, void *data) 600 { 601 struct mtk_dpi *dpi = dev_get_drvdata(dev); 602 struct drm_device *drm_dev = data; 603 int ret; 604 605 ret = mtk_ddp_comp_register(drm_dev, &dpi->ddp_comp); 606 if (ret < 0) { 607 dev_err(dev, "Failed to register component %s: %d\n", 608 dev->of_node->full_name, ret); 609 return ret; 610 } 611 612 ret = drm_encoder_init(drm_dev, &dpi->encoder, &mtk_dpi_encoder_funcs, 613 DRM_MODE_ENCODER_TMDS, NULL); 614 if (ret) { 615 dev_err(dev, "Failed to initialize decoder: %d\n", ret); 616 goto err_unregister; 617 } 618 drm_encoder_helper_add(&dpi->encoder, &mtk_dpi_encoder_helper_funcs); 619 620 /* Currently DPI0 is fixed to be driven by OVL1 */ 621 dpi->encoder.possible_crtcs = BIT(1); 622 623 dpi->encoder.bridge->encoder = &dpi->encoder; 624 ret = drm_bridge_attach(dpi->encoder.dev, dpi->encoder.bridge); 625 if (ret) { 626 dev_err(dev, "Failed to attach bridge: %d\n", ret); 627 goto err_cleanup; 628 } 629 630 dpi->bit_num = MTK_DPI_OUT_BIT_NUM_8BITS; 631 dpi->channel_swap = MTK_DPI_OUT_CHANNEL_SWAP_RGB; 632 dpi->yc_map = MTK_DPI_OUT_YC_MAP_RGB; 633 dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB; 634 635 return 0; 636 637 err_cleanup: 638 drm_encoder_cleanup(&dpi->encoder); 639 err_unregister: 640 mtk_ddp_comp_unregister(drm_dev, &dpi->ddp_comp); 641 return ret; 642 } 643 644 static void mtk_dpi_unbind(struct device *dev, struct device *master, 645 void *data) 646 { 647 struct mtk_dpi *dpi = dev_get_drvdata(dev); 648 struct drm_device *drm_dev = data; 649 650 drm_encoder_cleanup(&dpi->encoder); 651 mtk_ddp_comp_unregister(drm_dev, &dpi->ddp_comp); 652 } 653 654 static const struct component_ops mtk_dpi_component_ops = { 655 .bind = mtk_dpi_bind, 656 .unbind = mtk_dpi_unbind, 657 }; 658 659 static int mtk_dpi_probe(struct platform_device *pdev) 660 { 661 struct device *dev = &pdev->dev; 662 struct mtk_dpi *dpi; 663 struct resource *mem; 664 struct device_node *ep, *bridge_node = NULL; 665 int comp_id; 666 int ret; 667 668 dpi = devm_kzalloc(dev, sizeof(*dpi), GFP_KERNEL); 669 if (!dpi) 670 return -ENOMEM; 671 672 dpi->dev = dev; 673 674 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 675 dpi->regs = devm_ioremap_resource(dev, mem); 676 if (IS_ERR(dpi->regs)) { 677 ret = PTR_ERR(dpi->regs); 678 dev_err(dev, "Failed to ioremap mem resource: %d\n", ret); 679 return ret; 680 } 681 682 dpi->engine_clk = devm_clk_get(dev, "engine"); 683 if (IS_ERR(dpi->engine_clk)) { 684 ret = PTR_ERR(dpi->engine_clk); 685 dev_err(dev, "Failed to get engine clock: %d\n", ret); 686 return ret; 687 } 688 689 dpi->pixel_clk = devm_clk_get(dev, "pixel"); 690 if (IS_ERR(dpi->pixel_clk)) { 691 ret = PTR_ERR(dpi->pixel_clk); 692 dev_err(dev, "Failed to get pixel clock: %d\n", ret); 693 return ret; 694 } 695 696 dpi->tvd_clk = devm_clk_get(dev, "pll"); 697 if (IS_ERR(dpi->tvd_clk)) { 698 ret = PTR_ERR(dpi->tvd_clk); 699 dev_err(dev, "Failed to get tvdpll clock: %d\n", ret); 700 return ret; 701 } 702 703 dpi->irq = platform_get_irq(pdev, 0); 704 if (dpi->irq <= 0) { 705 dev_err(dev, "Failed to get irq: %d\n", dpi->irq); 706 return -EINVAL; 707 } 708 709 ep = of_graph_get_next_endpoint(dev->of_node, NULL); 710 if (ep) { 711 bridge_node = of_graph_get_remote_port_parent(ep); 712 of_node_put(ep); 713 } 714 if (!bridge_node) { 715 dev_err(dev, "Failed to find bridge node\n"); 716 return -ENODEV; 717 } 718 719 dev_info(dev, "Found bridge node: %s\n", bridge_node->full_name); 720 721 dpi->encoder.bridge = of_drm_find_bridge(bridge_node); 722 of_node_put(bridge_node); 723 if (!dpi->encoder.bridge) 724 return -EPROBE_DEFER; 725 726 comp_id = mtk_ddp_comp_get_id(dev->of_node, MTK_DPI); 727 if (comp_id < 0) { 728 dev_err(dev, "Failed to identify by alias: %d\n", comp_id); 729 return comp_id; 730 } 731 732 ret = mtk_ddp_comp_init(dev, dev->of_node, &dpi->ddp_comp, comp_id, 733 &mtk_dpi_funcs); 734 if (ret) { 735 dev_err(dev, "Failed to initialize component: %d\n", ret); 736 return ret; 737 } 738 739 platform_set_drvdata(pdev, dpi); 740 741 ret = component_add(dev, &mtk_dpi_component_ops); 742 if (ret) { 743 dev_err(dev, "Failed to add component: %d\n", ret); 744 return ret; 745 } 746 747 return 0; 748 } 749 750 static int mtk_dpi_remove(struct platform_device *pdev) 751 { 752 component_del(&pdev->dev, &mtk_dpi_component_ops); 753 754 return 0; 755 } 756 757 static const struct of_device_id mtk_dpi_of_ids[] = { 758 { .compatible = "mediatek,mt8173-dpi", }, 759 {} 760 }; 761 762 struct platform_driver mtk_dpi_driver = { 763 .probe = mtk_dpi_probe, 764 .remove = mtk_dpi_remove, 765 .driver = { 766 .name = "mediatek-dpi", 767 .of_match_table = mtk_dpi_of_ids, 768 }, 769 }; 770