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