1157873Simp/*- 2157873Simp * This file is provided under a dual BSD/GPLv2 license. When using or 3157873Simp * redistributing this file, you may do so under either license. 4157873Simp * 5157873Simp * GPL LICENSE SUMMARY 6157873Simp * 7157873Simp * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 8157873Simp * 9157873Simp * This program is free software; you can redistribute it and/or modify 10157873Simp * it under the terms of version 2 of the GNU General Public License as 11157873Simp * published by the Free Software Foundation. 12157873Simp * 13157873Simp * This program is distributed in the hope that it will be useful, but 14157873Simp * WITHOUT ANY WARRANTY; without even the implied warranty of 15157873Simp * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16157873Simp * General Public License for more details. 17157873Simp * 18157873Simp * You should have received a copy of the GNU General Public License 19157873Simp * along with this program; if not, write to the Free Software 20157873Simp * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 21157873Simp * The full GNU General Public License is included in this distribution 22157873Simp * in the file called LICENSE.GPL. 23157873Simp * 24157873Simp * BSD LICENSE 25157873Simp * 26157873Simp * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 27161370Simp * All rights reserved. 28157873Simp * 29157873Simp * Redistribution and use in source and binary forms, with or without 30157873Simp * modification, are permitted provided that the following conditions 31157873Simp * are met: 32157873Simp * 33157873Simp * * Redistributions of source code must retain the above copyright 34157873Simp * notice, this list of conditions and the following disclaimer. 35157873Simp * * Redistributions in binary form must reproduce the above copyright 36157873Simp * notice, this list of conditions and the following disclaimer in 37157873Simp * the documentation and/or other materials provided with the 38157873Simp * distribution. 39157873Simp * 40157873Simp * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 41157873Simp * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 42157873Simp * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 43157873Simp * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 44157873Simp * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45157873Simp * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 46157873Simp * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 47157873Simp * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 48157873Simp * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 49157873Simp * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 50157873Simp * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 51157873Simp */ 52157873Simp 53157873Simp#include <sys/cdefs.h> 54157873Simp__FBSDID("$FreeBSD: releng/11.0/sys/dev/isci/scil/scic_sds_pci.c 231136 2012-02-07 17:43:58Z jimharris $"); 55157873Simp 56157873Simp/** 57157873Simp * @file 58157873Simp * 59157873Simp * @brief This file contains the method implementations utilized in writing 60157873Simp * out PCI data for the SCI core. 61157873Simp */ 62157873Simp 63157873Simp#include <dev/isci/scil/scic_user_callback.h> 64157873Simp 65157873Simp#include <dev/isci/scil/scic_sds_pci.h> 66157873Simp#include <dev/isci/scil/scic_sds_controller.h> 67157873Simp 68157873Simp/** 69157873Simp * @brief This method reads from the driver the BARs that are needed to 70157873Simp * determine the virtual memory space for the controller registers 71157873Simp * 72157873Simp * @param[in] this_controller The controller for which to read the base 73157873Simp * address registers. 74157873Simp */ 75157873Simpvoid scic_sds_pci_bar_initialization( 76157873Simp SCIC_SDS_CONTROLLER_T* this_controller 77157873Simp) 78157873Simp{ 79157873Simp#ifdef ARLINGTON_BUILD 80157873Simp 81157873Simp #define ARLINGTON_LEX_BAR 0 82157873Simp #define ARLINGTON_SMU_BAR 1 83157873Simp #define ARLINGTON_SCU_BAR 2 84157873Simp #define LEX_REGISTER_OFFSET 0x40000 85157873Simp 86157873Simp this_controller->lex_registers = 87157873Simp ((char *)scic_cb_pci_get_bar( 88157873Simp this_controller, ARLINGTON_LEX_BAR) + LEX_REGISTER_OFFSET); 89157873Simp this_controller->smu_registers = 90157873Simp (SMU_REGISTERS_T *)scic_cb_pci_get_bar(this_controller, ARLINGTON_SMU_BAR); 91157873Simp this_controller->scu_registers = 92157873Simp (SCU_REGISTERS_T *)scic_cb_pci_get_bar(this_controller, ARLINGTON_SCU_BAR); 93157873Simp 94157873Simp#else // !ARLINGTON_BUILD 95157873Simp 96157873Simp#if !defined(ENABLE_PCI_IO_SPACE_ACCESS) 97157873Simp 98157873Simp this_controller->smu_registers = 99157873Simp (SMU_REGISTERS_T *)( 100157873Simp (char *)scic_cb_pci_get_bar(this_controller, PATSBURG_SMU_BAR) 101157873Simp +(0x4000 * this_controller->controller_index)); 102157873Simp this_controller->scu_registers = 103157873Simp (SCU_REGISTERS_T *)( 104157873Simp (char *)scic_cb_pci_get_bar(this_controller, PATSBURG_SCU_BAR) 105157873Simp +(0x400000 * this_controller->controller_index)); 106157873Simp 107161196Simp#else // !defined(ENABLE_PCI_IO_SPACE_ACCESS) 108161196Simp 109161196Simp if (this_controller->controller_index == 0) 110161196Simp { 111161196Simp this_controller->smu_registers = (SMU_REGISTERS_T *) 112161196Simp scic_cb_pci_get_bar(this_controller, PATSBURG_IO_SPACE_BAR0); 113157873Simp } 114157873Simp else 115157873Simp { 116161196Simp if (this_controller->pci_revision == SCU_PBG_HBA_REV_B0) 117161196Simp { 118157873Simp // SCU B0 violates PCI spec for size of IO bar this is corrected 119161196Simp // in subsequent version of the hardware so we can safely use the 120161196Simp // else condition below. 121161196Simp this_controller->smu_registers = (SMU_REGISTERS_T *) 122161196Simp (scic_cb_pci_get_bar(this_controller, PATSBURG_IO_SPACE_BAR0) + 0x100); 123161196Simp } 124161196Simp else 125161196Simp { 126161196Simp this_controller->smu_registers = (SMU_REGISTERS_T *) 127161196Simp scic_cb_pci_get_bar(this_controller, PATSBURG_IO_SPACE_BAR1); 128161196Simp } 129157873Simp } 130161370Simp 131161370Simp // No need to get the bar. We will be using the offset to write to 132161370Simp // input/output ports via 0xA0 and 0xA4. 133161370Simp this_controller->scu_registers = (SCU_REGISTERS_T *) 0; 134161370Simp 135161370Simp#endif // !defined(ENABLE_PCI_IO_SPACE_ACCESS) 136161370Simp 137161370Simp#endif // ARLINGTON_BUILD 138157873Simp} 139 140#if defined(ENABLE_PCI_IO_SPACE_ACCESS) && !defined(ARLINGTON_BUILD) 141 142/** 143 * @brief This method will read from PCI memory for the SMU register 144 * space via IO space access. 145 * 146 * @param[in] controller The controller for which to read a DWORD. 147 * @param[in] address This parameter depicts the address from 148 * which to read. 149 * 150 * @return The value being returned from the PCI memory location. 151 * 152 * @todo This PCI memory access calls likely need to be optimized into macro? 153 */ 154U32 scic_sds_pci_read_smu_dword( 155 SCI_CONTROLLER_HANDLE_T controller, 156 void * address 157) 158{ 159 return scic_cb_pci_read_dword(controller, address); 160} 161 162/** 163 * @brief This method will write to PCI memory for the SMU register 164 * space via IO space access. 165 * 166 * @param[in] controller The controller for which to read a DWORD. 167 * @param[in] address This parameter depicts the address into 168 * which to write. 169 * @param[out] write_value This parameter depicts the value being written 170 * into the PCI memory location. 171 * 172 * @todo This PCI memory access calls likely need to be optimized into macro? 173 */ 174void scic_sds_pci_write_smu_dword( 175 SCI_CONTROLLER_HANDLE_T controller, 176 void * address, 177 U32 write_value 178) 179{ 180 scic_cb_pci_write_dword(controller, address, write_value); 181} 182 183/** 184 * @brief This method will read from PCI memory for the SCU register 185 * space via IO space access. 186 * 187 * @param[in] controller The controller for which to read a DWORD. 188 * @param[in] address This parameter depicts the address from 189 * which to read. 190 * 191 * @return The value being returned from the PCI memory location. 192 * 193 * @todo This PCI memory access calls likely need to be optimized into macro? 194 */ 195U32 scic_sds_pci_read_scu_dword( 196 SCI_CONTROLLER_HANDLE_T controller, 197 void * address 198) 199{ 200 SCIC_SDS_CONTROLLER_T * this_controller = (SCIC_SDS_CONTROLLER_T*)controller; 201 202 scic_cb_pci_write_dword( 203 controller, 204 (void*) ((char *)(this_controller->smu_registers) + SCU_MMR_ADDRESS_WINDOW_OFFSET), 205 (U32) address 206 ); 207 208 return scic_cb_pci_read_dword( 209 controller, 210 (void*) ((char *)(this_controller->smu_registers) + SCU_MMR_DATA_WINDOW_OFFSET) 211 ); 212} 213 214/** 215 * @brief This method will write to PCI memory for the SCU register 216 * space via IO space access. 217 * 218 * @param[in] controller The controller for which to read a DWORD. 219 * @param[in] address This parameter depicts the address into 220 * which to write. 221 * @param[out] write_value This parameter depicts the value being written 222 * into the PCI memory location. 223 * 224 * @todo This PCI memory access calls likely need to be optimized into macro? 225 */ 226void scic_sds_pci_write_scu_dword( 227 SCI_CONTROLLER_HANDLE_T controller, 228 void * address, 229 U32 write_value 230) 231{ 232 SCIC_SDS_CONTROLLER_T * this_controller = (SCIC_SDS_CONTROLLER_T*)controller; 233 234 scic_cb_pci_write_dword( 235 controller, 236 (void*) ((char *)(this_controller->smu_registers) + SCU_MMR_ADDRESS_WINDOW_OFFSET), 237 (U32) address 238 ); 239 240 scic_cb_pci_write_dword( 241 controller, 242 (void*) ((char *)(this_controller->smu_registers) + SCU_MMR_DATA_WINDOW_OFFSET), 243 write_value 244 ); 245} 246 247#endif // defined(ENABLE_PCI_IO_SPACE_ACCESS) 248