Blob Blame History Raw
From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Date: Tue, 13 Feb 2018 14:00:42 +0200
Subject: drm: omapdrm: dispc: Pass DISPC pointer to dispc_ops operations
Git-commit: 50638ae569dc097a95218eb70140e68aa213b07c
Patch-mainline: v4.17-rc1
References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166

This removes the need to access the global DISPC private data in those
functions (both for the current accesses and the future ones that will
be introduced when allocating the DISPC private data dynamically).

In order to allow the omapdrm side to call the dispc_ops with a DISPC
pointer, we also introduce a new function dss_get_dispc() to retrieve
the DISPC corresponding to the DSS.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 drivers/gpu/drm/omapdrm/dss/base.c    |    6 
 drivers/gpu/drm/omapdrm/dss/dispc.c   |  223 ++++++++++++++++++----------------
 drivers/gpu/drm/omapdrm/dss/dpi.c     |    6 
 drivers/gpu/drm/omapdrm/dss/dsi.c     |    4 
 drivers/gpu/drm/omapdrm/dss/dss.h     |    6 
 drivers/gpu/drm/omapdrm/dss/hdmi4.c   |    7 -
 drivers/gpu/drm/omapdrm/dss/hdmi5.c   |    7 -
 drivers/gpu/drm/omapdrm/dss/omapdss.h |   95 ++++++++------
 drivers/gpu/drm/omapdrm/dss/sdi.c     |    6 
 drivers/gpu/drm/omapdrm/dss/venc.c    |    4 
 drivers/gpu/drm/omapdrm/omap_crtc.c   |   31 ++--
 drivers/gpu/drm/omapdrm/omap_drv.c    |   13 +
 drivers/gpu/drm/omapdrm/omap_drv.h    |    1 
 drivers/gpu/drm/omapdrm/omap_irq.c    |   32 ++--
 drivers/gpu/drm/omapdrm/omap_plane.c  |   12 -
 15 files changed, 257 insertions(+), 196 deletions(-)

--- a/drivers/gpu/drm/omapdrm/dss/base.c
+++ b/drivers/gpu/drm/omapdrm/dss/base.c
@@ -44,6 +44,12 @@ void omapdss_set_dss(struct dss_device *
 }
 EXPORT_SYMBOL(omapdss_set_dss);
 
