* Copyright (C) Jernej Skrabec <jernej.skrabec@siol.net>
*/
+#include <drm/drm_fourcc.h>
+#include <drm/drm_framebuffer.h>
+#include <drm/drm_plane.h>
#include <drm/drm_print.h>
#include "sun8i_csc.h"
#include "sun8i_mixer.h"
+enum sun8i_csc_mode {
+ SUN8I_CSC_MODE_OFF,
+ SUN8I_CSC_MODE_YUV2RGB,
+ SUN8I_CSC_MODE_YVU2RGB,
+};
+
static const u32 ccsc_base[][2] = {
[CCSC_MIXER0_LAYOUT] = {CCSC00_OFFSET, CCSC01_OFFSET},
[CCSC_MIXER1_LAYOUT] = {CCSC10_OFFSET, CCSC11_OFFSET},
mask, val);
}
+static u32 sun8i_csc_get_mode(struct drm_plane_state *state)
+{
+ const struct drm_format_info *format;
+
+ if (!state->crtc || !state->visible)
+ return SUN8I_CSC_MODE_OFF;
+
+ format = state->fb->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;
+ }
+}
+
void sun8i_csc_config(struct sun8i_mixer *mixer, int layer,
- enum sun8i_csc_mode mode,
- enum drm_color_encoding encoding,
- enum drm_color_range range)
+ struct drm_plane_state *state)
{
+ u32 mode = sun8i_csc_get_mode(state);
u32 base;
if (mixer->cfg->de_type == SUN8I_MIXER_DE3) {
sun8i_de3_ccsc_setup(mixer->engine.regs, layer,
- mode, encoding, range);
+ mode, state->color_encoding,
+ state->color_range);
return;
}
base = ccsc_base[mixer->cfg->ccsc][layer];
sun8i_csc_setup(mixer->engine.regs, base,
- mode, encoding, range);
+ mode, state->color_encoding,
+ state->color_range);
}
#include <drm/drm_color_mgmt.h>
+struct drm_plane_state;
struct sun8i_mixer;
/* VI channel CSC units offsets */
#define SUN8I_CSC_CTRL_EN BIT(0)
-enum sun8i_csc_mode {
- SUN8I_CSC_MODE_OFF,
- SUN8I_CSC_MODE_YUV2RGB,
- SUN8I_CSC_MODE_YVU2RGB,
-};
-
void sun8i_csc_config(struct sun8i_mixer *mixer, int layer,
- enum sun8i_csc_mode mode,
- enum drm_color_encoding encoding,
- enum drm_color_range range);
+ struct drm_plane_state *state);
#endif
SUN8I_MIXER_CHAN_VI_DS_M(vm));
}
-static u32 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 void sun8i_vi_layer_update_colors(struct sun8i_mixer *mixer, int channel,
- int overlay, struct drm_plane *plane)
-{
- struct drm_plane_state *state = plane->state;
- const struct drm_format_info *fmt;
- u32 csc_mode;
-
- fmt = state->fb->format;
- csc_mode = sun8i_vi_layer_get_csc_mode(fmt);
- sun8i_csc_config(mixer, channel, csc_mode,
- state->color_encoding,
- state->color_range);
-}
-
static void sun8i_vi_layer_update_buffer(struct sun8i_mixer *mixer, int channel,
int overlay, struct drm_plane *plane)
{
layer->overlay, plane);
sun8i_vi_layer_update_coord(mixer, layer->channel,
layer->overlay, plane);
- sun8i_vi_layer_update_colors(mixer, layer->channel,
- layer->overlay, plane);
+ sun8i_csc_config(mixer, layer->channel, new_state);
sun8i_vi_layer_update_buffer(mixer, layer->channel,
layer->overlay, plane);
}