1 /*
2 * Copyright (c) 1988 University of Utah.
3 * Copyright (c) 1990, 1993
4 * The Regents of the University of California. All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * the Systems Programming Group of the University of Utah Computer
8 * Science Department.
9 *
10 * %sccs.include.redist.c%
11 *
12 * from: Utah $Hdr: grf_dv.c 1.12 93/08/13$
13 *
14 * @(#)grf_dv.c 8.4 (Berkeley) 01/12/94
15 */
16
17 #include "grf.h"
18 #if NGRF > 0
19
20 /*
21 * Graphics routines for the DaVinci, HP98730/98731 Graphics system.
22 */
23 #include <sys/param.h>
24 #include <sys/errno.h>
25
26 #include <hp/dev/grfioctl.h>
27 #include <hp/dev/grfvar.h>
28 #include <hp300/dev/grf_dvreg.h>
29
30 #include <machine/cpu.h>
31
32 /*
33 * Initialize hardware.
34 * Must point g_display at a grfinfo structure describing the hardware.
35 * Returns 0 if hardware not present, non-zero ow.
36 */
37 dv_init(gp, addr)
38 struct grf_softc *gp;
39 caddr_t addr;
40 {
41 register struct dvboxfb *dbp;
42 struct grfinfo *gi = &gp->g_display;
43 int fboff;
44 extern caddr_t sctopa(), iomap();
45
46 dbp = (struct dvboxfb *) addr;
47 if (ISIIOVA(addr))
48 gi->gd_regaddr = (caddr_t) IIOP(addr);
49 else
50 gi->gd_regaddr = sctopa(vatosc(addr));
51 gi->gd_regsize = 0x20000;
52 gi->gd_fbwidth = (dbp->fbwmsb << 8) | dbp->fbwlsb;
53 gi->gd_fbheight = (dbp->fbhmsb << 8) | dbp->fbhlsb;
54 gi->gd_fbsize = gi->gd_fbwidth * gi->gd_fbheight;
55 fboff = (dbp->fbomsb << 8) | dbp->fbolsb;
56 gi->gd_fbaddr = (caddr_t) (*((u_char *)addr + fboff) << 16);
57 if (gi->gd_regaddr >= (caddr_t)DIOIIBASE) {
58 /*
59 * For DIO II space the fbaddr just computed is the offset
60 * from the select code base (regaddr) of the framebuffer.
61 * Hence it is also implicitly the size of the register set.
62 */
63 gi->gd_regsize = (int) gi->gd_fbaddr;
64 gi->gd_fbaddr += (int) gi->gd_regaddr;
65 gp->g_regkva = addr;
66 gp->g_fbkva = addr + gi->gd_regsize;
67 } else {
68 /*
69 * For DIO space we need to map the seperate framebuffer.
70 */
71 gp->g_regkva = addr;
72 gp->g_fbkva = iomap(gi->gd_fbaddr, gi->gd_fbsize);
73 }
74 gi->gd_dwidth = (dbp->dwmsb << 8) | dbp->dwlsb;
75 gi->gd_dheight = (dbp->dwmsb << 8) | dbp->dwlsb;
76 gi->gd_planes = 0; /* ?? */
77 gi->gd_colors = 256;
78
79 dv_reset(dbp);
80 return(1);
81 }
82
83 /*
84 * Magic code herein.
85 */
dv_reset(dbp)86 dv_reset(dbp)
87 register struct dvboxfb *dbp;
88 {
89 dbp->reset = 0x80;
90 DELAY(100);
91
92 dbp->interrupt = 0x04;
93 dbp->en_scan = 0x01;
94 dbp->fbwen = ~0;
95 dbp->opwen = ~0;
96 dbp->fold = 0x01;
97 dbp->drive = 0x01;
98 dbp->rep_rule = 0x33;
99 dbp->alt_rr = 0x33;
100 dbp->zrr = 0x33;
101
102 dbp->fbvenp = 0xFF;
103 dbp->dispen = 0x01;
104 dbp->fbvens = 0x0;
105 dbp->fv_trig = 0x01;
106 DELAY(100);
107 dbp->vdrive = 0x0;
108 dbp->zconfig = 0x0;
109
110 while (dbp->wbusy & 0x01)
111 DELAY(100);
112
113 dbp->cmapbank = 0;
114
115 dbp->red0 = 0;
116 dbp->red1 = 0;
117 dbp->green0 = 0;
118 dbp->green1 = 0;
119 dbp->blue0 = 0;
120 dbp->blue1 = 0;
121
122 dbp->panxh = 0;
123 dbp->panxl = 0;
124 dbp->panyh = 0;
125 dbp->panyl = 0;
126 dbp->zoom = 0;
127 dbp->cdwidth = 0x50;
128 dbp->chstart = 0x52;
129 dbp->cvwidth = 0x22;
130 dbp->pz_trig = 1;
131 }
132
133 /*
134 * Change the mode of the display.
135 * Right now all we can do is grfon/grfoff.
136 * Return a UNIX error number or 0 for success.
137 */
dv_mode(gp,cmd,data)138 dv_mode(gp, cmd, data)
139 register struct grf_softc *gp;
140 int cmd;
141 caddr_t data;
142 {
143 register struct dvboxfb *dbp;
144 int error = 0;
145
146 dbp = (struct dvboxfb *) gp->g_regkva;
147 switch (cmd) {
148 case GM_GRFON:
149 dbp->dispen = 0x01;
150 break;
151
152 case GM_GRFOFF:
153 break;
154
155 case GM_GRFOVON:
156 dbp->opwen = 0xF;
157 dbp->drive = 0x10;
158 break;
159
160 case GM_GRFOVOFF:
161 dbp->opwen = 0;
162 dbp->drive = 0x01;
163 break;
164
165 /*
166 * Remember UVA of mapping for GCDESCRIBE.
167 * XXX this should be per-process.
168 */
169 case GM_MAP:
170 gp->g_data = data;
171 break;
172
173 case GM_UNMAP:
174 gp->g_data = 0;
175 break;
176
177 #ifdef HPUXCOMPAT
178 case GM_DESCRIBE:
179 {
180 struct grf_fbinfo *fi = (struct grf_fbinfo *)data;
181 struct grfinfo *gi = &gp->g_display;
182 int i;
183
184 /* feed it what HP-UX expects */
185 fi->id = gi->gd_id;
186 fi->mapsize = gi->gd_fbsize;
187 fi->dwidth = gi->gd_dwidth;
188 fi->dlength = gi->gd_dheight;
189 fi->width = gi->gd_fbwidth;
190 fi->length = gi->gd_fbheight;
191 fi->bpp = NBBY;
192 fi->xlen = (fi->width * fi->bpp) / NBBY;
193 fi->npl = gi->gd_planes;
194 fi->bppu = fi->npl;
195 fi->nplbytes = fi->xlen * ((fi->length * fi->bpp) / NBBY);
196 bcopy("HP98730", fi->name, 8);
197 fi->attr = 2; /* HW block mover */
198 /*
199 * If mapped, return the UVA where mapped.
200 */
201 if (gp->g_data) {
202 fi->regbase = gp->g_data;
203 fi->fbbase = fi->regbase + gp->g_display.gd_regsize;
204 } else {
205 fi->fbbase = 0;
206 fi->regbase = 0;
207 }
208 for (i = 0; i < 6; i++)
209 fi->regions[i] = 0;
210 break;
211 }
212 #endif
213
214 default:
215 error = EINVAL;
216 break;
217 }
218 return(error);
219 }
220
221 #endif
222