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