diff options
author | Aymen Sghaier <aymen.sghaier@nxp.com> | 2017-11-07 15:28:30 +0100 |
---|---|---|
committer | Abel Vesa <abel.vesa@nxp.com> | 2018-06-11 10:08:40 +0300 |
commit | 5ca8d95b1797f2e169deec5029bf3ac1c41c5c85 (patch) | |
tree | a2da0f79383c2dd38aa16ccb64fed176213089eb /plat/imx/imx8mq | |
parent | 15a5bfb1856a80ce89b0553259b519fac35fcf7a (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.c | 11 | ||||
-rw-r--r-- | plat/imx/imx8mq/imx_rdc.c | 168 | ||||
-rw-r--r-- | plat/imx/imx8mq/include/imx_rdc.h | 221 | ||||
-rw-r--r-- | plat/imx/imx8mq/include/platform_def.h | 1 | ||||
-rw-r--r-- | plat/imx/imx8mq/platform.mk | 1 |
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 \ |