static int rcar_du_hdmi_connector_get_modes(struct drm_connector *connector)
{
- struct drm_encoder *encoder = connector->encoder;
+ struct rcar_du_connector *con = to_rcar_connector(connector);
+ struct drm_encoder *encoder = rcar_encoder_to_drm_encoder(con->encoder);
struct drm_encoder_slave_funcs *sfuncs = to_slave_funcs(encoder);
if (sfuncs->get_modes == NULL)
static int rcar_du_hdmi_connector_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
- struct drm_encoder *encoder = connector->encoder;
+ struct rcar_du_connector *con = to_rcar_connector(connector);
+ struct drm_encoder *encoder = rcar_encoder_to_drm_encoder(con->encoder);
struct drm_encoder_slave_funcs *sfuncs = to_slave_funcs(encoder);
+ struct rcar_du_device *rcdu = connector->dev->dev_private;
+ unsigned int max_width, max_height;
+ bool laced;
+
+ max_width = rcdu->info->max_xres;
+ max_height = rcdu->info->max_yres;
+ laced = rcdu->info->interlace;
+
+ if ((mode->hdisplay * mode->vdisplay) > (max_width * max_height))
+ return MODE_BAD_WIDTH;
+
+ if (((mode->hdisplay * mode->vdisplay) == (max_width * max_height))
+ && (laced) && (!(mode->flags & DRM_MODE_FLAG_INTERLACE)))
+ return MODE_BAD;
if (sfuncs->mode_valid == NULL)
return MODE_OK;
static enum drm_connector_status
rcar_du_hdmi_connector_detect(struct drm_connector *connector, bool force)
{
- struct drm_encoder *encoder = connector->encoder;
+ struct rcar_du_connector *con = to_rcar_connector(connector);
+ struct drm_encoder *encoder = rcar_encoder_to_drm_encoder(con->encoder);
struct drm_encoder_slave_funcs *sfuncs = to_slave_funcs(encoder);
if (sfuncs->detect == NULL)
connector = &rcon->connector;
connector->display_info.width_mm = 0;
connector->display_info.height_mm = 0;
+ connector->interlace_allowed = true;
ret = drm_connector_init(rcdu->ddev, connector, &connector_funcs,
DRM_MODE_CONNECTOR_HDMIA);