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