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 #include <drm/drm_print.h> 18 19 #include <video/imx-ipu-v3.h> 20 21 #include "imx-drm.h" 22 #include "ipuv3-plane.h" 23 24 struct ipu_plane_state { 25 struct drm_plane_state base; 26 bool use_pre; 27 }; 28 29 static inline struct ipu_plane_state * 30 to_ipu_plane_state(struct drm_plane_state *p) 31 { 32 return container_of(p, struct ipu_plane_state, base); 33 } 34 35 static unsigned int ipu_src_rect_width(const struct drm_plane_state *state) 36 { 37 return ALIGN(drm_rect_width(&state->src) >> 16, 8); 38 } 39 40 static inline struct ipu_plane *to_ipu_plane(struct drm_plane *p) 41 { 42 return container_of(p, struct ipu_plane, base); 43 } 44 45 static const uint32_t ipu_plane_all_formats[] = { 46 DRM_FORMAT_ARGB1555, 47 DRM_FORMAT_XRGB1555, 48 DRM_FORMAT_ABGR1555, 49 DRM_FORMAT_XBGR1555, 50 DRM_FORMAT_RGBA5551, 51 DRM_FORMAT_BGRA5551, 52 DRM_FORMAT_ARGB4444, 53 DRM_FORMAT_ARGB8888, 54 DRM_FORMAT_XRGB8888, 55 DRM_FORMAT_ABGR8888, 56 DRM_FORMAT_XBGR8888, 57 DRM_FORMAT_RGBA8888, 58 DRM_FORMAT_RGBX8888, 59 DRM_FORMAT_BGRA8888, 60 DRM_FORMAT_BGRX8888, 61 DRM_FORMAT_UYVY, 62 DRM_FORMAT_VYUY, 63 DRM_FORMAT_YUYV, 64 DRM_FORMAT_YVYU, 65 DRM_FORMAT_YUV420, 66 DRM_FORMAT_YVU420, 67 DRM_FORMAT_YUV422, 68 DRM_FORMAT_YVU422, 69 DRM_FORMAT_YUV444, 70 DRM_FORMAT_YVU444, 71 DRM_FORMAT_NV12, 72 DRM_FORMAT_NV16, 73 DRM_FORMAT_RGB565, 74 DRM_FORMAT_RGB565_A8, 75 DRM_FORMAT_BGR565_A8, 76 DRM_FORMAT_RGB888_A8, 77 DRM_FORMAT_BGR888_A8, 78 DRM_FORMAT_RGBX8888_A8, 79 DRM_FORMAT_BGRX8888_A8, 80 }; 81 82 static const uint32_t ipu_plane_rgb_formats[] = { 83 DRM_FORMAT_ARGB1555, 84 DRM_FORMAT_XRGB1555, 85 DRM_FORMAT_ABGR1555, 86 DRM_FORMAT_XBGR1555, 87 DRM_FORMAT_RGBA5551, 88 DRM_FORMAT_BGRA5551, 89 DRM_FORMAT_ARGB4444, 90 DRM_FORMAT_ARGB8888, 91 DRM_FORMAT_XRGB8888, 92 DRM_FORMAT_ABGR8888, 93 DRM_FORMAT_XBGR8888, 94 DRM_FORMAT_RGBA8888, 95 DRM_FORMAT_RGBX8888, 96 DRM_FORMAT_BGRA8888, 97 DRM_FORMAT_BGRX8888, 98 DRM_FORMAT_RGB565, 99 DRM_FORMAT_RGB565_A8, 100 DRM_FORMAT_BGR565_A8, 101 DRM_FORMAT_RGB888_A8, 102 DRM_FORMAT_BGR888_A8, 103 DRM_FORMAT_RGBX8888_A8, 104 DRM_FORMAT_BGRX8888_A8, 105 }; 106 107 static const uint64_t ipu_format_modifiers[] = { 108 DRM_FORMAT_MOD_LINEAR, 109 DRM_FORMAT_MOD_INVALID 110 }; 111 112 static const uint64_t pre_format_modifiers[] = { 113 DRM_FORMAT_MOD_LINEAR, 114 DRM_FORMAT_MOD_VIVANTE_TILED, 115 DRM_FORMAT_MOD_VIVANTE_SUPER_TILED, 116 DRM_FORMAT_MOD_INVALID 117 }; 118 119 int ipu_plane_irq(struct ipu_plane *ipu_plane) 120 { 121 return ipu_idmac_channel_irq(ipu_plane->ipu, ipu_plane->ipu_ch, 122 IPU_IRQ_EOF); 123 } 124 125 static inline unsigned long 126 drm_plane_state_to_eba(struct drm_plane_state *state, int plane) 127 { 128 struct drm_framebuffer *fb = state->fb; 129 struct drm_gem_dma_object *dma_obj; 130 int x = state->src.x1 >> 16; 131 int y = state->src.y1 >> 16; 132 133 dma_obj = drm_fb_dma_get_gem_obj(fb, plane); 134 BUG_ON(!dma_obj); 135 136 return dma_obj->dma_addr + fb->offsets[plane] + fb->pitches[plane] * y + 137 fb->format->cpp[plane] * x; 138 } 139 140 static inline unsigned long 141 drm_plane_state_to_ubo(struct drm_plane_state *state) 142 { 143 struct drm_framebuffer *fb = state->fb; 144 struct drm_gem_dma_object *dma_obj; 145 unsigned long eba = drm_plane_state_to_eba(state, 0); 146 int x = state->src.x1 >> 16; 147 int y = state->src.y1 >> 16; 148 149 dma_obj = drm_fb_dma_get_gem_obj(fb, 1); 150 BUG_ON(!dma_obj); 151 152 x /= fb->format->hsub; 153 y /= fb->format->vsub; 154 155 return dma_obj->dma_addr + fb->offsets[1] + fb->pitches[1] * y + 156 fb->format->cpp[1] * x - eba; 157 } 158 159 static inline unsigned long 160 drm_plane_state_to_vbo(struct drm_plane_state *state) 161 { 162 struct drm_framebuffer *fb = state->fb; 163 struct drm_gem_dma_object *dma_obj; 164 unsigned long eba = drm_plane_state_to_eba(state, 0); 165 int x = state->src.x1 >> 16; 166 int y = state->src.y1 >> 16; 167 168 dma_obj = drm_fb_dma_get_gem_obj(fb, 2); 169 BUG_ON(!dma_obj); 170 171 x /= fb->format->hsub; 172 y /= fb->format->vsub; 173 174 return dma_obj->dma_addr + fb->offsets[2] + fb->pitches[2] * y + 175 fb->format->cpp[2] * x - eba; 176 } 177 178 static void ipu_plane_put_resources(struct drm_device *dev, void *ptr) 179 { 180 struct ipu_plane *ipu_plane = ptr; 181 182 if (!IS_ERR_OR_NULL(ipu_plane->dp)) 183 ipu_dp_put(ipu_plane->dp); 184 if (!IS_ERR_OR_NULL(ipu_plane->dmfc)) 185 ipu_dmfc_put(ipu_plane->dmfc); 186 if (!IS_ERR_OR_NULL(ipu_plane->ipu_ch)) 187 ipu_idmac_put(ipu_plane->ipu_ch); 188 if (!IS_ERR_OR_NULL(ipu_plane->alpha_ch)) 189 ipu_idmac_put(ipu_plane->alpha_ch); 190 } 191 192 static int ipu_plane_get_resources(struct drm_device *dev, 193 struct ipu_plane *ipu_plane) 194 { 195 int ret; 196 int alpha_ch; 197 198 ipu_plane->ipu_ch = ipu_idmac_get(ipu_plane->ipu, ipu_plane->dma); 199 if (IS_ERR(ipu_plane->ipu_ch)) { 200 ret = PTR_ERR(ipu_plane->ipu_ch); 201 DRM_ERROR("failed to get idmac channel: %d\n", ret); 202 return ret; 203 } 204 205 ret = drmm_add_action_or_reset(dev, ipu_plane_put_resources, ipu_plane); 206 if (ret) 207 return ret; 208 209 alpha_ch = ipu_channel_alpha_channel(ipu_plane->dma); 210 if (alpha_ch >= 0) { 211 ipu_plane->alpha_ch = ipu_idmac_get(ipu_plane->ipu, alpha_ch); 212 if (IS_ERR(ipu_plane->alpha_ch)) { 213 ret = PTR_ERR(ipu_plane->alpha_ch); 214 DRM_ERROR("failed to get alpha idmac channel %d: %d\n", 215 alpha_ch, ret); 216 return ret; 217 } 218 } 219 220 ipu_plane->dmfc = ipu_dmfc_get(ipu_plane->ipu, ipu_plane->dma); 221 if (IS_ERR(ipu_plane->dmfc)) { 222 ret = PTR_ERR(ipu_plane->dmfc); 223 DRM_ERROR("failed to get dmfc: ret %d\n", ret); 224 return ret; 225 } 226 227 if (ipu_plane->dp_flow >= 0) { 228 ipu_plane->dp = ipu_dp_get(ipu_plane->ipu, ipu_plane->dp_flow); 229 if (IS_ERR(ipu_plane->dp)) { 230 ret = PTR_ERR(ipu_plane->dp); 231 DRM_ERROR("failed to get dp flow: %d\n", ret); 232 return ret; 233 } 234 } 235 236 return 0; 237 } 238 239 static bool ipu_plane_separate_alpha(struct ipu_plane *ipu_plane) 240 { 241 switch (ipu_plane->base.state->fb->format->format) { 242 case DRM_FORMAT_RGB565_A8: 243 case DRM_FORMAT_BGR565_A8: 244 case DRM_FORMAT_RGB888_A8: 245 case DRM_FORMAT_BGR888_A8: 246 case DRM_FORMAT_RGBX8888_A8: 247 case DRM_FORMAT_BGRX8888_A8: 248 return true; 249 default: 250 return false; 251 } 252 } 253 254 static void ipu_plane_enable(struct ipu_plane *ipu_plane) 255 { 256 if (ipu_plane->dp) 257 ipu_dp_enable(ipu_plane->ipu); 258 ipu_dmfc_enable_channel(ipu_plane->dmfc); 259 ipu_idmac_enable_channel(ipu_plane->ipu_ch); 260 if (ipu_plane_separate_alpha(ipu_plane)) 261 ipu_idmac_enable_channel(ipu_plane->alpha_ch); 262 if (ipu_plane->dp) 263 ipu_dp_enable_channel(ipu_plane->dp); 264 } 265 266 void ipu_plane_disable(struct ipu_plane *ipu_plane, bool disable_dp_channel) 267 { 268 int ret; 269 270 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); 271 272 ret = ipu_idmac_wait_busy(ipu_plane->ipu_ch, 50); 273 if (ret == -ETIMEDOUT) { 274 DRM_ERROR("[PLANE:%d] IDMAC timeout\n", 275 ipu_plane->base.base.id); 276 } 277 278 if (ipu_plane->dp && disable_dp_channel) 279 ipu_dp_disable_channel(ipu_plane->dp, false); 280 ipu_idmac_disable_channel(ipu_plane->ipu_ch); 281 if (ipu_plane->alpha_ch) 282 ipu_idmac_disable_channel(ipu_plane->alpha_ch); 283 ipu_dmfc_disable_channel(ipu_plane->dmfc); 284 if (ipu_plane->dp) 285 ipu_dp_disable(ipu_plane->ipu); 286 if (ipu_prg_present(ipu_plane->ipu)) 287 ipu_prg_channel_disable(ipu_plane->ipu_ch); 288 } 289 290 void ipu_plane_disable_deferred(struct drm_plane *plane) 291 { 292 struct ipu_plane *ipu_plane = to_ipu_plane(plane); 293 294 if (ipu_plane->disabling) { 295 ipu_plane->disabling = false; 296 ipu_plane_disable(ipu_plane, false); 297 } 298 } 299 300 static void ipu_plane_state_reset(struct drm_plane *plane) 301 { 302 struct ipu_plane_state *ipu_state; 303 304 if (plane->state) { 305 ipu_state = to_ipu_plane_state(plane->state); 306 __drm_atomic_helper_plane_destroy_state(plane->state); 307 kfree(ipu_state); 308 plane->state = NULL; 309 } 310 311 ipu_state = kzalloc(sizeof(*ipu_state), GFP_KERNEL); 312 313 if (ipu_state) 314 __drm_atomic_helper_plane_reset(plane, &ipu_state->base); 315 } 316 317 static struct drm_plane_state * 318 ipu_plane_duplicate_state(struct drm_plane *plane) 319 { 320 struct ipu_plane_state *state; 321 322 if (WARN_ON(!plane->state)) 323 return NULL; 324 325 state = kmalloc(sizeof(*state), GFP_KERNEL); 326 if (state) 327 __drm_atomic_helper_plane_duplicate_state(plane, &state->base); 328 329 return &state->base; 330 } 331 332 static void ipu_plane_destroy_state(struct drm_plane *plane, 333 struct drm_plane_state *state) 334 { 335 struct ipu_plane_state *ipu_state = to_ipu_plane_state(state); 336 337 __drm_atomic_helper_plane_destroy_state(state); 338 kfree(ipu_state); 339 } 340 341 static bool ipu_plane_format_mod_supported(struct drm_plane *plane, 342 uint32_t format, uint64_t modifier) 343 { 344 struct ipu_soc *ipu = to_ipu_plane(plane)->ipu; 345 346 /* linear is supported for all planes and formats */ 347 if (modifier == DRM_FORMAT_MOD_LINEAR) 348 return true; 349 350 /* 351 * Without a PRG the possible modifiers list only includes the linear 352 * modifier, so we always take the early return from this function and 353 * only end up here if the PRG is present. 354 */ 355 return ipu_prg_format_supported(ipu, format, modifier); 356 } 357 358 static const struct drm_plane_funcs ipu_plane_funcs = { 359 .update_plane = drm_atomic_helper_update_plane, 360 .disable_plane = drm_atomic_helper_disable_plane, 361 .reset = ipu_plane_state_reset, 362 .atomic_duplicate_state = ipu_plane_duplicate_state, 363 .atomic_destroy_state = ipu_plane_destroy_state, 364 .format_mod_supported = ipu_plane_format_mod_supported, 365 }; 366 367 static int ipu_plane_atomic_check(struct drm_plane *plane, 368 struct drm_atomic_state *state) 369 { 370 struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, 371 plane); 372 struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state, 373 plane); 374 struct drm_crtc_state *crtc_state; 375 struct device *dev = plane->dev->dev; 376 struct drm_framebuffer *fb = new_state->fb; 377 struct drm_framebuffer *old_fb = old_state->fb; 378 unsigned long eba, ubo, vbo, old_ubo, old_vbo, alpha_eba; 379 bool can_position = (plane->type == DRM_PLANE_TYPE_OVERLAY); 380 int ret; 381 382 /* Ok to disable */ 383 if (!fb) 384 return 0; 385 386 if (WARN_ON(!new_state->crtc)) 387 return -EINVAL; 388 389 crtc_state = 390 drm_atomic_get_new_crtc_state(state, 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