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