ls1028a: Configure stream IDs for integrated PCI and fix up Linux DT

Hardware comes out of reset with implicit values, but these are outside
the accepted range for Layerscape gen 3 chassis spec used on LS1028A.
Allocate different IDs and fix up Linux DT to use them.

Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Michael Walle <michael@walle.cc>
Reviewed-by: Priyanka Jain <priyanka.jain@nxp.com>
This commit is contained in:
Alex Marginean 2019-11-27 17:19:32 +02:00 committed by Priyanka Jain
parent c1ead04bc4
commit 3499dd033c
4 changed files with 119 additions and 0 deletions

View file

@ -1101,6 +1101,12 @@ static void config_core_prefetch(void)
}
}
#ifdef CONFIG_PCIE_ECAM_GENERIC
__weak void set_ecam_icids(void)
{
}
#endif
int arch_early_init_r(void)
{
#ifdef CONFIG_SYS_FSL_ERRATUM_A009635
@ -1152,6 +1158,9 @@ int arch_early_init_r(void)
#endif
#ifdef CONFIG_SYS_DPAA_QBMAN
setup_qbman_portals();
#endif
#ifdef CONFIG_PCIE_ECAM_GENERIC
set_ecam_icids();
#endif
return 0;
}

View file

@ -421,6 +421,12 @@ static void fdt_disable_multimedia(void *blob, unsigned int svr)
}
#endif
#ifdef CONFIG_PCIE_ECAM_GENERIC
__weak void fdt_fixup_ecam(void *blob)
{
}
#endif
void ft_cpu_setup(void *blob, bd_t *bd)
{
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
@ -485,4 +491,7 @@ void ft_cpu_setup(void *blob, bd_t *bd)
#ifdef CONFIG_ARCH_LS1028A
fdt_disable_multimedia(blob, svr);
#endif
#ifdef CONFIG_PCIE_ECAM_GENERIC
fdt_fixup_ecam(blob);
#endif
}

View file

@ -33,3 +33,96 @@ struct icid_id_table icid_tbl[] = {
};
int icid_tbl_sz = ARRAY_SIZE(icid_tbl);
/* integrated PCI is handled separately as it's not part of CCSR/SCFG */
#ifdef CONFIG_PCIE_ECAM_GENERIC
#define ECAM_IERB_BASE 0x1f0800000ULL
#define ECAM_IERB_OFFSET_NA -1
#define ECAM_IERB_FUNC_CNT ARRAY_SIZE(ierb_offset)
/* cache related transaction attributes for PCIe functions */
#define ECAM_IERB_MSICAR (ECAM_IERB_BASE + 0xa400)
#define ECAM_IERB_MSICAR_VALUE 0x30
/* offset of IERB config register per PCI function */
static int ierb_offset[] = {
0x0800,
0x1800,
0x2800,
0x3800,
0x4800,
0x5800,
0x6800,
ECAM_IERB_OFFSET_NA,
0x0804,
0x0808,
0x1804,
0x1808,
};
/*
* Use a custom function for LS1028A, for now this is the only SoC with IERB
* and we're currently considering reorganizing IERB for future SoCs.
*/
void set_ecam_icids(void)
{
int i;
out_le32(ECAM_IERB_MSICAR, ECAM_IERB_MSICAR_VALUE);
for (i = 0; i < ECAM_IERB_FUNC_CNT; i++) {
if (ierb_offset[i] == ECAM_IERB_OFFSET_NA)
continue;
out_le32(ECAM_IERB_BASE + ierb_offset[i],
FSL_ECAM_STREAM_ID_START + i);
}
}
static int fdt_setprop_inplace_idx_u32(void *fdt, int nodeoffset,
const char *name, uint32_t idx, u32 val)
{
val = cpu_to_be32(val);
return fdt_setprop_inplace_namelen_partial(fdt, nodeoffset, name,
strlen(name),
idx * sizeof(val), &val,
sizeof(val));
}
static int fdt_getprop_len(void *fdt, int nodeoffset, const char *name)
{
int len;
if (fdt_getprop_namelen(fdt, nodeoffset, name, strlen(name), &len))
return len;
return 0;
}
void fdt_fixup_ecam(void *blob)
{
int off;
off = fdt_node_offset_by_compatible(blob, 0, "pci-host-ecam-generic");
if (off < 0) {
debug("ECAM node not found\n");
return;
}
if (fdt_getprop_len(blob, off, "msi-map") != 16 ||
fdt_getprop_len(blob, off, "iommu-map") != 16) {
log_err("invalid msi/iommu-map propertly size in ECAM node\n");
return;
}
fdt_setprop_inplace_idx_u32(blob, off, "msi-map", 2,
FSL_ECAM_STREAM_ID_START);
fdt_setprop_inplace_idx_u32(blob, off, "msi-map", 3,
ECAM_IERB_FUNC_CNT);
fdt_setprop_inplace_idx_u32(blob, off, "iommu-map", 2,
FSL_ECAM_STREAM_ID_START);
fdt_setprop_inplace_idx_u32(blob, off, "iommu-map", 3,
ECAM_IERB_FUNC_CNT);
}
#endif /* CONFIG_PCIE_ECAM_GENERIC */

View file

@ -42,6 +42,10 @@
* -the MC is responsible for allocating and setting up 'isolation context
* IDs (ICIDs) based on the allocated stream IDs for all DPAA2 devices.
*
* - ECAM (integrated PCI)
* - U-Boot applies the value here to HW and does DT fix-up for both
* 'iommu-map' and 'msi-map'
*
* On Chasis-3 SoCs stream IDs are programmed in AMQ registers (32-bits) for
* each of the different bus masters. The relationship between
* the AMQ registers and stream IDs is defined in the table below:
@ -98,6 +102,10 @@
#define FSL_DPAA2_STREAM_ID_START 23
#define FSL_DPAA2_STREAM_ID_END 63
/* PCI IEPs, this overlaps DPAA2 but these two are exclusive at least for now */
#define FSL_ECAM_STREAM_ID_START 32
#define FSL_ECAM_STREAM_ID_END 63
#define FSL_SEC_STREAM_ID 64
#define FSL_SEC_JR1_STREAM_ID 65
#define FSL_SEC_JR2_STREAM_ID 66