blob: 99a8683e63831abba56cd9cc246e5dfb1eadd6fe [file] [log] [blame]
Sudip Mukherjee81dee672015-03-03 16:21:06 +05301#define USE_DVICHIP
2#ifdef USE_DVICHIP
3
4#include "ddk750_sii164.h"
5#include "ddk750_hwi2c.h"
6
7/* I2C Address of each SII164 chip */
8#define SII164_I2C_ADDRESS 0x70
9
10/* Define this definition to use hardware i2c. */
11#define USE_HW_I2C
12
13#ifdef USE_HW_I2C
Mike Rapoport6bdbe622015-09-12 11:07:36 +030014 #define i2cWriteReg sm750_hw_i2c_write_reg
Mike Rapoport5ccf7342015-09-12 11:07:35 +030015 #define i2cReadReg sm750_hw_i2c_read_reg
Sudip Mukherjee81dee672015-03-03 16:21:06 +053016#else
Mike Rapoport9a357142016-01-17 20:04:22 +020017 #define i2cWriteReg sm750_sw_i2c_write_reg
18 #define i2cReadReg sm750_sw_i2c_read_reg
Sudip Mukherjee81dee672015-03-03 16:21:06 +053019#endif
20
21/* SII164 Vendor and Device ID */
22#define SII164_VENDOR_ID 0x0001
23#define SII164_DEVICE_ID 0x0006
24
25#ifdef SII164_FULL_FUNCTIONS
26/* Name of the DVI Controller chip */
27static char *gDviCtrlChipName = "Silicon Image SiI 164";
28#endif
29
30/*
31 * sii164GetVendorID
32 * This function gets the vendor ID of the DVI controller chip.
33 *
34 * Output:
35 * Vendor ID
36 */
Supriya Karanth6fa7db82015-03-12 01:11:00 +090037unsigned short sii164GetVendorID(void)
Sudip Mukherjee81dee672015-03-03 16:21:06 +053038{
Juston Li78376532015-07-14 21:14:30 -070039 unsigned short vendorID;
Sudip Mukherjee81dee672015-03-03 16:21:06 +053040
Juston Li78376532015-07-14 21:14:30 -070041 vendorID = ((unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_VENDOR_ID_HIGH) << 8) |
42 (unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_VENDOR_ID_LOW);
Sudip Mukherjee81dee672015-03-03 16:21:06 +053043
Juston Li78376532015-07-14 21:14:30 -070044 return vendorID;
Sudip Mukherjee81dee672015-03-03 16:21:06 +053045}
46
47/*
48 * sii164GetDeviceID
49 * This function gets the device ID of the DVI controller chip.
50 *
51 * Output:
52 * Device ID
53 */
Supriya Karanth6fa7db82015-03-12 01:11:00 +090054unsigned short sii164GetDeviceID(void)
Sudip Mukherjee81dee672015-03-03 16:21:06 +053055{
Juston Li78376532015-07-14 21:14:30 -070056 unsigned short deviceID;
Sudip Mukherjee81dee672015-03-03 16:21:06 +053057
Juston Li78376532015-07-14 21:14:30 -070058 deviceID = ((unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_DEVICE_ID_HIGH) << 8) |
59 (unsigned short) i2cReadReg(SII164_I2C_ADDRESS, SII164_DEVICE_ID_LOW);
Sudip Mukherjee81dee672015-03-03 16:21:06 +053060
Juston Li78376532015-07-14 21:14:30 -070061 return deviceID;
Sudip Mukherjee81dee672015-03-03 16:21:06 +053062}
63
64
65
66/* DVI.C will handle all SiI164 chip stuffs and try it best to make code minimal and useful */
67
68/*
69 * sii164InitChip
70 * This function initialize and detect the DVI controller chip.
71 *
72 * Input:
73 * edgeSelect - Edge Select:
74 * 0 = Input data is falling edge latched (falling edge
75 * latched first in dual edge mode)
76 * 1 = Input data is rising edge latched (rising edge
77 * latched first in dual edge mode)
78 * busSelect - Input Bus Select:
79 * 0 = Input data bus is 12-bits wide
80 * 1 = Input data bus is 24-bits wide
81 * dualEdgeClkSelect - Dual Edge Clock Select
82 * 0 = Input data is single edge latched
83 * 1 = Input data is dual edge latched
84 * hsyncEnable - Horizontal Sync Enable:
85 * 0 = HSYNC input is transmitted as fixed LOW
86 * 1 = HSYNC input is transmitted as is
87 * vsyncEnable - Vertical Sync Enable:
88 * 0 = VSYNC input is transmitted as fixed LOW
89 * 1 = VSYNC input is transmitted as is
90 * deskewEnable - De-skewing Enable:
91 * 0 = De-skew disabled
92 * 1 = De-skew enabled
93 * deskewSetting - De-skewing Setting (increment of 260psec)
94 * 0 = 1 step --> minimum setup / maximum hold
95 * 1 = 2 step
96 * 2 = 3 step
97 * 3 = 4 step
98 * 4 = 5 step
99 * 5 = 6 step
100 * 6 = 7 step
101 * 7 = 8 step --> maximum setup / minimum hold
102 * continuousSyncEnable- SYNC Continuous:
103 * 0 = Disable
104 * 1 = Enable
105 * pllFilterEnable - PLL Filter Enable
106 * 0 = Disable PLL Filter
107 * 1 = Enable PLL Filter
108 * pllFilterValue - PLL Filter characteristics:
109 * 0~7 (recommended value is 4)
110 *
111 * Output:
112 * 0 - Success
113 * -1 - Fail.
114 */
115long sii164InitChip(
Juston Li78376532015-07-14 21:14:30 -0700116 unsigned char edgeSelect,
117 unsigned char busSelect,
118 unsigned char dualEdgeClkSelect,
119 unsigned char hsyncEnable,
120 unsigned char vsyncEnable,
121 unsigned char deskewEnable,
122 unsigned char deskewSetting,
123 unsigned char continuousSyncEnable,
124 unsigned char pllFilterEnable,
125 unsigned char pllFilterValue
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530126)
127{
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530128 unsigned char config;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530129
Juston Li78376532015-07-14 21:14:30 -0700130 /* Initialize the i2c bus */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530131#ifdef USE_HW_I2C
Juston Li78376532015-07-14 21:14:30 -0700132 /* Use fast mode. */
Mike Rapoport19f70ea2015-09-12 11:07:33 +0300133 sm750_hw_i2c_init(1);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530134#else
Mike Rapoportf2ea7732015-09-12 11:07:38 +0300135 sm750_sw_i2c_init(DEFAULT_I2C_SCL, DEFAULT_I2C_SDA);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530136#endif
137
Juston Li78376532015-07-14 21:14:30 -0700138 /* Check if SII164 Chip exists */
Juston Li259fef32015-07-14 21:14:45 -0700139 if ((sii164GetVendorID() == SII164_VENDOR_ID) && (sii164GetDeviceID() == SII164_DEVICE_ID)) {
Juston Li78376532015-07-14 21:14:30 -0700140 /*
141 * Initialize SII164 controller chip.
142 */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530143
Juston Li78376532015-07-14 21:14:30 -0700144 /* Select the edge */
145 if (edgeSelect == 0)
146 config = SII164_CONFIGURATION_LATCH_FALLING;
147 else
148 config = SII164_CONFIGURATION_LATCH_RISING;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530149
Juston Li78376532015-07-14 21:14:30 -0700150 /* Select bus wide */
151 if (busSelect == 0)
152 config |= SII164_CONFIGURATION_BUS_12BITS;
153 else
154 config |= SII164_CONFIGURATION_BUS_24BITS;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530155
Juston Li78376532015-07-14 21:14:30 -0700156 /* Select Dual/Single Edge Clock */
157 if (dualEdgeClkSelect == 0)
158 config |= SII164_CONFIGURATION_CLOCK_SINGLE;
159 else
160 config |= SII164_CONFIGURATION_CLOCK_DUAL;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530161
Juston Li78376532015-07-14 21:14:30 -0700162 /* Select HSync Enable */
163 if (hsyncEnable == 0)
164 config |= SII164_CONFIGURATION_HSYNC_FORCE_LOW;
165 else
166 config |= SII164_CONFIGURATION_HSYNC_AS_IS;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530167
Juston Li78376532015-07-14 21:14:30 -0700168 /* Select VSync Enable */
169 if (vsyncEnable == 0)
170 config |= SII164_CONFIGURATION_VSYNC_FORCE_LOW;
171 else
172 config |= SII164_CONFIGURATION_VSYNC_AS_IS;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530173
Juston Li78376532015-07-14 21:14:30 -0700174 i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530175
Juston Li78376532015-07-14 21:14:30 -0700176 /* De-skew enabled with default 111b value.
Elizabeth Ferdman35e4d8c2016-09-28 14:33:51 -0700177 * This fixes some artifacts problem in some mode on board 2.2.
178 * Somehow this fix does not affect board 2.1.
Juston Li78376532015-07-14 21:14:30 -0700179 */
180 if (deskewEnable == 0)
181 config = SII164_DESKEW_DISABLE;
182 else
183 config = SII164_DESKEW_ENABLE;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530184
Juston Li259fef32015-07-14 21:14:45 -0700185 switch (deskewSetting) {
Juston Li78376532015-07-14 21:14:30 -0700186 case 0:
187 config |= SII164_DESKEW_1_STEP;
188 break;
189 case 1:
190 config |= SII164_DESKEW_2_STEP;
191 break;
192 case 2:
193 config |= SII164_DESKEW_3_STEP;
194 break;
195 case 3:
196 config |= SII164_DESKEW_4_STEP;
197 break;
198 case 4:
199 config |= SII164_DESKEW_5_STEP;
200 break;
201 case 5:
202 config |= SII164_DESKEW_6_STEP;
203 break;
204 case 6:
205 config |= SII164_DESKEW_7_STEP;
206 break;
207 case 7:
208 config |= SII164_DESKEW_8_STEP;
209 break;
210 }
211 i2cWriteReg(SII164_I2C_ADDRESS, SII164_DESKEW, config);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530212
Juston Li78376532015-07-14 21:14:30 -0700213 /* Enable/Disable Continuous Sync. */
214 if (continuousSyncEnable == 0)
215 config = SII164_PLL_FILTER_SYNC_CONTINUOUS_DISABLE;
216 else
217 config = SII164_PLL_FILTER_SYNC_CONTINUOUS_ENABLE;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530218
Juston Li78376532015-07-14 21:14:30 -0700219 /* Enable/Disable PLL Filter */
220 if (pllFilterEnable == 0)
221 config |= SII164_PLL_FILTER_DISABLE;
222 else
223 config |= SII164_PLL_FILTER_ENABLE;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530224
Juston Li78376532015-07-14 21:14:30 -0700225 /* Set the PLL Filter value */
226 config |= ((pllFilterValue & 0x07) << 1);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530227
Juston Li78376532015-07-14 21:14:30 -0700228 i2cWriteReg(SII164_I2C_ADDRESS, SII164_PLL, config);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530229
Juston Li78376532015-07-14 21:14:30 -0700230 /* Recover from Power Down and enable output. */
231 config = i2cReadReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION);
232 config |= SII164_CONFIGURATION_POWER_NORMAL;
233 i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530234
Juston Li78376532015-07-14 21:14:30 -0700235 return 0;
236 }
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530237
Juston Li78376532015-07-14 21:14:30 -0700238 /* Return -1 if initialization fails. */
Amitoj Kaur Chawla732053a2016-02-24 22:30:15 +0530239 return -1;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530240}
241
242
243
244
245
Carlos E. Garcia69e98df2015-04-24 09:40:42 -0400246/* below sii164 function is not necessary */
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530247
248#ifdef SII164_FULL_FUNCTIONS
249
250/*
251 * sii164ResetChip
252 * This function resets the DVI Controller Chip.
253 */
Supriya Karanth6fa7db82015-03-12 01:11:00 +0900254void sii164ResetChip(void)
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530255{
Juston Li78376532015-07-14 21:14:30 -0700256 /* Power down */
257 sii164SetPower(0);
258 sii164SetPower(1);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530259}
260
261
262/*
263 * sii164GetChipString
264 * This function returns a char string name of the current DVI Controller chip.
265 * It's convenient for application need to display the chip name.
266 */
Supriya Karanth6fa7db82015-03-12 01:11:00 +0900267char *sii164GetChipString(void)
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530268{
Juston Li78376532015-07-14 21:14:30 -0700269 return gDviCtrlChipName;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530270}
271
272
273/*
274 * sii164SetPower
275 * This function sets the power configuration of the DVI Controller Chip.
276 *
277 * Input:
278 * powerUp - Flag to set the power down or up
279 */
280void sii164SetPower(
Juston Li78376532015-07-14 21:14:30 -0700281 unsigned char powerUp
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530282)
283{
Juston Li78376532015-07-14 21:14:30 -0700284 unsigned char config;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530285
Juston Li78376532015-07-14 21:14:30 -0700286 config = i2cReadReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION);
Juston Li259fef32015-07-14 21:14:45 -0700287 if (powerUp == 1) {
Juston Li78376532015-07-14 21:14:30 -0700288 /* Power up the chip */
289 config &= ~SII164_CONFIGURATION_POWER_MASK;
290 config |= SII164_CONFIGURATION_POWER_NORMAL;
291 i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
Juston Li259fef32015-07-14 21:14:45 -0700292 } else {
Juston Li78376532015-07-14 21:14:30 -0700293 /* Power down the chip */
294 config &= ~SII164_CONFIGURATION_POWER_MASK;
295 config |= SII164_CONFIGURATION_POWER_DOWN;
296 i2cWriteReg(SII164_I2C_ADDRESS, SII164_CONFIGURATION, config);
297 }
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530298}
299
300
301/*
302 * sii164SelectHotPlugDetectionMode
303 * This function selects the mode of the hot plug detection.
304 */
305static void sii164SelectHotPlugDetectionMode(
Juston Li78376532015-07-14 21:14:30 -0700306 sii164_hot_plug_mode_t hotPlugMode
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530307)
308{
Juston Li78376532015-07-14 21:14:30 -0700309 unsigned char detectReg;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530310
Juston Li78376532015-07-14 21:14:30 -0700311 detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) & ~SII164_DETECT_MONITOR_SENSE_OUTPUT_FLAG;
Juston Li259fef32015-07-14 21:14:45 -0700312 switch (hotPlugMode) {
Juston Li78376532015-07-14 21:14:30 -0700313 case SII164_HOTPLUG_DISABLE:
314 detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_HIGH;
315 break;
316 case SII164_HOTPLUG_USE_MDI:
317 detectReg &= ~SII164_DETECT_INTERRUPT_MASK;
318 detectReg |= SII164_DETECT_INTERRUPT_BY_HTPLG_PIN;
319 detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_MDI;
320 break;
321 case SII164_HOTPLUG_USE_RSEN:
322 detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_RSEN;
323 break;
324 case SII164_HOTPLUG_USE_HTPLG:
325 detectReg |= SII164_DETECT_MONITOR_SENSE_OUTPUT_HTPLG;
326 break;
327 }
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530328
Juston Li78376532015-07-14 21:14:30 -0700329 i2cWriteReg(SII164_I2C_ADDRESS, SII164_DETECT, detectReg);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530330}
331
332/*
333 * sii164EnableHotPlugDetection
334 * This function enables the Hot Plug detection.
335 *
336 * enableHotPlug - Enable (=1) / disable (=0) Hot Plug detection
337 */
338void sii164EnableHotPlugDetection(
Juston Li78376532015-07-14 21:14:30 -0700339 unsigned char enableHotPlug
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530340)
341{
Juston Li78376532015-07-14 21:14:30 -0700342 unsigned char detectReg;
Juston Li40403c12015-07-14 21:14:48 -0700343
Juston Li78376532015-07-14 21:14:30 -0700344 detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530345
Juston Li78376532015-07-14 21:14:30 -0700346 /* Depending on each DVI controller, need to enable the hot plug based on each
Elizabeth Ferdman35e4d8c2016-09-28 14:33:51 -0700347 * individual chip design.
348 */
Juston Li78376532015-07-14 21:14:30 -0700349 if (enableHotPlug != 0)
350 sii164SelectHotPlugDetectionMode(SII164_HOTPLUG_USE_MDI);
351 else
352 sii164SelectHotPlugDetectionMode(SII164_HOTPLUG_DISABLE);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530353}
354
355/*
356 * sii164IsConnected
357 * Check if the DVI Monitor is connected.
358 *
359 * Output:
360 * 0 - Not Connected
361 * 1 - Connected
362 */
Supriya Karanth6fa7db82015-03-12 01:11:00 +0900363unsigned char sii164IsConnected(void)
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530364{
Juston Li78376532015-07-14 21:14:30 -0700365 unsigned char hotPlugValue;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530366
Juston Li78376532015-07-14 21:14:30 -0700367 hotPlugValue = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) & SII164_DETECT_HOT_PLUG_STATUS_MASK;
368 if (hotPlugValue == SII164_DETECT_HOT_PLUG_STATUS_ON)
369 return 1;
370 else
371 return 0;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530372}
373
374/*
375 * sii164CheckInterrupt
Carlos E. Garcia69e98df2015-04-24 09:40:42 -0400376 * Checks if interrupt has occurred.
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530377 *
378 * Output:
379 * 0 - No interrupt
380 * 1 - Interrupt occurs
381 */
Supriya Karanth6fa7db82015-03-12 01:11:00 +0900382unsigned char sii164CheckInterrupt(void)
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530383{
Juston Li78376532015-07-14 21:14:30 -0700384 unsigned char detectReg;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530385
Juston Li78376532015-07-14 21:14:30 -0700386 detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT) & SII164_DETECT_MONITOR_STATE_MASK;
387 if (detectReg == SII164_DETECT_MONITOR_STATE_CHANGE)
388 return 1;
389 else
390 return 0;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530391}
392
393/*
394 * sii164ClearInterrupt
395 * Clear the hot plug interrupt.
396 */
Supriya Karanth6fa7db82015-03-12 01:11:00 +0900397void sii164ClearInterrupt(void)
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530398{
Juston Li78376532015-07-14 21:14:30 -0700399 unsigned char detectReg;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530400
Juston Li78376532015-07-14 21:14:30 -0700401 /* Clear the MDI interrupt */
402 detectReg = i2cReadReg(SII164_I2C_ADDRESS, SII164_DETECT);
403 i2cWriteReg(SII164_I2C_ADDRESS, SII164_DETECT, detectReg | SII164_DETECT_MONITOR_STATE_CLEAR);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530404}
405
406#endif
407
408#endif
409
410