mbox series

[v6,0/6] drm/imx: Introduce i.MX8qm/qxp DPU DRM

Message ID 1611213263-7245-1-git-send-email-victor.liu@nxp.com (mailing list archive)
Headers show
Series drm/imx: Introduce i.MX8qm/qxp DPU DRM | expand

Message

Liu Ying Jan. 21, 2021, 7:14 a.m. UTC
Hi,


This is the v6 series to introduce i.MX8qm/qxp Display Processing Unit(DPU)
DRM support.

DPU is comprised of a blit engine for 2D graphics, a display controller
and a command sequencer.  Outside of DPU, optional prefetch engines can
fetch data from memory prior to some DPU fetchunits of blit engine and
display controller.  The pre-fetchers support linear formats and Vivante
GPU tile formats.

Reference manual can be found at:
https://www.nxp.com/webapp/Download?colCode=IMX8DQXPRM


This patch set adds kernel modesetting support for the display controller part.
It supports two CRTCs per display controller, several planes, prefetch
engines and some properties of CRTC and plane.  Currently, the registers of
the controller is accessed without command sequencer involved, instead just by
using CPU.  DRM connectors would be created from the DPU KMS driver.


If people want to try this series with i.MX8qxp, clock patches can be found at
Shawn's i.MX for-next git branch, and power domain patches have already landed
in 5.11-rc1.

Version2 dropped the device tree patches because we'll use new dt binding
way to support i.MX8qm/qxp clocks.  It depends on the below series to do basic
conversions for the platforms which has not landed yet:
https://www.spinics.net/lists/linux-mmc/msg61965.html


I've sent the below series to add downstream bridges(embedded in i.MX8qm/qxp)
to support LVDS displays:
https://www.spinics.net/lists/arm-kernel/msg868239.html


Patch 1 ~ 3 add dt-bindings for DPU and prefetch engines.
Patch 4 is a minor improvement of a macro to suppress warning as the KMS driver
uses it.
Patch 5 introduces the DPU DRM support.
Patch 6 updates MAINTAINERS.

Welcome comments, thanks.

v5->v6:
* Use graph schema in the DPU dt-binding.
* Do not use macros where possible in the DPU DRM driver. (Laurentiu)
* Break dpu_plane_atomic_check() into some smaller functions. (Laurentiu)
* Address some minor comments from Laurentiu on the DPU DRM driver.
* Add dpu_crtc_err() helper marco in the DPU DRM driver to tell dmesg
  which CRTC generates error.
* Drop calling dev_set_drvdata() from dpu_drm_bind/unbind() in the DPU DRM
  driver as it is done in dpu_drm_probe().
* Some trivial tweaks.

v4->v5:
* Rebase up onto the latest drm-misc-next branch and remove the hook to
  drm_atomic_helper_legacy_gamma_set() from patch 5/6, because it was dropped
  by the newly landed commit 'drm: automatic legacy gamma support'.
* Remove a redundant blank line from dpu_plane_atomic_update() in patch 5/6.

v3->v4:
* Improve compatible properties in DPU and prefetch engines' dt bindings
  by using enum instead of oneOf+const.
* Add Rob's R-b tags on dt binding patches(patch 1/6, 2/6 and 3/6).
* Add Daniel's A-b tag on patch 4/6.

v2->v3:
* Fix DPU DRM driver build warnings which are
  Reported-by: kernel test robot <lkp@intel.com>.
* Drop DPU DRM driver build dependency on IMX_SCU, as dummy SCU functions have
  been added in header files by the patch 'firmware: imx: add dummy functions'
  which has landed in linux-next/master branch.
* Add a missing blank line in include/drm/drm_atomic.h.

v1->v2:
* Test this patch set also with i.MX8qm LVDS displays.
* Drop the device tree patches because we'll use new dt binding way to
  support i.MX8qm/qxp clocks.  This depends on a not-yet-landed patch set
  to do basic conversions for the platforms.
* Fix dt binding yamllint warnings.
* Require bypass0 and bypass1 clocks for both i.MX8qxp and i.MX8qm in DPU's
  dt binding documentation.
* Use new dt binding way to add clocks in the dt binding examples.
* Address several comments from Laurentiu on the DPU DRM patch.

