On Sun, Aug 09, 2020 at 11:51:02PM +0200, Linus Walleij wrote: > This makes it possible to use the s6e63m0 panel with a > DSI host, such as in the Samsung GT-I8190 (Golden) mobile > phone. > > Cc: Stephan Gerhold <stephan@xxxxxxxxxxx> > Cc: Paweł Chmiel <pawel.mikolaj.chmiel@xxxxxxxxx> > Signed-off-by: Linus Walleij <linus.walleij@xxxxxxxxxx> > --- > drivers/gpu/drm/panel/Kconfig | 8 ++ > drivers/gpu/drm/panel/Makefile | 1 + > .../gpu/drm/panel/panel-samsung-s6e63m0-dsi.c | 128 ++++++++++++++++++ > .../gpu/drm/panel/panel-samsung-s6e63m0-spi.c | 2 +- > drivers/gpu/drm/panel/panel-samsung-s6e63m0.c | 4 +- > drivers/gpu/drm/panel/panel-samsung-s6e63m0.h | 4 +- > 6 files changed, 144 insertions(+), 3 deletions(-) > create mode 100644 drivers/gpu/drm/panel/panel-samsung-s6e63m0-dsi.c > > diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig > index 96e1548e475f..731e84c5a13b 100644 > --- a/drivers/gpu/drm/panel/Kconfig > +++ b/drivers/gpu/drm/panel/Kconfig > @@ -343,6 +343,14 @@ config DRM_PANEL_SAMSUNG_S6E63M0_SPI > Say Y here if you want to be able to access the Samsung > S6E63M0 panel using SPI. > > +config DRM_PANEL_SAMSUNG_S6E63M0_DSI > + tristate "Samsung S6E63M0 RGB DSI interface" > + depends on DRM_MIPI_DSI > + depends on DRM_PANEL_SAMSUNG_S6E63M0 > + help > + Say Y here if you want to be able to access the Samsung > + S6E63M0 panel using DSI. > + > config DRM_PANEL_SAMSUNG_S6E88A0_AMS452EF01 > tristate "Samsung AMS452EF01 panel with S6E88A0 DSI video mode controller" > depends on OF > diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile > index 9cf71adfa794..14212cae3c29 100644 > --- a/drivers/gpu/drm/panel/Makefile > +++ b/drivers/gpu/drm/panel/Makefile > @@ -35,6 +35,7 @@ obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2) += panel-samsung-s6e3ha2.o > obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03) += panel-samsung-s6e63j0x03.o > obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E63M0) += panel-samsung-s6e63m0.o > obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E63M0_SPI) += panel-samsung-s6e63m0-spi.o > +obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E63M0_DSI) += panel-samsung-s6e63m0-dsi.o > obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E88A0_AMS452EF01) += panel-samsung-s6e88a0-ams452ef01.o > obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0) += panel-samsung-s6e8aa0.o > obj-$(CONFIG_DRM_PANEL_SEIKO_43WVF1G) += panel-seiko-43wvf1g.o > diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e63m0-dsi.c b/drivers/gpu/drm/panel/panel-samsung-s6e63m0-dsi.c > new file mode 100644 > index 000000000000..f4927a6ce26d > --- /dev/null > +++ b/drivers/gpu/drm/panel/panel-samsung-s6e63m0-dsi.c > @@ -0,0 +1,128 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * DSI interface to the Samsung S6E63M0 panel. > + * (C) 2019 Linus Walleij > + */ > + > +#include <linux/module.h> > +#include <linux/delay.h> > +#include <linux/of_device.h> > + > +#include <drm/drm_mipi_dsi.h> > +#include <drm/drm_print.h> > + > +#include "panel-samsung-s6e63m0.h" > + > +#define MCS_GLOBAL_PARAM 0xb0 > +#define S6E63M0_DSI_MAX_CHUNK 15 /* CMD + 15 bytes max */ > + > +static int s6e63m0_dsi_dcs_write(struct device *dev, const u8 *data, size_t len) > +{ > + struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); > + const u8 *seqp = data; > + u8 cmd; > + u8 cmdwritten; > + int remain; > + int chunk; > + int ret; > + > + DRM_DEV_INFO(dev, "DSI writing dcs seq: %*ph\n", (int)len, data); > + We should probably remove these or demote them to debug. It's quite verbose. > + /* Pick out and skip past the DCS command */ > + cmd = *seqp; > + seqp++; > + cmdwritten = 0; > + remain = len - 1; > + chunk = remain; > + > + /* Send max S6E63M0_DSI_MAX_CHUNK bytes at a time */ > + if (chunk > S6E63M0_DSI_MAX_CHUNK) > + chunk = S6E63M0_DSI_MAX_CHUNK; > + ret = mipi_dsi_dcs_write(dsi, cmd, seqp, chunk); > + if (ret < 0) { > + DRM_DEV_ERROR(dev, > + "error sending DCS command seq cmd %02x\n", > + cmd); > + return ret; > + } > + cmdwritten += chunk; > + seqp += chunk; > + > + while (cmdwritten < remain) { > + chunk = remain - cmdwritten; > + if (chunk > S6E63M0_DSI_MAX_CHUNK) > + chunk = S6E63M0_DSI_MAX_CHUNK; > + ret = mipi_dsi_dcs_write(dsi, MCS_GLOBAL_PARAM, &cmdwritten, 1); > + if (ret < 0) { > + DRM_DEV_ERROR(dev, > + "error sending CMD %02x global param %02x\n", > + cmd, cmdwritten); > + return ret; > + } > + ret = mipi_dsi_dcs_write(dsi, cmd, seqp, chunk); > + if (ret < 0) { > + DRM_DEV_ERROR(dev, > + "error sending CMD %02x chunk\n", > + cmd); > + return ret; > + } > + cmdwritten += chunk; > + seqp += chunk; > + } > + DRM_DEV_INFO(dev, "sent command %02x %02x bytes\n", > + cmd, cmdwritten); Here as well. However, otherwise it seems to work fine on my samsung-golden, so for the entire series: Tested-by: Stephan Gerhold <stephan@xxxxxxxxxxx> I think it would be great to get a Tested-by from someone using the SPI transport as well. It seems to be used in s5pv210-aries.dtsi. Thanks! Stephan > + > + usleep_range(8000, 9000); > + > + return 0; > +} > + > +static int s6e63m0_dsi_probe(struct mipi_dsi_device *dsi) > +{ > + struct device *dev = &dsi->dev; > + int ret; > + > + dsi->lanes = 2; > + dsi->format = MIPI_DSI_FMT_RGB888; > + dsi->hs_rate = 349440000; > + dsi->lp_rate = 9600000; > + dsi->mode_flags = MIPI_DSI_MODE_VIDEO | > + MIPI_DSI_MODE_EOT_PACKET | > + MIPI_DSI_MODE_VIDEO_BURST; > + > + ret = s6e63m0_probe(dev, s6e63m0_dsi_dcs_write, true); > + if (ret) > + return ret; > + > + ret = mipi_dsi_attach(dsi); > + if (ret < 0) > + s6e63m0_remove(dev); > + > + return ret; > +} > + > +static int s6e63m0_dsi_remove(struct mipi_dsi_device *dsi) > +{ > + mipi_dsi_detach(dsi); > + return s6e63m0_remove(&dsi->dev); > +} > + > +static const struct of_device_id s6e63m0_dsi_of_match[] = { > + { .compatible = "samsung,s6e63m0" }, > + { /* sentinel */ } > +}; > +MODULE_DEVICE_TABLE(of, s6e63m0_dsi_of_match); > + > +static struct mipi_dsi_driver s6e63m0_dsi_driver = { > + .probe = s6e63m0_dsi_probe, > + .remove = s6e63m0_dsi_remove, > + .driver = { > + .name = "panel-samsung-s6e63m0", > + .of_match_table = s6e63m0_dsi_of_match, > + }, > +}; > +module_mipi_dsi_driver(s6e63m0_dsi_driver); > + > +MODULE_AUTHOR("Linus Walleij <linusw@xxxxxxxxxx>"); > +MODULE_DESCRIPTION("s6e63m0 LCD DSI Driver"); > +MODULE_LICENSE("GPL v2"); > diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e63m0-spi.c b/drivers/gpu/drm/panel/panel-samsung-s6e63m0-spi.c > index 4082fbd75b79..0587eac52f2a 100644 > --- a/drivers/gpu/drm/panel/panel-samsung-s6e63m0-spi.c > +++ b/drivers/gpu/drm/panel/panel-samsung-s6e63m0-spi.c > @@ -60,7 +60,7 @@ static int s6e63m0_spi_probe(struct spi_device *spi) > DRM_DEV_ERROR(dev, "spi setup failed.\n"); > return ret; > } > - return s6e63m0_probe(dev, s6e63m0_spi_dcs_write); > + return s6e63m0_probe(dev, s6e63m0_spi_dcs_write, false); > } > > static int s6e63m0_spi_remove(struct spi_device *spi) > diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c b/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c > index 610676ef8a75..c6d17e938955 100644 > --- a/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c > +++ b/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c > @@ -403,7 +403,8 @@ static int s6e63m0_backlight_register(struct s6e63m0 *ctx) > } > > int s6e63m0_probe(struct device *dev, > - int (*dcs_write)(struct device *dev, const u8 *data, size_t len)) > + int (*dcs_write)(struct device *dev, const u8 *data, size_t len), > + bool dsi_mode) > { > struct s6e63m0 *ctx; > int ret; > @@ -436,6 +437,7 @@ int s6e63m0_probe(struct device *dev, > } > > drm_panel_init(&ctx->panel, dev, &s6e63m0_drm_funcs, > + dsi_mode ? DRM_MODE_CONNECTOR_DSI : > DRM_MODE_CONNECTOR_DPI); > > ret = s6e63m0_backlight_register(ctx); > diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e63m0.h b/drivers/gpu/drm/panel/panel-samsung-s6e63m0.h > index 44e31f39f211..229e23b0c97a 100644 > --- a/drivers/gpu/drm/panel/panel-samsung-s6e63m0.h > +++ b/drivers/gpu/drm/panel/panel-samsung-s6e63m0.h > @@ -4,7 +4,9 @@ > #define _PANEL_SAMSUNG_S6E63M0_H > > int s6e63m0_probe(struct device *dev, > - int (*dcs_write)(struct device *dev, const u8 *data, size_t len)); > + int (*dcs_write)(struct device *dev, const u8 *data, > + size_t len), > + bool dsi_mode); > int s6e63m0_remove(struct device *dev); > > #endif /* _PANEL_SAMSUNG_S6E63M0_H */ > -- > 2.26.2 > _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel