code:
/*	$OpenBSD: ts102reg.h,v 1.8 2008/06/26 05:42:13 ray Exp $	*/
/*	$NetBSD: ts102reg.h,v 1.7 2002/09/29 23:23:58 wiz Exp $ */

/*-
 * Copyright (c) 1998 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Matt Thomas.
 *
 * 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``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 FOUNDATION OR CONTRIBUTORS
 * 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.
 */
#ifndef _SPARC_DEV_TS102REG_H
#define	_SPARC_DEV_TS102REG_H

/* The TS102 consumes a 256MB region of the SPARCbook 3's address space.
 */
#define TS102_OFFSET_REGISTERS		0x02000000
#define TS102_OFFSET_CARD_A_ATTR_SPACE	0x04000000
#define TS102_OFFSET_CARD_B_ATTR_SPACE	0x05000000
#define TS102_SIZE_ATTR_SPACE		0x01000000
#define TS102_OFFSET_CARD_A_IO_SPACE	0x06000000
#define TS102_OFFSET_CARD_B_IO_SPACE	0x07000000
#define TS102_SIZE_IO_SPACE		0x01000000
#define TS102_OFFSET_CARD_A_MEM_SPACE	0x08000000
#define TS102_OFFSET_CARD_B_MEM_SPACE	0x0c000000
#define TS102_SIZE_MEM_SPACE		0x04000000

/* There are two separate register blocks within the TS102.  The first
 * gives access to PCMCIA card specific resources, and the second gives
 * access to the microcontroller interface
 */
#define	TS102_REG_CARD_A_INT	0x0000	/* Card A Interrupt Register */
#define	TS102_REG_CARD_A_STS	0x0004	/* Card A Status Register */
#define	TS102_REG_CARD_A_CTL	0x0008	/* Card A Control Register */
#define	TS102_REG_CARD_B_INT	0x0010	/* Card B Interrupt Register */
#define	TS102_REG_CARD_B_STS	0x0014	/* Card B Status Register */
#define	TS102_REG_CARD_B_CTL	0x0018	/* Card B Control Register */
#define	TS102_REG_UCTRL_INT	0x0020	/* Microcontroller Interrupt Register */
#define	TS102_REG_UCTRL_DATA	0x0024	/* Microcontroller Data Register */
#define	TS102_REG_UCTRL_STS	0x0028	/* Microcontroller Status Register */

struct uctrl_regs {
	volatile u_int8_t	intr;	/* Microcontroller Interrupt Reg */
	volatile u_int8_t	filler0[3];
	volatile u_int8_t	data;	/* Microcontroller Data Reg */
	volatile u_int8_t	filler1[3];
	volatile u_int8_t	stat;	/* Microcontroller Status Reg */
	volatile u_int8_t	filler2[3];
};

/* TS102 Card Interrupt Register definitions.
 *
 * There is one 16-bit interrupt register for each card.  Each register
 * contains interrupt status (read) and clear (write) bits and an
 * interrupt mask for each of the four interrupt sources.
 *
 * The request bit is the logical AND of the status and the mask bit,
 * and indicated and an interrupt is being requested.  The mask bits
 * allow masking of individual interrupts.  An interrupt is enabled when
 * the mask is set to 1 and is clear by write a 1 to the associated
 * request bit.
 *
 * The card interrupt register also contain the soft reset flag.
 * Setting this bit to 1 will the SPARCbook 3 to be reset.
 */
#define	TS102_CARD_INT_RQST_IRQ				0x0001
#define	TS102_CARD_INT_RQST_WP_STATUS_CHANGED		0x0002
#define	TS102_CARD_INT_RQST_BATTERY_STATUS_CHANGED	0x0004
#define	TS102_CARD_INT_RQST_CARDDETECT_STATUS_CHANGED	0x0008
#define	TS102_CARD_INT_STATUS_IRQ			0x0010
#define	TS102_CARD_INT_STATUS_WP_STATUS_CHANGED		0x0020
#define	TS102_CARD_INT_STATUS_BATTERY_STATUS_CHANGED	0x0040
#define	TS102_CARD_INT_STATUS_CARDDETECT_STATUS_CHANGED	0x0080
#define	TS102_CARD_INT_MASK_IRQ				0x0100
#define	TS102_CARD_INT_MASK_WP_STATUS			0x0200
#define	TS102_CARD_INT_MASK_BATTERY_STATUS		0x0400
#define	TS102_CARD_INT_MASK_CARDDETECT_STATUS		0x0800
#define	TS102_CARD_INT_SOFT_RESET			0x1000

/* TS102 Card Status Register definitions.  The Card Status Register
 * contains card status and control bit.
 */
#define	TS102_CARD_STS_PRES		0x0001	/* Card Present (1) */
#define	TS102_CARD_STS_IO		0x0002	/* (1) I/O Card, (0) = Mem Card */
#define	TS102_CARD_STS_TYPE3		0x0004	/* Type-3 PCMCIA card (disk) */
#define	TS102_CARD_STS_VCC		0x0008	/* Vcc (0=5V, 1=3.3V) */
#define	TS102_CARD_STS_VPP1_MASK	0x0030	/* Programming Voltage Control2 */
#define	TS102_CARD_STS_VPP1_NC		0x0030	/*    NC */
#define	TS102_CARD_STS_VPP1_VCC		0x0020	/*    Vcc (3.3V or 5V) */
#define	TS102_CARD_STS_VPP1_VPP		0x0010	/*    Vpp (12V) */
#define	TS102_CARD_STS_VPP1_0V		0x0000	/*    0V */
#define	TS102_CARD_STS_VPP2_MASK	0x00c0	/* Programming Voltage Control1 */
#define	TS102_CARD_STS_VPP2_NC		0x00c0	/*    NC */
#define	TS102_CARD_STS_VPP2_VCC		0x0080	/*    Vcc (3.3V or 5V) */
#define	TS102_CARD_STS_VPP2_VPP		0x0040	/*    Vpp (12V) */
#define	TS102_CARD_STS_VPP2_0V		0x0000	/*    0V */
#define	TS102_CARD_STS_WP		0x0100	/* Write Protect (1) */
#define	TS102_CARD_STS_BVD_MASK		0x0600	/* Battery Voltage Detect */
#define	TS102_CARD_STS_BVD_GOOD		0x0600	/*    Battery good */
#define	TS102_CARD_STS_BVD_LOW_OK	0x0400	/*    Battery low, data OK */
#define	TS102_CARD_STS_BVD_LOW_SUSPECT1	0x0200	/*    Battery low, data suspect */
#define	TS102_CARD_STS_BVD_LOW_SUSPECT0	0x0000	/*    Battery low, data suspect */
#define	TS102_CARD_STS_LVL		0x0800	/* Level (1) / Edge */
#define	TS102_CARD_STS_RDY		0x1000	/* Ready (1) / Not Busy */
#define	TS102_CARD_STS_VCCEN		0x2000	/* Powered Up (0) */
#define	TS102_CARD_STS_RIEN		0x4000	/* Not Supported */
#define	TS102_CARD_STS_ACEN		0x8000	/* Access Enabled (1) */

/* TS102 Card Control Register definitions
 */
#define	TS102_CARD_CTL_AA_MASK		0x0003	/* Attribute Address A[25:24] */
#define	TS102_CARD_CTL_IA_MASK		0x000c	/* I/O Address A[25:24] */
#define	TS102_CARD_CTL_IA_BITPOS	2	/* */
#define	TS102_CARD_CTL_CES_MASK		0x0070	/* CE/address setup time */
#define	TS102_CARD_CTL_CES_BITPOS	4	/* n+1 clocks */
#define	TS102_CARD_CTL_OWE_MASK		0x0380	/* OE/WE width */
#define	TS102_CARD_CTL_OWE_BITPOS	7	/* n+2 clocks */
#define	TS102_CARD_CTL_CEH		0x0400	/* Chip enable hold time */
						/* (0) - 1 clock */
						/* (1) - 2 clocks */
#define	TS102_CARD_CTL_SBLE		0x0800	/* SBus little endian */
#define	TS102_CARD_CTL_PCMBE		0x1000	/* PCMCIA big endian */
#define	TS102_CARD_CTL_RAHD		0x2000	/* Read ahead enable */
#define	TS102_CARD_CTL_INCDIS		0x4000	/* Address increment disable */
#define	TS102_CARD_CTL_PWRD		0x8000	/* Power down */

/* Microcontroller Interrupt Register
 */
