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.3 From 74b114fe2cfff9986b2469b3eb0035ca3d325d00 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 16 Dec 2008 11:44:07 +0100 Subject: i.MX Framebuffer: remove gpio setup function Remove the gpio mux setup function from i.MX framebuffer driver. This function is platform specific and thus should be done by the board setup. As there are currently no in-kernel users of this driver we do not break anything. Acked-by: Krzysztof Helt Signed-off-by: Sascha Hauer --- drivers/video/imxfb.c | 53 --------------------------------------------------- 1 file changed, 53 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c index ccd986140c95..a990d432f524 100644 --- a/drivers/video/imxfb.c +++ b/drivers/video/imxfb.c @@ -357,57 +357,6 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf return 0; } -static void imxfb_setup_gpio(struct imxfb_info *fbi) -{ - int width; - - LCDC_RMCR &= ~(RMCR_LCDC_EN | RMCR_SELF_REF); - - if( fbi->pcr & PCR_TFT ) - width = 16; - else - width = 1 << ((fbi->pcr >> 28) & 0x3); - - switch(width) { - case 16: - imx_gpio_mode(PD30_PF_LD15); - imx_gpio_mode(PD29_PF_LD14); - imx_gpio_mode(PD28_PF_LD13); - imx_gpio_mode(PD27_PF_LD12); - imx_gpio_mode(PD26_PF_LD11); - imx_gpio_mode(PD25_PF_LD10); - imx_gpio_mode(PD24_PF_LD9); - imx_gpio_mode(PD23_PF_LD8); - case 8: - imx_gpio_mode(PD22_PF_LD7); - imx_gpio_mode(PD21_PF_LD6); - imx_gpio_mode(PD20_PF_LD5); - imx_gpio_mode(PD19_PF_LD4); - case 4: - imx_gpio_mode(PD18_PF_LD3); - imx_gpio_mode(PD17_PF_LD2); - case 2: - imx_gpio_mode(PD16_PF_LD1); - case 1: - imx_gpio_mode(PD15_PF_LD0); - } - - /* initialize GPIOs */ - imx_gpio_mode(PD6_PF_LSCLK); - imx_gpio_mode(PD11_PF_CONTRAST); - imx_gpio_mode(PD14_PF_FLM_VSYNC); - imx_gpio_mode(PD13_PF_LP_HSYNC); - imx_gpio_mode(PD12_PF_ACD_OE); - - /* These are only needed for Sharp HR TFT displays */ - if (fbi->pcr & PCR_SHARP) { - imx_gpio_mode(PD7_PF_REV); - imx_gpio_mode(PD8_PF_CLS); - imx_gpio_mode(PD9_PF_PS); - imx_gpio_mode(PD10_PF_SPL_SPR); - } -} - #ifdef CONFIG_PM /* * Power management hooks. Note that we won't be called from IRQ context, @@ -594,8 +543,6 @@ static int __init imxfb_probe(struct platform_device *pdev) if (ret < 0) goto failed_cmap; - imxfb_setup_gpio(fbi); - imxfb_set_par(info); ret = register_framebuffer(info); if (ret < 0) { -- cgit v1.2.3 From 72330b0eeefc7abda35b5af55d0e2a9a3d05f04c Mon Sep 17 00:00:00 2001 From: Juergen Beisert Date: Tue, 16 Dec 2008 11:44:07 +0100 Subject: i.MX Framebuffer: Use readl/writel instead of direct pointer deref This patch prepares the current i.MX1 framebuffer driver for usage in the whole i.MX family. It switches to readl/writel for register accesses. Also it moves the register definitions to the driver where they belong. Acked-by: Krzysztof Helt Signed-off-by: Juergen Beisert Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/include/mach/imxfb.h | 45 ++++++++ drivers/video/imxfb.c | 193 ++++++++++++++++++++++----------- drivers/video/imxfb.h | 3 +- 3 files changed, 175 insertions(+), 66 deletions(-) (limited to 'drivers/video') diff --git a/arch/arm/mach-imx/include/mach/imxfb.h b/arch/arm/mach-imx/include/mach/imxfb.h index 3ed9ec8b9f00..3f24f741e906 100644 --- a/arch/arm/mach-imx/include/mach/imxfb.h +++ b/arch/arm/mach-imx/include/mach/imxfb.h @@ -1,6 +1,51 @@ /* * This structure describes the machine which we are running on. */ + +#define PCR_TFT (1 << 31) +#define PCR_COLOR (1 << 30) +#define PCR_PBSIZ_1 (0 << 28) +#define PCR_PBSIZ_2 (1 << 28) +#define PCR_PBSIZ_4 (2 << 28) +#define PCR_PBSIZ_8 (3 << 28) +#define PCR_BPIX_1 (0 << 25) +#define PCR_BPIX_2 (1 << 25) +#define PCR_BPIX_4 (2 << 25) +#define PCR_BPIX_8 (3 << 25) +#define PCR_BPIX_12 (4 << 25) +#define PCR_BPIX_16 (4 << 25) +#define PCR_PIXPOL (1 << 24) +#define PCR_FLMPOL (1 << 23) +#define PCR_LPPOL (1 << 22) +#define PCR_CLKPOL (1 << 21) +#define PCR_OEPOL (1 << 20) +#define PCR_SCLKIDLE (1 << 19) +#define PCR_END_SEL (1 << 18) +#define PCR_END_BYTE_SWAP (1 << 17) +#define PCR_REV_VS (1 << 16) +#define PCR_ACD_SEL (1 << 15) +#define PCR_ACD(x) (((x) & 0x7f) << 8) +#define PCR_SCLK_SEL (1 << 7) +#define PCR_SHARP (1 << 6) +#define PCR_PCD(x) ((x) & 0x3f) + +#define PWMR_CLS(x) (((x) & 0x1ff) << 16) +#define PWMR_LDMSK (1 << 15) +#define PWMR_SCR1 (1 << 10) +#define PWMR_SCR0 (1 << 9) +#define PWMR_CC_EN (1 << 8) +#define PWMR_PW(x) ((x) & 0xff) + +#define LSCR1_PS_RISE_DELAY(x) (((x) & 0x7f) << 26) +#define LSCR1_CLS_RISE_DELAY(x) (((x) & 0x3f) << 16) +#define LSCR1_REV_TOGGLE_DELAY(x) (((x) & 0xf) << 8) +#define LSCR1_GRAY2(x) (((x) & 0xf) << 4) +#define LSCR1_GRAY1(x) (((x) & 0xf)) + +#define DMACR_BURST (1 << 31) +#define DMACR_HM(x) (((x) & 0xf) << 16) +#define DMACR_TM(x) ((x) & 0xf) + struct imxfb_mach_info { u_long pixclock; diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c index a990d432f524..1bccf5ad0c7d 100644 --- a/drivers/video/imxfb.c +++ b/drivers/video/imxfb.c @@ -16,7 +16,6 @@ * linux-arm-kernel@lists.arm.linux.org.uk */ -//#define DEBUG 1 #include #include @@ -32,9 +31,8 @@ #include #include #include +#include -#include -#include #include /* @@ -44,6 +42,73 @@ #include "imxfb.h" +#define DRIVER_NAME "imx-fb" + +#define LCDC_SSA 0x00 + +#define LCDC_SIZE 0x04 +#define SIZE_XMAX(x) ((((x) >> 4) & 0x3f) << 20) +#define SIZE_YMAX(y) ((y) & 0x1ff) + +#define LCDC_VPW 0x08 +#define VPW_VPW(x) ((x) & 0x3ff) + +#define LCDC_CPOS 0x0C +#define CPOS_CC1 (1<<31) +#define CPOS_CC0 (1<<30) +#define CPOS_OP (1<<28) +#define CPOS_CXP(x) (((x) & 3ff) << 16) +#define CPOS_CYP(y) ((y) & 0x1ff) + +#define LCDC_LCWHB 0x10 +#define LCWHB_BK_EN (1<<31) +#define LCWHB_CW(w) (((w) & 0x1f) << 24) +#define LCWHB_CH(h) (((h) & 0x1f) << 16) +#define LCWHB_BD(x) ((x) & 0xff) + +#define LCDC_LCHCC 0x14 +#define LCHCC_CUR_COL_R(r) (((r) & 0x1f) << 11) +#define LCHCC_CUR_COL_G(g) (((g) & 0x3f) << 5) +#define LCHCC_CUR_COL_B(b) ((b) & 0x1f) + +#define LCDC_PCR 0x18 + +#define LCDC_HCR 0x1C +#define HCR_H_WIDTH(x) (((x) & 0x3f) << 26) +#define HCR_H_WAIT_1(x) (((x) & 0xff) << 8) +#define HCR_H_WAIT_2(x) ((x) & 0xff) + +#define LCDC_VCR 0x20 +#define VCR_V_WIDTH(x) (((x) & 0x3f) << 26) +#define VCR_V_WAIT_1(x) (((x) & 0xff) << 8) +#define VCR_V_WAIT_2(x) ((x) & 0xff) + +#define LCDC_POS 0x24 +#define POS_POS(x) ((x) & 1f) + +#define LCDC_LSCR1 0x28 +/* bit fields in imxfb.h */ + +#define LCDC_PWMR 0x2C +/* bit fields in imxfb.h */ + +#define LCDC_DMACR 0x30 +/* bit fields in imxfb.h */ + +#define LCDC_RMCR 0x34 +#define RMCR_LCDC_EN (1<<1) +#define RMCR_SELF_REF (1<<0) + +#define LCDC_LCDICR 0x38 +#define LCDICR_INT_SYN (1<<2) +#define LCDICR_INT_CON (1) + +#define LCDC_LCDISR 0x40 +#define LCDISR_UDR_ERR (1<<3) +#define LCDISR_ERR_RES (1<<2) +#define LCDISR_EOF (1<<1) +#define LCDISR_BOF (1<<0) + static struct imxfb_rgb def_rgb_16 = { .red = { .offset = 8, .length = 4, }, .green = { .offset = 4, .length = 4, }, @@ -67,7 +132,6 @@ static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf) return chan << bf->offset; } -#define LCDC_PALETTE(x) __REG2(IMX_LCDC_BASE+0x800, (x)<<2) static int imxfb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue, u_int trans, struct fb_info *info) @@ -81,7 +145,7 @@ imxfb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue, (CNVT_TOHW(green,4) << 4) | CNVT_TOHW(blue, 4); - LCDC_PALETTE(regno) = val; + writel(val, fbi->regs + 0x800 + (regno << 2)); ret = 0; } return ret; @@ -235,18 +299,23 @@ static void imxfb_enable_controller(struct imxfb_info *fbi) pr_debug("Enabling LCD controller\n"); /* initialize LCDC */ - LCDC_RMCR &= ~RMCR_LCDC_EN; /* just to be safe... */ + writel(readl(fbi->regs + LCDC_RMCR) & ~RMCR_LCDC_EN, + fbi->regs + LCDC_RMCR); /* just to be safe... */ + + writel(fbi->screen_dma, fbi->regs + LCDC_SSA); - LCDC_SSA = fbi->screen_dma; /* physical screen start address */ - LCDC_VPW = VPW_VPW(fbi->max_xres * fbi->max_bpp / 8 / 4); + writel(VPW_VPW(fbi->max_xres * fbi->max_bpp / 8 / 4), + fbi->regs + LCDC_VPW); - LCDC_POS = 0x00000000; /* panning offset 0 (0 pixel offset) */ + /* panning offset 0 (0 pixel offset) */ + writel(0x00000000, fbi->regs + LCDC_POS); /* disable hardware cursor */ - LCDC_CPOS &= ~(CPOS_CC0 | CPOS_CC1); + writel(readl(fbi->regs + LCDC_CPOS) & ~(CPOS_CC0 | CPOS_CC1), + fbi->regs + LCDC_CPOS); - LCDC_RMCR = RMCR_LCDC_EN; + writel(RMCR_LCDC_EN, fbi->regs + LCDC_RMCR); if(fbi->backlight_power) fbi->backlight_power(1); @@ -263,7 +332,7 @@ static void imxfb_disable_controller(struct imxfb_info *fbi) if(fbi->lcd_power) fbi->lcd_power(0); - LCDC_RMCR = 0; + writel(0, fbi->regs + LCDC_RMCR); } static int imxfb_blank(int blank, struct fb_info *info) @@ -340,19 +409,22 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf info->fix.id, var->lower_margin); #endif - LCDC_HCR = HCR_H_WIDTH(var->hsync_len) | - HCR_H_WAIT_1(var->left_margin) | - HCR_H_WAIT_2(var->right_margin); + writel(HCR_H_WIDTH(var->hsync_len) | + HCR_H_WAIT_1(var->left_margin) | + HCR_H_WAIT_2(var->right_margin), + fbi->regs + LCDC_HCR); - LCDC_VCR = VCR_V_WIDTH(var->vsync_len) | - VCR_V_WAIT_1(var->upper_margin) | - VCR_V_WAIT_2(var->lower_margin); + writel(VCR_V_WIDTH(var->vsync_len) | + VCR_V_WAIT_1(var->upper_margin) | + VCR_V_WAIT_2(var->lower_margin), + fbi->regs + LCDC_VCR); - LCDC_SIZE = SIZE_XMAX(var->xres) | SIZE_YMAX(var->yres); - LCDC_PCR = fbi->pcr; - LCDC_PWMR = fbi->pwmr; - LCDC_LSCR1 = fbi->lscr1; - LCDC_DMACR = fbi->dmacr; + writel(SIZE_XMAX(var->xres) | SIZE_YMAX(var->yres), + fbi->regs + LCDC_SIZE); + writel(fbi->pcr, fbi->regs + LCDC_PCR); + writel(fbi->pwmr, fbi->regs + LCDC_PWMR); + writel(fbi->lscr1, fbi->regs + LCDC_LSCR1); + writel(fbi->dmacr, fbi->regs + LCDC_DMACR); return 0; } @@ -384,10 +456,10 @@ static int imxfb_resume(struct platform_device *dev) #define imxfb_resume NULL #endif -static int __init imxfb_init_fbinfo(struct device *dev) +static int __init imxfb_init_fbinfo(struct platform_device *pdev) { - struct imxfb_mach_info *inf = dev->platform_data; - struct fb_info *info = dev_get_drvdata(dev); + struct imxfb_mach_info *inf = pdev->dev.platform_data; + struct fb_info *info = dev_get_drvdata(&pdev->dev); struct imxfb_info *fbi = info->par; pr_debug("%s\n",__func__); @@ -397,7 +469,6 @@ static int __init imxfb_init_fbinfo(struct device *dev) return -ENOMEM; memset(fbi, 0, sizeof(struct imxfb_info)); - fbi->dev = dev; strlcpy(info->fix.id, IMX_NAME, sizeof(info->fix.id)); @@ -453,31 +524,6 @@ static int __init imxfb_init_fbinfo(struct device *dev) return 0; } -/* - * Allocates the DRAM memory for the frame buffer. This buffer is - * remapped into a non-cached, non-buffered, memory region to - * allow pixel writes to occur without flushing the cache. - * Once this area is remapped, all virtual memory access to the - * video memory should occur at the new region. - */ -static int __init imxfb_map_video_memory(struct fb_info *info) -{ - struct imxfb_info *fbi = info->par; - - fbi->map_size = PAGE_ALIGN(info->fix.smem_len); - fbi->map_cpu = dma_alloc_writecombine(fbi->dev, fbi->map_size, - &fbi->map_dma,GFP_KERNEL); - - if (fbi->map_cpu) { - info->screen_base = fbi->map_cpu; - fbi->screen_cpu = fbi->map_cpu; - fbi->screen_dma = fbi->map_dma; - info->fix.smem_start = fbi->screen_dma; - } - - return fbi->map_cpu ? 0 : -ENOMEM; -} - static int __init imxfb_probe(struct platform_device *pdev) { struct imxfb_info *fbi; @@ -506,23 +552,38 @@ static int __init imxfb_probe(struct platform_device *pdev) platform_set_drvdata(pdev, info); - ret = imxfb_init_fbinfo(&pdev->dev); + ret = imxfb_init_fbinfo(pdev); if( ret < 0 ) goto failed_init; - res = request_mem_region(res->start, res->end - res->start + 1, "IMXFB"); + res = request_mem_region(res->start, resource_size(res), + DRIVER_NAME); if (!res) { ret = -EBUSY; - goto failed_regs; + goto failed_req; + } + + fbi->regs = ioremap(res->start, resource_size(res)); + if (fbi->regs == NULL) { + printk(KERN_ERR"Cannot map frame buffer registers\n"); + goto failed_ioremap; } if (!inf->fixed_screen_cpu) { - ret = imxfb_map_video_memory(info); - if (ret) { + fbi->map_size = PAGE_ALIGN(info->fix.smem_len); + fbi->map_cpu = dma_alloc_writecombine(&pdev->dev, + fbi->map_size, &fbi->map_dma, GFP_KERNEL); + + if (!fbi->map_cpu) { dev_err(&pdev->dev, "Failed to allocate video RAM: %d\n", ret); ret = -ENOMEM; goto failed_map; } + + info->screen_base = fbi->map_cpu; + fbi->screen_cpu = fbi->map_cpu; + fbi->screen_dma = fbi->map_dma; + info->fix.smem_start = fbi->screen_dma; } else { /* Fixed framebuffer mapping enables location of the screen in eSRAM */ fbi->map_cpu = inf->fixed_screen_cpu; @@ -559,18 +620,20 @@ failed_register: failed_cmap: if (!inf->fixed_screen_cpu) dma_free_writecombine(&pdev->dev,fbi->map_size,fbi->map_cpu, - fbi->map_dma); + fbi->map_dma); failed_map: - kfree(info->pseudo_palette); -failed_regs: + iounmap(fbi->regs); +failed_ioremap: release_mem_region(res->start, res->end - res->start); +failed_req: + kfree(info->pseudo_palette); failed_init: platform_set_drvdata(pdev, NULL); framebuffer_release(info); return ret; } -static int imxfb_remove(struct platform_device *pdev) +static int __devexit imxfb_remove(struct platform_device *pdev) { struct fb_info *info = platform_get_drvdata(pdev); struct imxfb_info *fbi = info->par; @@ -586,6 +649,7 @@ static int imxfb_remove(struct platform_device *pdev) kfree(info->pseudo_palette); framebuffer_release(info); + iounmap(fbi->regs); release_mem_region(res->start, res->end - res->start + 1); platform_set_drvdata(pdev, NULL); @@ -600,19 +664,18 @@ void imxfb_shutdown(struct platform_device * dev) } static struct platform_driver imxfb_driver = { - .probe = imxfb_probe, .suspend = imxfb_suspend, .resume = imxfb_resume, - .remove = imxfb_remove, + .remove = __devexit_p(imxfb_remove), .shutdown = imxfb_shutdown, .driver = { - .name = "imx-fb", + .name = DRIVER_NAME, }, }; int __init imxfb_init(void) { - return platform_driver_register(&imxfb_driver); + return platform_driver_probe(&imxfb_driver, imxfb_probe); } static void __exit imxfb_cleanup(void) diff --git a/drivers/video/imxfb.h b/drivers/video/imxfb.h index e837a8b48eb8..baa86a0fe29e 100644 --- a/drivers/video/imxfb.h +++ b/drivers/video/imxfb.h @@ -29,7 +29,8 @@ struct imxfb_rgb { #define NR_RGB 2 struct imxfb_info { - struct device *dev; + void __iomem *regs; + struct imxfb_rgb *rgb[NR_RGB]; u_int max_bpp; -- cgit v1.2.3 From d6ed5755ac26044473bcc9c9d2659624003652c8 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 16 Dec 2008 11:44:08 +0100 Subject: i.MX Framebuffer: fix margins The upper/lower and left/right margins are mixed up in the driver. Fix it Acked-by: Krzysztof Helt Signed-off-by: Sascha Hauer --- drivers/video/imxfb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c index 1bccf5ad0c7d..feaae73f56ac 100644 --- a/drivers/video/imxfb.c +++ b/drivers/video/imxfb.c @@ -410,13 +410,13 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf #endif writel(HCR_H_WIDTH(var->hsync_len) | - HCR_H_WAIT_1(var->left_margin) | - HCR_H_WAIT_2(var->right_margin), + HCR_H_WAIT_1(var->right_margin) | + HCR_H_WAIT_2(var->left_margin), fbi->regs + LCDC_HCR); writel(VCR_V_WIDTH(var->vsync_len) | - VCR_V_WAIT_1(var->upper_margin) | - VCR_V_WAIT_2(var->lower_margin), + VCR_V_WAIT_1(var->lower_margin) | + VCR_V_WAIT_2(var->upper_margin), fbi->regs + LCDC_VCR); writel(SIZE_XMAX(var->xres) | SIZE_YMAX(var->yres), -- cgit v1.2.3 From 24b9baf7a5678b95edb2a358594abd54dc69f8a0 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 16 Dec 2008 11:44:08 +0100 Subject: i.MX Framebuffer: remove header file Move contents of imxfb.h to imxfb.c since it is used only in this file Signed-off-by: Sascha Hauer --- drivers/video/imxfb.c | 62 ++++++++++++++++++++++++++++++++++++++++-- drivers/video/imxfb.h | 74 --------------------------------------------------- 2 files changed, 60 insertions(+), 76 deletions(-) delete mode 100644 drivers/video/imxfb.h (limited to 'drivers/video') diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c index feaae73f56ac..7b3400cfae6d 100644 --- a/drivers/video/imxfb.c +++ b/drivers/video/imxfb.c @@ -40,8 +40,6 @@ */ #define DEBUG_VAR 1 -#include "imxfb.h" - #define DRIVER_NAME "imx-fb" #define LCDC_SSA 0x00 @@ -109,6 +107,66 @@ #define LCDISR_EOF (1<<1) #define LCDISR_BOF (1<<0) +/* + * These are the bitfields for each + * display depth that we support. + */ +struct imxfb_rgb { + struct fb_bitfield red; + struct fb_bitfield green; + struct fb_bitfield blue; + struct fb_bitfield transp; +}; + +#define RGB_16 (0) +#define RGB_8 (1) +#define NR_RGB 2 + +struct imxfb_info { + struct platform_device *pdev; + void __iomem *regs; + + struct imxfb_rgb *rgb[NR_RGB]; + + u_int max_bpp; + u_int max_xres; + u_int max_yres; + + /* + * These are the addresses we mapped + * the framebuffer memory region to. + */ + dma_addr_t map_dma; + u_char *map_cpu; + u_int map_size; + + u_char *screen_cpu; + dma_addr_t screen_dma; + u_int palette_size; + + dma_addr_t dbar1; + dma_addr_t dbar2; + + u_int pcr; + u_int pwmr; + u_int lscr1; + u_int dmacr; + u_int cmap_inverse:1, + cmap_static:1, + unused:30; + + void (*lcd_power)(int); + void (*backlight_power)(int); +}; + +#define IMX_NAME "IMX" + +/* + * Minimum X and Y resolutions + */ +#define MIN_XRES 64 +#define MIN_YRES 64 + static struct imxfb_rgb def_rgb_16 = { .red = { .offset = 8, .length = 4, }, .green = { .offset = 4, .length = 4, }, diff --git a/drivers/video/imxfb.h b/drivers/video/imxfb.h deleted file mode 100644 index baa86a0fe29e..000000000000 --- a/drivers/video/imxfb.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * linux/drivers/video/imxfb.h - * - * Freescale i.MX Frame Buffer device driver - * - * Copyright (C) 2004 S.Hauer, Pengutronix - * - * Copyright (C) 1999 Eric A. Thomas - * Based on acornfb.c Copyright (C) Russell King. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - */ - -/* - * These are the bitfields for each - * display depth that we support. - */ -struct imxfb_rgb { - struct fb_bitfield red; - struct fb_bitfield green; - struct fb_bitfield blue; - struct fb_bitfield transp; -}; - -#define RGB_16 (0) -#define RGB_8 (1) -#define NR_RGB 2 - -struct imxfb_info { - void __iomem *regs; - - struct imxfb_rgb *rgb[NR_RGB]; - - u_int max_bpp; - u_int max_xres; - u_int max_yres; - - /* - * These are the addresses we mapped - * the framebuffer memory region to. - */ - dma_addr_t map_dma; - u_char * map_cpu; - u_int map_size; - - u_char * screen_cpu; - dma_addr_t screen_dma; - u_int palette_size; - - dma_addr_t dbar1; - dma_addr_t dbar2; - - u_int pcr; - u_int pwmr; - u_int lscr1; - u_int dmacr; - u_int cmap_inverse:1, - cmap_static:1, - unused:30; - - void (*lcd_power)(int); - void (*backlight_power)(int); -}; - -#define IMX_NAME "IMX" - -/* - * Minimum X and Y resolutions - */ -#define MIN_XRES 64 -#define MIN_YRES 64 - -- cgit v1.2.3 From 66c8719b2edaa08f23f3106c697891e6c765bd7a Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 16 Dec 2008 11:44:08 +0100 Subject: i.MX Framebuffer: Cleanup Coding style Signed-off-by: Sascha Hauer --- drivers/video/imxfb.c | 70 +++++++++++++++++++++++++-------------------------- 1 file changed, 34 insertions(+), 36 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c index 7b3400cfae6d..25323ea33a54 100644 --- a/drivers/video/imxfb.c +++ b/drivers/video/imxfb.c @@ -1,6 +1,4 @@ /* - * linux/drivers/video/imxfb.c - * * Freescale i.MX Frame Buffer device driver * * Copyright (C) 2004 Sascha Hauer, Pengutronix @@ -168,20 +166,21 @@ struct imxfb_info { #define MIN_YRES 64 static struct imxfb_rgb def_rgb_16 = { - .red = { .offset = 8, .length = 4, }, - .green = { .offset = 4, .length = 4, }, - .blue = { .offset = 0, .length = 4, }, - .transp = { .offset = 0, .length = 0, }, + .red = {.offset = 8, .length = 4,}, + .green = {.offset = 4, .length = 4,}, + .blue = {.offset = 0, .length = 4,}, + .transp = {.offset = 0, .length = 0,}, }; static struct imxfb_rgb def_rgb_8 = { - .red = { .offset = 0, .length = 8, }, - .green = { .offset = 0, .length = 8, }, - .blue = { .offset = 0, .length = 8, }, - .transp = { .offset = 0, .length = 0, }, + .red = {.offset = 0, .length = 8,}, + .green = {.offset = 0, .length = 8,}, + .blue = {.offset = 0, .length = 8,}, + .transp = {.offset = 0, .length = 0,}, }; -static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *info); +static int imxfb_activate_var(struct fb_var_screeninfo *var, + struct fb_info *info); static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf) { @@ -190,9 +189,8 @@ static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf) return chan << bf->offset; } -static int -imxfb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue, - u_int trans, struct fb_info *info) +static int imxfb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue, + u_int trans, struct fb_info *info) { struct imxfb_info *fbi = info->par; u_int val, ret = 1; @@ -209,8 +207,7 @@ imxfb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue, return ret; } -static int -imxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, +static int imxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int trans, struct fb_info *info) { struct imxfb_info *fbi = info->par; @@ -270,8 +267,7 @@ imxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, * yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale, * bitfields, horizontal timing, vertical timing. */ -static int -imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) +static int imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { struct imxfb_info *fbi = info->par; int rgbidx; @@ -343,8 +339,7 @@ static int imxfb_set_par(struct fb_info *info) info->fix.visual = FB_VISUAL_STATIC_PSEUDOCOLOR; } - info->fix.line_length = var->xres_virtual * - var->bits_per_pixel / 8; + info->fix.line_length = var->xres_virtual * var->bits_per_pixel / 8; fbi->palette_size = var->bits_per_pixel == 8 ? 256 : 16; imxfb_activate_var(var, info); @@ -375,9 +370,9 @@ static void imxfb_enable_controller(struct imxfb_info *fbi) writel(RMCR_LCDC_EN, fbi->regs + LCDC_RMCR); - if(fbi->backlight_power) + if (fbi->backlight_power) fbi->backlight_power(1); - if(fbi->lcd_power) + if (fbi->lcd_power) fbi->lcd_power(1); } @@ -385,9 +380,9 @@ static void imxfb_disable_controller(struct imxfb_info *fbi) { pr_debug("Disabling LCD controller\n"); - if(fbi->backlight_power) + if (fbi->backlight_power) fbi->backlight_power(0); - if(fbi->lcd_power) + if (fbi->lcd_power) fbi->lcd_power(0); writel(0, fbi->regs + LCDC_RMCR); @@ -495,7 +490,8 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf static int imxfb_suspend(struct platform_device *dev, pm_message_t state) { struct imxfb_info *fbi = platform_get_drvdata(dev); - pr_debug("%s\n",__func__); + + pr_debug("%s\n", __func__); imxfb_disable_controller(fbi); return 0; @@ -504,7 +500,8 @@ static int imxfb_suspend(struct platform_device *dev, pm_message_t state) static int imxfb_resume(struct platform_device *dev) { struct imxfb_info *fbi = platform_get_drvdata(dev); - pr_debug("%s\n",__func__); + + pr_debug("%s\n", __func__); imxfb_enable_controller(fbi); return 0; @@ -522,7 +519,7 @@ static int __init imxfb_init_fbinfo(struct platform_device *pdev) pr_debug("%s\n",__func__); - info->pseudo_palette = kmalloc( sizeof(u32) * 16, GFP_KERNEL); + info->pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL); if (!info->pseudo_palette) return -ENOMEM; @@ -530,22 +527,23 @@ static int __init imxfb_init_fbinfo(struct platform_device *pdev) strlcpy(info->fix.id, IMX_NAME, sizeof(info->fix.id)); - info->fix.type = FB_TYPE_PACKED_PIXELS; + info->fix.type = FB_TYPE_PACKED_PIXELS; info->fix.type_aux = 0; info->fix.xpanstep = 0; info->fix.ypanstep = 0; info->fix.ywrapstep = 0; - info->fix.accel = FB_ACCEL_NONE; + info->fix.accel = FB_ACCEL_NONE; info->var.nonstd = 0; info->var.activate = FB_ACTIVATE_NOW; info->var.height = -1; info->var.width = -1; info->var.accel_flags = 0; - info->var.vmode = FB_VMODE_NONINTERLACED; + info->var.vmode = FB_VMODE_NONINTERLACED; info->fbops = &imxfb_ops; - info->flags = FBINFO_FLAG_DEFAULT | FBINFO_READS_FAST; + info->flags = FBINFO_FLAG_DEFAULT | + FBINFO_READS_FAST; fbi->rgb[RGB_16] = &def_rgb_16; fbi->rgb[RGB_8] = &def_rgb_8; @@ -593,17 +591,17 @@ static int __init imxfb_probe(struct platform_device *pdev) printk("i.MX Framebuffer driver\n"); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if(!res) + if (!res) return -ENODEV; inf = pdev->dev.platform_data; - if(!inf) { + if (!inf) { dev_err(&pdev->dev,"No platform_data available\n"); return -ENOMEM; } info = framebuffer_alloc(sizeof(struct imxfb_info), &pdev->dev); - if(!info) + if (!info) return -ENOMEM; fbi = info->par; @@ -611,7 +609,7 @@ static int __init imxfb_probe(struct platform_device *pdev) platform_set_drvdata(pdev, info); ret = imxfb_init_fbinfo(pdev); - if( ret < 0 ) + if (ret < 0) goto failed_init; res = request_mem_region(res->start, resource_size(res), @@ -658,7 +656,7 @@ static int __init imxfb_probe(struct platform_device *pdev) */ imxfb_check_var(&info->var, info); - ret = fb_alloc_cmap(&info->cmap, 1<var.bits_per_pixel, 0); + ret = fb_alloc_cmap(&info->cmap, 1 << info->var.bits_per_pixel, 0); if (ret < 0) goto failed_cmap; -- cgit v1.2.3 From 278892736e99330195c8ae5861bcd9d791bbf19e Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 16 Dec 2008 11:44:09 +0100 Subject: i.MX Framebuffer: rename imxfb_mach_info to imx_fb_platform_data rename imxfb_mach_info to a name more common to kernel hackers Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/include/mach/imxfb.h | 5 ++- drivers/video/imxfb.c | 68 +++++++++++++++++----------------- 2 files changed, 37 insertions(+), 36 deletions(-) (limited to 'drivers/video') diff --git a/arch/arm/mach-imx/include/mach/imxfb.h b/arch/arm/mach-imx/include/mach/imxfb.h index 3f24f741e906..870d0d939616 100644 --- a/arch/arm/mach-imx/include/mach/imxfb.h +++ b/arch/arm/mach-imx/include/mach/imxfb.h @@ -46,7 +46,7 @@ #define DMACR_HM(x) (((x) & 0xf) << 16) #define DMACR_TM(x) ((x) & 0xf) -struct imxfb_mach_info { +struct imx_fb_platform_data { u_long pixclock; u_short xres; @@ -79,4 +79,5 @@ struct imxfb_mach_info { void (*lcd_power)(int); void (*backlight_power)(int); }; -void set_imx_fb_info(struct imxfb_mach_info *hard_imx_fb_info); + +void set_imx_fb_info(struct imx_fb_platform_data *); diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c index 25323ea33a54..3d1db003f995 100644 --- a/drivers/video/imxfb.c +++ b/drivers/video/imxfb.c @@ -513,7 +513,7 @@ static int imxfb_resume(struct platform_device *dev) static int __init imxfb_init_fbinfo(struct platform_device *pdev) { - struct imxfb_mach_info *inf = pdev->dev.platform_data; + struct imx_fb_platform_data *pdata = pdev->dev.platform_data; struct fb_info *info = dev_get_drvdata(&pdev->dev); struct imxfb_info *fbi = info->par; @@ -548,32 +548,32 @@ static int __init imxfb_init_fbinfo(struct platform_device *pdev) fbi->rgb[RGB_16] = &def_rgb_16; fbi->rgb[RGB_8] = &def_rgb_8; - fbi->max_xres = inf->xres; - info->var.xres = inf->xres; - info->var.xres_virtual = inf->xres; - fbi->max_yres = inf->yres; - info->var.yres = inf->yres; - info->var.yres_virtual = inf->yres; - fbi->max_bpp = inf->bpp; - info->var.bits_per_pixel = inf->bpp; - info->var.nonstd = inf->nonstd; - info->var.pixclock = inf->pixclock; - info->var.hsync_len = inf->hsync_len; - info->var.left_margin = inf->left_margin; - info->var.right_margin = inf->right_margin; - info->var.vsync_len = inf->vsync_len; - info->var.upper_margin = inf->upper_margin; - info->var.lower_margin = inf->lower_margin; - info->var.sync = inf->sync; - info->var.grayscale = inf->cmap_greyscale; - fbi->cmap_inverse = inf->cmap_inverse; - fbi->cmap_static = inf->cmap_static; - fbi->pcr = inf->pcr; - fbi->lscr1 = inf->lscr1; - fbi->dmacr = inf->dmacr; - fbi->pwmr = inf->pwmr; - fbi->lcd_power = inf->lcd_power; - fbi->backlight_power = inf->backlight_power; + fbi->max_xres = pdata->xres; + info->var.xres = pdata->xres; + info->var.xres_virtual = pdata->xres; + fbi->max_yres = pdata->yres; + info->var.yres = pdata->yres; + info->var.yres_virtual = pdata->yres; + fbi->max_bpp = pdata->bpp; + info->var.bits_per_pixel = pdata->bpp; + info->var.nonstd = pdata->nonstd; + info->var.pixclock = pdata->pixclock; + info->var.hsync_len = pdata->hsync_len; + info->var.left_margin = pdata->left_margin; + info->var.right_margin = pdata->right_margin; + info->var.vsync_len = pdata->vsync_len; + info->var.upper_margin = pdata->upper_margin; + info->var.lower_margin = pdata->lower_margin; + info->var.sync = pdata->sync; + info->var.grayscale = pdata->cmap_greyscale; + fbi->cmap_inverse = pdata->cmap_inverse; + fbi->cmap_static = pdata->cmap_static; + fbi->pcr = pdata->pcr; + fbi->lscr1 = pdata->lscr1; + fbi->dmacr = pdata->dmacr; + fbi->pwmr = pdata->pwmr; + fbi->lcd_power = pdata->lcd_power; + fbi->backlight_power = pdata->backlight_power; info->fix.smem_len = fbi->max_xres * fbi->max_yres * fbi->max_bpp / 8; @@ -584,7 +584,7 @@ static int __init imxfb_probe(struct platform_device *pdev) { struct imxfb_info *fbi; struct fb_info *info; - struct imxfb_mach_info *inf; + struct imx_fb_platform_data *pdata; struct resource *res; int ret; @@ -594,8 +594,8 @@ static int __init imxfb_probe(struct platform_device *pdev) if (!res) return -ENODEV; - inf = pdev->dev.platform_data; - if (!inf) { + pdata = pdev->dev.platform_data; + if (!pdata) { dev_err(&pdev->dev,"No platform_data available\n"); return -ENOMEM; } @@ -625,7 +625,7 @@ static int __init imxfb_probe(struct platform_device *pdev) goto failed_ioremap; } - if (!inf->fixed_screen_cpu) { + if (!pdata->fixed_screen_cpu) { fbi->map_size = PAGE_ALIGN(info->fix.smem_len); fbi->map_cpu = dma_alloc_writecombine(&pdev->dev, fbi->map_size, &fbi->map_dma, GFP_KERNEL); @@ -642,8 +642,8 @@ static int __init imxfb_probe(struct platform_device *pdev) info->fix.smem_start = fbi->screen_dma; } else { /* Fixed framebuffer mapping enables location of the screen in eSRAM */ - fbi->map_cpu = inf->fixed_screen_cpu; - fbi->map_dma = inf->fixed_screen_dma; + fbi->map_cpu = pdata->fixed_screen_cpu; + fbi->map_dma = pdata->fixed_screen_dma; info->screen_base = fbi->map_cpu; fbi->screen_cpu = fbi->map_cpu; fbi->screen_dma = fbi->map_dma; @@ -674,7 +674,7 @@ static int __init imxfb_probe(struct platform_device *pdev) failed_register: fb_dealloc_cmap(&info->cmap); failed_cmap: - if (!inf->fixed_screen_cpu) + if (!pdata->fixed_screen_cpu) dma_free_writecombine(&pdev->dev,fbi->map_size,fbi->map_cpu, fbi->map_dma); failed_map: -- cgit v1.2.3 From 80eee6bca4069c48247005aa07cb5e8e86042aa3 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 16 Dec 2008 11:44:09 +0100 Subject: i.MX Framebuffer: add TFT support With TFTs we can do 5/6/5 instead of 4/4/4. Add a bitfield for this and use it with TFTs. Acked-by: Krzysztof Helt Signed-off-by: Sascha Hauer --- drivers/video/imxfb.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c index 3d1db003f995..d58c68cd456e 100644 --- a/drivers/video/imxfb.c +++ b/drivers/video/imxfb.c @@ -116,16 +116,10 @@ struct imxfb_rgb { struct fb_bitfield transp; }; -#define RGB_16 (0) -#define RGB_8 (1) -#define NR_RGB 2 - struct imxfb_info { struct platform_device *pdev; void __iomem *regs; - struct imxfb_rgb *rgb[NR_RGB]; - u_int max_bpp; u_int max_xres; u_int max_yres; @@ -165,7 +159,14 @@ struct imxfb_info { #define MIN_XRES 64 #define MIN_YRES 64 -static struct imxfb_rgb def_rgb_16 = { +static struct imxfb_rgb def_rgb_16_tft = { + .red = {.offset = 11, .length = 5,}, + .green = {.offset = 5, .length = 6,}, + .blue = {.offset = 0, .length = 5,}, + .transp = {.offset = 0, .length = 0,}, +}; + +static struct imxfb_rgb def_rgb_16_stn = { .red = {.offset = 8, .length = 4,}, .green = {.offset = 4, .length = 4,}, .blue = {.offset = 0, .length = 4,}, @@ -270,7 +271,7 @@ static int imxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, static int imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { struct imxfb_info *fbi = info->par; - int rgbidx; + struct imxfb_rgb *rgb; if (var->xres < MIN_XRES) var->xres = MIN_XRES; @@ -286,23 +287,25 @@ static int imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) pr_debug("var->bits_per_pixel=%d\n", var->bits_per_pixel); switch (var->bits_per_pixel) { case 16: - rgbidx = RGB_16; + default: + if (readl(fbi->regs + LCDC_PCR) & PCR_TFT) + rgb = &def_rgb_16_tft; + else + rgb = &def_rgb_16_stn; break; case 8: - rgbidx = RGB_8; + rgb = &def_rgb_8; break; - default: - rgbidx = RGB_16; } /* * Copy the RGB parameters for this display * from the machine specific parameters. */ - var->red = fbi->rgb[rgbidx]->red; - var->green = fbi->rgb[rgbidx]->green; - var->blue = fbi->rgb[rgbidx]->blue; - var->transp = fbi->rgb[rgbidx]->transp; + var->red = rgb->red; + var->green = rgb->green; + var->blue = rgb->blue; + var->transp = rgb->transp; pr_debug("RGBT length = %d:%d:%d:%d\n", var->red.length, var->green.length, var->blue.length, @@ -545,9 +548,6 @@ static int __init imxfb_init_fbinfo(struct platform_device *pdev) info->flags = FBINFO_FLAG_DEFAULT | FBINFO_READS_FAST; - fbi->rgb[RGB_16] = &def_rgb_16; - fbi->rgb[RGB_8] = &def_rgb_8; - fbi->max_xres = pdata->xres; info->var.xres = pdata->xres; info->var.xres_virtual = pdata->xres; -- cgit v1.2.3