aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/via/hw.c
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/hw.c
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/hw.c')
-rw-r--r--drivers/video/via/hw.c73
1 files changed, 23 insertions, 50 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
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)