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 of_node_put(port); 815 port = of_graph_get_remote_port(ep); 816 if (!of_property_read_u32(port, "reg", ®) && reg > 0) 817 reg -= 1; 818 819 /* keep looking through upstream ports */ 820 engine = sun4i_tcon_find_engine_traverse(drv, remote, reg); 821 822 out_put_remote: 823 of_node_put(remote); 824 out_put_ep: 825 of_node_put(ep); 826 out_put_port: 827 of_node_put(port); 828 829 return engine; 830 } 831 832 /* 833 * The device tree binding says that the remote endpoint ID of any 834 * connection between components, up to and including the TCON, of 835 * the display pipeline should be equal to the actual ID of the local 836 * component. Thus we can look at any one of the input connections of 837 * the TCONs, and use that connection's remote endpoint ID as our own. 838 * 839 * Since the user of this function already finds the input port, 840 * the port is passed in directly without further checks. 841 */ 842 static int sun4i_tcon_of_get_id_from_port(struct device_node *port) 843 { 844 struct device_node *ep; 845 int ret = -EINVAL; 846 847 /* try finding an upstream endpoint */ 848 for_each_available_child_of_node(port, ep) { 849 struct device_node *remote; 850 u32 reg; 851 852 remote = of_graph_get_remote_endpoint(ep); 853 if (!remote) 854 continue; 855 856 ret = of_property_read_u32(remote, "reg", ®); 857 if (ret) 858 continue; 859 860 ret = reg; 861 } 862 863 return ret; 864 } 865 866 /* 867 * Once we know the TCON's id, we can look through the list of 868 * engines to find a matching one. We assume all engines have 869 * been probed and added to the list. 870 */ 871 static struct sunxi_engine *sun4i_tcon_get_engine_by_id(struct sun4i_drv *drv, 872 int id) 873 { 874 struct sunxi_engine *engine; 875 876 list_for_each_entry(engine, &drv->engine_list, list) 877 if (engine->id == id) 878 return engine; 879 880 return ERR_PTR(-EINVAL); 881 } 882 883 /* 884 * On SoCs with the old display pipeline design (Display Engine 1.0), 885 * we assumed the TCON was always tied to just one backend. However 886 * this proved not to be the case. On the A31, the TCON can select 887 * either backend as its source. On the A20 (and likely on the A10), 888 * the backend can choose which TCON to output to. 889 * 890 * The device tree binding says that the remote endpoint ID of any 891 * connection between components, up to and including the TCON, of 892 * the display pipeline should be equal to the actual ID of the local 893 * component. Thus we should be able to look at any one of the input 894 * connections of the TCONs, and use that connection's remote endpoint 895 * ID as our own. 896 * 897 * However the connections between the backend and TCON were assumed 898 * to be always singular, and their endpoit IDs were all incorrectly 899 * set to 0. This means for these old device trees, we cannot just look 900 * up the remote endpoint ID of a TCON input endpoint. TCON1 would be 901 * incorrectly identified as TCON0. 902 * 903 * This function first checks if the TCON node has 2 input endpoints. 904 * If so, then the device tree is a corrected version, and it will use 905 * sun4i_tcon_of_get_id() and sun4i_tcon_get_engine_by_id() from above 906 * to fetch the ID and engine directly. If not, then it is likely an 907 * old device trees, where the endpoint IDs were incorrect, but did not 908 * have endpoint connections between the backend and TCON across 909 * different display pipelines. It will fall back to the old method of 910 * traversing the of_graph to try and find a matching engine by device 911 * node. 912 * 913 * In the case of single display pipeline device trees, either method 914 * works. 915 */ 916 static struct sunxi_engine *sun4i_tcon_find_engine(struct sun4i_drv *drv, 917 struct device_node *node) 918 { 919 struct device_node *port; 920 struct sunxi_engine *engine; 921 922 port = of_graph_get_port_by_id(node, 0); 923 if (!port) 924 return ERR_PTR(-EINVAL); 925 926 /* 927 * Is this a corrected device tree with cross pipeline 928 * connections between the backend and TCON? 929 */ 930 if (of_get_child_count(port) > 1) { 931 /* Get our ID directly from an upstream endpoint */ 932 int id = sun4i_tcon_of_get_id_from_port(port); 933 934 /* Get our engine by matching our ID */ 935 engine = sun4i_tcon_get_engine_by_id(drv, id); 936 937 of_node_put(port); 938 return engine; 939 } 940 941 /* Fallback to old method by traversing input endpoints */ 942 of_node_put(port); 943 return sun4i_tcon_find_engine_traverse(drv, node, 0); 944 } 945 946 static int sun4i_tcon_bind(struct device *dev, struct device *master, 947 void *data) 948 { 949 struct drm_device *drm = data; 950 struct sun4i_drv *drv = drm->dev_private; 951 struct sunxi_engine *engine; 952 struct device_node *remote; 953 struct sun4i_tcon *tcon; 954 struct reset_control *edp_rstc; 955 bool has_lvds_rst, has_lvds_alt, can_lvds; 956 int ret; 957 958 engine = sun4i_tcon_find_engine(drv, dev->of_node); 959 if (IS_ERR(engine)) { 960 dev_err(dev, "Couldn't find matching engine\n"); 961 return -EPROBE_DEFER; 962 } 963 964 tcon = devm_kzalloc(dev, sizeof(*tcon), GFP_KERNEL); 965 if (!tcon) 966 return -ENOMEM; 967 dev_set_drvdata(dev, tcon); 968 tcon->drm = drm; 969 tcon->dev = dev; 970 tcon->id = engine->id; 971 tcon->quirks = of_device_get_match_data(dev); 972 973 tcon->lcd_rst = devm_reset_control_get(dev, "lcd"); 974 if (IS_ERR(tcon->lcd_rst)) { 975 dev_err(dev, "Couldn't get our reset line\n"); 976 return PTR_ERR(tcon->lcd_rst); 977 } 978 979 if (tcon->quirks->needs_edp_reset) { 980 edp_rstc = devm_reset_control_get_shared(dev, "edp"); 981 if (IS_ERR(edp_rstc)) { 982 dev_err(dev, "Couldn't get edp reset line\n"); 983 return PTR_ERR(edp_rstc); 984 } 985 986 ret = reset_control_deassert(edp_rstc); 987 if (ret) { 988 dev_err(dev, "Couldn't deassert edp reset line\n"); 989 return ret; 990 } 991 } 992 993 /* Make sure our TCON is reset */ 994 ret = reset_control_reset(tcon->lcd_rst); 995 if (ret) { 996 dev_err(dev, "Couldn't deassert our reset line\n"); 997 return ret; 998 } 999 1000 if (tcon->quirks->supports_lvds) { 1001 /* 1002 * This can only be made optional since we've had DT 1003 * nodes without the LVDS reset properties. 1004 * 1005 * If the property is missing, just disable LVDS, and 1006 * print a warning. 1007 */ 1008 tcon->lvds_rst = devm_reset_control_get_optional(dev, "lvds"); 1009 if (IS_ERR(tcon->lvds_rst)) { 1010 dev_err(dev, "Couldn't get our reset line\n"); 1011 return PTR_ERR(tcon->lvds_rst); 1012 } else if (tcon->lvds_rst) { 1013 has_lvds_rst = true; 1014 reset_control_reset(tcon->lvds_rst); 1015 } else { 1016 has_lvds_rst = false; 1017 } 1018 1019 /* 1020 * This can only be made optional since we've had DT 1021 * nodes without the LVDS reset properties. 1022 * 1023 * If the property is missing, just disable LVDS, and 1024 * print a warning. 1025 */ 1026 if (tcon->quirks->has_lvds_alt) { 1027 tcon->lvds_pll = devm_clk_get(dev, "lvds-alt"); 1028 if (IS_ERR(tcon->lvds_pll)) { 1029 if (PTR_ERR(tcon->lvds_pll) == -ENOENT) { 1030 has_lvds_alt = false; 1031 } else { 1032 dev_err(dev, "Couldn't get the LVDS PLL\n"); 1033 return PTR_ERR(tcon->lvds_pll); 1034 } 1035 } else { 1036 has_lvds_alt = true; 1037 } 1038 } 1039 1040 if (!has_lvds_rst || 1041 (tcon->quirks->has_lvds_alt && !has_lvds_alt)) { 1042 dev_warn(dev, "Missing LVDS properties, Please upgrade your DT\n"); 1043 dev_warn(dev, "LVDS output disabled\n"); 1044 can_lvds = false; 1045 } else { 1046 can_lvds = true; 1047 } 1048 } else { 1049 can_lvds = false; 1050 } 1051 1052 ret = sun4i_tcon_init_clocks(dev, tcon); 1053 if (ret) { 1054 dev_err(dev, "Couldn't init our TCON clocks\n"); 1055 goto err_assert_reset; 1056 } 1057 1058 ret = sun4i_tcon_init_regmap(dev, tcon); 1059 if (ret) { 1060 dev_err(dev, "Couldn't init our TCON regmap\n"); 1061 goto err_free_clocks; 1062 } 1063 1064 if (tcon->quirks->has_channel_0) { 1065 ret = sun4i_dclk_create(dev, tcon); 1066 if (ret) { 1067 dev_err(dev, "Couldn't create our TCON dot clock\n"); 1068 goto err_free_clocks; 1069 } 1070 } 1071 1072 ret = sun4i_tcon_init_irq(dev, tcon); 1073 if (ret) { 1074 dev_err(dev, "Couldn't init our TCON interrupts\n"); 1075 goto err_free_dotclock; 1076 } 1077 1078 tcon->crtc = sun4i_crtc_init(drm, engine, tcon); 1079 if (IS_ERR(tcon->crtc)) { 1080 dev_err(dev, "Couldn't create our CRTC\n"); 1081 ret = PTR_ERR(tcon->crtc); 1082 goto err_free_dotclock; 1083 } 1084 1085 if (tcon->quirks->has_channel_0) { 1086 /* 1087 * If we have an LVDS panel connected to the TCON, we should 1088 * just probe the LVDS connector. Otherwise, just probe RGB as 1089 * we used to. 1090 */ 1091 remote = of_graph_get_remote_node(dev->of_node, 1, 0); 1092 if (of_device_is_compatible(remote, "panel-lvds")) 1093 if (can_lvds) 1094 ret = sun4i_lvds_init(drm, tcon); 1095 else 1096 ret = -EINVAL; 1097 else 1098 ret = sun4i_rgb_init(drm, tcon); 1099 of_node_put(remote); 1100 1101 if (ret < 0) 1102 goto err_free_dotclock; 1103 } 1104 1105 if (tcon->quirks->needs_de_be_mux) { 1106 /* 1107 * We assume there is no dynamic muxing of backends 1108 * and TCONs, so we select the backend with same ID. 1109 * 1110 * While dynamic selection might be interesting, since 1111 * the CRTC is tied to the TCON, while the layers are 1112 * tied to the backends, this means, we will need to 1113 * switch between groups of layers. There might not be 1114 * a way to represent this constraint in DRM. 1115 */ 1116 regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG, 1117 SUN4I_TCON0_CTL_SRC_SEL_MASK, 1118 tcon->id); 1119 regmap_update_bits(tcon->regs, SUN4I_TCON1_CTL_REG, 1120 SUN4I_TCON1_CTL_SRC_SEL_MASK, 1121 tcon->id); 1122 } 1123 1124 list_add_tail(&tcon->list, &drv->tcon_list); 1125 1126 return 0; 1127 1128 err_free_dotclock: 1129 if (tcon->quirks->has_channel_0) 1130 sun4i_dclk_free(tcon); 1131 err_free_clocks: 1132 sun4i_tcon_free_clocks(tcon); 1133 err_assert_reset: 1134 reset_control_assert(tcon->lcd_rst); 1135 return ret; 1136 } 1137 1138 static void sun4i_tcon_unbind(struct device *dev, struct device *master, 1139 void *data) 1140 { 1141 struct sun4i_tcon *tcon = dev_get_drvdata(dev); 1142 1143 list_del(&tcon->list); 1144 if (tcon->quirks->has_channel_0) 1145 sun4i_dclk_free(tcon); 1146 sun4i_tcon_free_clocks(tcon); 1147 } 1148 1149 static const struct component_ops sun4i_tcon_ops = { 1150 .bind = sun4i_tcon_bind, 1151 .unbind = sun4i_tcon_unbind, 1152 }; 1153 1154 static int sun4i_tcon_probe(struct platform_device *pdev) 1155 { 1156 struct device_node *node = pdev->dev.of_node; 1157 const struct sun4i_tcon_quirks *quirks; 1158 struct drm_bridge *bridge; 1159 struct drm_panel *panel; 1160 int ret; 1161 1162 quirks = of_device_get_match_data(&pdev->dev); 1163 1164 /* panels and bridges are present only on TCONs with channel 0 */ 1165 if (quirks->has_channel_0) { 1166 ret = drm_of_find_panel_or_bridge(node, 1, 0, &panel, &bridge); 1167 if (ret == -EPROBE_DEFER) 1168 return ret; 1169 } 1170 1171 return component_add(&pdev->dev, &sun4i_tcon_ops); 1172 } 1173 1174 static int sun4i_tcon_remove(struct platform_device *pdev) 1175 { 1176 component_del(&pdev->dev, &sun4i_tcon_ops); 1177 1178 return 0; 1179 } 1180 1181 /* platform specific TCON muxing callbacks */ 1182 static int sun4i_a10_tcon_set_mux(struct sun4i_tcon *tcon, 1183 const struct drm_encoder *encoder) 1184 { 1185 struct sun4i_tcon *tcon0 = sun4i_get_tcon0(encoder->dev); 1186 u32 shift; 1187 1188 if (!tcon0) 1189 return -EINVAL; 1190 1191 switch (encoder->encoder_type) { 1192 case DRM_MODE_ENCODER_TMDS: 1193 /* HDMI */ 1194 shift = 8; 1195 break; 1196 default: 1197 return -EINVAL; 1198 } 1199 1200 regmap_update_bits(tcon0->regs, SUN4I_TCON_MUX_CTRL_REG, 1201 0x3 << shift, tcon->id << shift); 1202 1203 return 0; 1204 } 1205 1206 static int sun5i_a13_tcon_set_mux(struct sun4i_tcon *tcon, 1207 const struct drm_encoder *encoder) 1208 { 1209 u32 val; 1210 1211 if (encoder->encoder_type == DRM_MODE_ENCODER_TVDAC) 1212 val = 1; 1213 else 1214 val = 0; 1215 1216 /* 1217 * FIXME: Undocumented bits 1218 */ 1219 return regmap_write(tcon->regs, SUN4I_TCON_MUX_CTRL_REG, val); 1220 } 1221 1222 static int sun6i_tcon_set_mux(struct sun4i_tcon *tcon, 1223 const struct drm_encoder *encoder) 1224 { 1225 struct sun4i_tcon *tcon0 = sun4i_get_tcon0(encoder->dev); 1226 u32 shift; 1227 1228 if (!tcon0) 1229 return -EINVAL; 1230 1231 switch (encoder->encoder_type) { 1232 case DRM_MODE_ENCODER_TMDS: 1233 /* HDMI */ 1234 shift = 8; 1235 break; 1236 default: 1237 /* TODO A31 has MIPI DSI but A31s does not */ 1238 return -EINVAL; 1239 } 1240 1241 regmap_update_bits(tcon0->regs, SUN4I_TCON_MUX_CTRL_REG, 1242 0x3 << shift, tcon->id << shift); 1243 1244 return 0; 1245 } 1246 1247 static const struct sun4i_tcon_quirks sun4i_a10_quirks = { 1248 .has_channel_0 = true, 1249 .has_channel_1 = true, 1250 .set_mux = sun4i_a10_tcon_set_mux, 1251 }; 1252 1253 static const struct sun4i_tcon_quirks sun5i_a13_quirks = { 1254 .has_channel_0 = true, 1255 .has_channel_1 = true, 1256 .set_mux = sun5i_a13_tcon_set_mux, 1257 }; 1258 1259 static const struct sun4i_tcon_quirks sun6i_a31_quirks = { 1260 .has_channel_0 = true, 1261 .has_channel_1 = true, 1262 .has_lvds_alt = true, 1263 .needs_de_be_mux = true, 1264 .set_mux = sun6i_tcon_set_mux, 1265 }; 1266 1267 static const struct sun4i_tcon_quirks sun6i_a31s_quirks = { 1268 .has_channel_0 = true, 1269 .has_channel_1 = true, 1270 .needs_de_be_mux = true, 1271 }; 1272 1273 static const struct sun4i_tcon_quirks sun7i_a20_quirks = { 1274 .has_channel_0 = true, 1275 .has_channel_1 = true, 1276 /* Same display pipeline structure as A10 */ 1277 .set_mux = sun4i_a10_tcon_set_mux, 1278 }; 1279 1280 static const struct sun4i_tcon_quirks sun8i_a33_quirks = { 1281 .has_channel_0 = true, 1282 .has_lvds_alt = true, 1283 }; 1284 1285 static const struct sun4i_tcon_quirks sun8i_a83t_lcd_quirks = { 1286 .supports_lvds = true, 1287 .has_channel_0 = true, 1288 }; 1289 1290 static const struct sun4i_tcon_quirks sun8i_a83t_tv_quirks = { 1291 .has_channel_1 = true, 1292 }; 1293 1294 static const struct sun4i_tcon_quirks sun8i_v3s_quirks = { 1295 .has_channel_0 = true, 1296 }; 1297 1298 static const struct sun4i_tcon_quirks sun9i_a80_tcon_lcd_quirks = { 1299 .has_channel_0 = true, 1300 .needs_edp_reset = true, 1301 }; 1302 1303 static const struct sun4i_tcon_quirks sun9i_a80_tcon_tv_quirks = { 1304 .has_channel_1 = true, 1305 .needs_edp_reset = true, 1306 }; 1307 1308 /* sun4i_drv uses this list to check if a device node is a TCON */ 1309 const struct of_device_id sun4i_tcon_of_table[] = { 1310 { .compatible = "allwinner,sun4i-a10-tcon", .data = &sun4i_a10_quirks }, 1311 { .compatible = "allwinner,sun5i-a13-tcon", .data = &sun5i_a13_quirks }, 1312 { .compatible = "allwinner,sun6i-a31-tcon", .data = &sun6i_a31_quirks }, 1313 { .compatible = "allwinner,sun6i-a31s-tcon", .data = &sun6i_a31s_quirks }, 1314 { .compatible = "allwinner,sun7i-a20-tcon", .data = &sun7i_a20_quirks }, 1315 { .compatible = "allwinner,sun8i-a33-tcon", .data = &sun8i_a33_quirks }, 1316 { .compatible = "allwinner,sun8i-a83t-tcon-lcd", .data = &sun8i_a83t_lcd_quirks }, 1317 { .compatible = "allwinner,sun8i-a83t-tcon-tv", .data = &sun8i_a83t_tv_quirks }, 1318 { .compatible = "allwinner,sun8i-v3s-tcon", .data = &sun8i_v3s_quirks }, 1319 { .compatible = "allwinner,sun9i-a80-tcon-lcd", .data = &sun9i_a80_tcon_lcd_quirks }, 1320 { .compatible = "allwinner,sun9i-a80-tcon-tv", .data = &sun9i_a80_tcon_tv_quirks }, 1321 { } 1322 }; 1323 MODULE_DEVICE_TABLE(of, sun4i_tcon_of_table); 1324 EXPORT_SYMBOL(sun4i_tcon_of_table); 1325 1326 static struct platform_driver sun4i_tcon_platform_driver = { 1327 .probe = sun4i_tcon_probe, 1328 .remove = sun4i_tcon_remove, 1329 .driver = { 1330 .name = "sun4i-tcon", 1331 .of_match_table = sun4i_tcon_of_table, 1332 }, 1333 }; 1334 module_platform_driver(sun4i_tcon_platform_driver); 1335 1336 MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>"); 1337 MODULE_DESCRIPTION("Allwinner A10 Timing Controller Driver"); 1338 MODULE_LICENSE("GPL"); 1339