mbox series

[0/4] DRM driver for ST-Ericsson MCDE

Message ID 20190207083647.20615-1-linus.walleij@linaro.org (mailing list archive)
Headers show
Series DRM driver for ST-Ericsson MCDE | expand

Message

Linus Walleij Feb. 7, 2019, 8:36 a.m. UTC
This adds a driver for the ST-Ericsson MCDE.

I had to come up with some way to support passing an external
encoder to the simple KMS helper to make DSI work with the
simple KMS helper.

This work was motivated by the ongoing work on the LIMA driver,
as Ux500 has the MALI400 so once that driver is in place
as well, there will be a full graphic stack for Ux500 with
this display driver, which is pretty neat.

Linus Walleij (4):
  drm/simple_kms_helper: enable use of external encoder
  drm/mcde: Add device tree bindings
  drm/mcde: Add new driver for ST-Ericsson MCDE
  ARM: dts: Ux500: Add MCDE and Samsung display

 .../devicetree/bindings/display/ste,mcde.txt  |  110 ++
 Documentation/gpu/drivers.rst                 |    1 +
 Documentation/gpu/mcde.rst                    |    6 +
 arch/arm/boot/dts/ste-dbx5x0.dtsi             |   36 +-
 arch/arm/boot/dts/ste-href-stuib.dtsi         |   25 +
 arch/arm/boot/dts/ste-href-tvk1281618.dtsi    |   25 +
 drivers/gpu/drm/Kconfig                       |    2 +
 drivers/gpu/drm/Makefile                      |    1 +
 drivers/gpu/drm/drm_simple_kms_helper.c       |   23 +-
 drivers/gpu/drm/mcde/Kconfig                  |   18 +
 drivers/gpu/drm/mcde/Makefile                 |    3 +
 drivers/gpu/drm/mcde/mcde_display.c           | 1285 +++++++++++++++
 drivers/gpu/drm/mcde/mcde_drm.h               |   52 +
 drivers/gpu/drm/mcde/mcde_drv.c               |  540 +++++++
 drivers/gpu/drm/mcde/mcde_dsi.c               | 1376 +++++++++++++++++
 15 files changed, 3493 insertions(+), 10 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/ste,mcde.txt
 create mode 100644 Documentation/gpu/mcde.rst
 create mode 100644 drivers/gpu/drm/mcde/Kconfig
 create mode 100644 drivers/gpu/drm/mcde/Makefile
 create mode 100644 drivers/gpu/drm/mcde/mcde_display.c
 create mode 100644 drivers/gpu/drm/mcde/mcde_drm.h
 create mode 100644 drivers/gpu/drm/mcde/mcde_drv.c
 create mode 100644 drivers/gpu/drm/mcde/mcde_dsi.c

Comments

Daniel Vetter Feb. 7, 2019, 10:28 p.m. UTC | #1
On Thu, Feb 07, 2019 at 11:22:39PM +0100, Daniel Vetter wrote:
> On Thu, Feb 07, 2019 at 09:36:46AM +0100, Linus Walleij wrote:
> > +static const struct drm_mode_config_funcs mode_config_funcs = {
> > +	.fb_create = drm_gem_fb_create,
> 
> You need drm_gem_fb_create_with_dirty here because you have a manual
> upload screen. Also might head the advice from the kerneldoc and check
> your buffer alignment constraints here instead of in the check callback.
> But I guess either works, best would be if dumb_create would align stuff
> correctly (which it should), but since this is super theoretical (usually
> modes are even enough), who cares :-)

Forgot to mention: You might want to wire up the damage rect stuff and
only upload the part of the screen that userspace/fbdev tells you has
actually changed. Doesn't apply to all (or even most) userspace just yet,
since brand new stuff.
-Daniel
Sam Ravnborg Feb. 8, 2019, 7:31 p.m. UTC | #2
Hi Linus.

Good looking driver. A few nits in the following.
I did not try to follow the code, so no proper review done, sorry.

	Sam

> +++ b/drivers/gpu/drm/mcde/mcde_display.c
> @@ -0,0 +1,1284 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2018 Linus Walleij <linus.walleij@linaro.org>
> + * Parts of this file were based on the MCDE driver by Marcus Lorentzon
> + * (C) ST-Ericsson SA 2013
> + */
> +#include <linux/clk.h>
> +#include <linux/version.h>
> +#include <linux/dma-buf.h>
> +#include <linux/of_graph.h>
> +
> +#include <drm/drmP.h>

Please do not use drmP.h in new drivers.
drmP.h is deprecated and we are working on gettting rid of it.

> +
> +static void mcde_display_enable(struct drm_simple_display_pipe *pipe,
> +				struct drm_crtc_state *cstate,
> +				struct drm_plane_state *plane_state)
> +{
> +	struct drm_crtc *crtc = &pipe->crtc;
> +	struct drm_plane *plane = &pipe->plane;
> +	struct drm_device *drm = crtc->dev;
> +	struct mcde *mcde = drm->dev_private;
> +	const struct drm_display_mode *mode = &cstate->mode;
> +	struct drm_framebuffer *fb = plane->state->fb;
> +	u32 format = fb->format->format;
> +	u32 formatter_ppl = mode->hdisplay; /* pixels per line */
> +	u32 formatter_lpf = mode->vdisplay; /* lines per frame */
> +	int pkt_size, fifo_wtrmrk;
> +	int cpp = drm_format_plane_cpp(format, 0);
> +	int formatter_cpp;
> +	struct drm_format_name_buf tmp;
> +	u32 formatter_frame;
> +	u32 pkt_div;
> +	u32 val;

...
This is a very long function. Please consider splitting it up in a
a smaller more readable set of functions.


> +	default:
> +		dev_err(drm->dev, "Unknown pixel format 0x%08x\n",
> +			fb->format->format);
> +		break;
> +	}
Despite and unknow pixel format the following code is executed.
Looks wrong, if it is OK then maybe add a comment in the default: case
to say so.

> diff --git a/drivers/gpu/drm/mcde/mcde_drm.h b/drivers/gpu/drm/mcde/mcde_drm.h
> new file mode 100644
> index 000000000000..eea6dc23436a
> --- /dev/null
> +++ b/drivers/gpu/drm/mcde/mcde_drm.h
> @@ -0,0 +1,52 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (C) 2018 Linus Walleij <linus.walleij@linaro.org>
> + * Parts of this file were based on the MCDE driver by Marcus Lorentzon
> + * (C) ST-Ericsson SA 2013
> + */
> +#include <drm/drm_simple_kms_helper.h>
> +
> +#ifndef _MCDE_DRM_H_
> +#define _MCDE_DRM_H_
> +
It is considered good practice (at least by me) that a header
file includes all necessary files, so users do not need to care.
It looks like a few is missing here.

Also expand the include guards to cover the incldue files
so they are not included twice.
This file is likely only included once, so this is only to make it look
like any other heder file.


> diff --git a/drivers/gpu/drm/mcde/mcde_drv.c b/drivers/gpu/drm/mcde/mcde_drv.c
> new file mode 100644
> index 000000000000..cb65609ac812
> --- /dev/null
> +++ b/drivers/gpu/drm/mcde/mcde_drv.c
> @@ -0,0 +1,540 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2018 Linus Walleij <linus.walleij@linaro.org>
> + * Parts of this file were based on the MCDE driver by Marcus Lorentzon
> + * (C) ST-Ericsson SA 2013
> + */
> +
> +/**
> + * DOC: ST-Ericsson MCDE Driver
> + *
> + * The MCDE (short for Multi-channel display engine) is a graphics
> + * controller found in the Ux500 chipsets, such as NovaThor U8500.
> + * It was initially conceptualized by ST Microelectronics for the
> + * successor of the Nomadik line, STn8500 but productified in the
> + * ST-Ericsson U8500 where is was used for mass-market deployments
> + * in Android phones from Samsung and Sony Ericsson.
> + *
> + * It can do 1080p30 on SDTV CCIR656, DPI-2, DBI-2 or DSI for
> + * panels with or without frame buffering and can convert most
> + * input formats including most variants of RGB and YUV.
> + *
> + * The hardware has four display pipes, and the layout is a little
> + * bit like this:
> + *
> + * Memory     -> 6 channels -> 5 formatters -> DSI/DPI -> LCD/HDMI
> + * 10 sources    (overlays)                    3 x DSI
> + *
> + * The memory has 5 input channels (memory ports):
> + * 2 channel A (LCD/TV)
> + * 2 channel B (LCD/TV)
> + * 1 channel CO/C1 (Panel with embedded buffer)
> + *
> + * 3 of the formatters are for DSI
> + * 2 of the formatters are for DPI
> + *
> + * Behind the formatters are the DSI or DPI ports, that route to
> + * the external pins of the chip. As there are 3 DSI ports and one
> + * DPI port, it is possible to configure up to 4 display pipelines.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/dma-buf.h>
> +#include <linux/irq.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/of_platform.h>
> +#include <linux/slab.h>
> +#include <linux/component.h>

Please sort include files alphabatically.

> +
> +#include <drm/drmP.h>

And like before, get rid of drmP.h

> +#include <drm/drm_atomic_helper.h>
> +#include <drm/drm_crtc_helper.h>
> +#include <drm/drm_gem.h>
> +#include <drm/drm_gem_cma_helper.h>
> +#include <drm/drm_gem_framebuffer_helper.h>
> +#include <drm/drm_fb_helper.h>
> +#include <drm/drm_fb_cma_helper.h>
> +#include <drm/drm_panel.h>
> +#include <drm/drm_of.h>
> +#include <drm/drm_bridge.h>
Also alphabetically sort needed again.

> +
> +#define MCDE_CR 0x00000000
> +#define MCDE_CR_IFIFOEMPTYLINECOUNT_V422_SHIFT 0
> +#define MCDE_CR_IFIFOEMPTYLINECOUNT_V422_MASK 0x0000003F
> +#define MCDE_CR_IFIFOCTRLEN BIT(15)
> +#define MCDE_CR_UFRECOVERY_MODE_V422 BIT(16)
> +#define MCDE_CR_WRAP_MODE_V422_SHIFT BIT(17)
> +#define MCDE_CR_AUTOCLKG_EN BIT(30)
> +#define MCDE_CR_MCDEEN BIT(31)

The register definitions are spread over several .c files.
And that is also nice so it is easy to navigate to the register
definitions in the same file.
But if refactoring then this can be annoying as you may end up with two
files that require the same register definitions.
Consider an own heder file.

> +	if (ret) {
> +		dev_err(dev, "faule to add component master\n");
Spelling error. faule => failed?

> +++ b/drivers/gpu/drm/mcde/mcde_dsi.c
> @@ -0,0 +1,1374 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +#include <linux/platform_device.h>
> +#include <linux/module.h>
> +#include <linux/clk.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/io.h>
> +#include <linux/delay.h>
> +#include <linux/component.h>
> +#include <linux/of.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/regmap.h>
> +#include <video/mipi_display.h>
Alphabetic order.

> +
> +#include <drm/drm_device.h>
> +#include <drm/drm_encoder.h>
> +#include <drm/drm_modeset_helper_vtables.h>
> +#include <drm/drm_panel.h>
> +#include <drm/drm_atomic_helper.h>
> +#include <drm/drm_crtc_helper.h>
> +#include <drm/drm_mipi_dsi.h>
> +#include <drm/drm_print.h>
> +#include <drm/drm_bridge.h>
> +#include <drm/drm_of.h>
Alphabetic order.