patch-2.1.53 linux/drivers/sbus/char/creator.c
Next file: linux/drivers/sbus/char/fb.h
Previous file: linux/drivers/sbus/char/cgthree.c
Back to the patch index
Back to the overall index
- Lines: 356
- Date:
Thu Sep 4 12:54:48 1997
- Orig file:
v2.1.52/linux/drivers/sbus/char/creator.c
- Orig date:
Mon Aug 18 18:19:46 1997
diff -u --recursive --new-file v2.1.52/linux/drivers/sbus/char/creator.c linux/drivers/sbus/char/creator.c
@@ -1,4 +1,4 @@
-/* $Id: creator.c,v 1.7 1997/07/17 02:21:47 davem Exp $
+/* $Id: creator.c,v 1.12 1997/08/25 07:50:27 jj Exp $
* creator.c: Creator/Creator3D frame buffer driver
*
* Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -101,14 +101,24 @@
#define FFB_UCSR_RP_BUSY 0x02000000
struct ffb_fbc {
- u8 xxx1[0x200];
+ u8 xxx1[0x60];
+ volatile u32 by;
+ volatile u32 bx;
+ u32 xxx2;
+ u32 xxx3;
+ volatile u32 bh;
+ volatile u32 bw;
+ u8 xxx4[0x188];
volatile u32 ppc;
- u8 xxx2[0x50];
+ u32 xxx5;
+ volatile u32 fg;
+ volatile u32 bg;
+ u8 xxx6[0x44];
volatile u32 fbc;
volatile u32 rop;
- u8 xxx3[0x34];
+ u8 xxx7[0x34];
volatile u32 pmask;
- u8 xxx4[12];
+ u8 xxx8[12];
volatile u32 clip0min;
volatile u32 clip0max;
volatile u32 clip1min;
@@ -117,11 +127,17 @@
volatile u32 clip2max;
volatile u32 clip3min;
volatile u32 clip3max;
- u8 xxx5[0x3c];
+ u8 xxx9[0x3c];
volatile u32 unk1;
- u8 xxx6[0x500];
volatile u32 unk2;
- u8 xxx7[0xfc];
+ u8 xxx10[0x10];
+ volatile u32 fontxy;
+ volatile u32 fontw;
+ volatile u32 fontinc;
+ volatile u32 font;
+ u8 xxx11[0x4dc];
+ volatile u32 unk3;
+ u8 xxx12[0xfc];
volatile u32 ucsr;
};
@@ -141,6 +157,7 @@
static void ffb_setw(int, int, unsigned short, int);
static void ffb_cpyw(int, int, unsigned short *, int);
static void ffb_fill(int, int, int *);
+static void ffb_penguin(int,int,int);
static struct {
unsigned long voff;
@@ -176,6 +193,8 @@
uint size, page, r, map_size;
unsigned long map_offset = 0;
int i;
+ int alignment;
+ struct vm_area_struct *vmm;
size = vma->vm_end - vma->vm_start;
if (vma->vm_offset & ~PAGE_MASK)
@@ -184,15 +203,18 @@
/* Try to align RAM */
#define ALIGNMENT 0x400000
map_offset = vma->vm_offset + size;
+ alignment = 0;
if (vma->vm_offset < FFB_FBC_REGS_VOFF) {
- struct vm_area_struct *vmm = find_vma(current->mm, vma->vm_start);
- int alignment = ALIGNMENT - ((vma->vm_start - vma->vm_offset) & (ALIGNMENT - 1));
-
- if (alignment == ALIGNMENT) alignment = 0;
- if (alignment && (!vmm || vmm->vm_start >= vma->vm_end + alignment)) {
- vma->vm_start += alignment;
- vma->vm_end += alignment;
- }
+ vmm = find_vma(current->mm, vma->vm_start);
+ alignment = ALIGNMENT - ((vma->vm_start - vma->vm_offset) & (ALIGNMENT - 1));
+ } else if (vma->vm_offset >= FFB_DFB8R_VOFF && (vma->vm_offset & (ALIGNMENT - 1)) == 0x4000) {
+ vmm = find_vma(current->mm, vma->vm_start);
+ alignment = ALIGNMENT - (vma->vm_start & (ALIGNMENT - 1));
+ }
+ if (alignment == ALIGNMENT) alignment = 0;
+ if (alignment && (!vmm || vmm->vm_start >= vma->vm_end + alignment)) {
+ vma->vm_start += alignment;
+ vma->vm_end += alignment;
}
#undef ALIGNMENT
@@ -205,7 +227,7 @@
for (i = 0; i < sizeof (ffbmmap) / sizeof (ffbmmap[0]); i++)
if (ffbmmap[i].voff == vma->vm_offset+page) {
map_size = ffbmmap[i].size;
- map_offset = fb->info.ffb.physbase + ffbmmap[i].poff;
+ map_offset = (fb->info.ffb.physbase + ffbmmap[i].poff) & _PAGE_PADDR;
}
if (!map_size){
@@ -380,8 +402,8 @@
dac->type2 = 0x104;
/* Should this be just 0x7ff?? Should I do some margin handling and setcurshape
in that case? */
- dac->value2 = (((c->cpos.fbx - c->chot.fbx) & 0xffff) << 16)
- |((c->cpos.fby - c->chot.fby) & 0xffff);
+ dac->value2 = (((c->cpos.fby - c->chot.fby) & 0xffff) << 16)
+ |((c->cpos.fbx - c->chot.fbx) & 0xffff);
ffb_curs_enable (fb, fb->cursor.enable);
}
@@ -480,32 +502,14 @@
void
ffb_reset (fbinfo_t *fb)
{
- struct ffb_info *ffb = &(fb->info.ffb);
- int fifo;
-
- if (fb->setcursor)
- sun_hw_hide_cursor ();
-
- while ((fifo = (ffb->fbc->ucsr & FFB_UCSR_FIFO_MASK)) < 8);
- ffb->fbc->ppc = (FFB_PPC_ACE_DISABLE << FFB_PPC_ACE_SHIFT) |
- (FFB_PPC_DCE_DISABLE << FFB_PPC_DCE_SHIFT) |
- (FFB_PPC_ABE_DISABLE << FFB_PPC_ABE_SHIFT) |
- (FFB_PPC_VCE_DISABLE << FFB_PPC_VCE_SHIFT) |
- (FFB_PPC_APE_DISABLE << FFB_PPC_APE_SHIFT) |
- (FFB_PPC_CS_VARIABLE << FFB_PPC_CS_SHIFT);
- ffb->fbc->fbc = (FFB_FBC_WB_A << FFB_FBC_WB_SHIFT) |
- (FFB_FBC_PGE_MASK << FFB_FBC_BE_SHIFT) |
- (FFB_FBC_PGE_MASK << FFB_FBC_GE_SHIFT) |
- (FFB_FBC_PGE_MASK << FFB_FBC_RE_SHIFT);
- ffb->fbc->rop = (FFB_ROP_NEW << FFB_ROP_RGB_SHIFT);
- ffb->fbc->pmask = 0x00ffffff;
- while (ffb->fbc->ucsr & FFB_UCSR_RP_BUSY);
+ if (fb == &fbinfo[0])
+ sbus_hw_hide_cursor ();
}
__initfunc(static unsigned long ffb_postsetup (fbinfo_t *fb, unsigned long memory_start))
{
fb->info.ffb.clut = (u32 *)(memory_start);
- fb->color_map = (u8 *)(memory_start+256*4+256);
+ fb->color_map = (u8 *)(memory_start+256*4);
return memory_start + 256*4 + 256*3;
}
@@ -513,10 +517,11 @@
{
struct ffb_info *ffbinfo;
struct linux_prom64_registers regs[2*PROMREG_MAX];
-
+ int type;
+
if (prom_getproperty(ffb_node, "reg", (void *) regs, sizeof(regs)) <= 0)
return;
- ffb = regs[0].phys_addr;
+ ffb = (long)__va(regs[0].phys_addr);
printk ("creator%d at 0x%016lx ", slot, ffb);
fb->base = ffb; /* ??? */
@@ -536,9 +541,11 @@
fb->setw = ffb_setw;
fb->cpyw = ffb_cpyw;
fb->fill = ffb_fill;
+ fb->draw_penguin = ffb_penguin;
fb->ioctl = ffb_ioctl;
fb->cursor.hwsize.fbx = 64;
fb->cursor.hwsize.fby = 64;
+ fb->type.fb_depth = 24;
ffbinfo = (struct ffb_info *) &fb->info.ffb;
@@ -546,16 +553,18 @@
ffbinfo->fbc = (struct ffb_fbc *)(ffb + FFB_FBC_REGS_POFF);
ffbinfo->dac = (struct ffb_dac *)(ffb + FFB_DAC_POFF);
-
+
ffbinfo->dac->type = 0x8000;
ffbinfo->dac_rev = (ffbinfo->dac->value >> 0x1c);
if (slot == sun_prom_console_id)
fb_restore_palette = ffb_restore_palette;
+
+ type = prom_getintdefault (ffb_node, "board_type", 8);
/* Initialize Brooktree DAC */
- printk("DAC %d\n", ffbinfo->dac_rev);
+ printk("TYPE %d DAC %d\n", type, ffbinfo->dac_rev);
if (slot && sun_prom_console_id == slot)
return;
@@ -573,18 +582,152 @@
extern unsigned char vga_font[];
+#define FFB_BLITC_START(attr) \
+ { \
+ register struct ffb_fbc *ffb = fbinfo[0].info.ffb.fbc; \
+ register u32 *clut = fbinfo[0].info.ffb.clut; \
+ int i; \
+ ffb->ppc = 0x203; \
+ ffb->fg = clut[attr & 0xf]; \
+ ffb->fbc = 0x2000707f; \
+ ffb->rop = 0x83; \
+ ffb->pmask = 0xffffffff; \
+ ffb->bg = clut[attr>>4];
+#define FFB_BLITC_BODY4(count,x,y,start,action) \
+ while (count >= 4) { \
+ count -= 4; \
+ ffb->fontw = 32; \
+ ffb->fontinc = 0x10000; \
+ ffb->fontxy = (y << 16) + x; \
+ x += 32; \
+ start; \
+ for (i = 0; i < CHAR_HEIGHT; i++) { \
+ action; \
+ } \
+ }
+#define FFB_BLITC_BODY1(x,y,action) \
+ ffb->fontw = 8; \
+ ffb->fontinc = 0x10000; \
+ ffb->fontxy = (y << 16) + x; \
+ x += 8; \
+ for (i = 0; i < CHAR_HEIGHT; i++) { \
+ action; \
+ }
+#define FFB_BLITC_END \
+ }
+
static void ffb_blitc(unsigned short charattr, int xoff, int yoff)
{
+ unsigned char attrib = CHARATTR_TO_SUNCOLOR(charattr);
+ unsigned char *p = &vga_font[((unsigned char)charattr) << 4];
+ FFB_BLITC_START(attrib)
+ FFB_BLITC_BODY1(xoff, yoff, ffb->font=((*p++) << 24))
+ FFB_BLITC_END
}
static void ffb_setw(int xoff, int yoff, unsigned short c, int count)
{
+ unsigned char attrib = CHARATTR_TO_SUNCOLOR(c);
+ unsigned char *p = &vga_font[((unsigned char)c) << 4];
+ register unsigned char *q;
+ register uint l;
+ FFB_BLITC_START(attrib)
+ if (count >= 4) {
+ FFB_BLITC_BODY4(count, xoff, yoff, q = p,
+ l = *q++;
+ l |= l << 8;
+ l |= l << 16;
+ ffb->font=l)
+ }
+ while (count) {
+ count--;
+ q = p;
+ FFB_BLITC_BODY1(xoff, yoff, ffb->font=((*q++) << 24));
+ }
+ FFB_BLITC_END
}
static void ffb_cpyw(int xoff, int yoff, unsigned short *p, int count)
{
+ unsigned char attrib = CHARATTR_TO_SUNCOLOR(*p);
+ unsigned char *p1, *p2, *p3, *p4;
+ FFB_BLITC_START(attrib)
+ if (count >= 4) {
+ FFB_BLITC_BODY4(count, xoff, yoff,
+ p1 = &vga_font[((unsigned char)*p++) << 4];
+ p2 = &vga_font[((unsigned char)*p++) << 4];
+ p3 = &vga_font[((unsigned char)*p++) << 4];
+ p4 = &vga_font[((unsigned char)*p++) << 4],
+ ffb->font=((uint)*p4++) | ((((uint)*p3++) | ((((uint)*p2++) | (((uint)*p1++) << 8)) << 8)) << 8))
+ }
+ while (count) {
+ count--;
+ p1 = &vga_font[((unsigned char)*p++) << 4];
+ FFB_BLITC_BODY1(xoff, yoff, ffb->font=((*p1++) << 24));
+ }
+ FFB_BLITC_END
}
+#if 0
+#define FFB_FILL_START(attr) \
+ { \
+ register struct ffb_fbc *ffb = fbinfo[0].info.ffb.fbc; \
+ register u32 *clut = fbinfo[0].info.ffb.clut; \
+ ffb->ppc =0x1803; \
+ ffb->fg = clut[attr & 0xf]; \
+ ffb->fbc = 0x2000707f; \
+ ffb->rop = 0x83; \
+ ffb->pmask = 0xffffffff; \
+ ffb->unk2 = 8;
+#define FFB_FILL_END \
+ }
+#else
+#define FFB_FILL_START(attr) \
+ { \
+ register struct ffb_fbc *ffb = fbinfo[0].info.ffb.fbc; \
+ ffb->ppc = 0x1803; \
+ ffb->fg = 0; \
+ ffb->fbc = 0x2000707f; \
+ ffb->rop = 0x83; \
+ ffb->pmask = 0xffffffff; \
+ ffb->unk2 = 8;
+#define FFB_FILL_END \
+ }
+#endif
+
static void ffb_fill(int attrib, int count, int *boxes)
{
+ attrib = 5;
+ FFB_FILL_START(attrib)
+ while (count-- > 0) {
+ ffb->by = boxes[1];
+ ffb->bx = boxes[0];
+ ffb->bw = boxes[2];
+ ffb->bh = boxes[3];
+ boxes += 4;
+ }
+ FFB_FILL_END
+}
+
+__initfunc(void ffb_penguin(int x_margin, int y_margin, int ncpus))
+{
+ int i, j, k;
+ u32 *p, *q;
+ unsigned char *r;
+ unsigned char c;
+
+ p = (u32 *)(fbinfo[0].info.ffb.physbase + FFB_DFB24_POFF + y_margin*8192 + x_margin*4);
+ for (i = 0; i < 80; i++, p += 2048) {
+ q = p;
+ for (j = 0; j < ncpus; j++) {
+ r = linux_logo + 80 * i;
+ for (k = 0; k < 80; k++, r++) {
+ c = *r - 32;
+ *q++ = (linux_logo_red[c]) |
+ (linux_logo_green[c]<<8) |
+ (linux_logo_blue[c]<<16);
+ }
+ q += 8;
+ }
+ }
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov