drm/omap: fix analog tv-out modecheck

omapdrm rejects all venc (analog tv-out) videomodes, due to somewhat
strict checking of the values, making tv-out unusable.

We only support two videomodes, one for PAL and one for NTSC, so instead
of trying to check every field in the videomode struct, this patch makes
the driver check only the pixel clock and the size of the display.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
This commit is contained in:
Tomi Valkeinen 2017-06-13 12:02:09 +03:00
parent 2419672f4c
commit beea6214d1
1 changed files with 51 additions and 14 deletions

View File

@ -263,6 +263,12 @@ static const struct venc_config venc_config_pal_bdghi = {
.fid_ext_start_y__fid_ext_offset_y = 0x01380005,
};
enum venc_videomode {
VENC_MODE_UNKNOWN,
VENC_MODE_PAL,
VENC_MODE_NTSC,
};
static const struct videomode omap_dss_pal_vm = {
.hactive = 720,
.vactive = 574,
@ -297,6 +303,24 @@ static const struct videomode omap_dss_ntsc_vm = {
DISPLAY_FLAGS_SYNC_NEGEDGE,
};
static enum venc_videomode venc_get_videomode(const struct videomode *vm)
{
if (!(vm->flags & DISPLAY_FLAGS_INTERLACED))
return VENC_MODE_UNKNOWN;
if (vm->pixelclock == omap_dss_pal_vm.pixelclock &&
vm->hactive == omap_dss_pal_vm.hactive &&
vm->vactive == omap_dss_pal_vm.vactive)
return VENC_MODE_PAL;
if (vm->pixelclock == omap_dss_ntsc_vm.pixelclock &&
vm->hactive == omap_dss_ntsc_vm.hactive &&
vm->vactive == omap_dss_ntsc_vm.vactive)
return VENC_MODE_NTSC;
return VENC_MODE_UNKNOWN;
}
static struct {
struct platform_device *pdev;
void __iomem *base;
@ -423,14 +447,14 @@ static void venc_runtime_put(void)
static const struct venc_config *venc_timings_to_config(struct videomode *vm)
{
if (memcmp(&omap_dss_pal_vm, vm, sizeof(*vm)) == 0)
switch (venc_get_videomode(vm)) {
default:
WARN_ON_ONCE(1);
case VENC_MODE_PAL:
return &venc_config_pal_trm;
if (memcmp(&omap_dss_ntsc_vm, vm, sizeof(*vm)) == 0)
case VENC_MODE_NTSC:
return &venc_config_ntsc_trm;
BUG();
return NULL;
}
}
static int venc_power_on(struct omap_dss_device *dssdev)
@ -541,15 +565,28 @@ static void venc_display_disable(struct omap_dss_device *dssdev)
static void venc_set_timings(struct omap_dss_device *dssdev,
struct videomode *vm)
{
struct videomode actual_vm;
DSSDBG("venc_set_timings\n");
mutex_lock(&venc.venc_lock);
switch (venc_get_videomode(vm)) {
default:
WARN_ON_ONCE(1);
case VENC_MODE_PAL:
actual_vm = omap_dss_pal_vm;
break;
case VENC_MODE_NTSC:
actual_vm = omap_dss_ntsc_vm;
break;
}
/* Reset WSS data when the TV standard changes. */
if (memcmp(&venc.vm, vm, sizeof(*vm)))
if (memcmp(&venc.vm, &actual_vm, sizeof(actual_vm)))
venc.wss_data = 0;
venc.vm = *vm;
venc.vm = actual_vm;
dispc_set_tv_pclk(13500000);
@ -561,13 +598,13 @@ static int venc_check_timings(struct omap_dss_device *dssdev,
{
DSSDBG("venc_check_timings\n");
if (memcmp(&omap_dss_pal_vm, vm, sizeof(*vm)) == 0)
switch (venc_get_videomode(vm)) {
case VENC_MODE_PAL:
case VENC_MODE_NTSC:
return 0;
if (memcmp(&omap_dss_ntsc_vm, vm, sizeof(*vm)) == 0)
return 0;
default:
return -EINVAL;
}
}
static void venc_get_timings(struct omap_dss_device *dssdev,