mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-23 07:22:33 +00:00
166 lines
5.7 KiB
Diff
166 lines
5.7 KiB
Diff
|
From bfd6f67af0450e29378d390386210ac91c5dcfce Mon Sep 17 00:00:00 2001
|
||
|
From: Mateusz Kwiatkowski <kfyatek+publicgit@gmail.com>
|
||
|
Date: Thu, 15 Jul 2021 01:08:11 +0200
|
||
|
Subject: [PATCH] drm/vc4: Make VEC progressive modes readily
|
||
|
accessible
|
||
|
|
||
|
Add predefined modelines for the 240p (NTSC) and 288p (PAL) progressive
|
||
|
modes, and report them through vc4_vec_connector_get_modes().
|
||
|
|
||
|
Signed-off-by: Mateusz Kwiatkowski <kfyatek+publicgit@gmail.com>
|
||
|
---
|
||
|
drivers/gpu/drm/vc4/vc4_vec.c | 73 ++++++++++++++++++++++++++---------
|
||
|
1 file changed, 55 insertions(+), 18 deletions(-)
|
||
|
|
||
|
--- a/drivers/gpu/drm/vc4/vc4_vec.c
|
||
|
+++ b/drivers/gpu/drm/vc4/vc4_vec.c
|
||
|
@@ -228,7 +228,8 @@ enum vc4_vec_tv_mode_id {
|
||
|
};
|
||
|
|
||
|
struct vc4_vec_tv_mode {
|
||
|
- const struct drm_display_mode *mode;
|
||
|
+ const struct drm_display_mode *interlaced_mode;
|
||
|
+ const struct drm_display_mode *progressive_mode;
|
||
|
u32 config0;
|
||
|
u32 config1;
|
||
|
u32 custom_freq;
|
||
|
@@ -262,61 +263,81 @@ static const struct debugfs_reg32 vec_re
|
||
|
};
|
||
|
|
||
|
static const struct drm_display_mode drm_mode_480i = {
|
||
|
- DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 13500,
|
||
|
+ DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 13500,
|
||
|
720, 720 + 14, 720 + 14 + 64, 720 + 14 + 64 + 60, 0,
|
||
|
480, 480 + 7, 480 + 7 + 6, 525, 0,
|
||
|
DRM_MODE_FLAG_INTERLACE)
|
||
|
};
|
||
|
|
||
|
+static const struct drm_display_mode drm_mode_240p = {
|
||
|
+ DRM_MODE("720x240", DRM_MODE_TYPE_DRIVER, 13500,
|
||
|
+ 720, 720 + 14, 720 + 14 + 64, 720 + 14 + 64 + 60, 0,
|
||
|
+ 240, 240 + 3, 240 + 3 + 3, 262, 0, 0)
|
||
|
+};
|
||
|
+
|
||
|
static const struct drm_display_mode drm_mode_576i = {
|
||
|
- DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 13500,
|
||
|
+ DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 13500,
|
||
|
720, 720 + 20, 720 + 20 + 64, 720 + 20 + 64 + 60, 0,
|
||
|
576, 576 + 4, 576 + 4 + 6, 625, 0,
|
||
|
DRM_MODE_FLAG_INTERLACE)
|
||
|
};
|
||
|
|
||
|
+static const struct drm_display_mode drm_mode_288p = {
|
||
|
+ DRM_MODE("720x288", DRM_MODE_TYPE_DRIVER, 13500,
|
||
|
+ 720, 720 + 20, 720 + 20 + 64, 720 + 20 + 64 + 60, 0,
|
||
|
+ 288, 288 + 2, 288 + 2 + 3, 312, 0, 0)
|
||
|
+};
|
||
|
+
|
||
|
static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = {
|
||
|
[VC4_VEC_TV_MODE_NTSC] = {
|
||
|
- .mode = &drm_mode_480i,
|
||
|
+ .interlaced_mode = &drm_mode_480i,
|
||
|
+ .progressive_mode = &drm_mode_240p,
|
||
|
.config0 = VEC_CONFIG0_NTSC_STD | VEC_CONFIG0_PDEN,
|
||
|
.config1 = VEC_CONFIG1_C_CVBS_CVBS,
|
||
|
},
|
||
|
[VC4_VEC_TV_MODE_NTSC_J] = {
|
||
|
- .mode = &drm_mode_480i,
|
||
|
+ .interlaced_mode = &drm_mode_480i,
|
||
|
+ .progressive_mode = &drm_mode_240p,
|
||
|
.config0 = VEC_CONFIG0_NTSC_STD,
|
||
|
.config1 = VEC_CONFIG1_C_CVBS_CVBS,
|
||
|
},
|
||
|
[VC4_VEC_TV_MODE_NTSC_443] = {
|
||
|
/* NTSC with PAL chroma frequency */
|
||
|
- .mode = &drm_mode_480i,
|
||
|
+ .interlaced_mode = &drm_mode_480i,
|
||
|
+ .progressive_mode = &drm_mode_240p,
|
||
|
.config0 = VEC_CONFIG0_NTSC_STD,
|
||
|
.config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ,
|
||
|
.custom_freq = 0x2a098acb,
|
||
|
},
|
||
|
[VC4_VEC_TV_MODE_PAL] = {
|
||
|
- .mode = &drm_mode_576i,
|
||
|
+ .interlaced_mode = &drm_mode_576i,
|
||
|
+ .progressive_mode = &drm_mode_288p,
|
||
|
.config0 = VEC_CONFIG0_PAL_BDGHI_STD,
|
||
|
.config1 = VEC_CONFIG1_C_CVBS_CVBS,
|
||
|
},
|
||
|
[VC4_VEC_TV_MODE_PAL_M] = {
|
||
|
- .mode = &drm_mode_480i,
|
||
|
+ .interlaced_mode = &drm_mode_480i,
|
||
|
+ .progressive_mode = &drm_mode_240p,
|
||
|
.config0 = VEC_CONFIG0_PAL_M_STD,
|
||
|
.config1 = VEC_CONFIG1_C_CVBS_CVBS,
|
||
|
},
|
||
|
[VC4_VEC_TV_MODE_PAL_N] = {
|
||
|
- .mode = &drm_mode_576i,
|
||
|
+ .interlaced_mode = &drm_mode_576i,
|
||
|
+ .progressive_mode = &drm_mode_288p,
|
||
|
.config0 = VEC_CONFIG0_PAL_N_STD,
|
||
|
.config1 = VEC_CONFIG1_C_CVBS_CVBS,
|
||
|
},
|
||
|
[VC4_VEC_TV_MODE_PAL60] = {
|
||
|
/* PAL-M with chroma frequency of regular PAL */
|
||
|
- .mode = &drm_mode_480i,
|
||
|
+ .interlaced_mode = &drm_mode_480i,
|
||
|
+ .progressive_mode = &drm_mode_240p,
|
||
|
.config0 = VEC_CONFIG0_PAL_M_STD,
|
||
|
.config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ,
|
||
|
.custom_freq = 0x2a098acb,
|
||
|
},
|
||
|
[VC4_VEC_TV_MODE_SECAM] = {
|
||
|
- .mode = &drm_mode_576i,
|
||
|
+ .interlaced_mode = &drm_mode_576i,
|
||
|
+ .progressive_mode = &drm_mode_288p,
|
||
|
.config0 = VEC_CONFIG0_SECAM_STD,
|
||
|
.config1 = VEC_CONFIG1_C_CVBS_CVBS,
|
||
|
.custom_freq = 0x29c71c72,
|
||
|
@@ -370,16 +391,32 @@ vc4_vec_connector_detect(struct drm_conn
|
||
|
static int vc4_vec_connector_get_modes(struct drm_connector *connector)
|
||
|
{
|
||
|
struct drm_connector_state *state = connector->state;
|
||
|
- struct drm_display_mode *mode;
|
||
|
+ struct drm_display_mode *interlaced_mode, *progressive_mode;
|
||
|
|
||
|
- mode = drm_mode_duplicate(connector->dev,
|
||
|
- vc4_vec_tv_modes[state->tv.mode].mode);
|
||
|
- if (!mode) {
|
||
|
+ interlaced_mode =
|
||
|
+ drm_mode_duplicate(connector->dev,
|
||
|
+ vc4_vec_tv_modes[state->tv.mode].interlaced_mode);
|
||
|
+ progressive_mode =
|
||
|
+ drm_mode_duplicate(connector->dev,
|
||
|
+ vc4_vec_tv_modes[state->tv.mode].progressive_mode);
|
||
|
+ if (!interlaced_mode || !progressive_mode) {
|
||
|
DRM_ERROR("Failed to create a new display mode\n");
|
||
|
+ drm_mode_destroy(connector->dev, interlaced_mode);
|
||
|
+ drm_mode_destroy(connector->dev, progressive_mode);
|
||
|
return -ENOMEM;
|
||
|
}
|
||
|
|
||
|
- drm_mode_probed_add(connector, mode);
|
||
|
+ if (connector->cmdline_mode.specified &&
|
||
|
+ connector->cmdline_mode.refresh_specified &&
|
||
|
+ !connector->cmdline_mode.interlace)
|
||
|
+ /* progressive mode set at boot, let's make it preferred */
|
||
|
+ progressive_mode->type |= DRM_MODE_TYPE_PREFERRED;
|
||
|
+ else
|
||
|
+ /* otherwise, interlaced mode is preferred */
|
||
|
+ interlaced_mode->type |= DRM_MODE_TYPE_PREFERRED;
|
||
|
+
|
||
|
+ drm_mode_probed_add(connector, interlaced_mode);
|
||
|
+ drm_mode_probed_add(connector, progressive_mode);
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
@@ -576,7 +613,7 @@ static int vc4_vec_encoder_atomic_check(
|
||
|
struct drm_connector_state *conn_state)
|
||
|
{
|
||
|
const struct drm_display_mode *reference_mode =
|
||
|
- vc4_vec_tv_modes[conn_state->tv.mode].mode;
|
||
|
+ vc4_vec_tv_modes[conn_state->tv.mode].interlaced_mode;
|
||
|
|
||
|
if (crtc_state->adjusted_mode.crtc_clock != reference_mode->clock ||
|
||
|
crtc_state->adjusted_mode.crtc_htotal != reference_mode->htotal ||
|