aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/aty
diff options
context:
space:
mode:
authorVille Syrjala <syrjala@sci.fi>2009-06-30 14:41:42 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-30 21:56:01 -0400
commitee905d0c58a440a5bd10c845e8305f6f7f706be2 (patch)
tree0d67b5e021dd947ef047d722ff7872db2e38afa3 /drivers/video/aty
parenteafad22a05fdaca60f06433ffe8810aaa920d539 (diff)
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>
Diffstat (limited to 'drivers/video/aty')
-rw-r--r--drivers/video/aty/atyfb.h1
-rw-r--r--drivers/video/aty/atyfb_base.c52
-rw-r--r--drivers/video/aty/mach64_accel.c7
3 files changed, 46 insertions, 14 deletions
diff --git a/drivers/video/aty/atyfb.h b/drivers/video/aty/atyfb.h
index 0369653b5d88..1f39a62f899b 100644
--- a/drivers/video/aty/atyfb.h
+++ b/drivers/video/aty/atyfb.h
@@ -219,6 +219,7 @@ struct atyfb_par {
219#define M64F_XL_DLL 0x00080000 219#define M64F_XL_DLL 0x00080000
220#define M64F_MFB_FORCE_4 0x00100000 220#define M64F_MFB_FORCE_4 0x00100000
221#define M64F_HW_TRIPLE 0x00200000 221#define M64F_HW_TRIPLE 0x00200000
222#define M64F_XL_MEM 0x00400000
222 /* 223 /*
223 * Register access 224 * Register access
224 */ 225 */
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 06782906daf5..63d3739d43a8 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -363,8 +363,8 @@ static unsigned long phys_guiregbase[FB_MAX] __devinitdata = { 0, };
363#define ATI_CHIP_264GTPRO (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D) 363#define ATI_CHIP_264GTPRO (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D)
364#define ATI_CHIP_264LTPRO (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D) 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) 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_MOBIL_BUS) 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
369static struct { 369static struct {
370 u16 pci_id; 370 u16 pci_id;
@@ -541,6 +541,7 @@ static char ram_edo[] __devinitdata = "EDO";
541static char ram_sdram[] __devinitdata = "SDRAM (1:1)"; 541static char ram_sdram[] __devinitdata = "SDRAM (1:1)";
542static char ram_sgram[] __devinitdata = "SGRAM (1:1)"; 542static char ram_sgram[] __devinitdata = "SGRAM (1:1)";
543static char ram_sdram32[] __devinitdata = "SDRAM (2:1) (32-bit)"; 543static char ram_sdram32[] __devinitdata = "SDRAM (2:1) (32-bit)";
544static char ram_wram[] __devinitdata = "WRAM";
544static char ram_off[] __devinitdata = "OFF"; 545static char ram_off[] __devinitdata = "OFF";
545#endif /* CONFIG_FB_ATY_CT */ 546#endif /* CONFIG_FB_ATY_CT */
546 547
@@ -555,6 +556,10 @@ static char *aty_gx_ram[8] __devinitdata = {
555#ifdef CONFIG_FB_ATY_CT 556#ifdef CONFIG_FB_ATY_CT
556static char *aty_ct_ram[8] __devinitdata = { 557static char *aty_ct_ram[8] __devinitdata = {
557 ram_off, ram_dram, ram_edo, ram_edo, 558 ram_off, ram_dram, ram_edo, ram_edo,
559 ram_sdram, ram_sgram, ram_wram, ram_resv
560};
561static char *aty_xl_ram[8] __devinitdata = {
562 ram_off, ram_dram, ram_edo, ram_edo,
558 ram_sdram, ram_sgram, ram_sdram32, ram_resv 563 ram_sdram, ram_sgram, ram_sdram32, ram_resv
559}; 564};
560#endif /* CONFIG_FB_ATY_CT */ 565#endif /* CONFIG_FB_ATY_CT */
@@ -762,6 +767,17 @@ static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc)
762#endif /* CONFIG_FB_ATY_GENERIC_LCD */ 767#endif /* CONFIG_FB_ATY_GENERIC_LCD */
763} 768}
764 769
770static u32 calc_line_length(struct atyfb_par *par, u32 vxres, u32 bpp)
771{
772 u32 line_length = vxres * bpp / 8;
773
774 if (par->ram_type == SGRAM ||
775 (!M64_HAS(XL_MEM) && par->ram_type == WRAM))
776 line_length = (line_length + 63) & ~63;
777
778 return line_length;
779}
780
765static int aty_var_to_crtc(const struct fb_info *info, 781static int aty_var_to_crtc(const struct fb_info *info,
766 const struct fb_var_screeninfo *var, struct crtc *crtc) 782 const struct fb_var_screeninfo *var, struct crtc *crtc)
767{ 783{
@@ -771,13 +787,14 @@ static int aty_var_to_crtc(const struct fb_info *info,
771 u32 h_total, h_disp, h_sync_strt, h_sync_end, h_sync_dly, h_sync_wid, h_sync_pol; 787 u32 h_total, h_disp, h_sync_strt, h_sync_end, h_sync_dly, h_sync_wid, h_sync_pol;
772 u32 v_total, v_disp, v_sync_strt, v_sync_end, v_sync_wid, v_sync_pol, c_sync; 788 u32 v_total, v_disp, v_sync_strt, v_sync_end, v_sync_wid, v_sync_pol, c_sync;
773 u32 pix_width, dp_pix_width, dp_chain_mask; 789 u32 pix_width, dp_pix_width, dp_chain_mask;
790 u32 line_length;
774 791
775 /* input */ 792 /* input */
776 xres = var->xres; 793 xres = (var->xres + 7) & ~7;
777 yres = var->yres; 794 yres = var->yres;
778 vxres = var->xres_virtual; 795 vxres = (var->xres_virtual + 7) & ~7;
779 vyres = var->yres_virtual; 796 vyres = var->yres_virtual;
780 xoffset = var->xoffset; 797 xoffset = (var->xoffset + 7) & ~7;
781 yoffset = var->yoffset; 798 yoffset = var->yoffset;
782 bpp = var->bits_per_pixel; 799 bpp = var->bits_per_pixel;
783 if (bpp == 16) 800 if (bpp == 16)
@@ -829,7 +846,9 @@ static int aty_var_to_crtc(const struct fb_info *info,
829 } else 846 } else
830 FAIL("invalid bpp"); 847 FAIL("invalid bpp");
831 848
832 if (vxres * vyres * bpp / 8 > info->fix.smem_len) 849 line_length = calc_line_length(par, vxres, bpp);
850
851 if (vyres * line_length > info->fix.smem_len)
833 FAIL("not enough video RAM"); 852 FAIL("not enough video RAM");
834 853
835 h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1; 854 h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
@@ -971,7 +990,9 @@ static int aty_var_to_crtc(const struct fb_info *info,
971 crtc->xoffset = xoffset; 990 crtc->xoffset = xoffset;
972 crtc->yoffset = yoffset; 991 crtc->yoffset = yoffset;
973 crtc->bpp = bpp; 992 crtc->bpp = bpp;
974 crtc->off_pitch = ((yoffset*vxres+xoffset)*bpp/64) | (vxres<<19); 993 crtc->off_pitch =
994 ((yoffset * line_length + xoffset * bpp / 8) / 8) |
995 ((line_length / bpp) << 22);
975 crtc->vline_crnt_vline = 0; 996 crtc->vline_crnt_vline = 0;
976 997
977 crtc->h_tot_disp = h_total | (h_disp<<16); 998 crtc->h_tot_disp = h_total | (h_disp<<16);
@@ -1396,7 +1417,9 @@ static int atyfb_set_par(struct fb_info *info)
1396 } 1417 }
1397 aty_st_8(DAC_MASK, 0xff, par); 1418 aty_st_8(DAC_MASK, 0xff, par);
1398 1419
1399 info->fix.line_length = var->xres_virtual * var->bits_per_pixel/8; 1420 info->fix.line_length = calc_line_length(par, var->xres_virtual,
1421 var->bits_per_pixel);
1422
1400 info->fix.visual = var->bits_per_pixel <= 8 ? 1423 info->fix.visual = var->bits_per_pixel <= 8 ?
1401 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR; 1424 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
1402 1425
@@ -1507,10 +1530,12 @@ static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info)
1507{ 1530{
1508 u32 xoffset = info->var.xoffset; 1531 u32 xoffset = info->var.xoffset;
1509 u32 yoffset = info->var.yoffset; 1532 u32 yoffset = info->var.yoffset;
1510 u32 vxres = par->crtc.vxres; 1533 u32 line_length = info->fix.line_length;
1511 u32 bpp = info->var.bits_per_pixel; 1534 u32 bpp = info->var.bits_per_pixel;
1512 1535
1513 par->crtc.off_pitch = ((yoffset * vxres + xoffset) * bpp / 64) | (vxres << 19); 1536 par->crtc.off_pitch =
1537 ((yoffset * line_length + xoffset * bpp / 8) / 8) |
1538 ((line_length / bpp) << 22);
1514} 1539}
1515 1540
1516 1541
@@ -2203,7 +2228,7 @@ static void __devinit aty_calc_mem_refresh(struct atyfb_par *par, int xclk)
2203 const int *refresh_tbl; 2228 const int *refresh_tbl;
2204 int i, size; 2229 int i, size;
2205 2230
2206 if (IS_XL(par->pci_id) || IS_MOBILITY(par->pci_id)) { 2231 if (M64_HAS(XL_MEM)) {
2207 refresh_tbl = ragexl_tbl; 2232 refresh_tbl = ragexl_tbl;
2208 size = ARRAY_SIZE(ragexl_tbl); 2233 size = ARRAY_SIZE(ragexl_tbl);
2209 } else { 2234 } else {
@@ -2337,7 +2362,10 @@ static int __devinit aty_init(struct fb_info *info)
2337 par->pll_ops = &aty_pll_ct; 2362 par->pll_ops = &aty_pll_ct;
2338 par->bus_type = PCI; 2363 par->bus_type = PCI;
2339 par->ram_type = (aty_ld_le32(CNFG_STAT0, par) & 0x07); 2364 par->ram_type = (aty_ld_le32(CNFG_STAT0, par) & 0x07);
2340 ramname = aty_ct_ram[par->ram_type]; 2365 if (M64_HAS(XL_MEM))
2366 ramname = aty_xl_ram[par->ram_type];
2367 else
2368 ramname = aty_ct_ram[par->ram_type];
2341 /* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */ 2369 /* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */
2342 if (par->pll_limits.mclk == 67 && par->ram_type < SDRAM) 2370 if (par->pll_limits.mclk == 67 && par->ram_type < SDRAM)
2343 par->pll_limits.mclk = 63; 2371 par->pll_limits.mclk = 63;
diff --git a/drivers/video/aty/mach64_accel.c b/drivers/video/aty/mach64_accel.c
index 0cc9724e61a2..51fcc0a2c94a 100644
--- a/drivers/video/aty/mach64_accel.c
+++ b/drivers/video/aty/mach64_accel.c
@@ -63,14 +63,17 @@ static void reset_GTC_3D_engine(const struct atyfb_par *par)
63void aty_init_engine(struct atyfb_par *par, struct fb_info *info) 63void aty_init_engine(struct atyfb_par *par, struct fb_info *info)
64{ 64{
65 u32 pitch_value; 65 u32 pitch_value;
66 u32 vxres;
66 67
67 /* determine modal information from global mode structure */ 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 if (info->var.bits_per_pixel == 24) { 72 if (info->var.bits_per_pixel == 24) {
71 /* In 24 bpp, the engine is in 8 bpp - this requires that all */ 73 /* In 24 bpp, the engine is in 8 bpp - this requires that all */
72 /* horizontal coordinates and widths must be adjusted */ 74 /* horizontal coordinates and widths must be adjusted */
73 pitch_value *= 3; 75 pitch_value *= 3;
76 vxres *= 3;
74 } 77 }
75 78
76 /* On GTC (RagePro), we need to reset the 3D engine before */ 79 /* On GTC (RagePro), we need to reset the 3D engine before */
@@ -133,7 +136,7 @@ void aty_init_engine(struct atyfb_par *par, struct fb_info *info)
133 aty_st_le32(SC_LEFT, 0, par); 136 aty_st_le32(SC_LEFT, 0, par);
134 aty_st_le32(SC_TOP, 0, par); 137 aty_st_le32(SC_TOP, 0, par);
135 aty_st_le32(SC_BOTTOM, par->crtc.vyres - 1, par); 138 aty_st_le32(SC_BOTTOM, par->crtc.vyres - 1, par);
136 aty_st_le32(SC_RIGHT, pitch_value - 1, par); 139 aty_st_le32(SC_RIGHT, vxres - 1, par);
137 140
138 /* set background color to minimum value (usually BLACK) */ 141 /* set background color to minimum value (usually BLACK) */
139 aty_st_le32(DP_BKGD_CLR, 0, par); 142 aty_st_le32(DP_BKGD_CLR, 0, par);