Merge branch 'master' of https://gitlab.denx.de/u-boot/custodians/u-boot-spi
[oweals/u-boot.git] / arch / arm / cpu / armv8 / fsl-layerscape / icid.c
index ae3b8daa9564b720c82ad8ffddd76028d987b0d5..82c5a8b123a12125b1bfcfa9bc5faabcf8aa6c39 100644 (file)
 #include <asm/io.h>
 #include <asm/processor.h>
 #include <asm/arch-fsl-layerscape/fsl_icid.h>
+#include <fsl_fman.h>
 
 static void set_icid(struct icid_id_table *tbl, int size)
 {
        int i;
 
        for (i = 0; i < size; i++)
-               out_be32((u32 *)(tbl[i].reg_addr), tbl[i].reg);
+               if (tbl[i].le)
+                       out_le32((u32 *)(tbl[i].reg_addr), tbl[i].reg);
+               else
+                       out_be32((u32 *)(tbl[i].reg_addr), tbl[i].reg);
 }
 
+#ifdef CONFIG_SYS_DPAA_FMAN
+void set_fman_icids(struct fman_icid_id_table *tbl, int size)
+{
+       int i;
+       ccsr_fman_t *fm = (void *)CONFIG_SYS_FSL_FM1_ADDR;
+
+       for (i = 0; i < size; i++) {
+               out_be32(&fm->fm_bmi_common.fmbm_ppid[tbl[i].port_id - 1],
+                        tbl[i].icid);
+       }
+}
+#endif
+
 void set_icids(void)
 {
        /* setup general icid offsets */
        set_icid(icid_tbl, icid_tbl_sz);
+
+#ifdef CONFIG_SYS_DPAA_FMAN
+       set_fman_icids(fman_icid_tbl, fman_icid_tbl_sz);
+#endif
 }
 
 int fdt_set_iommu_prop(void *blob, int off, int smmu_ph, u32 *ids, int num_ids)
@@ -75,6 +96,66 @@ int fdt_fixup_icid_tbl(void *blob, int smmu_ph,
        return 0;
 }
 
+#ifdef CONFIG_SYS_DPAA_FMAN
+int get_fman_port_icid(int port_id, struct fman_icid_id_table *tbl,
+                      const int size)
+{
+       int i;
+
+       for (i = 0; i < size; i++) {
+               if (tbl[i].port_id == port_id)
+                       return tbl[i].icid;
+       }
+
+       return -1;
+}
+
+void fdt_fixup_fman_port_icid_by_compat(void *blob, int smmu_ph,
+                                       const char *compat)
+{
+       int noff, len, icid;
+       const u32 *prop;
+
+       noff = fdt_node_offset_by_compatible(blob, -1, compat);
+       while (noff > 0) {
+               prop = fdt_getprop(blob, noff, "cell-index", &len);
+               if (!prop) {
+                       printf("WARNING missing cell-index for fman port\n");
+                       continue;
+               }
+               if (len != 4) {
+                       printf("WARNING bad cell-index size for fman port\n");
+                       continue;
+               }
+
+               icid = get_fman_port_icid(fdt32_to_cpu(*prop),
+                                         fman_icid_tbl, fman_icid_tbl_sz);
+               if (icid < 0) {
+                       printf("WARNING unknown ICID for fman port %d\n",
+                              *prop);
+                       continue;
+               }
+
+               fdt_set_iommu_prop(blob, noff, smmu_ph, (u32 *)&icid, 1);
+
+               noff = fdt_node_offset_by_compatible(blob, noff, compat);
+       }
+}
+
+void fdt_fixup_fman_icids(void *blob, int smmu_ph)
+{
+       static const char * const compats[] = {
+               "fsl,fman-v3-port-oh",
+               "fsl,fman-v3-port-rx",
+               "fsl,fman-v3-port-tx",
+       };
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(compats); i++)
+               fdt_fixup_fman_port_icid_by_compat(blob, smmu_ph, compats[i]);
+}
+#endif
+
 int fdt_get_smmu_phandle(void *blob)
 {
        int noff, smmu_ph;
@@ -107,4 +188,8 @@ void fdt_fixup_icid(void *blob)
                return;
 
        fdt_fixup_icid_tbl(blob, smmu_ph, icid_tbl, icid_tbl_sz);
+
+#ifdef CONFIG_SYS_DPAA_FMAN
+       fdt_fixup_fman_icids(blob, smmu_ph);
+#endif
 }