diff options
Diffstat (limited to 'cvmx-error.c')
| -rw-r--r-- | cvmx-error.c | 144 | 
1 files changed, 137 insertions, 7 deletions
| diff --git a/cvmx-error.c b/cvmx-error.c index 2b77d4caef05a..47a119bae0e36 100644 --- a/cvmx-error.c +++ b/cvmx-error.c @@ -1,5 +1,5 @@  /***********************license start*************** - * Copyright (c) 2003-2010  Cavium Networks (support@cavium.com). All rights + * Copyright (c) 2003-2010  Cavium Inc. (support@cavium.com). All rights   * reserved.   *   * @@ -15,7 +15,7 @@   *     disclaimer in the documentation and/or other materials provided   *     with the distribution. - *   * Neither the name of Cavium Networks nor the names of + *   * Neither the name of Cavium Inc. nor the names of   *     its contributors may be used to endorse or promote products   *     derived from this software without specific prior written   *     permission. @@ -26,7 +26,7 @@   * countries.   * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" - * AND WITH ALL FAULTS AND CAVIUM  NETWORKS MAKES NO PROMISES, REPRESENTATIONS OR + * AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR   * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO   * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR   * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM @@ -51,6 +51,9 @@  #include <asm/octeon/cvmx-error-custom.h>  #include <asm/octeon/cvmx-pcie.h>  #include <asm/octeon/cvmx-srio.h> +#include <asm/octeon/cvmx-ciu2-defs.h> +#include <asm/octeon/cvmx-dfm-defs.h> +#include <asm/octeon/cvmx-lmcx-defs.h>  #include <asm/octeon/cvmx-pexp-defs.h>  #else  #include "cvmx.h" @@ -207,6 +210,17 @@ int __cvmx_error_display(const cvmx_error_info_t *info)      /* This assumes that all bits in the status register are RO or R/W1C */      __cvmx_error_write_hw(info->reg_type, info->status_addr, info->status_mask);      cvmx_safe_printf("%s", message); + +    /* Clear the source to reduce the chance for spurious interrupts.  */ +                                                                                 +    /* CN68XX has an CIU-15786 errata that accessing the ACK registers +     * can stop interrupts from propagating +     */ +    if (OCTEON_IS_MODEL(OCTEON_CN68XX)) +        cvmx_read_csr(CVMX_CIU2_INTR_CIU_READY); +    else if (OCTEON_IS_MODEL(OCTEON_CN68XX)) +        cvmx_read_csr(CVMX_CIU2_ACK_PPX_IP4(cvmx_get_core_num())); +      return 1;  } @@ -223,7 +237,31 @@ int __cvmx_error_display(const cvmx_error_info_t *info)  int cvmx_error_initialize(cvmx_error_flags_t flags)  {      __cvmx_error_flags = flags; -    if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS2_X)) +    if (OCTEON_IS_MODEL(OCTEON_CNF71XX)) +    { +        extern int cvmx_error_initialize_cnf71xx(void); +        if (cvmx_error_initialize_cnf71xx()) +            return -1; +    } +    else if (OCTEON_IS_MODEL(OCTEON_CN68XX)) +    { +        extern int cvmx_error_initialize_cn68xx(void); +        if (cvmx_error_initialize_cn68xx()) +            return -1; +    } +    else if (OCTEON_IS_MODEL(OCTEON_CN68XX_PASS1_X)) +    { +        extern int cvmx_error_initialize_cn68xxp1(void); +        if (cvmx_error_initialize_cn68xxp1()) +            return -1; +    } +    else if (OCTEON_IS_MODEL(OCTEON_CN66XX)) +    { +        extern int cvmx_error_initialize_cn66xx(void); +        if (cvmx_error_initialize_cn66xx()) +            return -1; +    } +    else if (OCTEON_IS_MODEL(OCTEON_CN63XX))      {          extern int cvmx_error_initialize_cn63xx(void);          if (cvmx_error_initialize_cn63xx()) @@ -235,6 +273,12 @@ int cvmx_error_initialize(cvmx_error_flags_t flags)          if (cvmx_error_initialize_cn63xxp1())              return -1;      } +    else if (OCTEON_IS_MODEL(OCTEON_CN61XX)) +    { +        extern int cvmx_error_initialize_cn61xx(void); +        if (cvmx_error_initialize_cn61xx()) +            return -1; +    }      else if (OCTEON_IS_MODEL(OCTEON_CN58XX_PASS1_X))      {          extern int cvmx_error_initialize_cn58xxp1(void); @@ -313,6 +357,11 @@ int cvmx_error_initialize(cvmx_error_flags_t flags)      /* Enable all of the purely internal error sources by default */      cvmx_error_enable_group(CVMX_ERROR_GROUP_INTERNAL, 0); +    /* According to workaround for errata KEY-14814 in cn63xx, clearing  +       SLI_INT_SUM[RML_TO] after enabling KEY interrupts */ +    if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X)) +        cvmx_write_csr(CVMX_PEXP_SLI_INT_SUM, 1); +      /* Enable DDR error reporting based on the memory controllers */      if (OCTEON_IS_MODEL(OCTEON_CN56XX))      { @@ -326,6 +375,32 @@ int cvmx_error_initialize(cvmx_error_flags_t flags)      else          cvmx_error_enable_group(CVMX_ERROR_GROUP_LMC, 0); +    /* Enable error interrupts for other LMC only if it is +       available. */ +    if (OCTEON_IS_MODEL(OCTEON_CN68XX)) +    { +        int i; +        for (i = 1; i < 4; i++) +        { +            cvmx_lmcx_dll_ctl2_t ctl2; +            ctl2.u64 = cvmx_read_csr(CVMX_LMCX_DLL_CTL2(i)); +            if (ctl2.s.intf_en) +                cvmx_error_enable_group(CVMX_ERROR_GROUP_LMC, i); +        }  +    } + +    /* Enable DFM error reporting based on feature availablility */ +    if (octeon_has_feature(OCTEON_FEATURE_DFM)) +    { +        /* Only configure interrupts if DFM clock is enabled. */ +        cvmx_dfm_fnt_sclk_t dfm_fnt_sclk; +        dfm_fnt_sclk.u64 = cvmx_read_csr(CVMX_DFM_FNT_SCLK); +        if (!dfm_fnt_sclk.s.sclkdis) +        { +            cvmx_error_enable_group(CVMX_ERROR_GROUP_DFM, 0); +        } +    } +      /* Old PCI parts don't have a common PCI init, so enable error          reporting if the bootloader told us we are a PCI host. PCIe          is handled when cvmx_pcie_rc_initialize is called */ @@ -333,9 +408,8 @@ int cvmx_error_initialize(cvmx_error_flags_t flags)          (cvmx_sysinfo_get()->bootloader_config_flags & CVMX_BOOTINFO_CFG_FLAG_PCI_HOST))          cvmx_error_enable_group(CVMX_ERROR_GROUP_PCI, 0); -    /* FIXME: Why is this needed for CN63XX? */ -    if (OCTEON_IS_MODEL(OCTEON_CN63XX)) -        cvmx_write_csr(CVMX_PEXP_SLI_INT_SUM, 1); +    /* Call poll once to clear out any pending interrupts */ +    cvmx_error_poll();      return 0;  } @@ -500,6 +574,24 @@ int cvmx_error_enable_group(cvmx_error_group_t group, int group_index)      for (i = 0; i < __cvmx_error_table_size; i++)      {          const cvmx_error_info_t *h = &__cvmx_error_table[i]; +        /* SGMII and XAUI has different ipd_port, use the same group_index +           for both the interfaces */ +        switch(group_index) +        { +            case 0x840: +                group_index = 0x800; +                break; +            case 0xa40: +                group_index = 0xa00; +                break; +            case 0xb40: +                group_index = 0xb00; +                break; +            case 0xc40: +                group_index = 0xc00; +                break; +        } +                      /* Skip entries that have a different group or group index. We              also skip entries that don't have an enable */          if ((h->group != group) || (h->group_index != group_index) || (!h->enable_addr)) @@ -543,6 +635,24 @@ int cvmx_error_disable_group(cvmx_error_group_t group, int group_index)      for (i = 0; i < __cvmx_error_table_size; i++)      {          const cvmx_error_info_t *h = &__cvmx_error_table[i]; + +        /* SGMII and XAUI has different ipd_port, use the same group_index +           for both the interfaces */ +        switch(group_index) +        { +            case 0x840: +                group_index = 0x800; +                break; +            case 0xa40: +                group_index = 0xa00; +                break; +            case 0xb40: +                group_index = 0xb00; +                break; +            case 0xc40: +                group_index = 0xc00; +                break; +        }          /* Skip entries that have a different group or group index. We              also skip entries that don't have an enable */          if ((h->group != group) || (h->group_index != group_index) || (!h->enable_addr)) @@ -640,3 +750,23 @@ int cvmx_error_disable(cvmx_error_register_t reg_type,      }  } + +/** + * Find the handler for a specific status register and mask + * + * @param status_addr + *                Status register address + * + * @return  Return the handler on success or null on failure. + */ +cvmx_error_info_t *cvmx_error_get_index(uint64_t status_addr) +{ +    int i; +    for (i = 0; i < __cvmx_error_table_size; i++) +    { +        if (__cvmx_error_table[i].status_addr == status_addr) +            return &__cvmx_error_table[i]; +    } + +    return NULL; +} | 
