From 9b82f3e61758ed897200f0244b63a77c1791bcba Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 30 Oct 2008 08:12:58 +0000 Subject: powerpc/ps3: Replace the flip_ctl logic in ps3av and ps3fb by a mutex Introduce ps3_gpu_mutex to synchronizes GPU-related operations, like: - invoking the L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT command using the lv1_gpu_context_attribute() hypervisor call, - handling the PS3AV_CID_AVB_PARAM packet in the PS3 A/V Settings driver. Signed-off-by: Geert Uytterhoeven Signed-off-by: Geoff Levand Signed-off-by: Paul Mackerras --- drivers/video/ps3fb.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c index 4b5d80771904..bd3e39baf7d2 100644 --- a/drivers/video/ps3fb.c +++ b/drivers/video/ps3fb.c @@ -460,12 +460,16 @@ static void ps3fb_sync_image(struct device *dev, u64 frame_offset, line_length |= (u64)src_line_length << 32; src_offset += GPU_FB_START; + + mutex_lock(&ps3_gpu_mutex); status = lv1_gpu_context_attribute(ps3fb.context_handle, L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, dst_offset, GPU_IOIF + src_offset, L1GPU_FB_BLIT_WAIT_FOR_COMPLETION | (width << 16) | height, line_length); + mutex_unlock(&ps3_gpu_mutex); + if (status) dev_err(dev, "%s: lv1_gpu_context_attribute FB_BLIT failed: %d\n", @@ -784,15 +788,6 @@ static int ps3fb_wait_for_vsync(u32 crtc) return 0; } -static void ps3fb_flip_ctl(int on, void *data) -{ - struct ps3fb_priv *priv = data; - if (on) - atomic_dec_if_positive(&priv->ext_flip); - else - atomic_inc(&priv->ext_flip); -} - /* * ioctl @@ -1228,7 +1223,6 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev) } ps3fb.task = task; - ps3av_register_flip_ctl(ps3fb_flip_ctl, &ps3fb); return 0; @@ -1258,10 +1252,9 @@ static int ps3fb_shutdown(struct ps3_system_bus_device *dev) dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__); - ps3fb_flip_ctl(0, &ps3fb); /* flip off */ + atomic_inc(&ps3fb.ext_flip); /* flip off */ ps3fb.dinfo->irq.mask = 0; - ps3av_register_flip_ctl(NULL, NULL); if (ps3fb.task) { struct task_struct *task = ps3fb.task; ps3fb.task = NULL; -- cgit v1.2.2 From 020f97063dd68a8e3b9aac928ac49a438b7416ce Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 1 Dec 2008 17:40:54 +0000 Subject: [ARM] omap: fix a pile of issues This patch fixes a number of sillies, from missing 'const' to using 'return' in void functions, to functions with no arguments not even 'void' and a cast which isn't required. Acked-by: Tony Lindgren Signed-off-by: Russell King --- drivers/video/omap/omapfb_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/video') diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c index 5a5e407dc45f..1a49519dafa4 100644 --- a/drivers/video/omap/omapfb_main.c +++ b/drivers/video/omap/omapfb_main.c @@ -392,7 +392,7 @@ static void set_fb_fix(struct fb_info *fbi) int bpp; rg = &plane->fbdev->mem_desc.region[plane->idx]; - fbi->screen_base = (char __iomem *)rg->vaddr; + fbi->screen_base = rg->vaddr; fix->smem_start = rg->paddr; fix->smem_len = rg->size; -- cgit v1.2.2 From f3179748a157c21d44d929fd3779421ebfbeaa93 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 9 Dec 2008 15:54:18 +1100 Subject: radeonfb: Disable new color expand acceleration unless explicitely enabled This new color expansion acceleration for radeonfb appears to trigger problems with X on VT switch and suspend/resume on some machines. It might be a problem in the VT layer or in X, but I haven't quite found it yet, so in the meantime, this disables the acceleration by default, reverting to 2.6.27 state. It can be enabled using the "accel_cexp" module parameter or fbdev argument. Signed-off-by: Benjamin Herrenschmidt Acked-by: David S. Miller Signed-off-by: Linus Torvalds --- drivers/video/aty/radeon_accel.c | 3 ++- drivers/video/aty/radeon_base.c | 6 ++++++ drivers/video/aty/radeonfb.h | 2 ++ 3 files changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers/video') diff --git a/drivers/video/aty/radeon_accel.c b/drivers/video/aty/radeon_accel.c index a547e5d4c8bf..8da5e5ab8547 100644 --- a/drivers/video/aty/radeon_accel.c +++ b/drivers/video/aty/radeon_accel.c @@ -256,7 +256,8 @@ void radeonfb_imageblit(struct fb_info *info, const struct fb_image *image) return; /* We only do 1 bpp color expansion for now */ - if (info->flags & FBINFO_HWACCEL_DISABLED || image->depth != 1) + if (!accel_cexp || + (info->flags & FBINFO_HWACCEL_DISABLED) || image->depth != 1) goto fallback; /* Fallback if running out of the screen. We may do clipping diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c index b3ffe8205d2b..d5b27f9d374d 100644 --- a/drivers/video/aty/radeon_base.c +++ b/drivers/video/aty/radeon_base.c @@ -282,6 +282,8 @@ static int backlight = 1; static int backlight = 0; #endif +int accel_cexp = 0; + /* * prototypes */ @@ -2520,6 +2522,8 @@ static int __init radeonfb_setup (char *options) } else if (!strncmp(this_opt, "ignore_devlist", 14)) { ignore_devlist = 1; #endif + } else if (!strncmp(this_opt, "accel_cexp", 12)) { + accel_cexp = 1; } else mode_option = this_opt; } @@ -2567,6 +2571,8 @@ module_param(monitor_layout, charp, 0); MODULE_PARM_DESC(monitor_layout, "Specify monitor mapping (like XFree86)"); module_param(force_measure_pll, bool, 0); MODULE_PARM_DESC(force_measure_pll, "Force measurement of PLL (debug)"); +module_param(accel_cexp, bool, 0); +MODULE_PARM_DESC(accel_cexp, "Use acceleration engine for color expansion"); #ifdef CONFIG_MTRR module_param(nomtrr, bool, 0); MODULE_PARM_DESC(nomtrr, "bool: disable use of MTRR registers"); diff --git a/drivers/video/aty/radeonfb.h b/drivers/video/aty/radeonfb.h index ea0b5b47acaf..974ca6d86540 100644 --- a/drivers/video/aty/radeonfb.h +++ b/drivers/video/aty/radeonfb.h @@ -638,4 +638,6 @@ static inline void radeonfb_bl_init(struct radeonfb_info *rinfo) {} static inline void radeonfb_bl_exit(struct radeonfb_info *rinfo) {} #endif +extern int accel_cexp; + #endif /* __RADEONFB_H__ */ -- cgit v1.2.2 From beaa4867eec02e6eb78e9e9ef503d7eff612b068 Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Tue, 9 Dec 2008 13:14:17 -0800 Subject: fbcon: fix workqueue shutdown Add a call to cancel_work_sync() in fbcon_exit() to cancel any pending work in the fbcon workqueue. The current implementation of fbcon_exit() sets the fbcon workqueue function info->queue.func to NULL, but does not assure that there is no work pending when it does so. On occasion, depending on system timing, there will still be pending work in the queue when fbcon_exit() is called. This results in a null pointer deference when run_workqueue() tries to call the queue's work function. Fixes errors on shutdown similar to these: Console: switching to colour dummy device 80x25 Unable to handle kernel paging request for data at address 0x00000000 Signed-off-by: Geoff Levand Cc: Krzysztof Helt Cc: Geert Uytterhoeven Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/console/fbcon.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/video') diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 67ff370d80af..0b2adefe9e3d 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -3531,12 +3531,18 @@ static void fbcon_exit(void) softback_buf = 0UL; for (i = 0; i < FB_MAX; i++) { + int pending; + mapped = 0; info = registered_fb[i]; if (info == NULL) continue; + pending = cancel_work_sync(&info->queue); + DPRINTK("fbcon: %s pending work\n", (pending ? "canceled" : + "no")); + for (j = first_fb_vc; j <= last_fb_vc; j++) { if (con2fb_map[j] == i) mapped = 1; -- cgit v1.2.2 From c1ab6cc68cb7d512ebba3496cd341286d2d7969d Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 9 Dec 2008 13:14:31 -0800 Subject: drivers/video/mb862xx/mb862xxfb.c: fix printk sparc64: drivers/video/mb862xx/mb862xxfb.c:929: warning: long long unsigned int format, resource_size_t arg (arg 4) drivers/video/mb862xx/mb862xxfb.c:931: warning: long long unsigned int format, resource_size_t arg (arg 4) We don't know what type the architecture uses to implement u64, hence they cannot be printed. Cc: Anatolij Gustschin Cc: Dmitry Baryshkov Cc: Anton Vorontsov Cc: Matteo Fortini Cc: Krzysztof Helt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/mb862xx/mb862xxfb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/mb862xx/mb862xxfb.c b/drivers/video/mb862xx/mb862xxfb.c index 38718d95fbb9..fb64234a3825 100644 --- a/drivers/video/mb862xx/mb862xxfb.c +++ b/drivers/video/mb862xx/mb862xxfb.c @@ -927,9 +927,9 @@ static int __devinit mb862xx_pci_probe(struct pci_dev *pdev, } dev_dbg(dev, "fb phys 0x%llx 0x%lx\n", - (u64)par->fb_base_phys, (ulong)par->mapped_vram); + (unsigned long long)par->fb_base_phys, (ulong)par->mapped_vram); dev_dbg(dev, "mmio phys 0x%llx 0x%lx\n", - (u64)par->mmio_base_phys, (ulong)par->mmio_len); + (unsigned long long)par->mmio_base_phys, (ulong)par->mmio_len); if (mb862xx_pci_gdc_init(par)) goto io_unmap; -- cgit v1.2.2 From 6c34bc2976b30dc8b56392c020e25bae1f363cab Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 10 Dec 2008 09:26:17 -0800 Subject: Revert "radeonfb: accelerate imageblit and other improvements" This reverts commit b1ee26bab14886350ba12a5c10cbc0696ac679bf, along with the "fixes" for it that all just caused problems: - c4c6fa9891f3d1bcaae4f39fb751d5302965b566 "radeonfb: fix problem with color expansion & alignment" - f3179748a157c21d44d929fd3779421ebfbeaa93 "radeonfb: Disable new color expand acceleration unless explicitely enabled" because even when disabled, it breaks for people. See http://bugzilla.kernel.org/show_bug.cgi?id=12191 for the latest example. Acked-by: Benjamin Herrenschmidt Acked-by: David S. Miller Cc: Krzysztof Halasa Cc: James Cloos Cc: "Rafael J. Wysocki" Cc: Krzysztof Helt Cc: Jean-Luc Coulon Cc: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/aty/radeon_accel.c | 295 ++++++++++------------------------- drivers/video/aty/radeon_backlight.c | 2 +- drivers/video/aty/radeon_base.c | 46 ++---- drivers/video/aty/radeon_pm.c | 6 +- drivers/video/aty/radeonfb.h | 40 ++--- 5 files changed, 122 insertions(+), 267 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/aty/radeon_accel.c b/drivers/video/aty/radeon_accel.c index 8da5e5ab8547..a469a3d6edcb 100644 --- a/drivers/video/aty/radeon_accel.c +++ b/drivers/video/aty/radeon_accel.c @@ -5,61 +5,61 @@ * --dte */ -#define FLUSH_CACHE_WORKAROUND 1 - -void radeon_fifo_update_and_wait(struct radeonfb_info *rinfo, int entries) +static void radeon_fixup_offset(struct radeonfb_info *rinfo) { - int i; + u32 local_base; + + /* *** Ugly workaround *** */ + /* + * On some platforms, the video memory is mapped at 0 in radeon chip space + * (like PPCs) by the firmware. X will always move it up so that it's seen + * by the chip to be at the same address as the PCI BAR. + * That means that when switching back from X, there is a mismatch between + * the offsets programmed into the engine. This means that potentially, + * accel operations done before radeonfb has a chance to re-init the engine + * will have incorrect offsets, and potentially trash system memory ! + * + * The correct fix is for fbcon to never call any accel op before the engine + * has properly been re-initialized (by a call to set_var), but this is a + * complex fix. This workaround in the meantime, called before every accel + * operation, makes sure the offsets are in sync. + */ - for (i=0; i<2000000; i++) { - rinfo->fifo_free = INREG(RBBM_STATUS) & 0x7f; - if (rinfo->fifo_free >= entries) - return; - udelay(10); - } - printk(KERN_ERR "radeonfb: FIFO Timeout !\n"); - /* XXX Todo: attempt to reset the engine */ -} + radeon_fifo_wait (1); + local_base = INREG(MC_FB_LOCATION) << 16; + if (local_base == rinfo->fb_local_base) + return; -static inline void radeon_fifo_wait(struct radeonfb_info *rinfo, int entries) -{ - if (entries <= rinfo->fifo_free) - rinfo->fifo_free -= entries; - else - radeon_fifo_update_and_wait(rinfo, entries); -} + rinfo->fb_local_base = local_base; -static inline void radeonfb_set_creg(struct radeonfb_info *rinfo, u32 reg, - u32 *cache, u32 new_val) -{ - if (new_val == *cache) - return; - *cache = new_val; - radeon_fifo_wait(rinfo, 1); - OUTREG(reg, new_val); + radeon_fifo_wait (3); + OUTREG(DEFAULT_PITCH_OFFSET, (rinfo->pitch << 0x16) | + (rinfo->fb_local_base >> 10)); + OUTREG(DST_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10)); + OUTREG(SRC_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10)); } static void radeonfb_prim_fillrect(struct radeonfb_info *rinfo, const struct fb_fillrect *region) { - radeonfb_set_creg(rinfo, DP_GUI_MASTER_CNTL, &rinfo->dp_gui_mc_cache, - rinfo->dp_gui_mc_base | GMC_BRUSH_SOLID_COLOR | ROP3_P); - radeonfb_set_creg(rinfo, DP_CNTL, &rinfo->dp_cntl_cache, - DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM); - radeonfb_set_creg(rinfo, DP_BRUSH_FRGD_CLR, &rinfo->dp_brush_fg_cache, - region->color); - - /* Ensure the dst cache is flushed and the engine idle before - * issuing the operation. - * - * This works around engine lockups on some cards - */ -#if FLUSH_CACHE_WORKAROUND - radeon_fifo_wait(rinfo, 2); + radeon_fifo_wait(4); + + OUTREG(DP_GUI_MASTER_CNTL, + rinfo->dp_gui_master_cntl /* contains, like GMC_DST_32BPP */ + | GMC_BRUSH_SOLID_COLOR + | ROP3_P); + if (radeon_get_dstbpp(rinfo->depth) != DST_8BPP) + OUTREG(DP_BRUSH_FRGD_CLR, rinfo->pseudo_palette[region->color]); + else + OUTREG(DP_BRUSH_FRGD_CLR, region->color); + OUTREG(DP_WRITE_MSK, 0xffffffff); + OUTREG(DP_CNTL, (DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM)); + + radeon_fifo_wait(2); OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL); OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE)); -#endif - radeon_fifo_wait(rinfo, 2); + + radeon_fifo_wait(2); OUTREG(DST_Y_X, (region->dy << 16) | region->dx); OUTREG(DST_WIDTH_HEIGHT, (region->width << 16) | region->height); } @@ -70,14 +70,15 @@ void radeonfb_fillrect(struct fb_info *info, const struct fb_fillrect *region) struct fb_fillrect modded; int vxres, vyres; - WARN_ON(rinfo->gfx_mode); - if (info->state != FBINFO_STATE_RUNNING || rinfo->gfx_mode) + if (info->state != FBINFO_STATE_RUNNING) return; if (info->flags & FBINFO_HWACCEL_DISABLED) { cfb_fillrect(info, region); return; } + radeon_fixup_offset(rinfo); + vxres = info->var.xres_virtual; vyres = info->var.yres_virtual; @@ -90,10 +91,6 @@ void radeonfb_fillrect(struct fb_info *info, const struct fb_fillrect *region) if(modded.dx + modded.width > vxres) modded.width = vxres - modded.dx; if(modded.dy + modded.height > vyres) modded.height = vyres - modded.dy; - if (info->fix.visual == FB_VISUAL_TRUECOLOR || - info->fix.visual == FB_VISUAL_DIRECTCOLOR ) - modded.color = ((u32 *) (info->pseudo_palette))[region->color]; - radeonfb_prim_fillrect(rinfo, &modded); } @@ -112,22 +109,22 @@ static void radeonfb_prim_copyarea(struct radeonfb_info *rinfo, if ( xdir < 0 ) { sx += w-1; dx += w-1; } if ( ydir < 0 ) { sy += h-1; dy += h-1; } - radeonfb_set_creg(rinfo, DP_GUI_MASTER_CNTL, &rinfo->dp_gui_mc_cache, - rinfo->dp_gui_mc_base | - GMC_BRUSH_NONE | - GMC_SRC_DATATYPE_COLOR | - ROP3_S | - DP_SRC_SOURCE_MEMORY); - radeonfb_set_creg(rinfo, DP_CNTL, &rinfo->dp_cntl_cache, - (xdir>=0 ? DST_X_LEFT_TO_RIGHT : 0) | - (ydir>=0 ? DST_Y_TOP_TO_BOTTOM : 0)); - -#if FLUSH_CACHE_WORKAROUND - radeon_fifo_wait(rinfo, 2); + radeon_fifo_wait(3); + OUTREG(DP_GUI_MASTER_CNTL, + rinfo->dp_gui_master_cntl /* i.e. GMC_DST_32BPP */ + | GMC_BRUSH_NONE + | GMC_SRC_DSTCOLOR + | ROP3_S + | DP_SRC_SOURCE_MEMORY ); + OUTREG(DP_WRITE_MSK, 0xffffffff); + OUTREG(DP_CNTL, (xdir>=0 ? DST_X_LEFT_TO_RIGHT : 0) + | (ydir>=0 ? DST_Y_TOP_TO_BOTTOM : 0)); + + radeon_fifo_wait(2); OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL); OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE)); -#endif - radeon_fifo_wait(rinfo, 3); + + radeon_fifo_wait(3); OUTREG(SRC_Y_X, (sy << 16) | sx); OUTREG(DST_Y_X, (dy << 16) | dx); OUTREG(DST_HEIGHT_WIDTH, (h << 16) | w); @@ -146,14 +143,15 @@ void radeonfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) modded.width = area->width; modded.height = area->height; - WARN_ON(rinfo->gfx_mode); - if (info->state != FBINFO_STATE_RUNNING || rinfo->gfx_mode) + if (info->state != FBINFO_STATE_RUNNING) return; if (info->flags & FBINFO_HWACCEL_DISABLED) { cfb_copyarea(info, area); return; } + radeon_fixup_offset(rinfo); + vxres = info->var.xres_virtual; vyres = info->var.yres_virtual; @@ -170,116 +168,13 @@ void radeonfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) radeonfb_prim_copyarea(rinfo, &modded); } -static void radeonfb_prim_imageblit(struct radeonfb_info *rinfo, - const struct fb_image *image, - u32 fg, u32 bg) -{ - unsigned int dwords; - u32 *bits; - - radeonfb_set_creg(rinfo, DP_GUI_MASTER_CNTL, &rinfo->dp_gui_mc_cache, - rinfo->dp_gui_mc_base | - GMC_BRUSH_NONE | GMC_DST_CLIP_LEAVE | - GMC_SRC_DATATYPE_MONO_FG_BG | - ROP3_S | - GMC_BYTE_ORDER_MSB_TO_LSB | - DP_SRC_SOURCE_HOST_DATA); - radeonfb_set_creg(rinfo, DP_CNTL, &rinfo->dp_cntl_cache, - DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM); - 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); - - /* Ensure the dst cache is flushed and the engine idle before - * issuing the operation. - * - * This works around engine lockups on some cards - */ -#if FLUSH_CACHE_WORKAROUND - radeon_fifo_wait(rinfo, 2); - OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL); - OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE)); -#endif - - /* X here pads width to a multiple of 32 and uses the clipper 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] - * there is such a restriction. - */ - 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)); - - dwords = (image->width + 31) >> 5; - dwords *= image->height; - bits = (u32*)(image->data); - - while(dwords >= 8) { - radeon_fifo_wait(rinfo, 8); -#if BITS_PER_LONG == 64 - __raw_writeq(*((u64 *)(bits)), rinfo->mmio_base + HOST_DATA0); - __raw_writeq(*((u64 *)(bits+2)), rinfo->mmio_base + HOST_DATA2); - __raw_writeq(*((u64 *)(bits+4)), rinfo->mmio_base + HOST_DATA4); - __raw_writeq(*((u64 *)(bits+6)), rinfo->mmio_base + HOST_DATA6); - bits += 8; -#else - __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA0); - __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA1); - __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA2); - __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA3); - __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA4); - __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA5); - __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA6); - __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA7); -#endif - dwords -= 8; - } - while(dwords--) { - radeon_fifo_wait(rinfo, 1); - __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA0); - } -} - void radeonfb_imageblit(struct fb_info *info, const struct fb_image *image) { struct radeonfb_info *rinfo = info->par; - u32 fg, bg; - WARN_ON(rinfo->gfx_mode); - if (info->state != FBINFO_STATE_RUNNING || rinfo->gfx_mode) - return; - - if (!image->width || !image->height) + if (info->state != FBINFO_STATE_RUNNING) return; - - /* We only do 1 bpp color expansion for now */ - if (!accel_cexp || - (info->flags & FBINFO_HWACCEL_DISABLED) || image->depth != 1) - goto fallback; - - /* Fallback if running out of the screen. We may do clipping - * in the future */ - if ((image->dx + image->width) > info->var.xres_virtual || - (image->dy + image->height) > info->var.yres_virtual) - goto fallback; - - if (info->fix.visual == FB_VISUAL_TRUECOLOR || - info->fix.visual == FB_VISUAL_DIRECTCOLOR) { - fg = ((u32*)(info->pseudo_palette))[image->fg_color]; - bg = ((u32*)(info->pseudo_palette))[image->bg_color]; - } else { - fg = image->fg_color; - bg = image->bg_color; - } - - radeonfb_prim_imageblit(rinfo, image, fg, bg); - return; - - fallback: - radeon_engine_idle(rinfo); + radeon_engine_idle(); cfb_imageblit(info, image); } @@ -290,8 +185,7 @@ int radeonfb_sync(struct fb_info *info) if (info->state != FBINFO_STATE_RUNNING) return 0; - - radeon_engine_idle(rinfo); + radeon_engine_idle(); return 0; } @@ -367,10 +261,9 @@ void radeonfb_engine_init (struct radeonfb_info *rinfo) /* disable 3D engine */ OUTREG(RB3D_CNTL, 0); - rinfo->fifo_free = 0; radeonfb_engine_reset(rinfo); - radeon_fifo_wait(rinfo, 1); + radeon_fifo_wait (1); if (IS_R300_VARIANT(rinfo)) { OUTREG(RB2D_DSTCACHE_MODE, INREG(RB2D_DSTCACHE_MODE) | RB2D_DC_AUTOFLUSH_ENABLE | @@ -384,7 +277,7 @@ void radeonfb_engine_init (struct radeonfb_info *rinfo) OUTREG(RB2D_DSTCACHE_MODE, 0); } - radeon_fifo_wait(rinfo, 3); + radeon_fifo_wait (3); /* We re-read MC_FB_LOCATION from card as it can have been * modified by XFree drivers (ouch !) */ @@ -395,57 +288,41 @@ void radeonfb_engine_init (struct radeonfb_info *rinfo) OUTREG(DST_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10)); OUTREG(SRC_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10)); - radeon_fifo_wait(rinfo, 1); -#ifdef __BIG_ENDIAN + radeon_fifo_wait (1); +#if defined(__BIG_ENDIAN) OUTREGP(DP_DATATYPE, HOST_BIG_ENDIAN_EN, ~HOST_BIG_ENDIAN_EN); #else OUTREGP(DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN); #endif - radeon_fifo_wait(rinfo, 2); + radeon_fifo_wait (2); OUTREG(DEFAULT_SC_TOP_LEFT, 0); OUTREG(DEFAULT_SC_BOTTOM_RIGHT, (DEFAULT_SC_RIGHT_MAX | DEFAULT_SC_BOTTOM_MAX)); - /* set default DP_GUI_MASTER_CNTL */ temp = radeon_get_dstbpp(rinfo->depth); - rinfo->dp_gui_mc_base = ((temp << 8) | GMC_CLR_CMP_CNTL_DIS); + rinfo->dp_gui_master_cntl = ((temp << 8) | GMC_CLR_CMP_CNTL_DIS); - rinfo->dp_gui_mc_cache = rinfo->dp_gui_mc_base | - GMC_BRUSH_SOLID_COLOR | - GMC_SRC_DATATYPE_COLOR; - radeon_fifo_wait(rinfo, 1); - OUTREG(DP_GUI_MASTER_CNTL, rinfo->dp_gui_mc_cache); + radeon_fifo_wait (1); + OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl | + GMC_BRUSH_SOLID_COLOR | + GMC_SRC_DATATYPE_COLOR)); + radeon_fifo_wait (7); /* clear line drawing regs */ - radeon_fifo_wait(rinfo, 2); OUTREG(DST_LINE_START, 0); OUTREG(DST_LINE_END, 0); - /* set brush and source color regs */ - rinfo->dp_brush_fg_cache = 0xffffffff; - rinfo->dp_brush_bg_cache = 0x00000000; - rinfo->dp_src_fg_cache = 0xffffffff; - rinfo->dp_src_bg_cache = 0x00000000; - radeon_fifo_wait(rinfo, 4); - OUTREG(DP_BRUSH_FRGD_CLR, rinfo->dp_brush_fg_cache); - OUTREG(DP_BRUSH_BKGD_CLR, rinfo->dp_brush_bg_cache); - OUTREG(DP_SRC_FRGD_CLR, rinfo->dp_src_fg_cache); - OUTREG(DP_SRC_BKGD_CLR, rinfo->dp_src_bg_cache); - - /* Default direction */ - rinfo->dp_cntl_cache = DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM; - radeon_fifo_wait(rinfo, 1); - OUTREG(DP_CNTL, rinfo->dp_cntl_cache); + /* set brush color regs */ + OUTREG(DP_BRUSH_FRGD_CLR, 0xffffffff); + OUTREG(DP_BRUSH_BKGD_CLR, 0x00000000); + + /* set source color regs */ + OUTREG(DP_SRC_FRGD_CLR, 0xffffffff); + OUTREG(DP_SRC_BKGD_CLR, 0x00000000); /* default write mask */ - radeon_fifo_wait(rinfo, 1); OUTREG(DP_WRITE_MSK, 0xffffffff); - /* Default to no swapping of host data */ - radeon_fifo_wait(rinfo, 1); - OUTREG(RBBM_GUICNTL, RBBM_GUICNTL_HOST_DATA_SWAP_NONE); - - /* Make sure it's settled */ - radeon_engine_idle(rinfo); + radeon_engine_idle (); } diff --git a/drivers/video/aty/radeon_backlight.c b/drivers/video/aty/radeon_backlight.c index f343ba83f0ae..1a056adb61c8 100644 --- a/drivers/video/aty/radeon_backlight.c +++ b/drivers/video/aty/radeon_backlight.c @@ -66,7 +66,7 @@ static int radeon_bl_update_status(struct backlight_device *bd) level = bd->props.brightness; del_timer_sync(&rinfo->lvds_timer); - radeon_engine_idle(rinfo); + radeon_engine_idle(); lvds_gen_cntl = INREG(LVDS_GEN_CNTL); if (level > 0) { diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c index d5b27f9d374d..d0f1a7fc2c9d 100644 --- a/drivers/video/aty/radeon_base.c +++ b/drivers/video/aty/radeon_base.c @@ -282,8 +282,6 @@ static int backlight = 1; static int backlight = 0; #endif -int accel_cexp = 0; - /* * prototypes */ @@ -854,6 +852,7 @@ static int radeonfb_pan_display (struct fb_var_screeninfo *var, if (rinfo->asleep) return 0; + radeon_fifo_wait(2); OUTREG(CRTC_OFFSET, ((var->yoffset * var->xres_virtual + var->xoffset) * var->bits_per_pixel / 8) & ~7); return 0; @@ -883,6 +882,7 @@ static int radeonfb_ioctl (struct fb_info *info, unsigned int cmd, if (rc) return rc; + radeon_fifo_wait(2); if (value & 0x01) { tmp = INREG(LVDS_GEN_CNTL); @@ -940,7 +940,7 @@ int radeon_screen_blank(struct radeonfb_info *rinfo, int blank, int mode_switch) if (rinfo->lock_blank) return 0; - radeon_engine_idle(rinfo); + radeon_engine_idle(); val = INREG(CRTC_EXT_CNTL); val &= ~(CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS | @@ -1048,7 +1048,7 @@ static int radeonfb_blank (int blank, struct fb_info *info) if (rinfo->asleep) return 0; - + return radeon_screen_blank(rinfo, blank, 0); } @@ -1074,6 +1074,8 @@ static int radeon_setcolreg (unsigned regno, unsigned red, unsigned green, pindex = regno; if (!rinfo->asleep) { + radeon_fifo_wait(9); + if (rinfo->bpp == 16) { pindex = regno * 8; @@ -1242,6 +1244,8 @@ static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_reg { int i; + radeon_fifo_wait(20); + /* Workaround from XFree */ if (rinfo->is_mobility) { /* A temporal workaround for the occational blanking on certain laptop @@ -1337,7 +1341,7 @@ static void radeon_lvds_timer_func(unsigned long data) { struct radeonfb_info *rinfo = (struct radeonfb_info *)data; - radeon_engine_idle(rinfo); + radeon_engine_idle(); OUTREG(LVDS_GEN_CNTL, rinfo->pending_lvds_gen_cntl); } @@ -1355,11 +1359,10 @@ void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode, if (nomodeset) return; - radeon_engine_idle(rinfo); - if (!regs_only) radeon_screen_blank(rinfo, FB_BLANK_NORMAL, 0); + radeon_fifo_wait(31); for (i=0; i<10; i++) OUTREG(common_regs[i].reg, common_regs[i].val); @@ -1387,6 +1390,7 @@ void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode, radeon_write_pll_regs(rinfo, mode); if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) { + radeon_fifo_wait(10); OUTREG(FP_CRTC_H_TOTAL_DISP, mode->fp_crtc_h_total_disp); OUTREG(FP_CRTC_V_TOTAL_DISP, mode->fp_crtc_v_total_disp); OUTREG(FP_H_SYNC_STRT_WID, mode->fp_h_sync_strt_wid); @@ -1401,6 +1405,7 @@ void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode, if (!regs_only) radeon_screen_blank(rinfo, FB_BLANK_UNBLANK, 0); + radeon_fifo_wait(2); OUTPLL(VCLK_ECP_CNTL, mode->vclk_ecp_cntl); return; @@ -1551,7 +1556,7 @@ static int radeonfb_set_par(struct fb_info *info) /* We always want engine to be idle on a mode switch, even * if we won't actually change the mode */ - radeon_engine_idle(rinfo); + radeon_engine_idle(); hSyncStart = mode->xres + mode->right_margin; hSyncEnd = hSyncStart + mode->hsync_len; @@ -1846,6 +1851,7 @@ static int radeonfb_set_par(struct fb_info *info) return 0; } + static struct fb_ops radeonfb_ops = { .owner = THIS_MODULE, .fb_check_var = radeonfb_check_var, @@ -1869,7 +1875,6 @@ static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo) info->par = rinfo; info->pseudo_palette = rinfo->pseudo_palette; info->flags = FBINFO_DEFAULT - | FBINFO_HWACCEL_IMAGEBLIT | FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_XPAN @@ -1877,7 +1882,6 @@ static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo) info->fbops = &radeonfb_ops; info->screen_base = rinfo->fb_base; info->screen_size = rinfo->mapped_vram; - /* Fill fix common fields */ strlcpy(info->fix.id, rinfo->name, sizeof(info->fix.id)); info->fix.smem_start = rinfo->fb_base_phys; @@ -1892,25 +1896,8 @@ static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo) info->fix.mmio_len = RADEON_REGSIZE; info->fix.accel = FB_ACCEL_ATI_RADEON; - /* Allocate colormap */ 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) info->flags |= FBINFO_HWACCEL_DISABLED; @@ -2019,6 +2006,7 @@ static void radeon_identify_vram(struct radeonfb_info *rinfo) u32 tom = INREG(NB_TOM); tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024); + radeon_fifo_wait(6); OUTREG(MC_FB_LOCATION, tom); OUTREG(DISPLAY_BASE_ADDR, (tom & 0xffff) << 16); OUTREG(CRTC2_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16); @@ -2522,8 +2510,6 @@ static int __init radeonfb_setup (char *options) } else if (!strncmp(this_opt, "ignore_devlist", 14)) { ignore_devlist = 1; #endif - } else if (!strncmp(this_opt, "accel_cexp", 12)) { - accel_cexp = 1; } else mode_option = this_opt; } @@ -2571,8 +2557,6 @@ module_param(monitor_layout, charp, 0); MODULE_PARM_DESC(monitor_layout, "Specify monitor mapping (like XFree86)"); module_param(force_measure_pll, bool, 0); MODULE_PARM_DESC(force_measure_pll, "Force measurement of PLL (debug)"); -module_param(accel_cexp, bool, 0); -MODULE_PARM_DESC(accel_cexp, "Use acceleration engine for color expansion"); #ifdef CONFIG_MTRR module_param(nomtrr, bool, 0); MODULE_PARM_DESC(nomtrr, "bool: disable use of MTRR registers"); diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c index 3df5015f1d13..675abdafc2d8 100644 --- a/drivers/video/aty/radeon_pm.c +++ b/drivers/video/aty/radeon_pm.c @@ -2653,9 +2653,9 @@ int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg) if (!(info->flags & FBINFO_HWACCEL_DISABLED)) { /* Make sure engine is reset */ - radeon_engine_idle(rinfo); + radeon_engine_idle(); radeonfb_engine_reset(rinfo); - radeon_engine_idle(rinfo); + radeon_engine_idle(); } /* Blank display and LCD */ @@ -2767,7 +2767,7 @@ int radeonfb_pci_resume(struct pci_dev *pdev) rinfo->asleep = 0; } else - radeon_engine_idle(rinfo); + radeon_engine_idle(); /* Restore display & engine */ radeon_write_mode (rinfo, &rinfo->state, 1); diff --git a/drivers/video/aty/radeonfb.h b/drivers/video/aty/radeonfb.h index 974ca6d86540..3ea1b00fdd22 100644 --- a/drivers/video/aty/radeonfb.h +++ b/drivers/video/aty/radeonfb.h @@ -336,15 +336,7 @@ struct radeonfb_info { int mon2_type; u8 *mon2_EDID; - /* accel bits */ - u32 dp_gui_mc_base; - u32 dp_gui_mc_cache; - u32 dp_cntl_cache; - u32 dp_brush_fg_cache; - u32 dp_brush_bg_cache; - u32 dp_src_fg_cache; - u32 dp_src_bg_cache; - u32 fifo_free; + u32 dp_gui_master_cntl; struct pll_info pll; @@ -356,7 +348,6 @@ struct radeonfb_info { int lock_blank; int dynclk; int no_schedule; - int gfx_mode; enum radeon_pm_mode pm_mode; reinit_function_ptr reinit_func; @@ -401,14 +392,8 @@ static inline void _radeon_msleep(struct radeonfb_info *rinfo, unsigned long ms) #define OUTREG8(addr,val) writeb(val, (rinfo->mmio_base)+addr) #define INREG16(addr) readw((rinfo->mmio_base)+addr) #define OUTREG16(addr,val) writew(val, (rinfo->mmio_base)+addr) - -#ifdef CONFIG_PPC -#define INREG(addr) ({ eieio(); ld_le32(rinfo->mmio_base+(addr)); }) -#define OUTREG(addr,val) do { eieio(); st_le32(rinfo->mmio_base+(addr),(val)); } while(0) -#else #define INREG(addr) readl((rinfo->mmio_base)+addr) #define OUTREG(addr,val) writel(val, (rinfo->mmio_base)+addr) -#endif static inline void _OUTREGP(struct radeonfb_info *rinfo, u32 addr, u32 val, u32 mask) @@ -550,7 +535,17 @@ static inline u32 radeon_get_dstbpp(u16 depth) * 2D Engine helper routines */ -extern void radeon_fifo_update_and_wait(struct radeonfb_info *rinfo, int entries); +static inline void _radeon_fifo_wait(struct radeonfb_info *rinfo, int entries) +{ + int i; + + for (i=0; i<2000000; i++) { + if ((INREG(RBBM_STATUS) & 0x7f) >= entries) + return; + udelay(1); + } + printk(KERN_ERR "radeonfb: FIFO Timeout !\n"); +} static inline void radeon_engine_flush (struct radeonfb_info *rinfo) { @@ -563,7 +558,7 @@ static inline void radeon_engine_flush (struct radeonfb_info *rinfo) /* Ensure FIFO is empty, ie, make sure the flush commands * has reached the cache */ - radeon_fifo_update_and_wait(rinfo, 64); + _radeon_fifo_wait (rinfo, 64); /* Wait for the flush to complete */ for (i=0; i < 2000000; i++) { @@ -575,12 +570,12 @@ static inline void radeon_engine_flush (struct radeonfb_info *rinfo) } -static inline void radeon_engine_idle(struct radeonfb_info *rinfo) +static inline void _radeon_engine_idle(struct radeonfb_info *rinfo) { int i; /* ensure FIFO is empty before waiting for idle */ - radeon_fifo_update_and_wait (rinfo, 64); + _radeon_fifo_wait (rinfo, 64); for (i=0; i<2000000; i++) { if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) { @@ -593,6 +588,8 @@ static inline void radeon_engine_idle(struct radeonfb_info *rinfo) } +#define radeon_engine_idle() _radeon_engine_idle(rinfo) +#define radeon_fifo_wait(entries) _radeon_fifo_wait(rinfo,entries) #define radeon_msleep(ms) _radeon_msleep(rinfo,ms) @@ -622,7 +619,6 @@ extern void radeonfb_imageblit(struct fb_info *p, const struct fb_image *image); extern int radeonfb_sync(struct fb_info *info); extern void radeonfb_engine_init (struct radeonfb_info *rinfo); extern void radeonfb_engine_reset(struct radeonfb_info *rinfo); -extern void radeon_fixup_mem_offset(struct radeonfb_info *rinfo); /* Other functions */ extern int radeon_screen_blank(struct radeonfb_info *rinfo, int blank, int mode_switch); @@ -638,6 +634,4 @@ static inline void radeonfb_bl_init(struct radeonfb_info *rinfo) {} static inline void radeonfb_bl_exit(struct radeonfb_info *rinfo) {} #endif -extern int accel_cexp; - #endif /* __RADEONFB_H__ */ -- cgit v1.2.2 From 46d01492b2c50791b9b66f9b9154ac8d25acaeb9 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 3 Dec 2008 13:52:21 +0000 Subject: powerpc/ps3: Add sub-match id modalias support commit 059e4938f8b060b10c4352e6c45739473bc73267 ("powerpc/ps3: Add a sub-match id to ps3_system_bus") forgot to update the module alias support: - Add the sub-match ids to the module aliases, so udev can distinguish between different types of sub-devices. - Rename PS3_MODULE_ALIAS_GRAPHICS to PS3_MODULE_ALIAS_GPU_FB, as ps3fb binds to the "FB" sub-device. Signed-off-by: Geert Uytterhoeven Signed-off-by: Geoff Levand Signed-off-by: Paul Mackerras --- drivers/video/ps3fb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c index bd3e39baf7d2..38ac805db97d 100644 --- a/drivers/video/ps3fb.c +++ b/drivers/video/ps3fb.c @@ -1289,8 +1289,8 @@ static int ps3fb_shutdown(struct ps3_system_bus_device *dev) } static struct ps3_system_bus_driver ps3fb_driver = { - .match_id = PS3_MATCH_ID_GRAPHICS, - .match_sub_id = PS3_MATCH_SUB_ID_FB, + .match_id = PS3_MATCH_ID_GPU, + .match_sub_id = PS3_MATCH_SUB_ID_GPU_FB, .core.name = DEVICE_NAME, .core.owner = THIS_MODULE, .probe = ps3fb_probe, @@ -1348,4 +1348,4 @@ module_exit(ps3fb_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("PS3 GPU Frame Buffer Driver"); MODULE_AUTHOR("Sony Computer Entertainment Inc."); -MODULE_ALIAS(PS3_MODULE_ALIAS_GRAPHICS); +MODULE_ALIAS(PS3_MODULE_ALIAS_GPU_FB); -- cgit v1.2.2 From 64b3d0e8122b422e879b23d42f9e0e8efbbf9744 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Thu, 18 Dec 2008 19:13:51 +0000 Subject: powerpc/mm: Rework usage of _PAGE_COHERENT/NO_CACHE/GUARDED Currently, we never set _PAGE_COHERENT in the PTEs, we just OR it in in the hash code based on some CPU feature bit. We also manipulate _PAGE_NO_CACHE and _PAGE_GUARDED by hand in all sorts of places. This changes the logic so that instead, the PTE now contains _PAGE_COHERENT for all normal RAM pages thay have I = 0 on platforms that need it. The hash code clears it if the feature bit is not set. It also adds some clean accessors to setup various valid combinations of access flags and change various bits of code to use them instead. This should help having the PTE actually containing the bit combinations that we really want. I also removed _PAGE_GUARDED from _PAGE_BASE on 44x and instead set it explicitely from the TLB miss. I will ultimately remove it completely as it appears that it might not be needed after all but in the meantime, having it in the TLB miss makes things a lot easier. Signed-off-by: Benjamin Herrenschmidt Acked-by: Kumar Gala Signed-off-by: Paul Mackerras --- drivers/video/controlfb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/controlfb.c b/drivers/video/controlfb.c index b0be7eac32d8..49fcbe8f18ac 100644 --- a/drivers/video/controlfb.c +++ b/drivers/video/controlfb.c @@ -298,10 +298,10 @@ static int controlfb_mmap(struct fb_info *info, return -EINVAL; start = info->fix.mmio_start; len = PAGE_ALIGN((start & ~PAGE_MASK)+info->fix.mmio_len); - pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE|_PAGE_GUARDED; + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); } else { /* framebuffer */ - pgprot_val(vma->vm_page_prot) |= _PAGE_WRITETHRU; + vma->vm_page_prot = pgprot_cached_wthru(vma->vm_page_prot); } start &= PAGE_MASK; if ((vma->vm_end - vma->vm_start + off) > len) -- cgit v1.2.2 From b51339fff240ff179730f8963a758147fd60f3ec Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 31 Oct 2008 20:23:26 +0900 Subject: sh: sh_mobile lcdc clock framework support Add clock framework support to the lcdc driver and adjust the board specific code accordingly. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- drivers/video/sh_mobile_lcdcfb.c | 46 ++++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 13 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index efff672fd7b8..c81ee00c54d7 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c @@ -35,6 +35,7 @@ struct sh_mobile_lcdc_chan { struct sh_mobile_lcdc_priv { void __iomem *base; #ifdef CONFIG_HAVE_CLK + struct clk *dot_clk; struct clk *clk; #endif unsigned long lddckr; @@ -207,6 +208,11 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) int k, m; int ret = 0; +#ifdef CONFIG_HAVE_CLK + clk_enable(priv->clk); + if (priv->dot_clk) + clk_enable(priv->dot_clk); +#endif /* reset */ lcdc_write(priv, _LDCNT2R, lcdc_read(priv, _LDCNT2R) | LCDC_RESET); lcdc_wait_bit(priv, _LDCNT2R, LCDC_RESET, 0); @@ -371,6 +377,12 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv) /* stop the lcdc */ sh_mobile_lcdc_start_stop(priv, 0); + +#ifdef CONFIG_HAVE_CLK + if (priv->dot_clk) + clk_disable(priv->dot_clk); + clk_disable(priv->clk); +#endif } static int sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch) @@ -413,9 +425,13 @@ static int sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch) return -EINVAL; } -static int sh_mobile_lcdc_setup_clocks(struct device *dev, int clock_source, +static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev, + int clock_source, struct sh_mobile_lcdc_priv *priv) { +#ifdef CONFIG_HAVE_CLK + char clk_name[8]; +#endif char *str; int icksel; @@ -430,14 +446,20 @@ static int sh_mobile_lcdc_setup_clocks(struct device *dev, int clock_source, priv->lddckr = icksel << 16; #ifdef CONFIG_HAVE_CLK + snprintf(clk_name, sizeof(clk_name), "lcdc%d", pdev->id); + priv->clk = clk_get(&pdev->dev, clk_name); + if (IS_ERR(priv->clk)) { + dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name); + return PTR_ERR(priv->clk); + } + if (str) { - priv->clk = clk_get(dev, str); - if (IS_ERR(priv->clk)) { - dev_err(dev, "cannot get clock %s\n", str); - return PTR_ERR(priv->clk); + priv->dot_clk = clk_get(&pdev->dev, str); + if (IS_ERR(priv->dot_clk)) { + dev_err(&pdev->dev, "cannot get dot clock %s\n", str); + clk_put(priv->clk); + return PTR_ERR(priv->dot_clk); } - - clk_enable(priv->clk); } #endif @@ -587,8 +609,7 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev) goto err1; } - error = sh_mobile_lcdc_setup_clocks(&pdev->dev, - pdata->clock_source, priv); + error = sh_mobile_lcdc_setup_clocks(pdev, pdata->clock_source, priv); if (error) { dev_err(&pdev->dev, "unable to setup clocks\n"); goto err1; @@ -697,10 +718,9 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev) } #ifdef CONFIG_HAVE_CLK - if (priv->clk) { - clk_disable(priv->clk); - clk_put(priv->clk); - } + if (priv->dot_clk) + clk_put(priv->dot_clk); + clk_put(priv->clk); #endif if (priv->base) -- cgit v1.2.2 From 679dc3c92ca7894c3df70ee3333ff9878e7d90b9 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Fri, 21 Nov 2008 14:34:25 +0900 Subject: sh: sh7760fb: Fix color pallette setting The setting of the color palette was wrong, fixed it. And removed fb_setcmap, and added fb_setcolreg function. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Paul Mundt --- drivers/video/sh7760fb.c | 86 +++++++++++------------------------------------- 1 file changed, 19 insertions(+), 67 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/sh7760fb.c b/drivers/video/sh7760fb.c index 8d0212da4514..653bdfee3057 100644 --- a/drivers/video/sh7760fb.c +++ b/drivers/video/sh7760fb.c @@ -13,6 +13,8 @@ * * Thanks to Siegfried Schaefer * for his original source and testing! + * + * sh7760_setcolreg get from drivers/video/sh_mobile_lcdcfb.c */ #include @@ -53,29 +55,6 @@ static irqreturn_t sh7760fb_irq(int irq, void *data) return IRQ_HANDLED; } -static void sh7760fb_wait_vsync(struct fb_info *info) -{ - struct sh7760fb_par *par = info->par; - - if (par->pd->novsync) - return; - - iowrite16(ioread16(par->base + LDINTR) & ~VINT_CHECK, - par->base + LDINTR); - - if (par->irq < 0) { - /* poll for vert. retrace: status bit is sticky */ - while (!(ioread16(par->base + LDINTR) & VINT_CHECK)) - cpu_relax(); - } else { - /* a "wait_for_irq_event(par->irq)" would be extremely nice */ - init_completion(&par->vsync); - enable_irq(par->irq); - wait_for_completion(&par->vsync); - disable_irq_nosync(par->irq); - } -} - /* wait_for_lps - wait until power supply has reached a certain state. */ static int wait_for_lps(struct sh7760fb_par *par, int val) { @@ -117,55 +96,28 @@ static int sh7760fb_blank(int blank, struct fb_info *info) return wait_for_lps(par, lps); } -/* set color registers */ -static int sh7760fb_setcmap(struct fb_cmap *cmap, struct fb_info *info) +static int sh7760_setcolreg (u_int regno, + u_int red, u_int green, u_int blue, + u_int transp, struct fb_info *info) { - struct sh7760fb_par *par = info->par; - u32 s = cmap->start; - u32 l = cmap->len; - u16 *r = cmap->red; - u16 *g = cmap->green; - u16 *b = cmap->blue; - u32 col, tmo; - int ret; + u32 *palette = info->pseudo_palette; - ret = 0; + if (regno >= 16) + return -EINVAL; - sh7760fb_wait_vsync(info); + /* only FB_VISUAL_TRUECOLOR supported */ - /* request palette access */ - iowrite16(LDPALCR_PALEN, par->base + LDPALCR); + red >>= 16 - info->var.red.length; + green >>= 16 - info->var.green.length; + blue >>= 16 - info->var.blue.length; + transp >>= 16 - info->var.transp.length; - /* poll for access grant */ - tmo = 100; - while (!(ioread16(par->base + LDPALCR) & LDPALCR_PALS) && (--tmo)) - cpu_relax(); + palette[regno] = (red << info->var.red.offset) | + (green << info->var.green.offset) | + (blue << info->var.blue.offset) | + (transp << info->var.transp.offset); - if (!tmo) { - ret = 1; - dev_dbg(info->dev, "no palette access!\n"); - goto out; - } - - while (l && (s < 256)) { - col = ((*r) & 0xff) << 16; - col |= ((*g) & 0xff) << 8; - col |= ((*b) & 0xff); - col &= SH7760FB_PALETTE_MASK; - iowrite32(col, par->base + LDPR(s)); - - if (s < 16) - ((u32 *) (info->pseudo_palette))[s] = s; - - s++; - l--; - r++; - g++; - b++; - } -out: - iowrite16(0, par->base + LDPALCR); - return ret; + return 0; } static void encode_fix(struct fb_fix_screeninfo *fix, struct fb_info *info, @@ -406,7 +358,7 @@ static struct fb_ops sh7760fb_ops = { .owner = THIS_MODULE, .fb_blank = sh7760fb_blank, .fb_check_var = sh7760fb_check_var, - .fb_setcmap = sh7760fb_setcmap, + .fb_setcolreg = sh7760_setcolreg, .fb_set_par = sh7760fb_set_par, .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, -- cgit v1.2.2 From 5c72f303a2b7862dbba79f4176ddc922a440b567 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Fri, 21 Nov 2008 14:35:29 +0900 Subject: sh: sh7760fb: Add support SH7720/SH7721 of Renesas SH7720 and 7721 has IP of Frame Buffer same as SH7760. This driver can support these. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Paul Mundt --- drivers/video/Kconfig | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 3f3ce13fef43..593bbc731016 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -2021,17 +2021,19 @@ config FB_COBALT depends on FB && MIPS_COBALT config FB_SH7760 - bool "SH7760/SH7763 LCDC support" - depends on FB && (CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7763) - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - Support for the SH7760/SH7763 integrated (D)STN/TFT LCD Controller. - Supports display resolutions up to 1024x1024 pixel, grayscale and - color operation, with depths ranging from 1 bpp to 8 bpp monochrome - and 8, 15 or 16 bpp color; 90 degrees clockwise display rotation for - panels <= 320 pixel horizontal resolution. + bool "SH7760/SH7763/SH7720/SH7721 LCDC support" + depends on FB && (CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7763 \ + || CPU_SUBTYPE_SH7720 || CPU_SUBTYPE_SH7721) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + Support for the SH7760/SH7763/SH7720/SH7721 integrated + (D)STN/TFT LCD Controller. + Supports display resolutions up to 1024x1024 pixel, grayscale and + color operation, with depths ranging from 1 bpp to 8 bpp monochrome + and 8, 15 or 16 bpp color; 90 degrees clockwise display rotation for + panels <= 320 pixel horizontal resolution. config FB_VIRTUAL tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)" -- cgit v1.2.2 From 2540c111ead82cad605ec2b14a1905ad914cc124 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 17 Dec 2008 17:29:49 +0900 Subject: sh_mobile_lcdc: use FB_SYS helpers instead of FB_CFB Since the sh_mobile_lcdc hardware has the framebuffer(s) in system RAM, use FB_SYS instead of FB_CFB. Also hook in read and write helpers. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- drivers/video/Kconfig | 8 ++++---- drivers/video/sh_mobile_lcdcfb.c | 8 +++++--- 2 files changed, 9 insertions(+), 7 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 593bbc731016..dd483bfe3951 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -1889,10 +1889,10 @@ config FB_W100 config FB_SH_MOBILE_LCDC tristate "SuperH Mobile LCDC framebuffer support" depends on FB && SUPERH - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - default m + select FB_SYS_FILLRECT + select FB_SYS_COPYAREA + select FB_SYS_IMAGEBLIT + select FB_SYS_FOPS ---help--- Frame buffer driver for the on-chip SH-Mobile LCD controller. diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index c81ee00c54d7..e339d829183c 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c @@ -499,9 +499,11 @@ static struct fb_fix_screeninfo sh_mobile_lcdc_fix = { static struct fb_ops sh_mobile_lcdc_ops = { .fb_setcolreg = sh_mobile_lcdc_setcolreg, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + .fb_read = fb_sys_read, + .fb_write = fb_sys_write, + .fb_fillrect = sys_fillrect, + .fb_copyarea = sys_copyarea, + .fb_imageblit = sys_imageblit, }; static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp) -- cgit v1.2.2 From 87884bd8ae42c875adbd62c84f47ed1cbb3e5090 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 19 Dec 2008 15:34:09 +0900 Subject: video: fix deferred io fsync() If CONFIG_FB_DEFERRED_IO is set, but there are framebuffers registered that does not make use of deferred io, then fsync() on those framebuffers will result in a crash. Fix that. This is needed for sh_mobile_lcdcfb since we always enable deferred io at compile time but we may disable deferred io for some types of hardware configurations. Signed-off-by: Magnus Damm Acked-by: Jaya Kumar Signed-off-by: Paul Mundt --- drivers/video/fb_defio.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/video') diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c index 4835bdc4e9f1..e6dafeddfa5b 100644 --- a/drivers/video/fb_defio.c +++ b/drivers/video/fb_defio.c @@ -60,6 +60,10 @@ int fb_deferred_io_fsync(struct file *file, struct dentry *dentry, int datasync) { struct fb_info *info = file->private_data; + /* Skip if deferred io is complied-in but disabled on this fbdev */ + if (!info->fbdefio) + return 0; + /* Kill off the delayed work */ cancel_rearming_delayed_work(&info->deferred_work); -- cgit v1.2.2 From 6e1038a95bebb8a1ad6066c95aa9c3af6963c9ff Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 19 Dec 2008 15:34:23 +0900 Subject: video: deferred io cleanup Make sure the mmap callback is set to NULL in the deferred io cleanup function. This way we can enable and disable deferred io on the fly. Signed-off-by: Magnus Damm Acked-by: Jaya Kumar Signed-off-by: Paul Mundt --- drivers/video/fb_defio.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/video') diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c index e6dafeddfa5b..06060ccd3c23 100644 --- a/drivers/video/fb_defio.c +++ b/drivers/video/fb_defio.c @@ -202,6 +202,9 @@ void fb_deferred_io_cleanup(struct fb_info *info) page = vmalloc_to_page(screen_base + i); page->mapping = NULL; } + + info->fbops->fb_mmap = NULL; + mutex_destroy(&fbdefio->lock); } EXPORT_SYMBOL_GPL(fb_deferred_io_cleanup); -- cgit v1.2.2 From 37b4837959cb9aa60686ca0d85f73d819251abad Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 19 Dec 2008 15:34:32 +0900 Subject: video: deferred io with physically contiguous memory Extend the deferred io code from only supporting vmalloc()ed frame buffer memory to support both vmalloc()ed and physically contiguous frame buffer memory. The sh_mobile_lcdcfb hardware does not support scatter gather so we need physically contiguous memory to back our frame buffer. Signed-off-by: Magnus Damm Acked-by: Jaya Kumar Signed-off-by: Paul Mundt --- drivers/video/fb_defio.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c index 06060ccd3c23..082026546aee 100644 --- a/drivers/video/fb_defio.c +++ b/drivers/video/fb_defio.c @@ -24,6 +24,19 @@ #include #include +struct page *fb_deferred_io_page(struct fb_info *info, unsigned long offs) +{ + void *screen_base = (void __force *) info->screen_base; + struct page *page; + + if (is_vmalloc_addr(screen_base + offs)) + page = vmalloc_to_page(screen_base + offs); + else + page = pfn_to_page((info->fix.smem_start + offs) >> PAGE_SHIFT); + + return page; +} + /* this is to find and return the vmalloc-ed fb pages */ static int fb_deferred_io_fault(struct vm_area_struct *vma, struct vm_fault *vmf) @@ -31,14 +44,12 @@ static int fb_deferred_io_fault(struct vm_area_struct *vma, unsigned long offset; struct page *page; struct fb_info *info = vma->vm_private_data; - /* info->screen_base is virtual memory */ - void *screen_base = (void __force *) info->screen_base; offset = vmf->pgoff << PAGE_SHIFT; if (offset >= info->fix.smem_len) return VM_FAULT_SIGBUS; - page = vmalloc_to_page(screen_base + offset); + page = fb_deferred_io_page(info, offset); if (!page) return VM_FAULT_SIGBUS; @@ -188,7 +199,6 @@ EXPORT_SYMBOL_GPL(fb_deferred_io_open); void fb_deferred_io_cleanup(struct fb_info *info) { - void *screen_base = (void __force *) info->screen_base; struct fb_deferred_io *fbdefio = info->fbdefio; struct page *page; int i; @@ -199,7 +209,7 @@ void fb_deferred_io_cleanup(struct fb_info *info) /* clear out the mapping that we setup */ for (i = 0 ; i < info->fix.smem_len; i += PAGE_SIZE) { - page = vmalloc_to_page(screen_base + i); + page = fb_deferred_io_page(info, i); page->mapping = NULL; } -- cgit v1.2.2 From 8564557a03c12adb9c4b76ae1e86db4113a04d13 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 19 Dec 2008 15:34:41 +0900 Subject: video: sh_mobile_lcdcfb deferred io support This patch adds sh_mobile_lcdcfb deferred io support for SYS panels. The LCDC hardware block managed by the sh_mobile_lcdcfb driver supports RGB or SYS panel configurations. SYS panels come with an external display controller that is resposible for refreshing the actual LCD panel. RGB panels are controlled directly by the LCDC and they need to be refreshed by the LCDC hardware. In the case of SYS panels we can save some power by configuring the LCDC hardware block in one-shot mode. In this one-shot mode panel refresh is managed by software. This works well together with deferred io since it allows us to stop clocks for most of the time and only enable clocks when we actually want to trigger an update. When there is no fbdev activity the clocks are kept stopped which allows us to deep sleep. The refresh rate in deferred io mode is set using platform data. The same platform data can also be used to disable deferred io mode. As with other deferred io frame buffers user space code should use fsync() on the frame buffer device to trigger an update. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- drivers/video/Kconfig | 1 + drivers/video/sh_mobile_lcdcfb.c | 170 ++++++++++++++++++++++++++++++++++----- 2 files changed, 149 insertions(+), 22 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index dd483bfe3951..d0c821992a99 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -1893,6 +1893,7 @@ config FB_SH_MOBILE_LCDC select FB_SYS_COPYAREA select FB_SYS_IMAGEBLIT select FB_SYS_FOPS + select FB_DEFERRED_IO ---help--- Frame buffer driver for the on-chip SH-Mobile LCD controller. diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index e339d829183c..0e2b8fd24df1 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c @@ -16,7 +16,9 @@ #include #include #include +#include #include