1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * i.MX IPUv3 DP Overlay Planes 4 * 5 * Copyright (C) 2013 Philipp Zabel, Pengutronix 6 */ 7 8 #include <drm/drm_atomic.h> 9 #include <drm/drm_atomic_helper.h> 10 #include <drm/drm_blend.h> 11 #include <drm/drm_fb_dma_helper.h> 12 #include <drm/drm_fourcc.h> 13 #include <drm/drm_framebuffer.h> 14 #include <drm/drm_gem_atomic_helper.h> 15 #include <drm/drm_gem_dma_helper.h> 16 #include <drm/drm_managed.h> 17 18 #include <video/imx-ipu-v3.h> 19 20 #include "imx-drm.h" 21 #include "ipuv3-plane.h" 22 23 struct ipu_plane_state { 24 struct drm_plane_state base; 25 bool use_pre; 26 }; 27 28 static inline struct ipu_plane_state * 29 to_ipu_plane_state(struct drm_plane_state *p) 30 { 31 return container_of(p, struct ipu_plane_state, base); 32 } 33 34 static unsigned int ipu_src_rect_width(const struct drm_plane_state *state) 35 { 36 return ALIGN(drm_rect_width(&state->src) >> 16, 8); 37 } 38 39 static inline struct ipu_plane *to_ipu_plane(struct drm_plane *p) 40 { 41 return container_of(p, struct ipu_plane, base); 42 } 43 44 static const uint32_t ipu_plane_all_formats[] = { 45 DRM_FORMAT_ARGB1555, 46 DRM_FORMAT_XRGB1555, 47 DRM_FORMAT_ABGR1555, 48 DRM_FORMAT_XBGR1555, 49 DRM_FORMAT_RGBA5551, 50 DRM_FORMAT_BGRA5551, 51 DRM_FORMAT_ARGB4444, 52 DRM_FORMAT_ARGB8888, 53 DRM_FORMAT_XRGB8888, 54 DRM_FORMAT_ABGR8888, 55 DRM_FORMAT_XBGR8888, 56 DRM_FORMAT_RGBA8888, 57 DRM_FORMAT_RGBX8888, 58 DRM_FORMAT_BGRA8888, 59 DRM_FORMAT_BGRX8888, 60 DRM_FORMAT_UYVY, 61 DRM_FORMAT_VYUY, 62 DRM_FORMAT_YUYV, 63 DRM_FORMAT_YVYU, 64 DRM_FORMAT_YUV420, 65 DRM_FORMAT_YVU420, 66 DRM_FORMAT_YUV422, 67 DRM_FORMAT_YVU422, 68 DRM_FORMAT_YUV444, 69 DRM_FORMAT_YVU444, 70 DRM_FORMAT_NV12, 71 DRM_FORMAT_NV16, 72 DRM_FORMAT_RGB565, 73 DRM_FORMAT_RGB565_A8, 74 DRM_FORMAT_BGR565_A8, 75 DRM_FORMAT_RGB888_A8, 76 DRM_FORMAT_BGR888_A8, 77 DRM_FORMAT_RGBX8888_A8, 78 DRM_FORMAT_BGRX8888_A8, 79 }; 80 81 static const uint32_t ipu_plane_rgb_formats[] = { 82 DRM_FORMAT_ARGB1555, 83 DRM_FORMAT_XRGB1555, 84 DRM_FORMAT_ABGR1555, 85 DRM_FORMAT_XBGR1555, 86 DRM_FORMAT_RGBA5551, 87 DRM_FORMAT_BGRA5551, 88 DRM_FORMAT_ARGB4444, 89 DRM_FORMAT_ARGB8888, 90 DRM_FORMAT_XRGB8888, 91 DRM_FORMAT_ABGR8888, 92 DRM_FORMAT_XBGR8888, 93 DRM_FORMAT_RGBA8888, 94 DRM_FORMAT_RGBX8888, 95 DRM_FORMAT_BGRA8888, 96 DRM_FORMAT_BGRX8888, 97 DRM_FORMAT_RGB565, 98 DRM_FORMAT_RGB565_A8, 99 DRM_FORMAT_BGR565_A8, 100 DRM_FORMAT_RGB888_A8, 101 DRM_FORMAT_BGR888_A8, 102 DRM_FORMAT_RGBX8888_A8, 103 DRM_FORMAT_BGRX8888_A8, 104 }; 105 106 static const uint64_t ipu_format_modifiers[] = { 107 DRM_FORMAT_MOD_LINEAR, 108 DRM_FORMAT_MOD_INVALID 109 }; 110 111 static const uint64_t pre_format_modifiers[] = { 112 DRM_FORMAT_MOD_LINEAR, 113 DRM_FORMAT_MOD_VIVANTE_TILED, 114 DRM_FORMAT_MOD_VIVANTE_SUPER_TILED, 115 DRM_FORMAT_MOD_INVALID 116 }; 117 118 int ipu_plane_irq(struct ipu_plane *ipu_plane) 119 { 120 return ipu_idmac_channel_irq(ipu_plane->ipu, ipu_plane->ipu_ch, 121 IPU_IRQ_EOF); 122 } 123 124 static inline unsigned long 125 drm_plane_state_to_eba(struct drm_plane_state *state, int plane) 126 { 127 struct drm_framebuffer *fb = state->fb; 128 struct drm_gem_dma_object *dma_obj; 129 int x = state->src.x1 >> 16; 130 int y = state->src.y1 >> 16; 131 132 dma_obj = drm_fb_dma_get_gem_obj(fb, plane); 133 BUG_ON(!dma_obj); 134 135 return dma_obj->dma_addr + fb->offsets[plane] + fb->pitches[plane] * y + 136 fb->format->cpp[plane] * x; 137 } 138 139 static inline unsigned long 140 drm_plane_state_to_ubo(struct drm_plane_state *state) 141 { 142 struct drm_framebuffer *fb = state->fb; 143 struct drm_gem_dma_object *dma_obj; 144 unsigned long eba = drm_plane_state_to_eba(state, 0); 145 int x = state->src.x1 >> 16; 146 int y = state->src.y1 >> 16; 147 148 dma_obj = drm_fb_dma_get_gem_obj(fb, 1); 149 BUG_ON(!dma_obj); 150 151 x /= fb->format->hsub; 152 y /= fb->format->vsub; 153 154 return dma_obj->dma_addr + fb->offsets[1] + fb->pitches[1] * y + 155 fb->format->cpp[1] * x - eba; 156 } 157 158 static inline unsigned long 159 drm_plane_state_to_vbo(struct drm_plane_state *state) 160 { 161 struct drm_framebuffer *fb = state->fb; 162 struct drm_gem_dma_object *dma_obj; 163 unsigned long eba = drm_plane_state_to_eba(state, 0); 164 int x = state->src.x1 >> 16; 165 int y = state->src.y1 >> 16; 166 167 dma_obj = drm_fb_dma_get_gem_obj(fb, 2); 168 BUG_ON(!dma_obj); 169 170 x /= fb->format->hsub; 171 y /= fb->format->vsub; 172 173 return dma_obj->dma_addr + fb->offsets[2] + fb->pitches[2] * y + 174 fb->format->cpp[2] * x - eba; 175 } 176 177 static void ipu_plane_put_resources(struct drm_device *dev, void *ptr) 178 { 179 struct ipu_plane *ipu_plane = ptr; 180 181 if (!IS_ERR_OR_NULL(ipu_plane->dp)) 182 ipu_dp_put(ipu_plane->dp); 183 if (!IS_ERR_OR_NULL(ipu_plane->dmfc)) 184 ipu_dmfc_put(ipu_plane->dmfc); 185 if (!IS_ERR_OR_NULL(ipu_plane->ipu_ch)) 186 ipu_idmac_put(ipu_plane->ipu_ch); 187 if (!IS_ERR_OR_NULL(ipu_plane->alpha_ch)) 188 ipu_idmac_put(ipu_plane->alpha_ch); 189 } 190 191 static int ipu_plane_get_resources(struct drm_device *dev, 192 struct ipu_plane *ipu_plane) 193 { 194 int ret; 195 int alpha_ch; 196 197 ipu_plane->ipu_ch = ipu_idmac_get(ipu_plane->ipu, ipu_plane->dma); 198 if (IS_ERR(ipu_plane->ipu_ch)) { 199 ret = PTR_ERR(ipu_plane->ipu_ch); 200 DRM_ERROR("failed to get idmac channel: %d\n", ret); 201 return ret; 202 } 203 204 ret = drmm_add_action_or_reset(dev, ipu_plane_put_resources, ipu_plane); 205 if (ret) 206 return ret; 207 208 alpha_ch = ipu_channel_alpha_channel(ipu_plane->dma); 209 if (alpha_ch >= 0) { 210 ipu_plane->alpha_ch = ipu_idmac_get(ipu_plane->ipu, alpha_ch); 211 if (IS_ERR(ipu_plane->alpha_ch)) { 212 ret = PTR_ERR(ipu_plane->alpha_ch); 213 DRM_ERROR("failed to get alpha idmac channel %d: %d\n", 214 alpha_ch, ret); 215 return ret; 216 } 217 } 218 219 ipu_plane->dmfc = ipu_dmfc_get(ipu_plane->ipu, ipu_plane->dma); 220 if (IS_ERR(ipu_plane->dmfc)) { 221 ret = PTR_ERR(ipu_plane->dmfc); 222 DRM_ERROR("failed to get dmfc: ret %d\n", ret); 223 return ret; 224 } 225 226 if (ipu_plane->dp_flow >= 0) { 227 ipu_plane->dp = ipu_dp_get(ipu_plane->ipu, ipu_plane->dp_flow); 228 if (IS_ERR(ipu_plane->dp)) { 229 ret = PTR_ERR(ipu_plane->dp); 230 DRM_ERROR("failed to get dp flow: %d\n", ret); 231 return ret; 232 } 233 } 234 235 return 0; 236 } 237 238 static bool ipu_plane_separate_alpha(struct ipu_plane *ipu_plane) 239 { 240 switch (ipu_plane->base.state->fb->format->format) { 241 case DRM_FORMAT_RGB565_A8: 242 case DRM_FORMAT_BGR565_A8: 243 case DRM_FORMAT_RGB888_A8: 244 case DRM_FORMAT_BGR888_A8: 245 case DRM_FORMAT_RGBX8888_A8: 246 case DRM_FORMAT_BGRX8888_A8: 247 return true; 248 default: 249 return false; 250 } 251 } 252 253 static void ipu_plane_enable(struct ipu_plane *ipu_plane) 254 { 255 if (ipu_plane->dp) 256 ipu_dp_enable(ipu_plane->ipu); 257 ipu_dmfc_enable_channel(ipu_plane->dmfc); 258 ipu_idmac_enable_channel(ipu_plane->ipu_ch); 259 if (ipu_plane_separate_alpha(ipu_plane)) 260 ipu_idmac_enable_channel(ipu_plane->alpha_ch); 261 if (ipu_plane->dp) 262 ipu_dp_enable_channel(ipu_plane->dp); 263 } 264 265 void ipu_plane_disable(struct ipu_plane *ipu_plane, bool disable_dp_channel) 266 { 267 int ret; 268 269 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); 270 271 ret = ipu_idmac_wait_busy(ipu_plane->ipu_ch, 50); 272 if (ret == -ETIMEDOUT) { 273 DRM_ERROR("[PLANE:%d] IDMAC timeout\n", 274 ipu_plane->base.base.id); 275 } 276 277 if (ipu_plane->dp && disable_dp_channel) 278 ipu_dp_disable_channel(ipu_plane->dp, false); 279 ipu_idmac_disable_channel(ipu_plane->ipu_ch); 280 if (ipu_plane->alpha_ch) 281 ipu_idmac_disable_channel(ipu_plane->alpha_ch); 282 ipu_dmfc_disable_channel(ipu_plane->dmfc); 283 if (ipu_plane->dp) 284 ipu_dp_disable(ipu_plane->ipu); 285 if (ipu_prg_present(ipu_plane->ipu)) 286 ipu_prg_channel_disable(ipu_plane->ipu_ch); 287 } 288 289 void ipu_plane_disable_deferred(struct drm_plane *plane) 290 { 291 struct ipu_plane *ipu_plane = to_ipu_plane(plane); 292 293 if (ipu_plane->disabling) { 294 ipu_plane->disabling = false; 295 ipu_plane_disable(ipu_plane, false); 296 } 297 } 298 299 static void ipu_plane_state_reset(struct drm_plane *plane) 300 { 301 struct ipu_plane_state *ipu_state; 302 303 if (plane->state) { 304 ipu_state = to_ipu_plane_state(plane->state); 305 __drm_atomic_helper_plane_destroy_state(plane->state); 306 kfree(ipu_state); 307 plane->state = NULL; 308 } 309 310 ipu_state = kzalloc(sizeof(*ipu_state), GFP_KERNEL); 311 312 if (ipu_state) 313 __drm_atomic_helper_plane_reset(plane, &ipu_state->base); 314 } 315 316 static struct drm_plane_state * 317 ipu_plane_duplicate_state(struct drm_plane *plane) 318 { 319 struct ipu_plane_state *state; 320 321 if (WARN_ON(!plane->state)) 322 return NULL; 323 324 state = kmalloc(sizeof(*state), GFP_KERNEL); 325 if (state) 326 __drm_atomic_helper_plane_duplicate_state(plane, &state->base); 327 328 return &state->base; 329 } 330 331 static void ipu_plane_destroy_state(struct drm_plane *plane, 332 struct drm_plane_state *state) 333 { 334 struct ipu_plane_state *ipu_state = to_ipu_plane_state(state); 335 336 __drm_atomic_helper_plane_destroy_state(state); 337 kfree(ipu_state); 338 } 339 340 static bool ipu_plane_format_mod_supported(struct drm_plane *plane, 341 uint32_t format, uint64_t modifier) 342 { 343 struct ipu_soc *ipu = to_ipu_plane(plane)->ipu; 344 345 /* linear is supported for all planes and formats */ 346 if (modifier == DRM_FORMAT_MOD_LINEAR) 347 return true; 348 349 /* 350 * Without a PRG the possible modifiers list only includes the linear 351 * modifier, so we always take the early return from this function and 352 * only end up here if the PRG is present. 353 */ 354 return ipu_prg_format_supported(ipu, format, modifier); 355 } 356 357 static const struct drm_plane_funcs ipu_plane_funcs = { 358 .update_plane = drm_atomic_helper_update_plane, 359 .disable_plane = drm_atomic_helper_disable_plane, 360 .reset = ipu_plane_state_reset, 361 .atomic_duplicate_state = ipu_plane_duplicate_state, 362 .atomic_destroy_state = ipu_plane_destroy_state, 363 .format_mod_supported = ipu_plane_format_mod_supported, 364 }; 365 366 static int ipu_plane_atomic_check(struct drm_plane *plane, 367 struct drm_atomic_state *state) 368 { 369 struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, 370 plane); 371 struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state, 372 plane); 373 struct drm_crtc_state *crtc_state; 374 struct device *dev = plane->dev->dev; 375 struct drm_framebuffer *fb = new_state->fb; 376 struct drm_framebuffer *old_fb = old_state->fb; 377 unsigned long eba, ubo, vbo, old_ubo, old_vbo, alpha_eba; 378 bool can_position = (plane->type == DRM_PLANE_TYPE_OVERLAY); 379 int ret; 380 381 /* Ok to disable */ 382 if (!fb) 383 return 0; 384 385 if (WARN_ON(!new_state->crtc)) 386 return -EINVAL; 387 388 crtc_state = 389 drm_atomic_get_existing_crtc_state(state, 390 new_state->crtc); 391 if (WARN_ON(!crtc_state)) 392 return -EINVAL; 393 394 ret = drm_atomic_helper_check_plane_state(new_state, crtc_state, 395 DRM_PLANE_NO_SCALING, 396 DRM_PLANE_NO_SCALING, 397 can_position, true); 398 if (ret) 399 return ret; 400 401 /* nothing to check when disabling or disabled */ 402 if (!crtc_state->enable) 403 return 0; 404 405 switch (plane->type) { 406 case DRM_PLANE_TYPE_PRIMARY: 407 /* full plane minimum width is 13 pixels */ 408 if (drm_rect_width(&new_state->dst) < 13) 409 return -EINVAL; 410 break; 411 case DRM_PLANE_TYPE_OVERLAY: 412 break; 413 default: 414 dev_warn(dev, "Unsupported plane type %d\n", plane->type); 415 return -EINVAL; 416 } 417 418 if (drm_rect_height(&new_state->dst) < 2) 419 return -EINVAL; 420 421 /* 422 * We support resizing active plane or changing its format by 423 * forcing CRTC mode change in plane's ->atomic_check callback 424 * and disabling all affected active planes in CRTC's ->atomic_disable 425 * callback. The planes will be reenabled in plane's ->atomic_update 426 * callback. 427 */ 428 if (old_fb && 429 (drm_rect_width(&new_state->dst) != drm_rect_width(&old_state->dst) || 430 drm_rect_height(&new_state->dst) != drm_rect_height(&old_state->dst) || 431 fb->format != old_fb->format)) 432 crtc_state->mode_changed = true; 433 434 eba = drm_plane_state_to_eba(new_state, 0); 435 436 if (eba & 0x7) 437 return -EINVAL; 438 439 if (fb->pitches[0] < 1 || fb->pitches[0] > 16384) 440 return -EINVAL; 441 442 if (old_fb && fb->pitches[0] != old_fb->pitches[0]) 443 crtc_state->mode_changed = true; 444 445 if (ALIGN(fb->width, 8) * fb->format->cpp[0] > 446 fb->pitches[0] + fb->offsets[0]) { 447 dev_warn(dev, "pitch is not big enough for 8 pixels alignment"); 448 return -EINVAL; 449 } 450 451 switch (fb->format->format) { 452 case DRM_FORMAT_YUV420: 453 case DRM_FORMAT_YVU420: 454 case DRM_FORMAT_YUV422: 455 case DRM_FORMAT_YVU422: 456 case DRM_FORMAT_YUV444: 457 case DRM_FORMAT_YVU444: 458 /* 459 * Multiplanar formats have to meet the following restrictions: 460 * - The (up to) three plane addresses are EBA, EBA+UBO, EBA+VBO 461 * - EBA, UBO and VBO are a multiple of 8 462 * - UBO and VBO are unsigned and not larger than 0xfffff8 463 * - Only EBA may be changed while scanout is active 464 * - The strides of U and V planes must be identical. 465 */ 466 vbo = drm_plane_state_to_vbo(new_state); 467 468 if (vbo & 0x7 || vbo > 0xfffff8) 469 return -EINVAL; 470 471 if (old_fb && (fb->format == old_fb->format)) { 472 old_vbo = drm_plane_state_to_vbo(old_state); 473 if (vbo != old_vbo) 474 crtc_state->mode_changed = true; 475 } 476 477 if (fb->pitches[1] != fb->pitches[2]) 478 return -EINVAL; 479 480 fallthrough; 481 case DRM_FORMAT_NV12: 482 case DRM_FORMAT_NV16: 483 ubo = drm_plane_state_to_ubo(new_state); 484 485 if (ubo & 0x7 || ubo > 0xfffff8) 486 return -EINVAL; 487 488 if (old_fb && (fb->format == old_fb->format)) { 489 old_ubo = drm_plane_state_to_ubo(old_state); 490 if (ubo != old_ubo) 491 crtc_state->mode_changed = true; 492 } 493 494 if (fb->pitches[1] < 1 || fb->pitches[1] > 16384) 495 return -EINVAL; 496 497 if (old_fb && old_fb->pitches[1] != fb->pitches[1]) 498 crtc_state->mode_changed = true; 499 500 /* 501 * The x/y offsets must be even in case of horizontal/vertical 502 * chroma subsampling. 503 */ 504 if (((new_state->src.x1 >> 16) & (fb->format->hsub - 1)) || 505 ((new_state->src.y1 >> 16) & (fb->format->vsub - 1))) 506 return -EINVAL; 507 break; 508 case DRM_FORMAT_RGB565_A8: 509 case DRM_FORMAT_BGR565_A8: 510 case DRM_FORMAT_RGB888_A8: 511 case DRM_FORMAT_BGR888_A8: 512 case DRM_FORMAT_RGBX8888_A8: 513 case DRM_FORMAT_BGRX8888_A8: 514 alpha_eba = drm_plane_state_to_eba(new_state, 1); 515 if (alpha_eba & 0x7) 516 return -EINVAL; 517 518 if (fb->pitches[1] < 1 || fb->pitches[1] > 16384) 519 return -EINVAL; 520 521 if (old_fb && old_fb->pitches[1] != fb->pitches[1]) 522 crtc_state->mode_changed = true; 523 break; 524 } 525 526 return 0; 527 } 528 529 static void ipu_plane_atomic_disable(struct drm_plane *plane, 530 struct drm_atomic_state *state) 531 { 532 struct ipu_plane *ipu_plane = to_ipu_plane(plane); 533 534 if (ipu_plane->dp) 535 ipu_dp_disable_channel(ipu_plane->dp, true); 536 ipu_plane->disabling = true; 537 } 538 539 static int ipu_chan_assign_axi_id(int ipu_chan) 540 { 541 switch (ipu_chan) { 542 case IPUV3_CHANNEL_MEM_BG_SYNC: 543 return 1; 544 case IPUV3_CHANNEL_MEM_FG_SYNC: 545 return 2; 546 case IPUV3_CHANNEL_MEM_DC_SYNC: 547 return 3; 548 default: 549 return 0; 550 } 551 } 552 553 static void ipu_calculate_bursts(u32 width, u32 cpp, u32 stride, 554 u8 *burstsize, u8 *num_bursts) 555 { 556 const unsigned int width_bytes = width * cpp; 557 unsigned int npb, bursts; 558 559 /* Maximum number of pixels per burst without overshooting stride */ 560 for (npb = 64 / cpp; npb > 0; --npb) { 561 if (round_up(width_bytes, npb * cpp) <= stride) 562 break; 563 } 564 *burstsize = npb; 565 566 /* Maximum number of consecutive bursts without overshooting stride */ 567 for (bursts = 8; bursts > 1; bursts /= 2) { 568 if (round_up(width_bytes, npb * cpp * bursts) <= stride) 569 break; 570 } 571 *num_bursts = bursts; 572 } 573 574 static void ipu_plane_atomic_update(struct drm_plane *plane, 575 struct drm_atomic_state *state) 576 { 577 struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state, 578 plane); 579 struct ipu_plane *ipu_plane = to_ipu_plane(plane); 580 struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, 581 plane); 582 struct ipu_plane_state *ipu_state = to_ipu_plane_state(new_state); 583 struct drm_crtc_state *crtc_state = new_state->crtc->state; 584 struct drm_framebuffer *fb = new_state->fb; 585 struct drm_rect *dst = &new_state->dst; 586 unsigned long eba, ubo, vbo; 587 unsigned long alpha_eba = 0; 588 enum ipu_color_space ics; 589 unsigned int axi_id = 0; 590 const struct drm_format_info *info; 591 u8 burstsize, num_bursts; 592 u32 width, height; 593 int active; 594 595 if (ipu_plane->dp_flow == IPU_DP_FLOW_SYNC_FG) 596 ipu_dp_set_window_pos(ipu_plane->dp, dst->x1, dst->y1); 597 598 switch (ipu_plane->dp_flow) { 599 case IPU_DP_FLOW_SYNC_BG: 600 if (new_state->normalized_zpos == 1) { 601 ipu_dp_set_global_alpha(ipu_plane->dp, 602 !fb->format->has_alpha, 0xff, 603 true); 604 } else { 605 ipu_dp_set_global_alpha(ipu_plane->dp, true, 0, true); 606 } 607 break; 608 case IPU_DP_FLOW_SYNC_FG: 609 if (new_state->normalized_zpos == 1) { 610 ipu_dp_set_global_alpha(ipu_plane->dp, 611 !fb->format->has_alpha, 0xff, 612 false); 613 } 614 break; 615 } 616 617 if (ipu_plane->dp_flow == IPU_DP_FLOW_SYNC_BG) 618 width = ipu_src_rect_width(new_state); 619 else 620 width = drm_rect_width(&new_state->src) >> 16; 621 height = drm_rect_height(&new_state->src) >> 16; 622 623 eba = drm_plane_state_to_eba(new_state, 0); 624 625 /* 626 * Configure PRG channel and attached PRE, this changes the EBA to an 627 * internal SRAM location. 628 */ 629 if (ipu_state->use_pre) { 630 axi_id = ipu_chan_assign_axi_id(ipu_plane->dma); 631 ipu_prg_channel_configure(ipu_plane->ipu_ch, axi_id, width, 632 height, fb->pitches[0], 633 fb->format->format, fb->modifier, 634 &eba); 635 } 636 637 if (!old_state->fb || 638 old_state->fb->format->format != fb->format->format || 639 old_state->color_encoding != new_state->color_encoding || 640 old_state->color_range != new_state->color_range) { 641 ics = ipu_drm_fourcc_to_colorspace(fb->format->format); 642 switch (ipu_plane->dp_flow) { 643 case IPU_DP_FLOW_SYNC_BG: 644 ipu_dp_setup_channel(ipu_plane->dp, new_state->color_encoding, 645 new_state->color_range, ics, 646 IPUV3_COLORSPACE_RGB); 647 break; 648 case IPU_DP_FLOW_SYNC_FG: 649 ipu_dp_setup_channel(ipu_plane->dp, new_state->color_encoding, 650 new_state->color_range, ics, 651 IPUV3_COLORSPACE_UNKNOWN); 652 break; 653 } 654 } 655 656 if (old_state->fb && !drm_atomic_crtc_needs_modeset(crtc_state)) { 657 /* nothing to do if PRE is used */ 658 if (ipu_state->use_pre) 659 return; 660 active = ipu_idmac_get_current_buffer(ipu_plane->ipu_ch); 661 ipu_cpmem_set_buffer(ipu_plane->ipu_ch, !active, eba); 662 ipu_idmac_select_buffer(ipu_plane->ipu_ch, !active); 663 if (ipu_plane_separate_alpha(ipu_plane)) { 664 active = ipu_idmac_get_current_buffer(ipu_plane->alpha_ch); 665 ipu_cpmem_set_buffer(ipu_plane->alpha_ch, !active, 666 alpha_eba); 667 ipu_idmac_select_buffer(ipu_plane->alpha_ch, !active); 668 } 669 return; 670 } 671 672 ics = ipu_drm_fourcc_to_colorspace(fb->format->format); 673 switch (ipu_plane->dp_flow) { 674 case IPU_DP_FLOW_SYNC_BG: 675 ipu_dp_setup_channel(ipu_plane->dp, DRM_COLOR_YCBCR_BT601, 676 DRM_COLOR_YCBCR_LIMITED_RANGE, ics, 677 IPUV3_COLORSPACE_RGB); 678 break; 679 case IPU_DP_FLOW_SYNC_FG: 680 ipu_dp_setup_channel(ipu_plane->dp, DRM_COLOR_YCBCR_BT601, 681 DRM_COLOR_YCBCR_LIMITED_RANGE, ics, 682 IPUV3_COLORSPACE_UNKNOWN); 683 break; 684 } 685 686 ipu_dmfc_config_wait4eot(ipu_plane->dmfc, width); 687 688 info = drm_format_info(fb->format->format); 689 ipu_calculate_bursts(width, info->cpp[0], fb->pitches[0], 690 &burstsize, &num_bursts); 691 692 ipu_cpmem_zero(ipu_plane->ipu_ch); 693 ipu_cpmem_set_resolution(ipu_plane->ipu_ch, width, height); 694 ipu_cpmem_set_fmt(ipu_plane->ipu_ch, fb->format->format); 695 ipu_cpmem_set_burstsize(ipu_plane->ipu_ch, burstsize); 696 ipu_cpmem_set_high_priority(ipu_plane->ipu_ch); 697 ipu_idmac_enable_watermark(ipu_plane->ipu_ch, true); 698 ipu_idmac_set_double_buffer(ipu_plane->ipu_ch, 1); 699 ipu_cpmem_set_stride(ipu_plane->ipu_ch, fb->pitches[0]); 700 ipu_cpmem_set_axi_id(ipu_plane->ipu_ch, axi_id); 701 702 switch (fb->format->format) { 703 case DRM_FORMAT_YUV420: 704 case DRM_FORMAT_YVU420: 705 case DRM_FORMAT_YUV422: 706 case DRM_FORMAT_YVU422: 707 case DRM_FORMAT_YUV444: 708 case DRM_FORMAT_YVU444: 709 ubo = drm_plane_state_to_ubo(new_state); 710 vbo = drm_plane_state_to_vbo(new_state); 711 if (fb->format->format == DRM_FORMAT_YVU420 || 712 fb->format->format == DRM_FORMAT_YVU422 || 713 fb->format->format == DRM_FORMAT_YVU444) 714 swap(ubo, vbo); 715 716 ipu_cpmem_set_yuv_planar_full(ipu_plane->ipu_ch, 717 fb->pitches[1], ubo, vbo); 718 719 dev_dbg(ipu_plane->base.dev->dev, 720 "phy = %lu %lu %lu, x = %d, y = %d", eba, ubo, vbo, 721 new_state->src.x1 >> 16, new_state->src.y1 >> 16); 722 break; 723 case DRM_FORMAT_NV12: 724 case DRM_FORMAT_NV16: 725 ubo = drm_plane_state_to_ubo(new_state); 726 727 ipu_cpmem_set_yuv_planar_full(ipu_plane->ipu_ch, 728 fb->pitches[1], ubo, ubo); 729 730 dev_dbg(ipu_plane->base.dev->dev, 731 "phy = %lu %lu, x = %d, y = %d", eba, ubo, 732 new_state->src.x1 >> 16, new_state->src.y1 >> 16); 733 break; 734 case DRM_FORMAT_RGB565_A8: 735 case DRM_FORMAT_BGR565_A8: 736 case DRM_FORMAT_RGB888_A8: 737 case DRM_FORMAT_BGR888_A8: 738 case DRM_FORMAT_RGBX8888_A8: 739 case DRM_FORMAT_BGRX8888_A8: 740 alpha_eba = drm_plane_state_to_eba(new_state, 1); 741 num_bursts = 0; 742 743 dev_dbg(ipu_plane->base.dev->dev, "phys = %lu %lu, x = %d, y = %d", 744 eba, alpha_eba, new_state->src.x1 >> 16, 745 new_state->src.y1 >> 16); 746 747 ipu_cpmem_set_burstsize(ipu_plane->ipu_ch, 16); 748 749 ipu_cpmem_zero(ipu_plane->alpha_ch); 750 ipu_cpmem_set_resolution(ipu_plane->alpha_ch, width, height); 751 ipu_cpmem_set_format_passthrough(ipu_plane->alpha_ch, 8); 752 ipu_cpmem_set_high_priority(ipu_plane->alpha_ch); 753 ipu_idmac_set_double_buffer(ipu_plane->alpha_ch, 1); 754 ipu_cpmem_set_stride(ipu_plane->alpha_ch, fb->pitches[1]); 755 ipu_cpmem_set_burstsize(ipu_plane->alpha_ch, 16); 756 ipu_cpmem_set_buffer(ipu_plane->alpha_ch, 0, alpha_eba); 757 ipu_cpmem_set_buffer(ipu_plane->alpha_ch, 1, alpha_eba); 758 break; 759 default: 760 dev_dbg(ipu_plane->base.dev->dev, "phys = %lu, x = %d, y = %d", 761 eba, new_state->src.x1 >> 16, new_state->src.y1 >> 16); 762 break; 763 } 764 ipu_cpmem_set_buffer(ipu_plane->ipu_ch, 0, eba); 765 ipu_cpmem_set_buffer(ipu_plane->ipu_ch, 1, eba); 766 ipu_idmac_lock_enable(ipu_plane->ipu_ch, num_bursts); 767 ipu_plane_enable(ipu_plane); 768 } 769 770 static const struct drm_plane_helper_funcs ipu_plane_helper_funcs = { 771 .atomic_check = ipu_plane_atomic_check, 772 .atomic_disable = ipu_plane_atomic_disable, 773 .atomic_update = ipu_plane_atomic_update, 774 }; 775 776 static const struct drm_plane_helper_funcs ipu_primary_plane_helper_funcs = { 777 .atomic_check = ipu_plane_atomic_check, 778 .atomic_disable = ipu_plane_atomic_disable, 779 .atomic_update = ipu_plane_atomic_update, 780 .get_scanout_buffer = drm_fb_dma_get_scanout_buffer, 781 }; 782 783 bool ipu_plane_atomic_update_pending(struct drm_plane *plane) 784 { 785 struct ipu_plane *ipu_plane = to_ipu_plane(plane); 786 struct drm_plane_state *state = plane->state; 787 struct ipu_plane_state *ipu_state = to_ipu_plane_state(state); 788 789 /* disabled crtcs must not block the update */ 790 if (!state->crtc) 791 return false; 792 793 if (ipu_state->use_pre) 794 return ipu_prg_channel_configure_pending(ipu_plane->ipu_ch); 795 796 /* 797 * Pretend no update is pending in the non-PRE/PRG case. For this to 798 * happen, an atomic update would have to be deferred until after the 799 * start of the next frame and simultaneously interrupt latency would 800 * have to be high enough to let the atomic update finish and issue an 801 * event before the previous end of frame interrupt handler can be 802 * executed. 803 */ 804 return false; 805 } 806 int ipu_planes_assign_pre(struct drm_device *dev, 807 struct drm_atomic_state *state) 808 { 809 struct drm_crtc_state *old_crtc_state, *crtc_state; 810 struct drm_plane_state *plane_state; 811 struct ipu_plane_state *ipu_state; 812 struct ipu_plane *ipu_plane; 813 struct drm_plane *plane; 814 struct drm_crtc *crtc; 815 int available_pres = ipu_prg_max_active_channels(); 816 int ret, i; 817 818 for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, crtc_state, i) { 819 ret = drm_atomic_add_affected_planes(state, crtc); 820 if (ret) 821 return ret; 822 } 823 824 /* 825 * We are going over the planes in 2 passes: first we assign PREs to 826 * planes with a tiling modifier, which need the PREs to resolve into 827 * linear. Any failure to assign a PRE there is fatal. In the second 828 * pass we try to assign PREs to linear FBs, to improve memory access 829 * patterns for them. Failure at this point is non-fatal, as we can 830 * scan out linear FBs without a PRE. 831 */ 832 for_each_new_plane_in_state(state, plane, plane_state, i) { 833 ipu_state = to_ipu_plane_state(plane_state); 834 ipu_plane = to_ipu_plane(plane); 835 836 if (!plane_state->fb) { 837 ipu_state->use_pre = false; 838 continue; 839 } 840 841 if (!(plane_state->fb->flags & DRM_MODE_FB_MODIFIERS) || 842 plane_state->fb->modifier == DRM_FORMAT_MOD_LINEAR) 843 continue; 844 845 if (!ipu_prg_present(ipu_plane->ipu) || !available_pres) 846 return -EINVAL; 847 848 if (!ipu_prg_format_supported(ipu_plane->ipu, 849 plane_state->fb->format->format, 850 plane_state->fb->modifier)) 851 return -EINVAL; 852 853 ipu_state->use_pre = true; 854 available_pres--; 855 } 856 857 for_each_new_plane_in_state(state, plane, plane_state, i) { 858 ipu_state = to_ipu_plane_state(plane_state); 859 ipu_plane = to_ipu_plane(plane); 860 861 if (!plane_state->fb) { 862 ipu_state->use_pre = false; 863 continue; 864 } 865 866 if ((plane_state->fb->flags & DRM_MODE_FB_MODIFIERS) && 867 plane_state->fb->modifier != DRM_FORMAT_MOD_LINEAR) 868 continue; 869 870 /* make sure that modifier is initialized */ 871 plane_state->fb->modifier = DRM_FORMAT_MOD_LINEAR; 872 873 if (ipu_prg_present(ipu_plane->ipu) && available_pres && 874 ipu_prg_format_supported(ipu_plane->ipu, 875 plane_state->fb->format->format, 876 plane_state->fb->modifier)) { 877 ipu_state->use_pre = true; 878 available_pres--; 879 } else { 880 ipu_state->use_pre = false; 881 } 882 } 883 884 return 0; 885 } 886 887 struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu, 888 int dma, int dp, unsigned int possible_crtcs, 889 enum drm_plane_type type) 890 { 891 struct ipu_plane *ipu_plane; 892 const uint64_t *modifiers = ipu_format_modifiers; 893 unsigned int zpos = (type == DRM_PLANE_TYPE_PRIMARY) ? 0 : 1; 894 unsigned int format_count; 895 const uint32_t *formats; 896 int ret; 897 898 DRM_DEBUG_KMS("channel %d, dp flow %d, possible_crtcs=0x%x\n", 899 dma, dp, possible_crtcs); 900 901 if (dp == IPU_DP_FLOW_SYNC_BG || dp == IPU_DP_FLOW_SYNC_FG) { 902 formats = ipu_plane_all_formats; 903 format_count = ARRAY_SIZE(ipu_plane_all_formats); 904 } else { 905 formats = ipu_plane_rgb_formats; 906 format_count = ARRAY_SIZE(ipu_plane_rgb_formats); 907 } 908 909 if (ipu_prg_present(ipu)) 910 modifiers = pre_format_modifiers; 911 912 ipu_plane = drmm_universal_plane_alloc(dev, struct ipu_plane, base, 913 possible_crtcs, &ipu_plane_funcs, 914 formats, format_count, modifiers, 915 type, NULL); 916 if (IS_ERR(ipu_plane)) { 917 DRM_ERROR("failed to allocate and initialize %s plane\n", 918 zpos ? "overlay" : "primary"); 919 return ipu_plane; 920 } 921 922 ipu_plane->ipu = ipu; 923 ipu_plane->dma = dma; 924 ipu_plane->dp_flow = dp; 925 926 if (type == DRM_PLANE_TYPE_PRIMARY) 927 drm_plane_helper_add(&ipu_plane->base, &ipu_primary_plane_helper_funcs); 928 else 929 drm_plane_helper_add(&ipu_plane->base, &ipu_plane_helper_funcs); 930 931 if (dp == IPU_DP_FLOW_SYNC_BG || dp == IPU_DP_FLOW_SYNC_FG) 932 ret = drm_plane_create_zpos_property(&ipu_plane->base, zpos, 0, 933 1); 934 else 935 ret = drm_plane_create_zpos_immutable_property(&ipu_plane->base, 936 0); 937 if (ret) 938 return ERR_PTR(ret); 939 940 ret = drm_plane_create_color_properties(&ipu_plane->base, 941 BIT(DRM_COLOR_YCBCR_BT601) | 942 BIT(DRM_COLOR_YCBCR_BT709), 943 BIT(DRM_COLOR_YCBCR_LIMITED_RANGE), 944 DRM_COLOR_YCBCR_BT601, 945 DRM_COLOR_YCBCR_LIMITED_RANGE); 946 if (ret) 947 return ERR_PTR(ret); 948 949 ret = ipu_plane_get_resources(dev, ipu_plane); 950 if (ret) { 951 DRM_ERROR("failed to get %s plane resources: %pe\n", 952 zpos ? "overlay" : "primary", &ret); 953 return ERR_PTR(ret); 954 } 955 956 return ipu_plane; 957 } 958