xref: /rk3399_rockchip-uboot/board/freescale/common/diu_ch7301.c (revision 67ee22b0681305ba1099c508eecade996abc1c65)
1*c53711bbSWang Dongsheng /*
2*c53711bbSWang Dongsheng  * Copyright 2014 Freescale Semiconductor, Inc.
3*c53711bbSWang Dongsheng  * Authors: Priyanka Jain <Priyanka.Jain@freescale.com>
4*c53711bbSWang Dongsheng  *	    Wang Dongsheng <dongsheng.wang@freescale.com>
5*c53711bbSWang Dongsheng  *
6*c53711bbSWang Dongsheng  * This file is copied and modified from the original t1040qds/diu.c.
7*c53711bbSWang Dongsheng  * Encoder can be used in T104x and LSx Platform.
8*c53711bbSWang Dongsheng  *
9*c53711bbSWang Dongsheng  * SPDX-License-Identifier:	GPL-2.0+
10*c53711bbSWang Dongsheng  */
11*c53711bbSWang Dongsheng 
12*c53711bbSWang Dongsheng #include <common.h>
13*c53711bbSWang Dongsheng #include <stdio_dev.h>
14*c53711bbSWang Dongsheng #include <i2c.h>
15*c53711bbSWang Dongsheng 
16*c53711bbSWang Dongsheng #define I2C_DVI_INPUT_DATA_FORMAT_REG		0x1F
17*c53711bbSWang Dongsheng #define I2C_DVI_PLL_CHARGE_CNTL_REG		0x33
18*c53711bbSWang Dongsheng #define I2C_DVI_PLL_DIVIDER_REG			0x34
19*c53711bbSWang Dongsheng #define I2C_DVI_PLL_SUPPLY_CNTL_REG		0x35
20*c53711bbSWang Dongsheng #define I2C_DVI_PLL_FILTER_REG			0x36
21*c53711bbSWang Dongsheng #define I2C_DVI_TEST_PATTERN_REG		0x48
22*c53711bbSWang Dongsheng #define I2C_DVI_POWER_MGMT_REG			0x49
23*c53711bbSWang Dongsheng #define I2C_DVI_LOCK_STATE_REG			0x4D
24*c53711bbSWang Dongsheng #define I2C_DVI_SYNC_POLARITY_REG		0x56
25*c53711bbSWang Dongsheng 
26*c53711bbSWang Dongsheng /*
27*c53711bbSWang Dongsheng  * Set VSYNC/HSYNC to active high. This is polarity of sync signals
28*c53711bbSWang Dongsheng  * from DIU->DVI. The DIU default is active igh, so DVI is set to
29*c53711bbSWang Dongsheng  * active high.
30*c53711bbSWang Dongsheng  */
31*c53711bbSWang Dongsheng #define I2C_DVI_INPUT_DATA_FORMAT_VAL		0x98
32*c53711bbSWang Dongsheng 
33*c53711bbSWang Dongsheng #define I2C_DVI_PLL_CHARGE_CNTL_HIGH_SPEED_VAL	0x06
34*c53711bbSWang Dongsheng #define I2C_DVI_PLL_DIVIDER_HIGH_SPEED_VAL	0x26
35*c53711bbSWang Dongsheng #define I2C_DVI_PLL_FILTER_HIGH_SPEED_VAL	0xA0
36*c53711bbSWang Dongsheng #define I2C_DVI_PLL_CHARGE_CNTL_LOW_SPEED_VAL	0x08
37*c53711bbSWang Dongsheng #define I2C_DVI_PLL_DIVIDER_LOW_SPEED_VAL	0x16
38*c53711bbSWang Dongsheng #define I2C_DVI_PLL_FILTER_LOW_SPEED_VAL	0x60
39*c53711bbSWang Dongsheng 
40*c53711bbSWang Dongsheng /* Clear test pattern */
41*c53711bbSWang Dongsheng #define I2C_DVI_TEST_PATTERN_VAL		0x18
42*c53711bbSWang Dongsheng /* Exit Power-down mode */
43*c53711bbSWang Dongsheng #define I2C_DVI_POWER_MGMT_VAL			0xC0
44*c53711bbSWang Dongsheng 
45*c53711bbSWang Dongsheng /* Monitor polarity is handled via DVI Sync Polarity Register */
46*c53711bbSWang Dongsheng #define I2C_DVI_SYNC_POLARITY_VAL		0x00
47*c53711bbSWang Dongsheng 
48*c53711bbSWang Dongsheng /* Programming of HDMI Chrontel CH7301 connector */
diu_set_dvi_encoder(unsigned int pixclock)49*c53711bbSWang Dongsheng int diu_set_dvi_encoder(unsigned int pixclock)
50*c53711bbSWang Dongsheng {
51*c53711bbSWang Dongsheng 	int ret;
52*c53711bbSWang Dongsheng 	u8 temp;
53*c53711bbSWang Dongsheng 
54*c53711bbSWang Dongsheng 	temp = I2C_DVI_TEST_PATTERN_VAL;
55*c53711bbSWang Dongsheng 	ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, I2C_DVI_TEST_PATTERN_REG, 1,
56*c53711bbSWang Dongsheng 			&temp, 1);
57*c53711bbSWang Dongsheng 	if (ret) {
58*c53711bbSWang Dongsheng 		puts("I2C: failed to select proper dvi test pattern\n");
59*c53711bbSWang Dongsheng 		return ret;
60*c53711bbSWang Dongsheng 	}
61*c53711bbSWang Dongsheng 	temp = I2C_DVI_INPUT_DATA_FORMAT_VAL;
62*c53711bbSWang Dongsheng 	ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, I2C_DVI_INPUT_DATA_FORMAT_REG,
63*c53711bbSWang Dongsheng 			1, &temp, 1);
64*c53711bbSWang Dongsheng 	if (ret) {
65*c53711bbSWang Dongsheng 		puts("I2C: failed to select dvi input data format\n");
66*c53711bbSWang Dongsheng 		return ret;
67*c53711bbSWang Dongsheng 	}
68*c53711bbSWang Dongsheng 
69*c53711bbSWang Dongsheng 	/* Set Sync polarity register */
70*c53711bbSWang Dongsheng 	temp = I2C_DVI_SYNC_POLARITY_VAL;
71*c53711bbSWang Dongsheng 	ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, I2C_DVI_SYNC_POLARITY_REG, 1,
72*c53711bbSWang Dongsheng 			&temp, 1);
73*c53711bbSWang Dongsheng 	if (ret) {
74*c53711bbSWang Dongsheng 		puts("I2C: failed to select dvi syc polarity\n");
75*c53711bbSWang Dongsheng 		return ret;
76*c53711bbSWang Dongsheng 	}
77*c53711bbSWang Dongsheng 
78*c53711bbSWang Dongsheng 	/* Set PLL registers based on pixel clock rate*/
79*c53711bbSWang Dongsheng 	if (pixclock > 65000000) {
80*c53711bbSWang Dongsheng 		temp = I2C_DVI_PLL_CHARGE_CNTL_HIGH_SPEED_VAL;
81*c53711bbSWang Dongsheng 		ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
82*c53711bbSWang Dongsheng 				I2C_DVI_PLL_CHARGE_CNTL_REG, 1,	&temp, 1);
83*c53711bbSWang Dongsheng 		if (ret) {
84*c53711bbSWang Dongsheng 			puts("I2C: failed to select dvi pll charge_cntl\n");
85*c53711bbSWang Dongsheng 			return ret;
86*c53711bbSWang Dongsheng 		}
87*c53711bbSWang Dongsheng 		temp = I2C_DVI_PLL_DIVIDER_HIGH_SPEED_VAL;
88*c53711bbSWang Dongsheng 		ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
89*c53711bbSWang Dongsheng 				I2C_DVI_PLL_DIVIDER_REG, 1, &temp, 1);
90*c53711bbSWang Dongsheng 		if (ret) {
91*c53711bbSWang Dongsheng 			puts("I2C: failed to select dvi pll divider\n");
92*c53711bbSWang Dongsheng 			return ret;
93*c53711bbSWang Dongsheng 		}
94*c53711bbSWang Dongsheng 		temp = I2C_DVI_PLL_FILTER_HIGH_SPEED_VAL;
95*c53711bbSWang Dongsheng 		ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
96*c53711bbSWang Dongsheng 				I2C_DVI_PLL_FILTER_REG, 1, &temp, 1);
97*c53711bbSWang Dongsheng 		if (ret) {
98*c53711bbSWang Dongsheng 			puts("I2C: failed to select dvi pll filter\n");
99*c53711bbSWang Dongsheng 			return ret;
100*c53711bbSWang Dongsheng 		}
101*c53711bbSWang Dongsheng 	} else {
102*c53711bbSWang Dongsheng 		temp = I2C_DVI_PLL_CHARGE_CNTL_LOW_SPEED_VAL;
103*c53711bbSWang Dongsheng 		ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
104*c53711bbSWang Dongsheng 				I2C_DVI_PLL_CHARGE_CNTL_REG, 1, &temp, 1);
105*c53711bbSWang Dongsheng 		if (ret) {
106*c53711bbSWang Dongsheng 			puts("I2C: failed to select dvi pll charge_cntl\n");
107*c53711bbSWang Dongsheng 			return ret;
108*c53711bbSWang Dongsheng 		}
109*c53711bbSWang Dongsheng 		temp = I2C_DVI_PLL_DIVIDER_LOW_SPEED_VAL;
110*c53711bbSWang Dongsheng 		ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
111*c53711bbSWang Dongsheng 				I2C_DVI_PLL_DIVIDER_REG, 1, &temp, 1);
112*c53711bbSWang Dongsheng 		if (ret) {
113*c53711bbSWang Dongsheng 			puts("I2C: failed to select dvi pll divider\n");
114*c53711bbSWang Dongsheng 			return ret;
115*c53711bbSWang Dongsheng 		}
116*c53711bbSWang Dongsheng 		temp = I2C_DVI_PLL_FILTER_LOW_SPEED_VAL;
117*c53711bbSWang Dongsheng 		ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
118*c53711bbSWang Dongsheng 				I2C_DVI_PLL_FILTER_REG, 1, &temp, 1);
119*c53711bbSWang Dongsheng 		if (ret) {
120*c53711bbSWang Dongsheng 			puts("I2C: failed to select dvi pll filter\n");
121*c53711bbSWang Dongsheng 			return ret;
122*c53711bbSWang Dongsheng 		}
123*c53711bbSWang Dongsheng 	}
124*c53711bbSWang Dongsheng 
125*c53711bbSWang Dongsheng 	temp = I2C_DVI_POWER_MGMT_VAL;
126*c53711bbSWang Dongsheng 	ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, I2C_DVI_POWER_MGMT_REG, 1,
127*c53711bbSWang Dongsheng 			&temp, 1);
128*c53711bbSWang Dongsheng 	if (ret) {
129*c53711bbSWang Dongsheng 		puts("I2C: failed to select dvi power mgmt\n");
130*c53711bbSWang Dongsheng 		return ret;
131*c53711bbSWang Dongsheng 	}
132*c53711bbSWang Dongsheng 
133*c53711bbSWang Dongsheng 	udelay(500);
134*c53711bbSWang Dongsheng 
135*c53711bbSWang Dongsheng 	return 0;
136*c53711bbSWang Dongsheng }
137