Patchwork [43/48] drm: omapdrm: dss: Pass omap_drm_private pointer to dss_mgr_ops

login
register
mail settings
Submitter Laurent Pinchart
Date Oct. 13, 2017, 2:59 p.m.
Message ID <20171013145944.26557-44-laurent.pinchart@ideasonboard.com>
Download mbox | patch
Permalink /patch/10005051/
State New
Headers show

Comments

Laurent Pinchart - Oct. 13, 2017, 2:59 p.m.
The dss_mgr_ops operations implemented by the omapdrm side have to look
up the omap_crtc objects from global variables as they are only passed a
channel number. In order to remove global variables pass the
omap_drm_private pointer to the dss_mgr_ops. This requires storing a
pointer to the dss_device in the omap_dss_device structure to allow
looking up the omap_drm_private in the dss_mgr_*() functions.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpu/drm/omapdrm/dss/dpi.c     |  1 +
 drivers/gpu/drm/omapdrm/dss/dsi.c     |  1 +
 drivers/gpu/drm/omapdrm/dss/dss.c     | 37 ---------------------------------
 drivers/gpu/drm/omapdrm/dss/dss.h     | 37 +++++++++++++++++++++++++++++++++
 drivers/gpu/drm/omapdrm/dss/hdmi4.c   |  1 +
 drivers/gpu/drm/omapdrm/dss/hdmi5.c   |  1 +
 drivers/gpu/drm/omapdrm/dss/omapdss.h | 39 ++++++++++++++++++++++-------------
 drivers/gpu/drm/omapdrm/dss/output.c  | 23 +++++++++++++--------
 drivers/gpu/drm/omapdrm/dss/sdi.c     |  1 +
 drivers/gpu/drm/omapdrm/dss/venc.c    |  1 +
 drivers/gpu/drm/omapdrm/omap_crtc.c   | 27 ++++++++++++++----------
 11 files changed, 98 insertions(+), 71 deletions(-)
Sebastian Reichel - Oct. 17, 2017, 9:23 p.m.
Hi,

On Fri, Oct 13, 2017 at 05:59:39PM +0300, Laurent Pinchart wrote:
> The dss_mgr_ops operations implemented by the omapdrm side have to look
> up the omap_crtc objects from global variables as they are only passed a
> channel number. In order to remove global variables pass the
> omap_drm_private pointer to the dss_mgr_ops. This requires storing a
> pointer to the dss_device in the omap_dss_device structure to allow
> looking up the omap_drm_private in the dss_mgr_*() functions.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>

-- Sebastian

