Re: [PATCH v6 1/2] drm/bridge: Add Cadence DSI driver
On Saturday 21 April 2018 11:50 AM, Boris Brezillon wrote: Hi Archit, On Sun, 15 Apr 2018 13:39:44 +0530 Archit Tanejawrote: +static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy, +struct cdns_dphy_cfg *cfg, +unsigned int dpi_htotal, +unsigned int dpi_bpp, +unsigned int dpi_hz, +unsigned int dsi_htotal, +unsigned int dsi_nlanes, +unsigned int *dsi_hfp_ext) +{ + u64 dlane_bps, dlane_bps_max, fbdiv, fbdiv_max, adj_dsi_htotal; + unsigned long pll_ref_hz = clk_get_rate(dphy->pll_ref_clk); + + memset(cfg, 0, sizeof(*cfg)); + + cfg->nlanes = dsi_nlanes; + + if (pll_ref_hz < 960 || pll_ref_hz >= 15000) + return -EINVAL; + else if (pll_ref_hz < 1920) + cfg->pll_ipdiv = 1; + else if (pll_ref_hz < 3840) + cfg->pll_ipdiv = 2; + else if (pll_ref_hz < 7680) + cfg->pll_ipdiv = 4; + else + cfg->pll_ipdiv = 8; + + /* +* Make sure DSI htotal is aligned on a lane boundary when calculating +* the expected data rate. This is done by extending HFP in case of +* misalignment. +*/ + adj_dsi_htotal = dsi_htotal; + if (dsi_htotal % dsi_nlanes) + adj_dsi_htotal += dsi_nlanes - (dsi_htotal % dsi_nlanes); + + dlane_bps = (u64)dpi_hz * adj_dsi_htotal; + + /* data rate in bytes/sec is not an integer, refuse the mode. */ + if (do_div(dlane_bps, dsi_nlanes * dpi_htotal)) + return -EINVAL; + + /* data rate was in bytes/sec, convert to bits/sec. */ + dlane_bps *= 8; + + if (dlane_bps > 25UL || dlane_bps < 16000UL) + return -EINVAL; + else if (dlane_bps >= 125000) + cfg->pll_opdiv = 1; + else if (dlane_bps >= 63000) + cfg->pll_opdiv = 2; + else if (dlane_bps >= 32000) + cfg->pll_opdiv = 4; + else if (dlane_bps >= 16000) + cfg->pll_opdiv = 8; + + /* +* Allow a deviation of 0.2% on the per-lane data rate to try to +* recover a potential mismatch between DPI and PPI clks. +*/ + dlane_bps_max = dlane_bps + (dlane_bps / 500); kbuild reported an error for 32 bit archs. I'm guessing it's because of this divide above? Yep, DIV_ROUND_UP_ULL() should fix the problem. + + fbdiv_max = DIV_ROUND_DOWN_ULL((dlane_bps + (dlane_bps / 500)) * 2 * You could use dlane_bps_max here instead. Sure. Otherwise, Reviewed-by: Archit Taneja Thanks for the review. Does that mean I'm allowed to apply the patch to drm-misc-next myself after fixing the div64 issue? Sure, please go ahead. Archit Regards, Boris ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v6 1/2] drm/bridge: Add Cadence DSI driver
Hi Archit, On Sun, 15 Apr 2018 13:39:44 +0530 Archit Tanejawrote: > > +static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy, > > +struct cdns_dphy_cfg *cfg, > > +unsigned int dpi_htotal, > > +unsigned int dpi_bpp, > > +unsigned int dpi_hz, > > +unsigned int dsi_htotal, > > +unsigned int dsi_nlanes, > > +unsigned int *dsi_hfp_ext) > > +{ > > + u64 dlane_bps, dlane_bps_max, fbdiv, fbdiv_max, adj_dsi_htotal; > > + unsigned long pll_ref_hz = clk_get_rate(dphy->pll_ref_clk); > > + > > + memset(cfg, 0, sizeof(*cfg)); > > + > > + cfg->nlanes = dsi_nlanes; > > + > > + if (pll_ref_hz < 960 || pll_ref_hz >= 15000) > > + return -EINVAL; > > + else if (pll_ref_hz < 1920) > > + cfg->pll_ipdiv = 1; > > + else if (pll_ref_hz < 3840) > > + cfg->pll_ipdiv = 2; > > + else if (pll_ref_hz < 7680) > > + cfg->pll_ipdiv = 4; > > + else > > + cfg->pll_ipdiv = 8; > > + > > + /* > > +* Make sure DSI htotal is aligned on a lane boundary when calculating > > +* the expected data rate. This is done by extending HFP in case of > > +* misalignment. > > +*/ > > + adj_dsi_htotal = dsi_htotal; > > + if (dsi_htotal % dsi_nlanes) > > + adj_dsi_htotal += dsi_nlanes - (dsi_htotal % dsi_nlanes); > > + > > + dlane_bps = (u64)dpi_hz * adj_dsi_htotal; > > + > > + /* data rate in bytes/sec is not an integer, refuse the mode. */ > > + if (do_div(dlane_bps, dsi_nlanes * dpi_htotal)) > > + return -EINVAL; > > + > > + /* data rate was in bytes/sec, convert to bits/sec. */ > > + dlane_bps *= 8; > > + > > + if (dlane_bps > 25UL || dlane_bps < 16000UL) > > + return -EINVAL; > > + else if (dlane_bps >= 125000) > > + cfg->pll_opdiv = 1; > > + else if (dlane_bps >= 63000) > > + cfg->pll_opdiv = 2; > > + else if (dlane_bps >= 32000) > > + cfg->pll_opdiv = 4; > > + else if (dlane_bps >= 16000) > > + cfg->pll_opdiv = 8; > > + > > + /* > > +* Allow a deviation of 0.2% on the per-lane data rate to try to > > +* recover a potential mismatch between DPI and PPI clks. > > +*/ > > + dlane_bps_max = dlane_bps + (dlane_bps / 500); > > kbuild reported an error for 32 bit archs. I'm guessing it's because of > this divide above? Yep, DIV_ROUND_UP_ULL() should fix the problem. > > > > + > > + fbdiv_max = DIV_ROUND_DOWN_ULL((dlane_bps + (dlane_bps / 500)) * 2 * > > You could use dlane_bps_max here instead. Sure. > > Otherwise, > > Reviewed-by: Archit Taneja Thanks for the review. Does that mean I'm allowed to apply the patch to drm-misc-next myself after fixing the div64 issue? Regards, Boris ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v6 1/2] drm/bridge: Add Cadence DSI driver
Hi, On Tuesday 10 April 2018 06:30 PM, Boris Brezillon wrote: From: Boris BrezillonAdd a driver for Cadence DPI -> DSI bridge. This driver only support a subset of Cadence DSI bridge capabilities. This driver has been tested/debugged in a simulated environment which explains why some of the features are missing. Here is a non-exhaustive list of missing features: * burst mode * DPHY init/configuration steps * support for additional input interfaces (SDI input) DSI commands and non-burst video mode have been tested. Signed-off-by: Boris Brezillon Reviewed-by: Andrzej Hajda Acked-by: Eric Anholt --- Hello, This version is still missing DPHY config/init code, mainly because I don't have a DPHY (either real or emulated) to test with. But I'm working on a DPHY abstraction layer to help extract common DPHY operations out of DSI drivers so that DPHY drivers can be used outside of the DRM world (I know D-PHYs can be used with CSI which belongs in V4L). Regards, Boris This version is still missing Changes in v6: - Use SPDX header - Do not enable the sys_clk in the probe function - Remove unneeded udelay() - Add a function to make sure the PLL and pixel clock are close enough to be recoverable if they don't match exactly - Add the DPHY init sequence used in simulation (likely to be different based on each SoC integration) Changes in v5: - Add runtime PM support Changes in v4: - Fix typos - Rename clks as suggested by Tomi - Fix DSI setup done in cdns_dsi_bridge_enable() - Add a precision about where this bridge is supposed to used to the Kconfig entry - Let DRM_CDNS_DSI select DRM_PANEL_BRIDGE - Remove the IP version from the DT compatible name - Adapt register the layout to match the one used in the last revision of the IP (hopefully the final version) Changes in v3: - replace magic values by real timing calculation. The DPHY PLL clock is still hardcoded since we don't have a working DPHY block yet, and this is the piece of HW we need to dynamically configure the PLL rate based on the display refresh rate and the resolution. - parse DSI devices represented with the OF-graph. This is needed to support DSI devices controlled through an external bus like I2C or SPI. - use the DRM panel-bridge infrastructure to simplify the DRM panel logic Changes in v2: - rebase on v4.12-rc1 and adapt to driver to the drm_bridge API changes - return the correct error when devm_clk_get(sysclk) fails - add missing depends on OF and select DRM_PANEL in the Kconfig entry DSI runtime PM --- drivers/gpu/drm/bridge/Kconfig| 10 + drivers/gpu/drm/bridge/Makefile |1 + drivers/gpu/drm/bridge/cdns-dsi.c | 1624 + 3 files changed, 1635 insertions(+) create mode 100644 drivers/gpu/drm/bridge/cdns-dsi.c diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index 3aa65bdecb0e..1cd267880b53 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -25,6 +25,16 @@ config DRM_ANALOGIX_ANX78XX the HDMI output of an application processor to MyDP or DisplayPort. +config DRM_CDNS_DSI + tristate "Cadence DPI/DSI bridge" + select DRM_KMS_HELPER + select DRM_MIPI_DSI + select DRM_PANEL_BRIDGE + depends on OF + help + Support Cadence DPI to DSI bridge. This is an internal + bridge and is meant to be directly embedded in a SoC. + config DRM_DUMB_VGA_DAC tristate "Dumb VGA DAC Bridge support" depends on OF diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile index 373eb28f31ed..aea7cbe9070b 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o +obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o obj-$(CONFIG_DRM_DUMB_VGA_DAC) += dumb-vga-dac.o obj-$(CONFIG_DRM_LVDS_ENCODER) += lvds-encoder.o obj-$(CONFIG_DRM_MEGACHIPS_STDP_GE_B850V3_FW) += megachips-stdp-ge-b850v3-fw.o diff --git a/drivers/gpu/drm/bridge/cdns-dsi.c b/drivers/gpu/drm/bridge/cdns-dsi.c new file mode 100644 index ..d4ceb961f475 --- /dev/null +++ b/drivers/gpu/drm/bridge/cdns-dsi.c @@ -0,0 +1,1624 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright: 2017 Cadence Design Systems, Inc. + * + * Author: Boris Brezillon + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define IP_CONF0x0 +#define SP_HS_FIFO_DEPTH(x)(((x) & GENMASK(30, 26)) >> 26) +#define SP_LP_FIFO_DEPTH(x)(((x) & GENMASK(25, 21)) >> 21) +#define VRS_FIFO_DEPTH(x) (((x)
Re: [PATCH v6 1/2] drm/bridge: Add Cadence DSI driver
Hi Boris, I love your patch! Yet something to improve: [auto build test ERROR on drm/drm-next] [also build test ERROR on v4.16 next-20180410] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Boris-Brezillon/drm-bridge-Add-Cadence-DSI-driver/20180411-060845 base: git://people.freedesktop.org/~airlied/linux.git drm-next config: arm-allyesconfig (attached as .config) compiler: arm-linux-gnueabi-gcc (Debian 7.2.0-11) 7.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=arm All errors (new ones prefixed by >>): drivers/gpu/drm/bridge/cdns-dsi.o: In function `cdns_dsi_get_dphy_pll_cfg.constprop.0': >> cdns-dsi.c:(.text+0x139c): undefined reference to `__aeabi_uldivmod' --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v6 1/2] drm/bridge: Add Cadence DSI driver
Hi Boris, I love your patch! Yet something to improve: [auto build test ERROR on drm/drm-next] [also build test ERROR on v4.16 next-20180410] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Boris-Brezillon/drm-bridge-Add-Cadence-DSI-driver/20180411-060845 base: git://people.freedesktop.org/~airlied/linux.git drm-next config: i386-allyesconfig (attached as .config) compiler: gcc-7 (Debian 7.3.0-1) 7.3.0 reproduce: # save the attached .config to linux build tree make ARCH=i386 All errors (new ones prefixed by >>): drivers/gpu/drm/bridge/cdns-dsi.o: In function `cdns_dsi_get_dphy_pll_cfg.isra.4': >> cdns-dsi.c:(.text+0xfdd): undefined reference to `__udivdi3' --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v6 1/2] drm/bridge: Add Cadence DSI driver
From: Boris BrezillonAdd a driver for Cadence DPI -> DSI bridge. This driver only support a subset of Cadence DSI bridge capabilities. This driver has been tested/debugged in a simulated environment which explains why some of the features are missing. Here is a non-exhaustive list of missing features: * burst mode * DPHY init/configuration steps * support for additional input interfaces (SDI input) DSI commands and non-burst video mode have been tested. Signed-off-by: Boris Brezillon Reviewed-by: Andrzej Hajda Acked-by: Eric Anholt --- Hello, This version is still missing DPHY config/init code, mainly because I don't have a DPHY (either real or emulated) to test with. But I'm working on a DPHY abstraction layer to help extract common DPHY operations out of DSI drivers so that DPHY drivers can be used outside of the DRM world (I know D-PHYs can be used with CSI which belongs in V4L). Regards, Boris This version is still missing Changes in v6: - Use SPDX header - Do not enable the sys_clk in the probe function - Remove unneeded udelay() - Add a function to make sure the PLL and pixel clock are close enough to be recoverable if they don't match exactly - Add the DPHY init sequence used in simulation (likely to be different based on each SoC integration) Changes in v5: - Add runtime PM support Changes in v4: - Fix typos - Rename clks as suggested by Tomi - Fix DSI setup done in cdns_dsi_bridge_enable() - Add a precision about where this bridge is supposed to used to the Kconfig entry - Let DRM_CDNS_DSI select DRM_PANEL_BRIDGE - Remove the IP version from the DT compatible name - Adapt register the layout to match the one used in the last revision of the IP (hopefully the final version) Changes in v3: - replace magic values by real timing calculation. The DPHY PLL clock is still hardcoded since we don't have a working DPHY block yet, and this is the piece of HW we need to dynamically configure the PLL rate based on the display refresh rate and the resolution. - parse DSI devices represented with the OF-graph. This is needed to support DSI devices controlled through an external bus like I2C or SPI. - use the DRM panel-bridge infrastructure to simplify the DRM panel logic Changes in v2: - rebase on v4.12-rc1 and adapt to driver to the drm_bridge API changes - return the correct error when devm_clk_get(sysclk) fails - add missing depends on OF and select DRM_PANEL in the Kconfig entry DSI runtime PM --- drivers/gpu/drm/bridge/Kconfig| 10 + drivers/gpu/drm/bridge/Makefile |1 + drivers/gpu/drm/bridge/cdns-dsi.c | 1624 + 3 files changed, 1635 insertions(+) create mode 100644 drivers/gpu/drm/bridge/cdns-dsi.c diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index 3aa65bdecb0e..1cd267880b53 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -25,6 +25,16 @@ config DRM_ANALOGIX_ANX78XX the HDMI output of an application processor to MyDP or DisplayPort. +config DRM_CDNS_DSI + tristate "Cadence DPI/DSI bridge" + select DRM_KMS_HELPER + select DRM_MIPI_DSI + select DRM_PANEL_BRIDGE + depends on OF + help + Support Cadence DPI to DSI bridge. This is an internal + bridge and is meant to be directly embedded in a SoC. + config DRM_DUMB_VGA_DAC tristate "Dumb VGA DAC Bridge support" depends on OF diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile index 373eb28f31ed..aea7cbe9070b 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o +obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o obj-$(CONFIG_DRM_DUMB_VGA_DAC) += dumb-vga-dac.o obj-$(CONFIG_DRM_LVDS_ENCODER) += lvds-encoder.o obj-$(CONFIG_DRM_MEGACHIPS_STDP_GE_B850V3_FW) += megachips-stdp-ge-b850v3-fw.o diff --git a/drivers/gpu/drm/bridge/cdns-dsi.c b/drivers/gpu/drm/bridge/cdns-dsi.c new file mode 100644 index ..d4ceb961f475 --- /dev/null +++ b/drivers/gpu/drm/bridge/cdns-dsi.c @@ -0,0 +1,1624 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright: 2017 Cadence Design Systems, Inc. + * + * Author: Boris Brezillon + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define IP_CONF0x0 +#define SP_HS_FIFO_DEPTH(x)(((x) & GENMASK(30, 26)) >> 26) +#define SP_LP_FIFO_DEPTH(x)(((x) & GENMASK(25, 21)) >> 21) +#define VRS_FIFO_DEPTH(x) (((x) & GENMASK(20, 16)) >> 16) +#define DIRCMD_FIFO_DEPTH(x) (((x) & GENMASK(15, 13))