Message ID | 1403604240-16738-16-git-send-email-tomi.valkeinen@ti.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Hi, On Tuesday 24 June 2014 03:34 PM, Tomi Valkeinen wrote: > Make the omapdrm driver use the new HDMI ops when possible. > > omapdrm will call set_hdmi_mode (when available) to tell the encoder > driver whether the monitor is a DVI or HDMI monitor, and if it's an HDMI > monitor, omapdrm will call set_hdmi_infoframe to to set the AVI > infoframe. <snip> > @@ -89,6 +91,31 @@ static void omap_encoder_mode_set(struct drm_encoder *encoder, > struct drm_display_mode *mode, > struct drm_display_mode *adjusted_mode) > { > + struct drm_device *dev = encoder->dev; > + struct omap_encoder *omap_encoder = to_omap_encoder(encoder); > + struct omap_dss_device *dssdev = omap_encoder->dssdev; > + struct drm_connector *connector; > + bool hdmi_mode; > + int r; > + > + hdmi_mode = false; > + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { > + if (connector->encoder == encoder) { > + hdmi_mode = omap_connector_get_hdmi_mode(connector); > + break; > + } > + } > + > + if (dssdev->driver->set_hdmi_mode) > + dssdev->driver->set_hdmi_mode(dssdev, hdmi_mode); When a HDMI monitor is replaced with a DVI one, we call the set_hdmi_mode() driver op to set the mode to DVI. But we don't call set_hdmi_infoframe() when the mode is set back to DVI. Do we need to set avi infoframe registers back to a default value, or are those registers just ignored in DVI mode? > + > + if (hdmi_mode && dssdev->driver->set_hdmi_infoframe) { > + struct hdmi_avi_infoframe avi; > + > + r = drm_hdmi_avi_infoframe_from_display_mode(&avi, adjusted_mode); > + if (r == 0) > + dssdev->driver->set_hdmi_infoframe(dssdev, &avi); > + } > } > Archit -- To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 25/06/14 14:03, Archit Taneja wrote: > Hi, > > On Tuesday 24 June 2014 03:34 PM, Tomi Valkeinen wrote: >> Make the omapdrm driver use the new HDMI ops when possible. >> >> omapdrm will call set_hdmi_mode (when available) to tell the encoder >> driver whether the monitor is a DVI or HDMI monitor, and if it's an HDMI >> monitor, omapdrm will call set_hdmi_infoframe to to set the AVI >> infoframe. > > <snip> > > >> @@ -89,6 +91,31 @@ static void omap_encoder_mode_set(struct >> drm_encoder *encoder, >> struct drm_display_mode *mode, >> struct drm_display_mode *adjusted_mode) >> { >> + struct drm_device *dev = encoder->dev; >> + struct omap_encoder *omap_encoder = to_omap_encoder(encoder); >> + struct omap_dss_device *dssdev = omap_encoder->dssdev; >> + struct drm_connector *connector; >> + bool hdmi_mode; >> + int r; >> + >> + hdmi_mode = false; >> + list_for_each_entry(connector, &dev->mode_config.connector_list, >> head) { >> + if (connector->encoder == encoder) { >> + hdmi_mode = omap_connector_get_hdmi_mode(connector); >> + break; >> + } >> + } >> + >> + if (dssdev->driver->set_hdmi_mode) >> + dssdev->driver->set_hdmi_mode(dssdev, hdmi_mode); > > When a HDMI monitor is replaced with a DVI one, we call the > set_hdmi_mode() driver op to set the mode to DVI. But we don't call > set_hdmi_infoframe() when the mode is set back to DVI. Do we need to set > avi infoframe registers back to a default value, or are those registers > just ignored in DVI mode? If I'm not mistaken, infoframes are a HDMI thing. When in DVI mode, the device driver should clear/disable/something the infoframe registers, depending on the HW in question. Tomi
On 24/06/14 13:04, Tomi Valkeinen wrote: > Make the omapdrm driver use the new HDMI ops when possible. > > omapdrm will call set_hdmi_mode (when available) to tell the encoder > driver whether the monitor is a DVI or HDMI monitor, and if it's an HDMI > monitor, omapdrm will call set_hdmi_infoframe to to set the AVI > infoframe. > > Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> > Cc: Rob Clark <robdclark@gmail.com> > --- > drivers/gpu/drm/omapdrm/omap_connector.c | 12 ++++++++++++ > drivers/gpu/drm/omapdrm/omap_drv.h | 1 + > drivers/gpu/drm/omapdrm/omap_encoder.c | 27 +++++++++++++++++++++++++++ > 3 files changed, 40 insertions(+) Ah, I forgot to add dri-devel list for this one. Dave, is it ok if I queue this one via fbdev tree, as it depends on the previous patches on this series? Tomi > > diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c > index 86f4ead0441d..19492cd31f10 100644 > --- a/drivers/gpu/drm/omapdrm/omap_connector.c > +++ b/drivers/gpu/drm/omapdrm/omap_connector.c > @@ -32,8 +32,16 @@ struct omap_connector { > struct drm_connector base; > struct omap_dss_device *dssdev; > struct drm_encoder *encoder; > + bool hdmi_mode; > }; > > +bool omap_connector_get_hdmi_mode(struct drm_connector *connector) > +{ > + struct omap_connector *omap_connector = to_omap_connector(connector); > + > + return omap_connector->hdmi_mode; > +} > + > void copy_timings_omap_to_drm(struct drm_display_mode *mode, > struct omap_video_timings *timings) > { > @@ -162,10 +170,14 @@ static int omap_connector_get_modes(struct drm_connector *connector) > drm_mode_connector_update_edid_property( > connector, edid); > n = drm_add_edid_modes(connector, edid); > + > + omap_connector->hdmi_mode = > + drm_detect_hdmi_monitor(edid); > } else { > drm_mode_connector_update_edid_property( > connector, NULL); > } > + > kfree(edid); > } else { > struct drm_display_mode *mode = drm_mode_create(dev); > diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h > index 284b80fc3c54..c204c1e7ce87 100644 > --- a/drivers/gpu/drm/omapdrm/omap_drv.h > +++ b/drivers/gpu/drm/omapdrm/omap_drv.h > @@ -194,6 +194,7 @@ struct drm_encoder *omap_connector_attached_encoder( > struct drm_connector *connector); > void omap_connector_flush(struct drm_connector *connector, > int x, int y, int w, int h); > +bool omap_connector_get_hdmi_mode(struct drm_connector *connector); > > void copy_timings_omap_to_drm(struct drm_display_mode *mode, > struct omap_video_timings *timings); > diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c b/drivers/gpu/drm/omapdrm/omap_encoder.c > index 5290a88c681d..7445fb1491ae 100644 > --- a/drivers/gpu/drm/omapdrm/omap_encoder.c > +++ b/drivers/gpu/drm/omapdrm/omap_encoder.c > @@ -17,6 +17,8 @@ > * this program. If not, see <http://www.gnu.org/licenses/>. > */ > > +#include <drm/drm_edid.h> > + > #include "omap_drv.h" > > #include "drm_crtc.h" > @@ -89,6 +91,31 @@ static void omap_encoder_mode_set(struct drm_encoder *encoder, > struct drm_display_mode *mode, > struct drm_display_mode *adjusted_mode) > { > + struct drm_device *dev = encoder->dev; > + struct omap_encoder *omap_encoder = to_omap_encoder(encoder); > + struct omap_dss_device *dssdev = omap_encoder->dssdev; > + struct drm_connector *connector; > + bool hdmi_mode; > + int r; > + > + hdmi_mode = false; > + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { > + if (connector->encoder == encoder) { > + hdmi_mode = omap_connector_get_hdmi_mode(connector); > + break; > + } > + } > + > + if (dssdev->driver->set_hdmi_mode) > + dssdev->driver->set_hdmi_mode(dssdev, hdmi_mode); > + > + if (hdmi_mode && dssdev->driver->set_hdmi_infoframe) { > + struct hdmi_avi_infoframe avi; > + > + r = drm_hdmi_avi_infoframe_from_display_mode(&avi, adjusted_mode); > + if (r == 0) > + dssdev->driver->set_hdmi_infoframe(dssdev, &avi); > + } > } > > static void omap_encoder_prepare(struct drm_encoder *encoder) >
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c index 86f4ead0441d..19492cd31f10 100644 --- a/drivers/gpu/drm/omapdrm/omap_connector.c +++ b/drivers/gpu/drm/omapdrm/omap_connector.c @@ -32,8 +32,16 @@ struct omap_connector { struct drm_connector base; struct omap_dss_device *dssdev; struct drm_encoder *encoder; + bool hdmi_mode; }; +bool omap_connector_get_hdmi_mode(struct drm_connector *connector) +{ + struct omap_connector *omap_connector = to_omap_connector(connector); + + return omap_connector->hdmi_mode; +} + void copy_timings_omap_to_drm(struct drm_display_mode *mode, struct omap_video_timings *timings) { @@ -162,10 +170,14 @@ static int omap_connector_get_modes(struct drm_connector *connector) drm_mode_connector_update_edid_property( connector, edid); n = drm_add_edid_modes(connector, edid); + + omap_connector->hdmi_mode = + drm_detect_hdmi_monitor(edid); } else { drm_mode_connector_update_edid_property( connector, NULL); } + kfree(edid); } else { struct drm_display_mode *mode = drm_mode_create(dev); diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h index 284b80fc3c54..c204c1e7ce87 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.h +++ b/drivers/gpu/drm/omapdrm/omap_drv.h @@ -194,6 +194,7 @@ struct drm_encoder *omap_connector_attached_encoder( struct drm_connector *connector); void omap_connector_flush(struct drm_connector *connector, int x, int y, int w, int h); +bool omap_connector_get_hdmi_mode(struct drm_connector *connector); void copy_timings_omap_to_drm(struct drm_display_mode *mode, struct omap_video_timings *timings); diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c b/drivers/gpu/drm/omapdrm/omap_encoder.c index 5290a88c681d..7445fb1491ae 100644 --- a/drivers/gpu/drm/omapdrm/omap_encoder.c +++ b/drivers/gpu/drm/omapdrm/omap_encoder.c @@ -17,6 +17,8 @@ * this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <drm/drm_edid.h> + #include "omap_drv.h" #include "drm_crtc.h" @@ -89,6 +91,31 @@ static void omap_encoder_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { + struct drm_device *dev = encoder->dev; + struct omap_encoder *omap_encoder = to_omap_encoder(encoder); + struct omap_dss_device *dssdev = omap_encoder->dssdev; + struct drm_connector *connector; + bool hdmi_mode; + int r; + + hdmi_mode = false; + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + if (connector->encoder == encoder) { + hdmi_mode = omap_connector_get_hdmi_mode(connector); + break; + } + } + + if (dssdev->driver->set_hdmi_mode) + dssdev->driver->set_hdmi_mode(dssdev, hdmi_mode); + + if (hdmi_mode && dssdev->driver->set_hdmi_infoframe) { + struct hdmi_avi_infoframe avi; + + r = drm_hdmi_avi_infoframe_from_display_mode(&avi, adjusted_mode); + if (r == 0) + dssdev->driver->set_hdmi_infoframe(dssdev, &avi); + } } static void omap_encoder_prepare(struct drm_encoder *encoder)
Make the omapdrm driver use the new HDMI ops when possible. omapdrm will call set_hdmi_mode (when available) to tell the encoder driver whether the monitor is a DVI or HDMI monitor, and if it's an HDMI monitor, omapdrm will call set_hdmi_infoframe to to set the AVI infoframe. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> Cc: Rob Clark <robdclark@gmail.com> --- drivers/gpu/drm/omapdrm/omap_connector.c | 12 ++++++++++++ drivers/gpu/drm/omapdrm/omap_drv.h | 1 + drivers/gpu/drm/omapdrm/omap_encoder.c | 27 +++++++++++++++++++++++++++ 3 files changed, 40 insertions(+)