/*      $NetBSD: cg2reg.h,v 1.7 2023/03/28 20:01:57 andvar Exp $ */

/*
* Copyright (c) 1994 Dennis Ferguson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in the
*    documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/* cg2reg.h - CG2 colour frame buffer definitions
*
* The mapped memory looks like:
*
*  offset     contents
* 0x000000  bit plane map - 1st (of 8) plane used by the X server in -mono mode
* 0x100000  pixel map - used by the X server in color mode
* 0x200000  raster op mode memory map - unused by X server
* 0x300000  random control registers (lots of spaces in between)
* 0x310000  shadow colour map
*/

/* Frame buffer memory size and depth */
#define CG2_FBSIZE      (1024 * 1024)
#define CG2_N_PLANE     8

/* Screen dimensions */
#define CG2_WIDTH       1152
#define CG2_HEIGHT      900

/* arrangement of bit plane mode memory */
union bitplane {
       u_short word[CG2_HEIGHT][CG2_WIDTH/(CG2_N_PLANE * sizeof(u_short))];
       u_short plane[CG2_FBSIZE/(CG2_N_PLANE * sizeof(u_short))];
};

/* arrangement of pixel mode memory */
union byteplane {
       u_char pixel[CG2_HEIGHT][CG2_WIDTH];
       u_char frame[CG2_FBSIZE];
};


/*
* Structure describing the first two megabytes of the frame buffer.
* Normal memory maps in bit plane and pixel modes
*/
struct cg2memfb {
       union bitplane memplane[CG2_N_PLANE];   /* bit plane map */
       union byteplane pixplane;               /* pixel map */
};


/*
* Control/status register.  The X server only appears to use update_cmap
* and video_enab.
*/
struct cg2statusreg {
       u_int reserved : 2;     /* not used */
       u_int fastread : 1;     /* r/o: has some feature I don't understand */
       u_int id : 1;           /* r/o: ext status and ID registers exist */
       u_int resolution : 4;   /* screen resolution, 0 means 1152x900 */
       u_int retrace : 1;      /* r/o: retrace in progress */
       u_int inpend : 1;       /* r/o: interrupt request */
       u_int ropmode : 3;      /* ?? */
       u_int inten : 1;        /* interrupt enable (for end of retrace) */
       u_int update_cmap : 1;  /* copy/use shadow colour map */
       u_int video_enab : 1;   /* enable video */
};


/*
* Extended status register.  Unused by X server
*/
struct cg2_extstatus {
       u_int gpintreq : 1;     /* interrupt request */
       u_int gpintdis : 1;     /* interrupt disable */
       u_int reserved : 13;    /* unused */
       u_int gpbus : 1;        /* bus enabled */
};


/*
* Double buffer control register.  It appears that (some of?) the
* cg2 cards support a pair of memory sets, referred to as `A' and
* `B', which can be swapped to allow atomic screen updates.  This
* controls them.
*/
struct dblbufreg {
       u_int display_b : 1;    /* display memory B (set) or A (reset) */
       u_int read_b : 1;       /* access memory B (set) or A (reset) */
       u_int nowrite_b : 1;    /* when set, writes don't update memory B */
       u_int nowrite_a : 1;    /* when set, writes don't update memory A */
       u_int read_ecmap : 1;   /* copy from(clear)/to(set) shadow colour map */
       u_int fast_read : 1;    /* fast reads, but wrong data */
       u_int wait : 1;         /* when set, remains so to end up v. retrace */
       u_int update_ecmap : 1; /* copy/use shadow colour map */
       u_int reserved : 8;
};


/*
* Zoom register, apparently present on Sun-2 colour boards only.  See
* the Sun documentation, I don't know anyone who still has a Sun-2.
*/
struct cg2_zoom {
       union {
               u_short reg;
               u_char reg_pad[4096];
       } wordpan;
       union {
               struct {
                       u_int unused  : 8;
                       u_int lineoff : 4;
                       u_int pixzoom : 4;
               } reg;
               u_short word;
               u_char reg_pad[4096];
       } zoom;
       union {
               struct {
                       u_int unused   : 8;
                       u_int lorigin  : 4;
                       u_int pixeloff : 4;
               } reg;
               u_short word;
               u_char reg_pad[4096];
       } pixpan;
       union {
               u_short reg;
               u_char reg_pad[4096];
       } varzoom;
};


/*
* Miscellany.  On the Sun-3 these registers exist in place of the above.
*/
struct cg2_nozoom {
       union {                         /* double buffer register (see above) */
               struct dblbufreg reg;
               u_short word;
               u_char reg_pad[4096];
       } dblbuf;
       union {                         /* start of DMA window */
               u_short reg;
               u_char reg_pad[4096];
       } dmabase;
       union {                         /* DMA window size */
               u_short reg;            /* actually 8 bits.  reg*16 == size */
               u_char reg_pad[4096];
       } dmawidth;
       union {                         /* frame count */
               u_short reg;            /* actually 8 bits only. r/o */
               u_char reg_pad[4096];
       } framecnt;
};


/*
* Raster op control registers.  X doesn't use this, but documented here
* for future reference.
*/
struct memropc {
       u_short mrc_dest;
       u_short mrc_source1;
       u_short mrc_source2;
       u_short mrc_pattern;
       u_short mrc_mask1;
       u_short mrc_mask2;
       u_short mrc_shift;
       u_short mrc_op;
       u_short mrc_width;
       u_short mrc_opcount;
       u_short mrc_decoderout;
       u_short mrc_x11;
       u_short mrc_x12;
       u_short mrc_x13;
       u_short mrc_x14;
       u_short mrc_x15;
};


/*
* Last chunk of the frame buffer (i.e. from offset 0x200000 and above).
* Exists separately from struct cg2memfb apparently because Sun software
* avoids mapping the latter, though X uses it.
*/
struct cg2fb {

#ifndef _KERNEL /* XXX - Hack! */
       /* XXX - Don't want this permanently in the kernel mapping. */
       union {                 /* raster op mode frame memory */
               union bitplane ropplane[CG2_N_PLANE];
               union byteplane roppixel;
       } ropio;
#endif  /* _KERNEL      XXX - Hack! */

       union {                 /* raster op control unit (1 per plane) */
               struct memropc ropregs;
               struct {
                       u_char pad[2048];
                       struct memropc ropregs;
               } prime;
               u_char reg_pad[4096];
       } ropcontrol[9];
       union {                 /* status register */
               struct cg2statusreg reg;
               u_short word;
               u_char reg_pad[4096];
       } status;
       union {                 /* per-plane mask register */
               u_short reg;    /* 8 bit mask register - set means plane r/w */
               u_char reg_pad[4096];
       } ppmask;
       union {                 /* miscellaneous registers */
               struct cg2_zoom zoom;
               struct cg2_nozoom nozoom;
       } misc;
       union {                 /* interrupt vector */
               u_short reg;
               u_char reg_pad[32];
       } intrptvec;
       union {                  /* board ID */
               u_short reg;
               u_char reg_pad[16];
       } id;
       union {                  /* extended status */
               struct cg2_extstatus reg;
               u_short word;
               u_char reg_pad[16];
       } extstatus;
       union {                  /* auxiliary raster op mode register (?)*/
               u_short reg;
               u_char reg_pad[4032];
       } ropmode;
       u_short redmap[256];    /* shadow colour maps */
       u_short greenmap[256];
       u_short bluemap[256];
};