Commit | Line | Data |
---|---|---|
23966d5b JC |
1 | /* |
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | |
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | |
4 | ||
5 | * This program is free software; you can redistribute it and/or | |
6 | * modify it under the terms of the GNU General Public | |
7 | * License as published by the Free Software Foundation; | |
8 | * either version 2, or (at your option) any later version. | |
9 | ||
10 | * This program is distributed in the hope that it will be useful, | |
11 | * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even | |
12 | * the implied warranty of MERCHANTABILITY or FITNESS FOR | |
13 | * A PARTICULAR PURPOSE.See the GNU General Public License | |
14 | * for more details. | |
15 | ||
16 | * You should have received a copy of the GNU General Public License | |
17 | * along with this program; if not, write to the Free Software | |
18 | * Foundation, Inc., | |
19 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
20 | */ | |
21 | ||
22 | #include "global.h" | |
23 | ||
24 | u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information | |
25 | *plvds_setting_info, struct lvds_chip_information *plvds_chip_info, | |
26 | u8 index) | |
27 | { | |
28 | u8 data; | |
29 | ||
c4df5489 | 30 | viaparinfo->shared->i2c_stuff.i2c_port = plvds_chip_info->i2c_port; |
23966d5b JC |
31 | viafb_i2c_readbyte(plvds_chip_info->lvds_chip_slave_addr, index, &data); |
32 | ||
33 | return data; | |
34 | } | |
35 | ||
36 | void viafb_gpio_i2c_write_mask_lvds(struct lvds_setting_information | |
37 | *plvds_setting_info, struct lvds_chip_information | |
38 | *plvds_chip_info, struct IODATA io_data) | |
39 | { | |
40 | int index, data; | |
41 | ||
c4df5489 | 42 | viaparinfo->shared->i2c_stuff.i2c_port = plvds_chip_info->i2c_port; |
23966d5b JC |
43 | |
44 | index = io_data.Index; | |
45 | data = viafb_gpio_i2c_read_lvds(plvds_setting_info, plvds_chip_info, | |
46 | index); | |
47 | data = (data & (~io_data.Mask)) | io_data.Data; | |
48 | ||
49 | viafb_i2c_writebyte(plvds_chip_info->lvds_chip_slave_addr, index, data); | |
50 | } | |
51 | ||
52 | void viafb_init_lvds_vt1636(struct lvds_setting_information | |
53 | *plvds_setting_info, struct lvds_chip_information *plvds_chip_info) | |
54 | { | |
55 | int reg_num, i; | |
56 | ||
57 | /* Common settings: */ | |
58 | reg_num = ARRAY_SIZE(COMMON_INIT_TBL_VT1636); | |
59 | ||
60 | for (i = 0; i < reg_num; i++) { | |
61 | viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, | |
62 | plvds_chip_info, | |
63 | COMMON_INIT_TBL_VT1636[i]); | |
64 | } | |
65 | ||
66 | /* Input Data Mode Select */ | |
67 | if (plvds_setting_info->device_lcd_dualedge) { | |
68 | viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, | |
69 | plvds_chip_info, | |
70 | DUAL_CHANNEL_ENABLE_TBL_VT1636[0]); | |
71 | } else { | |
72 | viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, | |
73 | plvds_chip_info, | |
74 | SINGLE_CHANNEL_ENABLE_TBL_VT1636[0]); | |
75 | } | |
76 | ||
77 | if (plvds_setting_info->LCDDithering) { | |
78 | viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, | |
79 | plvds_chip_info, | |
80 | DITHERING_ENABLE_TBL_VT1636[0]); | |
81 | } else { | |
82 | viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, | |
83 | plvds_chip_info, | |
84 | DITHERING_DISABLE_TBL_VT1636[0]); | |
85 | } | |
86 | } | |
87 | ||
88 | void viafb_enable_lvds_vt1636(struct lvds_setting_information | |
89 | *plvds_setting_info, | |
90 | struct lvds_chip_information *plvds_chip_info) | |
91 | { | |
92 | ||
93 | viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info, | |
94 | VDD_ON_TBL_VT1636[0]); | |
95 | ||
96 | /* Pad on: */ | |
97 | switch (plvds_chip_info->output_interface) { | |
98 | case INTERFACE_DVP0: | |
99 | { | |
100 | viafb_write_reg_mask(SR1E, VIASR, 0xC0, 0xC0); | |
101 | break; | |
102 | } | |
103 | ||
104 | case INTERFACE_DVP1: | |
105 | { | |
106 | viafb_write_reg_mask(SR1E, VIASR, 0x30, 0x30); | |
107 | break; | |
108 | } | |
109 | ||
110 | case INTERFACE_DFP_LOW: | |
111 | { | |
112 | viafb_write_reg_mask(SR2A, VIASR, 0x03, 0x03); | |
113 | break; | |
114 | } | |
115 | ||
116 | case INTERFACE_DFP_HIGH: | |
117 | { | |
118 | viafb_write_reg_mask(SR2A, VIASR, 0x03, 0x0C); | |
119 | break; | |
120 | } | |
121 | ||
122 | } | |
123 | } | |
124 | ||
125 | void viafb_disable_lvds_vt1636(struct lvds_setting_information | |
126 | *plvds_setting_info, | |
127 | struct lvds_chip_information *plvds_chip_info) | |
128 | { | |
129 | ||
130 | viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info, | |
131 | VDD_OFF_TBL_VT1636[0]); | |
132 | ||
133 | /* Pad off: */ | |
134 | switch (plvds_chip_info->output_interface) { | |
135 | case INTERFACE_DVP0: | |
136 | { | |
137 | viafb_write_reg_mask(SR1E, VIASR, 0x00, 0xC0); | |
138 | break; | |
139 | } | |
140 | ||
141 | case INTERFACE_DVP1: | |
142 | { | |
143 | viafb_write_reg_mask(SR1E, VIASR, 0x00, 0x30); | |
144 | break; | |
145 | } | |
146 | ||
147 | case INTERFACE_DFP_LOW: | |
148 | { | |
149 | viafb_write_reg_mask(SR2A, VIASR, 0x00, 0x03); | |
150 | break; | |
151 | } | |
152 | ||
153 | case INTERFACE_DFP_HIGH: | |
154 | { | |
155 | viafb_write_reg_mask(SR2A, VIASR, 0x00, 0x0C); | |
156 | break; | |
157 | } | |
158 | ||
159 | } | |
160 | } | |
161 | ||
162 | bool viafb_lvds_identify_vt1636(void) | |
163 | { | |
164 | u8 Buffer[2]; | |
165 | ||
166 | DEBUG_MSG(KERN_INFO "viafb_lvds_identify_vt1636.\n"); | |
167 | ||
168 | /* Sense VT1636 LVDS Transmiter */ | |
169 | viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr = | |
170 | VT1636_LVDS_I2C_ADDR; | |
171 | ||
172 | /* Check vendor ID first: */ | |
173 | viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info. | |
174 | lvds_chip_slave_addr, | |
175 | 0x00, &Buffer[0]); | |
176 | viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info. | |
177 | lvds_chip_slave_addr, | |
178 | 0x01, &Buffer[1]); | |
179 | ||
180 | if (!((Buffer[0] == 0x06) && (Buffer[1] == 0x11))) | |
181 | return false; | |
182 | ||
183 | /* Check Chip ID: */ | |
184 | viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info. | |
185 | lvds_chip_slave_addr, | |
186 | 0x02, &Buffer[0]); | |
187 | viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info. | |
188 | lvds_chip_slave_addr, | |
189 | 0x03, &Buffer[1]); | |
190 | if ((Buffer[0] == 0x45) && (Buffer[1] == 0x33)) { | |
191 | viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = | |
192 | VT1636_LVDS; | |
193 | return true; | |
194 | } | |
195 | ||
196 | return false; | |
197 | } | |
198 | ||
199 | static int get_clk_range_index(u32 Clk) | |
200 | { | |
201 | if (Clk < DPA_CLK_30M) | |
202 | return DPA_CLK_RANGE_30M; | |
203 | else if (Clk < DPA_CLK_50M) | |
204 | return DPA_CLK_RANGE_30_50M; | |
205 | else if (Clk < DPA_CLK_70M) | |
206 | return DPA_CLK_RANGE_50_70M; | |
207 | else if (Clk < DPA_CLK_100M) | |
208 | return DPA_CLK_RANGE_70_100M; | |
209 | else if (Clk < DPA_CLK_150M) | |
210 | return DPA_CLK_RANGE_100_150M; | |
211 | else | |
212 | return DPA_CLK_RANGE_150M; | |
213 | } | |
214 | ||
215 | static int get_lvds_dpa_setting_index(int panel_size_id, | |
216 | struct VT1636_DPA_SETTING *p_vt1636_dpasetting_tbl, | |
217 | int tbl_size) | |
218 | { | |
219 | int i; | |
220 | ||
221 | for (i = 0; i < tbl_size; i++) { | |
222 | if (panel_size_id == p_vt1636_dpasetting_tbl->PanelSizeID) | |
223 | return i; | |
224 | ||
225 | p_vt1636_dpasetting_tbl++; | |
226 | } | |
227 | ||
228 | return 0; | |
229 | } | |
230 | ||
231 | static void set_dpa_vt1636(struct lvds_setting_information | |
232 | *plvds_setting_info, struct lvds_chip_information *plvds_chip_info, | |
233 | struct VT1636_DPA_SETTING *p_vt1636_dpa_setting) | |
234 | { | |
235 | struct IODATA io_data; | |
236 | ||
237 | io_data.Index = 0x09; | |
238 | io_data.Mask = 0x1F; | |
239 | io_data.Data = p_vt1636_dpa_setting->CLK_SEL_ST1; | |
240 | viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, | |
241 | plvds_chip_info, io_data); | |
242 | ||
243 | io_data.Index = 0x08; | |
244 | io_data.Mask = 0x0F; | |
245 | io_data.Data = p_vt1636_dpa_setting->CLK_SEL_ST2; | |
246 | viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info, | |
247 | io_data); | |
248 | } | |
249 | ||
250 | void viafb_vt1636_patch_skew_on_vt3324( | |
251 | struct lvds_setting_information *plvds_setting_info, | |
252 | struct lvds_chip_information *plvds_chip_info) | |
253 | { | |
254 | int index, size; | |
255 | ||
256 | DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3324.\n"); | |
257 | ||
258 | /* Graphics DPA settings: */ | |
259 | index = get_clk_range_index(plvds_setting_info->vclk); | |
260 | viafb_set_dpa_gfx(plvds_chip_info->output_interface, | |
261 | &GFX_DPA_SETTING_TBL_VT3324[index]); | |
262 | ||
263 | /* LVDS Transmitter DPA settings: */ | |
264 | size = ARRAY_SIZE(VT1636_DPA_SETTING_TBL_VT3324); | |
265 | index = | |
266 | get_lvds_dpa_setting_index(plvds_setting_info->lcd_panel_id, | |
267 | VT1636_DPA_SETTING_TBL_VT3324, size); | |
268 | set_dpa_vt1636(plvds_setting_info, plvds_chip_info, | |
269 | &VT1636_DPA_SETTING_TBL_VT3324[index]); | |
270 | } | |
271 | ||
272 | void viafb_vt1636_patch_skew_on_vt3327( | |
273 | struct lvds_setting_information *plvds_setting_info, | |
274 | struct lvds_chip_information *plvds_chip_info) | |
275 | { | |
276 | int index, size; | |
277 | ||
278 | DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3327.\n"); | |
279 | ||
280 | /* Graphics DPA settings: */ | |
281 | index = get_clk_range_index(plvds_setting_info->vclk); | |
282 | viafb_set_dpa_gfx(plvds_chip_info->output_interface, | |
283 | &GFX_DPA_SETTING_TBL_VT3327[index]); | |
284 | ||
285 | /* LVDS Transmitter DPA settings: */ | |
286 | size = ARRAY_SIZE(VT1636_DPA_SETTING_TBL_VT3327); | |
287 | index = | |
288 | get_lvds_dpa_setting_index(plvds_setting_info->lcd_panel_id, | |
289 | VT1636_DPA_SETTING_TBL_VT3327, size); | |
290 | set_dpa_vt1636(plvds_setting_info, plvds_chip_info, | |
291 | &VT1636_DPA_SETTING_TBL_VT3327[index]); | |
292 | } | |
293 | ||
294 | void viafb_vt1636_patch_skew_on_vt3364( | |
295 | struct lvds_setting_information *plvds_setting_info, | |
296 | struct lvds_chip_information *plvds_chip_info) | |
297 | { | |
298 | int index; | |
299 | ||
300 | DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3364.\n"); | |
301 | ||
302 | /* Graphics DPA settings: */ | |
303 | index = get_clk_range_index(plvds_setting_info->vclk); | |
304 | viafb_set_dpa_gfx(plvds_chip_info->output_interface, | |
305 | &GFX_DPA_SETTING_TBL_VT3364[index]); | |
306 | } |