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