drm: rcar-du: Add max resolution support
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / gpu / drm / rcar-du / rcar_du_hdmicon.c
index 8abaaf2..61ca841 100644 (file)
@@ -25,7 +25,8 @@
 
 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)
@@ -37,8 +38,23 @@ static int rcar_du_hdmi_connector_get_modes(struct drm_connector *connector)
 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;
@@ -61,7 +77,8 @@ static void rcar_du_hdmi_connector_destroy(struct drm_connector *connector)
 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)
@@ -92,6 +109,7 @@ int rcar_du_hdmi_connector_init(struct rcar_du_device *rcdu,
        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);