Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

atyfb: fix alignment for block writes

Block writes require 64 byte alignment. Since block writes could be used
with SGRAM or WRAM also refine the memory type detection to check for
either type before deciding to use the 64 byte alignment.

Signed-off-by: Ville Syrjala <syrjala@sci.fi>
Tested-by: Mikulas Patocka <mpatocka@redhat.com>
Cc: Krzysztof Helt <krzysztof.h1@poczta.fm>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Ville Syrjala and committed by
Linus Torvalds
ee905d0c eafad22a

+46 -14
+1
drivers/video/aty/atyfb.h
··· 219 219 #define M64F_XL_DLL 0x00080000 220 220 #define M64F_MFB_FORCE_4 0x00100000 221 221 #define M64F_HW_TRIPLE 0x00200000 222 + #define M64F_XL_MEM 0x00400000 222 223 /* 223 224 * Register access 224 225 */
+40 -12
drivers/video/aty/atyfb_base.c
··· 363 363 #define ATI_CHIP_264GTPRO (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D) 364 364 #define ATI_CHIP_264LTPRO (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D) 365 365 366 - #define ATI_CHIP_264XL (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4) 367 - #define ATI_CHIP_MOBILITY (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4 | M64F_MOBIL_BUS) 366 + #define ATI_CHIP_264XL (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4 | M64F_XL_MEM) 367 + #define ATI_CHIP_MOBILITY (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4 | M64F_XL_MEM | M64F_MOBIL_BUS) 368 368 369 369 static struct { 370 370 u16 pci_id; ··· 541 541 static char ram_sdram[] __devinitdata = "SDRAM (1:1)"; 542 542 static char ram_sgram[] __devinitdata = "SGRAM (1:1)"; 543 543 static char ram_sdram32[] __devinitdata = "SDRAM (2:1) (32-bit)"; 544 + static char ram_wram[] __devinitdata = "WRAM"; 544 545 static char ram_off[] __devinitdata = "OFF"; 545 546 #endif /* CONFIG_FB_ATY_CT */ 546 547 ··· 555 554 556 555 #ifdef CONFIG_FB_ATY_CT 557 556 static char *aty_ct_ram[8] __devinitdata = { 557 + ram_off, ram_dram, ram_edo, ram_edo, 558 + ram_sdram, ram_sgram, ram_wram, ram_resv 559 + }; 560 + static char *aty_xl_ram[8] __devinitdata = { 558 561 ram_off, ram_dram, ram_edo, ram_edo, 559 562 ram_sdram, ram_sgram, ram_sdram32, ram_resv 560 563 }; ··· 767 762 #endif /* CONFIG_FB_ATY_GENERIC_LCD */ 768 763 } 769 764 765 + static u32 calc_line_length(struct atyfb_par *par, u32 vxres, u32 bpp) 766 + { 767 + u32 line_length = vxres * bpp / 8; 768 + 769 + if (par->ram_type == SGRAM || 770 + (!M64_HAS(XL_MEM) && par->ram_type == WRAM)) 771 + line_length = (line_length + 63) & ~63; 772 + 773 + return line_length; 774 + } 775 + 770 776 static int aty_var_to_crtc(const struct fb_info *info, 771 777 const struct fb_var_screeninfo *var, struct crtc *crtc) 772 778 { ··· 787 771 u32 h_total, h_disp, h_sync_strt, h_sync_end, h_sync_dly, h_sync_wid, h_sync_pol; 788 772 u32 v_total, v_disp, v_sync_strt, v_sync_end, v_sync_wid, v_sync_pol, c_sync; 789 773 u32 pix_width, dp_pix_width, dp_chain_mask; 774 + u32 line_length; 790 775 791 776 /* input */ 792 - xres = var->xres; 777 + xres = (var->xres + 7) & ~7; 793 778 yres = var->yres; 794 - vxres = var->xres_virtual; 779 + vxres = (var->xres_virtual + 7) & ~7; 795 780 vyres = var->yres_virtual; 796 - xoffset = var->xoffset; 781 + xoffset = (var->xoffset + 7) & ~7; 797 782 yoffset = var->yoffset; 798 783 bpp = var->bits_per_pixel; 799 784 if (bpp == 16) ··· 846 829 } else 847 830 FAIL("invalid bpp"); 848 831 849 - if (vxres * vyres * bpp / 8 > info->fix.smem_len) 832 + line_length = calc_line_length(par, vxres, bpp); 833 + 834 + if (vyres * line_length > info->fix.smem_len) 850 835 FAIL("not enough video RAM"); 851 836 852 837 h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1; ··· 990 971 crtc->xoffset = xoffset; 991 972 crtc->yoffset = yoffset; 992 973 crtc->bpp = bpp; 993 - crtc->off_pitch = ((yoffset*vxres+xoffset)*bpp/64) | (vxres<<19); 974 + crtc->off_pitch = 975 + ((yoffset * line_length + xoffset * bpp / 8) / 8) | 976 + ((line_length / bpp) << 22); 994 977 crtc->vline_crnt_vline = 0; 995 978 996 979 crtc->h_tot_disp = h_total | (h_disp<<16); ··· 1417 1396 } 1418 1397 aty_st_8(DAC_MASK, 0xff, par); 1419 1398 1420 - info->fix.line_length = var->xres_virtual * var->bits_per_pixel/8; 1399 + info->fix.line_length = calc_line_length(par, var->xres_virtual, 1400 + var->bits_per_pixel); 1401 + 1421 1402 info->fix.visual = var->bits_per_pixel <= 8 ? 1422 1403 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR; 1423 1404 ··· 1530 1507 { 1531 1508 u32 xoffset = info->var.xoffset; 1532 1509 u32 yoffset = info->var.yoffset; 1533 - u32 vxres = par->crtc.vxres; 1510 + u32 line_length = info->fix.line_length; 1534 1511 u32 bpp = info->var.bits_per_pixel; 1535 1512 1536 - par->crtc.off_pitch = ((yoffset * vxres + xoffset) * bpp / 64) | (vxres << 19); 1513 + par->crtc.off_pitch = 1514 + ((yoffset * line_length + xoffset * bpp / 8) / 8) | 1515 + ((line_length / bpp) << 22); 1537 1516 } 1538 1517 1539 1518 ··· 2228 2203 const int *refresh_tbl; 2229 2204 int i, size; 2230 2205 2231 - if (IS_XL(par->pci_id) || IS_MOBILITY(par->pci_id)) { 2206 + if (M64_HAS(XL_MEM)) { 2232 2207 refresh_tbl = ragexl_tbl; 2233 2208 size = ARRAY_SIZE(ragexl_tbl); 2234 2209 } else { ··· 2362 2337 par->pll_ops = &aty_pll_ct; 2363 2338 par->bus_type = PCI; 2364 2339 par->ram_type = (aty_ld_le32(CNFG_STAT0, par) & 0x07); 2365 - ramname = aty_ct_ram[par->ram_type]; 2340 + if (M64_HAS(XL_MEM)) 2341 + ramname = aty_xl_ram[par->ram_type]; 2342 + else 2343 + ramname = aty_ct_ram[par->ram_type]; 2366 2344 /* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */ 2367 2345 if (par->pll_limits.mclk == 67 && par->ram_type < SDRAM) 2368 2346 par->pll_limits.mclk = 63;
+5 -2
drivers/video/aty/mach64_accel.c
··· 63 63 void aty_init_engine(struct atyfb_par *par, struct fb_info *info) 64 64 { 65 65 u32 pitch_value; 66 + u32 vxres; 66 67 67 68 /* determine modal information from global mode structure */ 68 - pitch_value = info->var.xres_virtual; 69 + pitch_value = info->fix.line_length / (info->var.bits_per_pixel / 8); 70 + vxres = info->var.xres_virtual; 69 71 70 72 if (info->var.bits_per_pixel == 24) { 71 73 /* In 24 bpp, the engine is in 8 bpp - this requires that all */ 72 74 /* horizontal coordinates and widths must be adjusted */ 73 75 pitch_value *= 3; 76 + vxres *= 3; 74 77 } 75 78 76 79 /* On GTC (RagePro), we need to reset the 3D engine before */ ··· 136 133 aty_st_le32(SC_LEFT, 0, par); 137 134 aty_st_le32(SC_TOP, 0, par); 138 135 aty_st_le32(SC_BOTTOM, par->crtc.vyres - 1, par); 139 - aty_st_le32(SC_RIGHT, pitch_value - 1, par); 136 + aty_st_le32(SC_RIGHT, vxres - 1, par); 140 137 141 138 /* set background color to minimum value (usually BLACK) */ 142 139 aty_st_le32(DP_BKGD_CLR, 0, par);