xref: /OK3568_Linux_fs/u-boot/drivers/video/bridge/anx6345.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright (C) 2017 Vasily Khoruzhick <anarsoul@gmail.com>
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
5*4882a593Smuzhiyun  */
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #include <common.h>
8*4882a593Smuzhiyun #include <dm.h>
9*4882a593Smuzhiyun #include <errno.h>
10*4882a593Smuzhiyun #include <i2c.h>
11*4882a593Smuzhiyun #include <edid.h>
12*4882a593Smuzhiyun #include <video_bridge.h>
13*4882a593Smuzhiyun #include "../anx98xx-edp.h"
14*4882a593Smuzhiyun #include "../drm/rockchip_bridge.h"
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun #define DP_MAX_LINK_RATE		0x001
17*4882a593Smuzhiyun #define DP_MAX_LANE_COUNT		0x002
18*4882a593Smuzhiyun #define DP_MAX_LANE_COUNT_MASK		0x1f
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun DECLARE_GLOBAL_DATA_PTR;
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun struct anx6345_priv {
23*4882a593Smuzhiyun 	u8 chipid;
24*4882a593Smuzhiyun 	u8 edid[EDID_SIZE];
25*4882a593Smuzhiyun };
26*4882a593Smuzhiyun 
anx6345_write(struct udevice * dev,unsigned int addr_off,unsigned char reg_addr,unsigned char value)27*4882a593Smuzhiyun static int anx6345_write(struct udevice *dev, unsigned int addr_off,
28*4882a593Smuzhiyun 			 unsigned char reg_addr, unsigned char value)
29*4882a593Smuzhiyun {
30*4882a593Smuzhiyun 	uint8_t buf[2];
31*4882a593Smuzhiyun 	struct i2c_msg msg;
32*4882a593Smuzhiyun 	int ret;
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun 	msg.addr = addr_off;
35*4882a593Smuzhiyun 	msg.flags = 0;
36*4882a593Smuzhiyun 	buf[0] = reg_addr;
37*4882a593Smuzhiyun 	buf[1] = value;
38*4882a593Smuzhiyun 	msg.buf = buf;
39*4882a593Smuzhiyun 	msg.len = 2;
40*4882a593Smuzhiyun 	ret = dm_i2c_xfer(dev, &msg, 1);
41*4882a593Smuzhiyun 	if (ret) {
42*4882a593Smuzhiyun 		debug("%s: write failed, reg=%#x, value=%#x, ret=%d\n",
43*4882a593Smuzhiyun 		      __func__, reg_addr, value, ret);
44*4882a593Smuzhiyun 		return ret;
45*4882a593Smuzhiyun 	}
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun 	return 0;
48*4882a593Smuzhiyun }
49*4882a593Smuzhiyun 
anx6345_read(struct udevice * dev,unsigned int addr_off,unsigned char reg_addr,unsigned char * value)50*4882a593Smuzhiyun static int anx6345_read(struct udevice *dev, unsigned int addr_off,
51*4882a593Smuzhiyun 			unsigned char reg_addr, unsigned char *value)
52*4882a593Smuzhiyun {
53*4882a593Smuzhiyun 	uint8_t addr, val;
54*4882a593Smuzhiyun 	struct i2c_msg msg[2];
55*4882a593Smuzhiyun 	int ret;
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun 	msg[0].addr = addr_off;
58*4882a593Smuzhiyun 	msg[0].flags = 0;
59*4882a593Smuzhiyun 	addr = reg_addr;
60*4882a593Smuzhiyun 	msg[0].buf = &addr;
61*4882a593Smuzhiyun 	msg[0].len = 1;
62*4882a593Smuzhiyun 	msg[1].addr = addr_off;
63*4882a593Smuzhiyun 	msg[1].flags = I2C_M_RD;
64*4882a593Smuzhiyun 	msg[1].buf = &val;
65*4882a593Smuzhiyun 	msg[1].len = 1;
66*4882a593Smuzhiyun 	ret = dm_i2c_xfer(dev, msg, 2);
67*4882a593Smuzhiyun 	if (ret) {
68*4882a593Smuzhiyun 		debug("%s: read failed, reg=%.2x, value=%p, ret=%d\n",
69*4882a593Smuzhiyun 		      __func__, (int)reg_addr, value, ret);
70*4882a593Smuzhiyun 		return ret;
71*4882a593Smuzhiyun 	}
72*4882a593Smuzhiyun 	*value = val;
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun 	return 0;
75*4882a593Smuzhiyun }
76*4882a593Smuzhiyun 
anx6345_write_r0(struct udevice * dev,unsigned char reg_addr,unsigned char value)77*4882a593Smuzhiyun static int anx6345_write_r0(struct udevice *dev, unsigned char reg_addr,
78*4882a593Smuzhiyun 			    unsigned char value)
79*4882a593Smuzhiyun {
80*4882a593Smuzhiyun 	struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun 	return anx6345_write(dev, chip->chip_addr, reg_addr, value);
83*4882a593Smuzhiyun }
84*4882a593Smuzhiyun 
anx6345_read_r0(struct udevice * dev,unsigned char reg_addr,unsigned char * value)85*4882a593Smuzhiyun static int anx6345_read_r0(struct udevice *dev, unsigned char reg_addr,
86*4882a593Smuzhiyun 			   unsigned char *value)
87*4882a593Smuzhiyun {
88*4882a593Smuzhiyun 	struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun 	return anx6345_read(dev, chip->chip_addr, reg_addr, value);
91*4882a593Smuzhiyun }
92*4882a593Smuzhiyun 
anx6345_write_r1(struct udevice * dev,unsigned char reg_addr,unsigned char value)93*4882a593Smuzhiyun static int anx6345_write_r1(struct udevice *dev, unsigned char reg_addr,
94*4882a593Smuzhiyun 			    unsigned char value)
95*4882a593Smuzhiyun {
96*4882a593Smuzhiyun 	struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun 	return anx6345_write(dev, chip->chip_addr + 1, reg_addr, value);
99*4882a593Smuzhiyun }
100*4882a593Smuzhiyun 
anx6345_read_r1(struct udevice * dev,unsigned char reg_addr,unsigned char * value)101*4882a593Smuzhiyun static int anx6345_read_r1(struct udevice *dev, unsigned char reg_addr,
102*4882a593Smuzhiyun 			   unsigned char *value)
103*4882a593Smuzhiyun {
104*4882a593Smuzhiyun 	struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun 	return anx6345_read(dev, chip->chip_addr + 1, reg_addr, value);
107*4882a593Smuzhiyun }
108*4882a593Smuzhiyun 
anx6345_set_backlight(struct udevice * dev,int percent)109*4882a593Smuzhiyun static int anx6345_set_backlight(struct udevice *dev, int percent)
110*4882a593Smuzhiyun {
111*4882a593Smuzhiyun 	return -ENOSYS;
112*4882a593Smuzhiyun }
113*4882a593Smuzhiyun 
anx6345_aux_wait(struct udevice * dev)114*4882a593Smuzhiyun static int anx6345_aux_wait(struct udevice *dev)
115*4882a593Smuzhiyun {
116*4882a593Smuzhiyun 	int ret = -ETIMEDOUT;
117*4882a593Smuzhiyun 	u8 v;
118*4882a593Smuzhiyun 	int retries = 1000;
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun 	do {
121*4882a593Smuzhiyun 		anx6345_read_r0(dev, ANX9804_DP_AUX_CH_CTL_2, &v);
122*4882a593Smuzhiyun 		if (!(v & ANX9804_AUX_EN)) {
123*4882a593Smuzhiyun 			ret = 0;
124*4882a593Smuzhiyun 			break;
125*4882a593Smuzhiyun 		}
126*4882a593Smuzhiyun 		udelay(100);
127*4882a593Smuzhiyun 	} while (retries--);
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun 	if (ret) {
130*4882a593Smuzhiyun 		debug("%s: timed out waiting for AUX_EN to clear\n", __func__);
131*4882a593Smuzhiyun 		return ret;
132*4882a593Smuzhiyun 	}
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun 	ret = -ETIMEDOUT;
135*4882a593Smuzhiyun 	retries = 1000;
136*4882a593Smuzhiyun 	do {
137*4882a593Smuzhiyun 		anx6345_read_r1(dev, ANX9804_DP_INT_STA, &v);
138*4882a593Smuzhiyun 		if (v & ANX9804_RPLY_RECEIV) {
139*4882a593Smuzhiyun 			ret = 0;
140*4882a593Smuzhiyun 			break;
141*4882a593Smuzhiyun 		}
142*4882a593Smuzhiyun 		udelay(100);
143*4882a593Smuzhiyun 	} while (retries--);
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun 	if (ret) {
146*4882a593Smuzhiyun 		debug("%s: timed out waiting to receive reply\n", __func__);
147*4882a593Smuzhiyun 		return ret;
148*4882a593Smuzhiyun 	}
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun 	/* Clear RPLY_RECEIV bit */
151*4882a593Smuzhiyun 	anx6345_write_r1(dev, ANX9804_DP_INT_STA, v);
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun 	anx6345_read_r0(dev, ANX9804_AUX_CH_STA, &v);
154*4882a593Smuzhiyun 	if ((v & ANX9804_AUX_STATUS_MASK) != 0) {
155*4882a593Smuzhiyun 		debug("AUX status: %d\n", v & ANX9804_AUX_STATUS_MASK);
156*4882a593Smuzhiyun 		ret = -EIO;
157*4882a593Smuzhiyun 	}
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun 	return ret;
160*4882a593Smuzhiyun }
161*4882a593Smuzhiyun 
anx6345_aux_addr(struct udevice * dev,u32 addr)162*4882a593Smuzhiyun static void anx6345_aux_addr(struct udevice *dev, u32 addr)
163*4882a593Smuzhiyun {
164*4882a593Smuzhiyun 	u8 val;
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun 	val = addr & 0xff;
167*4882a593Smuzhiyun 	anx6345_write_r0(dev, ANX9804_DP_AUX_ADDR_7_0, val);
168*4882a593Smuzhiyun 	val = (addr >> 8) & 0xff;
169*4882a593Smuzhiyun 	anx6345_write_r0(dev, ANX9804_DP_AUX_ADDR_15_8, val);
170*4882a593Smuzhiyun 	val = (addr >> 16) & 0x0f;
171*4882a593Smuzhiyun 	anx6345_write_r0(dev, ANX9804_DP_AUX_ADDR_19_16, val);
172*4882a593Smuzhiyun }
173*4882a593Smuzhiyun 
anx6345_aux_transfer(struct udevice * dev,u8 req,u32 addr,u8 * buf,size_t len)174*4882a593Smuzhiyun static int anx6345_aux_transfer(struct udevice *dev, u8 req,
175*4882a593Smuzhiyun 				u32 addr, u8 *buf, size_t len)
176*4882a593Smuzhiyun {
177*4882a593Smuzhiyun 	int i, ret;
178*4882a593Smuzhiyun 	u8 ctrl1 = req;
179*4882a593Smuzhiyun 	u8 ctrl2 = ANX9804_AUX_EN;
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun 	if (len > 16)
182*4882a593Smuzhiyun 		return -E2BIG;
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun 	if (len)
185*4882a593Smuzhiyun 		ctrl1 |= ANX9804_AUX_LENGTH(len);
186*4882a593Smuzhiyun 	else
187*4882a593Smuzhiyun 		ctrl2 |= ANX9804_ADDR_ONLY;
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun 	if (len && !(req & ANX9804_AUX_TX_COMM_READ)) {
190*4882a593Smuzhiyun 		for (i = 0; i < len; i++)
191*4882a593Smuzhiyun 			anx6345_write_r0(dev, ANX9804_BUF_DATA_0 + i, buf[i]);
192*4882a593Smuzhiyun 	}
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun 	anx6345_aux_addr(dev, addr);
195*4882a593Smuzhiyun 	anx6345_write_r0(dev, ANX9804_DP_AUX_CH_CTL_1, ctrl1);
196*4882a593Smuzhiyun 	anx6345_write_r0(dev, ANX9804_DP_AUX_CH_CTL_2, ctrl2);
197*4882a593Smuzhiyun 	ret = anx6345_aux_wait(dev);
198*4882a593Smuzhiyun 	if (ret) {
199*4882a593Smuzhiyun 		debug("AUX transaction timed out\n");
200*4882a593Smuzhiyun 		return ret;
201*4882a593Smuzhiyun 	}
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun 	if (len && (req & ANX9804_AUX_TX_COMM_READ)) {
204*4882a593Smuzhiyun 		for (i = 0; i < len; i++)
205*4882a593Smuzhiyun 			anx6345_read_r0(dev, ANX9804_BUF_DATA_0 + i, &buf[i]);
206*4882a593Smuzhiyun 	}
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun 	return 0;
209*4882a593Smuzhiyun }
210*4882a593Smuzhiyun 
anx6345_read_aux_i2c(struct udevice * dev,u8 chip_addr,u8 offset,size_t count,u8 * buf)211*4882a593Smuzhiyun static int anx6345_read_aux_i2c(struct udevice *dev, u8 chip_addr,
212*4882a593Smuzhiyun 				u8 offset, size_t count, u8 *buf)
213*4882a593Smuzhiyun {
214*4882a593Smuzhiyun 	int i, ret;
215*4882a593Smuzhiyun 	size_t cur_cnt;
216*4882a593Smuzhiyun 	u8 cur_offset;
217*4882a593Smuzhiyun 
218*4882a593Smuzhiyun 	for (i = 0; i < count; i += 16) {
219*4882a593Smuzhiyun 		cur_cnt = (count - i) > 16 ? 16 : count - i;
220*4882a593Smuzhiyun 		cur_offset = offset + i;
221*4882a593Smuzhiyun 		ret = anx6345_aux_transfer(dev, ANX9804_AUX_TX_COMM_MOT,
222*4882a593Smuzhiyun 					   chip_addr, &cur_offset, 1);
223*4882a593Smuzhiyun 		if (ret) {
224*4882a593Smuzhiyun 			debug("%s: failed to set i2c offset: %d\n",
225*4882a593Smuzhiyun 			      __func__, ret);
226*4882a593Smuzhiyun 			return ret;
227*4882a593Smuzhiyun 		}
228*4882a593Smuzhiyun 		ret = anx6345_aux_transfer(dev, ANX9804_AUX_TX_COMM_READ,
229*4882a593Smuzhiyun 					   chip_addr, buf + i, cur_cnt);
230*4882a593Smuzhiyun 		if (ret) {
231*4882a593Smuzhiyun 			debug("%s: failed to read from i2c device: %d\n",
232*4882a593Smuzhiyun 			      __func__, ret);
233*4882a593Smuzhiyun 			return ret;
234*4882a593Smuzhiyun 		}
235*4882a593Smuzhiyun 	}
236*4882a593Smuzhiyun 
237*4882a593Smuzhiyun 	return 0;
238*4882a593Smuzhiyun }
239*4882a593Smuzhiyun 
anx6345_read_dpcd(struct udevice * dev,u32 reg,u8 * val)240*4882a593Smuzhiyun static int anx6345_read_dpcd(struct udevice *dev, u32 reg, u8 *val)
241*4882a593Smuzhiyun {
242*4882a593Smuzhiyun 	int ret;
243*4882a593Smuzhiyun 
244*4882a593Smuzhiyun 	ret = anx6345_aux_transfer(dev,
245*4882a593Smuzhiyun 				   ANX9804_AUX_TX_COMM_READ |
246*4882a593Smuzhiyun 				   ANX9804_AUX_TX_COMM_DP_TRANSACTION,
247*4882a593Smuzhiyun 				   reg, val, 1);
248*4882a593Smuzhiyun 	if (ret) {
249*4882a593Smuzhiyun 		debug("Failed to read DPCD\n");
250*4882a593Smuzhiyun 		return ret;
251*4882a593Smuzhiyun 	}
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun 	return 0;
254*4882a593Smuzhiyun }
255*4882a593Smuzhiyun 
anx6345_read_edid(struct udevice * dev,u8 * buf,int size)256*4882a593Smuzhiyun static int anx6345_read_edid(struct udevice *dev, u8 *buf, int size)
257*4882a593Smuzhiyun {
258*4882a593Smuzhiyun 	struct anx6345_priv *priv = dev_get_priv(dev);
259*4882a593Smuzhiyun 	int ret;
260*4882a593Smuzhiyun 
261*4882a593Smuzhiyun 	ret = anx6345_read_aux_i2c(dev, 0x50, 0x0, EDID_SIZE, priv->edid);
262*4882a593Smuzhiyun 	if (ret < 0) {
263*4882a593Smuzhiyun 		dev_err(dev, "failed to get edid\n");
264*4882a593Smuzhiyun 		return ret;
265*4882a593Smuzhiyun 	}
266*4882a593Smuzhiyun 
267*4882a593Smuzhiyun 	if (size > EDID_SIZE)
268*4882a593Smuzhiyun 		size = EDID_SIZE;
269*4882a593Smuzhiyun 	memcpy(buf, priv->edid, size);
270*4882a593Smuzhiyun 
271*4882a593Smuzhiyun 	return size;
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun 
anx6345_attach(struct udevice * dev)274*4882a593Smuzhiyun static int anx6345_attach(struct udevice *dev)
275*4882a593Smuzhiyun {
276*4882a593Smuzhiyun 	/* No-op */
277*4882a593Smuzhiyun 	return 0;
278*4882a593Smuzhiyun }
279*4882a593Smuzhiyun 
anx6345_init(struct udevice * dev)280*4882a593Smuzhiyun static int anx6345_init(struct udevice *dev)
281*4882a593Smuzhiyun {
282*4882a593Smuzhiyun 	struct anx6345_priv *priv = dev_get_priv(dev);
283*4882a593Smuzhiyun 	u8 c;
284*4882a593Smuzhiyun 	int ret, i;
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun 	/* Deassert reset and enable power */
287*4882a593Smuzhiyun 	ret = video_bridge_set_active(dev, true);
288*4882a593Smuzhiyun 	if (ret)
289*4882a593Smuzhiyun 		return ret;
290*4882a593Smuzhiyun 
291*4882a593Smuzhiyun 	/* Reset */
292*4882a593Smuzhiyun 	anx6345_write_r1(dev, ANX9804_RST_CTRL_REG, 1);
293*4882a593Smuzhiyun 	mdelay(100);
294*4882a593Smuzhiyun 	anx6345_write_r1(dev, ANX9804_RST_CTRL_REG, 0);
295*4882a593Smuzhiyun 
296*4882a593Smuzhiyun 	/* Write 0 to the powerdown reg (powerup everything) */
297*4882a593Smuzhiyun 	anx6345_write_r1(dev, ANX9804_POWERD_CTRL_REG, 0);
298*4882a593Smuzhiyun 
299*4882a593Smuzhiyun 	ret = anx6345_read_r1(dev, ANX9804_DEV_IDH_REG, &priv->chipid);
300*4882a593Smuzhiyun 	if (ret)
301*4882a593Smuzhiyun 		debug("%s: read id failed: %d\n", __func__, ret);
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun 	switch (priv->chipid) {
304*4882a593Smuzhiyun 	case 0x63:
305*4882a593Smuzhiyun 		debug("ANX63xx detected.\n");
306*4882a593Smuzhiyun 		break;
307*4882a593Smuzhiyun 	default:
308*4882a593Smuzhiyun 		debug("Error anx6345 chipid mismatch: %.2x\n", priv->chipid);
309*4882a593Smuzhiyun 		return -ENODEV;
310*4882a593Smuzhiyun 	}
311*4882a593Smuzhiyun 
312*4882a593Smuzhiyun 	for (i = 0; i < 100; i++) {
313*4882a593Smuzhiyun 		anx6345_read_r0(dev, ANX9804_SYS_CTRL2_REG, &c);
314*4882a593Smuzhiyun 		anx6345_write_r0(dev, ANX9804_SYS_CTRL2_REG, c);
315*4882a593Smuzhiyun 		anx6345_read_r0(dev, ANX9804_SYS_CTRL2_REG, &c);
316*4882a593Smuzhiyun 		if ((c & ANX9804_SYS_CTRL2_CHA_STA) == 0)
317*4882a593Smuzhiyun 			break;
318*4882a593Smuzhiyun 
319*4882a593Smuzhiyun 		mdelay(5);
320*4882a593Smuzhiyun 	}
321*4882a593Smuzhiyun 	if (i == 100)
322*4882a593Smuzhiyun 		debug("Error anx6345 clock is not stable\n");
323*4882a593Smuzhiyun 
324*4882a593Smuzhiyun 	/* Set a bunch of analog related register values */
325*4882a593Smuzhiyun 	anx6345_write_r0(dev, ANX9804_PLL_CTRL_REG, 0x00);
326*4882a593Smuzhiyun 	anx6345_write_r1(dev, ANX9804_ANALOG_DEBUG_REG1, 0x70);
327*4882a593Smuzhiyun 	anx6345_write_r0(dev, ANX9804_LINK_DEBUG_REG, 0x30);
328*4882a593Smuzhiyun 
329*4882a593Smuzhiyun 	/* Force HPD */
330*4882a593Smuzhiyun 	anx6345_write_r0(dev, ANX9804_SYS_CTRL3_REG,
331*4882a593Smuzhiyun 			 ANX9804_SYS_CTRL3_F_HPD | ANX9804_SYS_CTRL3_HPD_CTRL);
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun 	/* Power up and configure lanes */
334*4882a593Smuzhiyun 	anx6345_write_r0(dev, ANX9804_ANALOG_POWER_DOWN_REG, 0x00);
335*4882a593Smuzhiyun 	anx6345_write_r0(dev, ANX9804_TRAINING_LANE0_SET_REG, 0x00);
336*4882a593Smuzhiyun 	anx6345_write_r0(dev, ANX9804_TRAINING_LANE1_SET_REG, 0x00);
337*4882a593Smuzhiyun 	anx6345_write_r0(dev, ANX9804_TRAINING_LANE2_SET_REG, 0x00);
338*4882a593Smuzhiyun 	anx6345_write_r0(dev, ANX9804_TRAINING_LANE3_SET_REG, 0x00);
339*4882a593Smuzhiyun 
340*4882a593Smuzhiyun 	/* Reset AUX CH */
341*4882a593Smuzhiyun 	anx6345_write_r1(dev, ANX9804_RST_CTRL2_REG,
342*4882a593Smuzhiyun 			 ANX9804_RST_CTRL2_AUX);
343*4882a593Smuzhiyun 	anx6345_write_r1(dev, ANX9804_RST_CTRL2_REG, 0);
344*4882a593Smuzhiyun 
345*4882a593Smuzhiyun 	/* Powerdown audio and some other unused bits */
346*4882a593Smuzhiyun 	anx6345_write_r1(dev, ANX9804_POWERD_CTRL_REG, ANX9804_POWERD_AUDIO);
347*4882a593Smuzhiyun 	anx6345_write_r0(dev, ANX9804_HDCP_CONTROL_0_REG, 0x00);
348*4882a593Smuzhiyun 	anx6345_write_r0(dev, 0xa7, 0x00);
349*4882a593Smuzhiyun 
350*4882a593Smuzhiyun 	return 0;
351*4882a593Smuzhiyun }
352*4882a593Smuzhiyun 
anx6345_enable(struct udevice * dev)353*4882a593Smuzhiyun static int anx6345_enable(struct udevice *dev)
354*4882a593Smuzhiyun {
355*4882a593Smuzhiyun 	u8 colordepth, lanes, data_rate, c;
356*4882a593Smuzhiyun 	int i, bpp;
357*4882a593Smuzhiyun 	struct display_timing timing;
358*4882a593Smuzhiyun 	struct anx6345_priv *priv = dev_get_priv(dev);
359*4882a593Smuzhiyun 
360*4882a593Smuzhiyun 	if (edid_get_timing(priv->edid, EDID_SIZE, &timing, &bpp) != 0) {
361*4882a593Smuzhiyun 		debug("Failed to parse EDID\n");
362*4882a593Smuzhiyun 		return -EIO;
363*4882a593Smuzhiyun 	}
364*4882a593Smuzhiyun 	debug("%s: panel found: %dx%d, bpp %d\n", __func__,
365*4882a593Smuzhiyun 	      timing.hactive.typ, timing.vactive.typ, bpp);
366*4882a593Smuzhiyun 	if (bpp == 6)
367*4882a593Smuzhiyun 		colordepth = 0x00; /* 6 bit */
368*4882a593Smuzhiyun 	else
369*4882a593Smuzhiyun 		colordepth = 0x10; /* 8 bit */
370*4882a593Smuzhiyun 	anx6345_write_r1(dev, ANX9804_VID_CTRL2_REG, colordepth);
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun 	if (anx6345_read_dpcd(dev, DP_MAX_LINK_RATE, &data_rate)) {
373*4882a593Smuzhiyun 		debug("%s: Failed to DP_MAX_LINK_RATE\n", __func__);
374*4882a593Smuzhiyun 		return -EIO;
375*4882a593Smuzhiyun 	}
376*4882a593Smuzhiyun 	debug("%s: data_rate: %d\n", __func__, (int)data_rate);
377*4882a593Smuzhiyun 	if (anx6345_read_dpcd(dev, DP_MAX_LANE_COUNT, &lanes)) {
378*4882a593Smuzhiyun 		debug("%s: Failed to read DP_MAX_LANE_COUNT\n", __func__);
379*4882a593Smuzhiyun 		return -EIO;
380*4882a593Smuzhiyun 	}
381*4882a593Smuzhiyun 	lanes &= DP_MAX_LANE_COUNT_MASK;
382*4882a593Smuzhiyun 	debug("%s: lanes: %d\n", __func__, (int)lanes);
383*4882a593Smuzhiyun 
384*4882a593Smuzhiyun 	/* Set data-rate / lanes */
385*4882a593Smuzhiyun 	anx6345_write_r0(dev, ANX9804_LINK_BW_SET_REG, data_rate);
386*4882a593Smuzhiyun 	anx6345_write_r0(dev, ANX9804_LANE_COUNT_SET_REG, lanes);
387*4882a593Smuzhiyun 
388*4882a593Smuzhiyun 	/* Link training */
389*4882a593Smuzhiyun 	anx6345_write_r0(dev, ANX9804_LINK_TRAINING_CTRL_REG,
390*4882a593Smuzhiyun 			 ANX9804_LINK_TRAINING_CTRL_EN);
391*4882a593Smuzhiyun 	mdelay(5);
392*4882a593Smuzhiyun 	for (i = 0; i < 100; i++) {
393*4882a593Smuzhiyun 		anx6345_read_r0(dev, ANX9804_LINK_TRAINING_CTRL_REG, &c);
394*4882a593Smuzhiyun 		if ((priv->chipid == 0x63) && (c & 0x80) == 0)
395*4882a593Smuzhiyun 			break;
396*4882a593Smuzhiyun 
397*4882a593Smuzhiyun 		mdelay(5);
398*4882a593Smuzhiyun 	}
399*4882a593Smuzhiyun 	if (i == 100) {
400*4882a593Smuzhiyun 		debug("Error anx6345 link training timeout\n");
401*4882a593Smuzhiyun 		return -ENODEV;
402*4882a593Smuzhiyun 	}
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun 	/* Enable */
405*4882a593Smuzhiyun 	anx6345_write_r1(dev, ANX9804_VID_CTRL1_REG, ANX9804_VID_CTRL1_VID_EN |
406*4882a593Smuzhiyun 			 ANX9804_VID_CTRL1_DDR_CTRL | ANX9804_VID_CTRL1_EDGE);
407*4882a593Smuzhiyun 	/* Force stream valid */
408*4882a593Smuzhiyun 	anx6345_write_r0(dev, ANX9804_SYS_CTRL3_REG,
409*4882a593Smuzhiyun 			 ANX9804_SYS_CTRL3_F_HPD |
410*4882a593Smuzhiyun 			 ANX9804_SYS_CTRL3_HPD_CTRL |
411*4882a593Smuzhiyun 			 ANX9804_SYS_CTRL3_F_VALID |
412*4882a593Smuzhiyun 			 ANX9804_SYS_CTRL3_VALID_CTRL);
413*4882a593Smuzhiyun 
414*4882a593Smuzhiyun 	return 0;
415*4882a593Smuzhiyun }
416*4882a593Smuzhiyun 
anx6345_probe(struct udevice * dev)417*4882a593Smuzhiyun static int anx6345_probe(struct udevice *dev)
418*4882a593Smuzhiyun {
419*4882a593Smuzhiyun 	struct rockchip_bridge *bridge =
420*4882a593Smuzhiyun 		(struct rockchip_bridge *)dev_get_driver_data(dev);
421*4882a593Smuzhiyun 
422*4882a593Smuzhiyun 	if (device_get_uclass_id(dev->parent) != UCLASS_I2C)
423*4882a593Smuzhiyun 		return -EPROTONOSUPPORT;
424*4882a593Smuzhiyun 
425*4882a593Smuzhiyun 	bridge->dev = dev;
426*4882a593Smuzhiyun 
427*4882a593Smuzhiyun 	return anx6345_init(dev);
428*4882a593Smuzhiyun }
429*4882a593Smuzhiyun 
430*4882a593Smuzhiyun static const struct video_bridge_ops anx6345_ops = {
431*4882a593Smuzhiyun 	.attach = anx6345_attach,
432*4882a593Smuzhiyun 	.set_backlight = anx6345_set_backlight,
433*4882a593Smuzhiyun 	.read_edid = anx6345_read_edid,
434*4882a593Smuzhiyun };
435*4882a593Smuzhiyun 
anx6345_bridge_enable(struct rockchip_bridge * bridge)436*4882a593Smuzhiyun static void anx6345_bridge_enable(struct rockchip_bridge *bridge)
437*4882a593Smuzhiyun {
438*4882a593Smuzhiyun 	anx6345_enable(bridge->dev);
439*4882a593Smuzhiyun }
440*4882a593Smuzhiyun 
441*4882a593Smuzhiyun static const struct rockchip_bridge_funcs anx6345_bridge_funcs = {
442*4882a593Smuzhiyun 	.enable = anx6345_bridge_enable,
443*4882a593Smuzhiyun };
444*4882a593Smuzhiyun 
445*4882a593Smuzhiyun static struct rockchip_bridge anx6345_driver_data = {
446*4882a593Smuzhiyun 	.funcs = &anx6345_bridge_funcs,
447*4882a593Smuzhiyun };
448*4882a593Smuzhiyun 
449*4882a593Smuzhiyun static const struct udevice_id anx6345_ids[] = {
450*4882a593Smuzhiyun 	{
451*4882a593Smuzhiyun 		.compatible = "analogix,anx6345",
452*4882a593Smuzhiyun 		.data = (ulong)&anx6345_driver_data, },
453*4882a593Smuzhiyun 	{ }
454*4882a593Smuzhiyun };
455*4882a593Smuzhiyun 
456*4882a593Smuzhiyun U_BOOT_DRIVER(analogix_anx6345) = {
457*4882a593Smuzhiyun 	.name	= "analogix_anx6345",
458*4882a593Smuzhiyun 	.id	= UCLASS_VIDEO_BRIDGE,
459*4882a593Smuzhiyun 	.of_match = anx6345_ids,
460*4882a593Smuzhiyun 	.probe	= anx6345_probe,
461*4882a593Smuzhiyun 	.ops	= &anx6345_ops,
462*4882a593Smuzhiyun 	.priv_auto_alloc_size = sizeof(struct anx6345_priv),
463*4882a593Smuzhiyun };
464