scic_sds_pci.c revision 330897
1123474Swpaul/*- 2123474Swpaul * SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0 3123474Swpaul * 4123474Swpaul * This file is provided under a dual BSD/GPLv2 license. When using or 5123474Swpaul * redistributing this file, you may do so under either license. 6123474Swpaul * 7123474Swpaul * GPL LICENSE SUMMARY 8123474Swpaul * 9123474Swpaul * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 10123474Swpaul * 11123474Swpaul * This program is free software; you can redistribute it and/or modify 12123474Swpaul * it under the terms of version 2 of the GNU General Public License as 13123474Swpaul * published by the Free Software Foundation. 14123474Swpaul * 15123474Swpaul * This program is distributed in the hope that it will be useful, but 16123474Swpaul * WITHOUT ANY WARRANTY; without even the implied warranty of 17123474Swpaul * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18123474Swpaul * General Public License for more details. 19123474Swpaul * 20123474Swpaul * You should have received a copy of the GNU General Public License 21123474Swpaul * along with this program; if not, write to the Free Software 22123474Swpaul * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 23123474Swpaul * The full GNU General Public License is included in this distribution 24123474Swpaul * in the file called LICENSE.GPL. 25123474Swpaul * 26123474Swpaul * BSD LICENSE 27123474Swpaul * 28123474Swpaul * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 29123474Swpaul * All rights reserved. 30123474Swpaul * 31123474Swpaul * Redistribution and use in source and binary forms, with or without 32123474Swpaul * modification, are permitted provided that the following conditions 33123474Swpaul * are met: 34123474Swpaul * 35123474Swpaul * * Redistributions of source code must retain the above copyright 36123474Swpaul * notice, this list of conditions and the following disclaimer. 37123474Swpaul * * Redistributions in binary form must reproduce the above copyright 38123474Swpaul * notice, this list of conditions and the following disclaimer in 39123474Swpaul * the documentation and/or other materials provided with the 40123474Swpaul * distribution. 41123474Swpaul * 42123474Swpaul * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 43123474Swpaul * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 44123474Swpaul * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 45123474Swpaul * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 46123474Swpaul * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 47123474Swpaul * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 48124135Swpaul * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 49123474Swpaul * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 50123474Swpaul * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 51123474Swpaul * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 52123474Swpaul * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 53123474Swpaul */ 54123474Swpaul 55123474Swpaul#include <sys/cdefs.h> 56124060Swpaul__FBSDID("$FreeBSD: stable/11/sys/dev/isci/scil/scic_sds_pci.c 330897 2018-03-14 03:19:51Z eadler $"); 57124060Swpaul 58123474Swpaul/** 59123474Swpaul * @file 60123474Swpaul * 61123474Swpaul * @brief This file contains the method implementations utilized in writing 62123474Swpaul * out PCI data for the SCI core. 63123474Swpaul */ 64123695Swpaul 65123695Swpaul#include <dev/isci/scil/scic_user_callback.h> 66123695Swpaul 67123474Swpaul#include <dev/isci/scil/scic_sds_pci.h> 68123474Swpaul#include <dev/isci/scil/scic_sds_controller.h> 69123474Swpaul 70123474Swpaul/** 71123474Swpaul * @brief This method reads from the driver the BARs that are needed to 72123474Swpaul * determine the virtual memory space for the controller registers 73123474Swpaul * 74123474Swpaul * @param[in] this_controller The controller for which to read the base 75123474Swpaul * address registers. 76123474Swpaul */ 77123474Swpaulvoid scic_sds_pci_bar_initialization( 78123474Swpaul SCIC_SDS_CONTROLLER_T* this_controller 79123474Swpaul) 80123474Swpaul{ 81123474Swpaul#ifdef ARLINGTON_BUILD 82123474Swpaul 83123474Swpaul #define ARLINGTON_LEX_BAR 0 84123474Swpaul #define ARLINGTON_SMU_BAR 1 85123535Swpaul #define ARLINGTON_SCU_BAR 2 86123474Swpaul #define LEX_REGISTER_OFFSET 0x40000 87124100Swpaul 88123474Swpaul this_controller->lex_registers = 89124060Swpaul ((char *)scic_cb_pci_get_bar( 90124060Swpaul this_controller, ARLINGTON_LEX_BAR) + LEX_REGISTER_OFFSET); 91123474Swpaul this_controller->smu_registers = 92123474Swpaul (SMU_REGISTERS_T *)scic_cb_pci_get_bar(this_controller, ARLINGTON_SMU_BAR); 93123474Swpaul this_controller->scu_registers = 94123474Swpaul (SCU_REGISTERS_T *)scic_cb_pci_get_bar(this_controller, ARLINGTON_SCU_BAR); 95123474Swpaul 96123474Swpaul#else // !ARLINGTON_BUILD 97123474Swpaul 98123474Swpaul#if !defined(ENABLE_PCI_IO_SPACE_ACCESS) 99123474Swpaul 100124060Swpaul this_controller->smu_registers = 101124060Swpaul (SMU_REGISTERS_T *)( 102124060Swpaul (char *)scic_cb_pci_get_bar(this_controller, PATSBURG_SMU_BAR) 103124060Swpaul +(0x4000 * this_controller->controller_index)); 104124122Swpaul this_controller->scu_registers = 105124122Swpaul (SCU_REGISTERS_T *)( 106124122Swpaul (char *)scic_cb_pci_get_bar(this_controller, PATSBURG_SCU_BAR) 107124122Swpaul +(0x400000 * this_controller->controller_index)); 108124122Swpaul 109124060Swpaul#else // !defined(ENABLE_PCI_IO_SPACE_ACCESS) 110124060Swpaul 111124060Swpaul if (this_controller->controller_index == 0) 112124060Swpaul { 113124060Swpaul this_controller->smu_registers = (SMU_REGISTERS_T *) 114124060Swpaul scic_cb_pci_get_bar(this_controller, PATSBURG_IO_SPACE_BAR0); 115124060Swpaul } 116124060Swpaul else 117124060Swpaul { 118124122Swpaul if (this_controller->pci_revision == SCU_PBG_HBA_REV_B0) 119124122Swpaul { 120124122Swpaul // SCU B0 violates PCI spec for size of IO bar this is corrected 121124122Swpaul // in subsequent version of the hardware so we can safely use the 122124122Swpaul // else condition below. 123124060Swpaul this_controller->smu_registers = (SMU_REGISTERS_T *) 124124060Swpaul (scic_cb_pci_get_bar(this_controller, PATSBURG_IO_SPACE_BAR0) + 0x100); 125124060Swpaul } 126124060Swpaul else 127124060Swpaul { 128124060Swpaul this_controller->smu_registers = (SMU_REGISTERS_T *) 129124060Swpaul scic_cb_pci_get_bar(this_controller, PATSBURG_IO_SPACE_BAR1); 130124060Swpaul } 131124060Swpaul } 132123474Swpaul 133123474Swpaul // No need to get the bar. We will be using the offset to write to 134123474Swpaul // input/output ports via 0xA0 and 0xA4. 135123474Swpaul this_controller->scu_registers = (SCU_REGISTERS_T *) 0; 136123474Swpaul 137123474Swpaul#endif // !defined(ENABLE_PCI_IO_SPACE_ACCESS) 138124100Swpaul 139124100Swpaul#endif // ARLINGTON_BUILD 140124100Swpaul} 141124100Swpaul 142124100Swpaul#if defined(ENABLE_PCI_IO_SPACE_ACCESS) && !defined(ARLINGTON_BUILD) 143124100Swpaul 144124100Swpaul/** 145123474Swpaul * @brief This method will read from PCI memory for the SMU register 146123474Swpaul * space via IO space access. 147123474Swpaul * 148123474Swpaul * @param[in] controller The controller for which to read a DWORD. 149123474Swpaul * @param[in] address This parameter depicts the address from 150123474Swpaul * which to read. 151124060Swpaul * 152124060Swpaul * @return The value being returned from the PCI memory location. 153124060Swpaul * 154124060Swpaul * @todo This PCI memory access calls likely need to be optimized into macro? 155123474Swpaul */ 156123474SwpaulU32 scic_sds_pci_read_smu_dword( 157123474Swpaul SCI_CONTROLLER_HANDLE_T controller, 158123474Swpaul void * address 159123474Swpaul) 160123474Swpaul{ 161123474Swpaul return scic_cb_pci_read_dword(controller, address); 162124060Swpaul} 163124060Swpaul 164124060Swpaul/** 165124060Swpaul * @brief This method will write to PCI memory for the SMU register 166123474Swpaul * space via IO space access. 167123474Swpaul * 168123474Swpaul * @param[in] controller The controller for which to read a DWORD. 169123474Swpaul * @param[in] address This parameter depicts the address into 170123474Swpaul * which to write. 171123474Swpaul * @param[out] write_value This parameter depicts the value being written 172123474Swpaul * into the PCI memory location. 173123474Swpaul * 174123695Swpaul * @todo This PCI memory access calls likely need to be optimized into macro? 175123695Swpaul */ 176123695Swpaulvoid scic_sds_pci_write_smu_dword( 177123695Swpaul SCI_CONTROLLER_HANDLE_T controller, 178123695Swpaul void * address, 179123474Swpaul U32 write_value 180123474Swpaul) 181123474Swpaul{ 182123474Swpaul scic_cb_pci_write_dword(controller, address, write_value); 183123535Swpaul} 184123535Swpaul 185123535Swpaul/** 186123535Swpaul * @brief This method will read from PCI memory for the SCU register 187123695Swpaul * space via IO space access. 188123695Swpaul * 189123695Swpaul * @param[in] controller The controller for which to read a DWORD. 190123695Swpaul * @param[in] address This parameter depicts the address from 191123695Swpaul * which to read. 192123535Swpaul * 193123535Swpaul * @return The value being returned from the PCI memory location. 194123535Swpaul * 195123535Swpaul * @todo This PCI memory access calls likely need to be optimized into macro? 196123474Swpaul */ 197123474SwpaulU32 scic_sds_pci_read_scu_dword( 198123474Swpaul SCI_CONTROLLER_HANDLE_T controller, 199123474Swpaul void * address 200123474Swpaul) 201124060Swpaul{ 202124060Swpaul SCIC_SDS_CONTROLLER_T * this_controller = (SCIC_SDS_CONTROLLER_T*)controller; 203124060Swpaul 204124060Swpaul scic_cb_pci_write_dword( 205123474Swpaul controller, 206123474Swpaul (void*) ((char *)(this_controller->smu_registers) + SCU_MMR_ADDRESS_WINDOW_OFFSET), 207123474Swpaul (U32) address 208123474Swpaul ); 209123474Swpaul 210123474Swpaul return scic_cb_pci_read_dword( 211123474Swpaul controller, 212123474Swpaul (void*) ((char *)(this_controller->smu_registers) + SCU_MMR_DATA_WINDOW_OFFSET) 213123474Swpaul ); 214123474Swpaul} 215123474Swpaul 216123474Swpaul/** 217123474Swpaul * @brief This method will write to PCI memory for the SCU register 218123474Swpaul * space via IO space access. 219123474Swpaul * 220123474Swpaul * @param[in] controller The controller for which to read a DWORD. 221123474Swpaul * @param[in] address This parameter depicts the address into 222123474Swpaul * which to write. 223123474Swpaul * @param[out] write_value This parameter depicts the value being written 224123474Swpaul * into the PCI memory location. 225123474Swpaul * 226124060Swpaul * @todo This PCI memory access calls likely need to be optimized into macro? 227124060Swpaul */ 228123474Swpaulvoid scic_sds_pci_write_scu_dword( 229123474Swpaul SCI_CONTROLLER_HANDLE_T controller, 230123474Swpaul void * address, 231123474Swpaul U32 write_value 232123474Swpaul) 233123474Swpaul{ 234123474Swpaul SCIC_SDS_CONTROLLER_T * this_controller = (SCIC_SDS_CONTROLLER_T*)controller; 235124060Swpaul 236124060Swpaul scic_cb_pci_write_dword( 237123474Swpaul controller, 238123474Swpaul (void*) ((char *)(this_controller->smu_registers) + SCU_MMR_ADDRESS_WINDOW_OFFSET), 239123474Swpaul (U32) address 240123474Swpaul ); 241123474Swpaul 242123474Swpaul scic_cb_pci_write_dword( 243123474Swpaul controller, 244124060Swpaul (void*) ((char *)(this_controller->smu_registers) + SCU_MMR_DATA_WINDOW_OFFSET), 245124060Swpaul write_value 246123474Swpaul ); 247123474Swpaul} 248123474Swpaul 249123474Swpaul#endif // defined(ENABLE_PCI_IO_SPACE_ACCESS) 250123474Swpaul