arm: mvebu: AXP: Add possiblity to configure PEX detection pulse width
authorStefan Roese <sr@denx.de>
Fri, 10 Mar 2017 14:40:30 +0000 (15:40 +0100)
committerStefan Roese <sr@denx.de>
Thu, 23 Mar 2017 09:52:28 +0000 (10:52 +0100)
Tests have shown that on some boards the default width of the
configuration pulse for the PEX link detection might lead to
non-established PCIe links (link down). Especially under certain
conditions (higher temperature) and with specific PCIe devices
(in the case on the theadorable board its a Atheros PCIe WLAN
device). To enable a board-specific detection pulse width this weak
array "serdes_pex_pulse_width[4]" is introduced which can be
overwritten if needed by a board-specific version. If the board
code does not provide a non-weak version of this variable, the
default value will be used. So nothing is changed from the
current setup on the supported board.

Many thanks to Adam from Marvell for all his insights here and
his suggestion about testing with a changed detection pulse width.

Signed-off-by: Stefan Roese <sr@denx.de>
Suggested-by: Adam Shobash <adams@marvell.com>
Cc: Adam Shobash <adams@marvell.com>
Cc: Nadav Haklai <nadavh@marvell.com>
Cc: Konstantin Porotchkin <kostap@marvell.com>
Signed-off-by: Stefan Roese <sr@denx.de>
arch/arm/mach-mvebu/serdes/axp/high_speed_env_lib.c

index afc0cefda3c17072fde24bc7896ce52f0987236b..5925bae69f18257c72b80240a2cabe25d26f2278 100644 (file)
@@ -230,6 +230,20 @@ static int serdes_max_lines_get(void)
        return 0;
 }
 
+/*
+ * Tests have shown that on some boards the default width of the
+ * configuration pulse for the PEX link detection might lead to
+ * non-established PCIe links (link down). Especially under certain
+ * conditions (higher temperature) and with specific PCIe devices.
+ * To enable a board-specific detection pulse width this weak
+ * array "serdes_pex_pulse_width[4]" is introduced which can be
+ * overwritten if needed by a board-specific version. If the board
+ * code does not provide a non-weak version of this variable, the
+ * default value will be used. So nothing is changed from the
+ * current setup on the supported board.
+ */
+__weak u8 serdes_pex_pulse_width[4] = { 2, 2, 2, 2 };
+
 int serdes_phy_config(void)
 {
        int status = MV_OK;
@@ -891,6 +905,23 @@ int serdes_phy_config(void)
                        pex_unit = line_num >> 2;
                        pex_line_num = line_num % 4;
                        if (0 == pex_line_num) {
+                               /*
+                                * Configure the detection pulse with before
+                                * the reset is deasserted
+                                */
+
+                               /* Read the old value (indirect access) */
+                               reg_write(PEX_PHY_ACCESS_REG(pex_unit),
+                                         (0x48 << 16) | (1 << 31) |
+                                         (pex_line_num << 24));
+                               tmp = reg_read(PEX_PHY_ACCESS_REG(pex_unit));
+                               tmp &= ~(1 << 31);      /* Clear read */
+                               tmp &= ~(3 << 6);       /* Mask width */
+                               /* Insert new detection pulse width */
+                               tmp |= serdes_pex_pulse_width[pex_unit] << 6;
+                               /* Write value back */
+                               reg_write(PEX_PHY_ACCESS_REG(pex_unit), tmp);
+
                                reg_write(PEX_PHY_ACCESS_REG(pex_unit),
                                          (0xC1 << 16) | 0x24);
                                DEBUG_WR_REG(PEX_PHY_ACCESS_REG(pex_unit),