1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // Ingenic JZ47xx KMS driver 4 // 5 // Copyright (C) 2019, Paul Cercueil <paul@crapouillou.net> 6 7 #include "ingenic-drm.h" 8 9 #include <linux/component.h> 10 #include <linux/clk.h> 11 #include <linux/dma-mapping.h> 12 #include <linux/module.h> 13 #include <linux/of_device.h> 14 #include <linux/platform_device.h> 15 #include <linux/regmap.h> 16 17 #include <drm/drm_atomic.h> 18 #include <drm/drm_atomic_helper.h> 19 #include <drm/drm_bridge.h> 20 #include <drm/drm_crtc.h> 21 #include <drm/drm_crtc_helper.h> 22 #include <drm/drm_drv.h> 23 #include <drm/drm_gem_cma_helper.h> 24 #include <drm/drm_fb_cma_helper.h> 25 #include <drm/drm_fb_helper.h> 26 #include <drm/drm_fourcc.h> 27 #include <drm/drm_gem_framebuffer_helper.h> 28 #include <drm/drm_irq.h> 29 #include <drm/drm_managed.h> 30 #include <drm/drm_of.h> 31 #include <drm/drm_panel.h> 32 #include <drm/drm_plane.h> 33 #include <drm/drm_plane_helper.h> 34 #include <drm/drm_probe_helper.h> 35 #include <drm/drm_simple_kms_helper.h> 36 #include <drm/drm_vblank.h> 37 38 struct ingenic_dma_hwdesc { 39 u32 next; 40 u32 addr; 41 u32 id; 42 u32 cmd; 43 } __packed; 44 45 struct jz_soc_info { 46 bool needs_dev_clk; 47 bool has_osd; 48 unsigned int max_width, max_height; 49 }; 50 51 struct ingenic_drm { 52 struct drm_device drm; 53 /* 54 * f1 (aka. foreground1) is our primary plane, on top of which 55 * f0 (aka. foreground0) can be overlayed. Z-order is fixed in 56 * hardware and cannot be changed. 57 */ 58 struct drm_plane f0, f1, *ipu_plane; 59 struct drm_crtc crtc; 60 61 struct device *dev; 62 struct regmap *map; 63 struct clk *lcd_clk, *pix_clk; 64 const struct jz_soc_info *soc_info; 65 66 struct ingenic_dma_hwdesc *dma_hwdesc_f0, *dma_hwdesc_f1; 67 dma_addr_t dma_hwdesc_phys_f0, dma_hwdesc_phys_f1; 68 69 bool panel_is_sharp; 70 bool no_vblank; 71 }; 72 73 static const u32 ingenic_drm_primary_formats[] = { 74 DRM_FORMAT_XRGB1555, 75 DRM_FORMAT_RGB565, 76 DRM_FORMAT_XRGB8888, 77 }; 78 79 static bool ingenic_drm_writeable_reg(struct device *dev, unsigned int reg) 80 { 81 switch (reg) { 82 case JZ_REG_LCD_IID: 83 case JZ_REG_LCD_SA0: 84 case JZ_REG_LCD_FID0: 85 case JZ_REG_LCD_CMD0: 86 case JZ_REG_LCD_SA1: 87 case JZ_REG_LCD_FID1: 88 case JZ_REG_LCD_CMD1: 89 return false; 90 default: 91 return true; 92 } 93 } 94 95 static const struct regmap_config ingenic_drm_regmap_config = { 96 .reg_bits = 32, 97 .val_bits = 32, 98 .reg_stride = 4, 99 100 .max_register = JZ_REG_LCD_SIZE1, 101 .writeable_reg = ingenic_drm_writeable_reg, 102 }; 103 104 static inline struct ingenic_drm *drm_device_get_priv(struct drm_device *drm) 105 { 106 return container_of(drm, struct ingenic_drm, drm); 107 } 108 109 static inline struct ingenic_drm *drm_crtc_get_priv(struct drm_crtc *crtc) 110 { 111 return container_of(crtc, struct ingenic_drm, crtc); 112 } 113 114 static void ingenic_drm_crtc_atomic_enable(struct drm_crtc *crtc, 115 struct drm_crtc_state *state) 116 { 117 struct ingenic_drm *priv = drm_crtc_get_priv(crtc); 118 119 regmap_write(priv->map, JZ_REG_LCD_STATE, 0); 120 121 regmap_update_bits(priv->map, JZ_REG_LCD_CTRL, 122 JZ_LCD_CTRL_ENABLE | JZ_LCD_CTRL_DISABLE, 123 JZ_LCD_CTRL_ENABLE); 124 125 drm_crtc_vblank_on(crtc); 126 } 127 128 static void ingenic_drm_crtc_atomic_disable(struct drm_crtc *crtc, 129 struct drm_crtc_state *state) 130 { 131 struct ingenic_drm *priv = drm_crtc_get_priv(crtc); 132 unsigned int var; 133 134 drm_crtc_vblank_off(crtc); 135 136 regmap_update_bits(priv->map, JZ_REG_LCD_CTRL, 137 JZ_LCD_CTRL_DISABLE, JZ_LCD_CTRL_DISABLE); 138 139 regmap_read_poll_timeout(priv->map, JZ_REG_LCD_STATE, var, 140 var & JZ_LCD_STATE_DISABLED, 141 1000, 0); 142 } 143 144 static void ingenic_drm_crtc_update_timings(struct ingenic_drm *priv, 145 struct drm_display_mode *mode) 146 { 147 unsigned int vpe, vds, vde, vt, hpe, hds, hde, ht; 148 149 vpe = mode->vsync_end - mode->vsync_start; 150 vds = mode->vtotal - mode->vsync_start; 151 vde = vds + mode->vdisplay; 152 vt = vde + mode->vsync_start - mode->vdisplay; 153 154 hpe = mode->hsync_end - mode->hsync_start; 155 hds = mode->htotal - mode->hsync_start; 156 hde = hds + mode->hdisplay; 157 ht = hde + mode->hsync_start - mode->hdisplay; 158 159 regmap_write(priv->map, JZ_REG_LCD_VSYNC, 160 0 << JZ_LCD_VSYNC_VPS_OFFSET | 161 vpe << JZ_LCD_VSYNC_VPE_OFFSET); 162 163 regmap_write(priv->map, JZ_REG_LCD_HSYNC, 164 0 << JZ_LCD_HSYNC_HPS_OFFSET | 165 hpe << JZ_LCD_HSYNC_HPE_OFFSET); 166 167 regmap_write(priv->map, JZ_REG_LCD_VAT, 168 ht << JZ_LCD_VAT_HT_OFFSET | 169 vt << JZ_LCD_VAT_VT_OFFSET); 170 171 regmap_write(priv->map, JZ_REG_LCD_DAH, 172 hds << JZ_LCD_DAH_HDS_OFFSET | 173 hde << JZ_LCD_DAH_HDE_OFFSET); 174 regmap_write(priv->map, JZ_REG_LCD_DAV, 175 vds << JZ_LCD_DAV_VDS_OFFSET | 176 vde << JZ_LCD_DAV_VDE_OFFSET); 177 178 if (priv->panel_is_sharp) { 179 regmap_write(priv->map, JZ_REG_LCD_PS, hde << 16 | (hde + 1)); 180 regmap_write(priv->map, JZ_REG_LCD_CLS, hde << 16 | (hde + 1)); 181 regmap_write(priv->map, JZ_REG_LCD_SPL, hpe << 16 | (hpe + 1)); 182 regmap_write(priv->map, JZ_REG_LCD_REV, mode->htotal << 16); 183 } 184 185 regmap_set_bits(priv->map, JZ_REG_LCD_CTRL, 186 JZ_LCD_CTRL_OFUP | JZ_LCD_CTRL_BURST_16); 187 188 /* 189 * IPU restart - specify how much time the LCDC will wait before 190 * transferring a new frame from the IPU. The value is the one 191 * suggested in the programming manual. 192 */ 193 regmap_write(priv->map, JZ_REG_LCD_IPUR, JZ_LCD_IPUR_IPUREN | 194 (ht * vpe / 3) << JZ_LCD_IPUR_IPUR_LSB); 195 } 196 197 static int ingenic_drm_crtc_atomic_check(struct drm_crtc *crtc, 198 struct drm_crtc_state *state) 199 { 200 struct ingenic_drm *priv = drm_crtc_get_priv(crtc); 201 struct drm_plane_state *f1_state, *f0_state, *ipu_state = NULL; 202 long rate; 203 204 if (!drm_atomic_crtc_needs_modeset(state)) 205 return 0; 206 207 if (state->mode.hdisplay > priv->soc_info->max_width || 208 state->mode.vdisplay > priv->soc_info->max_height) 209 return -EINVAL; 210 211 rate = clk_round_rate(priv->pix_clk, 212 state->adjusted_mode.clock * 1000); 213 if (rate < 0) 214 return rate; 215 216 if (priv->soc_info->has_osd) { 217 f1_state = drm_atomic_get_plane_state(state->state, &priv->f1); 218 f0_state = drm_atomic_get_plane_state(state->state, &priv->f0); 219 220 if (IS_ENABLED(CONFIG_DRM_INGENIC_IPU) && priv->ipu_plane) { 221 ipu_state = drm_atomic_get_plane_state(state->state, priv->ipu_plane); 222 223 /* IPU and F1 planes cannot be enabled at the same time. */ 224 if (f1_state->fb && ipu_state->fb) { 225 dev_dbg(priv->dev, "Cannot enable both F1 and IPU\n"); 226 return -EINVAL; 227 } 228 } 229 230 /* If all the planes are disabled, we won't get a VBLANK IRQ */ 231 priv->no_vblank = !f1_state->fb && !f0_state->fb && 232 !(ipu_state && ipu_state->fb); 233 } 234 235 return 0; 236 } 237 238 static void ingenic_drm_crtc_atomic_begin(struct drm_crtc *crtc, 239 struct drm_crtc_state *oldstate) 240 { 241 struct ingenic_drm *priv = drm_crtc_get_priv(crtc); 242 u32 ctrl = 0; 243 244 if (priv->soc_info->has_osd && 245 drm_atomic_crtc_needs_modeset(crtc->state)) { 246 /* 247 * If IPU plane is enabled, enable IPU as source for the F1 248 * plane; otherwise use regular DMA. 249 */ 250 if (priv->ipu_plane && priv->ipu_plane->state->fb) 251 ctrl |= JZ_LCD_OSDCTRL_IPU; 252 253 regmap_update_bits(priv->map, JZ_REG_LCD_OSDCTRL, 254 JZ_LCD_OSDCTRL_IPU, ctrl); 255 } 256 } 257 258 static void ingenic_drm_crtc_atomic_flush(struct drm_crtc *crtc, 259 struct drm_crtc_state *oldstate) 260 { 261 struct ingenic_drm *priv = drm_crtc_get_priv(crtc); 262 struct drm_crtc_state *state = crtc->state; 263 struct drm_pending_vblank_event *event = state->event; 264 265 if (drm_atomic_crtc_needs_modeset(state)) { 266 ingenic_drm_crtc_update_timings(priv, &state->mode); 267 268 clk_set_rate(priv->pix_clk, state->adjusted_mode.clock * 1000); 269 } 270 271 if (event) { 272 state->event = NULL; 273 274 spin_lock_irq(&crtc->dev->event_lock); 275 if (drm_crtc_vblank_get(crtc) == 0) 276 drm_crtc_arm_vblank_event(crtc, event); 277 else 278 drm_crtc_send_vblank_event(crtc, event); 279 spin_unlock_irq(&crtc->dev->event_lock); 280 } 281 } 282 283 static int ingenic_drm_plane_atomic_check(struct drm_plane *plane, 284 struct drm_plane_state *state) 285 { 286 struct ingenic_drm *priv = drm_device_get_priv(plane->dev); 287 struct drm_crtc_state *crtc_state; 288 struct drm_crtc *crtc = state->crtc ?: plane->state->crtc; 289 int ret; 290 291 if (!crtc) 292 return 0; 293 294 crtc_state = drm_atomic_get_existing_crtc_state(state->state, crtc); 295 if (WARN_ON(!crtc_state)) 296 return -EINVAL; 297 298 ret = drm_atomic_helper_check_plane_state(state, crtc_state, 299 DRM_PLANE_HELPER_NO_SCALING, 300 DRM_PLANE_HELPER_NO_SCALING, 301 priv->soc_info->has_osd, 302 true); 303 if (ret) 304 return ret; 305 306 /* 307 * If OSD is not available, check that the width/height match. 308 * Note that state->src_* are in 16.16 fixed-point format. 309 */ 310 if (!priv->soc_info->has_osd && 311 (state->src_x != 0 || 312 (state->src_w >> 16) != state->crtc_w || 313 (state->src_h >> 16) != state->crtc_h)) 314 return -EINVAL; 315 316 /* 317 * Require full modeset if enabling or disabling a plane, or changing 318 * its position, size or depth. 319 */ 320 if (priv->soc_info->has_osd && 321 (!plane->state->fb || !state->fb || 322 plane->state->crtc_x != state->crtc_x || 323 plane->state->crtc_y != state->crtc_y || 324 plane->state->crtc_w != state->crtc_w || 325 plane->state->crtc_h != state->crtc_h || 326 plane->state->fb->format->format != state->fb->format->format)) 327 crtc_state->mode_changed = true; 328 329 return 0; 330 } 331 332 static void ingenic_drm_plane_enable(struct ingenic_drm *priv, 333 struct drm_plane *plane) 334 { 335 unsigned int en_bit; 336 337 if (priv->soc_info->has_osd) { 338 if (plane->type == DRM_PLANE_TYPE_PRIMARY) 339 en_bit = JZ_LCD_OSDC_F1EN; 340 else 341 en_bit = JZ_LCD_OSDC_F0EN; 342 343 regmap_set_bits(priv->map, JZ_REG_LCD_OSDC, en_bit); 344 } 345 } 346 347 void ingenic_drm_plane_disable(struct device *dev, struct drm_plane *plane) 348 { 349 struct ingenic_drm *priv = dev_get_drvdata(dev); 350 unsigned int en_bit; 351 352 if (priv->soc_info->has_osd) { 353 if (plane->type == DRM_PLANE_TYPE_PRIMARY) 354 en_bit = JZ_LCD_OSDC_F1EN; 355 else 356 en_bit = JZ_LCD_OSDC_F0EN; 357 358 regmap_clear_bits(priv->map, JZ_REG_LCD_OSDC, en_bit); 359 } 360 } 361 362 static void ingenic_drm_plane_atomic_disable(struct drm_plane *plane, 363 struct drm_plane_state *old_state) 364 { 365 struct ingenic_drm *priv = drm_device_get_priv(plane->dev); 366 367 ingenic_drm_plane_disable(priv->dev, plane); 368 } 369 370 void ingenic_drm_plane_config(struct device *dev, 371 struct drm_plane *plane, u32 fourcc) 372 { 373 struct ingenic_drm *priv = dev_get_drvdata(dev); 374 struct drm_plane_state *state = plane->state; 375 unsigned int xy_reg, size_reg; 376 unsigned int ctrl = 0; 377 378 ingenic_drm_plane_enable(priv, plane); 379 380 if (priv->soc_info->has_osd && 381 plane->type == DRM_PLANE_TYPE_PRIMARY) { 382 switch (fourcc) { 383 case DRM_FORMAT_XRGB1555: 384 ctrl |= JZ_LCD_OSDCTRL_RGB555; 385 fallthrough; 386 case DRM_FORMAT_RGB565: 387 ctrl |= JZ_LCD_OSDCTRL_BPP_15_16; 388 break; 389 case DRM_FORMAT_XRGB8888: 390 ctrl |= JZ_LCD_OSDCTRL_BPP_18_24; 391 break; 392 } 393 394 regmap_update_bits(priv->map, JZ_REG_LCD_OSDCTRL, 395 JZ_LCD_OSDCTRL_BPP_MASK, ctrl); 396 } else { 397 switch (fourcc) { 398 case DRM_FORMAT_XRGB1555: 399 ctrl |= JZ_LCD_CTRL_RGB555; 400 fallthrough; 401 case DRM_FORMAT_RGB565: 402 ctrl |= JZ_LCD_CTRL_BPP_15_16; 403 break; 404 case DRM_FORMAT_XRGB8888: 405 ctrl |= JZ_LCD_CTRL_BPP_18_24; 406 break; 407 } 408 409 regmap_update_bits(priv->map, JZ_REG_LCD_CTRL, 410 JZ_LCD_CTRL_BPP_MASK, ctrl); 411 } 412 413 if (priv->soc_info->has_osd) { 414 if (plane->type == DRM_PLANE_TYPE_PRIMARY) { 415 xy_reg = JZ_REG_LCD_XYP1; 416 size_reg = JZ_REG_LCD_SIZE1; 417 } else { 418 xy_reg = JZ_REG_LCD_XYP0; 419 size_reg = JZ_REG_LCD_SIZE0; 420 } 421 422 regmap_write(priv->map, xy_reg, 423 state->crtc_x << JZ_LCD_XYP01_XPOS_LSB | 424 state->crtc_y << JZ_LCD_XYP01_YPOS_LSB); 425 regmap_write(priv->map, size_reg, 426 state->crtc_w << JZ_LCD_SIZE01_WIDTH_LSB | 427 state->crtc_h << JZ_LCD_SIZE01_HEIGHT_LSB); 428 } 429 } 430 431 static void ingenic_drm_plane_atomic_update(struct drm_plane *plane, 432 struct drm_plane_state *oldstate) 433 { 434 struct ingenic_drm *priv = drm_device_get_priv(plane->dev); 435 struct drm_plane_state *state = plane->state; 436 struct ingenic_dma_hwdesc *hwdesc; 437 unsigned int width, height, cpp; 438 dma_addr_t addr; 439 440 if (state && state->fb) { 441 addr = drm_fb_cma_get_gem_addr(state->fb, state, 0); 442 width = state->src_w >> 16; 443 height = state->src_h >> 16; 444 cpp = state->fb->format->cpp[0]; 445 446 if (priv->soc_info->has_osd && plane->type == DRM_PLANE_TYPE_OVERLAY) 447 hwdesc = priv->dma_hwdesc_f0; 448 else 449 hwdesc = priv->dma_hwdesc_f1; 450 451 hwdesc->addr = addr; 452 hwdesc->cmd = JZ_LCD_CMD_EOF_IRQ | (width * height * cpp / 4); 453 454 if (drm_atomic_crtc_needs_modeset(state->crtc->state)) 455 ingenic_drm_plane_config(priv->dev, plane, 456 state->fb->format->format); 457 } 458 } 459 460 static void ingenic_drm_encoder_atomic_mode_set(struct drm_encoder *encoder, 461 struct drm_crtc_state *crtc_state, 462 struct drm_connector_state *conn_state) 463 { 464 struct ingenic_drm *priv = drm_device_get_priv(encoder->dev); 465 struct drm_display_mode *mode = &crtc_state->adjusted_mode; 466 struct drm_connector *conn = conn_state->connector; 467 struct drm_display_info *info = &conn->display_info; 468 unsigned int cfg; 469 470 priv->panel_is_sharp = info->bus_flags & DRM_BUS_FLAG_SHARP_SIGNALS; 471 472 if (priv->panel_is_sharp) { 473 cfg = JZ_LCD_CFG_MODE_SPECIAL_TFT_1 | JZ_LCD_CFG_REV_POLARITY; 474 } else { 475 cfg = JZ_LCD_CFG_PS_DISABLE | JZ_LCD_CFG_CLS_DISABLE 476 | JZ_LCD_CFG_SPL_DISABLE | JZ_LCD_CFG_REV_DISABLE; 477 } 478 479 if (mode->flags & DRM_MODE_FLAG_NHSYNC) 480 cfg |= JZ_LCD_CFG_HSYNC_ACTIVE_LOW; 481 if (mode->flags & DRM_MODE_FLAG_NVSYNC) 482 cfg |= JZ_LCD_CFG_VSYNC_ACTIVE_LOW; 483 if (info->bus_flags & DRM_BUS_FLAG_DE_LOW) 484 cfg |= JZ_LCD_CFG_DE_ACTIVE_LOW; 485 if (info->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE) 486 cfg |= JZ_LCD_CFG_PCLK_FALLING_EDGE; 487 488 if (!priv->panel_is_sharp) { 489 if (conn->connector_type == DRM_MODE_CONNECTOR_TV) { 490 if (mode->flags & DRM_MODE_FLAG_INTERLACE) 491 cfg |= JZ_LCD_CFG_MODE_TV_OUT_I; 492 else 493 cfg |= JZ_LCD_CFG_MODE_TV_OUT_P; 494 } else { 495 switch (*info->bus_formats) { 496 case MEDIA_BUS_FMT_RGB565_1X16: 497 cfg |= JZ_LCD_CFG_MODE_GENERIC_16BIT; 498 break; 499 case MEDIA_BUS_FMT_RGB666_1X18: 500 cfg |= JZ_LCD_CFG_MODE_GENERIC_18BIT; 501 break; 502 case MEDIA_BUS_FMT_RGB888_1X24: 503 cfg |= JZ_LCD_CFG_MODE_GENERIC_24BIT; 504 break; 505 case MEDIA_BUS_FMT_RGB888_3X8: 506 cfg |= JZ_LCD_CFG_MODE_8BIT_SERIAL; 507 break; 508 default: 509 break; 510 } 511 } 512 } 513 514 regmap_write(priv->map, JZ_REG_LCD_CFG, cfg); 515 } 516 517 static int ingenic_drm_encoder_atomic_check(struct drm_encoder *encoder, 518 struct drm_crtc_state *crtc_state, 519 struct drm_connector_state *conn_state) 520 { 521 struct drm_display_info *info = &conn_state->connector->display_info; 522 523 if (info->num_bus_formats != 1) 524 return -EINVAL; 525 526 if (conn_state->connector->connector_type == DRM_MODE_CONNECTOR_TV) 527 return 0; 528 529 switch (*info->bus_formats) { 530 case MEDIA_BUS_FMT_RGB565_1X16: 531 case MEDIA_BUS_FMT_RGB666_1X18: 532 case MEDIA_BUS_FMT_RGB888_1X24: 533 case MEDIA_BUS_FMT_RGB888_3X8: 534 return 0; 535 default: 536 return -EINVAL; 537 } 538 } 539 540 static void ingenic_drm_atomic_helper_commit_tail(struct drm_atomic_state *old_state) 541 { 542 /* 543 * Just your regular drm_atomic_helper_commit_tail(), but only calls 544 * drm_atomic_helper_wait_for_vblanks() if priv->no_vblank. 545 */ 546 struct drm_device *dev = old_state->dev; 547 struct ingenic_drm *priv = drm_device_get_priv(dev); 548 549 drm_atomic_helper_commit_modeset_disables(dev, old_state); 550 551 drm_atomic_helper_commit_planes(dev, old_state, 0); 552 553 drm_atomic_helper_commit_modeset_enables(dev, old_state); 554 555 drm_atomic_helper_commit_hw_done(old_state); 556 557 if (!priv->no_vblank) 558 drm_atomic_helper_wait_for_vblanks(dev, old_state); 559 560 drm_atomic_helper_cleanup_planes(dev, old_state); 561 } 562 563 static irqreturn_t ingenic_drm_irq_handler(int irq, void *arg) 564 { 565 struct ingenic_drm *priv = drm_device_get_priv(arg); 566 unsigned int state; 567 568 regmap_read(priv->map, JZ_REG_LCD_STATE, &state); 569 570 regmap_update_bits(priv->map, JZ_REG_LCD_STATE, 571 JZ_LCD_STATE_EOF_IRQ, 0); 572 573 if (state & JZ_LCD_STATE_EOF_IRQ) 574 drm_crtc_handle_vblank(&priv->crtc); 575 576 return IRQ_HANDLED; 577 } 578 579 static int ingenic_drm_enable_vblank(struct drm_crtc *crtc) 580 { 581 struct ingenic_drm *priv = drm_crtc_get_priv(crtc); 582 583 regmap_update_bits(priv->map, JZ_REG_LCD_CTRL, 584 JZ_LCD_CTRL_EOF_IRQ, JZ_LCD_CTRL_EOF_IRQ); 585 586 return 0; 587 } 588 589 static void ingenic_drm_disable_vblank(struct drm_crtc *crtc) 590 { 591 struct ingenic_drm *priv = drm_crtc_get_priv(crtc); 592 593 regmap_update_bits(priv->map, JZ_REG_LCD_CTRL, JZ_LCD_CTRL_EOF_IRQ, 0); 594 } 595 596 DEFINE_DRM_GEM_CMA_FOPS(ingenic_drm_fops); 597 598 static struct drm_driver ingenic_drm_driver_data = { 599 .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC, 600 .name = "ingenic-drm", 601 .desc = "DRM module for Ingenic SoCs", 602 .date = "20200716", 603 .major = 1, 604 .minor = 1, 605 .patchlevel = 0, 606 607 .fops = &ingenic_drm_fops, 608 DRM_GEM_CMA_DRIVER_OPS, 609 610 .irq_handler = ingenic_drm_irq_handler, 611 }; 612 613 static const struct drm_plane_funcs ingenic_drm_primary_plane_funcs = { 614 .update_plane = drm_atomic_helper_update_plane, 615 .disable_plane = drm_atomic_helper_disable_plane, 616 .reset = drm_atomic_helper_plane_reset, 617 .destroy = drm_plane_cleanup, 618 619 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, 620 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, 621 }; 622 623 static const struct drm_crtc_funcs ingenic_drm_crtc_funcs = { 624 .set_config = drm_atomic_helper_set_config, 625 .page_flip = drm_atomic_helper_page_flip, 626 .reset = drm_atomic_helper_crtc_reset, 627 .destroy = drm_crtc_cleanup, 628 629 .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, 630 .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, 631 632 .enable_vblank = ingenic_drm_enable_vblank, 633 .disable_vblank = ingenic_drm_disable_vblank, 634 635 .gamma_set = drm_atomic_helper_legacy_gamma_set, 636 }; 637 638 static const struct drm_plane_helper_funcs ingenic_drm_plane_helper_funcs = { 639 .atomic_update = ingenic_drm_plane_atomic_update, 640 .atomic_check = ingenic_drm_plane_atomic_check, 641 .atomic_disable = ingenic_drm_plane_atomic_disable, 642 .prepare_fb = drm_gem_fb_prepare_fb, 643 }; 644 645 static const struct drm_crtc_helper_funcs ingenic_drm_crtc_helper_funcs = { 646 .atomic_enable = ingenic_drm_crtc_atomic_enable, 647 .atomic_disable = ingenic_drm_crtc_atomic_disable, 648 .atomic_begin = ingenic_drm_crtc_atomic_begin, 649 .atomic_flush = ingenic_drm_crtc_atomic_flush, 650 .atomic_check = ingenic_drm_crtc_atomic_check, 651 }; 652 653 static const struct drm_encoder_helper_funcs ingenic_drm_encoder_helper_funcs = { 654 .atomic_mode_set = ingenic_drm_encoder_atomic_mode_set, 655 .atomic_check = ingenic_drm_encoder_atomic_check, 656 }; 657 658 static const struct drm_mode_config_funcs ingenic_drm_mode_config_funcs = { 659 .fb_create = drm_gem_fb_create, 660 .output_poll_changed = drm_fb_helper_output_poll_changed, 661 .atomic_check = drm_atomic_helper_check, 662 .atomic_commit = drm_atomic_helper_commit, 663 }; 664 665 static struct drm_mode_config_helper_funcs ingenic_drm_mode_config_helpers = { 666 .atomic_commit_tail = ingenic_drm_atomic_helper_commit_tail, 667 }; 668 669 static void ingenic_drm_unbind_all(void *d) 670 { 671 struct ingenic_drm *priv = d; 672 673 component_unbind_all(priv->dev, &priv->drm); 674 } 675 676 static int ingenic_drm_bind(struct device *dev) 677 { 678 struct platform_device *pdev = to_platform_device(dev); 679 const struct jz_soc_info *soc_info; 680 struct ingenic_drm *priv; 681 struct clk *parent_clk; 682 struct drm_bridge *bridge; 683 struct drm_panel *panel; 684 struct drm_encoder *encoder; 685 struct drm_device *drm; 686 void __iomem *base; 687 long parent_rate; 688 unsigned int i, clone_mask = 0; 689 int ret, irq; 690 691 soc_info = of_device_get_match_data(dev); 692 if (!soc_info) { 693 dev_err(dev, "Missing platform data\n"); 694 return -EINVAL; 695 } 696 697 priv = devm_drm_dev_alloc(dev, &ingenic_drm_driver_data, 698 struct ingenic_drm, drm); 699 if (IS_ERR(priv)) 700 return PTR_ERR(priv); 701 702 priv->soc_info = soc_info; 703 priv->dev = dev; 704 drm = &priv->drm; 705 706 platform_set_drvdata(pdev, priv); 707 708 ret = drmm_mode_config_init(drm); 709 if (ret) 710 return ret; 711 712 drm->mode_config.min_width = 0; 713 drm->mode_config.min_height = 0; 714 drm->mode_config.max_width = soc_info->max_width; 715 drm->mode_config.max_height = 4095; 716 drm->mode_config.funcs = &ingenic_drm_mode_config_funcs; 717 drm->mode_config.helper_private = &ingenic_drm_mode_config_helpers; 718 719 base = devm_platform_ioremap_resource(pdev, 0); 720 if (IS_ERR(base)) { 721 dev_err(dev, "Failed to get memory resource\n"); 722 return PTR_ERR(base); 723 } 724 725 priv->map = devm_regmap_init_mmio(dev, base, 726 &ingenic_drm_regmap_config); 727 if (IS_ERR(priv->map)) { 728 dev_err(dev, "Failed to create regmap\n"); 729 return PTR_ERR(priv->map); 730 } 731 732 irq = platform_get_irq(pdev, 0); 733 if (irq < 0) 734 return irq; 735 736 if (soc_info->needs_dev_clk) { 737 priv->lcd_clk = devm_clk_get(dev, "lcd"); 738 if (IS_ERR(priv->lcd_clk)) { 739 dev_err(dev, "Failed to get lcd clock\n"); 740 return PTR_ERR(priv->lcd_clk); 741 } 742 } 743 744 priv->pix_clk = devm_clk_get(dev, "lcd_pclk"); 745 if (IS_ERR(priv->pix_clk)) { 746 dev_err(dev, "Failed to get pixel clock\n"); 747 return PTR_ERR(priv->pix_clk); 748 } 749 750 priv->dma_hwdesc_f1 = dmam_alloc_coherent(dev, sizeof(*priv->dma_hwdesc_f1), 751 &priv->dma_hwdesc_phys_f1, 752 GFP_KERNEL); 753 if (!priv->dma_hwdesc_f1) 754 return -ENOMEM; 755 756 priv->dma_hwdesc_f1->next = priv->dma_hwdesc_phys_f1; 757 priv->dma_hwdesc_f1->id = 0xf1; 758 759 if (priv->soc_info->has_osd) { 760 priv->dma_hwdesc_f0 = dmam_alloc_coherent(dev, 761 sizeof(*priv->dma_hwdesc_f0), 762 &priv->dma_hwdesc_phys_f0, 763 GFP_KERNEL); 764 if (!priv->dma_hwdesc_f0) 765 return -ENOMEM; 766 767 priv->dma_hwdesc_f0->next = priv->dma_hwdesc_phys_f0; 768 priv->dma_hwdesc_f0->id = 0xf0; 769 } 770 771 if (soc_info->has_osd) 772 priv->ipu_plane = drm_plane_from_index(drm, 0); 773 774 drm_plane_helper_add(&priv->f1, &ingenic_drm_plane_helper_funcs); 775 776 ret = drm_universal_plane_init(drm, &priv->f1, 1, 777 &ingenic_drm_primary_plane_funcs, 778 ingenic_drm_primary_formats, 779 ARRAY_SIZE(ingenic_drm_primary_formats), 780 NULL, DRM_PLANE_TYPE_PRIMARY, NULL); 781 if (ret) { 782 dev_err(dev, "Failed to register plane: %i\n", ret); 783 return ret; 784 } 785 786 drm_crtc_helper_add(&priv->crtc, &ingenic_drm_crtc_helper_funcs); 787 788 ret = drm_crtc_init_with_planes(drm, &priv->crtc, &priv->f1, 789 NULL, &ingenic_drm_crtc_funcs, NULL); 790 if (ret) { 791 dev_err(dev, "Failed to init CRTC: %i\n", ret); 792 return ret; 793 } 794 795 if (soc_info->has_osd) { 796 drm_plane_helper_add(&priv->f0, 797 &ingenic_drm_plane_helper_funcs); 798 799 ret = drm_universal_plane_init(drm, &priv->f0, 1, 800 &ingenic_drm_primary_plane_funcs, 801 ingenic_drm_primary_formats, 802 ARRAY_SIZE(ingenic_drm_primary_formats), 803 NULL, DRM_PLANE_TYPE_OVERLAY, 804 NULL); 805 if (ret) { 806 dev_err(dev, "Failed to register overlay plane: %i\n", 807 ret); 808 return ret; 809 } 810 811 if (IS_ENABLED(CONFIG_DRM_INGENIC_IPU)) { 812 ret = component_bind_all(dev, drm); 813 if (ret) { 814 if (ret != -EPROBE_DEFER) 815 dev_err(dev, "Failed to bind components: %i\n", ret); 816 return ret; 817 } 818 819 ret = devm_add_action_or_reset(dev, ingenic_drm_unbind_all, priv); 820 if (ret) 821 return ret; 822 823 priv->ipu_plane = drm_plane_from_index(drm, 2); 824 if (!priv->ipu_plane) { 825 dev_err(dev, "Failed to retrieve IPU plane\n"); 826 return -EINVAL; 827 } 828 } 829 } 830 831 for (i = 0; ; i++) { 832 ret = drm_of_find_panel_or_bridge(dev->of_node, 0, i, &panel, &bridge); 833 if (ret) { 834 if (ret == -ENODEV) 835 break; /* we're done */ 836 if (ret != -EPROBE_DEFER) 837 dev_err(dev, "Failed to get bridge handle\n"); 838 return ret; 839 } 840 841 if (panel) 842 bridge = devm_drm_panel_bridge_add_typed(dev, panel, 843 DRM_MODE_CONNECTOR_DPI); 844 845 encoder = devm_kzalloc(dev, sizeof(*encoder), GFP_KERNEL); 846 if (!encoder) 847 return -ENOMEM; 848 849 encoder->possible_crtcs = 1; 850 851 drm_encoder_helper_add(encoder, &ingenic_drm_encoder_helper_funcs); 852 853 ret = drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_DPI); 854 if (ret) { 855 dev_err(dev, "Failed to init encoder: %d\n", ret); 856 return ret; 857 } 858 859 ret = drm_bridge_attach(encoder, bridge, NULL, 0); 860 if (ret) { 861 dev_err(dev, "Unable to attach bridge\n"); 862 return ret; 863 } 864 } 865 866 drm_for_each_encoder(encoder, drm) { 867 clone_mask |= BIT(drm_encoder_index(encoder)); 868 } 869 870 drm_for_each_encoder(encoder, drm) { 871 encoder->possible_clones = clone_mask; 872 } 873 874 ret = drm_irq_install(drm, irq); 875 if (ret) { 876 dev_err(dev, "Unable to install IRQ handler\n"); 877 return ret; 878 } 879 880 ret = drm_vblank_init(drm, 1); 881 if (ret) { 882 dev_err(dev, "Failed calling drm_vblank_init()\n"); 883 return ret; 884 } 885 886 drm_mode_config_reset(drm); 887 888 ret = clk_prepare_enable(priv->pix_clk); 889 if (ret) { 890 dev_err(dev, "Unable to start pixel clock\n"); 891 return ret; 892 } 893 894 if (priv->lcd_clk) { 895 parent_clk = clk_get_parent(priv->lcd_clk); 896 parent_rate = clk_get_rate(parent_clk); 897 898 /* LCD Device clock must be 3x the pixel clock for STN panels, 899 * or 1.5x the pixel clock for TFT panels. To avoid having to 900 * check for the LCD device clock everytime we do a mode change, 901 * we set the LCD device clock to the highest rate possible. 902 */ 903 ret = clk_set_rate(priv->lcd_clk, parent_rate); 904 if (ret) { 905 dev_err(dev, "Unable to set LCD clock rate\n"); 906 goto err_pixclk_disable; 907 } 908 909 ret = clk_prepare_enable(priv->lcd_clk); 910 if (ret) { 911 dev_err(dev, "Unable to start lcd clock\n"); 912 goto err_pixclk_disable; 913 } 914 } 915 916 /* Set address of our DMA descriptor chain */ 917 regmap_write(priv->map, JZ_REG_LCD_DA0, priv->dma_hwdesc_phys_f0); 918 regmap_write(priv->map, JZ_REG_LCD_DA1, priv->dma_hwdesc_phys_f1); 919 920 /* Enable OSD if available */ 921 if (soc_info->has_osd) 922 regmap_write(priv->map, JZ_REG_LCD_OSDC, JZ_LCD_OSDC_OSDEN); 923 924 ret = drm_dev_register(drm, 0); 925 if (ret) { 926 dev_err(dev, "Failed to register DRM driver\n"); 927 goto err_devclk_disable; 928 } 929 930 drm_fbdev_generic_setup(drm, 32); 931 932 return 0; 933 934 err_devclk_disable: 935 if (priv->lcd_clk) 936 clk_disable_unprepare(priv->lcd_clk); 937 err_pixclk_disable: 938 clk_disable_unprepare(priv->pix_clk); 939 return ret; 940 } 941 942 static int compare_of(struct device *dev, void *data) 943 { 944 return dev->of_node == data; 945 } 946 947 static void ingenic_drm_unbind(struct device *dev) 948 { 949 struct ingenic_drm *priv = dev_get_drvdata(dev); 950 951 if (priv->lcd_clk) 952 clk_disable_unprepare(priv->lcd_clk); 953 clk_disable_unprepare(priv->pix_clk); 954 955 drm_dev_unregister(&priv->drm); 956 drm_atomic_helper_shutdown(&priv->drm); 957 } 958 959 static const struct component_master_ops ingenic_master_ops = { 960 .bind = ingenic_drm_bind, 961 .unbind = ingenic_drm_unbind, 962 }; 963 964 static int ingenic_drm_probe(struct platform_device *pdev) 965 { 966 struct device *dev = &pdev->dev; 967 struct component_match *match = NULL; 968 struct device_node *np; 969 970 if (!IS_ENABLED(CONFIG_DRM_INGENIC_IPU)) 971 return ingenic_drm_bind(dev); 972 973 /* IPU is at port address 8 */ 974 np = of_graph_get_remote_node(dev->of_node, 8, 0); 975 if (!np) { 976 dev_err(dev, "Unable to get IPU node\n"); 977 return -EINVAL; 978 } 979 980 drm_of_component_match_add(dev, &match, compare_of, np); 981 982 return component_master_add_with_match(dev, &ingenic_master_ops, match); 983 } 984 985 static int ingenic_drm_remove(struct platform_device *pdev) 986 { 987 struct device *dev = &pdev->dev; 988 989 if (!IS_ENABLED(CONFIG_DRM_INGENIC_IPU)) 990 ingenic_drm_unbind(dev); 991 else 992 component_master_del(dev, &ingenic_master_ops); 993 994 return 0; 995 } 996 997 static const struct jz_soc_info jz4740_soc_info = { 998 .needs_dev_clk = true, 999 .has_osd = false, 1000 .max_width = 800, 1001 .max_height = 600, 1002 }; 1003 1004 static const struct jz_soc_info jz4725b_soc_info = { 1005 .needs_dev_clk = false, 1006 .has_osd = true, 1007 .max_width = 800, 1008 .max_height = 600, 1009 }; 1010 1011 static const struct jz_soc_info jz4770_soc_info = { 1012 .needs_dev_clk = false, 1013 .has_osd = true, 1014 .max_width = 1280, 1015 .max_height = 720, 1016 }; 1017 1018 static const struct of_device_id ingenic_drm_of_match[] = { 1019 { .compatible = "ingenic,jz4740-lcd", .data = &jz4740_soc_info }, 1020 { .compatible = "ingenic,jz4725b-lcd", .data = &jz4725b_soc_info }, 1021 { .compatible = "ingenic,jz4770-lcd", .data = &jz4770_soc_info }, 1022 { /* sentinel */ }, 1023 }; 1024 MODULE_DEVICE_TABLE(of, ingenic_drm_of_match); 1025 1026 static struct platform_driver ingenic_drm_driver = { 1027 .driver = { 1028 .name = "ingenic-drm", 1029 .of_match_table = of_match_ptr(ingenic_drm_of_match), 1030 }, 1031 .probe = ingenic_drm_probe, 1032 .remove = ingenic_drm_remove, 1033 }; 1034 1035 static int ingenic_drm_init(void) 1036 { 1037 int err; 1038 1039 if (IS_ENABLED(CONFIG_DRM_INGENIC_IPU)) { 1040 err = platform_driver_register(ingenic_ipu_driver_ptr); 1041 if (err) 1042 return err; 1043 } 1044 1045 return platform_driver_register(&ingenic_drm_driver); 1046 } 1047 module_init(ingenic_drm_init); 1048 1049 static void ingenic_drm_exit(void) 1050 { 1051 platform_driver_unregister(&ingenic_drm_driver); 1052 1053 if (IS_ENABLED(CONFIG_DRM_INGENIC_IPU)) 1054 platform_driver_unregister(ingenic_ipu_driver_ptr); 1055 } 1056 module_exit(ingenic_drm_exit); 1057 1058 MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>"); 1059 MODULE_DESCRIPTION("DRM driver for the Ingenic SoCs\n"); 1060 MODULE_LICENSE("GPL v2"); 1061