/* Copyright 2013-2016 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 __PHB4_H #define __PHB4_H #include /* * Memory map * * In addition to the 4K MMIO registers window, the PBCQ will * forward down one or two large MMIO regions for use by the * PHB. * * We try to use the largest MMIO window for the M64 space and * the smallest for the M32 space, but we require at least 2G * of M32, otherwise we carve it out of M64. */ #define M32_PCI_START 0x080000000 /* Offset of the actual M32 window in PCI */ #define M32_PCI_SIZE 0x80000000ul /* Size for M32 */ #if 0 /* * Interrupt map. * * Each PHB supports 2K interrupt sources, which is shared by * LSI and MSI. With default configuration, MSI would use range * [0, 0x7f7] and LSI would use [0x7f8, 0x7ff]. The interrupt * source should be combined with IRSN to form final hardware * IRQ. */ #define PHB4_MSI_IRQ_MIN 0x000 #define PHB4_MSI_IRQ_COUNT 0x7F8 #define PHB4_MSI_IRQ_MAX (PHB4_MSI_IRQ_MIN+PHB4_MSI_IRQ_COUNT-1) #define PHB4_LSI_IRQ_MIN (PHB4_MSI_IRQ_COUNT) #define PHB4_LSI_IRQ_COUNT 8 #define PHB4_LSI_IRQ_MAX (PHB4_LSI_IRQ_MIN+PHB4_LSI_IRQ_COUNT-1) #define PHB4_MSI_IRQ_BASE(chip, phb) (p8_chip_irq_phb_base(chip, phb) | \ PHB4_MSI_IRQ_MIN) #define PHB4_LSI_IRQ_BASE(chip, phb) (p8_chip_irq_phb_base(chip, phb) | \ PHB4_LSI_IRQ_MIN) #define PHB4_IRQ_NUM(irq) (irq & 0x7FF) #endif /* * 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 PHB4_LSI_PCIE_INTA 0 #define PHB4_LSI_PCIE_INTB 1 #define PHB4_LSI_PCIE_INTC 2 #define PHB4_LSI_PCIE_INTD 3 #define PHB4_LSI_PCIE_INF 6 #define PHB4_LSI_PCIE_ER 7 /* * In-memory tables * * PHB4 requires a bunch of tables to be in memory instead of * arrays inside the chip (unlike previous versions of the * design). * * Some of them (IVT, etc...) will be provided by the OS via an * OPAL call, not only not all of them, we also need to make sure * some like PELT-V exist before we do our internal slot probing * or bad thing would happen on error (the whole PHB would go into * Fatal error state). * * So we maintain a set of tables internally for those mandatory * ones within our core memory. They are fairly small. They can * still be replaced by OS provided ones via OPAL APIs (and reset * to the internal ones) so the OS can provide node local allocation * for better performances. * * All those tables have to be naturally aligned */ /* RTT Table : 128KB - Maps RID to PE# * * Entries are 2 bytes indexed by PCIe RID */ #define RTT_TABLE_ENTRIES 0x10000 #define RTT_TABLE_SIZE 0x20000 #define PELTV_TABLE_SIZE_MAX 0x20000 #define PHB4_RESERVED_PE_NUM(p) ((p)->num_pes - 1) /* * PHB4 PCI slot state. When you're going to apply any * changes here, please make sure the base state isn't * conflicting with those defined in pci-slot.h */ #define PHB4_SLOT_NORMAL PCI_SLOT_STATE_NORMAL #define PHB4_SLOT_LINK PCI_SLOT_STATE_LINK #define PHB4_SLOT_LINK_START (PHB4_SLOT_LINK + 1) #define PHB4_SLOT_LINK_WAIT_ELECTRICAL (PHB4_SLOT_LINK + 2) #define PHB4_SLOT_LINK_WAIT (PHB4_SLOT_LINK + 3) #define PHB4_SLOT_LINK_STABLE (PHB4_SLOT_LINK + 4) #define PHB4_SLOT_HRESET PCI_SLOT_STATE_HRESET #define PHB4_SLOT_HRESET_START (PHB4_SLOT_HRESET + 1) #define PHB4_SLOT_HRESET_DELAY (PHB4_SLOT_HRESET + 2) #define PHB4_SLOT_HRESET_DELAY2 (PHB4_SLOT_HRESET + 3) #define PHB4_SLOT_FRESET PCI_SLOT_STATE_FRESET #define PHB4_SLOT_FRESET_START (PHB4_SLOT_FRESET + 1) #define PHB4_SLOT_FRESET_ASSERT_DELAY (PHB4_SLOT_FRESET + 2) #define PHB4_SLOT_CRESET PCI_SLOT_STATE_CRESET #define PHB4_SLOT_CRESET_START (PHB4_SLOT_CRESET + 1) #define PHB4_SLOT_CRESET_WAIT_CQ (PHB4_SLOT_CRESET + 2) #define PHB4_SLOT_CRESET_REINIT (PHB4_SLOT_CRESET + 3) #define PHB4_SLOT_CRESET_FRESET (PHB4_SLOT_CRESET + 4) /* * PHB4 error descriptor. Errors from all components (PBCQ, PHB) * will be cached to PHB4 instance. However, PBCQ errors would * have higher priority than those from PHB */ #define PHB4_ERR_SRC_NONE 0 #define PHB4_ERR_SRC_PBCQ 1 #define PHB4_ERR_SRC_PHB 2 #define PHB4_ERR_CLASS_NONE 0 #define PHB4_ERR_CLASS_DEAD 1 #define PHB4_ERR_CLASS_FENCED 2 #define PHB4_ERR_CLASS_ER 3 #define PHB4_ERR_CLASS_INF 4 #define PHB4_ERR_CLASS_LAST 5 struct phb4_err { uint32_t err_src; uint32_t err_class; uint32_t err_bit; }; #define PHB4_LINK_LINK_RETRIES 4 /* Link timeouts, increments of 10ms */ #define PHB4_LINK_ELECTRICAL_RETRIES 100 #define PHB4_LINK_WAIT_RETRIES 200 #define PHB4_RX_ERR_MAX 8 /* PHB4 flags */ #define PHB4_AIB_FENCED 0x00000001 #define PHB4_CFG_USE_ASB 0x00000002 #define PHB4_CFG_BLOCKED 0x00000004 #define PHB4_CAPP_RECOVERY 0x00000008 #define PHB4_CAPP_DISABLE 0x00000010 struct phb4 { unsigned int index; /* 0..5 index inside p9 */ unsigned int flags; unsigned int chip_id; /* Chip ID (== GCID on p9) */ unsigned int pec; bool broken; unsigned int rev; /* 00MMmmmm */ #define PHB4_REV_NIMBUS_DD10 0xa40001 #define PHB4_REV_NIMBUS_DD20 0xa40002 void *regs; void *int_mmio; uint64_t pe_xscom; /* XSCOM bases */ uint64_t pe_stk_xscom; uint64_t pci_xscom; uint64_t pci_stk_xscom; uint64_t etu_xscom; struct lock lock; uint64_t mm0_base; /* Full MM window to PHB */ uint64_t mm0_size; /* '' '' '' */ uint64_t mm1_base; /* Full MM window to PHB */ uint64_t mm1_size; /* '' '' '' */ uint32_t base_msi; uint32_t base_lsi; uint64_t irq_port; uint32_t num_pes; uint32_t max_num_pes; uint32_t num_irqs; uint64_t creset_start_time; /* SkiBoot owned in-memory tables */ uint16_t *tbl_rtt; uint8_t *tbl_peltv; uint64_t tbl_peltv_size; uint64_t tbl_pest; uint64_t tbl_pest_size; bool skip_perst; /* Skip first perst */ bool has_link; int64_t ecap; /* cached PCI-E cap offset */ int64_t aercap; /* cached AER ecap offset */ const __be64 *lane_eq; bool lane_eq_en; unsigned int max_link_speed; unsigned int dt_max_link_speed; uint64_t mrt_size; uint64_t mbt_size; uint64_t tvt_size; /* FIXME: dynamically allocate only what's needed below */ uint64_t tve_cache[1024]; uint64_t mbt_cache[32][2]; uint64_t mdt_cache[512]; /* max num of PEs */ uint64_t mist_cache[4096/4];/* max num of MSIs */ uint64_t pfir_cache; /* Used by complete reset */ uint64_t nfir_cache; /* Used by complete reset */ bool err_pending; struct phb4_err err; /* Cache some RC registers that need to be emulated */ uint32_t rc_cache[4]; /* Current NPU2 relaxed ordering state */ bool ro_state; /* Any capp instance attached to the PHB4 */ struct capp *capp; struct phb phb; }; static inline struct phb4 *phb_to_phb4(struct phb *phb) { return container_of(phb, struct phb4, phb); } static inline bool phb4_err_pending(struct phb4 *p) { return p->err_pending; } static inline void phb4_set_err_pending(struct phb4 *p, bool pending) { if (!pending) { p->err.err_src = PHB4_ERR_SRC_NONE; p->err.err_class = PHB4_ERR_CLASS_NONE; p->err.err_bit = -1; } p->err_pending = pending; } #define PHB4_PER_CHIP 6 /* Max 6 PHBs per chip on p9 */ static inline int phb4_get_opal_id(unsigned int chip_id, unsigned int index) { return chip_id * PHB4_PER_CHIP + index; } #endif /* __PHB4_H */