1 /*- 2 * Copyright (c) 2015-2016 Landon Fuller <landon@landonf.org> 3 * Copyright (c) 2017 The FreeBSD Foundation 4 * All rights reserved. 5 * 6 * Portions of this software were developed by Landon Fuller 7 * under sponsorship from the FreeBSD Foundation. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer, 14 * without modification. 15 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 16 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 17 * redistribution must be conditioned upon including a substantially 18 * similar Disclaimer requirement for further binary redistribution. 19 * 20 * NO WARRANTY 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 24 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 25 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 26 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 29 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 31 * THE POSSIBILITY OF SUCH DAMAGES. 32 * 33 */ 34 35 #ifndef _SIBA_SIBAVAR_H_ 36 #define _SIBA_SIBAVAR_H_ 37 38 #include <sys/param.h> 39 #include <sys/bitstring.h> 40 #include <sys/bus.h> 41 #include <sys/limits.h> 42 #include <sys/lock.h> 43 #include <sys/mutex.h> 44 45 #include <machine/bus.h> 46 #include <sys/rman.h> 47 48 #include "siba.h" 49 50 /* 51 * Internal definitions shared by siba(4) driver implementations. 52 */ 53 54 struct siba_addrspace; 55 struct siba_admatch; 56 struct siba_cfg_block; 57 struct siba_devinfo; 58 struct siba_core_id; 59 struct siba_softc; 60 61 int siba_probe(device_t dev); 62 int siba_attach(device_t dev); 63 int siba_detach(device_t dev); 64 int siba_resume(device_t dev); 65 int siba_suspend(device_t dev); 66 u_int siba_get_intr_count(device_t dev, device_t child); 67 int siba_get_intr_ivec(device_t dev, device_t child, 68 u_int intr, u_int *ivec); 69 70 uint16_t siba_get_bhnd_mfgid(uint16_t ocp_vendor); 71 72 int siba_add_children(device_t bus); 73 74 struct siba_devinfo *siba_alloc_dinfo(device_t dev); 75 int siba_init_dinfo(device_t dev, device_t child, 76 struct siba_devinfo *dinfo, 77 const struct siba_core_id *core_id); 78 void siba_free_dinfo(device_t dev, device_t child, 79 struct siba_devinfo *dinfo); 80 81 u_int siba_port_count(struct siba_core_id *core_id, 82 bhnd_port_type port_type); 83 bool siba_is_port_valid(struct siba_core_id *core_id, 84 bhnd_port_type port_type, u_int port); 85 86 u_int siba_port_region_count( 87 struct siba_core_id *core_id, 88 bhnd_port_type port_type, u_int port); 89 90 int siba_cfg_index(struct siba_core_id *core_id, 91 bhnd_port_type type, u_int port, u_int region, 92 u_int *cfgidx); 93 94 int siba_addrspace_index(struct siba_core_id *core_id, 95 bhnd_port_type type, u_int port, u_int region, 96 u_int *addridx); 97 98 u_int siba_addrspace_device_port(u_int addrspace); 99 u_int siba_addrspace_device_region(u_int addrspace); 100 101 u_int siba_cfg_agent_port(u_int cfg); 102 u_int siba_cfg_agent_region(u_int cfg); 103 104 struct siba_addrspace *siba_find_addrspace(struct siba_devinfo *dinfo, 105 bhnd_port_type type, u_int port, u_int region); 106 107 struct siba_cfg_block *siba_find_cfg_block(struct siba_devinfo *dinfo, 108 bhnd_port_type type, u_int port, u_int region); 109 110 u_int siba_admatch_offset(uint8_t addrspace); 111 int siba_parse_admatch(uint32_t am, 112 struct siba_admatch *admatch); 113 114 void siba_write_target_state(device_t dev, 115 struct siba_devinfo *dinfo, bus_size_t reg, 116 uint32_t value, uint32_t mask); 117 int siba_wait_target_state(device_t dev, 118 struct siba_devinfo *dinfo, bus_size_t reg, 119 uint32_t value, uint32_t mask, u_int usec); 120 121 122 /* Sonics configuration register blocks */ 123 #define SIBA_CFG_NUM_2_2 1 /**< sonics <= 2.2 maps SIBA_CFG0. */ 124 #define SIBA_CFG_NUM_2_3 2 /**< sonics <= 2.3 maps SIBA_CFG0 and SIBA_CFG1 */ 125 #define SIBA_MAX_CFG SIBA_CFG_NUM_2_3 /**< maximum number of supported config 126 register blocks */ 127 128 #define SIBA_CFG_RID_BASE 100 /**< base resource ID for SIBA_CFG* register allocations */ 129 #define SIBA_CFG_RID(_dinfo, _cfg) \ 130 (SIBA_CFG_RID_BASE + (_cfg) + \ 131 (_dinfo->core_id.core_info.core_idx * SIBA_MAX_CFG)) 132 133 /* Sonics/OCP address space mappings */ 134 #define SIBA_CORE_ADDRSPACE 0 /**< Address space mapping the primary 135 device registers */ 136 137 #define SIBA_MAX_ADDRSPACE 4 /**< Maximum number of Sonics/OCP 138 * address space mappings for a 139 * single core. */ 140 141 /* bhnd(4) (port,region) representation of siba address space mappings */ 142 #define SIBA_MAX_PORT 2 /**< maximum number of advertised 143 * bhnd(4) ports */ 144 145 /** siba(4) address match descriptor */ 146 struct siba_admatch { 147 uint32_t am_base; /**< base address. */ 148 uint32_t am_size; /**< size. */ 149 bool am_negative; /**< if true, negative matching is performed. */ 150 bool am_enabled; /**< if true, matching on this entry is enabled. */ 151 }; 152 153 /** siba(4) address space descriptor */ 154 struct siba_addrspace { 155 uint32_t sa_base; /**< base address */ 156 uint32_t sa_size; /**< size */ 157 int sa_rid; /**< bus resource id */ 158 uint32_t sa_bus_reserved;/**< number of bytes at high end of 159 * address space reserved for the bus */ 160 }; 161 162 /** siba(4) config block descriptor */ 163 struct siba_cfg_block { 164 uint32_t cb_base; /**< base address */ 165 uint32_t cb_size; /**< size */ 166 int cb_rid; /**< bus resource id */ 167 }; 168 169 /** siba(4) backplane interrupt flag descriptor */ 170 struct siba_intr { 171 bool mapped; /**< if an irq has been mapped */ 172 int rid; /**< bus resource id, or -1 if unassigned */ 173 rman_res_t irq; /**< the mapped bus irq, if any */ 174 }; 175 176 /** 177 * siba(4) per-core identification info. 178 */ 179 struct siba_core_id { 180 struct bhnd_core_info core_info; /**< standard bhnd(4) core info */ 181 uint16_t sonics_vendor; /**< OCP vendor identifier used to generate 182 * the JEDEC-106 bhnd(4) vendor identifier. */ 183 uint8_t sonics_rev; /**< sonics backplane revision code */ 184 bool intr_en; /**< if backplane interrupt distribution is enabled for this core */ 185 u_int intr_flag; /**< backplane interrupt flag # */ 186 struct siba_admatch admatch[SIBA_MAX_ADDRSPACE]; /**< active address match descriptors defined by this core. */ 187 uint8_t num_admatch; /**< number of address match descriptors. */ 188 uint8_t num_cfg_blocks; /**< number of Sonics configuration register 189 blocks mapped to the core's enumeration 190 space */ 191 }; 192 193 /** 194 * siba(4) per-core PMU allocation state. 195 */ 196 typedef enum { 197 SIBA_PMU_NONE, /**< If the core has not yet allocated PMU state */ 198 SIBA_PMU_BHND, /**< If standard bhnd(4) PMU support should be used */ 199 SIBA_PMU_PWRCTL, /**< If legacy PWRCTL PMU support should be used */ 200 SIBA_PMU_FIXED, /**< If legacy fixed (no-op) PMU support should be used */ 201 } siba_pmu_state; 202 203 /** 204 * siba(4) per-device info 205 */ 206 struct siba_devinfo { 207 struct resource_list resources; /**< per-core memory regions. */ 208 struct siba_core_id core_id; /**< core identification info */ 209 struct siba_addrspace addrspace[SIBA_MAX_ADDRSPACE]; /**< memory map descriptors */ 210 struct siba_cfg_block cfg[SIBA_MAX_CFG]; /**< config block descriptors */ 211 struct siba_intr intr; /**< interrupt flag mapping, if any */ 212 213 struct bhnd_resource *cfg_res[SIBA_MAX_CFG]; /**< bus-mapped config block registers */ 214 int cfg_rid[SIBA_MAX_CFG]; /**< bus-mapped config block resource IDs */ 215 siba_pmu_state pmu_state; /**< per-core PMU state */ 216 union { 217 void *bhnd_info; /**< if SIBA_PMU_BHND, bhnd(4)-managed per-core PMU info. */ 218 device_t pwrctl; /**< if SIBA_PMU_PWRCTL, legacy PWRCTL provider. */ 219 } pmu; 220 }; 221 222 /** siba(4) per-instance state */ 223 struct siba_softc { 224 struct bhnd_softc bhnd_sc; /**< bhnd state */ 225 device_t dev; /**< siba device */ 226 struct mtx mtx; /**< state mutex */ 227 }; 228 229 #define SIBA_LOCK_INIT(sc) \ 230 mtx_init(&(sc)->mtx, device_get_nameunit((sc)->dev), NULL, MTX_DEF) 231 #define SIBA_LOCK(sc) mtx_lock(&(sc)->mtx) 232 #define SIBA_UNLOCK(sc) mtx_unlock(&(sc)->mtx) 233 #define SIBA_LOCK_ASSERT(sc, what) mtx_assert(&(sc)->mtx, what) 234 #define SIBA_LOCK_DESTROY(sc) mtx_destroy(&(sc)->mtx) 235 236 #endif /* _SIBA_SIBAVAR_H_ */ 237