1/* SPDX-License-Identifier: GPL-2.0 */ 2/* 3 * Copyright (C) 2020 Marvell International Ltd. 4 * 5 * Interface to the Octeon extended error status. 6 */ 7 8#ifndef __CVMX_ERROR_H__ 9#define __CVMX_ERROR_H__ 10 11/** 12 * There are generally many error status bits associated with a 13 * single logical group. The enumeration below is used to 14 * communicate high level groups to the error infastructure so 15 * error status bits can be enable or disabled in large groups. 16 */ 17typedef enum { 18 CVMX_ERROR_GROUP_INTERNAL, 19 CVMX_ERROR_GROUP_L2C, 20 CVMX_ERROR_GROUP_ETHERNET, 21 CVMX_ERROR_GROUP_MGMT_PORT, 22 CVMX_ERROR_GROUP_PCI, 23 CVMX_ERROR_GROUP_SRIO, 24 CVMX_ERROR_GROUP_USB, 25 CVMX_ERROR_GROUP_LMC, 26 CVMX_ERROR_GROUP_ILK, 27 CVMX_ERROR_GROUP_DFM, 28 CVMX_ERROR_GROUP_ILA, 29} cvmx_error_group_t; 30 31/** 32 * Flags representing special handling for some error registers. 33 * These flags are passed to cvmx_error_initialize() to control 34 * the handling of bits where the same flags were passed to the 35 * added cvmx_error_info_t. 36 */ 37typedef enum { 38 CVMX_ERROR_TYPE_NONE = 0, 39 CVMX_ERROR_TYPE_SBE = 1 << 0, 40 CVMX_ERROR_TYPE_DBE = 1 << 1, 41} cvmx_error_type_t; 42 43/** 44 * When registering for interest in an error status register, the 45 * type of the register needs to be known by cvmx-error. Most 46 * registers are either IO64 or IO32, but some blocks contain 47 * registers that can't be directly accessed. A good example of 48 * would be PCIe extended error state stored in config space. 49 */ 50typedef enum { 51 __CVMX_ERROR_REGISTER_NONE, 52 CVMX_ERROR_REGISTER_IO64, 53 CVMX_ERROR_REGISTER_IO32, 54 CVMX_ERROR_REGISTER_PCICONFIG, 55 CVMX_ERROR_REGISTER_SRIOMAINT, 56} cvmx_error_register_t; 57 58struct cvmx_error_info; 59/** 60 * Error handling functions must have the following prototype. 61 */ 62typedef int (*cvmx_error_func_t)(const struct cvmx_error_info *info); 63 64/** 65 * This structure is passed to all error handling functions. 66 */ 67typedef struct cvmx_error_info { 68 cvmx_error_register_t reg_type; 69 u64 status_addr; 70 u64 status_mask; 71 u64 enable_addr; 72 u64 enable_mask; 73 cvmx_error_type_t flags; 74 cvmx_error_group_t group; 75 int group_index; 76 cvmx_error_func_t func; 77 u64 user_info; 78 struct { 79 cvmx_error_register_t reg_type; 80 u64 status_addr; 81 u64 status_mask; 82 } parent; 83} cvmx_error_info_t; 84 85/** 86 * Initialize the error status system. This should be called once 87 * before any other functions are called. This function adds default 88 * handlers for most all error events but does not enable them. Later 89 * calls to cvmx_error_enable() are needed. 90 * 91 * @param flags Optional flags. 92 * 93 * Return: Zero on success, negative on failure. 94 */ 95int cvmx_error_initialize(void); 96 97/** 98 * Poll the error status registers and call the appropriate error 99 * handlers. This should be called in the RSL interrupt handler 100 * for your application or operating system. 101 * 102 * Return: Number of error handlers called. Zero means this call 103 * found no errors and was spurious. 104 */ 105int cvmx_error_poll(void); 106 107/** 108 * Register to be called when an error status bit is set. Most users 109 * will not need to call this function as cvmx_error_initialize() 110 * registers default handlers for most error conditions. This function 111 * is normally used to add more handlers without changing the existing 112 * handlers. 113 * 114 * @param new_info Information about the handler for a error register. The 115 * structure passed is copied and can be destroyed after the 116 * call. All members of the structure must be populated, even the 117 * parent information. 118 * 119 * Return: Zero on success, negative on failure. 120 */ 121int cvmx_error_add(const cvmx_error_info_t *new_info); 122 123/** 124 * Remove all handlers for a status register and mask. Normally 125 * this function should not be called. Instead a new handler should be 126 * installed to replace the existing handler. In the even that all 127 * reporting of a error bit should be removed, then use this 128 * function. 129 * 130 * @param reg_type Type of the status register to remove 131 * @param status_addr 132 * Status register to remove. 133 * @param status_mask 134 * All handlers for this status register with this mask will be 135 * removed. 136 * @param old_info If not NULL, this is filled with information about the handler 137 * that was removed. 138 * 139 * Return: Zero on success, negative on failure (not found). 140 */ 141int cvmx_error_remove(cvmx_error_register_t reg_type, u64 status_addr, u64 status_mask, 142 cvmx_error_info_t *old_info); 143 144/** 145 * Change the function and user_info for an existing error status 146 * register. This function should be used to replace the default 147 * handler with an application specific version as needed. 148 * 149 * @param reg_type Type of the status register to change 150 * @param status_addr 151 * Status register to change. 152 * @param status_mask 153 * All handlers for this status register with this mask will be 154 * changed. 155 * @param new_func New function to use to handle the error status 156 * @param new_user_info 157 * New user info parameter for the function 158 * @param old_func If not NULL, the old function is returned. Useful for restoring 159 * the old handler. 160 * @param old_user_info 161 * If not NULL, the old user info parameter. 162 * 163 * Return: Zero on success, negative on failure 164 */ 165int cvmx_error_change_handler(cvmx_error_register_t reg_type, u64 status_addr, u64 status_mask, 166 cvmx_error_func_t new_func, u64 new_user_info, 167 cvmx_error_func_t *old_func, u64 *old_user_info); 168 169/** 170 * Enable all error registers for a logical group. This should be 171 * called whenever a logical group is brought online. 172 * 173 * @param group Logical group to enable 174 * @param group_index 175 * Index for the group as defined in the cvmx_error_group_t 176 * comments. 177 * 178 * Return: Zero on success, negative on failure. 179 */ 180/* 181 * Rather than conditionalize the calls throughout the executive to not enable 182 * interrupts in Uboot, simply make the enable function do nothing 183 */ 184static inline int cvmx_error_enable_group(cvmx_error_group_t group, int group_index) 185{ 186 return 0; 187} 188 189/** 190 * Disable all error registers for a logical group. This should be 191 * called whenever a logical group is brought offline. Many blocks 192 * will report spurious errors when offline unless this function 193 * is called. 194 * 195 * @param group Logical group to disable 196 * @param group_index 197 * Index for the group as defined in the cvmx_error_group_t 198 * comments. 199 * 200 * Return: Zero on success, negative on failure. 201 */ 202/* 203 * Rather than conditionalize the calls throughout the executive to not disable 204 * interrupts in Uboot, simply make the enable function do nothing 205 */ 206static inline int cvmx_error_disable_group(cvmx_error_group_t group, int group_index) 207{ 208 return 0; 209} 210 211/** 212 * Enable all handlers for a specific status register mask. 213 * 214 * @param reg_type Type of the status register 215 * @param status_addr 216 * Status register address 217 * @param status_mask 218 * All handlers for this status register with this mask will be 219 * enabled. 220 * 221 * Return: Zero on success, negative on failure. 222 */ 223int cvmx_error_enable(cvmx_error_register_t reg_type, u64 status_addr, u64 status_mask); 224 225/** 226 * Disable all handlers for a specific status register and mask. 227 * 228 * @param reg_type Type of the status register 229 * @param status_addr 230 * Status register address 231 * @param status_mask 232 * All handlers for this status register with this mask will be 233 * disabled. 234 * 235 * Return: Zero on success, negative on failure. 236 */ 237int cvmx_error_disable(cvmx_error_register_t reg_type, u64 status_addr, u64 status_mask); 238 239/** 240 * @INTERNAL 241 * Function for processing non leaf error status registers. This function 242 * calls all handlers for this passed register and all children linked 243 * to it. 244 * 245 * @param info Error register to check 246 * 247 * Return: Number of error status bits found or zero if no bits were set. 248 */ 249int __cvmx_error_decode(const cvmx_error_info_t *info); 250 251/** 252 * @INTERNAL 253 * This error bit handler simply prints a message and clears the status bit 254 * 255 * @param info Error register to check 256 * 257 * @return 258 */ 259int __cvmx_error_display(const cvmx_error_info_t *info); 260 261/** 262 * Find the handler for a specific status register and mask 263 * 264 * @param status_addr 265 * Status register address 266 * 267 * Return: Return the handler on success or null on failure. 268 */ 269cvmx_error_info_t *cvmx_error_get_index(u64 status_addr); 270 271void __cvmx_install_gmx_error_handler_for_xaui(void); 272 273/** 274 * 78xx related 275 */ 276/** 277 * Compare two INTSN values. 278 * 279 * @param key INTSN value to search for 280 * @param data current entry from the searched array 281 * 282 * Return: Negative, 0 or positive when respectively key is less than, 283 * equal or greater than data. 284 */ 285int cvmx_error_intsn_cmp(const void *key, const void *data); 286 287/** 288 * @INTERNAL 289 * 290 * @param intsn Interrupt source number to display 291 * 292 * @param node Node number 293 * 294 * Return: Zero on success, -1 on error 295 */ 296int cvmx_error_intsn_display_v3(int node, u32 intsn); 297 298/** 299 * Initialize the error status system for cn78xx. This should be called once 300 * before any other functions are called. This function enables the interrupts 301 * described in the array. 302 * 303 * @param node Node number 304 * 305 * Return: Zero on success, negative on failure. 306 */ 307int cvmx_error_initialize_cn78xx(int node); 308 309/** 310 * Enable interrupt for a specific INTSN. 311 * 312 * @param node Node number 313 * @param intsn Interrupt source number 314 * 315 * Return: Zero on success, negative on failure. 316 */ 317int cvmx_error_intsn_enable_v3(int node, u32 intsn); 318 319/** 320 * Disable interrupt for a specific INTSN. 321 * 322 * @param node Node number 323 * @param intsn Interrupt source number 324 * 325 * Return: Zero on success, negative on failure. 326 */ 327int cvmx_error_intsn_disable_v3(int node, u32 intsn); 328 329/** 330 * Clear interrupt for a specific INTSN. 331 * 332 * @param intsn Interrupt source number 333 * 334 * Return: Zero on success, negative on failure. 335 */ 336int cvmx_error_intsn_clear_v3(int node, u32 intsn); 337 338/** 339 * Enable interrupts for a specific CSR(all the bits/intsn in the csr). 340 * 341 * @param node Node number 342 * @param csr_address CSR address 343 * 344 * Return: Zero on success, negative on failure. 345 */ 346int cvmx_error_csr_enable_v3(int node, u64 csr_address); 347 348/** 349 * Disable interrupts for a specific CSR (all the bits/intsn in the csr). 350 * 351 * @param node Node number 352 * @param csr_address CSR address 353 * 354 * Return: Zero 355 */ 356int cvmx_error_csr_disable_v3(int node, u64 csr_address); 357 358/** 359 * Enable all error registers for a logical group. This should be 360 * called whenever a logical group is brought online. 361 * 362 * @param group Logical group to enable 363 * @param xipd_port The IPD port value 364 * 365 * Return: Zero. 366 */ 367int cvmx_error_enable_group_v3(cvmx_error_group_t group, int xipd_port); 368 369/** 370 * Disable all error registers for a logical group. 371 * 372 * @param group Logical group to enable 373 * @param xipd_port The IPD port value 374 * 375 * Return: Zero. 376 */ 377int cvmx_error_disable_group_v3(cvmx_error_group_t group, int xipd_port); 378 379/** 380 * Enable all error registers for a specific category in a logical group. 381 * This should be called whenever a logical group is brought online. 382 * 383 * @param group Logical group to enable 384 * @param type Category in a logical group to enable 385 * @param xipd_port The IPD port value 386 * 387 * Return: Zero. 388 */ 389int cvmx_error_enable_group_type_v3(cvmx_error_group_t group, cvmx_error_type_t type, 390 int xipd_port); 391 392/** 393 * Disable all error registers for a specific category in a logical group. 394 * This should be called whenever a logical group is brought online. 395 * 396 * @param group Logical group to disable 397 * @param type Category in a logical group to disable 398 * @param xipd_port The IPD port value 399 * 400 * Return: Zero. 401 */ 402int cvmx_error_disable_group_type_v3(cvmx_error_group_t group, cvmx_error_type_t type, 403 int xipd_port); 404 405/** 406 * Clear all error registers for a logical group. 407 * 408 * @param group Logical group to disable 409 * @param xipd_port The IPD port value 410 * 411 * Return: Zero. 412 */ 413int cvmx_error_clear_group_v3(cvmx_error_group_t group, int xipd_port); 414 415/** 416 * Enable all error registers for a particular category. 417 * 418 * @param node CCPI node 419 * @param type category to enable 420 * 421 *Return: Zero. 422 */ 423int cvmx_error_enable_type_v3(int node, cvmx_error_type_t type); 424 425/** 426 * Disable all error registers for a particular category. 427 * 428 * @param node CCPI node 429 * @param type category to disable 430 * 431 *Return: Zero. 432 */ 433int cvmx_error_disable_type_v3(int node, cvmx_error_type_t type); 434 435void cvmx_octeon_hang(void) __attribute__((__noreturn__)); 436 437/** 438 * @INTERNAL 439 * 440 * Process L2C single and multi-bit ECC errors 441 * 442 */ 443int __cvmx_cn7xxx_l2c_l2d_ecc_error_display(int node, int intsn); 444 445/** 446 * Handle L2 cache TAG ECC errors and noway errors 447 * 448 * @param CCPI node 449 * @param intsn intsn from error array. 450 * @param remote true for remote node (cn78xx only) 451 * 452 * Return: 1 if handled, 0 if not handled 453 */ 454int __cvmx_cn7xxx_l2c_tag_error_display(int node, int intsn, bool remote); 455 456#endif 457