summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/panel
diff options
context:
space:
mode:
authorMaxime Ripard <maxime@cerno.tech>2022-04-05 12:37:03 +0300
committerMaxime Ripard <maxime@cerno.tech>2022-04-05 12:37:03 +0300
commitcf5c5763eb531ff5120111ad300126e926fb5a56 (patch)
tree41e3d49ad46f08fd6025264451390c7dc204303a /drivers/gpu/drm/panel
parent8047f98c8958d0f0c29882298ec293ff09ffea92 (diff)
parent3123109284176b1532874591f7c81f3837bbdc17 (diff)
downloadlinux-cf5c5763eb531ff5120111ad300126e926fb5a56.tar.xz
Merge drm/drm-fixes into drm-misc-fixes
Let's start the 5.18 fixes cycle. Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Diffstat (limited to 'drivers/gpu/drm/panel')
-rw-r--r--drivers/gpu/drm/panel/Kconfig23
-rw-r--r--drivers/gpu/drm/panel/Makefile2
-rw-r--r--drivers/gpu/drm/panel/panel-abt-y030xx067a.c4
-rw-r--r--drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c8
-rw-r--r--drivers/gpu/drm/panel/panel-edp.c102
-rw-r--r--drivers/gpu/drm/panel/panel-ilitek-ili9322.c4
-rw-r--r--drivers/gpu/drm/panel/panel-ilitek-ili9341.c3
-rw-r--r--drivers/gpu/drm/panel/panel-innolux-ej030na.c4
-rw-r--r--drivers/gpu/drm/panel/panel-lg-lb035q02.c4
-rw-r--r--drivers/gpu/drm/panel/panel-lg-lg4573.c4
-rw-r--r--drivers/gpu/drm/panel/panel-nec-nl8048hl11.c4
-rw-r--r--drivers/gpu/drm/panel/panel-novatek-nt35560.c561
-rw-r--r--drivers/gpu/drm/panel/panel-novatek-nt39016.c4
-rw-r--r--drivers/gpu/drm/panel/panel-samsung-atna33xc20.c4
-rw-r--r--drivers/gpu/drm/panel/panel-samsung-db7430.c3
-rw-r--r--drivers/gpu/drm/panel/panel-samsung-ld9040.c4
-rw-r--r--drivers/gpu/drm/panel/panel-samsung-s6d27a1.c3
-rw-r--r--drivers/gpu/drm/panel/panel-samsung-s6e63m0-spi.c3
-rw-r--r--drivers/gpu/drm/panel/panel-simple.c34
-rw-r--r--drivers/gpu/drm/panel/panel-sitronix-st7789v.c4
-rw-r--r--drivers/gpu/drm/panel/panel-sony-acx424akp.c490
-rw-r--r--drivers/gpu/drm/panel/panel-sony-acx565akm.c4
-rw-r--r--drivers/gpu/drm/panel/panel-tpo-td028ttec1.c4
-rw-r--r--drivers/gpu/drm/panel/panel-tpo-td043mtea1.c4
-rw-r--r--drivers/gpu/drm/panel/panel-tpo-tpg110.c3
-rw-r--r--drivers/gpu/drm/panel/panel-widechips-ws2401.c3
26 files changed, 727 insertions, 563 deletions
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 9989a316fe88..ddf5f38e8731 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -294,6 +294,18 @@ config DRM_PANEL_NOVATEK_NT35510
around the Novatek NT35510 display controller, such as some
Hydis panels.
+config DRM_PANEL_NOVATEK_NT35560
+ tristate "Novatek NT35560 DSI command mode panel"
+ depends on OF
+ depends on DRM_MIPI_DSI
+ depends on BACKLIGHT_CLASS_DEVICE
+ select VIDEOMODE_HELPERS
+ help
+ Say Y here if you want to enable the Novatek NT35560 display
+ controller. This panel supports DSI in both command and video
+ mode. This supports several panels such as Sony ACX424AKM and
+ ACX424AKP.
+
config DRM_PANEL_NOVATEK_NT35950
tristate "Novatek NT35950 DSI panel"
depends on OF
@@ -594,17 +606,6 @@ config DRM_PANEL_SITRONIX_ST7789V
Say Y here if you want to enable support for the Sitronix
ST7789V controller for 240x320 LCD panels
-config DRM_PANEL_SONY_ACX424AKP
- tristate "Sony ACX424AKP DSI command mode panel"
- depends on OF
- depends on DRM_MIPI_DSI
- depends on BACKLIGHT_CLASS_DEVICE
- select VIDEOMODE_HELPERS
- help
- Say Y here if you want to enable the Sony ACX424 display
- panel. This panel supports DSI in both command and video
- mode.
-
config DRM_PANEL_SONY_ACX565AKM
tristate "Sony ACX565AKM panel"
depends on GPIOLIB && OF && SPI
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index d99fbbce49d1..5740911f637c 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_DRM_PANEL_LG_LB035Q02) += panel-lg-lb035q02.o
obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o
obj-$(CONFIG_DRM_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o
obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35510) += panel-novatek-nt35510.o
+obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35560) += panel-novatek-nt35560.o
obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35950) += panel-novatek-nt35950.o
obj-$(CONFIG_DRM_PANEL_NOVATEK_NT36672A) += panel-novatek-nt36672a.o
obj-$(CONFIG_DRM_PANEL_NOVATEK_NT39016) += panel-novatek-nt39016.o
@@ -60,7 +61,6 @@ obj-$(CONFIG_DRM_PANEL_SHARP_LS060T1SX01) += panel-sharp-ls060t1sx01.o
obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7701) += panel-sitronix-st7701.o
obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7703) += panel-sitronix-st7703.o
obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7789V) += panel-sitronix-st7789v.o
-obj-$(CONFIG_DRM_PANEL_SONY_ACX424AKP) += panel-sony-acx424akp.o
obj-$(CONFIG_DRM_PANEL_SONY_ACX565AKM) += panel-sony-acx565akm.o
obj-$(CONFIG_DRM_PANEL_SONY_TULIP_TRULY_NT35521) += panel-sony-tulip-truly-nt35521.o
obj-$(CONFIG_DRM_PANEL_TDO_TL070WSH30) += panel-tdo-tl070wsh30.o
diff --git a/drivers/gpu/drm/panel/panel-abt-y030xx067a.c b/drivers/gpu/drm/panel/panel-abt-y030xx067a.c
index f043b484055b..ed626fdc08e8 100644
--- a/drivers/gpu/drm/panel/panel-abt-y030xx067a.c
+++ b/drivers/gpu/drm/panel/panel-abt-y030xx067a.c
@@ -293,15 +293,13 @@ static int y030xx067a_probe(struct spi_device *spi)
return 0;
}
-static int y030xx067a_remove(struct spi_device *spi)
+static void y030xx067a_remove(struct spi_device *spi)
{
struct y030xx067a *priv = spi_get_drvdata(spi);
drm_panel_remove(&priv->panel);
drm_panel_disable(&priv->panel);
drm_panel_unprepare(&priv->panel);
-
- return 0;
}
static const struct drm_display_mode y030xx067a_modes[] = {
diff --git a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
index 5fcbde789ddb..1be150ac758f 100644
--- a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
+++ b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
@@ -86,7 +86,7 @@ static const struct panel_init_cmd boe_tv110c9m_init_cmd[] = {
_INIT_DCS_CMD(0x0F, 0x73),
_INIT_DCS_CMD(0x95, 0xE6),
_INIT_DCS_CMD(0x96, 0xF0),
- _INIT_DCS_CMD(0x30, 0x11),
+ _INIT_DCS_CMD(0x30, 0x00),
_INIT_DCS_CMD(0x6D, 0x66),
_INIT_DCS_CMD(0x75, 0xA2),
_INIT_DCS_CMD(0x77, 0x3B),
@@ -112,17 +112,17 @@ static const struct panel_init_cmd boe_tv110c9m_init_cmd[] = {
_INIT_DCS_CMD(0xB1, 0x00, 0xD2, 0x01, 0x0B, 0x01, 0x34, 0x01, 0x76, 0x01, 0xA3, 0x01, 0xEF, 0x02, 0x27, 0x02, 0x29),
_INIT_DCS_CMD(0xB2, 0x02, 0x5F, 0x02, 0x9E, 0x02, 0xC9, 0x03, 0x00, 0x03, 0x26, 0x03, 0x53, 0x03, 0x63, 0x03, 0x73),
- _INIT_DCS_CMD(0xB3, 0x03, 0x86, 0x03, 0x9A, 0x03, 0xA7, 0x03, 0xCF, 0x03, 0xDE, 0x03, 0xE0),
+ _INIT_DCS_CMD(0xB3, 0x03, 0x86, 0x03, 0x9A, 0x03, 0xAF, 0x03, 0xDF, 0x03, 0xF5, 0x03, 0xE0),
_INIT_DCS_CMD(0xB4, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x45, 0x00, 0x65, 0x00, 0x81, 0x00, 0x99, 0x00, 0xAE, 0x00, 0xC1),
_INIT_DCS_CMD(0xB5, 0x00, 0xD2, 0x01, 0x0B, 0x01, 0x34, 0x01, 0x76, 0x01, 0xA3, 0x01, 0xEF, 0x02, 0x27, 0x02, 0x29),
_INIT_DCS_CMD(0xB6, 0x02, 0x5F, 0x02, 0x9E, 0x02, 0xC9, 0x03, 0x00, 0x03, 0x26, 0x03, 0x53, 0x03, 0x63, 0x03, 0x73),
- _INIT_DCS_CMD(0xB7, 0x03, 0x86, 0x03, 0x9A, 0x03, 0xA7, 0x03, 0xCF, 0x03, 0xDE, 0x03, 0xE0),
+ _INIT_DCS_CMD(0xB7, 0x03, 0x86, 0x03, 0x9A, 0x03, 0xAF, 0x03, 0xDF, 0x03, 0xF5, 0x03, 0xE0),
_INIT_DCS_CMD(0xB8, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x45, 0x00, 0x65, 0x00, 0x81, 0x00, 0x99, 0x00, 0xAE, 0x00, 0xC1),
_INIT_DCS_CMD(0xB9, 0x00, 0xD2, 0x01, 0x0B, 0x01, 0x34, 0x01, 0x76, 0x01, 0xA3, 0x01, 0xEF, 0x02, 0x27, 0x02, 0x29),
_INIT_DCS_CMD(0xBA, 0x02, 0x5F, 0x02, 0x9E, 0x02, 0xC9, 0x03, 0x00, 0x03, 0x26, 0x03, 0x53, 0x03, 0x63, 0x03, 0x73),
- _INIT_DCS_CMD(0xBB, 0x03, 0x86, 0x03, 0x9A, 0x03, 0xA7, 0x03, 0xCF, 0x03, 0xDE, 0x03, 0xE0),
+ _INIT_DCS_CMD(0xBB, 0x03, 0x86, 0x03, 0x9A, 0x03, 0xAF, 0x03, 0xDF, 0x03, 0xF5, 0x03, 0xE0),
_INIT_DCS_CMD(0xFF, 0x24),
_INIT_DCS_CMD(0xFB, 0x01),
diff --git a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/panel-edp.c
index 176ef0c3cc1d..f7bfcf63d48e 100644
--- a/drivers/gpu/drm/panel/panel-edp.c
+++ b/drivers/gpu/drm/panel/panel-edp.c
@@ -21,6 +21,7 @@
* DEALINGS IN THE SOFTWARE.
*/
+#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/iopoll.h>
@@ -36,8 +37,8 @@
#include <drm/drm_crtc.h>
#include <drm/drm_device.h>
-#include <drm/drm_dp_aux_bus.h>
-#include <drm/drm_dp_helper.h>
+#include <drm/dp/drm_dp_aux_bus.h>
+#include <drm/dp/drm_dp_helper.h>
#include <drm/drm_panel.h>
/**
@@ -222,6 +223,8 @@ struct panel_edp {
struct gpio_desc *enable_gpio;
struct gpio_desc *hpd_gpio;
+ const struct edp_panel_entry *detected_panel;
+
struct edid *edid;
struct drm_display_mode override_mode;
@@ -606,6 +609,28 @@ static int panel_edp_get_timings(struct drm_panel *panel,
return p->desc->num_timings;
}
+static int detected_panel_show(struct seq_file *s, void *data)
+{
+ struct drm_panel *panel = s->private;
+ struct panel_edp *p = to_panel_edp(panel);
+
+ if (IS_ERR(p->detected_panel))
+ seq_puts(s, "UNKNOWN\n");
+ else if (!p->detected_panel)
+ seq_puts(s, "HARDCODED\n");
+ else
+ seq_printf(s, "%s\n", p->detected_panel->name);
+
+ return 0;
+}
+
+DEFINE_SHOW_ATTRIBUTE(detected_panel);
+
+static void panel_edp_debugfs_init(struct drm_panel *panel, struct dentry *root)
+{
+ debugfs_create_file("detected_panel", 0600, root, panel, &detected_panel_fops);
+}
+
static const struct drm_panel_funcs panel_edp_funcs = {
.disable = panel_edp_disable,
.unprepare = panel_edp_unprepare,
@@ -613,6 +638,7 @@ static const struct drm_panel_funcs panel_edp_funcs = {
.enable = panel_edp_enable,
.get_modes = panel_edp_get_modes,
.get_timings = panel_edp_get_timings,
+ .debugfs_init = panel_edp_debugfs_init,
};
#define PANEL_EDP_BOUNDS_CHECK(to_check, bounds, field) \
@@ -666,7 +692,6 @@ static const struct edp_panel_entry *find_edp_panel(u32 panel_id);
static int generic_edp_panel_probe(struct device *dev, struct panel_edp *panel)
{
- const struct edp_panel_entry *edp_panel;
struct panel_desc *desc;
u32 panel_id;
char vend[4];
@@ -705,14 +730,14 @@ static int generic_edp_panel_probe(struct device *dev, struct panel_edp *panel)
}
drm_edid_decode_panel_id(panel_id, vend, &product_id);
- edp_panel = find_edp_panel(panel_id);
+ panel->detected_panel = find_edp_panel(panel_id);
/*
* We're using non-optimized timings and want it really obvious that
* someone needs to add an entry to the table, so we'll do a WARN_ON
* splat.
*/
- if (WARN_ON(!edp_panel)) {
+ if (WARN_ON(!panel->detected_panel)) {
dev_warn(dev,
"Unknown panel %s %#06x, using conservative timings\n",
vend, product_id);
@@ -734,12 +759,14 @@ static int generic_edp_panel_probe(struct device *dev, struct panel_edp *panel)
*/
desc->delay.unprepare = 2000;
desc->delay.enable = 200;
+
+ panel->detected_panel = ERR_PTR(-EINVAL);
} else {
dev_info(dev, "Detected %s %s (%#06x)\n",
- vend, edp_panel->name, product_id);
+ vend, panel->detected_panel->name, product_id);
/* Update the delay; everything else comes from EDID */
- desc->delay = *edp_panel->delay;
+ desc->delay = *panel->detected_panel->delay;
}
ret = 0;
@@ -1605,6 +1632,47 @@ static const struct panel_desc sharp_lq123p1jx31 = {
},
};
+static const struct drm_display_mode sharp_lq140m1jw46_mode[] = {
+ {
+ .clock = 346500,
+ .hdisplay = 1920,
+ .hsync_start = 1920 + 48,
+ .hsync_end = 1920 + 48 + 32,
+ .htotal = 1920 + 48 + 32 + 80,
+ .vdisplay = 1080,
+ .vsync_start = 1080 + 3,
+ .vsync_end = 1080 + 3 + 5,
+ .vtotal = 1080 + 3 + 5 + 69,
+ .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
+ }, {
+ .clock = 144370,
+ .hdisplay = 1920,
+ .hsync_start = 1920 + 48,
+ .hsync_end = 1920 + 48 + 32,
+ .htotal = 1920 + 48 + 32 + 80,
+ .vdisplay = 1080,
+ .vsync_start = 1080 + 3,
+ .vsync_end = 1080 + 3 + 5,
+ .vtotal = 1080 + 3 + 5 + 69,
+ .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
+ },
+};
+
+static const struct panel_desc sharp_lq140m1jw46 = {
+ .modes = sharp_lq140m1jw46_mode,
+ .num_modes = ARRAY_SIZE(sharp_lq140m1jw46_mode),
+ .bpc = 8,
+ .size = {
+ .width = 309,
+ .height = 174,
+ },
+ .delay = {
+ .hpd_absent = 80,
+ .enable = 50,
+ .unprepare = 500,
+ },
+};
+
static const struct drm_display_mode starry_kr122ea0sra_mode = {
.clock = 147000,
.hdisplay = 1920,
@@ -1719,6 +1787,9 @@ static const struct of_device_id platform_of_match[] = {
.compatible = "sharp,lq123p1jx31",
.data = &sharp_lq123p1jx31,
}, {
+ .compatible = "sharp,lq140m1jw46",
+ .data = &sharp_lq140m1jw46,
+ }, {
.compatible = "starry,kr122ea0sra",
.data = &starry_kr122ea0sra,
}, {
@@ -1745,6 +1816,19 @@ static const struct panel_delay delay_200_500_e50 = {
.enable = 50,
};
+static const struct panel_delay delay_200_500_e80_d50 = {
+ .hpd_absent = 200,
+ .unprepare = 500,
+ .enable = 80,
+ .disable = 50,
+};
+
+static const struct panel_delay delay_100_500_e200 = {
+ .hpd_absent = 100,
+ .unprepare = 500,
+ .enable = 200,
+};
+
#define EDP_PANEL_ENTRY(vend_chr_0, vend_chr_1, vend_chr_2, product_id, _delay, _name) \
{ \
.name = _name, \
@@ -1768,13 +1852,17 @@ static const struct edp_panel_entry edp_panels[] = {
EDP_PANEL_ENTRY('B', 'O', 'E', 0x07d1, &boe_nv133fhm_n61.delay, "NV133FHM-N61"),
EDP_PANEL_ENTRY('B', 'O', 'E', 0x082d, &boe_nv133fhm_n61.delay, "NV133FHM-N62"),
EDP_PANEL_ENTRY('B', 'O', 'E', 0x098d, &boe_nv110wtm_n61.delay, "NV110WTM-N61"),
+ EDP_PANEL_ENTRY('B', 'O', 'E', 0x0a5d, &delay_200_500_e50, "NV116WHM-N45"),
EDP_PANEL_ENTRY('C', 'M', 'N', 0x114c, &innolux_n116bca_ea1.delay, "N116BCA-EA1"),
EDP_PANEL_ENTRY('K', 'D', 'B', 0x0624, &kingdisplay_kd116n21_30nv_a010.delay, "116N21-30NV-A010"),
+ EDP_PANEL_ENTRY('K', 'D', 'B', 0x1120, &delay_200_500_e80_d50, "116N29-30NK-C007"),
EDP_PANEL_ENTRY('S', 'H', 'P', 0x154c, &delay_200_500_p2e100, "LQ116M1JW10"),
+ EDP_PANEL_ENTRY('S', 'T', 'A', 0x0100, &delay_100_500_e200, "2081116HHD028001-51D"),
+
{ /* sentinal */ }
};
diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9322.c b/drivers/gpu/drm/panel/panel-ilitek-ili9322.c
index 8e84df9a0033..3dfafa585127 100644
--- a/drivers/gpu/drm/panel/panel-ilitek-ili9322.c
+++ b/drivers/gpu/drm/panel/panel-ilitek-ili9322.c
@@ -896,14 +896,12 @@ static int ili9322_probe(struct spi_device *spi)
return 0;
}
-static int ili9322_remove(struct spi_device *spi)
+static void ili9322_remove(struct spi_device *spi)
{
struct ili9322 *ili = spi_get_drvdata(spi);
ili9322_power_off(ili);
drm_panel_remove(&ili->panel);
-
- return 0;
}
/*
diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c
index e1542451ef9d..6826f4d4826a 100644
--- a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c
+++ b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c
@@ -730,7 +730,7 @@ static int ili9341_probe(struct spi_device *spi)
return -1;
}
-static int ili9341_remove(struct spi_device *spi)
+static void ili9341_remove(struct spi_device *spi)
{
const struct spi_device_id *id = spi_get_device_id(spi);
struct ili9341 *ili = spi_get_drvdata(spi);
@@ -743,7 +743,6 @@ static int ili9341_remove(struct spi_device *spi)
drm_dev_unplug(drm);
drm_atomic_helper_shutdown(drm);
}
- return 0;
}
static void ili9341_shutdown(struct spi_device *spi)
diff --git a/drivers/gpu/drm/panel/panel-innolux-ej030na.c b/drivers/gpu/drm/panel/panel-innolux-ej030na.c
index c558de3f99be..e3b1daa0cb72 100644
--- a/drivers/gpu/drm/panel/panel-innolux-ej030na.c
+++ b/drivers/gpu/drm/panel/panel-innolux-ej030na.c
@@ -219,15 +219,13 @@ static int ej030na_probe(struct spi_device *spi)
return 0;
}
-static int ej030na_remove(struct spi_device *spi)
+static void ej030na_remove(struct spi_device *spi)
{
struct ej030na *priv = spi_get_drvdata(spi);
drm_panel_remove(&priv->panel);
drm_panel_disable(&priv->panel);
drm_panel_unprepare(&priv->panel);
-
- return 0;
}
static const struct drm_display_mode ej030na_modes[] = {
diff --git a/drivers/gpu/drm/panel/panel-lg-lb035q02.c b/drivers/gpu/drm/panel/panel-lg-lb035q02.c
index f3183b68704f..9d0d4faa3f58 100644
--- a/drivers/gpu/drm/panel/panel-lg-lb035q02.c
+++ b/drivers/gpu/drm/panel/panel-lg-lb035q02.c
@@ -203,14 +203,12 @@ static int lb035q02_probe(struct spi_device *spi)
return 0;
}
-static int lb035q02_remove(struct spi_device *spi)
+static void lb035q02_remove(struct spi_device *spi)
{
struct lb035q02_device *lcd = spi_get_drvdata(spi);
drm_panel_remove(&lcd->panel);
drm_panel_disable(&lcd->panel);
-
- return 0;
}
static const struct of_device_id lb035q02_of_match[] = {
diff --git a/drivers/gpu/drm/panel/panel-lg-lg4573.c b/drivers/gpu/drm/panel/panel-lg-lg4573.c
index 8e5160af1de5..cf246d15b7b6 100644
--- a/drivers/gpu/drm/panel/panel-lg-lg4573.c
+++ b/drivers/gpu/drm/panel/panel-lg-lg4573.c
@@ -266,14 +266,12 @@ static int lg4573_probe(struct spi_device *spi)
return 0;
}
-static int lg4573_remove(struct spi_device *spi)
+static void lg4573_remove(struct spi_device *spi)
{
struct lg4573 *ctx = spi_get_drvdata(spi);
lg4573_display_off(ctx);
drm_panel_remove(&ctx->panel);
-
- return 0;
}
static const struct of_device_id lg4573_of_match[] = {
diff --git a/drivers/gpu/drm/panel/panel-nec-nl8048hl11.c b/drivers/gpu/drm/panel/panel-nec-nl8048hl11.c
index 6e5ab1debc8b..81c5c541a351 100644
--- a/drivers/gpu/drm/panel/panel-nec-nl8048hl11.c
+++ b/drivers/gpu/drm/panel/panel-nec-nl8048hl11.c
@@ -212,15 +212,13 @@ static int nl8048_probe(struct spi_device *spi)
return 0;
}
-static int nl8048_remove(struct spi_device *spi)
+static void nl8048_remove(struct spi_device *spi)
{
struct nl8048_panel *lcd = spi_get_drvdata(spi);
drm_panel_remove(&lcd->panel);
drm_panel_disable(&lcd->panel);
drm_panel_unprepare(&lcd->panel);
-
- return 0;
}
static const struct of_device_id nl8048_of_match[] = {
diff --git a/drivers/gpu/drm/panel/panel-novatek-nt35560.c b/drivers/gpu/drm/panel/panel-novatek-nt35560.c
new file mode 100644
index 000000000000..1b6042321ea1
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-novatek-nt35560.c
@@ -0,0 +1,561 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * MIPI-DSI Novatek NT35560-based panel controller.
+ *
+ * Supported panels include:
+ * Sony ACX424AKM - a 480x854 AMOLED DSI panel
+ * Sony ACX424AKP - a 480x864 AMOLED DSI panel
+ *
+ * Copyright (C) Linaro Ltd. 2019-2021
+ * Author: Linus Walleij
+ * Based on code and know-how from Marcus Lorentzon
+ * Copyright (C) ST-Ericsson SA 2010
+ * Based on code and know-how from Johan Olson and Joakim Wesslen
+ * Copyright (C) Sony Ericsson Mobile Communications 2010
+ */
+#include <linux/backlight.h>
+#include <linux/delay.h>
+#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>
+
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_modes.h>
+#include <drm/drm_panel.h>
+
+#define NT35560_DCS_READ_ID1 0xDA
+#define NT35560_DCS_READ_ID2 0xDB
+#define NT35560_DCS_READ_ID3 0xDC
+#define NT35560_DCS_SET_MDDI 0xAE
+
+/*
+ * Sony seems to use vendor ID 0x81
+ */
+#define DISPLAY_SONY_ACX424AKP_ID1 0x8103
+#define DISPLAY_SONY_ACX424AKP_ID2 0x811a
+#define DISPLAY_SONY_ACX424AKP_ID3 0x811b
+/*
+ * The fourth ID looks like a bug, vendor IDs begin at 0x80
+ * and panel 00 ... seems like default values.
+ */
+#define DISPLAY_SONY_ACX424AKP_ID4 0x8000
+
+struct nt35560_config {
+ const struct drm_display_mode *vid_mode;
+ const struct drm_display_mode *cmd_mode;
+};
+
+struct nt35560 {
+ const struct nt35560_config *conf;
+ struct drm_panel panel;
+ struct device *dev;
+ struct regulator *supply;
+ struct gpio_desc *reset_gpio;
+ bool video_mode;
+};
+
+static const struct drm_display_mode sony_acx424akp_vid_mode = {
+ .clock = 27234,
+ .hdisplay = 480,
+ .hsync_start = 480 + 15,
+ .hsync_end = 480 + 15 + 0,
+ .htotal = 480 + 15 + 0 + 15,
+ .vdisplay = 864,
+ .vsync_start = 864 + 14,
+ .vsync_end = 864 + 14 + 1,
+ .vtotal = 864 + 14 + 1 + 11,
+ .width_mm = 48,
+ .height_mm = 84,
+ .flags = DRM_MODE_FLAG_PVSYNC,
+};
+
+/*
+ * The timings are not very helpful as the display is used in
+ * command mode using the maximum HS frequency.
+ */
+static const struct drm_display_mode sony_acx424akp_cmd_mode = {
+ .clock = 35478,
+ .hdisplay = 480,
+ .hsync_start = 480 + 154,
+ .hsync_end = 480 + 154 + 16,
+ .htotal = 480 + 154 + 16 + 32,
+ .vdisplay = 864,
+ .vsync_start = 864 + 1,
+ .vsync_end = 864 + 1 + 1,
+ .vtotal = 864 + 1 + 1 + 1,
+ /*
+ * Some desired refresh rate, experiments at the maximum "pixel"
+ * clock speed (HS clock 420 MHz) yields around 117Hz.
+ */
+ .width_mm = 48,
+ .height_mm = 84,
+};
+
+static const struct nt35560_config sony_acx424akp_data = {
+ .vid_mode = &sony_acx424akp_vid_mode,
+ .cmd_mode = &sony_acx424akp_cmd_mode,
+};
+
+static const struct drm_display_mode sony_acx424akm_vid_mode = {
+ .clock = 27234,
+ .hdisplay = 480,
+ .hsync_start = 480 + 15,
+ .hsync_end = 480 + 15 + 0,
+ .htotal = 480 + 15 + 0 + 15,
+ .vdisplay = 854,
+ .vsync_start = 854 + 14,
+ .vsync_end = 854 + 14 + 1,
+ .vtotal = 854 + 14 + 1 + 11,
+ .width_mm = 46,
+ .height_mm = 82,
+ .flags = DRM_MODE_FLAG_PVSYNC,
+};
+
+/*
+ * The timings are not very helpful as the display is used in
+ * command mode using the maximum HS frequency.
+ */
+static const struct drm_display_mode sony_acx424akm_cmd_mode = {
+ .clock = 35478,
+ .hdisplay = 480,
+ .hsync_start = 480 + 154,
+ .hsync_end = 480 + 154 + 16,
+ .htotal = 480 + 154 + 16 + 32,
+ .vdisplay = 854,
+ .vsync_start = 854 + 1,
+ .vsync_end = 854 + 1 + 1,
+ .vtotal = 854 + 1 + 1 + 1,
+ .width_mm = 46,
+ .height_mm = 82,
+};
+
+static const struct nt35560_config sony_acx424akm_data = {
+ .vid_mode = &sony_acx424akm_vid_mode,
+ .cmd_mode = &sony_acx424akm_cmd_mode,
+};
+
+static inline struct nt35560 *panel_to_nt35560(struct drm_panel *panel)
+{
+ return container_of(panel, struct nt35560, panel);
+}
+
+#define FOSC 20 /* 20Mhz */
+#define SCALE_FACTOR_NS_DIV_MHZ 1000
+
+static int nt35560_set_brightness(struct backlight_device *bl)
+{
+ struct nt35560 *nt = bl_get_data(bl);
+ struct mipi_dsi_device *dsi = to_mipi_dsi_device(nt->dev);
+ int period_ns = 1023;
+ int duty_ns = bl->props.brightness;
+ u8 pwm_ratio;
+ u8 pwm_div;
+ u8 par;
+ int ret;
+
+ if (backlight_is_blank(bl)) {
+ /* Disable backlight */
+ par = 0x00;
+ ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY,
+ &par, 1);
+ if (ret) {
+ dev_err(nt->dev, "failed to disable display backlight (%d)\n", ret);
+ return ret;
+ }
+ return 0;
+ }
+
+ /* Calculate the PWM duty cycle in n/256's */
+ pwm_ratio = max(((duty_ns * 256) / period_ns) - 1, 1);
+ pwm_div = max(1,
+ ((FOSC * period_ns) / 256) /
+ SCALE_FACTOR_NS_DIV_MHZ);
+
+ /* Set up PWM dutycycle ONE byte (differs from the standard) */
+ dev_dbg(nt->dev, "calculated duty cycle %02x\n", pwm_ratio);
+ ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,
+ &pwm_ratio, 1);
+ if (ret < 0) {
+ dev_err(nt->dev, "failed to set display PWM ratio (%d)\n", ret);
+ return ret;
+ }
+
+ /*
+ * Sequence to write PWMDIV:
+ * address data
+ * 0xF3 0xAA CMD2 Unlock
+ * 0x00 0x01 Enter CMD2 page 0
+ * 0X7D 0x01 No reload MTP of CMD2 P1
+ * 0x22 PWMDIV
+ * 0x7F 0xAA CMD2 page 1 lock
+ */
+ par = 0xaa;
+ ret = mipi_dsi_dcs_write(dsi, 0xf3, &par, 1);
+ if (ret < 0) {
+ dev_err(nt->dev, "failed to unlock CMD 2 (%d)\n", ret);
+ return ret;
+ }
+ par = 0x01;
+ ret = mipi_dsi_dcs_write(dsi, 0x00, &par, 1);
+ if (ret < 0) {
+ dev_err(nt->dev, "failed to enter page 1 (%d)\n", ret);
+ return ret;
+ }
+ par = 0x01;
+ ret = mipi_dsi_dcs_write(dsi, 0x7d, &par, 1);
+ if (ret < 0) {
+ dev_err(nt->dev, "failed to disable MTP reload (%d)\n", ret);
+ return ret;
+ }
+ ret = mipi_dsi_dcs_write(dsi, 0x22, &pwm_div, 1);
+ if (ret < 0) {
+ dev_err(nt->dev, "failed to set PWM divisor (%d)\n", ret);
+ return ret;
+ }
+ par = 0xaa;
+ ret = mipi_dsi_dcs_write(dsi, 0x7f, &par, 1);
+ if (ret < 0) {
+ dev_err(nt->dev, "failed to lock CMD 2 (%d)\n", ret);
+ return ret;
+ }
+
+ /* Enable backlight */
+ par = 0x24;
+ ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY,
+ &par, 1);
+ if (ret < 0) {
+ dev_err(nt->dev, "failed to enable display backlight (%d)\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct backlight_ops nt35560_bl_ops = {
+ .update_status = nt35560_set_brightness,
+};
+
+static const struct backlight_properties nt35560_bl_props = {
+ .type = BACKLIGHT_RAW,
+ .brightness = 512,
+ .max_brightness = 1023,
+};
+
+static int nt35560_read_id(struct nt35560 *nt)
+{
+ struct mipi_dsi_device *dsi = to_mipi_dsi_device(nt->dev);
+ u8 vendor, version, panel;
+ u16 val;
+ int ret;
+
+ ret = mipi_dsi_dcs_read(dsi, NT35560_DCS_READ_ID1, &vendor, 1);
+ if (ret < 0) {
+ dev_err(nt->dev, "could not vendor ID byte\n");
+ return ret;
+ }
+ ret = mipi_dsi_dcs_read(dsi, NT35560_DCS_READ_ID2, &version, 1);
+ if (ret < 0) {
+ dev_err(nt->dev, "could not read device version byte\n");
+ return ret;
+ }
+ ret = mipi_dsi_dcs_read(dsi, NT35560_DCS_READ_ID3, &panel, 1);
+ if (ret < 0) {
+ dev_err(nt->dev, "could not read panel ID byte\n");
+ return ret;
+ }
+
+ if (vendor == 0x00) {
+ dev_err(nt->dev, "device vendor ID is zero\n");
+ return -ENODEV;
+ }
+
+ val = (vendor << 8) | panel;
+ switch (val) {
+ case DISPLAY_SONY_ACX424AKP_ID1:
+ case DISPLAY_SONY_ACX424AKP_ID2:
+ case DISPLAY_SONY_ACX424AKP_ID3:
+ case DISPLAY_SONY_ACX424AKP_ID4:
+ dev_info(nt->dev, "MTP vendor: %02x, version: %02x, panel: %02x\n",
+ vendor, version, panel);
+ break;
+ default:
+ dev_info(nt->dev, "unknown vendor: %02x, version: %02x, panel: %02x\n",
+ vendor, version, panel);
+ break;
+ }
+
+ return 0;
+}
+
+static int nt35560_power_on(struct nt35560 *nt)
+{
+ int ret;
+
+ ret = regulator_enable(nt->supply);
+ if (ret) {
+ dev_err(nt->dev, "failed to enable supply (%d)\n", ret);
+ return ret;
+ }
+
+ /* Assert RESET */
+ gpiod_set_value_cansleep(nt->reset_gpio, 1);
+ udelay(20);
+ /* De-assert RESET */
+ gpiod_set_value_cansleep(nt->reset_gpio, 0);
+ usleep_range(11000, 20000);
+
+ return 0;
+}
+
+static void nt35560_power_off(struct nt35560 *nt)
+{
+ /* Assert RESET */
+ gpiod_set_value_cansleep(nt->reset_gpio, 1);
+ usleep_range(11000, 20000);
+
+ regulator_disable(nt->supply);
+}
+
+static int nt35560_prepare(struct drm_panel *panel)
+{
+ struct nt35560 *nt = panel_to_nt35560(panel);
+ struct mipi_dsi_device *dsi = to_mipi_dsi_device(nt->dev);
+ const u8 mddi = 3;
+ int ret;
+
+ ret = nt35560_power_on(nt);
+ if (ret)
+ return ret;
+
+ ret = nt35560_read_id(nt);
+ if (ret) {
+ dev_err(nt->dev, "failed to read panel ID (%d)\n", ret);
+ goto err_power_off;
+ }
+
+ /* Enabe tearing mode: send TE (tearing effect) at VBLANK */
+ ret = mipi_dsi_dcs_set_tear_on(dsi,
+ MIPI_DSI_DCS_TEAR_MODE_VBLANK);
+ if (ret) {
+ dev_err(nt->dev, "failed to enable vblank TE (%d)\n", ret);
+ goto err_power_off;
+ }
+
+ /*
+ * Set MDDI
+ *
+ * This presumably deactivates the Qualcomm MDDI interface and
+ * selects DSI, similar code is found in other drivers such as the
+ * Sharp LS043T1LE01 which makes us suspect that this panel may be
+ * using a Novatek NT35565 or similar display driver chip that shares
+ * this command. Due to the lack of documentation we cannot know for
+ * sure.
+ */
+ ret = mipi_dsi_dcs_write(dsi, NT35560_DCS_SET_MDDI,
+ &mddi, sizeof(mddi));
+ if (ret < 0) {
+ dev_err(nt->dev, "failed to set MDDI (%d)\n", ret);
+ goto err_power_off;
+ }
+
+ /* Exit sleep mode */
+ ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
+ if (ret) {
+ dev_err(nt->dev, "failed to exit sleep mode (%d)\n", ret);
+ goto err_power_off;
+ }
+ msleep(140);
+
+ ret = mipi_dsi_dcs_set_display_on(dsi);
+ if (ret) {
+ dev_err(nt->dev, "failed to turn display on (%d)\n", ret);
+ goto err_power_off;
+ }
+ if (nt->video_mode) {
+ /* In video mode turn peripheral on */
+ ret = mipi_dsi_turn_on_peripheral(dsi);
+ if (ret) {
+ dev_err(nt->dev, "failed to turn on peripheral\n");
+ goto err_power_off;
+ }
+ }
+
+ return 0;
+
+err_power_off:
+ nt35560_power_off(nt);
+ return ret;
+}
+
+static int nt35560_unprepare(struct drm_panel *panel)
+{
+ struct nt35560 *nt = panel_to_nt35560(panel);
+ struct mipi_dsi_device *dsi = to_mipi_dsi_device(nt->dev);
+ int ret;
+
+ ret = mipi_dsi_dcs_set_display_off(dsi);
+ if (ret) {
+ dev_err(nt->dev, "failed to turn display off (%d)\n", ret);
+ return ret;
+ }
+
+ /* Enter sleep mode */
+ ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
+ if (ret) {
+ dev_err(nt->dev, "failed to enter sleep mode (%d)\n", ret);
+ return ret;
+ }
+ msleep(85);
+
+ nt35560_power_off(nt);
+
+ return 0;
+}
+
+
+static int nt35560_get_modes(struct drm_panel *panel,
+ struct drm_connector *connector)
+{
+ struct nt35560 *nt = panel_to_nt35560(panel);
+ const struct nt35560_config *conf = nt->conf;
+ struct drm_display_mode *mode;
+
+ if (nt->video_mode)
+ mode = drm_mode_duplicate(connector->dev,
+ conf->vid_mode);
+ else
+ mode = drm_mode_duplicate(connector->dev,
+ conf->cmd_mode);
+ if (!mode) {
+ dev_err(panel->dev, "bad mode or failed to add mode\n");
+ return -EINVAL;
+ }
+ 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;
+
+ drm_mode_probed_add(connector, mode);
+
+ return 1; /* Number of modes */
+}
+
+static const struct drm_panel_funcs nt35560_drm_funcs = {
+ .unprepare = nt35560_unprepare,
+ .prepare = nt35560_prepare,
+ .get_modes = nt35560_get_modes,
+};
+
+static int nt35560_probe(struct mipi_dsi_device *dsi)
+{
+ struct device *dev = &dsi->dev;
+ struct nt35560 *nt;
+ int ret;
+
+ nt = devm_kzalloc(dev, sizeof(struct nt35560), GFP_KERNEL);
+ if (!nt)
+ return -ENOMEM;
+ nt->video_mode = of_property_read_bool(dev->of_node,
+ "enforce-video-mode");
+
+ mipi_dsi_set_drvdata(dsi, nt);
+ nt->dev = dev;
+
+ nt->conf = of_device_get_match_data(dev);
+ if (!nt->conf) {
+ dev_err(dev, "missing device configuration\n");
+ return -ENODEV;
+ }
+
+ dsi->lanes = 2;
+ dsi->format = MIPI_DSI_FMT_RGB888;
+ /*
+ * FIXME: these come from the ST-Ericsson vendor driver for the
+ * HREF520 and seems to reflect limitations in the PLLs on that
+ * platform, if you have the datasheet, please cross-check the
+ * actual max rates.
+ */
+ dsi->lp_rate = 19200000;
+ dsi->hs_rate = 420160000;
+
+ if (nt->video_mode)
+ /* Burst mode using event for sync */
+ dsi->mode_flags =
+ MIPI_DSI_MODE_VIDEO |
+ MIPI_DSI_MODE_VIDEO_BURST;
+ else
+ dsi->mode_flags =
+ MIPI_DSI_CLOCK_NON_CONTINUOUS;
+
+ nt->supply = devm_regulator_get(dev, "vddi");
+ if (IS_ERR(nt->supply))
+ return PTR_ERR(nt->supply);
+
+ /* This asserts RESET by default */
+ nt->reset_gpio = devm_gpiod_get_optional(dev, "reset",
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(nt->reset_gpio))
+ return dev_err_probe(dev, PTR_ERR(nt->reset_gpio),
+ "failed to request GPIO\n");
+
+ drm_panel_init(&nt->panel, dev, &nt35560_drm_funcs,
+ DRM_MODE_CONNECTOR_DSI);
+
+ nt->panel.backlight = devm_backlight_device_register(dev, "nt35560", dev, nt,
+ &nt35560_bl_ops, &nt35560_bl_props);
+ if (IS_ERR(nt->panel.backlight))
+ return dev_err_probe(dev, PTR_ERR(nt->panel.backlight),
+ "failed to register backlight device\n");
+
+ drm_panel_add(&nt->panel);
+
+ ret = mipi_dsi_attach(dsi);
+ if (ret < 0) {
+ drm_panel_remove(&nt->panel);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int nt35560_remove(struct mipi_dsi_device *dsi)
+{
+ struct nt35560 *nt = mipi_dsi_get_drvdata(dsi);
+
+ mipi_dsi_detach(dsi);
+ drm_panel_remove(&nt->panel);
+
+ return 0;
+}
+
+static const struct of_device_id nt35560_of_match[] = {
+ {
+ .compatible = "sony,acx424akp",
+ .data = &sony_acx424akp_data,
+ },
+ {
+ .compatible = "sony,acx424akm",
+ .data = &sony_acx424akm_data,
+ },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, nt35560_of_match);
+
+static struct mipi_dsi_driver nt35560_driver = {
+ .probe = nt35560_probe,
+ .remove = nt35560_remove,
+ .driver = {
+ .name = "panel-novatek-nt35560",
+ .of_match_table = nt35560_of_match,
+ },
+};
+module_mipi_dsi_driver(nt35560_driver);
+
+MODULE_AUTHOR("Linus Wallei <linus.walleij@linaro.org>");
+MODULE_DESCRIPTION("MIPI-DSI Novatek NT35560 Panel Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/panel/panel-novatek-nt39016.c b/drivers/gpu/drm/panel/panel-novatek-nt39016.c
index d036853db865..f58cfb10b58a 100644
--- a/drivers/gpu/drm/panel/panel-novatek-nt39016.c
+++ b/drivers/gpu/drm/panel/panel-novatek-nt39016.c
@@ -292,7 +292,7 @@ static int nt39016_probe(struct spi_device *spi)
return 0;
}
-static int nt39016_remove(struct spi_device *spi)
+static void nt39016_remove(struct spi_device *spi)
{
struct nt39016 *panel = spi_get_drvdata(spi);
@@ -300,8 +300,6 @@ static int nt39016_remove(struct spi_device *spi)
nt39016_disable(&panel->drm_panel);
nt39016_unprepare(&panel->drm_panel);
-
- return 0;
}
static const struct drm_display_mode kd035g6_display_modes[] = {
diff --git a/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c b/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c
index 221db6512859..20666b6217e7 100644
--- a/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c
+++ b/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c
@@ -14,8 +14,8 @@
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
-#include <drm/drm_dp_aux_bus.h>
-#include <drm/drm_dp_helper.h>
+#include <drm/dp/drm_dp_aux_bus.h>
+#include <drm/dp/drm_dp_helper.h>
#include <drm/drm_edid.h>
#include <drm/drm_panel.h>
diff --git a/drivers/gpu/drm/panel/panel-samsung-db7430.c b/drivers/gpu/drm/panel/panel-samsung-db7430.c
index ead479719f00..04640c5256a8 100644
--- a/drivers/gpu/drm/panel/panel-samsung-db7430.c
+++ b/drivers/gpu/drm/panel/panel-samsung-db7430.c
@@ -314,12 +314,11 @@ static int db7430_probe(struct spi_device *spi)
return 0;
}
-static int db7430_remove(struct spi_device *spi)
+static void db7430_remove(struct spi_device *spi)
{
struct db7430 *db = spi_get_drvdata(spi);
drm_panel_remove(&db->panel);
- return 0;
}
/*
diff --git a/drivers/gpu/drm/panel/panel-samsung-ld9040.c b/drivers/gpu/drm/panel/panel-samsung-ld9040.c
index c4b388850a13..01eb211f32f7 100644
--- a/drivers/gpu/drm/panel/panel-samsung-ld9040.c
+++ b/drivers/gpu/drm/panel/panel-samsung-ld9040.c
@@ -358,14 +358,12 @@ static int ld9040_probe(struct spi_device *spi)
return 0;
}
-static int ld9040_remove(struct spi_device *spi)
+static void ld9040_remove(struct spi_device *spi)
{
struct ld9040 *ctx = spi_get_drvdata(spi);
ld9040_power_off(ctx);
drm_panel_remove(&ctx->panel);
-
- return 0;
}
static const struct of_device_id ld9040_of_match[] = {
diff --git a/drivers/gpu/drm/panel/panel-samsung-s6d27a1.c b/drivers/gpu/drm/panel/panel-samsung-s6d27a1.c
index 1696ceb36aa0..2adb223a895c 100644
--- a/drivers/gpu/drm/panel/panel-samsung-s6d27a1.c
+++ b/drivers/gpu/drm/panel/panel-samsung-s6d27a1.c
@@ -291,12 +291,11 @@ static int s6d27a1_probe(struct spi_device *spi)
return 0;
}
-static int s6d27a1_remove(struct spi_device *spi)
+static void s6d27a1_remove(struct spi_device *spi)
{
struct s6d27a1 *ctx = spi_get_drvdata(spi);
drm_panel_remove(&ctx->panel);
- return 0;
}
static const struct of_device_id s6d27a1_match[] = {
diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e63m0-spi.c b/drivers/gpu/drm/panel/panel-samsung-s6e63m0-spi.c
index c178d962b0d5..d99afcc672ca 100644
--- a/drivers/gpu/drm/panel/panel-samsung-s6e63m0-spi.c
+++ b/drivers/gpu/drm/panel/panel-samsung-s6e63m0-spi.c
@@ -62,10 +62,9 @@ static int s6e63m0_spi_probe(struct spi_device *spi)
s6e63m0_spi_dcs_write, false);
}
-static int s6e63m0_spi_remove(struct spi_device *spi)
+static void s6e63m0_spi_remove(struct spi_device *spi)
{
s6e63m0_remove(&spi->dev);
- return 0;
}
static const struct of_device_id s6e63m0_spi_of_match[] = {
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index b42c1d816e79..a34f4198a534 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -2526,6 +2526,36 @@ static const struct panel_desc mitsubishi_aa070mc01 = {
.bus_flags = DRM_BUS_FLAG_DE_HIGH,
};
+static const struct display_timing multi_inno_mi0700s4t_6_timing = {
+ .pixelclock = { 29000000, 33000000, 38000000 },
+ .hactive = { 800, 800, 800 },
+ .hfront_porch = { 180, 210, 240 },
+ .hback_porch = { 16, 16, 16 },
+ .hsync_len = { 30, 30, 30 },
+ .vactive = { 480, 480, 480 },
+ .vfront_porch = { 12, 22, 32 },
+ .vback_porch = { 10, 10, 10 },
+ .vsync_len = { 13, 13, 13 },
+ .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 multi_inno_mi0700s4t_6 = {
+ .timings = &multi_inno_mi0700s4t_6_timing,
+ .num_timings = 1,
+ .bpc = 8,
+ .size = {
+ .width = 154,
+ .height = 86,
+ },
+ .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 display_timing multi_inno_mi1010ait_1cp_timing = {
.pixelclock = { 68900000, 70000000, 73400000 },
.hactive = { 1280, 1280, 1280 },
@@ -3028,6 +3058,7 @@ static const struct drm_display_mode rocktech_rk101ii01d_ct_mode = {
static const struct panel_desc rocktech_rk101ii01d_ct = {
.modes = &rocktech_rk101ii01d_ct_mode,
+ .bpc = 8,
.num_modes = 1,
.size = {
.width = 217,
@@ -3873,6 +3904,9 @@ static const struct of_device_id platform_of_match[] = {
.compatible = "mitsubishi,aa070mc01-ca1",
.data = &mitsubishi_aa070mc01,
}, {
+ .compatible = "multi-inno,mi0700s4t-6",
+ .data = &multi_inno_mi0700s4t_6,
+ }, {
.compatible = "multi-inno,mi1010ait-1cp",
.data = &multi_inno_mi1010ait_1cp,
}, {
diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7789v.c b/drivers/gpu/drm/panel/panel-sitronix-st7789v.c
index 61e565524542..bbc4569cbcdc 100644
--- a/drivers/gpu/drm/panel/panel-sitronix-st7789v.c
+++ b/drivers/gpu/drm/panel/panel-sitronix-st7789v.c
@@ -387,13 +387,11 @@ static int st7789v_probe(struct spi_device *spi)
return 0;
}
-static int st7789v_remove(struct spi_device *spi)
+static void st7789v_remove(struct spi_device *spi)
{
struct st7789v *ctx = spi_get_drvdata(spi);
drm_panel_remove(&ctx->panel);
-
- return 0;
}
static const struct of_device_id st7789v_of_match[] = {
diff --git a/drivers/gpu/drm/panel/panel-sony-acx424akp.c b/drivers/gpu/drm/panel/panel-sony-acx424akp.c
deleted file mode 100644
index 9536d56a94a5..000000000000
--- a/drivers/gpu/drm/panel/panel-sony-acx424akp.c
+++ /dev/null
@@ -1,490 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * MIPI-DSI Sony ACX424AKP panel driver. This is a 480x864
- * AMOLED panel with a command-only DSI interface.
- *
- * Copyright (C) Linaro Ltd. 2019
- * Author: Linus Walleij
- * Based on code and know-how from Marcus Lorentzon
- * Copyright (C) ST-Ericsson SA 2010
- */
-#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 ACX424_DCS_READ_ID1 0xDA
-#define ACX424_DCS_READ_ID2 0xDB
-#define ACX424_DCS_READ_ID3 0xDC
-#define ACX424_DCS_SET_MDDI 0xAE
-
-/*
- * Sony seems to use vendor ID 0x81
- */
-#define DISPLAY_SONY_ACX424AKP_ID1 0x811b
-#define DISPLAY_SONY_ACX424AKP_ID2 0x811a
-/*
- * The third ID looks like a bug, vendor IDs begin at 0x80
- * and panel 00 ... seems like default values.
- */
-#define DISPLAY_SONY_ACX424AKP_ID3 0x8000
-
-struct acx424akp {
- struct drm_panel panel;
- struct device *dev;
- struct regulator *supply;
- struct gpio_desc *reset_gpio;
- bool video_mode;
-};
-
-static const struct drm_display_mode sony_acx424akp_vid_mode = {
- .clock = 27234,
- .hdisplay = 480,
- .hsync_start = 480 + 15,
- .hsync_end = 480 + 15 + 0,
- .htotal = 480 + 15 + 0 + 15,
- .vdisplay = 864,
- .vsync_start = 864 + 14,
- .vsync_end = 864 + 14 + 1,
- .vtotal = 864 + 14 + 1 + 11,
- .width_mm = 48,
- .height_mm = 84,
- .flags = DRM_MODE_FLAG_PVSYNC,
-};
-
-/*
- * The timings are not very helpful as the display is used in
- * command mode using the maximum HS frequency.
- */
-static const struct drm_display_mode sony_acx424akp_cmd_mode = {
- .clock = 35478,
- .hdisplay = 480,
- .hsync_start = 480 + 154,
- .hsync_end = 480 + 154 + 16,
- .htotal = 480 + 154 + 16 + 32,
- .vdisplay = 864,
- .vsync_start = 864 + 1,
- .vsync_end = 864 + 1 + 1,
- .vtotal = 864 + 1 + 1 + 1,
- /*
- * Some desired refresh rate, experiments at the maximum "pixel"
- * clock speed (HS clock 420 MHz) yields around 117Hz.
- */
- .width_mm = 48,
- .height_mm = 84,
-};
-
-static inline struct acx424akp *panel_to_acx424akp(struct drm_panel *panel)
-{
- return container_of(panel, struct acx424akp, panel);
-}
-
-#define FOSC 20 /* 20Mhz */
-#define SCALE_FACTOR_NS_DIV_MHZ 1000
-
-static int acx424akp_set_brightness(struct backlight_device *bl)
-{
- struct acx424akp *acx = bl_get_data(bl);
- struct mipi_dsi_device *dsi = to_mipi_dsi_device(acx->dev);
- int period_ns = 1023;
- int duty_ns = bl->props.brightness;
- u8 pwm_ratio;
- u8 pwm_div;
- u8 par;
- int ret;
-
- if (backlight_is_blank(bl)) {
- /* Disable backlight */
- par = 0x00;
- ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY,
- &par, 1);
- if (ret) {
- dev_err(acx->dev, "failed to disable display backlight (%d)\n", ret);
- return ret;
- }
- return 0;
- }
-
- /* Calculate the PWM duty cycle in n/256's */
- pwm_ratio = max(((duty_ns * 256) / period_ns) - 1, 1);
- pwm_div = max(1,
- ((FOSC * period_ns) / 256) /
- SCALE_FACTOR_NS_DIV_MHZ);
-
- /* Set up PWM dutycycle ONE byte (differs from the standard) */
- dev_dbg(acx->dev, "calculated duty cycle %02x\n", pwm_ratio);
- ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,
- &pwm_ratio, 1);
- if (ret < 0) {
- dev_err(acx->dev, "failed to set display PWM ratio (%d)\n", ret);
- return ret;
- }
-
- /*
- * Sequence to write PWMDIV:
- * address data
- * 0xF3 0xAA CMD2 Unlock
- * 0x00 0x01 Enter CMD2 page 0
- * 0X7D 0x01 No reload MTP of CMD2 P1
- * 0x22 PWMDIV
- * 0x7F 0xAA CMD2 page 1 lock
- */
- par = 0xaa;
- ret = mipi_dsi_dcs_write(dsi, 0xf3, &par, 1);
- if (ret < 0) {
- dev_err(acx->dev, "failed to unlock CMD 2 (%d)\n", ret);
- return ret;
- }
- par = 0x01;
- ret = mipi_dsi_dcs_write(dsi, 0x00, &par, 1);
- if (ret < 0) {
- dev_err(acx->dev, "failed to enter page 1 (%d)\n", ret);
- return ret;
- }
- par = 0x01;
- ret = mipi_dsi_dcs_write(dsi, 0x7d, &par, 1);
- if (ret < 0) {
- dev_err(acx->dev, "failed to disable MTP reload (%d)\n", ret);
- return ret;
- }
- ret = mipi_dsi_dcs_write(dsi, 0x22, &pwm_div, 1);
- if (ret < 0) {
- dev_err(acx->dev, "failed to set PWM divisor (%d)\n", ret);
- return ret;
- }
- par = 0xaa;
- ret = mipi_dsi_dcs_write(dsi, 0x7f, &par, 1);
- if (ret < 0) {
- dev_err(acx->dev, "failed to lock CMD 2 (%d)\n", ret);
- return ret;
- }
-
- /* Enable backlight */
- par = 0x24;
- ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY,
- &par, 1);
- if (ret < 0) {
- dev_err(acx->dev, "failed to enable display backlight (%d)\n", ret);
- return ret;
- }
-
- return 0;
-}
-
-static const struct backlight_ops acx424akp_bl_ops = {
- .update_status = acx424akp_set_brightness,
-};
-
-static const struct backlight_properties acx424akp_bl_props = {
- .type = BACKLIGHT_RAW,
- .brightness = 512,
- .max_brightness = 1023,
-};
-
-static int acx424akp_read_id(struct acx424akp *acx)
-{
- struct mipi_dsi_device *dsi = to_mipi_dsi_device(acx->dev);
- u8 vendor, version, panel;
- u16 val;
- int ret;
-
- ret = mipi_dsi_dcs_read(dsi, ACX424_DCS_READ_ID1, &vendor, 1);
- if (ret < 0) {
- dev_err(acx->dev, "could not vendor ID byte\n");
- return ret;
- }
- ret = mipi_dsi_dcs_read(dsi, ACX424_DCS_READ_ID2, &version, 1);
- if (ret < 0) {
- dev_err(acx->dev, "could not read device version byte\n");
- return ret;
- }
- ret = mipi_dsi_dcs_read(dsi, ACX424_DCS_READ_ID3, &panel, 1);
- if (ret < 0) {
- dev_err(acx->dev, "could not read panel ID byte\n");
- return ret;
- }
-
- if (vendor == 0x00) {
- dev_err(acx->dev, "device vendor ID is zero\n");
- return -ENODEV;
- }
-
- val = (vendor << 8) | panel;
- switch (val) {
- case DISPLAY_SONY_ACX424AKP_ID1:
- case DISPLAY_SONY_ACX424AKP_ID2:
- case DISPLAY_SONY_ACX424AKP_ID3:
- dev_info(acx->dev, "MTP vendor: %02x, version: %02x, panel: %02x\n",
- vendor, version, panel);
- break;
- default:
- dev_info(acx->dev, "unknown vendor: %02x, version: %02x, panel: %02x\n",
- vendor, version, panel);
- break;
- }
-
- return 0;
-}
-
-static int acx424akp_power_on(struct acx424akp *acx)
-{
- int ret;
-
- ret = regulator_enable(acx->supply);
- if (ret) {
- dev_err(acx->dev, "failed to enable supply (%d)\n", ret);
- return ret;
- }
-
- /* Assert RESET */
- gpiod_set_value_cansleep(acx->reset_gpio, 1);
- udelay(20);
- /* De-assert RESET */
- gpiod_set_value_cansleep(acx->reset_gpio, 0);
- usleep_range(11000, 20000);
-
- return 0;
-}
-
-static void acx424akp_power_off(struct acx424akp *acx)
-{
- /* Assert RESET */
- gpiod_set_value_cansleep(acx->reset_gpio, 1);
- usleep_range(11000, 20000);
-
- regulator_disable(acx->supply);
-}
-
-static int acx424akp_prepare(struct drm_panel *panel)
-{
- struct acx424akp *acx = panel_to_acx424akp(panel);
- struct mipi_dsi_device *dsi = to_mipi_dsi_device(acx->dev);
- const u8 mddi = 3;
- int ret;
-
- ret = acx424akp_power_on(acx);
- if (ret)
- return ret;
-
- ret = acx424akp_read_id(acx);
- if (ret) {
- dev_err(acx->dev, "failed to read panel ID (%d)\n", ret);
- goto err_power_off;
- }
-
- /* Enabe tearing mode: send TE (tearing effect) at VBLANK */
- ret = mipi_dsi_dcs_set_tear_on(dsi,
- MIPI_DSI_DCS_TEAR_MODE_VBLANK);
- if (ret) {
- dev_err(acx->dev, "failed to enable vblank TE (%d)\n", ret);
- goto err_power_off;
- }
-
- /*
- * Set MDDI
- *
- * This presumably deactivates the Qualcomm MDDI interface and
- * selects DSI, similar code is found in other drivers such as the
- * Sharp LS043T1LE01 which makes us suspect that this panel may be
- * using a Novatek NT35565 or similar display driver chip that shares
- * this command. Due to the lack of documentation we cannot know for
- * sure.
- */
- ret = mipi_dsi_dcs_write(dsi, ACX424_DCS_SET_MDDI,
- &mddi, sizeof(mddi));
- if (ret < 0) {
- dev_err(acx->dev, "failed to set MDDI (%d)\n", ret);
- goto err_power_off;
- }
-
- /* Exit sleep mode */
- ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
- if (ret) {
- dev_err(acx->dev, "failed to exit sleep mode (%d)\n", ret);
- goto err_power_off;
- }
- msleep(140);
-
- ret = mipi_dsi_dcs_set_display_on(dsi);
- if (ret) {
- dev_err(acx->dev, "failed to turn display on (%d)\n", ret);
- goto err_power_off;
- }
- if (acx->video_mode) {
- /* In video mode turn peripheral on */
- ret = mipi_dsi_turn_on_peripheral(dsi);
- if (ret) {
- dev_err(acx->dev, "failed to turn on peripheral\n");
- goto err_power_off;
- }
- }
-
- return 0;
-
-err_power_off:
- acx424akp_power_off(acx);
- return ret;
-}
-
-static int acx424akp_unprepare(struct drm_panel *panel)
-{
- struct acx424akp *acx = panel_to_acx424akp(panel);
- struct mipi_dsi_device *dsi = to_mipi_dsi_device(acx->dev);
- int ret;
-
- ret = mipi_dsi_dcs_set_display_off(dsi);
- if (ret) {
- dev_err(acx->dev, "failed to turn display off (%d)\n", ret);
- return ret;
- }
-
- /* Enter sleep mode */
- ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
- if (ret) {
- dev_err(acx->dev, "failed to enter sleep mode (%d)\n", ret);
- return ret;
- }
- msleep(85);
-
- acx424akp_power_off(acx);
-
- return 0;
-}
-
-
-static int acx424akp_get_modes(struct drm_panel *panel,
- struct drm_connector *connector)
-{
- struct acx424akp *acx = panel_to_acx424akp(panel);
- struct drm_display_mode *mode;
-
- if (acx->video_mode)
- mode = drm_mode_duplicate(connector->dev,
- &sony_acx424akp_vid_mode);
- else
- mode = drm_mode_duplicate(connector->dev,
- &sony_acx424akp_cmd_mode);
- if (!mode) {
- dev_err(panel->dev, "bad mode or failed to add mode\n");
- return -EINVAL;
- }
- 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;
-
- drm_mode_probed_add(connector, mode);
-
- return 1; /* Number of modes */
-}
-
-static const struct drm_panel_funcs acx424akp_drm_funcs = {
- .unprepare = acx424akp_unprepare,
- .prepare = acx424akp_prepare,
- .get_modes = acx424akp_get_modes,
-};
-
-static int acx424akp_probe(struct mipi_dsi_device *dsi)
-{
- struct device *dev = &dsi->dev;
- struct acx424akp *acx;
- int ret;
-
- acx = devm_kzalloc(dev, sizeof(struct acx424akp), GFP_KERNEL);
- if (!acx)
- return -ENOMEM;
- acx->video_mode = of_property_read_bool(dev->of_node,
- "enforce-video-mode");
-
- mipi_dsi_set_drvdata(dsi, acx);
- acx->dev = dev;
-
- dsi->lanes = 2;
- dsi->format = MIPI_DSI_FMT_RGB888;
- /*
- * FIXME: these come from the ST-Ericsson vendor driver for the
- * HREF520 and seems to reflect limitations in the PLLs on that
- * platform, if you have the datasheet, please cross-check the
- * actual max rates.
- */
- dsi->lp_rate = 19200000;
- dsi->hs_rate = 420160000;
-
- if (acx->video_mode)
- /* Burst mode using event for sync */
- dsi->mode_flags =
- MIPI_DSI_MODE_VIDEO |
- MIPI_DSI_MODE_VIDEO_BURST;
- else
- dsi->mode_flags =
- MIPI_DSI_CLOCK_NON_CONTINUOUS;
-
- acx->supply = devm_regulator_get(dev, "vddi");
- if (IS_ERR(acx->supply))
- return PTR_ERR(acx->supply);
-
- /* This asserts RESET by default */
- acx->reset_gpio = devm_gpiod_get_optional(dev, "reset",
- GPIOD_OUT_HIGH);
- if (IS_ERR(acx->reset_gpio))
- return dev_err_probe(dev, PTR_ERR(acx->reset_gpio),
- "failed to request GPIO\n");
-
- drm_panel_init(&acx->panel, dev, &acx424akp_drm_funcs,
- DRM_MODE_CONNECTOR_DSI);
-
- acx->panel.backlight = devm_backlight_device_register(dev, "acx424akp", dev, acx,
- &acx424akp_bl_ops, &acx424akp_bl_props);
- if (IS_ERR(acx->panel.backlight))
- return dev_err_probe(dev, PTR_ERR(acx->panel.backlight),
- "failed to register backlight device\n");
-
- drm_panel_add(&acx->panel);
-
- ret = mipi_dsi_attach(dsi);
- if (ret < 0) {
- drm_panel_remove(&acx->panel);
- return ret;
- }
-
- return 0;
-}
-
-static int acx424akp_remove(struct mipi_dsi_device *dsi)
-{
- struct acx424akp *acx = mipi_dsi_get_drvdata(dsi);
-
- mipi_dsi_detach(dsi);
- drm_panel_remove(&acx->panel);
-
- return 0;
-}
-
-static const struct of_device_id acx424akp_of_match[] = {
- { .compatible = "sony,acx424akp" },
- { /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, acx424akp_of_match);
-
-static struct mipi_dsi_driver acx424akp_driver = {
- .probe = acx424akp_probe,
- .remove = acx424akp_remove,
- .driver = {
- .name = "panel-sony-acx424akp",
- .of_match_table = acx424akp_of_match,
- },
-};
-module_mipi_dsi_driver(acx424akp_driver);
-
-MODULE_AUTHOR("Linus Wallei <linus.walleij@linaro.org>");
-MODULE_DESCRIPTION("MIPI-DSI Sony acx424akp Panel Driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/panel/panel-sony-acx565akm.c b/drivers/gpu/drm/panel/panel-sony-acx565akm.c
index ba0b3ead150f..0d7541a33f87 100644
--- a/drivers/gpu/drm/panel/panel-sony-acx565akm.c
+++ b/drivers/gpu/drm/panel/panel-sony-acx565akm.c
@@ -655,7 +655,7 @@ static int acx565akm_probe(struct spi_device *spi)
return 0;
}
-static int acx565akm_remove(struct spi_device *spi)
+static void acx565akm_remove(struct spi_device *spi)
{
struct acx565akm_panel *lcd = spi_get_drvdata(spi);
@@ -666,8 +666,6 @@ static int acx565akm_remove(struct spi_device *spi)
drm_panel_disable(&lcd->panel);
drm_panel_unprepare(&lcd->panel);
-
- return 0;
}
static const struct of_device_id acx565akm_of_match[] = {
diff --git a/drivers/gpu/drm/panel/panel-tpo-td028ttec1.c b/drivers/gpu/drm/panel/panel-tpo-td028ttec1.c
index ba0c00d1a001..4dbf8b88f264 100644
--- a/drivers/gpu/drm/panel/panel-tpo-td028ttec1.c
+++ b/drivers/gpu/drm/panel/panel-tpo-td028ttec1.c
@@ -350,15 +350,13 @@ static int td028ttec1_probe(struct spi_device *spi)
return 0;
}
-static int td028ttec1_remove(struct spi_device *spi)
+static void td028ttec1_remove(struct spi_device *spi)
{
struct td028ttec1_panel *lcd = spi_get_drvdata(spi);
drm_panel_remove(&lcd->panel);
drm_panel_disable(&lcd->panel);
drm_panel_unprepare(&lcd->panel);
-
- return 0;
}
static const struct of_device_id td028ttec1_of_match[] = {
diff --git a/drivers/gpu/drm/panel/panel-tpo-td043mtea1.c b/drivers/gpu/drm/panel/panel-tpo-td043mtea1.c
index 1866cdb8f9c1..cf4609bb9b1d 100644
--- a/drivers/gpu/drm/panel/panel-tpo-td043mtea1.c
+++ b/drivers/gpu/drm/panel/panel-tpo-td043mtea1.c
@@ -463,7 +463,7 @@ static int td043mtea1_probe(struct spi_device *spi)
return 0;
}
-static int td043mtea1_remove(struct spi_device *spi)
+static void td043mtea1_remove(struct spi_device *spi)
{
struct td043mtea1_panel *lcd = spi_get_drvdata(spi);
@@ -472,8 +472,6 @@ static int td043mtea1_remove(struct spi_device *spi)
drm_panel_unprepare(&lcd->panel);
sysfs_remove_group(&spi->dev.kobj, &td043mtea1_attr_group);
-
- return 0;
}
static const struct of_device_id td043mtea1_of_match[] = {
diff --git a/drivers/gpu/drm/panel/panel-tpo-tpg110.c b/drivers/gpu/drm/panel/panel-tpo-tpg110.c
index e3791dad6830..0b1f5a11a055 100644
--- a/drivers/gpu/drm/panel/panel-tpo-tpg110.c
+++ b/drivers/gpu/drm/panel/panel-tpo-tpg110.c
@@ -450,12 +450,11 @@ static int tpg110_probe(struct spi_device *spi)
return 0;
}
-static int tpg110_remove(struct spi_device *spi)
+static void tpg110_remove(struct spi_device *spi)
{
struct tpg110 *tpg = spi_get_drvdata(spi);
drm_panel_remove(&tpg->panel);
- return 0;
}
static const struct of_device_id tpg110_match[] = {
diff --git a/drivers/gpu/drm/panel/panel-widechips-ws2401.c b/drivers/gpu/drm/panel/panel-widechips-ws2401.c
index 8bc976f54b80..236f3cb2b594 100644
--- a/drivers/gpu/drm/panel/panel-widechips-ws2401.c
+++ b/drivers/gpu/drm/panel/panel-widechips-ws2401.c
@@ -407,12 +407,11 @@ static int ws2401_probe(struct spi_device *spi)
return 0;
}
-static int ws2401_remove(struct spi_device *spi)
+static void ws2401_remove(struct spi_device *spi)
{
struct ws2401 *ws = spi_get_drvdata(spi);
drm_panel_remove(&ws->panel);
- return 0;
}
/*