diff options
author | Marcus Cooksey | 2016-02-29 17:32:02 -0600 |
---|---|---|
committer | Praneeth Bajjuri | 2016-03-16 16:48:13 -0500 |
commit | ba9386974bb3c977cbfa9a2ef9d09eda36ebc6bd (patch) | |
tree | 3a54024ff0faf7f58932fb8950a9c4214182f19a | |
parent | 764a4f8a51c7f65b9c3aec6f2e50d5222bf04b1a (diff) | |
download | kernel-video-ba9386974bb3c977cbfa9a2ef9d09eda36ebc6bd.tar.gz kernel-video-ba9386974bb3c977cbfa9a2ef9d09eda36ebc6bd.tar.xz kernel-video-ba9386974bb3c977cbfa9a2ef9d09eda36ebc6bd.zip |
OMAPDRM: Register HDMI HPD Callback for HDMI HPD Interrupts
HDMI hotplug detection is now achieved by registering
a DRM callback with the display driver. The display driver
will invoke this callback function when an HPD event occurs.
The HPD Poll worker task is used to reconfigure the display
mode based on monitor preferences.
Signed-off-by: Marcus Cooksey <mcooksey@ti.com>
Change-Id: I5c098bfdedffb83eab97b70c95c04c325140342c
-rw-r--r-- | drivers/gpu/drm/omapdrm/omap_connector.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/omapdrm/omap_drv.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/omapdrm/omap_drv.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/omapdrm/omap_irq.c | 25 |
4 files changed, 43 insertions, 0 deletions
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c index e5c72ee525a..5b02f8ad727 100644 --- a/drivers/gpu/drm/omapdrm/omap_connector.c +++ b/drivers/gpu/drm/omapdrm/omap_connector.c | |||
@@ -146,6 +146,9 @@ static enum drm_connector_status omap_connector_detect( | |||
146 | struct omap_dss_driver *dssdrv = dssdev->driver; | 146 | struct omap_dss_driver *dssdrv = dssdev->driver; |
147 | enum drm_connector_status ret; | 147 | enum drm_connector_status ret; |
148 | 148 | ||
149 | if (force) | ||
150 | ret = connector_status_connected; | ||
151 | |||
149 | if (dssdrv->detect) { | 152 | if (dssdrv->detect) { |
150 | if (dssdrv->detect(dssdev)) | 153 | if (dssdrv->detect(dssdev)) |
151 | ret = connector_status_connected; | 154 | ret = connector_status_connected; |
@@ -336,11 +339,21 @@ struct drm_connector *omap_connector_init(struct drm_device *dev, | |||
336 | omap_connector->encoder = encoder; | 339 | omap_connector->encoder = encoder; |
337 | 340 | ||
338 | connector = &omap_connector->base; | 341 | connector = &omap_connector->base; |
342 | connector->force = DRM_FORCE_ON; | ||
339 | 343 | ||
340 | drm_connector_init(dev, connector, &omap_connector_funcs, | 344 | drm_connector_init(dev, connector, &omap_connector_funcs, |
341 | connector_type); | 345 | connector_type); |
342 | drm_connector_helper_add(connector, &omap_connector_helper_funcs); | 346 | drm_connector_helper_add(connector, &omap_connector_helper_funcs); |
343 | 347 | ||
348 | if (dssdev->driver->register_hpd_callback) { | ||
349 | dssdev->driver->register_hpd_callback(dssdev, | ||
350 | omap_hdmi_hpd_irq_handler, | ||
351 | dev); | ||
352 | |||
353 | DBG("Registered ISR omap_drm_hdmi_hpd_irq"); | ||
354 | } | ||
355 | |||
356 | |||
344 | #if 0 /* enable when dss2 supports hotplug */ | 357 | #if 0 /* enable when dss2 supports hotplug */ |
345 | if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_HPD) | 358 | if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_HPD) |
346 | connector->polled = 0; | 359 | connector->polled = 0; |
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index ad35d9b5436..8526b2c427f 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c | |||
@@ -17,6 +17,7 @@ | |||
17 | * this program. If not, see <http://www.gnu.org/licenses/>. | 17 | * this program. If not, see <http://www.gnu.org/licenses/>. |
18 | */ | 18 | */ |
19 | 19 | ||
20 | #include <linux/interrupt.h> | ||
20 | #include "omap_drv.h" | 21 | #include "omap_drv.h" |
21 | 22 | ||
22 | #include "drm_crtc_helper.h" | 23 | #include "drm_crtc_helper.h" |
@@ -142,6 +143,7 @@ static int omap_connect_dssdevs(void) | |||
142 | 143 | ||
143 | for_each_dss_dev(dssdev) { | 144 | for_each_dss_dev(dssdev) { |
144 | r = dssdev->driver->connect(dssdev); | 145 | r = dssdev->driver->connect(dssdev); |
146 | |||
145 | if (r == -EPROBE_DEFER) { | 147 | if (r == -EPROBE_DEFER) { |
146 | omap_dss_put_device(dssdev); | 148 | omap_dss_put_device(dssdev); |
147 | goto cleanup; | 149 | goto cleanup; |
@@ -900,6 +902,7 @@ static int pdev_probe(struct platform_device *device) | |||
900 | 902 | ||
901 | DBG("%s", device->name); | 903 | DBG("%s", device->name); |
902 | return drm_platform_init(&omap_drm_driver, device); | 904 | return drm_platform_init(&omap_drm_driver, device); |
905 | |||
903 | } | 906 | } |
904 | 907 | ||
905 | static int pdev_remove(struct platform_device *device) | 908 | static int pdev_remove(struct platform_device *device) |
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h index d3394503333..12f3f295df6 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.h +++ b/drivers/gpu/drm/omapdrm/omap_drv.h | |||
@@ -151,6 +151,7 @@ int omap_gem_resume(struct device *dev); | |||
151 | int omap_irq_enable_vblank(struct drm_device *dev, int crtc_id); | 151 | int omap_irq_enable_vblank(struct drm_device *dev, int crtc_id); |
152 | void omap_irq_disable_vblank(struct drm_device *dev, int crtc_id); | 152 | void omap_irq_disable_vblank(struct drm_device *dev, int crtc_id); |
153 | irqreturn_t omap_irq_handler(int irq, void *arg); | 153 | irqreturn_t omap_irq_handler(int irq, void *arg); |
154 | irqreturn_t omap_hdmi_hpd_irq_handler(int irq, void *arg); | ||
154 | void omap_irq_preinstall(struct drm_device *dev); | 155 | void omap_irq_preinstall(struct drm_device *dev); |
155 | int omap_irq_postinstall(struct drm_device *dev); | 156 | int omap_irq_postinstall(struct drm_device *dev); |
156 | void omap_irq_uninstall(struct drm_device *dev); | 157 | void omap_irq_uninstall(struct drm_device *dev); |
@@ -367,6 +368,7 @@ struct drm_gem_object *omap_gem_new_ext(struct drm_device *dev, | |||
367 | 368 | ||
368 | void omap_gem_op_update(void); | 369 | void omap_gem_op_update(void); |
369 | int omap_gem_set_sync_object(struct drm_gem_object *obj, void *syncobj); | 370 | int omap_gem_set_sync_object(struct drm_gem_object *obj, void *syncobj); |
371 | |||
370 | /*********************************/ | 372 | /*********************************/ |
371 | 373 | ||
372 | 374 | ||
diff --git a/drivers/gpu/drm/omapdrm/omap_irq.c b/drivers/gpu/drm/omapdrm/omap_irq.c index 3eb097efc48..86d88bbc0f0 100644 --- a/drivers/gpu/drm/omapdrm/omap_irq.c +++ b/drivers/gpu/drm/omapdrm/omap_irq.c | |||
@@ -18,6 +18,7 @@ | |||
18 | */ | 18 | */ |
19 | 19 | ||
20 | #include "omap_drv.h" | 20 | #include "omap_drv.h" |
21 | #include "drm_fb_helper.h" | ||
21 | 22 | ||
22 | static DEFINE_SPINLOCK(list_lock); | 23 | static DEFINE_SPINLOCK(list_lock); |
23 | 24 | ||
@@ -187,6 +188,30 @@ void omap_irq_disable_vblank(struct drm_device *dev, int crtc_id) | |||
187 | dispc_runtime_put(); | 188 | dispc_runtime_put(); |
188 | } | 189 | } |
189 | 190 | ||
191 | irqreturn_t omap_hdmi_hpd_irq_handler(int irq, void *arg) | ||
192 | { | ||
193 | struct drm_device *dev = (struct drm_device *)arg; | ||
194 | struct drm_connector *connector; | ||
195 | struct omap_drm_private *priv = dev->dev_private; | ||
196 | unsigned long flags = 0; | ||
197 | |||
198 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
199 | if ((connector->connector_type == DRM_MODE_CONNECTOR_HDMIA) || | ||
200 | (connector->connector_type == DRM_MODE_CONNECTOR_HDMIB)) { | ||
201 | connector->status = connector_status_unknown; | ||
202 | |||
203 | if (priv->fbdev) { | ||
204 | spin_lock_irqsave(&list_lock, flags); | ||
205 | drm_kms_helper_poll_enable(dev); | ||
206 | connector->force = 0; | ||
207 | spin_unlock_irqrestore(&list_lock, flags); | ||
208 | } | ||
209 | } | ||
210 | } | ||
211 | |||
212 | return IRQ_HANDLED; | ||
213 | } | ||
214 | |||
190 | irqreturn_t omap_irq_handler(int irq, void *arg) | 215 | irqreturn_t omap_irq_handler(int irq, void *arg) |
191 | { | 216 | { |
192 | struct drm_device *dev = (struct drm_device *) arg; | 217 | struct drm_device *dev = (struct drm_device *) arg; |