summaryrefslogtreecommitdiff
path: root/plat/imx/imx8mq
diff options
context:
space:
mode:
authorAymen Sghaier <aymen.sghaier@nxp.com>2017-11-07 15:28:30 +0100
committerAbel Vesa <abel.vesa@nxp.com>2018-06-11 10:08:40 +0300
commit5ca8d95b1797f2e169deec5029bf3ac1c41c5c85 (patch)
treea2da0f79383c2dd38aa16ccb64fed176213089eb /plat/imx/imx8mq
parent15a5bfb1856a80ce89b0553259b519fac35fcf7a (diff)
imx8mq: Add rdc support
Enable the RDC driver for i.MX8MQ platform with a default settings as an example. Signed-off-by: Aymen Sghaier <aymen.sghaier@nxp.com>
Diffstat (limited to 'plat/imx/imx8mq')
-rw-r--r--plat/imx/imx8mq/imx8m_bl31_setup.c11
-rw-r--r--plat/imx/imx8mq/imx_rdc.c168
-rw-r--r--plat/imx/imx8mq/include/imx_rdc.h221
-rw-r--r--plat/imx/imx8mq/include/platform_def.h1
-rw-r--r--plat/imx/imx8mq/platform.mk1
5 files changed, 402 insertions, 0 deletions
diff --git a/plat/imx/imx8mq/imx8m_bl31_setup.c b/plat/imx/imx8mq/imx8m_bl31_setup.c
index 5b5bef59..f209b8fc 100644
--- a/plat/imx/imx8mq/imx8m_bl31_setup.c
+++ b/plat/imx/imx8mq/imx8m_bl31_setup.c
@@ -45,6 +45,7 @@
#include <soc.h>
#include <tzc380.h>
#include <imx_csu.h>
+#include <imx_rdc.h>
/* linker defined symbols */
#if USE_COHERENT_MEM
@@ -59,6 +60,15 @@
static entry_point_info_t bl32_image_ep_info;
static entry_point_info_t bl33_image_ep_info;
+/* set RDC settings */
+static void bl31_imx_rdc_setup(void)
+{
+ NOTICE("RDC imx_rdc_set_peripherals default \n");
+ imx_rdc_set_peripherals_default();
+ NOTICE("RDC imx_rdc_set_masters default \n");
+ imx_rdc_set_masters_default();
+}
+
static void bl31_imx_csu_setup(void)
{
NOTICE("Configuring CSU slaves ... \n");
@@ -199,6 +209,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
#endif
bl31_tzc380_setup();
bl31_imx_csu_setup();
+ bl31_imx_rdc_setup();
}
void bl31_plat_arch_setup(void)
diff --git a/plat/imx/imx8mq/imx_rdc.c b/plat/imx/imx8mq/imx_rdc.c
new file mode 100644
index 00000000..3f1d259e
--- /dev/null
+++ b/plat/imx/imx8mq/imx_rdc.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <platform_def.h>
+#include <utils_def.h>
+#include <imx_rdc.h>
+#include <mmio.h>
+
+/*
+ * Read RDC settings for one peripheral
+ * read the given domains field and lock bit
+ * for the given PDAP index [0..118]
+ */
+int imx_rdc_get_pdap(struct rdc_pdap_conf *p)
+{
+ struct imx_rdc_regs *imx_rdc = (struct imx_rdc_regs *)IMX_RDC_BASE;
+ uint32_t reg = 0;
+
+ reg = mmio_read_32((uintptr_t)&imx_rdc->pdap[p->index]);
+ p->lock = (reg & RDC_PDAP_LCK_MASK) >> RDC_PDAP_LCK_SHIFT;
+ p->domains = reg & 0xFF;
+
+ return 0;
+}
+
+/*
+ * Write RDC settings for one peripheral
+ * Check before write if is already locked then skip
+ */
+int imx_rdc_set_pdap(struct rdc_pdap_conf *p)
+{
+ struct imx_rdc_regs *imx_rdc = (struct imx_rdc_regs *)IMX_RDC_BASE;
+ struct rdc_pdap_conf r;
+ uint32_t i, reg = 0;
+ uint8_t multi_domain = 0;
+
+ /* Check if locked */
+ r.index = p->index;
+ imx_rdc_get_pdap(&r);
+ if (r.lock) {
+ WARN("RDC_PDAPn %d is already locked \n", p->index);
+ return -ENOENT;
+ }
+
+ /* Check if no domain assigned */
+ if (p->domains == 0)
+ return -EINVAL;
+ reg |= p->domains;
+
+ /* Check if SREQ is needed */
+ for (i = 0; i < 7; i += 2)
+ multi_domain += ((p->domains >> i) & 0x3) ? 1 : 0;
+ if (multi_domain > 1)
+ reg |= RDC_PDAP_SREQ_MASK;
+ /* Setup Lock from input */
+ reg |= p->lock << RDC_PDAP_LCK_SHIFT;
+ mmio_write_32((uintptr_t)&imx_rdc->pdap[p->index], reg);
+
+ return 0;
+}
+
+/*
+ * Setup RDC settings for multiple peripherals
+ */
+int imx_rdc_set_peripherals(struct rdc_pdap_conf *peripherals_list,
+ uint32_t count)
+{
+ int i, ret;
+
+ for (i = 0; i < count; i++) {
+ ret = imx_rdc_set_pdap(&peripherals_list[i]);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ * Read RDC setting for one master
+ * For the given index in p.index it returns the lock bit
+ * and the domain field into p structure.
+ */
+int imx_rdc_get_mda(struct rdc_mda_conf *p)
+{
+ struct imx_rdc_regs *imx_rdc = (struct imx_rdc_regs *)IMX_RDC_BASE;
+ uint32_t reg = 0;
+
+ reg = mmio_read_32((uintptr_t)&imx_rdc->mda[p->index]);
+ p->domain = reg & RDC_MDA_DID_MASK;
+ p->lock = (reg & RDC_MDA_LCK_MASK) >> RDC_MDA_LCK_SHIFT;
+ return 0;
+}
+
+/*
+ * Write RDC setting for one master
+ */
+int imx_rdc_set_mda(struct rdc_mda_conf *p)
+{
+ struct imx_rdc_regs *imx_rdc = (struct imx_rdc_regs *)IMX_RDC_BASE;
+ struct rdc_mda_conf r;
+ uint32_t reg = 0;
+ int ret = 0;
+
+ /* Check if it is locked */
+ r.index = p->index;
+ imx_rdc_get_mda(&r);
+ if (!r.lock) {
+ reg = (p->domain & RDC_MDA_DID_MASK)
+ | ((p->lock << RDC_MDA_LCK_SHIFT) & RDC_MDA_LCK_MASK);
+ NOTICE("imx_rdc_setup_mda(): write addr=0x%p, reg=0x%x\n",
+ &imx_rdc->mda[p->index], reg);
+ mmio_write_32((uintptr_t)&imx_rdc->mda[p->index], reg);
+ } else {
+ WARN("RDC_MDAn %d is already locked \n", p->index);
+ ret = -ENOENT;
+ }
+
+ return ret;
+}
+
+/*
+ * Setup RDC settings for multiple masters
+ */
+int imx_rdc_set_masters(struct rdc_mda_conf *masters_list, uint32_t count)
+{
+ int i, ret;
+
+ for (i = 0; i < count; i++) {
+ ret = imx_rdc_set_mda(&masters_list[i]);
+ if (ret)
+ break;
+ }
+
+ return ret;
+}
+
+/* Default peripherals settings as an example */
+static struct rdc_pdap_conf periph_config[] = {
+ {RDC_PDAP_GPIO1, 0x3, 0},
+ {RDC_PDAP_GPIO2, 0x3, 0},
+ {RDC_PDAP_GPIO3, 0x3, 0},
+ {RDC_PDAP_GPIO4, 0x3, 0},
+ {RDC_PDAP_GPIO5, 0x3, 0},
+};
+
+/* Default masters settings as an example */
+static struct rdc_mda_conf masters_config[] = {
+ {RDC_MDA_A53, 0, 0},
+ {RDC_MDA_CAAM, 0, 0},
+};
+
+void imx_rdc_set_peripherals_default(void)
+{
+ imx_rdc_set_peripherals(periph_config, ARRAY_SIZE(periph_config));
+}
+
+void imx_rdc_set_masters_default(void)
+{
+ imx_rdc_set_masters(masters_config, ARRAY_SIZE(masters_config));
+}
diff --git a/plat/imx/imx8mq/include/imx_rdc.h b/plat/imx/imx8mq/include/imx_rdc.h
new file mode 100644
index 00000000..cdc77192
--- /dev/null
+++ b/plat/imx/imx8mq/include/imx_rdc.h
@@ -0,0 +1,221 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __IMX_RDC_H__
+#define __IMX_RDC_H__
+
+/* Masters index */
+enum rdc_mda_idx {
+ RDC_MDA_A53 = 0,
+ RDC_MDA_M4 = 1,
+ RDC_MDA_PCIE_CTRL1 = 2,
+ RDC_MDA_PCIE_CTRL2 = 3,
+ RDC_MDA_VPU_DEC = 4,
+ RDC_MDA_LCDIF = 5,
+ RDC_MDA_CSI1 = 6,
+ RDC_MDA_CSI2 = 7,
+ RDC_MDA_Coresight = 8,
+ RDC_MDA_DAP = 9,
+ RDC_MDA_CAAM = 10,
+ RDC_MDA_SDMAp = 11,
+ RDC_MDA_SDMAb = 12,
+ RDC_MDA_APBHDMA = 13,
+ RDC_MDA_RAWNAND = 14,
+ RDC_MDA_uSDHC1 = 15,
+ RDC_MDA_uSDHC2 = 16,
+ RDC_MDA_DCSS = 17,
+ RDC_MDA_GPU = 18,
+ RDC_MDA_USB1 = 19,
+ RDC_MDA_USB2 = 20,
+ RDC_MDA_TESTPORT = 21,
+ RDC_MDA_ENET1_TX = 22,
+ RDC_MDA_ENET1_RX = 23,
+ RDC_MDA_SDMA2 = 24,
+ RDC_MDA_Reserved = 25,
+ RDC_MDA_SDMA1 = 26,
+};
+
+/* Peripherals index */
+enum rdc_pdap_idx {
+ RDC_PDAP_GPIO1 = 0,
+ RDC_PDAP_GPIO2 = 1,
+ RDC_PDAP_GPIO3 = 2,
+ RDC_PDAP_GPIO4 = 3,
+ RDC_PDAP_GPIO5 = 4,
+ RDC_PDAP_Reserved1 = 5,
+ RDC_PDAP_ANA_TSENSOR = 6,
+ RDC_PDAP_ANA_OSC = 7,
+ RDC_PDAP_WDOG1 = 8,
+ RDC_PDAP_WDOG2 = 9,
+ RDC_PDAP_WDOG3 = 10,
+ RDC_PDAP_Reserved2 = 11,
+ RDC_PDAP_SDMA2 = 12,
+ RDC_PDAP_GPT1 = 13,
+ RDC_PDAP_GPT2 = 14,
+ RDC_PDAP_GPT3 = 15,
+ RDC_PDAP_Reserved3 = 16,
+ RDC_PDAP_ROMCP = 17,
+ RDC_PDAP_LCDIF = 18,
+ RDC_PDAP_IOMUXC = 19,
+ RDC_PDAP_IOMUXC_GPR = 20,
+ RDC_PDAP_OCOTP_CTRL = 21,
+ RDC_PDAP_ANATOP_PLL = 22,
+ RDC_PDAP_SNVS_HP = 23,
+ RDC_PDAP_CCM = 24,
+ RDC_PDAP_SRC = 25,
+ RDC_PDAP_GPC = 26,
+ RDC_PDAP_SEMAPHORE1 = 27,
+ RDC_PDAP_SEMAPHORE2 = 28,
+ RDC_PDAP_RDC = 29,
+ RDC_PDAP_CSU = 30,
+ RDC_PDAP_Reserved4 = 31,
+ RDC_PDAP_MST0 = 32,
+ RDC_PDAP_MST1 = 33,
+ RDC_PDAP_MST2 = 34,
+ RDC_PDAP_MST3 = 35,
+ RDC_PDAP_HDMI_SEC = 36,
+ RDC_PDAP_Reserved5 = 37,
+ RDC_PDAP_PWM1 = 38,
+ RDC_PDAP_PWM2 = 39,
+ RDC_PDAP_PWM3 = 40,
+ RDC_PDAP_PWM4 = 41,
+ RDC_PDAP_SysCounter_RD = 42,
+ RDC_PDAP_SysCounter_CMP = 43,
+ RDC_PDAP_SysCounter_CTRL = 44,
+ RDC_PDAP_HDMI_CTRL = 45,
+ RDC_PDAP_GPT6 = 46,
+ RDC_PDAP_GPT5 = 47,
+ RDC_PDAP_GPT4 = 48,
+ RDC_PDAP_TZASC = 56,
+ RDC_PDAP_MTR = 59,
+ RDC_PDAP_PERFMON1 = 60,
+ RDC_PDAP_PERFMON2 = 61,
+ RDC_PDAP_PLATFORM_CTRL = 62,
+ RDC_PDAP_QoSC = 63,
+ RDC_PDAP_MIPI_PHY = 64,
+ RDC_PDAP_MIPI_DSI = 65,
+ RDC_PDAP_I2C1 = 66,
+ RDC_PDAP_I2C2 = 67,
+ RDC_PDAP_I2C3 = 68,
+ RDC_PDAP_I2C4 = 69,
+ RDC_PDAP_UART4 = 70,
+ RDC_PDAP_MIPI_CSI1 = 71,
+ RDC_PDAP_MIPI_CSI_PHY1 = 72,
+ RDC_PDAP_CSI1 = 73,
+ RDC_PDAP_MU_A = 74,
+ RDC_PDAP_MU_B = 75,
+ RDC_PDAP_SEMAPHORE_HS = 76,
+ RDC_PDAP_Reserved6 = 77,
+ RDC_PDAP_SAI1 = 78,
+ RDC_PDAP_Reserved7 = 79,
+ RDC_PDAP_SAI6 = 80,
+ RDC_PDAP_SAI5 = 81,
+ RDC_PDAP_SAI4 = 82,
+ RDC_PDAP_Reserved8 = 83,
+ RDC_PDAP_USDHC1 = 84,
+ RDC_PDAP_USDHC2 = 85,
+ RDC_PDAP_MIPI_CSI2 = 86,
+ RDC_PDAP_MIPI_CSI_PHY2 = 87,
+ RDC_PDAP_CSI2 = 88,
+ RDC_PDAP_Reserved9 = 89,
+ RDC_PDAP_Reserved10 = 90,
+ RDC_PDAP_QSPI = 91,
+ RDC_PDAP_Reserved11 = 92,
+ RDC_PDAP_SDMA1 = 93,
+ RDC_PDAP_ENET1 = 94,
+ RDC_PDAP_Reserved12 = 95,
+ RDC_PDAP_Reserved13 = 96,
+ RDC_PDAP_SPDIF1 = 97,
+ RDC_PDAP_ECSPI1 = 98,
+ RDC_PDAP_ECSPI2 = 99,
+ RDC_PDAP_ECSPI3 = 100,
+ RDC_PDAP_Reserved14 = 101,
+ RDC_PDAP_UART1 = 102,
+ RDC_PDAP_Reserved15 = 103,
+ RDC_PDAP_UART3 = 104,
+ RDC_PDAP_UART2 = 105,
+ RDC_PDAP_SPDIF2 = 106,
+ RDC_PDAP_SAI2 = 107,
+ RDC_PDAP_SAI3 = 108,
+ RDC_PDAP_Reserved16 = 109,
+ RDC_PDAP_Reserved17 = 110,
+ RDC_PDAP_SPBA1 = 111,
+ RDC_PDAP_CAAM = 114,
+ RDC_PDAP_DDRC_SEC = 115,
+ RDC_PDAP_GIC_EXSC = 116,
+ RDC_PDAP_USB_EXSC = 117,
+ RDC_PDAP_OCRAM_TZ = 118,
+ RDC_PDAP_OCRAM_S_TZ = 119,
+ RDC_PDAP_VPU_SEC = 120,
+ RDC_PDAP_DAP_EXSC = 121,
+ RDC_PDAP_ROMCP_SEC = 122,
+ RDC_PDAP_APBHDMA_SEC = 123,
+ RDC_PDAP_M4_SEC = 124,
+ RDC_PDAP_QSPI_SEC = 125,
+ RDC_PDAP_GPU_EXSC = 126,
+ RDC_PDAP_PCIE = 127,
+};
+
+/* RDC registers mapping */
+struct imx_rdc_regs {
+ uint32_t vir; /* Version information */
+ uint32_t reserved1[8];
+ uint32_t stat; /* Status */
+ uint32_t intctrl; /* Interrupt and Control */
+ uint32_t intstat; /* Interrupt Status */
+ uint32_t reserved2[116];
+ uint32_t mda[27]; /* Master Domain Assignment */
+ uint32_t reserved3[101];
+ uint32_t pdap[118]; /* Peripheral Domain Access Permissions */
+ uint32_t reserved4[138];
+ struct {
+ uint32_t mrsa; /* Memory Region Start Address */
+ uint32_t mrea; /* Memory Region End Address */
+ uint32_t mrc; /* Memory Region Control */
+ uint32_t mrvs; /* Memory Region Violation Status */
+ } mem_region[52];
+};
+
+struct rdc_pdap_conf {
+ enum rdc_pdap_idx index; /* Peripheral index */
+ uint8_t domains; /* Assigned domains */
+ uint8_t lock; /* Lock */
+};
+
+struct rdc_mda_conf {
+ enum rdc_mda_idx index; /* Master index */
+ uint8_t domain; /* Assigned domain */
+ uint8_t lock; /* Lock */
+};
+
+#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_DW_SHIFT(domain) ((domain) << 1)
+#define RDC_PDAP_DR_SHIFT(domain) (1 + RDC_PDAP_DW_SHIFT(domain))
+#define RDC_PDAP_DW_MASK(domain) (1 << RDC_PDAP_DW_SHIFT(domain))
+#define RDC_PDAP_DR_MASK(domain) (1 << RDC_PDAP_DR_SHIFT(domain))
+#define RDC_PDAP_DRW_MASK(domain) (RDC_PDAP_DW_MASK(domain) | \
+ RDC_PDAP_DR_MASK(domain))
+
+#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)
+
+int imx_rdc_get_pdap(struct rdc_pdap_conf *p);
+int imx_rdc_set_pdap(struct rdc_pdap_conf *p);
+int imx_rdc_set_peripherals(struct rdc_pdap_conf *peripheral_list,
+ uint32_t count);
+void imx_rdc_set_peripherals_default(void);
+int imx_rdc_get_mda(struct rdc_mda_conf *p);
+int imx_rdc_set_mda(struct rdc_mda_conf *p);
+int imx_rdc_set_masters(struct rdc_mda_conf *masters_list, uint32_t count);
+void imx_rdc_set_masters_default(void);
+
+#endif /* __IMX_RDC_H__*/
diff --git a/plat/imx/imx8mq/include/platform_def.h b/plat/imx/imx8mq/include/platform_def.h
index 222bc1cc..45632deb 100644
--- a/plat/imx/imx8mq/include/platform_def.h
+++ b/plat/imx/imx8mq/include/platform_def.h
@@ -50,6 +50,7 @@
#define IMX_ANAMIX_BASE 0x30360000
#define IMX_SRC_BASE 0x30390000
#define IMX_GPC_BASE 0x303a0000
+#define IMX_RDC_BASE 0x303d0000
#define IMX_CSU_BASE 0x303e0000
#define IMX_WDOG_BASE 0x30280000
#define IMX_SNVS_BASE 0x30370000
diff --git a/plat/imx/imx8mq/platform.mk b/plat/imx/imx8mq/platform.mk
index c1f5a220..0361161a 100644
--- a/plat/imx/imx8mq/platform.mk
+++ b/plat/imx/imx8mq/platform.mk
@@ -16,6 +16,7 @@ BL31_SOURCES += plat/imx/common/imx8_helpers.S \
plat/imx/imx8mq/ddrc.c \
plat/imx/imx8mq/imx8m_psci.c \
plat/imx/imx8mq/imx_csu.c \
+ plat/imx/imx8mq/imx_rdc.c \
plat/imx/common/imx8_topology.c \
plat/common/plat_psci_common.c \
lib/xlat_tables/aarch64/xlat_tables.c \