1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0 3 * 4 * This file is provided under a dual BSD/GPLv2 license. When using or 5 * redistributing this file, you may do so under either license. 6 * 7 * GPL LICENSE SUMMARY 8 * 9 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of version 2 of the GNU General Public License as 13 * published by the Free Software Foundation. 14 * 15 * This program is distributed in the hope that it will be useful, but 16 * WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 23 * The full GNU General Public License is included in this distribution 24 * in the file called LICENSE.GPL. 25 * 26 * BSD LICENSE 27 * 28 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 29 * All rights reserved. 30 * 31 * Redistribution and use in source and binary forms, with or without 32 * modification, are permitted provided that the following conditions 33 * are met: 34 * 35 * * Redistributions of source code must retain the above copyright 36 * notice, this list of conditions and the following disclaimer. 37 * * Redistributions in binary form must reproduce the above copyright 38 * notice, this list of conditions and the following disclaimer in 39 * the documentation and/or other materials provided with the 40 * distribution. 41 * 42 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 43 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 44 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 45 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 46 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 47 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 48 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 49 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 50 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 51 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 52 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 53 */ 54 55 #include <sys/cdefs.h> 56 __FBSDID("$FreeBSD$"); 57 58 /** 59 * @file 60 * 61 * @brief This file contains the implementation of the SGPIO register inteface 62 * methods. 63 */ 64 65 #include <dev/isci/scil/scic_sgpio.h> 66 #include <dev/isci/scil/scic_sds_controller_registers.h> 67 #include <dev/isci/scil/scic_user_callback.h> 68 69 /** 70 * @brief Function writes Value to the 71 * SGPIO Output Data Select Register (SGODSR) for phys specified by 72 * phy_mask paremeter 73 * 74 * @param[in] SCIC_SDS_CONTROLLER_T controller 75 * @param[in] phy_mask - This field is a bit mask that specifies the phys 76 * to be updated. 77 * @param[in] value - Value for write 78 * 79 * @return none 80 */ 81 static 82 void scic_sgpio_write_SGODSR_register( 83 SCIC_SDS_CONTROLLER_T *controller, 84 U32 phy_mask, 85 U32 value 86 ) 87 { 88 U8 phy_index; 89 90 for (phy_index = 0; phy_index < SCI_MAX_PHYS; phy_index++) 91 { 92 if (phy_mask >> phy_index & 1) 93 { 94 scu_sgpio_peg0_register_write( 95 controller, output_data_select[phy_index], value 96 ); 97 } 98 } 99 } 100 101 void scic_sgpio_set_vendor_code( 102 SCI_CONTROLLER_HANDLE_T controller, 103 U8 vendor_specific_sequence 104 ) 105 { 106 SCIC_SDS_CONTROLLER_T * core_controller = (SCIC_SDS_CONTROLLER_T *) controller; 107 108 scu_sgpio_peg0_register_write( 109 core_controller, vendor_specific_code, vendor_specific_sequence); 110 } 111 112 void scic_sgpio_set_blink_patterns( 113 SCI_CONTROLLER_HANDLE_T controller, 114 U8 pattern_a_low, 115 U8 pattern_a_high, 116 U8 pattern_b_low, 117 U8 pattern_b_high 118 ) 119 { 120 U32 value; 121 SCIC_SDS_CONTROLLER_T * core_controller = (SCIC_SDS_CONTROLLER_T *) controller; 122 123 value = (pattern_b_high << 12) + (pattern_b_low << 8) + (pattern_a_high << 4) + pattern_a_low; 124 125 scu_sgpio_peg0_register_write( 126 core_controller, blink_rate, value); 127 } 128 129 void scic_sgpio_set_functionality( 130 SCI_CONTROLLER_HANDLE_T controller, 131 BOOL sgpio_mode 132 ) 133 { 134 U32 value = DISABLE_SGPIO_FUNCTIONALITY; 135 SCIC_SDS_CONTROLLER_T * core_controller = (SCIC_SDS_CONTROLLER_T *) controller; 136 137 if(sgpio_mode) 138 { 139 value = ENABLE_SGPIO_FUNCTIONALITY; 140 } 141 142 scu_sgpio_peg0_register_write( 143 core_controller, interface_control, value); 144 } 145 146 void scic_sgpio_apply_led_blink_pattern( 147 SCI_CONTROLLER_HANDLE_T controller, 148 U32 phy_mask, 149 BOOL error, 150 BOOL locate, 151 BOOL activity, 152 U8 pattern_selection 153 ) 154 { 155 U32 output_value = 0; 156 157 SCIC_SDS_CONTROLLER_T * core_controller = (SCIC_SDS_CONTROLLER_T *) controller; 158 159 // Start with all LEDs turned off 160 output_value = (SGODSR_INVERT_BIT << SGODSR_ERROR_LED_SHIFT) 161 | (SGODSR_INVERT_BIT << SGODSR_LOCATE_LED_SHIFT) 162 | (SGODSR_INVERT_BIT << SGODSR_ACTIVITY_LED_SHIFT); 163 164 if(error) 165 { //apply pattern to error LED 166 output_value |= pattern_selection << SGODSR_ERROR_LED_SHIFT; 167 output_value &= ~(SGODSR_INVERT_BIT << SGODSR_ERROR_LED_SHIFT); 168 } 169 if(locate) 170 { //apply pattern to locate LED 171 output_value |= pattern_selection << SGODSR_LOCATE_LED_SHIFT; 172 output_value &= ~(SGODSR_INVERT_BIT << SGODSR_LOCATE_LED_SHIFT); 173 } 174 if(activity) 175 { //apply pattern to activity LED 176 output_value |= pattern_selection << SGODSR_ACTIVITY_LED_SHIFT; 177 output_value &= ~(SGODSR_INVERT_BIT << SGODSR_ACTIVITY_LED_SHIFT); 178 } 179 180 scic_sgpio_write_SGODSR_register(core_controller, phy_mask, output_value); 181 } 182 183 void scic_sgpio_set_led_blink_pattern( 184 SCI_CONTROLLER_HANDLE_T controller, 185 SCI_PORT_HANDLE_T port_handle, 186 BOOL error, 187 BOOL locate, 188 BOOL activity, 189 U8 pattern_selection 190 ) 191 { 192 U32 phy_mask; 193 194 SCIC_SDS_PORT_T * port = (SCIC_SDS_PORT_T *) port_handle; 195 196 phy_mask = scic_sds_port_get_phys(port); 197 198 scic_sgpio_apply_led_blink_pattern( 199 controller, phy_mask, error, locate, activity, pattern_selection); 200 } 201 202 void scic_sgpio_update_led_state( 203 SCI_CONTROLLER_HANDLE_T controller, 204 U32 phy_mask, 205 BOOL error, 206 BOOL locate, 207 BOOL activity 208 ) 209 { 210 U32 output_value; 211 212 SCIC_SDS_CONTROLLER_T * core_controller = (SCIC_SDS_CONTROLLER_T *) controller; 213 214 // Start with all LEDs turned on 215 output_value = 0x00000000; 216 217 if(!error) 218 { //turn off error LED 219 output_value |= SGODSR_INVERT_BIT << SGODSR_ERROR_LED_SHIFT; 220 } 221 if(!locate) 222 { //turn off locate LED 223 output_value |= SGODSR_INVERT_BIT << SGODSR_LOCATE_LED_SHIFT; 224 } 225 if(!activity) 226 { //turn off activity LED 227 output_value |= SGODSR_INVERT_BIT << SGODSR_ACTIVITY_LED_SHIFT; 228 } 229 230 scic_sgpio_write_SGODSR_register(core_controller, phy_mask, output_value); 231 } 232 233 void scic_sgpio_set_led_state( 234 SCI_CONTROLLER_HANDLE_T controller, 235 SCI_PORT_HANDLE_T port_handle, 236 BOOL error, 237 BOOL locate, 238 BOOL activity 239 ) 240 { 241 U32 phy_mask; 242 243 SCIC_SDS_PORT_T * port = (SCIC_SDS_PORT_T *) port_handle; 244 245 phy_mask = scic_sds_port_get_phys(port); 246 247 scic_sgpio_update_led_state(controller, phy_mask, error, locate, activity); 248 } 249 250 void scic_sgpio_set_to_hardware_control( 251 SCI_CONTROLLER_HANDLE_T controller, 252 BOOL is_hardware_controlled 253 ) 254 { 255 SCIC_SDS_CONTROLLER_T * core_controller = (SCIC_SDS_CONTROLLER_T *) controller; 256 U8 i; 257 U32 output_value; 258 259 //turn on hardware control for LED's 260 if(is_hardware_controlled) 261 { 262 output_value = SGPIO_HARDWARE_CONTROL; 263 } 264 else //turn off hardware control 265 { 266 output_value = SGPIO_SOFTWARE_CONTROL; 267 } 268 269 for(i = 0; i < SCI_MAX_PHYS; i++) 270 { 271 scu_sgpio_peg0_register_write( 272 core_controller, output_data_select[i], output_value); 273 } 274 } 275 276 U32 scic_sgpio_read( 277 SCI_CONTROLLER_HANDLE_T controller 278 ) 279 { 280 //Not supported in the SCU hardware returning 0xFFFFFFFF 281 return 0xffffffff; 282 } 283 284 void scic_sgpio_hardware_initialize( 285 SCI_CONTROLLER_HANDLE_T controller 286 ) 287 { 288 scic_sgpio_set_functionality(controller, TRUE); 289 scic_sgpio_set_to_hardware_control(controller, TRUE); 290 scic_sgpio_set_vendor_code(controller, 0x00); 291 } 292 293 void scic_sgpio_initialize( 294 SCI_CONTROLLER_HANDLE_T controller 295 ) 296 { 297 scic_sgpio_set_functionality(controller, TRUE); 298 scic_sgpio_set_to_hardware_control(controller, FALSE); 299 scic_sgpio_set_vendor_code(controller, 0x00); 300 } 301