1 /* $NetBSD: plumvideo.c,v 1.39 2008/04/28 20:23:21 martin Exp $ */
4 * Copyright (c) 1999-2002 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
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.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: plumvideo.c,v 1.39 2008/04/28 20:23:21 martin Exp $");
37 #include "plumohci.h" /* Plum2 OHCI shared memory allocated on V-RAM */
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/device.h>
44 #include <sys/ioctl.h>
46 #include <uvm/uvm_extern.h>
48 #include <dev/cons.h> /* consdev */
50 #include <mips/cache.h>
52 #include <machine/bus.h>
53 #include <machine/intr.h>
54 #include <machine/config_hook.h>
56 #include <hpcmips/tx/tx39var.h>
57 #include <hpcmips/dev/plumvar.h>
58 #include <hpcmips/dev/plumicuvar.h>
59 #include <hpcmips/dev/plumpowervar.h>
60 #include <hpcmips/dev/plumvideoreg.h>
62 #include <machine/bootinfo.h>
64 #include <dev/wscons/wsdisplayvar.h>
65 #include <dev/rasops/rasops.h>
66 #include <dev/hpc/video_subr.h>
68 #include <dev/wscons/wsconsio.h>
69 #include <dev/hpc/hpcfbvar.h>
70 #include <dev/hpc/hpcfbio.h>
72 #include <dev/hpc/bivideovar.h>
76 int plumvideo_debug
= 1;
77 #define DPRINTF(arg) if (plumvideo_debug) printf arg;
78 #define DPRINTFN(n, arg) if (plumvideo_debug > (n)) printf arg;
81 #define DPRINTFN(n, arg)
84 struct plumvideo_softc
{
86 tx_chipset_tag_t sc_tc
;
87 plum_chipset_tag_t sc_pc
;
89 void *sc_powerhook
; /* power management hook */
94 int sc_max_brightness
;
96 /* control register */
97 bus_space_tag_t sc_regt
;
98 bus_space_handle_t sc_regh
;
100 bus_space_tag_t sc_fbiot
;
101 bus_space_handle_t sc_fbioh
;
102 /* clut buffer (8bpp only) */
103 bus_space_tag_t sc_clutiot
;
104 bus_space_handle_t sc_clutioh
;
106 bus_space_tag_t sc_bitbltt
;
107 bus_space_handle_t sc_bitblth
;
109 struct video_chip sc_chip
;
110 struct hpcfb_fbconf sc_fbconf
;
111 struct hpcfb_dspconf sc_dspconf
;
114 int plumvideo_match(struct device
*, struct cfdata
*, void*);
115 void plumvideo_attach(struct device
*, struct device
*, void*);
117 int plumvideo_ioctl(void *, u_long
, void *, int, struct lwp
*);
118 paddr_t
plumvideo_mmap(void *, off_t
, int);
120 CFATTACH_DECL(plumvideo
, sizeof(struct plumvideo_softc
),
121 plumvideo_match
, plumvideo_attach
, NULL
, NULL
);
123 struct hpcfb_accessops plumvideo_ha
= {
124 plumvideo_ioctl
, plumvideo_mmap
127 int plumvideo_power(void *, int, long, void *);
129 int plumvideo_init(struct plumvideo_softc
*, int *);
130 void plumvideo_hpcfbinit(struct plumvideo_softc
*, int);
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
*, u_int32_t
*, int, int,
136 void (*)(bus_space_tag_t
, bus_space_handle_t
, u_int32_t
*, int, int));
137 static void _flush_cache(void) __attribute__((__unused__
)); /* !!! */
138 static void plumvideo_init_backlight(struct plumvideo_softc
*);
139 static void plumvideo_backlight(struct plumvideo_softc
*, int);
140 static void plumvideo_brightness(struct plumvideo_softc
*, int);
142 #ifdef PLUMVIDEODEBUG
143 void plumvideo_dump(struct plumvideo_softc
*);
150 plumvideo_match(struct device
*parent
, struct cfdata
*cf
, void *aux
)
153 * VRAM area also uses as UHOSTC shared RAM.
155 return (2); /* 1st attach group */
159 plumvideo_attach(struct device
*parent
, struct device
*self
, void *aux
)
161 struct plum_attach_args
*pa
= aux
;
162 struct plumvideo_softc
*sc
= (void*)self
;
163 struct hpcfb_attach_args ha
;
164 int console
, reverse_flag
;
166 sc
->sc_console
= console
= cn_tab
? 0 : 1;
167 sc
->sc_pc
= pa
->pa_pc
;
168 sc
->sc_regt
= pa
->pa_regt
;
169 sc
->sc_fbiot
= sc
->sc_clutiot
= sc
->sc_bitbltt
= pa
->pa_iot
;
173 /* map register area */
174 if (bus_space_map(sc
->sc_regt
, PLUM_VIDEO_REGBASE
,
175 PLUM_VIDEO_REGSIZE
, 0, &sc
->sc_regh
)) {
176 printf("register map failed\n");
180 /* initialize backlight and brightness values */
181 plumvideo_init_backlight(sc
);
184 plumvideo_power(sc
, 0, 0,
185 (void *)(console
? PWR_RESUME
: PWR_SUSPEND
));
186 /* Add a hard power hook to power saving */
187 sc
->sc_powerhook
= config_hook(CONFIG_HOOK_PMEVENT
,
188 CONFIG_HOOK_PMEVENT_HARDPOWER
,
190 plumvideo_power
, sc
);
191 if (sc
->sc_powerhook
== 0)
192 printf("WARNING unable to establish hard power hook");
195 * Initialize LCD controller
197 * reinstall bootinfo structure.
198 * some OHCI shared-buffer hack. XXX
200 if (plumvideo_init(sc
, &reverse_flag
) != 0)
205 /* Attach frame buffer device */
206 plumvideo_hpcfbinit(sc
, reverse_flag
);
208 #ifdef PLUMVIDEODEBUG
209 if (plumvideo_debug
> 0)
211 /* attach debug draw routine (debugging use) */
212 video_attach_drawfunc(&sc
->sc_chip
);
213 tx_conf_register_video(sc
->sc_pc
->pc_tc
, &sc
->sc_chip
);
214 #endif /* PLUMVIDEODEBUG */
216 if(console
&& hpcfb_cnattach(&sc
->sc_fbconf
) != 0) {
217 panic("plumvideo_attach: can't init fb console");
220 ha
.ha_console
= console
;
221 ha
.ha_accessops
= &plumvideo_ha
;
222 ha
.ha_accessctx
= sc
;
225 ha
.ha_fbconflist
= &sc
->sc_fbconf
;
226 ha
.ha_curdspconf
= 0;
228 ha
.ha_dspconflist
= &sc
->sc_dspconf
;
230 config_found(self
, &ha
, hpcfbprint
);
232 /* bivideo is no longer need */
233 bivideo_dont_attach
= 1;
234 #endif /* NBIVIDEO > 0 */
238 plumvideo_hpcfbinit(struct plumvideo_softc
*sc
, int reverse_flag
)
240 struct hpcfb_fbconf
*fb
= &sc
->sc_fbconf
;
241 struct video_chip
*chip
= &sc
->sc_chip
;
242 vaddr_t fbvaddr
= (vaddr_t
)sc
->sc_fbioh
;
243 int height
= chip
->vc_fbheight
;
244 int width
= chip
->vc_fbwidth
;
245 int depth
= chip
->vc_fbdepth
;
247 memset(fb
, 0, sizeof(struct hpcfb_fbconf
));
249 fb
->hf_conf_index
= 0; /* configuration index */
250 fb
->hf_nconfs
= 1; /* how many configurations */
251 strncpy(fb
->hf_name
, "PLUM built-in video", HPCFB_MAXNAMELEN
);
252 /* frame buffer name */
253 strncpy(fb
->hf_conf_name
, "LCD", HPCFB_MAXNAMELEN
);
254 /* configuration name */
255 fb
->hf_height
= height
;
256 fb
->hf_width
= width
;
257 fb
->hf_baseaddr
= (u_long
)fbvaddr
;
258 fb
->hf_offset
= (u_long
)fbvaddr
- mips_ptob(mips_btop(fbvaddr
));
259 /* frame buffer start offset */
260 fb
->hf_bytes_per_line
= (width
* depth
) / NBBY
;
262 fb
->hf_bytes_per_plane
= height
* fb
->hf_bytes_per_line
;
264 fb
->hf_access_flags
|= HPCFB_ACCESS_BYTE
;
265 fb
->hf_access_flags
|= HPCFB_ACCESS_WORD
;
266 fb
->hf_access_flags
|= HPCFB_ACCESS_DWORD
;
268 fb
->hf_access_flags
|= HPCFB_ACCESS_REVERSE
;
272 panic("plumvideo_hpcfbinit: not supported color depth");
275 fb
->hf_class
= HPCFB_CLASS_RGBCOLOR
;
276 fb
->hf_access_flags
|= HPCFB_ACCESS_STATIC
;
277 fb
->hf_pack_width
= 16;
278 fb
->hf_pixels_per_pack
= 1;
279 fb
->hf_pixel_width
= 16;
281 fb
->hf_class_data_length
= sizeof(struct hf_rgb_tag
);
282 /* reserved for future use */
283 fb
->hf_u
.hf_rgb
.hf_flags
= 0;
285 fb
->hf_u
.hf_rgb
.hf_red_width
= 5;
286 fb
->hf_u
.hf_rgb
.hf_red_shift
= 11;
287 fb
->hf_u
.hf_rgb
.hf_green_width
= 6;
288 fb
->hf_u
.hf_rgb
.hf_green_shift
= 5;
289 fb
->hf_u
.hf_rgb
.hf_blue_width
= 5;
290 fb
->hf_u
.hf_rgb
.hf_blue_shift
= 0;
291 fb
->hf_u
.hf_rgb
.hf_alpha_width
= 0;
292 fb
->hf_u
.hf_rgb
.hf_alpha_shift
= 0;
296 fb
->hf_class
= HPCFB_CLASS_INDEXCOLOR
;
297 fb
->hf_access_flags
|= HPCFB_ACCESS_STATIC
;
298 fb
->hf_pack_width
= 8;
299 fb
->hf_pixels_per_pack
= 1;
300 fb
->hf_pixel_width
= 8;
301 fb
->hf_class_data_length
= sizeof(struct hf_indexed_tag
);
302 /* reserved for future use */
303 fb
->hf_u
.hf_indexed
.hf_flags
= 0;
309 plumvideo_init(struct plumvideo_softc
*sc
, int *reverse
)
311 struct video_chip
*chip
= &sc
->sc_chip
;
312 bus_space_tag_t regt
= sc
->sc_regt
;
313 bus_space_handle_t regh
= sc
->sc_regh
;
316 int bpp
, width
, height
, vram_pitch
;
318 *reverse
= video_reverse_color();
319 chip
->vc_v
= sc
->sc_pc
->pc_tc
;
321 /* map BitBlt area */
322 if (bus_space_map(sc
->sc_bitbltt
,
323 PLUM_VIDEO_BITBLT_IOBASE
,
324 PLUM_VIDEO_BITBLT_IOSIZE
, 0,
326 printf(": BitBlt map failed\n");
330 reg
= plum_conf_read(regt
, regh
, PLUM_VIDEO_PLGMD_REG
);
332 switch (reg
& PLUM_VIDEO_PLGMD_GMODE_MASK
) {
333 case PLUM_VIDEO_PLGMD_16BPP
:
334 #if NPLUMOHCI > 0 /* reserve V-RAM area for USB OHCI */
341 bootinfo
->fb_type
= *reverse
? BIFB_D8_FF
: BIFB_D8_00
;
342 reg
&= ~PLUM_VIDEO_PLGMD_GMODE_MASK
;
343 plum_conf_write(regt
, regh
, PLUM_VIDEO_PLGMD_REG
, reg
);
344 reg
|= PLUM_VIDEO_PLGMD_8BPP
;
345 plum_conf_write(regt
, regh
, PLUM_VIDEO_PLGMD_REG
, reg
);
347 /* change BitBlt color depth */
348 plum_conf_write(sc
->sc_bitbltt
, sc
->sc_bitblth
, 0x8, 0);
351 case PLUM_VIDEO_PLGMD_8BPP
:
355 chip
->vc_fbdepth
= bpp
;
358 * Get display size from WindowsCE setted.
360 chip
->vc_fbwidth
= width
= bootinfo
->fb_width
=
361 plum_conf_read(regt
, regh
, PLUM_VIDEO_PLHPX_REG
) + 1;
362 chip
->vc_fbheight
= height
= bootinfo
->fb_height
=
363 plum_conf_read(regt
, regh
, PLUM_VIDEO_PLVT_REG
) -
364 plum_conf_read(regt
, regh
, PLUM_VIDEO_PLVDS_REG
);
367 * set line byte length to bootinfo and LCD controller.
369 vram_pitch
= bootinfo
->fb_line_bytes
= (width
* bpp
) / NBBY
;
370 plum_conf_write(regt
, regh
, PLUM_VIDEO_PLPIT1_REG
, vram_pitch
);
371 plum_conf_write(regt
, regh
, PLUM_VIDEO_PLPIT2_REG
,
372 vram_pitch
& PLUM_VIDEO_PLPIT2_MASK
);
373 plum_conf_write(regt
, regh
, PLUM_VIDEO_PLOFS_REG
, vram_pitch
);
376 * boot messages and map CLUT(if any).
378 printf("display mode: ");
386 if (bus_space_map(sc
->sc_clutiot
,
387 PLUM_VIDEO_CLUT_LCD_IOBASE
,
388 PLUM_VIDEO_CLUT_LCD_IOSIZE
, 0,
390 printf(": CLUT map failed\n");
393 /* install default CLUT */
394 plumvideo_clut_default(sc
);
402 * calcurate frame buffer size.
404 reg
= plum_conf_read(regt
, regh
, PLUM_VIDEO_PLGMD_REG
);
405 vram_size
= (width
* height
* bpp
) / NBBY
;
406 vram_size
= mips_round_page(vram_size
);
407 chip
->vc_fbsize
= vram_size
;
412 if (bus_space_map(sc
->sc_fbiot
, PLUM_VIDEO_VRAM_IOBASE
,
413 vram_size
, 0, &sc
->sc_fbioh
)) {
414 printf(": V-RAM map failed\n");
418 bootinfo
->fb_addr
= (unsigned char *)sc
->sc_fbioh
;
419 chip
->vc_fbvaddr
= (vaddr_t
)sc
->sc_fbioh
;
420 chip
->vc_fbpaddr
= PLUM_VIDEO_VRAM_IOBASE_PHYSICAL
;
426 plumvideo_ioctl(void *v
, u_long cmd
, void *data
, int flag
, struct lwp
*l
)
428 struct plumvideo_softc
*sc
= (struct plumvideo_softc
*)v
;
429 struct hpcfb_fbconf
*fbconf
;
430 struct hpcfb_dspconf
*dspconf
;
431 struct wsdisplay_cmap
*cmap
;
432 struct wsdisplay_param
*dispparam
;
439 case WSDISPLAYIO_GETCMAP
:
440 cmap
= (struct wsdisplay_cmap
*)data
;
444 if (sc
->sc_fbconf
.hf_class
!= HPCFB_CLASS_INDEXCOLOR
||
445 sc
->sc_fbconf
.hf_pack_width
!= 8 ||
446 !LEGAL_CLUT_INDEX(idx
) ||
447 !LEGAL_CLUT_INDEX(idx
+ cnt
- 1)) {
451 error
= cmap_work_alloc(&r
, &g
, &b
, &rgb
, cnt
);
454 plumvideo_clut_get(sc
, rgb
, idx
, cnt
);
455 rgb24_decompose(rgb
, r
, g
, b
, cnt
);
457 error
= copyout(r
, cmap
->red
, cnt
);
460 error
= copyout(g
, cmap
->green
, cnt
);
463 error
= copyout(b
, cmap
->blue
, cnt
);
466 cmap_work_free(r
, g
, b
, rgb
);
469 case WSDISPLAYIO_PUTCMAP
:
470 cmap
= (struct wsdisplay_cmap
*)data
;
474 if (sc
->sc_fbconf
.hf_class
!= HPCFB_CLASS_INDEXCOLOR
||
475 sc
->sc_fbconf
.hf_pack_width
!= 8 ||
476 !LEGAL_CLUT_INDEX(idx
) ||
477 !LEGAL_CLUT_INDEX(idx
+ cnt
- 1)) {
481 error
= cmap_work_alloc(&r
, &g
, &b
, &rgb
, cnt
);
484 error
= copyin(cmap
->red
, r
, cnt
);
487 error
= copyin(cmap
->green
, g
, cnt
);
490 error
= copyin(cmap
->blue
, b
, cnt
);
493 rgb24_compose(rgb
, r
, g
, b
, cnt
);
494 plumvideo_clut_set(sc
, rgb
, idx
, cnt
);
497 case WSDISPLAYIO_SVIDEO
:
498 if (*(int *)data
== WSDISPLAYIO_VIDEO_OFF
)
499 plumvideo_backlight(sc
, 0);
501 plumvideo_backlight(sc
, 1);
504 case WSDISPLAYIO_GVIDEO
:
505 *(int *)data
= sc
->sc_backlight
?
506 WSDISPLAYIO_VIDEO_ON
: WSDISPLAYIO_VIDEO_OFF
;
509 case WSDISPLAYIO_GETPARAM
:
510 dispparam
= (struct wsdisplay_param
*)data
;
511 switch (dispparam
->param
) {
512 case WSDISPLAYIO_PARAM_BACKLIGHT
:
515 dispparam
->curval
= sc
->sc_backlight
;
517 case WSDISPLAYIO_PARAM_BRIGHTNESS
:
518 if (sc
->sc_max_brightness
<= 0)
521 dispparam
->max
= sc
->sc_max_brightness
;
522 dispparam
->curval
= sc
->sc_brightness
;
529 case WSDISPLAYIO_SETPARAM
:
530 dispparam
= (struct wsdisplay_param
* )data
;
531 switch (dispparam
->param
) {
532 case WSDISPLAYIO_PARAM_BACKLIGHT
:
533 if (dispparam
->curval
< 0 || 1 < dispparam
->curval
)
535 plumvideo_backlight(sc
, dispparam
->curval
);
537 case WSDISPLAYIO_PARAM_BRIGHTNESS
:
538 if (sc
->sc_max_brightness
<= 0)
540 if (dispparam
->curval
< 0 ||
541 sc
->sc_max_brightness
< dispparam
->curval
)
543 plumvideo_brightness(sc
, dispparam
->curval
);
551 fbconf
= (struct hpcfb_fbconf
*)data
;
552 if (fbconf
->hf_conf_index
!= 0 &&
553 fbconf
->hf_conf_index
!= HPCFB_CURRENT_CONFIG
) {
556 *fbconf
= sc
->sc_fbconf
; /* structure assignment */
560 fbconf
= (struct hpcfb_fbconf
*)data
;
561 if (fbconf
->hf_conf_index
!= 0 &&
562 fbconf
->hf_conf_index
!= HPCFB_CURRENT_CONFIG
) {
566 * nothing to do because we have only one configuration
570 case HPCFBIO_GDSPCONF
:
571 dspconf
= (struct hpcfb_dspconf
*)data
;
572 if ((dspconf
->hd_unit_index
!= 0 &&
573 dspconf
->hd_unit_index
!= HPCFB_CURRENT_UNIT
) ||
574 (dspconf
->hd_conf_index
!= 0 &&
575 dspconf
->hd_conf_index
!= HPCFB_CURRENT_CONFIG
)) {
578 *dspconf
= sc
->sc_dspconf
; /* structure assignment */
581 case HPCFBIO_SDSPCONF
:
582 dspconf
= (struct hpcfb_dspconf
*)data
;
583 if ((dspconf
->hd_unit_index
!= 0 &&
584 dspconf
->hd_unit_index
!= HPCFB_CURRENT_UNIT
) ||
585 (dspconf
->hd_conf_index
!= 0 &&
586 dspconf
->hd_conf_index
!= HPCFB_CURRENT_CONFIG
)) {
591 * because we have only one unit and one configuration
597 /* XXX not implemented yet */
601 return (EPASSTHROUGH
);
605 plumvideo_mmap(void *ctx
, off_t offset
, int prot
)
607 struct plumvideo_softc
*sc
= (struct plumvideo_softc
*)ctx
;
609 if (offset
< 0 || (sc
->sc_fbconf
.hf_bytes_per_plane
+
610 sc
->sc_fbconf
.hf_offset
) < offset
) {
614 return (mips_btop(PLUM_VIDEO_VRAM_IOBASE_PHYSICAL
+ offset
));
617 static void __plumvideo_clut_get(bus_space_tag_t
, bus_space_handle_t
,
618 u_int32_t
*, int, int);
619 static void __plumvideo_clut_get(bus_space_tag_t iot
, bus_space_handle_t ioh
,
620 u_int32_t
*rgb
, int beg
, int cnt
)
624 for (i
= 0, beg
*= 4; i
< cnt
; i
++, beg
+= 4) {
625 *rgb
++ = bus_space_read_4(iot
, ioh
, beg
) &
631 plumvideo_clut_get(struct plumvideo_softc
*sc
, u_int32_t
*rgb
, int beg
,
635 KASSERT(LEGAL_CLUT_INDEX(beg
));
636 KASSERT(LEGAL_CLUT_INDEX(beg
+ cnt
- 1));
637 __plumvideo_clut_access(sc
, rgb
, beg
, cnt
, __plumvideo_clut_get
);
640 static void __plumvideo_clut_set(bus_space_tag_t
, bus_space_handle_t
,
641 u_int32_t
*, int, int);
642 static void __plumvideo_clut_set(bus_space_tag_t iot
, bus_space_handle_t ioh
,
643 u_int32_t
*rgb
, int beg
, int cnt
)
647 for (i
= 0, beg
*= 4; i
< cnt
; i
++, beg
+=4) {
648 bus_space_write_4(iot
, ioh
, beg
,
649 *rgb
++ & 0x00ffffff);
654 plumvideo_clut_set(struct plumvideo_softc
*sc
, u_int32_t
*rgb
, int beg
,
658 KASSERT(LEGAL_CLUT_INDEX(beg
));
659 KASSERT(LEGAL_CLUT_INDEX(beg
+ cnt
- 1));
660 __plumvideo_clut_access(sc
, rgb
, beg
, cnt
, __plumvideo_clut_set
);
663 static void __plumvideo_clut_default(bus_space_tag_t
, bus_space_handle_t
,
664 u_int32_t
*, int, int);
665 static void __plumvideo_clut_default(bus_space_tag_t iot
, bus_space_handle_t ioh
,
666 u_int32_t
*rgb
, int beg
, int cnt
)
668 static const u_int8_t compo6
[6] = { 0, 51, 102, 153, 204, 255 };
669 static const u_int32_t ansi_color
[16] = {
670 0x000000, 0xff0000, 0x00ff00, 0xffff00,
671 0x0000ff, 0xff00ff, 0x00ffff, 0xffffff,
672 0x000000, 0x800000, 0x008000, 0x808000,
673 0x000080, 0x800080, 0x008080, 0x808080,
677 /* ANSI escape sequence */
678 for (i
= 0; i
< 16; i
++) {
679 bus_space_write_4(iot
, ioh
, i
<< 2, ansi_color
[i
]);
681 /* 16 - 31, gray scale */
682 for ( ; i
< 32; i
++) {
683 int j
= (i
- 16) * 17;
684 bus_space_write_4(iot
, ioh
, i
<< 2, RGB24(j
, j
, j
));
686 /* 32 - 247, RGB color */
687 for (r
= 0; r
< 6; r
++) {
688 for (g
= 0; g
< 6; g
++) {
689 for (b
= 0; b
< 6; b
++) {
690 bus_space_write_4(iot
, ioh
, i
<< 2,
698 /* 248 - 245, just white */
699 for ( ; i
< 256; i
++) {
700 bus_space_write_4(iot
, ioh
, i
<< 2, 0xffffff);
705 plumvideo_clut_default(struct plumvideo_softc
*sc
)
707 __plumvideo_clut_access(sc
, NULL
, 0, 256, __plumvideo_clut_default
);
711 __plumvideo_clut_access(struct plumvideo_softc
*sc
, u_int32_t
*rgb
, int beg
,
712 int cnt
, void (*palette_func
)(bus_space_tag_t
, bus_space_handle_t
,
713 u_int32_t
*, int, int))
715 bus_space_tag_t regt
= sc
->sc_regt
;
716 bus_space_handle_t regh
= sc
->sc_regh
;
717 plumreg_t val
, gmode
;
720 val
= bus_space_read_4(regt
, regh
, PLUM_VIDEO_PLGMD_REG
);
721 gmode
= val
& PLUM_VIDEO_PLGMD_GMODE_MASK
;
722 val
&= ~PLUM_VIDEO_PLGMD_GMODE_MASK
;
723 bus_space_write_4(regt
, regh
, PLUM_VIDEO_PLGMD_REG
, val
);
725 /* palette access disable */
726 val
&= ~PLUM_VIDEO_PLGMD_PALETTE_ENABLE
;
727 bus_space_write_4(regt
, regh
, PLUM_VIDEO_PLGMD_REG
, val
);
729 /* change palette mode to CPU */
730 val
&= ~PLUM_VIDEO_PLGMD_MODE_DISPLAY
;
731 bus_space_write_4(regt
, regh
, PLUM_VIDEO_PLGMD_REG
, val
);
734 (*palette_func
) (sc
->sc_clutiot
, sc
->sc_clutioh
, rgb
, beg
, cnt
);
736 /* change palette mode to Display */
737 val
|= PLUM_VIDEO_PLGMD_MODE_DISPLAY
;
738 bus_space_write_4(regt
, regh
, PLUM_VIDEO_PLGMD_REG
, val
);
740 /* palette access enable */
741 val
|= PLUM_VIDEO_PLGMD_PALETTE_ENABLE
;
742 bus_space_write_4(regt
, regh
, PLUM_VIDEO_PLGMD_REG
, val
);
746 bus_space_write_4(regt
, regh
, PLUM_VIDEO_PLGMD_REG
, val
);
753 mips_dcache_wbinv_all();
754 mips_icache_sync_all();
758 plumvideo_power(void *ctx
, int type
, long id
, void *msg
)
760 struct plumvideo_softc
*sc
= ctx
;
766 return (0); /* serial console */
768 DPRINTF(("%s: ON\n", sc
->sc_dev
.dv_xname
));
770 plumvideo_backlight(sc
, 1);
775 DPRINTF(("%s: OFF\n", sc
->sc_dev
.dv_xname
));
777 plumvideo_backlight(sc
, 0);
785 plumvideo_init_backlight(struct plumvideo_softc
*sc
)
790 if (config_hook_call(CONFIG_HOOK_GET
,
791 CONFIG_HOOK_POWER_LCDLIGHT
, &val
) != -1) {
792 /* we can get real backlight state */
793 sc
->sc_backlight
= val
;
797 if (config_hook_call(CONFIG_HOOK_GET
,
798 CONFIG_HOOK_BRIGHTNESS_MAX
, &val
) != -1) {
799 /* we can get real brightness max */
800 sc
->sc_max_brightness
= val
;
803 if (config_hook_call(CONFIG_HOOK_GET
,
804 CONFIG_HOOK_BRIGHTNESS
, &val
) != -1) {
805 /* we can get real brightness */
806 sc
->sc_brightness
= val
;
808 sc
->sc_brightness
= sc
->sc_max_brightness
;
814 plumvideo_backlight(struct plumvideo_softc
*sc
, int on
)
816 plum_chipset_tag_t pc
= sc
->sc_pc
;
817 bus_space_tag_t regt
= sc
->sc_regt
;
818 bus_space_handle_t regh
= sc
->sc_regh
;
820 sc
->sc_backlight
= on
;
823 plum_power_establish(pc
, PLUM_PWR_LCD
);
825 plum_power_establish(pc
, PLUM_PWR_BKL
);
826 plum_conf_write(regt
, regh
, PLUM_VIDEO_PLLUM_REG
,
827 PLUM_VIDEO_PLLUM_MAX
);
830 plum_conf_write(regt
, regh
, PLUM_VIDEO_PLLUM_REG
,
831 PLUM_VIDEO_PLLUM_MIN
);
832 plum_power_disestablish(pc
, PLUM_PWR_BKL
);
834 plum_power_disestablish(pc
, PLUM_PWR_LCD
);
836 /* call machine dependent backlight control */
837 config_hook_call(CONFIG_HOOK_SET
,
838 CONFIG_HOOK_POWER_LCDLIGHT
, (void *)on
);
842 plumvideo_brightness(struct plumvideo_softc
*sc
, int val
)
845 sc
->sc_brightness
= val
;
846 /* call machine dependent brightness control */
847 if (sc
->sc_backlight
)
848 config_hook_call(CONFIG_HOOK_SET
,
849 CONFIG_HOOK_BRIGHTNESS
, &val
);
852 #ifdef PLUMVIDEODEBUG
854 plumvideo_dump(struct plumvideo_softc
*sc
)
856 bus_space_tag_t regt
= sc
->sc_regt
;
857 bus_space_handle_t regh
= sc
->sc_regh
;
862 for (i
= 0; i
< 0x160; i
+= 4) {
863 reg
= plum_conf_read(regt
, regh
, i
);
864 printf("0x%03x %08x", i
, reg
);
868 #endif /* PLUMVIDEODEBUG */