plumvideo.c revision 1.12 1 1.12 simonb /* $NetBSD: plumvideo.c,v 1.12 2000/06/26 04:55:41 simonb Exp $ */
2 1.1 uch
3 1.7 uch /*-
4 1.7 uch * Copyright (c) 1999, 2000 UCHIYAMA Yasushi. All rights reserved.
5 1.1 uch *
6 1.1 uch * Redistribution and use in source and binary forms, with or without
7 1.1 uch * modification, are permitted provided that the following conditions
8 1.1 uch * are met:
9 1.1 uch * 1. Redistributions of source code must retain the above copyright
10 1.1 uch * notice, this list of conditions and the following disclaimer.
11 1.7 uch * 2. Redistributions in binary form must reproduce the above copyright
12 1.7 uch * notice, this list of conditions and the following disclaimer in the
13 1.7 uch * documentation and/or other materials provided with the distribution.
14 1.7 uch * 3. The name of the author may not be used to endorse or promote products
15 1.1 uch * derived from this software without specific prior written permission.
16 1.1 uch *
17 1.7 uch * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 1.7 uch * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 1.7 uch * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 1.7 uch * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 1.7 uch * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 1.7 uch * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 1.7 uch * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 1.7 uch * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 1.7 uch * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 1.7 uch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 1.1 uch */
28 1.11 uch #define PLUMVIDEODEBUG
29 1.7 uch
30 1.1 uch #include "opt_tx39_debug.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
36 1.8 uch #include <sys/ioctl.h>
37 1.8 uch #include <sys/buf.h>
38 1.8 uch #include <vm/vm.h>
39 1.8 uch
40 1.2 uch #include <dev/cons.h> /* consdev */
41 1.2 uch
42 1.1 uch #include <machine/bus.h>
43 1.1 uch #include <machine/intr.h>
44 1.1 uch
45 1.1 uch #include <hpcmips/tx/tx39var.h>
46 1.1 uch #include <hpcmips/dev/plumvar.h>
47 1.1 uch #include <hpcmips/dev/plumicuvar.h>
48 1.1 uch #include <hpcmips/dev/plumpowervar.h>
49 1.1 uch #include <hpcmips/dev/plumvideoreg.h>
50 1.1 uch
51 1.2 uch #include <machine/bootinfo.h>
52 1.2 uch
53 1.8 uch #include <dev/wscons/wsdisplayvar.h>
54 1.8 uch #include <dev/rasops/rasops.h>
55 1.8 uch #include <arch/hpcmips/dev/video_subr.h>
56 1.8 uch
57 1.6 sato #include <dev/wscons/wsconsio.h>
58 1.4 uch #include <arch/hpcmips/dev/hpcfbvar.h>
59 1.4 uch #include <arch/hpcmips/dev/hpcfbio.h>
60 1.1 uch
61 1.3 uch #ifdef PLUMVIDEODEBUG
62 1.3 uch int plumvideo_debug = 1;
63 1.3 uch #define DPRINTF(arg) if (plumvideo_debug) printf arg;
64 1.3 uch #define DPRINTFN(n, arg) if (plumvideo_debug > (n)) printf arg;
65 1.3 uch #else
66 1.3 uch #define DPRINTF(arg)
67 1.3 uch #define DPRINTFN(n, arg)
68 1.3 uch #endif
69 1.3 uch
70 1.1 uch struct plumvideo_softc {
71 1.7 uch struct device sc_dev;
72 1.11 uch tx_chipset_tag_t sc_tc;
73 1.11 uch plum_chipset_tag_t sc_pc;
74 1.8 uch
75 1.8 uch /* control register */
76 1.7 uch bus_space_tag_t sc_regt;
77 1.7 uch bus_space_handle_t sc_regh;
78 1.8 uch /* frame buffer */
79 1.8 uch bus_space_tag_t sc_fbiot;
80 1.8 uch bus_space_handle_t sc_fbioh;
81 1.8 uch /* clut buffer (8bpp only) */
82 1.8 uch bus_space_tag_t sc_clutiot;
83 1.8 uch bus_space_handle_t sc_clutioh;
84 1.8 uch /* bitblt */
85 1.8 uch bus_space_tag_t sc_bitbltt;
86 1.8 uch bus_space_handle_t sc_bitblth;
87 1.7 uch
88 1.11 uch struct video_chip sc_chip;
89 1.8 uch struct hpcfb_fbconf sc_fbconf;
90 1.8 uch struct hpcfb_dspconf sc_dspconf;
91 1.1 uch };
92 1.1 uch
93 1.8 uch int plumvideo_match __P((struct device*, struct cfdata*, void*));
94 1.8 uch void plumvideo_attach __P((struct device*, struct device*, void*));
95 1.8 uch
96 1.7 uch int plumvideo_ioctl __P((void *, u_long, caddr_t, int, struct proc *));
97 1.12 simonb paddr_t plumvideo_mmap __P((void *, off_t, int));
98 1.7 uch
99 1.1 uch struct cfattach plumvideo_ca = {
100 1.1 uch sizeof(struct plumvideo_softc), plumvideo_match, plumvideo_attach
101 1.1 uch };
102 1.1 uch
103 1.7 uch struct hpcfb_accessops plumvideo_ha = {
104 1.7 uch plumvideo_ioctl, plumvideo_mmap
105 1.1 uch };
106 1.1 uch
107 1.5 uch int plumvideo_init __P((struct plumvideo_softc*));
108 1.8 uch void plumvideo_hpcfbinit __P((struct plumvideo_softc *));
109 1.8 uch
110 1.8 uch void plumvideo_clut_default __P((struct plumvideo_softc *));
111 1.8 uch void plumvideo_clut_set __P((struct plumvideo_softc *, u_int32_t *, int,
112 1.8 uch int));
113 1.8 uch void plumvideo_clut_get __P((struct plumvideo_softc *, u_int32_t *, int,
114 1.8 uch int));
115 1.8 uch void __plumvideo_clut_access __P((struct plumvideo_softc *,
116 1.8 uch void (*) __P((bus_space_tag_t,
117 1.8 uch bus_space_handle_t))));
118 1.8 uch static void _flush_cache __P((void)) __attribute__((__unused__)); /* !!! */
119 1.8 uch
120 1.3 uch #ifdef PLUMVIDEODEBUG
121 1.1 uch void plumvideo_dump __P((struct plumvideo_softc*));
122 1.3 uch #endif
123 1.1 uch
124 1.1 uch int
125 1.1 uch plumvideo_match(parent, cf, aux)
126 1.1 uch struct device *parent;
127 1.1 uch struct cfdata *cf;
128 1.1 uch void *aux;
129 1.1 uch {
130 1.2 uch /*
131 1.2 uch * VRAM area also uses as UHOSTC shared RAM.
132 1.2 uch */
133 1.8 uch return (2); /* 1st attach group */
134 1.1 uch }
135 1.1 uch
136 1.1 uch void
137 1.1 uch plumvideo_attach(parent, self, aux)
138 1.1 uch struct device *parent;
139 1.1 uch struct device *self;
140 1.1 uch void *aux;
141 1.1 uch {
142 1.1 uch struct plum_attach_args *pa = aux;
143 1.1 uch struct plumvideo_softc *sc = (void*)self;
144 1.7 uch struct hpcfb_attach_args ha;
145 1.7 uch int console;
146 1.1 uch
147 1.1 uch sc->sc_pc = pa->pa_pc;
148 1.1 uch sc->sc_regt = pa->pa_regt;
149 1.8 uch sc->sc_fbiot = sc->sc_clutiot = sc->sc_bitbltt = pa->pa_iot;
150 1.1 uch
151 1.7 uch printf(": ");
152 1.5 uch /*
153 1.5 uch * map register area
154 1.5 uch */
155 1.1 uch if (bus_space_map(sc->sc_regt, PLUM_VIDEO_REGBASE,
156 1.1 uch PLUM_VIDEO_REGSIZE, 0, &sc->sc_regh)) {
157 1.1 uch printf(": register map failed\n");
158 1.1 uch return;
159 1.1 uch }
160 1.2 uch
161 1.2 uch /*
162 1.2 uch * Power control
163 1.2 uch */
164 1.3 uch #ifndef PLUMVIDEODEBUG
165 1.3 uch if (bootinfo->bi_cnuse & BI_CNUSE_SERIAL) {
166 1.3 uch /* LCD power on and display off */
167 1.3 uch plum_power_disestablish(sc->sc_pc, PLUM_PWR_LCD);
168 1.3 uch /* power off V-RAM */
169 1.3 uch plum_power_disestablish(sc->sc_pc, PLUM_PWR_EXTPW2);
170 1.3 uch /* power off LCD */
171 1.3 uch plum_power_disestablish(sc->sc_pc, PLUM_PWR_EXTPW1);
172 1.3 uch /* power off RAMDAC */
173 1.3 uch plum_power_disestablish(sc->sc_pc, PLUM_PWR_EXTPW0);
174 1.3 uch /* back-light off */
175 1.3 uch plum_power_disestablish(sc->sc_pc, PLUM_PWR_BKL);
176 1.3 uch } else
177 1.3 uch #endif
178 1.3 uch {
179 1.3 uch /* LCD power on and display on */
180 1.3 uch plum_power_establish(sc->sc_pc, PLUM_PWR_LCD);
181 1.3 uch /* supply power to V-RAM */
182 1.3 uch plum_power_establish(sc->sc_pc, PLUM_PWR_EXTPW2);
183 1.3 uch /* supply power to LCD */
184 1.3 uch plum_power_establish(sc->sc_pc, PLUM_PWR_EXTPW1);
185 1.3 uch /* back-light on */
186 1.3 uch plum_power_establish(sc->sc_pc, PLUM_PWR_BKL);
187 1.3 uch }
188 1.2 uch
189 1.2 uch /*
190 1.5 uch * Initialize LCD controller
191 1.5 uch * map V-RAM area.
192 1.5 uch * reinstall bootinfo structure.
193 1.5 uch * some OHCI shared-buffer hack. XXX
194 1.2 uch */
195 1.5 uch if (plumvideo_init(sc) != 0)
196 1.5 uch return;
197 1.5 uch
198 1.5 uch printf("\n");
199 1.2 uch
200 1.11 uch /* Attach frame buffer device */
201 1.11 uch plumvideo_hpcfbinit(sc);
202 1.11 uch
203 1.3 uch #ifdef PLUMVIDEODEBUG
204 1.11 uch if (plumvideo_debug > 1)
205 1.3 uch plumvideo_dump(sc);
206 1.11 uch /* attach debug draw routine (debugging use) */
207 1.11 uch video_attach_drawfunc(&sc->sc_chip);
208 1.11 uch tx_conf_register_video(sc->sc_pc->pc_tc, &sc->sc_chip);
209 1.11 uch #endif /* PLUMVIDEODEBUG */
210 1.3 uch
211 1.7 uch console = cn_tab ? 0 : 1;
212 1.7 uch if(console && hpcfb_cnattach(&sc->sc_fbconf) != 0) {
213 1.2 uch panic("plumvideo_attach: can't init fb console");
214 1.2 uch }
215 1.7 uch
216 1.7 uch ha.ha_console = console;
217 1.7 uch ha.ha_accessops = &plumvideo_ha;
218 1.7 uch ha.ha_accessctx = sc;
219 1.7 uch ha.ha_curfbconf = 0;
220 1.7 uch ha.ha_nfbconf = 1;
221 1.7 uch ha.ha_fbconflist = &sc->sc_fbconf;
222 1.7 uch ha.ha_curdspconf = 0;
223 1.7 uch ha.ha_ndspconf = 1;
224 1.7 uch ha.ha_dspconflist = &sc->sc_dspconf;
225 1.7 uch
226 1.7 uch config_found(self, &ha, hpcfbprint);
227 1.1 uch }
228 1.1 uch
229 1.7 uch void
230 1.7 uch plumvideo_hpcfbinit(sc)
231 1.7 uch struct plumvideo_softc *sc;
232 1.7 uch {
233 1.7 uch struct hpcfb_fbconf *fb = &sc->sc_fbconf;
234 1.11 uch struct video_chip *chip = &sc->sc_chip;
235 1.8 uch vaddr_t fbvaddr = (vaddr_t)sc->sc_fbioh;
236 1.11 uch int height = chip->vc_fbheight;
237 1.11 uch int width = chip->vc_fbwidth;
238 1.11 uch int depth = chip->vc_fbdepth;
239 1.7 uch
240 1.7 uch memset(fb, 0, sizeof(struct hpcfb_fbconf));
241 1.7 uch
242 1.7 uch fb->hf_conf_index = 0; /* configuration index */
243 1.7 uch fb->hf_nconfs = 1; /* how many configurations */
244 1.8 uch strncpy(fb->hf_name, "PLUM built-in video", HPCFB_MAXNAMELEN);
245 1.8 uch /* frame buffer name */
246 1.8 uch strncpy(fb->hf_conf_name, "LCD", HPCFB_MAXNAMELEN);
247 1.8 uch /* configuration name */
248 1.11 uch fb->hf_height = height;
249 1.11 uch fb->hf_width = width;
250 1.7 uch fb->hf_baseaddr = mips_ptob(mips_btop(fbvaddr));
251 1.7 uch fb->hf_offset = (u_long)fbvaddr - fb->hf_baseaddr;
252 1.8 uch /* frame buffer start offset */
253 1.11 uch fb->hf_bytes_per_line = (width * depth) / NBBY;
254 1.7 uch fb->hf_nplanes = 1;
255 1.11 uch fb->hf_bytes_per_plane = height * fb->hf_bytes_per_line;
256 1.7 uch
257 1.7 uch fb->hf_access_flags |= HPCFB_ACCESS_BYTE;
258 1.7 uch fb->hf_access_flags |= HPCFB_ACCESS_WORD;
259 1.7 uch fb->hf_access_flags |= HPCFB_ACCESS_DWORD;
260 1.7 uch
261 1.11 uch switch (depth) {
262 1.7 uch default:
263 1.7 uch panic("plumvideo_hpcfbinit: not supported color depth\n");
264 1.7 uch /* NOTREACHED */
265 1.7 uch case 16:
266 1.7 uch fb->hf_class = HPCFB_CLASS_RGBCOLOR;
267 1.7 uch fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
268 1.7 uch fb->hf_pack_width = 16;
269 1.7 uch fb->hf_pixels_per_pack = 1;
270 1.7 uch fb->hf_pixel_width = 16;
271 1.7 uch
272 1.7 uch fb->hf_class_data_length = sizeof(struct hf_rgb_tag);
273 1.8 uch /* reserved for future use */
274 1.8 uch fb->hf_u.hf_rgb.hf_flags = 0;
275 1.7 uch
276 1.7 uch fb->hf_u.hf_rgb.hf_red_width = 5;
277 1.7 uch fb->hf_u.hf_rgb.hf_red_shift = 11;
278 1.7 uch fb->hf_u.hf_rgb.hf_green_width = 6;
279 1.7 uch fb->hf_u.hf_rgb.hf_green_shift = 5;
280 1.7 uch fb->hf_u.hf_rgb.hf_blue_width = 5;
281 1.7 uch fb->hf_u.hf_rgb.hf_blue_shift = 0;
282 1.7 uch fb->hf_u.hf_rgb.hf_alpha_width = 0;
283 1.7 uch fb->hf_u.hf_rgb.hf_alpha_shift = 0;
284 1.7 uch break;
285 1.7 uch
286 1.7 uch case 8:
287 1.7 uch fb->hf_class = HPCFB_CLASS_INDEXCOLOR;
288 1.7 uch fb->hf_access_flags |= HPCFB_ACCESS_STATIC;
289 1.7 uch fb->hf_pack_width = 8;
290 1.7 uch fb->hf_pixels_per_pack = 1;
291 1.7 uch fb->hf_pixel_width = 8;
292 1.7 uch fb->hf_class_data_length = sizeof(struct hf_indexed_tag);
293 1.8 uch /* reserved for future use */
294 1.8 uch fb->hf_u.hf_indexed.hf_flags = 0;
295 1.7 uch break;
296 1.7 uch }
297 1.1 uch }
298 1.1 uch
299 1.5 uch int
300 1.5 uch plumvideo_init(sc)
301 1.1 uch struct plumvideo_softc *sc;
302 1.1 uch {
303 1.1 uch bus_space_tag_t regt = sc->sc_regt;
304 1.1 uch bus_space_handle_t regh = sc->sc_regh;
305 1.1 uch plumreg_t reg;
306 1.5 uch size_t vram_size;
307 1.11 uch int bpp, width, height, vram_pitch;
308 1.11 uch struct video_chip *chip = &sc->sc_chip;
309 1.11 uch
310 1.11 uch chip->vc_v = sc->sc_pc->pc_tc;
311 1.8 uch #if notyet
312 1.8 uch /* map BitBlt area */
313 1.8 uch if (bus_space_map(sc->sc_bitbltt,
314 1.8 uch PLUM_VIDEO_BITBLT_IOBASE,
315 1.8 uch PLUM_VIDEO_BITBLT_IOSIZE, 0,
316 1.8 uch &sc->sc_bitblth)) {
317 1.8 uch printf(": BitBlt map failed\n");
318 1.8 uch return (1);
319 1.8 uch }
320 1.8 uch #endif
321 1.1 uch reg = plum_conf_read(regt, regh, PLUM_VIDEO_PLGMD_REG);
322 1.8 uch switch (reg & PLUM_VIDEO_PLGMD_GMODE_MASK) {
323 1.5 uch case PLUM_VIDEO_PLGMD_16BPP:
324 1.5 uch #ifdef PLUM_BIG_OHCI_BUFFER
325 1.5 uch printf("(16bpp disabled) ");
326 1.5 uch /* FALLTHROUGH */
327 1.5 uch #else /* PLUM_BIG_OHCI_BUFFER */
328 1.5 uch bpp = 16;
329 1.5 uch break;
330 1.5 uch #endif /* PLUM_BIG_OHCI_BUFFER */
331 1.1 uch default:
332 1.5 uch bootinfo->fb_type = BIFB_D8_FF; /* over ride */
333 1.8 uch reg &= ~PLUM_VIDEO_PLGMD_GMODE_MASK;
334 1.8 uch plum_conf_write(regt, regh, PLUM_VIDEO_PLGMD_REG, reg);
335 1.5 uch reg |= PLUM_VIDEO_PLGMD_8BPP;
336 1.1 uch plum_conf_write(regt, regh, PLUM_VIDEO_PLGMD_REG, reg);
337 1.8 uch #if notyet
338 1.8 uch /* change BitBlt color depth */
339 1.8 uch plum_conf_write(sc->sc_bitbltt, sc->sc_bitblth, 0x8, 0);
340 1.8 uch #endif
341 1.1 uch /* FALLTHROUGH */
342 1.1 uch case PLUM_VIDEO_PLGMD_8BPP:
343 1.5 uch bpp = 8;
344 1.5 uch break;
345 1.5 uch }
346 1.11 uch chip->vc_fbdepth = bpp;
347 1.10 uch
348 1.10 uch /*
349 1.10 uch * Get display size from WindowsCE setted.
350 1.10 uch */
351 1.11 uch chip->vc_fbwidth = width = bootinfo->fb_width =
352 1.10 uch plum_conf_read(regt, regh, PLUM_VIDEO_PLHPX_REG) + 1;
353 1.11 uch chip->vc_fbheight = height = bootinfo->fb_height =
354 1.10 uch plum_conf_read(regt, regh, PLUM_VIDEO_PLVT_REG) -
355 1.10 uch plum_conf_read(regt, regh, PLUM_VIDEO_PLVDS_REG);
356 1.5 uch
357 1.5 uch /*
358 1.5 uch * set line byte length to bootinfo and LCD controller.
359 1.5 uch */
360 1.11 uch bootinfo->fb_line_bytes = (width * bpp) / NBBY;
361 1.5 uch
362 1.11 uch vram_pitch = width / (8 / bpp);
363 1.5 uch plum_conf_write(regt, regh, PLUM_VIDEO_PLPIT1_REG, vram_pitch);
364 1.5 uch plum_conf_write(regt, regh, PLUM_VIDEO_PLPIT2_REG,
365 1.5 uch vram_pitch & PLUM_VIDEO_PLPIT2_MASK);
366 1.5 uch plum_conf_write(regt, regh, PLUM_VIDEO_PLOFS_REG, vram_pitch);
367 1.5 uch
368 1.5 uch /*
369 1.8 uch * boot messages and map CLUT(if any).
370 1.5 uch */
371 1.5 uch printf("display mode: ");
372 1.8 uch switch (bpp) {
373 1.8 uch default:
374 1.5 uch printf("disabled ");
375 1.5 uch break;
376 1.8 uch case 8:
377 1.5 uch printf("8bpp ");
378 1.8 uch /* map CLUT area */
379 1.8 uch if (bus_space_map(sc->sc_clutiot,
380 1.8 uch PLUM_VIDEO_CLUT_LCD_IOBASE,
381 1.8 uch PLUM_VIDEO_CLUT_LCD_IOSIZE, 0,
382 1.8 uch &sc->sc_clutioh)) {
383 1.8 uch printf(": CLUT map failed\n");
384 1.8 uch return (1);
385 1.8 uch }
386 1.8 uch /* install default CLUT */
387 1.8 uch plumvideo_clut_default(sc);
388 1.1 uch break;
389 1.8 uch case 16:
390 1.5 uch printf("16bpp ");
391 1.1 uch break;
392 1.1 uch }
393 1.1 uch
394 1.5 uch /*
395 1.5 uch * calcurate frame buffer size.
396 1.5 uch */
397 1.5 uch reg = plum_conf_read(regt, regh, PLUM_VIDEO_PLGMD_REG);
398 1.11 uch vram_size = (width * height * bpp) / NBBY;
399 1.5 uch vram_size = mips_round_page(vram_size);
400 1.11 uch chip->vc_fbsize = vram_size;
401 1.5 uch
402 1.5 uch /*
403 1.5 uch * map V-RAM area.
404 1.5 uch */
405 1.8 uch if (bus_space_map(sc->sc_fbiot, PLUM_VIDEO_VRAM_IOBASE,
406 1.8 uch vram_size, 0, &sc->sc_fbioh)) {
407 1.5 uch printf(": V-RAM map failed\n");
408 1.5 uch return (1);
409 1.5 uch }
410 1.5 uch
411 1.8 uch bootinfo->fb_addr = (unsigned char *)sc->sc_fbioh;
412 1.11 uch chip->vc_fbvaddr = (vaddr_t)sc->sc_fbioh;
413 1.11 uch chip->vc_fbpaddr = PLUM_VIDEO_VRAM_IOBASE_PHYSICAL;
414 1.5 uch
415 1.5 uch return (0);
416 1.7 uch }
417 1.7 uch
418 1.7 uch int
419 1.7 uch plumvideo_ioctl(v, cmd, data, flag, p)
420 1.7 uch void *v;
421 1.7 uch u_long cmd;
422 1.7 uch caddr_t data;
423 1.7 uch int flag;
424 1.7 uch struct proc *p;
425 1.7 uch {
426 1.7 uch struct plumvideo_softc *sc = (struct plumvideo_softc *)v;
427 1.7 uch struct hpcfb_fbconf *fbconf;
428 1.7 uch struct hpcfb_dspconf *dspconf;
429 1.8 uch struct wsdisplay_cmap *cmap;
430 1.8 uch u_int8_t *r, *g, *b;
431 1.8 uch u_int32_t *rgb;
432 1.8 uch int idx, cnt, error;
433 1.7 uch
434 1.7 uch switch (cmd) {
435 1.7 uch case WSDISPLAYIO_GETCMAP:
436 1.8 uch cmap = (struct wsdisplay_cmap*)data;
437 1.8 uch cnt = cmap->count;
438 1.8 uch idx = cmap->index;
439 1.8 uch
440 1.8 uch if (sc->sc_fbconf.hf_class != HPCFB_CLASS_INDEXCOLOR ||
441 1.8 uch sc->sc_fbconf.hf_pack_width != 8 ||
442 1.8 uch !LEGAL_CLUT_INDEX(idx) ||
443 1.8 uch !LEGAL_CLUT_INDEX(idx + cnt -1)) {
444 1.8 uch return (EINVAL);
445 1.8 uch }
446 1.8 uch
447 1.8 uch if (!uvm_useracc(cmap->red, cnt, B_WRITE) ||
448 1.8 uch !uvm_useracc(cmap->green, cnt, B_WRITE) ||
449 1.8 uch !uvm_useracc(cmap->blue, cnt, B_WRITE)) {
450 1.8 uch return (EFAULT);
451 1.8 uch }
452 1.8 uch
453 1.8 uch error = cmap_work_alloc(&r, &g, &b, &rgb, cnt);
454 1.8 uch if (error != 0) {
455 1.8 uch cmap_work_free(r, g, b, rgb);
456 1.8 uch return (ENOMEM);
457 1.8 uch }
458 1.8 uch plumvideo_clut_get(sc, rgb, idx, cnt);
459 1.8 uch rgb24_decompose(rgb, r, g, b, cnt);
460 1.8 uch
461 1.8 uch copyout(r, cmap->red, cnt);
462 1.8 uch copyout(g, cmap->green,cnt);
463 1.8 uch copyout(b, cmap->blue, cnt);
464 1.8 uch
465 1.8 uch cmap_work_free(r, g, b, rgb);
466 1.8 uch
467 1.8 uch return (0);
468 1.7 uch
469 1.7 uch case WSDISPLAYIO_PUTCMAP:
470 1.8 uch cmap = (struct wsdisplay_cmap*)data;
471 1.8 uch cnt = cmap->count;
472 1.8 uch idx = cmap->index;
473 1.8 uch
474 1.8 uch if (sc->sc_fbconf.hf_class != HPCFB_CLASS_INDEXCOLOR ||
475 1.8 uch sc->sc_fbconf.hf_pack_width != 8 ||
476 1.8 uch !LEGAL_CLUT_INDEX(idx) ||
477 1.8 uch !LEGAL_CLUT_INDEX(idx + cnt -1)) {
478 1.8 uch return (EINVAL);
479 1.8 uch }
480 1.8 uch
481 1.8 uch if (!uvm_useracc(cmap->red, cnt, B_WRITE) ||
482 1.8 uch !uvm_useracc(cmap->green, cnt, B_WRITE) ||
483 1.8 uch !uvm_useracc(cmap->blue, cnt, B_WRITE)) {
484 1.8 uch return (EFAULT);
485 1.8 uch }
486 1.8 uch
487 1.8 uch error = cmap_work_alloc(&r, &g, &b, &rgb, cnt);
488 1.8 uch if (error != 0) {
489 1.8 uch cmap_work_free(r, g, b, rgb);
490 1.8 uch return (ENOMEM);
491 1.8 uch }
492 1.8 uch rgb24_compose(rgb, r, g, b, cnt);
493 1.8 uch plumvideo_clut_set(sc, rgb, idx, cnt);
494 1.8 uch
495 1.8 uch cmap_work_free(r, g, b, rgb);
496 1.8 uch
497 1.9 uch return (0);
498 1.7 uch
499 1.7 uch case HPCFBIO_GCONF:
500 1.7 uch fbconf = (struct hpcfb_fbconf *)data;
501 1.7 uch if (fbconf->hf_conf_index != 0 &&
502 1.7 uch fbconf->hf_conf_index != HPCFB_CURRENT_CONFIG) {
503 1.7 uch return (EINVAL);
504 1.7 uch }
505 1.7 uch *fbconf = sc->sc_fbconf; /* structure assignment */
506 1.7 uch return (0);
507 1.7 uch
508 1.7 uch case HPCFBIO_SCONF:
509 1.7 uch fbconf = (struct hpcfb_fbconf *)data;
510 1.7 uch if (fbconf->hf_conf_index != 0 &&
511 1.7 uch fbconf->hf_conf_index != HPCFB_CURRENT_CONFIG) {
512 1.7 uch return (EINVAL);
513 1.7 uch }
514 1.7 uch /*
515 1.7 uch * nothing to do because we have only one configration
516 1.7 uch */
517 1.7 uch return (0);
518 1.7 uch
519 1.7 uch case HPCFBIO_GDSPCONF:
520 1.7 uch dspconf = (struct hpcfb_dspconf *)data;
521 1.7 uch if ((dspconf->hd_unit_index != 0 &&
522 1.7 uch dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) ||
523 1.7 uch (dspconf->hd_conf_index != 0 &&
524 1.7 uch dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) {
525 1.7 uch return (EINVAL);
526 1.7 uch }
527 1.7 uch *dspconf = sc->sc_dspconf; /* structure assignment */
528 1.7 uch return (0);
529 1.7 uch
530 1.7 uch case HPCFBIO_SDSPCONF:
531 1.7 uch dspconf = (struct hpcfb_dspconf *)data;
532 1.7 uch if ((dspconf->hd_unit_index != 0 &&
533 1.7 uch dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) ||
534 1.7 uch (dspconf->hd_conf_index != 0 &&
535 1.7 uch dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) {
536 1.7 uch return (EINVAL);
537 1.7 uch }
538 1.7 uch /*
539 1.7 uch * nothing to do
540 1.7 uch * because we have only one unit and one configration
541 1.7 uch */
542 1.7 uch return (0);
543 1.7 uch
544 1.7 uch case HPCFBIO_GOP:
545 1.7 uch case HPCFBIO_SOP:
546 1.7 uch /* XXX not implemented yet */
547 1.7 uch return (EINVAL);
548 1.7 uch }
549 1.7 uch
550 1.7 uch return (ENOTTY);
551 1.7 uch }
552 1.7 uch
553 1.12 simonb paddr_t
554 1.7 uch plumvideo_mmap(ctx, offset, prot)
555 1.7 uch void *ctx;
556 1.7 uch off_t offset;
557 1.7 uch int prot;
558 1.7 uch {
559 1.7 uch struct plumvideo_softc *sc = (struct plumvideo_softc *)ctx;
560 1.7 uch
561 1.7 uch if (offset < 0 || (sc->sc_fbconf.hf_bytes_per_plane +
562 1.7 uch sc->sc_fbconf.hf_offset) < offset) {
563 1.7 uch return (-1);
564 1.7 uch }
565 1.7 uch
566 1.7 uch return (mips_btop(PLUM_VIDEO_VRAM_IOBASE_PHYSICAL + offset));
567 1.8 uch }
568 1.8 uch
569 1.8 uch void
570 1.8 uch plumvideo_clut_get(sc, rgb, beg, cnt)
571 1.8 uch struct plumvideo_softc *sc;
572 1.8 uch u_int32_t *rgb;
573 1.8 uch int beg, cnt;
574 1.8 uch {
575 1.8 uch static void __plumvideo_clut_get __P((bus_space_tag_t,
576 1.8 uch bus_space_handle_t));
577 1.8 uch static void __plumvideo_clut_get(iot, ioh)
578 1.8 uch bus_space_tag_t iot;
579 1.10 uch bus_space_handle_t ioh;
580 1.8 uch {
581 1.8 uch int i;
582 1.8 uch
583 1.8 uch for (i = 0, beg *= 4; i < cnt; i++, beg += 4) {
584 1.8 uch *rgb++ = bus_space_read_4(iot, ioh, beg) &
585 1.8 uch 0x00ffffff;
586 1.8 uch }
587 1.8 uch }
588 1.8 uch
589 1.8 uch KASSERT(rgb);
590 1.8 uch KASSERT(LEGAL_CLUT_INDEX(beg));
591 1.8 uch KASSERT(LEGAL_CLUT_INDEX(beg + cnt - 1));
592 1.8 uch __plumvideo_clut_access(sc, __plumvideo_clut_get);
593 1.8 uch }
594 1.8 uch
595 1.8 uch void
596 1.8 uch plumvideo_clut_set(sc, rgb, beg, cnt)
597 1.8 uch struct plumvideo_softc *sc;
598 1.8 uch u_int32_t *rgb;
599 1.8 uch int beg, cnt;
600 1.8 uch {
601 1.8 uch static void __plumvideo_clut_set __P((bus_space_tag_t,
602 1.8 uch bus_space_handle_t));
603 1.8 uch static void __plumvideo_clut_set(iot, ioh)
604 1.8 uch bus_space_tag_t iot;
605 1.10 uch bus_space_handle_t ioh;
606 1.8 uch {
607 1.8 uch int i;
608 1.8 uch
609 1.8 uch for (i = 0, beg *= 4; i < cnt; i++, beg +=4) {
610 1.8 uch bus_space_write_4(iot, ioh, beg,
611 1.8 uch *rgb++ & 0x00ffffff);
612 1.8 uch }
613 1.8 uch }
614 1.8 uch
615 1.8 uch KASSERT(rgb);
616 1.8 uch KASSERT(LEGAL_CLUT_INDEX(beg));
617 1.8 uch KASSERT(LEGAL_CLUT_INDEX(beg + cnt - 1));
618 1.8 uch __plumvideo_clut_access(sc, __plumvideo_clut_set);
619 1.8 uch }
620 1.8 uch
621 1.8 uch void
622 1.8 uch plumvideo_clut_default(sc)
623 1.8 uch struct plumvideo_softc *sc;
624 1.8 uch {
625 1.8 uch static void __plumvideo_clut_default __P((bus_space_tag_t,
626 1.8 uch bus_space_handle_t));
627 1.8 uch static void __plumvideo_clut_default(iot, ioh)
628 1.8 uch bus_space_tag_t iot;
629 1.10 uch bus_space_handle_t ioh;
630 1.8 uch {
631 1.8 uch const u_int8_t compo6[6] = { 0, 51, 102, 153, 204, 255 };
632 1.8 uch const u_int32_t ansi_color[16] = {
633 1.8 uch 0x000000, 0xff0000, 0x00ff00, 0xffff00,
634 1.8 uch 0x0000ff, 0xff00ff, 0x00ffff, 0xffffff,
635 1.8 uch 0x000000, 0x800000, 0x008000, 0x808000,
636 1.8 uch 0x000080, 0x800080, 0x008080, 0x808080,
637 1.8 uch };
638 1.8 uch int i, r, g, b;
639 1.8 uch
640 1.8 uch /* ANSI escape sequence */
641 1.8 uch for (i = 0; i < 16; i++) {
642 1.8 uch bus_space_write_4(iot, ioh, i << 2, ansi_color[i]);
643 1.8 uch }
644 1.8 uch /* 16 - 31, gray scale */
645 1.8 uch for ( ; i < 32; i++) {
646 1.8 uch int j = (i - 16) * 17;
647 1.8 uch bus_space_write_4(iot, ioh, i << 2, RGB24(j, j, j));
648 1.8 uch }
649 1.8 uch /* 32 - 247, RGB color */
650 1.8 uch for (r = 0; r < 6; r++) {
651 1.8 uch for (g = 0; g < 6; g++) {
652 1.8 uch for (b = 0; b < 6; b++) {
653 1.8 uch bus_space_write_4(iot, ioh, i << 2,
654 1.8 uch RGB24(compo6[r],
655 1.8 uch compo6[g],
656 1.8 uch compo6[b]));
657 1.8 uch i++;
658 1.8 uch }
659 1.8 uch }
660 1.8 uch }
661 1.8 uch /* 248 - 245, just white */
662 1.8 uch for ( ; i < 256; i++) {
663 1.8 uch bus_space_write_4(iot, ioh, i << 2, 0xffffff);
664 1.8 uch }
665 1.8 uch }
666 1.8 uch
667 1.8 uch __plumvideo_clut_access(sc, __plumvideo_clut_default);
668 1.8 uch }
669 1.8 uch
670 1.8 uch void
671 1.8 uch __plumvideo_clut_access(sc, palette_func)
672 1.8 uch struct plumvideo_softc *sc;
673 1.8 uch void (*palette_func) __P((bus_space_tag_t, bus_space_handle_t));
674 1.8 uch {
675 1.8 uch bus_space_tag_t regt = sc->sc_regt;
676 1.8 uch bus_space_handle_t regh = sc->sc_regh;
677 1.8 uch plumreg_t val, gmode;
678 1.8 uch
679 1.8 uch /* display off */
680 1.8 uch val = bus_space_read_4(regt, regh, PLUM_VIDEO_PLGMD_REG);
681 1.8 uch gmode = val & PLUM_VIDEO_PLGMD_GMODE_MASK;
682 1.8 uch val &= ~PLUM_VIDEO_PLGMD_GMODE_MASK;
683 1.8 uch bus_space_write_4(regt, regh, PLUM_VIDEO_PLGMD_REG, val);
684 1.8 uch
685 1.8 uch /* palette access disable */
686 1.8 uch val &= ~PLUM_VIDEO_PLGMD_PALETTE_ENABLE;
687 1.8 uch bus_space_write_4(regt, regh, PLUM_VIDEO_PLGMD_REG, val);
688 1.8 uch
689 1.8 uch /* change palette mode to CPU */
690 1.8 uch val &= ~PLUM_VIDEO_PLGMD_MODE_DISPLAY;
691 1.8 uch bus_space_write_4(regt, regh, PLUM_VIDEO_PLGMD_REG, val);
692 1.8 uch
693 1.8 uch /* palette access */
694 1.8 uch (*palette_func) (sc->sc_clutiot, sc->sc_clutioh);
695 1.8 uch
696 1.8 uch /* change palette mode to Display */
697 1.8 uch val |= PLUM_VIDEO_PLGMD_MODE_DISPLAY;
698 1.8 uch bus_space_write_4(regt, regh, PLUM_VIDEO_PLGMD_REG, val);
699 1.9 uch
700 1.8 uch /* palette access enable */
701 1.8 uch val |= PLUM_VIDEO_PLGMD_PALETTE_ENABLE;
702 1.8 uch bus_space_write_4(regt, regh, PLUM_VIDEO_PLGMD_REG, val);
703 1.8 uch
704 1.8 uch /* display on */
705 1.8 uch val |= gmode;
706 1.8 uch bus_space_write_4(regt, regh, PLUM_VIDEO_PLGMD_REG, val);
707 1.8 uch }
708 1.8 uch
709 1.8 uch /* !!! */
710 1.8 uch static void
711 1.8 uch _flush_cache()
712 1.8 uch {
713 1.8 uch MachFlushCache();
714 1.1 uch }
715 1.1 uch
716 1.3 uch #ifdef PLUMVIDEODEBUG
717 1.1 uch void
718 1.1 uch plumvideo_dump(sc)
719 1.1 uch struct plumvideo_softc *sc;
720 1.1 uch {
721 1.1 uch bus_space_tag_t regt = sc->sc_regt;
722 1.1 uch bus_space_handle_t regh = sc->sc_regh;
723 1.1 uch
724 1.1 uch plumreg_t reg;
725 1.3 uch int i;
726 1.1 uch
727 1.5 uch for (i = 0; i < 0x160; i += 4) {
728 1.1 uch reg = plum_conf_read(regt, regh, i);
729 1.3 uch printf("0x%03x %08x", i, reg);
730 1.1 uch bitdisp(reg);
731 1.1 uch }
732 1.1 uch }
733 1.3 uch #endif /* PLUMVIDEODEBUG */
734