diff options
author | Christophe Lombard <clombard@linux.vnet.ibm.com> | 2021-10-14 17:56:56 +0200 |
---|---|---|
committer | Vasant Hegde <hegdevasant@linux.vnet.ibm.com> | 2021-10-19 12:26:01 +0530 |
commit | a7eae3eef52a3081f0f2188a10cd4dc1d7b8f1c1 (patch) | |
tree | 3bdcbe071eca7f8e96e599f43da766c9e2b8f687 /hw | |
parent | ca9a2b8b315121c6c9d45ca98bc70c0bc8603beb (diff) | |
download | skiboot-a7eae3eef52a3081f0f2188a10cd4dc1d7b8f1c1.zip skiboot-a7eae3eef52a3081f0f2188a10cd4dc1d7b8f1c1.tar.gz skiboot-a7eae3eef52a3081f0f2188a10cd4dc1d7b8f1c1.tar.bz2 |
pau: translation layer configuration
Next main part of the hypervisor PAU initialization.
The P10 PAU supports two OpenCAPI links.
The PAU provides various configuration selections for both of the OCAPI
Link Transaction Layer functions (OTLs). These include a link enable,
behavior controls, debug modes, and virtual channel credits to send to
the AFU. The OTL Configuration 0, OTL Configuration 1, OTL
Configuration 2, and TLX Credit Configuration registers are used to
control these functions.
This patch completes the PAU configuration following the
sections 17.1.3.4 to 17.1.3.10.2 of the workbook document.
Signed-off-by: Christophe Lombard <clombard@linux.vnet.ibm.com>
Reviewed-by: Frederic Barrat <fbarrat@linux.ibm.com>
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/pau.c | 192 |
1 files changed, 192 insertions, 0 deletions
@@ -7,6 +7,7 @@ #include <phys-map.h> #include <pau.h> #include <pau-regs.h> +#include <xscom-p10-regs.h> /* Number of PEs supported */ #define PAU_MAX_PE_NUM 16 @@ -173,6 +174,7 @@ static struct pau *pau_create(struct dt_node *dn) dev->pau = pau; dev->dn = link; dev->odl_index = dt_prop_get_u32(link, "ibm,odl-index"); + dev->pau_unit = dt_prop_get_u32(link, "ibm,pau-unit"); dev->op_unit = dt_prop_get_u32(link, "ibm,op-unit"); dev->phy_lane_mask = dt_prop_get_u32(link, "ibm,pau-lane-mask"); }; @@ -235,6 +237,22 @@ static int pau_opencapi_set_fence_control(struct pau_dev *dev, return OPAL_HARDWARE; } +static void pau_opencapi_mask_firs(struct pau *pau) +{ + uint64_t reg, val; + + reg = pau->xscom_base + PAU_FIR_MASK(1); + xscom_read(pau->chip_id, reg, &val); + val |= PAU_FIR1_NDL_BRICKS_0_5; + val |= PAU_FIR1_NDL_BRICKS_6_11; + xscom_write(pau->chip_id, reg, val); + + reg = pau->xscom_base + PAU_FIR_MASK(2); + xscom_read(pau->chip_id, reg, &val); + val |= PAU_FIR2_OTL_PERR; + xscom_write(pau->chip_id, reg, val); +} + static void pau_opencapi_assign_bars(struct pau *pau) { struct pau_dev *dev; @@ -670,10 +688,134 @@ static void pau_opencapi_enable_powerbus(struct pau *pau) pau_write(pau, reg, val); } +static void pau_opencapi_tl_config(struct pau_dev *dev) +{ + struct pau *pau = dev->pau; + uint64_t val; + + PAUDEVDBG(dev, "TL Configuration\n"); + + /* OTL Config 0 */ + val = 0; + val |= PAU_OTL_MISC_CFG0_EN; + val |= PAU_OTL_MISC_CFG0_BLOCK_PE_HANDLE; + val = SETFIELD(PAU_OTL_MISC_CFG0_BRICKID, val, dev->index); + val |= PAU_OTL_MISC_CFG0_ENABLE_4_0; + val |= PAU_OTL_MISC_CFG0_XLATE_RELEASE; + val |= PAU_OTL_MISC_CFG0_ENABLE_5_0; + pau_write(pau, PAU_OTL_MISC_CFG0(dev->index), val); + + /* OTL Config 1 */ + val = 0; + val = SETFIELD(PAU_OTL_MISC_CFG_TX_DRDY_WAIT, val, 0b010); + val = SETFIELD(PAU_OTL_MISC_CFG_TX_TEMP0_RATE, val, 0b0000); + val = SETFIELD(PAU_OTL_MISC_CFG_TX_TEMP1_RATE, val, 0b0011); + val = SETFIELD(PAU_OTL_MISC_CFG_TX_TEMP2_RATE, val, 0b0111); + val = SETFIELD(PAU_OTL_MISC_CFG_TX_TEMP3_RATE, val, 0b0010); + val = SETFIELD(PAU_OTL_MISC_CFG_TX_CRET_FREQ, val, 0b001); + pau_write(pau, PAU_OTL_MISC_CFG_TX(dev->index), val); + + /* OTL Config 2 - Done after link training, in otl_tx_send_enable() */ + + /* TLX Credit Configuration */ + val = 0; + val = SETFIELD(PAU_OTL_MISC_CFG_TLX_CREDITS_VC0, val, 0x40); + val = SETFIELD(PAU_OTL_MISC_CFG_TLX_CREDITS_VC1, val, 0x40); + val = SETFIELD(PAU_OTL_MISC_CFG_TLX_CREDITS_VC2, val, 0x40); + val = SETFIELD(PAU_OTL_MISC_CFG_TLX_CREDITS_VC3, val, 0x40); + val = SETFIELD(PAU_OTL_MISC_CFG_TLX_CREDITS_DCP0, val, 0x80); + val = SETFIELD(PAU_OTL_MISC_CFG_TLX_CREDITS_SPARE, val, 0x80); + val = SETFIELD(PAU_OTL_MISC_CFG_TLX_CREDITS_DCP2, val, 0x80); + val = SETFIELD(PAU_OTL_MISC_CFG_TLX_CREDITS_DCP3, val, 0x80); + pau_write(pau, PAU_OTL_MISC_CFG_TLX_CREDITS(dev->index), val); +} + +static void pau_opencapi_enable_otlcq_interface(struct pau_dev *dev) +{ + struct pau *pau = dev->pau; + uint8_t typemap = 0; + uint64_t reg, val; + + PAUDEVDBG(dev, "Enabling OTL-CQ Interface\n"); + + typemap |= 0x10 >> dev->index; + reg = PAU_CTL_MISC_CFG0; + val = pau_read(pau, reg); + typemap |= GETFIELD(PAU_CTL_MISC_CFG0_OTL_ENABLE, val); + val = SETFIELD(PAU_CTL_MISC_CFG0_OTL_ENABLE, val, typemap); + pau_write(pau, reg, val); +} + +static void pau_opencapi_address_translation_config(struct pau_dev *dev) +{ + struct pau *pau = dev->pau; + uint64_t reg, val; + + PAUDEVDBG(dev, "Address Translation Configuration\n"); + + /* OpenCAPI 4.0 Mode */ + reg = PAU_XSL_OSL_XLATE_CFG(dev->index); + val = pau_read(pau, reg); + val |= PAU_XSL_OSL_XLATE_CFG_AFU_DIAL; + val &= ~PAU_XSL_OSL_XLATE_CFG_OPENCAPI3; + pau_write(pau, reg, val); + + /* MMIO shootdowns (OpenCAPI 5.0) */ + reg = PAU_XTS_CFG3; + val = pau_read(pau, reg); + val |= PAU_XTS_CFG3_MMIOSD_OCAPI; + pau_write(pau, reg, val); + + /* XSL_GP - use defaults */ +} + +static void pau_opencapi_enable_ref_clock(struct pau_dev *dev) +{ + uint64_t reg, val; + int bit; + + switch (dev->pau_unit) { + case 0: + if (dev->index == 0) + bit = 16; + else + bit = 17; + break; + case 3: + if (dev->index == 0) + bit = 18; + else + bit = 19; + break; + case 4: + bit = 20; + break; + case 5: + bit = 21; + break; + case 6: + bit = 22; + break; + case 7: + bit = 23; + break; + default: + assert(false); + } + + reg = P10_ROOT_CONTROL_7; + xscom_read(dev->pau->chip_id, reg, &val); + val |= PPC_BIT(bit); + PAUDEVDBG(dev, "Enabling ref clock for PAU%d => %llx\n", + dev->pau_unit, val); + xscom_write(dev->pau->chip_id, reg, val); +} + static void pau_opencapi_init_hw(struct pau *pau) { struct pau_dev *dev = NULL; + pau_opencapi_mask_firs(pau); pau_opencapi_assign_bars(pau); /* Create phb */ @@ -707,6 +849,56 @@ static void pau_opencapi_init_hw(struct pau *pau) * and machine state allocation */ pau->mmio_access = true; + + pau_for_each_opencapi_dev(dev, pau) { + /* Procedure 17.1.3.4 - Transaction Layer Configuration + * OCAPI Link Transaction Layer functions + */ + pau_opencapi_tl_config(dev); + + /* Procedure 17.1.3.4.1 - Enabling OTL-CQ Interface */ + pau_opencapi_enable_otlcq_interface(dev); + + /* Procedure 17.1.3.4.2 - Place OTL into Reset State + * Reset (Fence) both OTL and the PowerBus for this + * Brick + */ + pau_opencapi_set_fence_control(dev, 0b11); + + /* Take PAU out of OTL Reset State + * Reset (Fence) only the PowerBus for this Brick, OTL + * will be operational + */ + pau_opencapi_set_fence_control(dev, 0b10); + + /* Procedure 17.1.3.5 - Address Translation Configuration */ + pau_opencapi_address_translation_config(dev); + + /* Procedure 17.1.3.6 - AFU Memory Range BARs */ + /* Will be done out of this process */ + + /* Procedure 17.1.3.8 - AFU MMIO Range BARs */ + /* done in pau_opencapi_assign_bars() */ + + /* Procedure 17.1.3.9 - AFU Config BARs */ + /* done in pau_opencapi_assign_bars() */ + + /* Precedure 17.1.3.10 - Relaxed Ordering Configuration */ + /* Procedure 17.1.3.10.1 - Generation-Id Registers MMIO Bars */ + /* done in pau_opencapi_assign_bars() */ + + /* Procedure 17.1.3.10.2 - Relaxed Ordering Source Configuration */ + /* For an OpenCAPI AFU that uses M2 Memory Mode, + * Relaxed Ordering can be used for accesses to the + * AFU's memory + */ + + /* Reset disabled. Place OTLs into Run State */ + pau_opencapi_set_fence_control(dev, 0b00); + + /* Enable reference clock */ + pau_opencapi_enable_ref_clock(dev); + } } static void pau_opencapi_init(struct pau *pau) |