@@ -98,7 +98,7 @@ static void meson_encoder_hdmi_set_vclk(struct meson_encoder_hdmi *encoder_hdmi,
hdmi_freq = vclk_freq;
/* VENC double pixels for 1080i, 720p and YUV420 modes */
- if (meson_venc_hdmi_venc_repeat(vic) ||
+ if (meson_venc_hdmi_venc_repeat(priv, vic) ||
encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24)
venc_freq *= 2;
@@ -107,6 +107,11 @@ static void meson_encoder_hdmi_set_vclk(struct meson_encoder_hdmi *encoder_hdmi,
if (mode->flags & DRM_MODE_FLAG_DBLCLK)
venc_freq /= 2;
+ /* VCLK double pixels for 480p and 576p on S4 */
+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_S4))
+ if (vic == 2 || vic == 3 || vic == 17 || vic == 18)
+ vclk_freq *= 2;
+
dev_dbg(priv->dev, "vclk:%d phy=%d venc=%d hdmi=%d enci=%d\n",
phy_freq, vclk_freq, venc_freq, hdmi_freq,
priv->venc.hdmi_use_enci);
@@ -146,7 +151,7 @@ static enum drm_mode_status meson_encoder_hdmi_mode_valid(struct drm_bridge *bri
return meson_vclk_dmt_supported_freq(priv, mode->clock);
/* Check against supported VIC modes */
- } else if (!meson_venc_hdmi_supported_vic(vic))
+ } else if (!meson_venc_hdmi_supported_vic(priv, vic))
return MODE_BAD;
vclk_freq = mode->clock;
@@ -168,7 +173,7 @@ static enum drm_mode_status meson_encoder_hdmi_mode_valid(struct drm_bridge *bri
hdmi_freq = vclk_freq;
/* VENC double pixels for 1080i, 720p and YUV420 modes */
- if (meson_venc_hdmi_venc_repeat(vic) ||
+ if (meson_venc_hdmi_venc_repeat(priv, vic) ||
drm_mode_is_420_only(display_info, mode) ||
(!is_hdmi2_sink &&
drm_mode_is_420_also(display_info, mode)))
@@ -179,6 +184,11 @@ static enum drm_mode_status meson_encoder_hdmi_mode_valid(struct drm_bridge *bri
if (mode->flags & DRM_MODE_FLAG_DBLCLK)
venc_freq /= 2;
+ /* VCLK double pixels for 480p and 576p on S4 */
+ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_S4))
+ if (vic == 2 || vic == 3 || vic == 17 || vic == 18)
+ vclk_freq *= 2;
+
dev_dbg(priv->dev, "%s: vclk:%d phy=%d venc=%d hdmi=%d\n",
__func__, phy_freq, vclk_freq, venc_freq, hdmi_freq);
@@ -444,7 +454,8 @@ int meson_encoder_hdmi_probe(struct meson_drm *priv)
if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL) ||
meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
- meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A) ||
+ meson_vpu_is_compatible(priv, VPU_COMPATIBLE_S4))
drm_connector_attach_hdr_output_metadata_property(meson_encoder_hdmi->connector);
drm_connector_attach_max_bpc_property(meson_encoder_hdmi->connector, 8, 8);
@@ -878,7 +878,7 @@ meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode)
}
EXPORT_SYMBOL_GPL(meson_venc_hdmi_supported_mode);
-bool meson_venc_hdmi_supported_vic(int vic)
+bool meson_venc_hdmi_supported_vic(struct meson_drm *priv, int vic)
{
struct meson_hdmi_venc_vic_mode *vmode = meson_hdmi_venc_vic_modes;
@@ -917,7 +917,7 @@ static void meson_venc_hdmi_get_dmt_vmode(const struct drm_display_mode *mode,
dmt_mode->encp.max_lncnt = mode->vtotal - 1;
}
-static union meson_hdmi_venc_mode *meson_venc_hdmi_get_vic_vmode(int vic)
+static union meson_hdmi_venc_mode *meson_venc_hdmi_get_vic_vmode(struct meson_drm *priv, int vic)
{
struct meson_hdmi_venc_vic_mode *vmode = meson_hdmi_venc_vic_modes;
@@ -930,7 +930,7 @@ static union meson_hdmi_venc_mode *meson_venc_hdmi_get_vic_vmode(int vic)
return NULL;
}
-bool meson_venc_hdmi_venc_repeat(int vic)
+bool meson_venc_hdmi_venc_repeat(struct meson_drm *priv, int vic)
{
/* Repeat VENC pixels for 480/576i/p, 720p50/60 and 1080p50/60 */
if (vic == 6 || vic == 7 || /* 480i */
@@ -989,8 +989,8 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
venc_hdmi_latency = 1;
}
- if (meson_venc_hdmi_supported_vic(vic)) {
- vmode = meson_venc_hdmi_get_vic_vmode(vic);
+ if (meson_venc_hdmi_supported_vic(priv, vic)) {
+ vmode = meson_venc_hdmi_get_vic_vmode(priv, vic);
if (!vmode) {
dev_err(priv->dev, "%s: Fatal Error, unsupported mode "
DRM_MODE_FMT "\n", __func__,
@@ -1004,7 +1004,7 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
}
/* Repeat VENC pixels for 480/576i/p, 720p50/60 and 1080p50/60 */
- if (meson_venc_hdmi_venc_repeat(vic))
+ if (meson_venc_hdmi_venc_repeat(priv, vic))
venc_repeat = true;
eof_lines = mode->vsync_start - mode->vdisplay;
@@ -54,8 +54,8 @@ void meson_encl_load_gamma(struct meson_drm *priv);
/* HDMI Clock parameters */
enum drm_mode_status
meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode);
-bool meson_venc_hdmi_supported_vic(int vic);
-bool meson_venc_hdmi_venc_repeat(int vic);
+bool meson_venc_hdmi_supported_vic(struct meson_drm *priv, int vic);
+bool meson_venc_hdmi_venc_repeat(struct meson_drm *priv, int vic);
/* CVBS Timings and Parameters */
extern struct meson_cvbs_enci_mode meson_cvbs_enci_pal;