Hi Peng, Some minor questions/remarks below.
On 2016-01-04 21:56, Peng Fan wrote: > From: Peng Fan <peng....@nxp.com> > > Introduce Resource Domain Controller support for i.MX. > Now i.MX6SX and i.MX7D supports this feature to assign masters > and peripherals to different domains. > > Signed-off-by: Ye.Li <ye...@nxp.com> > Signed-off-by: Peng Fan <peng....@nxp.com> > --- > arch/arm/imx-common/Kconfig | 8 ++ > arch/arm/imx-common/Makefile | 1 + > arch/arm/imx-common/rdc-sema.c | 184 > +++++++++++++++++++++++++++++ > arch/arm/include/asm/arch-mx6/imx-rdc.h | 12 ++ > arch/arm/include/asm/imx-common/rdc-sema.h | 117 ++++++++++++++++++ > 5 files changed, 322 insertions(+) > create mode 100644 arch/arm/imx-common/rdc-sema.c > create mode 100644 arch/arm/include/asm/arch-mx6/imx-rdc.h > create mode 100644 arch/arm/include/asm/imx-common/rdc-sema.h > > diff --git a/arch/arm/imx-common/Kconfig b/arch/arm/imx-common/Kconfig > index 2296239..c4f48bb 100644 > --- a/arch/arm/imx-common/Kconfig > +++ b/arch/arm/imx-common/Kconfig > @@ -3,3 +3,11 @@ config IMX_CONFIG > > config ROM_UNIFIED_SECTIONS > bool > + > +config IMX_RDC > + bool "i.MX Resource domain controller driver" > + depends on ARCH_MX6 || ARCH_MX7 > + help > + i.MX Resource domain controller is used to assign masters > + and peripherals to differet domains. This can be used to > + isolate resources. > diff --git a/arch/arm/imx-common/Makefile b/arch/arm/imx-common/Makefile > index e7190c3..568f41c 100644 > --- a/arch/arm/imx-common/Makefile > +++ b/arch/arm/imx-common/Makefile > @@ -27,6 +27,7 @@ ifeq ($(SOC),$(filter $(SOC),mx6 mx7)) > obj-y += cache.o init.o > obj-$(CONFIG_CMD_SATA) += sata.o > obj-$(CONFIG_IMX_VIDEO_SKIP) += video.o > +obj-$(CONFIG_IMX_RDC) += rdc-sema.o > obj-$(CONFIG_SECURE_BOOT) += hab.o > endif > ifeq ($(SOC),$(filter $(SOC),vf610)) > diff --git a/arch/arm/imx-common/rdc-sema.c b/arch/arm/imx-common/rdc-sema.c > new file mode 100644 > index 0000000..7db1ec5 > --- /dev/null > +++ b/arch/arm/imx-common/rdc-sema.c > @@ -0,0 +1,184 @@ > +/* > + * Copyright (C) 2016 Freescale Semiconductor, Inc. > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > +#include <common.h> > +#include <asm/io.h> > +#include <asm/arch/imx-regs.h> > +#include <asm/imx-common/rdc-sema.h> > +#include <asm/arch/imx-rdc.h> > +#include <asm-generic/errno.h> > + > +/* > + * Check if the RDC Semaphore is required for this peripheral. > + */ > +static inline int imx_rdc_check_sema_required(int per_id) > +{ > + struct rdc_regs *imx_rdc = (struct rdc_regs *)RDC_BASE_ADDR; > + u32 reg; > + > + reg = readl(&imx_rdc->pdap[per_id]); > + /* > + * No semaphore: > + * Intial value or this peripheral is assigned to only one domain > + */ > + if (!(reg & RDC_PDAP_SREQ_MASK)) > + return -ENOENT; > + > + return 0; > +} > + > +/* > + * Check the peripheral read / write access permission on Domain 0. > + * (Always assume the main CPU is in Domain 0) Hence you assuming that U-Boot is also always running on main CPU right? I guess this is ok for now. > + */ > +int imx_rdc_check_permission(int per_id) > +{ > + struct rdc_regs *imx_rdc = (struct rdc_regs *)RDC_BASE_ADDR; > + u32 reg; > + > + reg = readl(&imx_rdc->pdap[per_id]); > + if (!(reg & (RDC_PDAP_D0W_MASK | RDC_PDAP_D0R_MASK))) > + return -EACCES; /*No access*/ > + > + return 0; > +} > + > +/* > + * Lock up the RDC semaphore for this peripheral if semaphore is required. > + */ > +int imx_rdc_sema_lock(int per_id) > +{ > + struct rdc_sema_regs *imx_rdc_sema; > + int ret; > + u8 reg; > + > + ret = imx_rdc_check_sema_required(per_id); > + if (ret) > + return ret; > + > + if (per_id < SEMA_GATES_NUM) > + imx_rdc_sema = (struct rdc_sema_regs *)SEMAPHORE1_BASE_ADDR; > + else > + imx_rdc_sema = (struct rdc_sema_regs *)SEMAPHORE2_BASE_ADDR; > + > + do { > + writeb(RDC_SEMA_PROC_ID, > + &imx_rdc_sema->gate[per_id % SEMA_GATES_NUM]); > + reg = readb(&imx_rdc_sema->gate[per_id % SEMA_GATES_NUM]); > + if ((reg & RDC_SEMA_GATE_GTFSM_MASK) == RDC_SEMA_PROC_ID) > + break; /* Get the Semaphore*/ > + } while (1); > + > + return 0; > +} > + > +/* > + * Unlock the RDC semaphore for this peripheral if main CPU is the > + * semaphore owner. > + */ > +int imx_rdc_sema_unlock(int per_id) > +{ > + struct rdc_sema_regs *imx_rdc_sema; > + int ret; > + u8 reg; > + > + ret = imx_rdc_check_sema_required(per_id); > + if (ret) > + return ret; > + > + if (per_id < SEMA_GATES_NUM) > + imx_rdc_sema = (struct rdc_sema_regs *)SEMAPHORE1_BASE_ADDR; > + else > + imx_rdc_sema = (struct rdc_sema_regs *)SEMAPHORE2_BASE_ADDR; > + > + reg = readb(&imx_rdc_sema->gate[per_id % SEMA_GATES_NUM]); > + if ((reg & RDC_SEMA_GATE_GTFSM_MASK) != RDC_SEMA_PROC_ID) > + return 1; /*Not the semaphore owner */ > + > + writeb(0x0, &imx_rdc_sema->gate[per_id % SEMA_GATES_NUM]); > + > + return 0; > +} > + > +/* > + * Setup RDC setting for one peripheral > + */ > +int imx_rdc_setup_peri(rdc_peri_cfg_t p) > +{ > + struct rdc_regs *imx_rdc = (struct rdc_regs *)RDC_BASE_ADDR; > + u32 reg = 0; > + u32 share_count = 0; > + u32 peri_id = p & RDC_PERI_MASK; > + u32 domain = (p & RDC_DOMAIN_MASK) >> RDC_DOMAIN_SHIFT_BASE; > + > + /* No domain assigned */ > + if (domain == 0) > + return -EINVAL; > + > + reg |= domain; > + > + share_count = (domain & 0x3) > + + ((domain >> 2) & 0x3) > + + ((domain >> 4) & 0x3) > + + ((domain >> 6) & 0x3); > + > + if (share_count > 0x3) > + reg |= RDC_PDAP_SREQ_MASK; > + > + writel(reg, &imx_rdc->pdap[peri_id]); > + > + return 0; > +} > + > +/* > + * Setup RDC settings for multiple peripherals > + */ > +int imx_rdc_setup_peripherals(rdc_peri_cfg_t const *peripherals_list, > + unsigned count) > +{ > + rdc_peri_cfg_t const *p = peripherals_list; > + int i, ret; > + > + for (i = 0; i < count; i++) { > + ret = imx_rdc_setup_peri(*p); > + if (ret) > + return ret; > + p++; > + } > + > + return 0; > +} > + > +/* > + * Setup RDC setting for one master > + */ > +int imx_rdc_setup_ma(rdc_ma_cfg_t p) > +{ > + struct rdc_regs *imx_rdc = (struct rdc_regs *)RDC_BASE_ADDR; > + u32 master_id = (p & RDC_MASTER_MASK) >> RDC_MASTER_SHIFT; > + u32 domain = (p & RDC_DOMAIN_MASK) >> RDC_DOMAIN_SHIFT_BASE; > + > + writel((domain & RDC_MDA_DID_MASK), &imx_rdc->mda[master_id]); > + > + return 0; > +} > + > +/* > + * Setup RDC settings for multiple masters > + */ > +int imx_rdc_setup_masters(rdc_ma_cfg_t const *masters_list, unsigned count) > +{ > + rdc_ma_cfg_t const *p = masters_list; > + int i, ret; > + > + for (i = 0; i < count; i++) { > + ret = imx_rdc_setup_ma(*p); > + if (ret) > + return ret; > + p++; > + } > + > + return 0; > +} > diff --git a/arch/arm/include/asm/arch-mx6/imx-rdc.h > b/arch/arm/include/asm/arch-mx6/imx-rdc.h > new file mode 100644 > index 0000000..5754f04 > --- /dev/null > +++ b/arch/arm/include/asm/arch-mx6/imx-rdc.h > @@ -0,0 +1,12 @@ > +/* > + * Copyright (C) 2016 Freescale Semiconductor, Inc. > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +#ifndef __IMX_RDC_H__ > +#define __IMX_RDC_H__ > + > +#error "Please select cpu" I don't understand this, wouldn't lead this always to an error? > + > +#endif /* __IMX_RDC_H__*/ > diff --git a/arch/arm/include/asm/imx-common/rdc-sema.h > b/arch/arm/include/asm/imx-common/rdc-sema.h > new file mode 100644 > index 0000000..4470709 > --- /dev/null > +++ b/arch/arm/include/asm/imx-common/rdc-sema.h > @@ -0,0 +1,117 @@ > +/* > + * Copyright (C) 2016 Freescale Semiconductor, Inc. > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +#ifndef __RDC_SEMA_H__ > +#define __RDC_SEMA_H__ > + > +/* > + * [ 23 22 | 21 20 | 19 18 | 17 16 ] | [ 15 - 8 ] | [ 7 - 0 ] > + * d3 d2 d1 d0 | master id | peri id > + * d[x] means domain[x], x can be [3 - 0]. > + */ > +typedef u32 rdc_peri_cfg_t; > +typedef u32 rdc_ma_cfg_t; > + > +#define RDC_PERI_SHIFT 0 > +#define RDC_PERI_MASK 0xFF > + > +#define RDC_DOMAIN_SHIFT_BASE 16 > +#define RDC_DOMAIN_MASK 0xFF0000 > +#define RDC_DOMAIN_SHIFT(x) (RDC_DOMAIN_SHIFT_BASE + ((x << 1))) > +#define RDC_DOMAIN(x) ((rdc_peri_cfg_t)(0x3 << > RDC_DOMAIN_SHIFT(x))) > + > +#define RDC_MASTER_SHIFT 8 > +#define RDC_MASTER_MASK 0xFF00 > +#define RDC_MASTER_CFG(master_id, domain_id) > (rdc_ma_cfg_t)((master_id << 8) | \ > + (domain_id << RDC_DOMAIN_SHIFT_BASE)) > + > +/* The Following macro definitions are common to i.MX6SX and i.MX7D */ > +#define SEMA_GATES_NUM 64 > + > +#define RDC_MDA_DID_SHIFT 0 > +#define RDC_MDA_DID_MASK (0x3 << RDC_MDA_DID_SHIFT) > +#define RDC_MDA_LCK_SHIFT 31 > +#define RDC_MDA_LCK_MASK (0x1 << RDC_MDA_LCK_SHIFT) > + > +#define RDC_PDAP_D0W_SHIFT 0 > +#define RDC_PDAP_D0W_MASK (0x1 << RDC_PDAP_D0W_SHIFT) > +#define RDC_PDAP_D0R_SHIFT 1 > +#define RDC_PDAP_D0R_MASK (0x1 << RDC_PDAP_D0R_SHIFT) > +#define RDC_PDAP_D1W_SHIFT 2 > +#define RDC_PDAP_D1W_MASK (0x1 << RDC_PDAP_D1W_SHIFT) > +#define RDC_PDAP_D1R_SHIFT 3 > +#define RDC_PDAP_D1R_MASK (0x1 << RDC_PDAP_D1R_SHIFT) > +#define RDC_PDAP_D2W_SHIFT 4 > +#define RDC_PDAP_D2W_MASK (0x1 << RDC_PDAP_D2W_SHIFT) > +#define RDC_PDAP_D2R_SHIFT 5 > +#define RDC_PDAP_D2R_MASK (0x1 << RDC_PDAP_D2R_SHIFT) > +#define RDC_PDAP_D3W_SHIFT 6 > +#define RDC_PDAP_D3W_MASK (0x1 << RDC_PDAP_D3W_SHIFT) > +#define RDC_PDAP_D3R_SHIFT 7 > +#define RDC_PDAP_D3R_MASK (0x1 << RDC_PDAP_D3R_SHIFT) Nit: How about RDC_PDAP_DXW_SHIFT(domain) (2 * domain) style defines? > +#define RDC_PDAP_SREQ_SHIFT 30 > +#define RDC_PDAP_SREQ_MASK (0x1 << RDC_PDAP_SREQ_SHIFT) > +#define RDC_PDAP_LCK_SHIFT 31 > +#define RDC_PDAP_LCK_MASK (0x1 << RDC_PDAP_LCK_SHIFT) > + > +#define RDC_MRSA_SADR_SHIFT 7 > +#define RDC_MRSA_SADR_MASK (0x1ffffff << RDC_MRSA_SADR_SHIFT) > + > +#define RDC_MREA_EADR_SHIFT 7 > +#define RDC_MREA_EADR_MASK (0x1ffffff << RDC_MREA_EADR_SHIFT) > + > +#define RDC_MRC_D0W_SHIFT 0 > +#define RDC_MRC_D0W_MASK (0x1 << RDC_MRC_D0W_SHIFT) > +#define RDC_MRC_D0R_SHIFT 1 > +#define RDC_MRC_D0R_MASK (0x1 << RDC_MRC_D0R_SHIFT) > +#define RDC_MRC_D1W_SHIFT 2 > +#define RDC_MRC_D1W_MASK (0x1 << RDC_MRC_D1W_SHIFT) > +#define RDC_MRC_D1R_SHIFT 3 > +#define RDC_MRC_D1R_MASK (0x1 << RDC_MRC_D1R_SHIFT) > +#define RDC_MRC_D2W_SHIFT 4 > +#define RDC_MRC_D2W_MASK (0x1 << RDC_MRC_D2W_SHIFT) > +#define RDC_MRC_D2R_SHIFT 5 > +#define RDC_MRC_D2R_MASK (0x1 << RDC_MRC_D2R_SHIFT) > +#define RDC_MRC_D3W_SHIFT 6 > +#define RDC_MRC_D3W_MASK (0x1 << RDC_MRC_D3W_SHIFT) > +#define RDC_MRC_D3R_SHIFT 7 > +#define RDC_MRC_D3R_MASK (0x1 << RDC_MRC_D3R_SHIFT) > +#define RDC_MRC_ENA_SHIFT 30 > +#define RDC_MRC_ENA_MASK (0x1 << RDC_MRC_ENA_SHIFT) > +#define RDC_MRC_LCK_SHIFT 31 > +#define RDC_MRC_LCK_MASK (0x1 << RDC_MRC_LCK_SHIFT) > + > +#define RDC_MRVS_VDID_SHIFT 0 > +#define RDC_MRVS_VDID_MASK (0x3 << RDC_MRVS_VDID_SHIFT) > +#define RDC_MRVS_AD_SHIFT 4 > +#define RDC_MRVS_AD_MASK (0x1 << RDC_MRVS_AD_SHIFT) > +#define RDC_MRVS_VADDR_SHIFT 5 > +#define RDC_MRVS_VADDR_MASK (0x7ffffff << RDC_MRVS_VADDR_SHIFT) > + > +#define RDC_SEMA_GATE_GTFSM_SHIFT 0 > +#define RDC_SEMA_GATE_GTFSM_MASK (0xf << RDC_SEMA_GATE_GTFSM_SHIFT) > +#define RDC_SEMA_GATE_LDOM_SHIFT 5 > +#define RDC_SEMA_GATE_LDOM_MASK (0x3 << > RDC_SEMA_GATE_LDOM_SHIFT) > + > +#define RDC_SEMA_RSTGT_RSTGDP_SHIFT 0 > +#define RDC_SEMA_RSTGT_RSTGDP_MASK (0xff << RDC_SEMA_RSTGT_RSTGDP_SHIFT) > +#define RDC_SEMA_RSTGT_RSTGSM_SHIFT 2 > +#define RDC_SEMA_RSTGT_RSTGSM_MASK (0x3 << RDC_SEMA_RSTGT_RSTGSM_SHIFT) > +#define RDC_SEMA_RSTGT_RSTGMS_SHIFT 4 > +#define RDC_SEMA_RSTGT_RSTGMS_MASK (0xf << RDC_SEMA_RSTGT_RSTGMS_SHIFT) > +#define RDC_SEMA_RSTGT_RSTGTN_SHIFT 8 > +#define RDC_SEMA_RSTGT_RSTGTN_MASK (0xff << RDC_SEMA_RSTGT_RSTGTN_SHIFT) > + > +int imx_rdc_check_permission(int per_id); > +int imx_rdc_sema_lock(int per_id); > +int imx_rdc_sema_unlock(int per_id); > +int imx_rdc_setup_peri(rdc_peri_cfg_t p); > +int imx_rdc_setup_peripherals(rdc_peri_cfg_t const *peripherals_list, > + unsigned count); > +int imx_rdc_setup_ma(rdc_ma_cfg_t p); > +int imx_rdc_setup_masters(rdc_ma_cfg_t const *masters_list, unsigned count); > + > +#endif /* __RDC_SEMA_H__*/ _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot