u-boot/arch/arm/cpu/armv8/fsl-layerscape/icid.c
Tom Rini d678a59d2d Revert "Merge patch series "arm: dts: am62-beagleplay: Fix Beagleplay Ethernet""
When bringing in the series 'arm: dts: am62-beagleplay: Fix Beagleplay
Ethernet"' I failed to notice that b4 noticed it was based on next and
so took that as the base commit and merged that part of next to master.

This reverts commit c8ffd1356d, reversing
changes made to 2ee6f3a5f7.

Reported-by: Jonas Karlman <jonas@kwiboo.se>
Signed-off-by: Tom Rini <trini@konsulko.com>
2024-05-19 08:16:36 -06:00

194 lines
4 KiB
C

// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2018 NXP
*/
#include <common.h>
#include <linux/libfdt.h>
#include <fdt_support.h>
#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++)
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);
}
#if defined(CONFIG_SYS_DPAA_FMAN) && !defined(CONFIG_SPL_BUILD)
static void set_fman_icids(struct fman_icid_id_table *tbl, int size)
{
int i;
ccsr_fman_t *fm = (void *)CFG_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);
#if defined(CONFIG_SYS_DPAA_FMAN) && !defined(CONFIG_SPL_BUILD)
set_fman_icids(fman_icid_tbl, fman_icid_tbl_sz);
#endif
}
#ifndef CONFIG_SPL_BUILD
int fdt_set_iommu_prop(void *blob, int off, int smmu_ph, u32 *ids, int num_ids)
{
int i, ret;
u32 prop[8];
/*
* Note: The "iommus" property definition mentions Stream IDs while
* this code handles ICIDs. The current implementation assumes that
* ICIDs and Stream IDs are equal.
*/
for (i = 0; i < num_ids; i++) {
prop[i * 2] = cpu_to_fdt32(smmu_ph);
prop[i * 2 + 1] = cpu_to_fdt32(ids[i]);
}
ret = fdt_setprop(blob, off, "iommus",
prop, sizeof(u32) * num_ids * 2);
if (ret) {
printf("WARNING unable to set iommus: %s\n", fdt_strerror(ret));
return ret;
}
return 0;
}
static int fdt_fixup_icid_tbl(void *blob, int smmu_ph,
struct icid_id_table *tbl, int size)
{
int i, err, off;
for (i = 0; i < size; i++) {
if (!tbl[i].compat)
continue;
off = fdt_node_offset_by_compat_reg(blob,
tbl[i].compat,
tbl[i].compat_addr);
if (off > 0) {
err = fdt_set_iommu_prop(blob, off, smmu_ph,
&tbl[i].id, 1);
if (err)
return err;
} else {
printf("WARNING could not find node %s: %s.\n",
tbl[i].compat, fdt_strerror(off));
}
}
return 0;
}
#ifdef CONFIG_SYS_DPAA_FMAN
static 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;
}
static void fdt_fixup_fman_port_icid_by_compat(void *blob, int smmu_ph,
const char *compat)
{
int noff, len, icid;
const u32 *prop;
fdt_for_each_node_by_compatible(noff, blob, -1, compat) {
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);
}
}
static 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;
noff = fdt_node_offset_by_compatible(blob, -1, "arm,mmu-500");
if (noff < 0) {
printf("WARNING failed to get smmu node: %s\n",
fdt_strerror(noff));
return noff;
}
smmu_ph = fdt_get_phandle(blob, noff);
if (!smmu_ph) {
smmu_ph = fdt_create_phandle(blob, noff);
if (!smmu_ph) {
printf("WARNING failed to get smmu phandle\n");
return -1;
}
}
return smmu_ph;
}
void fdt_fixup_icid(void *blob)
{
int smmu_ph;
smmu_ph = fdt_get_smmu_phandle(blob);
if (smmu_ph < 0)
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
}
#endif