aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/sun4i/sun4i_backend.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2018-11-28 19:21:23 -0500
committerDave Airlie <airlied@redhat.com>2018-11-28 19:28:49 -0500
commit61647c77cb15354a329cbb36fe7a2253b36b51b1 (patch)
tree59d887f99bc4a2bdddc7cfc1d81794c2a4cdc759 /drivers/gpu/drm/sun4i/sun4i_backend.c
parent1a31c26ed7b495f152e3103dc7c68e3307a39541 (diff)
parent08f73d668048ffa3ba6b1426b6ba0a89b16aefd7 (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.c106
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
162static 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
178bool 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
158int sun4i_backend_update_layer_coord(struct sun4i_backend *backend, 192int 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
432void 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
398static bool sun4i_backend_plane_uses_scaler(struct drm_plane_state *state) 441static 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
488static 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
423static void sun4i_backend_atomic_begin(struct sunxi_engine *engine, 505static 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