>  drivers/gpu/drm/omapdrm/dss/dpi.c     |  1 +
>  drivers/gpu/drm/omapdrm/dss/dsi.c     |  1 +
>  drivers/gpu/drm/omapdrm/dss/dss.c     | 37 ---------------------------------
>  drivers/gpu/drm/omapdrm/dss/dss.h     | 37 +++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/omapdrm/dss/hdmi4.c   |  1 +
>  drivers/gpu/drm/omapdrm/dss/hdmi5.c   |  1 +
>  drivers/gpu/drm/omapdrm/dss/omapdss.h | 39 ++++++++++++++++++++++-------------
>  drivers/gpu/drm/omapdrm/dss/output.c  | 23 +++++++++++++--------
>  drivers/gpu/drm/omapdrm/dss/sdi.c     |  1 +
>  drivers/gpu/drm/omapdrm/dss/venc.c    |  1 +
>  drivers/gpu/drm/omapdrm/omap_crtc.c   | 27 ++++++++++++++----------
>  11 files changed, 98 insertions(+), 71 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c b/drivers/gpu/drm/omapdrm/dss/dpi.c
> index 3894e53ff58d..ae43ba81eb96 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dpi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dpi.c
> @@ -727,6 +727,7 @@ static void dpi_init_output_port(struct dpi_data *dpi, struct device_node *port)
>  	}
>  
>  	out->dev = &dpi->pdev->dev;
> +	out->dss = dpi->dss;
>  	out->id = OMAP_DSS_OUTPUT_DPI;
>  	out->output_type = OMAP_DISPLAY_TYPE_DPI;
>  	out->dispc_channel = dpi_get_channel(dpi, port_num);
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
> index 512625ed03e2..eafea72998dd 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> @@ -5044,6 +5044,7 @@ static void dsi_init_output(struct dsi_data *dsi)
>  	struct omap_dss_device *out = &dsi->output;
>  
>  	out->dev = dsi->dev;
> +	out->dss = dsi->dss;
>  	out->id = dsi->module_id == 0 ?
>  			OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2;
>  
> diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c
> index 8fec9bf6f06f..0e8c70591308 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dss.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dss.c
> @@ -49,9 +49,6 @@
>  
>  #include "omapdss.h"
>  #include "dss.h"
> -#include "../omap_drv.h"
> -
> -#define DSS_SZ_REGS			SZ_512
>  
>  struct dss_reg {
>  	u16 idx;
> @@ -96,40 +93,6 @@ struct dss_features {
>  	bool has_lcd_clk_src;
>  };
>  
> -struct dss_device {
> -	struct platform_device *pdev;
> -	struct omap_drm_private drm;
> -
> -	void __iomem    *base;
> -	struct regmap	*syscon_pll_ctrl;
> -	u32		syscon_pll_ctrl_offset;
> -
> -	struct clk	*parent_clk;
> -	struct clk	*dss_clk;
> -	unsigned long	dss_clk_rate;
> -
> -	unsigned long	cache_req_pck;
> -	unsigned long	cache_prate;
> -	struct dispc_clock_info cache_dispc_cinfo;
> -
> -	enum dss_clk_source dsi_clk_source[MAX_NUM_DSI];
> -	enum dss_clk_source dispc_clk_source;
> -	enum dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS];
> -
> -	bool		ctx_valid;
> -	u32		ctx[DSS_SZ_REGS / sizeof(u32)];
> -
> -	const struct dss_features *feat;
> -
> -	struct {
> -		struct dss_debugfs_entry *clk;
> -		struct dss_debugfs_entry *dss;
> -	} debugfs;
> -
> -	struct dss_pll	*video1_pll;
> -	struct dss_pll	*video2_pll;
> -};
> -
>  static const char * const dss_generic_clk_source_names[] = {
>  	[DSS_CLK_SRC_FCK]	= "FCK",
>  	[DSS_CLK_SRC_PLL1_1]	= "PLL1:1",
> diff --git a/drivers/gpu/drm/omapdrm/dss/dss.h b/drivers/gpu/drm/omapdrm/dss/dss.h
> index 5d6f8afca49d..cda2cbd888f0 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dss.h
> +++ b/drivers/gpu/drm/omapdrm/dss/dss.h
> @@ -26,6 +26,7 @@
>  #include <linux/interrupt.h>
>  
>  #include "omapdss.h"
> +#include "../omap_drv.h"
>  
>  struct dentry;
>  struct dss_debugfs_entry;
> @@ -241,6 +242,42 @@ struct dss_lcd_mgr_config {
>  	int lcden_sig_polarity;
>  };
>  
> +#define DSS_SZ_REGS			SZ_512
> +
> +struct dss_device {
> +	struct platform_device *pdev;
> +	struct omap_drm_private drm;
> +
> +	void __iomem    *base;
> +	struct regmap	*syscon_pll_ctrl;
> +	u32		syscon_pll_ctrl_offset;
> +
> +	struct clk	*parent_clk;
> +	struct clk	*dss_clk;
> +	unsigned long	dss_clk_rate;
> +
> +	unsigned long	cache_req_pck;
> +	unsigned long	cache_prate;
> +	struct dispc_clock_info cache_dispc_cinfo;
> +
> +	enum dss_clk_source dsi_clk_source[MAX_NUM_DSI];
> +	enum dss_clk_source dispc_clk_source;
> +	enum dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS];
> +
> +	bool		ctx_valid;
> +	u32		ctx[DSS_SZ_REGS / sizeof(u32)];
> +
> +	const struct dss_features *feat;
> +
> +	struct {
> +		struct dss_debugfs_entry *clk;
> +		struct dss_debugfs_entry *dss;
> +	} debugfs;
> +
> +	struct dss_pll	*video1_pll;
> +	struct dss_pll	*video2_pll;
> +};
> +
>  /* core */
>  static inline int dss_set_min_bus_tput(struct device *dev, unsigned long tput)
>  {
> diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
> index 56de3c75b0a0..501813f03466 100644
> --- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c
> +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
> @@ -566,6 +566,7 @@ static void hdmi_init_output(struct omap_hdmi *hdmi)
>  	struct omap_dss_device *out = &hdmi->output;
>  
>  	out->dev = &hdmi->pdev->dev;
> +	out->dss = hdmi->dss;
>  	out->id = OMAP_DSS_OUTPUT_HDMI;
>  	out->output_type = OMAP_DISPLAY_TYPE_HDMI;
>  	out->name = "hdmi->0";
> diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
> index 1e839af800e7..44954bdea6ce 100644
> --- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c
> +++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
> @@ -558,6 +558,7 @@ static void hdmi_init_output(struct omap_hdmi *hdmi)
>  	struct omap_dss_device *out = &hdmi->output;
>  
>  	out->dev = &hdmi->pdev->dev;
> +	out->dss = hdmi->dss;
>  	out->id = OMAP_DSS_OUTPUT_HDMI;
>  	out->output_type = OMAP_DISPLAY_TYPE_HDMI;
>  	out->name = "hdmi->0";
> diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
> index 32c5944b0bea..76ce94376454 100644
> --- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
> +++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
> @@ -59,6 +59,7 @@
>  #define DISPC_IRQ_ACBIAS_COUNT_STAT3	(1 << 29)
>  #define DISPC_IRQ_FRAMEDONE3		(1 << 30)
>  
> +struct omap_drm_private;
>  struct omap_dss_device;
>  struct dss_lcd_mgr_config;
>  struct snd_aes_iec958;
> @@ -471,6 +472,7 @@ struct omapdss_dsi_ops {
>  struct omap_dss_device {
>  	struct kobject kobj;
>  	struct device *dev;
> +	struct dss_device *dss; /* valid for DSS outputs only */
>  
>  	struct module *owner;
>  
> @@ -632,21 +634,30 @@ struct device_node *dss_of_port_get_parent_device(struct device_node *port);
>  u32 dss_of_port_get_port_number(struct device_node *port);
>  
>  struct dss_mgr_ops {
> -	int (*connect)(enum omap_channel channel,
> -		struct omap_dss_device *dst);
> -	void (*disconnect)(enum omap_channel channel,
> -		struct omap_dss_device *dst);
> -
> -	void (*start_update)(enum omap_channel channel);
> -	int (*enable)(enum omap_channel channel);
> -	void (*disable)(enum omap_channel channel);
> -	void (*set_timings)(enum omap_channel channel,
> -			const struct videomode *vm);
> -	void (*set_lcd_config)(enum omap_channel channel,
> -			const struct dss_lcd_mgr_config *config);
> -	int (*register_framedone_handler)(enum omap_channel channel,
> +	int (*connect)(struct omap_drm_private *priv,
> +		       enum omap_channel channel,
> +		       struct omap_dss_device *dst);
> +	void (*disconnect)(struct omap_drm_private *priv,
> +			   enum omap_channel channel,
> +			   struct omap_dss_device *dst);
> +
> +	void (*start_update)(struct omap_drm_private *priv,
> +			     enum omap_channel channel);
> +	int (*enable)(struct omap_drm_private *priv,
> +		      enum omap_channel channel);
> +	void (*disable)(struct omap_drm_private *priv,
> +			enum omap_channel channel);
> +	void (*set_timings)(struct omap_drm_private *priv,
> +			    enum omap_channel channel,
> +			    const struct videomode *vm);
> +	void (*set_lcd_config)(struct omap_drm_private *priv,
> +			       enum omap_channel channel,
> +			       const struct dss_lcd_mgr_config *config);
> +	int (*register_framedone_handler)(struct omap_drm_private *priv,
> +			enum omap_channel channel,
>  			void (*handler)(void *), void *data);
> -	void (*unregister_framedone_handler)(enum omap_channel channel,
> +	void (*unregister_framedone_handler)(struct omap_drm_private *priv,
> +			enum omap_channel channel,
>  			void (*handler)(void *), void *data);
>  };
>  
> diff --git a/drivers/gpu/drm/omapdrm/dss/output.c b/drivers/gpu/drm/omapdrm/dss/output.c
> index 0573b5099f8f..4a6ccad7e970 100644
> --- a/drivers/gpu/drm/omapdrm/dss/output.c
> +++ b/drivers/gpu/drm/omapdrm/dss/output.c
> @@ -21,6 +21,7 @@
>  #include <linux/slab.h>
>  #include <linux/of.h>
>  
> +#include "dss.h"
>  #include "omapdss.h"
>  
>  static LIST_HEAD(output_list);
> @@ -186,52 +187,56 @@ EXPORT_SYMBOL(dss_uninstall_mgr_ops);
>  
>  int dss_mgr_connect(struct omap_dss_device *dssdev, struct omap_dss_device *dst)
>  {
> -	return dss_mgr_ops->connect(dssdev->dispc_channel, dst);
> +	return dss_mgr_ops->connect(&dssdev->dss->drm,
> +				    dssdev->dispc_channel, dst);
>  }
>  
>  void dss_mgr_disconnect(struct omap_dss_device *dssdev,
>  			struct omap_dss_device *dst)
>  {
> -	dss_mgr_ops->disconnect(dssdev->dispc_channel, dst);
> +	dss_mgr_ops->disconnect(&dssdev->dss->drm, dssdev->dispc_channel, dst);
>  }
>  
>  void dss_mgr_set_timings(struct omap_dss_device *dssdev,
>  			 const struct videomode *vm)
>  {
> -	dss_mgr_ops->set_timings(dssdev->dispc_channel, vm);
> +	dss_mgr_ops->set_timings(&dssdev->dss->drm, dssdev->dispc_channel, vm);
>  }
>  
>  void dss_mgr_set_lcd_config(struct omap_dss_device *dssdev,
>  		const struct dss_lcd_mgr_config *config)
>  {
> -	dss_mgr_ops->set_lcd_config(dssdev->dispc_channel, config);
> +	dss_mgr_ops->set_lcd_config(&dssdev->dss->drm,
> +				    dssdev->dispc_channel, config);
>  }
>  
>  int dss_mgr_enable(struct omap_dss_device *dssdev)
>  {
> -	return dss_mgr_ops->enable(dssdev->dispc_channel);
> +	return dss_mgr_ops->enable(&dssdev->dss->drm, dssdev->dispc_channel);
>  }
>  
>  void dss_mgr_disable(struct omap_dss_device *dssdev)
>  {
> -	dss_mgr_ops->disable(dssdev->dispc_channel);
> +	dss_mgr_ops->disable(&dssdev->dss->drm, dssdev->dispc_channel);
>  }
>  
>  void dss_mgr_start_update(struct omap_dss_device *dssdev)
>  {
> -	dss_mgr_ops->start_update(dssdev->dispc_channel);
> +	dss_mgr_ops->start_update(&dssdev->dss->drm, dssdev->dispc_channel);
>  }
>  
>  int dss_mgr_register_framedone_handler(struct omap_dss_device *dssdev,
>  		void (*handler)(void *), void *data)
>  {
> -	return dss_mgr_ops->register_framedone_handler(dssdev->dispc_channel,
> +	return dss_mgr_ops->register_framedone_handler(&dssdev->dss->drm,
> +						       dssdev->dispc_channel,
>  						       handler, data);
>  }
>  
>  void dss_mgr_unregister_framedone_handler(struct omap_dss_device *dssdev,
>  		void (*handler)(void *), void *data)
>  {
> -	dss_mgr_ops->unregister_framedone_handler(dssdev->dispc_channel,
> +	dss_mgr_ops->unregister_framedone_handler(&dssdev->dss->drm,
> +						  dssdev->dispc_channel,
>  						  handler, data);
>  }
> diff --git a/drivers/gpu/drm/omapdrm/dss/sdi.c b/drivers/gpu/drm/omapdrm/dss/sdi.c
> index 681a3653dd8c..c41bf0d7dd18 100644
> --- a/drivers/gpu/drm/omapdrm/dss/sdi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/sdi.c
> @@ -332,6 +332,7 @@ static void sdi_init_output(struct sdi_device *sdi)
>  	struct omap_dss_device *out = &sdi->output;
>  
>  	out->dev = &sdi->pdev->dev;
> +	out->dss = sdi->dss;
>  	out->id = OMAP_DSS_OUTPUT_SDI;
>  	out->output_type = OMAP_DISPLAY_TYPE_SDI;
>  	out->name = "sdi.0";
> diff --git a/drivers/gpu/drm/omapdrm/dss/venc.c b/drivers/gpu/drm/omapdrm/dss/venc.c
> index d82645e84db7..f120d2910d0d 100644
> --- a/drivers/gpu/drm/omapdrm/dss/venc.c
> +++ b/drivers/gpu/drm/omapdrm/dss/venc.c
> @@ -821,6 +821,7 @@ static void venc_init_output(struct venc_device *venc)
>  	struct omap_dss_device *out = &venc->output;
>  
>  	out->dev = &venc->pdev->dev;
> +	out->dss = venc->dss;
>  	out->id = OMAP_DSS_OUTPUT_VENC;
>  	out->output_type = OMAP_DISPLAY_TYPE_VENC;
>  	out->name = "venc.0";
> diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
> index f78eac4a8b34..90a61a8199b4 100644
> --- a/drivers/gpu/drm/omapdrm/omap_crtc.c
> +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
> @@ -114,7 +114,8 @@ static struct omap_crtc *omap_crtcs[8];
>  static struct omap_dss_device *omap_crtc_output[8];
>  
>  /* we can probably ignore these until we support command-mode panels: */
> -static int omap_crtc_dss_connect(enum omap_channel channel,
> +static int omap_crtc_dss_connect(struct omap_drm_private *priv,
> +		enum omap_channel channel,
>  		struct omap_dss_device *dst)
>  {
>  	const struct dispc_ops *dispc_ops = dispc_get_ops();
> @@ -131,14 +132,16 @@ static int omap_crtc_dss_connect(enum omap_channel channel,
>  	return 0;
>  }
>  
> -static void omap_crtc_dss_disconnect(enum omap_channel channel,
> +static void omap_crtc_dss_disconnect(struct omap_drm_private *priv,
> +		enum omap_channel channel,
>  		struct omap_dss_device *dst)
>  {
>  	omap_crtc_output[channel] = NULL;
>  	dst->dispc_channel_connected = false;
>  }
>  
> -static void omap_crtc_dss_start_update(enum omap_channel channel)
> +static void omap_crtc_dss_start_update(struct omap_drm_private *priv,
> +				       enum omap_channel channel)
>  {
>  }
>  
> @@ -208,10 +211,10 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable)
>  }
>  
>  
> -static int omap_crtc_dss_enable(enum omap_channel channel)
> +static int omap_crtc_dss_enable(struct omap_drm_private *priv,
> +				enum omap_channel channel)
>  {
>  	struct omap_crtc *omap_crtc = omap_crtcs[channel];
> -	struct omap_drm_private *priv = omap_crtc->base.dev->dev_private;
>  
>  	priv->dispc_ops->mgr_set_timings(omap_crtc->channel, &omap_crtc->vm);
>  	omap_crtc_set_enabled(&omap_crtc->base, true);
> @@ -219,14 +222,16 @@ static int omap_crtc_dss_enable(enum omap_channel channel)
>  	return 0;
>  }
>  
> -static void omap_crtc_dss_disable(enum omap_channel channel)
> +static void omap_crtc_dss_disable(struct omap_drm_private *priv,
> +				  enum omap_channel channel)
>  {
>  	struct omap_crtc *omap_crtc = omap_crtcs[channel];
>  
>  	omap_crtc_set_enabled(&omap_crtc->base, false);
>  }
>  
> -static void omap_crtc_dss_set_timings(enum omap_channel channel,
> +static void omap_crtc_dss_set_timings(struct omap_drm_private *priv,
> +		enum omap_channel channel,
>  		const struct videomode *vm)
>  {
>  	struct omap_crtc *omap_crtc = omap_crtcs[channel];
> @@ -234,25 +239,25 @@ static void omap_crtc_dss_set_timings(enum omap_channel channel,
>  	omap_crtc->vm = *vm;
>  }
>  
> -static void omap_crtc_dss_set_lcd_config(enum omap_channel channel,
> +static void omap_crtc_dss_set_lcd_config(struct omap_drm_private *priv,
> +		enum omap_channel channel,
>  		const struct dss_lcd_mgr_config *config)
>  {
>  	struct omap_crtc *omap_crtc = omap_crtcs[channel];
> -	struct omap_drm_private *priv = omap_crtc->base.dev->dev_private;
>  
>  	DBG("%s", omap_crtc->name);
>  	priv->dispc_ops->mgr_set_lcd_config(omap_crtc->channel, config);
>  }
>  
>  static int omap_crtc_dss_register_framedone(
> -		enum omap_channel channel,
> +		struct omap_drm_private *priv, enum omap_channel channel,
>  		void (*handler)(void *), void *data)
>  {
>  	return 0;
>  }
>  
>  static void omap_crtc_dss_unregister_framedone(
> -		enum omap_channel channel,
> +		struct omap_drm_private *priv, enum omap_channel channel,
>  		void (*handler)(void *), void *data)
>  {
>  }
> -- 
> Regards,
> 
> Laurent Pinchart
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

Patch

diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c b/drivers/gpu/drm/omapdrm/dss/dpi.c
index 3894e53ff58d..ae43ba81eb96 100644
--- a/drivers/gpu/drm/omapdrm/dss/dpi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dpi.c
@@ -727,6 +727,7 @@  static void dpi_init_output_port(struct dpi_data *dpi, struct device_node *port)
 	}
 
 	out->dev = &dpi->pdev->dev;
+	out->dss = dpi->dss;
 	out->id = OMAP_DSS_OUTPUT_DPI;
 	out->output_type = OMAP_DISPLAY_TYPE_DPI;
 	out->dispc_channel = dpi_get_channel(dpi, port_num);
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index 512625ed03e2..eafea72998dd 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -5044,6 +5044,7 @@  static void dsi_init_output(struct dsi_data *dsi)
 	struct omap_dss_device *out = &dsi->output;
 
 	out->dev = dsi->dev;
+	out->dss = dsi->dss;
 	out->id = dsi->module_id == 0 ?
 			OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2;
 
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c
index 8fec9bf6f06f..0e8c70591308 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.c
+++ b/drivers/gpu/drm/omapdrm/dss/dss.c
@@ -49,9 +49,6 @@ 
 
 #include "omapdss.h"
 #include "dss.h"
-#include "../omap_drv.h"
-
-#define DSS_SZ_REGS			SZ_512
 
 struct dss_reg {
 	u16 idx;
@@ -96,40 +93,6 @@  struct dss_features {
 	bool has_lcd_clk_src;
 };
 
-struct dss_device {
-	struct platform_device *pdev;
-	struct omap_drm_private drm;
-
-	void __iomem    *base;
-	struct regmap	*syscon_pll_ctrl;
-	u32		syscon_pll_ctrl_offset;
-
-	struct clk	*parent_clk;
-	struct clk	*dss_clk;
-	unsigned long	dss_clk_rate;
-
-	unsigned long	cache_req_pck;
-	unsigned long	cache_prate;
-	struct dispc_clock_info cache_dispc_cinfo;
-
-	enum dss_clk_source dsi_clk_source[MAX_NUM_DSI];
-	enum dss_clk_source dispc_clk_source;
-	enum dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS];
-
-	bool		ctx_valid;
-	u32		ctx[DSS_SZ_REGS / sizeof(u32)];
-
-	const struct dss_features *feat;
-
-	struct {
-		struct dss_debugfs_entry *clk;
-		struct dss_debugfs_entry *dss;
-	} debugfs;
-
-	struct dss_pll	*video1_pll;
-	struct dss_pll	*video2_pll;
-};
-
 static const char * const dss_generic_clk_source_names[] = {
 	[DSS_CLK_SRC_FCK]	= "FCK",
 	[DSS_CLK_SRC_PLL1_1]	= "PLL1:1",
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.h b/drivers/gpu/drm/omapdrm/dss/dss.h
index 5d6f8afca49d..cda2cbd888f0 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.h
+++ b/drivers/gpu/drm/omapdrm/dss/dss.h
@@ -26,6 +26,7 @@ 
 #include <linux/interrupt.h>
 
 #include "omapdss.h"
+#include "../omap_drv.h"
 
 struct dentry;
 struct dss_debugfs_entry;
@@ -241,6 +242,42 @@  struct dss_lcd_mgr_config {
 	int lcden_sig_polarity;
 };
 
+#define DSS_SZ_REGS			SZ_512
+
+struct dss_device {
+	struct platform_device *pdev;
+	struct omap_drm_private drm;
+
+	void __iomem    *base;
+	struct regmap	*syscon_pll_ctrl;
+	u32		syscon_pll_ctrl_offset;
+
+	struct clk	*parent_clk;
+	struct clk	*dss_clk;
+	unsigned long	dss_clk_rate;
+
+	unsigned long	cache_req_pck;
+	unsigned long	cache_prate;
+	struct dispc_clock_info cache_dispc_cinfo;
+
+	enum dss_clk_source dsi_clk_source[MAX_NUM_DSI];
+	enum dss_clk_source dispc_clk_source;
+	enum dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS];
+
+	bool		ctx_valid;
+	u32		ctx[DSS_SZ_REGS / sizeof(u32)];
+
+	const struct dss_features *feat;
+
+	struct {
+		struct dss_debugfs_entry *clk;
+		struct dss_debugfs_entry *dss;
+	} debugfs;
+
+	struct dss_pll	*video1_pll;
+	struct dss_pll	*video2_pll;
+};
+
 /* core */
 static inline int dss_set_min_bus_tput(struct device *dev, unsigned long tput)
 {
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
index 56de3c75b0a0..501813f03466 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
@@ -566,6 +566,7 @@  static void hdmi_init_output(struct omap_hdmi *hdmi)
 	struct omap_dss_device *out = &hdmi->output;
 
 	out->dev = &hdmi->pdev->dev;
+	out->dss = hdmi->dss;
 	out->id = OMAP_DSS_OUTPUT_HDMI;
 	out->output_type = OMAP_DISPLAY_TYPE_HDMI;
 	out->name = "hdmi->0";
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
index 1e839af800e7..44954bdea6ce 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
@@ -558,6 +558,7 @@  static void hdmi_init_output(struct omap_hdmi *hdmi)
 	struct omap_dss_device *out = &hdmi->output;
 
 	out->dev = &hdmi->pdev->dev;
+	out->dss = hdmi->dss;
 	out->id = OMAP_DSS_OUTPUT_HDMI;
 	out->output_type = OMAP_DISPLAY_TYPE_HDMI;
 	out->name = "hdmi->0";
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 32c5944b0bea..76ce94376454 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -59,6 +59,7 @@ 
 #define DISPC_IRQ_ACBIAS_COUNT_STAT3	(1 << 29)
 #define DISPC_IRQ_FRAMEDONE3		(1 << 30)
 
+struct omap_drm_private;
 struct omap_dss_device;
 struct dss_lcd_mgr_config;
 struct snd_aes_iec958;
@@ -471,6 +472,7 @@  struct omapdss_dsi_ops {
 struct omap_dss_device {
 	struct kobject kobj;
 	struct device *dev;
+	struct dss_device *dss; /* valid for DSS outputs only */
 
 	struct module *owner;
 
@@ -632,21 +634,30 @@  struct device_node *dss_of_port_get_parent_device(struct device_node *port);
 u32 dss_of_port_get_port_number(struct device_node *port);
 
 struct dss_mgr_ops {
-	int (*connect)(enum omap_channel channel,
-		struct omap_dss_device *dst);
-	void (*disconnect)(enum omap_channel channel,
-		struct omap_dss_device *dst);
-
-	void (*start_update)(enum omap_channel channel);
-	int (*enable)(enum omap_channel channel);
-	void (*disable)(enum omap_channel channel);
-	void (*set_timings)(enum omap_channel channel,
-			const struct videomode *vm);
-	void (*set_lcd_config)(enum omap_channel channel,
-			const struct dss_lcd_mgr_config *config);
-	int (*register_framedone_handler)(enum omap_channel channel,
+	int (*connect)(struct omap_drm_private *priv,
+		       enum omap_channel channel,
+		       struct omap_dss_device *dst);
+	void (*disconnect)(struct omap_drm_private *priv,
+			   enum omap_channel channel,
+			   struct omap_dss_device *dst);
+
+	void (*start_update)(struct omap_drm_private *priv,
+			     enum omap_channel channel);
+	int (*enable)(struct omap_drm_private *priv,
+		      enum omap_channel channel);
+	void (*disable)(struct omap_drm_private *priv,
+			enum omap_channel channel);
+	void (*set_timings)(struct omap_drm_private *priv,
+			    enum omap_channel channel,
+			    const struct videomode *vm);
+	void (*set_lcd_config)(struct omap_drm_private *priv,
+			       enum omap_channel channel,
+			       const struct dss_lcd_mgr_config *config);
+	int (*register_framedone_handler)(struct omap_drm_private *priv,
+			enum omap_channel channel,
 			void (*handler)(void *), void *data);
-	void (*unregister_framedone_handler)(enum omap_channel channel,
+	void (*unregister_framedone_handler)(struct omap_drm_private *priv,
+			enum omap_channel channel,
 			void (*handler)(void *), void *data);
 };
 
diff --git a/drivers/gpu/drm/omapdrm/dss/output.c b/drivers/gpu/drm/omapdrm/dss/output.c
index 0573b5099f8f..4a6ccad7e970 100644
--- a/drivers/gpu/drm/omapdrm/dss/output.c
+++ b/drivers/gpu/drm/omapdrm/dss/output.c
@@ -21,6 +21,7 @@ 
 #include <linux/slab.h>
 #include <linux/of.h>
 
+#include "dss.h"
 #include "omapdss.h"
 
 static LIST_HEAD(output_list);
@@ -186,52 +187,56 @@  EXPORT_SYMBOL(dss_uninstall_mgr_ops);
 
 int dss_mgr_connect(struct omap_dss_device *dssdev, struct omap_dss_device *dst)
 {
-	return dss_mgr_ops->connect(dssdev->dispc_channel, dst);
+	return dss_mgr_ops->connect(&dssdev->dss->drm,
+				    dssdev->dispc_channel, dst);
 }
 
 void dss_mgr_disconnect(struct omap_dss_device *dssdev,
 			struct omap_dss_device *dst)
 {
-	dss_mgr_ops->disconnect(dssdev->dispc_channel, dst);
+	dss_mgr_ops->disconnect(&dssdev->dss->drm, dssdev->dispc_channel, dst);
 }
 
 void dss_mgr_set_timings(struct omap_dss_device *dssdev,
 			 const struct videomode *vm)
 {
-	dss_mgr_ops->set_timings(dssdev->dispc_channel, vm);
+	dss_mgr_ops->set_timings(&dssdev->dss->drm, dssdev->dispc_channel, vm);
 }
 
 void dss_mgr_set_lcd_config(struct omap_dss_device *dssdev,
 		const struct dss_lcd_mgr_config *config)
 {
-	dss_mgr_ops->set_lcd_config(dssdev->dispc_channel, config);
+	dss_mgr_ops->set_lcd_config(&dssdev->dss->drm,
+				    dssdev->dispc_channel, config);
 }
 
 int dss_mgr_enable(struct omap_dss_device *dssdev)
 {
-	return dss_mgr_ops->enable(dssdev->dispc_channel);
+	return dss_mgr_ops->enable(&dssdev->dss->drm, dssdev->dispc_channel);
 }
 
 void dss_mgr_disable(struct omap_dss_device *dssdev)
 {
-	dss_mgr_ops->disable(dssdev->dispc_channel);
+	dss_mgr_ops->disable(&dssdev->dss->drm, dssdev->dispc_channel);
 }
 
 void dss_mgr_start_update(struct omap_dss_device *dssdev)
 {
-	dss_mgr_ops->start_update(dssdev->dispc_channel);
+	dss_mgr_ops->start_update(&dssdev->dss->drm, dssdev->dispc_channel);
 }
 
 int dss_mgr_register_framedone_handler(struct omap_dss_device *dssdev,
 		void (*handler)(void *), void *data)
 {
-	return dss_mgr_ops->register_framedone_handler(dssdev->dispc_channel,
+	return dss_mgr_ops->register_framedone_handler(&dssdev->dss->drm,
+						       dssdev->dispc_channel,
 						       handler, data);
 }
 
 void dss_mgr_unregister_framedone_handler(struct omap_dss_device *dssdev,
 		void (*handler)(void *), void *data)
 {
-	dss_mgr_ops->unregister_framedone_handler(dssdev->dispc_channel,
+	dss_mgr_ops->unregister_framedone_handler(&dssdev->dss->drm,
+						  dssdev->dispc_channel,
 						  handler, data);
 }
diff --git a/drivers/gpu/drm/omapdrm/dss/sdi.c b/drivers/gpu/drm/omapdrm/dss/sdi.c
index 681a3653dd8c..c41bf0d7dd18 100644
--- a/drivers/gpu/drm/omapdrm/dss/sdi.c
+++ b/drivers/gpu/drm/omapdrm/dss/sdi.c
@@ -332,6 +332,7 @@  static void sdi_init_output(struct sdi_device *sdi)
 	struct omap_dss_device *out = &sdi->output;
 
 	out->dev = &sdi->pdev->dev;
+	out->dss = sdi->dss;
 	out->id = OMAP_DSS_OUTPUT_SDI;
 	out->output_type = OMAP_DISPLAY_TYPE_SDI;
 	out->name = "sdi.0";
diff --git a/drivers/gpu/drm/omapdrm/dss/venc.c b/drivers/gpu/drm/omapdrm/dss/venc.c
index d82645e84db7..f120d2910d0d 100644
--- a/drivers/gpu/drm/omapdrm/dss/venc.c
+++ b/drivers/gpu/drm/omapdrm/dss/venc.c
@@ -821,6 +821,7 @@  static void venc_init_output(struct venc_device *venc)
 	struct omap_dss_device *out = &venc->output;
 
 	out->dev = &venc->pdev->dev;
+	out->dss = venc->dss;
 	out->id = OMAP_DSS_OUTPUT_VENC;
 	out->output_type = OMAP_DISPLAY_TYPE_VENC;
 	out->name = "venc.0";
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index f78eac4a8b34..90a61a8199b4 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -114,7 +114,8 @@  static struct omap_crtc *omap_crtcs[8];
 static struct omap_dss_device *omap_crtc_output[8];
 
 /* we can probably ignore these until we support command-mode panels: */
-static int omap_crtc_dss_connect(enum omap_channel channel,
+static int omap_crtc_dss_connect(struct omap_drm_private *priv,
+		enum omap_channel channel,
 		struct omap_dss_device *dst)
 {
 	const struct dispc_ops *dispc_ops = dispc_get_ops();
@@ -131,14 +132,16 @@  static int omap_crtc_dss_connect(enum omap_channel channel,
 	return 0;
 }
 
-static void omap_crtc_dss_disconnect(enum omap_channel channel,
+static void omap_crtc_dss_disconnect(struct omap_drm_private *priv,
+		enum omap_channel channel,
 		struct omap_dss_device *dst)
 {
 	omap_crtc_output[channel] = NULL;
 	dst->dispc_channel_connected = false;
 }
 
-static void omap_crtc_dss_start_update(enum omap_channel channel)
+static void omap_crtc_dss_start_update(struct omap_drm_private *priv,
+				       enum omap_channel channel)
 {
 }
 
@@ -208,10 +211,10 @@  static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable)
 }
 
 
-static int omap_crtc_dss_enable(enum omap_channel channel)
+static int omap_crtc_dss_enable(struct omap_drm_private *priv,
+				enum omap_channel channel)
 {
 	struct omap_crtc *omap_crtc = omap_crtcs[channel];
-	struct omap_drm_private *priv = omap_crtc->base.dev->dev_private;
 
 	priv->dispc_ops->mgr_set_timings(omap_crtc->channel, &omap_crtc->vm);
 	omap_crtc_set_enabled(&omap_crtc->base, true);
@@ -219,14 +222,16 @@  static int omap_crtc_dss_enable(enum omap_channel channel)
 	return 0;
 }
 
-static void omap_crtc_dss_disable(enum omap_channel channel)
+static void omap_crtc_dss_disable(struct omap_drm_private *priv,
+				  enum omap_channel channel)
 {
 	struct omap_crtc *omap_crtc = omap_crtcs[channel];
 
 	omap_crtc_set_enabled(&omap_crtc->base, false);
 }
 
-static void omap_crtc_dss_set_timings(enum omap_channel channel,
+static void omap_crtc_dss_set_timings(struct omap_drm_private *priv,
+		enum omap_channel channel,
 		const struct videomode *vm)
 {
 	struct omap_crtc *omap_crtc = omap_crtcs[channel];
@@ -234,25 +239,25 @@  static void omap_crtc_dss_set_timings(enum omap_channel channel,
 	omap_crtc->vm = *vm;
 }
 
-static void omap_crtc_dss_set_lcd_config(enum omap_channel channel,
+static void omap_crtc_dss_set_lcd_config(struct omap_drm_private *priv,
+		enum omap_channel channel,
 		const struct dss_lcd_mgr_config *config)
 {
 	struct omap_crtc *omap_crtc = omap_crtcs[channel];
-	struct omap_drm_private *priv = omap_crtc->base.dev->dev_private;
 
 	DBG("%s", omap_crtc->name);
 	priv->dispc_ops->mgr_set_lcd_config(omap_crtc->channel, config);
 }
 
 static int omap_crtc_dss_register_framedone(
-		enum omap_channel channel,
+		struct omap_drm_private *priv, enum omap_channel channel,
 		void (*handler)(void *), void *data)
 {
 	return 0;
 }
 
 static void omap_crtc_dss_unregister_framedone(
-		enum omap_channel channel,
+		struct omap_drm_private *priv, enum omap_channel channel,
 		void (*handler)(void *), void *data)
 {
 }