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