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