174e39389SWyon Bi /*
274e39389SWyon Bi * (C) Copyright 2008-2017 Fuzhou Rockchip Electronics Co., Ltd
374e39389SWyon Bi *
474e39389SWyon Bi * SPDX-License-Identifier: GPL-2.0+
574e39389SWyon Bi */
674e39389SWyon Bi
71953e619SWyon Bi #include <drm/drm_mipi_dsi.h>
81953e619SWyon Bi
974e39389SWyon Bi #include <config.h>
1074e39389SWyon Bi #include <common.h>
1174e39389SWyon Bi #include <errno.h>
1274e39389SWyon Bi #include <asm/unaligned.h>
1374e39389SWyon Bi #include <asm/io.h>
1474e39389SWyon Bi #include <asm/hardware.h>
1574e39389SWyon Bi #include <dm/device.h>
1674e39389SWyon Bi #include <dm/read.h>
1774e39389SWyon Bi #include <dm/of_access.h>
1874e39389SWyon Bi #include <syscon.h>
1974e39389SWyon Bi #include <asm/arch-rockchip/clock.h>
201953e619SWyon Bi #include <linux/iopoll.h>
2174e39389SWyon Bi
2274e39389SWyon Bi #include "rockchip_display.h"
2374e39389SWyon Bi #include "rockchip_crtc.h"
2474e39389SWyon Bi #include "rockchip_connector.h"
2574e39389SWyon Bi #include "rockchip_panel.h"
2674e39389SWyon Bi #include "rockchip_phy.h"
271953e619SWyon Bi
281953e619SWyon Bi #define UPDATE(v, h, l) (((v) << (l)) & GENMASK((h), (l)))
2974e39389SWyon Bi
3074e39389SWyon Bi #define DSI_VERSION 0x00
3174e39389SWyon Bi #define DSI_PWR_UP 0x04
3274e39389SWyon Bi #define RESET 0
3374e39389SWyon Bi #define POWERUP BIT(0)
3474e39389SWyon Bi
3574e39389SWyon Bi #define DSI_CLKMGR_CFG 0x08
3674e39389SWyon Bi #define TO_CLK_DIVIDSION(div) (((div) & 0xff) << 8)
3774e39389SWyon Bi #define TX_ESC_CLK_DIVIDSION(div) (((div) & 0xff) << 0)
3874e39389SWyon Bi
3974e39389SWyon Bi #define DSI_DPI_VCID 0x0c
4074e39389SWyon Bi #define DPI_VID(vid) (((vid) & 0x3) << 0)
4174e39389SWyon Bi
4274e39389SWyon Bi #define DSI_DPI_COLOR_CODING 0x10
4374e39389SWyon Bi #define EN18_LOOSELY BIT(8)
4474e39389SWyon Bi #define DPI_COLOR_CODING_16BIT_1 0x0
4574e39389SWyon Bi #define DPI_COLOR_CODING_16BIT_2 0x1
4674e39389SWyon Bi #define DPI_COLOR_CODING_16BIT_3 0x2
4774e39389SWyon Bi #define DPI_COLOR_CODING_18BIT_1 0x3
4874e39389SWyon Bi #define DPI_COLOR_CODING_18BIT_2 0x4
4974e39389SWyon Bi #define DPI_COLOR_CODING_24BIT 0x5
5074e39389SWyon Bi
5174e39389SWyon Bi #define DSI_DPI_CFG_POL 0x14
5274e39389SWyon Bi #define COLORM_ACTIVE_LOW BIT(4)
5374e39389SWyon Bi #define SHUTD_ACTIVE_LOW BIT(3)
5474e39389SWyon Bi #define HSYNC_ACTIVE_LOW BIT(2)
5574e39389SWyon Bi #define VSYNC_ACTIVE_LOW BIT(1)
5674e39389SWyon Bi #define DATAEN_ACTIVE_LOW BIT(0)
5774e39389SWyon Bi
5874e39389SWyon Bi #define DSI_DPI_LP_CMD_TIM 0x18
5974e39389SWyon Bi #define OUTVACT_LPCMD_TIME(p) (((p) & 0xff) << 16)
6074e39389SWyon Bi #define INVACT_LPCMD_TIME(p) ((p) & 0xff)
6174e39389SWyon Bi
6274e39389SWyon Bi #define DSI_DBI_VCID 0x1c
6374e39389SWyon Bi #define DBI_VCID(x) UPDATE(x, 1, 0)
6474e39389SWyon Bi #define DSI_DBI_CFG 0x20
6574e39389SWyon Bi #define DSI_DBI_CMDSIZE 0x28
6674e39389SWyon Bi
6774e39389SWyon Bi #define DSI_PCKHDL_CFG 0x2c
6874e39389SWyon Bi #define CRC_RX_EN BIT(4)
6974e39389SWyon Bi #define ECC_RX_EN BIT(3)
7074e39389SWyon Bi #define BTA_EN BIT(2)
7174e39389SWyon Bi #define EOTP_RX_EN BIT(1)
7274e39389SWyon Bi #define EOTP_TX_EN BIT(0)
7374e39389SWyon Bi #define DSI_MODE_CFG 0x34
7474e39389SWyon Bi #define CMD_VIDEO_MODE BIT(0)
7574e39389SWyon Bi #define COMMAND_MODE BIT(0)
7674e39389SWyon Bi #define VIDEO_MODE 0
7774e39389SWyon Bi #define DSI_VID_MODE_CFG 0x38
7874e39389SWyon Bi #define VPG_EN BIT(16)
7974e39389SWyon Bi #define LP_CMD_EN BIT(15)
8074e39389SWyon Bi #define FRAME_BTA_ACK BIT(14)
8174e39389SWyon Bi #define LP_HFP_EN BIT(13)
8274e39389SWyon Bi #define LP_HBP_EN BIT(12)
8374e39389SWyon Bi #define LP_VACT_EN BIT(11)
8474e39389SWyon Bi #define LP_VFP_EN BIT(10)
8574e39389SWyon Bi #define LP_VBP_EN BIT(9)
8674e39389SWyon Bi #define LP_VSA_EN BIT(8)
8774e39389SWyon Bi #define VID_MODE_TYPE_BURST_SYNC_PULSES 0x0
8874e39389SWyon Bi #define VID_MODE_TYPE_BURST_SYNC_EVENTS 0x1
8974e39389SWyon Bi #define VID_MODE_TYPE_BURST 0x2
9074e39389SWyon Bi
9174e39389SWyon Bi #define DSI_VID_PKT_SIZE 0x3c
9274e39389SWyon Bi #define VID_PKT_SIZE(p) (((p) & 0x3fff) << 0)
9374e39389SWyon Bi #define VID_PKT_MAX_SIZE 0x3fff
9474e39389SWyon Bi
9574e39389SWyon Bi #define DSI_VID_NUM_CHUMKS 0x40
9674e39389SWyon Bi #define DSI_VID_NULL_PKT_SIZE 0x44
9774e39389SWyon Bi #define DSI_VID_HSA_TIME 0x48
9874e39389SWyon Bi #define DSI_VID_HBP_TIME 0x4c
9974e39389SWyon Bi #define DSI_VID_HLINE_TIME 0x50
10074e39389SWyon Bi #define DSI_VID_VSA_LINES 0x54
10174e39389SWyon Bi #define DSI_VID_VBP_LINES 0x58
10274e39389SWyon Bi #define DSI_VID_VFP_LINES 0x5c
10374e39389SWyon Bi #define DSI_VID_VACTIVE_LINES 0x60
10474e39389SWyon Bi #define DSI_EDPI_CMD_SIZE 0x64
10574e39389SWyon Bi #define DSI_CMD_MODE_CFG 0x68
10674e39389SWyon Bi #define MAX_RD_PKT_SIZE BIT(24)
10774e39389SWyon Bi #define DCS_LW_TX BIT(19)
10874e39389SWyon Bi #define DCS_SR_0P_TX BIT(18)
10974e39389SWyon Bi #define DCS_SW_1P_TX BIT(17)
11074e39389SWyon Bi #define DCS_SW_0P_TX BIT(16)
11174e39389SWyon Bi #define GEN_LW_TX BIT(14)
11274e39389SWyon Bi #define GEN_SR_2P_TX BIT(13)
11374e39389SWyon Bi #define GEN_SR_1P_TX BIT(12)
11474e39389SWyon Bi #define GEN_SR_0P_TX BIT(11)
11574e39389SWyon Bi #define GEN_SW_2P_TX BIT(10)
11674e39389SWyon Bi #define GEN_SW_1P_TX BIT(9)
11774e39389SWyon Bi #define GEN_SW_0P_TX BIT(8)
11874e39389SWyon Bi #define ACK_RQST_EN BIT(1)
11974e39389SWyon Bi #define TEAR_FX_EN BIT(0)
12074e39389SWyon Bi
12174e39389SWyon Bi #define DSI_GEN_HDR 0x6c
12274e39389SWyon Bi #define GEN_HDATA(data) (((data) & 0xffff) << 8)
12374e39389SWyon Bi #define GEN_HDATA_MASK (0xffff << 8)
12474e39389SWyon Bi #define GEN_HTYPE(type) (((type) & 0xff) << 0)
12574e39389SWyon Bi #define GEN_HTYPE_MASK 0xff
12674e39389SWyon Bi
12774e39389SWyon Bi #define DSI_GEN_PLD_DATA 0x70
12874e39389SWyon Bi
12974e39389SWyon Bi #define DSI_CMD_PKT_STATUS 0x74
13074e39389SWyon Bi #define GEN_CMD_EMPTY BIT(0)
13174e39389SWyon Bi #define GEN_CMD_FULL BIT(1)
13274e39389SWyon Bi #define GEN_PLD_W_EMPTY BIT(2)
13374e39389SWyon Bi #define GEN_PLD_W_FULL BIT(3)
13474e39389SWyon Bi #define GEN_PLD_R_EMPTY BIT(4)
13574e39389SWyon Bi #define GEN_PLD_R_FULL BIT(5)
13674e39389SWyon Bi #define GEN_RD_CMD_BUSY BIT(6)
13774e39389SWyon Bi
13874e39389SWyon Bi #define DSI_TO_CNT_CFG 0x78
13974e39389SWyon Bi #define HSTX_TO_CNT(p) (((p) & 0xffff) << 16)
14074e39389SWyon Bi #define LPRX_TO_CNT(p) ((p) & 0xffff)
14174e39389SWyon Bi
14274e39389SWyon Bi #define DSI_BTA_TO_CNT 0x8c
14374e39389SWyon Bi #define DSI_LPCLK_CTRL 0x94
14474e39389SWyon Bi #define AUTO_CLKLANE_CTRL BIT(1)
14574e39389SWyon Bi #define PHY_TXREQUESTCLKHS BIT(0)
14674e39389SWyon Bi
14774e39389SWyon Bi #define DSI_PHY_TMR_LPCLK_CFG 0x98
14874e39389SWyon Bi #define PHY_CLKHS2LP_TIME(lbcc) (((lbcc) & 0x3ff) << 16)
14974e39389SWyon Bi #define PHY_CLKLP2HS_TIME(lbcc) ((lbcc) & 0x3ff)
15074e39389SWyon Bi
15174e39389SWyon Bi #define DSI_PHY_TMR_CFG 0x9c
15274e39389SWyon Bi #define PHY_HS2LP_TIME(lbcc) (((lbcc) & 0xff) << 24)
15374e39389SWyon Bi #define PHY_LP2HS_TIME(lbcc) (((lbcc) & 0xff) << 16)
15474e39389SWyon Bi #define MAX_RD_TIME(lbcc) ((lbcc) & 0x7fff)
15574e39389SWyon Bi
15674e39389SWyon Bi #define DSI_PHY_RSTZ 0xa0
15774e39389SWyon Bi #define PHY_ENFORCEPLL BIT(3)
15874e39389SWyon Bi #define PHY_ENABLECLK BIT(2)
15974e39389SWyon Bi #define PHY_RSTZ BIT(1)
16074e39389SWyon Bi #define PHY_SHUTDOWNZ BIT(0)
16174e39389SWyon Bi
16274e39389SWyon Bi #define DSI_PHY_IF_CFG 0xa4
16374e39389SWyon Bi #define N_LANES(n) ((((n) - 1) & 0x3) << 0)
16474e39389SWyon Bi #define PHY_STOP_WAIT_TIME(cycle) (((cycle) & 0xff) << 8)
16574e39389SWyon Bi
16674e39389SWyon Bi #define DSI_PHY_STATUS 0xb0
16774e39389SWyon Bi #define PHY_STOPSTATE0LANE BIT(4)
16874e39389SWyon Bi #define PHY_STOPSTATECLKLANE BIT(2)
16974e39389SWyon Bi #define PHY_LOCK BIT(0)
17074e39389SWyon Bi #define PHY_STOPSTATELANE (PHY_STOPSTATE0LANE | \
17174e39389SWyon Bi PHY_STOPSTATECLKLANE)
17274e39389SWyon Bi
17374e39389SWyon Bi #define DSI_PHY_TST_CTRL0 0xb4
17474e39389SWyon Bi #define PHY_TESTCLK BIT(1)
17574e39389SWyon Bi #define PHY_TESTCLR BIT(0)
17674e39389SWyon Bi
17774e39389SWyon Bi #define DSI_PHY_TST_CTRL1 0xb8
17874e39389SWyon Bi #define PHY_TESTEN BIT(16)
17974e39389SWyon Bi #define PHY_TESTDOUT_SHIFT 8
18074e39389SWyon Bi #define PHY_TESTDIN_MASK GENMASK(7, 0)
18174e39389SWyon Bi #define PHY_TESTDIN(x) UPDATE(x, 7, 0)
18274e39389SWyon Bi
18374e39389SWyon Bi #define DSI_INT_ST0 0xbc
18474e39389SWyon Bi #define DSI_INT_ST1 0xc0
18574e39389SWyon Bi #define DSI_INT_MSK0 0xc4
18674e39389SWyon Bi #define DSI_INT_MSK1 0xc8
18774e39389SWyon Bi
18874e39389SWyon Bi #define PHY_STATUS_TIMEOUT_US 10000
18974e39389SWyon Bi #define CMD_PKT_STATUS_TIMEOUT_US 20000
19074e39389SWyon Bi
19174e39389SWyon Bi /* Test Code: 0x44 (HS RX Control of Lane 0) */
19274e39389SWyon Bi #define HSFREQRANGE(x) UPDATE(x, 6, 1)
19374e39389SWyon Bi /* Test Code: 0x17 (PLL Input Divider Ratio) */
19474e39389SWyon Bi #define INPUT_DIV(x) UPDATE(x, 6, 0)
19574e39389SWyon Bi /* Test Code: 0x18 (PLL Loop Divider Ratio) */
19674e39389SWyon Bi #define FEEDBACK_DIV_LO(x) UPDATE(x, 4, 0)
19774e39389SWyon Bi #define FEEDBACK_DIV_HI(x) (BIT(7) | UPDATE(x, 3, 0))
19874e39389SWyon Bi
199efcb7be1SNickey Yang #define GRF_REG_FIELD(reg, lsb, msb) (((reg) << 10) | ((lsb) << 5) | (msb))
20074e39389SWyon Bi
20174e39389SWyon Bi enum grf_reg_fields {
20274e39389SWyon Bi DPIUPDATECFG,
20374e39389SWyon Bi DPISHUTDN,
20474e39389SWyon Bi DPICOLORM,
20574e39389SWyon Bi VOPSEL,
20674e39389SWyon Bi TURNREQUEST,
20774e39389SWyon Bi TURNDISABLE,
208e9b1001bSGuochun Huang SKEWCALHS,
20974e39389SWyon Bi FORCETXSTOPMODE,
21074e39389SWyon Bi FORCERXMODE,
21174e39389SWyon Bi ENABLE_N,
21274e39389SWyon Bi MASTERSLAVEZ,
21374e39389SWyon Bi ENABLECLK,
21474e39389SWyon Bi BASEDIR,
21574e39389SWyon Bi MAX_FIELDS,
21674e39389SWyon Bi };
21774e39389SWyon Bi
21874e39389SWyon Bi struct dw_mipi_dsi_plat_data {
21974e39389SWyon Bi const u32 *dsi0_grf_reg_fields;
22074e39389SWyon Bi const u32 *dsi1_grf_reg_fields;
22174e39389SWyon Bi unsigned long max_bit_rate_per_lane;
22274e39389SWyon Bi };
22374e39389SWyon Bi
22474e39389SWyon Bi struct mipi_dphy {
22574e39389SWyon Bi /* Non-SNPS PHY */
22674e39389SWyon Bi struct rockchip_phy *phy;
22774e39389SWyon Bi
22874e39389SWyon Bi u16 input_div;
22974e39389SWyon Bi u16 feedback_div;
23074e39389SWyon Bi };
23174e39389SWyon Bi
23274e39389SWyon Bi struct dw_mipi_dsi {
2330594ce39SZhang Yubing struct rockchip_connector connector;
23474e39389SWyon Bi struct udevice *dev;
23574e39389SWyon Bi void *base;
23674e39389SWyon Bi void *grf;
23774e39389SWyon Bi int id;
23874e39389SWyon Bi struct dw_mipi_dsi *master;
23974e39389SWyon Bi struct dw_mipi_dsi *slave;
2403320fa93SWyon Bi bool prepared;
24174e39389SWyon Bi
24274e39389SWyon Bi unsigned int lane_mbps; /* per lane */
24374e39389SWyon Bi u32 channel;
24474e39389SWyon Bi u32 lanes;
24574e39389SWyon Bi u32 format;
24674e39389SWyon Bi u32 mode_flags;
24774e39389SWyon Bi struct mipi_dphy dphy;
2483320fa93SWyon Bi struct drm_display_mode mode;
24910bd5723SGuochun Huang bool data_swap;
250a7015c5eSZhibin Huang bool dual_channel;
251d451259aSGuochun Huang bool disable_hold_mode;
25274e39389SWyon Bi
25374e39389SWyon Bi const struct dw_mipi_dsi_plat_data *pdata;
25474e39389SWyon Bi };
25574e39389SWyon Bi
dsi_write(struct dw_mipi_dsi * dsi,u32 reg,u32 val)25674e39389SWyon Bi static inline void dsi_write(struct dw_mipi_dsi *dsi, u32 reg, u32 val)
25774e39389SWyon Bi {
25874e39389SWyon Bi writel(val, dsi->base + reg);
25974e39389SWyon Bi }
26074e39389SWyon Bi
dsi_read(struct dw_mipi_dsi * dsi,u32 reg)26174e39389SWyon Bi static inline u32 dsi_read(struct dw_mipi_dsi *dsi, u32 reg)
26274e39389SWyon Bi {
26374e39389SWyon Bi return readl(dsi->base + reg);
26474e39389SWyon Bi }
26574e39389SWyon Bi
dsi_update_bits(struct dw_mipi_dsi * dsi,u32 reg,u32 mask,u32 val)26674e39389SWyon Bi static inline void dsi_update_bits(struct dw_mipi_dsi *dsi,
26774e39389SWyon Bi u32 reg, u32 mask, u32 val)
26874e39389SWyon Bi {
26974e39389SWyon Bi u32 orig, tmp;
27074e39389SWyon Bi
27174e39389SWyon Bi orig = dsi_read(dsi, reg);
27274e39389SWyon Bi tmp = orig & ~mask;
27374e39389SWyon Bi tmp |= val & mask;
27474e39389SWyon Bi dsi_write(dsi, reg, tmp);
27574e39389SWyon Bi }
27674e39389SWyon Bi
grf_field_write(struct dw_mipi_dsi * dsi,enum grf_reg_fields index,unsigned int val)27774e39389SWyon Bi static void grf_field_write(struct dw_mipi_dsi *dsi, enum grf_reg_fields index,
27874e39389SWyon Bi unsigned int val)
27974e39389SWyon Bi {
28074e39389SWyon Bi const u32 field = dsi->id ? dsi->pdata->dsi1_grf_reg_fields[index] :
28174e39389SWyon Bi dsi->pdata->dsi0_grf_reg_fields[index];
28274e39389SWyon Bi u16 reg;
28374e39389SWyon Bi u8 msb, lsb;
28474e39389SWyon Bi
28574e39389SWyon Bi if (!field)
28674e39389SWyon Bi return;
28774e39389SWyon Bi
288efcb7be1SNickey Yang reg = (field >> 10) & 0x3ffff;
289efcb7be1SNickey Yang lsb = (field >> 5) & 0x1f;
290efcb7be1SNickey Yang msb = (field >> 0) & 0x1f;
29174e39389SWyon Bi
29274e39389SWyon Bi rk_clrsetreg(dsi->grf + reg, GENMASK(msb, lsb), val << lsb);
29374e39389SWyon Bi }
29474e39389SWyon Bi
dpishutdn_assert(struct dw_mipi_dsi * dsi)29574e39389SWyon Bi static inline void dpishutdn_assert(struct dw_mipi_dsi *dsi)
29674e39389SWyon Bi {
29774e39389SWyon Bi grf_field_write(dsi, DPISHUTDN, 1);
29874e39389SWyon Bi }
29974e39389SWyon Bi
dpishutdn_deassert(struct dw_mipi_dsi * dsi)30074e39389SWyon Bi static inline void dpishutdn_deassert(struct dw_mipi_dsi *dsi)
30174e39389SWyon Bi {
30274e39389SWyon Bi grf_field_write(dsi, DPISHUTDN, 0);
30374e39389SWyon Bi }
30474e39389SWyon Bi
genif_wait_w_pld_fifo_not_full(struct dw_mipi_dsi * dsi)30574e39389SWyon Bi static int genif_wait_w_pld_fifo_not_full(struct dw_mipi_dsi *dsi)
30674e39389SWyon Bi {
30774e39389SWyon Bi u32 sts;
30874e39389SWyon Bi int ret;
30974e39389SWyon Bi
31074e39389SWyon Bi ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
3111953e619SWyon Bi sts, !(sts & GEN_PLD_W_FULL),
31274e39389SWyon Bi CMD_PKT_STATUS_TIMEOUT_US);
31374e39389SWyon Bi if (ret < 0) {
31474e39389SWyon Bi printf("generic write payload fifo is full\n");
31574e39389SWyon Bi return ret;
31674e39389SWyon Bi }
31774e39389SWyon Bi
31874e39389SWyon Bi return 0;
31974e39389SWyon Bi }
32074e39389SWyon Bi
genif_wait_cmd_fifo_not_full(struct dw_mipi_dsi * dsi)32174e39389SWyon Bi static int genif_wait_cmd_fifo_not_full(struct dw_mipi_dsi *dsi)
32274e39389SWyon Bi {
32374e39389SWyon Bi u32 sts;
32474e39389SWyon Bi int ret;
32574e39389SWyon Bi
32674e39389SWyon Bi ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
3271953e619SWyon Bi sts, !(sts & GEN_CMD_FULL),
32874e39389SWyon Bi CMD_PKT_STATUS_TIMEOUT_US);
32974e39389SWyon Bi if (ret < 0) {
33074e39389SWyon Bi printf("generic write cmd fifo is full\n");
33174e39389SWyon Bi return ret;
33274e39389SWyon Bi }
33374e39389SWyon Bi
33474e39389SWyon Bi return 0;
33574e39389SWyon Bi }
33674e39389SWyon Bi
genif_wait_write_fifo_empty(struct dw_mipi_dsi * dsi)33774e39389SWyon Bi static int genif_wait_write_fifo_empty(struct dw_mipi_dsi *dsi)
33874e39389SWyon Bi {
33974e39389SWyon Bi u32 sts;
34074e39389SWyon Bi u32 mask;
34174e39389SWyon Bi int ret;
34274e39389SWyon Bi
34374e39389SWyon Bi mask = GEN_CMD_EMPTY | GEN_PLD_W_EMPTY;
34474e39389SWyon Bi ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
3451953e619SWyon Bi sts, (sts & mask) == mask,
34674e39389SWyon Bi CMD_PKT_STATUS_TIMEOUT_US);
34774e39389SWyon Bi if (ret < 0) {
34874e39389SWyon Bi printf("generic write fifo is full\n");
34974e39389SWyon Bi return ret;
35074e39389SWyon Bi }
35174e39389SWyon Bi
35274e39389SWyon Bi return 0;
35374e39389SWyon Bi }
35474e39389SWyon Bi
mipi_dphy_enableclk_assert(struct dw_mipi_dsi * dsi)35574e39389SWyon Bi static inline void mipi_dphy_enableclk_assert(struct dw_mipi_dsi *dsi)
35674e39389SWyon Bi {
35774e39389SWyon Bi dsi_update_bits(dsi, DSI_PHY_RSTZ, PHY_ENABLECLK, PHY_ENABLECLK);
35874e39389SWyon Bi udelay(1);
35974e39389SWyon Bi }
36074e39389SWyon Bi
mipi_dphy_enableclk_deassert(struct dw_mipi_dsi * dsi)36174e39389SWyon Bi static inline void mipi_dphy_enableclk_deassert(struct dw_mipi_dsi *dsi)
36274e39389SWyon Bi {
36374e39389SWyon Bi dsi_update_bits(dsi, DSI_PHY_RSTZ, PHY_ENABLECLK, 0);
36474e39389SWyon Bi udelay(1);
36574e39389SWyon Bi }
36674e39389SWyon Bi
mipi_dphy_shutdownz_assert(struct dw_mipi_dsi * dsi)36774e39389SWyon Bi static inline void mipi_dphy_shutdownz_assert(struct dw_mipi_dsi *dsi)
36874e39389SWyon Bi {
36974e39389SWyon Bi dsi_update_bits(dsi, DSI_PHY_RSTZ, PHY_SHUTDOWNZ, 0);
37074e39389SWyon Bi udelay(1);
37174e39389SWyon Bi }
37274e39389SWyon Bi
mipi_dphy_shutdownz_deassert(struct dw_mipi_dsi * dsi)37374e39389SWyon Bi static inline void mipi_dphy_shutdownz_deassert(struct dw_mipi_dsi *dsi)
37474e39389SWyon Bi {
37574e39389SWyon Bi dsi_update_bits(dsi, DSI_PHY_RSTZ, PHY_SHUTDOWNZ, PHY_SHUTDOWNZ);
37674e39389SWyon Bi udelay(1);
37774e39389SWyon Bi }
37874e39389SWyon Bi
mipi_dphy_rstz_assert(struct dw_mipi_dsi * dsi)37974e39389SWyon Bi static inline void mipi_dphy_rstz_assert(struct dw_mipi_dsi *dsi)
38074e39389SWyon Bi {
38174e39389SWyon Bi dsi_update_bits(dsi, DSI_PHY_RSTZ, PHY_RSTZ, 0);
38274e39389SWyon Bi udelay(1);
38374e39389SWyon Bi }
38474e39389SWyon Bi
mipi_dphy_rstz_deassert(struct dw_mipi_dsi * dsi)38574e39389SWyon Bi static inline void mipi_dphy_rstz_deassert(struct dw_mipi_dsi *dsi)
38674e39389SWyon Bi {
38774e39389SWyon Bi dsi_update_bits(dsi, DSI_PHY_RSTZ, PHY_RSTZ, PHY_RSTZ);
38874e39389SWyon Bi udelay(1);
38974e39389SWyon Bi }
39074e39389SWyon Bi
testif_testclk_assert(struct dw_mipi_dsi * dsi)39174e39389SWyon Bi static inline void testif_testclk_assert(struct dw_mipi_dsi *dsi)
39274e39389SWyon Bi {
39374e39389SWyon Bi dsi_update_bits(dsi, DSI_PHY_TST_CTRL0, PHY_TESTCLK, PHY_TESTCLK);
39474e39389SWyon Bi udelay(1);
39574e39389SWyon Bi }
39674e39389SWyon Bi
testif_testclk_deassert(struct dw_mipi_dsi * dsi)39774e39389SWyon Bi static inline void testif_testclk_deassert(struct dw_mipi_dsi *dsi)
39874e39389SWyon Bi {
39974e39389SWyon Bi dsi_update_bits(dsi, DSI_PHY_TST_CTRL0, PHY_TESTCLK, 0);
40074e39389SWyon Bi udelay(1);
40174e39389SWyon Bi }
40274e39389SWyon Bi
testif_testclr_assert(struct dw_mipi_dsi * dsi)40374e39389SWyon Bi static inline void testif_testclr_assert(struct dw_mipi_dsi *dsi)
40474e39389SWyon Bi {
40574e39389SWyon Bi dsi_update_bits(dsi, DSI_PHY_TST_CTRL0, PHY_TESTCLR, PHY_TESTCLR);
40674e39389SWyon Bi udelay(1);
40774e39389SWyon Bi }
40874e39389SWyon Bi
testif_testclr_deassert(struct dw_mipi_dsi * dsi)40974e39389SWyon Bi static inline void testif_testclr_deassert(struct dw_mipi_dsi *dsi)
41074e39389SWyon Bi {
41174e39389SWyon Bi dsi_update_bits(dsi, DSI_PHY_TST_CTRL0, PHY_TESTCLR, 0);
41274e39389SWyon Bi udelay(1);
41374e39389SWyon Bi }
41474e39389SWyon Bi
testif_testen_assert(struct dw_mipi_dsi * dsi)41574e39389SWyon Bi static inline void testif_testen_assert(struct dw_mipi_dsi *dsi)
41674e39389SWyon Bi {
41774e39389SWyon Bi dsi_update_bits(dsi, DSI_PHY_TST_CTRL1, PHY_TESTEN, PHY_TESTEN);
41874e39389SWyon Bi udelay(1);
41974e39389SWyon Bi }
42074e39389SWyon Bi
testif_testen_deassert(struct dw_mipi_dsi * dsi)42174e39389SWyon Bi static inline void testif_testen_deassert(struct dw_mipi_dsi *dsi)
42274e39389SWyon Bi {
42374e39389SWyon Bi dsi_update_bits(dsi, DSI_PHY_TST_CTRL1, PHY_TESTEN, 0);
42474e39389SWyon Bi udelay(1);
42574e39389SWyon Bi }
42674e39389SWyon Bi
testif_set_data(struct dw_mipi_dsi * dsi,u8 data)42774e39389SWyon Bi static inline void testif_set_data(struct dw_mipi_dsi *dsi, u8 data)
42874e39389SWyon Bi {
42974e39389SWyon Bi dsi_update_bits(dsi, DSI_PHY_TST_CTRL1,
43074e39389SWyon Bi PHY_TESTDIN_MASK, PHY_TESTDIN(data));
43174e39389SWyon Bi udelay(1);
43274e39389SWyon Bi }
43374e39389SWyon Bi
testif_get_data(struct dw_mipi_dsi * dsi)43474e39389SWyon Bi static inline u8 testif_get_data(struct dw_mipi_dsi *dsi)
43574e39389SWyon Bi {
43674e39389SWyon Bi return dsi_read(dsi, DSI_PHY_TST_CTRL1) >> PHY_TESTDOUT_SHIFT;
43774e39389SWyon Bi }
43874e39389SWyon Bi
testif_test_code_write(struct dw_mipi_dsi * dsi,u8 test_code)43974e39389SWyon Bi static void testif_test_code_write(struct dw_mipi_dsi *dsi, u8 test_code)
44074e39389SWyon Bi {
44174e39389SWyon Bi testif_testclk_assert(dsi);
44274e39389SWyon Bi testif_set_data(dsi, test_code);
44374e39389SWyon Bi testif_testen_assert(dsi);
44474e39389SWyon Bi testif_testclk_deassert(dsi);
44574e39389SWyon Bi testif_testen_deassert(dsi);
44674e39389SWyon Bi }
44774e39389SWyon Bi
testif_test_data_write(struct dw_mipi_dsi * dsi,u8 test_data)44874e39389SWyon Bi static void testif_test_data_write(struct dw_mipi_dsi *dsi, u8 test_data)
44974e39389SWyon Bi {
45074e39389SWyon Bi testif_testclk_deassert(dsi);
45174e39389SWyon Bi testif_set_data(dsi, test_data);
45274e39389SWyon Bi testif_testclk_assert(dsi);
45374e39389SWyon Bi }
45474e39389SWyon Bi
testif_write(struct dw_mipi_dsi * dsi,u8 test_code,u8 test_data)45574e39389SWyon Bi static void testif_write(struct dw_mipi_dsi *dsi, u8 test_code, u8 test_data)
45674e39389SWyon Bi {
45774e39389SWyon Bi testif_test_code_write(dsi, test_code);
45874e39389SWyon Bi testif_test_data_write(dsi, test_data);
45974e39389SWyon Bi
46074e39389SWyon Bi dev_dbg(dsi->dev,
46174e39389SWyon Bi "test_code=0x%02x, test_data=0x%02x, monitor_data=0x%02x\n",
46274e39389SWyon Bi test_code, test_data, testif_get_data(dsi));
46374e39389SWyon Bi }
46474e39389SWyon Bi
mipi_dphy_power_on(struct dw_mipi_dsi * dsi)46574e39389SWyon Bi static int mipi_dphy_power_on(struct dw_mipi_dsi *dsi)
46674e39389SWyon Bi {
46774e39389SWyon Bi u32 mask, val;
46874e39389SWyon Bi int ret;
46974e39389SWyon Bi
47074e39389SWyon Bi mipi_dphy_shutdownz_deassert(dsi);
47174e39389SWyon Bi mipi_dphy_rstz_deassert(dsi);
47274e39389SWyon Bi mdelay(2);
47374e39389SWyon Bi
47474e39389SWyon Bi if (dsi->dphy.phy) {
4753091368dSGuochun Huang rockchip_phy_set_mode(dsi->dphy.phy, PHY_MODE_MIPI_DPHY);
47674e39389SWyon Bi rockchip_phy_power_on(dsi->dphy.phy);
47774e39389SWyon Bi }
47874e39389SWyon Bi
47974e39389SWyon Bi ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS,
4801953e619SWyon Bi val, val & PHY_LOCK, PHY_STATUS_TIMEOUT_US);
48174e39389SWyon Bi if (ret < 0) {
48274e39389SWyon Bi dev_err(dsi->dev, "PHY is not locked\n");
48374e39389SWyon Bi return ret;
48474e39389SWyon Bi }
48574e39389SWyon Bi
48674e39389SWyon Bi udelay(200);
48774e39389SWyon Bi
48874e39389SWyon Bi mask = PHY_STOPSTATELANE;
48974e39389SWyon Bi ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS,
49074e39389SWyon Bi val, (val & mask) == mask,
4911953e619SWyon Bi PHY_STATUS_TIMEOUT_US);
49274e39389SWyon Bi if (ret < 0) {
49374e39389SWyon Bi dev_err(dsi->dev, "lane module is not in stop state\n");
49474e39389SWyon Bi return ret;
49574e39389SWyon Bi }
49674e39389SWyon Bi
49774e39389SWyon Bi udelay(10);
49874e39389SWyon Bi
49974e39389SWyon Bi return 0;
50074e39389SWyon Bi }
50174e39389SWyon Bi
dw_mipi_dsi_phy_init(struct dw_mipi_dsi * dsi)50274e39389SWyon Bi static void dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
50374e39389SWyon Bi {
50474e39389SWyon Bi /* Table 5-1 Frequency Ranges */
50574e39389SWyon Bi const struct {
50674e39389SWyon Bi unsigned long max_lane_mbps;
50774e39389SWyon Bi u8 hsfreqrange;
50874e39389SWyon Bi } hsfreqrange_table[] = {
50974e39389SWyon Bi { 90, 0x00}, { 100, 0x10}, { 110, 0x20}, { 130, 0x01},
51074e39389SWyon Bi { 140, 0x11}, { 150, 0x21}, { 170, 0x02}, { 180, 0x12},
51174e39389SWyon Bi { 200, 0x22}, { 220, 0x03}, { 240, 0x13}, { 250, 0x23},
51274e39389SWyon Bi { 270, 0x04}, { 300, 0x14}, { 330, 0x05}, { 360, 0x15},
51374e39389SWyon Bi { 400, 0x25}, { 450, 0x06}, { 500, 0x16}, { 550, 0x07},
51474e39389SWyon Bi { 600, 0x17}, { 650, 0x08}, { 700, 0x18}, { 750, 0x09},
51574e39389SWyon Bi { 800, 0x19}, { 850, 0x29}, { 900, 0x39}, { 950, 0x0a},
51674e39389SWyon Bi {1000, 0x1a}, {1050, 0x2a}, {1100, 0x3a}, {1150, 0x0b},
51774e39389SWyon Bi {1200, 0x1b}, {1250, 0x2b}, {1300, 0x3b}, {1350, 0x0c},
51874e39389SWyon Bi {1400, 0x1c}, {1450, 0x2c}, {1500, 0x3c}
51974e39389SWyon Bi };
52074e39389SWyon Bi u8 hsfreqrange, counter;
52174e39389SWyon Bi unsigned int index, txbyteclkhs;
52274e39389SWyon Bi u16 n, m;
52374e39389SWyon Bi
52474e39389SWyon Bi for (index = 0; index < ARRAY_SIZE(hsfreqrange_table); index++)
52574e39389SWyon Bi if (dsi->lane_mbps <= hsfreqrange_table[index].max_lane_mbps)
52674e39389SWyon Bi break;
52774e39389SWyon Bi
52874e39389SWyon Bi if (index == ARRAY_SIZE(hsfreqrange_table))
52974e39389SWyon Bi --index;
53074e39389SWyon Bi
53174e39389SWyon Bi hsfreqrange = hsfreqrange_table[index].hsfreqrange;
53274e39389SWyon Bi testif_write(dsi, 0x44, HSFREQRANGE(hsfreqrange));
53374e39389SWyon Bi
53474e39389SWyon Bi txbyteclkhs = dsi->lane_mbps >> 3;
5351953e619SWyon Bi counter = txbyteclkhs * 60 / 1000;
53674e39389SWyon Bi testif_write(dsi, 0x60, 0x80 | counter);
53774e39389SWyon Bi testif_write(dsi, 0x70, 0x80 | counter);
53874e39389SWyon Bi
53974e39389SWyon Bi n = dsi->dphy.input_div - 1;
54074e39389SWyon Bi m = dsi->dphy.feedback_div - 1;
54174e39389SWyon Bi testif_write(dsi, 0x19, 0x30);
54274e39389SWyon Bi testif_write(dsi, 0x17, INPUT_DIV(n));
54374e39389SWyon Bi testif_write(dsi, 0x18, FEEDBACK_DIV_LO(m));
54474e39389SWyon Bi testif_write(dsi, 0x18, FEEDBACK_DIV_HI(m >> 5));
54574e39389SWyon Bi }
54674e39389SWyon Bi
dw_mipi_dsi_get_lane_rate(struct dw_mipi_dsi * dsi)54774e39389SWyon Bi static unsigned long dw_mipi_dsi_get_lane_rate(struct dw_mipi_dsi *dsi)
54874e39389SWyon Bi {
5493320fa93SWyon Bi const struct drm_display_mode *mode = &dsi->mode;
55074e39389SWyon Bi unsigned long max_lane_rate = dsi->pdata->max_bit_rate_per_lane;
55174e39389SWyon Bi unsigned long lane_rate;
55274e39389SWyon Bi unsigned int value;
55374e39389SWyon Bi int bpp, lanes;
55474e39389SWyon Bi u64 tmp;
55574e39389SWyon Bi
55674e39389SWyon Bi /* optional override of the desired bandwidth */
55774e39389SWyon Bi value = dev_read_u32_default(dsi->dev, "rockchip,lane-rate", 0);
55874e39389SWyon Bi if (value > 0)
5591953e619SWyon Bi return value * 1000 * 1000;
56074e39389SWyon Bi
56174e39389SWyon Bi bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
56274e39389SWyon Bi if (bpp < 0)
56374e39389SWyon Bi bpp = 24;
56474e39389SWyon Bi
56574e39389SWyon Bi lanes = dsi->slave ? dsi->lanes * 2 : dsi->lanes;
56674e39389SWyon Bi tmp = (u64)mode->clock * 1000 * bpp;
56774e39389SWyon Bi do_div(tmp, lanes);
56874e39389SWyon Bi
56974e39389SWyon Bi /* take 1 / 0.9, since mbps must big than bandwidth of RGB */
57074e39389SWyon Bi tmp *= 10;
57174e39389SWyon Bi do_div(tmp, 9);
57274e39389SWyon Bi
57374e39389SWyon Bi if (tmp > max_lane_rate)
57474e39389SWyon Bi lane_rate = max_lane_rate;
57574e39389SWyon Bi else
57674e39389SWyon Bi lane_rate = tmp;
57774e39389SWyon Bi
57874e39389SWyon Bi return lane_rate;
57974e39389SWyon Bi }
58074e39389SWyon Bi
dw_mipi_dsi_set_pll(struct dw_mipi_dsi * dsi,unsigned long rate)58174e39389SWyon Bi static void dw_mipi_dsi_set_pll(struct dw_mipi_dsi *dsi, unsigned long rate)
58274e39389SWyon Bi {
58374e39389SWyon Bi unsigned long fin, fout;
58474e39389SWyon Bi unsigned long fvco_min, fvco_max, best_freq = 984000000;
58574e39389SWyon Bi u8 min_prediv, max_prediv;
58674e39389SWyon Bi u8 _prediv, best_prediv = 2;
58774e39389SWyon Bi u16 _fbdiv, best_fbdiv = 82;
58874e39389SWyon Bi u32 min_delta = ~0U;
58974e39389SWyon Bi
59074e39389SWyon Bi fin = 24000000;
59174e39389SWyon Bi fout = rate;
59274e39389SWyon Bi
59374e39389SWyon Bi /* 5Mhz < Fref / N < 40MHz, 80MHz < Fvco < 1500Mhz */
59474e39389SWyon Bi min_prediv = DIV_ROUND_UP(fin, 40000000);
59574e39389SWyon Bi max_prediv = fin / 5000000;
59674e39389SWyon Bi fvco_min = 80000000;
59774e39389SWyon Bi fvco_max = 1500000000;
59874e39389SWyon Bi
59974e39389SWyon Bi for (_prediv = min_prediv; _prediv <= max_prediv; _prediv++) {
60074e39389SWyon Bi u64 tmp, _fout;
60174e39389SWyon Bi u32 delta;
60274e39389SWyon Bi
60374e39389SWyon Bi /* Fvco = Fref * M / N */
60474e39389SWyon Bi tmp = (u64)fout * _prediv;
60574e39389SWyon Bi do_div(tmp, fin);
60674e39389SWyon Bi _fbdiv = tmp;
60774e39389SWyon Bi
60874e39389SWyon Bi /*
60974e39389SWyon Bi * Due to the use of a "by 2 pre-scaler," the range of the
61074e39389SWyon Bi * feedback multiplication value M is limited to even division
61174e39389SWyon Bi * numbers, and m must be greater than 12, less than 1000.
61274e39389SWyon Bi */
61374e39389SWyon Bi if (_fbdiv <= 12 || _fbdiv >= 1000)
61474e39389SWyon Bi continue;
61574e39389SWyon Bi
61674e39389SWyon Bi if (_fbdiv % 2)
61774e39389SWyon Bi ++_fbdiv;
61874e39389SWyon Bi
61974e39389SWyon Bi _fout = (u64)_fbdiv * fin;
62074e39389SWyon Bi do_div(_fout, _prediv);
62174e39389SWyon Bi
62274e39389SWyon Bi if (_fout < fvco_min || _fout > fvco_max)
62374e39389SWyon Bi continue;
62474e39389SWyon Bi
62574e39389SWyon Bi delta = abs(fout - _fout);
62674e39389SWyon Bi if (!delta) {
62774e39389SWyon Bi best_prediv = _prediv;
62874e39389SWyon Bi best_fbdiv = _fbdiv;
62974e39389SWyon Bi best_freq = _fout;
63074e39389SWyon Bi break;
63174e39389SWyon Bi } else if (delta < min_delta) {
63274e39389SWyon Bi best_prediv = _prediv;
63374e39389SWyon Bi best_fbdiv = _fbdiv;
63474e39389SWyon Bi best_freq = _fout;
63574e39389SWyon Bi min_delta = delta;
63674e39389SWyon Bi }
63774e39389SWyon Bi }
63874e39389SWyon Bi
6391953e619SWyon Bi dsi->lane_mbps = best_freq / 1000 / 1000;
64074e39389SWyon Bi dsi->dphy.input_div = best_prediv;
64174e39389SWyon Bi dsi->dphy.feedback_div = best_fbdiv;
64274e39389SWyon Bi if (dsi->slave) {
64374e39389SWyon Bi dsi->slave->lane_mbps = dsi->lane_mbps;
64474e39389SWyon Bi dsi->slave->dphy.input_div = dsi->dphy.input_div;
64574e39389SWyon Bi dsi->slave->dphy.feedback_div = dsi->dphy.feedback_div;
64674e39389SWyon Bi }
6473320fa93SWyon Bi if (dsi->master) {
6483320fa93SWyon Bi dsi->master->lane_mbps = dsi->lane_mbps;
6493320fa93SWyon Bi dsi->master->dphy.input_div = dsi->dphy.input_div;
6503320fa93SWyon Bi dsi->master->dphy.feedback_div = dsi->dphy.feedback_div;
6513320fa93SWyon Bi }
65274e39389SWyon Bi }
65374e39389SWyon Bi
dw_mipi_dsi_read_from_fifo(struct dw_mipi_dsi * dsi,const struct mipi_dsi_msg * msg)65474e39389SWyon Bi static int dw_mipi_dsi_read_from_fifo(struct dw_mipi_dsi *dsi,
65574e39389SWyon Bi const struct mipi_dsi_msg *msg)
65674e39389SWyon Bi {
65774e39389SWyon Bi u8 *payload = msg->rx_buf;
65874e39389SWyon Bi u16 length;
65974e39389SWyon Bi u32 val;
66074e39389SWyon Bi int ret;
66174e39389SWyon Bi
66274e39389SWyon Bi ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
6631953e619SWyon Bi val, !(val & GEN_RD_CMD_BUSY), 5000);
66474e39389SWyon Bi if (ret) {
66574e39389SWyon Bi printf("entire response isn't stored in the FIFO\n");
66674e39389SWyon Bi return ret;
66774e39389SWyon Bi }
66874e39389SWyon Bi
66974e39389SWyon Bi /* Receive payload */
67074e39389SWyon Bi for (length = msg->rx_len; length; length -= 4) {
67174e39389SWyon Bi ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
6721953e619SWyon Bi val, !(val & GEN_PLD_R_EMPTY), 5000);
67374e39389SWyon Bi if (ret) {
67474e39389SWyon Bi printf("Read payload FIFO is empty\n");
67574e39389SWyon Bi return ret;
67674e39389SWyon Bi }
67774e39389SWyon Bi
67874e39389SWyon Bi val = dsi_read(dsi, DSI_GEN_PLD_DATA);
67974e39389SWyon Bi
68074e39389SWyon Bi switch (length) {
68174e39389SWyon Bi case 3:
68274e39389SWyon Bi payload[2] = (val >> 16) & 0xff;
68374e39389SWyon Bi /* Fall through */
68474e39389SWyon Bi case 2:
68574e39389SWyon Bi payload[1] = (val >> 8) & 0xff;
68674e39389SWyon Bi /* Fall through */
68774e39389SWyon Bi case 1:
68874e39389SWyon Bi payload[0] = val & 0xff;
68974e39389SWyon Bi return 0;
69074e39389SWyon Bi }
69174e39389SWyon Bi
69274e39389SWyon Bi payload[0] = (val >> 0) & 0xff;
69374e39389SWyon Bi payload[1] = (val >> 8) & 0xff;
69474e39389SWyon Bi payload[2] = (val >> 16) & 0xff;
69574e39389SWyon Bi payload[3] = (val >> 24) & 0xff;
69674e39389SWyon Bi payload += 4;
69774e39389SWyon Bi }
69874e39389SWyon Bi
69974e39389SWyon Bi return 0;
70074e39389SWyon Bi }
70174e39389SWyon Bi
dw_mipi_dsi_turn_on_peripheral(struct dw_mipi_dsi * dsi)70274e39389SWyon Bi static int dw_mipi_dsi_turn_on_peripheral(struct dw_mipi_dsi *dsi)
70374e39389SWyon Bi {
70474e39389SWyon Bi dpishutdn_assert(dsi);
70574e39389SWyon Bi udelay(20);
70674e39389SWyon Bi dpishutdn_deassert(dsi);
70774e39389SWyon Bi
70874e39389SWyon Bi return 0;
70974e39389SWyon Bi }
71074e39389SWyon Bi
dw_mipi_dsi_shutdown_peripheral(struct dw_mipi_dsi * dsi)71174e39389SWyon Bi static int dw_mipi_dsi_shutdown_peripheral(struct dw_mipi_dsi *dsi)
71274e39389SWyon Bi {
71374e39389SWyon Bi dpishutdn_deassert(dsi);
71474e39389SWyon Bi udelay(20);
71574e39389SWyon Bi dpishutdn_assert(dsi);
71674e39389SWyon Bi
71774e39389SWyon Bi return 0;
71874e39389SWyon Bi }
71974e39389SWyon Bi
dw_mipi_dsi_transfer(struct dw_mipi_dsi * dsi,const struct mipi_dsi_msg * msg)72074e39389SWyon Bi static ssize_t dw_mipi_dsi_transfer(struct dw_mipi_dsi *dsi,
72174e39389SWyon Bi const struct mipi_dsi_msg *msg)
72274e39389SWyon Bi {
72374e39389SWyon Bi struct mipi_dsi_packet packet;
72474e39389SWyon Bi int ret;
72574e39389SWyon Bi int val;
72674e39389SWyon Bi
7271953e619SWyon Bi if (msg->flags & MIPI_DSI_MSG_USE_LPM) {
72874e39389SWyon Bi dsi_update_bits(dsi, DSI_VID_MODE_CFG, LP_CMD_EN, LP_CMD_EN);
72974e39389SWyon Bi dsi_update_bits(dsi, DSI_LPCLK_CTRL, PHY_TXREQUESTCLKHS, 0);
73074e39389SWyon Bi } else {
73174e39389SWyon Bi dsi_update_bits(dsi, DSI_VID_MODE_CFG, LP_CMD_EN, 0);
73274e39389SWyon Bi dsi_update_bits(dsi, DSI_LPCLK_CTRL,
73374e39389SWyon Bi PHY_TXREQUESTCLKHS, PHY_TXREQUESTCLKHS);
73474e39389SWyon Bi }
73574e39389SWyon Bi
73674e39389SWyon Bi switch (msg->type) {
73774e39389SWyon Bi case MIPI_DSI_SHUTDOWN_PERIPHERAL:
73874e39389SWyon Bi return dw_mipi_dsi_shutdown_peripheral(dsi);
73974e39389SWyon Bi case MIPI_DSI_TURN_ON_PERIPHERAL:
74074e39389SWyon Bi return dw_mipi_dsi_turn_on_peripheral(dsi);
74174e39389SWyon Bi case MIPI_DSI_DCS_SHORT_WRITE:
74274e39389SWyon Bi dsi_update_bits(dsi, DSI_CMD_MODE_CFG, DCS_SW_0P_TX,
74374e39389SWyon Bi dsi->mode_flags & MIPI_DSI_MODE_LPM ?
74474e39389SWyon Bi DCS_SW_0P_TX : 0);
74574e39389SWyon Bi break;
74674e39389SWyon Bi case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
74774e39389SWyon Bi dsi_update_bits(dsi, DSI_CMD_MODE_CFG, DCS_SW_1P_TX,
74874e39389SWyon Bi dsi->mode_flags & MIPI_DSI_MODE_LPM ?
74974e39389SWyon Bi DCS_SW_1P_TX : 0);
75074e39389SWyon Bi break;
75174e39389SWyon Bi case MIPI_DSI_DCS_LONG_WRITE:
75274e39389SWyon Bi dsi_update_bits(dsi, DSI_CMD_MODE_CFG, DCS_LW_TX,
75374e39389SWyon Bi dsi->mode_flags & MIPI_DSI_MODE_LPM ?
75474e39389SWyon Bi DCS_LW_TX : 0);
75574e39389SWyon Bi break;
75674e39389SWyon Bi case MIPI_DSI_DCS_READ:
75774e39389SWyon Bi dsi_update_bits(dsi, DSI_CMD_MODE_CFG, DCS_SR_0P_TX,
75874e39389SWyon Bi dsi->mode_flags & MIPI_DSI_MODE_LPM ?
75974e39389SWyon Bi DCS_SR_0P_TX : 0);
76074e39389SWyon Bi break;
76174e39389SWyon Bi case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE:
76274e39389SWyon Bi dsi_update_bits(dsi, DSI_CMD_MODE_CFG, MAX_RD_PKT_SIZE,
76374e39389SWyon Bi dsi->mode_flags & MIPI_DSI_MODE_LPM ?
76474e39389SWyon Bi MAX_RD_PKT_SIZE : 0);
76574e39389SWyon Bi break;
76674e39389SWyon Bi case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM:
76774e39389SWyon Bi dsi_update_bits(dsi, DSI_CMD_MODE_CFG, GEN_SW_0P_TX,
76874e39389SWyon Bi dsi->mode_flags & MIPI_DSI_MODE_LPM ?
76974e39389SWyon Bi GEN_SW_0P_TX : 0);
77074e39389SWyon Bi break;
77174e39389SWyon Bi case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM:
77274e39389SWyon Bi dsi_update_bits(dsi, DSI_CMD_MODE_CFG, GEN_SW_1P_TX,
77374e39389SWyon Bi dsi->mode_flags & MIPI_DSI_MODE_LPM ?
77474e39389SWyon Bi GEN_SW_1P_TX : 0);
77574e39389SWyon Bi break;
77674e39389SWyon Bi case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM:
77774e39389SWyon Bi dsi_update_bits(dsi, DSI_CMD_MODE_CFG, GEN_SW_2P_TX,
77874e39389SWyon Bi dsi->mode_flags & MIPI_DSI_MODE_LPM ?
77974e39389SWyon Bi GEN_SW_2P_TX : 0);
78074e39389SWyon Bi break;
78174e39389SWyon Bi case MIPI_DSI_GENERIC_LONG_WRITE:
78274e39389SWyon Bi dsi_update_bits(dsi, DSI_CMD_MODE_CFG, GEN_LW_TX,
78374e39389SWyon Bi dsi->mode_flags & MIPI_DSI_MODE_LPM ?
78474e39389SWyon Bi GEN_LW_TX : 0);
78574e39389SWyon Bi break;
78674e39389SWyon Bi case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM:
78774e39389SWyon Bi dsi_update_bits(dsi, DSI_CMD_MODE_CFG, GEN_SR_0P_TX,
78874e39389SWyon Bi dsi->mode_flags & MIPI_DSI_MODE_LPM ?
78974e39389SWyon Bi GEN_SR_0P_TX : 0);
79074e39389SWyon Bi break;
79174e39389SWyon Bi case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM:
79274e39389SWyon Bi dsi_update_bits(dsi, DSI_CMD_MODE_CFG, GEN_SR_1P_TX,
79374e39389SWyon Bi dsi->mode_flags & MIPI_DSI_MODE_LPM ?
79474e39389SWyon Bi GEN_SR_1P_TX : 0);
79574e39389SWyon Bi break;
79674e39389SWyon Bi case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM:
79774e39389SWyon Bi dsi_update_bits(dsi, DSI_CMD_MODE_CFG, GEN_SR_2P_TX,
79874e39389SWyon Bi dsi->mode_flags & MIPI_DSI_MODE_LPM ?
79974e39389SWyon Bi GEN_SR_2P_TX : 0);
80074e39389SWyon Bi break;
80174e39389SWyon Bi default:
80274e39389SWyon Bi return -EINVAL;
80374e39389SWyon Bi }
80474e39389SWyon Bi
80574e39389SWyon Bi if (msg->flags & MIPI_DSI_MSG_REQ_ACK)
80674e39389SWyon Bi dsi_update_bits(dsi, DSI_CMD_MODE_CFG,
80774e39389SWyon Bi ACK_RQST_EN, ACK_RQST_EN);
80874e39389SWyon Bi
80974e39389SWyon Bi /* create a packet to the DSI protocol */
81074e39389SWyon Bi ret = mipi_dsi_create_packet(&packet, msg);
81174e39389SWyon Bi if (ret) {
81274e39389SWyon Bi printf("failed to create packet: %d\n", ret);
81374e39389SWyon Bi return ret;
81474e39389SWyon Bi }
81574e39389SWyon Bi
81674e39389SWyon Bi /* Send payload */
81774e39389SWyon Bi while (DIV_ROUND_UP(packet.payload_length, 4)) {
81874e39389SWyon Bi /*
81974e39389SWyon Bi * Alternatively, you can always keep the FIFO
82074e39389SWyon Bi * nearly full by monitoring the FIFO state until
82174e39389SWyon Bi * it is not full, and then writea single word of data.
82274e39389SWyon Bi * This solution is more resource consuming
82374e39389SWyon Bi * but it simultaneously avoids FIFO starvation,
82474e39389SWyon Bi * making it possible to use FIFO sizes smaller than
82574e39389SWyon Bi * the amount of data of the longest packet to be written.
82674e39389SWyon Bi */
82774e39389SWyon Bi ret = genif_wait_w_pld_fifo_not_full(dsi);
82874e39389SWyon Bi if (ret)
82974e39389SWyon Bi return ret;
83074e39389SWyon Bi
83174e39389SWyon Bi if (packet.payload_length < 4) {
83274e39389SWyon Bi /* send residu payload */
83374e39389SWyon Bi val = 0;
83474e39389SWyon Bi memcpy(&val, packet.payload, packet.payload_length);
83574e39389SWyon Bi dsi_write(dsi, DSI_GEN_PLD_DATA, val);
83674e39389SWyon Bi packet.payload_length = 0;
83774e39389SWyon Bi } else {
83874e39389SWyon Bi val = get_unaligned_le32(packet.payload);
83974e39389SWyon Bi dsi_write(dsi, DSI_GEN_PLD_DATA, val);
84074e39389SWyon Bi packet.payload += 4;
84174e39389SWyon Bi packet.payload_length -= 4;
84274e39389SWyon Bi }
84374e39389SWyon Bi }
84474e39389SWyon Bi
84574e39389SWyon Bi ret = genif_wait_cmd_fifo_not_full(dsi);
84674e39389SWyon Bi if (ret)
84774e39389SWyon Bi return ret;
84874e39389SWyon Bi
84974e39389SWyon Bi /* Send packet header */
85074e39389SWyon Bi val = get_unaligned_le32(packet.header);
85174e39389SWyon Bi dsi_write(dsi, DSI_GEN_HDR, val);
85274e39389SWyon Bi
85374e39389SWyon Bi ret = genif_wait_write_fifo_empty(dsi);
85474e39389SWyon Bi if (ret)
85574e39389SWyon Bi return ret;
85674e39389SWyon Bi
85774e39389SWyon Bi if (msg->rx_len) {
85874e39389SWyon Bi ret = dw_mipi_dsi_read_from_fifo(dsi, msg);
85974e39389SWyon Bi if (ret < 0)
86074e39389SWyon Bi return ret;
86174e39389SWyon Bi }
86274e39389SWyon Bi
86374e39389SWyon Bi if (dsi->slave) {
86474e39389SWyon Bi ret = dw_mipi_dsi_transfer(dsi->slave, msg);
86574e39389SWyon Bi if (ret < 0)
86674e39389SWyon Bi return ret;
86774e39389SWyon Bi }
86874e39389SWyon Bi
86974e39389SWyon Bi return msg->rx_len ? msg->rx_len : msg->tx_len;
87074e39389SWyon Bi }
87174e39389SWyon Bi
dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi * dsi)87274e39389SWyon Bi static void dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi)
87374e39389SWyon Bi {
87474e39389SWyon Bi u32 val = LP_VACT_EN | LP_VFP_EN | LP_VBP_EN | LP_VSA_EN |
87574e39389SWyon Bi LP_HFP_EN | LP_HBP_EN;
87674e39389SWyon Bi
877edbf2db2SGuochun Huang if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_NO_HFP)
87874e39389SWyon Bi val &= ~LP_HFP_EN;
87974e39389SWyon Bi
880edbf2db2SGuochun Huang if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_NO_HBP)
88174e39389SWyon Bi val &= ~LP_HBP_EN;
88274e39389SWyon Bi
88374e39389SWyon Bi if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
88474e39389SWyon Bi val |= VID_MODE_TYPE_BURST;
88574e39389SWyon Bi else if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
88674e39389SWyon Bi val |= VID_MODE_TYPE_BURST_SYNC_PULSES;
88774e39389SWyon Bi else
88874e39389SWyon Bi val |= VID_MODE_TYPE_BURST_SYNC_EVENTS;
88974e39389SWyon Bi
89074e39389SWyon Bi dsi_write(dsi, DSI_VID_MODE_CFG, val);
89174e39389SWyon Bi
89274e39389SWyon Bi if (dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)
89374e39389SWyon Bi dsi_update_bits(dsi, DSI_LPCLK_CTRL,
89474e39389SWyon Bi AUTO_CLKLANE_CTRL, AUTO_CLKLANE_CTRL);
89574e39389SWyon Bi }
89674e39389SWyon Bi
dw_mipi_dsi_enable(struct dw_mipi_dsi * dsi)89774e39389SWyon Bi static void dw_mipi_dsi_enable(struct dw_mipi_dsi *dsi)
89874e39389SWyon Bi {
8993320fa93SWyon Bi const struct drm_display_mode *mode = &dsi->mode;
90074e39389SWyon Bi
90174e39389SWyon Bi dsi_update_bits(dsi, DSI_LPCLK_CTRL,
90274e39389SWyon Bi PHY_TXREQUESTCLKHS, PHY_TXREQUESTCLKHS);
90374e39389SWyon Bi
90474e39389SWyon Bi dsi_write(dsi, DSI_PWR_UP, RESET);
90574e39389SWyon Bi
90674e39389SWyon Bi if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
90774e39389SWyon Bi dsi_update_bits(dsi, DSI_MODE_CFG, CMD_VIDEO_MODE, VIDEO_MODE);
90874e39389SWyon Bi } else {
90974e39389SWyon Bi dsi_write(dsi, DSI_DBI_VCID, DBI_VCID(dsi->channel));
91074e39389SWyon Bi dsi_update_bits(dsi, DSI_CMD_MODE_CFG, DCS_LW_TX, 0);
91174e39389SWyon Bi dsi_write(dsi, DSI_EDPI_CMD_SIZE, mode->hdisplay);
91274e39389SWyon Bi dsi_update_bits(dsi, DSI_MODE_CFG,
91374e39389SWyon Bi CMD_VIDEO_MODE, COMMAND_MODE);
91474e39389SWyon Bi }
91574e39389SWyon Bi
91674e39389SWyon Bi dsi_write(dsi, DSI_PWR_UP, POWERUP);
91774e39389SWyon Bi
91874e39389SWyon Bi if (dsi->slave)
91974e39389SWyon Bi dw_mipi_dsi_enable(dsi->slave);
92074e39389SWyon Bi }
92174e39389SWyon Bi
dw_mipi_dsi_disable(struct dw_mipi_dsi * dsi)92274e39389SWyon Bi static void dw_mipi_dsi_disable(struct dw_mipi_dsi *dsi)
92374e39389SWyon Bi {
92474e39389SWyon Bi dsi_write(dsi, DSI_PWR_UP, RESET);
92574e39389SWyon Bi dsi_write(dsi, DSI_LPCLK_CTRL, 0);
92674e39389SWyon Bi dsi_write(dsi, DSI_EDPI_CMD_SIZE, 0);
92774e39389SWyon Bi dsi_update_bits(dsi, DSI_MODE_CFG, CMD_VIDEO_MODE, COMMAND_MODE);
92874e39389SWyon Bi dsi_write(dsi, DSI_PWR_UP, POWERUP);
92974e39389SWyon Bi
93074e39389SWyon Bi if (dsi->slave)
93174e39389SWyon Bi dw_mipi_dsi_disable(dsi->slave);
93274e39389SWyon Bi }
93374e39389SWyon Bi
dw_mipi_dsi_post_disable(struct dw_mipi_dsi * dsi)93474e39389SWyon Bi static void dw_mipi_dsi_post_disable(struct dw_mipi_dsi *dsi)
93574e39389SWyon Bi {
9363320fa93SWyon Bi if (!dsi->prepared)
9373320fa93SWyon Bi return;
9383320fa93SWyon Bi
9393320fa93SWyon Bi if (dsi->master)
9403320fa93SWyon Bi dw_mipi_dsi_post_disable(dsi->master);
9413320fa93SWyon Bi
94274e39389SWyon Bi dsi_write(dsi, DSI_PWR_UP, RESET);
94374e39389SWyon Bi dsi_write(dsi, DSI_PHY_RSTZ, 0);
94474e39389SWyon Bi
94565617e2fSWyon Bi if (dsi->dphy.phy)
94665617e2fSWyon Bi rockchip_phy_power_off(dsi->dphy.phy);
94765617e2fSWyon Bi
9483320fa93SWyon Bi dsi->prepared = false;
9493320fa93SWyon Bi
95074e39389SWyon Bi if (dsi->slave)
95174e39389SWyon Bi dw_mipi_dsi_post_disable(dsi->slave);
95274e39389SWyon Bi }
95374e39389SWyon Bi
dw_mipi_dsi_init(struct dw_mipi_dsi * dsi)95474e39389SWyon Bi static void dw_mipi_dsi_init(struct dw_mipi_dsi *dsi)
95574e39389SWyon Bi {
95674e39389SWyon Bi u32 esc_clk_div;
95774e39389SWyon Bi
95874e39389SWyon Bi dsi_write(dsi, DSI_PWR_UP, RESET);
95974e39389SWyon Bi
96074e39389SWyon Bi /* The maximum value of the escape clock frequency is 20MHz */
96174e39389SWyon Bi esc_clk_div = DIV_ROUND_UP(dsi->lane_mbps >> 3, 20);
96274e39389SWyon Bi dsi_write(dsi, DSI_CLKMGR_CFG, TO_CLK_DIVIDSION(10) |
96374e39389SWyon Bi TX_ESC_CLK_DIVIDSION(esc_clk_div));
96474e39389SWyon Bi }
96574e39389SWyon Bi
dw_mipi_dsi_dpi_config(struct dw_mipi_dsi * dsi,struct drm_display_mode * mode)96674e39389SWyon Bi static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi,
96774e39389SWyon Bi struct drm_display_mode *mode)
96874e39389SWyon Bi {
96974e39389SWyon Bi u32 val = 0, color = 0;
97074e39389SWyon Bi
97174e39389SWyon Bi switch (dsi->format) {
97274e39389SWyon Bi case MIPI_DSI_FMT_RGB888:
97374e39389SWyon Bi color = DPI_COLOR_CODING_24BIT;
97474e39389SWyon Bi break;
97574e39389SWyon Bi case MIPI_DSI_FMT_RGB666:
97674e39389SWyon Bi color = DPI_COLOR_CODING_18BIT_2 | EN18_LOOSELY;
97774e39389SWyon Bi break;
97874e39389SWyon Bi case MIPI_DSI_FMT_RGB666_PACKED:
97974e39389SWyon Bi color = DPI_COLOR_CODING_18BIT_1;
98074e39389SWyon Bi break;
98174e39389SWyon Bi case MIPI_DSI_FMT_RGB565:
98274e39389SWyon Bi color = DPI_COLOR_CODING_16BIT_1;
98374e39389SWyon Bi break;
98474e39389SWyon Bi }
98574e39389SWyon Bi
98674e39389SWyon Bi if (mode->flags & DRM_MODE_FLAG_NVSYNC)
98774e39389SWyon Bi val |= VSYNC_ACTIVE_LOW;
98874e39389SWyon Bi if (mode->flags & DRM_MODE_FLAG_NHSYNC)
98974e39389SWyon Bi val |= HSYNC_ACTIVE_LOW;
99074e39389SWyon Bi
99174e39389SWyon Bi dsi_write(dsi, DSI_DPI_VCID, DPI_VID(dsi->channel));
99274e39389SWyon Bi dsi_write(dsi, DSI_DPI_COLOR_CODING, color);
99374e39389SWyon Bi dsi_write(dsi, DSI_DPI_CFG_POL, val);
99474e39389SWyon Bi dsi_write(dsi, DSI_DPI_LP_CMD_TIM, OUTVACT_LPCMD_TIME(4)
99574e39389SWyon Bi | INVACT_LPCMD_TIME(4));
99674e39389SWyon Bi }
99774e39389SWyon Bi
dw_mipi_dsi_packet_handler_config(struct dw_mipi_dsi * dsi)99874e39389SWyon Bi static void dw_mipi_dsi_packet_handler_config(struct dw_mipi_dsi *dsi)
99974e39389SWyon Bi {
100074e39389SWyon Bi u32 val = CRC_RX_EN | ECC_RX_EN | BTA_EN | EOTP_TX_EN;
100174e39389SWyon Bi
1002edbf2db2SGuochun Huang if (dsi->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET)
100374e39389SWyon Bi val &= ~EOTP_TX_EN;
100474e39389SWyon Bi
100574e39389SWyon Bi dsi_write(dsi, DSI_PCKHDL_CFG, val);
100674e39389SWyon Bi }
100774e39389SWyon Bi
dw_mipi_dsi_video_packet_config(struct dw_mipi_dsi * dsi,struct drm_display_mode * mode)100874e39389SWyon Bi static void dw_mipi_dsi_video_packet_config(struct dw_mipi_dsi *dsi,
100974e39389SWyon Bi struct drm_display_mode *mode)
101074e39389SWyon Bi {
10113320fa93SWyon Bi dsi_write(dsi, DSI_VID_PKT_SIZE, VID_PKT_SIZE(mode->hdisplay));
101274e39389SWyon Bi }
101374e39389SWyon Bi
dw_mipi_dsi_command_mode_config(struct dw_mipi_dsi * dsi)101474e39389SWyon Bi static void dw_mipi_dsi_command_mode_config(struct dw_mipi_dsi *dsi)
101574e39389SWyon Bi {
101674e39389SWyon Bi dsi_write(dsi, DSI_TO_CNT_CFG, HSTX_TO_CNT(1000) | LPRX_TO_CNT(1000));
101774e39389SWyon Bi dsi_write(dsi, DSI_BTA_TO_CNT, 0xd00);
101874e39389SWyon Bi }
101974e39389SWyon Bi
102074e39389SWyon Bi /* Get lane byte clock cycles. */
dw_mipi_dsi_get_hcomponent_lbcc(struct dw_mipi_dsi * dsi,u64 hcomponent)102174e39389SWyon Bi static int dw_mipi_dsi_get_hcomponent_lbcc(struct dw_mipi_dsi *dsi,
10221b964072SGuochun Huang u64 hcomponent)
102374e39389SWyon Bi {
10241b964072SGuochun Huang u64 lbcc;
102574e39389SWyon Bi
10261953e619SWyon Bi lbcc = hcomponent * dsi->lane_mbps * 1000 / 8;
102774e39389SWyon Bi
10283320fa93SWyon Bi if (!dsi->mode.clock)
102974e39389SWyon Bi return 0;
103074e39389SWyon Bi
10313320fa93SWyon Bi return DIV_ROUND_CLOSEST(lbcc, dsi->mode.clock);
103274e39389SWyon Bi }
103374e39389SWyon Bi
dw_mipi_dsi_line_timer_config(struct dw_mipi_dsi * dsi)103474e39389SWyon Bi static void dw_mipi_dsi_line_timer_config(struct dw_mipi_dsi *dsi)
103574e39389SWyon Bi {
103674e39389SWyon Bi int htotal, hsa, hbp, lbcc;
10373320fa93SWyon Bi struct drm_display_mode *mode = &dsi->mode;
103874e39389SWyon Bi
103974e39389SWyon Bi htotal = mode->htotal;
104074e39389SWyon Bi hsa = mode->hsync_end - mode->hsync_start;
104174e39389SWyon Bi hbp = mode->htotal - mode->hsync_end;
104274e39389SWyon Bi
104374e39389SWyon Bi lbcc = dw_mipi_dsi_get_hcomponent_lbcc(dsi, htotal);
104474e39389SWyon Bi dsi_write(dsi, DSI_VID_HLINE_TIME, lbcc);
104574e39389SWyon Bi
104674e39389SWyon Bi lbcc = dw_mipi_dsi_get_hcomponent_lbcc(dsi, hsa);
104774e39389SWyon Bi dsi_write(dsi, DSI_VID_HSA_TIME, lbcc);
104874e39389SWyon Bi
104974e39389SWyon Bi lbcc = dw_mipi_dsi_get_hcomponent_lbcc(dsi, hbp);
105074e39389SWyon Bi dsi_write(dsi, DSI_VID_HBP_TIME, lbcc);
105174e39389SWyon Bi }
105274e39389SWyon Bi
dw_mipi_dsi_vertical_timing_config(struct dw_mipi_dsi * dsi)105374e39389SWyon Bi static void dw_mipi_dsi_vertical_timing_config(struct dw_mipi_dsi *dsi)
105474e39389SWyon Bi {
105574e39389SWyon Bi u32 vactive, vsa, vfp, vbp;
10563320fa93SWyon Bi struct drm_display_mode *mode = &dsi->mode;
105774e39389SWyon Bi
105874e39389SWyon Bi vactive = mode->vdisplay;
105974e39389SWyon Bi vsa = mode->vsync_end - mode->vsync_start;
106074e39389SWyon Bi vfp = mode->vsync_start - mode->vdisplay;
106174e39389SWyon Bi vbp = mode->vtotal - mode->vsync_end;
106274e39389SWyon Bi
106374e39389SWyon Bi dsi_write(dsi, DSI_VID_VACTIVE_LINES, vactive);
106474e39389SWyon Bi dsi_write(dsi, DSI_VID_VSA_LINES, vsa);
106574e39389SWyon Bi dsi_write(dsi, DSI_VID_VFP_LINES, vfp);
106674e39389SWyon Bi dsi_write(dsi, DSI_VID_VBP_LINES, vbp);
106774e39389SWyon Bi }
106874e39389SWyon Bi
dw_mipi_dsi_dphy_timing_config(struct dw_mipi_dsi * dsi)106974e39389SWyon Bi static void dw_mipi_dsi_dphy_timing_config(struct dw_mipi_dsi *dsi)
107074e39389SWyon Bi {
107174e39389SWyon Bi dsi_write(dsi, DSI_PHY_TMR_CFG, PHY_HS2LP_TIME(0x14)
107274e39389SWyon Bi | PHY_LP2HS_TIME(0x10) | MAX_RD_TIME(10000));
107374e39389SWyon Bi
107474e39389SWyon Bi dsi_write(dsi, DSI_PHY_TMR_LPCLK_CFG, PHY_CLKHS2LP_TIME(0x40)
107574e39389SWyon Bi | PHY_CLKLP2HS_TIME(0x40));
107674e39389SWyon Bi }
107774e39389SWyon Bi
dw_mipi_dsi_dphy_interface_config(struct dw_mipi_dsi * dsi)107874e39389SWyon Bi static void dw_mipi_dsi_dphy_interface_config(struct dw_mipi_dsi *dsi)
107974e39389SWyon Bi {
108074e39389SWyon Bi dsi_write(dsi, DSI_PHY_IF_CFG, PHY_STOP_WAIT_TIME(0x20) |
108174e39389SWyon Bi N_LANES(dsi->lanes));
108274e39389SWyon Bi }
108374e39389SWyon Bi
dw_mipi_dsi_clear_err(struct dw_mipi_dsi * dsi)108474e39389SWyon Bi static void dw_mipi_dsi_clear_err(struct dw_mipi_dsi *dsi)
108574e39389SWyon Bi {
108674e39389SWyon Bi dsi_read(dsi, DSI_INT_ST0);
108774e39389SWyon Bi dsi_read(dsi, DSI_INT_ST1);
108874e39389SWyon Bi dsi_write(dsi, DSI_INT_MSK0, 0);
108974e39389SWyon Bi dsi_write(dsi, DSI_INT_MSK1, 0);
109074e39389SWyon Bi }
109174e39389SWyon Bi
dw_mipi_dsi_connector_init(struct rockchip_connector * conn,struct display_state * state)10920594ce39SZhang Yubing static int dw_mipi_dsi_connector_init(struct rockchip_connector *conn, struct display_state *state)
109358c17f51SSandy Huang {
109458c17f51SSandy Huang struct connector_state *conn_state = &state->conn_state;
10950594ce39SZhang Yubing struct dw_mipi_dsi *dsi = dev_get_priv(conn->dev);
109674e39389SWyon Bi
1097cb17ca6cSSandy Huang conn_state->disp_info = rockchip_get_disp_info(conn_state->type, dsi->id);
10980594ce39SZhang Yubing dsi->dphy.phy = conn->phy;
109974e39389SWyon Bi
110074e39389SWyon Bi conn_state->output_mode = ROCKCHIP_OUT_MODE_P888;
1101df0a5c43SDamon Ding conn_state->color_encoding = DRM_COLOR_YCBCR_BT709;
1102df0a5c43SDamon Ding conn_state->color_range = DRM_COLOR_YCBCR_FULL_RANGE;
1103e9b1001bSGuochun Huang conn_state->output_if |=
1104e9b1001bSGuochun Huang dsi->id ? VOP_OUTPUT_IF_MIPI1 : VOP_OUTPUT_IF_MIPI0;
110574e39389SWyon Bi
1106d451259aSGuochun Huang if (!(dsi->mode_flags & MIPI_DSI_MODE_VIDEO)) {
1107d451259aSGuochun Huang conn_state->output_flags |= ROCKCHIP_OUTPUT_MIPI_DS_MODE;
1108d451259aSGuochun Huang conn_state->hold_mode = dsi->disable_hold_mode ? false : true;
1109d451259aSGuochun Huang }
1110d451259aSGuochun Huang
1111e9b1001bSGuochun Huang #ifndef CONFIG_ROCKCHIP_RK3568
11123320fa93SWyon Bi if (dsi->id) {
11133320fa93SWyon Bi struct udevice *dev;
11143320fa93SWyon Bi int ret;
11153320fa93SWyon Bi
11163320fa93SWyon Bi ret = uclass_get_device_by_name(UCLASS_DISPLAY, "dsi@ff960000",
11173320fa93SWyon Bi &dev);
11183320fa93SWyon Bi if (ret)
11193320fa93SWyon Bi return ret;
11203320fa93SWyon Bi
11213320fa93SWyon Bi dsi->master = dev_get_priv(dev);
11223320fa93SWyon Bi if (!dsi->master)
11233320fa93SWyon Bi return -ENODEV;
11243320fa93SWyon Bi
1125bee25ee6SGuochun Huang conn_state->output_flags = ROCKCHIP_OUTPUT_DATA_SWAP;
11263320fa93SWyon Bi }
1127e9b1001bSGuochun Huang #endif
11283320fa93SWyon Bi
1129a7015c5eSZhibin Huang if (dsi->dual_channel) {
11303320fa93SWyon Bi struct udevice *dev;
11313320fa93SWyon Bi int ret;
11323320fa93SWyon Bi
1133cea9b549SWyon Bi ret = uclass_get_device_by_name(UCLASS_DISPLAY,
1134cea9b549SWyon Bi #if defined(CONFIG_ROCKCHIP_RK3288)
1135cea9b549SWyon Bi "dsi@ff964000",
1136e9b1001bSGuochun Huang #elif defined(CONFIG_ROCKCHIP_RK3399)
1137cea9b549SWyon Bi "dsi@ff968000",
1138e9b1001bSGuochun Huang #else
1139e9b1001bSGuochun Huang "dsi@fe070000",
1140cea9b549SWyon Bi #endif
11413320fa93SWyon Bi &dev);
11423320fa93SWyon Bi if (ret)
11433320fa93SWyon Bi return ret;
11443320fa93SWyon Bi
11453320fa93SWyon Bi dsi->slave = dev_get_priv(dev);
11463320fa93SWyon Bi if (!dsi->slave)
11473320fa93SWyon Bi return -ENODEV;
11483320fa93SWyon Bi
114974e39389SWyon Bi dsi->lanes /= 2;
115074e39389SWyon Bi dsi->slave->lanes = dsi->lanes;
115174e39389SWyon Bi dsi->slave->format = dsi->format;
115274e39389SWyon Bi dsi->slave->mode_flags = dsi->mode_flags;
115374e39389SWyon Bi dsi->slave->channel = dsi->channel;
1154bee25ee6SGuochun Huang conn_state->output_flags =
1155bee25ee6SGuochun Huang ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE;
115610bd5723SGuochun Huang if (dsi->data_swap)
115710bd5723SGuochun Huang conn_state->output_flags |= ROCKCHIP_OUTPUT_DATA_SWAP;
115810bd5723SGuochun Huang
1159e9b1001bSGuochun Huang conn_state->output_if |= VOP_OUTPUT_IF_MIPI1;
1160e9b1001bSGuochun Huang
1161e9b1001bSGuochun Huang #if defined(CONFIG_ROCKCHIP_RK3568)
1162e9b1001bSGuochun Huang struct rockchip_phy *phy = NULL;
1163e9b1001bSGuochun Huang struct udevice *phy_dev;
1164e9b1001bSGuochun Huang
1165e9b1001bSGuochun Huang ret = uclass_get_device_by_phandle(UCLASS_PHY, dev,
1166e9b1001bSGuochun Huang "phys", &phy_dev);
1167e9b1001bSGuochun Huang if (ret)
1168e9b1001bSGuochun Huang return -ENODEV;
1169e9b1001bSGuochun Huang
1170e9b1001bSGuochun Huang phy = (struct rockchip_phy *)dev_get_driver_data(phy_dev);
1171e9b1001bSGuochun Huang if (!phy)
1172e9b1001bSGuochun Huang return -ENODEV;
1173e9b1001bSGuochun Huang
1174e9b1001bSGuochun Huang dsi->slave->dphy.phy = phy;
1175e9b1001bSGuochun Huang if (phy->funcs && phy->funcs->init)
1176e9b1001bSGuochun Huang return phy->funcs->init(phy);
1177e9b1001bSGuochun Huang #endif
1178e9b1001bSGuochun Huang
117974e39389SWyon Bi }
118074e39389SWyon Bi
118174e39389SWyon Bi return 0;
118274e39389SWyon Bi }
118374e39389SWyon Bi
dw_mipi_dsi_set_hs_clk(struct dw_mipi_dsi * dsi,unsigned long rate)118474e39389SWyon Bi static void dw_mipi_dsi_set_hs_clk(struct dw_mipi_dsi *dsi, unsigned long rate)
118574e39389SWyon Bi {
118674e39389SWyon Bi rate = rockchip_phy_set_pll(dsi->dphy.phy, rate);
11871953e619SWyon Bi dsi->lane_mbps = rate / 1000 / 1000;
118874e39389SWyon Bi }
118974e39389SWyon Bi
dw_mipi_dsi_host_init(struct dw_mipi_dsi * dsi)119074e39389SWyon Bi static void dw_mipi_dsi_host_init(struct dw_mipi_dsi *dsi)
119174e39389SWyon Bi {
119274e39389SWyon Bi dw_mipi_dsi_init(dsi);
11933320fa93SWyon Bi dw_mipi_dsi_dpi_config(dsi, &dsi->mode);
119474e39389SWyon Bi dw_mipi_dsi_packet_handler_config(dsi);
119574e39389SWyon Bi dw_mipi_dsi_video_mode_config(dsi);
11963320fa93SWyon Bi dw_mipi_dsi_video_packet_config(dsi, &dsi->mode);
119774e39389SWyon Bi dw_mipi_dsi_command_mode_config(dsi);
119874e39389SWyon Bi dsi_update_bits(dsi, DSI_MODE_CFG, CMD_VIDEO_MODE, COMMAND_MODE);
119974e39389SWyon Bi dw_mipi_dsi_line_timer_config(dsi);
120074e39389SWyon Bi dw_mipi_dsi_vertical_timing_config(dsi);
120174e39389SWyon Bi dw_mipi_dsi_dphy_timing_config(dsi);
120274e39389SWyon Bi dw_mipi_dsi_dphy_interface_config(dsi);
120374e39389SWyon Bi dw_mipi_dsi_clear_err(dsi);
120474e39389SWyon Bi }
120574e39389SWyon Bi
dw_mipi_dsi_vop_routing(struct dw_mipi_dsi * dsi,int vop_id)120674e39389SWyon Bi static void dw_mipi_dsi_vop_routing(struct dw_mipi_dsi *dsi, int vop_id)
120774e39389SWyon Bi {
120874e39389SWyon Bi grf_field_write(dsi, VOPSEL, vop_id);
120974e39389SWyon Bi
121074e39389SWyon Bi if (dsi->slave)
121174e39389SWyon Bi grf_field_write(dsi->slave, VOPSEL, vop_id);
121274e39389SWyon Bi }
121374e39389SWyon Bi
mipi_dphy_init(struct dw_mipi_dsi * dsi)121474e39389SWyon Bi static void mipi_dphy_init(struct dw_mipi_dsi *dsi)
121574e39389SWyon Bi {
12163320fa93SWyon Bi u32 map[] = {0x0, 0x1, 0x3, 0x7, 0xf};
121774e39389SWyon Bi
121874e39389SWyon Bi mipi_dphy_enableclk_deassert(dsi);
121974e39389SWyon Bi mipi_dphy_shutdownz_assert(dsi);
122074e39389SWyon Bi mipi_dphy_rstz_assert(dsi);
122174e39389SWyon Bi testif_testclr_assert(dsi);
122274e39389SWyon Bi
122374e39389SWyon Bi /* Configures DPHY to work as a Master */
122474e39389SWyon Bi grf_field_write(dsi, MASTERSLAVEZ, 1);
122574e39389SWyon Bi
122674e39389SWyon Bi /* Configures lane as TX */
122774e39389SWyon Bi grf_field_write(dsi, BASEDIR, 0);
122874e39389SWyon Bi
122974e39389SWyon Bi /* Set all REQUEST inputs to zero */
123074e39389SWyon Bi grf_field_write(dsi, TURNREQUEST, 0);
123174e39389SWyon Bi grf_field_write(dsi, TURNDISABLE, 0);
123274e39389SWyon Bi grf_field_write(dsi, FORCETXSTOPMODE, 0);
123374e39389SWyon Bi grf_field_write(dsi, FORCERXMODE, 0);
123474e39389SWyon Bi udelay(1);
123574e39389SWyon Bi
123674e39389SWyon Bi testif_testclr_deassert(dsi);
123774e39389SWyon Bi
123874e39389SWyon Bi if (!dsi->dphy.phy)
123974e39389SWyon Bi dw_mipi_dsi_phy_init(dsi);
124074e39389SWyon Bi
124174e39389SWyon Bi /* Enable Data Lane Module */
12423320fa93SWyon Bi grf_field_write(dsi, ENABLE_N, map[dsi->lanes]);
124374e39389SWyon Bi
124474e39389SWyon Bi /* Enable Clock Lane Module */
124574e39389SWyon Bi grf_field_write(dsi, ENABLECLK, 1);
124674e39389SWyon Bi
124774e39389SWyon Bi mipi_dphy_enableclk_assert(dsi);
124874e39389SWyon Bi }
124974e39389SWyon Bi
dw_mipi_dsi_pre_enable(struct dw_mipi_dsi * dsi)125074e39389SWyon Bi static void dw_mipi_dsi_pre_enable(struct dw_mipi_dsi *dsi)
125174e39389SWyon Bi {
12523320fa93SWyon Bi if (dsi->prepared)
12533320fa93SWyon Bi return;
12543320fa93SWyon Bi
12553320fa93SWyon Bi if (dsi->master)
12563320fa93SWyon Bi dw_mipi_dsi_pre_enable(dsi->master);
12573320fa93SWyon Bi
125874e39389SWyon Bi dw_mipi_dsi_host_init(dsi);
125974e39389SWyon Bi mipi_dphy_init(dsi);
126074e39389SWyon Bi mipi_dphy_power_on(dsi);
126174e39389SWyon Bi dsi_write(dsi, DSI_PWR_UP, POWERUP);
126274e39389SWyon Bi
12633320fa93SWyon Bi dsi->prepared = true;
12643320fa93SWyon Bi
126574e39389SWyon Bi if (dsi->slave)
126674e39389SWyon Bi dw_mipi_dsi_pre_enable(dsi->slave);
126774e39389SWyon Bi }
126874e39389SWyon Bi
dw_mipi_dsi_connector_prepare(struct rockchip_connector * conn,struct display_state * state)12690594ce39SZhang Yubing static int dw_mipi_dsi_connector_prepare(struct rockchip_connector *conn,
12700594ce39SZhang Yubing struct display_state *state)
127174e39389SWyon Bi {
127274e39389SWyon Bi struct connector_state *conn_state = &state->conn_state;
127374e39389SWyon Bi struct crtc_state *crtc_state = &state->crtc_state;
12740594ce39SZhang Yubing struct dw_mipi_dsi *dsi = dev_get_priv(conn->dev);
127574e39389SWyon Bi unsigned long lane_rate;
127674e39389SWyon Bi
12773320fa93SWyon Bi memcpy(&dsi->mode, &conn_state->mode, sizeof(struct drm_display_mode));
12783320fa93SWyon Bi if (dsi->slave) {
12793320fa93SWyon Bi dsi->mode.hdisplay /= 2;
12803320fa93SWyon Bi memcpy(&dsi->slave->mode, &dsi->mode,
12813320fa93SWyon Bi sizeof(struct drm_display_mode));
12823320fa93SWyon Bi }
128374e39389SWyon Bi
128474e39389SWyon Bi lane_rate = dw_mipi_dsi_get_lane_rate(dsi);
128574e39389SWyon Bi if (dsi->dphy.phy)
128674e39389SWyon Bi dw_mipi_dsi_set_hs_clk(dsi, lane_rate);
128774e39389SWyon Bi else
128874e39389SWyon Bi dw_mipi_dsi_set_pll(dsi, lane_rate);
128974e39389SWyon Bi
1290e9b1001bSGuochun Huang if (dsi->slave && dsi->slave->dphy.phy)
1291e9b1001bSGuochun Huang dw_mipi_dsi_set_hs_clk(dsi->slave, lane_rate);
1292e9b1001bSGuochun Huang
129374e39389SWyon Bi printf("final DSI-Link bandwidth: %u Mbps x %d\n",
129474e39389SWyon Bi dsi->lane_mbps, dsi->slave ? dsi->lanes * 2 : dsi->lanes);
129574e39389SWyon Bi
129674e39389SWyon Bi dw_mipi_dsi_vop_routing(dsi, crtc_state->crtc_id);
129774e39389SWyon Bi dw_mipi_dsi_pre_enable(dsi);
129874e39389SWyon Bi
129974e39389SWyon Bi return 0;
130074e39389SWyon Bi }
130174e39389SWyon Bi
dw_mipi_dsi_connector_unprepare(struct rockchip_connector * conn,struct display_state * state)13020594ce39SZhang Yubing static void dw_mipi_dsi_connector_unprepare(struct rockchip_connector *conn,
13030594ce39SZhang Yubing struct display_state *state)
130474e39389SWyon Bi {
13050594ce39SZhang Yubing struct dw_mipi_dsi *dsi = dev_get_priv(conn->dev);
130674e39389SWyon Bi
130774e39389SWyon Bi dw_mipi_dsi_post_disable(dsi);
130874e39389SWyon Bi }
130974e39389SWyon Bi
dw_mipi_dsi_connector_enable(struct rockchip_connector * conn,struct display_state * state)13100594ce39SZhang Yubing static int dw_mipi_dsi_connector_enable(struct rockchip_connector *conn,
13110594ce39SZhang Yubing struct display_state *state)
131274e39389SWyon Bi {
13130594ce39SZhang Yubing struct dw_mipi_dsi *dsi = dev_get_priv(conn->dev);
131474e39389SWyon Bi
131574e39389SWyon Bi dw_mipi_dsi_enable(dsi);
131674e39389SWyon Bi
131774e39389SWyon Bi return 0;
131874e39389SWyon Bi }
131974e39389SWyon Bi
dw_mipi_dsi_connector_disable(struct rockchip_connector * conn,struct display_state * state)13200594ce39SZhang Yubing static int dw_mipi_dsi_connector_disable(struct rockchip_connector *conn,
13210594ce39SZhang Yubing struct display_state *state)
132274e39389SWyon Bi {
13230594ce39SZhang Yubing struct dw_mipi_dsi *dsi = dev_get_priv(conn->dev);
132474e39389SWyon Bi
132574e39389SWyon Bi dw_mipi_dsi_disable(dsi);
132674e39389SWyon Bi
132774e39389SWyon Bi return 0;
132874e39389SWyon Bi }
132974e39389SWyon Bi
133074e39389SWyon Bi static const struct rockchip_connector_funcs dw_mipi_dsi_connector_funcs = {
133174e39389SWyon Bi .init = dw_mipi_dsi_connector_init,
133274e39389SWyon Bi .prepare = dw_mipi_dsi_connector_prepare,
133374e39389SWyon Bi .unprepare = dw_mipi_dsi_connector_unprepare,
133474e39389SWyon Bi .enable = dw_mipi_dsi_connector_enable,
133574e39389SWyon Bi .disable = dw_mipi_dsi_connector_disable,
133674e39389SWyon Bi };
133774e39389SWyon Bi
dw_mipi_dsi_probe(struct udevice * dev)133874e39389SWyon Bi static int dw_mipi_dsi_probe(struct udevice *dev)
133974e39389SWyon Bi {
134074e39389SWyon Bi struct dw_mipi_dsi *dsi = dev_get_priv(dev);
13410594ce39SZhang Yubing const struct dw_mipi_dsi_plat_data *pdata =
13420594ce39SZhang Yubing (const struct dw_mipi_dsi_plat_data *)dev_get_driver_data(dev);
13433320fa93SWyon Bi int id;
134474e39389SWyon Bi
134574e39389SWyon Bi dsi->base = dev_read_addr_ptr(dev);
134674e39389SWyon Bi dsi->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
134774e39389SWyon Bi if (IS_ERR(dsi->grf))
134874e39389SWyon Bi return PTR_ERR(dsi->grf);
134974e39389SWyon Bi
135074e39389SWyon Bi id = of_alias_get_id(ofnode_to_np(dev->node), "dsi");
135174e39389SWyon Bi if (id < 0)
135274e39389SWyon Bi id = 0;
135374e39389SWyon Bi
135474e39389SWyon Bi dsi->dev = dev;
135574e39389SWyon Bi dsi->pdata = pdata;
135674e39389SWyon Bi dsi->id = id;
1357a7015c5eSZhibin Huang dsi->dual_channel = dev_read_bool(dsi->dev, "rockchip,dual-channel");
135810bd5723SGuochun Huang dsi->data_swap = dev_read_bool(dsi->dev, "rockchip,data-swap");
1359d451259aSGuochun Huang dsi->disable_hold_mode = dev_read_bool(dsi->dev, "disable-hold-mode");
136074e39389SWyon Bi
13610594ce39SZhang Yubing rockchip_connector_bind(&dsi->connector, dev, dsi->id, &dw_mipi_dsi_connector_funcs, NULL,
13620594ce39SZhang Yubing DRM_MODE_CONNECTOR_DSI);
13630594ce39SZhang Yubing
136474e39389SWyon Bi return 0;
136574e39389SWyon Bi }
136674e39389SWyon Bi
136774e39389SWyon Bi static const u32 px30_dsi_grf_reg_fields[MAX_FIELDS] = {
136874e39389SWyon Bi [DPIUPDATECFG] = GRF_REG_FIELD(0x0434, 7, 7),
136974e39389SWyon Bi [DPICOLORM] = GRF_REG_FIELD(0x0434, 3, 3),
137074e39389SWyon Bi [DPISHUTDN] = GRF_REG_FIELD(0x0434, 2, 2),
137174e39389SWyon Bi [FORCETXSTOPMODE] = GRF_REG_FIELD(0x0438, 7, 10),
137274e39389SWyon Bi [TURNDISABLE] = GRF_REG_FIELD(0x0438, 5, 5),
137374e39389SWyon Bi [VOPSEL] = GRF_REG_FIELD(0x0438, 0, 0),
137474e39389SWyon Bi };
137574e39389SWyon Bi
137674e39389SWyon Bi static const struct dw_mipi_dsi_plat_data px30_mipi_dsi_plat_data = {
137774e39389SWyon Bi .dsi0_grf_reg_fields = px30_dsi_grf_reg_fields,
137874e39389SWyon Bi .max_bit_rate_per_lane = 1000000000UL,
137974e39389SWyon Bi };
138074e39389SWyon Bi
1381f8841d3bSNickey Yang static const u32 rk1808_dsi_grf_reg_fields[MAX_FIELDS] = {
1382f8841d3bSNickey Yang [MASTERSLAVEZ] = GRF_REG_FIELD(0x0440, 8, 8),
1383f8841d3bSNickey Yang [DPIUPDATECFG] = GRF_REG_FIELD(0x0440, 7, 7),
1384f8841d3bSNickey Yang [DPICOLORM] = GRF_REG_FIELD(0x0440, 3, 3),
1385f8841d3bSNickey Yang [DPISHUTDN] = GRF_REG_FIELD(0x0440, 2, 2),
1386f8841d3bSNickey Yang [FORCETXSTOPMODE] = GRF_REG_FIELD(0x0444, 7, 10),
1387f8841d3bSNickey Yang [FORCERXMODE] = GRF_REG_FIELD(0x0444, 6, 6),
1388f8841d3bSNickey Yang [TURNDISABLE] = GRF_REG_FIELD(0x0444, 5, 5),
1389f8841d3bSNickey Yang };
1390f8841d3bSNickey Yang
1391f8841d3bSNickey Yang static const struct dw_mipi_dsi_plat_data rk1808_mipi_dsi_plat_data = {
1392f8841d3bSNickey Yang .dsi0_grf_reg_fields = rk1808_dsi_grf_reg_fields,
1393f8841d3bSNickey Yang .max_bit_rate_per_lane = 2000000000UL,
1394f8841d3bSNickey Yang };
1395f8841d3bSNickey Yang
139674e39389SWyon Bi static const u32 rk3128_dsi_grf_reg_fields[MAX_FIELDS] = {
139774e39389SWyon Bi [FORCETXSTOPMODE] = GRF_REG_FIELD(0x0150, 10, 13),
139874e39389SWyon Bi [FORCERXMODE] = GRF_REG_FIELD(0x0150, 9, 9),
139974e39389SWyon Bi [TURNDISABLE] = GRF_REG_FIELD(0x0150, 8, 8),
140074e39389SWyon Bi [DPICOLORM] = GRF_REG_FIELD(0x0150, 5, 5),
140174e39389SWyon Bi [DPISHUTDN] = GRF_REG_FIELD(0x0150, 4, 4),
140274e39389SWyon Bi };
140374e39389SWyon Bi
140474e39389SWyon Bi static const struct dw_mipi_dsi_plat_data rk3128_mipi_dsi_plat_data = {
140574e39389SWyon Bi .dsi0_grf_reg_fields = rk3128_dsi_grf_reg_fields,
140674e39389SWyon Bi .max_bit_rate_per_lane = 1000000000UL,
140774e39389SWyon Bi };
140874e39389SWyon Bi
140974e39389SWyon Bi static const u32 rk3288_dsi0_grf_reg_fields[MAX_FIELDS] = {
141074e39389SWyon Bi [DPICOLORM] = GRF_REG_FIELD(0x025c, 8, 8),
141174e39389SWyon Bi [DPISHUTDN] = GRF_REG_FIELD(0x025c, 7, 7),
141274e39389SWyon Bi [VOPSEL] = GRF_REG_FIELD(0x025c, 6, 6),
141374e39389SWyon Bi [FORCETXSTOPMODE] = GRF_REG_FIELD(0x0264, 8, 11),
141474e39389SWyon Bi [FORCERXMODE] = GRF_REG_FIELD(0x0264, 4, 7),
141574e39389SWyon Bi [TURNDISABLE] = GRF_REG_FIELD(0x0264, 0, 3),
141674e39389SWyon Bi [TURNREQUEST] = GRF_REG_FIELD(0x03a4, 8, 10),
141774e39389SWyon Bi [DPIUPDATECFG] = GRF_REG_FIELD(0x03a8, 0, 0),
141874e39389SWyon Bi };
141974e39389SWyon Bi
142074e39389SWyon Bi static const u32 rk3288_dsi1_grf_reg_fields[MAX_FIELDS] = {
142174e39389SWyon Bi [DPICOLORM] = GRF_REG_FIELD(0x025c, 11, 11),
142274e39389SWyon Bi [DPISHUTDN] = GRF_REG_FIELD(0x025c, 10, 10),
142374e39389SWyon Bi [VOPSEL] = GRF_REG_FIELD(0x025c, 9, 9),
142474e39389SWyon Bi [ENABLE_N] = GRF_REG_FIELD(0x0268, 12, 15),
142574e39389SWyon Bi [FORCETXSTOPMODE] = GRF_REG_FIELD(0x0268, 8, 11),
142674e39389SWyon Bi [FORCERXMODE] = GRF_REG_FIELD(0x0268, 4, 7),
142774e39389SWyon Bi [TURNDISABLE] = GRF_REG_FIELD(0x0268, 0, 3),
142874e39389SWyon Bi [BASEDIR] = GRF_REG_FIELD(0x027c, 15, 15),
142974e39389SWyon Bi [MASTERSLAVEZ] = GRF_REG_FIELD(0x027c, 14, 14),
143074e39389SWyon Bi [ENABLECLK] = GRF_REG_FIELD(0x027c, 12, 12),
143174e39389SWyon Bi [TURNREQUEST] = GRF_REG_FIELD(0x03a4, 4, 7),
143274e39389SWyon Bi [DPIUPDATECFG] = GRF_REG_FIELD(0x03a8, 1, 1),
143374e39389SWyon Bi };
143474e39389SWyon Bi
143574e39389SWyon Bi static const struct dw_mipi_dsi_plat_data rk3288_mipi_dsi_plat_data = {
143674e39389SWyon Bi .dsi0_grf_reg_fields = rk3288_dsi0_grf_reg_fields,
143774e39389SWyon Bi .dsi1_grf_reg_fields = rk3288_dsi1_grf_reg_fields,
143874e39389SWyon Bi .max_bit_rate_per_lane = 1500000000UL,
143974e39389SWyon Bi };
144074e39389SWyon Bi
144174e39389SWyon Bi static const u32 rk3366_dsi_grf_reg_fields[MAX_FIELDS] = {
144274e39389SWyon Bi [VOPSEL] = GRF_REG_FIELD(0x0400, 2, 2),
144374e39389SWyon Bi [DPIUPDATECFG] = GRF_REG_FIELD(0x0410, 9, 9),
144474e39389SWyon Bi [DPICOLORM] = GRF_REG_FIELD(0x0410, 3, 3),
144574e39389SWyon Bi [DPISHUTDN] = GRF_REG_FIELD(0x0410, 2, 2),
144674e39389SWyon Bi [FORCETXSTOPMODE] = GRF_REG_FIELD(0x0414, 7, 10),
144774e39389SWyon Bi [FORCERXMODE] = GRF_REG_FIELD(0x0414, 6, 6),
144874e39389SWyon Bi [TURNDISABLE] = GRF_REG_FIELD(0x0414, 5, 5),
144974e39389SWyon Bi };
145074e39389SWyon Bi
145174e39389SWyon Bi static const struct dw_mipi_dsi_plat_data rk3366_mipi_dsi_plat_data = {
145274e39389SWyon Bi .dsi0_grf_reg_fields = rk3366_dsi_grf_reg_fields,
145374e39389SWyon Bi .max_bit_rate_per_lane = 1000000000UL,
145474e39389SWyon Bi };
145574e39389SWyon Bi
145674e39389SWyon Bi static const u32 rk3368_dsi_grf_reg_fields[MAX_FIELDS] = {
145774e39389SWyon Bi [DPIUPDATECFG] = GRF_REG_FIELD(0x0418, 7, 7),
145874e39389SWyon Bi [DPICOLORM] = GRF_REG_FIELD(0x0418, 3, 3),
145974e39389SWyon Bi [DPISHUTDN] = GRF_REG_FIELD(0x0418, 2, 2),
146074e39389SWyon Bi [FORCETXSTOPMODE] = GRF_REG_FIELD(0x041c, 7, 10),
146174e39389SWyon Bi [FORCERXMODE] = GRF_REG_FIELD(0x041c, 6, 6),
146274e39389SWyon Bi [TURNDISABLE] = GRF_REG_FIELD(0x041c, 5, 5),
146374e39389SWyon Bi };
146474e39389SWyon Bi
146574e39389SWyon Bi static const struct dw_mipi_dsi_plat_data rk3368_mipi_dsi_plat_data = {
146674e39389SWyon Bi .dsi0_grf_reg_fields = rk3368_dsi_grf_reg_fields,
146774e39389SWyon Bi .max_bit_rate_per_lane = 1000000000UL,
146874e39389SWyon Bi };
146974e39389SWyon Bi
147074e39389SWyon Bi static const u32 rk3399_dsi0_grf_reg_fields[MAX_FIELDS] = {
147174e39389SWyon Bi [DPIUPDATECFG] = GRF_REG_FIELD(0x6224, 15, 15),
147274e39389SWyon Bi [DPISHUTDN] = GRF_REG_FIELD(0x6224, 14, 14),
147374e39389SWyon Bi [DPICOLORM] = GRF_REG_FIELD(0x6224, 13, 13),
147474e39389SWyon Bi [VOPSEL] = GRF_REG_FIELD(0x6250, 0, 0),
147574e39389SWyon Bi [TURNREQUEST] = GRF_REG_FIELD(0x6258, 12, 15),
147674e39389SWyon Bi [TURNDISABLE] = GRF_REG_FIELD(0x6258, 8, 11),
147774e39389SWyon Bi [FORCETXSTOPMODE] = GRF_REG_FIELD(0x6258, 4, 7),
147874e39389SWyon Bi [FORCERXMODE] = GRF_REG_FIELD(0x6258, 0, 3),
147974e39389SWyon Bi };
148074e39389SWyon Bi
148174e39389SWyon Bi static const u32 rk3399_dsi1_grf_reg_fields[MAX_FIELDS] = {
148274e39389SWyon Bi [VOPSEL] = GRF_REG_FIELD(0x6250, 4, 4),
148374e39389SWyon Bi [DPIUPDATECFG] = GRF_REG_FIELD(0x6250, 3, 3),
148474e39389SWyon Bi [DPISHUTDN] = GRF_REG_FIELD(0x6250, 2, 2),
148574e39389SWyon Bi [DPICOLORM] = GRF_REG_FIELD(0x6250, 1, 1),
148674e39389SWyon Bi [TURNDISABLE] = GRF_REG_FIELD(0x625c, 12, 15),
148774e39389SWyon Bi [FORCETXSTOPMODE] = GRF_REG_FIELD(0x625c, 8, 11),
148874e39389SWyon Bi [FORCERXMODE] = GRF_REG_FIELD(0x625c, 4, 7),
148974e39389SWyon Bi [ENABLE_N] = GRF_REG_FIELD(0x625c, 0, 3),
149074e39389SWyon Bi [MASTERSLAVEZ] = GRF_REG_FIELD(0x6260, 7, 7),
149174e39389SWyon Bi [ENABLECLK] = GRF_REG_FIELD(0x6260, 6, 6),
149274e39389SWyon Bi [BASEDIR] = GRF_REG_FIELD(0x6260, 5, 5),
149374e39389SWyon Bi [TURNREQUEST] = GRF_REG_FIELD(0x6260, 0, 3),
149474e39389SWyon Bi };
149574e39389SWyon Bi
149674e39389SWyon Bi static const struct dw_mipi_dsi_plat_data rk3399_mipi_dsi_plat_data = {
149774e39389SWyon Bi .dsi0_grf_reg_fields = rk3399_dsi0_grf_reg_fields,
149874e39389SWyon Bi .dsi1_grf_reg_fields = rk3399_dsi1_grf_reg_fields,
149974e39389SWyon Bi .max_bit_rate_per_lane = 1500000000UL,
150074e39389SWyon Bi };
150174e39389SWyon Bi
15021652d553SHongming Zou static const u32 rk3506_dsi_grf_reg_fields[MAX_FIELDS] = {
15031652d553SHongming Zou [DPIUPDATECFG] = GRF_REG_FIELD(0x0014, 2, 2),
15041652d553SHongming Zou [DPICOLORM] = GRF_REG_FIELD(0x0014, 1, 1),
15051652d553SHongming Zou [DPISHUTDN] = GRF_REG_FIELD(0x0014, 0, 0),
15061652d553SHongming Zou [SKEWCALHS] = GRF_REG_FIELD(0x0018, 11, 15),
15071652d553SHongming Zou [FORCETXSTOPMODE] = GRF_REG_FIELD(0x0018, 4, 7),
15081652d553SHongming Zou [TURNDISABLE] = GRF_REG_FIELD(0x0018, 2, 2),
15091652d553SHongming Zou [FORCERXMODE] = GRF_REG_FIELD(0x0018, 0, 0),
1510bd446d86SHongming Zou [ENABLE_N] = GRF_REG_FIELD(0x0018, 8, 9),
15111652d553SHongming Zou };
15121652d553SHongming Zou
15131652d553SHongming Zou static const struct dw_mipi_dsi_plat_data rk3506_mipi_dsi_plat_data = {
15141652d553SHongming Zou .dsi0_grf_reg_fields = rk3506_dsi_grf_reg_fields,
15151652d553SHongming Zou .max_bit_rate_per_lane = 1500000000UL,
15161652d553SHongming Zou };
15171652d553SHongming Zou
15180dba8b5cSGuochun Huang static const u32 rk3562_dsi_grf_reg_fields[MAX_FIELDS] = {
15190dba8b5cSGuochun Huang [DPIUPDATECFG] = GRF_REG_FIELD(0x05d0, 2, 2),
15200dba8b5cSGuochun Huang [DPICOLORM] = GRF_REG_FIELD(0x05d0, 1, 1),
15210dba8b5cSGuochun Huang [DPISHUTDN] = GRF_REG_FIELD(0x05d0, 0, 0),
15220dba8b5cSGuochun Huang [SKEWCALHS] = GRF_REG_FIELD(0x05d4, 11, 15),
15230dba8b5cSGuochun Huang [FORCETXSTOPMODE] = GRF_REG_FIELD(0x05d4, 4, 7),
15240dba8b5cSGuochun Huang [TURNDISABLE] = GRF_REG_FIELD(0x05d4, 2, 2),
15250dba8b5cSGuochun Huang [FORCERXMODE] = GRF_REG_FIELD(0x05d4, 0, 0),
15260dba8b5cSGuochun Huang };
15270dba8b5cSGuochun Huang
15280dba8b5cSGuochun Huang static const struct dw_mipi_dsi_plat_data rk3562_mipi_dsi_plat_data = {
15290dba8b5cSGuochun Huang .dsi0_grf_reg_fields = rk3562_dsi_grf_reg_fields,
15300dba8b5cSGuochun Huang .max_bit_rate_per_lane = 1200000000UL,
15310dba8b5cSGuochun Huang };
15320dba8b5cSGuochun Huang
1533e9b1001bSGuochun Huang static const u32 rk3568_dsi0_grf_reg_fields[MAX_FIELDS] = {
1534e9b1001bSGuochun Huang [DPIUPDATECFG] = GRF_REG_FIELD(0x0360, 2, 2),
1535e9b1001bSGuochun Huang [DPICOLORM] = GRF_REG_FIELD(0x0360, 1, 1),
1536e9b1001bSGuochun Huang [DPISHUTDN] = GRF_REG_FIELD(0x0360, 0, 0),
1537e9b1001bSGuochun Huang [SKEWCALHS] = GRF_REG_FIELD(0x0368, 11, 15),
1538e9b1001bSGuochun Huang [FORCETXSTOPMODE] = GRF_REG_FIELD(0x0368, 4, 7),
1539e9b1001bSGuochun Huang [TURNDISABLE] = GRF_REG_FIELD(0x0368, 2, 2),
1540e9b1001bSGuochun Huang [FORCERXMODE] = GRF_REG_FIELD(0x0368, 0, 0),
1541e9b1001bSGuochun Huang };
1542e9b1001bSGuochun Huang
1543e9b1001bSGuochun Huang static const u32 rk3568_dsi1_grf_reg_fields[MAX_FIELDS] = {
1544e9b1001bSGuochun Huang [DPIUPDATECFG] = GRF_REG_FIELD(0x0360, 10, 10),
1545e9b1001bSGuochun Huang [DPICOLORM] = GRF_REG_FIELD(0x0360, 9, 9),
1546e9b1001bSGuochun Huang [DPISHUTDN] = GRF_REG_FIELD(0x0360, 8, 8),
1547e9b1001bSGuochun Huang [SKEWCALHS] = GRF_REG_FIELD(0x036c, 11, 15),
1548e9b1001bSGuochun Huang [FORCETXSTOPMODE] = GRF_REG_FIELD(0x036c, 4, 7),
1549e9b1001bSGuochun Huang [TURNDISABLE] = GRF_REG_FIELD(0x036c, 2, 2),
1550e9b1001bSGuochun Huang [FORCERXMODE] = GRF_REG_FIELD(0x036c, 0, 0),
1551e9b1001bSGuochun Huang };
1552e9b1001bSGuochun Huang
1553e9b1001bSGuochun Huang static const struct dw_mipi_dsi_plat_data rk3568_mipi_dsi_plat_data = {
1554e9b1001bSGuochun Huang .dsi0_grf_reg_fields = rk3568_dsi0_grf_reg_fields,
1555e9b1001bSGuochun Huang .dsi1_grf_reg_fields = rk3568_dsi1_grf_reg_fields,
155663f3640cSGuochun Huang .max_bit_rate_per_lane = 1200000000UL,
1557e9b1001bSGuochun Huang };
1558e9b1001bSGuochun Huang
155974e39389SWyon Bi static const u32 rv1108_dsi_grf_reg_fields[MAX_FIELDS] = {
156074e39389SWyon Bi [DPICOLORM] = GRF_REG_FIELD(0x0410, 7, 7),
156174e39389SWyon Bi [DPISHUTDN] = GRF_REG_FIELD(0x0410, 6, 6),
156274e39389SWyon Bi [DPIUPDATECFG] = GRF_REG_FIELD(0x0410, 8, 8),
156374e39389SWyon Bi [FORCERXMODE] = GRF_REG_FIELD(0x0414, 5, 5),
156474e39389SWyon Bi [FORCETXSTOPMODE] = GRF_REG_FIELD(0x0414, 6, 9),
156574e39389SWyon Bi [TURNDISABLE] = GRF_REG_FIELD(0x0414, 4, 4),
156674e39389SWyon Bi };
156774e39389SWyon Bi
156874e39389SWyon Bi static const struct dw_mipi_dsi_plat_data rv1108_mipi_dsi_plat_data = {
156974e39389SWyon Bi .dsi0_grf_reg_fields = rv1108_dsi_grf_reg_fields,
157074e39389SWyon Bi .max_bit_rate_per_lane = 1000000000UL,
157174e39389SWyon Bi };
157274e39389SWyon Bi
1573efcb7be1SNickey Yang static const u32 rv1126_dsi_grf_reg_fields[MAX_FIELDS] = {
1574efcb7be1SNickey Yang [DPIUPDATECFG] = GRF_REG_FIELD(0x0008, 5, 5),
1575efcb7be1SNickey Yang [DPISHUTDN] = GRF_REG_FIELD(0x0008, 4, 4),
1576efcb7be1SNickey Yang [DPICOLORM] = GRF_REG_FIELD(0x0008, 3, 3),
1577efcb7be1SNickey Yang [FORCETXSTOPMODE] = GRF_REG_FIELD(0x10220, 4, 7),
1578efcb7be1SNickey Yang [TURNDISABLE] = GRF_REG_FIELD(0x10220, 2, 2),
1579efcb7be1SNickey Yang [FORCERXMODE] = GRF_REG_FIELD(0x10220, 0, 0),
1580efcb7be1SNickey Yang };
1581efcb7be1SNickey Yang
1582efcb7be1SNickey Yang static const struct dw_mipi_dsi_plat_data rv1126_mipi_dsi_plat_data = {
1583efcb7be1SNickey Yang .dsi0_grf_reg_fields = rv1126_dsi_grf_reg_fields,
1584efcb7be1SNickey Yang .max_bit_rate_per_lane = 1000000000UL,
1585efcb7be1SNickey Yang };
1586efcb7be1SNickey Yang
1587f62fdeadSHongming Zou static const u32 rv1126b_dsi_grf_reg_fields[MAX_FIELDS] = {
1588f62fdeadSHongming Zou [DPIUPDATECFG] = GRF_REG_FIELD(0x8000c, 3, 3),
1589f62fdeadSHongming Zou [DPICOLORM] = GRF_REG_FIELD(0x8000c, 1, 1),
1590f62fdeadSHongming Zou [DPISHUTDN] = GRF_REG_FIELD(0x8000c, 0, 0),
1591f62fdeadSHongming Zou [FORCETXSTOPMODE] = GRF_REG_FIELD(0x80010, 4, 7),
1592f62fdeadSHongming Zou [TURNDISABLE] = GRF_REG_FIELD(0x80010, 2, 2),
1593f62fdeadSHongming Zou [FORCERXMODE] = GRF_REG_FIELD(0x80010, 0, 0),
1594f62fdeadSHongming Zou };
1595f62fdeadSHongming Zou
1596f62fdeadSHongming Zou static const struct dw_mipi_dsi_plat_data rv1126b_mipi_dsi_plat_data = {
1597f62fdeadSHongming Zou .dsi0_grf_reg_fields = rv1126b_dsi_grf_reg_fields,
1598f62fdeadSHongming Zou .max_bit_rate_per_lane = 1000000000UL,
1599f62fdeadSHongming Zou };
1600f62fdeadSHongming Zou
160174e39389SWyon Bi static const struct udevice_id dw_mipi_dsi_ids[] = {
160274e39389SWyon Bi {
160374e39389SWyon Bi .compatible = "rockchip,px30-mipi-dsi",
16040594ce39SZhang Yubing .data = (ulong)&px30_mipi_dsi_plat_data,
160574e39389SWyon Bi },
160674e39389SWyon Bi {
1607f8841d3bSNickey Yang .compatible = "rockchip,rk1808-mipi-dsi",
16080594ce39SZhang Yubing .data = (ulong)&rk1808_mipi_dsi_plat_data,
1609f8841d3bSNickey Yang },
1610f8841d3bSNickey Yang {
161174e39389SWyon Bi .compatible = "rockchip,rk3128-mipi-dsi",
16120594ce39SZhang Yubing .data = (ulong)&rk3128_mipi_dsi_plat_data,
161374e39389SWyon Bi },
161474e39389SWyon Bi {
161574e39389SWyon Bi .compatible = "rockchip,rk3288-mipi-dsi",
16160594ce39SZhang Yubing .data = (ulong)&rk3288_mipi_dsi_plat_data,
161774e39389SWyon Bi },
161874e39389SWyon Bi {
161974e39389SWyon Bi .compatible = "rockchip,rk3366-mipi-dsi",
16200594ce39SZhang Yubing .data = (ulong)&rk3366_mipi_dsi_plat_data,
162174e39389SWyon Bi },
162274e39389SWyon Bi {
162374e39389SWyon Bi .compatible = "rockchip,rk3368-mipi-dsi",
16240594ce39SZhang Yubing .data = (ulong)&rk3368_mipi_dsi_plat_data,
162574e39389SWyon Bi },
162674e39389SWyon Bi {
162774e39389SWyon Bi .compatible = "rockchip,rk3399-mipi-dsi",
16280594ce39SZhang Yubing .data = (ulong)&rk3399_mipi_dsi_plat_data,
162974e39389SWyon Bi },
163074e39389SWyon Bi {
16311652d553SHongming Zou .compatible = "rockchip,rk3506-mipi-dsi",
16321652d553SHongming Zou .data = (ulong)&rk3506_mipi_dsi_plat_data,
16331652d553SHongming Zou },
16341652d553SHongming Zou {
16350dba8b5cSGuochun Huang .compatible = "rockchip,rk3562-mipi-dsi",
16360dba8b5cSGuochun Huang .data = (ulong)&rk3562_mipi_dsi_plat_data,
16370dba8b5cSGuochun Huang },
16380dba8b5cSGuochun Huang {
1639e9b1001bSGuochun Huang .compatible = "rockchip,rk3568-mipi-dsi",
16400594ce39SZhang Yubing .data = (ulong)&rk3568_mipi_dsi_plat_data,
1641e9b1001bSGuochun Huang },
1642e9b1001bSGuochun Huang {
164374e39389SWyon Bi .compatible = "rockchip,rv1108-mipi-dsi",
16440594ce39SZhang Yubing .data = (ulong)&rv1108_mipi_dsi_plat_data,
164574e39389SWyon Bi },
1646efcb7be1SNickey Yang {
1647efcb7be1SNickey Yang .compatible = "rockchip,rv1126-mipi-dsi",
16480594ce39SZhang Yubing .data = (ulong)&rv1126_mipi_dsi_plat_data,
1649efcb7be1SNickey Yang },
1650f62fdeadSHongming Zou {
1651f62fdeadSHongming Zou .compatible = "rockchip,rv1126b-mipi-dsi",
1652*ea0eaad4SHongming Zou .data = (ulong)&rv1126b_mipi_dsi_plat_data,
1653f62fdeadSHongming Zou },
165474e39389SWyon Bi {}
165574e39389SWyon Bi };
165674e39389SWyon Bi
dw_mipi_dsi_host_transfer(struct mipi_dsi_host * host,const struct mipi_dsi_msg * msg)16571953e619SWyon Bi static ssize_t dw_mipi_dsi_host_transfer(struct mipi_dsi_host *host,
16581953e619SWyon Bi const struct mipi_dsi_msg *msg)
16591953e619SWyon Bi {
16601953e619SWyon Bi struct dw_mipi_dsi *dsi = dev_get_priv(host->dev);
16611953e619SWyon Bi
16621953e619SWyon Bi return dw_mipi_dsi_transfer(dsi, msg);
16631953e619SWyon Bi }
16641953e619SWyon Bi
dw_mipi_dsi_host_attach(struct mipi_dsi_host * host,struct mipi_dsi_device * device)16651953e619SWyon Bi static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host,
16661953e619SWyon Bi struct mipi_dsi_device *device)
16671953e619SWyon Bi {
16681953e619SWyon Bi struct dw_mipi_dsi *dsi = dev_get_priv(host->dev);
16691953e619SWyon Bi
16701953e619SWyon Bi if (device->lanes < 1 || device->lanes > 8)
16711953e619SWyon Bi return -EINVAL;
16721953e619SWyon Bi
16731953e619SWyon Bi dsi->lanes = device->lanes;
16741953e619SWyon Bi dsi->channel = device->channel;
16751953e619SWyon Bi dsi->format = device->format;
16761953e619SWyon Bi dsi->mode_flags = device->mode_flags;
16771953e619SWyon Bi
16781953e619SWyon Bi return 0;
16791953e619SWyon Bi }
16801953e619SWyon Bi
16811953e619SWyon Bi static const struct mipi_dsi_host_ops dw_mipi_dsi_host_ops = {
16821953e619SWyon Bi .attach = dw_mipi_dsi_host_attach,
16831953e619SWyon Bi .transfer = dw_mipi_dsi_host_transfer,
16841953e619SWyon Bi };
16851953e619SWyon Bi
dw_mipi_dsi_bind(struct udevice * dev)16861953e619SWyon Bi static int dw_mipi_dsi_bind(struct udevice *dev)
16871953e619SWyon Bi {
16881953e619SWyon Bi struct mipi_dsi_host *host = dev_get_platdata(dev);
16891953e619SWyon Bi
16901953e619SWyon Bi host->dev = dev;
16911953e619SWyon Bi host->ops = &dw_mipi_dsi_host_ops;
16921953e619SWyon Bi
16931953e619SWyon Bi return dm_scan_fdt_dev(dev);
16941953e619SWyon Bi }
16951953e619SWyon Bi
dw_mipi_dsi_child_post_bind(struct udevice * dev)16961953e619SWyon Bi static int dw_mipi_dsi_child_post_bind(struct udevice *dev)
16971953e619SWyon Bi {
16981953e619SWyon Bi struct mipi_dsi_host *host = dev_get_platdata(dev->parent);
16991953e619SWyon Bi struct mipi_dsi_device *device = dev_get_parent_platdata(dev);
17003320fa93SWyon Bi char name[20];
17013320fa93SWyon Bi
17023320fa93SWyon Bi sprintf(name, "%s.%d", host->dev->name, device->channel);
17033320fa93SWyon Bi device_set_name(dev, name);
17041953e619SWyon Bi
17051953e619SWyon Bi device->dev = dev;
17061953e619SWyon Bi device->host = host;
17071953e619SWyon Bi device->lanes = dev_read_u32_default(dev, "dsi,lanes", 4);
17081953e619SWyon Bi device->format = dev_read_u32_default(dev, "dsi,format",
17091953e619SWyon Bi MIPI_DSI_FMT_RGB888);
17101953e619SWyon Bi device->mode_flags = dev_read_u32_default(dev, "dsi,flags",
17111953e619SWyon Bi MIPI_DSI_MODE_VIDEO |
17121953e619SWyon Bi MIPI_DSI_MODE_VIDEO_BURST |
1713edbf2db2SGuochun Huang MIPI_DSI_MODE_VIDEO_NO_HBP |
17141953e619SWyon Bi MIPI_DSI_MODE_LPM |
1715edbf2db2SGuochun Huang MIPI_DSI_MODE_NO_EOT_PACKET);
17161953e619SWyon Bi device->channel = dev_read_u32_default(dev, "reg", 0);
17171953e619SWyon Bi
17181953e619SWyon Bi return 0;
17191953e619SWyon Bi }
17201953e619SWyon Bi
dw_mipi_dsi_child_pre_probe(struct udevice * dev)17211953e619SWyon Bi static int dw_mipi_dsi_child_pre_probe(struct udevice *dev)
17221953e619SWyon Bi {
17231953e619SWyon Bi struct mipi_dsi_device *device = dev_get_parent_platdata(dev);
17241953e619SWyon Bi int ret;
17251953e619SWyon Bi
17261953e619SWyon Bi ret = mipi_dsi_attach(device);
17271953e619SWyon Bi if (ret) {
17281953e619SWyon Bi dev_err(dev, "mipi_dsi_attach() failed: %d\n", ret);
17291953e619SWyon Bi return ret;
17301953e619SWyon Bi }
17311953e619SWyon Bi
17321953e619SWyon Bi return 0;
17331953e619SWyon Bi }
17341953e619SWyon Bi
173574e39389SWyon Bi U_BOOT_DRIVER(dw_mipi_dsi) = {
173674e39389SWyon Bi .name = "dw_mipi_dsi",
173774e39389SWyon Bi .id = UCLASS_DISPLAY,
173874e39389SWyon Bi .of_match = dw_mipi_dsi_ids,
173974e39389SWyon Bi .probe = dw_mipi_dsi_probe,
17401953e619SWyon Bi .bind = dw_mipi_dsi_bind,
174174e39389SWyon Bi .priv_auto_alloc_size = sizeof(struct dw_mipi_dsi),
17421953e619SWyon Bi .per_child_platdata_auto_alloc_size = sizeof(struct mipi_dsi_device),
17431953e619SWyon Bi .platdata_auto_alloc_size = sizeof(struct mipi_dsi_host),
17441953e619SWyon Bi .child_post_bind = dw_mipi_dsi_child_post_bind,
17451953e619SWyon Bi .child_pre_probe = dw_mipi_dsi_child_pre_probe,
174674e39389SWyon Bi };
1747