Commit bcc9a465 authored by Guido Gunther's avatar Guido Gunther

Merge branch 'unbreak-panel' into 'imx8-4.18-wip'

Unbreak built in LCD panel

Closes #5

See merge request !18
parents 96172929 f87b0ae8
......@@ -16,7 +16,7 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2088a-rdb.dtb
dtb-$(CONFIG_SOC_IMX8MQ) += emcraft-imx8-som.dtb
dtb-$(CONFIG_SOC_IMX8MQ) += librem5-evk.dtb
dtb-$(CONFIG_SOC_IMX8MQ) += librem5-evk-lcdonly.dtb
dtb-$(CONFIG_SOC_IMX8MQ) += librem5-evk-hdmi.dtb
dtb-$(CONFIG_SOC_IMX8MQ) += librem5-evk-otg.dtb
dtb-$(CONFIG_SOC_IMX8MQ) += librem5-evk-usbhost.dtb
dtb-$(CONFIG_SOC_IMX8MQ) += librem5-evk-lcdusbhost.dtb
......@@ -15,5 +15,3 @@
/dts-v1/;
#include "librem5-evk.dtsi"
#include "librem5-evk-lcd.dtsi"
......@@ -15,3 +15,5 @@
/dts-v1/;
#include "librem5-evk.dtsi"
#include "librem5-evk-lcd.dtsi"
......@@ -30,6 +30,7 @@
#include <linux/of_platform.h>
#include <linux/phy/phy.h>
#include <linux/spinlock.h>
#include <soc/imx8/soc.h>
#include <video/mipi_display.h>
#include <video/videomode.h>
......@@ -758,16 +759,6 @@ static void nwl_dsi_finish_transmission(struct nwl_mipi_dsi *dsi, u32 status)
if (!xfer)
return;
if (status & TX_FIFO_OVFLW) {
DRM_DEV_ERROR_RATELIMITED(dsi->dev, "tx fifo overflow");
return;
}
if (status & HS_TX_TIMEOUT) {
DRM_DEV_ERROR_RATELIMITED(dsi->dev, "HS tx timeout");
return;
}
if (xfer->direction == DSI_PACKET_SEND && status & TX_PKT_DONE) {
xfer->status = xfer->tx_len;
end_packet = true;
......@@ -780,6 +771,13 @@ static void nwl_dsi_finish_transmission(struct nwl_mipi_dsi *dsi, u32 status)
complete(&xfer->completed);
}
#define B0_SILICON_ID 0x20
static bool nwl_use_e11418_workaround(void)
{
return (imx8_get_soc_revision() == B0_SILICON_ID) ? true : false;
}
static void nwl_dsi_begin_transmission(struct nwl_mipi_dsi *dsi)
{
struct mipi_dsi_transfer *xfer = dsi->xfer;
......@@ -789,6 +787,7 @@ static void nwl_dsi_begin_transmission(struct nwl_mipi_dsi *dsi)
u16 word_count;
u8 hs_mode;
u32 val;
u32 hs_workaround = 0;
/* Send the payload, if any */
length = pkt->payload_length;
......@@ -796,6 +795,7 @@ static void nwl_dsi_begin_transmission(struct nwl_mipi_dsi *dsi)
while (length >= 4) {
val = get_unaligned_le32(payload);
hs_workaround |= !(val & 0xFFFF00);
nwl_dsi_write(dsi, TX_PAYLOAD, val);
payload += 4;
length -= 4;
......@@ -808,6 +808,7 @@ static void nwl_dsi_begin_transmission(struct nwl_mipi_dsi *dsi)
/* Fall through */
case 2:
val |= payload[1] << 8;
hs_workaround |= !(val & 0xFFFF00);
/* Fall through */
case 1:
val |= payload[0];
......@@ -824,7 +825,15 @@ static void nwl_dsi_begin_transmission(struct nwl_mipi_dsi *dsi)
* header[2] = Word Count MSB (LP) or second param (SP)
*/
word_count = pkt->header[1] | (pkt->header[2] << 8);
hs_mode = (xfer->msg->flags & MIPI_DSI_MSG_USE_LPM)?0:1;
if ((hs_workaround && nwl_use_e11418_workaround())) {
DRM_DEV_DEBUG_DRIVER(dsi->dev,
"Using hs mode workaround for cmd 0x%x",
xfer->cmd);
hs_mode = 1;
} else {
hs_mode = (xfer->msg->flags & MIPI_DSI_MSG_USE_LPM)?0:1;
}
val = WC(word_count) |
TX_VC(xfer->msg->channel) |
TX_DT(xfer->msg->type) |
......@@ -909,6 +918,12 @@ static irqreturn_t nwl_dsi_irq_handler(int irq, void *data)
irq_status & RX_PKT_PAYLOAD_DATA_RCVD)
nwl_dsi_finish_transmission(dsi, irq_status);
if (irq_status & TX_FIFO_OVFLW)
DRM_DEV_ERROR_RATELIMITED(dsi->dev, "tx fifo overflow");
if (irq_status & HS_TX_TIMEOUT)
DRM_DEV_ERROR_RATELIMITED(dsi->dev, "HS tx timeout");
return IRQ_HANDLED;
}
......
......@@ -12,11 +12,14 @@
#include <linux/gpio/consumer.h>
#include <video/mipi_display.h>
#include <video/display_timing.h>
#include <linux/debugfs.h>
#define DRV_NAME "jh057n00900"
/* The Rockteck jh057n00900 uses a Sitronix ST7703 */
#define ST7703_DCS_CMD_ALLPOFF 0x22 /* all pixels off */
#define ST7703_DCS_CMD_ALLPON 0x23 /* all pixels on */
/* Manufacturer Command Set */
#define ST7703_CMD_SETDISP 0xB2 /* display resolution */
#define ST7703_CMD_SETRGBIF 0xB3 /* porch adjustment */
......@@ -43,6 +46,8 @@ struct jh057n {
struct backlight_device *backlight;
bool prepared;
bool enabled;
struct dentry *debugfs;
};
static const struct drm_display_mode default_mode = {
......@@ -61,7 +66,6 @@ static const struct drm_display_mode default_mode = {
.height_mm = 130,
};
static inline struct jh057n *panel_to_jh057n(struct drm_panel *panel)
{
return container_of(panel, struct jh057n, panel);
......@@ -88,47 +92,25 @@ static int jh057n_init_sequence(struct jh057n *ctx)
struct device *dev = ctx->dev;
int ret;
/* Enable user command */
dsi_generic_write_seq(ctx, ST7703_CMD_SETEXTC, /* 3 */
0xF1, 0x12, 0x83);
/* 6 params in ST7703 docs */
dsi_generic_write_seq(ctx, ST7703_CMD_SETMIPI, /* 27 */
0x33, 0x81, 0x05, 0xF9, 0x0E, 0x0E, 0x20, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x25,
0x00, 0x91, 0x0A, 0x00, 0x00, 0x02, 0x4F, 0x11,
0x00, 0x00, 0x37);
/* 6 params in ST7703 docs */
dsi_generic_write_seq(ctx, ST7703_CMD_SETPOWER_EXT, /* 4 */
0x76, 0x22, 0x20, 0x03);
/* 4 params in ST7703 docs */
dsi_generic_write_seq(ctx, ST7703_CMD_SETRGBIF, /* 10 */
0x10, 0x10, 0x05, 0x05, 0x03, 0xFF, 0x00, 0x00,
0x00, 0x00);
/* 8 params in ST7703 docs */
dsi_generic_write_seq(ctx, ST7703_CMD_SETSCR, /* 9 */
0x73, 0x73, 0x50, 0x50, 0x00, 0x00, 0x08, 0x70,
0x00);
/* -1.6V & + 1.9V */
dsi_generic_write_seq(ctx, ST7703_CMD_SETVDC, 0x4E);
/* SS_PANEL, REV_PANEL, BGR_PANEL */
dsi_generic_write_seq(ctx, ST7703_CMD_SETPANEL, 0x0B);
/* 2 params in ST7703 docs */
dsi_generic_write_seq(ctx, ST7703_CMD_SETCYC, 0x80);
/* weird values, e.g. a 720 panel has BIT(1) 3rd param */
dsi_generic_write_seq(ctx, ST7703_CMD_SETDISP, 0xF0, 0x12, 0x30);
dsi_generic_write_seq(ctx, ST7703_CMD_SETEQ, /* 14 */
0x07, 0x07, 0x0B, 0x0B, 0x03, 0x0B, 0x00, 0x00,
0x00, 0x00, 0xFF, 0x00, 0xC0, 0x10);
dsi_generic_write_seq(ctx, ST7703_CMD_SETPOWER, /* 12 */
0x54, 0x00, 0x1E, 0x1E, 0x77, 0xF1, 0xFF, 0xFF,
0xCC, 0xCC, 0x77, 0x77);
/* setbgp is different from our first data set*/
dsi_generic_write_seq(ctx, ST7703_CMD_SETBGP, 0x08, 0x08);
mdelay(100);
/* setvcom is different from our first data set*/
dsi_generic_write_seq(ctx, ST7703_CMD_SETVCOM, 0x3F, 0x3F);
/* undocumented */
dsi_generic_write_seq(ctx, 0xBF, 0x02, 0x11, 0x00);
dsi_generic_write_seq(ctx, ST7703_CMD_SETGIP1, /* 63 */
0x82, 0x10, 0x06, 0x05, 0x9E, 0x0A, 0xA5, 0x12,
......@@ -139,7 +121,6 @@ static int jh057n_init_sequence(struct jh057n *ctx)
0x64, 0x20, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
0x02, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
/* 39 parameters accordin to ST7703 docs */
dsi_generic_write_seq(ctx, ST7703_CMD_SETGIP2, /* 61 */
0x02, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x02, 0x46, 0x02, 0x88,
......@@ -309,6 +290,47 @@ static const struct drm_panel_funcs jh057n_drm_funcs = {
.get_modes = jh057n_get_modes,
};
static int allpixelson_set(void *data, u64 val)
{
struct jh057n *ctx = data;
DRM_DEV_DEBUG_DRIVER(ctx->dev, "Setting all pixels on");
dsi_generic_write_seq(ctx, ST7703_DCS_CMD_ALLPON);
/* reset the panel after val seconds */
msleep(val*1000);
jh057n_unprepare(&ctx->panel);
msleep(10);
jh057n_prepare(&ctx->panel);
jh057n_enable(&ctx->panel);
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(allpixelson_fops, NULL,
allpixelson_set, "%llu\n");
static int jh057n_debugfs_init (struct jh057n *ctx)
{
struct dentry *f;
ctx->debugfs = debugfs_create_dir(DRV_NAME, NULL);
if (!ctx->debugfs)
return -ENOMEM;
f = debugfs_create_file("allpixelson", S_IRUSR | S_IWUSR,
ctx->debugfs, ctx, &allpixelson_fops);
if (!f)
return -ENOMEM;
return 0;
}
static void jh057n_debugfs_remove(struct jh057n *ctx)
{
debugfs_remove_recursive(ctx->debugfs);
ctx->debugfs = NULL;
}
static int jh057n_probe(struct mipi_dsi_device *dsi)
{
struct device *dev = &dsi->dev;
......@@ -368,6 +390,7 @@ static int jh057n_probe(struct mipi_dsi_device *dsi)
default_mode.vrefresh,
mipi_dsi_pixel_format_to_bpp(dsi->format), dsi->lanes);
jh057n_debugfs_init(ctx);
return 0;
}
......@@ -381,6 +404,8 @@ static int jh057n_remove(struct mipi_dsi_device *dsi)
if (ctx->backlight)
put_device(&ctx->backlight->dev);
jh057n_debugfs_remove(ctx);
return 0;
}
......
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