aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-12-28 23:19:47 -0500
committerDavid S. Miller <davem@davemloft.net>2008-12-28 23:19:47 -0500
commite3c6d4ee545e427b55882d97d3b663c6411645fe (patch)
tree294326663fb757739a98083c2ddd570d1eaf7337 /drivers/video
parent5bc053089376217943187ed5153d0d1e5c5085b6 (diff)
parent3c92ec8ae91ecf59d88c798301833d7cf83f2179 (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts: arch/sparc64/kernel/idprom.c
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/Kconfig33
-rw-r--r--drivers/video/aty/radeon_accel.c294
-rw-r--r--drivers/video/aty/radeon_backlight.c2
-rw-r--r--drivers/video/aty/radeon_base.c40
-rw-r--r--drivers/video/aty/radeon_pm.c6
-rw-r--r--drivers/video/aty/radeonfb.h38
-rw-r--r--drivers/video/console/fbcon.c84
-rw-r--r--drivers/video/controlfb.c4
-rw-r--r--drivers/video/fb_defio.c27
-rw-r--r--drivers/video/macfb.c33
-rw-r--r--drivers/video/mb862xx/mb862xxfb.c4
-rw-r--r--drivers/video/omap/omapfb_main.c2
-rw-r--r--drivers/video/ps3fb.c23
-rw-r--r--drivers/video/sh7760fb.c86
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c198
15 files changed, 394 insertions, 480 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 3f3ce13fef43..d0c821992a99 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1889,10 +1889,11 @@ config FB_W100
1889config FB_SH_MOBILE_LCDC 1889config FB_SH_MOBILE_LCDC
1890 tristate "SuperH Mobile LCDC framebuffer support" 1890 tristate "SuperH Mobile LCDC framebuffer support"
1891 depends on FB && SUPERH 1891 depends on FB && SUPERH
1892 select FB_CFB_FILLRECT 1892 select FB_SYS_FILLRECT
1893 select FB_CFB_COPYAREA 1893 select FB_SYS_COPYAREA
1894 select FB_CFB_IMAGEBLIT 1894 select FB_SYS_IMAGEBLIT
1895 default m 1895 select FB_SYS_FOPS
1896 select FB_DEFERRED_IO
1896 ---help--- 1897 ---help---
1897 Frame buffer driver for the on-chip SH-Mobile LCD controller. 1898 Frame buffer driver for the on-chip SH-Mobile LCD controller.
1898 1899
@@ -2021,17 +2022,19 @@ config FB_COBALT
2021 depends on FB && MIPS_COBALT 2022 depends on FB && MIPS_COBALT
2022 2023
2023config FB_SH7760 2024config FB_SH7760
2024 bool "SH7760/SH7763 LCDC support" 2025 bool "SH7760/SH7763/SH7720/SH7721 LCDC support"
2025 depends on FB && (CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7763) 2026 depends on FB && (CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7763 \
2026 select FB_CFB_FILLRECT 2027 || CPU_SUBTYPE_SH7720 || CPU_SUBTYPE_SH7721)
2027 select FB_CFB_COPYAREA 2028 select FB_CFB_FILLRECT
2028 select FB_CFB_IMAGEBLIT 2029 select FB_CFB_COPYAREA
2029 help 2030 select FB_CFB_IMAGEBLIT
2030 Support for the SH7760/SH7763 integrated (D)STN/TFT LCD Controller. 2031 ---help---
2031 Supports display resolutions up to 1024x1024 pixel, grayscale and 2032 Support for the SH7760/SH7763/SH7720/SH7721 integrated
2032 color operation, with depths ranging from 1 bpp to 8 bpp monochrome 2033 (D)STN/TFT LCD Controller.
2033 and 8, 15 or 16 bpp color; 90 degrees clockwise display rotation for 2034 Supports display resolutions up to 1024x1024 pixel, grayscale and
2034 panels <= 320 pixel horizontal resolution. 2035 color operation, with depths ranging from 1 bpp to 8 bpp monochrome
2036 and 8, 15 or 16 bpp color; 90 degrees clockwise display rotation for
2037 panels <= 320 pixel horizontal resolution.
2035 2038
2036config FB_VIRTUAL 2039config FB_VIRTUAL
2037 tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)" 2040 tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
diff --git a/drivers/video/aty/radeon_accel.c b/drivers/video/aty/radeon_accel.c
index a547e5d4c8bf..a469a3d6edcb 100644
--- a/drivers/video/aty/radeon_accel.c
+++ b/drivers/video/aty/radeon_accel.c
@@ -5,61 +5,61 @@
5 * --dte 5 * --dte
6 */ 6 */
7 7
8#define FLUSH_CACHE_WORKAROUND 1 8static void radeon_fixup_offset(struct radeonfb_info *rinfo)
9
10void radeon_fifo_update_and_wait(struct radeonfb_info *rinfo, int entries)
11{ 9{
12 int i; 10 u32 local_base;
11
12 /* *** Ugly workaround *** */
13 /*
14 * On some platforms, the video memory is mapped at 0 in radeon chip space
15 * (like PPCs) by the firmware. X will always move it up so that it's seen
16 * by the chip to be at the same address as the PCI BAR.
17 * That means that when switching back from X, there is a mismatch between
18 * the offsets programmed into the engine. This means that potentially,
19 * accel operations done before radeonfb has a chance to re-init the engine
20 * will have incorrect offsets, and potentially trash system memory !
21 *
22 * The correct fix is for fbcon to never call any accel op before the engine
23 * has properly been re-initialized (by a call to set_var), but this is a
24 * complex fix. This workaround in the meantime, called before every accel
25 * operation, makes sure the offsets are in sync.
26 */
13 27
14 for (i=0; i<2000000; i++) { 28 radeon_fifo_wait (1);
15 rinfo->fifo_free = INREG(RBBM_STATUS) & 0x7f; 29 local_base = INREG(MC_FB_LOCATION) << 16;
16 if (rinfo->fifo_free >= entries) 30 if (local_base == rinfo->fb_local_base)
17 return; 31 return;
18 udelay(10);
19 }
20 printk(KERN_ERR "radeonfb: FIFO Timeout !\n");
21 /* XXX Todo: attempt to reset the engine */
22}
23 32
24static inline void radeon_fifo_wait(struct radeonfb_info *rinfo, int entries) 33 rinfo->fb_local_base = local_base;
25{
26 if (entries <= rinfo->fifo_free)
27 rinfo->fifo_free -= entries;
28 else
29 radeon_fifo_update_and_wait(rinfo, entries);
30}
31 34
32static inline void radeonfb_set_creg(struct radeonfb_info *rinfo, u32 reg, 35 radeon_fifo_wait (3);
33 u32 *cache, u32 new_val) 36 OUTREG(DEFAULT_PITCH_OFFSET, (rinfo->pitch << 0x16) |
34{ 37 (rinfo->fb_local_base >> 10));
35 if (new_val == *cache) 38 OUTREG(DST_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10));
36 return; 39 OUTREG(SRC_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10));
37 *cache = new_val;
38 radeon_fifo_wait(rinfo, 1);
39 OUTREG(reg, new_val);
40} 40}
41 41
42static void radeonfb_prim_fillrect(struct radeonfb_info *rinfo, 42static void radeonfb_prim_fillrect(struct radeonfb_info *rinfo,
43 const struct fb_fillrect *region) 43 const struct fb_fillrect *region)
44{ 44{
45 radeonfb_set_creg(rinfo, DP_GUI_MASTER_CNTL, &rinfo->dp_gui_mc_cache, 45 radeon_fifo_wait(4);
46 rinfo->dp_gui_mc_base | GMC_BRUSH_SOLID_COLOR | ROP3_P); 46
47 radeonfb_set_creg(rinfo, DP_CNTL, &rinfo->dp_cntl_cache, 47 OUTREG(DP_GUI_MASTER_CNTL,
48 DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM); 48 rinfo->dp_gui_master_cntl /* contains, like GMC_DST_32BPP */
49 radeonfb_set_creg(rinfo, DP_BRUSH_FRGD_CLR, &rinfo->dp_brush_fg_cache, 49 | GMC_BRUSH_SOLID_COLOR
50 region->color); 50 | ROP3_P);
51 51 if (radeon_get_dstbpp(rinfo->depth) != DST_8BPP)
52 /* Ensure the dst cache is flushed and the engine idle before 52 OUTREG(DP_BRUSH_FRGD_CLR, rinfo->pseudo_palette[region->color]);
53 * issuing the operation. 53 else
54 * 54 OUTREG(DP_BRUSH_FRGD_CLR, region->color);
55 * This works around engine lockups on some cards 55 OUTREG(DP_WRITE_MSK, 0xffffffff);
56 */ 56 OUTREG(DP_CNTL, (DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM));
57#if FLUSH_CACHE_WORKAROUND 57
58 radeon_fifo_wait(rinfo, 2); 58 radeon_fifo_wait(2);
59 OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL); 59 OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL);
60 OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE)); 60 OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE));
61#endif 61
62 radeon_fifo_wait(rinfo, 2); 62 radeon_fifo_wait(2);
63 OUTREG(DST_Y_X, (region->dy << 16) | region->dx); 63 OUTREG(DST_Y_X, (region->dy << 16) | region->dx);
64 OUTREG(DST_WIDTH_HEIGHT, (region->width << 16) | region->height); 64 OUTREG(DST_WIDTH_HEIGHT, (region->width << 16) | region->height);
65} 65}
@@ -70,14 +70,15 @@ void radeonfb_fillrect(struct fb_info *info, const struct fb_fillrect *region)
70 struct fb_fillrect modded; 70 struct fb_fillrect modded;
71 int vxres, vyres; 71 int vxres, vyres;
72 72
73 WARN_ON(rinfo->gfx_mode); 73 if (info->state != FBINFO_STATE_RUNNING)
74 if (info->state != FBINFO_STATE_RUNNING || rinfo->gfx_mode)
75 return; 74 return;
76 if (info->flags & FBINFO_HWACCEL_DISABLED) { 75 if (info->flags & FBINFO_HWACCEL_DISABLED) {
77 cfb_fillrect(info, region); 76 cfb_fillrect(info, region);
78 return; 77 return;
79 } 78 }
80 79
80 radeon_fixup_offset(rinfo);
81
81 vxres = info->var.xres_virtual; 82 vxres = info->var.xres_virtual;
82 vyres = info->var.yres_virtual; 83 vyres = info->var.yres_virtual;
83 84
@@ -90,10 +91,6 @@ void radeonfb_fillrect(struct fb_info *info, const struct fb_fillrect *region)
90 if(modded.dx + modded.width > vxres) modded.width = vxres - modded.dx; 91 if(modded.dx + modded.width > vxres) modded.width = vxres - modded.dx;
91 if(modded.dy + modded.height > vyres) modded.height = vyres - modded.dy; 92 if(modded.dy + modded.height > vyres) modded.height = vyres - modded.dy;
92 93
93 if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
94 info->fix.visual == FB_VISUAL_DIRECTCOLOR )
95 modded.color = ((u32 *) (info->pseudo_palette))[region->color];
96
97 radeonfb_prim_fillrect(rinfo, &modded); 94 radeonfb_prim_fillrect(rinfo, &modded);
98} 95}
99 96
@@ -112,22 +109,22 @@ static void radeonfb_prim_copyarea(struct radeonfb_info *rinfo,
112 if ( xdir < 0 ) { sx += w-1; dx += w-1; } 109 if ( xdir < 0 ) { sx += w-1; dx += w-1; }
113 if ( ydir < 0 ) { sy += h-1; dy += h-1; } 110 if ( ydir < 0 ) { sy += h-1; dy += h-1; }
114 111
115 radeonfb_set_creg(rinfo, DP_GUI_MASTER_CNTL, &rinfo->dp_gui_mc_cache, 112 radeon_fifo_wait(3);
116 rinfo->dp_gui_mc_base | 113 OUTREG(DP_GUI_MASTER_CNTL,
117 GMC_BRUSH_NONE | 114 rinfo->dp_gui_master_cntl /* i.e. GMC_DST_32BPP */
118 GMC_SRC_DATATYPE_COLOR | 115 | GMC_BRUSH_NONE
119 ROP3_S | 116 | GMC_SRC_DSTCOLOR
120 DP_SRC_SOURCE_MEMORY); 117 | ROP3_S
121 radeonfb_set_creg(rinfo, DP_CNTL, &rinfo->dp_cntl_cache, 118 | DP_SRC_SOURCE_MEMORY );
122 (xdir>=0 ? DST_X_LEFT_TO_RIGHT : 0) | 119 OUTREG(DP_WRITE_MSK, 0xffffffff);
123 (ydir>=0 ? DST_Y_TOP_TO_BOTTOM : 0)); 120 OUTREG(DP_CNTL, (xdir>=0 ? DST_X_LEFT_TO_RIGHT : 0)
124 121 | (ydir>=0 ? DST_Y_TOP_TO_BOTTOM : 0));
125#if FLUSH_CACHE_WORKAROUND 122
126 radeon_fifo_wait(rinfo, 2); 123 radeon_fifo_wait(2);
127 OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL); 124 OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL);
128 OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE)); 125 OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE));
129#endif 126
130 radeon_fifo_wait(rinfo, 3); 127 radeon_fifo_wait(3);
131 OUTREG(SRC_Y_X, (sy << 16) | sx); 128 OUTREG(SRC_Y_X, (sy << 16) | sx);
132 OUTREG(DST_Y_X, (dy << 16) | dx); 129 OUTREG(DST_Y_X, (dy << 16) | dx);
133 OUTREG(DST_HEIGHT_WIDTH, (h << 16) | w); 130 OUTREG(DST_HEIGHT_WIDTH, (h << 16) | w);
@@ -146,14 +143,15 @@ void radeonfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
146 modded.width = area->width; 143 modded.width = area->width;
147 modded.height = area->height; 144 modded.height = area->height;
148 145
149 WARN_ON(rinfo->gfx_mode); 146 if (info->state != FBINFO_STATE_RUNNING)
150 if (info->state != FBINFO_STATE_RUNNING || rinfo->gfx_mode)
151 return; 147 return;
152 if (info->flags & FBINFO_HWACCEL_DISABLED) { 148 if (info->flags & FBINFO_HWACCEL_DISABLED) {
153 cfb_copyarea(info, area); 149 cfb_copyarea(info, area);
154 return; 150 return;
155 } 151 }
156 152
153 radeon_fixup_offset(rinfo);
154
157 vxres = info->var.xres_virtual; 155 vxres = info->var.xres_virtual;
158 vyres = info->var.yres_virtual; 156 vyres = info->var.yres_virtual;
159 157
@@ -170,115 +168,13 @@ void radeonfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
170 radeonfb_prim_copyarea(rinfo, &modded); 168 radeonfb_prim_copyarea(rinfo, &modded);
171} 169}
172 170
173static void radeonfb_prim_imageblit(struct radeonfb_info *rinfo,
174 const struct fb_image *image,
175 u32 fg, u32 bg)
176{
177 unsigned int dwords;
178 u32 *bits;
179
180 radeonfb_set_creg(rinfo, DP_GUI_MASTER_CNTL, &rinfo->dp_gui_mc_cache,
181 rinfo->dp_gui_mc_base |
182 GMC_BRUSH_NONE | GMC_DST_CLIP_LEAVE |
183 GMC_SRC_DATATYPE_MONO_FG_BG |
184 ROP3_S |
185 GMC_BYTE_ORDER_MSB_TO_LSB |
186 DP_SRC_SOURCE_HOST_DATA);
187 radeonfb_set_creg(rinfo, DP_CNTL, &rinfo->dp_cntl_cache,
188 DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM);
189 radeonfb_set_creg(rinfo, DP_SRC_FRGD_CLR, &rinfo->dp_src_fg_cache, fg);
190 radeonfb_set_creg(rinfo, DP_SRC_BKGD_CLR, &rinfo->dp_src_bg_cache, bg);
191
192 /* Ensure the dst cache is flushed and the engine idle before
193 * issuing the operation.
194 *
195 * This works around engine lockups on some cards
196 */
197#if FLUSH_CACHE_WORKAROUND
198 radeon_fifo_wait(rinfo, 2);
199 OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL);
200 OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE));
201#endif
202
203 /* X here pads width to a multiple of 32 and uses the clipper to
204 * adjust the result. Is that really necessary ? Things seem to
205 * work ok for me without that and the doco doesn't seem to imply]
206 * there is such a restriction.
207 */
208 radeon_fifo_wait(rinfo, 4);
209 OUTREG(SC_TOP_LEFT, (image->dy << 16) | image->dx);
210 OUTREG(SC_BOTTOM_RIGHT, ((image->dy + image->height) << 16) |
211 (image->dx + image->width));
212 OUTREG(DST_Y_X, (image->dy << 16) | image->dx);
213
214 OUTREG(DST_HEIGHT_WIDTH, (image->height << 16) | ((image->width + 31) & ~31));
215
216 dwords = (image->width + 31) >> 5;
217 dwords *= image->height;
218 bits = (u32*)(image->data);
219
220 while(dwords >= 8) {
221 radeon_fifo_wait(rinfo, 8);
222#if BITS_PER_LONG == 64
223 __raw_writeq(*((u64 *)(bits)), rinfo->mmio_base + HOST_DATA0);
224 __raw_writeq(*((u64 *)(bits+2)), rinfo->mmio_base + HOST_DATA2);
225 __raw_writeq(*((u64 *)(bits+4)), rinfo->mmio_base + HOST_DATA4);
226 __raw_writeq(*((u64 *)(bits+6)), rinfo->mmio_base + HOST_DATA6);
227 bits += 8;
228#else
229 __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA0);
230 __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA1);
231 __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA2);
232 __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA3);
233 __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA4);
234 __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA5);
235 __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA6);
236 __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA7);
237#endif
238 dwords -= 8;
239 }
240 while(dwords--) {
241 radeon_fifo_wait(rinfo, 1);
242 __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA0);
243 }
244}
245
246void radeonfb_imageblit(struct fb_info *info, const struct fb_image *image) 171void radeonfb_imageblit(struct fb_info *info, const struct fb_image *image)
247{ 172{
248 struct radeonfb_info *rinfo = info->par; 173 struct radeonfb_info *rinfo = info->par;
249 u32 fg, bg;
250
251 WARN_ON(rinfo->gfx_mode);
252 if (info->state != FBINFO_STATE_RUNNING || rinfo->gfx_mode)
253 return;
254 174
255 if (!image->width || !image->height) 175 if (info->state != FBINFO_STATE_RUNNING)
256 return; 176 return;
257 177 radeon_engine_idle();
258 /* We only do 1 bpp color expansion for now */
259 if (info->flags & FBINFO_HWACCEL_DISABLED || image->depth != 1)
260 goto fallback;
261
262 /* Fallback if running out of the screen. We may do clipping
263 * in the future */
264 if ((image->dx + image->width) > info->var.xres_virtual ||
265 (image->dy + image->height) > info->var.yres_virtual)
266 goto fallback;
267
268 if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
269 info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
270 fg = ((u32*)(info->pseudo_palette))[image->fg_color];
271 bg = ((u32*)(info->pseudo_palette))[image->bg_color];
272 } else {
273 fg = image->fg_color;
274 bg = image->bg_color;
275 }
276
277 radeonfb_prim_imageblit(rinfo, image, fg, bg);
278 return;
279
280 fallback:
281 radeon_engine_idle(rinfo);
282 178
283 cfb_imageblit(info, image); 179 cfb_imageblit(info, image);
284} 180}
@@ -289,8 +185,7 @@ int radeonfb_sync(struct fb_info *info)
289 185
290 if (info->state != FBINFO_STATE_RUNNING) 186 if (info->state != FBINFO_STATE_RUNNING)
291 return 0; 187 return 0;
292 188 radeon_engine_idle();
293 radeon_engine_idle(rinfo);
294 189
295 return 0; 190 return 0;
296} 191}
@@ -366,10 +261,9 @@ void radeonfb_engine_init (struct radeonfb_info *rinfo)
366 /* disable 3D engine */ 261 /* disable 3D engine */
367 OUTREG(RB3D_CNTL, 0); 262 OUTREG(RB3D_CNTL, 0);
368 263
369 rinfo->fifo_free = 0;
370 radeonfb_engine_reset(rinfo); 264 radeonfb_engine_reset(rinfo);
371 265
372 radeon_fifo_wait(rinfo, 1); 266 radeon_fifo_wait (1);
373 if (IS_R300_VARIANT(rinfo)) { 267 if (IS_R300_VARIANT(rinfo)) {
374 OUTREG(RB2D_DSTCACHE_MODE, INREG(RB2D_DSTCACHE_MODE) | 268 OUTREG(RB2D_DSTCACHE_MODE, INREG(RB2D_DSTCACHE_MODE) |
375 RB2D_DC_AUTOFLUSH_ENABLE | 269 RB2D_DC_AUTOFLUSH_ENABLE |
@@ -383,7 +277,7 @@ void radeonfb_engine_init (struct radeonfb_info *rinfo)
383 OUTREG(RB2D_DSTCACHE_MODE, 0); 277 OUTREG(RB2D_DSTCACHE_MODE, 0);
384 } 278 }
385 279
386 radeon_fifo_wait(rinfo, 3); 280 radeon_fifo_wait (3);
387 /* We re-read MC_FB_LOCATION from card as it can have been 281 /* We re-read MC_FB_LOCATION from card as it can have been
388 * modified by XFree drivers (ouch !) 282 * modified by XFree drivers (ouch !)
389 */ 283 */
@@ -394,57 +288,41 @@ void radeonfb_engine_init (struct radeonfb_info *rinfo)
394 OUTREG(DST_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10)); 288 OUTREG(DST_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10));
395 OUTREG(SRC_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10)); 289 OUTREG(SRC_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10));
396 290
397 radeon_fifo_wait(rinfo, 1); 291 radeon_fifo_wait (1);
398#ifdef __BIG_ENDIAN 292#if defined(__BIG_ENDIAN)
399 OUTREGP(DP_DATATYPE, HOST_BIG_ENDIAN_EN, ~HOST_BIG_ENDIAN_EN); 293 OUTREGP(DP_DATATYPE, HOST_BIG_ENDIAN_EN, ~HOST_BIG_ENDIAN_EN);
400#else 294#else
401 OUTREGP(DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN); 295 OUTREGP(DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN);
402#endif 296#endif
403 radeon_fifo_wait(rinfo, 2); 297 radeon_fifo_wait (2);
404 OUTREG(DEFAULT_SC_TOP_LEFT, 0); 298 OUTREG(DEFAULT_SC_TOP_LEFT, 0);
405 OUTREG(DEFAULT_SC_BOTTOM_RIGHT, (DEFAULT_SC_RIGHT_MAX | 299 OUTREG(DEFAULT_SC_BOTTOM_RIGHT, (DEFAULT_SC_RIGHT_MAX |
406 DEFAULT_SC_BOTTOM_MAX)); 300 DEFAULT_SC_BOTTOM_MAX));
407 301
408 /* set default DP_GUI_MASTER_CNTL */
409 temp = radeon_get_dstbpp(rinfo->depth); 302 temp = radeon_get_dstbpp(rinfo->depth);
410 rinfo->dp_gui_mc_base = ((temp << 8) | GMC_CLR_CMP_CNTL_DIS); 303 rinfo->dp_gui_master_cntl = ((temp << 8) | GMC_CLR_CMP_CNTL_DIS);
411 304
412 rinfo->dp_gui_mc_cache = rinfo->dp_gui_mc_base | 305 radeon_fifo_wait (1);
413 GMC_BRUSH_SOLID_COLOR | 306 OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl |
414 GMC_SRC_DATATYPE_COLOR; 307 GMC_BRUSH_SOLID_COLOR |
415 radeon_fifo_wait(rinfo, 1); 308 GMC_SRC_DATATYPE_COLOR));
416 OUTREG(DP_GUI_MASTER_CNTL, rinfo->dp_gui_mc_cache);
417 309
310 radeon_fifo_wait (7);
418 311
419 /* clear line drawing regs */ 312 /* clear line drawing regs */
420 radeon_fifo_wait(rinfo, 2);
421 OUTREG(DST_LINE_START, 0); 313 OUTREG(DST_LINE_START, 0);
422 OUTREG(DST_LINE_END, 0); 314 OUTREG(DST_LINE_END, 0);
423 315
424 /* set brush and source color regs */ 316 /* set brush color regs */
425 rinfo->dp_brush_fg_cache = 0xffffffff; 317 OUTREG(DP_BRUSH_FRGD_CLR, 0xffffffff);
426 rinfo->dp_brush_bg_cache = 0x00000000; 318 OUTREG(DP_BRUSH_BKGD_CLR, 0x00000000);
427 rinfo->dp_src_fg_cache = 0xffffffff; 319
428 rinfo->dp_src_bg_cache = 0x00000000; 320 /* set source color regs */
429 radeon_fifo_wait(rinfo, 4); 321 OUTREG(DP_SRC_FRGD_CLR, 0xffffffff);
430 OUTREG(DP_BRUSH_FRGD_CLR, rinfo->dp_brush_fg_cache); 322 OUTREG(DP_SRC_BKGD_CLR, 0x00000000);
431 OUTREG(DP_BRUSH_BKGD_CLR, rinfo->dp_brush_bg_cache);
432 OUTREG(DP_SRC_FRGD_CLR, rinfo->dp_src_fg_cache);
433 OUTREG(DP_SRC_BKGD_CLR, rinfo->dp_src_bg_cache);
434
435 /* Default direction */
436 rinfo->dp_cntl_cache = DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM;
437 radeon_fifo_wait(rinfo, 1);
438 OUTREG(DP_CNTL, rinfo->dp_cntl_cache);
439 323
440 /* default write mask */ 324 /* default write mask */
441 radeon_fifo_wait(rinfo, 1);
442 OUTREG(DP_WRITE_MSK, 0xffffffff); 325 OUTREG(DP_WRITE_MSK, 0xffffffff);
443 326
444 /* Default to no swapping of host data */ 327 radeon_engine_idle ();
445 radeon_fifo_wait(rinfo, 1);
446 OUTREG(RBBM_GUICNTL, RBBM_GUICNTL_HOST_DATA_SWAP_NONE);
447
448 /* Make sure it's settled */
449 radeon_engine_idle(rinfo);
450} 328}
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)
66 level = bd->props.brightness; 66 level = bd->props.brightness;
67 67
68 del_timer_sync(&rinfo->lvds_timer); 68 del_timer_sync(&rinfo->lvds_timer);
69 radeon_engine_idle(rinfo); 69 radeon_engine_idle();
70 70
71 lvds_gen_cntl = INREG(LVDS_GEN_CNTL); 71 lvds_gen_cntl = INREG(LVDS_GEN_CNTL);
72 if (level > 0) { 72 if (level > 0) {
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index b3ffe8205d2b..d0f1a7fc2c9d 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -852,6 +852,7 @@ static int radeonfb_pan_display (struct fb_var_screeninfo *var,
852 if (rinfo->asleep) 852 if (rinfo->asleep)
853 return 0; 853 return 0;
854 854
855 radeon_fifo_wait(2);
855 OUTREG(CRTC_OFFSET, ((var->yoffset * var->xres_virtual + var->xoffset) 856 OUTREG(CRTC_OFFSET, ((var->yoffset * var->xres_virtual + var->xoffset)
856 * var->bits_per_pixel / 8) & ~7); 857 * var->bits_per_pixel / 8) & ~7);
857 return 0; 858 return 0;
@@ -881,6 +882,7 @@ static int radeonfb_ioctl (struct fb_info *info, unsigned int cmd,
881 if (rc) 882 if (rc)
882 return rc; 883 return rc;
883 884
885 radeon_fifo_wait(2);
884 if (value & 0x01) { 886 if (value & 0x01) {
885 tmp = INREG(LVDS_GEN_CNTL); 887 tmp = INREG(LVDS_GEN_CNTL);
886 888
@@ -938,7 +940,7 @@ int radeon_screen_blank(struct radeonfb_info *rinfo, int blank, int mode_switch)
938 if (rinfo->lock_blank) 940 if (rinfo->lock_blank)
939 return 0; 941 return 0;
940 942
941 radeon_engine_idle(rinfo); 943 radeon_engine_idle();
942 944
943 val = INREG(CRTC_EXT_CNTL); 945 val = INREG(CRTC_EXT_CNTL);
944 val &= ~(CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS | 946 val &= ~(CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS |
@@ -1046,7 +1048,7 @@ static int radeonfb_blank (int blank, struct fb_info *info)
1046 1048
1047 if (rinfo->asleep) 1049 if (rinfo->asleep)
1048 return 0; 1050 return 0;
1049 1051
1050 return radeon_screen_blank(rinfo, blank, 0); 1052 return radeon_screen_blank(rinfo, blank, 0);
1051} 1053}
1052 1054
@@ -1072,6 +1074,8 @@ static int radeon_setcolreg (unsigned regno, unsigned red, unsigned green,
1072 pindex = regno; 1074 pindex = regno;
1073 1075
1074 if (!rinfo->asleep) { 1076 if (!rinfo->asleep) {
1077 radeon_fifo_wait(9);
1078
1075 if (rinfo->bpp == 16) { 1079 if (rinfo->bpp == 16) {
1076 pindex = regno * 8; 1080 pindex = regno * 8;
1077 1081
@@ -1240,6 +1244,8 @@ static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_reg
1240{ 1244{
1241 int i; 1245 int i;
1242 1246
1247 radeon_fifo_wait(20);
1248
1243 /* Workaround from XFree */ 1249 /* Workaround from XFree */
1244 if (rinfo->is_mobility) { 1250 if (rinfo->is_mobility) {
1245 /* A temporal workaround for the occational blanking on certain laptop 1251 /* A temporal workaround for the occational blanking on certain laptop
@@ -1335,7 +1341,7 @@ static void radeon_lvds_timer_func(unsigned long data)
1335{ 1341{
1336 struct radeonfb_info *rinfo = (struct radeonfb_info *)data; 1342 struct radeonfb_info *rinfo = (struct radeonfb_info *)data;
1337 1343
1338 radeon_engine_idle(rinfo); 1344 radeon_engine_idle();
1339 1345
1340 OUTREG(LVDS_GEN_CNTL, rinfo->pending_lvds_gen_cntl); 1346 OUTREG(LVDS_GEN_CNTL, rinfo->pending_lvds_gen_cntl);
1341} 1347}
@@ -1353,11 +1359,10 @@ void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode,
1353 if (nomodeset) 1359 if (nomodeset)
1354 return; 1360 return;
1355 1361
1356 radeon_engine_idle(rinfo);
1357
1358 if (!regs_only) 1362 if (!regs_only)
1359 radeon_screen_blank(rinfo, FB_BLANK_NORMAL, 0); 1363 radeon_screen_blank(rinfo, FB_BLANK_NORMAL, 0);
1360 1364
1365 radeon_fifo_wait(31);
1361 for (i=0; i<10; i++) 1366 for (i=0; i<10; i++)
1362 OUTREG(common_regs[i].reg, common_regs[i].val); 1367 OUTREG(common_regs[i].reg, common_regs[i].val);
1363 1368
@@ -1385,6 +1390,7 @@ void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode,
1385 radeon_write_pll_regs(rinfo, mode); 1390 radeon_write_pll_regs(rinfo, mode);
1386 1391
1387 if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) { 1392 if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
1393 radeon_fifo_wait(10);
1388 OUTREG(FP_CRTC_H_TOTAL_DISP, mode->fp_crtc_h_total_disp); 1394 OUTREG(FP_CRTC_H_TOTAL_DISP, mode->fp_crtc_h_total_disp);
1389 OUTREG(FP_CRTC_V_TOTAL_DISP, mode->fp_crtc_v_total_disp); 1395 OUTREG(FP_CRTC_V_TOTAL_DISP, mode->fp_crtc_v_total_disp);
1390 OUTREG(FP_H_SYNC_STRT_WID, mode->fp_h_sync_strt_wid); 1396 OUTREG(FP_H_SYNC_STRT_WID, mode->fp_h_sync_strt_wid);
@@ -1399,6 +1405,7 @@ void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode,
1399 if (!regs_only) 1405 if (!regs_only)
1400 radeon_screen_blank(rinfo, FB_BLANK_UNBLANK, 0); 1406 radeon_screen_blank(rinfo, FB_BLANK_UNBLANK, 0);
1401 1407
1408 radeon_fifo_wait(2);
1402 OUTPLL(VCLK_ECP_CNTL, mode->vclk_ecp_cntl); 1409 OUTPLL(VCLK_ECP_CNTL, mode->vclk_ecp_cntl);
1403 1410
1404 return; 1411 return;
@@ -1549,7 +1556,7 @@ static int radeonfb_set_par(struct fb_info *info)
1549 /* We always want engine to be idle on a mode switch, even 1556 /* We always want engine to be idle on a mode switch, even
1550 * if we won't actually change the mode 1557 * if we won't actually change the mode
1551 */ 1558 */
1552 radeon_engine_idle(rinfo); 1559 radeon_engine_idle();
1553 1560
1554 hSyncStart = mode->xres + mode->right_margin; 1561 hSyncStart = mode->xres + mode->right_margin;
1555 hSyncEnd = hSyncStart + mode->hsync_len; 1562 hSyncEnd = hSyncStart + mode->hsync_len;
@@ -1844,6 +1851,7 @@ static int radeonfb_set_par(struct fb_info *info)
1844 return 0; 1851 return 0;
1845} 1852}
1846 1853
1854
1847static struct fb_ops radeonfb_ops = { 1855static struct fb_ops radeonfb_ops = {
1848 .owner = THIS_MODULE, 1856 .owner = THIS_MODULE,
1849 .fb_check_var = radeonfb_check_var, 1857 .fb_check_var = radeonfb_check_var,
@@ -1867,7 +1875,6 @@ static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo)
1867 info->par = rinfo; 1875 info->par = rinfo;
1868 info->pseudo_palette = rinfo->pseudo_palette; 1876 info->pseudo_palette = rinfo->pseudo_palette;
1869 info->flags = FBINFO_DEFAULT 1877 info->flags = FBINFO_DEFAULT
1870 | FBINFO_HWACCEL_IMAGEBLIT
1871 | FBINFO_HWACCEL_COPYAREA 1878 | FBINFO_HWACCEL_COPYAREA
1872 | FBINFO_HWACCEL_FILLRECT 1879 | FBINFO_HWACCEL_FILLRECT
1873 | FBINFO_HWACCEL_XPAN 1880 | FBINFO_HWACCEL_XPAN
@@ -1875,7 +1882,6 @@ static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo)
1875 info->fbops = &radeonfb_ops; 1882 info->fbops = &radeonfb_ops;
1876 info->screen_base = rinfo->fb_base; 1883 info->screen_base = rinfo->fb_base;
1877 info->screen_size = rinfo->mapped_vram; 1884 info->screen_size = rinfo->mapped_vram;
1878
1879 /* Fill fix common fields */ 1885 /* Fill fix common fields */
1880 strlcpy(info->fix.id, rinfo->name, sizeof(info->fix.id)); 1886 strlcpy(info->fix.id, rinfo->name, sizeof(info->fix.id));
1881 info->fix.smem_start = rinfo->fb_base_phys; 1887 info->fix.smem_start = rinfo->fb_base_phys;
@@ -1890,25 +1896,8 @@ static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo)
1890 info->fix.mmio_len = RADEON_REGSIZE; 1896 info->fix.mmio_len = RADEON_REGSIZE;
1891 info->fix.accel = FB_ACCEL_ATI_RADEON; 1897 info->fix.accel = FB_ACCEL_ATI_RADEON;
1892 1898
1893 /* Allocate colormap */
1894 fb_alloc_cmap(&info->cmap, 256, 0); 1899 fb_alloc_cmap(&info->cmap, 256, 0);
1895 1900
1896 /* Setup pixmap used for acceleration */
1897#define PIXMAP_SIZE (2048 * 4)
1898
1899 info->pixmap.addr = kmalloc(PIXMAP_SIZE, GFP_KERNEL);
1900 if (!info->pixmap.addr) {
1901 printk(KERN_ERR "radeonfb: Failed to allocate pixmap !\n");
1902 noaccel = 1;
1903 goto bail;
1904 }
1905 info->pixmap.size = PIXMAP_SIZE;
1906 info->pixmap.flags = FB_PIXMAP_SYSTEM;
1907 info->pixmap.scan_align = 4;
1908 info->pixmap.buf_align = 4;
1909 info->pixmap.access_align = 32;
1910
1911bail:
1912 if (noaccel) 1901 if (noaccel)
1913 info->flags |= FBINFO_HWACCEL_DISABLED; 1902 info->flags |= FBINFO_HWACCEL_DISABLED;
1914 1903
@@ -2017,6 +2006,7 @@ static void radeon_identify_vram(struct radeonfb_info *rinfo)
2017 u32 tom = INREG(NB_TOM); 2006 u32 tom = INREG(NB_TOM);
2018 tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024); 2007 tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024);
2019 2008
2009 radeon_fifo_wait(6);
2020 OUTREG(MC_FB_LOCATION, tom); 2010 OUTREG(MC_FB_LOCATION, tom);
2021 OUTREG(DISPLAY_BASE_ADDR, (tom & 0xffff) << 16); 2011 OUTREG(DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
2022 OUTREG(CRTC2_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16); 2012 OUTREG(CRTC2_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
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)
2653 2653
2654 if (!(info->flags & FBINFO_HWACCEL_DISABLED)) { 2654 if (!(info->flags & FBINFO_HWACCEL_DISABLED)) {
2655 /* Make sure engine is reset */ 2655 /* Make sure engine is reset */
2656 radeon_engine_idle(rinfo); 2656 radeon_engine_idle();
2657 radeonfb_engine_reset(rinfo); 2657 radeonfb_engine_reset(rinfo);
2658 radeon_engine_idle(rinfo); 2658 radeon_engine_idle();
2659 } 2659 }
2660 2660
2661 /* Blank display and LCD */ 2661 /* Blank display and LCD */
@@ -2767,7 +2767,7 @@ int radeonfb_pci_resume(struct pci_dev *pdev)
2767 2767
2768 rinfo->asleep = 0; 2768 rinfo->asleep = 0;
2769 } else 2769 } else
2770 radeon_engine_idle(rinfo); 2770 radeon_engine_idle();
2771 2771
2772 /* Restore display & engine */ 2772 /* Restore display & engine */
2773 radeon_write_mode (rinfo, &rinfo->state, 1); 2773 radeon_write_mode (rinfo, &rinfo->state, 1);
diff --git a/drivers/video/aty/radeonfb.h b/drivers/video/aty/radeonfb.h
index ea0b5b47acaf..3ea1b00fdd22 100644
--- a/drivers/video/aty/radeonfb.h
+++ b/drivers/video/aty/radeonfb.h
@@ -336,15 +336,7 @@ struct radeonfb_info {
336 int mon2_type; 336 int mon2_type;
337 u8 *mon2_EDID; 337 u8 *mon2_EDID;
338 338
339 /* accel bits */ 339 u32 dp_gui_master_cntl;
340 u32 dp_gui_mc_base;
341 u32 dp_gui_mc_cache;
342 u32 dp_cntl_cache;
343 u32 dp_brush_fg_cache;
344 u32 dp_brush_bg_cache;
345 u32 dp_src_fg_cache;
346 u32 dp_src_bg_cache;
347 u32 fifo_free;
348 340
349 struct pll_info pll; 341 struct pll_info pll;
350 342
@@ -356,7 +348,6 @@ struct radeonfb_info {
356 int lock_blank; 348 int lock_blank;
357 int dynclk; 349 int dynclk;
358 int no_schedule; 350 int no_schedule;
359 int gfx_mode;
360 enum radeon_pm_mode pm_mode; 351 enum radeon_pm_mode pm_mode;
361 reinit_function_ptr reinit_func; 352 reinit_function_ptr reinit_func;
362 353
@@ -401,14 +392,8 @@ static inline void _radeon_msleep(struct radeonfb_info *rinfo, unsigned long ms)
401#define OUTREG8(addr,val) writeb(val, (rinfo->mmio_base)+addr) 392#define OUTREG8(addr,val) writeb(val, (rinfo->mmio_base)+addr)
402#define INREG16(addr) readw((rinfo->mmio_base)+addr) 393#define INREG16(addr) readw((rinfo->mmio_base)+addr)
403#define OUTREG16(addr,val) writew(val, (rinfo->mmio_base)+addr) 394#define OUTREG16(addr,val) writew(val, (rinfo->mmio_base)+addr)
404
405#ifdef CONFIG_PPC
406#define INREG(addr) ({ eieio(); ld_le32(rinfo->mmio_base+(addr)); })
407#define OUTREG(addr,val) do { eieio(); st_le32(rinfo->mmio_base+(addr),(val)); } while(0)
408#else
409#define INREG(addr) readl((rinfo->mmio_base)+addr) 395#define INREG(addr) readl((rinfo->mmio_base)+addr)
410#define OUTREG(addr,val) writel(val, (rinfo->mmio_base)+addr) 396#define OUTREG(addr,val) writel(val, (rinfo->mmio_base)+addr)
411#endif
412 397
413static inline void _OUTREGP(struct radeonfb_info *rinfo, u32 addr, 398static inline void _OUTREGP(struct radeonfb_info *rinfo, u32 addr,
414 u32 val, u32 mask) 399 u32 val, u32 mask)
@@ -550,7 +535,17 @@ static inline u32 radeon_get_dstbpp(u16 depth)
550 * 2D Engine helper routines 535 * 2D Engine helper routines
551 */ 536 */
552 537
553extern void radeon_fifo_update_and_wait(struct radeonfb_info *rinfo, int entries); 538static inline void _radeon_fifo_wait(struct radeonfb_info *rinfo, int entries)
539{
540 int i;
541
542 for (i=0; i<2000000; i++) {
543 if ((INREG(RBBM_STATUS) & 0x7f) >= entries)
544 return;
545 udelay(1);
546 }
547 printk(KERN_ERR "radeonfb: FIFO Timeout !\n");
548}
554 549
555static inline void radeon_engine_flush (struct radeonfb_info *rinfo) 550static inline void radeon_engine_flush (struct radeonfb_info *rinfo)
556{ 551{
@@ -563,7 +558,7 @@ static inline void radeon_engine_flush (struct radeonfb_info *rinfo)
563 /* Ensure FIFO is empty, ie, make sure the flush commands 558 /* Ensure FIFO is empty, ie, make sure the flush commands
564 * has reached the cache 559 * has reached the cache
565 */ 560 */
566 radeon_fifo_update_and_wait(rinfo, 64); 561 _radeon_fifo_wait (rinfo, 64);
567 562
568 /* Wait for the flush to complete */ 563 /* Wait for the flush to complete */
569 for (i=0; i < 2000000; i++) { 564 for (i=0; i < 2000000; i++) {
@@ -575,12 +570,12 @@ static inline void radeon_engine_flush (struct radeonfb_info *rinfo)
575} 570}
576 571
577 572
578static inline void radeon_engine_idle(struct radeonfb_info *rinfo) 573static inline void _radeon_engine_idle(struct radeonfb_info *rinfo)
579{ 574{
580 int i; 575 int i;
581 576
582 /* ensure FIFO is empty before waiting for idle */ 577 /* ensure FIFO is empty before waiting for idle */
583 radeon_fifo_update_and_wait (rinfo, 64); 578 _radeon_fifo_wait (rinfo, 64);
584 579
585 for (i=0; i<2000000; i++) { 580 for (i=0; i<2000000; i++) {
586 if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) { 581 if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) {
@@ -593,6 +588,8 @@ static inline void radeon_engine_idle(struct radeonfb_info *rinfo)
593} 588}
594 589
595 590
591#define radeon_engine_idle() _radeon_engine_idle(rinfo)
592#define radeon_fifo_wait(entries) _radeon_fifo_wait(rinfo,entries)
596#define radeon_msleep(ms) _radeon_msleep(rinfo,ms) 593#define radeon_msleep(ms) _radeon_msleep(rinfo,ms)
597 594
598 595
@@ -622,7 +619,6 @@ extern void radeonfb_imageblit(struct fb_info *p, const struct fb_image *image);
622extern int radeonfb_sync(struct fb_info *info); 619extern int radeonfb_sync(struct fb_info *info);
623extern void radeonfb_engine_init (struct radeonfb_info *rinfo); 620extern void radeonfb_engine_init (struct radeonfb_info *rinfo);
624extern void radeonfb_engine_reset(struct radeonfb_info *rinfo); 621extern void radeonfb_engine_reset(struct radeonfb_info *rinfo);
625extern void radeon_fixup_mem_offset(struct radeonfb_info *rinfo);
626 622
627/* Other functions */ 623/* Other functions */
628extern int radeon_screen_blank(struct radeonfb_info *rinfo, int blank, int mode_switch); 624extern int radeon_screen_blank(struct radeonfb_info *rinfo, int blank, int mode_switch);
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 67ff370d80af..4bcff81b50e0 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -81,9 +81,6 @@
81#ifdef CONFIG_ATARI 81#ifdef CONFIG_ATARI
82#include <asm/atariints.h> 82#include <asm/atariints.h>
83#endif 83#endif
84#ifdef CONFIG_MAC
85#include <asm/macints.h>
86#endif
87#if defined(__mc68000__) 84#if defined(__mc68000__)
88#include <asm/machdep.h> 85#include <asm/machdep.h>
89#include <asm/setup.h> 86#include <asm/setup.h>
@@ -160,8 +157,6 @@ static int fbcon_set_origin(struct vc_data *);
160 157
161/* # VBL ints between cursor state changes */ 158/* # VBL ints between cursor state changes */
162#define ATARI_CURSOR_BLINK_RATE (42) 159#define ATARI_CURSOR_BLINK_RATE (42)
163#define MAC_CURSOR_BLINK_RATE (32)
164#define DEFAULT_CURSOR_BLINK_RATE (20)
165 160
166static int vbl_cursor_cnt; 161static int vbl_cursor_cnt;
167static int fbcon_cursor_noblink; 162static int fbcon_cursor_noblink;
@@ -210,19 +205,6 @@ static void fbcon_start(void);
210static void fbcon_exit(void); 205static void fbcon_exit(void);
211static struct device *fbcon_device; 206static struct device *fbcon_device;
212 207
213#ifdef CONFIG_MAC
214/*
215 * On the Macintoy, there may or may not be a working VBL int. We need to probe
216 */
217static int vbl_detected;
218
219static irqreturn_t fb_vbl_detect(int irq, void *dummy)
220{
221 vbl_detected++;
222 return IRQ_HANDLED;
223}
224#endif
225
226#ifdef CONFIG_FRAMEBUFFER_CONSOLE_ROTATION 208#ifdef CONFIG_FRAMEBUFFER_CONSOLE_ROTATION
227static inline void fbcon_set_rotation(struct fb_info *info) 209static inline void fbcon_set_rotation(struct fb_info *info)
228{ 210{
@@ -421,7 +403,7 @@ static void fb_flashcursor(struct work_struct *work)
421 release_console_sem(); 403 release_console_sem();
422} 404}
423 405
424#if defined(CONFIG_ATARI) || defined(CONFIG_MAC) 406#ifdef CONFIG_ATARI
425static int cursor_blink_rate; 407static int cursor_blink_rate;
426static irqreturn_t fb_vbl_handler(int irq, void *dev_id) 408static irqreturn_t fb_vbl_handler(int irq, void *dev_id)
427{ 409{
@@ -949,9 +931,7 @@ static const char *fbcon_startup(void)
949 struct fb_info *info = NULL; 931 struct fb_info *info = NULL;
950 struct fbcon_ops *ops; 932 struct fbcon_ops *ops;
951 int rows, cols; 933 int rows, cols;
952 int irqres;
953 934
954 irqres = 1;
955 /* 935 /*
956 * If num_registered_fb is zero, this is a call for the dummy part. 936 * If num_registered_fb is zero, this is a call for the dummy part.
957 * The frame buffer devices weren't initialized yet. 937 * The frame buffer devices weren't initialized yet.
@@ -1040,56 +1020,11 @@ static const char *fbcon_startup(void)
1040#ifdef CONFIG_ATARI 1020#ifdef CONFIG_ATARI
1041 if (MACH_IS_ATARI) { 1021 if (MACH_IS_ATARI) {
1042 cursor_blink_rate = ATARI_CURSOR_BLINK_RATE; 1022 cursor_blink_rate = ATARI_CURSOR_BLINK_RATE;
1043 irqres = 1023 (void)request_irq(IRQ_AUTO_4, fb_vbl_handler,
1044 request_irq(IRQ_AUTO_4, fb_vbl_handler,
1045 IRQ_TYPE_PRIO, "framebuffer vbl", 1024 IRQ_TYPE_PRIO, "framebuffer vbl",
1046 info); 1025 info);
1047 } 1026 }
1048#endif /* CONFIG_ATARI */ 1027#endif /* CONFIG_ATARI */
1049
1050#ifdef CONFIG_MAC
1051 /*
1052 * On a Macintoy, the VBL interrupt may or may not be active.
1053 * As interrupt based cursor is more reliable and race free, we
1054 * probe for VBL interrupts.
1055 */
1056 if (MACH_IS_MAC) {
1057 int ct = 0;
1058 /*
1059 * Probe for VBL: set temp. handler ...
1060 */
1061 irqres = request_irq(IRQ_MAC_VBL, fb_vbl_detect, 0,
1062 "framebuffer vbl", info);
1063 vbl_detected = 0;
1064
1065 /*
1066 * ... and spin for 20 ms ...
1067 */
1068 while (!vbl_detected && ++ct < 1000)
1069 udelay(20);
1070
1071 if (ct == 1000)
1072 printk
1073 ("fbcon_startup: No VBL detected, using timer based cursor.\n");
1074
1075 free_irq(IRQ_MAC_VBL, fb_vbl_detect);
1076
1077 if (vbl_detected) {
1078 /*
1079 * interrupt based cursor ok
1080 */
1081 cursor_blink_rate = MAC_CURSOR_BLINK_RATE;
1082 irqres =
1083 request_irq(IRQ_MAC_VBL, fb_vbl_handler, 0,
1084 "framebuffer vbl", info);
1085 } else {
1086 /*
1087 * VBL not detected: fall through, use timer based cursor
1088 */
1089 irqres = 1;
1090 }
1091 }
1092#endif /* CONFIG_MAC */
1093 1028
1094 fbcon_add_cursor_timer(info); 1029 fbcon_add_cursor_timer(info);
1095 fbcon_has_exited = 0; 1030 fbcon_has_exited = 0;
@@ -3520,23 +3455,26 @@ static void fbcon_exit(void)
3520 return; 3455 return;
3521 3456
3522#ifdef CONFIG_ATARI 3457#ifdef CONFIG_ATARI
3523 free_irq(IRQ_AUTO_4, fb_vbl_handler); 3458 if (MACH_IS_ATARI)
3524#endif 3459 free_irq(IRQ_AUTO_4, fb_vbl_handler);
3525#ifdef CONFIG_MAC
3526 if (MACH_IS_MAC && vbl_detected)
3527 free_irq(IRQ_MAC_VBL, fb_vbl_handler);
3528#endif 3460#endif
3529 3461
3530 kfree((void *)softback_buf); 3462 kfree((void *)softback_buf);
3531 softback_buf = 0UL; 3463 softback_buf = 0UL;
3532 3464
3533 for (i = 0; i < FB_MAX; i++) { 3465 for (i = 0; i < FB_MAX; i++) {
3466 int pending;
3467
3534 mapped = 0; 3468 mapped = 0;
3535 info = registered_fb[i]; 3469 info = registered_fb[i];
3536 3470
3537 if (info == NULL) 3471 if (info == NULL)
3538 continue; 3472 continue;
3539 3473
3474 pending = cancel_work_sync(&info->queue);
3475 DPRINTK("fbcon: %s pending work\n", (pending ? "canceled" :
3476 "no"));
3477
3540 for (j = first_fb_vc; j <= last_fb_vc; j++) { 3478 for (j = first_fb_vc; j <= last_fb_vc; j++) {
3541 if (con2fb_map[j] == i) 3479 if (con2fb_map[j] == i)
3542 mapped = 1; 3480 mapped = 1;
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,
298 return -EINVAL; 298 return -EINVAL;
299 start = info->fix.mmio_start; 299 start = info->fix.mmio_start;
300 len = PAGE_ALIGN((start & ~PAGE_MASK)+info->fix.mmio_len); 300 len = PAGE_ALIGN((start & ~PAGE_MASK)+info->fix.mmio_len);
301 pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE|_PAGE_GUARDED; 301 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
302 } else { 302 } else {
303 /* framebuffer */ 303 /* framebuffer */
304 pgprot_val(vma->vm_page_prot) |= _PAGE_WRITETHRU; 304 vma->vm_page_prot = pgprot_cached_wthru(vma->vm_page_prot);
305 } 305 }
306 start &= PAGE_MASK; 306 start &= PAGE_MASK;
307 if ((vma->vm_end - vma->vm_start + off) > len) 307 if ((vma->vm_end - vma->vm_start + off) > len)
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c
index 4835bdc4e9f1..082026546aee 100644
--- a/drivers/video/fb_defio.c
+++ b/drivers/video/fb_defio.c
@@ -24,6 +24,19 @@
24#include <linux/rmap.h> 24#include <linux/rmap.h>
25#include <linux/pagemap.h> 25#include <linux/pagemap.h>
26 26
27struct page *fb_deferred_io_page(struct fb_info *info, unsigned long offs)
28{
29 void *screen_base = (void __force *) info->screen_base;
30 struct page *page;
31
32 if (is_vmalloc_addr(screen_base + offs))
33 page = vmalloc_to_page(screen_base + offs);
34 else
35 page = pfn_to_page((info->fix.smem_start + offs) >> PAGE_SHIFT);
36
37 return page;
38}
39
27/* this is to find and return the vmalloc-ed fb pages */ 40/* this is to find and return the vmalloc-ed fb pages */
28static int fb_deferred_io_fault(struct vm_area_struct *vma, 41static int fb_deferred_io_fault(struct vm_area_struct *vma,
29 struct vm_fault *vmf) 42 struct vm_fault *vmf)
@@ -31,14 +44,12 @@ static int fb_deferred_io_fault(struct vm_area_struct *vma,
31 unsigned long offset; 44 unsigned long offset;
32 struct page *page; 45 struct page *page;
33 struct fb_info *info = vma->vm_private_data; 46 struct fb_info *info = vma->vm_private_data;
34 /* info->screen_base is virtual memory */
35 void *screen_base = (void __force *) info->screen_base;
36 47
37 offset = vmf->pgoff << PAGE_SHIFT; 48 offset = vmf->pgoff << PAGE_SHIFT;
38 if (offset >= info->fix.smem_len) 49 if (offset >= info->fix.smem_len)
39 return VM_FAULT_SIGBUS; 50 return VM_FAULT_SIGBUS;
40 51
41 page = vmalloc_to_page(screen_base + offset); 52 page = fb_deferred_io_page(info, offset);
42 if (!page) 53 if (!page)
43 return VM_FAULT_SIGBUS; 54 return VM_FAULT_SIGBUS;
44 55
@@ -60,6 +71,10 @@ int fb_deferred_io_fsync(struct file *file, struct dentry *dentry, int datasync)
60{ 71{
61 struct fb_info *info = file->private_data; 72 struct fb_info *info = file->private_data;
62 73
74 /* Skip if deferred io is complied-in but disabled on this fbdev */
75 if (!info->fbdefio)
76 return 0;
77
63 /* Kill off the delayed work */ 78 /* Kill off the delayed work */
64 cancel_rearming_delayed_work(&info->deferred_work); 79 cancel_rearming_delayed_work(&info->deferred_work);
65 80
@@ -184,7 +199,6 @@ EXPORT_SYMBOL_GPL(fb_deferred_io_open);
184 199
185void fb_deferred_io_cleanup(struct fb_info *info) 200void fb_deferred_io_cleanup(struct fb_info *info)
186{ 201{
187 void *screen_base = (void __force *) info->screen_base;
188 struct fb_deferred_io *fbdefio = info->fbdefio; 202 struct fb_deferred_io *fbdefio = info->fbdefio;
189 struct page *page; 203 struct page *page;
190 int i; 204 int i;
@@ -195,9 +209,12 @@ void fb_deferred_io_cleanup(struct fb_info *info)
195 209
196 /* clear out the mapping that we setup */ 210 /* clear out the mapping that we setup */
197 for (i = 0 ; i < info->fix.smem_len; i += PAGE_SIZE) { 211 for (i = 0 ; i < info->fix.smem_len; i += PAGE_SIZE) {
198 page = vmalloc_to_page(screen_base + i); 212 page = fb_deferred_io_page(info, i);
199 page->mapping = NULL; 213 page->mapping = NULL;
200 } 214 }
215
216 info->fbops->fb_mmap = NULL;
217 mutex_destroy(&fbdefio->lock);
201} 218}
202EXPORT_SYMBOL_GPL(fb_deferred_io_cleanup); 219EXPORT_SYMBOL_GPL(fb_deferred_io_cleanup);
203 220
diff --git a/drivers/video/macfb.c b/drivers/video/macfb.c
index ee380d5f3410..d66887e8cbb1 100644
--- a/drivers/video/macfb.c
+++ b/drivers/video/macfb.c
@@ -36,7 +36,6 @@
36#include <asm/irq.h> 36#include <asm/irq.h>
37#include <asm/macintosh.h> 37#include <asm/macintosh.h>
38#include <asm/io.h> 38#include <asm/io.h>
39#include <asm/machw.h>
40 39
41/* Common DAC base address for the LC, RBV, Valkyrie, and IIvx */ 40/* Common DAC base address for the LC, RBV, Valkyrie, and IIvx */
42#define DAC_BASE 0x50f24000 41#define DAC_BASE 0x50f24000
@@ -78,34 +77,34 @@ static int csc_setpalette (unsigned int regno, unsigned int red,
78 unsigned int green, unsigned int blue, 77 unsigned int green, unsigned int blue,
79 struct fb_info *fb_info); 78 struct fb_info *fb_info);
80 79
81static volatile struct { 80static struct {
82 unsigned char addr; 81 unsigned char addr;
83 /* Note: word-aligned */ 82 /* Note: word-aligned */
84 char pad[3]; 83 char pad[3];
85 unsigned char lut; 84 unsigned char lut;
86} *valkyrie_cmap_regs; 85} __iomem *valkyrie_cmap_regs;
87 86
88static volatile struct { 87static struct {
89 unsigned char addr; 88 unsigned char addr;
90 unsigned char lut; 89 unsigned char lut;
91} *v8_brazil_cmap_regs; 90} __iomem *v8_brazil_cmap_regs;
92 91
93static volatile struct { 92static struct {
94 unsigned char addr; 93 unsigned char addr;
95 char pad1[3]; /* word aligned */ 94 char pad1[3]; /* word aligned */
96 unsigned char lut; 95 unsigned char lut;
97 char pad2[3]; /* word aligned */ 96 char pad2[3]; /* word aligned */
98 unsigned char cntl; /* a guess as to purpose */ 97 unsigned char cntl; /* a guess as to purpose */
99} *rbv_cmap_regs; 98} __iomem *rbv_cmap_regs;
100 99
101static volatile struct { 100static struct {
102 unsigned long reset; 101 unsigned long reset;
103 unsigned long pad1[3]; 102 unsigned long pad1[3];
104 unsigned char pad2[3]; 103 unsigned char pad2[3];
105 unsigned char lut; 104 unsigned char lut;
106} *dafb_cmap_regs; 105} __iomem *dafb_cmap_regs;
107 106
108static volatile struct { 107static struct {
109 unsigned char addr; /* OFFSET: 0x00 */ 108 unsigned char addr; /* OFFSET: 0x00 */
110 unsigned char pad1[15]; 109 unsigned char pad1[15];
111 unsigned char lut; /* OFFSET: 0x10 */ 110 unsigned char lut; /* OFFSET: 0x10 */
@@ -114,16 +113,16 @@ static volatile struct {
114 unsigned char pad3[7]; 113 unsigned char pad3[7];
115 unsigned long vbl_addr; /* OFFSET: 0x28 */ 114 unsigned long vbl_addr; /* OFFSET: 0x28 */
116 unsigned int status2; /* OFFSET: 0x2C */ 115 unsigned int status2; /* OFFSET: 0x2C */
117} *civic_cmap_regs; 116} __iomem *civic_cmap_regs;
118 117
119static volatile struct { 118static struct {
120 char pad1[0x40]; 119 char pad1[0x40];
121 unsigned char clut_waddr; /* 0x40 */ 120 unsigned char clut_waddr; /* 0x40 */
122 char pad2; 121 char pad2;
123 unsigned char clut_data; /* 0x42 */ 122 unsigned char clut_data; /* 0x42 */
124 char pad3[0x3]; 123 char pad3[0x3];
125 unsigned char clut_raddr; /* 0x46 */ 124 unsigned char clut_raddr; /* 0x46 */
126} *csc_cmap_regs; 125} __iomem *csc_cmap_regs;
127 126
128/* We will leave these the way they are for the time being */ 127/* We will leave these the way they are for the time being */
129struct mdc_cmap_regs { 128struct mdc_cmap_regs {
@@ -507,10 +506,10 @@ static int csc_setpalette (unsigned int regno, unsigned int red,
507 struct fb_info *info) 506 struct fb_info *info)
508{ 507{
509 mdelay(1); 508 mdelay(1);
510 csc_cmap_regs->clut_waddr = regno; 509 nubus_writeb(regno, &csc_cmap_regs->clut_waddr);
511 csc_cmap_regs->clut_data = red; 510 nubus_writeb(red, &csc_cmap_regs->clut_data);
512 csc_cmap_regs->clut_data = green; 511 nubus_writeb(green, &csc_cmap_regs->clut_data);
513 csc_cmap_regs->clut_data = blue; 512 nubus_writeb(blue, &csc_cmap_regs->clut_data);
514 return 0; 513 return 0;
515} 514}
516 515
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,
927 } 927 }
928 928
929 dev_dbg(dev, "fb phys 0x%llx 0x%lx\n", 929 dev_dbg(dev, "fb phys 0x%llx 0x%lx\n",
930 (u64)par->fb_base_phys, (ulong)par->mapped_vram); 930 (unsigned long long)par->fb_base_phys, (ulong)par->mapped_vram);
931 dev_dbg(dev, "mmio phys 0x%llx 0x%lx\n", 931 dev_dbg(dev, "mmio phys 0x%llx 0x%lx\n",
932 (u64)par->mmio_base_phys, (ulong)par->mmio_len); 932 (unsigned long long)par->mmio_base_phys, (ulong)par->mmio_len);
933 933
934 if (mb862xx_pci_gdc_init(par)) 934 if (mb862xx_pci_gdc_init(par))
935 goto io_unmap; 935 goto io_unmap;
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)
392 int bpp; 392 int bpp;
393 393
394 rg = &plane->fbdev->mem_desc.region[plane->idx]; 394 rg = &plane->fbdev->mem_desc.region[plane->idx];
395 fbi->screen_base = (char __iomem *)rg->vaddr; 395 fbi->screen_base = rg->vaddr;
396 fix->smem_start = rg->paddr; 396 fix->smem_start = rg->paddr;
397 fix->smem_len = rg->size; 397 fix->smem_len = rg->size;
398 398
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c
index 4b5d80771904..38ac805db97d 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,
460 line_length |= (u64)src_line_length << 32; 460 line_length |= (u64)src_line_length << 32;
461 461
462 src_offset += GPU_FB_START; 462 src_offset += GPU_FB_START;
463
464 mutex_lock(&ps3_gpu_mutex);
463 status = lv1_gpu_context_attribute(ps3fb.context_handle, 465 status = lv1_gpu_context_attribute(ps3fb.context_handle,
464 L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, 466 L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT,
465 dst_offset, GPU_IOIF + src_offset, 467 dst_offset, GPU_IOIF + src_offset,
466 L1GPU_FB_BLIT_WAIT_FOR_COMPLETION | 468 L1GPU_FB_BLIT_WAIT_FOR_COMPLETION |
467 (width << 16) | height, 469 (width << 16) | height,
468 line_length); 470 line_length);
471 mutex_unlock(&ps3_gpu_mutex);
472
469 if (status) 473 if (status)
470 dev_err(dev, 474 dev_err(dev,
471 "%s: lv1_gpu_context_attribute FB_BLIT failed: %d\n", 475 "%s: lv1_gpu_context_attribute FB_BLIT failed: %d\n",
@@ -784,15 +788,6 @@ static int ps3fb_wait_for_vsync(u32 crtc)
784 return 0; 788 return 0;
785} 789}
786 790
787static void ps3fb_flip_ctl(int on, void *data)
788{
789 struct ps3fb_priv *priv = data;
790 if (on)
791 atomic_dec_if_positive(&priv->ext_flip);
792 else
793 atomic_inc(&priv->ext_flip);
794}
795
796 791
797 /* 792 /*
798 * ioctl 793 * ioctl
@@ -1228,7 +1223,6 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
1228 } 1223 }
1229 1224
1230 ps3fb.task = task; 1225 ps3fb.task = task;
1231 ps3av_register_flip_ctl(ps3fb_flip_ctl, &ps3fb);
1232 1226
1233 return 0; 1227 return 0;
1234 1228
@@ -1258,10 +1252,9 @@ static int ps3fb_shutdown(struct ps3_system_bus_device *dev)
1258 1252
1259 dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__); 1253 dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__);
1260 1254
1261 ps3fb_flip_ctl(0, &ps3fb); /* flip off */ 1255 atomic_inc(&ps3fb.ext_flip); /* flip off */
1262 ps3fb.dinfo->irq.mask = 0; 1256 ps3fb.dinfo->irq.mask = 0;
1263 1257
1264 ps3av_register_flip_ctl(NULL, NULL);
1265 if (ps3fb.task) { 1258 if (ps3fb.task) {
1266 struct task_struct *task = ps3fb.task; 1259 struct task_struct *task = ps3fb.task;
1267 ps3fb.task = NULL; 1260 ps3fb.task = NULL;
@@ -1296,8 +1289,8 @@ static int ps3fb_shutdown(struct ps3_system_bus_device *dev)
1296} 1289}
1297 1290
1298static struct ps3_system_bus_driver ps3fb_driver = { 1291static struct ps3_system_bus_driver ps3fb_driver = {
1299 .match_id = PS3_MATCH_ID_GRAPHICS, 1292 .match_id = PS3_MATCH_ID_GPU,
1300 .match_sub_id = PS3_MATCH_SUB_ID_FB, 1293 .match_sub_id = PS3_MATCH_SUB_ID_GPU_FB,
1301 .core.name = DEVICE_NAME, 1294 .core.name = DEVICE_NAME,
1302 .core.owner = THIS_MODULE, 1295 .core.owner = THIS_MODULE,
1303 .probe = ps3fb_probe, 1296 .probe = ps3fb_probe,
@@ -1355,4 +1348,4 @@ module_exit(ps3fb_exit);
1355MODULE_LICENSE("GPL"); 1348MODULE_LICENSE("GPL");
1356MODULE_DESCRIPTION("PS3 GPU Frame Buffer Driver"); 1349MODULE_DESCRIPTION("PS3 GPU Frame Buffer Driver");
1357MODULE_AUTHOR("Sony Computer Entertainment Inc."); 1350MODULE_AUTHOR("Sony Computer Entertainment Inc.");
1358MODULE_ALIAS(PS3_MODULE_ALIAS_GRAPHICS); 1351MODULE_ALIAS(PS3_MODULE_ALIAS_GPU_FB);
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 @@
13 * 13 *
14 * Thanks to Siegfried Schaefer <s.schaefer at schaefer-edv.de> 14 * Thanks to Siegfried Schaefer <s.schaefer at schaefer-edv.de>
15 * for his original source and testing! 15 * for his original source and testing!
16 *
17 * sh7760_setcolreg get from drivers/video/sh_mobile_lcdcfb.c
16 */ 18 */
17 19
18#include <linux/completion.h> 20#include <linux/completion.h>
@@ -53,29 +55,6 @@ static irqreturn_t sh7760fb_irq(int irq, void *data)
53 return IRQ_HANDLED; 55 return IRQ_HANDLED;
54} 56}
55 57
56static void sh7760fb_wait_vsync(struct fb_info *info)
57{
58 struct sh7760fb_par *par = info->par;
59
60 if (par->pd->novsync)
61 return;
62
63 iowrite16(ioread16(par->base + LDINTR) & ~VINT_CHECK,
64 par->base + LDINTR);
65
66 if (par->irq < 0) {
67 /* poll for vert. retrace: status bit is sticky */
68 while (!(ioread16(par->base + LDINTR) & VINT_CHECK))
69 cpu_relax();
70 } else {
71 /* a "wait_for_irq_event(par->irq)" would be extremely nice */
72 init_completion(&par->vsync);
73 enable_irq(par->irq);
74 wait_for_completion(&par->vsync);
75 disable_irq_nosync(par->irq);
76 }
77}
78
79/* wait_for_lps - wait until power supply has reached a certain state. */ 58/* wait_for_lps - wait until power supply has reached a certain state. */
80static int wait_for_lps(struct sh7760fb_par *par, int val) 59static int wait_for_lps(struct sh7760fb_par *par, int val)
81{ 60{
@@ -117,55 +96,28 @@ static int sh7760fb_blank(int blank, struct fb_info *info)
117 return wait_for_lps(par, lps); 96 return wait_for_lps(par, lps);
118} 97}
119 98
120/* set color registers */ 99static int sh7760_setcolreg (u_int regno,
121static int sh7760fb_setcmap(struct fb_cmap *cmap, struct fb_info *info) 100 u_int red, u_int green, u_int blue,
101 u_int transp, struct fb_info *info)
122{ 102{
123 struct sh7760fb_par *par = info->par; 103 u32 *palette = info->pseudo_palette;
124 u32 s = cmap->start;
125 u32 l = cmap->len;
126 u16 *r = cmap->red;
127 u16 *g = cmap->green;
128 u16 *b = cmap->blue;
129 u32 col, tmo;
130 int ret;
131 104
132 ret = 0; 105 if (regno >= 16)
106 return -EINVAL;
133 107
134 sh7760fb_wait_vsync(info); 108 /* only FB_VISUAL_TRUECOLOR supported */
135 109
136 /* request palette access */ 110 red >>= 16 - info->var.red.length;
137 iowrite16(LDPALCR_PALEN, par->base + LDPALCR); 111 green >>= 16 - info->var.green.length;
112 blue >>= 16 - info->var.blue.length;
113 transp >>= 16 - info->var.transp.length;
138 114
139 /* poll for access grant */ 115 palette[regno] = (red << info->var.red.offset) |
140 tmo = 100; 116 (green << info->var.green.offset) |
141 while (!(ioread16(par->base + LDPALCR) & LDPALCR_PALS) && (--tmo)) 117 (blue << info->var.blue.offset) |
142 cpu_relax(); 118 (transp << info->var.transp.offset);
143 119
144 if (!tmo) { 120 return 0;
145 ret = 1;
146 dev_dbg(info->dev, "no palette access!\n");
147 goto out;
148 }
149
150 while (l && (s < 256)) {
151 col = ((*r) & 0xff) << 16;
152 col |= ((*g) & 0xff) << 8;
153 col |= ((*b) & 0xff);
154 col &= SH7760FB_PALETTE_MASK;
155 iowrite32(col, par->base + LDPR(s));
156
157 if (s < 16)
158 ((u32 *) (info->pseudo_palette))[s] = s;
159
160 s++;
161 l--;
162 r++;
163 g++;
164 b++;
165 }
166out:
167 iowrite16(0, par->base + LDPALCR);
168 return ret;
169} 121}
170 122
171static void encode_fix(struct fb_fix_screeninfo *fix, struct fb_info *info, 123static void encode_fix(struct fb_fix_screeninfo *fix, struct fb_info *info,
@@ -406,7 +358,7 @@ static struct fb_ops sh7760fb_ops = {
406 .owner = THIS_MODULE, 358 .owner = THIS_MODULE,
407 .fb_blank = sh7760fb_blank, 359 .fb_blank = sh7760fb_blank,
408 .fb_check_var = sh7760fb_check_var, 360 .fb_check_var = sh7760fb_check_var,
409 .fb_setcmap = sh7760fb_setcmap, 361 .fb_setcolreg = sh7760_setcolreg,
410 .fb_set_par = sh7760fb_set_par, 362 .fb_set_par = sh7760fb_set_par,
411 .fb_fillrect = cfb_fillrect, 363 .fb_fillrect = cfb_fillrect,
412 .fb_copyarea = cfb_copyarea, 364 .fb_copyarea = cfb_copyarea,
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index efff672fd7b8..0e2b8fd24df1 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -16,7 +16,9 @@
16#include <linux/clk.h> 16#include <linux/clk.h>
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/dma-mapping.h> 18#include <linux/dma-mapping.h>
19#include <linux/interrupt.h>
19#include <video/sh_mobile_lcdc.h> 20#include <video/sh_mobile_lcdc.h>
21#include <asm/atomic.h>
20 22
21#define PALETTE_NR 16 23#define PALETTE_NR 16
22 24
@@ -30,11 +32,15 @@ struct sh_mobile_lcdc_chan {
30 u32 pseudo_palette[PALETTE_NR]; 32 u32 pseudo_palette[PALETTE_NR];
31 struct fb_info info; 33 struct fb_info info;
32 dma_addr_t dma_handle; 34 dma_addr_t dma_handle;
35 struct fb_deferred_io defio;
33}; 36};
34 37
35struct sh_mobile_lcdc_priv { 38struct sh_mobile_lcdc_priv {
36 void __iomem *base; 39 void __iomem *base;
40 int irq;
37#ifdef CONFIG_HAVE_CLK 41#ifdef CONFIG_HAVE_CLK
42 atomic_t clk_usecnt;
43 struct clk *dot_clk;
38 struct clk *clk; 44 struct clk *clk;
39#endif 45#endif
40 unsigned long lddckr; 46 unsigned long lddckr;
@@ -56,7 +62,7 @@ struct sh_mobile_lcdc_priv {
56 62
57/* per-channel registers */ 63/* per-channel registers */
58enum { LDDCKPAT1R, LDDCKPAT2R, LDMT1R, LDMT2R, LDMT3R, LDDFR, LDSM1R, 64enum { LDDCKPAT1R, LDDCKPAT2R, LDMT1R, LDMT2R, LDMT3R, LDDFR, LDSM1R,
59 LDSA1R, LDMLSR, LDHCNR, LDHSYNR, LDVLNR, LDVSYNR, LDPMR }; 65 LDSM2R, LDSA1R, LDMLSR, LDHCNR, LDHSYNR, LDVLNR, LDVSYNR, LDPMR };
60 66
61static unsigned long lcdc_offs_mainlcd[] = { 67static unsigned long lcdc_offs_mainlcd[] = {
62 [LDDCKPAT1R] = 0x400, 68 [LDDCKPAT1R] = 0x400,
@@ -66,6 +72,7 @@ static unsigned long lcdc_offs_mainlcd[] = {
66 [LDMT3R] = 0x420, 72 [LDMT3R] = 0x420,
67 [LDDFR] = 0x424, 73 [LDDFR] = 0x424,
68 [LDSM1R] = 0x428, 74 [LDSM1R] = 0x428,
75 [LDSM2R] = 0x42c,
69 [LDSA1R] = 0x430, 76 [LDSA1R] = 0x430,
70 [LDMLSR] = 0x438, 77 [LDMLSR] = 0x438,
71 [LDHCNR] = 0x448, 78 [LDHCNR] = 0x448,
@@ -83,6 +90,7 @@ static unsigned long lcdc_offs_sublcd[] = {
83 [LDMT3R] = 0x608, 90 [LDMT3R] = 0x608,
84 [LDDFR] = 0x60c, 91 [LDDFR] = 0x60c,
85 [LDSM1R] = 0x610, 92 [LDSM1R] = 0x610,
93 [LDSM2R] = 0x614,
86 [LDSA1R] = 0x618, 94 [LDSA1R] = 0x618,
87 [LDMLSR] = 0x620, 95 [LDMLSR] = 0x620,
88 [LDHCNR] = 0x624, 96 [LDHCNR] = 0x624,
@@ -96,6 +104,8 @@ static unsigned long lcdc_offs_sublcd[] = {
96#define LCDC_RESET 0x00000100 104#define LCDC_RESET 0x00000100
97#define DISPLAY_BEU 0x00000008 105#define DISPLAY_BEU 0x00000008
98#define LCDC_ENABLE 0x00000001 106#define LCDC_ENABLE 0x00000001
107#define LDINTR_FE 0x00000400
108#define LDINTR_FS 0x00000004
99 109
100static void lcdc_write_chan(struct sh_mobile_lcdc_chan *chan, 110static void lcdc_write_chan(struct sh_mobile_lcdc_chan *chan,
101 int reg_nr, unsigned long data) 111 int reg_nr, unsigned long data)
@@ -170,6 +180,65 @@ struct sh_mobile_lcdc_sys_bus_ops sh_mobile_lcdc_sys_bus_ops = {
170 lcdc_sys_read_data, 180 lcdc_sys_read_data,
171}; 181};
172 182
183#ifdef CONFIG_HAVE_CLK
184static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv)
185{
186 if (atomic_inc_and_test(&priv->clk_usecnt)) {
187 clk_enable(priv->clk);
188 if (priv->dot_clk)
189 clk_enable(priv->dot_clk);
190 }
191}
192
193static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv)
194{
195 if (atomic_sub_return(1, &priv->clk_usecnt) == -1) {
196 if (priv->dot_clk)
197 clk_disable(priv->dot_clk);
198 clk_disable(priv->clk);
199 }
200}
201#else
202static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv) {}
203static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv) {}
204#endif
205
206static void sh_mobile_lcdc_deferred_io(struct fb_info *info,
207 struct list_head *pagelist)
208{
209 struct sh_mobile_lcdc_chan *ch = info->par;
210
211 /* enable clocks before accessing hardware */
212 sh_mobile_lcdc_clk_on(ch->lcdc);
213
214 /* trigger panel update */
215 lcdc_write_chan(ch, LDSM2R, 1);
216}
217
218static void sh_mobile_lcdc_deferred_io_touch(struct fb_info *info)
219{
220 struct fb_deferred_io *fbdefio = info->fbdefio;
221
222 if (fbdefio)
223 schedule_delayed_work(&info->deferred_work, fbdefio->delay);
224}
225
226static irqreturn_t sh_mobile_lcdc_irq(int irq, void *data)
227{
228 struct sh_mobile_lcdc_priv *priv = data;
229 unsigned long tmp;
230
231 /* acknowledge interrupt */
232 tmp = lcdc_read(priv, _LDINTR);
233 tmp &= 0xffffff00; /* mask in high 24 bits */
234 tmp |= 0x000000ff ^ LDINTR_FS; /* status in low 8 */
235 lcdc_write(priv, _LDINTR, tmp);
236
237 /* disable clocks */
238 sh_mobile_lcdc_clk_off(priv);
239 return IRQ_HANDLED;
240}
241
173static void sh_mobile_lcdc_start_stop(struct sh_mobile_lcdc_priv *priv, 242static void sh_mobile_lcdc_start_stop(struct sh_mobile_lcdc_priv *priv,
174 int start) 243 int start)
175{ 244{
@@ -207,6 +276,11 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
207 int k, m; 276 int k, m;
208 int ret = 0; 277 int ret = 0;
209 278
279 /* enable clocks before accessing the hardware */
280 for (k = 0; k < ARRAY_SIZE(priv->ch); k++)
281 if (priv->ch[k].enabled)
282 sh_mobile_lcdc_clk_on(priv);
283
210 /* reset */ 284 /* reset */
211 lcdc_write(priv, _LDCNT2R, lcdc_read(priv, _LDCNT2R) | LCDC_RESET); 285 lcdc_write(priv, _LDCNT2R, lcdc_read(priv, _LDCNT2R) | LCDC_RESET);
212 lcdc_wait_bit(priv, _LDCNT2R, LCDC_RESET, 0); 286 lcdc_wait_bit(priv, _LDCNT2R, LCDC_RESET, 0);
@@ -249,7 +323,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
249 lcdc_write(priv, _LDDCKSTPR, 0); 323 lcdc_write(priv, _LDDCKSTPR, 0);
250 lcdc_wait_bit(priv, _LDDCKSTPR, ~0, 0); 324 lcdc_wait_bit(priv, _LDDCKSTPR, ~0, 0);
251 325
252 /* interrupts are disabled */ 326 /* interrupts are disabled to begin with */
253 lcdc_write(priv, _LDINTR, 0); 327 lcdc_write(priv, _LDINTR, 0);
254 328
255 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { 329 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
@@ -310,9 +384,6 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
310 return ret; 384 return ret;
311 } 385 }
312 386
313 /* --- display_lcdc_data() --- */
314 lcdc_write(priv, _LDINTR, 0x00000f00);
315
316 /* word and long word swap */ 387 /* word and long word swap */
317 lcdc_write(priv, _LDDDSR, lcdc_read(priv, _LDDDSR) | 6); 388 lcdc_write(priv, _LDDDSR, lcdc_read(priv, _LDDDSR) | 6);
318 389
@@ -334,8 +405,24 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
334 /* set line size */ 405 /* set line size */
335 lcdc_write_chan(ch, LDMLSR, ch->info.fix.line_length); 406 lcdc_write_chan(ch, LDMLSR, ch->info.fix.line_length);
336 407
337 /* continuous read mode */ 408 /* setup deferred io if SYS bus */
338 lcdc_write_chan(ch, LDSM1R, 0); 409 tmp = ch->cfg.sys_bus_cfg.deferred_io_msec;
410 if (ch->ldmt1r_value & (1 << 12) && tmp) {
411 ch->defio.deferred_io = sh_mobile_lcdc_deferred_io;
412 ch->defio.delay = msecs_to_jiffies(tmp);
413 ch->info.fbdefio = &ch->defio;
414 fb_deferred_io_init(&ch->info);
415
416 /* one-shot mode */
417 lcdc_write_chan(ch, LDSM1R, 1);
418
419 /* enable "Frame End Interrupt Enable" bit */
420 lcdc_write(priv, _LDINTR, LDINTR_FE);
421
422 } else {
423 /* continuous read mode */
424 lcdc_write_chan(ch, LDSM1R, 0);
425 }
339 } 426 }
340 427
341 /* display output */ 428 /* display output */
@@ -359,6 +446,7 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
359{ 446{
360 struct sh_mobile_lcdc_chan *ch; 447 struct sh_mobile_lcdc_chan *ch;
361 struct sh_mobile_lcdc_board_cfg *board_cfg; 448 struct sh_mobile_lcdc_board_cfg *board_cfg;
449 unsigned long tmp;
362 int k; 450 int k;
363 451
364 /* tell the board code to disable the panel */ 452 /* tell the board code to disable the panel */
@@ -367,10 +455,22 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
367 board_cfg = &ch->cfg.board_cfg; 455 board_cfg = &ch->cfg.board_cfg;
368 if (board_cfg->display_off) 456 if (board_cfg->display_off)
369 board_cfg->display_off(board_cfg->board_data); 457 board_cfg->display_off(board_cfg->board_data);
458
459 /* cleanup deferred io if SYS bus */
460 tmp = ch->cfg.sys_bus_cfg.deferred_io_msec;
461 if (ch->ldmt1r_value & (1 << 12) && tmp) {
462 fb_deferred_io_cleanup(&ch->info);
463 ch->info.fbdefio = NULL;
464 }
370 } 465 }
371 466
372 /* stop the lcdc */ 467 /* stop the lcdc */
373 sh_mobile_lcdc_start_stop(priv, 0); 468 sh_mobile_lcdc_start_stop(priv, 0);
469
470 /* stop clocks */
471 for (k = 0; k < ARRAY_SIZE(priv->ch); k++)
472 if (priv->ch[k].enabled)
473 sh_mobile_lcdc_clk_off(priv);
374} 474}
375 475
376static int sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch) 476static int sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch)
@@ -413,9 +513,13 @@ static int sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch)
413 return -EINVAL; 513 return -EINVAL;
414} 514}
415 515
416static int sh_mobile_lcdc_setup_clocks(struct device *dev, int clock_source, 516static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev,
517 int clock_source,
417 struct sh_mobile_lcdc_priv *priv) 518 struct sh_mobile_lcdc_priv *priv)
418{ 519{
520#ifdef CONFIG_HAVE_CLK
521 char clk_name[8];
522#endif
419 char *str; 523 char *str;
420 int icksel; 524 int icksel;
421 525
@@ -430,14 +534,21 @@ static int sh_mobile_lcdc_setup_clocks(struct device *dev, int clock_source,
430 priv->lddckr = icksel << 16; 534 priv->lddckr = icksel << 16;
431 535
432#ifdef CONFIG_HAVE_CLK 536#ifdef CONFIG_HAVE_CLK
537 atomic_set(&priv->clk_usecnt, -1);
538 snprintf(clk_name, sizeof(clk_name), "lcdc%d", pdev->id);
539 priv->clk = clk_get(&pdev->dev, clk_name);
540 if (IS_ERR(priv->clk)) {
541 dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
542 return PTR_ERR(priv->clk);
543 }
544
433 if (str) { 545 if (str) {
434 priv->clk = clk_get(dev, str); 546 priv->dot_clk = clk_get(&pdev->dev, str);
435 if (IS_ERR(priv->clk)) { 547 if (IS_ERR(priv->dot_clk)) {
436 dev_err(dev, "cannot get clock %s\n", str); 548 dev_err(&pdev->dev, "cannot get dot clock %s\n", str);
437 return PTR_ERR(priv->clk); 549 clk_put(priv->clk);
550 return PTR_ERR(priv->dot_clk);
438 } 551 }
439
440 clk_enable(priv->clk);
441 } 552 }
442#endif 553#endif
443 554
@@ -475,11 +586,34 @@ static struct fb_fix_screeninfo sh_mobile_lcdc_fix = {
475 .accel = FB_ACCEL_NONE, 586 .accel = FB_ACCEL_NONE,
476}; 587};
477 588
589static void sh_mobile_lcdc_fillrect(struct fb_info *info,
590 const struct fb_fillrect *rect)
591{
592 sys_fillrect(info, rect);
593 sh_mobile_lcdc_deferred_io_touch(info);
594}
595
596static void sh_mobile_lcdc_copyarea(struct fb_info *info,
597 const struct fb_copyarea *area)
598{
599 sys_copyarea(info, area);
600 sh_mobile_lcdc_deferred_io_touch(info);
601}
602
603static void sh_mobile_lcdc_imageblit(struct fb_info *info,
604 const struct fb_image *image)
605{
606 sys_imageblit(info, image);
607 sh_mobile_lcdc_deferred_io_touch(info);
608}
609
478static struct fb_ops sh_mobile_lcdc_ops = { 610static struct fb_ops sh_mobile_lcdc_ops = {
479 .fb_setcolreg = sh_mobile_lcdc_setcolreg, 611 .fb_setcolreg = sh_mobile_lcdc_setcolreg,
480 .fb_fillrect = cfb_fillrect, 612 .fb_read = fb_sys_read,
481 .fb_copyarea = cfb_copyarea, 613 .fb_write = fb_sys_write,
482 .fb_imageblit = cfb_imageblit, 614 .fb_fillrect = sh_mobile_lcdc_fillrect,
615 .fb_copyarea = sh_mobile_lcdc_copyarea,
616 .fb_imageblit = sh_mobile_lcdc_imageblit,
483}; 617};
484 618
485static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp) 619static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp)
@@ -540,8 +674,9 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
540 } 674 }
541 675
542 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 676 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
543 if (res == NULL) { 677 i = platform_get_irq(pdev, 0);
544 dev_err(&pdev->dev, "cannot find IO resource\n"); 678 if (!res || i < 0) {
679 dev_err(&pdev->dev, "cannot get platform resources\n");
545 error = -ENOENT; 680 error = -ENOENT;
546 goto err0; 681 goto err0;
547 } 682 }
@@ -553,6 +688,14 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
553 goto err0; 688 goto err0;
554 } 689 }
555 690
691 error = request_irq(i, sh_mobile_lcdc_irq, IRQF_DISABLED,
692 pdev->dev.bus_id, priv);
693 if (error) {
694 dev_err(&pdev->dev, "unable to request irq\n");
695 goto err1;
696 }
697
698 priv->irq = i;
556 platform_set_drvdata(pdev, priv); 699 platform_set_drvdata(pdev, priv);
557 pdata = pdev->dev.platform_data; 700 pdata = pdev->dev.platform_data;
558 701
@@ -587,8 +730,7 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
587 goto err1; 730 goto err1;
588 } 731 }
589 732
590 error = sh_mobile_lcdc_setup_clocks(&pdev->dev, 733 error = sh_mobile_lcdc_setup_clocks(pdev, pdata->clock_source, priv);
591 pdata->clock_source, priv);
592 if (error) { 734 if (error) {
593 dev_err(&pdev->dev, "unable to setup clocks\n"); 735 dev_err(&pdev->dev, "unable to setup clocks\n");
594 goto err1; 736 goto err1;
@@ -637,6 +779,7 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
637 info->fix.smem_start = priv->ch[i].dma_handle; 779 info->fix.smem_start = priv->ch[i].dma_handle;
638 info->screen_base = buf; 780 info->screen_base = buf;
639 info->device = &pdev->dev; 781 info->device = &pdev->dev;
782 info->par = &priv->ch[i];
640 } 783 }
641 784
642 if (error) 785 if (error)
@@ -664,6 +807,10 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
664 (int) priv->ch[i].cfg.lcd_cfg.xres, 807 (int) priv->ch[i].cfg.lcd_cfg.xres,
665 (int) priv->ch[i].cfg.lcd_cfg.yres, 808 (int) priv->ch[i].cfg.lcd_cfg.yres,
666 priv->ch[i].cfg.bpp); 809 priv->ch[i].cfg.bpp);
810
811 /* deferred io mode: disable clock to save power */
812 if (info->fbdefio)
813 sh_mobile_lcdc_clk_off(priv);
667 } 814 }
668 815
669 return 0; 816 return 0;
@@ -697,15 +844,16 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev)
697 } 844 }
698 845
699#ifdef CONFIG_HAVE_CLK 846#ifdef CONFIG_HAVE_CLK
700 if (priv->clk) { 847 if (priv->dot_clk)
701 clk_disable(priv->clk); 848 clk_put(priv->dot_clk);
702 clk_put(priv->clk); 849 clk_put(priv->clk);
703 }
704#endif 850#endif
705 851
706 if (priv->base) 852 if (priv->base)
707 iounmap(priv->base); 853 iounmap(priv->base);
708 854
855 if (priv->irq)
856 free_irq(priv->irq, priv);
709 kfree(priv); 857 kfree(priv);
710 return 0; 858 return 0;
711} 859}