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 /drivers/video/via | |
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>
Diffstat (limited to 'drivers/video/via')
-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); |