Home | History | Annotate | Line # | Download | only in iomd
vidc20config.c revision 1.2.4.7
      1  1.2.4.7  nathanw /*	$NetBSD: vidc20config.c,v 1.2.4.7 2002/10/18 02:35:33 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.7  nathanw __KERNEL_RCSID(0, "$NetBSD: vidc20config.c,v 1.2.4.7 2002/10/18 02:35:33 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.7  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.7  nathanw 	vidcvideo_setpalette(vidc);
    279  1.2.4.2  nathanw }
    280  1.2.4.2  nathanw 
    281  1.2.4.2  nathanw 
    282  1.2.4.2  nathanw void
    283  1.2.4.2  nathanw vidcvideo_getstate(vidc)
    284  1.2.4.2  nathanw 	struct vidc_state *vidc;
    285  1.2.4.2  nathanw {
    286  1.2.4.2  nathanw 	*vidc = *vidc_current;
    287  1.2.4.2  nathanw }
    288  1.2.4.2  nathanw 
    289  1.2.4.2  nathanw 
    290  1.2.4.2  nathanw void
    291  1.2.4.2  nathanw vidcvideo_getmode(mode)
    292  1.2.4.2  nathanw 	struct vidc_mode *mode;
    293  1.2.4.2  nathanw {
    294  1.2.4.2  nathanw 	*mode = *vidc_currentmode;
    295  1.2.4.2  nathanw }
    296  1.2.4.2  nathanw 
    297  1.2.4.2  nathanw 
    298  1.2.4.2  nathanw static int
    299  1.2.4.2  nathanw vidcvideo_coldinit(void)
    300  1.2.4.2  nathanw {
    301  1.2.4.2  nathanw 	int found;
    302  1.2.4.2  nathanw 	int loop;
    303  1.2.4.2  nathanw 
    304  1.2.4.2  nathanw 	/* Blank out the cursor */
    305  1.2.4.2  nathanw 
    306  1.2.4.2  nathanw 	vidcvideo_write(VIDC_CP1, 0x0);
    307  1.2.4.2  nathanw 	vidcvideo_write(VIDC_CP2, 0x0);
    308  1.2.4.2  nathanw 	vidcvideo_write(VIDC_CP3, 0x0);
    309  1.2.4.2  nathanw 
    310  1.2.4.2  nathanw 	/* Try to determine the current mode */
    311  1.2.4.2  nathanw 	vidc_initialmode.hder     = bootconfig.width+1;
    312  1.2.4.2  nathanw 	vidc_initialmode.vder     = bootconfig.height+1;
    313  1.2.4.2  nathanw 	vidc_initialmode.log2_bpp = bootconfig.log2_bpp;
    314  1.2.4.2  nathanw 
    315  1.2.4.2  nathanw 	dispbase = vmem_base = dispstart = videomemory.vidm_vbase;
    316  1.2.4.2  nathanw 	phys_base = videomemory.vidm_pbase;
    317  1.2.4.2  nathanw 
    318  1.2.4.2  nathanw 	/* Nut - should be using videomemory.vidm_size - mark */
    319  1.2.4.2  nathanw 	if (videomemory.vidm_type == VIDEOMEM_TYPE_DRAM) {
    320  1.2.4.2  nathanw 		dispsize = videomemory.vidm_size;
    321  1.2.4.2  nathanw 		transfersize = 16;
    322  1.2.4.2  nathanw 	} else {
    323  1.2.4.2  nathanw 		dispsize = bootconfig.vram[0].pages * NBPG;
    324  1.2.4.2  nathanw 		transfersize = dispsize >> 10;
    325  1.2.4.2  nathanw 	};
    326  1.2.4.2  nathanw 
    327  1.2.4.2  nathanw 	ptov = dispbase - phys_base;
    328  1.2.4.2  nathanw 
    329  1.2.4.2  nathanw 	dispend = dispstart+dispsize;
    330  1.2.4.2  nathanw 
    331  1.2.4.2  nathanw 	/* try to find the current mode from the bootloader in my table */
    332  1.2.4.2  nathanw 	vidc_currentmode = &vidcmodes[0];
    333  1.2.4.2  nathanw 	loop = 0;
    334  1.2.4.2  nathanw 	found = 0;
    335  1.2.4.2  nathanw 	while (vidcmodes[loop].pixel_rate != 0) {
    336  1.2.4.2  nathanw   		if (vidcmodes[loop].hder == (bootconfig.width + 1)
    337  1.2.4.2  nathanw   		    && vidcmodes[loop].vder == (bootconfig.height + 1)
    338  1.2.4.2  nathanw 		    && vidcmodes[loop].frame_rate == bootconfig.framerate) {
    339  1.2.4.2  nathanw 			vidc_currentmode = &vidcmodes[loop];
    340  1.2.4.2  nathanw 			found = 1;
    341  1.2.4.2  nathanw 		}
    342  1.2.4.2  nathanw 		++loop;
    343  1.2.4.2  nathanw 	}
    344  1.2.4.2  nathanw 
    345  1.2.4.2  nathanw 	/* if not found choose first mode but dont be picky on the framerate */
    346  1.2.4.2  nathanw 	if (!found) {
    347  1.2.4.2  nathanw 		vidc_currentmode = &vidcmodes[0];
    348  1.2.4.2  nathanw 		loop = 0;
    349  1.2.4.2  nathanw 		found = 0;
    350  1.2.4.2  nathanw 
    351  1.2.4.2  nathanw 		while (vidcmodes[loop].pixel_rate != 0) {
    352  1.2.4.2  nathanw 			if (vidcmodes[loop].hder == (bootconfig.width + 1)
    353  1.2.4.2  nathanw  			    && vidcmodes[loop].vder == (bootconfig.height + 1)) {
    354  1.2.4.2  nathanw  				vidc_currentmode = &vidcmodes[loop];
    355  1.2.4.2  nathanw  				found = 1;
    356  1.2.4.2  nathanw  			}
    357  1.2.4.2  nathanw  			++loop;
    358  1.2.4.2  nathanw  		}
    359  1.2.4.2  nathanw 	}
    360  1.2.4.2  nathanw 
    361  1.2.4.2  nathanw 	vidc_currentmode->log2_bpp = bootconfig.log2_bpp;
    362  1.2.4.2  nathanw 
    363  1.2.4.2  nathanw 	dispstart = dispbase;
    364  1.2.4.2  nathanw 	dispend = dispstart+dispsize;
    365  1.2.4.2  nathanw 
    366  1.2.4.2  nathanw 	IOMD_WRITE_WORD(IOMD_VIDINIT, dispstart-ptov);
    367  1.2.4.2  nathanw 	IOMD_WRITE_WORD(IOMD_VIDSTART, dispstart-ptov);
    368  1.2.4.2  nathanw 	IOMD_WRITE_WORD(IOMD_VIDEND, (dispend-transfersize)-ptov);
    369  1.2.4.2  nathanw 	return 0;
    370  1.2.4.2  nathanw }
    371  1.2.4.2  nathanw 
    372  1.2.4.2  nathanw 
    373  1.2.4.2  nathanw /* simple function to abstract vidc variables ; returns virt start address of screen */
    374  1.2.4.2  nathanw /* XXX asumption that video memory is mapped in twice */
    375  1.2.4.2  nathanw void *vidcvideo_hwscroll(int bytes) {
    376  1.2.4.2  nathanw 	dispstart += bytes;
    377  1.2.4.2  nathanw 	if (dispstart >= dispbase + dispsize) dispstart -= dispsize;
    378  1.2.4.2  nathanw 	if (dispstart <  dispbase)            dispstart += dispsize;
    379  1.2.4.2  nathanw 	dispend = dispstart+dispsize;
    380  1.2.4.2  nathanw 
    381  1.2.4.2  nathanw 	/* return the start of the bit map of the screen (left top) */
    382  1.2.4.2  nathanw 	return (void *) dispstart;
    383  1.2.4.2  nathanw }
    384  1.2.4.2  nathanw 
    385  1.2.4.2  nathanw 
    386  1.2.4.2  nathanw /* reset the HW scroll to be at the start for the benefit of f.e. X */
    387  1.2.4.2  nathanw void *vidcvideo_hwscroll_reset(void) {
    388  1.2.4.2  nathanw 	void *cookie = (void *) dispstart;
    389  1.2.4.2  nathanw 
    390  1.2.4.2  nathanw 	dispstart = dispbase;
    391  1.2.4.2  nathanw 	dispend = dispstart + dispsize;
    392  1.2.4.2  nathanw 	return cookie;
    393  1.2.4.2  nathanw }
    394  1.2.4.2  nathanw 
    395  1.2.4.2  nathanw 
    396  1.2.4.2  nathanw /* put HW scroll back to where it was */
    397  1.2.4.2  nathanw void *vidcvideo_hwscroll_back(void *cookie) {
    398  1.2.4.2  nathanw 	dispstart = (int) cookie;
    399  1.2.4.2  nathanw 	dispend = dispstart + dispsize;
    400  1.2.4.2  nathanw 	return cookie;
    401  1.2.4.2  nathanw }
    402  1.2.4.2  nathanw 
    403  1.2.4.2  nathanw 
    404  1.2.4.4  nathanw /* this function is to be called perferably at vsync */
    405  1.2.4.2  nathanw void vidcvideo_progr_scroll(void) {
    406  1.2.4.2  nathanw 	IOMD_WRITE_WORD(IOMD_VIDINIT, dispstart-ptov);
    407  1.2.4.2  nathanw 	IOMD_WRITE_WORD(IOMD_VIDSTART, dispstart-ptov);
    408  1.2.4.2  nathanw 	IOMD_WRITE_WORD(IOMD_VIDEND, (dispend-transfersize)-ptov);
    409  1.2.4.2  nathanw }
    410  1.2.4.2  nathanw 
    411  1.2.4.2  nathanw 
    412  1.2.4.2  nathanw /*
    413  1.2.4.2  nathanw  * Select a new mode by reprogramming the VIDC chip
    414  1.2.4.2  nathanw  * XXX this part is known not to work for 32bpp
    415  1.2.4.2  nathanw  */
    416  1.2.4.2  nathanw 
    417  1.2.4.2  nathanw struct vidc_mode newmode;
    418  1.2.4.2  nathanw 
    419  1.2.4.2  nathanw static const int bpp_mask_table[] = {
    420  1.2.4.2  nathanw 	0,  /* 1bpp */
    421  1.2.4.2  nathanw 	1,  /* 2bpp */
    422  1.2.4.2  nathanw 	2,  /* 4bpp */
    423  1.2.4.2  nathanw 	3,  /* 8bpp */
    424  1.2.4.2  nathanw 	4,  /* 16bpp */
    425  1.2.4.2  nathanw 	6   /* 32bpp */
    426  1.2.4.2  nathanw };
    427  1.2.4.2  nathanw 
    428  1.2.4.2  nathanw 
    429  1.2.4.2  nathanw void
    430  1.2.4.2  nathanw vidcvideo_setmode(struct vidc_mode *mode)
    431  1.2.4.2  nathanw {
    432  1.2.4.2  nathanw 	register int acc;
    433  1.2.4.2  nathanw 	int bpp_mask;
    434  1.2.4.2  nathanw         int ereg;
    435  1.2.4.2  nathanw 	int best_r, best_v;
    436  1.2.4.2  nathanw 	int least_error;
    437  1.2.4.2  nathanw 	int r, v, f;
    438  1.2.4.2  nathanw 
    439  1.2.4.2  nathanw 	/*
    440  1.2.4.2  nathanw 	 * Find out what bit mask we need to or with the vidc20 control register
    441  1.2.4.2  nathanw 	 * in order to generate the desired number of bits per pixel.
    442  1.2.4.2  nathanw 	 * log_bpp is log base 2 of the number of bits per pixel.
    443  1.2.4.2  nathanw 	 */
    444  1.2.4.2  nathanw 
    445  1.2.4.2  nathanw 	bpp_mask = bpp_mask_table[mode->log2_bpp];
    446  1.2.4.2  nathanw 
    447  1.2.4.2  nathanw 	newmode = *mode;
    448  1.2.4.2  nathanw 	vidc_currentmode = &newmode;
    449  1.2.4.2  nathanw 
    450  1.2.4.2  nathanw 	least_error = INT_MAX;
    451  1.2.4.2  nathanw 	best_r = 0; best_v = 0;
    452  1.2.4.2  nathanw 
    453  1.2.4.2  nathanw 	for (v = 63; v > 0; v--) {
    454  1.2.4.2  nathanw 		for (r = 63; r > 0; r--) {
    455  1.2.4.2  nathanw 			f = ((v * vidc_fref) /1000) / r;
    456  1.2.4.2  nathanw 			if (least_error >=
    457  1.2.4.2  nathanw 			    abs(f - vidc_currentmode->pixel_rate)) {
    458  1.2.4.2  nathanw 				least_error =
    459  1.2.4.2  nathanw 				    abs(f - vidc_currentmode->pixel_rate);
    460  1.2.4.2  nathanw 				best_r = r;
    461  1.2.4.2  nathanw 				best_v = v;
    462  1.2.4.2  nathanw 			}
    463  1.2.4.2  nathanw 		}
    464  1.2.4.2  nathanw 	}
    465  1.2.4.2  nathanw 
    466  1.2.4.2  nathanw 	if (best_r > 63) best_r=63;
    467  1.2.4.2  nathanw 	if (best_v > 63) best_v=63;
    468  1.2.4.2  nathanw 	if (best_r < 1)  best_r= 1;
    469  1.2.4.2  nathanw 	if (best_v < 1)  best_v= 1;
    470  1.2.4.2  nathanw 
    471  1.2.4.2  nathanw 	vidcvideo_write(VIDC_FSYNREG, (best_v-1)<<8 | (best_r-1)<<0);
    472  1.2.4.2  nathanw 
    473  1.2.4.2  nathanw 	acc=0;
    474  1.2.4.2  nathanw 	acc+=vidc_currentmode->hswr;	vidcvideo_write(VIDC_HSWR, (acc - 8 ) & (~1));
    475  1.2.4.2  nathanw 	acc+=vidc_currentmode->hbsr;	vidcvideo_write(VIDC_HBSR, (acc - 12) & (~1));
    476  1.2.4.2  nathanw 	acc+=vidc_currentmode->hdsr;	vidcvideo_write(VIDC_HDSR, (acc - 18) & (~1));
    477  1.2.4.2  nathanw 	acc+=vidc_currentmode->hder;	vidcvideo_write(VIDC_HDER, (acc - 18) & (~1));
    478  1.2.4.2  nathanw 	acc+=vidc_currentmode->hber;	vidcvideo_write(VIDC_HBER, (acc - 12) & (~1));
    479  1.2.4.2  nathanw 	acc+=vidc_currentmode->hcr;	vidcvideo_write(VIDC_HCR,  (acc - 8 ) & (~3));
    480  1.2.4.2  nathanw 
    481  1.2.4.2  nathanw 	acc=0;
    482  1.2.4.2  nathanw 	acc+=vidc_currentmode->vswr;	vidcvideo_write(VIDC_VSWR, (acc - 1));
    483  1.2.4.2  nathanw 	acc+=vidc_currentmode->vbsr;	vidcvideo_write(VIDC_VBSR, (acc - 1));
    484  1.2.4.2  nathanw 	acc+=vidc_currentmode->vdsr;	vidcvideo_write(VIDC_VDSR, (acc - 1));
    485  1.2.4.2  nathanw 	acc+=vidc_currentmode->vder;	vidcvideo_write(VIDC_VDER, (acc - 1));
    486  1.2.4.2  nathanw 	acc+=vidc_currentmode->vber;	vidcvideo_write(VIDC_VBER, (acc - 1));
    487  1.2.4.2  nathanw 	acc+=vidc_currentmode->vcr;	vidcvideo_write(VIDC_VCR,  (acc - 1));
    488  1.2.4.2  nathanw 
    489  1.2.4.2  nathanw 	IOMD_WRITE_WORD(IOMD_FSIZE, vidc_currentmode->vcr
    490  1.2.4.2  nathanw 	    + vidc_currentmode->vswr
    491  1.2.4.2  nathanw 	    + vidc_currentmode->vber
    492  1.2.4.2  nathanw 	    + vidc_currentmode->vbsr - 1);
    493  1.2.4.2  nathanw 
    494  1.2.4.2  nathanw 	if (dispsize <= 1024*1024)
    495  1.2.4.2  nathanw 		vidcvideo_write(VIDC_DCTL, vidc_currentmode->hder>>2 | 1<<16 | 1<<12);
    496  1.2.4.2  nathanw 	else
    497  1.2.4.2  nathanw 		vidcvideo_write(VIDC_DCTL, vidc_currentmode->hder>>2 | 3<<16 | 1<<12);
    498  1.2.4.2  nathanw 
    499  1.2.4.2  nathanw 	ereg = 1<<12;
    500  1.2.4.2  nathanw 	if (vidc_currentmode->sync_pol & 0x01)
    501  1.2.4.2  nathanw 		ereg |= 1<<16;
    502  1.2.4.2  nathanw 	if (vidc_currentmode->sync_pol & 0x02)
    503  1.2.4.2  nathanw 		ereg |= 1<<18;
    504  1.2.4.2  nathanw 	vidcvideo_write(VIDC_EREG, ereg);
    505  1.2.4.2  nathanw 	if (dispsize > 1024*1024) {
    506  1.2.4.2  nathanw 		if (vidc_currentmode->hder >= 800)
    507  1.2.4.2  nathanw  			vidcvideo_write(VIDC_CONREG, 7<<8 | bpp_mask<<5);
    508  1.2.4.2  nathanw 		else
    509  1.2.4.2  nathanw 			vidcvideo_write(VIDC_CONREG, 6<<8 | bpp_mask<<5);
    510  1.2.4.2  nathanw 	} else {
    511  1.2.4.2  nathanw 		vidcvideo_write(VIDC_CONREG, 7<<8 | bpp_mask<<5);
    512  1.2.4.2  nathanw 	}
    513  1.2.4.2  nathanw }
    514  1.2.4.2  nathanw 
    515  1.2.4.2  nathanw 
    516  1.2.4.3  nathanw #if 0
    517  1.2.4.2  nathanw /* not used for now */
    518  1.2.4.2  nathanw void
    519  1.2.4.2  nathanw vidcvideo_set_display_base(base)
    520  1.2.4.2  nathanw 	u_int base;
    521  1.2.4.2  nathanw {
    522  1.2.4.2  nathanw 	dispstart = dispstart-dispbase + base;
    523  1.2.4.2  nathanw 	dispbase = vmem_base = base;
    524  1.2.4.2  nathanw 	dispend = base + dispsize;
    525  1.2.4.2  nathanw 	ptov = dispbase - phys_base;
    526  1.2.4.2  nathanw }
    527  1.2.4.3  nathanw #endif
    528  1.2.4.2  nathanw 
    529  1.2.4.2  nathanw 
    530  1.2.4.2  nathanw /*
    531  1.2.4.2  nathanw  * Main initialisation routine for now
    532  1.2.4.2  nathanw  */
    533  1.2.4.2  nathanw 
    534  1.2.4.2  nathanw static int cursor_init = 0;
    535  1.2.4.2  nathanw 
    536  1.2.4.2  nathanw int
    537  1.2.4.2  nathanw vidcvideo_init(void)
    538  1.2.4.2  nathanw {
    539  1.2.4.2  nathanw 	vidcvideo_coldinit();
    540  1.2.4.2  nathanw 	if (cold_init && (cursor_init == 0))
    541  1.2.4.2  nathanw 		/*	vidcvideo_flash_go() */;
    542  1.2.4.2  nathanw 
    543  1.2.4.2  nathanw 	/* setting a mode goes wrong in 32 bpp ... 8 and 16 seem OK */
    544  1.2.4.2  nathanw 	vidcvideo_setmode(vidc_currentmode);
    545  1.2.4.2  nathanw 	vidcvideo_blank(0);			/* display on */
    546  1.2.4.2  nathanw 
    547  1.2.4.5  nathanw 	vidcvideo_stdpalette();
    548  1.2.4.2  nathanw 
    549  1.2.4.2  nathanw 	if (cold_init == 0) {
    550  1.2.4.2  nathanw 		vidcvideo_write(VIDC_CP1, 0x0);
    551  1.2.4.2  nathanw 		vidcvideo_write(VIDC_CP2, 0x0);
    552  1.2.4.2  nathanw 		vidcvideo_write(VIDC_CP3, 0x0);
    553  1.2.4.2  nathanw 	} else {
    554  1.2.4.2  nathanw 		vidcvideo_cursor_init(CURSOR_MAX_WIDTH, CURSOR_MAX_HEIGHT);
    555  1.2.4.2  nathanw 	};
    556  1.2.4.2  nathanw 
    557  1.2.4.2  nathanw 	cold_init=1;
    558  1.2.4.2  nathanw 	return 0;
    559  1.2.4.2  nathanw }
    560  1.2.4.2  nathanw 
    561  1.2.4.2  nathanw 
    562  1.2.4.2  nathanw /* reinitialise the vidcvideo */
    563  1.2.4.2  nathanw void
    564  1.2.4.2  nathanw vidcvideo_reinit()
    565  1.2.4.2  nathanw {
    566  1.2.4.2  nathanw 	vidcvideo_coldinit();
    567  1.2.4.2  nathanw 	vidcvideo_setmode(vidc_currentmode);
    568  1.2.4.2  nathanw }
    569  1.2.4.2  nathanw 
    570  1.2.4.2  nathanw 
    571  1.2.4.2  nathanw int
    572  1.2.4.2  nathanw vidcvideo_cursor_init(int width, int height)
    573  1.2.4.2  nathanw {
    574  1.2.4.2  nathanw 	static char *cursor_data = NULL;
    575  1.2.4.2  nathanw 	int counter;
    576  1.2.4.2  nathanw 	int line;
    577  1.2.4.2  nathanw 	paddr_t pa;
    578  1.2.4.2  nathanw 
    579  1.2.4.2  nathanw 	cursor_width  = width;
    580  1.2.4.2  nathanw 	cursor_height = height;
    581  1.2.4.2  nathanw 
    582  1.2.4.2  nathanw 	if (!cursor_data) {
    583  1.2.4.2  nathanw 		/* Allocate cursor memory first time round */
    584  1.2.4.2  nathanw 		cursor_data = (char *)uvm_km_zalloc(kernel_map, NBPG);
    585  1.2.4.2  nathanw 		if (!cursor_data)
    586  1.2.4.7  nathanw 			panic("Cannot allocate memory for hardware cursor");
    587  1.2.4.2  nathanw 		(void) pmap_extract(pmap_kernel(), (vaddr_t)cursor_data, &pa);
    588  1.2.4.2  nathanw 		IOMD_WRITE_WORD(IOMD_CURSINIT, pa);
    589  1.2.4.2  nathanw 	}
    590  1.2.4.2  nathanw 
    591  1.2.4.2  nathanw 	/* Blank the cursor while initialising it's sprite */
    592  1.2.4.2  nathanw 
    593  1.2.4.2  nathanw 	vidcvideo_write ( VIDC_CP1, 0x0 );
    594  1.2.4.2  nathanw 	vidcvideo_write ( VIDC_CP2, 0x0 );
    595  1.2.4.2  nathanw 	vidcvideo_write ( VIDC_CP3, 0x0 );
    596  1.2.4.2  nathanw 
    597  1.2.4.2  nathanw  	cursor_normal       = cursor_data;
    598  1.2.4.2  nathanw 	cursor_transparent  = cursor_data + (height * width);
    599  1.2.4.2  nathanw 
    600  1.2.4.2  nathanw  	cursor_transparent += 32;					/* ALIGN */
    601  1.2.4.2  nathanw 	cursor_transparent = (char *)((int)cursor_transparent & (~31) );
    602  1.2.4.2  nathanw 
    603  1.2.4.2  nathanw 	for ( line = 0; line<height; ++ line )
    604  1.2.4.2  nathanw 	{
    605  1.2.4.2  nathanw 	    for ( counter=0; counter<width/4;counter++ )
    606  1.2.4.2  nathanw 		cursor_normal[line * width + counter]=0x55;		/* why 0x55 ? */
    607  1.2.4.2  nathanw 	    for ( ; counter<8; counter++ )
    608  1.2.4.2  nathanw 		cursor_normal[line * width + counter]=0;
    609  1.2.4.2  nathanw 	}
    610  1.2.4.2  nathanw 
    611  1.2.4.2  nathanw 	for ( line = 0; line<height; ++ line )
    612  1.2.4.2  nathanw 	{
    613  1.2.4.2  nathanw 	    for ( counter=0; counter<width/4;counter++ )
    614  1.2.4.2  nathanw 		cursor_transparent[line * width + counter]=0x00;
    615  1.2.4.2  nathanw 	    for ( ; counter<8; counter++ )
    616  1.2.4.2  nathanw 		cursor_transparent[line * width + counter]=0;
    617  1.2.4.2  nathanw 	}
    618  1.2.4.2  nathanw 
    619  1.2.4.2  nathanw 
    620  1.2.4.2  nathanw 	(void) pmap_extract(pmap_kernel(), (vaddr_t)cursor_normal,
    621  1.2.4.2  nathanw 	    (paddr_t *)&p_cursor_normal);
    622  1.2.4.2  nathanw 	(void) pmap_extract(pmap_kernel(), (vaddr_t)cursor_transparent,
    623  1.2.4.2  nathanw 	    (paddr_t *)&p_cursor_transparent);
    624  1.2.4.2  nathanw 
    625  1.2.4.2  nathanw 	memset ( cursor_normal, 0x55, width*height );			/* white? */
    626  1.2.4.2  nathanw 	memset ( cursor_transparent, 0x00, width*height );		/* to see the diffence */
    627  1.2.4.2  nathanw 
    628  1.2.4.2  nathanw 	/* Ok, now program the cursor; should be blank */
    629  1.2.4.2  nathanw 	vidcvideo_enablecursor(0);
    630  1.2.4.2  nathanw 
    631  1.2.4.2  nathanw         return 0;
    632  1.2.4.2  nathanw }
    633  1.2.4.2  nathanw 
    634  1.2.4.2  nathanw 
    635  1.2.4.2  nathanw void
    636  1.2.4.2  nathanw vidcvideo_updatecursor(xcur, ycur)
    637  1.2.4.2  nathanw 	int xcur, ycur;
    638  1.2.4.2  nathanw {
    639  1.2.4.2  nathanw 	int frontporch = vidc_currentmode->hswr + vidc_currentmode->hbsr + vidc_currentmode->hdsr;
    640  1.2.4.2  nathanw 	int topporch   = vidc_currentmode->vswr + vidc_currentmode->vbsr + vidc_currentmode->vdsr;
    641  1.2.4.2  nathanw 
    642  1.2.4.2  nathanw 	vidcvideo_write(VIDC_HCSR, frontporch -17 + xcur);
    643  1.2.4.2  nathanw 	vidcvideo_write(VIDC_VCSR, topporch   -2  + (ycur+1)-2 + 3 - cursor_height);
    644  1.2.4.2  nathanw 	vidcvideo_write(VIDC_VCER, topporch   -2  + (ycur+3)+2 + 3 );
    645  1.2.4.2  nathanw 	return;
    646  1.2.4.2  nathanw }
    647  1.2.4.2  nathanw 
    648  1.2.4.2  nathanw 
    649  1.2.4.2  nathanw void
    650  1.2.4.2  nathanw vidcvideo_enablecursor(on)
    651  1.2.4.2  nathanw 	int on;
    652  1.2.4.2  nathanw {
    653  1.2.4.2  nathanw 	if (on) {
    654  1.2.4.2  nathanw 		IOMD_WRITE_WORD(IOMD_CURSINIT,p_cursor_normal);
    655  1.2.4.2  nathanw 	} else {
    656  1.2.4.2  nathanw 		IOMD_WRITE_WORD(IOMD_CURSINIT,p_cursor_transparent);
    657  1.2.4.2  nathanw 	};
    658  1.2.4.2  nathanw 	vidcvideo_write ( VIDC_CP1, 0xffffff );		/* enable */
    659  1.2.4.2  nathanw 
    660  1.2.4.2  nathanw 	return;
    661  1.2.4.2  nathanw }
    662  1.2.4.2  nathanw 
    663  1.2.4.2  nathanw 
    664  1.2.4.5  nathanw void
    665  1.2.4.5  nathanw vidcvideo_stdpalette()
    666  1.2.4.2  nathanw {
    667  1.2.4.5  nathanw 	int i;
    668  1.2.4.2  nathanw 
    669  1.2.4.5  nathanw 	switch (vidc_currentmode->log2_bpp) {
    670  1.2.4.5  nathanw 	case 0: /* 1 bpp */
    671  1.2.4.5  nathanw 	case 1: /* 2 bpp */
    672  1.2.4.5  nathanw 	case 2: /* 4 bpp */
    673  1.2.4.5  nathanw 	case 3: /* 8 bpp */
    674  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALREG, 0x00000000);
    675  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALETTE, VIDC_COL(  0,   0,   0));
    676  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALETTE, VIDC_COL(255,   0,   0));
    677  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALETTE, VIDC_COL(  0, 255,   0));
    678  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 255,   0));
    679  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALETTE, VIDC_COL(  0,   0, 255));
    680  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALETTE, VIDC_COL(255,   0, 255));
    681  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALETTE, VIDC_COL(  0, 255, 255));
    682  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 255, 255));
    683  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALETTE, VIDC_COL(128, 128, 128));
    684  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 128, 128));
    685  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALETTE, VIDC_COL(128, 255, 128));
    686  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 255, 128));
    687  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALETTE, VIDC_COL(128, 128, 255));
    688  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 128, 255));
    689  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALETTE, VIDC_COL(255, 255, 255));
    690  1.2.4.5  nathanw 		break;
    691  1.2.4.5  nathanw 	case 4: /* 16 bpp */
    692  1.2.4.5  nathanw 		/*
    693  1.2.4.5  nathanw 		 * The use of the palette in 16-bit modes is quite
    694  1.2.4.5  nathanw 		 * fun.  Comments in linux/drivers/video/acornfb.c
    695  1.2.4.5  nathanw 		 * imply that it goes something like this:
    696  1.2.4.5  nathanw 		 *
    697  1.2.4.5  nathanw 		 * red   = LUT[pixel[7:0]].red
    698  1.2.4.5  nathanw 		 * green = LUT[pixel[11:4]].green
    699  1.2.4.5  nathanw 		 * blue  = LUT[pixel[15:8]].blue
    700  1.2.4.5  nathanw 		 *
    701  1.2.4.6  nathanw 		 * We use 6:5:5 R:G:B cos that's what Xarm32VIDC wants.
    702  1.2.4.5  nathanw 		 */
    703  1.2.4.6  nathanw #define RBITS 6
    704  1.2.4.6  nathanw #define GBITS 5
    705  1.2.4.6  nathanw #define BBITS 5
    706  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALREG, 0x00000000);
    707  1.2.4.5  nathanw 		for (i = 0; i < 256; i++) {
    708  1.2.4.6  nathanw 			int r, g, b;
    709  1.2.4.5  nathanw 
    710  1.2.4.6  nathanw 			r = i & ((1 << RBITS) - 1);
    711  1.2.4.6  nathanw 			g = (i >> (RBITS - 4)) & ((1 << GBITS) - 1);
    712  1.2.4.6  nathanw 			b = (i >> (RBITS + GBITS - 8)) & ((1 << BBITS) - 1);
    713  1.2.4.5  nathanw 			vidcvideo_write(VIDC_PALETTE,
    714  1.2.4.6  nathanw 			    VIDC_COL(r << (8 - RBITS) | r >> (2 * RBITS - 8),
    715  1.2.4.6  nathanw 				g << (8 - GBITS) | g >> (2 * GBITS - 8),
    716  1.2.4.6  nathanw 				b << (8 - BBITS) | b >> (2 * BBITS - 8)));
    717  1.2.4.5  nathanw 		}
    718  1.2.4.5  nathanw 		break;
    719  1.2.4.5  nathanw 	case 5: /* 32 bpp */
    720  1.2.4.5  nathanw 		vidcvideo_write(VIDC_PALREG, 0x00000000);
    721  1.2.4.5  nathanw 		for (i = 0; i < 256; i++)
    722  1.2.4.5  nathanw 			vidcvideo_write(VIDC_PALETTE, VIDC_COL(i, i, i));
    723  1.2.4.5  nathanw 		break;
    724  1.2.4.5  nathanw 	}
    725  1.2.4.5  nathanw 
    726  1.2.4.2  nathanw }
    727  1.2.4.2  nathanw 
    728  1.2.4.2  nathanw int
    729  1.2.4.2  nathanw vidcvideo_blank(video_off)
    730  1.2.4.2  nathanw 	int video_off;
    731  1.2.4.2  nathanw {
    732  1.2.4.2  nathanw         int ereg;
    733  1.2.4.2  nathanw 
    734  1.2.4.2  nathanw 	ereg = 1<<12;
    735  1.2.4.2  nathanw 	if (vidc_currentmode->sync_pol & 0x01)
    736  1.2.4.2  nathanw 		ereg |= 1<<16;
    737  1.2.4.2  nathanw 	if (vidc_currentmode->sync_pol & 0x02)
    738  1.2.4.2  nathanw 		ereg |= 1<<18;
    739  1.2.4.2  nathanw 
    740  1.2.4.2  nathanw 	if (!video_off) {
    741  1.2.4.2  nathanw     		vidcvideo_write(VIDC_EREG, ereg);
    742  1.2.4.2  nathanw 	} else {
    743  1.2.4.2  nathanw 		vidcvideo_write(VIDC_EREG, 0);
    744  1.2.4.2  nathanw 	};
    745  1.2.4.2  nathanw 	return 0;
    746  1.2.4.2  nathanw }
    747  1.2.4.2  nathanw 
    748  1.2.4.2  nathanw /* end of vidc20config.c */
    749