summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 @@
+Boe Corporation 8.0" WUXGA TFT LCD panel
+
+Required properties:
+- compatible: should be "boe,tv080wum-nl0"
+
+This binding is compatible with the simple-panel binding, which is specified
+in 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 @@
+Innolux Corporation 12.1" G121X1-L03 XGA (1024x768) TFT LCD panel
+
+Required properties:
+- compatible: should be "innolux,g121x1-l03"
+
+This binding is compatible with the simple-panel binding, which is specified
+in 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 @@
+Kyocera Corporation 12.1" XGA (1024x768) TFT LCD panel
+
+Required properties:
+- compatible: should be "kyo,tcg121xglp"
+
+This binding is compatible with the simple-panel binding, which is specified
+in 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 @@
+Sharp Microelectronics 4.3" qHD TFT LCD panel
+
+Required properties:
+- compatible: should be "sharp,ls043t1le01-qhd"
+- reg: DSI virtual channel of the peripheral
+- power-supply: phandle of the regulator that provides the supply voltage
+
+Optional properties:
+- backlight: phandle of the backlight device attached to the panel
+- reset-gpios: a GPIO spec for the reset pin
+
+Example:
+
+ mdss_dsi@fd922800 {
+ panel@0 {
+ compatible = "sharp,ls043t1le01-qhd";
+ reg = <0>;
+ avdd-supply = <&pm8941_l22>;
+ backlight = <&pm8941_wled>;
+ reset-gpios = <&pm8941_gpios 19 GPIO_ACTIVE_HIGH>;
+ };
+ };
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 @@
+Panasonic 10" WUXGA TFT LCD panel
+
+Required properties:
+- compatible: should be "panasonic,vvx10f034n00"
+- reg: DSI virtual channel of the peripheral
+- power-supply: phandle of the regulator that provides the supply voltage
+
+Optional properties:
+- backlight: phandle of the backlight device attached to the panel
+
+Example:
+
+ mdss_dsi@fd922800 {
+ panel@0 {
+ compatible = "panasonic,vvx10f034n00";
+ reg = <0>;
+ power-supply = <&vreg_vsp>;
+ backlight = <&lp8566_wled>;
+ };
+ };
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 @@
+QiaoDian XianShi Corporation 4"3 TFT LCD panel
+
+Required properties:
+- compatible: should be "qiaodian,qd43003c0-40"
+
+This binding is compatible with the simple-panel binding, which is specified
+in 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
avago Avago Technologies
avic Shanghai AVIC Optoelectronics Co., Ltd.
axis Axis Communications AB
+boe BOE Technology Group Co., Ltd.
bosch Bosch Sensortec GmbH
boundary Boundary Devices Inc.
brcm Broadcom Corporation
@@ -123,6 +124,7 @@ jedec JEDEC Solid State Technology Association
karo Ka-Ro electronics GmbH
keymile Keymile GmbH
kinetic Kinetic Technologies
+kyo Kyocera Corporation
lacie LaCie
lantiq Lantiq Semiconductor
lenovo Lenovo Group Ltd.
@@ -180,6 +182,7 @@ qca Qualcomm Atheros, Inc.
qcom Qualcomm Technologies, Inc
qemu QEMU, a generic and open source machine emulator and virtualizer
qi Qi Hardware
+qiaodian QiaoDian XianShi Corporation
qnap QNAP Systems, Inc.
radxa Radxa
raidsonic 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
Designware HDMI block. This is used in conjunction with
the i.MX6 HDMI driver.
-
config DRM_NXP_PTN3460
tristate "NXP PTN3460 DP/LVDS bridge"
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 @@
ccflags-y := -Iinclude/drm
-obj-$(CONFIG_DRM_DW_HDMI) += dw_hdmi.o
-obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw_hdmi-ahb-audio.o
+obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
+obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o
obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o
obj-$(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 @@
#include <sound/pcm_drm_eld.h>
#include <sound/pcm_iec958.h>
-#include "dw_hdmi-audio.h"
+#include "dw-hdmi-audio.h"
#define DRIVER_NAME "dw-hdmi-ahb-audio"
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 @@
#include <drm/drm_encoder_slave.h>
#include <drm/bridge/dw_hdmi.h>
-#include "dw_hdmi.h"
-#include "dw_hdmi-audio.h"
+#include "dw-hdmi.h"
+#include "dw-hdmi-audio.h"
#define HDMI_EDID_LEN 512
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,
}
EXPORT_SYMBOL(mipi_dsi_create_packet);
+/**
+ * mipi_dsi_shutdown_peripheral() - sends a Shutdown Peripheral command
+ * @dsi: DSI peripheral device
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int mipi_dsi_shutdown_peripheral(struct mipi_dsi_device *dsi)
+{
+ struct mipi_dsi_msg msg = {
+ .channel = dsi->channel,
+ .type = MIPI_DSI_SHUTDOWN_PERIPHERAL,
+ .tx_buf = (u8 [2]) { 0, 0 },
+ .tx_len = 2,
+ };
+
+ return mipi_dsi_device_transfer(dsi, &msg);
+}
+EXPORT_SYMBOL(mipi_dsi_shutdown_peripheral);
+
+/**
+ * mipi_dsi_turn_on_peripheral() - sends a Turn On Peripheral command
+ * @dsi: DSI peripheral device
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int mipi_dsi_turn_on_peripheral(struct mipi_dsi_device *dsi)
+{
+ struct mipi_dsi_msg msg = {
+ .channel = dsi->channel,
+ .type = MIPI_DSI_TURN_ON_PERIPHERAL,
+ .tx_buf = (u8 [2]) { 0, 0 },
+ .tx_len = 2,
+ };
+
+ return mipi_dsi_device_transfer(dsi, &msg);
+}
+EXPORT_SYMBOL(mipi_dsi_turn_on_peripheral);
+
/*
* mipi_dsi_set_maximum_return_packet_size() - specify the maximum size of the
* 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
Say Y here if you want to enable support for LG4573 RGB panel.
To compile this driver as a module, choose M here.
+config DRM_PANEL_PANASONIC_VVX10F034N00
+ tristate "Panasonic VVX10F034N00 1920x1200 video mode panel"
+ depends on OF
+ depends on DRM_MIPI_DSI
+ depends on BACKLIGHT_CLASS_DEVICE
+ help
+ Say Y here if you want to enable support for Panasonic VVX10F034N00
+ WUXGA (1920x1200) Novatek NT1397-based DSI panel as found in some
+ Xperia Z2 tablets
+
config DRM_PANEL_SAMSUNG_S6E8AA0
tristate "Samsung S6E8AA0 DSI video mode panel"
depends on OF
@@ -51,4 +61,13 @@ config DRM_PANEL_SHARP_LQ101R1SX01
To compile this driver as a module, choose M here: the module
will be called panel-sharp-lq101r1sx01.
+config DRM_PANEL_SHARP_LS043T1LE01
+ tristate "Sharp LS043T1LE01 qHD video mode panel"
+ depends on OF
+ depends on DRM_MIPI_DSI
+ depends on BACKLIGHT_CLASS_DEVICE
+ help
+ Say Y here if you want to enable support for Sharp LS043T1LE01 qHD
+ (540x960) DSI panel as found on the Qualcomm APQ8074 Dragonboard
+
endmenu
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 @@
obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o
obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o
+obj-$(CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00) += panel-panasonic-vvx10f034n00.o
obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o
obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0) += panel-samsung-s6e8aa0.o
obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o
+obj-$(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 @@
+/*
+ * Copyright (C) 2015 Red Hat
+ * Copyright (C) 2015 Sony Mobile Communications Inc.
+ * Author: Werner Johansson <werner.johansson@sonymobile.com>
+ *
+ * Based on AUO panel driver by Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/backlight.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/regulator/consumer.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_panel.h>
+
+#include <video/mipi_display.h>
+
+/*
+ * When power is turned off to this panel a minimum off time of 500ms has to be
+ * observed before powering back on as there's no external reset pin. Keep
+ * track of earliest wakeup time and delay subsequent prepare call accordingly
+ */
+#define MIN_POFF_MS (500)
+
+struct wuxga_nt_panel {
+ struct drm_panel base;
+ struct mipi_dsi_device *dsi;
+
+ struct backlight_device *backlight;
+ struct regulator *supply;
+
+ bool prepared;
+ bool enabled;
+
+ ktime_t earliest_wake;
+
+ const struct drm_display_mode *mode;
+};
+
+static inline struct wuxga_nt_panel *to_wuxga_nt_panel(struct drm_panel *panel)
+{
+ return container_of(panel, struct wuxga_nt_panel, base);
+}
+
+static int wuxga_nt_panel_on(struct wuxga_nt_panel *wuxga_nt)
+{
+ struct mipi_dsi_device *dsi = wuxga_nt->dsi;
+ int ret;
+
+ ret = mipi_dsi_turn_on_peripheral(dsi);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int wuxga_nt_panel_disable(struct drm_panel *panel)
+{
+ struct wuxga_nt_panel *wuxga_nt = to_wuxga_nt_panel(panel);
+
+ if (!wuxga_nt->enabled)
+ return 0;
+
+ mipi_dsi_shutdown_peripheral(wuxga_nt->dsi);
+
+ if (wuxga_nt->backlight) {
+ wuxga_nt->backlight->props.power = FB_BLANK_POWERDOWN;
+ wuxga_nt->backlight->props.state |= BL_CORE_FBBLANK;
+ backlight_update_status(wuxga_nt->backlight);
+ }
+
+ wuxga_nt->enabled = false;
+
+ return 0;
+}
+
+static int wuxga_nt_panel_unprepare(struct drm_panel *panel)
+{
+ struct wuxga_nt_panel *wuxga_nt = to_wuxga_nt_panel(panel);
+
+ if (!wuxga_nt->prepared)
+ return 0;
+
+ regulator_disable(wuxga_nt->supply);
+ wuxga_nt->earliest_wake = ktime_add_ms(ktime_get_real(), MIN_POFF_MS);
+ wuxga_nt->prepared = false;
+
+ return 0;
+}
+
+static int wuxga_nt_panel_prepare(struct drm_panel *panel)
+{
+ struct wuxga_nt_panel *wuxga_nt = to_wuxga_nt_panel(panel);
+ int ret;
+ s64 enablewait;
+
+ if (wuxga_nt->prepared)
+ return 0;
+
+ /*
+ * If the user re-enabled the panel before the required off-time then
+ * we need to wait the remaining period before re-enabling regulator
+ */
+ enablewait = ktime_ms_delta(wuxga_nt->earliest_wake, ktime_get_real());
+
+ /* Sanity check, this should never happen */
+ if (enablewait > MIN_POFF_MS)
+ enablewait = MIN_POFF_MS;
+
+ if (enablewait > 0)
+ msleep(enablewait);
+
+ ret = regulator_enable(wuxga_nt->supply);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * A minimum delay of 250ms is required after power-up until commands
+ * can be sent
+ */
+ msleep(250);
+
+ ret = wuxga_nt_panel_on(wuxga_nt);
+ if (ret < 0) {
+ dev_err(panel->dev, "failed to set panel on: %d\n", ret);
+ goto poweroff;
+ }
+
+ wuxga_nt->prepared = true;
+
+ return 0;
+
+poweroff:
+ regulator_disable(wuxga_nt->supply);
+
+ return ret;
+}
+
+static int wuxga_nt_panel_enable(struct drm_panel *panel)
+{
+ struct wuxga_nt_panel *wuxga_nt = to_wuxga_nt_panel(panel);
+
+ if (wuxga_nt->enabled)
+ return 0;
+
+ if (wuxga_nt->backlight) {
+ wuxga_nt->backlight->props.power = FB_BLANK_UNBLANK;
+ wuxga_nt->backlight->props.state &= ~BL_CORE_FBBLANK;
+ backlight_update_status(wuxga_nt->backlight);
+ }
+
+ wuxga_nt->enabled = true;
+
+ return 0;
+}
+
+static const struct drm_display_mode default_mode = {
+ .clock = 164402,
+ .hdisplay = 1920,
+ .hsync_start = 1920 + 152,
+ .hsync_end = 1920 + 152 + 52,
+ .htotal = 1920 + 152 + 52 + 20,
+ .vdisplay = 1200,
+ .vsync_start = 1200 + 24,
+ .vsync_end = 1200 + 24 + 6,
+ .vtotal = 1200 + 24 + 6 + 48,
+ .vrefresh = 60,
+};
+
+static int wuxga_nt_panel_get_modes(struct drm_panel *panel)
+{
+ struct drm_display_mode *mode;
+
+ mode = drm_mode_duplicate(panel->drm, &default_mode);
+ if (!mode) {
+ dev_err(panel->drm->dev, "failed to add mode %ux%ux@%u\n",
+ default_mode.hdisplay, default_mode.vdisplay,
+ default_mode.vrefresh);
+ return -ENOMEM;
+ }
+
+ drm_mode_set_name(mode);
+
+ drm_mode_probed_add(panel->connector, mode);
+
+ panel->connector->display_info.width_mm = 217;
+ panel->connector->display_info.height_mm = 136;
+
+ return 1;
+}
+
+static const struct drm_panel_funcs wuxga_nt_panel_funcs = {
+ .disable = wuxga_nt_panel_disable,
+ .unprepare = wuxga_nt_panel_unprepare,
+ .prepare = wuxga_nt_panel_prepare,
+ .enable = wuxga_nt_panel_enable,
+ .get_modes = wuxga_nt_panel_get_modes,
+};
+
+static const struct of_device_id wuxga_nt_of_match[] = {
+ { .compatible = "panasonic,vvx10f034n00", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, wuxga_nt_of_match);
+
+static int wuxga_nt_panel_add(struct wuxga_nt_panel *wuxga_nt)
+{
+ struct device *dev = &wuxga_nt->dsi->dev;
+ struct device_node *np;
+ int ret;
+
+ wuxga_nt->mode = &default_mode;
+
+ wuxga_nt->supply = devm_regulator_get(dev, "power");
+ if (IS_ERR(wuxga_nt->supply))
+ return PTR_ERR(wuxga_nt->supply);
+
+ np = of_parse_phandle(dev->of_node, "backlight", 0);
+ if (np) {
+ wuxga_nt->backlight = of_find_backlight_by_node(np);
+ of_node_put(np);
+
+ if (!wuxga_nt->backlight)
+ return -EPROBE_DEFER;
+ }
+
+ drm_panel_init(&wuxga_nt->base);
+ wuxga_nt->base.funcs = &wuxga_nt_panel_funcs;
+ wuxga_nt->base.dev = &wuxga_nt->dsi->dev;
+
+ ret = drm_panel_add(&wuxga_nt->base);
+ if (ret < 0)
+ goto put_backlight;
+
+ return 0;
+
+put_backlight:
+ if (wuxga_nt->backlight)
+ put_device(&wuxga_nt->backlight->dev);
+
+ return ret;
+}
+
+static void wuxga_nt_panel_del(struct wuxga_nt_panel *wuxga_nt)
+{
+ if (wuxga_nt->base.dev)
+ drm_panel_remove(&wuxga_nt->base);
+
+ if (wuxga_nt->backlight)
+ put_device(&wuxga_nt->backlight->dev);
+}
+
+static int wuxga_nt_panel_probe(struct mipi_dsi_device *dsi)
+{
+ struct wuxga_nt_panel *wuxga_nt;
+ int ret;
+
+ dsi->lanes = 4;
+ dsi->format = MIPI_DSI_FMT_RGB888;
+ dsi->mode_flags = MIPI_DSI_MODE_VIDEO |
+ MIPI_DSI_MODE_VIDEO_HSE |
+ MIPI_DSI_CLOCK_NON_CONTINUOUS |
+ MIPI_DSI_MODE_LPM;
+
+ wuxga_nt = devm_kzalloc(&dsi->dev, sizeof(*wuxga_nt), GFP_KERNEL);
+ if (!wuxga_nt)
+ return -ENOMEM;
+
+ mipi_dsi_set_drvdata(dsi, wuxga_nt);
+
+ wuxga_nt->dsi = dsi;
+
+ ret = wuxga_nt_panel_add(wuxga_nt);
+ if (ret < 0)
+ return ret;
+
+ return mipi_dsi_attach(dsi);
+}
+
+static int wuxga_nt_panel_remove(struct mipi_dsi_device *dsi)
+{
+ struct wuxga_nt_panel *wuxga_nt = mipi_dsi_get_drvdata(dsi);
+ int ret;
+
+ ret = wuxga_nt_panel_disable(&wuxga_nt->base);
+ if (ret < 0)
+ dev_err(&dsi->dev, "failed to disable panel: %d\n", ret);
+
+ ret = mipi_dsi_detach(dsi);
+ if (ret < 0)
+ dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", ret);
+
+ drm_panel_detach(&wuxga_nt->base);
+ wuxga_nt_panel_del(wuxga_nt);
+
+ return 0;
+}
+
+static void wuxga_nt_panel_shutdown(struct mipi_dsi_device *dsi)
+{
+ struct wuxga_nt_panel *wuxga_nt = mipi_dsi_get_drvdata(dsi);
+
+ wuxga_nt_panel_disable(&wuxga_nt->base);
+}
+
+static struct mipi_dsi_driver wuxga_nt_panel_driver = {
+ .driver = {
+ .name = "panel-panasonic-vvx10f034n00",
+ .of_match_table = wuxga_nt_of_match,
+ },
+ .probe = wuxga_nt_panel_probe,
+ .remove = wuxga_nt_panel_remove,
+ .shutdown = wuxga_nt_panel_shutdown,
+};
+module_mipi_dsi_driver(wuxga_nt_panel_driver);
+
+MODULE_AUTHOR("Werner Johansson <werner.johansson@sonymobile.com>");
+MODULE_DESCRIPTION("Panasonic VVX10F034N00 Novatek NT1397-based WUXGA (1920x1200) video mode panel driver");
+MODULE_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 @@
+/*
+ * Copyright (C) 2015 Red Hat
+ * Copyright (C) 2015 Sony Mobile Communications Inc.
+ * Author: Werner Johansson <werner.johansson@sonymobile.com>
+ *
+ * Based on AUO panel driver by Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/backlight.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/regulator/consumer.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_panel.h>
+
+#include <video/mipi_display.h>
+
+struct sharp_nt_panel {
+ struct drm_panel base;
+ struct mipi_dsi_device *dsi;
+
+ struct backlight_device *backlight;
+ struct regulator *supply;
+ struct gpio_desc *reset_gpio;
+
+ bool prepared;
+ bool enabled;
+
+ const struct drm_display_mode *mode;
+};
+
+static inline struct sharp_nt_panel *to_sharp_nt_panel(struct drm_panel *panel)
+{
+ return container_of(panel, struct sharp_nt_panel, base);
+}
+
+static int sharp_nt_panel_init(struct sharp_nt_panel *sharp_nt)
+{
+ struct mipi_dsi_device *dsi = sharp_nt->dsi;
+ int ret;
+
+ dsi->mode_flags |= MIPI_DSI_MODE_LPM;
+
+ ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
+ if (ret < 0)
+ return ret;
+
+ msleep(120);
+
+ /* Novatek two-lane operation */
+ ret = mipi_dsi_dcs_write(dsi, 0xae, (u8[]){ 0x03 }, 1);
+ if (ret < 0)
+ return ret;
+
+ /* Set both MCU and RGB I/F to 24bpp */
+ ret = mipi_dsi_dcs_set_pixel_format(dsi, MIPI_DCS_PIXEL_FMT_24BIT |
+ (MIPI_DCS_PIXEL_FMT_24BIT << 4));
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int sharp_nt_panel_on(struct sharp_nt_panel *sharp_nt)
+{
+ struct mipi_dsi_device *dsi = sharp_nt->dsi;
+ int ret;
+
+ dsi->mode_flags |= MIPI_DSI_MODE_LPM;
+
+ ret = mipi_dsi_dcs_set_display_on(dsi);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int sharp_nt_panel_off(struct sharp_nt_panel *sharp_nt)
+{
+ struct mipi_dsi_device *dsi = sharp_nt->dsi;
+ int ret;
+
+ dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
+
+ ret = mipi_dsi_dcs_set_display_off(dsi);
+ if (ret < 0)
+ return ret;
+
+ ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+
+static int sharp_nt_panel_disable(struct drm_panel *panel)
+{
+ struct sharp_nt_panel *sharp_nt = to_sharp_nt_panel(panel);
+
+ if (!sharp_nt->enabled)
+ return 0;
+
+ if (sharp_nt->backlight) {
+ sharp_nt->backlight->props.power = FB_BLANK_POWERDOWN;
+ backlight_update_status(sharp_nt->backlight);
+ }
+
+ sharp_nt->enabled = false;
+
+ return 0;
+}
+
+static int sharp_nt_panel_unprepare(struct drm_panel *panel)
+{
+ struct sharp_nt_panel *sharp_nt = to_sharp_nt_panel(panel);
+ int ret;
+
+ if (!sharp_nt->prepared)
+ return 0;
+
+ ret = sharp_nt_panel_off(sharp_nt);
+ if (ret < 0) {
+ dev_err(panel->dev, "failed to set panel off: %d\n", ret);
+ return ret;
+ }
+
+ regulator_disable(sharp_nt->supply);
+ if (sharp_nt->reset_gpio)
+ gpiod_set_value(sharp_nt->reset_gpio, 0);
+
+ sharp_nt->prepared = false;
+
+ return 0;
+}
+
+static int sharp_nt_panel_prepare(struct drm_panel *panel)
+{
+ struct sharp_nt_panel *sharp_nt = to_sharp_nt_panel(panel);
+ int ret;
+
+ if (sharp_nt->prepared)
+ return 0;
+
+ ret = regulator_enable(sharp_nt->supply);
+ if (ret < 0)
+ return ret;
+
+ msleep(20);
+
+ if (sharp_nt->reset_gpio) {
+ gpiod_set_value(sharp_nt->reset_gpio, 1);
+ msleep(1);
+ gpiod_set_value(sharp_nt->reset_gpio, 0);
+ msleep(1);
+ gpiod_set_value(sharp_nt->reset_gpio, 1);
+ msleep(10);
+ }
+
+ ret = sharp_nt_panel_init(sharp_nt);
+ if (ret < 0) {
+ dev_err(panel->dev, "failed to init panel: %d\n", ret);
+ goto poweroff;
+ }
+
+ ret = sharp_nt_panel_on(sharp_nt);
+ if (ret < 0) {
+ dev_err(panel->dev, "failed to set panel on: %d\n", ret);
+ goto poweroff;
+ }
+
+ sharp_nt->prepared = true;
+
+ return 0;
+
+poweroff:
+ regulator_disable(sharp_nt->supply);
+ if (sharp_nt->reset_gpio)
+ gpiod_set_value(sharp_nt->reset_gpio, 0);
+ return ret;
+}
+
+static int sharp_nt_panel_enable(struct drm_panel *panel)
+{
+ struct sharp_nt_panel *sharp_nt = to_sharp_nt_panel(panel);
+
+ if (sharp_nt->enabled)
+ return 0;
+
+ if (sharp_nt->backlight) {
+ sharp_nt->backlight->props.power = FB_BLANK_UNBLANK;
+ backlight_update_status(sharp_nt->backlight);
+ }
+
+ sharp_nt->enabled = true;
+
+ return 0;
+}
+
+static const struct drm_display_mode default_mode = {
+ .clock = 41118,
+ .hdisplay = 540,
+ .hsync_start = 540 + 48,
+ .hsync_end = 540 + 48 + 80,
+ .htotal = 540 + 48 + 80 + 32,
+ .vdisplay = 960,
+ .vsync_start = 960 + 3,
+ .vsync_end = 960 + 3 + 15,
+ .vtotal = 960 + 3 + 15 + 1,
+ .vrefresh = 60,
+};
+
+static int sharp_nt_panel_get_modes(struct drm_panel *panel)
+{
+ struct drm_display_mode *mode;
+
+ mode = drm_mode_duplicate(panel->drm, &default_mode);
+ if (!mode) {
+ dev_err(panel->drm->dev, "failed to add mode %ux%ux@%u\n",
+ default_mode.hdisplay, default_mode.vdisplay,
+ default_mode.vrefresh);
+ return -ENOMEM;
+ }
+
+ drm_mode_set_name(mode);
+
+ drm_mode_probed_add(panel->connector, mode);
+
+ panel->connector->display_info.width_mm = 54;
+ panel->connector->display_info.height_mm = 95;
+
+ return 1;
+}
+
+static const struct drm_panel_funcs sharp_nt_panel_funcs = {
+ .disable = sharp_nt_panel_disable,
+ .unprepare = sharp_nt_panel_unprepare,
+ .prepare = sharp_nt_panel_prepare,
+ .enable = sharp_nt_panel_enable,
+ .get_modes = sharp_nt_panel_get_modes,
+};
+
+static int sharp_nt_panel_add(struct sharp_nt_panel *sharp_nt)
+{
+ struct device *dev = &sharp_nt->dsi->dev;
+ struct device_node *np;
+ int ret;
+
+ sharp_nt->mode = &default_mode;
+
+ sharp_nt->supply = devm_regulator_get(dev, "avdd");
+ if (IS_ERR(sharp_nt->supply))
+ return PTR_ERR(sharp_nt->supply);
+
+ sharp_nt->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+ if (IS_ERR(sharp_nt->reset_gpio)) {
+ dev_err(dev, "cannot get reset-gpios %ld\n",
+ PTR_ERR(sharp_nt->reset_gpio));
+ sharp_nt->reset_gpio = NULL;
+ } else {
+ gpiod_set_value(sharp_nt->reset_gpio, 0);
+ }
+
+ np = of_parse_phandle(dev->of_node, "backlight", 0);
+ if (np) {
+ sharp_nt->backlight = of_find_backlight_by_node(np);
+ of_node_put(np);
+
+ if (!sharp_nt->backlight)
+ return -EPROBE_DEFER;
+ }
+
+ drm_panel_init(&sharp_nt->base);
+ sharp_nt->base.funcs = &sharp_nt_panel_funcs;
+ sharp_nt->base.dev = &sharp_nt->dsi->dev;
+
+ ret = drm_panel_add(&sharp_nt->base);
+ if (ret < 0)
+ goto put_backlight;
+
+ return 0;
+
+put_backlight:
+ if (sharp_nt->backlight)
+ put_device(&sharp_nt->backlight->dev);
+
+ return ret;
+}