diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c
index 070053f..a80ebe1 100644
--- a/drivers/gpu/drm/omapdrm/dss/dispc.c
+++ b/drivers/gpu/drm/omapdrm/dss/dispc.c
@@ -698,27 +698,12 @@ static const char *dispc_get_mgr_name(enum omap_channel channel)
 	return mgr_desc[channel].name;
 }
 
-static u32 dispc_mgr_get_vsync_irq(enum omap_channel channel)
-{
-	return mgr_desc[channel].vsync_irq;
-}
-
-static u32 dispc_mgr_get_framedone_irq(enum omap_channel channel)
+static bool dispc_mgr_has_framedone(enum omap_channel channel)
 {
 	if (channel == OMAP_DSS_CHANNEL_DIGIT && dispc.feat->no_framedone_tv)
-		return 0;
-
-	return mgr_desc[channel].framedone_irq;
-}
-
-static u32 dispc_mgr_get_sync_lost_irq(enum omap_channel channel)
-{
-	return mgr_desc[channel].sync_lost_irq;
-}
+		return false;
 
-u32 dispc_wb_get_framedone_irq(void)
-{
-	return DISPC_IRQ_FRAMEDONEWB;
+	return true;
 }
 
 static void dispc_mgr_enable(enum omap_channel channel, bool enable)
@@ -3604,6 +3589,121 @@ static void dispc_write_irqenable(u32 mask)
 	dispc_read_reg(DISPC_IRQENABLE);
 }
 
