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 int mtk_dpi_bridge_attach(struct drm_bridge *bridge, 526 enum drm_bridge_attach_flags flags) 527 { 528 struct mtk_dpi *dpi = bridge_to_dpi(bridge); 529 530 return drm_bridge_attach(bridge->encoder, dpi->next_bridge, 531 &dpi->bridge, flags); 532 } 533 534 static void mtk_dpi_bridge_mode_set(struct drm_bridge *bridge, 535 const struct drm_display_mode *mode, 536 const struct drm_display_mode *adjusted_mode) 537 { 538 struct mtk_dpi *dpi = bridge_to_dpi(bridge); 539 540 drm_mode_copy(&dpi->mode, adjusted_mode); 541 } 542 543 static void mtk_dpi_bridge_disable(struct drm_bridge *bridge) 544 { 545 struct mtk_dpi *dpi = bridge_to_dpi(bridge); 546 547 mtk_dpi_power_off(dpi); 548 } 549 550 static void mtk_dpi_bridge_enable(struct drm_bridge *bridge) 551 { 552 struct mtk_dpi *dpi = bridge_to_dpi(bridge); 553 554 mtk_dpi_power_on(dpi); 555 mtk_dpi_set_display_mode(dpi, &dpi->mode); 556 } 557 558 static const struct drm_bridge_funcs mtk_dpi_bridge_funcs = { 559 .attach = mtk_dpi_bridge_attach, 560 .mode_set = mtk_dpi_bridge_mode_set, 561 .disable = mtk_dpi_bridge_disable, 562 .enable = mtk_dpi_bridge_enable, 563 }; 564 565 static void mtk_dpi_start(struct mtk_ddp_comp *comp) 566 { 567 struct mtk_dpi *dpi = container_of(comp, struct mtk_dpi, ddp_comp); 568 569 mtk_dpi_power_on(dpi); 570 } 571 572 static void mtk_dpi_stop(struct mtk_ddp_comp *comp) 573 { 574 struct mtk_dpi *dpi = container_of(comp, struct mtk_dpi, ddp_comp); 575 576 mtk_dpi_power_off(dpi); 577 } 578 579 static const struct mtk_ddp_comp_funcs mtk_dpi_funcs = { 580 .start = mtk_dpi_start, 581 .stop = mtk_dpi_stop, 582 }; 583 584 static int mtk_dpi_bind(struct device *dev, struct device *master, void *data) 585 { 586 struct mtk_dpi *dpi = dev_get_drvdata(dev); 587 struct drm_device *drm_dev = data; 588 int ret; 589 590 ret = mtk_ddp_comp_register(drm_dev, &dpi->ddp_comp); 591 if (ret < 0) { 592 dev_err(dev, "Failed to register component %pOF: %d\n", 593 dev->of_node, ret); 594 return ret; 595 } 596 597 ret = drm_simple_encoder_init(drm_dev, &dpi->encoder, 598 DRM_MODE_ENCODER_TMDS); 599 if (ret) { 600 dev_err(dev, "Failed to initialize decoder: %d\n", ret); 601 goto err_unregister; 602 } 603 604 dpi->encoder.possible_crtcs = mtk_drm_find_possible_crtc_by_comp(drm_dev, dpi->ddp_comp); 605 606 ret = drm_bridge_attach(&dpi->encoder, &dpi->bridge, NULL, 0); 607 if (ret) { 608 dev_err(dev, "Failed to attach bridge: %d\n", ret); 609 goto err_cleanup; 610 } 611 612 dpi->bit_num = MTK_DPI_OUT_BIT_NUM_8BITS; 613 dpi->channel_swap = MTK_DPI_OUT_CHANNEL_SWAP_RGB; 614 dpi->yc_map = MTK_DPI_OUT_YC_MAP_RGB; 615 dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB; 616 617 return 0; 618 619 err_cleanup: 620 drm_encoder_cleanup(&dpi->encoder); 621 err_unregister: 622 mtk_ddp_comp_unregister(drm_dev, &dpi->ddp_comp); 623 return ret; 624 } 625 626 static void mtk_dpi_unbind(struct device *dev, struct device *master, 627 void *data) 628 { 629 struct mtk_dpi *dpi = dev_get_drvdata(dev); 630 struct drm_device *drm_dev = data; 631 632 drm_encoder_cleanup(&dpi->encoder); 633 mtk_ddp_comp_unregister(drm_dev, &dpi->ddp_comp); 634 } 635 636 static const struct component_ops mtk_dpi_component_ops = { 637 .bind = mtk_dpi_bind, 638 .unbind = mtk_dpi_unbind, 639 }; 640 641 static unsigned int mt8173_calculate_factor(int clock) 642 { 643 if (clock <= 27000) 644 return 3 << 4; 645 else if (clock <= 84000) 646 return 3 << 3; 647 else if (clock <= 167000) 648 return 3 << 2; 649 else 650 return 3 << 1; 651 } 652 653 static unsigned int mt2701_calculate_factor(int clock) 654 { 655 if (clock <= 64000) 656 return 4; 657 else if (clock <= 128000) 658 return 2; 659 else 660 return 1; 661 } 662 663 static unsigned int mt8183_calculate_factor(int clock) 664 { 665 if (clock <= 27000) 666 return 8; 667 else if (clock <= 167000) 668 return 4; 669 else 670 return 2; 671 } 672 673 static const struct mtk_dpi_conf mt8173_conf = { 674 .cal_factor = mt8173_calculate_factor, 675 .reg_h_fre_con = 0xe0, 676 }; 677 678 static const struct mtk_dpi_conf mt2701_conf = { 679 .cal_factor = mt2701_calculate_factor, 680 .reg_h_fre_con = 0xb0, 681 .edge_sel_en = true, 682 }; 683 684 static const struct mtk_dpi_conf mt8183_conf = { 685 .cal_factor = mt8183_calculate_factor, 686 .reg_h_fre_con = 0xe0, 687 }; 688 689 static int mtk_dpi_probe(struct platform_device *pdev) 690 { 691 struct device *dev = &pdev->dev; 692 struct mtk_dpi *dpi; 693 struct resource *mem; 694 int comp_id; 695 int ret; 696 697 dpi = devm_kzalloc(dev, sizeof(*dpi), GFP_KERNEL); 698 if (!dpi) 699 return -ENOMEM; 700 701 dpi->dev = dev; 702 dpi->conf = (struct mtk_dpi_conf *)of_device_get_match_data(dev); 703 704 dpi->pinctrl = devm_pinctrl_get(&pdev->dev); 705 if (IS_ERR(dpi->pinctrl)) { 706 dpi->pinctrl = NULL; 707 dev_dbg(&pdev->dev, "Cannot find pinctrl!\n"); 708 } 709 if (dpi->pinctrl) { 710 dpi->pins_gpio = pinctrl_lookup_state(dpi->pinctrl, "sleep"); 711 if (IS_ERR(dpi->pins_gpio)) { 712 dpi->pins_gpio = NULL; 713 dev_dbg(&pdev->dev, "Cannot find pinctrl idle!\n"); 714 } 715 if (dpi->pins_gpio) 716 pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio); 717 718 dpi->pins_dpi = pinctrl_lookup_state(dpi->pinctrl, "default"); 719 if (IS_ERR(dpi->pins_dpi)) { 720 dpi->pins_dpi = NULL; 721 dev_dbg(&pdev->dev, "Cannot find pinctrl active!\n"); 722 } 723 } 724 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 725 dpi->regs = devm_ioremap_resource(dev, mem); 726 if (IS_ERR(dpi->regs)) { 727 ret = PTR_ERR(dpi->regs); 728 dev_err(dev, "Failed to ioremap mem resource: %d\n", ret); 729 return ret; 730 } 731 732 dpi->engine_clk = devm_clk_get(dev, "engine"); 733 if (IS_ERR(dpi->engine_clk)) { 734 ret = PTR_ERR(dpi->engine_clk); 735 if (ret != -EPROBE_DEFER) 736 dev_err(dev, "Failed to get engine clock: %d\n", ret); 737 738 return ret; 739 } 740 741 dpi->pixel_clk = devm_clk_get(dev, "pixel"); 742 if (IS_ERR(dpi->pixel_clk)) { 743 ret = PTR_ERR(dpi->pixel_clk); 744 if (ret != -EPROBE_DEFER) 745 dev_err(dev, "Failed to get pixel clock: %d\n", ret); 746 747 return ret; 748 } 749 750 dpi->tvd_clk = devm_clk_get(dev, "pll"); 751 if (IS_ERR(dpi->tvd_clk)) { 752 ret = PTR_ERR(dpi->tvd_clk); 753 if (ret != -EPROBE_DEFER) 754 dev_err(dev, "Failed to get tvdpll clock: %d\n", ret); 755 756 return ret; 757 } 758 759 dpi->irq = platform_get_irq(pdev, 0); 760 if (dpi->irq <= 0) { 761 dev_err(dev, "Failed to get irq: %d\n", dpi->irq); 762 return -EINVAL; 763 } 764 765 ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0, 766 NULL, &dpi->next_bridge); 767 if (ret) 768 return ret; 769 770 dev_info(dev, "Found bridge node: %pOF\n", dpi->next_bridge->of_node); 771 772 comp_id = mtk_ddp_comp_get_id(dev->of_node, MTK_DPI); 773 if (comp_id < 0) { 774 dev_err(dev, "Failed to identify by alias: %d\n", comp_id); 775 return comp_id; 776 } 777 778 ret = mtk_ddp_comp_init(dev, dev->of_node, &dpi->ddp_comp, comp_id, 779 &mtk_dpi_funcs); 780 if (ret) { 781 dev_err(dev, "Failed to initialize component: %d\n", ret); 782 return ret; 783 } 784 785 platform_set_drvdata(pdev, dpi); 786 787 dpi->bridge.funcs = &mtk_dpi_bridge_funcs; 788 dpi->bridge.of_node = dev->of_node; 789 dpi->bridge.type = DRM_MODE_CONNECTOR_DPI; 790 791 drm_bridge_add(&dpi->bridge); 792 793 ret = component_add(dev, &mtk_dpi_component_ops); 794 if (ret) { 795 drm_bridge_remove(&dpi->bridge); 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 struct mtk_dpi *dpi = platform_get_drvdata(pdev); 806 807 component_del(&pdev->dev, &mtk_dpi_component_ops); 808 drm_bridge_remove(&dpi->bridge); 809 810 return 0; 811 } 812 813 static const struct of_device_id mtk_dpi_of_ids[] = { 814 { .compatible = "mediatek,mt2701-dpi", 815 .data = &mt2701_conf, 816 }, 817 { .compatible = "mediatek,mt8173-dpi", 818 .data = &mt8173_conf, 819 }, 820 { .compatible = "mediatek,mt8183-dpi", 821 .data = &mt8183_conf, 822 }, 823 { }, 824 }; 825 826 struct platform_driver mtk_dpi_driver = { 827 .probe = mtk_dpi_probe, 828 .remove = mtk_dpi_remove, 829 .driver = { 830 .name = "mediatek-dpi", 831 .of_match_table = mtk_dpi_of_ids, 832 }, 833 }; 834