
On 12/07/2017 02:53 PM, Ahmed Mansour wrote:
This patch adds changes necessary to move functionality present in PowerPC folders with ARM architectures that have DPAA1 QBMan hardware
- Created new board/freescale/common/portals.c to house shared device tree fixups for DPAA1 devices with ARM and PowerPC cores
- Added new header file to top includes directory to allow files in both architectures to grab the function prototypes
- Port inhibit_portals() from PowerPC to ARM. This function is used in setup to disable interrupts on all QMan and BMan portals. It is needed because the interrupts are enabled by default for all portals including unused/uninitialised portals. When the kernel attempts to go to deep sleep the unused portals prevent it from doing so
Signed-off-by: Ahmed Mansour ahmed.mansour@nxp.com
arch/arm/cpu/armv8/fsl-layerscape/cpu.c | 4 + arch/arm/cpu/armv8/fsl-layerscape/fdt.c | 15 + .../arm/cpu/armv8/fsl-layerscape/fsl_lsch2_speed.c | 3 + .../include/asm/arch-fsl-layerscape/immap_lsch2.h | 29 ++ arch/powerpc/cpu/mpc85xx/cpu_init.c | 3 +- arch/powerpc/cpu/mpc85xx/fdt.c | 1 + arch/powerpc/cpu/mpc85xx/portals.c | 281 ------------------- arch/powerpc/include/asm/fsl_liodn.h | 7 +- arch/powerpc/include/asm/fsl_portals.h | 4 - arch/powerpc/include/asm/immap_85xx.h | 60 ---- drivers/misc/Makefile | 1 + drivers/misc/portals.c | 312 +++++++++++++++++++++ include/configs/ls1043a_common.h | 2 + include/fsl_qbman.h | 75 +++++ 14 files changed, 449 insertions(+), 348 deletions(-) create mode 100644 drivers/misc/portals.c create mode 100644 include/fsl_qbman.h
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c index ab5d76e..e67f489 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c @@ -29,6 +29,7 @@ #include <fsl_ddr.h> #endif #include <asm/arch/clock.h> +#include <fsl_qbman.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -527,6 +528,9 @@ int arch_early_init_r(void) #ifdef CONFIG_FMAN_ENET fman_enet_init(); #endif +#ifdef CONFIG_SYS_DPAA_QBMAN
- setup_qbman_portals();
+#endif return 0; }
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c index cae59da..ba8b9e0 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c @@ -26,6 +26,8 @@ #ifdef CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT #include <asm/armv8/sec_firmware.h> #endif +#include <asm/arch/speed.h> +#include <fsl_qbman.h>
int fdt_fixup_phy_connection(void *blob, int offset, phy_interface_t phyc) { @@ -395,6 +397,12 @@ void ft_cpu_setup(void *blob, bd_t *bd) } #endif
+#ifdef CONFIG_SYS_DPAA_QBMAN
- struct sys_info sysinfo;
- get_sys_info(&sysinfo);
I would prefer to add a new function to fsl_lsch3_speed.c to return freq_qman.
+#endif
#ifdef CONFIG_MP ft_fixup_cpu(blob); #endif @@ -415,6 +423,13 @@ void ft_cpu_setup(void *blob, bd_t *bd) fdt_fixup_esdhc(blob, bd); #endif
+#ifdef CONFIG_SYS_DPAA_QBMAN
- fdt_fixup_bportals(blob);
- fdt_fixup_qportals(blob);
- do_fixup_by_compat_u32(blob, "fsl,qman",
"clock-frequency", sysinfo.freq_qman, 1);
+#endif
#ifdef CONFIG_SYS_DPAA_FMAN fdt_fixup_fman_firmware(blob); #endif diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_speed.c b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_speed.c index 2d7775e..eaab948 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_speed.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_speed.c @@ -155,6 +155,9 @@ void get_sys_info(struct sys_info *sys_info) sys_info->freq_localbus = sys_info->freq_systembus / CONFIG_SYS_FSL_IFC_CLK_DIV; #endif +#ifdef CONFIG_SYS_DPAA_QBMAN
- sys_info->freq_qman = sys_info->freq_systembus;
+#endif }
int get_clocks(void)
<snip>
diff --git a/drivers/misc/portals.c b/drivers/misc/portals.c new file mode 100644 index 0000000..5974962 --- /dev/null +++ b/drivers/misc/portals.c @@ -0,0 +1,312 @@ +/*
- Copyright 2008-2011 Freescale Semiconductor, Inc.
- Copyright 2016 NXP
Please update copyright year
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <libfdt.h> +#include <fdt_support.h>
+#include <asm/processor.h> +#include <asm/io.h> +#ifndef CONFIG_ARM +#include <asm/fsl_portals.h> +#include <asm/fsl_liodn.h> +#endif +#include <fsl_qbman.h>
+#define MAX_BPORTALS (CONFIG_SYS_BMAN_CINH_SIZE / CONFIG_SYS_BMAN_SP_CINH_SIZE) +#define MAX_QPORTALS (CONFIG_SYS_QMAN_CINH_SIZE / CONFIG_SYS_QMAN_SP_CINH_SIZE) +void setup_qbman_portals(void) +{
- void __iomem *bpaddr = (void *)CONFIG_SYS_BMAN_CINH_BASE +
CONFIG_SYS_BMAN_SWP_ISDR_REG;
- void __iomem *qpaddr = (void *)CONFIG_SYS_QMAN_CINH_BASE +
CONFIG_SYS_QMAN_SWP_ISDR_REG;
+#ifndef CONFIG_ARM
Wouldn't it be better to use another config option more specific to QMAN? There is no guaranteed connection between !ARM and QMAN.
- struct ccsr_qman *qman = (void *)CONFIG_SYS_FSL_QMAN_ADDR;
- /* Set the Qman initiator BAR to match the LAW (for DQRR stashing) */
+#ifdef CONFIG_PHYS_64BIT
- out_be32(&qman->qcsp_bare, (u32)(CONFIG_SYS_QMAN_MEM_PHYS >> 32));
+#endif
- out_be32(&qman->qcsp_bar, (u32)CONFIG_SYS_QMAN_MEM_PHYS);
+#endif +#ifdef CONFIG_FSL_CORENET
- int i;
- for (i = 0; i < CONFIG_SYS_QMAN_NUM_PORTALS; i++) {
u8 sdest = qp_info[i].sdest;
u16 fliodn = qp_info[i].fliodn;
u16 dliodn = qp_info[i].dliodn;
u16 liodn_off = qp_info[i].liodn_offset;
out_be32(&qman->qcsp[i].qcsp_lio_cfg, (liodn_off << 16) |
dliodn);
/* set frame liodn */
out_be32(&qman->qcsp[i].qcsp_io_cfg, (sdest << 16) | fliodn);
- }
+#endif
- /* Change default state of BMan ISDR portals to all 1s */
- inhibit_portals(bpaddr, CONFIG_SYS_BMAN_NUM_PORTALS, MAX_BPORTALS,
CONFIG_SYS_BMAN_SP_CINH_SIZE);
- inhibit_portals(qpaddr, CONFIG_SYS_QMAN_NUM_PORTALS, MAX_QPORTALS,
CONFIG_SYS_QMAN_SP_CINH_SIZE);
+}
+void inhibit_portals(void __iomem *addr, int max_portals,
int arch_max_portals, int portal_cinh_size)
+{
- u32 val;
- int i;
- /* arch_max_portals is the maximum based on memory size. This includes
* the reserved memory in the SoC. max_portals the number of physical
* portals in the SoC
*/
- if (max_portals > arch_max_portals) {
printf("ERROR: portal config error\n");
max_portals = arch_max_portals;
- }
- for (i = 0; i < max_portals; i++) {
out_be32(addr, -1);
val = in_be32(addr);
if (!val) {
printf("ERROR: Stopped after %d portals\n", i);
goto done;
}
addr += portal_cinh_size;
- }
+#ifdef DEBUG
- printf("Cleared %d portals\n", i);
Use debug().
+#endif +done: +}
+#ifndef CONFIG_ARM
Same here and many places below.
+static int fdt_qportal(void *blob, int off, int id, char *name,
enum fsl_dpaa_dev dev, int create)
+{
- int childoff, dev_off, ret = 0;
- u32 dev_handle;
+#ifdef CONFIG_FSL_CORENET
- int num;
- u32 liodns[2];
+#endif
- childoff = fdt_subnode_offset(blob, off, name);
- if (create) {
char handle[64], *p;
strncpy(handle, name, sizeof(handle));
p = strchr(handle, '@');
if (!strncmp(name, "fman", 4)) {
*p = *(p + 1);
p++;
}
*p = '\0';
dev_off = fdt_path_offset(blob, handle);
/* skip this node if alias is not found */
if (dev_off == -FDT_ERR_BADPATH)
return 0;
if (dev_off < 0)
return dev_off;
if (childoff <= 0)
childoff = fdt_add_subnode(blob, off, name);
/* need to update the dev_off after adding a subnode */
dev_off = fdt_path_offset(blob, handle);
if (dev_off < 0)
return dev_off;
if (childoff > 0) {
dev_handle = fdt_get_phandle(blob, dev_off);
if (dev_handle <= 0) {
dev_handle = fdt_alloc_phandle(blob);
ret = fdt_set_phandle(blob, dev_off,
dev_handle);
if (ret < 0)
return ret;
}
ret = fdt_setprop(blob, childoff, "dev-handle",
&dev_handle, sizeof(dev_handle));
if (ret < 0)
return ret;
+#ifdef CONFIG_FSL_CORENET
num = get_dpaa_liodn(dev, &liodns[0], id);
ret = fdt_setprop(blob, childoff, "fsl,liodn",
&liodns[0], sizeof(u32) * num);
if (!strncmp(name, "pme", 3)) {
u32 pme_rev1, pme_rev2;
ccsr_pme_t *pme_regs =
(void *)CONFIG_SYS_FSL_CORENET_PME_ADDR;
pme_rev1 = in_be32(&pme_regs->pm_ip_rev_1);
pme_rev2 = in_be32(&pme_regs->pm_ip_rev_2);
ret = fdt_setprop(blob, childoff,
"fsl,pme-rev1", &pme_rev1,
sizeof(u32));
if (ret < 0)
return ret;
ret = fdt_setprop(blob, childoff,
"fsl,pme-rev2", &pme_rev2,
sizeof(u32));
}
+#endif
} else {
return childoff;
}
- } else {
if (childoff > 0)
ret = fdt_del_node(blob, childoff);
- }
- return ret;
+} +#endif /* CONFIG_ARM */
+#ifdef CONFIG_SYS_DPAA_QBMAN
+void fdt_fixup_qportals(void *blob) +{
- int off, err;
- unsigned int maj, min;
- unsigned int ip_cfg;
- struct ccsr_qman *qman = (void *)CONFIG_SYS_FSL_QMAN_ADDR;
- u32 rev_1 = in_be32(&qman->ip_rev_1);
- u32 rev_2 = in_be32(&qman->ip_rev_2);
- char compat[64];
- int compat_len;
- maj = (rev_1 >> 8) & 0xff;
- min = rev_1 & 0xff;
- ip_cfg = rev_2 & 0xff;
- compat_len = sprintf(compat, "fsl,qman-portal-%u.%u.%u",
maj, min, ip_cfg) + 1;
- compat_len += sprintf(compat + compat_len, "fsl,qman-portal") + 1;
- off = fdt_node_offset_by_compatible(blob, -1, "fsl,qman-portal");
- while (off != -FDT_ERR_NOTFOUND) {
+#ifndef CONFIG_ARM +#ifdef CONFIG_FSL_CORENET
u32 liodns[2];
+#endif
const int *ci = fdt_getprop(blob, off, "cell-index", &err);
int i;
if (!ci)
goto err;
i = *ci;
+#ifdef CONFIG_SYS_DPAA_FMAN
int j;
+#endif
+#endif /* CONFIG_ARM */
err = fdt_setprop(blob, off, "compatible", compat, compat_len);
if (err < 0)
goto err;
+#ifndef CONFIG_ARM +#ifdef CONFIG_FSL_CORENET
liodns[0] = qp_info[i].dliodn;
liodns[1] = qp_info[i].fliodn;
err = fdt_setprop(blob, off, "fsl,liodn",
&liodns, sizeof(u32) * 2);
if (err < 0)
goto err;
+#endif
i++;
err = fdt_qportal(blob, off, i, "crypto@0", FSL_HW_PORTAL_SEC,
IS_E_PROCESSOR(get_svr()));
if (err < 0)
goto err;
+#ifdef CONFIG_FSL_CORENET +#ifdef CONFIG_SYS_DPAA_PME
err = fdt_qportal(blob, off, i, "pme@0", FSL_HW_PORTAL_PME, 1);
if (err < 0)
goto err;
+#else
fdt_qportal(blob, off, i, "pme@0", FSL_HW_PORTAL_PME, 0);
+#endif +#endif
+#ifdef CONFIG_SYS_DPAA_FMAN
for (j = 0; j < CONFIG_SYS_NUM_FMAN; j++) {
char name[] = "fman@0";
name[sizeof(name) - 2] = '0' + j;
err = fdt_qportal(blob, off, i, name,
FSL_HW_PORTAL_FMAN1 + j, 1);
if (err < 0)
goto err;
}
+#endif +#ifdef CONFIG_SYS_DPAA_RMAN
err = fdt_qportal(blob, off, i, "rman@0",
FSL_HW_PORTAL_RMAN, 1);
if (err < 0)
goto err;
+#endif +#endif /* CONFIG_ARM */
+err:
if (err < 0) {
printf("ERROR: unable to create props for %s: %s\n",
fdt_get_name(blob, off, NULL),
fdt_strerror(err));
return;
}
off = fdt_node_offset_by_compatible(blob, off,
"fsl,qman-portal");
- }
+}
+void fdt_fixup_bportals(void *blob) +{
- int off, err;
- unsigned int maj, min;
- unsigned int ip_cfg;
- struct ccsr_bman *bman = (void *)CONFIG_SYS_FSL_BMAN_ADDR;
- u32 rev_1 = in_be32(&bman->ip_rev_1);
- u32 rev_2 = in_be32(&bman->ip_rev_2);
- char compat[64];
- int compat_len;
- maj = (rev_1 >> 8) & 0xff;
- min = rev_1 & 0xff;
- ip_cfg = rev_2 & 0xff;
- compat_len = sprintf(compat, "fsl,bman-portal-%u.%u.%u",
maj, min, ip_cfg) + 1;
- compat_len += sprintf(compat + compat_len, "fsl,bman-portal") + 1;
- off = fdt_node_offset_by_compatible(blob, -1, "fsl,bman-portal");
- while (off != -FDT_ERR_NOTFOUND) {
err = fdt_setprop(blob, off, "compatible", compat, compat_len);
if (err < 0) {
printf("ERROR: unable to create props for %s: %s\n",
fdt_get_name(blob, off, NULL),
fdt_strerror(err));
return;
}
off = fdt_node_offset_by_compatible(blob, off,
"fsl,bman-portal");
- }
+}
+#endif /* CONFIG_SYS_DPAA_QBMAN */ diff --git a/include/configs/ls1043a_common.h b/include/configs/ls1043a_common.h index a4cd09a..f4c2447 100644 --- a/include/configs/ls1043a_common.h +++ b/include/configs/ls1043a_common.h @@ -194,6 +194,8 @@ #endif #endif
+#define CONFIG_SYS_DPAA_QBMAN /* Support Q/Bman */
/* FMan ucode */ #ifndef SPL_NO_FMAN #define CONFIG_SYS_DPAA_FMAN diff --git a/include/fsl_qbman.h b/include/fsl_qbman.h new file mode 100644 index 0000000..9449836 --- /dev/null +++ b/include/fsl_qbman.h @@ -0,0 +1,75 @@ +/*
- Copyright 2016 NXP
Please update copyright year.
York