tx3912video.c revision 1.7 1 1.7 uch /* $NetBSD: tx3912video.c,v 1.7 2000/01/07 15:10:50 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.7 uch txreg_t reg;
170 1.1 uch
171 1.1 uch /* Inquire bit depth */
172 1.1 uch fb_depth = tx3912video_fbdepth(tc, 0);
173 1.7 uch
174 1.7 uch switch (fb_depth) {
175 1.7 uch case 2:
176 1.7 uch bootinfo->fb_type = BIFB_D2_M2L_0;
177 1.7 uch break;
178 1.7 uch case 4:
179 1.7 uch /* XXX should implement rasops4.c */
180 1.7 uch fb_depth = 2;
181 1.7 uch bootinfo->fb_type = BIFB_D2_M2L_0;
182 1.7 uch reg = tx_conf_read(tc, TX3912_VIDEOCTRL1_REG);
183 1.7 uch TX3912_VIDEOCTRL1_BITSEL_CLR(reg);
184 1.7 uch reg = TX3912_VIDEOCTRL1_BITSEL_SET(
185 1.7 uch reg, TX3912_VIDEOCTRL1_BITSEL_2BITGREYSCALE);
186 1.7 uch tx_conf_write(tc, TX3912_VIDEOCTRL1_REG, reg);
187 1.7 uch break;
188 1.7 uch case 8:
189 1.7 uch bootinfo->fb_type = BIFB_D8_FF;
190 1.7 uch break;
191 1.7 uch }
192 1.7 uch
193 1.6 uch tx3912video_chip.vc_fbdepth = fb_depth;
194 1.6 uch tx3912video_chip.vc_fbwidth = fb_width;
195 1.6 uch tx3912video_chip.vc_fbheight= fb_height;
196 1.7 uch
197 1.1 uch
198 1.1 uch /* Allocate framebuffer area */
199 1.1 uch if (tx3912video_framebuffer_alloc(tc, fb_start, fb_width, fb_height,
200 1.1 uch fb_depth, &addr, &size)) {
201 1.1 uch return 1;
202 1.1 uch }
203 1.1 uch #if notyet
204 1.1 uch tx3912video_resolution_init(tc, fb_width, fb_height);
205 1.1 uch #else
206 1.1 uch /* Use Windows CE setting. */
207 1.1 uch #endif
208 1.1 uch /* Set DMA transfer address to VID module */
209 1.1 uch tx3912video_framebuffer_init(tc, addr, size);
210 1.1 uch
211 1.1 uch /* Syncronize framebuffer addr to frame signal */
212 1.1 uch tx3912video_reset(tc);
213 1.1 uch
214 1.1 uch *fb_line_bytes = (fb_width * fb_depth) / 8;
215 1.1 uch *fb_addr = addr; /* Phsical address */
216 1.1 uch *fb_size = size;
217 1.1 uch
218 1.1 uch return 0;
219 1.1 uch }
220 1.1 uch
221 1.1 uch int
222 1.1 uch tx3912video_framebuffer_alloc(tc, start, h, v, depth, fb_addr, fb_size)
223 1.1 uch tx_chipset_tag_t tc;
224 1.1 uch u_int32_t start;
225 1.1 uch int h, v, depth;
226 1.1 uch u_int32_t *fb_addr, *fb_size;
227 1.1 uch {
228 1.1 uch struct extent_fixed ex_fixed[2];
229 1.1 uch struct extent *ex;
230 1.1 uch u_long addr, size;
231 1.1 uch int err;
232 1.1 uch
233 1.1 uch /* Calcurate frame buffer size */
234 1.1 uch size = (h * v * depth) / 8;
235 1.1 uch
236 1.1 uch /* Allocate V-RAM area */
237 1.1 uch if (!(ex = extent_create("Frame buffer address", start,
238 1.1 uch start + TX3912_FRAMEBUFFER_MAX,
239 1.1 uch 0, (caddr_t)ex_fixed, sizeof ex_fixed,
240 1.1 uch EX_NOWAIT))) {
241 1.1 uch return 1;
242 1.1 uch }
243 1.1 uch if((err = extent_alloc_subregion(ex, start, start + size, size,
244 1.1 uch TX3912_FRAMEBUFFER_ALIGNMENT,
245 1.1 uch TX3912_FRAMEBUFFER_BOUNDARY,
246 1.1 uch EX_FAST|EX_NOWAIT, &addr))) {
247 1.1 uch return 1;
248 1.1 uch }
249 1.6 uch tx3912video_chip.vc_fbaddr = addr;
250 1.6 uch tx3912video_chip.vc_fbsize = size;
251 1.6 uch
252 1.1 uch *fb_addr = addr;
253 1.1 uch *fb_size = size;
254 1.1 uch
255 1.1 uch return 0;
256 1.1 uch }
257 1.1 uch
258 1.1 uch void
259 1.1 uch tx3912video_framebuffer_init(tc, fb_addr, fb_size)
260 1.1 uch tx_chipset_tag_t tc;
261 1.1 uch u_int32_t fb_addr, fb_size;
262 1.1 uch {
263 1.1 uch u_int32_t reg, vaddr, bank, base;
264 1.1 uch
265 1.1 uch /* XXX currently I don't set DFVAL, so force DF signal toggled on
266 1.1 uch * XXX each frame. */
267 1.1 uch reg = tx_conf_read(tc, TX3912_VIDEOCTRL1_REG);
268 1.1 uch reg &= ~TX3912_VIDEOCTRL1_DFMODE;
269 1.1 uch tx_conf_write(tc, TX3912_VIDEOCTRL1_REG, reg);
270 1.1 uch
271 1.1 uch /* Set DMA transfer start and end address */
272 1.1 uch
273 1.1 uch bank = TX3912_VIDEOCTRL3_VIDBANK(fb_addr);
274 1.1 uch base = TX3912_VIDEOCTRL3_VIDBASEHI(fb_addr);
275 1.1 uch reg = TX3912_VIDEOCTRL3_VIDBANK_SET(0, bank);
276 1.1 uch /* Upper address counter */
277 1.1 uch reg = TX3912_VIDEOCTRL3_VIDBASEHI_SET(reg, base);
278 1.1 uch tx_conf_write(tc, TX3912_VIDEOCTRL3_REG, reg);
279 1.1 uch
280 1.1 uch /* Lower address counter */
281 1.1 uch base = TX3912_VIDEOCTRL4_VIDBASELO(fb_addr + fb_size);
282 1.1 uch reg = TX3912_VIDEOCTRL4_VIDBASELO_SET(0, base);
283 1.1 uch
284 1.1 uch /* Set DF-signal rate */
285 1.1 uch reg = TX3912_VIDEOCTRL4_DFVAL_SET(reg, 0); /* XXX not yet*/
286 1.1 uch
287 1.1 uch /* Set VIDDONE signal delay after FRAME signal */
288 1.1 uch /* XXX not yet*/
289 1.1 uch tx_conf_write(tc, TX3912_VIDEOCTRL4_REG, reg);
290 1.1 uch
291 1.1 uch /* Clear frame buffer */
292 1.1 uch vaddr = MIPS_PHYS_TO_KSEG1(fb_addr);
293 1.1 uch bzero((void*)vaddr, fb_size);
294 1.1 uch }
295 1.1 uch
296 1.1 uch void
297 1.1 uch tx3912video_resolution_init(tc, h, v)
298 1.1 uch tx_chipset_tag_t tc;
299 1.1 uch int h;
300 1.1 uch int v;
301 1.1 uch {
302 1.1 uch u_int32_t reg, val;
303 1.1 uch int split, bit8, horzval, lineval;
304 1.1 uch
305 1.1 uch reg = tx_conf_read(tc, TX3912_VIDEOCTRL1_REG);
306 1.1 uch split = reg & TX3912_VIDEOCTRL1_DISPSPLIT;
307 1.1 uch bit8 = (TX3912_VIDEOCTRL1_BITSEL(reg) ==
308 1.1 uch TX3912_VIDEOCTRL1_BITSEL_8BITCOLOR);
309 1.1 uch val = TX3912_VIDEOCTRL1_BITSEL(reg);
310 1.1 uch
311 1.1 uch if ((val == TX3912_VIDEOCTRL1_BITSEL_8BITCOLOR) &&
312 1.1 uch !split) {
313 1.3 uch /* (LCD horizontal pixels / 8bit) * RGB - 1 */
314 1.3 uch horzval = (h / 8) * 3 - 1;
315 1.1 uch } else {
316 1.1 uch horzval = h / 4 - 1;
317 1.1 uch }
318 1.1 uch lineval = (split ? v / 2 : v) - 1;
319 1.1 uch
320 1.1 uch /* Video rate */
321 1.3 uch /* XXX
322 1.3 uch * probably This value should be determined from DFINT and LCDINT
323 1.3 uch */
324 1.1 uch reg = TX3912_VIDEOCTRL2_VIDRATE_SET(0, horzval + 1);
325 1.1 uch /* Horizontal size of LCD */
326 1.1 uch reg = TX3912_VIDEOCTRL2_HORZVAL_SET(reg, horzval);
327 1.1 uch /* # of lines for the LCD */
328 1.1 uch reg = TX3912_VIDEOCTRL2_LINEVAL_SET(reg, lineval);
329 1.1 uch
330 1.1 uch tx_conf_write(tc, TX3912_VIDEOCTRL2_REG, reg);
331 1.1 uch }
332 1.1 uch
333 1.6 uch int
334 1.1 uch tx3912video_fbdepth(tc, verbose)
335 1.1 uch tx_chipset_tag_t tc;
336 1.1 uch int verbose;
337 1.1 uch {
338 1.1 uch u_int32_t reg, val;
339 1.1 uch
340 1.1 uch reg = tx_conf_read(tc, TX3912_VIDEOCTRL1_REG);
341 1.1 uch val = TX3912_VIDEOCTRL1_BITSEL(reg);
342 1.1 uch switch (val) {
343 1.1 uch case TX3912_VIDEOCTRL1_BITSEL_8BITCOLOR:
344 1.1 uch if (verbose)
345 1.1 uch printf("8bit color");
346 1.1 uch return 8;
347 1.1 uch case TX3912_VIDEOCTRL1_BITSEL_4BITGREYSCALE:
348 1.1 uch if (verbose)
349 1.1 uch printf("4bit greyscale");
350 1.1 uch return 4;
351 1.1 uch case TX3912_VIDEOCTRL1_BITSEL_2BITGREYSCALE:
352 1.1 uch if (verbose)
353 1.1 uch printf("2bit greyscale");
354 1.1 uch return 2;
355 1.1 uch case TX3912_VIDEOCTRL1_BITSEL_MONOCHROME:
356 1.1 uch if (verbose)
357 1.1 uch printf("monochrome");
358 1.1 uch return 1;
359 1.1 uch }
360 1.1 uch return 0;
361 1.1 uch }
362 1.1 uch
363 1.1 uch void
364 1.1 uch tx3912video_reset(tc)
365 1.1 uch tx_chipset_tag_t tc;
366 1.1 uch {
367 1.1 uch u_int32_t reg;
368 1.1 uch
369 1.1 uch reg = tx_conf_read(tc, TX3912_VIDEOCTRL1_REG);
370 1.3 uch
371 1.1 uch /* Disable video logic at end of this frame */
372 1.1 uch reg |= TX3912_VIDEOCTRL1_ENFREEZEFRAME;
373 1.1 uch tx_conf_write(tc, TX3912_VIDEOCTRL1_REG, reg);
374 1.3 uch
375 1.1 uch /* Wait for end of frame */
376 1.1 uch delay(300 * 1000);
377 1.3 uch
378 1.1 uch /* Make sure to disable video logic */
379 1.1 uch reg &= ~TX3912_VIDEOCTRL1_ENVID;
380 1.1 uch tx_conf_write(tc, TX3912_VIDEOCTRL1_REG, reg);
381 1.3 uch
382 1.1 uch delay(1000);
383 1.3 uch
384 1.1 uch /* Enable video logic again */
385 1.1 uch reg &= ~TX3912_VIDEOCTRL1_ENFREEZEFRAME;
386 1.1 uch reg |= TX3912_VIDEOCTRL1_ENVID;
387 1.1 uch tx_conf_write(tc, TX3912_VIDEOCTRL1_REG, reg);
388 1.3 uch
389 1.1 uch delay(1000);
390 1.1 uch }
391 1.1 uch
392 1.6 uch /*
393 1.6 uch * Debug routines.
394 1.6 uch */
395 1.6 uch
396 1.6 uch void
397 1.6 uch tx3912video_calibration_pattern()
398 1.6 uch {
399 1.6 uch struct tx3912video_chip *vc = &tx3912video_chip;
400 1.6 uch int x, y;
401 1.6 uch
402 1.6 uch x = vc->vc_fbwidth - 40;
403 1.6 uch y = vc->vc_fbheight - 40;
404 1.6 uch tx3912video_line(40, 40, x , 40);
405 1.6 uch tx3912video_line(x , 40, x , y );
406 1.6 uch tx3912video_line(x , y , 40, y );
407 1.6 uch tx3912video_line(40, y , 40, 40);
408 1.6 uch tx3912video_line(40, 40, x , y );
409 1.6 uch tx3912video_line(x, 40, 40, y );
410 1.6 uch }
411 1.6 uch
412 1.6 uch #define BPP2 ({ \
413 1.6 uch u_int8_t bitmap; \
414 1.6 uch bitmap = *(volatile u_int8_t*)MIPS_PHYS_TO_KSEG1(addr); \
415 1.6 uch *(volatile u_int8_t*)MIPS_PHYS_TO_KSEG1(addr) = \
416 1.6 uch (bitmap & ~(0x3 << ((3 - (x % 4)) * 2))); \
417 1.6 uch })
418 1.6 uch
419 1.6 uch #define BPP4 ({ \
420 1.6 uch u_int8_t bitmap; \
421 1.6 uch bitmap = *(volatile u_int8_t*)MIPS_PHYS_TO_KSEG1(addr); \
422 1.6 uch *(volatile u_int8_t*)MIPS_PHYS_TO_KSEG1(addr) = \
423 1.6 uch (bitmap & ~(0xf << ((1 - (x % 2)) * 4))); \
424 1.6 uch })
425 1.6 uch
426 1.6 uch #define BPP8 ({ \
427 1.6 uch *(volatile u_int8_t*)MIPS_PHYS_TO_KSEG1(addr) = 0xff; \
428 1.6 uch })
429 1.6 uch
430 1.6 uch #define BRESENHAM(a, b, c, d, func) ({ \
431 1.6 uch u_int32_t fbaddr = vc->vc_fbaddr; \
432 1.6 uch u_int32_t fbwidth = vc->vc_fbwidth; \
433 1.6 uch u_int32_t fbdepth = vc->vc_fbdepth; \
434 1.6 uch len = a, step = b -1; \
435 1.6 uch if (step == 0) \
436 1.6 uch return; \
437 1.6 uch kstep = len == 0 ? 0 : 1; \
438 1.6 uch for (i = k = 0, j = step / 2; i <= step; i++) { \
439 1.6 uch x = xbase c; \
440 1.6 uch y = ybase d; \
441 1.6 uch addr = fbaddr + (((y * fbwidth + x) * fbdepth) >> 3); \
442 1.6 uch func; \
443 1.6 uch j -= len; \
444 1.6 uch while (j < 0) { \
445 1.6 uch j += step; \
446 1.6 uch k += kstep; \
447 1.6 uch } \
448 1.6 uch } \
449 1.6 uch })
450 1.6 uch
451 1.6 uch #define DRAWLINE(func) ({ \
452 1.6 uch if (x < 0) { \
453 1.6 uch if (y < 0) { \
454 1.6 uch if (_y < _x) { \
455 1.6 uch BRESENHAM(_y, _x, -i, -k, func); \
456 1.6 uch } else { \
457 1.6 uch BRESENHAM(_x, _y, -k, -i, func); \
458 1.6 uch } \
459 1.6 uch } else { \
460 1.6 uch if (_y < _x) { \
461 1.6 uch BRESENHAM(_y, _x, -i, +k, func); \
462 1.6 uch } else { \
463 1.6 uch BRESENHAM(_x, _y, -k, +i, func); \
464 1.6 uch } \
465 1.6 uch } \
466 1.6 uch } else { \
467 1.6 uch if (y < 0) { \
468 1.6 uch if (_y < _x) { \
469 1.6 uch BRESENHAM(_y, _x, +i, -k, func); \
470 1.6 uch } else { \
471 1.6 uch BRESENHAM(_x, _y, +k, -i, func); \
472 1.6 uch } \
473 1.6 uch } else { \
474 1.6 uch if (_y < _x) { \
475 1.6 uch BRESENHAM(_y, _x, +i, +k, func); \
476 1.6 uch } else { \
477 1.6 uch BRESENHAM(_x, _y, +k, +i, func); \
478 1.6 uch } \
479 1.6 uch } \
480 1.6 uch } \
481 1.6 uch })
482 1.6 uch
483 1.6 uch #define LINEFUNC(b) \
484 1.6 uch static void linebpp##b __P((int, int, int, int)); \
485 1.6 uch static void \
486 1.6 uch linebpp##b##(x0, y0, x1, y1) \
487 1.6 uch int x0, y0, x1, y1; \
488 1.6 uch { \
489 1.6 uch struct tx3912video_chip *vc = &tx3912video_chip; \
490 1.6 uch u_int32_t addr; \
491 1.6 uch int i, j, k, len, step, kstep; \
492 1.6 uch int x, _x, y, _y; \
493 1.6 uch int xbase, ybase; \
494 1.6 uch x = x1 - x0; \
495 1.6 uch y = y1 - y0; \
496 1.6 uch _x = abs(x); \
497 1.6 uch _y = abs(y); \
498 1.6 uch xbase = x0; \
499 1.6 uch ybase = y0; \
500 1.6 uch DRAWLINE(BPP##b##); \
501 1.6 uch }
502 1.1 uch
503 1.6 uch #define DOTFUNC(b) \
504 1.6 uch static void dotbpp##b __P((int, int)); \
505 1.6 uch static void \
506 1.6 uch dotbpp##b##(x, y) \
507 1.6 uch int x, y; \
508 1.6 uch { \
509 1.6 uch struct tx3912video_chip *vc = &tx3912video_chip; \
510 1.6 uch u_int32_t addr; \
511 1.6 uch addr = vc->vc_fbaddr + (((y * vc->vc_fbwidth + x) * \
512 1.6 uch vc->vc_fbdepth) >> 3); \
513 1.6 uch BPP##b; \
514 1.6 uch }
515 1.6 uch
516 1.6 uch static void linebpp_unimpl __P((int, int, int, int));
517 1.6 uch static void dotbpp_unimpl __P((int, int));
518 1.6 uch static
519 1.6 uch void linebpp_unimpl(x0, y0, x1, y1)
520 1.6 uch int x0, y0, x1, y1;
521 1.6 uch {
522 1.6 uch return;
523 1.6 uch }
524 1.6 uch static
525 1.6 uch void dotbpp_unimpl(x, y)
526 1.6 uch int x, y;
527 1.6 uch {
528 1.6 uch return;
529 1.6 uch }
530 1.6 uch
531 1.6 uch LINEFUNC(2)
532 1.6 uch LINEFUNC(4)
533 1.6 uch LINEFUNC(8)
534 1.6 uch DOTFUNC(2)
535 1.6 uch DOTFUNC(4)
536 1.6 uch DOTFUNC(8)
537 1.6 uch
538 1.6 uch void
539 1.6 uch tx3912video_attach_drawfunc(vc)
540 1.6 uch struct tx3912video_chip *vc;
541 1.6 uch {
542 1.6 uch switch (vc->vc_fbdepth) {
543 1.6 uch default:
544 1.6 uch vc->vc_drawline = linebpp_unimpl;
545 1.6 uch vc->vc_drawdot = dotbpp_unimpl;
546 1.6 uch break;
547 1.6 uch case 8:
548 1.6 uch vc->vc_drawline = linebpp8;
549 1.6 uch vc->vc_drawdot = dotbpp8;
550 1.6 uch break;
551 1.6 uch case 4:
552 1.6 uch vc->vc_drawline = linebpp4;
553 1.6 uch vc->vc_drawdot = dotbpp4;
554 1.6 uch break;
555 1.6 uch case 2:
556 1.6 uch vc->vc_drawline = linebpp2;
557 1.6 uch vc->vc_drawdot = dotbpp2;
558 1.6 uch break;
559 1.6 uch }
560 1.6 uch }
561 1.6 uch
562 1.6 uch void
563 1.6 uch tx3912video_line(x0, y0, x1, y1)
564 1.6 uch int x0, y0, x1, y1;
565 1.6 uch {
566 1.6 uch struct tx3912video_chip *vc = &tx3912video_chip;
567 1.6 uch vc->vc_drawline(x0, y0, x1, y1);
568 1.6 uch }
569 1.6 uch
570 1.6 uch void
571 1.6 uch tx3912video_dot(x, y)
572 1.6 uch int x, y;
573 1.6 uch {
574 1.6 uch struct tx3912video_chip *vc = &tx3912video_chip;
575 1.6 uch vc->vc_drawdot(x, y);
576 1.6 uch }
577