Home | History | Annotate | Line # | Download | only in iomd
vidc20config.c revision 1.2.4.5
      1  1.2.4.5  nathanw /*	$NetBSD: vidc20config.c,v 1.2.4.5 2002/06/20 03:38:13 nathanw Exp $	*/
      2  1.2.4.2  nathanw 
      3  1.2.4.2  nathanw /*
      4  1.2.4.2  nathanw  * Copyright (c) 2001 Reinoud Zandijk
      5  1.2.4.2  nathanw  * Copyright (c) 1996 Mark Brinicombe
      6  1.2.4.2  nathanw  * Copyright (c) 1996 Robert Black
      7  1.2.4.2  nathanw  * Copyright (c) 1994-1995 Melvyn Tang-Richardson
      8  1.2.4.2  nathanw  * Copyright (c) 1994-1995 RiscBSD kernel team
      9  1.2.4.2  nathanw  * All rights reserved.
     10  1.2.4.2  nathanw  *
     11  1.2.4.2  nathanw  * Redistribution and use in source and binary forms, with or without
     12  1.2.4.2  nathanw  * modification, are permitted provided that the following conditions
     13  1.2.4.2  nathanw  * are met:
     14  1.2.4.2  nathanw  * 1. Redistributions of source code must retain the above copyright
     15  1.2.4.2  nathanw  *    notice, this list of conditions and the following disclaimer.
     16  1.2.4.2  nathanw  * 2. Redistributions in binary form must reproduce the above copyright
     17  1.2.4.2  nathanw  *    notice, this list of conditions and the following disclaimer in the
     18  1.2.4.2  nathanw  *    documentation and/or other materials provided with the distribution.
     19  1.2.4.2  nathanw  * 3. All advertising materials mentioning features or use of this software
     20  1.2.4.2  nathanw  *    must display the following acknowledgement:
     21  1.2.4.2  nathanw  *	This product includes software developed by the RiscBSD kernel team
     22  1.2.4.2  nathanw  * 4. The name of the company nor the name of the author may be used to
     23  1.2.4.2  nathanw  *    endorse or promote products derived from this software without specific
     24  1.2.4.2  nathanw  *    prior written permission.
     25  1.2.4.2  nathanw  *
     26  1.2.4.2  nathanw  * THIS SOFTWARE IS PROVIDED BY THE RISCBSD TEAM ``AS IS'' AND ANY EXPRESS
     27  1.2.4.2  nathanw  * OR IMPLIED  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     28  1.2.4.2  nathanw  * WARRANTIES OF  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     29  1.2.4.2  nathanw  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
     30  1.2.4.2  nathanw  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31  1.2.4.2  nathanw  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32  1.2.4.2  nathanw  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33  1.2.4.2  nathanw  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34  1.2.4.2  nathanw  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35  1.2.4.2  nathanw  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
     36  1.2.4.2  nathanw  * THE POSSIBILITY OF SUCH DAMAGE.
     37  1.2.4.2  nathanw  *
     38  1.2.4.2  nathanw  * NetBSD kernel project
     39  1.2.4.2  nathanw  *
     40  1.2.4.2  nathanw  * vidcvideo.c
     41  1.2.4.2  nathanw  *
     42  1.2.4.2  nathanw  * This file is the lower basis of the wscons driver for VIDC based ARM machines.
     43  1.2.4.2  nathanw  * It features the initialisation and all VIDC writing and keeps in internal state
     44  1.2.4.2  nathanw  * copy.
     45  1.2.4.2  nathanw  * Its currenly set up as a library file and not as a device; it could be named
     46  1.2.4.2  nathanw  * vidcvideo0 eventually.
     47  1.2.4.2  nathanw  */
     48  1.2.4.2  nathanw 
     49  1.2.4.2  nathanw #include <sys/cdefs.h>
     50  1.2.4.3  nathanw 
     51  1.2.4.5  nathanw __KERNEL_RCSID(0, "$NetBSD: vidc20config.c,v 1.2.4.5 2002/06/20 03:38:13 nathanw Exp $");
     52  1.2.4.3  nathanw 
     53  1.2.4.2  nathanw #include <sys/types.h>
     54  1.2.4.2  nathanw #include <sys/param.h>
     55  1.2.4.2  nathanw #include <arm/iomd/vidc.h>
     56  1.2.4.2  nathanw #include <arm/arm32/katelib.h>
     57  1.2.4.2  nathanw #include <machine/bootconfig.h>
     58  1.2.4.2  nathanw #include <machine/intr.h>
     59  1.2.4.2  nathanw 
     60  1.2.4.2  nathanw #include <sys/systm.h>
     61  1.2.4.2  nathanw #include <sys/device.h>
     62  1.2.4.2  nathanw #include <uvm/uvm_extern.h>
     63  1.2.4.2  nathanw 
     64  1.2.4.2  nathanw #include <arm/iomd/iomdreg.h>
     65  1.2.4.2  nathanw #include <arm/iomd/iomdvar.h>
     66  1.2.4.2  nathanw #include <arm/iomd/vidc20config.h>
     67  1.2.4.2  nathanw 
     68  1.2.4.4  nathanw 
     69  1.2.4.2  nathanw /*
     70  1.2.4.2  nathanw  * A structure containing ALL the information required to restore
     71  1.2.4.2  nathanw  * the VIDC20 to any given state.  ALL vidc transactions should
     72  1.2.4.2  nathanw  * go through these procedures, which record the vidc's state.
     73  1.2.4.2  nathanw  * it may be an idea to set the permissions of the vidc base address
     74  1.2.4.2  nathanw  * so we get a fault, so the fault routine can record the state but
     75  1.2.4.2  nathanw  * I guess that's not really necessary for the time being, since we
     76  1.2.4.2  nathanw  * can make the kernel more secure later on.  Also, it is possible
     77  1.2.4.2  nathanw  * to write a routine to allow 'reading' of the vidc registers.
     78  1.2.4.2  nathanw  */
     79  1.2.4.2  nathanw 
     80  1.2.4.2  nathanw static struct vidc_state vidc_lookup = {
     81  1.2.4.2  nathanw 	{ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
     82  1.2.4.2  nathanw           0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
     83  1.2.4.2  nathanw           0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
     84  1.2.4.2  nathanw           0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
     85  1.2.4.2  nathanw           0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
     86  1.2.4.2  nathanw           0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
     87  1.2.4.2  nathanw           0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
     88  1.2.4.2  nathanw           0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0
     89  1.2.4.2  nathanw 	},
     90  1.2.4.2  nathanw 
     91  1.2.4.2  nathanw 	VIDC_PALREG,
     92  1.2.4.2  nathanw 	VIDC_BCOL,
     93  1.2.4.2  nathanw 	VIDC_CP1 ,
     94  1.2.4.2  nathanw 	VIDC_CP2,
     95  1.2.4.2  nathanw 	VIDC_CP3,
     96  1.2.4.2  nathanw 	VIDC_HCR,
     97  1.2.4.2  nathanw 	VIDC_HSWR,
     98  1.2.4.2  nathanw 	VIDC_HBSR,
     99  1.2.4.2  nathanw 	VIDC_HDSR,
    100  1.2.4.2  nathanw 	VIDC_HDER,
    101  1.2.4.2  nathanw 	VIDC_HBER,
    102  1.2.4.2  nathanw 	VIDC_HCSR,
    103  1.2.4.2  nathanw 	VIDC_HIR,
    104  1.2.4.2  nathanw 	VIDC_VCR,
    105  1.2.4.2  nathanw 	VIDC_VSWR,
    106  1.2.4.2  nathanw 	VIDC_VBSR,
    107  1.2.4.2  nathanw 	VIDC_VDSR,
    108  1.2.4.2  nathanw 	VIDC_VDER,
    109  1.2.4.2  nathanw 	VIDC_VBER,
    110  1.2.4.2  nathanw 	VIDC_VCSR,
    111  1.2.4.2  nathanw 	VIDC_VCER,
    112  1.2.4.2  nathanw 	VIDC_EREG,
    113  1.2.4.2  nathanw 	VIDC_FSYNREG,
    114  1.2.4.2  nathanw 	VIDC_CONREG,
    115  1.2.4.2  nathanw 	VIDC_DCTL
    116  1.2.4.2  nathanw };
    117  1.2.4.2  nathanw 
    118  1.2.4.2  nathanw struct vidc_state vidc_current[1];
    119  1.2.4.2  nathanw 
    120  1.2.4.2  nathanw 
    121  1.2.4.2  nathanw /*
    122  1.2.4.2  nathanw  * XXX global display variables XXX ... should be a structure
    123  1.2.4.2  nathanw  */
    124  1.2.4.2  nathanw static int cold_init = 0;		/* flags initialisation */
    125  1.2.4.2  nathanw extern videomemory_t videomemory;
    126  1.2.4.2  nathanw 
    127  1.2.4.4  nathanw static struct vidc_mode  vidc_initialmode;
    128  1.2.4.2  nathanw static struct vidc_mode *vidc_currentmode;
    129  1.2.4.2  nathanw 
    130  1.2.4.2  nathanw unsigned int dispstart;
    131  1.2.4.2  nathanw unsigned int dispsize;
    132  1.2.4.2  nathanw unsigned int dispbase;
    133  1.2.4.2  nathanw unsigned int dispend;
    134  1.2.4.2  nathanw unsigned int ptov;
    135  1.2.4.2  nathanw unsigned int vmem_base;
    136  1.2.4.2  nathanw unsigned int phys_base;
    137  1.2.4.2  nathanw unsigned int transfersize;
    138  1.2.4.2  nathanw 
    139  1.2.4.2  nathanw 
    140  1.2.4.2  nathanw /* cursor stuff */
    141  1.2.4.2  nathanw char *cursor_normal;
    142  1.2.4.2  nathanw char *cursor_transparent;
    143  1.2.4.4  nathanw int   p_cursor_normal;
    144  1.2.4.4  nathanw int   p_cursor_transparent;
    145  1.2.4.4  nathanw int   cursor_width;
    146  1.2.4.4  nathanw int   cursor_height;
    147  1.2.4.2  nathanw 
    148  1.2.4.2  nathanw 
    149  1.2.4.2  nathanw /*
    150  1.2.4.2  nathanw  * VIDC mode definitions
    151  1.2.4.2  nathanw  * generated from RISC OS mode definition file by an `awk' script
    152  1.2.4.2  nathanw  */
    153  1.2.4.2  nathanw extern struct vidc_mode vidcmodes[];
    154  1.2.4.2  nathanw 
    155  1.2.4.2  nathanw 
    156  1.2.4.2  nathanw /*
    157  1.2.4.2  nathanw  * configuration printing
    158  1.2.4.2  nathanw  *
    159  1.2.4.2  nathanw  */
    160  1.2.4.2  nathanw 
    161  1.2.4.2  nathanw void
    162  1.2.4.2  nathanw vidcvideo_printdetails(void)
    163  1.2.4.2  nathanw {
    164  1.2.4.2  nathanw         printf(": refclk=%dMHz %dKB %s ", (vidc_fref / 1000000),
    165  1.2.4.2  nathanw             videomemory.vidm_size / 1024,
    166  1.2.4.2  nathanw             (videomemory.vidm_type == VIDEOMEM_TYPE_VRAM) ? "VRAM" : "DRAM");
    167  1.2.4.2  nathanw }
    168  1.2.4.2  nathanw 
    169  1.2.4.4  nathanw 
    170  1.2.4.2  nathanw /*
    171  1.2.4.2  nathanw  * Common functions to directly access VIDC registers
    172  1.2.4.2  nathanw  */
    173  1.2.4.2  nathanw int
    174  1.2.4.2  nathanw vidcvideo_write(reg, value)
    175  1.2.4.2  nathanw 	u_int reg;
    176  1.2.4.2  nathanw 	int value;
    177  1.2.4.2  nathanw {
    178  1.2.4.2  nathanw 	int counter;
    179  1.2.4.2  nathanw 
    180  1.2.4.2  nathanw 	int *current;
    181  1.2.4.2  nathanw 	int *tab;
    182  1.2.4.2  nathanw 
    183  1.2.4.2  nathanw 	tab 	= (int *)&vidc_lookup;
    184  1.2.4.2  nathanw 	current = (int *)vidc_current;
    185  1.2.4.2  nathanw 
    186  1.2.4.2  nathanw 
    187  1.2.4.2  nathanw 	/*
    188  1.2.4.2  nathanw 	 * OK, the VIDC_PALETTE register is handled differently
    189  1.2.4.2  nathanw 	 * to the others on the VIDC, so take that into account here
    190  1.2.4.2  nathanw 	 */
    191  1.2.4.2  nathanw 	if (reg==VIDC_PALREG) {
    192  1.2.4.2  nathanw 		vidc_current->palreg = 0;
    193  1.2.4.2  nathanw 		WriteWord(vidc_base, reg | value);
    194  1.2.4.2  nathanw 		return 0;
    195  1.2.4.2  nathanw 	}
    196  1.2.4.2  nathanw 
    197  1.2.4.2  nathanw 	if (reg==VIDC_PALETTE) {
    198  1.2.4.2  nathanw 		WriteWord(vidc_base, reg | value);
    199  1.2.4.2  nathanw 		vidc_current->palette[vidc_current->palreg] = value;
    200  1.2.4.2  nathanw 		vidc_current->palreg++;
    201  1.2.4.2  nathanw 		vidc_current->palreg = vidc_current->palreg & 0xff;
    202  1.2.4.2  nathanw 		return 0;
    203  1.2.4.2  nathanw 	}
    204  1.2.4.2  nathanw 
    205  1.2.4.2  nathanw 	/*
    206  1.2.4.2  nathanw 	 * Undefine SAFER if you wish to speed things up (a little)
    207  1.2.4.2  nathanw 	 * although this means the function will assume things abou
    208  1.2.4.2  nathanw 	 * the structure of vidc_state. i.e. the first 256 words are
    209  1.2.4.2  nathanw 	 * the palette array
    210  1.2.4.2  nathanw 	 */
    211  1.2.4.2  nathanw 
    212  1.2.4.2  nathanw #define SAFER
    213  1.2.4.2  nathanw 
    214  1.2.4.2  nathanw #ifdef 	SAFER
    215  1.2.4.2  nathanw #define INITVALUE 0
    216  1.2.4.2  nathanw #else
    217  1.2.4.2  nathanw #define INITVALUE 256
    218  1.2.4.2  nathanw #endif
    219  1.2.4.2  nathanw 
    220  1.2.4.2  nathanw 	for ( counter=INITVALUE; counter<= sizeof(struct vidc_state); counter++ ) {
    221  1.2.4.2  nathanw 		if ( reg==tab[counter] ) {
    222  1.2.4.2  nathanw 			WriteWord ( vidc_base, reg | value );
    223  1.2.4.2  nathanw 			current[counter] = value;
    224  1.2.4.2  nathanw 			return 0;
    225  1.2.4.2  nathanw 		}
    226  1.2.4.2  nathanw 	}
    227  1.2.4.2  nathanw 	return -1;
    228  1.2.4.2  nathanw }
    229  1.2.4.2  nathanw 
    230  1.2.4.2  nathanw 
    231  1.2.4.2  nathanw void
    232  1.2.4.2  nathanw vidcvideo_setpalette(vidc)
    233  1.2.4.2  nathanw 	struct vidc_state *vidc;
    234  1.2.4.2  nathanw {
    235  1.2.4.2  nathanw 	int counter = 0;
    236  1.2.4.2  nathanw 
    237  1.2.4.2  nathanw 	vidcvideo_write(VIDC_PALREG, 0x00000000);
    238  1.2.4.2  nathanw 	for (counter = 0; counter < 255; counter++)
    239  1.2.4.2  nathanw 		vidcvideo_write(VIDC_PALETTE, vidc->palette[counter]);
    240  1.2.4.2  nathanw }
    241  1.2.4.2  nathanw 
    242  1.2.4.2  nathanw 
    243  1.2.4.2  nathanw void
    244  1.2.4.2  nathanw vidcvideo_setstate(vidc)
    245  1.2.4.2  nathanw 	struct vidc_state *vidc;
    246  1.2.4.2  nathanw {
    247  1.2.4.4  nathanw 	vidcvideo_write ( VIDC_PALREG,		vidc->palreg 	);
    248  1.2.4.2  nathanw 	vidcvideo_write ( VIDC_BCOL,		vidc->bcol	);
    249  1.2.4.2  nathanw 	vidcvideo_write ( VIDC_CP1,		vidc->cp1	);
    250  1.2.4.2  nathanw 	vidcvideo_write ( VIDC_CP2,		vidc->cp2	);
    251  1.2.4.2  nathanw 	vidcvideo_write ( VIDC_CP3,		vidc->cp3	);
    252  1.2.4.2  nathanw 	vidcvideo_write ( VIDC_HCR,		vidc->hcr	);
    253  1.2.4.2  nathanw 	vidcvideo_write ( VIDC_HSWR,		vidc->hswr	);
    254  1.2.4.2  nathanw 	vidcvideo_write ( VIDC_HBSR,		vidc->hbsr	);
    255  1.2.4.2  nathanw 	vidcvideo_write ( VIDC_HDSR,		vidc->hdsr	);
    256  1.2.4.2  nathanw 	vidcvideo_write ( VIDC_HDER,		vidc->hder	);
    257  1.2.4.2  nathanw 	vidcvideo_write ( VIDC_HBER,		vidc->hber	);
    258  1.2.4.2  nathanw 	vidcvideo_write ( VIDC_HCSR,		vidc->hcsr	);
    259  1.2.4.2  nathanw 	vidcvideo_write ( VIDC_HIR,		vidc->hir	);
    260  1.2.4.2  nathanw 	vidcvideo_write ( VIDC_VCR,		vidc->vcr	);
    261  1.2.4.2  nathanw 	vidcvideo_write ( VIDC_VSWR,		vidc->vswr	);
    262  1.2.4.2  nathanw 	vidcvideo_write ( VIDC_VBSR,		vidc->vbsr	);
    263  1.2.4.2  nathanw 	vidcvideo_write ( VIDC_VDSR,		vidc->vdsr	);
    264  1.2.4.2  nathanw 	vidcvideo_write ( VIDC_VDER,		vidc->vder	);
    265  1.2.4.2  nathanw 	vidcvideo_write ( VIDC_VBER,		vidc->vber	);
    266  1.2.4.2  nathanw 	vidcvideo_write ( VIDC_VCSR,		vidc->vcsr	);
    267  1.2.4.2  nathanw 	vidcvideo_write ( VIDC_VCER,		vidc->vcer	);
    268  1.2.4.2  nathanw /*
    269  1.2.4.2  nathanw  * Right, dunno what to set these to yet, but let's keep RiscOS's
    270  1.2.4.2  nathanw  * ones for now, until the time is right to finish this code
    271  1.2.4.2  nathanw  */
    272  1.2.4.2  nathanw 
    273  1.2.4.2  nathanw /*	vidcvideo_write ( VIDC_EREG,		vidc->ereg	);	*/
    274  1.2.4.2  nathanw /*	vidcvideo_write ( VIDC_FSYNREG,	vidc->fsynreg	);	*/
    275  1.2.4.2  nathanw /*	vidcvideo_write ( VIDC_CONREG,	vidc->conreg	);	*/
    276  1.2.4.2  nathanw /*	vidcvideo_write ( VIDC_DCTL,		vidc->dctl	);	*/
    277  1.2.4.2  nathanw 
    278  1.2.4.2  nathanw }
    279  1.2.4.2  nathanw 
    280  1.2.4.2  nathanw 
    281  1.2.4.2  nathanw void
    282  1.2.4.2  nathanw vidcvideo_getstate(vidc)
    283  1.2.4.2  nathanw 	struct vidc_state *vidc;
    284  1.2.4.2  nathanw {
    285  1.2.4.2  nathanw 	*vidc = *vidc_current;
    286  1.2.4.2  nathanw }
    287  1.2.4.2  nathanw 
    288  1.2.4.2  nathanw 
    289  1.2.4.2  nathanw void
    290  1.2.4.2  nathanw vidcvideo_getmode(mode)
    291  1.2.4.2  nathanw 	struct vidc_mode *mode;
    292  1.2.4.2  nathanw {
    293  1.2.4.2  nathanw 	*mode = *vidc_currentmode;
    294  1.2.4.2  nathanw }
    295  1.2.4.2  nathanw 
    296  1.2.4.2  nathanw 
    297  1.2.4.2  nathanw static int
    298  1.2.4.2  nathanw vidcvideo_coldinit(void)
    299  1.2.4.2  nathanw {
    300  1.2.4.2  nathanw 	int found;
    301  1.2.4.2  nathanw 	int loop;
    302  1.2.4.2  nathanw 
    303  1.2.4.2  nathanw 	/* Blank out the cursor */
    304  1.2.4.2  nathanw 
    305  1.2.4.2  nathanw 	vidcvideo_write(VIDC_CP1, 0x0);
    306  1.2.4.2  nathanw 	vidcvideo_write(VIDC_CP2, 0x0);
    307  1.2.4.2  nathanw 	vidcvideo_write(VIDC_CP3, 0x0);
    308  1.2.4.2  nathanw 
    309  1.2.4.2  nathanw 	/* Try to determine the current mode */
    310  1.2.4.2  nathanw 	vidc_initialmode.hder     = bootconfig.width+1;
    311  1.2.4.2  nathanw 	vidc_initialmode.vder     = bootconfig.height+1;
    312  1.2.4.2  nathanw 	vidc_initialmode.log2_bpp = bootconfig.log2_bpp;
    313  1.2.4.2  nathanw 
    314  1.2.4.2  nathanw 	dispbase = vmem_base = dispstart = videomemory.vidm_vbase;
    315  1.2.4.2  nathanw 	phys_base = videomemory.vidm_pbase;
    316  1.2.4.2  nathanw 
    317  1.2.4.2  nathanw 	/* Nut - should be using videomemory.vidm_size - mark */
    318  1.2.4.2  nathanw 	if (videomemory.vidm_type == VIDEOMEM_TYPE_DRAM) {
    319  1.2.4.2  nathanw 		dispsize = videomemory.vidm_size;
    320  1.2.4.2  nathanw 		transfersize = 16;
    321  1.2.4.2  nathanw 	} else {
    322  1.2.4.2  nathanw 		dispsize = bootconfig.vram[0].pages * NBPG;
    323  1.2.4.2  nathanw 		transfersize = dispsize >> 10;
    324  1.2.4.2  nathanw 	};
    325  1.2.4.2  nathanw 
    326  1.2.4.2  nathanw 	ptov = dispbase - phys_base;
    327  1.2.4.2  nathanw 
    328  1.2.4.2  nathanw 	dispend = dispstart+dispsize;
    329  1.2.4.2  nathanw 
    330  1.2.4.2  nathanw 	/* try to find the current mode from the bootloader in my table */
    331  1.2.4.2  nathanw 	vidc_currentmode = &vidcmodes[0];
    332  1.2.4.2  nathanw 	loop = 0;
    333  1.2.4.2  nathanw 	found = 0;
    334  1.2.4.2  nathanw 	while (vidcmodes[loop].pixel_rate != 0) {
    335  1.2.4.2  nathanw   		if (vidcmodes[loop].hder == (bootconfig.width + 1)
    336  1.2.4.2  nathanw   		    && vidcmodes[loop].vder == (bootconfig.height + 1)
    337  1.2.4.2  nathanw 		    && vidcmodes[loop].frame_rate == bootconfig.framerate) {
    338  1.2.4.2  nathanw 			vidc_currentmode = &vidcmodes[loop];
    339  1.2.4.2  nathanw 			found = 1;
    340  1.2.4.2  nathanw 		}
    341  1.2.4.2  nathanw 		++loop;
    342  1.2.4.2  nathanw 	}
    343  1.2.4.2  nathanw 
    344  1.2.4.2  nathanw 	/* if not found choose first mode but dont be picky on the framerate */
    345  1.2.4.2  nathanw 	if (!found) {
    346  1.2.4.2  nathanw 		vidc_currentmode = &vidcmodes[0];
    347  1.2.4.2  nathanw 		loop = 0;
    348  1.2.4.2  nathanw 		found = 0;
    349  1.2.4.2  nathanw 
    350  1.2.4.2  nathanw 		while (vidcmodes[loop].pixel_rate != 0) {
    351  1.2.4.2  nathanw 			if (vidcmodes[loop].hder == (bootconfig.width + 1)
    352  1.2.4.2  nathanw  			    && vidcmodes[loop].vder == (bootconfig.height + 1)) {
    353  1.2.4.2  nathanw  				vidc_currentmode = &vidcmodes[loop];
    354  1.2.4.2  nathanw  				found = 1;
    355  1.2.4.2  nathanw  			}
    356  1.2.4.2  nathanw  			++loop;
    357  1.2.4.2  nathanw  		}
    358  1.2.4.2  nathanw 	}
    359  1.2.4.2  nathanw 
    360  1.2.4.2  nathanw 	vidc_currentmode->log2_bpp = bootconfig.log2_bpp;
    361  1.2.4.2  nathanw 
    362  1.2.4.2  nathanw 	dispstart = dispbase;
    363  1.2.4.2  nathanw 	dispend = dispstart+dispsize;
    364  1.2.4.2  nathanw 
    365  1.2.4.2  nathanw 	IOMD_WRITE_WORD(IOMD_VIDINIT, dispstart-ptov);
    366  1.2.4.2  nathanw 	IOMD_WRITE_WORD(IOMD_VIDSTART, dispstart-ptov);
    367  1.2.4.2  nathanw 	IOMD_WRITE_WORD(IOMD_VIDEND, (dispend-transfersize)-ptov);
    368  1.2.4.2  nathanw 	return 0;
    369  1.2.4.2  nathanw }
    370  1.2.4.2  nathanw 
    371  1.2.4.2  nathanw 
    372  1.2.4.2  nathanw /* simple function to abstract vidc variables ; returns virt start address of screen */
    373  1.2.4.2  nathanw /* XXX asumption that video memory is mapped in twice */
    374  1.2.4.2  nathanw void *vidcvideo_hwscroll(int bytes) {
    375  1.2.4.2  nathanw 	dispstart += bytes;
    376  1.2.4.2  nathanw 	if (dispstart >= dispbase + dispsize) dispstart -= dispsize;
    377  1.2.4.2  nathanw 	if (dispstart <  dispbase)            dispstart += dispsize;
    378  1.2.4.2  nathanw 	dispend = dispstart+dispsize;
    379  1.2.4.2  nathanw 
    380  1.2.4.2  nathanw 	/* return the start of the bit map of the screen (left top) */
    381  1.2.4.2  nathanw 	return (void *) dispstart;
    382  1.2.4.2  nathanw }
    383  1.2.4.2  nathanw 
    384  1.2.4.2  nathanw 
    385  1.2.4.2  nathanw /* reset the HW scroll to be at the start for the benefit of f.e. X */
    386  1.2.4.2  nathanw void *vidcvideo_hwscroll_reset(void) {
    387  1.2.4.2  nathanw 	void *cookie = (void *) dispstart;
    388  1.2.4.2  nathanw 
    389  1.2.4.2  nathanw 	dispstart = dispbase;
    390  1.2.4.2  nathanw 	dispend = dispstart + dispsize;
    391  1.2.4.2  nathanw 	return cookie;
    392  1.2.4.2  nathanw }
    393  1.2.4.2  nathanw 
    394  1.2.4.2  nathanw 
    395  1.2.4.2  nathanw /* put HW scroll back to where it was */
    396  1.2.4.2  nathanw void *vidcvideo_hwscroll_back(void *cookie) {
    397  1.2.4.2  nathanw 	dispstart = (int) cookie;
    398  1.2.4.2  nathanw 	dispend = dispstart + dispsize;
    399  1.2.4.2  nathanw 	return cookie;
    400  1.2.4.2  nathanw }
    401  1.2.4.2  nathanw 
    402  1.2.4.2  nathanw 
    403  1.2.4.4  nathanw /* this function is to be called perferably at vsync */
    404  1.2.4.2  nathanw void vidcvideo_progr_scroll(void) {
    405  1.2.4.2  nathanw 	IOMD_WRITE_WORD(IOMD_VIDINIT, dispstart-ptov);
    406  1.2.4.2  nathanw 	IOMD_WRITE_WORD(IOMD_VIDSTART, dispstart-ptov);
    407  1.2.4.2  nathanw 	IOMD_WRITE_WORD(IOMD_VIDEND, (dispend-transfersize)-ptov);
    408  1.2.4.2  nathanw }
    409  1.2.4.2  nathanw 
    410  1.2.4.2  nathanw 
    411  1.2.4.2  nathanw /*
    412  1.2.4.2  nathanw  * Select a new mode by reprogramming the VIDC chip
    413  1.2.4.2  nathanw  * XXX this part is known not to work for 32bpp
    414  1.2.4.2  nathanw  */
    415  1.2.4.2  nathanw 
    416  1.2.4.2  nathanw struct vidc_mode newmode;
    417  1.2.4.2  nathanw 
    418  1.2.4.2  nathanw static const int bpp_mask_table[] = {
    419  1.2.4.2  nathanw 	0,  /* 1bpp */
    420  1.2.4.2  nathanw 	1,  /* 2bpp */
    421  1.2.4.2  nathanw 	2,  /* 4bpp */
    422  1.2.4.2  nathanw 	3,  /* 8bpp */
    423  1.2.4.2  nathanw 	4,  /* 16bpp */
    424  1.2.4.2  nathanw 	6   /* 32bpp */
    425  1.2.4.2  nathanw };
    426  1.2.4.2  nathanw 
    427  1.2.4.2  nathanw 
    428  1.2.4.2  nathanw void
    429  1.2.4.2  nathanw vidcvideo_setmode(struct vidc_mode *mode)
    430  1.2.4.2  nathanw {
    431  1.2.4.2  nathanw 	register int acc;
    432  1.2.4.2  nathanw 	int bpp_mask;
    433  1.2.4.2  nathanw         int ereg;
    434  1.2.4.2  nathanw 	int best_r, best_v;
    435  1.2.4.2  nathanw 	int least_error;
    436  1.2.4.2  nathanw 	int r, v, f;
    437  1.2.4.2  nathanw 
    438  1.2.4.2  nathanw 	/*
    439  1.2.4.2  nathanw 	 * Find out what bit mask we need to or with the vidc20 control register
    440  1.2.4.2  nathanw 	 * in order to generate the desired number of bits per pixel.
    441  1.2.4.2  nathanw 	 * log_bpp is log base 2 of the number of bits per pixel.
    442  1.2.4.2  nathanw 	 */
    443  1.2.4.2  nathanw 
    444  1.2.4.2  nathanw 	bpp_mask = bpp_mask_table[mode->log2_bpp];
    445  1.2.4.2  nathanw 
    446  1.2.4.2  nathanw 	newmode = *mode;
    447  1.2.4.2  nathanw 	vidc_currentmode = &newmode;
    448  1.2.4.2  nathanw 
    449  1.2.4.2  nathanw 	least_error = INT_MAX;
    450  1.2.4.2  nathanw 	best_r = 0; best_v = 0;
    451  1.2.4.2  nathanw 
    452  1.2.4.2  nathanw 	for (v = 63; v > 0; v--) {
    453  1.2.4.2  nathanw 		for (r = 63; r > 0; r--) {
    454  1.2.4.2  nathanw 			f = ((v * vidc_fref) /1000) / r;
    455  1.2.4.2  nathanw 			if (least_error >=
    456  1.2.4.2  nathanw 			    abs(f - vidc_currentmode->pixel_rate)) {
    457  1.2.4.2  nathanw 				least_error =
    458  1.2.4.2  nathanw 				    abs(f - vidc_currentmode->pixel_rate);
    459  1.2.4.2  nathanw 				best_r = r;
    460  1.2.4.2  nathanw 				best_v = v;
    461  1.2.4.2  nathanw 			}
    462  1.2.4.2  nathanw 		}
    463  1.2.4.2  nathanw 	}
    464  1.2.4.2  nathanw 
    465  1.2.4.2  nathanw 	if (best_r > 63) best_r=63;
    466  1.2.4.2  nathanw 	if (best_v > 63) best_v=63;
    467  1.2.4.2  nathanw 	if (best_r < 1)  best_r= 1;
    468  1.2.4.2  nathanw 	if (best_v < 1)  best_v= 1;
    469  1.2.4.2  nathanw 
    470  1.2.4.2  nathanw 	vidcvideo_write(VIDC_FSYNREG, (best_v-1)<<8 | (best_r-1)<<0);
    471  1.2.4.2  nathanw 
    472  1.2.4.2  nathanw 	acc=0;
    473  1.2.4.2  nathanw 	acc+=vidc_currentmode->hswr;	vidcvideo_write(VIDC_HSWR, (acc - 8 ) & (~1));
    474  1.2.4.2  nathanw 	acc+=vidc_currentmode->hbsr;	vidcvideo_write(VIDC_HBSR, (acc - 12) & (~1));
    475  1.2.4.2  nathanw 	acc+=vidc_currentmode->hdsr;	vidcvideo_write(VIDC_HDSR, (acc - 18) & (~1));
    476  1.2.4.2  nathanw 	acc+=vidc_currentmode->hder;	vidcvideo_write(VIDC_HDER, (acc - 18) & (~1));
    477  1.2.4.2  nathanw 	acc+=vidc_currentmode->hber;	vidcvideo_write(VIDC_HBER, (acc - 12) & (~1));
    478  1.2.4.2  nathanw 	acc+=vidc_currentmode->hcr;	vidcvideo_write(VIDC_HCR,  (acc - 8 ) & (~3));
    479  1.2.4.2  nathanw 
    480  1.2.4.2  nathanw 	acc=0;
    481  1.2.4.2  nathanw 	acc+=vidc_currentmode->vswr;	vidcvideo_write(VIDC_VSWR, (acc - 1));
    482  1.2.4.2  nathanw 	acc+=vidc_currentmode->vbsr;	vidcvideo_write(VIDC_VBSR, (acc - 1));
    483  1.2.4.2  nathanw 	acc+=vidc_currentmode->vdsr;	vidcvideo_write(VIDC_VDSR, (acc - 1));
    484  1.2.4.2  nathanw 	acc+=vidc_currentmode->vder;	vidcvideo_write(VIDC_VDER, (acc - 1));
    485  1.2.4.2  nathanw 	acc+=vidc_currentmode->vber;	vidcvideo_write(VIDC_VBER, (acc - 1));
    486  1.2.4.2  nathanw 	acc+=vidc_currentmode->vcr;	vidcvideo_write(VIDC_VCR,  (acc - 1));
    487  1.2.4.2  nathanw 
    488  1.2.4.2  nathanw 	IOMD_WRITE_WORD(IOMD_FSIZE, vidc_currentmode->vcr
    489  1.2.4.2  nathanw 	    + vidc_currentmode->vswr
    490  1.2.4.2  nathanw 	    + vidc_currentmode->vber
    491  1.2.4.2  nathanw 	    + vidc_currentmode->vbsr - 1);
    492  1.2.4.2  nathanw 
    493  1.2.4.2  nathanw 	if (dispsize <= 1024*1024)
    494  1.2.4.2  nathanw 		vidcvideo_write(VIDC_DCTL, vidc_currentmode->hder>>2 | 1<<16 | 1<<12);
    495  1.2.4.2  nathanw 	else
    496  1.2.4.2  nathanw 		vidcvideo_write(VIDC_DCTL, vidc_currentmode->hder>>2 | 3<<16 | 1<<12);
    497  1.2.4.2  nathanw 
    498  1.2.4.2  nathanw 	ereg = 1<<12;
    499  1.2.4.2  nathanw 	if (vidc_currentmode->sync_pol & 0x01)
    500  1.2.4.2  nathanw 		ereg |= 1<<16;
    501  1.2.4.2  nathanw 	if (vidc_currentmode->sync_pol & 0x02)
    502  1.2.4.2  nathanw 		ereg |= 1<<18;
    503  1.2.4.2  nathanw 	vidcvideo_write(VIDC_EREG, ereg);
    504  1.2.4.2  nathanw 	if (dispsize > 1024*1024) {
    505  1.2.4.2  nathanw 		if (vidc_currentmode->hder >= 800)
    506  1.2.4.2  nathanw  			vidcvideo_write(VIDC_CONREG, 7<<8 | bpp_mask<<5);
    507  1.2.4.2  nathanw 		else
    508  1.2.4.2  nathanw 			vidcvideo_write(VIDC_CONREG, 6<<8 | bpp_mask<<5);
    509  1.2.4.2  nathanw 	} else {
    510  1.2.4.2  nathanw 		vidcvideo_write(VIDC_CONREG, 7<<8 | bpp_mask<<5);
    511  1.2.4.2  nathanw 	}
    512  1.2.4.2  nathanw }
    513  1.2.4.2  nathanw 
    514  1.2.4.2  nathanw 
    515  1.2.4.3  nathanw #if 0
    516  1.2.4.2  nathanw /* not used for now */
    517  1.2.4.2  nathanw void
    518  1.2.4.2  nathanw vidcvideo_set_display_base(base)
    519  1.2.4.2  nathanw 	u_int base;
    520  1.2.4.2  nathanw {
    521  1.2.4.2  nathanw 	dispstart = dispstart-dispbase + base;
    522  1.2.4.2  nathanw 	dispbase = vmem_base = base;
    523  1.2.4.2  nathanw 	dispend = base + dispsize;
    524  1.2.4.2  nathanw 	ptov = dispbase - phys_base;
    525  1.2.4.2  nathanw }
    526  1.2.4.3  nathanw #endif
    527  1.2.4.2  nathanw 
    528  1.2.4.2  nathanw 
    529  1.2.4.2  nathanw /*
    530  1.2.4.2  nathanw  * Main initialisation routine for now
    531  1.2.4.2  nathanw  */
    532  1.2.4.2  nathanw 
    533  1.2.4.2  nathanw static int cursor_init = 0;
    534  1.2.4.2  nathanw 
    535  1.2.4.2  nathanw int
    536  1.2.4.2  nathanw vidcvideo_init(void)
    537  1.2.4.2  nathanw {
    538  1.2.4.2  nathanw 	vidcvideo_coldinit();
    539  1.2.4.2  nathanw 	if (cold_init && (cursor_init == 0))
    540  1.2.4.2  nathanw 		/*	vidcvideo_flash_go() */;
    541  1.2.4.2  nathanw 
    542  1.2.4.2  nathanw 	/* setting a mode goes wrong in 32 bpp ... 8 and 16 seem OK */
    543  1.2.4.2  nathanw 	vidcvideo_setmode(vidc_currentmode);
    544  1.2.4.2  nathanw 	vidcvideo_blank(0);			/* display on */
    545  1.2.4.2  nathanw 
    546  1.2.4.5  nathanw 	vidcvideo_stdpalette();
    547  1.2.4.2  nathanw 
    548  1.2.4.2  nathanw 	if (cold_init == 0) {
    549  1.2.4.2  nathanw 		vidcvideo_write(VIDC_CP1, 0x0);
    550  1.2.4.2  nathanw 		vidcvideo_write(VIDC_CP2, 0x0);
    551  1.2.4.2  nathanw 		vidcvideo_write(VIDC_CP3, 0x0);
    552  1.2.4.2  nathanw 	} else {
    553  1.2.4.2  nathanw 		vidcvideo_cursor_init(CURSOR_MAX_WIDTH, CURSOR_MAX_HEIGHT);
    554  1.2.4.2  nathanw 	};
    555  1.2.4.2  nathanw 
    556  1.2.4.2  nathanw 	cold_init=1;
    557  1.2.4.2  nathanw 	return 0;
    558  1.2.4.2  nathanw }
    559  1.2.4.2  nathanw 
    560  1.2.4.2  nathanw 
    561  1.2.4.2  nathanw /* reinitialise the vidcvideo */
    562  1.2.4.2  nathanw void
    563  1.2.4.2  nathanw vidcvideo_reinit()
    564  1.2.4.2  nathanw {
    565  1.2.4.2  nathanw 	vidcvideo_coldinit();
    566  1.2.4.2  nathanw 	vidcvideo_setmode(vidc_currentmode);
    567  1.2.4.2  nathanw }
    568  1.2.4.2  nathanw 
    569  1.2.4.2  nathanw 
    570  1.2.4.2  nathanw int
    571  1.2.4.2  nathanw vidcvideo_cursor_init(int width, int height)
    572  1.2.4.2  nathanw {
    573  1.2.4.2  nathanw 	static char *cursor_data = NULL;
    574  1.2.4.2  nathanw 	int counter;
    575  1.2.4.2  nathanw 	int line;
    576  1.2.4.2  nathanw 	paddr_t pa;
    577  1.2.4.2  nathanw 
    578  1.2.4.2  nathanw 	cursor_width  = width;
    579  1.2.4.2  nathanw 	cursor_height = height;
    580  1.2.4.2  nathanw 
    581  1.2.4.2  nathanw 	if (!cursor_data) {
    582  1.2.4.2  nathanw 		/* Allocate cursor memory first time round */
    583  1.2.4.2  nathanw 		cursor_data = (char *)uvm_km_zalloc(kernel_map, NBPG);
    584  1.2.4.2  nathanw 		if (!cursor_data)
    585  1.2.4.2  nathanw 			panic("Cannot allocate memory for hardware cursor\n");
    586  1.2.4.2  nathanw 		(void) pmap_extract(pmap_kernel(), (vaddr_t)cursor_data, &pa);
    587  1.2.4.2  nathanw 		IOMD_WRITE_WORD(IOMD_CURSINIT, pa);
    588  1.2.4.2  nathanw 	}
    589  1.2.4.2  nathanw 
    590  1.2.4.2  nathanw 	/* Blank the cursor while initialising it's sprite */
    591  1.2.4.2  nathanw 
    592  1.2.4.2  nathanw 	vidcvideo_write ( VIDC_CP1, 0x0 );
    593  1.2.4.2  nathanw 	vidcvideo_write ( VIDC_CP2, 0x0 );
    594  1.2.4.2  nathanw 	vidcvideo_write ( VIDC_CP3, 0x0 );
    595  1.2.4.2  nathanw 
    596  1.2.4.2  nathanw  	cursor_normal       = cursor_data;
    597  1.2.4.2  nathanw 	cursor_transparent  = cursor_data + (height * width);
    598  1.2.4.2  nathanw 
    599  1.2.4.2  nathanw  	cursor_transparent += 32;					/* ALIGN */
    600  1.2.4.2  nathanw 	cursor_transparent = (char *)((int)cursor_transparent & (~31) );
    601  1.2.4.2  nathanw 
    602  1.2.4.2  nathanw 	for ( line = 0; line<height; ++ line )
    603  1.2.4.2  nathanw 	{
    604  1.2.4.2  nathanw 	    for ( counter=0; counter<width/4;counter++ )
    605  1.2.4.2  nathanw 		cursor_normal[line * width + counter]=0x55;		/* why 0x55 ? */
    606  1.2.4.2  nathanw 	    for ( ; counter<8; counter++ )
    607  1.2.4.2  nathanw 		cursor_normal[line * width + counter]=0;
    608  1.2.4.2  nathanw 	}
    609  1.2.4.2  nathanw 
    610  1.2.4.2  nathanw 	for ( line = 0; line<height; ++ line )
    611  1.2.4.2  nathanw 	{
    612  1.2.4.2  nathanw 	    for ( counter=0; counter<width/4;counter++ )
    613  1.2.4.2  nathanw 		cursor_transparent[line * width + counter]=0x00;
    614  1.2.4.2  nathanw 	    for ( ; counter<8; counter++ )
    615  1.2.4.2  nathanw 		cursor_transparent[line * width + counter]=0;
    616  1.2.4.2  nathanw 	}
    617  1.2.4.2  nathanw 
    618  1.2.4.2  nathanw 
    619  1.2.4.2  nathanw 	(void) pmap_extract(pmap_kernel(), (vaddr_t)cursor_normal,
    620  1.2.4.2  nathanw 	    (paddr_t *)&p_cursor_normal);
    621  1.2.4.2  nathanw 	(void) pmap_extract(pmap_kernel(), (vaddr_t)cursor_transparent,
    622  1.2.4.2  nathanw 	    (paddr_t *)&p_cursor_transparent);
    623  1.2.4.2  nathanw 
    624  1.2.4.2  nathanw 	memset ( cursor_normal, 0x55, width*height );			/* white? */
    625  1.2.4.2  nathanw 	memset ( cursor_transparent, 0x00, width*height );		/* to see the diffence */
    626  1.2.4.2  nathanw 
    627  1.2.4.2  nathanw 	/* Ok, now program the cursor; should be blank */
    628  1.2.4.2  nathanw 	vidcvideo_enablecursor(0);
    629  1.2.4.2  nathanw 
    630  1.2.4.2  nathanw         return 0;
    631  1.2.4.2  nathanw }
    632  1.2.4.2  nathanw 
    633  1.2.4.2  nathanw 
    634  1.2.4.2  nathanw void
    635  1.2.4.2  nathanw vidcvideo_updatecursor(xcur, ycur)
    636  1.2.4.2  nathanw 	int xcur, ycur;
    637  1.2.4.2  nathanw {
    638  1.2.4.2  nathanw 	int frontporch = vidc_currentmode->hswr + vidc_currentmode->hbsr + vidc_currentmode->hdsr;
    639  1.2.4.2  nathanw 	int topporch   = vidc_currentmode->vswr + vidc_currentmode->vbsr + vidc_currentmode->vdsr;
    640  1.2.4.2  nathanw 
    641  1.2.4.2  nathanw 	vidcvideo_write(VIDC_HCSR, frontporch -17 + xcur);
    642  1.2.4.2  nathanw 	vidcvideo_write(VIDC_VCSR, topporch   -2  + (ycur+1)-2 + 3 - cursor_height);
    643  1.2.4.2  nathanw 	vidcvideo_write(VIDC_VCER, topporch   -2  + (ycur+3)+2 + 3 );
    644  1.2.4.2  nathanw 	return;
    645  1.2.4.2  nathanw }
    646  1.2.4.2  nathanw 
    647  1.2.4.2  nathanw 
    648  1.2.4.2  nathanw void
    649  1.2.4.2  nathanw vidcvideo_enablecursor(on)
    650  1.2.4.2  nathanw 	int on;
    651  1.2.4.2  nathanw {
    652  1.2.4.2  nathanw 	if (on) {
    653  1.2.4.2  nathanw 		IOMD_WRITE_WORD(IOMD_CURSINIT,p_cursor_normal);
    654  1.2.4.2  nathanw 	} else {
    655  1.2.4.2  nathanw 		IOMD_WRITE_WORD(IOMD_CURSINIT,p_cursor_transparent);
    656  1.2.4.2  nathanw 	};
    657  1.2.4.2  nathanw 	vidcvideo_write ( VIDC_CP1, 0xffffff );		/* enable */
    658  1.2.4.2  nathanw 
    659  1.2.4.2  nathanw 	return;
    660  1.2.4.2  nathanw }
    661  1.2.4.2  nathanw 
    662  1.2.4.2  nathanw 
    663  1.2.4.5  nathanw void
    664  1.2.4.5  nathanw vidcvideo_stdpalette()
    665  1.2.4.2  nathanw {
    666  1.2.4.5  nathanw 	int i;
    667  1.2.4.2  nathanw 
    668  1.2.4.5  nathanw 	switch (vidc_currentmode->log2_bpp) {
    669  1.2.4.5  nathanw 	case 0: /* 1 bpp */
    670  1.2.4.5  nathanw 	case 1: /* 2 bpp */
    671  1.2.4.5  nathanw 	case 2: /* 4 bpp */
    672  1.2.4.5  nathanw 	case 3: /* 8 bpp */
    673  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALREG, 0x00000000);
    674  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALETTE, VIDC_COL(  0,   0,   0));
    675  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALETTE, VIDC_COL(255,   0,   0));
    676  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALETTE, VIDC_COL(  0, 255,   0));
    677  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 255,   0));
    678  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALETTE, VIDC_COL(  0,   0, 255));
    679  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALETTE, VIDC_COL(255,   0, 255));
    680  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALETTE, VIDC_COL(  0, 255, 255));
    681  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 255, 255));
    682  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALETTE, VIDC_COL(128, 128, 128));
    683  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 128, 128));
    684  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALETTE, VIDC_COL(128, 255, 128));
    685  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 255, 128));
    686  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALETTE, VIDC_COL(128, 128, 255));
    687  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 128, 255));
    688  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 255, 255));
    689  1.2.4.5  nathanw 		break;
    690  1.2.4.5  nathanw 	case 4: /* 16 bpp */
    691  1.2.4.5  nathanw 		/*
    692  1.2.4.5  nathanw 		 * The use of the palette in 16-bit modes is quite
    693  1.2.4.5  nathanw 		 * fun.  Comments in linux/drivers/video/acornfb.c
    694  1.2.4.5  nathanw 		 * imply that it goes something like this:
    695  1.2.4.5  nathanw 		 *
    696  1.2.4.5  nathanw 		 * red   = LUT[pixel[7:0]].red
    697  1.2.4.5  nathanw 		 * green = LUT[pixel[11:4]].green
    698  1.2.4.5  nathanw 		 * blue  = LUT[pixel[15:8]].blue
    699  1.2.4.5  nathanw 		 *
    700  1.2.4.5  nathanw 		 * We just want 5:5:5 R:G:B.
    701  1.2.4.5  nathanw 		 */
    702  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALREG, 0x00000000);
    703  1.2.4.5  nathanw 		for (i = 0; i < 256; i++) {
    704  1.2.4.5  nathanw 			int r5, g5, b5;
    705  1.2.4.5  nathanw 
    706  1.2.4.5  nathanw 			r5 = i & 0x1f;
    707  1.2.4.5  nathanw 			g5 = (i >> 1) & 0x1f;
    708  1.2.4.5  nathanw 			b5 = (i >> 2) & 0x1f;
    709  1.2.4.5  nathanw 			vidcvideo_write(VIDC_PALETTE,
    710  1.2.4.5  nathanw 			    VIDC_COL(r5 << 3 | r5 >> 2, g5 << 3 | g5 >> 2,
    711  1.2.4.5  nathanw 				b5 << 3 | b5 >> 2));
    712  1.2.4.5  nathanw 		}
    713  1.2.4.5  nathanw 		break;
    714  1.2.4.5  nathanw 	case 5: /* 32 bpp */
    715  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALREG, 0x00000000);
    716  1.2.4.5  nathanw 		for (i = 0; i < 256; i++)
    717  1.2.4.5  nathanw 			vidcvideo_write(VIDC_PALETTE, VIDC_COL(i, i, i));
    718  1.2.4.5  nathanw 		break;
    719  1.2.4.5  nathanw 	}
    720  1.2.4.5  nathanw 
    721  1.2.4.2  nathanw }
    722  1.2.4.2  nathanw 
    723  1.2.4.2  nathanw int
    724  1.2.4.2  nathanw vidcvideo_blank(video_off)
    725  1.2.4.2  nathanw 	int video_off;
    726  1.2.4.2  nathanw {
    727  1.2.4.2  nathanw         int ereg;
    728  1.2.4.2  nathanw 
    729  1.2.4.2  nathanw 	ereg = 1<<12;
    730  1.2.4.2  nathanw 	if (vidc_currentmode->sync_pol & 0x01)
    731  1.2.4.2  nathanw 		ereg |= 1<<16;
    732  1.2.4.2  nathanw 	if (vidc_currentmode->sync_pol & 0x02)
    733  1.2.4.2  nathanw 		ereg |= 1<<18;
    734  1.2.4.2  nathanw 
    735  1.2.4.2  nathanw 	if (!video_off) {
    736  1.2.4.2  nathanw     		vidcvideo_write(VIDC_EREG, ereg);
    737  1.2.4.2  nathanw 	} else {
    738  1.2.4.2  nathanw 		vidcvideo_write(VIDC_EREG, 0);
    739  1.2.4.2  nathanw 	};
    740  1.2.4.2  nathanw 	return 0;
    741  1.2.4.2  nathanw }
    742  1.2.4.2  nathanw 
    743  1.2.4.2  nathanw /* end of vidc20config.c */
    744