1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * i.MX IPUv3 Graphics driver 4 * 5 * Copyright (C) 2011 Sascha Hauer, Pengutronix 6 */ 7 8#include <linux/clk.h> 9#include <linux/component.h> 10#include <linux/device.h> 11#include <linux/dma-mapping.h> 12#include <linux/errno.h> 13#include <linux/export.h> 14#include <linux/module.h> 15#include <linux/platform_device.h> 16 17#include <video/imx-ipu-v3.h> 18 19#include <drm/drm_atomic.h> 20#include <drm/drm_atomic_helper.h> 21#include <drm/drm_fb_cma_helper.h> 22#include <drm/drm_gem_cma_helper.h> 23#include <drm/drm_probe_helper.h> 24#include <drm/drm_vblank.h> 25 26#include "imx-drm.h" 27#include "ipuv3-plane.h" 28 29#define DRIVER_DESC "i.MX IPUv3 Graphics" 30 31struct ipu_crtc { 32 struct device *dev; 33 struct drm_crtc base; 34 35 /* plane[0] is the full plane, plane[1] is the partial plane */ 36 struct ipu_plane *plane[2]; 37 38 struct ipu_dc *dc; 39 struct ipu_di *di; 40 int irq; 41 struct drm_pending_vblank_event *event; 42}; 43 44static inline struct ipu_crtc *to_ipu_crtc(struct drm_crtc *crtc) 45{ 46 return container_of(crtc, struct ipu_crtc, base); 47} 48 49static void ipu_crtc_atomic_enable(struct drm_crtc *crtc, 50 struct drm_crtc_state *old_state) 51{ 52 struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); 53 struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent); 54 55 ipu_prg_enable(ipu); 56 ipu_dc_enable(ipu); 57 ipu_dc_enable_channel(ipu_crtc->dc); 58 ipu_di_enable(ipu_crtc->di); 59} 60 61static void ipu_crtc_disable_planes(struct ipu_crtc *ipu_crtc, 62 struct drm_crtc_state *old_crtc_state) 63{ 64 bool disable_partial = false; 65 bool disable_full = false; 66 struct drm_plane *plane; 67 68 drm_atomic_crtc_state_for_each_plane(plane, old_crtc_state) { 69 if (plane == &ipu_crtc->plane[0]->base) 70 disable_full = true; 71 if (ipu_crtc->plane[1] && plane == &ipu_crtc->plane[1]->base) 72 disable_partial = true; 73 } 74 75 if (disable_partial) 76 ipu_plane_disable(ipu_crtc->plane[1], true); 77 if (disable_full) 78 ipu_plane_disable(ipu_crtc->plane[0], true); 79} 80 81static void ipu_crtc_atomic_disable(struct drm_crtc *crtc, 82 struct drm_crtc_state *old_crtc_state) 83{ 84 struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); 85 struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent); 86 87 ipu_dc_disable_channel(ipu_crtc->dc); 88 ipu_di_disable(ipu_crtc->di); 89 /* 90 * Planes must be disabled before DC clock is removed, as otherwise the 91 * attached IDMACs will be left in undefined state, possibly hanging 92 * the IPU or even system. 93 */ 94 ipu_crtc_disable_planes(ipu_crtc, old_crtc_state); 95 ipu_dc_disable(ipu); 96 ipu_prg_disable(ipu); 97 98 drm_crtc_vblank_off(crtc); 99 100 spin_lock_irq(&crtc->dev->event_lock); 101 if (crtc->state->event && !crtc->state->active) { 102 drm_crtc_send_vblank_event(crtc, crtc->state->event); 103 crtc->state->event = NULL; 104 } 105 spin_unlock_irq(&crtc->dev->event_lock); 106} 107 108static void imx_drm_crtc_reset(struct drm_crtc *crtc) 109{ 110 struct imx_crtc_state *state; 111 112 if (crtc->state) 113 __drm_atomic_helper_crtc_destroy_state(crtc->state); 114 115 kfree(to_imx_crtc_state(crtc->state)); 116 crtc->state = NULL; 117 118 state = kzalloc(sizeof(*state), GFP_KERNEL); 119 if (state) 120 __drm_atomic_helper_crtc_reset(crtc, &state->base); 121} 122 123static struct drm_crtc_state *imx_drm_crtc_duplicate_state(struct drm_crtc *crtc) 124{ 125 struct imx_crtc_state *state; 126 127 state = kzalloc(sizeof(*state), GFP_KERNEL); 128 if (!state) 129 return NULL; 130 131 __drm_atomic_helper_crtc_duplicate_state(crtc, &state->base); 132 133 WARN_ON(state->base.crtc != crtc); 134 state->base.crtc = crtc; 135 136 return &state->base; 137} 138 139static void imx_drm_crtc_destroy_state(struct drm_crtc *crtc, 140 struct drm_crtc_state *state) 141{ 142 __drm_atomic_helper_crtc_destroy_state(state); 143 kfree(to_imx_crtc_state(state)); 144} 145 146static int ipu_enable_vblank(struct drm_crtc *crtc) 147{ 148 struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); 149 150 enable_irq(ipu_crtc->irq); 151 152 return 0; 153} 154 155static void ipu_disable_vblank(struct drm_crtc *crtc) 156{ 157 struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); 158 159 disable_irq_nosync(ipu_crtc->irq); 160} 161 162static const struct drm_crtc_funcs ipu_crtc_funcs = { 163 .set_config = drm_atomic_helper_set_config, 164 .destroy = drm_crtc_cleanup, 165 .page_flip = drm_atomic_helper_page_flip, 166 .reset = imx_drm_crtc_reset, 167 .atomic_duplicate_state = imx_drm_crtc_duplicate_state, 168 .atomic_destroy_state = imx_drm_crtc_destroy_state, 169 .enable_vblank = ipu_enable_vblank, 170 .disable_vblank = ipu_disable_vblank, 171}; 172 173static irqreturn_t ipu_irq_handler(int irq, void *dev_id) 174{ 175 struct ipu_crtc *ipu_crtc = dev_id; 176 struct drm_crtc *crtc = &ipu_crtc->base; 177 unsigned long flags; 178 int i; 179 180 drm_crtc_handle_vblank(crtc); 181 182 if (ipu_crtc->event) { 183 for (i = 0; i < ARRAY_SIZE(ipu_crtc->plane); i++) { 184 struct ipu_plane *plane = ipu_crtc->plane[i]; 185 186 if (!plane) 187 continue; 188 189 if (ipu_plane_atomic_update_pending(&plane->base)) 190 break; 191 } 192 193 if (i == ARRAY_SIZE(ipu_crtc->plane)) { 194 spin_lock_irqsave(&crtc->dev->event_lock, flags); 195 drm_crtc_send_vblank_event(crtc, ipu_crtc->event); 196 ipu_crtc->event = NULL; 197 drm_crtc_vblank_put(crtc); 198 spin_unlock_irqrestore(&crtc->dev->event_lock, flags); 199 } 200 } 201 202 return IRQ_HANDLED; 203} 204 205static bool ipu_crtc_mode_fixup(struct drm_crtc *crtc, 206 const struct drm_display_mode *mode, 207 struct drm_display_mode *adjusted_mode) 208{ 209 struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); 210 struct videomode vm; 211 int ret; 212 213 drm_display_mode_to_videomode(adjusted_mode, &vm); 214 215 ret = ipu_di_adjust_videomode(ipu_crtc->di, &vm); 216 if (ret) 217 return false; 218 219 if ((vm.vsync_len == 0) || (vm.hsync_len == 0)) 220 return false; 221 222 drm_display_mode_from_videomode(&vm, adjusted_mode); 223 224 return true; 225} 226 227static int ipu_crtc_atomic_check(struct drm_crtc *crtc, 228 struct drm_crtc_state *state) 229{ 230 u32 primary_plane_mask = drm_plane_mask(crtc->primary); 231 232 if (state->active && (primary_plane_mask & state->plane_mask) == 0) 233 return -EINVAL; 234 235 return 0; 236} 237 238static void ipu_crtc_atomic_begin(struct drm_crtc *crtc, 239 struct drm_crtc_state *old_crtc_state) 240{ 241 drm_crtc_vblank_on(crtc); 242} 243 244static void ipu_crtc_atomic_flush(struct drm_crtc *crtc, 245 struct drm_crtc_state *old_crtc_state) 246{ 247 spin_lock_irq(&crtc->dev->event_lock); 248 if (crtc->state->event) { 249 struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); 250 251 WARN_ON(drm_crtc_vblank_get(crtc)); 252 ipu_crtc->event = crtc->state->event; 253 crtc->state->event = NULL; 254 } 255 spin_unlock_irq(&crtc->dev->event_lock); 256} 257 258static void ipu_crtc_mode_set_nofb(struct drm_crtc *crtc) 259{ 260 struct drm_device *dev = crtc->dev; 261 struct drm_encoder *encoder; 262 struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); 263 struct drm_display_mode *mode = &crtc->state->adjusted_mode; 264 struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(crtc->state); 265 struct ipu_di_signal_cfg sig_cfg = {}; 266 unsigned long encoder_types = 0; 267 268 dev_dbg(ipu_crtc->dev, "%s: mode->hdisplay: %d\n", __func__, 269 mode->hdisplay); 270 dev_dbg(ipu_crtc->dev, "%s: mode->vdisplay: %d\n", __func__, 271 mode->vdisplay); 272 273 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 274 if (encoder->crtc == crtc) 275 encoder_types |= BIT(encoder->encoder_type); 276 } 277 278 dev_dbg(ipu_crtc->dev, "%s: attached to encoder types 0x%lx\n", 279 __func__, encoder_types); 280 281 /* 282 * If we have DAC or LDB, then we need the IPU DI clock to be 283 * the same as the LDB DI clock. For TVDAC, derive the IPU DI 284 * clock from 27 MHz TVE_DI clock, but allow to divide it. 285 */ 286 if (encoder_types & (BIT(DRM_MODE_ENCODER_DAC) | 287 BIT(DRM_MODE_ENCODER_LVDS))) 288 sig_cfg.clkflags = IPU_DI_CLKMODE_SYNC | IPU_DI_CLKMODE_EXT; 289 else if (encoder_types & BIT(DRM_MODE_ENCODER_TVDAC)) 290 sig_cfg.clkflags = IPU_DI_CLKMODE_EXT; 291 else 292 sig_cfg.clkflags = 0; 293 294 sig_cfg.enable_pol = !(imx_crtc_state->bus_flags & DRM_BUS_FLAG_DE_LOW); 295 /* Default to driving pixel data on negative clock edges */ 296 sig_cfg.clk_pol = !!(imx_crtc_state->bus_flags & 297 DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE); 298 sig_cfg.bus_format = imx_crtc_state->bus_format; 299 sig_cfg.v_to_h_sync = 0; 300 sig_cfg.hsync_pin = imx_crtc_state->di_hsync_pin; 301 sig_cfg.vsync_pin = imx_crtc_state->di_vsync_pin; 302 303 drm_display_mode_to_videomode(mode, &sig_cfg.mode); 304 305 ipu_dc_init_sync(ipu_crtc->dc, ipu_crtc->di, 306 mode->flags & DRM_MODE_FLAG_INTERLACE, 307 imx_crtc_state->bus_format, mode->hdisplay); 308 ipu_di_init_sync_panel(ipu_crtc->di, &sig_cfg); 309} 310 311static const struct drm_crtc_helper_funcs ipu_helper_funcs = { 312 .mode_fixup = ipu_crtc_mode_fixup, 313 .mode_set_nofb = ipu_crtc_mode_set_nofb, 314 .atomic_check = ipu_crtc_atomic_check, 315 .atomic_begin = ipu_crtc_atomic_begin, 316 .atomic_flush = ipu_crtc_atomic_flush, 317 .atomic_disable = ipu_crtc_atomic_disable, 318 .atomic_enable = ipu_crtc_atomic_enable, 319}; 320 321static void ipu_put_resources(struct ipu_crtc *ipu_crtc) 322{ 323 if (!IS_ERR_OR_NULL(ipu_crtc->dc)) 324 ipu_dc_put(ipu_crtc->dc); 325 if (!IS_ERR_OR_NULL(ipu_crtc->di)) 326 ipu_di_put(ipu_crtc->di); 327} 328 329static int ipu_get_resources(struct ipu_crtc *ipu_crtc, 330 struct ipu_client_platformdata *pdata) 331{ 332 struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent); 333 int ret; 334 335 ipu_crtc->dc = ipu_dc_get(ipu, pdata->dc); 336 if (IS_ERR(ipu_crtc->dc)) { 337 ret = PTR_ERR(ipu_crtc->dc); 338 goto err_out; 339 } 340 341 ipu_crtc->di = ipu_di_get(ipu, pdata->di); 342 if (IS_ERR(ipu_crtc->di)) { 343 ret = PTR_ERR(ipu_crtc->di); 344 goto err_out; 345 } 346 347 return 0; 348err_out: 349 ipu_put_resources(ipu_crtc); 350 351 return ret; 352} 353 354static int ipu_crtc_init(struct ipu_crtc *ipu_crtc, 355 struct ipu_client_platformdata *pdata, struct drm_device *drm) 356{ 357 struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent); 358 struct drm_crtc *crtc = &ipu_crtc->base; 359 int dp = -EINVAL; 360 int ret; 361 362 ret = ipu_get_resources(ipu_crtc, pdata); 363 if (ret) { 364 dev_err(ipu_crtc->dev, "getting resources failed with %d.\n", 365 ret); 366 return ret; 367 } 368 369 if (pdata->dp >= 0) 370 dp = IPU_DP_FLOW_SYNC_BG; 371 ipu_crtc->plane[0] = ipu_plane_init(drm, ipu, pdata->dma[0], dp, 0, 372 DRM_PLANE_TYPE_PRIMARY); 373 if (IS_ERR(ipu_crtc->plane[0])) { 374 ret = PTR_ERR(ipu_crtc->plane[0]); 375 goto err_put_resources; 376 } 377 378 crtc->port = pdata->of_node; 379 drm_crtc_helper_add(crtc, &ipu_helper_funcs); 380 drm_crtc_init_with_planes(drm, crtc, &ipu_crtc->plane[0]->base, NULL, 381 &ipu_crtc_funcs, NULL); 382 383 ret = ipu_plane_get_resources(ipu_crtc->plane[0]); 384 if (ret) { 385 dev_err(ipu_crtc->dev, "getting plane 0 resources failed with %d.\n", 386 ret); 387 goto err_put_resources; 388 } 389 390 /* If this crtc is using the DP, add an overlay plane */ 391 if (pdata->dp >= 0 && pdata->dma[1] > 0) { 392 ipu_crtc->plane[1] = ipu_plane_init(drm, ipu, pdata->dma[1], 393 IPU_DP_FLOW_SYNC_FG, 394 drm_crtc_mask(&ipu_crtc->base), 395 DRM_PLANE_TYPE_OVERLAY); 396 if (IS_ERR(ipu_crtc->plane[1])) { 397 ipu_crtc->plane[1] = NULL; 398 } else { 399 ret = ipu_plane_get_resources(ipu_crtc->plane[1]); 400 if (ret) { 401 dev_err(ipu_crtc->dev, "getting plane 1 " 402 "resources failed with %d.\n", ret); 403 goto err_put_plane0_res; 404 } 405 } 406 } 407 408 ipu_crtc->irq = ipu_plane_irq(ipu_crtc->plane[0]); 409 ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler, 0, 410 "imx_drm", ipu_crtc); 411 if (ret < 0) { 412 dev_err(ipu_crtc->dev, "irq request failed with %d.\n", ret); 413 goto err_put_plane1_res; 414 } 415 /* Only enable IRQ when we actually need it to trigger work. */ 416 disable_irq(ipu_crtc->irq); 417 418 return 0; 419 420err_put_plane1_res: 421 if (ipu_crtc->plane[1]) 422 ipu_plane_put_resources(ipu_crtc->plane[1]); 423err_put_plane0_res: 424 ipu_plane_put_resources(ipu_crtc->plane[0]); 425err_put_resources: 426 ipu_put_resources(ipu_crtc); 427 428 return ret; 429} 430 431static int ipu_drm_bind(struct device *dev, struct device *master, void *data) 432{ 433 struct ipu_client_platformdata *pdata = dev->platform_data; 434 struct drm_device *drm = data; 435 struct ipu_crtc *ipu_crtc; 436 437 ipu_crtc = dev_get_drvdata(dev); 438 memset(ipu_crtc, 0, sizeof(*ipu_crtc)); 439 440 ipu_crtc->dev = dev; 441 442 return ipu_crtc_init(ipu_crtc, pdata, drm); 443} 444 445static void ipu_drm_unbind(struct device *dev, struct device *master, 446 void *data) 447{ 448 struct ipu_crtc *ipu_crtc = dev_get_drvdata(dev); 449 450 ipu_put_resources(ipu_crtc); 451 if (ipu_crtc->plane[1]) 452 ipu_plane_put_resources(ipu_crtc->plane[1]); 453 ipu_plane_put_resources(ipu_crtc->plane[0]); 454} 455 456static const struct component_ops ipu_crtc_ops = { 457 .bind = ipu_drm_bind, 458 .unbind = ipu_drm_unbind, 459}; 460 461static int ipu_drm_probe(struct platform_device *pdev) 462{ 463 struct device *dev = &pdev->dev; 464 struct ipu_crtc *ipu_crtc; 465 int ret; 466 467 if (!dev->platform_data) 468 return -EINVAL; 469 470 ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); 471 if (ret) 472 return ret; 473 474 ipu_crtc = devm_kzalloc(dev, sizeof(*ipu_crtc), GFP_KERNEL); 475 if (!ipu_crtc) 476 return -ENOMEM; 477 478 dev_set_drvdata(dev, ipu_crtc); 479 480 return component_add(dev, &ipu_crtc_ops); 481} 482 483static int ipu_drm_remove(struct platform_device *pdev) 484{ 485 component_del(&pdev->dev, &ipu_crtc_ops); 486 return 0; 487} 488 489struct platform_driver ipu_drm_driver = { 490 .driver = { 491 .name = "imx-ipuv3-crtc", 492 }, 493 .probe = ipu_drm_probe, 494 .remove = ipu_drm_remove, 495}; 496