blob: 7f11123e6f3ecdad5c34f80e8f45d48fdde281b0 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Wang Dongsheng9fdaa5c2014-03-19 10:47:55 +08002/*
3 * Copyright 2014 Freescale Semiconductor, Inc.
Biwen Lid15aa9f2019-12-31 15:33:44 +08004 * Copyright 2019 NXP
Wang Dongsheng9fdaa5c2014-03-19 10:47:55 +08005 * Authors: Priyanka Jain <Priyanka.Jain@freescale.com>
6 * Wang Dongsheng <dongsheng.wang@freescale.com>
7 *
8 * This file is copied and modified from the original t1040qds/diu.c.
9 * Encoder can be used in T104x and LSx Platform.
Wang Dongsheng9fdaa5c2014-03-19 10:47:55 +080010 */
11
12#include <common.h>
13#include <stdio_dev.h>
14#include <i2c.h>
15
16#define I2C_DVI_INPUT_DATA_FORMAT_REG 0x1F
17#define I2C_DVI_PLL_CHARGE_CNTL_REG 0x33
18#define I2C_DVI_PLL_DIVIDER_REG 0x34
19#define I2C_DVI_PLL_SUPPLY_CNTL_REG 0x35
20#define I2C_DVI_PLL_FILTER_REG 0x36
21#define I2C_DVI_TEST_PATTERN_REG 0x48
22#define I2C_DVI_POWER_MGMT_REG 0x49
23#define I2C_DVI_LOCK_STATE_REG 0x4D
24#define I2C_DVI_SYNC_POLARITY_REG 0x56
25
26/*
27 * Set VSYNC/HSYNC to active high. This is polarity of sync signals
28 * from DIU->DVI. The DIU default is active igh, so DVI is set to
29 * active high.
30 */
31#define I2C_DVI_INPUT_DATA_FORMAT_VAL 0x98
32
33#define I2C_DVI_PLL_CHARGE_CNTL_HIGH_SPEED_VAL 0x06
34#define I2C_DVI_PLL_DIVIDER_HIGH_SPEED_VAL 0x26
35#define I2C_DVI_PLL_FILTER_HIGH_SPEED_VAL 0xA0
36#define I2C_DVI_PLL_CHARGE_CNTL_LOW_SPEED_VAL 0x08
37#define I2C_DVI_PLL_DIVIDER_LOW_SPEED_VAL 0x16
38#define I2C_DVI_PLL_FILTER_LOW_SPEED_VAL 0x60
39
40/* Clear test pattern */
41#define I2C_DVI_TEST_PATTERN_VAL 0x18
42/* Exit Power-down mode */
43#define I2C_DVI_POWER_MGMT_VAL 0xC0
44
45/* Monitor polarity is handled via DVI Sync Polarity Register */
46#define I2C_DVI_SYNC_POLARITY_VAL 0x00
47
48/* Programming of HDMI Chrontel CH7301 connector */
49int diu_set_dvi_encoder(unsigned int pixclock)
50{
51 int ret;
52 u8 temp;
53
54 temp = I2C_DVI_TEST_PATTERN_VAL;
Biwen Lid15aa9f2019-12-31 15:33:44 +080055#ifdef CONFIG_DM_I2C
56 struct udevice *dev;
57
58 ret = i2c_get_chip_for_busnum(CONFIG_SYS_I2C_DVI_BUS_NUM,
59 CONFIG_SYS_I2C_DVI_ADDR,
60 1, &dev);
61 if (ret) {
62 printf("%s: Cannot find udev for a bus %d\n", __func__,
63 CONFIG_SYS_I2C_DVI_BUS_NUM);
64 return ret;
65 }
66 ret = dm_i2c_write(dev, I2C_DVI_TEST_PATTERN_REG, &temp, 1);
67 if (ret) {
68 puts("I2C: failed to select proper dvi test pattern\n");
69 return ret;
70 }
71 temp = I2C_DVI_INPUT_DATA_FORMAT_VAL;
72 ret = dm_i2c_write(dev, I2C_DVI_INPUT_DATA_FORMAT_REG, &temp, 1);
73 if (ret) {
74 puts("I2C: failed to select dvi input data format\n");
75 return ret;
76 }
77
78 /* Set Sync polarity register */
79 temp = I2C_DVI_SYNC_POLARITY_VAL;
80 ret = dm_i2c_write(dev, I2C_DVI_SYNC_POLARITY_REG, &temp, 1);
81 if (ret) {
82 puts("I2C: failed to select dvi syc polarity\n");
83 return ret;
84 }
85
86 /* Set PLL registers based on pixel clock rate*/
87 if (pixclock > 65000000) {
88 temp = I2C_DVI_PLL_CHARGE_CNTL_HIGH_SPEED_VAL;
89 ret = dm_i2c_write(dev, I2C_DVI_PLL_CHARGE_CNTL_REG, &temp, 1);
90 if (ret) {
91 puts("I2C: failed to select dvi pll charge_cntl\n");
92 return ret;
93 }
94 temp = I2C_DVI_PLL_DIVIDER_HIGH_SPEED_VAL;
95 ret = dm_i2c_write(dev, I2C_DVI_PLL_DIVIDER_REG, &temp, 1);
96 if (ret) {
97 puts("I2C: failed to select dvi pll divider\n");
98 return ret;
99 }
100 temp = I2C_DVI_PLL_FILTER_HIGH_SPEED_VAL;
101 ret = dm_i2c_write(dev, I2C_DVI_PLL_FILTER_REG, &temp, 1);
102 if (ret) {
103 puts("I2C: failed to select dvi pll filter\n");
104 return ret;
105 }
106 } else {
107 temp = I2C_DVI_PLL_CHARGE_CNTL_LOW_SPEED_VAL;
108 ret = dm_i2c_write(dev, I2C_DVI_PLL_CHARGE_CNTL_REG, &temp, 1);
109 if (ret) {
110 puts("I2C: failed to select dvi pll charge_cntl\n");
111 return ret;
112 }
113 temp = I2C_DVI_PLL_DIVIDER_LOW_SPEED_VAL;
114 ret = dm_i2c_write(dev, I2C_DVI_PLL_DIVIDER_REG, &temp, 1);
115 if (ret) {
116 puts("I2C: failed to select dvi pll divider\n");
117 return ret;
118 }
119 temp = I2C_DVI_PLL_FILTER_LOW_SPEED_VAL;
120 ret = dm_i2c_write(dev, I2C_DVI_PLL_FILTER_REG, &temp, 1);
121 if (ret) {
122 puts("I2C: failed to select dvi pll filter\n");
123 return ret;
124 }
125 }
126
127 temp = I2C_DVI_POWER_MGMT_VAL;
128 ret = dm_i2c_write(dev, I2C_DVI_POWER_MGMT_REG, &temp, 1);
129 if (ret) {
130 puts("I2C: failed to select dvi power mgmt\n");
131 return ret;
132 }
133#else
Wang Dongsheng9fdaa5c2014-03-19 10:47:55 +0800134 ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, I2C_DVI_TEST_PATTERN_REG, 1,
135 &temp, 1);
136 if (ret) {
137 puts("I2C: failed to select proper dvi test pattern\n");
138 return ret;
139 }
140 temp = I2C_DVI_INPUT_DATA_FORMAT_VAL;
141 ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, I2C_DVI_INPUT_DATA_FORMAT_REG,
142 1, &temp, 1);
143 if (ret) {
144 puts("I2C: failed to select dvi input data format\n");
145 return ret;
146 }
147
148 /* Set Sync polarity register */
149 temp = I2C_DVI_SYNC_POLARITY_VAL;
150 ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, I2C_DVI_SYNC_POLARITY_REG, 1,
151 &temp, 1);
152 if (ret) {
153 puts("I2C: failed to select dvi syc polarity\n");
154 return ret;
155 }
156
157 /* Set PLL registers based on pixel clock rate*/
158 if (pixclock > 65000000) {
159 temp = I2C_DVI_PLL_CHARGE_CNTL_HIGH_SPEED_VAL;
160 ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
161 I2C_DVI_PLL_CHARGE_CNTL_REG, 1, &temp, 1);
162 if (ret) {
163 puts("I2C: failed to select dvi pll charge_cntl\n");
164 return ret;
165 }
166 temp = I2C_DVI_PLL_DIVIDER_HIGH_SPEED_VAL;
167 ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
168 I2C_DVI_PLL_DIVIDER_REG, 1, &temp, 1);
169 if (ret) {
170 puts("I2C: failed to select dvi pll divider\n");
171 return ret;
172 }
173 temp = I2C_DVI_PLL_FILTER_HIGH_SPEED_VAL;
174 ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
175 I2C_DVI_PLL_FILTER_REG, 1, &temp, 1);
176 if (ret) {
177 puts("I2C: failed to select dvi pll filter\n");
178 return ret;
179 }
180 } else {
181 temp = I2C_DVI_PLL_CHARGE_CNTL_LOW_SPEED_VAL;
182 ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
183 I2C_DVI_PLL_CHARGE_CNTL_REG, 1, &temp, 1);
184 if (ret) {
185 puts("I2C: failed to select dvi pll charge_cntl\n");
186 return ret;
187 }
188 temp = I2C_DVI_PLL_DIVIDER_LOW_SPEED_VAL;
189 ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
190 I2C_DVI_PLL_DIVIDER_REG, 1, &temp, 1);
191 if (ret) {
192 puts("I2C: failed to select dvi pll divider\n");
193 return ret;
194 }
195 temp = I2C_DVI_PLL_FILTER_LOW_SPEED_VAL;
196 ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR,
197 I2C_DVI_PLL_FILTER_REG, 1, &temp, 1);
198 if (ret) {
199 puts("I2C: failed to select dvi pll filter\n");
200 return ret;
201 }
202 }
203
204 temp = I2C_DVI_POWER_MGMT_VAL;
205 ret = i2c_write(CONFIG_SYS_I2C_DVI_ADDR, I2C_DVI_POWER_MGMT_REG, 1,
206 &temp, 1);
207 if (ret) {
208 puts("I2C: failed to select dvi power mgmt\n");
209 return ret;
210 }
Biwen Lid15aa9f2019-12-31 15:33:44 +0800211#endif
Wang Dongsheng9fdaa5c2014-03-19 10:47:55 +0800212
213 udelay(500);
214
215 return 0;
216}