1 /* $id: p9100fb.c,v 1.4 1999/08/18 10:55:01 shadow Exp $
2 * p9100fb.c: P9100 frame buffer driver
4 * Copyright 1999 Derrick J Brashear (shadow@dementia.org)
7 #include <linux/module.h>
8 #include <linux/sched.h>
9 #include <linux/kernel.h>
10 #include <linux/errno.h>
11 #include <linux/string.h>
13 #include <linux/tty.h>
14 #include <linux/malloc.h>
15 #include <linux/vmalloc.h>
16 #include <linux/delay.h>
17 #include <linux/interrupt.h>
19 #include <linux/init.h>
20 #include <linux/selection.h>
22 #include <video/sbusfb.h>
25 #include <video/fbcon-cfb8.h>
29 static struct sbus_mmap_map p9100_mmap_map
[] = {
30 #if 0 /* For now, play we're a dumb color fb */
31 { P9100_CTL_OFF
, 0x38000000, 0x2000 },
32 { P9100_CMD_OFF
, 0x38002000, 0x2000 },
33 { P9100_FB_OFF
, 0x38800000, 0x200000 },
34 { CG3_MMAP_OFFSET
, 0x38800000, SBUS_MMAP_FBSIZE(1) },
36 { CG3_MMAP_OFFSET
, 0x0, SBUS_MMAP_FBSIZE(1) },
41 #define _READCTL(member, out) \
43 struct p9100_ctrl *actual; \
44 actual = (struct p9100_ctrl *)fb->s.p9100.ctrl; \
45 out = actual-> ## member ; \
48 #define READCTL(member, out) \
50 struct p9100_ctrl *enab, *actual; \
51 actual = (struct p9100_ctrl *)fb->s.p9100.ctrl; \
52 enab = (struct p9100_ctrl *)fb->s.p9100.fbmem; \
53 out = enab-> ## member ; \
54 out = actual-> ## member ; \
57 #define WRITECTL(member, val) \
60 struct p9100_ctrl *enab, *actual; \
61 actual = (struct p9100_ctrl *)fb->s.p9100.ctrl; \
62 enab = (struct p9100_ctrl *)fb->s.p9100.fbmem; \
63 __writetmp = enab-> ## member ; \
64 actual-> ## member = val; \
67 static void p9100_loadcmap (struct fb_info_sbusfb
*fb
, struct display
*p
, int index
, int count
)
72 _READCTL(pwrup_cfg
, tmp
);
73 WRITECTL(ramdac_cmap_wridx
, (index
<< 16));
75 for (i
= index
; count
--; i
++){
76 _READCTL(pwrup_cfg
, tmp
);
77 WRITECTL(ramdac_palette_data
, (fb
->color_map
CM(i
,0) << 16));
78 _READCTL(pwrup_cfg
, tmp
);
79 WRITECTL(ramdac_palette_data
, (fb
->color_map
CM(i
,1) << 16));
80 _READCTL(pwrup_cfg
, tmp
);
81 WRITECTL(ramdac_palette_data
, (fb
->color_map
CM(i
,2) << 16));
85 static void p9100_blank (struct fb_info_sbusfb
*fb
)
88 READCTL(vid_screenpaint_timectl1
, val
);
89 val
&= ~ SCREENPAINT_TIMECTL1_ENABLE_VIDEO
;
90 WRITECTL(vid_screenpaint_timectl1
, val
);
93 static void p9100_unblank (struct fb_info_sbusfb
*fb
)
96 READCTL(vid_screenpaint_timectl1
, val
);
97 val
|= SCREENPAINT_TIMECTL1_ENABLE_VIDEO
;
98 WRITECTL(vid_screenpaint_timectl1
, val
);
101 static void p9100_margins (struct fb_info_sbusfb
*fb
, struct display
*p
, int x_margin
, int y_margin
)
103 p
->screen_base
+= (y_margin
- fb
->y_margin
) * p
->line_length
+
104 (x_margin
- fb
->x_margin
);
107 static char idstring
[60] __initdata
= { 0 };
109 char * __init
p9100fb_init(struct fb_info_sbusfb
*fb
)
111 struct fb_fix_screeninfo
*fix
= &fb
->fix
;
112 struct display
*disp
= &fb
->disp
;
113 struct fbtype
*type
= &fb
->type
;
114 unsigned long phys
= fb
->sbdp
->reg_addrs
[2].phys_addr
;
117 #ifndef FBCON_HAS_CFB8
121 /* Control regs: fb->sbdp->reg_addrs[0].phys_addr
122 * Command regs: fb->sbdp->reg_addrs[1].phys_addr
123 * Frame buffer: fb->sbdp->reg_addrs[2].phys_addr
126 if (!fb
->s
.p9100
.ctrl
) {
127 fb
->s
.p9100
.ctrl
= (struct p9100_ctrl
*)
128 sparc_alloc_io(fb
->sbdp
->reg_addrs
[0].phys_addr
, 0,
129 fb
->sbdp
->reg_addrs
[1].reg_size
, "p9100_ctrl", fb
->iospace
, 0);
132 strcpy(fb
->info
.modename
, "p9100");
133 strcpy(fix
->id
, "p9100");
134 fix
->accel
= FB_ACCEL_SUN_CGTHREE
;
135 fix
->line_length
= fb
->var
.xres_virtual
;
137 disp
->scrollmode
= SCROLL_YREDRAW
;
138 if (!disp
->screen_base
)
140 (char *)sparc_alloc_io(phys
, 0, type
->fb_size
, "p9100_ram",
142 fb
->s
.p9100
.fbmem
= disp
->screen_base
;
143 disp
->screen_base
+= fix
->line_length
* fb
->y_margin
+ fb
->x_margin
;
145 READCTL(sys_config
, tmp
);
146 switch ((tmp
>> SYS_CONFIG_PIXELSIZE_SHIFT
) & 7) {
160 printk("p9100: screen depth unknown: 0x%x", tmp
);
164 fb
->dispsw
= fbcon_cfb8
;
166 fb
->margins
= p9100_margins
;
167 fb
->loadcmap
= p9100_loadcmap
;
168 fb
->blank
= p9100_blank
;
169 fb
->unblank
= p9100_unblank
;
172 fb
->mmap_map
= p9100_mmap_map
;
174 sprintf(idstring
, "%s at 0x%x", "p9100", disp
->screen_base
);