diff options
Diffstat (limited to 'drivers/video/via/dvi.c')
-rw-r--r-- | drivers/video/via/dvi.c | 189 |
1 files changed, 119 insertions, 70 deletions
diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c index 39b040bb3817..84e21b39dd0b 100644 --- a/drivers/video/via/dvi.c +++ b/drivers/video/via/dvi.c | |||
@@ -25,10 +25,12 @@ | |||
25 | static void tmds_register_write(int index, u8 data); | 25 | static void tmds_register_write(int index, u8 data); |
26 | static int tmds_register_read(int index); | 26 | static int tmds_register_read(int index); |
27 | static int tmds_register_read_bytes(int index, u8 *buff, int buff_len); | 27 | static int tmds_register_read_bytes(int index, u8 *buff, int buff_len); |
28 | static void dvi_get_panel_size_from_DDCv1(struct tmds_chip_information | 28 | static void __devinit dvi_get_panel_size_from_DDCv1( |
29 | *tmds_chip, struct tmds_setting_information *tmds_setting); | 29 | struct tmds_chip_information *tmds_chip, |
30 | static void dvi_get_panel_size_from_DDCv2(struct tmds_chip_information | 30 | struct tmds_setting_information *tmds_setting); |
31 | *tmds_chip, struct tmds_setting_information *tmds_setting); | 31 | static void __devinit dvi_get_panel_size_from_DDCv2( |
32 | struct tmds_chip_information *tmds_chip, | ||
33 | struct tmds_setting_information *tmds_setting); | ||
32 | static int viafb_dvi_query_EDID(void); | 34 | static int viafb_dvi_query_EDID(void); |
33 | 35 | ||
34 | static int check_tmds_chip(int device_id_subaddr, int device_id) | 36 | static int check_tmds_chip(int device_id_subaddr, int device_id) |
@@ -39,7 +41,7 @@ static int check_tmds_chip(int device_id_subaddr, int device_id) | |||
39 | return FAIL; | 41 | return FAIL; |
40 | } | 42 | } |
41 | 43 | ||
42 | void viafb_init_dvi_size(struct tmds_chip_information *tmds_chip, | 44 | void __devinit viafb_init_dvi_size(struct tmds_chip_information *tmds_chip, |
43 | struct tmds_setting_information *tmds_setting) | 45 | struct tmds_setting_information *tmds_setting) |
44 | { | 46 | { |
45 | DEBUG_MSG(KERN_INFO "viafb_init_dvi_size()\n"); | 47 | DEBUG_MSG(KERN_INFO "viafb_init_dvi_size()\n"); |
@@ -60,7 +62,7 @@ void viafb_init_dvi_size(struct tmds_chip_information *tmds_chip, | |||
60 | return; | 62 | return; |
61 | } | 63 | } |
62 | 64 | ||
63 | int viafb_tmds_trasmitter_identify(void) | 65 | int __devinit viafb_tmds_trasmitter_identify(void) |
64 | { | 66 | { |
65 | unsigned char sr2a = 0, sr1e = 0, sr3e = 0; | 67 | unsigned char sr2a = 0, sr1e = 0, sr3e = 0; |
66 | 68 | ||
@@ -208,8 +210,6 @@ void viafb_dvi_set_mode(struct VideoModeTable *mode, int mode_bpp, | |||
208 | } | 210 | } |
209 | } | 211 | } |
210 | viafb_fill_crtc_timing(pDviTiming, mode, mode_bpp / 8, set_iga); | 212 | viafb_fill_crtc_timing(pDviTiming, mode, mode_bpp / 8, set_iga); |
211 | viafb_set_output_path(DEVICE_DVI, set_iga, | ||
212 | viaparinfo->chip_info->tmds_chip_info.output_interface); | ||
213 | } | 213 | } |
214 | 214 | ||
215 | /* Sense DVI Connector */ | 215 | /* Sense DVI Connector */ |
@@ -313,8 +313,9 @@ static int viafb_dvi_query_EDID(void) | |||
313 | } | 313 | } |
314 | 314 | ||
315 | /* Get Panel Size Using EDID1 Table */ | 315 | /* Get Panel Size Using EDID1 Table */ |
316 | static void dvi_get_panel_size_from_DDCv1(struct tmds_chip_information | 316 | static void __devinit dvi_get_panel_size_from_DDCv1( |
317 | *tmds_chip, struct tmds_setting_information *tmds_setting) | 317 | struct tmds_chip_information *tmds_chip, |
318 | struct tmds_setting_information *tmds_setting) | ||
318 | { | 319 | { |
319 | int i, max_h = 0, tmp, restore; | 320 | int i, max_h = 0, tmp, restore; |
320 | unsigned char rData; | 321 | unsigned char rData; |
@@ -418,8 +419,9 @@ static void dvi_get_panel_size_from_DDCv1(struct tmds_chip_information | |||
418 | } | 419 | } |
419 | 420 | ||
420 | /* Get Panel Size Using EDID2 Table */ | 421 | /* Get Panel Size Using EDID2 Table */ |
421 | static void dvi_get_panel_size_from_DDCv2(struct tmds_chip_information | 422 | static void __devinit dvi_get_panel_size_from_DDCv2( |
422 | *tmds_chip, struct tmds_setting_information *tmds_setting) | 423 | struct tmds_chip_information *tmds_chip, |
424 | struct tmds_setting_information *tmds_setting) | ||
423 | { | 425 | { |
424 | int restore; | 426 | int restore; |
425 | unsigned char R_Buffer[2]; | 427 | unsigned char R_Buffer[2]; |
@@ -468,64 +470,107 @@ static void dvi_get_panel_size_from_DDCv2(struct tmds_chip_information | |||
468 | void viafb_dvi_disable(void) | 470 | void viafb_dvi_disable(void) |
469 | { | 471 | { |
470 | if (viaparinfo->chip_info-> | 472 | if (viaparinfo->chip_info-> |
471 | tmds_chip_info.output_interface == INTERFACE_DVP0) | ||
472 | viafb_write_reg(SR1E, VIASR, | ||
473 | viafb_read_reg(VIASR, SR1E) & (~0xC0)); | ||
474 | |||
475 | if (viaparinfo->chip_info-> | ||
476 | tmds_chip_info.output_interface == INTERFACE_DVP1) | ||
477 | viafb_write_reg(SR1E, VIASR, | ||
478 | viafb_read_reg(VIASR, SR1E) & (~0x30)); | ||
479 | |||
480 | if (viaparinfo->chip_info-> | ||
481 | tmds_chip_info.output_interface == INTERFACE_DFP_HIGH) | ||
482 | viafb_write_reg(SR2A, VIASR, | ||
483 | viafb_read_reg(VIASR, SR2A) & (~0x0C)); | ||
484 | |||
485 | if (viaparinfo->chip_info-> | ||
486 | tmds_chip_info.output_interface == INTERFACE_DFP_LOW) | ||
487 | viafb_write_reg(SR2A, VIASR, | ||
488 | viafb_read_reg(VIASR, SR2A) & (~0x03)); | ||
489 | |||
490 | if (viaparinfo->chip_info-> | ||
491 | tmds_chip_info.output_interface == INTERFACE_TMDS) | 473 | tmds_chip_info.output_interface == INTERFACE_TMDS) |
492 | /* Turn off TMDS power. */ | 474 | /* Turn off TMDS power. */ |
493 | viafb_write_reg(CRD2, VIACR, | 475 | viafb_write_reg(CRD2, VIACR, |
494 | viafb_read_reg(VIACR, CRD2) | 0x08); | 476 | viafb_read_reg(VIACR, CRD2) | 0x08); |
495 | } | 477 | } |
496 | 478 | ||
479 | static void dvi_patch_skew_dvp0(void) | ||
480 | { | ||
481 | /* Reset data driving first: */ | ||
482 | viafb_write_reg_mask(SR1B, VIASR, 0, BIT1); | ||
483 | viafb_write_reg_mask(SR2A, VIASR, 0, BIT4); | ||
484 | |||
485 | switch (viaparinfo->chip_info->gfx_chip_name) { | ||
486 | case UNICHROME_P4M890: | ||
487 | { | ||
488 | if ((viaparinfo->tmds_setting_info->h_active == 1600) && | ||
489 | (viaparinfo->tmds_setting_info->v_active == | ||
490 | 1200)) | ||
491 | viafb_write_reg_mask(CR96, VIACR, 0x03, | ||
492 | BIT0 + BIT1 + BIT2); | ||
493 | else | ||
494 | viafb_write_reg_mask(CR96, VIACR, 0x07, | ||
495 | BIT0 + BIT1 + BIT2); | ||
496 | break; | ||
497 | } | ||
498 | |||
499 | case UNICHROME_P4M900: | ||
500 | { | ||
501 | viafb_write_reg_mask(CR96, VIACR, 0x07, | ||
502 | BIT0 + BIT1 + BIT2 + BIT3); | ||
503 | viafb_write_reg_mask(SR1B, VIASR, 0x02, BIT1); | ||
504 | viafb_write_reg_mask(SR2A, VIASR, 0x10, BIT4); | ||
505 | break; | ||
506 | } | ||
507 | |||
508 | default: | ||
509 | { | ||
510 | break; | ||
511 | } | ||
512 | } | ||
513 | } | ||
514 | |||
515 | static void dvi_patch_skew_dvp_low(void) | ||
516 | { | ||
517 | switch (viaparinfo->chip_info->gfx_chip_name) { | ||
518 | case UNICHROME_K8M890: | ||
519 | { | ||
520 | viafb_write_reg_mask(CR99, VIACR, 0x03, BIT0 + BIT1); | ||
521 | break; | ||
522 | } | ||
523 | |||
524 | case UNICHROME_P4M900: | ||
525 | { | ||
526 | viafb_write_reg_mask(CR99, VIACR, 0x08, | ||
527 | BIT0 + BIT1 + BIT2 + BIT3); | ||
528 | break; | ||
529 | } | ||
530 | |||
531 | case UNICHROME_P4M890: | ||
532 | { | ||
533 | viafb_write_reg_mask(CR99, VIACR, 0x0F, | ||
534 | BIT0 + BIT1 + BIT2 + BIT3); | ||
535 | break; | ||
536 | } | ||
537 | |||
538 | default: | ||
539 | { | ||
540 | break; | ||
541 | } | ||
542 | } | ||
543 | } | ||
544 | |||
497 | /* If Enable DVI, turn off pad */ | 545 | /* If Enable DVI, turn off pad */ |
498 | void viafb_dvi_enable(void) | 546 | void viafb_dvi_enable(void) |
499 | { | 547 | { |
500 | u8 data; | 548 | u8 data; |
501 | 549 | ||
502 | if (viaparinfo->chip_info-> | 550 | switch (viaparinfo->chip_info->tmds_chip_info.output_interface) { |
503 | tmds_chip_info.output_interface == INTERFACE_DVP0) { | 551 | case INTERFACE_DVP0: |
504 | viafb_write_reg(SR1E, VIASR, | 552 | viafb_write_reg_mask(CR6B, VIACR, 0x01, BIT0); |
505 | viafb_read_reg(VIASR, SR1E) | 0xC0); | 553 | viafb_write_reg_mask(CR6C, VIACR, 0x21, BIT0 + BIT5); |
554 | dvi_patch_skew_dvp0(); | ||
506 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) | 555 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) |
507 | tmds_register_write(0x88, 0x3b); | 556 | tmds_register_write(0x88, 0x3b); |
508 | else | 557 | else |
509 | /*clear CR91[5] to direct on display period | 558 | /*clear CR91[5] to direct on display period |
510 | in the secondary diplay path */ | 559 | in the secondary diplay path */ |
511 | viafb_write_reg(CR91, VIACR, | 560 | via_write_reg_mask(VIACR, 0x91, 0x00, 0x20); |
512 | viafb_read_reg(VIACR, CR91) & 0xDF); | 561 | break; |
513 | } | ||
514 | 562 | ||
515 | if (viaparinfo->chip_info-> | 563 | case INTERFACE_DVP1: |
516 | tmds_chip_info.output_interface == INTERFACE_DVP1) { | 564 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) |
517 | viafb_write_reg(SR1E, VIASR, | 565 | viafb_write_reg_mask(CR93, VIACR, 0x21, BIT0 + BIT5); |
518 | viafb_read_reg(VIASR, SR1E) | 0x30); | ||
519 | 566 | ||
520 | /*fix dvi cann't be enabled with MB VT5718C4 - Al Zhang */ | 567 | /*fix dvi cann't be enabled with MB VT5718C4 - Al Zhang */ |
521 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) { | 568 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) |
522 | tmds_register_write(0x88, 0x3b); | 569 | tmds_register_write(0x88, 0x3b); |
523 | } else { | 570 | else |
524 | /*clear CR91[5] to direct on display period | 571 | /*clear CR91[5] to direct on display period |
525 | in the secondary diplay path */ | 572 | in the secondary diplay path */ |
526 | viafb_write_reg(CR91, VIACR, | 573 | via_write_reg_mask(VIACR, 0x91, 0x00, 0x20); |
527 | viafb_read_reg(VIACR, CR91) & 0xDF); | ||
528 | } | ||
529 | 574 | ||
530 | /*fix DVI cannot enable on EPIA-M board */ | 575 | /*fix DVI cannot enable on EPIA-M board */ |
531 | if (viafb_platform_epia_dvi == 1) { | 576 | if (viafb_platform_epia_dvi == 1) { |
@@ -537,36 +582,40 @@ void viafb_dvi_enable(void) | |||
537 | else | 582 | else |
538 | data = 0x37; | 583 | data = 0x37; |
539 | viafb_i2c_writebyte(viaparinfo->chip_info-> | 584 | viafb_i2c_writebyte(viaparinfo->chip_info-> |
540 | tmds_chip_info.i2c_port, | 585 | tmds_chip_info.i2c_port, |
541 | viaparinfo->chip_info-> | 586 | viaparinfo->chip_info-> |
542 | tmds_chip_info.tmds_chip_slave_addr, | 587 | tmds_chip_info.tmds_chip_slave_addr, |
543 | 0x08, data); | 588 | 0x08, data); |
544 | } | 589 | } |
545 | } | 590 | } |
546 | } | 591 | break; |
547 | 592 | ||
548 | if (viaparinfo->chip_info-> | 593 | case INTERFACE_DFP_HIGH: |
549 | tmds_chip_info.output_interface == INTERFACE_DFP_HIGH) { | 594 | if (viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266) |
550 | viafb_write_reg(SR2A, VIASR, | 595 | via_write_reg_mask(VIACR, CR97, 0x03, 0x03); |
551 | viafb_read_reg(VIASR, SR2A) | 0x0C); | ||
552 | viafb_write_reg(CR91, VIACR, | ||
553 | viafb_read_reg(VIACR, CR91) & 0xDF); | ||
554 | } | ||
555 | 596 | ||
556 | if (viaparinfo->chip_info-> | 597 | via_write_reg_mask(VIACR, 0x91, 0x00, 0x20); |
557 | tmds_chip_info.output_interface == INTERFACE_DFP_LOW) { | 598 | break; |
558 | viafb_write_reg(SR2A, VIASR, | 599 | |
559 | viafb_read_reg(VIASR, SR2A) | 0x03); | 600 | case INTERFACE_DFP_LOW: |
560 | viafb_write_reg(CR91, VIACR, | 601 | if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) |
561 | viafb_read_reg(VIACR, CR91) & 0xDF); | 602 | break; |
562 | } | 603 | |
563 | if (viaparinfo->chip_info-> | 604 | dvi_patch_skew_dvp_low(); |
564 | tmds_chip_info.output_interface == INTERFACE_TMDS) { | 605 | via_write_reg_mask(VIACR, 0x91, 0x00, 0x20); |
606 | break; | ||
607 | |||
608 | case INTERFACE_TMDS: | ||
565 | /* Turn on Display period in the panel path. */ | 609 | /* Turn on Display period in the panel path. */ |
566 | viafb_write_reg_mask(CR91, VIACR, 0, BIT7); | 610 | viafb_write_reg_mask(CR91, VIACR, 0, BIT7); |
567 | 611 | ||
568 | /* Turn on TMDS power. */ | 612 | /* Turn on TMDS power. */ |
569 | viafb_write_reg_mask(CRD2, VIACR, 0, BIT3); | 613 | viafb_write_reg_mask(CRD2, VIACR, 0, BIT3); |
614 | break; | ||
570 | } | 615 | } |
571 | } | ||
572 | 616 | ||
617 | if (viaparinfo->tmds_setting_info->iga_path == IGA2) { | ||
618 | /* Disable LCD Scaling */ | ||
619 | viafb_write_reg_mask(CR79, VIACR, 0x00, BIT0); | ||
620 | } | ||
621 | } | ||