diff options
author | Dave Airlie <airlied@redhat.com> | 2018-11-28 19:21:23 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2018-11-28 19:28:49 -0500 |
commit | 61647c77cb15354a329cbb36fe7a2253b36b51b1 (patch) | |
tree | 59d887f99bc4a2bdddc7cfc1d81794c2a4cdc759 /drivers/gpu/drm/sun4i/sun4i_backend.c | |
parent | 1a31c26ed7b495f152e3103dc7c68e3307a39541 (diff) | |
parent | 08f73d668048ffa3ba6b1426b6ba0a89b16aefd7 (diff) |
Merge tag 'drm-misc-next-2018-11-28' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for v4.21:
Core Changes:
- Merge drm_info.c into drm_debugfs.c
- Complete the fake drm_crtc_commit's hw_done/flip_done sooner.
- Remove deprecated drm_obj_ref/unref functions. All drivers use get/put now.
- Decrease stack use of drm_gem_prime_mmap.
- Improve documentation for dumb callbacks.
Driver Changes:
- Add edid support to virtio.
- Wait on implicit fence in meson and sun4i.
- Add support for BGRX8888 to sun4i.
- Preparation patches for sun4i driver to start supporting linear and tiled YUV formats.
- Add support for HDMI 1.4 4k modes to meson, and support for VIC alternate timings.
- Drop custom dumb_map in vkms.
- Small fixes and cleanups to v3d.
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/151a3270-b1be-ed75-bd58-6b29d741f592@linux.intel.com
Diffstat (limited to 'drivers/gpu/drm/sun4i/sun4i_backend.c')
-rw-r--r-- | drivers/gpu/drm/sun4i/sun4i_backend.c | 106 |
1 files changed, 94 insertions, 12 deletions
diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c index bf49c55b0f2c..9e9255ee59cd 100644 --- a/drivers/gpu/drm/sun4i/sun4i_backend.c +++ b/drivers/gpu/drm/sun4i/sun4i_backend.c | |||
@@ -48,8 +48,12 @@ static const u32 sunxi_rgb2yuv_coef[12] = { | |||
48 | /* | 48 | /* |
49 | * These coefficients are taken from the A33 BSP from Allwinner. | 49 | * These coefficients are taken from the A33 BSP from Allwinner. |
50 | * | 50 | * |
51 | * The formula is for each component, each coefficient being multiplied by | 51 | * The first three values of each row are coded as 13-bit signed fixed-point |
52 | * 1024 and each constant being multiplied by 16: | 52 | * numbers, with 10 bits for the fractional part. The fourth value is a |
53 | * constant coded as a 14-bit signed fixed-point number with 4 bits for the | ||
54 | * fractional part. | ||
55 | * | ||
56 | * The values in table order give the following colorspace translation: | ||
53 | * G = 1.164 * Y - 0.391 * U - 0.813 * V + 135 | 57 | * G = 1.164 * Y - 0.391 * U - 0.813 * V + 135 |
54 | * R = 1.164 * Y + 1.596 * V - 222 | 58 | * R = 1.164 * Y + 1.596 * V - 222 |
55 | * B = 1.164 * Y + 2.018 * U + 276 | 59 | * B = 1.164 * Y + 2.018 * U + 276 |
@@ -155,6 +159,36 @@ static int sun4i_backend_drm_format_to_layer(u32 format, u32 *mode) | |||
155 | return 0; | 159 | return 0; |
156 | } | 160 | } |
157 | 161 | ||
162 | static const uint32_t sun4i_backend_formats[] = { | ||
163 | DRM_FORMAT_ARGB1555, | ||
164 | DRM_FORMAT_ARGB4444, | ||
165 | DRM_FORMAT_ARGB8888, | ||
166 | DRM_FORMAT_BGRX8888, | ||
167 | DRM_FORMAT_RGB565, | ||
168 | DRM_FORMAT_RGB888, | ||
169 | DRM_FORMAT_RGBA4444, | ||
170 | DRM_FORMAT_RGBA5551, | ||
171 | DRM_FORMAT_UYVY, | ||
172 | DRM_FORMAT_VYUY, | ||
173 | DRM_FORMAT_XRGB8888, | ||
174 | DRM_FORMAT_YUYV, | ||
175 | DRM_FORMAT_YVYU, | ||
176 | }; | ||
177 | |||
178 | bool sun4i_backend_format_is_supported(uint32_t fmt, uint64_t modifier) | ||
179 | { | ||
180 | unsigned int i; | ||
181 | |||
182 | if (modifier != DRM_FORMAT_MOD_LINEAR) | ||
183 | return false; | ||
184 | |||
185 | for (i = 0; i < ARRAY_SIZE(sun4i_backend_formats); i++) | ||
186 | if (sun4i_backend_formats[i] == fmt) | ||
187 | return true; | ||
188 | |||
189 | return false; | ||
190 | } | ||
191 | |||
158 | int sun4i_backend_update_layer_coord(struct sun4i_backend *backend, | 192 | int sun4i_backend_update_layer_coord(struct sun4i_backend *backend, |
159 | int layer, struct drm_plane *plane) | 193 | int layer, struct drm_plane *plane) |
160 | { | 194 | { |
@@ -395,6 +429,15 @@ int sun4i_backend_update_layer_zpos(struct sun4i_backend *backend, int layer, | |||
395 | return 0; | 429 | return 0; |
396 | } | 430 | } |
397 | 431 | ||
432 | void sun4i_backend_cleanup_layer(struct sun4i_backend *backend, | ||
433 | int layer) | ||
434 | { | ||
435 | regmap_update_bits(backend->engine.regs, | ||
436 | SUN4I_BACKEND_ATTCTL_REG0(layer), | ||
437 | SUN4I_BACKEND_ATTCTL_REG0_LAY_VDOEN | | ||
438 | SUN4I_BACKEND_ATTCTL_REG0_LAY_YUVEN, 0); | ||
439 | } | ||
440 | |||
398 | static bool sun4i_backend_plane_uses_scaler(struct drm_plane_state *state) | 441 | static bool sun4i_backend_plane_uses_scaler(struct drm_plane_state *state) |
399 | { | 442 | { |
400 | u16 src_h = state->src_h >> 16; | 443 | u16 src_h = state->src_h >> 16; |
@@ -413,11 +456,50 @@ static bool sun4i_backend_plane_uses_frontend(struct drm_plane_state *state) | |||
413 | { | 456 | { |
414 | struct sun4i_layer *layer = plane_to_sun4i_layer(state->plane); | 457 | struct sun4i_layer *layer = plane_to_sun4i_layer(state->plane); |
415 | struct sun4i_backend *backend = layer->backend; | 458 | struct sun4i_backend *backend = layer->backend; |
459 | uint32_t format = state->fb->format->format; | ||
460 | uint64_t modifier = state->fb->modifier; | ||
416 | 461 | ||
417 | if (IS_ERR(backend->frontend)) | 462 | if (IS_ERR(backend->frontend)) |
418 | return false; | 463 | return false; |
419 | 464 | ||
420 | return sun4i_backend_plane_uses_scaler(state); | 465 | if (!sun4i_frontend_format_is_supported(format, modifier)) |
466 | return false; | ||
467 | |||
468 | if (!sun4i_backend_format_is_supported(format, modifier)) | ||
469 | return true; | ||
470 | |||
471 | /* | ||
472 | * TODO: The backend alone allows 2x and 4x integer scaling, including | ||
473 | * support for an alpha component (which the frontend doesn't support). | ||
474 | * Use the backend directly instead of the frontend in this case, with | ||
475 | * another test to return false. | ||
476 | */ | ||
477 | |||
478 | if (sun4i_backend_plane_uses_scaler(state)) | ||
479 | return true; | ||
480 | |||
481 | /* | ||
482 | * Here the format is supported by both the frontend and the backend | ||
483 | * and no frontend scaling is required, so use the backend directly. | ||
484 | */ | ||
485 | return false; | ||
486 | } | ||
487 | |||
488 | static bool sun4i_backend_plane_is_supported(struct drm_plane_state *state, | ||
489 | bool *uses_frontend) | ||
490 | { | ||
491 | if (sun4i_backend_plane_uses_frontend(state)) { | ||
492 | *uses_frontend = true; | ||
493 | return true; | ||
494 | } | ||
495 | |||
496 | *uses_frontend = false; | ||
497 | |||
498 | /* Scaling is not supported without the frontend. */ | ||
499 | if (sun4i_backend_plane_uses_scaler(state)) | ||
500 | return false; | ||
501 | |||
502 | return true; | ||
421 | } | 503 | } |
422 | 504 | ||
423 | static void sun4i_backend_atomic_begin(struct sunxi_engine *engine, | 505 | static void sun4i_backend_atomic_begin(struct sunxi_engine *engine, |
@@ -460,14 +542,19 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine, | |||
460 | struct drm_framebuffer *fb = plane_state->fb; | 542 | struct drm_framebuffer *fb = plane_state->fb; |
461 | struct drm_format_name_buf format_name; | 543 | struct drm_format_name_buf format_name; |
462 | 544 | ||
463 | if (sun4i_backend_plane_uses_frontend(plane_state)) { | 545 | if (!sun4i_backend_plane_is_supported(plane_state, |
546 | &layer_state->uses_frontend)) | ||
547 | return -EINVAL; | ||
548 | |||
549 | if (layer_state->uses_frontend) { | ||
464 | DRM_DEBUG_DRIVER("Using the frontend for plane %d\n", | 550 | DRM_DEBUG_DRIVER("Using the frontend for plane %d\n", |
465 | plane->index); | 551 | plane->index); |
466 | |||
467 | layer_state->uses_frontend = true; | ||
468 | num_frontend_planes++; | 552 | num_frontend_planes++; |
469 | } else { | 553 | } else { |
470 | layer_state->uses_frontend = false; | 554 | if (fb->format->is_yuv) { |
555 | DRM_DEBUG_DRIVER("Plane FB format is YUV\n"); | ||
556 | num_yuv_planes++; | ||
557 | } | ||
471 | } | 558 | } |
472 | 559 | ||
473 | DRM_DEBUG_DRIVER("Plane FB format is %s\n", | 560 | DRM_DEBUG_DRIVER("Plane FB format is %s\n", |
@@ -476,11 +563,6 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine, | |||
476 | if (fb->format->has_alpha || (plane_state->alpha != DRM_BLEND_ALPHA_OPAQUE)) | 563 | if (fb->format->has_alpha || (plane_state->alpha != DRM_BLEND_ALPHA_OPAQUE)) |
477 | num_alpha_planes++; | 564 | num_alpha_planes++; |
478 | 565 | ||
479 | if (fb->format->is_yuv) { | ||
480 | DRM_DEBUG_DRIVER("Plane FB format is YUV\n"); | ||
481 | num_yuv_planes++; | ||
482 | } | ||
483 | |||
484 | DRM_DEBUG_DRIVER("Plane zpos is %d\n", | 566 | DRM_DEBUG_DRIVER("Plane zpos is %d\n", |
485 | plane_state->normalized_zpos); | 567 | plane_state->normalized_zpos); |
486 | 568 | ||