diff options
| -rw-r--r-- | drivers/video/intelfb/intelfb.h | 2 | ||||
| -rw-r--r-- | drivers/video/intelfb/intelfbdrv.c | 2 | ||||
| -rw-r--r-- | drivers/video/intelfb/intelfbhw.c | 216 | ||||
| -rw-r--r-- | drivers/video/intelfb/intelfbhw.h | 1 |
4 files changed, 137 insertions, 84 deletions
diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/intelfb/intelfb.h index 43128f9b68f0..631a3a95de40 100644 --- a/drivers/video/intelfb/intelfb.h +++ b/drivers/video/intelfb/intelfb.h | |||
| @@ -286,7 +286,7 @@ struct intelfb_info { | |||
| 286 | int pll_index; | 286 | int pll_index; |
| 287 | }; | 287 | }; |
| 288 | 288 | ||
| 289 | #define IS_I9xx(dinfo) (((dinfo)->chipset == INTEL_915G)||(dinfo->chipset == INTEL_915GM)||((dinfo)->chipset == INTEL_945G)||(dinfo->chipset==INTEL_945GM)) | 289 | #define IS_I9XX(dinfo) (((dinfo)->chipset == INTEL_915G)||(dinfo->chipset == INTEL_915GM)||((dinfo)->chipset == INTEL_945G)||(dinfo->chipset==INTEL_945GM)) |
| 290 | 290 | ||
| 291 | /*** function prototypes ***/ | 291 | /*** function prototypes ***/ |
| 292 | 292 | ||
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c index 54ce74547a3e..9e83664e345c 100644 --- a/drivers/video/intelfb/intelfbdrv.c +++ b/drivers/video/intelfb/intelfbdrv.c | |||
| @@ -1480,7 +1480,7 @@ intelfb_cursor(struct fb_info *info, struct fb_cursor *cursor) | |||
| 1480 | intelfbhw_cursor_hide(dinfo); | 1480 | intelfbhw_cursor_hide(dinfo); |
| 1481 | 1481 | ||
| 1482 | /* If XFree killed the cursor - restore it */ | 1482 | /* If XFree killed the cursor - restore it */ |
| 1483 | physical = (dinfo->mobile || IS_I9xx(dinfo)) ? dinfo->cursor.physical : | 1483 | physical = (dinfo->mobile || IS_I9XX(dinfo)) ? dinfo->cursor.physical : |
| 1484 | (dinfo->cursor.offset << 12); | 1484 | (dinfo->cursor.offset << 12); |
| 1485 | 1485 | ||
| 1486 | if (INREG(CURSOR_A_BASEADDR) != physical) { | 1486 | if (INREG(CURSOR_A_BASEADDR) != physical) { |
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c index 0c3553c35808..2bcf249bdf22 100644 --- a/drivers/video/intelfb/intelfbhw.c +++ b/drivers/video/intelfb/intelfbhw.c | |||
| @@ -47,8 +47,8 @@ struct pll_min_max { | |||
| 47 | int min_n, max_n; | 47 | int min_n, max_n; |
| 48 | int min_p, max_p; | 48 | int min_p, max_p; |
| 49 | int min_p1, max_p1; | 49 | int min_p1, max_p1; |
| 50 | int min_vco_freq, max_vco_freq; | 50 | int min_vco, max_vco; |
| 51 | int p_transition_clock; | 51 | int p_transition_clk, ref_clk; |
| 52 | int p_inc_lo, p_inc_hi; | 52 | int p_inc_lo, p_inc_hi; |
| 53 | }; | 53 | }; |
| 54 | 54 | ||
| @@ -57,8 +57,8 @@ struct pll_min_max { | |||
| 57 | #define PLLS_MAX 2 | 57 | #define PLLS_MAX 2 |
| 58 | 58 | ||
| 59 | static struct pll_min_max plls[PLLS_MAX] = { | 59 | static struct pll_min_max plls[PLLS_MAX] = { |
| 60 | { 108, 140, 18, 26, 6, 16, 3, 16, 4, 128, 0, 31, 930000, 1400000, 165000, 4, 22 }, //I8xx | 60 | { 108, 140, 18, 26, 6, 16, 3, 16, 4, 128, 0, 31, 930000, 1400000, 165000, 48000, 4, 22 }, //I8xx |
| 61 | { 75, 120, 10, 20, 5, 9, 4, 7, 5, 80, 1, 8, 930000, 2800000, 200000, 10, 5 } //I9xx | 61 | { 75, 120, 10, 20, 5, 9, 4, 7, 5, 80, 1, 8, 930000, 2800000, 200000, 96000, 10, 5 } //I9xx |
| 62 | }; | 62 | }; |
| 63 | 63 | ||
| 64 | int | 64 | int |
| @@ -570,21 +570,26 @@ static int calc_vclock3(int index, int m, int n, int p) | |||
| 570 | { | 570 | { |
| 571 | if (p == 0 || n == 0) | 571 | if (p == 0 || n == 0) |
| 572 | return 0; | 572 | return 0; |
| 573 | return PLL_REFCLK * m / n / p; | 573 | return plls[index].ref_clk * m / n / p; |
| 574 | } | 574 | } |
| 575 | 575 | ||
| 576 | static int calc_vclock(int index, int m1, int m2, int n, int p1, int p2) | 576 | static int calc_vclock(int index, int m1, int m2, int n, int p1, int p2, int lvds) |
| 577 | { | 577 | { |
| 578 | int p2_val; | ||
| 578 | switch(index) | 579 | switch(index) |
| 579 | { | 580 | { |
| 580 | case PLLS_I9xx: | 581 | case PLLS_I9xx: |
| 581 | if (p1 == 0) | 582 | if (p1 == 0) |
| 582 | return 0; | 583 | return 0; |
| 583 | return ((PLL_REFCLK * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / | 584 | if (lvds) |
| 584 | ((p1)) * (p2 ? 10 : 5))); | 585 | p2_val = p2 ? 7 : 14; |
| 586 | else | ||
| 587 | p2_val = p2 ? 5 : 10; | ||
| 588 | return ((plls[index].ref_clk * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / | ||
| 589 | ((p1)) * (p2_val))); | ||
| 585 | case PLLS_I8xx: | 590 | case PLLS_I8xx: |
| 586 | default: | 591 | default: |
| 587 | return ((PLL_REFCLK * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / | 592 | return ((plls[index].ref_clk * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / |
| 588 | ((p1+2) * (1 << (p2 + 1))))); | 593 | ((p1+2) * (1 << (p2 + 1))))); |
| 589 | } | 594 | } |
| 590 | } | 595 | } |
| @@ -596,7 +601,7 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw) | |||
| 596 | int i, m1, m2, n, p1, p2; | 601 | int i, m1, m2, n, p1, p2; |
| 597 | int index = dinfo->pll_index; | 602 | int index = dinfo->pll_index; |
| 598 | DBG_MSG("intelfbhw_print_hw_state\n"); | 603 | DBG_MSG("intelfbhw_print_hw_state\n"); |
| 599 | 604 | ||
| 600 | if (!hw || !dinfo) | 605 | if (!hw || !dinfo) |
| 601 | return; | 606 | return; |
| 602 | /* Read in as much of the HW state as possible. */ | 607 | /* Read in as much of the HW state as possible. */ |
| @@ -611,12 +616,14 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw) | |||
| 611 | p1 = 0; | 616 | p1 = 0; |
| 612 | else | 617 | else |
| 613 | p1 = (hw->vga_pd >> VGAPD_0_P1_SHIFT) & DPLL_P1_MASK; | 618 | p1 = (hw->vga_pd >> VGAPD_0_P1_SHIFT) & DPLL_P1_MASK; |
| 619 | |||
| 614 | p2 = (hw->vga_pd >> VGAPD_0_P2_SHIFT) & DPLL_P2_MASK; | 620 | p2 = (hw->vga_pd >> VGAPD_0_P2_SHIFT) & DPLL_P2_MASK; |
| 621 | |||
| 615 | printk(" VGA0: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", | 622 | printk(" VGA0: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", |
| 616 | m1, m2, n, p1, p2); | 623 | m1, m2, n, p1, p2); |
| 617 | printk(" VGA0: clock is %d\n", | 624 | printk(" VGA0: clock is %d\n", |
| 618 | calc_vclock(index, m1, m2, n, p1, p2)); | 625 | calc_vclock(index, m1, m2, n, p1, p2, 0)); |
| 619 | 626 | ||
| 620 | n = (hw->vga1_divisor >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK; | 627 | n = (hw->vga1_divisor >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK; |
| 621 | m1 = (hw->vga1_divisor >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK; | 628 | m1 = (hw->vga1_divisor >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK; |
| 622 | m2 = (hw->vga1_divisor >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK; | 629 | m2 = (hw->vga1_divisor >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK; |
| @@ -627,39 +634,96 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw) | |||
| 627 | p2 = (hw->vga_pd >> VGAPD_1_P2_SHIFT) & DPLL_P2_MASK; | 634 | p2 = (hw->vga_pd >> VGAPD_1_P2_SHIFT) & DPLL_P2_MASK; |
| 628 | printk(" VGA1: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", | 635 | printk(" VGA1: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", |
| 629 | m1, m2, n, p1, p2); | 636 | m1, m2, n, p1, p2); |
| 630 | printk(" VGA1: clock is %d\n", calc_vclock(index, m1, m2, n, p1, p2)); | 637 | printk(" VGA1: clock is %d\n", calc_vclock(index, m1, m2, n, p1, p2, 0)); |
| 631 | 638 | ||
| 632 | printk(" DPLL_A: 0x%08x\n", hw->dpll_a); | 639 | printk(" DPLL_A: 0x%08x\n", hw->dpll_a); |
| 633 | printk(" DPLL_B: 0x%08x\n", hw->dpll_b); | 640 | printk(" DPLL_B: 0x%08x\n", hw->dpll_b); |
| 634 | printk(" FPA0: 0x%08x\n", hw->fpa0); | 641 | printk(" FPA0: 0x%08x\n", hw->fpa0); |
| 635 | printk(" FPA1: 0x%08x\n", hw->fpa1); | 642 | printk(" FPA1: 0x%08x\n", hw->fpa1); |
| 636 | printk(" FPB0: 0x%08x\n", hw->fpb0); | 643 | printk(" FPB0: 0x%08x\n", hw->fpb0); |
| 637 | printk(" FPB1: 0x%08x\n", hw->fpb1); | 644 | printk(" FPB1: 0x%08x\n", hw->fpb1); |
| 638 | 645 | ||
| 639 | n = (hw->fpa0 >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK; | 646 | n = (hw->fpa0 >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK; |
| 640 | m1 = (hw->fpa0 >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK; | 647 | m1 = (hw->fpa0 >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK; |
| 641 | m2 = (hw->fpa0 >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK; | 648 | m2 = (hw->fpa0 >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK; |
| 642 | if (hw->dpll_a & DPLL_P1_FORCE_DIV2) | 649 | |
| 643 | p1 = 0; | 650 | if (IS_I9XX(dinfo)) { |
| 644 | else | 651 | int tmpp1; |
| 645 | p1 = (hw->dpll_a >> DPLL_P1_SHIFT) & DPLL_P1_MASK; | 652 | |
| 646 | p2 = (hw->dpll_a >> DPLL_P2_SHIFT) & DPLL_P2_MASK; | 653 | if (hw->dpll_a & DPLL_P1_FORCE_DIV2) |
| 654 | p1 = 0; | ||
| 655 | else | ||
| 656 | p1 = (hw->dpll_a >> DPLL_P1_SHIFT) & 0xff; | ||
| 657 | |||
| 658 | tmpp1 = p1; | ||
| 659 | |||
| 660 | switch (tmpp1) | ||
| 661 | { | ||
| 662 | case 0x1: p1 = 1; break; | ||
| 663 | case 0x2: p1 = 2; break; | ||
| 664 | case 0x4: p1 = 3; break; | ||
| 665 | case 0x8: p1 = 4; break; | ||
| 666 | case 0x10: p1 = 5; break; | ||
| 667 | case 0x20: p1 = 6; break; | ||
| 668 | case 0x40: p1 = 7; break; | ||
| 669 | case 0x80: p1 = 8; break; | ||
| 670 | default: break; | ||
| 671 | } | ||
| 672 | |||
| 673 | p2 = (hw->dpll_a >> DPLL_I9XX_P2_SHIFT) & DPLL_P2_MASK; | ||
| 674 | |||
| 675 | } else { | ||
| 676 | if (hw->dpll_a & DPLL_P1_FORCE_DIV2) | ||
| 677 | p1 = 0; | ||
| 678 | else | ||
| 679 | p1 = (hw->dpll_a >> DPLL_P1_SHIFT) & DPLL_P1_MASK; | ||
| 680 | p2 = (hw->dpll_a >> DPLL_P2_SHIFT) & DPLL_P2_MASK; | ||
| 681 | } | ||
| 682 | |||
| 647 | printk(" PLLA0: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", | 683 | printk(" PLLA0: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", |
| 648 | m1, m2, n, p1, p2); | 684 | m1, m2, n, p1, p2); |
| 649 | printk(" PLLA0: clock is %d\n", calc_vclock(index, m1, m2, n, p1, p2)); | 685 | printk(" PLLA0: clock is %d\n", calc_vclock(index, m1, m2, n, p1, p2, 0)); |
| 650 | 686 | ||
| 651 | n = (hw->fpa1 >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK; | 687 | n = (hw->fpa1 >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK; |
| 652 | m1 = (hw->fpa1 >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK; | 688 | m1 = (hw->fpa1 >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK; |
| 653 | m2 = (hw->fpa1 >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK; | 689 | m2 = (hw->fpa1 >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK; |
| 654 | if (hw->dpll_a & DPLL_P1_FORCE_DIV2) | 690 | |
| 655 | p1 = 0; | 691 | if (IS_I9XX(dinfo)) { |
| 656 | else | 692 | int tmpp1; |
| 657 | p1 = (hw->dpll_a >> DPLL_P1_SHIFT) & DPLL_P1_MASK; | 693 | |
| 658 | p2 = (hw->dpll_a >> DPLL_P2_SHIFT) & DPLL_P2_MASK; | 694 | if (hw->dpll_a & DPLL_P1_FORCE_DIV2) |
| 695 | p1 = 0; | ||
| 696 | else | ||
| 697 | p1 = (hw->dpll_a >> DPLL_P1_SHIFT) & 0xff; | ||
| 698 | |||
| 699 | tmpp1 = p1; | ||
| 700 | |||
| 701 | switch (tmpp1) | ||
| 702 | { | ||
| 703 | case 0x1: p1 = 1; break; | ||
| 704 | case 0x2: p1 = 2; break; | ||
| 705 | case 0x4: p1 = 3; break; | ||
| 706 | case 0x8: p1 = 4; break; | ||
| 707 | case 0x10: p1 = 5; break; | ||
| 708 | case 0x20: p1 = 6; break; | ||
| 709 | case 0x40: p1 = 7; break; | ||
| 710 | case 0x80: p1 = 8; break; | ||
| 711 | default: break; | ||
| 712 | } | ||
| 713 | |||
| 714 | p2 = (hw->dpll_a >> DPLL_I9XX_P2_SHIFT) & DPLL_P2_MASK; | ||
| 715 | |||
| 716 | } else { | ||
| 717 | if (hw->dpll_a & DPLL_P1_FORCE_DIV2) | ||
| 718 | p1 = 0; | ||
| 719 | else | ||
| 720 | p1 = (hw->dpll_a >> DPLL_P1_SHIFT) & DPLL_P1_MASK; | ||
| 721 | p2 = (hw->dpll_a >> DPLL_P2_SHIFT) & DPLL_P2_MASK; | ||
| 722 | } | ||
| 659 | printk(" PLLA1: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", | 723 | printk(" PLLA1: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", |
| 660 | m1, m2, n, p1, p2); | 724 | m1, m2, n, p1, p2); |
| 661 | printk(" PLLA1: clock is %d\n", calc_vclock(index, m1, m2, n, p1, p2)); | 725 | printk(" PLLA1: clock is %d\n", calc_vclock(index, m1, m2, n, p1, p2, 0)); |
| 662 | 726 | ||
| 663 | #if 0 | 727 | #if 0 |
| 664 | printk(" PALETTE_A:\n"); | 728 | printk(" PALETTE_A:\n"); |
| 665 | for (i = 0; i < PALETTE_8_ENTRIES) | 729 | for (i = 0; i < PALETTE_8_ENTRIES) |
| @@ -767,7 +831,7 @@ splitm(int index, unsigned int m, unsigned int *retm1, unsigned int *retm2) | |||
| 767 | /* no point optimising too much - brute force m */ | 831 | /* no point optimising too much - brute force m */ |
| 768 | for (m1 = plls[index].min_m1; m1 < plls[index].max_m1+1; m1++) { | 832 | for (m1 = plls[index].min_m1; m1 < plls[index].max_m1+1; m1++) { |
| 769 | for (m2 = plls[index].min_m2; m2 < plls[index].max_m2+1; m2++) { | 833 | for (m2 = plls[index].min_m2; m2 < plls[index].max_m2+1; m2++) { |
| 770 | testm = ( 5 * ( m1 + 2 )) + (m2 + 2); | 834 | testm = (5 * (m1 + 2)) + (m2 + 2); |
| 771 | if (testm == m) { | 835 | if (testm == m) { |
| 772 | *retm1 = (unsigned int)m1; | 836 | *retm1 = (unsigned int)m1; |
| 773 | *retm2 = (unsigned int)m2; | 837 | *retm2 = (unsigned int)m2; |
| @@ -785,21 +849,11 @@ splitp(int index, unsigned int p, unsigned int *retp1, unsigned int *retp2) | |||
| 785 | int p1, p2; | 849 | int p1, p2; |
| 786 | 850 | ||
| 787 | if (index == PLLS_I9xx) { | 851 | if (index == PLLS_I9xx) { |
| 788 | switch (p) { | 852 | |
| 789 | case 10: | 853 | p2 = 0; // for now |
| 790 | p1 = 2; | 854 | |
| 791 | p2 = 0; | 855 | p1 = p / (p2 ? 5 : 10); |
| 792 | break; | 856 | |
| 793 | case 20: | ||
| 794 | p1 = 1; | ||
| 795 | p2 = 0; | ||
| 796 | break; | ||
| 797 | default: | ||
| 798 | p1 = (p / 10) + 1; | ||
| 799 | p2 = 0; | ||
| 800 | break; | ||
| 801 | } | ||
| 802 | |||
| 803 | *retp1 = (unsigned int)p1; | 857 | *retp1 = (unsigned int)p1; |
| 804 | *retp2 = (unsigned int)p2; | 858 | *retp2 = (unsigned int)p2; |
| 805 | return 0; | 859 | return 0; |
| @@ -844,13 +898,13 @@ calc_pll_params(int index, int clock, u32 *retm1, u32 *retm2, u32 *retn, u32 *re | |||
| 844 | 898 | ||
| 845 | DBG_MSG("Clock is %d\n", clock); | 899 | DBG_MSG("Clock is %d\n", clock); |
| 846 | 900 | ||
| 847 | div_max = plls[index].max_vco_freq / clock; | 901 | div_max = plls[index].max_vco / clock; |
| 848 | if (index == PLLS_I9xx) | 902 | if (index == PLLS_I9xx) |
| 849 | div_min = 5; | 903 | div_min = 5; |
| 850 | else | 904 | else |
| 851 | div_min = ROUND_UP_TO(plls[index].min_vco_freq, clock) / clock; | 905 | div_min = ROUND_UP_TO(plls[index].min_vco, clock) / clock; |
| 852 | 906 | ||
| 853 | if (clock <= plls[index].p_transition_clock) | 907 | if (clock <= plls[index].p_transition_clk) |
| 854 | p_inc = plls[index].p_inc_lo; | 908 | p_inc = plls[index].p_inc_lo; |
| 855 | else | 909 | else |
| 856 | p_inc = plls[index].p_inc_hi; | 910 | p_inc = plls[index].p_inc_hi; |
| @@ -861,15 +915,6 @@ calc_pll_params(int index, int clock, u32 *retm1, u32 *retm2, u32 *retn, u32 *re | |||
| 861 | if (p_max > plls[index].max_p) | 915 | if (p_max > plls[index].max_p) |
| 862 | p_max = plls[index].max_p; | 916 | p_max = plls[index].max_p; |
| 863 | 917 | ||
| 864 | if (clock < PLL_REFCLK && index == PLLS_I9xx) { | ||
| 865 | p_min = 10; | ||
| 866 | p_max = 20; | ||
| 867 | /* this makes 640x480 work it really shouldn't | ||
| 868 | - SOMEONE WITHOUT DOCS WOZ HERE */ | ||
| 869 | if (clock < 30000) | ||
| 870 | clock *= 4; | ||
| 871 | } | ||
| 872 | |||
| 873 | DBG_MSG("p range is %d-%d (%d)\n", p_min, p_max, p_inc); | 918 | DBG_MSG("p range is %d-%d (%d)\n", p_min, p_max, p_inc); |
| 874 | 919 | ||
| 875 | p = p_min; | 920 | p = p_min; |
| @@ -883,7 +928,7 @@ calc_pll_params(int index, int clock, u32 *retm1, u32 *retm2, u32 *retn, u32 *re | |||
| 883 | f_vco = clock * p; | 928 | f_vco = clock * p; |
| 884 | 929 | ||
| 885 | do { | 930 | do { |
| 886 | m = ROUND_UP_TO(f_vco * n, PLL_REFCLK) / PLL_REFCLK; | 931 | m = ROUND_UP_TO(f_vco * n, plls[index].ref_clk) / plls[index].ref_clk; |
| 887 | if (m < plls[index].min_m) | 932 | if (m < plls[index].min_m) |
| 888 | m = plls[index].min_m + 1; | 933 | m = plls[index].min_m + 1; |
| 889 | if (m > plls[index].max_m) | 934 | if (m > plls[index].max_m) |
| @@ -899,7 +944,7 @@ calc_pll_params(int index, int clock, u32 *retm1, u32 *retm2, u32 *retn, u32 *re | |||
| 899 | f_err = clock - f_out; | 944 | f_err = clock - f_out; |
| 900 | else/* slightly bias the error for bigger clocks */ | 945 | else/* slightly bias the error for bigger clocks */ |
| 901 | f_err = f_out - clock + 1; | 946 | f_err = f_out - clock + 1; |
| 902 | 947 | ||
| 903 | if (f_err < err_best) { | 948 | if (f_err < err_best) { |
| 904 | m_best = m; | 949 | m_best = m; |
| 905 | n_best = n; | 950 | n_best = n; |
| @@ -928,14 +973,14 @@ calc_pll_params(int index, int clock, u32 *retm1, u32 *retm2, u32 *retn, u32 *re | |||
| 928 | "f: %d (%d), VCO: %d\n", | 973 | "f: %d (%d), VCO: %d\n", |
| 929 | m, m1, m2, n, n1, p, p1, p2, | 974 | m, m1, m2, n, n1, p, p1, p2, |
| 930 | calc_vclock3(index, m, n, p), | 975 | calc_vclock3(index, m, n, p), |
| 931 | calc_vclock(index, m1, m2, n1, p1, p2), | 976 | calc_vclock(index, m1, m2, n1, p1, p2, 0), |
| 932 | calc_vclock3(index, m, n, p) * p); | 977 | calc_vclock3(index, m, n, p) * p); |
| 933 | *retm1 = m1; | 978 | *retm1 = m1; |
| 934 | *retm2 = m2; | 979 | *retm2 = m2; |
| 935 | *retn = n1; | 980 | *retn = n1; |
| 936 | *retp1 = p1; | 981 | *retp1 = p1; |
| 937 | *retp2 = p2; | 982 | *retp2 = p2; |
| 938 | *retclock = calc_vclock(index, m1, m2, n1, p1, p2); | 983 | *retclock = calc_vclock(index, m1, m2, n1, p1, p2, 0); |
| 939 | 984 | ||
| 940 | return 0; | 985 | return 0; |
| 941 | } | 986 | } |
| @@ -1032,7 +1077,7 @@ intelfbhw_mode_to_hw(struct intelfb_info *dinfo, struct intelfb_hwstate *hw, | |||
| 1032 | /* Desired clock in kHz */ | 1077 | /* Desired clock in kHz */ |
| 1033 | clock_target = 1000000000 / var->pixclock; | 1078 | clock_target = 1000000000 / var->pixclock; |
| 1034 | 1079 | ||
| 1035 | if (calc_pll_params(dinfo->pll_index, clock_target, &m1, &m2, | 1080 | if (calc_pll_params(dinfo->pll_index, clock_target, &m1, &m2, |
| 1036 | &n, &p1, &p2, &clock)) { | 1081 | &n, &p1, &p2, &clock)) { |
| 1037 | WRN_MSG("calc_pll_params failed\n"); | 1082 | WRN_MSG("calc_pll_params failed\n"); |
| 1038 | return 1; | 1083 | return 1; |
| @@ -1053,7 +1098,14 @@ intelfbhw_mode_to_hw(struct intelfb_info *dinfo, struct intelfb_hwstate *hw, | |||
| 1053 | *dpll &= ~DPLL_P1_FORCE_DIV2; | 1098 | *dpll &= ~DPLL_P1_FORCE_DIV2; |
| 1054 | *dpll &= ~((DPLL_P2_MASK << DPLL_P2_SHIFT) | | 1099 | *dpll &= ~((DPLL_P2_MASK << DPLL_P2_SHIFT) | |
| 1055 | (DPLL_P1_MASK << DPLL_P1_SHIFT)); | 1100 | (DPLL_P1_MASK << DPLL_P1_SHIFT)); |
| 1056 | *dpll |= (p2 << DPLL_P2_SHIFT) | (p1 << DPLL_P1_SHIFT); | 1101 | |
| 1102 | if (IS_I9XX(dinfo)) { | ||
| 1103 | *dpll |= (p2 << DPLL_I9XX_P2_SHIFT); | ||
| 1104 | *dpll |= (1 << (p1 - 1)) << DPLL_P1_SHIFT; | ||
| 1105 | } else { | ||
| 1106 | *dpll |= (p2 << DPLL_P2_SHIFT) | (p1 << DPLL_P1_SHIFT); | ||
| 1107 | } | ||
| 1108 | |||
| 1057 | *fp0 = (n << FP_N_DIVISOR_SHIFT) | | 1109 | *fp0 = (n << FP_N_DIVISOR_SHIFT) | |
| 1058 | (m1 << FP_M1_DIVISOR_SHIFT) | | 1110 | (m1 << FP_M1_DIVISOR_SHIFT) | |
| 1059 | (m2 << FP_M2_DIVISOR_SHIFT); | 1111 | (m2 << FP_M2_DIVISOR_SHIFT); |
| @@ -1264,19 +1316,19 @@ intelfbhw_program_mode(struct intelfb_info *dinfo, | |||
| 1264 | tmp = INREG(pipe_conf_reg); | 1316 | tmp = INREG(pipe_conf_reg); |
| 1265 | tmp &= ~PIPECONF_ENABLE; | 1317 | tmp &= ~PIPECONF_ENABLE; |
| 1266 | OUTREG(pipe_conf_reg, tmp); | 1318 | OUTREG(pipe_conf_reg, tmp); |
| 1267 | 1319 | ||
| 1268 | count = 0; | 1320 | count = 0; |
| 1269 | do { | 1321 | do { |
| 1270 | tmp_val[count%3] = INREG(0x70000); | 1322 | tmp_val[count%3] = INREG(0x70000); |
| 1271 | if ((tmp_val[0] == tmp_val[1]) && (tmp_val[1]==tmp_val[2])) | 1323 | if ((tmp_val[0] == tmp_val[1]) && (tmp_val[1]==tmp_val[2])) |
| 1272 | break; | 1324 | break; |
| 1273 | count++; | 1325 | count++; |
| 1274 | udelay(1); | 1326 | udelay(1); |
| 1275 | if (count % 200 == 0) { | 1327 | if (count % 200 == 0) { |
| 1276 | tmp = INREG(pipe_conf_reg); | 1328 | tmp = INREG(pipe_conf_reg); |
| 1277 | tmp &= ~PIPECONF_ENABLE; | 1329 | tmp &= ~PIPECONF_ENABLE; |
| 1278 | OUTREG(pipe_conf_reg, tmp); | 1330 | OUTREG(pipe_conf_reg, tmp); |
| 1279 | } | 1331 | } |
| 1280 | } while(count < 2000); | 1332 | } while(count < 2000); |
| 1281 | 1333 | ||
| 1282 | OUTREG(ADPA, INREG(ADPA) & ~ADPA_DAC_ENABLE); | 1334 | OUTREG(ADPA, INREG(ADPA) & ~ADPA_DAC_ENABLE); |
| @@ -1289,7 +1341,7 @@ intelfbhw_program_mode(struct intelfb_info *dinfo, | |||
| 1289 | tmp &= ~DISPPLANE_PLANE_ENABLE; | 1341 | tmp &= ~DISPPLANE_PLANE_ENABLE; |
| 1290 | OUTREG(DSPBCNTR, tmp); | 1342 | OUTREG(DSPBCNTR, tmp); |
| 1291 | 1343 | ||
| 1292 | /* Wait for vblank. For now, just wait for a 50Hz cycle (20ms)) */ | 1344 | /* Wait for vblank. For now, just wait for a 50Hz cycle (20ms)) */ |
| 1293 | mdelay(20); | 1345 | mdelay(20); |
| 1294 | 1346 | ||
| 1295 | /* Disable Sync */ | 1347 | /* Disable Sync */ |
| @@ -1359,7 +1411,7 @@ intelfbhw_program_mode(struct intelfb_info *dinfo, | |||
| 1359 | OUTREG(DSPACNTR, | 1411 | OUTREG(DSPACNTR, |
| 1360 | hw->disp_a_ctrl|DISPPLANE_PLANE_ENABLE); | 1412 | hw->disp_a_ctrl|DISPPLANE_PLANE_ENABLE); |
| 1361 | mdelay(1); | 1413 | mdelay(1); |
| 1362 | } | 1414 | } |
| 1363 | } | 1415 | } |
| 1364 | 1416 | ||
| 1365 | OUTREG(DSPACNTR, hw->disp_a_ctrl & ~DISPPLANE_PLANE_ENABLE); | 1417 | OUTREG(DSPACNTR, hw->disp_a_ctrl & ~DISPPLANE_PLANE_ENABLE); |
| @@ -1744,7 +1796,7 @@ intelfbhw_cursor_init(struct intelfb_info *dinfo) | |||
| 1744 | DBG_MSG("intelfbhw_cursor_init\n"); | 1796 | DBG_MSG("intelfbhw_cursor_init\n"); |
| 1745 | #endif | 1797 | #endif |
| 1746 | 1798 | ||
| 1747 | if (dinfo->mobile || IS_I9xx(dinfo)) { | 1799 | if (dinfo->mobile || IS_I9XX(dinfo)) { |
| 1748 | if (!dinfo->cursor.physical) | 1800 | if (!dinfo->cursor.physical) |
| 1749 | return; | 1801 | return; |
| 1750 | tmp = INREG(CURSOR_A_CONTROL); | 1802 | tmp = INREG(CURSOR_A_CONTROL); |
| @@ -1777,7 +1829,7 @@ intelfbhw_cursor_hide(struct intelfb_info *dinfo) | |||
| 1777 | #endif | 1829 | #endif |
| 1778 | 1830 | ||
| 1779 | dinfo->cursor_on = 0; | 1831 | dinfo->cursor_on = 0; |
| 1780 | if (dinfo->mobile || IS_I9xx(dinfo)) { | 1832 | if (dinfo->mobile || IS_I9XX(dinfo)) { |
| 1781 | if (!dinfo->cursor.physical) | 1833 | if (!dinfo->cursor.physical) |
| 1782 | return; | 1834 | return; |
| 1783 | tmp = INREG(CURSOR_A_CONTROL); | 1835 | tmp = INREG(CURSOR_A_CONTROL); |
| @@ -1807,7 +1859,7 @@ intelfbhw_cursor_show(struct intelfb_info *dinfo) | |||
| 1807 | if (dinfo->cursor_blanked) | 1859 | if (dinfo->cursor_blanked) |
| 1808 | return; | 1860 | return; |
| 1809 | 1861 | ||
| 1810 | if (dinfo->mobile || IS_I9xx(dinfo)) { | 1862 | if (dinfo->mobile || IS_I9XX(dinfo)) { |
| 1811 | if (!dinfo->cursor.physical) | 1863 | if (!dinfo->cursor.physical) |
| 1812 | return; | 1864 | return; |
| 1813 | tmp = INREG(CURSOR_A_CONTROL); | 1865 | tmp = INREG(CURSOR_A_CONTROL); |
| @@ -1833,8 +1885,8 @@ intelfbhw_cursor_setpos(struct intelfb_info *dinfo, int x, int y) | |||
| 1833 | #endif | 1885 | #endif |
| 1834 | 1886 | ||
| 1835 | /* | 1887 | /* |
| 1836 | * Sets the position. The coordinates are assumed to already | 1888 | * Sets the position. The coordinates are assumed to already |
| 1837 | * have any offset adjusted. Assume that the cursor is never | 1889 | * have any offset adjusted. Assume that the cursor is never |
| 1838 | * completely off-screen, and that x, y are always >= 0. | 1890 | * completely off-screen, and that x, y are always >= 0. |
| 1839 | */ | 1891 | */ |
| 1840 | 1892 | ||
| @@ -1842,7 +1894,7 @@ intelfbhw_cursor_setpos(struct intelfb_info *dinfo, int x, int y) | |||
| 1842 | ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT); | 1894 | ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT); |
| 1843 | OUTREG(CURSOR_A_POSITION, tmp); | 1895 | OUTREG(CURSOR_A_POSITION, tmp); |
| 1844 | 1896 | ||
| 1845 | if (IS_I9xx(dinfo)) { | 1897 | if (IS_I9XX(dinfo)) { |
| 1846 | OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.physical); | 1898 | OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.physical); |
| 1847 | } | 1899 | } |
| 1848 | } | 1900 | } |
diff --git a/drivers/video/intelfb/intelfbhw.h b/drivers/video/intelfb/intelfbhw.h index a3ec8f92eb64..10acda098b71 100644 --- a/drivers/video/intelfb/intelfbhw.h +++ b/drivers/video/intelfb/intelfbhw.h | |||
| @@ -133,6 +133,7 @@ | |||
| 133 | #define DPLL_VGA_MODE_DISABLE (1 << 28) | 133 | #define DPLL_VGA_MODE_DISABLE (1 << 28) |
| 134 | #define DPLL_P2_MASK 1 | 134 | #define DPLL_P2_MASK 1 |
| 135 | #define DPLL_P2_SHIFT 23 | 135 | #define DPLL_P2_SHIFT 23 |
| 136 | #define DPLL_I9XX_P2_SHIFT 24 | ||
| 136 | #define DPLL_P1_FORCE_DIV2 (1 << 21) | 137 | #define DPLL_P1_FORCE_DIV2 (1 << 21) |
| 137 | #define DPLL_P1_MASK 0x1f | 138 | #define DPLL_P1_MASK 0x1f |
| 138 | #define DPLL_P1_SHIFT 16 | 139 | #define DPLL_P1_SHIFT 16 |