Liu Ying (6):
  dt-bindings: display: imx: Add i.MX8qxp/qm DPU binding
  dt-bindings: display: imx: Add i.MX8qxp/qm PRG binding
  dt-bindings: display: imx: Add i.MX8qxp/qm DPR channel binding
  drm/atomic: Avoid unused-but-set-variable warning on
    for_each_old_plane_in_state
  drm/imx: Introduce i.MX8qm/qxp DPU DRM
  MAINTAINERS: add maintainer for i.MX8qxp DPU DRM driver

 .../bindings/display/imx/fsl,imx8qxp-dprc.yaml     |   87 ++
 .../bindings/display/imx/fsl,imx8qxp-dpu.yaml      |  387 +++++++
 .../bindings/display/imx/fsl,imx8qxp-prg.yaml      |   60 ++
 MAINTAINERS                                        |    9 +
 drivers/gpu/drm/imx/Kconfig                        |    1 +
 drivers/gpu/drm/imx/Makefile                       |    1 +
 drivers/gpu/drm/imx/dpu/Kconfig                    |   10 +
 drivers/gpu/drm/imx/dpu/Makefile                   |   10 +
 drivers/gpu/drm/imx/dpu/dpu-constframe.c           |  171 +++
 drivers/gpu/drm/imx/dpu/dpu-core.c                 | 1094 ++++++++++++++++++++
 drivers/gpu/drm/imx/dpu/dpu-crtc.c                 |  967 +++++++++++++++++
 drivers/gpu/drm/imx/dpu/dpu-crtc.h                 |   66 ++
 drivers/gpu/drm/imx/dpu/dpu-disengcfg.c            |  117 +++
 drivers/gpu/drm/imx/dpu/dpu-dprc.c                 |  718 +++++++++++++
 drivers/gpu/drm/imx/dpu/dpu-dprc.h                 |   40 +
 drivers/gpu/drm/imx/dpu/dpu-drv.c                  |  292 ++++++
 drivers/gpu/drm/imx/dpu/dpu-drv.h                  |   28 +
 drivers/gpu/drm/imx/dpu/dpu-extdst.c               |  299 ++++++
 drivers/gpu/drm/imx/dpu/dpu-fetchdecode.c          |  294 ++++++
 drivers/gpu/drm/imx/dpu/dpu-fetcheco.c             |  224 ++++
 drivers/gpu/drm/imx/dpu/dpu-fetchlayer.c           |  154 +++
 drivers/gpu/drm/imx/dpu/dpu-fetchunit.c            |  609 +++++++++++
 drivers/gpu/drm/imx/dpu/dpu-fetchunit.h            |  191 ++++
 drivers/gpu/drm/imx/dpu/dpu-fetchwarp.c            |  250 +++++
 drivers/gpu/drm/imx/dpu/dpu-framegen.c             |  395 +++++++
 drivers/gpu/drm/imx/dpu/dpu-gammacor.c             |  223 ++++
 drivers/gpu/drm/imx/dpu/dpu-hscaler.c              |  275 +++++
 drivers/gpu/drm/imx/dpu/dpu-kms.c                  |  540 ++++++++++
 drivers/gpu/drm/imx/dpu/dpu-kms.h                  |   23 +
 drivers/gpu/drm/imx/dpu/dpu-layerblend.c           |  348 +++++++
 drivers/gpu/drm/imx/dpu/dpu-plane.c                |  799 ++++++++++++++
 drivers/gpu/drm/imx/dpu/dpu-plane.h                |   56 +
 drivers/gpu/drm/imx/dpu/dpu-prg.c                  |  433 ++++++++
 drivers/gpu/drm/imx/dpu/dpu-prg.h                  |   45 +
 drivers/gpu/drm/imx/dpu/dpu-prv.h                  |  233 +++++
 drivers/gpu/drm/imx/dpu/dpu-tcon.c                 |  250 +++++
 drivers/gpu/drm/imx/dpu/dpu-vscaler.c              |  308 ++++++
 drivers/gpu/drm/imx/dpu/dpu.h                      |  385 +++++++
 include/drm/drm_atomic.h                           |    5 +-
 39 files changed, 10396 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dprc.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-dpu.yaml
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8qxp-prg.yaml
 create mode 100644 drivers/gpu/drm/imx/dpu/Kconfig
 create mode 100644 drivers/gpu/drm/imx/dpu/Makefile
 create mode 100644 drivers/gpu/drm/imx/dpu/dpu-constframe.c
 create mode 100644 drivers/gpu/drm/imx/dpu/dpu-core.c
 create mode 100644 drivers/gpu/drm/imx/dpu/dpu-crtc.c
 create mode 100644 drivers/gpu/drm/imx/dpu/dpu-crtc.h
 create mode 100644 drivers/gpu/drm/imx/dpu/dpu-disengcfg.c
 create mode 100644 drivers/gpu/drm/imx/dpu/dpu-dprc.c
 create mode 100644 drivers/gpu/drm/imx/dpu/dpu-dprc.h
 create mode 100644 drivers/gpu/drm/imx/dpu/dpu-drv.c
 create mode 100644 drivers/gpu/drm/imx/dpu/dpu-drv.h
 create mode 100644 drivers/gpu/drm/imx/dpu/dpu-extdst.c
 create mode 100644 drivers/gpu/drm/imx/dpu/dpu-fetchdecode.c
 create mode 100644 drivers/gpu/drm/imx/dpu/dpu-fetcheco.c
 create mode 100644 drivers/gpu/drm/imx/dpu/dpu-fetchlayer.c
 create mode 100644 drivers/gpu/drm/imx/dpu/dpu-fetchunit.c
 create mode 100644 drivers/gpu/drm/imx/dpu/dpu-fetchunit.h
 create mode 100644 drivers/gpu/drm/imx/dpu/dpu-fetchwarp.c
 create mode 100644 drivers/gpu/drm/imx/dpu/dpu-framegen.c
 create mode 100644 drivers/gpu/drm/imx/dpu/dpu-gammacor.c
 create mode 100644 drivers/gpu/drm/imx/dpu/dpu-hscaler.c
 create mode 100644 drivers/gpu/drm/imx/dpu/dpu-kms.c
 create mode 100644 drivers/gpu/drm/imx/dpu/dpu-kms.h
 create mode 100644 drivers/gpu/drm/imx/dpu/dpu-layerblend.c
 create mode 100644 drivers/gpu/drm/imx/dpu/dpu-plane.c
 create mode 100644 drivers/gpu/drm/imx/dpu/dpu-plane.h
 create mode 100644 drivers/gpu/drm/imx/dpu/dpu-prg.c
 create mode 100644 drivers/gpu/drm/imx/dpu/dpu-prg.h
 create mode 100644 drivers/gpu/drm/imx/dpu/dpu-prv.h
 create mode 100644 drivers/gpu/drm/imx/dpu/dpu-tcon.c
 create mode 100644 drivers/gpu/drm/imx/dpu/dpu-vscaler.c
 create mode 100644 drivers/gpu/drm/imx/dpu/dpu.h

