[PATCH u-boot-marvell 4/9] arm: mvebu: a38x: serdes: Don't overwrite read-only SAR PCIe registers
Stefan Roese
sr at denx.de
Fri Oct 8 08:27:57 CEST 2021
On 24.09.21 22:59, Marek Behún wrote:
> From: Pali Rohár <pali at kernel.org>
>
> Device/Port Type bits of PCIe Root Port PCI Express Capabilities Register
> are read-only SAR registers and are initialized according to current mode
> configured by PCIe controller. Changing PCIe controller mode (from Root
> Complex mode to Endpoint mode or the other way) is possible via PCI
> Express Control Register (offset 0x41A00), bit 1 (ConfRoot Complex). This
> has to be done in PCIe controller driver (in our case pci_mvebu.c). Note
> that default mode is Root Complex.
>
> Maximum Link Speed bits of PCIe Root Port Link Capabilities Register are
> platform specific and overwriting them does not make sense. They are set by
> PCIe controller according to current SerDes configuration. For A38x it is
> 5.0 GT/s if SerDes supports appropriate speed.
>
> Maximum Link Width bits of PCIe Root Port Link Capabilities Register are
> read-only SAR registers, but unfortunately if this is not set correctly
> here, then access PCI config space of the endpoint card behind this Root
> Port does not work.
>
> Signed-off-by: Pali Rohár <pali at kernel.org>
> Reviewed-by: Marek Behún <marek.behun at nic.cz>
Reviewed-by: Stefan Roese <sr at denx.de>
Thanks,
Stefan
> ---
> arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c | 22 ----------
> arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h | 4 ++
> .../serdes/a38x/high_speed_env_spec.c | 40 +++++++------------
> 3 files changed, 19 insertions(+), 47 deletions(-)
>
> diff --git a/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c b/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c
> index 0eb31d589c..7c18df8113 100644
> --- a/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c
> +++ b/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c
> @@ -28,28 +28,6 @@ int hws_pex_config(const struct serdes_map *serdes_map, u8 count)
>
> DEBUG_INIT_FULL_S("\n### hws_pex_config ###\n");
>
> - for (idx = 0; idx < count; idx++) {
> - serdes_type = serdes_map[idx].serdes_type;
> - /* configuration for PEX only */
> - if ((serdes_type != PEX0) && (serdes_type != PEX1) &&
> - (serdes_type != PEX2) && (serdes_type != PEX3))
> - continue;
> -
> - if ((serdes_type != PEX0) &&
> - ((serdes_map[idx].serdes_mode == PEX_ROOT_COMPLEX_X4) ||
> - (serdes_map[idx].serdes_mode == PEX_END_POINT_X4))) {
> - /* for PEX by4 - relevant for the first port only */
> - continue;
> - }
> -
> - /* Set Device/Port Type to RootComplex */
> - pex_idx = serdes_type - PEX0;
> - tmp = reg_read(PEX_CAPABILITIES_REG(pex_idx));
> - tmp &= ~(0xf << 20);
> - tmp |= (0x4 << 20);
> - reg_write(PEX_CAPABILITIES_REG(pex_idx), tmp);
> - }
> -
> tmp = reg_read(SOC_CONTROL_REG1);
> tmp &= ~0x03;
>
> diff --git a/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h b/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h
> index a882d24208..5d70166fc5 100644
> --- a/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h
> +++ b/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h
> @@ -6,8 +6,12 @@
> #ifndef _CTRL_PEX_H
> #define _CTRL_PEX_H
>
> +#include <pci.h>
> #include "high_speed_env_spec.h"
>
> +/* Direct access to PEX0 Root Port's PCIe Capability structure */
> +#define PEX0_RP_PCIE_CFG_OFFSET (0x00080000 + 0x60)
> +
> /* Sample at Reset */
> #define MPP_SAMPLE_AT_RESET(id) (0xe4200 + (id * 4))
>
> diff --git a/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c b/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c
> index 09192acef2..a712fa8994 100644
> --- a/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c
> +++ b/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c
> @@ -1714,7 +1714,7 @@ int serdes_power_up_ctrl(u32 serdes_num, int serdes_power_up,
> (serdes_mode == PEX_END_POINT_X1);
> pex_idx = serdes_type - PEX0;
>
> - if ((is_pex_by1 == 1) || (serdes_type == PEX0)) {
> + if (serdes_type == PEX0) {
> /* For PEX by 4, init only the PEX 0 */
> reg_data = reg_read(SOC_CONTROL_REG1);
> if (is_pex_by1 == 1)
> @@ -1723,30 +1723,20 @@ int serdes_power_up_ctrl(u32 serdes_num, int serdes_power_up,
> reg_data &= ~0x4000;
> reg_write(SOC_CONTROL_REG1, reg_data);
>
> - /* Set Maximum Link Width to X1 or X4 */
> - reg_data = reg_read(PEX_CFG_DIRECT_ACCESS(
> - pex_idx,
> - PEX_LINK_CAPABILITY_REG));
> - reg_data &= ~0x3f0;
> - if (is_pex_by1 == 1)
> - reg_data |= 0x10;
> - else
> - reg_data |= 0x40;
> - reg_write(PEX_CFG_DIRECT_ACCESS(
> - pex_idx,
> - PEX_LINK_CAPABILITY_REG),
> - reg_data);
> -
> - /* Set Maximum Link Speed to 5 GT/s */
> - reg_data = reg_read(PEX_CFG_DIRECT_ACCESS(
> - pex_idx,
> - PEX_LINK_CAPABILITY_REG));
> - reg_data &= ~0xf;
> - reg_data |= 0x2;
> - reg_write(PEX_CFG_DIRECT_ACCESS(
> - pex_idx,
> - PEX_LINK_CAPABILITY_REG),
> - reg_data);
> + /*
> + * Set Maximum Link Width to X1 or X4 in Root
> + * Port's PCIe Link Capability register.
> + * This register is read-only but if is not set
> + * correctly then access to PCI config space of
> + * endpoint card behind this Root Port does not
> + * work.
> + */
> + reg_data = reg_read(PEX0_RP_PCIE_CFG_OFFSET +
> + PCI_EXP_LNKCAP);
> + reg_data &= ~PCI_EXP_LNKCAP_MLW;
> + reg_data |= (is_pex_by1 ? 1 : 4) << 4;
> + reg_write(PEX0_RP_PCIE_CFG_OFFSET +
> + PCI_EXP_LNKCAP, reg_data);
>
> /*
> * Set Common Clock Configuration to indicates
>
Viele Grüße,
Stefan
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-51 Fax: (+49)-8142-66989-80 Email: sr at denx.de
More information about the U-Boot
mailing list