All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peng Fan <van.freenix@gmail.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 02/11] imx: imx-common: introduce Resource Domain Controller support
Date: Tue,  5 Jan 2016 13:56:15 +0800	[thread overview]
Message-ID: <1451973384-26824-3-git-send-email-van.freenix@gmail.com> (raw)
In-Reply-To: <1451973384-26824-1-git-send-email-van.freenix@gmail.com>

From: Peng Fan <peng.fan@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.li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@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)
+ */
+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"
+
+#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)
+#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__*/
-- 
2.6.2

  parent reply	other threads:[~2016-01-05  5:56 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-05  5:56 [U-Boot] [PATCH 00/11] imx: introduce rdc and boot auxiliary core Peng Fan
2016-01-05  5:56 ` [U-Boot] [PATCH 01/11] imx: mx6: introduce rdc regs Peng Fan
2016-01-05  5:56 ` Peng Fan [this message]
2016-01-07  6:52   ` [U-Boot] [PATCH 02/11] imx: imx-common: introduce Resource Domain Controller support Stefan Agner
2016-01-07  7:34     ` Peng Fan
2016-01-05  5:56 ` [U-Boot] [PATCH 03/11] imx: mx6sx Add RDC mappings of masters and peripherals Peng Fan
2016-01-07  6:55   ` Stefan Agner
2016-01-05  5:56 ` [U-Boot] [PATCH 04/11] imx: mx7d: Add RDC support Peng Fan
2016-01-05  5:56 ` [U-Boot] [PATCH 05/11] imx: mx7d: clock support for RDC Peng Fan
2016-01-05  5:56 ` [U-Boot] [PATCH 06/11] imx: imx-common: introduce boot auxiliary core Peng Fan
2016-01-07  6:59   ` Stefan Agner
2016-01-07  8:38     ` Peng Fan
2016-01-08  1:51       ` Ye Li
2016-01-13 20:45       ` Stefan Agner
2016-01-14 17:15         ` Tom Rini
2016-01-14 17:54           ` Stefan Agner
2016-01-14 18:07             ` Tom Rini
2016-01-18  4:07         ` Peng Fan
2016-01-14 17:17   ` Simon Glass
2016-01-18  4:14     ` Peng Fan
2016-01-05  5:56 ` [U-Boot] [PATCH 07/11] imx: mx6: implement functions to " Peng Fan
2016-01-05  5:56 ` [U-Boot] [PATCH 08/11] imx: mx6sxsabresd: add command and macros for boot m4 core Peng Fan
2016-01-05  5:56 ` [U-Boot] [PATCH 09/11] imx: mx7: implement functions to boot auxiliary core Peng Fan
2016-01-05  5:56 ` [U-Boot] [PATCH 10/11] imx: mx7dsabresd: add command and macros for boot m4 core Peng Fan
2016-01-05  5:56 ` [U-Boot] [PATCH 11/11] imx: mx7d: isolate resources to domain 0 for A7 core Peng Fan
2016-01-07  7:04   ` Stefan Agner
2016-01-07 10:42     ` Peng Fan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1451973384-26824-3-git-send-email-van.freenix@gmail.com \
    --to=van.freenix@gmail.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.