diff options
Diffstat (limited to 'drivers/gpu/drm/sun4i/sun8i_vi_layer.c')
-rw-r--r-- | drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 40 |
1 files changed, 30 insertions, 10 deletions
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c index b8398ca18b0f..22c8c5375d0d 100644 --- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c +++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c @@ -12,8 +12,9 @@ #include <drm/drm_plane_helper.h> #include <drm/drm_probe_helper.h> -#include "sun8i_vi_layer.h" +#include "sun8i_csc.h" #include "sun8i_mixer.h" +#include "sun8i_vi_layer.h" #include "sun8i_vi_scaler.h" static void sun8i_vi_layer_enable(struct sun8i_mixer *mixer, int channel, @@ -210,28 +211,47 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel, return 0; } +static bool sun8i_vi_layer_get_csc_mode(const struct drm_format_info *format) +{ + if (!format->is_yuv) + return SUN8I_CSC_MODE_OFF; + + switch (format->format) { + case DRM_FORMAT_YVU411: + case DRM_FORMAT_YVU420: + case DRM_FORMAT_YVU422: + case DRM_FORMAT_YVU444: + return SUN8I_CSC_MODE_YVU2RGB; + default: + return SUN8I_CSC_MODE_YUV2RGB; + } +} + static int sun8i_vi_layer_update_formats(struct sun8i_mixer *mixer, int channel, int overlay, struct drm_plane *plane) { struct drm_plane_state *state = plane->state; - const struct de2_fmt_info *fmt_info; - u32 val, ch_base; + u32 val, ch_base, csc_mode, hw_fmt; + const struct drm_format_info *fmt; + int ret; ch_base = sun8i_channel_base(mixer, channel); - fmt_info = sun8i_mixer_format_info(state->fb->format->format); - if (!fmt_info) { + fmt = state->fb->format; + ret = sun8i_mixer_drm_format_to_hw(fmt->format, &hw_fmt); + if (ret) { DRM_DEBUG_DRIVER("Invalid format\n"); - return -EINVAL; + return ret; } - val = fmt_info->de2_fmt << SUN8I_MIXER_CHAN_VI_LAYER_ATTR_FBFMT_OFFSET; + val = hw_fmt << SUN8I_MIXER_CHAN_VI_LAYER_ATTR_FBFMT_OFFSET; regmap_update_bits(mixer->engine.regs, SUN8I_MIXER_CHAN_VI_LAYER_ATTR(ch_base, overlay), SUN8I_MIXER_CHAN_VI_LAYER_ATTR_FBFMT_MASK, val); - if (fmt_info->csc != SUN8I_CSC_MODE_OFF) { - sun8i_csc_set_ccsc_coefficients(mixer, channel, fmt_info->csc, + csc_mode = sun8i_vi_layer_get_csc_mode(fmt); + if (csc_mode != SUN8I_CSC_MODE_OFF) { + sun8i_csc_set_ccsc_coefficients(mixer, channel, csc_mode, state->color_encoding, state->color_range); sun8i_csc_enable_ccsc(mixer, channel, true); @@ -239,7 +259,7 @@ static int sun8i_vi_layer_update_formats(struct sun8i_mixer *mixer, int channel, sun8i_csc_enable_ccsc(mixer, channel, false); } - if (fmt_info->rgb) + if (!fmt->is_yuv) val = SUN8I_MIXER_CHAN_VI_LAYER_ATTR_RGB_MODE; else val = 0; |