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