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 /**
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
scic_sgpio_write_SGODSR_register(SCIC_SDS_CONTROLLER_T * controller,U32 phy_mask,U32 value)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
scic_sgpio_set_vendor_code(SCI_CONTROLLER_HANDLE_T controller,U8 vendor_specific_sequence)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
scic_sgpio_set_blink_patterns(SCI_CONTROLLER_HANDLE_T controller,U8 pattern_a_low,U8 pattern_a_high,U8 pattern_b_low,U8 pattern_b_high)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
scic_sgpio_set_functionality(SCI_CONTROLLER_HANDLE_T controller,BOOL sgpio_mode)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
scic_sgpio_apply_led_blink_pattern(SCI_CONTROLLER_HANDLE_T controller,U32 phy_mask,BOOL error,BOOL locate,BOOL activity,U8 pattern_selection)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
scic_sgpio_set_led_blink_pattern(SCI_CONTROLLER_HANDLE_T controller,SCI_PORT_HANDLE_T port_handle,BOOL error,BOOL locate,BOOL activity,U8 pattern_selection)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
scic_sgpio_update_led_state(SCI_CONTROLLER_HANDLE_T controller,U32 phy_mask,BOOL error,BOOL locate,BOOL activity)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
scic_sgpio_set_led_state(SCI_CONTROLLER_HANDLE_T controller,SCI_PORT_HANDLE_T port_handle,BOOL error,BOOL locate,BOOL activity)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
scic_sgpio_set_to_hardware_control(SCI_CONTROLLER_HANDLE_T controller,BOOL is_hardware_controlled)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
scic_sgpio_read(SCI_CONTROLLER_HANDLE_T controller)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
scic_sgpio_hardware_initialize(SCI_CONTROLLER_HANDLE_T controller)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
scic_sgpio_initialize(SCI_CONTROLLER_HANDLE_T controller)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