[PATCH 3/6] staging: drm/imx: add i.MX IPUv3 base driver
The IPU is the Image Processing Unit found on i.MX51/53/6 SoCs. It features several units for image processing, this patch adds support for the units needed for Framebuffer support, namely: - Display Controller (dc) - Display Interface (di) - Display Multi Fifo Controller (dmfc) - Display Processor (dp) - Image DMA Controller (idmac) This patch is based on the Freescale driver, but follows a different approach. The Freescale code implements logical idmac channels and the handling of the subunits is hidden in common idmac code pathes in big switch/case statements. This patch instead just provides code and resource management for the different subunits. The user, in this case the framebuffer driver, decides how the different units play together. The IPU has other units missing in this patch: - CMOS Sensor Interface (csi) - Video Deinterlacer (vdi) - Sensor Multi FIFO Controler (smfc) - Image Converter (ic) - Image Rotator (irt) Signed-off-by: Sascha Hauer --- drivers/staging/imx-drm/Kconfig |8 + drivers/staging/imx-drm/Makefile|1 + drivers/staging/imx-drm/imx-drm-core.c |2 + drivers/staging/imx-drm/ipu-v3/Makefile |3 + drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h | 318 drivers/staging/imx-drm/ipu-v3/ipu-common.c | 1143 +++ drivers/staging/imx-drm/ipu-v3/ipu-dc.c | 372 + drivers/staging/imx-drm/ipu-v3/ipu-di.c | 700 drivers/staging/imx-drm/ipu-v3/ipu-dmfc.c | 408 ++ drivers/staging/imx-drm/ipu-v3/ipu-dp.c | 336 drivers/staging/imx-drm/ipu-v3/ipu-prv.h| 206 + 11 files changed, 3497 insertions(+) create mode 100644 drivers/staging/imx-drm/ipu-v3/Makefile create mode 100644 drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h create mode 100644 drivers/staging/imx-drm/ipu-v3/ipu-common.c create mode 100644 drivers/staging/imx-drm/ipu-v3/ipu-dc.c create mode 100644 drivers/staging/imx-drm/ipu-v3/ipu-di.c create mode 100644 drivers/staging/imx-drm/ipu-v3/ipu-dmfc.c create mode 100644 drivers/staging/imx-drm/ipu-v3/ipu-dp.c create mode 100644 drivers/staging/imx-drm/ipu-v3/ipu-prv.h diff --git a/drivers/staging/imx-drm/Kconfig b/drivers/staging/imx-drm/Kconfig index 9e27012..4849bfa 100644 --- a/drivers/staging/imx-drm/Kconfig +++ b/drivers/staging/imx-drm/Kconfig @@ -19,3 +19,11 @@ config DRM_IMX_FB_HELPER config DRM_IMX_PARALLEL_DISPLAY tristate "Support for parallel displays" depends on DRM_IMX + +config DRM_IMX_IPUV3_CORE + tristate "IPUv3 core support" + depends on DRM_IMX + help + Choose this if you have a i.MX5/6 system and want + to use the IPU. This option only enables IPU base + support. diff --git a/drivers/staging/imx-drm/Makefile b/drivers/staging/imx-drm/Makefile index c8f582e..e3a5b6f 100644 --- a/drivers/staging/imx-drm/Makefile +++ b/drivers/staging/imx-drm/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_DRM_IMX) += imxdrm.o obj-$(CONFIG_DRM_IMX_PARALLEL_DISPLAY) += parallel-display.o obj-$(CONFIG_DRM_IMX_FB_HELPER) += imx-fbdev.o +obj-$(CONFIG_DRM_IMX_IPUV3_CORE) += ipu-v3/ diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index 225e835..1913199b 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -137,6 +137,7 @@ found: encoder_type, interface_pix_fmt); return 0; } +EXPORT_SYMBOL_GPL(imx_drm_crtc_panel_format); int imx_drm_crtc_vblank_get(struct imx_drm_crtc *imx_drm_crtc) { @@ -647,6 +648,7 @@ int imx_drm_encoder_add_possible_crtcs( return 0; } +EXPORT_SYMBOL_GPL(imx_drm_encoder_add_possible_crtcs); int imx_drm_encoder_get_mux_id(struct imx_drm_encoder *imx_drm_encoder, struct drm_crtc *crtc) diff --git a/drivers/staging/imx-drm/ipu-v3/Makefile b/drivers/staging/imx-drm/ipu-v3/Makefile new file mode 100644 index 000..28ed72e --- /dev/null +++ b/drivers/staging/imx-drm/ipu-v3/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_DRM_IMX_IPUV3_CORE) += imx-ipu-v3.o + +imx-ipu-v3-objs := ipu-common.o ipu-dc.o ipu-di.o ipu-dp.o ipu-dmfc.o diff --git a/drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h b/drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h new file mode 100644 index 000..74158dd --- /dev/null +++ b/drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h @@ -0,0 +1,318 @@ +/* + * Copyright 2005-2009 Freescale Semiconductor, Inc. + * + * The code contained herein is licensed under the GNU Lesser General + * Public License. You may obtain a copy of the GNU Lesser General + * Public License Version 2.1 or later at the following locations: + * + * http://www.opensource.org/licenses/lgpl-license.html + * http://www.gnu.org/copyleft/lgpl.html + */ + +#ifndef __DRM_IPU_H__ +#define __DRM_IPU_H__ + +#include +#include +#include +#include +#include + +struct ipu_soc; + +enum ipuv3_type { + IPUV3EX, + IPUV3M, + IPUV3H, +}; +
Re: [PATCH 3/6] staging: drm/imx: add i.MX IPUv3 base driver
On 12.09.2012 12:31, Sascha Hauer wrote: The IPU is the Image Processing Unit found on i.MX51/53/6 SoCs. It features several units for image processing, this patch adds support for the units needed for Framebuffer support, namely: - Display Controller (dc) - Display Interface (di) - Display Multi Fifo Controller (dmfc) - Display Processor (dp) - Image DMA Controller (idmac) This patch is based on the Freescale driver, but follows a different approach. The Freescale code implements logical idmac channels and the handling of the subunits is hidden in common idmac code pathes in big switch/case statements. This patch instead just provides code and resource management for the different subunits. The user, in this case the framebuffer driver, decides how the different units play together. The IPU has other units missing in this patch: - CMOS Sensor Interface (csi) - Video Deinterlacer (vdi) - Sensor Multi FIFO Controler (smfc) - Image Converter (ic) - Image Rotator (irt) Signed-off-by: Sascha Hauer s.ha...@pengutronix.de +static int ipu_reset(struct ipu_soc *ipu) +{ + unsigned long timeout; + + ipu_cm_write(ipu, 0x807F, IPU_MEM_RST); + + timeout = jiffies + msecs_to_jiffies(1000); + while (ipu_cm_read(ipu, IPU_MEM_RST) 0x8000) { + if (time_after(jiffies, timeout)) + return -ETIME; + cpu_relax(); + } + + mdelay(300); + return 0; +} While doing some boot time measurement with i.MX6, we found that the above mdelay(300) is hurting regarding boot time. On i.MX6 you have two IPU instances, so in the end you get 600ms additional delay. Looking at the Freescale code, this function looks like static int ipu_reset(struct ipu_soc *ipu) { int timeout = 1000; ipu_cm_write(ipu, 0x807F, IPU_MEM_RST); while (ipu_cm_read(ipu, IPU_MEM_RST) 0x8000) { if (!timeout--) return -ETIME; msleep(1); } return 0; } So there is a msleep() in the loop but no mdelay() outside. Any idea why the mdelay() is needed here? Or what could be done regarding boot time with this? Note: This is just a question, this shouldn't block the staging process. Best regards Dirk ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 3/6] staging: drm/imx: add i.MX IPUv3 base driver
On Fri, Sep 14, 2012 at 11:29:06AM +0200, Dirk Behme wrote: > On 12.09.2012 12:31, Sascha Hauer wrote: > >+ > >+ timeout = jiffies + msecs_to_jiffies(1000); > >+ while (ipu_cm_read(ipu, IPU_MEM_RST) & 0x8000) { > >+ if (time_after(jiffies, timeout)) > >+ return -ETIME; > >+ cpu_relax(); > >+ } > >+ > >+ mdelay(300); > > > >+ return 0; > >+} > > While doing some boot time measurement with i.MX6, we found that the > above mdelay(300) is hurting regarding boot time. On i.MX6 you have > two IPU instances, so in the end you get 600ms additional delay. > > Looking at the Freescale code, this function looks like > > static int ipu_reset(struct ipu_soc *ipu) > { > int timeout = 1000; > > ipu_cm_write(ipu, 0x807F, IPU_MEM_RST); > > while (ipu_cm_read(ipu, IPU_MEM_RST) & 0x8000) { > if (!timeout--) >return -ETIME; > msleep(1); > } > return 0; > } > > So there is a msleep() in the loop but no mdelay() outside. Any idea > why the mdelay() is needed here? Or what could be done regarding > boot time with this? I remember we had issues on i.MX51 or 53 without it, but I would have to recheck it. In any way, I think this should be reworked. The reset takes quite a long time and it's not nice to block the boot process for so long. Some asynchronous reset would be nice here. Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- |
[PATCH 3/6] staging: drm/imx: add i.MX IPUv3 base driver
On 12.09.2012 12:31, Sascha Hauer wrote: > The IPU is the Image Processing Unit found on i.MX51/53/6 SoCs. It > features several units for image processing, this patch adds support > for the units needed for Framebuffer support, namely: > > - Display Controller (dc) > - Display Interface (di) > - Display Multi Fifo Controller (dmfc) > - Display Processor (dp) > - Image DMA Controller (idmac) > > This patch is based on the Freescale driver, but follows a different > approach. The Freescale code implements logical idmac channels and > the handling of the subunits is hidden in common idmac code pathes > in big switch/case statements. This patch instead just provides code > and resource management for the different subunits. The user, in this > case the framebuffer driver, decides how the different units play > together. > > The IPU has other units missing in this patch: > > - CMOS Sensor Interface (csi) > - Video Deinterlacer (vdi) > - Sensor Multi FIFO Controler (smfc) > - Image Converter (ic) > - Image Rotator (irt) > > Signed-off-by: Sascha Hauer > +static int ipu_reset(struct ipu_soc *ipu) > +{ > + unsigned long timeout; > + > + ipu_cm_write(ipu, 0x807F, IPU_MEM_RST); > + > + timeout = jiffies + msecs_to_jiffies(1000); > + while (ipu_cm_read(ipu, IPU_MEM_RST) & 0x8000) { > + if (time_after(jiffies, timeout)) > + return -ETIME; > + cpu_relax(); > + } > + > + mdelay(300); > + return 0; > +} While doing some boot time measurement with i.MX6, we found that the above mdelay(300) is hurting regarding boot time. On i.MX6 you have two IPU instances, so in the end you get 600ms additional delay. Looking at the Freescale code, this function looks like static int ipu_reset(struct ipu_soc *ipu) { int timeout = 1000; ipu_cm_write(ipu, 0x807F, IPU_MEM_RST); while (ipu_cm_read(ipu, IPU_MEM_RST) & 0x8000) { if (!timeout--) return -ETIME; msleep(1); } return 0; } So there is a msleep() in the loop but no mdelay() outside. Any idea why the mdelay() is needed here? Or what could be done regarding boot time with this? Note: This is just a question, this shouldn't block the staging process. Best regards Dirk
Re: [PATCH 3/6] staging: drm/imx: add i.MX IPUv3 base driver
On Fri, Sep 14, 2012 at 11:29:06AM +0200, Dirk Behme wrote: On 12.09.2012 12:31, Sascha Hauer wrote: + + timeout = jiffies + msecs_to_jiffies(1000); + while (ipu_cm_read(ipu, IPU_MEM_RST) 0x8000) { + if (time_after(jiffies, timeout)) + return -ETIME; + cpu_relax(); + } + + mdelay(300); + return 0; +} While doing some boot time measurement with i.MX6, we found that the above mdelay(300) is hurting regarding boot time. On i.MX6 you have two IPU instances, so in the end you get 600ms additional delay. Looking at the Freescale code, this function looks like static int ipu_reset(struct ipu_soc *ipu) { int timeout = 1000; ipu_cm_write(ipu, 0x807F, IPU_MEM_RST); while (ipu_cm_read(ipu, IPU_MEM_RST) 0x8000) { if (!timeout--) return -ETIME; msleep(1); } return 0; } So there is a msleep() in the loop but no mdelay() outside. Any idea why the mdelay() is needed here? Or what could be done regarding boot time with this? I remember we had issues on i.MX51 or 53 without it, but I would have to recheck it. In any way, I think this should be reworked. The reset takes quite a long time and it's not nice to block the boot process for so long. Some asynchronous reset would be nice here. Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 3/6] staging: drm/imx: add i.MX IPUv3 base driver
The IPU is the Image Processing Unit found on i.MX51/53/6 SoCs. It features several units for image processing, this patch adds support for the units needed for Framebuffer support, namely: - Display Controller (dc) - Display Interface (di) - Display Multi Fifo Controller (dmfc) - Display Processor (dp) - Image DMA Controller (idmac) This patch is based on the Freescale driver, but follows a different approach. The Freescale code implements logical idmac channels and the handling of the subunits is hidden in common idmac code pathes in big switch/case statements. This patch instead just provides code and resource management for the different subunits. The user, in this case the framebuffer driver, decides how the different units play together. The IPU has other units missing in this patch: - CMOS Sensor Interface (csi) - Video Deinterlacer (vdi) - Sensor Multi FIFO Controler (smfc) - Image Converter (ic) - Image Rotator (irt) Signed-off-by: Sascha Hauer --- drivers/staging/imx-drm/Kconfig |8 + drivers/staging/imx-drm/Makefile|1 + drivers/staging/imx-drm/ipu-v3/Makefile |3 + drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h | 318 drivers/staging/imx-drm/ipu-v3/ipu-common.c | 1143 +++ drivers/staging/imx-drm/ipu-v3/ipu-dc.c | 379 + drivers/staging/imx-drm/ipu-v3/ipu-di.c | 700 drivers/staging/imx-drm/ipu-v3/ipu-dmfc.c | 408 ++ drivers/staging/imx-drm/ipu-v3/ipu-dp.c | 336 drivers/staging/imx-drm/ipu-v3/ipu-prv.h| 206 + 10 files changed, 3502 insertions(+) create mode 100644 drivers/staging/imx-drm/ipu-v3/Makefile create mode 100644 drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h create mode 100644 drivers/staging/imx-drm/ipu-v3/ipu-common.c create mode 100644 drivers/staging/imx-drm/ipu-v3/ipu-dc.c create mode 100644 drivers/staging/imx-drm/ipu-v3/ipu-di.c create mode 100644 drivers/staging/imx-drm/ipu-v3/ipu-dmfc.c create mode 100644 drivers/staging/imx-drm/ipu-v3/ipu-dp.c create mode 100644 drivers/staging/imx-drm/ipu-v3/ipu-prv.h diff --git a/drivers/staging/imx-drm/Kconfig b/drivers/staging/imx-drm/Kconfig index 9e27012..4849bfa 100644 --- a/drivers/staging/imx-drm/Kconfig +++ b/drivers/staging/imx-drm/Kconfig @@ -19,3 +19,11 @@ config DRM_IMX_FB_HELPER config DRM_IMX_PARALLEL_DISPLAY tristate "Support for parallel displays" depends on DRM_IMX + +config DRM_IMX_IPUV3_CORE + tristate "IPUv3 core support" + depends on DRM_IMX + help + Choose this if you have a i.MX5/6 system and want + to use the IPU. This option only enables IPU base + support. diff --git a/drivers/staging/imx-drm/Makefile b/drivers/staging/imx-drm/Makefile index c8f582e..e3a5b6f 100644 --- a/drivers/staging/imx-drm/Makefile +++ b/drivers/staging/imx-drm/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_DRM_IMX) += imxdrm.o obj-$(CONFIG_DRM_IMX_PARALLEL_DISPLAY) += parallel-display.o obj-$(CONFIG_DRM_IMX_FB_HELPER) += imx-fbdev.o +obj-$(CONFIG_DRM_IMX_IPUV3_CORE) += ipu-v3/ diff --git a/drivers/staging/imx-drm/ipu-v3/Makefile b/drivers/staging/imx-drm/ipu-v3/Makefile new file mode 100644 index 000..28ed72e --- /dev/null +++ b/drivers/staging/imx-drm/ipu-v3/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_DRM_IMX_IPUV3_CORE) += imx-ipu-v3.o + +imx-ipu-v3-objs := ipu-common.o ipu-dc.o ipu-di.o ipu-dp.o ipu-dmfc.o diff --git a/drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h b/drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h new file mode 100644 index 000..74158dd --- /dev/null +++ b/drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h @@ -0,0 +1,318 @@ +/* + * Copyright 2005-2009 Freescale Semiconductor, Inc. + * + * The code contained herein is licensed under the GNU Lesser General + * Public License. You may obtain a copy of the GNU Lesser General + * Public License Version 2.1 or later at the following locations: + * + * http://www.opensource.org/licenses/lgpl-license.html + * http://www.gnu.org/copyleft/lgpl.html + */ + +#ifndef __DRM_IPU_H__ +#define __DRM_IPU_H__ + +#include +#include +#include +#include +#include + +struct ipu_soc; + +enum ipuv3_type { + IPUV3EX, + IPUV3M, + IPUV3H, +}; + +/* + * Bitfield of Display Interface signal polarities. + */ +struct ipu_di_signal_cfg { + unsigned datamask_en:1; + unsigned interlaced:1; + unsigned odd_field_first:1; + unsigned clksel_en:1; + unsigned clkidle_en:1; + unsigned data_pol:1;/* true = inverted */ + unsigned clk_pol:1; /* true = rising edge */ + unsigned enable_pol:1; + unsigned Hsync_pol:1; /* true = active high */ + unsigned Vsync_pol:1; + + u16 width; + u16 height; + u32 pixel_fmt; + u16 h_start_width; + u16 h_sync_width; + u16 h_end_width; + u16 v_start_width; + u16 v_sync_width; + u16 v_end_width; + u32 v_to_h_sync; + unsigned long