Commit 762dff2e authored by Ville Syrjälä's avatar Ville Syrjälä

drm/i915: Add support for half float framebuffers for ivb+ sprites

ivb+ supports fp16 pixel formats on the sprite planes planes. Expose
that capability.

On ivb/hsw fp16 scanout is slightly busted. The output from the plane
will have 1/4 the expected value. For the sprite plane we can fix that
up with the plane gamma unit. This was fixed on bdw.

v2: Rebase on top of icl fp16
    Split the ivb+ sprite birs into a separate patch
v3: Move ivb_need_sprite_gamma() check one level up so that
    we don't waste time programming garbage into he gamma registers
Reviewed-by: default avatarMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191015193035.25982-10-ville.syrjala@linux.intel.com
parent 03b0ce95
...@@ -1316,6 +1316,16 @@ static u32 ivb_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state) ...@@ -1316,6 +1316,16 @@ static u32 ivb_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
return sprctl; return sprctl;
} }
static bool ivb_need_sprite_gamma(const struct intel_plane_state *plane_state)
{
struct drm_i915_private *dev_priv =
to_i915(plane_state->base.plane->dev);
const struct drm_framebuffer *fb = plane_state->base.fb;
return fb->format->cpp[0] == 8 &&
(IS_IVYBRIDGE(dev_priv) || IS_HASWELL(dev_priv));
}
static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state, static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state) const struct intel_plane_state *plane_state)
{ {
...@@ -1338,6 +1348,12 @@ static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state, ...@@ -1338,6 +1348,12 @@ static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state,
case DRM_FORMAT_XRGB8888: case DRM_FORMAT_XRGB8888:
sprctl |= SPRITE_FORMAT_RGBX888; sprctl |= SPRITE_FORMAT_RGBX888;
break; break;
case DRM_FORMAT_XBGR16161616F:
sprctl |= SPRITE_FORMAT_RGBX161616 | SPRITE_RGB_ORDER_RGBX;
break;
case DRM_FORMAT_XRGB16161616F:
sprctl |= SPRITE_FORMAT_RGBX161616;
break;
case DRM_FORMAT_YUYV: case DRM_FORMAT_YUYV:
sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV; sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV;
break; break;
...@@ -1355,7 +1371,8 @@ static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state, ...@@ -1355,7 +1371,8 @@ static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state,
return 0; return 0;
} }
sprctl |= SPRITE_INT_GAMMA_DISABLE; if (!ivb_need_sprite_gamma(plane_state))
sprctl |= SPRITE_INT_GAMMA_DISABLE;
if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709) if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
sprctl |= SPRITE_YUV_TO_RGB_CSC_FORMAT_BT709; sprctl |= SPRITE_YUV_TO_RGB_CSC_FORMAT_BT709;
...@@ -1377,12 +1394,26 @@ static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state, ...@@ -1377,12 +1394,26 @@ static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state,
return sprctl; return sprctl;
} }
static void ivb_sprite_linear_gamma(u16 gamma[18]) static void ivb_sprite_linear_gamma(const struct intel_plane_state *plane_state,
u16 gamma[18])
{ {
int i; int scale, i;
for (i = 0; i < 17; i++) /*
gamma[i] = (i << 10) / 16; * WaFP16GammaEnabling:ivb,hsw
* "Workaround : When using the 64-bit format, the sprite output
* on each color channel has one quarter amplitude. It can be
* brought up to full amplitude by using sprite internal gamma
* correction, pipe gamma correction, or pipe color space
* conversion to multiply the sprite output by four."
*/
scale = 4;
for (i = 0; i < 16; i++)
gamma[i] = min((scale * i << 10) / 16, (1 << 10) - 1);
gamma[i] = min((scale * i << 10) / 16, 1 << 10);
i++;
gamma[i] = 3 << 10; gamma[i] = 3 << 10;
i++; i++;
...@@ -1396,7 +1427,10 @@ static void ivb_update_gamma(const struct intel_plane_state *plane_state) ...@@ -1396,7 +1427,10 @@ static void ivb_update_gamma(const struct intel_plane_state *plane_state)
u16 gamma[18]; u16 gamma[18];
int i; int i;
ivb_sprite_linear_gamma(gamma); if (!ivb_need_sprite_gamma(plane_state))
return;
ivb_sprite_linear_gamma(plane_state, gamma);
/* FIXME these register are single buffered :( */ /* FIXME these register are single buffered :( */
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
...@@ -2551,6 +2585,8 @@ static bool snb_sprite_format_mod_supported(struct drm_plane *_plane, ...@@ -2551,6 +2585,8 @@ static bool snb_sprite_format_mod_supported(struct drm_plane *_plane,
switch (format) { switch (format) {
case DRM_FORMAT_XRGB8888: case DRM_FORMAT_XRGB8888:
case DRM_FORMAT_XBGR8888: case DRM_FORMAT_XBGR8888:
case DRM_FORMAT_XRGB16161616F:
case DRM_FORMAT_XBGR16161616F:
case DRM_FORMAT_YUYV: case DRM_FORMAT_YUYV:
case DRM_FORMAT_YVYU: case DRM_FORMAT_YVYU:
case DRM_FORMAT_UYVY: case DRM_FORMAT_UYVY:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment