jitao shi has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/32097
Change subject: WIP: mediaek/mt8183: add panel driver for kukui p2 ......................................................................
WIP: mediaek/mt8183: add panel driver for kukui p2
BUG=b:80501386,b:117254947 BRANCH=none TEST=build pass
Change-Id: I878c9e0454acdbc0cd2cd310b8519efb845bb6ee Signed-off-by: Jitao Shi jitao.shi@mediatek.com --- M src/mainboard/google/kukui/mainboard.c M src/soc/mediatek/mt8183/dsi.c 2 files changed, 222 insertions(+), 35 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/97/32097/1
diff --git a/src/mainboard/google/kukui/mainboard.c b/src/mainboard/google/kukui/mainboard.c index bf9bd02..541485a 100644 --- a/src/mainboard/google/kukui/mainboard.c +++ b/src/mainboard/google/kukui/mainboard.c @@ -13,6 +13,7 @@ * GNU General Public License for more details. */
+#include <boardid.h> #include <bootmode.h> #include <console/console.h> #include <delay.h> @@ -55,11 +56,72 @@
static void configure_display(void) { - /* board from p0 */ - gpio_output(GPIO(LCM_RST), 0); - udelay(100); - gpio_output(GPIO(LCM_RST), 1); - mdelay(20); + + printk(BIOS_ERR, "board_id() = %d\n", board_id()); + + if (board_id() < 2) { + /* board from p1 */ + gpio_output(GPIO(LCM_RST), 0); + udelay(100); + gpio_output(GPIO(LCM_RST), 1); + mdelay(20); + } else { + /* board from p2 */ + printk(BIOS_ERR, "board from p2\n"); + + gpio_output(GPIO(LCM_RST), 0); + gpio_output(GPIO(BPI_BUS3), 0); + gpio_output(GPIO(MISC_BSI_CK_3), 0); + gpio_output(GPIO(PERIPHERAL_EN9), 0); + gpio_output(GPIO(SIM2_SRST), 0); + gpio_output(GPIO(SIM2_SIO), 0); + gpio_output(GPIO(BPI_OLAT1), 0); + gpio_output(GPIO(SIM2_SCLK), 0); + gpio_set_pull(GPIO(LCM_RST), GPIO_PULL_ENABLE, GPIO_PULL_UP); + gpio_set_pull(GPIO(BPI_BUS3), GPIO_PULL_ENABLE, GPIO_PULL_UP); + gpio_set_pull(GPIO(MISC_BSI_CK_3), GPIO_PULL_ENABLE, GPIO_PULL_UP); + gpio_set_pull(GPIO(PERIPHERAL_EN9), GPIO_PULL_ENABLE, GPIO_PULL_UP); + gpio_set_pull(GPIO(SIM2_SRST), GPIO_PULL_ENABLE, GPIO_PULL_UP); + gpio_set_pull(GPIO(SIM2_SIO), GPIO_PULL_ENABLE, GPIO_PULL_UP); + gpio_set_pull(GPIO(BPI_OLAT1), GPIO_PULL_ENABLE, GPIO_PULL_UP); + gpio_set_pull(GPIO(SIM2_SCLK), GPIO_PULL_ENABLE, GPIO_PULL_UP); + + mdelay(20); + mdelay(20); + mdelay(20); + mdelay(20); + mdelay(20); + mdelay(20); + mdelay(20); + mdelay(20); + mdelay(20); + + gpio_output(GPIO(MISC_BSI_CK_3), 1); + gpio_output(GPIO(PERIPHERAL_EN9), 1); + gpio_output(GPIO(SIM2_SRST), 1); + gpio_output(GPIO(SIM2_SIO), 1); + gpio_output(GPIO(BPI_OLAT1), 1); + gpio_output(GPIO(SIM2_SCLK), 1); + + mdelay(20); + mdelay(20); + mdelay(20); + mdelay(20); + mdelay(20); + gpio_output(GPIO(LCM_RST), 1); + mdelay(20); + gpio_output(GPIO(BPI_BUS3), 1); + mdelay(20); + mdelay(20); + + printk(BIOS_ERR, "aaadump_gpio_reg : reg[ox350] = 0x%x\n", read32((void *)GPIO_BASE + 0x350)); + printk(BIOS_ERR, "aaadump_gpio_reg : reg[ox10] = 0x%x\n", read32((void *)GPIO_BASE + 0x10)); + printk(BIOS_ERR, "aaadump_gpio_reg : reg[ox110] = 0x%x\n", read32((void *)GPIO_BASE + 0x110)); + + printk(BIOS_ERR, "aaadump_gpio_reg : reg[ox390] = 0x%x\n", read32((void *)GPIO_BASE + 0x390)); + printk(BIOS_ERR, "aaadump_gpio_reg : reg[ox20] = 0x%x\n", read32((void *)GPIO_BASE + 0x20)); + printk(BIOS_ERR, "aaadump_gpio_reg : reg[ox120] = 0x%x\n", read32((void *)GPIO_BASE + 0x120)); + } }
static const struct edid kukui_innolux_edid = { @@ -84,6 +146,76 @@ {DELAY_CMD, 120, {}}, };
+static const struct edid kukui_p097pfg_ssd2858_edid = { + .panel_bits_per_color = 8, + .panel_bits_per_pixel = 24, + .mode = { + .name = "1536x2048@60Hz", + .pixel_clock = 229000, + .lvds_dual_channel = 0, + .refresh = 60, + .ha = 1536, .hbl = 160, .hso = 80, .hspw = 26, .hborder = 0, + .va = 2048, .vbl = 32, .vso = 20, .vspw = 2, .vborder = 0, + .phsync = '-', .pvsync = '-', + .x_mm = 147, .y_mm = 196, + }, +}; + +struct lcm_init_table lcm_p097pfg_ssd2858_init_cmd[] = { + /* SSD2858 config */ + {INIT_CMD, 2, {0xff, 0x00}}, + /* LOCKCNT=0x1f4, MRX=0, POSTDIV=1 (/2}}, MULT=0x49 + * 27 Mhz => 985.5 Mhz */ + {INIT_CMD, 6, {0x00, 0x08, 0x01, 0xf4, 0x01, 0x49}}, + /* MTXDIV=1, SYSDIV=3 (=> 4) */ + {INIT_CMD, 6, {0x00, 0x0c, 0x00, 0x00, 0x00, 0x03}}, + /* MTXVPF=24bpp, MRXLS=4 lanes, MRXVB=bypass, MRXECC=1, MRXEOT=1 + * MRXEE=1 */ + {INIT_CMD, 6, {0x00, 0x14, 0x0c, 0x3d, 0x80, 0x0f}}, + {INIT_CMD, 6, {0x00, 0x20, 0x15, 0x92, 0x56, 0x7d}}, + {INIT_CMD, 6, {0x00, 0x24, 0x00, 0x00, 0x30, 0x00}}, + +// {INIT_CMD, 1, {0x11}}, +// {DELAY_CMD, 120, {}}, + + {INIT_CMD, 6, {0x10, 0x08, 0x01, 0x20, 0x04, 0x45}}, + {INIT_CMD, 6, {0x10, 0x1c, 0x00, 0x00, 0x00, 0x00}}, + {INIT_CMD, 6, {0x20, 0x0c, 0x00, 0x00, 0x00, 0x04}}, + /* Pixel clock 985.5 Mhz * 0x49/0x4b = 959 Mhz */ + {INIT_CMD, 6, {0x20, 0x10, 0x00, 0x4b, 0x00, 0x49}}, + {INIT_CMD, 6, {0x20, 0xa0, 0x00, 0x00, 0x00, 0x00}}, + /* EOT=1, LPE = 0, LSOUT=4 lanes, LPD=25 */ + {INIT_CMD, 6, {0x60, 0x08, 0x00, 0xd9, 0x00, 0x08}}, + {INIT_CMD, 6, {0x60, 0x14, 0x01, 0x00, 0x01, 0x06}}, + /* DSI0 enable (default: probably not needed) */ + {INIT_CMD, 6, {0x60, 0x80, 0x00, 0x00, 0x00, 0x0f}}, + /* DSI1 enable */ + {INIT_CMD, 6, {0x60, 0xa0, 0x00, 0x00, 0x00, 0x0f}}, + + /* HSA=0x18, VSA=0x02, HBP=0x50, VBP=0x0c */ + {INIT_CMD, 6, {0x60, 0x0c, 0x0c, 0x50, 0x02, 0x18}}, + /* VACT= 0x800 (2048}}, VFP= 0x14, HFP=0x50 */ + {INIT_CMD, 6, {0x60, 0x10, 0x08, 0x00, 0x14, 0x50}}, + /* HACT=0x300 (768) */ + {INIT_CMD, 6, {0x60, 0x84, 0x00, 0x00, 0x03, 0x00}}, + {INIT_CMD, 6, {0x60, 0xa4, 0x00, 0x00, 0x03, 0x00}}, + + /* Take panel out of sleep. */ + {INIT_CMD, 2, {0xff, 0x01}}, + {INIT_CMD, 1, {0x11}}, + {DELAY_CMD, 120, {}}, + {INIT_CMD, 1, {0x29}}, + {DELAY_CMD, 20, {}}, + {INIT_CMD, 2, {0xff, 0x00}}, + + //{INIT_CMD, 6, {0x60, 0x14, 0x41, 0x00, 0x81, 0x02}}, + //{INIT_CMD, 6, {0x60, 0x14, 0xc1, 0x00, 0x81, 0x0A}}, + {DELAY_CMD, 120, {}}, + {INIT_CMD, 1, {0x11}}, + {DELAY_CMD, 120, {}}, + {INIT_CMD, 1, {0x29}}, + {DELAY_CMD, 20, {}}, +};
static void display_startup(void) { @@ -91,16 +223,30 @@ u32 mipi_dsi_flags; struct edid edid;
- edid = kukui_innolux_edid; - mipi_dsi_flags = MIPI_DSI_MODE_VIDEO | - MIPI_DSI_MODE_VIDEO_SYNC_PULSE | - MIPI_DSI_MODE_LPM; + if (board_id() < 2) { + edid = kukui_innolux_edid; + mipi_dsi_flags = MIPI_DSI_MODE_VIDEO | + MIPI_DSI_MODE_VIDEO_SYNC_PULSE | + MIPI_DSI_MODE_LPM; + } else { + edid = kukui_p097pfg_ssd2858_edid; + mipi_dsi_flags = MIPI_DSI_MODE_VIDEO | + MIPI_DSI_MODE_VIDEO_BURST | + MIPI_DSI_MODE_LPM; + }
edid_set_framebuffer_bits_per_pixel(&edid, 32, 0);
mtk_ddp_init(); - ret = mtk_dsi_init(mipi_dsi_flags, MIPI_DSI_FMT_RGB888, 4, - false, &edid, lcm_init_cmd, sizeof(lcm_init_cmd) / sizeof(struct lcm_init_table)); + if (board_id() < 2) + ret = mtk_dsi_init(mipi_dsi_flags, MIPI_DSI_FMT_RGB888, 4, + false, &edid, lcm_init_cmd, sizeof(lcm_init_cmd) / sizeof(struct lcm_init_table)); + else { + ret = mtk_dsi_init(mipi_dsi_flags, MIPI_DSI_FMT_RGB888, 4, + false, &edid, lcm_p097pfg_ssd2858_init_cmd, sizeof(lcm_p097pfg_ssd2858_init_cmd) / sizeof(struct lcm_init_table)); + printk(BIOS_ERR, "mtk_dsi_init from p2\n"); + } + if (ret < 0) { printk(BIOS_ERR, "dsi init fail\n"); return; diff --git a/src/soc/mediatek/mt8183/dsi.c b/src/soc/mediatek/mt8183/dsi.c index f96d847..316d92d 100644 --- a/src/soc/mediatek/mt8183/dsi.c +++ b/src/soc/mediatek/mt8183/dsi.c @@ -14,6 +14,7 @@ */
#include <arch/io.h> +#include <boardid.h> #include <console/console.h> #include <delay.h> #include <soc/addressmap.h> @@ -97,6 +98,11 @@
printk(BIOS_ERR, "data_rate: %u bps\n", data_rate);
+ if (board_id() == 2) + data_rate = 1420000000; + + printk(BIOS_ERR, "board_id() == 2 data_rate: %u bps\n", data_rate); + if (data_rate >= 2000000000) { txdiv = 1; txdiv0 = 0; @@ -169,26 +175,28 @@ timcon3 = phy_timing->clk_hs_prepare | phy_timing->clk_hs_post << 8 | phy_timing->clk_hs_exit << 16;
- dsi_write32(&dsi->dsi_phy_timecon0, timcon0); - dsi_write32(&dsi->dsi_phy_timecon1, timcon1); - dsi_write32(&dsi->dsi_phy_timecon2, timcon2); - dsi_write32(&dsi->dsi_phy_timecon3, timcon3); + if (board_id() < 2) { + dsi_write32(&dsi->dsi_phy_timecon0, timcon0); + dsi_write32(&dsi->dsi_phy_timecon1, timcon1); + dsi_write32(&dsi->dsi_phy_timecon2, timcon2); + dsi_write32(&dsi->dsi_phy_timecon3, timcon3); + } else { + dsi_write32(&dsi->dsi_phy_timecon0, 0x0e1c070d); + dsi_write32(&dsi->dsi_phy_timecon1, 0x1a411334); + dsi_write32(&dsi->dsi_phy_timecon2, 0x11420100); + dsi_write32(&dsi->dsi_phy_timecon3, 0x001a180a); + } }
static void mtk_dsi_reset(void) { - dsi_setbits_le32(&dsi->dsi_con_ctrl, 3); - dsi_clrbits_le32(&dsi->dsi_con_ctrl, 1); + dsi_write32(&dsi->dsi_con_ctrl, 1); + dsi_write32(&dsi->dsi_con_ctrl, 0); }
static void mtk_dsi_clk_hs_mode_enable(void) { - dsi_setbits_le32(&dsi->dsi_phy_lccon, LC_HS_TX_EN); -} - -static void mtk_dsi_clk_hs_mode_disable(void) -{ - dsi_clrbits_le32(&dsi->dsi_phy_lccon, LC_HS_TX_EN); + dsi_setbits_le32(&dsi->dsi_phy_lccon, 1); }
static void mtk_dsi_set_mode(u32 mode_flags) @@ -312,7 +320,7 @@ edid->mode.hborder) * bpp - 10; else hbp_byte = (edid->mode.hbl - edid->mode.hso - - edid->mode.hborder) * bpp - 10; + edid->mode.hborder) * bpp - 8;
hsync_active_byte = edid->mode.hspw * bpp - 10; hfp_byte = (edid->mode.hso - edid->mode.hborder) * bpp - 12; @@ -348,8 +356,8 @@
static void mtk_dsi_start(void) { - dsi_write32(&dsi->dsi_start, 0); - dsi_write32(&dsi->dsi_start, 1); + dsi_clrbits_le32(&dsi->dsi_start, 1); + dsi_setbits_le32(&dsi->dsi_start, 1); }
static void mtk_dsi_cmdq(u8 *data, u8 len) @@ -359,6 +367,15 @@ u8 cmdq_size; u32 reg_val, cmdq_mask, i, config, cmdq_off, type, intsta_0;
+ + while(read32(&dsi->dsi_intsta) & (1 << 31)) { + printk(BIOS_ERR, "mtk_dsi_cmdq wait dsi no busy\n"); + mdelay(20); + } + + printk(BIOS_ERR, "mtk_dsi_cmdq dsi no busy\n"); + dsi_write32(&dsi->dsi_intsta, 0); + switch (len) { case 0: return; @@ -393,14 +410,17 @@ reg_val = (type << 8) | config; }
- for (i = 0; i < len; i++) - dsi_clrsetbits_le32(&dsi->dsi_cmdq0 + ((cmdq_off + i) & (~0x3)), + for (i = 0; i < 0x20; i = i + 4) + dsi_write32((void *)DSI_BASE + 0x200 + i, 0); + + for (i = 0; i < len; i++) { + dsi_clrsetbits_le32((void *)DSI_BASE + 0x200 + ((cmdq_off + i) & (0xfffffffc)), (0xff << (((i + cmdq_off) & 3) * 8)), tx_buf[i] << (((i + cmdq_off) & 3) * 8)); + }
dsi_clrsetbits_le32(&dsi->dsi_cmdq0, cmdq_mask, reg_val); dsi_clrsetbits_le32(&dsi->dsi_cmdq_size, CMDQ_SIZE, cmdq_size); - dsi_write32(&dsi->dsi_intsta, 0); mtk_dsi_start();
stopwatch_init_usecs_expire(&sw, 400); @@ -414,7 +434,12 @@ if (!(intsta_0 & CMD_DONE_INT_FLAG)) printk(BIOS_ERR, "dsi DONE INT Timeout\n");
- dsi_write32(&dsi->dsi_start, 0); + for (i = 0x200; i < 0x210; i = i + 4) + printk(BIOS_ERR, "dump_dsi_reg : reg[0x%x] = 0x%x\n", i, read32((void *)DSI_BASE + i)); + + printk(BIOS_ERR, "xxxdump_dsi_reg : reg[0x60] = 0x%x\n", read32((void *)DSI_BASE + 0x60)); + printk(BIOS_ERR, "xxxdump_dsi_reg : reg[0x00] = 0x%x\n", read32((void *)DSI_BASE)); + printk(BIOS_ERR, "xxxdump_dsi_reg : reg[0x14] = 0x%x\n", read32((void *)DSI_BASE + 0x14)); }
static void push_table(struct lcm_init_table *init_cmd, u32 count) @@ -426,7 +451,17 @@
switch (cmd) { case DELAY_CMD: - mdelay(init_cmd[i].cmd); + if (init_cmd[i].cmd > 20) { + mdelay(20); + mdelay(20); + mdelay(20); + mdelay(20); + mdelay(20); + mdelay(20); + } else { + mdelay(20); + } + printk(BIOS_ERR, "delay : init_cmd[%d].len = 0x%x\n", i, init_cmd[i].len); break;
case END_OF_TABLE: @@ -434,6 +469,7 @@
case INIT_CMD: default: + printk(BIOS_ERR, "init_cmd : init_cmd[%d].data[0] = 0x%x\n", i, init_cmd[i].data[0]); mtk_dsi_cmdq(init_cmd[i].data, init_cmd[i].len); break; } @@ -443,7 +479,7 @@ int mtk_dsi_init(u32 mode_flags, u32 format, u32 lanes, bool dual, const struct edid *edid, struct lcm_init_table *init_cmd, u32 count) { - int data_rate; + int data_rate, i; struct mtk_phy_timing phy_timing;
mtk_dsi_phy_timing_calc(format, lanes, edid, &phy_timing); @@ -453,18 +489,23 @@ if (data_rate < 0) return -1;
- mtk_dsi_reset(); dsi_write32(&dsi->dsi_force_commit, 3); + mtk_dsi_reset(); mtk_dsi_phy_timconfig(data_rate, &phy_timing); mtk_dsi_rxtx_control(mode_flags, lanes); - mtk_dsi_clk_hs_mode_disable(); mtk_dsi_config_vdo_timing(mode_flags, format, edid); mtk_dsi_clk_hs_mode_enable(); - mtk_dsi_set_mode(0); push_table(init_cmd, count); mtk_dsi_set_mode(mode_flags); mtk_dsi_start();
+ dsi_write32((void *)DSI_BASE + 0x178, 0x00ff0000); + dsi_write32((void *)DSI_BASE + 0x17c, 0x00200040); + + for (i = 0; i < 0x208; i = i + 4) { + printk(BIOS_ERR, "dump_dsi_reg : reg[ox%x] = 0x%x\n", i, read32((void *)DSI_BASE + i)); + } + return 0; }