[PATCH v2 10/28] drm: omapdrm: dsi: Handle pin muxing internally

Tomi Valkeinen tomi.valkeinen at ti.com
Tue May 9 09:37:36 UTC 2017


On 08/05/17 14:32, Laurent Pinchart wrote:
> Don't rely on callback functions provided by the platform, but access
> the syscon internally to mux the DSI pins.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> ---
>  drivers/gpu/drm/omapdrm/dss/core.c | 20 ----------
>  drivers/gpu/drm/omapdrm/dss/dsi.c  | 82 ++++++++++++++++++++++++++++++++++++--
>  drivers/gpu/drm/omapdrm/dss/dss.h  |  2 -
>  3 files changed, 79 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/core.c b/drivers/gpu/drm/omapdrm/dss/core.c
> index 35def6fd6acd..524ecdd138f4 100644
> --- a/drivers/gpu/drm/omapdrm/dss/core.c
> +++ b/drivers/gpu/drm/omapdrm/dss/core.c
> @@ -50,26 +50,6 @@ enum omapdss_version omapdss_get_version(void)
>  }
>  EXPORT_SYMBOL(omapdss_get_version);
>  
> -int dss_dsi_enable_pads(int dsi_id, unsigned lane_mask)
> -{
> -	struct omap_dss_board_info *board_data = core.pdev->dev.platform_data;
> -
> -	if (!board_data->dsi_enable_pads)
> -		return -ENOENT;
> -
> -	return board_data->dsi_enable_pads(dsi_id, lane_mask);
> -}
> -
> -void dss_dsi_disable_pads(int dsi_id, unsigned lane_mask)
> -{
> -	struct omap_dss_board_info *board_data = core.pdev->dev.platform_data;
> -
> -	if (!board_data->dsi_disable_pads)
> -		return;
> -
> -	return board_data->dsi_disable_pads(dsi_id, lane_mask);
> -}
> -
>  int dss_set_min_bus_tput(struct device *dev, unsigned long tput)
>  {
>  	struct omap_dss_board_info *pdata = core.pdev->dev.platform_data;
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
> index 400f903d8197..d86a1ca6da00 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> @@ -20,6 +20,8 @@
>  #define DSS_SUBSYS_NAME "DSI"
>  
>  #include <linux/kernel.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/regmap.h>
>  #include <linux/io.h>
>  #include <linux/clk.h>
>  #include <linux/device.h>
> @@ -329,6 +331,7 @@ struct dsi_data {
>  	bool is_enabled;
>  
>  	struct clk *dss_clk;
> +	struct regmap *syscon;
>  
>  	struct dispc_clock_info user_dispc_cinfo;
>  	struct dss_pll_clock_info user_dsi_cinfo;
> @@ -2073,6 +2076,64 @@ static unsigned dsi_get_lane_mask(struct platform_device *dsidev)
>  	return mask;
>  }
>  
> +/* OMAP4 CONTROL_DSIPHY */
> +#define OMAP4_DSIPHY_SYSCON_OFFSET			0x78
> +
> +#define OMAP4_DSI2_LANEENABLE_SHIFT			29
> +#define OMAP4_DSI2_LANEENABLE_MASK			(0x7 << 29)
> +#define OMAP4_DSI1_LANEENABLE_SHIFT			24
> +#define OMAP4_DSI1_LANEENABLE_MASK			(0x1f << 24)
> +#define OMAP4_DSI1_PIPD_SHIFT				19
> +#define OMAP4_DSI1_PIPD_MASK				(0x1f << 19)
> +#define OMAP4_DSI2_PIPD_SHIFT				14
> +#define OMAP4_DSI2_PIPD_MASK				(0x1f << 14)
> +
> +static int dsi_omap4_mux_pads(struct dsi_data *dsi, unsigned int lanes)
> +{
> +	u32 enable_mask, enable_shift;
> +	u32 pipd_mask, pipd_shift;
> +	u32 reg;
> +
> +	if (!dsi->syscon)
> +		return 0;
> +
> +	if (dsi->module_id == 0) {
> +		enable_mask = OMAP4_DSI1_LANEENABLE_MASK;
> +		enable_shift = OMAP4_DSI1_LANEENABLE_SHIFT;
> +		pipd_mask = OMAP4_DSI1_PIPD_MASK;
> +		pipd_shift = OMAP4_DSI1_PIPD_SHIFT;
> +	} else if (dsi->module_id == 1) {
> +		enable_mask = OMAP4_DSI2_LANEENABLE_MASK;
> +		enable_shift = OMAP4_DSI2_LANEENABLE_SHIFT;
> +		pipd_mask = OMAP4_DSI2_PIPD_MASK;
> +		pipd_shift = OMAP4_DSI2_PIPD_SHIFT;
> +	} else {
> +		return -ENODEV;
> +	}
> +
> +	regmap_read(dsi->syscon, OMAP4_DSIPHY_SYSCON_OFFSET, &reg);
> +
> +	reg &= ~enable_mask;
> +	reg &= ~pipd_mask;
> +
> +	reg |= (lanes << enable_shift) & enable_mask;
> +	reg |= (lanes << pipd_shift) & pipd_mask;
> +
> +	regmap_write(dsi->syscon, OMAP4_DSIPHY_SYSCON_OFFSET, reg);
> +
> +	return 0;
> +}
> +
> +static int dsi_enable_pads(struct dsi_data *dsi, unsigned int lane_mask)
> +{
> +	return dsi_omap4_mux_pads(dsi, lane_mask);
> +}
> +
> +static void dsi_disable_pads(struct dsi_data *dsi)
> +{
> +	dsi_omap4_mux_pads(dsi, 0);
> +}
> +
>  static int dsi_cio_init(struct platform_device *dsidev)
>  {
>  	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
> @@ -2081,7 +2142,7 @@ static int dsi_cio_init(struct platform_device *dsidev)
>  
>  	DSSDBG("DSI CIO init starts");
>  
> -	r = dss_dsi_enable_pads(dsi->module_id, dsi_get_lane_mask(dsidev));
> +	r = dsi_enable_pads(dsi, dsi_get_lane_mask(dsidev));
>  	if (r)
>  		return r;
>  
> @@ -2191,7 +2252,7 @@ static int dsi_cio_init(struct platform_device *dsidev)
>  		dsi_cio_disable_lane_override(dsidev);
>  err_scp_clk_dom:
>  	dsi_disable_scp_clk(dsidev);
> -	dss_dsi_disable_pads(dsi->module_id, dsi_get_lane_mask(dsidev));
> +	dsi_disable_pads(dsi);
>  	return r;
>  }
>  
> @@ -2204,7 +2265,7 @@ static void dsi_cio_uninit(struct platform_device *dsidev)
>  
>  	dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_OFF);
>  	dsi_disable_scp_clk(dsidev);
> -	dss_dsi_disable_pads(dsi->module_id, dsi_get_lane_mask(dsidev));
> +	dsi_disable_pads(dsi);
>  }
>  
>  static void dsi_config_tx_fifo(struct platform_device *dsidev,
> @@ -5332,6 +5393,21 @@ static int dsi_bind(struct device *dev, struct device *master, void *data)
>  
>  	dsi->module_id = d->id;
>  
> +	if (dsi->data->type == DSI_TYPE_OMAP4) {
> +		struct device_node *np;
> +
> +		/*
> +		 * The OMAP4 display DT bindings don't reference the padconf
> +		 * syscon. Our only option to retrieve it is to find it by name.
> +		 */

We could also do DT modifications at early boot phase (we do that
already for a few things for tilcdc and omapdss), and then have the
driver require the reference to padconf.

But I think this is fine too.

Reviewed-by: Tomi Valkeinen <tomi.valkeinen at ti.com>

 Tomi

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <https://lists.freedesktop.org/archives/dri-devel/attachments/20170509/404d6f25/attachment-0001.sig>


More information about the dri-devel mailing list