summaryrefslogtreecommitdiff
path: root/usr/src/uts/sun4u/io/px/px_lib4u.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/sun4u/io/px/px_lib4u.c')
-rw-r--r--usr/src/uts/sun4u/io/px/px_lib4u.c102
1 files changed, 102 insertions, 0 deletions
diff --git a/usr/src/uts/sun4u/io/px/px_lib4u.c b/usr/src/uts/sun4u/io/px/px_lib4u.c
index 0573a88a85..a9e1388722 100644
--- a/usr/src/uts/sun4u/io/px/px_lib4u.c
+++ b/usr/src/uts/sun4u/io/px/px_lib4u.c
@@ -69,6 +69,31 @@ static boolean_t px_cpr_callb(void *arg, int code);
static uint_t px_cb_intr(caddr_t arg);
/*
+ * ACKNAK Latency Threshold Table.
+ * See Fire PRM 2.0 section 1.2.12.2, table 1-17.
+ */
+int px_acknak_timer_table[LINK_MAX_PKT_ARR_SIZE][LINK_WIDTH_ARR_SIZE] = {
+ {0xED, 0x49, 0x43, 0x30},
+ {0x1A0, 0x76, 0x6B, 0x48},
+ {0x22F, 0x9A, 0x56, 0x56},
+ {0x42F, 0x11A, 0x96, 0x96},
+ {0x82F, 0x21A, 0x116, 0x116},
+ {0x102F, 0x41A, 0x216, 0x216}
+};
+
+/*
+ * TxLink Replay Timer Latency Table
+ * See Fire PRM 2.0 sections 1.2.12.3, table 1-18.
+ */
+int px_replay_timer_table[LINK_MAX_PKT_ARR_SIZE][LINK_WIDTH_ARR_SIZE] = {
+ {0x379, 0x112, 0xFC, 0xB4},
+ {0x618, 0x1BA, 0x192, 0x10E},
+ {0x831, 0x242, 0x143, 0x143},
+ {0xFB1, 0x422, 0x233, 0x233},
+ {0x1EB0, 0x7E1, 0x412, 0x412},
+ {0x3CB0, 0xF61, 0x7D2, 0x7D2}
+};
+/*
* px_lib_map_registers
*
* This function is called from the attach routine to map the registers
@@ -2605,3 +2630,80 @@ px_lib_get_bdf(px_t *px_p)
return (bdf);
}
+
+/*ARGSUSED*/
+int
+px_lib_get_root_complex_mps(px_t *px_p, dev_info_t *dip, int *mps)
+{
+ pxu_t *pxu_p;
+ caddr_t csr_base;
+
+ pxu_p = (pxu_t *)px_p->px_plat_p;
+
+ if (pxu_p == NULL)
+ return (DDI_FAILURE);
+
+ csr_base = (caddr_t)pxu_p->px_address[PX_REG_CSR];
+
+
+ *mps = CSR_XR(csr_base, TLU_DEVICE_CAPABILITIES) &
+ TLU_DEVICE_CAPABILITIES_MPS_MASK;
+
+ return (DDI_SUCCESS);
+}
+
+/*ARGSUSED*/
+int
+px_lib_set_root_complex_mps(px_t *px_p, dev_info_t *dip, int mps)
+{
+ pxu_t *pxu_p;
+ caddr_t csr_base;
+ uint64_t dev_ctrl;
+ int link_width, val;
+ px_chip_type_t chip_type = px_identity_init(px_p);
+
+ pxu_p = (pxu_t *)px_p->px_plat_p;
+
+ if (pxu_p == NULL)
+ return (DDI_FAILURE);
+
+ csr_base = (caddr_t)pxu_p->px_address[PX_REG_CSR];
+
+ dev_ctrl = CSR_XR(csr_base, TLU_DEVICE_CONTROL);
+ dev_ctrl |= (mps << TLU_DEVICE_CONTROL_MPS);
+
+ CSR_XS(csr_base, TLU_DEVICE_CONTROL, dev_ctrl);
+
+ link_width = CSR_FR(csr_base, TLU_LINK_STATUS, WIDTH);
+
+ /*
+ * Convert link_width to match timer array configuration.
+ */
+ switch (link_width) {
+ case 1:
+ link_width = 0;
+ break;
+ case 4:
+ link_width = 1;
+ break;
+ case 8:
+ link_width = 2;
+ break;
+ case 16:
+ link_width = 3;
+ break;
+ default:
+ link_width = 0;
+ }
+
+ val = px_replay_timer_table[mps][link_width];
+ CSR_XS(csr_base, LPU_TXLINK_REPLAY_TIMER_THRESHOLD, val);
+
+ if (chip_type == PX_CHIP_OBERON)
+ return (DDI_SUCCESS);
+
+ val = px_acknak_timer_table[mps][link_width];
+ CSR_XS(csr_base, LPU_TXLINK_FREQUENT_NAK_LATENCY_TIMER_THRESHOLD, val);
+
+ return (DDI_SUCCESS);
+}