1 /* 2 * Copyright (C) 2015 Free Electrons 3 * Copyright (C) 2015 NextThing Co 4 * 5 * Maxime Ripard <maxime.ripard@free-electrons.com> 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License as 9 * published by the Free Software Foundation; either version 2 of 10 * the License, or (at your option) any later version. 11 */ 12 13 #include <drm/drmP.h> 14 #include <drm/drm_atomic_helper.h> 15 #include <drm/drm_crtc.h> 16 #include <drm/drm_crtc_helper.h> 17 #include <drm/drm_encoder.h> 18 #include <drm/drm_modes.h> 19 #include <drm/drm_of.h> 20 21 #include <uapi/drm/drm_mode.h> 22 23 #include <linux/component.h> 24 #include <linux/ioport.h> 25 #include <linux/of_address.h> 26 #include <linux/of_device.h> 27 #include <linux/of_irq.h> 28 #include <linux/regmap.h> 29 #include <linux/reset.h> 30 31 #include "sun4i_crtc.h" 32 #include "sun4i_dotclock.h" 33 #include "sun4i_drv.h" 34 #include "sun4i_lvds.h" 35 #include "sun4i_rgb.h" 36 #include "sun4i_tcon.h" 37 #include "sun6i_mipi_dsi.h" 38 #include "sunxi_engine.h" 39 40 static struct drm_connector *sun4i_tcon_get_connector(const struct drm_encoder *encoder) 41 { 42 struct drm_connector *connector; 43 struct drm_connector_list_iter iter; 44 45 drm_connector_list_iter_begin(encoder->dev, &iter); 46 drm_for_each_connector_iter(connector, &iter) 47 if (connector->encoder == encoder) { 48 drm_connector_list_iter_end(&iter); 49 return connector; 50 } 51 drm_connector_list_iter_end(&iter); 52 53 return NULL; 54 } 55 56 static int sun4i_tcon_get_pixel_depth(const struct drm_encoder *encoder) 57 { 58 struct drm_connector *connector; 59 struct drm_display_info *info; 60 61 connector = sun4i_tcon_get_connector(encoder); 62 if (!connector) 63 return -EINVAL; 64 65 info = &connector->display_info; 66 if (info->num_bus_formats != 1) 67 return -EINVAL; 68 69 switch (info->bus_formats[0]) { 70 case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: 71 return 18; 72 73 case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA: 74 case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG: 75 return 24; 76 } 77 78 return -EINVAL; 79 } 80 81 static void sun4i_tcon_channel_set_status(struct sun4i_tcon *tcon, int channel, 82 bool enabled) 83 { 84 struct clk *clk; 85 86 switch (channel) { 87 case 0: 88 WARN_ON(!tcon->quirks->has_channel_0); 89 regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG, 90 SUN4I_TCON0_CTL_TCON_ENABLE, 91 enabled ? SUN4I_TCON0_CTL_TCON_ENABLE : 0); 92 clk = tcon->dclk; 93 break; 94 case 1: 95 WARN_ON(!tcon->quirks->has_channel_1); 96 regmap_update_bits(tcon->regs, SUN4I_TCON1_CTL_REG, 97 SUN4I_TCON1_CTL_TCON_ENABLE, 98 enabled ? SUN4I_TCON1_CTL_TCON_ENABLE : 0); 99 clk = tcon->sclk1; 100 break; 101 default: 102 DRM_WARN("Unknown channel... doing nothing\n"); 103 return; 104 } 105 106 if (enabled) { 107 clk_prepare_enable(clk); 108 clk_rate_exclusive_get(clk); 109 } else { 110 clk_rate_exclusive_put(clk); 111 clk_disable_unprepare(clk); 112 } 113 } 114 115 static void sun4i_tcon_lvds_set_status(struct sun4i_tcon *tcon, 116 const struct drm_encoder *encoder, 117 bool enabled) 118 { 119 if (enabled) { 120 u8 val; 121 122 regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_IF_REG, 123 SUN4I_TCON0_LVDS_IF_EN, 124 SUN4I_TCON0_LVDS_IF_EN); 125 126 /* 127 * As their name suggest, these values only apply to the A31 128 * and later SoCs. We'll have to rework this when merging 129 * support for the older SoCs. 130 */ 131 regmap_write(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG, 132 SUN6I_TCON0_LVDS_ANA0_C(2) | 133 SUN6I_TCON0_LVDS_ANA0_V(3) | 134 SUN6I_TCON0_LVDS_ANA0_PD(2) | 135 SUN6I_TCON0_LVDS_ANA0_EN_LDO); 136 udelay(2); 137 138 regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG, 139 SUN6I_TCON0_LVDS_ANA0_EN_MB, 140 SUN6I_TCON0_LVDS_ANA0_EN_MB); 141 udelay(2); 142 143 regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG, 144 SUN6I_TCON0_LVDS_ANA0_EN_DRVC, 145 SUN6I_TCON0_LVDS_ANA0_EN_DRVC); 146 147 if (sun4i_tcon_get_pixel_depth(encoder) == 18) 148 val = 7; 149 else 150 val = 0xf; 151 152 regmap_write_bits(tcon->regs, SUN4I_TCON0_LVDS_ANA0_REG, 153 SUN6I_TCON0_LVDS_ANA0_EN_DRVD(0xf), 154 SUN6I_TCON0_LVDS_ANA0_EN_DRVD(val)); 155 } else { 156 regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_IF_REG, 157 SUN4I_TCON0_LVDS_IF_EN, 0); 158 } 159 } 160 161 void sun4i_tcon_set_status(struct sun4i_tcon *tcon, 162 const struct drm_encoder *encoder, 163 bool enabled) 164 { 165 bool is_lvds = false; 166 int channel; 167 168 switch (encoder->encoder_type) { 169 case DRM_MODE_ENCODER_LVDS: 170 is_lvds = true; 171 /* Fallthrough */ 172 case DRM_MODE_ENCODER_DSI: 173 case DRM_MODE_ENCODER_NONE: 174 channel = 0; 175 break; 176 case DRM_MODE_ENCODER_TMDS: 177 case DRM_MODE_ENCODER_TVDAC: 178 channel = 1; 179 break; 180 default: 181 DRM_DEBUG_DRIVER("Unknown encoder type, doing nothing...\n"); 182 return; 183 } 184 185 if (is_lvds && !enabled) 186 sun4i_tcon_lvds_set_status(tcon, encoder, false); 187 188 regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG, 189 SUN4I_TCON_GCTL_TCON_ENABLE, 190 enabled ? SUN4I_TCON_GCTL_TCON_ENABLE : 0); 191 192 if (is_lvds && enabled) 193 sun4i_tcon_lvds_set_status(tcon, encoder, true); 194 195 sun4i_tcon_channel_set_status(tcon, channel, enabled); 196 } 197 198 void sun4i_tcon_enable_vblank(struct sun4i_tcon *tcon, bool enable) 199 { 200 u32 mask, val = 0; 201 202 DRM_DEBUG_DRIVER("%sabling VBLANK interrupt\n", enable ? "En" : "Dis"); 203 204 mask = SUN4I_TCON_GINT0_VBLANK_ENABLE(0) | 205 SUN4I_TCON_GINT0_VBLANK_ENABLE(1) | 206 SUN4I_TCON_GINT0_TCON0_TRI_FINISH_ENABLE; 207 208 if (enable) 209 val = mask; 210 211 regmap_update_bits(tcon->regs, SUN4I_TCON_GINT0_REG, mask, val); 212 } 213 EXPORT_SYMBOL(sun4i_tcon_enable_vblank); 214 215 /* 216 * This function is a helper for TCON output muxing. The TCON output 217 * muxing control register in earlier SoCs (without the TCON TOP block) 218 * are located in TCON0. This helper returns a pointer to TCON0's 219 * sun4i_tcon structure, or NULL if not found. 220 */ 221 static struct sun4i_tcon *sun4i_get_tcon0(struct drm_device *drm) 222 { 223 struct sun4i_drv *drv = drm->dev_private; 224 struct sun4i_tcon *tcon; 225 226 list_for_each_entry(tcon, &drv->tcon_list, list) 227 if (tcon->id == 0) 228 return tcon; 229 230 dev_warn(drm->dev, 231 "TCON0 not found, display output muxing may not work\n"); 232 233 return NULL; 234 } 235 236 void sun4i_tcon_set_mux(struct sun4i_tcon *tcon, int channel, 237 const struct drm_encoder *encoder) 238 { 239 int ret = -ENOTSUPP; 240 241 if (tcon->quirks->set_mux) 242 ret = tcon->quirks->set_mux(tcon, encoder); 243 244 DRM_DEBUG_DRIVER("Muxing encoder %s to CRTC %s: %d\n", 245 encoder->name, encoder->crtc->name, ret); 246 } 247 248 static int sun4i_tcon_get_clk_delay(const struct drm_display_mode *mode, 249 int channel) 250 { 251 int delay = mode->vtotal - mode->vdisplay; 252 253 if (mode->flags & DRM_MODE_FLAG_INTERLACE) 254 delay /= 2; 255 256 if (channel == 1) 257 delay -= 2; 258 259 delay = min(delay, 30); 260 261 DRM_DEBUG_DRIVER("TCON %d clock delay %u\n", channel, delay); 262 263 return delay; 264 } 265 266 static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon, 267 const struct drm_display_mode *mode) 268 { 269 /* Configure the dot clock */ 270 clk_set_rate(tcon->dclk, mode->crtc_clock * 1000); 271 272 /* Set the resolution */ 273 regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG, 274 SUN4I_TCON0_BASIC0_X(mode->crtc_hdisplay) | 275 SUN4I_TCON0_BASIC0_Y(mode->crtc_vdisplay)); 276 } 277 278 static void sun4i_tcon0_mode_set_cpu(struct sun4i_tcon *tcon, 279 struct mipi_dsi_device *device, 280 const struct drm_display_mode *mode) 281 { 282 u8 bpp = mipi_dsi_pixel_format_to_bpp(device->format); 283 u8 lanes = device->lanes; 284 u32 block_space, start_delay; 285 u32 tcon_div; 286 287 tcon->dclk_min_div = 4; 288 tcon->dclk_max_div = 127; 289 290 sun4i_tcon0_mode_set_common(tcon, mode); 291 292 regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG, 293 SUN4I_TCON0_CTL_IF_MASK, 294 SUN4I_TCON0_CTL_IF_8080); 295 296 regmap_write(tcon->regs, SUN4I_TCON_ECC_FIFO_REG, 297 SUN4I_TCON_ECC_FIFO_EN); 298 299 regmap_write(tcon->regs, SUN4I_TCON0_CPU_IF_REG, 300 SUN4I_TCON0_CPU_IF_MODE_DSI | 301 SUN4I_TCON0_CPU_IF_TRI_FIFO_FLUSH | 302 SUN4I_TCON0_CPU_IF_TRI_FIFO_EN | 303 SUN4I_TCON0_CPU_IF_TRI_EN); 304 305 /* 306 * This looks suspicious, but it works... 307 * 308 * The datasheet says that this should be set higher than 20 * 309 * pixel cycle, but it's not clear what a pixel cycle is. 310 */ 311 regmap_read(tcon->regs, SUN4I_TCON0_DCLK_REG, &tcon_div); 312 tcon_div &= GENMASK(6, 0); 313 block_space = mode->htotal * bpp / (tcon_div * lanes); 314 block_space -= mode->hdisplay + 40; 315 316 regmap_write(tcon->regs, SUN4I_TCON0_CPU_TRI0_REG, 317 SUN4I_TCON0_CPU_TRI0_BLOCK_SPACE(block_space) | 318 SUN4I_TCON0_CPU_TRI0_BLOCK_SIZE(mode->hdisplay)); 319 320 regmap_write(tcon->regs, SUN4I_TCON0_CPU_TRI1_REG, 321 SUN4I_TCON0_CPU_TRI1_BLOCK_NUM(mode->vdisplay)); 322 323 start_delay = (mode->crtc_vtotal - mode->crtc_vdisplay - 10 - 1); 324 start_delay = start_delay * mode->crtc_htotal * 149; 325 start_delay = start_delay / (mode->crtc_clock / 1000) / 8; 326 regmap_write(tcon->regs, SUN4I_TCON0_CPU_TRI2_REG, 327 SUN4I_TCON0_CPU_TRI2_TRANS_START_SET(10) | 328 SUN4I_TCON0_CPU_TRI2_START_DELAY(start_delay)); 329 330 /* 331 * The Allwinner BSP has a comment that the period should be 332 * the display clock * 15, but uses an hardcoded 3000... 333 */ 334 regmap_write(tcon->regs, SUN4I_TCON_SAFE_PERIOD_REG, 335 SUN4I_TCON_SAFE_PERIOD_NUM(3000) | 336 SUN4I_TCON_SAFE_PERIOD_MODE(3)); 337 338 /* Enable the output on the pins */ 339 regmap_write(tcon->regs, SUN4I_TCON0_IO_TRI_REG, 340 0xe0000000); 341 } 342 343 static void sun4i_tcon0_mode_set_lvds(struct sun4i_tcon *tcon, 344 const struct drm_encoder *encoder, 345 const struct drm_display_mode *mode) 346 { 347 unsigned int bp; 348 u8 clk_delay; 349 u32 reg, val = 0; 350 351 WARN_ON(!tcon->quirks->has_channel_0); 352 353 tcon->dclk_min_div = 7; 354 tcon->dclk_max_div = 7; 355 sun4i_tcon0_mode_set_common(tcon, mode); 356 357 /* Adjust clock delay */ 358 clk_delay = sun4i_tcon_get_clk_delay(mode, 0); 359 regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG, 360 SUN4I_TCON0_CTL_CLK_DELAY_MASK, 361 SUN4I_TCON0_CTL_CLK_DELAY(clk_delay)); 362 363 /* 364 * This is called a backporch in the register documentation, 365 * but it really is the back porch + hsync 366 */ 367 bp = mode->crtc_htotal - mode->crtc_hsync_start; 368 DRM_DEBUG_DRIVER("Setting horizontal total %d, backporch %d\n", 369 mode->crtc_htotal, bp); 370 371 /* Set horizontal display timings */ 372 regmap_write(tcon->regs, SUN4I_TCON0_BASIC1_REG, 373 SUN4I_TCON0_BASIC1_H_TOTAL(mode->htotal) | 374 SUN4I_TCON0_BASIC1_H_BACKPORCH(bp)); 375 376 /* 377 * This is called a backporch in the register documentation, 378 * but it really is the back porch + hsync 379 */ 380 bp = mode->crtc_vtotal - mode->crtc_vsync_start; 381 DRM_DEBUG_DRIVER("Setting vertical total %d, backporch %d\n", 382 mode->crtc_vtotal, bp); 383 384 /* Set vertical display timings */ 385 regmap_write(tcon->regs, SUN4I_TCON0_BASIC2_REG, 386 SUN4I_TCON0_BASIC2_V_TOTAL(mode->crtc_vtotal * 2) | 387 SUN4I_TCON0_BASIC2_V_BACKPORCH(bp)); 388 389 reg = SUN4I_TCON0_LVDS_IF_CLK_SEL_TCON0 | 390 SUN4I_TCON0_LVDS_IF_DATA_POL_NORMAL | 391 SUN4I_TCON0_LVDS_IF_CLK_POL_NORMAL; 392 if (sun4i_tcon_get_pixel_depth(encoder) == 24) 393 reg |= SUN4I_TCON0_LVDS_IF_BITWIDTH_24BITS; 394 else 395 reg |= SUN4I_TCON0_LVDS_IF_BITWIDTH_18BITS; 396 397 regmap_write(tcon->regs, SUN4I_TCON0_LVDS_IF_REG, reg); 398 399 /* Setup the polarity of the various signals */ 400 if (!(mode->flags & DRM_MODE_FLAG_PHSYNC)) 401 val |= SUN4I_TCON0_IO_POL_HSYNC_POSITIVE; 402 403 if (!(mode->flags & DRM_MODE_FLAG_PVSYNC)) 404 val |= SUN4I_TCON0_IO_POL_VSYNC_POSITIVE; 405 406 regmap_write(tcon->regs, SUN4I_TCON0_IO_POL_REG, val); 407 408 /* Map output pins to channel 0 */ 409 regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG, 410 SUN4I_TCON_GCTL_IOMAP_MASK, 411 SUN4I_TCON_GCTL_IOMAP_TCON0); 412 413 /* Enable the output on the pins */ 414 regmap_write(tcon->regs, SUN4I_TCON0_IO_TRI_REG, 0xe0000000); 415 } 416 417 static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon, 418 const struct drm_display_mode *mode) 419 { 420 unsigned int bp, hsync, vsync; 421 u8 clk_delay; 422 u32 val = 0; 423 424 WARN_ON(!tcon->quirks->has_channel_0); 425 426 tcon->dclk_min_div = 6; 427 tcon->dclk_max_div = 127; 428 sun4i_tcon0_mode_set_common(tcon, mode); 429 430 /* Adjust clock delay */ 431 clk_delay = sun4i_tcon_get_clk_delay(mode, 0); 432 regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG, 433 SUN4I_TCON0_CTL_CLK_DELAY_MASK, 434 SUN4I_TCON0_CTL_CLK_DELAY(clk_delay)); 435 436 /* 437 * This is called a backporch in the register documentation, 438 * but it really is the back porch + hsync 439 */ 440 bp = mode->crtc_htotal - mode->crtc_hsync_start; 441 DRM_DEBUG_DRIVER("Setting horizontal total %d, backporch %d\n", 442 mode->crtc_htotal, bp); 443 444 /* Set horizontal display timings */ 445 regmap_write(tcon->regs, SUN4I_TCON0_BASIC1_REG, 446 SUN4I_TCON0_BASIC1_H_TOTAL(mode->crtc_htotal) | 447 SUN4I_TCON0_BASIC1_H_BACKPORCH(bp)); 448 449 /* 450 * This is called a backporch in the register documentation, 451 * but it really is the back porch + hsync 452 */ 453 bp = mode->crtc_vtotal - mode->crtc_vsync_start; 454 DRM_DEBUG_DRIVER("Setting vertical total %d, backporch %d\n", 455 mode->crtc_vtotal, bp); 456 457 /* Set vertical display timings */ 458 regmap_write(tcon->regs, SUN4I_TCON0_BASIC2_REG, 459 SUN4I_TCON0_BASIC2_V_TOTAL(mode->crtc_vtotal * 2) | 460 SUN4I_TCON0_BASIC2_V_BACKPORCH(bp)); 461 462 /* Set Hsync and Vsync length */ 463 hsync = mode->crtc_hsync_end - mode->crtc_hsync_start; 464 vsync = mode->crtc_vsync_end - mode->crtc_vsync_start; 465 DRM_DEBUG_DRIVER("Setting HSYNC %d, VSYNC %d\n", hsync, vsync); 466 regmap_write(tcon->regs, SUN4I_TCON0_BASIC3_REG, 467 SUN4I_TCON0_BASIC3_V_SYNC(vsync) | 468 SUN4I_TCON0_BASIC3_H_SYNC(hsync)); 469 470 /* Setup the polarity of the various signals */ 471 if (mode->flags & DRM_MODE_FLAG_PHSYNC) 472 val |= SUN4I_TCON0_IO_POL_HSYNC_POSITIVE; 473 474 if (mode->flags & DRM_MODE_FLAG_PVSYNC) 475 val |= SUN4I_TCON0_IO_POL_VSYNC_POSITIVE; 476 477 regmap_update_bits(tcon->regs, SUN4I_TCON0_IO_POL_REG, 478 SUN4I_TCON0_IO_POL_HSYNC_POSITIVE | SUN4I_TCON0_IO_POL_VSYNC_POSITIVE, 479 val); 480 481 /* Map output pins to channel 0 */ 482 regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG, 483 SUN4I_TCON_GCTL_IOMAP_MASK, 484 SUN4I_TCON_GCTL_IOMAP_TCON0); 485 486 /* Enable the output on the pins */ 487 regmap_write(tcon->regs, SUN4I_TCON0_IO_TRI_REG, 0); 488 } 489 490 static void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon, 491 const struct drm_display_mode *mode) 492 { 493 unsigned int bp, hsync, vsync, vtotal; 494 u8 clk_delay; 495 u32 val; 496 497 WARN_ON(!tcon->quirks->has_channel_1); 498 499 /* Configure the dot clock */ 500 clk_set_rate(tcon->sclk1, mode->crtc_clock * 1000); 501 502 /* Adjust clock delay */ 503 clk_delay = sun4i_tcon_get_clk_delay(mode, 1); 504 regmap_update_bits(tcon->regs, SUN4I_TCON1_CTL_REG, 505 SUN4I_TCON1_CTL_CLK_DELAY_MASK, 506 SUN4I_TCON1_CTL_CLK_DELAY(clk_delay)); 507 508 /* Set interlaced mode */ 509 if (mode->flags & DRM_MODE_FLAG_INTERLACE) 510 val = SUN4I_TCON1_CTL_INTERLACE_ENABLE; 511 else 512 val = 0; 513 regmap_update_bits(tcon->regs, SUN4I_TCON1_CTL_REG, 514 SUN4I_TCON1_CTL_INTERLACE_ENABLE, 515 val); 516 517 /* Set the input resolution */ 518 regmap_write(tcon->regs, SUN4I_TCON1_BASIC0_REG, 519 SUN4I_TCON1_BASIC0_X(mode->crtc_hdisplay) | 520 SUN4I_TCON1_BASIC0_Y(mode->crtc_vdisplay)); 521 522 /* Set the upscaling resolution */ 523 regmap_write(tcon->regs, SUN4I_TCON1_BASIC1_REG, 524 SUN4I_TCON1_BASIC1_X(mode->crtc_hdisplay) | 525 SUN4I_TCON1_BASIC1_Y(mode->crtc_vdisplay)); 526 527 /* Set the output resolution */ 528 regmap_write(tcon->regs, SUN4I_TCON1_BASIC2_REG, 529 SUN4I_TCON1_BASIC2_X(mode->crtc_hdisplay) | 530 SUN4I_TCON1_BASIC2_Y(mode->crtc_vdisplay)); 531 532 /* Set horizontal display timings */ 533 bp = mode->crtc_htotal - mode->crtc_hsync_start; 534 DRM_DEBUG_DRIVER("Setting horizontal total %d, backporch %d\n", 535 mode->htotal, bp); 536 regmap_write(tcon->regs, SUN4I_TCON1_BASIC3_REG, 537 SUN4I_TCON1_BASIC3_H_TOTAL(mode->crtc_htotal) | 538 SUN4I_TCON1_BASIC3_H_BACKPORCH(bp)); 539 540 bp = mode->crtc_vtotal - mode->crtc_vsync_start; 541 DRM_DEBUG_DRIVER("Setting vertical total %d, backporch %d\n", 542 mode->crtc_vtotal, bp); 543 544 /* 545 * The vertical resolution needs to be doubled in all 546 * cases. We could use crtc_vtotal and always multiply by two, 547 * but that leads to a rounding error in interlace when vtotal 548 * is odd. 549 * 550 * This happens with TV's PAL for example, where vtotal will 551 * be 625, crtc_vtotal 312, and thus crtc_vtotal * 2 will be 552 * 624, which apparently confuses the hardware. 553 * 554 * To work around this, we will always use vtotal, and 555 * multiply by two only if we're not in interlace. 556 */ 557 vtotal = mode->vtotal; 558 if (!(mode->flags & DRM_MODE_FLAG_INTERLACE)) 559 vtotal = vtotal * 2; 560 561 /* Set vertical display timings */ 562 regmap_write(tcon->regs, SUN4I_TCON1_BASIC4_REG, 563 SUN4I_TCON1_BASIC4_V_TOTAL(vtotal) | 564 SUN4I_TCON1_BASIC4_V_BACKPORCH(bp)); 565 566 /* Set Hsync and Vsync length */ 567 hsync = mode->crtc_hsync_end - mode->crtc_hsync_start; 568 vsync = mode->crtc_vsync_end - mode->crtc_vsync_start; 569 DRM_DEBUG_DRIVER("Setting HSYNC %d, VSYNC %d\n", hsync, vsync); 570 regmap_write(tcon->regs, SUN4I_TCON1_BASIC5_REG, 571 SUN4I_TCON1_BASIC5_V_SYNC(vsync) | 572 SUN4I_TCON1_BASIC5_H_SYNC(hsync)); 573 574 /* Map output pins to channel 1 */ 575 regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG, 576 SUN4I_TCON_GCTL_IOMAP_MASK, 577 SUN4I_TCON_GCTL_IOMAP_TCON1); 578 } 579 580 void sun4i_tcon_mode_set(struct sun4i_tcon *tcon, 581 const struct drm_encoder *encoder, 582 const struct drm_display_mode *mode) 583 { 584 struct sun6i_dsi *dsi; 585 586 switch (encoder->encoder_type) { 587 case DRM_MODE_ENCODER_DSI: 588 /* 589 * This is not really elegant, but it's the "cleaner" 590 * way I could think of... 591 */ 592 dsi = encoder_to_sun6i_dsi(encoder); 593 sun4i_tcon0_mode_set_cpu(tcon, dsi->device, mode); 594 break; 595 case DRM_MODE_ENCODER_LVDS: 596 sun4i_tcon0_mode_set_lvds(tcon, encoder, mode); 597 break; 598 case DRM_MODE_ENCODER_NONE: 599 sun4i_tcon0_mode_set_rgb(tcon, mode); 600 sun4i_tcon_set_mux(tcon, 0, encoder); 601 break; 602 case DRM_MODE_ENCODER_TVDAC: 603 case DRM_MODE_ENCODER_TMDS: 604 sun4i_tcon1_mode_set(tcon, mode); 605 sun4i_tcon_set_mux(tcon, 1, encoder); 606 break; 607 default: 608 DRM_DEBUG_DRIVER("Unknown encoder type, doing nothing...\n"); 609 } 610 } 611 EXPORT_SYMBOL(sun4i_tcon_mode_set); 612 613 static void sun4i_tcon_finish_page_flip(struct drm_device *dev, 614 struct sun4i_crtc *scrtc) 615 { 616 unsigned long flags; 617 618 spin_lock_irqsave(&dev->event_lock, flags); 619 if (scrtc->event) { 620 drm_crtc_send_vblank_event(&scrtc->crtc, scrtc->event); 621 drm_crtc_vblank_put(&scrtc->crtc); 622 scrtc->event = NULL; 623 } 624 spin_unlock_irqrestore(&dev->event_lock, flags); 625 } 626 627 static irqreturn_t sun4i_tcon_handler(int irq, void *private) 628 { 629 struct sun4i_tcon *tcon = private; 630 struct drm_device *drm = tcon->drm; 631 struct sun4i_crtc *scrtc = tcon->crtc; 632 struct sunxi_engine *engine = scrtc->engine; 633 unsigned int status; 634 635 regmap_read(tcon->regs, SUN4I_TCON_GINT0_REG, &status); 636 637 if (!(status & (SUN4I_TCON_GINT0_VBLANK_INT(0) | 638 SUN4I_TCON_GINT0_VBLANK_INT(1) | 639 SUN4I_TCON_GINT0_TCON0_TRI_FINISH_INT))) 640 return IRQ_NONE; 641 642 drm_crtc_handle_vblank(&scrtc->crtc); 643 sun4i_tcon_finish_page_flip(drm, scrtc); 644 645 /* Acknowledge the interrupt */ 646 regmap_update_bits(tcon->regs, SUN4I_TCON_GINT0_REG, 647 SUN4I_TCON_GINT0_VBLANK_INT(0) | 648 SUN4I_TCON_GINT0_VBLANK_INT(1) | 649 SUN4I_TCON_GINT0_TCON0_TRI_FINISH_INT, 650 0); 651 652 if (engine->ops->vblank_quirk) 653 engine->ops->vblank_quirk(engine); 654 655 return IRQ_HANDLED; 656 } 657 658 static int sun4i_tcon_init_clocks(struct device *dev, 659 struct sun4i_tcon *tcon) 660 { 661 tcon->clk = devm_clk_get(dev, "ahb"); 662 if (IS_ERR(tcon->clk)) { 663 dev_err(dev, "Couldn't get the TCON bus clock\n"); 664 return PTR_ERR(tcon->clk); 665 } 666 clk_prepare_enable(tcon->clk); 667 668 if (tcon->quirks->has_channel_0) { 669 tcon->sclk0 = devm_clk_get(dev, "tcon-ch0"); 670 if (IS_ERR(tcon->sclk0)) { 671 dev_err(dev, "Couldn't get the TCON channel 0 clock\n"); 672 return PTR_ERR(tcon->sclk0); 673 } 674 } 675 676 if (tcon->quirks->has_channel_1) { 677 tcon->sclk1 = devm_clk_get(dev, "tcon-ch1"); 678 if (IS_ERR(tcon->sclk1)) { 679 dev_err(dev, "Couldn't get the TCON channel 1 clock\n"); 680 return PTR_ERR(tcon->sclk1); 681 } 682 } 683 684 return 0; 685 } 686 687 static void sun4i_tcon_free_clocks(struct sun4i_tcon *tcon) 688 { 689 clk_disable_unprepare(tcon->clk); 690 } 691 692 static int sun4i_tcon_init_irq(struct device *dev, 693 struct sun4i_tcon *tcon) 694 { 695 struct platform_device *pdev = to_platform_device(dev); 696 int irq, ret; 697 698 irq = platform_get_irq(pdev, 0); 699 if (irq < 0) { 700 dev_err(dev, "Couldn't retrieve the TCON interrupt\n"); 701 return irq; 702 } 703 704 ret = devm_request_irq(dev, irq, sun4i_tcon_handler, 0, 705 dev_name(dev), tcon); 706 if (ret) { 707 dev_err(dev, "Couldn't request the IRQ\n"); 708 return ret; 709 } 710 711 return 0; 712 } 713 714 static struct regmap_config sun4i_tcon_regmap_config = { 715 .reg_bits = 32, 716 .val_bits = 32, 717 .reg_stride = 4, 718 .max_register = 0x800, 719 }; 720 721 static int sun4i_tcon_init_regmap(struct device *dev, 722 struct sun4i_tcon *tcon) 723 { 724 struct platform_device *pdev = to_platform_device(dev); 725 struct resource *res; 726 void __iomem *regs; 727 728 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 729 regs = devm_ioremap_resource(dev, res); 730 if (IS_ERR(regs)) 731 return PTR_ERR(regs); 732 733 tcon->regs = devm_regmap_init_mmio(dev, regs, 734 &sun4i_tcon_regmap_config); 735 if (IS_ERR(tcon->regs)) { 736 dev_err(dev, "Couldn't create the TCON regmap\n"); 737 return PTR_ERR(tcon->regs); 738 } 739 740 /* Make sure the TCON is disabled and all IRQs are off */ 741 regmap_write(tcon->regs, SUN4I_TCON_GCTL_REG, 0); 742 regmap_write(tcon->regs, SUN4I_TCON_GINT0_REG, 0); 743 regmap_write(tcon->regs, SUN4I_TCON_GINT1_REG, 0); 744 745 /* Disable IO lines and set them to tristate */ 746 regmap_write(tcon->regs, SUN4I_TCON0_IO_TRI_REG, ~0); 747 regmap_write(tcon->regs, SUN4I_TCON1_IO_TRI_REG, ~0); 748 749 return 0; 750 } 751 752 /* 753 * On SoCs with the old display pipeline design (Display Engine 1.0), 754 * the TCON is always tied to just one backend. Hence we can traverse 755 * the of_graph upwards to find the backend our tcon is connected to, 756 * and take its ID as our own. 757 * 758 * We can either identify backends from their compatible strings, which 759 * means maintaining a large list of them. Or, since the backend is 760 * registered and binded before the TCON, we can just go through the 761 * list of registered backends and compare the device node. 762 * 763 * As the structures now store engines instead of backends, here this 764 * function in fact searches the corresponding engine, and the ID is 765 * requested via the get_id function of the engine. 766 */ 767 static struct sunxi_engine * 768 sun4i_tcon_find_engine_traverse(struct sun4i_drv *drv, 769 struct device_node *node, 770 u32 port_id) 771 { 772 struct device_node *port, *ep, *remote; 773 struct sunxi_engine *engine = ERR_PTR(-EINVAL); 774 u32 reg = 0; 775 776 port = of_graph_get_port_by_id(node, port_id); 777 if (!port) 778 return ERR_PTR(-EINVAL); 779 780 /* 781 * This only works if there is only one path from the TCON 782 * to any display engine. Otherwise the probe order of the 783 * TCONs and display engines is not guaranteed. They may 784 * either bind to the wrong one, or worse, bind to the same 785 * one if additional checks are not done. 786 * 787 * Bail out if there are multiple input connections. 788 */ 789 if (of_get_available_child_count(port) != 1) 790 goto out_put_port; 791 792 /* Get the first connection without specifying an ID */ 793 ep = of_get_next_available_child(port, NULL); 794 if (!ep) 795 goto out_put_port; 796 797 remote = of_graph_get_remote_port_parent(ep); 798 if (!remote) 799 goto out_put_ep; 800 801 /* does this node match any registered engines? */ 802 list_for_each_entry(engine, &drv->engine_list, list) 803 if (remote == engine->node) 804 goto out_put_remote; 805 806 /* 807 * According to device tree binding input ports have even id 808 * number and output ports have odd id. Since component with 809 * more than one input and one output (TCON TOP) exits, correct 810 * remote input id has to be calculated by subtracting 1 from 811 * remote output id. If this for some reason can't be done, 0 812 * is used as input port id. 813 */ 814 port = of_graph_get_remote_port(ep); 815 if (!of_property_read_u32(port, "reg", ®) && reg > 0) 816 reg -= 1; 817 818 /* keep looking through upstream ports */ 819 engine = sun4i_tcon_find_engine_traverse(drv, remote, reg); 820 821 out_put_remote: 822 of_node_put(remote); 823 out_put_ep: 824 of_node_put(ep); 825 out_put_port: 826 of_node_put(port); 827 828 return engine; 829 } 830 831 /* 832 * The device tree binding says that the remote endpoint ID of any 833 * connection between components, up to and including the TCON, of 834 * the display pipeline should be equal to the actual ID of the local 835 * component. Thus we can look at any one of the input connections of 836 * the TCONs, and use that connection's remote endpoint ID as our own. 837 * 838 * Since the user of this function already finds the input port, 839 * the port is passed in directly without further checks. 840 */ 841 static int sun4i_tcon_of_get_id_from_port(struct device_node *port) 842 { 843 struct device_node *ep; 844 int ret = -EINVAL; 845 846 /* try finding an upstream endpoint */ 847 for_each_available_child_of_node(port, ep) { 848 struct device_node *remote; 849 u32 reg; 850 851 remote = of_graph_get_remote_endpoint(ep); 852 if (!remote) 853 continue; 854 855 ret = of_property_read_u32(remote, "reg", ®); 856 if (ret) 857 continue; 858 859 ret = reg; 860 } 861 862 return ret; 863 } 864 865 /* 866 * Once we know the TCON's id, we can look through the list of 867 * engines to find a matching one. We assume all engines have 868 * been probed and added to the list. 869 */ 870 static struct sunxi_engine *sun4i_tcon_get_engine_by_id(struct sun4i_drv *drv, 871 int id) 872 { 873 struct sunxi_engine *engine; 874 875 list_for_each_entry(engine, &drv->engine_list, list) 876 if (engine->id == id) 877 return engine; 878 879 return ERR_PTR(-EINVAL); 880 } 881 882 /* 883 * On SoCs with the old display pipeline design (Display Engine 1.0), 884 * we assumed the TCON was always tied to just one backend. However 885 * this proved not to be the case. On the A31, the TCON can select 886 * either backend as its source. On the A20 (and likely on the A10), 887 * the backend can choose which TCON to output to. 888 * 889 * The device tree binding says that the remote endpoint ID of any 890 * connection between components, up to and including the TCON, of 891 * the display pipeline should be equal to the actual ID of the local 892 * component. Thus we should be able to look at any one of the input 893 * connections of the TCONs, and use that connection's remote endpoint 894 * ID as our own. 895 * 896 * However the connections between the backend and TCON were assumed 897 * to be always singular, and their endpoit IDs were all incorrectly 898 * set to 0. This means for these old device trees, we cannot just look 899 * up the remote endpoint ID of a TCON input endpoint. TCON1 would be 900 * incorrectly identified as TCON0. 901 * 902 * This function first checks if the TCON node has 2 input endpoints. 903 * If so, then the device tree is a corrected version, and it will use 904 * sun4i_tcon_of_get_id() and sun4i_tcon_get_engine_by_id() from above 905 * to fetch the ID and engine directly. If not, then it is likely an 906 * old device trees, where the endpoint IDs were incorrect, but did not 907 * have endpoint connections between the backend and TCON across 908 * different display pipelines. It will fall back to the old method of 909 * traversing the of_graph to try and find a matching engine by device 910 * node. 911 * 912 * In the case of single display pipeline device trees, either method 913 * works. 914 */ 915 static struct sunxi_engine *sun4i_tcon_find_engine(struct sun4i_drv *drv, 916 struct device_node *node) 917 { 918 struct device_node *port; 919 struct sunxi_engine *engine; 920 921 port = of_graph_get_port_by_id(node, 0); 922 if (!port) 923 return ERR_PTR(-EINVAL); 924 925 /* 926 * Is this a corrected device tree with cross pipeline 927 * connections between the backend and TCON? 928 */ 929 if (of_get_child_count(port) > 1) { 930 /* Get our ID directly from an upstream endpoint */ 931 int id = sun4i_tcon_of_get_id_from_port(port); 932 933 /* Get our engine by matching our ID */ 934 engine = sun4i_tcon_get_engine_by_id(drv, id); 935 936 of_node_put(port); 937 return engine; 938 } 939 940 /* Fallback to old method by traversing input endpoints */ 941 of_node_put(port); 942 return sun4i_tcon_find_engine_traverse(drv, node, 0); 943 } 944 945 static int sun4i_tcon_bind(struct device *dev, struct device *master, 946 void *data) 947 { 948 struct drm_device *drm = data; 949 struct sun4i_drv *drv = drm->dev_private; 950 struct sunxi_engine *engine; 951 struct device_node *remote; 952 struct sun4i_tcon *tcon; 953 struct reset_control *edp_rstc; 954 bool has_lvds_rst, has_lvds_alt, can_lvds; 955 int ret; 956 957 engine = sun4i_tcon_find_engine(drv, dev->of_node); 958 if (IS_ERR(engine)) { 959 dev_err(dev, "Couldn't find matching engine\n"); 960 return -EPROBE_DEFER; 961 } 962 963 tcon = devm_kzalloc(dev, sizeof(*tcon), GFP_KERNEL); 964 if (!tcon) 965 return -ENOMEM; 966 dev_set_drvdata(dev, tcon); 967 tcon->drm = drm; 968 tcon->dev = dev; 969 tcon->id = engine->id; 970 tcon->quirks = of_device_get_match_data(dev); 971 972 tcon->lcd_rst = devm_reset_control_get(dev, "lcd"); 973 if (IS_ERR(tcon->lcd_rst)) { 974 dev_err(dev, "Couldn't get our reset line\n"); 975 return PTR_ERR(tcon->lcd_rst); 976 } 977 978 if (tcon->quirks->needs_edp_reset) { 979 edp_rstc = devm_reset_control_get_shared(dev, "edp"); 980 if (IS_ERR(edp_rstc)) { 981 dev_err(dev, "Couldn't get edp reset line\n"); 982 return PTR_ERR(edp_rstc); 983 } 984 985 ret = reset_control_deassert(edp_rstc); 986 if (ret) { 987 dev_err(dev, "Couldn't deassert edp reset line\n"); 988 return ret; 989 } 990 } 991 992 /* Make sure our TCON is reset */ 993 ret = reset_control_reset(tcon->lcd_rst); 994 if (ret) { 995 dev_err(dev, "Couldn't deassert our reset line\n"); 996 return ret; 997 } 998 999 if (tcon->quirks->supports_lvds) { 1000 /* 1001 * This can only be made optional since we've had DT 1002 * nodes without the LVDS reset properties. 1003 * 1004 * If the property is missing, just disable LVDS, and 1005 * print a warning. 1006 */ 1007 tcon->lvds_rst = devm_reset_control_get_optional(dev, "lvds"); 1008 if (IS_ERR(tcon->lvds_rst)) { 1009 dev_err(dev, "Couldn't get our reset line\n"); 1010 return PTR_ERR(tcon->lvds_rst); 1011 } else if (tcon->lvds_rst) { 1012 has_lvds_rst = true; 1013 reset_control_reset(tcon->lvds_rst); 1014 } else { 1015 has_lvds_rst = false; 1016 } 1017 1018 /* 1019 * This can only be made optional since we've had DT 1020 * nodes without the LVDS reset properties. 1021 * 1022 * If the property is missing, just disable LVDS, and 1023 * print a warning. 1024 */ 1025 if (tcon->quirks->has_lvds_alt) { 1026 tcon->lvds_pll = devm_clk_get(dev, "lvds-alt"); 1027 if (IS_ERR(tcon->lvds_pll)) { 1028 if (PTR_ERR(tcon->lvds_pll) == -ENOENT) { 1029 has_lvds_alt = false; 1030 } else { 1031 dev_err(dev, "Couldn't get the LVDS PLL\n"); 1032 return PTR_ERR(tcon->lvds_pll); 1033 } 1034 } else { 1035 has_lvds_alt = true; 1036 } 1037 } 1038 1039 if (!has_lvds_rst || 1040 (tcon->quirks->has_lvds_alt && !has_lvds_alt)) { 1041 dev_warn(dev, "Missing LVDS properties, Please upgrade your DT\n"); 1042 dev_warn(dev, "LVDS output disabled\n"); 1043 can_lvds = false; 1044 } else { 1045 can_lvds = true; 1046 } 1047 } else { 1048 can_lvds = false; 1049 } 1050 1051 ret = sun4i_tcon_init_clocks(dev, tcon); 1052 if (ret) { 1053 dev_err(dev, "Couldn't init our TCON clocks\n"); 1054 goto err_assert_reset; 1055 } 1056 1057 ret = sun4i_tcon_init_regmap(dev, tcon); 1058 if (ret) { 1059 dev_err(dev, "Couldn't init our TCON regmap\n"); 1060 goto err_free_clocks; 1061 } 1062 1063 if (tcon->quirks->has_channel_0) { 1064 ret = sun4i_dclk_create(dev, tcon); 1065 if (ret) { 1066 dev_err(dev, "Couldn't create our TCON dot clock\n"); 1067 goto err_free_clocks; 1068 } 1069 } 1070 1071 ret = sun4i_tcon_init_irq(dev, tcon); 1072 if (ret) { 1073 dev_err(dev, "Couldn't init our TCON interrupts\n"); 1074 goto err_free_dotclock; 1075 } 1076 1077 tcon->crtc = sun4i_crtc_init(drm, engine, tcon); 1078 if (IS_ERR(tcon->crtc)) { 1079 dev_err(dev, "Couldn't create our CRTC\n"); 1080 ret = PTR_ERR(tcon->crtc); 1081 goto err_free_dotclock; 1082 } 1083 1084 if (tcon->quirks->has_channel_0) { 1085 /* 1086 * If we have an LVDS panel connected to the TCON, we should 1087 * just probe the LVDS connector. Otherwise, just probe RGB as 1088 * we used to. 1089 */ 1090 remote = of_graph_get_remote_node(dev->of_node, 1, 0); 1091 if (of_device_is_compatible(remote, "panel-lvds")) 1092 if (can_lvds) 1093 ret = sun4i_lvds_init(drm, tcon); 1094 else 1095 ret = -EINVAL; 1096 else 1097 ret = sun4i_rgb_init(drm, tcon); 1098 of_node_put(remote); 1099 1100 if (ret < 0) 1101 goto err_free_dotclock; 1102 } 1103 1104 if (tcon->quirks->needs_de_be_mux) { 1105 /* 1106 * We assume there is no dynamic muxing of backends 1107 * and TCONs, so we select the backend with same ID. 1108 * 1109 * While dynamic selection might be interesting, since 1110 * the CRTC is tied to the TCON, while the layers are 1111 * tied to the backends, this means, we will need to 1112 * switch between groups of layers. There might not be 1113 * a way to represent this constraint in DRM. 1114 */ 1115 regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG, 1116 SUN4I_TCON0_CTL_SRC_SEL_MASK, 1117 tcon->id); 1118 regmap_update_bits(tcon->regs, SUN4I_TCON1_CTL_REG, 1119 SUN4I_TCON1_CTL_SRC_SEL_MASK, 1120 tcon->id); 1121 } 1122 1123 list_add_tail(&tcon->list, &drv->tcon_list); 1124 1125 return 0; 1126 1127 err_free_dotclock: 1128 if (tcon->quirks->has_channel_0) 1129 sun4i_dclk_free(tcon); 1130 err_free_clocks: 1131 sun4i_tcon_free_clocks(tcon); 1132 err_assert_reset: 1133 reset_control_assert(tcon->lcd_rst); 1134 return ret; 1135 } 1136 1137 static void sun4i_tcon_unbind(struct device *dev, struct device *master, 1138 void *data) 1139 { 1140 struct sun4i_tcon *tcon = dev_get_drvdata(dev); 1141 1142 list_del(&tcon->list); 1143 if (tcon->quirks->has_channel_0) 1144 sun4i_dclk_free(tcon); 1145 sun4i_tcon_free_clocks(tcon); 1146 } 1147 1148 static const struct component_ops sun4i_tcon_ops = { 1149 .bind = sun4i_tcon_bind, 1150 .unbind = sun4i_tcon_unbind, 1151 }; 1152 1153 static int sun4i_tcon_probe(struct platform_device *pdev) 1154 { 1155 struct device_node *node = pdev->dev.of_node; 1156 const struct sun4i_tcon_quirks *quirks; 1157 struct drm_bridge *bridge; 1158 struct drm_panel *panel; 1159 int ret; 1160 1161 quirks = of_device_get_match_data(&pdev->dev); 1162 1163 /* panels and bridges are present only on TCONs with channel 0 */ 1164 if (quirks->has_channel_0) { 1165 ret = drm_of_find_panel_or_bridge(node, 1, 0, &panel, &bridge); 1166 if (ret == -EPROBE_DEFER) 1167 return ret; 1168 } 1169 1170 return component_add(&pdev->dev, &sun4i_tcon_ops); 1171 } 1172 1173 static int sun4i_tcon_remove(struct platform_device *pdev) 1174 { 1175 component_del(&pdev->dev, &sun4i_tcon_ops); 1176 1177 return 0; 1178 } 1179 1180 /* platform specific TCON muxing callbacks */ 1181 static int sun4i_a10_tcon_set_mux(struct sun4i_tcon *tcon, 1182 const struct drm_encoder *encoder) 1183 { 1184 struct sun4i_tcon *tcon0 = sun4i_get_tcon0(encoder->dev); 1185 u32 shift; 1186 1187 if (!tcon0) 1188 return -EINVAL; 1189 1190 switch (encoder->encoder_type) { 1191 case DRM_MODE_ENCODER_TMDS: 1192 /* HDMI */ 1193 shift = 8; 1194 break; 1195 default: 1196 return -EINVAL; 1197 } 1198 1199 regmap_update_bits(tcon0->regs, SUN4I_TCON_MUX_CTRL_REG, 1200 0x3 << shift, tcon->id << shift); 1201 1202 return 0; 1203 } 1204 1205 static int sun5i_a13_tcon_set_mux(struct sun4i_tcon *tcon, 1206 const struct drm_encoder *encoder) 1207 { 1208 u32 val; 1209 1210 if (encoder->encoder_type == DRM_MODE_ENCODER_TVDAC) 1211 val = 1; 1212 else 1213 val = 0; 1214 1215 /* 1216 * FIXME: Undocumented bits 1217 */ 1218 return regmap_write(tcon->regs, SUN4I_TCON_MUX_CTRL_REG, val); 1219 } 1220 1221 static int sun6i_tcon_set_mux(struct sun4i_tcon *tcon, 1222 const struct drm_encoder *encoder) 1223 { 1224 struct sun4i_tcon *tcon0 = sun4i_get_tcon0(encoder->dev); 1225 u32 shift; 1226 1227 if (!tcon0) 1228 return -EINVAL; 1229 1230 switch (encoder->encoder_type) { 1231 case DRM_MODE_ENCODER_TMDS: 1232 /* HDMI */ 1233 shift = 8; 1234 break; 1235 default: 1236 /* TODO A31 has MIPI DSI but A31s does not */ 1237 return -EINVAL; 1238 } 1239 1240 regmap_update_bits(tcon0->regs, SUN4I_TCON_MUX_CTRL_REG, 1241 0x3 << shift, tcon->id << shift); 1242 1243 return 0; 1244 } 1245 1246 static const struct sun4i_tcon_quirks sun4i_a10_quirks = { 1247 .has_channel_0 = true, 1248 .has_channel_1 = true, 1249 .set_mux = sun4i_a10_tcon_set_mux, 1250 }; 1251 1252 static const struct sun4i_tcon_quirks sun5i_a13_quirks = { 1253 .has_channel_0 = true, 1254 .has_channel_1 = true, 1255 .set_mux = sun5i_a13_tcon_set_mux, 1256 }; 1257 1258 static const struct sun4i_tcon_quirks sun6i_a31_quirks = { 1259 .has_channel_0 = true, 1260 .has_channel_1 = true, 1261 .has_lvds_alt = true, 1262 .needs_de_be_mux = true, 1263 .set_mux = sun6i_tcon_set_mux, 1264 }; 1265 1266 static const struct sun4i_tcon_quirks sun6i_a31s_quirks = { 1267 .has_channel_0 = true, 1268 .has_channel_1 = true, 1269 .needs_de_be_mux = true, 1270 }; 1271 1272 static const struct sun4i_tcon_quirks sun7i_a20_quirks = { 1273 .has_channel_0 = true, 1274 .has_channel_1 = true, 1275 /* Same display pipeline structure as A10 */ 1276 .set_mux = sun4i_a10_tcon_set_mux, 1277 }; 1278 1279 static const struct sun4i_tcon_quirks sun8i_a33_quirks = { 1280 .has_channel_0 = true, 1281 .has_lvds_alt = true, 1282 }; 1283 1284 static const struct sun4i_tcon_quirks sun8i_a83t_lcd_quirks = { 1285 .supports_lvds = true, 1286 .has_channel_0 = true, 1287 }; 1288 1289 static const struct sun4i_tcon_quirks sun8i_a83t_tv_quirks = { 1290 .has_channel_1 = true, 1291 }; 1292 1293 static const struct sun4i_tcon_quirks sun8i_v3s_quirks = { 1294 .has_channel_0 = true, 1295 }; 1296 1297 static const struct sun4i_tcon_quirks sun9i_a80_tcon_lcd_quirks = { 1298 .has_channel_0 = true, 1299 .needs_edp_reset = true, 1300 }; 1301 1302 static const struct sun4i_tcon_quirks sun9i_a80_tcon_tv_quirks = { 1303 .has_channel_1 = true, 1304 .needs_edp_reset = true, 1305 }; 1306 1307 /* sun4i_drv uses this list to check if a device node is a TCON */ 1308 const struct of_device_id sun4i_tcon_of_table[] = { 1309 { .compatible = "allwinner,sun4i-a10-tcon", .data = &sun4i_a10_quirks }, 1310 { .compatible = "allwinner,sun5i-a13-tcon", .data = &sun5i_a13_quirks }, 1311 { .compatible = "allwinner,sun6i-a31-tcon", .data = &sun6i_a31_quirks }, 1312 { .compatible = "allwinner,sun6i-a31s-tcon", .data = &sun6i_a31s_quirks }, 1313 { .compatible = "allwinner,sun7i-a20-tcon", .data = &sun7i_a20_quirks }, 1314 { .compatible = "allwinner,sun8i-a33-tcon", .data = &sun8i_a33_quirks }, 1315 { .compatible = "allwinner,sun8i-a83t-tcon-lcd", .data = &sun8i_a83t_lcd_quirks }, 1316 { .compatible = "allwinner,sun8i-a83t-tcon-tv", .data = &sun8i_a83t_tv_quirks }, 1317 { .compatible = "allwinner,sun8i-v3s-tcon", .data = &sun8i_v3s_quirks }, 1318 { .compatible = "allwinner,sun9i-a80-tcon-lcd", .data = &sun9i_a80_tcon_lcd_quirks }, 1319 { .compatible = "allwinner,sun9i-a80-tcon-tv", .data = &sun9i_a80_tcon_tv_quirks }, 1320 { } 1321 }; 1322 MODULE_DEVICE_TABLE(of, sun4i_tcon_of_table); 1323 EXPORT_SYMBOL(sun4i_tcon_of_table); 1324 1325 static struct platform_driver sun4i_tcon_platform_driver = { 1326 .probe = sun4i_tcon_probe, 1327 .remove = sun4i_tcon_remove, 1328 .driver = { 1329 .name = "sun4i-tcon", 1330 .of_match_table = sun4i_tcon_of_table, 1331 }, 1332 }; 1333 module_platform_driver(sun4i_tcon_platform_driver); 1334 1335 MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>"); 1336 MODULE_DESCRIPTION("Allwinner A10 Timing Controller Driver"); 1337 MODULE_LICENSE("GPL"); 1338