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