linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Noralf Trønnes" <noralf@tronnes.org>
To: Eric Anholt <eric@anholt.net>,
	dri-devel@lists.freedesktop.org, Rob Herring <robh+dt@kernel.org>,
	Mark Rutland <mark.rutland@arm.com>,
	devicetree@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, Heiner Kallweit <hkallweit1@gmail.com>
Subject: Re: [PATCH 2/3] drm: Add an hx8367d tinydrm driver.
Date: Sat, 27 Oct 2018 18:12:56 +0200	[thread overview]
Message-ID: <a3995168-3d9f-07b3-1e93-7ee5bd14e5a8@tronnes.org> (raw)
In-Reply-To: <20181024184313.2967-3-eric@anholt.net>


Den 24.10.2018 20.43, skrev Eric Anholt:
> I want to sort out support for tinydrm in vc4, so I needed to get a
> tinydrm-appropriate panel working and this is what I had on hand.
> This is derived from a combination of ili9341.c from tinydrm and
> fb_hx8357d.c from staging's fbtft.  The register header is copied
> directly from staging's fbtft, on the assumption that we will delete
> that copy later.
>
> Signed-off-by: Eric Anholt <eric@anholt.net>
> ---
>   MAINTAINERS                       |   7 +
>   drivers/gpu/drm/tinydrm/Kconfig   |  11 ++
>   drivers/gpu/drm/tinydrm/Makefile  |   1 +
>   drivers/gpu/drm/tinydrm/hx8357d.c | 261 ++++++++++++++++++++++++++++++
>   drivers/gpu/drm/tinydrm/hx8357d.h |  71 ++++++++
>   5 files changed, 351 insertions(+)
>   create mode 100644 drivers/gpu/drm/tinydrm/hx8357d.c
>   create mode 100644 drivers/gpu/drm/tinydrm/hx8357d.h
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 39c3f6682ace..e78971e20a11 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -4623,6 +4623,13 @@ S:	Maintained
>   F:	drivers/gpu/drm/tinydrm/ili9225.c
>   F:	Documentation/devicetree/bindings/display/ilitek,ili9225.txt
>   
> +DRM DRIVER FOR HX8357D PANELS
> +M:	Eric Anholt <eric@anholt.net>
> +T:	git git://anongit.freedesktop.org/drm/drm-misc
> +S:	Maintained
> +F:	drivers/gpu/drm/tinydrm/hx8357d.c
> +F:	Documentation/devicetree/bindings/display/himax,hx8357d.txt
> +
>   DRM DRIVER FOR INTEL I810 VIDEO CARDS
>   S:	Orphan / Obsolete
>   F:	drivers/gpu/drm/i810/
> diff --git a/drivers/gpu/drm/tinydrm/Kconfig b/drivers/gpu/drm/tinydrm/Kconfig
> index 16f4b5c91f1b..2c408ac1a900 100644
> --- a/drivers/gpu/drm/tinydrm/Kconfig
> +++ b/drivers/gpu/drm/tinydrm/Kconfig
> @@ -10,6 +10,17 @@ menuconfig DRM_TINYDRM
>   config TINYDRM_MIPI_DBI
>   	tristate
>   
> +config TINYDRM_HX8357D
> +	tristate "DRM support for HX8357D display panels"
> +	depends on DRM_TINYDRM && SPI
> +	depends on BACKLIGHT_CLASS_DEVICE
> +	select TINYDRM_MIPI_DBI
> +	help
> +	  DRM driver for the following HX8357D panels:
> +	  * YX350HV15-T 3.5" 340x350 TFT (Adafruit 3.5")
> +
> +	  If M is selected the module will be called hx8357d.
> +
>   config TINYDRM_ILI9225
>   	tristate "DRM support for ILI9225 display panels"
>   	depends on DRM_TINYDRM && SPI
> diff --git a/drivers/gpu/drm/tinydrm/Makefile b/drivers/gpu/drm/tinydrm/Makefile
> index 14d99080665a..f823066f7743 100644
> --- a/drivers/gpu/drm/tinydrm/Makefile
> +++ b/drivers/gpu/drm/tinydrm/Makefile
> @@ -4,6 +4,7 @@ obj-$(CONFIG_DRM_TINYDRM)		+= core/
>   obj-$(CONFIG_TINYDRM_MIPI_DBI)		+= mipi-dbi.o
>   
>   # Displays
> +obj-$(CONFIG_TINYDRM_HX8357D)		+= hx8357d.o
>   obj-$(CONFIG_TINYDRM_ILI9225)		+= ili9225.o
>   obj-$(CONFIG_TINYDRM_ILI9341)		+= ili9341.o
>   obj-$(CONFIG_TINYDRM_MI0283QT)		+= mi0283qt.o
> diff --git a/drivers/gpu/drm/tinydrm/hx8357d.c b/drivers/gpu/drm/tinydrm/hx8357d.c
> new file mode 100644
> index 000000000000..51d4da624d57
> --- /dev/null
> +++ b/drivers/gpu/drm/tinydrm/hx8357d.c
> @@ -0,0 +1,261 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * DRM driver for the HX8357D LCD controller
> + *
> + * Copyright 2018 Broadcom
> + * Copyright 2018 David Lechner <david@lechnology.com>
> + * Copyright 2016 Noralf Trønnes
> + * Copyright (C) 2015 Adafruit Industries
> + * Copyright (C) 2013 Christian Vogelgsang
> + */
> +
> +#include <linux/backlight.h>
> +#include <linux/delay.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/module.h>
> +#include <linux/property.h>
> +#include <linux/spi/spi.h>
> +
> +#include <drm/drm_fb_helper.h>
> +#include <drm/drm_gem_framebuffer_helper.h>
> +#include <drm/drm_modeset_helper.h>
> +#include <drm/tinydrm/mipi-dbi.h>
> +#include <drm/tinydrm/tinydrm-helpers.h>
> +#include <video/mipi_display.h>
> +#include "hx8357d.h"

I prefer to have the defines in the driver instead of an extra header file.
The reason is that usually only a handful of defines are actually used,
in this case it's 9.

> +
> +#define HX8357D_MADCTL_MY  0x80
> +#define HX8357D_MADCTL_MX  0x40
> +#define HX8357D_MADCTL_MV  0x20
> +#define HX8357D_MADCTL_ML  0x10
> +#define HX8357D_MADCTL_RGB 0x00
> +#define HX8357D_MADCTL_BGR 0x08
> +#define HX8357D_MADCTL_MH  0x04
> +
> +static void yx240qv29_enable(struct drm_simple_display_pipe *pipe,
> +			     struct drm_crtc_state *crtc_state,
> +			     struct drm_plane_state *plane_state)
> +{
> +	struct tinydrm_device *tdev = pipe_to_tinydrm(pipe);
> +	struct mipi_dbi *mipi = mipi_dbi_from_tinydrm(tdev);
> +	u8 addr_mode;
> +	int ret;
> +
> +	DRM_DEBUG_KMS("\n");
> +
> +	ret = mipi_dbi_poweron_conditional_reset(mipi);
> +	if (ret < 0)
> +		return;
> +	if (ret == 1)
> +		goto out_enable;
> +
> +	/* setextc */
> +	mipi_dbi_command(mipi, HX8357D_SETC, 0xFF, 0x83, 0x57);
> +	msleep(150);
> +
> +	/* setRGB which also enables SDO */
> +	mipi_dbi_command(mipi, HX8357_SETRGB, 0x00, 0x00, 0x06, 0x06);
> +
> +	/* -1.52V */
> +	mipi_dbi_command(mipi, HX8357D_SETCOM, 0x25);
> +
> +	/* Normal mode 70Hz, Idle mode 55 Hz */
> +	mipi_dbi_command(mipi, HX8357_SETOSC, 0x68);
> +
> +	/* Set Panel - BGR, Gate direction swapped */
> +	mipi_dbi_command(mipi, HX8357_SETPANEL, 0x05);
> +
> +	mipi_dbi_command(mipi, HX8357_SETPWR1,
> +			 0x00,  /* Not deep standby */
> +			 0x15,  /* BT */
> +			 0x1C,  /* VSPR */
> +			 0x1C,  /* VSNR */
> +			 0x83,  /* AP */
> +			 0xAA);  /* FS */
> +
> +	mipi_dbi_command(mipi, HX8357D_SETSTBA,
> +			 0x50,  /* OPON normal */
> +			 0x50,  /* OPON idle */
> +			 0x01,  /* STBA */
> +			 0x3C,  /* STBA */
> +			 0x1E,  /* STBA */
> +			 0x08);  /* GEN */
> +
> +	mipi_dbi_command(mipi, HX8357D_SETCYC,
> +			 0x02,  /* NW 0x02 */
> +			 0x40,  /* RTN */
> +			 0x00,  /* DIV */
> +			 0x2A,  /* DUM */
> +			 0x2A,  /* DUM */
> +			 0x0D,  /* GDON */
> +			 0x78);  /* GDOFF */
> +
> +	mipi_dbi_command(mipi, HX8357D_SETGAMMA,
> +			 0x02,
> +			 0x0A,
> +			 0x11,
> +			 0x1d,
> +			 0x23,
> +			 0x35,
> +			 0x41,
> +			 0x4b,
> +			 0x4b,
> +			 0x42,
> +			 0x3A,
> +			 0x27,
> +			 0x1B,
> +			 0x08,
> +			 0x09,
> +			 0x03,
> +			 0x02,
> +			 0x0A,
> +			 0x11,
> +			 0x1d,
> +			 0x23,
> +			 0x35,
> +			 0x41,
> +			 0x4b,
> +			 0x4b,
> +			 0x42,
> +			 0x3A,
> +			 0x27,
> +			 0x1B,
> +			 0x08,
> +			 0x09,
> +			 0x03,
> +			 0x00,
> +			 0x01);
> +
> +	/* 16 bit */
> +	mipi_dbi_command(mipi, MIPI_DCS_SET_PIXEL_FORMAT,
> +			 MIPI_DCS_PIXEL_FMT_16BIT);
> +
> +	/* TE off */
> +	mipi_dbi_command(mipi, MIPI_DCS_SET_TEAR_ON, 0x00);
> +
> +	/* tear line */
> +	mipi_dbi_command(mipi, MIPI_DCS_SET_TEAR_SCANLINE, 0x00, 0x02);
> +
> +	/* Exit Sleep */
> +	mipi_dbi_command(mipi, MIPI_DCS_EXIT_SLEEP_MODE);
> +	msleep(150);
> +
> +	/* display on */
> +	mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_ON);
> +	usleep_range(5000, 7000);
> +
> +out_enable:
> +	switch (mipi->rotation) {
> +	default:
> +		addr_mode = HX8357D_MADCTL_MX | HX8357D_MADCTL_MY;
> +		break;
> +	case 90:
> +		addr_mode = HX8357D_MADCTL_MV | HX8357D_MADCTL_MY;
> +		break;
> +	case 180:
> +		addr_mode = 0;
> +		break;
> +	case 270:
> +		addr_mode = HX8357D_MADCTL_MV | HX8357D_MADCTL_MX;
> +		break;
> +	}
> +	mipi_dbi_command(mipi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode);
> +	mipi_dbi_enable_flush(mipi, crtc_state, plane_state);
> +}
> +
> +static const struct drm_simple_display_pipe_funcs hx8357d_pipe_funcs = {
> +	.enable = yx240qv29_enable,
> +	.disable = mipi_dbi_pipe_disable,
> +	.update = tinydrm_display_pipe_update,
> +	.prepare_fb = drm_gem_fb_simple_display_pipe_prepare_fb,
> +};
> +
> +static const struct drm_display_mode yx350hv15_mode = {
> +	TINYDRM_MODE(320, 480, 60, 75),
> +};
> +
> +DEFINE_DRM_GEM_CMA_FOPS(hx8357d_fops);
> +
> +static struct drm_driver hx8357d_driver = {
> +	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | DRIVER_ATOMIC,
> +	.fops			= &hx8357d_fops,
> +	TINYDRM_GEM_DRIVER_OPS,
> +	.debugfs_init		= mipi_dbi_debugfs_init,
> +	.name			= "hx8357d",
> +	.desc			= "HX8357D",
> +	.date			= "20181023",
> +	.major			= 1,
> +	.minor			= 0,
> +};
> +
> +static const struct of_device_id hx8357d_of_match[] = {
> +	{ .compatible = "adafruit,yx350hv15" },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, hx8357d_of_match);
> +
> +static const struct spi_device_id hx8357d_id[] = {
> +	{ "hx8357d", 0 },

Last time I tried, module autoloading didn't work unless this contains
the last part of the compatible. In this case: "yx350hv15".
Have you checked that autoloading does work?

Otherwise this looks good:
Reviewed-by: Noralf Trønnes <noralf@tronnes.org>

> +	{ }
> +};
> +MODULE_DEVICE_TABLE(spi, hx8357d_id);
> +
> +static int hx8357d_probe(struct spi_device *spi)
> +{
> +	struct device *dev = &spi->dev;
> +	struct mipi_dbi *mipi;
> +	struct gpio_desc *dc;
> +	u32 rotation = 0;
> +	int ret;
> +
> +	mipi = devm_kzalloc(dev, sizeof(*mipi), GFP_KERNEL);
> +	if (!mipi)
> +		return -ENOMEM;
> +
> +	dc = devm_gpiod_get(dev, "dc", GPIOD_OUT_LOW);
> +	if (IS_ERR(dc)) {
> +		DRM_DEV_ERROR(dev, "Failed to get gpio 'dc'\n");
> +		return PTR_ERR(dc);
> +	}
> +
> +	mipi->backlight = devm_of_find_backlight(dev);
> +	if (IS_ERR(mipi->backlight))
> +		return PTR_ERR(mipi->backlight);
> +
> +	device_property_read_u32(dev, "rotation", &rotation);
> +
> +	ret = mipi_dbi_spi_init(spi, mipi, dc);
> +	if (ret)
> +		return ret;
> +
> +	ret = mipi_dbi_init(&spi->dev, mipi, &hx8357d_pipe_funcs,
> +			    &hx8357d_driver, &yx350hv15_mode, rotation);
> +	if (ret)
> +		return ret;
> +
> +	spi_set_drvdata(spi, mipi);
> +
> +	return devm_tinydrm_register(&mipi->tinydrm);
> +}
> +
> +static void hx8357d_shutdown(struct spi_device *spi)
> +{
> +	struct mipi_dbi *mipi = spi_get_drvdata(spi);
> +
> +	tinydrm_shutdown(&mipi->tinydrm);
> +}
> +
> +static struct spi_driver hx8357d_spi_driver = {
> +	.driver = {
> +		.name = "hx8357d",
> +		.of_match_table = hx8357d_of_match,
> +	},
> +	.id_table = hx8357d_id,
> +	.probe = hx8357d_probe,
> +	.shutdown = hx8357d_shutdown,
> +};
> +module_spi_driver(hx8357d_spi_driver);
> +
> +MODULE_DESCRIPTION("HX8357D DRM driver");
> +MODULE_AUTHOR("Eric Anholt <eric@anholt.net>");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/gpu/drm/tinydrm/hx8357d.h b/drivers/gpu/drm/tinydrm/hx8357d.h
> new file mode 100644
> index 000000000000..6180b093f94f
> --- /dev/null
> +++ b/drivers/gpu/drm/tinydrm/hx8357d.h
> @@ -0,0 +1,71 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * This is our library for the Adafruit  ILI9341 Breakout and Shield
> + * ----> http://www.adafruit.com/products/1651
> + *
> + * Check out the links above for our tutorials and wiring diagrams
> + * These displays use SPI to communicate, 4 or 5 pins are required to
> + * interface (RST is optional)
> + * Adafruit invests time and resources providing this open source code,
> + * please support Adafruit and open-source hardware by purchasing
> + * products from Adafruit!
> + *
> + * Written by Limor Fried/Ladyada for Adafruit Industries.
> + * MIT license, all text above must be included in any redistribution
> + */
> +
> +#ifndef __HX8357_H__
> +#define __HX8357_H__
> +
> +#define HX8357D 0xD
> +#define HX8357B 0xB
> +
> +#define HX8357_TFTWIDTH  320
> +#define HX8357_TFTHEIGHT 480
> +
> +#define HX8357_SETOSC 0xB0
> +#define HX8357_SETPWR1 0xB1
> +#define HX8357B_SETDISPLAY 0xB2
> +#define HX8357_SETRGB 0xB3
> +#define HX8357D_SETCOM  0xB6
> +
> +#define HX8357B_SETDISPMODE  0xB4
> +#define HX8357D_SETCYC  0xB4
> +#define HX8357B_SETOTP 0xB7
> +#define HX8357D_SETC 0xB9
> +
> +#define HX8357B_SET_PANEL_DRIVING 0xC0
> +#define HX8357D_SETSTBA 0xC0
> +#define HX8357B_SETDGC  0xC1
> +#define HX8357B_SETID  0xC3
> +#define HX8357B_SETDDB  0xC4
> +#define HX8357B_SETDISPLAYFRAME 0xC5
> +#define HX8357B_GAMMASET 0xC8
> +#define HX8357B_SETCABC  0xC9
> +#define HX8357_SETPANEL  0xCC
> +
> +#define HX8357B_SETPOWER 0xD0
> +#define HX8357B_SETVCOM 0xD1
> +#define HX8357B_SETPWRNORMAL 0xD2
> +
> +#define HX8357B_RDID1   0xDA
> +#define HX8357B_RDID2   0xDB
> +#define HX8357B_RDID3   0xDC
> +#define HX8357B_RDID4   0xDD
> +
> +#define HX8357D_SETGAMMA 0xE0
> +
> +#define HX8357B_SETGAMMA 0xC8
> +#define HX8357B_SETPANELRELATED  0xE9
> +
> +/* Color definitions */
> +#define	HX8357_BLACK   0x0000
> +#define	HX8357_BLUE    0x001F
> +#define	HX8357_RED     0xF800
> +#define	HX8357_GREEN   0x07E0
> +#define HX8357_CYAN    0x07FF
> +#define HX8357_MAGENTA 0xF81F
> +#define HX8357_YELLOW  0xFFE0
> +#define HX8357_WHITE   0xFFFF
> +
> +#endif /* __HX8357_H__ */


  reply	other threads:[~2018-10-27 16:13 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-10-24 18:43 [PATCH 0/3] drm: tinydrm driver for adafruit PiTFT 3.5" touchscreen Eric Anholt
2018-10-24 18:43 ` [PATCH 1/3] dt-bindings: new binding for Himax HX8357D display panels Eric Anholt
2018-10-25 21:42   ` Rob Herring
2018-10-27 16:10   ` Noralf Trønnes
2018-10-24 18:43 ` [PATCH 2/3] drm: Add an hx8367d tinydrm driver Eric Anholt
2018-10-27 16:12   ` Noralf Trønnes [this message]
2018-10-30 22:46     ` Eric Anholt
2018-10-24 18:43 ` [PATCH 3/3] drm/tinydrm: Fix setting of the column/page end addresses Eric Anholt
2018-10-27 16:13   ` Noralf Trønnes
2018-10-25 16:29 ` [PATCH 0/3] drm: tinydrm driver for adafruit PiTFT 3.5" touchscreen Eric Anholt
2018-10-25 21:52   ` Noralf Trønnes
2018-10-26  2:30     ` Eric Anholt
2018-10-26 19:16       ` Noralf Trønnes
2018-10-26 20:57         ` Noralf Trønnes
2018-10-31 16:27   ` Noralf Trønnes

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=a3995168-3d9f-07b3-1e93-7ee5bd14e5a8@tronnes.org \
    --to=noralf@tronnes.org \
    --cc=devicetree@vger.kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=eric@anholt.net \
    --cc=hkallweit1@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=robh+dt@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).