Dash:
[t2.git] / architecture / mips64 / package / linux / 4004_all-add-impact-driver.patch
blob48fa5140ce673e9ee65c55b138ab0421c96e8efb
1 diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
2 index 591a13a59787..0f28a5604867 100644
3 --- a/drivers/video/fbdev/Kconfig
4 +++ b/drivers/video/fbdev/Kconfig
5 @@ -721,6 +721,12 @@ config FB_GBE_MEM
6 This is the amount of memory reserved for the framebuffer,
7 which can be any value between 1MB and 8MB.
9 +config FB_IMPACT
10 + tristate "SGI Impact graphics support"
11 + depends on FB && (SGI_IP22 || SGI_IP26 || SGI_IP27 || SGI_IP28 || SGI_IP30)
12 + help
13 + SGI Impact (MardiGras/MGRAS) graphics card support.
15 config FB_SBUS
16 bool "SBUS and UPA framebuffers"
17 depends on (FB = y) && SPARC
18 diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile
19 index 13c900320c2c..25e16a8be5aa 100644
20 --- a/drivers/video/fbdev/Makefile
21 +++ b/drivers/video/fbdev/Makefile
22 @@ -125,6 +125,7 @@ obj-$(CONFIG_FB_PUV3_UNIGFX) += fb-puv3.o
23 obj-$(CONFIG_FB_HYPERV) += hyperv_fb.o
24 obj-$(CONFIG_FB_OPENCORES) += ocfb.o
25 obj-$(CONFIG_FB_SM712) += sm712fb.o
26 +obj-$(CONFIG_FB_IMPACT) += impact.o
28 # Platform or fallback drivers go here
29 obj-$(CONFIG_FB_UVESA) += uvesafb.o
30 diff --git a/drivers/video/fbdev/impact.c b/drivers/video/fbdev/impact.c
31 new file mode 100644
32 index 000000000000..caaa6fb400cc
33 --- /dev/null
34 +++ b/drivers/video/fbdev/impact.c
35 @@ -0,0 +1,1298 @@
36 +/*
37 + * drivers/video/fbdev/impact.c
38 + * SGI Octane MardiGras (IMPACTSR) graphics
39 + * SGI Indigo2 MardiGras (IMPACT) graphics
40 + *
41 + * Copyright (c)
42 + * 2004-2006 by Stanislaw Skowronek <skylark@unaligned.org> (author)
43 + * 2005 by Peter Fuerst <post@pfrst.de> (Indigo2 adaptation)
44 + * 2007-2009 by Johannes Dickgreber <tanzy@gmx.de> (platform_driver)
45 + * 2014 by Thomas Bogendoerfer <tsbogend@alpha.franken.de> (gio_driver)
46 + * 2011-2015 by Joshua Kinard <kumba@gentoo.org> (upkeeping/maintenance)
47 + *
48 + * Based on linux/drivers/video/skeletonfb.c
49 + *
50 + * This driver, as most of the IP30 (SGI Octane) port, is a result of massive
51 + * amounts of reverse engineering and trial-and-error. If anyone is interested
52 + * in helping with it, please contact me: <skylark@unaligned.org>.
53 + *
54 + * The basic functions of this driver are filling and blitting rectangles.
55 + * To achieve the latter, two DMA operations are used on Impact. It is unclear
56 + * to me, why is it so, but even Xsgi (the IRIX X11 server) does it this way.
57 + * It seems that fb->fb operations are not operational on these cards.
58 + *
59 + * For this purpose, a kernel DMA pool is allocated (pool number 0). This pool
60 + * is (by default) 64kB in size. An ioctl could be used to set the value at
61 + * run-time. Applications can use this pool, however proper locking has to be
62 + * guaranteed. Kernel should be locked out from this pool by an ioctl.
63 + *
64 + * The IMPACT is quite well worked-out currently, except for the Geometry
65 + * Engines (GE11). Any information about use of those devices would be very
66 + * useful. It would enable a Linux OpenGL driver, as most of OpenGL calls are
67 + * supported directly by the hardware. So far, I can't initialize the GE11.
68 + * Verification of microcode crashes the graphics.
69 + *
70 + * This file is subject to the terms and conditions of the GNU General Public
71 + * License. See the file COPYING in the main directory of this archive for
72 + * more details.
73 + */
75 +#include <linux/module.h>
76 +#include <linux/kernel.h>
77 +#include <linux/errno.h>
78 +#include <linux/string.h>
79 +#include <linux/mm.h>
80 +#include <linux/tty.h>
81 +#include <linux/slab.h>
82 +#include <linux/delay.h>
83 +#include <linux/fb.h>
84 +#include <linux/init.h>
85 +#include <linux/vmalloc.h>
86 +#include <linux/module.h>
87 +#include <linux/dma-mapping.h>
88 +#include <linux/spinlock.h>
89 +#include <linux/font.h>
91 +#include <video/impact.h>
93 +#ifndef SGI_INDIGO2
94 +/* IP27/IP30 */
95 +#include <linux/platform_device.h>
96 +#define USE_POOLS 5
97 +extern unsigned long xtalk_get_swin(int node, int wid);
98 +#else
99 +/* IP22/IP28 */
100 +#include <asm/sgi/mc.h>
101 +#include <asm/gio_device.h>
102 +#define USE_POOLS 4
103 +#endif
105 +#define MAX_POOLS 5
106 +#define IMP_KPOOL_SIZE 65536
107 +#define ALPHA_WAR 33
109 +/**
110 + * struct impact_par - Impact private data.
111 + * @mmio_virt: virtual mmio base.
112 + * @mmio_base: physical mmio base.
113 + * @pool_txtbl: txtbl[p][i] = pgidx(phys[p][i]).
114 + * @pool_txnum: valid: txtbl[p][0 ... (txnum[p] - 1)].
115 + * @pool_txmax: alloc: txtbl[p][0 ... (txmax[p] - 1)].
116 + * @pool_txphys: txphys[p] = dma_addr(txtbl[p]).
117 + * @kpool_virt: virt[p]: txnum[p] page_addr.
118 + * @kpool_phys: phys[p][i] = dma_addr(virt[p][i]).
119 + * @kpool_size: TBD.
120 + * @num_rss: TBD.
121 + * @open_flag: TBD.
122 + * @lock: private lock variable for spin locking/unlocking.
123 + * @pseudo_palette: TBD.
124 + * @dev: struct device pointer for generic device data.
125 + */
126 +struct impact_par {
127 + /* I/O bases. */
128 + void * __iomem mmio_virt;
129 + unsigned long mmio_base;
131 + /* DMA pool management. */
132 + u32 *pool_txtbl[MAX_POOLS];
133 + u32 pool_txnum[MAX_POOLS];
134 + u32 pool_txmax[MAX_POOLS];
135 + unsigned long pool_txphys[MAX_POOLS];
137 + /* Kernel DMA pools. */
138 + unsigned long **kpool_virt[MAX_POOLS];
139 + unsigned long *kpool_phys[MAX_POOLS];
140 + u32 kpool_size[MAX_POOLS];
142 + /* Board config. */
143 + u32 num_ge;
144 + u32 num_rss;
146 + /* Locking. */
147 + int open_flag;
148 + spinlock_t lock;
150 + /* Misc. */
151 + u32 pseudo_palette[16];
152 + struct device *dev;
155 +static struct fb_fix_screeninfo
156 +impact_fix_default = {
157 +#ifndef SGI_INDIGO2
158 + .id = "ImpactSR 0RSS",
159 +#else
160 + .id = "Impact",
161 +#endif
162 + .smem_start = 0,
163 + .smem_len = 0,
164 + .type = FB_TYPE_PACKED_PIXELS,
165 + .visual = FB_VISUAL_TRUECOLOR,
166 + .xpanstep = 0,
167 + .ypanstep = 0,
168 + .ywrapstep = 0,
169 + .line_length = 0,
170 + .accel = FB_ACCEL_SGI_IMPACT,
173 +static struct fb_var_screeninfo
174 +impact_var_default = {
175 + .xres = 1280,
176 + .yres = 1024,
177 + .xres_virtual = 1280,
178 + .yres_virtual = 1024,
179 + .bits_per_pixel = 24,
180 + .red = { .offset = 0, .length = 8 },
181 + .green = { .offset = 8, .length = 8 },
182 + .blue = { .offset = 16, .length = 8 },
183 + .transp = { .offset = 24, .length = 8 },
187 +/* ----------------------------------------------------------------------- */
188 +/* Gory details */
189 +#define MMIO (((struct impact_par *)info->par)->mmio_virt)
191 +/**
192 + * impact_wait_cfifo_empty - wait until impact CFIFO buffer is empty.
193 + * @info: struct fb_info pointer to framebuffer data.
194 + */
195 +static inline void
196 +impact_wait_cfifo_empty(struct fb_info *info)
198 + while (IMP_FIFOSTATUS(MMIO) & MSK_CFIFO_CNT)
199 + cpu_relax();
202 +/**
203 + * impact_wait_dma_done - wait until pending DMA operations are complete.
204 + * @info: struct fb_info pointer to framebuffer data.
205 + */
206 +static inline void
207 +impact_wait_dma_done(struct fb_info *info)
209 + while (IMP_DMABUSY(MMIO) & 0x1f)
210 + cpu_relax();
212 + while (!(IMP_STATUS(MMIO) & 1))
213 + cpu_relax();
215 + while (!(IMP_STATUS(MMIO) & 2)) /* RSS_IDLE */
216 + cpu_relax();
218 + while (!(IMP_RESTATUS(MMIO) & 0x100))
219 + cpu_relax();
222 +/**
223 + * impact_wait_dma_ready - wait until DMA is ready.
224 + * @info: struct fb_info pointer to framebuffer data.
225 + */
226 +static inline void
227 +impact_wait_dma_ready(struct fb_info *info)
229 + IMP_CFIFOW(MMIO) = 0x000e0100;
230 + while (IMP_DMABUSY(MMIO) & 0x1eff)
231 + cpu_relax();
233 + while (!(IMP_STATUS(MMIO) & 2))
234 + cpu_relax();
236 +/* ----------------------------------------------------------------------- */
239 +/* ----------------------------------------------------------------------- */
240 +/* DMA management */
242 +/**
243 + * impact_detachtxtbl - TBD.
244 + * @info: struct fb_info pointer to framebuffer data.
245 + * @pool: DMA pool number.
246 + */
247 +static inline void
248 +impact_detachtxtbl(struct fb_info *info, unsigned long pool)
250 + /* Clear DMA pool. */
251 + impact_wait_cfifo_empty(info);
252 + impact_wait_dma_done(info);
253 + IMP_CFIFOPW1(MMIO) = IMP_CMD_HQ_TXBASE(pool);
254 + IMP_CFIFOP(MMIO) = 0x0000000000000009;
255 + IMP_CFIFOP(MMIO) = IMP_CMD_HQ_TXMAX(pool, 0);
256 + IMP_CFIFOP(MMIO) = IMP_CMD_HQ_PGBITS(pool, 0);
257 +#ifndef SGI_INDIGO2
258 + IMP_CFIFOP(MMIO) = IMP_CMD_HQ_484B(pool, 0x00080000);
259 +#endif
260 + impact_wait_cfifo_empty(info);
261 + impact_wait_dma_ready(info);
264 +/**
265 + * impact_initdma - init impact DMA.
266 + * @info: struct fb_info pointer to framebuffer data.
267 + */
268 +static inline void __init
269 +impact_initdma(struct fb_info *info)
271 + struct impact_par *par = info->par;
272 + unsigned long pool;
274 + /* Clear DMA pools. */
275 + for (pool = 0; pool < MAX_POOLS; pool++) {
276 + impact_detachtxtbl(info, pool);
277 + par->pool_txmax[pool] = 0;
278 + par->pool_txnum[pool] = 0;
281 + /* Set DMA parameters. */
282 + impact_wait_cfifo_empty(info);
283 + IMP_CFIFOP(MMIO) = IMP_CMD_HQ_PGSIZE(0);
284 + IMP_CFIFOP(MMIO) = IMP_CMD_HQ_STACKPTR(0);
285 +#ifndef SGI_INDIGO2
286 + IMP_CFIFOP(MMIO) = IMP_CMD_HQ_484A(0, 0x00180000);
287 +#endif
288 + IMP_CFIFOPW(MMIO) = 0x000e0100;
289 + IMP_CFIFOPW(MMIO) = 0x000e0100;
290 + IMP_CFIFOPW(MMIO) = 0x000e0100;
291 + IMP_CFIFOPW(MMIO) = 0x000e0100;
292 + IMP_CFIFOPW(MMIO) = 0x000e0100;
293 +#ifndef SGI_INDIGO2
294 + IMP_REG32(MMIO, 0x40918) = 0x00680000;
295 + IMP_REG32(MMIO, 0x40920) = 0x80280000;
296 + IMP_REG32(MMIO, 0x40928) = 0x00000000;
297 +#endif
300 +/**
301 + * impact_writetxtbl - write to the texture (?) tables.
302 + * @info: struct fb_info pointer to framebuffer data.
303 + * @pool: DMA pool number.
304 + */
305 +static void
306 +impact_writetxtbl(struct fb_info *info, int pool)
308 + struct impact_par *par = info->par;
310 + impact_wait_cfifo_empty(info);
311 + impact_wait_dma_done(info);
313 + /* Inform the card about a new DMA pool. */
314 + IMP_CFIFOPW1(MMIO) = IMP_CMD_HQ_TXBASE(pool);
315 + IMP_CFIFOP(MMIO) = par->pool_txphys[pool];
316 + IMP_CFIFOP(MMIO) = IMP_CMD_HQ_TXMAX(pool, par->pool_txnum[pool]);
317 + IMP_CFIFOP(MMIO) = IMP_CMD_HQ_PGBITS(pool, 0x0a);
318 +#ifndef SGI_INDIGO2
319 + IMP_CFIFOP(MMIO) = IMP_CMD_HQ_484B(pool, 0x00180000);
320 +#endif
321 + IMP_CFIFOPW(MMIO) = 0x000e0100;
322 + IMP_CFIFOPW(MMIO) = 0x000e0100;
323 + IMP_CFIFOPW(MMIO) = 0x000e0100;
324 + IMP_CFIFOPW(MMIO) = 0x000e0100;
325 + IMP_CFIFOPW(MMIO) = 0x000e0100;
327 + impact_wait_cfifo_empty(info);
328 + impact_wait_dma_ready(info);
331 +/**
332 + * impact_dma_alloc - use correct dma alloc func based on machine type.
333 + * @dev: struct device pointer to pass to dma_alloc_[non]coherent().
334 + * @size: dma size to alloc.
335 + * @dma_handle: pointer to dma handle.
336 + * @gfp: gfp flags.
337 + */
338 +static inline void
339 +*impact_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
340 + gfp_t gfp)
342 +#ifndef SGI_INDIGO2
343 + /* IP27/IP30 are coherent. */
344 + return dma_alloc_coherent(dev, size, dma_handle, gfp);
345 +#else
346 + /* IP22/IP28 are noncoherent. */
347 + return dma_alloc_noncoherent(dev, size, dma_handle, gfp);
348 +#endif
351 +/**
352 + * impact_dma_free - use correct dma free func based on machine type.
353 + * @dev: struct device pointer to pass to dma_free_[non]coherent().
354 + * @size: dma size to free.
355 + * @vaddr: void pointer to virtual address to free.
356 + * @dma_handle: dma handle address.
357 + */
358 +static inline void
359 +impact_dma_free(struct device *dev, size_t size, void *vaddr,
360 + dma_addr_t dma_handle)
362 +#ifndef SGI_INDIGO2
363 + /* IP27/IP30 are coherent. */
364 + dma_free_coherent(dev, size, vaddr, dma_handle);
365 +#else
366 + /* IP22/IP28 are noncoherent. */
367 + dma_free_noncoherent(dev, size, vaddr, dma_handle);
368 +#endif
371 +/**
372 + * impact_alloctxtbl - allocate the texture (?) tables.
373 + * @info: struct fb_info pointer to framebuffer data.
374 + * @pool: DMA pool number.
375 + * @pages: number of memory pages to allocate.
376 + */
377 +static void
378 +impact_alloctxtbl(struct fb_info *info, int pool, int pages)
380 + int alloc_count;
381 + u32 *dma_alloc;
382 + dma_addr_t dma_handle;
383 + struct impact_par *par = info->par;
385 + if (pages > par->pool_txmax[pool]) {
386 + /* Grow the pool; unlikely, but supported. */
387 + alloc_count = pages;
388 + if (alloc_count < 1024)
389 + alloc_count = 1024;
391 + if (par->pool_txmax[pool])
392 + impact_dma_free(par->dev, (par->pool_txmax[pool] * 4),
393 + par->pool_txtbl[pool],
394 + par->pool_txphys[pool]);
395 + dma_alloc = impact_dma_alloc(par->dev, (alloc_count * 4),
396 + &dma_handle, GFP_KERNEL);
397 + par->pool_txtbl[pool] = dma_alloc;
398 + par->pool_txphys[pool] = dma_handle;
399 + par->pool_txmax[pool] = alloc_count;
401 + par->pool_txnum[pool] = pages;
404 +/**
405 + * impact_resize_kpool - resize kernel DMA pools.
406 + * @info: struct fb_info pointer to framebuffer data.
407 + * @pool: DMA pool number.
408 + * @size: new pool size.
409 + * @growonly: only grow the pool (?).
410 + */
411 +static void
412 +impact_resize_kpool(struct fb_info *info, int pool, int size, bool growonly)
414 + int i, pages;
415 + unsigned long *dma_alloc;
416 + dma_addr_t dma_handle;
417 + struct impact_par *par = info->par;
419 + if (growonly && (par->kpool_size[pool] >= size))
420 + return;
422 + /* Single line smallcopy (1280 * 4) MUST work. */
423 + if (size < 8192)
424 + size = 8192;
425 + pages = ((size + (PAGE_SIZE - 1)) >> PAGE_SHIFT);
427 + /* Before manipulating the tbl, detach it from the card. */
428 + impact_detachtxtbl(info, pool);
429 + if (par->kpool_size[pool] > 0) {
430 + for (i = 0; i < par->pool_txnum[pool]; i++) {
431 + ClearPageReserved(
432 + virt_to_page(par->kpool_virt[pool][i]));
433 + impact_dma_free(par->dev, PAGE_SIZE,
434 + par->kpool_virt[pool][i],
435 + par->kpool_phys[pool][i]);
437 + vfree(par->kpool_phys[pool]);
438 + vfree(par->kpool_virt[pool]);
440 + impact_alloctxtbl(info, pool, pages);
442 + par->kpool_virt[pool] = vzalloc(pages * sizeof(unsigned long));
443 + par->kpool_phys[pool] = vzalloc(pages * sizeof(unsigned long));
444 + for (i = 0; i < par->pool_txnum[pool]; i++) {
445 + dma_alloc = impact_dma_alloc(par->dev, PAGE_SIZE,
446 + &dma_handle, GFP_KERNEL);
447 + par->kpool_virt[pool][i] = dma_alloc;
448 + SetPageReserved(virt_to_page(par->kpool_virt[pool][i]));
449 + par->kpool_phys[pool][i] = dma_handle;
450 + par->pool_txtbl[pool][i] = (dma_handle >> PAGE_SHIFT);
452 + dma_cache_sync(NULL, par->pool_txtbl[pool], (i * 4),
453 + DMA_BIDIRECTIONAL);
455 + /* Finally, reattach the tbl to the card. */
456 + impact_writetxtbl(info, pool);
457 + par->kpool_size[pool] = (pages * PAGE_SIZE);
459 +/* ----------------------------------------------------------------------- */
462 +/* ----------------------------------------------------------------------- */
463 +/* Basic drawing stuff */
465 +/**
466 + * impact_rect - fill rectangle (?).
467 + * @info: struct fb_info pointer to framebuffer data.
468 + * @r: const struct fb_fillrect pointer to rectangle fill data.
469 + * @lo: PP1 logic operation.
470 + */
471 +static void
472 +impact_rect(struct fb_info *info, const struct fb_fillrect *r, u32 lo)
474 + u32 palette;
476 + impact_wait_cfifo_empty(info);
478 + if (lo == IMP_LO_COPY)
479 + IMP_CFIFO(MMIO) = IMP_CMD_PP1FILLMODE(0x6300, lo);
480 + else
481 + IMP_CFIFO(MMIO) = IMP_CMD_PP1FILLMODE(0x6304, lo);
483 + palette = ((u32 *)info->pseudo_palette)[r->color];
484 + IMP_CFIFO(MMIO) = IMP_CMD_FILLMODE(0);
485 + IMP_CFIFO(MMIO) = IMP_CMD_PACKEDCOLOR(palette);
486 + IMP_CFIFO(MMIO) = IMP_CMD_BLOCKXYSTARTI(r->dx, r->dy);
487 + IMP_CFIFO(MMIO) = IMP_CMD_BLOCKXYENDI(((r->dx + r->width) - 1),
488 + ((r->dy + r->height) - 1));
489 + IMP_CFIFO(MMIO) = IMP_CMD_IR_ALIAS(0x18);
492 +/**
493 + * impact_smallcopy - copy a small area (?).
494 + * @info: struct fb_info pointer to framebuffer data.
495 + * @new: const struct fb_copyarea pointer to new area data.
496 + */
497 +static void
498 +impact_smallcopy(struct fb_info *info, const struct fb_copyarea *a)
500 + u32 tw;
501 + struct impact_par *par = info->par;
503 + if (unlikely(a->width < 1 || a->height < 1))
504 + return;
506 + tw = ((a->width + 1) & ~1);
508 + /* Setup and perform DMA from RE to host. */
509 + impact_wait_dma_done(info);
511 + /*
512 + * Select the RSS to read from.
514 + * XXX: Beware, only Indigo2 MaxImpact has 2 REs, SI/HI will hang!
515 + */
516 + if (par->num_rss == 2) {
517 + if (a->sy & 1)
518 + IMP_CFIFO(MMIO) = IMP_CMD_CONFIG(0xca5);
519 + else
520 + IMP_CFIFO(MMIO) = IMP_CMD_CONFIG(0xca4);
521 + } else {
522 + IMP_CFIFO(MMIO) = IMP_CMD_CONFIG(0xca4);
525 + IMP_CFIFO(MMIO) = IMP_CMD_PIXCMD(2);
526 + IMP_CFIFO(MMIO) = IMP_CMD_PP1FILLMODE(0x2200, IMP_LO_COPY);
527 + IMP_CFIFO(MMIO) = IMP_CMD_COLORMASKLSBSA(0xffffff);
528 + IMP_CFIFO(MMIO) = IMP_CMD_COLORMASKLSBSB(0xffffff);
529 + IMP_CFIFO(MMIO) = IMP_CMD_COLORMASKMSBS(0);
530 + IMP_CFIFO(MMIO) = IMP_CMD_DRBPOINTERS(0xc8240);
531 + IMP_CFIFO(MMIO) = IMP_CMD_BLOCKXYSTARTI(a->sx,
532 + ((a->sy + a->height) - 1));
533 + IMP_CFIFO(MMIO) = IMP_CMD_BLOCKXYENDI(((a->sx + tw) - 1), a->sy);
534 + IMP_CFIFO(MMIO) = IMP_CMD_XFRMASKLO(0xffffff);
535 + IMP_CFIFO(MMIO) = IMP_CMD_XFRMASKHI(0xffffff);
536 + IMP_CFIFO(MMIO) = IMP_CMD_XFRSIZE(tw, a->height);
537 + IMP_CFIFO(MMIO) = IMP_CMD_XFRCOUNTERS(tw, a->height);
538 + IMP_CFIFO(MMIO) = IMP_CMD_XFRMODE(0x00080);
539 + IMP_CFIFO(MMIO) = IMP_CMD_FILLMODE(0x01000000);
540 + IMP_CFIFO(MMIO) = IMP_CMD_HQ_PIXELFORMAT(0x200);
541 + IMP_CFIFO(MMIO) = IMP_CMD_HQ_SCANWIDTH(tw << 2);
542 + IMP_CFIFO(MMIO) = IMP_CMD_HQ_DMATYPE(0x0a);
543 + IMP_CFIFO(MMIO) = IMP_CMD_HQ_PG_LIST_0(0x80000000);
544 + IMP_CFIFO(MMIO) = IMP_CMD_HQ_PG_WIDTH(tw << 2);
545 + IMP_CFIFO(MMIO) = IMP_CMD_HQ_PG_OFFSET(0);
546 + IMP_CFIFO(MMIO) = IMP_CMD_HQ_PG_STARTADDR(0);
547 + IMP_CFIFO(MMIO) = IMP_CMD_HQ_PG_LINECNT(a->height);
548 + IMP_CFIFO(MMIO) = IMP_CMD_HQ_PG_WIDTHA(tw << 2);
549 + IMP_CFIFO(MMIO) = IMP_CMD_XFRCONTROL(8);
550 + IMP_CFIFO(MMIO) = IMP_CMD_GLINE_XSTARTF(1);
551 + IMP_CFIFO(MMIO) = IMP_CMD_IR_ALIAS(0x18);
552 + IMP_CFIFO(MMIO) = IMP_CMD_HQ_DMACTRL_0(8);
553 + IMP_CFIFO(MMIO) = IMP_CMD_XFRCONTROL(9);
554 + impact_wait_dma_ready(info);
555 + IMP_CFIFO(MMIO) = IMP_CMD_GLINE_XSTARTF(0);
556 + IMP_CFIFO(MMIO) = IMP_CMD_RE_TOGGLECNTX(0);
557 + IMP_CFIFO(MMIO) = IMP_CMD_XFRCOUNTERS(0, 0);
559 + /* Setup and perform DMA from host to RE. */
560 + impact_wait_dma_done(info);
561 + IMP_CFIFO(MMIO) = IMP_CMD_CONFIG(0xca4);
562 + IMP_CFIFO(MMIO) = IMP_CMD_PP1FILLMODE(0x6200, IMP_LO_COPY);
563 + IMP_CFIFO(MMIO) = IMP_CMD_BLOCKXYSTARTI(a->dx,
564 + ((a->dy + a->height) - 1));
565 + IMP_CFIFO(MMIO) = IMP_CMD_BLOCKXYENDI(((a->dx + tw) - 1), a->dy);
566 + IMP_CFIFO(MMIO) = IMP_CMD_FILLMODE(0x01400000);
567 + IMP_CFIFO(MMIO) = IMP_CMD_XFRMODE(0x00080);
568 + IMP_CFIFO(MMIO) = IMP_CMD_HQ_PIXELFORMAT(0x600);
569 + IMP_CFIFO(MMIO) = IMP_CMD_HQ_SCANWIDTH(tw << 2);
570 + IMP_CFIFO(MMIO) = IMP_CMD_HQ_DMATYPE(0x0c);
571 + IMP_CFIFO(MMIO) = IMP_CMD_PIXCMD(3);
572 + IMP_CFIFO(MMIO) = IMP_CMD_XFRSIZE(tw, a->height);
573 + IMP_CFIFO(MMIO) = IMP_CMD_XFRCOUNTERS(tw, a->height);
574 + IMP_CFIFO(MMIO) = IMP_CMD_GLINE_XSTARTF(1);
575 + IMP_CFIFO(MMIO) = IMP_CMD_IR_ALIAS(0x18);
576 + IMP_CFIFO(MMIO) = IMP_CMD_XFRCONTROL(1);
577 + IMP_CFIFO(MMIO) = IMP_CMD_HQ_PG_LIST_0(0x80000000);
578 + IMP_CFIFO(MMIO) = IMP_CMD_HQ_PG_OFFSET(0);
579 + IMP_CFIFO(MMIO) = IMP_CMD_HQ_PG_STARTADDR(0);
580 + IMP_CFIFO(MMIO) = IMP_CMD_HQ_PG_LINECNT(a->height);
581 + IMP_CFIFO(MMIO) = IMP_CMD_HQ_PG_WIDTHA(tw << 2);
582 + IMP_CFIFO(MMIO) = IMP_CMD_HQ_DMACTRL_0(0);
583 + IMP_CFIFOW1(MMIO) = 0x000e0400;
584 + impact_wait_dma_done(info);
585 + IMP_CFIFO(MMIO) = IMP_CMD_GLINE_XSTARTF(0);
586 + IMP_CFIFO(MMIO) = IMP_CMD_RE_TOGGLECNTX(0);
587 + IMP_CFIFO(MMIO) = IMP_CMD_XFRCOUNTERS(0, 0);
589 +/* ----------------------------------------------------------------------- */
592 +/* ----------------------------------------------------------------------- */
593 +/* Accelerated functions */
595 +/**
596 + * impact_fb_fillrect - draws a rectangle.
597 + * @info: struct fb_info pointer to framebuffer data.
598 + * @r: const struct fb_fillrect pointer to rectangle fill data.
599 + */
600 +static void
601 +impact_fb_fillrect(struct fb_info *info, const struct fb_fillrect *r)
603 + struct impact_par *par = info->par;
604 + unsigned long flags;
606 + spin_lock_irqsave(&par->lock, flags);
607 + if (!par->open_flag) {
608 + switch (r->rop) {
609 + case ROP_XOR:
610 + impact_rect(info, r, IMP_LO_XOR);
611 + break;
612 + case ROP_COPY:
613 + default:
614 + impact_rect(info, r, IMP_LO_COPY);
615 + break;
618 + spin_unlock_irqrestore(&par->lock, flags);
621 +/**
622 + * impact_fb_copyarea - copy data from one area to another.
623 + * @info: struct fb_info pointer to framebuffer data.
624 + * @area: const struct fb_copyarea pointer to area data.
625 + */
626 +static void
627 +impact_fb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
629 + u32 th;
630 + struct fb_copyarea tmp, new;
631 + struct impact_par *par = info->par;
632 + unsigned long flags;
634 + if ((area->width < 1) || (area->height < 1))
635 + return;
637 + tmp.width = area->width;
638 + tmp.height = area->height;
640 + spin_lock_irqsave(&par->lock, flags);
641 + if (par->open_flag)
642 + goto out;
644 + tmp.sx = area->sx;
645 + tmp.sy = (0x3ff - ((area->sy + tmp.height) - 1));
646 + tmp.dx = area->dx;
647 + tmp.dy = (0x3ff - ((area->dy + tmp.height) - 1));
648 + th = (par->kpool_size[0] / (tmp.width * 4));
650 + IMP_CFIFO(MMIO) = IMP_CMD_XYWIN(0, 0);
651 + if (tmp.dy > tmp.sy) {
652 + tmp.dy += tmp.height;
653 + tmp.sy += tmp.height;
654 + while (tmp.height > 0) {
655 + new = tmp;
656 + new.height = ((th > tmp.height) ? tmp.height : th);
657 + new.sy -= new.height;
658 + new.dy -= new.height;
659 + impact_smallcopy(info, &new);
660 + tmp.dy -= new.height;
661 + tmp.sy -= new.height;
662 + tmp.height -= new.height;
664 + } else {
665 + while (tmp.height > 0) {
666 + new = tmp;
667 + new.height = ((th > tmp.height) ? tmp.height : th);
668 + impact_smallcopy(info, &new);
669 + tmp.dy += new.height;
670 + tmp.sy += new.height;
671 + tmp.height -= new.height;
674 + IMP_CFIFO(MMIO) = IMP_CMD_PIXCMD(0);
675 + IMP_CFIFO(MMIO) = IMP_CMD_HQ_PIXELFORMAT(0xe00);
676 + IMP_CFIFO(MMIO) = IMP_CMD_CONFIG(0xcac);
677 + IMP_CFIFO(MMIO) = IMP_CMD_XYWIN(0, 0x3ff);
679 +out:
680 + spin_unlock_irqrestore(&par->lock, flags);
683 +/**
684 + * impact_fb_imageblit_8bpp - draw 8bpp blits (?).
685 + * @info: struct fb_info pointer to framebuffer data.
686 + * @img: const struct fb_image pointer to image data.
688 + * 8-bpp blits are done as PIO draw operations; the pixels are unpacked
689 + * into 32-bpp values from the current palette in software.
690 + */
691 +static void
692 +impact_fb_imageblit_8bpp(struct fb_info *info, const struct fb_image *img)
694 + bool bit;
695 + int i, u, v;
696 + const u8 *dp;
697 + u32 pix, pal[256];
699 + /* Setup PIO to RE. */
700 + impact_wait_cfifo_empty(info);
701 + IMP_CFIFO(MMIO) = IMP_CMD_PP1FILLMODE(0x6300, IMP_LO_COPY);
702 + IMP_CFIFO(MMIO) = IMP_CMD_BLOCKXYSTARTI(img->dx, img->dy);
703 + IMP_CFIFO(MMIO) = IMP_CMD_BLOCKXYENDI(((img->dx + img->width) - 1),
704 + ((img->dy + img->height) - 1));
705 + IMP_CFIFO(MMIO) = IMP_CMD_FILLMODE(0x00c00000);
706 + IMP_CFIFO(MMIO) = IMP_CMD_XFRMODE(0x00080);
707 + IMP_CFIFO(MMIO) = IMP_CMD_XFRSIZE(img->width, img->height);
708 + IMP_CFIFO(MMIO) = IMP_CMD_XFRCOUNTERS(img->width, img->height);
709 + IMP_CFIFO(MMIO) = IMP_CMD_GLINE_XSTARTF(1);
710 + IMP_CFIFO(MMIO) = IMP_CMD_IR_ALIAS(0x18);
712 + /* XXX: Another workaround, 33 writes to alpha. */
713 + for (i = 0; i < ALPHA_WAR; i++)
714 + IMP_CFIFO(MMIO) = IMP_CMD_ALPHA(0);
715 + IMP_CFIFO(MMIO) = IMP_CMD_XFRCONTROL(2);
717 + /* Pairs of pixels are sent in two writes to the RE. */
718 + bit = false;
719 + dp = img->data;
720 + for (v = 0; v < 256; v++)
721 + pal[v] = ((u32 *)info->pseudo_palette)[v];
722 + for (v = 0; v < img->height; v++) {
723 + for (u = 0; u < img->width; u++) {
724 + pix = pal[*(dp++)];
725 + if (bit)
726 + IMP_CFIFO(MMIO) = IMP_CMD_CHAR_L(pix);
727 + else
728 + IMP_CFIFO(MMIO) = IMP_CMD_CHAR_H(pix);
729 + bit ^= true;
732 + if (bit)
733 + IMP_CFIFO(MMIO) = IMP_CMD_CHAR_L(0);
735 + IMP_CFIFO(MMIO) = IMP_CMD_GLINE_XSTARTF(0);
736 + IMP_CFIFO(MMIO) = IMP_CMD_RE_TOGGLECNTX(0);
737 + IMP_CFIFO(MMIO) = IMP_CMD_XFRCOUNTERS(0, 0);
740 +/**
741 + * impact_fb_imageblit_1bpp - draw 1bpp blits (?).
742 + * @info: struct fb_info pointer to framebuffer data.
743 + * @img: const struct fb_image pointer to image data.
745 + * 1-bpp blits are done as character drawing; the bitmaps are drawn as
746 + * 8-bit wide strips; technically, Impact supports 16-pixel wide characters,
747 + * but Linux bitmap alignment is 8 bits and most draws are 8 pixels wide
748 + * (font width), anyway.
749 + */
750 +static void
751 +impact_fb_imageblit_1bpp(struct fb_info *info, const struct fb_image *img)
753 + u32 x, y, w, h, b;
754 + int u, v, a;
755 + const u8 *d;
757 + impact_wait_cfifo_empty(info);
758 + IMP_CFIFO(MMIO) = IMP_CMD_PP1FILLMODE(0x6300, IMP_LO_COPY);
759 + IMP_CFIFO(MMIO) = IMP_CMD_FILLMODE(0x400018);
761 + a = ((u32 *)info->pseudo_palette)[img->fg_color];
762 + IMP_CFIFO(MMIO) = IMP_CMD_PACKEDCOLOR(a);
764 + a = ((u32 *)info->pseudo_palette)[img->bg_color];
765 + IMP_CFIFO(MMIO) = IMP_CMD_BKGRD_RG(a & 0xffff);
766 + IMP_CFIFO(MMIO) = IMP_CMD_BKGRD_BA((a & 0xff0000) >> 16);
768 + x = img->dx;
769 + y = img->dy;
770 + w = img->width;
771 + h = img->height;
772 + b = ((w + 7) / 8);
773 + for (u = 0; u < b; u++) {
774 + impact_wait_cfifo_empty(info);
775 + a = ((w < 8) ? w : 8);
776 + d = (img->data + u);
778 + IMP_CFIFO(MMIO) = IMP_CMD_BLOCKXYSTARTI(x, y);
779 + IMP_CFIFO(MMIO) = IMP_CMD_BLOCKXYENDI(((x + a) - 1),
780 + ((y + h) - 1));
781 + IMP_CFIFO(MMIO) = IMP_CMD_IR_ALIAS(0x18);
783 + for (v = 0; v < h; v++) {
784 + IMP_CFIFO(MMIO) = IMP_CMD_CHAR((*d) << 24);
785 + d += b;
788 + w -= a;
789 + x += a;
793 +/**
794 + * impact_fb_imageblit - draws a image to the display.
795 + * @info: struct fb_info pointer to framebuffer data.
796 + * @img: const struct fb_image pointer to image data.
797 + */
798 +static void
799 +impact_fb_imageblit(struct fb_info *info, const struct fb_image *img)
801 + struct impact_par *par = info->par;
802 + unsigned long flags;
804 + spin_lock_irqsave(&par->lock, flags);
805 + if (!par->open_flag) {
806 + switch (img->depth) {
807 + case 1:
808 + impact_fb_imageblit_1bpp(info, img);
809 + break;
810 + case 8:
811 + impact_fb_imageblit_8bpp(info, img);
812 + break;
815 + spin_unlock_irqrestore(&par->lock, flags);
818 +/**
819 + * impact_fb_sync - wait for blit idle (unimplemented).
820 + * @info: struct fb_info pointer to framebuffer data.
822 + * Returns 0.
823 + */
824 +static int
825 +impact_fb_sync(struct fb_info *info)
827 + return 0;
830 +/**
831 + * impact_fb_blank - blank the display.
832 + * @blank_mode: specifies the blanking mode.
833 + * @info: struct fb_info pointer to framebuffer data.
834 + */
835 +static int
836 +impact_fb_blank(int blank_mode, struct fb_info *info)
838 + switch (blank_mode) {
839 + case FB_BLANK_UNBLANK: /* Unblanking */
840 + IMP_REG8(MMIO, 0x61811) = 4;
841 + IMP_REG8(MMIO, 0x61910) = 0xff;
842 + IMP_REG8(MMIO, 0x60d88) = 3;
843 + break;
844 + case FB_BLANK_NORMAL: /* Normal blanking */
845 + case FB_BLANK_VSYNC_SUSPEND: /* VESA blank (vsync off) */
846 + case FB_BLANK_HSYNC_SUSPEND: /* VESA blank (hsync off) */
847 + case FB_BLANK_POWERDOWN: /* Poweroff */
848 + IMP_REG8(MMIO, 0x61811) = 4;
849 + IMP_REG8(MMIO, 0x61910) = 0;
850 + IMP_REG8(MMIO, 0x60d88) = 1;
851 + break;
854 + return 0;
857 +/**
858 + * impact_fb_setcolreg - set the specified color register.
859 + * @regno: register number.
860 + * @r: red value.
861 + * @g: green value.
862 + * @b: blue value.
863 + * @a: alpha value.
864 + * @info: struct fb_info pointer to framebuffer data.
865 + */
866 +static int
867 +impact_fb_setcolreg(u32 regno, u32 r, u32 g, u32 b, u32 a,
868 + struct fb_info *info)
870 + if (regno > 255)
871 + return 1;
873 + ((u32 *)info->pseudo_palette)[regno] =
874 + (r >> 8) | (g & 0x00ff00) | ((b << 8) & 0xff0000);
875 + return 0;
877 +/* ----------------------------------------------------------------------- */
880 +/* ----------------------------------------------------------------------- */
881 +/* Framebuffer access */
883 +/**
884 + * impact_fb_read - read from the framebuffer (unimplemented).
885 + * @info: struct fb_info pointer to framebuffer data.
886 + * @buf: s8 pointer to buffer.
887 + * @count: bytes of data to read.
888 + * @ppos: loff_t pointer to ??.
889 + */
890 +static ssize_t
891 +impact_fb_read(struct fb_info *info, char *buf, size_t count, loff_t *ppos)
893 + return -EINVAL;
896 +/**
897 + * impact_fb_write - write to the framebuffer (unimplemented).
898 + * @info: struct fb_info pointer to framebuffer data.
899 + * @buf: const s8 pointer to buffer.
900 + * @count: bytes of data to write.
901 + * @ppos: loff_t pointer to ??.
902 + */
903 +static ssize_t
904 +impact_fb_write(struct fb_info *info, const char *buf, size_t count,
905 + loff_t *ppos)
907 + return -EINVAL;
909 +/* ----------------------------------------------------------------------- */
912 +/* ----------------------------------------------------------------------- */
913 +/* Userland access */
915 +/**
916 + * impact_fb_ioctl - framebuffer ioctl() access (unimplemented).
917 + * @info: struct fb_info pointer to framebuffer data.
918 + * @cmd: ioctl command.
919 + * @arg: ioctl argument.
920 + */
921 +static int
922 +impact_fb_ioctl(struct fb_info *info, u32 cmd, unsigned long arg)
924 + return -EINVAL;
926 +/* ----------------------------------------------------------------------- */
929 +/* ----------------------------------------------------------------------- */
930 +/* Mmap/open/release. */
932 +/**
933 + * impact_fb_mmap - framebuffer ioctl() access (unimplemented).
934 + * @info: struct fb_info pointer to framebuffer data.
935 + * @vma: struct vm_area_struct pointer for virtual memory info.
936 + */
937 +static int
938 +impact_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
940 + int ret;
941 + u32 pool, i, n;
942 + unsigned long size = (vma->vm_end - vma->vm_start);
943 + unsigned long offset = (vma->vm_pgoff << PAGE_SHIFT);
944 + unsigned long start = vma->vm_start;
945 + unsigned long pfn;
946 + struct impact_par *par = info->par;
948 + switch (offset) {
949 + case 0x0000000:
950 + default:
951 + if (unlikely((offset + size) > 0x200000))
952 + return -EINVAL;
954 + if (unlikely(vma->vm_pgoff > (~0UL >> PAGE_SHIFT)))
955 + return -EINVAL;
957 + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
958 + vma->vm_flags |= VM_IO;
959 + pfn = ((par->mmio_base + offset) >> PAGE_SHIFT);
960 + ret = remap_pfn_range(vma, vma->vm_start, pfn, size,
961 + vma->vm_page_prot);
962 + if (unlikely(ret))
963 + return -EAGAIN;
964 + break;
965 + case 0x1000000:
966 + case 0x2000000:
967 + case 0x3000000:
968 + case 0x8000000:
969 + case 0x9000000:
970 + case 0xa000000:
971 + case 0xb000000:
972 + if (unlikely(size > 0x1000000))
973 + return -EINVAL;
975 + pool = ((offset >> 24) & 3);
976 + n = (((size + PAGE_SIZE) - 1) >> PAGE_SHIFT);
978 + if ((n * PAGE_SIZE) != par->kpool_size[pool])
979 + impact_resize_kpool(info, pool, size,
980 + (offset & 0x8000000));
981 + for (i = 0; i < n; i++) {
982 + pfn = (par->kpool_phys[pool][i] >> PAGE_SHIFT);
983 + ret = remap_pfn_range(vma, start, pfn, PAGE_SIZE,
984 + vma->vm_page_prot);
985 + if (unlikely(ret))
986 + return -EAGAIN;
987 + start += PAGE_SIZE;
991 + return 0;
994 +/**
995 + * impact_fb_open - framebuffer open().
996 + * @info: struct fb_info pointer to framebuffer data.
997 + * @user: flag to indicate usermode access.
998 + */
999 +static int
1000 +impact_fb_open(struct fb_info *info, int user)
1002 + struct impact_par *par = info->par;
1003 + unsigned long flags;
1005 + spin_lock_irqsave(&par->lock, flags);
1006 + if (user)
1007 + par->open_flag++;
1008 + spin_unlock_irqrestore(&par->lock, flags);
1010 + return 0;
1013 +/**
1014 + * impact_fb_release - framebuffer release().
1015 + * @info: struct fb_info pointer to framebuffer data.
1016 + * @user: flag to indicate usermode access.
1017 + */
1018 +static int
1019 +impact_fb_release(struct fb_info *info, int user)
1021 + struct impact_par *par = info->par;
1022 + unsigned long flags;
1024 + spin_lock_irqsave(&par->lock, flags);
1025 + if (user && par->open_flag)
1026 + par->open_flag--;
1027 + spin_unlock_irqrestore(&par->lock, flags);
1029 + return 0;
1031 +/* ----------------------------------------------------------------------- */
1034 +/* ----------------------------------------------------------------------- */
1035 +/* Impact framebuffer operations */
1037 +static struct
1038 +fb_ops impact_ops = {
1039 + .owner = THIS_MODULE,
1040 + .fb_read = impact_fb_read,
1041 + .fb_write = impact_fb_write,
1042 + .fb_blank = impact_fb_blank,
1043 + .fb_fillrect = impact_fb_fillrect,
1044 + .fb_copyarea = impact_fb_copyarea,
1045 + .fb_imageblit = impact_fb_imageblit,
1046 + .fb_sync = impact_fb_sync,
1047 + .fb_ioctl = impact_fb_ioctl,
1048 + .fb_setcolreg = impact_fb_setcolreg,
1049 + .fb_mmap = impact_fb_mmap,
1050 + .fb_open = impact_fb_open,
1051 + .fb_release = impact_fb_release,
1053 +/* ----------------------------------------------------------------------- */
1056 +/* ----------------------------------------------------------------------- */
1057 +/* Hardware initialization */
1059 +/**
1060 + * impact_inithq - init impact HQ3/4.
1061 + * @info: struct fb_info pointer to framebuffer data.
1062 + */
1063 +static inline void __init
1064 +impact_inithq(struct fb_info *info)
1066 + /* Not really needed, the friendly PROM did this already for us... */
1067 + /* CFIFO parameters */
1068 + IMP_CFIFO_HW(MMIO) = VAL_CFIFO_HW;
1069 + IMP_CFIFO_LW(MMIO) = VAL_CFIFO_LW;
1070 + IMP_CFIFO_DELAY(MMIO) = VAL_CFIFO_DELAY;
1072 + /* DFIFO parameters */
1073 + IMP_DFIFO_HW(MMIO) = VAL_DFIFO_HW;
1074 + IMP_DFIFO_LW(MMIO) = VAL_DFIFO_LW;
1075 + IMP_DFIFO_DELAY(MMIO) = VAL_DFIFO_DELAY;
1078 +/**
1079 + * impact_initrss - init impact RSS.
1080 + * @info: struct fb_info pointer to framebuffer data.
1081 + */
1082 +static inline void __init
1083 +impact_initrss(struct fb_info *info)
1085 + /* Transfer mask registers. */
1086 + IMP_CFIFO(MMIO) = IMP_CMD_COLORMASKLSBSA(0xffffff);
1087 + IMP_CFIFO(MMIO) = IMP_CMD_COLORMASKLSBSB(0xffffff);
1088 + IMP_CFIFO(MMIO) = IMP_CMD_COLORMASKMSBS(0);
1089 + IMP_CFIFO(MMIO) = IMP_CMD_XFRMASKLO(0xffffff);
1090 + IMP_CFIFO(MMIO) = IMP_CMD_XFRMASKHI(0xffffff);
1092 + /* Use the main plane. */
1093 + IMP_CFIFO(MMIO) = IMP_CMD_DRBPOINTERS(0xc8240);
1095 + /* Set the RE into vertical flip mode. */
1096 + IMP_CFIFO(MMIO) = IMP_CMD_CONFIG(0xcac);
1097 + IMP_CFIFO(MMIO) = IMP_CMD_XYWIN(0, 0x3ff);
1100 +/**
1101 + * impact_initxmap - init impact XMAP.
1102 + * @info: struct fb_info pointer to framebuffer data.
1103 + */
1104 +static inline void __init
1105 +impact_initxmap(struct fb_info *info)
1107 + /* Set XMAP into 24-bpp mode. */
1108 + IMP_XMAP_PP1SELECT(MMIO) = 0x01;
1109 + IMP_XMAP_INDEX(MMIO) = 0x00;
1110 + IMP_XMAP_MAIN_MODE(MMIO) = 0x07a4;
1113 +/**
1114 + * impact_initvc3 - init impact VC3.
1115 + * @info: struct fb_info pointer to framebuffer data.
1116 + */
1117 +static inline void __init
1118 +impact_initvc3(struct fb_info *info)
1120 + /* Cursor Begone! (disable DISPLAY bit) */
1121 + IMP_VC3_INDEXDATA(MMIO) = 0x1d000100;
1124 +/**
1125 + * impact_hw_init - init impact hardware.
1126 + * @info: struct fb_info pointer to framebuffer data.
1127 + */
1128 +static inline void __init
1129 +impact_hw_init(struct fb_info *info)
1131 + /* initialize hardware */
1132 + impact_inithq(info);
1133 + impact_initvc3(info);
1134 + impact_initrss(info);
1135 + impact_initxmap(info);
1136 + impact_initdma(info);
1138 +/* ----------------------------------------------------------------------- */
1141 +/* ----------------------------------------------------------------------- */
1142 +/* XIO/GIO Probing - a bit ugly... */
1144 +/**
1145 + * impact_common_probe - probe code common to both XIO/GIO buses.
1146 + * @info: struct fb_info pointer to framebuffer data.
1147 + * @par: struct impact_par pointer to impact data.
1148 + */
1149 +static int
1150 +impact_common_probe(struct fb_info *info, struct impact_par *par)
1152 + int i, ret;
1154 + /* Set defaults. */
1155 + info->screen_base = NULL;
1156 + info->fbops = &impact_ops;
1157 + info->var = impact_var_default;
1158 + info->fix = impact_fix_default;
1159 + info->flags = (FBINFO_DEFAULT |
1160 + FBINFO_HWACCEL_COPYAREA |
1161 + FBINFO_HWACCEL_FILLRECT |
1162 + FBINFO_HWACCEL_IMAGEBLIT);
1163 + info->pseudo_palette = par->pseudo_palette;
1164 + info->fix.mmio_start = par->mmio_base;
1165 + info->fix.mmio_len = 0x200000;
1167 + /* Get board config. */
1168 + par->num_ge = IMP_BDVERS1(par->mmio_virt) & 3;
1169 + par->num_rss = par->num_ge;
1170 + info->fix.id[9] = '0' + par->num_rss;
1172 + /* Init hardware. */
1173 + impact_hw_init(info);
1175 + /* Initialize kpools. */
1176 + impact_resize_kpool(info, 0, 65536, false);
1177 + for (i = 1; i < USE_POOLS; ++i)
1178 + impact_resize_kpool(info, i, 8192, false);
1180 + /* Alloc cmap. */
1181 + ret = fb_alloc_cmap(&info->cmap, 256, 0);
1182 + if (ret)
1183 + goto err_alloc_cmap;
1185 + /* Register framebuffer. */
1186 + ret = register_framebuffer(info);
1187 + if (ret)
1188 + goto err_reg_fb;
1190 + pr_info("fb%d: %s frame buffer device\n", info->node, info->fix.id);
1191 + return 0;
1193 +err_reg_fb:
1194 + fb_dealloc_cmap(&info->cmap);
1195 +err_alloc_cmap:
1196 + framebuffer_release(info);
1197 + return ret;
1200 +#ifndef SGI_INDIGO2
1201 +/**
1202 + * impact_xio_probe - probe for impact card on XIO bus.
1203 + * @dev: struct platform_device pointer to device information.
1204 + */
1205 +static int
1206 +impact_xio_probe(struct platform_device *dev)
1208 + int ret;
1209 + struct fb_info *info = NULL;
1210 + struct impact_par *par = NULL;
1212 + info = framebuffer_alloc(sizeof(struct impact_par), &dev->dev);
1213 + if (!info)
1214 + return -ENOMEM;
1216 + par = info->par;
1217 + par->dev = &dev->dev;
1218 + par->dev->coherent_dma_mask = ~0;
1219 + par->open_flag = 0;
1220 + spin_lock_init(&par->lock);
1222 + par->mmio_base = xtalk_get_swin(0, dev->id);
1223 + par->mmio_virt = ioremap_nocache(par->mmio_base, 0x200000);
1225 + ret = impact_common_probe(info, par);
1226 + platform_set_drvdata(dev, info);
1228 + return ret;
1231 +static struct platform_driver
1232 +impact_driver = {
1233 + .probe = impact_xio_probe,
1234 + /* add remove someday */
1235 + .driver = {
1236 + .name = "impact",
1237 + },
1240 +static int __init
1241 +impact_init(void)
1243 + return platform_driver_register(&impact_driver);
1246 +static void __exit
1247 +impact_exit(void)
1249 + platform_driver_unregister(&impact_driver);
1252 +MODULE_ALIAS("platform:impact");
1254 +#else /* SGI_INDIGO2 */
1256 +/**
1257 + * impact_gio_probe - probe for impact card on GIO bus.
1258 + * @dev: struct gio_device pointer to device information.
1259 + * @id: const struct gio_device_id pointer to GIO dev id.
1260 + */
1261 +static int
1262 +impact_gio_probe(struct gio_device *dev, const struct gio_device_id *id)
1264 + int ret;
1265 + struct fb_info *info;
1266 + struct impact_par *par;
1268 + if (!dev->resource.start)
1269 + return -EINVAL;
1271 + if (!request_mem_region(dev->resource.start, 0x200000, "Impact"))
1272 + return -ENODEV;
1274 + info = framebuffer_alloc(sizeof(struct impact_par), &dev->dev);
1275 + if (!info)
1276 + return -ENOMEM;
1278 + par = info->par;
1279 + par->dev = &dev->dev;
1280 + par->dev->coherent_dma_mask = ~0;
1281 + par->open_flag = 0;
1282 + spin_lock_init(&par->lock);
1284 + par->mmio_base = dev->resource.start;
1285 + par->mmio_virt = ioremap(par->mmio_base, 0x200000);
1286 + gio_set_master(dev);
1288 + ret = impact_common_probe(info, par);
1290 + return ret;
1293 +static struct gio_device_id
1294 +impact_ids[] = {
1295 + { .id = 0x10 },
1296 + { .id = 0xff }
1299 +static struct gio_driver
1300 +impact_driver = {
1301 + .name = "impact",
1302 + .id_table = impact_ids,
1303 + .probe = impact_gio_probe,
1304 + /* add remove someday */
1307 +static int __init
1308 +impact_init(void)
1310 + return gio_register_driver(&impact_driver);
1313 +static void __exit
1314 +impact_exit(void)
1316 + gio_unregister_driver(&impact_driver);
1319 +MODULE_ALIAS("gio:impact");
1321 +#endif /* SGI_INDIGO2 */
1322 +/* ----------------------------------------------------------------------- */
1325 +module_init(impact_init);
1326 +module_exit(impact_exit);
1328 +MODULE_AUTHOR("Stanislaw Skowronek <skylark@unaligned.org>");
1329 +MODULE_AUTHOR("Johannes Dickgreber <tanzy@gmx.de>");
1330 +MODULE_AUTHOR("Joshua Kinard <kumba@gentoo.org>");
1331 +MODULE_DESCRIPTION("SGI Impact/MardiGras Video Driver");
1332 +MODULE_LICENSE("GPL");
1333 +MODULE_VERSION("0.42.3");
1334 diff --git a/include/uapi/linux/fb.h b/include/uapi/linux/fb.h
1335 index 6cd9b198b7c6..2ebb46eaccfd 100644
1336 --- a/include/uapi/linux/fb.h
1337 +++ b/include/uapi/linux/fb.h
1338 @@ -133,6 +133,7 @@
1339 #define FB_ACCEL_NEOMAGIC_NM2360 97 /* NeoMagic NM2360 */
1340 #define FB_ACCEL_NEOMAGIC_NM2380 98 /* NeoMagic NM2380 */
1341 #define FB_ACCEL_PXA3XX 99 /* PXA3xx */
1342 +#define FB_ACCEL_SGI_IMPACT 666 /* SGI Impact (MGRAS) */
1344 #define FB_ACCEL_SAVAGE4 0x80 /* S3 Savage4 */
1345 #define FB_ACCEL_SAVAGE3D 0x81 /* S3 Savage3D */
1346 diff --git a/include/video/impact.h b/include/video/impact.h
1347 new file mode 100644
1348 index 000000000000..2efa228fc6d9
1349 --- /dev/null
1350 +++ b/include/video/impact.h
1351 @@ -0,0 +1,337 @@
1353 + * linux/drivers/video/impact.h
1354 + * SGI Octane MardiGras (IMPACTSR) graphics
1355 + * SGI Indigo2 MardiGras (IMPACT) graphics
1357 + * Copyright (c)
1358 + * 2004-2006 by Stanislaw Skowronek <skylark@unaligned.org> (author)
1359 + * 2005 by Peter Fuerst <post@pfrst.de> (Indigo2 adaptation)
1360 + * 2007-2009 by Johannes Dickgreber <tanzy@gmx.de> (platform_driver)
1361 + * 2014 by Thomas Bogendoerfer <tsbogend@alpha.franken.de> (gio_driver)
1362 + * 2011-2015 by Joshua Kinard <kumba@gentoo.org> (upkeeping/maintenance)
1364 + * This file is subject to the terms and conditions of the GNU General Public
1365 + * License. See the file COPYING in the main directory of this archive for
1366 + * more details.
1367 + */
1369 +#ifndef _IMPACT_H
1370 +#define _IMPACT_H
1372 +/* IP22/IP28 have HQ3, IP30 has HQ4. */
1373 +#if defined(CONFIG_SGI_IP22) || defined(CONFIG_SGI_IP28)
1374 +#define SGI_INDIGO2 1
1375 +#else
1376 +#undef SGI_INDIGO2
1377 +#endif
1379 +/* Some fixed register values. */
1380 +#ifndef SGI_INDIGO2
1381 + /* ImpactSR (HQ4) registers */
1382 + #define VAL_CFIFO_HW 0x47
1383 + #define VAL_CFIFO_LW 0x14
1384 + #define VAL_CFIFO_DELAY 0x64
1385 + #define VAL_DFIFO_HW 0x40
1386 + #define VAL_DFIFO_LW 0x10
1387 + #define VAL_DFIFO_DELAY 0
1388 + #define MSK_CFIFO_CNT 0xff
1389 + #define USEPOOLS 5
1390 + #define MMIO_FIXED 0x900000001c000000
1391 +#else
1392 + /* Impact (HQ3) registers */
1393 + #define VAL_CFIFO_HW 0x20 /* 0x18 ? */
1394 + #define VAL_CFIFO_LW 0x14
1395 + #define VAL_CFIFO_DELAY 0x64
1396 + #define VAL_DFIFO_HW 0x28
1397 + #define VAL_DFIFO_LW 0x14
1398 + #define VAL_DFIFO_DELAY 0xfff
1399 + #define MSK_CFIFO_CNT 0x7f
1400 + #define USEPOOLS 4
1401 + #define MMIO_FIXED 0x900000001f000000
1402 +#endif
1404 +/* Convenient access macros */
1405 +#define IMP_REG64(vma, off) (*(volatile u64 *)((vma) + (off)))
1406 +#define IMP_REG32(vma, off) (*(volatile u32 *)((vma) + (off)))
1407 +#define IMP_REG16(vma, off) (*(volatile u16 *)((vma) + (off)))
1408 +#define IMP_REG8(vma, off) (*(volatile u8 *)((vma) + (off)))
1410 +#ifndef SGI_INDIGO2
1411 + /* ImpactSR (HQ4) register offsets */
1412 + #define IMP_CFIFO(vma) IMP_REG64(vma, 0x020400)
1413 + #define IMP_CFIFOW(vma) IMP_REG32(vma, 0x020400)
1414 + #define IMP_CFIFOW1(vma) IMP_REG32(vma, 0x020404)
1415 + #define IMP_CFIFOP(vma) IMP_REG64(vma, 0x130400)
1416 + #define IMP_CFIFOPW(vma) IMP_REG32(vma, 0x130400)
1417 + #define IMP_CFIFOPW1(vma) IMP_REG32(vma, 0x130404)
1419 + #define IMP_STATUS(vma) IMP_REG32(vma, 0x020000)
1420 + #define IMP_FIFOSTATUS(vma) IMP_REG32(vma, 0x020008)
1421 + #define IMP_GIOSTATUS(vma) IMP_REG32(vma, 0x020100)
1422 + #define IMP_DMABUSY(vma) IMP_REG32(vma, 0x020200)
1424 + #define IMP_CFIFO_HW(vma) IMP_REG32(vma, 0x040000)
1425 + #define IMP_CFIFO_LW(vma) IMP_REG32(vma, 0x040008)
1426 + #define IMP_CFIFO_DELAY(vma) IMP_REG32(vma, 0x040010)
1427 + #define IMP_DFIFO_HW(vma) IMP_REG32(vma, 0x040020)
1428 + #define IMP_DFIFO_LW(vma) IMP_REG32(vma, 0x040028)
1429 + #define IMP_DFIFO_DELAY(vma) IMP_REG32(vma, 0x040030)
1431 + #define IMP_XMAP_OFF(off) (0x71c00 + (off))
1432 + #define IMP_VC3_OFF(off) (0x72000 + (off))
1433 + #define IMP_RSS_OFF(off) (0x2c000 + (off))
1434 +#else
1435 + /* Impact (HQ3) register offsets */
1436 + #define IMP_CFIFO(vma) IMP_REG64(vma, 0x070080)
1437 + #define IMP_CFIFOW(vma) IMP_REG32(vma, 0x070080)
1438 + #define IMP_CFIFOW1(vma) IMP_REG32(vma, 0x070084)
1439 + #define IMP_CFIFOP(vma) IMP_REG64(vma, 0x050080)
1440 + #define IMP_CFIFOPW(vma) IMP_REG32(vma, 0x050080)
1441 + #define IMP_CFIFOPW1(vma) IMP_REG32(vma, 0x050084)
1443 + #define IMP_STATUS(vma) IMP_REG32(vma, 0x070000)
1444 + #define IMP_FIFOSTATUS(vma) IMP_REG32(vma, 0x070004)
1445 + #define IMP_GIOSTATUS(vma) IMP_REG32(vma, 0x070100)
1446 + #define IMP_DMABUSY(vma) IMP_REG32(vma, 0x070104)
1448 + #define IMP_CFIFO_HW(vma) IMP_REG32(vma, 0x050020)
1449 + #define IMP_CFIFO_LW(vma) IMP_REG32(vma, 0x050024)
1450 + #define IMP_CFIFO_DELAY(vma) IMP_REG32(vma, 0x050028)
1451 + #define IMP_DFIFO_HW(vma) IMP_REG32(vma, 0x05002c)
1452 + #define IMP_DFIFO_LW(vma) IMP_REG32(vma, 0x050030)
1453 + #define IMP_DFIFO_DELAY(vma) IMP_REG32(vma, 0x050034)
1455 + #define IMP_XMAP_OFF(off) (0x61c00 + (off))
1456 + #define IMP_VC3_OFF(off) (0x62000 + (off))
1457 + #define IMP_RSS_OFF(off) (0x7c000 + (off))
1458 +#endif
1460 +#define IMP_RESTATUS(vma) IMP_REG32(vma, IMP_RSS_OFF(0x578))
1462 +#define IMP_XMAP_PP1SELECT(vma) IMP_REG8(vma, IMP_XMAP_OFF(0x008))
1463 +#define IMP_XMAP_INDEX(vma) IMP_REG8(vma, IMP_XMAP_OFF(0x088))
1464 +#define IMP_XMAP_CONFIG(vma) IMP_REG32(vma, IMP_XMAP_OFF(0x100))
1465 +#define IMP_XMAP_CONFIGB(vma) IMP_REG8(vma, IMP_XMAP_OFF(0x108))
1466 +#define IMP_XMAP_BUF_SELECT(vma) IMP_REG32(vma, IMP_XMAP_OFF(0x180))
1467 +#define IMP_XMAP_MAIN_MODE(vma) IMP_REG32(vma, IMP_XMAP_OFF(0x200))
1468 +#define IMP_XMAP_OVERLAY_MODE(vma) IMP_REG32(vma, IMP_XMAP_OFF(0x280))
1469 +#define IMP_XMAP_DIB(vma) IMP_REG32(vma, IMP_XMAP_OFF(0x300))
1470 +#define IMP_XMAP_DIB_DW(vma) IMP_REG32(vma, IMP_XMAP_OFF(0x340))
1471 +#define IMP_XMAP_RE_RAC(vma) IMP_REG32(vma, IMP_XMAP_OFF(0x380))
1473 +#define IMP_VC3_INDEX(vma) IMP_REG8(vma, IMP_VC3_OFF(0x008))
1474 +#define IMP_VC3_INDEXDATA(vma) IMP_REG32(vma, IMP_VC3_OFF(0x038))
1475 +#define IMP_VC3_DATA(vma) IMP_REG16(vma, IMP_VC3_OFF(0x0b0))
1476 +#define IMP_VC3_RAM(vma) IMP_REG16(vma, IMP_VC3_OFF(0x190))
1478 +#define IMP_BDVERS0(vma) IMP_REG8(vma, IMP_VC3_OFF(0x408))
1479 +#define IMP_BDVERS1(vma) IMP_REG8(vma, IMP_VC3_OFF(0x488))
1482 +/* FIFO status */
1483 +#ifdef SGI_INDIGO2
1484 + #define IMP_CFIFO_MAX 64
1485 +#else
1486 + #define IMP_CFIFO_MAX 128
1487 +#endif
1488 +#define IMP_BFIFO_MAX 16
1491 +/* Commands for CFIFO */
1492 +#define IMP_CMD_WRITERSS(reg, val) \
1493 + (((0x00180004L | ((reg) << 8)) << 32) | ((u32)(val) & 0xffffffff))
1495 +#define IMP_CMD_EXECRSS(reg, val) \
1496 + (((0x001c0004L | ((reg) << 8)) << 32) | ((u32)(val) & 0xffffffff))
1498 +#define IMP_CMD_GLINE_XSTARTF(v) IMP_CMD_WRITERSS(0x00c, v)
1499 +#define IMP_CMD_IR_ALIAS(v) IMP_CMD_EXECRSS(0x045, v)
1500 +#define IMP_CMD_BLOCKXYSTARTI(x, y) IMP_CMD_WRITERSS(0x046, ((x) << 16) | (y))
1501 +#define IMP_CMD_BLOCKXYENDI(x, y) IMP_CMD_WRITERSS(0x047, ((x) << 16) | (y))
1502 +#define IMP_CMD_PACKEDCOLOR(v) IMP_CMD_WRITERSS(0x05b, v)
1503 +#define IMP_CMD_RED(v) IMP_CMD_WRITERSS(0x05c, v)
1504 +#define IMP_CMD_ALPHA(v) IMP_CMD_WRITERSS(0x05f, v)
1505 +#define IMP_CMD_CHAR(v) IMP_CMD_EXECRSS(0x070, v)
1506 +#define IMP_CMD_CHAR_H(v) IMP_CMD_WRITERSS(0x070, v)
1507 +#define IMP_CMD_CHAR_L(v) IMP_CMD_EXECRSS(0x071, v)
1508 +#define IMP_CMD_XFRCONTROL(v) IMP_CMD_WRITERSS(0x102, v)
1509 +#define IMP_CMD_FILLMODE(v) IMP_CMD_WRITERSS(0x110, v)
1510 +#define IMP_CMD_CONFIG(v) IMP_CMD_WRITERSS(0x112, v)
1511 +#define IMP_CMD_XYWIN(x, y) IMP_CMD_WRITERSS(0x115, ((y) << 16) | (x))
1512 +#define IMP_CMD_BKGRD_RG(v) IMP_CMD_WRITERSS(0x140, ((v) << 8))
1513 +#define IMP_CMD_BKGRD_BA(v) IMP_CMD_WRITERSS(0x141, ((v) << 8))
1514 +#define IMP_CMD_WINMODE(v) IMP_CMD_WRITERSS(0x14f, v)
1515 +#define IMP_CMD_XFRSIZE(x, y) IMP_CMD_WRITERSS(0x153, ((y) << 16) | (x))
1516 +#define IMP_CMD_XFRMASKLO(v) IMP_CMD_WRITERSS(0x156, v)
1517 +#define IMP_CMD_XFRMASKHI(v) IMP_CMD_WRITERSS(0x157, v)
1518 +#define IMP_CMD_XFRCOUNTERS(x, y) IMP_CMD_WRITERSS(0x158, ((y) << 16) | (x))
1519 +#define IMP_CMD_XFRMODE(v) IMP_CMD_WRITERSS(0x159, v)
1520 +#define IMP_CMD_RE_TOGGLECNTX(v) IMP_CMD_WRITERSS(0x15f, v)
1521 +#define IMP_CMD_PIXCMD(v) IMP_CMD_WRITERSS(0x160, v)
1522 +#define IMP_CMD_PP1FILLMODE(m, o) IMP_CMD_WRITERSS(0x161, (m) | (o << 26))
1523 +#define IMP_CMD_COLORMASKMSBS(v) IMP_CMD_WRITERSS(0x162, v)
1524 +#define IMP_CMD_COLORMASKLSBSA(v) IMP_CMD_WRITERSS(0x163, v)
1525 +#define IMP_CMD_COLORMASKLSBSB(v) IMP_CMD_WRITERSS(0x164, v)
1526 +#define IMP_CMD_BLENDFACTOR(v) IMP_CMD_WRITERSS(0x165, v)
1527 +#define IMP_CMD_DRBPOINTERS(v) IMP_CMD_WRITERSS(0x16d, v)
1529 +#define IMP_UNSIGNED(v) ((unsigned)(v) & 0xffffffff)
1531 +#define IMP_CMD_HQ_PIXELFORMAT(v) (0x000c000400000000L | IMP_UNSIGNED(v))
1532 +#define IMP_CMD_HQ_SCANWIDTH(v) (0x000a020400000000L | IMP_UNSIGNED(v))
1533 +#define IMP_CMD_HQ_DMATYPE(v) (0x000a060400000000L | IMP_UNSIGNED(v))
1534 +#define IMP_CMD_HQ_PG_LIST_0(v) (0x0008000400000000L | IMP_UNSIGNED(v))
1535 +#define IMP_CMD_HQ_PG_WIDTH(v) (0x0008040400000000L | IMP_UNSIGNED(v))
1536 +#define IMP_CMD_HQ_PG_OFFSET(v) (0x0008050400000000L | IMP_UNSIGNED(v))
1537 +#define IMP_CMD_HQ_PG_STARTADDR(v) (0x0008060400000000L | IMP_UNSIGNED(v))
1538 +#define IMP_CMD_HQ_PG_LINECNT(v) (0x0008070400000000L | IMP_UNSIGNED(v))
1539 +#define IMP_CMD_HQ_PG_WIDTHA(v) (0x0008080400000000L | IMP_UNSIGNED(v))
1540 +#define IMP_CMD_HQ_PGSIZE(v) (0x00482a0400000000L | IMP_UNSIGNED(v))
1541 +#define IMP_CMD_HQ_STACKPTR(v) (0x00483a0400000000L | IMP_UNSIGNED(v))
1542 +#define IMP_CMD_HQ_TXBASE(p) (0x00482008 | ((p) << 9))
1544 +#define IMP_CMD_HQ_DMACTRL_0(v) (0x00080b04000000b1L | ((v) & 8))
1546 +#define IMP_CMD_HQ_TXMAX(p, v) \
1547 + (0x0048300400000000L | IMP_UNSIGNED(v) | \
1548 + ((unsigned long)(p) << 40))
1550 +#define IMP_CMD_HQ_PGBITS(p, v) \
1551 + (0x00482b0400000000L | IMP_UNSIGNED(v) | \
1552 + ((unsigned long)(p) << 40))
1554 +#define IMP_CMD_HQ_484A(p, v) \
1555 + ((0x00484a0400000000L + ((unsigned long)(p) << 40)) | \
1556 + IMP_UNSIGNED(v))
1558 +#define IMP_CMD_HQ_484B(p, v) \
1559 + ((0x00484b0400000000L + ((unsigned long)(p) << 40)) | \
1560 + IMP_UNSIGNED(v))
1563 + * Logic operations for the PP1:
1564 + * - SI = source invert
1565 + * - DI = dest invert
1566 + * - RI = result invert
1567 + */
1568 +#define IMP_LO_AND 0x01
1569 +#define IMP_LO_SI_AND 0x04
1570 +#define IMP_LO_DI_AND 0x02
1571 +#define IMP_LO_RI_AND 0x0e
1573 +#define IMP_LO_OR 0x07
1574 +#define IMP_LO_SI_OR 0x0d
1575 +#define IMP_LO_DI_OR 0x0b
1576 +#define IMP_LO_RI_OR 0x08
1578 +#define IMP_LO_XOR 0x06
1579 +#define IMP_LO_RI_XOR 0x09
1581 +#define IMP_LO_NOP 0x05
1582 +#define IMP_LO_RI_NOP 0x0a
1584 +#define IMP_LO_COPY 0x03
1585 +#define IMP_LO_RI_COPY 0x0c
1587 +#define IMP_LO_CLEAR 0x00
1588 +#define IMP_LO_SET 0x0f
1590 +/* Blending factors */
1591 +#define IMP_BLEND_ALPHA 0x0704c900
1596 + * For the future. These will replace the above
1597 + * macros to make the code look more C-like.
1598 + */
1600 +static inline void ImpactCFifoCmd64(unsigned long vma, unsigned cmd,
1601 + unsigned reg, unsigned val)
1603 +// #if (_MIPS_SZLONG == 64) see Xmd.h
1604 +#if 1
1605 + IMP_CFIFO(vma) = (unsigned long long)(cmd | reg << 8) << 32 | val;
1606 +#else
1607 + IMP_CFIFOW(vma) = cmd | reg << 8;
1608 + IMP_CFIFOW(vma) = val;
1609 +#endif
1612 +static inline void ImpactCFifoPCmd32(unsigned long vma, unsigned cmd,
1613 + unsigned reg)
1615 + IMP_CFIFOPW(vma) = cmd | reg << 8;
1618 +static inline void ImpactCFifoPCmd32lo(unsigned long vma, unsigned cmd,
1619 + unsigned reg)
1621 + IMP_CFIFOPW1(vma) = cmd | reg << 8;
1624 +static inline void ImpactCmdWriteRss(unsigned long vma, unsigned reg,
1625 + unsigned val)
1627 + ImpactCFifoCmd64(vma, 0x00180004, reg, val);
1630 +static inline void ImpactCmdExecRss(unsigned long vma, unsigned reg,
1631 + unsigned val)
1633 + ImpactCFifoCmd64(vma, 0x001c0004, reg, val);
1636 +#define impact_cmd_gline_xstartf(a, v) ImpactCmdWriteRss(a, 0x000c, v)
1637 +#define impact_cmd_ir_alias(a, v) ImpactCmdExecRss(a, 0x0045, v)
1638 +#define impact_cmd_blockxystarti(a, x, y) ImpactCmdWriteRss(a, 0x0046, (x) << 16 | (y))
1639 +#define impact_cmd_blockxyendi(a, x, y) ImpactCmdWriteRss(a, 0x0047, (x) << 16 | (y))
1640 +#define impact_cmd_packedcolor(a, v) ImpactCmdWriteRss(a, 0x005b, v)
1641 +#define impact_cmd_red(a, v) ImpactCmdWriteRss(a, 0x005c, v)
1642 +#define impact_cmd_alpha(a, v) ImpactCmdWriteRss(a, 0x005f, v)
1643 +#define impact_cmd_char(a, v) ImpactCmdExecRss(a, 0x0070, v)
1644 +#define impact_cmd_char_h(a, v) ImpactCmdWriteRss(a, 0x0070, v)
1645 +#define impact_cmd_char_l(a, v) ImpactCmdExecRss(a, 0x0071, v)
1646 +#define impact_cmd_xfrcontrol(a, v) ImpactCmdWriteRss(a, 0x0102, v)
1647 +#define impact_cmd_fillmode(a, v) ImpactCmdWriteRss(a, 0x0110, v)
1648 +#define impact_cmd_config(a, v) ImpactCmdWriteRss(a, 0x0112, v)
1649 +#define impact_cmd_xywin(a, x, y) ImpactCmdWriteRss(a, 0x0115, (y) << 16 | (x))
1650 +#define impact_cmd_bkgrd_rg(a, v) ImpactCmdWriteRss(a, 0x0140, (v) << 8)
1651 +#define impact_cmd_bkgrd_ba(a, v) ImpactCmdWriteRss(a, 0x0141, (v) << 8)
1652 +#define impact_cmd_winmode(a, v) ImpactCmdWriteRss(a, 0x014f, v)
1653 +#define impact_cmd_xfrsize(a, x, y) ImpactCmdWriteRss(a, 0x0153, (y) << 16 | (x))
1654 +#define impact_cmd_xfrmasklo(a, v) ImpactCmdWriteRss(a, 0x0156, v)
1655 +#define impact_cmd_xfrmaskhi(a, v) ImpactCmdWriteRss(a, 0x0157, v)
1656 +#define impact_cmd_xfrcounters(a, x, y) ImpactCmdWriteRss(a, 0x0158, (y) << 16 | (x))
1657 +#define impact_cmd_xfrmode(a, v) ImpactCmdWriteRss(a, 0x0159, v)
1658 +#define impact_cmd_re_togglecntx(a, v) ImpactCmdWriteRss(a, 0x015f, v)
1659 +#define impact_cmd_pixcmd(a, v) ImpactCmdWriteRss(a, 0x0160, v)
1660 +#define impact_cmd_pp1fillmode(a, m, o) ImpactCmdWriteRss(a, 0x0161, (m) | (o) << 26)
1661 +#define impact_cmd_colormaskmsbs(a, v) ImpactCmdWriteRss(a, 0x0162, v)
1662 +#define impact_cmd_colormasklsbsa(a, v) ImpactCmdWriteRss(a, 0x0163, v)
1663 +#define impact_cmd_colormasklsbsb(a, v) ImpactCmdWriteRss(a, 0x0164, v)
1664 +#define impact_cmd_blendfactor(a, v) ImpactCmdWriteRss(a, 0x0165, v)
1665 +#define impact_cmd_drbpointers(a, v) ImpactCmdWriteRss(a, 0x016d, v)
1667 +#define impact_cmd_hq_pixelformat(a, v) ImpactCFifoCmd64(a, 0x000c0004, 0, v)
1668 +#define impact_cmd_hq_scanwidth(a, v) ImpactCFifoCmd64(a, 0x000a0204, 0, v)
1669 +#define impact_cmd_hq_dmatype(a, v) ImpactCFifoCmd64(a, 0x000a0604, 0, v)
1670 +#define impact_cmd_hq_pg_list_0(a, v) ImpactCFifoCmd64(a, 0x00080004, 0, v)
1671 +#define impact_cmd_hq_pg_width(a, v) ImpactCFifoCmd64(a, 0x00080404, 0, v)
1672 +#define impact_cmd_hq_pg_offset(a, v) ImpactCFifoCmd64(a, 0x00080504, 0, v)
1673 +#define impact_cmd_hq_pg_startaddr(a, v) ImpactCFifoCmd64(a, 0x00080604, 0, v)
1674 +#define impact_cmd_hq_pg_linecnt(a, v) ImpactCFifoCmd64(a, 0x00080704, 0, v)
1675 +#define impact_cmd_hq_pg_widtha(a, v) ImpactCFifoCmd64(a, 0x00080804, 0, v)
1676 +#define impact_cmd_hq_dmactrl_0(a, v) ImpactCFifoCmd64(a, 0x00080b04, 0, 0xb1 | (v) & 8)
1678 +#define impact_cmd_hq_txbase(a, p) ImpactCFifoPCmd32lo(a, (0x00482008 | (p) << 9), 0)
1679 +#define impact_cmd_hq_txmax(a, p, v) ImpactCFifoPCmd64(a, (0x00483004 | (p) << 8), 0, v)
1680 +#define impact_cmd_hq_pgbits(a, p, v) ImpactCFifoPCmd64(a, (0x00482b04 + ((p) << 8)), 0, v)
1681 +#define impact_cmd_hq_pgsize(a, v) ImpactCFifoPCmd64(a, 0x00482a04, 0, v)
1682 +#define impact_cmd_hq_stackptr(a, v) ImpactCFifoPCmd64(a, 0x00483a04, 0, v)
1684 +#define impact_cmd_hq_484A(a, p, v) ImpactCFifoPCmd64(a, (0x00484a04 + ((p) << 8)), 0, v)
1685 +#define impact_cmd_hq_484B(a, p, v) ImpactCFifoPCmd64(a, (0x00484b04 + ((p) << 8)), 0, v)
1688 +#endif /* _IMPACT_H */