提交 c4c6fa98 编写于 作者: B Benjamin Herrenschmidt 提交者: Linus Torvalds

radeonfb: fix problem with color expansion & alignment

The engine on some radeon variants locks up if color expansion is called
for non aligned source data.  This patch enables a feature of the core
fbdev to request aligned input pixmaps and uses the HW clipping engine to
clip the output to the requested size

Addresses http://bugzilla.kernel.org/show_bug.cgi?id=11875Signed-off-by: NBenjamin Herrenschmidt <benh@kernel.crashing.org>
Tested-by: NJames Cloos <cloos@jhcloos.com>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Krzysztof Helt <krzysztof.h1@poczta.fm>
Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
上级 b93c35ff
...@@ -174,12 +174,12 @@ static void radeonfb_prim_imageblit(struct radeonfb_info *rinfo, ...@@ -174,12 +174,12 @@ static void radeonfb_prim_imageblit(struct radeonfb_info *rinfo,
const struct fb_image *image, const struct fb_image *image,
u32 fg, u32 bg) u32 fg, u32 bg)
{ {
unsigned int src_bytes, dwords; unsigned int dwords;
u32 *bits; u32 *bits;
radeonfb_set_creg(rinfo, DP_GUI_MASTER_CNTL, &rinfo->dp_gui_mc_cache, radeonfb_set_creg(rinfo, DP_GUI_MASTER_CNTL, &rinfo->dp_gui_mc_cache,
rinfo->dp_gui_mc_base | rinfo->dp_gui_mc_base |
GMC_BRUSH_NONE | GMC_BRUSH_NONE | GMC_DST_CLIP_LEAVE |
GMC_SRC_DATATYPE_MONO_FG_BG | GMC_SRC_DATATYPE_MONO_FG_BG |
ROP3_S | ROP3_S |
GMC_BYTE_ORDER_MSB_TO_LSB | GMC_BYTE_ORDER_MSB_TO_LSB |
...@@ -189,9 +189,6 @@ static void radeonfb_prim_imageblit(struct radeonfb_info *rinfo, ...@@ -189,9 +189,6 @@ static void radeonfb_prim_imageblit(struct radeonfb_info *rinfo,
radeonfb_set_creg(rinfo, DP_SRC_FRGD_CLR, &rinfo->dp_src_fg_cache, fg); radeonfb_set_creg(rinfo, DP_SRC_FRGD_CLR, &rinfo->dp_src_fg_cache, fg);
radeonfb_set_creg(rinfo, DP_SRC_BKGD_CLR, &rinfo->dp_src_bg_cache, bg); radeonfb_set_creg(rinfo, DP_SRC_BKGD_CLR, &rinfo->dp_src_bg_cache, bg);
radeon_fifo_wait(rinfo, 1);
OUTREG(DST_Y_X, (image->dy << 16) | image->dx);
/* Ensure the dst cache is flushed and the engine idle before /* Ensure the dst cache is flushed and the engine idle before
* issuing the operation. * issuing the operation.
* *
...@@ -205,13 +202,19 @@ static void radeonfb_prim_imageblit(struct radeonfb_info *rinfo, ...@@ -205,13 +202,19 @@ static void radeonfb_prim_imageblit(struct radeonfb_info *rinfo,
/* X here pads width to a multiple of 32 and uses the clipper to /* X here pads width to a multiple of 32 and uses the clipper to
* adjust the result. Is that really necessary ? Things seem to * adjust the result. Is that really necessary ? Things seem to
* work ok for me without that and the doco doesn't seem to imply * work ok for me without that and the doco doesn't seem to imply]
* there is such a restriction. * there is such a restriction.
*/ */
OUTREG(DST_WIDTH_HEIGHT, (image->width << 16) | image->height); radeon_fifo_wait(rinfo, 4);
OUTREG(SC_TOP_LEFT, (image->dy << 16) | image->dx);
OUTREG(SC_BOTTOM_RIGHT, ((image->dy + image->height) << 16) |
(image->dx + image->width));
OUTREG(DST_Y_X, (image->dy << 16) | image->dx);
OUTREG(DST_HEIGHT_WIDTH, (image->height << 16) | ((image->width + 31) & ~31));
src_bytes = (((image->width * image->depth) + 7) / 8) * image->height; dwords = (image->width + 31) >> 5;
dwords = (src_bytes + 3) / 4; dwords *= image->height;
bits = (u32*)(image->data); bits = (u32*)(image->data);
while(dwords >= 8) { while(dwords >= 8) {
......
...@@ -1875,6 +1875,7 @@ static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo) ...@@ -1875,6 +1875,7 @@ static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo)
info->fbops = &radeonfb_ops; info->fbops = &radeonfb_ops;
info->screen_base = rinfo->fb_base; info->screen_base = rinfo->fb_base;
info->screen_size = rinfo->mapped_vram; info->screen_size = rinfo->mapped_vram;
/* Fill fix common fields */ /* Fill fix common fields */
strlcpy(info->fix.id, rinfo->name, sizeof(info->fix.id)); strlcpy(info->fix.id, rinfo->name, sizeof(info->fix.id));
info->fix.smem_start = rinfo->fb_base_phys; info->fix.smem_start = rinfo->fb_base_phys;
...@@ -1889,8 +1890,25 @@ static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo) ...@@ -1889,8 +1890,25 @@ static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo)
info->fix.mmio_len = RADEON_REGSIZE; info->fix.mmio_len = RADEON_REGSIZE;
info->fix.accel = FB_ACCEL_ATI_RADEON; info->fix.accel = FB_ACCEL_ATI_RADEON;
/* Allocate colormap */
fb_alloc_cmap(&info->cmap, 256, 0); fb_alloc_cmap(&info->cmap, 256, 0);
/* Setup pixmap used for acceleration */
#define PIXMAP_SIZE (2048 * 4)
info->pixmap.addr = kmalloc(PIXMAP_SIZE, GFP_KERNEL);
if (!info->pixmap.addr) {
printk(KERN_ERR "radeonfb: Failed to allocate pixmap !\n");
noaccel = 1;
goto bail;
}
info->pixmap.size = PIXMAP_SIZE;
info->pixmap.flags = FB_PIXMAP_SYSTEM;
info->pixmap.scan_align = 4;
info->pixmap.buf_align = 4;
info->pixmap.access_align = 32;
bail:
if (noaccel) if (noaccel)
info->flags |= FBINFO_HWACCEL_DISABLED; info->flags |= FBINFO_HWACCEL_DISABLED;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册