summaryrefslogtreecommitdiff
path: root/src/soc
diff options
context:
space:
mode:
authorVinod Polimera <vpolimer@codeaurora.org>2021-03-16 18:37:40 +0530
committerJulius Werner <jwerner@chromium.org>2021-08-03 21:22:26 +0000
commite8cd480046b2f8660c52d5503d5cc0cd4a5cd002 (patch)
treea736c1e6fe9c69b11a90c2be2fc53c737e82c05d /src/soc
parent8ca68cf2ae8d172c237cf05d37f2b5c5a2775f9f (diff)
sc7180: Add display support for mipi panels
- configure TROGDOR_HAS_MIPI_PANEL to "n" by default, it can be updated for mipi panels. - add simple rm69299 panel as an example to append new mipi panels. - use existing edid struct to update mipi panel parameters. - add dsi command tx interface for mipi panel on commands. Change-Id: Id698265a4e2399ad1c26e026e9a5f8ecd305467f Signed-off-by: Vinod Polimera <vpolimer@codeaurora.org> Signed-off-by: Julius Werner <jwerner@chromium.org> Reviewed-on: https://review.coreboot.org/c/coreboot/+/52662 Reviewed-by: Shelley Chen <shchen@google.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/soc')
-rw-r--r--src/soc/qualcomm/sc7180/display/dsi.c152
-rw-r--r--src/soc/qualcomm/sc7180/include/soc/display/mipi_dsi.h11
-rw-r--r--src/soc/qualcomm/sc7180/include/soc/display/panel.h17
3 files changed, 169 insertions, 11 deletions
diff --git a/src/soc/qualcomm/sc7180/display/dsi.c b/src/soc/qualcomm/sc7180/display/dsi.c
index 016531bda3..268200809a 100644
--- a/src/soc/qualcomm/sc7180/display/dsi.c
+++ b/src/soc/qualcomm/sc7180/display/dsi.c
@@ -2,10 +2,15 @@
#include <device/mmio.h>
#include <console/console.h>
+#include <assert.h>
#include <edid.h>
+#include <delay.h>
+#include <symbols.h>
#include <types.h>
-#include <soc/display/mdssreg.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>
#define DSI_DMA_STREAM1 0x0
@@ -17,6 +22,7 @@
#define DSI_WC1 0x0
#define DSI_EOF_BLLP_PWR 0x9
#define DSI_DMA_TRIGGER_SEL 0x4
+#define TRAFFIC_MODE 0x1
#define DSI_EN 0x1
#define DSI_CLKLN_EN 0x1
@@ -24,6 +30,11 @@
#define HS_TX_TO 0xEA60
#define TIMER_RESOLUTION 0x4
+#define DSI_PAYLOAD_BYTE_BOUND 8
+#define DSI_PAYLOAD_SIZE_ALIGN 4
+#define DSI_CMD_DMA_TPG_EN BIT(1)
+#define DSI_TPG_DMA_FIFO_MODE BIT(2)
+#define DSI_CMD_DMA_PATTERN_SEL (BIT(16) | BIT(17))
static void mdss_dsi_host_init(int num_of_lanes)
{
@@ -55,11 +66,13 @@ static void mdss_dsi_host_init(int num_of_lanes)
*/
ctrl_mode |= BIT(1);
+ mdss_dsi_clock_config();
write32(&dsi0->trig_ctrl, DSI_DMA_STREAM1 << 8 | DSI_DMA_TRIGGER_SEL);
write32(&dsi0->ctrl, dlnx_en << 4 | ctrl_mode);
write32(&dsi0->cmd_mode_dma_ctrl,
- DSI_EMBED_MODE1 << 28 | DSI_POWER_MODE2 << 26 |
- DSI_PACK_TYPE1 << 24 | DSI_VC1 << 22 | DSI_DT1 << 16 | DSI_WC1);
+ DSI_EMBED_MODE1 << 28 | DSI_POWER_MODE2 << 26 |
+ DSI_PACK_TYPE1 << 24 | DSI_VC1 << 22 | DSI_DT1 << 16 | DSI_WC1);
+ write32(&dsi0->eot_packet_ctrl, 0x1);
}
static void mdss_dsi_reset(void)
@@ -106,8 +119,6 @@ void mdss_dsi_video_mode_config(struct edid *edid, uint32_t bpp)
vfp = edid->mode.vso;
vbp = edid->mode.vbl - edid->mode.vso;
- mdss_dsi_clock_config();
-
write32(&dsi0->video_mode_active_h,
((edid->mode.ha + hbp) << 16) |
hbp);
@@ -121,12 +132,12 @@ void mdss_dsi_video_mode_config(struct edid *edid, uint32_t bpp)
(edid->mode.ha + hfp +
hbp - 1));
- write32(&dsi0->video_mode_active_hsync, (edid->mode.hspw << 16) | 0);
+ write32(&dsi0->video_mode_active_hsync, (edid->mode.hspw << 16));
write32(&dsi0->video_mode_active_vsync, 0x0);
- write32(&dsi0->video_mode_active_vsync_vpos, edid->mode.vspw << 16 | 0);
+ write32(&dsi0->video_mode_active_vsync_vpos, edid->mode.vspw << 16);
write32(&dsi0->video_mode_ctrl,
- DSI_EOF_BLLP_PWR << 12 | dst_format << 4);
+ DSI_EOF_BLLP_PWR << 12 | dst_format << 4 | TRAFFIC_MODE << 8);
write32(&dsi0->hs_timer_ctrl, HS_TX_TO | TIMER_RESOLUTION << 16);
@@ -153,9 +164,132 @@ void mdss_dsi_clock_config(void)
setbits32(&dsi0->clk_ctrl, DSI_AHBM_SCLK_ON | DSI_FORCE_ON_DYN_AHBM_HCLK);
/* Clock for MDP/DSI, for DMA out from MDP */
- setbits32(&dsi0->clk_ctrl, DSI_FORCE_ON_DYN_AHBM_HCLK);
+ setbits32(&dsi0->clk_ctrl, DSI_PCLK_ON);
/* Clock for rest of DSI */
setbits32(&dsi0->clk_ctrl, DSI_AHBS_HCLK_ON | DSI_DSICLK_ON |
DSI_BYTECLK_ON | DSI_ESCCLK_ON);
}
+
+static void mdss_dsi_set_intr(void)
+{
+ write32(&dsi0->int_ctrl, 0x0);
+
+ /* Enable all HW interrupts. */
+ setbits32(&dsi0->int_ctrl, DSI_CMD_MODE_DMA_DONE_MASK | DSI_CMD_MODE_MDP_DONE_MASK |
+ DSI_VIDEO_MODE_DONE_MASK | DSI_ERROR_MASK | DSI_BTA_DONE_MASK);
+}
+
+static int mdss_dsi_cmd_dma_trigger_for_panel(void)
+{
+ uint32_t read_value;
+ uint32_t count = 0;
+ int status = 0;
+
+ mdss_dsi_set_intr();
+ write32(&dsi0->cmd_mode_dma_sw_trigger, 0x1);
+ dsb();
+
+ read_value = read32(&dsi0->int_ctrl) & 0x1;
+
+ while (read_value != 0x1) {
+ read_value = read32(&dsi0->int_ctrl) & 0x1;
+ count++;
+ if (count > 0xffff) {
+ status = -1;
+ printk(BIOS_ERR,
+ "Panel CMD: count :%d command mode dma test failed\n", count);
+ printk(BIOS_ERR,
+ "Panel CMD: read value = %x, addr=%p\n",
+ read_value, (&dsi0->int_ctrl));
+ return status;
+ }
+ }
+
+ write32(&dsi0->int_ctrl, (read32(&dsi0->int_ctrl) | 0x01000001));
+ return status;
+}
+
+static int mdss_dsi_cmds_tx(struct mipi_dsi_cmd *cmds, int count)
+{
+ struct mipi_dsi_cmd *cm;
+ uint8_t *pload = _dma_coherent;
+ uint32_t size;
+ int data = 0;
+ int ret = 0;
+ uint32_t *bp = NULL;
+
+ cm = cmds;
+
+ 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;
+
+ /* 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;
+
+ 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);
+ }
+
+ return ret;
+}
+
+static void mdss_dsi_clear_intr(void)
+{
+ write32(&dsi0->int_ctrl, 0x0);
+
+ /* Clear all the hardware interrupts */
+ setbits32(&dsi0->int_ctrl, DSI_CMD_MODE_DMA_DONE_AK | DSI_CMD_MODE_MDP_DONE_AK |
+ DSI_VIDEO_MODE_DONE_AK | DSI_BTA_DONE_AK | DSI_ERROR_AK);
+ write32(&dsi0->err_int_mask0, 0x13FF3BFF);
+}
+
+int mdss_dsi_panel_initialize(const struct panel_data *pinfo)
+{
+ int status = 0;
+ uint32_t ctrl_mode = 0;
+ struct mipi_dsi_cmd *cmds;
+
+ assert((pinfo != NULL) && (pinfo->init_cmd != NULL));
+ cmds = pinfo->init_cmd;
+ 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);
+ write32(&dsi0->ctrl, ctrl_mode);
+ mdss_dsi_clear_intr();
+
+ return status;
+}
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 47fd3084c6..3b3dc513ab 100644
--- a/src/soc/qualcomm/sc7180/include/soc/display/mipi_dsi.h
+++ b/src/soc/qualcomm/sc7180/include/soc/display/mipi_dsi.h
@@ -3,6 +3,7 @@
#ifndef _SOC_DISPLAY_MIPI_DSI_H_
#define _SOC_DISPLAY_MIPI_DSI_H_
+#include <soc/display/panel.h>
/**********************************************************
DSI register configuration options
**********************************************************/
@@ -14,6 +15,12 @@
#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,
@@ -21,7 +28,7 @@ enum {
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);
+void mdss_dsi_video_mode_config(struct edid *edid, uint32_t bpp);
+int mdss_dsi_panel_initialize(const struct panel_data *pinfo);
#endif
diff --git a/src/soc/qualcomm/sc7180/include/soc/display/panel.h b/src/soc/qualcomm/sc7180/include/soc/display/panel.h
new file mode 100644
index 0000000000..04a7a6ab06
--- /dev/null
+++ b/src/soc/qualcomm/sc7180/include/soc/display/panel.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _PANEL_H_
+#define _PANEL_H_
+
+#include <types.h>
+
+struct panel_data {
+ uint8_t lanes;
+ struct mipi_dsi_cmd *init_cmd;
+ uint32_t init_cmd_count;
+};
+
+void panel_power_on(void);
+const struct panel_data *get_panel_config(struct edid *edid);
+
+#endif /*_PANEL_H_ */