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