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/hw.c | |
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/hw.c')
-rw-r--r-- | drivers/video/via/hw.c | 73 |
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 | ||
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) |