[U-Boot] [PATCH] ls1028a: Configure stream IDs for integrated PCI and fix up Linux DT
Alexandru Marginean
alexm.osslist at gmail.com
Wed Nov 27 14:47:37 UTC 2019
Hi Michael,
On 11/27/2019 3:33 PM, Michael Walle wrote:
> Hi Alex,
>
> Am 2019-11-27 14:57, schrieb Alex Marginean:
>> 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 at nxp.com>
>> ---
>> arch/arm/cpu/armv8/fsl-layerscape/fdt.c | 9 ++
>> .../asm/arch-fsl-layerscape/stream_id_lsch3.h | 8 ++
>> board/freescale/ls1028a/ls1028a.c | 106 ++++++++++++++++++
>
> Doh :( is there no other place where to put this fixup? That would mean I
> have to replicate this code for our custom board and so does every board
> which uses the LS1028A. Shouldn't this be in the SoC LS1028A architecture
> specific code?
Yeah, you're right about that.
It should probably go into armv8/fsl-layerscape/icid.c or somewhere
around there.
I'll send a v2.
Thanks!
Alex
>
>> 3 files changed, 123 insertions(+)
>>
>> diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
>> b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
>> index e993209593..1e7e46e88a 100644
>> --- a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
>> +++ b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
>> @@ -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
>> }
>> diff --git
>> a/arch/arm/include/asm/arch-fsl-layerscape/stream_id_lsch3.h
>> b/arch/arm/include/asm/arch-fsl-layerscape/stream_id_lsch3.h
>> index 94ea99a349..01d362d183 100644
>> --- a/arch/arm/include/asm/arch-fsl-layerscape/stream_id_lsch3.h
>> +++ b/arch/arm/include/asm/arch-fsl-layerscape/stream_id_lsch3.h
>> @@ -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'
>> + *
>
> mhh this is not entirely true, because it is the board code which
> does the fixup, which may lead to some confusion. >
>> * 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
>> diff --git a/board/freescale/ls1028a/ls1028a.c
>> b/board/freescale/ls1028a/ls1028a.c
>> index a9606b8865..1f5dc0d0b2 100644
>> --- a/board/freescale/ls1028a/ls1028a.c
>> +++ b/board/freescale/ls1028a/ls1028a.c
>> @@ -28,6 +28,52 @@
>>
>> DECLARE_GLOBAL_DATA_PTR;
>>
>> +#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.
>> + */
>> +static 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);
>> + }
>> +}
>> +
>> +#endif /* CONFIG_PCIE_ECAM_GENERIC */
>> +
>> int config_board_mux(void)
>> {
>> #if defined(CONFIG_TARGET_LS1028AQDS) && defined(CONFIG_FSL_QIXIS)
>> @@ -88,6 +134,16 @@ int board_init(void)
>> #endif
>>
>> #endif
>> +
>> + /*
>> + * ICIDs for other hardware blocks are set really early on,
>> before MMU
>> + * is set up. For integrated PCI we need access to IERB which is
>> not
>> + * part of CCSR, so we have to wait for MMU mappings to be applied
>> + */
>> +#ifdef CONFIG_PCIE_ECAM_GENERIC
>> + set_ecam_icids();
>> +#endif
>> +
>> return 0;
>> }
>>
>> @@ -244,3 +300,53 @@ int checkboard(void)
>> return 0;
>> }
>> #endif
>> +
>> +#ifdef CONFIG_PCIE_ECAM_GENERIC
>> +
>> +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 */
>
> -michael
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> https://lists.denx.de/listinfo/u-boot
More information about the U-Boot
mailing list