aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/via
diff options
context:
space:
mode:
authorFlorian Tobias Schandinat <FlorianSchandinat@gmx.de>2009-09-22 19:47:29 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-23 10:39:53 -0400
commit2d6e8851f608bd0c811f2df83eeff4ad8631e723 (patch)
tree76aad6e6e48a294d742acc4a0751e5d8ab86bf50 /drivers/video/via
parent5016af53ebbd1450c2656c94dfbd1dad15c19f60 (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.c73
-rw-r--r--drivers/video/via/hw.h33
-rw-r--r--drivers/video/via/lcd.c10
-rw-r--r--drivers/video/via/viafbdev.c3
-rw-r--r--drivers/video/via/viafbdev.h1
5 files changed, 27 insertions, 93 deletions
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c
index 86050e79b89..4910561a9d3 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
39struct 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
46static struct pll_map pll_value[] = { 39static 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
644void 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
655void 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
651void viafb_set_output_path(int device, int set_iga, int output_interface) 664void 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
1079void 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
1103void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga) 1092void 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
2741void 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*/
2760void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh, 2733void 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 cf1dfd5c7fd..817033d2d3b 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 */
621struct iga1_offset {
622 int reg_num;
623 struct io_register reg[IGA1_OFFSET_REG_NUM];
624};
625
626/* IGA2 Offset Register */
627struct iga2_offset {
628 int reg_num;
629 struct io_register reg[IGA2_OFFSET_REG_NUM];
630};
631
632struct 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 */
638struct iga1_fetch_count { 610struct 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);
904u8 viafb_read_reg(int io_port, u8 index); 876u8 viafb_read_reg(int io_port, u8 index);
905void viafb_lock_crt(void); 877void viafb_lock_crt(void);
906void viafb_unlock_crt(void); 878void viafb_unlock_crt(void);
907void viafb_load_offset_reg(int h_addr, int bpp_byte, int set_iga);
908void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga); 879void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga);
909void viafb_write_regx(struct io_reg RegTable[], int ItemNum); 880void viafb_write_regx(struct io_reg RegTable[], int ItemNum);
910struct VideoModeTable *viafb_get_modetbl_pointer(int Index); 881struct VideoModeTable *viafb_get_modetbl_pointer(int Index);
@@ -928,6 +899,8 @@ void viafb_get_mmio_info(unsigned long *mmio_base, u32 *mmio_len);
928void viafb_set_iga_path(void); 899void viafb_set_iga_path(void);
929void viafb_set_primary_address(u32 addr); 900void viafb_set_primary_address(u32 addr);
930void viafb_set_secondary_address(u32 addr); 901void viafb_set_secondary_address(u32 addr);
902void viafb_set_primary_pitch(u32 pitch);
903void viafb_set_secondary_pitch(u32 pitch);
931void viafb_get_fb_info(unsigned int *fb_base, unsigned int *fb_len); 904void 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 144d34bdf0a..e3e597f937a 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 03f98d68320..e9c9f0ec842 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 ca39ec1689e..159619bc80b 100644
--- a/drivers/video/via/viafbdev.h
+++ b/drivers/video/via/viafbdev.h
@@ -97,7 +97,6 @@ extern int viafb_memsize;
97extern int strict_strtoul(const char *cp, unsigned int base, 97extern int strict_strtoul(const char *cp, unsigned int base,
98 unsigned long *res); 98 unsigned long *res);
99 99
100void viafb_memory_pitch_patch(struct fb_info *info);
101void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh, 100void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh,
102 int mode_index); 101 int mode_index);
103int viafb_get_mode_index(int hres, int vres); 102int viafb_get_mode_index(int hres, int vres);