From 9b97383b789c1b2a8d4bc54d142a12f9d0a12aa1 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Fri, 5 Dec 2014 11:46:56 +0100 Subject: [PATCH 01/23] drm/mipi-dsi: Avoid potential NULL pointer dereference The mipi_dsi_packet_create() function dereferences the msg pointer before checking that it's valid. Move the dereference down to where it is required to avoid potentially dereferencing a NULL pointer. Reported-by: Dan Carpenter Signed-off-by: Thierry Reding --- drivers/gpu/drm/drm_mipi_dsi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index c0644bb865f2..2d5ca8eec13a 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c @@ -323,8 +323,6 @@ EXPORT_SYMBOL(mipi_dsi_packet_format_is_long); int mipi_dsi_create_packet(struct mipi_dsi_packet *packet, const struct mipi_dsi_msg *msg) { - const u8 *tx = msg->tx_buf; - if (!packet || !msg) return -EINVAL; @@ -353,8 +351,10 @@ int mipi_dsi_create_packet(struct mipi_dsi_packet *packet, packet->header[2] = (msg->tx_len >> 8) & 0xff; packet->payload_length = msg->tx_len; - packet->payload = tx; + packet->payload = msg->tx_buf; } else { + const u8 *tx = msg->tx_buf; + packet->header[1] = (msg->tx_len > 0) ? tx[0] : 0; packet->header[2] = (msg->tx_len > 1) ? tx[1] : 0; } From f65110e6800ef76f1c683cca9189b099e4d65a0b Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 19 Nov 2014 10:29:54 +0100 Subject: [PATCH 02/23] of: Add vendor prefix for Giantplus Technology Co., Ltd. Signed-off-by: Philipp Zabel Signed-off-by: Lucas Stach Acked-by: Rob Herring Signed-off-by: Thierry Reding --- Documentation/devicetree/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index b1df0ad1306c..8b6ae0bd4896 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -62,6 +62,7 @@ fsl Freescale Semiconductor GEFanuc GE Fanuc Intelligent Platforms Embedded Systems, Inc. gef GE Fanuc Intelligent Platforms Embedded Systems, Inc. geniatech Geniatech, Inc. +giantplus Giantplus Technology Co., Ltd. globalscale Globalscale Technologies, Inc. gmt Global Mixed-mode Technology, Inc. google Google, Inc. From d435a2af12349e6285559196675ad45f1e4a041d Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 19 Nov 2014 10:29:55 +0100 Subject: [PATCH 03/23] drm/panel: simple: Add support for Giantplus GPG482739QS5 This patch adds support for the GiantPlus GPG48273QS5 4.3" WQVGA TFT LCD panel to the simple-panel driver. This panel is connected via a parallel bus and uses both HSYNC and VSYNC, whose lengths are unfortunately not clearly defined. The datasheet only specifies the front- and backporch length, but the timing diagram suggests that both sync signals should be asserted for exactly one clock cycle. Signed-off-by: Philipp Zabel Signed-off-by: Lucas Stach Signed-off-by: Thierry Reding --- .../bindings/panel/giantplus,gpg482739qs5.txt | 7 +++++ drivers/gpu/drm/panel/panel-simple.c | 26 +++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 Documentation/devicetree/bindings/panel/giantplus,gpg482739qs5.txt diff --git a/Documentation/devicetree/bindings/panel/giantplus,gpg482739qs5.txt b/Documentation/devicetree/bindings/panel/giantplus,gpg482739qs5.txt new file mode 100644 index 000000000000..24b0b624434b --- /dev/null +++ b/Documentation/devicetree/bindings/panel/giantplus,gpg482739qs5.txt @@ -0,0 +1,7 @@ +GiantPlus GPG48273QS5 4.3" (480x272) WQVGA TFT LCD panel + +Required properties: +- compatible: should be "giantplus,gpg48273qs5" + +This binding is compatible with the simple-panel binding, which is specified +in simple-panel.txt in this directory. diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 6049d245c20e..787983c3603d 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -566,6 +566,29 @@ static const struct panel_desc foxlink_fl500wvr00_a0t = { .bus_format = MEDIA_BUS_FMT_RGB888_1X24, }; +static const struct drm_display_mode giantplus_gpg482739qs5_mode = { + .clock = 9000, + .hdisplay = 480, + .hsync_start = 480 + 5, + .hsync_end = 480 + 5 + 1, + .htotal = 480 + 5 + 1 + 40, + .vdisplay = 272, + .vsync_start = 272 + 8, + .vsync_end = 272 + 8 + 1, + .vtotal = 272 + 8 + 1 + 8, + .vrefresh = 60, +}; + +static const struct panel_desc giantplus_gpg482739qs5 = { + .modes = &giantplus_gpg482739qs5_mode, + .num_modes = 1, + .bpc = 8, + .size = { + .width = 95, + .height = 54, + }, +}; + static const struct drm_display_mode hannstar_hsd070pww1_mode = { .clock = 71100, .hdisplay = 1280, @@ -762,6 +785,9 @@ static const struct of_device_id platform_of_match[] = { }, { .compatible = "foxlink,fl500wvr00-a0t", .data = &foxlink_fl500wvr00_a0t, + }, { + .compatible = "giantplus,gpg482739qs5", + .data = &giantplus_gpg482739qs5 }, { .compatible = "hannstar,hsd070pww1", .data = &hannstar_hsd070pww1, From 4569619d0f3a38c41a4556c79ef63cabd4282558 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 8 Dec 2014 15:05:48 +0100 Subject: [PATCH 04/23] drm/panel: sharp: lq101r1sx01: Add delay after display on After switching the display on (using the DCS display_on command), wait for 6 frames (100ms at 60 Hz) to give the display more time to prepare. Failing to do this results in the panel not initializing properly in a large number of cases. Signed-off-by: Thierry Reding --- drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c b/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c index 9d81759d82fc..8a11e83ab582 100644 --- a/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c +++ b/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c @@ -41,6 +41,16 @@ static inline struct sharp_panel *to_sharp_panel(struct drm_panel *panel) return container_of(panel, struct sharp_panel, base); } +static void sharp_wait_frames(struct sharp_panel *sharp, unsigned int frames) +{ + unsigned int refresh = drm_mode_vrefresh(sharp->mode); + + if (WARN_ON(frames > refresh)) + return; + + msleep(1000 / (refresh / frames)); +} + static int sharp_panel_write(struct sharp_panel *sharp, u16 offset, u8 value) { u8 payload[3] = { offset >> 8, offset & 0xff, value }; @@ -238,6 +248,9 @@ static int sharp_panel_prepare(struct drm_panel *panel) sharp->prepared = true; + /* wait for 6 frames before continuing */ + sharp_wait_frames(sharp, 6); + return 0; poweroff: From ee920bca27da6c33de6ee73de7b34dee0298f703 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 8 Dec 2014 15:38:17 +0100 Subject: [PATCH 05/23] drm/panel: sharp: lq101r1sx01: Respect power timings Before shutting down the display using the DCS display_off command, wait for 4 frames according to the datasheet. Furthermore, after enabling the power supply, the supply voltage needs around 10 ms to settle. After that, another 120 ms is required before a DCS exit_sleep_mode command can be sent. While at it, no longer send the DCS soft_reset command. This is totally unnecessary because we've just powered up the display, hence it will be in a reset state already. Signed-off-by: Thierry Reding --- .../gpu/drm/panel/panel-sharp-lq101r1sx01.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c b/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c index 8a11e83ab582..745ceb1ef36e 100644 --- a/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c +++ b/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c @@ -116,6 +116,8 @@ static int sharp_panel_unprepare(struct drm_panel *panel) if (!sharp->prepared) return 0; + sharp_wait_frames(sharp, 4); + err = mipi_dsi_dcs_set_display_off(sharp->link1); if (err < 0) dev_err(panel->dev, "failed to set display off: %d\n", err); @@ -180,15 +182,13 @@ static int sharp_panel_prepare(struct drm_panel *panel) if (err < 0) return err; - usleep_range(10000, 20000); - - err = mipi_dsi_dcs_soft_reset(sharp->link1); - if (err < 0) { - dev_err(panel->dev, "soft reset failed: %d\n", err); - goto poweroff; - } - - msleep(120); + /* + * According to the datasheet, the panel needs around 10 ms to fully + * power up. At least another 120 ms is required before exiting sleep + * mode to make sure the panel is ready. Throw in another 20 ms for + * good measure. + */ + msleep(150); err = mipi_dsi_dcs_exit_sleep_mode(sharp->link1); if (err < 0) { From d6e8d3bc34358c9b5c81786f6ac5c1ab96a62de6 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 18 Dec 2014 17:11:47 +0100 Subject: [PATCH 06/23] drm/panel: sharp: lq101r1sx01: Remove unneeded include Nothing in the file needs symbols from include/linux/host1x.h, so remove the include. Signed-off-by: Thierry Reding --- drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c b/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c index 745ceb1ef36e..3cce3ca19601 100644 --- a/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c +++ b/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c @@ -19,8 +19,6 @@ #include