Comments

Laurentiu Palcu Jan. 25, 2021, 1:48 p.m. UTC | #1
Hi Liu Ying,

Just some minor comments below.

On Thu, Jan 21, 2021 at 03:14:22PM +0800, Liu Ying wrote:
> This patch introduces i.MX8qm/qxp Display Processing Unit(DPU) DRM support.
> 
> DPU is comprised of two main components that include a blit engine for
> 2D graphics accelerations(with composition support) and a display controller
> for display output processing, as well as a command sequencer.  Outside of
> DPU, optional prefetch engines, a.k.a, Prefetch Resolve Gasket(PRG) and
> Display Prefetch Resolve(DPR), can fetch data from memory prior to some DPU
> fetchunits of blit engine and display controller.  The prefetch engines
> support reading linear formats and resolving Vivante GPU tile formats.
> 
> This patch adds kernel modesetting support for the display controller part.
> The driver supports two CRTCs per display controller, planes backed by
> four fetchunits(decode0/1, fetchlayer, fetchwarp), fetchunit allocation
> logic for the two CRTCs, prefetch engines(with tile resolving supported),
> plane upscaling/deinterlacing/yuv2rgb CSC/alpha blending and CRTC gamma
> correction.  The registers of the controller is accessed without command
> sequencer involved, instead just by using CPU.
> 
> Reference manual can be found at:
> https://www.nxp.com/webapp/Download?colCode=IMX8DQXPRM
> 
> Signed-off-by: Liu Ying <victor.liu@nxp.com>
> ---
> v5->v6:
> * Do not use macros where possible. (Laurentiu)
> * Break dpu_plane_atomic_check() into some smaller functions. (Laurentiu)
> * Address some minor comments from Laurentiu.
> * Add dpu_crtc_err() helper marco to tell dmesg which CRTC generates error.
> * Drop calling dev_set_drvdata() from dpu_drm_bind/unbind() as it is done
>   in dpu_drm_probe().
> * Some trivial tweaks.
> 
> v4->v5:
> * Rebase up onto the latest drm-misc-next branch and remove the hook to
>   drm_atomic_helper_legacy_gamma_set(), because it was dropped by the newly
>   landed commit 'drm: automatic legacy gamma support'.
> * Remove a redundant blank line from dpu_plane_atomic_update().
> 
> v3->v4:
> * No change.
> 
> v2->v3:
> * Fix build warnings Reported-by: kernel test robot <lkp@intel.com>.
> * Drop build dependency on IMX_SCU, as dummy SCU functions have been added in
>   header files by the patch 'firmware: imx: add dummy functions' which has
>   landed in linux-next/master branch.
> 
> v1->v2:
> * Add compatible for i.MX8qm DPU, as this is tested with i.MX8qm LVDS displays.
>   (Laurentiu)
> * Fix PRG burst size and stride. (Laurentiu)
> * Put 'ports' OF node to fix the bail-out logic in dpu_drm_probe(). (Laurentiu)
> 
>  drivers/gpu/drm/imx/Kconfig               |    1 +
>  drivers/gpu/drm/imx/Makefile              |    1 +
>  drivers/gpu/drm/imx/dpu/Kconfig           |   10 +
>  drivers/gpu/drm/imx/dpu/Makefile          |   10 +
>  drivers/gpu/drm/imx/dpu/dpu-constframe.c  |  171 +++++
>  drivers/gpu/drm/imx/dpu/dpu-core.c        | 1094 +++++++++++++++++++++++++++++
>  drivers/gpu/drm/imx/dpu/dpu-crtc.c        |  967 +++++++++++++++++++++++++
>  drivers/gpu/drm/imx/dpu/dpu-crtc.h        |   66 ++
>  drivers/gpu/drm/imx/dpu/dpu-disengcfg.c   |  117 +++
>  drivers/gpu/drm/imx/dpu/dpu-dprc.c        |  718 +++++++++++++++++++
>  drivers/gpu/drm/imx/dpu/dpu-dprc.h        |   40 ++
>  drivers/gpu/drm/imx/dpu/dpu-drv.c         |  292 ++++++++
>  drivers/gpu/drm/imx/dpu/dpu-drv.h         |   28 +
>  drivers/gpu/drm/imx/dpu/dpu-extdst.c      |  299 ++++++++
>  drivers/gpu/drm/imx/dpu/dpu-fetchdecode.c |  294 ++++++++
>  drivers/gpu/drm/imx/dpu/dpu-fetcheco.c    |  224 ++++++
>  drivers/gpu/drm/imx/dpu/dpu-fetchlayer.c  |  154 ++++
>  drivers/gpu/drm/imx/dpu/dpu-fetchunit.c   |  609 ++++++++++++++++
>  drivers/gpu/drm/imx/dpu/dpu-fetchunit.h   |  191 +++++
>  drivers/gpu/drm/imx/dpu/dpu-fetchwarp.c   |  250 +++++++
>  drivers/gpu/drm/imx/dpu/dpu-framegen.c    |  395 +++++++++++
>  drivers/gpu/drm/imx/dpu/dpu-gammacor.c    |  223 ++++++
>  drivers/gpu/drm/imx/dpu/dpu-hscaler.c     |  275 ++++++++
>  drivers/gpu/drm/imx/dpu/dpu-kms.c         |  540 ++++++++++++++
>  drivers/gpu/drm/imx/dpu/dpu-kms.h         |   23 +
>  drivers/gpu/drm/imx/dpu/dpu-layerblend.c  |  348 +++++++++
>  drivers/gpu/drm/imx/dpu/dpu-plane.c       |  799 +++++++++++++++++++++
>  drivers/gpu/drm/imx/dpu/dpu-plane.h       |   56 ++
>  drivers/gpu/drm/imx/dpu/dpu-prg.c         |  433 ++++++++++++
>  drivers/gpu/drm/imx/dpu/dpu-prg.h         |   45 ++
>  drivers/gpu/drm/imx/dpu/dpu-prv.h         |  233 ++++++
>  drivers/gpu/drm/imx/dpu/dpu-tcon.c        |  250 +++++++
>  drivers/gpu/drm/imx/dpu/dpu-vscaler.c     |  308 ++++++++
>  drivers/gpu/drm/imx/dpu/dpu.h             |  385 ++++++++++
>  34 files changed, 9849 insertions(+)
>  create mode 100644 drivers/gpu/drm/imx/dpu/Kconfig
>  create mode 100644 drivers/gpu/drm/imx/dpu/Makefile
>  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-constframe.c
>  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-core.c
>  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-crtc.c
>  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-crtc.h
>  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-disengcfg.c
>  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-dprc.c
>  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-dprc.h
>  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-drv.c
>  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-drv.h
>  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-extdst.c
>  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-fetchdecode.c
>  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-fetcheco.c
>  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-fetchlayer.c
>  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-fetchunit.c
>  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-fetchunit.h
>  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-fetchwarp.c
>  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-framegen.c
>  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-gammacor.c
>  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-hscaler.c
>  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-kms.c
>  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-kms.h
>  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-layerblend.c
>  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-plane.c
>  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-plane.h
>  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-prg.c
>  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-prg.h
>  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-prv.h
>  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-tcon.c
>  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-vscaler.c
>  create mode 100644 drivers/gpu/drm/imx/dpu/dpu.h
>

[...]

> diff --git a/drivers/gpu/drm/imx/dpu/dpu-core.c b/drivers/gpu/drm/imx/dpu/dpu-core.c
> new file mode 100644
> index 00000000..7dab6cc
> --- /dev/null
> +++ b/drivers/gpu/drm/imx/dpu/dpu-core.c

[...]

> +static int dpu_get_irqs(struct platform_device *pdev, struct dpu_soc *dpu)
> +{
> +	unsigned int i, j;
> +
> +	/* do not get the reserved irq */
> +	for (i = 0, j = 0; i < DPU_IRQ_COUNT - 1; i++, j++) {
> +		if (i == DPU_IRQ_RESERVED)
> +			j++;
> +
> +		dpu->irq[j] = platform_get_irq(pdev, i);
> +		if (dpu->irq[j] < 0) {
> +			dev_err_probe(dpu->dev, dpu->irq[j],
> +				      "failed to get irq\n");
> +			return dpu->irq[i];

I think you want 'return dpu->irq[j]'.

> +		}
> +	}
> +
> +	return 0;
> +}

[...]

> +static const struct dpu_irq_handler_map {
> +	void (*handler)(struct irq_desc *desc);
> +} dpu_irq_handler_maps[DPU_IRQ_COUNT] = {
> +	{},						/* 0 */
> +	{},						/* 1 */
> +	{},						/* 2 */
> +	{dpu_extdst0_shdload_irq_handler},		/* 3 */
> +	{},						/* 4 */
> +	{},						/* 5 */
> +	{dpu_extdst4_shdload_irq_handler},		/* 6 */
> +	{},						/* 7 */
> +	{},						/* 8 */
> +	{dpu_extdst1_shdload_irq_handler},		/* 9 */
> +	{},						/* 10 */
> +	{},						/* 11 */
> +	{dpu_extdst5_shdload_irq_handler},		/* 12 */
> +	{},						/* 13 */
> +	{},						/* 14 */
> +	{dpu_disengcfg_shdload0_irq_handler},		/* 15 */
> +	{dpu_disengcfg_framecomplete0_irq_handler},	/* 16 */
> +	{dpu_disengcfg_seqcomplete0_irq_handler},	/* 17 */
> +	{},						/* 18 */
> +	{},						/* 19 */
> +	{},						/* 20 */
> +	{},						/* 21 */
> +	{},						/* 22 */
> +	{},						/* 23 */
> +	{},						/* 24 */
> +	{dpu_disengcfg_shdload1_irq_handler},		/* 25 */
> +	{dpu_disengcfg_framecomplete1_irq_handler},	/* 26 */
> +	{dpu_disengcfg_seqcomplete1_irq_handler},	/* 27 */
> +	{},						/* 28 */
> +	{},						/* 29 */
> +	{},						/* 30 */
> +	{},						/* 31 */
> +	{},						/* 32 */
> +	{},						/* 33 */
> +	{},						/* 34 */
> +	{/* reserved */},				/* 35 */
> +	{},						/* 36 */
> +	{},						/* 37 */
> +	{},						/* 38 */
> +	{},						/* 39 */
> +	{},						/* 40 */
> +	{},						/* 41 */
> +	{},						/* 42 */
> +	{},						/* 43 */
> +	{},						/* 44 */
> +	{},						/* 45 */
> +	{},						/* 46 */
> +	{},						/* 47 */
> +	{},						/* 48 */
> +};

Why not make this an array of pointers to functions. Do we need a struct?
Something like:

static void (* const dpu_irq_handler[DPU_IRQ_COUNT])(struct irq_desc *) = {
	[3] = dpu_extdst0_shdload_irq_handler,
	[6] = dpu_extdst4_shdload_irq_handler,
	...
};

[...]

> +static int
> +dpu_get_fetchunits_for_plane_grp(struct dpu_soc *dpu,
> +				 const struct dpu_units *us,
> +				 struct dpu_fetchunit ***fu,
> +				 unsigned int *cnt,
> +				 struct dpu_fetchunit *
> +						(*get)(struct dpu_soc *dpu,
> +						       unsigned int id))
> +{
> +	unsigned int fu_cnt = 0;
> +	int i, j, ret;
> +
> +	for (i = 0; i < us->cnt; i++) {
> +		if (us->types[i] == DPU_DISP)
> +			fu_cnt++;
> +	}
> +
> +	*cnt = fu_cnt;
> +
> +	*fu = devm_kcalloc(dpu->dev, fu_cnt, sizeof(**fu), GFP_KERNEL);
> +	if (!(*fu))
> +		return -ENOMEM;
> +
> +	for (i = 0, j = 0; i < us->cnt; i++) {
> +		if (us->types[i] != DPU_DISP)
> +			continue;
> +
> +		(*fu)[j] = (*get)(dpu, us->ids[i]);

You can also call get() directly. No need to dereference function
pointers.

> +		if (IS_ERR((*fu)[j])) {
> +			ret = PTR_ERR((*fu)[j]);
> +			dev_err(dpu->dev, "failed to get %s%d: %d\n",
> +						us->name, us->ids[i], ret);
> +			return ret;
> +		}
> +		j++;
> +	}
> +
> +	return 0;
> +}

[...]

> +static void
> +dpu_put_fetchunits_for_plane_grp(struct dpu_fetchunit ***fu,
> +				 unsigned int *cnt,
> +				 void (*put)(struct dpu_fetchunit *fu))
> +{
> +	int i;
> +
> +	for (i = 0; i < *cnt; i++)
> +		(*put)((*fu)[i]);

Same here, you can call put() directly.

> +
> +	*cnt = 0;
> +}

Thanks,
laurentiu
Liu Ying Jan. 26, 2021, 5:20 a.m. UTC | #2
On Mon, 2021-01-25 at 15:48 +0200, Laurentiu Palcu wrote:
> Hi Liu Ying,
> 
> Just some minor comments below.
> 
> On Thu, Jan 21, 2021 at 03:14:22PM +0800, Liu Ying wrote:
> > This patch introduces i.MX8qm/qxp Display Processing Unit(DPU) DRM support.
> > 
> > DPU is comprised of two main components that include a blit engine for
> > 2D graphics accelerations(with composition support) and a display controller
> > for display output processing, as well as a command sequencer.  Outside of
> > DPU, optional prefetch engines, a.k.a, Prefetch Resolve Gasket(PRG) and
> > Display Prefetch Resolve(DPR), can fetch data from memory prior to some DPU
> > fetchunits of blit engine and display controller.  The prefetch engines
> > support reading linear formats and resolving Vivante GPU tile formats.
> > 
> > This patch adds kernel modesetting support for the display controller part.
> > The driver supports two CRTCs per display controller, planes backed by
> > four fetchunits(decode0/1, fetchlayer, fetchwarp), fetchunit allocation
> > logic for the two CRTCs, prefetch engines(with tile resolving supported),
> > plane upscaling/deinterlacing/yuv2rgb CSC/alpha blending and CRTC gamma
> > correction.  The registers of the controller is accessed without command
> > sequencer involved, instead just by using CPU.
> > 
> > Reference manual can be found at:
> > https://www.nxp.com/webapp/Download?colCode=IMX8DQXPRM
> > 
> > Signed-off-by: Liu Ying <victor.liu@nxp.com>
> > ---
> > v5->v6:
> > * Do not use macros where possible. (Laurentiu)
> > * Break dpu_plane_atomic_check() into some smaller functions. (Laurentiu)
> > * Address some minor comments from Laurentiu.
> > * Add dpu_crtc_err() helper marco to tell dmesg which CRTC generates error.
> > * Drop calling dev_set_drvdata() from dpu_drm_bind/unbind() as it is done
> >   in dpu_drm_probe().
> > * Some trivial tweaks.
> > 
> > v4->v5:
> > * Rebase up onto the latest drm-misc-next branch and remove the hook to
> >   drm_atomic_helper_legacy_gamma_set(), because it was dropped by the newly
> >   landed commit 'drm: automatic legacy gamma support'.
> > * Remove a redundant blank line from dpu_plane_atomic_update().
> > 
> > v3->v4:
> > * No change.
> > 
> > v2->v3:
> > * Fix build warnings Reported-by: kernel test robot <lkp@intel.com>.
> > * Drop build dependency on IMX_SCU, as dummy SCU functions have been added in
> >   header files by the patch 'firmware: imx: add dummy functions' which has
> >   landed in linux-next/master branch.
> > 
> > v1->v2:
> > * Add compatible for i.MX8qm DPU, as this is tested with i.MX8qm LVDS displays.
> >   (Laurentiu)
> > * Fix PRG burst size and stride. (Laurentiu)
> > * Put 'ports' OF node to fix the bail-out logic in dpu_drm_probe(). (Laurentiu)
> > 
> >  drivers/gpu/drm/imx/Kconfig               |    1 +
> >  drivers/gpu/drm/imx/Makefile              |    1 +
> >  drivers/gpu/drm/imx/dpu/Kconfig           |   10 +
> >  drivers/gpu/drm/imx/dpu/Makefile          |   10 +
> >  drivers/gpu/drm/imx/dpu/dpu-constframe.c  |  171 +++++
> >  drivers/gpu/drm/imx/dpu/dpu-core.c        | 1094 +++++++++++++++++++++++++++++
> >  drivers/gpu/drm/imx/dpu/dpu-crtc.c        |  967 +++++++++++++++++++++++++
> >  drivers/gpu/drm/imx/dpu/dpu-crtc.h        |   66 ++
> >  drivers/gpu/drm/imx/dpu/dpu-disengcfg.c   |  117 +++
> >  drivers/gpu/drm/imx/dpu/dpu-dprc.c        |  718 +++++++++++++++++++
> >  drivers/gpu/drm/imx/dpu/dpu-dprc.h        |   40 ++
> >  drivers/gpu/drm/imx/dpu/dpu-drv.c         |  292 ++++++++
> >  drivers/gpu/drm/imx/dpu/dpu-drv.h         |   28 +
> >  drivers/gpu/drm/imx/dpu/dpu-extdst.c      |  299 ++++++++
> >  drivers/gpu/drm/imx/dpu/dpu-fetchdecode.c |  294 ++++++++
> >  drivers/gpu/drm/imx/dpu/dpu-fetcheco.c    |  224 ++++++
> >  drivers/gpu/drm/imx/dpu/dpu-fetchlayer.c  |  154 ++++
> >  drivers/gpu/drm/imx/dpu/dpu-fetchunit.c   |  609 ++++++++++++++++
> >  drivers/gpu/drm/imx/dpu/dpu-fetchunit.h   |  191 +++++
> >  drivers/gpu/drm/imx/dpu/dpu-fetchwarp.c   |  250 +++++++
> >  drivers/gpu/drm/imx/dpu/dpu-framegen.c    |  395 +++++++++++
> >  drivers/gpu/drm/imx/dpu/dpu-gammacor.c    |  223 ++++++
> >  drivers/gpu/drm/imx/dpu/dpu-hscaler.c     |  275 ++++++++
> >  drivers/gpu/drm/imx/dpu/dpu-kms.c         |  540 ++++++++++++++
> >  drivers/gpu/drm/imx/dpu/dpu-kms.h         |   23 +
> >  drivers/gpu/drm/imx/dpu/dpu-layerblend.c  |  348 +++++++++
> >  drivers/gpu/drm/imx/dpu/dpu-plane.c       |  799 +++++++++++++++++++++
> >  drivers/gpu/drm/imx/dpu/dpu-plane.h       |   56 ++
> >  drivers/gpu/drm/imx/dpu/dpu-prg.c         |  433 ++++++++++++
> >  drivers/gpu/drm/imx/dpu/dpu-prg.h         |   45 ++
> >  drivers/gpu/drm/imx/dpu/dpu-prv.h         |  233 ++++++
> >  drivers/gpu/drm/imx/dpu/dpu-tcon.c        |  250 +++++++
> >  drivers/gpu/drm/imx/dpu/dpu-vscaler.c     |  308 ++++++++
> >  drivers/gpu/drm/imx/dpu/dpu.h             |  385 ++++++++++
> >  34 files changed, 9849 insertions(+)
> >  create mode 100644 drivers/gpu/drm/imx/dpu/Kconfig
> >  create mode 100644 drivers/gpu/drm/imx/dpu/Makefile
> >  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-constframe.c
> >  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-core.c
> >  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-crtc.c
> >  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-crtc.h
> >  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-disengcfg.c
> >  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-dprc.c
> >  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-dprc.h
> >  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-drv.c
> >  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-drv.h
> >  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-extdst.c
> >  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-fetchdecode.c
> >  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-fetcheco.c
> >  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-fetchlayer.c
> >  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-fetchunit.c
> >  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-fetchunit.h
> >  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-fetchwarp.c
> >  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-framegen.c
> >  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-gammacor.c
> >  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-hscaler.c
> >  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-kms.c
> >  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-kms.h
> >  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-layerblend.c
> >  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-plane.c
> >  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-plane.h
> >  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-prg.c
> >  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-prg.h
> >  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-prv.h
> >  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-tcon.c
> >  create mode 100644 drivers/gpu/drm/imx/dpu/dpu-vscaler.c
> >  create mode 100644 drivers/gpu/drm/imx/dpu/dpu.h
> > 
> 
> [...]
> 
> > diff --git a/drivers/gpu/drm/imx/dpu/dpu-core.c b/drivers/gpu/drm/imx/dpu/dpu-core.c
> > new file mode 100644
> > index 00000000..7dab6cc
> > --- /dev/null
> > +++ b/drivers/gpu/drm/imx/dpu/dpu-core.c
> 
> [...]
> 
> > +static int dpu_get_irqs(struct platform_device *pdev, struct dpu_soc *dpu)
> > +{
> > +	unsigned int i, j;
> > +
> > +	/* do not get the reserved irq */
> > +	for (i = 0, j = 0; i < DPU_IRQ_COUNT - 1; i++, j++) {
> > +		if (i == DPU_IRQ_RESERVED)
> > +			j++;
> > +
> > +		dpu->irq[j] = platform_get_irq(pdev, i);
> > +		if (dpu->irq[j] < 0) {
> > +			dev_err_probe(dpu->dev, dpu->irq[j],
> > +				      "failed to get irq\n");
> > +			return dpu->irq[i];
> 
> I think you want 'return dpu->irq[j]'.

Good catch.

> 
> > +		}
> > +	}
> > +
> > +	return 0;
> > +}
> 
> [...]
> 
> > +static const struct dpu_irq_handler_map {
> > +	void (*handler)(struct irq_desc *desc);
> > +} dpu_irq_handler_maps[DPU_IRQ_COUNT] = {
> > +	{},						/* 0 */
> > +	{},						/* 1 */
> > +	{},						/* 2 */
> > +	{dpu_extdst0_shdload_irq_handler},		/* 3 */
> > +	{},						/* 4 */
> > +	{},						/* 5 */
> > +	{dpu_extdst4_shdload_irq_handler},		/* 6 */
> > +	{},						/* 7 */
> > +	{},						/* 8 */
> > +	{dpu_extdst1_shdload_irq_handler},		/* 9 */
> > +	{},						/* 10 */
> > +	{},						/* 11 */
> > +	{dpu_extdst5_shdload_irq_handler},		/* 12 */
> > +	{},						/* 13 */
> > +	{},						/* 14 */
> > +	{dpu_disengcfg_shdload0_irq_handler},		/* 15 */
> > +	{dpu_disengcfg_framecomplete0_irq_handler},	/* 16 */
> > +	{dpu_disengcfg_seqcomplete0_irq_handler},	/* 17 */
> > +	{},						/* 18 */
> > +	{},						/* 19 */
> > +	{},						/* 20 */
> > +	{},						/* 21 */
> > +	{},						/* 22 */
> > +	{},						/* 23 */
> > +	{},						/* 24 */
> > +	{dpu_disengcfg_shdload1_irq_handler},		/* 25 */
> > +	{dpu_disengcfg_framecomplete1_irq_handler},	/* 26 */
> > +	{dpu_disengcfg_seqcomplete1_irq_handler},	/* 27 */
> > +	{},						/* 28 */
> > +	{},						/* 29 */
> > +	{},						/* 30 */
> > +	{},						/* 31 */
> > +	{},						/* 32 */
> > +	{},						/* 33 */
> > +	{},						/* 34 */
> > +	{/* reserved */},				/* 35 */
> > +	{},						/* 36 */
> > +	{},						/* 37 */
> > +	{},						/* 38 */
> > +	{},						/* 39 */
> > +	{},						/* 40 */
> > +	{},						/* 41 */
> > +	{},						/* 42 */
> > +	{},						/* 43 */
> > +	{},						/* 44 */
> > +	{},						/* 45 */
> > +	{},						/* 46 */
> > +	{},						/* 47 */
> > +	{},						/* 48 */
> > +};
> 
> Why not make this an array of pointers to functions. Do we need a struct?
> Something like:
> 
> static void (* const dpu_irq_handler[DPU_IRQ_COUNT])(struct irq_desc *) = {
> 	[3] = dpu_extdst0_shdload_irq_handler,
> 	[6] = dpu_extdst4_shdload_irq_handler,
> 	...
> };