+struct dispc_device *dispc_get_dispc(struct dss_device *dss)
+{
+	return dss->dispc;
+}
+EXPORT_SYMBOL(dispc_get_dispc);
+
 const struct dispc_ops *dispc_get_ops(struct dss_device *dss)
 {
 	return dss->dispc_ops;
--- a/drivers/gpu/drm/omapdrm/dss/dispc.c
+++ b/drivers/gpu/drm/omapdrm/dss/dispc.c
@@ -162,7 +162,7 @@ struct dispc_features {
 #define DISPC_MAX_NR_FIFOS 5
 #define DISPC_MAX_CHANNEL_GAMMA 4
 
-static struct {
+struct dispc_device {
 	struct platform_device *pdev;
 	void __iomem    *base;
 	struct dss_device *dss;
@@ -194,7 +194,9 @@ static struct {
 
 	/* DISPC_CONTROL & DISPC_CONFIG lock*/
 	spinlock_t control_lock;
-} dispc;
+};
+
+static struct dispc_device dispc;
 
 enum omap_color_component {
 	/* used for all color formats for OMAP3 and earlier
@@ -361,9 +363,7 @@ static unsigned long dispc_mgr_pclk_rate
 static unsigned long dispc_plane_pclk_rate(enum omap_plane_id plane);
 static unsigned long dispc_plane_lclk_rate(enum omap_plane_id plane);
 
-static void dispc_clear_irqstatus(u32 mask);
-static bool dispc_mgr_is_enabled(enum omap_channel channel);
-static void dispc_clear_irqstatus(u32 mask);
+static void dispc_clear_irqstatus(struct dispc_device *dispc, u32 mask);
 
 static inline void dispc_write_reg(const u16 idx, u32 val)
 {
@@ -396,14 +396,14 @@ static void mgr_fld_write(enum omap_chan
 		spin_unlock_irqrestore(&dispc.control_lock, flags);
 }
 
-static int dispc_get_num_ovls(void)
+static int dispc_get_num_ovls(struct dispc_device *dispc)
 {
-	return dispc.feat->num_ovls;
+	return dispc->feat->num_ovls;
 }
 
-static int dispc_get_num_mgrs(void)
+static int dispc_get_num_mgrs(struct dispc_device *dispc)
 {
-	return dispc.feat->num_mgrs;
+	return dispc->feat->num_mgrs;
 }
 
 static void dispc_get_reg_field(enum dispc_feat_reg_field id,
@@ -455,7 +455,7 @@ static void dispc_save_context(void)
 		SR(CONFIG3);
 	}
 
-	for (i = 0; i < dispc_get_num_mgrs(); i++) {
+	for (i = 0; i < dispc_get_num_mgrs(&dispc); i++) {
 		SR(DEFAULT_COLOR(i));
 		SR(TRANS_COLOR(i));
 		SR(SIZE_MGR(i));
@@ -477,7 +477,7 @@ static void dispc_save_context(void)
 		}
 	}
 
-	for (i = 0; i < dispc_get_num_ovls(); i++) {
+	for (i = 0; i < dispc_get_num_ovls(&dispc); i++) {
 		SR(OVL_BA0(i));
 		SR(OVL_BA1(i));
 		SR(OVL_POSITION(i));
@@ -561,7 +561,7 @@ static void dispc_restore_context(void)
 	if (dispc_has_feature(FEAT_MGR_LCD3))
 		RR(CONFIG3);
 
-	for (i = 0; i < dispc_get_num_mgrs(); i++) {
+	for (i = 0; i < dispc_get_num_mgrs(&dispc); i++) {
 		RR(DEFAULT_COLOR(i));
 		RR(TRANS_COLOR(i));
 		RR(SIZE_MGR(i));
@@ -583,7 +583,7 @@ static void dispc_restore_context(void)
 		}
 	}
 
-	for (i = 0; i < dispc_get_num_ovls(); i++) {
+	for (i = 0; i < dispc_get_num_ovls(&dispc); i++) {
 		RR(OVL_BA0(i));
 		RR(OVL_BA1(i));
 		RR(OVL_POSITION(i));
@@ -648,7 +648,7 @@ static void dispc_restore_context(void)
 	if (dispc_has_feature(FEAT_MGR_LCD3))
 		RR(CONTROL3);
 	/* clear spurious SYNC_LOST_DIGIT interrupts */
-	dispc_clear_irqstatus(DISPC_IRQ_SYNC_LOST_DIGIT);
+	dispc_clear_irqstatus(&dispc, DISPC_IRQ_SYNC_LOST_DIGIT);
 
 	/*
 	 * enable last so IRQs won't trigger before
@@ -662,41 +662,44 @@ static void dispc_restore_context(void)
 #undef SR
 #undef RR
 
-int dispc_runtime_get(void)
+int dispc_runtime_get(struct dispc_device *dispc)
 {
 	int r;
 
 	DSSDBG("dispc_runtime_get\n");
 
-	r = pm_runtime_get_sync(&dispc.pdev->dev);
+	r = pm_runtime_get_sync(&dispc->pdev->dev);
 	WARN_ON(r < 0);
 	return r < 0 ? r : 0;
 }
 
-void dispc_runtime_put(void)
+void dispc_runtime_put(struct dispc_device *dispc)
 {
 	int r;
 
 	DSSDBG("dispc_runtime_put\n");
 
-	r = pm_runtime_put_sync(&dispc.pdev->dev);
+	r = pm_runtime_put_sync(&dispc->pdev->dev);
 	WARN_ON(r < 0 && r != -ENOSYS);
 }
 
-static u32 dispc_mgr_get_vsync_irq(enum omap_channel channel)
+static u32 dispc_mgr_get_vsync_irq(struct dispc_device *dispc,
+				   enum omap_channel channel)
 {
 	return mgr_desc[channel].vsync_irq;
 }
 
-static u32 dispc_mgr_get_framedone_irq(enum omap_channel channel)
+static u32 dispc_mgr_get_framedone_irq(struct dispc_device *dispc,
+				       enum omap_channel channel)
 {
-	if (channel == OMAP_DSS_CHANNEL_DIGIT && dispc.feat->no_framedone_tv)
+	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)
+static u32 dispc_mgr_get_sync_lost_irq(struct dispc_device *dispc,
+				       enum omap_channel channel)
 {
 	return mgr_desc[channel].sync_lost_irq;
 }
@@ -706,27 +709,30 @@ u32 dispc_wb_get_framedone_irq(void)
 	return DISPC_IRQ_FRAMEDONEWB;
 }
 
-static void dispc_mgr_enable(enum omap_channel channel, bool enable)
+static void dispc_mgr_enable(struct dispc_device *dispc,
+			     enum omap_channel channel, bool enable)
 {
 	mgr_fld_write(channel, DISPC_MGR_FLD_ENABLE, enable);
 	/* flush posted write */
 	mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE);
 }
 
-static bool dispc_mgr_is_enabled(enum omap_channel channel)
+static bool dispc_mgr_is_enabled(struct dispc_device *dispc,
+				 enum omap_channel channel)
 {
 	return !!mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE);
 }
 
-static bool dispc_mgr_go_busy(enum omap_channel channel)
+static bool dispc_mgr_go_busy(struct dispc_device *dispc,
+			      enum omap_channel channel)
 {
 	return mgr_fld_read(channel, DISPC_MGR_FLD_GO) == 1;
 }
 
-static void dispc_mgr_go(enum omap_channel channel)
+static void dispc_mgr_go(struct dispc_device *dispc, enum omap_channel channel)
 {
-	WARN_ON(!dispc_mgr_is_enabled(channel));
-	WARN_ON(dispc_mgr_go_busy(channel));
+	WARN_ON(!dispc_mgr_is_enabled(dispc, channel));
+	WARN_ON(dispc_mgr_go_busy(dispc, channel));
 
 	DSSDBG("GO %s\n", mgr_desc[channel].name);
 
@@ -864,7 +870,7 @@ static void dispc_ovl_write_color_conv_c
 static void dispc_setup_color_conv_coef(void)
 {
 	int i;
-	int num_ovl = dispc_get_num_ovls();
+	int num_ovl = dispc_get_num_ovls(&dispc);
 	const struct color_conv_coef ctbl_bt601_5_ovl = {
 		/* YUV -> RGB */
 		298, 409, 0, 298, -208, -100, 298, 0, 517, 0,
@@ -956,7 +962,7 @@ static void dispc_ovl_enable_zorder_plan
 	if (!dispc_has_feature(FEAT_ALPHA_FREE_ZORDER))
 		return;
 
-	for (i = 0; i < dispc_get_num_ovls(); i++)
+	for (i = 0; i < dispc_get_num_ovls(&dispc); i++)
 		REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(i), 1, 25, 25);
 }
 
@@ -1213,7 +1219,7 @@ static void dispc_configure_burst_sizes(
 	const int burst_size = BURST_SIZE_X8;
 
 	/* Configure burst size always to maximum size */
-	for (i = 0; i < dispc_get_num_ovls(); ++i)
+	for (i = 0; i < dispc_get_num_ovls(&dispc); ++i)
 		dispc_ovl_set_burst_size(i, burst_size);
 	if (dispc.feat->has_writeback)
 		dispc_ovl_set_burst_size(OMAP_DSS_WB, burst_size);
@@ -1240,9 +1246,10 @@ static bool dispc_ovl_color_mode_support
 	return false;
 }
 
-static const u32 *dispc_ovl_get_color_modes(enum omap_plane_id plane)
+static const u32 *dispc_ovl_get_color_modes(struct dispc_device *dispc,
+					    enum omap_plane_id plane)
 {
-	return dispc.feat->supported_color_modes[plane];
+	return dispc->feat->supported_color_modes[plane];
 }
 
 static void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable)
@@ -1359,7 +1366,7 @@ static void dispc_init_fifos(void)
 	/*
 	 * Setup default fifo thresholds.
 	 */
-	for (i = 0; i < dispc_get_num_ovls(); ++i) {
+	for (i = 0; i < dispc_get_num_ovls(&dispc); ++i) {
 		u32 low, high;
 		const bool use_fifomerge = false;
 		const bool manual_update = false;
@@ -1462,7 +1469,7 @@ void dispc_ovl_compute_fifo_thresholds(e
 
 	if (use_fifomerge) {
 		total_fifo_size = 0;
-		for (i = 0; i < dispc_get_num_ovls(); ++i)
+		for (i = 0; i < dispc_get_num_ovls(&dispc); ++i)
 			total_fifo_size += dispc_ovl_get_fifo_size(i);
 	} else {
 		total_fifo_size = ovl_fifo_size;
@@ -1528,7 +1535,7 @@ static void dispc_init_mflag(void)
 		(1 << 0) |	/* MFLAG_CTRL = force always on */
 		(0 << 2));	/* MFLAG_START = disable */
 
-	for (i = 0; i < dispc_get_num_ovls(); ++i) {
+	for (i = 0; i < dispc_get_num_ovls(&dispc); ++i) {
 		u32 size = dispc_ovl_get_fifo_size(i);
 		u32 unit = dispc.feat->buffer_size_unit;
 		u32 low, high;
@@ -2631,13 +2638,14 @@ static int dispc_ovl_setup_common(enum o
 	return 0;
 }
 
-static int dispc_ovl_setup(enum omap_plane_id plane,
-		const struct omap_overlay_info *oi,
-		const struct videomode *vm, bool mem_to_mem,
-		enum omap_channel channel)
+static int dispc_ovl_setup(struct dispc_device *dispc,
+			   enum omap_plane_id plane,
+			   const struct omap_overlay_info *oi,
+			   const struct videomode *vm, bool mem_to_mem,
+			   enum omap_channel channel)
 {
 	int r;
-	enum omap_overlay_caps caps = dispc.feat->overlay_caps[plane];
+	enum omap_overlay_caps caps = dispc->feat->overlay_caps[plane];
 	const bool replication = true;
 
 	DSSDBG("dispc_ovl_setup %d, pa %pad, pa_uv %pad, sw %d, %d,%d, %dx%d ->"
@@ -2724,7 +2732,8 @@ int dispc_wb_setup(const struct omap_dss
 	return r;
 }
 
-static int dispc_ovl_enable(enum omap_plane_id plane, bool enable)
+static int dispc_ovl_enable(struct dispc_device *dispc,
+			    enum omap_plane_id plane, bool enable)
 {
 	DSSDBG("dispc_enable_plane %d, %d\n", plane, enable);
 
@@ -2733,9 +2742,11 @@ static int dispc_ovl_enable(enum omap_pl
 	return 0;
 }
 
-static enum omap_dss_output_id dispc_mgr_get_supported_outputs(enum omap_channel channel)
+static enum omap_dss_output_id
+dispc_mgr_get_supported_outputs(struct dispc_device *dispc,
+				enum omap_channel channel)
 {
-	return dss_get_supported_outputs(dispc.dss, channel);
+	return dss_get_supported_outputs(dispc->dss, channel);
 }
 
 static void dispc_lcd_enable_signal_polarity(bool act_high)
@@ -2810,8 +2821,9 @@ static void dispc_mgr_enable_alpha_fixed
 		REG_FLD_MOD(DISPC_CONFIG, enable, 19, 19);
 }
 
-static void dispc_mgr_setup(enum omap_channel channel,
-		const struct omap_overlay_manager_info *info)
+static void dispc_mgr_setup(struct dispc_device *dispc,
+			    enum omap_channel channel,
+			    const struct omap_overlay_manager_info *info)
 {
 	dispc_mgr_set_default_color(channel, info->default_color);
 	dispc_mgr_set_trans_key(channel, info->trans_key_type, info->trans_key);
@@ -2883,8 +2895,9 @@ static void dispc_mgr_enable_stallmode(e
 	mgr_fld_write(channel, DISPC_MGR_FLD_STALLMODE, enable);
 }
 
-static void dispc_mgr_set_lcd_config(enum omap_channel channel,
-		const struct dss_lcd_mgr_config *config)
+static void dispc_mgr_set_lcd_config(struct dispc_device *dispc,
+				     enum omap_channel channel,
+				     const struct dss_lcd_mgr_config *config)
 {
 	dispc_mgr_set_io_pad_mode(config->io_pad_mode);
 
@@ -3039,8 +3052,9 @@ static int vm_flag_to_int(enum display_f
 }
 
 /* change name to mode? */
-static void dispc_mgr_set_timings(enum omap_channel channel,
-			   const struct videomode *vm)
+static void dispc_mgr_set_timings(struct dispc_device *dispc,
+				  enum omap_channel channel,
+				  const struct videomode *vm)
 {
 	unsigned int xtot, ytot;
 	unsigned long ht, vt;
@@ -3078,7 +3092,7 @@ static void dispc_mgr_set_timings(enum o
 		if (t.flags & DISPLAY_FLAGS_INTERLACED)
 			t.vactive /= 2;
 
-		if (dispc.feat->supports_double_pixel)
+		if (dispc->feat->supports_double_pixel)
 			REG_FLD_MOD(DISPC_CONTROL,
 				    !!(t.flags & DISPLAY_FLAGS_DOUBLECLK),
 				    19, 17);
@@ -3241,7 +3255,7 @@ void dispc_dump_clocks(struct seq_file *
 	u32 l;
 	enum dss_clk_source dispc_clk_src = dss_get_dispc_clk_source(dispc.dss);
 
-	if (dispc_runtime_get())
+	if (dispc_runtime_get(&dispc))
 		return;
 
 	seq_printf(s, "- DISPC -\n");
@@ -3267,7 +3281,7 @@ void dispc_dump_clocks(struct seq_file *
 	if (dispc_has_feature(FEAT_MGR_LCD3))
 		dispc_dump_clocks_channel(s, OMAP_DSS_CHANNEL_LCD3);
 
-	dispc_runtime_put();
+	dispc_runtime_put(&dispc);
 }
 
 static int dispc_dump_regs(struct seq_file *s, void *p)
@@ -3290,7 +3304,7 @@ static int dispc_dump_regs(struct seq_fi
 
 #define DUMPREG(r) seq_printf(s, "%-50s %08x\n", #r, dispc_read_reg(r))
 
-	if (dispc_runtime_get())
+	if (dispc_runtime_get(&dispc))
 		return 0;
 
 	/* DISPC common registers */
@@ -3328,7 +3342,7 @@ static int dispc_dump_regs(struct seq_fi
 	p_names = mgr_names;
 
 	/* DISPC channel specific registers */
-	for (i = 0; i < dispc_get_num_mgrs(); i++) {
+	for (i = 0; i < dispc_get_num_mgrs(&dispc); i++) {
 		DUMPREG(i, DISPC_DEFAULT_COLOR);
 		DUMPREG(i, DISPC_TRANS_COLOR);
 		DUMPREG(i, DISPC_SIZE_MGR);
@@ -3354,7 +3368,7 @@ static int dispc_dump_regs(struct seq_fi
 
 	p_names = ovl_names;
 
-	for (i = 0; i < dispc_get_num_ovls(); i++) {
+	for (i = 0; i < dispc_get_num_ovls(&dispc); i++) {
 		DUMPREG(i, DISPC_OVL_BA0);
 		DUMPREG(i, DISPC_OVL_BA1);
 		DUMPREG(i, DISPC_OVL_POSITION);
@@ -3432,7 +3446,7 @@ static int dispc_dump_regs(struct seq_fi
 	/* Video pipeline coefficient registers */
 
 	/* start from OMAP_DSS_VIDEO1 */
-	for (i = 1; i < dispc_get_num_ovls(); i++) {
+	for (i = 1; i < dispc_get_num_ovls(&dispc); i++) {
 		for (j = 0; j < 8; j++)
 			DUMPREG(i, DISPC_OVL_FIR_COEF_H, j);
 
@@ -3459,7 +3473,7 @@ static int dispc_dump_regs(struct seq_fi
 		}
 	}
 
-	dispc_runtime_put();
+	dispc_runtime_put(&dispc);
 
 #undef DISPC_REG
 #undef DUMPREG
@@ -3567,22 +3581,22 @@ int dispc_mgr_get_clock_div(enum omap_ch
 	return 0;
 }
 
-static u32 dispc_read_irqstatus(void)
+static u32 dispc_read_irqstatus(struct dispc_device *dispc)
 {
 	return dispc_read_reg(DISPC_IRQSTATUS);
 }
 
-static void dispc_clear_irqstatus(u32 mask)
+static void dispc_clear_irqstatus(struct dispc_device *dispc, u32 mask)
 {
 	dispc_write_reg(DISPC_IRQSTATUS, mask);
 }
 
-static void dispc_write_irqenable(u32 mask)
+static void dispc_write_irqenable(struct dispc_device *dispc, u32 mask)
 {
 	u32 old_mask = dispc_read_reg(DISPC_IRQENABLE);
 
 	/* clear the irqstatus for newly enabled irqs */
-	dispc_clear_irqstatus((mask ^ old_mask) & mask);
+	dispc_clear_irqstatus(dispc, (mask ^ old_mask) & mask);
 
 	dispc_write_reg(DISPC_IRQENABLE, mask);
 
@@ -3600,11 +3614,12 @@ void dispc_disable_sidle(void)
 	REG_FLD_MOD(DISPC_SYSCONFIG, 1, 4, 3);	/* SIDLEMODE: no idle */
 }
 
-static u32 dispc_mgr_gamma_size(enum omap_channel channel)
+static u32 dispc_mgr_gamma_size(struct dispc_device *dispc,
+				enum omap_channel channel)
 {
 	const struct dispc_gamma_desc *gdesc = &mgr_desc[channel].gamma;
 
-	if (!dispc.feat->has_gamma_table)
+	if (!dispc->feat->has_gamma_table)
 		return 0;
 
 	return gdesc->len;
@@ -3653,18 +3668,19 @@ static const struct drm_color_lut dispc_
 	{ .red = U16_MAX, .green = U16_MAX, .blue = U16_MAX, },
 };
 
-static void dispc_mgr_set_gamma(enum omap_channel channel,
-			 const struct drm_color_lut *lut,
-			 unsigned int length)
+static void dispc_mgr_set_gamma(struct dispc_device *dispc,
+				enum omap_channel channel,
+				const struct drm_color_lut *lut,
+				unsigned int length)
 {
 	const struct dispc_gamma_desc *gdesc = &mgr_desc[channel].gamma;
-	u32 *table = dispc.gamma_table[channel];
+	u32 *table = dispc->gamma_table[channel];
 	uint i;
 
 	DSSDBG("%s: channel %d, lut len %u, hw len %u\n", __func__,
 	       channel, length, gdesc->len);
 
-	if (!dispc.feat->has_gamma_table)
+	if (!dispc->feat->has_gamma_table)
 		return;
 
 	if (lut == NULL || length < 2) {
@@ -3696,7 +3712,7 @@ static void dispc_mgr_set_gamma(enum oma
 		}
 	}
 
-	if (dispc.is_enabled)
+	if (dispc->is_enabled)
 		dispc_mgr_write_gamma_table(channel);
 }
 
@@ -3726,7 +3742,7 @@ static int dispc_init_gamma_tables(void)
 
 		dispc.gamma_table[channel] = gt;
 
-		dispc_mgr_set_gamma(channel, NULL, 0);
+		dispc_mgr_set_gamma(&dispc, channel, NULL, 0);
 	}
 	return 0;
 }
@@ -4296,43 +4312,44 @@ static irqreturn_t dispc_irq_handler(int
 	return dispc.user_handler(irq, dispc.user_data);
 }
 
-static int dispc_request_irq(irq_handler_t handler, void *dev_id)
+static int dispc_request_irq(struct dispc_device *dispc, irq_handler_t handler,
+			     void *dev_id)
 {
 	int r;
 
-	if (dispc.user_handler != NULL)
+	if (dispc->user_handler != NULL)
 		return -EBUSY;
 
-	dispc.user_handler = handler;
-	dispc.user_data = dev_id;
+	dispc->user_handler = handler;
+	dispc->user_data = dev_id;
 
 	/* ensure the dispc_irq_handler sees the values above */
 	smp_wmb();
 
-	r = devm_request_irq(&dispc.pdev->dev, dispc.irq, dispc_irq_handler,
-			     IRQF_SHARED, "OMAP DISPC", &dispc);
+	r = devm_request_irq(&dispc->pdev->dev, dispc->irq, dispc_irq_handler,
+			     IRQF_SHARED, "OMAP DISPC", dispc);
 	if (r) {
-		dispc.user_handler = NULL;
-		dispc.user_data = NULL;
+		dispc->user_handler = NULL;
+		dispc->user_data = NULL;
 	}
 
 	return r;
 }
 
-static void dispc_free_irq(void *dev_id)
+static void dispc_free_irq(struct dispc_device *dispc, void *dev_id)
 {
-	devm_free_irq(&dispc.pdev->dev, dispc.irq, &dispc);
+	devm_free_irq(&dispc->pdev->dev, dispc->irq, dispc);
 
-	dispc.user_handler = NULL;
-	dispc.user_data = NULL;
+	dispc->user_handler = NULL;
+	dispc->user_data = NULL;
 }
 
-static u32 dispc_get_memory_bandwidth_limit(void)
+static u32 dispc_get_memory_bandwidth_limit(struct dispc_device *dispc)
 {
 	u32 limit = 0;
 
 	/* Optional maximum memory bandwidth */
-	of_property_read_u32(dispc.pdev->dev.of_node, "max-memory-bandwidth",
+	of_property_read_u32(dispc->pdev->dev.of_node, "max-memory-bandwidth",
 			     &limit);
 
 	return limit;
@@ -4439,7 +4456,8 @@ static void dispc_errata_i734_wa_fini(vo
 
 static void dispc_errata_i734_wa(void)
 {
-	u32 framedone_irq = dispc_mgr_get_framedone_irq(OMAP_DSS_CHANNEL_LCD);
+	u32 framedone_irq = dispc_mgr_get_framedone_irq(&dispc,
+							OMAP_DSS_CHANNEL_LCD);
 	struct omap_overlay_info ovli;
 	struct dss_lcd_mgr_config lcd_conf;
 	u32 gatestate;
@@ -4458,39 +4476,39 @@ static void dispc_errata_i734_wa(void)
 	REG_FLD_MOD(DISPC_CONFIG, 0x1f, 8, 4);
 
 	/* Setup and enable GFX plane */
-	dispc_ovl_setup(OMAP_DSS_GFX, &ovli, &i734.vm, false,
-		OMAP_DSS_CHANNEL_LCD);
-	dispc_ovl_enable(OMAP_DSS_GFX, true);
+	dispc_ovl_setup(&dispc, OMAP_DSS_GFX, &ovli, &i734.vm, false,
+			OMAP_DSS_CHANNEL_LCD);
+	dispc_ovl_enable(&dispc, OMAP_DSS_GFX, true);
 
 	/* Set up and enable display manager for LCD1 */
-	dispc_mgr_setup(OMAP_DSS_CHANNEL_LCD, &i734.mgri);
+	dispc_mgr_setup(&dispc, OMAP_DSS_CHANNEL_LCD, &i734.mgri);
 	dispc_calc_clock_rates(dss_get_dispc_clk_rate(dispc.dss),
 			       &lcd_conf.clock_info);
-	dispc_mgr_set_lcd_config(OMAP_DSS_CHANNEL_LCD, &lcd_conf);
-	dispc_mgr_set_timings(OMAP_DSS_CHANNEL_LCD, &i734.vm);
+	dispc_mgr_set_lcd_config(&dispc, OMAP_DSS_CHANNEL_LCD, &lcd_conf);
+	dispc_mgr_set_timings(&dispc, OMAP_DSS_CHANNEL_LCD, &i734.vm);
 
-	dispc_clear_irqstatus(framedone_irq);
+	dispc_clear_irqstatus(&dispc, framedone_irq);
 
 	/* Enable and shut the channel to produce just one frame */
-	dispc_mgr_enable(OMAP_DSS_CHANNEL_LCD, true);
-	dispc_mgr_enable(OMAP_DSS_CHANNEL_LCD, false);
+	dispc_mgr_enable(&dispc, OMAP_DSS_CHANNEL_LCD, true);
+	dispc_mgr_enable(&dispc, OMAP_DSS_CHANNEL_LCD, false);
 
 	/* Busy wait for framedone. We can't fiddle with irq handlers
 	 * in PM resume. Typically the loop runs less than 5 times and
 	 * waits less than a micro second.
 	 */
 	count = 0;
-	while (!(dispc_read_irqstatus() & framedone_irq)) {
+	while (!(dispc_read_irqstatus(&dispc) & framedone_irq)) {
 		if (count++ > 10000) {
 			dev_err(&dispc.pdev->dev, "%s: framedone timeout\n",
 				__func__);
 			break;
 		}
 	}
-	dispc_ovl_enable(OMAP_DSS_GFX, false);
+	dispc_ovl_enable(&dispc, OMAP_DSS_GFX, false);
 
 	/* Clear all irq bits before continuing */
-	dispc_clear_irqstatus(0xffffffff);
+	dispc_clear_irqstatus(&dispc, 0xffffffff);
 
 	/* Restore the original state to LCD1 output gates */
 	REG_FLD_MOD(DISPC_CONFIG, gatestate, 8, 4);
@@ -4610,7 +4628,7 @@ static int dispc_bind(struct device *dev
 
 	pm_runtime_enable(&pdev->dev);
 
-	r = dispc_runtime_get();
+	r = dispc_runtime_get(&dispc);
 	if (r)
 		goto err_runtime_get;
 
@@ -4620,8 +4638,9 @@ static int dispc_bind(struct device *dev
 	dev_dbg(&pdev->dev, "OMAP DISPC rev %d.%d\n",
 	       FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
 
-	dispc_runtime_put();
+	dispc_runtime_put(&dispc);
 
+	dss->dispc = &dispc;
 	dss->dispc_ops = &dispc_ops;
 
 	dispc.debugfs = dss_debugfs_create_file(dss, "dispc", dispc_dump_regs,
@@ -4634,13 +4653,13 @@ err_runtime_get:
 	return r;
 }
 
-static void dispc_unbind(struct device *dev, struct device *master,
-			       void *data)
+static void dispc_unbind(struct device *dev, struct device *master, void *data)
 {
 	struct dss_device *dss = dispc.dss;
 
 	dss_debugfs_remove_file(dispc.debugfs);
 
+	dss->dispc = NULL;
 	dss->dispc_ops = NULL;
 
 	pm_runtime_disable(dev);
--- a/drivers/gpu/drm/omapdrm/dss/dpi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dpi.c
@@ -406,7 +406,7 @@ static int dpi_display_enable(struct oma
 			goto err_reg_enable;
 	}
 
-	r = dispc_runtime_get();
+	r = dispc_runtime_get(dpi->dss->dispc);
 	if (r)
 		goto err_get_dispc;
 
@@ -442,7 +442,7 @@ err_set_mode:
 		dss_pll_disable(dpi->pll);
 err_pll_init:
 err_src_sel:
-	dispc_runtime_put();
+	dispc_runtime_put(dpi->dss->dispc);
 err_get_dispc:
 	if (dpi->vdds_dsi_reg)
 		regulator_disable(dpi->vdds_dsi_reg);
@@ -466,7 +466,7 @@ static void dpi_display_disable(struct o
 		dss_pll_disable(dpi->pll);
 	}
 
-	dispc_runtime_put();
+	dispc_runtime_put(dpi->dss->dispc);
 
 	if (dpi->vdds_dsi_reg)
 		regulator_disable(dpi->vdds_dsi_reg);
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -5525,7 +5525,7 @@ static int dsi_runtime_suspend(struct de
 	/* wait for current handler to finish before turning the DSI off */
 	synchronize_irq(dsi->irq);
 
-	dispc_runtime_put();
+	dispc_runtime_put(dsi->dss->dispc);
 
 	return 0;
 }
@@ -5535,7 +5535,7 @@ static int dsi_runtime_resume(struct dev
 	struct dsi_data *dsi = dev_get_drvdata(dev);
 	int r;
 
-	r = dispc_runtime_get();
+	r = dispc_runtime_get(dsi->dss->dispc);
 	if (r)
 		return r;
 
--- a/drivers/gpu/drm/omapdrm/dss/dss.h
+++ b/drivers/gpu/drm/omapdrm/dss/dss.h
@@ -25,6 +25,7 @@
 
 #include "omapdss.h"
 
+struct dispc_device;
 struct dss_debugfs_entry;
 struct platform_device;
 struct seq_file;
@@ -272,6 +273,7 @@ struct dss_device {
 	struct dss_pll	*video1_pll;
 	struct dss_pll	*video2_pll;
 
+	struct dispc_device *dispc;
 	const struct dispc_ops *dispc_ops;
 };
 
@@ -407,8 +409,8 @@ static inline void dpi_uninit_port(struc
 /* DISPC */
 void dispc_dump_clocks(struct seq_file *s);
 
-int dispc_runtime_get(void);
-void dispc_runtime_put(void);
+int dispc_runtime_get(struct dispc_device *dispc);
+void dispc_runtime_put(struct dispc_device *dispc);
 
 void dispc_enable_sidle(void);
 void dispc_disable_sidle(void);
--- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
@@ -819,16 +819,19 @@ static int hdmi4_remove(struct platform_
 
 static int hdmi_runtime_suspend(struct device *dev)
 {
-	dispc_runtime_put();
+	struct omap_hdmi *hdmi = dev_get_drvdata(dev);
+
+	dispc_runtime_put(hdmi->dss->dispc);
 
 	return 0;
 }
 
 static int hdmi_runtime_resume(struct device *dev)
 {
+	struct omap_hdmi *hdmi = dev_get_drvdata(dev);
 	int r;
 
-	r = dispc_runtime_get();
+	r = dispc_runtime_get(hdmi->dss->dispc);
 	if (r < 0)
 		return r;
 
--- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
@@ -814,16 +814,19 @@ static int hdmi5_remove(struct platform_
 
 static int hdmi_runtime_suspend(struct device *dev)
 {
-	dispc_runtime_put();
+	struct omap_hdmi *hdmi = dev_get_drvdata(dev);
+
+	dispc_runtime_put(hdmi->dss->dispc);
 
 	return 0;
 }
 
 static int hdmi_runtime_resume(struct device *dev)
 {
+	struct omap_hdmi *hdmi = dev_get_drvdata(dev);
 	int r;
 
-	r = dispc_runtime_get();
+	r = dispc_runtime_get(hdmi->dss->dispc);
 	if (r < 0)
 		return r;
 
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -62,6 +62,8 @@
 struct dss_device;
 struct omap_drm_private;
 struct omap_dss_device;
+struct dispc_device;
+struct dss_device;
 struct dss_lcd_mgr_config;
 struct snd_aes_iec958;
 struct snd_cea_861_aud_if;
@@ -690,49 +692,64 @@ void dss_mgr_unregister_framedone_handle
 /* dispc ops */
 
 struct dispc_ops {
-	u32 (*read_irqstatus)(void);
-	void (*clear_irqstatus)(u32 mask);
-	void (*write_irqenable)(u32 mask);
-
-	int (*request_irq)(irq_handler_t handler, void *dev_id);
-	void (*free_irq)(void *dev_id);
-
-	int (*runtime_get)(void);
-	void (*runtime_put)(void);
-
-	int (*get_num_ovls)(void);
-	int (*get_num_mgrs)(void);
-
-	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,
-			const struct dss_lcd_mgr_config *config);
-	void (*mgr_set_timings)(enum omap_channel channel,
-			const struct videomode *vm);
-	void (*mgr_setup)(enum omap_channel channel,
-			const struct omap_overlay_manager_info *info);
-	enum omap_dss_output_id (*mgr_get_supported_outputs)(enum omap_channel channel);
-	u32 (*mgr_gamma_size)(enum omap_channel channel);
-	void (*mgr_set_gamma)(enum omap_channel channel,
-		const struct drm_color_lut *lut,
-		unsigned int length);
-
-	int (*ovl_enable)(enum omap_plane_id plane, bool enable);
-	int (*ovl_setup)(enum omap_plane_id plane,
+	u32 (*read_irqstatus)(struct dispc_device *dispc);
+	void (*clear_irqstatus)(struct dispc_device *dispc, u32 mask);
+	void (*write_irqenable)(struct dispc_device *dispc, u32 mask);
+
+	int (*request_irq)(struct dispc_device *dispc, irq_handler_t handler,
+			   void *dev_id);
+	void (*free_irq)(struct dispc_device *dispc, void *dev_id);
+
+	int (*runtime_get)(struct dispc_device *dispc);
+	void (*runtime_put)(struct dispc_device *dispc);
+
+	int (*get_num_ovls)(struct dispc_device *dispc);
+	int (*get_num_mgrs)(struct dispc_device *dispc);
+
+	u32 (*get_memory_bandwidth_limit)(struct dispc_device *dispc);
+
+	void (*mgr_enable)(struct dispc_device *dispc,
+			   enum omap_channel channel, bool enable);
+	bool (*mgr_is_enabled)(struct dispc_device *dispc,
+			       enum omap_channel channel);
+	u32 (*mgr_get_vsync_irq)(struct dispc_device *dispc,
+				 enum omap_channel channel);
+	u32 (*mgr_get_framedone_irq)(struct dispc_device *dispc,
+				     enum omap_channel channel);
+	u32 (*mgr_get_sync_lost_irq)(struct dispc_device *dispc,
+				     enum omap_channel channel);
+	bool (*mgr_go_busy)(struct dispc_device *dispc,
+			    enum omap_channel channel);
+	void (*mgr_go)(struct dispc_device *dispc, enum omap_channel channel);
+	void (*mgr_set_lcd_config)(struct dispc_device *dispc,
+				   enum omap_channel channel,
+				   const struct dss_lcd_mgr_config *config);
+	void (*mgr_set_timings)(struct dispc_device *dispc,
+				enum omap_channel channel,
+				const struct videomode *vm);
+	void (*mgr_setup)(struct dispc_device *dispc, enum omap_channel channel,
+			  const struct omap_overlay_manager_info *info);
+	enum omap_dss_output_id (*mgr_get_supported_outputs)(
+			struct dispc_device *dispc, enum omap_channel channel);
+	u32 (*mgr_gamma_size)(struct dispc_device *dispc,
+			      enum omap_channel channel);
+	void (*mgr_set_gamma)(struct dispc_device *dispc,
+			      enum omap_channel channel,
+			      const struct drm_color_lut *lut,
+			      unsigned int length);
+
+	int (*ovl_enable)(struct dispc_device *dispc, enum omap_plane_id plane,
+			  bool enable);
+	int (*ovl_setup)(struct dispc_device *dispc, enum omap_plane_id plane,
 			 const struct omap_overlay_info *oi,
-			const struct videomode *vm, bool mem_to_mem,
-			enum omap_channel channel);
+			 const struct videomode *vm, bool mem_to_mem,
+			 enum omap_channel channel);
 
-	const u32 *(*ovl_get_color_modes)(enum omap_plane_id plane);
+	const u32 *(*ovl_get_color_modes)(struct dispc_device *dispc,
+					  enum omap_plane_id plane);
 };
 
+struct dispc_device *dispc_get_dispc(struct dss_device *dss);
 const struct dispc_ops *dispc_get_ops(struct dss_device *dss);
 
 bool omapdss_component_is_display(struct device_node *node);
--- a/drivers/gpu/drm/omapdrm/dss/sdi.c
+++ b/drivers/gpu/drm/omapdrm/dss/sdi.c
@@ -141,7 +141,7 @@ static int sdi_display_enable(struct oma
 	if (r)
 		goto err_reg_enable;
 
-	r = dispc_runtime_get();
+	r = dispc_runtime_get(sdi.dss->dispc);
 	if (r)
 		goto err_get_dispc;
 
@@ -203,7 +203,7 @@ err_mgr_enable:
 err_sdi_enable:
 err_set_dss_clock_div:
 err_calc_clock_div:
-	dispc_runtime_put();
+	dispc_runtime_put(sdi.dss->dispc);
 err_get_dispc:
 	regulator_disable(sdi.vdds_sdi_reg);
 err_reg_enable:
@@ -216,7 +216,7 @@ static void sdi_display_disable(struct o
 
 	dss_sdi_disable(sdi.dss);
 
-	dispc_runtime_put();
+	dispc_runtime_put(sdi.dss->dispc);
 
 	regulator_disable(sdi.vdds_sdi_reg);
 }
--- a/drivers/gpu/drm/omapdrm/dss/venc.c
+++ b/drivers/gpu/drm/omapdrm/dss/venc.c
@@ -956,7 +956,7 @@ static int venc_runtime_suspend(struct d
 	if (venc.tv_dac_clk)
 		clk_disable_unprepare(venc.tv_dac_clk);
 
-	dispc_runtime_put();
+	dispc_runtime_put(venc.dss->dispc);
 
 	return 0;
 }
@@ -965,7 +965,7 @@ static int venc_runtime_resume(struct de
 {
 	int r;
 
-	r = dispc_runtime_get();
+	r = dispc_runtime_get(venc.dss->dispc);
 	if (r < 0)
 		return r;
 
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -117,10 +117,13 @@ static int omap_crtc_dss_connect(struct
 		enum omap_channel channel,
 		struct omap_dss_device *dst)
 {
+	const struct dispc_ops *dispc_ops = priv->dispc_ops;
+	struct dispc_device *dispc = priv->dispc;
+
 	if (omap_crtc_output[channel])
 		return -EINVAL;
 
-	if (!(priv->dispc_ops->mgr_get_supported_outputs(channel) & dst->id))
+	if (!(dispc_ops->mgr_get_supported_outputs(dispc, channel) & dst->id))
 		return -EINVAL;
 
 	omap_crtc_output[channel] = dst;
@@ -157,7 +160,7 @@ static void omap_crtc_set_enabled(struct
 		return;
 
 	if (omap_crtc_output[channel]->output_type == OMAP_DISPLAY_TYPE_HDMI) {
-		priv->dispc_ops->mgr_enable(channel, enable);
+		priv->dispc_ops->mgr_enable(priv->dispc, channel, enable);
 		omap_crtc->enabled = enable;
 		return;
 	}
@@ -170,8 +173,9 @@ static void omap_crtc_set_enabled(struct
 		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);
+	framedone_irq = priv->dispc_ops->mgr_get_framedone_irq(priv->dispc,
+							       channel);
+	vsync_irq = priv->dispc_ops->mgr_get_vsync_irq(priv->dispc, channel);
 
 	if (enable) {
 		wait = omap_irq_wait_init(dev, vsync_irq, 1);
@@ -191,7 +195,7 @@ static void omap_crtc_set_enabled(struct
 			wait = omap_irq_wait_init(dev, vsync_irq, 2);
 	}
 
-	priv->dispc_ops->mgr_enable(channel, enable);
+	priv->dispc_ops->mgr_enable(priv->dispc, channel, enable);
 	omap_crtc->enabled = enable;
 
 	ret = omap_irq_wait(dev, wait, msecs_to_jiffies(100));
@@ -213,7 +217,8 @@ static int omap_crtc_dss_enable(struct o
 {
 	struct omap_crtc *omap_crtc = omap_crtcs[channel];
 
-	priv->dispc_ops->mgr_set_timings(omap_crtc->channel, &omap_crtc->vm);
+	priv->dispc_ops->mgr_set_timings(priv->dispc, omap_crtc->channel,
+					 &omap_crtc->vm);
 	omap_crtc_set_enabled(&omap_crtc->base, true);
 
 	return 0;
@@ -243,7 +248,8 @@ static void omap_crtc_dss_set_lcd_config
 	struct omap_crtc *omap_crtc = omap_crtcs[channel];
 
 	DBG("%s", omap_crtc->name);
-	priv->dispc_ops->mgr_set_lcd_config(omap_crtc->channel, config);
+	priv->dispc_ops->mgr_set_lcd_config(priv->dispc, omap_crtc->channel,
+					    config);
 }
 
 static int omap_crtc_dss_register_framedone(
@@ -300,7 +306,7 @@ void omap_crtc_vblank_irq(struct drm_crt
 	 * If the dispc is busy we're racing the flush operation. Try again on
 	 * the next vblank interrupt.
 	 */
-	if (priv->dispc_ops->mgr_go_busy(omap_crtc->channel)) {
+	if (priv->dispc_ops->mgr_go_busy(priv->dispc, omap_crtc->channel)) {
 		spin_unlock(&crtc->dev->event_lock);
 		return;
 	}
@@ -337,7 +343,7 @@ static void omap_crtc_write_crtc_propert
 	info.partial_alpha_enabled = false;
 	info.cpr_enable = false;
 
-	priv->dispc_ops->mgr_setup(omap_crtc->channel, &info);
+	priv->dispc_ops->mgr_setup(priv->dispc, omap_crtc->channel, &info);
 }
 
 /* -----------------------------------------------------------------------------
@@ -537,7 +543,8 @@ static void omap_crtc_atomic_flush(struc
 			length = crtc->state->gamma_lut->length /
 				sizeof(*lut);
 		}
-		priv->dispc_ops->mgr_set_gamma(omap_crtc->channel, lut, length);
+		priv->dispc_ops->mgr_set_gamma(priv->dispc, omap_crtc->channel,
+					       lut, length);
 	}
 
 	omap_crtc_write_crtc_properties(crtc);
@@ -552,7 +559,7 @@ static void omap_crtc_atomic_flush(struc
 	WARN_ON(ret != 0);
 
 	spin_lock_irq(&crtc->dev->event_lock);
-	priv->dispc_ops->mgr_go(omap_crtc->channel);
+	priv->dispc_ops->mgr_go(priv->dispc, omap_crtc->channel);
 	omap_crtc_arm_event(crtc);
 	spin_unlock_irq(&crtc->dev->event_lock);
 }
@@ -734,7 +741,7 @@ struct drm_crtc *omap_crtc_init(struct d
 	 * extracted with dispc_mgr_gamma_size(). If it returns 0
 	 * gamma table is not supprted.
 	 */
-	if (priv->dispc_ops->mgr_gamma_size(channel)) {
+	if (priv->dispc_ops->mgr_gamma_size(priv->dispc, channel)) {
 		unsigned int gamma_lut_size = 256;
 
 		drm_crtc_enable_color_mgmt(crtc, 0, false, gamma_lut_size);
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -69,7 +69,7 @@ static void omap_atomic_commit_tail(stru
 	struct drm_device *dev = old_state->dev;
 	struct omap_drm_private *priv = dev->dev_private;
 
-	priv->dispc_ops->runtime_get();
+	priv->dispc_ops->runtime_get(priv->dispc);
 
 	/* Apply the atomic update. */
 	drm_atomic_helper_commit_modeset_disables(dev, old_state);
@@ -113,7 +113,7 @@ static void omap_atomic_commit_tail(stru
 
 	drm_atomic_helper_cleanup_planes(dev, old_state);
 
-	priv->dispc_ops->runtime_put();
+	priv->dispc_ops->runtime_put(priv->dispc);
 }
 
 static const struct drm_mode_config_helper_funcs omap_mode_config_helper_funcs = {
@@ -191,7 +191,7 @@ cleanup:
 static int omap_modeset_init_properties(struct drm_device *dev)
 {
 	struct omap_drm_private *priv = dev->dev_private;
-	unsigned int num_planes = priv->dispc_ops->get_num_ovls();
+	unsigned int num_planes = priv->dispc_ops->get_num_ovls(priv->dispc);
 
 	priv->zorder_prop = drm_property_create_range(dev, 0, "zorder", 0,
 						      num_planes - 1);
@@ -205,8 +205,8 @@ static int omap_modeset_init(struct drm_
 {
 	struct omap_drm_private *priv = dev->dev_private;
 	struct omap_dss_device *dssdev = NULL;
-	int num_ovls = priv->dispc_ops->get_num_ovls();
-	int num_mgrs = priv->dispc_ops->get_num_mgrs();
+	int num_ovls = priv->dispc_ops->get_num_ovls(priv->dispc);
+	int num_mgrs = priv->dispc_ops->get_num_mgrs(priv->dispc);
 	int num_crtcs, crtc_idx, plane_idx;
 	int ret;
 	u32 plane_crtc_mask;
@@ -521,6 +521,7 @@ static int omapdrm_init(struct omap_drm_
 
 	priv->dev = dev;
 	priv->dss = omapdss_get_dss();
+	priv->dispc = dispc_get_dispc(priv->dss);
 	priv->dispc_ops = dispc_get_ops(priv->dss);
 
 	omap_crtc_pre_init(priv);
@@ -549,7 +550,7 @@ static int omapdrm_init(struct omap_drm_
 	/* Get memory bandwidth limits */
 	if (priv->dispc_ops->get_memory_bandwidth_limit)
 		priv->max_bandwidth =
-				priv->dispc_ops->get_memory_bandwidth_limit();
+			priv->dispc_ops->get_memory_bandwidth_limit(priv->dispc);
 
 	omap_gem_init(ddev);
 
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -51,6 +51,7 @@ struct omap_drm_private {
 	u32 omaprev;
 
 	struct dss_device *dss;
+	struct dispc_device *dispc;
 	const struct dispc_ops *dispc_ops;
 
 	unsigned int num_crtcs;
--- a/drivers/gpu/drm/omapdrm/omap_irq.c
+++ b/drivers/gpu/drm/omapdrm/omap_irq.c
@@ -38,7 +38,7 @@ static void omap_irq_update(struct drm_d
 
 	DBG("irqmask=%08x", irqmask);
 
-	priv->dispc_ops->write_irqenable(irqmask);
+	priv->dispc_ops->write_irqenable(priv->dispc, irqmask);
 }
 
 static void omap_irq_wait_handler(struct omap_irq_wait *wait)
@@ -108,7 +108,8 @@ int omap_irq_enable_vblank(struct drm_cr
 	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);
+	priv->irq_mask |= priv->dispc_ops->mgr_get_vsync_irq(priv->dispc,
+							     channel);
 	omap_irq_update(dev);
 	spin_unlock_irqrestore(&priv->wait_lock, flags);
 
@@ -134,7 +135,8 @@ void omap_irq_disable_vblank(struct drm_
 	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);
+	priv->irq_mask &= ~priv->dispc_ops->mgr_get_vsync_irq(priv->dispc,
+							      channel);
 	omap_irq_update(dev);
 	spin_unlock_irqrestore(&priv->wait_lock, flags);
 }
@@ -198,9 +200,9 @@ static irqreturn_t omap_irq_handler(int
 	unsigned int id;
 	u32 irqstatus;
 
-	irqstatus = priv->dispc_ops->read_irqstatus();
-	priv->dispc_ops->clear_irqstatus(irqstatus);
-	priv->dispc_ops->read_irqstatus();        /* flush posted write */
+	irqstatus = priv->dispc_ops->read_irqstatus(priv->dispc);
+	priv->dispc_ops->clear_irqstatus(priv->dispc, irqstatus);
+	priv->dispc_ops->read_irqstatus(priv->dispc);	/* flush posted write */
 
 	VERB("irqs: %08x", irqstatus);
 
@@ -208,12 +210,12 @@ static irqreturn_t omap_irq_handler(int
 		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 & priv->dispc_ops->mgr_get_vsync_irq(priv->dispc, channel)) {
 			drm_handle_vblank(dev, id);
 			omap_crtc_vblank_irq(crtc);
 		}
 
-		if (irqstatus & priv->dispc_ops->mgr_get_sync_lost_irq(channel))
+		if (irqstatus & priv->dispc_ops->mgr_get_sync_lost_irq(priv->dispc, channel))
 			omap_crtc_error_irq(crtc, irqstatus);
 	}
 
@@ -247,7 +249,7 @@ static const u32 omap_underflow_irqs[] =
 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 num_mgrs = priv->dispc_ops->get_num_mgrs(priv->dispc);
 	unsigned int max_planes;
 	unsigned int i;
 	int ret;
@@ -265,13 +267,13 @@ int omap_drm_irq_install(struct drm_devi
 	}
 
 	for (i = 0; i < num_mgrs; ++i)
-		priv->irq_mask |= priv->dispc_ops->mgr_get_sync_lost_irq(i);
+		priv->irq_mask |= priv->dispc_ops->mgr_get_sync_lost_irq(priv->dispc, i);
 
-	priv->dispc_ops->runtime_get();
-	priv->dispc_ops->clear_irqstatus(0xffffffff);
-	priv->dispc_ops->runtime_put();
+	priv->dispc_ops->runtime_get(priv->dispc);
+	priv->dispc_ops->clear_irqstatus(priv->dispc, 0xffffffff);
+	priv->dispc_ops->runtime_put(priv->dispc);
 
-	ret = priv->dispc_ops->request_irq(omap_irq_handler, dev);
+	ret = priv->dispc_ops->request_irq(priv->dispc, omap_irq_handler, dev);
 	if (ret < 0)
 		return ret;
 
@@ -289,5 +291,5 @@ void omap_drm_irq_uninstall(struct drm_d
 
 	dev->irq_enabled = false;
 
-	priv->dispc_ops->free_irq(dev);
+	priv->dispc_ops->free_irq(priv->dispc, dev);
 }
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -77,17 +77,17 @@ static void omap_plane_atomic_update(str
 			&info.paddr, &info.p_uv_addr);
 
 	/* and finally, update omapdss: */
-	ret = priv->dispc_ops->ovl_setup(omap_plane->id, &info,
+	ret = priv->dispc_ops->ovl_setup(priv->dispc, omap_plane->id, &info,
 			      omap_crtc_timings(state->crtc), false,
 			      omap_crtc_channel(state->crtc));
 	if (ret) {
 		dev_err(plane->dev->dev, "Failed to setup plane %s\n",
 			omap_plane->name);
-		priv->dispc_ops->ovl_enable(omap_plane->id, false);
+		priv->dispc_ops->ovl_enable(priv->dispc, omap_plane->id, false);
 		return;
 	}
 
-	priv->dispc_ops->ovl_enable(omap_plane->id, true);
+	priv->dispc_ops->ovl_enable(priv->dispc, omap_plane->id, true);
 }
 
 static void omap_plane_atomic_disable(struct drm_plane *plane,
@@ -100,7 +100,7 @@ static void omap_plane_atomic_disable(st
 	plane->state->zpos = plane->type == DRM_PLANE_TYPE_PRIMARY
 			   ? 0 : omap_plane->id;
 
-	priv->dispc_ops->ovl_enable(omap_plane->id, false);
+	priv->dispc_ops->ovl_enable(priv->dispc, omap_plane->id, false);
 }
 
 static int omap_plane_atomic_check(struct drm_plane *plane,
@@ -259,7 +259,7 @@ struct drm_plane *omap_plane_init(struct
 		u32 possible_crtcs)
 {
 	struct omap_drm_private *priv = dev->dev_private;
-	unsigned int num_planes = priv->dispc_ops->get_num_ovls();
+	unsigned int num_planes = priv->dispc_ops->get_num_ovls(priv->dispc);
 	struct drm_plane *plane;
 	struct omap_plane *omap_plane;
 	enum omap_plane_id id;
@@ -278,7 +278,7 @@ struct drm_plane *omap_plane_init(struct
 	if (!omap_plane)
 		return ERR_PTR(-ENOMEM);
 
-	formats = priv->dispc_ops->ovl_get_color_modes(id);
+	formats = priv->dispc_ops->ovl_get_color_modes(priv->dispc, id);
 	for (nformats = 0; formats[nformats]; ++nformats)
 		;
 	omap_plane->id = id;