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