@@ -8,6 +8,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
@@ -174,6 +175,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");
};
@@ -236,6 +238,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;
@@ -671,10 +689,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 */
@@ -708,6 +850,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)
@@ -12,6 +12,10 @@
#define PAU_FIR_ACTION1(n) (0x407 + (n) * 0x40)
#define PAU_FIR_MAX 3
+#define PAU_FIR1_NDL_BRICKS_0_5 PPC_BITMASK(0, 11)
+#define PAU_FIR1_NDL_BRICKS_6_11 PPC_BITMASK(47, 58)
+#define PAU_FIR2_OTL_PERR PPC_BIT(18)
+
/* PAU RING: Indirect address/data port */
#define PAU_MISC_SCOM_IND_SCOM_ADDR 0x33e
#define PAU_MISC_DA_ADDR PPC_BITMASK(0, 23)
@@ -28,6 +32,7 @@
#define PAU_BLOCK_CQ_SM(n) PAU_BLOCK(4, (n))
#define PAU_BLOCK_CQ_CTL PAU_BLOCK(4, 4)
#define PAU_BLOCK_CQ_DAT PAU_BLOCK(4, 5)
+#define PAU_BLOCK_OTL(brk) PAU_BLOCK(4, 0xC + (brk))
#define PAU_BLOCK_XSL PAU_BLOCK(4, 0xE)
#define PAU_BLOCK_PAU_XTS PAU_BLOCK(7, 1)
#define PAU_BLOCK_PAU_MISC PAU_BLOCK(7, 2)
@@ -60,6 +65,8 @@
#define PAU_MISC_MACHINE_ALLOC_ENABLE PPC_BIT(0)
/* CQ_CTL block registers */
+#define PAU_CTL_MISC_CFG0 (PAU_BLOCK_CQ_CTL + 0x000)
+#define PAU_CTL_MISC_CFG0_OTL_ENABLE PPC_BITMASK(52, 56)
#define PAU_CTL_MISC_CFG2 (PAU_BLOCK_CQ_CTL + 0x010)
#define PAU_CTL_MISC_CFG2_OCAPI_MODE PPC_BITMASK(0, 4)
#define PAU_CTL_MISC_CFG2_OCAPI_4 PPC_BITMASK(10, 14)
@@ -86,15 +93,45 @@
#define PAU_DAT_MISC_CFG1 (PAU_BLOCK_CQ_DAT + 0x008)
#define PAU_DAT_MISC_CFG1_OCAPI_MODE PPC_BITMASK(40, 44)
+/* OTL block registers */
+#define PAU_OTL_MISC_CFG0(brk) (PAU_BLOCK_OTL(brk) + 0x000)
+#define PAU_OTL_MISC_CFG0_EN PPC_BIT(0)
+#define PAU_OTL_MISC_CFG0_BLOCK_PE_HANDLE PPC_BIT(1)
+#define PAU_OTL_MISC_CFG0_BRICKID PPC_BITMASK(2, 3)
+#define PAU_OTL_MISC_CFG0_ENABLE_4_0 PPC_BIT(51)
+#define PAU_OTL_MISC_CFG0_XLATE_RELEASE PPC_BIT(62)
+#define PAU_OTL_MISC_CFG0_ENABLE_5_0 PPC_BIT(63)
+#define PAU_OTL_MISC_CFG_TLX_CREDITS(brk) (PAU_BLOCK_OTL(brk) + 0x050)
+#define PAU_OTL_MISC_CFG_TLX_CREDITS_VC0 PPC_BITMASK(0, 7)
+#define PAU_OTL_MISC_CFG_TLX_CREDITS_VC1 PPC_BITMASK(8, 15)
+#define PAU_OTL_MISC_CFG_TLX_CREDITS_VC2 PPC_BITMASK(16, 23)
+#define PAU_OTL_MISC_CFG_TLX_CREDITS_VC3 PPC_BITMASK(24, 31)
+#define PAU_OTL_MISC_CFG_TLX_CREDITS_DCP0 PPC_BITMASK(32, 39)
+#define PAU_OTL_MISC_CFG_TLX_CREDITS_SPARE PPC_BITMASK(40, 47)
+#define PAU_OTL_MISC_CFG_TLX_CREDITS_DCP2 PPC_BITMASK(48, 55)
+#define PAU_OTL_MISC_CFG_TLX_CREDITS_DCP3 PPC_BITMASK(56, 63)
+#define PAU_OTL_MISC_CFG_TX(brk) (PAU_BLOCK_OTL(brk) + 0x058)
+#define PAU_OTL_MISC_CFG_TX_DRDY_WAIT PPC_BITMASK(5, 7)
+#define PAU_OTL_MISC_CFG_TX_TEMP0_RATE PPC_BITMASK(8, 11)
+#define PAU_OTL_MISC_CFG_TX_TEMP1_RATE PPC_BITMASK(12, 15)
+#define PAU_OTL_MISC_CFG_TX_TEMP2_RATE PPC_BITMASK(16, 19)
+#define PAU_OTL_MISC_CFG_TX_TEMP3_RATE PPC_BITMASK(20, 23)
+#define PAU_OTL_MISC_CFG_TX_CRET_FREQ PPC_BITMASK(32, 34)
+
/* XSL block registers */
#define PAU_XSL_WRAP_CFG (PAU_BLOCK_XSL + 0x100)
#define PAU_XSL_WRAP_CFG_CLOCK_ENABLE PPC_BIT(0)
+#define PAU_XSL_OSL_XLATE_CFG(brk) (PAU_BLOCK_XSL + 0x040 + (brk) * 8)
+#define PAU_XSL_OSL_XLATE_CFG_AFU_DIAL PPC_BIT(0)
+#define PAU_XSL_OSL_XLATE_CFG_OPENCAPI3 PPC_BIT(32)
/* XTS block registers */
#define PAU_XTS_CFG (PAU_BLOCK_PAU_XTS + 0x020)
#define PAU_XTS_CFG_OPENCAPI PPC_BIT(15)
#define PAU_XTS_CFG2 (PAU_BLOCK_PAU_XTS + 0x028)
#define PAU_XTS_CFG2_XSL2_ENA PPC_BIT(55)
+#define PAU_XTS_CFG3 (PAU_BLOCK_PAU_XTS + 0x068)
+#define PAU_XTS_CFG3_MMIOSD_OCAPI PPC_BIT(5)
/* MISC block registers */
#define PAU_MISC_OPTICAL_IO_CONFIG (PAU_BLOCK_PAU_MISC + 0x018)
@@ -53,4 +53,6 @@
#define P10_NCU_DARN_BAR_EN PPC_BIT(0)
#define P10_NCU_DARN_BAR_ADDRMSK 0x000ffffffffff000ull /* 4k aligned */
+#define P10_ROOT_CONTROL_7 0x50017
+
#endif /* __XSCOM_P10_REGS_H__ */