aboutsummaryrefslogtreecommitdiffstats
path: root/cvmx-error.c
diff options
context:
space:
mode:
Diffstat (limited to 'cvmx-error.c')
-rw-r--r--cvmx-error.c144
1 files changed, 137 insertions, 7 deletions
diff --git a/cvmx-error.c b/cvmx-error.c
index 2b77d4caef05..47a119bae0e3 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;
+}