diff options
| author | Florian Tobias Schandinat <FlorianSchandinat@gmx.de> | 2009-09-22 19:47:29 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-23 10:39:53 -0400 |
| commit | 2d6e8851f608bd0c811f2df83eeff4ad8631e723 (patch) | |
| tree | 76aad6e6e48a294d742acc4a0751e5d8ab86bf50 | |
| parent | 5016af53ebbd1450c2656c94dfbd1dad15c19f60 (diff) | |
viafb: improve pitch handling
Split the pitch handling up and replaces the calculation from virtual xres
and bpp with fix.line_length which already contains the pitch and does not
add any constrains for the virtual resolution.
Also add a bit to the second pitch which the documentation mentions but
which was ignored by the driver.
Although it is a bit unclear what the right pitch for some LCD modes is
this patch should have no negative runtime impact.
Signed-off-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
Cc: Scott Fang <ScottFang@viatech.com.cn>
Cc: Joseph Chan <JosephChan@via.com.tw>
Cc: Harald Welte <laforge@gnumonks.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
| -rw-r--r-- | drivers/video/via/hw.c | 73 | ||||
| -rw-r--r-- | drivers/video/via/hw.h | 33 | ||||
| -rw-r--r-- | drivers/video/via/lcd.c | 10 | ||||
| -rw-r--r-- | drivers/video/via/viafbdev.c | 3 | ||||
| -rw-r--r-- | drivers/video/via/viafbdev.h | 1 |
5 files changed, 27 insertions, 93 deletions
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index 86050e79b892..4910561a9d34 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c | |||
| @@ -36,13 +36,6 @@ static const struct pci_device_id_info pciidlist[] = { | |||
| 36 | {0, 0, 0} | 36 | {0, 0, 0} |
| 37 | }; | 37 | }; |
| 38 | 38 | ||
| 39 | struct offset offset_reg = { | ||
| 40 | /* IGA1 Offset Register */ | ||
| 41 | {IGA1_OFFSET_REG_NUM, {{CR13, 0, 7}, {CR35, 5, 7} } }, | ||
| 42 | /* IGA2 Offset Register */ | ||
| 43 | {IGA2_OFFSET_REG_NUM, {{CR66, 0, 7}, {CR67, 0, 1} } } | ||
| 44 | }; | ||
| 45 | |||
| 46 | static struct pll_map pll_value[] = { | 39 | static struct pll_map pll_value[] = { |
| 47 | {CLK_25_175M, CLE266_PLL_25_175M, K800_PLL_25_175M, CX700_25_175M}, | 40 | {CLK_25_175M, CLE266_PLL_25_175M, K800_PLL_25_175M, CX700_25_175M}, |
| 48 | {CLK_29_581M, CLE266_PLL_29_581M, K800_PLL_29_581M, CX700_29_581M}, | 41 | {CLK_29_581M, CLE266_PLL_29_581M, K800_PLL_29_581M, CX700_29_581M}, |
| @@ -648,6 +641,26 @@ void viafb_set_secondary_address(u32 addr) | |||
| 648 | viafb_write_reg_mask(CRA3, VIACR, (addr >> 26) & 0x07, 0x07); | 641 | viafb_write_reg_mask(CRA3, VIACR, (addr >> 26) & 0x07, 0x07); |
| 649 | } | 642 | } |
| 650 | 643 | ||
| 644 | void viafb_set_primary_pitch(u32 pitch) | ||
| 645 | { | ||
| 646 | DEBUG_MSG(KERN_DEBUG "viafb_set_primary_pitch(0x%08X)\n", pitch); | ||
| 647 | /* spec does not say that first adapter skips 3 bits but old | ||
| 648 | * code did it and seems to be reasonable in analogy to 2nd adapter | ||
| 649 | */ | ||
| 650 | pitch = pitch >> 3; | ||
| 651 | viafb_write_reg(0x13, VIACR, pitch & 0xFF); | ||
| 652 | viafb_write_reg_mask(0x35, VIACR, (pitch >> (8 - 5)) & 0xE0, 0xE0); | ||
| 653 | } | ||
| 654 | |||
| 655 | void viafb_set_secondary_pitch(u32 pitch) | ||
| 656 | { | ||
| 657 | DEBUG_MSG(KERN_DEBUG "viafb_set_secondary_pitch(0x%08X)\n", pitch); | ||
| 658 | pitch = pitch >> 3; | ||
| 659 | viafb_write_reg(0x66, VIACR, pitch & 0xFF); | ||
| 660 | viafb_write_reg_mask(0x67, VIACR, (pitch >> 8) & 0x03, 0x03); | ||
| 661 | viafb_write_reg_mask(0x71, VIACR, (pitch >> (10 - 7)) & 0x80, 0x80); | ||
| 662 | } | ||
| 663 | |||
| 651 | void viafb_set_output_path(int device, int set_iga, int output_interface) | 664 | void viafb_set_output_path(int device, int set_iga, int output_interface) |
| 652 | { | 665 | { |
| 653 | switch (device) { | 666 | switch (device) { |
| @@ -1076,30 +1089,6 @@ void viafb_write_regx(struct io_reg RegTable[], int ItemNum) | |||
| 1076 | } | 1089 | } |
| 1077 | } | 1090 | } |
| 1078 | 1091 | ||
| 1079 | void viafb_load_offset_reg(int h_addr, int bpp_byte, int set_iga) | ||
| 1080 | { | ||
| 1081 | int reg_value; | ||
| 1082 | int viafb_load_reg_num; | ||
| 1083 | struct io_register *reg; | ||
| 1084 | |||
| 1085 | switch (set_iga) { | ||
| 1086 | case IGA1_IGA2: | ||
| 1087 | case IGA1: | ||
| 1088 | reg_value = IGA1_OFFSET_FORMULA(h_addr, bpp_byte); | ||
| 1089 | viafb_load_reg_num = offset_reg.iga1_offset_reg.reg_num; | ||
| 1090 | reg = offset_reg.iga1_offset_reg.reg; | ||
| 1091 | viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR); | ||
| 1092 | if (set_iga == IGA1) | ||
| 1093 | break; | ||
| 1094 | case IGA2: | ||
| 1095 | reg_value = IGA2_OFFSET_FORMULA(h_addr, bpp_byte); | ||
| 1096 | viafb_load_reg_num = offset_reg.iga2_offset_reg.reg_num; | ||
| 1097 | reg = offset_reg.iga2_offset_reg.reg; | ||
| 1098 | viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR); | ||
| 1099 | break; | ||
| 1100 | } | ||
| 1101 | } | ||
| 1102 | |||
| 1103 | void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga) | 1092 | void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga) |
| 1104 | { | 1093 | { |
| 1105 | int reg_value; | 1094 | int reg_value; |
| @@ -1869,7 +1858,6 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, | |||
| 1869 | load_fix_bit_crtc_reg(); | 1858 | load_fix_bit_crtc_reg(); |
| 1870 | viafb_lock_crt(); | 1859 | viafb_lock_crt(); |
| 1871 | viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7); | 1860 | viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7); |
| 1872 | viafb_load_offset_reg(h_addr, bpp_byte, set_iga); | ||
| 1873 | viafb_load_fetch_count_reg(h_addr, bpp_byte, set_iga); | 1861 | viafb_load_fetch_count_reg(h_addr, bpp_byte, set_iga); |
| 1874 | 1862 | ||
| 1875 | /* load FIFO */ | 1863 | /* load FIFO */ |
| @@ -2322,6 +2310,9 @@ int viafb_setmode(int vmode_index, int hor_res, int ver_res, int video_bpp, | |||
| 2322 | } | 2310 | } |
| 2323 | } | 2311 | } |
| 2324 | 2312 | ||
| 2313 | viafb_set_primary_pitch(viafbinfo->fix.line_length); | ||
| 2314 | viafb_set_secondary_pitch(viafb_dual_fb ? viafbinfo1->fix.line_length | ||
| 2315 | : viafbinfo->fix.line_length); | ||
| 2325 | /* Update Refresh Rate Setting */ | 2316 | /* Update Refresh Rate Setting */ |
| 2326 | 2317 | ||
| 2327 | /* Clear On Screen */ | 2318 | /* Clear On Screen */ |
| @@ -2738,24 +2729,6 @@ void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\ | |||
| 2738 | } | 2729 | } |
| 2739 | } | 2730 | } |
| 2740 | 2731 | ||
| 2741 | void viafb_memory_pitch_patch(struct fb_info *info) | ||
| 2742 | { | ||
| 2743 | if (info->var.xres != info->var.xres_virtual) { | ||
| 2744 | viafb_load_offset_reg(info->var.xres_virtual, | ||
| 2745 | info->var.bits_per_pixel >> 3, IGA1); | ||
| 2746 | |||
| 2747 | if (viafb_SAMM_ON) { | ||
| 2748 | viafb_load_offset_reg(viafb_second_virtual_xres, | ||
| 2749 | viafb_bpp1 >> 3, | ||
| 2750 | IGA2); | ||
| 2751 | } else { | ||
| 2752 | viafb_load_offset_reg(info->var.xres_virtual, | ||
| 2753 | info->var.bits_per_pixel >> 3, IGA2); | ||
| 2754 | } | ||
| 2755 | |||
| 2756 | } | ||
| 2757 | } | ||
| 2758 | |||
| 2759 | /*According var's xres, yres fill var's other timing information*/ | 2732 | /*According var's xres, yres fill var's other timing information*/ |
| 2760 | void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh, | 2733 | void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh, |
| 2761 | int mode_index) | 2734 | int mode_index) |
diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h index cf1dfd5c7fdf..817033d2d3be 100644 --- a/drivers/video/via/hw.h +++ b/drivers/video/via/hw.h | |||
| @@ -147,14 +147,8 @@ is reserved, so it may have problem to set 1600x1200 on IGA2. */ | |||
| 147 | /* location: {CR5F,0,4} */ | 147 | /* location: {CR5F,0,4} */ |
| 148 | #define IGA2_VER_SYNC_END_REG_NUM 1 | 148 | #define IGA2_VER_SYNC_END_REG_NUM 1 |
| 149 | 149 | ||
| 150 | /* Define Offset and Fetch Count Register*/ | 150 | /* Define Fetch Count Register*/ |
| 151 | 151 | ||
| 152 | /* location: {CR13,0,7},{CR35,5,7} */ | ||
| 153 | #define IGA1_OFFSET_REG_NUM 2 | ||
| 154 | /* 8 bytes alignment. */ | ||
| 155 | #define IGA1_OFFSER_ALIGN_BYTE 8 | ||
| 156 | /* x: H resolution, y: color depth */ | ||
| 157 | #define IGA1_OFFSET_FORMULA(x, y) ((x*y)/IGA1_OFFSER_ALIGN_BYTE) | ||
| 158 | /* location: {SR1C,0,7},{SR1D,0,1} */ | 152 | /* location: {SR1C,0,7},{SR1D,0,1} */ |
| 159 | #define IGA1_FETCH_COUNT_REG_NUM 2 | 153 | #define IGA1_FETCH_COUNT_REG_NUM 2 |
| 160 | /* 16 bytes alignment. */ | 154 | /* 16 bytes alignment. */ |
| @@ -164,11 +158,6 @@ is reserved, so it may have problem to set 1600x1200 on IGA2. */ | |||
| 164 | #define IGA1_FETCH_COUNT_FORMULA(x, y) \ | 158 | #define IGA1_FETCH_COUNT_FORMULA(x, y) \ |
| 165 | (((x*y)/IGA1_FETCH_COUNT_ALIGN_BYTE) + IGA1_FETCH_COUNT_PATCH_VALUE) | 159 | (((x*y)/IGA1_FETCH_COUNT_ALIGN_BYTE) + IGA1_FETCH_COUNT_PATCH_VALUE) |
| 166 | 160 | ||
| 167 | /* location: {CR66,0,7},{CR67,0,1} */ | ||
| 168 | #define IGA2_OFFSET_REG_NUM 2 | ||
| 169 | #define IGA2_OFFSET_ALIGN_BYTE 8 | ||
| 170 | /* x: H resolution, y: color depth */ | ||
| 171 | #define IGA2_OFFSET_FORMULA(x, y) ((x*y)/IGA2_OFFSET_ALIGN_BYTE) | ||
| 172 | /* location: {CR65,0,7},{CR67,2,3} */ | 161 | /* location: {CR65,0,7},{CR67,2,3} */ |
| 173 | #define IGA2_FETCH_COUNT_REG_NUM 2 | 162 | #define IGA2_FETCH_COUNT_REG_NUM 2 |
| 174 | #define IGA2_FETCH_COUNT_ALIGN_BYTE 16 | 163 | #define IGA2_FETCH_COUNT_ALIGN_BYTE 16 |
| @@ -617,23 +606,6 @@ struct iga2_ver_sync_end { | |||
| 617 | struct io_register reg[IGA2_VER_SYNC_END_REG_NUM]; | 606 | struct io_register reg[IGA2_VER_SYNC_END_REG_NUM]; |
| 618 | }; | 607 | }; |
| 619 | 608 | ||
| 620 | /* IGA1 Offset Register */ | ||
| 621 | struct iga1_offset { | ||
| 622 | int reg_num; | ||
| 623 | struct io_register reg[IGA1_OFFSET_REG_NUM]; | ||
| 624 | }; | ||
| 625 | |||
| 626 | /* IGA2 Offset Register */ | ||
| 627 | struct iga2_offset { | ||
| 628 | int reg_num; | ||
| 629 | struct io_register reg[IGA2_OFFSET_REG_NUM]; | ||
| 630 | }; | ||
| 631 | |||
| 632 | struct offset { | ||
| 633 | struct iga1_offset iga1_offset_reg; | ||
| 634 | struct iga2_offset iga2_offset_reg; | ||
| 635 | }; | ||
| 636 | |||
| 637 | /* IGA1 Fetch Count Register */ | 609 | /* IGA1 Fetch Count Register */ |
| 638 | struct iga1_fetch_count { | 610 | struct iga1_fetch_count { |
| 639 | int reg_num; | 611 | int reg_num; |
| @@ -904,7 +876,6 @@ void viafb_write_reg(u8 index, u16 io_port, u8 data); | |||
| 904 | u8 viafb_read_reg(int io_port, u8 index); | 876 | u8 viafb_read_reg(int io_port, u8 index); |
| 905 | void viafb_lock_crt(void); | 877 | void viafb_lock_crt(void); |
| 906 | void viafb_unlock_crt(void); | 878 | void viafb_unlock_crt(void); |
| 907 | void viafb_load_offset_reg(int h_addr, int bpp_byte, int set_iga); | ||
| 908 | void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga); | 879 | void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga); |
| 909 | void viafb_write_regx(struct io_reg RegTable[], int ItemNum); | 880 | void viafb_write_regx(struct io_reg RegTable[], int ItemNum); |
| 910 | struct VideoModeTable *viafb_get_modetbl_pointer(int Index); | 881 | struct VideoModeTable *viafb_get_modetbl_pointer(int Index); |
| @@ -928,6 +899,8 @@ void viafb_get_mmio_info(unsigned long *mmio_base, u32 *mmio_len); | |||
| 928 | void viafb_set_iga_path(void); | 899 | void viafb_set_iga_path(void); |
| 929 | void viafb_set_primary_address(u32 addr); | 900 | void viafb_set_primary_address(u32 addr); |
| 930 | void viafb_set_secondary_address(u32 addr); | 901 | void viafb_set_secondary_address(u32 addr); |
| 902 | void viafb_set_primary_pitch(u32 pitch); | ||
| 903 | void viafb_set_secondary_pitch(u32 pitch); | ||
| 931 | void viafb_get_fb_info(unsigned int *fb_base, unsigned int *fb_len); | 904 | void viafb_get_fb_info(unsigned int *fb_base, unsigned int *fb_len); |
| 932 | 905 | ||
| 933 | #endif /* __HW_H__ */ | 906 | #endif /* __HW_H__ */ |
diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c index 144d34bdf0ac..e3e597f937a5 100644 --- a/drivers/video/via/lcd.c +++ b/drivers/video/via/lcd.c | |||
| @@ -952,13 +952,10 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table, | |||
| 952 | int video_index = plvds_setting_info->lcd_panel_size; | 952 | int video_index = plvds_setting_info->lcd_panel_size; |
| 953 | int set_iga = plvds_setting_info->iga_path; | 953 | int set_iga = plvds_setting_info->iga_path; |
| 954 | int mode_bpp = plvds_setting_info->bpp; | 954 | int mode_bpp = plvds_setting_info->bpp; |
| 955 | int viafb_load_reg_num = 0; | ||
| 956 | int reg_value = 0; | ||
| 957 | int set_hres, set_vres; | 955 | int set_hres, set_vres; |
| 958 | int panel_hres, panel_vres; | 956 | int panel_hres, panel_vres; |
| 959 | u32 pll_D_N; | 957 | u32 pll_D_N; |
| 960 | int offset; | 958 | int offset; |
| 961 | struct io_register *reg = NULL; | ||
| 962 | struct display_timing mode_crt_reg, panel_crt_reg; | 959 | struct display_timing mode_crt_reg, panel_crt_reg; |
| 963 | struct crt_mode_table *panel_crt_table = NULL; | 960 | struct crt_mode_table *panel_crt_table = NULL; |
| 964 | struct VideoModeTable *vmode_tbl = NULL; | 961 | struct VideoModeTable *vmode_tbl = NULL; |
| @@ -1038,16 +1035,11 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table, | |||
| 1038 | } | 1035 | } |
| 1039 | 1036 | ||
| 1040 | /* Offset for simultaneous */ | 1037 | /* Offset for simultaneous */ |
| 1041 | reg_value = offset; | 1038 | viafb_set_secondary_pitch(offset << 3); |
| 1042 | viafb_load_reg_num = offset_reg.iga2_offset_reg.reg_num; | ||
| 1043 | reg = offset_reg.iga2_offset_reg.reg; | ||
| 1044 | viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR); | ||
| 1045 | DEBUG_MSG(KERN_INFO "viafb_load_reg!!\n"); | 1039 | DEBUG_MSG(KERN_INFO "viafb_load_reg!!\n"); |
| 1046 | viafb_load_fetch_count_reg(set_hres, 4, IGA2); | 1040 | viafb_load_fetch_count_reg(set_hres, 4, IGA2); |
| 1047 | /* Fetch count for simultaneous */ | 1041 | /* Fetch count for simultaneous */ |
| 1048 | } else { /* SAMM */ | 1042 | } else { /* SAMM */ |
| 1049 | /* Offset for IGA2 only */ | ||
| 1050 | viafb_load_offset_reg(set_hres, mode_bpp / 8, set_iga); | ||
| 1051 | /* Fetch count for IGA2 only */ | 1043 | /* Fetch count for IGA2 only */ |
| 1052 | viafb_load_fetch_count_reg(set_hres, mode_bpp / 8, set_iga); | 1044 | viafb_load_fetch_count_reg(set_hres, mode_bpp / 8, set_iga); |
| 1053 | 1045 | ||
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index 03f98d683205..e9c9f0ec842a 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c | |||
| @@ -175,9 +175,6 @@ static int viafb_set_par(struct fb_info *info) | |||
| 175 | info->var.bits_per_pixel, vmode_index1, | 175 | info->var.bits_per_pixel, vmode_index1, |
| 176 | viafb_second_xres, viafb_second_yres, viafb_bpp1); | 176 | viafb_second_xres, viafb_second_yres, viafb_bpp1); |
| 177 | 177 | ||
| 178 | /*We should set memory offset according virtual_x */ | ||
| 179 | /*Fix me:put this function into viafb_setmode */ | ||
| 180 | viafb_memory_pitch_patch(info); | ||
| 181 | viafb_update_fix(info); | 178 | viafb_update_fix(info); |
| 182 | viafb_bpp = info->var.bits_per_pixel; | 179 | viafb_bpp = info->var.bits_per_pixel; |
| 183 | /* Update viafb_accel, it is necessary to our 2D accelerate */ | 180 | /* Update viafb_accel, it is necessary to our 2D accelerate */ |
diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h index ca39ec1689e1..159619bc80b1 100644 --- a/drivers/video/via/viafbdev.h +++ b/drivers/video/via/viafbdev.h | |||
| @@ -97,7 +97,6 @@ extern int viafb_memsize; | |||
| 97 | extern int strict_strtoul(const char *cp, unsigned int base, | 97 | extern int strict_strtoul(const char *cp, unsigned int base, |
| 98 | unsigned long *res); | 98 | unsigned long *res); |
| 99 | 99 | ||
| 100 | void viafb_memory_pitch_patch(struct fb_info *info); | ||
| 101 | void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh, | 100 | void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh, |
| 102 | int mode_index); | 101 | int mode_index); |
| 103 | int viafb_get_mode_index(int hres, int vres); | 102 | int viafb_get_mode_index(int hres, int vres); |
