Commit 6406e45c authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm/panel/for-4.3-rc1' of git://anongit.freedesktop.org/tegra/linux into drm-next

drm/panel: Changes for v4.3-rc1

This introduces support for a couple of new panels and also contains
some work to restructure the directories to get more consistency, to
deal better with more panel and bridge drivers getting added.

* tag 'drm/panel/for-4.3-rc1' of git://anongit.freedesktop.org/tegra/linux:
  drm/bridge: Put Kconfig entries in a separate menu
  drm/panel: Add support for LG LG4573 480x800 4.3" panel
  drm/panel: Add display timing for Okaya RS800480T-7X0GP
  of: Add Okaya Electric America vendor prefix
  drm/panel: simple: Add support for NEC NL4827HC19-05B 480x272 panel
  drm/panel: simple: Add support for AUO B080UAN01
  drm/panel: simple: Correct minimum hsync length of the HannStar HSD070PWW1 panel
  drm/panel: simple: Add bus format for HannStar HSD070PWW1 LVDS panel
  drm/bridge: Add vendor prefixes
  drm/panel: Add Samsung prefix to panel drivers
  drm/exynos: Remove PTN3460 dependency
parents bef2c7bd a33ee95f
AU Optronics Corporation 8.0" WUXGA TFT LCD panel
Required properties:
- compatible: should be "auo,b101ean01"
This binding is compatible with the simple-panel binding, which is specified
in simple-panel.txt in this directory.
LG LG4573 TFT Liquid Crystal Display with SPI control bus
Required properties:
- compatible: "lg,lg4573"
- reg: address of the panel on the SPI bus
The panel must obey rules for SPI slave device specified in document [1].
[1]: Documentation/devicetree/bindings/spi/spi-bus.txt
Example:
lcd_panel: display@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "lg,lg4573";
spi-max-frequency = <10000000>;
reg = <0>;
};
NEC LCD Technologies,Ltd. WQVGA TFT LCD panel
Required properties:
- compatible: should be "nec,nl4827hc19-05b"
This binding is compatible with the simple-panel binding, which is specified
in simple-panel.txt in this directory.
OKAYA Electric America, Inc. RS800480T-7X0GP 7" WVGA LCD panel
Required properties:
- compatible: should be "okaya,rs800480t-7x0gp"
This binding is compatible with the simple-panel binding, which is specified
in simple-panel.txt in this directory.
......@@ -148,6 +148,7 @@ nintendo Nintendo
nokia Nokia
nvidia NVIDIA
nxp NXP Semiconductors
okaya Okaya Electric America, Inc.
onnn ON Semiconductor Corp.
opencores OpenCores.org
ortustech Ortus Technology Co., Ltd.
......
......@@ -124,14 +124,14 @@ CONFIG_REGULATOR_S2MPS11=y
CONFIG_REGULATOR_S5M8767=y
CONFIG_REGULATOR_TPS65090=y
CONFIG_DRM=y
CONFIG_DRM_PTN3460=y
CONFIG_DRM_PS8622=y
CONFIG_DRM_NXP_PTN3460=y
CONFIG_DRM_PARADE_PS8622=y
CONFIG_DRM_EXYNOS=y
CONFIG_DRM_EXYNOS_FIMD=y
CONFIG_DRM_EXYNOS_DSI=y
CONFIG_DRM_EXYNOS_HDMI=y
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_PANEL_S6E8AA0=y
CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0=y
CONFIG_FB_SIMPLE=y
CONFIG_EXYNOS_VIDEO=y
CONFIG_EXYNOS_MIPI_DSI=y
......
......@@ -429,15 +429,15 @@ CONFIG_VIDEO_RENESAS_VSP1=m
CONFIG_VIDEO_ADV7180=m
CONFIG_VIDEO_ML86V7667=m
CONFIG_DRM=y
CONFIG_DRM_PTN3460=m
CONFIG_DRM_PS8622=m
CONFIG_DRM_NXP_PTN3460=m
CONFIG_DRM_PARADE_PS8622=m
CONFIG_DRM_EXYNOS=m
CONFIG_DRM_EXYNOS_DSI=y
CONFIG_DRM_EXYNOS_FIMD=y
CONFIG_DRM_EXYNOS_HDMI=y
CONFIG_DRM_RCAR_DU=m
CONFIG_DRM_TEGRA=y
CONFIG_DRM_PANEL_S6E8AA0=m
CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0=m
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_FB_ARMCLCD=y
CONFIG_FB_WM8505=y
......
......@@ -99,8 +99,6 @@ config DRM_KMS_CMA_HELPER
source "drivers/gpu/drm/i2c/Kconfig"
source "drivers/gpu/drm/bridge/Kconfig"
config DRM_TDFX
tristate "3dfx Banshee/Voodoo3+"
depends on DRM && PCI
......@@ -255,6 +253,8 @@ source "drivers/gpu/drm/tegra/Kconfig"
source "drivers/gpu/drm/panel/Kconfig"
source "drivers/gpu/drm/bridge/Kconfig"
source "drivers/gpu/drm/sti/Kconfig"
source "drivers/gpu/drm/amd/amdkfd/Kconfig"
......
config DRM_BRIDGE
def_bool y
depends on DRM
help
Bridge registration and lookup framework.
menu "Display Interface Bridges"
depends on DRM && DRM_BRIDGE
config DRM_DW_HDMI
tristate
depends on DRM
select DRM_KMS_HELPER
config DRM_PTN3460
tristate "PTN3460 DP/LVDS bridge"
depends on DRM
config DRM_NXP_PTN3460
tristate "NXP PTN3460 DP/LVDS bridge"
depends on OF
select DRM_KMS_HELPER
select DRM_PANEL
---help---
ptn3460 eDP-LVDS bridge chip driver.
NXP PTN3460 eDP-LVDS bridge chip driver.
config DRM_PS8622
config DRM_PARADE_PS8622
tristate "Parade eDP/LVDS bridge"
depends on DRM
depends on OF
select DRM_PANEL
select DRM_KMS_HELPER
select BACKLIGHT_LCD_SUPPORT
select BACKLIGHT_CLASS_DEVICE
---help---
parade eDP-LVDS bridge chip driver.
Parade eDP-LVDS bridge chip driver.
endmenu
ccflags-y := -Iinclude/drm
obj-$(CONFIG_DRM_PS8622) += ps8622.o
obj-$(CONFIG_DRM_PTN3460) += ptn3460.o
obj-$(CONFIG_DRM_DW_HDMI) += dw_hdmi.o
obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o
obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o
......@@ -56,7 +56,7 @@ config DRM_EXYNOS_DSI
config DRM_EXYNOS_DP
bool "EXYNOS DRM DP driver support"
depends on DRM_EXYNOS && (DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON) && (DRM_PTN3460=n || DRM_PTN3460=y || DRM_PTN3460=DRM_EXYNOS)
depends on DRM_EXYNOS && (DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON)
default DRM_EXYNOS
select DRM_PANEL
help
......
......@@ -18,13 +18,21 @@ config DRM_PANEL_SIMPLE
that it can be automatically turned off when the panel goes into a
low power state.
config DRM_PANEL_LD9040
tristate "LD9040 RGB/SPI panel"
config DRM_PANEL_SAMSUNG_LD9040
tristate "Samsung LD9040 RGB/SPI panel"
depends on OF && SPI
select VIDEOMODE_HELPERS
config DRM_PANEL_S6E8AA0
tristate "S6E8AA0 DSI video mode panel"
config DRM_PANEL_LG_LG4573
tristate "LG4573 RGB/SPI panel"
depends on OF && SPI
select VIDEOMODE_HELPERS
help
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_SAMSUNG_S6E8AA0
tristate "Samsung S6E8AA0 DSI video mode panel"
depends on OF
select DRM_MIPI_DSI
select VIDEOMODE_HELPERS
......
obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o
obj-$(CONFIG_DRM_PANEL_LD9040) += panel-ld9040.o
obj-$(CONFIG_DRM_PANEL_S6E8AA0) += panel-s6e8aa0.o
obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.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
/*
* Copyright (C) 2015 Heiko Schocher <hs@denx.de>
*
* from:
* drivers/gpu/drm/panel/panel-ld9040.c
* ld9040 AMOLED LCD drm_panel driver.
*
* Copyright (c) 2014 Samsung Electronics Co., Ltd
* Derived from drivers/video/backlight/ld9040.c
*
* Andrzej Hajda <a.hajda@samsung.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.
*/
#include <drm/drmP.h>
#include <drm/drm_panel.h>
#include <linux/gpio/consumer.h>
#include <linux/regulator/consumer.h>
#include <linux/spi/spi.h>
#include <video/mipi_display.h>
#include <video/of_videomode.h>
#include <video/videomode.h>
struct lg4573 {
struct drm_panel panel;
struct spi_device *spi;
struct videomode vm;
};
static inline struct lg4573 *panel_to_lg4573(struct drm_panel *panel)
{
return container_of(panel, struct lg4573, panel);
}
static int lg4573_spi_write_u16(struct lg4573 *ctx, u16 data)
{
struct spi_transfer xfer = {
.len = 2,
};
u16 temp = cpu_to_be16(data);
struct spi_message msg;
dev_dbg(ctx->panel.dev, "writing data: %x\n", data);
xfer.tx_buf = &temp;
spi_message_init(&msg);
spi_message_add_tail(&xfer, &msg);
return spi_sync(ctx->spi, &msg);
}
static int lg4573_spi_write_u16_array(struct lg4573 *ctx, const u16 *buffer,
unsigned int count)
{
unsigned int i;
int ret;
for (i = 0; i < count; i++) {
ret = lg4573_spi_write_u16(ctx, buffer[i]);
if (ret)
return ret;
}
return 0;
}
static int lg4573_spi_write_dcs(struct lg4573 *ctx, u8 dcs)
{
return lg4573_spi_write_u16(ctx, (0x70 << 8 | dcs));
}
static int lg4573_display_on(struct lg4573 *ctx)
{
int ret;
ret = lg4573_spi_write_dcs(ctx, MIPI_DCS_EXIT_SLEEP_MODE);
if (ret)
return ret;
msleep(5);
return lg4573_spi_write_dcs(ctx, MIPI_DCS_SET_DISPLAY_ON);
}
static int lg4573_display_off(struct lg4573 *ctx)
{
int ret;
ret = lg4573_spi_write_dcs(ctx, MIPI_DCS_SET_DISPLAY_OFF);
if (ret)
return ret;
msleep(120);
return lg4573_spi_write_dcs(ctx, MIPI_DCS_ENTER_SLEEP_MODE);
}
static int lg4573_display_mode_settings(struct lg4573 *ctx)
{
static const u16 display_mode_settings[] = {
0x703A, 0x7270, 0x70B1, 0x7208,
0x723B, 0x720F, 0x70B2, 0x7200,
0x72C8, 0x70B3, 0x7200, 0x70B4,
0x7200, 0x70B5, 0x7242, 0x7210,
0x7210, 0x7200, 0x7220, 0x70B6,
0x720B, 0x720F, 0x723C, 0x7213,
0x7213, 0x72E8, 0x70B7, 0x7246,
0x7206, 0x720C, 0x7200, 0x7200,
};
dev_dbg(ctx->panel.dev, "transfer display mode settings\n");
return lg4573_spi_write_u16_array(ctx, display_mode_settings,
ARRAY_SIZE(display_mode_settings));
}
static int lg4573_power_settings(struct lg4573 *ctx)
{
static const u16 power_settings[] = {
0x70C0, 0x7201, 0x7211, 0x70C3,
0x7207, 0x7203, 0x7204, 0x7204,
0x7204, 0x70C4, 0x7212, 0x7224,
0x7218, 0x7218, 0x7202, 0x7249,
0x70C5, 0x726F, 0x70C6, 0x7241,
0x7263,
};
dev_dbg(ctx->panel.dev, "transfer power settings\n");
return lg4573_spi_write_u16_array(ctx, power_settings,
ARRAY_SIZE(power_settings));
}
static int lg4573_gamma_settings(struct lg4573 *ctx)
{
static const u16 gamma_settings[] = {
0x70D0, 0x7203, 0x7207, 0x7273,
0x7235, 0x7200, 0x7201, 0x7220,
0x7200, 0x7203, 0x70D1, 0x7203,
0x7207, 0x7273, 0x7235, 0x7200,
0x7201, 0x7220, 0x7200, 0x7203,
0x70D2, 0x7203, 0x7207, 0x7273,
0x7235, 0x7200, 0x7201, 0x7220,
0x7200, 0x7203, 0x70D3, 0x7203,
0x7207, 0x7273, 0x7235, 0x7200,
0x7201, 0x7220, 0x7200, 0x7203,
0x70D4, 0x7203, 0x7207, 0x7273,
0x7235, 0x7200, 0x7201, 0x7220,
0x7200, 0x7203, 0x70D5, 0x7203,
0x7207, 0x7273, 0x7235, 0x7200,
0x7201, 0x7220, 0x7200, 0x7203,
};
dev_dbg(ctx->panel.dev, "transfer gamma settings\n");
return lg4573_spi_write_u16_array(ctx, gamma_settings,
ARRAY_SIZE(gamma_settings));
}
static int lg4573_init(struct lg4573 *ctx)
{
int ret;
dev_dbg(ctx->panel.dev, "initializing LCD\n");
ret = lg4573_display_mode_settings(ctx);
if (ret)
return ret;
ret = lg4573_power_settings(ctx);
if (ret)
return ret;
return lg4573_gamma_settings(ctx);
}
static int lg4573_power_on(struct lg4573 *ctx)
{
return lg4573_display_on(ctx);
}
static int lg4573_disable(struct drm_panel *panel)
{
struct lg4573 *ctx = panel_to_lg4573(panel);
return lg4573_display_off(ctx);
}
static int lg4573_enable(struct drm_panel *panel)
{
struct lg4573 *ctx = panel_to_lg4573(panel);
lg4573_init(ctx);
return lg4573_power_on(ctx);
}
static const struct drm_display_mode default_mode = {
.clock = 27000,
.hdisplay = 480,
.hsync_start = 480 + 10,
.hsync_end = 480 + 10 + 59,
.htotal = 480 + 10 + 59 + 10,
.vdisplay = 800,
.vsync_start = 800 + 15,
.vsync_end = 800 + 15 + 15,
.vtotal = 800 + 15 + 15 + 15,
.vrefresh = 60,
};
static int lg4573_get_modes(struct drm_panel *panel)
{
struct drm_connector *connector = panel->connector;
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);
mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
drm_mode_probed_add(connector, mode);
panel->connector->display_info.width_mm = 61;
panel->connector->display_info.height_mm = 103;
return 1;
}
static const struct drm_panel_funcs lg4573_drm_funcs = {
.disable = lg4573_disable,
.enable = lg4573_enable,
.get_modes = lg4573_get_modes,
};
static int lg4573_probe(struct spi_device *spi)
{
struct lg4573 *ctx;
int ret;
ctx = devm_kzalloc(&spi->dev, sizeof(*ctx), GFP_KERNEL);
if (!ctx)
return -ENOMEM;
ctx->spi = spi;
spi_set_drvdata(spi, ctx);
spi->bits_per_word = 8;
ret = spi_setup(spi);
if (ret < 0) {
dev_err(&spi->dev, "SPI setup failed: %d\n", ret);
return ret;
}
drm_panel_init(&ctx->panel);
ctx->panel.dev = &spi->dev;
ctx->panel.funcs = &lg4573_drm_funcs;
return drm_panel_add(&ctx->panel);
}
static int 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[] = {
{ .compatible = "lg,lg4573" },
{ }
};
MODULE_DEVICE_TABLE(of, lg4573_of_match);
static struct spi_driver lg4573_driver = {
.probe = lg4573_probe,
.remove = lg4573_remove,
.driver = {
.name = "lg4573",
.owner = THIS_MODULE,
.of_match_table = lg4573_of_match,
},
};
module_spi_driver(lg4573_driver);
MODULE_AUTHOR("Heiko Schocher <hs@denx.de>");
MODULE_DESCRIPTION("lg4573 LCD Driver");
MODULE_LICENSE("GPL v2");
......@@ -377,7 +377,7 @@ static struct spi_driver ld9040_driver = {
.probe = ld9040_probe,
.remove = ld9040_remove,
.driver = {
.name = "ld9040",
.name = "panel-samsung-ld9040",
.owner = THIS_MODULE,
.of_match_table = ld9040_of_match,
},
......
......@@ -1051,7 +1051,7 @@ static struct mipi_dsi_driver s6e8aa0_driver = {
.probe = s6e8aa0_probe,
.remove = s6e8aa0_remove,
.driver = {
.name = "panel_s6e8aa0",
.name = "panel-samsung-s6e8aa0",
.of_match_table = s6e8aa0_of_match,
},
};
......
......@@ -713,7 +713,12 @@ static const struct display_timing hannstar_hsd070pww1_timing = {
.hactive = { 1280, 1280, 1280 },
.hfront_porch = { 1, 1, 10 },
.hback_porch = { 1, 1, 10 },
.hsync_len = { 52, 158, 661 },
/*
* According to the data sheet, the minimum horizontal blanking interval
* is 54 clocks (1 + 52 + 1), but tests with a Nitrogen6X have shown the
* minimum working horizontal blanking interval to be 60 clocks.
*/
.hsync_len = { 58, 158, 661 },
.vactive = { 800, 800, 800 },
.vfront_porch = { 1, 1, 10 },
.vback_porch = { 1, 1, 10 },
......@@ -729,6 +734,7 @@ static const struct panel_desc hannstar_hsd070pww1 = {
.width = 151,
.height = 94,
},
.bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
};
static const struct display_timing hannstar_hsd100pxn1_timing = {
......@@ -943,6 +949,60 @@ static const struct panel_desc lg_lp129qe = {
},
};
static const struct drm_display_mode nec_nl4827hc19_05b_mode = {
.clock = 10870,
.hdisplay = 480,
.hsync_start = 480 + 2,
.hsync_end = 480 + 2 + 41,
.htotal = 480 + 2 + 41 + 2,
.vdisplay = 272,
.vsync_start = 272 + 2,
.vsync_end = 272 + 2 + 4,
.vtotal = 272 + 2 + 4 + 2,
.vrefresh = 74,
};
static const struct panel_desc nec_nl4827hc19_05b = {
.modes = &nec_nl4827hc19_05b_mode,
.num_modes = 1,
.bpc = 8,
.size = {
.width = 95,
.height = 54,
},
.bus_format = MEDIA_BUS_FMT_RGB888_1X24
};
static const struct display_timing okaya_rs800480t_7x0gp_timing = {
.pixelclock = { 30000000, 30000000, 40000000 },
.hactive = { 800, 800, 800 },
.hfront_porch = { 40, 40, 40 },
.hback_porch = { 40, 40, 40 },
.hsync_len = { 1, 48, 48 },
.vactive = { 480, 480, 480 },
.vfront_porch = { 13, 13, 13 },
.vback_porch = { 29, 29, 29 },
.vsync_len = { 3, 3, 3 },
.flags = DISPLAY_FLAGS_DE_HIGH,
};
static const struct panel_desc okaya_rs800480t_7x0gp = {
.timings = &okaya_rs800480t_7x0gp_timing,
.num_timings = 1,
.bpc = 6,
.size = {
.width = 154,
.height = 87,
},
.delay = {
.prepare = 41,
.enable = 50,
.unprepare = 41,
.disable = 50,
},
.bus_format = MEDIA_BUS_FMT_RGB666_1X18,
};
static const struct drm_display_mode ortustech_com43h4m85ulc_mode = {
.clock = 25000,
.hdisplay = 480,
......@@ -1112,6 +1172,12 @@ static const struct of_device_id platform_of_match[] = {
}, {
.compatible = "lg,lp129qe",
.data = &lg_lp129qe,
}, {
.compatible = "nec,nl4827hc19-05b",
.data = &nec_nl4827hc19_05b,
}, {
.compatible = "okaya,rs800480t-7x0gp",
.data = &okaya_rs800480t_7x0gp,
}, {
.compatible = "ortustech,com43h4m85ulc",
.data = &ortustech_com43h4m85ulc,
......@@ -1169,6 +1235,34 @@ struct panel_desc_dsi {
unsigned int lanes;
};
static const struct drm_display_mode auo_b080uan01_mode = {
.clock = 154500,
.hdisplay = 1200,
.hsync_start = 1200 + 62,
.hsync_end = 1200 + 62 + 4,
.htotal = 1200 + 62 + 4 + 62,
.vdisplay = 1920,
.vsync_start = 1920 + 9,
.vsync_end = 1920 + 9 + 2,
.vtotal = 1920 + 9 + 2 + 8,
.vrefresh = 60,
};
static const struct panel_desc_dsi auo_b080uan01 = {
.desc = {
.modes = &auo_b080uan01_mode,
.num_modes = 1,
.bpc = 8,
.size = {
.width = 108,
.height = 272,
},
},
.flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS,
.format = MIPI_DSI_FMT_RGB888,
.lanes = 4,
};
static const struct drm_display_mode lg_ld070wx3_sl01_mode = {
.clock = 71000,
.hdisplay = 800,
......@@ -1256,6 +1350,9 @@ static const struct panel_desc_dsi panasonic_vvx10f004b00 = {
static const struct of_device_id dsi_of_match[] = {
{
.compatible = "auo,b080uan01",
.data = &auo_b080uan01
}, {
.compatible = "lg,ld070wx3-sl01",
.data = &lg_ld070wx3_sl01
}, {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment