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