Alright, will use the function array.

> 
> [...]
> 
> > +static int
> > +dpu_get_fetchunits_for_plane_grp(struct dpu_soc *dpu,
> > +				 const struct dpu_units *us,
> > +				 struct dpu_fetchunit ***fu,
> > +				 unsigned int *cnt,
> > +				 struct dpu_fetchunit *
> > +						(*get)(struct dpu_soc *dpu,
> > +						       unsigned int id))
> > +{
> > +	unsigned int fu_cnt = 0;
> > +	int i, j, ret;
> > +
> > +	for (i = 0; i < us->cnt; i++) {
> > +		if (us->types[i] == DPU_DISP)
> > +			fu_cnt++;
> > +	}
> > +
> > +	*cnt = fu_cnt;
> > +
> > +	*fu = devm_kcalloc(dpu->dev, fu_cnt, sizeof(**fu), GFP_KERNEL);
> > +	if (!(*fu))
> > +		return -ENOMEM;
> > +
> > +	for (i = 0, j = 0; i < us->cnt; i++) {
> > +		if (us->types[i] != DPU_DISP)
> > +			continue;
> > +
> > +		(*fu)[j] = (*get)(dpu, us->ids[i]);
> 
> You can also call get() directly. No need to dereference function
> pointers.

Will do.

> 
> > +		if (IS_ERR((*fu)[j])) {
> > +			ret = PTR_ERR((*fu)[j]);
> > +			dev_err(dpu->dev, "failed to get %s%d: %d\n",
> > +						us->name, us->ids[i], ret);
> > +			return ret;
> > +		}
> > +		j++;
> > +	}
> > +
> > +	return 0;
> > +}
> 
> [...]
> 
> > +static void
> > +dpu_put_fetchunits_for_plane_grp(struct dpu_fetchunit ***fu,
> > +				 unsigned int *cnt,
> > +				 void (*put)(struct dpu_fetchunit *fu))
> > +{
> > +	int i;
> > +
> > +	for (i = 0; i < *cnt; i++)
> > +		(*put)((*fu)[i]);
> 
> Same here, you can call put() directly.

Will do.

Thanks,
Liu Ying