[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