return pclk <= dispc->feat->max_tv_pclk;
}
-bool dispc_mgr_timings_ok(struct dispc_device *dispc, enum omap_channel channel,
- const struct videomode *vm)
+static int dispc_mgr_check_timings(struct dispc_device *dispc,
+ enum omap_channel channel,
+ const struct videomode *vm)
{
if (!_dispc_mgr_size_ok(dispc, vm->hactive, vm->vactive))
- return false;
+ return MODE_BAD;
if (!_dispc_mgr_pclk_ok(dispc, channel, vm->pixelclock))
- return false;
+ return MODE_BAD;
if (dss_mgr_is_lcd(channel)) {
/* TODO: OMAP4+ supports interlace for LCD outputs */
if (vm->flags & DISPLAY_FLAGS_INTERLACED)
- return false;
+ return MODE_BAD;
if (!_dispc_lcd_timings_ok(dispc, vm->hsync_len,
vm->hfront_porch, vm->hback_porch,
vm->vsync_len, vm->vfront_porch,
vm->vback_porch))
- return false;
+ return MODE_BAD;
}
- return true;
+ return MODE_OK;
}
static void _dispc_mgr_set_lcd_timings(struct dispc_device *dispc,
DSSDBG("channel %d xres %u yres %u\n", channel, t.hactive, t.vactive);
- if (!dispc_mgr_timings_ok(dispc, channel, &t)) {
+ if (dispc_mgr_check_timings(dispc, channel, &t)) {
BUG();
return;
}
.mgr_go_busy = dispc_mgr_go_busy,
.mgr_go = dispc_mgr_go,
.mgr_set_lcd_config = dispc_mgr_set_lcd_config,
+ .mgr_check_timings = dispc_mgr_check_timings,
.mgr_set_timings = dispc_mgr_set_timings,
.mgr_setup = dispc_mgr_setup,
.mgr_gamma_size = dispc_mgr_gamma_size,
struct videomode *vm)
{
struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
- enum omap_channel channel = dpi->output.dispc_channel;
int lck_div, pck_div;
unsigned long fck;
unsigned long pck;
if (vm->hactive % 8 != 0)
return -EINVAL;
- if (!dispc_mgr_timings_ok(dpi->dss->dispc, channel, vm))
- return -EINVAL;
-
if (vm->pixelclock == 0)
return -EINVAL;
unsigned long pck_min, unsigned long pck_max,
dispc_div_calc_func func, void *data);
-bool dispc_mgr_timings_ok(struct dispc_device *dispc,
- enum omap_channel channel,
- const struct videomode *vm);
int dispc_calc_clock_rates(struct dispc_device *dispc,
unsigned long dispc_fclk_rate,
struct dispc_clock_info *cinfo);
hdmi_power_off_core(hdmi);
}
-static int hdmi_display_check_timings(struct omap_dss_device *dssdev,
- struct videomode *vm)
-{
- struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
-
- if (!dispc_mgr_timings_ok(hdmi->dss->dispc, dssdev->dispc_channel, vm))
- return -EINVAL;
-
- return 0;
-}
-
static void hdmi_display_set_timings(struct omap_dss_device *dssdev,
const struct videomode *vm)
{
.enable = hdmi_display_enable,
.disable = hdmi_display_disable,
- .check_timings = hdmi_display_check_timings,
.set_timings = hdmi_display_set_timings,
.read_edid = hdmi_read_edid,
hdmi_power_off_core(hdmi);
}
-static int hdmi_display_check_timings(struct omap_dss_device *dssdev,
- struct videomode *vm)
-{
- struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
-
- if (!dispc_mgr_timings_ok(hdmi->dss->dispc, dssdev->dispc_channel, vm))
- return -EINVAL;
-
- return 0;
-}
-
static void hdmi_display_set_timings(struct omap_dss_device *dssdev,
const struct videomode *vm)
{
.enable = hdmi_display_enable,
.disable = hdmi_display_disable,
- .check_timings = hdmi_display_check_timings,
.set_timings = hdmi_display_set_timings,
.read_edid = hdmi_read_edid,
void (*mgr_set_lcd_config)(struct dispc_device *dispc,
enum omap_channel channel,
const struct dss_lcd_mgr_config *config);
+ int (*mgr_check_timings)(struct dispc_device *dispc,
+ enum omap_channel channel,
+ const struct videomode *vm);
void (*mgr_set_timings)(struct dispc_device *dispc,
enum omap_channel channel,
const struct videomode *vm);
static int sdi_check_timings(struct omap_dss_device *dssdev,
struct videomode *vm)
{
- struct sdi_device *sdi = dssdev_to_sdi(dssdev);
- enum omap_channel channel = dssdev->dispc_channel;
-
- if (!dispc_mgr_timings_ok(sdi->dss->dispc, channel, vm))
- return -EINVAL;
-
if (vm->pixelclock == 0)
return -EINVAL;
struct drm_display_mode *mode)
{
struct omap_connector *omap_connector = to_omap_connector(connector);
+ enum omap_channel channel = omap_connector->output->dispc_channel;
+ struct omap_drm_private *priv = connector->dev->dev_private;
struct omap_dss_device *dssdev;
struct videomode vm = {0};
struct drm_device *dev = connector->dev;
drm_display_mode_to_videomode(mode, &vm);
mode->vrefresh = drm_mode_vrefresh(mode);
+ r = priv->dispc_ops->mgr_check_timings(priv->dispc, channel, &vm);
+ if (r)
+ goto done;
+
for (dssdev = omap_connector->output; dssdev; dssdev = dssdev->next) {
if (!dssdev->ops->check_timings)
continue;
struct drm_connector_state *conn_state)
{
struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
+ enum omap_channel channel = omap_encoder->output->dispc_channel;
struct drm_device *dev = encoder->dev;
+ struct omap_drm_private *priv = dev->dev_private;
struct omap_dss_device *dssdev;
struct videomode vm = { 0 };
int ret;
drm_display_mode_to_videomode(&crtc_state->mode, &vm);
+ ret = priv->dispc_ops->mgr_check_timings(priv->dispc, channel, &vm);
+ if (ret)
+ goto done;
+
for (dssdev = omap_encoder->output; dssdev; dssdev = dssdev->next) {
if (!dssdev->ops->check_timings)
continue;
ret = dssdev->ops->check_timings(dssdev, &vm);
- if (ret) {
- dev_err(dev->dev, "invalid timings: %d\n", ret);
- return ret;
- }
+ if (ret)
+ goto done;
}
drm_display_mode_from_videomode(&vm, &crtc_state->adjusted_mode);
- return 0;
+done:
+ if (ret)
+ dev_err(dev->dev, "invalid timings: %d\n", ret);
+
+ return ret;
}
static const struct drm_encoder_helper_funcs omap_encoder_helper_funcs = {