@@ -139,8 +139,12 @@ static void sun4i_crtc_mode_set_nofb(struct drm_crtc *crtc)
struct drm_display_mode *mode = &crtc->state->adjusted_mode;
struct drm_encoder *encoder = sun4i_crtc_get_encoder(crtc);
struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc);
+ struct sunxi_engine *engine = scrtc->engine;
sun4i_tcon_mode_set(scrtc->tcon, encoder, mode);
+
+ if (engine->ops->mode_set)
+ engine->ops->mode_set(engine, mode);
}
static const struct drm_crtc_helper_funcs sun4i_crtc_helper_funcs = {
@@ -257,6 +257,40 @@ const struct de2_fmt_info *sun8i_mixer_format_info(u32 format)
return NULL;
}
+static void sun8i_mode_set(struct sunxi_engine *engine,
+ struct drm_display_mode *mode)
+{
+ u32 dst_w = mode->crtc_hdisplay;
+ u32 dst_h = mode->crtc_vdisplay;
+ u32 outsize = SUN8I_MIXER_SIZE(dst_w, dst_h);
+ bool interlaced = false;
+ u32 val;
+ struct sun8i_mixer *mixer = engine_to_sun8i_mixer(engine);
+ u32 bld_base = sun8i_blender_base(mixer);
+
+ DRM_DEBUG_DRIVER("Mode change, updating global size W: %u H: %u\n",
+ dst_w, dst_h);
+ regmap_write(mixer->engine.regs,
+ SUN8I_MIXER_GLOBAL_SIZE,
+ outsize);
+ regmap_write(mixer->engine.regs,
+ SUN8I_MIXER_BLEND_OUTSIZE(bld_base), outsize);
+
+ interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
+
+ if (interlaced)
+ val = SUN8I_MIXER_BLEND_OUTCTL_INTERLACED;
+ else
+ val = 0;
+
+ regmap_update_bits(mixer->engine.regs,
+ SUN8I_MIXER_BLEND_OUTCTL(bld_base),
+ SUN8I_MIXER_BLEND_OUTCTL_INTERLACED,
+ val);
+ DRM_DEBUG_DRIVER("Switching display mixer interlaced mode %s\n",
+ interlaced ? "on" : "off");
+}
+
static void sun8i_atomic_begin(struct sunxi_engine *engine,
struct drm_crtc_state *old_state)
{
@@ -325,6 +359,7 @@ static const struct sunxi_engine_ops sun8i_engine_ops = {
.commit = sun8i_mixer_commit,
.layers_init = sun8i_layers_init,
.atomic_begin = sun8i_atomic_begin,
+ .mode_set = sun8i_mode_set,
};
static struct regmap_config sun8i_mixer_regmap_config = {
@@ -99,36 +99,6 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel,
insize = SUN8I_MIXER_SIZE(src_w, src_h);
outsize = SUN8I_MIXER_SIZE(dst_w, dst_h);
- if (plane->type == DRM_PLANE_TYPE_PRIMARY) {
- bool interlaced = false;
- u32 val;
-
- DRM_DEBUG_DRIVER("Primary layer, updating global size W: %u H: %u\n",
- dst_w, dst_h);
- regmap_write(mixer->engine.regs,
- SUN8I_MIXER_GLOBAL_SIZE,
- outsize);
- regmap_write(mixer->engine.regs,
- SUN8I_MIXER_BLEND_OUTSIZE(bld_base), outsize);
-
- if (state->crtc)
- interlaced = state->crtc->state->adjusted_mode.flags
- & DRM_MODE_FLAG_INTERLACE;
-
- if (interlaced)
- val = SUN8I_MIXER_BLEND_OUTCTL_INTERLACED;
- else
- val = 0;
-
- regmap_update_bits(mixer->engine.regs,
- SUN8I_MIXER_BLEND_OUTCTL(bld_base),
- SUN8I_MIXER_BLEND_OUTCTL_INTERLACED,
- val);
-
- DRM_DEBUG_DRIVER("Switching display mixer interlaced mode %s\n",
- interlaced ? "on" : "off");
- }
-
/* Set height and width */
DRM_DEBUG_DRIVER("Layer source offset X: %d Y: %d\n",
state->src.x1 >> 16, state->src.y1 >> 16);
@@ -108,6 +108,14 @@ struct sunxi_engine_ops {
* This function is optional.
*/
void (*vblank_quirk)(struct sunxi_engine *engine);
+
+ /**
+ * @mode_set:
+ *
+ * This function is optional.
+ */
+ void (*mode_set)(struct sunxi_engine *engine,
+ struct drm_display_mode *mode);
};
/**