1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  23  */
  24 
  25 /*
  26  * Copyright 2019, Joyent, Inc.
  27  */
  28 
  29 #ifndef _SYS_PCIEB_H
  30 #define _SYS_PCIEB_H
  31 
  32 #ifdef  __cplusplus
  33 extern "C" {
  34 #endif
  35 
  36 #if defined(DEBUG)
  37 #define PCIEB_DEBUG pcieb_dbg
  38 extern void pcieb_dbg(uint_t bit, dev_info_t *dip, char *fmt, ...);
  39 #else /* DEBUG */
  40 #define PCIEB_DEBUG(...)
  41 #endif /* DEBUG */
  42 
  43 typedef enum {  /* same sequence as pcieb_debug_sym[] */
  44         /*  0 */ DBG_ATTACH,
  45         /*  1 */ DBG_PWR,
  46         /*  2 */ DBG_INTR
  47 } pcieb_debug_bit_t;
  48 
  49 /*
  50  * Intel specific register offsets with bit definitions.
  51  */
  52 #define PCIEB_PX_CAPABILITY_ID  0x44
  53 #define PCIEB_BRIDGE_CONF               0x40
  54 
  55 /*
  56  * PCI/PCI-E Configuration register specific values.
  57  */
  58 #define PX_PMODE        0x4000          /* PCI/PCIX Mode */
  59 #define PX_PFREQ_66     0x200           /* PCI clock frequency */
  60 #define PX_PFREQ_100    0x400
  61 #define PX_PFREQ_133    0x600
  62 #define PX_PMRE         0x80            /* Peer memory read enable */
  63 
  64 /*
  65  * Downstream delayed transaction resource partitioning.
  66  */
  67 #define PX_ODTP         0x40            /* Max. of two entries PX and PCI */
  68 
  69 /*
  70  * Maximum upstream delayed transaction.
  71  */
  72 #define PX_MDT_44       0x00
  73 #define PX_MDT_11       0x01
  74 #define PX_MDT_22       0x10
  75 
  76 #define NUM_LOGICAL_SLOTS       32
  77 #define PCIEB_RANGE_LEN         2
  78 #define PCIEB_32BIT_IO          1
  79 #define PCIEB_32bit_MEM         1
  80 #define PCIEB_MEMGRAIN          0x100000
  81 #define PCIEB_IOGRAIN           0x1000
  82 
  83 #define PCIEB_16bit_IOADDR(addr) ((uint16_t)(((uint8_t)(addr) & 0xF0) << 8))
  84 #define PCIEB_LADDR(lo, hi) (((uint16_t)(hi) << 16) | (uint16_t)(lo))
  85 #define PCIEB_32bit_MEMADDR(addr) (PCIEB_LADDR(0, ((uint16_t)(addr) & 0xFFF0)))
  86 
  87 /*
  88  * Intel 41210 PCIe-to-PCI Bridge has two Functions F0 and F2:
  89  * VID: 0x8086
  90  * DID: F0 = 0x340, F2 = 0x341
  91  */
  92 #define PCIEB_IS_41210_F0(bus_dev_ven_id) (bus_dev_ven_id == 0x3408086)
  93 #define PCIEB_IS_41210_F2(bus_dev_ven_id) (bus_dev_ven_id == 0x3418086)
  94 #define PCIEB_IS_41210_BRIDGE(bus_dev_ven_id) \
  95         (PCIEB_IS_41210_F0(bus_dev_ven_id) || PCIEB_IS_41210_F2(bus_dev_ven_id))
  96 
  97 typedef struct {
  98         dev_info_t              *pcieb_dip;
  99 
 100         /* Interrupt support */
 101         ddi_intr_handle_t       *pcieb_htable;          /* Intr Handlers */
 102         int                     pcieb_htable_size;      /* htable size */
 103         int                     pcieb_intr_count;       /* Num of Intr */
 104         uint_t                  pcieb_intr_priority;    /* Intr Priority */
 105         int                     pcieb_intr_type;        /* (MSI | FIXED) */
 106         int                     pcieb_isr_tab[4];       /* MSI source offset */
 107 
 108         int                     pcieb_init_flags;
 109         kmutex_t                pcieb_mutex;            /* Soft state mutex */
 110         kmutex_t                pcieb_intr_mutex;       /* Intr handler mutex */
 111         kmutex_t                pcieb_err_mutex;        /* Error mutex */
 112         kmutex_t                pcieb_peek_poke_mutex;  /* Peekpoke mutex */
 113 
 114         /* FMA */
 115         boolean_t               pcieb_no_aer_msi;
 116         ddi_iblock_cookie_t     pcieb_fm_ibc;
 117 } pcieb_devstate_t;
 118 
 119 /*
 120  * soft state pointer
 121  */
 122 extern void *pcieb_state;
 123 
 124 /* soft state flags */
 125 #define PCIEB_SOFT_STATE_CLOSED         0x00
 126 #define PCIEB_SOFT_STATE_OPEN           0x01
 127 #define PCIEB_SOFT_STATE_OPEN_EXCL      0x02
 128 
 129 /* init flags */
 130 #define PCIEB_INIT_MUTEX                0x01
 131 #define PCIEB_INIT_HTABLE               0x02
 132 #define PCIEB_INIT_ALLOC                0x04
 133 #define PCIEB_INIT_HANDLER              0x08
 134 #define PCIEB_INIT_ENABLE               0x10
 135 #define PCIEB_INIT_BLOCK                0x20
 136 #define PCIEB_INIT_FM                   0x40
 137 
 138 #define PCIEB_INTR_SRC_UNKNOWN  0x0     /* must be 0 */
 139 #define PCIEB_INTR_SRC_HP       0x1
 140 #define PCIEB_INTR_SRC_PME      0x2
 141 #define PCIEB_INTR_SRC_AER      0x4
 142 
 143 /*
 144  * Need to put vendor ids in a common file and not platform specific files
 145  * as is done today. Until then putting this vendor id define here.
 146  */
 147 #define NVIDIA_VENDOR_ID        0x10de  /* Nvidia Vendor Id */
 148 
 149 #ifdef  PCIEB_BCM
 150 
 151 /* Workaround for address space limitation in Broadcom 5714/5715 */
 152 #define PCIEB_ADDR_LIMIT_LO             0ull
 153 #define PCIEB_ADDR_LIMIT_HI             ((1ull << 40) - 1)
 154 
 155 #endif  /* PCIEB_BCM */
 156 
 157 /*
 158  * The following values are used to initialize the cache line size
 159  * and latency timer registers for PCI, PCI-X and PCIe2PCI devices.
 160  */
 161 #define PCIEB_CACHE_LINE_SIZE   0x10    /* 64 bytes in # of DWORDs */
 162 #define PCIEB_LATENCY_TIMER     0x40    /* 64 PCI cycles */
 163 
 164 extern void     pcieb_set_pci_perf_parameters(dev_info_t *dip,
 165                     ddi_acc_handle_t config_handle);
 166 extern void     pcieb_plat_attach_workaround(dev_info_t *dip);
 167 extern void     pcieb_plat_intr_attach(pcieb_devstate_t *pcieb);
 168 extern void     pcieb_plat_initchild(dev_info_t *child);
 169 extern void     pcieb_plat_uninitchild(dev_info_t *child);
 170 extern int      pcieb_plat_ctlops(dev_info_t *rdip, ddi_ctl_enum_t ctlop,
 171     void *arg);
 172 extern int      pcieb_plat_pcishpc_probe(dev_info_t *dip,
 173     ddi_acc_handle_t config_handle);
 174 extern int      pcieb_plat_peekpoke(dev_info_t *dip, dev_info_t *rdip,
 175     ddi_ctl_enum_t ctlop, void *arg, void *result);
 176 extern void     pcieb_set_prot_scan(dev_info_t *dip, ddi_acc_impl_t *hdlp);
 177 extern int      pcieb_plat_intr_ops(dev_info_t *dip, dev_info_t *rdip,
 178     ddi_intr_op_t intr_op, ddi_intr_handle_impl_t *hdlp, void *result);
 179 extern boolean_t        pcieb_plat_msi_supported(dev_info_t *dip);
 180 extern boolean_t        pcieb_plat_pwr_disable(dev_info_t *dip);
 181 
 182 #if defined(__i386) || defined(__amd64)
 183 extern void     pcieb_intel_error_workaround(dev_info_t *dip);
 184 extern void     pcieb_intel_serr_workaround(dev_info_t *dip, boolean_t mcheck);
 185 extern void     pcieb_intel_rber_workaround(dev_info_t *dip);
 186 extern void     pcieb_intel_sw_workaround(dev_info_t *dip);
 187 extern void     pcieb_intel_mps_workaround(dev_info_t *dip);
 188 extern void     pcieb_init_osc(dev_info_t *dip);
 189 extern void     pcieb_peekpoke_cb(dev_info_t *, ddi_fm_error_t *);
 190 extern int      pcishpc_init(dev_info_t *dip);
 191 extern int      pcishpc_uninit(dev_info_t *dip);
 192 extern int      pcishpc_intr(dev_info_t *dip);
 193 #endif /* defined(__i386) || defined(__amd64) */
 194 
 195 #ifdef PX_PLX
 196 extern void     pcieb_attach_plx_workarounds(pcieb_devstate_t *pcieb);
 197 extern int      pcieb_init_plx_workarounds(pcieb_devstate_t *pcieb,
 198     dev_info_t *child);
 199 #endif /* PX_PLX */
 200 
 201 #ifdef  __cplusplus
 202 }
 203 #endif
 204 
 205 #endif  /* _SYS_PCIEB_H */