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@xxxxxxxxxxxxxxxx> > --- > 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 &= ~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@xxxxxx> Tomi
Attachment:
signature.asc
Description: OpenPGP digital signature
_______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel