diff options
Diffstat (limited to 'drivers/gpu/drm/panel')
53 files changed, 3599 insertions, 376 deletions
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index 2b9d6db7860b..869e535faefa 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -300,6 +300,7 @@ config DRM_PANEL_LEADTEK_LTK500HD1829 config DRM_PANEL_SAMSUNG_LD9040 tristate "Samsung LD9040 RGB/SPI panel" depends on OF && SPI + depends on BACKLIGHT_CLASS_DEVICE select VIDEOMODE_HELPERS config DRM_PANEL_LG_LB035Q02 @@ -553,6 +554,13 @@ config DRM_PANEL_SAMSUNG_S6D27A1 This panel can be found in Samsung Galaxy Ace 2 GT-I8160 mobile phone. +config DRM_PANEL_SAMSUNG_S6D7AA0 + tristate "Samsung S6D7AA0 MIPI-DSI video mode panel controller" + depends on OF + depends on BACKLIGHT_CLASS_DEVICE + select DRM_MIPI_DSI + select VIDEOMODE_HELPERS + config DRM_PANEL_SAMSUNG_S6E3HA2 tristate "Samsung S6E3HA2 DSI video mode panel" depends on OF @@ -726,6 +734,17 @@ config DRM_PANEL_SONY_TULIP_TRULY_NT35521 NT35521 1280x720 video mode panel as found on Sony Xperia M4 Aqua phone. +config DRM_PANEL_STARTEK_KD070FHFID015 + tristate "STARTEK KD070FHFID015 panel" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y here if you want to enable support for STARTEK KD070FHFID015 DSI panel + based on RENESAS-R69429 controller. The pannel is a 7-inch TFT LCD display + with a resolution of 1024 x 600 pixels. It provides a MIPI DSI interface to + the host, a built-in LED backlight and touch controller. + config DRM_PANEL_TDO_TL070WSH30 tristate "TDO TL070WSH30 DSI panel" depends on OF @@ -786,6 +805,17 @@ config DRM_PANEL_VISIONOX_VTDR6130 Say Y here if you want to enable support for Visionox VTDR6130 1080x2400 AMOLED DSI panel. +config DRM_PANEL_VISIONOX_R66451 + tristate "Visionox R66451" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + select DRM_DISPLAY_DP_HELPER + select DRM_DISPLAY_HELPER + help + Say Y here if you want to enable support for Visionox + R66451 1080x2340 AMOLED DSI panel. + config DRM_PANEL_WIDECHIPS_WS2401 tristate "Widechips WS2401 DPI panel driver" depends on SPI && GPIOLIB diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index ff169781e82d..433e93d57949 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -54,6 +54,7 @@ obj-$(CONFIG_DRM_PANEL_SAMSUNG_DB7430) += panel-samsung-db7430.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6D16D0) += panel-samsung-s6d16d0.o obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6D27A1) += panel-samsung-s6d27a1.o +obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6D7AA0) += panel-samsung-s6d7aa0.o 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 @@ -73,6 +74,7 @@ obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7789V) += panel-sitronix-st7789v.o obj-$(CONFIG_DRM_PANEL_SONY_ACX565AKM) += panel-sony-acx565akm.o obj-$(CONFIG_DRM_PANEL_SONY_TD4353_JDI) += panel-sony-td4353-jdi.o obj-$(CONFIG_DRM_PANEL_SONY_TULIP_TRULY_NT35521) += panel-sony-tulip-truly-nt35521.o +obj-$(CONFIG_DRM_PANEL_STARTEK_KD070FHFID015) += panel-startek-kd070fhfid015.o obj-$(CONFIG_DRM_PANEL_TDO_TL070WSH30) += panel-tdo-tl070wsh30.o obj-$(CONFIG_DRM_PANEL_TPO_TD028TTEC1) += panel-tpo-td028ttec1.o obj-$(CONFIG_DRM_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o @@ -80,5 +82,6 @@ obj-$(CONFIG_DRM_PANEL_TPO_TPG110) += panel-tpo-tpg110.o obj-$(CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA) += panel-truly-nt35597.o obj-$(CONFIG_DRM_PANEL_VISIONOX_RM69299) += panel-visionox-rm69299.o obj-$(CONFIG_DRM_PANEL_VISIONOX_VTDR6130) += panel-visionox-vtdr6130.o +obj-$(CONFIG_DRM_PANEL_VISIONOX_R66451) += panel-visionox-r66451.o obj-$(CONFIG_DRM_PANEL_WIDECHIPS_WS2401) += panel-widechips-ws2401.o obj-$(CONFIG_DRM_PANEL_XINPENG_XPP055C272) += panel-xinpeng-xpp055c272.o diff --git a/drivers/gpu/drm/panel/panel-abt-y030xx067a.c b/drivers/gpu/drm/panel/panel-abt-y030xx067a.c index 1cc0f1d09684..662c7bcbe6e5 100644 --- a/drivers/gpu/drm/panel/panel-abt-y030xx067a.c +++ b/drivers/gpu/drm/panel/panel-abt-y030xx067a.c @@ -11,7 +11,8 @@ #include <linux/gpio/consumer.h> #include <linux/media-bus-format.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> +#include <linux/platform_device.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <linux/spi/spi.h> diff --git a/drivers/gpu/drm/panel/panel-auo-a030jtn01.c b/drivers/gpu/drm/panel/panel-auo-a030jtn01.c index 3c976a98de6a..6c86ebf2cad7 100644 --- a/drivers/gpu/drm/panel/panel-auo-a030jtn01.c +++ b/drivers/gpu/drm/panel/panel-auo-a030jtn01.c @@ -11,8 +11,8 @@ #include <linux/device.h> #include <linux/gpio/consumer.h> #include <linux/media-bus-format.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/of_device.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <linux/spi/spi.h> diff --git a/drivers/gpu/drm/panel/panel-boe-himax8279d.c b/drivers/gpu/drm/panel/panel-boe-himax8279d.c index d879b3b14c48..11b64acbe8a9 100644 --- a/drivers/gpu/drm/panel/panel-boe-himax8279d.c +++ b/drivers/gpu/drm/panel/panel-boe-himax8279d.c @@ -10,7 +10,6 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/gpio/consumer.h> #include <linux/regulator/consumer.h> diff --git a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c index 783234ae0f57..c9087f474cbc 100644 --- a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c +++ b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c @@ -8,7 +8,6 @@ #include <linux/gpio/consumer.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/regulator/consumer.h> #include <drm/drm_connector.h> @@ -36,6 +35,7 @@ struct panel_desc { const struct panel_init_cmd *init_cmds; unsigned int lanes; bool discharge_on_disable; + bool lp11_before_reset; }; struct boe_panel { @@ -451,11 +451,14 @@ static const struct panel_init_cmd inx_hj110iz_init_cmd[] = { _INIT_DCS_CMD(0xFF, 0x20), _INIT_DCS_CMD(0xFB, 0x01), _INIT_DCS_CMD(0x05, 0xD1), - _INIT_DCS_CMD(0x0D, 0x63), - _INIT_DCS_CMD(0x07, 0x8C), + _INIT_DCS_CMD(0x06, 0xC0), + _INIT_DCS_CMD(0x07, 0x87), _INIT_DCS_CMD(0x08, 0x4B), + + _INIT_DCS_CMD(0x0D, 0x63), _INIT_DCS_CMD(0x0E, 0x91), _INIT_DCS_CMD(0x0F, 0x69), + _INIT_DCS_CMD(0x94, 0x00), _INIT_DCS_CMD(0x95, 0xF5), _INIT_DCS_CMD(0x96, 0xF5), _INIT_DCS_CMD(0x9D, 0x00), @@ -463,98 +466,96 @@ static const struct panel_init_cmd inx_hj110iz_init_cmd[] = { _INIT_DCS_CMD(0x69, 0x98), _INIT_DCS_CMD(0x75, 0xA2), _INIT_DCS_CMD(0x77, 0xB3), + + _INIT_DCS_CMD(0x58, 0x43), _INIT_DCS_CMD(0xFF, 0x24), _INIT_DCS_CMD(0xFB, 0x01), _INIT_DCS_CMD(0x91, 0x44), - _INIT_DCS_CMD(0x92, 0x7A), - _INIT_DCS_CMD(0x93, 0x1A), - _INIT_DCS_CMD(0x94, 0x40), - _INIT_DCS_CMD(0x9A, 0x08), + _INIT_DCS_CMD(0x92, 0x4C), + _INIT_DCS_CMD(0x94, 0x86), _INIT_DCS_CMD(0x60, 0x96), _INIT_DCS_CMD(0x61, 0xD0), _INIT_DCS_CMD(0x63, 0x70), - _INIT_DCS_CMD(0xC2, 0xCF), - _INIT_DCS_CMD(0x9B, 0x0F), - _INIT_DCS_CMD(0x9A, 0x08), + _INIT_DCS_CMD(0xC2, 0xCA), + _INIT_DCS_CMD(0x00, 0x03), _INIT_DCS_CMD(0x01, 0x03), _INIT_DCS_CMD(0x02, 0x03), - _INIT_DCS_CMD(0x03, 0x03), - _INIT_DCS_CMD(0x04, 0x03), - _INIT_DCS_CMD(0x05, 0x03), - _INIT_DCS_CMD(0x06, 0x22), - _INIT_DCS_CMD(0x07, 0x06), - _INIT_DCS_CMD(0x08, 0x00), - _INIT_DCS_CMD(0x09, 0x1D), - _INIT_DCS_CMD(0x0A, 0x1C), - _INIT_DCS_CMD(0x0B, 0x13), - _INIT_DCS_CMD(0x0C, 0x12), - _INIT_DCS_CMD(0x0D, 0x11), - _INIT_DCS_CMD(0x0E, 0x10), - _INIT_DCS_CMD(0x0F, 0x0F), - _INIT_DCS_CMD(0x10, 0x0E), - _INIT_DCS_CMD(0x11, 0x0D), - _INIT_DCS_CMD(0x12, 0x0C), + _INIT_DCS_CMD(0x03, 0x29), + _INIT_DCS_CMD(0x04, 0x22), + _INIT_DCS_CMD(0x05, 0x22), + _INIT_DCS_CMD(0x06, 0x0B), + _INIT_DCS_CMD(0x07, 0x1D), + _INIT_DCS_CMD(0x08, 0x1C), + _INIT_DCS_CMD(0x09, 0x05), + _INIT_DCS_CMD(0x0A, 0x08), + _INIT_DCS_CMD(0x0B, 0x09), + _INIT_DCS_CMD(0x0C, 0x0A), + _INIT_DCS_CMD(0x0D, 0x0C), + _INIT_DCS_CMD(0x0E, 0x0D), + _INIT_DCS_CMD(0x0F, 0x0E), + _INIT_DCS_CMD(0x10, 0x0F), + _INIT_DCS_CMD(0x11, 0x10), + _INIT_DCS_CMD(0x12, 0x11), _INIT_DCS_CMD(0x13, 0x04), - _INIT_DCS_CMD(0x14, 0x03), + _INIT_DCS_CMD(0x14, 0x00), _INIT_DCS_CMD(0x15, 0x03), _INIT_DCS_CMD(0x16, 0x03), _INIT_DCS_CMD(0x17, 0x03), _INIT_DCS_CMD(0x18, 0x03), - _INIT_DCS_CMD(0x19, 0x03), - _INIT_DCS_CMD(0x1A, 0x03), - _INIT_DCS_CMD(0x1B, 0x03), - _INIT_DCS_CMD(0x1C, 0x22), - _INIT_DCS_CMD(0x1D, 0x06), - _INIT_DCS_CMD(0x1E, 0x00), - _INIT_DCS_CMD(0x1F, 0x1D), - _INIT_DCS_CMD(0x20, 0x1C), - _INIT_DCS_CMD(0x21, 0x13), - _INIT_DCS_CMD(0x22, 0x12), - _INIT_DCS_CMD(0x23, 0x11), - _INIT_DCS_CMD(0x24, 0x10), - _INIT_DCS_CMD(0x25, 0x0F), - _INIT_DCS_CMD(0x26, 0x0E), - _INIT_DCS_CMD(0x27, 0x0D), - _INIT_DCS_CMD(0x28, 0x0C), + _INIT_DCS_CMD(0x19, 0x29), + _INIT_DCS_CMD(0x1A, 0x22), + _INIT_DCS_CMD(0x1B, 0x22), + _INIT_DCS_CMD(0x1C, 0x0B), + _INIT_DCS_CMD(0x1D, 0x1D), + _INIT_DCS_CMD(0x1E, 0x1C), + _INIT_DCS_CMD(0x1F, 0x05), + _INIT_DCS_CMD(0x20, 0x08), + _INIT_DCS_CMD(0x21, 0x09), + _INIT_DCS_CMD(0x22, 0x0A), + _INIT_DCS_CMD(0x23, 0x0C), + _INIT_DCS_CMD(0x24, 0x0D), + _INIT_DCS_CMD(0x25, 0x0E), + _INIT_DCS_CMD(0x26, 0x0F), + _INIT_DCS_CMD(0x27, 0x10), + _INIT_DCS_CMD(0x28, 0x11), _INIT_DCS_CMD(0x29, 0x04), - _INIT_DCS_CMD(0x2A, 0x03), + _INIT_DCS_CMD(0x2A, 0x00), _INIT_DCS_CMD(0x2B, 0x03), - _INIT_DCS_CMD(0x2F, 0x05), - _INIT_DCS_CMD(0x30, 0x32), - _INIT_DCS_CMD(0x31, 0x43), - _INIT_DCS_CMD(0x33, 0x05), - _INIT_DCS_CMD(0x34, 0x32), - _INIT_DCS_CMD(0x35, 0x43), - _INIT_DCS_CMD(0x37, 0x44), - _INIT_DCS_CMD(0x38, 0x40), + _INIT_DCS_CMD(0x2F, 0x0A), + _INIT_DCS_CMD(0x30, 0x35), + _INIT_DCS_CMD(0x37, 0xA7), _INIT_DCS_CMD(0x39, 0x00), - _INIT_DCS_CMD(0x3A, 0x18), - _INIT_DCS_CMD(0x3B, 0x00), - _INIT_DCS_CMD(0x3D, 0x93), - _INIT_DCS_CMD(0xAB, 0x44), - _INIT_DCS_CMD(0xAC, 0x40), + _INIT_DCS_CMD(0x3A, 0x46), + _INIT_DCS_CMD(0x3B, 0x32), + _INIT_DCS_CMD(0x3D, 0x12), + + _INIT_DCS_CMD(0x3F, 0x33), + _INIT_DCS_CMD(0x40, 0x31), + _INIT_DCS_CMD(0x41, 0x40), + _INIT_DCS_CMD(0x42, 0x42), + _INIT_DCS_CMD(0x47, 0x77), + _INIT_DCS_CMD(0x48, 0x77), + _INIT_DCS_CMD(0x4A, 0x45), + _INIT_DCS_CMD(0x4B, 0x45), + _INIT_DCS_CMD(0x4C, 0x14), _INIT_DCS_CMD(0x4D, 0x21), _INIT_DCS_CMD(0x4E, 0x43), _INIT_DCS_CMD(0x4F, 0x65), - _INIT_DCS_CMD(0x50, 0x87), - _INIT_DCS_CMD(0x51, 0x78), - _INIT_DCS_CMD(0x52, 0x56), - _INIT_DCS_CMD(0x53, 0x34), - _INIT_DCS_CMD(0x54, 0x21), - _INIT_DCS_CMD(0x55, 0x83), - _INIT_DCS_CMD(0x56, 0x08), + _INIT_DCS_CMD(0x55, 0x06), + _INIT_DCS_CMD(0x56, 0x06), _INIT_DCS_CMD(0x58, 0x21), - _INIT_DCS_CMD(0x59, 0x40), - _INIT_DCS_CMD(0x5A, 0x00), - _INIT_DCS_CMD(0x5B, 0x2C), - _INIT_DCS_CMD(0x5E, 0x00, 0x10), + _INIT_DCS_CMD(0x59, 0x70), + _INIT_DCS_CMD(0x5A, 0x46), + _INIT_DCS_CMD(0x5B, 0x32), + _INIT_DCS_CMD(0x5C, 0x88), + _INIT_DCS_CMD(0x5E, 0x00, 0x00), _INIT_DCS_CMD(0x5F, 0x00), - _INIT_DCS_CMD(0x7A, 0x00), - _INIT_DCS_CMD(0x7B, 0x00), + _INIT_DCS_CMD(0x7A, 0xFF), + _INIT_DCS_CMD(0x7B, 0xFF), _INIT_DCS_CMD(0x7C, 0x00), _INIT_DCS_CMD(0x7D, 0x00), _INIT_DCS_CMD(0x7E, 0x20), @@ -564,152 +565,183 @@ static const struct panel_init_cmd inx_hj110iz_init_cmd[] = { _INIT_DCS_CMD(0x82, 0x08), _INIT_DCS_CMD(0x97, 0x02), _INIT_DCS_CMD(0xC5, 0x10), + + _INIT_DCS_CMD(0xD7, 0x55), + _INIT_DCS_CMD(0xD8, 0x55), + _INIT_DCS_CMD(0xD9, 0x23), _INIT_DCS_CMD(0xDA, 0x05), _INIT_DCS_CMD(0xDB, 0x01), - _INIT_DCS_CMD(0xDC, 0x7A), + _INIT_DCS_CMD(0xDC, 0x65), _INIT_DCS_CMD(0xDD, 0x55), _INIT_DCS_CMD(0xDE, 0x27), _INIT_DCS_CMD(0xDF, 0x01), - _INIT_DCS_CMD(0xE0, 0x7A), + _INIT_DCS_CMD(0xE0, 0x65), _INIT_DCS_CMD(0xE1, 0x01), - _INIT_DCS_CMD(0xE2, 0x7A), + _INIT_DCS_CMD(0xE2, 0x65), _INIT_DCS_CMD(0xE3, 0x01), - _INIT_DCS_CMD(0xE4, 0x7A), + _INIT_DCS_CMD(0xE4, 0x65), _INIT_DCS_CMD(0xE5, 0x01), - _INIT_DCS_CMD(0xE6, 0x7A), + _INIT_DCS_CMD(0xE6, 0x65), _INIT_DCS_CMD(0xE7, 0x00), _INIT_DCS_CMD(0xE8, 0x00), _INIT_DCS_CMD(0xE9, 0x01), - _INIT_DCS_CMD(0xEA, 0x7A), + _INIT_DCS_CMD(0xEA, 0x65), _INIT_DCS_CMD(0xEB, 0x01), - _INIT_DCS_CMD(0xEE, 0x7A), + _INIT_DCS_CMD(0xEE, 0x65), _INIT_DCS_CMD(0xEF, 0x01), - _INIT_DCS_CMD(0xF0, 0x7A), - + _INIT_DCS_CMD(0xF0, 0x65), _INIT_DCS_CMD(0xB6, 0x05, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x05, 0x00, 0x00), + _INIT_DCS_CMD(0xFF, 0x25), - _INIT_DCS_CMD(0xFB, 0x01), + _INIT_DCS_CMD(0xFB, 0x01), _INIT_DCS_CMD(0x05, 0x00), - - _INIT_DCS_CMD(0x13, 0x02), - _INIT_DCS_CMD(0x14, 0xDF), _INIT_DCS_CMD(0xF1, 0x10), + _INIT_DCS_CMD(0x1E, 0x00), - _INIT_DCS_CMD(0x1F, 0x00), - _INIT_DCS_CMD(0x20, 0x2C), + _INIT_DCS_CMD(0x1F, 0x46), + _INIT_DCS_CMD(0x20, 0x32), + _INIT_DCS_CMD(0x25, 0x00), - _INIT_DCS_CMD(0x26, 0x00), - _INIT_DCS_CMD(0x27, 0x2C), + _INIT_DCS_CMD(0x26, 0x46), + _INIT_DCS_CMD(0x27, 0x32), + _INIT_DCS_CMD(0x3F, 0x80), _INIT_DCS_CMD(0x40, 0x00), _INIT_DCS_CMD(0x43, 0x00), - _INIT_DCS_CMD(0x44, 0x18), - _INIT_DCS_CMD(0x45, 0x00), + _INIT_DCS_CMD(0x44, 0x46), + _INIT_DCS_CMD(0x45, 0x46), + + _INIT_DCS_CMD(0x48, 0x46), + _INIT_DCS_CMD(0x49, 0x32), - _INIT_DCS_CMD(0x48, 0x00), - _INIT_DCS_CMD(0x49, 0x2C), _INIT_DCS_CMD(0x5B, 0x80), + _INIT_DCS_CMD(0x5C, 0x00), - _INIT_DCS_CMD(0x5D, 0x00), - _INIT_DCS_CMD(0x5E, 0x00), - _INIT_DCS_CMD(0x61, 0x00), - _INIT_DCS_CMD(0x62, 0x2C), - _INIT_DCS_CMD(0x68, 0x10), + _INIT_DCS_CMD(0x5D, 0x46), + _INIT_DCS_CMD(0x5E, 0x32), + + _INIT_DCS_CMD(0x5F, 0x46), + _INIT_DCS_CMD(0x60, 0x32), + + _INIT_DCS_CMD(0x61, 0x46), + _INIT_DCS_CMD(0x62, 0x32), + _INIT_DCS_CMD(0x68, 0x0C), + + _INIT_DCS_CMD(0x6C, 0x0D), + _INIT_DCS_CMD(0x6E, 0x0D), + _INIT_DCS_CMD(0x78, 0x00), + _INIT_DCS_CMD(0x79, 0xC5), + _INIT_DCS_CMD(0x7A, 0x0C), + _INIT_DCS_CMD(0x7B, 0xB0), + _INIT_DCS_CMD(0xFF, 0x26), _INIT_DCS_CMD(0xFB, 0x01), _INIT_DCS_CMD(0x00, 0xA1), _INIT_DCS_CMD(0x02, 0x31), - _INIT_DCS_CMD(0x0A, 0xF2), - _INIT_DCS_CMD(0x04, 0x28), + _INIT_DCS_CMD(0x0A, 0xF4), + _INIT_DCS_CMD(0x04, 0x50), _INIT_DCS_CMD(0x06, 0x30), _INIT_DCS_CMD(0x0C, 0x16), _INIT_DCS_CMD(0x0D, 0x0D), _INIT_DCS_CMD(0x0F, 0x00), _INIT_DCS_CMD(0x11, 0x00), _INIT_DCS_CMD(0x12, 0x50), - _INIT_DCS_CMD(0x13, 0x56), - _INIT_DCS_CMD(0x14, 0x57), + _INIT_DCS_CMD(0x13, 0x40), + _INIT_DCS_CMD(0x14, 0x58), _INIT_DCS_CMD(0x15, 0x00), _INIT_DCS_CMD(0x16, 0x10), _INIT_DCS_CMD(0x17, 0xA0), _INIT_DCS_CMD(0x18, 0x86), _INIT_DCS_CMD(0x22, 0x00), _INIT_DCS_CMD(0x23, 0x00), - _INIT_DCS_CMD(0x19, 0x0D), - _INIT_DCS_CMD(0x1A, 0x7F), - _INIT_DCS_CMD(0x1B, 0x0C), - _INIT_DCS_CMD(0x1C, 0xBF), - _INIT_DCS_CMD(0x2A, 0x0D), - _INIT_DCS_CMD(0x2B, 0x7F), - _INIT_DCS_CMD(0x20, 0x00), + + _INIT_DCS_CMD(0x19, 0x0E), + _INIT_DCS_CMD(0x1A, 0x31), + _INIT_DCS_CMD(0x1B, 0x0D), + _INIT_DCS_CMD(0x1C, 0x29), + _INIT_DCS_CMD(0x2A, 0x0E), + _INIT_DCS_CMD(0x2B, 0x31), _INIT_DCS_CMD(0x1D, 0x00), - _INIT_DCS_CMD(0x1E, 0x78), - _INIT_DCS_CMD(0x1F, 0x78), + _INIT_DCS_CMD(0x1E, 0x62), + _INIT_DCS_CMD(0x1F, 0x62), - _INIT_DCS_CMD(0x2F, 0x03), - _INIT_DCS_CMD(0x30, 0x78), - _INIT_DCS_CMD(0x33, 0x78), - _INIT_DCS_CMD(0x34, 0x66), - _INIT_DCS_CMD(0x35, 0x11), + _INIT_DCS_CMD(0x2F, 0x06), + _INIT_DCS_CMD(0x30, 0x62), + _INIT_DCS_CMD(0x31, 0x06), + _INIT_DCS_CMD(0x32, 0x7F), + _INIT_DCS_CMD(0x33, 0x11), + _INIT_DCS_CMD(0x34, 0x89), + _INIT_DCS_CMD(0x35, 0x67), - _INIT_DCS_CMD(0x39, 0x10), - _INIT_DCS_CMD(0x3A, 0x78), + _INIT_DCS_CMD(0x39, 0x0B), + _INIT_DCS_CMD(0x3A, 0x62), _INIT_DCS_CMD(0x3B, 0x06), _INIT_DCS_CMD(0xC8, 0x04), - _INIT_DCS_CMD(0xC9, 0x84), + _INIT_DCS_CMD(0xC9, 0x89), _INIT_DCS_CMD(0xCA, 0x4E), _INIT_DCS_CMD(0xCB, 0x00), + _INIT_DCS_CMD(0xA9, 0x3F), + _INIT_DCS_CMD(0xAA, 0x3E), + _INIT_DCS_CMD(0xAB, 0x3D), + _INIT_DCS_CMD(0xAC, 0x3C), + _INIT_DCS_CMD(0xAD, 0x3B), + _INIT_DCS_CMD(0xAE, 0x3A), + _INIT_DCS_CMD(0xAF, 0x39), + _INIT_DCS_CMD(0xB0, 0x38), - _INIT_DCS_CMD(0xA9, 0x50), - _INIT_DCS_CMD(0xAA, 0x4F), - _INIT_DCS_CMD(0xAB, 0x4D), - _INIT_DCS_CMD(0xAC, 0x4A), - _INIT_DCS_CMD(0xAD, 0x48), - _INIT_DCS_CMD(0xAE, 0x46), _INIT_DCS_CMD(0xFF, 0x27), _INIT_DCS_CMD(0xFB, 0x01), + + _INIT_DCS_CMD(0xD0, 0x11), + _INIT_DCS_CMD(0xD1, 0x54), + _INIT_DCS_CMD(0xDE, 0x43), + _INIT_DCS_CMD(0xDF, 0x02), + _INIT_DCS_CMD(0xC0, 0x18), _INIT_DCS_CMD(0xC1, 0x00), _INIT_DCS_CMD(0xC2, 0x00), + _INIT_DCS_CMD(0x00, 0x00), + _INIT_DCS_CMD(0xC3, 0x00), _INIT_DCS_CMD(0x56, 0x06), + _INIT_DCS_CMD(0x58, 0x80), - _INIT_DCS_CMD(0x59, 0x75), + _INIT_DCS_CMD(0x59, 0x78), _INIT_DCS_CMD(0x5A, 0x00), - _INIT_DCS_CMD(0x5B, 0x02), + _INIT_DCS_CMD(0x5B, 0x18), _INIT_DCS_CMD(0x5C, 0x00), - _INIT_DCS_CMD(0x5D, 0x00), + _INIT_DCS_CMD(0x5D, 0x01), _INIT_DCS_CMD(0x5E, 0x20), _INIT_DCS_CMD(0x5F, 0x10), _INIT_DCS_CMD(0x60, 0x00), - _INIT_DCS_CMD(0x61, 0x2E), + _INIT_DCS_CMD(0x61, 0x1C), _INIT_DCS_CMD(0x62, 0x00), _INIT_DCS_CMD(0x63, 0x01), - _INIT_DCS_CMD(0x64, 0x43), - _INIT_DCS_CMD(0x65, 0x2D), + _INIT_DCS_CMD(0x64, 0x44), + _INIT_DCS_CMD(0x65, 0x1B), _INIT_DCS_CMD(0x66, 0x00), _INIT_DCS_CMD(0x67, 0x01), - _INIT_DCS_CMD(0x68, 0x43), + _INIT_DCS_CMD(0x68, 0x44), + _INIT_DCS_CMD(0x98, 0x01), _INIT_DCS_CMD(0xB4, 0x03), - _INIT_DCS_CMD(0x9B, 0xBD), - _INIT_DCS_CMD(0xA0, 0x90), - _INIT_DCS_CMD(0xAB, 0x1B), - _INIT_DCS_CMD(0xBC, 0x0C), + _INIT_DCS_CMD(0x9B, 0xBE), + + _INIT_DCS_CMD(0xAB, 0x14), + _INIT_DCS_CMD(0xBC, 0x08), _INIT_DCS_CMD(0xBD, 0x28), _INIT_DCS_CMD(0xFF, 0x2A), _INIT_DCS_CMD(0xFB, 0x01), - _INIT_DCS_CMD(0x22, 0x2F), _INIT_DCS_CMD(0x23, 0x08), _INIT_DCS_CMD(0x24, 0x00), - _INIT_DCS_CMD(0x25, 0x65), + _INIT_DCS_CMD(0x25, 0x62), _INIT_DCS_CMD(0x26, 0xF8), _INIT_DCS_CMD(0x27, 0x00), _INIT_DCS_CMD(0x28, 0x1A), @@ -719,18 +751,29 @@ static const struct panel_init_cmd inx_hj110iz_init_cmd[] = { _INIT_DCS_CMD(0x2D, 0x1A), _INIT_DCS_CMD(0x64, 0x96), - _INIT_DCS_CMD(0x65, 0x00), + _INIT_DCS_CMD(0x65, 0x10), _INIT_DCS_CMD(0x66, 0x00), + _INIT_DCS_CMD(0x67, 0x96), + _INIT_DCS_CMD(0x68, 0x10), + _INIT_DCS_CMD(0x69, 0x00), _INIT_DCS_CMD(0x6A, 0x96), - _INIT_DCS_CMD(0x6B, 0x00), + _INIT_DCS_CMD(0x6B, 0x10), _INIT_DCS_CMD(0x6C, 0x00), _INIT_DCS_CMD(0x70, 0x92), - _INIT_DCS_CMD(0x71, 0x00), + _INIT_DCS_CMD(0x71, 0x10), _INIT_DCS_CMD(0x72, 0x00), - _INIT_DCS_CMD(0xA2, 0x33), + _INIT_DCS_CMD(0x79, 0x96), + _INIT_DCS_CMD(0x7A, 0x10), + _INIT_DCS_CMD(0x88, 0x96), + _INIT_DCS_CMD(0x89, 0x10), + + _INIT_DCS_CMD(0xA2, 0x3F), _INIT_DCS_CMD(0xA3, 0x30), _INIT_DCS_CMD(0xA4, 0xC0), + _INIT_DCS_CMD(0xA5, 0x03), + _INIT_DCS_CMD(0xE8, 0x00), + _INIT_DCS_CMD(0x97, 0x3C), _INIT_DCS_CMD(0x98, 0x02), _INIT_DCS_CMD(0x99, 0x95), @@ -739,38 +782,68 @@ static const struct panel_init_cmd inx_hj110iz_init_cmd[] = { _INIT_DCS_CMD(0x9C, 0x0B), _INIT_DCS_CMD(0x9D, 0x0A), _INIT_DCS_CMD(0x9E, 0x90), + + _INIT_DCS_CMD(0xFF, 0x25), + _INIT_DCS_CMD(0x13, 0x02), + _INIT_DCS_CMD(0x14, 0xD7), + _INIT_DCS_CMD(0xDB, 0x02), + _INIT_DCS_CMD(0xDC, 0xD7), + _INIT_DCS_CMD(0x17, 0xCF), + _INIT_DCS_CMD(0x19, 0x0F), + _INIT_DCS_CMD(0x1B, 0x5B), + + _INIT_DCS_CMD(0xFF, 0x20), + + _INIT_DCS_CMD(0xB0, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x24, 0x00, 0x38, 0x00, 0x4C, 0x00, 0x5E, 0x00, 0x6F, 0x00, 0x7E), + _INIT_DCS_CMD(0xB1, 0x00, 0x8C, 0x00, 0xBE, 0x00, 0xE5, 0x01, 0x27, 0x01, 0x58, 0x01, 0xA8, 0x01, 0xE8, 0x01, 0xEA), + _INIT_DCS_CMD(0xB2, 0x02, 0x28, 0x02, 0x71, 0x02, 0x9E, 0x02, 0xDA, 0x03, 0x00, 0x03, 0x31, 0x03, 0x40, 0x03, 0x51), + _INIT_DCS_CMD(0xB3, 0x03, 0x62, 0x03, 0x75, 0x03, 0x89, 0x03, 0x9C, 0x03, 0xAA, 0x03, 0xB2), + + _INIT_DCS_CMD(0xB4, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x27, 0x00, 0x3D, 0x00, 0x52, 0x00, 0x64, 0x00, 0x75, 0x00, 0x84), + _INIT_DCS_CMD(0xB5, 0x00, 0x93, 0x00, 0xC5, 0x00, 0xEC, 0x01, 0x2C, 0x01, 0x5D, 0x01, 0xAC, 0x01, 0xEC, 0x01, 0xEE), + _INIT_DCS_CMD(0xB6, 0x02, 0x2B, 0x02, 0x73, 0x02, 0xA0, 0x02, 0xDB, 0x03, 0x01, 0x03, 0x31, 0x03, 0x41, 0x03, 0x51), + _INIT_DCS_CMD(0xB7, 0x03, 0x63, 0x03, 0x75, 0x03, 0x89, 0x03, 0x9C, 0x03, 0xAA, 0x03, 0xB2), + + _INIT_DCS_CMD(0xB8, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x2A, 0x00, 0x40, 0x00, 0x56, 0x00, 0x68, 0x00, 0x7A, 0x00, 0x89), + _INIT_DCS_CMD(0xB9, 0x00, 0x98, 0x00, 0xC9, 0x00, 0xF1, 0x01, 0x30, 0x01, 0x61, 0x01, 0xB0, 0x01, 0xEF, 0x01, 0xF1), + _INIT_DCS_CMD(0xBA, 0x02, 0x2E, 0x02, 0x76, 0x02, 0xA3, 0x02, 0xDD, 0x03, 0x02, 0x03, 0x32, 0x03, 0x42, 0x03, 0x53), + _INIT_DCS_CMD(0xBB, 0x03, 0x66, 0x03, 0x75, 0x03, 0x89, 0x03, 0x9C, 0x03, 0xAA, 0x03, 0xB2), + + _INIT_DCS_CMD(0xFF, 0x21), + _INIT_DCS_CMD(0xB0, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x24, 0x00, 0x38, 0x00, 0x4C, 0x00, 0x5E, 0x00, 0x6F, 0x00, 0x7E), + _INIT_DCS_CMD(0xB1, 0x00, 0x8C, 0x00, 0xBE, 0x00, 0xE5, 0x01, 0x27, 0x01, 0x58, 0x01, 0xA8, 0x01, 0xE8, 0x01, 0xEA), + _INIT_DCS_CMD(0xB2, 0x02, 0x28, 0x02, 0x71, 0x02, 0x9E, 0x02, 0xDA, 0x03, 0x00, 0x03, 0x31, 0x03, 0x40, 0x03, 0x51), + _INIT_DCS_CMD(0xB3, 0x03, 0x62, 0x03, 0x77, 0x03, 0x90, 0x03, 0xAC, 0x03, 0xCA, 0x03, 0xDA), + + _INIT_DCS_CMD(0xB4, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x27, 0x00, 0x3D, 0x00, 0x52, 0x00, 0x64, 0x00, 0x75, 0x00, 0x84), + _INIT_DCS_CMD(0xB5, 0x00, 0x93, 0x00, 0xC5, 0x00, 0xEC, 0x01, 0x2C, 0x01, 0x5D, 0x01, 0xAC, 0x01, 0xEC, 0x01, 0xEE), + _INIT_DCS_CMD(0xB6, 0x02, 0x2B, 0x02, 0x73, 0x02, 0xA0, 0x02, 0xDB, 0x03, 0x01, 0x03, 0x31, 0x03, 0x41, 0x03, 0x51), + _INIT_DCS_CMD(0xB7, 0x03, 0x63, 0x03, 0x77, 0x03, 0x90, 0x03, 0xAC, 0x03, 0xCA, 0x03, 0xDA), + + _INIT_DCS_CMD(0xB8, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x2A, 0x00, 0x40, 0x00, 0x56, 0x00, 0x68, 0x00, 0x7A, 0x00, 0x89), + _INIT_DCS_CMD(0xB9, 0x00, 0x98, 0x00, 0xC9, 0x00, 0xF1, 0x01, 0x30, 0x01, 0x61, 0x01, 0xB0, 0x01, 0xEF, 0x01, 0xF1), + _INIT_DCS_CMD(0xBA, 0x02, 0x2E, 0x02, 0x76, 0x02, 0xA3, 0x02, 0xDD, 0x03, 0x02, 0x03, 0x32, 0x03, 0x42, 0x03, 0x53), + _INIT_DCS_CMD(0xBB, 0x03, 0x66, 0x03, 0x77, 0x03, 0x90, 0x03, 0xAC, 0x03, 0xCA, 0x03, 0xDA), + _INIT_DCS_CMD(0xFF, 0xF0), _INIT_DCS_CMD(0xFB, 0x01), _INIT_DCS_CMD(0x3A, 0x08), - _INIT_DCS_CMD(0xFF, 0xD0), - _INIT_DCS_CMD(0xFB, 0x01), - _INIT_DCS_CMD(0x00, 0x33), - _INIT_DCS_CMD(0x08, 0x01), - _INIT_DCS_CMD(0x09, 0xBF), - _INIT_DCS_CMD(0x2F, 0x33), - _INIT_DCS_CMD(0xFF, 0x23), - _INIT_DCS_CMD(0xFB, 0x01), - _INIT_DCS_CMD(0x00, 0x80), - _INIT_DCS_CMD(0x07, 0x00), - _INIT_DCS_CMD(0xFF, 0x20), - _INIT_DCS_CMD(0xFB, 0x01), - _INIT_DCS_CMD(0x30, 0x00), - _INIT_DCS_CMD(0xFF, 0x24), - _INIT_DCS_CMD(0x5C, 0x88), - _INIT_DCS_CMD(0x5D, 0x08), + _INIT_DCS_CMD(0xFF, 0x10), _INIT_DCS_CMD(0xB9, 0x01), + _INIT_DCS_CMD(0xFF, 0x20), + _INIT_DCS_CMD(0x18, 0x40), _INIT_DCS_CMD(0xFF, 0x10), + _INIT_DCS_CMD(0xB9, 0x02), _INIT_DCS_CMD(0xFF, 0x10), + _INIT_DCS_CMD(0xFB, 0x01), - _INIT_DCS_CMD(0xBB, 0x13), - _INIT_DCS_CMD(0x3B, 0x03, 0x96, 0x1A, 0x04, 0x04), + _INIT_DCS_CMD(0xB0, 0x01), _INIT_DCS_CMD(0x35, 0x00), - _INIT_DCS_CMD(0x51, 0x0F, 0xFF), - _INIT_DCS_CMD(0x53, 0x24), + _INIT_DCS_CMD(0x3B, 0x03, 0xAE, 0x1A, 0x04, 0x04), _INIT_DELAY_CMD(100), _INIT_DCS_CMD(0x11), _INIT_DELAY_CMD(200), @@ -780,7 +853,6 @@ static const struct panel_init_cmd inx_hj110iz_init_cmd[] = { }; static const struct panel_init_cmd boe_init_cmd[] = { - _INIT_DELAY_CMD(24), _INIT_DCS_CMD(0xB0, 0x05), _INIT_DCS_CMD(0xB1, 0xE5), _INIT_DCS_CMD(0xB3, 0x52), @@ -1228,6 +1300,414 @@ static const struct panel_init_cmd starry_qfh032011_53g_init_cmd[] = { {}, }; +static const struct panel_init_cmd starry_himax83102_j02_init_cmd[] = { + _INIT_DCS_CMD(0xB9, 0x83, 0x10, 0x21, 0x55, 0x00), + _INIT_DCS_CMD(0xB1, 0x2C, 0xB5, 0xB5, 0x31, 0xF1, 0x31, 0xD7, 0x2F, 0x36, 0x36, 0x36, 0x36, 0x1A, 0x8B, 0x11, + 0x65, 0x00, 0x88, 0xFA, 0xFF, 0xFF, 0x8F, 0xFF, 0x08, 0x74, 0x33), + _INIT_DCS_CMD(0xB2, 0x00, 0x47, 0xB0, 0x80, 0x00, 0x12, 0x72, 0x3C, 0xA3, 0x03, 0x03, 0x00, 0x00, 0x88, 0xF5), + _INIT_DCS_CMD(0xB4, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x63, 0x5C, 0x63, 0x5C, 0x01, 0x9E), + _INIT_DCS_CMD(0xE9, 0xCD), + _INIT_DCS_CMD(0xBA, 0x84), + _INIT_DCS_CMD(0xE9, 0x3F), + _INIT_DCS_CMD(0xBC, 0x1B, 0x04), + _INIT_DCS_CMD(0xBE, 0x20), + _INIT_DCS_CMD(0xBF, 0xFC, 0xC4), + _INIT_DCS_CMD(0xC0, 0x36, 0x36, 0x22, 0x11, 0x22, 0xA0, 0x61, 0x08, 0xF5, 0x03), + _INIT_DCS_CMD(0xE9, 0xCC), + _INIT_DCS_CMD(0xC7, 0x80), + _INIT_DCS_CMD(0xE9, 0x3F), + _INIT_DCS_CMD(0xE9, 0xC6), + _INIT_DCS_CMD(0xC8, 0x97), + _INIT_DCS_CMD(0xE9, 0x3F), + _INIT_DCS_CMD(0xC9, 0x00, 0x1E, 0x13, 0x88, 0x01), + _INIT_DCS_CMD(0xCB, 0x08, 0x13, 0x07, 0x00, 0x0F, 0x33), + _INIT_DCS_CMD(0xCC, 0x02), + _INIT_DCS_CMD(0xE9, 0xC4), + _INIT_DCS_CMD(0xD0, 0x03), + _INIT_DCS_CMD(0xE9, 0x3F), + _INIT_DCS_CMD(0xD1, 0x37, 0x06, 0x00, 0x02, 0x04, 0x0C, 0xFF), + _INIT_DCS_CMD(0xD2, 0x1F, 0x11, 0x1F), + _INIT_DCS_CMD(0xD3, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x37, 0x47, 0x34, 0x3B, 0x12, 0x12, 0x03, + 0x03, 0x32, 0x10, 0x10, 0x00, 0x10, 0x32, 0x10, 0x08, 0x00, 0x08, 0x32, 0x17, 0x94, 0x07, 0x94, 0x00, 0x00), + _INIT_DCS_CMD(0xD5, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x19, 0x19, 0x40, 0x40, 0x1A, 0x1A, + 0x1B, 0x1B, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x20, 0x21, 0x28, 0x29, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18), + _INIT_DCS_CMD(0xD6, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x40, 0x40, 0x19, 0x19, 0x1A, 0x1A, + 0x1B, 0x1B, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x29, 0x28, 0x21, 0x20, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18), + _INIT_DCS_CMD(0xD8, 0xAA, 0xBA, 0xEA, 0xAA, 0xAA, 0xA0, 0xAA, 0xBA, 0xEA, 0xAA, 0xAA, 0xA0, 0xAA, 0xBA, 0xEA, 0xAA, + 0xAA, 0xA0, 0xAA, 0xBA, 0xEA, 0xAA, 0xAA, 0xA0, 0xAA, 0xBA, 0xEA, 0xAA, 0xAA, 0xA0, 0xAA, 0xBA, 0xEA, 0xAA, 0xAA, 0xA0), + _INIT_DCS_CMD(0xE0, 0x00, 0x09, 0x14, 0x1E, 0x26, 0x48, 0x61, 0x67, 0x6C, 0x67, 0x7D, 0x7F, 0x80, 0x8B, 0x87, 0x8F, 0x98, 0xAB, + 0xAB, 0x55, 0x5C, 0x68, 0x73, 0x00, 0x09, 0x14, 0x1E, 0x26, 0x48, 0x61, 0x67, 0x6C, 0x67, 0x7D, 0x7F, 0x80, 0x8B, 0x87, 0x8F, 0x98, 0xAB, 0xAB, 0x55, 0x5C, 0x68, 0x73), + _INIT_DCS_CMD(0xE7, 0x0E, 0x10, 0x10, 0x21, 0x2B, 0x9A, 0x02, 0x54, 0x9A, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x12, 0x05, 0x02, 0x02, 0x10), + _INIT_DCS_CMD(0xBD, 0x01), + _INIT_DCS_CMD(0xB1, 0x01, 0xBF, 0x11), + _INIT_DCS_CMD(0xCB, 0x86), + _INIT_DCS_CMD(0xD2, 0x3C, 0xFA), + _INIT_DCS_CMD(0xD3, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0C, 0x01), + _INIT_DCS_CMD(0xE7, 0x02, 0x00, 0x28, 0x01, 0x7E, 0x0F, 0x7E, 0x10, 0xA0, 0x00, 0x00, 0x20, 0x40, 0x50, 0x40), + _INIT_DCS_CMD(0xBD, 0x02), + _INIT_DCS_CMD(0xD8, 0xFF, 0xFF, 0xBF, 0xFE, 0xAA, 0xA0, 0xFF, 0xFF, 0xBF, 0xFE, 0xAA, 0xA0), + _INIT_DCS_CMD(0xE7, 0xFE, 0x04, 0xFE, 0x04, 0xFE, 0x04, 0x03, 0x03, 0x03, 0x26, 0x00, 0x26, 0x81, 0x02, 0x40, 0x00, 0x20, 0x9E, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00), + _INIT_DCS_CMD(0xBD, 0x03), + _INIT_DCS_CMD(0xE9, 0xC6), + _INIT_DCS_CMD(0xB4, 0x03, 0xFF, 0xF8), + _INIT_DCS_CMD(0xE9, 0x3F), + _INIT_DCS_CMD(0xD8, 0x00, 0x2A, 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xA8, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xA8, + 0x00, 0x00, 0x00, 0x2A, 0xAA, 0xA8, 0x00, 0x00), + _INIT_DCS_CMD(0xBD, 0x00), + _INIT_DCS_CMD(0xE9, 0xC4), + _INIT_DCS_CMD(0xBA, 0x96), + _INIT_DCS_CMD(0xE9, 0x3F), + _INIT_DCS_CMD(0xBD, 0x01), + _INIT_DCS_CMD(0xE9, 0xC5), + _INIT_DCS_CMD(0xBA, 0x4F), + _INIT_DCS_CMD(0xE9, 0x3F), + _INIT_DCS_CMD(0xBD, 0x00), + _INIT_DCS_CMD(0x11), + _INIT_DELAY_CMD(120), + _INIT_DCS_CMD(0x29), + {}, +}; + +static const struct panel_init_cmd starry_ili9882t_init_cmd[] = { + _INIT_DELAY_CMD(5), + _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x01), + _INIT_DCS_CMD(0x00, 0x42), + _INIT_DCS_CMD(0x01, 0x11), + _INIT_DCS_CMD(0x02, 0x00), + _INIT_DCS_CMD(0x03, 0x00), + + _INIT_DCS_CMD(0x04, 0x01), + _INIT_DCS_CMD(0x05, 0x11), + _INIT_DCS_CMD(0x06, 0x00), + _INIT_DCS_CMD(0x07, 0x00), + + _INIT_DCS_CMD(0x08, 0x80), + _INIT_DCS_CMD(0x09, 0x81), + _INIT_DCS_CMD(0x0A, 0x71), + _INIT_DCS_CMD(0x0B, 0x00), + + _INIT_DCS_CMD(0x0C, 0x00), + _INIT_DCS_CMD(0x0E, 0x1A), + + _INIT_DCS_CMD(0x24, 0x00), + _INIT_DCS_CMD(0x25, 0x00), + _INIT_DCS_CMD(0x26, 0x00), + _INIT_DCS_CMD(0x27, 0x00), + + _INIT_DCS_CMD(0x2C, 0xD4), + _INIT_DCS_CMD(0xB9, 0x40), + + _INIT_DCS_CMD(0xB0, 0x11), + + _INIT_DCS_CMD(0xE6, 0x32), + _INIT_DCS_CMD(0xD1, 0x30), + + _INIT_DCS_CMD(0xD6, 0x55), + + _INIT_DCS_CMD(0xD0, 0x01), + _INIT_DCS_CMD(0xE3, 0x93), + _INIT_DCS_CMD(0xE4, 0x00), + _INIT_DCS_CMD(0xE5, 0x80), + + _INIT_DCS_CMD(0x31, 0x07), + _INIT_DCS_CMD(0x32, 0x07), + _INIT_DCS_CMD(0x33, 0x07), + _INIT_DCS_CMD(0x34, 0x07), + _INIT_DCS_CMD(0x35, 0x07), + _INIT_DCS_CMD(0x36, 0x01), + _INIT_DCS_CMD(0x37, 0x00), + _INIT_DCS_CMD(0x38, 0x28), + _INIT_DCS_CMD(0x39, 0x29), + _INIT_DCS_CMD(0x3A, 0x11), + _INIT_DCS_CMD(0x3B, 0x13), + _INIT_DCS_CMD(0x3C, 0x15), + _INIT_DCS_CMD(0x3D, 0x17), + _INIT_DCS_CMD(0x3E, 0x09), + _INIT_DCS_CMD(0x3F, 0x0D), + _INIT_DCS_CMD(0x40, 0x02), + _INIT_DCS_CMD(0x41, 0x02), + _INIT_DCS_CMD(0x42, 0x02), + _INIT_DCS_CMD(0x43, 0x02), + _INIT_DCS_CMD(0x44, 0x02), + _INIT_DCS_CMD(0x45, 0x02), + _INIT_DCS_CMD(0x46, 0x02), + + _INIT_DCS_CMD(0x47, 0x07), + _INIT_DCS_CMD(0x48, 0x07), + _INIT_DCS_CMD(0x49, 0x07), + _INIT_DCS_CMD(0x4A, 0x07), + _INIT_DCS_CMD(0x4B, 0x07), + _INIT_DCS_CMD(0x4C, 0x01), + _INIT_DCS_CMD(0x4D, 0x00), + _INIT_DCS_CMD(0x4E, 0x28), + _INIT_DCS_CMD(0x4F, 0x29), + _INIT_DCS_CMD(0x50, 0x10), + _INIT_DCS_CMD(0x51, 0x12), + _INIT_DCS_CMD(0x52, 0x14), + _INIT_DCS_CMD(0x53, 0x16), + _INIT_DCS_CMD(0x54, 0x08), + _INIT_DCS_CMD(0x55, 0x0C), + _INIT_DCS_CMD(0x56, 0x02), + _INIT_DCS_CMD(0x57, 0x02), + _INIT_DCS_CMD(0x58, 0x02), + _INIT_DCS_CMD(0x59, 0x02), + _INIT_DCS_CMD(0x5A, 0x02), + _INIT_DCS_CMD(0x5B, 0x02), + _INIT_DCS_CMD(0x5C, 0x02), + + _INIT_DCS_CMD(0x61, 0x07), + _INIT_DCS_CMD(0x62, 0x07), + _INIT_DCS_CMD(0x63, 0x07), + _INIT_DCS_CMD(0x64, 0x07), + _INIT_DCS_CMD(0x65, 0x07), + _INIT_DCS_CMD(0x66, 0x01), + _INIT_DCS_CMD(0x67, 0x00), + _INIT_DCS_CMD(0x68, 0x28), + _INIT_DCS_CMD(0x69, 0x29), + _INIT_DCS_CMD(0x6A, 0x16), + _INIT_DCS_CMD(0x6B, 0x14), + _INIT_DCS_CMD(0x6C, 0x12), + _INIT_DCS_CMD(0x6D, 0x10), + _INIT_DCS_CMD(0x6E, 0x0C), + _INIT_DCS_CMD(0x6F, 0x08), + _INIT_DCS_CMD(0x70, 0x02), + _INIT_DCS_CMD(0x71, 0x02), + _INIT_DCS_CMD(0x72, 0x02), + _INIT_DCS_CMD(0x73, 0x02), + _INIT_DCS_CMD(0x74, 0x02), + _INIT_DCS_CMD(0x75, 0x02), + _INIT_DCS_CMD(0x76, 0x02), + + _INIT_DCS_CMD(0x77, 0x07), + _INIT_DCS_CMD(0x78, 0x07), + _INIT_DCS_CMD(0x79, 0x07), + _INIT_DCS_CMD(0x7A, 0x07), + _INIT_DCS_CMD(0x7B, 0x07), + _INIT_DCS_CMD(0x7C, 0x01), + _INIT_DCS_CMD(0x7D, 0x00), + _INIT_DCS_CMD(0x7E, 0x28), + _INIT_DCS_CMD(0x7F, 0x29), + _INIT_DCS_CMD(0x80, 0x17), + _INIT_DCS_CMD(0x81, 0x15), + _INIT_DCS_CMD(0x82, 0x13), + _INIT_DCS_CMD(0x83, 0x11), + _INIT_DCS_CMD(0x84, 0x0D), + _INIT_DCS_CMD(0x85, 0x09), + _INIT_DCS_CMD(0x86, 0x02), + _INIT_DCS_CMD(0x87, 0x07), + _INIT_DCS_CMD(0x88, 0x07), + _INIT_DCS_CMD(0x89, 0x07), + _INIT_DCS_CMD(0x8A, 0x07), + _INIT_DCS_CMD(0x8B, 0x07), + _INIT_DCS_CMD(0x8C, 0x07), + + _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x02), + _INIT_DCS_CMD(0x29, 0x3A), + _INIT_DCS_CMD(0x2A, 0x3B), + + _INIT_DCS_CMD(0x06, 0x01), + _INIT_DCS_CMD(0x07, 0x01), + _INIT_DCS_CMD(0x08, 0x0C), + _INIT_DCS_CMD(0x09, 0x44), + + _INIT_DCS_CMD(0x3C, 0x0A), + _INIT_DCS_CMD(0x39, 0x11), + _INIT_DCS_CMD(0x3D, 0x00), + _INIT_DCS_CMD(0x3A, 0x0C), + _INIT_DCS_CMD(0x3B, 0x44), + + _INIT_DCS_CMD(0x53, 0x1F), + _INIT_DCS_CMD(0x5E, 0x40), + _INIT_DCS_CMD(0x84, 0x00), + + _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x03), + _INIT_DCS_CMD(0x20, 0x01), + _INIT_DCS_CMD(0x21, 0x3C), + _INIT_DCS_CMD(0x22, 0xFA), + + _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x0A), + _INIT_DCS_CMD(0xE0, 0x01), + _INIT_DCS_CMD(0xE2, 0x01), + _INIT_DCS_CMD(0xE5, 0x91), + _INIT_DCS_CMD(0xE6, 0x3C), + _INIT_DCS_CMD(0xE7, 0x00), + _INIT_DCS_CMD(0xE8, 0xFA), + + _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x12), + _INIT_DCS_CMD(0x87, 0x2C), + + _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x05), + _INIT_DCS_CMD(0x73, 0xE5), + _INIT_DCS_CMD(0x7F, 0x6B), + _INIT_DCS_CMD(0x6D, 0xA4), + _INIT_DCS_CMD(0x79, 0x54), + _INIT_DCS_CMD(0x69, 0x97), + _INIT_DCS_CMD(0x6A, 0x97), + _INIT_DCS_CMD(0xA5, 0x3F), + _INIT_DCS_CMD(0x61, 0xDA), + _INIT_DCS_CMD(0xA7, 0xF1), + _INIT_DCS_CMD(0x5F, 0x01), + _INIT_DCS_CMD(0x62, 0x3F), + _INIT_DCS_CMD(0x1D, 0x90), + _INIT_DCS_CMD(0x86, 0x87), + + _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x06), + _INIT_DCS_CMD(0xC0, 0x80), + _INIT_DCS_CMD(0xC1, 0x07), + _INIT_DCS_CMD(0xCA, 0x58), + _INIT_DCS_CMD(0xCB, 0x02), + _INIT_DCS_CMD(0xCE, 0x58), + _INIT_DCS_CMD(0xCF, 0x02), + _INIT_DCS_CMD(0x67, 0x60), + _INIT_DCS_CMD(0x10, 0x00), + _INIT_DCS_CMD(0x92, 0x22), + _INIT_DCS_CMD(0xD3, 0x08), + _INIT_DCS_CMD(0xD6, 0x55), + _INIT_DCS_CMD(0xDC, 0x38), + + _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x08), + _INIT_DCS_CMD(0xE0, 0x00, 0x10, 0x2A, 0x4D, 0x61, 0x56, 0x6A, 0x6E, 0x79, 0x76, 0x8F, 0x95, 0x98, 0xAE, 0xAA, 0xB2, 0xBB, 0xCE, 0xC6, 0xBD, 0xD5, 0xE2, 0xE8), + _INIT_DCS_CMD(0xE1, 0x00, 0x10, 0x2A, 0x4D, 0x61, 0x56, 0x6A, 0x6E, 0x79, 0x76, 0x8F, 0x95, 0x98, 0xAE, 0xAA, 0xB2, 0xBB, 0xCE, 0xC6, 0xBD, 0xD5, 0xE2, 0xE8), + + _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x04), + _INIT_DCS_CMD(0xBA, 0x81), + + _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x0C), + _INIT_DCS_CMD(0x00, 0x02), + _INIT_DCS_CMD(0x01, 0x00), + _INIT_DCS_CMD(0x02, 0x03), + _INIT_DCS_CMD(0x03, 0x01), + _INIT_DCS_CMD(0x04, 0x03), + _INIT_DCS_CMD(0x05, 0x02), + _INIT_DCS_CMD(0x06, 0x04), + _INIT_DCS_CMD(0x07, 0x03), + _INIT_DCS_CMD(0x08, 0x03), + _INIT_DCS_CMD(0x09, 0x04), + _INIT_DCS_CMD(0x0A, 0x04), + _INIT_DCS_CMD(0x0B, 0x05), + _INIT_DCS_CMD(0x0C, 0x04), + _INIT_DCS_CMD(0x0D, 0x06), + _INIT_DCS_CMD(0x0E, 0x05), + _INIT_DCS_CMD(0x0F, 0x07), + _INIT_DCS_CMD(0x10, 0x04), + _INIT_DCS_CMD(0x11, 0x08), + _INIT_DCS_CMD(0x12, 0x05), + _INIT_DCS_CMD(0x13, 0x09), + _INIT_DCS_CMD(0x14, 0x05), + _INIT_DCS_CMD(0x15, 0x0A), + _INIT_DCS_CMD(0x16, 0x06), + _INIT_DCS_CMD(0x17, 0x0B), + _INIT_DCS_CMD(0x18, 0x05), + _INIT_DCS_CMD(0x19, 0x0C), + _INIT_DCS_CMD(0x1A, 0x06), + _INIT_DCS_CMD(0x1B, 0x0D), + _INIT_DCS_CMD(0x1C, 0x06), + _INIT_DCS_CMD(0x1D, 0x0E), + _INIT_DCS_CMD(0x1E, 0x07), + _INIT_DCS_CMD(0x1F, 0x0F), + _INIT_DCS_CMD(0x20, 0x06), + _INIT_DCS_CMD(0x21, 0x10), + _INIT_DCS_CMD(0x22, 0x07), + _INIT_DCS_CMD(0x23, 0x11), + _INIT_DCS_CMD(0x24, 0x07), + _INIT_DCS_CMD(0x25, 0x12), + _INIT_DCS_CMD(0x26, 0x08), + _INIT_DCS_CMD(0x27, 0x13), + _INIT_DCS_CMD(0x28, 0x07), + _INIT_DCS_CMD(0x29, 0x14), + _INIT_DCS_CMD(0x2A, 0x08), + _INIT_DCS_CMD(0x2B, 0x15), + _INIT_DCS_CMD(0x2C, 0x08), + _INIT_DCS_CMD(0x2D, 0x16), + _INIT_DCS_CMD(0x2E, 0x09), + _INIT_DCS_CMD(0x2F, 0x17), + _INIT_DCS_CMD(0x30, 0x08), + _INIT_DCS_CMD(0x31, 0x18), + _INIT_DCS_CMD(0x32, 0x09), + _INIT_DCS_CMD(0x33, 0x19), + _INIT_DCS_CMD(0x34, 0x09), + _INIT_DCS_CMD(0x35, 0x1A), + _INIT_DCS_CMD(0x36, 0x0A), + _INIT_DCS_CMD(0x37, 0x1B), + _INIT_DCS_CMD(0x38, 0x0A), + _INIT_DCS_CMD(0x39, 0x1C), + _INIT_DCS_CMD(0x3A, 0x0A), + _INIT_DCS_CMD(0x3B, 0x1D), + _INIT_DCS_CMD(0x3C, 0x0A), + _INIT_DCS_CMD(0x3D, 0x1E), + _INIT_DCS_CMD(0x3E, 0x0A), + _INIT_DCS_CMD(0x3F, 0x1F), + + _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x04), + _INIT_DCS_CMD(0xBA, 0x01), + + _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x0E), + _INIT_DCS_CMD(0x02, 0x0C), + _INIT_DCS_CMD(0x20, 0x10), + _INIT_DCS_CMD(0x25, 0x16), + _INIT_DCS_CMD(0x26, 0xE0), + _INIT_DCS_CMD(0x27, 0x00), + _INIT_DCS_CMD(0x29, 0x71), + _INIT_DCS_CMD(0x2A, 0x46), + _INIT_DCS_CMD(0x2B, 0x1F), + _INIT_DCS_CMD(0x2D, 0xC7), + _INIT_DCS_CMD(0x31, 0x02), + _INIT_DCS_CMD(0x32, 0xDF), + _INIT_DCS_CMD(0x33, 0x5A), + _INIT_DCS_CMD(0x34, 0xC0), + _INIT_DCS_CMD(0x35, 0x5A), + _INIT_DCS_CMD(0x36, 0xC0), + _INIT_DCS_CMD(0x38, 0x65), + _INIT_DCS_CMD(0x80, 0x3E), + _INIT_DCS_CMD(0x81, 0xA0), + _INIT_DCS_CMD(0xB0, 0x01), + _INIT_DCS_CMD(0xB1, 0xCC), + _INIT_DCS_CMD(0xC0, 0x12), + _INIT_DCS_CMD(0xC2, 0xCC), + _INIT_DCS_CMD(0xC3, 0xCC), + _INIT_DCS_CMD(0xC4, 0xCC), + _INIT_DCS_CMD(0xC5, 0xCC), + _INIT_DCS_CMD(0xC6, 0xCC), + _INIT_DCS_CMD(0xC7, 0xCC), + _INIT_DCS_CMD(0xC8, 0xCC), + _INIT_DCS_CMD(0xC9, 0xCC), + _INIT_DCS_CMD(0x30, 0x00), + _INIT_DCS_CMD(0x00, 0x81), + _INIT_DCS_CMD(0x08, 0x02), + _INIT_DCS_CMD(0x09, 0x00), + _INIT_DCS_CMD(0x07, 0x21), + _INIT_DCS_CMD(0x04, 0x10), + + _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x1E), + _INIT_DCS_CMD(0x60, 0x00), + _INIT_DCS_CMD(0x64, 0x00), + _INIT_DCS_CMD(0x6D, 0x00), + + _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x0B), + _INIT_DCS_CMD(0xA6, 0x44), + _INIT_DCS_CMD(0xA7, 0xB6), + _INIT_DCS_CMD(0xA8, 0x03), + _INIT_DCS_CMD(0xA9, 0x03), + _INIT_DCS_CMD(0xAA, 0x51), + _INIT_DCS_CMD(0xAB, 0x51), + _INIT_DCS_CMD(0xAC, 0x04), + _INIT_DCS_CMD(0xBD, 0x92), + _INIT_DCS_CMD(0xBE, 0xA1), + + _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x05), + _INIT_DCS_CMD(0x86, 0x87), + + _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x06), + _INIT_DCS_CMD(0x92, 0x22), + + _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x00), + _INIT_DCS_CMD(0x11), + _INIT_DELAY_CMD(120), + _INIT_DCS_CMD(0x29), + _INIT_DELAY_CMD(20), + {}, +}; + static inline struct boe_panel *to_boe_panel(struct drm_panel *panel) { return container_of(panel, struct boe_panel, base); @@ -1366,6 +1846,10 @@ static int boe_panel_prepare(struct drm_panel *panel) usleep_range(10000, 11000); + if (boe->desc->lp11_before_reset) { + mipi_dsi_dcs_nop(boe->dsi); + usleep_range(1000, 2000); + } gpiod_set_value(boe->enable_gpio, 1); usleep_range(1000, 2000); gpiod_set_value(boe->enable_gpio, 0); @@ -1431,15 +1915,15 @@ static const struct panel_desc boe_tv110c9m_desc = { }; static const struct drm_display_mode inx_hj110iz_default_mode = { - .clock = 166594, + .clock = 168432, .hdisplay = 1200, .hsync_start = 1200 + 40, .hsync_end = 1200 + 40 + 8, .htotal = 1200 + 40 + 8 + 28, .vdisplay = 2000, .vsync_start = 2000 + 26, - .vsync_end = 2000 + 26 + 1, - .vtotal = 2000 + 26 + 1 + 149, + .vsync_end = 2000 + 26 + 2, + .vtotal = 2000 + 26 + 2 + 172, .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, }; @@ -1592,6 +2076,7 @@ static const struct panel_desc boe_tv105wum_nw0_desc = { .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | MIPI_DSI_MODE_LPM, .init_cmds = boe_init_cmd, + .lp11_before_reset = true, }; static const struct drm_display_mode starry_qfh032011_53g_default_mode = { @@ -1620,6 +2105,62 @@ static const struct panel_desc starry_qfh032011_53g_desc = { .init_cmds = starry_qfh032011_53g_init_cmd, }; +static const struct drm_display_mode starry_himax83102_j02_default_mode = { + .clock = 161600, + .hdisplay = 1200, + .hsync_start = 1200 + 40, + .hsync_end = 1200 + 40 + 20, + .htotal = 1200 + 40 + 20 + 40, + .vdisplay = 1920, + .vsync_start = 1920 + 116, + .vsync_end = 1920 + 116 + 8, + .vtotal = 1920 + 116 + 8 + 12, + .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, +}; + +static const struct panel_desc starry_himax83102_j02_desc = { + .modes = &starry_himax83102_j02_default_mode, + .bpc = 8, + .size = { + .width_mm = 141, + .height_mm = 226, + }, + .lanes = 4, + .format = MIPI_DSI_FMT_RGB888, + .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | + MIPI_DSI_MODE_LPM, + .init_cmds = starry_himax83102_j02_init_cmd, + .lp11_before_reset = true, +}; + +static const struct drm_display_mode starry_ili9882t_default_mode = { + .clock = 165280, + .hdisplay = 1200, + .hsync_start = 1200 + 72, + .hsync_end = 1200 + 72 + 30, + .htotal = 1200 + 72 + 30 + 72, + .vdisplay = 1920, + .vsync_start = 1920 + 68, + .vsync_end = 1920 + 68 + 2, + .vtotal = 1920 + 68 + 2 + 10, + .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, +}; + +static const struct panel_desc starry_ili9882t_desc = { + .modes = &starry_ili9882t_default_mode, + .bpc = 8, + .size = { + .width_mm = 141, + .height_mm = 226, + }, + .lanes = 4, + .format = MIPI_DSI_FMT_RGB888, + .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | + MIPI_DSI_MODE_LPM, + .init_cmds = starry_ili9882t_init_cmd, + .lp11_before_reset = true, +}; + static int boe_panel_get_modes(struct drm_panel *panel, struct drm_connector *connector) { @@ -1793,6 +2334,12 @@ static const struct of_device_id boe_of_match[] = { { .compatible = "starry,2081101qfh032011-53g", .data = &starry_qfh032011_53g_desc }, + { .compatible = "starry,himax83102-j02", + .data = &starry_himax83102_j02_desc + }, + { .compatible = "starry,ili9882t", + .data = &starry_ili9882t_desc + }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, boe_of_match); diff --git a/drivers/gpu/drm/panel/panel-dsi-cm.c b/drivers/gpu/drm/panel/panel-dsi-cm.c index ba17bcc4461c..6b3f4d664d2a 100644 --- a/drivers/gpu/drm/panel/panel-dsi-cm.c +++ b/drivers/gpu/drm/panel/panel-dsi-cm.c @@ -11,7 +11,7 @@ #include <linux/gpio/consumer.h> #include <linux/jiffies.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/regulator/consumer.h> #include <drm/drm_connector.h> diff --git a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/panel-edp.c index e23ddab2126e..feb665df35a1 100644 --- a/drivers/gpu/drm/panel/panel-edp.c +++ b/drivers/gpu/drm/panel/panel-edp.c @@ -903,7 +903,7 @@ err_finished_ddc_init: return err; } -static int panel_edp_remove(struct device *dev) +static void panel_edp_remove(struct device *dev) { struct panel_edp *panel = dev_get_drvdata(dev); @@ -918,8 +918,6 @@ static int panel_edp_remove(struct device *dev) kfree(panel->edid); panel->edid = NULL; - - return 0; } static void panel_edp_shutdown(struct device *dev) @@ -1868,6 +1866,7 @@ static const struct panel_delay delay_200_500_e200 = { */ static const struct edp_panel_entry edp_panels[] = { EDP_PANEL_ENTRY('A', 'U', 'O', 0x1062, &delay_200_500_e50, "B120XAN01.0"), + EDP_PANEL_ENTRY('A', 'U', 'O', 0x145c, &delay_200_500_e50, "B116XAB01.4"), EDP_PANEL_ENTRY('A', 'U', 'O', 0x1e9b, &delay_200_500_e50, "B133UAN02.1"), EDP_PANEL_ENTRY('A', 'U', 'O', 0x1ea5, &delay_200_500_e50, "B116XAK01.6"), EDP_PANEL_ENTRY('A', 'U', 'O', 0x405c, &auo_b116xak01.delay, "B116XAK01"), @@ -1891,6 +1890,7 @@ static const struct edp_panel_entry edp_panels[] = { EDP_PANEL_ENTRY('C', 'M', 'N', 0x1153, &delay_200_500_e80_d50, "N116BGE-EA2"), EDP_PANEL_ENTRY('C', 'M', 'N', 0x1154, &delay_200_500_e80_d50, "N116BCA-EA2"), EDP_PANEL_ENTRY('C', 'M', 'N', 0x1247, &delay_200_500_e80_d50, "N120ACA-EA1"), + EDP_PANEL_ENTRY('C', 'M', 'N', 0x14d4, &delay_200_500_e80_d50, "N140HCA-EAC"), EDP_PANEL_ENTRY('I', 'V', 'O', 0x057d, &delay_200_500_e200, "R140NWF5 RH"), EDP_PANEL_ENTRY('I', 'V', 'O', 0x854a, &delay_200_500_p2e100, "M133NW4J"), @@ -1934,9 +1934,9 @@ static int panel_edp_platform_probe(struct platform_device *pdev) return panel_edp_probe(&pdev->dev, id->data, NULL); } -static int panel_edp_platform_remove(struct platform_device *pdev) +static void panel_edp_platform_remove(struct platform_device *pdev) { - return panel_edp_remove(&pdev->dev); + panel_edp_remove(&pdev->dev); } static void panel_edp_platform_shutdown(struct platform_device *pdev) @@ -1957,7 +1957,7 @@ static struct platform_driver panel_edp_platform_driver = { .pm = &panel_edp_pm_ops, }, .probe = panel_edp_platform_probe, - .remove = panel_edp_platform_remove, + .remove_new = panel_edp_platform_remove, .shutdown = panel_edp_platform_shutdown, }; diff --git a/drivers/gpu/drm/panel/panel-feixin-k101-im2ba02.c b/drivers/gpu/drm/panel/panel-feixin-k101-im2ba02.c index 76572c922983..986e3e192881 100644 --- a/drivers/gpu/drm/panel/panel-feixin-k101-im2ba02.c +++ b/drivers/gpu/drm/panel/panel-feixin-k101-im2ba02.c @@ -7,7 +7,6 @@ #include <linux/delay.h> #include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/of_device.h> #include <linux/regulator/consumer.h> #include <drm/drm_mipi_dsi.h> diff --git a/drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c b/drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c index df493da50afe..48e3acaecdf3 100644 --- a/drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c +++ b/drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c @@ -11,7 +11,7 @@ #include <linux/gpio/consumer.h> #include <linux/delay.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/mod_devicetable.h> #include <linux/regulator/consumer.h> #define FEIYANG_INIT_CMD_LEN 2 diff --git a/drivers/gpu/drm/panel/panel-himax-hx8394.c b/drivers/gpu/drm/panel/panel-himax-hx8394.c index d4fb5d1b295b..c73243d85de7 100644 --- a/drivers/gpu/drm/panel/panel-himax-hx8394.c +++ b/drivers/gpu/drm/panel/panel-himax-hx8394.c @@ -15,7 +15,7 @@ #include <linux/media-bus-format.h> #include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/regulator/consumer.h> #include <video/mipi_display.h> diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9322.c b/drivers/gpu/drm/panel/panel-ilitek-ili9322.c index 3dfafa585127..61c872f0f7ca 100644 --- a/drivers/gpu/drm/panel/panel-ilitek-ili9322.c +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9322.c @@ -22,7 +22,8 @@ #include <linux/bitops.h> #include <linux/gpio/consumer.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> +#include <linux/platform_device.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <linux/spi/spi.h> diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c index 3fdf884b3257..3574681891e8 100644 --- a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c @@ -23,7 +23,7 @@ #include <linux/delay.h> #include <linux/gpio/consumer.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/regulator/consumer.h> #include <linux/spi/spi.h> diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c b/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c index 1ec696adf9de..7838947a1bf3 100644 --- a/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c @@ -9,7 +9,7 @@ #include <linux/errno.h> #include <linux/kernel.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/gpio/consumer.h> #include <linux/regulator/consumer.h> @@ -455,6 +455,174 @@ static const struct ili9881c_instr k101_im2byl02_init[] = { ILI9881C_COMMAND_INSTR(0xD3, 0x3F), /* VN0 */ }; +static const struct ili9881c_instr tl050hdv35_init[] = { + ILI9881C_SWITCH_PAGE_INSTR(3), + ILI9881C_COMMAND_INSTR(0x01, 0x00), + ILI9881C_COMMAND_INSTR(0x02, 0x00), + ILI9881C_COMMAND_INSTR(0x03, 0x73), + ILI9881C_COMMAND_INSTR(0x04, 0x00), + ILI9881C_COMMAND_INSTR(0x05, 0x00), + ILI9881C_COMMAND_INSTR(0x06, 0x0a), + ILI9881C_COMMAND_INSTR(0x07, 0x00), + ILI9881C_COMMAND_INSTR(0x08, 0x00), + ILI9881C_COMMAND_INSTR(0x09, 0x01), + ILI9881C_COMMAND_INSTR(0x0a, 0x00), + ILI9881C_COMMAND_INSTR(0x0b, 0x00), + ILI9881C_COMMAND_INSTR(0x0c, 0x01), + ILI9881C_COMMAND_INSTR(0x0d, 0x00), + ILI9881C_COMMAND_INSTR(0x0e, 0x00), + ILI9881C_COMMAND_INSTR(0x0f, 0x1d), + ILI9881C_COMMAND_INSTR(0x10, 0x1d), + ILI9881C_COMMAND_INSTR(0x15, 0x00), + ILI9881C_COMMAND_INSTR(0x16, 0x00), + ILI9881C_COMMAND_INSTR(0x17, 0x00), + ILI9881C_COMMAND_INSTR(0x18, 0x00), + ILI9881C_COMMAND_INSTR(0x19, 0x00), + ILI9881C_COMMAND_INSTR(0x1a, 0x00), + ILI9881C_COMMAND_INSTR(0x1b, 0x00), + ILI9881C_COMMAND_INSTR(0x1c, 0x00), + ILI9881C_COMMAND_INSTR(0x1d, 0x00), + ILI9881C_COMMAND_INSTR(0x1e, 0x40), + ILI9881C_COMMAND_INSTR(0x1f, 0x80), + ILI9881C_COMMAND_INSTR(0x20, 0x06), + ILI9881C_COMMAND_INSTR(0x21, 0x02), + ILI9881C_COMMAND_INSTR(0x28, 0x33), + ILI9881C_COMMAND_INSTR(0x29, 0x03), + ILI9881C_COMMAND_INSTR(0x2a, 0x00), + ILI9881C_COMMAND_INSTR(0x2b, 0x00), + ILI9881C_COMMAND_INSTR(0x2c, 0x00), + ILI9881C_COMMAND_INSTR(0x2d, 0x00), + ILI9881C_COMMAND_INSTR(0x2e, 0x00), + ILI9881C_COMMAND_INSTR(0x2f, 0x00), + ILI9881C_COMMAND_INSTR(0x35, 0x00), + ILI9881C_COMMAND_INSTR(0x36, 0x00), + ILI9881C_COMMAND_INSTR(0x37, 0x00), + ILI9881C_COMMAND_INSTR(0x38, 0x3C), + ILI9881C_COMMAND_INSTR(0x39, 0x00), + ILI9881C_COMMAND_INSTR(0x3a, 0x40), + ILI9881C_COMMAND_INSTR(0x3b, 0x40), + ILI9881C_COMMAND_INSTR(0x3c, 0x00), + ILI9881C_COMMAND_INSTR(0x3d, 0x00), + ILI9881C_COMMAND_INSTR(0x3e, 0x00), + ILI9881C_COMMAND_INSTR(0x3f, 0x00), + ILI9881C_COMMAND_INSTR(0x40, 0x00), + ILI9881C_COMMAND_INSTR(0x41, 0x00), + ILI9881C_COMMAND_INSTR(0x42, 0x00), + ILI9881C_COMMAND_INSTR(0x43, 0x00), + ILI9881C_COMMAND_INSTR(0x44, 0x00), + ILI9881C_COMMAND_INSTR(0x55, 0xab), + ILI9881C_COMMAND_INSTR(0x5a, 0x89), + ILI9881C_COMMAND_INSTR(0x5b, 0xab), + ILI9881C_COMMAND_INSTR(0x5c, 0xcd), + ILI9881C_COMMAND_INSTR(0x5d, 0xef), + ILI9881C_COMMAND_INSTR(0x5e, 0x11), + ILI9881C_COMMAND_INSTR(0x5f, 0x01), + ILI9881C_COMMAND_INSTR(0x60, 0x00), + ILI9881C_COMMAND_INSTR(0x61, 0x15), + ILI9881C_COMMAND_INSTR(0x62, 0x14), + ILI9881C_COMMAND_INSTR(0x63, 0x0e), + ILI9881C_COMMAND_INSTR(0x64, 0x0f), + ILI9881C_COMMAND_INSTR(0x65, 0x0c), + ILI9881C_COMMAND_INSTR(0x66, 0x0d), + ILI9881C_COMMAND_INSTR(0x67, 0x06), + ILI9881C_COMMAND_INSTR(0x68, 0x02), + ILI9881C_COMMAND_INSTR(0x69, 0x07), + ILI9881C_COMMAND_INSTR(0x6a, 0x02), + ILI9881C_COMMAND_INSTR(0x6b, 0x02), + ILI9881C_COMMAND_INSTR(0x6c, 0x02), + ILI9881C_COMMAND_INSTR(0x6d, 0x02), + ILI9881C_COMMAND_INSTR(0x6e, 0x02), + ILI9881C_COMMAND_INSTR(0x6f, 0x02), + ILI9881C_COMMAND_INSTR(0x70, 0x02), + ILI9881C_COMMAND_INSTR(0x71, 0x02), + ILI9881C_COMMAND_INSTR(0x72, 0x02), + ILI9881C_COMMAND_INSTR(0x73, 0x02), + ILI9881C_COMMAND_INSTR(0x74, 0x02), + ILI9881C_COMMAND_INSTR(0x75, 0x01), + ILI9881C_COMMAND_INSTR(0x76, 0x00), + ILI9881C_COMMAND_INSTR(0x77, 0x14), + ILI9881C_COMMAND_INSTR(0x78, 0x15), + ILI9881C_COMMAND_INSTR(0x79, 0x0e), + ILI9881C_COMMAND_INSTR(0x7a, 0x0f), + ILI9881C_COMMAND_INSTR(0x7b, 0x0c), + ILI9881C_COMMAND_INSTR(0x7c, 0x0d), + ILI9881C_COMMAND_INSTR(0x7d, 0x06), + ILI9881C_COMMAND_INSTR(0x7e, 0x02), + ILI9881C_COMMAND_INSTR(0x7f, 0x07), + ILI9881C_COMMAND_INSTR(0x88, 0x02), + ILI9881C_COMMAND_INSTR(0x89, 0x02), + ILI9881C_COMMAND_INSTR(0x8A, 0x02), + ILI9881C_SWITCH_PAGE_INSTR(4), + ILI9881C_COMMAND_INSTR(0x38, 0x01), + ILI9881C_COMMAND_INSTR(0x39, 0x00), + ILI9881C_COMMAND_INSTR(0x6c, 0x15), + ILI9881C_COMMAND_INSTR(0x6e, 0x2b), + ILI9881C_COMMAND_INSTR(0x6f, 0x33), + ILI9881C_COMMAND_INSTR(0x8d, 0x18), + ILI9881C_COMMAND_INSTR(0x87, 0xba), + ILI9881C_COMMAND_INSTR(0x26, 0x76), + ILI9881C_COMMAND_INSTR(0xb2, 0xd1), + ILI9881C_COMMAND_INSTR(0xb5, 0x06), + ILI9881C_COMMAND_INSTR(0x3a, 0x24), + ILI9881C_COMMAND_INSTR(0x35, 0x1f), + ILI9881C_COMMAND_INSTR(0x33, 0x14), + ILI9881C_COMMAND_INSTR(0x3b, 0x98), + ILI9881C_SWITCH_PAGE_INSTR(1), + ILI9881C_COMMAND_INSTR(0x22, 0x0a), + ILI9881C_COMMAND_INSTR(0x31, 0x00), + ILI9881C_COMMAND_INSTR(0x40, 0x33), + ILI9881C_COMMAND_INSTR(0x53, 0xa2), + ILI9881C_COMMAND_INSTR(0x55, 0x92), + ILI9881C_COMMAND_INSTR(0x50, 0x96), + ILI9881C_COMMAND_INSTR(0x51, 0x96), + ILI9881C_COMMAND_INSTR(0x60, 0x22), + ILI9881C_COMMAND_INSTR(0x61, 0x00), + ILI9881C_COMMAND_INSTR(0x62, 0x19), + ILI9881C_COMMAND_INSTR(0x63, 0x00), + ILI9881C_COMMAND_INSTR(0xa0, 0x08), + ILI9881C_COMMAND_INSTR(0xa1, 0x11), + ILI9881C_COMMAND_INSTR(0xa2, 0x19), + ILI9881C_COMMAND_INSTR(0xa3, 0x0d), + ILI9881C_COMMAND_INSTR(0xa4, 0x0d), + ILI9881C_COMMAND_INSTR(0xa5, 0x1e), + ILI9881C_COMMAND_INSTR(0xa6, 0x14), + ILI9881C_COMMAND_INSTR(0xa7, 0x17), + ILI9881C_COMMAND_INSTR(0xa8, 0x4f), + ILI9881C_COMMAND_INSTR(0xa9, 0x1a), + ILI9881C_COMMAND_INSTR(0xaa, 0x27), + ILI9881C_COMMAND_INSTR(0xab, 0x49), + ILI9881C_COMMAND_INSTR(0xac, 0x1a), + ILI9881C_COMMAND_INSTR(0xad, 0x18), + ILI9881C_COMMAND_INSTR(0xae, 0x4c), + ILI9881C_COMMAND_INSTR(0xaf, 0x22), + ILI9881C_COMMAND_INSTR(0xb0, 0x27), + ILI9881C_COMMAND_INSTR(0xb1, 0x4b), + ILI9881C_COMMAND_INSTR(0xb2, 0x60), + ILI9881C_COMMAND_INSTR(0xb3, 0x39), + ILI9881C_COMMAND_INSTR(0xc0, 0x08), + ILI9881C_COMMAND_INSTR(0xc1, 0x11), + ILI9881C_COMMAND_INSTR(0xc2, 0x19), + ILI9881C_COMMAND_INSTR(0xc3, 0x0d), + ILI9881C_COMMAND_INSTR(0xc4, 0x0d), + ILI9881C_COMMAND_INSTR(0xc5, 0x1e), + ILI9881C_COMMAND_INSTR(0xc6, 0x14), + ILI9881C_COMMAND_INSTR(0xc7, 0x17), + ILI9881C_COMMAND_INSTR(0xc8, 0x4f), + ILI9881C_COMMAND_INSTR(0xc9, 0x1a), + ILI9881C_COMMAND_INSTR(0xca, 0x27), + ILI9881C_COMMAND_INSTR(0xcb, 0x49), + ILI9881C_COMMAND_INSTR(0xcc, 0x1a), + ILI9881C_COMMAND_INSTR(0xcd, 0x18), + ILI9881C_COMMAND_INSTR(0xce, 0x4c), + ILI9881C_COMMAND_INSTR(0xcf, 0x33), + ILI9881C_COMMAND_INSTR(0xd0, 0x27), + ILI9881C_COMMAND_INSTR(0xd1, 0x4b), + ILI9881C_COMMAND_INSTR(0xd2, 0x60), + ILI9881C_COMMAND_INSTR(0xd3, 0x39), + ILI9881C_SWITCH_PAGE_INSTR(0), + ILI9881C_COMMAND_INSTR(0x36, 0x03), +}; + static const struct ili9881c_instr w552946ab_init[] = { ILI9881C_SWITCH_PAGE_INSTR(3), ILI9881C_COMMAND_INSTR(0x01, 0x00), @@ -812,6 +980,23 @@ static const struct drm_display_mode k101_im2byl02_default_mode = { .height_mm = 217, }; +static const struct drm_display_mode tl050hdv35_default_mode = { + .clock = 59400, + + .hdisplay = 720, + .hsync_start = 720 + 18, + .hsync_end = 720 + 18 + 3, + .htotal = 720 + 18 + 3 + 20, + + .vdisplay = 1280, + .vsync_start = 1280 + 26, + .vsync_end = 1280 + 26 + 6, + .vtotal = 1280 + 26 + 6 + 28, + + .width_mm = 62, + .height_mm = 110, +}; + static const struct drm_display_mode w552946aba_default_mode = { .clock = 64000, @@ -944,6 +1129,14 @@ static const struct ili9881c_desc k101_im2byl02_desc = { .mode_flags = MIPI_DSI_MODE_VIDEO_SYNC_PULSE, }; +static const struct ili9881c_desc tl050hdv35_desc = { + .init = tl050hdv35_init, + .init_length = ARRAY_SIZE(tl050hdv35_init), + .mode = &tl050hdv35_default_mode, + .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | + MIPI_DSI_MODE_LPM, +}; + static const struct ili9881c_desc w552946aba_desc = { .init = w552946ab_init, .init_length = ARRAY_SIZE(w552946ab_init), @@ -955,6 +1148,7 @@ static const struct ili9881c_desc w552946aba_desc = { static const struct of_device_id ili9881c_of_match[] = { { .compatible = "bananapi,lhr050h41", .data = &lhr050h41_desc }, { .compatible = "feixin,k101-im2byl02", .data = &k101_im2byl02_desc }, + { .compatible = "tdo,tl050hdv35", .data = &tl050hdv35_desc }, { .compatible = "wanchanglong,w552946aba", .data = &w552946aba_desc }, { } }; diff --git a/drivers/gpu/drm/panel/panel-innolux-ej030na.c b/drivers/gpu/drm/panel/panel-innolux-ej030na.c index b2b0ebc9e943..8fdbda59be48 100644 --- a/drivers/gpu/drm/panel/panel-innolux-ej030na.c +++ b/drivers/gpu/drm/panel/panel-innolux-ej030na.c @@ -11,7 +11,8 @@ #include <linux/gpio/consumer.h> #include <linux/media-bus-format.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> +#include <linux/platform_device.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <linux/spi/spi.h> diff --git a/drivers/gpu/drm/panel/panel-innolux-p079zca.c b/drivers/gpu/drm/panel/panel-innolux-p079zca.c index 9992d0d4c0e5..485178a99910 100644 --- a/drivers/gpu/drm/panel/panel-innolux-p079zca.c +++ b/drivers/gpu/drm/panel/panel-innolux-p079zca.c @@ -7,7 +7,6 @@ #include <linux/gpio/consumer.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/regulator/consumer.h> #include <video/mipi_display.h> diff --git a/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c b/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c index 323c33c9c37a..4879835fe101 100644 --- a/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c +++ b/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c @@ -16,7 +16,7 @@ #include <linux/gpio/consumer.h> #include <linux/delay.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/regulator/consumer.h> #define JD9365DA_INIT_CMD_LEN 2 diff --git a/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c b/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c index 8f4f137a2af6..213008499caa 100644 --- a/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c +++ b/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c @@ -404,38 +404,30 @@ static int jdi_panel_add(struct jdi_panel *jdi) ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(jdi->supplies), jdi->supplies); - if (ret < 0) { - dev_err(dev, "failed to init regulator, ret=%d\n", ret); - return ret; - } + if (ret < 0) + return dev_err_probe(dev, ret, + "failed to init regulator, ret=%d\n", ret); jdi->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW); if (IS_ERR(jdi->enable_gpio)) { - ret = PTR_ERR(jdi->enable_gpio); - dev_err(dev, "cannot get enable-gpio %d\n", ret); - return ret; + return dev_err_probe(dev, PTR_ERR(jdi->enable_gpio), + "cannot get enable-gpio %d\n", ret); } jdi->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); - if (IS_ERR(jdi->reset_gpio)) { - ret = PTR_ERR(jdi->reset_gpio); - dev_err(dev, "cannot get reset-gpios %d\n", ret); - return ret; - } + if (IS_ERR(jdi->reset_gpio)) + return dev_err_probe(dev, PTR_ERR(jdi->reset_gpio), + "cannot get reset-gpios %d\n", ret); jdi->dcdc_en_gpio = devm_gpiod_get(dev, "dcdc-en", GPIOD_OUT_LOW); - if (IS_ERR(jdi->dcdc_en_gpio)) { - ret = PTR_ERR(jdi->dcdc_en_gpio); - dev_err(dev, "cannot get dcdc-en-gpio %d\n", ret); - return ret; - } + if (IS_ERR(jdi->dcdc_en_gpio)) + return dev_err_probe(dev, PTR_ERR(jdi->dcdc_en_gpio), + "cannot get dcdc-en-gpio %d\n", ret); jdi->backlight = drm_panel_create_dsi_backlight(jdi->dsi); - if (IS_ERR(jdi->backlight)) { - ret = PTR_ERR(jdi->backlight); - dev_err(dev, "failed to register backlight %d\n", ret); - return ret; - } + if (IS_ERR(jdi->backlight)) + return dev_err_probe(dev, PTR_ERR(jdi->backlight), + "failed to register backlight %d\n", ret); drm_panel_init(&jdi->base, &jdi->dsi->dev, &jdi_panel_funcs, DRM_MODE_CONNECTOR_DSI); diff --git a/drivers/gpu/drm/panel/panel-khadas-ts050.c b/drivers/gpu/drm/panel/panel-khadas-ts050.c index 1ab1ebe30882..b942a0162274 100644 --- a/drivers/gpu/drm/panel/panel-khadas-ts050.c +++ b/drivers/gpu/drm/panel/panel-khadas-ts050.c @@ -568,7 +568,7 @@ static const struct khadas_ts050_panel_cmd init_code[] = { {0xfb, 0x01}, /* Select CMD1 */ {0xff, 0x00}, - {0xd3, 0x05}, /* RGBMIPICTRL: VSYNC back porch = 5 */ + {0xd3, 0x22}, /* RGBMIPICTRL: VSYNC back porch = 34 */ {0xd4, 0x04}, /* RGBMIPICTRL: VSYNC front porch = 4 */ }; @@ -717,15 +717,15 @@ static int khadas_ts050_panel_disable(struct drm_panel *panel) } static const struct drm_display_mode default_mode = { - .clock = 120000, - .hdisplay = 1088, - .hsync_start = 1088 + 104, - .hsync_end = 1088 + 104 + 4, - .htotal = 1088 + 104 + 4 + 127, + .clock = 160000, + .hdisplay = 1080, + .hsync_start = 1080 + 117, + .hsync_end = 1080 + 117 + 5, + .htotal = 1080 + 117 + 5 + 160, .vdisplay = 1920, .vsync_start = 1920 + 4, - .vsync_end = 1920 + 4 + 2, - .vtotal = 1920 + 4 + 2 + 3, + .vsync_end = 1920 + 4 + 3, + .vtotal = 1920 + 4 + 3 + 31, .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, }; diff --git a/drivers/gpu/drm/panel/panel-leadtek-ltk050h3146w.c b/drivers/gpu/drm/panel/panel-leadtek-ltk050h3146w.c index d2efd887484b..d41482d3a34f 100644 --- a/drivers/gpu/drm/panel/panel-leadtek-ltk050h3146w.c +++ b/drivers/gpu/drm/panel/panel-leadtek-ltk050h3146w.c @@ -8,7 +8,6 @@ #include <linux/media-bus-format.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/regulator/consumer.h> #include <video/display_timing.h> diff --git a/drivers/gpu/drm/panel/panel-lvds.c b/drivers/gpu/drm/panel/panel-lvds.c index de8758c30e6e..1b8e3156914c 100644 --- a/drivers/gpu/drm/panel/panel-lvds.c +++ b/drivers/gpu/drm/panel/panel-lvds.c @@ -10,7 +10,7 @@ #include <linux/gpio/consumer.h> #include <linux/module.h> -#include <linux/of_platform.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/regulator/consumer.h> #include <linux/slab.h> @@ -228,15 +228,13 @@ static int panel_lvds_probe(struct platform_device *pdev) return 0; } -static int panel_lvds_remove(struct platform_device *pdev) +static void panel_lvds_remove(struct platform_device *pdev) { struct panel_lvds *lvds = platform_get_drvdata(pdev); drm_panel_remove(&lvds->panel); drm_panel_disable(&lvds->panel); - - return 0; } static const struct of_device_id panel_lvds_of_table[] = { @@ -248,7 +246,7 @@ MODULE_DEVICE_TABLE(of, panel_lvds_of_table); static struct platform_driver panel_lvds_driver = { .probe = panel_lvds_probe, - .remove = panel_lvds_remove, + .remove_new = panel_lvds_remove, .driver = { .name = "panel-lvds", .of_match_table = panel_lvds_of_table, diff --git a/drivers/gpu/drm/panel/panel-magnachip-d53e6ea8966.c b/drivers/gpu/drm/panel/panel-magnachip-d53e6ea8966.c index 26d358b9b85a..799c2161fc85 100644 --- a/drivers/gpu/drm/panel/panel-magnachip-d53e6ea8966.c +++ b/drivers/gpu/drm/panel/panel-magnachip-d53e6ea8966.c @@ -18,7 +18,6 @@ #include <linux/media-bus-format.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/regulator/consumer.h> #include <linux/spi/spi.h> diff --git a/drivers/gpu/drm/panel/panel-mantix-mlaf057we51.c b/drivers/gpu/drm/panel/panel-mantix-mlaf057we51.c index 9243b2ad828d..ea4a6bf6d35b 100644 --- a/drivers/gpu/drm/panel/panel-mantix-mlaf057we51.c +++ b/drivers/gpu/drm/panel/panel-mantix-mlaf057we51.c @@ -10,7 +10,7 @@ #include <linux/gpio/consumer.h> #include <linux/media-bus-format.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/regulator/consumer.h> #include <video/mipi_display.h> diff --git a/drivers/gpu/drm/panel/panel-newvision-nv3051d.c b/drivers/gpu/drm/panel/panel-newvision-nv3051d.c index a07958038ffd..ad98dd9322b4 100644 --- a/drivers/gpu/drm/panel/panel-newvision-nv3051d.c +++ b/drivers/gpu/drm/panel/panel-newvision-nv3051d.c @@ -13,7 +13,7 @@ #include <linux/gpio/consumer.h> #include <linux/media-bus-format.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/regulator/consumer.h> #include <video/display_timing.h> diff --git a/drivers/gpu/drm/panel/panel-newvision-nv3052c.c b/drivers/gpu/drm/panel/panel-newvision-nv3052c.c index cf078f0d3cd3..71e57de6d8b2 100644 --- a/drivers/gpu/drm/panel/panel-newvision-nv3052c.c +++ b/drivers/gpu/drm/panel/panel-newvision-nv3052c.c @@ -11,7 +11,8 @@ #include <linux/gpio/consumer.h> #include <linux/media-bus-format.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> +#include <linux/platform_device.h> #include <linux/regulator/consumer.h> #include <linux/spi/spi.h> #include <video/mipi_display.h> diff --git a/drivers/gpu/drm/panel/panel-novatek-nt35510.c b/drivers/gpu/drm/panel/panel-novatek-nt35510.c index 493c3c23f0d6..d6dceb858008 100644 --- a/drivers/gpu/drm/panel/panel-novatek-nt35510.c +++ b/drivers/gpu/drm/panel/panel-novatek-nt35510.c @@ -26,7 +26,7 @@ #include <linux/bitops.h> #include <linux/gpio/consumer.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> diff --git a/drivers/gpu/drm/panel/panel-novatek-nt35560.c b/drivers/gpu/drm/panel/panel-novatek-nt35560.c index cc7f96d70826..5bbea734123b 100644 --- a/drivers/gpu/drm/panel/panel-novatek-nt35560.c +++ b/drivers/gpu/drm/panel/panel-novatek-nt35560.c @@ -18,7 +18,6 @@ #include <linux/gpio/consumer.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/regulator/consumer.h> #include <video/mipi_display.h> diff --git a/drivers/gpu/drm/panel/panel-novatek-nt35950.c b/drivers/gpu/drm/panel/panel-novatek-nt35950.c index 8b108ac80b55..412ca84d0581 100644 --- a/drivers/gpu/drm/panel/panel-novatek-nt35950.c +++ b/drivers/gpu/drm/panel/panel-novatek-nt35950.c @@ -8,7 +8,7 @@ #include <linux/delay.h> #include <linux/gpio/consumer.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/of_graph.h> #include <linux/regulator/consumer.h> diff --git a/drivers/gpu/drm/panel/panel-novatek-nt36523.c b/drivers/gpu/drm/panel/panel-novatek-nt36523.c index d30dbbfb67b1..9632b9e95b71 100644 --- a/drivers/gpu/drm/panel/panel-novatek-nt36523.c +++ b/drivers/gpu/drm/panel/panel-novatek-nt36523.c @@ -5,13 +5,16 @@ * Copyright (c) 2022, 2023 Jianhua Lu <[email protected]> */ +#include <linux/backlight.h> #include <linux/delay.h> #include <linux/gpio/consumer.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/of_graph.h> #include <linux/regulator/consumer.h> +#include <video/mipi_display.h> + #include <drm/drm_connector.h> #include <drm/drm_crtc.h> #include <drm/drm_mipi_dsi.h> @@ -30,6 +33,7 @@ struct panel_info { struct drm_panel panel; struct mipi_dsi_device *dsi[2]; const struct panel_desc *desc; + enum drm_panel_orientation orientation; struct gpio_desc *reset_gpio; struct backlight_device *backlight; @@ -53,6 +57,7 @@ struct panel_desc { int (*init_sequence)(struct panel_info *pinfo); bool is_dual_dsi; + bool has_dcs_backlight; }; static inline struct panel_info *to_panel_info(struct drm_panel *panel) @@ -478,6 +483,456 @@ static int elish_csot_init_sequence(struct panel_info *pinfo) return 0; } +static int j606f_boe_init_sequence(struct panel_info *pinfo) +{ + struct mipi_dsi_device *dsi = pinfo->dsi[0]; + struct device *dev = &dsi->dev; + int ret; + + mipi_dsi_dcs_write_seq(dsi, 0xff, 0x20); + mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0x05, 0xd9); + mipi_dsi_dcs_write_seq(dsi, 0x07, 0x78); + mipi_dsi_dcs_write_seq(dsi, 0x08, 0x5a); + mipi_dsi_dcs_write_seq(dsi, 0x0d, 0x63); + mipi_dsi_dcs_write_seq(dsi, 0x0e, 0x91); + mipi_dsi_dcs_write_seq(dsi, 0x0f, 0x73); + mipi_dsi_dcs_write_seq(dsi, 0x95, 0xeb); + mipi_dsi_dcs_write_seq(dsi, 0x96, 0xeb); + mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_PARTIAL_ROWS, 0x11); + mipi_dsi_dcs_write_seq(dsi, 0x6d, 0x66); + mipi_dsi_dcs_write_seq(dsi, 0x75, 0xa2); + mipi_dsi_dcs_write_seq(dsi, 0x77, 0xb3); + mipi_dsi_dcs_write_seq(dsi, 0xb0, 0x00, 0x08, 0x00, 0x23, 0x00, 0x4d, 0x00, 0x6d, 0x00, + 0x89, 0x00, 0xa1, 0x00, 0xb6, 0x00, 0xc9); + mipi_dsi_dcs_write_seq(dsi, 0xb1, 0x00, 0xda, 0x01, 0x13, 0x01, 0x3c, 0x01, 0x7e, 0x01, + 0xab, 0x01, 0xf7, 0x02, 0x2f, 0x02, 0x31); + mipi_dsi_dcs_write_seq(dsi, 0xb2, 0x02, 0x67, 0x02, 0xa6, 0x02, 0xd1, 0x03, 0x08, 0x03, + 0x2e, 0x03, 0x5b, 0x03, 0x6b, 0x03, 0x7b); + mipi_dsi_dcs_write_seq(dsi, 0xb3, 0x03, 0x8e, 0x03, 0xa2, 0x03, 0xb7, 0x03, 0xe7, 0x03, + 0xfd, 0x03, 0xff); + mipi_dsi_dcs_write_seq(dsi, 0xb4, 0x00, 0x08, 0x00, 0x23, 0x00, 0x4d, 0x00, 0x6d, 0x00, + 0x89, 0x00, 0xa1, 0x00, 0xb6, 0x00, 0xc9); + mipi_dsi_dcs_write_seq(dsi, 0xb5, 0x00, 0xda, 0x01, 0x13, 0x01, 0x3c, 0x01, 0x7e, 0x01, + 0xab, 0x01, 0xf7, 0x02, 0x2f, 0x02, 0x31); + mipi_dsi_dcs_write_seq(dsi, 0xb6, 0x02, 0x67, 0x02, 0xa6, 0x02, 0xd1, 0x03, 0x08, 0x03, + 0x2e, 0x03, 0x5b, 0x03, 0x6b, 0x03, 0x7b); + mipi_dsi_dcs_write_seq(dsi, 0xb7, 0x03, 0x8e, 0x03, 0xa2, 0x03, 0xb7, 0x03, 0xe7, 0x03, + 0xfd, 0x03, 0xff); + mipi_dsi_dcs_write_seq(dsi, 0xb8, 0x00, 0x08, 0x00, 0x23, 0x00, 0x4d, 0x00, 0x6d, 0x00, + 0x89, 0x00, 0xa1, 0x00, 0xb6, 0x00, 0xc9); + mipi_dsi_dcs_write_seq(dsi, 0xb9, 0x00, 0xda, 0x01, 0x13, 0x01, 0x3c, 0x01, 0x7e, 0x01, + 0xab, 0x01, 0xf7, 0x02, 0x2f, 0x02, 0x31); + mipi_dsi_dcs_write_seq(dsi, 0xba, 0x02, 0x67, 0x02, 0xa6, 0x02, 0xd1, 0x03, 0x08, 0x03, + 0x2e, 0x03, 0x5b, 0x03, 0x6b, 0x03, 0x7b); + mipi_dsi_dcs_write_seq(dsi, 0xbb, 0x03, 0x8e, 0x03, 0xa2, 0x03, 0xb7, 0x03, 0xe7, 0x03, + 0xfd, 0x03, 0xff); + mipi_dsi_dcs_write_seq(dsi, 0xff, 0x21); + mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0xb0, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x45, 0x00, 0x65, 0x00, + 0x81, 0x00, 0x99, 0x00, 0xae, 0x00, 0xc1); + mipi_dsi_dcs_write_seq(dsi, 0xb1, 0x00, 0xd2, 0x01, 0x0b, 0x01, 0x34, 0x01, 0x76, 0x01, + 0xa3, 0x01, 0xef, 0x02, 0x27, 0x02, 0x29); + mipi_dsi_dcs_write_seq(dsi, 0xb2, 0x02, 0x5f, 0x02, 0x9e, 0x02, 0xc9, 0x03, 0x00, 0x03, + 0x26, 0x03, 0x53, 0x03, 0x63, 0x03, 0x73); + mipi_dsi_dcs_write_seq(dsi, 0xb3, 0x03, 0x86, 0x03, 0x9a, 0x03, 0xaf, 0x03, 0xdf, 0x03, + 0xf5, 0x03, 0xf7); + mipi_dsi_dcs_write_seq(dsi, 0xb4, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x45, 0x00, 0x65, 0x00, + 0x81, 0x00, 0x99, 0x00, 0xae, 0x00, 0xc1); + mipi_dsi_dcs_write_seq(dsi, 0xb5, 0x00, 0xd2, 0x01, 0x0b, 0x01, 0x34, 0x01, 0x76, 0x01, + 0xa3, 0x01, 0xef, 0x02, 0x27, 0x02, 0x29); + mipi_dsi_dcs_write_seq(dsi, 0xb6, 0x02, 0x5f, 0x02, 0x9e, 0x02, 0xc9, 0x03, 0x00, 0x03, + 0x26, 0x03, 0x53, 0x03, 0x63, 0x03, 0x73); + mipi_dsi_dcs_write_seq(dsi, 0xb7, 0x03, 0x86, 0x03, 0x9a, 0x03, 0xaf, 0x03, 0xdf, 0x03, + 0xf5, 0x03, 0xf7); + mipi_dsi_dcs_write_seq(dsi, 0xb8, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x45, 0x00, 0x65, 0x00, + 0x81, 0x00, 0x99, 0x00, 0xae, 0x00, 0xc1); + mipi_dsi_dcs_write_seq(dsi, 0xb9, 0x00, 0xd2, 0x01, 0x0b, 0x01, 0x34, 0x01, 0x76, 0x01, + 0xa3, 0x01, 0xef, 0x02, 0x27, 0x02, 0x29); + mipi_dsi_dcs_write_seq(dsi, 0xba, 0x02, 0x5f, 0x02, 0x9e, 0x02, 0xc9, 0x03, 0x00, 0x03, + 0x26, 0x03, 0x53, 0x03, 0x63, 0x03, 0x73); + mipi_dsi_dcs_write_seq(dsi, 0xbb, 0x03, 0x86, 0x03, 0x9a, 0x03, 0xaf, 0x03, 0xdf, 0x03, + 0xf5, 0x03, 0xf7); + mipi_dsi_dcs_write_seq(dsi, 0xff, 0x23); + mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0x00, 0x80); + mipi_dsi_dcs_write_seq(dsi, 0x07, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x11, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0x12, 0x77); + mipi_dsi_dcs_write_seq(dsi, 0x15, 0x07); + mipi_dsi_dcs_write_seq(dsi, 0x16, 0x07); + mipi_dsi_dcs_write_seq(dsi, 0xff, 0x24); + mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0x00, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x01, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x02, 0x1c); + mipi_dsi_dcs_write_seq(dsi, 0x03, 0x1c); + mipi_dsi_dcs_write_seq(dsi, 0x04, 0x1d); + mipi_dsi_dcs_write_seq(dsi, 0x05, 0x1d); + mipi_dsi_dcs_write_seq(dsi, 0x06, 0x04); + mipi_dsi_dcs_write_seq(dsi, 0x07, 0x04); + mipi_dsi_dcs_write_seq(dsi, 0x08, 0x0f); + mipi_dsi_dcs_write_seq(dsi, 0x09, 0x0f); + mipi_dsi_dcs_write_seq(dsi, 0x0a, 0x0e); + mipi_dsi_dcs_write_seq(dsi, 0x0b, 0x0e); + mipi_dsi_dcs_write_seq(dsi, 0x0c, 0x0d); + mipi_dsi_dcs_write_seq(dsi, 0x0d, 0x0d); + mipi_dsi_dcs_write_seq(dsi, 0x0e, 0x0c); + mipi_dsi_dcs_write_seq(dsi, 0x0f, 0x0c); + mipi_dsi_dcs_write_seq(dsi, 0x10, 0x08); + mipi_dsi_dcs_write_seq(dsi, 0x11, 0x08); + mipi_dsi_dcs_write_seq(dsi, 0x12, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x13, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x14, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x15, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x16, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x17, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x18, 0x1c); + mipi_dsi_dcs_write_seq(dsi, 0x19, 0x1c); + mipi_dsi_dcs_write_seq(dsi, 0x1a, 0x1d); + mipi_dsi_dcs_write_seq(dsi, 0x1b, 0x1d); + mipi_dsi_dcs_write_seq(dsi, 0x1c, 0x04); + mipi_dsi_dcs_write_seq(dsi, 0x1d, 0x04); + mipi_dsi_dcs_write_seq(dsi, 0x1e, 0x0f); + mipi_dsi_dcs_write_seq(dsi, 0x1f, 0x0f); + mipi_dsi_dcs_write_seq(dsi, 0x20, 0x0e); + mipi_dsi_dcs_write_seq(dsi, 0x21, 0x0e); + mipi_dsi_dcs_write_seq(dsi, 0x22, 0x0d); + mipi_dsi_dcs_write_seq(dsi, 0x23, 0x0d); + mipi_dsi_dcs_write_seq(dsi, 0x24, 0x0c); + mipi_dsi_dcs_write_seq(dsi, 0x25, 0x0c); + mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_GAMMA_CURVE, 0x08); + mipi_dsi_dcs_write_seq(dsi, 0x27, 0x08); + mipi_dsi_dcs_write_seq(dsi, 0x28, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x29, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x2a, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x2b, 0x00); + mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_LUT, 0x20); + mipi_dsi_dcs_write_seq(dsi, 0x2f, 0x0a); + mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_PARTIAL_ROWS, 0x44); + mipi_dsi_dcs_write_seq(dsi, 0x33, 0x0c); + mipi_dsi_dcs_write_seq(dsi, 0x34, 0x32); + mipi_dsi_dcs_write_seq(dsi, 0x37, 0x44); + mipi_dsi_dcs_write_seq(dsi, 0x38, 0x40); + mipi_dsi_dcs_write_seq(dsi, 0x39, 0x00); + + ret = mipi_dsi_dcs_set_pixel_format(dsi, 0x9a); + if (ret < 0) { + dev_err(dev, "Failed to set pixel format: %d\n", ret); + return ret; + } + + mipi_dsi_dcs_write_seq(dsi, 0x3b, 0xa0); + mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_3D_CONTROL, 0x42); + mipi_dsi_dcs_write_seq(dsi, 0x3f, 0x06); + mipi_dsi_dcs_write_seq(dsi, 0x43, 0x06); + mipi_dsi_dcs_write_seq(dsi, 0x47, 0x66); + mipi_dsi_dcs_write_seq(dsi, 0x4a, 0x9a); + mipi_dsi_dcs_write_seq(dsi, 0x4b, 0xa0); + mipi_dsi_dcs_write_seq(dsi, 0x4c, 0x91); + mipi_dsi_dcs_write_seq(dsi, 0x4d, 0x21); + mipi_dsi_dcs_write_seq(dsi, 0x4e, 0x43); + + ret = mipi_dsi_dcs_set_display_brightness(dsi, 18); + if (ret < 0) { + dev_err(dev, "Failed to set display brightness: %d\n", ret); + return ret; + } + + mipi_dsi_dcs_write_seq(dsi, 0x52, 0x34); + mipi_dsi_dcs_write_seq(dsi, 0x55, 0x82, 0x02); + mipi_dsi_dcs_write_seq(dsi, 0x56, 0x04); + mipi_dsi_dcs_write_seq(dsi, 0x58, 0x21); + mipi_dsi_dcs_write_seq(dsi, 0x59, 0x30); + mipi_dsi_dcs_write_seq(dsi, 0x5a, 0xba); + mipi_dsi_dcs_write_seq(dsi, 0x5b, 0xa0); + mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_CABC_MIN_BRIGHTNESS, 0x00, 0x06); + mipi_dsi_dcs_write_seq(dsi, 0x5f, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x65, 0x82); + mipi_dsi_dcs_write_seq(dsi, 0x7e, 0x20); + mipi_dsi_dcs_write_seq(dsi, 0x7f, 0x3c); + mipi_dsi_dcs_write_seq(dsi, 0x82, 0x04); + mipi_dsi_dcs_write_seq(dsi, 0x97, 0xc0); + mipi_dsi_dcs_write_seq(dsi, 0xb6, + 0x05, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, + 0x05, 0x00, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x92, 0xc4); + mipi_dsi_dcs_write_seq(dsi, 0x93, 0x1a); + mipi_dsi_dcs_write_seq(dsi, 0x94, 0x5f); + mipi_dsi_dcs_write_seq(dsi, 0xd7, 0x55); + mipi_dsi_dcs_write_seq(dsi, 0xda, 0x0a); + mipi_dsi_dcs_write_seq(dsi, 0xde, 0x08); + mipi_dsi_dcs_write_seq(dsi, 0xdb, 0x05); + mipi_dsi_dcs_write_seq(dsi, 0xdc, 0xc4); + mipi_dsi_dcs_write_seq(dsi, 0xdd, 0x22); + mipi_dsi_dcs_write_seq(dsi, 0xdf, 0x05); + mipi_dsi_dcs_write_seq(dsi, 0xe0, 0xc4); + mipi_dsi_dcs_write_seq(dsi, 0xe1, 0x05); + mipi_dsi_dcs_write_seq(dsi, 0xe2, 0xc4); + mipi_dsi_dcs_write_seq(dsi, 0xe3, 0x05); + mipi_dsi_dcs_write_seq(dsi, 0xe4, 0xc4); + mipi_dsi_dcs_write_seq(dsi, 0xe5, 0x05); + mipi_dsi_dcs_write_seq(dsi, 0xe6, 0xc4); + mipi_dsi_dcs_write_seq(dsi, 0x5c, 0x88); + mipi_dsi_dcs_write_seq(dsi, 0x5d, 0x08); + mipi_dsi_dcs_write_seq(dsi, 0x8d, 0x88); + mipi_dsi_dcs_write_seq(dsi, 0x8e, 0x08); + mipi_dsi_dcs_write_seq(dsi, 0xb5, 0x90); + mipi_dsi_dcs_write_seq(dsi, 0xff, 0x25); + mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0x05, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x19, 0x07); + mipi_dsi_dcs_write_seq(dsi, 0x1f, 0xba); + mipi_dsi_dcs_write_seq(dsi, 0x20, 0xa0); + mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_GAMMA_CURVE, 0xba); + mipi_dsi_dcs_write_seq(dsi, 0x27, 0xa0); + mipi_dsi_dcs_write_seq(dsi, 0x33, 0xba); + mipi_dsi_dcs_write_seq(dsi, 0x34, 0xa0); + mipi_dsi_dcs_write_seq(dsi, 0x3f, 0xe0); + mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_VSYNC_TIMING, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x44, 0x00); + mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_GET_SCANLINE, 0x40); + mipi_dsi_dcs_write_seq(dsi, 0x48, 0xba); + mipi_dsi_dcs_write_seq(dsi, 0x49, 0xa0); + mipi_dsi_dcs_write_seq(dsi, 0x5b, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x5c, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x5d, 0x00); + mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_CABC_MIN_BRIGHTNESS, 0xd0); + mipi_dsi_dcs_write_seq(dsi, 0x61, 0xba); + mipi_dsi_dcs_write_seq(dsi, 0x62, 0xa0); + mipi_dsi_dcs_write_seq(dsi, 0xf1, 0x10); + mipi_dsi_dcs_write_seq(dsi, 0xff, 0x2a); + mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0x64, 0x16); + mipi_dsi_dcs_write_seq(dsi, 0x67, 0x16); + mipi_dsi_dcs_write_seq(dsi, 0x6a, 0x16); + mipi_dsi_dcs_write_seq(dsi, 0x70, 0x30); + mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_READ_PPS_START, 0xf3); + mipi_dsi_dcs_write_seq(dsi, 0xa3, 0xff); + mipi_dsi_dcs_write_seq(dsi, 0xa4, 0xff); + mipi_dsi_dcs_write_seq(dsi, 0xa5, 0xff); + mipi_dsi_dcs_write_seq(dsi, 0xd6, 0x08); + mipi_dsi_dcs_write_seq(dsi, 0xff, 0x26); + mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0x00, 0xa1); + mipi_dsi_dcs_write_seq(dsi, 0x0a, 0xf2); + mipi_dsi_dcs_write_seq(dsi, 0x04, 0x28); + mipi_dsi_dcs_write_seq(dsi, 0x06, 0x30); + mipi_dsi_dcs_write_seq(dsi, 0x0c, 0x13); + mipi_dsi_dcs_write_seq(dsi, 0x0d, 0x0a); + mipi_dsi_dcs_write_seq(dsi, 0x0f, 0x0a); + mipi_dsi_dcs_write_seq(dsi, 0x11, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x12, 0x50); + mipi_dsi_dcs_write_seq(dsi, 0x13, 0x51); + mipi_dsi_dcs_write_seq(dsi, 0x14, 0x65); + mipi_dsi_dcs_write_seq(dsi, 0x15, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x16, 0x10); + mipi_dsi_dcs_write_seq(dsi, 0x17, 0xa0); + mipi_dsi_dcs_write_seq(dsi, 0x18, 0x86); + mipi_dsi_dcs_write_seq(dsi, 0x19, 0x11); + mipi_dsi_dcs_write_seq(dsi, 0x1a, 0x7b); + mipi_dsi_dcs_write_seq(dsi, 0x1b, 0x10); + mipi_dsi_dcs_write_seq(dsi, 0x1c, 0xbb); + mipi_dsi_dcs_write_seq(dsi, 0x22, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x23, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x2a, 0x11); + mipi_dsi_dcs_write_seq(dsi, 0x2b, 0x7b); + mipi_dsi_dcs_write_seq(dsi, 0x1d, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x1e, 0xc3); + mipi_dsi_dcs_write_seq(dsi, 0x1f, 0xc3); + mipi_dsi_dcs_write_seq(dsi, 0x24, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x25, 0xc3); + mipi_dsi_dcs_write_seq(dsi, 0x2f, 0x05); + mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_PARTIAL_ROWS, 0xc3); + mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_PARTIAL_COLUMNS, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x32, 0xc3); + mipi_dsi_dcs_write_seq(dsi, 0x39, 0x00); + + ret = mipi_dsi_dcs_set_pixel_format(dsi, 0xc3); + if (ret < 0) { + dev_err(dev, "Failed to set pixel format: %d\n", ret); + return ret; + } + + mipi_dsi_dcs_write_seq(dsi, 0x20, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0x33, 0x11); + mipi_dsi_dcs_write_seq(dsi, 0x34, 0x78); + mipi_dsi_dcs_write_seq(dsi, 0x35, 0x16); + mipi_dsi_dcs_write_seq(dsi, 0xc8, 0x04); + mipi_dsi_dcs_write_seq(dsi, 0xc9, 0x82); + mipi_dsi_dcs_write_seq(dsi, 0xca, 0x4e); + mipi_dsi_dcs_write_seq(dsi, 0xcb, 0x00); + mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_READ_PPS_CONTINUE, 0x4c); + mipi_dsi_dcs_write_seq(dsi, 0xaa, 0x47); + mipi_dsi_dcs_write_seq(dsi, 0xff, 0x27); + mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0x56, 0x06); + mipi_dsi_dcs_write_seq(dsi, 0x58, 0x80); + mipi_dsi_dcs_write_seq(dsi, 0x59, 0x53); + mipi_dsi_dcs_write_seq(dsi, 0x5a, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x5b, 0x14); + mipi_dsi_dcs_write_seq(dsi, 0x5c, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x5d, 0x01); + mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_CABC_MIN_BRIGHTNESS, 0x20); + mipi_dsi_dcs_write_seq(dsi, 0x5f, 0x10); + mipi_dsi_dcs_write_seq(dsi, 0x60, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x61, 0x1d); + mipi_dsi_dcs_write_seq(dsi, 0x62, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x63, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0x64, 0x24); + mipi_dsi_dcs_write_seq(dsi, 0x65, 0x1c); + mipi_dsi_dcs_write_seq(dsi, 0x66, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x67, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0x68, 0x25); + mipi_dsi_dcs_write_seq(dsi, 0x00, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x78, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0xc3, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0xd1, 0x24); + mipi_dsi_dcs_write_seq(dsi, 0xd2, 0x30); + mipi_dsi_dcs_write_seq(dsi, 0xff, 0x2a); + mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0x22, 0x2f); + mipi_dsi_dcs_write_seq(dsi, 0x23, 0x08); + mipi_dsi_dcs_write_seq(dsi, 0x24, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x25, 0xc3); + mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_GAMMA_CURVE, 0xf8); + mipi_dsi_dcs_write_seq(dsi, 0x27, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x28, 0x1a); + mipi_dsi_dcs_write_seq(dsi, 0x29, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x2a, 0x1a); + mipi_dsi_dcs_write_seq(dsi, 0x2b, 0x00); + mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_LUT, 0x1a); + mipi_dsi_dcs_write_seq(dsi, 0xff, 0xe0); + mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0x14, 0x60); + mipi_dsi_dcs_write_seq(dsi, 0x16, 0xc0); + mipi_dsi_dcs_write_seq(dsi, 0xff, 0xf0); + mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01); + + ret = mipi_dsi_dcs_set_pixel_format(dsi, 0x08); + if (ret < 0) { + dev_err(dev, "Failed to set pixel format: %d\n", ret); + return ret; + } + + mipi_dsi_dcs_write_seq(dsi, 0xff, 0x24); + mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01); + + ret = mipi_dsi_dcs_set_pixel_format(dsi, 0x5d); + if (ret < 0) { + dev_err(dev, "Failed to set pixel format: %d\n", ret); + return ret; + } + + mipi_dsi_dcs_write_seq(dsi, 0x3b, 0x60); + mipi_dsi_dcs_write_seq(dsi, 0x4a, 0x5d); + mipi_dsi_dcs_write_seq(dsi, 0x4b, 0x60); + mipi_dsi_dcs_write_seq(dsi, 0x5a, 0x70); + mipi_dsi_dcs_write_seq(dsi, 0x5b, 0x60); + mipi_dsi_dcs_write_seq(dsi, 0x91, 0x44); + mipi_dsi_dcs_write_seq(dsi, 0x92, 0x75); + mipi_dsi_dcs_write_seq(dsi, 0xdb, 0x05); + mipi_dsi_dcs_write_seq(dsi, 0xdc, 0x75); + mipi_dsi_dcs_write_seq(dsi, 0xdd, 0x22); + mipi_dsi_dcs_write_seq(dsi, 0xdf, 0x05); + mipi_dsi_dcs_write_seq(dsi, 0xe0, 0x75); + mipi_dsi_dcs_write_seq(dsi, 0xe1, 0x05); + mipi_dsi_dcs_write_seq(dsi, 0xe2, 0x75); + mipi_dsi_dcs_write_seq(dsi, 0xe3, 0x05); + mipi_dsi_dcs_write_seq(dsi, 0xe4, 0x75); + mipi_dsi_dcs_write_seq(dsi, 0xe5, 0x05); + mipi_dsi_dcs_write_seq(dsi, 0xe6, 0x75); + mipi_dsi_dcs_write_seq(dsi, 0x5c, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x5d, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x8d, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x8e, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0xff, 0x25); + mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0x1f, 0x70); + mipi_dsi_dcs_write_seq(dsi, 0x20, 0x60); + mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_GAMMA_CURVE, 0x70); + mipi_dsi_dcs_write_seq(dsi, 0x27, 0x60); + mipi_dsi_dcs_write_seq(dsi, 0x33, 0x70); + mipi_dsi_dcs_write_seq(dsi, 0x34, 0x60); + mipi_dsi_dcs_write_seq(dsi, 0x48, 0x70); + mipi_dsi_dcs_write_seq(dsi, 0x49, 0x60); + mipi_dsi_dcs_write_seq(dsi, 0x5b, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x61, 0x70); + mipi_dsi_dcs_write_seq(dsi, 0x62, 0x60); + mipi_dsi_dcs_write_seq(dsi, 0xff, 0x26); + mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0x02, 0x31); + mipi_dsi_dcs_write_seq(dsi, 0x19, 0x0a); + mipi_dsi_dcs_write_seq(dsi, 0x1a, 0x7f); + mipi_dsi_dcs_write_seq(dsi, 0x1b, 0x0a); + mipi_dsi_dcs_write_seq(dsi, 0x1c, 0x0c); + mipi_dsi_dcs_write_seq(dsi, 0x2a, 0x0a); + mipi_dsi_dcs_write_seq(dsi, 0x2b, 0x7f); + mipi_dsi_dcs_write_seq(dsi, 0x1e, 0x75); + mipi_dsi_dcs_write_seq(dsi, 0x1f, 0x75); + mipi_dsi_dcs_write_seq(dsi, 0x25, 0x75); + mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_PARTIAL_ROWS, 0x75); + mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_PARTIAL_COLUMNS, 0x05); + mipi_dsi_dcs_write_seq(dsi, 0x32, 0x8d); + + ret = mipi_dsi_dcs_set_pixel_format(dsi, 0x75); + if (ret < 0) { + dev_err(dev, "Failed to set pixel format: %d\n", ret); + return ret; + } + + mipi_dsi_dcs_write_seq(dsi, 0xff, 0x2a); + mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0x25, 0x75); + mipi_dsi_dcs_write_seq(dsi, 0xff, 0x10); + mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0xb9, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0xff, 0x20); + mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0x18, 0x40); + mipi_dsi_dcs_write_seq(dsi, 0xff, 0x10); + mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0xb9, 0x02); + + ret = mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK); + if (ret < 0) { + dev_err(dev, "Failed to set tear on: %d\n", ret); + return ret; + } + + mipi_dsi_dcs_write_seq(dsi, 0xbb, 0x13); + mipi_dsi_dcs_write_seq(dsi, 0x3b, 0x03, 0x5f, 0x1a, 0x04, 0x04); + mipi_dsi_dcs_write_seq(dsi, 0xff, 0x10); + usleep_range(10000, 11000); + mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01); + + ret = mipi_dsi_dcs_set_display_brightness(dsi, 0); + if (ret < 0) { + dev_err(dev, "Failed to set display brightness: %d\n", ret); + return ret; + } + + mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x2c); + mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_POWER_SAVE, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0x68, 0x05, 0x01); + + ret = mipi_dsi_dcs_exit_sleep_mode(dsi); + if (ret < 0) { + dev_err(dev, "Failed to exit sleep mode: %d\n", ret); + return ret; + } + msleep(100); + + ret = mipi_dsi_dcs_set_display_on(dsi); + if (ret < 0) { + dev_err(dev, "Failed to set display on: %d\n", ret); + return ret; + } + msleep(30); + + return 0; +} + static const struct drm_display_mode elish_boe_modes[] = { { /* There is only one 120 Hz timing, but it doesn't work perfectly, 104 Hz preferred */ @@ -508,6 +963,22 @@ static const struct drm_display_mode elish_csot_modes[] = { }, }; +static const struct drm_display_mode j606f_boe_modes[] = { + { + .clock = (1200 + 58 + 2 + 60) * (2000 + 26 + 2 + 93) * 60 / 1000, + .hdisplay = 1200, + .hsync_start = 1200 + 58, + .hsync_end = 1200 + 58 + 2, + .htotal = 1200 + 58 + 2 + 60, + .vdisplay = 2000, + .vsync_start = 2000 + 26, + .vsync_end = 2000 + 26 + 2, + .vtotal = 2000 + 26 + 2 + 93, + .width_mm = 143, + .height_mm = 235, + }, +}; + static const struct panel_desc elish_boe_desc = { .modes = elish_boe_modes, .num_modes = ARRAY_SIZE(elish_boe_modes), @@ -544,6 +1015,20 @@ static const struct panel_desc elish_csot_desc = { .is_dual_dsi = true, }; +static const struct panel_desc j606f_boe_desc = { + .modes = j606f_boe_modes, + .num_modes = ARRAY_SIZE(j606f_boe_modes), + .width_mm = 143, + .height_mm = 235, + .bpc = 8, + .lanes = 4, + .format = MIPI_DSI_FMT_RGB888, + .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | + MIPI_DSI_CLOCK_NON_CONTINUOUS | MIPI_DSI_MODE_LPM, + .init_sequence = j606f_boe_init_sequence, + .has_dcs_backlight = true, +}; + static void nt36523_reset(struct panel_info *pinfo) { gpiod_set_value_cansleep(pinfo->reset_gpio, 1); @@ -672,13 +1157,74 @@ static int nt36523_get_modes(struct drm_panel *panel, return pinfo->desc->num_modes; } +static enum drm_panel_orientation nt36523_get_orientation(struct drm_panel *panel) +{ + struct panel_info *pinfo = to_panel_info(panel); + + return pinfo->orientation; +} + static const struct drm_panel_funcs nt36523_panel_funcs = { .disable = nt36523_disable, .prepare = nt36523_prepare, .unprepare = nt36523_unprepare, .get_modes = nt36523_get_modes, + .get_orientation = nt36523_get_orientation, }; +static int nt36523_bl_update_status(struct backlight_device *bl) +{ + struct mipi_dsi_device *dsi = bl_get_data(bl); + u16 brightness = backlight_get_brightness(bl); + int ret; + + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + + ret = mipi_dsi_dcs_set_display_brightness_large(dsi, brightness); + if (ret < 0) + return ret; + + dsi->mode_flags |= MIPI_DSI_MODE_LPM; + + return 0; +} + +static int nt36523_bl_get_brightness(struct backlight_device *bl) +{ + struct mipi_dsi_device *dsi = bl_get_data(bl); + u16 brightness; + int ret; + + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + + ret = mipi_dsi_dcs_get_display_brightness_large(dsi, &brightness); + if (ret < 0) + return ret; + + dsi->mode_flags |= MIPI_DSI_MODE_LPM; + + return brightness; +} + +static const struct backlight_ops nt36523_bl_ops = { + .update_status = nt36523_bl_update_status, + .get_brightness = nt36523_bl_get_brightness, +}; + +static struct backlight_device *nt36523_create_backlight(struct mipi_dsi_device *dsi) +{ + struct device *dev = &dsi->dev; + const struct backlight_properties props = { + .type = BACKLIGHT_RAW, + .brightness = 512, + .max_brightness = 4095, + .scale = BACKLIGHT_SCALE_NON_LINEAR, + }; + + return devm_backlight_device_register(dev, dev_name(dev), dev, dsi, + &nt36523_bl_ops, &props); +} + static int nt36523_probe(struct mipi_dsi_device *dsi) { struct device *dev = &dsi->dev; @@ -730,9 +1276,22 @@ static int nt36523_probe(struct mipi_dsi_device *dsi) mipi_dsi_set_drvdata(dsi, pinfo); drm_panel_init(&pinfo->panel, dev, &nt36523_panel_funcs, DRM_MODE_CONNECTOR_DSI); - ret = drm_panel_of_backlight(&pinfo->panel); - if (ret) - return dev_err_probe(dev, ret, "failed to get backlight\n"); + ret = of_drm_get_panel_orientation(dev->of_node, &pinfo->orientation); + if (ret < 0) { + dev_err(dev, "%pOF: failed to get orientation %d\n", dev->of_node, ret); + return ret; + } + + if (pinfo->desc->has_dcs_backlight) { + pinfo->panel.backlight = nt36523_create_backlight(dsi); + if (IS_ERR(pinfo->panel.backlight)) + return dev_err_probe(dev, PTR_ERR(pinfo->panel.backlight), + "Failed to create backlight\n"); + } else { + ret = drm_panel_of_backlight(&pinfo->panel); + if (ret) + return dev_err_probe(dev, ret, "Failed to get backlight\n"); + } drm_panel_add(&pinfo->panel); @@ -751,6 +1310,10 @@ static int nt36523_probe(struct mipi_dsi_device *dsi) static const struct of_device_id nt36523_of_match[] = { { + .compatible = "lenovo,j606f-boe-nt36523w", + .data = &j606f_boe_desc, + }, + { .compatible = "xiaomi,elish-boe-nt36523", .data = &elish_boe_desc, }, diff --git a/drivers/gpu/drm/panel/panel-novatek-nt36672a.c b/drivers/gpu/drm/panel/panel-novatek-nt36672a.c index 73bcffa1e0c1..33fb3d715e54 100644 --- a/drivers/gpu/drm/panel/panel-novatek-nt36672a.c +++ b/drivers/gpu/drm/panel/panel-novatek-nt36672a.c @@ -16,7 +16,6 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/gpio/consumer.h> #include <linux/pinctrl/consumer.h> diff --git a/drivers/gpu/drm/panel/panel-novatek-nt39016.c b/drivers/gpu/drm/panel/panel-novatek-nt39016.c index f58cfb10b58a..059260262b5a 100644 --- a/drivers/gpu/drm/panel/panel-novatek-nt39016.c +++ b/drivers/gpu/drm/panel/panel-novatek-nt39016.c @@ -12,7 +12,6 @@ #include <linux/media-bus-format.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <linux/spi/spi.h> diff --git a/drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c b/drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c index aba556c98300..4819ada69482 100644 --- a/drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c +++ b/drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c @@ -308,7 +308,7 @@ static struct i2c_driver lcd_olinuxino_driver = { .name = "lcd_olinuxino", .of_match_table = lcd_olinuxino_of_ids, }, - .probe_new = lcd_olinuxino_probe, + .probe = lcd_olinuxino_probe, .remove = lcd_olinuxino_remove, }; diff --git a/drivers/gpu/drm/panel/panel-orisetech-ota5601a.c b/drivers/gpu/drm/panel/panel-orisetech-ota5601a.c index e46be5014d42..c415dacf1816 100644 --- a/drivers/gpu/drm/panel/panel-orisetech-ota5601a.c +++ b/drivers/gpu/drm/panel/panel-orisetech-ota5601a.c @@ -12,7 +12,6 @@ #include <linux/media-bus-format.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <linux/spi/spi.h> diff --git a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c index 11d6ca276c1e..4618c892cdd6 100644 --- a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c +++ b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c @@ -47,7 +47,6 @@ #include <linux/media-bus-format.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/of_graph.h> #include <linux/pm.h> @@ -489,7 +488,7 @@ static struct i2c_driver rpi_touchscreen_driver = { .name = "rpi_touchscreen", .of_match_table = rpi_touchscreen_of_ids, }, - .probe_new = rpi_touchscreen_probe, + .probe = rpi_touchscreen_probe, .remove = rpi_touchscreen_remove, }; diff --git a/drivers/gpu/drm/panel/panel-samsung-db7430.c b/drivers/gpu/drm/panel/panel-samsung-db7430.c index 117b26845083..14c6700e37b3 100644 --- a/drivers/gpu/drm/panel/panel-samsung-db7430.c +++ b/drivers/gpu/drm/panel/panel-samsung-db7430.c @@ -56,10 +56,6 @@ struct db7430 { struct mipi_dbi dbi; /** @panel: the DRM panel instance for this device */ struct drm_panel panel; - /** @width: the width of this panel in mm */ - u32 width; - /** @height: the height of this panel in mm */ - u32 height; /** @reset: reset GPIO line */ struct gpio_desc *reset; /** @regulators: VCCIO and VIO supply regulators */ diff --git a/drivers/gpu/drm/panel/panel-samsung-ld9040.c b/drivers/gpu/drm/panel/panel-samsung-ld9040.c index 01eb211f32f7..9f438683a6f6 100644 --- a/drivers/gpu/drm/panel/panel-samsung-ld9040.c +++ b/drivers/gpu/drm/panel/panel-samsung-ld9040.c @@ -8,6 +8,7 @@ * Andrzej Hajda <[email protected]> */ +#include <linux/backlight.h> #include <linux/delay.h> #include <linux/gpio/consumer.h> #include <linux/module.h> @@ -180,15 +181,15 @@ static void ld9040_init(struct ld9040 *ctx) { ld9040_dcs_write_seq_static(ctx, MCS_USER_SETTING, 0x5a, 0x5a); ld9040_dcs_write_seq_static(ctx, MCS_PANEL_CONDITION, - 0x05, 0x65, 0x96, 0x71, 0x7d, 0x19, 0x3b, 0x0d, - 0x19, 0x7e, 0x0d, 0xe2, 0x00, 0x00, 0x7e, 0x7d, - 0x07, 0x07, 0x20, 0x20, 0x20, 0x02, 0x02); + 0x05, 0x5e, 0x96, 0x6b, 0x7d, 0x0d, 0x3f, 0x00, + 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0x05, 0x1f, 0x1f, 0x1f, 0x00, 0x00); ld9040_dcs_write_seq_static(ctx, MCS_DISPCTL, - 0x02, 0x08, 0x08, 0x10, 0x10); + 0x02, 0x06, 0x0a, 0x10, 0x10); ld9040_dcs_write_seq_static(ctx, MCS_MANPWR, 0x04); ld9040_dcs_write_seq_static(ctx, MCS_POWER_CTRL, 0x0a, 0x87, 0x25, 0x6a, 0x44, 0x02, 0x88); - ld9040_dcs_write_seq_static(ctx, MCS_ELVSS_ON, 0x0d, 0x00, 0x16); + ld9040_dcs_write_seq_static(ctx, MCS_ELVSS_ON, 0x0f, 0x00, 0x16); ld9040_dcs_write_seq_static(ctx, MCS_GTCON, 0x09, 0x00, 0x00); ld9040_brightness_set(ctx); ld9040_dcs_write_seq_static(ctx, MIPI_DCS_EXIT_SLEEP_MODE); @@ -310,8 +311,30 @@ static int ld9040_parse_dt(struct ld9040 *ctx) return 0; } +static int ld9040_bl_update_status(struct backlight_device *dev) +{ + struct ld9040 *ctx = bl_get_data(dev); + + ctx->brightness = backlight_get_brightness(dev); + ld9040_brightness_set(ctx); + + return 0; +} + +static const struct backlight_ops ld9040_bl_ops = { + .update_status = ld9040_bl_update_status, +}; + +static const struct backlight_properties ld9040_bl_props = { + .type = BACKLIGHT_RAW, + .scale = BACKLIGHT_SCALE_NON_LINEAR, + .max_brightness = ARRAY_SIZE(ld9040_gammas) - 1, + .brightness = ARRAY_SIZE(ld9040_gammas) - 1, +}; + static int ld9040_probe(struct spi_device *spi) { + struct backlight_device *bldev; struct device *dev = &spi->dev; struct ld9040 *ctx; int ret; @@ -323,7 +346,7 @@ static int ld9040_probe(struct spi_device *spi) spi_set_drvdata(spi, ctx); ctx->dev = dev; - ctx->brightness = ARRAY_SIZE(ld9040_gammas) - 1; + ctx->brightness = ld9040_bl_props.brightness; ret = ld9040_parse_dt(ctx); if (ret < 0) @@ -353,6 +376,12 @@ static int ld9040_probe(struct spi_device *spi) drm_panel_init(&ctx->panel, dev, &ld9040_drm_funcs, DRM_MODE_CONNECTOR_DPI); + bldev = devm_backlight_device_register(dev, dev_name(dev), dev, + ctx, &ld9040_bl_ops, + &ld9040_bl_props); + if (IS_ERR(bldev)) + return PTR_ERR(bldev); + drm_panel_add(&ctx->panel); return 0; diff --git a/drivers/gpu/drm/panel/panel-samsung-s6d16d0.c b/drivers/gpu/drm/panel/panel-samsung-s6d16d0.c index 008e2b0d6652..79f611963c61 100644 --- a/drivers/gpu/drm/panel/panel-samsung-s6d16d0.c +++ b/drivers/gpu/drm/panel/panel-samsung-s6d16d0.c @@ -11,7 +11,7 @@ #include <linux/gpio/consumer.h> #include <linux/regulator/consumer.h> #include <linux/delay.h> -#include <linux/of_device.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> struct s6d16d0 { diff --git a/drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c b/drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c new file mode 100644 index 000000000000..ea5a85779382 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c @@ -0,0 +1,584 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Samsung S6D7AA0 MIPI-DSI TFT LCD controller drm_panel driver. + * + * Copyright (C) 2022 Artur Weber <[email protected]> + */ + +#include <linux/backlight.h> +#include <linux/delay.h> +#include <linux/gpio/consumer.h> +#include <linux/module.h> +#include <linux/regulator/consumer.h> +#include <linux/of.h> + +#include <video/mipi_display.h> +#include <drm/drm_mipi_dsi.h> +#include <drm/drm_modes.h> +#include <drm/drm_panel.h> + +/* Manufacturer command set */ +#define MCS_BL_CTL 0xc3 +#define MCS_OTP_RELOAD 0xd0 +#define MCS_PASSWD1 0xf0 +#define MCS_PASSWD2 0xf1 +#define MCS_PASSWD3 0xfc + +struct s6d7aa0 { + struct drm_panel panel; + struct mipi_dsi_device *dsi; + struct gpio_desc *reset_gpio; + struct regulator_bulk_data supplies[2]; + const struct s6d7aa0_panel_desc *desc; +}; + +struct s6d7aa0_panel_desc { + unsigned int panel_type; + int (*init_func)(struct s6d7aa0 *ctx); + int (*off_func)(struct s6d7aa0 *ctx); + const struct drm_display_mode *drm_mode; + unsigned long mode_flags; + u32 bus_flags; + bool has_backlight; + bool use_passwd3; +}; + +enum s6d7aa0_panels { + S6D7AA0_PANEL_LSL080AL02, + S6D7AA0_PANEL_LSL080AL03, + S6D7AA0_PANEL_LTL101AT01, +}; + +static inline struct s6d7aa0 *panel_to_s6d7aa0(struct drm_panel *panel) +{ + return container_of(panel, struct s6d7aa0, panel); +} + +static void s6d7aa0_reset(struct s6d7aa0 *ctx) +{ + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + msleep(50); + gpiod_set_value_cansleep(ctx->reset_gpio, 0); + msleep(50); +} + +static int s6d7aa0_lock(struct s6d7aa0 *ctx, bool lock) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + + if (lock) { + mipi_dsi_dcs_write_seq(dsi, MCS_PASSWD1, 0xa5, 0xa5); + mipi_dsi_dcs_write_seq(dsi, MCS_PASSWD2, 0xa5, 0xa5); + if (ctx->desc->use_passwd3) + mipi_dsi_dcs_write_seq(dsi, MCS_PASSWD3, 0x5a, 0x5a); + } else { + mipi_dsi_dcs_write_seq(dsi, MCS_PASSWD1, 0x5a, 0x5a); + mipi_dsi_dcs_write_seq(dsi, MCS_PASSWD2, 0x5a, 0x5a); + if (ctx->desc->use_passwd3) + mipi_dsi_dcs_write_seq(dsi, MCS_PASSWD3, 0xa5, 0xa5); + } + + return 0; +} + +static int s6d7aa0_on(struct s6d7aa0 *ctx) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + struct device *dev = &dsi->dev; + int ret; + + ret = ctx->desc->init_func(ctx); + if (ret < 0) { + dev_err(dev, "Failed to initialize panel: %d\n", ret); + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + return ret; + } + + ret = mipi_dsi_dcs_set_display_on(dsi); + if (ret < 0) { + dev_err(dev, "Failed to set display on: %d\n", ret); + return ret; + } + + return 0; +} + +static int s6d7aa0_off(struct s6d7aa0 *ctx) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + struct device *dev = &dsi->dev; + int ret; + + ret = ctx->desc->off_func(ctx); + if (ret < 0) { + dev_err(dev, "Panel-specific off function failed: %d\n", ret); + return ret; + } + + ret = mipi_dsi_dcs_set_display_off(dsi); + if (ret < 0) { + dev_err(dev, "Failed to set display off: %d\n", ret); + return ret; + } + msleep(64); + + ret = mipi_dsi_dcs_enter_sleep_mode(dsi); + if (ret < 0) { + dev_err(dev, "Failed to enter sleep mode: %d\n", ret); + return ret; + } + msleep(120); + + return 0; +} + +static int s6d7aa0_prepare(struct drm_panel *panel) +{ + struct s6d7aa0 *ctx = panel_to_s6d7aa0(panel); + struct device *dev = &ctx->dsi->dev; + int ret; + + ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies); + if (ret < 0) { + dev_err(dev, "Failed to enable regulators: %d\n", ret); + return ret; + } + + s6d7aa0_reset(ctx); + + ret = s6d7aa0_on(ctx); + if (ret < 0) { + dev_err(dev, "Failed to initialize panel: %d\n", ret); + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + return ret; + } + + return 0; +} + +static int s6d7aa0_disable(struct drm_panel *panel) +{ + struct s6d7aa0 *ctx = panel_to_s6d7aa0(panel); + struct device *dev = &ctx->dsi->dev; + int ret; + + ret = s6d7aa0_off(ctx); + if (ret < 0) + dev_err(dev, "Failed to un-initialize panel: %d\n", ret); + + return 0; +} + +static int s6d7aa0_unprepare(struct drm_panel *panel) +{ + struct s6d7aa0 *ctx = panel_to_s6d7aa0(panel); + + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies); + + return 0; +} + +/* Backlight control code */ + +static int s6d7aa0_bl_update_status(struct backlight_device *bl) +{ + struct mipi_dsi_device *dsi = bl_get_data(bl); + u16 brightness = backlight_get_brightness(bl); + int ret; + + ret = mipi_dsi_dcs_set_display_brightness(dsi, brightness); + if (ret < 0) + return ret; + + return 0; +} + +static int s6d7aa0_bl_get_brightness(struct backlight_device *bl) +{ + struct mipi_dsi_device *dsi = bl_get_data(bl); + u16 brightness; + int ret; + + ret = mipi_dsi_dcs_get_display_brightness(dsi, &brightness); + if (ret < 0) + return ret; + + return brightness & 0xff; +} + +static const struct backlight_ops s6d7aa0_bl_ops = { + .update_status = s6d7aa0_bl_update_status, + .get_brightness = s6d7aa0_bl_get_brightness, +}; + +static struct backlight_device * +s6d7aa0_create_backlight(struct mipi_dsi_device *dsi) +{ + struct device *dev = &dsi->dev; + const struct backlight_properties props = { + .type = BACKLIGHT_RAW, + .brightness = 255, + .max_brightness = 255, + }; + + return devm_backlight_device_register(dev, dev_name(dev), dev, dsi, + &s6d7aa0_bl_ops, &props); +} + +/* Initialization code and structures for LSL080AL02 panel */ + +static int s6d7aa0_lsl080al02_init(struct s6d7aa0 *ctx) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + struct device *dev = &dsi->dev; + int ret; + + usleep_range(20000, 25000); + + ret = s6d7aa0_lock(ctx, false); + if (ret < 0) { + dev_err(dev, "Failed to unlock registers: %d\n", ret); + return ret; + } + + mipi_dsi_dcs_write_seq(dsi, MCS_OTP_RELOAD, 0x00, 0x10); + usleep_range(1000, 1500); + + /* SEQ_B6_PARAM_8_R01 */ + mipi_dsi_dcs_write_seq(dsi, 0xb6, 0x10); + + /* BL_CTL_ON */ + mipi_dsi_dcs_write_seq(dsi, MCS_BL_CTL, 0x40, 0x00, 0x28); + + usleep_range(5000, 6000); + + mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_ADDRESS_MODE, 0x04); + + ret = mipi_dsi_dcs_exit_sleep_mode(dsi); + if (ret < 0) { + dev_err(dev, "Failed to exit sleep mode: %d\n", ret); + return ret; + } + + msleep(120); + mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_ADDRESS_MODE, 0x00); + + ret = s6d7aa0_lock(ctx, true); + if (ret < 0) { + dev_err(dev, "Failed to lock registers: %d\n", ret); + return ret; + } + + ret = mipi_dsi_dcs_set_display_on(dsi); + if (ret < 0) { + dev_err(dev, "Failed to set display on: %d\n", ret); + return ret; + } + + return 0; +} + +static int s6d7aa0_lsl080al02_off(struct s6d7aa0 *ctx) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + + /* BL_CTL_OFF */ + mipi_dsi_dcs_write_seq(dsi, MCS_BL_CTL, 0x40, 0x00, 0x20); + + return 0; +} + +static const struct drm_display_mode s6d7aa0_lsl080al02_mode = { + .clock = (800 + 16 + 4 + 140) * (1280 + 8 + 4 + 4) * 60 / 1000, + .hdisplay = 800, + .hsync_start = 800 + 16, + .hsync_end = 800 + 16 + 4, + .htotal = 800 + 16 + 4 + 140, + .vdisplay = 1280, + .vsync_start = 1280 + 8, + .vsync_end = 1280 + 8 + 4, + .vtotal = 1280 + 8 + 4 + 4, + .width_mm = 108, + .height_mm = 173, +}; + +static const struct s6d7aa0_panel_desc s6d7aa0_lsl080al02_desc = { + .panel_type = S6D7AA0_PANEL_LSL080AL02, + .init_func = s6d7aa0_lsl080al02_init, + .off_func = s6d7aa0_lsl080al02_off, + .drm_mode = &s6d7aa0_lsl080al02_mode, + .mode_flags = MIPI_DSI_MODE_VSYNC_FLUSH | MIPI_DSI_MODE_VIDEO_NO_HFP, + .bus_flags = DRM_BUS_FLAG_DE_HIGH, + + .has_backlight = false, + .use_passwd3 = false, +}; + +/* Initialization code and structures for LSL080AL03 panel */ + +static int s6d7aa0_lsl080al03_init(struct s6d7aa0 *ctx) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + struct device *dev = &dsi->dev; + int ret; + + usleep_range(20000, 25000); + + ret = s6d7aa0_lock(ctx, false); + if (ret < 0) { + dev_err(dev, "Failed to unlock registers: %d\n", ret); + return ret; + } + + if (ctx->desc->panel_type == S6D7AA0_PANEL_LSL080AL03) { + mipi_dsi_dcs_write_seq(dsi, MCS_BL_CTL, 0xc7, 0x00, 0x29); + mipi_dsi_dcs_write_seq(dsi, 0xbc, 0x01, 0x4e, 0xa0); + mipi_dsi_dcs_write_seq(dsi, 0xfd, 0x16, 0x10, 0x11, 0x23, + 0x09); + mipi_dsi_dcs_write_seq(dsi, 0xfe, 0x00, 0x02, 0x03, 0x21, + 0x80, 0x78); + } else if (ctx->desc->panel_type == S6D7AA0_PANEL_LTL101AT01) { + mipi_dsi_dcs_write_seq(dsi, MCS_BL_CTL, 0x40, 0x00, 0x08); + mipi_dsi_dcs_write_seq(dsi, 0xbc, 0x01, 0x4e, 0x0b); + mipi_dsi_dcs_write_seq(dsi, 0xfd, 0x16, 0x10, 0x11, 0x23, + 0x09); + mipi_dsi_dcs_write_seq(dsi, 0xfe, 0x00, 0x02, 0x03, 0x21, + 0x80, 0x68); + } + + mipi_dsi_dcs_write_seq(dsi, 0xb3, 0x51); + mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x24); + mipi_dsi_dcs_write_seq(dsi, 0xf2, 0x02, 0x08, 0x08); + + usleep_range(10000, 11000); + + mipi_dsi_dcs_write_seq(dsi, 0xc0, 0x80, 0x80, 0x30); + mipi_dsi_dcs_write_seq(dsi, 0xcd, + 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, + 0x2e, 0x2e, 0x2e, 0x2e, 0x2e); + mipi_dsi_dcs_write_seq(dsi, 0xce, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0xc1, 0x03); + + ret = mipi_dsi_dcs_exit_sleep_mode(dsi); + if (ret < 0) { + dev_err(dev, "Failed to exit sleep mode: %d\n", ret); + return ret; + } + + ret = s6d7aa0_lock(ctx, true); + if (ret < 0) { + dev_err(dev, "Failed to lock registers: %d\n", ret); + return ret; + } + + ret = mipi_dsi_dcs_set_display_on(dsi); + if (ret < 0) { + dev_err(dev, "Failed to set display on: %d\n", ret); + return ret; + } + + return 0; +} + +static int s6d7aa0_lsl080al03_off(struct s6d7aa0 *ctx) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + + mipi_dsi_dcs_write_seq(dsi, 0x22, 0x00); + + return 0; +} + +static const struct drm_display_mode s6d7aa0_lsl080al03_mode = { + .clock = (768 + 18 + 16 + 126) * (1024 + 8 + 2 + 6) * 60 / 1000, + .hdisplay = 768, + .hsync_start = 768 + 18, + .hsync_end = 768 + 18 + 16, + .htotal = 768 + 18 + 16 + 126, + .vdisplay = 1024, + .vsync_start = 1024 + 8, + .vsync_end = 1024 + 8 + 2, + .vtotal = 1024 + 8 + 2 + 6, + .width_mm = 122, + .height_mm = 163, +}; + +static const struct s6d7aa0_panel_desc s6d7aa0_lsl080al03_desc = { + .panel_type = S6D7AA0_PANEL_LSL080AL03, + .init_func = s6d7aa0_lsl080al03_init, + .off_func = s6d7aa0_lsl080al03_off, + .drm_mode = &s6d7aa0_lsl080al03_mode, + .mode_flags = MIPI_DSI_MODE_NO_EOT_PACKET, + .bus_flags = 0, + + .has_backlight = true, + .use_passwd3 = true, +}; + +/* Initialization structures for LTL101AT01 panel */ + +static const struct drm_display_mode s6d7aa0_ltl101at01_mode = { + .clock = (768 + 96 + 16 + 184) * (1024 + 8 + 2 + 6) * 60 / 1000, + .hdisplay = 768, + .hsync_start = 768 + 96, + .hsync_end = 768 + 96 + 16, + .htotal = 768 + 96 + 16 + 184, + .vdisplay = 1024, + .vsync_start = 1024 + 8, + .vsync_end = 1024 + 8 + 2, + .vtotal = 1024 + 8 + 2 + 6, + .width_mm = 148, + .height_mm = 197, +}; + +static const struct s6d7aa0_panel_desc s6d7aa0_ltl101at01_desc = { + .panel_type = S6D7AA0_PANEL_LTL101AT01, + .init_func = s6d7aa0_lsl080al03_init, /* Similar init to LSL080AL03 */ + .off_func = s6d7aa0_lsl080al03_off, + .drm_mode = &s6d7aa0_ltl101at01_mode, + .mode_flags = MIPI_DSI_MODE_NO_EOT_PACKET, + .bus_flags = 0, + + .has_backlight = true, + .use_passwd3 = true, +}; + +static int s6d7aa0_get_modes(struct drm_panel *panel, + struct drm_connector *connector) +{ + struct drm_display_mode *mode; + struct s6d7aa0 *ctx; + + ctx = container_of(panel, struct s6d7aa0, panel); + if (!ctx) + return -EINVAL; + + mode = drm_mode_duplicate(connector->dev, ctx->desc->drm_mode); + if (!mode) + return -ENOMEM; + + drm_mode_set_name(mode); + + mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; + connector->display_info.width_mm = mode->width_mm; + connector->display_info.height_mm = mode->height_mm; + connector->display_info.bus_flags = ctx->desc->bus_flags; + drm_mode_probed_add(connector, mode); + + return 1; +} + +static const struct drm_panel_funcs s6d7aa0_panel_funcs = { + .disable = s6d7aa0_disable, + .prepare = s6d7aa0_prepare, + .unprepare = s6d7aa0_unprepare, + .get_modes = s6d7aa0_get_modes, +}; + +static int s6d7aa0_probe(struct mipi_dsi_device *dsi) +{ + struct device *dev = &dsi->dev; + struct s6d7aa0 *ctx; + int ret; + + ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return -ENOMEM; + + ctx->desc = of_device_get_match_data(dev); + if (!ctx->desc) + return -ENODEV; + + ctx->supplies[0].supply = "power"; + ctx->supplies[1].supply = "vmipi"; + ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->supplies), + ctx->supplies); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to get regulators\n"); + + ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(ctx->reset_gpio)) + return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio), + "Failed to get reset-gpios\n"); + + ctx->dsi = dsi; + mipi_dsi_set_drvdata(dsi, ctx); + + dsi->lanes = 4; + dsi->format = MIPI_DSI_FMT_RGB888; + dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST + | ctx->desc->mode_flags; + + drm_panel_init(&ctx->panel, dev, &s6d7aa0_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + ctx->panel.prepare_prev_first = true; + + ret = drm_panel_of_backlight(&ctx->panel); + if (ret) + return dev_err_probe(dev, ret, "Failed to get backlight\n"); + + /* Use DSI-based backlight as fallback if available */ + if (ctx->desc->has_backlight && !ctx->panel.backlight) { + ctx->panel.backlight = s6d7aa0_create_backlight(dsi); + if (IS_ERR(ctx->panel.backlight)) + return dev_err_probe(dev, PTR_ERR(ctx->panel.backlight), + "Failed to create backlight\n"); + } + + drm_panel_add(&ctx->panel); + + ret = mipi_dsi_attach(dsi); + if (ret < 0) { + dev_err(dev, "Failed to attach to DSI host: %d\n", ret); + drm_panel_remove(&ctx->panel); + return ret; + } + + return 0; +} + +static void s6d7aa0_remove(struct mipi_dsi_device *dsi) +{ + struct s6d7aa0 *ctx = mipi_dsi_get_drvdata(dsi); + int ret; + + ret = mipi_dsi_detach(dsi); + if (ret < 0) + dev_err(&dsi->dev, "Failed to detach from DSI host: %d\n", ret); + + drm_panel_remove(&ctx->panel); +} + +static const struct of_device_id s6d7aa0_of_match[] = { + { + .compatible = "samsung,lsl080al02", + .data = &s6d7aa0_lsl080al02_desc + }, + { + .compatible = "samsung,lsl080al03", + .data = &s6d7aa0_lsl080al03_desc + }, + { + .compatible = "samsung,ltl101at01", + .data = &s6d7aa0_ltl101at01_desc + }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, s6d7aa0_of_match); + +static struct mipi_dsi_driver s6d7aa0_driver = { + .probe = s6d7aa0_probe, + .remove = s6d7aa0_remove, + .driver = { + .name = "panel-samsung-s6d7aa0", + .of_match_table = s6d7aa0_of_match, + }, +}; +module_mipi_dsi_driver(s6d7aa0_driver); + +MODULE_AUTHOR("Artur Weber <[email protected]>"); +MODULE_DESCRIPTION("Samsung S6D7AA0 MIPI-DSI LCD controller driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c b/drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c index 39eef3dce7c9..639a4fdf57bb 100644 --- a/drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c +++ b/drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c @@ -12,7 +12,7 @@ #include <linux/delay.h> #include <linux/gpio/consumer.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/regulator/consumer.h> #include <drm/drm_mipi_dsi.h> diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e63m0-dsi.c b/drivers/gpu/drm/panel/panel-samsung-s6e63m0-dsi.c index ed3895e4ca5e..a89d925fdfb2 100644 --- a/drivers/gpu/drm/panel/panel-samsung-s6e63m0-dsi.c +++ b/drivers/gpu/drm/panel/panel-samsung-s6e63m0-dsi.c @@ -6,7 +6,7 @@ #include <linux/module.h> #include <linux/delay.h> -#include <linux/of_device.h> +#include <linux/mod_devicetable.h> #include <drm/drm_mipi_dsi.h> #include <drm/drm_print.h> diff --git a/drivers/gpu/drm/panel/panel-samsung-sofef00.c b/drivers/gpu/drm/panel/panel-samsung-sofef00.c index 1ebb79e3103c..cbf9607dd576 100644 --- a/drivers/gpu/drm/panel/panel-samsung-sofef00.c +++ b/drivers/gpu/drm/panel/panel-samsung-sofef00.c @@ -8,7 +8,6 @@ #include <linux/gpio/consumer.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/regulator/consumer.h> #include <linux/backlight.h> diff --git a/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c b/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c index c250ca36a5b3..658c7c040570 100644 --- a/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c +++ b/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c @@ -278,14 +278,12 @@ static int seiko_panel_probe(struct device *dev, return 0; } -static int seiko_panel_remove(struct platform_device *pdev) +static void seiko_panel_remove(struct platform_device *pdev) { struct seiko_panel *panel = platform_get_drvdata(pdev); drm_panel_remove(&panel->base); drm_panel_disable(&panel->base); - - return 0; } static void seiko_panel_shutdown(struct platform_device *pdev) @@ -347,7 +345,7 @@ static struct platform_driver seiko_panel_platform_driver = { .of_match_table = platform_of_match, }, .probe = seiko_panel_platform_probe, - .remove = seiko_panel_remove, + .remove_new = seiko_panel_remove, .shutdown = seiko_panel_shutdown, }; module_platform_driver(seiko_panel_platform_driver); diff --git a/drivers/gpu/drm/panel/panel-sharp-ls037v7dw01.c b/drivers/gpu/drm/panel/panel-sharp-ls037v7dw01.c index a07d0f6c3e69..76bd9e810827 100644 --- a/drivers/gpu/drm/panel/panel-sharp-ls037v7dw01.c +++ b/drivers/gpu/drm/panel/panel-sharp-ls037v7dw01.c @@ -189,15 +189,13 @@ static int ls037v7dw01_probe(struct platform_device *pdev) return 0; } -static int ls037v7dw01_remove(struct platform_device *pdev) +static void ls037v7dw01_remove(struct platform_device *pdev) { struct ls037v7dw01_panel *lcd = platform_get_drvdata(pdev); drm_panel_remove(&lcd->panel); drm_panel_disable(&lcd->panel); drm_panel_unprepare(&lcd->panel); - - return 0; } static const struct of_device_id ls037v7dw01_of_match[] = { @@ -209,7 +207,7 @@ MODULE_DEVICE_TABLE(of, ls037v7dw01_of_match); static struct platform_driver ls037v7dw01_driver = { .probe = ls037v7dw01_probe, - .remove = ls037v7dw01_remove, + .remove_new = ls037v7dw01_remove, .driver = { .name = "panel-sharp-ls037v7dw01", .of_match_table = ls037v7dw01_of_match, diff --git a/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c b/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c index d1ec80a3e3c7..855e64444daa 100644 --- a/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c +++ b/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c @@ -28,9 +28,6 @@ struct sharp_nt_panel { struct gpio_desc *reset_gpio; bool prepared; - bool enabled; - - const struct drm_display_mode *mode; }; static inline struct sharp_nt_panel *to_sharp_nt_panel(struct drm_panel *panel) @@ -97,19 +94,6 @@ static int sharp_nt_panel_off(struct sharp_nt_panel *sharp_nt) return 0; } - -static int sharp_nt_panel_disable(struct drm_panel *panel) -{ - struct sharp_nt_panel *sharp_nt = to_sharp_nt_panel(panel); - - if (!sharp_nt->enabled) - return 0; - - sharp_nt->enabled = false; - - return 0; -} - static int sharp_nt_panel_unprepare(struct drm_panel *panel) { struct sharp_nt_panel *sharp_nt = to_sharp_nt_panel(panel); @@ -179,28 +163,16 @@ poweroff: return ret; } -static int sharp_nt_panel_enable(struct drm_panel *panel) -{ - struct sharp_nt_panel *sharp_nt = to_sharp_nt_panel(panel); - - if (sharp_nt->enabled) - return 0; - - sharp_nt->enabled = true; - - return 0; -} - static const struct drm_display_mode default_mode = { - .clock = 41118, + .clock = (540 + 48 + 32 + 80) * (960 + 3 + 10 + 15) * 60 / 1000, .hdisplay = 540, .hsync_start = 540 + 48, - .hsync_end = 540 + 48 + 80, - .htotal = 540 + 48 + 80 + 32, + .hsync_end = 540 + 48 + 32, + .htotal = 540 + 48 + 32 + 80, .vdisplay = 960, .vsync_start = 960 + 3, - .vsync_end = 960 + 3 + 15, - .vtotal = 960 + 3 + 15 + 1, + .vsync_end = 960 + 3 + 10, + .vtotal = 960 + 3 + 10 + 15, }; static int sharp_nt_panel_get_modes(struct drm_panel *panel, @@ -227,10 +199,8 @@ static int sharp_nt_panel_get_modes(struct drm_panel *panel, } static const struct drm_panel_funcs sharp_nt_panel_funcs = { - .disable = sharp_nt_panel_disable, .unprepare = sharp_nt_panel_unprepare, .prepare = sharp_nt_panel_prepare, - .enable = sharp_nt_panel_enable, .get_modes = sharp_nt_panel_get_modes, }; @@ -239,8 +209,6 @@ static int sharp_nt_panel_add(struct sharp_nt_panel *sharp_nt) struct device *dev = &sharp_nt->dsi->dev; int ret; - sharp_nt->mode = &default_mode; - sharp_nt->supply = devm_regulator_get(dev, "avdd"); if (IS_ERR(sharp_nt->supply)) return PTR_ERR(sharp_nt->supply); @@ -280,6 +248,7 @@ static int sharp_nt_panel_probe(struct mipi_dsi_device *dsi) dsi->lanes = 2; dsi->format = MIPI_DSI_FMT_RGB888; dsi->mode_flags = MIPI_DSI_MODE_VIDEO | + MIPI_DSI_MODE_VIDEO_SYNC_PULSE | MIPI_DSI_MODE_VIDEO_HSE | MIPI_DSI_CLOCK_NON_CONTINUOUS | MIPI_DSI_MODE_NO_EOT_PACKET; diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 065f378bba9d..95959dcc6e0e 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -141,7 +141,6 @@ struct panel_simple { bool prepared; - ktime_t prepared_time; ktime_t unprepared_time; const struct panel_desc *desc; @@ -351,8 +350,6 @@ static int panel_simple_resume(struct device *dev) if (p->desc->delay.prepare) msleep(p->desc->delay.prepare); - p->prepared_time = ktime_get_boottime(); - return 0; } @@ -566,7 +563,6 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc) return -ENOMEM; panel->enabled = false; - panel->prepared_time = 0; panel->desc = desc; panel->supply = devm_regulator_get(dev, "power"); @@ -759,8 +755,8 @@ static const struct panel_desc ampire_am_480272h3tmqw_t01h = { .num_modes = 1, .bpc = 8, .size = { - .width = 105, - .height = 67, + .width = 99, + .height = 58, }, .bus_format = MEDIA_BUS_FMT_RGB888_1X24, }; @@ -778,6 +774,36 @@ static const struct drm_display_mode ampire_am800480r3tmqwa1h_mode = { .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC, }; +static const struct display_timing ampire_am_800480l1tmqw_t00h_timing = { + .pixelclock = { 29930000, 33260000, 36590000 }, + .hactive = { 800, 800, 800 }, + .hfront_porch = { 1, 40, 168 }, + .hback_porch = { 88, 88, 88 }, + .hsync_len = { 1, 128, 128 }, + .vactive = { 480, 480, 480 }, + .vfront_porch = { 1, 35, 37 }, + .vback_porch = { 8, 8, 8 }, + .vsync_len = { 1, 2, 2 }, + .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW | + DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE | + DISPLAY_FLAGS_SYNC_POSEDGE, +}; + +static const struct panel_desc ampire_am_800480l1tmqw_t00h = { + .timings = &ire_am_800480l1tmqw_t00h_timing, + .num_timings = 1, + .bpc = 8, + .size = { + .width = 111, + .height = 67, + }, + .bus_format = MEDIA_BUS_FMT_RGB888_1X24, + .bus_flags = DRM_BUS_FLAG_DE_HIGH | + DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE | + DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE, + .connector_type = DRM_MODE_CONNECTOR_DPI, +}; + static const struct panel_desc ampire_am800480r3tmqwa1h = { .modes = &ire_am800480r3tmqwa1h_mode, .num_modes = 1, @@ -969,21 +995,21 @@ static const struct panel_desc auo_g104sn02 = { .connector_type = DRM_MODE_CONNECTOR_LVDS, }; -static const struct drm_display_mode auo_g121ean01_mode = { - .clock = 66700, - .hdisplay = 1280, - .hsync_start = 1280 + 58, - .hsync_end = 1280 + 58 + 8, - .htotal = 1280 + 58 + 8 + 70, - .vdisplay = 800, - .vsync_start = 800 + 6, - .vsync_end = 800 + 6 + 4, - .vtotal = 800 + 6 + 4 + 10, +static const struct display_timing auo_g121ean01_timing = { + .pixelclock = { 60000000, 74400000, 90000000 }, + .hactive = { 1280, 1280, 1280 }, + .hfront_porch = { 20, 50, 100 }, + .hback_porch = { 20, 50, 100 }, + .hsync_len = { 30, 100, 200 }, + .vactive = { 800, 800, 800 }, + .vfront_porch = { 2, 10, 25 }, + .vback_porch = { 2, 10, 25 }, + .vsync_len = { 4, 18, 50 }, }; static const struct panel_desc auo_g121ean01 = { - .modes = &auo_g121ean01_mode, - .num_modes = 1, + .timings = &auo_g121ean01_timing, + .num_timings = 1, .bpc = 8, .size = { .width = 261, @@ -1159,7 +1185,9 @@ static const struct panel_desc auo_t215hvn01 = { .delay = { .disable = 5, .unprepare = 1000, - } + }, + .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, + .connector_type = DRM_MODE_CONNECTOR_LVDS, }; static const struct drm_display_mode avic_tm070ddh03_mode = { @@ -1211,6 +1239,37 @@ static const struct panel_desc bananapi_s070wv20_ct16 = { }, }; +static const struct display_timing boe_ev121wxm_n10_1850_timing = { + .pixelclock = { 69922000, 71000000, 72293000 }, + .hactive = { 1280, 1280, 1280 }, + .hfront_porch = { 48, 48, 48 }, + .hback_porch = { 80, 80, 80 }, + .hsync_len = { 32, 32, 32 }, + .vactive = { 800, 800, 800 }, + .vfront_porch = { 3, 3, 3 }, + .vback_porch = { 14, 14, 14 }, + .vsync_len = { 6, 6, 6 }, +}; + +static const struct panel_desc boe_ev121wxm_n10_1850 = { + .timings = &boe_ev121wxm_n10_1850_timing, + .num_timings = 1, + .bpc = 8, + .size = { + .width = 261, + .height = 163, + }, + .delay = { + .prepare = 9, + .enable = 300, + .unprepare = 300, + .disable = 560, + }, + .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, + .bus_flags = DRM_BUS_FLAG_DE_HIGH, + .connector_type = DRM_MODE_CONNECTOR_LVDS, +}; + static const struct drm_display_mode boe_hv070wsa_mode = { .clock = 42105, .hdisplay = 1024, @@ -2117,6 +2176,7 @@ static const struct panel_desc innolux_at043tn24 = { .height = 54, }, .bus_format = MEDIA_BUS_FMT_RGB888_1X24, + .connector_type = DRM_MODE_CONNECTOR_DPI, .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE, }; @@ -2142,6 +2202,38 @@ static const struct panel_desc innolux_at070tn92 = { .bus_format = MEDIA_BUS_FMT_RGB888_1X24, }; +static const struct display_timing innolux_g070ace_l01_timing = { + .pixelclock = { 25200000, 35000000, 35700000 }, + .hactive = { 800, 800, 800 }, + .hfront_porch = { 30, 32, 87 }, + .hback_porch = { 30, 32, 87 }, + .hsync_len = { 1, 1, 1 }, + .vactive = { 480, 480, 480 }, + .vfront_porch = { 3, 3, 3 }, + .vback_porch = { 13, 13, 13 }, + .vsync_len = { 1, 1, 4 }, + .flags = DISPLAY_FLAGS_DE_HIGH, +}; + +static const struct panel_desc innolux_g070ace_l01 = { + .timings = &innolux_g070ace_l01_timing, + .num_timings = 1, + .bpc = 8, + .size = { + .width = 152, + .height = 91, + }, + .delay = { + .prepare = 10, + .enable = 50, + .disable = 50, + .unprepare = 500, + }, + .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, + .bus_flags = DRM_BUS_FLAG_DE_HIGH, + .connector_type = DRM_MODE_CONNECTOR_LVDS, +}; + static const struct display_timing innolux_g070y2_l01_timing = { .pixelclock = { 28000000, 29500000, 32000000 }, .hactive = { 800, 800, 800 }, @@ -2284,6 +2376,37 @@ static const struct panel_desc innolux_g121x1_l03 = { }, }; +static const struct display_timing innolux_g156hce_l01_timings = { + .pixelclock = { 120000000, 141860000, 150000000 }, + .hactive = { 1920, 1920, 1920 }, + .hfront_porch = { 80, 90, 100 }, + .hback_porch = { 80, 90, 100 }, + .hsync_len = { 20, 30, 30 }, + .vactive = { 1080, 1080, 1080 }, + .vfront_porch = { 3, 10, 20 }, + .vback_porch = { 3, 10, 20 }, + .vsync_len = { 4, 10, 10 }, +}; + +static const struct panel_desc innolux_g156hce_l01 = { + .timings = &innolux_g156hce_l01_timings, + .num_timings = 1, + .bpc = 8, + .size = { + .width = 344, + .height = 194, + }, + .delay = { + .prepare = 1, /* T1+T2 */ + .enable = 450, /* T5 */ + .disable = 200, /* T6 */ + .unprepare = 10, /* T3+T7 */ + }, + .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, + .bus_flags = DRM_BUS_FLAG_DE_HIGH, + .connector_type = DRM_MODE_CONNECTOR_LVDS, +}; + static const struct drm_display_mode innolux_n156bge_l21_mode = { .clock = 69300, .hdisplay = 1366, @@ -3109,11 +3232,13 @@ static const struct drm_display_mode powertip_ph800480t013_idf02_mode = { .vsync_start = 480 + 49, .vsync_end = 480 + 49 + 2, .vtotal = 480 + 49 + 2 + 22, + .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC, }; static const struct panel_desc powertip_ph800480t013_idf02 = { .modes = &powertip_ph800480t013_idf02_mode, .num_modes = 1, + .bpc = 8, .size = { .width = 152, .height = 91, @@ -3188,6 +3313,32 @@ static const struct panel_desc qishenglong_gopher2b_lcd = { .connector_type = DRM_MODE_CONNECTOR_DPI, }; +static const struct display_timing rocktech_rk043fn48h_timing = { + .pixelclock = { 6000000, 9000000, 12000000 }, + .hactive = { 480, 480, 480 }, + .hback_porch = { 8, 43, 43 }, + .hfront_porch = { 2, 8, 8 }, + .hsync_len = { 1, 1, 1 }, + .vactive = { 272, 272, 272 }, + .vback_porch = { 2, 12, 12 }, + .vfront_porch = { 1, 4, 4 }, + .vsync_len = { 1, 10, 10 }, + .flags = DISPLAY_FLAGS_VSYNC_LOW | DISPLAY_FLAGS_HSYNC_LOW | + DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE, +}; + +static const struct panel_desc rocktech_rk043fn48h = { + .timings = &rocktech_rk043fn48h_timing, + .num_timings = 1, + .bpc = 8, + .size = { + .width = 95, + .height = 54, + }, + .bus_format = MEDIA_BUS_FMT_RGB888_1X24, + .connector_type = DRM_MODE_CONNECTOR_DPI, +}; + static const struct display_timing rocktech_rk070er9427_timing = { .pixelclock = { 26400000, 33300000, 46800000 }, .hactive = { 800, 800, 800 }, @@ -3931,6 +4082,9 @@ static const struct of_device_id platform_of_match[] = { .compatible = "ampire,am-480272h3tmqw-t01h", .data = &ire_am_480272h3tmqw_t01h, }, { + .compatible = "ampire,am-800480l1tmqw-t00h", + .data = &ire_am_800480l1tmqw_t00h, + }, { .compatible = "ampire,am800480r3tmqwa1h", .data = &ire_am800480r3tmqwa1h, }, { @@ -3985,6 +4139,9 @@ static const struct of_device_id platform_of_match[] = { .compatible = "bananapi,s070wv20-ct16", .data = &bananapi_s070wv20_ct16, }, { + .compatible = "boe,ev121wxm-n10-1850", + .data = &boe_ev121wxm_n10_1850, + }, { .compatible = "boe,hv070wsa-100", .data = &boe_hv070wsa }, { @@ -4099,6 +4256,9 @@ static const struct of_device_id platform_of_match[] = { .compatible = "innolux,at070tn92", .data = &innolux_at070tn92, }, { + .compatible = "innolux,g070ace-l01", + .data = &innolux_g070ace_l01, + }, { .compatible = "innolux,g070y2-l01", .data = &innolux_g070y2_l01, }, { @@ -4114,6 +4274,9 @@ static const struct of_device_id platform_of_match[] = { .compatible = "innolux,g121x1-l03", .data = &innolux_g121x1_l03, }, { + .compatible = "innolux,g156hce-l01", + .data = &innolux_g156hce_l01, + }, { .compatible = "innolux,n156bge-l21", .data = &innolux_n156bge_l21, }, { @@ -4219,6 +4382,9 @@ static const struct of_device_id platform_of_match[] = { .compatible = "qishenglong,gopher2b-lcd", .data = &qishenglong_gopher2b_lcd, }, { + .compatible = "rocktech,rk043fn48h", + .data = &rocktech_rk043fn48h, + }, { .compatible = "rocktech,rk070er9427", .data = &rocktech_rk070er9427, }, { @@ -4326,20 +4492,18 @@ MODULE_DEVICE_TABLE(of, platform_of_match); static int panel_simple_platform_probe(struct platform_device *pdev) { - const struct of_device_id *id; + const struct panel_desc *desc; - id = of_match_node(platform_of_match, pdev->dev.of_node); - if (!id) + desc = of_device_get_match_data(&pdev->dev); + if (!desc) return -ENODEV; - return panel_simple_probe(&pdev->dev, id->data); + return panel_simple_probe(&pdev->dev, desc); } -static int panel_simple_platform_remove(struct platform_device *pdev) +static void panel_simple_platform_remove(struct platform_device *pdev) { panel_simple_remove(&pdev->dev); - - return 0; } static void panel_simple_platform_shutdown(struct platform_device *pdev) @@ -4360,7 +4524,7 @@ static struct platform_driver panel_simple_platform_driver = { .pm = &panel_simple_pm_ops, }, .probe = panel_simple_platform_probe, - .remove = panel_simple_platform_remove, + .remove_new = panel_simple_platform_remove, .shutdown = panel_simple_platform_shutdown, }; @@ -4605,15 +4769,12 @@ MODULE_DEVICE_TABLE(of, dsi_of_match); static int panel_simple_dsi_probe(struct mipi_dsi_device *dsi) { const struct panel_desc_dsi *desc; - const struct of_device_id *id; int err; - id = of_match_node(dsi_of_match, dsi->dev.of_node); - if (!id) + desc = of_device_get_match_data(&dsi->dev); + if (!desc) return -ENODEV; - desc = id->data; - err = panel_simple_probe(&dsi->dev, &desc->desc); if (err < 0) return err; diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7701.c b/drivers/gpu/drm/panel/panel-sitronix-st7701.c index 7eae83aa0ea1..0459965e1b4f 100644 --- a/drivers/gpu/drm/panel/panel-sitronix-st7701.c +++ b/drivers/gpu/drm/panel/panel-sitronix-st7701.c @@ -12,7 +12,7 @@ #include <linux/gpio/consumer.h> #include <linux/delay.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/regulator/consumer.h> #include <video/mipi_display.h> diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7703.c b/drivers/gpu/drm/panel/panel-sitronix-st7703.c index 6747ca237ced..6a3945639535 100644 --- a/drivers/gpu/drm/panel/panel-sitronix-st7703.c +++ b/drivers/gpu/drm/panel/panel-sitronix-st7703.c @@ -13,7 +13,7 @@ #include <linux/media-bus-format.h> #include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/regulator/consumer.h> #include <video/display_timing.h> @@ -28,6 +28,7 @@ /* Manufacturer specific Commands send via DSI */ #define ST7703_CMD_ALL_PIXEL_OFF 0x22 #define ST7703_CMD_ALL_PIXEL_ON 0x23 +#define ST7703_CMD_SETAPID 0xB1 #define ST7703_CMD_SETDISP 0xB2 #define ST7703_CMD_SETRGBIF 0xB3 #define ST7703_CMD_SETCYC 0xB4 @@ -41,12 +42,15 @@ #define ST7703_CMD_UNKNOWN_BF 0xBF #define ST7703_CMD_SETSCR 0xC0 #define ST7703_CMD_SETPOWER 0xC1 +#define ST7703_CMD_SETECO 0xC6 +#define ST7703_CMD_SETIO 0xC7 +#define ST7703_CMD_SETCABC 0xC8 #define ST7703_CMD_SETPANEL 0xCC -#define ST7703_CMD_UNKNOWN_C6 0xC6 #define ST7703_CMD_SETGAMMA 0xE0 #define ST7703_CMD_SETEQ 0xE3 #define ST7703_CMD_SETGIP1 0xE9 #define ST7703_CMD_SETGIP2 0xEA +#define ST7703_CMD_UNKNOWN_EF 0xEF struct st7703 { struct device *dev; @@ -249,8 +253,7 @@ static int xbd599_init_sequence(struct st7703 *ctx) * ESD_DET_TIME_SEL = 0 frames */); - /* Undocumented command. */ - mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_UNKNOWN_C6, 0x01, 0x00, 0xFF, 0xFF, 0x00); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETECO, 0x01, 0x00, 0xFF, 0xFF, 0x00); mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETPOWER, 0x74, /* VBTHS, VBTLS: VGH = 17V, VBL = -11V */ @@ -338,6 +341,98 @@ static const struct st7703_panel_desc xbd599_desc = { .init_sequence = xbd599_init_sequence, }; +static int rg353v2_init_sequence(struct st7703 *ctx) +{ + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); + + /* + * Init sequence was supplied by the panel vendor. + */ + + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETEXTC, 0xf1, 0x12, 0x83); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETAPID, 0x00, 0x00, 0x00, + 0xda, 0x80); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETDISP, 0x00, 0x13, 0x70); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETRGBIF, 0x10, 0x10, 0x28, + 0x28, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETCYC, 0x80); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETBGP, 0x0a, 0x0a); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETVCOM, 0x92, 0x92); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETPOWER_EXT, 0x25, 0x22, + 0xf0, 0x63); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETMIPI, 0x33, 0x81, 0x05, + 0xf9, 0x0e, 0x0e, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x44, 0x25, 0x00, 0x90, 0x0a, + 0x00, 0x00, 0x01, 0x4f, 0x01, 0x00, 0x00, 0x37); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETVDC, 0x47); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_UNKNOWN_BF, 0x02, 0x11, 0x00); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETSCR, 0x73, 0x73, 0x50, 0x50, + 0x00, 0x00, 0x12, 0x50, 0x00); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETPOWER, 0x53, 0xc0, 0x32, + 0x32, 0x77, 0xe1, 0xdd, 0xdd, 0x77, 0x77, 0x33, + 0x33); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETECO, 0x82, 0x00, 0xbf, 0xff, + 0x00, 0xff); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETIO, 0xb8, 0x00, 0x0a, 0x00, + 0x00, 0x00); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETCABC, 0x10, 0x40, 0x1e, + 0x02); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETPANEL, 0x0b); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETGAMMA, 0x00, 0x07, 0x0d, + 0x37, 0x35, 0x3f, 0x41, 0x44, 0x06, 0x0c, 0x0d, + 0x0f, 0x11, 0x10, 0x12, 0x14, 0x1a, 0x00, 0x07, + 0x0d, 0x37, 0x35, 0x3f, 0x41, 0x44, 0x06, 0x0c, + 0x0d, 0x0f, 0x11, 0x10, 0x12, 0x14, 0x1a); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETEQ, 0x07, 0x07, 0x0b, 0x0b, + 0x0b, 0x0b, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, + 0xc0, 0x10); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETGIP1, 0xc8, 0x10, 0x02, 0x00, + 0x00, 0xb0, 0xb1, 0x11, 0x31, 0x23, 0x28, 0x80, + 0xb0, 0xb1, 0x27, 0x08, 0x00, 0x04, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x00, + 0x88, 0x88, 0xba, 0x60, 0x24, 0x08, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x88, 0x88, 0xba, 0x71, 0x35, + 0x18, 0x88, 0x88, 0x88, 0x88, 0x88, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETGIP2, 0x97, 0x0a, 0x82, 0x02, + 0x03, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x81, 0x88, 0xba, 0x17, 0x53, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x80, 0x88, 0xba, 0x06, 0x42, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x23, 0x00, + 0x00, 0x02, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_UNKNOWN_EF, 0xff, 0xff, 0x01); + + return 0; +} + +static const struct drm_display_mode rg353v2_mode = { + .hdisplay = 640, + .hsync_start = 640 + 40, + .hsync_end = 640 + 40 + 2, + .htotal = 640 + 40 + 2 + 80, + .vdisplay = 480, + .vsync_start = 480 + 18, + .vsync_end = 480 + 18 + 2, + .vtotal = 480 + 18 + 2 + 28, + .clock = 24150, + .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, + .width_mm = 70, + .height_mm = 57, +}; + +static const struct st7703_panel_desc rg353v2_desc = { + .mode = &rg353v2_mode, + .lanes = 4, + .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | + MIPI_DSI_MODE_NO_EOT_PACKET | MIPI_DSI_MODE_LPM, + .format = MIPI_DSI_FMT_RGB888, + .init_sequence = rg353v2_init_sequence, +}; + static int st7703_enable(struct drm_panel *panel) { struct st7703 *ctx = panel_to_st7703(panel); @@ -598,6 +693,7 @@ static void st7703_remove(struct mipi_dsi_device *dsi) } static const struct of_device_id st7703_of_match[] = { + { .compatible = "anbernic,rg353v-panel-v2", .data = &rg353v2_desc }, { .compatible = "rocktech,jh057n00900", .data = &jh057n00900_panel_desc }, { .compatible = "xingbangda,xbd599", .data = &xbd599_desc }, { /* sentinel */ } diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7789v.c b/drivers/gpu/drm/panel/panel-sitronix-st7789v.c index bbc4569cbcdc..88e80fe98112 100644 --- a/drivers/gpu/drm/panel/panel-sitronix-st7789v.c +++ b/drivers/gpu/drm/panel/panel-sitronix-st7789v.c @@ -10,14 +10,12 @@ #include <linux/spi/spi.h> #include <video/mipi_display.h> +#include <linux/media-bus-format.h> #include <drm/drm_device.h> #include <drm/drm_modes.h> #include <drm/drm_panel.h> -#define ST7789V_COLMOD_RGB_FMT_18BITS (6 << 4) -#define ST7789V_COLMOD_CTRL_FMT_18BITS (6 << 0) - #define ST7789V_RAMCTRL_CMD 0xb0 #define ST7789V_RAMCTRL_RM_RGB BIT(4) #define ST7789V_RAMCTRL_DM_RGB BIT(0) @@ -29,7 +27,8 @@ #define ST7789V_RGBCTRL_RCM(n) (((n) & 3) << 5) #define ST7789V_RGBCTRL_VSYNC_HIGH BIT(3) #define ST7789V_RGBCTRL_HSYNC_HIGH BIT(2) -#define ST7789V_RGBCTRL_PCLK_HIGH BIT(1) +#define ST7789V_RGBCTRL_PCLK_FALLING BIT(1) +#define ST7789V_RGBCTRL_DE_LOW BIT(0) #define ST7789V_RGBCTRL_VBP(n) ((n) & 0x7f) #define ST7789V_RGBCTRL_HBP(n) ((n) & 0x1f) @@ -111,11 +110,26 @@ return val; \ } while (0) +#define ST7789V_IDS { 0x85, 0x85, 0x52 } +#define ST7789V_IDS_SIZE 3 + +struct st7789_panel_info { + const struct drm_display_mode *mode; + u32 bus_format; + u32 bus_flags; + bool invert_mode; + bool partial_mode; + u16 partial_start; + u16 partial_end; +}; + struct st7789v { struct drm_panel panel; + const struct st7789_panel_info *info; struct spi_device *spi; struct gpio_desc *reset; struct regulator *power; + enum drm_panel_orientation orientation; }; enum st7789v_prefix { @@ -132,17 +146,12 @@ static int st7789v_spi_write(struct st7789v *ctx, enum st7789v_prefix prefix, u8 data) { struct spi_transfer xfer = { }; - struct spi_message msg; u16 txbuf = ((prefix & 1) << 8) | data; - spi_message_init(&msg); - xfer.tx_buf = &txbuf; - xfer.bits_per_word = 9; xfer.len = sizeof(txbuf); - spi_message_add_tail(&xfer, &msg); - return spi_sync(ctx->spi, &msg); + return spi_sync_transfer(ctx->spi, &xfer, 1); } static int st7789v_write_command(struct st7789v *ctx, u8 cmd) @@ -155,6 +164,76 @@ static int st7789v_write_data(struct st7789v *ctx, u8 cmd) return st7789v_spi_write(ctx, ST7789V_DATA, cmd); } +static int st7789v_read_data(struct st7789v *ctx, u8 cmd, u8 *buf, + unsigned int len) +{ + struct spi_transfer xfer[2] = { }; + struct spi_message msg; + u16 txbuf = ((ST7789V_COMMAND & 1) << 8) | cmd; + u16 rxbuf[4] = {}; + u8 bit9 = 0; + int ret, i; + + switch (len) { + case 1: + case 3: + case 4: + break; + default: + return -EOPNOTSUPP; + } + + spi_message_init(&msg); + + xfer[0].tx_buf = &txbuf; + xfer[0].len = sizeof(txbuf); + spi_message_add_tail(&xfer[0], &msg); + + xfer[1].rx_buf = rxbuf; + xfer[1].len = len * 2; + spi_message_add_tail(&xfer[1], &msg); + + ret = spi_sync(ctx->spi, &msg); + if (ret) + return ret; + + for (i = 0; i < len; i++) { + buf[i] = rxbuf[i] >> i | (bit9 << (9 - i)); + if (i) + bit9 = rxbuf[i] & GENMASK(i - 1, 0); + } + + return 0; +} + +static int st7789v_check_id(struct drm_panel *panel) +{ + const u8 st7789v_ids[ST7789V_IDS_SIZE] = ST7789V_IDS; + struct st7789v *ctx = panel_to_st7789v(panel); + bool invalid_ids = false; + int ret, i; + u8 ids[3]; + + if (ctx->spi->mode & SPI_NO_RX) + return 0; + + ret = st7789v_read_data(ctx, MIPI_DCS_GET_DISPLAY_ID, ids, ST7789V_IDS_SIZE); + if (ret) + return ret; + + for (i = 0; i < ST7789V_IDS_SIZE; i++) { + if (ids[i] != st7789v_ids[i]) { + invalid_ids = true; + break; + } + } + + if (invalid_ids) + return -EIO; + + return 0; +} + static const struct drm_display_mode default_mode = { .clock = 7000, .hdisplay = 240, @@ -165,18 +244,102 @@ static const struct drm_display_mode default_mode = { .vsync_start = 320 + 8, .vsync_end = 320 + 8 + 4, .vtotal = 320 + 8 + 4 + 4, + .width_mm = 61, + .height_mm = 103, + .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC, +}; + +static const struct drm_display_mode t28cp45tn89_mode = { + .clock = 6008, + .hdisplay = 240, + .hsync_start = 240 + 38, + .hsync_end = 240 + 38 + 10, + .htotal = 240 + 38 + 10 + 10, + .vdisplay = 320, + .vsync_start = 320 + 8, + .vsync_end = 320 + 8 + 4, + .vtotal = 320 + 8 + 4 + 4, + .width_mm = 43, + .height_mm = 57, + .flags = DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC, +}; + +static const struct drm_display_mode et028013dma_mode = { + .clock = 3000, + .hdisplay = 240, + .hsync_start = 240 + 38, + .hsync_end = 240 + 38 + 10, + .htotal = 240 + 38 + 10 + 10, + .vdisplay = 320, + .vsync_start = 320 + 8, + .vsync_end = 320 + 8 + 4, + .vtotal = 320 + 8 + 4 + 4, + .width_mm = 43, + .height_mm = 58, + .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC, +}; + +static const struct drm_display_mode jt240mhqs_hwt_ek_e3_mode = { + .clock = 6000, + .hdisplay = 240, + .hsync_start = 240 + 28, + .hsync_end = 240 + 28 + 10, + .htotal = 240 + 28 + 10 + 10, + .vdisplay = 280, + .vsync_start = 280 + 8, + .vsync_end = 280 + 8 + 4, + .vtotal = 280 + 8 + 4 + 4, + .width_mm = 43, + .height_mm = 37, + .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC, +}; + +static const struct st7789_panel_info default_panel = { + .mode = &default_mode, + .invert_mode = true, + .bus_format = MEDIA_BUS_FMT_RGB666_1X18, + .bus_flags = DRM_BUS_FLAG_DE_HIGH | + DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE, +}; + +static const struct st7789_panel_info t28cp45tn89_panel = { + .mode = &t28cp45tn89_mode, + .invert_mode = false, + .bus_format = MEDIA_BUS_FMT_RGB565_1X16, + .bus_flags = DRM_BUS_FLAG_DE_HIGH | + DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE, +}; + +static const struct st7789_panel_info et028013dma_panel = { + .mode = &et028013dma_mode, + .invert_mode = true, + .bus_format = MEDIA_BUS_FMT_RGB666_1X18, + .bus_flags = DRM_BUS_FLAG_DE_HIGH | + DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE, +}; + +static const struct st7789_panel_info jt240mhqs_hwt_ek_e3_panel = { + .mode = &jt240mhqs_hwt_ek_e3_mode, + .invert_mode = true, + .bus_format = MEDIA_BUS_FMT_RGB666_1X18, + .bus_flags = DRM_BUS_FLAG_DE_HIGH | + DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE, + .partial_mode = true, + .partial_start = 38, + .partial_end = 318, }; static int st7789v_get_modes(struct drm_panel *panel, struct drm_connector *connector) { + struct st7789v *ctx = panel_to_st7789v(panel); struct drm_display_mode *mode; - mode = drm_mode_duplicate(connector->dev, &default_mode); + mode = drm_mode_duplicate(connector->dev, ctx->info->mode); if (!mode) { - dev_err(panel->dev, "failed to add mode %ux%ux@%u\n", - default_mode.hdisplay, default_mode.vdisplay, - drm_mode_vrefresh(&default_mode)); + dev_err(panel->dev, "failed to add mode %ux%u@%u\n", + ctx->info->mode->hdisplay, ctx->info->mode->vdisplay, + drm_mode_vrefresh(ctx->info->mode)); return -ENOMEM; } @@ -185,17 +348,65 @@ static int st7789v_get_modes(struct drm_panel *panel, mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; drm_mode_probed_add(connector, mode); - connector->display_info.width_mm = 61; - connector->display_info.height_mm = 103; + connector->display_info.bpc = 6; + connector->display_info.width_mm = ctx->info->mode->width_mm; + connector->display_info.height_mm = ctx->info->mode->height_mm; + connector->display_info.bus_flags = ctx->info->bus_flags; + drm_display_info_set_bus_formats(&connector->display_info, + &ctx->info->bus_format, 1); + + /* + * TODO: Remove once all drm drivers call + * drm_connector_set_orientation_from_panel() + */ + drm_connector_set_panel_orientation(connector, ctx->orientation); return 1; } +static enum drm_panel_orientation st7789v_get_orientation(struct drm_panel *p) +{ + struct st7789v *ctx = panel_to_st7789v(p); + + return ctx->orientation; +} + static int st7789v_prepare(struct drm_panel *panel) { struct st7789v *ctx = panel_to_st7789v(panel); + u8 mode, pixel_fmt, polarity; int ret; + if (!ctx->info->partial_mode) + mode = ST7789V_RGBCTRL_WO; + else + mode = 0; + + switch (ctx->info->bus_format) { + case MEDIA_BUS_FMT_RGB666_1X18: + pixel_fmt = MIPI_DCS_PIXEL_FMT_18BIT; + break; + case MEDIA_BUS_FMT_RGB565_1X16: + pixel_fmt = MIPI_DCS_PIXEL_FMT_16BIT; + break; + default: + dev_err(panel->dev, "unsupported bus format: %d\n", + ctx->info->bus_format); + return -EINVAL; + } + + pixel_fmt = (pixel_fmt << 4) | pixel_fmt; + + polarity = 0; + if (ctx->info->mode->flags & DRM_MODE_FLAG_PVSYNC) + polarity |= ST7789V_RGBCTRL_VSYNC_HIGH; + if (ctx->info->mode->flags & DRM_MODE_FLAG_PHSYNC) + polarity |= ST7789V_RGBCTRL_HSYNC_HIGH; + if (ctx->info->bus_flags & DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE) + polarity |= ST7789V_RGBCTRL_PCLK_FALLING; + if (ctx->info->bus_flags & DRM_BUS_FLAG_DE_LOW) + polarity |= ST7789V_RGBCTRL_DE_LOW; + ret = regulator_enable(ctx->power); if (ret) return ret; @@ -205,6 +416,14 @@ static int st7789v_prepare(struct drm_panel *panel) gpiod_set_value(ctx->reset, 0); msleep(120); + /* + * Avoid failing if the IDs are invalid in case the Rx bus width + * description is missing. + */ + ret = st7789v_check_id(panel); + if (ret) + dev_warn(panel->dev, "Unrecognized panel IDs"); + ST7789V_TEST(ret, st7789v_write_command(ctx, MIPI_DCS_EXIT_SLEEP_MODE)); /* We need to wait 120ms after a sleep out command */ @@ -216,9 +435,7 @@ static int st7789v_prepare(struct drm_panel *panel) ST7789V_TEST(ret, st7789v_write_command(ctx, MIPI_DCS_SET_PIXEL_FORMAT)); - ST7789V_TEST(ret, st7789v_write_data(ctx, - (MIPI_DCS_PIXEL_FMT_18BIT << 4) | - (MIPI_DCS_PIXEL_FMT_18BIT))); + ST7789V_TEST(ret, st7789v_write_data(ctx, pixel_fmt)); ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_PORCTRL_CMD)); ST7789V_TEST(ret, st7789v_write_data(ctx, 0xc)); @@ -296,7 +513,44 @@ static int st7789v_prepare(struct drm_panel *panel) ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN61(0x1b))); ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_NVGAMCTRL_VN62(0x28))); - ST7789V_TEST(ret, st7789v_write_command(ctx, MIPI_DCS_ENTER_INVERT_MODE)); + if (ctx->info->invert_mode) { + ST7789V_TEST(ret, st7789v_write_command(ctx, + MIPI_DCS_ENTER_INVERT_MODE)); + } else { + ST7789V_TEST(ret, st7789v_write_command(ctx, + MIPI_DCS_EXIT_INVERT_MODE)); + } + + if (ctx->info->partial_mode) { + u8 area_data[4] = { + (ctx->info->partial_start >> 8) & 0xff, + (ctx->info->partial_start >> 0) & 0xff, + ((ctx->info->partial_end - 1) >> 8) & 0xff, + ((ctx->info->partial_end - 1) >> 0) & 0xff, + }; + + /* Caution: if userspace ever pushes a mode different from the + * expected one (i.e., the one advertised by get_modes), we'll + * add margins. + */ + + ST7789V_TEST(ret, st7789v_write_command( + ctx, MIPI_DCS_ENTER_PARTIAL_MODE)); + + ST7789V_TEST(ret, st7789v_write_command( + ctx, MIPI_DCS_SET_PAGE_ADDRESS)); + ST7789V_TEST(ret, st7789v_write_data(ctx, area_data[0])); + ST7789V_TEST(ret, st7789v_write_data(ctx, area_data[1])); + ST7789V_TEST(ret, st7789v_write_data(ctx, area_data[2])); + ST7789V_TEST(ret, st7789v_write_data(ctx, area_data[3])); + + ST7789V_TEST(ret, st7789v_write_command( + ctx, MIPI_DCS_SET_PARTIAL_ROWS)); + ST7789V_TEST(ret, st7789v_write_data(ctx, area_data[0])); + ST7789V_TEST(ret, st7789v_write_data(ctx, area_data[1])); + ST7789V_TEST(ret, st7789v_write_data(ctx, area_data[2])); + ST7789V_TEST(ret, st7789v_write_data(ctx, area_data[3])); + } ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_RAMCTRL_CMD)); ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_RAMCTRL_DM_RGB | @@ -305,11 +559,9 @@ static int st7789v_prepare(struct drm_panel *panel) ST7789V_RAMCTRL_MAGIC)); ST7789V_TEST(ret, st7789v_write_command(ctx, ST7789V_RGBCTRL_CMD)); - ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_RGBCTRL_WO | + ST7789V_TEST(ret, st7789v_write_data(ctx, mode | ST7789V_RGBCTRL_RCM(2) | - ST7789V_RGBCTRL_VSYNC_HIGH | - ST7789V_RGBCTRL_HSYNC_HIGH | - ST7789V_RGBCTRL_PCLK_HIGH)); + polarity)); ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_RGBCTRL_VBP(8))); ST7789V_TEST(ret, st7789v_write_data(ctx, ST7789V_RGBCTRL_HBP(20))); @@ -346,41 +598,52 @@ static int st7789v_unprepare(struct drm_panel *panel) } static const struct drm_panel_funcs st7789v_drm_funcs = { - .disable = st7789v_disable, - .enable = st7789v_enable, - .get_modes = st7789v_get_modes, - .prepare = st7789v_prepare, - .unprepare = st7789v_unprepare, + .disable = st7789v_disable, + .enable = st7789v_enable, + .get_modes = st7789v_get_modes, + .get_orientation = st7789v_get_orientation, + .prepare = st7789v_prepare, + .unprepare = st7789v_unprepare, }; static int st7789v_probe(struct spi_device *spi) { + struct device *dev = &spi->dev; struct st7789v *ctx; int ret; - ctx = devm_kzalloc(&spi->dev, sizeof(*ctx), GFP_KERNEL); + ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); if (!ctx) return -ENOMEM; spi_set_drvdata(spi, ctx); ctx->spi = spi; - drm_panel_init(&ctx->panel, &spi->dev, &st7789v_drm_funcs, + spi->bits_per_word = 9; + ret = spi_setup(spi); + if (ret < 0) + return dev_err_probe(&spi->dev, ret, "Failed to setup spi\n"); + + ctx->info = device_get_match_data(&spi->dev); + + drm_panel_init(&ctx->panel, dev, &st7789v_drm_funcs, DRM_MODE_CONNECTOR_DPI); - ctx->power = devm_regulator_get(&spi->dev, "power"); - if (IS_ERR(ctx->power)) - return PTR_ERR(ctx->power); + ctx->power = devm_regulator_get(dev, "power"); + ret = PTR_ERR_OR_ZERO(ctx->power); + if (ret) + return dev_err_probe(dev, ret, "Failed to get regulator\n"); - ctx->reset = devm_gpiod_get(&spi->dev, "reset", GPIOD_OUT_LOW); - if (IS_ERR(ctx->reset)) { - dev_err(&spi->dev, "Couldn't get our reset line\n"); - return PTR_ERR(ctx->reset); - } + ctx->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); + ret = PTR_ERR_OR_ZERO(ctx->reset); + if (ret) + return dev_err_probe(dev, ret, "Failed to get reset line\n"); ret = drm_panel_of_backlight(&ctx->panel); if (ret) - return ret; + return dev_err_probe(dev, ret, "Failed to get backlight\n"); + + of_drm_get_panel_orientation(spi->dev.of_node, &ctx->orientation); drm_panel_add(&ctx->panel); @@ -394,8 +657,21 @@ static void st7789v_remove(struct spi_device *spi) drm_panel_remove(&ctx->panel); } +static const struct spi_device_id st7789v_spi_id[] = { + { "st7789v", (unsigned long) &default_panel }, + { "t28cp45tn89-v17", (unsigned long) &t28cp45tn89_panel }, + { "et028013dma", (unsigned long) &et028013dma_panel }, + { "jt240mhqs-hwt-ek-e3", (unsigned long) &jt240mhqs_hwt_ek_e3_panel }, + { } +}; +MODULE_DEVICE_TABLE(spi, st7789v_spi_id); + static const struct of_device_id st7789v_of_match[] = { - { .compatible = "sitronix,st7789v" }, + { .compatible = "sitronix,st7789v", .data = &default_panel }, + { .compatible = "inanbo,t28cp45tn89-v17", .data = &t28cp45tn89_panel }, + { .compatible = "edt,et028013dma", .data = &et028013dma_panel }, + { .compatible = "jasonic,jt240mhqs-hwt-ek-e3", + .data = &jt240mhqs_hwt_ek_e3_panel }, { } }; MODULE_DEVICE_TABLE(of, st7789v_of_match); @@ -403,6 +679,7 @@ MODULE_DEVICE_TABLE(of, st7789v_of_match); static struct spi_driver st7789v_driver = { .probe = st7789v_probe, .remove = st7789v_remove, + .id_table = st7789v_spi_id, .driver = { .name = "st7789v", .of_match_table = st7789v_of_match, diff --git a/drivers/gpu/drm/panel/panel-sony-td4353-jdi.c b/drivers/gpu/drm/panel/panel-sony-td4353-jdi.c index 8d8813dbaa45..1bde2f01786b 100644 --- a/drivers/gpu/drm/panel/panel-sony-td4353-jdi.c +++ b/drivers/gpu/drm/panel/panel-sony-td4353-jdi.c @@ -14,7 +14,6 @@ #include <linux/gpio/consumer.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/regulator/consumer.h> #include <video/mipi_display.h> diff --git a/drivers/gpu/drm/panel/panel-startek-kd070fhfid015.c b/drivers/gpu/drm/panel/panel-startek-kd070fhfid015.c new file mode 100644 index 000000000000..6e77a2d71d81 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-startek-kd070fhfid015.c @@ -0,0 +1,406 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2016 InforceComputing + * Copyright (C) 2016 Linaro Ltd + * Copyright (C) 2023 BayLibre, SAS + * + * Authors: + * - Vinay Simha BN <[email protected]> + * - Sumit Semwal <[email protected]> + * - Guillaume La Roque <[email protected]> + * + */ + +#include <linux/backlight.h> +#include <linux/delay.h> +#include <linux/gpio/consumer.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/regulator/consumer.h> + +#include <video/mipi_display.h> + +#include <drm/drm_mipi_dsi.h> +#include <drm/drm_modes.h> +#include <drm/drm_panel.h> + +#define DSI_REG_MCAP 0xB0 +#define DSI_REG_IS 0xB3 /* Interface Setting */ +#define DSI_REG_IIS 0xB4 /* Interface ID Setting */ +#define DSI_REG_CTRL 0xB6 + +enum { + IOVCC = 0, + POWER = 1 +}; + +struct stk_panel { + bool prepared; + const struct drm_display_mode *mode; + struct backlight_device *backlight; + struct drm_panel base; + struct gpio_desc *enable_gpio; /* Power IC supply enable */ + struct gpio_desc *reset_gpio; /* External reset */ + struct mipi_dsi_device *dsi; + struct regulator_bulk_data supplies[2]; +}; + +static inline struct stk_panel *to_stk_panel(struct drm_panel *panel) +{ + return container_of(panel, struct stk_panel, base); +} + +static int stk_panel_init(struct stk_panel *stk) +{ + struct mipi_dsi_device *dsi = stk->dsi; + struct device *dev = &stk->dsi->dev; + int ret; + + ret = mipi_dsi_dcs_soft_reset(dsi); + if (ret < 0) { + dev_err(dev, "failed to mipi_dsi_dcs_soft_reset: %d\n", ret); + return ret; + } + mdelay(5); + + ret = mipi_dsi_dcs_exit_sleep_mode(dsi); + if (ret < 0) { + dev_err(dev, "failed to set exit sleep mode: %d\n", ret); + return ret; + } + msleep(120); + + mipi_dsi_generic_write_seq(dsi, DSI_REG_MCAP, 0x04); + + /* Interface setting, video mode */ + mipi_dsi_generic_write_seq(dsi, DSI_REG_IS, 0x14, 0x08, 0x00, 0x22, 0x00); + mipi_dsi_generic_write_seq(dsi, DSI_REG_IIS, 0x0C, 0x00); + mipi_dsi_generic_write_seq(dsi, DSI_REG_CTRL, 0x3A, 0xD3); + + ret = mipi_dsi_dcs_set_display_brightness(dsi, 0x77); + if (ret < 0) { + dev_err(dev, "failed to write display brightness: %d\n", ret); + return ret; + } + + mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY, + MIPI_DCS_WRITE_MEMORY_START); + + ret = mipi_dsi_dcs_set_pixel_format(dsi, 0x77); + if (ret < 0) { + dev_err(dev, "failed to set pixel format: %d\n", ret); + return ret; + } + + ret = mipi_dsi_dcs_set_column_address(dsi, 0, stk->mode->hdisplay - 1); + if (ret < 0) { + dev_err(dev, "failed to set column address: %d\n", ret); + return ret; + } + + ret = mipi_dsi_dcs_set_page_address(dsi, 0, stk->mode->vdisplay - 1); + if (ret < 0) { + dev_err(dev, "failed to set page address: %d\n", ret); + return ret; + } + + return 0; +} + +static int stk_panel_on(struct stk_panel *stk) +{ + struct mipi_dsi_device *dsi = stk->dsi; + struct device *dev = &stk->dsi->dev; + int ret; + + ret = mipi_dsi_dcs_set_display_on(dsi); + if (ret < 0) + dev_err(dev, "failed to set display on: %d\n", ret); + + mdelay(20); + + return ret; +} + +static void stk_panel_off(struct stk_panel *stk) +{ + struct mipi_dsi_device *dsi = stk->dsi; + struct device *dev = &stk->dsi->dev; + int ret; + + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + + ret = mipi_dsi_dcs_set_display_off(dsi); + if (ret < 0) + dev_err(dev, "failed to set display off: %d\n", ret); + + ret = mipi_dsi_dcs_enter_sleep_mode(dsi); + if (ret < 0) + dev_err(dev, "failed to enter sleep mode: %d\n", ret); + + msleep(100); +} + +static int stk_panel_unprepare(struct drm_panel *panel) +{ + struct stk_panel *stk = to_stk_panel(panel); + + if (!stk->prepared) + return 0; + + stk_panel_off(stk); + regulator_bulk_disable(ARRAY_SIZE(stk->supplies), stk->supplies); + gpiod_set_value(stk->reset_gpio, 0); + gpiod_set_value(stk->enable_gpio, 1); + + stk->prepared = false; + + return 0; +} + +static int stk_panel_prepare(struct drm_panel *panel) +{ + struct stk_panel *stk = to_stk_panel(panel); + struct device *dev = &stk->dsi->dev; + int ret; + + if (stk->prepared) + return 0; + + gpiod_set_value(stk->reset_gpio, 0); + gpiod_set_value(stk->enable_gpio, 0); + ret = regulator_enable(stk->supplies[IOVCC].consumer); + if (ret < 0) + return ret; + + mdelay(8); + ret = regulator_enable(stk->supplies[POWER].consumer); + if (ret < 0) + goto iovccoff; + + mdelay(20); + gpiod_set_value(stk->enable_gpio, 1); + mdelay(20); + gpiod_set_value(stk->reset_gpio, 1); + mdelay(10); + ret = stk_panel_init(stk); + if (ret < 0) { + dev_err(dev, "failed to init panel: %d\n", ret); + goto poweroff; + } + + ret = stk_panel_on(stk); + if (ret < 0) { + dev_err(dev, "failed to set panel on: %d\n", ret); + goto poweroff; + } + + stk->prepared = true; + + return 0; + +poweroff: + regulator_disable(stk->supplies[POWER].consumer); +iovccoff: + regulator_disable(stk->supplies[IOVCC].consumer); + gpiod_set_value(stk->reset_gpio, 0); + gpiod_set_value(stk->enable_gpio, 0); + + return ret; +} + +static const struct drm_display_mode default_mode = { + .clock = 163204, + .hdisplay = 1200, + .hsync_start = 1200 + 144, + .hsync_end = 1200 + 144 + 16, + .htotal = 1200 + 144 + 16 + 45, + .vdisplay = 1920, + .vsync_start = 1920 + 8, + .vsync_end = 1920 + 8 + 4, + .vtotal = 1920 + 8 + 4 + 4, + .width_mm = 95, + .height_mm = 151, +}; + +static int stk_panel_get_modes(struct drm_panel *panel, + struct drm_connector *connector) +{ + struct drm_display_mode *mode; + + mode = drm_mode_duplicate(connector->dev, &default_mode); + if (!mode) { + dev_err(panel->dev, "failed to add mode %ux%ux@%u\n", + default_mode.hdisplay, default_mode.vdisplay, + drm_mode_vrefresh(&default_mode)); + return -ENOMEM; + } + + drm_mode_set_name(mode); + drm_mode_probed_add(connector, mode); + connector->display_info.width_mm = default_mode.width_mm; + connector->display_info.height_mm = default_mode.height_mm; + return 1; +} + +static int dsi_dcs_bl_get_brightness(struct backlight_device *bl) +{ + struct mipi_dsi_device *dsi = bl_get_data(bl); + int ret; + u16 brightness; + + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + ret = mipi_dsi_dcs_get_display_brightness(dsi, &brightness); + if (ret < 0) + return ret; + + dsi->mode_flags |= MIPI_DSI_MODE_LPM; + return brightness & 0xff; +} + +static int dsi_dcs_bl_update_status(struct backlight_device *bl) +{ + struct mipi_dsi_device *dsi = bl_get_data(bl); + struct device *dev = &dsi->dev; + int ret; + + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + ret = mipi_dsi_dcs_set_display_brightness(dsi, bl->props.brightness); + if (ret < 0) { + dev_err(dev, "failed to set DSI control: %d\n", ret); + return ret; + } + + dsi->mode_flags |= MIPI_DSI_MODE_LPM; + return 0; +} + +static const struct backlight_ops dsi_bl_ops = { + .update_status = dsi_dcs_bl_update_status, + .get_brightness = dsi_dcs_bl_get_brightness, +}; + +static struct backlight_device * +drm_panel_create_dsi_backlight(struct mipi_dsi_device *dsi) +{ + struct device *dev = &dsi->dev; + struct backlight_properties props = { + .type = BACKLIGHT_RAW, + .brightness = 255, + .max_brightness = 255, + }; + + return devm_backlight_device_register(dev, dev_name(dev), dev, dsi, + &dsi_bl_ops, &props); +} + +static const struct drm_panel_funcs stk_panel_funcs = { + .unprepare = stk_panel_unprepare, + .prepare = stk_panel_prepare, + .get_modes = stk_panel_get_modes, +}; + +static const struct of_device_id stk_of_match[] = { + { .compatible = "startek,kd070fhfid015", }, + { } +}; +MODULE_DEVICE_TABLE(of, stk_of_match); + +static int stk_panel_add(struct stk_panel *stk) +{ + struct device *dev = &stk->dsi->dev; + int ret; + + stk->mode = &default_mode; + + stk->supplies[IOVCC].supply = "iovcc"; + stk->supplies[POWER].supply = "power"; + ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(stk->supplies), stk->supplies); + if (ret) { + dev_err(dev, "regulator_bulk failed\n"); + return ret; + } + + stk->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(stk->reset_gpio)) { + ret = PTR_ERR(stk->reset_gpio); + dev_err(dev, "cannot get reset-gpios %d\n", ret); + return ret; + } + + stk->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW); + if (IS_ERR(stk->enable_gpio)) { + ret = PTR_ERR(stk->enable_gpio); + dev_err(dev, "cannot get enable-gpio %d\n", ret); + return ret; + } + + stk->backlight = drm_panel_create_dsi_backlight(stk->dsi); + if (IS_ERR(stk->backlight)) { + ret = PTR_ERR(stk->backlight); + dev_err(dev, "failed to register backlight %d\n", ret); + return ret; + } + + drm_panel_init(&stk->base, &stk->dsi->dev, &stk_panel_funcs, + DRM_MODE_CONNECTOR_DSI); + + drm_panel_add(&stk->base); + + return 0; +} + +static int stk_panel_probe(struct mipi_dsi_device *dsi) +{ + struct stk_panel *stk; + int ret; + + dsi->lanes = 4; + dsi->format = MIPI_DSI_FMT_RGB888; + dsi->mode_flags = (MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_LPM); + + stk = devm_kzalloc(&dsi->dev, sizeof(*stk), GFP_KERNEL); + if (!stk) + return -ENOMEM; + + mipi_dsi_set_drvdata(dsi, stk); + + stk->dsi = dsi; + + ret = stk_panel_add(stk); + if (ret < 0) + return ret; + + ret = mipi_dsi_attach(dsi); + if (ret < 0) + drm_panel_remove(&stk->base); + + return 0; +} + +static void stk_panel_remove(struct mipi_dsi_device *dsi) +{ + struct stk_panel *stk = mipi_dsi_get_drvdata(dsi); + int err; + + err = mipi_dsi_detach(dsi); + if (err < 0) + dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", + err); + + drm_panel_remove(&stk->base); +} + +static struct mipi_dsi_driver stk_panel_driver = { + .driver = { + .name = "panel-startek-kd070fhfid015", + .of_match_table = stk_of_match, + }, + .probe = stk_panel_probe, + .remove = stk_panel_remove, +}; +module_mipi_dsi_driver(stk_panel_driver); + +MODULE_AUTHOR("Guillaume La Roque <[email protected]>"); +MODULE_DESCRIPTION("STARTEK KD070FHFID015"); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/panel/panel-truly-nt35597.c b/drivers/gpu/drm/panel/panel-truly-nt35597.c index b31cffb660a7..4f4009f9fe25 100644 --- a/drivers/gpu/drm/panel/panel-truly-nt35597.c +++ b/drivers/gpu/drm/panel/panel-truly-nt35597.c @@ -7,7 +7,7 @@ #include <linux/delay.h> #include <linux/gpio/consumer.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/of_graph.h> #include <linux/pinctrl/consumer.h> #include <linux/regulator/consumer.h> diff --git a/drivers/gpu/drm/panel/panel-visionox-r66451.c b/drivers/gpu/drm/panel/panel-visionox-r66451.c new file mode 100644 index 000000000000..00fc28ad3d07 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-visionox-r66451.c @@ -0,0 +1,390 @@ +//SPDX-License-Identifier: GPL-2.0-only +//Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + +#include <linux/backlight.h> +#include <linux/delay.h> +#include <linux/gpio/consumer.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/regulator/consumer.h> + +#include <drm/drm_mipi_dsi.h> +#include <drm/drm_probe_helper.h> +#include <drm/drm_modes.h> +#include <drm/drm_panel.h> +#include <drm/display/drm_dsc.h> +#include <drm/display/drm_dsc_helper.h> + +#include <video/mipi_display.h> + +struct visionox_r66451 { + struct drm_panel panel; + struct mipi_dsi_device *dsi; + struct gpio_desc *reset_gpio; + struct regulator_bulk_data supplies[2]; + bool prepared, enabled; +}; + +static inline struct visionox_r66451 *to_visionox_r66451(struct drm_panel *panel) +{ + return container_of(panel, struct visionox_r66451, panel); +} + +static void visionox_r66451_reset(struct visionox_r66451 *ctx) +{ + gpiod_set_value_cansleep(ctx->reset_gpio, 0); + usleep_range(10000, 10100); + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + usleep_range(10000, 10100); + gpiod_set_value_cansleep(ctx->reset_gpio, 0); + usleep_range(10000, 10100); +} + +static int visionox_r66451_on(struct visionox_r66451 *ctx) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + + dsi->mode_flags |= MIPI_DSI_MODE_LPM; + + mipi_dsi_dcs_write_seq(dsi, 0xb0, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0xc2, + 0x09, 0x24, 0x0c, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x09, 0x3c); + mipi_dsi_dcs_write_seq(dsi, 0xd7, + 0x00, 0xb9, 0x3c, 0x00, 0x40, 0x04, 0x00, 0xa0, 0x0a, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, + 0x3c, 0x00, 0x40, 0x04, 0x00, 0xa0, 0x0a); + mipi_dsi_dcs_write_seq(dsi, 0xb0, 0x80); + mipi_dsi_dcs_write_seq(dsi, 0xde, + 0x40, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, + 0x10, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x02, 0x00, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0xb0, 0x04); + mipi_dsi_dcs_write_seq(dsi, 0xe8, 0x00, 0x02); + mipi_dsi_dcs_write_seq(dsi, 0xe4, 0x00, 0x08); + mipi_dsi_dcs_write_seq(dsi, 0xb0, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0xc4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x32); + mipi_dsi_dcs_write_seq(dsi, 0xcf, + 0x64, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x0b, 0x77, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x03); + mipi_dsi_dcs_write_seq(dsi, 0xd3, + 0x45, 0x00, 0x00, 0x01, 0x13, 0x15, 0x00, 0x15, 0x07, + 0x0f, 0x77, 0x77, 0x77, 0x37, 0xb2, 0x11, 0x00, 0xa0, + 0x3c, 0x9c); + mipi_dsi_dcs_write_seq(dsi, 0xd7, + 0x00, 0xb9, 0x34, 0x00, 0x40, 0x04, 0x00, 0xa0, 0x0a, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, + 0x34, 0x00, 0x40, 0x04, 0x00, 0xa0, 0x0a); + mipi_dsi_dcs_write_seq(dsi, 0xd8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3a, 0x00, 0x3a, 0x00, 0x3a, 0x00, 0x3a, 0x00, 0x3a, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, + 0x00, 0x32, 0x00, 0x0a, 0x00, 0x22); + mipi_dsi_dcs_write_seq(dsi, 0xdf, + 0x50, 0x42, 0x58, 0x81, 0x2d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x0f, 0xff, 0xd4, 0x0e, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0f, 0x53, 0xf1, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0xf7, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0xb0, 0x80); + mipi_dsi_dcs_write_seq(dsi, 0xe4, 0x34, 0xb4, 0x00, 0x00, 0x00, 0x39, 0x04, 0x09, 0x34); + mipi_dsi_dcs_write_seq(dsi, 0xe6, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0xb0, 0x04); + mipi_dsi_dcs_write_seq(dsi, 0xdf, 0x50, 0x40); + mipi_dsi_dcs_write_seq(dsi, 0xf3, 0x50, 0x00, 0x00, 0x00, 0x00); + mipi_dsi_dcs_write_seq(dsi, 0xf2, 0x11); + mipi_dsi_dcs_write_seq(dsi, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x01); + mipi_dsi_dcs_write_seq(dsi, 0xf4, 0x00, 0x02); + mipi_dsi_dcs_write_seq(dsi, 0xf2, 0x19); + mipi_dsi_dcs_write_seq(dsi, 0xdf, 0x50, 0x42); + mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK); + mipi_dsi_dcs_set_column_address(dsi, 0, 1080 - 1); + mipi_dsi_dcs_set_page_address(dsi, 0, 2340 - 1); + + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + + return 0; +} + +static int visionox_r66451_off(struct visionox_r66451 *ctx) +{ + ctx->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + return 0; +} + +static int visionox_r66451_prepare(struct drm_panel *panel) +{ + struct visionox_r66451 *ctx = to_visionox_r66451(panel); + struct mipi_dsi_device *dsi = ctx->dsi; + struct device *dev = &dsi->dev; + int ret; + + if (ctx->prepared) + return 0; + + ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), + ctx->supplies); + if (ret < 0) + return ret; + + visionox_r66451_reset(ctx); + + ret = visionox_r66451_on(ctx); + if (ret < 0) { + dev_err(dev, "Failed to initialize panel: %d\n", ret); + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies); + return ret; + } + + mipi_dsi_compression_mode(ctx->dsi, true); + + ctx->prepared = true; + return 0; +} + +static int visionox_r66451_unprepare(struct drm_panel *panel) +{ + struct visionox_r66451 *ctx = to_visionox_r66451(panel); + struct device *dev = &ctx->dsi->dev; + int ret; + + if (!ctx->prepared) + return 0; + + ret = visionox_r66451_off(ctx); + if (ret < 0) + dev_err(dev, "Failed to un-initialize panel: %d\n", ret); + + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies); + + ctx->prepared = false; + return 0; +} + +static const struct drm_display_mode visionox_r66451_mode = { + .clock = 345830, + .hdisplay = 1080, + .hsync_start = 1175, + .hsync_end = 1176, + .htotal = 1216, + .vdisplay = 2340, + .vsync_start = 2365, + .vsync_end = 2366, + .vtotal = 2370, + .width_mm = 0, + .height_mm = 0, + .type = DRM_MODE_TYPE_DRIVER, +}; + +static int visionox_r66451_enable(struct drm_panel *panel) +{ + struct visionox_r66451 *ctx = to_visionox_r66451(panel); + struct mipi_dsi_device *dsi = ctx->dsi; + struct drm_dsc_picture_parameter_set pps; + int ret; + + if (ctx->enabled) + return 0; + + if (!dsi->dsc) { + dev_err(&dsi->dev, "DSC not attached to DSI\n"); + return -ENODEV; + } + + drm_dsc_pps_payload_pack(&pps, dsi->dsc); + ret = mipi_dsi_picture_parameter_set(dsi, &pps); + if (ret) { + dev_err(&dsi->dev, "Failed to set PPS\n"); + return ret; + } + + ret = mipi_dsi_dcs_exit_sleep_mode(dsi); + if (ret < 0) { + dev_err(&dsi->dev, "Failed to exit sleep mode: %d\n", ret); + return ret; + } + msleep(120); + + ret = mipi_dsi_dcs_set_display_on(dsi); + if (ret < 0) { + dev_err(&dsi->dev, "Failed on set display on: %d\n", ret); + return ret; + } + msleep(20); + + ctx->enabled = true; + + return 0; +} + +static int visionox_r66451_disable(struct drm_panel *panel) +{ + struct visionox_r66451 *ctx = to_visionox_r66451(panel); + struct mipi_dsi_device *dsi = ctx->dsi; + struct device *dev = &dsi->dev; + int ret; + + ctx->enabled = false; + + ret = mipi_dsi_dcs_set_display_off(dsi); + if (ret < 0) { + dev_err(dev, "Failed to set display off: %d\n", ret); + return ret; + } + msleep(20); + + ret = mipi_dsi_dcs_enter_sleep_mode(dsi); + if (ret < 0) { + dev_err(dev, "Failed to enter sleep mode: %d\n", ret); + return ret; + } + msleep(120); + + return 0; +} + +static int visionox_r66451_get_modes(struct drm_panel *panel, + struct drm_connector *connector) +{ + drm_connector_helper_get_modes_fixed(connector, &visionox_r66451_mode); + return 1; +} + +static const struct drm_panel_funcs visionox_r66451_funcs = { + .prepare = visionox_r66451_prepare, + .unprepare = visionox_r66451_unprepare, + .get_modes = visionox_r66451_get_modes, + .enable = visionox_r66451_enable, + .disable = visionox_r66451_disable, +}; + +static int visionox_r66451_bl_update_status(struct backlight_device *bl) +{ + struct mipi_dsi_device *dsi = bl_get_data(bl); + u16 brightness = backlight_get_brightness(bl); + + return mipi_dsi_dcs_set_display_brightness(dsi, brightness); +} + +static const struct backlight_ops visionox_r66451_bl_ops = { + .update_status = visionox_r66451_bl_update_status, +}; + +static struct backlight_device * +visionox_r66451_create_backlight(struct mipi_dsi_device *dsi) +{ + struct device *dev = &dsi->dev; + const struct backlight_properties props = { + .type = BACKLIGHT_RAW, + .brightness = 255, + .max_brightness = 4095, + }; + + return devm_backlight_device_register(dev, dev_name(dev), dev, dsi, + &visionox_r66451_bl_ops, &props); +} + +static int visionox_r66451_probe(struct mipi_dsi_device *dsi) +{ + struct device *dev = &dsi->dev; + struct visionox_r66451 *ctx; + struct drm_dsc_config *dsc; + int ret = 0; + + ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return -ENOMEM; + + dsc = devm_kzalloc(dev, sizeof(*dsc), GFP_KERNEL); + if (!dsc) + return -ENOMEM; + + /* Set DSC params */ + dsc->dsc_version_major = 0x1; + dsc->dsc_version_minor = 0x2; + + dsc->slice_height = 20; + dsc->slice_width = 540; + dsc->slice_count = 2; + dsc->bits_per_component = 8; + dsc->bits_per_pixel = 8 << 4; + dsc->block_pred_enable = true; + + dsi->dsc = dsc; + + ctx->supplies[0].supply = "vddio"; + ctx->supplies[1].supply = "vdd"; + + ret = devm_regulator_bulk_get(&dsi->dev, ARRAY_SIZE(ctx->supplies), + ctx->supplies); + + if (ret < 0) + return ret; + + ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(ctx->reset_gpio)) + return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio), "Failed to get reset-gpios\n"); + + ctx->dsi = dsi; + mipi_dsi_set_drvdata(dsi, ctx); + + dsi->lanes = 4; + dsi->format = MIPI_DSI_FMT_RGB888; + dsi->mode_flags = MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS; + + drm_panel_init(&ctx->panel, dev, &visionox_r66451_funcs, DRM_MODE_CONNECTOR_DSI); + ctx->panel.backlight = visionox_r66451_create_backlight(dsi); + if (IS_ERR(ctx->panel.backlight)) + return dev_err_probe(dev, PTR_ERR(ctx->panel.backlight), + "Failed to create backlight\n"); + + drm_panel_add(&ctx->panel); + + ret = mipi_dsi_attach(dsi); + if (ret < 0) { + dev_err(dev, "Failed to attach to DSI host: %d\n", ret); + drm_panel_remove(&ctx->panel); + } + + return ret; +} + +static void visionox_r66451_remove(struct mipi_dsi_device *dsi) +{ + struct visionox_r66451 *ctx = mipi_dsi_get_drvdata(dsi); + int ret; + + ret = mipi_dsi_detach(dsi); + if (ret < 0) + dev_err(&dsi->dev, "Failed to detach DSI host: %d\n", ret); + + drm_panel_remove(&ctx->panel); +} + +static const struct of_device_id visionox_r66451_of_match[] = { + {.compatible = "visionox,r66451"}, + { /*sentinel*/ } +}; +MODULE_DEVICE_TABLE(of, visionox_r66451_of_match); + +static struct mipi_dsi_driver visionox_r66451_driver = { + .probe = visionox_r66451_probe, + .remove = visionox_r66451_remove, + .driver = { + .name = "panel-visionox-r66451", + .of_match_table = visionox_r66451_of_match, + }, +}; + +module_mipi_dsi_driver(visionox_r66451_driver); + +MODULE_AUTHOR("Jessica Zhang <[email protected]>"); +MODULE_DESCRIPTION("Panel driver for the Visionox R66451 AMOLED DSI panel"); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/panel/panel-visionox-rm69299.c b/drivers/gpu/drm/panel/panel-visionox-rm69299.c index ec228c269146..c2806e4fd553 100644 --- a/drivers/gpu/drm/panel/panel-visionox-rm69299.c +++ b/drivers/gpu/drm/panel/panel-visionox-rm69299.c @@ -5,7 +5,7 @@ #include <linux/delay.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/mod_devicetable.h> #include <linux/gpio/consumer.h> #include <linux/regulator/consumer.h> |