25 #define viafb_compact_res(x, y) (((x)<<16)|(y))
29 static const int PowerSequenceOn[3][3] = {
30 {0x10, 0x08, 0x06}, {0x10, 0x08, 0x06}, {0x19, 0x1FE, 0x01}
32 static const int PowerSequenceOff[3][3] = {
33 {0x06, 0x08, 0x10}, {0x00, 0x00, 0x00}, {0xD2, 0x19, 0x01}
51 static bool lvds_identify_integratedlvds(
void);
52 static void __devinit fp_id_to_vindex(
int panel_id);
53 static int lvds_register_read(
int index);
54 static void load_lcd_scaling(
int set_hres,
int set_vres,
int panel_hres,
71 static void lcd_powersequence_off(
void);
72 static void lcd_powersequence_on(
void);
73 static void fill_lcd_format(
void);
74 static void check_diport_of_integrated_lvds(
79 static inline bool check_lvds_chip(
int device_id_subaddr,
int device_id)
81 return lvds_register_read(device_id_subaddr) ==
device_id;
89 viaparinfo->lvds_setting_info2->lcd_panel_hres =
91 viaparinfo->lvds_setting_info2->lcd_panel_vres =
93 viaparinfo->lvds_setting_info2->device_lcd_dualedge =
94 viaparinfo->lvds_setting_info->device_lcd_dualedge;
99 static bool lvds_identify_integratedlvds(
void)
105 if (
viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
106 viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name =
109 "(Internal LVDS + External LVDS)\n");
111 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
114 "so can't support two dual channel LVDS!\n");
118 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
120 viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name =
123 "(Internal LVDS + Internal LVDS)\n");
127 if (!
viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
128 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
133 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
147 "Found VIA VT1636 LVDS on port i2c 0x31\n");
150 viaparinfo->chip_info->lvds_chip_info.i2c_port =
153 "Found VIA VT1636 LVDS on port gpio 0x2c\n");
158 lvds_identify_integratedlvds();
160 if (
viaparinfo->chip_info->lvds_chip_info.lvds_chip_name)
164 viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr =
170 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name);
172 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name);
176 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
178 viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr =
183 static void __devinit fp_id_to_vindex(
int panel_id)
193 viaparinfo->lvds_setting_info->lcd_panel_hres = 640;
194 viaparinfo->lvds_setting_info->lcd_panel_vres = 480;
195 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
196 viaparinfo->lvds_setting_info->LCDDithering = 1;
199 viaparinfo->lvds_setting_info->lcd_panel_hres = 800;
200 viaparinfo->lvds_setting_info->lcd_panel_vres = 600;
201 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
202 viaparinfo->lvds_setting_info->LCDDithering = 1;
205 viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
206 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
207 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
208 viaparinfo->lvds_setting_info->LCDDithering = 1;
211 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
212 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
213 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
214 viaparinfo->lvds_setting_info->LCDDithering = 1;
217 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
218 viaparinfo->lvds_setting_info->lcd_panel_vres = 1024;
219 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
220 viaparinfo->lvds_setting_info->LCDDithering = 1;
223 viaparinfo->lvds_setting_info->lcd_panel_hres = 1400;
224 viaparinfo->lvds_setting_info->lcd_panel_vres = 1050;
225 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
226 viaparinfo->lvds_setting_info->LCDDithering = 1;
229 viaparinfo->lvds_setting_info->lcd_panel_hres = 1600;
230 viaparinfo->lvds_setting_info->lcd_panel_vres = 1200;
231 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
232 viaparinfo->lvds_setting_info->LCDDithering = 1;
235 viaparinfo->lvds_setting_info->lcd_panel_hres = 800;
236 viaparinfo->lvds_setting_info->lcd_panel_vres = 480;
237 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
238 viaparinfo->lvds_setting_info->LCDDithering = 1;
241 viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
242 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
243 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
244 viaparinfo->lvds_setting_info->LCDDithering = 1;
247 viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
248 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
249 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
250 viaparinfo->lvds_setting_info->LCDDithering = 0;
253 viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
254 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
255 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
256 viaparinfo->lvds_setting_info->LCDDithering = 0;
259 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
260 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
261 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
262 viaparinfo->lvds_setting_info->LCDDithering = 0;
265 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
266 viaparinfo->lvds_setting_info->lcd_panel_vres = 1024;
267 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
268 viaparinfo->lvds_setting_info->LCDDithering = 0;
271 viaparinfo->lvds_setting_info->lcd_panel_hres = 1400;
272 viaparinfo->lvds_setting_info->lcd_panel_vres = 1050;
273 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
274 viaparinfo->lvds_setting_info->LCDDithering = 0;
277 viaparinfo->lvds_setting_info->lcd_panel_hres = 1600;
278 viaparinfo->lvds_setting_info->lcd_panel_vres = 1200;
279 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
280 viaparinfo->lvds_setting_info->LCDDithering = 0;
283 viaparinfo->lvds_setting_info->lcd_panel_hres = 1366;
284 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
285 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
286 viaparinfo->lvds_setting_info->LCDDithering = 0;
289 viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
290 viaparinfo->lvds_setting_info->lcd_panel_vres = 600;
291 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
292 viaparinfo->lvds_setting_info->LCDDithering = 1;
295 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
296 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
297 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
298 viaparinfo->lvds_setting_info->LCDDithering = 1;
301 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
302 viaparinfo->lvds_setting_info->lcd_panel_vres = 800;
303 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
304 viaparinfo->lvds_setting_info->LCDDithering = 1;
307 viaparinfo->lvds_setting_info->lcd_panel_hres = 1360;
308 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
309 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
310 viaparinfo->lvds_setting_info->LCDDithering = 0;
313 viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
314 viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
315 viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
316 viaparinfo->lvds_setting_info->LCDDithering = 0;
319 viaparinfo->lvds_setting_info->lcd_panel_hres = 480;
320 viaparinfo->lvds_setting_info->lcd_panel_vres = 640;
321 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
322 viaparinfo->lvds_setting_info->LCDDithering = 1;
326 viaparinfo->lvds_setting_info->lcd_panel_hres = 1200;
327 viaparinfo->lvds_setting_info->lcd_panel_vres = 900;
328 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
329 viaparinfo->lvds_setting_info->LCDDithering = 0;
332 viaparinfo->lvds_setting_info->lcd_panel_hres = 800;
333 viaparinfo->lvds_setting_info->lcd_panel_vres = 600;
334 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
335 viaparinfo->lvds_setting_info->LCDDithering = 1;
339 static int lvds_register_read(
int index)
344 (
u8)
viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr,
349 static void load_lcd_scaling(
int set_hres,
int set_vres,
int panel_hres,
353 int viafb_load_reg_num;
362 if (set_hres < panel_hres) {
364 switch (
viaparinfo->chip_info->gfx_chip_name) {
374 viafb_load_reg_num, reg,
VIACR);
395 viafb_load_reg_num, reg,
VIACR);
406 if (set_vres < panel_vres) {
408 switch (
viaparinfo->chip_info->gfx_chip_name) {
418 viafb_load_reg_num, reg,
VIACR);
439 viafb_load_reg_num, reg,
VIACR);
450 static void via_pitch_alignment_patch_lcd(
int iga_path,
int hres,
int bpp)
452 unsigned char cr13, cr35, cr65, cr66, cr67;
453 unsigned long dwScreenPitch = 0;
454 unsigned long dwPitch;
456 dwPitch = hres * (bpp >> 3);
457 if (dwPitch & 0x1F) {
458 dwScreenPitch = ((dwPitch + 31) & ~31) >> 3;
459 if (iga_path ==
IGA2) {
461 cr66 = (
unsigned char)(dwScreenPitch & 0xFF);
466 char)((dwScreenPitch & 0x300) >> 8);
472 cr67 |= (
unsigned char)((dwScreenPitch & 0x600) >> 7);
474 cr65 = (
unsigned char)((dwScreenPitch >> 1) & 0xFF);
479 cr13 = (
unsigned char)(dwScreenPitch & 0xFF);
484 char)((dwScreenPitch & 0x700) >> 3);
495 switch (
viaparinfo->chip_info->gfx_chip_name) {
512 switch (
viaparinfo->chip_info->gfx_chip_name) {
526 lcd_patch_skew_dvp0(plvds_setting_info, plvds_chip_info);
529 lcd_patch_skew_dvp1(plvds_setting_info, plvds_chip_info);
545 int set_iga = plvds_setting_info->
iga_path;
547 int set_hres = cxres ? cxres : var->
xres;
548 int set_vres = cyres ? cyres : var->
yres;
554 const struct fb_videomode *mode_crt_table, *panel_crt_table;
568 if (set_iga ==
IGA2 && (set_hres < panel_hres || set_vres < panel_vres)
571 load_lcd_scaling(set_hres, set_vres, panel_hres, panel_vres);
576 via_write_reg_mask(
VIACR, 0x79, 0x00,
582 else if (set_iga ==
IGA2)
594 lcd_patch_skew(plvds_setting_info, plvds_chip_info);
602 via_pitch_alignment_patch_lcd(plvds_setting_info->
iga_path, set_hres,
610 bool turn_off_first_powersequence =
false;
611 bool turn_off_second_powersequence =
false;
613 turn_off_first_powersequence =
true;
615 turn_off_first_powersequence =
true;
617 turn_off_second_powersequence =
true;
618 if (turn_off_second_powersequence) {
627 if (turn_off_first_powersequence) {
718 lcd_powersequence_off();
724 viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name))
725 integrated_lvds_disable(
viaparinfo->lvds_setting_info,
728 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name)
729 integrated_lvds_disable(
viaparinfo->lvds_setting_info,
732 lvds_chip_info.lvds_chip_name)
736 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
752 static void set_lcd_output_path(
int set_iga,
int output_interface)
754 switch (output_interface) {
775 set_lcd_output_path(
viaparinfo->lvds_setting_info->iga_path,
776 viaparinfo->chip_info->lvds_chip_info.output_interface);
778 set_lcd_output_path(
viaparinfo->lvds_setting_info2->iga_path,
780 lvds_chip_info2.output_interface);
785 lcd_powersequence_on();
788 viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name))
789 integrated_lvds_enable(
viaparinfo->lvds_setting_info2, \
792 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name)
793 integrated_lvds_enable(
viaparinfo->lvds_setting_info,
796 lvds_chip_info.lvds_chip_name)
801 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
814 static void lcd_powersequence_off(
void)
821 for (i = 0; i < 3; i++) {
822 mask = PowerSequenceOff[0][
i];
823 data = PowerSequenceOff[1][
i] &
mask;
825 udelay(PowerSequenceOff[2][i]);
832 static void lcd_powersequence_on(
void)
842 for (i = 0; i < 3; i++) {
843 mask = PowerSequenceOn[0][
i];
844 data = PowerSequenceOn[1][
i] &
mask;
846 udelay(PowerSequenceOn[2][i]);
852 static void fill_lcd_format(
void)
854 u8 bdithering = 0, bdual = 0;
856 if (
viaparinfo->lvds_setting_info->device_lcd_dualedge)
858 if (
viaparinfo->lvds_setting_info->LCDDithering)
864 static void check_diport_of_integrated_lvds(
912 "Display Hardware Layout: 0x%x, LCD DI Port: 0x%x\n",
930 switch (
viaparinfo->chip_info->gfx_chip_name) {
944 check_diport_of_integrated_lvds(plvds_chip_info,
949 switch (
viaparinfo->chip_info->gfx_chip_name) {
965 unsigned char __iomem *romptr, *tableptr, *biosptr;
968 const u32 romaddr = 0x000C0000;
971 biosptr =
ioremap(romaddr, 0x10000);
972 start_pattern =
readw(biosptr);
975 if (start_pattern == 0xAA55) {
978 romptr = biosptr + 0x1B;
979 tableptr = biosptr +
readw(romptr);
983 romptr = tableptr + 18;
984 romptr = biosptr +
readw(romptr);
991 core_base =
readb(romptr);