[U-Boot] [PATCH] board: ls1028a: set up integrated PCI stream IDs and cache attributes

Bin Meng bmeng.cn at gmail.com
Fri Aug 9 09:58:13 UTC 2019


Hi Alex,

On Fri, Aug 9, 2019 at 3:59 PM Alex Marginean
<alexandru.marginean at nxp.com> wrote:
>
> Configure stream IDs for integrated PCI devices.  There are hardware
> defaults but unfortunately they are outside the acceptable range for
> SMMU, so we need to tune them down.  Use values based on Linux device tree
> iommu-map or, if missing, start from HW base value shifted down by 4.
>
> Signed-off-by: Alex Marginean <alexm.osslist at gmail.com>
> ---
>  board/freescale/ls1028a/ls1028a.c | 64 +++++++++++++++++++++++++++++++
>  1 file changed, 64 insertions(+)
>
> diff --git a/board/freescale/ls1028a/ls1028a.c b/board/freescale/ls1028a/ls1028a.c
> index 49a9292c31..05eac6f9c4 100644
> --- a/board/freescale/ls1028a/ls1028a.c
> +++ b/board/freescale/ls1028a/ls1028a.c
> @@ -118,6 +118,67 @@ void detail_board_ddr_info(void)
>  }
>
>  #ifdef CONFIG_OF_BOARD_SETUP
> +
> +/*
> + * Hardware default stream IDs are 0x4000 + PCI function #, but that's outside
> + * the acceptable range for SMMU.  Use Linux DT values instead or at least
> + * smaller defaults.
> + */
> +#define ECAM_NUM_PFS                   7
> +#define ECAM_IERB_BASE                 0x1F0800000
> +#define ECAM_PFAMQ(pf, vf)             ((ECAM_IERB_BASE + 0x800 + (pf) * \
> +                                         0x1000 + (vf) * 4))
> +/* cache related transaction attributes for PCIe functions */
> +#define ECAM_IERB_MSICAR               (ECAM_IERB_BASE + 0xa400)
> +#define ECAM_IERB_MSICAR_VALUE         0x30
> +
> +/* number of VFs per PF, VFs have their own AMQ settings */
> +static const u8 enetc_vfs[ECAM_NUM_PFS] = { 2, 2 };
> +
> +void setup_ecam_amq(void *blob)

nits: this should be static

> +{
> +       int streamid, sid_base, off;
> +       int pf, vf, vfnn = 1;
> +       u32 iommu_map[4];
> +       int err;
> +
> +       /*
> +        * Look up the stream ID settings in the DT, if found apply the values
> +        * to HW, otherwise use HW values shifted down by 4.
> +        */
> +       off = fdt_node_offset_by_compatible(blob, 0, "pci-host-ecam-generic");
> +       if (off < 0) {
> +               debug("ECAM node not found\n");
> +               return;
> +       }
> +
> +       err = fdtdec_get_int_array(blob, off, "iommu-map", iommu_map, 4);
> +       if (err) {
> +               sid_base = in_le32(ECAM_PFAMQ(0, 0)) >> 4;
> +               debug("\"iommu-map\" not found, using default SID base %04x\n",
> +                     sid_base);
> +       } else {
> +               sid_base = iommu_map[2];
> +       }
> +       /* set up AMQs for all integrated PCI functions */
> +       for (pf = 0; pf < ECAM_NUM_PFS; pf++) {
> +               streamid = sid_base + pf;
> +               out_le32(ECAM_PFAMQ(pf, 0), streamid);
> +
> +               /* set up AMQs for VFs, if any */
> +               for (vf = 0; vf < enetc_vfs[pf]; vf++, vfnn++) {
> +                       streamid = sid_base + ECAM_NUM_PFS + vfnn;
> +                       out_le32(ECAM_PFAMQ(pf, vf + 1), streamid);
> +               }
> +       }
> +}
> +
> +void setup_ecam_cacheattr(void)

ditto

> +{
> +       /* set MSI cache attributes */
> +       out_le32(ECAM_IERB_MSICAR, ECAM_IERB_MSICAR_VALUE);
> +}
> +
>  int ft_board_setup(void *blob, bd_t *bd)
>  {
>         u64 base[CONFIG_NR_DRAM_BANKS];
> @@ -143,6 +204,9 @@ int ft_board_setup(void *blob, bd_t *bd)
>
>         fdt_fixup_memory_banks(blob, base, size, 2);
>
> +       setup_ecam_amq(blob);
> +       setup_ecam_cacheattr();
> +
>         return 0;
>  }
>  #endif

Not only programming the registers, but also I think we will need fix
up the <msi-map> property used by the "pci-host-ecam-generic", just
like what it was done in fdt_pcie_set_msi_map_entry() in
pcie_layerscape_fixup.c

Regards,
Bin


More information about the U-Boot mailing list