#define	TS102_UCTRL_INT_TXE_REQ		0x01	/* transmit FIFO empty */
#define	TS102_UCTRL_INT_TXNF_REQ	0x02	/* transmit FIFO not full */
#define	TS102_UCTRL_INT_RXNE_REQ	0x04	/* receive FIFO not empty */
#define	TS102_UCTRL_INT_RXO_REQ		0x08	/* receive FIFO overflow */
#define	TS102_UCTRL_INT_TXE_MSK		0x10	/* transmit FIFO empty */
#define	TS102_UCTRL_INT_TXNF_MSK	0x20	/* transmit FIFO not full */
#define	TS102_UCTRL_INT_RXNE_MSK	0x40	/* receive FIFO not empty */
#define	TS102_UCTRL_INT_RXO_MSK		0x80	/* receive FIFO overflow */

/* TS102 Microcontroller Data Register (only 8 bits are significant).
 */
#define	TS102_UCTRL_DATA_MASK		0xff

/* TS102 Microcontroller Status Register.
 *	read 1 if asserted
 *	write 1 to clear
 */
#define	TS102_UCTRL_STS_TXE_STA		0x01	/* transmit FIFO empty */
#define	TS102_UCTRL_STS_TXNF_STA	0x02	/* transmit FIFO not full */
#define	TS102_UCTRL_STS_RXNE_STA	0x04	/* receive FIFO not empty */
#define	TS102_UCTRL_STS_RXO_STA		0x08	/* receive FIFO overflow */
#define	TS102_UCTRL_STS_MASK		0x0f	/* Only 4 bits significant */

enum ts102_opcode {			/* Argument	Returned */
    TS102_OP_RD_SERIAL_NUM=0x01,	/* none		ack + 4 bytes */
    TS102_OP_RD_ETHER_ADDR=0x02,	/* none		ack + 6 bytes */
    TS102_OP_RD_HW_VERSION=0x03,	/* none		ack + 2 bytes */
    TS102_OP_RD_UCTLR_VERSION=0x04,	/* none		ack + 2 bytes */
    TS102_OP_RD_MAX_TEMP=0x05,		/* none		ack + 1 bytes */
    TS102_OP_RD_MIN_TEMP=0x06,		/* none		ack + 1 bytes */
    TS102_OP_RD_CURRENT_TEMP=0x07,	/* none		ack + 1 bytes */
    TS102_OP_RD_SYSTEM_VARIANT=0x08,	/* none		ack + 4 bytes */
    TS102_OP_RD_POWERON_CYCLES=0x09,	/* none		ack + 4 bytes */
    TS102_OP_RD_POWERON_SECONDS=0x0a,	/* none		ack + 4 bytes */
    TS102_OP_RD_RESET_STATUS=0x0b,	/* none		ack + 1 bytes */
#define	TS102_RESET_STATUS_RESERVED0	0x00
#define	TS102_RESET_STATUS_POWERON	0x01
#define	TS102_RESET_STATUS_KEYBOARD	0x02
#define	TS102_RESET_STATUS_WATCHDOG	0x03
#define	TS102_RESET_STATUS_TIMEOUT	0x04
#define	TS102_RESET_STATUS_SOFTWARE	0x05
#define	TS102_RESET_STATUS_BROWNOUT	0x06
#define	TS102_RESET_STATUS_RESERVED1	0x07
    TS102_OP_RD_EVENT_STATUS=0x0c,	/* none		ack + 2 bytes */
#define	TS102_EVENT_STATUS_SHUTDOWN_REQUEST			0x0001
#define	TS102_EVENT_STATUS_LOW_POWER_WARNING			0x0002
/* Internal Warning Changed 0x0002 */
#define	TS102_EVENT_STATUS_VERY_LOW_POWER_WARNING		0x0004
/* Discharge Event 0x0004 */
#define	TS102_EVENT_STATUS_BATT_CHANGED				0x0008
/* Internal Status Changed 0x0008 */
#define	TS102_EVENT_STATUS_EXT_KEYBOARD_STATUS_CHANGE		0x0010
#define	TS102_EVENT_STATUS_EXT_MOUSE_STATUS_CHANGE		0x0020
#define	TS102_EVENT_STATUS_EXTERNAL_VGA_STATUS_CHANGE		0x0040
#define	TS102_EVENT_STATUS_LID_STATUS_CHANGE			0x0080
#define	TS102_EVENT_STATUS_MICROCONTROLLER_ERROR		0x0100
#define	TS102_EVENT_STATUS_RESERVED				0x0200
/* Wakeup 0x0200 */
#define	TS102_EVENT_STATUS_EXT_BATT_STATUS_CHANGE		0x0400
#define	TS102_EVENT_STATUS_EXT_BATT_CHARGING_STATUS_CHANGE	0x0800
#define	TS102_EVENT_STATUS_EXT_BATT_LOW_POWER			0x1000
#define	TS102_EVENT_STATUS_DC_STATUS_CHANGE			0x2000
#define	TS102_EVENT_STATUS_CHARGING_STATUS_CHANGE		0x4000
#define	TS102_EVENT_STATUS_POWERON_BTN_PRESSED			0x8000
    TS102_OP_RD_REAL_TIME_CLK=0x0d,	/* none		ack + 7 bytes */
    TS102_OP_RD_EXT_VGA_PORT=0x0e,	/* none		ack + 1 bytes */
    TS102_OP_RD_UCTRL_ROM_CKSUM=0x0f,	/* none		ack + 2 bytes */
    TS102_OP_RD_ERROR_STATUS=0x10,	/* none		ack + 2 bytes */
#define	TS102_ERROR_STATUS_NO_ERROR				0x00
#define	TS102_ERROR_STATUS_COMMAND_ERROR			0x01
#define	TS102_ERROR_STATUS_EXECUTION_ERROR			0x02
#define	TS102_ERROR_STATUS_PHYSICAL_ERROR			0x04
    TS102_OP_RD_EXT_STATUS=0x11,	/* none		ack + 2 bytes */
#define	TS102_EXT_STATUS_MAIN_POWER_AVAILABLE			0x0001
#define	TS102_EXT_STATUS_INTERNAL_BATTERY_ATTACHED		0x0002
#define	TS102_EXT_STATUS_EXTERNAL_BATTERY_ATTACHED		0x0004
#define	TS102_EXT_STATUS_EXTERNAL_VGA_ATTACHED			0x0008
#define	TS102_EXT_STATUS_EXTERNAL_KEYBOARD_ATTACHED		0x0010
#define	TS102_EXT_STATUS_EXTERNAL_MOUSE_ATTACHED		0x0020
#define	TS102_EXT_STATUS_LID_DOWN				0x0040
#define	TS102_EXT_STATUS_INTERNAL_BATTERY_CHARGING		0x0080
#define	TS102_EXT_STATUS_EXTERNAL_BATTERY_CHARGING		0x0100
#define	TS102_EXT_STATUS_INTERNAL_BATTERY_DISCHARGING		0x0200
#define	TS102_EXT_STATUS_EXTERNAL_BATTERY_DISCHARGING		0x0400
    TS102_OP_RD_USER_CONFIG=0x12,	/* none		ack + 2 bytes */
    TS102_OP_RD_UCTRL_VLT=0x13,		/* none		ack + 1 bytes */
    TS102_OP_RD_INT_BATT_VLT=0x14,	/* none		ack + 1 bytes */
    TS102_OP_RD_DC_IN_VLT=0x15,		/* none		ack + 1 bytes */
    TS102_OP_RD_HORZ_PRT_VLT=0x16,	/* none		ack + 1 bytes */
    TS102_OP_RD_VERT_PTR_VLT=0x17,	/* none		ack + 1 bytes */
    TS102_OP_RD_INT_CHARGE_RATE=0x18,	/* none		ack + 1 bytes */
    TS102_OP_RD_EXT_CHARGE_RATE=0x19,	/* none		ack + 1 bytes */
    TS102_OP_RD_RTC_ALARM=0x1a,		/* none		ack + 7 bytes */
    TS102_OP_RD_EVENT_STATUS_NO_RESET=0x1b,	/* none		ack + 2 bytes */
    TS102_OP_RD_INT_KBD_LAYOUT=0x1c,	/* none		ack + 2 bytes */
    TS102_OP_RD_EXT_KBD_LAYOUT=0x1d,	/* none		ack + 2 bytes */
    TS102_OP_RD_EEPROM_STATUS=0x1e,	/* none		ack + 2 bytes */
#define	TS102_EEPROM_STATUS_FACTORY_AREA_CHECKSUM_FAIL		0x01
#define	TS102_EEPROM_STATUS_CONSUMER_AREA_CHECKSUM_FAIL		0x02
#define	TS102_EEPROM_STATUS_USER_AREA_CHECKSUM_FAIL		0x04
#define	TS102_EEPROM_STATUS_VPD_AREA_CHECKSUM_FAIL		0x08

