mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 01:49:46 +00:00
drm: rp1: rp1-vec: Experimental support for 405 and 819-line TV
Add video mode "544x380i" for obsolete TV System A (405 lines) Add video mode "848x738i" for obsolete TV System E (819 lines) Experimental change, in testing. Currently the 819-line mode has rather non-square pixels (due to the inconvenience of changing VDAC clock from 108 MHz, and a 1024-column width limit in VEC). The new modes are monochrome only. Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
This commit is contained in:
committed by
njhollinghurst
parent
89bd4e64da
commit
3e0f89dc54
@@ -231,6 +231,21 @@ static const struct drm_display_mode rp1vec_modes[4] = {
|
||||
}
|
||||
};
|
||||
|
||||
static const struct drm_display_mode rp1vec_extra_modes[] = {
|
||||
{ /* Experimental 405-line mode */
|
||||
DRM_MODE("544x378i", DRM_MODE_TYPE_DRIVER, 6750,
|
||||
544, 544 + 12, 544 + 12 + 60, 667, 0,
|
||||
380, 380 + 0, 380 + 0 + 8, 405, 0,
|
||||
DRM_MODE_FLAG_INTERLACE)
|
||||
},
|
||||
{ /* Experimental 819-line mode (System E) */
|
||||
DRM_MODE("848x738i", DRM_MODE_TYPE_DRIVER, 21600,
|
||||
848, 848 + 26, 848 + 26 + 54, 1055, 0,
|
||||
738, 738 + 6, 738 + 6 + 1, 819, 0,
|
||||
DRM_MODE_FLAG_INTERLACE)
|
||||
}
|
||||
};
|
||||
|
||||
static int rp1vec_connector_get_modes(struct drm_connector *connector)
|
||||
{
|
||||
struct rp1_vec *vec = container_of(connector, struct rp1_vec, connector);
|
||||
@@ -264,6 +279,14 @@ static int rp1vec_connector_get_modes(struct drm_connector *connector)
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(rp1vec_extra_modes); i++) {
|
||||
struct drm_display_mode *mode =
|
||||
drm_mode_duplicate(connector->dev,
|
||||
&rp1vec_extra_modes[i]);
|
||||
drm_mode_probed_add(connector, mode);
|
||||
n++;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -324,15 +347,30 @@ static enum drm_mode_status rp1vec_mode_valid(struct drm_device *dev,
|
||||
mode->htotal * vtotal_full < 41 * mode->clock &&
|
||||
vdisplay_full <= 576)
|
||||
goto vgood;
|
||||
if (vtotal_full == 405 && !prog &&
|
||||
mode->htotal * vtotal_full > 39 * mode->clock &&
|
||||
mode->htotal * vtotal_full < 41 * mode->clock &&
|
||||
vdisplay_full <= 380)
|
||||
goto vgood;
|
||||
if (vtotal_full == 819 && !prog &&
|
||||
mode->htotal * vtotal_full > 39 * mode->clock &&
|
||||
mode->htotal * vtotal_full < 41 * mode->clock &&
|
||||
vdisplay_full <= 738)
|
||||
goto vgood;
|
||||
|
||||
return MODE_BAD;
|
||||
|
||||
vgood:
|
||||
/* Check pixel rate (kHz) and horizontal size limit */
|
||||
if (mode->clock == 13500 && mode->hdisplay <= 720)
|
||||
return MODE_OK;
|
||||
if (mode->clock >= 15428 && mode->clock <= 15429 &&
|
||||
if ((mode->clock == 15428 || mode->clock == 15429) &&
|
||||
mode->hdisplay <= 800)
|
||||
return MODE_OK;
|
||||
if (mode->clock == 6750 && mode->hdisplay <= 544)
|
||||
return MODE_OK;
|
||||
if (mode->clock == 21600 && mode->hdisplay <= 848)
|
||||
return MODE_OK;
|
||||
return MODE_BAD;
|
||||
}
|
||||
|
||||
@@ -454,8 +492,8 @@ static int rp1vec_platform_probe(struct platform_device *pdev)
|
||||
ret = drmm_mode_config_init(drm);
|
||||
if (ret)
|
||||
goto err_free_drm;
|
||||
drm->mode_config.max_width = 800;
|
||||
drm->mode_config.max_height = 576;
|
||||
drm->mode_config.max_width = 848;
|
||||
drm->mode_config.max_height = 738;
|
||||
drm->mode_config.fb_base = 0;
|
||||
drm->mode_config.preferred_depth = 32;
|
||||
drm->mode_config.prefer_shadow = 0;
|
||||
|
||||
@@ -324,6 +324,56 @@ static const struct rp1vec_hwmode rp1vec_hwmodes[3][2][2] = {
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* Derived from Andrew H's 405-line mode @ 6.75 MHz pixclk
|
||||
* with slightly extended horizontal active region to show 544 columns
|
||||
* and two more scanlines stolen from vertical blanking to give 380 rows
|
||||
* (which all seems to fall within the original 405-line specifications).
|
||||
* Corrected with first_field_odd = true.
|
||||
*/
|
||||
static const struct rp1vec_hwmode vintage_405line_mode = {
|
||||
.total_cols = 552,
|
||||
.rows_per_field = 190,
|
||||
.ref_hfp = 8,
|
||||
.ref_vfp = 0,
|
||||
.interlaced = true,
|
||||
.first_field_odd = true,
|
||||
.yuv_scaling = 0x11c00000,
|
||||
.back_end_regs = {
|
||||
0x06802900, 0x06f01430, 0x14d503cc, 0x00000000,
|
||||
0x000010de, 0x00000000, 0x00000007, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00d90195, 0x000e00ca, 0x00cb00d8, 0x000a0195,
|
||||
0x00000000, 0x007bffff, 0x3b1389d8, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x0be20200, 0x20f0f800, 0x265c7f00, 0x000843fe,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* First plausible attempt at an 819-line mode (System E) @ 21.6 MHz.
|
||||
* (NB: Pixels are not square; due to the currently-fixed 108 MHz VDAC
|
||||
* rate and 1024-column width limit, we can't conveniently do better.)
|
||||
*/
|
||||
static const struct rp1vec_hwmode vintage_819line_mode = {
|
||||
.total_cols = 856,
|
||||
.rows_per_field = 369,
|
||||
.ref_hfp = 22,
|
||||
.ref_vfp = 6,
|
||||
.interlaced = true,
|
||||
.first_field_odd = true,
|
||||
.yuv_scaling = 0x1d200000,
|
||||
.back_end_regs = {
|
||||
0x03a7145f, 0x03c10a08, 0x0a4d0114, 0x00000000,
|
||||
0x000008a6, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x01c10330, 0x00270196, 0x019701c0, 0x000c0333,
|
||||
0x00000000, 0x007bffff, 0x3b1389d8, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x0be20200, 0x20f0f800, 0x265c7f00, 0x00084126,
|
||||
},
|
||||
};
|
||||
|
||||
void rp1vec_hw_setup(struct rp1_vec *vec,
|
||||
u32 in_format,
|
||||
struct drm_display_mode const *mode,
|
||||
@@ -335,12 +385,22 @@ void rp1vec_hw_setup(struct rp1_vec *vec,
|
||||
|
||||
/* Pick the appropriate "base" mode, which we may modify */
|
||||
mode_ilaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
|
||||
if (mode->vtotal >= 272 * (1 + mode_ilaced))
|
||||
mode_family = 1;
|
||||
else
|
||||
mode_family = (tvstd == RP1VEC_TVSTD_PAL_M || tvstd == RP1VEC_TVSTD_PAL60) ? 2 : 0;
|
||||
mode_narrow = (mode->clock >= 14336);
|
||||
hwm = &rp1vec_hwmodes[mode_family][mode_ilaced][mode_narrow];
|
||||
if (mode->vtotal == 405 && mode_ilaced) { /* somewhat tested */
|
||||
hwm = &vintage_405line_mode;
|
||||
mode_family = 1;
|
||||
} else if (mode->vtotal == 819 && mode_ilaced) { /* XXXperimental */
|
||||
hwm = &vintage_819line_mode;
|
||||
mode_family = 1;
|
||||
} else {
|
||||
if (mode->vtotal >= 272 * (1 + mode_ilaced))
|
||||
mode_family = 1;
|
||||
else if (tvstd == RP1VEC_TVSTD_PAL_M || tvstd == RP1VEC_TVSTD_PAL60)
|
||||
mode_family = 2;
|
||||
else
|
||||
mode_family = 0;
|
||||
hwm = &rp1vec_hwmodes[mode_family][mode_ilaced][mode_narrow];
|
||||
}
|
||||
dev_info(&vec->pdev->dev,
|
||||
"%s: in_fmt=\'%c%c%c%c\' mode=%dx%d%s [%d%d%d] tvstd=%d (%s)",
|
||||
__func__, in_format, in_format >> 8, in_format >> 16, in_format >> 24,
|
||||
|
||||
Reference in New Issue
Block a user