Commit 41322aa6 authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Tomi Valkeinen

drm/omap: Pass drm_display_mode to .check_timings() and .set_timings()

The omap_dss_device .check_timings() and .set_timings() operations
operate on struct videomode, while the DRM API operates on struct
drm_display_mode. This forces conversion from to videomode in the
callers. While that's not a problem per se, it creates a difference with
the drm_bridge API.

Replace the videomode parameter to the .check_timings() and
.set_timings() operations with a drm_display_mode. This pushed the
conversion to videomode down to the DSS devices in some cases. If needed
they will be converted to operate on drm_display_mode natively.
Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: default avatarSebastian Reichel <sebastian.reichel@collabora.com>
Tested-by: default avatarSebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: default avatarTomi Valkeinen <tomi.valkeinen@ti.com>
parent d68164fe
...@@ -1127,20 +1127,20 @@ static int dsicm_get_modes(struct omap_dss_device *dssdev, ...@@ -1127,20 +1127,20 @@ static int dsicm_get_modes(struct omap_dss_device *dssdev,
} }
static int dsicm_check_timings(struct omap_dss_device *dssdev, static int dsicm_check_timings(struct omap_dss_device *dssdev,
struct videomode *vm) struct drm_display_mode *mode)
{ {
struct panel_drv_data *ddata = to_panel_data(dssdev); struct panel_drv_data *ddata = to_panel_data(dssdev);
int ret = 0; int ret = 0;
if (vm->hactive != ddata->vm.hactive) if (mode->hdisplay != ddata->vm.hactive)
ret = -EINVAL; ret = -EINVAL;
if (vm->vactive != ddata->vm.vactive) if (mode->vdisplay != ddata->vm.vactive)
ret = -EINVAL; ret = -EINVAL;
if (ret) { if (ret) {
dev_warn(dssdev->dev, "wrong resolution: %d x %d", dev_warn(dssdev->dev, "wrong resolution: %d x %d",
vm->hactive, vm->vactive); mode->hdisplay, mode->vdisplay);
dev_warn(dssdev->dev, "panel resolution: %d x %d", dev_warn(dssdev->dev, "panel resolution: %d x %d",
ddata->vm.hactive, ddata->vm.vactive); ddata->vm.hactive, ddata->vm.vactive);
} }
......
...@@ -459,7 +459,7 @@ static void dpi_display_disable(struct omap_dss_device *dssdev) ...@@ -459,7 +459,7 @@ static void dpi_display_disable(struct omap_dss_device *dssdev)
} }
static void dpi_set_timings(struct omap_dss_device *dssdev, static void dpi_set_timings(struct omap_dss_device *dssdev,
const struct videomode *vm) const struct drm_display_mode *mode)
{ {
struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev); struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
...@@ -467,13 +467,13 @@ static void dpi_set_timings(struct omap_dss_device *dssdev, ...@@ -467,13 +467,13 @@ static void dpi_set_timings(struct omap_dss_device *dssdev,
mutex_lock(&dpi->lock); mutex_lock(&dpi->lock);
dpi->vm = *vm; drm_display_mode_to_videomode(mode, &dpi->vm);
mutex_unlock(&dpi->lock); mutex_unlock(&dpi->lock);
} }
static int dpi_check_timings(struct omap_dss_device *dssdev, static int dpi_check_timings(struct omap_dss_device *dssdev,
struct videomode *vm) struct drm_display_mode *mode)
{ {
struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev); struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
int lck_div, pck_div; int lck_div, pck_div;
...@@ -482,20 +482,20 @@ static int dpi_check_timings(struct omap_dss_device *dssdev, ...@@ -482,20 +482,20 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
struct dpi_clk_calc_ctx ctx; struct dpi_clk_calc_ctx ctx;
bool ok; bool ok;
if (vm->hactive % 8 != 0) if (mode->hdisplay % 8 != 0)
return -EINVAL; return -EINVAL;
if (vm->pixelclock == 0) if (mode->clock == 0)
return -EINVAL; return -EINVAL;
if (dpi->pll) { if (dpi->pll) {
ok = dpi_pll_clk_calc(dpi, vm->pixelclock, &ctx); ok = dpi_pll_clk_calc(dpi, mode->clock * 1000, &ctx);
if (!ok) if (!ok)
return -EINVAL; return -EINVAL;
fck = ctx.pll_cinfo.clkout[ctx.clkout_idx]; fck = ctx.pll_cinfo.clkout[ctx.clkout_idx];
} else { } else {
ok = dpi_dss_clk_calc(dpi, vm->pixelclock, &ctx); ok = dpi_dss_clk_calc(dpi, mode->clock * 1000, &ctx);
if (!ok) if (!ok)
return -EINVAL; return -EINVAL;
...@@ -507,7 +507,7 @@ static int dpi_check_timings(struct omap_dss_device *dssdev, ...@@ -507,7 +507,7 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
pck = fck / lck_div / pck_div; pck = fck / lck_div / pck_div;
vm->pixelclock = pck; mode->clock = pck / 1000;
return 0; return 0;
} }
......
...@@ -249,15 +249,15 @@ static void hdmi_power_off_full(struct omap_hdmi *hdmi) ...@@ -249,15 +249,15 @@ static void hdmi_power_off_full(struct omap_hdmi *hdmi)
} }
static void hdmi_display_set_timings(struct omap_dss_device *dssdev, static void hdmi_display_set_timings(struct omap_dss_device *dssdev,
const struct videomode *vm) const struct drm_display_mode *mode)
{ {
struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev); struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
mutex_lock(&hdmi->lock); mutex_lock(&hdmi->lock);
hdmi->cfg.vm = *vm; drm_display_mode_to_videomode(mode, &hdmi->cfg.vm);
dispc_set_tv_pclk(hdmi->dss->dispc, vm->pixelclock); dispc_set_tv_pclk(hdmi->dss->dispc, mode->clock * 1000);
mutex_unlock(&hdmi->lock); mutex_unlock(&hdmi->lock);
} }
......
...@@ -248,15 +248,15 @@ static void hdmi_power_off_full(struct omap_hdmi *hdmi) ...@@ -248,15 +248,15 @@ static void hdmi_power_off_full(struct omap_hdmi *hdmi)
} }
static void hdmi_display_set_timings(struct omap_dss_device *dssdev, static void hdmi_display_set_timings(struct omap_dss_device *dssdev,
const struct videomode *vm) const struct drm_display_mode *mode)
{ {
struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev); struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
mutex_lock(&hdmi->lock); mutex_lock(&hdmi->lock);
hdmi->cfg.vm = *vm; drm_display_mode_to_videomode(mode, &hdmi->cfg.vm);
dispc_set_tv_pclk(hdmi->dss->dispc, vm->pixelclock); dispc_set_tv_pclk(hdmi->dss->dispc, mode->clock * 1000);
mutex_unlock(&hdmi->lock); mutex_unlock(&hdmi->lock);
} }
......
...@@ -366,9 +366,9 @@ struct omap_dss_device_ops { ...@@ -366,9 +366,9 @@ struct omap_dss_device_ops {
void (*post_disable)(struct omap_dss_device *dssdev); void (*post_disable)(struct omap_dss_device *dssdev);
int (*check_timings)(struct omap_dss_device *dssdev, int (*check_timings)(struct omap_dss_device *dssdev,
struct videomode *vm); struct drm_display_mode *mode);
void (*set_timings)(struct omap_dss_device *dssdev, void (*set_timings)(struct omap_dss_device *dssdev,
const struct videomode *vm); const struct drm_display_mode *mode);
bool (*detect)(struct omap_dss_device *dssdev); bool (*detect)(struct omap_dss_device *dssdev);
......
...@@ -206,36 +206,37 @@ static void sdi_display_disable(struct omap_dss_device *dssdev) ...@@ -206,36 +206,37 @@ static void sdi_display_disable(struct omap_dss_device *dssdev)
} }
static void sdi_set_timings(struct omap_dss_device *dssdev, static void sdi_set_timings(struct omap_dss_device *dssdev,
const struct videomode *vm) const struct drm_display_mode *mode)
{ {
struct sdi_device *sdi = dssdev_to_sdi(dssdev); struct sdi_device *sdi = dssdev_to_sdi(dssdev);
sdi->vm = *vm; drm_display_mode_to_videomode(mode, &sdi->vm);
} }
static int sdi_check_timings(struct omap_dss_device *dssdev, static int sdi_check_timings(struct omap_dss_device *dssdev,
struct videomode *vm) struct drm_display_mode *mode)
{ {
struct sdi_device *sdi = dssdev_to_sdi(dssdev); struct sdi_device *sdi = dssdev_to_sdi(dssdev);
struct dispc_clock_info dispc_cinfo; struct dispc_clock_info dispc_cinfo;
unsigned long pixelclock = mode->clock * 1000;
unsigned long fck; unsigned long fck;
unsigned long pck; unsigned long pck;
int r; int r;
if (vm->pixelclock == 0) if (pixelclock == 0)
return -EINVAL; return -EINVAL;
r = sdi_calc_clock_div(sdi, vm->pixelclock, &fck, &dispc_cinfo); r = sdi_calc_clock_div(sdi, pixelclock, &fck, &dispc_cinfo);
if (r) if (r)
return r; return r;
pck = fck / dispc_cinfo.lck_div / dispc_cinfo.pck_div; pck = fck / dispc_cinfo.lck_div / dispc_cinfo.pck_div;
if (pck != vm->pixelclock) { if (pck != pixelclock) {
DSSWARN("Pixel clock adjusted from %lu Hz to %lu Hz\n", DSSWARN("Pixel clock adjusted from %lu Hz to %lu Hz\n",
vm->pixelclock, pck); pixelclock, pck);
vm->pixelclock = pck; mode->clock = pck / 1000;
} }
return 0; return 0;
......
...@@ -544,29 +544,29 @@ static int venc_get_modes(struct omap_dss_device *dssdev, ...@@ -544,29 +544,29 @@ static int venc_get_modes(struct omap_dss_device *dssdev,
return ARRAY_SIZE(modes); return ARRAY_SIZE(modes);
} }
static enum venc_videomode venc_get_videomode(const struct videomode *vm) static enum venc_videomode venc_get_videomode(const struct drm_display_mode *mode)
{ {
if (!(vm->flags & DISPLAY_FLAGS_INTERLACED)) if (!(mode->flags & DRM_MODE_FLAG_INTERLACE))
return VENC_MODE_UNKNOWN; return VENC_MODE_UNKNOWN;
if (vm->pixelclock == omap_dss_pal_vm.pixelclock && if (mode->clock == omap_dss_pal_vm.pixelclock / 1000 &&
vm->hactive == omap_dss_pal_vm.hactive && mode->hdisplay == omap_dss_pal_vm.hactive &&
vm->vactive == omap_dss_pal_vm.vactive) mode->vdisplay == omap_dss_pal_vm.vactive)
return VENC_MODE_PAL; return VENC_MODE_PAL;
if (vm->pixelclock == omap_dss_ntsc_vm.pixelclock && if (mode->clock == omap_dss_ntsc_vm.pixelclock / 1000 &&
vm->hactive == omap_dss_ntsc_vm.hactive && mode->hdisplay == omap_dss_ntsc_vm.hactive &&
vm->vactive == omap_dss_ntsc_vm.vactive) mode->vdisplay == omap_dss_ntsc_vm.vactive)
return VENC_MODE_NTSC; return VENC_MODE_NTSC;
return VENC_MODE_UNKNOWN; return VENC_MODE_UNKNOWN;
} }
static void venc_set_timings(struct omap_dss_device *dssdev, static void venc_set_timings(struct omap_dss_device *dssdev,
const struct videomode *vm) const struct drm_display_mode *mode)
{ {
struct venc_device *venc = dssdev_to_venc(dssdev); struct venc_device *venc = dssdev_to_venc(dssdev);
enum venc_videomode venc_mode = venc_get_videomode(vm); enum venc_videomode venc_mode = venc_get_videomode(mode);
DSSDBG("venc_set_timings\n"); DSSDBG("venc_set_timings\n");
...@@ -591,17 +591,17 @@ static void venc_set_timings(struct omap_dss_device *dssdev, ...@@ -591,17 +591,17 @@ static void venc_set_timings(struct omap_dss_device *dssdev,
} }
static int venc_check_timings(struct omap_dss_device *dssdev, static int venc_check_timings(struct omap_dss_device *dssdev,
struct videomode *vm) struct drm_display_mode *mode)
{ {
DSSDBG("venc_check_timings\n"); DSSDBG("venc_check_timings\n");
switch (venc_get_videomode(vm)) { switch (venc_get_videomode(mode)) {
case VENC_MODE_PAL: case VENC_MODE_PAL:
*vm = omap_dss_pal_vm; drm_display_mode_from_videomode(&omap_dss_pal_vm, mode);
return 0; return 0;
case VENC_MODE_NTSC: case VENC_MODE_NTSC:
*vm = omap_dss_ntsc_vm; drm_display_mode_from_videomode(&omap_dss_ntsc_vm, mode);
return 0; return 0;
default: default:
......
...@@ -245,22 +245,19 @@ enum drm_mode_status omap_connector_mode_fixup(struct omap_dss_device *dssdev, ...@@ -245,22 +245,19 @@ enum drm_mode_status omap_connector_mode_fixup(struct omap_dss_device *dssdev,
const struct drm_display_mode *mode, const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode) struct drm_display_mode *adjusted_mode)
{ {
struct videomode vm = { 0 };
int ret; int ret;
drm_display_mode_to_videomode(mode, &vm); drm_mode_copy(adjusted_mode, mode);
for (; dssdev; dssdev = dssdev->next) { for (; dssdev; dssdev = dssdev->next) {
if (!dssdev->ops->check_timings) if (!dssdev->ops->check_timings)
continue; continue;
ret = dssdev->ops->check_timings(dssdev, &vm); ret = dssdev->ops->check_timings(dssdev, adjusted_mode);
if (ret) if (ret)
return MODE_BAD; return MODE_BAD;
} }
drm_display_mode_from_videomode(&vm, adjusted_mode);
return MODE_OK; return MODE_OK;
} }
......
...@@ -134,7 +134,7 @@ static void omap_encoder_mode_set(struct drm_encoder *encoder, ...@@ -134,7 +134,7 @@ static void omap_encoder_mode_set(struct drm_encoder *encoder,
for (dssdev = omap_encoder->output; dssdev; dssdev = dssdev->next) { for (dssdev = omap_encoder->output; dssdev; dssdev = dssdev->next) {
if (dssdev->ops->set_timings) if (dssdev->ops->set_timings)
dssdev->ops->set_timings(dssdev, &vm); dssdev->ops->set_timings(dssdev, adjusted_mode);
} }
/* Set the HDMI mode and HDMI infoframe if applicable. */ /* Set the HDMI mode and HDMI infoframe if applicable. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment