[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