    /* Read/Write/Modify Commands
     */
    TS102_OP_CTL_LCD=0x20,		/* 4 byte mask	ack + 4 bytes */
#define	TS102_LCD_CAPS_LOCK		0x0001
#define	TS102_LCD_SCROLL_LOCK		0x0002
#define	TS102_LCD_NUMLOCK		0x0004
#define	TS102_LCD_DISK_ACTIVE		0x0008
#define	TS102_LCD_LAN_ACTIVE		0x0010
#define	TS102_LCD_WAN_ACTIVE		0x0020
#define	TS102_LCD_PCMCIA_ACTIVE		0x0040
#define	TS102_LCD_DC_OK			0x0080
#define	TS102_LCD_COMPOSE		0x0100
    TS102_OP_CTL_BITPORT=0x21,		/* mask		ack + 1 byte */
#define	TS102_BITPORT_TFTPWR		0x01	/* TFT power (low) */
#define	TS102_BITPORT_SYNCINVA		0x02	/* ext. monitor sync (low) */
#define	TS102_BITPORT_SYNCINVB		0x04	/* ext. monitor sync (low) */
#define	TS102_BITPORT_BP_DIS		0x08	/* no bootprom from pcmcia (high) */
						/* boot from pcmcia (low) */
#define	TS102_BITPORT_ENCSYNC		0x10	/* enab composite sync (low) */
#define	TS102_BITPORT_DISK_POWER	0x20	/* internal disk power (low) */
    TS102_OP_CTL_DEV=0x22,		/* mask 	ack + 1 byte */
#define TS102_DEVCTL_CHARGE_DISABLE	0x01	/* dis/en charging */
#define TS102_DEVCTL_POINTER_DISABLE	0x04	/* dis/en pointer */
#define TS102_DEVCTL_KEYCLICK		0x08	/* keyclick? */
#define TS102_DEVCTL_INT_BTNCLICK	0x10	/* internal button click? */
#define TS102_DEVCTL_EXT_BTNCLICK	0x20	/* ext. button click?? */
    TS102_OP_CTL_SPEAKER_VOLUME=0x23,	/* mask		ack + 1 byte */
    TS102_OP_CTL_TFT_BRIGHTNESS=0x24,	/* mask		ack + 1 byte */
    TS102_OP_CTL_WATCHDOG=0x25,		/* mask		ack + 1 byte */
    TS102_OP_CTL_FCTRY_EEPROM=0x26,	/* mask		ack + 1 byte */
    TS102_OP_CTL_SECURITY_KEY=0x27,	/* no idea */
    TS102_OP_CTL_KDB_TIME_UNTL_RTP=0x28, /* mask 	ack + 1 byte */
    TS102_OP_CTL_KBD_TIME_BTWN_RPTS=0x29, /* mask	ack + 1 byte */
    TS102_OP_CTL_TIMEZONE=0x2a,		/* mask		ack + 1 byte */
    TS102_OP_CTL_MARK_SPACE_RATIO=0x2b,	/* mask		ack + 1 byte */
    TS102_OP_CTL_MOUSE_SENS=0x2c, 	/* mask		ack + 1 byte */
    TS102_OP_CTL_MOUSE_SCAN=0x2d,	/* no idea invalid?*/
    TS102_OP_CTL_DIAGNOSTIC_MODE=0x2e,	/* mask		ack + 1 byte */
#define	TS102_DIAGNOSTIC_MODE_CMD_DIAG_ON_LCD	0x01
#define	TS102_DIAGNOSTIC_MODE_KDB_MS_9600	0x02
    TS102_OP_CTL_SCREEN_CONTRAST=0x2f,	/* mask		ack + 1 byte */

    /* Commands returning no status
     */
    TS102_OP_CMD_RING_BELL=0x30,	/* msb,lsb	ack */
    TS102_OP_RD_INPUT_SOURCE=0x31,	/* no idea */
    TS102_OP_CMD_DIAGNOSTIC_STATUS=0x32, /* msb,lsb	ack */
    TS102_OP_CMD_CLR_KEY_COMBO_TBL=0x33, /* none	ack */
    TS102_OP_CMD_SOFTWARE_RESET=0x34,	/* none		ack */
    TS102_OP_CMD_SET_RTC=0x35,		/* smhddmy	ack */
    TS102_OP_CMD_RECAL_PTR=0x36,	/* none		ack */
    TS102_OP_CMD_SET_BELL_FREQ=0x37,	/* msb,lsb	ack */
    TS102_OP_CMD_SET_INT_BATT_RATE=0x39, /* charge-lvl	ack */
    TS102_OP_CMD_SET_EXT_BATT_RATE=0x3a, /* charge-lvl	ack */
    TS102_OP_CMD_SET_RTC_ALARM=0x3b,	/* smhddmy	ack */

    /* Block transfer commands
     */
    TS102_OP_BLK_RD_EEPROM=0x40,	/* len off		ack <data> */
    TS102_OP_BLK_WR_EEPROM=0x41,	/* len off <data>	ack */
    TS102_OP_BLK_WR_STATUS=0x42,	/* len off <data>	ack */
    TS102_OP_BLK_DEF_SPCL_CHAR=0x43,	/* len off <8b data>	ack */
#define	TS102_BLK_OFF_DEF_WAN1			0
#define	TS102_BLK_OFF_DEF_WAN2			1
#define	TS102_BLK_OFF_DEF_LAN1			2
#define	TS102_BLK_OFF_DEF_LAN2			3
#define	TS102_BLK_OFF_DEF_PCMCIA		4
#define	TS102_BLK_OFF_DEF_DC_GOOD		5
#define	TS102_BLK_OFF_DEF_BACKSLASH		6

    /* Generic commands
     */
    TS102_OP_GEN_DEF_KEY_COMBO_ENT=0x50, /* seq com-length	ack */
    TS102_OP_GEN_DEF_STRING_TBL_ENT=0x51, /* str-code len <str>	ack */
    TS102_OP_GEN_DEF_STS_CTRN_DISP=0x52, /* len <msg>		ack */

    /* Generic commands with optional status
     */
    TS102_OP_GEN_STS_EMU_COMMAND=0x64,	/* <command>	ack */
    TS102_OP_GEN_STS_RD_EMU_REGISTER=0x65, /* reg	ack + 1 byte */
    TS102_OP_GEN_STS_WR_EMU_REGISTER=0x66, /* reg,val	ack */
    TS102_OP_GEN_STS_RD_EMU_RAM=0x67,	/* addr		ack + 1 byte */
    TS102_OP_GEN_STS_WR_EMU_RAM=0x68,	/* addr,val	ack */
    TS102_OP_GEN_STS_RD_BQ_REGISTER=0x69, /* reg	ack + 1 byte */
    TS102_OP_GEN_STS_WR_BQ_REGISTER=0x6a, /* reg,val	ack */

    /* Administration commands
     */
    TS102_OP_ADMIN_SET_USER_PASS=0x70,	/* len <pass>   ack */
    TS102_OP_ADMIN_VRFY_USER_PASS=0x71,	/* len <pass>   ack + status */
    TS102_OP_ADMIN_GET_SYSTEM_PASS=0x72, /* none	ack + <7bytekey> */
    TS102_OP_ADMIN_VRFY_SYSTEM_PASS=0x73, /* len <pass>   ack + status */
    TS102_OP_RD_INT_CHARGE_LEVEL=0x7a,	/* ack + 2 byte */
    TS102_OP_RD_EXT_CHARGE_LEVEL=0x7b,	/* ack + 2 byte */
#define	TS102_CHARGE_UNKNOWN	0xfa
    TS102_OP_SLEEP=0x80, 		/* supposedly sleeps, not sure */
    TS102_OP_ADMIN_POWER_OFF=0x82,	/* len <pass>	none */
    TS102_OP_ADMIN_POWER_RESTART=0x83,	/* msb,xx,lsb	none */
};

#define	TS102_UCTRL_ACK		0xfe
#define	TS102_UCTRL_NACK	0xfc
#define	TS102_UCTRL_INTR	0xfa

