mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-11 07:34:31 +00:00
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:
parent
c1ead04bc4
commit
3499dd033c
4 changed files with 119 additions and 0 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue