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