#endif /* _SPARC_DEV_TS102REG_H */


code:
/*	$OpenBSD: tvtwo.c,v 1.19 2015/03/28 19:07:08 miod Exp $	*/

/*
 * Copyright (c) 2003, 2006, 2008, Miodrag Vallat.
 * 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.
 *
 */

/*
 * Driver for the Parallax XVideo and PowerVideo graphics boards.
 *
 * Some details about these board used to be available at:
 *   http://www.jlw.com/~woolsey/parallax/support/developers/xvideotech.html
 */

/*
 * The Parallax XVideo series frame buffers are 8/24-bit accelerated
 * frame buffers, with hardware MPEG capabilities using a CCube chipset.
 */

/*
 * Currently, this driver can only handle the 8-bit and 24-bit planes of the
 * frame buffer, in an unaccelerated mode.
 *
 * TODO:
 * - nvram handling
 * - use the accelerator
 * - interface to the c^3
 */

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/buf.h>
#include <sys/device.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/conf.h>

#include <uvm/uvm_extern.h>

#include <machine/autoconf.h>
#include <machine/pmap.h>
#include <machine/cpu.h>
#include <machine/conf.h>

#include <dev/wscons/wsconsio.h>
#include <dev/wscons/wsdisplayvar.h>
#include <dev/rasops/rasops.h>
#include <machine/fbvar.h>

/*
 * The memory layout of the board is as follows:
 *
 *	PROM0		000000 - 00ffff
 *	overlay plane	010000 - 037fff
 *	registers	040000 - 0404d0
 *	CCube		050000 - 05ffff
 *	8-bit plane	080000 - 17ffff
 *	24-bit plane	200000 - 6fffff
 *	PROM1		7f0000 - 7fffff
 */

#define	PX_PROM0_OFFSET		0x000000
#define	PX_OVERLAY_OFFSET	0x010000
#define	PX_REG_OFFSET		0x040000
#define	PX_CCUBE_OFFSET		0x050000
#define	PX_PLANE8_OFFSET	0x080000
#define	PX_PLANE24_OFFSET	0x200000
#define	PX_PROM1_OFFSET		0x7f0000

#define	PX_MAP_SIZE		0x800000

/*
 * Partial registers layout
 */

#define	PX_REG_DISPKLUGE	0x00b8	/* write only */
#define	DISPKLUGE_DEFAULT	0xc41f
#define	DISPKLUGE_BLANK		(1 << 12)
#define	DISPKLUGE_SYNC		(1 << 13)

#define	PX_REG_BT463_RED	0x0480
#define	PX_REG_BT463_GREEN	0x0490
#define	PX_REG_BT463_BLUE	0x04a0
#define	PX_REG_BT463_ALL	0x04b0

#define	PX_REG_SIZE		0x04d0

/* per-display variables */
struct tvtwo_softc {
	struct	sunfb	sc_sunfb;	/* common base device */
	struct	rom_reg sc_phys;

	volatile u_int8_t *sc_m8;
	volatile u_int8_t *sc_m24;
	volatile u_int8_t *sc_regs;
};

int	tvtwo_ioctl(void *, u_long, caddr_t, int, struct proc *);
paddr_t	tvtwo_mmap(void *, off_t, int);
void	tvtwo_burner(void *, u_int, u_int);

struct wsdisplay_accessops tvtwo_accessops = {
	.ioctl = tvtwo_ioctl,
	.mmap = tvtwo_mmap,
	.burn_screen = tvtwo_burner
};

void	tvtwo_directcmap(struct tvtwo_softc *);
static __inline__
void	tvtwo_ramdac_wraddr(struct tvtwo_softc *, u_int32_t);
void	tvtwo_reset(struct tvtwo_softc *, u_int);
void	tvtwo_setcolor(void *, u_int, u_int8_t, u_int8_t, u_int8_t);

int	tvtwomatch(struct device *, void *, void *);
void	tvtwoattach(struct device *, struct device *, void *);

struct cfattach tvtwo_ca = {
	sizeof(struct tvtwo_softc), tvtwomatch, tvtwoattach
};

struct cfdriver tvtwo_cd = {
	NULL, "tvtwo", DV_DULL
};

/*
 * Default frame buffer resolution, depending upon the "freqcode"
 */
#define	NFREQCODE	5
const int defwidth[NFREQCODE] = { 1152, 1152, 1152, 1024, 640 };
const int defheight[NFREQCODE] = { 900, 900, 900, 768, 480 };

/*
 * Match an XVideo or PowerVideo card.
 */
int
tvtwomatch(struct device *parent, void *vcf, void *aux)
{
	struct confargs *ca = aux;
	struct romaux *ra = &ca->ca_ra;

	if (strcmp(ra->ra_name, "PGI,tvtwo") == 0 ||
	    strcmp(ra->ra_name, "PGI,tvthree") == 0)
		return (1);

	return (0);
}

