root/usr/src/uts/sun4u/serengeti/sys/sgsbbc_priv.h
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */

/*
 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef _SYS_SGSBBC_PRIV_H
#define _SYS_SGSBBC_PRIV_H

#pragma ident   "%Z%%M% %I%     %E% SMI"

#ifdef  __cplusplus
extern "C" {
#endif

/*
 * Private structures used by the Serengeti SBBC Driver
 *
 * The Serengeti SBBC driver handles communication between the
 * System Controller Software (ScApp) and Solaris via SBBC
 * registers and IOSRAM.
 *
 * This header file contains necessary definitions to enable
 * such communication.
 *
 * Register offsets and definitions can be found in
 * Serengeti Architecture Programmer's Reference
 * Revision 1.3 11/16/1999
 * Section 2.5 to 2.8
 */

#include <sys/types.h>
#include <sys/dditypes.h>
#include <sys/sgsbbc.h>

/*
 * SBBC Interrupt registers
 */
#define SBBC_MAX_INTRS          32

/*
 * Different interrupts
 */
#define INTERRUPT_ON    0x1     /* bit 0 */
/*
 * EPLD Interrupt Register Offset for communication with the SC
 */
#define EPLD_INTERRUPT  0x13

/*
 * register numbers for mapping in OBP reg properties
 */
#define RNUM_SBBC_REGS          1

/*
 * SBBC registers and devices on CPU/memory board
 */
#define SBBC_REGS_OFFSET        0x800000
#define SBBC_REGS_SIZE          0x6230
#define SBBC_EPLD_OFFSET        0x8e0000
#define SBBC_EPLD_SIZE          0x20
#define SBBC_SRAM_OFFSET        0x900000
#define SBBC_SRAM_SIZE          0x20000         /* max. 128KB of SRAM */
/*
 * Register Offsets
 */
#define SBBC_PCI_INT_STATUS     0x2320
#define SBBC_PCI_INT_ENABLE     0x2330

/*
 * Port Interrupt Enable Register
 *
 * Field        Bits    Reset   Type    Description
 *                      State
 * Resvd        <31:8>  0       R       Reserved
 * PINT1_EN     <7:4>   0       RW      Enables for each of the 4 PCI
 *                                      interrupt lines for Port Interrupt
 *                                      Generation register 1.  Bit 7
 *                                      corresponds to PCI Interrupt D,
 *                                      bit 4 corresponds to PCI Interrupt A.
 * PINT0_EN     <3:0>   0       RW      Same as above, but for register 0.
 */
#define SBBC_PCI_ENABLE_INT_A   0x11    /* Enable both PCI Interrupt A */
#define SBBC_PCI_ENABLE_MASK    0xff    /* Mask for the two enable registers */

#ifdef  DEBUG
#define SGSBBC_DBG_MASK_MBOX            0x00000001
#define SGSBBC_DBG_MASK_INTR            0x00000002
#define SGSBBC_DBG_MASK_EVENT           0x00000004

extern uint_t sgsbbc_debug;
#define SGSBBC_DBG_ALL  if (sgsbbc_debug)       prom_printf
#define SGSBBC_DBG_MBOX \
        if (sgsbbc_debug & SGSBBC_DBG_MASK_MBOX) printf
#define SGSBBC_DBG_INTR \
        if (sgsbbc_debug & SGSBBC_DBG_MASK_INTR) cmn_err
#define SGSBBC_DBG_EVENT \
        if (sgsbbc_debug & SGSBBC_DBG_MASK_EVENT) cmn_err

#else   /* DEBUG */
#define SGSBBC_DBG_ALL
#define SGSBBC_DBG_MBOX
#define SGSBBC_DBG_INTR
#define SGSBBC_DBG_EVENT

#endif  /* DEBUG */


typedef struct sbbc_intrs {
        sbbc_intrfunc_t         sbbc_handler;   /* interrupt handler */
        caddr_t                 sbbc_arg;       /* interrupt argument */
        ddi_softintr_t          sbbc_intr_id;
        kmutex_t                *sbbc_intr_lock;        /* for state flag */
        uint_t                  *sbbc_intr_state;       /* handler state */
        struct sbbc_intrs       *sbbc_intr_next;
        int                     registered;
} sbbc_intrs_t;

struct sbbc_epld_regs {
        uchar_t         epld_reg[32];
};

/*
 * device soft state
 */
typedef struct sbbc_softstate {
        struct sbbc_softstate   *prev;
        struct sbbc_softstate   *next;

        struct chosen_iosram    *iosram; /* back reference */
        dev_info_t              *dip;

        /*
         * Tunnel Info.
         */
        void                    *sram;

        /*
         * SBBC Register Info.
         */
        caddr_t                         sbbc_regs;      /* common device regs */
        uint32_t                        *port_int_regs; /* interrupt regs */
        struct sbbc_epld_regs           *epld_regs;     /* EPLD regs */
        uint32_t                        sram_toc;       /* SRAM TOC */

        /*
         * device map handles for register mapping
         */
        ddi_acc_handle_t                sbbc_reg_handle1;
        ddi_acc_handle_t                sbbc_reg_handle2;
        /*
         * SBBC Interrupts
         */
        uint_t                  inumber;
        ddi_iblock_cookie_t     iblock;
        ddi_idevice_cookie_t    idevice;

        sbbc_intrs_t            *intr_hdlrs;

        /*
         * misc.
         */
        kmutex_t                sbbc_lock;      /* mutex for this struct */
        uchar_t                 suspended;      /* TRUE if instance suspended */
        uchar_t                 chosen;         /* TRUE if instance 'chosen' */
        int                     sbbc_instance;
        int                     sbbc_state;     /* see below */
} sbbc_softstate_t;
/* sbbc iosram state */
#define SBBC_STATE_INIT 0x0001          /* initialization */
#define SBBC_STATE_DETACH 0x0002        /* IOSRAM instance being detached */

/*
 * Structure used for tunnel switch
 */
typedef struct {
        dev_info_t      *cur_dip;       /* current dip that we compare to */
        dev_info_t      *new_dip;       /* new dip that fits the condition */
} sbbc_find_dip_t;

/*
 * Routines for mapping and unmapping SBBC internal registers
 */
extern int      sbbc_map_regs(sbbc_softstate_t *);

/*
 * Interrupt related routines
 */
extern int      sbbc_add_intr(sbbc_softstate_t *);
extern void     sbbc_enable_intr(sbbc_softstate_t *);
extern void     sbbc_disable_intr(sbbc_softstate_t *);
extern int      sbbc_send_intr(sbbc_softstate_t *, int);
extern uint_t   sbbc_intr_handler();

extern sbbc_softstate_t *sbbc_get_soft_state(int);

/*
 * To protect master_chosen
 */
extern kmutex_t chosen_lock;

#ifdef  __cplusplus
}
#endif

#endif  /* _SYS_SGSBBC_PRIV_H */