+static u64 dispc_hw_to_api_irq(u32 hw)
+{
+	u64 api = 0;
+
+	if (hw & DISPC_IRQ_OCP_ERR)
+		api |= DSS_IRQ_DEVICE_OCP_ERR;
+
+	if (hw & DISPC_IRQ_FRAMEDONE)
+		api |= DSS_IRQ_MGR_FRAME_DONE(0);
+	if (hw & DISPC_IRQ_VSYNC)
+		api |= DSS_IRQ_MGR_VSYNC_EVEN(0);
+	if (hw & DISPC_IRQ_SYNC_LOST)
+		api |= DSS_IRQ_MGR_SYNC_LOST(0);
+
+	if (hw & DISPC_IRQ_EVSYNC_EVEN)
+		api |= DSS_IRQ_MGR_VSYNC_EVEN(1);
+	if (hw & DISPC_IRQ_EVSYNC_ODD)
+		api |= DSS_IRQ_MGR_VSYNC_ODD(1);
+	if (hw & DISPC_IRQ_SYNC_LOST_DIGIT)
+		api |= DSS_IRQ_MGR_SYNC_LOST(1);
+	if (hw & DISPC_IRQ_FRAMEDONETV)
+		api |= DSS_IRQ_MGR_FRAME_DONE(1);
+
+	if (hw & DISPC_IRQ_SYNC_LOST2)
+		api |= DSS_IRQ_MGR_SYNC_LOST(2);
+	if (hw & DISPC_IRQ_VSYNC2)
+		api |= DSS_IRQ_MGR_VSYNC_EVEN(2);
+	if (hw & DISPC_IRQ_FRAMEDONE2)
+		api |= DSS_IRQ_MGR_FRAME_DONE(2);
+
+	if (hw & DISPC_IRQ_SYNC_LOST3)
+		api |= DSS_IRQ_MGR_SYNC_LOST(3);
+	if (hw & DISPC_IRQ_VSYNC3)
+		api |= DSS_IRQ_MGR_VSYNC_EVEN(3);
+	if (hw & DISPC_IRQ_FRAMEDONE3)
+		api |= DSS_IRQ_MGR_FRAME_DONE(3);
+
+	if (hw & DISPC_IRQ_GFX_FIFO_UNDERFLOW)
+		api |= DSS_IRQ_OVL_FIFO_UNDERFLOW(0);
+	if (hw & DISPC_IRQ_VID1_FIFO_UNDERFLOW)
+		api |= DSS_IRQ_OVL_FIFO_UNDERFLOW(1);
+	if (hw & DISPC_IRQ_VID2_FIFO_UNDERFLOW)
+		api |= DSS_IRQ_OVL_FIFO_UNDERFLOW(2);
+	if (hw & DISPC_IRQ_VID3_FIFO_UNDERFLOW)
+		api |= DSS_IRQ_OVL_FIFO_UNDERFLOW(3);
+
+	return api;
+}
+
+static u32 dispc_api_to_hw_irq(u64 api)
+{
+	u32 hw = 0;
+
+	if (api & DSS_IRQ_DEVICE_OCP_ERR)
+		hw |= DISPC_IRQ_OCP_ERR;
+
+	if (api & DSS_IRQ_MGR_FRAME_DONE(0))
+		hw |= DISPC_IRQ_FRAMEDONE;
+	if (api & DSS_IRQ_MGR_VSYNC_EVEN(0))
+		hw |= DISPC_IRQ_VSYNC;
+	if (api & DSS_IRQ_MGR_SYNC_LOST(0))
+		hw |= DISPC_IRQ_SYNC_LOST;
+
+	if (api & DSS_IRQ_MGR_VSYNC_EVEN(1))
+		hw |= DISPC_IRQ_EVSYNC_EVEN;
+	if (api & DSS_IRQ_MGR_VSYNC_ODD(1))
+		hw |= DISPC_IRQ_EVSYNC_ODD;
+	if (api & DSS_IRQ_MGR_SYNC_LOST(1))
+		hw |= DISPC_IRQ_SYNC_LOST_DIGIT;
+	if (api & DSS_IRQ_MGR_FRAME_DONE(1))
+		hw |= DISPC_IRQ_FRAMEDONETV;
+
+	if (api & DSS_IRQ_MGR_SYNC_LOST(2))
+		hw |= DISPC_IRQ_SYNC_LOST2;
+	if (api & DSS_IRQ_MGR_VSYNC_EVEN(2))
+		hw |= DISPC_IRQ_VSYNC2;
+	if (api & DSS_IRQ_MGR_FRAME_DONE(2))
+		hw |= DISPC_IRQ_FRAMEDONE2;
+
+	if (api & DSS_IRQ_MGR_SYNC_LOST(3))
+		hw |= DISPC_IRQ_SYNC_LOST3;
+	if (api & DSS_IRQ_MGR_VSYNC_EVEN(3))
+		hw |= DISPC_IRQ_VSYNC3;
+	if (api & DSS_IRQ_MGR_FRAME_DONE(3))
+		hw |= DISPC_IRQ_FRAMEDONE3;
+
+	if (api & DSS_IRQ_OVL_FIFO_UNDERFLOW(0))
+		hw |= DISPC_IRQ_GFX_FIFO_UNDERFLOW;
+	if (api & DSS_IRQ_OVL_FIFO_UNDERFLOW(1))
+		hw |= DISPC_IRQ_VID1_FIFO_UNDERFLOW;
+	if (api & DSS_IRQ_OVL_FIFO_UNDERFLOW(2))
+		hw |= DISPC_IRQ_VID2_FIFO_UNDERFLOW;
+	if (api & DSS_IRQ_OVL_FIFO_UNDERFLOW(3))
+		hw |= DISPC_IRQ_VID3_FIFO_UNDERFLOW;
+
+	return hw;
+}
+
+static u64 dispc_api_read_irqstatus(u64 clearmask)
+{
+	u32 hw_clearmask = dispc_api_to_hw_irq(clearmask);
+	u32 hw_status = dispc_read_irqstatus();
+
+	dispc_clear_irqstatus(hw_clearmask & hw_status);
+
+	return dispc_hw_to_api_irq(hw_status);
+}
+
+static void dispc_api_write_irqenable(u64 enable)
+{
+	u32 hw_enable = dispc_api_to_hw_irq(enable);
+
+	dispc_write_irqenable(hw_enable);
+}
+
 void dispc_enable_sidle(void)
 {
 	REG_FLD_MOD(DISPC_SYSCONFIG, 2, 4, 3);	/* SIDLEMODE: smart idle */
@@ -4453,7 +4553,7 @@ static void dispc_errata_i734_wa_fini(void)
 
 static void dispc_errata_i734_wa(void)
 {
-	u32 framedone_irq = dispc_mgr_get_framedone_irq(OMAP_DSS_CHANNEL_LCD);
+	u32 framedone_irq = DISPC_IRQ_FRAMEDONE;
 	struct omap_overlay_info ovli;
 	struct dss_lcd_mgr_config lcd_conf;
 	u32 gatestate;
@@ -4511,9 +4611,8 @@ static void dispc_errata_i734_wa(void)
 }
 
 static const struct dispc_ops dispc_ops = {
-	.read_irqstatus = dispc_read_irqstatus,
-	.clear_irqstatus = dispc_clear_irqstatus,
-	.write_irqenable = dispc_write_irqenable,
+	.read_irqstatus = dispc_api_read_irqstatus,
+	.write_irqenable = dispc_api_write_irqenable,
 
 	.request_irq = dispc_request_irq,
 	.free_irq = dispc_free_irq,
@@ -4527,13 +4626,12 @@ static void dispc_errata_i734_wa(void)
 	.get_ovl_name = dispc_get_ovl_name,
 	.get_mgr_name = dispc_get_mgr_name,
 
+	.mgr_has_framedone = dispc_mgr_has_framedone,
+
 	.get_memory_bandwidth_limit = dispc_get_memory_bandwidth_limit,
 
 	.mgr_enable = dispc_mgr_enable,
 	.mgr_is_enabled = dispc_mgr_is_enabled,
-	.mgr_get_vsync_irq = dispc_mgr_get_vsync_irq,
-	.mgr_get_framedone_irq = dispc_mgr_get_framedone_irq,
-	.mgr_get_sync_lost_irq = dispc_mgr_get_sync_lost_irq,
 	.mgr_go_busy = dispc_mgr_go_busy,
 	.mgr_go = dispc_mgr_go,
 	.mgr_set_lcd_config = dispc_mgr_set_lcd_config,
diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.h b/drivers/gpu/drm/omapdrm/dss/dispc.h
index e901dd1..e71266e 100644
--- a/drivers/gpu/drm/omapdrm/dss/dispc.h
+++ b/drivers/gpu/drm/omapdrm/dss/dispc.h
@@ -18,6 +18,39 @@
 #ifndef __OMAP2_DISPC_REG_H
 #define __OMAP2_DISPC_REG_H
 
+/* DISPC IRQ bits */
+#define DISPC_IRQ_FRAMEDONE		(1 << 0)
+#define DISPC_IRQ_VSYNC			(1 << 1)
+#define DISPC_IRQ_EVSYNC_EVEN		(1 << 2)
+#define DISPC_IRQ_EVSYNC_ODD		(1 << 3)
+#define DISPC_IRQ_ACBIAS_COUNT_STAT	(1 << 4)
+#define DISPC_IRQ_PROG_LINE_NUM		(1 << 5)
+#define DISPC_IRQ_GFX_FIFO_UNDERFLOW	(1 << 6)
+#define DISPC_IRQ_GFX_END_WIN		(1 << 7)
+#define DISPC_IRQ_PAL_GAMMA_MASK	(1 << 8)
+#define DISPC_IRQ_OCP_ERR		(1 << 9)
+#define DISPC_IRQ_VID1_FIFO_UNDERFLOW	(1 << 10)
+#define DISPC_IRQ_VID1_END_WIN		(1 << 11)
+#define DISPC_IRQ_VID2_FIFO_UNDERFLOW	(1 << 12)
+#define DISPC_IRQ_VID2_END_WIN		(1 << 13)
+#define DISPC_IRQ_SYNC_LOST		(1 << 14)
+#define DISPC_IRQ_SYNC_LOST_DIGIT	(1 << 15)
+#define DISPC_IRQ_WAKEUP		(1 << 16)
+#define DISPC_IRQ_SYNC_LOST2		(1 << 17)
+#define DISPC_IRQ_VSYNC2		(1 << 18)
+#define DISPC_IRQ_VID3_END_WIN		(1 << 19)
+#define DISPC_IRQ_VID3_FIFO_UNDERFLOW	(1 << 20)
+#define DISPC_IRQ_ACBIAS_COUNT_STAT2	(1 << 21)
+#define DISPC_IRQ_FRAMEDONE2		(1 << 22)
+#define DISPC_IRQ_FRAMEDONEWB		(1 << 23)
+#define DISPC_IRQ_FRAMEDONETV		(1 << 24)
+#define DISPC_IRQ_WBBUFFEROVERFLOW	(1 << 25)
+#define DISPC_IRQ_WBUNCOMPLETEERROR	(1 << 26)
+#define DISPC_IRQ_SYNC_LOST3		(1 << 27)
+#define DISPC_IRQ_VSYNC3		(1 << 28)
+#define DISPC_IRQ_ACBIAS_COUNT_STAT3	(1 << 29)
+#define DISPC_IRQ_FRAMEDONE3		(1 << 30)
+
 /* DISPC common registers */
 #define DISPC_REVISION			0x0000
 #define DISPC_SYSCONFIG			0x0010
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index d7ed1a4..b1499c2 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -27,37 +27,29 @@
 #include <uapi/drm/drm_mode.h>
 #include <drm/drm_crtc.h>
 
-#define DISPC_IRQ_FRAMEDONE		(1 << 0)
-#define DISPC_IRQ_VSYNC			(1 << 1)
-#define DISPC_IRQ_EVSYNC_EVEN		(1 << 2)
-#define DISPC_IRQ_EVSYNC_ODD		(1 << 3)
-#define DISPC_IRQ_ACBIAS_COUNT_STAT	(1 << 4)
-#define DISPC_IRQ_PROG_LINE_NUM		(1 << 5)
-#define DISPC_IRQ_GFX_FIFO_UNDERFLOW	(1 << 6)
-#define DISPC_IRQ_GFX_END_WIN		(1 << 7)
-#define DISPC_IRQ_PAL_GAMMA_MASK	(1 << 8)
-#define DISPC_IRQ_OCP_ERR		(1 << 9)
-#define DISPC_IRQ_VID1_FIFO_UNDERFLOW	(1 << 10)
-#define DISPC_IRQ_VID1_END_WIN		(1 << 11)
-#define DISPC_IRQ_VID2_FIFO_UNDERFLOW	(1 << 12)
-#define DISPC_IRQ_VID2_END_WIN		(1 << 13)
-#define DISPC_IRQ_SYNC_LOST		(1 << 14)
-#define DISPC_IRQ_SYNC_LOST_DIGIT	(1 << 15)
-#define DISPC_IRQ_WAKEUP		(1 << 16)
-#define DISPC_IRQ_SYNC_LOST2		(1 << 17)
-#define DISPC_IRQ_VSYNC2		(1 << 18)
-#define DISPC_IRQ_VID3_END_WIN		(1 << 19)
-#define DISPC_IRQ_VID3_FIFO_UNDERFLOW	(1 << 20)
-#define DISPC_IRQ_ACBIAS_COUNT_STAT2	(1 << 21)
-#define DISPC_IRQ_FRAMEDONE2		(1 << 22)
-#define DISPC_IRQ_FRAMEDONEWB		(1 << 23)
-#define DISPC_IRQ_FRAMEDONETV		(1 << 24)
-#define DISPC_IRQ_WBBUFFEROVERFLOW	(1 << 25)
-#define DISPC_IRQ_WBUNCOMPLETEERROR	(1 << 26)
-#define DISPC_IRQ_SYNC_LOST3		(1 << 27)
-#define DISPC_IRQ_VSYNC3		(1 << 28)
-#define DISPC_IRQ_ACBIAS_COUNT_STAT3	(1 << 29)
-#define DISPC_IRQ_FRAMEDONE3		(1 << 30)
+#define DSS_MAX_CHANNELS 8
+#define DSS_MAX_OVLS 8
+
+#define DSS_IRQ_DEVICE_OCP_ERR		BIT_ULL(0)
+
+#define DSS_IRQ_MGR_BIT_N(ch, bit)	(4 + 4 * ch + bit)
+#define DSS_IRQ_OVL_BIT_N(ovl, bit) \
+	(DSS_IRQ_MGR_BIT_N(DSS_MAX_CHANNELS, 0) + 1 * ovl + bit)
+
+#define DSS_IRQ_MGR_BIT(ch, bit)	BIT_ULL(DSS_IRQ_MGR_BIT_N(ch, bit))
+#define DSS_IRQ_OVL_BIT(ovl, bit)	BIT_ULL(DSS_IRQ_OVL_BIT_N(ovl, bit))
+
+#define DSS_IRQ_MGR_MASK(ch) \
+	GENMASK_ULL(DSS_IRQ_MGR_BIT_N(ch, 3), DSS_IRQ_MGR_BIT_N(ch, 0))
+#define DSS_IRQ_OVL_MASK(ovl) \
+	GENMASK_ULL(DSS_IRQ_OVL_BIT_N(ovl, 0), DSS_IRQ_OVL_BIT_N(ovl, 0))
+
+#define DSS_IRQ_MGR_FRAME_DONE(ch)	DSS_IRQ_MGR_BIT(ch, 0)
+#define DSS_IRQ_MGR_VSYNC_EVEN(ch)	DSS_IRQ_MGR_BIT(ch, 1)
+#define DSS_IRQ_MGR_VSYNC_ODD(ch)	DSS_IRQ_MGR_BIT(ch, 2)
+#define DSS_IRQ_MGR_SYNC_LOST(ch)	DSS_IRQ_MGR_BIT(ch, 3)
+
+#define DSS_IRQ_OVL_FIFO_UNDERFLOW(ovl)	DSS_IRQ_OVL_BIT(ovl, 0)
 
 struct omap_dss_device;
 struct dss_lcd_mgr_config;
@@ -678,9 +670,8 @@ void dss_mgr_unregister_framedone_handler(enum omap_channel channel,
 /* dispc ops */
 
 struct dispc_ops {
-	u32 (*read_irqstatus)(void);
-	void (*clear_irqstatus)(u32 mask);
-	void (*write_irqenable)(u32 mask);
+	u64 (*read_irqstatus)(u64 clearmask);
+	void (*write_irqenable)(u64 enable);
 
 	int (*request_irq)(irq_handler_t handler, void *dev_id);
 	void (*free_irq)(void *dev_id);
@@ -694,13 +685,12 @@ struct dispc_ops {
 	const char *(*get_ovl_name)(enum omap_plane_id plane);
 	const char *(*get_mgr_name)(enum omap_channel channel);
 
+	bool (*mgr_has_framedone)(enum omap_channel channel);
+
 	u32 (*get_memory_bandwidth_limit)(void);
 
 	void (*mgr_enable)(enum omap_channel channel, bool enable);
 	bool (*mgr_is_enabled)(enum omap_channel channel);
-	u32 (*mgr_get_vsync_irq)(enum omap_channel channel);
-	u32 (*mgr_get_framedone_irq)(enum omap_channel channel);
-	u32 (*mgr_get_sync_lost_irq)(enum omap_channel channel);
 	bool (*mgr_go_busy)(enum omap_channel channel);
 	void (*mgr_go)(enum omap_channel channel);
 	void (*mgr_set_lcd_config)(enum omap_channel channel,
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index fee8a63..f7e1668 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -149,7 +149,7 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable)
 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
 	enum omap_channel channel = omap_crtc->channel;
 	struct omap_irq_wait *wait;
-	u32 framedone_irq, vsync_irq;
+	u64 vsync_irq, framedone_irq;
 	int ret;
 
 	if (WARN_ON(omap_crtc->enabled == enable))
@@ -169,8 +169,10 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable)
 		omap_crtc->ignore_digit_sync_lost = true;
 	}
 
-	framedone_irq = priv->dispc_ops->mgr_get_framedone_irq(channel);
-	vsync_irq = priv->dispc_ops->mgr_get_vsync_irq(channel);
+
+	vsync_irq = (DSS_IRQ_MGR_VSYNC_EVEN(channel) |
+		     DSS_IRQ_MGR_VSYNC_ODD(channel));
+	framedone_irq = DSS_IRQ_MGR_FRAME_DONE(channel);
 
 	if (enable) {
 		wait = omap_irq_wait_init(dev, vsync_irq, 1);
@@ -184,7 +186,7 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable)
 		 * even and odd frames.
 		 */
 
-		if (framedone_irq)
+		if (priv->dispc_ops->mgr_has_framedone(channel))
 			wait = omap_irq_wait_init(dev, framedone_irq, 1);
 		else
 			wait = omap_irq_wait_init(dev, vsync_irq, 2);
@@ -272,17 +274,17 @@ static void omap_crtc_dss_unregister_framedone(
  * Setup, Flush and Page Flip
  */
 
-void omap_crtc_error_irq(struct drm_crtc *crtc, uint32_t irqstatus)
+void omap_crtc_error_irq(struct drm_crtc *crtc, u64 irqstatus)
 {
 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
 
 	if (omap_crtc->ignore_digit_sync_lost) {
-		irqstatus &= ~DISPC_IRQ_SYNC_LOST_DIGIT;
+		irqstatus &= ~DSS_IRQ_MGR_SYNC_LOST(omap_crtc->channel);
 		if (!irqstatus)
 			return;
 	}
 
-	DRM_ERROR_RATELIMITED("%s: errors: %08x\n", omap_crtc->name, irqstatus);
+	DRM_ERROR_RATELIMITED("%s: errors: %016llx\n", omap_crtc->name, irqstatus);
 }
 
 void omap_crtc_vblank_irq(struct drm_crtc *crtc)
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.h b/drivers/gpu/drm/omapdrm/omap_crtc.h
index ad7b007..55e2e02 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.h
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.h
@@ -37,7 +37,7 @@
 struct drm_crtc *omap_crtc_init(struct drm_device *dev,
 		struct drm_plane *plane, struct omap_dss_device *dssdev);
 int omap_crtc_wait_pending(struct drm_crtc *crtc);
-void omap_crtc_error_irq(struct drm_crtc *crtc, uint32_t irqstatus);
+void omap_crtc_error_irq(struct drm_crtc *crtc, u64 irqstatus);
 void omap_crtc_vblank_irq(struct drm_crtc *crtc);
 
 #endif /* __OMAPDRM_CRTC_H__ */
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h
index 0ac97fe..1a479ea 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -81,8 +81,7 @@ struct omap_drm_private {
 	/* irq handling: */
 	spinlock_t wait_lock;		/* protects the wait_list */
 	struct list_head wait_list;	/* list of omap_irq_wait */
-	uint32_t irq_mask;		/* enabled irqs in addition to wait_list */
-
+	u64 irq_mask;			/* enabled irqs in addition to wait_list */
 	/* memory bandwidth limit if it is needed on the platform */
 	unsigned int max_bandwidth;
 };
diff --git a/drivers/gpu/drm/omapdrm/omap_irq.c b/drivers/gpu/drm/omapdrm/omap_irq.c
index b0f6850..57ea08e 100644
--- a/drivers/gpu/drm/omapdrm/omap_irq.c
+++ b/drivers/gpu/drm/omapdrm/omap_irq.c
@@ -20,25 +20,24 @@
 struct omap_irq_wait {
 	struct list_head node;
 	wait_queue_head_t wq;
-	uint32_t irqmask;
+	u64 irqmask;
 	int count;
 };
 
 /* call with wait_lock and dispc runtime held */
-static void omap_irq_update(struct drm_device *dev)
+static void omap_irq_full_mask(struct drm_device *dev, u64 *irqmask)
 {
 	struct omap_drm_private *priv = dev->dev_private;
 	struct omap_irq_wait *wait;
-	uint32_t irqmask = priv->irq_mask;
 
 	assert_spin_locked(&priv->wait_lock);
 
-	list_for_each_entry(wait, &priv->wait_list, node)
-		irqmask |= wait->irqmask;
+	*irqmask = priv->irq_mask;
 
-	DBG("irqmask=%08x", irqmask);
+	list_for_each_entry(wait, &priv->wait_list, node)
+		*irqmask |= wait->irqmask;
 
-	priv->dispc_ops->write_irqenable(irqmask);
+	DBG("irqmask 0x%016llx", *irqmask);
 }
 
 static void omap_irq_wait_handler(struct omap_irq_wait *wait)
@@ -48,19 +47,24 @@ static void omap_irq_wait_handler(struct omap_irq_wait *wait)
 }
 
 struct omap_irq_wait * omap_irq_wait_init(struct drm_device *dev,
-		uint32_t irqmask, int count)
+		u64 waitmask, int count)
 {
 	struct omap_drm_private *priv = dev->dev_private;
 	struct omap_irq_wait *wait = kzalloc(sizeof(*wait), GFP_KERNEL);
 	unsigned long flags;
+	u64 irqmask;
+
+	if (!wait)
+		return NULL;
 
 	init_waitqueue_head(&wait->wq);
-	wait->irqmask = irqmask;
+	wait->irqmask = waitmask;
 	wait->count = count;
 
 	spin_lock_irqsave(&priv->wait_lock, flags);
 	list_add(&wait->node, &priv->wait_list);
-	omap_irq_update(dev);
+	omap_irq_full_mask(dev, &irqmask);
+	priv->dispc_ops->write_irqenable(irqmask);
 	spin_unlock_irqrestore(&priv->wait_lock, flags);
 
 	return wait;
@@ -71,13 +75,15 @@ int omap_irq_wait(struct drm_device *dev, struct omap_irq_wait *wait,
 {
 	struct omap_drm_private *priv = dev->dev_private;
 	unsigned long flags;
+	u64 irqmask;
 	int ret;
 
 	ret = wait_event_timeout(wait->wq, (wait->count <= 0), timeout);
 
 	spin_lock_irqsave(&priv->wait_lock, flags);
 	list_del(&wait->node);
-	omap_irq_update(dev);
+	omap_irq_full_mask(dev, &irqmask);
+	priv->dispc_ops->write_irqenable(irqmask);
 	spin_unlock_irqrestore(&priv->wait_lock, flags);
 
 	kfree(wait);
@@ -104,12 +110,15 @@ int omap_irq_enable_vblank(struct drm_crtc *crtc)
 	struct omap_drm_private *priv = dev->dev_private;
 	unsigned long flags;
 	enum omap_channel channel = omap_crtc_channel(crtc);
+	u64 irqmask;
 
 	DBG("dev=%p, crtc=%u", dev, channel);
 
 	spin_lock_irqsave(&priv->wait_lock, flags);
-	priv->irq_mask |= priv->dispc_ops->mgr_get_vsync_irq(channel);
-	omap_irq_update(dev);
+	priv->irq_mask |= DSS_IRQ_MGR_VSYNC_EVEN(channel) |
+		DSS_IRQ_MGR_VSYNC_ODD(channel);
+	omap_irq_full_mask(dev, &irqmask);
+	priv->dispc_ops->write_irqenable(irqmask);
 	spin_unlock_irqrestore(&priv->wait_lock, flags);
 
 	return 0;
@@ -130,36 +139,36 @@ void omap_irq_disable_vblank(struct drm_crtc *crtc)
 	struct omap_drm_private *priv = dev->dev_private;
 	unsigned long flags;
 	enum omap_channel channel = omap_crtc_channel(crtc);
+	u64 irqmask;
 
 	DBG("dev=%p, crtc=%u", dev, channel);
 
 	spin_lock_irqsave(&priv->wait_lock, flags);
-	priv->irq_mask &= ~priv->dispc_ops->mgr_get_vsync_irq(channel);
-	omap_irq_update(dev);
+	priv->irq_mask &= ~(DSS_IRQ_MGR_VSYNC_EVEN(channel) |
+			    DSS_IRQ_MGR_VSYNC_ODD(channel));
+	omap_irq_full_mask(dev, &irqmask);
+	priv->dispc_ops->write_irqenable(irqmask);
 	spin_unlock_irqrestore(&priv->wait_lock, flags);
 }
 
 static void omap_irq_fifo_underflow(struct omap_drm_private *priv,
-				    u32 irqstatus)
+				    u64 irqstatus)
 {
 	static DEFINE_RATELIMIT_STATE(_rs, DEFAULT_RATELIMIT_INTERVAL,
 				      DEFAULT_RATELIMIT_BURST);
-	static const u32 irqbits[] = { DISPC_IRQ_GFX_FIFO_UNDERFLOW,
-				       DISPC_IRQ_VID1_FIFO_UNDERFLOW,
-				       DISPC_IRQ_VID2_FIFO_UNDERFLOW,
-				       DISPC_IRQ_VID3_FIFO_UNDERFLOW };
-
-	const u32 mask = DISPC_IRQ_GFX_FIFO_UNDERFLOW
-		       | DISPC_IRQ_VID1_FIFO_UNDERFLOW
-		       | DISPC_IRQ_VID2_FIFO_UNDERFLOW
-		       | DISPC_IRQ_VID3_FIFO_UNDERFLOW;
+	static const u64 uf_mask =
+		DSS_IRQ_OVL_FIFO_UNDERFLOW(0) | DSS_IRQ_OVL_FIFO_UNDERFLOW(1) |
+		DSS_IRQ_OVL_FIFO_UNDERFLOW(2) | DSS_IRQ_OVL_FIFO_UNDERFLOW(3) |
+		DSS_IRQ_OVL_FIFO_UNDERFLOW(4) | DSS_IRQ_OVL_FIFO_UNDERFLOW(5) |
+		DSS_IRQ_OVL_FIFO_UNDERFLOW(6) |	DSS_IRQ_OVL_FIFO_UNDERFLOW(7);
 	unsigned int i;
+	u64 masked;
 
 	spin_lock(&priv->wait_lock);
-	irqstatus &= priv->irq_mask & mask;
+	masked = irqstatus & uf_mask & priv->irq_mask;
 	spin_unlock(&priv->wait_lock);
 
-	if (!irqstatus)
+	if (!masked)
 		return;
 
 	if (!__ratelimit(&_rs))
@@ -167,21 +176,19 @@ static void omap_irq_fifo_underflow(struct omap_drm_private *priv,
 
 	DRM_ERROR("FIFO underflow on ");
 
-	for (i = 0; i < ARRAY_SIZE(irqbits); ++i) {
-		if (irqbits[i] & irqstatus)
-			pr_cont("%s ", priv->dispc_ops->get_ovl_name(i));
+	for (i = 0; i < DSS_MAX_OVLS; ++i) {
+		if (masked & DSS_IRQ_OVL_FIFO_UNDERFLOW(i))
+			pr_cont("%u:%s ", i, priv->dispc_ops->get_ovl_name(i));
 	}
 
-	pr_cont("(0x%08x)\n", irqstatus);
+	pr_cont("(%016llx)\n", irqstatus);
 }
 
 static void omap_irq_ocp_error_handler(struct drm_device *dev,
-	u32 irqstatus)
+				       u64 irqstatus)
 {
-	if (!(irqstatus & DISPC_IRQ_OCP_ERR))
-		return;
-
-	dev_err_ratelimited(dev->dev, "OCP error\n");
+	if (irqstatus & DSS_IRQ_DEVICE_OCP_ERR)
+		dev_err_ratelimited(dev->dev, "OCP error\n");
 }
 
 static irqreturn_t omap_irq_handler(int irq, void *arg)
@@ -191,47 +198,40 @@ static irqreturn_t omap_irq_handler(int irq, void *arg)
 	struct omap_irq_wait *wait, *n;
 	unsigned long flags;
 	unsigned int id;
-	u32 irqstatus;
+	u64 irqstatus, clearmask;
 
-	irqstatus = priv->dispc_ops->read_irqstatus();
-	priv->dispc_ops->clear_irqstatus(irqstatus);
-	priv->dispc_ops->read_irqstatus();        /* flush posted write */
+	spin_lock_irqsave(&priv->wait_lock, flags);
+	omap_irq_full_mask(dev, &clearmask);
+	irqstatus = priv->dispc_ops->read_irqstatus(clearmask);
+
+	list_for_each_entry_safe(wait, n, &priv->wait_list, node) {
+		if (irqstatus & wait->irqmask)
+			omap_irq_wait_handler(wait);
+	}
+	spin_unlock_irqrestore(&priv->wait_lock, flags);
 
-	VERB("irqs: %08x", irqstatus);
+	VERB("irqs: 0x%016llx\n", irqstatus);
 
 	for (id = 0; id < priv->num_crtcs; id++) {
 		struct drm_crtc *crtc = priv->crtcs[id];
 		enum omap_channel channel = omap_crtc_channel(crtc);
 
-		if (irqstatus & priv->dispc_ops->mgr_get_vsync_irq(channel)) {
+		if (irqstatus & (DSS_IRQ_MGR_VSYNC_EVEN(channel) |
+				 DSS_IRQ_MGR_VSYNC_ODD(channel))) {
 			drm_handle_vblank(dev, id);
 			omap_crtc_vblank_irq(crtc);
 		}
 
-		if (irqstatus & priv->dispc_ops->mgr_get_sync_lost_irq(channel))
+		if (irqstatus & DSS_IRQ_MGR_SYNC_LOST(channel))
 			omap_crtc_error_irq(crtc, irqstatus);
 	}
 
 	omap_irq_ocp_error_handler(dev, irqstatus);
 	omap_irq_fifo_underflow(priv, irqstatus);
 
-	spin_lock_irqsave(&priv->wait_lock, flags);
-	list_for_each_entry_safe(wait, n, &priv->wait_list, node) {
-		if (wait->irqmask & irqstatus)
-			omap_irq_wait_handler(wait);
-	}
-	spin_unlock_irqrestore(&priv->wait_lock, flags);
-
 	return IRQ_HANDLED;
 }
 
-static const u32 omap_underflow_irqs[] = {
-	[OMAP_DSS_GFX] = DISPC_IRQ_GFX_FIFO_UNDERFLOW,
-	[OMAP_DSS_VIDEO1] = DISPC_IRQ_VID1_FIFO_UNDERFLOW,
-	[OMAP_DSS_VIDEO2] = DISPC_IRQ_VID2_FIFO_UNDERFLOW,
-	[OMAP_DSS_VIDEO3] = DISPC_IRQ_VID3_FIFO_UNDERFLOW,
-};
-
 /*
  * We need a special version, instead of just using drm_irq_install(),
  * because we need to register the irq via omapdss.  Once omapdss and
@@ -242,29 +242,21 @@ static irqreturn_t omap_irq_handler(int irq, void *arg)
 int omap_drm_irq_install(struct drm_device *dev)
 {
 	struct omap_drm_private *priv = dev->dev_private;
-	unsigned int num_mgrs = priv->dispc_ops->get_num_mgrs();
-	unsigned int max_planes;
 	unsigned int i;
 	int ret;
 
 	spin_lock_init(&priv->wait_lock);
 	INIT_LIST_HEAD(&priv->wait_list);
 
-	priv->irq_mask = DISPC_IRQ_OCP_ERR;
-
-	max_planes = min(ARRAY_SIZE(priv->planes),
-			 ARRAY_SIZE(omap_underflow_irqs));
-	for (i = 0; i < max_planes; ++i) {
-		if (priv->planes[i])
-			priv->irq_mask |= omap_underflow_irqs[i];
-	}
+	priv->irq_mask = DSS_IRQ_DEVICE_OCP_ERR;
 
-	for (i = 0; i < num_mgrs; ++i)
-		priv->irq_mask |= priv->dispc_ops->mgr_get_sync_lost_irq(i);
+	for (i = 0; i < priv->num_planes; ++i)
+		priv->irq_mask |= DSS_IRQ_OVL_FIFO_UNDERFLOW(
+			omap_plane_get_id(priv->planes[i]));
 
-	priv->dispc_ops->runtime_get();
-	priv->dispc_ops->clear_irqstatus(0xffffffff);
-	priv->dispc_ops->runtime_put();
+	for (i = 0; i < priv->num_crtcs; ++i)
+		priv->irq_mask |= DSS_IRQ_MGR_SYNC_LOST(
+			omap_crtc_channel(priv->crtcs[i]));
 
 	ret = priv->dispc_ops->request_irq(omap_irq_handler, dev);
 	if (ret < 0)
diff --git a/drivers/gpu/drm/omapdrm/omap_irq.h b/drivers/gpu/drm/omapdrm/omap_irq.h
index 606c099..8a7971d 100644
--- a/drivers/gpu/drm/omapdrm/omap_irq.h
+++ b/drivers/gpu/drm/omapdrm/omap_irq.h
@@ -32,7 +32,7 @@
 int omap_drm_irq_install(struct drm_device *dev);
 
 struct omap_irq_wait *omap_irq_wait_init(struct drm_device *dev,
-		uint32_t irqmask, int count);
+		u64 irqmask, int count);
 int omap_irq_wait(struct drm_device *dev, struct omap_irq_wait *wait,
 		unsigned long timeout);
 
diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c
index 6f9d9ef..0040d29 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -239,6 +239,13 @@ static int omap_plane_atomic_get_property(struct drm_plane *plane,
 	.atomic_get_property = omap_plane_atomic_get_property,
 };
 
+enum omap_plane_id omap_plane_get_id(struct drm_plane *plane)
+{
+	struct omap_plane *omap_plane = to_omap_plane(plane);
+
+	return omap_plane->id;
+}
+
 static const enum omap_plane_id plane_idx_to_id[] = {
 	OMAP_DSS_GFX,
 	OMAP_DSS_VIDEO1,
diff --git a/drivers/gpu/drm/omapdrm/omap_plane.h b/drivers/gpu/drm/omapdrm/omap_plane.h
index dc5e82a..dbab345 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.h
+++ b/drivers/gpu/drm/omapdrm/omap_plane.h
@@ -33,5 +33,6 @@ struct drm_plane *omap_plane_init(struct drm_device *dev,
 		u32 possible_crtcs);
 void omap_plane_install_properties(struct drm_plane *plane,
 		struct drm_mode_object *obj);
+enum omap_plane_id omap_plane_get_id(struct drm_plane *plane);
 
 #endif /* __OMAPDRM_PLANE_H__ */
