[U-Boot] [PATCH v1 1/2] drivers/misc: Share qbman init between archs
York Sun
york.sun at nxp.com
Thu Dec 7 23:08:58 UTC 2017
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 at 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 at 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 at 0", FSL_HW_PORTAL_PME, 1);
> + if (err < 0)
> + goto err;
> +#else
> + fdt_qportal(blob, off, i, "pme at 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 at 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 at 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
More information about the U-Boot
mailing list