Attention is currently required from: Shelley Chen, Hung-Te Lin. Hello Hung-Te Lin, Shelley Chen,
I'd like you to do a code review. Please visit
https://review.coreboot.org/c/coreboot/+/56966
to review the following change.
Change subject: qualcomm/sc7180: Switch to common MIPI panel library ......................................................................
qualcomm/sc7180: Switch to common MIPI panel library
This patch changes the sc7180 boards to use the new common MIPI panel framework, which allows more flexible initialization command packing and sharing panel definitions between boards. (I'm taking the lane count control back out again for now, since it seems we only ever want 4 for now anyway, and if we ever have a need for a different lane count it's not clear whether that should be a property of the board or the panel or both. Better to leave that decision until we have a real use case.)
Signed-off-by: Julius Werner jwerner@chromium.org Change-Id: I78f6efbaa9da88a3574d5c6a51061e308412340e --- M src/device/mipi/Kconfig M src/device/mipi/Makefile.inc A src/device/mipi/panel-VIS_RM69299.c M src/mainboard/google/trogdor/Kconfig M src/mainboard/google/trogdor/Makefile.inc M src/mainboard/google/trogdor/mainboard.c M src/soc/qualcomm/sc7180/display/dsi.c M src/soc/qualcomm/sc7180/include/soc/display/mipi_dsi.h 8 files changed, 137 insertions(+), 91 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/66/56966/1
diff --git a/src/device/mipi/Kconfig b/src/device/mipi/Kconfig index 3e6f95d..72105e4 100644 --- a/src/device/mipi/Kconfig +++ b/src/device/mipi/Kconfig @@ -36,3 +36,5 @@ config MIPI_PANEL_STA_2081101QFH032011_53G bool
+config MIPI_PANEL_VIS_RM69299 + bool diff --git a/src/device/mipi/Makefile.inc b/src/device/mipi/Makefile.inc index cea7c3af..d58e838 100644 --- a/src/device/mipi/Makefile.inc +++ b/src/device/mipi/Makefile.inc @@ -20,6 +20,8 @@
panel-params-$(CONFIG_MIPI_PANEL_STA_2081101QFH032011_53G) += panel-STA_2081101QFH032011_53G
+panel-params-$(CONFIG_MIPI_PANEL_VIS_RM69299) += panel-VIS_RM69299 + $(foreach params,$(panel-params-y), \ $(eval cbfs-files-y += $(params)) \ $(eval $(params)-file := $(params).c:struct) \ diff --git a/src/device/mipi/panel-VIS_RM69299.c b/src/device/mipi/panel-VIS_RM69299.c new file mode 100644 index 0000000..5fdea60 --- /dev/null +++ b/src/device/mipi/panel-VIS_RM69299.c @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <device/mipi_panel.h> + +struct panel_serializable_data VIS_RM69299 = { + .edid = { + .ascii_string = "RM69299", + .manufacturer_name = "RM", + .panel_bits_per_color = 8, + .panel_bits_per_pixel = 24, + .mode = { + .pixel_clock = 158695, + .lvds_dual_channel = 0, + .refresh = 60, + .ha = 1080, .hbl = 64, .hso = 26, .hspw = 2, + .va = 2248, .vbl = 64, .vso = 56, .vspw = 4, + .phsync = '-', .pvsync = '-', + .x_mm = 74, .y_mm = 131, + }, + }, + .orientation = LB_FB_ORIENTATION_NORMAL, + .init = { + PANEL_DCS(0xFE, 0x00, 0x15, 0x80), + PANEL_DCS(0xc2, 0x08, 0x15, 0x80), + PANEL_DCS(0x35, 0x00, 0x15, 0x80), + PANEL_DCS(0x51, 0xff, 0x15, 0x80), + PANEL_DCS(0x11, 0x00, 0x05, 0x80), + PANEL_DELAY(150), + PANEL_DCS(0x29, 0x00, 0x05, 0x80), + PANEL_DELAY(50), + PANEL_END, + }, +}; diff --git a/src/mainboard/google/trogdor/Kconfig b/src/mainboard/google/trogdor/Kconfig index ad86a53..55829be 100644 --- a/src/mainboard/google/trogdor/Kconfig +++ b/src/mainboard/google/trogdor/Kconfig @@ -15,6 +15,7 @@ config TROGDOR_HAS_MIPI_PANEL bool default n + select MIPI_PANEL_VIS_RM69299
config TROGDOR_HAS_FINGERPRINT bool diff --git a/src/mainboard/google/trogdor/Makefile.inc b/src/mainboard/google/trogdor/Makefile.inc index f42e147..9a71ea5 100644 --- a/src/mainboard/google/trogdor/Makefile.inc +++ b/src/mainboard/google/trogdor/Makefile.inc @@ -15,7 +15,6 @@ romstage-y += chromeos.c
ramstage-y += mainboard.c -ramstage-y += panel_driver.c ifneq ($(CONFIG_BOARD_GOOGLE_BUBS),y) ramstage-y += reset.c endif diff --git a/src/mainboard/google/trogdor/mainboard.c b/src/mainboard/google/trogdor/mainboard.c index 96751fe..02a1f7d 100644 --- a/src/mainboard/google/trogdor/mainboard.c +++ b/src/mainboard/google/trogdor/mainboard.c @@ -1,11 +1,14 @@ /* SPDX-License-Identifier: GPL-2.0-only */
#include <bootmode.h> +#include <cbfs.h> #include <console/console.h> #include <delay.h> #include <device/device.h> #include <device/i2c_simple.h> +#include <device/mipi_panel.h> #include <drivers/ti/sn65dsi86bridge/sn65dsi86bridge.h> +#include <edid.h> #include <framebuffer_info.h> #include <soc/display/mipi_dsi.h> #include <soc/display/mdssreg.h> @@ -64,7 +67,7 @@ qupv3_se_fw_load_and_init(QUPV3_1_SE5, SE_PROTOCOL_I2C, MIXED); /* Codec I2C */ }
-static void configure_display(void) +static void power_on_bridge(void) { printk(BIOS_INFO, "%s: Bridge gpio init\n", __func__);
@@ -75,25 +78,38 @@ gpio_output(GPIO_EN_PP3300_DX_EDP, 1); }
-static enum cb_err display_init(struct edid *edid, const struct panel_data *pinfo) +static struct panel_serializable_data *get_mipi_panel(void) { - uint32_t dsi_bpp = 24; - uint32_t lanes = pinfo ? pinfo->lanes : 4; + const char *cbfs_filename = "panel-VIS_RM69299";
- if (mdss_dsi_config(edid, lanes, dsi_bpp)) - return CB_ERR; - if (CONFIG(TROGDOR_HAS_MIPI_PANEL)) { - if (mdss_dsi_panel_initialize(pinfo)) - return CB_ERR; - } else { - sn65dsi86_bridge_configure(BRIDGE_BUS, BRIDGE_CHIP, edid, lanes, dsi_bpp); + struct panel_serializable_data *panel = cbfs_map(cbfs_filename, NULL); + if (!panel) { + printk(BIOS_ERR, "Could not find panel data for %s!\n", cbfs_filename); + return NULL; }
- if (CONFIG(TROGDOR_HAS_BRIDGE_BACKLIGHT)) - sn65dsi86_backlight_enable(BRIDGE_BUS, BRIDGE_CHIP); + return panel; +}
- mdp_dsi_video_config(edid); - mdss_dsi_video_mode_config(edid, dsi_bpp); +static enum cb_err display_init(struct panel_serializable_data *panel) +{ + uint32_t dsi_bpp = 24; + uint32_t lanes = 4; + + if (mdss_dsi_config(&panel->edid, lanes, dsi_bpp)) + return CB_ERR; + if (CONFIG(TROGDOR_HAS_MIPI_PANEL)) { + if (mdss_dsi_panel_initialize(panel->init)) + return CB_ERR; + } else { + sn65dsi86_bridge_configure(BRIDGE_BUS, BRIDGE_CHIP, &panel->edid, + lanes, dsi_bpp); + if (CONFIG(TROGDOR_HAS_BRIDGE_BACKLIGHT)) + sn65dsi86_backlight_enable(BRIDGE_BUS, BRIDGE_CHIP); + } + + mdp_dsi_video_config(&panel->edid); + mdss_dsi_video_mode_config(&panel->edid, dsi_bpp); mdp_dsi_video_on();
return CB_SUCCESS; @@ -101,28 +117,37 @@
static void display_startup(void) { - static struct edid ed; - enum dp_pll_clk_src ref_clk = SN65_SEL_19MHZ; - const struct panel_data *pinfo = NULL; + struct panel_serializable_data *panel = NULL;
- if (display_init_required()) { - if (CONFIG(TROGDOR_HAS_MIPI_PANEL)) { - pinfo = get_panel_config(&ed); - } else { - i2c_init(QUPV3_0_SE2, I2C_SPEED_FAST); /* EDP Bridge I2C */ - configure_display(); - mdelay(250); /* Delay for the panel to be up */ - sn65dsi86_bridge_init(BRIDGE_BUS, BRIDGE_CHIP, ref_clk); - if (sn65dsi86_bridge_read_edid(BRIDGE_BUS, BRIDGE_CHIP, &ed) < 0) - return; - } - - printk(BIOS_INFO, "display init!\n"); - if (display_init(&ed, pinfo) == CB_SUCCESS) - fb_new_framebuffer_info_from_edid(&ed, (uintptr_t)0); - - } else + if (!display_init_required()) { printk(BIOS_INFO, "Skipping display init.\n"); + return; + } + + if (CONFIG(TROGDOR_HAS_MIPI_PANEL)) { + panel = get_mipi_panel(); + if (!panel) + return; + } else { + enum dp_pll_clk_src ref_clk = SN65_SEL_19MHZ; + static struct panel_serializable_data edp_panel = { + .orientation = LB_FB_ORIENTATION_NORMAL, + }; + i2c_init(QUPV3_0_SE2, I2C_SPEED_FAST); /* EDP Bridge I2C */ + power_on_bridge(); + mdelay(250); /* Delay for the panel to be up */ + sn65dsi86_bridge_init(BRIDGE_BUS, BRIDGE_CHIP, ref_clk); + if (sn65dsi86_bridge_read_edid(BRIDGE_BUS, BRIDGE_CHIP, &edp_panel.edid) < 0) + return; + panel = &edp_panel; + } + + printk(BIOS_INFO, "display init!\n"); + edid_set_framebuffer_bits_per_pixel(&panel->edid, 32, 0); + if (display_init(panel) == CB_SUCCESS) { + struct fb_info *info = fb_new_framebuffer_info_from_edid(&panel->edid, 0); + fb_set_orientation(info, panel->orientation); + } }
static void mainboard_init(struct device *dev) diff --git a/src/soc/qualcomm/sc7180/display/dsi.c b/src/soc/qualcomm/sc7180/display/dsi.c index 2682008..02db813 100644 --- a/src/soc/qualcomm/sc7180/display/dsi.c +++ b/src/soc/qualcomm/sc7180/display/dsi.c @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */
+#include <device/mipi_panel.h> #include <device/mmio.h> #include <console/console.h> #include <assert.h> @@ -9,7 +10,6 @@ #include <types.h> #include <string.h> #include <soc/display/mipi_dsi.h> -#include <soc/display/panel.h> #include <soc/display/mdssreg.h> #include <soc/display/dsi_phy.h>
@@ -210,57 +210,51 @@ return status; }
-static int mdss_dsi_cmds_tx(struct mipi_dsi_cmd *cmds, int count) +static cb_err_t mdss_dsi_send_init_cmd(enum panel_init_cmd cmd, const u8 *body, u8 len) { - struct mipi_dsi_cmd *cm; uint8_t *pload = _dma_coherent; uint32_t size; + cb_err_t ret; int data = 0; - int ret = 0; uint32_t *bp = NULL;
- cm = cmds; + /* The payload size has to be a multiple of 4 */ + memcpy(pload, body, len); + size = ALIGN_UP(len, DSI_PAYLOAD_SIZE_ALIGN); + memset(pload + len, 0, size - len); + assert(size < DSI_PAYLOAD_BYTE_BOUND);
- for (int i = 0; i < count; i++) { - /* The payload size has to be a multiple of 4 */ - size = ALIGN_UP(cm->size, DSI_PAYLOAD_SIZE_ALIGN); - assert(size < DSI_PAYLOAD_BYTE_BOUND); - memcpy(pload, (cm[i].payload), size); + bp = (uint32_t *)pload;
- bp = (uint32_t *)pload; + /* Enable custom pattern stored in TPG DMA FIFO */ + data = DSI_CMD_DMA_PATTERN_SEL;
- /* Enable custom pattern stored in TPG DMA FIFO */ - data = DSI_CMD_DMA_PATTERN_SEL; + /* select CMD_DMA_FIFO_MODE to 1 */ + data |= DSI_TPG_DMA_FIFO_MODE; + data |= DSI_CMD_DMA_TPG_EN;
- /* select CMD_DMA_FIFO_MODE to 1 */ - data |= DSI_TPG_DMA_FIFO_MODE; - data |= DSI_CMD_DMA_TPG_EN; - - write32(&dsi0->test_pattern_gen_ctrl, data); - for (int j = 0; j < size; j += 4) { - write32(&dsi0->test_pattern_gen_cmd_dma_init_val, *bp); - bp++; - } - - if ((size % 8) != 0) - write32(&dsi0->test_pattern_gen_cmd_dma_init_val, 0x0); - - write32(&dsi0->dma_cmd_length, size); - write32(&dsi0->cmd_mode_dma_sw_trigger, 0x1); - ret += mdss_dsi_cmd_dma_trigger_for_panel(); - - /* Reset the DMA TPG FIFO */ - write32(&dsi0->tpg_dma_fifo_reset, 0x1); - write32(&dsi0->tpg_dma_fifo_reset, 0x0); - - /* Disable CMD_DMA_TPG */ - write32(&dsi0->test_pattern_gen_ctrl, 0x0); - if (cm[i].delay_us) - udelay(cm[i].delay_us); - else - udelay(80); + write32(&dsi0->test_pattern_gen_ctrl, data); + for (int j = 0; j < size; j += 4) { + write32(&dsi0->test_pattern_gen_cmd_dma_init_val, *bp); + bp++; }
+ if ((size % 8) != 0) + write32(&dsi0->test_pattern_gen_cmd_dma_init_val, 0x0); + + write32(&dsi0->dma_cmd_length, size); + write32(&dsi0->cmd_mode_dma_sw_trigger, 0x1); + ret = mdss_dsi_cmd_dma_trigger_for_panel(); + + /* Reset the DMA TPG FIFO */ + write32(&dsi0->tpg_dma_fifo_reset, 0x1); + write32(&dsi0->tpg_dma_fifo_reset, 0x0); + + /* Disable CMD_DMA_TPG */ + write32(&dsi0->test_pattern_gen_ctrl, 0x0); + + udelay(80); + return ret; }
@@ -274,22 +268,19 @@ write32(&dsi0->err_int_mask0, 0x13FF3BFF); }
-int mdss_dsi_panel_initialize(const struct panel_data *pinfo) +cb_err_t mdss_dsi_panel_initialize(const u8 *init_cmds) { - int status = 0; uint32_t ctrl_mode = 0; - struct mipi_dsi_cmd *cmds;
- assert((pinfo != NULL) && (pinfo->init_cmd != NULL)); - cmds = pinfo->init_cmd; + assert(init_cmds != NULL); ctrl_mode = read32(&dsi0->ctrl);
/* Enable command mode before sending the commands */ write32(&dsi0->ctrl, ctrl_mode | 0x04);
- status = mdss_dsi_cmds_tx(cmds, pinfo->init_cmd_count); + cb_err_t ret = mipi_panel_parse_init_commands(init_cmds, mdss_dsi_send_init_cmd); write32(&dsi0->ctrl, ctrl_mode); mdss_dsi_clear_intr();
- return status; + return ret; } diff --git a/src/soc/qualcomm/sc7180/include/soc/display/mipi_dsi.h b/src/soc/qualcomm/sc7180/include/soc/display/mipi_dsi.h index 3b3dc51..a7c9b6e 100644 --- a/src/soc/qualcomm/sc7180/include/soc/display/mipi_dsi.h +++ b/src/soc/qualcomm/sc7180/include/soc/display/mipi_dsi.h @@ -3,7 +3,6 @@ #ifndef _SOC_DISPLAY_MIPI_DSI_H_ #define _SOC_DISPLAY_MIPI_DSI_H_
-#include <soc/display/panel.h> /********************************************************** DSI register configuration options **********************************************************/ @@ -15,12 +14,6 @@ #define DSI_VIDEO_DST_FORMAT_RGB666_LOOSE 2 #define DSI_VIDEO_DST_FORMAT_RGB888 3
-struct mipi_dsi_cmd { - char payload[4]; - uint32_t size; - int delay_us; -}; - enum { DSI_VIDEO_MODE, DSI_CMD_MODE, @@ -29,6 +22,6 @@ enum cb_err mdss_dsi_config(struct edid *edid, uint32_t num_of_lanes, uint32_t bpp); void mdss_dsi_clock_config(void); void mdss_dsi_video_mode_config(struct edid *edid, uint32_t bpp); -int mdss_dsi_panel_initialize(const struct panel_data *pinfo); +cb_err_t mdss_dsi_panel_initialize(const u8 *init_cmds);
#endif