void
tvtwoattach(struct device *parent, struct device *self, void *args)
{
	struct tvtwo_softc *sc = (struct tvtwo_softc *)self;
	struct confargs *ca = args;
	int node, width, height, freqcode;
	int isconsole;
	char *freqstring, *revision;

	node = ca->ca_ra.ra_node;

	printf(": %s", getpropstring(node, "model"));
	revision = getpropstring(node, "revision");
	if (*revision != '\0')
		printf(", revision %s", revision);

	/*
	 * Older XVideo provide two sets of SBus registers:
	 *	R0		040000 - 040800
	 *	R1		080000 - 17d200
	 * While the more recent revisions provide only one register:
	 *	R0		000000 - 7fffff
	 *
	 * We'll simply ``rewrite'' R0 on older boards and handle them as
	 * recent boards.
	 */
	if (ca->ca_ra.ra_nreg > 1) {
		ca->ca_ra.ra_paddr =
		    (void *)((vaddr_t)ca->ca_ra.ra_paddr - PX_REG_OFFSET);
		ca->ca_ra.ra_len = PX_MAP_SIZE;
	}

	isconsole = node == fbnode;

	/* Map registers. */
	sc->sc_regs = mapiodev(ca->ca_ra.ra_reg, PX_REG_OFFSET, PX_REG_SIZE);

	/*
	 * Compute framebuffer size.
	 * Older boards do not have the ``freqcode'' property and are
	 * restricted to 1152x900.
	 */
	freqstring = getpropstring(node, "freqcode");
	if (*freqstring != '\0') {
		freqcode = (int)*freqstring;
		if (freqcode == 'g') {
			width = height = 1024;
		} else {
			if (freqcode < '1' || freqcode > NFREQCODE + '0')
				freqcode = 0;
			else
				freqcode -= '1';
			width = defwidth[freqcode];
			height = defheight[freqcode];

			/* in case our table is wrong or incomplete... */
			width = getpropint(node, "hres", width);
			height = getpropint(node, "vres", height);
		}
	} else {
		width = 1152;
		height = 900;
	}

	/*
	 * Since the depth property is missing, we could do
	 * fb_setsize(&sc->sc_sunfb, 8, width, height, node, ca->ca_bustype);
	 * but for safety in case it would exist and be set to 32, do it
	 * manually...
	 */
	sc->sc_sunfb.sf_depth = 8;
	sc->sc_sunfb.sf_width = width;
	sc->sc_sunfb.sf_height = height;
	sc->sc_sunfb.sf_linebytes = width >= 1024 ? width : 1024;
	sc->sc_sunfb.sf_fbsize = sc->sc_sunfb.sf_linebytes * height;

	printf(", %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height);

	/* Map the frame buffer memory area we're interested in. */
	sc->sc_phys = ca->ca_ra.ra_reg[0];
	sc->sc_m8 = mapiodev(ca->ca_ra.ra_reg,
	    PX_PLANE8_OFFSET, round_page(sc->sc_sunfb.sf_fbsize));
	sc->sc_m24 = mapiodev(ca->ca_ra.ra_reg,
	    PX_PLANE24_OFFSET, round_page(4 * sc->sc_sunfb.sf_fbsize));

	/* Enable video. */
	tvtwo_burner(sc, 1, 0);

	sc->sc_sunfb.sf_ro.ri_hw = sc;
	sc->sc_sunfb.sf_ro.ri_bits = (u_char *)sc->sc_m8;

	fbwscons_init(&sc->sc_sunfb, isconsole);
	fbwscons_setcolormap(&sc->sc_sunfb, tvtwo_setcolor);

	if (isconsole)
		fbwscons_console_init(&sc->sc_sunfb, -1);

	fbwscons_attach(&sc->sc_sunfb, &tvtwo_accessops, isconsole);
}

int
tvtwo_ioctl(void *dev, u_long cmd, caddr_t data, int flags, struct proc *p)
{
	struct tvtwo_softc *sc = dev;
	struct wsdisplay_fbinfo *wdf;

	/*
	 * Note that, although the emulation (text) mode is running in a
	 * 8-bit plane, we advertize the frame buffer as 32-bit.
	 */
	switch (cmd) {
	case WSDISPLAYIO_GTYPE:
		*(u_int *)data = WSDISPLAY_TYPE_XVIDEO;
		break;
	case WSDISPLAYIO_GINFO:
		wdf = (struct wsdisplay_fbinfo *)data;
		wdf->height = sc->sc_sunfb.sf_height;
		wdf->width = sc->sc_sunfb.sf_width;
		wdf->depth = 32;
		wdf->cmsize = 0;
		break;
	case WSDISPLAYIO_GETSUPPORTEDDEPTH:
		*(u_int *)data = WSDISPLAYIO_DEPTH_24_32;
		break;
	case WSDISPLAYIO_LINEBYTES:
		*(u_int *)data = sc->sc_sunfb.sf_linebytes * 4;
		break;

	case WSDISPLAYIO_GETCMAP:
	case WSDISPLAYIO_PUTCMAP:
		break;

	case WSDISPLAYIO_SMODE:
		if (*(int *)data == WSDISPLAYIO_MODE_EMUL) {
			/* Back from X11 to text mode */
			tvtwo_reset(sc, 8);
		} else {
			/* Starting X11, initialize 32-bit mode */
			tvtwo_reset(sc, 32);
		}
		break;

	case WSDISPLAYIO_SVIDEO:
	case WSDISPLAYIO_GVIDEO:
		break;

	case WSDISPLAYIO_GCURPOS:
	case WSDISPLAYIO_SCURPOS:
	case WSDISPLAYIO_GCURMAX:
	case WSDISPLAYIO_GCURSOR:
	case WSDISPLAYIO_SCURSOR:
	default:
		return (-1);
	}

	return (0);
}

paddr_t
tvtwo_mmap(void *v, off_t offset, int prot)
{
	struct tvtwo_softc *sc = v;

	if (offset & PGOFSET)
		return (-1);

	/* Allow mapping as a dumb framebuffer from offset 0 */
	if (offset >= 0 && offset < sc->sc_sunfb.sf_fbsize * 4) {
		return (REG2PHYS(&sc->sc_phys,
		    PX_PLANE24_OFFSET + offset) | PMAP_NC);
	}

	return (-1);
}

void
tvtwo_burner(void *v, u_int on, u_int flags)
{
	struct tvtwo_softc *sc = v;
	u_int32_t dispkluge;

	if (on)
		dispkluge = DISPKLUGE_DEFAULT & ~DISPKLUGE_BLANK;
	else {
		dispkluge = DISPKLUGE_DEFAULT | DISPKLUGE_BLANK;
		if (flags & WSDISPLAY_BURN_VBLANK)
			dispkluge |= DISPKLUGE_SYNC;
	}

	*(volatile u_int32_t *)(sc->sc_regs + PX_REG_DISPKLUGE) = dispkluge;
}

void
tvtwo_reset(struct tvtwo_softc *sc, u_int depth)
{
	if (depth == 32) {
		/* Initialize a direct color map. */
		tvtwo_directcmap(sc);
	} else {
		fbwscons_setcolormap(&sc->sc_sunfb, tvtwo_setcolor);
	}
}

/*
 * Simple Bt463 programming routines.
 */

static __inline__ void
tvtwo_ramdac_wraddr(struct tvtwo_softc *sc, u_int32_t addr)
{
	volatile u_int32_t *dac = (u_int32_t *)(sc->sc_regs + PX_REG_BT463_RED);

	dac[0] = (addr & 0xff);		/* lo addr */
	dac[1] = ((addr >> 8) & 0xff);	/* hi addr */
}

void
tvtwo_directcmap(struct tvtwo_softc *sc)
{
	volatile u_int32_t *dac = (u_int32_t *)(sc->sc_regs + PX_REG_BT463_RED);
	u_int32_t c;

	tvtwo_ramdac_wraddr(sc, 0);
	for (c = 0; c < 256; c++) {
		dac[3] = c;	/* R */
		dac[3] = c;	/* G */
		dac[3] = c;	/* B */
	}
}

void
tvtwo_setcolor(void *v, u_int index, u_int8_t r, u_int8_t g, u_int8_t b)
{
	struct tvtwo_softc *sc = v;
	volatile u_int32_t *dac = (u_int32_t *)(sc->sc_regs + PX_REG_BT463_RED);

	tvtwo_ramdac_wraddr(sc, index);
	dac[3] = r;
	dac[3] = g;
	dac[3] = b;
}

license: unknown


code:
/*	$OpenBSD: vigra.c,v 1.20 2015/03/28 19:07:08 miod Exp $	*/

/*
 * Copyright (c) 2002, 2003, Miodrag Vallat.
 * 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.
 *
 */

/*
 * Driver for the Vigra VS series of SBus framebuffers.
 *
 * The VS10, VS11 and VS12 models are supported. VS10-EK is handled by the
 * regular cgthree driver.
 *
 * The monochrome VS14, 16 grays VS15, and color VS18 are not supported.
 */

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/buf.h>
#include <sys/device.h>
#include <sys/ioctl.h>
#include <sys/malloc.h>
#include <sys/mman.h>
#include <sys/tty.h>
#include <sys/conf.h>

#include <uvm/uvm_extern.h>

#include <machine/autoconf.h>
#include <machine/pmap.h>
#include <machine/cpu.h>
#include <machine/conf.h>

#include <dev/wscons/wsconsio.h>
#include <dev/wscons/wsdisplayvar.h>
#include <dev/rasops/rasops.h>
#include <machine/fbvar.h>

/*
 * The hardware information below has been gathered through experiments, as
 * well as the debug information of the SunOS 4.x vigfb driver.
 */

/*
 * Control and status registers
 */

struct csregs {
	u_int32_t	sosr;
	u_int32_t	g3rr;
	u_int32_t	bcr;	/* board control register */
	u_int32_t	spr;
	u_int32_t	g3sr;	/* ramdac status register */
#define	STATUS_INTR	0x0001
	u_int32_t	imr;	/* interrupt mode register */
	u_int32_t	ewcr;
	u_int32_t	ssr;
};

/*
 * G300 layout
 */

struct g300dac {
	u_int32_t	cmap[256];
	u_int32_t	g3null;
	u_int32_t	unused1[32];
	u_int32_t	half_sync;
	u_int32_t	back_porch;
	u_int32_t	display;
	u_int32_t	short_display;
	u_int32_t	broad_pulse;
	u_int32_t	vsync;
	u_int32_t	vblank;
	u_int32_t	vdisplay;
	u_int32_t	line_time;
	u_int32_t	tos1;
	u_int32_t	mem_init;
	u_int32_t	transfer_delay;
	u_int32_t	unused2[19];
	u_int32_t	mask;
	u_int32_t	unused3[31];
	u_int32_t	cr;
	u_int32_t	unused4[31];
	u_int32_t	tos2;
	u_int32_t	unused5[31];
	u_int32_t	boot_location;
};

/*
 * G335 layout
 */

struct g335dac {
	u_int32_t	boot_location;
	u_int32_t	unused1[32];
	u_int32_t	half_sync;
	u_int32_t	back_porch;
	u_int32_t	display;
	u_int32_t	short_display;
	u_int32_t	broad_pulse;
	u_int32_t	vsync;
	u_int32_t	vpre_equalize;
	u_int32_t	vpost_equalize;
	u_int32_t	vblank;
	u_int32_t	vdisplay;
	u_int32_t	line_time;
	u_int32_t	tos1;
	u_int32_t	mem_init;
	u_int32_t	transfer_delay;
	u_int32_t	unused2[17];
	u_int32_t	mask;
	u_int32_t	unused3[31];
	u_int32_t	cra;
	u_int32_t	unused4[15];
	u_int32_t	crb;
	u_int32_t	unused5[15];
	u_int32_t	tos2;
	u_int32_t	unused6[32];
	u_int32_t	cursor_palette[3];
	u_int32_t	unused7[28];
	u_int32_t	checksum[3];
	u_int32_t	unused8[4];
	u_int32_t	cursor_position;
	u_int32_t	unused9[56];
	u_int32_t	cmap[256];
	u_int32_t	cursor_store[512];
};

union dac {
	struct g300dac	g300;
	struct g335dac	g335;
};

/*
 * SBUS register mappings
 */
#define	VIGRA_REG_RAMDAC	1	/* either G300 or G335 */
#define	VIGRA_REG_CSR		2
#define	VIGRA_REG_VRAM		3

#define	VIGRA_NREG		4

union vigracmap {
	u_char		cm_map[256][4];	/* 256 R/G/B entries plus pad */
	u_int32_t	cm_chip[256];	/* the way the chip gets loaded */
};

/* per-display variables */
struct vigra_softc {
	struct	sunfb sc_sunfb;		/* common base part */
	struct	rom_reg	sc_phys;	/* phys address description */
	volatile struct	csregs *sc_regs;/* control registers */
	volatile union dac *sc_ramdac;	/* ramdac registers */
	union	vigracmap sc_cmap;	/* current colormap */
	int	sc_g300;
	struct	intrhand sc_ih;
};

void	vigra_burner(void *, u_int, u_int);
int	vigra_getcmap(union vigracmap *, struct wsdisplay_cmap *, int);
int	vigra_intr(void *);
int	vigra_ioctl(void *, u_long, caddr_t, int, struct proc *);
static __inline__
void	vigra_loadcmap_deferred(struct vigra_softc *, u_int, u_int);
void	vigra_loadcmap_immediate(struct vigra_softc *, int, int);
paddr_t	vigra_mmap(void *, off_t, int);
int	vigra_putcmap(union vigracmap *, struct wsdisplay_cmap *, int);
void	vigra_setcolor(void *, u_int, u_int8_t, u_int8_t, u_int8_t);

struct wsdisplay_accessops vigra_accessops = {
	.ioctl = vigra_ioctl,
	.mmap = vigra_mmap,
	.burn_screen = vigra_burner
};

int	vigramatch(struct device *, void *, void *);
void	vigraattach(struct device *, struct device *, void *);

struct cfattach vigra_ca = {
	sizeof (struct vigra_softc), vigramatch, vigraattach
};

struct cfdriver vigra_cd = {
	NULL, "vigra", DV_DULL
};

/*
 * Match a supported vigra card.
 */
int
vigramatch(struct device *parent, void *vcf, void *aux)
{
	struct confargs *ca = aux;
	struct romaux *ra = &ca->ca_ra;

	if (strcmp("vs10", ra->ra_name) != 0 &&
	    strcmp("vs11", ra->ra_name) != 0 &&
	    strcmp("vs12", ra->ra_name) != 0)
		return (0);

	return (1);
}

/*
 * Attach and initialize a vigra display, as well as a child wsdisplay.
 */
void
vigraattach(struct device *parent, struct device *self, void *args)
{
	struct vigra_softc *sc = (struct vigra_softc *)self;
	struct confargs *ca = args;
	int node, pri, isconsole = 0;
	char *nam;

	pri = ca->ca_ra.ra_intr[0].int_pri;
	printf(" pri %d", pri);

	if (ca->ca_ra.ra_nreg < VIGRA_NREG) {
		printf("\n%s: expected %d registers, got %d",
		    self->dv_xname, VIGRA_NREG, ca->ca_ra.ra_nreg);
		return;
	}

	node = ca->ca_ra.ra_node;
	nam = getpropstring(node, "model");
	if (*nam == '\0')
		nam = (char *)ca->ca_ra.ra_name;
	printf(": %s", nam);

	isconsole = node == fbnode;

	/*
	 * Check whether we are using an G300 or an G335 chip.
	 * The VS10 and VS12 use the G300, while the VS11 uses a G335.
	 */
	sc->sc_g300 = strncmp(nam, "VIGRA,vs11", strlen("VIGRA,vs11"));

	sc->sc_regs = mapiodev(&ca->ca_ra.ra_reg[VIGRA_REG_CSR], 0,
	    ca->ca_ra.ra_reg[VIGRA_REG_CSR].rr_len);
	sc->sc_ramdac = mapiodev(&ca->ca_ra.ra_reg[VIGRA_REG_RAMDAC], 0,
	    ca->ca_ra.ra_reg[VIGRA_REG_RAMDAC].rr_len);
	sc->sc_phys = ca->ca_ra.ra_reg[VIGRA_REG_VRAM];

	sc->sc_ih.ih_fun = vigra_intr;
	sc->sc_ih.ih_arg = sc;
	intr_establish(pri, &sc->sc_ih, IPL_FB, self->dv_xname);

	/* enable video */
	vigra_burner(sc, 1, 0);

	fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, ca->ca_bustype);
	sc->sc_sunfb.sf_ro.ri_bits = mapiodev(&ca->ca_ra.ra_reg[VIGRA_REG_VRAM],
	    0, round_page(sc->sc_sunfb.sf_fbsize));
	sc->sc_sunfb.sf_ro.ri_hw = sc;

	printf(", %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height);

	fbwscons_init(&sc->sc_sunfb, isconsole);
	fbwscons_setcolormap(&sc->sc_sunfb, vigra_setcolor);

	if (isconsole)
		fbwscons_console_init(&sc->sc_sunfb, -1);

	fbwscons_attach(&sc->sc_sunfb, &vigra_accessops, isconsole);
}

int
vigra_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p)
{
	struct vigra_softc *sc = v;
	struct wsdisplay_cmap *cm;
	struct wsdisplay_fbinfo *wdf;
	int error;

	switch (cmd) {
	case WSDISPLAYIO_GTYPE:
		*(u_int *)data = WSDISPLAY_TYPE_UNKNOWN;
		break;
	case WSDISPLAYIO_GINFO:
		wdf = (struct wsdisplay_fbinfo *)data;
		wdf->height = sc->sc_sunfb.sf_height;
		wdf->width  = sc->sc_sunfb.sf_width;
		wdf->depth  = sc->sc_sunfb.sf_depth;
		wdf->cmsize = 256;
		break;
	case WSDISPLAYIO_LINEBYTES:
		*(u_int *)data = sc->sc_sunfb.sf_linebytes;
		break;

	case WSDISPLAYIO_GETCMAP:
		cm = (struct wsdisplay_cmap *)data;
		error = vigra_getcmap(&sc->sc_cmap, cm, sc->sc_g300);
		if (error)
			return (error);
		break;
	case WSDISPLAYIO_PUTCMAP:
		cm = (struct wsdisplay_cmap *)data;
		error = vigra_putcmap(&sc->sc_cmap, cm, sc->sc_g300);
		if (error)
			return (error);
		vigra_loadcmap_deferred(sc, cm->index, cm->count);
		break;

	case WSDISPLAYIO_SVIDEO:
	case WSDISPLAYIO_GVIDEO:
		break;

	case WSDISPLAYIO_GCURPOS:
	case WSDISPLAYIO_SCURPOS:
	case WSDISPLAYIO_GCURMAX:
	case WSDISPLAYIO_GCURSOR:
	case WSDISPLAYIO_SCURSOR:
	default:
		return (-1);	/* not supported yet */
        }

	return (0);
}

