tx3912video.c revision 1.9 1 1.9 sato /* $NetBSD: tx3912video.c,v 1.9 2000/04/03 03:35:38 sato 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.8 uch #include "hpcfb.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.8 uch #if NHPCFB > 0
44 1.9 sato #include <dev/wscons/wsconsio.h>
45 1.8 uch #include <arch/hpcmips/dev/hpcfbvar.h>
46 1.8 uch #include <arch/hpcmips/dev/hpcfbio.h>
47 1.8 uch #include <arch/hpcmips/dev/bivideovar.h>
48 1.2 uch #endif
49 1.8 uch #include <machine/autoconf.h> /* XXX */
50 1.2 uch
51 1.6 uch #undef TX3912VIDEO_DEBUG
52 1.6 uch
53 1.3 uch void tx3912video_framebuffer_init __P((tx_chipset_tag_t, u_int32_t,
54 1.3 uch u_int32_t));
55 1.3 uch int tx3912video_framebuffer_alloc __P((tx_chipset_tag_t, u_int32_t,
56 1.3 uch int, int, int, u_int32_t*,
57 1.3 uch u_int32_t*));
58 1.1 uch void tx3912video_reset __P((tx_chipset_tag_t));
59 1.1 uch void tx3912video_resolution_init __P((tx_chipset_tag_t, int, int));
60 1.1 uch int tx3912video_fbdepth __P((tx_chipset_tag_t, int));
61 1.1 uch
62 1.1 uch int tx3912video_match __P((struct device*, struct cfdata*, void*));
63 1.1 uch void tx3912video_attach __P((struct device*, struct device*, void*));
64 1.1 uch int tx3912video_print __P((void*, const char*));
65 1.1 uch
66 1.6 uch struct tx3912video_chip {
67 1.6 uch u_int32_t vc_fbaddr;
68 1.6 uch u_int32_t vc_fbsize;
69 1.6 uch int vc_fbdepth;
70 1.6 uch int vc_fbwidth;
71 1.6 uch int vc_fbheight;
72 1.6 uch
73 1.6 uch void (*vc_drawline) __P((int, int, int, int));
74 1.6 uch void (*vc_drawdot) __P((int, int));
75 1.6 uch };
76 1.6 uch
77 1.1 uch struct tx3912video_softc {
78 1.1 uch struct device sc_dev;
79 1.6 uch
80 1.6 uch struct tx3912video_chip *sc_chip;
81 1.1 uch };
82 1.1 uch
83 1.1 uch struct fb_attach_args {
84 1.1 uch const char *fba_name;
85 1.1 uch };
86 1.1 uch
87 1.1 uch struct cfattach tx3912video_ca = {
88 1.3 uch sizeof(struct tx3912video_softc), tx3912video_match,
89 1.3 uch tx3912video_attach
90 1.1 uch };
91 1.1 uch
92 1.6 uch /* console */
93 1.6 uch struct tx3912video_chip tx3912video_chip;
94 1.6 uch
95 1.6 uch void tx3912video_attach_drawfunc __P((struct tx3912video_chip*));
96 1.6 uch
97 1.1 uch int
98 1.1 uch tx3912video_match(parent, cf, aux)
99 1.1 uch struct device *parent;
100 1.1 uch struct cfdata *cf;
101 1.1 uch void *aux;
102 1.1 uch {
103 1.1 uch return 1;
104 1.1 uch }
105 1.1 uch
106 1.1 uch void
107 1.1 uch tx3912video_attach(parent, self, aux)
108 1.1 uch struct device *parent;
109 1.1 uch struct device *self;
110 1.1 uch void *aux;
111 1.1 uch {
112 1.1 uch struct txsim_attach_args *ta = aux;
113 1.1 uch struct tx3912video_softc *sc = (void*)self;
114 1.1 uch tx_chipset_tag_t tc = ta->ta_tc;
115 1.8 uch struct mainbus_attach_args ma; /* XXX */
116 1.4 uch txreg_t reg;
117 1.1 uch
118 1.6 uch sc->sc_chip = &tx3912video_chip;
119 1.5 uch
120 1.5 uch printf(": ");
121 1.1 uch tx3912video_fbdepth(tc, 1);
122 1.6 uch printf(", frame buffer 0x%08x-0x%08x", sc->sc_chip->vc_fbaddr,
123 1.6 uch sc->sc_chip->vc_fbaddr + sc->sc_chip->vc_fbsize);
124 1.4 uch
125 1.5 uch printf("\n");
126 1.5 uch
127 1.6 uch #ifndef TX3912VIDEO_DEBUG
128 1.4 uch if (bootinfo->bi_cnuse & BI_CNUSE_SERIAL) {
129 1.5 uch printf("%s: power off\n", sc->sc_dev.dv_xname);
130 1.4 uch reg = tx_conf_read(tc, TX3912_VIDEOCTRL1_REG);
131 1.4 uch reg &= ~(TX3912_VIDEOCTRL1_DISPON |
132 1.4 uch TX3912_VIDEOCTRL1_ENVID);
133 1.4 uch tx_conf_write(tc, TX3912_VIDEOCTRL1_REG, reg);
134 1.4 uch }
135 1.6 uch #endif /* TX3912VIDEO_DEBUG */
136 1.6 uch
137 1.6 uch /* attach debug draw routine */
138 1.6 uch tx3912video_attach_drawfunc(sc->sc_chip);
139 1.1 uch
140 1.1 uch /* Attach frame buffer device */
141 1.8 uch #if NHPCFB > 0
142 1.2 uch if (!(bootinfo->bi_cnuse & BI_CNUSE_SERIAL)) {
143 1.8 uch if (hpcfb_cnattach(0, 0, 0, 0)) {
144 1.2 uch panic("tx3912video_attach: can't init fb console");
145 1.2 uch }
146 1.2 uch }
147 1.8 uch ma.ma_name = "bivideo"; /* XXX */
148 1.8 uch config_found(self, &ma, tx3912video_print);
149 1.2 uch #endif
150 1.1 uch }
151 1.1 uch
152 1.1 uch int
153 1.1 uch tx3912video_print(aux, pnp)
154 1.1 uch void *aux;
155 1.1 uch const char *pnp;
156 1.1 uch {
157 1.1 uch return pnp ? QUIET : UNCONF;
158 1.1 uch }
159 1.1 uch
160 1.1 uch int
161 1.1 uch tx3912video_init(tc, fb_start, fb_width, fb_height, fb_addr, fb_size,
162 1.1 uch fb_line_bytes)
163 1.1 uch tx_chipset_tag_t tc;
164 1.1 uch u_int32_t fb_start; /* Physical address */
165 1.1 uch int fb_width, fb_height;
166 1.1 uch u_int32_t *fb_addr, *fb_size;
167 1.1 uch int *fb_line_bytes;
168 1.1 uch {
169 1.1 uch u_int32_t addr, size;
170 1.1 uch int fb_depth;
171 1.7 uch txreg_t reg;
172 1.1 uch
173 1.1 uch /* Inquire bit depth */
174 1.1 uch fb_depth = tx3912video_fbdepth(tc, 0);
175 1.7 uch
176 1.7 uch switch (fb_depth) {
177 1.7 uch case 2:
178 1.7 uch bootinfo->fb_type = BIFB_D2_M2L_0;
179 1.7 uch break;
180 1.7 uch case 4:
181 1.7 uch /* XXX should implement rasops4.c */
182 1.7 uch fb_depth = 2;
183 1.7 uch bootinfo->fb_type = BIFB_D2_M2L_0;
184 1.7 uch reg = tx_conf_read(tc, TX3912_VIDEOCTRL1_REG);
185 1.7 uch TX3912_VIDEOCTRL1_BITSEL_CLR(reg);
186 1.7 uch reg = TX3912_VIDEOCTRL1_BITSEL_SET(
187 1.7 uch reg, TX3912_VIDEOCTRL1_BITSEL_2BITGREYSCALE);
188 1.7 uch tx_conf_write(tc, TX3912_VIDEOCTRL1_REG, reg);
189 1.7 uch break;
190 1.7 uch case 8:
191 1.7 uch bootinfo->fb_type = BIFB_D8_FF;
192 1.7 uch break;
193 1.7 uch }
194 1.7 uch
195 1.6 uch tx3912video_chip.vc_fbdepth = fb_depth;
196 1.6 uch tx3912video_chip.vc_fbwidth = fb_width;
197 1.6 uch tx3912video_chip.vc_fbheight= fb_height;
198 1.7 uch
199 1.1 uch
200 1.1 uch /* Allocate framebuffer area */
201 1.1 uch if (tx3912video_framebuffer_alloc(tc, fb_start, fb_width, fb_height,
202 1.1 uch fb_depth, &addr, &size)) {
203 1.1 uch return 1;
204 1.1 uch }
205 1.1 uch #if notyet
206 1.1 uch tx3912video_resolution_init(tc, fb_width, fb_height);
207 1.1 uch #else
208 1.1 uch /* Use Windows CE setting. */
209 1.1 uch #endif
210 1.1 uch /* Set DMA transfer address to VID module */
211 1.1 uch tx3912video_framebuffer_init(tc, addr, size);
212 1.1 uch
213 1.1 uch /* Syncronize framebuffer addr to frame signal */
214 1.1 uch tx3912video_reset(tc);
215 1.1 uch
216 1.1 uch *fb_line_bytes = (fb_width * fb_depth) / 8;
217 1.1 uch *fb_addr = addr; /* Phsical address */
218 1.1 uch *fb_size = size;
219 1.1 uch
220 1.1 uch return 0;
221 1.1 uch }
222 1.1 uch
223 1.1 uch int
224 1.1 uch tx3912video_framebuffer_alloc(tc, start, h, v, depth, fb_addr, fb_size)
225 1.1 uch tx_chipset_tag_t tc;
226 1.1 uch u_int32_t start;
227 1.1 uch int h, v, depth;
228 1.1 uch u_int32_t *fb_addr, *fb_size;
229 1.1 uch {
230 1.1 uch struct extent_fixed ex_fixed[2];
231 1.1 uch struct extent *ex;
232 1.1 uch u_long addr, size;
233 1.1 uch int err;
234 1.1 uch
235 1.1 uch /* Calcurate frame buffer size */
236 1.1 uch size = (h * v * depth) / 8;
237 1.1 uch
238 1.1 uch /* Allocate V-RAM area */
239 1.1 uch if (!(ex = extent_create("Frame buffer address", start,
240 1.1 uch start + TX3912_FRAMEBUFFER_MAX,
241 1.1 uch 0, (caddr_t)ex_fixed, sizeof ex_fixed,
242 1.1 uch EX_NOWAIT))) {
243 1.1 uch return 1;
244 1.1 uch }
245 1.1 uch if((err = extent_alloc_subregion(ex, start, start + size, size,
246 1.1 uch TX3912_FRAMEBUFFER_ALIGNMENT,
247 1.1 uch TX3912_FRAMEBUFFER_BOUNDARY,
248 1.1 uch EX_FAST|EX_NOWAIT, &addr))) {
249 1.1 uch return 1;
250 1.1 uch }
251 1.6 uch tx3912video_chip.vc_fbaddr = addr;
252 1.6 uch tx3912video_chip.vc_fbsize = size;
253 1.6 uch
254 1.1 uch *fb_addr = addr;
255 1.1 uch *fb_size = size;
256 1.1 uch
257 1.1 uch return 0;
258 1.1 uch }
259 1.1 uch
260 1.1 uch void
261 1.1 uch tx3912video_framebuffer_init(tc, fb_addr, fb_size)
262 1.1 uch tx_chipset_tag_t tc;
263 1.1 uch u_int32_t fb_addr, fb_size;
264 1.1 uch {
265 1.1 uch u_int32_t reg, vaddr, bank, base;
266 1.1 uch
267 1.1 uch /* XXX currently I don't set DFVAL, so force DF signal toggled on
268 1.1 uch * XXX each frame. */
269 1.1 uch reg = tx_conf_read(tc, TX3912_VIDEOCTRL1_REG);
270 1.1 uch reg &= ~TX3912_VIDEOCTRL1_DFMODE;
271 1.1 uch tx_conf_write(tc, TX3912_VIDEOCTRL1_REG, reg);
272 1.1 uch
273 1.1 uch /* Set DMA transfer start and end address */
274 1.1 uch
275 1.1 uch bank = TX3912_VIDEOCTRL3_VIDBANK(fb_addr);
276 1.1 uch base = TX3912_VIDEOCTRL3_VIDBASEHI(fb_addr);
277 1.1 uch reg = TX3912_VIDEOCTRL3_VIDBANK_SET(0, bank);
278 1.1 uch /* Upper address counter */
279 1.1 uch reg = TX3912_VIDEOCTRL3_VIDBASEHI_SET(reg, base);
280 1.1 uch tx_conf_write(tc, TX3912_VIDEOCTRL3_REG, reg);
281 1.1 uch
282 1.1 uch /* Lower address counter */
283 1.1 uch base = TX3912_VIDEOCTRL4_VIDBASELO(fb_addr + fb_size);
284 1.1 uch reg = TX3912_VIDEOCTRL4_VIDBASELO_SET(0, base);
285 1.1 uch
286 1.1 uch /* Set DF-signal rate */
287 1.1 uch reg = TX3912_VIDEOCTRL4_DFVAL_SET(reg, 0); /* XXX not yet*/
288 1.1 uch
289 1.1 uch /* Set VIDDONE signal delay after FRAME signal */
290 1.1 uch /* XXX not yet*/
291 1.1 uch tx_conf_write(tc, TX3912_VIDEOCTRL4_REG, reg);
292 1.1 uch
293 1.1 uch /* Clear frame buffer */
294 1.1 uch vaddr = MIPS_PHYS_TO_KSEG1(fb_addr);
295 1.1 uch bzero((void*)vaddr, fb_size);
296 1.1 uch }
297 1.1 uch
298 1.1 uch void
299 1.1 uch tx3912video_resolution_init(tc, h, v)
300 1.1 uch tx_chipset_tag_t tc;
301 1.1 uch int h;
302 1.1 uch int v;
303 1.1 uch {
304 1.1 uch u_int32_t reg, val;
305 1.1 uch int split, bit8, horzval, lineval;
306 1.1 uch
307 1.1 uch reg = tx_conf_read(tc, TX3912_VIDEOCTRL1_REG);
308 1.1 uch split = reg & TX3912_VIDEOCTRL1_DISPSPLIT;
309 1.1 uch bit8 = (TX3912_VIDEOCTRL1_BITSEL(reg) ==
310 1.1 uch TX3912_VIDEOCTRL1_BITSEL_8BITCOLOR);
311 1.1 uch val = TX3912_VIDEOCTRL1_BITSEL(reg);
312 1.1 uch
313 1.1 uch if ((val == TX3912_VIDEOCTRL1_BITSEL_8BITCOLOR) &&
314 1.1 uch !split) {
315 1.3 uch /* (LCD horizontal pixels / 8bit) * RGB - 1 */
316 1.3 uch horzval = (h / 8) * 3 - 1;
317 1.1 uch } else {
318 1.1 uch horzval = h / 4 - 1;
319 1.1 uch }
320 1.1 uch lineval = (split ? v / 2 : v) - 1;
321 1.1 uch
322 1.1 uch /* Video rate */
323 1.3 uch /* XXX
324 1.3 uch * probably This value should be determined from DFINT and LCDINT
325 1.3 uch */
326 1.1 uch reg = TX3912_VIDEOCTRL2_VIDRATE_SET(0, horzval + 1);
327 1.1 uch /* Horizontal size of LCD */
328 1.1 uch reg = TX3912_VIDEOCTRL2_HORZVAL_SET(reg, horzval);
329 1.1 uch /* # of lines for the LCD */
330 1.1 uch reg = TX3912_VIDEOCTRL2_LINEVAL_SET(reg, lineval);
331 1.1 uch
332 1.1 uch tx_conf_write(tc, TX3912_VIDEOCTRL2_REG, reg);
333 1.1 uch }
334 1.1 uch
335 1.6 uch int
336 1.1 uch tx3912video_fbdepth(tc, verbose)
337 1.1 uch tx_chipset_tag_t tc;
338 1.1 uch int verbose;
339 1.1 uch {
340 1.1 uch u_int32_t reg, val;
341 1.1 uch
342 1.1 uch reg = tx_conf_read(tc, TX3912_VIDEOCTRL1_REG);
343 1.1 uch val = TX3912_VIDEOCTRL1_BITSEL(reg);
344 1.1 uch switch (val) {
345 1.1 uch case TX3912_VIDEOCTRL1_BITSEL_8BITCOLOR:
346 1.1 uch if (verbose)
347 1.1 uch printf("8bit color");
348 1.1 uch return 8;
349 1.1 uch case TX3912_VIDEOCTRL1_BITSEL_4BITGREYSCALE:
350 1.1 uch if (verbose)
351 1.1 uch printf("4bit greyscale");
352 1.1 uch return 4;
353 1.1 uch case TX3912_VIDEOCTRL1_BITSEL_2BITGREYSCALE:
354 1.1 uch if (verbose)
355 1.1 uch printf("2bit greyscale");
356 1.1 uch return 2;
357 1.1 uch case TX3912_VIDEOCTRL1_BITSEL_MONOCHROME:
358 1.1 uch if (verbose)
359 1.1 uch printf("monochrome");
360 1.1 uch return 1;
361 1.1 uch }
362 1.1 uch return 0;
363 1.1 uch }
364 1.1 uch
365 1.1 uch void
366 1.1 uch tx3912video_reset(tc)
367 1.1 uch tx_chipset_tag_t tc;
368 1.1 uch {
369 1.1 uch u_int32_t reg;
370 1.1 uch
371 1.1 uch reg = tx_conf_read(tc, TX3912_VIDEOCTRL1_REG);
372 1.3 uch
373 1.1 uch /* Disable video logic at end of this frame */
374 1.1 uch reg |= TX3912_VIDEOCTRL1_ENFREEZEFRAME;
375 1.1 uch tx_conf_write(tc, TX3912_VIDEOCTRL1_REG, reg);
376 1.3 uch
377 1.1 uch /* Wait for end of frame */
378 1.1 uch delay(300 * 1000);
379 1.3 uch
380 1.1 uch /* Make sure to disable video logic */
381 1.1 uch reg &= ~TX3912_VIDEOCTRL1_ENVID;
382 1.1 uch tx_conf_write(tc, TX3912_VIDEOCTRL1_REG, reg);
383 1.3 uch
384 1.1 uch delay(1000);
385 1.3 uch
386 1.1 uch /* Enable video logic again */
387 1.1 uch reg &= ~TX3912_VIDEOCTRL1_ENFREEZEFRAME;
388 1.1 uch reg |= TX3912_VIDEOCTRL1_ENVID;
389 1.1 uch tx_conf_write(tc, TX3912_VIDEOCTRL1_REG, reg);
390 1.3 uch
391 1.1 uch delay(1000);
392 1.1 uch }
393 1.1 uch
394 1.6 uch /*
395 1.6 uch * Debug routines.
396 1.6 uch */
397 1.6 uch
398 1.6 uch void
399 1.6 uch tx3912video_calibration_pattern()
400 1.6 uch {
401 1.6 uch struct tx3912video_chip *vc = &tx3912video_chip;
402 1.6 uch int x, y;
403 1.6 uch
404 1.6 uch x = vc->vc_fbwidth - 40;
405 1.6 uch y = vc->vc_fbheight - 40;
406 1.6 uch tx3912video_line(40, 40, x , 40);
407 1.6 uch tx3912video_line(x , 40, x , y );
408 1.6 uch tx3912video_line(x , y , 40, y );
409 1.6 uch tx3912video_line(40, y , 40, 40);
410 1.6 uch tx3912video_line(40, 40, x , y );
411 1.6 uch tx3912video_line(x, 40, 40, y );
412 1.6 uch }
413 1.6 uch
414 1.6 uch #define BPP2 ({ \
415 1.6 uch u_int8_t bitmap; \
416 1.6 uch bitmap = *(volatile u_int8_t*)MIPS_PHYS_TO_KSEG1(addr); \
417 1.6 uch *(volatile u_int8_t*)MIPS_PHYS_TO_KSEG1(addr) = \
418 1.6 uch (bitmap & ~(0x3 << ((3 - (x % 4)) * 2))); \
419 1.6 uch })
420 1.6 uch
421 1.6 uch #define BPP4 ({ \
422 1.6 uch u_int8_t bitmap; \
423 1.6 uch bitmap = *(volatile u_int8_t*)MIPS_PHYS_TO_KSEG1(addr); \
424 1.6 uch *(volatile u_int8_t*)MIPS_PHYS_TO_KSEG1(addr) = \
425 1.6 uch (bitmap & ~(0xf << ((1 - (x % 2)) * 4))); \
426 1.6 uch })
427 1.6 uch
428 1.6 uch #define BPP8 ({ \
429 1.6 uch *(volatile u_int8_t*)MIPS_PHYS_TO_KSEG1(addr) = 0xff; \
430 1.6 uch })
431 1.6 uch
432 1.6 uch #define BRESENHAM(a, b, c, d, func) ({ \
433 1.6 uch u_int32_t fbaddr = vc->vc_fbaddr; \
434 1.6 uch u_int32_t fbwidth = vc->vc_fbwidth; \
435 1.6 uch u_int32_t fbdepth = vc->vc_fbdepth; \
436 1.6 uch len = a, step = b -1; \
437 1.6 uch if (step == 0) \
438 1.6 uch return; \
439 1.6 uch kstep = len == 0 ? 0 : 1; \
440 1.6 uch for (i = k = 0, j = step / 2; i <= step; i++) { \
441 1.6 uch x = xbase c; \
442 1.6 uch y = ybase d; \
443 1.6 uch addr = fbaddr + (((y * fbwidth + x) * fbdepth) >> 3); \
444 1.6 uch func; \
445 1.6 uch j -= len; \
446 1.6 uch while (j < 0) { \
447 1.6 uch j += step; \
448 1.6 uch k += kstep; \
449 1.6 uch } \
450 1.6 uch } \
451 1.6 uch })
452 1.6 uch
453 1.6 uch #define DRAWLINE(func) ({ \
454 1.6 uch if (x < 0) { \
455 1.6 uch if (y < 0) { \
456 1.6 uch if (_y < _x) { \
457 1.6 uch BRESENHAM(_y, _x, -i, -k, func); \
458 1.6 uch } else { \
459 1.6 uch BRESENHAM(_x, _y, -k, -i, func); \
460 1.6 uch } \
461 1.6 uch } else { \
462 1.6 uch if (_y < _x) { \
463 1.6 uch BRESENHAM(_y, _x, -i, +k, func); \
464 1.6 uch } else { \
465 1.6 uch BRESENHAM(_x, _y, -k, +i, func); \
466 1.6 uch } \
467 1.6 uch } \
468 1.6 uch } else { \
469 1.6 uch if (y < 0) { \
470 1.6 uch if (_y < _x) { \
471 1.6 uch BRESENHAM(_y, _x, +i, -k, func); \
472 1.6 uch } else { \
473 1.6 uch BRESENHAM(_x, _y, +k, -i, func); \
474 1.6 uch } \
475 1.6 uch } else { \
476 1.6 uch if (_y < _x) { \
477 1.6 uch BRESENHAM(_y, _x, +i, +k, func); \
478 1.6 uch } else { \
479 1.6 uch BRESENHAM(_x, _y, +k, +i, func); \
480 1.6 uch } \
481 1.6 uch } \
482 1.6 uch } \
483 1.6 uch })
484 1.6 uch
485 1.6 uch #define LINEFUNC(b) \
486 1.6 uch static void linebpp##b __P((int, int, int, int)); \
487 1.6 uch static void \
488 1.6 uch linebpp##b##(x0, y0, x1, y1) \
489 1.6 uch int x0, y0, x1, y1; \
490 1.6 uch { \
491 1.6 uch struct tx3912video_chip *vc = &tx3912video_chip; \
492 1.6 uch u_int32_t addr; \
493 1.6 uch int i, j, k, len, step, kstep; \
494 1.6 uch int x, _x, y, _y; \
495 1.6 uch int xbase, ybase; \
496 1.6 uch x = x1 - x0; \
497 1.6 uch y = y1 - y0; \
498 1.6 uch _x = abs(x); \
499 1.6 uch _y = abs(y); \
500 1.6 uch xbase = x0; \
501 1.6 uch ybase = y0; \
502 1.6 uch DRAWLINE(BPP##b##); \
503 1.6 uch }
504 1.1 uch
505 1.6 uch #define DOTFUNC(b) \
506 1.6 uch static void dotbpp##b __P((int, int)); \
507 1.6 uch static void \
508 1.6 uch dotbpp##b##(x, y) \
509 1.6 uch int x, y; \
510 1.6 uch { \
511 1.6 uch struct tx3912video_chip *vc = &tx3912video_chip; \
512 1.6 uch u_int32_t addr; \
513 1.6 uch addr = vc->vc_fbaddr + (((y * vc->vc_fbwidth + x) * \
514 1.6 uch vc->vc_fbdepth) >> 3); \
515 1.6 uch BPP##b; \
516 1.6 uch }
517 1.6 uch
518 1.6 uch static void linebpp_unimpl __P((int, int, int, int));
519 1.6 uch static void dotbpp_unimpl __P((int, int));
520 1.6 uch static
521 1.6 uch void linebpp_unimpl(x0, y0, x1, y1)
522 1.6 uch int x0, y0, x1, y1;
523 1.6 uch {
524 1.6 uch return;
525 1.6 uch }
526 1.6 uch static
527 1.6 uch void dotbpp_unimpl(x, y)
528 1.6 uch int x, y;
529 1.6 uch {
530 1.6 uch return;
531 1.6 uch }
532 1.6 uch
533 1.6 uch LINEFUNC(2)
534 1.6 uch LINEFUNC(4)
535 1.6 uch LINEFUNC(8)
536 1.6 uch DOTFUNC(2)
537 1.6 uch DOTFUNC(4)
538 1.6 uch DOTFUNC(8)
539 1.6 uch
540 1.6 uch void
541 1.6 uch tx3912video_attach_drawfunc(vc)
542 1.6 uch struct tx3912video_chip *vc;
543 1.6 uch {
544 1.6 uch switch (vc->vc_fbdepth) {
545 1.6 uch default:
546 1.6 uch vc->vc_drawline = linebpp_unimpl;
547 1.6 uch vc->vc_drawdot = dotbpp_unimpl;
548 1.6 uch break;
549 1.6 uch case 8:
550 1.6 uch vc->vc_drawline = linebpp8;
551 1.6 uch vc->vc_drawdot = dotbpp8;
552 1.6 uch break;
553 1.6 uch case 4:
554 1.6 uch vc->vc_drawline = linebpp4;
555 1.6 uch vc->vc_drawdot = dotbpp4;
556 1.6 uch break;
557 1.6 uch case 2:
558 1.6 uch vc->vc_drawline = linebpp2;
559 1.6 uch vc->vc_drawdot = dotbpp2;
560 1.6 uch break;
561 1.6 uch }
562 1.6 uch }
563 1.6 uch
564 1.6 uch void
565 1.6 uch tx3912video_line(x0, y0, x1, y1)
566 1.6 uch int x0, y0, x1, y1;
567 1.6 uch {
568 1.6 uch struct tx3912video_chip *vc = &tx3912video_chip;
569 1.6 uch vc->vc_drawline(x0, y0, x1, y1);
570 1.6 uch }
571 1.6 uch
572 1.6 uch void
573 1.6 uch tx3912video_dot(x, y)
574 1.6 uch int x, y;
575 1.6 uch {
576 1.6 uch struct tx3912video_chip *vc = &tx3912video_chip;
577 1.6 uch vc->vc_drawdot(x, y);
578 1.6 uch }
579