[coreboot-gerrit] Change in coreboot[master]: rockchip/rk3399: mipi dsi support LONG_WRITE type
Lin Huang (Code Review)
gerrit at coreboot.org
Wed Jan 17 08:13:39 CET 2018
Lin Huang has uploaded this change for review. ( https://review.coreboot.org/23299
Change subject: rockchip/rk3399: mipi dsi support LONG_WRITE type
......................................................................
rockchip/rk3399: mipi dsi support LONG_WRITE type
some panel need transfer initial code, and some of them will over
3 bytes, so need to support LONG_WRITE type in driver. Refactor mipi
dsi transfer function to support it.
Change-Id: I212c14165e074c40a4a1a25140d9e8dfdfba465f
Signed-off-by: Lin Huang <hl at rock-chips.com>
---
M src/mainboard/google/gru/mainboard.c
M src/soc/rockchip/rk3399/include/soc/mipi.h
M src/soc/rockchip/rk3399/mipi.c
3 files changed, 216 insertions(+), 133 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/99/23299/1
diff --git a/src/mainboard/google/gru/mainboard.c b/src/mainboard/google/gru/mainboard.c
index 1212ad5..0611ca5 100644
--- a/src/mainboard/google/gru/mainboard.c
+++ b/src/mainboard/google/gru/mainboard.c
@@ -378,136 +378,137 @@
static struct panel_init_command kd097d04_init_commands[] = {
/* voltage setting */
- { 0xB0, 0x00 },
- { 0xB2, 0x02 },
- { 0xB3, 0x11 },
- { 0xB4, 0x00 },
- { 0xB6, 0x80 },
+ _INIT_CMD(0xB0, 0x00),
+ _INIT_CMD(0xB2, 0x02),
+ _INIT_CMD(0xB3, 0x11),
+ _INIT_CMD(0xB4, 0x00),
+ _INIT_CMD(0xB6, 0x80),
/* VCOM disable */
- { 0xB8, 0x80 },
- { 0xBA, 0x43 },
+ _INIT_CMD(0xB8, 0x80),
+ _INIT_CMD(0xBA, 0x43),
/* VCOM setting */
- { 0xBB, 0x53 },
+ _INIT_CMD(0xBB, 0x53),
/* VSP setting */
- { 0xBC, 0x0A },
+ _INIT_CMD(0xBC, 0x0A),
/* VSN setting */
- { 0xBD, 0x4A },
+ _INIT_CMD(0xBD, 0x4A),
/* VGH setting */
- { 0xBE, 0x2F },
+ _INIT_CMD(0xBE, 0x2F),
/* VGL setting */
- { 0xBF, 0x1A },
- { 0xF0, 0x39 },
- { 0xF1, 0x21 },
+ _INIT_CMD(0xBF, 0x1A),
+ _INIT_CMD(0xF0, 0x39),
+ _INIT_CMD(0xF1, 0x21),
/* Gamma setting */
- { 0xB0, 0x02 },
- { 0xC0, 0x00 },
- { 0xC1, 0x01 },
- { 0xC2, 0x0B },
- { 0xC3, 0x15 },
- { 0xC4, 0x22 },
- { 0xC5, 0x11 },
- { 0xC6, 0x15 },
- { 0xC7, 0x19 },
- { 0xC8, 0x1A },
- { 0xC9, 0x16 },
- { 0xCA, 0x18 },
- { 0xCB, 0x13 },
- { 0xCC, 0x18 },
- { 0xCD, 0x13 },
- { 0xCE, 0x1C },
- { 0xCF, 0x19 },
- { 0xD0, 0x21 },
- { 0xD1, 0x2C },
- { 0xD2, 0x2F },
- { 0xD3, 0x30 },
- { 0xD4, 0x19 },
- { 0xD5, 0x1F },
- { 0xD6, 0x00 },
- { 0xD7, 0x01 },
- { 0xD8, 0x0B },
- { 0xD9, 0x15 },
- { 0xDA, 0x22 },
- { 0xDB, 0x11 },
- { 0xDC, 0x15 },
- { 0xDD, 0x19 },
- { 0xDE, 0x1A },
- { 0xDF, 0x16 },
- { 0xE0, 0x18 },
- { 0xE1, 0x13 },
- { 0xE2, 0x18 },
- { 0xE3, 0x13 },
- { 0xE4, 0x1C },
- { 0xE5, 0x19 },
- { 0xE6, 0x21 },
- { 0xE7, 0x2C },
- { 0xE8, 0x2F },
- { 0xE9, 0x30 },
- { 0xEA, 0x19 },
- { 0xEB, 0x1F },
+ _INIT_CMD(0xB0, 0x02),
+ _INIT_CMD(0xC0, 0x00),
+ _INIT_CMD(0xC1, 0x01),
+ _INIT_CMD(0xC2, 0x0B),
+ _INIT_CMD(0xC3, 0x15),
+ _INIT_CMD(0xC4, 0x22),
+ _INIT_CMD(0xC5, 0x11),
+ _INIT_CMD(0xC6, 0x15),
+ _INIT_CMD(0xC7, 0x19),
+ _INIT_CMD(0xC8, 0x1A),
+ _INIT_CMD(0xC9, 0x16),
+ _INIT_CMD(0xCA, 0x18),
+ _INIT_CMD(0xCB, 0x13),
+ _INIT_CMD(0xCC, 0x18),
+ _INIT_CMD(0xCD, 0x13),
+ _INIT_CMD(0xCE, 0x1C),
+ _INIT_CMD(0xCF, 0x19),
+ _INIT_CMD(0xD0, 0x21),
+ _INIT_CMD(0xD1, 0x2C),
+ _INIT_CMD(0xD2, 0x2F),
+ _INIT_CMD(0xD3, 0x30),
+ _INIT_CMD(0xD4, 0x19),
+ _INIT_CMD(0xD5, 0x1F),
+ _INIT_CMD(0xD6, 0x00),
+ _INIT_CMD(0xD7, 0x01),
+ _INIT_CMD(0xD8, 0x0B),
+ _INIT_CMD(0xD9, 0x15),
+ _INIT_CMD(0xDA, 0x22),
+ _INIT_CMD(0xDB, 0x11),
+ _INIT_CMD(0xDC, 0x15),
+ _INIT_CMD(0xDD, 0x19),
+ _INIT_CMD(0xDE, 0x1A),
+ _INIT_CMD(0xDF, 0x16),
+ _INIT_CMD(0xE0, 0x18),
+ _INIT_CMD(0xE1, 0x13),
+ _INIT_CMD(0xE2, 0x18),
+ _INIT_CMD(0xE3, 0x13),
+ _INIT_CMD(0xE4, 0x1C),
+ _INIT_CMD(0xE5, 0x19),
+ _INIT_CMD(0xE6, 0x21),
+ _INIT_CMD(0xE7, 0x2C),
+ _INIT_CMD(0xE8, 0x2F),
+ _INIT_CMD(0xE9, 0x30),
+ _INIT_CMD(0xEA, 0x19),
+ _INIT_CMD(0xEB, 0x1F),
/* GOA MUX setting */
- { 0xB0, 0x01 },
- { 0xC0, 0x10 },
- { 0xC1, 0x0F },
- { 0xC2, 0x0E },
- { 0xC3, 0x0D },
- { 0xC4, 0x0C },
- { 0xC5, 0x0B },
- { 0xC6, 0x0A },
- { 0xC7, 0x09 },
- { 0xC8, 0x08 },
- { 0xC9, 0x07 },
- { 0xCA, 0x06 },
- { 0xCB, 0x05 },
- { 0xCC, 0x00 },
- { 0xCD, 0x01 },
- { 0xCE, 0x02 },
- { 0xCF, 0x03 },
- { 0xD0, 0x04 },
- { 0xD6, 0x10 },
- { 0xD7, 0x0F },
- { 0xD8, 0x0E },
- { 0xD9, 0x0D },
- { 0xDA, 0x0C },
- { 0xDB, 0x0B },
- { 0xDC, 0x0A },
- { 0xDD, 0x09 },
- { 0xDE, 0x08 },
- { 0xDF, 0x07 },
- { 0xE0, 0x06 },
- { 0xE1, 0x05 },
- { 0xE2, 0x00 },
- { 0xE3, 0x01 },
- { 0xE4, 0x02 },
- { 0xE5, 0x03 },
- { 0xE6, 0x04 },
- { 0xE7, 0x00 },
- { 0xEC, 0xC0 },
+ _INIT_CMD(0xB0, 0x01),
+ _INIT_CMD(0xC0, 0x10),
+ _INIT_CMD(0xC1, 0x0F),
+ _INIT_CMD(0xC2, 0x0E),
+ _INIT_CMD(0xC3, 0x0D),
+ _INIT_CMD(0xC4, 0x0C),
+ _INIT_CMD(0xC5, 0x0B),
+ _INIT_CMD(0xC6, 0x0A),
+ _INIT_CMD(0xC7, 0x09),
+ _INIT_CMD(0xC8, 0x08),
+ _INIT_CMD(0xC9, 0x07),
+ _INIT_CMD(0xCA, 0x06),
+ _INIT_CMD(0xCB, 0x05),
+ _INIT_CMD(0xCC, 0x00),
+ _INIT_CMD(0xCD, 0x01),
+ _INIT_CMD(0xCE, 0x02),
+ _INIT_CMD(0xCF, 0x03),
+ _INIT_CMD(0xD0, 0x04),
+ _INIT_CMD(0xD6, 0x10),
+ _INIT_CMD(0xD7, 0x0F),
+ _INIT_CMD(0xD8, 0x0E),
+ _INIT_CMD(0xD9, 0x0D),
+ _INIT_CMD(0xDA, 0x0C),
+ _INIT_CMD(0xDB, 0x0B),
+ _INIT_CMD(0xDC, 0x0A),
+ _INIT_CMD(0xDD, 0x09),
+ _INIT_CMD(0xDE, 0x08),
+ _INIT_CMD(0xDF, 0x07),
+ _INIT_CMD(0xE0, 0x06),
+ _INIT_CMD(0xE1, 0x05),
+ _INIT_CMD(0xE2, 0x00),
+ _INIT_CMD(0xE3, 0x01),
+ _INIT_CMD(0xE4, 0x02),
+ _INIT_CMD(0xE5, 0x03),
+ _INIT_CMD(0xE6, 0x04),
+ _INIT_CMD(0xE7, 0x00),
+ _INIT_CMD(0xEC, 0xC0),
/* GOA timing setting */
- { 0xB0, 0x03 },
- { 0xC0, 0x01 },
- { 0xC2, 0x6F },
- { 0xC3, 0x6F },
- { 0xC5, 0x36 },
- { 0xC8, 0x08 },
- { 0xC9, 0x04 },
- { 0xCA, 0x41 },
- { 0xCC, 0x43 },
- { 0xCF, 0x60 },
- { 0xD2, 0x04 },
- { 0xD3, 0x04 },
- { 0xD4, 0x03 },
- { 0xD5, 0x02 },
- { 0xD6, 0x01 },
- { 0xD7, 0x00 },
- { 0xDB, 0x01 },
- { 0xDE, 0x36 },
- { 0xE6, 0x6F },
- { 0xE7, 0x6F },
+ _INIT_CMD(0xB0, 0x03),
+ _INIT_CMD(0xC0, 0x01),
+ _INIT_CMD(0xC2, 0x6F),
+ _INIT_CMD(0xC3, 0x6F),
+ _INIT_CMD(0xC5, 0x36),
+ _INIT_CMD(0xC8, 0x08),
+ _INIT_CMD(0xC9, 0x04),
+ _INIT_CMD(0xCA, 0x41),
+ _INIT_CMD(0xCC, 0x43),
+ _INIT_CMD(0xCF, 0x60),
+ _INIT_CMD(0xD2, 0x04),
+ _INIT_CMD(0xD3, 0x04),
+ _INIT_CMD(0xD4, 0x03),
+ _INIT_CMD(0xD5, 0x02),
+ _INIT_CMD(0xD6, 0x01),
+ _INIT_CMD(0xD7, 0x00),
+ _INIT_CMD(0xDB, 0x01),
+ _INIT_CMD(0xDE, 0x36),
+ _INIT_CMD(0xE6, 0x6F),
+ _INIT_CMD(0xE7, 0x6F),
/* GOE setting */
- { 0xB0, 0x06 },
- { 0xB8, 0xA5 },
- { 0xC0, 0xA5 },
- { 0xD5, 0x3F },
+ _INIT_CMD(0xB0, 0x06),
+ _INIT_CMD(0xB8, 0xA5),
+ _INIT_CMD(0xC0, 0xA5),
+ _INIT_CMD(0xD5, 0x3F),
+ {},
};
const struct mipi_panel_data kd097d04_panel = {
@@ -517,7 +518,6 @@
.display_on_udelay = 120000,
.video_mode_udelay = 5000,
.init_cmd = kd097d04_init_commands,
- .num_init_commands = ARRAY_SIZE(kd097d04_init_commands)
};
static const struct edid_mode kd097d04_edid_mode = {
diff --git a/src/soc/rockchip/rk3399/include/soc/mipi.h b/src/soc/rockchip/rk3399/include/soc/mipi.h
index 933ea89..286c60a 100644
--- a/src/soc/rockchip/rk3399/include/soc/mipi.h
+++ b/src/soc/rockchip/rk3399/include/soc/mipi.h
@@ -267,6 +267,10 @@
#define MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM 0x23
#define MIPI_DSI_DCS_LONG_WRITE 0x39
+#define _INIT_CMD(...) { \
+ .len = sizeof((char[]){__VA_ARGS__}), \
+ .data = {__VA_ARGS__} }
+
enum mipi_dsi_pixel_format {
MIPI_DSI_FMT_RGB888,
MIPI_DSI_FMT_RGB666,
@@ -324,8 +328,8 @@
};
struct panel_init_command {
- u8 cmd;
- u8 data;
+ int len;
+ char data[10];
};
struct mipi_panel_data {
@@ -334,7 +338,6 @@
u8 lanes;
u32 display_on_udelay;
u32 video_mode_udelay;
- u32 num_init_commands;
struct panel_init_command *init_cmd;
};
diff --git a/src/soc/rockchip/rk3399/mipi.c b/src/soc/rockchip/rk3399/mipi.c
index 825eb72..5e23b01 100644
--- a/src/soc/rockchip/rk3399/mipi.c
+++ b/src/soc/rockchip/rk3399/mipi.c
@@ -564,6 +564,21 @@
return -1;
}
+static int rk_mipi_dsi_check_write_full(struct rk_mipi_dsi *dsi)
+{
+ struct stopwatch sw;
+ int val;
+
+ stopwatch_init_msecs_expire(&sw, 20);
+ do {
+ val = read32(&dsi->mipi_regs->dsi_cmd_pkt_status);
+ if (!(val & GEN_PLD_W_FULL))
+ return 0;
+ } while (!stopwatch_expired(&sw));
+
+ return -1;
+}
+
static int rk_mipi_dsi_gen_pkt_hdr_write(struct rk_mipi_dsi *dsi, u32 hdr_val)
{
int val;
@@ -600,15 +615,68 @@
return rk_mipi_dsi_gen_pkt_hdr_write(dsi, val);
}
-static int rk_mipi_dsi_dci_cmd_arg(struct rk_mipi_dsi *dsi, u8 cmd, u8 arg)
+static int rk_mipi_dsi_dci_long_write(struct rk_mipi_dsi *dsi,
+ char *data, int len)
{
+ u32 remainder;
+ int ret = 0;
+
+ while (DIV_ROUND_UP(len, 4)) {
+ if (len < 4) {
+ remainder = 0;
+ memcpy(&remainder, data, len);
+ write32(&dsi->mipi_regs->dsi_gen_pld_data, remainder);
+ len = 0;
+ } else {
+ memcpy(&remainder, data, 4);
+ write32(&dsi->mipi_regs->dsi_gen_pld_data, remainder);
+ data += 4;
+ len -= 4;
+ }
+
+ ret = rk_mipi_dsi_check_write_full(dsi);
+ if (ret) {
+ printk(BIOS_ERR, "fail to write fifo alway full\n");
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
+static int rk_mipi_dsi_write(struct rk_mipi_dsi *dsi, char *data, int len)
+{
+ u16 buf = 0;
u32 val;
- u16 data;
+ int ret = 0;
rk_mipi_message_config(dsi);
- data = cmd | (arg << 8);
- val = GEN_HDATA(data) | GEN_HTYPE(MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM);
+ switch (len) {
+ case 0:
+ printk(BIOS_ERR, "not data!\n");
+ return -1;
+ case 1:
+ val = GEN_HDATA(*data) |
+ GEN_HTYPE(MIPI_DSI_DCS_SHORT_WRITE);
+ break;
+
+ case 2:
+ buf = *data++;
+ buf |= *data << 8;
+ val = GEN_HDATA(buf) |
+ GEN_HTYPE(MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM);
+ break;
+
+ default:
+ ret = rk_mipi_dsi_dci_long_write(dsi, data, len);
+ if (ret) {
+ printk(BIOS_ERR, "error happen when long write\n");
+ return ret;
+ }
+ val = GEN_HDATA(len) | GEN_HTYPE(MIPI_DSI_DCS_LONG_WRITE);
+ break;
+ }
return rk_mipi_dsi_gen_pkt_hdr_write(dsi, val);
}
@@ -642,6 +710,7 @@
const struct mipi_panel_data *panel_data)
{
int i, num;
+ struct panel_init_command *cmds;
for (i = 0; i < panel_data->mipi_num; i++) {
rk_mipi[i].lanes = panel_data->lanes / panel_data->mipi_num;
@@ -649,11 +718,22 @@
rk_mipi_enable(&rk_mipi[i], edid, panel_data);
}
- for (num = 0; num < panel_data->num_init_commands; num++) {
- for (i = 0; i < panel_data->mipi_num; i++)
- rk_mipi_dsi_dci_cmd_arg(&rk_mipi[i],
- panel_data->init_cmd[num].cmd,
- panel_data->init_cmd[num].data);
+ if (panel_data->init_cmd) {
+ cmds = panel_data->init_cmd;
+ for (num = 0; cmds[num].len != 0; num++) {
+ struct panel_init_command *cmd = &cmds[num];
+ for (i = 0; i < panel_data->mipi_num; i++) {
+ if (rk_mipi_dsi_write(&rk_mipi[i], cmd->data,
+ cmd->len))
+ return;
+
+ /* make sure panel pick up the command */
+ if (rk_mipi_dsi_dcs_cmd(&rk_mipi[i],
+ MIPI_DCS_NOP))
+ return;
+ }
+ }
+
}
for (i = 0; i < panel_data->mipi_num; i++) {
--
To view, visit https://review.coreboot.org/23299
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I212c14165e074c40a4a1a25140d9e8dfdfba465f
Gerrit-Change-Number: 23299
Gerrit-PatchSet: 1
Gerrit-Owner: Lin Huang <hl at rock-chips.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20180117/310847d6/attachment-0001.html>
More information about the coreboot-gerrit
mailing list