tx3912video.c revision 1.6 1 1.6 uch /* $NetBSD: tx3912video.c,v 1.6 2000/01/06 18:10:42 uch Exp $ */
2 1.1 uch
3 1.1 uch /*
4 1.5 uch * Copyright (c) 1999, 2000, by UCHIYAMA Yasushi
5 1.1 uch * All rights reserved.
6 1.1 uch *
7 1.1 uch * Redistribution and use in source and binary forms, with or without
8 1.1 uch * modification, are permitted provided that the following conditions
9 1.1 uch * are met:
10 1.1 uch * 1. Redistributions of source code must retain the above copyright
11 1.1 uch * notice, this list of conditions and the following disclaimer.
12 1.1 uch * 2. The name of the developer may NOT be used to endorse or promote products
13 1.1 uch * derived from this software without specific prior written permission.
14 1.1 uch *
15 1.1 uch * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 1.1 uch * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 1.1 uch * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 1.1 uch * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 1.1 uch * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 1.1 uch * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 1.1 uch * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 1.1 uch * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 1.1 uch * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 1.1 uch * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 1.1 uch * SUCH DAMAGE.
26 1.1 uch *
27 1.1 uch */
28 1.1 uch #include "opt_tx39_debug.h"
29 1.2 uch #include "fb.h"
30 1.1 uch
31 1.1 uch #include <sys/param.h>
32 1.1 uch #include <sys/systm.h>
33 1.1 uch #include <sys/device.h>
34 1.1 uch #include <sys/extent.h>
35 1.1 uch
36 1.1 uch #include <machine/bus.h>
37 1.2 uch #include <machine/bootinfo.h> /* bootinfo */
38 1.1 uch
39 1.1 uch #include <hpcmips/tx/tx39var.h>
40 1.1 uch #include <hpcmips/tx/tx3912videovar.h>
41 1.1 uch #include <hpcmips/tx/tx3912videoreg.h>
42 1.1 uch
43 1.2 uch #if NFB > 0
44 1.2 uch #include <dev/rcons/raster.h>
45 1.2 uch #include <dev/wscons/wsdisplayvar.h>
46 1.2 uch #include <arch/hpcmips/dev/fbvar.h>
47 1.2 uch #endif
48 1.2 uch
49 1.6 uch #undef TX3912VIDEO_DEBUG
50 1.6 uch
51 1.3 uch void tx3912video_framebuffer_init __P((tx_chipset_tag_t, u_int32_t,
52 1.3 uch u_int32_t));
53 1.3 uch int tx3912video_framebuffer_alloc __P((tx_chipset_tag_t, u_int32_t,
54 1.3 uch int, int, int, u_int32_t*,
55 1.3 uch u_int32_t*));
56 1.1 uch void tx3912video_reset __P((tx_chipset_tag_t));
57 1.1 uch void tx3912video_resolution_init __P((tx_chipset_tag_t, int, int));
58 1.1 uch int tx3912video_fbdepth __P((tx_chipset_tag_t, int));
59 1.1 uch
60 1.1 uch int tx3912video_match __P((struct device*, struct cfdata*, void*));
61 1.1 uch void tx3912video_attach __P((struct device*, struct device*, void*));
62 1.1 uch int tx3912video_print __P((void*, const char*));
63 1.1 uch
64 1.6 uch struct tx3912video_chip {
65 1.6 uch u_int32_t vc_fbaddr;
66 1.6 uch u_int32_t vc_fbsize;
67 1.6 uch int vc_fbdepth;
68 1.6 uch int vc_fbwidth;
69 1.6 uch int vc_fbheight;
70 1.6 uch
71 1.6 uch void (*vc_drawline) __P((int, int, int, int));
72 1.6 uch void (*vc_drawdot) __P((int, int));
73 1.6 uch };
74 1.6 uch
75 1.1 uch struct tx3912video_softc {
76 1.1 uch struct device sc_dev;
77 1.6 uch
78 1.6 uch struct tx3912video_chip *sc_chip;
79 1.1 uch };
80 1.1 uch
81 1.1 uch struct fb_attach_args {
82 1.1 uch const char *fba_name;
83 1.1 uch };
84 1.1 uch
85 1.1 uch struct cfattach tx3912video_ca = {
86 1.3 uch sizeof(struct tx3912video_softc), tx3912video_match,
87 1.3 uch tx3912video_attach
88 1.1 uch };
89 1.1 uch
90 1.6 uch /* console */
91 1.6 uch struct tx3912video_chip tx3912video_chip;
92 1.6 uch
93 1.6 uch void tx3912video_attach_drawfunc __P((struct tx3912video_chip*));
94 1.6 uch
95 1.1 uch int
96 1.1 uch tx3912video_match(parent, cf, aux)
97 1.1 uch struct device *parent;
98 1.1 uch struct cfdata *cf;
99 1.1 uch void *aux;
100 1.1 uch {
101 1.1 uch return 1;
102 1.1 uch }
103 1.1 uch
104 1.1 uch void
105 1.1 uch tx3912video_attach(parent, self, aux)
106 1.1 uch struct device *parent;
107 1.1 uch struct device *self;
108 1.1 uch void *aux;
109 1.1 uch {
110 1.1 uch struct txsim_attach_args *ta = aux;
111 1.1 uch struct tx3912video_softc *sc = (void*)self;
112 1.1 uch tx_chipset_tag_t tc = ta->ta_tc;
113 1.1 uch struct fb_attach_args fba;
114 1.4 uch txreg_t reg;
115 1.1 uch
116 1.6 uch sc->sc_chip = &tx3912video_chip;
117 1.5 uch
118 1.5 uch printf(": ");
119 1.1 uch tx3912video_fbdepth(tc, 1);
120 1.6 uch printf(", frame buffer 0x%08x-0x%08x", sc->sc_chip->vc_fbaddr,
121 1.6 uch sc->sc_chip->vc_fbaddr + sc->sc_chip->vc_fbsize);
122 1.4 uch
123 1.5 uch printf("\n");
124 1.5 uch
125 1.6 uch #ifndef TX3912VIDEO_DEBUG
126 1.4 uch if (bootinfo->bi_cnuse & BI_CNUSE_SERIAL) {
127 1.5 uch printf("%s: power off\n", sc->sc_dev.dv_xname);
128 1.4 uch reg = tx_conf_read(tc, TX3912_VIDEOCTRL1_REG);
129 1.4 uch reg &= ~(TX3912_VIDEOCTRL1_DISPON |
130 1.4 uch TX3912_VIDEOCTRL1_ENVID);
131 1.4 uch tx_conf_write(tc, TX3912_VIDEOCTRL1_REG, reg);
132 1.4 uch }
133 1.6 uch #endif /* TX3912VIDEO_DEBUG */
134 1.6 uch
135 1.6 uch /* attach debug draw routine */
136 1.6 uch tx3912video_attach_drawfunc(sc->sc_chip);
137 1.1 uch
138 1.1 uch /* Attach frame buffer device */
139 1.2 uch #if NFB > 0
140 1.2 uch if (!(bootinfo->bi_cnuse & BI_CNUSE_SERIAL)) {
141 1.2 uch if (fb_cnattach(0, 0, 0, 0)) {
142 1.2 uch panic("tx3912video_attach: can't init fb console");
143 1.2 uch }
144 1.2 uch }
145 1.1 uch fba.fba_name = "fb";
146 1.1 uch config_found(self, &fba, tx3912video_print);
147 1.2 uch #endif
148 1.1 uch }
149 1.1 uch
150 1.1 uch int
151 1.1 uch tx3912video_print(aux, pnp)
152 1.1 uch void *aux;
153 1.1 uch const char *pnp;
154 1.1 uch {
155 1.1 uch return pnp ? QUIET : UNCONF;
156 1.1 uch }
157 1.1 uch
158 1.1 uch int
159 1.1 uch tx3912video_init(tc, fb_start, fb_width, fb_height, fb_addr, fb_size,
160 1.1 uch fb_line_bytes)
161 1.1 uch tx_chipset_tag_t tc;
162 1.1 uch u_int32_t fb_start; /* Physical address */
163 1.1 uch int fb_width, fb_height;
164 1.1 uch u_int32_t *fb_addr, *fb_size;
165 1.1 uch int *fb_line_bytes;
166 1.1 uch {
167 1.1 uch u_int32_t addr, size;
168 1.1 uch int fb_depth;
169 1.1 uch
170 1.1 uch /* Inquire bit depth */
171 1.1 uch fb_depth = tx3912video_fbdepth(tc, 0);
172 1.6 uch tx3912video_chip.vc_fbdepth = fb_depth;
173 1.6 uch tx3912video_chip.vc_fbwidth = fb_width;
174 1.6 uch tx3912video_chip.vc_fbheight= fb_height;
175 1.1 uch
176 1.1 uch /* Allocate framebuffer area */
177 1.1 uch if (tx3912video_framebuffer_alloc(tc, fb_start, fb_width, fb_height,
178 1.1 uch fb_depth, &addr, &size)) {
179 1.1 uch return 1;
180 1.1 uch }
181 1.1 uch #if notyet
182 1.1 uch tx3912video_resolution_init(tc, fb_width, fb_height);
183 1.1 uch #else
184 1.1 uch /* Use Windows CE setting. */
185 1.1 uch #endif
186 1.1 uch /* Set DMA transfer address to VID module */
187 1.1 uch tx3912video_framebuffer_init(tc, addr, size);
188 1.1 uch
189 1.1 uch /* Syncronize framebuffer addr to frame signal */
190 1.1 uch tx3912video_reset(tc);
191 1.1 uch
192 1.1 uch *fb_line_bytes = (fb_width * fb_depth) / 8;
193 1.1 uch *fb_addr = addr; /* Phsical address */
194 1.1 uch *fb_size = size;
195 1.1 uch
196 1.1 uch return 0;
197 1.1 uch }
198 1.1 uch
199 1.1 uch int
200 1.1 uch tx3912video_framebuffer_alloc(tc, start, h, v, depth, fb_addr, fb_size)
201 1.1 uch tx_chipset_tag_t tc;
202 1.1 uch u_int32_t start;
203 1.1 uch int h, v, depth;
204 1.1 uch u_int32_t *fb_addr, *fb_size;
205 1.1 uch {
206 1.1 uch struct extent_fixed ex_fixed[2];
207 1.1 uch struct extent *ex;
208 1.1 uch u_long addr, size;
209 1.1 uch int err;
210 1.1 uch
211 1.1 uch /* Calcurate frame buffer size */
212 1.1 uch size = (h * v * depth) / 8;
213 1.1 uch
214 1.1 uch /* Allocate V-RAM area */
215 1.1 uch if (!(ex = extent_create("Frame buffer address", start,
216 1.1 uch start + TX3912_FRAMEBUFFER_MAX,
217 1.1 uch 0, (caddr_t)ex_fixed, sizeof ex_fixed,
218 1.1 uch EX_NOWAIT))) {
219 1.1 uch return 1;
220 1.1 uch }
221 1.1 uch if((err = extent_alloc_subregion(ex, start, start + size, size,
222 1.1 uch TX3912_FRAMEBUFFER_ALIGNMENT,
223 1.1 uch TX3912_FRAMEBUFFER_BOUNDARY,
224 1.1 uch EX_FAST|EX_NOWAIT, &addr))) {
225 1.1 uch return 1;
226 1.1 uch }
227 1.6 uch tx3912video_chip.vc_fbaddr = addr;
228 1.6 uch tx3912video_chip.vc_fbsize = size;
229 1.6 uch
230 1.1 uch *fb_addr = addr;
231 1.1 uch *fb_size = size;
232 1.1 uch
233 1.1 uch return 0;
234 1.1 uch }
235 1.1 uch
236 1.1 uch void
237 1.1 uch tx3912video_framebuffer_init(tc, fb_addr, fb_size)
238 1.1 uch tx_chipset_tag_t tc;
239 1.1 uch u_int32_t fb_addr, fb_size;
240 1.1 uch {
241 1.1 uch u_int32_t reg, vaddr, bank, base;
242 1.1 uch
243 1.1 uch /* XXX currently I don't set DFVAL, so force DF signal toggled on
244 1.1 uch * XXX each frame. */
245 1.1 uch reg = tx_conf_read(tc, TX3912_VIDEOCTRL1_REG);
246 1.1 uch reg &= ~TX3912_VIDEOCTRL1_DFMODE;
247 1.1 uch tx_conf_write(tc, TX3912_VIDEOCTRL1_REG, reg);
248 1.1 uch
249 1.1 uch /* Set DMA transfer start and end address */
250 1.1 uch
251 1.1 uch bank = TX3912_VIDEOCTRL3_VIDBANK(fb_addr);
252 1.1 uch base = TX3912_VIDEOCTRL3_VIDBASEHI(fb_addr);
253 1.1 uch reg = TX3912_VIDEOCTRL3_VIDBANK_SET(0, bank);
254 1.1 uch /* Upper address counter */
255 1.1 uch reg = TX3912_VIDEOCTRL3_VIDBASEHI_SET(reg, base);
256 1.1 uch tx_conf_write(tc, TX3912_VIDEOCTRL3_REG, reg);
257 1.1 uch
258 1.1 uch /* Lower address counter */
259 1.1 uch base = TX3912_VIDEOCTRL4_VIDBASELO(fb_addr + fb_size);
260 1.1 uch reg = TX3912_VIDEOCTRL4_VIDBASELO_SET(0, base);
261 1.1 uch
262 1.1 uch /* Set DF-signal rate */
263 1.1 uch reg = TX3912_VIDEOCTRL4_DFVAL_SET(reg, 0); /* XXX not yet*/
264 1.1 uch
265 1.1 uch /* Set VIDDONE signal delay after FRAME signal */
266 1.1 uch /* XXX not yet*/
267 1.1 uch tx_conf_write(tc, TX3912_VIDEOCTRL4_REG, reg);
268 1.1 uch
269 1.1 uch /* Clear frame buffer */
270 1.1 uch vaddr = MIPS_PHYS_TO_KSEG1(fb_addr);
271 1.1 uch bzero((void*)vaddr, fb_size);
272 1.1 uch }
273 1.1 uch
274 1.1 uch void
275 1.1 uch tx3912video_resolution_init(tc, h, v)
276 1.1 uch tx_chipset_tag_t tc;
277 1.1 uch int h;
278 1.1 uch int v;
279 1.1 uch {
280 1.1 uch u_int32_t reg, val;
281 1.1 uch int split, bit8, horzval, lineval;
282 1.1 uch
283 1.1 uch reg = tx_conf_read(tc, TX3912_VIDEOCTRL1_REG);
284 1.1 uch split = reg & TX3912_VIDEOCTRL1_DISPSPLIT;
285 1.1 uch bit8 = (TX3912_VIDEOCTRL1_BITSEL(reg) ==
286 1.1 uch TX3912_VIDEOCTRL1_BITSEL_8BITCOLOR);
287 1.1 uch val = TX3912_VIDEOCTRL1_BITSEL(reg);
288 1.1 uch
289 1.1 uch if ((val == TX3912_VIDEOCTRL1_BITSEL_8BITCOLOR) &&
290 1.1 uch !split) {
291 1.3 uch /* (LCD horizontal pixels / 8bit) * RGB - 1 */
292 1.3 uch horzval = (h / 8) * 3 - 1;
293 1.1 uch } else {
294 1.1 uch horzval = h / 4 - 1;
295 1.1 uch }
296 1.1 uch lineval = (split ? v / 2 : v) - 1;
297 1.1 uch
298 1.1 uch /* Video rate */
299 1.3 uch /* XXX
300 1.3 uch * probably This value should be determined from DFINT and LCDINT
301 1.3 uch */
302 1.1 uch reg = TX3912_VIDEOCTRL2_VIDRATE_SET(0, horzval + 1);
303 1.1 uch /* Horizontal size of LCD */
304 1.1 uch reg = TX3912_VIDEOCTRL2_HORZVAL_SET(reg, horzval);
305 1.1 uch /* # of lines for the LCD */
306 1.1 uch reg = TX3912_VIDEOCTRL2_LINEVAL_SET(reg, lineval);
307 1.1 uch
308 1.1 uch tx_conf_write(tc, TX3912_VIDEOCTRL2_REG, reg);
309 1.1 uch }
310 1.1 uch
311 1.6 uch int
312 1.1 uch tx3912video_fbdepth(tc, verbose)
313 1.1 uch tx_chipset_tag_t tc;
314 1.1 uch int verbose;
315 1.1 uch {
316 1.1 uch u_int32_t reg, val;
317 1.1 uch
318 1.1 uch reg = tx_conf_read(tc, TX3912_VIDEOCTRL1_REG);
319 1.1 uch val = TX3912_VIDEOCTRL1_BITSEL(reg);
320 1.1 uch switch (val) {
321 1.1 uch case TX3912_VIDEOCTRL1_BITSEL_8BITCOLOR:
322 1.1 uch if (verbose)
323 1.1 uch printf("8bit color");
324 1.1 uch return 8;
325 1.1 uch case TX3912_VIDEOCTRL1_BITSEL_4BITGREYSCALE:
326 1.1 uch if (verbose)
327 1.1 uch printf("4bit greyscale");
328 1.1 uch return 4;
329 1.1 uch case TX3912_VIDEOCTRL1_BITSEL_2BITGREYSCALE:
330 1.1 uch if (verbose)
331 1.1 uch printf("2bit greyscale");
332 1.1 uch return 2;
333 1.1 uch case TX3912_VIDEOCTRL1_BITSEL_MONOCHROME:
334 1.1 uch if (verbose)
335 1.1 uch printf("monochrome");
336 1.1 uch return 1;
337 1.1 uch }
338 1.1 uch return 0;
339 1.1 uch }
340 1.1 uch
341 1.1 uch void
342 1.1 uch tx3912video_reset(tc)
343 1.1 uch tx_chipset_tag_t tc;
344 1.1 uch {
345 1.1 uch u_int32_t reg;
346 1.1 uch
347 1.1 uch reg = tx_conf_read(tc, TX3912_VIDEOCTRL1_REG);
348 1.3 uch
349 1.1 uch /* Disable video logic at end of this frame */
350 1.1 uch reg |= TX3912_VIDEOCTRL1_ENFREEZEFRAME;
351 1.1 uch tx_conf_write(tc, TX3912_VIDEOCTRL1_REG, reg);
352 1.3 uch
353 1.1 uch /* Wait for end of frame */
354 1.1 uch delay(300 * 1000);
355 1.3 uch
356 1.1 uch /* Make sure to disable video logic */
357 1.1 uch reg &= ~TX3912_VIDEOCTRL1_ENVID;
358 1.1 uch tx_conf_write(tc, TX3912_VIDEOCTRL1_REG, reg);
359 1.3 uch
360 1.1 uch delay(1000);
361 1.3 uch
362 1.1 uch /* Enable video logic again */
363 1.1 uch reg &= ~TX3912_VIDEOCTRL1_ENFREEZEFRAME;
364 1.1 uch reg |= TX3912_VIDEOCTRL1_ENVID;
365 1.1 uch tx_conf_write(tc, TX3912_VIDEOCTRL1_REG, reg);
366 1.3 uch
367 1.1 uch delay(1000);
368 1.1 uch }
369 1.1 uch
370 1.6 uch /*
371 1.6 uch * Debug routines.
372 1.6 uch */
373 1.6 uch
374 1.6 uch void
375 1.6 uch tx3912video_calibration_pattern()
376 1.6 uch {
377 1.6 uch struct tx3912video_chip *vc = &tx3912video_chip;
378 1.6 uch int x, y;
379 1.6 uch
380 1.6 uch x = vc->vc_fbwidth - 40;
381 1.6 uch y = vc->vc_fbheight - 40;
382 1.6 uch tx3912video_line(40, 40, x , 40);
383 1.6 uch tx3912video_line(x , 40, x , y );
384 1.6 uch tx3912video_line(x , y , 40, y );
385 1.6 uch tx3912video_line(40, y , 40, 40);
386 1.6 uch tx3912video_line(40, 40, x , y );
387 1.6 uch tx3912video_line(x, 40, 40, y );
388 1.6 uch }
389 1.6 uch
390 1.6 uch #define BPP2 ({ \
391 1.6 uch u_int8_t bitmap; \
392 1.6 uch bitmap = *(volatile u_int8_t*)MIPS_PHYS_TO_KSEG1(addr); \
393 1.6 uch *(volatile u_int8_t*)MIPS_PHYS_TO_KSEG1(addr) = \
394 1.6 uch (bitmap & ~(0x3 << ((3 - (x % 4)) * 2))); \
395 1.6 uch })
396 1.6 uch
397 1.6 uch #define BPP4 ({ \
398 1.6 uch u_int8_t bitmap; \
399 1.6 uch bitmap = *(volatile u_int8_t*)MIPS_PHYS_TO_KSEG1(addr); \
400 1.6 uch *(volatile u_int8_t*)MIPS_PHYS_TO_KSEG1(addr) = \
401 1.6 uch (bitmap & ~(0xf << ((1 - (x % 2)) * 4))); \
402 1.6 uch })
403 1.6 uch
404 1.6 uch #define BPP8 ({ \
405 1.6 uch *(volatile u_int8_t*)MIPS_PHYS_TO_KSEG1(addr) = 0xff; \
406 1.6 uch })
407 1.6 uch
408 1.6 uch #define BRESENHAM(a, b, c, d, func) ({ \
409 1.6 uch u_int32_t fbaddr = vc->vc_fbaddr; \
410 1.6 uch u_int32_t fbwidth = vc->vc_fbwidth; \
411 1.6 uch u_int32_t fbdepth = vc->vc_fbdepth; \
412 1.6 uch len = a, step = b -1; \
413 1.6 uch if (step == 0) \
414 1.6 uch return; \
415 1.6 uch kstep = len == 0 ? 0 : 1; \
416 1.6 uch for (i = k = 0, j = step / 2; i <= step; i++) { \
417 1.6 uch x = xbase c; \
418 1.6 uch y = ybase d; \
419 1.6 uch addr = fbaddr + (((y * fbwidth + x) * fbdepth) >> 3); \
420 1.6 uch func; \
421 1.6 uch j -= len; \
422 1.6 uch while (j < 0) { \
423 1.6 uch j += step; \
424 1.6 uch k += kstep; \
425 1.6 uch } \
426 1.6 uch } \
427 1.6 uch })
428 1.6 uch
429 1.6 uch #define DRAWLINE(func) ({ \
430 1.6 uch if (x < 0) { \
431 1.6 uch if (y < 0) { \
432 1.6 uch if (_y < _x) { \
433 1.6 uch BRESENHAM(_y, _x, -i, -k, func); \
434 1.6 uch } else { \
435 1.6 uch BRESENHAM(_x, _y, -k, -i, func); \
436 1.6 uch } \
437 1.6 uch } else { \
438 1.6 uch if (_y < _x) { \
439 1.6 uch BRESENHAM(_y, _x, -i, +k, func); \
440 1.6 uch } else { \
441 1.6 uch BRESENHAM(_x, _y, -k, +i, func); \
442 1.6 uch } \
443 1.6 uch } \
444 1.6 uch } else { \
445 1.6 uch if (y < 0) { \
446 1.6 uch if (_y < _x) { \
447 1.6 uch BRESENHAM(_y, _x, +i, -k, func); \
448 1.6 uch } else { \
449 1.6 uch BRESENHAM(_x, _y, +k, -i, func); \
450 1.6 uch } \
451 1.6 uch } else { \
452 1.6 uch if (_y < _x) { \
453 1.6 uch BRESENHAM(_y, _x, +i, +k, func); \
454 1.6 uch } else { \
455 1.6 uch BRESENHAM(_x, _y, +k, +i, func); \
456 1.6 uch } \
457 1.6 uch } \
458 1.6 uch } \
459 1.6 uch })
460 1.6 uch
461 1.6 uch #define LINEFUNC(b) \
462 1.6 uch static void linebpp##b __P((int, int, int, int)); \
463 1.6 uch static void \
464 1.6 uch linebpp##b##(x0, y0, x1, y1) \
465 1.6 uch int x0, y0, x1, y1; \
466 1.6 uch { \
467 1.6 uch struct tx3912video_chip *vc = &tx3912video_chip; \
468 1.6 uch u_int32_t addr; \
469 1.6 uch int i, j, k, len, step, kstep; \
470 1.6 uch int x, _x, y, _y; \
471 1.6 uch int xbase, ybase; \
472 1.6 uch x = x1 - x0; \
473 1.6 uch y = y1 - y0; \
474 1.6 uch _x = abs(x); \
475 1.6 uch _y = abs(y); \
476 1.6 uch xbase = x0; \
477 1.6 uch ybase = y0; \
478 1.6 uch DRAWLINE(BPP##b##); \
479 1.6 uch }
480 1.1 uch
481 1.6 uch #define DOTFUNC(b) \
482 1.6 uch static void dotbpp##b __P((int, int)); \
483 1.6 uch static void \
484 1.6 uch dotbpp##b##(x, y) \
485 1.6 uch int x, y; \
486 1.6 uch { \
487 1.6 uch struct tx3912video_chip *vc = &tx3912video_chip; \
488 1.6 uch u_int32_t addr; \
489 1.6 uch addr = vc->vc_fbaddr + (((y * vc->vc_fbwidth + x) * \
490 1.6 uch vc->vc_fbdepth) >> 3); \
491 1.6 uch BPP##b; \
492 1.6 uch }
493 1.6 uch
494 1.6 uch static void linebpp_unimpl __P((int, int, int, int));
495 1.6 uch static void dotbpp_unimpl __P((int, int));
496 1.6 uch static
497 1.6 uch void linebpp_unimpl(x0, y0, x1, y1)
498 1.6 uch int x0, y0, x1, y1;
499 1.6 uch {
500 1.6 uch return;
501 1.6 uch }
502 1.6 uch static
503 1.6 uch void dotbpp_unimpl(x, y)
504 1.6 uch int x, y;
505 1.6 uch {
506 1.6 uch return;
507 1.6 uch }
508 1.6 uch
509 1.6 uch LINEFUNC(2)
510 1.6 uch LINEFUNC(4)
511 1.6 uch LINEFUNC(8)
512 1.6 uch DOTFUNC(2)
513 1.6 uch DOTFUNC(4)
514 1.6 uch DOTFUNC(8)
515 1.6 uch
516 1.6 uch void
517 1.6 uch tx3912video_attach_drawfunc(vc)
518 1.6 uch struct tx3912video_chip *vc;
519 1.6 uch {
520 1.6 uch switch (vc->vc_fbdepth) {
521 1.6 uch default:
522 1.6 uch vc->vc_drawline = linebpp_unimpl;
523 1.6 uch vc->vc_drawdot = dotbpp_unimpl;
524 1.6 uch break;
525 1.6 uch case 8:
526 1.6 uch vc->vc_drawline = linebpp8;
527 1.6 uch vc->vc_drawdot = dotbpp8;
528 1.6 uch break;
529 1.6 uch case 4:
530 1.6 uch vc->vc_drawline = linebpp4;
531 1.6 uch vc->vc_drawdot = dotbpp4;
532 1.6 uch break;
533 1.6 uch case 2:
534 1.6 uch vc->vc_drawline = linebpp2;
535 1.6 uch vc->vc_drawdot = dotbpp2;
536 1.6 uch break;
537 1.6 uch }
538 1.6 uch }
539 1.6 uch
540 1.6 uch void
541 1.6 uch tx3912video_line(x0, y0, x1, y1)
542 1.6 uch int x0, y0, x1, y1;
543 1.6 uch {
544 1.6 uch struct tx3912video_chip *vc = &tx3912video_chip;
545 1.6 uch vc->vc_drawline(x0, y0, x1, y1);
546 1.6 uch }
547 1.6 uch
548 1.6 uch void
549 1.6 uch tx3912video_dot(x, y)
550 1.6 uch int x, y;
551 1.6 uch {
552 1.6 uch struct tx3912video_chip *vc = &tx3912video_chip;
553 1.6 uch vc->vc_drawdot(x, y);
554 1.6 uch }
555