paddr_t
vigra_mmap(void *v, off_t offset, int prot)
{
	struct vigra_softc *sc = v;

	if (offset & PGOFSET)
		return (-1);

	if (offset >= 0 && offset < sc->sc_sunfb.sf_fbsize) {
		return (REG2PHYS(&sc->sc_phys, offset) | PMAP_NC);
	}

	return (-1);
}

void
vigra_setcolor(void *v, u_int index, u_int8_t r, u_int8_t g, u_int8_t b)
{
	struct vigra_softc *sc = v;

	if (sc->sc_g300) {
		sc->sc_cmap.cm_map[index][3] = r;
		sc->sc_cmap.cm_map[index][2] = g;
		sc->sc_cmap.cm_map[index][1] = b;
	} else {
		sc->sc_cmap.cm_map[index][3] = b;
		sc->sc_cmap.cm_map[index][2] = g;
		sc->sc_cmap.cm_map[index][1] = r;
	}
	sc->sc_cmap.cm_map[index][0] = 0;	/* no alpha channel */

	vigra_loadcmap_immediate(sc, index, 1);
}

int
vigra_getcmap(union vigracmap *cm, struct wsdisplay_cmap *rcm, int g300)
{
	u_int index = rcm->index, count = rcm->count, i;
	int error;

	if (index >= 256 || count > 256 - index)
		return (EINVAL);

	if (g300) {
		for (i = 0; i < count; i++) {
			if ((error = copyout(&cm->cm_map[index + i][3],
			    &rcm->red[i], 1)) != 0)
				return (error);
			if ((error = copyout(&cm->cm_map[index + i][1],
			    &rcm->blue[i], 1)) != 0)
				return (error);
		}
	} else {
		for (i = 0; i < count; i++) {
			if ((error = copyout(&cm->cm_map[index + i][1],
			    &rcm->red[i], 1)) != 0)
				return (error);
			if ((error = copyout(&cm->cm_map[index + i][3],
			    &rcm->blue[i], 1)) != 0)
				return (error);
		}
	}

	for (i = 0; i < count; i++) {
		if ((error = copyout(&cm->cm_map[index + i][2],
		    &rcm->green[i], 1)) != 0)
			return (error);
	}
	return (0);
}

int
vigra_putcmap(union vigracmap *cm, struct wsdisplay_cmap *rcm, int g300)
{
	u_int index = rcm->index, count = rcm->count, i;
	int error;

	if (index >= 256 || count > 256 - index)
		return (EINVAL);

	if (g300) {
		for (i = 0; i < count; i++) {
			if ((error = copyin(&rcm->red[i],
			    &cm->cm_map[index + i][3], 1)) != 0)
				return (error);
			if ((error = copyin(&rcm->blue[i],
			    &cm->cm_map[index + i][1], 1)) != 0)
				return (error);
		}
	} else {
		for (i = 0; i < count; i++) {
			if ((error = copyin(&rcm->red[i],
			    &cm->cm_map[index + i][1], 1)) != 0)
				return (error);
			if ((error = copyin(&rcm->blue[i],
			    &cm->cm_map[index + i][3], 1)) != 0)
				return (error);
		}
	}

	for (i = 0; i < count; i++) {
		if ((error = copyin(&rcm->green[i],
		    &cm->cm_map[index + i][2], 1)) != 0)
			return (error);
		cm->cm_map[index + i][0] = 0;	/* no alpha channel */
	}
	return (0);
}

void
vigra_loadcmap_immediate(struct vigra_softc *sc, int start, int ncolors)
{
	u_int32_t *colp = &sc->sc_cmap.cm_chip[start];
	volatile u_int32_t *lutp;

	if (sc->sc_g300)
		lutp = &(sc->sc_ramdac->g300.cmap[start]);
	else
		lutp = &(sc->sc_ramdac->g335.cmap[start]);

	while (--ncolors >= 0)
		*lutp++ = *colp++;
}

static __inline__ void
vigra_loadcmap_deferred(struct vigra_softc *sc, u_int start, u_int ncolors)
{

	sc->sc_regs->imr = 1;
}

void
vigra_burner(void *v, u_int on, u_int flags)
{
	struct vigra_softc *sc = v;

	if (on) {
		sc->sc_regs->bcr = 0;
	} else {
		sc->sc_regs->bcr = 1;
	}
}

int
vigra_intr(void *v)
{
	struct vigra_softc *sc = v;

	if (sc->sc_regs->imr == 0 ||
	    !ISSET(sc->sc_regs->g3sr, STATUS_INTR)) {
		/* Not expecting an interrupt, it's not for us. */
		return (0);
	}

	/* Acknowledge the interrupt and disable it. */
	sc->sc_regs->imr = 0;

	vigra_loadcmap_immediate(sc, 0, 256);

	return (1);
}


code:
/*	$OpenBSD: vmereg.h,v 1.1 1997/08/08 08:25:32 downsj Exp $	*/
/*	$NetBSD: vmereg.h,v 1.2 1997/06/07 19:10:57 pk Exp $ */

/*
 * Copyright (c) 1997 	Paul Kranenburg
 *
 * 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.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by Paul Kranenburg.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
 *
 */

struct vmebusreg {
	u_int32_t	vmebus_cr;	/* VMEbus control register */
	u_int32_t	vmebus_afar;	/* VMEbus async fault address */
	u_int32_t	vmebus_afsr;	/* VMEbus async fault status */
};

/* Control Register bits */
#define VMEBUS_CR_C	0x80000000	/* I/O cache enable */
#define VMEBUS_CR_S	0x40000000	/* VME slave enable */
#define VMEBUS_CR_L	0x20000000	/* Loopback enable (diagnostic) */
#define VMEBUS_CR_R	0x10000000	/* VMEbus reset */
#define VMEBUS_CR_RSVD	0x0ffffff0	/* reserved */
#define VMEBUS_CR_IMPL	0x0000000f	/* VMEbus interface implementation */

/* Asynchronous Fault Status bits */
#define VMEBUS_AFSR_SZ	0xe0000000	/* Error transaction size */
#define    VMEBUS_AFSR_SZ4	0	/* 4 byte */
#define    VMEBUS_AFSR_SZ1	1	/* 1 byte */
#define    VMEBUS_AFSR_SZ2	2	/* 2 byte */
#define    VMEBUS_AFSR_SZ32	5	/* 32 byte */
#define VMEBUS_AFSR_TO	0x10000000	/* VME master access time-out */
#define VMEBUS_AFSR_BERR 0x08000000	/* VME master got BERR */
#define VMEBUS_AFSR_WB	0x04000000	/* IOC write-back error (if SZ == 32) */
					/* Non-IOC write error (id SZ != 32) */
#define VMEBUS_AFSR_ERR	0x02000000	/* Error summary bit */
#define VMEBUS_AFSR_S	0x01000000	/* MVME error in supervisor space */
#define VMEBUS_AFSR_ME	0x00800000	/* Multiple error */
#define VMEBUS_AFSR_RSVD 0x007fffff	/* reserved */

struct vmebusvec {
	volatile u_int8_t	vmebusvec[16];
};

/* VME address modifiers */
#define VMEMOD_A16_D_S	0x2d		/* 16-bit address, data, supervisor */
#define VMEMOD_A24_D_S	0x3d		/* 24-bit address, data, supervisor */
#define VMEMOD_A32_D_S	0x0d		/* 32-bit address, data, supervisor */

#define VMEMOD_D32	0x40		/* 32-bit access */


code:
/*	$OpenBSD: xbox.c,v 1.6 2015/03/28 19:10:45 miod Exp $	*/

/*
 * Copyright (c) 1999 Jason L. Wright (jason@thought.net)
 * 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.
 */

/*
 * Driver for the Sun SBus Expansion Subsystem
 */

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/errno.h>
#include <sys/ioctl.h>
#include <sys/syslog.h>
#include <sys/device.h>
#include <sys/malloc.h>

#include <machine/autoconf.h>
#include <sparc/cpu.h>
#include <sparc/sparc/cpuvar.h>
#include <sparc/dev/sbusvar.h>

#include <sparc/dev/xboxreg.h>
#include <sparc/dev/xboxvar.h>

int	xboxmatch(struct device *, void *, void *);
void	xboxattach(struct device *, struct device *, void *);
int	xboxprint(void *, const char *);
void	xbox_fix_range(struct xbox_softc *sc, struct sbus_softc *sbp);

struct cfattach xbox_ca = {
	sizeof (struct xbox_softc), xboxmatch, xboxattach
};

struct cfdriver xbox_cd = {
	NULL, "xbox", DV_DULL
};

int
xboxmatch(parent, vcf, aux)
	struct device *parent;
	void *vcf, *aux;
{
	struct confargs *ca = aux;
	struct romaux *ra = &ca->ca_ra;

	if (strcmp("SUNW,xbox", ra->ra_name))
		return (0);

	if (!sbus_testdma((struct sbus_softc *)parent, ca))
		return(0);
	return (1);
}

