[1/4] drm: bridge: dw_mipi_dsi: access registers via a regmap
diff mbox series

Message ID 20191031142633.12460-2-adrian.ratiu@collabora.com
State New
Headers show
Series
  • Genericize DW MIPI DSI bridge and add i.MX 6 driver
Related show

Commit Message

Adrian Ratiu Oct. 31, 2019, 2:26 p.m. UTC
Convert the common bridge code and the two rockchip & stm drivers
which currently use it to the regmap API in anticipation for further
changes to make it more generic and add older DSI host controller
support as found on i.mx6 based devices.

No functional changes other than requiring the platform drivers to
provide a regmap via their plat_data. Going further each platform
driver can also add its own regmap configuration like for maximum
write offsets, r/w callbacks or different register layouts.

Suggested-by: Boris Brezillon <boris.brezillon@collabora.com>
Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
---
 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 189 +++++++++---------
 .../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c   |  36 +++-
 drivers/gpu/drm/stm/dw_mipi_dsi-stm.c         |  44 ++--
 include/drm/bridge/dw_mipi_dsi.h              |   2 +-
 4 files changed, 155 insertions(+), 116 deletions(-)

Comments

Neil Armstrong Nov. 4, 2019, 9:15 a.m. UTC | #1
On 31/10/2019 15:26, Adrian Ratiu wrote:
> Convert the common bridge code and the two rockchip & stm drivers
> which currently use it to the regmap API in anticipation for further
> changes to make it more generic and add older DSI host controller
> support as found on i.mx6 based devices.
> 
> No functional changes other than requiring the platform drivers to
> provide a regmap via their plat_data. Going further each platform
> driver can also add its own regmap configuration like for maximum
> write offsets, r/w callbacks or different register layouts.
> 
> Suggested-by: Boris Brezillon <boris.brezillon@collabora.com>
> Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 189 +++++++++---------
>  .../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c   |  36 +++-
>  drivers/gpu/drm/stm/dw_mipi_dsi-stm.c         |  44 ++--
>  include/drm/bridge/dw_mipi_dsi.h              |   2 +-
>  4 files changed, 155 insertions(+), 116 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> index b6e793bb653c..4ef3e9038cc2 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> @@ -15,6 +15,7 @@
>  #include <linux/module.h>
>  #include <linux/of_device.h>
>  #include <linux/pm_runtime.h>
> +#include <linux/regmap.h>
>  #include <linux/reset.h>
>  
>  #include <video/mipi_display.h>
> @@ -226,7 +227,7 @@ struct dw_mipi_dsi {
>  	struct mipi_dsi_host dsi_host;
>  	struct drm_bridge *panel_bridge;
>  	struct device *dev;
> -	void __iomem *base;
> +	struct regmap *regs;
>  
>  	struct clk *pclk;
>  
> @@ -280,16 +281,6 @@ static inline struct dw_mipi_dsi *bridge_to_dsi(struct drm_bridge *bridge)
>  	return container_of(bridge, struct dw_mipi_dsi, bridge);
>  }
>  
> -static inline void dsi_write(struct dw_mipi_dsi *dsi, u32 reg, u32 val)
> -{
> -	writel(val, dsi->base + reg);
> -}
> -
> -static inline u32 dsi_read(struct dw_mipi_dsi *dsi, u32 reg)
> -{
> -	return readl(dsi->base + reg);
> -}
> -
>  static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host,
>  				   struct mipi_dsi_device *device)
>  {
> @@ -366,29 +357,29 @@ static void dw_mipi_message_config(struct dw_mipi_dsi *dsi,
>  	if (lpm)
>  		val |= CMD_MODE_ALL_LP;
>  
> -	dsi_write(dsi, DSI_LPCLK_CTRL, lpm ? 0 : PHY_TXREQUESTCLKHS);
> -	dsi_write(dsi, DSI_CMD_MODE_CFG, val);
> +	regmap_write(dsi->regs, DSI_LPCLK_CTRL, lpm ? 0 : PHY_TXREQUESTCLKHS);
> +	regmap_write(dsi->regs, DSI_CMD_MODE_CFG, val);
>  }
>  
>  static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)
>  {
>  	int ret;
> -	u32 val, mask;
> +	u32 val = 0, mask;
>  
> -	ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
> -				 val, !(val & GEN_CMD_FULL), 1000,
> -				 CMD_PKT_STATUS_TIMEOUT_US);
> +	ret = regmap_read_poll_timeout(dsi->regs, DSI_CMD_PKT_STATUS,
> +				       val, !(val & GEN_CMD_FULL), 1000,
> +				       CMD_PKT_STATUS_TIMEOUT_US);
>  	if (ret) {
>  		dev_err(dsi->dev, "failed to get available command FIFO\n");
>  		return ret;
>  	}
>  
> -	dsi_write(dsi, DSI_GEN_HDR, hdr_val);
> +	regmap_write(dsi->regs, DSI_GEN_HDR, hdr_val);
>  
>  	mask = GEN_CMD_EMPTY | GEN_PLD_W_EMPTY;
> -	ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
> -				 val, (val & mask) == mask,
> -				 1000, CMD_PKT_STATUS_TIMEOUT_US);
> +	ret = regmap_read_poll_timeout(dsi->regs, DSI_CMD_PKT_STATUS,
> +				       val, (val & mask) == mask,
> +				       1000, CMD_PKT_STATUS_TIMEOUT_US);
>  	if (ret) {
>  		dev_err(dsi->dev, "failed to write command FIFO\n");
>  		return ret;
> @@ -403,24 +394,26 @@ static int dw_mipi_dsi_write(struct dw_mipi_dsi *dsi,
>  	const u8 *tx_buf = packet->payload;
>  	int len = packet->payload_length, pld_data_bytes = sizeof(u32), ret;
>  	__le32 word;
> -	u32 val;
> +	u32 val = 0;
>  
>  	while (len) {
>  		if (len < pld_data_bytes) {
>  			word = 0;
>  			memcpy(&word, tx_buf, len);
> -			dsi_write(dsi, DSI_GEN_PLD_DATA, le32_to_cpu(word));
> +			regmap_write(dsi->regs, DSI_GEN_PLD_DATA,
> +				     le32_to_cpu(word));
>  			len = 0;
>  		} else {
>  			memcpy(&word, tx_buf, pld_data_bytes);
> -			dsi_write(dsi, DSI_GEN_PLD_DATA, le32_to_cpu(word));
> +			regmap_write(dsi->regs, DSI_GEN_PLD_DATA,
> +				     le32_to_cpu(word));
>  			tx_buf += pld_data_bytes;
>  			len -= pld_data_bytes;
>  		}
>  
> -		ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
> -					 val, !(val & GEN_PLD_W_FULL), 1000,
> -					 CMD_PKT_STATUS_TIMEOUT_US);
> +		ret = regmap_read_poll_timeout(dsi->regs, DSI_CMD_PKT_STATUS,
> +					       val, !(val & GEN_PLD_W_FULL),
> +					       1000, CMD_PKT_STATUS_TIMEOUT_US);
>  		if (ret) {
>  			dev_err(dsi->dev,
>  				"failed to get available write payload FIFO\n");
> @@ -438,12 +431,12 @@ static int dw_mipi_dsi_read(struct dw_mipi_dsi *dsi,
>  {
>  	int i, j, ret, len = msg->rx_len;
>  	u8 *buf = msg->rx_buf;
> -	u32 val;
> +	u32 val = 0;
>  
>  	/* Wait end of the read operation */
> -	ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
> -				 val, !(val & GEN_RD_CMD_BUSY),
> -				 1000, CMD_PKT_STATUS_TIMEOUT_US);
> +	ret = regmap_read_poll_timeout(dsi->regs, DSI_CMD_PKT_STATUS,
> +				       val, !(val & GEN_RD_CMD_BUSY),
> +				       1000, CMD_PKT_STATUS_TIMEOUT_US);
>  	if (ret) {
>  		dev_err(dsi->dev, "Timeout during read operation\n");
>  		return ret;
> @@ -451,15 +444,15 @@ static int dw_mipi_dsi_read(struct dw_mipi_dsi *dsi,
>  
>  	for (i = 0; i < len; i += 4) {
>  		/* Read fifo must not be empty before all bytes are read */
> -		ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
> -					 val, !(val & GEN_PLD_R_EMPTY),
> -					 1000, CMD_PKT_STATUS_TIMEOUT_US);
> +		ret = regmap_read_poll_timeout(dsi->regs, DSI_CMD_PKT_STATUS,
> +					       val, !(val & GEN_PLD_R_EMPTY),
> +					       1000, CMD_PKT_STATUS_TIMEOUT_US);
>  		if (ret) {
>  			dev_err(dsi->dev, "Read payload FIFO is empty\n");
>  			return ret;
>  		}
>  
> -		val = dsi_read(dsi, DSI_GEN_PLD_DATA);
> +		regmap_read(dsi->regs, DSI_GEN_PLD_DATA, &val);
>  		for (j = 0; j < 4 && j + i < len; j++)
>  			buf[i + j] = val >> (8 * j);
>  	}
> @@ -536,29 +529,29 @@ static void dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi)
>  	}
>  #endif /* CONFIG_DEBUG_FS */
>  
> -	dsi_write(dsi, DSI_VID_MODE_CFG, val);
> +	regmap_write(dsi->regs, DSI_VID_MODE_CFG, val);
>  }
>  
>  static void dw_mipi_dsi_set_mode(struct dw_mipi_dsi *dsi,
>  				 unsigned long mode_flags)
>  {
> -	dsi_write(dsi, DSI_PWR_UP, RESET);
> +	regmap_write(dsi->regs, DSI_PWR_UP, RESET);
>  
>  	if (mode_flags & MIPI_DSI_MODE_VIDEO) {
> -		dsi_write(dsi, DSI_MODE_CFG, ENABLE_VIDEO_MODE);
> +		regmap_write(dsi->regs, DSI_MODE_CFG, ENABLE_VIDEO_MODE);
>  		dw_mipi_dsi_video_mode_config(dsi);
> -		dsi_write(dsi, DSI_LPCLK_CTRL, PHY_TXREQUESTCLKHS);
> +		regmap_write(dsi->regs, DSI_LPCLK_CTRL, PHY_TXREQUESTCLKHS);
>  	} else {
> -		dsi_write(dsi, DSI_MODE_CFG, ENABLE_CMD_MODE);
> +		regmap_write(dsi->regs, DSI_MODE_CFG, ENABLE_CMD_MODE);
>  	}
>  
> -	dsi_write(dsi, DSI_PWR_UP, POWERUP);
> +	regmap_write(dsi->regs, DSI_PWR_UP, POWERUP);
>  }
>  
>  static void dw_mipi_dsi_disable(struct dw_mipi_dsi *dsi)
>  {
> -	dsi_write(dsi, DSI_PWR_UP, RESET);
> -	dsi_write(dsi, DSI_PHY_RSTZ, PHY_RSTZ);
> +	regmap_write(dsi->regs, DSI_PWR_UP, RESET);
> +	regmap_write(dsi->regs, DSI_PHY_RSTZ, PHY_RSTZ);
>  }
>  
>  static void dw_mipi_dsi_init(struct dw_mipi_dsi *dsi)
> @@ -573,14 +566,14 @@ static void dw_mipi_dsi_init(struct dw_mipi_dsi *dsi)
>  	 */
>  	u32 esc_clk_division = (dsi->lane_mbps >> 3) / 20 + 1;
>  
> -	dsi_write(dsi, DSI_PWR_UP, RESET);
> +	regmap_write(dsi->regs, DSI_PWR_UP, RESET);
>  
>  	/*
>  	 * TODO dw drv improvements
>  	 * timeout clock division should be computed with the
>  	 * high speed transmission counter timeout and byte lane...
>  	 */
> -	dsi_write(dsi, DSI_CLKMGR_CFG, TO_CLK_DIVISION(10) |
> +	regmap_write(dsi->regs, DSI_CLKMGR_CFG, TO_CLK_DIVISION(10) |
>  		  TX_ESC_CLK_DIVISION(esc_clk_division));
>  }
>  
> @@ -609,22 +602,22 @@ static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi,
>  	if (mode->flags & DRM_MODE_FLAG_NHSYNC)
>  		val |= HSYNC_ACTIVE_LOW;
>  
> -	dsi_write(dsi, DSI_DPI_VCID, DPI_VCID(dsi->channel));
> -	dsi_write(dsi, DSI_DPI_COLOR_CODING, color);
> -	dsi_write(dsi, DSI_DPI_CFG_POL, val);
> +	regmap_write(dsi->regs, DSI_DPI_VCID, DPI_VCID(dsi->channel));
> +	regmap_write(dsi->regs, DSI_DPI_COLOR_CODING, color);
> +	regmap_write(dsi->regs, DSI_DPI_CFG_POL, val);
>  	/*
>  	 * TODO dw drv improvements
>  	 * largest packet sizes during hfp or during vsa/vpb/vfp
>  	 * should be computed according to byte lane, lane number and only
>  	 * if sending lp cmds in high speed is enable (PHY_TXREQUESTCLKHS)
>  	 */
> -	dsi_write(dsi, DSI_DPI_LP_CMD_TIM, OUTVACT_LPCMD_TIME(4)
> +	regmap_write(dsi->regs, DSI_DPI_LP_CMD_TIM, OUTVACT_LPCMD_TIME(4)
>  		  | INVACT_LPCMD_TIME(4));
>  }
>  
>  static void dw_mipi_dsi_packet_handler_config(struct dw_mipi_dsi *dsi)
>  {
> -	dsi_write(dsi, DSI_PCKHDL_CFG, CRC_RX_EN | ECC_RX_EN | BTA_EN);
> +	regmap_write(dsi->regs, DSI_PCKHDL_CFG, CRC_RX_EN | ECC_RX_EN | BTA_EN);
>  }
>  
>  static void dw_mipi_dsi_video_packet_config(struct dw_mipi_dsi *dsi,
> @@ -638,7 +631,7 @@ static void dw_mipi_dsi_video_packet_config(struct dw_mipi_dsi *dsi,
>  	 * non-burst video modes, see dw_mipi_dsi_video_mode_config()...
>  	 */
>  
> -	dsi_write(dsi, DSI_VID_PKT_SIZE,
> +	regmap_write(dsi->regs, DSI_VID_PKT_SIZE,
>  		       dw_mipi_is_dual_mode(dsi) ?
>  				VID_PKT_SIZE(mode->hdisplay / 2) :
>  				VID_PKT_SIZE(mode->hdisplay));
> @@ -651,14 +644,15 @@ static void dw_mipi_dsi_command_mode_config(struct dw_mipi_dsi *dsi)
>  	 * compute high speed transmission counter timeout according
>  	 * to the timeout clock division (TO_CLK_DIVISION) and byte lane...
>  	 */
> -	dsi_write(dsi, DSI_TO_CNT_CFG, HSTX_TO_CNT(1000) | LPRX_TO_CNT(1000));
> +	regmap_write(dsi->regs, DSI_TO_CNT_CFG,
> +		     HSTX_TO_CNT(1000) | LPRX_TO_CNT(1000));
>  	/*
>  	 * TODO dw drv improvements
>  	 * the Bus-Turn-Around Timeout Counter should be computed
>  	 * according to byte lane...
>  	 */
> -	dsi_write(dsi, DSI_BTA_TO_CNT, 0xd00);
> -	dsi_write(dsi, DSI_MODE_CFG, ENABLE_CMD_MODE);
> +	regmap_write(dsi->regs, DSI_BTA_TO_CNT, 0xd00);
> +	regmap_write(dsi->regs, DSI_MODE_CFG, ENABLE_CMD_MODE);
>  }
>  
>  /* Get lane byte clock cycles. */
> @@ -692,13 +686,13 @@ static void dw_mipi_dsi_line_timer_config(struct dw_mipi_dsi *dsi,
>  	 * computations below may be improved...
>  	 */
>  	lbcc = dw_mipi_dsi_get_hcomponent_lbcc(dsi, mode, htotal);
> -	dsi_write(dsi, DSI_VID_HLINE_TIME, lbcc);
> +	regmap_write(dsi->regs, DSI_VID_HLINE_TIME, lbcc);
>  
>  	lbcc = dw_mipi_dsi_get_hcomponent_lbcc(dsi, mode, hsa);
> -	dsi_write(dsi, DSI_VID_HSA_TIME, lbcc);
> +	regmap_write(dsi->regs, DSI_VID_HSA_TIME, lbcc);
>  
>  	lbcc = dw_mipi_dsi_get_hcomponent_lbcc(dsi, mode, hbp);
> -	dsi_write(dsi, DSI_VID_HBP_TIME, lbcc);
> +	regmap_write(dsi->regs, DSI_VID_HBP_TIME, lbcc);
>  }
>  
>  static void dw_mipi_dsi_vertical_timing_config(struct dw_mipi_dsi *dsi,
> @@ -711,10 +705,10 @@ static void dw_mipi_dsi_vertical_timing_config(struct dw_mipi_dsi *dsi,
>  	vfp = mode->vsync_start - mode->vdisplay;
>  	vbp = mode->vtotal - mode->vsync_end;
>  
> -	dsi_write(dsi, DSI_VID_VACTIVE_LINES, vactive);
> -	dsi_write(dsi, DSI_VID_VSA_LINES, vsa);
> -	dsi_write(dsi, DSI_VID_VFP_LINES, vfp);
> -	dsi_write(dsi, DSI_VID_VBP_LINES, vbp);
> +	regmap_write(dsi->regs, DSI_VID_VACTIVE_LINES, vactive);
> +	regmap_write(dsi->regs, DSI_VID_VSA_LINES, vsa);
> +	regmap_write(dsi->regs, DSI_VID_VFP_LINES, vfp);
> +	regmap_write(dsi->regs, DSI_VID_VBP_LINES, vbp);
>  }
>  
>  static void dw_mipi_dsi_dphy_timing_config(struct dw_mipi_dsi *dsi)
> @@ -729,19 +723,24 @@ static void dw_mipi_dsi_dphy_timing_config(struct dw_mipi_dsi *dsi)
>  	 * DSI_CMD_MODE_CFG.MAX_RD_PKT_SIZE_LP (see CMD_MODE_ALL_LP)
>  	 */
>  
> -	hw_version = dsi_read(dsi, DSI_VERSION) & VERSION;
> +	regmap_read(dsi->regs, DSI_VERSION, &hw_version);
> +	hw_version &= VERSION;
>  
>  	if (hw_version >= HWVER_131) {
> -		dsi_write(dsi, DSI_PHY_TMR_CFG, PHY_HS2LP_TIME_V131(0x40) |
> -			  PHY_LP2HS_TIME_V131(0x40));
> -		dsi_write(dsi, DSI_PHY_TMR_RD_CFG, MAX_RD_TIME_V131(10000));
> +		regmap_write(dsi->regs, DSI_PHY_TMR_CFG,
> +			     PHY_HS2LP_TIME_V131(0x40) |
> +			     PHY_LP2HS_TIME_V131(0x40));
> +		regmap_write(dsi->regs, DSI_PHY_TMR_RD_CFG,
> +			     MAX_RD_TIME_V131(10000));
>  	} else {
> -		dsi_write(dsi, DSI_PHY_TMR_CFG, PHY_HS2LP_TIME(0x40) |
> -			  PHY_LP2HS_TIME(0x40) | MAX_RD_TIME(10000));
> +		regmap_write(dsi->regs, DSI_PHY_TMR_CFG,
> +			     PHY_HS2LP_TIME(0x40) |
> +			     PHY_LP2HS_TIME(0x40) |
> +			     MAX_RD_TIME(10000));
>  	}
>  
> -	dsi_write(dsi, DSI_PHY_TMR_LPCLK_CFG, PHY_CLKHS2LP_TIME(0x40)
> -		  | PHY_CLKLP2HS_TIME(0x40));
> +	regmap_write(dsi->regs, DSI_PHY_TMR_LPCLK_CFG,
> +		     PHY_CLKHS2LP_TIME(0x40) | PHY_CLKLP2HS_TIME(0x40));
>  }
>  
>  static void dw_mipi_dsi_dphy_interface_config(struct dw_mipi_dsi *dsi)
> @@ -751,46 +750,49 @@ static void dw_mipi_dsi_dphy_interface_config(struct dw_mipi_dsi *dsi)
>  	 * stop wait time should be the maximum between host dsi
>  	 * and panel stop wait times
>  	 */
> -	dsi_write(dsi, DSI_PHY_IF_CFG, PHY_STOP_WAIT_TIME(0x20) |
> -		  N_LANES(dsi->lanes));
> +	regmap_write(dsi->regs, DSI_PHY_IF_CFG,
> +		     PHY_STOP_WAIT_TIME(0x20) | N_LANES(dsi->lanes));
>  }
>  
>  static void dw_mipi_dsi_dphy_init(struct dw_mipi_dsi *dsi)
>  {
>  	/* Clear PHY state */
> -	dsi_write(dsi, DSI_PHY_RSTZ, PHY_DISFORCEPLL | PHY_DISABLECLK
> -		  | PHY_RSTZ | PHY_SHUTDOWNZ);
> -	dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_UNTESTCLR);
> -	dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_TESTCLR);
> -	dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_UNTESTCLR);
> +	regmap_write(dsi->regs, DSI_PHY_RSTZ, PHY_DISFORCEPLL | PHY_DISABLECLK
> +		     | PHY_RSTZ | PHY_SHUTDOWNZ);
> +	regmap_write(dsi->regs, DSI_PHY_TST_CTRL0, PHY_UNTESTCLR);
> +	regmap_write(dsi->regs, DSI_PHY_TST_CTRL0, PHY_TESTCLR);
> +	regmap_write(dsi->regs, DSI_PHY_TST_CTRL0, PHY_UNTESTCLR);
>  }
>  
>  static void dw_mipi_dsi_dphy_enable(struct dw_mipi_dsi *dsi)
>  {
> -	u32 val;
> +	u32 val = 0;
>  	int ret;
>  
> -	dsi_write(dsi, DSI_PHY_RSTZ, PHY_ENFORCEPLL | PHY_ENABLECLK |
> -		  PHY_UNRSTZ | PHY_UNSHUTDOWNZ);
> +	regmap_write(dsi->regs, DSI_PHY_RSTZ, PHY_ENFORCEPLL | PHY_ENABLECLK |
> +		     PHY_UNRSTZ | PHY_UNSHUTDOWNZ);
>  
> -	ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS, val,
> -				 val & PHY_LOCK, 1000, PHY_STATUS_TIMEOUT_US);
> +	ret = regmap_read_poll_timeout(dsi->regs, DSI_PHY_STATUS,
> +				       val, val & PHY_LOCK,
> +				       1000, PHY_STATUS_TIMEOUT_US);
>  	if (ret)
>  		DRM_DEBUG_DRIVER("failed to wait phy lock state\n");
>  
> -	ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS,
> -				 val, val & PHY_STOP_STATE_CLK_LANE, 1000,
> -				 PHY_STATUS_TIMEOUT_US);
> +	ret = regmap_read_poll_timeout(dsi->regs, DSI_PHY_STATUS,
> +				       val, val & PHY_STOP_STATE_CLK_LANE, 1000,
> +				       PHY_STATUS_TIMEOUT_US);
>  	if (ret)
>  		DRM_DEBUG_DRIVER("failed to wait phy clk lane stop state\n");
>  }
>  
>  static void dw_mipi_dsi_clear_err(struct dw_mipi_dsi *dsi)
>  {
> -	dsi_read(dsi, DSI_INT_ST0);
> -	dsi_read(dsi, DSI_INT_ST1);
> -	dsi_write(dsi, DSI_INT_MSK0, 0);
> -	dsi_write(dsi, DSI_INT_MSK1, 0);
> +	u32 val;
> +
> +	regmap_read(dsi->regs, DSI_INT_ST0, &val);
> +	regmap_read(dsi->regs, DSI_INT_ST1, &val);
> +	regmap_write(dsi->regs, DSI_INT_MSK0, 0);
> +	regmap_write(dsi->regs, DSI_INT_MSK1, 0);
>  }
>  
>  static void dw_mipi_dsi_bridge_post_disable(struct drm_bridge *bridge)
> @@ -996,13 +998,10 @@ __dw_mipi_dsi_probe(struct platform_device *pdev,
>  		return ERR_PTR(-ENODEV);
>  	}
>  
> -	if (!plat_data->base) {
> -		dsi->base = devm_platform_ioremap_resource(pdev, 0);
> -		if (IS_ERR(dsi->base))
> -			return ERR_PTR(-ENODEV);
> -
> -	} else {
> -		dsi->base = plat_data->base;
> +	dsi->regs = plat_data->regs;
> +	if (!dsi->regs) {
> +		DRM_ERROR("DSI regmap not supplied by platform driver\n");
> +		return ERR_PTR(-ENODEV);
>  	}
>  
>  	dsi->pclk = devm_clk_get(dev, "pclk");
> diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
> index bc073ec5c183..3c33ed1fa805 100644
> --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
> @@ -24,6 +24,8 @@
>  #include "rockchip_drm_drv.h"
>  #include "rockchip_drm_vop.h"
>  
> +#define DRIVER_NAME "dw-mipi-dsi-rockchip"
> +
>  #define DSI_PHY_RSTZ			0xa0
>  #define PHY_DISFORCEPLL			0
>  #define PHY_ENFORCEPLL			BIT(3)
> @@ -212,7 +214,7 @@ struct rockchip_dw_dsi_chip_data {
>  struct dw_mipi_dsi_rockchip {
>  	struct device *dev;
>  	struct drm_encoder encoder;
> -	void __iomem *base;
> +	struct regmap *regs;
>  
>  	struct regmap *grf_regmap;
>  	struct clk *pllref_clk;
> @@ -297,12 +299,15 @@ static int max_mbps_to_parameter(unsigned int max_mbps)
>  
>  static inline void dsi_write(struct dw_mipi_dsi_rockchip *dsi, u32 reg, u32 val)
>  {
> -	writel(val, dsi->base + reg);
> +	regmap_write(dsi->regs, reg, val);
>  }
>  
>  static inline u32 dsi_read(struct dw_mipi_dsi_rockchip *dsi, u32 reg)
>  {
> -	return readl(dsi->base + reg);
> +	u32 val;
> +
> +	regmap_read(dsi->regs, reg, &val);
> +	return val;
>  }
>  
>  static inline void dsi_set(struct dw_mipi_dsi_rockchip *dsi, u32 reg, u32 mask)
> @@ -884,6 +889,13 @@ static const struct dw_mipi_dsi_host_ops dw_mipi_dsi_rockchip_host_ops = {
>  	.detach = dw_mipi_dsi_rockchip_host_detach,
>  };
>  
> +static const struct regmap_config rockchip_dsi_regmap_config = {
> +	.reg_bits = 32,
> +	.val_bits = 32,
> +	.reg_stride = 4,
> +	.name = DRIVER_NAME,
> +};
> +
>  static int dw_mipi_dsi_rockchip_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> @@ -892,6 +904,7 @@ static int dw_mipi_dsi_rockchip_probe(struct platform_device *pdev)
>  	struct resource *res;
>  	const struct rockchip_dw_dsi_chip_data *cdata =
>  				of_device_get_match_data(dev);
> +	void __iomem *regs;
>  	int ret, i;
>  
>  	dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
> @@ -899,10 +912,17 @@ static int dw_mipi_dsi_rockchip_probe(struct platform_device *pdev)
>  		return -ENOMEM;
>  
>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> -	dsi->base = devm_ioremap_resource(dev, res);
> -	if (IS_ERR(dsi->base)) {
> +	regs = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(regs)) {
>  		DRM_DEV_ERROR(dev, "Unable to get dsi registers\n");
> -		return PTR_ERR(dsi->base);
> +		return PTR_ERR(regs);
> +	}
> +
> +	dsi->regs = devm_regmap_init_mmio(dev, regs,
> +					  &rockchip_dsi_regmap_config);
> +	if (IS_ERR(dsi->regs)) {
> +		DRM_DEV_ERROR(dev, "Unable to create DSI regmap\n");
> +		return PTR_ERR(dsi->regs);
>  	}
>  
>  	i = 0;
> @@ -954,7 +974,7 @@ static int dw_mipi_dsi_rockchip_probe(struct platform_device *pdev)
>  	}
>  
>  	dsi->dev = dev;
> -	dsi->pdata.base = dsi->base;
> +	dsi->pdata.regs = dsi->regs;
>  	dsi->pdata.max_data_lanes = dsi->cdata->max_data_lanes;
>  	dsi->pdata.phy_ops = &dw_mipi_dsi_rockchip_phy_ops;
>  	dsi->pdata.host_ops = &dw_mipi_dsi_rockchip_host_ops;
> @@ -1072,6 +1092,6 @@ struct platform_driver dw_mipi_dsi_rockchip_driver = {
>  	.remove		= dw_mipi_dsi_rockchip_remove,
>  	.driver		= {
>  		.of_match_table = dw_mipi_dsi_rockchip_dt_ids,
> -		.name	= "dw-mipi-dsi-rockchip",
> +		.name	= DRIVER_NAME,
>  	},
>  };
> diff --git a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
> index 514efefb0016..cc233271347b 100644
> --- a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
> +++ b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
> @@ -12,6 +12,7 @@
>  #include <linux/module.h>
>  #include <linux/platform_device.h>
>  #include <linux/regulator/consumer.h>
> +#include <linux/regmap.h>
>  
>  #include <video/mipi_display.h>
>  
> @@ -19,6 +20,8 @@
>  #include <drm/drm_mipi_dsi.h>
>  #include <drm/drm_print.h>
>  
> +#define DRIVER_NAME "stm32-display-dsi"
> +
>  #define HWVER_130			0x31333000	/* IP version 1.30 */
>  #define HWVER_131			0x31333100	/* IP version 1.31 */
>  
> @@ -75,7 +78,7 @@ enum dsi_color {
>  #define TIMEOUT_US	200000
>  
>  struct dw_mipi_dsi_stm {
> -	void __iomem *base;
> +	struct regmap *regs;
>  	struct clk *pllref_clk;
>  	struct dw_mipi_dsi *dsi;
>  	u32 hw_version;
> @@ -86,12 +89,15 @@ struct dw_mipi_dsi_stm {
>  
>  static inline void dsi_write(struct dw_mipi_dsi_stm *dsi, u32 reg, u32 val)
>  {
> -	writel(val, dsi->base + reg);
> +	regmap_write(dsi->regs, reg, val);
>  }
>  
>  static inline u32 dsi_read(struct dw_mipi_dsi_stm *dsi, u32 reg)
>  {
> -	return readl(dsi->base + reg);
> +	u32 val;
> +
> +	regmap_read(dsi->regs, reg, &val);
> +	return val;
>  }
>  
>  static inline void dsi_set(struct dw_mipi_dsi_stm *dsi, u32 reg, u32 mask)
> @@ -202,15 +208,15 @@ static int dw_mipi_dsi_phy_init(void *priv_data)
>  
>  	/* Enable the regulator */
>  	dsi_set(dsi, DSI_WRPCR, WRPCR_REGEN | WRPCR_BGREN);
> -	ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & WISR_RRS,
> -				 SLEEP_US, TIMEOUT_US);
> +	ret = regmap_read_poll_timeout(dsi->regs, DSI_WISR, val, val & WISR_RRS,
> +				       SLEEP_US, TIMEOUT_US);
>  	if (ret)
>  		DRM_DEBUG_DRIVER("!TIMEOUT! waiting REGU, let's continue\n");
>  
>  	/* Enable the DSI PLL & wait for its lock */
>  	dsi_set(dsi, DSI_WRPCR, WRPCR_PLLEN);
> -	ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & WISR_PLLLS,
> -				 SLEEP_US, TIMEOUT_US);
> +	ret = regmap_read_poll_timeout(dsi->regs, DSI_WISR, val,
> +				       val & WISR_PLLLS, SLEEP_US, TIMEOUT_US);
>  	if (ret)
>  		DRM_DEBUG_DRIVER("!TIMEOUT! waiting PLL, let's continue\n");
>  
> @@ -327,12 +333,20 @@ static const struct of_device_id dw_mipi_dsi_stm_dt_ids[] = {
>  };
>  MODULE_DEVICE_TABLE(of, dw_mipi_dsi_stm_dt_ids);
>  
> +static const struct regmap_config stm_dsi_regmap_config = {
> +	.reg_bits = 32,
> +	.val_bits = 32,
> +	.reg_stride = 4,
> +	.name = DRIVER_NAME,
> +};
> +
>  static int dw_mipi_dsi_stm_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
>  	struct dw_mipi_dsi_stm *dsi;
>  	struct clk *pclk;
>  	struct resource *res;
> +	void __iomem *regs;
>  	int ret;
>  
>  	dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
> @@ -340,13 +354,19 @@ static int dw_mipi_dsi_stm_probe(struct platform_device *pdev)
>  		return -ENOMEM;
>  
>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> -	dsi->base = devm_ioremap_resource(dev, res);
> -	if (IS_ERR(dsi->base)) {
> -		ret = PTR_ERR(dsi->base);
> +	regs = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(regs)) {
> +		ret = PTR_ERR(regs);
>  		DRM_ERROR("Unable to get dsi registers %d\n", ret);
>  		return ret;
>  	}
>  
> +	dsi->regs = devm_regmap_init_mmio(dev, regs, &stm_dsi_regmap_config);
> +	if (IS_ERR(dsi->regs)) {
> +		DRM_DEV_ERROR(dev, "Unable to create DSI regmap\n");
> +		return PTR_ERR(dsi->regs);
> +	}
> +
>  	dsi->vdd_supply = devm_regulator_get(dev, "phy-dsi");
>  	if (IS_ERR(dsi->vdd_supply)) {
>  		ret = PTR_ERR(dsi->vdd_supply);
> @@ -396,7 +416,7 @@ static int dw_mipi_dsi_stm_probe(struct platform_device *pdev)
>  		goto err_dsi_probe;
>  	}
>  
> -	dw_mipi_dsi_stm_plat_data.base = dsi->base;
> +	dw_mipi_dsi_stm_plat_data.regs = dsi->regs;
>  	dw_mipi_dsi_stm_plat_data.priv_data = dsi;
>  
>  	platform_set_drvdata(pdev, dsi);
> @@ -474,7 +494,7 @@ static struct platform_driver dw_mipi_dsi_stm_driver = {
>  	.remove		= dw_mipi_dsi_stm_remove,
>  	.driver		= {
>  		.of_match_table = dw_mipi_dsi_stm_dt_ids,
> -		.name	= "stm32-display-dsi",
> +		.name	= DRIVER_NAME,
>  		.pm = &dw_mipi_dsi_stm_pm_ops,
>  	},
>  };
> diff --git a/include/drm/bridge/dw_mipi_dsi.h b/include/drm/bridge/dw_mipi_dsi.h
> index 94cc64a342e1..ecc1897efa62 100644
> --- a/include/drm/bridge/dw_mipi_dsi.h
> +++ b/include/drm/bridge/dw_mipi_dsi.h
> @@ -37,7 +37,7 @@ struct dw_mipi_dsi_host_ops {
>  };
>  
>  struct dw_mipi_dsi_plat_data {
> -	void __iomem *base;
> +	struct regmap *regs;
>  	unsigned int max_data_lanes;
>  
>  	enum drm_mode_status (*mode_valid)(void *priv_data,
> 

OK for the dw-mipi-dsi changes, but why should the dw_mipi_dsi-stm be changed aswell ?

AFAIK these are independent.

Neil
Adrian Ratiu Nov. 4, 2019, 12:03 p.m. UTC | #2
On Mon, 04 Nov 2019, Neil Armstrong <narmstrong@baylibre.com> 
wrote:
> On 31/10/2019 15:26, Adrian Ratiu wrote: 
>> Convert the common bridge code and the two rockchip & stm 
>> drivers which currently use it to the regmap API in 
>> anticipation for further changes to make it more generic and 
>> add older DSI host controller support as found on i.mx6 based 
>> devices.   No functional changes other than requiring the 
>> platform drivers to provide a regmap via their plat_data. Going 
>> further each platform driver can also add its own regmap 
>> configuration like for maximum write offsets, r/w callbacks or 
>> different register layouts.   Suggested-by: Boris Brezillon 
>> <boris.brezillon@collabora.com> Signed-off-by: Adrian Ratiu 
>> <adrian.ratiu@collabora.com> --- 
>>  drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 189 
>>  +++++++++--------- .../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c 
>>  |  36 +++- drivers/gpu/drm/stm/dw_mipi_dsi-stm.c         |  44 
>>  ++-- include/drm/bridge/dw_mipi_dsi.h              |   2 +- 4 
>>  files changed, 155 insertions(+), 116 deletions(-) 
>>  diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
>> b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c index 
>> b6e793bb653c..4ef3e9038cc2 100644 --- 
>> a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ 
>> b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -15,6 +15,7 
>> @@ 
>>  #include <linux/module.h> #include <linux/of_device.h> 
>>  #include <linux/pm_runtime.h> 
>> +#include <linux/regmap.h> 
>>  #include <linux/reset.h>  #include <video/mipi_display.h> 
>> @@ -226,7 +227,7 @@ struct dw_mipi_dsi { 
>>  	struct mipi_dsi_host dsi_host; struct drm_bridge 
>>  *panel_bridge; struct device *dev; 
>> -	void __iomem *base; +	struct regmap *regs; 
>>   struct clk *pclk;  
>> @@ -280,16 +281,6 @@ static inline struct dw_mipi_dsi 
>> *bridge_to_dsi(struct drm_bridge *bridge) 
>>  	return container_of(bridge, struct dw_mipi_dsi, bridge); }  
>> -static inline void dsi_write(struct dw_mipi_dsi *dsi, u32 reg, 
>> u32 val) -{ -	writel(val, dsi->base + reg); -} - -static 
>> inline u32 dsi_read(struct dw_mipi_dsi *dsi, u32 reg) -{ - 
>> return readl(dsi->base + reg); -} - 
>>  static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host, 
>>  struct mipi_dsi_device *device) { 
>> @@ -366,29 +357,29 @@ static void dw_mipi_message_config(struct 
>> dw_mipi_dsi *dsi, 
>>  	if (lpm) val |= CMD_MODE_ALL_LP;  
>> -	dsi_write(dsi, DSI_LPCLK_CTRL, lpm ? 0 : 
>> PHY_TXREQUESTCLKHS); -	dsi_write(dsi, DSI_CMD_MODE_CFG, 
>> val); +	regmap_write(dsi->regs, DSI_LPCLK_CTRL, lpm ? 0 : 
>> PHY_TXREQUESTCLKHS); +	regmap_write(dsi->regs, 
>> DSI_CMD_MODE_CFG, val); 
>>  }  static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi 
>>  *dsi, u32 hdr_val) { int ret; 
>> -	u32 val, mask; +	u32 val = 0, mask; 
>>   
>> -	ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS, - 
>> val, !(val & GEN_CMD_FULL), 1000, - 
>> CMD_PKT_STATUS_TIMEOUT_US); +	ret = 
>> regmap_read_poll_timeout(dsi->regs, DSI_CMD_PKT_STATUS, + 
>> val, !(val & GEN_CMD_FULL), 1000, + 
>> CMD_PKT_STATUS_TIMEOUT_US); 
>>  	if (ret) { dev_err(dsi->dev, "failed to get available 
>>  command FIFO\n"); return ret; }  
>> -	dsi_write(dsi, DSI_GEN_HDR, hdr_val); + 
>> regmap_write(dsi->regs, DSI_GEN_HDR, hdr_val); 
>>   mask = GEN_CMD_EMPTY | GEN_PLD_W_EMPTY; 
>> -	ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS, - 
>> val, (val & mask) == mask, -				 1000, 
>> CMD_PKT_STATUS_TIMEOUT_US); +	ret = 
>> regmap_read_poll_timeout(dsi->regs, DSI_CMD_PKT_STATUS, + 
>> val, (val & mask) == mask, + 
>> 1000, CMD_PKT_STATUS_TIMEOUT_US); 
>>  	if (ret) { dev_err(dsi->dev, "failed to write command 
>>  FIFO\n"); return ret; 
>> @@ -403,24 +394,26 @@ static int dw_mipi_dsi_write(struct 
>> dw_mipi_dsi *dsi, 
>>  	const u8 *tx_buf = packet->payload; int len = 
>>  packet->payload_length, pld_data_bytes = sizeof(u32), ret; 
>>  __le32 word; 
>> -	u32 val; +	u32 val = 0; 
>>   while (len) { if (len < pld_data_bytes) { word = 0; 
>>  memcpy(&word, tx_buf, len); 
>> -			dsi_write(dsi, DSI_GEN_PLD_DATA, 
>> le32_to_cpu(word)); + 
>> regmap_write(dsi->regs, DSI_GEN_PLD_DATA, + 
>> le32_to_cpu(word)); 
>>  			len = 0; } else { memcpy(&word, tx_buf, 
>>  pld_data_bytes); 
>> -			dsi_write(dsi, DSI_GEN_PLD_DATA, 
>> le32_to_cpu(word)); + 
>> regmap_write(dsi->regs, DSI_GEN_PLD_DATA, + 
>> le32_to_cpu(word)); 
>>  			tx_buf += pld_data_bytes; len -= 
>>  pld_data_bytes; }  
>> -		ret = readl_poll_timeout(dsi->base + 
>> DSI_CMD_PKT_STATUS, - 
>> val, !(val & GEN_PLD_W_FULL), 1000, - 
>> CMD_PKT_STATUS_TIMEOUT_US); +		ret = 
>> regmap_read_poll_timeout(dsi->regs, DSI_CMD_PKT_STATUS, + 
>> val, !(val & GEN_PLD_W_FULL), + 
>> 1000, CMD_PKT_STATUS_TIMEOUT_US); 
>>  		if (ret) { dev_err(dsi->dev, "failed to get 
>>  available write payload FIFO\n"); 
>> @@ -438,12 +431,12 @@ static int dw_mipi_dsi_read(struct 
>> dw_mipi_dsi *dsi, 
>>  { int i, j, ret, len = msg->rx_len; u8 *buf = msg->rx_buf; 
>> -	u32 val; +	u32 val = 0; 
>>   /* Wait end of the read operation */ 
>> -	ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS, - 
>> val, !(val & GEN_RD_CMD_BUSY), - 
>> 1000, CMD_PKT_STATUS_TIMEOUT_US); +	ret = 
>> regmap_read_poll_timeout(dsi->regs, DSI_CMD_PKT_STATUS, + 
>> val, !(val & GEN_RD_CMD_BUSY), + 
>> 1000, CMD_PKT_STATUS_TIMEOUT_US); 
>>  	if (ret) { dev_err(dsi->dev, "Timeout during read 
>>  operation\n"); return ret; 
>> @@ -451,15 +444,15 @@ static int dw_mipi_dsi_read(struct 
>> dw_mipi_dsi *dsi, 
>>   for (i = 0; i < len; i += 4) { /* Read fifo must not be empty 
>>  before all bytes are read */ 
>> -		ret = readl_poll_timeout(dsi->base + 
>> DSI_CMD_PKT_STATUS, - 
>> val, !(val & GEN_PLD_R_EMPTY), - 
>> 1000, CMD_PKT_STATUS_TIMEOUT_US); +		ret = 
>> regmap_read_poll_timeout(dsi->regs, DSI_CMD_PKT_STATUS, + 
>> val, !(val & GEN_PLD_R_EMPTY), + 
>> 1000, CMD_PKT_STATUS_TIMEOUT_US); 
>>  		if (ret) { dev_err(dsi->dev, "Read payload FIFO is 
>>  empty\n"); return ret; }  
>> -		val = dsi_read(dsi, DSI_GEN_PLD_DATA); + 
>> regmap_read(dsi->regs, DSI_GEN_PLD_DATA, &val); 
>>  		for (j = 0; j < 4 && j + i < len; j++) buf[i + j] 
>>  = val >> (8 * j); } 
>> @@ -536,29 +529,29 @@ static void 
>> dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi) 
>>  	} #endif /* CONFIG_DEBUG_FS */  
>> -	dsi_write(dsi, DSI_VID_MODE_CFG, val); + 
>> regmap_write(dsi->regs, DSI_VID_MODE_CFG, val); 
>>  }  static void dw_mipi_dsi_set_mode(struct dw_mipi_dsi *dsi, 
>>  unsigned long mode_flags) { 
>> -	dsi_write(dsi, DSI_PWR_UP, RESET); + 
>> regmap_write(dsi->regs, DSI_PWR_UP, RESET); 
>>   if (mode_flags & MIPI_DSI_MODE_VIDEO) { 
>> -		dsi_write(dsi, DSI_MODE_CFG, ENABLE_VIDEO_MODE); + 
>> regmap_write(dsi->regs, DSI_MODE_CFG, ENABLE_VIDEO_MODE); 
>>  		dw_mipi_dsi_video_mode_config(dsi); 
>> -		dsi_write(dsi, DSI_LPCLK_CTRL, 
>> PHY_TXREQUESTCLKHS); +		regmap_write(dsi->regs, 
>> DSI_LPCLK_CTRL, PHY_TXREQUESTCLKHS); 
>>  	} else { 
>> -		dsi_write(dsi, DSI_MODE_CFG, ENABLE_CMD_MODE); + 
>> regmap_write(dsi->regs, DSI_MODE_CFG, ENABLE_CMD_MODE); 
>>  	}  
>> -	dsi_write(dsi, DSI_PWR_UP, POWERUP); + 
>> regmap_write(dsi->regs, DSI_PWR_UP, POWERUP); 
>>  }  static void dw_mipi_dsi_disable(struct dw_mipi_dsi *dsi) { 
>> -	dsi_write(dsi, DSI_PWR_UP, RESET); -	dsi_write(dsi, 
>> DSI_PHY_RSTZ, PHY_RSTZ); +	regmap_write(dsi->regs, 
>> DSI_PWR_UP, RESET); +	regmap_write(dsi->regs, 
>> DSI_PHY_RSTZ, PHY_RSTZ); 
>>  }  static void dw_mipi_dsi_init(struct dw_mipi_dsi *dsi) 
>> @@ -573,14 +566,14 @@ static void dw_mipi_dsi_init(struct 
>> dw_mipi_dsi *dsi) 
>>  	 */ u32 esc_clk_division = (dsi->lane_mbps >> 3) / 20 + 1;  
>> -	dsi_write(dsi, DSI_PWR_UP, RESET); + 
>> regmap_write(dsi->regs, DSI_PWR_UP, RESET); 
>>   /* * TODO dw drv improvements * timeout clock division should 
>>  be computed with the * high speed transmission counter timeout 
>>  and byte lane...  */ 
>> -	dsi_write(dsi, DSI_CLKMGR_CFG, TO_CLK_DIVISION(10) | + 
>> regmap_write(dsi->regs, DSI_CLKMGR_CFG, TO_CLK_DIVISION(10) | 
>>  		  TX_ESC_CLK_DIVISION(esc_clk_division)); }  
>> @@ -609,22 +602,22 @@ static void dw_mipi_dsi_dpi_config(struct 
>> dw_mipi_dsi *dsi, 
>>  	if (mode->flags & DRM_MODE_FLAG_NHSYNC) val |= 
>>  HSYNC_ACTIVE_LOW;  
>> -	dsi_write(dsi, DSI_DPI_VCID, DPI_VCID(dsi->channel)); - 
>> dsi_write(dsi, DSI_DPI_COLOR_CODING, color); - 
>> dsi_write(dsi, DSI_DPI_CFG_POL, val); + 
>> regmap_write(dsi->regs, DSI_DPI_VCID, DPI_VCID(dsi->channel)); 
>> +	regmap_write(dsi->regs, DSI_DPI_COLOR_CODING, color); + 
>> regmap_write(dsi->regs, DSI_DPI_CFG_POL, val); 
>>  	/* * TODO dw drv improvements * largest packet sizes 
>>  during hfp or during vsa/vpb/vfp * should be computed 
>>  according to byte lane, lane number and only * if sending lp 
>>  cmds in high speed is enable (PHY_TXREQUESTCLKHS) */ 
>> -	dsi_write(dsi, DSI_DPI_LP_CMD_TIM, OUTVACT_LPCMD_TIME(4) + 
>> regmap_write(dsi->regs, DSI_DPI_LP_CMD_TIM, 
>> OUTVACT_LPCMD_TIME(4) 
>>  		  | INVACT_LPCMD_TIME(4)); }  static void 
>>  dw_mipi_dsi_packet_handler_config(struct dw_mipi_dsi *dsi) { 
>> -	dsi_write(dsi, DSI_PCKHDL_CFG, CRC_RX_EN | ECC_RX_EN | 
>> BTA_EN); +	regmap_write(dsi->regs, DSI_PCKHDL_CFG, CRC_RX_EN 
>> | ECC_RX_EN | BTA_EN); 
>>  }  static void dw_mipi_dsi_video_packet_config(struct 
>>  dw_mipi_dsi *dsi, 
>> @@ -638,7 +631,7 @@ static void 
>> dw_mipi_dsi_video_packet_config(struct dw_mipi_dsi *dsi, 
>>  	 * non-burst video modes, see 
>>  dw_mipi_dsi_video_mode_config()...  */  
>> -	dsi_write(dsi, DSI_VID_PKT_SIZE, + 
>> regmap_write(dsi->regs, DSI_VID_PKT_SIZE, 
>>  		       dw_mipi_is_dual_mode(dsi) ? 
>>  VID_PKT_SIZE(mode->hdisplay / 2) : 
>>  VID_PKT_SIZE(mode->hdisplay)); 
>> @@ -651,14 +644,15 @@ static void 
>> dw_mipi_dsi_command_mode_config(struct dw_mipi_dsi *dsi) 
>>  	 * compute high speed transmission counter timeout 
>>  according * to the timeout clock division (TO_CLK_DIVISION) 
>>  and byte lane...  */ 
>> -	dsi_write(dsi, DSI_TO_CNT_CFG, HSTX_TO_CNT(1000) | 
>> LPRX_TO_CNT(1000)); +	regmap_write(dsi->regs, 
>> DSI_TO_CNT_CFG, +		     HSTX_TO_CNT(1000) | 
>> LPRX_TO_CNT(1000)); 
>>  	/* * TODO dw drv improvements * the Bus-Turn-Around 
>>  Timeout Counter should be computed * according to byte lane... 
>>  */ 
>> -	dsi_write(dsi, DSI_BTA_TO_CNT, 0xd00); - 
>> dsi_write(dsi, DSI_MODE_CFG, ENABLE_CMD_MODE); + 
>> regmap_write(dsi->regs, DSI_BTA_TO_CNT, 0xd00); + 
>> regmap_write(dsi->regs, DSI_MODE_CFG, ENABLE_CMD_MODE); 
>>  }  /* Get lane byte clock cycles. */ 
>> @@ -692,13 +686,13 @@ static void 
>> dw_mipi_dsi_line_timer_config(struct dw_mipi_dsi *dsi, 
>>  	 * computations below may be improved...  */ lbcc = 
>>  dw_mipi_dsi_get_hcomponent_lbcc(dsi, mode, htotal); 
>> -	dsi_write(dsi, DSI_VID_HLINE_TIME, lbcc); + 
>> regmap_write(dsi->regs, DSI_VID_HLINE_TIME, lbcc); 
>>   lbcc = dw_mipi_dsi_get_hcomponent_lbcc(dsi, mode, hsa); 
>> -	dsi_write(dsi, DSI_VID_HSA_TIME, lbcc); + 
>> regmap_write(dsi->regs, DSI_VID_HSA_TIME, lbcc); 
>>   lbcc = dw_mipi_dsi_get_hcomponent_lbcc(dsi, mode, hbp); 
>> -	dsi_write(dsi, DSI_VID_HBP_TIME, lbcc); + 
>> regmap_write(dsi->regs, DSI_VID_HBP_TIME, lbcc); 
>>  }  static void dw_mipi_dsi_vertical_timing_config(struct 
>>  dw_mipi_dsi *dsi, 
>> @@ -711,10 +705,10 @@ static void 
>> dw_mipi_dsi_vertical_timing_config(struct dw_mipi_dsi *dsi, 
>>  	vfp = mode->vsync_start - mode->vdisplay; vbp = 
>>  mode->vtotal - mode->vsync_end;  
>> -	dsi_write(dsi, DSI_VID_VACTIVE_LINES, vactive); - 
>> dsi_write(dsi, DSI_VID_VSA_LINES, vsa); -	dsi_write(dsi, 
>> DSI_VID_VFP_LINES, vfp); -	dsi_write(dsi, DSI_VID_VBP_LINES, 
>> vbp); +	regmap_write(dsi->regs, DSI_VID_VACTIVE_LINES, 
>> vactive); +	regmap_write(dsi->regs, DSI_VID_VSA_LINES, vsa); + 
>> regmap_write(dsi->regs, DSI_VID_VFP_LINES, vfp); + 
>> regmap_write(dsi->regs, DSI_VID_VBP_LINES, vbp); 
>>  }  static void dw_mipi_dsi_dphy_timing_config(struct 
>>  dw_mipi_dsi *dsi) 
>> @@ -729,19 +723,24 @@ static void 
>> dw_mipi_dsi_dphy_timing_config(struct dw_mipi_dsi *dsi) 
>>  	 * DSI_CMD_MODE_CFG.MAX_RD_PKT_SIZE_LP (see 
>>  CMD_MODE_ALL_LP) */  
>> -	hw_version = dsi_read(dsi, DSI_VERSION) & VERSION; + 
>> regmap_read(dsi->regs, DSI_VERSION, &hw_version); +	hw_version 
>> &= VERSION; 
>>   if (hw_version >= HWVER_131) { 
>> -		dsi_write(dsi, DSI_PHY_TMR_CFG, 
>> PHY_HS2LP_TIME_V131(0x40) | - 
>> PHY_LP2HS_TIME_V131(0x40)); -		dsi_write(dsi, 
>> DSI_PHY_TMR_RD_CFG, MAX_RD_TIME_V131(10000)); + 
>> regmap_write(dsi->regs, DSI_PHY_TMR_CFG, + 
>> PHY_HS2LP_TIME_V131(0x40) | + 
>> PHY_LP2HS_TIME_V131(0x40)); + 
>> regmap_write(dsi->regs, DSI_PHY_TMR_RD_CFG, + 
>> MAX_RD_TIME_V131(10000)); 
>>  	} else { 
>> -		dsi_write(dsi, DSI_PHY_TMR_CFG, 
>> PHY_HS2LP_TIME(0x40) | - 
>> PHY_LP2HS_TIME(0x40) | MAX_RD_TIME(10000)); + 
>> regmap_write(dsi->regs, DSI_PHY_TMR_CFG, + 
>> PHY_HS2LP_TIME(0x40) | + 
>> PHY_LP2HS_TIME(0x40) | + 
>> MAX_RD_TIME(10000)); 
>>  	}  
>> -	dsi_write(dsi, DSI_PHY_TMR_LPCLK_CFG, 
>> PHY_CLKHS2LP_TIME(0x40) -		  | 
>> PHY_CLKLP2HS_TIME(0x40)); +	regmap_write(dsi->regs, 
>> DSI_PHY_TMR_LPCLK_CFG, + 
>> PHY_CLKHS2LP_TIME(0x40) | PHY_CLKLP2HS_TIME(0x40)); 
>>  }  static void dw_mipi_dsi_dphy_interface_config(struct 
>>  dw_mipi_dsi *dsi) 
>> @@ -751,46 +750,49 @@ static void 
>> dw_mipi_dsi_dphy_interface_config(struct dw_mipi_dsi *dsi) 
>>  	 * stop wait time should be the maximum between host dsi * 
>>  and panel stop wait times */ 
>> -	dsi_write(dsi, DSI_PHY_IF_CFG, PHY_STOP_WAIT_TIME(0x20) | 
>> -		  N_LANES(dsi->lanes)); + 
>> regmap_write(dsi->regs, DSI_PHY_IF_CFG, + 
>> PHY_STOP_WAIT_TIME(0x20) | N_LANES(dsi->lanes)); 
>>  }  static void dw_mipi_dsi_dphy_init(struct dw_mipi_dsi *dsi) 
>>  { /* Clear PHY state */ 
>> -	dsi_write(dsi, DSI_PHY_RSTZ, PHY_DISFORCEPLL | 
>> PHY_DISABLECLK -		  | PHY_RSTZ | PHY_SHUTDOWNZ); - 
>> dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_UNTESTCLR); - 
>> dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_TESTCLR); - 
>> dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_UNTESTCLR); + 
>> regmap_write(dsi->regs, DSI_PHY_RSTZ, PHY_DISFORCEPLL | 
>> PHY_DISABLECLK +		     | PHY_RSTZ | PHY_SHUTDOWNZ); 
>> +	regmap_write(dsi->regs, DSI_PHY_TST_CTRL0, PHY_UNTESTCLR); 
>> +	regmap_write(dsi->regs, DSI_PHY_TST_CTRL0, PHY_TESTCLR); + 
>> regmap_write(dsi->regs, DSI_PHY_TST_CTRL0, PHY_UNTESTCLR); 
>>  }  static void dw_mipi_dsi_dphy_enable(struct dw_mipi_dsi 
>>  *dsi) { 
>> -	u32 val; +	u32 val = 0; 
>>  	int ret;  
>> -	dsi_write(dsi, DSI_PHY_RSTZ, PHY_ENFORCEPLL | 
>> PHY_ENABLECLK | -		  PHY_UNRSTZ | PHY_UNSHUTDOWNZ); + 
>> regmap_write(dsi->regs, DSI_PHY_RSTZ, PHY_ENFORCEPLL | 
>> PHY_ENABLECLK | +		     PHY_UNRSTZ | 
>> PHY_UNSHUTDOWNZ); 
>>   
>> -	ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS, val, 
>> -				 val & PHY_LOCK, 1000, 
>> PHY_STATUS_TIMEOUT_US); +	ret = 
>> regmap_read_poll_timeout(dsi->regs, DSI_PHY_STATUS, + 
>> val, val & PHY_LOCK, + 
>> 1000, PHY_STATUS_TIMEOUT_US); 
>>  	if (ret) DRM_DEBUG_DRIVER("failed to wait phy lock 
>>  state\n");  
>> -	ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS, - 
>> val, val & PHY_STOP_STATE_CLK_LANE, 1000, - 
>> PHY_STATUS_TIMEOUT_US); +	ret = 
>> regmap_read_poll_timeout(dsi->regs, DSI_PHY_STATUS, + 
>> val, val & PHY_STOP_STATE_CLK_LANE, 1000, + 
>> PHY_STATUS_TIMEOUT_US); 
>>  	if (ret) DRM_DEBUG_DRIVER("failed to wait phy clk lane 
>>  stop state\n"); }  static void dw_mipi_dsi_clear_err(struct 
>>  dw_mipi_dsi *dsi) { 
>> -	dsi_read(dsi, DSI_INT_ST0); -	dsi_read(dsi, 
>> DSI_INT_ST1); -	dsi_write(dsi, DSI_INT_MSK0, 0); - 
>> dsi_write(dsi, DSI_INT_MSK1, 0); +	u32 val; + + 
>> regmap_read(dsi->regs, DSI_INT_ST0, &val); + 
>> regmap_read(dsi->regs, DSI_INT_ST1, &val); + 
>> regmap_write(dsi->regs, DSI_INT_MSK0, 0); + 
>> regmap_write(dsi->regs, DSI_INT_MSK1, 0); 
>>  }  static void dw_mipi_dsi_bridge_post_disable(struct 
>>  drm_bridge *bridge) 
>> @@ -996,13 +998,10 @@ __dw_mipi_dsi_probe(struct 
>> platform_device *pdev, 
>>  		return ERR_PTR(-ENODEV); }  
>> -	if (!plat_data->base) { -		dsi->base = 
>> devm_platform_ioremap_resource(pdev, 0); -		if 
>> (IS_ERR(dsi->base)) -			return 
>> ERR_PTR(-ENODEV); - -	} else { -		dsi->base 
>> = plat_data->base; +	dsi->regs = plat_data->regs; +	if 
>> (!dsi->regs) { +		DRM_ERROR("DSI regmap not supplied 
>> by platform driver\n"); +		return ERR_PTR(-ENODEV); 
>>  	}  dsi->pclk = devm_clk_get(dev, "pclk"); 
>> diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c 
>> b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c index 
>> bc073ec5c183..3c33ed1fa805 100644 --- 
>> a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c +++ 
>> b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c @@ -24,6 
>> +24,8 @@ 
>>  #include "rockchip_drm_drv.h" #include "rockchip_drm_vop.h"  
>> +#define DRIVER_NAME "dw-mipi-dsi-rockchip" + 
>>  #define DSI_PHY_RSTZ			0xa0 #define 
>>  PHY_DISFORCEPLL			0 #define PHY_ENFORCEPLL 
>>  BIT(3) 
>> @@ -212,7 +214,7 @@ struct rockchip_dw_dsi_chip_data { 
>>  struct dw_mipi_dsi_rockchip { struct device *dev; struct 
>>  drm_encoder encoder; 
>> -	void __iomem *base; +	struct regmap *regs; 
>>   struct regmap *grf_regmap; struct clk *pllref_clk; 
>> @@ -297,12 +299,15 @@ static int max_mbps_to_parameter(unsigned 
>> int max_mbps) 
>>   static inline void dsi_write(struct dw_mipi_dsi_rockchip 
>>  *dsi, u32 reg, u32 val) { 
>> -	writel(val, dsi->base + reg); +	regmap_write(dsi->regs, 
>> reg, val); 
>>  }  static inline u32 dsi_read(struct dw_mipi_dsi_rockchip 
>>  *dsi, u32 reg) { 
>> -	return readl(dsi->base + reg); +	u32 val; + + 
>> regmap_read(dsi->regs, reg, &val); +	return val; 
>>  }  static inline void dsi_set(struct dw_mipi_dsi_rockchip 
>>  *dsi, u32 reg, u32 mask) 
>> @@ -884,6 +889,13 @@ static const struct dw_mipi_dsi_host_ops 
>> dw_mipi_dsi_rockchip_host_ops = { 
>>  	.detach = dw_mipi_dsi_rockchip_host_detach, };  
>> +static const struct regmap_config rockchip_dsi_regmap_config = 
>> { +	.reg_bits = 32, +	.val_bits = 32, + 
>> .reg_stride = 4, +	.name = DRIVER_NAME, +}; + 
>>  static int dw_mipi_dsi_rockchip_probe(struct platform_device 
>>  *pdev) { struct device *dev = &pdev->dev; 
>> @@ -892,6 +904,7 @@ static int 
>> dw_mipi_dsi_rockchip_probe(struct platform_device *pdev) 
>>  	struct resource *res; const struct 
>>  rockchip_dw_dsi_chip_data *cdata = 
>>  of_device_get_match_data(dev); 
>> +	void __iomem *regs; 
>>  	int ret, i;  dsi = devm_kzalloc(dev, sizeof(*dsi), 
>>  GFP_KERNEL); 
>> @@ -899,10 +912,17 @@ static int 
>> dw_mipi_dsi_rockchip_probe(struct platform_device *pdev) 
>>  		return -ENOMEM;  res = platform_get_resource(pdev, 
>>  IORESOURCE_MEM, 0); 
>> -	dsi->base = devm_ioremap_resource(dev, res); -	if 
>> (IS_ERR(dsi->base)) { +	regs = devm_ioremap_resource(dev, 
>> res); +	if (IS_ERR(regs)) { 
>>  		DRM_DEV_ERROR(dev, "Unable to get dsi 
>>  registers\n"); 
>> -		return PTR_ERR(dsi->base); +		return 
>> PTR_ERR(regs); +	} + +	dsi->regs = 
>> devm_regmap_init_mmio(dev, regs, + 
>> &rockchip_dsi_regmap_config); +	if (IS_ERR(dsi->regs)) { + 
>> DRM_DEV_ERROR(dev, "Unable to create DSI regmap\n"); + 
>> return PTR_ERR(dsi->regs); 
>>  	}  i = 0; 
>> @@ -954,7 +974,7 @@ static int 
>> dw_mipi_dsi_rockchip_probe(struct platform_device *pdev) 
>>  	}  dsi->dev = dev; 
>> -	dsi->pdata.base = dsi->base; +	dsi->pdata.regs = 
>> dsi->regs; 
>>  	dsi->pdata.max_data_lanes = dsi->cdata->max_data_lanes; 
>>  dsi->pdata.phy_ops = &dw_mipi_dsi_rockchip_phy_ops; 
>>  dsi->pdata.host_ops = &dw_mipi_dsi_rockchip_host_ops; 
>> @@ -1072,6 +1092,6 @@ struct platform_driver 
>> dw_mipi_dsi_rockchip_driver = { 
>>  	.remove		= dw_mipi_dsi_rockchip_remove, .driver 
>>  = { .of_match_table = dw_mipi_dsi_rockchip_dt_ids, 
>> -		.name	= "dw-mipi-dsi-rockchip", + 
>> .name	= DRIVER_NAME, 
>>  	}, }; 
>> diff --git a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c 
>> b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c index 
>> 514efefb0016..cc233271347b 100644 --- 
>> a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c +++ 
>> b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c @@ -12,6 +12,7 @@ 
>>  #include <linux/module.h> #include <linux/platform_device.h> 
>>  #include <linux/regulator/consumer.h> 
>> +#include <linux/regmap.h> 
>>   #include <video/mipi_display.h>  
>> @@ -19,6 +20,8 @@ 
>>  #include <drm/drm_mipi_dsi.h> #include <drm/drm_print.h>  
>> +#define DRIVER_NAME "stm32-display-dsi" + 
>>  #define HWVER_130			0x31333000	/* IP 
>>  version 1.30 */ #define HWVER_131			0x31333100 
>>  /* IP version 1.31 */  
>> @@ -75,7 +78,7 @@ enum dsi_color { 
>>  #define TIMEOUT_US	200000  struct dw_mipi_dsi_stm { 
>> -	void __iomem *base; +	struct regmap *regs; 
>>  	struct clk *pllref_clk; struct dw_mipi_dsi *dsi; u32 
>>  hw_version; 
>> @@ -86,12 +89,15 @@ struct dw_mipi_dsi_stm { 
>>   static inline void dsi_write(struct dw_mipi_dsi_stm *dsi, u32 
>>  reg, u32 val) { 
>> -	writel(val, dsi->base + reg); +	regmap_write(dsi->regs, 
>> reg, val); 
>>  }  static inline u32 dsi_read(struct dw_mipi_dsi_stm *dsi, u32 
>>  reg) { 
>> -	return readl(dsi->base + reg); +	u32 val; + + 
>> regmap_read(dsi->regs, reg, &val); +	return val; 
>>  }  static inline void dsi_set(struct dw_mipi_dsi_stm *dsi, u32 
>>  reg, u32 mask) 
>> @@ -202,15 +208,15 @@ static int dw_mipi_dsi_phy_init(void 
>> *priv_data) 
>>   /* Enable the regulator */ dsi_set(dsi, DSI_WRPCR, 
>>  WRPCR_REGEN | WRPCR_BGREN); 
>> -	ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & 
>> WISR_RRS, -				 SLEEP_US, TIMEOUT_US); + 
>> ret = regmap_read_poll_timeout(dsi->regs, DSI_WISR, val, val & 
>> WISR_RRS, +				       SLEEP_US, 
>> TIMEOUT_US); 
>>  	if (ret) DRM_DEBUG_DRIVER("!TIMEOUT! waiting REGU, let's 
>>  continue\n");  /* Enable the DSI PLL & wait for its lock */ 
>>  dsi_set(dsi, DSI_WRPCR, WRPCR_PLLEN); 
>> -	ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & 
>> WISR_PLLLS, -				 SLEEP_US, 
>> TIMEOUT_US); +	ret = regmap_read_poll_timeout(dsi->regs, 
>> DSI_WISR, val, +				       val & 
>> WISR_PLLLS, SLEEP_US, TIMEOUT_US); 
>>  	if (ret) DRM_DEBUG_DRIVER("!TIMEOUT! waiting PLL, let's 
>>  continue\n");  
>> @@ -327,12 +333,20 @@ static const struct of_device_id 
>> dw_mipi_dsi_stm_dt_ids[] = { 
>>  }; MODULE_DEVICE_TABLE(of, dw_mipi_dsi_stm_dt_ids);  
>> +static const struct regmap_config stm_dsi_regmap_config = { + 
>> .reg_bits = 32, +	.val_bits = 32, +	.reg_stride = 4, + 
>> .name = DRIVER_NAME, +}; + 
>>  static int dw_mipi_dsi_stm_probe(struct platform_device *pdev) 
>>  { struct device *dev = &pdev->dev; struct dw_mipi_dsi_stm 
>>  *dsi; struct clk *pclk; struct resource *res; 
>> +	void __iomem *regs; 
>>  	int ret;  dsi = devm_kzalloc(dev, sizeof(*dsi), 
>>  GFP_KERNEL); 
>> @@ -340,13 +354,19 @@ static int dw_mipi_dsi_stm_probe(struct 
>> platform_device *pdev) 
>>  		return -ENOMEM;  res = platform_get_resource(pdev, 
>>  IORESOURCE_MEM, 0); 
>> -	dsi->base = devm_ioremap_resource(dev, res); -	if 
>> (IS_ERR(dsi->base)) { -		ret = PTR_ERR(dsi->base); 
>> +	regs = devm_ioremap_resource(dev, res); +	if 
>> (IS_ERR(regs)) { +		ret = PTR_ERR(regs); 
>>  		DRM_ERROR("Unable to get dsi registers %d\n", 
>>  ret); return ret; }  
>> +	dsi->regs = devm_regmap_init_mmio(dev, regs, 
>> &stm_dsi_regmap_config); +	if (IS_ERR(dsi->regs)) { + 
>> DRM_DEV_ERROR(dev, "Unable to create DSI regmap\n"); + 
>> return PTR_ERR(dsi->regs); +	} + 
>>  	dsi->vdd_supply = devm_regulator_get(dev, "phy-dsi"); if 
>>  (IS_ERR(dsi->vdd_supply)) { ret = PTR_ERR(dsi->vdd_supply); 
>> @@ -396,7 +416,7 @@ static int dw_mipi_dsi_stm_probe(struct 
>> platform_device *pdev) 
>>  		goto err_dsi_probe; }  
>> -	dw_mipi_dsi_stm_plat_data.base = dsi->base; + 
>> dw_mipi_dsi_stm_plat_data.regs = dsi->regs; 
>>  	dw_mipi_dsi_stm_plat_data.priv_data = dsi; 
>>  platform_set_drvdata(pdev, dsi); 
>> @@ -474,7 +494,7 @@ static struct platform_driver 
>> dw_mipi_dsi_stm_driver = { 
>>  	.remove		= dw_mipi_dsi_stm_remove, .driver 
>>  = { .of_match_table = dw_mipi_dsi_stm_dt_ids, 
>> -		.name	= "stm32-display-dsi", + 
>> .name	= DRIVER_NAME, 
>>  		.pm = &dw_mipi_dsi_stm_pm_ops, }, }; 
>> diff --git a/include/drm/bridge/dw_mipi_dsi.h 
>> b/include/drm/bridge/dw_mipi_dsi.h index 
>> 94cc64a342e1..ecc1897efa62 100644 --- 
>> a/include/drm/bridge/dw_mipi_dsi.h +++ 
>> b/include/drm/bridge/dw_mipi_dsi.h @@ -37,7 +37,7 @@ struct 
>> dw_mipi_dsi_host_ops { 
>>  };  struct dw_mipi_dsi_plat_data { 
>> -	void __iomem *base; +	struct regmap *regs; 
>>  	unsigned int max_data_lanes;  enum drm_mode_status 
>>  (*mode_valid)(void *priv_data, 
>>  
> 
> OK for the dw-mipi-dsi changes, but why should the 
> dw_mipi_dsi-stm be changed aswell ? 
> 
> AFAIK these are independent.

I don't understand how they are independent. Isn't the stm driver 
also using the same dw-mipi-dsi bridge as rockchip and now imx 
since it was first added in commit
c1c026dbc183 ("drm/stm: Add STM32 DSI controller driver") ?

I don't have the hardware to test the stm driver on a live boot, 
but compilation certainly fails if I don't modify it :)

>
> Neil
Neil Armstrong Nov. 4, 2019, 3:46 p.m. UTC | #3
Hi Adrian,

On 04/11/2019 13:03, Adrian Ratiu wrote:
> On Mon, 04 Nov 2019, Neil Armstrong <narmstrong@baylibre.com> wrote:
>> On 31/10/2019 15:26, Adrian Ratiu wrote:
>>
>> OK for the dw-mipi-dsi changes, but why should the dw_mipi_dsi-stm be changed aswell ?
>> AFAIK these are independent.
> 
> I don't understand how they are independent. Isn't the stm driver also using the same dw-mipi-dsi bridge as rockchip and now imx since it was first added in commit
> c1c026dbc183 ("drm/stm: Add STM32 DSI controller driver") ?
> 
> I don't have the hardware to test the stm driver on a live boot, but compilation certainly fails if I don't modify it :)

Ignore my comment, this patch is fine, please keep:
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>

when resending.

Neil

> 
>>
>> Neil

Patch
diff mbox series

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index b6e793bb653c..4ef3e9038cc2 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -15,6 +15,7 @@ 
 #include <linux/module.h>
 #include <linux/of_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/regmap.h>
 #include <linux/reset.h>
 
 #include <video/mipi_display.h>
@@ -226,7 +227,7 @@  struct dw_mipi_dsi {
 	struct mipi_dsi_host dsi_host;
 	struct drm_bridge *panel_bridge;
 	struct device *dev;
-	void __iomem *base;
+	struct regmap *regs;
 
 	struct clk *pclk;
 
@@ -280,16 +281,6 @@  static inline struct dw_mipi_dsi *bridge_to_dsi(struct drm_bridge *bridge)
 	return container_of(bridge, struct dw_mipi_dsi, bridge);
 }
 
-static inline void dsi_write(struct dw_mipi_dsi *dsi, u32 reg, u32 val)
-{
-	writel(val, dsi->base + reg);
-}
-
-static inline u32 dsi_read(struct dw_mipi_dsi *dsi, u32 reg)
-{
-	return readl(dsi->base + reg);
-}
-
 static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host,
 				   struct mipi_dsi_device *device)
 {
@@ -366,29 +357,29 @@  static void dw_mipi_message_config(struct dw_mipi_dsi *dsi,
 	if (lpm)
 		val |= CMD_MODE_ALL_LP;
 
-	dsi_write(dsi, DSI_LPCLK_CTRL, lpm ? 0 : PHY_TXREQUESTCLKHS);
-	dsi_write(dsi, DSI_CMD_MODE_CFG, val);
+	regmap_write(dsi->regs, DSI_LPCLK_CTRL, lpm ? 0 : PHY_TXREQUESTCLKHS);
+	regmap_write(dsi->regs, DSI_CMD_MODE_CFG, val);
 }
 
 static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)
 {
 	int ret;
-	u32 val, mask;
+	u32 val = 0, mask;
 
-	ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
-				 val, !(val & GEN_CMD_FULL), 1000,
-				 CMD_PKT_STATUS_TIMEOUT_US);
+	ret = regmap_read_poll_timeout(dsi->regs, DSI_CMD_PKT_STATUS,
+				       val, !(val & GEN_CMD_FULL), 1000,
+				       CMD_PKT_STATUS_TIMEOUT_US);
 	if (ret) {
 		dev_err(dsi->dev, "failed to get available command FIFO\n");
 		return ret;
 	}
 
-	dsi_write(dsi, DSI_GEN_HDR, hdr_val);
+	regmap_write(dsi->regs, DSI_GEN_HDR, hdr_val);
 
 	mask = GEN_CMD_EMPTY | GEN_PLD_W_EMPTY;
-	ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
-				 val, (val & mask) == mask,
-				 1000, CMD_PKT_STATUS_TIMEOUT_US);
+	ret = regmap_read_poll_timeout(dsi->regs, DSI_CMD_PKT_STATUS,
+				       val, (val & mask) == mask,
+				       1000, CMD_PKT_STATUS_TIMEOUT_US);
 	if (ret) {
 		dev_err(dsi->dev, "failed to write command FIFO\n");
 		return ret;
@@ -403,24 +394,26 @@  static int dw_mipi_dsi_write(struct dw_mipi_dsi *dsi,
 	const u8 *tx_buf = packet->payload;
 	int len = packet->payload_length, pld_data_bytes = sizeof(u32), ret;
 	__le32 word;
-	u32 val;
+	u32 val = 0;
 
 	while (len) {
 		if (len < pld_data_bytes) {
 			word = 0;
 			memcpy(&word, tx_buf, len);
-			dsi_write(dsi, DSI_GEN_PLD_DATA, le32_to_cpu(word));
+			regmap_write(dsi->regs, DSI_GEN_PLD_DATA,
+				     le32_to_cpu(word));
 			len = 0;
 		} else {
 			memcpy(&word, tx_buf, pld_data_bytes);
-			dsi_write(dsi, DSI_GEN_PLD_DATA, le32_to_cpu(word));
+			regmap_write(dsi->regs, DSI_GEN_PLD_DATA,
+				     le32_to_cpu(word));
 			tx_buf += pld_data_bytes;
 			len -= pld_data_bytes;
 		}
 
-		ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
-					 val, !(val & GEN_PLD_W_FULL), 1000,
-					 CMD_PKT_STATUS_TIMEOUT_US);
+		ret = regmap_read_poll_timeout(dsi->regs, DSI_CMD_PKT_STATUS,
+					       val, !(val & GEN_PLD_W_FULL),
+					       1000, CMD_PKT_STATUS_TIMEOUT_US);
 		if (ret) {
 			dev_err(dsi->dev,
 				"failed to get available write payload FIFO\n");
@@ -438,12 +431,12 @@  static int dw_mipi_dsi_read(struct dw_mipi_dsi *dsi,
 {
 	int i, j, ret, len = msg->rx_len;
 	u8 *buf = msg->rx_buf;
-	u32 val;
+	u32 val = 0;
 
 	/* Wait end of the read operation */
-	ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
-				 val, !(val & GEN_RD_CMD_BUSY),
-				 1000, CMD_PKT_STATUS_TIMEOUT_US);
+	ret = regmap_read_poll_timeout(dsi->regs, DSI_CMD_PKT_STATUS,
+				       val, !(val & GEN_RD_CMD_BUSY),
+				       1000, CMD_PKT_STATUS_TIMEOUT_US);
 	if (ret) {
 		dev_err(dsi->dev, "Timeout during read operation\n");
 		return ret;
@@ -451,15 +444,15 @@  static int dw_mipi_dsi_read(struct dw_mipi_dsi *dsi,
 
 	for (i = 0; i < len; i += 4) {
 		/* Read fifo must not be empty before all bytes are read */
-		ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
-					 val, !(val & GEN_PLD_R_EMPTY),
-					 1000, CMD_PKT_STATUS_TIMEOUT_US);
+		ret = regmap_read_poll_timeout(dsi->regs, DSI_CMD_PKT_STATUS,
+					       val, !(val & GEN_PLD_R_EMPTY),
+					       1000, CMD_PKT_STATUS_TIMEOUT_US);
 		if (ret) {
 			dev_err(dsi->dev, "Read payload FIFO is empty\n");
 			return ret;
 		}
 
-		val = dsi_read(dsi, DSI_GEN_PLD_DATA);
+		regmap_read(dsi->regs, DSI_GEN_PLD_DATA, &val);
 		for (j = 0; j < 4 && j + i < len; j++)
 			buf[i + j] = val >> (8 * j);
 	}
@@ -536,29 +529,29 @@  static void dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi)
 	}
 #endif /* CONFIG_DEBUG_FS */
 
-	dsi_write(dsi, DSI_VID_MODE_CFG, val);
+	regmap_write(dsi->regs, DSI_VID_MODE_CFG, val);
 }
 
 static void dw_mipi_dsi_set_mode(struct dw_mipi_dsi *dsi,
 				 unsigned long mode_flags)
 {
-	dsi_write(dsi, DSI_PWR_UP, RESET);
+	regmap_write(dsi->regs, DSI_PWR_UP, RESET);
 
 	if (mode_flags & MIPI_DSI_MODE_VIDEO) {
-		dsi_write(dsi, DSI_MODE_CFG, ENABLE_VIDEO_MODE);
+		regmap_write(dsi->regs, DSI_MODE_CFG, ENABLE_VIDEO_MODE);
 		dw_mipi_dsi_video_mode_config(dsi);
-		dsi_write(dsi, DSI_LPCLK_CTRL, PHY_TXREQUESTCLKHS);
+		regmap_write(dsi->regs, DSI_LPCLK_CTRL, PHY_TXREQUESTCLKHS);
 	} else {
-		dsi_write(dsi, DSI_MODE_CFG, ENABLE_CMD_MODE);
+		regmap_write(dsi->regs, DSI_MODE_CFG, ENABLE_CMD_MODE);
 	}
 
-	dsi_write(dsi, DSI_PWR_UP, POWERUP);
+	regmap_write(dsi->regs, DSI_PWR_UP, POWERUP);
 }
 
 static void dw_mipi_dsi_disable(struct dw_mipi_dsi *dsi)
 {
-	dsi_write(dsi, DSI_PWR_UP, RESET);
-	dsi_write(dsi, DSI_PHY_RSTZ, PHY_RSTZ);
+	regmap_write(dsi->regs, DSI_PWR_UP, RESET);
+	regmap_write(dsi->regs, DSI_PHY_RSTZ, PHY_RSTZ);
 }
 
 static void dw_mipi_dsi_init(struct dw_mipi_dsi *dsi)
@@ -573,14 +566,14 @@  static void dw_mipi_dsi_init(struct dw_mipi_dsi *dsi)
 	 */
 	u32 esc_clk_division = (dsi->lane_mbps >> 3) / 20 + 1;
 
-	dsi_write(dsi, DSI_PWR_UP, RESET);
+	regmap_write(dsi->regs, DSI_PWR_UP, RESET);
 
 	/*
 	 * TODO dw drv improvements
 	 * timeout clock division should be computed with the
 	 * high speed transmission counter timeout and byte lane...
 	 */
-	dsi_write(dsi, DSI_CLKMGR_CFG, TO_CLK_DIVISION(10) |
+	regmap_write(dsi->regs, DSI_CLKMGR_CFG, TO_CLK_DIVISION(10) |
 		  TX_ESC_CLK_DIVISION(esc_clk_division));
 }
 
@@ -609,22 +602,22 @@  static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi,
 	if (mode->flags & DRM_MODE_FLAG_NHSYNC)
 		val |= HSYNC_ACTIVE_LOW;
 
-	dsi_write(dsi, DSI_DPI_VCID, DPI_VCID(dsi->channel));
-	dsi_write(dsi, DSI_DPI_COLOR_CODING, color);
-	dsi_write(dsi, DSI_DPI_CFG_POL, val);
+	regmap_write(dsi->regs, DSI_DPI_VCID, DPI_VCID(dsi->channel));
+	regmap_write(dsi->regs, DSI_DPI_COLOR_CODING, color);
+	regmap_write(dsi->regs, DSI_DPI_CFG_POL, val);
 	/*
 	 * TODO dw drv improvements
 	 * largest packet sizes during hfp or during vsa/vpb/vfp
 	 * should be computed according to byte lane, lane number and only
 	 * if sending lp cmds in high speed is enable (PHY_TXREQUESTCLKHS)
 	 */
-	dsi_write(dsi, DSI_DPI_LP_CMD_TIM, OUTVACT_LPCMD_TIME(4)
+	regmap_write(dsi->regs, DSI_DPI_LP_CMD_TIM, OUTVACT_LPCMD_TIME(4)
 		  | INVACT_LPCMD_TIME(4));
 }
 
 static void dw_mipi_dsi_packet_handler_config(struct dw_mipi_dsi *dsi)
 {
-	dsi_write(dsi, DSI_PCKHDL_CFG, CRC_RX_EN | ECC_RX_EN | BTA_EN);
+	regmap_write(dsi->regs, DSI_PCKHDL_CFG, CRC_RX_EN | ECC_RX_EN | BTA_EN);
 }
 
 static void dw_mipi_dsi_video_packet_config(struct dw_mipi_dsi *dsi,
@@ -638,7 +631,7 @@  static void dw_mipi_dsi_video_packet_config(struct dw_mipi_dsi *dsi,
 	 * non-burst video modes, see dw_mipi_dsi_video_mode_config()...
 	 */
 
-	dsi_write(dsi, DSI_VID_PKT_SIZE,
+	regmap_write(dsi->regs, DSI_VID_PKT_SIZE,
 		       dw_mipi_is_dual_mode(dsi) ?
 				VID_PKT_SIZE(mode->hdisplay / 2) :
 				VID_PKT_SIZE(mode->hdisplay));
@@ -651,14 +644,15 @@  static void dw_mipi_dsi_command_mode_config(struct dw_mipi_dsi *dsi)
 	 * compute high speed transmission counter timeout according
 	 * to the timeout clock division (TO_CLK_DIVISION) and byte lane...
 	 */
-	dsi_write(dsi, DSI_TO_CNT_CFG, HSTX_TO_CNT(1000) | LPRX_TO_CNT(1000));
+	regmap_write(dsi->regs, DSI_TO_CNT_CFG,
+		     HSTX_TO_CNT(1000) | LPRX_TO_CNT(1000));
 	/*
 	 * TODO dw drv improvements
 	 * the Bus-Turn-Around Timeout Counter should be computed
 	 * according to byte lane...
 	 */
-	dsi_write(dsi, DSI_BTA_TO_CNT, 0xd00);
-	dsi_write(dsi, DSI_MODE_CFG, ENABLE_CMD_MODE);
+	regmap_write(dsi->regs, DSI_BTA_TO_CNT, 0xd00);
+	regmap_write(dsi->regs, DSI_MODE_CFG, ENABLE_CMD_MODE);
 }
 
 /* Get lane byte clock cycles. */
@@ -692,13 +686,13 @@  static void dw_mipi_dsi_line_timer_config(struct dw_mipi_dsi *dsi,
 	 * computations below may be improved...
 	 */
 	lbcc = dw_mipi_dsi_get_hcomponent_lbcc(dsi, mode, htotal);
-	dsi_write(dsi, DSI_VID_HLINE_TIME, lbcc);
+	regmap_write(dsi->regs, DSI_VID_HLINE_TIME, lbcc);
 
 	lbcc = dw_mipi_dsi_get_hcomponent_lbcc(dsi, mode, hsa);
-	dsi_write(dsi, DSI_VID_HSA_TIME, lbcc);
+	regmap_write(dsi->regs, DSI_VID_HSA_TIME, lbcc);
 
 	lbcc = dw_mipi_dsi_get_hcomponent_lbcc(dsi, mode, hbp);
-	dsi_write(dsi, DSI_VID_HBP_TIME, lbcc);
+	regmap_write(dsi->regs, DSI_VID_HBP_TIME, lbcc);
 }
 
 static void dw_mipi_dsi_vertical_timing_config(struct dw_mipi_dsi *dsi,
@@ -711,10 +705,10 @@  static void dw_mipi_dsi_vertical_timing_config(struct dw_mipi_dsi *dsi,
 	vfp = mode->vsync_start - mode->vdisplay;
 	vbp = mode->vtotal - mode->vsync_end;
 
-	dsi_write(dsi, DSI_VID_VACTIVE_LINES, vactive);
-	dsi_write(dsi, DSI_VID_VSA_LINES, vsa);
-	dsi_write(dsi, DSI_VID_VFP_LINES, vfp);
-	dsi_write(dsi, DSI_VID_VBP_LINES, vbp);
+	regmap_write(dsi->regs, DSI_VID_VACTIVE_LINES, vactive);
+	regmap_write(dsi->regs, DSI_VID_VSA_LINES, vsa);
+	regmap_write(dsi->regs, DSI_VID_VFP_LINES, vfp);
+	regmap_write(dsi->regs, DSI_VID_VBP_LINES, vbp);
 }
 
 static void dw_mipi_dsi_dphy_timing_config(struct dw_mipi_dsi *dsi)
@@ -729,19 +723,24 @@  static void dw_mipi_dsi_dphy_timing_config(struct dw_mipi_dsi *dsi)
 	 * DSI_CMD_MODE_CFG.MAX_RD_PKT_SIZE_LP (see CMD_MODE_ALL_LP)
 	 */
 
-	hw_version = dsi_read(dsi, DSI_VERSION) & VERSION;
+	regmap_read(dsi->regs, DSI_VERSION, &hw_version);
+	hw_version &= VERSION;
 
 	if (hw_version >= HWVER_131) {
-		dsi_write(dsi, DSI_PHY_TMR_CFG, PHY_HS2LP_TIME_V131(0x40) |
-			  PHY_LP2HS_TIME_V131(0x40));
-		dsi_write(dsi, DSI_PHY_TMR_RD_CFG, MAX_RD_TIME_V131(10000));
+		regmap_write(dsi->regs, DSI_PHY_TMR_CFG,
+			     PHY_HS2LP_TIME_V131(0x40) |
+			     PHY_LP2HS_TIME_V131(0x40));
+		regmap_write(dsi->regs, DSI_PHY_TMR_RD_CFG,
+			     MAX_RD_TIME_V131(10000));
 	} else {
-		dsi_write(dsi, DSI_PHY_TMR_CFG, PHY_HS2LP_TIME(0x40) |
-			  PHY_LP2HS_TIME(0x40) | MAX_RD_TIME(10000));
+		regmap_write(dsi->regs, DSI_PHY_TMR_CFG,
+			     PHY_HS2LP_TIME(0x40) |
+			     PHY_LP2HS_TIME(0x40) |
+			     MAX_RD_TIME(10000));
 	}
 
-	dsi_write(dsi, DSI_PHY_TMR_LPCLK_CFG, PHY_CLKHS2LP_TIME(0x40)
-		  | PHY_CLKLP2HS_TIME(0x40));
+	regmap_write(dsi->regs, DSI_PHY_TMR_LPCLK_CFG,
+		     PHY_CLKHS2LP_TIME(0x40) | PHY_CLKLP2HS_TIME(0x40));
 }
 
 static void dw_mipi_dsi_dphy_interface_config(struct dw_mipi_dsi *dsi)
@@ -751,46 +750,49 @@  static void dw_mipi_dsi_dphy_interface_config(struct dw_mipi_dsi *dsi)
 	 * stop wait time should be the maximum between host dsi
 	 * and panel stop wait times
 	 */
-	dsi_write(dsi, DSI_PHY_IF_CFG, PHY_STOP_WAIT_TIME(0x20) |
-		  N_LANES(dsi->lanes));
+	regmap_write(dsi->regs, DSI_PHY_IF_CFG,
+		     PHY_STOP_WAIT_TIME(0x20) | N_LANES(dsi->lanes));
 }
 
 static void dw_mipi_dsi_dphy_init(struct dw_mipi_dsi *dsi)
 {
 	/* Clear PHY state */
-	dsi_write(dsi, DSI_PHY_RSTZ, PHY_DISFORCEPLL | PHY_DISABLECLK
-		  | PHY_RSTZ | PHY_SHUTDOWNZ);
-	dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_UNTESTCLR);
-	dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_TESTCLR);
-	dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_UNTESTCLR);
+	regmap_write(dsi->regs, DSI_PHY_RSTZ, PHY_DISFORCEPLL | PHY_DISABLECLK
+		     | PHY_RSTZ | PHY_SHUTDOWNZ);
+	regmap_write(dsi->regs, DSI_PHY_TST_CTRL0, PHY_UNTESTCLR);
+	regmap_write(dsi->regs, DSI_PHY_TST_CTRL0, PHY_TESTCLR);
+	regmap_write(dsi->regs, DSI_PHY_TST_CTRL0, PHY_UNTESTCLR);
 }
 
 static void dw_mipi_dsi_dphy_enable(struct dw_mipi_dsi *dsi)
 {
-	u32 val;
+	u32 val = 0;
 	int ret;
 
-	dsi_write(dsi, DSI_PHY_RSTZ, PHY_ENFORCEPLL | PHY_ENABLECLK |
-		  PHY_UNRSTZ | PHY_UNSHUTDOWNZ);
+	regmap_write(dsi->regs, DSI_PHY_RSTZ, PHY_ENFORCEPLL | PHY_ENABLECLK |
+		     PHY_UNRSTZ | PHY_UNSHUTDOWNZ);
 
-	ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS, val,
-				 val & PHY_LOCK, 1000, PHY_STATUS_TIMEOUT_US);
+	ret = regmap_read_poll_timeout(dsi->regs, DSI_PHY_STATUS,
+				       val, val & PHY_LOCK,
+				       1000, PHY_STATUS_TIMEOUT_US);
 	if (ret)
 		DRM_DEBUG_DRIVER("failed to wait phy lock state\n");
 
-	ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS,
-				 val, val & PHY_STOP_STATE_CLK_LANE, 1000,
-				 PHY_STATUS_TIMEOUT_US);
+	ret = regmap_read_poll_timeout(dsi->regs, DSI_PHY_STATUS,
+				       val, val & PHY_STOP_STATE_CLK_LANE, 1000,
+				       PHY_STATUS_TIMEOUT_US);
 	if (ret)
 		DRM_DEBUG_DRIVER("failed to wait phy clk lane stop state\n");
 }
 
 static void dw_mipi_dsi_clear_err(struct dw_mipi_dsi *dsi)
 {
-	dsi_read(dsi, DSI_INT_ST0);
-	dsi_read(dsi, DSI_INT_ST1);
-	dsi_write(dsi, DSI_INT_MSK0, 0);
-	dsi_write(dsi, DSI_INT_MSK1, 0);
+	u32 val;
+
+	regmap_read(dsi->regs, DSI_INT_ST0, &val);
+	regmap_read(dsi->regs, DSI_INT_ST1, &val);
+	regmap_write(dsi->regs, DSI_INT_MSK0, 0);
+	regmap_write(dsi->regs, DSI_INT_MSK1, 0);
 }
 
 static void dw_mipi_dsi_bridge_post_disable(struct drm_bridge *bridge)
@@ -996,13 +998,10 @@  __dw_mipi_dsi_probe(struct platform_device *pdev,
 		return ERR_PTR(-ENODEV);
 	}
 
-	if (!plat_data->base) {
-		dsi->base = devm_platform_ioremap_resource(pdev, 0);
-		if (IS_ERR(dsi->base))
-			return ERR_PTR(-ENODEV);
-
-	} else {
-		dsi->base = plat_data->base;
+	dsi->regs = plat_data->regs;
+	if (!dsi->regs) {
+		DRM_ERROR("DSI regmap not supplied by platform driver\n");
+		return ERR_PTR(-ENODEV);
 	}
 
 	dsi->pclk = devm_clk_get(dev, "pclk");
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
index bc073ec5c183..3c33ed1fa805 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
@@ -24,6 +24,8 @@ 
 #include "rockchip_drm_drv.h"
 #include "rockchip_drm_vop.h"
 
+#define DRIVER_NAME "dw-mipi-dsi-rockchip"
+
 #define DSI_PHY_RSTZ			0xa0
 #define PHY_DISFORCEPLL			0
 #define PHY_ENFORCEPLL			BIT(3)
@@ -212,7 +214,7 @@  struct rockchip_dw_dsi_chip_data {
 struct dw_mipi_dsi_rockchip {
 	struct device *dev;
 	struct drm_encoder encoder;
-	void __iomem *base;
+	struct regmap *regs;
 
 	struct regmap *grf_regmap;
 	struct clk *pllref_clk;
@@ -297,12 +299,15 @@  static int max_mbps_to_parameter(unsigned int max_mbps)
 
 static inline void dsi_write(struct dw_mipi_dsi_rockchip *dsi, u32 reg, u32 val)
 {
-	writel(val, dsi->base + reg);
+	regmap_write(dsi->regs, reg, val);
 }
 
 static inline u32 dsi_read(struct dw_mipi_dsi_rockchip *dsi, u32 reg)
 {
-	return readl(dsi->base + reg);
+	u32 val;
+
+	regmap_read(dsi->regs, reg, &val);
+	return val;
 }
 
 static inline void dsi_set(struct dw_mipi_dsi_rockchip *dsi, u32 reg, u32 mask)
@@ -884,6 +889,13 @@  static const struct dw_mipi_dsi_host_ops dw_mipi_dsi_rockchip_host_ops = {
 	.detach = dw_mipi_dsi_rockchip_host_detach,
 };
 
+static const struct regmap_config rockchip_dsi_regmap_config = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+	.name = DRIVER_NAME,
+};
+
 static int dw_mipi_dsi_rockchip_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -892,6 +904,7 @@  static int dw_mipi_dsi_rockchip_probe(struct platform_device *pdev)
 	struct resource *res;
 	const struct rockchip_dw_dsi_chip_data *cdata =
 				of_device_get_match_data(dev);
+	void __iomem *regs;
 	int ret, i;
 
 	dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
@@ -899,10 +912,17 @@  static int dw_mipi_dsi_rockchip_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	dsi->base = devm_ioremap_resource(dev, res);
-	if (IS_ERR(dsi->base)) {
+	regs = devm_ioremap_resource(dev, res);
+	if (IS_ERR(regs)) {
 		DRM_DEV_ERROR(dev, "Unable to get dsi registers\n");
-		return PTR_ERR(dsi->base);
+		return PTR_ERR(regs);
+	}
+
+	dsi->regs = devm_regmap_init_mmio(dev, regs,
+					  &rockchip_dsi_regmap_config);
+	if (IS_ERR(dsi->regs)) {
+		DRM_DEV_ERROR(dev, "Unable to create DSI regmap\n");
+		return PTR_ERR(dsi->regs);
 	}
 
 	i = 0;
@@ -954,7 +974,7 @@  static int dw_mipi_dsi_rockchip_probe(struct platform_device *pdev)
 	}
 
 	dsi->dev = dev;
-	dsi->pdata.base = dsi->base;
+	dsi->pdata.regs = dsi->regs;
 	dsi->pdata.max_data_lanes = dsi->cdata->max_data_lanes;
 	dsi->pdata.phy_ops = &dw_mipi_dsi_rockchip_phy_ops;
 	dsi->pdata.host_ops = &dw_mipi_dsi_rockchip_host_ops;
@@ -1072,6 +1092,6 @@  struct platform_driver dw_mipi_dsi_rockchip_driver = {
 	.remove		= dw_mipi_dsi_rockchip_remove,
 	.driver		= {
 		.of_match_table = dw_mipi_dsi_rockchip_dt_ids,
-		.name	= "dw-mipi-dsi-rockchip",
+		.name	= DRIVER_NAME,
 	},
 };
diff --git a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
index 514efefb0016..cc233271347b 100644
--- a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
+++ b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
@@ -12,6 +12,7 @@ 
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
+#include <linux/regmap.h>
 
 #include <video/mipi_display.h>
 
@@ -19,6 +20,8 @@ 
 #include <drm/drm_mipi_dsi.h>
 #include <drm/drm_print.h>
 
+#define DRIVER_NAME "stm32-display-dsi"
+
 #define HWVER_130			0x31333000	/* IP version 1.30 */
 #define HWVER_131			0x31333100	/* IP version 1.31 */
 
@@ -75,7 +78,7 @@  enum dsi_color {
 #define TIMEOUT_US	200000
 
 struct dw_mipi_dsi_stm {
-	void __iomem *base;
+	struct regmap *regs;
 	struct clk *pllref_clk;
 	struct dw_mipi_dsi *dsi;
 	u32 hw_version;
@@ -86,12 +89,15 @@  struct dw_mipi_dsi_stm {
 
 static inline void dsi_write(struct dw_mipi_dsi_stm *dsi, u32 reg, u32 val)
 {
-	writel(val, dsi->base + reg);
+	regmap_write(dsi->regs, reg, val);
 }
 
 static inline u32 dsi_read(struct dw_mipi_dsi_stm *dsi, u32 reg)
 {
-	return readl(dsi->base + reg);
+	u32 val;
+
+	regmap_read(dsi->regs, reg, &val);
+	return val;
 }
 
 static inline void dsi_set(struct dw_mipi_dsi_stm *dsi, u32 reg, u32 mask)
@@ -202,15 +208,15 @@  static int dw_mipi_dsi_phy_init(void *priv_data)
 
 	/* Enable the regulator */
 	dsi_set(dsi, DSI_WRPCR, WRPCR_REGEN | WRPCR_BGREN);
-	ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & WISR_RRS,
-				 SLEEP_US, TIMEOUT_US);
+	ret = regmap_read_poll_timeout(dsi->regs, DSI_WISR, val, val & WISR_RRS,
+				       SLEEP_US, TIMEOUT_US);
 	if (ret)
 		DRM_DEBUG_DRIVER("!TIMEOUT! waiting REGU, let's continue\n");
 
 	/* Enable the DSI PLL & wait for its lock */
 	dsi_set(dsi, DSI_WRPCR, WRPCR_PLLEN);
-	ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & WISR_PLLLS,
-				 SLEEP_US, TIMEOUT_US);
+	ret = regmap_read_poll_timeout(dsi->regs, DSI_WISR, val,
+				       val & WISR_PLLLS, SLEEP_US, TIMEOUT_US);
 	if (ret)
 		DRM_DEBUG_DRIVER("!TIMEOUT! waiting PLL, let's continue\n");
 
@@ -327,12 +333,20 @@  static const struct of_device_id dw_mipi_dsi_stm_dt_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, dw_mipi_dsi_stm_dt_ids);
 
+static const struct regmap_config stm_dsi_regmap_config = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+	.name = DRIVER_NAME,
+};
+
 static int dw_mipi_dsi_stm_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct dw_mipi_dsi_stm *dsi;
 	struct clk *pclk;
 	struct resource *res;
+	void __iomem *regs;
 	int ret;
 
 	dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
@@ -340,13 +354,19 @@  static int dw_mipi_dsi_stm_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	dsi->base = devm_ioremap_resource(dev, res);
-	if (IS_ERR(dsi->base)) {
-		ret = PTR_ERR(dsi->base);
+	regs = devm_ioremap_resource(dev, res);
+	if (IS_ERR(regs)) {
+		ret = PTR_ERR(regs);
 		DRM_ERROR("Unable to get dsi registers %d\n", ret);
 		return ret;
 	}
 
+	dsi->regs = devm_regmap_init_mmio(dev, regs, &stm_dsi_regmap_config);
+	if (IS_ERR(dsi->regs)) {
+		DRM_DEV_ERROR(dev, "Unable to create DSI regmap\n");
+		return PTR_ERR(dsi->regs);
+	}
+
 	dsi->vdd_supply = devm_regulator_get(dev, "phy-dsi");
 	if (IS_ERR(dsi->vdd_supply)) {
 		ret = PTR_ERR(dsi->vdd_supply);
@@ -396,7 +416,7 @@  static int dw_mipi_dsi_stm_probe(struct platform_device *pdev)
 		goto err_dsi_probe;
 	}
 
-	dw_mipi_dsi_stm_plat_data.base = dsi->base;
+	dw_mipi_dsi_stm_plat_data.regs = dsi->regs;
 	dw_mipi_dsi_stm_plat_data.priv_data = dsi;
 
 	platform_set_drvdata(pdev, dsi);
@@ -474,7 +494,7 @@  static struct platform_driver dw_mipi_dsi_stm_driver = {
 	.remove		= dw_mipi_dsi_stm_remove,
 	.driver		= {
 		.of_match_table = dw_mipi_dsi_stm_dt_ids,
-		.name	= "stm32-display-dsi",
+		.name	= DRIVER_NAME,
 		.pm = &dw_mipi_dsi_stm_pm_ops,
 	},
 };
diff --git a/include/drm/bridge/dw_mipi_dsi.h b/include/drm/bridge/dw_mipi_dsi.h
index 94cc64a342e1..ecc1897efa62 100644
--- a/include/drm/bridge/dw_mipi_dsi.h
+++ b/include/drm/bridge/dw_mipi_dsi.h
@@ -37,7 +37,7 @@  struct dw_mipi_dsi_host_ops {
 };
 
 struct dw_mipi_dsi_plat_data {
-	void __iomem *base;
+	struct regmap *regs;
 	unsigned int max_data_lanes;
 
 	enum drm_mode_status (*mode_valid)(void *priv_data,