DO NOT SUBMIT. Estelle display driver.
Change-Id: I5f41d0fb144fb6d404680f09aece4e2e47d15a0e
diff --git a/system/dev/board/astro/astro-display.c b/system/dev/board/astro/astro-display.c
index e334f5b..eb64f7a 100644
--- a/system/dev/board/astro/astro-display.c
+++ b/system/dev/board/astro/astro-display.c
@@ -16,9 +16,30 @@
static const pbus_mmio_t display_mmios[] = {
{
+ // Canvas
.base = S905D2_DMC_BASE,
.length = S905D2_DMC_LENGTH,
},
+ {
+ // DSI Host Controller
+ .base = S905D2_MIPI_DSI_BASE,
+ .length = S905D2_MIPI_DSI_LENGTH,
+ },
+ {
+ // DSI PHY
+ .base = S905D2_DSI_PHY_BASE,
+ .length = S905D2_DSI_PHY_LENGTH,
+ },
+ {
+ // HHI
+ .base = S905D2_HIU_BASE,
+ .length = S905D2_HIU_LENGTH,
+ },
+ {
+ // VBUS/VPU
+ .base = S905D2_VPU_BASE,
+ .length = S905D2_VPU_LENGTH,
+ },
};
static const pbus_irq_t display_irqs[] = {
diff --git a/system/dev/display/astro-display/aml_dsi.h b/system/dev/display/astro-display/aml_dsi.h
new file mode 100644
index 0000000..3811e53
--- /dev/null
+++ b/system/dev/display/astro-display/aml_dsi.h
@@ -0,0 +1,864 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#pragma once
+
+/* TOP MIPI_DSI AML Registers */
+#define MIPI_DSI_TOP_SW_RESET (0xF0 << 2)
+#define MIPI_DSI_TOP_CLK_CNTL (0xF1 << 2)
+#define MIPI_DSI_TOP_CNTL (0xF2 << 2)
+#define MIPI_DSI_TOP_SUSPEND_CNTL (0xF3 << 2)
+#define MIPI_DSI_TOP_SUSPEND_LINE (0xF4 << 2)
+#define MIPI_DSI_TOP_SUSPEND_PIX (0xF5 << 2)
+#define MIPI_DSI_TOP_MEAS_CNTL (0xF6 << 2)
+#define MIPI_DSI_TOP_STAT (0xF7 << 2)
+#define MIPI_DSI_TOP_MEAS_STAT_TE0 (0xF8 << 2)
+#define MIPI_DSI_TOP_MEAS_STAT_TE1 (0xF9 << 2)
+#define MIPI_DSI_TOP_MEAS_STAT_VS0 (0xFA << 2)
+#define MIPI_DSI_TOP_MEAS_STAT_VS1 (0xFB << 2)
+#define MIPI_DSI_TOP_INTR_CNTL_STAT (0xFC << 2)
+#define MIPI_DSI_TOP_MEM_PD (0xFD << 2)
+
+#define MIPI_DSI_PHY_CTRL (0x000 << 2)
+#define MIPI_DSI_CHAN_CTRL (0x001 << 2)
+#define MIPI_DSI_CHAN_STS (0x002 << 2)
+#define MIPI_DSI_CLK_TIM (0x003 << 2)
+#define MIPI_DSI_HS_TIM (0x004 << 2)
+#define MIPI_DSI_LP_TIM (0x005 << 2)
+#define MIPI_DSI_ANA_UP_TIM (0x006 << 2)
+#define MIPI_DSI_INIT_TIM (0x007 << 2)
+#define MIPI_DSI_WAKEUP_TIM (0x008 << 2)
+#define MIPI_DSI_LPOK_TIM (0x009 << 2)
+#define MIPI_DSI_LP_WCHDOG (0x00a << 2)
+#define MIPI_DSI_ANA_CTRL (0x00b << 2)
+#define MIPI_DSI_CLK_TIM1 (0x00c << 2)
+#define MIPI_DSI_TURN_WCHDOG (0x00d << 2)
+#define MIPI_DSI_ULPS_CHECK (0x00e << 2)
+#define MIPI_DSI_TEST_CTRL0 (0x00f << 2)
+#define MIPI_DSI_TEST_CTRL1 (0x010 << 2)
+/* *************************************************************
+ * Define MIPI DSI Default config
+ */
+/* Range [0,3] */
+#define MIPI_DSI_VIRTUAL_CHAN_ID 0
+/* Define DSI command transfer type: high speed or low power */
+#define MIPI_DSI_CMD_TRANS_TYPE DCS_TRANS_LP
+/* Define if DSI command need ack: req_ack or no_ack */
+#define MIPI_DSI_DCS_ACK_TYPE MIPI_DSI_DCS_NO_ACK
+
+#define MIPI_DSI_TEAR_SWITCH MIPI_DCS_DISABLE_TEAR
+
+/* PLL_CNTL bit: GP0 */
+#define LCD_PLL_LOCK_GP0_G12A (31)
+#define LCD_PLL_EN_GP0_G12A (28)
+#define LCD_PLL_RST_GP0_G12A (29)
+#define LCD_PLL_OD_GP0_G12A (16)
+#define LCD_PLL_N_GP0_G12A (10)
+#define LCD_PLL_M_GP0_G12A (0)
+
+/* ******** frequency limit (unit: kHz) ******** */
+#define PLL_FRAC_OD_FB_GP0_G12A 0
+#define SS_LEVEL_MAX_GP0_G12A 5
+#define PLL_FRAC_RANGE_GP0_G12A (1 << 17)
+#define PLL_OD_SEL_MAX_GP0_G12A 5
+#define PLL_VCO_MIN_GP0_G12A (3000 * 1000)
+#define PLL_VCO_MAX_GP0_G12A (6000 * 1000)
+
+/* PLL_CNTL bit: hpll */
+#define LCD_PLL_LOCK_HPLL_G12A (31)
+#define LCD_PLL_EN_HPLL_G12A (28)
+#define LCD_PLL_RST_HPLL_G12A (29)
+#define LCD_PLL_N_HPLL_G12A (10)
+#define LCD_PLL_M_HPLL_G12A (0)
+
+#define LCD_PLL_OD3_HPLL_G12A (20)
+#define LCD_PLL_OD2_HPLL_G12A (18)
+#define LCD_PLL_OD1_HPLL_G12A (16)
+
+/* ******** frequency limit (unit: kHz) ******** */
+#define PLL_FRAC_OD_FB_HPLL_G12A 0
+#define SS_LEVEL_MAX_HPLL_G12A 1
+#define PLL_FRAC_RANGE_HPLL_G12A (1 << 17)
+#define PLL_OD_SEL_MAX_HPLL_G12A 3
+#define PLL_VCO_MIN_HPLL_G12A (3000 * 1000)
+#define PLL_VCO_MAX_HPLL_G12A (6000 * 1000)
+
+/* video */
+#define PLL_M_MIN_G12A 2
+#define PLL_M_MAX_G12A 511
+#define PLL_N_MIN_G12A 1
+#define PLL_N_MAX_G12A 1
+#define PLL_FREF_MIN_G12A (5 * 1000)
+#define PLL_FREF_MAX_G12A (25 * 1000)
+#define CRT_VID_CLK_IN_MAX_G12A (6000 * 1000)
+#define ENCL_CLK_IN_MAX_G12A (200 * 1000)
+
+#define MIPI_DSI_COLOR_24BIT (0x5)
+
+#define MIPI_PHY_CLK_MAX (1000)
+#define MAX_ERROR (2 * 1000)
+#define CRT_VID_DIV_MAX (255)
+
+/* **********************************
+ * clk parameter bit define
+ * pll_ctrl, div_ctrl, clk_ctrl
+ * ********************************** */
+/* ******** pll_ctrl ******** */
+#define PLL_CTRL_OD3 20 /* [21:20] */
+#define PLL_CTRL_OD2 18 /* [19:18] */
+#define PLL_CTRL_OD1 16 /* [17:16] */
+#define PLL_CTRL_N 9 /* [13:9] */
+#define PLL_CTRL_M 0 /* [8:0] */
+
+/* ******** div_ctrl ******** */
+#define DIV_CTRL_EDP_DIV1 24 /* [26:24] */
+#define DIV_CTRL_EDP_DIV0 20 /* [23:20] */
+#define DIV_CTRL_DIV_SEL 8 /* [15:8] */
+#define DIV_CTRL_XD 0 /* [7:0] */
+
+/* ******** clk_ctrl ******** */
+#define CLK_CTRL_LEVEL 28 /* [30:28] */
+#define CLK_CTRL_FRAC 0 /* [18:0] */
+
+/* ******** MIPI_DSI_PHY ******** */
+/* bit[15:11] */
+#define MIPI_PHY_LANE_BIT 11
+#define MIPI_PHY_LANE_WIDTH 5
+
+/* MIPI-DSI */
+#define DSI_LANE_0 (1 << 4)
+#define DSI_LANE_1 (1 << 3)
+#define DSI_LANE_CLK (1 << 2)
+#define DSI_LANE_2 (1 << 1)
+#define DSI_LANE_3 (1 << 0)
+#define DSI_LANE_COUNT_1 (DSI_LANE_CLK | DSI_LANE_0)
+#define DSI_LANE_COUNT_2 (DSI_LANE_CLK | DSI_LANE_0 | DSI_LANE_1)
+#define DSI_LANE_COUNT_3 (DSI_LANE_CLK | DSI_LANE_0 |\
+ DSI_LANE_1 | DSI_LANE_2)
+#define DSI_LANE_COUNT_4 (DSI_LANE_CLK | DSI_LANE_0 |\
+ DSI_LANE_1 | DSI_LANE_2 | DSI_LANE_3)
+
+#define OPERATION_VIDEO_MODE 0
+#define OPERATION_COMMAND_MODE 1
+
+#define SYNC_PULSE 0x0
+#define SYNC_EVENT 0x1
+#define BURST_MODE 0x2
+
+/* command config */
+#define DSI_CMD_SIZE_INDEX 1 /* byte[1] */
+#define DSI_GPIO_INDEX 2 /* byte[2] */
+
+#define DSI_INIT_ON_MAX 100
+#define DSI_INIT_OFF_MAX 30
+
+/* **** DPHY timing parameter Value (unit: 0.01ns) **** */
+/* >100ns (4M) */
+#define DPHY_TIME_LP_TESC(ui) (250 * 100)
+/* >50ns */
+#define DPHY_TIME_LP_LPX(ui) (100 * 100)
+/* (lpx, 2*lpx) */
+#define DPHY_TIME_LP_TA_SURE(ui) DPHY_TIME_LP_LPX(ui)
+/* 4*lpx */
+#define DPHY_TIME_LP_TA_GO(ui) (4 * DPHY_TIME_LP_LPX(ui))
+/* 5*lpx */
+#define DPHY_TIME_LP_TA_GETX(ui) (5 * DPHY_TIME_LP_LPX(ui))
+/* >100ns */
+#define DPHY_TIME_HS_EXIT(ui) (110 * 100)
+/* max(8*ui, 60+4*ui), (teot)<105+12*ui */
+#define DPHY_TIME_HS_TRAIL(ui) ((ui > (60 * 100 / 4)) ? \
+ (8 * ui) : ((60 * 100) + 4 * ui))
+/* (40+4*ui, 85+6*ui) */
+#define DPHY_TIME_HS_PREPARE(ui) (50 * 100 + 4 * ui)
+/* hs_prepare+hs_zero >145+10*ui */
+#define DPHY_TIME_HS_ZERO(ui) (160 * 100 + 10 * ui - \
+ DPHY_TIME_HS_PREPARE(ui))
+/* >60ns, (teot)<105+12*ui */
+#define DPHY_TIME_CLK_TRAIL(ui) (70 * 100)
+/* >60+52*ui */
+#define DPHY_TIME_CLK_POST(ui) (2 * (60 * 100 + 52 * ui))
+/* (38, 95) */
+#define DPHY_TIME_CLK_PREPARE(ui) (50 * 100)
+/* clk_prepare+clk_zero > 300 */
+#define DPHY_TIME_CLK_ZERO(ui) (320 * 100 - DPHY_TIME_CLK_PREPARE(ui))
+/* >8*ui */
+#define DPHY_TIME_CLK_PRE(ui) (10 * ui)
+/* >100us */
+#define DPHY_TIME_INIT(ui) (110 * 1000 * 100)
+/* >1ms */
+#define DPHY_TIME_WAKEUP(ui) (1020 * 1000 * 100)
+
+/* MIPI DSI Relative REGISTERs Definitions */
+/* For MIPI_DSI_TOP_CNTL */
+#define BIT_DPI_COLOR_MODE 20
+#define BIT_IN_COLOR_MODE 16
+#define BIT_CHROMA_SUBSAMPLE 14
+#define BIT_COMP2_SEL 12
+#define BIT_COMP1_SEL 10
+#define BIT_COMP0_SEL 8
+#define BIT_DE_POL 6
+#define BIT_HSYNC_POL 5
+#define BIT_VSYNC_POL 4
+#define BIT_DPICOLORM 3
+#define BIT_DPISHUTDN 2
+#define BIT_EDPITE_INTR_PULSE 1
+#define BIT_ERR_INTR_PULSE 0
+
+/* For MIPI_DSI_DWC_CLKMGR_CFG_OS */
+#define BIT_TO_CLK_DIV 8
+#define BIT_TX_ESC_CLK_DIV 0
+
+/* For MIPI_DSI_DWC_PCKHDL_CFG_OS */
+#define BIT_CRC_RX_EN 4
+#define BIT_ECC_RX_EN 3
+#define BIT_BTA_EN 2
+#define BIT_EOTP_RX_EN 1
+#define BIT_EOTP_TX_EN 0
+
+/* For MIPI_DSI_DWC_VID_MODE_CFG_OS */
+#define BIT_LP_CMD_EN 15
+#define BIT_FRAME_BTA_ACK_EN 14
+#define BIT_LP_HFP_EN 13
+#define BIT_LP_HBP_EN 12
+#define BIT_LP_VCAT_EN 11
+#define BIT_LP_VFP_EN 10
+#define BIT_LP_VBP_EN 9
+#define BIT_LP_VSA_EN 8
+#define BIT_VID_MODE_TYPE 0
+
+/* For MIPI_DSI_DWC_PHY_STATUS_OS */
+#define BIT_PHY_ULPSACTIVENOT3LANE 12
+#define BIT_PHY_STOPSTATE3LANE 11
+#define BIT_PHY_ULPSACTIVENOT2LANE 10
+#define BIT_PHY_STOPSTATE2LANE 9
+#define BIT_PHY_ULPSACTIVENOT1LANE 8
+#define BIT_PHY_STOPSTATE1LANE 7
+#define BIT_PHY_RXULPSESC0LANE 6
+#define BIT_PHY_ULPSACTIVENOT0LANE 5
+#define BIT_PHY_STOPSTATE0LANE 4
+#define BIT_PHY_ULPSACTIVENOTCLK 3
+#define BIT_PHY_STOPSTATECLKLANE 2
+#define BIT_PHY_DIRECTION 1
+#define BIT_PHY_LOCK 0
+
+/* For MIPI_DSI_DWC_PHY_IF_CFG_OS */
+#define BIT_PHY_STOP_WAIT_TIME 8
+#define BIT_N_LANES 0
+
+/* For MIPI_DSI_DWC_DPI_COLOR_CODING_OS */
+#define BIT_LOOSELY18_EN 8
+#define BIT_DPI_COLOR_CODING 0
+
+/* For MIPI_DSI_DWC_GEN_HDR_OS */
+#define BIT_GEN_WC_MSBYTE 16
+#define BIT_GEN_WC_LSBYTE 8
+#define BIT_GEN_VC 6
+#define BIT_GEN_DT 0
+
+/* For MIPI_DSI_DWC_LPCLK_CTRL_OS */
+#define BIT_AUTOCLKLANE_CTRL 1
+#define BIT_TXREQUESTCLKHS 0
+
+/* For MIPI_DSI_DWC_DPI_CFG_POL_OS */
+#define BIT_COLORM_ACTIVE_LOW 4
+#define BIT_SHUTD_ACTIVE_LOW 3
+#define BIT_HSYNC_ACTIVE_LOW 2
+#define BIT_VSYNC_ACTIVE_LOW 1
+#define BIT_DATAEN_ACTIVE_LOW 0
+
+/* For MIPI_DSI_DWC_CMD_MODE_CFG_OS */
+#define BIT_MAX_RD_PKT_SIZE 24
+#define BIT_DCS_LW_TX 19
+#define BIT_DCS_SR_0P_TX 18
+#define BIT_DCS_SW_1P_TX 17
+#define BIT_DCS_SW_0P_TX 16
+#define BIT_GEN_LW_TX 14
+#define BIT_GEN_SR_2P_TX 13
+#define BIT_GEN_SR_1P_TX 12
+#define BIT_GEN_SR_0P_TX 11
+#define BIT_GEN_SW_2P_TX 10
+#define BIT_GEN_SW_1P_TX 9
+#define BIT_GEN_SW_0P_TX 8
+#define BIT_ACK_RQST_EN 1
+#define BIT_TEAR_FX_EN 0
+
+/* For MIPI_DSI_DWC_CMD_PKT_STATUS_OS */
+/* For DBI no use full */
+#define BIT_DBI_RD_CMD_BUSY 14
+#define BIT_DBI_PLD_R_FULL 13
+#define BIT_DBI_PLD_R_EMPTY 12
+#define BIT_DBI_PLD_W_FULL 11
+#define BIT_DBI_PLD_W_EMPTY 10
+#define BIT_DBI_CMD_FULL 9
+#define BIT_DBI_CMD_EMPTY 8
+/* For Generic interface */
+#define BIT_GEN_RD_CMD_BUSY 6
+#define BIT_GEN_PLD_R_FULL 5
+#define BIT_GEN_PLD_R_EMPTY 4
+#define BIT_GEN_PLD_W_FULL 3
+#define BIT_GEN_PLD_W_EMPTY 2
+#define BIT_GEN_CMD_FULL 1
+#define BIT_GEN_CMD_EMPTY 0
+
+/* For MIPI_DSI_TOP_MEAS_CNTL */
+/* measure vsync control */
+#define BIT_CNTL_MEAS_VSYNC 10
+/* tear measure enable */
+#define BIT_EDPITE_MEAS_EN 9
+/* not clear the counter */
+#define BIT_EDPITE_ACCUM_MEAS_EN 8
+#define BIT_EDPITE_VSYNC_SPAN 0
+
+/* For MIPI_DSI_TOP_STAT */
+/* signal from halt */
+#define BIT_STAT_EDPIHALT 31
+/* line number when edpite pulse */
+#define BIT_STAT_TE_LINE 16
+/* pixel number when edpite pulse */
+#define BIT_STAT_TE_PIXEL 0
+
+/* For MIPI_DSI_TOP_INTR_CNTL_STAT */
+/* State/Clear for pic_eof */
+#define BIT_STAT_CLR_DWC_PIC_EOF 21
+/* State/Clear for de_fall */
+#define BIT_STAT_CLR_DWC_DE_FALL 20
+/* State/Clear for de_rise */
+#define BIT_STAT_CLR_DWC_DE_RISE 19
+/* State/Clear for vs_fall */
+#define BIT_STAT_CLR_DWC_VS_FALL 18
+/* State/Clear for vs_rise */
+#define BIT_STAT_CLR_DWC_VS_RISE 17
+/* State/Clear for edpite */
+#define BIT_STAT_CLR_DWC_EDPITE 16
+/* end of picture */
+#define BIT_PIC_EOF 5
+/* data enable fall */
+#define BIT_DE_FALL 4
+/* data enable rise */
+#define BIT_DE_RISE 3
+/* vsync fall */
+#define BIT_VS_FALL 2
+/* vsync rise */
+#define BIT_VS_RISE 1
+/* edpite int enable */
+#define BIT_EDPITE_INT_EN 0
+
+/* For MIPI_DSI_TOP_MEAS_CNTL */
+/* vsync measure enable */
+#define BIT_VSYNC_MEAS_EN 19
+/* vsync accumulate measure */
+#define BIT_VSYNC_ACCUM_MEAS_EN 18
+/* vsync span */
+#define BIT_VSYNC_SPAN 10
+/* tearing measure enable */
+#define BIT_TE_MEAS_EN 9
+/* tearing accumulate measure */
+#define BIT_TE_ACCUM_MEAS_EN 8
+/* tearing span */
+#define BIT_TE_SPAN 0
+
+/* For MIPI_DSI_DWC_INT_ST0_OS */
+/* LP1 contention error from lane0 */
+#define BIT_DPHY_ERR_4 20
+/* LP0 contention error from lane0 */
+#define BIT_DPHY_ERR_3 19
+/* ErrControl error from lane0 */
+#define BIT_DPHY_ERR_2 18
+/* ErrSyncEsc error from lane0 */
+#define BIT_DPHY_ERR_1 17
+/* ErrEsc escape error lane0 */
+#define BIT_DPHY_ERR_0 16
+#define BIT_ACK_ERR_15 15
+#define BIT_ACK_ERR_14 14
+#define BIT_ACK_ERR_13 13
+#define BIT_ACK_ERR_12 12
+#define BIT_ACK_ERR_11 11
+#define BIT_ACK_ERR_10 10
+#define BIT_ACK_ERR_9 9
+#define BIT_ACK_ERR_8 8
+#define BIT_ACK_ERR_7 7
+#define BIT_ACK_ERR_6 6
+#define BIT_ACK_ERR_5 5
+#define BIT_ACK_ERR_4 4
+#define BIT_ACK_ERR_3 3
+#define BIT_ACK_ERR_2 2
+#define BIT_ACK_ERR_1 1
+#define BIT_ACK_ERR_0 0
+
+/* Command transfer type in command mode */
+#define DCS_TRANS_HS 0
+#define DCS_TRANS_LP 1
+
+#define MIPI_DSI_DCS_NO_ACK 0
+#define MIPI_DSI_DCS_REQ_ACK 1
+
+/* DSI Tear Defines */
+#define MIPI_DCS_SET_TEAR_ON_MODE_0 0
+#define MIPI_DCS_SET_TEAR_ON_MODE_1 1
+#define MIPI_DCS_ENABLE_TEAR 1
+#define MIPI_DCS_DISABLE_TEAR 0
+
+
+/* MIPI DCS Pixel-to-Byte Format */
+#define DCS_PF_RSVD 0x0
+#define DCS_PF_3BIT 0x1
+#define DCS_PF_8BIT 0x2
+#define DCS_PF_12BIT 0x3
+#define DCS_PF_16BIT 0x5
+#define DCS_PF_18BIT 0x6
+#define DCS_PF_24BIT 0x7
+
+/* MIPI DSI/VENC Color Format Definitions */
+#define MIPI_DSI_VENC_COLOR_30B 0x0
+#define MIPI_DSI_VENC_COLOR_24B 0x1
+#define MIPI_DSI_VENC_COLOR_18B 0x2
+#define MIPI_DSI_VENC_COLOR_16B 0x3
+
+#define COLOR_16BIT_CFG_1 0x0
+#define COLOR_16BIT_CFG_2 0x1
+#define COLOR_16BIT_CFG_3 0x2
+#define COLOR_18BIT_CFG_1 0x3
+#define COLOR_18BIT_CFG_2 0x4
+#define COLOR_24BIT 0x5
+#define COLOR_20BIT_LOOSE 0x6
+#define COLOR_24_BIT_YCBCR 0x7
+#define COLOR_16BIT_YCBCR 0x8
+#define COLOR_30BIT 0x9
+#define COLOR_36BIT 0xa
+#define COLOR_12BIT 0xb
+#define COLOR_RGB_111 0xc
+#define COLOR_RGB_332 0xd
+#define COLOR_RGB_444 0xe
+
+
+enum div_sel_e {
+ CLK_DIV_SEL_1 = 0,
+ CLK_DIV_SEL_2, /* 1 */
+ CLK_DIV_SEL_3, /* 2 */
+ CLK_DIV_SEL_3p5, /* 3 */
+ CLK_DIV_SEL_3p75, /* 4 */
+ CLK_DIV_SEL_4, /* 5 */
+ CLK_DIV_SEL_5, /* 6 */
+ CLK_DIV_SEL_6, /* 7 */
+ CLK_DIV_SEL_6p25, /* 8 */
+ CLK_DIV_SEL_7, /* 9 */
+ CLK_DIV_SEL_7p5, /* 10 */
+ CLK_DIV_SEL_12, /* 11 */
+ CLK_DIV_SEL_14, /* 12 */
+ CLK_DIV_SEL_15, /* 13 */
+ CLK_DIV_SEL_2p5, /* 14 */
+ CLK_DIV_SEL_MAX,
+};
+
+
+typedef struct {
+ uint32_t lcd_bits;
+ uint32_t h_active;
+ uint32_t v_active;
+ uint32_t h_period;
+ uint32_t v_period;
+
+ uint32_t fr_adj_type;
+ uint32_t ss_level;
+ uint32_t clk_auto_gen;
+ uint32_t lcd_clock;
+
+ uint32_t clk_ctrl;
+ uint32_t pll_ctrl;
+ uint32_t div_ctrl;
+ uint32_t clk_change;
+
+ uint32_t lcd_clk_dft;
+ uint32_t hPeriod_dft;
+ uint32_t vPeriod_dft;
+
+ uint32_t sync_duration_numerator;
+ uint32_t sync_duration_denominator;
+
+ uint32_t vid_pixel_on;
+ uint32_t vid_line_on;
+
+ uint32_t hSync_width;
+ uint32_t hSync_backPorch;
+ uint32_t hSync_pol;
+ uint32_t vSync_width;
+ uint32_t vSync_backPorch;
+ uint32_t vSync_pol;
+
+ uint32_t hOffset;
+ uint32_t vOffset;
+
+ uint32_t de_hs_addr;
+ uint32_t de_he_addr;
+ uint32_t de_vs_addr;
+ uint32_t de_ve_addr;
+
+ uint32_t hs_hs_addr;
+ uint32_t hs_he_addr;
+ uint32_t hs_vs_addr;
+ uint32_t hs_ve_addr;
+
+ uint32_t vs_hs_addr;
+ uint32_t vs_he_addr;
+ uint32_t vs_vs_addr;
+ uint32_t vs_ve_addr;
+} lcd_timing_t;
+
+typedef struct {
+ uint32_t lane_num;
+ uint32_t bit_rate_max;
+ uint32_t bit_rate_min;
+ uint32_t bit_rate;
+ uint32_t clock_factor;
+ uint32_t factor_numerator;
+ uint32_t factor_denominator;
+ uint32_t opp_mode_init;
+ uint32_t opp_mode_display;
+ uint32_t video_mode_type;
+ uint32_t clk_always_hs;
+ uint32_t phy_switch;
+ uint32_t venc_data_width;
+ uint32_t dpi_data_format;
+
+ uint32_t hLine; // Overall time for each video line
+ uint32_t hSyncActive; // Horizontal Sync Active Period
+ uint32_t hBackporch; // Horizontal Back Porch Period
+ uint32_t vSyncActive; // Vertical Sync Active Period
+ uint32_t vBackporch; // Vertical Back Porch Period
+ uint32_t vFrontporch; // Vertical Front Porch Period
+ uint32_t vActiveLines; // Vertical Active Period
+
+ unsigned char check_en;
+ unsigned char check_reg;
+ unsigned char check_cnt;
+ unsigned char check_state;
+
+} dsi_config_t;
+
+typedef struct {
+ uint32_t lp_tesc;
+ uint32_t lp_lpx;
+ uint32_t lp_ta_sure;
+ uint32_t lp_ta_go;
+ uint32_t lp_ta_get;
+ uint32_t hs_exit;
+ uint32_t hs_trail;
+ uint32_t hs_zero;
+ uint32_t hs_prepare;
+ uint32_t clk_trail;
+ uint32_t clk_post;
+ uint32_t clk_zero;
+ uint32_t clk_prepare;
+ uint32_t clk_pre;
+ uint32_t init;
+ uint32_t wakeup;
+ uint32_t state_change;
+} dsi_phy_config_t;
+
+typedef struct {
+ int data_bits;
+ int vid_num_chunks;
+ int pixel_per_chunk; /* pkt_size */
+ int vid_null_size;
+ int byte_per_chunk; /* internal usage */
+ int multi_pkt_en; /* internal usage */
+
+ /* vid timing */
+ uint32_t hline;
+ uint32_t hsa;
+ uint32_t hbp;
+ uint32_t vsa;
+ uint32_t vbp;
+ uint32_t vfp;
+ uint32_t vact;
+} dsi_video_t;
+
+struct dsi_cmd_request_s {
+ unsigned char data_type;
+ unsigned char vc_id;
+ unsigned char *payload;
+ unsigned short pld_count;
+ unsigned int req_ack;
+};
+
+
+
+
+enum mipi_dsi_data_type_host_e {
+ DT_VSS = 0x01,
+ DT_VSE = 0x11,
+ DT_HSS = 0x21,
+ DT_HSE = 0x31,
+ DT_EOTP = 0x08,
+ DT_CMOFF = 0x02,
+ DT_CMON = 0x12,
+ DT_SHUT_DOWN = 0x22,
+ DT_TURN_ON = 0x32,
+ DT_GEN_SHORT_WR_0 = 0x03,
+ DT_GEN_SHORT_WR_1 = 0x13,
+ DT_GEN_SHORT_WR_2 = 0x23,
+ DT_GEN_RD_0 = 0x04,
+ DT_GEN_RD_1 = 0x14,
+ DT_GEN_RD_2 = 0x24,
+ DT_DCS_SHORT_WR_0 = 0x05,
+ DT_DCS_SHORT_WR_1 = 0x15,
+ DT_DCS_RD_0 = 0x06,
+ DT_SET_MAX_RET_PKT_SIZE = 0x37,
+ DT_NULL_PKT = 0x09,
+ DT_BLANK_PKT = 0x19,
+ DT_GEN_LONG_WR = 0x29,
+ DT_DCS_LONG_WR = 0x39,
+ DT_20BIT_LOOSE_YCBCR = 0x0c,
+ DT_24BIT_YCBCR = 0x1c,
+ DT_16BIT_YCBCR = 0x2c,
+ DT_30BIT_RGB_101010 = 0x0d,
+ DT_36BIT_RGB_121212 = 0x1d,
+ DT_12BIT_YCBCR = 0x3d,
+ DT_16BIT_RGB_565 = 0x0e,
+ DT_18BIT_RGB_666 = 0x1e,
+ DT_18BIT_LOOSE_RGB_666 = 0x2e,
+ DT_24BIT_RGB_888 = 0x3e
+};
+
+/* DCS Command List */
+#define DCS_ENTER_IDLE_MODE 0x39
+#define DCS_ENTER_INVERT_MODE 0x21
+#define DCS_ENTER_NORMAL_MODE 0x13
+#define DCS_ENTER_PARTIAL_MODE 0x12
+#define DCS_ENTER_SLEEP_MODE 0x10
+#define DCS_EXIT_IDLE_MODE 0x38
+#define DCS_EXIT_INVERT_MODE 0x20
+#define DCS_EXIT_SLEEP_MODE 0x11
+#define DCS_GET_3D_CONTROL 0x3f
+#define DCS_GET_ADDRESS_MODE 0x0b
+#define DCS_GET_BLUE_CHANNEL 0x08
+#define DCS_GET_DIAGNOSTIC_RESULT 0x0f
+#define DCS_GET_DISPLAY_MODE 0x0d
+#define DCS_GET_GREEN_CHANNEL 0x07
+#define DCS_GET_PIXEL_FORMAT 0x0c
+#define DCS_GET_POWER_MODE 0x0a
+#define DCS_GET_RED_CHANNEL 0x06
+#define DCS_GET_SCANLINE 0x45
+#define DCS_GET_SIGNAL_MODE 0x0e
+#define DCS_NOP 0x00
+#define DCS_READ_DDB_CONTINUE 0xa8
+#define DCS_READ_DDB_START 0xa1
+#define DCS_READ_MEMORY_CONTINUE 0x3e
+#define DCS_READ_MEMORY_START 0x2e
+#define DCS_SET_3D_CONTROL 0x3d
+#define DCS_SET_ADDRESS_MODE 0x36
+#define DCS_SET_COLUMN_ADDRESS 0x2a
+#define DCS_SET_DISPLAY_OFF 0x28
+#define DCS_SET_DISPLAY_ON 0x29
+#define DCS_SET_GAMMA_CURVE 0x26
+#define DCS_SET_PAGE_ADDRESS 0x2b
+#define DCS_SET_PARTIAL_COLUMNS 0x31
+#define DCS_SET_PARTIAL_ROWS 0x30
+#define DCS_SET_PIXEL_FORMAT 0x3a
+#define DCS_SET_SCROLL_AREA 0x33
+#define DCS_SET_SCROLL_START 0x37
+#define DCS_SET_TEAR_OFF 0x34
+#define DCS_SET_TEAR_ON 0x35
+#define DCS_SET_TEAR_SCANLINE 0x44
+#define DCS_SET_VSYNC_TIMING 0x40
+#define DCS_SOFT_RESET 0x01
+#define DCS_WRITE_LUT 0x2d
+#define DCS_WRITE_MEMORY_CONTINUE 0x3c
+#define DCS_WRITE_MEMORY_START 0x2c
+
+
+
+enum mipi_dsi_data_type_peripheral_e {
+ DT_RESP_TE = 0xba,
+ DT_RESP_ACK = 0x84,
+ DT_RESP_ACK_ERR = 0x02,
+ DT_RESP_EOT = 0x08,
+ DT_RESP_GEN_READ_1 = 0x11,
+ DT_RESP_GEN_READ_2 = 0x12,
+ DT_RESP_GEN_READ_LONG = 0x1a,
+ DT_RESP_DCS_READ_LONG = 0x1c,
+ DT_RESP_DCS_READ_1 = 0x21,
+ DT_RESP_DCS_READ_2 = 0x22,
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#if 0
+//------------------------------------------------------------------------------
+// Top-level registers: AmLogic proprietary
+//------------------------------------------------------------------------------
+// 31: 4 Reserved. Default 0.
+// 3 RW ~tim_rst_n: 1=Assert SW reset on mipi_dsi_host_timing block. 0=Release reset. Default 1.
+// 2 RW ~dpi_rst_n: 1=Assert SW reset on mipi_dsi_host_dpi block. 0=Release reset. Default 1.
+// 1 RW ~intr_rst_n: 1=Assert SW reset on mipi_dsi_host_intr block. 0=Release reset. Default 1.
+// 0 RW ~dwc_rst_n: 1=Assert SW reset on IP core. 0=Release reset. Default 1.
+#define MIPI_DSI_TOP_SW_RESET (0x1cf0)
+// 31: 5 Reserved. Default 0.
+// 4 RW manual_edpihalt: 1=Manual suspend VencL; 0=do not suspend VencL. Default 0.
+// 3 RW auto_edpihalt_en: 1=Enable IP's edpihalt signal to suspend VencL; 0=IP's edpihalt signal does not affect VencL. Default 0.
+// 2 RW clock_freerun: Apply to auto-clock gate only. Default 0.
+// 0=Default, use auto-clock gating to save power;
+// 1=use free-run clock, disable auto-clock gating, for debug mode.
+// 1 RW enable_pixclk: A manual clock gate option, due to DWC IP does not have auto-clock gating. 1=Enable pixclk. Default 0.
+// 0 RW enable_sysclk: A manual clock gate option, due to DWC IP does not have auto-clock gating. 1=Enable sysclk. Default 0.
+#define MIPI_DSI_TOP_CLK_CNTL (0x1cf1)
+// 31:27 Reserved. Default 0.
+// 26 RW de_dpi_pol: 1= Invert DE polarity from mipi_dsi_host_dpi. Default 0.
+// 25 RW hsync_dpi_pol: 1= Invert HS polarity from mipi_dsi_host_dpi. Default 0.
+// 24 RW vsync_dpi_pol: 1= Invert VS polarity from mipi_dsi_host_dpi. Default 0.
+// 23:20 RW dpi_color_mode: Define DPI pixel format. Default 0.
+// 0=16-bit RGB565 config 1;
+// 1=16-bit RGB565 config 2;
+// 2=16-bit RGB565 config 3;
+// 3=18-bit RGB666 config 1;
+// 4=18-bit RGB666 config 2;
+// 5=24-bit RGB888;
+// 6=20-bit YCbCr 4:2:2;
+// 7=24-bit YCbCr 4:2:2;
+// 8=16-bit YCbCr 4:2:2;
+// 9=30-bit RGB;
+// 10=36-bit RGB;
+// 11=12-bit YCbCr 4:2:0.
+// 19 Reserved. Default 0.
+// 18:16 RW in_color_mode: Define VENC data width. Default 0.
+// 0=30-bit pixel;
+// 1=24-bit pixel;
+// 2=18-bit pixel, RGB666;
+// 3=16-bit pixel, RGB565.
+// 15:14 RW chroma_subsample: Define method of chroma subsampling. Default 0.
+// Applicable to YUV422 or YUV420 only.
+// 0=Use even pixel's chroma;
+// 1=Use odd pixel's chroma;
+// 2=Use averaged value between even and odd pair.
+// 13:12 RW comp2_sel: Select which component to be Cr or B: 0=comp0; 1=comp1; 2=comp2. Default 2.
+// 11:10 RW comp1_sel: Select which component to be Cb or G: 0=comp0; 1=comp1; 2=comp2. Default 1.
+// 9: 8 RW comp0_sel: Select which component to be Y or R: 0=comp0; 1=comp1; 2=comp2. Default 0.
+// 7 Reserved. Default 0.
+// 6 RW de_venc_pol: 1= Invert DE polarity from VENC. Default 0.
+// 5 RW hsync_venc_pol: 1= Invert HS polarity from VENC. Default 0.
+// 4 RW vsync_venc_pol: 1= Invert VS polarity from VENC. Default 0.
+// 3 RW dpicolorm: Signal to IP. Default 0.
+// 2 RW dpishutdn: Signal to IP. Default 0.
+// 1 Reserved. Default 0.
+// 0 Reserved. Default 0.
+#define MIPI_DSI_TOP_CNTL (0x1cf2)
+// 31:16 Reserved. Default 0.
+// 15: 8 RW suspend_frame_rate: Define rate of timed-suspend. Default 0.
+// 0=Execute suspend every frame; 1=Every other frame; ...; 255=Every 256 frame.
+// 7: 3 Reserved. Default 0.
+// 2 RW timed_suspend_en: 1=Enable timed suspend VencL. 0=Disable timed suspend. Default 0.
+// 1 RW manual_suspend_en: 1=Enable manual suspend VencL. 1=Cancel manual suspend VencL. Default 0.
+// 0 RW suspend_on_edpihalt:1=Enable IP's edpihalt signal to suspend VencL; 0=IP's edpihalt signal does not affect VencL. Default 1.
+#define MIPI_DSI_TOP_SUSPEND_CNTL (0x1cf3)
+// 31:29 Reserved. Default 0.
+// 28:16 RW suspend_line_end: Define timed-suspend region. Suspend from [pix_start,line_start] to [pix_end,line_end]. Default 0.
+// 15:13 Reserved. Default 0.
+// 12: 0 RW suspend_line_start: Define timed-suspend region. Suspend from [pix_start,line_start] to [pix_end,line_end]. Default 0.
+#define MIPI_DSI_TOP_SUSPEND_LINE (0x1cf4)
+// 31:29 Reserved. Default 0.
+// 28:16 RW suspend_pix_end: Define timed-suspend region. Suspend from [pix_start,line_start] to [pix_end,line_end]. Default 0.
+// 15:13 Reserved. Default 0.
+// 12: 0 RW suspend_pix_start: Define timed-suspend region. Suspend from [pix_start,line_start] to [pix_end,line_end]. Default 0.
+#define MIPI_DSI_TOP_SUSPEND_PIX (0x1cf5)
+// 31:20 Reserved. Default 0.
+// 19:10 RW meas_vsync: Control on measuring Host Controller's vsync. Default 0.
+// [ 19] meas_en: 1=Enable measurement
+// [ 18] accum_meas_en: 0=meas_count is cleared at the end of each measure;
+// 1=meas_count is accumulated at the end of each measure.
+// [17:10] vsync_span: Define the duration of a measure is to last for how many Vsyncs.
+// 9: 0 RW meas_edpite: Control on measuring Display Slave's edpite. Default 0.
+// [ 9] meas_en: 1=Enable measurement
+// [ 8] accum_meas_en: 0=meas_count is cleared at the end of each measure;
+// 1=meas_count is accumulated at the end of each measure.
+// [ 7: 0] edpite_span: Define the duration of a measure is to last for how many edpite.
+#define MIPI_DSI_TOP_MEAS_CNTL (0x1cf6)
+// 31 R stat_edpihalt: status of edpihalt signal from IP. Default 0.
+// 30:29 Reserved. Default 0.
+// 28:16 R stat_te_line: Snapshot of Host's line position at edpite. Default 0.
+// 15:13 Reserved. Default 0.
+// 12: 0 R stat_te_pix: Snapshot of Host's pixel position at edpite. Default 0.
+#define MIPI_DSI_TOP_STAT (0x1cf7)
+// To measure display slave's frame rate, we can use a reference clock to measure the duration of one of more edpite pulse(s).
+// Measurement control is by register MIPI_DSI_TOP_MEAS_CNTL bit[9:0].
+// Reference clock comes from clk_rst_tst.cts_dsi_meas_clk, and is defined by HIU register HHI_VDIN_MEAS_CLK_CNTL bit[23:12].
+// Mesurement result is in MIPI_DSI_TOP_MEAS_STAT_TE0 and MIPI_DSI_TOP_MEAS_STAT_TE1, as below:
+// edpite_meas_count[47:0]: Number of reference clock cycles counted during one measure period (non-incremental measure), or
+// during all measure periods so far (incremental measure).
+// edpite_meas_count_n[3:0]:Number of measure periods has been done. Number can wrap over.
+//
+// 31: 0 R edpite_meas_count[31:0]. Default 0.
+#define MIPI_DSI_TOP_MEAS_STAT_TE0 (0x1cf8)
+// 19:16 R edpite_meas_count_n. Default 0.
+// 15: 0 R edpite_meas_count[47:32]. Default 0.
+#define MIPI_DSI_TOP_MEAS_STAT_TE1 (0x1cf9)
+// To measure Host's frame rate, we can use a reference clock to measure the duration of one of more Vsync pulse(s).
+// Measurement control is by register MIPI_DSI_TOP_MEAS_CNTL bit[19:10].
+// Reference clock comes from clk_rst_tst.cts_dsi_meas_clk, and is defined by HIU register HHI_VDIN_MEAS_CLK_CNTL bit[23:12].
+// Mesurement result is in MIPI_DSI_TOP_MEAS_STAT_VS0 and MIPI_DSI_TOP_MEAS_STAT_VS1, as below:
+// vsync_meas_count[47:0]: Number of reference clock cycles counted during one measure period (non-incremental measure), or
+// during all measure periods so far (incremental measure).
+// vsync_meas_count_n[3:0]: Number of measure periods has been done. Number can wrap over.
+//
+// 31: 0 R vsync_meas_count[31:0]. Default 0.
+#define MIPI_DSI_TOP_MEAS_STAT_VS0 (0x1cfa)
+// 19:16 R vsync_meas_count_n. Default 0.
+// 15: 0 R vsync_meas_count[47:32]. Default 0.
+#define MIPI_DSI_TOP_MEAS_STAT_VS1 (0x1cfb)
+// 31:16 RW intr_stat/clr. For each bit, read as this interrupt level status, write 1 to clear. Default 0.
+// Note: To clear the interrupt level, simply write 1 to the specific bit, no need to write 0 afterwards.
+// [31:22] Reserved
+// [ 21] stat/clr of EOF interrupt
+// [ 20] stat/clr of de_fall interrupt
+// [ 19] stat/clr of de_rise interrupt
+// [ 18] stat/clr of vs_fall interrupt
+// [ 17] stat/clr of vs_rise interrupt
+// [ 16] stat/clr of dwc_edpite interrupt
+// 15: 0 RW intr_enable. For each bit, 1=enable this interrupt, 0=disable. Default 0.
+// [15: 6] Reserved
+// [ 5] EOF (End_Of_Field) interrupt
+// [ 4] de_fall interrupt
+// [ 3] de_rise interrupt
+// [ 2] vs_fall interrupt
+// [ 1] vs_rise interrupt
+// [ 0] dwc_edpite interrupt
+#define MIPI_DSI_TOP_INTR_CNTL_STAT (0x1cfc)
+// 31: 2 Reserved. Default 0.
+// 1: 0 RW mem_pd. Default 3.
+#define MIPI_DSI_TOP_MEM_PD (0x1cfd)
+#endif
\ No newline at end of file
diff --git a/system/dev/display/astro-display/astro-display.c b/system/dev/display/astro-display/astro-display.c
index b04a670..88cc716 100644
--- a/system/dev/display/astro-display/astro-display.c
+++ b/system/dev/display/astro-display/astro-display.c
@@ -3,24 +3,56 @@
// found in the LICENSE file.
#include "astro-display.h"
-#include <assert.h>
-#include <ddk/binding.h>
-#include <ddk/debug.h>
-#include <ddk/device.h>
-#include <ddk/driver.h>
-#include <ddk/io-buffer.h>
-#include <ddk/protocol/display.h>
-#include <ddk/protocol/platform-defs.h>
-#include <ddk/protocol/platform-device.h>
-#include <hw/reg.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <zircon/assert.h>
-#include <zircon/device/display.h>
-#include <zircon/syscalls.h>
+
+
+const struct display_setting g_disp_setting = {
+ .lcd_bits = 8,
+ .hActive = 600,
+ .vActive = 1024,
+ .hPeriod = 680,
+ .vPeriod = 1194,
+ .hSync_width = 24,
+ .hSync_backPorch = 36,
+ .hSync_pol = 0,
+ .vSync_width = 10,
+ .vSync_backPorch = 80,
+ .vSync_pol = 0,
+
+ // Clock configs
+ .fr_adj_type = 0,
+ .ss_level = 0,
+ .clk_auto_gen = 1,
+ .lcd_clock = 48715200,
+
+ //mipi vals
+ .lane_num = 4,
+ .bit_rate_max = 400,
+ .factor_numerator = 0,
+ .opp_mode_init = 1,
+ .opp_mode_display = 0,
+ .video_mode_type = 2,
+ .clk_always_hs = 0,
+ .phy_switch = 0,
+};
+
+struct lcd_clk_config g_lcd_clk_cfg = {
+ .od_fb = PLL_FRAC_OD_FB_HPLL_G12A,
+ .ss_level_max = SS_LEVEL_MAX_HPLL_G12A,
+ .pll_frac_range = PLL_FRAC_RANGE_HPLL_G12A,
+ .pll_od_sel_max = PLL_OD_SEL_MAX_HPLL_G12A,
+ .pll_vco_fmax = PLL_VCO_MAX_HPLL_G12A,
+ .pll_vco_fmin = PLL_VCO_MIN_HPLL_G12A,
+ .pll_m_max = PLL_M_MAX_G12A,
+ .pll_m_min = PLL_M_MIN_G12A,
+ .pll_n_max = PLL_N_MAX_G12A,
+ .pll_n_min = PLL_N_MIN_G12A,
+ .pll_ref_fmax = PLL_FREF_MAX_G12A,
+ .pll_ref_fmin = PLL_FREF_MIN_G12A,
+ .pll_out_fmax = CRT_VID_CLK_IN_MAX_G12A,
+ .pll_out_fmin = PLL_VCO_MIN_HPLL_G12A / 16,
+ .div_out_fmax = CRT_VID_CLK_IN_MAX_G12A,
+ .xd_out_fmax = ENCL_CLK_IN_MAX_G12A,
+};
static zx_status_t vc_set_mode(void* ctx, zx_display_info_t* info) {
return ZX_OK;
@@ -169,54 +201,23 @@
.open = vc_open,
};
-/* Table from Linux source */
-/* TODO: Need to separate backlight driver from display driver */
-static const uint8_t backlight_init_table[] = {
- 0xa2, 0x20,
- 0xa5, 0x54,
- 0x00, 0xff,
- 0x01, 0x05,
- 0xa2, 0x20,
- 0xa5, 0x54,
- 0xa1, 0xb7,
- 0xa0, 0xff,
- 0x00, 0x80,
-};
-
-static void init_backlight(astro_display_t* display) {
-
- // power on backlight
- gpio_config(&display->gpio, 0, GPIO_DIR_OUT);
- gpio_write(&display->gpio, 0, 1);
- usleep(1000);
-
- for (size_t i = 0; i < sizeof(backlight_init_table); i+=2) {
- if(i2c_transact_sync(&display->i2c, 0, &backlight_init_table[i], 2, NULL, 0) != ZX_OK) {
- DISP_ERROR("Backlight write failed: reg[0x%x]: 0x%x\n", backlight_init_table[i],
- backlight_init_table[i+1]);
- }
+static zx_status_t populate_init_config(astro_display_t* display) {
+ display->disp_setting = calloc(1, sizeof(struct display_setting));
+ if (!display->disp_setting) {
+ DISP_ERROR("Could not allocate disp_setting structure.\n");
+ return ZX_ERR_NO_MEMORY;
}
-}
-static void config_canvas(astro_display_t* display) {
- uint32_t fbh = display->disp_info.height * 2;
- uint32_t fbw = display->disp_info.stride * 2;
+ display->lcd_clk_cfg = calloc(1, sizeof(struct lcd_clk_config));
+ if (!display->lcd_clk_cfg) {
+ DISP_ERROR("Could not allocate lcd_clk_config structure\n");
+ return ZX_ERR_NO_MEMORY;
+ }
- DISP_INFO("Canvas Diminsions: w=%d h=%d\n", fbw, fbh);
+ memcpy(display->disp_setting, &g_disp_setting, sizeof(struct display_setting));
+ memcpy(display->lcd_clk_cfg, &g_lcd_clk_cfg, sizeof(struct lcd_clk_config));
- // set framebuffer address in DMC, read/modify/write
- WRITE32_DMC_REG(DMC_CAV_LUT_DATAL,
- (((io_buffer_phys(&display->fbuffer) + 7) >> 3) & DMC_CAV_ADDR_LMASK) |
- ((((fbw + 7) >> 3) & DMC_CAV_WIDTH_LMASK) << DMC_CAV_WIDTH_LBIT));
-
- WRITE32_DMC_REG(DMC_CAV_LUT_DATAH,
- ((((fbw + 7) >> 3) >> DMC_CAV_WIDTH_LWID) << DMC_CAV_WIDTH_HBIT) |
- ((fbh & DMC_CAV_HEIGHT_MASK) << DMC_CAV_HEIGHT_BIT));
-
- WRITE32_DMC_REG(DMC_CAV_LUT_ADDR, DMC_CAV_LUT_ADDR_WR_EN | OSD2_DMC_CAV_INDEX );
- // read a cbus to make sure last write finish.
- READ32_DMC_REG(DMC_CAV_LUT_DATAH);
-
+ return ZX_OK;
}
static zx_status_t setup_display_if(astro_display_t* display) {
@@ -240,6 +241,36 @@
return status;
}
+ // Populated internal structures based on predefined tables
+ if ((status = populate_init_config(display)) != ZX_OK) {
+ DISP_ERROR("populate_init_config failed!\n");
+ return status;
+ }
+
+ // Populate internal LCD timing structure based on predefined tables
+ if ((status = astro_lcd_timing(display)) != ZX_OK) {
+ DISP_ERROR("astro_lcd_timing failed!\n");
+ return status;
+ }
+
+ // Populate internal DSI Config structure based on predefined tables
+ if ((status = astro_dsi_load_config(display)) != ZX_OK) {
+ DISP_ERROR("astro_dsi_load_config failed!\n");
+ return status;
+ }
+
+ // Populate dsi clock related values
+ if ((status = astro_dsi_generate_hpll(display)) != ZX_OK) {
+ DISP_ERROR("astro_dsi_generate_hpll failed!\n");
+ return status;
+ }
+
+ display_clock_init(display);
+ lcd_mipi_phy_set(display, true); // enable mipi-phy
+ aml_dsi_host_on(display);
+
+ // dump_display_info(display);
+
config_canvas(display);
init_backlight(display);
@@ -308,10 +339,38 @@
}
// Map all the various MMIOs
- status = pdev_map_mmio_buffer(&display->pdev, 0, ZX_CACHE_POLICY_UNCACHED_DEVICE,
+ status = pdev_map_mmio_buffer(&display->pdev, MMIO_CANVAS, ZX_CACHE_POLICY_UNCACHED_DEVICE,
&display->mmio_dmc);
if (status != ZX_OK) {
- DISP_ERROR("Could not map display MMIO DC\n");
+ DISP_ERROR("Could not map display MMIO DMC\n");
+ goto fail;
+ }
+
+ status = pdev_map_mmio_buffer(&display->pdev, MMIO_MPI_DSI, ZX_CACHE_POLICY_UNCACHED_DEVICE,
+ &display->mmio_mipi_dsi);
+ if (status != ZX_OK) {
+ DISP_ERROR("Could not map display MMIO MIPI_DSI\n");
+ goto fail;
+ }
+
+ status = pdev_map_mmio_buffer(&display->pdev, MMIO_DSI_PHY, ZX_CACHE_POLICY_UNCACHED_DEVICE,
+ &display->mmio_dsi_phy);
+ if (status != ZX_OK) {
+ DISP_ERROR("Could not map display MMIO DSI PHY\n");
+ goto fail;
+ }
+
+ status = pdev_map_mmio_buffer(&display->pdev, MMIO_HHI, ZX_CACHE_POLICY_UNCACHED_DEVICE,
+ &display->mmio_hhi);
+ if (status != ZX_OK) {
+ DISP_ERROR("Could not map display MMIO HHI\n");
+ goto fail;
+ }
+
+ status = pdev_map_mmio_buffer(&display->pdev, MMIO_VPU, ZX_CACHE_POLICY_UNCACHED_DEVICE,
+ &display->mmio_vpu);
+ if (status != ZX_OK) {
+ DISP_ERROR("Could not map display MMIO VPU\n");
goto fail;
}
diff --git a/system/dev/display/astro-display/astro-display.h b/system/dev/display/astro-display/astro-display.h
index 016047d..2eb4c2c 100644
--- a/system/dev/display/astro-display/astro-display.h
+++ b/system/dev/display/astro-display/astro-display.h
@@ -5,28 +5,67 @@
#pragma once
#include <assert.h>
-#include <ddk/io-buffer.h>
-#include <ddk/protocol/display.h>
-#include <ddk/protocol/gpio.h>
-#include <ddk/protocol/i2c.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <zircon/device/display.h>
+#include <unistd.h>
+#include <threads.h>
+#include <hw/reg.h>
+#include <ddk/binding.h>
+#include <ddk/debug.h>
#include <ddk/device.h>
+#include <ddk/driver.h>
#include <ddk/io-buffer.h>
+#include <ddk/protocol/display.h>
+#include <ddk/protocol/gpio.h>
+#include <ddk/protocol/i2c.h>
#include <ddk/protocol/platform-device.h>
+#include <ddk/protocol/platform-defs.h>
+#include <zircon/device/display.h>
#include <zircon/listnode.h>
#include <zircon/types.h>
-#include <threads.h>
+#include <zircon/assert.h>
+#include <zircon/device/display.h>
+#include <zircon/syscalls.h>
+
+#include "hhi.h"
+#include "dw_dsi.h"
+#include "aml_dsi.h"
#define DISP_ERROR(fmt, ...) zxlogf(ERROR, "[%s %d]" fmt, __func__, __LINE__, ##__VA_ARGS__)
#define DISP_INFO(fmt, ...) zxlogf(INFO, "[%s %d]" fmt, __func__, __LINE__, ##__VA_ARGS__)
#define DISP_TRACE zxlogf(INFO, "[%s %d]\n", __func__, __LINE__)
-#define READ32_DMC_REG(a) readl(io_buffer_virt(&display->mmio_dmc) + a)
-#define WRITE32_DMC_REG(a, v) writel(v, io_buffer_virt(&display->mmio_dmc) + a)
+#define DISPLAY_MASK(start, count) (((1 << (count)) - 1) << (start))
+#define DISPLAY_SET_MASK(mask, start, count, value) \
+ ((mask & ~DISPLAY_MASK(start, count)) | \
+ (((value) << (start)) & DISPLAY_MASK(start, count)))
+
+#define READ32_DMC_REG(a) readl(io_buffer_virt(&display->mmio_dmc) + a)
+#define WRITE32_DMC_REG(a, v) writel(v, io_buffer_virt(&display->mmio_dmc) + a)
+
+#define READ32_MIPI_DSI_REG(a) readl(io_buffer_virt(&display->mmio_mipi_dsi) + a)
+#define WRITE32_MIPI_DSI_REG(a, v) writel(v, io_buffer_virt(&display->mmio_mipi_dsi) + a)
+
+#define READ32_DSI_PHY_REG(a) readl(io_buffer_virt(&display->mmio_dsi_phy) + a)
+#define WRITE32_DSI_PHY_REG(a, v) writel(v, io_buffer_virt(&display->mmio_dsi_phy) + a)
+
+#define READ32_HHI_REG(a) readl(io_buffer_virt(&display->mmio_hhi) + a)
+#define WRITE32_HHI_REG(a, v) writel(v, io_buffer_virt(&display->mmio_hhi) + a)
+
+#define READ32_VPU_REG(a) readl(io_buffer_virt(&display->mmio_vpu) + a)
+#define WRITE32_VPU_REG(a, v) writel(v, io_buffer_virt(&display->mmio_vpu) + a)
+
+#define SET_BIT32(x, dest, value, start, count) \
+ WRITE32_##x##_REG(dest, (READ32_##x##_REG(dest) & ~DISPLAY_MASK(start, count)) | \
+ (((value) << (start)) & DISPLAY_MASK(start, count)))
+
+#define GET_BIT32(x, dest, start, count) \
+ ((READ32_##x##_REG(dest) >> (start)) & ((1 << (count)) - 1))
+
+#define WRITE32_REG(x, a, v) WRITE32_##x##_REG(a, v)
+#define READ32_REG(x, a) READ32_##x##_REG(a)
#define DMC_CAV_LUT_DATAL (0x12 << 2)
@@ -49,6 +88,93 @@
#define OSD2_DMC_CAV_INDEX 0x40
+// Should match display_mmios table in board driver
+enum {
+ MMIO_CANVAS,
+ MMIO_MPI_DSI,
+ MMIO_DSI_PHY,
+ MMIO_HHI,
+ MMIO_VPU,
+};
+
+struct lcd_clk_config { /* unit: kHz */
+ /* IN-OUT parameters */
+ uint32_t fin;
+ uint32_t fout;
+
+ /* pll parameters */
+ uint32_t pll_mode; /* txl */
+ uint32_t od_fb;
+ uint32_t pll_m;
+ uint32_t pll_n;
+ uint32_t pll_fvco;
+ uint32_t pll_od1_sel;
+ uint32_t pll_od2_sel;
+ uint32_t pll_od3_sel;
+ uint32_t pll_pi_div_sel; /* txhd */
+ uint32_t pll_level;
+ uint32_t pll_frac;
+ uint32_t pll_fout;
+ uint32_t ss_level;
+ uint32_t div_sel;
+ uint32_t xd;
+
+ /* clk path node parameters */
+ uint32_t ss_level_max;
+ uint32_t pll_m_max;
+ uint32_t pll_m_min;
+ uint32_t pll_n_max;
+ uint32_t pll_n_min;
+ uint32_t pll_frac_range;
+ uint32_t pll_od_sel_max;
+ uint32_t div_sel_max;
+ uint32_t xd_max;
+ uint32_t pll_ref_fmax;
+ uint32_t pll_ref_fmin;
+ uint32_t pll_vco_fmax;
+ uint32_t pll_vco_fmin;
+ uint32_t pll_out_fmax;
+ uint32_t pll_out_fmin;
+ uint32_t div_in_fmax;
+ uint32_t div_out_fmax;
+ uint32_t xd_out_fmax;
+ uint32_t err_fmin;
+};
+
+/* This structure is populated based on hardware/lcd type. Its values come from vendor.
+ * This table is the top level structure used to populated all Clocks/LCD/DSI/BackLight/etc
+ * values
+ */
+struct display_setting {
+ // DSI/LCD Timings
+ uint32_t lcd_bits;
+ uint32_t hActive;
+ uint32_t vActive;
+ uint32_t hPeriod;
+ uint32_t vPeriod;
+ uint32_t hSync_width;
+ uint32_t hSync_backPorch;
+ uint32_t hSync_pol;
+ uint32_t vSync_width;
+ uint32_t vSync_backPorch;
+ uint32_t vSync_pol;
+
+ // LCD configs
+ uint32_t fr_adj_type;
+ uint32_t ss_level;
+ uint32_t clk_auto_gen;
+ uint32_t lcd_clock;
+
+ // MIPI/DSI configs
+ uint32_t lane_num;
+ uint32_t bit_rate_max;
+ uint32_t factor_numerator;
+ uint32_t opp_mode_init;
+ uint32_t opp_mode_display;
+ uint32_t video_mode_type;
+ uint32_t clk_always_hs;
+ uint32_t phy_switch;
+};
typedef struct {
zx_device_t* zxdev;
@@ -64,9 +190,20 @@
thrd_t main_thread;
io_buffer_t mmio_dmc;
+ io_buffer_t mmio_mipi_dsi;
+ io_buffer_t mmio_dsi_phy;
+ io_buffer_t mmio_hhi;
+ io_buffer_t mmio_vpu;
io_buffer_t fbuffer;
zx_display_info_t disp_info;
+ lcd_timing_t* lcd_timing;
+ dsi_config_t* dsi_cfg;
+ dsi_phy_config_t* dsi_phy_cfg;
+ dsi_video_t* dsi_vid;
+ struct display_setting* disp_setting;
+ struct lcd_clk_config* lcd_clk_cfg;
+
uint8_t input_color_format;
uint8_t output_color_format;
uint8_t color_depth;
@@ -77,3 +214,13 @@
} astro_display_t;
+void init_backlight(astro_display_t* display);
+void config_canvas(astro_display_t* display);
+zx_status_t astro_lcd_timing(astro_display_t* display);
+zx_status_t astro_dsi_generate_hpll(astro_display_t* display);
+zx_status_t astro_dsi_load_config(astro_display_t* display);
+void dump_display_info(astro_display_t* display);
+
+zx_status_t display_clock_init(astro_display_t* display);
+void lcd_mipi_phy_set(astro_display_t* display, bool enable);
+zx_status_t aml_dsi_host_on(astro_display_t* display);
\ No newline at end of file
diff --git a/system/dev/display/astro-display/backlight.c b/system/dev/display/astro-display/backlight.c
new file mode 100644
index 0000000..cef16b2
--- /dev/null
+++ b/system/dev/display/astro-display/backlight.c
@@ -0,0 +1,34 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "astro-display.h"
+
+/* Table from Linux source */
+/* TODO: Need to separate backlight driver from display driver */
+static const uint8_t backlight_init_table[] = {
+ 0xa2, 0x20,
+ 0xa5, 0x54,
+ 0x00, 0xff,
+ 0x01, 0x05,
+ 0xa2, 0x20,
+ 0xa5, 0x54,
+ 0xa1, 0xb7,
+ 0xa0, 0xff,
+ 0x00, 0x80,
+};
+
+void init_backlight(astro_display_t* display) {
+
+ // power on backlight
+ gpio_config(&display->gpio, 0, GPIO_DIR_OUT);
+ gpio_write(&display->gpio, 0, 1);
+ usleep(1000);
+
+ for (size_t i = 0; i < sizeof(backlight_init_table); i+=2) {
+ if(i2c_transact_sync(&display->i2c, 0, &backlight_init_table[i], 2, NULL, 0) != ZX_OK) {
+ DISP_ERROR("Backlight write failed: reg[0x%x]: 0x%x\n", backlight_init_table[i],
+ backlight_init_table[i+1]);
+ }
+ }
+}
diff --git a/system/dev/display/astro-display/canvas.c b/system/dev/display/astro-display/canvas.c
new file mode 100644
index 0000000..3afa045
--- /dev/null
+++ b/system/dev/display/astro-display/canvas.c
@@ -0,0 +1,26 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "astro-display.h"
+
+void config_canvas(astro_display_t* display) {
+ uint32_t fbh = display->disp_info.height * 2;
+ uint32_t fbw = display->disp_info.stride * 2;
+
+ DISP_INFO("Canvas Diminsions: w=%d h=%d\n", fbw, fbh);
+
+ // set framebuffer address in DMC, read/modify/write
+ WRITE32_DMC_REG(DMC_CAV_LUT_DATAL,
+ (((io_buffer_phys(&display->fbuffer) + 7) >> 3) & DMC_CAV_ADDR_LMASK) |
+ ((((fbw + 7) >> 3) & DMC_CAV_WIDTH_LMASK) << DMC_CAV_WIDTH_LBIT));
+
+ WRITE32_DMC_REG(DMC_CAV_LUT_DATAH,
+ ((((fbw + 7) >> 3) >> DMC_CAV_WIDTH_LWID) << DMC_CAV_WIDTH_HBIT) |
+ ((fbh & DMC_CAV_HEIGHT_MASK) << DMC_CAV_HEIGHT_BIT));
+
+ WRITE32_DMC_REG(DMC_CAV_LUT_ADDR, DMC_CAV_LUT_ADDR_WR_EN | OSD2_DMC_CAV_INDEX );
+ // read a cbus to make sure last write finish.
+ READ32_DMC_REG(DMC_CAV_LUT_DATAH);
+
+}
diff --git a/system/dev/display/astro-display/display_clock.c b/system/dev/display/astro-display/display_clock.c
new file mode 100644
index 0000000..abc36cf
--- /dev/null
+++ b/system/dev/display/astro-display/display_clock.c
@@ -0,0 +1,329 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "astro-display.h"
+
+/************************************************************************************************/
+/* VENC Related Configs */
+/************************************************************************************************/
+
+#define STV2_SEL 5
+#define STV1_SEL 4
+static void lcd_encl_tcon_set(astro_display_t* display)
+{
+
+ WRITE32_REG(VPU, L_RGB_BASE_ADDR, 0);
+ WRITE32_REG(VPU, L_RGB_COEFF_ADDR, 0x400);
+
+ switch (display->lcd_timing->lcd_bits) {
+ case 6:
+ WRITE32_REG(VPU, L_DITH_CNTL_ADDR, 0x600);
+ break;
+ case 8:
+ WRITE32_REG(VPU, L_DITH_CNTL_ADDR, 0x400);
+ break;
+ case 10:
+ default:
+ WRITE32_REG(VPU, L_DITH_CNTL_ADDR, 0x0);
+ break;
+ }
+
+ /* DE signal for TTL m8,m8m2 */
+ WRITE32_REG(VPU, L_OEH_HS_ADDR, display->lcd_timing->de_hs_addr);
+ WRITE32_REG(VPU, L_OEH_HE_ADDR, display->lcd_timing->de_he_addr);
+ WRITE32_REG(VPU, L_OEH_VS_ADDR, display->lcd_timing->de_vs_addr);
+ WRITE32_REG(VPU, L_OEH_VE_ADDR, display->lcd_timing->de_ve_addr);
+ /* DE signal for TTL m8b */
+ WRITE32_REG(VPU, L_OEV1_HS_ADDR, display->lcd_timing->de_hs_addr);
+ WRITE32_REG(VPU, L_OEV1_HE_ADDR, display->lcd_timing->de_he_addr);
+ WRITE32_REG(VPU, L_OEV1_VS_ADDR, display->lcd_timing->de_vs_addr);
+ WRITE32_REG(VPU, L_OEV1_VE_ADDR, display->lcd_timing->de_ve_addr);
+
+ /* Hsync signal for TTL m8,m8m2 */
+ if (display->lcd_timing->hSync_pol == 0) {
+ WRITE32_REG(VPU, L_STH1_HS_ADDR, display->lcd_timing->hs_he_addr);
+ WRITE32_REG(VPU, L_STH1_HE_ADDR, display->lcd_timing->hs_hs_addr);
+ } else {
+ WRITE32_REG(VPU, L_STH1_HS_ADDR, display->lcd_timing->hs_hs_addr);
+ WRITE32_REG(VPU, L_STH1_HE_ADDR, display->lcd_timing->hs_he_addr);
+ }
+ WRITE32_REG(VPU, L_STH1_VS_ADDR, display->lcd_timing->hs_vs_addr);
+ WRITE32_REG(VPU, L_STH1_VE_ADDR, display->lcd_timing->hs_ve_addr);
+
+ /* Vsync signal for TTL m8,m8m2 */
+ WRITE32_REG(VPU, L_STV1_HS_ADDR, display->lcd_timing->vs_hs_addr);
+ WRITE32_REG(VPU, L_STV1_HE_ADDR, display->lcd_timing->vs_he_addr);
+ if (display->lcd_timing->vSync_pol == 0) {
+ WRITE32_REG(VPU, L_STV1_VS_ADDR, display->lcd_timing->vs_ve_addr);
+ WRITE32_REG(VPU, L_STV1_VE_ADDR, display->lcd_timing->vs_vs_addr);
+ } else {
+ WRITE32_REG(VPU, L_STV1_VS_ADDR, display->lcd_timing->vs_vs_addr);
+ WRITE32_REG(VPU, L_STV1_VE_ADDR, display->lcd_timing->vs_ve_addr);
+ }
+
+ /* DE signal */
+ WRITE32_REG(VPU, L_DE_HS_ADDR, display->lcd_timing->de_hs_addr);
+ WRITE32_REG(VPU, L_DE_HE_ADDR, display->lcd_timing->de_he_addr);
+ WRITE32_REG(VPU, L_DE_VS_ADDR, display->lcd_timing->de_vs_addr);
+ WRITE32_REG(VPU, L_DE_VE_ADDR, display->lcd_timing->de_ve_addr);
+
+ /* Hsync signal */
+ WRITE32_REG(VPU, L_HSYNC_HS_ADDR, display->lcd_timing->hs_hs_addr);
+ WRITE32_REG(VPU, L_HSYNC_HE_ADDR, display->lcd_timing->hs_he_addr);
+ WRITE32_REG(VPU, L_HSYNC_VS_ADDR, display->lcd_timing->hs_vs_addr);
+ WRITE32_REG(VPU, L_HSYNC_VE_ADDR, display->lcd_timing->hs_ve_addr);
+
+ /* Vsync signal */
+ WRITE32_REG(VPU, L_VSYNC_HS_ADDR, display->lcd_timing->vs_hs_addr);
+ WRITE32_REG(VPU, L_VSYNC_HE_ADDR, display->lcd_timing->vs_he_addr);
+ WRITE32_REG(VPU, L_VSYNC_VS_ADDR, display->lcd_timing->vs_vs_addr);
+ WRITE32_REG(VPU, L_VSYNC_VE_ADDR, display->lcd_timing->vs_ve_addr);
+
+ WRITE32_REG(VPU, L_INV_CNT_ADDR, 0);
+ WRITE32_REG(VPU, L_TCON_MISC_SEL_ADDR, ((1 << STV1_SEL) | (1 << STV2_SEL)));
+
+ WRITE32_REG(VPU, VPP_MISC, READ32_REG(VPU, VPP_MISC) & ~(VPP_OUT_SATURATE));
+}
+
+static void lcd_venc_set(astro_display_t* display)
+{
+ unsigned int h_active, v_active;
+ unsigned int video_on_pixel, video_on_line;
+
+ h_active = display->lcd_timing->h_active;
+ v_active = display->lcd_timing->v_active;
+ video_on_pixel = display->lcd_timing->vid_pixel_on;
+ video_on_line = display->lcd_timing->vid_line_on;
+
+ WRITE32_REG(VPU, ENCL_VIDEO_EN, 0);
+
+ WRITE32_REG(VPU, VPU_VIU_VENC_MUX_CTRL, (0 << 0) | (0 << 2)); // viu1 select encl | viu2 select encl
+ WRITE32_REG(VPU, ENCL_VIDEO_MODE, 0x8000); // bit[15] shadown en
+ WRITE32_REG(VPU, ENCL_VIDEO_MODE_ADV, 0x0418); // Sampling rate: 1
+
+ // bypass filter
+ WRITE32_REG(VPU, ENCL_VIDEO_FILT_CTRL, 0x1000);
+ WRITE32_REG(VPU, ENCL_VIDEO_MAX_PXCNT, display->lcd_timing->h_period - 1);
+ WRITE32_REG(VPU, ENCL_VIDEO_MAX_LNCNT, display->lcd_timing->v_period - 1);
+ WRITE32_REG(VPU, ENCL_VIDEO_HAVON_BEGIN, video_on_pixel);
+ WRITE32_REG(VPU, ENCL_VIDEO_HAVON_END, h_active - 1 + video_on_pixel);
+ WRITE32_REG(VPU, ENCL_VIDEO_VAVON_BLINE, video_on_line);
+ WRITE32_REG(VPU, ENCL_VIDEO_VAVON_ELINE, v_active - 1 + video_on_line);
+
+ WRITE32_REG(VPU, ENCL_VIDEO_HSO_BEGIN, display->lcd_timing->hs_hs_addr);
+ WRITE32_REG(VPU, ENCL_VIDEO_HSO_END, display->lcd_timing->hs_he_addr);
+ WRITE32_REG(VPU, ENCL_VIDEO_VSO_BEGIN, display->lcd_timing->vs_hs_addr);
+ WRITE32_REG(VPU, ENCL_VIDEO_VSO_END, display->lcd_timing->vs_he_addr);
+ WRITE32_REG(VPU, ENCL_VIDEO_VSO_BLINE, display->lcd_timing->vs_vs_addr);
+ WRITE32_REG(VPU, ENCL_VIDEO_VSO_ELINE, display->lcd_timing->vs_ve_addr);
+ WRITE32_REG(VPU, ENCL_VIDEO_RGBIN_CTRL, 3);
+
+ WRITE32_REG(VPU, ENCL_VIDEO_EN, 1);
+}
+
+
+/************************************************************************************************/
+/* PLL / CLOCK Related Configs */
+/************************************************************************************************/
+static unsigned int lcd_clk_div_g9_gxtvbb[][3] = {
+ /* divider, shift_val, shift_sel */
+ {CLK_DIV_SEL_1, 0xffff, 0,},
+ {CLK_DIV_SEL_2, 0x0aaa, 0,},
+ {CLK_DIV_SEL_3, 0x0db6, 0,},
+ {CLK_DIV_SEL_3p5, 0x36cc, 1,},
+ {CLK_DIV_SEL_3p75, 0x6666, 2,},
+ {CLK_DIV_SEL_4, 0x0ccc, 0,},
+ {CLK_DIV_SEL_5, 0x739c, 2,},
+ {CLK_DIV_SEL_6, 0x0e38, 0,},
+ {CLK_DIV_SEL_6p25, 0x0000, 3,},
+ {CLK_DIV_SEL_7, 0x3c78, 1,},
+ {CLK_DIV_SEL_7p5, 0x78f0, 2,},
+ {CLK_DIV_SEL_12, 0x0fc0, 0,},
+ {CLK_DIV_SEL_14, 0x3f80, 1,},
+ {CLK_DIV_SEL_15, 0x7f80, 2,},
+ {CLK_DIV_SEL_2p5, 0x5294, 2,},
+ {CLK_DIV_SEL_MAX, 0xffff, 0,},
+};
+
+static void lcd_set_vclk_crt(astro_display_t* display)
+{
+ struct lcd_clk_config *cConf = display->lcd_clk_cfg;
+
+ /* setup the XD divider value */
+ SET_BIT32(HHI, HHI_VIID_CLK_DIV, (cConf->xd-1), VCLK2_XD, 8);
+ usleep(5);
+
+ /* select vid_pll_clk */
+ SET_BIT32(HHI, HHI_VIID_CLK_CNTL, 0, VCLK2_CLK_IN_SEL, 3);
+ SET_BIT32(HHI, HHI_VIID_CLK_CNTL, 1, VCLK2_EN, 1);
+ usleep(2);
+
+ /* [15:12] encl_clk_sel, select vclk2_div1 */
+ SET_BIT32(HHI, HHI_VIID_CLK_DIV, 8, ENCL_CLK_SEL, 4);
+ /* release vclk2_div_reset and enable vclk2_div */
+ SET_BIT32(HHI, HHI_VIID_CLK_DIV, 1, VCLK2_XD_EN, 2);
+ usleep(5);
+
+ SET_BIT32(HHI, HHI_VIID_CLK_CNTL, 1, VCLK2_DIV1_EN, 1);
+ SET_BIT32(HHI, HHI_VIID_CLK_CNTL, 1, VCLK2_SOFT_RST, 1);
+ usleep(10);
+ SET_BIT32(HHI, HHI_VIID_CLK_CNTL, 0, VCLK2_SOFT_RST, 1);
+ usleep(5);
+
+ /* enable CTS_ENCL clk gate */
+ SET_BIT32(HHI, HHI_VID_CLK_CNTL2, 1, ENCL_GATE_VCLK, 1);
+}
+
+static void lcd_set_vid_pll_div(astro_display_t* display)
+{
+ unsigned int shift_val, shift_sel;
+ int i;
+ struct lcd_clk_config *cConf = display->lcd_clk_cfg;
+
+ SET_BIT32(HHI, HHI_VIID_CLK_CNTL, 0, VCLK2_EN, 1);
+ usleep(5);
+
+ /* Disable the div output clock */
+ SET_BIT32(HHI, HHI_VID_PLL_CLK_DIV, 0, 19, 1);
+ SET_BIT32(HHI, HHI_VID_PLL_CLK_DIV, 0, 15, 1);
+
+ i = 0;
+ while (lcd_clk_div_g9_gxtvbb[i][0] != CLK_DIV_SEL_MAX) {
+ if (cConf->div_sel == lcd_clk_div_g9_gxtvbb[i][0])
+ break;
+ i++;
+ }
+ if (lcd_clk_div_g9_gxtvbb[i][0] == CLK_DIV_SEL_MAX)
+ DISP_ERROR("invalid clk divider\n");
+ shift_val = lcd_clk_div_g9_gxtvbb[i][1];
+ shift_sel = lcd_clk_div_g9_gxtvbb[i][2];
+
+ if (shift_val == 0xffff) { /* if divide by 1 */
+ SET_BIT32(HHI, HHI_VID_PLL_CLK_DIV, 1, 18, 1);
+ } else {
+ SET_BIT32(HHI, HHI_VID_PLL_CLK_DIV, 0, 18, 1);
+ SET_BIT32(HHI, HHI_VID_PLL_CLK_DIV, 0, 16, 2);
+ SET_BIT32(HHI, HHI_VID_PLL_CLK_DIV, 0, 15, 1);
+ SET_BIT32(HHI, HHI_VID_PLL_CLK_DIV, 0, 0, 14);
+
+ SET_BIT32(HHI, HHI_VID_PLL_CLK_DIV, shift_sel, 16, 2);
+ SET_BIT32(HHI, HHI_VID_PLL_CLK_DIV, 1, 15, 1);
+ SET_BIT32(HHI, HHI_VID_PLL_CLK_DIV, shift_val, 0, 14);
+ SET_BIT32(HHI, HHI_VID_PLL_CLK_DIV, 0, 15, 1);
+ }
+ /* Enable the final output clock */
+ SET_BIT32(HHI, HHI_VID_PLL_CLK_DIV, 1, 19, 1);
+}
+
+#define PLL_WAIT_LOCK_CNT_G12A 1000
+static int lcd_pll_wait_lock_g12a(astro_display_t* display)
+{
+ // uint32_t pll_ctrl, pll_ctrl3, pll_ctrl6;
+ uint32_t pll_lock;
+ int wait_loop = PLL_WAIT_LOCK_CNT_G12A; /* 200 */
+ zx_status_t status = ZX_OK;
+
+ // pll_ctrl = HHI_HDMI_PLL_CNTL0;
+ // pll_ctrl3 = HHI_HDMI_PLL_CNTL3;
+ // pll_ctrl6 = HHI_HDMI_PLL_CNTL6;
+ do {
+ usleep(50);
+ pll_lock = GET_BIT32(HHI, HHI_HDMI_PLL_CNTL0, 31, 1);
+ wait_loop--;
+ } while ((pll_lock != 1) && (wait_loop > 0));
+
+ if (pll_lock == 1) {
+ goto pll_lock_end_g12a;
+ } else {
+ DISP_ERROR("pll try 1, lock: %d\n", pll_lock);
+ SET_BIT32(HHI, HHI_HDMI_PLL_CNTL3, 1, 31, 1);
+ wait_loop = PLL_WAIT_LOCK_CNT_G12A;
+ do {
+ usleep(50);
+ pll_lock = GET_BIT32(HHI, HHI_HDMI_PLL_CNTL0, 31, 1);
+ wait_loop--;
+ } while ((pll_lock != 1) && (wait_loop > 0));
+ }
+
+ if (pll_lock == 1) {
+ goto pll_lock_end_g12a;
+ } else {
+ DISP_ERROR("pll try 2, lock: %d\n", pll_lock);
+ WRITE32_REG(HHI, HHI_HDMI_PLL_CNTL6, 0x55540000);
+ wait_loop = PLL_WAIT_LOCK_CNT_G12A;
+ do {
+ usleep(50);
+ pll_lock = GET_BIT32(HHI, HHI_HDMI_PLL_CNTL0, 31, 1);
+ wait_loop--;
+ } while ((pll_lock != 1) && (wait_loop > 0));
+ }
+
+ if (pll_lock != 1)
+ status = ZX_ERR_CALL_FAILED;
+
+pll_lock_end_g12a:
+ DISP_ERROR("pll_lock=%d, wait_loop=%d\n", pll_lock, (PLL_WAIT_LOCK_CNT_G12A - wait_loop));
+ return status;
+}
+
+zx_status_t display_clock_init(astro_display_t* display) {
+ zx_status_t status = ZX_OK;
+ uint32_t pll_ctrl, pll_ctrl1, pll_ctrl3, pll_ctrl4, pll_ctrl6;
+ struct lcd_clk_config *cConf = display->lcd_clk_cfg;
+
+ pll_ctrl = ((1 << LCD_PLL_EN_HPLL_G12A) |
+ (1 << 25) | /* clk out gate */
+ (cConf->pll_n << LCD_PLL_N_HPLL_G12A) |
+ (cConf->pll_m << LCD_PLL_M_HPLL_G12A) |
+ (cConf->pll_od1_sel << LCD_PLL_OD1_HPLL_G12A) |
+ (cConf->pll_od2_sel << LCD_PLL_OD2_HPLL_G12A) |
+ (cConf->pll_od3_sel << LCD_PLL_OD3_HPLL_G12A));
+ pll_ctrl1 = (cConf->pll_frac << 0);
+ if (cConf->pll_frac) {
+ pll_ctrl |= (1 << 27);
+ pll_ctrl3 = 0x6a285c00;
+ pll_ctrl4 = 0x65771290;
+ pll_ctrl6 = 0x56540000;
+ } else {
+ pll_ctrl3 = 0x48681c00;
+ pll_ctrl4 = 0x33771290;
+ pll_ctrl6 = 0x56540000;
+ }
+
+ WRITE32_REG(HHI, HHI_HDMI_PLL_CNTL0, pll_ctrl);
+ WRITE32_REG(HHI, HHI_HDMI_PLL_CNTL1, pll_ctrl1);
+ WRITE32_REG(HHI, HHI_HDMI_PLL_CNTL2, 0x00);
+ WRITE32_REG(HHI, HHI_HDMI_PLL_CNTL3, pll_ctrl3);
+ WRITE32_REG(HHI, HHI_HDMI_PLL_CNTL4, pll_ctrl4);
+ WRITE32_REG(HHI, HHI_HDMI_PLL_CNTL5, 0x39272000);
+ WRITE32_REG(HHI, HHI_HDMI_PLL_CNTL6, pll_ctrl6);
+ SET_BIT32(HHI, HHI_HDMI_PLL_CNTL0, 1, LCD_PLL_RST_HPLL_G12A, 1);
+ usleep(100);
+ SET_BIT32(HHI, HHI_HDMI_PLL_CNTL0, 0, LCD_PLL_RST_HPLL_G12A, 1);
+
+ status = lcd_pll_wait_lock_g12a(display);
+ if (status != ZX_OK) {
+ DISP_ERROR("hpll lock failed\n");
+ goto exit;
+ }
+
+ lcd_set_vid_pll_div(display);
+
+ SET_BIT32(HHI, HHI_VDIN_MEAS_CLK_CNTL, 0, 21, 3);
+ SET_BIT32(HHI, HHI_VDIN_MEAS_CLK_CNTL, 0, 12, 7);
+ SET_BIT32(HHI, HHI_VDIN_MEAS_CLK_CNTL, 1, 20, 1);
+
+ SET_BIT32(HHI, HHI_MIPIDSI_PHY_CLK_CNTL, 0, 12, 3);
+ SET_BIT32(HHI, HHI_MIPIDSI_PHY_CLK_CNTL, 1, 8, 1);
+ SET_BIT32(HHI, HHI_MIPIDSI_PHY_CLK_CNTL, 0, 0, 7);
+
+ lcd_set_vclk_crt(display);
+ usleep(10000);
+
+ lcd_venc_set(display);
+ lcd_encl_tcon_set(display);
+
+exit:
+ return status;
+}
\ No newline at end of file
diff --git a/system/dev/display/astro-display/display_config.c b/system/dev/display/astro-display/display_config.c
new file mode 100644
index 0000000..d63b000
--- /dev/null
+++ b/system/dev/display/astro-display/display_config.c
@@ -0,0 +1,339 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "astro-display.h"
+
+static const unsigned int od_fb_table[2] = {1, 2};
+static const unsigned int od_table[6] = {
+ 1, 2, 4, 8, 16, 32
+};
+
+static int check_pll(struct lcd_clk_config *cConf,
+ unsigned int pll_fout)
+{
+ unsigned int m, n;
+ unsigned int od1_sel, od2_sel, od3_sel, od1, od2, od3;
+ unsigned int pll_fod2_in, pll_fod3_in, pll_fvco;
+ unsigned int od_fb = 0, pll_frac;
+ int done;
+
+ done = 0;
+ if ((pll_fout > cConf->pll_out_fmax) ||
+ (pll_fout < cConf->pll_out_fmin)) {
+ return done;
+ }
+ for (od3_sel = cConf->pll_od_sel_max; od3_sel > 0; od3_sel--) {
+ od3 = od_table[od3_sel - 1];
+ pll_fod3_in = pll_fout * od3;
+ for (od2_sel = od3_sel; od2_sel > 0; od2_sel--) {
+ od2 = od_table[od2_sel - 1];
+ pll_fod2_in = pll_fod3_in * od2;
+ for (od1_sel = od2_sel; od1_sel > 0; od1_sel--) {
+ od1 = od_table[od1_sel - 1];
+ pll_fvco = pll_fod2_in * od1;
+ if ((pll_fvco < cConf->pll_vco_fmin) ||
+ (pll_fvco > cConf->pll_vco_fmax)) {
+ continue;
+ }
+ cConf->pll_od1_sel = od1_sel - 1;
+ cConf->pll_od2_sel = od2_sel - 1;
+ cConf->pll_od3_sel = od3_sel - 1;
+ cConf->pll_fout = pll_fout;
+ cConf->pll_fvco = pll_fvco;
+ n = 1;
+ od_fb = cConf->od_fb;
+ pll_fvco = pll_fvco / od_fb_table[od_fb];
+ m = pll_fvco / cConf->fin;
+ pll_frac = (pll_fvco % cConf->fin) *
+ cConf->pll_frac_range / cConf->fin;
+ cConf->pll_m = m;
+ cConf->pll_n = n;
+ cConf->pll_frac = pll_frac;
+ done = 1;
+ break;
+ }
+ }
+ }
+ return done;
+}
+
+zx_status_t astro_dsi_generate_hpll(astro_display_t* display) {
+ uint32_t dsi_bit_rate_min = 0;
+ uint32_t dsi_bit_rate_max = 0;
+ uint32_t tmp;
+ uint32_t pll_fout;
+ uint32_t clk_div_sel, xd;
+ int done;
+
+ ZX_DEBUG_ASSERT(display);
+ ZX_DEBUG_ASSERT(display->dsi_cfg);
+ ZX_DEBUG_ASSERT(display->lcd_clk_cfg);
+
+ display->lcd_clk_cfg->fout = display->lcd_timing->lcd_clock / 1000; // KHz
+ display->lcd_clk_cfg->err_fmin = MAX_ERROR;
+ if (display->lcd_clk_cfg->fout > display->lcd_clk_cfg->xd_out_fmax) {
+ DISP_ERROR("Invalid LCD Clock value %dKHz\n", display->lcd_clk_cfg->fout);
+ return ZX_ERR_OUT_OF_RANGE;
+ }
+
+ display->lcd_clk_cfg->xd_max = CRT_VID_DIV_MAX;
+ tmp = display->dsi_cfg->bit_rate_max;
+ dsi_bit_rate_max = tmp * 1000; // change to KHz
+ dsi_bit_rate_min = dsi_bit_rate_max - display->lcd_clk_cfg->fout;
+
+ clk_div_sel = CLK_DIV_SEL_1;
+ for (xd = 1; xd <= display->lcd_clk_cfg->xd_max; xd++) {
+ pll_fout = display->lcd_clk_cfg->fout * xd;
+ if ((pll_fout > dsi_bit_rate_max) || (pll_fout < dsi_bit_rate_min)) {
+ continue;
+ }
+ display->dsi_cfg->bit_rate = pll_fout * 1000;
+ display->dsi_cfg->clock_factor = xd;
+ display->lcd_clk_cfg->xd = xd;
+ display->lcd_clk_cfg->div_sel = clk_div_sel;
+ done = check_pll(display->lcd_clk_cfg, pll_fout);
+ if (done) {
+ goto generate_clk_done;
+ }
+ }
+
+generate_clk_done:
+ if (done) {
+ display->lcd_timing->pll_ctrl =
+ (display->lcd_clk_cfg->pll_od1_sel << PLL_CTRL_OD1) |
+ (display->lcd_clk_cfg->pll_od2_sel << PLL_CTRL_OD2) |
+ (display->lcd_clk_cfg->pll_od3_sel << PLL_CTRL_OD3) |
+ (display->lcd_clk_cfg->pll_n << PLL_CTRL_N) |
+ (display->lcd_clk_cfg->pll_m << PLL_CTRL_M);
+ display->lcd_timing->div_ctrl =
+ (display->lcd_clk_cfg->div_sel << DIV_CTRL_DIV_SEL) |
+ (display->lcd_clk_cfg->xd << DIV_CTRL_XD);
+ display->lcd_timing->clk_ctrl = (display->lcd_clk_cfg->pll_frac << CLK_CTRL_FRAC);
+ } else {
+ display->lcd_timing->pll_ctrl =
+ (1 << PLL_CTRL_OD1) |
+ (1 << PLL_CTRL_OD2) |
+ (1 << PLL_CTRL_OD3) |
+ (1 << PLL_CTRL_N) |
+ (50 << PLL_CTRL_M);
+ display->lcd_timing->div_ctrl =
+ (CLK_DIV_SEL_1 << DIV_CTRL_DIV_SEL) |
+ (7 << DIV_CTRL_XD);
+ display->lcd_timing->clk_ctrl = (0 << CLK_CTRL_FRAC);
+ DISP_ERROR("Out of clock range, reset to default setting\n");
+ }
+
+ display->lcd_clk_cfg->ss_level =
+ (display->lcd_timing->ss_level > display->lcd_clk_cfg->ss_level_max)?
+ 0 : display->lcd_timing->ss_level;
+
+ return ZX_OK;
+}
+
+zx_status_t astro_dsi_load_config(astro_display_t* display) {
+ zx_status_t status = ZX_OK;
+
+ ZX_DEBUG_ASSERT(display);
+
+ if (!display->disp_setting) {
+ DISP_ERROR("Display Configuration has not been populated! Exiting.\n");
+ return ZX_ERR_UNAVAILABLE;
+ }
+
+ if (!display->lcd_clk_cfg) {
+ DISP_ERROR("LCD Clock/PLL Configuration has not been populated! Exiting.\n");
+ return ZX_ERR_UNAVAILABLE;
+ }
+
+ // lcd timing should already be populated
+ if(!display->lcd_timing) {
+ DISP_ERROR("LCD Timing structure has not been populated! Exiting.\n");
+ return ZX_ERR_UNAVAILABLE;
+ }
+
+ // allocate dsi config structure
+ if (display->dsi_cfg != NULL) {
+ DISP_INFO("Re-Populating MIPI DSI Config parameters\n");
+ memset(display->dsi_cfg, 0, sizeof(dsi_config_t));
+ } else {
+ display->dsi_cfg = calloc(1, sizeof(dsi_config_t));
+ if (!display->dsi_cfg) {
+ DISP_ERROR("Could not allocate dsi_config structure\n");
+ return ZX_ERR_NO_MEMORY;
+ }
+ }
+
+ // allocate dsi phy config here as well
+ if (display->dsi_phy_cfg != NULL) {
+ DISP_INFO("Re-Populating MIPI DSI PHY Config parameters\n");
+ memset(display->dsi_phy_cfg, 0, sizeof(dsi_phy_config_t));
+ } else {
+ display->dsi_phy_cfg = calloc(1, sizeof(dsi_phy_config_t));
+ if (!display->dsi_phy_cfg) {
+ DISP_ERROR("Could not allocate dsi_phy_cfg structure\n");
+ return ZX_ERR_NO_MEMORY;
+ }
+ }
+
+ display->dsi_cfg->lane_num = display->disp_setting->lane_num;
+ display->dsi_cfg->bit_rate_max = display->disp_setting->bit_rate_max;
+ display->dsi_cfg->factor_numerator = display->disp_setting->factor_numerator;
+ display->dsi_cfg->opp_mode_init = display->disp_setting->opp_mode_init;
+ display->dsi_cfg->opp_mode_display = display->disp_setting->opp_mode_display;
+ display->dsi_cfg->video_mode_type = display->disp_setting->video_mode_type;
+ display->dsi_cfg->clk_always_hs = display->disp_setting->clk_always_hs;
+ display->dsi_cfg->phy_switch = display->disp_setting->phy_switch;
+
+ if (display->lcd_timing->lcd_bits == 8) {
+ display->dsi_cfg->venc_data_width = MIPI_DSI_VENC_COLOR_24B;
+ display->dsi_cfg->dpi_data_format = MIPI_DSI_COLOR_24BIT;
+ } else {
+ DISP_ERROR("Unsupported LCD Bits\n");
+ return ZX_ERR_NOT_SUPPORTED;
+ }
+
+
+ if (display->dsi_cfg->bit_rate_max == 0) {
+ DISP_ERROR("Auto bit rate calculation not supported\n");
+ return ZX_ERR_NOT_SUPPORTED;
+ }
+
+ if (display->dsi_cfg->bit_rate_max < (display->lcd_clk_cfg->pll_out_fmin/1000)) {
+ DISP_ERROR("Bit rate of %dMHz not supported (min = %dMHz)\n",
+ display->dsi_cfg->bit_rate_max, (display->lcd_clk_cfg->pll_out_fmin/1000));
+ return ZX_ERR_OUT_OF_RANGE;
+ }
+
+ if (display->dsi_cfg->bit_rate_max > MIPI_PHY_CLK_MAX) {
+ DISP_ERROR("Bit rate of %dMHz out of range (max = %dMHz)\n",
+ display->dsi_cfg->bit_rate_max, MIPI_PHY_CLK_MAX);
+ return ZX_ERR_OUT_OF_RANGE;
+ }
+
+ /* Venc resolution format */
+ switch (display->disp_setting->phy_switch) {
+ case 1: /* standard */
+ display->dsi_phy_cfg->state_change = 1;
+ break;
+ case 2: /* slow */
+ display->dsi_phy_cfg->state_change = 2;
+ break;
+ case 0: /* auto */
+ default:
+ if ((display->lcd_timing->h_active != 240) &&
+ (display->lcd_timing->h_active != 768) &&
+ (display->lcd_timing->h_active != 1920) &&
+ (display->lcd_timing->h_active != 2560)) {
+ display->dsi_phy_cfg->state_change = 2;
+ } else {
+ display->dsi_phy_cfg->state_change = 1;
+ }
+ break;
+ }
+
+ return status;
+}
+
+zx_status_t astro_lcd_timing(astro_display_t* display) {
+ zx_status_t status = ZX_OK;
+ uint32_t de_hstart, de_vstart;
+ uint32_t hstart, hend, vstart, vend;
+ uint32_t hPeriod, vPeriod, hActive, vActive;
+ uint32_t hSync_backPorch, hSync_width, vSync_width, vSync_backPorch;
+ uint32_t sync_duration;
+ uint32_t clk;
+ ZX_DEBUG_ASSERT(display);
+
+ if (!display->disp_setting) {
+ DISP_ERROR("Display Configuration has not been populated! Exiting.\n");
+ return ZX_ERR_UNAVAILABLE;
+ }
+
+ // allocate lcd_timing structure
+ if (display->lcd_timing != NULL) {
+ DISP_INFO("Re-Populating LCD Timing parameters\n");
+ memset(display->lcd_timing, 0, sizeof(lcd_timing_t));
+ } else {
+ display->lcd_timing = calloc(1, sizeof(lcd_timing_t));
+ if (!display->lcd_timing) {
+ DISP_ERROR("Could not allocate lcd_timing structure\n");
+ return ZX_ERR_NO_MEMORY;
+ }
+ }
+
+ // populate values that match 1:1
+ display->lcd_timing->fr_adj_type = display->disp_setting->fr_adj_type;
+ display->lcd_timing->ss_level = display->disp_setting->ss_level;
+ display->lcd_timing->clk_auto_gen = display->disp_setting->clk_auto_gen;
+ display->lcd_timing->lcd_clock = display->disp_setting->lcd_clock;
+
+ display->lcd_timing->hSync_width = display->disp_setting->hSync_width;
+ display->lcd_timing->hSync_backPorch = display->disp_setting->hSync_backPorch;
+ display->lcd_timing->hSync_pol = display->disp_setting->hSync_pol;
+ display->lcd_timing->vSync_width = display->disp_setting->vSync_width;
+ display->lcd_timing->vSync_backPorch = display->disp_setting->vSync_backPorch;
+ display->lcd_timing->vSync_pol = display->disp_setting->vSync_pol;
+
+ display->lcd_timing->lcd_bits = display->disp_setting->lcd_bits;
+ display->lcd_timing->h_active = display->disp_setting->hActive;
+ display->lcd_timing->v_active = display->disp_setting->vActive;
+ display->lcd_timing->h_period = display->disp_setting->hPeriod;
+ display->lcd_timing->v_period = display->disp_setting->vPeriod;
+
+ clk = display->lcd_timing->lcd_clock;
+
+ if (clk < 200) {
+ sync_duration = clk * 100;
+ display->lcd_timing->lcd_clock = clk * display->lcd_timing->h_period *
+ display->lcd_timing->v_period;
+ } else {
+ sync_duration = ((clk / display->lcd_timing->h_period) * 100) /
+ display->lcd_timing->v_period;
+ }
+
+ display->lcd_timing->lcd_clk_dft = display->lcd_timing->lcd_clock;
+ display->lcd_timing->hPeriod_dft = display->lcd_timing->h_period;
+ display->lcd_timing->vPeriod_dft = display->lcd_timing->v_period;
+ display->lcd_timing->sync_duration_numerator = sync_duration;
+ display->lcd_timing->sync_duration_denominator = 100;
+
+
+ hPeriod = display->lcd_timing->h_period;
+ vPeriod = display->lcd_timing->v_period;
+ hActive = display->lcd_timing->h_active;
+ vActive = display->lcd_timing->v_active;
+
+ hSync_width = display->lcd_timing->hSync_width;
+ hSync_backPorch = display->lcd_timing->hSync_backPorch;
+ vSync_width = display->lcd_timing->vSync_width;
+ vSync_backPorch = display->lcd_timing->vSync_backPorch;
+
+ de_hstart = hPeriod - hActive - 1;
+ de_vstart = vPeriod - vActive;
+
+ display->lcd_timing->vid_pixel_on = de_hstart;
+ display->lcd_timing->vid_line_on = de_vstart;
+
+ display->lcd_timing->de_hs_addr = de_hstart;
+ display->lcd_timing->de_he_addr = de_hstart + hActive;
+ display->lcd_timing->de_vs_addr = de_vstart;
+ display->lcd_timing->de_ve_addr = de_vstart + vActive - 1;
+
+
+ hstart = (de_hstart + hPeriod - hSync_backPorch - hSync_width) % hPeriod;
+ hend = (de_hstart + hPeriod - hSync_backPorch) % hPeriod;
+ display->lcd_timing->hs_hs_addr = hstart;
+ display->lcd_timing->hs_he_addr = hend;
+ display->lcd_timing->hs_vs_addr = 0;
+ display->lcd_timing->hs_ve_addr = vPeriod - 1;
+
+ display->lcd_timing->vs_hs_addr = (hstart + hPeriod) % hPeriod;
+ display->lcd_timing->vs_he_addr = display->lcd_timing->vs_hs_addr;
+ vstart = (de_vstart + vPeriod - vSync_backPorch - vSync_width) % vPeriod;
+ vend = (de_vstart + vPeriod - vSync_backPorch) % vPeriod;
+ display->lcd_timing->vs_vs_addr = vstart;
+ display->lcd_timing->vs_ve_addr = vend;
+
+ return status;
+}
\ No newline at end of file
diff --git a/system/dev/display/astro-display/display_debug.c b/system/dev/display/astro-display/display_debug.c
new file mode 100644
index 0000000..7b21c4a
--- /dev/null
+++ b/system/dev/display/astro-display/display_debug.c
@@ -0,0 +1,194 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "astro-display.h"
+
+void dump_display_info(astro_display_t* display) {
+
+ if (display->lcd_clk_cfg) {
+ DISP_INFO("#############################\n");
+ DISP_INFO("Dumping lcd_clk_cfg structure:\n");
+ DISP_INFO("#############################\n");
+ DISP_INFO("fin = 0x%x (%u)\n", display->lcd_clk_cfg->fin,display->lcd_clk_cfg->fin);
+ DISP_INFO("fout = 0x%x (%u)\n", display->lcd_clk_cfg->fout,display->lcd_clk_cfg->fout);
+ DISP_INFO("pll_mode = 0x%x (%u)\n", display->lcd_clk_cfg->pll_mode,display->lcd_clk_cfg->pll_mode);
+ DISP_INFO("od_fb = 0x%x (%u)\n", display->lcd_clk_cfg->od_fb,display->lcd_clk_cfg->od_fb);
+ DISP_INFO("pll_m = 0x%x (%u)\n", display->lcd_clk_cfg->pll_m,display->lcd_clk_cfg->pll_m);
+ DISP_INFO("pll_n = 0x%x (%u)\n", display->lcd_clk_cfg->pll_n,display->lcd_clk_cfg->pll_n);
+ DISP_INFO("pll_fvco = 0x%x (%u)\n", display->lcd_clk_cfg->pll_fvco,display->lcd_clk_cfg->pll_fvco);
+ DISP_INFO("pll_od1_sel = 0x%x (%u)\n", display->lcd_clk_cfg->pll_od1_sel,display->lcd_clk_cfg->pll_od1_sel);
+ DISP_INFO("pll_od2_sel = 0x%x (%u)\n", display->lcd_clk_cfg->pll_od2_sel,display->lcd_clk_cfg->pll_od2_sel);
+ DISP_INFO("pll_od3_sel = 0x%x (%u)\n", display->lcd_clk_cfg->pll_od3_sel,display->lcd_clk_cfg->pll_od3_sel);
+ DISP_INFO("pll_pi_div_sel = 0x%x (%u)\n", display->lcd_clk_cfg->pll_pi_div_sel,display->lcd_clk_cfg->pll_pi_div_sel);
+ DISP_INFO("pll_level = 0x%x (%u)\n", display->lcd_clk_cfg->pll_level,display->lcd_clk_cfg->pll_level);
+ DISP_INFO("pll_frac = 0x%x (%u)\n", display->lcd_clk_cfg->pll_frac,display->lcd_clk_cfg->pll_frac);
+ DISP_INFO("pll_fout = 0x%x (%u)\n", display->lcd_clk_cfg->pll_fout,display->lcd_clk_cfg->pll_fout);
+ DISP_INFO("ss_level = 0x%x (%u)\n", display->lcd_clk_cfg->ss_level,display->lcd_clk_cfg->ss_level);
+ DISP_INFO("div_sel = 0x%x (%u)\n", display->lcd_clk_cfg->div_sel,display->lcd_clk_cfg->div_sel);
+ DISP_INFO("xd = 0x%x (%u)\n", display->lcd_clk_cfg->xd,display->lcd_clk_cfg->xd);
+ DISP_INFO("ss_level_max = 0x%x (%u)\n", display->lcd_clk_cfg->ss_level_max,display->lcd_clk_cfg->ss_level_max);
+ DISP_INFO("pll_m_max = 0x%x (%u)\n", display->lcd_clk_cfg->pll_m_max,display->lcd_clk_cfg->pll_m_max);
+ DISP_INFO("pll_m_min = 0x%x (%u)\n", display->lcd_clk_cfg->pll_m_min,display->lcd_clk_cfg->pll_m_min);
+ DISP_INFO("pll_n_max = 0x%x (%u)\n", display->lcd_clk_cfg->pll_n_max,display->lcd_clk_cfg->pll_n_max);
+ DISP_INFO("pll_n_min = 0x%x (%u)\n", display->lcd_clk_cfg->pll_n_min,display->lcd_clk_cfg->pll_n_min);
+ DISP_INFO("pll_frac_range = 0x%x (%u)\n", display->lcd_clk_cfg->pll_frac_range,display->lcd_clk_cfg->pll_frac_range);
+ DISP_INFO("pll_od_sel_max = 0x%x (%u)\n", display->lcd_clk_cfg->pll_od_sel_max,display->lcd_clk_cfg->pll_od_sel_max);
+ DISP_INFO("div_sel_max = 0x%x (%u)\n", display->lcd_clk_cfg->div_sel_max,display->lcd_clk_cfg->div_sel_max);
+ DISP_INFO("xd_max = 0x%x (%u)\n", display->lcd_clk_cfg->xd_max,display->lcd_clk_cfg->xd_max);
+ DISP_INFO("pll_ref_fmax = 0x%x (%u)\n", display->lcd_clk_cfg->pll_ref_fmax,display->lcd_clk_cfg->pll_ref_fmax);
+ DISP_INFO("pll_ref_fmin = 0x%x (%u)\n", display->lcd_clk_cfg->pll_ref_fmin,display->lcd_clk_cfg->pll_ref_fmin);
+ DISP_INFO("pll_vco_fmax = 0x%x (%u)\n", display->lcd_clk_cfg->pll_vco_fmax,display->lcd_clk_cfg->pll_vco_fmax);
+ DISP_INFO("pll_vco_fmin = 0x%x (%u)\n", display->lcd_clk_cfg->pll_vco_fmin,display->lcd_clk_cfg->pll_vco_fmin);
+ DISP_INFO("pll_out_fmax = 0x%x (%u)\n", display->lcd_clk_cfg->pll_out_fmax,display->lcd_clk_cfg->pll_out_fmax);
+ DISP_INFO("pll_out_fmin = 0x%x (%u)\n", display->lcd_clk_cfg->pll_out_fmin,display->lcd_clk_cfg->pll_out_fmin);
+ DISP_INFO("div_in_fmax = 0x%x (%u)\n", display->lcd_clk_cfg->div_in_fmax,display->lcd_clk_cfg->div_in_fmax);
+ DISP_INFO("div_out_fmax = 0x%x (%u)\n", display->lcd_clk_cfg->div_out_fmax,display->lcd_clk_cfg->div_out_fmax);
+ DISP_INFO("xd_out_fmax = 0x%x (%u)\n", display->lcd_clk_cfg->xd_out_fmax,display->lcd_clk_cfg->xd_out_fmax);
+ DISP_INFO("err_fmin = 0x%x (%u)\n", display->lcd_clk_cfg->err_fmin,display->lcd_clk_cfg->err_fmin);
+ }
+
+ if (display->disp_setting) {
+ DISP_INFO("#############################\n");
+ DISP_INFO("Dumping disp_setting structure:\n");
+ DISP_INFO("#############################\n");
+ DISP_INFO("lcd_bits = 0x%x (%u)\n", display->disp_setting->lcd_bits, display->disp_setting->lcd_bits);
+ DISP_INFO("hActive = 0x%x (%u)\n", display->disp_setting->hActive, display->disp_setting->hActive);
+ DISP_INFO("vActive = 0x%x (%u)\n", display->disp_setting->vActive, display->disp_setting->vActive);
+ DISP_INFO("hPeriod = 0x%x (%u)\n", display->disp_setting->hPeriod, display->disp_setting->hPeriod);
+ DISP_INFO("vPeriod = 0x%x (%u)\n", display->disp_setting->vPeriod, display->disp_setting->vPeriod);
+ DISP_INFO("hSync_width = 0x%x (%u)\n", display->disp_setting->hSync_width, display->disp_setting->hSync_width);
+ DISP_INFO("hSync_backPorch = 0x%x (%u)\n", display->disp_setting->hSync_backPorch, display->disp_setting->hSync_backPorch);
+ DISP_INFO("hSync_pol = 0x%x (%u)\n", display->disp_setting->hSync_pol, display->disp_setting->hSync_pol);
+ DISP_INFO("vSync_width = 0x%x (%u)\n", display->disp_setting->vSync_width, display->disp_setting->vSync_width);
+ DISP_INFO("vSync_backPorch = 0x%x (%u)\n", display->disp_setting->vSync_backPorch, display->disp_setting->vSync_backPorch);
+ DISP_INFO("vSync_pol = 0x%x (%u)\n", display->disp_setting->vSync_pol, display->disp_setting->vSync_pol);
+ DISP_INFO("fr_adj_type = 0x%x (%u)\n", display->disp_setting->fr_adj_type, display->disp_setting->fr_adj_type);
+ DISP_INFO("ss_level = 0x%x (%u)\n", display->disp_setting->ss_level, display->disp_setting->ss_level);
+ DISP_INFO("clk_auto_gen = 0x%x (%u)\n", display->disp_setting->clk_auto_gen, display->disp_setting->clk_auto_gen);
+ DISP_INFO("lcd_clock = 0x%x (%u)\n", display->disp_setting->lcd_clock, display->disp_setting->lcd_clock);
+ DISP_INFO("lane_num = 0x%x (%u)\n", display->disp_setting->lane_num, display->disp_setting->lane_num);
+ DISP_INFO("bit_rate_max = 0x%x (%u)\n", display->disp_setting->bit_rate_max, display->disp_setting->bit_rate_max);
+ DISP_INFO("factor_numerator = 0x%x (%u)\n", display->disp_setting->factor_numerator, display->disp_setting->factor_numerator);
+ DISP_INFO("opp_mode_init = 0x%x (%u)\n", display->disp_setting->opp_mode_init, display->disp_setting->opp_mode_init);
+ DISP_INFO("opp_mode_display = 0x%x (%u)\n", display->disp_setting->opp_mode_display, display->disp_setting->opp_mode_display);
+ DISP_INFO("video_mode_type = 0x%x (%u)\n", display->disp_setting->video_mode_type, display->disp_setting->video_mode_type);
+ DISP_INFO("clk_always_hs = 0x%x (%u)\n", display->disp_setting->clk_always_hs, display->disp_setting->clk_always_hs);
+ DISP_INFO("phy_switch = 0x%x (%u)\n", display->disp_setting->phy_switch, display->disp_setting->phy_switch);
+ }
+
+ if (display->lcd_timing) {
+ DISP_INFO("#############################\n");
+ DISP_INFO("Dumping lcd_timing structure:\n");
+ DISP_INFO("#############################\n");
+ DISP_INFO("lcd_bits = 0x%x (%u)\n", display->lcd_timing->lcd_bits, display->lcd_timing->lcd_bits);
+ DISP_INFO("h_active = 0x%x (%u)\n", display->lcd_timing->h_active, display->lcd_timing->h_active);
+ DISP_INFO("v_active = 0x%x (%u)\n", display->lcd_timing->v_active, display->lcd_timing->v_active);
+ DISP_INFO("h_period = 0x%x (%u)\n", display->lcd_timing->h_period, display->lcd_timing->h_period);
+ DISP_INFO("v_period = 0x%x (%u)\n", display->lcd_timing->v_period, display->lcd_timing->v_period);
+ DISP_INFO("fr_adj_type = 0x%x (%u)\n", display->lcd_timing->fr_adj_type, display->lcd_timing->fr_adj_type);
+ DISP_INFO("ss_level = 0x%x (%u)\n", display->lcd_timing->ss_level, display->lcd_timing->ss_level);
+ DISP_INFO("clk_auto_gen = 0x%x (%u)\n", display->lcd_timing->clk_auto_gen, display->lcd_timing->clk_auto_gen);
+ DISP_INFO("lcd_clock = 0x%x (%u)\n", display->lcd_timing->lcd_clock, display->lcd_timing->lcd_clock);
+ DISP_INFO("clk_ctrl = 0x%x (%u)\n", display->lcd_timing->clk_ctrl, display->lcd_timing->clk_ctrl);
+ DISP_INFO("pll_ctrl = 0x%x (%u)\n", display->lcd_timing->pll_ctrl, display->lcd_timing->pll_ctrl);
+ DISP_INFO("div_ctrl = 0x%x (%u)\n", display->lcd_timing->div_ctrl, display->lcd_timing->div_ctrl);
+ DISP_INFO("clk_change = 0x%x (%u)\n", display->lcd_timing->clk_change, display->lcd_timing->clk_change);
+ DISP_INFO("lcd_clk_dft = 0x%x (%u)\n", display->lcd_timing->lcd_clk_dft, display->lcd_timing->lcd_clk_dft);
+ DISP_INFO("hPeriod_dft = 0x%x (%u)\n", display->lcd_timing->hPeriod_dft, display->lcd_timing->hPeriod_dft);
+ DISP_INFO("vPeriod_dft = 0x%x (%u)\n", display->lcd_timing->vPeriod_dft, display->lcd_timing->vPeriod_dft);
+ DISP_INFO("sync_duration_numerator = 0x%x (%u)\n", display->lcd_timing->sync_duration_numerator, display->lcd_timing->sync_duration_numerator);
+ DISP_INFO("sync_duration_denominator = 0x%x (%u)\n", display->lcd_timing->sync_duration_denominator, display->lcd_timing->sync_duration_denominator);
+ DISP_INFO("vid_pixel_on = 0x%x (%u)\n", display->lcd_timing->vid_pixel_on, display->lcd_timing->vid_pixel_on);
+ DISP_INFO("vid_line_on = 0x%x (%u)\n", display->lcd_timing->vid_line_on, display->lcd_timing->vid_line_on);
+ DISP_INFO("hSync_width = 0x%x (%u)\n", display->lcd_timing->hSync_width, display->lcd_timing->hSync_width);
+ DISP_INFO("hSync_backPorch = 0x%x (%u)\n", display->lcd_timing->hSync_backPorch, display->lcd_timing->hSync_backPorch);
+ DISP_INFO("hSync_pol = 0x%x (%u)\n", display->lcd_timing->hSync_pol, display->lcd_timing->hSync_pol);
+ DISP_INFO("vSync_width = 0x%x (%u)\n", display->lcd_timing->vSync_width, display->lcd_timing->vSync_width);
+ DISP_INFO("vSync_backPorch = 0x%x (%u)\n", display->lcd_timing->vSync_backPorch, display->lcd_timing->vSync_backPorch);
+ DISP_INFO("vSync_pol = 0x%x (%u)\n", display->lcd_timing->vSync_pol, display->lcd_timing->vSync_pol);
+ DISP_INFO("hOffset = 0x%x (%u)\n", display->lcd_timing->hOffset, display->lcd_timing->hOffset);
+ DISP_INFO("vOffset = 0x%x (%u)\n", display->lcd_timing->vOffset, display->lcd_timing->vOffset);
+ DISP_INFO("de_hs_addr = 0x%x (%u)\n", display->lcd_timing->de_hs_addr, display->lcd_timing->de_hs_addr);
+ DISP_INFO("de_he_addr = 0x%x (%u)\n", display->lcd_timing->de_he_addr, display->lcd_timing->de_he_addr);
+ DISP_INFO("de_vs_addr = 0x%x (%u)\n", display->lcd_timing->de_vs_addr, display->lcd_timing->de_vs_addr);
+ DISP_INFO("de_ve_addr = 0x%x (%u)\n", display->lcd_timing->de_ve_addr, display->lcd_timing->de_ve_addr);
+ DISP_INFO("hs_hs_addr = 0x%x (%u)\n", display->lcd_timing->hs_hs_addr, display->lcd_timing->hs_hs_addr);
+ DISP_INFO("hs_he_addr = 0x%x (%u)\n", display->lcd_timing->hs_he_addr, display->lcd_timing->hs_he_addr);
+ DISP_INFO("hs_vs_addr = 0x%x (%u)\n", display->lcd_timing->hs_vs_addr, display->lcd_timing->hs_vs_addr);
+ DISP_INFO("hs_ve_addr = 0x%x (%u)\n", display->lcd_timing->hs_ve_addr, display->lcd_timing->hs_ve_addr);
+ DISP_INFO("vs_hs_addr = 0x%x (%u)\n", display->lcd_timing->vs_hs_addr, display->lcd_timing->vs_hs_addr);
+ DISP_INFO("vs_he_addr = 0x%x (%u)\n", display->lcd_timing->vs_he_addr, display->lcd_timing->vs_he_addr);
+ DISP_INFO("vs_vs_addr = 0x%x (%u)\n", display->lcd_timing->vs_vs_addr, display->lcd_timing->vs_vs_addr);
+ DISP_INFO("vs_ve_addr = 0x%x (%u)\n", display->lcd_timing->vs_ve_addr, display->lcd_timing->vs_ve_addr);
+ }
+
+ if (display->dsi_cfg) {
+ DISP_INFO("#############################\n");
+ DISP_INFO("Dumping dsi_cfg structure:\n");
+ DISP_INFO("#############################\n");
+ DISP_INFO("lane_num = 0x%x (%u)\n", display->dsi_cfg->lane_num ,display->dsi_cfg->lane_num);
+ DISP_INFO("bit_rate_max = 0x%x (%u)\n", display->dsi_cfg->bit_rate_max ,display->dsi_cfg->bit_rate_max);
+ DISP_INFO("bit_rate_min = 0x%x (%u)\n", display->dsi_cfg->bit_rate_min ,display->dsi_cfg->bit_rate_min);
+ DISP_INFO("bit_rate = 0x%x (%u)\n", display->dsi_cfg->bit_rate ,display->dsi_cfg->bit_rate);
+ DISP_INFO("clock_factor = 0x%x (%u)\n", display->dsi_cfg->clock_factor ,display->dsi_cfg->clock_factor);
+ DISP_INFO("factor_numerator = 0x%x (%u)\n", display->dsi_cfg->factor_numerator ,display->dsi_cfg->factor_numerator);
+ DISP_INFO("factor_denominator = 0x%x (%u)\n", display->dsi_cfg->factor_denominator ,display->dsi_cfg->factor_denominator);
+ DISP_INFO("opp_mode_init = 0x%x (%u)\n", display->dsi_cfg->opp_mode_init ,display->dsi_cfg->opp_mode_init);
+ DISP_INFO("opp_mode_display = 0x%x (%u)\n", display->dsi_cfg->opp_mode_display ,display->dsi_cfg->opp_mode_display);
+ DISP_INFO("video_mode_type = 0x%x (%u)\n", display->dsi_cfg->video_mode_type ,display->dsi_cfg->video_mode_type);
+ DISP_INFO("clk_always_hs = 0x%x (%u)\n", display->dsi_cfg->clk_always_hs ,display->dsi_cfg->clk_always_hs);
+ DISP_INFO("phy_switch = 0x%x (%u)\n", display->dsi_cfg->phy_switch ,display->dsi_cfg->phy_switch);
+ DISP_INFO("venc_data_width = 0x%x (%u)\n", display->dsi_cfg->venc_data_width ,display->dsi_cfg->venc_data_width);
+ DISP_INFO("dpi_data_format = 0x%x (%u)\n", display->dsi_cfg->dpi_data_format ,display->dsi_cfg->dpi_data_format);
+ DISP_INFO("hLine = 0x%x (%u)\n", display->dsi_cfg->hLine ,display->dsi_cfg->hLine);
+ DISP_INFO("hSyncActive = 0x%x (%u)\n", display->dsi_cfg->hSyncActive ,display->dsi_cfg->hSyncActive);
+ DISP_INFO("hBackporch = 0x%x (%u)\n", display->dsi_cfg->hBackporch ,display->dsi_cfg->hBackporch);
+ DISP_INFO("vSyncActive = 0x%x (%u)\n", display->dsi_cfg->vSyncActive ,display->dsi_cfg->vSyncActive);
+ DISP_INFO("vBackporch = 0x%x (%u)\n", display->dsi_cfg->vBackporch ,display->dsi_cfg->vBackporch);
+ DISP_INFO("vFrontporch = 0x%x (%u)\n", display->dsi_cfg->vFrontporch ,display->dsi_cfg->vFrontporch);
+ DISP_INFO("vActiveLines = 0x%x (%u)\n", display->dsi_cfg->vActiveLines ,display->dsi_cfg->vActiveLines);
+ }
+
+ if (display->dsi_phy_cfg) {
+ DISP_INFO("#############################\n");
+ DISP_INFO("Dumping dsi_phy_cfg structure:\n");
+ DISP_INFO("#############################\n");
+ DISP_INFO("lp_tesc = 0x%x (%u)\n", display->dsi_phy_cfg->lp_tesc, display->dsi_phy_cfg->lp_tesc);
+ DISP_INFO("lp_lpx = 0x%x (%u)\n", display->dsi_phy_cfg->lp_lpx, display->dsi_phy_cfg->lp_lpx);
+ DISP_INFO("lp_ta_sure = 0x%x (%u)\n", display->dsi_phy_cfg->lp_ta_sure, display->dsi_phy_cfg->lp_ta_sure);
+ DISP_INFO("lp_ta_go = 0x%x (%u)\n", display->dsi_phy_cfg->lp_ta_go, display->dsi_phy_cfg->lp_ta_go);
+ DISP_INFO("lp_ta_get = 0x%x (%u)\n", display->dsi_phy_cfg->lp_ta_get, display->dsi_phy_cfg->lp_ta_get);
+ DISP_INFO("hs_exit = 0x%x (%u)\n", display->dsi_phy_cfg->hs_exit, display->dsi_phy_cfg->hs_exit);
+ DISP_INFO("hs_trail = 0x%x (%u)\n", display->dsi_phy_cfg->hs_trail, display->dsi_phy_cfg->hs_trail);
+ DISP_INFO("hs_zero = 0x%x (%u)\n", display->dsi_phy_cfg->hs_zero, display->dsi_phy_cfg->hs_zero);
+ DISP_INFO("hs_prepare = 0x%x (%u)\n", display->dsi_phy_cfg->hs_prepare, display->dsi_phy_cfg->hs_prepare);
+ DISP_INFO("clk_trail = 0x%x (%u)\n", display->dsi_phy_cfg->clk_trail, display->dsi_phy_cfg->clk_trail);
+ DISP_INFO("clk_post = 0x%x (%u)\n", display->dsi_phy_cfg->clk_post, display->dsi_phy_cfg->clk_post);
+ DISP_INFO("clk_zero = 0x%x (%u)\n", display->dsi_phy_cfg->clk_zero, display->dsi_phy_cfg->clk_zero);
+ DISP_INFO("clk_prepare = 0x%x (%u)\n", display->dsi_phy_cfg->clk_prepare, display->dsi_phy_cfg->clk_prepare);
+ DISP_INFO("clk_pre = 0x%x (%u)\n", display->dsi_phy_cfg->clk_pre, display->dsi_phy_cfg->clk_pre);
+ DISP_INFO("init = 0x%x (%u)\n", display->dsi_phy_cfg->init, display->dsi_phy_cfg->init);
+ DISP_INFO("wakeup = 0x%x (%u)\n", display->dsi_phy_cfg->wakeup, display->dsi_phy_cfg->wakeup);
+ DISP_INFO("state_change = 0x%x (%u)\n", display->dsi_phy_cfg->state_change, display->dsi_phy_cfg->state_change);
+ }
+
+ if (display->dsi_vid) {
+ DISP_INFO("#############################\n");
+ DISP_INFO("Dumping dsi_vid structure:\n");
+ DISP_INFO("#############################\n");
+ DISP_INFO("data_bits = 0x%x (%d)\n", display->dsi_vid->data_bits, display->dsi_vid->data_bits);
+ DISP_INFO("vid_num_chunks = 0x%x (%d)\n", display->dsi_vid->vid_num_chunks, display->dsi_vid->vid_num_chunks);
+ DISP_INFO("pixel_per_chunk = 0x%x (%d)\n", display->dsi_vid->pixel_per_chunk, display->dsi_vid->pixel_per_chunk);
+ DISP_INFO("vid_null_size = 0x%x (%d)\n", display->dsi_vid->vid_null_size, display->dsi_vid->vid_null_size);
+ DISP_INFO("byte_per_chunk = 0x%x (%d)\n", display->dsi_vid->byte_per_chunk, display->dsi_vid->byte_per_chunk);
+ DISP_INFO("multi_pkt_en = 0x%x (%d)\n", display->dsi_vid->multi_pkt_en, display->dsi_vid->multi_pkt_en);
+ DISP_INFO("hline = 0x%x (%u)\n", display->dsi_vid->hline, display->dsi_vid->hline);
+ DISP_INFO("hsa = 0x%x (%u)\n", display->dsi_vid->hsa, display->dsi_vid->hsa);
+ DISP_INFO("hbp = 0x%x (%u)\n", display->dsi_vid->hbp, display->dsi_vid->hbp);
+ DISP_INFO("vsa = 0x%x (%u)\n", display->dsi_vid->vsa, display->dsi_vid->vsa);
+ DISP_INFO("vbp = 0x%x (%u)\n", display->dsi_vid->vbp, display->dsi_vid->vbp);
+ DISP_INFO("vfp = 0x%x (%u)\n", display->dsi_vid->vfp, display->dsi_vid->vfp);
+ DISP_INFO("vact = 0x%x (%u)\n", display->dsi_vid->vact, display->dsi_vid->vact);
+ }
+}
diff --git a/system/dev/display/astro-display/dsi.c b/system/dev/display/astro-display/dsi.c
new file mode 100644
index 0000000..fee0fa5
--- /dev/null
+++ b/system/dev/display/astro-display/dsi.c
@@ -0,0 +1,1246 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "astro-display.h"
+
+#define CMD_TIMEOUT_CNT 3000
+
+
+void lcd_mipi_phy_set(astro_display_t* display, bool enable) {
+ uint32_t phy_bit, phy_width;
+ uint32_t lane_cnt;
+
+ if (enable) {
+ /* HHI_MIPI_CNTL0 */
+ /* DIF_REF_CTL1:31-16bit, DIF_REF_CTL0:15-0bit */
+ WRITE32_REG(HHI, HHI_MIPI_CNTL0, (0xa487 << 16) | (0x8 << 0));
+
+ /* HHI_MIPI_CNTL1 */
+ /* DIF_REF_CTL2:15-0bit; bandgap bit16 */
+ WRITE32_REG(HHI, HHI_MIPI_CNTL1, (0x1 << 16) | (0x002e << 0));
+
+ /* HHI_MIPI_CNTL2 */
+ /* DIF_TX_CTL1:31-16bit, DIF_TX_CTL0:15-0bit */
+ WRITE32_REG(HHI, HHI_MIPI_CNTL2, (0x2680 << 16) | (0x45a << 0));
+
+ phy_bit = MIPI_PHY_LANE_BIT;
+ phy_width = MIPI_PHY_LANE_WIDTH;
+ switch (display->dsi_cfg->lane_num) {
+ case 1:
+ lane_cnt = DSI_LANE_COUNT_1;
+ break;
+ case 2:
+ lane_cnt = DSI_LANE_COUNT_2;
+ break;
+ case 3:
+ lane_cnt = DSI_LANE_COUNT_3;
+ break;
+ case 4:
+ lane_cnt = DSI_LANE_COUNT_4;
+ break;
+ default:
+ lane_cnt = 0;
+ break;
+ }
+ SET_BIT32(HHI, HHI_MIPI_CNTL2, lane_cnt, phy_bit, phy_width);
+ } else {
+ WRITE32_REG(HHI, HHI_MIPI_CNTL0, 0);
+ WRITE32_REG(HHI, HHI_MIPI_CNTL1, 0);
+ WRITE32_REG(HHI, HHI_MIPI_CNTL2, 0);
+ }
+}
+
+#define max(x, y) ((x > y)? x : y)
+
+static void mipi_dsi_phy_config(astro_display_t* display, uint32_t dsi_ui) {
+ uint32_t temp, t_ui, t_req_min, t_req_max, t_req, n;
+
+ t_ui = (1000000 * 100) / (dsi_ui / 1000); /* 0.01ns*100 */
+ temp = t_ui * 8; /* lane_byte cycle time */
+
+ display->dsi_phy_cfg->lp_tesc = ((DPHY_TIME_LP_TESC(t_ui) + temp - 1) / temp) & 0xff;
+ display->dsi_phy_cfg->lp_lpx = ((DPHY_TIME_LP_LPX(t_ui) + temp - 1) / temp) & 0xff;
+ display->dsi_phy_cfg->lp_ta_sure = ((DPHY_TIME_LP_TA_SURE(t_ui) + temp - 1) / temp) &
+ 0xff;
+ display->dsi_phy_cfg->lp_ta_go = ((DPHY_TIME_LP_TA_GO(t_ui) + temp - 1) / temp) & 0xff;
+ display->dsi_phy_cfg->lp_ta_get = ((DPHY_TIME_LP_TA_GETX(t_ui) + temp - 1) / temp) &
+ 0xff;
+ display->dsi_phy_cfg->hs_exit = ((DPHY_TIME_HS_EXIT(t_ui) + temp - 1) / temp) & 0xff;
+ display->dsi_phy_cfg->clk_prepare = ((DPHY_TIME_CLK_PREPARE(t_ui) + temp - 1) / temp) &
+ 0xff;
+ display->dsi_phy_cfg->clk_zero = ((DPHY_TIME_CLK_ZERO(t_ui) + temp - 1) / temp) & 0xff;
+ display->dsi_phy_cfg->clk_pre = ((DPHY_TIME_CLK_PRE(t_ui) + temp - 1) / temp) & 0xff;
+ display->dsi_phy_cfg->init = (DPHY_TIME_INIT(t_ui) + temp - 1) / temp;
+ display->dsi_phy_cfg->wakeup = (DPHY_TIME_WAKEUP(t_ui) + temp - 1) / temp;
+
+ t_req_max = ((105 * 100 + 12 * t_ui) / 100);
+ for (n = 0; n <= 0xff; n++) {
+ display->dsi_phy_cfg->clk_trail = n;
+ if (((temp * display->dsi_phy_cfg->clk_trail / 100) > 70) &&
+ ((temp * display->dsi_phy_cfg->clk_trail / 100) < t_req_max)) {
+ DISP_INFO("t_ui=%d, t_req=%d\n", t_ui, t_req_max);
+ DISP_INFO("clk_trail=%d, n=%d\n", display->dsi_phy_cfg->clk_trail, n);
+
+ break;
+ }
+ }
+
+ t_req_min = 2 * ((60 * 100 + 52 * t_ui) / 100);
+ for (n = 0; n <= 0xff; n++) {
+ display->dsi_phy_cfg->clk_post = n;
+ if ((temp * display->dsi_phy_cfg->clk_post / 100) >= t_req_min) {
+ DISP_INFO("t_ui=%d, t_req_min=%d\n", t_ui, t_req_min);
+ DISP_INFO("clk_post=%d, n=%d\n", display->dsi_phy_cfg->clk_post, n);
+
+ break;
+ }
+ }
+
+ t_req_min = max(8 * t_ui / 100, (60 * 100 + 4 * t_ui) / 100) + 10;
+ t_req_max = ((105 * 100 + 12 * t_ui) / 100);
+ for (n = 0; n <= 0xff; n++) {
+ display->dsi_phy_cfg->hs_trail = n;
+ if (((temp * display->dsi_phy_cfg->hs_trail / 100) > t_req_min) &&
+ ((temp * display->dsi_phy_cfg->hs_trail / 100) < t_req_max)) {
+ DISP_INFO("t_req_min=%d, t_req_max=%d\n", t_req_min, t_req_max);
+ DISP_INFO("t_ui=%d, hs_trail=%d, n=%d\n", t_ui, display->dsi_phy_cfg->hs_trail, n);
+
+ break;
+ }
+ }
+
+ t_req_min = (40 * 100 + 4 * t_ui) / 100;
+ t_req_max = ((85 * 100 + 6 * t_ui) / 100);
+ for (n = 0; n <= 0xff; n++) {
+ display->dsi_phy_cfg->hs_prepare = n;
+ if (((temp * display->dsi_phy_cfg->hs_prepare / 100) > t_req_min) &&
+ ((temp * display->dsi_phy_cfg->hs_prepare / 100) < t_req_max)) {
+ DISP_INFO("t_req_min=%d, t_req_max=%d\n", t_req_min, t_req_max);
+ DISP_INFO("t_ui=%d, hs_prepare=%d, n=%d\n", t_ui, display->dsi_phy_cfg->hs_prepare, n);
+
+ break;
+ }
+ }
+
+ t_req_min = ((145 * 100 + 10 * t_ui) / 100) - ((40 * 100 + 4 * t_ui) / 100);
+ for (n = 0; n <= 0xff; n++) {
+ display->dsi_phy_cfg->hs_zero = n;
+ if ((temp * display->dsi_phy_cfg->hs_zero / 100) > t_req_min) {
+ DISP_INFO("t_ui=%d, t_req_min=%d\n", t_ui, t_req_min);
+ DISP_INFO("hs_zero=%d, n=%d\n", display->dsi_phy_cfg->hs_zero, n);
+
+ break;
+ }
+ }
+
+ /* check dphy spec: (unit: ns) */
+ if ((temp * display->dsi_phy_cfg->lp_tesc / 100) <= 100)
+ DISP_ERROR("lp_tesc timing error\n");
+ if ((temp * display->dsi_phy_cfg->lp_lpx / 100) <= 50)
+ DISP_ERROR("lp_lpx timing error\n");
+ if ((temp * display->dsi_phy_cfg->hs_exit / 100) <= 100)
+ DISP_ERROR("hs_exit timing error\n");
+ t_req = ((t_ui > (60 * 100 / 4)) ?
+ (8 * t_ui) : ((60 * 100) + 4 * t_ui));
+ if ((temp * display->dsi_phy_cfg->hs_trail / 100) <= ((t_req + 50) / 100))
+ DISP_ERROR("hs_trail timing error\n");
+ t_req = temp * display->dsi_phy_cfg->hs_prepare / 100;
+ if ((t_req <= (40 + (t_ui * 4 / 100))) ||
+ (t_req >= (85 + (t_ui * 6 / 100))))
+ DISP_ERROR("hs_prepare timing error\n");
+ t_req = 145 + (t_ui * 10 / 100);
+ if (((temp * display->dsi_phy_cfg->hs_zero / 100) +
+ (temp * display->dsi_phy_cfg->hs_prepare / 100)) <= t_req)
+ DISP_ERROR("hs_zero timing error\n");
+ if ((temp * display->dsi_phy_cfg->init / 100) <= 100000)
+ DISP_ERROR("init timing error\n");
+ if ((temp * display->dsi_phy_cfg->wakeup / 100) <= 1000000)
+ DISP_ERROR("wakeup timing error\n");
+
+ DISP_INFO("%s:\n"
+ "lp_tesc = 0x%02x\n"
+ "lp_lpx = 0x%02x\n"
+ "lp_ta_sure = 0x%02x\n"
+ "lp_ta_go = 0x%02x\n"
+ "lp_ta_get = 0x%02x\n"
+ "hs_exit = 0x%02x\n"
+ "hs_trail = 0x%02x\n"
+ "hs_zero = 0x%02x\n"
+ "hs_prepare = 0x%02x\n"
+ "clk_trail = 0x%02x\n"
+ "clk_post = 0x%02x\n"
+ "clk_zero = 0x%02x\n"
+ "clk_prepare = 0x%02x\n"
+ "clk_pre = 0x%02x\n"
+ "init = 0x%02x\n"
+ "wakeup = 0x%02x\n\n",
+ __func__,
+ display->dsi_phy_cfg->lp_tesc, display->dsi_phy_cfg->lp_lpx, display->dsi_phy_cfg->lp_ta_sure,
+ display->dsi_phy_cfg->lp_ta_go, display->dsi_phy_cfg->lp_ta_get, display->dsi_phy_cfg->hs_exit,
+ display->dsi_phy_cfg->hs_trail, display->dsi_phy_cfg->hs_zero, display->dsi_phy_cfg->hs_prepare,
+ display->dsi_phy_cfg->clk_trail, display->dsi_phy_cfg->clk_post,
+ display->dsi_phy_cfg->clk_zero, display->dsi_phy_cfg->clk_prepare, display->dsi_phy_cfg->clk_pre,
+ display->dsi_phy_cfg->init, display->dsi_phy_cfg->wakeup);
+}
+
+static void mipi_dsi_video_config(astro_display_t* display)
+{
+ uint32_t h_period, hs_width, hs_bp;
+ uint32_t den, num;
+ uint32_t v_period, v_active, vs_width, vs_bp;
+
+ h_period = display->lcd_timing->h_period;
+ hs_width = display->lcd_timing->hSync_width;
+ hs_bp = display->lcd_timing->hSync_backPorch;
+ den = display->dsi_cfg->factor_denominator;
+ num = display->dsi_cfg->factor_numerator;
+
+ display->dsi_vid->hline = (h_period * den + num - 1) / num;
+ display->dsi_vid->hsa = (hs_width * den + num - 1) / num;
+ display->dsi_vid->hbp = (hs_bp * den + num - 1) / num;
+
+ v_period = display->lcd_timing->v_period;
+ v_active = display->lcd_timing->v_active;
+ vs_width = display->lcd_timing->vSync_width;
+ vs_bp = display->lcd_timing->vSync_backPorch;
+ display->dsi_vid->vsa = vs_width;
+ display->dsi_vid->vbp = vs_bp;
+ display->dsi_vid->vfp = v_period - v_active - vs_bp - vs_width;
+ display->dsi_vid->vact = v_active;
+
+ DISP_INFO("MIPI DSI video timing:\n"
+ " HLINE = %d\n"
+ " HSA = %d\n"
+ " HBP = %d\n"
+ " VSA = %d\n"
+ " VBP = %d\n"
+ " VFP = %d\n"
+ " VACT = %d\n\n",
+ display->dsi_vid->hline, display->dsi_vid->hsa, display->dsi_vid->hbp,
+ display->dsi_vid->vsa, display->dsi_vid->vbp, display->dsi_vid->vfp, display->dsi_vid->vact);
+}
+
+static void mipi_dsi_vid_mode_config(astro_display_t* display)
+{
+ if (display->dsi_cfg->video_mode_type == BURST_MODE) {
+ display->dsi_vid->pixel_per_chunk = display->lcd_timing->h_active;
+ display->dsi_vid->vid_num_chunks = 0;
+ display->dsi_vid->vid_null_size = 0;
+ } else {
+ DISP_ERROR("Non-Burst mode is not supported\n");
+ while(1);
+ }
+
+ mipi_dsi_video_config(display);
+}
+
+static void mipi_dsi_config_post(astro_display_t* display)
+{
+ uint32_t pclk, lanebyteclk;
+ uint32_t den, num;
+
+ pclk = display->lcd_timing->lcd_clock / 1000;
+
+ /* pclk lanebyteclk factor */
+ if (display->dsi_cfg->factor_numerator == 0) {
+ lanebyteclk = display->dsi_cfg->bit_rate / 8 / 1000;
+ DISP_INFO("pixel_clk = %d.%03dMHz, bit_rate = %d.%03dMHz, lanebyteclk = %d.%03dMHz\n",
+ (pclk / 1000), (pclk % 1000),
+ (display->dsi_cfg->bit_rate / 1000000),
+ ((display->dsi_cfg->bit_rate / 1000) % 1000),
+ (lanebyteclk / 1000), (lanebyteclk % 1000));
+ display->dsi_cfg->factor_numerator = 8;
+ display->dsi_cfg->factor_denominator = display->dsi_cfg->clock_factor;
+ }
+ num = display->dsi_cfg->factor_numerator;
+ den = display->dsi_cfg->factor_denominator;
+ DISP_INFO("num=%d, den=%d, factor=%d.%02d\n",
+ num, den, (den / num), ((den % num) * 100 / num));
+
+ if (display->dsi_cfg->opp_mode_display == OPERATION_VIDEO_MODE) {
+ mipi_dsi_vid_mode_config(display);
+ }
+
+ /* phy config */
+ mipi_dsi_phy_config(display, display->dsi_cfg->bit_rate);
+}
+
+static void mipi_dcs_set(astro_display_t* display, int trans_type, int req_ack, int tear_en)
+{
+ WRITE32_REG(MIPI_DSI, DW_DSI_CMD_MODE_CFG,
+ (trans_type << BIT_MAX_RD_PKT_SIZE) |
+ (trans_type << BIT_DCS_LW_TX) |
+ (trans_type << BIT_DCS_SR_0P_TX) |
+ (trans_type << BIT_DCS_SW_1P_TX) |
+ (trans_type << BIT_DCS_SW_0P_TX) |
+ (trans_type << BIT_GEN_LW_TX) |
+ (trans_type << BIT_GEN_SR_2P_TX) |
+ (trans_type << BIT_GEN_SR_1P_TX) |
+ (trans_type << BIT_GEN_SR_0P_TX) |
+ (trans_type << BIT_GEN_SW_2P_TX) |
+ (trans_type << BIT_GEN_SW_1P_TX) |
+ (trans_type << BIT_GEN_SW_0P_TX) |
+ (req_ack << BIT_ACK_RQST_EN) |
+ (tear_en << BIT_TEAR_FX_EN));
+
+ if (tear_en == MIPI_DCS_ENABLE_TEAR) {
+ /* Enable Tear Interrupt if tear_en is valid */
+ SET_BIT32(MIPI_DSI, MIPI_DSI_TOP_INTR_CNTL_STAT, 0x1, BIT_EDPITE_INT_EN, 1);
+ /* Enable Measure Vsync */
+ SET_BIT32(MIPI_DSI, MIPI_DSI_TOP_MEAS_CNTL, 0x1, BIT_VSYNC_MEAS_EN, 1);
+ SET_BIT32(MIPI_DSI, MIPI_DSI_TOP_MEAS_CNTL, 0x1, BIT_TE_MEAS_EN, 1);
+ }
+
+ /* Packet header settings */
+ WRITE32_REG(MIPI_DSI, DW_DSI_PCKHDL_CFG,
+ (1 << BIT_CRC_RX_EN) |
+ (1 << BIT_ECC_RX_EN) |
+ (req_ack << BIT_BTA_EN) |
+ (0 << BIT_EOTP_RX_EN) |
+ (0 << BIT_EOTP_TX_EN));
+}
+
+
+static void set_mipi_dsi_host(astro_display_t* display, uint32_t vcid, uint32_t chroma_subsample,
+ uint32_t operation_mode)
+{
+ uint32_t dpi_data_format, venc_data_width;
+ uint32_t lane_num, vid_mode_type;
+ uint32_t temp;
+
+ venc_data_width = display->dsi_cfg->venc_data_width;
+ dpi_data_format = display->dsi_cfg->dpi_data_format;
+ lane_num = (uint32_t)(display->dsi_cfg->lane_num);
+ vid_mode_type = (uint32_t)(display->dsi_cfg->video_mode_type);
+
+ /* ----------------------------------------------------- */
+ /* Standard Configuration for Video Mode Operation */
+ /* ----------------------------------------------------- */
+ /* 1, Configure Lane number and phy stop wait time */
+ if (display->dsi_phy_cfg->state_change == 2) {
+ WRITE32_REG(MIPI_DSI, DW_DSI_PHY_IF_CFG,
+ (0x28 << BIT_PHY_STOP_WAIT_TIME) |
+ ((lane_num-1) << BIT_N_LANES));
+ } else {
+ WRITE32_REG(MIPI_DSI, DW_DSI_PHY_IF_CFG,
+ (1 << BIT_PHY_STOP_WAIT_TIME) |
+ ((lane_num-1) << BIT_N_LANES));
+ }
+
+ /* 2.1, Configure Virtual channel settings */
+ WRITE32_REG(MIPI_DSI, DW_DSI_DPI_VCID, vcid);
+ /* 2.2, Configure Color format */
+ WRITE32_REG(MIPI_DSI, DW_DSI_DPI_COLOR_CODING,
+ (((dpi_data_format == COLOR_18BIT_CFG_2) ?
+ 1 : 0) << BIT_LOOSELY18_EN) |
+ (dpi_data_format << BIT_DPI_COLOR_CODING));
+ /* 2.2.1 Configure Set color format for DPI register */
+ temp = (READ32_REG(MIPI_DSI, MIPI_DSI_TOP_CNTL) &
+ ~(0xf<<BIT_DPI_COLOR_MODE) &
+ ~(0x7<<BIT_IN_COLOR_MODE) &
+ ~(0x3<<BIT_CHROMA_SUBSAMPLE));
+ WRITE32_REG(MIPI_DSI, MIPI_DSI_TOP_CNTL,
+ (temp |
+ (dpi_data_format << BIT_DPI_COLOR_MODE) |
+ (venc_data_width << BIT_IN_COLOR_MODE) |
+ (chroma_subsample << BIT_CHROMA_SUBSAMPLE)));
+ /* 2.3 Configure Signal polarity */
+ WRITE32_REG(MIPI_DSI, DW_DSI_DPI_CFG_POL,
+ (0x0 << BIT_COLORM_ACTIVE_LOW) |
+ (0x0 << BIT_SHUTD_ACTIVE_LOW) |
+ (0 << BIT_HSYNC_ACTIVE_LOW) |
+ (0 << BIT_VSYNC_ACTIVE_LOW) |
+ (0x0 << BIT_DATAEN_ACTIVE_LOW));
+
+ if (operation_mode == OPERATION_VIDEO_MODE) {
+ /* 3.1 Configure Low power and video mode type settings */
+ WRITE32_REG(MIPI_DSI, DW_DSI_VID_MODE_CFG,
+ (1 << BIT_LP_HFP_EN) | /* enalbe lp */
+ (1 << BIT_LP_HBP_EN) | /* enalbe lp */
+ (1 << BIT_LP_VCAT_EN) | /* enalbe lp */
+ (1 << BIT_LP_VFP_EN) | /* enalbe lp */
+ (1 << BIT_LP_VBP_EN) | /* enalbe lp */
+ (1 << BIT_LP_VSA_EN) | /* enalbe lp */
+ (0 << BIT_FRAME_BTA_ACK_EN) |
+ /* enable BTA after one frame, TODO, need check */
+ /* (1 << BIT_LP_CMD_EN) | */
+ /* enable the command transmission only in lp mode */
+ (vid_mode_type << BIT_VID_MODE_TYPE));
+ /* burst non burst mode */
+ /* [23:16]outvact, [7:0]invact */
+ WRITE32_REG(MIPI_DSI, DW_DSI_DPI_LP_CMD_TIM,
+ (4 << 16) | (4 << 0));
+ /* 3.2 Configure video packet size settings */
+ WRITE32_REG(MIPI_DSI, DW_DSI_VID_PKT_SIZE,
+ display->dsi_vid->pixel_per_chunk);
+ WRITE32_REG(MIPI_DSI, DW_DSI_VID_NUM_CHUNKS,
+ display->dsi_vid->vid_num_chunks);
+ WRITE32_REG(MIPI_DSI, DW_DSI_VID_NULL_SIZE,
+ display->dsi_vid->vid_null_size);
+ /* 4 Configure the video relative parameters according to
+ * the output type
+ */
+ /* include horizontal timing and vertical line */
+ WRITE32_REG(MIPI_DSI, DW_DSI_VID_HLINE_TIME, display->dsi_vid->hline);
+ WRITE32_REG(MIPI_DSI, DW_DSI_VID_HSA_TIME, display->dsi_vid->hsa);
+ WRITE32_REG(MIPI_DSI, DW_DSI_VID_HBP_TIME, display->dsi_vid->hbp);
+ WRITE32_REG(MIPI_DSI, DW_DSI_VID_VSA_LINES, display->dsi_vid->vsa);
+ WRITE32_REG(MIPI_DSI, DW_DSI_VID_VBP_LINES, display->dsi_vid->vbp);
+ WRITE32_REG(MIPI_DSI, DW_DSI_VID_VFP_LINES, display->dsi_vid->vfp);
+ WRITE32_REG(MIPI_DSI, DW_DSI_VID_VACTIVE_LINES,
+ display->dsi_vid->vact);
+ } /* operation_mode == OPERATION_VIDEO_MODE */
+
+ /* ----------------------------------------------------- */
+ /* Finish Configuration */
+ /* ----------------------------------------------------- */
+
+ /* Inner clock divider settings */
+ WRITE32_REG(MIPI_DSI, DW_DSI_CLKMGR_CFG,
+ (0x1 << BIT_TO_CLK_DIV) |
+ (display->dsi_phy_cfg->lp_tesc << BIT_TX_ESC_CLK_DIV));
+ /* Packet header settings //move to mipi_dcs_set */
+ /* WRITE32_REG(MIPI_DSI, DW_DSI_PCKHDL_CFG,
+ * (1 << BIT_CRC_RX_EN) |
+ * (1 << BIT_ECC_RX_EN) |
+ * (0 << BIT_BTA_EN) |
+ * (0 << BIT_EOTP_RX_EN) |
+ * (0 << BIT_EOTP_TX_EN) );
+ */
+ /* operation mode setting: video/command mode */
+ WRITE32_REG(MIPI_DSI, DW_DSI_MODE_CFG, operation_mode);
+
+ /* Phy Timer */
+ if (display->dsi_phy_cfg->state_change == 2)
+ WRITE32_REG(MIPI_DSI, DW_DSI_PHY_TMR_CFG, 0x03320000);
+ else
+ WRITE32_REG(MIPI_DSI, DW_DSI_PHY_TMR_CFG, 0x090f0000);
+
+ if (display->dsi_phy_cfg->state_change == 2)
+ WRITE32_REG(MIPI_DSI, DW_DSI_PHY_TMR_LPCLK_CFG, 0x870025);
+ else
+ WRITE32_REG(MIPI_DSI, DW_DSI_PHY_TMR_LPCLK_CFG, 0x260017);
+}
+
+static void dsi_dump_host(astro_display_t* display) {
+ DISP_INFO("%s: DUMPING DSI HOST REGS\n", __func__);
+ DISP_INFO("DW_DSI_VERSION = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_VERSION));
+ DISP_INFO("DW_DSI_PWR_UP = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_PWR_UP));
+ DISP_INFO("DW_DSI_CLKMGR_CFG = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_CLKMGR_CFG));
+ DISP_INFO("DW_DSI_DPI_VCID = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_DPI_VCID));
+ DISP_INFO("DW_DSI_DPI_COLOR_CODING = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_DPI_COLOR_CODING));
+ DISP_INFO("DW_DSI_DPI_CFG_POL = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_DPI_CFG_POL));
+ DISP_INFO("DW_DSI_DPI_LP_CMD_TIM = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_DPI_LP_CMD_TIM));
+ DISP_INFO("DW_DSI_DBI_VCID = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_DBI_VCID));
+ DISP_INFO("DW_DSI_DBI_CFG = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_DBI_CFG));
+ DISP_INFO("DW_DSI_DBI_PARTITIONING_EN = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_DBI_PARTITIONING_EN));
+ DISP_INFO("DW_DSI_DBI_CMDSIZE = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_DBI_CMDSIZE));
+ DISP_INFO("DW_DSI_PCKHDL_CFG = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_PCKHDL_CFG));
+ DISP_INFO("DW_DSI_GEN_VCID = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_GEN_VCID));
+ DISP_INFO("DW_DSI_MODE_CFG = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_MODE_CFG));
+ DISP_INFO("DW_DSI_VID_MODE_CFG = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_VID_MODE_CFG));
+ DISP_INFO("DW_DSI_VID_PKT_SIZE = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_VID_PKT_SIZE));
+ DISP_INFO("DW_DSI_VID_NUM_CHUNKS = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_VID_NUM_CHUNKS));
+ DISP_INFO("DW_DSI_VID_NULL_SIZE = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_VID_NULL_SIZE));
+ DISP_INFO("DW_DSI_VID_HSA_TIME = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_VID_HSA_TIME));
+ DISP_INFO("DW_DSI_VID_HBP_TIME = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_VID_HBP_TIME));
+ DISP_INFO("DW_DSI_VID_HLINE_TIME = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_VID_HLINE_TIME));
+ DISP_INFO("DW_DSI_VID_VSA_LINES = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_VID_VSA_LINES));
+ DISP_INFO("DW_DSI_VID_VBP_LINES = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_VID_VBP_LINES));
+ DISP_INFO("DW_DSI_VID_VFP_LINES = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_VID_VFP_LINES));
+ DISP_INFO("DW_DSI_VID_VACTIVE_LINES = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_VID_VACTIVE_LINES));
+ DISP_INFO("DW_DSI_EDPI_CMD_SIZE = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_EDPI_CMD_SIZE));
+ DISP_INFO("DW_DSI_CMD_MODE_CFG = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_CMD_MODE_CFG));
+ DISP_INFO("DW_DSI_GEN_HDR = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_GEN_HDR));
+ DISP_INFO("DW_DSI_GEN_PLD_DATA = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_GEN_PLD_DATA));
+ DISP_INFO("DW_DSI_CMD_PKT_STATUS = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_CMD_PKT_STATUS));
+ DISP_INFO("DW_DSI_TO_CNT_CFG = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_TO_CNT_CFG));
+ DISP_INFO("DW_DSI_HS_RD_TO_CNT = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_HS_RD_TO_CNT));
+ DISP_INFO("DW_DSI_LP_RD_TO_CNT = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_LP_RD_TO_CNT));
+ DISP_INFO("DW_DSI_HS_WR_TO_CNT = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_HS_WR_TO_CNT));
+ DISP_INFO("DW_DSI_LP_WR_TO_CNT = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_LP_WR_TO_CNT));
+ DISP_INFO("DW_DSI_BTA_TO_CNT = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_BTA_TO_CNT));
+ DISP_INFO("DW_DSI_SDF_3D = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_SDF_3D));
+ DISP_INFO("DW_DSI_LPCLK_CTRL = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_LPCLK_CTRL));
+ DISP_INFO("DW_DSI_PHY_TMR_LPCLK_CFG = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_PHY_TMR_LPCLK_CFG));
+ DISP_INFO("DW_DSI_PHY_TMR_CFG = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_PHY_TMR_CFG));
+ DISP_INFO("DW_DSI_PHY_RSTZ = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_PHY_RSTZ));
+ DISP_INFO("DW_DSI_PHY_IF_CFG = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_PHY_IF_CFG));
+ DISP_INFO("DW_DSI_PHY_ULPS_CTRL = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_PHY_ULPS_CTRL));
+ DISP_INFO("DW_DSI_PHY_TX_TRIGGERS = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_PHY_TX_TRIGGERS));
+ DISP_INFO("DW_DSI_PHY_STATUS = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_PHY_STATUS));
+ DISP_INFO("DW_DSI_PHY_TST_CTRL0 = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_PHY_TST_CTRL0));
+ DISP_INFO("DW_DSI_PHY_TST_CTRL1 = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_PHY_TST_CTRL1));
+ DISP_INFO("DW_DSI_INT_ST0 = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_INT_ST0));
+ DISP_INFO("DW_DSI_INT_ST1 = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_INT_ST1));
+ DISP_INFO("DW_DSI_INT_MSK0 = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_INT_MSK0));
+ DISP_INFO("DW_DSI_INT_MSK1 = 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_INT_MSK1));
+}
+
+static void dsi_phy_dump(astro_display_t* display) {
+ DISP_INFO("%s: DUMPING PHY REGS\n", __func__);
+
+ DISP_INFO("MIPI_DSI_PHY_CTRL = 0x%x\n", READ32_REG(DSI_PHY, MIPI_DSI_PHY_CTRL));
+ DISP_INFO("MIPI_DSI_CHAN_CTRL = 0x%x\n", READ32_REG(DSI_PHY, MIPI_DSI_CHAN_CTRL));
+ DISP_INFO("MIPI_DSI_CHAN_STS = 0x%x\n", READ32_REG(DSI_PHY, MIPI_DSI_CHAN_STS));
+ DISP_INFO("MIPI_DSI_CLK_TIM = 0x%x\n", READ32_REG(DSI_PHY, MIPI_DSI_CLK_TIM));
+ DISP_INFO("MIPI_DSI_HS_TIM = 0x%x\n", READ32_REG(DSI_PHY, MIPI_DSI_HS_TIM));
+ DISP_INFO("MIPI_DSI_LP_TIM = 0x%x\n", READ32_REG(DSI_PHY, MIPI_DSI_LP_TIM));
+ DISP_INFO("MIPI_DSI_ANA_UP_TIM = 0x%x\n", READ32_REG(DSI_PHY, MIPI_DSI_ANA_UP_TIM));
+ DISP_INFO("MIPI_DSI_INIT_TIM = 0x%x\n", READ32_REG(DSI_PHY, MIPI_DSI_INIT_TIM));
+ DISP_INFO("MIPI_DSI_WAKEUP_TIM = 0x%x\n", READ32_REG(DSI_PHY, MIPI_DSI_WAKEUP_TIM));
+ DISP_INFO("MIPI_DSI_LPOK_TIM = 0x%x\n", READ32_REG(DSI_PHY, MIPI_DSI_LPOK_TIM));
+ DISP_INFO("MIPI_DSI_LP_WCHDOG = 0x%x\n", READ32_REG(DSI_PHY, MIPI_DSI_LP_WCHDOG));
+ DISP_INFO("MIPI_DSI_ANA_CTRL = 0x%x\n", READ32_REG(DSI_PHY, MIPI_DSI_ANA_CTRL));
+ DISP_INFO("MIPI_DSI_CLK_TIM1 = 0x%x\n", READ32_REG(DSI_PHY, MIPI_DSI_CLK_TIM1));
+ DISP_INFO("MIPI_DSI_TURN_WCHDOG = 0x%x\n", READ32_REG(DSI_PHY, MIPI_DSI_TURN_WCHDOG));
+ DISP_INFO("MIPI_DSI_ULPS_CHECK = 0x%x\n", READ32_REG(DSI_PHY, MIPI_DSI_ULPS_CHECK));
+ DISP_INFO("MIPI_DSI_TEST_CTRL0 = 0x%x\n", READ32_REG(DSI_PHY, MIPI_DSI_TEST_CTRL0));
+ DISP_INFO("MIPI_DSI_TEST_CTRL1 = 0x%x\n", READ32_REG(DSI_PHY, MIPI_DSI_TEST_CTRL1));
+
+ DISP_INFO("\n");
+
+}
+
+static void dsi_phy_init(astro_display_t* display, uint32_t lane_num)
+{
+ /* enable phy clock. */
+ WRITE32_REG(DSI_PHY, MIPI_DSI_PHY_CTRL, 0x1); /* enable DSI top clock. */
+ WRITE32_REG(DSI_PHY, MIPI_DSI_PHY_CTRL,
+ (1 << 0) | /* enable the DSI PLL clock . */
+ (1 << 7) |
+ /* enable pll clock which connected to
+ * DDR clock path
+ */
+ (1 << 8) | /* enable the clock divider counter */
+ (0 << 9) | /* enable the divider clock out */
+ (0 << 10) | /* clock divider. 1: freq/4, 0: freq/2 */
+ (0 << 11) |
+ /* 1: select the mipi DDRCLKHS from clock divider,
+ * 0: from PLL clock
+ */
+ (0 << 12)); /* enable the byte clock generateion. */
+ /* enable the divider clock out */
+ SET_BIT32(DSI_PHY, MIPI_DSI_PHY_CTRL, 1, 9, 1);
+ /* enable the byte clock generateion. */
+ SET_BIT32(DSI_PHY, MIPI_DSI_PHY_CTRL, 1, 12, 1);
+ SET_BIT32(DSI_PHY, MIPI_DSI_PHY_CTRL, 1, 31, 1);
+ SET_BIT32(DSI_PHY, MIPI_DSI_PHY_CTRL, 0, 31, 1);
+
+ /* 0x05210f08);//0x03211c08 */
+ WRITE32_REG(DSI_PHY, MIPI_DSI_CLK_TIM,
+ (display->dsi_phy_cfg->clk_trail | (display->dsi_phy_cfg->clk_post << 8) |
+ (display->dsi_phy_cfg->clk_zero << 16) | (display->dsi_phy_cfg->clk_prepare << 24)));
+ WRITE32_REG(DSI_PHY, MIPI_DSI_CLK_TIM1, display->dsi_phy_cfg->clk_pre); /* ?? */
+ /* 0x050f090d */
+ WRITE32_REG(DSI_PHY, MIPI_DSI_HS_TIM,
+ (display->dsi_phy_cfg->hs_exit | (display->dsi_phy_cfg->hs_trail << 8) |
+ (display->dsi_phy_cfg->hs_zero << 16) | (display->dsi_phy_cfg->hs_prepare << 24)));
+ /* 0x4a370e0e */
+ WRITE32_REG(DSI_PHY, MIPI_DSI_LP_TIM,
+ (display->dsi_phy_cfg->lp_lpx | (display->dsi_phy_cfg->lp_ta_sure << 8) |
+ (display->dsi_phy_cfg->lp_ta_go << 16) | (display->dsi_phy_cfg->lp_ta_get << 24)));
+ /* ?? //some number to reduce sim time. */
+ WRITE32_REG(DSI_PHY, MIPI_DSI_ANA_UP_TIM, 0x0100);
+ /* 0xe20 //30d4 -> d4 to reduce sim time. */
+ WRITE32_REG(DSI_PHY, MIPI_DSI_INIT_TIM, display->dsi_phy_cfg->init);
+ /* 0x8d40 //1E848-> 48 to reduct sim time. */
+ WRITE32_REG(DSI_PHY, MIPI_DSI_WAKEUP_TIM, display->dsi_phy_cfg->wakeup);
+ /* wait for the LP analog ready. */
+ WRITE32_REG(DSI_PHY, MIPI_DSI_LPOK_TIM, 0x7C);
+ /* 1/3 of the tWAKEUP. */
+ WRITE32_REG(DSI_PHY, MIPI_DSI_ULPS_CHECK, 0x927C);
+ /* phy TURN watch dog. */
+ WRITE32_REG(DSI_PHY, MIPI_DSI_LP_WCHDOG, 0x1000);
+ /* phy ESC command watch dog. */
+ WRITE32_REG(DSI_PHY, MIPI_DSI_TURN_WCHDOG, 0x1000);
+
+ /* Powerup the analog circuit. */
+ switch (lane_num) {
+ case 1:
+ WRITE32_REG(DSI_PHY, MIPI_DSI_CHAN_CTRL, 0x0e);
+ break;
+ case 2:
+ WRITE32_REG(DSI_PHY, MIPI_DSI_CHAN_CTRL, 0x0c);
+ break;
+ case 3:
+ WRITE32_REG(DSI_PHY, MIPI_DSI_CHAN_CTRL, 0x08);
+ break;
+ case 4:
+ default:
+ WRITE32_REG(DSI_PHY, MIPI_DSI_CHAN_CTRL, 0);
+ break;
+ }
+}
+
+#define DPHY_TIMEOUT 200000
+static void check_phy_status(astro_display_t* display)
+{
+ int i = 0;
+
+ while (GET_BIT32(MIPI_DSI, DW_DSI_PHY_STATUS,
+ BIT_PHY_LOCK, 1) == 0) {
+ if (i++ >= DPHY_TIMEOUT) {
+ DISP_ERROR("phy_lock timeout 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_PHY_STATUS));
+ break;
+ }
+ usleep(6);
+ }
+
+ i = 0;
+ usleep(10);
+ while (GET_BIT32(MIPI_DSI, DW_DSI_PHY_STATUS,
+ BIT_PHY_STOPSTATECLKLANE, 1) == 0) {
+ if (i == 0) {
+ DISP_INFO(" Waiting STOP STATE LANE\n");
+ }
+ if (i++ >= DPHY_TIMEOUT) {
+ DISP_ERROR("lane_state timeout 0x%x\n", READ32_REG(MIPI_DSI, DW_DSI_PHY_STATUS));
+ break;
+ }
+ usleep(6);
+ }
+}
+
+static void set_dsi_phy_config(astro_display_t* display)
+{
+ /* Digital */
+ /* Power up DSI */
+ WRITE32_REG(MIPI_DSI, DW_DSI_PWR_UP, 1);
+
+ /* Setup Parameters of DPHY */
+ WRITE32_REG(MIPI_DSI, DW_DSI_PHY_TST_CTRL1, 0x00010044);/*testcode*/
+ WRITE32_REG(MIPI_DSI, DW_DSI_PHY_TST_CTRL0, 0x2);
+ WRITE32_REG(MIPI_DSI, DW_DSI_PHY_TST_CTRL0, 0x0);
+ WRITE32_REG(MIPI_DSI, DW_DSI_PHY_TST_CTRL1, 0x00000074);/*testwrite*/
+ WRITE32_REG(MIPI_DSI, DW_DSI_PHY_TST_CTRL0, 0x2);
+ WRITE32_REG(MIPI_DSI, DW_DSI_PHY_TST_CTRL0, 0x0);
+
+ /* Power up D-PHY */
+ WRITE32_REG(MIPI_DSI, DW_DSI_PHY_RSTZ, 0xf);
+
+ /* Analog */
+ dsi_phy_init(display, display->dsi_cfg->lane_num);
+
+ /* Check the phylock/stopstateclklane to decide if the DPHY is ready */
+ check_phy_status(display);
+
+ /* Trigger a sync active for esc_clk */
+ SET_BIT32(DSI_PHY, MIPI_DSI_PHY_CTRL, 1, 1, 1);
+
+ /* Startup transfer, default lpclk */
+ WRITE32_REG(MIPI_DSI, DW_DSI_LPCLK_CTRL,
+ (0x1 << BIT_AUTOCLKLANE_CTRL) |
+ (0x1 << BIT_TXREQUESTCLKHS));
+}
+
+
+
+/* MIPI DSI Specific functions */
+static inline void print_mipi_cmd_status(astro_display_t* display, int cnt, uint32_t status)
+{
+ if (cnt == 0)
+{ DISP_ERROR("cmd error: status=0x%04x, int0=0x%06x, int1=0x%06x\n",
+ status,
+ READ32_REG(MIPI_DSI, DW_DSI_INT_ST0),
+ READ32_REG(MIPI_DSI, DW_DSI_INT_ST1));
+ }
+}
+
+static void dsi_bta_control(astro_display_t* display, int en)
+{
+ if (en) {
+ SET_BIT32(MIPI_DSI, DW_DSI_CMD_MODE_CFG,
+ MIPI_DSI_DCS_REQ_ACK, BIT_ACK_RQST_EN, 1);
+ SET_BIT32(MIPI_DSI, DW_DSI_PCKHDL_CFG,
+ MIPI_DSI_DCS_REQ_ACK, BIT_BTA_EN, 1);
+ } else {
+ SET_BIT32(MIPI_DSI, DW_DSI_PCKHDL_CFG,
+ MIPI_DSI_DCS_NO_ACK, BIT_BTA_EN, 1);
+ SET_BIT32(MIPI_DSI, DW_DSI_CMD_MODE_CFG,
+ MIPI_DSI_DCS_NO_ACK, BIT_ACK_RQST_EN, 1);
+ }
+}
+
+
+static int wait_bta_ack(astro_display_t* display)
+{
+ uint32_t phy_status;
+ int i;
+
+ /* Check if phydirection is RX */
+ i = CMD_TIMEOUT_CNT;
+ do {
+ usleep(10);
+ i--;
+ phy_status = READ32_REG(MIPI_DSI, DW_DSI_PHY_STATUS);
+ } while ((((phy_status & 0x2) >> BIT_PHY_DIRECTION) == 0x0) && (i > 0));
+ if (i == 0) {
+ DISP_ERROR("phy direction error: RX\n");
+ return -1;
+ }
+
+ /* Check if phydirection is return to TX */
+ i = CMD_TIMEOUT_CNT;
+ do {
+ usleep(10);
+ i--;
+ phy_status = READ32_REG(MIPI_DSI, DW_DSI_PHY_STATUS);
+ } while ((((phy_status & 0x2) >> BIT_PHY_DIRECTION) == 0x1) && (i > 0));
+ if (i == 0) {
+ DISP_ERROR("phy direction error: TX\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static void wait_cmd_fifo_empty(astro_display_t* display)
+{
+ uint32_t cmd_status;
+ int i = CMD_TIMEOUT_CNT;
+
+ do {
+ usleep(10);
+ i--;
+ cmd_status = READ32_REG(MIPI_DSI, DW_DSI_CMD_PKT_STATUS);
+ } while ((((cmd_status >> BIT_GEN_CMD_EMPTY) & 0x1) != 0x1) && (i > 0));
+ print_mipi_cmd_status(display, i, cmd_status);
+}
+static unsigned short dsi_rx_n;
+
+static void dsi_set_max_return_pkt_size(astro_display_t* display, struct dsi_cmd_request_s *req)
+{
+ uint32_t d_para[2];
+
+ d_para[0] = (uint32_t)(req->payload[2] & 0xff);
+ d_para[1] = (uint32_t)(req->payload[3] & 0xff);
+ dsi_rx_n = (unsigned short)((d_para[1] << 8) | d_para[0]);
+ generic_if_wr(display, DW_DSI_GEN_HDR,
+ ((d_para[1] << BIT_GEN_WC_MSBYTE) |
+ (d_para[0] << BIT_GEN_WC_LSBYTE) |
+ (((uint32_t)req->vc_id) << BIT_GEN_VC) |
+ (DT_SET_MAX_RET_PKT_SIZE << BIT_GEN_DT)));
+ if (req->req_ack == MIPI_DSI_DCS_REQ_ACK) {
+ wait_bta_ack(display);
+ } else if (req->req_ack == MIPI_DSI_DCS_NO_ACK) {
+ wait_cmd_fifo_empty(display);
+ }
+}
+
+
+static int dsi_generic_read_packet(astro_display_t* display, struct dsi_cmd_request_s *req,
+ unsigned char *r_data)
+{
+ unsigned int d_para[2], read_data;
+ unsigned int i, j, done;
+ int ret = 0;
+
+ switch (req->data_type) {
+ case DT_GEN_RD_1:
+ d_para[0] = (req->pld_count == 0) ?
+ 0 : (((unsigned int)req->payload[2]) & 0xff);
+ d_para[1] = 0;
+ break;
+ case DT_GEN_RD_2:
+ d_para[0] = (req->pld_count == 0) ?
+ 0 : (((unsigned int)req->payload[2]) & 0xff);
+ d_para[1] = (req->pld_count < 2) ?
+ 0 : (((unsigned int)req->payload[3]) & 0xff);
+ break;
+ case DT_GEN_RD_0:
+ default:
+ d_para[0] = 0;
+ d_para[1] = 0;
+ break;
+ }
+
+ if (MIPI_DSI_DCS_ACK_TYPE == MIPI_DSI_DCS_NO_ACK)
+ dsi_bta_control(display, 1);
+ generic_if_wr(display, DW_DSI_GEN_HDR,
+ ((d_para[1] << BIT_GEN_WC_MSBYTE) |
+ (d_para[0] << BIT_GEN_WC_LSBYTE) |
+ (((unsigned int)req->vc_id) << BIT_GEN_VC) |
+ (((unsigned int)req->data_type) << BIT_GEN_DT)));
+ ret = wait_bta_ack(display);
+ if (ret)
+ return -1;
+
+ i = 0;
+ done = 0;
+ while (done == 0) {
+ read_data = generic_if_rd(display, DW_DSI_GEN_PLD_DATA);
+ for (j = 0; j < 4; j++) {
+ if (i < dsi_rx_n) {
+ r_data[i] = (unsigned char)
+ ((read_data >> (j*8)) & 0xff);
+ i++;
+ } else {
+ done = 1;
+ break;
+ }
+ }
+ }
+ if (MIPI_DSI_DCS_ACK_TYPE == MIPI_DSI_DCS_NO_ACK)
+ dsi_bta_control(display, 0);
+
+ return dsi_rx_n;
+}
+
+static int dsi_dcs_read_packet(astro_display_t* display, struct dsi_cmd_request_s *req,
+ unsigned char *r_data)
+{
+ unsigned int d_command, read_data;
+ unsigned int i, j, done;
+ int ret = 0;
+
+ d_command = ((unsigned int)req->payload[2]) & 0xff;
+
+ if (MIPI_DSI_DCS_ACK_TYPE == MIPI_DSI_DCS_NO_ACK)
+ dsi_bta_control(display, 1);
+ generic_if_wr(display, DW_DSI_GEN_HDR,
+ ((0 << BIT_GEN_WC_MSBYTE) |
+ (d_command << BIT_GEN_WC_LSBYTE) |
+ (((unsigned int)req->vc_id) << BIT_GEN_VC) |
+ (((unsigned int)req->data_type) << BIT_GEN_DT)));
+ ret = wait_bta_ack(display);
+ if (ret)
+ return -1;
+
+ i = 0;
+ done = 0;
+ while (done == 0) {
+ read_data = generic_if_rd(display, DW_DSI_GEN_PLD_DATA);
+ for (j = 0; j < 4; j++) {
+ if (i < dsi_rx_n) {
+ r_data[i] = (unsigned char)
+ ((read_data >> (j*8)) & 0xff);
+ i++;
+ } else {
+ done = 1;
+ break;
+ }
+ }
+ }
+
+ if (MIPI_DSI_DCS_ACK_TYPE == MIPI_DSI_DCS_NO_ACK)
+ dsi_bta_control(display, 0);
+
+ return dsi_rx_n;
+}
+
+
+/* *************************************************************
+ * Function: dcs_write_short_packet
+ * DCS Write Short Packet with Generic Interface
+ * Supported Data Type: DT_DCS_SHORT_WR_0, DT_DCS_SHORT_WR_1,
+ */
+static void dsi_dcs_write_short_packet(astro_display_t* display, struct dsi_cmd_request_s *req)
+{
+ unsigned int d_command, d_para;
+
+ d_command = ((unsigned int)req->payload[2]) & 0xff;
+ d_para = (req->pld_count < 2) ?
+ 0 : (((unsigned int)req->payload[3]) & 0xff);
+
+ generic_if_wr(display, DW_DSI_GEN_HDR,
+ ((d_para << BIT_GEN_WC_MSBYTE) |
+ (d_command << BIT_GEN_WC_LSBYTE) |
+ (((unsigned int)req->vc_id) << BIT_GEN_VC) |
+ (((unsigned int)req->data_type) << BIT_GEN_DT)));
+ if (req->req_ack == MIPI_DSI_DCS_REQ_ACK)
+ wait_bta_ack(display);
+ else if (req->req_ack == MIPI_DSI_DCS_NO_ACK)
+ wait_cmd_fifo_empty(display);
+}
+
+/* *************************************************************
+ * Function: dsi_write_long_packet
+ * Write Long Packet with Generic Interface
+ * Supported Data Type: DT_GEN_LONG_WR, DT_DCS_LONG_WR
+ */
+static void dsi_write_long_packet(astro_display_t* display, struct dsi_cmd_request_s *req)
+{
+ unsigned int d_command, payload_data, header_data;
+ unsigned int cmd_status;
+ unsigned int i, j, data_index, n, temp;
+
+ /* payload[2] start (payload[0]: data_type, payload[1]: data_cnt) */
+ data_index = DSI_CMD_SIZE_INDEX + 1;
+ d_command = ((unsigned int)req->payload[data_index]) & 0xff;
+
+ /* Write Payload Register First */
+ n = (req->pld_count+3)/4;
+ for (i = 0; i < n; i++) {
+ payload_data = 0;
+ if (i < (req->pld_count/4))
+ temp = 4;
+ else
+ temp = req->pld_count % 4;
+ for (j = 0; j < temp; j++) {
+ payload_data |= (((unsigned int)
+ req->payload[data_index+(i*4)+j]) << (j*8));
+ }
+
+ /* Check the pld fifo status before write to it,
+ * do not need check every word
+ */
+ if ((i == (n/3)) || (i == (n/2))) {
+ j = CMD_TIMEOUT_CNT;
+ do {
+ usleep(10);
+ j--;
+ cmd_status = READ32_REG(MIPI_DSI,
+ DW_DSI_CMD_PKT_STATUS);
+ } while ((((cmd_status >> BIT_GEN_PLD_W_FULL) & 0x1) ==
+ 0x1) && (j > 0));
+ print_mipi_cmd_status(display, j, cmd_status);
+ }
+ /* Use direct memory write to save time when in
+ * WRITE_MEMORY_CONTINUE
+ */
+ if (d_command == DCS_WRITE_MEMORY_CONTINUE) {
+ WRITE32_REG(MIPI_DSI, DW_DSI_GEN_PLD_DATA,
+ payload_data);
+ } else {
+ generic_if_wr(display, DW_DSI_GEN_PLD_DATA,
+ payload_data);
+ }
+ }
+
+ /* Check cmd fifo status before write to it */
+ j = CMD_TIMEOUT_CNT;
+ do {
+ usleep(10);
+ j--;
+ cmd_status = READ32_REG(MIPI_DSI, DW_DSI_CMD_PKT_STATUS);
+ } while ((((cmd_status >> BIT_GEN_CMD_FULL) & 0x1) == 0x1) && (j > 0));
+ print_mipi_cmd_status(display, j, cmd_status);
+ /* Write Header Register */
+ /* include command */
+ header_data = ((((unsigned int)req->pld_count) << BIT_GEN_WC_LSBYTE) |
+ (((unsigned int)req->vc_id) << BIT_GEN_VC) |
+ (((unsigned int)req->data_type) << BIT_GEN_DT));
+ generic_if_wr(display, DW_DSI_GEN_HDR, header_data);
+ if (req->req_ack == MIPI_DSI_DCS_REQ_ACK)
+ wait_bta_ack(display);
+ else if (req->req_ack == MIPI_DSI_DCS_NO_ACK)
+ wait_cmd_fifo_empty(display);
+}
+
+int dsi_read_single(astro_display_t* display, unsigned char *payload, unsigned char *rd_data,
+ unsigned int rd_byte_len)
+{
+ int num = 0;
+ unsigned char temp[4];
+ unsigned char vc_id = MIPI_DSI_VIRTUAL_CHAN_ID;
+ unsigned int req_ack;
+ struct dsi_cmd_request_s dsi_cmd_req;
+
+ req_ack = MIPI_DSI_DCS_ACK_TYPE;
+ dsi_cmd_req.data_type = DT_SET_MAX_RET_PKT_SIZE;
+ dsi_cmd_req.vc_id = (vc_id & 0x3);
+ temp[0] = dsi_cmd_req.data_type;
+ temp[1] = 2;
+ temp[2] = (unsigned char)((rd_byte_len >> 0) & 0xff);
+ temp[3] = (unsigned char)((rd_byte_len >> 8) & 0xff);
+ dsi_cmd_req.payload = &temp[0];
+ dsi_cmd_req.pld_count = 2;
+ dsi_cmd_req.req_ack = req_ack;
+ dsi_set_max_return_pkt_size(display, &dsi_cmd_req);
+
+ /* payload struct: */
+ /* data_type, data_cnt, command, parameters... */
+ req_ack = MIPI_DSI_DCS_REQ_ACK; /* need BTA ack */
+ dsi_cmd_req.data_type = payload[0];
+ dsi_cmd_req.vc_id = (vc_id & 0x3);
+ dsi_cmd_req.payload = &payload[0];
+ dsi_cmd_req.pld_count = payload[DSI_CMD_SIZE_INDEX];
+ dsi_cmd_req.req_ack = req_ack;
+ switch (dsi_cmd_req.data_type) {/* analysis data_type */
+ case DT_GEN_RD_0:
+ case DT_GEN_RD_1:
+ case DT_GEN_RD_2:
+ num = dsi_generic_read_packet(display, &dsi_cmd_req, rd_data);
+ break;
+ case DT_DCS_RD_0:
+ num = dsi_dcs_read_packet(display, &dsi_cmd_req, rd_data);
+ break;
+ default:
+ DISP_ERROR("read un-support data_type: 0x%02x\n",
+ dsi_cmd_req.data_type);
+ break;
+ }
+
+ if (num < 0) {
+ DISP_ERROR("mipi-dsi read error\n");
+ }
+
+ return num;
+}
+
+static void mipi_dsi_check_state(astro_display_t* display, unsigned char reg, unsigned char cnt)
+{
+ int ret = 0, i;
+ unsigned char *rd_data;
+ unsigned char payload[3] = {DT_GEN_RD_1, 1, 0x04};
+
+ if (display->dsi_cfg->check_en == 0) {
+ return;
+ }
+
+ display->dsi_cfg->check_state = 0;
+ rd_data = (unsigned char *)malloc(sizeof(unsigned char) * cnt);
+ if (rd_data == NULL) {
+ DISP_ERROR("%s: rd_data malloc error\n", __func__);
+ return;
+ }
+
+ payload[2] = reg;
+ ret = dsi_read_single(display, payload, rd_data, cnt);
+ if (ret < 0) {
+ display->dsi_cfg->check_state = 0;
+ SET_BIT32(VPU, L_VCOM_VS_ADDR, 0, 12, 1);
+ free(rd_data);
+ return;
+ }
+ if (ret > cnt) {
+ DISP_ERROR("%s: read back cnt is wrong\n", __func__);
+ free(rd_data);
+ return;
+ }
+
+ display->dsi_cfg->check_state = 1;
+ SET_BIT32(VPU, L_VCOM_VS_ADDR, 1, 12, 1);
+ DISP_INFO("read reg 0x%02x: ", reg);
+ for (i = 0; i < ret; i++) {
+ if (i == 0)
+ DISP_INFO("0x%02x", rd_data[i]);
+ else
+ DISP_INFO(",0x%02x", rd_data[i]);
+ }
+ DISP_INFO("\n");
+
+ free(rd_data);
+}
+
+#if 0
+int dsi_write_cmd(unsigned char *payload)
+{
+ int i = 0, j = 0, num = 0;
+ int k = 0, n = 0;
+ unsigned char rd_data[100];
+ struct dsi_cmd_request_s dsi_cmd_req;
+ unsigned char vc_id = MIPI_DSI_VIRTUAL_CHAN_ID;
+ uint32_t req_ack = MIPI_DSI_DCS_ACK_TYPE;
+ struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
+ struct lcd_power_ctrl_s *lcd_power;
+ char *str;
+ int gpio;
+
+ /* mipi command(payload) */
+ /* format: data_type, cmd_size, data.... */
+ /* special: data_type=0xff,
+ * cmd_size<0xff means delay ms,
+ * cmd_size=0xff means ending.
+ * data_type=0xf0,
+ * data0=gpio_index, data1=gpio_value, data2=delay.
+ */
+ while (i < DSI_CMD_SIZE_MAX) {
+ if (payload[i] == 0xff) {
+ j = 2;
+ if (payload[i+1] == 0xff)
+ break;
+ else
+ mdelay(payload[i+1]);
+ } else if (payload[i] == 0xf0) { /* gpio */
+ j = (DSI_CMD_SIZE_INDEX + 1) +
+ payload[i+DSI_CMD_SIZE_INDEX];
+ if (payload[i+DSI_CMD_SIZE_INDEX] < 3) {
+ DISP_ERROR("wrong cmd_size %d for gpio\n",
+ payload[i+DSI_CMD_SIZE_INDEX]);
+ break;
+ }
+ lcd_power = lcd_drv->lcd_config->lcd_power;
+ str = lcd_power->cpu_gpio[payload[i+DSI_GPIO_INDEX]];
+ gpio = aml_lcd_gpio_name_map_num(str);
+ aml_lcd_gpio_set(gpio, payload[i+DSI_GPIO_INDEX+1]);
+ if (payload[i+DSI_GPIO_INDEX+2])
+ mdelay(payload[i+DSI_GPIO_INDEX+2]);
+ } else if (payload[i] == 0xfc) { /* check state */
+ j = (DSI_CMD_SIZE_INDEX + 1) +
+ payload[i+DSI_CMD_SIZE_INDEX];
+ if (payload[i+DSI_CMD_SIZE_INDEX] < 2) {
+ DISP_ERROR("wrong cmd_size %d for check state\n",
+ payload[i+DSI_CMD_SIZE_INDEX]);
+ break;
+ }
+ if (payload[i+DSI_GPIO_INDEX+2] > 0) {
+ mipi_dsi_check_state(
+ payload[i+DSI_GPIO_INDEX],
+ payload[i+DSI_GPIO_INDEX+1]);
+ }
+ } else if ((payload[i] & 0xf) == 0x0) {
+ DISP_ERROR("data_type: 0x%02x\n", payload[i]);
+ break;
+ } else {
+ /* payload[i+DSI_CMD_SIZE_INDEX] is data count */
+ j = (DSI_CMD_SIZE_INDEX + 1) +
+ payload[i+DSI_CMD_SIZE_INDEX];
+ dsi_cmd_req.data_type = payload[i];
+ dsi_cmd_req.vc_id = (vc_id & 0x3);
+ dsi_cmd_req.payload = &payload[i];
+ dsi_cmd_req.pld_count = payload[i+DSI_CMD_SIZE_INDEX];
+ dsi_cmd_req.req_ack = req_ack;
+ switch (dsi_cmd_req.data_type) {/* analysis data_type */
+ case DT_GEN_SHORT_WR_0:
+ case DT_GEN_SHORT_WR_1:
+ case DT_GEN_SHORT_WR_2:
+ dsi_generic_write_short_packet(&dsi_cmd_req);
+ break;
+ case DT_DCS_SHORT_WR_0:
+ case DT_DCS_SHORT_WR_1:
+ dsi_dcs_write_short_packet(&dsi_cmd_req);
+ break;
+ case DT_DCS_LONG_WR:
+ case DT_GEN_LONG_WR:
+ dsi_write_long_packet(&dsi_cmd_req);
+ break;
+ case DT_TURN_ON:
+ SET_BIT32(MIPI_DSI, MIPI_DSI_TOP_CNTL, 1, 2, 1);
+ mdelay(20); /* wait for vsync trigger */
+ SET_BIT32(MIPI_DSI, MIPI_DSI_TOP_CNTL, 0, 2, 1);
+ mdelay(20); /* wait for vsync trigger */
+ break;
+ case DT_SHUT_DOWN:
+ SET_BIT32(MIPI_DSI, MIPI_DSI_TOP_CNTL, 1, 2, 1);
+ mdelay(20); /* wait for vsync trigger */
+ break;
+ case DT_SET_MAX_RET_PKT_SIZE:
+ dsi_set_max_return_pkt_size(&dsi_cmd_req);
+ break;
+#ifdef DSI_CMD_READ_VALID
+ case DT_GEN_RD_0:
+ case DT_GEN_RD_1:
+ case DT_GEN_RD_2:
+ /* need BTA ack */
+ dsi_cmd_req.req_ack = MIPI_DSI_DCS_REQ_ACK;
+ dsi_cmd_req.pld_count =
+ (dsi_cmd_req.pld_count > 2) ?
+ 2 : dsi_cmd_req.pld_count;
+ n = dsi_generic_read_packet(&dsi_cmd_req,
+ &rd_data[0]);
+ DISP_ERROR("generic read data");
+ for (k = 0; k < dsi_cmd_req.pld_count; k++) {
+ DISP_INFO(" 0x%02x",
+ dsi_cmd_req.payload[k+2]);
+ }
+ for (k = 0; k < n; k++)
+ DISP_INFO("0x%02x ", rd_data[k]);
+ DISP_INFO("\n");
+ break;
+ case DT_DCS_RD_0:
+ /* need BTA ack */
+ dsi_cmd_req.req_ack = MIPI_DSI_DCS_REQ_ACK;
+ n = dsi_dcs_read_packet(&dsi_cmd_req,
+ &rd_data[0]);
+ DISP_INFO("dcs read data 0x%02x:\n",
+ dsi_cmd_req.payload[2]);
+ for (k = 0; k < n; k++)
+ DISP_INFO("0x%02x ", rd_data[k]);
+ DISP_INFO("\n");
+ break;
+#endif
+ default:
+ DISP_ERROR("[warning]un-support data_type: 0x%02x\n",
+ dsi_cmd_req.data_type);
+
+ break;
+ }
+ }
+ i += j;
+ num++;
+ }
+
+ return num;
+}
+#endif
+
+static void set_mipi_dsi_lpclk_ctrl(astro_display_t* display, uint32_t operation_mode) {
+ uint32_t lpclk = 1;
+
+ if (operation_mode == OPERATION_VIDEO_MODE) {
+ if (display->dsi_cfg->clk_always_hs) { /* clk always hs */
+ lpclk = 0;
+ } else { /* enable clk lp state */
+ lpclk = 1;
+ }
+ } else { /* enable clk lp state */
+ lpclk = 1;
+ }
+ SET_BIT32(MIPI_DSI, DW_DSI_LPCLK_CTRL, lpclk, BIT_AUTOCLKLANE_CTRL, 1);
+}
+
+static void mipi_dsi_link_on(astro_display_t* display) {
+
+ set_mipi_dsi_lpclk_ctrl(display, display->dsi_cfg->opp_mode_init);
+
+ // dsi_write_cmd(dconf->dsi_init_on);
+
+ // dsi_write_cmd(lcd_ext->config->table_init_on);
+
+ set_mipi_dsi_host(display, MIPI_DSI_VIRTUAL_CHAN_ID,
+ 0, /* Chroma sub sample, only for
+ * YUV 422 or 420, even or odd
+ */
+ display->dsi_cfg->opp_mode_display);
+ set_mipi_dsi_lpclk_ctrl(display, display->dsi_cfg->opp_mode_display);
+}
+
+static void startup_mipi_dsi_host(astro_display_t* display)
+{
+
+ /* Enable dwc mipi_dsi_host's clock */
+ SET_BIT32(MIPI_DSI, MIPI_DSI_TOP_CNTL, 0x3, 4, 2);
+ /* mipi_dsi_host's reset */
+ SET_BIT32(MIPI_DSI, MIPI_DSI_TOP_SW_RESET, 0xf, 0, 4);
+ /* Release mipi_dsi_host's reset */
+ SET_BIT32(MIPI_DSI, MIPI_DSI_TOP_SW_RESET, 0x0, 0, 4);
+ /* Enable dwc mipi_dsi_host's clock */
+ SET_BIT32(MIPI_DSI, MIPI_DSI_TOP_CLK_CNTL, 0x3, 0, 2);
+
+ WRITE32_REG(MIPI_DSI, MIPI_DSI_TOP_MEM_PD, 0);
+
+ usleep(10000);
+}
+
+
+zx_status_t aml_dsi_host_on(astro_display_t* display) {
+
+ ZX_DEBUG_ASSERT(display);
+
+ display->dsi_vid = calloc(1, sizeof(dsi_video_t));
+ if (!display->dsi_vid) {
+ DISP_ERROR("Could not allocate dsi_video_t\n");
+ return ZX_ERR_NO_MEMORY;
+ }
+
+ mipi_dsi_config_post(display);
+
+ startup_mipi_dsi_host(display);
+
+ mipi_dcs_set(display, MIPI_DSI_CMD_TRANS_TYPE, /* 0: high speed, 1: low power */
+ MIPI_DSI_DCS_ACK_TYPE, /* if need bta ack check */
+ MIPI_DSI_TEAR_SWITCH); /* enable tear ack */
+
+ set_mipi_dsi_host(display, MIPI_DSI_VIRTUAL_CHAN_ID, /* Virtual channel id */
+ 0, /* Chroma sub sample, only for YUV 422 or 420, even or odd */
+ display->dsi_cfg->opp_mode_init); /* DSI operation mode, video or command */
+ set_dsi_phy_config(display);
+
+ mipi_dsi_link_on(display);
+
+
+ return ZX_OK;
+}
\ No newline at end of file
diff --git a/system/dev/display/astro-display/dw_dsi.h b/system/dev/display/astro-display/dw_dsi.h
new file mode 100644
index 0000000..82ee599
--- /dev/null
+++ b/system/dev/display/astro-display/dw_dsi.h
@@ -0,0 +1,57 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#pragma once
+
+#define DW_DSI_VERSION (0x00 << 2) /* contains the vers of the DSI host controller */
+#define DW_DSI_PWR_UP (0x01 << 2) /* controls the power up of the core */
+#define DW_DSI_CLKMGR_CFG (0x02 << 2) /* configs the factor for internal dividers */
+#define DW_DSI_DPI_VCID (0x03 << 2) /* configs the Virt Chan ID for DPI traffic */
+#define DW_DSI_DPI_COLOR_CODING (0x04 << 2) /* configs DPI color coding */
+#define DW_DSI_DPI_CFG_POL (0x05 << 2) /* configs the polarity of DPI signals */
+#define DW_DSI_DPI_LP_CMD_TIM (0x06 << 2) /* configs the timing for lp cmds (in vid mode) */
+#define DW_DSI_DBI_VCID (0x07 << 2) /* configs Virtual Channel ID for DBI traffic */
+#define DW_DSI_DBI_CFG (0x08 << 2) /* configs the bit width of pixels for DBI */
+#define DW_DSI_DBI_PARTITIONING_EN (0x09 << 2) /* host partition DBI traffic automatically */
+#define DW_DSI_DBI_CMDSIZE (0x0A << 2) /* cmd size for auto partitioning of DBI */
+#define DW_DSI_PCKHDL_CFG (0x0B << 2) /* how EoTp, BTA, CRC and ECC are to be used */
+#define DW_DSI_GEN_VCID (0x0C << 2) /* Virtual Channel ID of READ responses to store */
+#define DW_DSI_MODE_CFG (0x0D << 2) /* mode of op between Video or Command Mode */
+#define DW_DSI_VID_MODE_CFG (0x0E << 2) /* Video mode operation config */
+#define DW_DSI_VID_PKT_SIZE (0x0F << 2) /* video packet size */
+#define DW_DSI_VID_NUM_CHUNKS (0x10 << 2) /* number of chunks to use */
+#define DW_DSI_VID_NULL_SIZE (0x11 << 2) /* configs the size of null packets */
+#define DW_DSI_VID_HSA_TIME (0x12 << 2) /* configs the video HSA time */
+#define DW_DSI_VID_HBP_TIME (0x13 << 2) /* configs the video HBP time */
+#define DW_DSI_VID_HLINE_TIME (0x14 << 2) /* configs the overall time for each video line */
+#define DW_DSI_VID_VSA_LINES (0x15 << 2) /* configs the VSA period */
+#define DW_DSI_VID_VBP_LINES (0x16 << 2) /* configs the VBP period */
+#define DW_DSI_VID_VFP_LINES (0x17 << 2) /* configs the VFP period */
+#define DW_DSI_VID_VACTIVE_LINES (0x18 << 2) /* configs the vertical resolution of video */
+#define DW_DSI_EDPI_CMD_SIZE (0x19 << 2) /* configs the size of eDPI packets */
+#define DW_DSI_CMD_MODE_CFG (0x1A << 2) /* command mode operation config */
+#define DW_DSI_GEN_HDR (0x1B << 2) /* header for new packets */
+#define DW_DSI_GEN_PLD_DATA (0x1C << 2) /* payload for packets sent using the Gen i/f */
+#define DW_DSI_CMD_PKT_STATUS (0x1D << 2) /* info about FIFOs related to DBI and Gen i/f */
+#define DW_DSI_TO_CNT_CFG (0x1E << 2) /* counters that trig timeout errors */
+#define DW_DSI_HS_RD_TO_CNT (0x1F << 2) /* Peri Resp timeout after HS Rd operations */
+#define DW_DSI_LP_RD_TO_CNT (0x20 << 2) /* Peri Resp timeout after LP Rd operations */
+#define DW_DSI_HS_WR_TO_CNT (0x21 << 2) /* Peri Resp timeout after HS Wr operations */
+#define DW_DSI_LP_WR_TO_CNT (0x22 << 2) /* Peri Resp timeout after LP Wr operations */
+#define DW_DSI_BTA_TO_CNT (0x23 << 2) /* Peri Resp timeout after Bus Turnaround comp */
+#define DW_DSI_SDF_3D (0x24 << 2) /* 3D cntrl info for VSS packets in video mode. */
+#define DW_DSI_LPCLK_CTRL (0x25 << 2) /* non continuous clock in the clock lane. */
+#define DW_DSI_PHY_TMR_LPCLK_CFG (0x26 << 2) /* time for the clock lane */
+#define DW_DSI_PHY_TMR_CFG (0x27 << 2) /* time for the data lanes */
+#define DW_DSI_PHY_RSTZ (0x28 << 2) /* controls resets and the PLL of the D-PHY. */
+#define DW_DSI_PHY_IF_CFG (0x29 << 2) /* number of active lanes */
+#define DW_DSI_PHY_ULPS_CTRL (0x2A << 2) /* entering and leaving ULPS in the D- PHY. */
+#define DW_DSI_PHY_TX_TRIGGERS (0x2B << 2) /* pins that activate triggers in the D-PHY */
+#define DW_DSI_PHY_STATUS (0x2C << 2) /* contains info about the status of the D- PHY */
+#define DW_DSI_PHY_TST_CTRL0 (0x2D << 2) /* controls clock and clear pins of the D-PHY */
+#define DW_DSI_PHY_TST_CTRL1 (0x2E << 2) /* controls data and enable pins of the D-PHY */
+#define DW_DSI_INT_ST0 (0x3F << 2) /* status of intr from ack and D-PHY */
+#define DW_DSI_INT_ST1 (0x30 << 2) /* status of intr related to timeout, ECC, etc */
+#define DW_DSI_INT_MSK0 (0x31 << 2) /* masks interrupts that affect the INT_ST0 reg */
+#define DW_DSI_INT_MSK1 (0x32 << 2) /* masks interrupts that affect the INT_ST1 reg */
diff --git a/system/dev/display/astro-display/hhi.h b/system/dev/display/astro-display/hhi.h
new file mode 100644
index 0000000..8dd7004
--- /dev/null
+++ b/system/dev/display/astro-display/hhi.h
@@ -0,0 +1,565 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#pragma once
+
+#define HHI_MIPI_CNTL0 (0x000 << 2)
+#define HHI_MIPI_CNTL1 (0x001 << 2)
+#define HHI_MIPI_CNTL2 (0x002 << 2)
+#define HHI_MIPI_STS (0x003 << 2)
+#define HHI_CHECK_CLK_RESULT (0x004 << 2)
+#define HHI_GP0_PLL_CNTL0 (0x010 << 2)
+#define HHI_GP0_PLL_CNTL1 (0x011 << 2)
+#define HHI_GP0_PLL_CNTL2 (0x012 << 2)
+#define HHI_GP0_PLL_CNTL3 (0x013 << 2)
+#define HHI_GP0_PLL_CNTL4 (0x014 << 2)
+#define HHI_GP0_PLL_CNTL5 (0x015 << 2)
+#define HHI_GP0_PLL_CNTL6 (0x016 << 2)
+#define HHI_GP0_PLL_STS (0x017 << 2)
+#define HHI_PCIE_PLL_CNTL0 (0x026 << 2)
+#define HHI_PCIE_PLL_CNTL1 (0x027 << 2)
+#define HHI_PCIE_PLL_CNTL2 (0x028 << 2)
+#define HHI_PCIE_PLL_CNTL3 (0x029 << 2)
+#define HHI_PCIE_PLL_CNTL4 (0x02a << 2)
+#define HHI_PCIE_PLL_CNTL5 (0x02b << 2)
+#define HHI_PCIE_PLL_STS (0x02c << 2)
+#define HHI_XTAL_DIVN_CNTL (0x02f << 2)
+#define HHI_GCLK2_MPEG0 (0x030 << 2)
+#define HHI_GCLK2_MPEG1 (0x031 << 2)
+#define HHI_GCLK2_MPEG2 (0x032 << 2)
+#define HHI_GCLK2_OTHER (0x034 << 2)
+#define HHI_HIFI_PLL_CNTL0 (0x036 << 2)
+#define HHI_HIFI_PLL_CNTL1 (0x037 << 2)
+#define HHI_HIFI_PLL_CNTL2 (0x038 << 2)
+#define HHI_HIFI_PLL_CNTL3 (0x039 << 2)
+#define HHI_HIFI_PLL_CNTL4 (0x03a << 2)
+#define HHI_HIFI_PLL_CNTL5 (0x03b << 2)
+#define HHI_HIFI_PLL_CNTL6 (0x03c << 2)
+#define HHI_HIFI_PLL_STS (0x03d << 2)
+#define HHI_TIMER90K (0x03f << 2)
+#define HHI_MEM_PD_REG0 (0x040 << 2)
+#define HHI_VPU_MEM_PD_REG0 (0x041 << 2)
+#define HHI_VPU_MEM_PD_REG1 (0x042 << 2)
+#define HHI_VIID_CLK_DIV (0x04a << 2)
+#define HHI_VIID_CLK_CNTL (0x04b << 2)
+#define HHI_VPU_MEM_PD_REG2 (0x04d << 2)
+#define HHI_GCLK_LOCK (0x04f << 2)
+#define HHI_GCLK_MPEG0 (0x050 << 2)
+#define HHI_GCLK_MPEG1 (0x051 << 2)
+#define HHI_GCLK_MPEG2 (0x052 << 2)
+#define HHI_GCLK_OTHER (0x054 << 2)
+#define HHI_GCLK_SP_MPEG (0x055 << 2)
+#define HHI_SYS_CPU_CLK_CNTL1 (0x057 << 2)
+#define HHI_SYS_CPU_RESET_CNTL (0x058 << 2)
+#define HHI_VID_CLK_DIV (0x059 << 2)
+#define HHI_MPEG_CLK_CNTL (0x05d << 2)
+#define HHI_VID_CLK_CNTL (0x05f << 2)
+#define HHI_TS_CLK_CNTL (0x064 << 2)
+#define HHI_VID_CLK_CNTL2 (0x065 << 2)
+#define HHI_SYS_CPU_CLK_CNTL (0x067 << 2)
+#define HHI_VID_PLL_CLK_DIV (0x068 << 2)
+#define HHI_MALI_CLK_CNTL (0x06c << 2)
+#define HHI_VPU_CLKC_CNTL (0x06d << 2)
+#define HHI_VPU_CLK_CNTL (0x06f << 2)
+#define HHI_HDMI_CLK_CNTL (0x073 << 2)
+#define HHI_ETH_CLK_CNTL (0x076 << 2)
+#define HHI_VDEC_CLK_CNTL (0x078 << 2)
+#define HHI_VDEC2_CLK_CNTL (0x079 << 2)
+#define HHI_VDEC3_CLK_CNTL (0x07a << 2)
+#define HHI_VDEC4_CLK_CNTL (0x07b << 2)
+#define HHI_HDCP22_CLK_CNTL (0x07c << 2)
+#define HHI_VAPBCLK_CNTL (0x07d << 2)
+#define HHI_VPU_CLKB_CNTL (0x083 << 2)
+#define HHI_GEN_CLK_CNTL (0x08a << 2)
+#define HHI_VDIN_MEAS_CLK_CNTL (0x094 << 2)
+#define HHI_MIPIDSI_PHY_CLK_CNTL (0x095 << 2)
+#define HHI_NAND_CLK_CNTL (0x097 << 2)
+#define HHI_SD_EMMC_CLK_CNTL (0x099 << 2)
+#define HHI_WAVE420L_CLK_CNTL (0x09a << 2)
+#define HHI_WAVE420L_CLK_CNTL2 (0x09b << 2)
+#define HHI_MPLL_CNTL0 (0x09e << 2)
+#define HHI_MPLL_CNTL1 (0x09f << 2)
+#define HHI_MPLL_CNTL2 (0x0a0 << 2)
+#define HHI_MPLL_CNTL3 (0x0a1 << 2)
+#define HHI_MPLL_CNTL4 (0x0a2 << 2)
+#define HHI_MPLL_CNTL5 (0x0a3 << 2)
+#define HHI_MPLL_CNTL6 (0x0a4 << 2)
+#define HHI_MPLL_CNTL7 (0x0a5 << 2)
+#define HHI_MPLL_CNTL8 (0x0a6 << 2)
+#define HHI_MPLL_STS (0x0a7 << 2)
+#define HHI_FIX_PLL_CNTL0 (0x0a8 << 2)
+#define HHI_FIX_PLL_CNTL1 (0x0a9 << 2)
+#define HHI_FIX_PLL_CNTL2 (0x0aa << 2)
+#define HHI_FIX_PLL_CNTL3 (0x0ab << 2)
+#define HHI_FIX_PLL_CNTL4 (0x0ac << 2)
+#define HHI_FIX_PLL_CNTL5 (0x0ad << 2)
+#define HHI_FIX_PLL_CNTL6 (0x0ae << 2)
+#define HHI_FIX_PLL_STS (0x0af << 2)
+#define HHI_VDAC_CNTL0 (0x0bb << 2)
+#define HHI_VDAC_CNTL1 (0x0bc << 2)
+#define HHI_SYS_PLL_CNTL0 (0x0bd << 2)
+#define HHI_SYS_PLL_CNTL1 (0x0be << 2)
+#define HHI_SYS_PLL_CNTL2 (0x0bf << 2)
+#define HHI_SYS_PLL_CNTL3 (0x0c0 << 2)
+#define HHI_SYS_PLL_CNTL4 (0x0c1 << 2)
+#define HHI_SYS_PLL_CNTL5 (0x0c2 << 2)
+#define HHI_SYS_PLL_CNTL6 (0x0c3 << 2)
+#define HHI_SYS_PLL_STS (0x0c4 << 2)
+#define HHI_HDMI_PLL_CNTL0 (0x0c8 << 2)
+#define HHI_HDMI_PLL_CNTL1 (0x0c9 << 2)
+#define HHI_HDMI_PLL_CNTL2 (0x0ca << 2)
+#define HHI_HDMI_PLL_CNTL3 (0x0cb << 2)
+#define HHI_HDMI_PLL_CNTL4 (0x0cc << 2)
+#define HHI_HDMI_PLL_CNTL5 (0x0cd << 2)
+#define HHI_HDMI_PLL_CNTL6 (0x0ce << 2)
+#define HHI_HDMI_PLL_STS (0x0cf << 2)
+#define HHI_HDMI_PHY_CNTL0 (0x0e8 << 2)
+#define HHI_HDMI_PHY_CNTL1 (0x0e9 << 2)
+#define HHI_HDMI_PHY_CNTL2 (0x0ea << 2)
+#define HHI_HDMI_PHY_CNTL3 (0x0eb << 2)
+#define HHI_HDMI_PHY_CNTL4 (0x0ec << 2)
+#define HHI_HDMI_PHY_CNTL5 (0x0ed << 2)
+#define HHI_HDMI_PHY_STATUS (0x0ee << 2)
+#define HHI_VID_LOCK_CLK_CNTL (0x0f2 << 2)
+#define HHI_AXI_PIPEL_CNTL (0x0f4 << 2)
+#define HHI_BT656_CLK_CNTL (0x0f5 << 2)
+#define HHI_CDAC_CLK_CNTL (0x0f6 << 2)
+#define HHI_SPICC_CLK_CNTL (0x0f7 << 2)
+
+
+#define ENCL_TCON_INVERT_CTL (0x1bfd << 2)
+#define ENCL_SYNC_LINE_LENGTH (0x1c4c << 2)
+#define ENCL_SYNC_PIXEL_EN (0x1c4d << 2)
+#define ENCL_SYNC_TO_LINE_EN (0x1c4e << 2)
+#define ENCL_SYNC_TO_PIXEL (0x1c4f << 2)
+#define ENCL_VFIFO2VD_CTL (0x1c90 << 2)
+#define ENCL_VFIFO2VD_PIXEL_START (0x1c91 << 2)
+#define ENCL_VFIFO2VD_PIXEL_END (0x1c92 << 2)
+#define ENCL_VFIFO2VD_LINE_TOP_START (0x1c93 << 2)
+#define ENCL_VFIFO2VD_LINE_TOP_END (0x1c94 << 2)
+#define ENCL_VFIFO2VD_LINE_BOT_START (0x1c95 << 2)
+#define ENCL_VFIFO2VD_LINE_BOT_END (0x1c96 << 2)
+#define ENCL_VFIFO2VD_CTL2 (0x1c97 << 2)
+#define ENCL_TST_EN (0x1c98 << 2)
+#define ENCL_TST_MDSEL (0x1c99 << 2)
+#define ENCL_TST_Y (0x1c9a << 2)
+#define ENCL_TST_CB (0x1c9b << 2)
+#define ENCL_TST_CR (0x1c9c << 2)
+#define ENCL_TST_CLRBAR_STRT (0x1c9d << 2)
+#define ENCL_TST_CLRBAR_WIDTH (0x1c9e << 2)
+#define ENCL_TST_VDCNT_STSET (0x1c9f << 2)
+#define ENCL_VIDEO_EN (0x1ca0 << 2)
+#define ENCL_VIDEO_Y_SCL (0x1ca1 << 2)
+#define ENCL_VIDEO_PB_SCL (0x1ca2 << 2)
+#define ENCL_VIDEO_PR_SCL (0x1ca3 << 2)
+#define ENCL_VIDEO_Y_OFFST (0x1ca4 << 2)
+#define ENCL_VIDEO_PB_OFFST (0x1ca5 << 2)
+#define ENCL_VIDEO_PR_OFFST (0x1ca6 << 2)
+#define ENCL_VIDEO_MODE (0x1ca7 << 2)
+#define ENCL_VIDEO_MODE_ADV (0x1ca8 << 2)
+#define ENCL_DBG_PX_RST (0x1ca9 << 2)
+#define ENCL_DBG_LN_RST (0x1caa << 2)
+#define ENCL_DBG_PX_INT (0x1cab << 2)
+#define ENCL_DBG_LN_INT (0x1cac << 2)
+#define ENCL_VIDEO_YFP1_HTIME (0x1cad << 2)
+#define ENCL_VIDEO_YFP2_HTIME (0x1cae << 2)
+#define ENCL_VIDEO_YC_DLY (0x1caf << 2)
+#define ENCL_VIDEO_MAX_PXCNT (0x1cb0 << 2)
+#define ENCL_VIDEO_HAVON_END (0x1cb1 << 2)
+#define ENCL_VIDEO_HAVON_BEGIN (0x1cb2 << 2)
+#define ENCL_VIDEO_VAVON_ELINE (0x1cb3 << 2)
+#define ENCL_VIDEO_VAVON_BLINE (0x1cb4 << 2)
+#define ENCL_VIDEO_HSO_BEGIN (0x1cb5 << 2)
+#define ENCL_VIDEO_HSO_END (0x1cb6 << 2)
+#define ENCL_VIDEO_VSO_BEGIN (0x1cb7 << 2)
+#define ENCL_VIDEO_VSO_END (0x1cb8 << 2)
+#define ENCL_VIDEO_VSO_BLINE (0x1cb9 << 2)
+#define ENCL_VIDEO_VSO_ELINE (0x1cba << 2)
+#define ENCL_VIDEO_MAX_LNCNT (0x1cbb << 2)
+#define ENCL_VIDEO_BLANKY_VAL (0x1cbc << 2)
+#define ENCL_VIDEO_BLANKPB_VAL (0x1cbd << 2)
+#define ENCL_VIDEO_BLANKPR_VAL (0x1cbe << 2)
+#define ENCL_VIDEO_HOFFST (0x1cbf << 2)
+#define ENCL_VIDEO_VOFFST (0x1cc0 << 2)
+#define ENCL_VIDEO_RGB_CTRL (0x1cc1 << 2)
+#define ENCL_VIDEO_FILT_CTRL (0x1cc2 << 2)
+#define ENCL_VIDEO_OFLD_VPEQ_OFST (0x1cc3 << 2)
+#define ENCL_VIDEO_OFLD_VOAV_OFST (0x1cc4 << 2)
+#define ENCL_VIDEO_MATRIX_CB (0x1cc5 << 2)
+#define ENCL_VIDEO_MATRIX_CR (0x1cc6 << 2)
+#define ENCL_VIDEO_RGBIN_CTRL (0x1cc7 << 2)
+#define ENCL_MAX_LINE_SWITCH_POINT (0x1cc8 << 2)
+#define ENCL_DACSEL_0 (0x1cc9 << 2)
+#define ENCL_DACSEL_1 (0x1cca << 2)
+#define ENCL_INFO_READ (0x271f << 2)
+
+#define VPU_VIU_VENC_MUX_CTRL (0x271a << 2)
+#define VPU_HDMI_SETTING (0x271b << 2)
+#define VPU_HDMI_DATA_OVR (0x2727 << 2)
+#define VPU_HDMI_FMT_CTRL (0x2743 << 2)
+
+#define L_GAMMA_CNTL_PORT (0x1400 << 2)
+#define L_GAMMA_DATA_PORT (0x1401 << 2)
+#define L_GAMMA_ADDR_PORT (0x1402 << 2)
+#define L_GAMMA_VCOM_HSWITCH_ADDR (0x1403 << 2)
+#define L_RGB_BASE_ADDR (0x1405 << 2)
+#define L_RGB_COEFF_ADDR (0x1406 << 2)
+#define L_POL_CNTL_ADDR (0x1407 << 2)
+#define L_DITH_CNTL_ADDR (0x1408 << 2)
+#define L_GAMMA_PROBE_CTRL (0x1409 << 2)
+#define L_GAMMA_PROBE_COLOR_L (0x140a << 2)
+#define L_GAMMA_PROBE_COLOR_H (0x140b << 2)
+#define L_GAMMA_PROBE_HL_COLOR (0x140c << 2)
+#define L_GAMMA_PROBE_POS_X (0x140d << 2)
+#define L_GAMMA_PROBE_POS_Y (0x140e << 2)
+#define L_STH1_HS_ADDR (0x1410 << 2)
+#define L_STH1_HE_ADDR (0x1411 << 2)
+#define L_STH1_VS_ADDR (0x1412 << 2)
+#define L_STH1_VE_ADDR (0x1413 << 2)
+#define L_STH2_HS_ADDR (0x1414 << 2)
+#define L_STH2_HE_ADDR (0x1415 << 2)
+#define L_STH2_VS_ADDR (0x1416 << 2)
+#define L_STH2_VE_ADDR (0x1417 << 2)
+#define L_OEH_HS_ADDR (0x1418 << 2)
+#define L_OEH_HE_ADDR (0x1419 << 2)
+#define L_OEH_VS_ADDR (0x141a << 2)
+#define L_OEH_VE_ADDR (0x141b << 2)
+#define L_VCOM_HSWITCH_ADDR (0x141c << 2)
+#define L_VCOM_VS_ADDR (0x141d << 2)
+#define L_VCOM_VE_ADDR (0x141e << 2)
+#define L_CPV1_HS_ADDR (0x141f << 2)
+#define L_CPV1_HE_ADDR (0x1420 << 2)
+#define L_CPV1_VS_ADDR (0x1421 << 2)
+#define L_CPV1_VE_ADDR (0x1422 << 2)
+#define L_CPV2_HS_ADDR (0x1423 << 2)
+#define L_CPV2_HE_ADDR (0x1424 << 2)
+#define L_CPV2_VS_ADDR (0x1425 << 2)
+#define L_CPV2_VE_ADDR (0x1426 << 2)
+#define L_STV1_HS_ADDR (0x1427 << 2)
+#define L_STV1_HE_ADDR (0x1428 << 2)
+#define L_STV1_VS_ADDR (0x1429 << 2)
+#define L_STV1_VE_ADDR (0x142a << 2)
+#define L_STV2_HS_ADDR (0x142b << 2)
+#define L_STV2_HE_ADDR (0x142c << 2)
+#define L_STV2_VS_ADDR (0x142d << 2)
+#define L_STV2_VE_ADDR (0x142e << 2)
+#define L_OEV1_HS_ADDR (0x142f << 2)
+#define L_OEV1_HE_ADDR (0x1430 << 2)
+#define L_OEV1_VS_ADDR (0x1431 << 2)
+#define L_OEV1_VE_ADDR (0x1432 << 2)
+#define L_OEV2_HS_ADDR (0x1433 << 2)
+#define L_OEV2_HE_ADDR (0x1434 << 2)
+#define L_OEV2_VS_ADDR (0x1435 << 2)
+#define L_OEV2_VE_ADDR (0x1436 << 2)
+#define L_OEV3_HS_ADDR (0x1437 << 2)
+#define L_OEV3_HE_ADDR (0x1438 << 2)
+#define L_OEV3_VS_ADDR (0x1439 << 2)
+#define L_OEV3_VE_ADDR (0x143a << 2)
+#define L_LCD_PWR_ADDR (0x143b << 2)
+#define L_LCD_PWM0_LO_ADDR (0x143c << 2)
+#define L_LCD_PWM0_HI_ADDR (0x143d << 2)
+#define L_LCD_PWM1_LO_ADDR (0x143e << 2)
+#define L_LCD_PWM1_HI_ADDR (0x143f << 2)
+#define L_INV_CNT_ADDR (0x1440 << 2)
+#define L_TCON_MISC_SEL_ADDR (0x1441 << 2)
+#define L_DUAL_PORT_CNTL_ADDR (0x1442 << 2)
+#define L_TCON_DOUBLE_CTL (0x1449 << 2)
+#define L_TCON_PATTERN_HI (0x144a << 2)
+#define L_TCON_PATTERN_LO (0x144b << 2)
+#define L_DE_HS_ADDR (0x1451 << 2)
+#define L_DE_HE_ADDR (0x1452 << 2)
+#define L_DE_VS_ADDR (0x1453 << 2)
+#define L_DE_VE_ADDR (0x1454 << 2)
+#define L_HSYNC_HS_ADDR (0x1455 << 2)
+#define L_HSYNC_HE_ADDR (0x1456 << 2)
+#define L_HSYNC_VS_ADDR (0x1457 << 2)
+#define L_HSYNC_VE_ADDR (0x1458 << 2)
+#define L_VSYNC_HS_ADDR (0x1459 << 2)
+#define L_VSYNC_HE_ADDR (0x145a << 2)
+#define L_VSYNC_VS_ADDR (0x145b << 2)
+#define L_VSYNC_VE_ADDR (0x145c << 2)
+#define L_LCD_MCU_CTL (0x145d << 2)
+
+#define VPP_DUMMY_DATA (0x1d00 << 2)
+#define VPP_LINE_IN_LENGTH (0x1d01 << 2)
+#define VPP_PIC_IN_HEIGHT (0x1d02 << 2)
+#define VPP_SCALE_COEF_IDX (0x1d03 << 2)
+#define VPP_SCALE_COEF (0x1d04 << 2)
+#define VPP_VSC_REGION12_STARTP (0x1d05 << 2)
+#define VPP_VSC_REGION34_STARTP (0x1d06 << 2)
+#define VPP_VSC_REGION4_ENDP (0x1d07 << 2)
+#define VPP_VSC_START_PHASE_STEP (0x1d08 << 2)
+#define VPP_VSC_REGION0_PHASE_SLOPE (0x1d09 << 2)
+#define VPP_VSC_REGION1_PHASE_SLOPE (0x1d0a << 2)
+#define VPP_VSC_REGION3_PHASE_SLOPE (0x1d0b << 2)
+#define VPP_VSC_REGION4_PHASE_SLOPE (0x1d0c << 2)
+#define VPP_VSC_PHASE_CTRL (0x1d0d << 2)
+#define VPP_VSC_INI_PHASE (0x1d0e << 2)
+#define VPP_HSC_REGION12_STARTP (0x1d10 << 2)
+#define VPP_HSC_REGION34_STARTP (0x1d11 << 2)
+#define VPP_HSC_REGION4_ENDP (0x1d12 << 2)
+#define VPP_HSC_START_PHASE_STEP (0x1d13 << 2)
+#define VPP_HSC_REGION0_PHASE_SLOPE (0x1d14 << 2)
+#define VPP_HSC_REGION1_PHASE_SLOPE (0x1d15 << 2)
+#define VPP_HSC_REGION3_PHASE_SLOPE (0x1d16 << 2)
+#define VPP_HSC_REGION4_PHASE_SLOPE (0x1d17 << 2)
+#define VPP_HSC_PHASE_CTRL (0x1d18 << 2)
+#define VPP_SC_MISC (0x1d19 << 2)
+#define VPP_PREBLEND_VD1_H_START_END (0x1d1a << 2)
+#define VPP_PREBLEND_VD1_V_START_END (0x1d1b << 2)
+#define VPP_POSTBLEND_VD1_H_START_END (0x1d1c << 2)
+#define VPP_POSTBLEND_VD1_V_START_END (0x1d1d << 2)
+#define VPP_BLEND_VD2_H_START_END (0x1d1e << 2)
+#define VPP_BLEND_VD2_V_START_END (0x1d1f << 2)
+#define VPP_PREBLEND_H_SIZE (0x1d20 << 2)
+#define VPP_POSTBLEND_H_SIZE (0x1d21 << 2)
+#define VPP_HOLD_LINES (0x1d22 << 2)
+#define VPP_BLEND_ONECOLOR_CTRL (0x1d23 << 2)
+#define VPP_PREBLEND_CURRENT_XY (0x1d24 << 2)
+#define VPP_POSTBLEND_CURRENT_XY (0x1d25 << 2)
+#define VPP_MISC (0x1d26 << 2)
+#define VPP_OFIFO_SIZE (0x1d27 << 2)
+#define VPP_FIFO_STATUS (0x1d28 << 2)
+#define VPP_SMOKE_CTRL (0x1d29 << 2)
+#define VPP_SMOKE1_VAL (0x1d2a << 2)
+#define VPP_SMOKE2_VAL (0x1d2b << 2)
+#define VPP_SMOKE3_VAL (0x1d2c << 2)
+#define VPP_SMOKE1_H_START_END (0x1d2d << 2)
+#define VPP_SMOKE1_V_START_END (0x1d2e << 2)
+#define VPP_SMOKE2_H_START_END (0x1d2f << 2)
+#define VPP_SMOKE2_V_START_END (0x1d30 << 2)
+#define VPP_SMOKE3_H_START_END (0x1d31 << 2)
+#define VPP_SMOKE3_V_START_END (0x1d32 << 2)
+#define VPP_SCO_FIFO_CTRL (0x1d33 << 2)
+#define VPP_HSC_PHASE_CTRL1 (0x1d34 << 2)
+#define VPP_HSC_INI_PAT_CTRL (0x1d35 << 2)
+#define VPP_VADJ_CTRL (0x1d40 << 2)
+#define VPP_VADJ1_Y (0x1d41 << 2)
+#define VPP_VADJ1_MA_MB (0x1d42 << 2)
+#define VPP_VADJ1_MC_MD (0x1d43 << 2)
+#define VPP_VADJ2_Y (0x1d44 << 2)
+#define VPP_VADJ2_MA_MB (0x1d45 << 2)
+#define VPP_VADJ2_MC_MD (0x1d46 << 2)
+#define VPP_HSHARP_CTRL (0x1d50 << 2)
+#define VPP_HSHARP_LUMA_THRESH01 (0x1d51 << 2)
+#define VPP_HSHARP_LUMA_THRESH23 (0x1d52 << 2)
+#define VPP_HSHARP_CHROMA_THRESH01 (0x1d53 << 2)
+#define VPP_HSHARP_CHROMA_THRESH23 (0x1d54 << 2)
+#define VPP_HSHARP_LUMA_GAIN (0x1d55 << 2)
+#define VPP_HSHARP_CHROMA_GAIN (0x1d56 << 2)
+#define VPP_MATRIX_PROBE_COLOR (0x1d5c << 2)
+#define VPP_MATRIX_PROBE_COLOR1 (0x1dd7 << 2)
+#define VPP_MATRIX_HL_COLOR (0x1d5d << 2)
+#define VPP_MATRIX_PROBE_POS (0x1d5e << 2)
+#define VPP_MATRIX_CTRL (0x1d5f << 2)
+#define VPP_MATRIX_COEF00_01 (0x1d60 << 2)
+#define VPP_MATRIX_COEF02_10 (0x1d61 << 2)
+#define VPP_MATRIX_COEF11_12 (0x1d62 << 2)
+#define VPP_MATRIX_COEF20_21 (0x1d63 << 2)
+#define VPP_MATRIX_COEF22 (0x1d64 << 2)
+#define VPP_MATRIX_OFFSET0_1 (0x1d65 << 2)
+#define VPP_MATRIX_OFFSET2 (0x1d66 << 2)
+#define VPP_MATRIX_PRE_OFFSET0_1 (0x1d67 << 2)
+#define VPP_MATRIX_PRE_OFFSET2 (0x1d68 << 2)
+#define VPP_DUMMY_DATA1 (0x1d69 << 2)
+#define VPP_GAINOFF_CTRL0 (0x1d6a << 2)
+#define VPP_GAINOFF_CTRL1 (0x1d6b << 2)
+#define VPP_GAINOFF_CTRL2 (0x1d6c << 2)
+#define VPP_GAINOFF_CTRL3 (0x1d6d << 2)
+#define VPP_GAINOFF_CTRL4 (0x1d6e << 2)
+#define VPP_CHROMA_ADDR_PORT (0x1d70 << 2)
+#define VPP_CHROMA_DATA_PORT (0x1d71 << 2)
+#define VPP_GCLK_CTRL0 (0x1d72 << 2)
+#define VPP_GCLK_CTRL1 (0x1d73 << 2)
+#define VPP_SC_GCLK_CTRL (0x1d74 << 2)
+#define VPP_MISC1 (0x1d76 << 2)
+#define VPP_SRSCL_GCLK_CTRL (0x1d77 << 2)
+#define VPP_OSDSR_GCLK_CTRL (0x1d78 << 2)
+#define VPP_XVYCC_GCLK_CTRL (0x1d79 << 2)
+#define VPP_BLACKEXT_CTRL (0x1d80 << 2)
+#define VPP_DNLP_CTRL_00 (0x1d81 << 2)
+#define VPP_DNLP_CTRL_01 (0x1d82 << 2)
+#define VPP_DNLP_CTRL_02 (0x1d83 << 2)
+#define VPP_DNLP_CTRL_03 (0x1d84 << 2)
+#define VPP_DNLP_CTRL_04 (0x1d85 << 2)
+#define VPP_DNLP_CTRL_05 (0x1d86 << 2)
+#define VPP_DNLP_CTRL_06 (0x1d87 << 2)
+#define VPP_DNLP_CTRL_07 (0x1d88 << 2)
+#define VPP_DNLP_CTRL_08 (0x1d89 << 2)
+#define VPP_DNLP_CTRL_09 (0x1d8a << 2)
+#define VPP_DNLP_CTRL_10 (0x1d8b << 2)
+#define VPP_DNLP_CTRL_11 (0x1d8c << 2)
+#define VPP_DNLP_CTRL_12 (0x1d8d << 2)
+#define VPP_DNLP_CTRL_13 (0x1d8e << 2)
+#define VPP_DNLP_CTRL_14 (0x1d8f << 2)
+#define VPP_DNLP_CTRL_15 (0x1d90 << 2)
+#define VPP_SRSHARP0_CTRL (0x1d91 << 2)
+#define VPP_SRSHARP1_CTRL (0x1d92 << 2)
+#define VPP_DOLBY_CTRL (0x1d93 << 2)
+#define VPP_DAT_CONV_PARA0 (0x1d94 << 2)
+#define VPP_DAT_CONV_PARA1 (0x1d95 << 2)
+#define VPP_SYNC_SEL0 (0x1d96 << 2)
+#define VPP_VADJ1_BLACK_VAL (0x1d97 << 2)
+#define VPP_VADJ2_BLACK_VAL (0x1d98 << 2)
+#define VPP_BLUE_STRETCH_1 (0x1d9c << 2)
+#define VPP_BLUE_STRETCH_2 (0x1d9d << 2)
+#define VPP_BLUE_STRETCH_3 (0x1d9e << 2)
+#define VPP_CCORING_CTRL (0x1da0 << 2)
+#define VPP_VE_ENABLE_CTRL (0x1da1 << 2)
+#define VPP_VE_DEMO_LEFT_TOP_SCREEN_WIDTH (0x1da2 << 2)
+#define VPP_VE_DEMO_CENTER_BAR (0x1da3 << 2)
+#define VPP_VE_H_V_SIZE (0x1da4 << 2)
+#define VPP_OUT_H_V_SIZE (0x1da5 << 2)
+#define VPP_IN_H_V_SIZE (0x1da6 << 2)
+#define VPP_VDO_MEAS_CTRL (0x1da8 << 2)
+#define VPP_VDO_MEAS_VS_COUNT_HI (0x1da9 << 2)
+#define VPP_VDO_MEAS_VS_COUNT_LO (0x1daa << 2)
+#define VPP_INPUT_CTRL (0x1dab << 2)
+#define VPP_CTI_CTRL2 (0x1dac << 2)
+#define VPP_PEAKING_SAT_THD1 (0x1dad << 2)
+#define VPP_PEAKING_SAT_THD2 (0x1dae << 2)
+#define VPP_PEAKING_SAT_THD3 (0x1daf << 2)
+#define VPP_PEAKING_SAT_THD4 (0x1db0 << 2)
+#define VPP_PEAKING_SAT_THD5 (0x1db1 << 2)
+#define VPP_PEAKING_SAT_THD6 (0x1db2 << 2)
+#define VPP_PEAKING_SAT_THD7 (0x1db3 << 2)
+#define VPP_PEAKING_SAT_THD8 (0x1db4 << 2)
+#define VPP_PEAKING_SAT_THD9 (0x1db5 << 2)
+#define VPP_PEAKING_GAIN_ADD1 (0x1db6 << 2)
+#define VPP_PEAKING_GAIN_ADD2 (0x1db7 << 2)
+#define VPP_PEAKING_DNLP (0x1db8 << 2)
+#define VPP_SHARP_DEMO_WIN_CTRL1 (0x1db9 << 2)
+#define VPP_SHARP_DEMO_WIN_CTRL2 (0x1dba << 2)
+#define VPP_FRONT_HLTI_CTRL (0x1dbb << 2)
+#define VPP_FRONT_CTI_CTRL (0x1dbc << 2)
+#define VPP_FRONT_CTI_CTRL2 (0x1dbd << 2)
+#define VPP_OSD_VSC_PHASE_STEP (0x1dc0 << 2)
+#define VPP_OSD_VSC_INI_PHASE (0x1dc1 << 2)
+#define VPP_OSD_VSC_CTRL0 (0x1dc2 << 2)
+#define VPP_OSD_HSC_PHASE_STEP (0x1dc3 << 2)
+#define VPP_OSD_HSC_INI_PHASE (0x1dc4 << 2)
+#define VPP_OSD_HSC_CTRL0 (0x1dc5 << 2)
+#define VPP_OSD_HSC_INI_PAT_CTRL (0x1dc6 << 2)
+#define VPP_OSD_SC_DUMMY_DATA (0x1dc7 << 2)
+#define VPP_OSD_SC_CTRL0 (0x1dc8 << 2)
+#define VPP_OSD_SCI_WH_M1 (0x1dc9 << 2)
+#define VPP_OSD_SCO_H_START_END (0x1dca << 2)
+#define VPP_OSD_SCO_V_START_END (0x1dcb << 2)
+#define VPP_OSD_SCALE_COEF_IDX (0x1dcc << 2)
+#define VPP_OSD_SCALE_COEF (0x1dcd << 2)
+#define VPP_INT_LINE_NUM (0x1dce << 2)
+#define VPP_XVYCC_MISC (0x1dcf << 2)
+#define VPP_HLTI_DN_FLT (0x1dd0 << 2)
+#define VPP_HLTI_GAIN (0x1dd1 << 2)
+#define VPP_HLTI_PARA (0x1dd2 << 2)
+#define VPP_HCTI_DN_FLT (0x1dd3 << 2)
+#define VPP_HCTI_GAIN (0x1dd4 << 2)
+#define VPP_HCTI_PARA (0x1dd5 << 2)
+#define VPP_VCTI_PARA (0x1dd6 << 2)
+#define VPP_OFIFO_URG_CTRL (0x1dd8 << 2)
+#define VPP_CLIP_MISC0 (0x1dd9 << 2)
+#define VPP_CLIP_MISC1 (0x1dda << 2)
+#define VPP_MATRIX_COEF13_14 (0x1ddb << 2)
+#define VPP_MATRIX_COEF23_24 (0x1ddc << 2)
+#define VPP_MATRIX_COEF15_25 (0x1ddd << 2)
+#define VPP_MATRIX_CLIP (0x1dde << 2)
+#define VPP_XVYCC_MISC0 (0x1ddf << 2)
+#define VPP_XVYCC_MISC1 (0x1de0 << 2)
+#define VPP_VD1_CLIP_MISC0 (0x1de1 << 2)
+#define VPP_VD1_CLIP_MISC1 (0x1de2 << 2)
+#define VPP_VD2_CLIP_MISC0 (0x1de3 << 2)
+#define VPP_VD2_CLIP_MISC1 (0x1de4 << 2)
+#define VPP_VE_DITHER_CTRL (0x3120 << 2)
+#define VPP_VE_DITHER_LUT_1 (0x3121 << 2)
+#define VPP_VE_DITHER_LUT_2 (0x3122 << 2)
+#define VPP_VE_DITHER_LUT_3 (0x3123 << 2)
+#define VPP_VE_DITHER_LUT_4 (0x3124 << 2)
+#define VPP_VE_DITHER_LUT_5 (0x3125 << 2)
+#define VPP_VE_DITHER_LUT_6 (0x3126 << 2)
+#define VPP_VE_DITHER_LUT_7 (0x3127 << 2)
+#define VPP_VE_DITHER_LUT_8 (0x3128 << 2)
+#define VPP_VE_DITHER_LUT_9 (0x3129 << 2)
+#define VPP_VE_DITHER_LUT_10 (0x312a << 2)
+#define VPP_VE_DITHER_LUT_11 (0x312b << 2)
+#define VPP_VE_DITHER_LUT_12 (0x312c << 2)
+#define VPP_OSDSC_DITHER_CTRL (0x3130 << 2)
+#define VPP_OSDSC_DITHER_LUT_1 (0x3131 << 2)
+#define VPP_OSDSC_DITHER_LUT_2 (0x3132 << 2)
+#define VPP_OSDSC_DITHER_LUT_3 (0x3133 << 2)
+#define VPP_OSDSC_DITHER_LUT_4 (0x3134 << 2)
+#define VPP_OSDSC_DITHER_LUT_5 (0x3135 << 2)
+#define VPP_OSDSC_DITHER_LUT_6 (0x3136 << 2)
+#define VPP_OSDSC_DITHER_LUT_7 (0x3137 << 2)
+#define VPP_OSDSC_DITHER_LUT_8 (0x3138 << 2)
+#define VPP_OSDSC_DITHER_LUT_9 (0x3139 << 2)
+#define VPP_OSDSC_DITHER_LUT_10 (0x313a << 2)
+#define VPP_OSDSC_DITHER_LUT_11 (0x313b << 2)
+#define VPP_OSDSC_DITHER_LUT_12 (0x313c << 2)
+#define VPP_OSDSC_DITHER_LUT_13 (0x313d << 2)
+#define VPP_OSDSC_DITHER_LUT_14 (0x313e << 2)
+#define VPP_OSDSC_DITHER_LUT_15 (0x313f << 2)
+#define VPP_EOTF_CTL (0x31d0 << 2)
+#define VPP_EOTF_COEF00_01 (0x31d1 << 2)
+#define VPP_EOTF_COEF02_10 (0x31d2 << 2)
+#define VPP_EOTF_COEF11_12 (0x31d3 << 2)
+#define VPP_EOTF_COEF20_21 (0x31d4 << 2)
+#define VPP_EOTF_COEF22_RS (0x31d5 << 2)
+#define VPP_EOTF_LUT_ADDR_PORT (0x31d6 << 2)
+#define VPP_EOTF_LUT_DATA_PORT (0x31d7 << 2)
+#define VPP_EOTF_3X3_OFST_0 (0x31d8 << 2)
+#define VPP_EOTF_3X3_OFST_1 (0x31d9 << 2)
+
+#define VPP_OUT_SATURATE (1 << 0)
+
+ /*#define HHI_VIID_CLK_DIV 0x4a*/
+#define DAC0_CLK_SEL 28
+#define DAC1_CLK_SEL 24
+#define DAC2_CLK_SEL 20
+#define VCLK2_XD_RST 17
+#define VCLK2_XD_EN 16
+#define ENCL_CLK_SEL 12
+#define VCLK2_XD 0
+
+ /*#define HHI_VIID_CLK_CNTL 0x4b*/
+#define VCLK2_EN 19
+#define VCLK2_CLK_IN_SEL 16
+#define VCLK2_SOFT_RST 15
+#define VCLK2_DIV12_EN 4
+#define VCLK2_DIV6_EN 3
+#define VCLK2_DIV4_EN 2
+#define VCLK2_DIV2_EN 1
+#define VCLK2_DIV1_EN 0
+
+ /*#define HHI_VIID_DIVIDER_CNTL 0x4c*/
+#define DIV_CLK_IN_EN 16
+#define DIV_CLK_SEL 15
+#define DIV_POST_TCNT 12
+#define DIV_LVDS_CLK_EN 11
+#define DIV_LVDS_DIV2 10
+#define DIV_POST_SEL 8
+#define DIV_POST_SOFT_RST 7
+#define DIV_PRE_SEL 4
+#define DIV_PRE_SOFT_RST 3
+#define DIV_POST_RST 1
+#define DIV_PRE_RST 0
+
+ /*#define HHI_VID_CLK_DIV 0x59*/
+#define ENCI_CLK_SEL 28
+#define ENCP_CLK_SEL 24
+#define ENCT_CLK_SEL 20
+#define VCLK_XD_RST 17
+#define VCLK_XD_EN 16
+#define ENCL_CLK_SEL 12
+#define VCLK_XD1 8
+#define VCLK_XD0 0
+
+ /*#define HHI_VID_CLK_CNTL2 0x65*/
+#define HDMI_TX_PIXEL_GATE_VCLK 5
+#define VDAC_GATE_VCLK 4
+#define ENCL_GATE_VCLK 3
+#define ENCP_GATE_VCLK 2
+#define ENCT_GATE_VCLK 1
+#define ENCI_GATE_VCLK 0
+
+
diff --git a/system/dev/display/astro-display/lcd.c b/system/dev/display/astro-display/lcd.c
new file mode 100644
index 0000000..239b412
--- /dev/null
+++ b/system/dev/display/astro-display/lcd.c
@@ -0,0 +1,6 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "astro-display.h"
+
diff --git a/system/dev/display/astro-display/mipi_dsi.c b/system/dev/display/astro-display/mipi_dsi.c
new file mode 100644
index 0000000..28ca6d0
--- /dev/null
+++ b/system/dev/display/astro-display/mipi_dsi.c
@@ -0,0 +1,67 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "astro-display.h"
+
+static uint32_t mipi_dsi_generic_read(astro_display_t* display, uint32_t address)
+{
+ uint32_t data_out;
+
+ if (address != DW_DSI_GEN_PLD_DATA) {
+ DISP_ERROR(" Error Address : %x\n", address);
+ }
+
+ data_out = READ32_REG(MIPI_DSI, address);
+ return data_out;
+}
+
+
+static uint32_t generic_if_wr(astro_display_t* display, uint32_t address, uint32_t data_in)
+{
+ if ((address != DW_DSI_GEN_HDR) &&
+ (address != DW_DSI_GEN_PLD_DATA)) {
+ DISP_ERROR(" Error Address : 0x%x\n", address);
+ }
+
+ DISP_INFO("address 0x%x = 0x%08x\n", address, data_in);
+
+ WRITE32_REG(MIPI_DSI, address, data_in);
+
+ return 0;
+}
+
+
+static void dsi_generic_write_short_packet(astro_display_t* display, struct dsi_cmd_request_s *req)
+{
+ unsigned int d_para[2];
+
+ switch (req->data_type) {
+ case DT_GEN_SHORT_WR_1:
+ d_para[0] = (req->pld_count == 0) ?
+ 0 : (((unsigned int)req->payload[2]) & 0xff);
+ d_para[1] = 0;
+ break;
+ case DT_GEN_SHORT_WR_2:
+ d_para[0] = (req->pld_count == 0) ?
+ 0 : (((unsigned int)req->payload[2]) & 0xff);
+ d_para[1] = (req->pld_count < 2) ?
+ 0 : (((unsigned int)req->payload[3]) & 0xff);
+ break;
+ case DT_GEN_SHORT_WR_0:
+ default:
+ d_para[0] = 0;
+ d_para[1] = 0;
+ break;
+ }
+
+ generic_if_wr(display, DW_DSI_GEN_HDR,
+ ((d_para[1] << BIT_GEN_WC_MSBYTE) |
+ (d_para[0] << BIT_GEN_WC_LSBYTE) |
+ (((unsigned int)req->vc_id) << BIT_GEN_VC) |
+ (((unsigned int)req->data_type) << BIT_GEN_DT)));
+ if (req->req_ack == MIPI_DSI_DCS_REQ_ACK)
+ wait_bta_ack(display);
+ else if (req->req_ack == MIPI_DSI_DCS_NO_ACK)
+ wait_cmd_fifo_empty(display);
+}
diff --git a/system/dev/display/astro-display/rules.mk b/system/dev/display/astro-display/rules.mk
index 43b2d73..fdee69d 100644
--- a/system/dev/display/astro-display/rules.mk
+++ b/system/dev/display/astro-display/rules.mk
@@ -10,6 +10,14 @@
MODULE_SRCS += \
$(LOCAL_DIR)/astro-display.c \
+ $(LOCAL_DIR)/backlight.c \
+ $(LOCAL_DIR)/canvas.c \
+ $(LOCAL_DIR)/dsi.c \
+ $(LOCAL_DIR)/lcd.c \
+ $(LOCAL_DIR)/display_debug.c \
+ $(LOCAL_DIR)/display_config.c \
+ $(LOCAL_DIR)/display_clock.c \
+ $(LOCAL_DIR)/mipi_dsi.c \
MODULE_STATIC_LIBS := system/ulib/ddk system/ulib/sync
diff --git a/system/dev/soc/amlogic/include/soc/aml-s905d2/s905d2-hw.h b/system/dev/soc/amlogic/include/soc/aml-s905d2/s905d2-hw.h
index 8c4a265..1407178 100644
--- a/system/dev/soc/amlogic/include/soc/aml-s905d2/s905d2-hw.h
+++ b/system/dev/soc/amlogic/include/soc/aml-s905d2/s905d2-hw.h
@@ -23,6 +23,12 @@
#define S905D2_RESET_BASE 0xffd01000
#define S905D2_RESET_LENGTH 0x1000
+#define S905D2_MIPI_DSI_BASE 0xffd07000
+#define S905D2_MIPI_DSI_LENGTH 0x1000
+
+#define S905D2_DSI_PHY_BASE 0xff644000
+#define S905D2_DSI_PHY_LENGTH 0x1000
+
#define S905D2_USBPHY20_BASE 0xff636000
#define S905D2_USBPHY20_LENGTH 0x2000
@@ -32,6 +38,9 @@
#define S905D2_HIU_BASE 0xff63c000
#define S905D2_HIU_LENGTH 0x2000
+#define S905D2_VPU_BASE 0xff900000
+#define S905D2_VPU_LENGTH 0x10000
+
#define S905D2_MALI_BASE 0xffe40000
#define S905D2_MALI_LENGTH 0x40000