Re: [PATCH v3 6/6] drm/stm: Add STM32 DSI host driver
On 06/06/2017 01:41 PM, Neil Armstrong wrote: Hi Philippe, On 06/02/2017 04:37 PM, Philippe CORNU wrote: Add the STM32 DSI host driver that uses the Synopsys DesignWare MIPI DSI DRM bridge. Signed-off-by: Philippe CORNU--- drivers/gpu/drm/stm/Kconfig | 8 + drivers/gpu/drm/stm/Makefile | 2 + drivers/gpu/drm/stm/dw_mipi_dsi-stm.c | 353 ++ 3 files changed, 363 insertions(+) create mode 100644 drivers/gpu/drm/stm/dw_mipi_dsi-stm.c diff --git a/drivers/gpu/drm/stm/Kconfig b/drivers/gpu/drm/stm/Kconfig index 4b88223..4c0d670 100644 --- a/drivers/gpu/drm/stm/Kconfig +++ b/drivers/gpu/drm/stm/Kconfig @@ -14,3 +14,11 @@ config DRM_STM STMicroelectronics STM32 MCUs. To compile this driver as a module, choose M here: the module will be called stm-drm. + +config DRM_STM_DSI + tristate "STMicroelectronics specific extensions for Synopsys MIPI DSI" + depends on DRM_STM + select DRM_MIPI_DSI + select DRM_DW_MIPI_DSI + help + Choose this option for MIPI DSI support on STMicroelectronics SoC. diff --git a/drivers/gpu/drm/stm/Makefile b/drivers/gpu/drm/stm/Makefile index a09ecf4..d883adc 100644 --- a/drivers/gpu/drm/stm/Makefile +++ b/drivers/gpu/drm/stm/Makefile @@ -2,4 +2,6 @@ stm-drm-y := \ drv.o \ ltdc.o +obj-$(CONFIG_DRM_STM_DSI) += dw_mipi_dsi-stm.o + obj-$(CONFIG_DRM_STM) += stm-drm.o diff --git a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c new file mode 100644 index 000..8dedc5c --- /dev/null +++ b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c @@ -0,0 +1,353 @@ +/* + * Copyright (C) STMicroelectronics SA 2017 + * + * Authors: Philippe Cornu + * Yannick Fertre + * + * License terms: GNU General Public License (GPL), version 2 + */ + +#include +#include +#include We don't seem to use any math64 funcs. +#include +#include +#include +#include +#include + +/* DSI wrapper register & bit definitions */ +/* Note: registers are named as in the Reference Manual */ +#define DSI_WCFGR 0x0400 /* Wrapper ConFiGuration Reg */ +#define WCFGR_DSIM BIT(0) /* DSI Mode */ +#define WCFGR_COLMUX GENMASK(3, 1) /* COLor MUltipleXing */ + +#define DSI_WCR0x0404 /* Wrapper Control Reg */ +#define WCR_DSIEN BIT(3) /* DSI ENable */ + +#define DSI_WISR 0x040C /* Wrapper Interrupt and Status Reg */ +#define WISR_PLLLS BIT(8) /* PLL Lock Status */ +#define WISR_RRS BIT(12) /* Regulator Ready Status */ + +#define DSI_WPCR0 0x0418 /* Wrapper Phy Conf Reg 0 */ +#define WPCR0_UIX4 GENMASK(5, 0) /* Unit Interval X 4 */ +#define WPCR0_TDDL BIT(16) /* Turn Disable Data Lanes */ + +#define DSI_WRPCR 0x0430 /* Wrapper Regulator & Pll Ctrl Reg */ +#define WRPCR_PLLENBIT(0) /* PLL ENable */ +#define WRPCR_NDIV GENMASK(8, 2) /* pll loop DIVision Factor */ +#define WRPCR_IDF GENMASK(14, 11) /* pll Input Division Factor */ +#define WRPCR_ODF GENMASK(17, 16) /* pll Output Division Factor */ +#define WRPCR_REGENBIT(24) /* REGulator ENable */ +#define WRPCR_BGRENBIT(28) /* BandGap Reference ENable */ +#define IDF_MIN1 +#define IDF_MAX7 +#define NDIV_MIN 10 +#define NDIV_MAX 125 +#define ODF_MIN1 +#define ODF_MAX8 + +/* dsi color format coding according to the datasheet */ +enum dsi_color { + DSI_RGB565_CONF1, + DSI_RGB565_CONF2, + DSI_RGB565_CONF3, + DSI_RGB666_CONF1, + DSI_RGB666_CONF2, + DSI_RGB888, +}; + +#define LANE_MIN_KBPS 31250 +#define LANE_MAX_KBPS 50 + +/* Sleep & timeout for regulator on/off, pll lock/unlock & fifo empty */ +#define SLEEP_US 1000 +#define TIMEOUT_US 20 + +struct dw_mipi_dsi_stm { + void __iomem *base; + struct clk *pllref_clk; +}; + +static inline void dsi_write(struct dw_mipi_dsi_stm *dsi, u32 reg, u32 val) +{ + writel_relaxed(val, dsi->base + reg); +} + +static inline u32 dsi_read(struct dw_mipi_dsi_stm *dsi, u32 reg) +{ + return readl_relaxed(dsi->base + reg); +} + +static inline void dsi_set(struct dw_mipi_dsi_stm *dsi, u32 reg, u32 mask) +{ + dsi_write(dsi, reg, dsi_read(dsi, reg) | mask); +} + +static inline void dsi_clear(struct dw_mipi_dsi_stm *dsi, u32 reg, u32 mask) +{ + dsi_write(dsi, reg, dsi_read(dsi, reg) & ~mask); +} + +static inline void dsi_update_bits(struct dw_mipi_dsi_stm *dsi, u32 reg, + u32 mask, u32 val) +{ + dsi_write(dsi, reg, (dsi_read(dsi, reg) & ~mask) | val); +} + +static enum dsi_color dsi_color_from_mipi(enum mipi_dsi_pixel_format fmt) +{ + switch (fmt) { + case MIPI_DSI_FMT_RGB888: +
Re: [PATCH v3 6/6] drm/stm: Add STM32 DSI host driver
Hi Philippe, On 06/02/2017 04:37 PM, Philippe CORNU wrote: > Add the STM32 DSI host driver that uses the Synopsys DesignWare > MIPI DSI DRM bridge. > > Signed-off-by: Philippe CORNU> --- > drivers/gpu/drm/stm/Kconfig | 8 + > drivers/gpu/drm/stm/Makefile | 2 + > drivers/gpu/drm/stm/dw_mipi_dsi-stm.c | 353 > ++ > 3 files changed, 363 insertions(+) > create mode 100644 drivers/gpu/drm/stm/dw_mipi_dsi-stm.c > > diff --git a/drivers/gpu/drm/stm/Kconfig b/drivers/gpu/drm/stm/Kconfig > index 4b88223..4c0d670 100644 > --- a/drivers/gpu/drm/stm/Kconfig > +++ b/drivers/gpu/drm/stm/Kconfig > @@ -14,3 +14,11 @@ config DRM_STM > STMicroelectronics STM32 MCUs. > To compile this driver as a module, choose M here: the module > will be called stm-drm. > + > +config DRM_STM_DSI > + tristate "STMicroelectronics specific extensions for Synopsys MIPI DSI" > + depends on DRM_STM > + select DRM_MIPI_DSI > + select DRM_DW_MIPI_DSI > + help > + Choose this option for MIPI DSI support on STMicroelectronics SoC. > diff --git a/drivers/gpu/drm/stm/Makefile b/drivers/gpu/drm/stm/Makefile > index a09ecf4..d883adc 100644 > --- a/drivers/gpu/drm/stm/Makefile > +++ b/drivers/gpu/drm/stm/Makefile > @@ -2,4 +2,6 @@ stm-drm-y := \ > drv.o \ > ltdc.o > > +obj-$(CONFIG_DRM_STM_DSI) += dw_mipi_dsi-stm.o > + > obj-$(CONFIG_DRM_STM) += stm-drm.o > diff --git a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c > b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c > new file mode 100644 > index 000..8dedc5c > --- /dev/null > +++ b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c > @@ -0,0 +1,353 @@ > +/* > + * Copyright (C) STMicroelectronics SA 2017 > + * > + * Authors: Philippe Cornu > + * Yannick Fertre > + * > + * License terms: GNU General Public License (GPL), version 2 > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/* DSI wrapper register & bit definitions */ > +/* Note: registers are named as in the Reference Manual */ > +#define DSI_WCFGR0x0400 /* Wrapper ConFiGuration Reg */ > +#define WCFGR_DSIM BIT(0) /* DSI Mode */ > +#define WCFGR_COLMUX GENMASK(3, 1) /* COLor MUltipleXing */ > + > +#define DSI_WCR 0x0404 /* Wrapper Control Reg */ > +#define WCR_DSIENBIT(3) /* DSI ENable */ > + > +#define DSI_WISR 0x040C /* Wrapper Interrupt and Status Reg */ > +#define WISR_PLLLS BIT(8) /* PLL Lock Status */ > +#define WISR_RRS BIT(12) /* Regulator Ready Status */ > + > +#define DSI_WPCR00x0418 /* Wrapper Phy Conf Reg 0 */ > +#define WPCR0_UIX4 GENMASK(5, 0) /* Unit Interval X 4 */ > +#define WPCR0_TDDL BIT(16) /* Turn Disable Data Lanes */ > + > +#define DSI_WRPCR0x0430 /* Wrapper Regulator & Pll Ctrl Reg */ > +#define WRPCR_PLLEN BIT(0) /* PLL ENable */ > +#define WRPCR_NDIV GENMASK(8, 2) /* pll loop DIVision Factor */ > +#define WRPCR_IDFGENMASK(14, 11) /* pll Input Division Factor */ > +#define WRPCR_ODFGENMASK(17, 16) /* pll Output Division Factor */ > +#define WRPCR_REGEN BIT(24) /* REGulator ENable */ > +#define WRPCR_BGREN BIT(28) /* BandGap Reference ENable */ > +#define IDF_MIN 1 > +#define IDF_MAX 7 > +#define NDIV_MIN 10 > +#define NDIV_MAX 125 > +#define ODF_MIN 1 > +#define ODF_MAX 8 > + > +/* dsi color format coding according to the datasheet */ > +enum dsi_color { > + DSI_RGB565_CONF1, > + DSI_RGB565_CONF2, > + DSI_RGB565_CONF3, > + DSI_RGB666_CONF1, > + DSI_RGB666_CONF2, > + DSI_RGB888, > +}; > + > +#define LANE_MIN_KBPS31250 > +#define LANE_MAX_KBPS50 > + > +/* Sleep & timeout for regulator on/off, pll lock/unlock & fifo empty */ > +#define SLEEP_US 1000 > +#define TIMEOUT_US 20 > + > +struct dw_mipi_dsi_stm { > + void __iomem *base; > + struct clk *pllref_clk; > +}; > + > +static inline void dsi_write(struct dw_mipi_dsi_stm *dsi, u32 reg, u32 val) > +{ > + writel_relaxed(val, dsi->base + reg); > +} > + > +static inline u32 dsi_read(struct dw_mipi_dsi_stm *dsi, u32 reg) > +{ > + return readl_relaxed(dsi->base + reg); > +} > + > +static inline void dsi_set(struct dw_mipi_dsi_stm *dsi, u32 reg, u32 mask) > +{ > + dsi_write(dsi, reg, dsi_read(dsi, reg) | mask); > +} > + > +static inline void dsi_clear(struct dw_mipi_dsi_stm *dsi, u32 reg, u32 mask) > +{ > + dsi_write(dsi, reg, dsi_read(dsi, reg) & ~mask); > +} > + > +static inline void dsi_update_bits(struct dw_mipi_dsi_stm *dsi, u32 reg, > +u32 mask, u32 val) > +{ > + dsi_write(dsi, reg, (dsi_read(dsi, reg) & ~mask) | val); > +} > + > +static enum dsi_color dsi_color_from_mipi(enum
[PATCH v3 6/6] drm/stm: Add STM32 DSI host driver
Add the STM32 DSI host driver that uses the Synopsys DesignWare MIPI DSI DRM bridge. Signed-off-by: Philippe CORNU--- drivers/gpu/drm/stm/Kconfig | 8 + drivers/gpu/drm/stm/Makefile | 2 + drivers/gpu/drm/stm/dw_mipi_dsi-stm.c | 353 ++ 3 files changed, 363 insertions(+) create mode 100644 drivers/gpu/drm/stm/dw_mipi_dsi-stm.c diff --git a/drivers/gpu/drm/stm/Kconfig b/drivers/gpu/drm/stm/Kconfig index 4b88223..4c0d670 100644 --- a/drivers/gpu/drm/stm/Kconfig +++ b/drivers/gpu/drm/stm/Kconfig @@ -14,3 +14,11 @@ config DRM_STM STMicroelectronics STM32 MCUs. To compile this driver as a module, choose M here: the module will be called stm-drm. + +config DRM_STM_DSI + tristate "STMicroelectronics specific extensions for Synopsys MIPI DSI" + depends on DRM_STM + select DRM_MIPI_DSI + select DRM_DW_MIPI_DSI + help + Choose this option for MIPI DSI support on STMicroelectronics SoC. diff --git a/drivers/gpu/drm/stm/Makefile b/drivers/gpu/drm/stm/Makefile index a09ecf4..d883adc 100644 --- a/drivers/gpu/drm/stm/Makefile +++ b/drivers/gpu/drm/stm/Makefile @@ -2,4 +2,6 @@ stm-drm-y := \ drv.o \ ltdc.o +obj-$(CONFIG_DRM_STM_DSI) += dw_mipi_dsi-stm.o + obj-$(CONFIG_DRM_STM) += stm-drm.o diff --git a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c new file mode 100644 index 000..8dedc5c --- /dev/null +++ b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c @@ -0,0 +1,353 @@ +/* + * Copyright (C) STMicroelectronics SA 2017 + * + * Authors: Philippe Cornu + * Yannick Fertre + * + * License terms: GNU General Public License (GPL), version 2 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* DSI wrapper register & bit definitions */ +/* Note: registers are named as in the Reference Manual */ +#define DSI_WCFGR 0x0400 /* Wrapper ConFiGuration Reg */ +#define WCFGR_DSIM BIT(0) /* DSI Mode */ +#define WCFGR_COLMUX GENMASK(3, 1) /* COLor MUltipleXing */ + +#define DSI_WCR0x0404 /* Wrapper Control Reg */ +#define WCR_DSIEN BIT(3) /* DSI ENable */ + +#define DSI_WISR 0x040C /* Wrapper Interrupt and Status Reg */ +#define WISR_PLLLS BIT(8) /* PLL Lock Status */ +#define WISR_RRS BIT(12) /* Regulator Ready Status */ + +#define DSI_WPCR0 0x0418 /* Wrapper Phy Conf Reg 0 */ +#define WPCR0_UIX4 GENMASK(5, 0) /* Unit Interval X 4 */ +#define WPCR0_TDDL BIT(16) /* Turn Disable Data Lanes */ + +#define DSI_WRPCR 0x0430 /* Wrapper Regulator & Pll Ctrl Reg */ +#define WRPCR_PLLENBIT(0) /* PLL ENable */ +#define WRPCR_NDIV GENMASK(8, 2) /* pll loop DIVision Factor */ +#define WRPCR_IDF GENMASK(14, 11) /* pll Input Division Factor */ +#define WRPCR_ODF GENMASK(17, 16) /* pll Output Division Factor */ +#define WRPCR_REGENBIT(24) /* REGulator ENable */ +#define WRPCR_BGRENBIT(28) /* BandGap Reference ENable */ +#define IDF_MIN1 +#define IDF_MAX7 +#define NDIV_MIN 10 +#define NDIV_MAX 125 +#define ODF_MIN1 +#define ODF_MAX8 + +/* dsi color format coding according to the datasheet */ +enum dsi_color { + DSI_RGB565_CONF1, + DSI_RGB565_CONF2, + DSI_RGB565_CONF3, + DSI_RGB666_CONF1, + DSI_RGB666_CONF2, + DSI_RGB888, +}; + +#define LANE_MIN_KBPS 31250 +#define LANE_MAX_KBPS 50 + +/* Sleep & timeout for regulator on/off, pll lock/unlock & fifo empty */ +#define SLEEP_US 1000 +#define TIMEOUT_US 20 + +struct dw_mipi_dsi_stm { + void __iomem *base; + struct clk *pllref_clk; +}; + +static inline void dsi_write(struct dw_mipi_dsi_stm *dsi, u32 reg, u32 val) +{ + writel_relaxed(val, dsi->base + reg); +} + +static inline u32 dsi_read(struct dw_mipi_dsi_stm *dsi, u32 reg) +{ + return readl_relaxed(dsi->base + reg); +} + +static inline void dsi_set(struct dw_mipi_dsi_stm *dsi, u32 reg, u32 mask) +{ + dsi_write(dsi, reg, dsi_read(dsi, reg) | mask); +} + +static inline void dsi_clear(struct dw_mipi_dsi_stm *dsi, u32 reg, u32 mask) +{ + dsi_write(dsi, reg, dsi_read(dsi, reg) & ~mask); +} + +static inline void dsi_update_bits(struct dw_mipi_dsi_stm *dsi, u32 reg, + u32 mask, u32 val) +{ + dsi_write(dsi, reg, (dsi_read(dsi, reg) & ~mask) | val); +} + +static enum dsi_color dsi_color_from_mipi(enum mipi_dsi_pixel_format fmt) +{ + switch (fmt) { + case MIPI_DSI_FMT_RGB888: + return DSI_RGB888; + case MIPI_DSI_FMT_RGB666: + return DSI_RGB666_CONF2; + case MIPI_DSI_FMT_RGB666_PACKED: + return