/*      $NetBSD: pccreg.h,v 1.11 2011/02/01 20:19:31 chuck Exp $        */

/*
* Copyright (c) 1995 Charles D. Cranor
* 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.
*/

/*
* peripheral channel controller on mvme147
*/
#ifndef __MVME68K_PCCREG_H
#define __MVME68K_PCCREG_H

/*
* Offsets to the MVME147's onboard device registers.
* (Relative to the bus_space_tag_t passed in from 'mainbus')
*/
#define PCC_LE_OFF      0x0800          /* offset of LANCE ethernet chip */
#define PCC_VME_OFF     0x1000          /* offset of VME chip */
#define PCC_LPT_OFF     0x1800          /* offset of parallel port register */
#define PCC_ZS0_OFF     0x2000          /* offset of first 8530 UART */
#define PCC_ZS1_OFF     0x2800          /* offset of second 8530 UART */
#define PCC_WDSC_OFF    0x3000          /* offset of 33c93 SCSI chip */

/*
* This is needed to figure out the boot device.
* (The physical address of the boot device's registers are passed in
* from the Boot ROM)
*/
#define PCC_PADDR(off) ((void *)(0xfffe0000u + (off)))

/*
* The PCC chip's own registers. These are 8-bits wide, unless
* otherwise indicated.
*/
#define PCCREG_DMA_TABLE_ADDR   0x00 /* DMA table address (32-bit) */
#define PCCREG_DMA_DATA_ADDR    0x04 /* DMA data address (32-bit) */
#define PCCREG_DMA_BYTE_COUNT   0x08 /* DMA byte count (32-bit) */
#define PCCREG_DMA_DATA_HOLD    0x0c /* DMA data hold register (32-bit) */
#define PCCREG_TMR1_PRELOAD     0x10 /* Timer1 preload (16-bit) */
#define PCCREG_TMR1_COUNT       0x12 /* Timer1 count (16-bit) */
#define PCCREG_TMR2_PRELOAD     0x14 /* Timer2 preload (16-bit) */
#define PCCREG_TMR2_COUNT       0x16 /* Timer2 count (16-bit) */
#define PCCREG_TMR1_INTR_CTRL   0x18 /* Timer1 interrupt ctrl */
#define PCCREG_TMR1_CONTROL     0x19 /* Timer1 ctrl reg */
#define PCCREG_TMR2_INTR_CTRL   0x1a /* Timer2 interrupt ctrl */
#define PCCREG_TMR2_CONTROL     0x1b /* Timer2 ctrl reg */
#define PCCREG_ACFAIL_INTR_CTRL 0x1c /* ACFAIL intr reg */
#define PCCREG_WDOG_INTR_CTRL   0x1d /* Watchdog intr reg */
#define PCCREG_PRNT_INTR_CTRL   0x1e /* Printer intr reg */
#define PCCREG_PRNT_CONTROL     0x1f /* Printer ctrl */
#define PCCREG_DMA_INTR_CTRL    0x20 /* DMA interrupt control */
#define PCCREG_DMA_CONTROL      0x21 /* DMA csr */
#define PCCREG_BUSERR_INTR_CTRL 0x22 /* Bus error interrupt */
#define PCCREG_DMA_STATUS       0x23 /* DMA status register */
#define PCCREG_ABORT_INTR_CTRL  0x24 /* ABORT interrupt control reg */
#define PCCREG_TABLE_ADDR_FC    0x25 /* Table address function code reg */
#define PCCREG_SERIAL_INTR_CTRL 0x26 /* Serial interrupt reg */
#define PCCREG_GENERAL_CONTROL  0x27 /* General control register */
#define PCCREG_LANCE_INTR_CTRL  0x28 /* Ethernet interrupt */
#define PCCREG_GENERAL_STATUS   0x29 /* General status */
#define PCCREG_SCSI_INTR_CTRL   0x2a /* SCSI interrupt reg */
#define PCCREG_SLAVE_BASE_ADDR  0x2b /* Slave base addr reg */
#define PCCREG_SOFT1_INTR_CTRL  0x2c /* Software interrupt #1 cr */
#define PCCREG_VECTOR_BASE      0x2d /* Interrupt base vector register */
#define PCCREG_SOFT2_INTR_CTRL  0x2e /* Software interrupt #2 cr */
#define PCCREG_REVISION         0x2f /* Revision level */

#define PCCREG_SIZE             0x30

/*
* Convenience macros for reading the PCC chip's registers
* through bus_space.
*/
#define pcc_reg_read(sc,r)      \
               bus_space_read_1((sc)->sc_bust, (sc)->sc_bush, (r))
#define pcc_reg_read16(sc,r)    \
               bus_space_read_2((sc)->sc_bust, (sc)->sc_bush, (r))
#define pcc_reg_read32(sc,r)    \
               bus_space_read_4((sc)->sc_bust, (sc)->sc_bush, (r))
#define pcc_reg_write(sc,r,v)   \
               bus_space_write_1((sc)->sc_bust, (sc)->sc_bush, (r), (v))
#define pcc_reg_write16(sc,r,v) \
               bus_space_write_2((sc)->sc_bust, (sc)->sc_bush, (r), (v))
#define pcc_reg_write32(sc,r,v) \
               bus_space_write_4((sc)->sc_bust, (sc)->sc_bush, (r), (v))


/*
* we lock off our interrupt vector at 0x40.
*/

#define PCC_VECBASE     0x40
#define PCC_NVEC        12

/*
* vectors we use
*/

#define PCCV_ACFAIL     0
#define PCCV_BERR       1
#define PCCV_ABORT      2
#define PCCV_ZS         3
#define PCCV_LE         4
#define PCCV_SCSI       5
#define PCCV_DMA        6
#define PCCV_PRINTER    7
#define PCCV_TIMER1     8
#define PCCV_TIMER2     9
#define PCCV_SOFT1      10
#define PCCV_SOFT2      11

/*
* enable interrupt
*/

#define PCC_ICLEAR  0x80
#define PCC_IENABLE 0x08

/*
* interrupt mask
*/

#define PCC_IMASK 0x7

/*
* clock/timer
*/

#define PCC_TIMERACK            0x80    /* ack intr */
#define PCC_TIMERCLEAR          0x0     /* reset and clear timer */
#define PCC_TIMERENABLE         0x1     /* Enable clock */
#define PCC_TIMERSTOP           0x3     /* stop clock, but don't clear it */
#define PCC_TIMERSTART          0x7     /* start timer */
#define PCC_TIMEROVFLSHIFT      4

#define PCC_TIMERFREQ           160000
#define pcc_timer_hz2lim(hz)    (0x10000 - (PCC_TIMERFREQ/(hz)))
#define pcc_timer_us2lim(us)    (0x10000 - (PCC_TIMERFREQ/(1000000/(us))))

/*
* serial control
*/

#define PCC_ZSEXTERN 0x10       /* let PCC supply vector */

/*
* abort switch
*/

#define PCC_ABORT_IEN   0x08    /* enable interrupt */
#define PCC_ABORT_ABS   0x40    /* current state of switch */
#define PCC_ABORT_ACK   0x80    /* interrupt active; write to ack */

/*
* general control register
*/

#define PCC_GENCR_IEN   0x10    /* global interrupt enable */

/*
* slave base address register
*/
#define PCC_SLAVE_BASE_MASK     (0x01fu)

#endif /* __MVME68K_PCCREG_H */