void
xboxattach(parent, self, aux)
	struct device *parent, *self;
	void *aux;
{
	struct xbox_softc *sc = (struct xbox_softc *)self;
	struct confargs *ca = aux;
	struct romaux *ra = &ca->ca_ra;
	int node = ra->ra_node;
	struct confargs oca;
	char *s;

	s = getpropstring(node, "model");
	printf(": model %s", s);

	s = getpropstring(node, "child-present");
	if (strcmp(s, "false") == 0) {
		printf(": no devices\n");
		return;
	}

	sc->sc_regs.xa_write0 = mapiodev(&ra->ra_reg[0], 0,
	    sizeof(*sc->sc_regs.xa_write0));
	sc->sc_regs.xa_errs = mapiodev(&ra->ra_reg[1], 0,
	    sizeof(*sc->sc_regs.xa_errs));
	sc->sc_regs.xa_ctl0 = mapiodev(&ra->ra_reg[2], 0,
	    sizeof(*sc->sc_regs.xa_ctl0));
	sc->sc_regs.xa_ctl1 = mapiodev(&ra->ra_reg[3], 0,
	    sizeof(*sc->sc_regs.xa_ctl1));
	sc->sc_regs.xa_elua = mapiodev(&ra->ra_reg[4], 0,
	    sizeof(*sc->sc_regs.xa_elua));
	sc->sc_regs.xa_ella = mapiodev(&ra->ra_reg[5], 0,
	    sizeof(*sc->sc_regs.xa_ella));
	sc->sc_regs.xa_rsrv = mapiodev(&ra->ra_reg[6], 0,
	    sizeof(*sc->sc_regs.xa_rsrv));
	sc->sc_regs.xb_errs = mapiodev(&ra->ra_reg[7], 0,
	    sizeof(*sc->sc_regs.xb_errs));
	sc->sc_regs.xb_ctl0 = mapiodev(&ra->ra_reg[8], 0,
	    sizeof(*sc->sc_regs.xb_ctl0));
	sc->sc_regs.xb_ctl1 = mapiodev(&ra->ra_reg[9], 0,
	    sizeof(*sc->sc_regs.xb_ctl1));
	sc->sc_regs.xb_elua = mapiodev(&ra->ra_reg[10], 0,
	    sizeof(*sc->sc_regs.xb_elua));
	sc->sc_regs.xb_ella = mapiodev(&ra->ra_reg[11], 0,
	    sizeof(*sc->sc_regs.xb_ella));
	sc->sc_regs.xb_rsrv = mapiodev(&ra->ra_reg[12], 0,
	    sizeof(*sc->sc_regs.xb_rsrv));

	sc->sc_key = getpropint(node, "write0-key", -1);
	sc->sc_node = node;

	*sc->sc_regs.xa_write0 = (sc->sc_key << 24) | XAC_CTL1_OFFSET |
	    XBOX_CTL1_CSIE | XBOX_CTL1_TRANSPARENT;
	*sc->sc_regs.xa_write0 = (sc->sc_key << 24) | XBC_CTL1_OFFSET |
	    XBOX_CTL1_XSIE | XBOX_CTL1_XSBRE | XBOX_CTL1_XSSE;
	DELAY(100);

	xbox_fix_range(sc, (struct sbus_softc *)parent);

	printf("\n");

	oca = (*ca);
	oca.ca_bustype = BUS_XBOX;
	if (ra->ra_bp != NULL && strcmp(ra->ra_bp->name, "SUNW,xbox") == 0)
		oca.ca_ra.ra_bp = ra->ra_bp + 1;
	else
		oca.ca_ra.ra_bp = NULL;

	(void)config_found(&sc->sc_dv, (void *)&oca, xboxprint);
}

/*
 * Fix up our address ranges based on parent address spaces.
 */
void
xbox_fix_range(sc, sbp)
	struct xbox_softc *sc;
	struct sbus_softc *sbp;
{
	int rlen, i, j;

	rlen = getproplen(sc->sc_node, "ranges");
	sc->sc_range =
		(struct rom_range *)malloc(rlen, M_DEVBUF, M_NOWAIT);
	if (sc->sc_range == NULL) {
		printf("%s: PROM ranges too large: %d\n",
				sc->sc_dv.dv_xname, rlen);
		return;
	}
	sc->sc_nrange = rlen / sizeof(struct rom_range);
	(void)getprop(sc->sc_node, "ranges", sc->sc_range, rlen);

	for (i = 0; i < sc->sc_nrange; i++) {
		for (j = 0; j < sbp->sc_nrange; j++) {
			if (sc->sc_range[i].pspace == sbp->sc_range[j].cspace) {
				sc->sc_range[i].poffset +=
				    sbp->sc_range[j].poffset;
				sc->sc_range[i].pspace =
				    sbp->sc_range[j].pspace;
				break;
			}
		}
	}
}

int
xboxprint(args, sbus)
	void *args;
	const char *sbus;
{
	struct confargs *ca = args;

	if (sbus)
		printf("%s at %s", ca->ca_ra.ra_name, sbus);
	return (UNCONF);
}


code:
/*	$OpenBSD: xboxreg.h,v 1.2 2003/06/02 18:40:59 jason Exp $	*/

/*
 * Copyright (c) 1999 Jason L. Wright (jason@thought.net)
 * 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.
 */

struct xbox_errs {
	volatile	u_int32_t xe_errd;	/* error descriptor */
	volatile	u_int32_t xe_errva;	/* error virtual addr */
	volatile	u_int32_t xe_stat;	/* status */
	volatile	u_int32_t xe_ctl0;	/* control reg 0 */
};

struct xbox_regs {
	/* XA space */
	volatile	u_int32_t *xa_write0;	/* write0 reg */
	struct		xbox_errs *xa_errs;	/* errors */
	volatile	u_int32_t *xa_ctl0;	/* ctl0 reg */
	volatile	u_int32_t *xa_ctl1;	/* ctl1 reg */
	volatile	u_int32_t *xa_elua;
	volatile	u_int32_t *xa_ella;
	volatile	u_int32_t *xa_rsrv;	/* reserved */

	/* XB space */
	struct		xbox_errs *xb_errs;	/* errors */
	volatile	u_int32_t *xb_ctl0;	/* ctl0 reg */
	volatile	u_int32_t *xb_ctl1;	/* ctl1 reg */
	volatile	u_int32_t *xb_elua;
	volatile	u_int32_t *xb_ella;
	volatile	u_int32_t *xb_rsrv;	/* reserved */
};

#define	XAC_CTL0_OFFSET		0x100000	/* control reg 0 */
#define	XAC_CTL1_OFFSET		0x110000	/* control reg 1 */
#define	XAC_ELUA_OFFSET		0x120000
#define	XAC_ELLA_OFFSET		0x130000
#define	XAC_ERR_EN_OFFSET	0x140000	/* error enable */

#define	XBC_CTL0_OFFSET		0x500000	/* control reg 0 */
#define	XBC_CTL1_OFFSET		0x510000	/* control reg 1 */
#define	XBC_ELUA_OFFSET		0x520000
#define	XBC_ELLA_OFFSET		0x530000
#define	XBC_ERR_EN_OFFSET	0x540000	/* error enable */

/*
 * Control register 1
 */
#define	XBOX_CTL1_CDPTE1	0x8000	/* cable data parity test enb */
#define	XBOX_CTL1_CRTE		0x4000	/* cable rerun test enb */
#define	XBOX_CTL1_SRST		0x3000	/* software reset mask */
#define	XBOX_CTL1_SRST_XARS	0x1000
#define	XBOX_CTL1_SRST_CRES	0x2000
#define	XBOX_CTL1_SRST_HRES	0x3000
#define	XBOX_CTL1_DTE		0x0800	/* dvma test enb */
#define	XBOX_CTL1_CDPTE		0x0400	/* cable data parity test enb */
#define	XBOX_CTL1_ITE		0x0200	/* interrupt test enb */
#define	XBOX_CTL1_CDPTE0	0x0100	/* cable data parity test enb, dpr0 */
#define	XBOX_CTL1_ELDS		0x00c0	/* error log dvma size */
#define	XBOX_CTL1_XSSE		0x0020	/* expansion sbus slot select enb */
#define	XBOX_CTL1_XSBRE		0x0010	/* expansion sbus bus request enb */
#define	XBOX_CTL1_XSIE		0x0008	/* expansion sbus interrupt enb */
#define	XBOX_CTL1_ELDE		0x0004	/* error log dvma enable */
#define	XBOX_CTL1_CSIE		0x0002	/* cable serial interrupt enb */
#define	XBOX_CTL1_TRANSPARENT	0x0001	/* transparent mode enb */


code:
/*	$OpenBSD: xboxvar.h,v 1.3 2006/06/02 20:00:54 miod Exp $	*/

/*
 * Copyright (c) 1999 Jason L. Wright (jason@thought.net)
 * 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.
 */

struct xbox_softc {
	struct device	sc_dv;			/* base device */
	u_int32_t	sc_key;			/* device key */
	int		sc_node;		/* sbus node */
	int		sc_attached;		/* has sbus attached? */
	int		sc_nrange;		/* number of ranges */
	struct		rom_range *sc_range;	/* address ranges */
	struct		xbox_regs sc_regs;	/* register pointers */
};