From 6bbe0924a799d33c1a8c9de38b60a5e0251f2aea Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 10 Mar 2017 15:40:30 +0100 Subject: [PATCH] arm: mvebu: AXP: Add possiblity to configure PEX detection pulse width 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 Suggested-by: Adam Shobash Cc: Adam Shobash Cc: Nadav Haklai Cc: Konstantin Porotchkin Signed-off-by: Stefan Roese --- .../serdes/axp/high_speed_env_lib.c | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/arch/arm/mach-mvebu/serdes/axp/high_speed_env_lib.c b/arch/arm/mach-mvebu/serdes/axp/high_speed_env_lib.c index afc0cefda3..5925bae69f 100644 --- a/arch/arm/mach-mvebu/serdes/axp/high_speed_env_lib.c +++ b/arch/arm/mach-mvebu/serdes/axp/high_speed_env_lib.c @@ -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), -- 2.25.1