aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--asm/head.S58
-rw-r--r--core/affinity.c4
-rw-r--r--core/chip.c6
-rw-r--r--core/cpu.c18
-rw-r--r--core/init.c7
-rw-r--r--core/interrupts.c10
-rw-r--r--core/test/run-cpufeatures.c2
-rw-r--r--core/test/run-flash-firmware-versions.c2
-rw-r--r--doc/opal-api/opal-pci-get-hub-diag-data-50.rst55
-rwxr-xr-xexternal/xscom-utils/adu_scoms.py6
-rw-r--r--external/xscom-utils/getscom.c7
-rw-r--r--hdata/cpu-common.c16
-rw-r--r--hdata/iohub.c94
-rw-r--r--hdata/pcia.c6
-rw-r--r--hdata/spira.c114
-rw-r--r--hdata/spira.h6
-rw-r--r--hdata/test/hdata_to_dt.c13
-rw-r--r--hw/Makefile.inc3
-rw-r--r--hw/cec.c2
-rw-r--r--hw/chiptod.c3
-rw-r--r--hw/dts.c64
-rw-r--r--hw/fsp/fsp.c1
-rw-r--r--hw/gx.c158
-rw-r--r--hw/nx-842.c6
-rw-r--r--hw/nx-crypto.c16
-rw-r--r--hw/nx-rng.c6
-rw-r--r--hw/p7ioc-inits.c1096
-rw-r--r--hw/p7ioc-phb.c3242
-rw-r--r--hw/p7ioc.c688
-rw-r--r--hw/psi.c105
-rw-r--r--hw/slw.c6
-rw-r--r--hw/xscom.c10
-rw-r--r--include/chip.h24
-rw-r--r--include/gx.h53
-rw-r--r--include/interrupts.h122
-rw-r--r--include/mem-map.h5
-rw-r--r--include/nx.h44
-rw-r--r--include/opal-api.h110
-rw-r--r--include/p7ioc-regs.h444
-rw-r--r--include/p7ioc.h367
-rw-r--r--include/processor.h12
-rw-r--r--include/psi.h14
-rw-r--r--include/skiboot.h2
-rw-r--r--platforms/ibm-fsp/apollo-pci.c1
44 files changed, 42 insertions, 6986 deletions
diff --git a/asm/head.S b/asm/head.S
index bd06149..18a9c12 100644
--- a/asm/head.S
+++ b/asm/head.S
@@ -44,12 +44,6 @@
. = 0
.global __head
__head:
- /*
- * When booting a P7 machine in OPAL mode this pointer is used to
- * find the opal variant of the NACA. Unused on other machines.
- */
- .llong opal_naca
-
/* This entry point is used when booting with a flat device-tree
* pointer in r3
*/
@@ -343,10 +337,6 @@ boot_entry:
mfspr %r28,SPR_PVR
li %r26,3 /* Default to SMT4 */
srdi %r3,%r28,16
- cmpwi cr0,%r3,PVR_TYPE_P7
- beq 1f
- cmpwi cr0,%r3,PVR_TYPE_P7P
- beq 1f
cmpwi cr0,%r3,PVR_TYPE_P8
beq 2f
cmpwi cr0,%r3,PVR_TYPE_P8E
@@ -693,10 +683,6 @@ init_shared_sprs:
mfspr %r3,SPR_PVR
srdi %r3,%r3,16
- cmpwi cr0,%r3,PVR_TYPE_P7
- beq 1f
- cmpwi cr0,%r3,PVR_TYPE_P7P
- beq 2f
cmpwi cr0,%r3,PVR_TYPE_P8E
beq 3f
cmpwi cr0,%r3,PVR_TYPE_P8
@@ -710,20 +696,6 @@ init_shared_sprs:
/* Unsupported CPU type... what do we do ? */
b 9f
-1: /* P7 */
- mtspr SPR_SDR1, %r0
- /* TSCR: Value from pHyp */
- LOAD_IMM32(%r3,0x880DE880)
- mtspr SPR_TSCR, %r3
- b 9f
-
-2: /* P7+ */
- mtspr SPR_SDR1, %r0
- /* TSCR: Recommended value by HW folks */
- LOAD_IMM32(%r3,0x88CDE880)
- mtspr SPR_TSCR, %r3
- b 9f
-
3: /* P8E/P8 */
mtspr SPR_SDR1, %r0
/* TSCR: Recommended value by HW folks */
@@ -795,10 +767,6 @@ init_shared_sprs:
init_replicated_sprs:
mfspr %r3,SPR_PVR
srdi %r3,%r3,16
- cmpwi cr0,%r3,PVR_TYPE_P7
- beq 1f
- cmpwi cr0,%r3,PVR_TYPE_P7P
- beq 1f
cmpwi cr0,%r3,PVR_TYPE_P8E
beq 3f
cmpwi cr0,%r3,PVR_TYPE_P8
@@ -812,16 +780,6 @@ init_replicated_sprs:
/* Unsupported CPU type... what do we do ? */
b 9f
-1: /* P7, P7+ */
- /* LPCR: sane value */
- LOAD_IMM64(%r3,0x0040000000000004)
- mtspr SPR_LPCR, %r3
- sync
- isync
- LOAD_IMM64(%r3,0x0)
- mtspr SPR_DSCR,%r3
- b 9f
-
3: /* P8, P8E */
/* LPCR: sane value */
LOAD_IMM64(%r3,0x0040000000000000)
@@ -903,22 +861,6 @@ hv_lid_load_table:
.long 0
.long 0
-/*
- *
- * OPAL variant of NACA. This is only used when booting a P7 in OPAL mode.
- *
- */
-.global opal_naca
-opal_naca:
- .llong opal_boot_trampoline /* Primary entry (used ?) */
- .llong opal_boot_trampoline /* Secondary entry (used ?) */
- .llong spira /* Spira pointer */
- .llong 0 /* Load address */
- .llong opal_boot_trampoline /* 0x180 trampoline */
- .llong 0 /* More stuff as seen in objdump ...*/
- .llong 0
- .llong 0
- .llong 0
/* The FSP seems to ignore our primary/secondary entry
* points and instead copy that bit down to 0x180 and
diff --git a/core/affinity.c b/core/affinity.c
index 10d483d..070a1cd 100644
--- a/core/affinity.c
+++ b/core/affinity.c
@@ -120,9 +120,7 @@ void add_core_associativity(struct cpu_thread *cpu)
if (!chip)
return;
- if (proc_gen == proc_gen_p7)
- core_id = (cpu->pir >> 2) & 0x7;
- else if (proc_gen == proc_gen_p8)
+ if (proc_gen == proc_gen_p8)
core_id = (cpu->pir >> 3) & 0xf;
else if (proc_gen == proc_gen_p9)
core_id = (cpu->pir >> 2) & 0x1f;
diff --git a/core/chip.c b/core/chip.c
index b01ec5b..221cf2d 100644
--- a/core/chip.c
+++ b/core/chip.c
@@ -31,7 +31,7 @@ uint32_t pir_to_chip_id(uint32_t pir)
else if (proc_gen == proc_gen_p8)
return P8_PIR2GCID(pir);
else
- return P7_PIR2GCID(pir);
+ assert(false);
}
uint32_t pir_to_core_id(uint32_t pir)
@@ -41,7 +41,7 @@ uint32_t pir_to_core_id(uint32_t pir)
else if (proc_gen == proc_gen_p8)
return P8_PIR2COREID(pir);
else
- return P7_PIR2COREID(pir);
+ assert(false);
}
uint32_t pir_to_thread_id(uint32_t pir)
@@ -51,7 +51,7 @@ uint32_t pir_to_thread_id(uint32_t pir)
else if (proc_gen == proc_gen_p8)
return P8_PIR2THREADID(pir);
else
- return P7_PIR2THREADID(pir);
+ assert(false);
}
struct proc_chip *next_chip(struct proc_chip *chip)
diff --git a/core/cpu.c b/core/cpu.c
index 62c0201..168a49a 100644
--- a/core/cpu.c
+++ b/core/cpu.c
@@ -110,7 +110,7 @@ static void cpu_wake(struct cpu_thread *cpu)
if (!cpu->in_idle)
return;
- if (proc_gen == proc_gen_p8 || proc_gen == proc_gen_p7) {
+ if (proc_gen == proc_gen_p8) {
/* Poke IPI */
icp_kick_cpu(cpu);
} else if (proc_gen == proc_gen_p9) {
@@ -992,10 +992,6 @@ void init_boot_cpu(void)
/* Get CPU family and other flags based on PVR */
switch(PVR_TYPE(pvr)) {
- case PVR_TYPE_P7:
- case PVR_TYPE_P7P:
- proc_gen = proc_gen_p7;
- break;
case PVR_TYPE_P8E:
case PVR_TYPE_P8:
proc_gen = proc_gen_p8;
@@ -1023,11 +1019,6 @@ void init_boot_cpu(void)
/* Get a CPU thread count based on family */
switch(proc_gen) {
- case proc_gen_p7:
- cpu_thread_count = 4;
- prlog(PR_INFO, "CPU: P7 generation processor"
- " (max %d threads/core)\n", cpu_thread_count);
- break;
case proc_gen_p8:
cpu_thread_count = 8;
prlog(PR_INFO, "CPU: P8 generation processor"
@@ -1580,13 +1571,6 @@ static int64_t opal_reinit_cpus(uint64_t flags)
if (req.set_bits || req.clr_bits)
cpu_change_all_hid0(&req);
- /* If we have a P7, error out for LE switch, do nothing for BE */
- if (proc_gen < proc_gen_p8) {
- if (flags & OPAL_REINIT_CPUS_HILE_LE)
- rc = OPAL_UNSUPPORTED;
- flags &= ~(OPAL_REINIT_CPUS_HILE_BE | OPAL_REINIT_CPUS_HILE_LE);
- }
-
if (flags & OPAL_REINIT_CPUS_TM_SUSPEND_DISABLED) {
flags &= ~OPAL_REINIT_CPUS_TM_SUSPEND_DISABLED;
diff --git a/core/init.c b/core/init.c
index 2c39688..3db9df3 100644
--- a/core/init.c
+++ b/core/init.c
@@ -1103,9 +1103,9 @@ void __noreturn __nomcount main_cpu_entry(const void *fdt)
/* Allocate our split trace buffers now. Depends add_opal_node() */
init_trace_buffers();
- /* On P7/P8, get the ICPs and make sure they are in a sane state */
+ /* On P8, get the ICPs and make sure they are in a sane state */
init_interrupts();
- if (proc_gen == proc_gen_p7 || proc_gen == proc_gen_p8)
+ if (proc_gen == proc_gen_p8)
cpu_set_ipi_enable(true);
/* On P9, initialize XIVE */
@@ -1238,9 +1238,6 @@ void __noreturn __nomcount main_cpu_entry(const void *fdt)
/* Init In-Memory Collection related stuff (load the IMC dtb into memory) */
imc_init();
- /* Probe IO hubs */
- probe_p7ioc();
-
/* Probe PHB3 on P8 */
probe_phb3();
diff --git a/core/interrupts.c b/core/interrupts.c
index 5d7a68c..b053401 100644
--- a/core/interrupts.c
+++ b/core/interrupts.c
@@ -152,16 +152,6 @@ uint32_t get_psi_interrupt(uint32_t chip_id)
uint32_t irq;
switch(proc_gen) {
- case proc_gen_p7:
- /* Get the chip ID into position, it already has
- * the T bit so all we need is room for the GX
- * bit, 9 bit BUID and 4 bit level
- */
- irq = chip_id << (1 + 9 + 4);
-
- /* Add in the BUID */
- irq |= P7_PSI_IRQ_BUID << 4;
- break;
case proc_gen_p8:
irq = p8_chip_irq_block_base(chip_id, P8_IRQ_BLOCK_MISC);
irq += P8_IRQ_MISC_PSI_BASE;
diff --git a/core/test/run-cpufeatures.c b/core/test/run-cpufeatures.c
index 9db2144..c072e5f 100644
--- a/core/test/run-cpufeatures.c
+++ b/core/test/run-cpufeatures.c
@@ -44,7 +44,7 @@ static inline unsigned long mfspr(unsigned int spr);
#include "../cpufeatures.c"
-static unsigned long fake_pvr = PVR_TYPE_P7;
+static unsigned long fake_pvr = PVR_TYPE_P8;
static inline unsigned long mfspr(unsigned int spr)
{
diff --git a/core/test/run-flash-firmware-versions.c b/core/test/run-flash-firmware-versions.c
index 924f3e9..8fff714 100644
--- a/core/test/run-flash-firmware-versions.c
+++ b/core/test/run-flash-firmware-versions.c
@@ -103,7 +103,7 @@ char __rodata_start[1], __rodata_end[1];
const char version[]="Hello world!";
-enum proc_gen proc_gen = proc_gen_p7;
+enum proc_gen proc_gen = proc_gen_p8;
static char *loaded_version_buf;
static size_t loaded_version_buf_size;
diff --git a/doc/opal-api/opal-pci-get-hub-diag-data-50.rst b/doc/opal-api/opal-pci-get-hub-diag-data-50.rst
index e7b2584..7ee9806 100644
--- a/doc/opal-api/opal-pci-get-hub-diag-data-50.rst
+++ b/doc/opal-api/opal-pci-get-hub-diag-data-50.rst
@@ -7,61 +7,14 @@ OPAL_PCI_GET_HUB_DIAG_DATA
#define OPAL_PCI_GET_HUB_DIAG_DATA 50
- enum {
- OPAL_P7IOC_DIAG_TYPE_NONE = 0,
- OPAL_P7IOC_DIAG_TYPE_RGC = 1,
- OPAL_P7IOC_DIAG_TYPE_BI = 2,
- OPAL_P7IOC_DIAG_TYPE_CI = 3,
- OPAL_P7IOC_DIAG_TYPE_MISC = 4,
- OPAL_P7IOC_DIAG_TYPE_I2C = 5,
- OPAL_P7IOC_DIAG_TYPE_LAST = 6
- };
-
- struct OpalIoP7IOCErrorData {
- __be16 type;
-
- /* GEM */
- __be64 gemXfir;
- __be64 gemRfir;
- __be64 gemRirqfir;
- __be64 gemMask;
- __be64 gemRwof;
-
- /* LEM */
- __be64 lemFir;
- __be64 lemErrMask;
- __be64 lemAction0;
- __be64 lemAction1;
- __be64 lemWof;
-
- union {
- struct OpalIoP7IOCRgcErrorData {
- __be64 rgcStatus; /* 3E1C10 */
- __be64 rgcLdcp; /* 3E1C18 */
- }rgc;
- struct OpalIoP7IOCBiErrorData {
- __be64 biLdcp0; /* 3C0100, 3C0118 */
- __be64 biLdcp1; /* 3C0108, 3C0120 */
- __be64 biLdcp2; /* 3C0110, 3C0128 */
- __be64 biFenceStatus; /* 3C0130, 3C0130 */
-
- uint8_t biDownbound; /* BI Downbound or Upbound */
- }bi;
- struct OpalIoP7IOCCiErrorData {
- __be64 ciPortStatus; /* 3Dn008 */
- __be64 ciPortLdcp; /* 3Dn010 */
-
- uint8_t ciPort; /* Index of CI port: 0/1 */
- }ci;
- };
- };
-
int64_t opal_pci_get_hub_diag_data(uint64_t hub_id, void *diag_buffer, uint64_t diag_buffer_len);
-Fetch diagnostic data for an IO hub. Currently, this is only implemented for
-p7ioc, which is specific to POWER7, something that was only ever available
+Fetch diagnostic data for an IO hub. This was only implemented for hardware
+specific to POWER7 systems, something that was only ever available
internally to IBM for development purposes.
+It is currently not used.
+
If :ref:`OPAL_PCI_NEXT_ERROR` error type is `OPAL_EEH_IOC_ERROR` and severity
is `OPAL_EEH_SEV_INF`, then the OS should call :ref:`OPAL_PCI_GET_HUB_DIAG_DATA`
to retreive diagnostic data to log appropriately.
diff --git a/external/xscom-utils/adu_scoms.py b/external/xscom-utils/adu_scoms.py
index bb077db..a1b7d89 100755
--- a/external/xscom-utils/adu_scoms.py
+++ b/external/xscom-utils/adu_scoms.py
@@ -176,11 +176,7 @@ class GetSCom(object):
c_id = val >> 44
id = c_id & 0xff
- if id == 0xf9:
- name = "P7 processor"
- elif id == 0xe8:
- name = "P7+ processor"
- elif id == 0xef:
+ if id == 0xef:
name = "P8E (Murano) processor"
elif id == 0xea:
name = "P8 (Venice) processor"
diff --git a/external/xscom-utils/getscom.c b/external/xscom-utils/getscom.c
index 8c96634..dab4994 100644
--- a/external/xscom-utils/getscom.c
+++ b/external/xscom-utils/getscom.c
@@ -47,12 +47,6 @@ static void print_chip_info(uint32_t chip_id)
cfam_id = f000f >> 44;
switch(cfam_id & 0xff) {
- case 0xf9:
- name = "P7 processor";
- break;
- case 0xe8:
- name = "P7+ processor";
- break;
case 0xef:
name = "P8E (Murano) processor";
break;
@@ -79,7 +73,6 @@ static void print_chip_info(uint32_t chip_id)
printf("%08x | DD%lx.%lx | %s\n",
chip_id, (cfam_id >> 16) & 0xf, (cfam_id >> 8) & 0xf, name);
-
}
extern const char version[];
diff --git a/hdata/cpu-common.c b/hdata/cpu-common.c
index f6dda4e..0924dd5 100644
--- a/hdata/cpu-common.c
+++ b/hdata/cpu-common.c
@@ -30,12 +30,6 @@ struct dt_node * add_core_common(struct dt_node *cpus,
struct dt_node *cpu;
uint32_t version;
uint64_t freq;
- const uint8_t pa_features_p7[] = {
- 6, 0,
- 0xf6, 0x3f, 0xc7, 0x00, 0x80, 0xc0 };
- const uint8_t pa_features_p7p[] = {
- 6, 0,
- 0xf6, 0x3f, 0xc7, 0xc0, 0x80, 0xc0 };
const uint8_t pa_features_p8[] = {
24, 0,
0xf6, 0x3f, 0xc7, 0xc0, 0x80, 0xd0, 0x80, 0x00,
@@ -80,16 +74,6 @@ struct dt_node * add_core_common(struct dt_node *cpus,
*/
version = mfspr(SPR_PVR);
switch(PVR_TYPE(version)) {
- case PVR_TYPE_P7:
- name = "PowerPC,POWER7";
- pa_features = pa_features_p7;
- pa_features_size = sizeof(pa_features_p7);
- break;
- case PVR_TYPE_P7P:
- name = "PowerPC,POWER7+";
- pa_features = pa_features_p7p;
- pa_features_size = sizeof(pa_features_p7p);
- break;
case PVR_TYPE_P8E:
case PVR_TYPE_P8:
case PVR_TYPE_P8NVL:
diff --git a/hdata/iohub.c b/hdata/iohub.c
index feb8d6a..c81dc5e 100644
--- a/hdata/iohub.c
+++ b/hdata/iohub.c
@@ -22,43 +22,12 @@
#include <ccan/str/str.h>
#include <ccan/array_size/array_size.h>
#include <device.h>
-#include <p7ioc.h>
#include <vpd.h>
#include <inttypes.h>
#include <string.h>
#include "hdata.h"
-static void io_add_common(struct dt_node *hn, const struct cechub_io_hub *hub)
-{
- dt_add_property_cells(hn, "#address-cells", 2);
- dt_add_property_cells(hn, "#size-cells", 2);
- dt_add_property_cells(hn, "ibm,buid-ext", be32_to_cpu(hub->buid_ext));
- dt_add_property_cells(hn, "ibm,chip-id",
- pcid_to_chip_id(be32_to_cpu(hub->proc_chip_id)));
- dt_add_property_cells(hn, "ibm,gx-index", be32_to_cpu(hub->gx_index));
- dt_add_property_cells(hn, "revision", be32_to_cpu(hub->ec_level));
-
- /* Instead of exposing the GX BARs as separate ranges as we *should*
- * do in an ideal world, we just create a pass-through ranges and
- * we use separate properties for the BARs.
- *
- * This is hackish but will do for now and avoids us having to
- * do too complex ranges property parsing
- */
- dt_add_property(hn, "ranges", NULL, 0);
- dt_add_property_u64(hn, "ibm,gx-bar-1", be64_to_cpu(hub->gx_ctrl_bar1));
- dt_add_property_u64(hn, "ibm,gx-bar-2", be64_to_cpu(hub->gx_ctrl_bar2));
-
- /* Add presence detect if valid */
- if (hub->flags & CECHUB_HUB_FLAG_FAB_BR0_PDT)
- dt_add_property_cells(hn, "ibm,br0-presence-detect",
- hub->fab_br0_pdt);
- if (hub->flags & CECHUB_HUB_FLAG_FAB_BR1_PDT)
- dt_add_property_cells(hn, "ibm,br1-presence-detect",
- hub->fab_br1_pdt);
-}
-
static bool io_get_lx_info(const void *kwvpd, unsigned int kwvpd_sz,
int lx_idx, struct dt_node *hn)
{
@@ -131,63 +100,6 @@ static void io_get_loc_code(const void *sp_iohubs, struct dt_node *hn, const cha
}
}
-static struct dt_node *io_add_p7ioc(const struct cechub_io_hub *hub,
- const void *sp_iohubs)
-{
- struct dt_node *hn;
- uint64_t reg[2];
-
- const void *kwvpd;
- unsigned int kwvpd_sz;
-
- prlog(PR_DEBUG, " GX#%d BUID_Ext = 0x%x\n",
- be32_to_cpu(hub->gx_index),
- be32_to_cpu(hub->buid_ext));
- prlog(PR_DEBUG, " GX BAR 0 = 0x%016"PRIx64"\n",
- be64_to_cpu(hub->gx_ctrl_bar0));
- prlog(PR_DEBUG, " GX BAR 1 = 0x%016"PRIx64"\n",
- be64_to_cpu(hub->gx_ctrl_bar1));
- prlog(PR_DEBUG, " GX BAR 2 = 0x%016"PRIx64"\n",
- be64_to_cpu(hub->gx_ctrl_bar2));
- prlog(PR_DEBUG, " GX BAR 3 = 0x%016"PRIx64"\n",
- be64_to_cpu(hub->gx_ctrl_bar3));
- prlog(PR_DEBUG, " GX BAR 4 = 0x%016"PRIx64"\n",
- be64_to_cpu(hub->gx_ctrl_bar4));
-
- /* We only know about memory map 1 */
- if (be32_to_cpu(hub->mem_map_vers) != 1) {
- prerror("P7IOC: Unknown memory map %d\n", be32_to_cpu(hub->mem_map_vers));
- /* We try to continue anyway ... */
- }
-
- reg[0] = cleanup_addr(be64_to_cpu(hub->gx_ctrl_bar1));
- reg[1] = 0x2000000;
-
- hn = dt_new_addr(dt_root, "io-hub", reg[0]);
- if (!hn)
- return NULL;
-
- dt_add_property(hn, "reg", reg, sizeof(reg));
- dt_add_property_strings(hn, "compatible", "ibm,p7ioc", "ibm,ioda-hub");
-
- kwvpd = HDIF_get_idata(sp_iohubs, CECHUB_ASCII_KEYWORD_VPD, &kwvpd_sz);
- if (kwvpd && kwvpd != sp_iohubs) {
- /*
- * XX We don't know how to properly find the LXRn
- * record so for now we'll just try LXR0 and if not
- * found, we try LXR1
- */
- if (!io_get_lx_info(kwvpd, kwvpd_sz, 0, hn))
- io_get_lx_info(kwvpd, kwvpd_sz, 1, hn);
- } else {
- prlog(PR_DEBUG, "CEC: P7IOC Keywords not found.\n");
- }
-
- io_get_loc_code(sp_iohubs, hn, "ibm,io-base-loc-code");
-
- return hn;
-}
-
static struct dt_node *io_add_phb3(const struct cechub_io_hub *hub,
const struct HDIF_common_hdr *sp_iohubs,
unsigned int index, struct dt_node *xcom,
@@ -856,7 +768,6 @@ static void io_parse_fru(const void *sp_iohubs)
for (i = 0; i < count; i++) {
const struct cechub_io_hub *hub;
unsigned int size, hub_id;
- struct dt_node *hn;
uint32_t chip_id;
hub = HDIF_get_iarray_item(sp_iohubs, CECHUB_FRU_IO_HUBS,
@@ -892,11 +803,6 @@ static void io_parse_fru(const void *sp_iohubs)
be32_to_cpu(hub->ec_level), be16_to_cpu(hub->hub_num));
switch(hub_id) {
- case CECHUB_HUB_P7IOC:
- prlog(PR_INFO, "CEC: P7IOC !\n");
- hn = io_add_p7ioc(hub, sp_iohubs);
- io_add_common(hn, hub);
- break;
case CECHUB_HUB_MURANO:
case CECHUB_HUB_MURANO_SEGU:
prlog(PR_INFO, "CEC: Murano !\n");
diff --git a/hdata/pcia.c b/hdata/pcia.c
index 9b210e4..0638327 100644
--- a/hdata/pcia.c
+++ b/hdata/pcia.c
@@ -158,9 +158,7 @@ static struct dt_node *add_core_node(struct dt_node *cpus,
be32_to_cpu(t->pir), okay);
dt_add_property_cells(cpu, "l2-cache", l2_phandle);
- if (proc_gen == proc_gen_p7)
- icp_compat = "IBM,power7-icp";
- else
+ if (proc_gen == proc_gen_p8)
icp_compat = "IBM,power8-icp";
/* Get HW Chip ID */
@@ -182,7 +180,7 @@ static struct dt_node *add_core_node(struct dt_node *cpus,
dt_add_property(cpu, "ibm,ppc-interrupt-server#s", iserv, 4 * threads);
- /* Add the ICP node for this CPU for P7 / P8 */
+ /* Add the ICP node for this CPU for P8 */
if (proc_gen <= proc_gen_p8)
add_xics_icp(pcia, threads, icp_compat);
diff --git a/hdata/spira.c b/hdata/spira.c
index 43c76f9..6891a9c 100644
--- a/hdata/spira.c
+++ b/hdata/spira.c
@@ -255,9 +255,8 @@ static struct dt_node *add_xscom_node(uint64_t base, uint32_t hw_id,
uint64_t freq;
switch (proc_gen) {
- case proc_gen_p7:
case proc_gen_p8:
- /* On P7 and P8 all the chip SCOMs share single region */
+ /* On P8 all the chip SCOMs share single region */
addr = base | ((uint64_t)hw_id << PPC_BITLSHIFT(28));
break;
case proc_gen_p9:
@@ -285,10 +284,6 @@ static struct dt_node *add_xscom_node(uint64_t base, uint32_t hw_id,
dt_add_property(node, "scom-controller", NULL, 0);
switch(proc_gen) {
- case proc_gen_p7:
- dt_add_property_strings(node, "compatible",
- "ibm,xscom", "ibm,power7-xscom");
- break;
case proc_gen_p8:
dt_add_property_strings(node, "compatible",
"ibm,xscom", "ibm,power8-xscom");
@@ -375,11 +370,6 @@ static void add_psihb_node(struct dt_node *np)
/* PSI host bridge */
switch(proc_gen) {
- case proc_gen_p7:
- psi_scom = 0x2010c00;
- psi_slen = 0x10;
- psi_comp = "ibm,power7-psihb-x";
- break;
case proc_gen_p8:
psi_scom = 0x2010900;
psi_slen = 0x20;
@@ -635,72 +625,6 @@ static bool add_xscom_sppcrd(uint64_t xscom_base)
return i > 0;
}
-static void add_xscom_sppaca(uint64_t xscom_base)
-{
- const struct HDIF_common_hdr *hdif;
- unsigned int i;
- struct dt_node *np, *vpd_node;
-
- for_each_ntuple_idx(&spira.ntuples.paca, hdif, i, PACA_HDIF_SIG) {
- const struct sppaca_cpu_id *id;
- unsigned int chip_id, size;
- int ve;
-
- /* We only suport old style PACA on P7 ! */
- assert(proc_gen == proc_gen_p7);
-
- id = HDIF_get_idata(hdif, SPPACA_IDATA_CPU_ID, &size);
-
- if (!CHECK_SPPTR(id)) {
- prerror("XSCOM: Bad processor data %d\n", i);
- continue;
- }
-
- ve = be32_to_cpu(id->verify_exists_flags) & CPU_ID_VERIFY_MASK;
- ve >>= CPU_ID_VERIFY_SHIFT;
- if (ve == CPU_ID_VERIFY_NOT_INSTALLED ||
- ve == CPU_ID_VERIFY_UNUSABLE)
- continue;
-
- /* Convert to HW chip ID */
- chip_id = P7_PIR2GCID(be32_to_cpu(id->pir));
-
- /* do we already have an XSCOM for this chip? */
- if (find_xscom_for_chip(chip_id))
- continue;
-
- /* Create the XSCOM node */
- np = add_xscom_node(xscom_base, chip_id,
- be32_to_cpu(id->processor_chip_id));
- if (!np)
- continue;
-
- /* Add chip VPD */
- vpd_node = dt_add_vpd_node(hdif, SPPACA_IDATA_FRU_ID,
- SPPACA_IDATA_KW_VPD);
- if (vpd_node)
- dt_add_property_cells(vpd_node, "ibm,chip-id", chip_id);
-
- /* Add chip associativity data */
- dt_add_property_cells(np, "ibm,ccm-node-id",
- be32_to_cpu(id->ccm_node_id));
- if (size > SPIRA_CPU_ID_MIN_SIZE) {
- dt_add_property_cells(np, "ibm,hw-card-id",
- be32_to_cpu(id->hw_card_id));
- dt_add_property_cells(np, "ibm,hw-module-id",
- be32_to_cpu(id->hardware_module_id));
- if (!dt_find_property(np, "ibm,dbob-id"))
- dt_add_property_cells(np, "ibm,dbob-id",
- be32_to_cpu(id->drawer_book_octant_blade_id));
- dt_add_property_cells(np, "ibm,mem-interleave-scope",
- be32_to_cpu(id->memory_interleaving_scope));
- }
-
- /* Add PSI Host bridge */
- add_psihb_node(np);
- }
-}
-
static void add_xscom(void)
{
const void *ms_vpd;
@@ -727,23 +651,12 @@ static void add_xscom(void)
xscom_base = be64_to_cpu(pmbs->xscom_addr);
- /* Some FSP (on P7) give me a crap base address for XSCOM (it has
- * spurious bits set as far as I can tell). Since only 5 bits 18:22 can
- * be programmed in hardware, let's isolate these. This seems to give
- * me the right value on VPL1
- */
- if (cpu_type == PVR_TYPE_P7)
- xscom_base &= 0x80003e0000000000ul;
-
/* Get rid of the top bits */
xscom_base = cleanup_addr(xscom_base);
/* First, try the new proc_chip ntuples for chip data */
if (add_xscom_sppcrd(xscom_base))
return;
-
- /* Otherwise, check the old-style PACA, looking for unique chips */
- add_xscom_sppaca(xscom_base);
}
static void add_chiptod_node(unsigned int chip_id, int flags)
@@ -766,9 +679,6 @@ static void add_chiptod_node(unsigned int chip_id, int flags)
len = 0x34;
switch(proc_gen) {
- case proc_gen_p7:
- compat_str = "ibm,power7-chiptod";
- break;
case proc_gen_p8:
compat_str = "ibm,power8-chiptod";
break;
@@ -908,10 +818,6 @@ static void add_nx_node(u32 gcid)
return;
switch (proc_gen) {
- case proc_gen_p7:
- dt_add_property_strings(nx, "compatible", "ibm,power-nx",
- "ibm,power7-nx");
- break;
case proc_gen_p8:
dt_add_property_strings(nx, "compatible", "ibm,power-nx",
"ibm,power8-nx");
@@ -1314,24 +1220,6 @@ uint32_t pcid_to_chip_id(uint32_t proc_chip_id)
return be32_to_cpu(cinfo->xscom_id);
}
- /* Otherwise, check the old-style PACA, looking for unique chips */
- for_each_ntuple_idx(&spira.ntuples.paca, hdif, i, PACA_HDIF_SIG) {
- const struct sppaca_cpu_id *id;
-
- /* We only suport old style PACA on P7 ! */
- assert(proc_gen == proc_gen_p7);
-
- id = HDIF_get_idata(hdif, SPPACA_IDATA_CPU_ID, NULL);
-
- if (!CHECK_SPPTR(id)) {
- prerror("XSCOM: Bad processor data %d\n", i);
- continue;
- }
-
- if (proc_chip_id == be32_to_cpu(id->processor_chip_id))
- return P7_PIR2GCID(be32_to_cpu(id->pir));
- }
-
/* Not found, what to do ? Assert ? For now return a number
* guaranteed to not exist
*/
diff --git a/hdata/spira.h b/hdata/spira.h
index 41159d2..09de4da 100644
--- a/hdata/spira.h
+++ b/hdata/spira.h
@@ -518,11 +518,6 @@ struct msvpd_pmover_bsr_synchro {
#define MSVPD_PMS_FLAG_PMOVER_EN 0x40000000
#define MSVPD_PMS_FLAG_BSR_EN 0x20000000
#define MSVPD_PMS_FLAG_XSCOMBASE_VALID 0x10000000
- /* P7 values for BSR mode */
-#define MSVPD_PMS_FLAG_P7BSR_1M_MODE 0x00000000
-#define MSVPD_PMS_FLAG_P7BSR_2M_MODE 0x02000000
-#define MSVPD_PMS_FLAG_P7BSR_4M_MODE 0x04000000
-#define MSVPD_PMS_FLAG_P7BSR_8M_MODE 0x06000000
__be32 hwlocks_per_page;
__be64 hwlock_addr;
__be64 pmover_addr;
@@ -655,7 +650,6 @@ struct cechub_io_hub {
#define CECHUB_HUB_FAB_BR1_PDT_PHB4 0x08 /* p7ioc only */
#define CECHUB_HUB_FAB_BR1_PDT_PHB5 0x04 /* p7ioc only */
__be16 iohub_id; /* the type of hub */
-#define CECHUB_HUB_P7IOC 0x60e7 /* from VPL3 */
#define CECHUB_HUB_MURANO 0x20ef /* Murano from spec */
#define CECHUB_HUB_MURANO_SEGU 0x0001 /* Murano+Seguso from spec */
#define CECHUB_HUB_VENICE_WYATT 0x0010 /* Venice+Wyatt from spec */
diff --git a/hdata/test/hdata_to_dt.c b/hdata/test/hdata_to_dt.c
index 5d30600..8692177 100644
--- a/hdata/test/hdata_to_dt.c
+++ b/hdata/test/hdata_to_dt.c
@@ -63,15 +63,11 @@ unsigned long tb_hz = 512000000;
#define PVR_VERS_MIN(_pvr) GETFIELD(SPR_PVR_VERS_MIN, _pvr)
/* PVR definitions - copied from skiboot include/processor.h */
-#define PVR_TYPE_P7 0x003f
-#define PVR_TYPE_P7P 0x004a
#define PVR_TYPE_P8E 0x004b
#define PVR_TYPE_P8 0x004d
#define PVR_TYPE_P8NVL 0x004c
#define PVR_TYPE_P9 0x004e
#define PVR_TYPE_P9P 0x004f
-#define PVR_P7 0x003f0201
-#define PVR_P7P 0x004a0201
#define PVR_P8E 0x004b0201
#define PVR_P8 0x004d0200
#define PVR_P8NVL 0x004c0100
@@ -103,7 +99,7 @@ static inline struct cpu_job *cpu_queue_job(struct cpu_thread *cpu,
}
struct cpu_thread __boot_cpu, *boot_cpu = &__boot_cpu;
-static unsigned long fake_pvr = PVR_P7;
+static unsigned long fake_pvr = PVR_P8;
static inline unsigned long mfspr(unsigned int spr)
{
@@ -186,7 +182,7 @@ void op_display(enum op_severity s, enum op_module m, uint16_t code)
char __rodata_start[1], __rodata_end[1];
-enum proc_gen proc_gen = proc_gen_p7;
+enum proc_gen proc_gen = proc_gen_p8;
static bool spira_check_ptr(const void *ptr, const char *file, unsigned int line)
{
@@ -316,10 +312,6 @@ int main(int argc, char *argv[])
} else if (strcmp(argv[i], "-b") == 0) {
blobs = true;
opt_count++;
- } else if (strcmp(argv[i], "-7") == 0) {
- fake_pvr = PVR_P7;
- proc_gen = proc_gen_p7;
- opt_count++;
} else if (strcmp(argv[i], "-8E") == 0) {
fake_pvr = PVR_P8;
proc_gen = proc_gen_p8;
@@ -352,7 +344,6 @@ int main(int argc, char *argv[])
" -q Quiet mode\n"
" -b Keep blobs in the output\n"
"\n"
- " -7 Force PVR to POWER7\n"
" -8 Force PVR to POWER8\n"
" -8E Force PVR to POWER8E\n"
" -9 Force PVR to POWER9 (nimbus)\n"
diff --git a/hw/Makefile.inc b/hw/Makefile.inc
index 2885b50..e90f5cd 100644
--- a/hw/Makefile.inc
+++ b/hw/Makefile.inc
@@ -1,9 +1,8 @@
# -*-Makefile-*-
SUBDIRS += hw
-HW_OBJS = xscom.o chiptod.o gx.o cec.o lpc.o lpc-uart.o psi.o
+HW_OBJS = xscom.o chiptod.o cec.o lpc.o lpc-uart.o psi.o
HW_OBJS += homer.o slw.o occ.o fsi-master.o centaur.o imc.o
HW_OBJS += nx.o nx-rng.o nx-crypto.o nx-compress.o nx-842.o nx-gzip.o
-HW_OBJS += p7ioc.o p7ioc-inits.o p7ioc-phb.o
HW_OBJS += phb3.o sfc-ctrl.o fake-rtc.o bt.o p8-i2c.o prd.o
HW_OBJS += dts.o lpc-rtc.o npu.o npu-hw-procedures.o xive.o phb4.o
HW_OBJS += fake-nvram.o lpc-mbox.o npu2.o npu2-hw-procedures.o
diff --git a/hw/cec.c b/hw/cec.c
index 5f1e658..20706d1 100644
--- a/hw/cec.c
+++ b/hw/cec.c
@@ -16,9 +16,9 @@
#include <skiboot.h>
#include <cec.h>
-#include <p7ioc.h>
#include <interrupts.h>
#include <opal-api.h>
+#include <opal-internal.h>
/*
* Note: This file os only used on P7/P7+
diff --git a/hw/chiptod.c b/hw/chiptod.c
index 668789e..a2eaf02 100644
--- a/hw/chiptod.c
+++ b/hw/chiptod.c
@@ -132,7 +132,6 @@
static enum chiptod_type {
chiptod_unknown,
- chiptod_p7,
chiptod_p8,
chiptod_p9
} chiptod_type;
@@ -1647,8 +1646,6 @@ static bool chiptod_probe(void)
if (dt_has_node_property(np, "primary", NULL)) {
chiptod_primary = chip;
- if (dt_node_is_compatible(np, "ibm,power7-chiptod"))
- chiptod_type = chiptod_p7;
if (dt_node_is_compatible(np, "ibm,power8-chiptod"))
chiptod_type = chiptod_p8;
if (dt_node_is_compatible(np, "ibm,power9-chiptod"))
diff --git a/hw/dts.c b/hw/dts.c
index dffdfcb..e57bd33 100644
--- a/hw/dts.c
+++ b/hw/dts.c
@@ -38,67 +38,6 @@ enum {
SENSOR_DTS_ATTR_TEMP_TRIP
};
-/* Different sensor locations */
-#define P7_CT_ZONE_LSU 0
-#define P7_CT_ZONE_ISU 1
-#define P7_CT_ZONE_IFU 2
-#define P7_CT_ZONE_VFU 3
-#define P7_CT_ZONE_L3C 4
-#define P7_CT_ZONES 5
-
-/* Per core Digital Thermal Sensors */
-#define EX_THERM_P7_DTS_RESULT0 0x8050000
-#define EX_THERM_P7_DTS_RESULT1 0x8050001
-
-/*
- * DTS2 Thermal Sensor Results
- *
- * 0..7 sensor with id 0.
- * 8..15 sensor with id 1. (Only chiplets)
- * 16..23 sensor with id 2. (Only chiplets)
- * 24..31 sensor with id 3. (Only chiplets)
- * 32..39 sensor with id 4. (Only chiplets)
- * 40..56 reserved0
- * 57 Trip warning history
- * 58 Trip critical history
- * 59 Trip fatal history
- * 60 reserved1
- * 61..63 ID of worst case DTS2 (Only valid in EX core chiplets)
- */
-static int dts_read_core_temp_p7(uint32_t pir, struct dts *dts)
-{
- int32_t chip_id = pir_to_chip_id(pir);
- int32_t core = pir_to_core_id(pir);
- uint64_t dts0;
- struct dts temps[P7_CT_ZONES];
- int i;
- int rc;
-
- rc = xscom_read(chip_id,
- XSCOM_ADDR_P8_EX(core, EX_THERM_P7_DTS_RESULT0),
- &dts0);
- if (rc)
- return rc;
-
- temps[P7_CT_ZONE_LSU].temp = (dts0 >> 56) & 0xff;
- temps[P7_CT_ZONE_ISU].temp = (dts0 >> 48) & 0xff;
- temps[P7_CT_ZONE_IFU].temp = (dts0 >> 40) & 0xff;
- temps[P7_CT_ZONE_VFU].temp = (dts0 >> 32) & 0xff;
- temps[P7_CT_ZONE_L3C].temp = (dts0 >> 24) & 0xff;
-
- /* keep the max DTS */
- for (i = 0; i < P7_CT_ZONES; i++) {
- int16_t t = temps[i].temp;
- if (t > dts->temp)
- dts->temp = t;
- }
- dts->trip = (dts0 >> 3) & 0xf;
-
- prlog(PR_TRACE, "DTS: Chip %x Core %x temp:%dC trip:%x\n",
- chip_id, core, dts->temp, dts->trip);
-
- return 0;
-}
/* Therm mac result masking for DTS (result(0:15)
* 0:3 - 0x0
@@ -271,9 +210,6 @@ static int dts_read_core_temp(u32 pir, struct dts *dts, u8 attr,
int rc;
switch (proc_gen) {
- case proc_gen_p7:
- rc = dts_read_core_temp_p7(pir, dts);
- break;
case proc_gen_p8:
rc = dts_read_core_temp_p8(pir, dts);
break;
diff --git a/hw/fsp/fsp.c b/hw/fsp/fsp.c
index 8fe2aed..aa393c7 100644
--- a/hw/fsp/fsp.c
+++ b/hw/fsp/fsp.c
@@ -29,7 +29,6 @@
#include <fsp.h>
#include <lock.h>
#include <interrupts.h>
-#include <gx.h>
#include <device.h>
#include <trace.h>
#include <timebase.h>
diff --git a/hw/gx.c b/hw/gx.c
deleted file mode 100644
index 12cea5b..0000000
--- a/hw/gx.c
+++ /dev/null
@@ -1,158 +0,0 @@
-/* Copyright 2013-2014 IBM Corp.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- * implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <skiboot.h>
-#include <gx.h>
-#include <xscom.h>
-
-/*
- * Note: This file os only used on P7/P7+
- */
-
-/* Configuration of the PSI BUID, see the explanation in
- * interrupts.h
- */
-static int gx_p7_configure_psi_buid(uint32_t chip, uint32_t buid)
-{
- uint64_t mode1;
- int rc;
-
- rc = xscom_read(chip, GX_P7_MODE1_REG, &mode1);
- if (rc) {
- prerror("GX: XSCOM error %d reading GX MODE1 REG\n", rc);
- return rc;
- }
-
- mode1 = SETFIELD(GX_P7_MODE1_PSI_BUID, mode1, buid);
- mode1 &= ~GX_P7_MODE1_PSI_BUID_DISABLE;
-
- printf("GX: MODE1_REG set to 0x%llx\n", mode1);
- rc = xscom_write(chip, GX_P7_MODE1_REG, mode1);
- if (rc) {
- prerror("GX: XSCOM error %d writing GX MODE1 REG\n", rc);
- return rc;
- }
-
- return 0;
-}
-
-static int gx_p7p_configure_psi_buid(uint32_t chip, uint32_t buid)
-{
- uint64_t mode4;
- int rc;
-
- rc = xscom_read(chip, GX_P7P_MODE4_REG, &mode4);
- if (rc) {
- prerror("GX: XSCOM error %d reading GX MODE1 REG\n", rc);
- return rc;
- }
-
- mode4 = SETFIELD(GX_P7P_MODE4_PSI_BUID, mode4, buid);
- mode4 &= ~GX_P7P_MODE4_PSI_BUID_DISABLE;
-
- rc = xscom_write(chip, GX_P7P_MODE4_REG, mode4);
- if (rc) {
- prerror("GX: XSCOM error %d writing GX MODE1 REG\n", rc);
- return rc;
- }
-
- return 0;
-}
-
-/* Configure the BUID of the PSI interrupt in the GX
- * controller.
- *
- * @chip: Chip number (0..31)
- * @buid: 9-bit BUID value
- */
-int gx_configure_psi_buid(uint32_t chip, uint32_t buid)
-{
- uint32_t pvr = mfspr(SPR_PVR);
-
- printf("GX: PSI BUID for PVR %x (type %x) chip %d BUID 0x%x\n",
- pvr, PVR_TYPE(pvr), chip, buid);
-
- switch (PVR_TYPE(pvr)) {
- case PVR_TYPE_P7:
- return gx_p7_configure_psi_buid(chip, buid);
- case PVR_TYPE_P7P:
- return gx_p7p_configure_psi_buid(chip, buid);
- }
- return -1;
-}
-
-
-static int gx_p7_configure_tce_bar(uint32_t chip, uint32_t gx, uint64_t addr,
- uint64_t size)
-{
- uint32_t areg, mreg;
- int rc;
-
- switch (gx) {
- case 0:
- areg = GX_P7_GX0_TCE_BAR;
- mreg = GX_P7_GX0_TCE_MASK;
- break;
- case 1:
- areg = GX_P7_GX1_TCE_BAR;
- mreg = GX_P7_GX1_TCE_MASK;
- break;
- default:
- return -EINVAL;
- }
-
- if (addr) {
- uint64_t taddr, tmask;
-
- /* The address field contains bits 18 to 43 of the address */
- taddr = SETFIELD(GX_P7_TCE_BAR_ADDR, 0ul,
- (addr >> GX_P7_TCE_BAR_ADDR_SHIFT));
- taddr |= GX_P7_TCE_BAR_ENABLE;
- tmask = SETFIELD(GX_P7_TCE_MASK, 0ul,
- ~((size - 1) >> GX_P7_TCE_BAR_ADDR_SHIFT));
- rc = xscom_write(chip, areg, 0);
- rc |= xscom_write(chip, mreg, tmask);
- rc |= xscom_write(chip, areg, taddr);
- } else {
- rc = xscom_write(chip, areg, 0);
- }
- return rc ? -EIO : 0;
-}
-
-/* Configure the TCE BAR of a given GX bus
- *
- * @chip: Chip number (0..31)
- * @gx : GX bus index
- * @addr: base address of TCE table
- * @size: size of TCE table
- */
-int gx_configure_tce_bar(uint32_t chip, uint32_t gx, uint64_t addr,
- uint64_t size)
-{
- uint32_t pvr = mfspr(SPR_PVR);
-
- printf("GX: TCE BAR for PVR %x (type %x) chip %d gx %d\n",
- pvr, PVR_TYPE(pvr), chip, gx);
-
- /* We only support P7... is there a P7+ with P5IOC2 ? */
- switch (PVR_TYPE(pvr)) {
- case PVR_TYPE_P7:
- return gx_p7_configure_tce_bar(chip, gx, addr, size);
- }
- return -EINVAL;
-}
-
-
diff --git a/hw/nx-842.c b/hw/nx-842.c
index 8009f03..d4abe08 100644
--- a/hw/nx-842.c
+++ b/hw/nx-842.c
@@ -191,11 +191,7 @@ void nx_enable_842(struct dt_node *node, u32 gcid, u32 pb_base)
u64 cfg_dma, cfg_842, cfg_ee;
int rc;
- if (dt_node_is_compatible(node, "ibm,power7-nx")) {
- cfg_dma = pb_base + NX_P7_DMA_CFG;
- cfg_842 = pb_base + NX_P7_842_CFG;
- cfg_ee = pb_base + NX_P7_EE_CFG;
- } else if (dt_node_is_compatible(node, "ibm,power8-nx")) {
+ if (dt_node_is_compatible(node, "ibm,power8-nx")) {
cfg_dma = pb_base + NX_P8_DMA_CFG;
cfg_842 = pb_base + NX_P8_842_CFG;
cfg_ee = pb_base + NX_P8_EE_CFG;
diff --git a/hw/nx-crypto.c b/hw/nx-crypto.c
index 769112f..04cc789 100644
--- a/hw/nx-crypto.c
+++ b/hw/nx-crypto.c
@@ -38,10 +38,10 @@
#define AMF_COMPLETION_MODE NX_DMA_COMPLETION_MODE_PDMA
#define AMF_CPB_WR (0) /* CPB WR not done with AMF */
#define AMF_OUTPUT_DATA_WR NX_DMA_OUTPUT_DATA_WR_DMA
-#define EE_CH7 (0) /* disable engine AMF 2(P7) / 3(P8) */
-#define EE_CH6 (0) /* disable engine AMF 1(P7) / 2(P8) */
-#define EE_CH5 (0) /* disable engine AMF 0(P7) / 1(P8) */
-#define EE_CH4 (0) /* disable engine SYM 2(P7) / AMF 0(P8) */
+#define EE_CH7 (0) /* disable engine AMF 3(P8) */
+#define EE_CH6 (0) /* disable engine AMF 2(P8) */
+#define EE_CH5 (0) /* disable engine AMF 1(P8) */
+#define EE_CH4 (0) /* disable engine SYM AMF 0(P8) */
#define EE_CH3 (0) /* disable engine SYM 1 */
#define EE_CH2 (0) /* disable engine SYM 0 */
@@ -268,13 +268,7 @@ void nx_create_crypto_node(struct dt_node *node)
prlog(PR_INFO, "NX%d: Crypto at 0x%x\n", gcid, pb_base);
- if (dt_node_is_compatible(node, "ibm,power7-nx")) {
- cfg_dma = pb_base + NX_P7_DMA_CFG;
- cfg_sym = pb_base + NX_P7_SYM_CFG;
- cfg_asym = pb_base + NX_P7_ASYM_CFG;
- cfg_iq = pb_base + NX_P7_CRB_IQ;
- cfg_ee = pb_base + NX_P7_EE_CFG;
- } else if (dt_node_is_compatible(node, "ibm,power8-nx")) {
+ if (dt_node_is_compatible(node, "ibm,power8-nx")) {
cfg_dma = pb_base + NX_P8_DMA_CFG;
cfg_sym = pb_base + NX_P8_SYM_CFG;
cfg_asym = pb_base + NX_P8_ASYM_CFG;
diff --git a/hw/nx-rng.c b/hw/nx-rng.c
index c0c90f5..d2fc7a3 100644
--- a/hw/nx-rng.c
+++ b/hw/nx-rng.c
@@ -58,11 +58,7 @@ void nx_create_rng_node(struct dt_node *node)
gcid = dt_get_chip_id(node);
pb_base = dt_get_address(node, 0, NULL);
- if (dt_node_is_compatible(node, "ibm,power7-nx")) {
- xbar = pb_base + NX_P7_RNG_BAR;
- xcfg = pb_base + NX_P7_RNG_CFG;
- addr_mask = NX_P7_RNG_BAR_ADDR;
- } else if (dt_node_is_compatible(node, "ibm,power8-nx")) {
+ if (dt_node_is_compatible(node, "ibm,power8-nx")) {
xbar = pb_base + NX_P8_RNG_BAR;
xcfg = pb_base + NX_P8_RNG_CFG;
addr_mask = NX_P8_RNG_BAR_ADDR;
diff --git a/hw/p7ioc-inits.c b/hw/p7ioc-inits.c
deleted file mode 100644
index 0d50694..0000000
--- a/hw/p7ioc-inits.c
+++ /dev/null
@@ -1,1096 +0,0 @@
-/* Copyright 2013-2014 IBM Corp.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- * implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * This inits are in part auto-generated from tables coming
- * from the HW guys, then hand updated
- */
-#include <skiboot.h>
-#include <p7ioc.h>
-#include <p7ioc-regs.h>
-#include <io.h>
-#include <processor.h>
-#include <timebase.h>
-
-#undef DUMP_CI_ROUTING
-#undef DUMP_REG_WRITES
-
-#ifdef DUMP_REG_WRITES
-#define REGW(offset, value) do { \
- out_be64(ioc->regs + (offset), (value)); \
- printf(" REGW: %06lx=%016lx RB: %016llx\n", \
- (unsigned long)(offset), \
- (unsigned long)(value), \
- in_be64(ioc->regs + (offset))); \
- in_be64(ioc->regs + (offset)); \
- } while(0)
-#else
-#define REGW(offset, value) do { \
- out_be64(ioc->regs + (offset), (value)); \
- in_be64(ioc->regs + (offset)); \
- } while(0)
-#endif
-#define REGR(offset) in_be64(ioc->regs + (offset))
-
-static void p7ioc_init_BI(struct p7ioc *ioc)
-{
- printf("P7IOC: Init BI...\n");
-
- /*** General settings ***/
-
- /* Init_1 and Init_2: Different between P7 and P7+ */
- if (PVR_TYPE(mfspr(SPR_PVR)) == PVR_TYPE_P7P) {
- printf("P7IOC: -> Configured for P7+\n");
-
- /* Chicken switches */
- REGW(0x3c00d8, 0x0004000000000600UL);
- /* GX config */
- REGW(0x3c00a0, 0x9F8929BE00880085UL);
- } else {
- printf("P7IOC: -> Configured for P7\n");
-
- /* P7 setting assumes "early write done" mode is
- * enabled in the GX controller. It seems to be
- * the case but maybe we want to check/set it via
- * xscom ?
- */
- /* Chicken switches */
- REGW(0x3c00d8, 0x00040000000004C0UL);
- /* GX config */
- REGW(0x3c00a0, 0x9C8929BE00880085UL);
- }
-
- /*
- * Note: While running skiboot on Firebird-L, I have
- * to print something or wait for a while. The root
- * cause wasn't identified yet.
- */
- time_wait_ms(100);
-
- /* Init_3: Upbound Credit Config */
- REGW(0x3c00c8, 0x0303060403030000UL);
- /* Init_4: Credit Init Timer */
- REGW(0x3c00e8, 0x00000000000000FFUL);
-
- /* Init_4.1: BI Ack Timing */
- REGW(0x3c00e8, 0x0000FC0000000000UL);
- /* Init_5: Ordering Override 0*/
- REGW(0x3c0200, 0x0000000000000000UL);
- /* Init_6: Ordering Override 1*/
- REGW(0x3c0208, 0x0000000000000000UL);
-
- /*** Downbound TTYPE table ***/
-
- /* Init_7: Enable sequence / speculation for CI Loads */
- REGW(0x3c00a8, 0x0000000000000004UL);
- /* Init_8: */
- REGW(0x3c00b0, 0x700800C000000000UL);
- /* Init_9: Enable sequence / speculation for CI Stores */
- REGW(0x3c00a8, 0x0000000000000005UL);
- /* Init_10: */
- REGW(0x3c00b0, 0x704820C000000000UL);
- /* Init_11: Enable speculation for EOI */
- REGW(0x3c00a8, 0x000000000000001BUL);
- /* Init_12: */
- REGW(0x3c00b0, 0x3590204000000000UL);
- /* Init_13: ENable speculation for DMA Rd Responses */
- REGW(0x3c00a8, 0x0000000000000020UL);
- /* Init_14: */
- REGW(0x3c00b0, 0x1103C4C000000000UL);
- /* Init_15: Enable sequence for DMA RWNITC */
- REGW(0x3c00a8, 0x0000000000000001UL);
- /* Init_16: */
- REGW(0x3c00b0, 0xC000000000000000UL);
- /* Init_17: Enable sequence for IOKill */
- REGW(0x3c00a8, 0x0000000000000009UL);
- /* Init_18: */
- REGW(0x3c00b0, 0x4208210000000000UL);
- /* Init_19: Enable sequence for IOKill */
- REGW(0x3c00a8, 0x000000000000000AUL);
- /* Init_20: */
- REGW(0x3c00b0, 0x4200210000000000UL);
- /* Init_21: Enable sequence for FMTC CI Store w/Kill */
- REGW(0x3c00a8, 0x0000000000000021UL);
-
- /*** Timer controls ***/
-
- /* Init_22: */
- REGW(0x3c00b0, 0x4200300000000000UL);
- /* Init_23: Dnbound timer mask */
- REGW(0x3c0190, 0x0040000000000000UL);
- /* Init_24: Upbound timer mask 0 */
- REGW(0x3c0180, 0x0010001000100010UL);
- /* Init_25: Upbound timer mask 1 */
- REGW(0x3c0188, 0x0010000000000000UL);
- /* Init_26: Credit sync check config */
- REGW(0x3c00f0, 0xC102000000000000UL);
-
- /*** Setup trace ***/
-
- /* Init_27: DBG stop trace */
- REGW(0x3c0410, 0x4000000000000000UL);
- /* Init_28: DBG control */
- REGW(0x3c0400, 0x0000000000000000UL);
- /* Init_29: DBG Mode */
- REGW(0x3c0408, 0xA0000000F0CC3300UL);
- /* Init_29a: DBG C0 (Stop on Error) */
- REGW(0x3c0418, 0xF4F00FFF00000000UL);
- /* Init_30: DBG pre-mux select */
- REGW(0x3c0478, 0x0023000000000000UL);
- /* Init_31: CA0 mode */
- REGW(0x3c04b0, 0x8000000000000000UL);
- /* Init_32: CA0 Compression 0 */
- REGW(0x3c04b8, 0x0000000000000000UL);
- /* Init_33: CA0 Compression 1 */
- REGW(0x3c04c0, 0x0000000000000000UL);
- /* Init_34: CA0 Pattern A march (cmd1 selected val) */
- REGW(0x3c0480, 0x008000007FFFFF00UL);
- /* Init_35: CA0 Trigger 0 definition (pattern A) */
- REGW(0x3c04a0, 0x8000000000000000UL);
- /* Init_36: CA1 mode */
- REGW(0x3c0530, 0x8000000000000000UL);
- /* Init_37: CA1 Compression 0 */
- REGW(0x3c0538, 0x0000000000000000UL);
- /* Init_38: CA1 Compression 1 */
- REGW(0x3c0540, 0x0000000000000000UL);
- /* Init_39: CA2 mode */
- REGW(0x3c05b0, 0x8000000000000000UL);
- /* Init_40: CA2 Compression 0 */
- REGW(0x3c05b8, 0x0000000000000000UL);
- /* Init_41: CA2 Compression 1 */
- REGW(0x3c05c0, 0x0000000000000000UL);
- /* Init_42: CA3 Mode */
- REGW(0x3c0630, 0x8000000000000000UL);
- /* Init_43: CA3 Compression 0 */
- REGW(0x3c0638, 0x0000000000000000UL);
- /* Init_44: CA3 Compression 1 */
- REGW(0x3c0640, 0x0000000000000000UL);
- /* Init_45: CA3 Pattern A match (AIB val) */
- REGW(0x3c0600, 0x80000100FFFEFF00UL);
- /* Init_46: CA3 Trigger 0 definition (pattern A) */
- REGW(0x3c0620, 0x8000000000000000UL);
- /* Init_47: DBG unfreeze trace */
- REGW(0x3c0410, 0x1000000000000000UL);
- /* Init_48: DBG start trace */
- REGW(0x3c0410, 0x8000000000000000UL);
-
- /*** AIB Port Config ***/
-
- /* Init_49: AIB Port Information */
- REGW(0x3c00d0, 0x0888888800000000UL);
- /* Init_50: Port Ordering controls */
- REGW(0x3c0200, 0x0000000000000000UL);
-
- /*** LEMs (need to match recov. tables) ***/
-
- /* Init_51: Clear upbound LEM */
- REGW(0x3c0000, 0x0000000000000000UL);
- /* Init_52: Clear upbound WOF */
- REGW(0x3c0040, 0x0000000000000000UL);
- /* Init_53: Clear Dnbound LEM */
- REGW(0x3c0050, 0x0000000000000000UL);
- /* Init_54: Clear Dnbound WOF */
- REGW(0x3c0090, 0x0000000000000000UL);
- /* Init_55: Clear Fences */
- REGW(0x3c0130, 0x0000000000000000UL);
- /* Init_56: Clear Erpt latches */
- REGW(0x3c0148, 0x0080000000000000UL);
- /* Init_57: Set Upbound LEM Action0 */
- REGW(0x3c0030, 0x0800000000800000UL);
- /* Init_58: Set Upbound LEN Action1 */
- REGW(0x3c0038, 0x0000000000000000UL);
- /* Init_59: Set Upbound LEM Mask (AND write) */
- REGW(0x3c0020, 0x0800000000000000UL);
- /* Init_60: Set Dnbound LEM Action0 */
- REGW(0x3c0080, 0x2000080CA07FFF40UL);
- /* Init_61: Set Dnbound LEM Action1 */
- REGW(0x3c0088, 0x0000000000000000UL);
- /* Init_62: Set Dnbound LEM Mask (AND write) */
- REGW(0x3c0070, 0x00000800200FFE00UL);
-
- /*** Setup Fences (need to match recov. tables) ***/
-
- /* Init_63: Set Upbound Damage Control 0 (GX Err) */
- REGW(0x3c0100, 0xF7FFFFFFFF7FFFFFUL);
- /* Init_64: Set Upbound Damage Control 1 (AIB Fence) */
- REGW(0x3c0108, 0xF7FFFFFFFF7FFFFFUL);
- /* Init_65: Set Upbound Damage Control 2 (Drop Pkt) */
- REGW(0x3c0110, 0x0010054000000000UL);
- /* Init_66: Set Dnbound Damage Control 0 (GX Err) */
- REGW(0x3c0118, 0xDFFFF7F35F8000BFUL);
- /* Init_67: Set Dnbound Damage Control 1 (AIB Fence) */
- REGW(0x3c0120, 0xDFFFF7F35F8000BFUL);
- /* Init_68: Set Dnbound Damage Control 2 (Drop Pkt) */
- REGW(0x3c0128, 0x0000000C00000000UL);
-}
-
-static void p7ioc_init_MISC_HSS(struct p7ioc *ioc)
-{
- unsigned int i, regbase;
-
- printf("P7IOC: Init HSS...\n");
-
- /* Note: These values might need to be tweaked per system and
- * per physical port depending on electrical characteristics.
- *
- * For now we stick to the defaults provided by the spec.
- */
- for (i = 0; i < P7IOC_NUM_PHBS; i++) {
- regbase = P7IOC_HSS_BASE + i * P7IOC_HSS_STRIDE;
-
- if (!p7ioc_phb_enabled(ioc, i))
- continue;
-
- /* Init_1: HSSn CTL2 */
- REGW(regbase + P7IOC_HSSn_CTL2_OFFSET, 0xFFFF6DB6DB000000UL);
- /* Init_2: HSSn CTL3 */
- REGW(regbase + P7IOC_HSSn_CTL3_OFFSET, 0x1130000320000000UL);
- /* Init_3: HSSn CTL8 */
- REGW(regbase + P7IOC_HSSn_CTL8_OFFSET, 0xDDDDDDDD00000000UL);
-
-#if 0 /* All these remain set to the values configured by the FSP */
- /* Init_4: HSSn CTL9 */
- REGW(regbase + P7IOC_HSSn_CTL9_OFFSET, 0x9999999900000000);
- /* Init_5: HSSn CTL10 */
- REGW(regbase + P7IOC_HSSn_CTL10_OFFSET, 0x8888888800000000);
- /* Init_6: HSSn CTL11 */
- REGW(regbase + P7IOC_HSSn_CTL11_OFFSET, 0x4444444400000000);
- /* Init_7: HSSn CTL12 */
- REGW(regbase + P7IOC_HSSn_CTL12_OFFSET, 0x3333333300000000);
- /* Init_8: HSSn CTL13 */
- REGW(regbase + P7IOC_HSSn_CTL13_OFFSET, 0x2222222200000000);
- /* Init_9: HSSn CTL14 */
- REGW(regbase + P7IOC_HSSn_CTL14_OFFSET, 0x1111111100000000);
- /* Init_10: HSSn CTL15 */
- REGW(regbase + P7IOC_HSSn_CTL15_OFFSET, 0x1111111100000000);
- /* Init_11: HSSn CTL16 */
- REGW(regbase + P7IOC_HSSn_CTL16_OFFSET, 0x9999999900000000);
- /* Init_12: HSSn CTL17 */
- REGW(regbase + P7IOC_HSSn_CTL17_OFFSET, 0x8888888800000000);
- /* Init_13: HSSn CTL18 */
- REGW(regbase + P7IOC_HSSn_CTL18_OFFSET, 0xDDDDDDDD00000000);
- /* Init_14: HSSn CTL19 */
- REGW(regbase + P7IOC_HSSn_CTL19_OFFSET, 0xCCCCCCCC00000000);
- /* Init_15: HSSn CTL20 */
- REGW(regbase + P7IOC_HSSn_CTL20_OFFSET, 0xBBBBBBBB00000000);
- /* Init_16: HSSn CTL21 */
- REGW(regbase + P7IOC_HSSn_CTL21_OFFSET, 0x9999999900000000);
- /* Init_17: HSSn CTL22 */
- REGW(regbase + P7IOC_HSSn_CTL22_OFFSET, 0x8888888800000000);
- /* Init_18: HSSn CTL23 */
- REGW(regbase + P7IOC_HSSn_CTL23_OFFSET, 0x7777777700000000);
-#endif
- }
-}
-
-static void p7ioc_init_RGC(struct p7ioc *ioc)
-{
- unsigned int i;
- uint64_t val, cfg;
-
- printf("P7IOC: Init RGC...\n");
-
- /*** Clear ERPT Macros ***/
-
- /* Init_1: RGC Configuration reg */
- cfg = REGR(0x3e1c08);
- REGW(0x3e1c08, cfg | PPC_BIT(1));
- time_wait_ms(1);
-
- /* Init_2: RGC Configuration reg */
- REGW(0x3e1c08, cfg);
-
- /*** Set LEM regs (needs to match recov. code) */
-
- /* Init_3: LEM FIR Accumulator */
- REGW(0x3e1e00, 0x0000000000000000UL);
- /* Init_4: LEM Action 0 */
- REGW(0x3e1e30, 0x0FFF791F0B030000UL);
- /* Init_5: LEN Action 1 */
- REGW(0x3e1e38, 0x0000000000000000UL);
- /* Init_6: LEM WOF */
- REGW(0x3e1e40, 0x0000000000000000UL);
- /* Init_7: LEM Mask Reg (AND write) */
- REGW(0x3e1e20, 0x0FFF001F03030000UL);
-
- /*** Set GEM regs (masks still on, no irpts can occur yet) ***/
-
- /* Init_8: GEM XFIR */
- REGW(0x3e0008, 0x0000000000000000UL);
- /* Init_9: GEM WOF */
- REGW(0x3e0028, 0x0000000000000000UL);
-
- /*** Set Damage Controls (needs to match recov.) ***/
-
- /* Init_10: LDCP */
- REGW(0x3e1c18, 0xF00086C0B4FCFFFFUL);
-
- /*** Read status (optional) ***/
-
- /* Init_11: Read status */
- val = REGR(0x3e1c10);
- printf("P7IOC: Init_11 Status: %016llx\n", val);
-
- /*** Set running configuration **/
-
- /* Init_12: Configuration reg (modes, values, timers) */
- REGW(0x3e1c08, 0x10000077CE100000UL);
-
- /* Init_13: Cmd/Dat Crd Allocation */
- REGW(0x3e1c20, 0x00000103000700FFUL);
- /* Init_14: GP reg - disable errs, wrap, stop_trc */
- REGW(0x3e1018, 0x0000000000000000UL);
- /* Init_15: Configuration reg (start init timers) */
- cfg = REGR(0x3e1c08);
- REGW(0x3e1c08, cfg | 0x00003f0000000000UL);
-
- /*** Setup interrupts ***/
-
- /* Init_16: BUID Register
- *
- * XXX NOTE: This needs to be clarified. According to the doc
- * the register contains a 9-bit BUID, which makes sense so far.
- *
- * However, the initialization sequence says "depends on which
- * GX bus) which doesn't since afaik the GX bus number is encoded
- * in the BUID Extension bit which is right *above* the 9-bit
- * BUID in the interrupt message.
- *
- * So I must be missing something here... For now I'll just
- * write my 9-bit BUID and we'll see what happens.
- *
- */
- REGW(0x3e1800, (uint64_t)ioc->rgc_buid << PPC_BITLSHIFT(31));
-
- /* Init_17: Supposed to lock the IODA table but we aren't racing
- * with anybody so there is little point.
- *
- * Note: If/when we support some kind of error recovery that
- * involves re-initializing the IOC, then we might have
- * to take some locks but it's assumed that the necessary
- * lock(s) will be obtained by the caller.
- */
- //REGR(0x3e1840, 0x0000000000000000);
-
- /* Init_18: IODA Table Addr: Select IST*/
- REGW(0x3e1820, 0x8001000000000000UL);
- /* Init_19: IODA Table Data: IRPT 0 */
- REGW(0x3e1830, 0x0000000000000000UL);
- /* Init_20: IODA Table Data: IRPT 1 */
- REGW(0x3e1830, 0x0000000000000000UL);
- /* Init_21: IODA Table Addr: Select HRT */
- REGW(0x3e1820, 0x8000000000000000UL);
- /* Init_22: IODA Table Data: HRT
- *
- * XXX Figure out what this actually is and what value should
- * we use. For now, do like BML and use 0
- */
- for (i = 0; i < 4; i++)
- REGW(0x3e1830, 0x0000000000000000UL);
-
- /* Init_23: IODA Table Addr: select XIVT */
- REGW(0x3e1820, 0x8002000000000000UL);
- /* Init_24: IODA Table Data: Mask all interrupts */
- for (i = 0; i < 16; i++)
- REGW(0x3e1830, 0x000000ff00000000UL);
-
- /* Init_25: Clear table lock if any was stale */
- REGW(0x3e1840, 0x0000000000000000UL);
-
- /* Init_32..37: Set the PHB AIB addresses. We configure those
- * to the values recommended in the p7IOC doc.
- *
- * XXX NOTE: I cannot find a documentation for these, I assume
- * they just take the full 64-bit address, but we may want to
- * dbl check just in case (it seems to be what BML does but
- * I'm good at mis-reading Milton's Perl).
- */
- for (i = 0; i < P7IOC_NUM_PHBS; i++) {
- if (!p7ioc_phb_enabled(ioc, i))
- continue;
- REGW(0x3e1080 + (i << 3),
- ioc->mmio1_win_start + PHBn_AIB_BASE(i));
- }
-}
-
-static void p7ioc_init_ci_routing(struct p7ioc *ioc)
-{
- unsigned int i, j = 0;
- uint64_t rmatch[47];
- uint64_t rmask[47];
- uint64_t pmask;
-
- /* Init_130: clear all matches (except 47 which routes to the RGC) */
- for (i = 0; i < 47; i++) {
- rmatch[i] = REGR(P7IOC_CI_RMATC_REG(i)) &
- ~(P7IOC_CI_RMATC_ADDR_VALID |
- P7IOC_CI_RMATC_BUID_VALID |
- P7IOC_CI_RMATC_TYPE_VALID);
- rmask[i] = 0;
- REGW(P7IOC_CI_RMATC_REG(i), rmatch[i]);
- }
-
- /* Init_131...224: configure routing for everything except RGC
- *
- * We are using a slightly different routing setup than the
- * example to make the code easier. We configure all PHB
- * routing entries by doing all of PHB0 first, then all of PHB1
- * etc...
- *
- * Then we append everything else except the RGC itself which
- * remains hard wired at entry 47. So the unused entries live
- * at 39..46.
- *
- * - 0 : PHB0 LSI BUID
- * - 1 : PHB0 MSI BUID
- * - 2 : PHB0 AIB Registers
- * - 3 : PHB0 IO Space
- * - 4 : PHB0 M32 Space
- * - 5 : PHB0 M64 Space
- * - 6..11 : PHB1
- * - 12..17 : PHB2
- * - 18..23 : PHB3
- * - 24..29 : PHB4
- * - 30..35 : PHB5
- * - 36 : Invalidates broadcast (FMTC)
- * - 37 : Interrupt response for RGC
- * - 38 : RGC GEM BUID
- * - 39..46 : Unused (alternate M64 ?)
- * - 47 : RGC ASB Registers (catch all)
- */
-
- /* Helper macro to set a rule */
-#define CI_ADD_RULE(p, k, d, m) do { \
- rmask[j] = P7IOC_CI_RMATC_ENCODE_##k(m); \
- rmatch[j]= P7IOC_CI_RMATC_PORT(p) | \
- P7IOC_CI_RMATC_##k##_VALID | \
- P7IOC_CI_RMATC_ENCODE_##k(d); \
- j++; \
- } while (0)
-
- pmask = 0;
- for (i = 0; i < P7IOC_NUM_PHBS; i++) {
- unsigned int buid_base = ioc->buid_base + PHBn_BUID_BASE(i);
-
- if (!p7ioc_phb_enabled(ioc, i))
- continue;
-
- /* LSI BUIDs, match all 9 bits (1 BUID per PHB) */
- CI_ADD_RULE(P7IOC_CI_PHB_PORT(i), BUID,
- buid_base + PHB_BUID_LSI_OFFSET, 0x1ff);
-
- /* MSI BUIDs, match 4 bits (16 BUIDs per PHB) */
- CI_ADD_RULE(P7IOC_CI_PHB_PORT(i), BUID,
- buid_base + PHB_BUID_MSI_OFFSET, 0x1f0);
-
- /* AIB reg space */
- CI_ADD_RULE(P7IOC_CI_PHB_PORT(i), ADDR,
- ioc->mmio1_win_start + PHBn_AIB_BASE(i),
- ~(PHBn_AIB_SIZE - 1));
-
- /* IO space */
- CI_ADD_RULE(P7IOC_CI_PHB_PORT(i), ADDR,
- ioc->mmio1_win_start + PHBn_IO_BASE(i),
- ~(PHB_IO_SIZE - 1));
-
- /* M32 space */
- CI_ADD_RULE(P7IOC_CI_PHB_PORT(i), ADDR,
- ioc->mmio2_win_start + PHBn_M32_BASE(i),
- ~(PHB_M32_SIZE - 1));
-
- /* M64 space */
- CI_ADD_RULE(P7IOC_CI_PHB_PORT(i), ADDR,
- ioc->mmio2_win_start + PHBn_M64_BASE(i),
- ~(PHB_M64_SIZE - 1));
-
- /* For use with invalidate bcasts */
- pmask |= P7IOC_CI_PHB_PORT(i);
- }
-
- /* Invalidates broadcast to all PHBs */
- CI_ADD_RULE(pmask, TYPE, 0x80, 0xf0);
-
- /* Interrupt responses go to RGC */
- CI_ADD_RULE(P7IOC_CI_RGC_PORT, TYPE, 0x60, 0xf0);
-
- /* RGC GEM BUID (1 BUID) */
- CI_ADD_RULE(P7IOC_CI_RGC_PORT, BUID, ioc->rgc_buid, 0x1ff);
-
- /* Program the values masks first */
- for (i = 0; i < 47; i++)
- REGW(P7IOC_CI_RMASK_REG(i), rmask[i]);
- for (i = 0; i < 47; i++)
- REGW(P7IOC_CI_RMATC_REG(i), rmatch[i]);
-
- /* Init_225: CI Match 47 (Configure RGC catch all) */
- REGW(P7IOC_CI_RMASK_REG(47), 0x0000000000000000UL);
- REGW(P7IOC_CI_RMATC_REG(47), 0x4000800000000000UL);
-
-#ifdef DUMP_CI_ROUTING
- printf("P7IOC: CI Routing table:\n");
- for (i = 0; i < 48; i++)
- printf(" [%.2d] MTCH: %016llx MSK: %016llx\n", i,
- REGR(P7IOC_CI_RMATC_REG(i)),
- REGR(P7IOC_CI_RMASK_REG(i)));
-#endif /* DUMP_CI_ROUTING */
-}
-
-static void p7ioc_init_CI(struct p7ioc *ioc)
-{
- printf("P7IOC: Init CI...\n");
-
- /*** Clear ERPT macros ***/
-
- /* XXX NOTE: The doc seems to also provide "alternate freq ratio"
- * settings. Not sure what they are about, let's stick to the
- * original values for now.
- */
-
- /* Init_1: CI Port 0 Configuration */
- REGW(0x3d0000, 0x420000C0073F0002UL);
- /* Init_2: CI Port 0 Configuration */
- REGW(0x3d0000, 0x020000C0073F0002UL);
- /* Init_3: CI Port 1 Configuration */
- REGW(0x3d1000, 0x42000FCF07200002UL);
- /* Init_4: CI Port 1 Configuration */
- REGW(0x3d1000, 0x02000FCF07200002UL);
- /* Init_5: CI Port 2 Configuration */
- REGW(0x3d2000, 0x420000C307200002UL);
- /* Init_6: CI Port 2 Configuration */
- REGW(0x3d2000, 0x020000C307200002UL);
- /* Init_7: CI Port 3 Configuration */
- REGW(0x3d3000, 0x420000C307200002UL);
- /* Init_8: CI Port 3 Configuration */
- REGW(0x3d3000, 0x020000C307200002UL);
- /* Init_9: CI Port 4 Configuration */
- REGW(0x3d4000, 0x420000C307200002UL);
- /* Init_10: CI Port 4 Configuration */
- REGW(0x3d4000, 0x020000C307200002UL);
- /* Init_11: CI Port 5 Configuration */
- REGW(0x3d5000, 0x420000C307200002UL);
- /* Init_12: CI Port 5 Configuration */
- REGW(0x3d5000, 0x020000C307200002UL);
- /* Init_13: CI Port 6 Configuration */
- REGW(0x3d6000, 0x420000C307200002UL);
- /* Init_14: CI Port 6 Configuration */
- REGW(0x3d6000, 0x020000C307200002UL);
- /* Init_15: CI Port 7 Configuration */
- REGW(0x3d7000, 0x420000C307200002UL);
- /* Init_16: CI Port 7 Configuration */
- REGW(0x3d7000, 0x020000C307200002UL);
-
- /*** Set LEM regs (need to match recov.) ***/
-
- /* Init_17: CI Port 0 LEM FIR Accumulator */
- REGW(0x3d0200, 0x0000000000000000UL);
- /* Init_18: CI Port 0 LEM Action 0 */
- REGW(0x3d0230, 0x0A00000000000000UL);
- /* Init_19: CI Port 0 LEM Action 1 */
- REGW(0x3d0238, 0x0000000000000000UL);
- /* Init_20: CI Port 0 LEM WOF */
- REGW(0x3d0240, 0x0000000000000000UL);
- /* Init_21: CI Port 0 LEM Mask (AND write) */
- REGW(0x3d0220, 0x0200000000000000UL);
- /* Init_22: CI Port 1 LEM FIR Accumularor */
- REGW(0x3d1200, 0x0000000000000000UL);
- /* Init_23: CI Port 1 LEM Action 0 */
- REGW(0x3d1230, 0x0000000000000000UL);
- /* Init_24: CI Port 1 LEM Action 1 */
- REGW(0x3d1238, 0x0000000000000000UL);
- /* Init_25: CI Port 1 LEM WOF */
- REGW(0x3d1240, 0x0000000000000000UL);
- /* Init_26: CI Port 1 LEM Mask (AND write) */
- REGW(0x3d1220, 0x0000000000000000UL);
- /* Init_27: CI Port 2 LEM FIR Accumulator */
- REGW(0x3d2200, 0x0000000000000000UL);
- /* Init_28: CI Port 2 LEM Action 0 */
- REGW(0x3d2230, 0xA4F4000000000000UL);
- /* Init_29: CI Port 2 LEM Action 1 */
- REGW(0x3d2238, 0x0000000000000000UL);
- /* Init_30: CI Port 2 LEM WOF */
- REGW(0x3d2240, 0x0000000000000000UL);
- /* Init_31: CI Port 2 LEM Mask (AND write) */
- REGW(0x3d2220, 0x0000000000000000UL);
- /* Init_32: CI Port 3 LEM FIR Accumulator */
- REGW(0x3d3200, 0x0000000000000000UL);
- /* Init_33: CI Port 3 LEM Action 0 */
- REGW(0x3d3230, 0xA4F4000000000000UL);
- /* Init_34: CI Port 3 LEM Action 1 */
- REGW(0x3d3238, 0x0000000000000000UL);
- /* Init_35: CI Port 3 LEM WOF */
- REGW(0x3d3240, 0x0000000000000000UL);
- /* Init_36: CI Port 3 LEM Mask (AND write) */
- REGW(0x3d3220, 0x0000000000000000UL);
- /* Init_37: CI Port 4 LEM FIR Accumulator */
- REGW(0x3d4200, 0x0000000000000000UL);
- /* Init_38: CI Port 4 Action 0 */
- REGW(0x3d4230, 0xA4F4000000000000UL);
- /* Init_39: CI Port 4 Action 1 */
- REGW(0x3d4238, 0x0000000000000000UL);
- /* Init_40: CI Port 4 WOF */
- REGW(0x3d4240, 0x0000000000000000UL);
- /* Init_41: CI Port 4 Mask (AND write) */
- REGW(0x3d4220, 0x0000000000000000UL);
- /* Init_42: CI Port 5 LEM FIR Accumulator */
- REGW(0x3d5200, 0x0000000000000000UL);
- /* Init_43: CI Port 5 Action 0 */
- REGW(0x3d5230, 0xA4F4000000000000UL);
- /* Init_44: CI Port 5 Action 1 */
- REGW(0x3d5238, 0x0000000000000000UL);
- /* Init_45: CI Port 4 WOF */
- REGW(0x3d5240, 0x0000000000000000UL);
- /* Init_46: CI Port 5 Mask (AND write) */
- REGW(0x3d5220, 0x0000000000000000UL);
- /* Init_47: CI Port 6 LEM FIR Accumulator */
- REGW(0x3d6200, 0x0000000000000000UL);
- /* Init_48: CI Port 6 Action 0 */
- REGW(0x3d6230, 0xA4F4000000000000UL);
- /* Init_49: CI Port 6 Action 1 */
- REGW(0x3d6238, 0x0000000000000000UL);
- /* Init_50: CI Port 6 WOF */
- REGW(0x3d6240, 0x0000000000000000UL);
- /* Init_51: CI Port 6 Mask (AND write) */
- REGW(0x3d6220, 0x0000000000000000UL);
- /* Init_52: CI Port 7 LEM FIR Accumulator */
- REGW(0x3d7200, 0x0000000000000000UL);
- /* Init_53: CI Port 7 Action 0 */
- REGW(0x3d7230, 0xA4F4000000000000UL);
- /* Init_54: CI Port 7 Action 1 */
- REGW(0x3d7238, 0x0000000000000000UL);
- /* Init_55: CI Port 7 WOF */
- REGW(0x3d7240, 0x0000000000000000UL);
- /* Init_56: CI Port 7 Mask (AND write) */
- REGW(0x3d7220, 0x0000000000000000UL);
-
- /*** Set Damage Controls (need match recov.) ***/
-
- /* Init_57: CI Port 0 LDCP*/
- REGW(0x3d0010, 0x421A0000000075FFUL);
- /* Init_58: CI Port 1 LDCP */
- REGW(0x3d1010, 0x421A000000007FFFUL);
- /* Init_59: CI Port 2 LDCP */
- REGW(0x3d2010, 0x421A24F400005B0BUL);
- /* Init_60: CI Port 3 LDCP */
- REGW(0x3d3010, 0x421A24F400005B0BUL);
- /* Init_61: CI Port 4 LDCP */
- REGW(0x3d4010, 0x421A24F400005B0BUL);
- /* Init_62: CI Port 5 LDCP */
- REGW(0x3d5010, 0x421A24F400005B0BUL);
- /* Init_63: CI Port 6 LDCP */
- REGW(0x3d6010, 0x421A24F400005B0BUL);
- /* Init_64: CI Port 7 LDCP */
- REGW(0x3d7010, 0x421A24F400005B0BUL);
-
- /*** Setup Trace 0 ***/
-
- /* Init_65: CI Trc 0 DBG - Run/Status (stop trace) */
- REGW(0x3d0810, 0x5000000000000000UL);
- /* Init_66: CI Trc 0 DBG - Mode (not cross trig CA's) */
- REGW(0x3d0808, 0xB0000000F0000000UL);
- /* Init_66a: CI Trc 0 DBG - C0 (stop on error) */
- REGW(0x3d0818, 0xF4F00FFF00000000UL);
- /* Init_67: CI Trc 0 DBG - Select (port 0 mode 2) */
- REGW(0x3d0878, 0x0002000000000000UL);
- /* Init_68: CI Trc 0 CA0 - Pattern A (RX cmd val) */
- REGW(0x3d0880, 0xC0200000DFFFFF00UL);
- /* Init_69: CI Trc 0 CA0 - Trigger 0 (Pattern A) */
- REGW(0x3d08a0, 0x8000000000000000UL);
- /* Init_70: CI Trc 0 - Mode */
- REGW(0x3d08b0, 0x8000000000000000UL);
- /* Init_71: CI Trc 0 CA1 - Pattern A (TX cmd val) */
- REGW(0x3d0900, 0xC0200000DFFFFF00UL);
- /* Init_72: CI Trc 0 CA1 - Trigger 0 (Pattern A) */
- REGW(0x3d0920, 0x8000000000000000UL);
- /* Init_73: CI Trc 0 CA1 - Mode */
- REGW(0x3d0930, 0x8000000000000000UL);
- /* Init_74: CI Trc 0 DBG - Run/Status (start trace) */
- REGW(0x3d0810, 0x8000000000000000UL);
-
- /*** Setup Trace 1 ***/
-
- /* Init_75: CI Trc 1 DBG - Run/Status (stop trace) */
- REGW(0x3d0c10, 0x5000000000000000UL);
- /* Init_76: CI Trc 1 DBG - Mode (not cross trig CA's) */
- REGW(0x3d0c08, 0xB0000000F0000000UL);
- /* Init_76a: CI Trc 1 DBG - C0 (stop on error) */
- REGW(0x3d0c18, 0xF4F00FFF00000000UL);
- /* Init_77: CI Trc 1 DBG - Select (port 1 mode 2) */
- REGW(0x3d0c78, 0x0102000000000000UL);
- /* Init_78: CI Trc 1 CA0 - Pattern A (RX cmd val) */
- REGW(0x3d0c80, 0xC0200000DFFFFF00UL);
- /* Init_79: CI Trc 1 CA0 - Trigger 0 (Pattern A) */
- REGW(0x3d0ca0, 0x8000000000000000UL);
- /* Init_80: CI Trc 1 CA0 - Mode */
- REGW(0x3d0cb0, 0x8000000000000000UL);
- /* Init_81: CI Trc 1 CA1 - Pattern A (TX cmd val) */
- REGW(0x3d0d00, 0xC0200000DFFFFF00UL);
- /* Init_82: CI Trc 1 CA1 - Trigger 0 (Pattern A) */
- REGW(0x3d0d20, 0x8000000000000000UL);
- /* Init_83: CI Trc 1 CA1 - Mode */
- REGW(0x3d0d30, 0x8000000000000000UL);
- /* Init_84: CI Trc 1 DBG - Run/Status (start trace) */
- REGW(0x3d0c10, 0x8000000000000000UL);
-
- /* Init_85...92:
- *
- * XXX NOTE: Here we normally read the Port 0 to 7 status regs
- * which is optional. Eventually we might want to do it to check
- * if the status matches expectations
- *
- * (regs 0x3d0008 to 0x3d7008)
- */
-
- /*** Set buffer allocations (credits) ***/
-
- /* Init_93: CI Port 0 Rx Cmd Buffer Allocation */
- REGW(0x3d0050, 0x0808040400000000UL);
- /* Init_94: CI Port 0 Rx Dat Buffer Allocation */
- REGW(0x3d0060, 0x0006000200000000UL);
- /* Init_95: CI Port 1 Tx Cmd Buffer Allocation */
- REGW(0x3d1030, 0x0000040400000000UL);
- /* Init_96: CI Port 1 Tx Dat Buffer Allocation */
- REGW(0x3d1040, 0x0000004800000000UL);
- /* Init_97: CI Port 1 Rx Cmd Buffer Allocation */
- REGW(0x3d1050, 0x0008000000000000UL);
- /* Init_98: CI Port 1 Rx Dat Buffer Allocation */
- REGW(0x3d1060, 0x0048000000000000UL);
- /* Init_99: CI Port 2 Tx Cmd Buffer Allocation */
- REGW(0x3d2030, 0x0808080800000000UL);
- /* Init_100: CI Port 2 Tx Dat Buffer Allocation */
- REGW(0x3d2040, 0x0086008200000000UL);
- /* Init_101: CI Port 2 Rx Cmd Buffer Allocation */
- REGW(0x3d2050, 0x0808080800000000UL);
- /* Init_102: CI Port 2 Rx Dat Buffer Allocation */
- REGW(0x3d2060, 0x8648000000000000UL);
- /* Init_103: CI Port 3 Tx Cmd Buffer Allocation */
- REGW(0x3d3030, 0x0808080800000000UL);
- /* Init_104: CI Port 3 Tx Dat Buffer Allocation */
- REGW(0x3d3040, 0x0086008200000000UL);
- /* Init_105: CI Port 3 Rx Cmd Buffer Allocation */
- REGW(0x3d3050, 0x0808080800000000UL);
- /* Init_106: CI Port 3 Rx Dat Buffer Allocation */
- REGW(0x3d3060, 0x8648000000000000UL);
- /* Init_107: CI Port 4 Tx Cmd Buffer Allocation */
- REGW(0x3d4030, 0x0808080800000000UL);
- /* Init_108: CI Port 4 Tx Dat Buffer Allocation */
- REGW(0x3d4040, 0x0086008200000000UL);
- /* Init_109: CI Port 4 Rx Cmd Buffer Allocation */
- REGW(0x3d4050, 0x0808080800000000UL);
- /* Init_110: CI Port 4 Rx Dat Buffer Allocation */
- REGW(0x3d4060, 0x8648000000000000UL);
- /* Init_111: CI Port 5 Tx Cmd Buffer Allocation */
- REGW(0x3d5030, 0x0808080800000000UL);
- /* Init_112: CI Port 5 Tx Dat Buffer Allocation */
- REGW(0x3d5040, 0x0086008200000000UL);
- /* Init_113: CI Port 5 Rx Cmd Buffer Allocation */
- REGW(0x3d5050, 0x0808080800000000UL);
- /* Init_114: CI Port 5 Rx Dat Buffer Allocation */
- REGW(0x3d5060, 0x8648000000000000UL);
- /* Init_115: CI Port 6 Tx Cmd Buffer Allocation */
- REGW(0x3d6030, 0x0808080800000000UL);
- /* Init_116: CI Port 6 Tx Dat Buffer Allocation */
- REGW(0x3d6040, 0x0086008200000000UL);
- /* Init_117: CI Port 6 Rx Cmd Buffer Allocation */
- REGW(0x3d6050, 0x0808080800000000UL);
- /* Init_118: CI Port 6 Rx Dat Buffer Allocation */
- REGW(0x3d6060, 0x8648000000000000UL);
- /* Init_119: CI Port 7 Tx Cmd Buffer Allocation */
- REGW(0x3d7030, 0x0808080800000000UL);
- /* Init_120: CI Port 7 Tx Dat Buffer Allocation */
- REGW(0x3d7040, 0x0086008200000000UL);
- /* Init_121: CI Port 7 Rx Cmd Buffer Allocation */
- REGW(0x3d7050, 0x0808080800000000UL);
- /* Init_122: CI Port 6 Rx Dat Buffer Allocation */
- REGW(0x3d7060, 0x8648000000000000UL);
-
- /*** Channel ordering ***/
-
- /* Init_123: CI Port 1 Ordering */
- REGW(0x3d1070, 0x73D0735E00000000UL);
- /* Init_124: CI Port 2 Ordering */
- REGW(0x3d2070, 0x73D0735E00000000UL);
- /* Init_125: CI Port 3 Ordering */
- REGW(0x3d3070, 0x73D0735E00000000UL);
- /* Init_126: CI Port 4 Ordering */
- REGW(0x3d4070, 0x73D0735E00000000UL);
- /* Init_127: CI Port 5 Ordering */
- REGW(0x3d5070, 0x73D0735E00000000UL);
- /* Init_128: CI Port 6 Ordering */
- REGW(0x3d6070, 0x73D0735E00000000UL);
- /* Init_129: CI POrt 7 Ordering */
- REGW(0x3d7070, 0x73D0735E00000000UL);
-
- /*** Setup routing (port 0 only) */
-
- p7ioc_init_ci_routing(ioc);
-
- /*** Set Running Configuration/Crd Init Timers ***
- *
- * XXX NOTE: Supposed to only modify bits 8:15
- */
-
- /* Init_226: CI Port 1 Configuration */
- REGW(0x3d1000, 0x023F0FCF07200002UL);
- /* Init_227: CI Port 2 Configuration */
- REGW(0x3d2000, 0x023F00C307200002UL);
- /* Init_228: CI Port 3 Configuration */
- REGW(0x3d3000, 0x023F00C307200002UL);
- /* Init_229: CI Port 4 Configuration */
- REGW(0x3d4000, 0x023F00C307200002UL);
- /* Init_230: CI Port 5 Configuration */
- REGW(0x3d5000, 0x023F00C307200002UL);
- /* Init_231: CI Port 6 Configuration */
- REGW(0x3d6000, 0x023F00C307200002UL);
- /* Init_232: CI Port 7 Configuration */
- REGW(0x3d7000, 0x023F00C307200002UL);
- /* Init_233: CI Port 0 Configuration */
- REGW(0x3d0000, 0x023F00C0073F0002UL);
-}
-
-static void p7ioc_init_PHBs(struct p7ioc *ioc)
-{
- unsigned int i;
-
- printf("P7IOC: Init PHBs...\n");
-
- /* We use the same reset sequence that we use for
- * fast reboot for consistency
- */
- for (i = 0; i < P7IOC_NUM_PHBS; i++) {
- if (p7ioc_phb_enabled(ioc, i))
- p7ioc_phb_reset(&ioc->phbs[i].phb);
- }
-}
-
-static void p7ioc_init_MISC(struct p7ioc *ioc)
-{
- printf("P7IOC: Init MISC...\n");
-
- /*** Set LEM regs ***/
-
- /* Init_1: LEM FIR Accumulator */
- REGW(0x3ea000, 0x0000000000000000UL);
- /* Init_2: LEM Action 0 */
- REGW(0x3ea030, 0xFFFFFFFCEE3FFFFFUL);
- /* Init_3: LEM Action 1 */
- REGW(0x3ea038, 0x0000000001C00000UL);
- /* Init_4: LEM WOF */
- REGW(0x3ea040, 0x0000000000000000UL);
- /* Init_5: LEM Mask (AND write) */
- REGW(0x3ea020, 0x000F03F0CD3FFFFFUL);
- /* Init_5.1: I2C LEM FIR Accumulator */
- REGW(0x3eb000, 0x0000000000000000UL);
- /* Init_5.2: I2C LEM Action 0 */
- REGW(0x3eb030, 0xEE00000000000000UL);
- /* Init_5.3: I2C LEM Action 1 */
- REGW(0x3eb038, 0x0000000000000000UL);
- /* Init_5.4: I2C LEM WOF */
- REGW(0x3eb040, 0x0000000000000000UL);
- /* Init_5.5: I2C LEM Mask (AND write) */
- REGW(0x3eb020, 0x4600000000000000UL);
-
- /*** Set RGC GP bits (error enables) ***/
-
- /* Init_7: RGC GP0 control (enable umux errors) */
- REGW(0x3e1018, 0x8888880000000000ULL);
-
- /*** Central Trace Setup ***
- *
- * By default trace 4 PHBs Rx/Tx, but this can be changed
- * for debugging purposes
- */
-
- /* Init_8: */
- REGW(0x3ea810, 0x5000000000000000UL);
- /* Init_9: */
- REGW(0x3ea800, 0x0000000000000000UL);
- /* Init_10: */
- REGW(0x3ea808, 0xB0000000F0000000UL);
- /* Init_11: */
- REGW(0x3ea818, 0xF4F00FFF00000000UL);
- /* Init_12: */
- REGW(0x3ea820, 0x0000000000000000UL);
- /* Init_13: */
- REGW(0x3ea828, 0x0000000000000000UL);
- /* Init_14: */
- REGW(0x3ea830, 0x0000000000000000UL);
- /* Init_15: */
- REGW(0x3ea838, 0x0000000000000000UL);
- /* Init_16: */
- REGW(0x3ea840, 0x0000000000000000UL);
- /* Init_17: */
- REGW(0x3ea878, 0x0300000000000000UL);
-
- /* Init_18: PHB0 mux select (Rx/Tx) */
- REGW(0x000F80, 0x0000000000000000UL);
- /* Init_19: PHB1 mux select (Rx/Tx) */
- REGW(0x010F80, 0x0000000000000000UL);
- /* Init_19.0: PHB2 mux select (Rx/Tx) */
- REGW(0x020F80, 0x0000000000000000UL);
- /* Init_19.1: PHB3 mux select (Rx/Tx) */
- REGW(0x030F80, 0x0000000000000000UL);
- /* Init_19.2: PHB4 mux select (Rx/Tx) */
- REGW(0x040F80, 0x0000000000000000UL);
- /* Init_19.3: PHB5 mux select (Rx/Tx) */
- REGW(0x050F80, 0x0000000000000000UL);
-
- /* Init_20: */
- REGW(0x3ea880, 0x40008000FF7F0000UL);
- /* Init_21: */
- REGW(0x3ea888, 0x0000000000000000UL);
- /* Init_22: */
- REGW(0x3ea890, 0x0000000000000000UL);
- /* Init_23: */
- REGW(0x3ea898, 0x0000000000000000UL);
- /* Init_24: */
- REGW(0x3ea8a0, 0x8000000000000000UL);
- /* Init_25: */
- REGW(0x3ea8a8, 0x0000000000000000UL);
- /* Init_26: */
- REGW(0x3ea8b0, 0x8000000000000000UL);
- /* Init_27: */
- REGW(0x3ea8b8, 0x0000000000000000UL);
- /* Init_28: */
- REGW(0x3ea8c0, 0x0000000000000000UL);
- /* Init_29: */
- REGW(0x3ea900, 0x40008000FF7F0000UL);
- /* Init_30: */
- REGW(0x3ea908, 0x0000000000000000UL);
- /* Init_31: */
- REGW(0x3ea910, 0x0000000000000000UL);
- /* Init_32: */
- REGW(0x3ea918, 0x0000000000000000UL);
- /* Init_33: */
- REGW(0x3ea920, 0x8000000000000000UL);
- /* Init_34: */
- REGW(0x3ea928, 0x0000000000000000UL);
- /* Init_35: */
- REGW(0x3ea930, 0x8000000000000000UL);
- /* Init_36: */
- REGW(0x3ea938, 0x0000000000000000UL);
- /* Init_37: */
- REGW(0x3ea940, 0x0000000000000000UL);
- /* Init_38: */
- REGW(0x3ea980, 0x40008000FF7F0000UL);
- /* Init_39: */
- REGW(0x3ea988, 0x0000000000000000UL);
- /* Init_40: */
- REGW(0x3ea990, 0x0000000000000000UL);
- /* Init_41: */
- REGW(0x3ea998, 0x0000000000000000UL);
- /* Init_42: */
- REGW(0x3ea9a0, 0x8000000000000000UL);
- /* Init_43: */
- REGW(0x3ea9a8, 0x0000000000000000UL);
- /* Init_44: */
- REGW(0x3ea9b0, 0x8000000000000000UL);
- /* Init_45: */
- REGW(0x3ea9b8, 0x0000000000000000UL);
- /* Init_46: */
- REGW(0x3ea9c0, 0x0000000000000000UL);
- /* Init_47: */
- REGW(0x3eaa00, 0x40008000FF7F0000UL);
- /* Init_48: */
- REGW(0x3eaa08, 0x0000000000000000UL);
- /* Init_49: */
- REGW(0x3eaa10, 0x0000000000000000UL);
- /* Init_50: */
- REGW(0x3eaa18, 0x0000000000000000UL);
- /* Init_51: */
- REGW(0x3eaa20, 0x8000000000000000UL);
- /* Init_52: */
- REGW(0x3eaa28, 0x0000000000000000UL);
- /* Init_53: */
- REGW(0x3eaa30, 0x8000000000000000UL);
- /* Init_54: */
- REGW(0x3eaa38, 0x0000000000000000UL);
- /* Init_55: */
- REGW(0x3eaa40, 0x0000000000000000UL);
- /* Init_56: */
- REGW(0x3ea810, 0x1000000000000000UL);
- /* Init_57: */
- REGW(0x3ea810, 0x8000000000000000UL);
-
- /*** I2C Master init fixup */
-
- /* Init_58: I2C Master Operation Control */
- REGW(0x3eb0a8, 0x8100000000000000UL);
-}
-
-static void p7ioc_init_GEM(struct p7ioc *ioc)
-{
- printf("P7IOC: Init GEM...\n");
-
- /*** Check for errors */
-
- /* XXX TODO */
-#if 0
- /* Init_1: */
- REGR(0x3e0008, 0);
- /* Init_2: */
- REGR(0x3e0010, 0);
- /* Init_3: */
- REGR(0x3e0018, 0);
-#endif
-
- /*** Get ready for new errors, allow interrupts ***
- *
- * XXX: Need to leave all unused port masked to prevent
- * invalid errors
- */
-
- /* Init_4: GEM XFIR */
- REGW(0x3e0008, 0x0000000000000000);
- /* Init_5: GEM Mask (See FIXME) */
- REGW(0x3e0020, 0x000F033FFFFFFFFFUL);
- /* Init_6: GEM WOF */
- REGW(0x3e0028, 0x0000000000000000);
-}
-
-int64_t p7ioc_inits(struct p7ioc *ioc)
-{
- p7ioc_init_BI(ioc);
- p7ioc_init_MISC_HSS(ioc);
- p7ioc_init_RGC(ioc);
- p7ioc_init_CI(ioc);
- p7ioc_init_PHBs(ioc);
- p7ioc_init_MISC(ioc);
- p7ioc_init_GEM(ioc);
-
- return OPAL_SUCCESS;
-
-}
-
-void p7ioc_reset(struct io_hub *hub)
-{
- struct p7ioc *ioc = iohub_to_p7ioc(hub);
- unsigned int i;
-
- /* We could do a full cold reset of P7IOC but for now, let's
- * not bother and just try to clean up the interrupts as best
- * as possible
- */
-
- /* XXX TODO: RGC interrupts */
-
- printf("P7IOC: Clearing IODA...\n");
-
- /* First clear all IODA tables and wait a bit */
- for (i = 0; i < 6; i++) {
- if (p7ioc_phb_enabled(ioc, i))
- p7ioc_phb_reset(&ioc->phbs[i].phb);
- }
-}
diff --git a/hw/p7ioc-phb.c b/hw/p7ioc-phb.c
deleted file mode 100644
index ac01103..0000000
--- a/hw/p7ioc-phb.c
+++ /dev/null
@@ -1,3242 +0,0 @@
-/* Copyright 2013-2014 IBM Corp.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- * implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <skiboot.h>
-#include <p7ioc.h>
-#include <p7ioc-regs.h>
-#include <io.h>
-#include <timebase.h>
-#include <affinity.h>
-#include <pci-cfg.h>
-#include <pci.h>
-#include <pci-slot.h>
-#include <interrupts.h>
-#include <opal.h>
-#include <ccan/str/str.h>
-
-#define PHBDBG(p, fmt, a...) prlog(PR_DEBUG, "PHB#%04x: " fmt, \
- (p)->phb.opal_id, ## a)
-#define PHBERR(p, fmt, a...) prlog(PR_ERR, "PHB#%04x: " fmt, \
- (p)->phb.opal_id, ## a)
-
-/* Helper to select an IODA table entry */
-static inline void p7ioc_phb_ioda_sel(struct p7ioc_phb *p, uint32_t table,
- uint32_t addr, bool autoinc)
-{
- out_be64(p->regs + PHB_IODA_ADDR,
- (autoinc ? PHB_IODA_AD_AUTOINC : 0) |
- SETFIELD(PHB_IODA_AD_TSEL, 0ul, table) |
- SETFIELD(PHB_IODA_AD_TADR, 0ul, addr));
-}
-
-static bool p7ioc_phb_fenced(struct p7ioc_phb *p)
-{
- struct p7ioc *ioc = p->ioc;
- uint64_t fence, fbits;
-
- fbits = 0x0003000000000000UL >> (p->index * 4);
- fence = in_be64(ioc->regs + P7IOC_CHIP_FENCE_SHADOW);
-
- return (fence & fbits) != 0;
-}
-
-/*
- * Configuration space access
- *
- * The PHB lock is assumed to be already held
- */
-static int64_t p7ioc_pcicfg_check(struct p7ioc_phb *p, uint32_t bdfn,
- uint32_t offset, uint32_t size)
-{
- uint32_t sm = size - 1;
-
- if (offset > 0xfff || bdfn > 0xffff)
- return OPAL_PARAMETER;
- if (offset & sm)
- return OPAL_PARAMETER;
-
- /* The root bus only has a device at 0 and we get into an
- * error state if we try to probe beyond that, so let's
- * avoid that and just return an error to Linux
- */
- if ((bdfn >> 8) == 0 && (bdfn & 0xff))
- return OPAL_HARDWARE;
-
- /* Check PHB state */
- if (p->broken)
- return OPAL_HARDWARE;
-
- return OPAL_SUCCESS;
-}
-
-#define P7IOC_PCI_CFG_READ(size, type) \
-static int64_t p7ioc_pcicfg_read##size(struct phb *phb, uint32_t bdfn, \
- uint32_t offset, type *data) \
-{ \
- struct p7ioc_phb *p = phb_to_p7ioc_phb(phb); \
- uint64_t addr; \
- void *base = p->regs; \
- int64_t rc; \
- \
- /* Initialize data in case of error */ \
- *data = (type)0xffffffff; \
- \
- rc = p7ioc_pcicfg_check(p, bdfn, offset, sizeof(type)); \
- if (rc) \
- return rc; \
- \
- if (p7ioc_phb_fenced(p)) { \
- if (!(p->flags & P7IOC_PHB_CFG_USE_ASB)) \
- return OPAL_HARDWARE; \
- \
- base = p->regs_asb; \
- } else if ((p->flags & P7IOC_PHB_CFG_BLOCKED) && bdfn != 0) { \
- return OPAL_HARDWARE; \
- } \
- \
- addr = PHB_CA_ENABLE; \
- addr = SETFIELD(PHB_CA_BDFN, addr, bdfn); \
- addr = SETFIELD(PHB_CA_REG, addr, offset); \
- out_be64(base + PHB_CONFIG_ADDRESS, addr); \
- *data = in_le##size(base + PHB_CONFIG_DATA + \
- (offset & (4 - sizeof(type)))); \
- \
- return OPAL_SUCCESS; \
-}
-
-#define P7IOC_PCI_CFG_WRITE(size, type) \
-static int64_t p7ioc_pcicfg_write##size(struct phb *phb, uint32_t bdfn, \
- uint32_t offset, type data) \
-{ \
- struct p7ioc_phb *p = phb_to_p7ioc_phb(phb); \
- void *base = p->regs; \
- uint64_t addr; \
- int64_t rc; \
- \
- rc = p7ioc_pcicfg_check(p, bdfn, offset, sizeof(type)); \
- if (rc) \
- return rc; \
- \
- if (p7ioc_phb_fenced(p)) { \
- if (!(p->flags & P7IOC_PHB_CFG_USE_ASB)) \
- return OPAL_HARDWARE; \
- \
- base = p->regs_asb; \
- } else if ((p->flags & P7IOC_PHB_CFG_BLOCKED) && bdfn != 0) { \
- return OPAL_HARDWARE; \
- } \
- \
- addr = PHB_CA_ENABLE; \
- addr = SETFIELD(PHB_CA_BDFN, addr, bdfn); \
- addr = SETFIELD(PHB_CA_REG, addr, offset); \
- out_be64(base + PHB_CONFIG_ADDRESS, addr); \
- out_le##size(base + PHB_CONFIG_DATA + \
- (offset & (4 - sizeof(type))), data); \
- \
- return OPAL_SUCCESS; \
-}
-
-P7IOC_PCI_CFG_READ(8, uint8_t)
-P7IOC_PCI_CFG_READ(16, uint16_t)
-P7IOC_PCI_CFG_READ(32, uint32_t)
-P7IOC_PCI_CFG_WRITE(8, uint8_t)
-P7IOC_PCI_CFG_WRITE(16, uint16_t)
-P7IOC_PCI_CFG_WRITE(32, uint32_t)
-
-static void p7ioc_eeh_read_phb_status(struct p7ioc_phb *p,
- struct OpalIoP7IOCPhbErrorData *stat)
-{
- uint16_t tmp16;
- unsigned int i;
-
- memset(stat, 0, sizeof(struct OpalIoP7IOCPhbErrorData));
-
-
- /* Error data common part */
- stat->common.version = OPAL_PHB_ERROR_DATA_VERSION_1;
- stat->common.ioType = OPAL_PHB_ERROR_DATA_TYPE_P7IOC;
- stat->common.len = sizeof(struct OpalIoP7IOCPhbErrorData);
-
- /*
- * We read some registers using config space through AIB.
- *
- * Get to other registers using ASB when possible to get to them
- * through a fence if one is present.
- *
- * Note that the OpalIoP7IOCPhbErrorData has oddities, such as the
- * bridge control being 32-bit and the UTL registers being 32-bit
- * (which they really are, but they use the top 32-bit of a 64-bit
- * register so we need to be a bit careful).
- */
-
- /* Use ASB to access PCICFG if the PHB has been fenced */
- p->flags |= P7IOC_PHB_CFG_USE_ASB;
-
- /* Grab RC bridge control, make it 32-bit */
- p7ioc_pcicfg_read16(&p->phb, 0, PCI_CFG_BRCTL, &tmp16);
- stat->brdgCtl = tmp16;
-
- /* Grab UTL status registers */
- stat->portStatusReg = hi32(in_be64(p->regs_asb
- + UTL_PCIE_PORT_STATUS));
- stat->rootCmplxStatus = hi32(in_be64(p->regs_asb
- + UTL_RC_STATUS));
- stat->busAgentStatus = hi32(in_be64(p->regs_asb
- + UTL_SYS_BUS_AGENT_STATUS));
-
- /*
- * Grab various RC PCIe capability registers. All device, slot
- * and link status are 16-bit, so we grab the pair control+status
- * for each of them
- */
- p7ioc_pcicfg_read32(&p->phb, 0, p->ecap + PCICAP_EXP_DEVCTL,
- &stat->deviceStatus);
- p7ioc_pcicfg_read32(&p->phb, 0, p->ecap + PCICAP_EXP_SLOTCTL,
- &stat->slotStatus);
- p7ioc_pcicfg_read32(&p->phb, 0, p->ecap + PCICAP_EXP_LCTL,
- &stat->linkStatus);
-
- /*
- * I assume those are the standard config space header, cmd & status
- * together makes 32-bit. Secondary status is 16-bit so I'll clear
- * the top on that one
- */
- p7ioc_pcicfg_read32(&p->phb, 0, PCI_CFG_CMD, &stat->devCmdStatus);
- p7ioc_pcicfg_read16(&p->phb, 0, PCI_CFG_SECONDARY_STATUS, &tmp16);
- stat->devSecStatus = tmp16;
-
- /* Grab a bunch of AER regs */
- p7ioc_pcicfg_read32(&p->phb, 0, p->aercap + PCIECAP_AER_RERR_STA,
- &stat->rootErrorStatus);
- p7ioc_pcicfg_read32(&p->phb, 0, p->aercap + PCIECAP_AER_UE_STATUS,
- &stat->uncorrErrorStatus);
- p7ioc_pcicfg_read32(&p->phb, 0, p->aercap + PCIECAP_AER_CE_STATUS,
- &stat->corrErrorStatus);
- p7ioc_pcicfg_read32(&p->phb, 0, p->aercap + PCIECAP_AER_HDR_LOG0,
- &stat->tlpHdr1);
- p7ioc_pcicfg_read32(&p->phb, 0, p->aercap + PCIECAP_AER_HDR_LOG1,
- &stat->tlpHdr2);
- p7ioc_pcicfg_read32(&p->phb, 0, p->aercap + PCIECAP_AER_HDR_LOG2,
- &stat->tlpHdr3);
- p7ioc_pcicfg_read32(&p->phb, 0, p->aercap + PCIECAP_AER_HDR_LOG3,
- &stat->tlpHdr4);
- p7ioc_pcicfg_read32(&p->phb, 0, p->aercap + PCIECAP_AER_SRCID,
- &stat->sourceId);
-
- /* Restore to AIB */
- p->flags &= ~P7IOC_PHB_CFG_USE_ASB;
-
- /*
- * No idea what that that is supposed to be, opal.h says
- * "Record data about the call to allocate a buffer."
- *
- * Let's leave them alone for now...
- *
- * uint64_t errorClass;
- * uint64_t correlator;
- */
-
- /* P7IOC MMIO Error Regs */
- stat->p7iocPlssr = in_be64(p->regs_asb + PHB_CPU_LOADSTORE_STATUS);
- stat->p7iocCsr = in_be64(p->regs_asb + PHB_DMA_CHAN_STATUS);
- stat->lemFir = in_be64(p->regs_asb + PHB_LEM_FIR_ACCUM);
- stat->lemErrorMask = in_be64(p->regs_asb + PHB_LEM_ERROR_MASK);
- stat->lemWOF = in_be64(p->regs_asb + PHB_LEM_WOF);
- stat->phbErrorStatus = in_be64(p->regs_asb + PHB_ERR_STATUS);
- stat->phbFirstErrorStatus = in_be64(p->regs_asb + PHB_ERR1_STATUS);
- stat->phbErrorLog0 = in_be64(p->regs_asb + PHB_ERR_LOG_0);
- stat->phbErrorLog1 = in_be64(p->regs_asb + PHB_ERR_LOG_1);
- stat->mmioErrorStatus = in_be64(p->regs_asb + PHB_OUT_ERR_STATUS);
- stat->mmioFirstErrorStatus = in_be64(p->regs_asb + PHB_OUT_ERR1_STATUS);
- stat->mmioErrorLog0 = in_be64(p->regs_asb + PHB_OUT_ERR_LOG_0);
- stat->mmioErrorLog1 = in_be64(p->regs_asb + PHB_OUT_ERR_LOG_1);
- stat->dma0ErrorStatus = in_be64(p->regs_asb + PHB_INA_ERR_STATUS);
- stat->dma0FirstErrorStatus = in_be64(p->regs_asb + PHB_INA_ERR1_STATUS);
- stat->dma0ErrorLog0 = in_be64(p->regs_asb + PHB_INA_ERR_LOG_0);
- stat->dma0ErrorLog1 = in_be64(p->regs_asb + PHB_INA_ERR_LOG_1);
- stat->dma1ErrorStatus = in_be64(p->regs_asb + PHB_INB_ERR_STATUS);
- stat->dma1FirstErrorStatus = in_be64(p->regs_asb + PHB_INB_ERR1_STATUS);
- stat->dma1ErrorLog0 = in_be64(p->regs_asb + PHB_INB_ERR_LOG_0);
- stat->dma1ErrorLog1 = in_be64(p->regs_asb + PHB_INB_ERR_LOG_1);
-
- /* Grab PESTA & B content */
- p7ioc_phb_ioda_sel(p, IODA_TBL_PESTA, 0, true);
- for (i = 0; i < OPAL_P7IOC_NUM_PEST_REGS; i++)
- stat->pestA[i] = in_be64(p->regs_asb + PHB_IODA_DATA0);
- p7ioc_phb_ioda_sel(p, IODA_TBL_PESTB, 0, true);
- for (i = 0; i < OPAL_P7IOC_NUM_PEST_REGS; i++)
- stat->pestB[i] = in_be64(p->regs_asb + PHB_IODA_DATA0);
-}
-
-static int64_t p7ioc_eeh_freeze_status(struct phb *phb, uint64_t pe_number,
- uint8_t *freeze_state,
- uint16_t *pci_error_type,
- uint16_t *severity)
-{
- struct p7ioc_phb *p = phb_to_p7ioc_phb(phb);
- uint64_t peev_bit = PPC_BIT(pe_number & 0x3f);
- uint64_t peev, pesta, pestb;
-
- /* Defaults: not frozen */
- *freeze_state = OPAL_EEH_STOPPED_NOT_FROZEN;
- *pci_error_type = OPAL_EEH_NO_ERROR;
-
- /* Check dead */
- if (p->broken) {
- *freeze_state = OPAL_EEH_STOPPED_MMIO_DMA_FREEZE;
- *pci_error_type = OPAL_EEH_PHB_ERROR;
- if (severity)
- *severity = OPAL_EEH_SEV_PHB_DEAD;
- return OPAL_SUCCESS;
- }
-
- /* Check fence */
- if (p7ioc_phb_fenced(p)) {
- /* Should be OPAL_EEH_STOPPED_TEMP_UNAVAIL ? */
- *freeze_state = OPAL_EEH_STOPPED_MMIO_DMA_FREEZE;
- *pci_error_type = OPAL_EEH_PHB_ERROR;
- if (severity)
- *severity = OPAL_EEH_SEV_PHB_FENCED;
- return OPAL_SUCCESS;
- }
-
- /* Check the PEEV */
- p7ioc_phb_ioda_sel(p, IODA_TBL_PEEV, 0, true);
- peev = in_be64(p->regs + PHB_IODA_DATA0);
- if (pe_number > 63)
- peev = in_be64(p->regs + PHB_IODA_DATA0);
- if (!(peev & peev_bit))
- return OPAL_SUCCESS;
-
- /* Indicate that we have an ER pending */
- p7ioc_phb_set_err_pending(p, true);
- if (severity)
- *severity = OPAL_EEH_SEV_PE_ER;
-
- /* Read the PESTA & PESTB */
- p7ioc_phb_ioda_sel(p, IODA_TBL_PESTA, pe_number, false);
- pesta = in_be64(p->regs + PHB_IODA_DATA0);
- p7ioc_phb_ioda_sel(p, IODA_TBL_PESTB, pe_number, false);
- pestb = in_be64(p->regs + PHB_IODA_DATA0);
-
- /* Convert them */
- if (pesta & IODA_PESTA_MMIO_FROZEN)
- *freeze_state |= OPAL_EEH_STOPPED_MMIO_FREEZE;
- if (pestb & IODA_PESTB_DMA_STOPPED)
- *freeze_state |= OPAL_EEH_STOPPED_DMA_FREEZE;
-
- /* XXX Handle more causes */
- if (pesta & IODA_PESTA_MMIO_CAUSE)
- *pci_error_type = OPAL_EEH_PE_MMIO_ERROR;
- else
- *pci_error_type = OPAL_EEH_PE_DMA_ERROR;
-
- return OPAL_SUCCESS;
-}
-
-static int64_t p7ioc_eeh_next_error(struct phb *phb, uint64_t *first_frozen_pe,
- uint16_t *pci_error_type, uint16_t *severity)
-{
- struct p7ioc_phb *p = phb_to_p7ioc_phb(phb);
- struct p7ioc *ioc = p->ioc;
- uint64_t fir, peev0, peev1;
- uint32_t cfg32, i;
-
- /* Check if there're pending errors on the IOC. */
- if (p7ioc_err_pending(ioc) &&
- p7ioc_check_LEM(ioc, pci_error_type, severity))
- return OPAL_SUCCESS;
-
- /* Clear result */
- *pci_error_type = OPAL_EEH_NO_ERROR;
- *severity = OPAL_EEH_SEV_NO_ERROR;
- *first_frozen_pe = (uint64_t)-1;
-
- /* Check dead */
- if (p->broken) {
- *pci_error_type = OPAL_EEH_PHB_ERROR;
- *severity = OPAL_EEH_SEV_PHB_DEAD;
- return OPAL_SUCCESS;
- }
-
- /* Check fence */
- if (p7ioc_phb_fenced(p)) {
- /* Should be OPAL_EEH_STOPPED_TEMP_UNAVAIL ? */
- *pci_error_type = OPAL_EEH_PHB_ERROR;
- *severity = OPAL_EEH_SEV_PHB_FENCED;
- p7ioc_phb_set_err_pending(p, false);
- return OPAL_SUCCESS;
- }
-
- /*
- * If we don't have pending errors, which might be moved
- * from IOC to the PHB, then check if there has any frozen PEs.
- */
- if (!p7ioc_phb_err_pending(p)) {
- p7ioc_phb_ioda_sel(p, IODA_TBL_PEEV, 0, true);
- peev0 = in_be64(p->regs + PHB_IODA_DATA0);
- peev1 = in_be64(p->regs + PHB_IODA_DATA0);
- if (peev0 || peev1) {
- p->err.err_src = P7IOC_ERR_SRC_PHB0 + p->index;
- p->err.err_class = P7IOC_ERR_CLASS_ER;
- p->err.err_bit = 0;
- p7ioc_phb_set_err_pending(p, true);
- }
- }
-
- /* Check the pending errors, which might come from IOC */
- if (p7ioc_phb_err_pending(p)) {
- /*
- * If the frozen PE is caused by a malfunctioning TLP, we
- * need reset the PHB. So convert ER to PHB-fatal error
- * for the case.
- */
- if (p->err.err_class == P7IOC_ERR_CLASS_ER) {
- fir = in_be64(p->regs_asb + PHB_LEM_FIR_ACCUM);
- if (fir & PPC_BIT(60)) {
- p7ioc_pcicfg_read32(&p->phb, 0,
- p->aercap + PCIECAP_AER_UE_STATUS, &cfg32);
- if (cfg32 & PCIECAP_AER_UE_MALFORMED_TLP)
- p->err.err_class = P7IOC_ERR_CLASS_PHB;
- }
- }
-
- /*
- * Map P7IOC internal error class to that one OS can handle.
- * For P7IOC_ERR_CLASS_ER, we also need figure out the frozen
- * PE.
- */
- switch (p->err.err_class) {
- case P7IOC_ERR_CLASS_PHB:
- *pci_error_type = OPAL_EEH_PHB_ERROR;
- *severity = OPAL_EEH_SEV_PHB_FENCED;
- p7ioc_phb_set_err_pending(p, false);
- break;
- case P7IOC_ERR_CLASS_MAL:
- case P7IOC_ERR_CLASS_INF:
- *pci_error_type = OPAL_EEH_PHB_ERROR;
- *severity = OPAL_EEH_SEV_INF;
- p7ioc_phb_set_err_pending(p, false);
- break;
- case P7IOC_ERR_CLASS_ER:
- *pci_error_type = OPAL_EEH_PE_ERROR;
- *severity = OPAL_EEH_SEV_PE_ER;
- p7ioc_phb_ioda_sel(p, IODA_TBL_PEEV, 0, true);
- peev0 = in_be64(p->regs + PHB_IODA_DATA0);
- peev1 = in_be64(p->regs + PHB_IODA_DATA0);
-
- for (i = 0 ; i < 64; i++) {
- if (PPC_BIT(i) & peev1) {
- *first_frozen_pe = i + 64;
- break;
- }
- }
- for (i = 0 ;
- *first_frozen_pe == (uint64_t)-1 && i < 64;
- i++) {
- if (PPC_BIT(i) & peev0) {
- *first_frozen_pe = i;
- break;
- }
- }
-
- /* No frozen PE? */
- if (*first_frozen_pe == (uint64_t)-1) {
- *pci_error_type = OPAL_EEH_NO_ERROR;
- *severity = OPAL_EEH_SEV_NO_ERROR;
- p7ioc_phb_set_err_pending(p, false);
- }
-
- break;
- default:
- *pci_error_type = OPAL_EEH_NO_ERROR;
- *severity = OPAL_EEH_SEV_NO_ERROR;
- p7ioc_phb_set_err_pending(p, false);
- }
- }
-
- return OPAL_SUCCESS;
-}
-
-static void p7ioc_ER_err_clear(struct p7ioc_phb *p)
-{
- u64 err, lem;
- u32 val;
-
- /* Rec 1,2 */
- lem = in_be64(p->regs + PHB_LEM_FIR_ACCUM);
-
- /* Rec 3,4,5 AER registers (could use cfg space accessors) */
- out_be64(p->regs + PHB_CONFIG_ADDRESS, 0x8000001c00000000ull);
- out_be32(p->regs + PHB_CONFIG_DATA, 0x10000000);
-
- /* Rec 6,7,8 XXX DOC whacks payload & req size ... we don't */
- out_be64(p->regs + PHB_CONFIG_ADDRESS, 0x8000005000000000ull);
- val = in_be32(p->regs + PHB_CONFIG_DATA);
- out_be32(p->regs + PHB_CONFIG_DATA, (val & 0xe0700000) | 0x0f000f00);
-
- /* Rec 9,10,11 */
- out_be64(p->regs + PHB_CONFIG_ADDRESS, 0x8000010400000000ull);
- out_be32(p->regs + PHB_CONFIG_DATA, 0xffffffff);
-
- /* Rec 12,13,14 */
- out_be64(p->regs + PHB_CONFIG_ADDRESS, 0x8000011000000000ull);
- out_be32(p->regs + PHB_CONFIG_DATA, 0xffffffff);
-
- /* Rec 23,24,25 */
- out_be64(p->regs + PHB_CONFIG_ADDRESS, 0x8000013000000000ull);
- out_be32(p->regs + PHB_CONFIG_DATA, 0xffffffff);
-
- /* Rec 26,27,28 */
- out_be64(p->regs + PHB_CONFIG_ADDRESS, 0x8000004000000000ull);
- out_be32(p->regs + PHB_CONFIG_DATA, 0x470100f8);
-
- /* Rec 29..34 UTL registers */
- err = in_be64(p->regs + UTL_SYS_BUS_AGENT_STATUS);
- out_be64(p->regs + UTL_SYS_BUS_AGENT_STATUS, err);
- err = in_be64(p->regs + UTL_PCIE_PORT_STATUS);
- out_be64(p->regs + UTL_PCIE_PORT_STATUS, err);
- err = in_be64(p->regs + UTL_RC_STATUS);
- out_be64(p->regs + UTL_RC_STATUS, err);
-
- /* PHB error traps registers */
- err = in_be64(p->regs + PHB_ERR_STATUS);
- out_be64(p->regs + PHB_ERR_STATUS, err);
- out_be64(p->regs + PHB_ERR1_STATUS, 0);
- out_be64(p->regs + PHB_ERR_LOG_0, 0);
- out_be64(p->regs + PHB_ERR_LOG_1, 0);
-
- err = in_be64(p->regs + PHB_OUT_ERR_STATUS);
- out_be64(p->regs + PHB_OUT_ERR_STATUS, err);
- out_be64(p->regs + PHB_OUT_ERR1_STATUS, 0);
- out_be64(p->regs + PHB_OUT_ERR_LOG_0, 0);
- out_be64(p->regs + PHB_OUT_ERR_LOG_1, 0);
-
- err = in_be64(p->regs + PHB_INA_ERR_STATUS);
- out_be64(p->regs + PHB_INA_ERR_STATUS, err);
- out_be64(p->regs + PHB_INA_ERR1_STATUS, 0);
- out_be64(p->regs + PHB_INA_ERR_LOG_0, 0);
- out_be64(p->regs + PHB_INA_ERR_LOG_1, 0);
-
- err = in_be64(p->regs + PHB_INB_ERR_STATUS);
- out_be64(p->regs + PHB_INB_ERR_STATUS, err);
- out_be64(p->regs + PHB_INB_ERR1_STATUS, 0);
- out_be64(p->regs + PHB_INB_ERR_LOG_0, 0);
- out_be64(p->regs + PHB_INB_ERR_LOG_1, 0);
-
- /* Rec 67, 68 LEM */
- out_be64(p->regs + PHB_LEM_FIR_AND_MASK, ~lem);
- out_be64(p->regs + PHB_LEM_WOF, 0);
-}
-
-static int64_t p7ioc_eeh_freeze_clear(struct phb *phb, uint64_t pe_number,
- uint64_t eeh_action_token)
-{
- struct p7ioc_phb *p = phb_to_p7ioc_phb(phb);
- uint64_t peev0, peev1;
-
- /* XXX Now this is a heavy hammer, coming roughly from the P7IOC doc
- * and my old "pseudopal" code. It will need to be refined. In general
- * error handling will have to be reviewed and probably done properly
- * "from scratch" based on the description in the p7IOC spec.
- *
- * XXX Additionally, when handling interrupts, we might want to consider
- * masking while processing and/or ack'ing interrupt bits etc...
- */
- u64 err;
-
- /* Summary. If nothing, move to clearing the PESTs which can
- * contain a freeze state from a previous error or simply set
- * explicitly by the user
- */
- err = in_be64(p->regs + PHB_ETU_ERR_SUMMARY);
- if (err == 0)
- goto clear_pest;
-
- p7ioc_ER_err_clear(p);
-
- clear_pest:
- /* XXX We just clear the whole PESTA for MMIO clear and PESTB
- * for DMA clear. We might want to only clear the frozen bit
- * as to not clobber the rest of the state. However, we expect
- * the state to have been harvested before the clear operations
- * so this might not be an issue
- */
- if (eeh_action_token & OPAL_EEH_ACTION_CLEAR_FREEZE_MMIO) {
- p7ioc_phb_ioda_sel(p, IODA_TBL_PESTA, pe_number, false);
- out_be64(p->regs + PHB_IODA_DATA0, 0);
- }
- if (eeh_action_token & OPAL_EEH_ACTION_CLEAR_FREEZE_DMA) {
- p7ioc_phb_ioda_sel(p, IODA_TBL_PESTB, pe_number, false);
- out_be64(p->regs + PHB_IODA_DATA0, 0);
- }
-
- /* Update ER pending indication */
- p7ioc_phb_ioda_sel(p, IODA_TBL_PEEV, 0, true);
- peev0 = in_be64(p->regs + PHB_IODA_DATA0);
- peev1 = in_be64(p->regs + PHB_IODA_DATA0);
- if (peev0 || peev1) {
- p->err.err_src = P7IOC_ERR_SRC_PHB0 + p->index;
- p->err.err_class = P7IOC_ERR_CLASS_ER;
- p->err.err_bit = 0;
- p7ioc_phb_set_err_pending(p, true);
- } else
- p7ioc_phb_set_err_pending(p, false);
-
- return OPAL_SUCCESS;
-}
-
-static int64_t p7ioc_eeh_freeze_set(struct phb *phb, uint64_t pe_number,
- uint64_t eeh_action_token)
-{
- struct p7ioc_phb *p = phb_to_p7ioc_phb(phb);
- uint64_t data;
-
- if (pe_number > 127)
- return OPAL_PARAMETER;
-
- if (eeh_action_token != OPAL_EEH_ACTION_SET_FREEZE_MMIO &&
- eeh_action_token != OPAL_EEH_ACTION_SET_FREEZE_DMA &&
- eeh_action_token != OPAL_EEH_ACTION_SET_FREEZE_ALL)
- return OPAL_PARAMETER;
-
- if (eeh_action_token & OPAL_EEH_ACTION_SET_FREEZE_MMIO) {
- p7ioc_phb_ioda_sel(p, IODA_TBL_PESTA, pe_number, false);
- data = in_be64(p->regs + PHB_IODA_DATA0);
- data |= IODA_PESTA_MMIO_FROZEN;
- out_be64(p->regs + PHB_IODA_DATA0, data);
- }
-
- if (eeh_action_token & OPAL_EEH_ACTION_SET_FREEZE_DMA) {
- p7ioc_phb_ioda_sel(p, IODA_TBL_PESTB, pe_number, false);
- data = in_be64(p->regs + PHB_IODA_DATA0);
- data |= IODA_PESTB_DMA_STOPPED;
- out_be64(p->regs + PHB_IODA_DATA0, data);
- }
-
- return OPAL_SUCCESS;
-}
-
-static int64_t p7ioc_err_inject_finalize(struct p7ioc_phb *p, uint64_t addr,
- uint64_t mask, uint64_t ctrl,
- bool is_write)
-{
- if (is_write)
- ctrl |= PHB_PAPR_ERR_INJ_CTL_WR;
- else
- ctrl |= PHB_PAPR_ERR_INJ_CTL_RD;
-
- /* HW100549: Take read and write for outbound errors
- * on DD10 chip
- */
- if (p->rev == P7IOC_REV_DD10)
- ctrl |= (PHB_PAPR_ERR_INJ_CTL_RD | PHB_PAPR_ERR_INJ_CTL_WR);
-
- out_be64(p->regs + PHB_PAPR_ERR_INJ_ADDR, addr);
- out_be64(p->regs + PHB_PAPR_ERR_INJ_MASK, mask);
- out_be64(p->regs + PHB_PAPR_ERR_INJ_CTL, ctrl);
-
- return OPAL_SUCCESS;
-}
-
-static int64_t p7ioc_err_inject_mem32(struct p7ioc_phb *p, uint64_t pe_number,
- uint64_t addr, uint64_t mask,
- bool is_write)
-{
- uint64_t a, m, prefer, base;
- uint64_t ctrl = PHB_PAPR_ERR_INJ_CTL_OUTB;
- int32_t index;
-
- a = 0x0ull;
- prefer = 0x0ull;
- for (index = 0; index < 128; index++) {
- if (GETFIELD(IODA_XXDT_PE, p->m32d_cache[index]) != pe_number)
- continue;
-
- base = p->m32_base + M32_PCI_START +
- (M32_PCI_SIZE / 128) * index;
-
- /* Update preferred address */
- if (!prefer) {
- prefer = GETFIELD(PHB_PAPR_ERR_INJ_MASK_MMIO, base);
- prefer = SETFIELD(PHB_PAPR_ERR_INJ_MASK_MMIO,
- 0x0ull, prefer);
- }
-
- /* The input address matches ? */
- if (addr >= base &&
- addr < base + (M32_PCI_SIZE / 128)) {
- a = addr;
- break;
- }
- }
-
- /* Invalid PE number */
- if (!prefer)
- return OPAL_PARAMETER;
-
- /* Specified address is out of range */
- if (!a) {
- a = prefer;
- m = PHB_PAPR_ERR_INJ_MASK_MMIO;
- } else {
- m = mask;
- }
-
- return p7ioc_err_inject_finalize(p, a, m, ctrl, is_write);
-}
-
-static int64_t p7ioc_err_inject_io32(struct p7ioc_phb *p, uint64_t pe_number,
- uint64_t addr, uint64_t mask,
- bool is_write)
-{
- uint64_t a, m, prefer, base;
- uint64_t ctrl = PHB_PAPR_ERR_INJ_CTL_OUTB;
- int32_t index;
-
- a = 0x0ull;
- prefer = 0x0ull;
- for (index = 0; index < 128; index++) {
- if (GETFIELD(IODA_XXDT_PE, p->iod_cache[index]) != pe_number)
- continue;
-
- base = p->io_base + (PHB_IO_SIZE / 128) * index;
-
- /* Update preferred address */
- if (!prefer) {
- prefer = GETFIELD(PHB_PAPR_ERR_INJ_MASK_IO, base);
- prefer = SETFIELD(PHB_PAPR_ERR_INJ_MASK_IO, 0x0ull, prefer);
- }
-
- /* The input address matches ? */
- if (addr >= base &&
- addr < base + (PHB_IO_SIZE / 128)) {
- a = addr;
- break;
- }
- }
-
- /* Invalid PE number */
- if (!prefer)
- return OPAL_PARAMETER;
-
- /* Specified address is out of range */
- if (!a) {
- a = prefer;
- m = PHB_PAPR_ERR_INJ_MASK_IO;
- } else {
- m = mask;
- }
-
- return p7ioc_err_inject_finalize(p, a, m, ctrl, is_write);
-}
-
-static int64_t p7ioc_err_inject_cfg(struct p7ioc_phb *p, uint64_t pe_number,
- uint64_t addr, uint64_t mask,
- bool is_write)
-{
- uint64_t a, m;
- uint64_t ctrl = PHB_PAPR_ERR_INJ_CTL_CFG;
- uint8_t v_bits, base, bus_no;
-
- /* Looking into PELTM to see if the PCI bus# is owned
- * by the PE#. Otherwise, we have to figure one out.
- */
- base = GETFIELD(IODA_PELTM_BUS, p->peltm_cache[pe_number]);
- v_bits = GETFIELD(IODA_PELTM_BUS_VALID, p->peltm_cache[pe_number]);
- switch (v_bits) {
- case IODA_BUS_VALID_3_BITS:
- case IODA_BUS_VALID_4_BITS:
- case IODA_BUS_VALID_5_BITS:
- case IODA_BUS_VALID_6_BITS:
- case IODA_BUS_VALID_7_BITS:
- case IODA_BUS_VALID_ALL:
- base = GETFIELD(IODA_PELTM_BUS, p->peltm_cache[pe_number]);
- base &= (0xff - (((1 << (7 - v_bits)) - 1)));
- a = SETFIELD(PHB_PAPR_ERR_INJ_MASK_CFG, 0x0ul, base);
- m = PHB_PAPR_ERR_INJ_MASK_CFG;
-
- bus_no = GETFIELD(PHB_PAPR_ERR_INJ_MASK_CFG, addr);
- bus_no &= (0xff - (((1 << (7 - v_bits)) - 1)));
- if (base == bus_no) {
- a = addr;
- m = mask;
- }
-
- break;
- case IODA_BUS_VALID_ANY:
- default:
- return OPAL_PARAMETER;
- }
-
- return p7ioc_err_inject_finalize(p, a, m, ctrl, is_write);
-}
-
-static int64_t p7ioc_err_inject_dma(struct p7ioc_phb *p, uint64_t pe_number,
- uint64_t addr, uint64_t mask,
- bool is_write)
-{
- uint64_t ctrl = PHB_PAPR_ERR_INJ_CTL_INB;
- int32_t index;
-
- /* For DMA, we just pick address from TVT */
- for (index = 0; index < 128; index++) {
- if (GETFIELD(IODA_TVT1_PE_NUM, p->tve_hi_cache[index]) !=
- pe_number)
- continue;
-
- addr = SETFIELD(PHB_PAPR_ERR_INJ_MASK_DMA, 0ul, index);
- mask = PHB_PAPR_ERR_INJ_MASK_DMA;
- break;
- }
-
- /* Some PE might not have DMA capability */
- if (index >= 128)
- return OPAL_PARAMETER;
-
- return p7ioc_err_inject_finalize(p, addr, mask, ctrl, is_write);
-}
-
-static int64_t p7ioc_err_inject(struct phb *phb, uint64_t pe_number,
- uint32_t type, uint32_t func,
- uint64_t addr, uint64_t mask)
-{
- struct p7ioc_phb *p = phb_to_p7ioc_phb(phb);
- int64_t (*handler)(struct p7ioc_phb *p, uint64_t pe_number,
- uint64_t addr, uint64_t mask, bool is_write);
- bool is_write;
-
- /* To support 64-bits error later */
- if (type == OPAL_ERR_INJECT_TYPE_IOA_BUS_ERR64)
- return OPAL_UNSUPPORTED;
-
- /* We can't inject error to the reserved PE#127 */
- if (pe_number > 126)
- return OPAL_PARAMETER;
-
- /* Clear the leftover from last time */
- out_be64(p->regs + PHB_PAPR_ERR_INJ_CTL, 0x0ul);
-
- /* Check if PE number is valid one in PELTM cache */
- if (p->peltm_cache[pe_number] == 0x0001f80000000000ull)
- return OPAL_PARAMETER;
-
- /* Clear the leftover from last time */
- out_be64(p->regs + PHB_PAPR_ERR_INJ_CTL, 0x0ul);
-
- switch (func) {
- case OPAL_ERR_INJECT_FUNC_IOA_LD_MEM_ADDR:
- case OPAL_ERR_INJECT_FUNC_IOA_LD_MEM_DATA:
- is_write = false;
- handler = p7ioc_err_inject_mem32;
- break;
- case OPAL_ERR_INJECT_FUNC_IOA_ST_MEM_ADDR:
- case OPAL_ERR_INJECT_FUNC_IOA_ST_MEM_DATA:
- is_write = true;
- handler = p7ioc_err_inject_mem32;
- break;
- case OPAL_ERR_INJECT_FUNC_IOA_LD_IO_ADDR:
- case OPAL_ERR_INJECT_FUNC_IOA_LD_IO_DATA:
- is_write = false;
- handler = p7ioc_err_inject_io32;
- break;
- case OPAL_ERR_INJECT_FUNC_IOA_ST_IO_ADDR:
- case OPAL_ERR_INJECT_FUNC_IOA_ST_IO_DATA:
- is_write = true;
- handler = p7ioc_err_inject_io32;
- break;
- case OPAL_ERR_INJECT_FUNC_IOA_LD_CFG_ADDR:
- case OPAL_ERR_INJECT_FUNC_IOA_LD_CFG_DATA:
- is_write = false;
- handler = p7ioc_err_inject_cfg;
- break;
- case OPAL_ERR_INJECT_FUNC_IOA_ST_CFG_ADDR:
- case OPAL_ERR_INJECT_FUNC_IOA_ST_CFG_DATA:
- is_write = true;
- handler = p7ioc_err_inject_cfg;
- break;
- case OPAL_ERR_INJECT_FUNC_IOA_DMA_RD_ADDR:
- case OPAL_ERR_INJECT_FUNC_IOA_DMA_RD_DATA:
- case OPAL_ERR_INJECT_FUNC_IOA_DMA_RD_MASTER:
- case OPAL_ERR_INJECT_FUNC_IOA_DMA_RD_TARGET:
- is_write = false;
- handler = p7ioc_err_inject_dma;
- break;
- case OPAL_ERR_INJECT_FUNC_IOA_DMA_WR_ADDR:
- case OPAL_ERR_INJECT_FUNC_IOA_DMA_WR_DATA:
- case OPAL_ERR_INJECT_FUNC_IOA_DMA_WR_MASTER:
- case OPAL_ERR_INJECT_FUNC_IOA_DMA_WR_TARGET:
- is_write = true;
- handler = p7ioc_err_inject_dma;
- break;
- default:
- return OPAL_PARAMETER;
- }
-
- return handler(p, pe_number, addr, mask, is_write);
-}
-
-static int64_t p7ioc_get_diag_data(struct phb *phb, void *diag_buffer,
- uint64_t diag_buffer_len)
-{
- struct p7ioc_phb *p = phb_to_p7ioc_phb(phb);
- struct OpalIoP7IOCPhbErrorData *diag = diag_buffer;
-
- if (diag_buffer_len < sizeof(struct OpalIoP7IOCPhbErrorData))
- return OPAL_PARAMETER;
-
- /* Specific error data */
- p7ioc_eeh_read_phb_status(p, diag);
-
- /*
- * We're running to here probably because of errors (MAL
- * or INF class) from IOC. For the case, we need clear
- * the pending errors and mask the error bit for MAL class
- * error. Fortunately, we shouldn't get MAL class error from
- * IOC on P7IOC.
- */
- if (p7ioc_phb_err_pending(p) &&
- p->err.err_class == P7IOC_ERR_CLASS_INF &&
- p->err.err_src >= P7IOC_ERR_SRC_PHB0 &&
- p->err.err_src <= P7IOC_ERR_SRC_PHB5) {
- p7ioc_ER_err_clear(p);
- p7ioc_phb_set_err_pending(p, false);
- }
-
- return OPAL_SUCCESS;
-}
-
-/*
- * We don't support address remapping now since all M64
- * BARs are sharing on remapping base address. We might
- * introduce flag to the PHB in order to trace that. The
- * flag allows to be changed for once. It's something to
- * do in future.
- */
-static int64_t p7ioc_set_phb_mem_window(struct phb *phb,
- uint16_t window_type,
- uint16_t window_num,
- uint64_t base,
- uint64_t __unused pci_base,
- uint64_t size)
-{
- struct p7ioc_phb *p = phb_to_p7ioc_phb(phb);
- uint64_t data64;
-
- switch (window_type) {
- case OPAL_IO_WINDOW_TYPE:
- case OPAL_M32_WINDOW_TYPE:
- return OPAL_UNSUPPORTED;
- case OPAL_M64_WINDOW_TYPE:
- if (window_num >= 16)
- return OPAL_PARAMETER;
- /* The base and size should be 16MB aligned */
- if (base & 0xFFFFFF || size & 0xFFFFFF)
- return OPAL_PARAMETER;
- data64 = p->m64b_cache[window_num];
- data64 = SETFIELD(IODA_M64BT_BASE, data64, base >> 24);
- size = (size >> 24);
- data64 = SETFIELD(IODA_M64BT_MASK, data64, 0x1000000 - size);
- break;
- default:
- return OPAL_PARAMETER;
- }
-
- /*
- * If the M64 BAR hasn't enabled yet, we needn't flush
- * the setting to hardware and just keep it to the cache
- */
- p->m64b_cache[window_num] = data64;
- if (!(data64 & IODA_M64BT_ENABLE))
- return OPAL_SUCCESS;
- p7ioc_phb_ioda_sel(p, IODA_TBL_M64BT, window_num, false);
- out_be64(p->regs + PHB_IODA_DATA0, data64);
-
- return OPAL_SUCCESS;
-}
-
-/*
- * We can't enable or disable I/O and M32 dynamically, even
- * unnecessary. So the function only support M64 BARs.
- */
-static int64_t p7ioc_phb_mmio_enable(struct phb *phb,
- uint16_t window_type,
- uint16_t window_num,
- uint16_t enable)
-{
- struct p7ioc_phb *p = phb_to_p7ioc_phb(phb);
- uint64_t data64, base, mask;
-
- switch (window_type) {
- case OPAL_IO_WINDOW_TYPE:
- case OPAL_M32_WINDOW_TYPE:
- return OPAL_UNSUPPORTED;
- case OPAL_M64_WINDOW_TYPE:
- if (window_num >= 16 ||
- enable >= OPAL_ENABLE_M64_NON_SPLIT)
- return OPAL_PARAMETER;
-
- break;
- default:
- return OPAL_PARAMETER;
- }
-
- /*
- * While enabling one specific M64 BAR, we should have
- * the base/size configured correctly. Otherwise, it
- * probably incurs fenced AIB.
- */
- data64 = p->m64b_cache[window_num];
- if (enable == OPAL_ENABLE_M64_SPLIT) {
- base = GETFIELD(IODA_M64BT_BASE, data64);
- base = (base << 24);
- mask = GETFIELD(IODA_M64BT_MASK, data64);
- if (base < p->m64_base || mask == 0x0ul)
- return OPAL_PARTIAL;
-
- data64 |= IODA_M64BT_ENABLE;
- } else if (enable == OPAL_DISABLE_M64) {
- data64 &= ~IODA_M64BT_ENABLE;
- }
-
- p7ioc_phb_ioda_sel(p, IODA_TBL_M64BT, window_num, false);
- out_be64(p->regs + PHB_IODA_DATA0, data64);
- p->m64b_cache[window_num] = data64;
-
- return OPAL_SUCCESS;
-}
-
-static int64_t p7ioc_map_pe_mmio_window(struct phb *phb, uint64_t pe_number,
- uint16_t window_type,
- uint16_t window_num,
- uint16_t segment_num)
-{
- struct p7ioc_phb *p = phb_to_p7ioc_phb(phb);
- uint64_t tbl, index;
- uint64_t *cache;
-
- if (pe_number > 127)
- return OPAL_PARAMETER;
-
- switch(window_type) {
- case OPAL_IO_WINDOW_TYPE:
- if (window_num != 0 || segment_num > 127)
- return OPAL_PARAMETER;
- tbl = IODA_TBL_IODT;
- index = segment_num;
- cache = &p->iod_cache[index];
- break;
- case OPAL_M32_WINDOW_TYPE:
- if (window_num != 0 || segment_num > 127)
- return OPAL_PARAMETER;
- tbl = IODA_TBL_M32DT;
- index = segment_num;
- cache = &p->m32d_cache[index];
- break;
- case OPAL_M64_WINDOW_TYPE:
- if (window_num > 15 || segment_num > 7)
- return OPAL_PARAMETER;
-
- tbl = IODA_TBL_M64DT;
- index = window_num << 3 | segment_num;
- cache = &p->m64d_cache[index];
- break;
- default:
- return OPAL_PARAMETER;
- }
-
- p7ioc_phb_ioda_sel(p, tbl, index, false);
- out_be64(p->regs + PHB_IODA_DATA0,
- SETFIELD(IODA_XXDT_PE, 0ull, pe_number));
-
- /* Update cache */
- *cache = SETFIELD(IODA_XXDT_PE, 0ull, pe_number);
-
- return OPAL_SUCCESS;
-}
-
-
-static int64_t p7ioc_set_pe(struct phb *phb, uint64_t pe_number,
- uint64_t bdfn, uint8_t bus_compare,
- uint8_t dev_compare, uint8_t func_compare,
- uint8_t pe_action)
-{
- struct p7ioc_phb *p = phb_to_p7ioc_phb(phb);
- uint64_t pelt;
- uint64_t *cache = &p->peltm_cache[pe_number];
-
- if (pe_number > 127 || bdfn > 0xffff)
- return OPAL_PARAMETER;
- if (pe_action != OPAL_MAP_PE && pe_action != OPAL_UNMAP_PE)
- return OPAL_PARAMETER;
- if (bus_compare > 7)
- return OPAL_PARAMETER;
-
- if (pe_action == OPAL_MAP_PE) {
- pelt = SETFIELD(IODA_PELTM_BUS, 0ul, bdfn >> 8);
- pelt |= SETFIELD(IODA_PELTM_DEV, 0ul, (bdfn >> 3) & 0x1f);
- pelt |= SETFIELD(IODA_PELTM_FUNC, 0ul, bdfn & 0x7);
- pelt |= SETFIELD(IODA_PELTM_BUS_VALID, 0ul, bus_compare);
- if (dev_compare)
- pelt |= IODA_PELTM_DEV_VALID;
- if (func_compare)
- pelt |= IODA_PELTM_FUNC_VALID;
- } else
- pelt = 0;
-
- p7ioc_phb_ioda_sel(p, IODA_TBL_PELTM, pe_number, false);
- out_be64(p->regs + PHB_IODA_DATA0, pelt);
-
- /* Update cache */
- *cache = pelt;
-
- return OPAL_SUCCESS;
-}
-
-
-static int64_t p7ioc_set_peltv(struct phb *phb, uint32_t parent_pe,
- uint32_t child_pe, uint8_t state)
-{
- struct p7ioc_phb *p = phb_to_p7ioc_phb(phb);
- uint32_t reg;
- uint64_t mask, peltv;
- uint64_t *cache;
- if (parent_pe > 127 || child_pe > 127)
- return OPAL_PARAMETER;
-
- cache = (child_pe >> 6) ? &p->peltv_hi_cache[parent_pe] :
- &p->peltv_lo_cache[parent_pe];
- reg = (child_pe >> 6) ? PHB_IODA_DATA1 : PHB_IODA_DATA0;
- child_pe &= 0x2f;
- mask = 1ull << (63 - child_pe);
-
- p7ioc_phb_ioda_sel(p, IODA_TBL_PELTV, parent_pe, false);
- peltv = in_be64(p->regs + reg);
- if (state)
- peltv |= mask;
- else
- peltv &= ~mask;
- out_be64(p->regs + reg, peltv);
-
- /* Update cache */
- *cache = peltv;
-
- return OPAL_SUCCESS;
-}
-
-static int64_t p7ioc_map_pe_dma_window(struct phb *phb, uint64_t pe_number,
- uint16_t window_id, uint16_t tce_levels,
- uint64_t tce_table_addr,
- uint64_t tce_table_size,
- uint64_t tce_page_size)
-{
- struct p7ioc_phb *p = phb_to_p7ioc_phb(phb);
- uint64_t tvt0, tvt1, t, pelt;
- uint64_t dma_window_size;
- uint64_t *cache_lo, *cache_hi;
-
- if (pe_number > 127 || window_id > 127 || tce_levels != 1)
- return OPAL_PARAMETER;
- cache_lo = &p->tve_lo_cache[window_id];
- cache_hi = &p->tve_hi_cache[window_id];
-
- /* Encode table size */
- dma_window_size = tce_page_size * (tce_table_size >> 3);
- t = ilog2(dma_window_size);
- if (t < 27)
- return OPAL_PARAMETER;
- tvt0 = SETFIELD(IODA_TVT0_TCE_TABLE_SIZE, 0ul, (t - 26));
-
- /* Encode TCE page size */
- switch(tce_page_size) {
- case 0x1000: /* 4K */
- tvt1 = SETFIELD(IODA_TVT1_IO_PSIZE, 0ul, 1ul);
- break;
- case 0x10000: /* 64K */
- tvt1 = SETFIELD(IODA_TVT1_IO_PSIZE, 0ul, 5ul);
- break;
- case 0x1000000: /* 16M */
- tvt1 = SETFIELD(IODA_TVT1_IO_PSIZE, 0ul, 13ul);
- break;
- case 0x400000000UL: /* 16G */
- tvt1 = SETFIELD(IODA_TVT1_IO_PSIZE, 0ul, 23ul);
- break;
- default:
- return OPAL_PARAMETER;
- }
-
- /* XXX Hub number ... leave 0 for now */
-
- /* Shift in the address. The table address is "off by 4 bits"
- * but since the field is itself shifted by 16, we basically
- * need to write the address >> 12, which basically boils down
- * to writing a 4k page address
- */
- tvt0 = SETFIELD(IODA_TVT0_TABLE_ADDR, tvt0, tce_table_addr >> 12);
-
- /* Read the PE filter info from the PELT-M */
- p7ioc_phb_ioda_sel(p, IODA_TBL_PELTM, pe_number, false);
- pelt = in_be64(p->regs + PHB_IODA_DATA0);
-
- /* Copy in filter bits from PELT */
- tvt0 = SETFIELD(IODA_TVT0_BUS_VALID, tvt0,
- GETFIELD(IODA_PELTM_BUS_VALID, pelt));
- tvt0 = SETFIELD(IODA_TVT0_BUS_NUM, tvt0,
- GETFIELD(IODA_PELTM_BUS, pelt));
- tvt1 = SETFIELD(IODA_TVT1_DEV_NUM, tvt1,
- GETFIELD(IODA_PELTM_DEV, pelt));
- tvt1 = SETFIELD(IODA_TVT1_FUNC_NUM, tvt1,
- GETFIELD(IODA_PELTM_FUNC, pelt));
- if (pelt & IODA_PELTM_DEV_VALID)
- tvt1 |= IODA_TVT1_DEV_VALID;
- if (pelt & IODA_PELTM_FUNC_VALID)
- tvt1 |= IODA_TVT1_FUNC_VALID;
- tvt1 = SETFIELD(IODA_TVT1_PE_NUM, tvt1, pe_number);
-
- /* Write the TVE */
- p7ioc_phb_ioda_sel(p, IODA_TBL_TVT, window_id, false);
- out_be64(p->regs + PHB_IODA_DATA1, tvt1);
- out_be64(p->regs + PHB_IODA_DATA0, tvt0);
-
- /* Update cache */
- *cache_lo = tvt0;
- *cache_hi = tvt1;
-
- return OPAL_SUCCESS;
-}
-
-static int64_t p7ioc_map_pe_dma_window_real(struct phb *phb __unused,
- uint64_t pe_number __unused,
- uint16_t dma_window_num __unused,
- uint64_t pci_start_addr __unused,
- uint64_t pci_mem_size __unused)
-{
- /* XXX Not yet implemented (not yet used by Linux) */
- return OPAL_UNSUPPORTED;
-}
-
-static int64_t p7ioc_set_mve(struct phb *phb, uint32_t mve_number,
- uint64_t pe_number)
-{
- struct p7ioc_phb *p = phb_to_p7ioc_phb(phb);
- uint64_t pelt, mve = 0;
- uint64_t *cache = &p->mve_cache[mve_number];
-
- if (pe_number > 127 || mve_number > 255)
- return OPAL_PARAMETER;
-
- /* Read the PE filter info from the PELT-M */
- p7ioc_phb_ioda_sel(p, IODA_TBL_PELTM, pe_number, false);
- pelt = in_be64(p->regs + PHB_IODA_DATA0);
-
- mve = SETFIELD(IODA_MVT_BUS_VALID, mve,
- GETFIELD(IODA_PELTM_BUS_VALID, pelt));
- mve = SETFIELD(IODA_MVT_BUS_NUM, mve,
- GETFIELD(IODA_PELTM_BUS, pelt));
- mve = SETFIELD(IODA_MVT_DEV_NUM, mve,
- GETFIELD(IODA_PELTM_DEV, pelt));
- mve = SETFIELD(IODA_MVT_FUNC_NUM, mve,
- GETFIELD(IODA_PELTM_FUNC, pelt));
- if (pelt & IODA_PELTM_DEV_VALID)
- mve |= IODA_MVT_DEV_VALID;
- if (pelt & IODA_PELTM_FUNC_VALID)
- mve |= IODA_MVT_FUNC_VALID;
- mve = SETFIELD(IODA_MVT_PE_NUM, mve, pe_number);
-
- p7ioc_phb_ioda_sel(p, IODA_TBL_MVT, mve_number, false);
- out_be64(p->regs + PHB_IODA_DATA0, mve);
-
- /* Update cache */
- *cache = mve;
-
- return OPAL_SUCCESS;
-}
-
-static int64_t p7ioc_set_mve_enable(struct phb *phb, uint32_t mve_number,
- uint32_t state)
-{
- struct p7ioc_phb *p = phb_to_p7ioc_phb(phb);
- uint64_t mve;
- uint64_t *cache = &p->mve_cache[mve_number];
-
- if (mve_number > 255)
- return OPAL_PARAMETER;
-
- p7ioc_phb_ioda_sel(p, IODA_TBL_MVT, mve_number, false);
- mve = in_be64(p->regs + PHB_IODA_DATA0);
- if (state)
- mve |= IODA_MVT_VALID;
- else
- mve &= ~IODA_MVT_VALID;
- out_be64(p->regs + PHB_IODA_DATA0, mve);
-
- /* Update cache */
- *cache = mve;
-
- return OPAL_SUCCESS;
-}
-
-static int64_t p7ioc_set_xive_pe(struct phb *phb, uint64_t pe_number,
- uint32_t xive_num)
-{
- struct p7ioc_phb *p = phb_to_p7ioc_phb(phb);
- uint64_t xive;
-
- if (pe_number > 127 || xive_num > 255)
- return OPAL_PARAMETER;
-
- /* Update MXIVE cache */
- xive = p->mxive_cache[xive_num];
- xive = SETFIELD(IODA_XIVT_PENUM, xive, pe_number);
- p->mxive_cache[xive_num] = xive;
-
- /* Update HW */
- p7ioc_phb_ioda_sel(p, IODA_TBL_MXIVT, xive_num, false);
- xive = in_be64(p->regs + PHB_IODA_DATA0);
- xive = SETFIELD(IODA_XIVT_PENUM, xive, pe_number);
- out_be64(p->regs + PHB_IODA_DATA0, xive);
-
- return OPAL_SUCCESS;
-}
-
-static int64_t p7ioc_get_msi_32(struct phb *phb __unused, uint64_t mve_number,
- uint32_t xive_num, uint8_t msi_range,
- uint32_t *msi_address, uint32_t *message_data)
-{
- if (mve_number > 255 || xive_num > 255 || msi_range != 1)
- return OPAL_PARAMETER;
-
- *msi_address = 0xffff0000 | (mve_number << 4);
- *message_data = xive_num;
-
- return OPAL_SUCCESS;
-}
-
-static int64_t p7ioc_get_msi_64(struct phb *phb __unused, uint64_t mve_number,
- uint32_t xive_num, uint8_t msi_range,
- uint64_t *msi_address, uint32_t *message_data)
-{
- if (mve_number > 255 || xive_num > 255 || msi_range != 1)
- return OPAL_PARAMETER;
-
- *msi_address = (9ul << 60) | (((u64)mve_number) << 48);
- *message_data = xive_num;
-
- return OPAL_SUCCESS;
-}
-
-static void p7ioc_root_port_init(struct phb *phb, struct pci_device *dev,
- int ecap, int aercap)
-{
- uint16_t bdfn = dev->bdfn;
- uint16_t val16;
- uint32_t val32;
-
- /* Enable SERR and parity checking */
- pci_cfg_read16(phb, bdfn, PCI_CFG_CMD, &val16);
- val16 |= (PCI_CFG_CMD_SERR_EN | PCI_CFG_CMD_PERR_RESP);
- pci_cfg_write16(phb, bdfn, PCI_CFG_CMD, val16);
-
- /* Enable reporting various errors */
- if (!ecap) return;
- pci_cfg_read16(phb, bdfn, ecap + PCICAP_EXP_DEVCTL, &val16);
- val16 |= (PCICAP_EXP_DEVCTL_CE_REPORT |
- PCICAP_EXP_DEVCTL_NFE_REPORT |
- PCICAP_EXP_DEVCTL_FE_REPORT |
- PCICAP_EXP_DEVCTL_UR_REPORT);
- pci_cfg_write16(phb, bdfn, ecap + PCICAP_EXP_DEVCTL, val16);
-
- /* Mask various unrecoverable errors */
- if (!aercap) return;
- pci_cfg_read32(phb, bdfn, aercap + PCIECAP_AER_UE_MASK, &val32);
- val32 |= (PCIECAP_AER_UE_MASK_POISON_TLP |
- PCIECAP_AER_UE_MASK_COMPL_TIMEOUT |
- PCIECAP_AER_UE_MASK_COMPL_ABORT |
- PCIECAP_AER_UE_MASK_ECRC);
- pci_cfg_write32(phb, bdfn, aercap + PCIECAP_AER_UE_MASK, val32);
-
- /* Report various unrecoverable errors as fatal errors */
- pci_cfg_read32(phb, bdfn, aercap + PCIECAP_AER_UE_SEVERITY, &val32);
- val32 |= (PCIECAP_AER_UE_SEVERITY_DLLP |
- PCIECAP_AER_UE_SEVERITY_SURPRISE_DOWN |
- PCIECAP_AER_UE_SEVERITY_FLOW_CTL_PROT |
- PCIECAP_AER_UE_SEVERITY_UNEXP_COMPL |
- PCIECAP_AER_UE_SEVERITY_RECV_OVFLOW |
- PCIECAP_AER_UE_SEVERITY_MALFORMED_TLP);
- pci_cfg_write32(phb, bdfn, aercap + PCIECAP_AER_UE_SEVERITY, val32);
-
- /* Mask various recoverable errors */
- pci_cfg_read32(phb, bdfn, aercap + PCIECAP_AER_CE_MASK, &val32);
- val32 |= PCIECAP_AER_CE_MASK_ADV_NONFATAL;
- pci_cfg_write32(phb, bdfn, aercap + PCIECAP_AER_CE_MASK, val32);
-
- /* Enable ECRC check */
- pci_cfg_read32(phb, bdfn, aercap + PCIECAP_AER_CAPCTL, &val32);
- val32 |= (PCIECAP_AER_CAPCTL_ECRCG_EN |
- PCIECAP_AER_CAPCTL_ECRCC_EN);
- pci_cfg_write32(phb, bdfn, aercap + PCIECAP_AER_CAPCTL, val32);
-
- /* Enable all error reporting */
- pci_cfg_read32(phb, bdfn, aercap + PCIECAP_AER_RERR_CMD, &val32);
- val32 |= (PCIECAP_AER_RERR_CMD_FE |
- PCIECAP_AER_RERR_CMD_NFE |
- PCIECAP_AER_RERR_CMD_CE);
- pci_cfg_write32(phb, bdfn, aercap + PCIECAP_AER_RERR_CMD, val32);
-}
-
-static void p7ioc_switch_port_init(struct phb *phb,
- struct pci_device *dev,
- int ecap, int aercap)
-{
- uint16_t bdfn = dev->bdfn;
- uint16_t val16;
- uint32_t val32;
-
- /* Enable SERR and parity checking and disable INTx */
- pci_cfg_read16(phb, bdfn, PCI_CFG_CMD, &val16);
- val16 |= (PCI_CFG_CMD_PERR_RESP |
- PCI_CFG_CMD_SERR_EN |
- PCI_CFG_CMD_INTx_DIS);
- pci_cfg_write16(phb, bdfn, PCI_CFG_CMD, val16);
-
- /* Disable partity error and enable system error */
- pci_cfg_read16(phb, bdfn, PCI_CFG_BRCTL, &val16);
- val16 &= ~PCI_CFG_BRCTL_PERR_RESP_EN;
- val16 |= PCI_CFG_BRCTL_SERR_EN;
- pci_cfg_write16(phb, bdfn, PCI_CFG_BRCTL, val16);
-
- /* Enable reporting various errors */
- if (!ecap) return;
- pci_cfg_read16(phb, bdfn, ecap + PCICAP_EXP_DEVCTL, &val16);
- val16 |= (PCICAP_EXP_DEVCTL_CE_REPORT |
- PCICAP_EXP_DEVCTL_NFE_REPORT |
- PCICAP_EXP_DEVCTL_FE_REPORT);
- pci_cfg_write16(phb, bdfn, ecap + PCICAP_EXP_DEVCTL, val16);
-
- /* Unmask all unrecoverable errors */
- if (!aercap) return;
- pci_cfg_write32(phb, bdfn, aercap + PCIECAP_AER_UE_MASK, 0x0);
-
- /* Severity of unrecoverable errors */
- if (dev->dev_type == PCIE_TYPE_SWITCH_UPPORT)
- val32 = (PCIECAP_AER_UE_SEVERITY_DLLP |
- PCIECAP_AER_UE_SEVERITY_SURPRISE_DOWN |
- PCIECAP_AER_UE_SEVERITY_FLOW_CTL_PROT |
- PCIECAP_AER_UE_SEVERITY_RECV_OVFLOW |
- PCIECAP_AER_UE_SEVERITY_MALFORMED_TLP |
- PCIECAP_AER_UE_SEVERITY_INTERNAL);
- else
- val32 = (PCIECAP_AER_UE_SEVERITY_FLOW_CTL_PROT |
- PCIECAP_AER_UE_SEVERITY_INTERNAL);
- pci_cfg_write32(phb, bdfn, aercap + PCIECAP_AER_UE_SEVERITY, val32);
-
- /* Mask various correctable errors */
- val32 = PCIECAP_AER_CE_MASK_ADV_NONFATAL;
- pci_cfg_write32(phb, bdfn, aercap + PCIECAP_AER_CE_MASK, val32);
-
- /* Enable ECRC generation and disable ECRC check */
- pci_cfg_read32(phb, bdfn, aercap + PCIECAP_AER_CAPCTL, &val32);
- val32 |= PCIECAP_AER_CAPCTL_ECRCG_EN;
- val32 &= ~PCIECAP_AER_CAPCTL_ECRCC_EN;
- pci_cfg_write32(phb, bdfn, aercap + PCIECAP_AER_CAPCTL, val32);
-}
-
-static void p7ioc_endpoint_init(struct phb *phb,
- struct pci_device *dev,
- int ecap, int aercap)
-{
- uint16_t bdfn = dev->bdfn;
- uint16_t val16;
- uint32_t val32;
-
- /* Enable SERR and parity checking */
- pci_cfg_read16(phb, bdfn, PCI_CFG_CMD, &val16);
- val16 |= (PCI_CFG_CMD_PERR_RESP |
- PCI_CFG_CMD_SERR_EN);
- pci_cfg_write16(phb, bdfn, PCI_CFG_CMD, val16);
-
- /* Enable reporting various errors */
- if (!ecap) return;
- pci_cfg_read16(phb, bdfn, ecap + PCICAP_EXP_DEVCTL, &val16);
- val16 &= ~PCICAP_EXP_DEVCTL_CE_REPORT;
- val16 |= (PCICAP_EXP_DEVCTL_NFE_REPORT |
- PCICAP_EXP_DEVCTL_FE_REPORT |
- PCICAP_EXP_DEVCTL_UR_REPORT);
- pci_cfg_write16(phb, bdfn, ecap + PCICAP_EXP_DEVCTL, val16);
-
- /* Enable ECRC generation and check */
- pci_cfg_read32(phb, bdfn, aercap + PCIECAP_AER_CAPCTL, &val32);
- val32 |= (PCIECAP_AER_CAPCTL_ECRCG_EN |
- PCIECAP_AER_CAPCTL_ECRCC_EN);
- pci_cfg_write32(phb, bdfn, aercap + PCIECAP_AER_CAPCTL, val32);
-}
-
-static int p7ioc_device_init(struct phb *phb,
- struct pci_device *dev,
- void *data __unused)
-{
- int ecap, aercap;
-
- /* Common initialization for the device */
- pci_device_init(phb, dev);
-
- ecap = pci_cap(dev, PCI_CFG_CAP_ID_EXP, false);
- aercap = pci_cap(dev, PCIECAP_ID_AER, true);
- if (dev->dev_type == PCIE_TYPE_ROOT_PORT)
- p7ioc_root_port_init(phb, dev, ecap, aercap);
- else if (dev->dev_type == PCIE_TYPE_SWITCH_UPPORT ||
- dev->dev_type == PCIE_TYPE_SWITCH_DNPORT)
- p7ioc_switch_port_init(phb, dev, ecap, aercap);
- else
- p7ioc_endpoint_init(phb, dev, ecap, aercap);
-
- return 0;
-}
-
-static int64_t p7ioc_pci_reinit(struct phb *phb,
- uint64_t scope, uint64_t data)
-{
- struct pci_device *pd;
- uint16_t bdfn = data;
- int ret;
-
- if (scope != OPAL_REINIT_PCI_DEV)
- return OPAL_PARAMETER;
-
- pd = pci_find_dev(phb, bdfn);
- if (!pd)
- return OPAL_PARAMETER;
-
- ret = p7ioc_device_init(phb, pd, NULL);
- if (ret)
- return OPAL_HARDWARE;
-
- return OPAL_SUCCESS;
-}
-
-static uint8_t p7ioc_choose_bus(struct phb *phb __unused,
- struct pci_device *bridge,
- uint8_t candidate, uint8_t *max_bus,
- bool *use_max)
-{
- uint8_t m, al;
- int i;
-
- /* Bus number selection is nasty on P7IOC. Our EEH HW can only cope
- * with bus ranges that are naturally aligned powers of two. It also
- * has "issues" with dealing with more than 32 bus numbers.
- *
- * On the other hand we can deal with overlaps to some extent as
- * the PELT-M entries are ordered.
- *
- * We also don't need to bother with the busses between the upstream
- * and downstream ports of switches.
- *
- * For now we apply this simple mechanism which matche what OFW does
- * under OPAL:
- *
- * - Top level bus (PHB to RC) is 0
- * - RC to first device is 1..ff
- * - Then going down, a switch gets (N = parent bus, M = parent max)
- * * Upstream bridge is N+1, M, use_max = false
- * * Downstream bridge is closest power of two from 32 down and
- * * use max
- *
- * XXX NOTE: If we have access to HW VPDs, we could know whether
- * this is a bridge with a single device on it such as IPR and
- * limit ourselves to a single bus number.
- */
-
- /* Default use_max is false (legacy) */
- *use_max = false;
-
- /* If we are the root complex or we are not in PCIe land anymore, just
- * use legacy algorithm
- */
- if (!bridge || !pci_has_cap(bridge, PCI_CFG_CAP_ID_EXP, false))
- return candidate;
-
- /* Figure out the bridge type */
- switch(bridge->dev_type) {
- case PCIE_TYPE_PCIX_TO_PCIE:
- /* PCI-X to PCIE ... hrm, let's not bother too much with that */
- return candidate;
- case PCIE_TYPE_SWITCH_UPPORT:
- case PCIE_TYPE_ROOT_PORT:
- /* Upstream port, we use legacy handling as well */
- return candidate;
- case PCIE_TYPE_SWITCH_DNPORT:
- case PCIE_TYPE_PCIE_TO_PCIX:
- /* That leaves us with the interesting cases that we handle */
- break;
- default:
- /* Should not happen, treat as legacy */
- prerror("PCI: Device %04x has unsupported type %d in choose_bus\n",
- bridge->bdfn, bridge->dev_type);
- return candidate;
- }
-
- /* Ok, let's find a power of two that fits, fallback to 1 */
- for (i = 5; i >= 0; i--) {
- m = (1 << i) - 1;
- al = (candidate + m) & ~m;
- if (al <= *max_bus && (al + m) <= *max_bus)
- break;
- }
- if (i < 0)
- return 0;
- *use_max = true;
- *max_bus = al + m;
- return al;
-}
-
-static int64_t p7ioc_get_reserved_pe_number(struct phb *phb __unused)
-{
- return 127;
-}
-
-/* p7ioc_phb_init_ioda_cache - Reset the IODA cache values
- */
-static void p7ioc_phb_init_ioda_cache(struct p7ioc_phb *p)
-{
- unsigned int i;
-
- for (i = 0; i < 8; i++)
- p->lxive_cache[i] = SETFIELD(IODA_XIVT_PRIORITY, 0ull, 0xff);
- for (i = 0; i < 256; i++) {
- p->mxive_cache[i] = SETFIELD(IODA_XIVT_PRIORITY, 0ull, 0xff);
- p->mve_cache[i] = 0;
- }
- for (i = 0; i < 16; i++)
- p->m64b_cache[i] = 0;
-
- /*
- * Since there is only one root port under the PHB,
- * We make all PELTM entries except last one to be
- * invalid by configuring their RID to 00:00.1. The
- * last entry is to encompass all RIDs.
- */
- for (i = 0; i < 127; i++)
- p->peltm_cache[i] = 0x0001f80000000000UL;
- p->peltm_cache[127] = 0x0ul;
-
- for (i = 0; i < 128; i++) {
- p->peltv_lo_cache[i] = 0;
- p->peltv_hi_cache[i] = 0;
- p->tve_lo_cache[i] = 0;
- p->tve_hi_cache[i] = 0;
- p->iod_cache[i] = 0;
- p->m32d_cache[i] = 0;
- p->m64d_cache[i] = 0;
- }
-}
-
-/* p7ioc_phb_ioda_reset - Reset the IODA tables
- *
- * @purge: If true, the cache is cleared and the cleared values
- * are applied to HW. If false, the cached values are
- * applied to HW
- *
- * This reset the IODA tables in the PHB. It is called at
- * initialization time, on PHB reset, and can be called
- * explicitly from OPAL
- */
-static int64_t p7ioc_ioda_reset(struct phb *phb, bool purge)
-{
- struct p7ioc_phb *p = phb_to_p7ioc_phb(phb);
- unsigned int i;
- uint64_t reg64;
- uint64_t data64, data64_hi;
- uint8_t prio;
- uint16_t server;
- uint64_t m_server, m_prio;
-
- /* If the "purge" argument is set, we clear the table cache */
- if (purge)
- p7ioc_phb_init_ioda_cache(p);
-
- /* Init_18..19: Setup the HRT
- *
- * XXX NOTE: I still don't completely get that HRT business so
- * I'll just mimmic BML and put the PHB number + 1 in there
- */
- p7ioc_phb_ioda_sel(p, IODA_TBL_HRT, 0, true);
- out_be64(p->regs + PHB_IODA_DATA0, p->index + 1);
- out_be64(p->regs + PHB_IODA_DATA0, p->index + 1);
- out_be64(p->regs + PHB_IODA_DATA0, p->index + 1);
- out_be64(p->regs + PHB_IODA_DATA0, p->index + 1);
-
- /* Init_20..21: Cleanup the LXIVT
- *
- * We set the priority to FF (masked) and clear everything
- * else. That means we leave the HRT index to 0 which is
- * going to remain unmodified... for now.
- */
- p7ioc_phb_ioda_sel(p, IODA_TBL_LXIVT, 0, true);
- for (i = 0; i < 8; i++) {
- data64 = p->lxive_cache[i];
- server = GETFIELD(IODA_XIVT_SERVER, data64);
- prio = GETFIELD(IODA_XIVT_PRIORITY, data64);
-
- /* Now we mangle the server and priority */
- if (prio == 0xff) {
- m_server = 0;
- m_prio = 0xff;
- } else {
- m_server = server >> 3;
- m_prio = (prio >> 3) | ((server & 7) << 5);
- }
-
- data64 = SETFIELD(IODA_XIVT_SERVER, data64, m_server);
- data64 = SETFIELD(IODA_XIVT_PRIORITY, data64, m_prio);
- out_be64(p->regs + PHB_IODA_DATA0, data64);
- }
-
- /* Init_22..23: Cleanup the MXIVT
- *
- * We set the priority to FF (masked) and clear everything
- * else. That means we leave the HRT index to 0 which is
- * going to remain unmodified... for now.
- */
- p7ioc_phb_ioda_sel(p, IODA_TBL_MXIVT, 0, true);
- for (i = 0; i < 256; i++) {
- data64 = p->mxive_cache[i];
- server = GETFIELD(IODA_XIVT_SERVER, data64);
- prio = GETFIELD(IODA_XIVT_PRIORITY, data64);
-
- /* Now we mangle the server and priority */
- if (prio == 0xff) {
- m_server = 0;
- m_prio = 0xff;
- } else {
- m_server = server >> 3;
- m_prio = (prio >> 3) | ((server & 7) << 5);
- }
-
- data64 = SETFIELD(IODA_XIVT_SERVER, data64, m_server);
- data64 = SETFIELD(IODA_XIVT_PRIORITY, data64, m_prio);
- out_be64(p->regs + PHB_IODA_DATA0, data64);
- }
-
- /* Init_24..25: Cleanup the MVT */
- p7ioc_phb_ioda_sel(p, IODA_TBL_MVT, 0, true);
- for (i = 0; i < 256; i++) {
- data64 = p->mve_cache[i];
- out_be64(p->regs + PHB_IODA_DATA0, data64);
- }
-
- /* Init_26..27: Cleanup the PELTM
- *
- * A completely clear PELTM should make everything match PE 0
- */
- p7ioc_phb_ioda_sel(p, IODA_TBL_PELTM, 0, true);
- for (i = 0; i < 127; i++) {
- data64 = p->peltm_cache[i];
- out_be64(p->regs + PHB_IODA_DATA0, data64);
- }
-
- /* Init_28..30: Cleanup the PELTV */
- p7ioc_phb_ioda_sel(p, IODA_TBL_PELTV, 0, true);
- for (i = 0; i < 127; i++) {
- data64 = p->peltv_lo_cache[i];
- data64_hi = p->peltv_hi_cache[i];
- out_be64(p->regs + PHB_IODA_DATA1, data64_hi);
- out_be64(p->regs + PHB_IODA_DATA0, data64);
- }
-
- /* Init_31..33: Cleanup the TVT */
- p7ioc_phb_ioda_sel(p, IODA_TBL_TVT, 0, true);
- for (i = 0; i < 127; i++) {
- data64 = p->tve_lo_cache[i];
- data64_hi = p->tve_hi_cache[i];
- out_be64(p->regs + PHB_IODA_DATA1, data64_hi);
- out_be64(p->regs + PHB_IODA_DATA0, data64);
- }
-
- /* Init_34..35: Cleanup the M64BT
- *
- * We don't enable M64 BARs by default. However,
- * we shouldn't purge the hw and cache for it in
- * future.
- */
- p7ioc_phb_ioda_sel(p, IODA_TBL_M64BT, 0, true);
- for (i = 0; i < 16; i++)
- out_be64(p->regs + PHB_IODA_DATA0, 0);
-
- /* Init_36..37: Cleanup the IODT */
- p7ioc_phb_ioda_sel(p, IODA_TBL_IODT, 0, true);
- for (i = 0; i < 127; i++) {
- data64 = p->iod_cache[i];
- out_be64(p->regs + PHB_IODA_DATA0, data64);
- }
-
- /* Init_38..39: Cleanup the M32DT */
- p7ioc_phb_ioda_sel(p, IODA_TBL_M32DT, 0, true);
- for (i = 0; i < 127; i++) {
- data64 = p->m32d_cache[i];
- out_be64(p->regs + PHB_IODA_DATA0, data64);
- }
-
- /* Init_40..41: Cleanup the M64DT */
- p7ioc_phb_ioda_sel(p, IODA_TBL_M64BT, 0, true);
- for (i = 0; i < 16; i++) {
- data64 = p->m64b_cache[i];
- out_be64(p->regs + PHB_IODA_DATA0, data64);
- }
-
- p7ioc_phb_ioda_sel(p, IODA_TBL_M64DT, 0, true);
- for (i = 0; i < 127; i++) {
- data64 = p->m64d_cache[i];
- out_be64(p->regs + PHB_IODA_DATA0, data64);
- }
-
- /* Clear up the TCE cache */
- reg64 = in_be64(p->regs + PHB_PHB2_CONFIG);
- reg64 &= ~PHB_PHB2C_64B_TCE_EN;
- out_be64(p->regs + PHB_PHB2_CONFIG, reg64);
- reg64 |= PHB_PHB2C_64B_TCE_EN;
- out_be64(p->regs + PHB_PHB2_CONFIG, reg64);
- in_be64(p->regs + PHB_PHB2_CONFIG);
-
- /* Clear PEST & PEEV */
- for (i = 0; i < OPAL_P7IOC_NUM_PEST_REGS; i++) {
- uint64_t pesta, pestb;
-
- p7ioc_phb_ioda_sel(p, IODA_TBL_PESTA, i, false);
- pesta = in_be64(p->regs + PHB_IODA_DATA0);
- out_be64(p->regs + PHB_IODA_DATA0, 0);
- p7ioc_phb_ioda_sel(p, IODA_TBL_PESTB, i, false);
- pestb = in_be64(p->regs + PHB_IODA_DATA0);
- out_be64(p->regs + PHB_IODA_DATA0, 0);
-
- if ((pesta & IODA_PESTA_MMIO_FROZEN) ||
- (pestb & IODA_PESTB_DMA_STOPPED))
- PHBDBG(p, "Frozen PE#%x (%s - %s)\n",
- i, (pestb & IODA_PESTB_DMA_STOPPED) ? "DMA" : "",
- (pesta & IODA_PESTA_MMIO_FROZEN) ? "MMIO" : "");
- }
-
- p7ioc_phb_ioda_sel(p, IODA_TBL_PEEV, 0, true);
- for (i = 0; i < 2; i++)
- out_be64(p->regs + PHB_IODA_DATA0, 0);
-
- return OPAL_SUCCESS;
-}
-
-/*
- * Clear anything we have in PAPR Error Injection registers. Though
- * the spec says the PAPR error injection should be one-shot without
- * the "sticky" bit. However, that's false according to the experiments
- * I had. So we have to clear it at appropriate point in kernel to
- * avoid endless frozen PE.
- */
-static int64_t p7ioc_papr_errinjct_reset(struct phb *phb)
-{
- struct p7ioc_phb *p = phb_to_p7ioc_phb(phb);
-
- out_be64(p->regs + PHB_PAPR_ERR_INJ_CTL, 0x0ul);
- out_be64(p->regs + PHB_PAPR_ERR_INJ_ADDR, 0x0ul);
- out_be64(p->regs + PHB_PAPR_ERR_INJ_MASK, 0x0ul);
-
- return OPAL_SUCCESS;
-}
-
-static int64_t p7ioc_get_presence_state(struct pci_slot *slot, uint8_t *val)
-{
- struct p7ioc_phb *p = phb_to_p7ioc_phb(slot->phb);
- uint64_t reg;
-
- reg = in_be64(p->regs + PHB_PCIE_SLOTCTL2);
- if (reg & PHB_PCIE_SLOTCTL2_PRSTN_STAT)
- *val = OPAL_PCI_SLOT_PRESENT;
- else
- *val = OPAL_PCI_SLOT_EMPTY;
-
- return OPAL_SUCCESS;
-}
-
-static int64_t p7ioc_get_link_state(struct pci_slot *slot, uint8_t *val)
-{
- struct p7ioc_phb *p = phb_to_p7ioc_phb(slot->phb);
- uint64_t reg64;
- uint16_t state;
- int64_t rc;
-
- /* Check if the link training is completed */
- reg64 = in_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL);
- if (!(reg64 & PHB_PCIE_DLP_TC_DL_LINKACT)) {
- *val = 0;
- return OPAL_SUCCESS;
- }
-
- /* Grab link width from PCIe capability */
- rc = p7ioc_pcicfg_read16(&p->phb, 0, p->ecap + PCICAP_EXP_LSTAT,
- &state);
- if (rc < 0) {
- PHBERR(p, "%s: Error %lld reading link status\n",
- __func__, rc);
- return OPAL_HARDWARE;
- }
-
- if (state & PCICAP_EXP_LSTAT_DLLL_ACT)
- *val = ((state & PCICAP_EXP_LSTAT_WIDTH) >> 4);
- else
- *val = 0;
-
- return OPAL_SUCCESS;
-}
-
-static int64_t p7ioc_get_power_state(struct pci_slot *slot, uint8_t *val)
-{
- struct p7ioc_phb *p = phb_to_p7ioc_phb(slot->phb);
- uint64_t reg64;
-
- reg64 = in_be64(p->regs + PHB_PCIE_SLOTCTL2);
- if (reg64 & PHB_PCIE_SLOTCTL2_PWR_EN_STAT)
- *val = PCI_SLOT_POWER_ON;
- else
- *val = PCI_SLOT_POWER_OFF;
-
- return OPAL_SUCCESS;
-}
-
-static int64_t p7ioc_set_power_state(struct pci_slot *slot, uint8_t val)
-{
- struct p7ioc_phb *p = phb_to_p7ioc_phb(slot->phb);
- uint64_t reg64;
- uint8_t state = PCI_SLOT_POWER_OFF;
-
- if (val != PCI_SLOT_POWER_OFF && val != PCI_SLOT_POWER_ON)
- return OPAL_PARAMETER;
-
- /* If the power state has been put into the requested one */
- reg64 = in_be64(p->regs + PHB_PCIE_SLOTCTL2);
- if (reg64 & PHB_PCIE_SLOTCTL2_PWR_EN_STAT)
- state = PCI_SLOT_POWER_ON;
- if (state == val)
- return OPAL_SUCCESS;
-
- /* Power on/off */
- if (val == PCI_SLOT_POWER_ON) {
- reg64 &= ~(0x8c00000000000000ul);
- out_be64(p->regs + PHB_HOTPLUG_OVERRIDE, reg64);
- reg64 |= 0x8400000000000000ul;
- out_be64(p->regs + PHB_HOTPLUG_OVERRIDE, reg64);
- } else {
- reg64 &= ~(0x8c00000000000000ul);
- reg64 |= 0x8400000000000000ul;
- out_be64(p->regs + PHB_HOTPLUG_OVERRIDE, reg64);
- reg64 &= ~(0x8c00000000000000ul);
- reg64 |= 0x0c00000000000000ul;
- out_be64(p->regs + PHB_HOTPLUG_OVERRIDE, reg64);
- }
-
- return OPAL_SUCCESS;
-}
-
-static void p7ioc_prepare_link_change(struct pci_slot *slot, bool up)
-{
- struct p7ioc_phb *p = phb_to_p7ioc_phb(slot->phb);
- uint64_t ci_idx = p->index + 2;
- uint32_t cfg32;
-
- if (!up) {
- /* Mask PCIE port interrupts and AER receiver error */
- out_be64(p->regs + UTL_PCIE_PORT_IRQ_EN, 0x7E00000000000000UL);
- p7ioc_pcicfg_read32(&p->phb, 0,
- p->aercap + PCIECAP_AER_CE_MASK, &cfg32);
- cfg32 |= PCIECAP_AER_CE_RECVR_ERR;
- p7ioc_pcicfg_write32(&p->phb, 0,
- p->aercap + PCIECAP_AER_CE_MASK, cfg32);
-
- /* Mask CI port error and clear it */
- out_be64(p->ioc->regs + P7IOC_CIn_LEM_ERR_MASK(ci_idx),
- 0xa4f4000000000000ul);
- out_be64(p->regs + PHB_LEM_ERROR_MASK,
- 0xadb650c9808dd051ul);
- out_be64(p->ioc->regs + P7IOC_CIn_LEM_FIR(ci_idx),
- 0x0ul);
-
- /* Block access to PCI-CFG space */
- p->flags |= P7IOC_PHB_CFG_BLOCKED;
- } else {
- /* Clear spurious errors and enable PCIE port interrupts */
- out_be64(p->regs + UTL_PCIE_PORT_STATUS, 0x00E0000000000000UL);
- out_be64(p->regs + UTL_PCIE_PORT_IRQ_EN, 0xFE65000000000000UL);
-
- /* Clear AER receiver error status */
- p7ioc_pcicfg_write32(&p->phb, 0,
- p->aercap + PCIECAP_AER_CE_STATUS,
- PCIECAP_AER_CE_RECVR_ERR);
- /* Unmask receiver error status in AER */
- p7ioc_pcicfg_read32(&p->phb, 0,
- p->aercap + PCIECAP_AER_CE_MASK, &cfg32);
- cfg32 &= ~PCIECAP_AER_CE_RECVR_ERR;
- p7ioc_pcicfg_write32(&p->phb, 0,
- p->aercap + PCIECAP_AER_CE_MASK, cfg32);
- /* Clear and Unmask CI port and PHB errors */
- out_be64(p->ioc->regs + P7IOC_CIn_LEM_FIR(ci_idx), 0x0ul);
- out_be64(p->regs + PHB_LEM_FIR_ACCUM, 0x0ul);
- out_be64(p->ioc->regs + P7IOC_CIn_LEM_ERR_MASK_AND(ci_idx),
- 0x0ul);
- out_be64(p->regs + PHB_LEM_ERROR_MASK, 0x1249a1147f500f2cul);
-
- /* Don't block access to PCI-CFG space */
- p->flags &= ~P7IOC_PHB_CFG_BLOCKED;
-
- /* Restore slot's state */
- pci_slot_set_state(slot, P7IOC_SLOT_NORMAL);
-
- /*
- * We might lose the bus numbers in the reset and we need
- * restore the bus numbers. Otherwise, some adpaters (e.g.
- * IPR) can't be probed properly by kernel. We don't need
- * restore bus numbers for all kinds of resets. However,
- * it's not harmful to restore the bus numbers, which makes
- * the logic simplified
- */
- pci_restore_bridge_buses(slot->phb, slot->pd);
- if (slot->phb->ops->device_init)
- pci_walk_dev(slot->phb, slot->pd,
- slot->phb->ops->device_init, NULL);
- }
-}
-
-static int64_t p7ioc_poll_link(struct pci_slot *slot)
-{
- struct p7ioc_phb *p = phb_to_p7ioc_phb(slot->phb);
- uint64_t reg64;
-
- switch (slot->state) {
- case P7IOC_SLOT_NORMAL:
- case P7IOC_SLOT_LINK_START:
- PHBDBG(p, "LINK: Start polling\n");
- reg64 = in_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL);
- reg64 &= ~PHB_PCIE_DLP_TCTX_DISABLE;
- out_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL, reg64);
- slot->retries = 100;
- pci_slot_set_state(slot, P7IOC_SLOT_LINK_WAIT);
- return pci_slot_set_sm_timeout(slot, msecs_to_tb(10));
- case P7IOC_SLOT_LINK_WAIT:
- reg64 = in_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL);
- if (reg64 & PHB_PCIE_DLP_TC_DL_LINKACT) {
- PHBDBG(p, "LINK: Up\n");
- slot->ops.prepare_link_change(slot, true);
- return OPAL_SUCCESS;
- }
-
- if (slot->retries-- == 0) {
- PHBERR(p, "LINK: Timeout waiting for link up\n");
- goto out;
- }
- return pci_slot_set_sm_timeout(slot, msecs_to_tb(10));
- default:
- PHBERR(p, "LINK: Unexpected slot state %08x\n",
- slot->state);
- }
-
-out:
- pci_slot_set_state(slot, P7IOC_SLOT_NORMAL);
- return OPAL_HARDWARE;
-}
-
-static int64_t p7ioc_hreset(struct pci_slot *slot)
-{
- struct p7ioc_phb *p = phb_to_p7ioc_phb(slot->phb);
- uint8_t presence = 1;
- uint16_t brctl;
- uint64_t reg64;
-
- switch (slot->state) {
- case P7IOC_SLOT_NORMAL:
- PHBDBG(p, "HRESET: Starts\n");
- if (slot->ops.get_presence_state)
- slot->ops.get_presence_state(slot, &presence);
- if (!presence) {
- PHBDBG(p, "HRESET: No device\n");
- return OPAL_SUCCESS;
- }
-
- PHBDBG(p, "HRESET: Prepare for link down\n");
- slot->ops.prepare_link_change(slot, false);
-
- /* Disable link to avoid training issues */
- PHBDBG(p, "HRESET: Disable link training\n");
- reg64 = in_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL);
- reg64 |= PHB_PCIE_DLP_TCTX_DISABLE;
- out_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL, reg64);
- pci_slot_set_state(slot, P7IOC_SLOT_HRESET_TRAINING);
- slot->retries = 15;
- /* fall through */
- case P7IOC_SLOT_HRESET_TRAINING:
- reg64 = in_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL);
- if (!(reg64 & PHB_PCIE_DLP_TCRX_DISABLED)) {
- if (slot->retries -- == 0) {
- PHBERR(p, "HRESET: Timeout disabling link training\n");
- goto out;
- }
-
- return pci_slot_set_sm_timeout(slot, msecs_to_tb(10));
- }
- /* fall through */
- case P7IOC_SLOT_HRESET_START:
- PHBDBG(p, "HRESET: Assert\n");
- p7ioc_pcicfg_read16(&p->phb, 0, PCI_CFG_BRCTL, &brctl);
- brctl |= PCI_CFG_BRCTL_SECONDARY_RESET;
- p7ioc_pcicfg_write16(&p->phb, 0, PCI_CFG_BRCTL, brctl);
-
- pci_slot_set_state(slot, P7IOC_SLOT_HRESET_DELAY);
- return pci_slot_set_sm_timeout(slot, secs_to_tb(1));
- case P7IOC_SLOT_HRESET_DELAY:
- PHBDBG(p, "HRESET: Deassert\n");
- p7ioc_pcicfg_read16(&p->phb, 0, PCI_CFG_BRCTL, &brctl);
- brctl &= ~PCI_CFG_BRCTL_SECONDARY_RESET;
- p7ioc_pcicfg_write16(&p->phb, 0, PCI_CFG_BRCTL, brctl);
- pci_slot_set_state(slot, P7IOC_SLOT_HRESET_DELAY2);
- return pci_slot_set_sm_timeout(slot, msecs_to_tb(200));
- case P7IOC_SLOT_HRESET_DELAY2:
- pci_slot_set_state(slot, P7IOC_SLOT_LINK_START);
- return slot->ops.poll_link(slot);
- default:
- PHBERR(p, "HRESET: Unexpected slot state %08x\n",
- slot->state);
- }
-
-out:
- pci_slot_set_state(slot, P7IOC_SLOT_NORMAL);
- return OPAL_HARDWARE;
-}
-
-static int64_t p7ioc_freset(struct pci_slot *slot)
-{
- struct p7ioc_phb *p = phb_to_p7ioc_phb(slot->phb);
- uint8_t presence = 1;
- uint64_t reg64;
-
- switch (slot->state) {
- case P7IOC_SLOT_NORMAL:
- case P7IOC_SLOT_FRESET_START:
- PHBDBG(p, "FRESET: Starts\n");
- if (slot->ops.get_presence_state)
- slot->ops.get_presence_state(slot, &presence);
- if (!presence) {
- PHBDBG(p, "FRESET: No device\n");
- pci_slot_set_state(slot, P7IOC_SLOT_NORMAL);
- return OPAL_SUCCESS;
- }
-
- PHBDBG(p, "FRESET: Prepare for link down\n");
- slot->ops.prepare_link_change(slot, false);
-
- /* Check power state */
- reg64 = in_be64(p->regs + PHB_PCIE_SLOTCTL2);
- if (reg64 & PHB_PCIE_SLOTCTL2_PWR_EN_STAT) {
- PHBDBG(p, "FRESET: Power on, turn off\n");
- reg64 = in_be64(p->regs + PHB_HOTPLUG_OVERRIDE);
- reg64 &= ~(0x8c00000000000000ul);
- reg64 |= 0x8400000000000000ul;
- out_be64(p->regs + PHB_HOTPLUG_OVERRIDE, reg64);
- reg64 &= ~(0x8c00000000000000ul);
- reg64 |= 0x0c00000000000000ul;
- out_be64(p->regs + PHB_HOTPLUG_OVERRIDE, reg64);
- pci_slot_set_state(slot, P7IOC_SLOT_FRESET_POWER_OFF);
- return pci_slot_set_sm_timeout(slot, secs_to_tb(2));
- }
- /* fall through */
- case P7IOC_SLOT_FRESET_POWER_OFF:
- PHBDBG(p, "FRESET: Power off, turn on\n");
- reg64 = in_be64(p->regs + PHB_HOTPLUG_OVERRIDE);
- reg64 &= ~(0x8c00000000000000ul);
- out_be64(p->regs + PHB_HOTPLUG_OVERRIDE, reg64);
- reg64 |= 0x8400000000000000ul;
- out_be64(p->regs + PHB_HOTPLUG_OVERRIDE, reg64);
- pci_slot_set_state(slot, P7IOC_SLOT_FRESET_POWER_ON);
- return pci_slot_set_sm_timeout(slot, secs_to_tb(2));
- case P7IOC_SLOT_FRESET_POWER_ON:
- PHBDBG(p, "FRESET: Disable link training\n");
- reg64 = in_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL);
- reg64 |= PHB_PCIE_DLP_TCTX_DISABLE;
- out_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL, reg64);
- pci_slot_set_state(slot, P7IOC_SLOT_HRESET_TRAINING);
- slot->retries = 200;
- /* fall through */
- case P7IOC_SLOT_HRESET_TRAINING:
- reg64 = in_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL);
- if (!(reg64 & PHB_PCIE_DLP_TCRX_DISABLED)) {
- if (slot->retries -- == 0) {
- PHBERR(p, "HRESET: Timeout disabling link training\n");
- goto out;
- }
-
- return pci_slot_set_sm_timeout(slot, msecs_to_tb(10));
- }
-
- PHBDBG(p, "FRESET: Assert\n");
- reg64 = in_be64(p->regs + PHB_RESET);
- reg64 &= ~0x2000000000000000ul;
- out_be64(p->regs + PHB_RESET, reg64);
- pci_slot_set_state(slot, P7IOC_SLOT_FRESET_ASSERT);
- return pci_slot_set_sm_timeout(slot, secs_to_tb(1));
- case P7IOC_SLOT_FRESET_ASSERT:
- PHBDBG(p, "FRESET: Deassert\n");
- reg64 = in_be64(p->regs + PHB_RESET);
- reg64 |= 0x2000000000000000ul;
- out_be64(p->regs + PHB_RESET, reg64);
-
- pci_slot_set_state(slot, P7IOC_SLOT_LINK_START);
- return slot->ops.poll_link(slot);
- default:
- PHBERR(p, "FRESET: Unexpected slot state %08x\n",
- slot->state);
- }
-
-out:
- pci_slot_set_state(slot, P7IOC_SLOT_NORMAL);
- return OPAL_HARDWARE;
-}
-
-static int64_t p7ioc_creset(struct pci_slot *slot)
-{
- struct p7ioc_phb *p = phb_to_p7ioc_phb(slot->phb);
- struct p7ioc *ioc = p->ioc;
- uint64_t reg64;
-
- switch (slot->state) {
- case P7IOC_SLOT_NORMAL:
- PHBDBG(p, "CRESET: Starts\n");
- p->flags |= P7IOC_PHB_CFG_BLOCKED;
- p7ioc_phb_reset(slot->phb);
-
- /*
- * According to the experiment, we probably still have the
- * fenced state with the corresponding PHB in the Fence WOF
- * and we need clear that explicitly. Besides, the RGC might
- * already have informational error and we should clear that
- * explicitly as well. Otherwise, RGC XIVE#0 won't issue
- * interrupt any more.
- */
- reg64 = in_be64(ioc->regs + P7IOC_CHIP_FENCE_WOF);
- reg64 &= ~PPC_BIT(15 + p->index * 4);
- out_be64(ioc->regs + P7IOC_CHIP_FENCE_WOF, reg64);
-
- /* Clear informational error from RGC */
- reg64 = in_be64(ioc->regs + P7IOC_RGC_LEM_BASE +
- P7IOC_LEM_WOF_OFFSET);
- reg64 &= ~PPC_BIT(18);
- out_be64(ioc->regs + P7IOC_RGC_LEM_BASE +
- P7IOC_LEM_WOF_OFFSET, reg64);
- reg64 = in_be64(ioc->regs + P7IOC_RGC_LEM_BASE +
- P7IOC_LEM_FIR_OFFSET);
- reg64 &= ~PPC_BIT(18);
- out_be64(ioc->regs + P7IOC_RGC_LEM_BASE +
- P7IOC_LEM_FIR_OFFSET, reg64);
-
- /* Swith to fundamental reset */
- pci_slot_set_state(slot, P7IOC_SLOT_FRESET_START);
- return slot->ops.freset(slot);
- default:
- PHBERR(p, "CRESET: Unexpected slot state %08x\n",
- slot->state);
- }
-
- pci_slot_set_state(slot, P7IOC_SLOT_NORMAL);
- return OPAL_HARDWARE;
-}
-
-static struct pci_slot *p7ioc_phb_slot_create(struct phb *phb)
-{
- struct pci_slot *slot;
-
- slot = pci_slot_alloc(phb, NULL);
- if (!slot)
- return NULL;
-
- /* Elementary functions */
- slot->ops.get_presence_state = p7ioc_get_presence_state;
- slot->ops.get_link_state = p7ioc_get_link_state;
- slot->ops.get_power_state = p7ioc_get_power_state;
- slot->ops.get_attention_state = NULL;
- slot->ops.get_latch_state = NULL;
- slot->ops.set_power_state = p7ioc_set_power_state;
- slot->ops.set_attention_state = NULL;
-
- /*
- * For PHB slots, we have to split the fundamental reset
- * into 2 steps. We might not have the first step which
- * is to power off/on the slot, or it's controlled by
- * individual platforms.
- */
- slot->ops.prepare_link_change = p7ioc_prepare_link_change;
- slot->ops.poll_link = p7ioc_poll_link;
- slot->ops.hreset = p7ioc_hreset;
- slot->ops.freset = p7ioc_freset;
- slot->ops.creset = p7ioc_creset;
-
- return slot;
-}
-
-static const struct phb_ops p7ioc_phb_ops = {
- .cfg_read8 = p7ioc_pcicfg_read8,
- .cfg_read16 = p7ioc_pcicfg_read16,
- .cfg_read32 = p7ioc_pcicfg_read32,
- .cfg_write8 = p7ioc_pcicfg_write8,
- .cfg_write16 = p7ioc_pcicfg_write16,
- .cfg_write32 = p7ioc_pcicfg_write32,
- .choose_bus = p7ioc_choose_bus,
- .get_reserved_pe_number = p7ioc_get_reserved_pe_number,
- .device_init = p7ioc_device_init,
- .device_remove = NULL,
- .pci_reinit = p7ioc_pci_reinit,
- .eeh_freeze_status = p7ioc_eeh_freeze_status,
- .eeh_freeze_clear = p7ioc_eeh_freeze_clear,
- .eeh_freeze_set = p7ioc_eeh_freeze_set,
- .err_inject = p7ioc_err_inject,
- .get_diag_data2 = p7ioc_get_diag_data,
- .next_error = p7ioc_eeh_next_error,
- .phb_mmio_enable = p7ioc_phb_mmio_enable,
- .set_phb_mem_window = p7ioc_set_phb_mem_window,
- .map_pe_mmio_window = p7ioc_map_pe_mmio_window,
- .set_pe = p7ioc_set_pe,
- .set_peltv = p7ioc_set_peltv,
- .map_pe_dma_window = p7ioc_map_pe_dma_window,
- .map_pe_dma_window_real = p7ioc_map_pe_dma_window_real,
- .set_mve = p7ioc_set_mve,
- .set_mve_enable = p7ioc_set_mve_enable,
- .set_xive_pe = p7ioc_set_xive_pe,
- .get_msi_32 = p7ioc_get_msi_32,
- .get_msi_64 = p7ioc_get_msi_64,
- .ioda_reset = p7ioc_ioda_reset,
- .papr_errinjct_reset = p7ioc_papr_errinjct_reset,
-};
-
-/* p7ioc_phb_get_xive - Interrupt control from OPAL */
-static int64_t p7ioc_msi_get_xive(struct irq_source *is, uint32_t isn,
- uint16_t *server, uint8_t *prio)
-{
- struct p7ioc_phb *p = is->data;
- uint32_t irq, fbuid = P7_IRQ_FBUID(isn);
- uint64_t xive;
-
- if (fbuid < p->buid_msi || fbuid >= (p->buid_msi + 0x10))
- return OPAL_PARAMETER;
-
- irq = isn & 0xff;
- xive = p->mxive_cache[irq];
-
- *server = GETFIELD(IODA_XIVT_SERVER, xive);
- *prio = GETFIELD(IODA_XIVT_PRIORITY, xive);
-
- return OPAL_SUCCESS;
-}
-
-/* p7ioc_phb_set_xive - Interrupt control from OPAL */
-static int64_t p7ioc_msi_set_xive(struct irq_source *is, uint32_t isn,
- uint16_t server, uint8_t prio)
-{
- struct p7ioc_phb *p = is->data;
- uint32_t irq, fbuid = P7_IRQ_FBUID(isn);
- uint64_t xive, m_server, m_prio;
-
- if (fbuid < p->buid_msi || fbuid >= (p->buid_msi + 0x10))
- return OPAL_PARAMETER;
-
- /* We cache the arguments because we have to mangle
- * it in order to hijack 3 bits of priority to extend
- * the server number
- */
- irq = isn & 0xff;
- xive = p->mxive_cache[irq];
- xive = SETFIELD(IODA_XIVT_SERVER, xive, server);
- xive = SETFIELD(IODA_XIVT_PRIORITY, xive, prio);
- p->mxive_cache[irq] = xive;
-
- /* Now we mangle the server and priority */
- if (prio == 0xff) {
- m_server = 0;
- m_prio = 0xff;
- } else {
- m_server = server >> 3;
- m_prio = (prio >> 3) | ((server & 7) << 5);
- }
-
- /* We use HRT entry 0 always for now */
- p7ioc_phb_ioda_sel(p, IODA_TBL_MXIVT, irq, false);
- xive = in_be64(p->regs + PHB_IODA_DATA0);
- xive = SETFIELD(IODA_XIVT_SERVER, xive, m_server);
- xive = SETFIELD(IODA_XIVT_PRIORITY, xive, m_prio);
- out_be64(p->regs + PHB_IODA_DATA0, xive);
-
- return OPAL_SUCCESS;
-}
-
-/* p7ioc_phb_get_xive - Interrupt control from OPAL */
-static int64_t p7ioc_lsi_get_xive(struct irq_source *is, uint32_t isn,
- uint16_t *server, uint8_t *prio)
-{
- struct p7ioc_phb *p = is->data;
- uint32_t irq = (isn & 0x7);
- uint32_t fbuid = P7_IRQ_FBUID(isn);
- uint64_t xive;
-
- if (fbuid != p->buid_lsi)
- return OPAL_PARAMETER;
-
- xive = p->lxive_cache[irq];
- *server = GETFIELD(IODA_XIVT_SERVER, xive);
- *prio = GETFIELD(IODA_XIVT_PRIORITY, xive);
-
- return OPAL_SUCCESS;
-}
-
-/* p7ioc_phb_set_xive - Interrupt control from OPAL */
-static int64_t p7ioc_lsi_set_xive(struct irq_source *is, uint32_t isn,
- uint16_t server, uint8_t prio)
-{
- struct p7ioc_phb *p = is->data;
- uint32_t irq = (isn & 0x7);
- uint32_t fbuid = P7_IRQ_FBUID(isn);
- uint64_t xive, m_server, m_prio;
-
- if (fbuid != p->buid_lsi)
- return OPAL_PARAMETER;
-
- xive = SETFIELD(IODA_XIVT_SERVER, 0ull, server);
- xive = SETFIELD(IODA_XIVT_PRIORITY, xive, prio);
-
- /*
- * We cache the arguments because we have to mangle
- * it in order to hijack 3 bits of priority to extend
- * the server number
- */
- p->lxive_cache[irq] = xive;
-
- /* Now we mangle the server and priority */
- if (prio == 0xff) {
- m_server = 0;
- m_prio = 0xff;
- } else {
- m_server = server >> 3;
- m_prio = (prio >> 3) | ((server & 7) << 5);
- }
-
- /* We use HRT entry 0 always for now */
- p7ioc_phb_ioda_sel(p, IODA_TBL_LXIVT, irq, false);
- xive = in_be64(p->regs + PHB_IODA_DATA0);
- xive = SETFIELD(IODA_XIVT_SERVER, xive, m_server);
- xive = SETFIELD(IODA_XIVT_PRIORITY, xive, m_prio);
- out_be64(p->regs + PHB_IODA_DATA0, xive);
-
- return OPAL_SUCCESS;
-}
-
-static void p7ioc_phb_err_interrupt(struct irq_source *is, uint32_t isn)
-{
- struct p7ioc_phb *p = is->data;
- uint64_t peev0, peev1;
-
- PHBDBG(p, "Got interrupt 0x%04x\n", isn);
-
- opal_pci_eeh_set_evt(p->phb.opal_id);
-
- /* If the PHB is broken, go away */
- if (p->broken)
- return;
-
- /*
- * Check if there's an error pending and update PHB fence
- * state and return, the ER error is drowned at this point
- */
- phb_lock(&p->phb);
- if (p7ioc_phb_fenced(p)) {
- PHBERR(p, "ER error ignored, PHB fenced\n");
- phb_unlock(&p->phb);
- return;
- }
-
- /*
- * If we already had pending errors, which might be
- * moved from IOC, then we needn't check PEEV to avoid
- * overwriting the errors from IOC.
- */
- if (!p7ioc_phb_err_pending(p)) {
- phb_unlock(&p->phb);
- return;
- }
-
- /*
- * We don't have pending errors from IOC, it's safe
- * to check PEEV for frozen PEs.
- */
- p7ioc_phb_ioda_sel(p, IODA_TBL_PEEV, 0, true);
- peev0 = in_be64(p->regs + PHB_IODA_DATA0);
- peev1 = in_be64(p->regs + PHB_IODA_DATA0);
- if (peev0 || peev1) {
- p->err.err_src = P7IOC_ERR_SRC_PHB0 + p->index;
- p->err.err_class = P7IOC_ERR_CLASS_ER;
- p->err.err_bit = 0;
- p7ioc_phb_set_err_pending(p, true);
- }
- phb_unlock(&p->phb);
-}
-
-static uint64_t p7ioc_lsi_attributes(struct irq_source *is __unused,
- uint32_t isn)
-{
- uint32_t irq = (isn & 0x7);
-
- if (irq == PHB_LSI_PCIE_ERROR)
- return IRQ_ATTR_TARGET_OPAL | IRQ_ATTR_TARGET_RARE | IRQ_ATTR_TYPE_LSI;
- return IRQ_ATTR_TARGET_LINUX;
-}
-
-
-/* MSIs (OS owned) */
-static const struct irq_source_ops p7ioc_msi_irq_ops = {
- .get_xive = p7ioc_msi_get_xive,
- .set_xive = p7ioc_msi_set_xive,
-};
-
-/* LSIs (OS owned) */
-static const struct irq_source_ops p7ioc_lsi_irq_ops = {
- .get_xive = p7ioc_lsi_get_xive,
- .set_xive = p7ioc_lsi_set_xive,
- .attributes = p7ioc_lsi_attributes,
- .interrupt = p7ioc_phb_err_interrupt,
-};
-
-static void p7ioc_pcie_add_node(struct p7ioc_phb *p)
-{
-
- uint64_t reg[2], iob, m32b, m64b, tkill;
- uint32_t lsibase, icsp = get_ics_phandle();
- struct dt_node *np;
-
- reg[0] = cleanup_addr((uint64_t)p->regs);
- reg[1] = 0x100000;
-
- np = dt_new_addr(p->ioc->dt_node, "pciex", reg[0]);
- if (!np)
- return;
-
- p->phb.dt_node = np;
- dt_add_property_strings(np, "compatible", "ibm,p7ioc-pciex",
- "ibm,ioda-phb");
- dt_add_property_strings(np, "device_type", "pciex");
- dt_add_property(np, "reg", reg, sizeof(reg));
- dt_add_property_cells(np, "#address-cells", 3);
- dt_add_property_cells(np, "#size-cells", 2);
- dt_add_property_cells(np, "#interrupt-cells", 1);
- dt_add_property_cells(np, "bus-range", 0, 0xff);
- dt_add_property_cells(np, "clock-frequency", 0x200, 0); /* ??? */
- dt_add_property_cells(np, "interrupt-parent", icsp);
- /* XXX FIXME: add slot-name */
- //dt_property_cell("bus-width", 8); /* Figure it out from VPD ? */
-
- /* "ranges", we only expose IO and M32
- *
- * Note: The kernel expects us to have chopped of 64k from the
- * M32 size (for the 32-bit MSIs). If we don't do that, it will
- * get confused (OPAL does it)
- */
- iob = cleanup_addr(p->io_base);
- m32b = cleanup_addr(p->m32_base + M32_PCI_START);
- dt_add_property_cells(np, "ranges",
- /* IO space */
- 0x01000000, 0x00000000, 0x00000000,
- hi32(iob), lo32(iob), 0, PHB_IO_SIZE,
- /* M32 space */
- 0x02000000, 0x00000000, M32_PCI_START,
- hi32(m32b), lo32(m32b), 0,M32_PCI_SIZE - 0x10000);
-
- /* XXX FIXME: add opal-memwin32, dmawins, etc... */
- m64b = cleanup_addr(p->m64_base);
- dt_add_property_u64s(np, "ibm,opal-m64-window",
- m64b, m64b, PHB_M64_SIZE);
- dt_add_property_cells(np, "ibm,opal-msi-ports", 256);
- dt_add_property_cells(np, "ibm,opal-num-pes", 128);
- dt_add_property_cells(np, "ibm,opal-reserved-pe", 127);
- dt_add_property_cells(np, "ibm,opal-msi-ranges",
- p->buid_msi << 4, 0x100);
- tkill = reg[0] + PHB_TCE_KILL;
- dt_add_property_cells(np, "ibm,opal-tce-kill",
- hi32(tkill), lo32(tkill));
- dt_add_property_cells(np, "ibm,supported-tce-sizes",
- 12, // 4K
- 16, // 64K
- 24, // 16M
- 34); // 16G
-
- /*
- * Linux may use this property to allocate the diag data buffer, which
- * can be used for either of these structs. Pass the largest to ensure
- * they can both fit in this buffer.
- */
- dt_add_property_cells(np, "ibm,phb-diag-data-size",
- MAX(sizeof(struct OpalIoP7IOCPhbErrorData),
- sizeof(struct OpalIoP7IOCErrorData)));
-
- /* Add associativity properties */
- add_chip_dev_associativity(np);
-
- /* The interrupt maps will be generated in the RC node by the
- * PCI code based on the content of this structure:
- */
- lsibase = p->buid_lsi << 4;
- p->phb.lstate.int_size = 2;
- p->phb.lstate.int_val[0][0] = lsibase + PHB_LSI_PCIE_INTA;
- p->phb.lstate.int_val[0][1] = 1;
- p->phb.lstate.int_val[1][0] = lsibase + PHB_LSI_PCIE_INTB;
- p->phb.lstate.int_val[1][1] = 1;
- p->phb.lstate.int_val[2][0] = lsibase + PHB_LSI_PCIE_INTC;
- p->phb.lstate.int_val[2][1] = 1;
- p->phb.lstate.int_val[3][0] = lsibase + PHB_LSI_PCIE_INTD;
- p->phb.lstate.int_val[3][1] = 1;
- p->phb.lstate.int_parent[0] = icsp;
- p->phb.lstate.int_parent[1] = icsp;
- p->phb.lstate.int_parent[2] = icsp;
- p->phb.lstate.int_parent[3] = icsp;
-}
-
-/* p7ioc_phb_setup - Setup a p7ioc_phb data structure
- *
- * WARNING: This is called before the AIB register routing is
- * established. If this wants to access PHB registers, it must
- * use the ASB hard coded variant (slower)
- */
-void p7ioc_phb_setup(struct p7ioc *ioc, uint8_t index)
-{
- struct p7ioc_phb *p = &ioc->phbs[index];
- unsigned int buid_base = ioc->buid_base + PHBn_BUID_BASE(index);
- struct pci_slot *slot;
-
- p->index = index;
- p->ioc = ioc;
- p->gen = 2; /* Operate in Gen2 mode by default */
- p->phb.ops = &p7ioc_phb_ops;
- p->phb.phb_type = phb_type_pcie_v2;
- p->regs_asb = ioc->regs + PHBn_ASB_BASE(index);
- p->regs = ioc->regs + PHBn_AIB_BASE(index);
- p->buid_lsi = buid_base + PHB_BUID_LSI_OFFSET;
- p->buid_msi = buid_base + PHB_BUID_MSI_OFFSET;
- p->io_base = ioc->mmio1_win_start + PHBn_IO_BASE(index);
- p->m32_base = ioc->mmio2_win_start + PHBn_M32_BASE(index);
- p->m64_base = ioc->mmio2_win_start + PHBn_M64_BASE(index);
- p->phb.scan_map = 0x1; /* Only device 0 to scan */
-
- /* Find P7IOC base location code in IOC */
- p->phb.base_loc_code = dt_prop_get_def(ioc->dt_node,
- "ibm,io-base-loc-code", NULL);
- if (!p->phb.base_loc_code)
- prerror("P7IOC: Base location code not found !\n");
-
- /* Create device node for PHB */
- p7ioc_pcie_add_node(p);
-
- /* Register OS interrupt sources */
- register_irq_source(&p7ioc_msi_irq_ops, p, p->buid_msi << 4, 256);
- register_irq_source(&p7ioc_lsi_irq_ops, p, p->buid_lsi << 4, 8);
-
- /* Initialize IODA table caches */
- p7ioc_phb_init_ioda_cache(p);
-
- /* We register the PHB before we initialize it so we
- * get a useful OPAL ID for it
- */
- pci_register_phb(&p->phb, OPAL_DYNAMIC_PHB_ID);
- slot = p7ioc_phb_slot_create(&p->phb);
- if (!slot)
- prlog(PR_NOTICE, "P7IOC: Cannot create PHB#%x slot\n",
- p->phb.opal_id);
-
- /* Platform additional setup */
- if (platform.pci_setup_phb)
- platform.pci_setup_phb(&p->phb, p->index);
-}
-
-static bool p7ioc_phb_wait_dlp_reset(struct p7ioc_phb *p)
-{
- unsigned int i;
- uint64_t val;
-
- /*
- * Firmware cannot access the UTL core regs or PCI config space
- * until the cores are out of DL_PGRESET.
- * DL_PGRESET should be polled until it is inactive with a value
- * of '0'. The recommended polling frequency is once every 1ms.
- * Firmware should poll at least 200 attempts before giving up.
- * MMIO Stores to the link are silently dropped by the UTL core if
- * the link is down.
- * MMIO Loads to the link will be dropped by the UTL core and will
- * eventually time-out and will return an all ones response if the
- * link is down.
- */
-#define DLP_RESET_ATTEMPTS 400
-
- printf("P7IOC: Waiting for DLP PG reset to complete...\n");
- for (i = 0; i < DLP_RESET_ATTEMPTS; i++) {
- val = in_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL);
- if (!(val & PHB_PCIE_DLP_TC_DL_PGRESET))
- break;
- time_wait_ms(1);
- }
- if (val & PHB_PCIE_DLP_TC_DL_PGRESET) {
- PHBERR(p, "Timeout waiting for DLP PG reset !\n");
- return false;
- }
- return true;
-}
-
-/* p7ioc_phb_init_rc - Initialize the Root Complex config space
- */
-static bool p7ioc_phb_init_rc_cfg(struct p7ioc_phb *p)
-{
- int64_t ecap, aercap;
-
- /* XXX Handle errors ? */
-
- /* Init_51..51:
- *
- * Set primary bus to 0, secondary to 1 and subordinate to 0xff
- */
- p7ioc_pcicfg_write32(&p->phb, 0, PCI_CFG_PRIMARY_BUS, 0x00ff0100);
-
- /* Init_52..57
- *
- * IO and Memory base & limits are set to base > limit, which
- * allows all inbounds.
- *
- * XXX This has the potential of confusing the OS which might
- * think that nothing is forwarded downstream. We probably need
- * to fix this to match the IO and M32 PHB windows
- */
- p7ioc_pcicfg_write16(&p->phb, 0, PCI_CFG_IO_BASE, 0x0010);
- p7ioc_pcicfg_write32(&p->phb, 0, PCI_CFG_MEM_BASE, 0x00000010);
- p7ioc_pcicfg_write32(&p->phb, 0, PCI_CFG_PREF_MEM_BASE, 0x00000010);
-
- /* Init_58..: Setup bridge control to enable forwarding of CORR, FATAL,
- * and NONFATAL errors
- */
- p7ioc_pcicfg_write16(&p->phb, 0, PCI_CFG_BRCTL, PCI_CFG_BRCTL_SERR_EN);
-
- /* Init_60..61
- *
- * PCIE Device control/status, enable error reporting, disable relaxed
- * ordering, set MPS to 128 (see note), clear errors.
- *
- * Note: The doc recommends to set MPS to 4K. This has proved to have
- * some issues as it requires specific claming of MRSS on devices and
- * we've found devices in the field that misbehave when doing that.
- *
- * We currently leave it all to 128 bytes (minimum setting) at init
- * time. The generic PCIe probing later on might apply a different
- * value, or the kernel will, but we play it safe at early init
- */
- if (p->ecap <= 0) {
- ecap = pci_find_cap(&p->phb, 0, PCI_CFG_CAP_ID_EXP);
- if (ecap < 0) {
- PHBERR(p, "Can't locate PCI-E capability\n");
- return false;
- }
- p->ecap = ecap;
- } else {
- ecap = p->ecap;
- }
-
- p7ioc_pcicfg_write16(&p->phb, 0, ecap + PCICAP_EXP_DEVSTAT,
- PCICAP_EXP_DEVSTAT_CE |
- PCICAP_EXP_DEVSTAT_NFE |
- PCICAP_EXP_DEVSTAT_FE |
- PCICAP_EXP_DEVSTAT_UE);
-
- p7ioc_pcicfg_write16(&p->phb, 0, ecap + PCICAP_EXP_DEVCTL,
- PCICAP_EXP_DEVCTL_CE_REPORT |
- PCICAP_EXP_DEVCTL_NFE_REPORT |
- PCICAP_EXP_DEVCTL_FE_REPORT |
- PCICAP_EXP_DEVCTL_UR_REPORT |
- SETFIELD(PCICAP_EXP_DEVCTL_MPS, 0, PCIE_MPS_128B));
-
- /* Init_62..63
- *
- * Root Control Register. Enable error reporting
- *
- * Note: Added CRS visibility.
- */
- p7ioc_pcicfg_write16(&p->phb, 0, ecap + PCICAP_EXP_RC,
- PCICAP_EXP_RC_SYSERR_ON_CE |
- PCICAP_EXP_RC_SYSERR_ON_NFE |
- PCICAP_EXP_RC_SYSERR_ON_FE |
- PCICAP_EXP_RC_CRS_VISIBLE);
-
- /* Init_64..65
- *
- * Device Control 2. Enable ARI fwd, set timer
- */
- p7ioc_pcicfg_write16(&p->phb, 0, ecap + PCICAP_EXP_DCTL2,
- SETFIELD(PCICAP_EXP_DCTL2_CMPTOUT, 0, 2) |
- PCICAP_EXP_DCTL2_ARI_FWD);
-
- /* Init_66..81
- *
- * AER inits
- */
- aercap = pci_find_ecap(&p->phb, 0, PCIECAP_ID_AER, NULL);
- if (aercap < 0) {
- /* Shouldn't happen */
- PHBERR(p, "Failed to locate AER capability in bridge\n");
- return false;
- }
- p->aercap = aercap;
-
- /* Clear all UE status */
- p7ioc_pcicfg_write32(&p->phb, 0, aercap + PCIECAP_AER_UE_STATUS,
- 0xffffffff);
- /* Disable some error reporting as per the P7IOC spec */
- p7ioc_pcicfg_write32(&p->phb, 0, aercap + PCIECAP_AER_UE_MASK,
- PCIECAP_AER_UE_POISON_TLP |
- PCIECAP_AER_UE_COMPL_TIMEOUT |
- PCIECAP_AER_UE_COMPL_ABORT |
- PCIECAP_AER_UE_ECRC);
- /* Report some errors as fatal */
- p7ioc_pcicfg_write32(&p->phb, 0, aercap + PCIECAP_AER_UE_SEVERITY,
- PCIECAP_AER_UE_DLP |
- PCIECAP_AER_UE_SURPRISE_DOWN |
- PCIECAP_AER_UE_FLOW_CTL_PROT |
- PCIECAP_AER_UE_UNEXP_COMPL |
- PCIECAP_AER_UE_RECV_OVFLOW |
- PCIECAP_AER_UE_MALFORMED_TLP);
- /* Clear all CE status */
- p7ioc_pcicfg_write32(&p->phb, 0, aercap + PCIECAP_AER_CE_STATUS,
- 0xffffffff);
- /* Disable some error reporting as per the P7IOC spec */
- p7ioc_pcicfg_write32(&p->phb, 0, aercap + PCIECAP_AER_CE_MASK,
- PCIECAP_AER_CE_ADV_NONFATAL);
- /* Enable ECRC generation & checking */
- p7ioc_pcicfg_write32(&p->phb, 0, aercap + PCIECAP_AER_CAPCTL,
- PCIECAP_AER_CAPCTL_ECRCG_EN |
- PCIECAP_AER_CAPCTL_ECRCC_EN);
- /* Enable reporting in root error control */
- p7ioc_pcicfg_write32(&p->phb, 0, aercap + PCIECAP_AER_RERR_CMD,
- PCIECAP_AER_RERR_CMD_FE |
- PCIECAP_AER_RERR_CMD_NFE |
- PCIECAP_AER_RERR_CMD_CE);
- /* Clear root error status */
- p7ioc_pcicfg_write32(&p->phb, 0, aercap + PCIECAP_AER_RERR_STA,
- 0xffffffff);
-
- return true;
-}
-
-static void p7ioc_phb_init_utl(struct p7ioc_phb *p)
-{
- /* Init_82..84: Clear spurious errors and assign errors to the
- * right "interrupt" signal
- */
- out_be64(p->regs + UTL_SYS_BUS_AGENT_STATUS, 0xffffffffffffffffUL);
- out_be64(p->regs + UTL_SYS_BUS_AGENT_ERR_SEVERITY, 0x0000000000000000UL);
- out_be64(p->regs + UTL_SYS_BUS_AGENT_IRQ_EN, 0xac80000000000000UL);
-
- /* Init_85..89: Setup buffer allocations */
- out_be64(p->regs + UTL_OUT_POST_DAT_BUF_ALLOC, 0x0400000000000000UL);
- out_be64(p->regs + UTL_IN_POST_HDR_BUF_ALLOC, 0x1000000000000000UL);
- out_be64(p->regs + UTL_IN_POST_DAT_BUF_ALLOC, 0x4000000000000000UL);
- out_be64(p->regs + UTL_PCIE_TAGS_ALLOC, 0x0800000000000000UL);
- out_be64(p->regs + UTL_GBIF_READ_TAGS_ALLOC, 0x0800000000000000UL);
-
- /* Init_90: PCI Express port control */
- out_be64(p->regs + UTL_PCIE_PORT_CONTROL, 0x8480000000000000UL);
-
- /* Init_91..93: Clean & setup port errors */
- out_be64(p->regs + UTL_PCIE_PORT_STATUS, 0xff7fffffffffffffUL);
- out_be64(p->regs + UTL_PCIE_PORT_ERROR_SEV, 0x00e0000000000000UL);
- out_be64(p->regs + UTL_PCIE_PORT_IRQ_EN, 0x7e65000000000000UL);
-
- /* Init_94 : Cleanup RC errors */
- out_be64(p->regs + UTL_RC_STATUS, 0xffffffffffffffffUL);
-}
-
-static void p7ioc_phb_init_errors(struct p7ioc_phb *p)
-{
- /* Init_98: LEM Error Mask : Temporarily disable error interrupts */
- out_be64(p->regs + PHB_LEM_ERROR_MASK, 0xffffffffffffffffUL);
-
- /* Init_99..107: Configure main error traps & clear old state */
- out_be64(p->regs + PHB_ERR_STATUS, 0xffffffffffffffffUL);
- out_be64(p->regs + PHB_ERR1_STATUS, 0x0000000000000000UL);
- out_be64(p->regs + PHB_ERR_LEM_ENABLE, 0xffffffffefffffffUL);
- out_be64(p->regs + PHB_ERR_FREEZE_ENABLE, 0x0000000061c00000UL);
- out_be64(p->regs + PHB_ERR_AIB_FENCE_ENABLE, 0xffffffc58c000000UL);
- out_be64(p->regs + PHB_ERR_LOG_0, 0x0000000000000000UL);
- out_be64(p->regs + PHB_ERR_LOG_1, 0x0000000000000000UL);
- out_be64(p->regs + PHB_ERR_STATUS_MASK, 0x0000000000000000UL);
- out_be64(p->regs + PHB_ERR1_STATUS_MASK, 0x0000000000000000UL);
-
- /* Init_108_116: Configure MMIO error traps & clear old state */
- out_be64(p->regs + PHB_OUT_ERR_STATUS, 0xffffffffffffffffUL);
- out_be64(p->regs + PHB_OUT_ERR1_STATUS, 0x0000000000000000UL);
- out_be64(p->regs + PHB_OUT_ERR_LEM_ENABLE, 0xffffffffffffffffUL);
- out_be64(p->regs + PHB_OUT_ERR_FREEZE_ENABLE, 0x0000430803000000UL);
- out_be64(p->regs + PHB_OUT_ERR_AIB_FENCE_ENABLE, 0x9df3bc00f0f0700fUL);
- out_be64(p->regs + PHB_OUT_ERR_LOG_0, 0x0000000000000000UL);
- out_be64(p->regs + PHB_OUT_ERR_LOG_1, 0x0000000000000000UL);
- out_be64(p->regs + PHB_OUT_ERR_STATUS_MASK, 0x0000000000000000UL);
- out_be64(p->regs + PHB_OUT_ERR1_STATUS_MASK, 0x0000000000000000UL);
-
- /* Init_117_125: Configure DMA_A error traps & clear old state */
- out_be64(p->regs + PHB_INA_ERR_STATUS, 0xffffffffffffffffUL);
- out_be64(p->regs + PHB_INA_ERR1_STATUS, 0x0000000000000000UL);
- out_be64(p->regs + PHB_INA_ERR_LEM_ENABLE, 0xffffffffffffffffUL);
- out_be64(p->regs + PHB_INA_ERR_FREEZE_ENABLE, 0xc00003ff01006000UL);
- out_be64(p->regs + PHB_INA_ERR_AIB_FENCE_ENABLE, 0x3fff50007e559fd8UL);
- out_be64(p->regs + PHB_INA_ERR_LOG_0, 0x0000000000000000UL);
- out_be64(p->regs + PHB_INA_ERR_LOG_1, 0x0000000000000000UL);
- out_be64(p->regs + PHB_INA_ERR_STATUS_MASK, 0x0000000000000000UL);
- out_be64(p->regs + PHB_INA_ERR1_STATUS_MASK, 0x0000000000000000UL);
-
- /* Init_126_134: Configure DMA_B error traps & clear old state */
- out_be64(p->regs + PHB_INB_ERR_STATUS, 0xffffffffffffffffUL);
- out_be64(p->regs + PHB_INB_ERR1_STATUS, 0x0000000000000000UL);
- out_be64(p->regs + PHB_INB_ERR_LEM_ENABLE, 0xffffffffffffffffUL);
- out_be64(p->regs + PHB_INB_ERR_FREEZE_ENABLE, 0x0000000000000000UL);
- out_be64(p->regs + PHB_INB_ERR_AIB_FENCE_ENABLE, 0x18ff80ffff7f0000UL);
- out_be64(p->regs + PHB_INB_ERR_LOG_0, 0x0000000000000000UL);
- out_be64(p->regs + PHB_INB_ERR_LOG_1, 0x0000000000000000UL);
- out_be64(p->regs + PHB_INB_ERR_STATUS_MASK, 0x0000000000000000UL);
- out_be64(p->regs + PHB_INB_ERR1_STATUS_MASK, 0x0000000000000000UL);
-
- /* Init_135..138: Cleanup & configure LEM */
- out_be64(p->regs + PHB_LEM_FIR_ACCUM, 0x0000000000000000UL);
- out_be64(p->regs + PHB_LEM_ACTION0, 0xffffffffffffffffUL);
- out_be64(p->regs + PHB_LEM_ACTION1, 0x0000000000000000UL);
- out_be64(p->regs + PHB_LEM_WOF, 0x0000000000000000UL);
-}
-
-/* p7ioc_phb_init - Initialize the PHB hardware
- *
- * This is currently only called at boot time. It will eventually
- * be called at runtime, for example in some cases of error recovery
- * after a PHB reset in which case we might need locks etc...
- */
-int64_t p7ioc_phb_init(struct p7ioc_phb *p)
-{
- uint64_t val;
-
- PHBDBG(p, "Initializing PHB %x...\n", p->index);
-
- /*
- * We re-init the PHB on a creset (and a few other cases)
- * so clear the broken flag
- */
- p->broken = false;
-
- /* For some reason, the doc wants us to read the version
- * register, so let's do it. We shoud probably check that
- * the value makes sense...
- */
- val = in_be64(p->regs_asb + PHB_VERSION);
- p->rev = ((val >> 16) & 0xffff) | (val & 0xffff);
- PHBDBG(p, "PHB version: %08x\n", p->rev);
-
- /*
- * Configure AIB operations
- *
- * This register maps upbound commands to AIB channels.
- * DMA Write=0, DMA Read=2, MMIO Load Response=1,
- * Interrupt Request=1, TCE Read=3.
- */
- /* Init_1: AIB TX Channel Mapping */
- out_be64(p->regs_asb + PHB_AIB_TX_CHAN_MAPPING, 0x0211300000000000UL);
-
- /*
- * This group of steps initializes the AIB RX credits for
- * the CI block’s port that is attached to this PHB.
- *
- * Channel 0 (Dkill): 32 command credits, 0 data credits
- * (effectively infinite command credits)
- * Channel 1 (DMA/TCE Read Responses): 32 command credits, 32 data
- * credits (effectively infinite
- * command and data credits)
- * Channel 2 (Interrupt Reissue/Return): 32 command, 0 data credits
- * (effectively infinite
- * command credits)
- * Channel 3 (MMIO Load/Stores, EOIs): 1 command, 1 data credit
- */
-
- /* Init_2: AIB RX Command Credit */
- out_be64(p->regs_asb + PHB_AIB_RX_CMD_CRED, 0x0020002000200001UL);
- /* Init_3: AIB RX Data Credit */
- out_be64(p->regs_asb + PHB_AIB_RX_DATA_CRED, 0x0000002000000001UL);
- /* Init_4: AXIB RX Credit Init Timer */
- out_be64(p->regs_asb + PHB_AIB_RX_CRED_INIT_TIMER, 0xFF00000000000000UL);
-
- /*
- * Enable all 32 AIB and TCE tags.
- *
- * AIB tags are used for DMA read requests.
- * TCE tags are used for every internal transaction as well as TCE
- * read requests.
- */
-
- /* Init_5: PHB - AIB Tag Enable Register */
- out_be64(p->regs_asb + PHB_AIB_TAG_ENABLE, 0xFFFFFFFF00000000UL);
- /* Init_6: PHB – TCE Tag Enable Register */
- out_be64(p->regs_asb + PHB_TCE_TAG_ENABLE, 0xFFFFFFFF00000000UL);
-
- /* Init_7: PCIE - System Configuration Register
- *
- * This is the default value out of reset. This register can be
- * modified to change the following fields if needed:
- *
- * bits 04:09 - SYS_EC0C_MAXLINKWIDTH[5:0]
- * The default link width is x8. This can be reduced
- * to x1 or x4, if needed.
- *
- * bits 10:12 - SYS_EC04_MAX_PAYLOAD[2:0]
- *
- * The default max payload size is 4KB. This can be
- * reduced to the allowed ranges from 128B
- * to 2KB if needed.
- */
- out_be64(p->regs + PHB_PCIE_SYSTEM_CONFIG, 0x422800FC20000000UL);
-
- /* Init_8: PHB - PCI-E Reset Register
- *
- * This will deassert reset for the PCI-E cores, including the
- * PHY and HSS macros. The TLDLP core will begin link training
- * shortly after this register is written.
- * This will also assert reset for the internal scan-only error
- * report macros. The error report macro reset will be deasserted
- * in a later step.
- * Firmware will verify in a later step whether the PCI-E link
- * has been established.
- *
- * NOTE: We perform a PERST at the end of the init sequence so
- * we could probably skip that link training.
- */
- out_be64(p->regs + PHB_RESET, 0xE800000000000000UL);
-
- /* Init_9: BUID
- *
- * Only the top 5 bit of the MSI field are implemented, the bottom
- * are always 0. Our buid_msi value should also be a multiple of
- * 16 so it should all fit well
- */
- val = SETFIELD(PHB_BUID_LSI, 0ul, P7_BUID_BASE(p->buid_lsi));
- val |= SETFIELD(PHB_BUID_MSI, 0ul, P7_BUID_BASE(p->buid_msi));
- out_be64(p->regs + PHB_BUID, val);
-
- /* Init_10..12: IO Space */
- out_be64(p->regs + PHB_IO_BASE_ADDR, p->io_base);
- out_be64(p->regs + PHB_IO_BASE_MASK, ~(PHB_IO_SIZE - 1));
- out_be64(p->regs + PHB_IO_START_ADDR, 0);
-
- /* Init_13..15: M32 Space */
- out_be64(p->regs + PHB_M32_BASE_ADDR, p->m32_base + M32_PCI_START);
- out_be64(p->regs + PHB_M32_BASE_MASK, ~(M32_PCI_SIZE - 1));
- out_be64(p->regs + PHB_M32_START_ADDR, M32_PCI_START);
-
- /* Init_16: PCIE-E Outbound Request Upper Address */
- out_be64(p->regs + PHB_M64_UPPER_BITS, 0);
-
- /* Init_17: PCIE-E PHB2 Configuration
- *
- * We enable IO, M32, 32-bit MSI and 64-bit MSI
- */
- out_be64(p->regs + PHB_PHB2_CONFIG,
- PHB_PHB2C_32BIT_MSI_EN |
- PHB_PHB2C_IO_EN |
- PHB_PHB2C_64BIT_MSI_EN |
- PHB_PHB2C_M32_EN |
- PHB_PHB2C_64B_TCE_EN);
-
- /* Init_18..xx: Reset all IODA tables */
- p7ioc_ioda_reset(&p->phb, false);
-
- /* Init_42..47: Clear UTL & DLP error log regs */
- out_be64(p->regs + PHB_PCIE_UTL_ERRLOG1, 0xffffffffffffffffUL);
- out_be64(p->regs + PHB_PCIE_UTL_ERRLOG2, 0xffffffffffffffffUL);
- out_be64(p->regs + PHB_PCIE_UTL_ERRLOG3, 0xffffffffffffffffUL);
- out_be64(p->regs + PHB_PCIE_UTL_ERRLOG4, 0xffffffffffffffffUL);
- out_be64(p->regs + PHB_PCIE_DLP_ERRLOG1, 0xffffffffffffffffUL);
- out_be64(p->regs + PHB_PCIE_DLP_ERRLOG2, 0xffffffffffffffffUL);
-
- /* Init_48: Wait for DLP core to be out of reset */
- if (!p7ioc_phb_wait_dlp_reset(p))
- goto failed;
-
- /* Init_49 - Clear port status */
- out_be64(p->regs + UTL_PCIE_PORT_STATUS, 0xffffffffffffffffUL);
-
- /* Init_50..81: Init root complex config space */
- if (!p7ioc_phb_init_rc_cfg(p))
- goto failed;
-
- /* Init_82..94 : Init UTL */
- p7ioc_phb_init_utl(p);
-
- /* Init_95: PCI-E Reset, deassert reset for internal error macros */
- out_be64(p->regs + PHB_RESET, 0xe000000000000000UL);
-
- /* Init_96: PHB Control register. Various PHB settings:
- *
- * - Enable ECC for various internal RAMs
- * - Enable all TCAM entries
- * - Set failed DMA read requests to return Completer Abort on error
- */
- out_be64(p->regs + PHB_CONTROL, 0x7f38000000000000UL);
-
- /* Init_97: Legacy Control register
- *
- * The spec sets bit 0 to enable DKill to flush the TCEs. We do not
- * use that mechanism however, we require the OS to directly access
- * the TCE Kill register, so we leave that bit set to 0
- */
- out_be64(p->regs + PHB_LEGACY_CTRL, 0x0000000000000000);
-
- /* Init_98..138 : Setup error registers */
- p7ioc_phb_init_errors(p);
-
- /* Init_139: Read error summary */
- val = in_be64(p->regs + PHB_ETU_ERR_SUMMARY);
- if (val) {
- PHBERR(p, "Errors detected during PHB init: 0x%16llx\n", val);
- goto failed;
- }
-
- /* Steps Init_140..142 have been removed from the spec. */
-
- /* Init_143..144: Enable IO, MMIO, Bus master etc... and clear
- * status bits
- */
- p7ioc_pcicfg_write16(&p->phb, 0, PCI_CFG_STAT,
- PCI_CFG_STAT_SENT_TABORT |
- PCI_CFG_STAT_RECV_TABORT |
- PCI_CFG_STAT_RECV_MABORT |
- PCI_CFG_STAT_SENT_SERR |
- PCI_CFG_STAT_RECV_PERR);
- p7ioc_pcicfg_write16(&p->phb, 0, PCI_CFG_CMD,
- PCI_CFG_CMD_SERR_EN |
- PCI_CFG_CMD_PERR_RESP |
- PCI_CFG_CMD_BUS_MASTER_EN |
- PCI_CFG_CMD_MEM_EN |
- PCI_CFG_CMD_IO_EN);
-
- /* At this point, the spec suggests doing a bus walk. However we
- * haven't powered up the slots with the SHCP controller. We'll
- * deal with that and link training issues later, for now, let's
- * enable the full range of error detection
- */
-
- /* Init_145..149: Enable error interrupts and LEM */
- out_be64(p->regs + PHB_ERR_IRQ_ENABLE, 0x0000000061c00000UL);
- out_be64(p->regs + PHB_OUT_ERR_IRQ_ENABLE, 0x0000430803000000UL);
- out_be64(p->regs + PHB_INA_ERR_IRQ_ENABLE, 0xc00003ff01006000UL);
- out_be64(p->regs + PHB_INB_ERR_IRQ_ENABLE, 0x0000000000000000UL);
- out_be64(p->regs + PHB_LEM_ERROR_MASK, 0x1249a1147f500f2cUL);
-
- /* Init_150: Enable DMA read/write TLP address speculation */
- out_be64(p->regs + PHB_TCE_PREFETCH, 0x0000c00000000000UL);
-
- /* Init_151..152: Set various timeouts */
- out_be64(p->regs + PHB_TIMEOUT_CTRL1, 0x1611112010200000UL);
- out_be64(p->regs + PHB_TIMEOUT_CTRL2, 0x0000561300000000UL);
-
- return OPAL_SUCCESS;
-
- failed:
- PHBERR(p, "Initialization failed\n");
- p->broken = true;
-
- return OPAL_HARDWARE;
-}
-
-void p7ioc_phb_reset(struct phb *phb)
-{
- struct p7ioc_phb *p = phb_to_p7ioc_phb(phb);
- struct p7ioc *ioc = p->ioc;
- uint64_t ci_idx, rreg;
- unsigned int i;
- bool fenced;
-
- /* Check our fence status. The fence bits we care about are
- * two bits per PHB at IBM bit location 14 and 15 + 4*phb
- */
- fenced = p7ioc_phb_fenced(p);
-
- PHBDBG(p, "PHB reset... (fenced: %d)\n", (int)fenced);
-
- /*
- * If not fenced and already functional, let's do an IODA reset
- * to clear pending DMAs and wait a bit for thing to settle. It's
- * notable that the IODA table cache won't be emptied so that we
- * can restore them during error recovery.
- */
- if (!p->broken && !fenced) {
- PHBDBG(p, " ioda reset ...\n");
- p7ioc_ioda_reset(&p->phb, false);
- time_wait_ms(100);
- }
-
- /* CI port index */
- ci_idx = p->index + 2;
-
- /* Reset register bits for this PHB */
- rreg = 0;/*PPC_BIT(8 + ci_idx * 2);*/ /* CI port config reset */
- rreg |= PPC_BIT(9 + ci_idx * 2); /* CI port func reset */
- rreg |= PPC_BIT(32 + p->index); /* PHBn config reset */
-
- /* Mask various errors during reset and clear pending errors */
- out_be64(ioc->regs + P7IOC_CIn_LEM_ERR_MASK(ci_idx),
- 0xa4f4000000000000ul);
- out_be64(p->regs_asb + PHB_LEM_ERROR_MASK, 0xadb650c9808dd051ul);
- out_be64(ioc->regs + P7IOC_CIn_LEM_FIR(ci_idx), 0);
-
- /* We need to retry in case the fence doesn't lift due to a
- * problem with lost credits (HW guys). How many times ?
- */
-#define MAX_PHB_RESET_RETRIES 5
- for (i = 0; i < MAX_PHB_RESET_RETRIES; i++) {
- PHBDBG(p, " reset try %d...\n", i);
- /* Apply reset */
- out_be64(ioc->regs + P7IOC_CCRR, rreg);
- time_wait_ms(1);
- out_be64(ioc->regs + P7IOC_CCRR, 0);
-
- /* Check if fence lifed */
- fenced = p7ioc_phb_fenced(p);
- PHBDBG(p, " fenced: %d...\n", (int)fenced);
- if (!fenced)
- break;
- }
-
- /* Reset failed, not much to do, maybe add an error return */
- if (fenced) {
- PHBERR(p, "Reset failed, fence still set !\n");
- p->broken = true;
- return;
- }
-
- /* Wait a bit */
- time_wait_ms(100);
-
- /* Re-initialize the PHB */
- p7ioc_phb_init(p);
-
- /* Restore the CI error mask */
- out_be64(ioc->regs + P7IOC_CIn_LEM_ERR_MASK_AND(ci_idx), 0);
-}
-
-
-
diff --git a/hw/p7ioc.c b/hw/p7ioc.c
deleted file mode 100644
index 44ce3d8..0000000
--- a/hw/p7ioc.c
+++ /dev/null
@@ -1,688 +0,0 @@
-/* Copyright 2013-2014 IBM Corp.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- * implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <skiboot.h>
-#include <p7ioc.h>
-#include <p7ioc-regs.h>
-#include <cec.h>
-#include <opal.h>
-#include <io.h>
-#include <vpd.h>
-#include <interrupts.h>
-#include <ccan/str/str.h>
-
-/*
- * Determine the base address of LEM registers according to
- * the indicated error source.
- */
-static void *p7ioc_LEM_base(struct p7ioc *ioc, uint32_t err_src)
-{
- uint32_t index;
- void *base = NULL;
-
- switch (err_src) {
- case P7IOC_ERR_SRC_RGC:
- base = ioc->regs + P7IOC_RGC_LEM_BASE;
- break;
- case P7IOC_ERR_SRC_BI_UP:
- base = ioc->regs + P7IOC_BI_UP_LEM_BASE;
- break;
- case P7IOC_ERR_SRC_BI_DOWN:
- base = ioc->regs + P7IOC_BI_DOWN_LEM_BASE;
- break;
- case P7IOC_ERR_SRC_CI_P0:
- case P7IOC_ERR_SRC_CI_P1:
- case P7IOC_ERR_SRC_CI_P2:
- case P7IOC_ERR_SRC_CI_P3:
- case P7IOC_ERR_SRC_CI_P4:
- case P7IOC_ERR_SRC_CI_P5:
- case P7IOC_ERR_SRC_CI_P6:
- case P7IOC_ERR_SRC_CI_P7:
- index = err_src - P7IOC_ERR_SRC_CI_P0;
- base = ioc->regs + P7IOC_CI_PORTn_LEM_BASE(index);
- break;
- case P7IOC_ERR_SRC_PHB0:
- case P7IOC_ERR_SRC_PHB1:
- case P7IOC_ERR_SRC_PHB2:
- case P7IOC_ERR_SRC_PHB3:
- case P7IOC_ERR_SRC_PHB4:
- case P7IOC_ERR_SRC_PHB5:
- index = err_src - P7IOC_ERR_SRC_PHB0;
- base = ioc->regs + P7IOC_PHBn_LEM_BASE(index);
- break;
- case P7IOC_ERR_SRC_MISC:
- base = ioc->regs + P7IOC_MISC_LEM_BASE;
- break;
- case P7IOC_ERR_SRC_I2C:
- base = ioc->regs + P7IOC_I2C_LEM_BASE;
- break;
- default:
- prerror("%s: Unknown error source %d\n",
- __func__, err_src);
- }
-
- return base;
-}
-
-static void p7ioc_get_diag_common(struct p7ioc *ioc,
- void *base,
- struct OpalIoP7IOCErrorData *data)
-{
- /* GEM */
- data->gemXfir = in_be64(ioc->regs + P7IOC_GEM_XFIR);
- data->gemRfir = in_be64(ioc->regs + P7IOC_GEM_RFIR);
- data->gemRirqfir = in_be64(ioc->regs + P7IOC_GEM_RIRQFIR);
- data->gemMask = in_be64(ioc->regs + P7IOC_GEM_MASK);
- data->gemRwof = in_be64(ioc->regs + P7IOC_GEM_RWOF);
-
- /* LEM */
- data->lemFir = in_be64(base + P7IOC_LEM_FIR_OFFSET);
- data->lemErrMask = in_be64(base + P7IOC_LEM_ERR_MASK_OFFSET);
- data->lemAction0 = in_be64(base + P7IOC_LEM_ACTION_0_OFFSET);
- data->lemAction1 = in_be64(base + P7IOC_LEM_ACTION_1_OFFSET);
- data->lemWof = in_be64(base + P7IOC_LEM_WOF_OFFSET);
-}
-
-static int64_t p7ioc_get_diag_data(struct io_hub *hub,
- void *diag_buffer,
- uint64_t diag_buffer_len)
-{
- struct p7ioc *ioc = iohub_to_p7ioc(hub);
- struct OpalIoP7IOCErrorData *data = diag_buffer;
- void *base;
-
- /* Make sure we have enough buffer */
- if (diag_buffer_len < sizeof(struct OpalIoP7IOCErrorData))
- return OPAL_PARAMETER;
-
- /* We need do nothing if there're no pending errors */
- if (!p7ioc_err_pending(ioc))
- return OPAL_CLOSED;
-
- /*
- * We needn't collect diag-data for CI Port{2, ..., 7}
- * and PHB{0, ..., 5} since their errors (except GXE)
- * have been cached to the specific PHB.
- */
- base = p7ioc_LEM_base(ioc, ioc->err.err_src);
- if (!base) {
- p7ioc_set_err_pending(ioc, false);
- return OPAL_INTERNAL_ERROR;
- }
-
- switch (ioc->err.err_src) {
- case P7IOC_ERR_SRC_RGC:
- data->type = OPAL_P7IOC_DIAG_TYPE_RGC;
- p7ioc_get_diag_common(ioc, base, data);
-
- data->rgc.rgcStatus = in_be64(ioc->regs + 0x3E1C10);
- data->rgc.rgcLdcp = in_be64(ioc->regs + 0x3E1C18);
-
- break;
- case P7IOC_ERR_SRC_BI_UP:
- data->type = OPAL_P7IOC_DIAG_TYPE_BI;
- data->bi.biDownbound = 0;
- p7ioc_get_diag_common(ioc, base, data);
-
- data->bi.biLdcp0 = in_be64(ioc->regs + 0x3C0100);
- data->bi.biLdcp1 = in_be64(ioc->regs + 0x3C0108);
- data->bi.biLdcp2 = in_be64(ioc->regs + 0x3C0110);
- data->bi.biFenceStatus = in_be64(ioc->regs + 0x3C0130);
-
- break;
- case P7IOC_ERR_SRC_BI_DOWN:
- data->type = OPAL_P7IOC_DIAG_TYPE_BI;
- data->bi.biDownbound = 1;
- p7ioc_get_diag_common(ioc, base, data);
-
- data->bi.biLdcp0 = in_be64(ioc->regs + 0x3C0118);
- data->bi.biLdcp1 = in_be64(ioc->regs + 0x3C0120);
- data->bi.biLdcp2 = in_be64(ioc->regs + 0x3C0128);
- data->bi.biFenceStatus = in_be64(ioc->regs + 0x3C0130);
-
- break;
- case P7IOC_ERR_SRC_CI_P0:
- case P7IOC_ERR_SRC_CI_P1:
- data->type = OPAL_P7IOC_DIAG_TYPE_CI;
- data->ci.ciPort = ioc->err.err_src - P7IOC_ERR_SRC_CI_P0;
- p7ioc_get_diag_common(ioc, base, data);
-
- data->ci.ciPortStatus = in_be64(base + 0x008);
- data->ci.ciPortLdcp = in_be64(base + 0x010);
- break;
- case P7IOC_ERR_SRC_MISC:
- data->type = OPAL_P7IOC_DIAG_TYPE_MISC;
- p7ioc_get_diag_common(ioc, base, data);
- break;
- case P7IOC_ERR_SRC_I2C:
- data->type = OPAL_P7IOC_DIAG_TYPE_I2C;
- p7ioc_get_diag_common(ioc, base, data);
- break;
- default:
- p7ioc_set_err_pending(ioc, false);
- return OPAL_CLOSED;
- }
-
- /* For errors of MAL class, we need mask it */
- if (ioc->err.err_class == P7IOC_ERR_CLASS_MAL)
- out_be64(base + P7IOC_LEM_ERR_MASK_OR_OFFSET,
- PPC_BIT(63 - ioc->err.err_bit));
- p7ioc_set_err_pending(ioc, false);
-
- return OPAL_SUCCESS;
-}
-
-static const struct io_hub_ops p7ioc_hub_ops = {
- .get_diag_data = p7ioc_get_diag_data,
- .reset = p7ioc_reset,
-};
-
-static int64_t p7ioc_rgc_get_xive(struct irq_source *is, uint32_t isn,
- uint16_t *server, uint8_t *prio)
-{
- struct p7ioc *ioc = is->data;
- uint32_t irq = (isn & 0xf);
- uint32_t fbuid = P7_IRQ_FBUID(isn);
- uint64_t xive;
-
- if (fbuid != ioc->rgc_buid)
- return OPAL_PARAMETER;
-
- xive = ioc->xive_cache[irq];
- *server = GETFIELD(IODA_XIVT_SERVER, xive);
- *prio = GETFIELD(IODA_XIVT_PRIORITY, xive);
-
- return OPAL_SUCCESS;
- }
-
-static int64_t p7ioc_rgc_set_xive(struct irq_source *is, uint32_t isn,
- uint16_t server, uint8_t prio)
-{
- struct p7ioc *ioc = is->data;
- uint32_t irq = (isn & 0xf);
- uint32_t fbuid = P7_IRQ_FBUID(isn);
- uint64_t xive;
- uint64_t m_server, m_prio;
-
- if (fbuid != ioc->rgc_buid)
- return OPAL_PARAMETER;
-
- xive = SETFIELD(IODA_XIVT_SERVER, 0ull, server);
- xive = SETFIELD(IODA_XIVT_PRIORITY, xive, prio);
- ioc->xive_cache[irq] = xive;
-
- /* Now we mangle the server and priority */
- if (prio == 0xff) {
- m_server = 0;
- m_prio = 0xff;
- } else {
- m_server = server >> 3;
- m_prio = (prio >> 3) | ((server & 7) << 5);
- }
-
- /* Update the XIVE. Don't care HRT entry on P7IOC */
- out_be64(ioc->regs + 0x3e1820, (0x0002000000000000UL | irq));
- xive = in_be64(ioc->regs + 0x3e1830);
- xive = SETFIELD(IODA_XIVT_SERVER, xive, m_server);
- xive = SETFIELD(IODA_XIVT_PRIORITY, xive, m_prio);
- out_be64(ioc->regs + 0x3e1830, xive);
-
- return OPAL_SUCCESS;
-}
-
-/*
- * The function is used to figure out the error class and error
- * bit according to LEM WOF.
- *
- * The bits of WOF register have been classified according to
- * the error severity. Of course, we should process those errors
- * with higher priority. For example, there have 2 errors (GXE, INF)
- * pending, we should process GXE, and INF is meaningless in face
- * of GXE.
- */
-static bool p7ioc_err_bit(struct p7ioc *ioc, uint64_t wof)
-{
- uint64_t val, severity[P7IOC_ERR_CLASS_LAST];
- int32_t class, bit, err_bit = -1;
-
- /* Clear severity array */
- memset(severity, 0, sizeof(uint64_t) * P7IOC_ERR_CLASS_LAST);
-
- /*
- * The severity array has fixed values. However, it depends
- * on the damage settings for individual components. We're
- * using fixed values based on the assumption that damage settings
- * are fixed for now. If we change it some day, we also need
- * change the severity array accordingly. Anyway, it's something
- * to improve in future so that we can figure out the severity
- * array from hardware registers.
- */
- switch (ioc->err.err_src) {
- case P7IOC_ERR_SRC_EI:
- /* EI won't create interrupt yet */
- break;
- case P7IOC_ERR_SRC_RGC:
- severity[P7IOC_ERR_CLASS_GXE] = 0xF00086E0F4FCFFFFUL;
- severity[P7IOC_ERR_CLASS_RGA] = 0x0000010000000000UL;
- severity[P7IOC_ERR_CLASS_INF] = 0x0FFF781F0B030000UL;
- break;
- case P7IOC_ERR_SRC_BI_UP:
- severity[P7IOC_ERR_CLASS_GXE] = 0xF7FFFFFF7FFFFFFFUL;
- severity[P7IOC_ERR_CLASS_INF] = 0x0800000080000000UL;
- break;
- case P7IOC_ERR_SRC_BI_DOWN:
- severity[P7IOC_ERR_CLASS_GXE] = 0xDFFFF7F35F8000BFUL;
- severity[P7IOC_ERR_CLASS_INF] = 0x2000080CA07FFF40UL;
- break;
- case P7IOC_ERR_SRC_CI_P0:
- severity[P7IOC_ERR_CLASS_GXE] = 0xF5FF000000000000UL;
- severity[P7IOC_ERR_CLASS_INF] = 0x0200FFFFFFFFFFFFUL;
- severity[P7IOC_ERR_CLASS_MAL] = 0x0800000000000000UL;
- break;
- case P7IOC_ERR_SRC_CI_P1:
- severity[P7IOC_ERR_CLASS_GXE] = 0xFFFF000000000000UL;
- severity[P7IOC_ERR_CLASS_INF] = 0x0000FFFFFFFFFFFFUL;
- break;
- case P7IOC_ERR_SRC_CI_P2:
- case P7IOC_ERR_SRC_CI_P3:
- case P7IOC_ERR_SRC_CI_P4:
- case P7IOC_ERR_SRC_CI_P5:
- case P7IOC_ERR_SRC_CI_P6:
- case P7IOC_ERR_SRC_CI_P7:
- severity[P7IOC_ERR_CLASS_GXE] = 0x5B0B000000000000UL;
- severity[P7IOC_ERR_CLASS_PHB] = 0xA4F4000000000000UL;
- severity[P7IOC_ERR_CLASS_INF] = 0x0000FFFFFFFFFFFFUL;
- break;
- case P7IOC_ERR_SRC_MISC:
- severity[P7IOC_ERR_CLASS_GXE] = 0x0000000310000000UL;
- severity[P7IOC_ERR_CLASS_PLL] = 0x0000000001C00000UL;
- severity[P7IOC_ERR_CLASS_INF] = 0x555FFFF0EE3FFFFFUL;
- severity[P7IOC_ERR_CLASS_MAL] = 0xAAA0000C00000000UL;
- break;
- case P7IOC_ERR_SRC_I2C:
- severity[P7IOC_ERR_CLASS_GXE] = 0x1100000000000000UL;
- severity[P7IOC_ERR_CLASS_INF] = 0xEEFFFFFFFFFFFFFFUL;
- break;
- case P7IOC_ERR_SRC_PHB0:
- case P7IOC_ERR_SRC_PHB1:
- case P7IOC_ERR_SRC_PHB2:
- case P7IOC_ERR_SRC_PHB3:
- case P7IOC_ERR_SRC_PHB4:
- case P7IOC_ERR_SRC_PHB5:
- severity[P7IOC_ERR_CLASS_PHB] = 0xADB650CB808DD051UL;
- severity[P7IOC_ERR_CLASS_ER] = 0x0000A0147F50092CUL;
- severity[P7IOC_ERR_CLASS_INF] = 0x52490F2000222682UL;
- break;
- }
-
- /*
- * The error class (ERR_CLASS) has been defined based on
- * their severity. The priority of those errors out of same
- * class should be defined based on the position of corresponding
- * bit in LEM (Local Error Macro) register.
- */
- for (class = P7IOC_ERR_CLASS_NONE + 1;
- err_bit < 0 && class < P7IOC_ERR_CLASS_LAST;
- class++) {
- val = wof & severity[class];
- if (!val) continue;
-
- for (bit = 0; bit < 64; bit++) {
- if (val & PPC_BIT(bit)) {
- err_bit = 63 - bit;
- break;
- }
- }
- }
-
- /* If we don't find the error bit, we needn't go on. */
- if (err_bit < 0)
- return false;
-
- ioc->err.err_class = class - 1;
- ioc->err.err_bit = err_bit;
- return true;
-}
-
-/*
- * Check LEM to determine the detailed error information.
- * The function is expected to be called while OS calls
- * to OPAL API opal_pci_next_error(). Eventually, the errors
- * from CI Port{2, ..., 7} or PHB{0, ..., 5} would be cached
- * to the specific PHB, the left errors would be cached to
- * the IOC.
- */
-bool p7ioc_check_LEM(struct p7ioc *ioc,
- uint16_t *pci_error_type,
- uint16_t *severity)
-{
- void *base;
- uint64_t fir, wof, mask;
- struct p7ioc_phb *p;
- int32_t index;
- bool ret;
-
- /* Make sure we have error pending on IOC */
- if (!p7ioc_err_pending(ioc))
- return false;
-
- /*
- * The IOC probably has been put to fatal error
- * state (GXE) because of failure on reading on
- * GEM FIR.
- */
- if (ioc->err.err_src == P7IOC_ERR_SRC_NONE &&
- ioc->err.err_class != P7IOC_ERR_CLASS_NONE)
- goto err;
-
- /*
- * Get the base address of LEM registers according
- * to the error source. If we failed to get that,
- * the error pending flag would be cleared.
- */
- base = p7ioc_LEM_base(ioc, ioc->err.err_src);
- if (!base) {
- p7ioc_set_err_pending(ioc, false);
- return false;
- }
-
- /* IOC would be broken upon broken FIR */
- fir = in_be64(base + P7IOC_LEM_FIR_OFFSET);
- if (fir == 0xffffffffffffffffUL) {
- ioc->err.err_src = P7IOC_ERR_SRC_NONE;
- ioc->err.err_class = P7IOC_ERR_CLASS_GXE;
- goto err;
- }
-
- /* Read on ERR_MASK and WOF. However, we needn't do for PHBn */
- wof = in_be64(base + P7IOC_LEM_WOF_OFFSET);
- if (ioc->err.err_src >= P7IOC_ERR_SRC_PHB0 &&
- ioc->err.err_src <= P7IOC_ERR_SRC_PHB5) {
- mask = 0x0ull;
- } else {
- mask = in_be64(base + P7IOC_LEM_ERR_MASK_OFFSET);
- in_be64(base + P7IOC_LEM_ACTION_0_OFFSET);
- in_be64(base + P7IOC_LEM_ACTION_1_OFFSET);
- }
-
- /*
- * We need process those unmasked error first. If we're
- * failing to get the error bit, we needn't proceed.
- */
- if (wof & ~mask)
- wof &= ~mask;
- if (!wof) {
- p7ioc_set_err_pending(ioc, false);
- return false;
- }
-
- if (!p7ioc_err_bit(ioc, wof)) {
- p7ioc_set_err_pending(ioc, false);
- return false;
- }
-
-err:
- /*
- * We run into here because of valid error. Those errors
- * from CI Port{2, ..., 7} and PHB{0, ..., 5} will be cached
- * to the specific PHB. However, we will cache the global
- * errors (e.g. GXE) to IOC directly. For the left errors,
- * they will be cached to IOC.
- */
- if (((ioc->err.err_src >= P7IOC_ERR_SRC_CI_P2 &&
- ioc->err.err_src <= P7IOC_ERR_SRC_CI_P7) ||
- (ioc->err.err_src >= P7IOC_ERR_SRC_PHB0 &&
- ioc->err.err_src <= P7IOC_ERR_SRC_PHB5)) &&
- ioc->err.err_class != P7IOC_ERR_CLASS_GXE) {
- index = (ioc->err.err_src >= P7IOC_ERR_SRC_PHB0 &&
- ioc->err.err_src <= P7IOC_ERR_SRC_PHB5) ?
- (ioc->err.err_src - P7IOC_ERR_SRC_PHB0) :
- (ioc->err.err_src - P7IOC_ERR_SRC_CI_P2);
- p = &ioc->phbs[index];
-
- if (p7ioc_phb_enabled(ioc, index)) {
- p->err.err_src = ioc->err.err_src;
- p->err.err_class = ioc->err.err_class;
- p->err.err_bit = ioc->err.err_bit;
- p7ioc_phb_set_err_pending(p, true);
- p7ioc_set_err_pending(ioc, false);
-
- return false;
- }
- }
-
- /*
- * Map the internal error class to that OS can recognize.
- * Errors from PHB or the associated CI port would be
- * GXE, PHB-fatal, ER, or INF. For the case, GXE will be
- * cached to IOC and the left classes will be cached to
- * the specific PHB.
- */
- switch (ioc->err.err_class) {
- case P7IOC_ERR_CLASS_GXE:
- case P7IOC_ERR_CLASS_PLL:
- case P7IOC_ERR_CLASS_RGA:
- *pci_error_type = OPAL_EEH_IOC_ERROR;
- *severity = OPAL_EEH_SEV_IOC_DEAD;
- ret = true;
- break;
- case P7IOC_ERR_CLASS_INF:
- case P7IOC_ERR_CLASS_MAL:
- *pci_error_type = OPAL_EEH_IOC_ERROR;
- *severity = OPAL_EEH_SEV_INF;
- ret = false;
- break;
- default:
- p7ioc_set_err_pending(ioc, false);
- ret = false;
- }
-
- return ret;
-}
-
-/*
- * Check GEM to see if there has any problematic components.
- * The function is expected to be called in RGC interrupt
- * handler. Also, it's notable that failure on reading on
- * XFIR will cause GXE directly.
- */
-static bool p7ioc_check_GEM(struct p7ioc *ioc)
-{
- uint64_t xfir, rwof;
-
- /*
- * Recov_5: Read GEM Xfir
- * Recov_6: go to GXE recovery?
- */
- xfir = in_be64(ioc->regs + P7IOC_GEM_XFIR);
- if (xfir == 0xffffffffffffffffUL) {
- ioc->err.err_src = P7IOC_ERR_SRC_NONE;
- ioc->err.err_class = P7IOC_ERR_CLASS_GXE;
- p7ioc_set_err_pending(ioc, true);
- return true;
- }
-
- /*
- * Recov_7: Read GEM Rfir
- * Recov_8: Read GEM RIRQfir
- * Recov_9: Read GEM RWOF
- * Recov_10: Read Fence Shadow
- * Recov_11: Read Fence Shadow WOF
- */
- in_be64(ioc->regs + P7IOC_GEM_RFIR);
- in_be64(ioc->regs + P7IOC_GEM_RIRQFIR);
- rwof = in_be64(ioc->regs + P7IOC_GEM_RWOF);
- in_be64(ioc->regs + P7IOC_CHIP_FENCE_SHADOW);
- in_be64(ioc->regs + P7IOC_CHIP_FENCE_WOF);
-
- /*
- * Check GEM RWOF to see which component has been
- * put into problematic state.
- */
- ioc->err.err_src = P7IOC_ERR_SRC_NONE;
- if (rwof & PPC_BIT(1)) ioc->err.err_src = P7IOC_ERR_SRC_RGC;
- else if (rwof & PPC_BIT(2)) ioc->err.err_src = P7IOC_ERR_SRC_BI_UP;
- else if (rwof & PPC_BIT(3)) ioc->err.err_src = P7IOC_ERR_SRC_BI_DOWN;
- else if (rwof & PPC_BIT(4)) ioc->err.err_src = P7IOC_ERR_SRC_CI_P0;
- else if (rwof & PPC_BIT(5)) ioc->err.err_src = P7IOC_ERR_SRC_CI_P1;
- else if (rwof & PPC_BIT(6)) ioc->err.err_src = P7IOC_ERR_SRC_CI_P2;
- else if (rwof & PPC_BIT(7)) ioc->err.err_src = P7IOC_ERR_SRC_CI_P3;
- else if (rwof & PPC_BIT(8)) ioc->err.err_src = P7IOC_ERR_SRC_CI_P4;
- else if (rwof & PPC_BIT(9)) ioc->err.err_src = P7IOC_ERR_SRC_CI_P5;
- else if (rwof & PPC_BIT(10)) ioc->err.err_src = P7IOC_ERR_SRC_CI_P6;
- else if (rwof & PPC_BIT(11)) ioc->err.err_src = P7IOC_ERR_SRC_CI_P7;
- else if (rwof & PPC_BIT(16)) ioc->err.err_src = P7IOC_ERR_SRC_PHB0;
- else if (rwof & PPC_BIT(17)) ioc->err.err_src = P7IOC_ERR_SRC_PHB1;
- else if (rwof & PPC_BIT(18)) ioc->err.err_src = P7IOC_ERR_SRC_PHB2;
- else if (rwof & PPC_BIT(19)) ioc->err.err_src = P7IOC_ERR_SRC_PHB3;
- else if (rwof & PPC_BIT(20)) ioc->err.err_src = P7IOC_ERR_SRC_PHB4;
- else if (rwof & PPC_BIT(21)) ioc->err.err_src = P7IOC_ERR_SRC_PHB5;
- else if (rwof & PPC_BIT(24)) ioc->err.err_src = P7IOC_ERR_SRC_MISC;
- else if (rwof & PPC_BIT(25)) ioc->err.err_src = P7IOC_ERR_SRC_I2C;
-
- /*
- * If we detect any problematic components, the OS is
- * expected to poll that for more details through OPAL
- * interface.
- */
- if (ioc->err.err_src != P7IOC_ERR_SRC_NONE) {
- p7ioc_set_err_pending(ioc, true);
- return true;
- }
-
- return false;
-}
-
-static void p7ioc_rgc_interrupt(struct irq_source *is, uint32_t isn)
-{
- struct p7ioc *ioc = is->data;
-
- printf("Got RGC interrupt 0x%04x\n", isn);
-
- /* We will notify OS while getting error from GEM */
- if (p7ioc_check_GEM(ioc))
- /* This is a bit hacky but works - we raise the event
- on a downstream phb as the OS needs to call
- opal_pci_next_error for all phbs to ensure all events
- are cleared anyway. */
- opal_pci_eeh_set_evt(ioc->phbs[0].phb.opal_id);
-}
-
-static uint64_t p7ioc_rgc_irq_attributes(struct irq_source *is __unused,
- uint32_t isn __unused)
-{
- return IRQ_ATTR_TARGET_OPAL | IRQ_ATTR_TARGET_RARE | IRQ_ATTR_TYPE_LSI;
-}
-
-static const struct irq_source_ops p7ioc_rgc_irq_ops = {
- .get_xive = p7ioc_rgc_get_xive,
- .set_xive = p7ioc_rgc_set_xive,
- .attributes = p7ioc_rgc_irq_attributes,
- .interrupt = p7ioc_rgc_interrupt,
-};
-
-static void p7ioc_create_hub(struct dt_node *np)
-{
- struct p7ioc *ioc;
- unsigned int i, id;
- u64 bar1, bar2;
- u32 pdt;
- char *path;
-
- /* Use the BUID extension as ID and add it to device-tree */
- id = dt_prop_get_u32(np, "ibm,buid-ext");
- path = dt_get_path(np);
- printf("P7IOC: Found at %s ID 0x%x\n", path, id);
- free(path);
-
- /* Load VPD LID */
- vpd_preload(np);
- vpd_iohub_load(np);
-
- ioc = zalloc(sizeof(struct p7ioc));
- if (!ioc)
- return;
- ioc->hub.hub_id = id;
- ioc->hub.ops = &p7ioc_hub_ops;
- ioc->dt_node = np;
-
- bar1 = dt_prop_get_u64(np, "ibm,gx-bar-1");
- bar2 = dt_prop_get_u64(np, "ibm,gx-bar-2");
-
- ioc->regs = (void *)bar1;
-
- ioc->mmio1_win_start = bar1;
- ioc->mmio1_win_size = MWIN1_SIZE;
- ioc->mmio2_win_start = bar2;
- ioc->mmio2_win_size = MWIN2_SIZE;
-
- ioc->buid_base = id << 9;
- ioc->rgc_buid = ioc->buid_base + RGC_BUID_OFFSET;
-
- /* Add some DT properties */
- dt_add_property_cells(np, "ibm,opal-hubid", 0, id);
-
- /* XXX Fixme: how many RGC interrupts ? */
- dt_add_property_cells(np, "interrupt-parent", get_ics_phandle());
- dt_add_property_cells(np, "interrupts", ioc->rgc_buid << 4, 1);
- dt_add_property_cells(np, "interrupt-base", ioc->rgc_buid << 4);
-
- /* XXX What about ibm,opal-mmio-real ? */
-
- /* Clear the RGC XIVE cache */
- for (i = 0; i < 16; i++)
- ioc->xive_cache[i] = SETFIELD(IODA_XIVT_PRIORITY, 0ull, 0xff);
-
- /*
- * Register RGC interrupts
- *
- * For now I assume only 0 is... to verify with Greg or HW guys,
- * we support all 16
- */
- register_irq_source(&p7ioc_rgc_irq_ops, ioc, ioc->rgc_buid << 4, 1);
-
- /* Check for presence detect from HDAT, we use only BR1 on P7IOC */
- pdt = dt_prop_get_u32_def(np, "ibm,br1-presence-detect", 0xffffffff);
- if (pdt != 0xffffffff)
- printf("P7IOC: Presence detect from HDAT : 0x%02x\n", pdt);
- else {
- }
- ioc->phb_pdt = pdt & 0xff;
-
- /* Setup PHB structures (no HW access yet) */
- for (i = 0; i < P7IOC_NUM_PHBS; i++) {
- if (p7ioc_phb_enabled(ioc, i))
- p7ioc_phb_setup(ioc, i);
- }
-
- /* Now, we do the bulk of the inits */
- p7ioc_inits(ioc);
-
- printf("P7IOC: Initialization complete\n");
-
- cec_register(&ioc->hub);
-}
-
-void probe_p7ioc(void)
-{
- struct dt_node *np;
-
- dt_for_each_compatible(dt_root, np, "ibm,p7ioc")
- p7ioc_create_hub(np);
-}
-
-
-
diff --git a/hw/psi.c b/hw/psi.c
index ff6b0a9..5435c46 100644
--- a/hw/psi.c
+++ b/hw/psi.c
@@ -21,7 +21,6 @@
#include <psi.h>
#include <fsp.h>
#include <opal.h>
-#include <gx.h>
#include <interrupts.h>
#include <cpu.h>
#include <dio-p9.h>
@@ -286,8 +285,7 @@ static void psi_spurious_fsp_irq(struct psi *psi)
reg = PSIHB_XSCOM_P8_HBCSR_CLR;
bit = PSIHB_XSCOM_P8_HBSCR_FSP_IRQ;
} else {
- reg = PSIHB_XSCOM_P7_HBCSR_CLR;
- bit = PSIHB_XSCOM_P7_HBSCR_FSP_IRQ;
+ assert(false);
}
xscom_write(psi->chip_id, psi->xscom_base + reg, bit);
}
@@ -345,42 +343,6 @@ static void psihb_interrupt(struct irq_source *is, uint32_t isn __unused)
fsp_console_poll(NULL);
}
-static int64_t psi_p7_set_xive(struct irq_source *is, uint32_t isn __unused,
- uint16_t server, uint8_t priority)
-{
- struct psi *psi = is->data;
- uint64_t xivr;
-
- /* Populate the XIVR */
- xivr = (uint64_t)server << 40;
- xivr |= (uint64_t)priority << 32;
- xivr |= P7_IRQ_BUID(psi->interrupt) << 16;
-
- out_be64(psi->regs + PSIHB_XIVR, xivr);
-
- return OPAL_SUCCESS;
-}
-
-static int64_t psi_p7_get_xive(struct irq_source *is, uint32_t isn __unused,
- uint16_t *server, uint8_t *priority)
-{
- struct psi *psi = is->data;
- uint64_t xivr;
-
- /* Read & decode the XIVR */
- xivr = in_be64(psi->regs + PSIHB_XIVR);
-
- *server = (xivr >> 40) & 0x7ff;
- *priority = (xivr >> 32) & 0xff;
-
- return OPAL_SUCCESS;
-}
-
-static uint64_t psi_p7_irq_attributes(struct irq_source *is __unused,
- uint32_t isn __unused)
-{
- return IRQ_ATTR_TARGET_OPAL | IRQ_ATTR_TARGET_FREQUENT | IRQ_ATTR_TYPE_LSI;
-}
static const uint32_t psi_p8_irq_to_xivr[P8_IRQ_PSI_IRQ_COUNT] = {
[P8_IRQ_PSI_FSP] = PSIHB_XIVR_FSP,
@@ -429,14 +391,6 @@ void psi_irq_reset(void)
}
}
-static const struct irq_source_ops psi_p7_irq_ops = {
- .get_xive = psi_p7_get_xive,
- .set_xive = psi_p7_set_xive,
- .interrupt = psihb_interrupt,
- .attributes = psi_p7_irq_attributes,
-};
-
-
static int64_t psi_p8_set_xive(struct irq_source *is, uint32_t isn,
uint16_t server, uint8_t priority)
{
@@ -679,9 +633,6 @@ static void psi_tce_enable(struct psi *psi, bool enable)
u64 val;
switch (proc_gen) {
- case proc_gen_p7:
- addr = psi->regs + PSIHB_CR;
- break;
case proc_gen_p8:
case proc_gen_p9:
addr = psi->regs + PSIHB_PHBSCR;
@@ -715,10 +666,6 @@ void psi_init_for_fsp(struct psi *psi)
psi_tce_enable(psi, false);
switch (proc_gen) {
- case proc_gen_p7:
- out_be64(psi->regs + PSIHB_TAR, PSI_TCE_TABLE_BASE |
- PSIHB_TAR_16K_ENTRIES);
- break;
case proc_gen_p8:
case proc_gen_p9:
out_be64(psi->regs + PSIHB_TAR, PSI_TCE_TABLE_BASE |
@@ -762,20 +709,6 @@ void psi_set_external_irq_policy(bool policy)
psi_ext_irq_policy = policy;
}
-static void psi_init_p7_interrupt(struct psi *psi)
-{
- /* On P7, we get a single interrupt */
- out_be64(psi->regs + PSIHB_XIVR,
- P7_IRQ_BUID(psi->interrupt) << 16 |
- 0xffull << 32);
-
- /* Configure it in the GX controller as well */
- gx_configure_psi_buid(psi->chip_id, P7_IRQ_BUID(psi->interrupt));
-
- /* Register the IRQ source */
- register_irq_source(&psi_p7_irq_ops, psi, psi->interrupt, 1);
-}
-
static void psi_init_p8_interrupts(struct psi *psi)
{
uint32_t irq;
@@ -852,9 +785,6 @@ static void psi_init_interrupts(struct psi *psi)
{
/* Configure the interrupt BUID and mask it */
switch (proc_gen) {
- case proc_gen_p7:
- psi_init_p7_interrupt(psi);
- break;
case proc_gen_p8:
psi_init_p8_interrupts(psi);
break;
@@ -935,10 +865,6 @@ static void psi_create_mm_dtnode(struct psi *psi)
/* Hard wire size to 4G */
dt_add_property_u64s(np, "reg", addr, 0x100000000ull);
switch (proc_gen) {
- case proc_gen_p7:
- dt_add_property_strings(np, "compatible", "ibm,psi",
- "ibm,power7-psi");
- break;
case proc_gen_p8:
dt_add_property_strings(np, "compatible", "ibm,psi",
"ibm,power8-psi");
@@ -971,31 +897,6 @@ static struct psi *alloc_psi(struct proc_chip *chip, uint64_t base)
return psi;
}
-static struct psi *psi_probe_p7(struct proc_chip *chip, u64 base)
-{
- struct psi *psi = NULL;
- uint64_t rc, val;
-
- rc = xscom_read(chip->id, base + PSIHB_XSCOM_P7_HBBAR, &val);
- if (rc) {
- prerror("PSI: Error %llx reading PSIHB BAR on chip %d\n",
- rc, chip->id);
- return NULL;
- }
- if (val & PSIHB_XSCOM_P7_HBBAR_EN) {
- psi = alloc_psi(chip, base);
- if (!psi)
- return NULL;
- rc = val >> 36; /* Bits 0:1 = 0x00; 2:27 Bridge BAR... */
- rc <<= 20; /* ... corresponds to bits 18:43 of base addr */
- psi->regs = (void *)rc;
- psi->interrupt = get_psi_interrupt(chip->id);
- } else
- printf("PSI[0x%03x]: Working link not found\n", chip->id);
-
- return psi;
-}
-
static struct psi *psi_probe_p8(struct proc_chip *chip, u64 base)
{
struct psi *psi = NULL;
@@ -1050,9 +951,7 @@ static bool psi_init_psihb(struct dt_node *psihb)
base = dt_get_address(psihb, 0, NULL);
- if (dt_node_is_compatible(psihb, "ibm,power7-psihb-x"))
- psi = psi_probe_p7(chip, base);
- else if (dt_node_is_compatible(psihb, "ibm,power8-psihb-x"))
+ if (dt_node_is_compatible(psihb, "ibm,power8-psihb-x"))
psi = psi_probe_p8(chip, base);
else if (dt_node_is_compatible(psihb, "ibm,power9-psihb-x"))
psi = psi_probe_p9(chip, base);
diff --git a/hw/slw.c b/hw/slw.c
index 096202b..c872b63 100644
--- a/hw/slw.c
+++ b/hw/slw.c
@@ -384,7 +384,7 @@ struct cpu_idle_states {
u32 flags;
};
-static struct cpu_idle_states power7_cpu_idle_states[] = {
+static struct cpu_idle_states nap_only_cpu_idle_states[] = {
{ /* nap */
.name = "nap",
.latency_ns = 4000,
@@ -843,8 +843,8 @@ void add_cpu_idle_state_properties(void)
}
} else {
- states = power7_cpu_idle_states;
- nr_states = ARRAY_SIZE(power7_cpu_idle_states);
+ states = nap_only_cpu_idle_states;
+ nr_states = ARRAY_SIZE(nap_only_cpu_idle_states);
}
diff --git a/hw/xscom.c b/hw/xscom.c
index c484bee..bfe51c2 100644
--- a/hw/xscom.c
+++ b/hw/xscom.c
@@ -756,14 +756,6 @@ static void xscom_init_chip_info(struct proc_chip *chip)
/* Identify chip */
switch(val & 0xff) {
- case 0xf9:
- chip->type = PROC_CHIP_P7;
- assert(proc_gen == proc_gen_p7);
- break;
- case 0xe8:
- chip->type = PROC_CHIP_P7P;
- assert(proc_gen == proc_gen_p7);
- break;
case 0xef:
chip->type = PROC_CHIP_P8_MURANO;
assert(proc_gen == proc_gen_p8);
@@ -864,7 +856,7 @@ void xscom_init(void)
struct proc_chip *chip;
const char *chip_name;
static const char *chip_names[] = {
- "UNKNOWN", "P7", "P7+", "P8E", "P8", "P8NVL", "P9N", "P9C", "P9P"
+ "UNKNOWN", "P8E", "P8", "P8NVL", "P9N", "P9C", "P9P"
};
chip = get_chip(gcid);
diff --git a/include/chip.h b/include/chip.h
index 5231d17..f94149b 100644
--- a/include/chip.h
+++ b/include/chip.h
@@ -31,31 +31,11 @@
* This ID is the HW fabric ID of a chip based on the XSCOM numbering,
* also known as "GCID" (Global Chip ID).
*
- * The format of this number is different between P7 and P8 and care must
+ * The format of this number is different between chip generations and care must
* be taken when trying to convert between this chip ID and some other
* representation such as PIR values, interrupt-server numbers etc... :
*
- * P7 GCID
- * -------
- *
- * Global chip ID is a 6 bit number:
- *
- * NodeID T ChipID
- * | | | |
- * |___|___|___|___|___|___|
- *
- * Where T is the "torrent" bit and is 0 for P7 chips and 1 for
- * directly XSCOM'able IO chips such as Torrent
- *
- * This macro converts a PIR to a GCID
*/
-#define P7_PIR2GCID(pir) ({ \
- uint32_t _pir = pir; \
- ((_pir >> 4) & 0x38) | ((_pir >> 5) & 0x3); })
-
-#define P7_PIR2COREID(pir) (((pir) >> 2) & 0x7)
-
-#define P7_PIR2THREADID(pir) ((pir) & 0x3)
/*
* P8 GCID
@@ -119,8 +99,6 @@ struct p9_dio;
/* Chip type */
enum proc_chip_type {
PROC_CHIP_UNKNOWN,
- PROC_CHIP_P7,
- PROC_CHIP_P7P,
PROC_CHIP_P8_MURANO,
PROC_CHIP_P8_VENICE,
PROC_CHIP_P8_NAPLES,
diff --git a/include/gx.h b/include/gx.h
deleted file mode 100644
index 4ba1661..0000000
--- a/include/gx.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* Copyright 2013-2014 IBM Corp.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- * implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Definitions relative to the P7 and P7+ GX controller
- */
-#ifndef __GX_H
-#define __GX_H
-
-#include <bitutils.h>
-
-/* P7 GX Mode 1 register (contains PSI BUID) */
-#define GX_P7_MODE1_REG 0x0201180A
-#define GX_P7_MODE1_PSI_BUID PPC_BITMASK(18,26)
-#define GX_P7_MODE1_PSI_BUID_DISABLE PPC_BIT(27)
-
-/* P7+ GX Mode 4 register (PSI and NX BUIDs ) */
-#define GX_P7P_MODE4_REG 0x02011811
-#define GX_P7P_MODE4_ENABLE_NX_BUID PPC_BIT(0)
-#define GX_P7P_MODE4_NX_BUID_BASE PPC_BITMASK(1,9)
-#define GX_P7P_MODE4_NX_BUID_MASK PPC_BITMASK(10,18)
-#define GX_P7P_MODE4_PSI_BUID PPC_BITMASK(19,27)
-#define GX_P7P_MODE4_PSI_BUID_DISABLE PPC_BIT(28)
-
-/* P7 GX TCE BAR and mask */
-#define GX_P7_GX0_TCE_BAR 0x02011845
-#define GX_P7_TCE_BAR_ADDR PPC_BITMASK(0,25)
-#define GX_P7_TCE_BAR_ADDR_SHIFT PPC_BITLSHIFT(43)
-#define GX_P7_TCE_BAR_ENABLE PPC_BIT(26)
-#define GX_P7_GX0_TCE_MASK 0x0201184B
-#define GX_P7_TCE_MASK PPC_BITMASK(0,25)
-#define GX_P7_GX1_TCE_BAR 0x02011885
-#define GX_P7_GX1_TCE_MASK 0x0201188B
-
-
-extern int gx_configure_psi_buid(uint32_t chip, uint32_t buid);
-extern int gx_configure_tce_bar(uint32_t chip, uint32_t gx, uint64_t addr,
- uint64_t size);
-
-#endif /* __GX_H */
diff --git a/include/interrupts.h b/include/interrupts.h
index 2c4fa7e..7024fac 100644
--- a/include/interrupts.h
+++ b/include/interrupts.h
@@ -20,128 +20,6 @@
#include <stdint.h>
#include <ccan/list/list.h>
-/*
- * Note about interrupt numbers on P7/P7+
- * ======================================
- *
- * The form of an interrupt number in the system on P7/P7+ is as follow:
- *
- * | Node | T| Chip|GX| BUID | Level |
- * |--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|
- *
- * Where:
- *
- * - Node : The 3-bit node number
- * - T : 1 for a Torrent chip, 0 otherwise
- * - Chip : 2-bit chip number in a node
- * - GX : GX bus identifier
- * - BUID : Bus identifier (*)
- * - Level : Interrupt number
- *
- * (*) The BUID/Level distinction is mostly historical, interrupt
- * controllers such as the ICS in the PHBs "use" some of the
- * low BUID bits as an extension to the interrupt number
- *
- * The NodeID and ChipID together form a 5-bit Processor Chip ID as
- * found in the PIR or in the SPIRA data structures (without the T bit)
- *
- * PSI interrupt numbering scheme:
- * -------------------------------
- *
- * This is tentatively deduced from stuff I found in some SCOM regs
- * and in the BookIV. The PSIHB can be used to specify the 9-bit BUID,
- * the Level is always 0. The doc also says that it prepends the 6-bit
- * PowerBus chipID (Node + T + Chip). I *assume* that it also prepends
- * a 0 in place of the GX bit.
- *
- * OPAL seems to be arbitrarily using a BUID value of 0x3, I shall do
- * the same "just in case" :-)
- *
- * NOTE: From grep'ing around the giant SCOM file for "Build", I found
- * what looks like a register in the GX controller (Mode1
- * register) where the PSI BUID can be stored as well. From
- * looking around with the FSP getscom command, it appears
- * that both pHyp and OPAL set this consistently to the same
- * value that appears in the PHB configuration.
- *
- * => This is confirmed. The NX needs a similar configuration, this
- * tells the GX controller not to forward transactions for these
- * BUIDs down the GX bus.
- *
- * PCI interrupt numbering scheme:
- * -------------------------------
- *
- * See IOCs
- *
- * NX interrupt numbering scheme (p7+):
- * ------------------------------------
- *
- * TBD
- *
- *
- * Additional note about routing of interrupts in P7 and P7+
- * =========================================================
- *
- * There are two on-chip sources of interrupts on these that need a
- * special treatment: The PSI interrupt and the NX interrupts.
- *
- * The problem is that they use the same BUID space as the IO chips
- * connected to the GX bus, so the GX controller needs to be told
- * about these BUIDs in order to avoid forwarding them down the GX
- * link (and possibly choking due to the lack of reply).
- *
- * The bad news is that it's all undocumented. The good news is that
- * I found the info after chatting with Bill Daly (HW design) and
- * looking at the SCOM register maps.
- *
- * The way to set that up differs between P7 and P7+:
- *
- * - On P7, it's in the GX_MODE1 register at SCOM 0x0201180A, which
- * among other things, contains those bits:
- *
- * 18:26 PSI_BUID: BUID to be used to indicate the interrupt is
- * for the PSI
- * 27 DISABLE_PSI_BUID: set to 1 to disable the buid reservation
- * for PSI
- *
- * So one must write the 9-bit BUID (without the top chipID) of the
- * PSI interrupt in there and clear the disable bit.
- *
- * - On P7+ it's in the GX_MODE4 register at SCOM 0x02011811
- *
- * 0 ENABLE_NX_BUID: set to 1 to enable the buid reservation for nx
- * 1:9 NX_BUID_BASE: BUID BASE to be used to indicate the interrupt
- * is for the nx
- * 10:18 NX_BUID_MASK: BUID mask for the nx buid base
- * 19:27 PSI_BUID: BUID to be used to indicate the interrupt is for
- * the PSI
- * 28 DISABLE_PSI_BUID: set to 1 to disable the buid reservation
- * for PSI
- *
- * Note: The NX_BUID_MASK should have bits set to 1 that are relevant for
- * the comparison to NX_BUID_BASE, ie 4 interrupts means a mask
- * value of b'111111100
- */
-
-#define P7_PSI_IRQ_BUID 0x3 /* 9-bit BUID for the PSI interrupts */
-
-/* Extract individual components of an IRQ number */
-#define P7_IRQ_BUID(irq) (((irq) >> 4) & 0x1ff)
-#define P7_IRQ_GXID(irq) (((irq) >> 13) & 0x1)
-#define P7_IRQ_CHIP(irq) (((irq) >> 14) & 0x3)
-#define P7_IRQ_TBIT(irq) (((irq) >> 16) & 0x1)
-#define P7_IRQ_NODE(irq) (((irq) >> 17) & 0x7)
-
-/* Extract the "full BUID" (extension + BUID) */
-#define P7_IRQ_FBUID(irq) (((irq) >> 4) & 0xffff)
-
-/* BUID Extension (GX + CHIP + T + NODE) */
-#define P7_IRQ_BEXT(irq) (((irq) >> 13) & 0x7f)
-
-/* Strip extension from BUID */
-#define P7_BUID_BASE(buid) ((buid) & 0x1ff)
-
-
/* Note about interrupt numbers on P8
* ==================================
*
diff --git a/include/mem-map.h b/include/mem-map.h
index fa5cacb..fc535e5 100644
--- a/include/mem-map.h
+++ b/include/mem-map.h
@@ -94,11 +94,8 @@
#define SPIRA_HEAP_BASE (SKIBOOT_BASE + 0x01200000)
#define SPIRA_HEAP_SIZE 0x00800000
-/* This is our PSI TCE table. It's 16K entries on P7 and 256K
- * entries on P8
- */
+/* This is our PSI TCE table. It's 256K entries on P8 */
#define PSI_TCE_TABLE_BASE (SKIBOOT_BASE + 0x01a00000)
-#define PSI_TCE_TABLE_SIZE_P7 0x00020000UL
#define PSI_TCE_TABLE_SIZE_P8 0x00200000UL
/* Total size of the above area
diff --git a/include/nx.h b/include/nx.h
index 0322349..dcaf20f 100644
--- a/include/nx.h
+++ b/include/nx.h
@@ -21,15 +21,12 @@
/* Register addresses and bit fields */
/*************************************/
-#define NX_P7_SAT(sat, offset) XSCOM_SAT(0x1, sat, offset)
#define NX_P8_SAT(sat, offset) XSCOM_SAT(0xc, sat, offset)
#define NX_P9_SAT(sat, offset) XSCOM_SAT(0x4, sat, offset)
/* Random Number Generator */
-#define NX_P7_RNG_BAR NX_P7_SAT(0x2, 0x0c)
#define NX_P8_RNG_BAR NX_P8_SAT(0x2, 0x0d)
#define NX_P9_RNG_BAR NX_P9_SAT(0x2, 0x0d)
-#define NX_P7_RNG_BAR_ADDR PPC_BITMASK(18, 51)
#define NX_P8_RNG_BAR_ADDR PPC_BITMASK(14, 51)
/*
* Section 5.30 of P9 NX Workbook Version 2.42 shows RNG BAR as:
@@ -44,12 +41,10 @@
#define NX_RNG_BAR_SIZE PPC_BITMASK(53, 55)
#define NX_RNG_BAR_ENABLE PPC_BIT(52)
-#define NX_P7_RNG_CFG NX_P7_SAT(0x2, 0x12)
#define NX_P8_RNG_CFG NX_P8_SAT(0x2, 0x12)
#define NX_RNG_CFG_ENABLE PPC_BIT(63)
/* Symmetric Crypto */
-#define NX_P7_SYM_CFG NX_P7_SAT(0x2, 0x09)
#define NX_P8_SYM_CFG NX_P8_SAT(0x2, 0x0a)
#define NX_SYM_CFG_CI PPC_BITMASK(2, 14)
#define NX_SYM_CFG_CT PPC_BITMASK(18, 23)
@@ -57,15 +52,13 @@
#define NX_SYM_CFG_ENABLE PPC_BIT(63)
/* Asymmetric Crypto */
-#define NX_P7_ASYM_CFG NX_P7_SAT(0x2, 0x0a)
#define NX_P8_ASYM_CFG NX_P8_SAT(0x2, 0x0b)
#define NX_ASYM_CFG_CI PPC_BITMASK(2, 14)
#define NX_ASYM_CFG_CT PPC_BITMASK(18, 23)
#define NX_ASYM_CFG_FC_ENABLE PPC_BITMASK(32, 52)
#define NX_ASYM_CFG_ENABLE PPC_BIT(63)
-/* 842 Compression. CFG is used only on P7+ and P8 */
-#define NX_P7_842_CFG NX_P7_SAT(0x2, 0x0b)
+/* 842 Compression. CFG is used only on P8 */
#define NX_P8_842_CFG NX_P8_SAT(0x2, 0x0c)
#define NX_842_CFG_CI PPC_BITMASK(2, 14)
#define NX_842_CFG_CT PPC_BITMASK(18, 23)
@@ -73,7 +66,6 @@
#define NX_842_CFG_ENABLE PPC_BIT(63)
/* DMA */
-#define NX_P7_DMA_CFG NX_P7_SAT(0x1, 0x02)
#define NX_P8_DMA_CFG NX_P8_SAT(0x1, 0x02)
#define NX_P9_DMA_CFG NX_P9_SAT(0x1, 0x02)
#define NX_DMA_CFG_GZIP_COMPRESS_MAX_RR PPC_BITMASK(8, 11)
@@ -101,7 +93,6 @@
#define NX_DMA_CFG_842_OUTPUT_DATA_WR PPC_BIT(63)
/* Engine Enable Register */
-#define NX_P7_EE_CFG NX_P7_SAT(0x1, 0x01)
#define NX_P8_EE_CFG NX_P8_SAT(0x1, 0x01)
#define NX_P9_EE_CFG NX_P9_SAT(0x1, 0x01)
#define NX_EE_CFG_EFUSE PPC_BIT(0)
@@ -123,7 +114,6 @@
#define NX_P9_DMA_VAS_MMIO_ADDR PPC_BITMASK(8, 38)
/* PowerBus Registers */
-#define NX_P7_CRB_IQ NX_P7_SAT(0x2, 0x0e)
#define NX_P8_CRB_IQ NX_P8_SAT(0x2, 0x0f)
#define NX_CRB_IQ_SYM PPC_BITMASK(0, 2)
#define NX_CRB_IQ_ASYM PPC_BITMASK(3, 5)
@@ -165,7 +155,6 @@
#define NX_P9_ERAT_STATUS_CTRL NX_P9_SAT(0x3, 0x16)
/* NX Status Register */
-#define NX_P7_STATUS NX_P7_SAT(0x1, 0x00)
#define NX_P8_STATUS NX_P8_SAT(0x1, 0x00)
#define NX_P9_STATUS NX_P9_SAT(0x1, 0x00) /* DMA Status register */
#define NX_STATUS_HMI_ACTIVE PPC_BIT(54)
@@ -180,10 +169,8 @@
#define NX_STATUS_DMA_CH7_IDLE PPC_BIT(63)
/* Channel Status Registers */
-#define NX_P7_CH_CRB(ch) NX_P7_SAT(0x1, 0x03 + ((ch) * 2))
#define NX_P8_CH_CRB(ch) NX_P8_SAT(0x1, 0x03 + ((ch) * 2))
#define NX_P9_CH_CRB(ch) NX_P9_SAT(0x1, 0x03 + ((ch) * 2))
-#define NX_P7_CH_STATUS(ch) NX_P7_SAT(0x1, 0x04 + ((ch) * 2))
#define NX_P8_CH_STATUS(ch) NX_P8_SAT(0x1, 0x04 + ((ch) * 2))
#define NX_CH_STATUS_ABORT PPC_BIT(0)
#define NX_CH_STATUS_CCB_VALID PPC_BIT(4)
@@ -196,7 +183,6 @@
#define NX_CH_STATUS_CRB_SJT PPC_BITMASK(50, 63)
/* Kill Register */
-#define NX_P7_CRB_KILL NX_P7_SAT(0x1, 0x13)
#define NX_P8_CRB_KILL NX_P8_SAT(0x1, 0x13)
#define NX_P9_CRB_KILL NX_P9_SAT(0x1, 0x13)
#define NX_CRB_KILL_LPID_KILL PPC_BIT(0)
@@ -211,62 +197,41 @@
#define NX_CRB_KILL_ALG_CH PPC_BITMASK(56, 63)
/* Fault Isolation Registers (FIR) */
-#define NX_P7_DE_FIR_DATA NX_P7_SAT(0x4, 0x00)
#define NX_P8_DE_FIR_DATA NX_P8_SAT(0x4, 0x00)
#define NX_P9_DE_FIR_DATA NX_P9_SAT(0x4, 0x00)
-#define NX_P7_DE_FIR_DATA_CLR NX_P7_SAT(0x4, 0x01)
#define NX_P8_DE_FIR_DATA_CLR NX_P8_SAT(0x4, 0x01)
#define NX_P9_DE_FIR_DATA_CLR NX_P9_SAT(0x4, 0x01)
-#define NX_P7_DE_FIR_DATA_SET NX_P7_SAT(0x4, 0x02)
#define NX_P8_DE_FIR_DATA_SET NX_P8_SAT(0x4, 0x02)
#define NX_P9_DE_FIR_DATA_SET NX_P9_SAT(0x4, 0x02)
-#define NX_P7_DE_FIR_MASK NX_P7_SAT(0x4, 0x06)
#define NX_P8_DE_FIR_MASK NX_P8_SAT(0x4, 0x03)
#define NX_P9_DE_FIR_MASK NX_P9_SAT(0x4, 0x03)
-#define NX_P7_DE_FIR_MASK_CLR NX_P7_SAT(0x4, 0x07)
#define NX_P8_DE_FIR_MASK_CLR NX_P8_SAT(0x4, 0x04)
#define NX_P9_DE_FIR_MASK_CLR NX_P9_SAT(0x4, 0x04)
-#define NX_P7_DE_FIR_MASK_SET NX_P7_SAT(0x4, 0x08)
#define NX_P8_DE_FIR_MASK_SET NX_P8_SAT(0x4, 0x05)
#define NX_P9_DE_FIR_MASK_SET NX_P9_SAT(0x4, 0x05)
-#define NX_P7_DE_FIR_ACTION0 NX_P7_SAT(0x4, 0x03)
#define NX_P8_DE_FIR_ACTION0 NX_P8_SAT(0x4, 0x06)
#define NX_P9_DE_FIR_ACTION0 NX_P9_SAT(0x4, 0x06)
-#define NX_P7_DE_FIR_ACTION1 NX_P7_SAT(0x4, 0x04)
#define NX_P8_DE_FIR_ACTION1 NX_P8_SAT(0x4, 0x07)
#define NX_P9_DE_FIR_ACTION1 NX_P9_SAT(0x4, 0x07)
-#define NX_P7_DE_FIR_WOF NX_P7_SAT(0x4, 0x05)
#define NX_P8_DE_FIR_WOF NX_P8_SAT(0x4, 0x08)
-#define NX_P7_PB_FIR_DATA NX_P7_SAT(0x2, 0x00)
#define NX_P9_PB_FIR_DATA NX_P9_SAT(0x2, 0x00)
#define NX_P8_PB_FIR_DATA NX_P8_SAT(0x2, 0x00)
-#define NX_P7_PB_FIR_DATA_CLR NX_P7_SAT(0x2, 0x01)
#define NX_P8_PB_FIR_DATA_CLR NX_P8_SAT(0x2, 0x01)
#define NX_P9_PB_FIR_DATA_CLR NX_P9_SAT(0x2, 0x01)
-#define NX_P7_PB_FIR_DATA_SET NX_P7_SAT(0x2, 0x02)
#define NX_P8_PB_FIR_DATA_SET NX_P8_SAT(0x2, 0x02)
#define NX_P9_PB_FIR_DATA_SET NX_P9_SAT(0x2, 0x02)
-#define NX_P7_PB_FIR_MASK NX_P7_SAT(0x2, 0x06)
#define NX_P8_PB_FIR_MASK NX_P8_SAT(0x2, 0x03)
#define NX_P9_PB_FIR_MASK NX_P9_SAT(0x2, 0x03)
-#define NX_P7_PB_FIR_MASK_CLR NX_P7_SAT(0x2, 0x07)
#define NX_P8_PB_FIR_MASK_CLR NX_P8_SAT(0x2, 0x04)
#define NX_P9_PB_FIR_MASK_CLR NX_P9_SAT(0x2, 0x04)
-#define NX_P7_PB_FIR_MASK_SET NX_P7_SAT(0x2, 0x08)
#define NX_P8_PB_FIR_MASK_SET NX_P8_SAT(0x2, 0x05)
#define NX_P9_PB_FIR_MASK_SET NX_P9_SAT(0x2, 0x05)
-#define NX_P7_PB_FIR_ACTION0 NX_P7_SAT(0x2, 0x03)
#define NX_P8_PB_FIR_ACTION0 NX_P8_SAT(0x2, 0x06)
#define NX_P9_PB_FIR_ACTION0 NX_P9_SAT(0x2, 0x06)
-#define NX_P7_PB_FIR_ACTION1 NX_P7_SAT(0x2, 0x04)
#define NX_P8_PB_FIR_ACTION1 NX_P8_SAT(0x2, 0x07)
#define NX_P9_PB_FIR_ACTION1 NX_P9_SAT(0x2, 0x07)
-#define NX_P7_PB_FIR_WOF NX_P7_SAT(0x2, 0x05)
#define NX_P8_PB_FIR_WOF NX_P8_SAT(0x2, 0x08)
-#define NX_FIR_MCD_PB_CMD_HANG PPC_BIT(0) /* P7 only */
#define NX_FIR_SHM_INV PPC_BIT(1)
-#define NX_FIR_MCD_ARRAY_ECC_CE PPC_BIT(2) /* P7 only */
-#define NX_FIR_MCD_ARRAY_ECC_UE PPC_BIT(3) /* P7 only */
#define NX_FIR_CH0_ECC_CE PPC_BIT(4)
#define NX_FIR_CH0_ECC_UE PPC_BIT(5)
#define NX_FIR_CH1_ECC_CE PPC_BIT(6)
@@ -296,9 +261,6 @@
#define NX_FIR_CRB_UE PPC_BIT(31)
#define NX_FIR_CRB_SUE PPC_BIT(32)
#define NX_FIR_DMA_RW_ECC_SUE PPC_BIT(33)
-#define NX_FIR_MCD_CFG_REG_PARITY PPC_BIT(34) /* P7 only */
-#define NX_FIR_MCD_RECOVERY_INV_STATE PPC_BIT(35) /* P7 only */
-#define NX_FIR_P7_PARITY PPC_BIT(36) /* P7 only */
#define NX_FIR_CH4_ECC_CE PPC_BIT(36) /* P8 only */
#define NX_FIR_CH5_ECC_UE_2 PPC_BIT(37) /* P8 only */
#define NX_FIR_P8_PARITY PPC_BITMASK(48, 49)
@@ -312,14 +274,14 @@
/* Arbitrary Coprocessor Type values */
#define NX_CT_SYM (1)
-#define NX_CT_ASYM (2) /* on P7+ and P8 */
+#define NX_CT_ASYM (2) /* on P8 */
#define NX_CT_GZIP (2) /* on P9 and later */
#define NX_CT_842 (3)
/* Coprocessor Instance counter
* NX workbook, section 5.5.1
* "Assigning <CT,CI> Values"
- * Only on P7+ and P8
+ * Only on P8
*/
#define NX_SYM_CFG_CI_MAX (511)
#define NX_SYM_CFG_CI_LSHIFT (2)
diff --git a/include/opal-api.h b/include/opal-api.h
index 2981b46..0b0ae19 100644
--- a/include/opal-api.h
+++ b/include/opal-api.h
@@ -788,55 +788,6 @@ enum {
OPAL_HMI_FLAGS_NEW_EVENT = (1ull << 63), /* An event has been created */
};
-enum {
- OPAL_P7IOC_DIAG_TYPE_NONE = 0,
- OPAL_P7IOC_DIAG_TYPE_RGC = 1,
- OPAL_P7IOC_DIAG_TYPE_BI = 2,
- OPAL_P7IOC_DIAG_TYPE_CI = 3,
- OPAL_P7IOC_DIAG_TYPE_MISC = 4,
- OPAL_P7IOC_DIAG_TYPE_I2C = 5,
- OPAL_P7IOC_DIAG_TYPE_LAST = 6
-};
-
-struct OpalIoP7IOCErrorData {
- __be16 type;
-
- /* GEM */
- __be64 gemXfir;
- __be64 gemRfir;
- __be64 gemRirqfir;
- __be64 gemMask;
- __be64 gemRwof;
-
- /* LEM */
- __be64 lemFir;
- __be64 lemErrMask;
- __be64 lemAction0;
- __be64 lemAction1;
- __be64 lemWof;
-
- union {
- struct OpalIoP7IOCRgcErrorData {
- __be64 rgcStatus; /* 3E1C10 */
- __be64 rgcLdcp; /* 3E1C18 */
- }rgc;
- struct OpalIoP7IOCBiErrorData {
- __be64 biLdcp0; /* 3C0100, 3C0118 */
- __be64 biLdcp1; /* 3C0108, 3C0120 */
- __be64 biLdcp2; /* 3C0110, 3C0128 */
- __be64 biFenceStatus; /* 3C0130, 3C0130 */
-
- uint8_t biDownbound; /* BI Downbound or Upbound */
- }bi;
- struct OpalIoP7IOCCiErrorData {
- __be64 ciPortStatus; /* 3Dn008 */
- __be64 ciPortLdcp; /* 3Dn010 */
-
- uint8_t ciPort; /* Index of CI port: 0/1 */
- }ci;
- };
-};
-
/**
* This structure defines the overlay which will be used to store PHB error
* data upon request.
@@ -846,13 +797,11 @@ enum {
};
enum {
- OPAL_PHB_ERROR_DATA_TYPE_P7IOC = 1,
OPAL_PHB_ERROR_DATA_TYPE_PHB3 = 2,
OPAL_PHB_ERROR_DATA_TYPE_PHB4 = 3
};
enum {
- OPAL_P7IOC_NUM_PEST_REGS = 128,
OPAL_PHB3_NUM_PEST_REGS = 256,
OPAL_PHB4_NUM_PEST_REGS = 512
};
@@ -863,65 +812,6 @@ struct OpalIoPhbErrorCommon {
__be32 len;
};
-struct OpalIoP7IOCPhbErrorData {
- struct OpalIoPhbErrorCommon common;
-
- __be32 brdgCtl;
-
- // P7IOC utl regs
- __be32 portStatusReg;
- __be32 rootCmplxStatus;
- __be32 busAgentStatus;
-
- // P7IOC cfg regs
- __be32 deviceStatus;
- __be32 slotStatus;
- __be32 linkStatus;
- __be32 devCmdStatus;
- __be32 devSecStatus;
-
- // cfg AER regs
- __be32 rootErrorStatus;
- __be32 uncorrErrorStatus;
- __be32 corrErrorStatus;
- __be32 tlpHdr1;
- __be32 tlpHdr2;
- __be32 tlpHdr3;
- __be32 tlpHdr4;
- __be32 sourceId;
-
- __be32 rsv3;
-
- // Record data about the call to allocate a buffer.
- __be64 errorClass;
- __be64 correlator;
-
- //P7IOC MMIO Error Regs
- __be64 p7iocPlssr; // n120
- __be64 p7iocCsr; // n110
- __be64 lemFir; // nC00
- __be64 lemErrorMask; // nC18
- __be64 lemWOF; // nC40
- __be64 phbErrorStatus; // nC80
- __be64 phbFirstErrorStatus; // nC88
- __be64 phbErrorLog0; // nCC0
- __be64 phbErrorLog1; // nCC8
- __be64 mmioErrorStatus; // nD00
- __be64 mmioFirstErrorStatus; // nD08
- __be64 mmioErrorLog0; // nD40
- __be64 mmioErrorLog1; // nD48
- __be64 dma0ErrorStatus; // nD80
- __be64 dma0FirstErrorStatus; // nD88
- __be64 dma0ErrorLog0; // nDC0
- __be64 dma0ErrorLog1; // nDC8
- __be64 dma1ErrorStatus; // nE00
- __be64 dma1FirstErrorStatus; // nE08
- __be64 dma1ErrorLog0; // nE40
- __be64 dma1ErrorLog1; // nE48
- __be64 pestA[OPAL_P7IOC_NUM_PEST_REGS];
- __be64 pestB[OPAL_P7IOC_NUM_PEST_REGS];
-};
-
struct OpalIoPhb3ErrorData {
struct OpalIoPhbErrorCommon common;
diff --git a/include/p7ioc-regs.h b/include/p7ioc-regs.h
deleted file mode 100644
index 4eb10d6..0000000
--- a/include/p7ioc-regs.h
+++ /dev/null
@@ -1,444 +0,0 @@
-/* Copyright 2013-2014 IBM Corp.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- * implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __P7IOC_REGS_H
-#define __P7IOC_REGS_H
-
-/*
- * Register definitions
- *
- * We only define some registers here. Ideally we should auto-generate
- * the full list from the spec. For now I add them as I need them
- */
-
-/* RGC GEM registers */
-#define P7IOC_GEM_XFIR 0x3E0008
-#define P7IOC_GEM_RFIR 0x3E0010
-#define P7IOC_GEM_RIRQFIR 0x3E0018
-#define P7IOC_GEM_MASK 0x3E0020
-#define P7IOC_GEM_RWOF 0x3E0028
-
-/* LEM register base */
-#define P7IOC_RGC_LEM_BASE 0x3E1E00
-#define P7IOC_BI_UP_LEM_BASE 0x3C0000
-#define P7IOC_BI_DOWN_LEM_BASE 0x3C0050
-#define P7IOC_CI_PORTn_LEM_BASE(n) (0x3d0200 | ((n) * 0x1000))
-#define P7IOC_PHBn_LEM_BASE(n) (0x000C00 | ((n) * 0x10000))
-#define P7IOC_MISC_LEM_BASE 0x3EA000
-#define P7IOC_I2C_LEM_BASE 0x3EB000
-
-/* LEM register offset */
-#define P7IOC_LEM_FIR_OFFSET 0x00
-#define P7IOC_LEM_FIR_AND_OFFSET 0x08
-#define P7IOC_LEM_FIR_OR_OFFSET 0x10
-#define P7IOC_LEM_ERR_MASK_OFFSET 0x18
-#define P7IOC_LEM_ERR_MASK_AND_OFFSET 0x20
-#define P7IOC_LEM_ERR_MASK_OR_OFFSET 0x28
-#define P7IOC_LEM_ACTION_0_OFFSET 0x30
-#define P7IOC_LEM_ACTION_1_OFFSET 0x38
-#define P7IOC_LEM_WOF_OFFSET 0x40
-
-/* HSS registers */
-#define P7IOC_HSS_BASE 0x3E8000
-#define P7IOC_HSS_STRIDE 0x200
-#define P7IOC_HSSn_CTL2_OFFSET 0x10
-#define P7IOC_HSSn_CTL3_OFFSET 0x18
-#define P7IOC_HSSn_CTL8_OFFSET 0x40
-#define P7IOC_HSSn_CTL9_OFFSET 0x48
-#define P7IOC_HSSn_CTL10_OFFSET 0x50
-#define P7IOC_HSSn_CTL11_OFFSET 0x58
-#define P7IOC_HSSn_CTL12_OFFSET 0x60
-#define P7IOC_HSSn_CTL13_OFFSET 0x68
-#define P7IOC_HSSn_CTL14_OFFSET 0x70
-#define P7IOC_HSSn_CTL15_OFFSET 0x78
-#define P7IOC_HSSn_CTL16_OFFSET 0x80
-#define P7IOC_HSSn_CTL17_OFFSET 0x88
-#define P7IOC_HSSn_CTL18_OFFSET 0x90
-#define P7IOC_HSSn_CTL19_OFFSET 0x98
-#define P7IOC_HSSn_CTL20_OFFSET 0xa0
-#define P7IOC_HSSn_CTL21_OFFSET 0xa8
-#define P7IOC_HSSn_CTL22_OFFSET 0xb0
-#define P7IOC_HSSn_CTL23_OFFSET 0xb8
-
-/* CI Routing registers & helper macros */
-#define P7IOC_CI_RMATC_REG(i) (0x3D0400ul + ((i) << 4))
-#define P7IOC_CI_RMASK_REG(i) (0x3D0408ul + ((i) << 4))
-
-#define P7IOC_CI_RMATC_PORT(n) PPC_BIT(n)
-#define P7IOC_CI_RMATC_ADDR_VALID PPC_BIT(16)
-#define P7IOC_CI_RMATC_BUID_VALID PPC_BIT(17)
-#define P7IOC_CI_RMATC_TYPE_VALID PPC_BIT(18)
-
-/* AIB Addresses are 48-bit, the top 32 are used in
- * the routing tables, we thus shift by 16
- */
-#define P7IOC_CI_RMATC_ENCODE_ADDR(addr) ((uint32_t)((addr) >> 16))
-#define P7IOC_CI_RMATC_ENCODE_BUID(buid) ((uint32_t)((buid) << 20))
-#define P7IOC_CI_RMATC_ENCODE_TYPE(type) ((uint32_t)(type))
-
-/* CI port numbers */
-#define P7IOC_CI_PHB_PORT(pnum) ((pnum) + 2)
-#define P7IOC_CI_UPSTREAM_PORT 0
-#define P7IOC_CI_RGC_PORT 1
-
-/* Other random chip registers */
-#define P7IOC_CHIP_FENCE_SHADOW 0x3ec010
-#define P7IOC_CHIP_FENCE_WOF 0x3ec018
-#define P7IOC_CCRR 0x3e1c00
-
-/* CI registers */
-#define P7IOC_CIn_BASE(n) (0x3d0000 | ((n) * 0x1000))
-#define P7IOC_CIn_LEM_FIR(n) (P7IOC_CIn_BASE(n) + 0x200)
-#define P7IOC_CIn_LEM_FIR_AND(n) (P7IOC_CIn_BASE(n) + 0x208)
-#define P7IOC_CIn_LEM_FIR_OR(n) (P7IOC_CIn_BASE(n) + 0x210)
-#define P7IOC_CIn_LEM_ERR_MASK(n) (P7IOC_CIn_BASE(n) + 0x218)
-#define P7IOC_CIn_LEM_ERR_MASK_AND(n) (P7IOC_CIn_BASE(n) + 0x220)
-#define P7IOC_CIn_LEM_ERR_MASK_OR(n) (P7IOC_CIn_BASE(n) + 0x228)
-
-/*
- * PHB registers
- */
-
-/* PHB Fundamental register set A */
-#define PHB_BUID 0x100
-#define PHB_BUID_LSI PPC_BITMASK(7,15)
-#define PHB_BUID_MSI PPC_BITMASK(23,31)
-#define PHB_DMA_CHAN_STATUS 0x110
-#define PHB_CPU_LOADSTORE_STATUS 0x120
-#define PHB_CONFIG_DATA 0x130
-#define PHB_LOCK0 0x138
-#define PHB_CONFIG_ADDRESS 0x140
-#define PHB_CA_ENABLE PPC_BIT(0)
-#define PHB_CA_BUS PPC_BITMASK(4,11)
-#define PHB_CA_DEV PPC_BITMASK(12,16)
-#define PHB_CA_FUNC PPC_BITMASK(17,19)
-#define PHB_CA_BDFN PPC_BITMASK(4,19) /* bus,dev,func */
-#define PHB_CA_REG PPC_BITMASK(20,31)
-#define PHB_LOCK1 0x148
-#define PHB_PHB2_CONFIG 0x160
-#define PHB_PHB2C_64B_TCE_EN PPC_BIT(2)
-#define PHB_PHB2C_32BIT_MSI_EN PPC_BIT(8)
-#define PHB_PHB2C_IO_EN PPC_BIT(12)
-#define PHB_PHB2C_64BIT_MSI_EN PPC_BIT(14)
-#define PHB_PHB2C_M32_EN PPC_BIT(16)
-#define PHB_IO_BASE_ADDR 0x170
-#define PHB_IO_BASE_MASK 0x178
-#define PHB_IO_START_ADDR 0x180
-#define PHB_M32_BASE_ADDR 0x190
-#define PHB_M32_BASE_MASK 0x198
-#define PHB_M32_START_ADDR 0x1a0
-#define PHB_M64_UPPER_BITS 0x1f0
-#define PHB_TCE_KILL 0x210
-#define PHB_TCEKILL_PAIR PPC_BIT(0)
-#define PHB_TCEKILL_ADDR PPC_BITMASK(16,59)
-#define PHB_TCE_PREFETCH 0x218
-#define PHB_IODA_ADDR 0x220
-#define PHB_IODA_AD_AUTOINC PPC_BIT(0)
-#define PHB_IODA_AD_TSEL PPC_BITMASK(11,15)
-#define PHB_IODA_AD_TADR PPC_BITMASK(48,63)
-#define PHB_IODA_DATA0 0x228
-#define PHB_IODA_DATA1 0x230
-#define PHB_LOCK2 0x240
-#define PHB_XIVE_UPDATE 0x248
-#define PHB_PHB2_GEN_CAP 0x250
-#define PHB_PHB2_TCE_CAP 0x258
-#define PHB_PHB2_IRQ_CAP 0x260
-#define PHB_PHB2_EEH_CAP 0x268
-#define PHB_PAPR_ERR_INJ_CTL 0x2b0
-#define PHB_PAPR_ERR_INJ_CTL_INB PPC_BIT(0)
-#define PHB_PAPR_ERR_INJ_CTL_OUTB PPC_BIT(1)
-#define PHB_PAPR_ERR_INJ_CTL_STICKY PPC_BIT(2)
-#define PHB_PAPR_ERR_INJ_CTL_CFG PPC_BIT(3)
-#define PHB_PAPR_ERR_INJ_CTL_RD PPC_BIT(4)
-#define PHB_PAPR_ERR_INJ_CTL_WR PPC_BIT(5)
-#define PHB_PAPR_ERR_INJ_CTL_FREEZE PPC_BIT(6)
-#define PHB_PAPR_ERR_INJ_ADDR 0x2b8
-#define PHB_PAPR_ERR_INJ_MASK 0x2c0
-#define PHB_PAPR_ERR_INJ_MASK_CFG PPC_BITMASK(4,11)
-#define PHB_PAPR_ERR_INJ_MASK_MMIO PPC_BITMASK(16,39) /* 16M aligned */
-#define PHB_PAPR_ERR_INJ_MASK_IO PPC_BITMASK(16,47) /* 64K aligned */
-#define PHB_PAPR_ERR_INJ_MASK_DMA PPC_BITMASK(60,63) /* 16 window */
-#define PHB_ETU_ERR_SUMMARY 0x2c8
-
-/* UTL registers */
-#define UTL_SYS_BUS_CONTROL 0x400
-#define UTL_STATUS 0x408
-#define UTL_SYS_BUS_AGENT_STATUS 0x410
-#define UTL_SYS_BUS_AGENT_ERR_SEVERITY 0x418
-#define UTL_SYS_BUS_AGENT_IRQ_EN 0x420
-#define UTL_SYS_BUS_BURST_SZ_CONF 0x440
-#define UTL_REVISION_ID 0x448
-#define UTL_OUT_POST_HDR_BUF_ALLOC 0x4c0
-#define UTL_OUT_POST_DAT_BUF_ALLOC 0x4d0
-#define UTL_IN_POST_HDR_BUF_ALLOC 0x4e0
-#define UTL_IN_POST_DAT_BUF_ALLOC 0x4f0
-#define UTL_OUT_NP_BUF_ALLOC 0x500
-#define UTL_IN_NP_BUF_ALLOC 0x510
-#define UTL_PCIE_TAGS_ALLOC 0x520
-#define UTL_GBIF_READ_TAGS_ALLOC 0x530
-#define UTL_PCIE_PORT_CONTROL 0x540
-#define UTL_PCIE_PORT_STATUS 0x548
-#define UTL_PCIE_PORT_ERROR_SEV 0x550
-#define UTL_PCIE_PORT_IRQ_EN 0x558
-#define UTL_RC_STATUS 0x560
-#define UTL_RC_ERR_SEVERITY 0x568
-#define UTL_RC_IRQ_EN 0x570
-#define UTL_EP_STATUS 0x578
-#define UTL_EP_ERR_SEVERITY 0x580
-#define UTL_EP_ERR_IRQ_EN 0x588
-#define UTL_PCI_PM_CTRL1 0x590
-#define UTL_PCI_PM_CTRL2 0x598
-#define UTL_GP_CTL1 0x5a0
-#define UTL_GP_CTL2 0x5a8
-
-/* PCI-E Stack registers */
-#define PHB_PCIE_SYSTEM_CONFIG 0x600
-#define PHB_PCIE_BUS_NUMBER 0x608
-#define PHB_PCIE_SYSTEM_TEST 0x618
-#define PHB_PCIE_LINK_MANAGEMENT 0x630
-#define PHB_PCIE_DLP_TRAIN_CTL 0x640
-#define PHB_PCIE_DLP_TCTX_DISABLE PPC_BIT(1)
-#define PHB_PCIE_DLP_TCRX_DISABLED PPC_BIT(16)
-#define PHB_PCIE_DLP_TC_DL_LINKUP PPC_BIT(21)
-#define PHB_PCIE_DLP_TC_DL_PGRESET PPC_BIT(22)
-#define PHB_PCIE_DLP_TC_DL_LINKACT PPC_BIT(23)
-#define PHB_PCIE_SLOP_LOOPBACK_STATUS 0x648
-#define PHB_PCIE_AER_CONTROL 0x650
-#define PHB_PCIE_AUX_POWER_CONTROL 0x658
-#define PHB_PCIE_SLOTCTL1 0x660
-#define PHB_PCIE_SLOTCTL2 0x668
-#define PHB_PCIE_SLOTCTL2_SLOTWAKE PPC_BIT(16)
-#define PHB_PCIE_SLOTCTL2_PWR_EN_STAT PPC_BIT(17)
-#define PHB_PCIE_SLOTCTL2_RCK_EN_STAT PPC_BIT(18)
-#define PHB_PCIE_SLOTCTL2_PERST_STAT PPC_BIT(19)
-#define PHB_PCIE_SLOTCTL2_PLED_S PPC_BITMASK(20,21) /* use PCIE_INDIC_* */
-#define PHB_PCIE_SLOTCTL2_ALED_S PPC_BITMASK(22,23)
-#define PHB_PCIE_SLOTCTL2_PRSTN_STAT PPC_BIT(24)
-#define PHB_PCIE_SLOTCTL2_PWRFLT_STAT PPC_BIT(25)
-#define PHB_PCIE_UTL_CONFIG 0x670
-#define PHB_PCIE_DLP_CONTROL 0x678
-#define PHB_PCIE_UTL_ERRLOG1 0x680
-#define PHB_PCIE_UTL_ERRLOG2 0x688
-#define PHB_PCIE_UTL_ERRLOG3 0x690
-#define PHB_PCIE_UTL_ERRLOG4 0x698
-#define PHB_PCIE_DLP_ERRLOG1 0x6a0
-#define PHB_PCIE_DLP_ERRLOG2 0x6a8
-#define PHB_PCIE_UTL_ERR_INJECT 0x6c0
-#define PHB_PCIE_TLDLP_ERR_INJECT 0x6c8
-#define PHB_PCIE_STRAPPING 0x700
-
-/* Fundamental register set B */
-#define PHB_VERSION 0x800
-#define PHB_RESET 0x808
-#define PHB_CONTROL 0x810
-#define PHB_AIB_RX_CRED_INIT_TIMER 0x818
-#define PHB_AIB_RX_CMD_CRED 0x820
-#define PHB_AIB_RX_DATA_CRED 0x828
-#define PHB_AIB_TX_CMD_CRED 0x830
-#define PHB_AIB_TX_DATA_CRED 0x838
-#define PHB_AIB_TX_CHAN_MAPPING 0x840
-#define PHB_AIB_TX_CRED_SYNC_CTRL 0x848
-#define PHB_LEGACY_CTRL 0x850
-#define PHB_AIB_TAG_ENABLE 0x858
-#define PHB_AIB_FENCE_CTRL 0x860
-#define PHB_TCE_TAG_ENABLE 0x868
-#define PHB_TCE_WATERMARK 0x870
-#define PHB_TIMEOUT_CTRL1 0x878
-#define PHB_TIMEOUT_CTRL2 0x880
-#define PHB_QUIESCE_DMA_G 0x888
-#define PHB_AIB_TAG_STATUS 0x900
-#define PHB_TCE_TAG_STATUS 0x908
-
-/* FIR & Error registers */
-#define PHB_LEM_FIR_ACCUM 0xc00
-#define PHB_LEM_FIR_AND_MASK 0xc08
-#define PHB_LEM_FIR_OR_MASK 0xc10
-#define PHB_LEM_ERROR_MASK 0xc18
-#define PHB_LEM_ERROR_AND_MASK 0xc20
-#define PHB_LEM_ERROR_OR_MASK 0xc28
-#define PHB_LEM_ACTION0 0xc30
-#define PHB_LEM_ACTION1 0xc38
-#define PHB_LEM_WOF 0xc40
-#define PHB_ERR_STATUS 0xc80
-#define PHB_ERR1_STATUS 0xc88
-#define PHB_ERR_INJECT 0xc90
-#define PHB_ERR_LEM_ENABLE 0xc98
-#define PHB_ERR_IRQ_ENABLE 0xca0
-#define PHB_ERR_FREEZE_ENABLE 0xca8
-#define PHB_ERR_AIB_FENCE_ENABLE 0xcb0
-#define PHB_ERR_LOG_0 0xcc0
-#define PHB_ERR_LOG_1 0xcc8
-#define PHB_ERR_STATUS_MASK 0xcd0
-#define PHB_ERR1_STATUS_MASK 0xcd8
-
-#define PHB_OUT_ERR_STATUS 0xd00
-#define PHB_OUT_ERR1_STATUS 0xd08
-#define PHB_OUT_ERR_INJECT 0xd10
-#define PHB_OUT_ERR_LEM_ENABLE 0xd18
-#define PHB_OUT_ERR_IRQ_ENABLE 0xd20
-#define PHB_OUT_ERR_FREEZE_ENABLE 0xd28
-#define PHB_OUT_ERR_AIB_FENCE_ENABLE 0xd30
-#define PHB_OUT_ERR_LOG_0 0xd40
-#define PHB_OUT_ERR_LOG_1 0xd48
-#define PHB_OUT_ERR_STATUS_MASK 0xd50
-#define PHB_OUT_ERR1_STATUS_MASK 0xd58
-
-#define PHB_INA_ERR_STATUS 0xd80
-#define PHB_INA_ERR1_STATUS 0xd88
-#define PHB_INA_ERR_INJECT 0xd90
-#define PHB_INA_ERR_LEM_ENABLE 0xd98
-#define PHB_INA_ERR_IRQ_ENABLE 0xda0
-#define PHB_INA_ERR_FREEZE_ENABLE 0xda8
-#define PHB_INA_ERR_AIB_FENCE_ENABLE 0xdb0
-#define PHB_INA_ERR_LOG_0 0xdc0
-#define PHB_INA_ERR_LOG_1 0xdc8
-#define PHB_INA_ERR_STATUS_MASK 0xdd0
-#define PHB_INA_ERR1_STATUS_MASK 0xdd8
-
-#define PHB_INB_ERR_STATUS 0xe00
-#define PHB_INB_ERR1_STATUS 0xe08
-#define PHB_INB_ERR_INJECT 0xe10
-#define PHB_INB_ERR_LEM_ENABLE 0xe18
-#define PHB_INB_ERR_IRQ_ENABLE 0xe20
-#define PHB_INB_ERR_FREEZE_ENABLE 0xe28
-#define PHB_INB_ERR_AIB_FENCE_ENABLE 0xe30
-#define PHB_INB_ERR_LOG_0 0xe40
-#define PHB_INB_ERR_LOG_1 0xe48
-#define PHB_INB_ERR_STATUS_MASK 0xe50
-#define PHB_INB_ERR1_STATUS_MASK 0xe58
-
-/* Performance monitor & Debug registers */
-#define PHB_TRACE_CONTROL 0xf80
-#define PHB_PERFMON_CONFIG 0xf88
-#define PHB_PERFMON_CTR0 0xf90
-#define PHB_PERFMON_CTR1 0xf98
-#define PHB_PERFMON_CTR2 0xfa0
-#define PHB_PERFMON_CTR3 0xfa8
-#define PHB_HOTPLUG_OVERRIDE 0xfb0
-
-/*
- * IODA tables
- */
-
-#define IODA_TBL_HRT 0
-#define IODA_TBL_LIST 1
-#define IODA_TBL_LXIVT 2
-#define IODA_TBL_MIST 3
-#define IODA_TBL_MXIVT 4
-#define IODA_TBL_MVT 5
-#define IODA_TBL_PELTM 6
-#define IODA_TBL_PESTA 7
-#define IODA_TBL_PESTB 8
-#define IODA_TBL_TVT 9
-#define IODA_TBL_TCAM 10
-#define IODA_TBL_TDR 11
-#define IODA_TBL_PELTV 12
-#define IODA_TBL_M64BT 16
-#define IODA_TBL_IODT 17
-#define IODA_TBL_M32DT 18
-#define IODA_TBL_M64DT 19
-#define IODA_TBL_PEEV 20
-
-/* L/M XIVT */
-#define IODA_XIVT_SERVER PPC_BITMASK(8,23)
-#define IODA_XIVT_PRIORITY PPC_BITMASK(24,31)
-#define IODA_XIVT_PENUM PPC_BITMASK(41,47)
-#define IODA_XIVT_HUBNUM PPC_BITMASK(58,59)
-
-/* M64BT */
-#define IODA_M64BT_ENABLE PPC_BIT(0)
-#define IODA_M64BT_BASE PPC_BITMASK(8,31)
-#define IODA_M64BT_MASK PPC_BITMASK(40,63)
-
-/* IODT/M32DT/M64DX */
-#define IODA_XXDT_PE PPC_BITMASK(0,6)
-
-/* PELTM */
-#define IODA_PELTM_BUS PPC_BITMASK(0,7)
-#define IODA_PELTM_DEV PPC_BITMASK(8,12)
-#define IODA_PELTM_FUNC PPC_BITMASK(13,15)
-#define IODA_PELTM_BUS_VALID PPC_BITMASK(16,18)
-#define IODA_BUS_VALID_ANY 0
-#define IODA_BUS_VALID_3_BITS 2
-#define IODA_BUS_VALID_4_BITS 3
-#define IODA_BUS_VALID_5_BITS 4
-#define IODA_BUS_VALID_6_BITS 5
-#define IODA_BUS_VALID_7_BITS 6
-#define IODA_BUS_VALID_ALL 7
-#define IODA_PELTM_DEV_VALID PPC_BIT(19)
-#define IODA_PELTM_FUNC_VALID PPC_BIT(20)
-
-/* TVT */
-#define IODA_TVT0_TABLE_ADDR PPC_BITMASK(0,47)
-#define IODA_TVT0_BUS_VALID PPC_BITMASK(48,50)
-#define IODA_TVT0_TCE_TABLE_SIZE PPC_BITMASK(51,55)
-#define IODA_TVT0_BUS_NUM PPC_BITMASK(56,63)
-#define IODA_TVT1_DEV_VALID PPC_BIT(2)
-#define IODA_TVT1_DEV_NUM PPC_BITMASK(3,7)
-#define IODA_TVT1_HUB_NUM PPC_BITMASK(10,11)
-#define IODA_TVT1_FUNC_VALID PPC_BIT(12)
-#define IODA_TVT1_FUNC_NUM PPC_BITMASK(13,15)
-#define IODA_TVT1_IO_PSIZE PPC_BITMASK(19,23)
-#define IODA_TVT1_PE_NUM PPC_BITMASK(57,63)
-
-/* MVT */
-#define IODA_MVT_VALID PPC_BIT(0)
-#define IODA_MVT_BUS_VALID PPC_BITMASK(21,23)
-#define IODA_MVT_BUS_NUM PPC_BITMASK(24,31)
-#define IODA_MVT_PE_NUM PPC_BITMASK(41,47)
-#define IODA_MVT_DEV_VALID PPC_BIT(50)
-#define IODA_MVT_DEV_NUM PPC_BITMASK(51,55)
-#define IODA_MVT_FUNC_VALID PPC_BIT(60)
-#define IODA_MVT_FUNC_NUM PPC_BITMASK(61,63)
-
-/* PESTA */
-#define IODA_PESTA_MMIO_FROZEN PPC_BIT(0)
-#define IODA_PESTA_MMIO_CAUSE PPC_BIT(2)
-#define IODA_PESTA_CFG_READ PPC_BIT(3)
-#define IODA_PESTA_CFG_WRITE PPC_BIT(4)
-#define IODA_PESTA_TTYPE PPC_BITMASK(5,7)
-#define PESTA_TTYPE_DMA_WRITE 0
-#define PESTA_TTYPE_MSI 1
-#define PESTA_TTYPE_DMA_READ 2
-#define PESTA_TTYPE_DMA_READ_RESP 3
-#define PESTA_TTYPE_MMIO_LOAD 4
-#define PESTA_TTYPE_MMIO_STORE 5
-#define PESTA_TTYPE_OTHER 7
-#define IODA_PESTA_CA_RETURN PPC_BIT(8)
-#define IODA_PESTA_UTL_RTOS_TIMEOUT PPC_BIT(8) /* Same bit as CA return */
-#define IODA_PESTA_UR_RETURN PPC_BIT(9)
-#define IODA_PESTA_UTL_NONFATAL PPC_BIT(10)
-#define IODA_PESTA_UTL_FATAL PPC_BIT(11)
-#define IODA_PESTA_TAG_REUSE_ERROR PPC_BIT(12)
-#define IODA_PESTA_PARITY_UE PPC_BIT(13)
-#define IODA_PESTA_UTL_CORRECTABLE PPC_BIT(14)
-#define IODA_PESTA_UTL_INTERRUPT PPC_BIT(15)
-#define IODA_PESTA_MMIO_XLATE PPC_BIT(16)
-#define IODA_PESTA_IODA_ERROR PPC_BIT(16) /* Same bit as MMIO xlate */
-#define IODA_PESTA_TVT_EXT_ERROR PPC_BIT(17)
-#define IODA_PESTA_TCE_PAGE_FAULT PPC_BIT(18)
-#define IODA_PESTA_TCE_ACCESS_FAULT PPC_BIT(19)
-#define IODA_PESTA_DMA_RESP_TIMEOUT PPC_BIT(20)
-#define IODA_PESTA_AIB_SIZE_INVALID PPC_BIT(21)
-#define IODA_PESTA_LEM_BIT PPC_BITMASK(26,31)
-#define IODA_PESTA_RID PPC_BITMASK(32,47)
-#define IODA_PESTA_MSI_DATA PPC_BITMASK(48,63)
-
-/* PESTB */
-#define IODA_PESTB_DMA_STOPPED PPC_BIT(0)
-#define IODA_PESTB_FAIL_ADDR PPC_BITMASK(3,63)
-
-#endif /* __P7IOC_REGS_H */
diff --git a/include/p7ioc.h b/include/p7ioc.h
deleted file mode 100644
index 96f9209..0000000
--- a/include/p7ioc.h
+++ /dev/null
@@ -1,367 +0,0 @@
-/* Copyright 2013-2014 IBM Corp.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- * implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __P7IOC_H
-#define __P7IOC_H
-
-#include <cec.h>
-#include <pci.h>
-
-#include <ccan/container_of/container_of.h>
-
-/*
- * Memory windows and BUID assignment
- *
- * - GX BAR assignment
- *
- * I don't know of any spec here, so we're going to mimmic what
- * OPAL seems to be doing:
- *
- * - BAR 0 : 32M, disabled. We just leave it alone.
- * - BAR 1 : 8G, enabled. Appears to correspond to the MMIO
- * space of the IOC itself and the PCI IO space
- * - BAR 2: 128G,
- * - BAR 3: 128G,
- * - BAR 4: 128G, all 3 contiguous, forming a single 368G region
- * and is used for M32 and M64 PHB windows.
- *
- * - Memory map
- *
- * MWIN1 = BAR1 (8G)
- * MWIN2 = BAR2,3,4 (384G)
- *
- * MWIN2 is divided into 6 * 4G regions for use by M32's (*) and
- * 6 * 32G regions for use by M64's.
- *
- * (*) The M32 will typically be configured to only 2G or so, however
- * the OS is in control of that setting, and since we have to reserve
- * a power of two, we reserve the whole 4G.
- *
- * - RGC registers: MWIN1 + 0x00000000
- * - PHBn IO space: MWIN1 + 0x01000000 + n * 0x00800000 (8M each)
- * - PHBn M32 : MWIN2 + n * 0x1_00000000 (4G each)
- * - PHBn M64 : MWIN2 + (n + 1) * 0x8_00000000 (32G each)
- *
- * - BUID map. The RGC has interrupts, each PHB has then its own
- * interrupts (errors etc...), 4 LSIs and 256 LSIs so
- * respectively 1 BUID for self, 1 for LSIs and 16 for LSIs
- *
- * We keep all BUIDs below 0x10 reserved. They will be used for things
- * like the PSI controller, the NX unit, etc.. in the P7 chip.
- *
- * RGC : 0x010
- * PHBn LSI : 0x040 + n * 0x40 ( 1 BUID)
- * PHBn MSI : 0x060 + n * 0x40 (0x10 BUIDs)
- *
- * -> For routing, each PHB gets a block of 0x40 BUIDs:
- *
- * from 0x40 * (n + 1) to 0x7f * (n + 1)
- */
-
-/* Some definitions resulting from the above description
- *
- * Note: A better approach might be to read the GX BAR content
- * and isolate the biggest contiguous windows. From there
- * we could divide things algorithmically and thus be
- * less sensitive to a change in the memory map by the FSP
- */
-#define MWIN1_SIZE 0x200000000ul /* MWIN1 is 8G */
-#define MWIN2_SIZE 0x6000000000ul /* MWIN2 is 384G */
-#define PHB_IO_OFFSET 0x01000000ul /* Offset of PHB IO space in MWIN1 */
-#define PHB_IO_SIZE 0x00800000ul
-#define PHB_M32_OFFSET 0x0ul /* Offset of PHB M32 space in MWIN2 */
-#define PHB_M32_SIZE 0x100000000ul
-#define PHB_M64_OFFSET 0x800000000ul /* Offset of PHB M64 space in MWIN2 */
-#define PHB_M64_SIZE 0x800000000ul
-#define RGC_BUID_OFFSET 0x10 /* Offset of RGC BUID */
-#define PHB_BUID_OFFSET 0x40 /* Offset of PHB BUID blocks */
-#define PHB_BUID_SIZE 0x40 /* Size of PHB BUID blocks */
-#define PHB_BUID_LSI_OFFSET 0x00 /* Offset of LSI in PHB BUID block */
-#define PHB_BUID_MSI_OFFSET 0x20 /* Offset of MSI in PHB BUID block */
-#define PHB_BUID_MSI_SIZE 0x10 /* Size of PHB MSI BUID block */
-
-#define PHBn_IO_BASE(n) (PHB_IO_OFFSET + (n) * PHB_IO_SIZE)
-#define PHBn_M32_BASE(n) (PHB_M32_OFFSET + (n) * PHB_M32_SIZE)
-#define PHBn_M64_BASE(n) (PHB_M64_OFFSET + (n) * PHB_M64_SIZE)
-#define PHBn_BUID_BASE(n) (PHB_BUID_OFFSET + (n) * PHB_BUID_SIZE)
-
-#define BUID_TO_PHB(buid) (((buid) - PHB_BUID_OFFSET) / PHB_BUID_SIZE)
-
-/* p7ioc has 6 PHBs */
-#define P7IOC_NUM_PHBS 6
-
-/* M32 window setting at boot:
- *
- * To allow for DMA, we need to split the 32-bit PCI address space between
- * MMIO and DMA. For now, we use a 2G/2G split with MMIO at the top.
- *
- * Note: The top 64K of the M32 space are used by MSIs. This is not
- * visible here but need to be conveyed to the OS one way or another
- *
- * Note2: The space reserved in the system address space for M32 is always
- * 4G. That we chose to use a smaller portion of it is not relevant to
- * the upper levels. To keep things consistent, the offset we apply to
- * the window start is also applied on the host side.
- */
-#define M32_PCI_START 0x80000000
-#define M32_PCI_SIZE 0x80000000
-
-/* PHB registers exist in both a hard coded space and a programmable
- * AIB space. We program the latter to the values recommended in the
- * documentation:
- *
- * 0x80000 + n * 0x10000
- */
-#define PHBn_ASB_BASE(n) (((n) << 16))
-#define PHBn_ASB_SIZE 0x10000ul
-#define PHBn_AIB_BASE(n) (0x80000ul + ((n) << 16))
-#define PHBn_AIB_SIZE 0x10000ul
-
-/*
- * LSI interrupts
- *
- * The LSI interrupt block supports 8 interrupts. 4 of them are the
- * standard PCIe INTA..INTB. The rest is for additional functions
- * of the PHB
- */
-#define PHB_LSI_PCIE_INTA 0
-#define PHB_LSI_PCIE_INTB 1
-#define PHB_LSI_PCIE_INTC 2
-#define PHB_LSI_PCIE_INTD 3
-#define PHB_LSI_PCIE_HOTPLUG 4
-#define PHB_LSI_PCIE_PERFCTR 5
-#define PHB_LSI_PCIE_UNUSED 6
-#define PHB_LSI_PCIE_ERROR 7
-
-/* P7IOC PHB slot states */
-#define P7IOC_SLOT_NORMAL PCI_SLOT_STATE_NORMAL
-#define P7IOC_SLOT_LINK PCI_SLOT_STATE_LINK
-#define P7IOC_SLOT_LINK_START (P7IOC_SLOT_LINK + 1)
-#define P7IOC_SLOT_LINK_WAIT (P7IOC_SLOT_LINK + 2)
-#define P7IOC_SLOT_HRESET PCI_SLOT_STATE_HRESET
-#define P7IOC_SLOT_HRESET_START (P7IOC_SLOT_HRESET + 1)
-#define P7IOC_SLOT_HRESET_TRAINING (P7IOC_SLOT_HRESET + 2)
-#define P7IOC_SLOT_HRESET_DELAY (P7IOC_SLOT_HRESET + 3)
-#define P7IOC_SLOT_HRESET_DELAY2 (P7IOC_SLOT_HRESET + 4)
-#define P7IOC_SLOT_FRESET PCI_SLOT_STATE_FRESET
-#define P7IOC_SLOT_FRESET_START (P7IOC_SLOT_FRESET + 1)
-#define P7IOC_SLOT_FRESET_TRAINING (P7IOC_SLOT_FRESET + 2)
-#define P7IOC_SLOT_FRESET_POWER_OFF (P7IOC_SLOT_FRESET + 3)
-#define P7IOC_SLOT_FRESET_POWER_ON (P7IOC_SLOT_FRESET + 4)
-#define P7IOC_SLOT_FRESET_ASSERT (P7IOC_SLOT_FRESET + 5)
-#define P7IOC_SLOT_FRESET_DEASSERT (P7IOC_SLOT_FRESET + 6)
-#define P7IOC_SLOT_CRESET PCI_SLOT_STATE_CRESET
-#define P7IOC_SLOT_CRESET_START (P7IOC_SLOT_CRESET + 1)
-
-/*
- * In order to support error detection and recovery on different
- * types of IOCs (e.g. P5IOC, P7IOC, P8IOC), the best bet would
- * be make the implementation to be 2 layers: OPAL layer and IOC
- * layer. The OPAL layer just handles the general information and
- * IOC layer should process much more detailed information, which
- * is sensitive to itself.
- */
-#define P7IOC_ERR_SRC_NONE 0
-#define P7IOC_ERR_SRC_EI 1
-#define P7IOC_ERR_SRC_RGC 2
-#define P7IOC_ERR_SRC_BI_UP 3
-#define P7IOC_ERR_SRC_BI_DOWN 4
-#define P7IOC_ERR_SRC_CI_P0 5
-#define P7IOC_ERR_SRC_CI_P1 6
-#define P7IOC_ERR_SRC_CI_P2 7
-#define P7IOC_ERR_SRC_CI_P3 8
-#define P7IOC_ERR_SRC_CI_P4 9
-#define P7IOC_ERR_SRC_CI_P5 10
-#define P7IOC_ERR_SRC_CI_P6 11
-#define P7IOC_ERR_SRC_CI_P7 12
-#define P7IOC_ERR_SRC_PHB0 13
-#define P7IOC_ERR_SRC_PHB1 14
-#define P7IOC_ERR_SRC_PHB2 15
-#define P7IOC_ERR_SRC_PHB3 16
-#define P7IOC_ERR_SRC_PHB4 17
-#define P7IOC_ERR_SRC_PHB5 18
-#define P7IOC_ERR_SRC_MISC 19
-#define P7IOC_ERR_SRC_I2C 20
-#define P7IOC_ERR_SRC_LAST 21
-
-#define P7IOC_ERR_CLASS_NONE 0
-#define P7IOC_ERR_CLASS_GXE 1
-#define P7IOC_ERR_CLASS_PLL 2
-#define P7IOC_ERR_CLASS_RGA 3
-#define P7IOC_ERR_CLASS_PHB 4
-#define P7IOC_ERR_CLASS_ER 5
-#define P7IOC_ERR_CLASS_INF 6
-#define P7IOC_ERR_CLASS_MAL 7
-#define P7IOC_ERR_CLASS_LAST 8
-
-/*
- * P7IOC error descriptor. For errors from PHB and PE, they
- * will be cached to the corresponding PHBs. However, the
- * left errors (e.g. EI, CI Port0/1) will be cached to the
- * IOC directly.
- */
-struct p7ioc_err {
- uint32_t err_src;
- uint32_t err_class;
- uint32_t err_bit;
-};
-
-struct p7ioc;
-
-#define P7IOC_PHB_CFG_USE_ASB 0x00000001 /* ASB to access PCI-CFG */
-#define P7IOC_PHB_CFG_BLOCKED 0x00000002 /* PCI-CFG blocked except 0 */
-
-struct p7ioc_phb {
- uint8_t index; /* 0..5 index inside p7ioc */
- uint8_t gen;
- uint32_t flags;
- bool broken;
-#define P7IOC_REV_DD10 0x00a20001
-#define P7IOC_REV_DD11 0x00a20002
- uint32_t rev; /* Both major and minor have 2 bytes */
- void *regs_asb;
- void *regs; /* AIB regs */
- uint32_t buid_lsi;
- uint32_t buid_msi;
- uint64_t io_base;
- uint64_t m32_base;
- uint64_t m64_base;
- int64_t ecap; /* cached PCI-E cap offset */
- int64_t aercap; /* cached AER ecap offset */
- uint64_t lxive_cache[8];
- uint64_t mxive_cache[256];
- uint64_t mve_cache[256];
- uint64_t peltm_cache[128];
- uint64_t peltv_lo_cache[128];
- uint64_t peltv_hi_cache[128];
- uint64_t tve_lo_cache[128];
- uint64_t tve_hi_cache[128];
- uint64_t iod_cache[128];
- uint64_t m32d_cache[128];
- uint64_t m64b_cache[16];
- uint64_t m64d_cache[128];
- bool err_pending;
- struct p7ioc_err err;
- struct p7ioc *ioc;
- struct phb phb;
-};
-
-static inline struct p7ioc_phb *phb_to_p7ioc_phb(struct phb *phb)
-{
- return container_of(phb, struct p7ioc_phb, phb);
-}
-
-static inline bool p7ioc_phb_err_pending(struct p7ioc_phb *p)
-{
- return p->err_pending;
-}
-
-static inline void p7ioc_phb_set_err_pending(struct p7ioc_phb *p, bool pending)
-{
- if (!pending) {
- p->err.err_src = P7IOC_ERR_SRC_NONE;
- p->err.err_class = P7IOC_ERR_CLASS_NONE;
- p->err.err_bit = -1;
- }
-
- p->err_pending = pending;
-}
-
-/*
- * State structure for P7IOC IO HUB
- */
-struct p7ioc {
- /* Device node */
- struct dt_node *dt_node;
-
- /* MMIO regs */
- void *regs;
-
- /* Main MMIO window from GX for registers & PCI IO space */
- uint64_t mmio1_win_start;
- uint64_t mmio1_win_size;
-
- /* Secondary MMIO window for PCI MMIO space */
- uint64_t mmio2_win_start;
- uint64_t mmio2_win_size;
-
- /* BUID base for the PHB. This does include the top bits
- * (chip, GX bus ID, etc...). This is initialized from the
- * SPIRA. It does not contain the offset 0x10 for RGC
- * interrupts.
- *
- * The OPAL-defined "interrupt-base" property will contain
- * the RGC BUID, not this base value, since this is the real
- * starting point of interrupts for the IOC and we don't want
- * to cover the BUID 0..f gap which is reserved for P7 on-chip
- * interrupt sources.
- */
- uint32_t buid_base;
- uint32_t rgc_buid;
-
- /* XIVT cache for RGC interrupts */
- uint64_t xive_cache[16];
- bool err_pending;
- struct p7ioc_err err;
-
- /* PHB array & presence detect */
- struct p7ioc_phb phbs[P7IOC_NUM_PHBS];
- uint8_t phb_pdt;
-
- struct io_hub hub;
-};
-
-static inline struct p7ioc *iohub_to_p7ioc(struct io_hub *hub)
-{
- return container_of(hub, struct p7ioc, hub);
-}
-
-static inline bool p7ioc_err_pending(struct p7ioc *ioc)
-{
- return ioc->err_pending;
-}
-
-static inline void p7ioc_set_err_pending(struct p7ioc *ioc, bool pending)
-{
- if (!pending) {
- ioc->err.err_src = P7IOC_ERR_SRC_NONE;
- ioc->err.err_class = P7IOC_ERR_CLASS_NONE;
- ioc->err.err_bit = -1;
- }
-
- ioc->err_pending = pending;
-}
-
-static inline bool p7ioc_phb_enabled(struct p7ioc *ioc, unsigned int phb)
-{
- return !!(ioc->phb_pdt & (0x80 >> phb));
-}
-
-extern int64_t p7ioc_inits(struct p7ioc *ioc);
-
-extern void p7ioc_phb_setup(struct p7ioc *ioc, uint8_t index);
-extern int64_t p7ioc_phb_init(struct p7ioc_phb *p);
-
-extern bool p7ioc_check_LEM(struct p7ioc *ioc, uint16_t *pci_error_type,
- uint16_t *severity);
-extern int64_t p7ioc_phb_get_xive(struct p7ioc_phb *p, uint32_t isn,
- uint16_t *server, uint8_t *prio);
-extern int64_t p7ioc_phb_set_xive(struct p7ioc_phb *p, uint32_t isn,
- uint16_t server, uint8_t prio);
-extern void p7ioc_reset(struct io_hub *hub);
-extern void p7ioc_phb_reset(struct phb *phb);
-
-#endif /* __P7IOC_H */
diff --git a/include/processor.h b/include/processor.h
index edcc210..b759752 100644
--- a/include/processor.h
+++ b/include/processor.h
@@ -19,7 +19,7 @@
#include <bitutils.h>
-/* P7 MSR bits */
+/* MSR bits */
#define MSR_SF PPC_BIT(0) /* 64-bit mode */
#define MSR_HV PPC_BIT(3) /* Hypervisor mode */
#define MSR_VEC PPC_BIT(38) /* VMX enable */
@@ -41,7 +41,6 @@
/* PIR */
#define SPR_PIR_P9_MASK 0x7fff /* Mask of implemented bits */
#define SPR_PIR_P8_MASK 0x1fff /* Mask of implemented bits */
-#define SPR_PIR_P7_MASK 0x03ff /* Mask of implemented bits */
/* SPR register definitions */
#define SPR_DSCR 0x011 /* RW: Data stream control reg */
@@ -96,12 +95,7 @@
/* Bits in LPCR */
-/* Powersave Exit Cause Enable is different for P7 and P8 */
-#define SPR_LPCR_P7_PECE PPC_BITMASK(49,51)
-#define SPR_LPCR_P7_PECE0 PPC_BIT(49) /* Wake on external interrupts */
-#define SPR_LPCR_P7_PECE1 PPC_BIT(50) /* Wake on decrementer */
-#define SPR_LPCR_P7_PECE2 PPC_BIT(51) /* Wake on MCs, HMIs, etc... */
-
+/* Powersave Exit Cause Enable is different on each generation */
#define SPR_LPCR_P8_PECE PPC_BITMASK(47,51)
#define SPR_LPCR_P8_PECE0 PPC_BIT(47) /* Wake on priv doorbell */
#define SPR_LPCR_P8_PECE1 PPC_BIT(48) /* Wake on hv doorbell */
@@ -200,8 +194,6 @@
#define PVR_VERS_MIN(_pvr) GETFIELD(SPR_PVR_VERS_MIN, _pvr)
/* PVR definitions */
-#define PVR_TYPE_P7 0x003f
-#define PVR_TYPE_P7P 0x004a
#define PVR_TYPE_P8E 0x004b /* Murano */
#define PVR_TYPE_P8 0x004d /* Venice */
#define PVR_TYPE_P8NVL 0x004c /* Naples */
diff --git a/include/psi.h b/include/psi.h
index 79555ec..ad56ce1 100644
--- a/include/psi.h
+++ b/include/psi.h
@@ -54,7 +54,7 @@
#define PSIHB_CR 0x20
#define PSIHB_CR_FSP_CMD_ENABLE PPC_BIT(0)
#define PSIHB_CR_FSP_MMIO_ENABLE PPC_BIT(1)
-#define PSIHB_CR_TCE_ENABLE PPC_BIT(2) /* P7 only */
+#define PSIHB_CR_TCE_ENABLE PPC_BIT(2)
#define PSIHB_CR_FSP_IRQ_ENABLE PPC_BIT(3)
#define PSIHB_CR_FSP_ERR_RSP_ENABLE PPC_BIT(4)
#define PSIHB_CR_PSI_LINK_ENABLE PPC_BIT(5)
@@ -81,9 +81,6 @@
/* PSI Status / Error Mask Register */
#define PSIHB_SEMR 0x28
-/* XIVR and BUID used for PSI interrupts on P7 */
-#define PSIHB_XIVR 0x30
-
/* XIVR and BUID used for PSI interrupts on P8 */
#define PSIHB_XIVR_FSP 0x30
#define PSIHB_XIVR_OCC 0x60
@@ -123,13 +120,6 @@
/*
* PSI Host Bridge Registers (XSCOM)
*/
-#define PSIHB_XSCOM_P7_HBBAR 0x9
-#define PSIHB_XSCOM_P7_HBBAR_EN PPC_BIT(28)
-#define PSIHB_XSCOM_P7_HBCSR 0xd
-#define PSIHB_XSCOM_P7_HBCSR_SET 0x11
-#define PSIHB_XSCOM_P7_HBCSR_CLR 0x12
-#define PSIHB_XSCOM_P7_HBSCR_FSP_IRQ PPC_BIT(13)
-
#define PSIHB_XSCOM_P8_BASE 0xa
#define PSIHB_XSCOM_P8_HBBAR_EN PPC_BIT(63)
#define PSIHB_XSCOM_P8_HBCSR 0xe
@@ -166,8 +156,6 @@
/*
* Layout of the PSI DMA address space
*
- * On P7, we instanciate a TCE table of 16K TCEs mapping 64M
- *
* On P8, we use a larger mapping of 256K TCEs which provides
* us with a 1G window in order to fit the trace buffers
*
diff --git a/include/skiboot.h b/include/skiboot.h
index d70d828..1b3bacb 100644
--- a/include/skiboot.h
+++ b/include/skiboot.h
@@ -107,7 +107,6 @@ void _prlog(int log_level, const char* fmt, ...) __attribute__((format (printf,
/* Processor generation */
enum proc_gen {
proc_gen_unknown,
- proc_gen_p7, /* P7 and P7+ */
proc_gen_p8,
proc_gen_p9,
};
@@ -203,7 +202,6 @@ extern void copy_sreset_vector(void);
extern void copy_sreset_vector_fast_reboot(void);
/* Various probe routines, to replace with an initcall system */
-extern void probe_p7ioc(void);
extern void probe_phb3(void);
extern void probe_phb4(void);
extern int preload_capp_ucode(void);
diff --git a/platforms/ibm-fsp/apollo-pci.c b/platforms/ibm-fsp/apollo-pci.c
index f79b7b3..a6e8d38 100644
--- a/platforms/ibm-fsp/apollo-pci.c
+++ b/platforms/ibm-fsp/apollo-pci.c
@@ -17,7 +17,6 @@
#include <skiboot.h>
#include <device.h>
#include <fsp.h>
-#include <p7ioc.h>
#include <pci-cfg.h>
#include <pci.h>
#include <pci-slot.h>