summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2015-12-16 17:37:52 -0500
committerDave Airlie <airlied@redhat.com>2015-12-16 17:37:52 -0500
commit07ade8446192296fa7149a035c1d2e14341fbc22 (patch)
treeefaa14f48cfc0b4da214db8df89392478e4642bb
parent51bce5bc38bdb79c0f7ab33f1fe91a68ef1afa77 (diff)
parentd2a6f0f5597696ebf5bb34089be3b88ba2455b7a (diff)
Merge tag 'drm/panel/for-4.5-rc1' of git://anongit.freedesktop.org/tegra/linux into drm-next
drm/panel: Changes for v4.5-rc1 This set of changes brings in a few more helpers for DSI support as well as a couple of new drivers and support for some more simple panels. * tag 'drm/panel/for-4.5-rc1' of git://anongit.freedesktop.org/tegra/linux: drm/panel: simple: Add QiaoDian qd43003c0-40 of: Add vendor prefix for QiaoDian Xianshi drm/panel: add kernel doc for size attributes in panel_desc drm/panel: simple: Add support for Kyocera TCG121XGLP panel devicetree: add vendor prefix for Kyocera Corporation drm/bridge: Remove gratuitous blank line drm/bridge: dw-hdmi: Use dashes in filenames drm/panel: Add Sharp LS043T1LE01 MIPI DSI panel dt-bindings: Add Sharp LS043T1LE01 panel binding drm/dsi: Add Turn On/Shutdown Peripheral command helpers drm/panel: Add Panasonic VVX10F034N00 MIPI DSI panel dt-bindings: Add Panasonic VVX10F034N00 panel binding drm/panel: simple: Add support for Innolux G121X1-L03 drm/panel: simple: Add support for BOE TV080WUM-NL0 dt-bindings: Add BOE TV080WUM-NL0 panel binding of: Add vendor prefix for BOE Technology Group drm/dsi: Add a helper to get bits per pixel of MIPI DSI pixel format
-rw-r--r--Documentation/devicetree/bindings/display/panel/boe,tv080wum-nl0.txt7
-rw-r--r--Documentation/devicetree/bindings/display/panel/innolux,g121x1-l03.txt7
-rw-r--r--Documentation/devicetree/bindings/display/panel/kyo,tcg121xglp.txt7
-rw-r--r--Documentation/devicetree/bindings/display/panel/sharp,ls043t1le01.txt22
-rw-r--r--Documentation/devicetree/bindings/panel/panasonic,vvx10f034n00.txt20
-rw-r--r--Documentation/devicetree/bindings/panel/qiaodian,qd43003c0-40.txt7
-rw-r--r--Documentation/devicetree/bindings/vendor-prefixes.txt3
-rw-r--r--drivers/gpu/drm/bridge/Kconfig1
-rw-r--r--drivers/gpu/drm/bridge/Makefile4
-rw-r--r--drivers/gpu/drm/bridge/dw-hdmi-ahb-audio.c (renamed from drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c)2
-rw-r--r--drivers/gpu/drm/bridge/dw-hdmi-audio.h (renamed from drivers/gpu/drm/bridge/dw_hdmi-audio.h)0
-rw-r--r--drivers/gpu/drm/bridge/dw-hdmi.c (renamed from drivers/gpu/drm/bridge/dw_hdmi.c)4
-rw-r--r--drivers/gpu/drm/bridge/dw-hdmi.h (renamed from drivers/gpu/drm/bridge/dw_hdmi.h)0
-rw-r--r--drivers/gpu/drm/drm_mipi_dsi.c38
-rw-r--r--drivers/gpu/drm/panel/Kconfig19
-rw-r--r--drivers/gpu/drm/panel/Makefile2
-rw-r--r--drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c334
-rw-r--r--drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c387
-rw-r--r--drivers/gpu/drm/panel/panel-simple.c123
-rw-r--r--include/drm/drm_mipi_dsi.h27
20 files changed, 1008 insertions, 6 deletions
diff --git a/Documentation/devicetree/bindings/display/panel/boe,tv080wum-nl0.txt b/Documentation/devicetree/bindings/display/panel/boe,tv080wum-nl0.txt
new file mode 100644
index 000000000000..50be5e2438b2
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/boe,tv080wum-nl0.txt
@@ -0,0 +1,7 @@
1Boe Corporation 8.0" WUXGA TFT LCD panel
2
3Required properties:
4- compatible: should be "boe,tv080wum-nl0"
5
6This binding is compatible with the simple-panel binding, which is specified
7in simple-panel.txt in this directory.
diff --git a/Documentation/devicetree/bindings/display/panel/innolux,g121x1-l03.txt b/Documentation/devicetree/bindings/display/panel/innolux,g121x1-l03.txt
new file mode 100644
index 000000000000..649744620ae1
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/innolux,g121x1-l03.txt
@@ -0,0 +1,7 @@
1Innolux Corporation 12.1" G121X1-L03 XGA (1024x768) TFT LCD panel
2
3Required properties:
4- compatible: should be "innolux,g121x1-l03"
5
6This binding is compatible with the simple-panel binding, which is specified
7in simple-panel.txt in this directory.
diff --git a/Documentation/devicetree/bindings/display/panel/kyo,tcg121xglp.txt b/Documentation/devicetree/bindings/display/panel/kyo,tcg121xglp.txt
new file mode 100644
index 000000000000..a8e940fe731e
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/kyo,tcg121xglp.txt
@@ -0,0 +1,7 @@
1Kyocera Corporation 12.1" XGA (1024x768) TFT LCD panel
2
3Required properties:
4- compatible: should be "kyo,tcg121xglp"
5
6This binding is compatible with the simple-panel binding, which is specified
7in simple-panel.txt in this directory.
diff --git a/Documentation/devicetree/bindings/display/panel/sharp,ls043t1le01.txt b/Documentation/devicetree/bindings/display/panel/sharp,ls043t1le01.txt
new file mode 100644
index 000000000000..3770a111968b
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/sharp,ls043t1le01.txt
@@ -0,0 +1,22 @@
1Sharp Microelectronics 4.3" qHD TFT LCD panel
2
3Required properties:
4- compatible: should be "sharp,ls043t1le01-qhd"
5- reg: DSI virtual channel of the peripheral
6- power-supply: phandle of the regulator that provides the supply voltage
7
8Optional properties:
9- backlight: phandle of the backlight device attached to the panel
10- reset-gpios: a GPIO spec for the reset pin
11
12Example:
13
14 mdss_dsi@fd922800 {
15 panel@0 {
16 compatible = "sharp,ls043t1le01-qhd";
17 reg = <0>;
18 avdd-supply = <&pm8941_l22>;
19 backlight = <&pm8941_wled>;
20 reset-gpios = <&pm8941_gpios 19 GPIO_ACTIVE_HIGH>;
21 };
22 };
diff --git a/Documentation/devicetree/bindings/panel/panasonic,vvx10f034n00.txt b/Documentation/devicetree/bindings/panel/panasonic,vvx10f034n00.txt
new file mode 100644
index 000000000000..37dedf6a6702
--- /dev/null
+++ b/Documentation/devicetree/bindings/panel/panasonic,vvx10f034n00.txt
@@ -0,0 +1,20 @@
1Panasonic 10" WUXGA TFT LCD panel
2
3Required properties:
4- compatible: should be "panasonic,vvx10f034n00"
5- reg: DSI virtual channel of the peripheral
6- power-supply: phandle of the regulator that provides the supply voltage
7
8Optional properties:
9- backlight: phandle of the backlight device attached to the panel
10
11Example:
12
13 mdss_dsi@fd922800 {
14 panel@0 {
15 compatible = "panasonic,vvx10f034n00";
16 reg = <0>;
17 power-supply = <&vreg_vsp>;
18 backlight = <&lp8566_wled>;
19 };
20 };
diff --git a/Documentation/devicetree/bindings/panel/qiaodian,qd43003c0-40.txt b/Documentation/devicetree/bindings/panel/qiaodian,qd43003c0-40.txt
new file mode 100644
index 000000000000..0fbdab89ac3d
--- /dev/null
+++ b/Documentation/devicetree/bindings/panel/qiaodian,qd43003c0-40.txt
@@ -0,0 +1,7 @@
1QiaoDian XianShi Corporation 4"3 TFT LCD panel
2
3Required properties:
4- compatible: should be "qiaodian,qd43003c0-40"
5
6This binding is compatible with the simple-panel binding, which is specified
7in simple-panel.txt in this directory.
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 55df1d444e9f..6b0fc4ff3c47 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -33,6 +33,7 @@ auo AU Optronics Corporation
33avago Avago Technologies 33avago Avago Technologies
34avic Shanghai AVIC Optoelectronics Co., Ltd. 34avic Shanghai AVIC Optoelectronics Co., Ltd.
35axis Axis Communications AB 35axis Axis Communications AB
36boe BOE Technology Group Co., Ltd.
36bosch Bosch Sensortec GmbH 37bosch Bosch Sensortec GmbH
37boundary Boundary Devices Inc. 38boundary Boundary Devices Inc.
38brcm Broadcom Corporation 39brcm Broadcom Corporation
@@ -123,6 +124,7 @@ jedec JEDEC Solid State Technology Association
123karo Ka-Ro electronics GmbH 124karo Ka-Ro electronics GmbH
124keymile Keymile GmbH 125keymile Keymile GmbH
125kinetic Kinetic Technologies 126kinetic Kinetic Technologies
127kyo Kyocera Corporation
126lacie LaCie 128lacie LaCie
127lantiq Lantiq Semiconductor 129lantiq Lantiq Semiconductor
128lenovo Lenovo Group Ltd. 130lenovo Lenovo Group Ltd.
@@ -180,6 +182,7 @@ qca Qualcomm Atheros, Inc.
180qcom Qualcomm Technologies, Inc 182qcom Qualcomm Technologies, Inc
181qemu QEMU, a generic and open source machine emulator and virtualizer 183qemu QEMU, a generic and open source machine emulator and virtualizer
182qi Qi Hardware 184qi Qi Hardware
185qiaodian QiaoDian XianShi Corporation
183qnap QNAP Systems, Inc. 186qnap QNAP Systems, Inc.
184radxa Radxa 187radxa Radxa
185raidsonic RaidSonic Technology GmbH 188raidsonic RaidSonic Technology GmbH
diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index 6dddd392aa42..27e2022de89d 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -22,7 +22,6 @@ config DRM_DW_HDMI_AHB_AUDIO
22 Designware HDMI block. This is used in conjunction with 22 Designware HDMI block. This is used in conjunction with
23 the i.MX6 HDMI driver. 23 the i.MX6 HDMI driver.
24 24
25
26config DRM_NXP_PTN3460 25config DRM_NXP_PTN3460
27 tristate "NXP PTN3460 DP/LVDS bridge" 26 tristate "NXP PTN3460 DP/LVDS bridge"
28 depends on OF 27 depends on OF
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index d4e28beec30e..f13c33d67c03 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -1,6 +1,6 @@
1ccflags-y := -Iinclude/drm 1ccflags-y := -Iinclude/drm
2 2
3obj-$(CONFIG_DRM_DW_HDMI) += dw_hdmi.o 3obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
4obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw_hdmi-ahb-audio.o 4obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
5obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o 5obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o
6obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o 6obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o
diff --git a/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c b/drivers/gpu/drm/bridge/dw-hdmi-ahb-audio.c
index 59f630f1c61a..122bb015f4a9 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi-ahb-audio.c
@@ -21,7 +21,7 @@
21#include <sound/pcm_drm_eld.h> 21#include <sound/pcm_drm_eld.h>
22#include <sound/pcm_iec958.h> 22#include <sound/pcm_iec958.h>
23 23
24#include "dw_hdmi-audio.h" 24#include "dw-hdmi-audio.h"
25 25
26#define DRIVER_NAME "dw-hdmi-ahb-audio" 26#define DRIVER_NAME "dw-hdmi-ahb-audio"
27 27
diff --git a/drivers/gpu/drm/bridge/dw_hdmi-audio.h b/drivers/gpu/drm/bridge/dw-hdmi-audio.h
index 91f631beecc7..91f631beecc7 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi-audio.h
+++ b/drivers/gpu/drm/bridge/dw-hdmi-audio.h
diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
index 56de9f1c95fc..298018a8562e 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -27,8 +27,8 @@
27#include <drm/drm_encoder_slave.h> 27#include <drm/drm_encoder_slave.h>
28#include <drm/bridge/dw_hdmi.h> 28#include <drm/bridge/dw_hdmi.h>
29 29
30#include "dw_hdmi.h" 30#include "dw-hdmi.h"
31#include "dw_hdmi-audio.h" 31#include "dw-hdmi-audio.h"
32 32
33#define HDMI_EDID_LEN 512 33#define HDMI_EDID_LEN 512
34 34
diff --git a/drivers/gpu/drm/bridge/dw_hdmi.h b/drivers/gpu/drm/bridge/dw-hdmi.h
index fc9a560429d6..fc9a560429d6 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.h
+++ b/drivers/gpu/drm/bridge/dw-hdmi.h
diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index 2d5ca8eec13a..6e6a9c58d404 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -365,6 +365,44 @@ int mipi_dsi_create_packet(struct mipi_dsi_packet *packet,
365} 365}
366EXPORT_SYMBOL(mipi_dsi_create_packet); 366EXPORT_SYMBOL(mipi_dsi_create_packet);
367 367
368/**
369 * mipi_dsi_shutdown_peripheral() - sends a Shutdown Peripheral command
370 * @dsi: DSI peripheral device
371 *
372 * Return: 0 on success or a negative error code on failure.
373 */
374int mipi_dsi_shutdown_peripheral(struct mipi_dsi_device *dsi)
375{
376 struct mipi_dsi_msg msg = {
377 .channel = dsi->channel,
378 .type = MIPI_DSI_SHUTDOWN_PERIPHERAL,
379 .tx_buf = (u8 [2]) { 0, 0 },
380 .tx_len = 2,
381 };
382
383 return mipi_dsi_device_transfer(dsi, &msg);
384}
385EXPORT_SYMBOL(mipi_dsi_shutdown_peripheral);
386
387/**
388 * mipi_dsi_turn_on_peripheral() - sends a Turn On Peripheral command
389 * @dsi: DSI peripheral device
390 *
391 * Return: 0 on success or a negative error code on failure.
392 */
393int mipi_dsi_turn_on_peripheral(struct mipi_dsi_device *dsi)
394{
395 struct mipi_dsi_msg msg = {
396 .channel = dsi->channel,
397 .type = MIPI_DSI_TURN_ON_PERIPHERAL,
398 .tx_buf = (u8 [2]) { 0, 0 },
399 .tx_len = 2,
400 };
401
402 return mipi_dsi_device_transfer(dsi, &msg);
403}
404EXPORT_SYMBOL(mipi_dsi_turn_on_peripheral);
405
368/* 406/*
369 * mipi_dsi_set_maximum_return_packet_size() - specify the maximum size of the 407 * mipi_dsi_set_maximum_return_packet_size() - specify the maximum size of the
370 * the payload in a long packet transmitted from the peripheral back to the 408 * the payload in a long packet transmitted from the peripheral back to the
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 7d4704b1292b..1500ab99f548 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -31,6 +31,16 @@ config DRM_PANEL_LG_LG4573
31 Say Y here if you want to enable support for LG4573 RGB panel. 31 Say Y here if you want to enable support for LG4573 RGB panel.
32 To compile this driver as a module, choose M here. 32 To compile this driver as a module, choose M here.
33 33
34config DRM_PANEL_PANASONIC_VVX10F034N00
35 tristate "Panasonic VVX10F034N00 1920x1200 video mode panel"
36 depends on OF
37 depends on DRM_MIPI_DSI
38 depends on BACKLIGHT_CLASS_DEVICE
39 help
40 Say Y here if you want to enable support for Panasonic VVX10F034N00
41 WUXGA (1920x1200) Novatek NT1397-based DSI panel as found in some
42 Xperia Z2 tablets
43
34config DRM_PANEL_SAMSUNG_S6E8AA0 44config DRM_PANEL_SAMSUNG_S6E8AA0
35 tristate "Samsung S6E8AA0 DSI video mode panel" 45 tristate "Samsung S6E8AA0 DSI video mode panel"
36 depends on OF 46 depends on OF
@@ -51,4 +61,13 @@ config DRM_PANEL_SHARP_LQ101R1SX01
51 To compile this driver as a module, choose M here: the module 61 To compile this driver as a module, choose M here: the module
52 will be called panel-sharp-lq101r1sx01. 62 will be called panel-sharp-lq101r1sx01.
53 63
64config DRM_PANEL_SHARP_LS043T1LE01
65 tristate "Sharp LS043T1LE01 qHD video mode panel"
66 depends on OF
67 depends on DRM_MIPI_DSI
68 depends on BACKLIGHT_CLASS_DEVICE
69 help
70 Say Y here if you want to enable support for Sharp LS043T1LE01 qHD
71 (540x960) DSI panel as found on the Qualcomm APQ8074 Dragonboard
72
54endmenu 73endmenu
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index d0f016dd7ddb..f277eed933d6 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -1,5 +1,7 @@
1obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o 1obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o
2obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o 2obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o
3obj-$(CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00) += panel-panasonic-vvx10f034n00.o
3obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o 4obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o
4obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0) += panel-samsung-s6e8aa0.o 5obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0) += panel-samsung-s6e8aa0.o
5obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o 6obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o
7obj-$(CONFIG_DRM_PANEL_SHARP_LS043T1LE01) += panel-sharp-ls043t1le01.o
diff --git a/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c b/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c
new file mode 100644
index 000000000000..7f915f706fa6
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c
@@ -0,0 +1,334 @@
1/*
2 * Copyright (C) 2015 Red Hat
3 * Copyright (C) 2015 Sony Mobile Communications Inc.
4 * Author: Werner Johansson <werner.johansson@sonymobile.com>
5 *
6 * Based on AUO panel driver by Rob Clark <robdclark@gmail.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published by
10 * the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <linux/backlight.h>
22#include <linux/module.h>
23#include <linux/of.h>
24#include <linux/regulator/consumer.h>
25
26#include <drm/drmP.h>
27#include <drm/drm_crtc.h>
28#include <drm/drm_mipi_dsi.h>
29#include <drm/drm_panel.h>
30
31#include <video/mipi_display.h>
32
33/*
34 * When power is turned off to this panel a minimum off time of 500ms has to be
35 * observed before powering back on as there's no external reset pin. Keep
36 * track of earliest wakeup time and delay subsequent prepare call accordingly
37 */
38#define MIN_POFF_MS (500)
39
40struct wuxga_nt_panel {
41 struct drm_panel base;
42 struct mipi_dsi_device *dsi;
43
44 struct backlight_device *backlight;
45 struct regulator *supply;
46
47 bool prepared;
48 bool enabled;
49
50 ktime_t earliest_wake;
51
52 const struct drm_display_mode *mode;
53};
54
55static inline struct wuxga_nt_panel *to_wuxga_nt_panel(struct drm_panel *panel)
56{
57 return container_of(panel, struct wuxga_nt_panel, base);
58}
59
60static int wuxga_nt_panel_on(struct wuxga_nt_panel *wuxga_nt)
61{
62 struct mipi_dsi_device *dsi = wuxga_nt->dsi;
63 int ret;
64
65 ret = mipi_dsi_turn_on_peripheral(dsi);
66 if (ret < 0)
67 return ret;
68
69 return 0;
70}
71
72static int wuxga_nt_panel_disable(struct drm_panel *panel)
73{
74 struct wuxga_nt_panel *wuxga_nt = to_wuxga_nt_panel(panel);
75
76 if (!wuxga_nt->enabled)
77 return 0;
78
79 mipi_dsi_shutdown_peripheral(wuxga_nt->dsi);
80
81 if (wuxga_nt->backlight) {
82 wuxga_nt->backlight->props.power = FB_BLANK_POWERDOWN;
83 wuxga_nt->backlight->props.state |= BL_CORE_FBBLANK;
84 backlight_update_status(wuxga_nt->backlight);
85 }
86
87 wuxga_nt->enabled = false;
88
89 return 0;
90}
91
92static int wuxga_nt_panel_unprepare(struct drm_panel *panel)
93{
94 struct wuxga_nt_panel *wuxga_nt = to_wuxga_nt_panel(panel);
95
96 if (!wuxga_nt->prepared)
97 return 0;
98
99 regulator_disable(wuxga_nt->supply);
100 wuxga_nt->earliest_wake = ktime_add_ms(ktime_get_real(), MIN_POFF_MS);
101 wuxga_nt->prepared = false;
102
103 return 0;
104}
105
106static int wuxga_nt_panel_prepare(struct drm_panel *panel)
107{
108 struct wuxga_nt_panel *wuxga_nt = to_wuxga_nt_panel(panel);
109 int ret;
110 s64 enablewait;
111
112 if (wuxga_nt->prepared)
113 return 0;
114
115 /*
116 * If the user re-enabled the panel before the required off-time then
117 * we need to wait the remaining period before re-enabling regulator
118 */
119 enablewait = ktime_ms_delta(wuxga_nt->earliest_wake, ktime_get_real());
120
121 /* Sanity check, this should never happen */
122 if (enablewait > MIN_POFF_MS)
123 enablewait = MIN_POFF_MS;
124
125 if (enablewait > 0)
126 msleep(enablewait);
127
128 ret = regulator_enable(wuxga_nt->supply);
129 if (ret < 0)
130 return ret;
131
132 /*
133 * A minimum delay of 250ms is required after power-up until commands
134 * can be sent
135 */
136 msleep(250);
137
138 ret = wuxga_nt_panel_on(wuxga_nt);
139 if (ret < 0) {
140 dev_err(panel->dev, "failed to set panel on: %d\n", ret);
141 goto poweroff;
142 }
143
144 wuxga_nt->prepared = true;
145
146 return 0;
147
148poweroff:
149 regulator_disable(wuxga_nt->supply);
150
151 return ret;
152}
153
154static int wuxga_nt_panel_enable(struct drm_panel *panel)
155{
156 struct wuxga_nt_panel *wuxga_nt = to_wuxga_nt_panel(panel);
157
158 if (wuxga_nt->enabled)
159 return 0;
160
161 if (wuxga_nt->backlight) {
162 wuxga_nt->backlight->props.power = FB_BLANK_UNBLANK;
163 wuxga_nt->backlight->props.state &= ~BL_CORE_FBBLANK;
164 backlight_update_status(wuxga_nt->backlight);
165 }
166
167 wuxga_nt->enabled = true;
168
169 return 0;
170}
171
172static const struct drm_display_mode default_mode = {
173 .clock = 164402,
174 .hdisplay = 1920,
175 .hsync_start = 1920 + 152,
176 .hsync_end = 1920 + 152 + 52,
177 .htotal = 1920 + 152 + 52 + 20,
178 .vdisplay = 1200,
179 .vsync_start = 1200 + 24,
180 .vsync_end = 1200 + 24 + 6,
181 .vtotal = 1200 + 24 + 6 + 48,
182 .vrefresh = 60,
183};
184
185static int wuxga_nt_panel_get_modes(struct drm_panel *panel)
186{
187 struct drm_display_mode *mode;
188
189 mode = drm_mode_duplicate(panel->drm, &default_mode);
190 if (!mode) {
191 dev_err(panel->drm->dev, "failed to add mode %ux%ux@%u\n",
192 default_mode.hdisplay, default_mode.vdisplay,
193 default_mode.vrefresh);
194 return -ENOMEM;
195 }
196
197 drm_mode_set_name(mode);
198
199 drm_mode_probed_add(panel->connector, mode);
200
201 panel->connector->display_info.width_mm = 217;
202 panel->connector->display_info.height_mm = 136;
203
204 return 1;
205}
206
207static const struct drm_panel_funcs wuxga_nt_panel_funcs = {
208 .disable = wuxga_nt_panel_disable,
209 .unprepare = wuxga_nt_panel_unprepare,
210 .prepare = wuxga_nt_panel_prepare,
211 .enable = wuxga_nt_panel_enable,
212 .get_modes = wuxga_nt_panel_get_modes,
213};
214
215static const struct of_device_id wuxga_nt_of_match[] = {
216 { .compatible = "panasonic,vvx10f034n00", },
217 { }
218};
219MODULE_DEVICE_TABLE(of, wuxga_nt_of_match);
220
221static int wuxga_nt_panel_add(struct wuxga_nt_panel *wuxga_nt)
222{
223 struct device *dev = &wuxga_nt->dsi->dev;
224 struct device_node *np;
225 int ret;
226
227 wuxga_nt->mode = &default_mode;
228
229 wuxga_nt->supply = devm_regulator_get(dev, "power");
230 if (IS_ERR(wuxga_nt->supply))
231 return PTR_ERR(wuxga_nt->supply);
232
233 np = of_parse_phandle(dev->of_node, "backlight", 0);
234 if (np) {
235 wuxga_nt->backlight = of_find_backlight_by_node(np);
236 of_node_put(np);
237
238 if (!wuxga_nt->backlight)
239 return -EPROBE_DEFER;
240 }
241
242 drm_panel_init(&wuxga_nt->base);
243 wuxga_nt->base.funcs = &wuxga_nt_panel_funcs;
244 wuxga_nt->base.dev = &wuxga_nt->dsi->dev;
245
246 ret = drm_panel_add(&wuxga_nt->base);
247 if (ret < 0)
248 goto put_backlight;
249
250 return 0;
251
252put_backlight:
253 if (wuxga_nt->backlight)
254 put_device(&wuxga_nt->backlight->dev);
255
256 return ret;
257}
258
259static void wuxga_nt_panel_del(struct wuxga_nt_panel *wuxga_nt)
260{
261 if (wuxga_nt->base.dev)
262 drm_panel_remove(&wuxga_nt->base);
263
264 if (wuxga_nt->backlight)
265 put_device(&wuxga_nt->backlight->dev);
266}
267
268static int wuxga_nt_panel_probe(struct mipi_dsi_device *dsi)
269{
270 struct wuxga_nt_panel *wuxga_nt;
271 int ret;
272
273 dsi->lanes = 4;
274 dsi->format = MIPI_DSI_FMT_RGB888;
275 dsi->mode_flags = MIPI_DSI_MODE_VIDEO |
276 MIPI_DSI_MODE_VIDEO_HSE |
277 MIPI_DSI_CLOCK_NON_CONTINUOUS |
278 MIPI_DSI_MODE_LPM;
279
280 wuxga_nt = devm_kzalloc(&dsi->dev, sizeof(*wuxga_nt), GFP_KERNEL);
281 if (!wuxga_nt)
282 return -ENOMEM;
283
284 mipi_dsi_set_drvdata(dsi, wuxga_nt);
285
286 wuxga_nt->dsi = dsi;
287
288 ret = wuxga_nt_panel_add(wuxga_nt);
289 if (ret < 0)
290 return ret;
291
292 return mipi_dsi_attach(dsi);
293}
294
295static int wuxga_nt_panel_remove(struct mipi_dsi_device *dsi)
296{
297 struct wuxga_nt_panel *wuxga_nt = mipi_dsi_get_drvdata(dsi);
298 int ret;
299
300 ret = wuxga_nt_panel_disable(&wuxga_nt->base);
301 if (ret < 0)
302 dev_err(&dsi->dev, "failed to disable panel: %d\n", ret);
303
304 ret = mipi_dsi_detach(dsi);
305 if (ret < 0)
306 dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", ret);
307
308 drm_panel_detach(&wuxga_nt->base);
309 wuxga_nt_panel_del(wuxga_nt);
310
311 return 0;
312}
313
314static void wuxga_nt_panel_shutdown(struct mipi_dsi_device *dsi)
315{
316 struct wuxga_nt_panel *wuxga_nt = mipi_dsi_get_drvdata(dsi);
317
318 wuxga_nt_panel_disable(&wuxga_nt->base);
319}
320
321static struct mipi_dsi_driver wuxga_nt_panel_driver = {
322 .driver = {
323 .name = "panel-panasonic-vvx10f034n00",
324 .of_match_table = wuxga_nt_of_match,
325 },
326 .probe = wuxga_nt_panel_probe,
327 .remove = wuxga_nt_panel_remove,
328 .shutdown = wuxga_nt_panel_shutdown,
329};
330module_mipi_dsi_driver(wuxga_nt_panel_driver);
331
332MODULE_AUTHOR("Werner Johansson <werner.johansson@sonymobile.com>");
333MODULE_DESCRIPTION("Panasonic VVX10F034N00 Novatek NT1397-based WUXGA (1920x1200) video mode panel driver");
334MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c b/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c
new file mode 100644
index 000000000000..3aeb0bda4947
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c
@@ -0,0 +1,387 @@
1/*
2 * Copyright (C) 2015 Red Hat
3 * Copyright (C) 2015 Sony Mobile Communications Inc.
4 * Author: Werner Johansson <werner.johansson@sonymobile.com>
5 *
6 * Based on AUO panel driver by Rob Clark <robdclark@gmail.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published by
10 * the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <linux/backlight.h>
22#include <linux/gpio/consumer.h>
23#include <linux/module.h>
24#include <linux/of.h>
25#include <linux/regulator/consumer.h>
26
27#include <drm/drmP.h>
28#include <drm/drm_crtc.h>
29#include <drm/drm_mipi_dsi.h>
30#include <drm/drm_panel.h>
31
32#include <video/mipi_display.h>
33
34struct sharp_nt_panel {
35 struct drm_panel base;
36 struct mipi_dsi_device *dsi;
37
38 struct backlight_device *backlight;
39 struct regulator *supply;
40 struct gpio_desc *reset_gpio;
41
42 bool prepared;
43 bool enabled;
44
45 const struct drm_display_mode *mode;
46};
47
48static inline struct sharp_nt_panel *to_sharp_nt_panel(struct drm_panel *panel)
49{
50 return container_of(panel, struct sharp_nt_panel, base);
51}
52
53static int sharp_nt_panel_init(struct sharp_nt_panel *sharp_nt)
54{
55 struct mipi_dsi_device *dsi = sharp_nt->dsi;
56 int ret;
57
58 dsi->mode_flags |= MIPI_DSI_MODE_LPM;
59
60 ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
61 if (ret < 0)
62 return ret;
63
64 msleep(120);
65
66 /* Novatek two-lane operation */
67 ret = mipi_dsi_dcs_write(dsi, 0xae, (u8[]){ 0x03 }, 1);
68 if (ret < 0)
69 return ret;
70
71 /* Set both MCU and RGB I/F to 24bpp */
72 ret = mipi_dsi_dcs_set_pixel_format(dsi, MIPI_DCS_PIXEL_FMT_24BIT |
73 (MIPI_DCS_PIXEL_FMT_24BIT << 4));
74 if (ret < 0)
75 return ret;
76
77 return 0;
78}
79
80static int sharp_nt_panel_on(struct sharp_nt_panel *sharp_nt)
81{
82 struct mipi_dsi_device *dsi = sharp_nt->dsi;
83 int ret;
84
85 dsi->mode_flags |= MIPI_DSI_MODE_LPM;
86
87 ret = mipi_dsi_dcs_set_display_on(dsi);
88 if (ret < 0)
89 return ret;
90
91 return 0;
92}
93
94static int sharp_nt_panel_off(struct sharp_nt_panel *sharp_nt)
95{
96 struct mipi_dsi_device *dsi = sharp_nt->dsi;
97 int ret;
98
99 dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
100
101 ret = mipi_dsi_dcs_set_display_off(dsi);
102 if (ret < 0)
103 return ret;
104
105 ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
106 if (ret < 0)
107 return ret;
108
109 return 0;
110}
111
112
113static int sharp_nt_panel_disable(struct drm_panel *panel)
114{
115 struct sharp_nt_panel *sharp_nt = to_sharp_nt_panel(panel);
116
117 if (!sharp_nt->enabled)
118 return 0;
119
120 if (sharp_nt->backlight) {
121 sharp_nt->backlight->props.power = FB_BLANK_POWERDOWN;
122 backlight_update_status(sharp_nt->backlight);
123 }
124
125 sharp_nt->enabled = false;
126
127 return 0;
128}
129
130static int sharp_nt_panel_unprepare(struct drm_panel *panel)
131{
132 struct sharp_nt_panel *sharp_nt = to_sharp_nt_panel(panel);
133 int ret;
134
135 if (!sharp_nt->prepared)
136 return 0;
137
138 ret = sharp_nt_panel_off(sharp_nt);
139 if (ret < 0) {
140 dev_err(panel->dev, "failed to set panel off: %d\n", ret);
141 return ret;
142 }
143
144 regulator_disable(sharp_nt->supply);
145 if (sharp_nt->reset_gpio)
146 gpiod_set_value(sharp_nt->reset_gpio, 0);
147
148 sharp_nt->prepared = false;
149
150 return 0;
151}
152
153static int sharp_nt_panel_prepare(struct drm_panel *panel)
154{
155 struct sharp_nt_panel *sharp_nt = to_sharp_nt_panel(panel);
156 int ret;
157
158 if (sharp_nt->prepared)
159 return 0;
160
161 ret = regulator_enable(sharp_nt->supply);
162 if (ret < 0)
163 return ret;
164
165 msleep(20);
166
167 if (sharp_nt->reset_gpio) {
168 gpiod_set_value(sharp_nt->reset_gpio, 1);
169 msleep(1);
170 gpiod_set_value(sharp_nt->reset_gpio, 0);
171 msleep(1);
172 gpiod_set_value(sharp_nt->reset_gpio, 1);
173 msleep(10);
174 }
175
176 ret = sharp_nt_panel_init(sharp_nt);
177 if (ret < 0) {
178 dev_err(panel->dev, "failed to init panel: %d\n", ret);
179 goto poweroff;
180 }
181
182 ret = sharp_nt_panel_on(sharp_nt);
183 if (ret < 0) {
184 dev_err(panel->dev, "failed to set panel on: %d\n", ret);
185 goto poweroff;
186 }
187
188 sharp_nt->prepared = true;
189
190 return 0;
191
192poweroff:
193 regulator_disable(sharp_nt->supply);
194 if (sharp_nt->reset_gpio)
195 gpiod_set_value(sharp_nt->reset_gpio, 0);
196 return ret;
197}
198
199static int sharp_nt_panel_enable(struct drm_panel *panel)
200{
201 struct sharp_nt_panel *sharp_nt = to_sharp_nt_panel(panel);
202
203 if (sharp_nt->enabled)
204 return 0;
205
206 if (sharp_nt->backlight) {
207 sharp_nt->backlight->props.power = FB_BLANK_UNBLANK;
208 backlight_update_status(sharp_nt->backlight);
209 }
210
211 sharp_nt->enabled = true;
212
213 return 0;
214}
215
216static const struct drm_display_mode default_mode = {
217 .clock = 41118,
218 .hdisplay = 540,
219 .hsync_start = 540 + 48,
220 .hsync_end = 540 + 48 + 80,
221 .htotal = 540 + 48 + 80 + 32,
222 .vdisplay = 960,
223 .vsync_start = 960 + 3,
224 .vsync_end = 960 + 3 + 15,
225 .vtotal = 960 + 3 + 15 + 1,
226 .vrefresh = 60,
227};
228
229static int sharp_nt_panel_get_modes(struct drm_panel *panel)
230{
231 struct drm_display_mode *mode;
232
233 mode = drm_mode_duplicate(panel->drm, &default_mode);
234 if (!mode) {
235 dev_err(panel->drm->dev, "failed to add mode %ux%ux@%u\n",
236 default_mode.hdisplay, default_mode.vdisplay,
237 default_mode.vrefresh);
238 return -ENOMEM;
239 }
240
241 drm_mode_set_name(mode);
242
243 drm_mode_probed_add(panel->connector, mode);
244
245 panel->connector->display_info.width_mm = 54;
246 panel->connector->display_info.height_mm = 95;
247
248 return 1;
249}
250
251static const struct drm_panel_funcs sharp_nt_panel_funcs = {
252 .disable = sharp_nt_panel_disable,
253 .unprepare = sharp_nt_panel_unprepare,
254 .prepare = sharp_nt_panel_prepare,
255 .enable = sharp_nt_panel_enable,
256 .get_modes = sharp_nt_panel_get_modes,
257};
258
259static int sharp_nt_panel_add(struct sharp_nt_panel *sharp_nt)
260{
261 struct device *dev = &sharp_nt->dsi->dev;
262 struct device_node *np;
263 int ret;
264
265 sharp_nt->mode = &default_mode;
266
267 sharp_nt->supply = devm_regulator_get(dev, "avdd");
268 if (IS_ERR(sharp_nt->supply))
269 return PTR_ERR(sharp_nt->supply);
270
271 sharp_nt->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
272 if (IS_ERR(sharp_nt->reset_gpio)) {
273 dev_err(dev, "cannot get reset-gpios %ld\n",
274 PTR_ERR(sharp_nt->reset_gpio));
275 sharp_nt->reset_gpio = NULL;
276 } else {
277 gpiod_set_value(sharp_nt->reset_gpio, 0);
278 }
279
280 np = of_parse_phandle(dev->of_node, "backlight", 0);
281 if (np) {
282 sharp_nt->backlight = of_find_backlight_by_node(np);
283 of_node_put(np);
284
285 if (!sharp_nt->backlight)
286 return -EPROBE_DEFER;
287 }
288
289 drm_panel_init(&sharp_nt->base);
290 sharp_nt->base.funcs = &sharp_nt_panel_funcs;
291 sharp_nt->base.dev = &sharp_nt->dsi->dev;
292
293 ret = drm_panel_add(&sharp_nt->base);
294 if (ret < 0)
295 goto put_backlight;
296
297 return 0;
298
299put_backlight:
300 if (sharp_nt->backlight)
301 put_device(&sharp_nt->backlight->dev);
302
303 return ret;
304}
305
306static void sharp_nt_panel_del(struct sharp_nt_panel *sharp_nt)
307{
308 if (sharp_nt->base.dev)
309 drm_panel_remove(&sharp_nt->base);
310
311 if (sharp_nt->backlight)
312 put_device(&sharp_nt->backlight->dev);
313}
314
315static int sharp_nt_panel_probe(struct mipi_dsi_device *dsi)
316{
317 struct sharp_nt_panel *sharp_nt;
318 int ret;
319
320 dsi->lanes = 2;
321 dsi->format = MIPI_DSI_FMT_RGB888;
322 dsi->mode_flags = MIPI_DSI_MODE_VIDEO |
323 MIPI_DSI_MODE_VIDEO_HSE |
324 MIPI_DSI_CLOCK_NON_CONTINUOUS |
325 MIPI_DSI_MODE_EOT_PACKET;
326
327 sharp_nt = devm_kzalloc(&dsi->dev, sizeof(*sharp_nt), GFP_KERNEL);
328 if (!sharp_nt)
329 return -ENOMEM;
330
331 mipi_dsi_set_drvdata(dsi, sharp_nt);
332
333 sharp_nt->dsi = dsi;
334
335 ret = sharp_nt_panel_add(sharp_nt);
336 if (ret < 0)
337 return ret;
338
339 return mipi_dsi_attach(dsi);
340}
341
342static int sharp_nt_panel_remove(struct mipi_dsi_device *dsi)
343{
344 struct sharp_nt_panel *sharp_nt = mipi_dsi_get_drvdata(dsi);
345 int ret;
346
347 ret = sharp_nt_panel_disable(&sharp_nt->base);
348 if (ret < 0)
349 dev_err(&dsi->dev, "failed to disable panel: %d\n", ret);
350
351 ret = mipi_dsi_detach(dsi);
352 if (ret < 0)
353 dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", ret);
354
355 drm_panel_detach(&sharp_nt->base);
356 sharp_nt_panel_del(sharp_nt);
357
358 return 0;
359}
360
361static void sharp_nt_panel_shutdown(struct mipi_dsi_device *dsi)
362{
363 struct sharp_nt_panel *sharp_nt = mipi_dsi_get_drvdata(dsi);
364
365 sharp_nt_panel_disable(&sharp_nt->base);
366}
367
368static const struct of_device_id sharp_nt_of_match[] = {
369 { .compatible = "sharp,ls043t1le01-qhd", },
370 { }
371};
372MODULE_DEVICE_TABLE(of, sharp_nt_of_match);
373
374static struct mipi_dsi_driver sharp_nt_panel_driver = {
375 .driver = {
376 .name = "panel-sharp-ls043t1le01-qhd",
377 .of_match_table = sharp_nt_of_match,
378 },
379 .probe = sharp_nt_panel_probe,
380 .remove = sharp_nt_panel_remove,
381 .shutdown = sharp_nt_panel_shutdown,
382};
383module_mipi_dsi_driver(sharp_nt_panel_driver);
384
385MODULE_AUTHOR("Werner Johansson <werner.johansson@sonymobile.com>");
386MODULE_DESCRIPTION("Sharp LS043T1LE01 NT35565-based qHD (540x960) video mode panel driver");
387MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index f97b73ec4713..f88a631c43ab 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -44,6 +44,10 @@ struct panel_desc {
44 44
45 unsigned int bpc; 45 unsigned int bpc;
46 46
47 /**
48 * @width: width (in millimeters) of the panel's active display area
49 * @height: height (in millimeters) of the panel's active display area
50 */
47 struct { 51 struct {
48 unsigned int width; 52 unsigned int width;
49 unsigned int height; 53 unsigned int height;
@@ -832,6 +836,34 @@ static const struct panel_desc innolux_g121i1_l01 = {
832 }, 836 },
833}; 837};
834 838
839static const struct drm_display_mode innolux_g121x1_l03_mode = {
840 .clock = 65000,
841 .hdisplay = 1024,
842 .hsync_start = 1024 + 0,
843 .hsync_end = 1024 + 1,
844 .htotal = 1024 + 0 + 1 + 320,
845 .vdisplay = 768,
846 .vsync_start = 768 + 38,
847 .vsync_end = 768 + 38 + 1,
848 .vtotal = 768 + 38 + 1 + 0,
849 .vrefresh = 60,
850};
851
852static const struct panel_desc innolux_g121x1_l03 = {
853 .modes = &innolux_g121x1_l03_mode,
854 .num_modes = 1,
855 .bpc = 6,
856 .size = {
857 .width = 246,
858 .height = 185,
859 },
860 .delay = {
861 .enable = 200,
862 .unprepare = 200,
863 .disable = 400,
864 },
865};
866
835static const struct drm_display_mode innolux_n116bge_mode = { 867static const struct drm_display_mode innolux_n116bge_mode = {
836 .clock = 76420, 868 .clock = 76420,
837 .hdisplay = 1366, 869 .hdisplay = 1366,
@@ -902,6 +934,30 @@ static const struct panel_desc innolux_zj070na_01p = {
902 }, 934 },
903}; 935};
904 936
937static const struct display_timing kyo_tcg121xglp_timing = {
938 .pixelclock = { 52000000, 65000000, 71000000 },
939 .hactive = { 1024, 1024, 1024 },
940 .hfront_porch = { 2, 2, 2 },
941 .hback_porch = { 2, 2, 2 },
942 .hsync_len = { 86, 124, 244 },
943 .vactive = { 768, 768, 768 },
944 .vfront_porch = { 2, 2, 2 },
945 .vback_porch = { 2, 2, 2 },
946 .vsync_len = { 6, 34, 73 },
947 .flags = DISPLAY_FLAGS_DE_HIGH,
948};
949
950static const struct panel_desc kyo_tcg121xglp = {
951 .timings = &kyo_tcg121xglp_timing,
952 .num_timings = 1,
953 .bpc = 8,
954 .size = {
955 .width = 246,
956 .height = 184,
957 },
958 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
959};
960
905static const struct drm_display_mode lg_lb070wv8_mode = { 961static const struct drm_display_mode lg_lb070wv8_mode = {
906 .clock = 33246, 962 .clock = 33246,
907 .hdisplay = 800, 963 .hdisplay = 800,
@@ -1027,6 +1083,30 @@ static const struct panel_desc ortustech_com43h4m85ulc = {
1027 .bus_format = MEDIA_BUS_FMT_RGB888_1X24, 1083 .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
1028}; 1084};
1029 1085
1086static const struct drm_display_mode qd43003c0_40_mode = {
1087 .clock = 9000,
1088 .hdisplay = 480,
1089 .hsync_start = 480 + 8,
1090 .hsync_end = 480 + 8 + 4,
1091 .htotal = 480 + 8 + 4 + 39,
1092 .vdisplay = 272,
1093 .vsync_start = 272 + 4,
1094 .vsync_end = 272 + 4 + 10,
1095 .vtotal = 272 + 4 + 10 + 2,
1096 .vrefresh = 60,
1097};
1098
1099static const struct panel_desc qd43003c0_40 = {
1100 .modes = &qd43003c0_40_mode,
1101 .num_modes = 1,
1102 .bpc = 8,
1103 .size = {
1104 .width = 95,
1105 .height = 53,
1106 },
1107 .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
1108};
1109
1030static const struct drm_display_mode samsung_ltn101nt05_mode = { 1110static const struct drm_display_mode samsung_ltn101nt05_mode = {
1031 .clock = 54030, 1111 .clock = 54030,
1032 .hdisplay = 1024, 1112 .hdisplay = 1024,
@@ -1158,6 +1238,9 @@ static const struct of_device_id platform_of_match[] = {
1158 .compatible ="innolux,g121i1-l01", 1238 .compatible ="innolux,g121i1-l01",
1159 .data = &innolux_g121i1_l01 1239 .data = &innolux_g121i1_l01
1160 }, { 1240 }, {
1241 .compatible = "innolux,g121x1-l03",
1242 .data = &innolux_g121x1_l03,
1243 }, {
1161 .compatible = "innolux,n116bge", 1244 .compatible = "innolux,n116bge",
1162 .data = &innolux_n116bge, 1245 .data = &innolux_n116bge,
1163 }, { 1246 }, {
@@ -1167,6 +1250,9 @@ static const struct of_device_id platform_of_match[] = {
1167 .compatible = "innolux,zj070na-01p", 1250 .compatible = "innolux,zj070na-01p",
1168 .data = &innolux_zj070na_01p, 1251 .data = &innolux_zj070na_01p,
1169 }, { 1252 }, {
1253 .compatible = "kyo,tcg121xglp",
1254 .data = &kyo_tcg121xglp,
1255 }, {
1170 .compatible = "lg,lb070wv8", 1256 .compatible = "lg,lb070wv8",
1171 .data = &lg_lb070wv8, 1257 .data = &lg_lb070wv8,
1172 }, { 1258 }, {
@@ -1182,6 +1268,9 @@ static const struct of_device_id platform_of_match[] = {
1182 .compatible = "ortustech,com43h4m85ulc", 1268 .compatible = "ortustech,com43h4m85ulc",
1183 .data = &ortustech_com43h4m85ulc, 1269 .data = &ortustech_com43h4m85ulc,
1184 }, { 1270 }, {
1271 .compatible = "qiaodian,qd43003c0-40",
1272 .data = &qd43003c0_40,
1273 }, {
1185 .compatible = "samsung,ltn101nt05", 1274 .compatible = "samsung,ltn101nt05",
1186 .data = &samsung_ltn101nt05, 1275 .data = &samsung_ltn101nt05,
1187 }, { 1276 }, {
@@ -1263,6 +1352,36 @@ static const struct panel_desc_dsi auo_b080uan01 = {
1263 .lanes = 4, 1352 .lanes = 4,
1264}; 1353};
1265 1354
1355static const struct drm_display_mode boe_tv080wum_nl0_mode = {
1356 .clock = 160000,
1357 .hdisplay = 1200,
1358 .hsync_start = 1200 + 120,
1359 .hsync_end = 1200 + 120 + 20,
1360 .htotal = 1200 + 120 + 20 + 21,
1361 .vdisplay = 1920,
1362 .vsync_start = 1920 + 21,
1363 .vsync_end = 1920 + 21 + 3,
1364 .vtotal = 1920 + 21 + 3 + 18,
1365 .vrefresh = 60,
1366 .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
1367};
1368
1369static const struct panel_desc_dsi boe_tv080wum_nl0 = {
1370 .desc = {
1371 .modes = &boe_tv080wum_nl0_mode,
1372 .num_modes = 1,
1373 .size = {
1374 .width = 107,
1375 .height = 172,
1376 },
1377 },
1378 .flags = MIPI_DSI_MODE_VIDEO |
1379 MIPI_DSI_MODE_VIDEO_BURST |
1380 MIPI_DSI_MODE_VIDEO_SYNC_PULSE,
1381 .format = MIPI_DSI_FMT_RGB888,
1382 .lanes = 4,
1383};
1384
1266static const struct drm_display_mode lg_ld070wx3_sl01_mode = { 1385static const struct drm_display_mode lg_ld070wx3_sl01_mode = {
1267 .clock = 71000, 1386 .clock = 71000,
1268 .hdisplay = 800, 1387 .hdisplay = 800,
@@ -1348,11 +1467,15 @@ static const struct panel_desc_dsi panasonic_vvx10f004b00 = {
1348 .lanes = 4, 1467 .lanes = 4,
1349}; 1468};
1350 1469
1470
1351static const struct of_device_id dsi_of_match[] = { 1471static const struct of_device_id dsi_of_match[] = {
1352 { 1472 {
1353 .compatible = "auo,b080uan01", 1473 .compatible = "auo,b080uan01",
1354 .data = &auo_b080uan01 1474 .data = &auo_b080uan01
1355 }, { 1475 }, {
1476 .compatible = "boe,tv080wum-nl0",
1477 .data = &boe_tv080wum_nl0
1478 }, {
1356 .compatible = "lg,ld070wx3-sl01", 1479 .compatible = "lg,ld070wx3-sl01",
1357 .data = &lg_ld070wx3_sl01 1480 .data = &lg_ld070wx3_sl01
1358 }, { 1481 }, {
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index f1d8d0dbb4f1..1b3b1f8c8cdf 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -163,9 +163,36 @@ static inline struct mipi_dsi_device *to_mipi_dsi_device(struct device *dev)
163 return container_of(dev, struct mipi_dsi_device, dev); 163 return container_of(dev, struct mipi_dsi_device, dev);
164} 164}
165 165
166/**
167 * mipi_dsi_pixel_format_to_bpp - obtain the number of bits per pixel for any
168 * given pixel format defined by the MIPI DSI
169 * specification
170 * @fmt: MIPI DSI pixel format
171 *
172 * Returns: The number of bits per pixel of the given pixel format.
173 */
174static inline int mipi_dsi_pixel_format_to_bpp(enum mipi_dsi_pixel_format fmt)
175{
176 switch (fmt) {
177 case MIPI_DSI_FMT_RGB888:
178 case MIPI_DSI_FMT_RGB666:
179 return 24;
180
181 case MIPI_DSI_FMT_RGB666_PACKED:
182 return 18;
183
184 case MIPI_DSI_FMT_RGB565:
185 return 16;
186 }
187
188 return -EINVAL;
189}
190
166struct mipi_dsi_device *of_find_mipi_dsi_device_by_node(struct device_node *np); 191struct mipi_dsi_device *of_find_mipi_dsi_device_by_node(struct device_node *np);
167int mipi_dsi_attach(struct mipi_dsi_device *dsi); 192int mipi_dsi_attach(struct mipi_dsi_device *dsi);
168int mipi_dsi_detach(struct mipi_dsi_device *dsi); 193int mipi_dsi_detach(struct mipi_dsi_device *dsi);
194int mipi_dsi_shutdown_peripheral(struct mipi_dsi_device *dsi);
195int mipi_dsi_turn_on_peripheral(struct mipi_dsi_device *dsi);
169int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi, 196int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi,
170 u16 value); 197 u16 value);
171 198