1
0
Fork 0

Merge branch 'master' of git://www.denx.de/git/u-boot-imx

utp
Tom Rini 2016-02-21 07:56:16 -05:00
commit 595af9db24
34 changed files with 1506 additions and 57 deletions

View File

@ -21,6 +21,7 @@
#include <asm/arch/crm_regs.h>
#include <dm.h>
#include <imx_thermal.h>
#include <mmc.h>
enum ldo_reg {
LDO_ARM,
@ -355,7 +356,7 @@ __weak int board_mmc_get_env_dev(int devno)
return CONFIG_SYS_MMC_ENV_DEV;
}
int mmc_get_env_dev(void)
static int mmc_get_boot_dev(void)
{
struct src *src_regs = (struct src *)SRC_BASE_ADDR;
u32 soc_sbmr = readl(&src_regs->sbmr1);
@ -370,15 +371,44 @@ int mmc_get_env_dev(void)
*/
bootsel = (soc_sbmr & 0x000000FF) >> 6;
/* If not boot from sd/mmc, use default value */
/* No boot from sd/mmc */
if (bootsel != 1)
return CONFIG_SYS_MMC_ENV_DEV;
return -1;
/* BOOT_CFG2[3] and BOOT_CFG2[4] */
devno = (soc_sbmr & 0x00001800) >> 11;
return devno;
}
int mmc_get_env_dev(void)
{
int devno = mmc_get_boot_dev();
/* If not boot from sd/mmc, use default value */
if (devno < 0)
return CONFIG_SYS_MMC_ENV_DEV;
return board_mmc_get_env_dev(devno);
}
#ifdef CONFIG_SYS_MMC_ENV_PART
__weak int board_mmc_get_env_part(int devno)
{
return CONFIG_SYS_MMC_ENV_PART;
}
uint mmc_get_env_part(struct mmc *mmc)
{
int devno = mmc_get_boot_dev();
/* If not boot from sd/mmc, use default value */
if (devno < 0)
return CONFIG_SYS_MMC_ENV_PART;
return board_mmc_get_env_part(devno);
}
#endif
#endif
int board_postclk_init(void)
@ -537,3 +567,41 @@ void imx_setup_hdmi(void)
writel(reg, &mxc_ccm->chsccdr);
}
#endif
#ifdef CONFIG_IMX_BOOTAUX
int arch_auxiliary_core_up(u32 core_id, u32 boot_private_data)
{
struct src *src_reg;
u32 stack, pc;
if (!boot_private_data)
return -EINVAL;
stack = *(u32 *)boot_private_data;
pc = *(u32 *)(boot_private_data + 4);
/* Set the stack and pc to M4 bootROM */
writel(stack, M4_BOOTROM_BASE_ADDR);
writel(pc, M4_BOOTROM_BASE_ADDR + 4);
/* Enable M4 */
src_reg = (struct src *)SRC_BASE_ADDR;
clrsetbits_le32(&src_reg->scr, SRC_SCR_M4C_NON_SCLR_RST_MASK,
SRC_SCR_M4_ENABLE_MASK);
return 0;
}
int arch_auxiliary_core_check_up(u32 core_id)
{
struct src *src_reg = (struct src *)SRC_BASE_ADDR;
unsigned val;
val = readl(&src_reg->scr);
if (val & SRC_SCR_M4C_NON_SCLR_RST_MASK)
return 0; /* assert in reset */
return 1;
}
#endif

View File

@ -1067,6 +1067,12 @@ void clock_init(void)
#ifdef CONFIG_NAND_MXS
clock_enable(CCGR_RAWNAND, 1);
#endif
if (IS_ENABLED(CONFIG_IMX_RDC)) {
clock_enable(CCGR_RDC, 1);
clock_enable(CCGR_SEMA1, 1);
clock_enable(CCGR_SEMA2, 1);
}
}
#ifdef CONFIG_SECURE_BOOT

View File

@ -12,6 +12,8 @@
#include <asm/imx-common/boot_mode.h>
#include <asm/imx-common/dma.h>
#include <asm/imx-common/hab.h>
#include <asm/imx-common/rdc-sema.h>
#include <asm/arch/imx-rdc.h>
#include <asm/arch/crm_regs.h>
#include <dm.h>
#include <imx_thermal.h>
@ -29,6 +31,65 @@ U_BOOT_DEVICE(imx7_thermal) = {
};
#endif
#ifdef CONFIG_IMX_RDC
/*
* In current design, if any peripheral was assigned to both A7 and M4,
* it will receive ipg_stop or ipg_wait when any of the 2 platforms enter
* low power mode. So M4 sleep will cause some peripherals fail to work
* at A7 core side. At default, all resources are in domain 0 - 3.
*
* There are 26 peripherals impacted by this IC issue:
* SIM2(sim2/emvsim2)
* SIM1(sim1/emvsim1)
* UART1/UART2/UART3/UART4/UART5/UART6/UART7
* SAI1/SAI2/SAI3
* WDOG1/WDOG2/WDOG3/WDOG4
* GPT1/GPT2/GPT3/GPT4
* PWM1/PWM2/PWM3/PWM4
* ENET1/ENET2
* Software Workaround:
* Here we setup some resources to domain 0 where M4 codes will move
* the M4 out of this domain. Then M4 is not able to access them any longer.
* This is a workaround for ic issue. So the peripherals are not shared
* by them. This way requires the uboot implemented the RDC driver and
* set the 26 IPs above to domain 0 only. M4 code will assign resource
* to its own domain, if it want to use the resource.
*/
static rdc_peri_cfg_t const resources[] = {
(RDC_PER_SIM1 | RDC_DOMAIN(0)),
(RDC_PER_SIM2 | RDC_DOMAIN(0)),
(RDC_PER_UART1 | RDC_DOMAIN(0)),
(RDC_PER_UART2 | RDC_DOMAIN(0)),
(RDC_PER_UART3 | RDC_DOMAIN(0)),
(RDC_PER_UART4 | RDC_DOMAIN(0)),
(RDC_PER_UART5 | RDC_DOMAIN(0)),
(RDC_PER_UART6 | RDC_DOMAIN(0)),
(RDC_PER_UART7 | RDC_DOMAIN(0)),
(RDC_PER_SAI1 | RDC_DOMAIN(0)),
(RDC_PER_SAI2 | RDC_DOMAIN(0)),
(RDC_PER_SAI3 | RDC_DOMAIN(0)),
(RDC_PER_WDOG1 | RDC_DOMAIN(0)),
(RDC_PER_WDOG2 | RDC_DOMAIN(0)),
(RDC_PER_WDOG3 | RDC_DOMAIN(0)),
(RDC_PER_WDOG4 | RDC_DOMAIN(0)),
(RDC_PER_GPT1 | RDC_DOMAIN(0)),
(RDC_PER_GPT2 | RDC_DOMAIN(0)),
(RDC_PER_GPT3 | RDC_DOMAIN(0)),
(RDC_PER_GPT4 | RDC_DOMAIN(0)),
(RDC_PER_PWM1 | RDC_DOMAIN(0)),
(RDC_PER_PWM2 | RDC_DOMAIN(0)),
(RDC_PER_PWM3 | RDC_DOMAIN(0)),
(RDC_PER_PWM4 | RDC_DOMAIN(0)),
(RDC_PER_ENET1 | RDC_DOMAIN(0)),
(RDC_PER_ENET2 | RDC_DOMAIN(0)),
};
static void isolate_resource(void)
{
imx_rdc_setup_peripherals(resources, ARRAY_SIZE(resources));
}
#endif
#if defined(CONFIG_SECURE_BOOT)
struct imx_sec_config_fuse_t const imx_sec_config_fuse = {
.bank = 1,
@ -163,6 +224,9 @@ int arch_cpu_init(void)
mxs_dma_init();
#endif
if (IS_ENABLED(CONFIG_IMX_RDC))
isolate_resource();
return 0;
}
@ -211,6 +275,42 @@ void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
}
#endif
#ifdef CONFIG_IMX_BOOTAUX
int arch_auxiliary_core_up(u32 core_id, u32 boot_private_data)
{
u32 stack, pc;
struct src *src_reg = (struct src *)SRC_BASE_ADDR;
if (!boot_private_data)
return 1;
stack = *(u32 *)boot_private_data;
pc = *(u32 *)(boot_private_data + 4);
/* Set the stack and pc to M4 bootROM */
writel(stack, M4_BOOTROM_BASE_ADDR);
writel(pc, M4_BOOTROM_BASE_ADDR + 4);
/* Enable M4 */
clrsetbits_le32(&src_reg->m4rcr, SRC_M4RCR_M4C_NON_SCLR_RST_MASK,
SRC_M4RCR_ENABLE_M4_MASK);
return 0;
}
int arch_auxiliary_core_check_up(u32 core_id)
{
uint32_t val;
struct src *src_reg = (struct src *)SRC_BASE_ADDR;
val = readl(&src_reg->m4rcr);
if (val & 0x00000001)
return 0; /* assert in reset */
return 1;
}
#endif
void set_wdog_reset(struct wdog_regs *wdog)
{
u32 reg = readw(&wdog->wcr);

View File

@ -3,3 +3,17 @@ 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.
config IMX_BOOTAUX
bool "Support boot auxiliary core"
depends on ARCH_MX7 || ARCH_MX6
help
bootaux [addr] to boot auxiliary core.

View File

@ -27,6 +27,8 @@ 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_IMX_BOOTAUX) += imx_bootaux.o
obj-$(CONFIG_SECURE_BOOT) += hab.o
endif
ifeq ($(SOC),$(filter $(SOC),vf610))

View File

@ -0,0 +1,72 @@
/*
* Copyright (C) 2016 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <command.h>
/* Allow for arch specific config before we boot */
static int __arch_auxiliary_core_up(u32 core_id, u32 boot_private_data)
{
/* please define platform specific arch_auxiliary_core_up() */
return CMD_RET_FAILURE;
}
int arch_auxiliary_core_up(u32 core_id, u32 boot_private_data)
__attribute__((weak, alias("__arch_auxiliary_core_up")));
/* Allow for arch specific config before we boot */
static int __arch_auxiliary_core_check_up(u32 core_id)
{
/* please define platform specific arch_auxiliary_core_check_up() */
return 0;
}
int arch_auxiliary_core_check_up(u32 core_id)
__attribute__((weak, alias("__arch_auxiliary_core_check_up")));
/*
* To i.MX6SX and i.MX7D, the image supported by bootaux needs
* the reset vector at the head for the image, with SP and PC
* as the first two words.
*
* Per the cortex-M reference manual, the reset vector of M4 needs
* to exist at 0x0 (TCMUL). The PC and SP are the first two addresses
* of that vector. So to boot M4, the A core must build the M4's reset
* vector with getting the PC and SP from image and filling them to
* TCMUL. When M4 is kicked, it will load the PC and SP by itself.
* The TCMUL is mapped to (M4_BOOTROM_BASE_ADDR) at A core side for
* accessing the M4 TCMUL.
*/
int do_bootaux(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
ulong addr;
int ret, up;
if (argc < 2)
return CMD_RET_USAGE;
up = arch_auxiliary_core_check_up(0);
if (up) {
printf("## Auxiliary core is already up\n");
return CMD_RET_SUCCESS;
}
addr = simple_strtoul(argv[1], NULL, 16);
printf("## Starting auxiliary core at 0x%08lX ...\n", addr);
ret = arch_auxiliary_core_up(0, addr);
if (ret)
return CMD_RET_FAILURE;
return CMD_RET_SUCCESS;
}
U_BOOT_CMD(
bootaux, CONFIG_SYS_MAXARGS, 1, do_bootaux,
"Start auxiliary core",
""
);

View File

@ -0,0 +1,183 @@
/*
* 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 [dom_id].
*/
int imx_rdc_check_permission(int per_id, int dom_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_DRW_MASK(dom_id)))
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;
}

View File

@ -0,0 +1,16 @@
/*
* Copyright (C) 2016 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __IMX_RDC_H__
#define __IMX_RDC_H__
#if defined(CONFIG_MX6SX)
#include "mx6sx_rdc.h"
#else
#error "Please select cpu"
#endif /* CONFIG_MX6SX */
#endif /* __IMX_RDC_H__*/

View File

@ -356,6 +356,30 @@ extern void imx_get_mac_from_fuse(int dev_id, unsigned char *mac);
#define SRC_SCR_CORE_3_ENABLE_OFFSET 24
#define SRC_SCR_CORE_3_ENABLE_MASK (1<<SRC_SCR_CORE_3_ENABLE_OFFSET)
struct rdc_regs {
u32 vir; /* Version information */
u32 reserved1[8];
u32 stat; /* Status */
u32 intctrl; /* Interrupt and Control */
u32 intstat; /* Interrupt Status */
u32 reserved2[116];
u32 mda[32]; /* Master Domain Assignment */
u32 reserved3[96];
u32 pdap[104]; /* Peripheral Domain Access Permissions */
u32 reserved4[88];
struct {
u32 mrsa; /* Memory Region Start Address */
u32 mrea; /* Memory Region End Address */
u32 mrc; /* Memory Region Control */
u32 mrvs; /* Memory Region Violation Status */
} mem_region[55];
};
struct rdc_sema_regs {
u8 gate[64]; /* Gate */
u16 rstgt; /* Reset Gate */
};
/* WEIM registers */
struct weim {
u32 cs0gcr1;
@ -414,6 +438,11 @@ struct src {
u32 gpr10;
};
#define SRC_SCR_M4_ENABLE_OFFSET 22
#define SRC_SCR_M4_ENABLE_MASK (1 << 22)
#define SRC_SCR_M4C_NON_SCLR_RST_OFFSET 4
#define SRC_SCR_M4C_NON_SCLR_RST_MASK (1 << 4)
/* GPR1 bitfields */
#define IOMUXC_GPR1_APP_CLK_REQ_N BIT(30)
#define IOMUXC_GPR1_PCIE_EXIT_L1 BIT(28)

View File

@ -0,0 +1,155 @@
/*
* Copyright (C) 2014 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __MX6SX_RDC_H__
#define __MX6SX_RDC_H__
#define RDC_SEMA_PROC_ID 2 /* The processor ID for main CPU */
enum {
RDC_PER_PWM1 = 0,
RDC_PER_PWM2,
RDC_PER_PWM3,
RDC_PER_PWM4,
RDC_PER_CAN1,
RDC_PER_CAN2,
RDC_PER_GPT,
RDC_PER_GPIO1,
RDC_PER_GPIO2,
RDC_PER_GPIO3,
RDC_PER_GPIO4,
RDC_PER_GPIO5,
RDC_PER_GPIO6,
RDC_PER_GPIO7,
RDC_PER_KPP,
RDC_PER_WDOG1,
RDC_PER_WODG2,
RDC_PER_CCM,
RDC_PER_ANATOPDIG,
RDC_PER_SNVSHP,
RDC_PER_EPIT1,
RDC_PER_EPIT2,
RDC_PER_SRC,
RDC_PER_GPC,
RDC_PER_IOMUXC,
RDC_PER_IOMUXCGPR,
RDC_PER_CANFD1,
RDC_PER_SDMA,
RDC_PER_CANFD2,
RDC_PER_SEMA1,
RDC_PER_SEMA2,
RDC_PER_RDC,
RDC_PER_AIPSTZ1_GE1,
RDC_PER_AIPSTZ2_GE2,
RDC_PER_USBO2H_PL301,
RDC_PER_USBO2H_USB,
RDC_PER_ENET1,
RDC_PER_MLB25,
RDC_PER_USDHC1,
RDC_PER_USDHC2,
RDC_PER_USDHC3,
RDC_PER_USDHC4,
RDC_PER_I2C1,
RDC_PER_I2C2,
RDC_PER_I2C3,
RDC_PER_ROMCP,
RDC_PER_MMDC,
RDC_PER_ENET2,
RDC_PER_EIM,
RDC_PER_OCOTP,
RDC_PER_CSU,
RDC_PER_PERFMON1,
RDC_PER_PERFMON2,
RDC_PER_AXIMON,
RDC_PER_TZASC1,
RDC_PER_SAI1,
RDC_PER_AUDMUX,
RDC_PER_SAI2,
RDC_PER_QSPI1,
RDC_PER_QSPI2,
RDC_PER_UART2,
RDC_PER_UART3,
RDC_PER_UART4,
RDC_PER_UART5,
RDC_PER_I2C4,
RDC_PER_QOSC,
RDC_PER_CAAM,
RDC_PER_DAP,
RDC_PER_ADC1,
RDC_PER_ADC2,
RDC_PER_WDOG3,
RDC_PER_ECSPI5,
RDC_PER_SEMA4,
RDC_PER_MUPORT1,
RDC_PER_CANFD_CPU,
RDC_PER_MUPORT2,
RDC_PER_UART6,
RDC_PER_PWM5,
RDC_PER_PWM6,
RDC_PER_PWM7,
RDC_PER_PWM8,
RDC_PER_AIPSTZ3_GE0,
RDC_PER_AIPSTZ3_GE1,
RDC_PER_RESERVED1,
RDC_PER_SPDIF,
RDC_PER_ECSPI1,
RDC_PER_ECSPI2,
RDC_PER_ECSPI3,
RDC_PER_ECSPI4,
RDC_PER_RESERVED2,
RDC_PER_RESERVED3,
RDC_PER_UART1,
RDC_PER_ESAI,
RDC_PER_SSI1,
RDC_PER_SSI2,
RDC_PER_SSI3,
RDC_PER_ASRC,
RDC_PER_RESERVED4,
RDC_PER_SPBA_MA,
RDC_PER_GIS,
RDC_PER_DCIC1,
RDC_PER_DCIC2,
RDC_PER_CSI1,
RDC_PER_PXP,
RDC_PER_CSI2,
RDC_PER_LCDIF1,
RDC_PER_LCDIF2,
RDC_PER_VADC,
RDC_PER_VDEC,
RDC_PER_SPBA_DISPLAYMIX,
};
enum {
RDC_MA_A9_L2CACHE = 0,
RDC_MA_M4,
RDC_MA_GPU,
RDC_MA_CSI1,
RDC_MA_CSI2,
RDC_MA_LCDIF1,
RDC_MA_LCDIF2,
RDC_MA_PXP,
RDC_MA_PCIE_CTRL,
RDC_MA_DAP,
RDC_MA_CAAM,
RDC_MA_SDMA_PERI,
RDC_MA_SDMA_BURST,
RDC_MA_APBHDMA,
RDC_MA_RAWNAND,
RDC_MA_USDHC1,
RDC_MA_USDHC2,
RDC_MA_USDHC3,
RDC_MA_USDHC4,
RDC_MA_USB,
RDC_MA_MLB,
RDC_MA_TEST,
RDC_MA_ENET1_TX,
RDC_MA_ENET1_RX,
RDC_MA_ENET2_TX,
RDC_MA_ENET2_RX,
RDC_MA_SDMA,
};
#endif /* __MX6SX_RDC_H__*/

View File

@ -0,0 +1,16 @@
/*
* Copyright (C) 2016 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __IMX_RDC_H__
#define __IMX_RDC_H__
#if defined(CONFIG_MX7D)
#include "mx7d_rdc.h"
#else
#error "Please select cpu"
#endif /* CONFIG_MX7D */
#endif /* __IMX_RDC_H__*/

View File

@ -212,10 +212,16 @@
#define DEBUG_MONITOR_BASE_ADDR IP2APB_AXIMON_IPS_BASE_ADDR
#define USB_BASE_ADDR USBOTG1_IPS_BASE_ADDR
#define SEMAPHORE1_BASE_ADDR SEMA41_IPS_BASE_ADDR
#define SEMAPHORE2_BASE_ADDR SEMA42_IPS_BASE_ADDR
#define RDC_BASE_ADDR RDC_IPS_BASE_ADDR
#define FEC_QUIRK_ENET_MAC
#define SNVS_LPGPR 0x68
#define CONFIG_SYS_FSL_SEC_ADDR (CAAM_IPS_BASE_ADDR)
#define CONFIG_SYS_FSL_JR0_ADDR (CONFIG_SYS_FSL_SEC_ADDR + 0x1000)
#if !(defined(__KERNEL_STRICT_NAMES) || defined(__ASSEMBLY__))
#include <asm/imx-common/regs-lcdif.h>
#include <asm/types.h>
@ -257,6 +263,11 @@ struct src {
u32 ddrc_rcr;
};
#define SRC_M4RCR_M4C_NON_SCLR_RST_OFFSET 0
#define SRC_M4RCR_M4C_NON_SCLR_RST_MASK (1 << 0)
#define SRC_M4RCR_ENABLE_M4_OFFSET 3
#define SRC_M4RCR_ENABLE_M4_MASK (1 << 3)
/* GPR0 Bit Fields */
#define IOMUXC_GPR_GPR0_DMAREQ_MUX_SEL0_MASK 0x1u
#define IOMUXC_GPR_GPR0_DMAREQ_MUX_SEL0_SHIFT 0

View File

@ -0,0 +1,163 @@
/*
* Copyright (C) 2016 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __MX7D_RDC_H__
#define __MX7D_RDC_H__
#define RDC_SEMA_PROC_ID 2 /* The processor ID for main CPU */
enum {
RDC_PER_GPIO1 = 0,
RDC_PER_GPIO2,
RDC_PER_GPIO3,
RDC_PER_GPIO4,
RDC_PER_GPIO5,
RDC_PER_GPIO6,
RDC_PER_GPIO7,
RDC_PER_IOMUXC_LPSR_GPR,
RDC_PER_WDOG1,
RDC_PER_WDOG2,
RDC_PER_WDOG3,
RDC_PER_WDOG4,
RDC_PER_IOMUXC_LPSR,
RDC_PER_GPT1,
RDC_PER_GPT2,
RDC_PER_GPT3,
RDC_PER_GPT4,
RDC_PER_ROMCP,
RDC_PER_KPP,
RDC_PER_IOMUXC,
RDC_PER_IOMUXCGPR,
RDC_PER_OCOTP,
RDC_PER_ANATOP_DIG,
RDC_PER_SNVS_HP,
RDC_PER_CCM,
RDC_PER_SRC,
RDC_PER_GPC,
RDC_PER_SEMA1,
RDC_PER_SEMA2,
RDC_PER_RDC,
RDC_PER_CSU,
RDC_PER_RESERVED1,
RDC_PER_RESERVED2,
RDC_PER_ADC1,
RDC_PER_ADC2,
RDC_PER_ECSPI4,
RDC_PER_FLEX_TIMER1,
RDC_PER_FLEX_TIMER2,
RDC_PER_PWM1,
RDC_PER_PWM2,
RDC_PER_PWM3,
RDC_PER_PWM4,
RDC_PER_SYSTEM_COUNTER_READ,
RDC_PER_SYSTEM_COUNTER_COMPARE,
RDC_PER_SYSTEM_COUNTER_CONTROL,
RDC_PER_PCIE_PHY,
RDC_PER_RESERVED3,
RDC_PER_EPDC,
RDC_PER_PXP,
RDC_PER_CSI,
RDC_PER_RESERVED4,
RDC_PER_LCDIF,
RDC_PER_RESERVED5,
RDC_PER_MIPI_CSI,
RDC_PER_MIPI_DSI,
RDC_PER_RESERVED6,
RDC_PER_TZASC,
RDC_PER_DDR_PHY,
RDC_PER_DDRC,
RDC_PER_RESERVED7,
RDC_PER_PERFMON1,
RDC_PER_PERFMON2,
RDC_PER_AXI_DEBUG_MON,
RDC_PER_QOSC,
RDC_PER_FLEXCAN1,
RDC_PER_FLEXCAN2,
RDC_PER_I2C1,
RDC_PER_I2C2,
RDC_PER_I2C3,
RDC_PER_I2C4,
RDC_PER_UART4,
RDC_PER_UART5,
RDC_PER_UART6,
RDC_PER_UART7,
RDC_PER_MU_A,
RDC_PER_MU_B,
RDC_PER_SEMAPHORE_HS,
RDC_PER_USB_PL301,
RDC_PER_RESERVED8,
RDC_PER_RESERVED9,
RDC_PER_RESERVED10,
RDC_PER_USB1,
RDC_PER_USB2,
RDC_PER_USB3,
RDC_PER_USDHC1,
RDC_PER_USDHC2,
RDC_PER_USDHC3,
RDC_PER_RESERVED11,
RDC_PER_RESERVED12,
RDC_PER_SIM1,
RDC_PER_SIM2,
RDC_PER_QSPI,
RDC_PER_WEIM,
RDC_PER_SDMA,
RDC_PER_ENET1,
RDC_PER_ENET2,
RDC_PER_RESERVED13,
RDC_PER_RESERVED14,
RDC_PER_ECSPI1,
RDC_PER_ECSPI2,
RDC_PER_ECSPI3,
RDC_PER_RESERVED15,
RDC_PER_UART1,
RDC_PER_UART2,
RDC_PER_UART3,
RDC_PER_RESERVED16,
RDC_PER_SAI1,
RDC_PER_SAI2,
RDC_PER_SAI3,
RDC_PER_RESERVED17,
RDC_PER_RESERVED18,
RDC_PER_SPBA,
RDC_PER_DAP,
RDC_PER_RESERVED19,
RDC_PER_RESERVED20,
RDC_PER_RESERVED21,
RDC_PER_CAAM,
RDC_PER_RESERVED22,
};
enum {
RDC_MA_A7 = 0,
RDC_MA_M4,
RDC_MA_PCIE,
RDC_MA_CSI,
RDC_MA_EPDC,
RDC_MA_LCDIF,
RDC_MA_DISPLAY_PORT,
RDC_MA_PXP,
RDC_MA_CORESIGHT,
RDC_MA_DAP,
RDC_MA_CAAM,
RDC_MA_SDMA_PERI,
RDC_MA_SDMA_BURST,
RDC_MA_APBHDMA,
RDC_MA_RAWNAND,
RDC_MA_USDHC1,
RDC_MA_USDHC2,
RDC_MA_USDHC3,
RDC_MA_NC1,
RDC_MA_USB,
RDC_MA_NC2,
RDC_MA_TEST,
RDC_MA_ENET1_TX,
RDC_MA_ENET1_RX,
RDC_MA_ENET2_TX,
RDC_MA_ENET2_RX,
RDC_MA_SDMA,
};
#endif /* __MX7D_RDC_H__*/

View File

@ -0,0 +1,100 @@
/*
* Copyright (C) 2016 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __RDC_SEMA_H__
#define __RDC_SEMA_H__
/*
* rdc_peri_cfg_t and rdc_ma_cft_t use the same layout.
*
* [ 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_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)
#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_DW_SHIFT(domain) (domain)
#define RDC_MRC_DR_SHIFT(domain) (1 + RDC_MRC_DW_SHIFT(domain))
#define RDC_MRC_DW_MASK(domain) (1 << RDC_MRC_DW_SHIFT(domain))
#define RDC_MRC_DR_MASK(domain) (1 << RDC_MRC_DR_SHIFT(domain))
#define RDC_MRC_DRW_MASK(domain) (RDC_MRC_DW_MASK(domain) | \
RDC_MRC_DR_MASK(domain))
#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 dom_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__*/

View File

@ -1,5 +1,5 @@
MX7DSABRESD BOARD
M: Adrian Alonso <aalonso@freescale.com>
M: Adrian Alonso <adrian.alonso@nxp.com>
S: Maintained
F: board/freescale/mx7dsabresd
F: include/configs/mx7dsabresd.h

View File

@ -23,6 +23,7 @@
#include <i2c.h>
#include <asm/imx-common/mxc_i2c.h>
#include <asm/arch/crm_regs.h>
#include <usb.h>
#include <usb/ehci-fsl.h>
DECLARE_GLOBAL_DATA_PTR;
@ -111,6 +112,14 @@ static iomux_v3_cfg_t const usdhc3_emmc_pads[] = {
MX7D_PAD_SD3_RESET_B__GPIO6_IO11 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
};
static iomux_v3_cfg_t const usb_otg1_pads[] = {
MX7D_PAD_GPIO1_IO05__USB_OTG1_PWR | MUX_PAD_CTRL(NO_PAD_CTRL),
};
static iomux_v3_cfg_t const usb_otg2_pads[] = {
MX7D_PAD_UART3_CTS_B__USB_OTG2_PWR | MUX_PAD_CTRL(NO_PAD_CTRL),
};
#define IOX_SDI IMX_GPIO_NR(1, 9)
#define IOX_STCP IMX_GPIO_NR(1, 12)
#define IOX_SHCP IMX_GPIO_NR(1, 13)
@ -511,6 +520,10 @@ int board_early_init_f(void)
setup_iomux_uart();
setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
imx_iomux_v3_setup_multiple_pads(usb_otg1_pads,
ARRAY_SIZE(usb_otg1_pads));
imx_iomux_v3_setup_multiple_pads(usb_otg2_pads,
ARRAY_SIZE(usb_otg2_pads));
return 0;
}
@ -602,29 +615,11 @@ int checkboard(void)
}
#ifdef CONFIG_USB_EHCI_MX7
static iomux_v3_cfg_t const usb_otg1_pads[] = {
MX7D_PAD_GPIO1_IO05__USB_OTG1_PWR | MUX_PAD_CTRL(NO_PAD_CTRL),
};
static iomux_v3_cfg_t const usb_otg2_pads[] = {
MX7D_PAD_UART3_CTS_B__USB_OTG2_PWR | MUX_PAD_CTRL(NO_PAD_CTRL),
};
int board_ehci_hcd_init(int port)
int board_usb_phy_mode(int port)
{
switch (port) {
case 0:
imx_iomux_v3_setup_multiple_pads(usb_otg1_pads,
ARRAY_SIZE(usb_otg1_pads));
break;
case 1:
imx_iomux_v3_setup_multiple_pads(usb_otg2_pads,
ARRAY_SIZE(usb_otg2_pads));
break;
default:
printf("MXC USB port %d not yet supported\n", port);
return -EINVAL;
}
return 0;
if (port == 0)
return USB_INIT_DEVICE;
else
return USB_INIT_HOST;
}
#endif

View File

@ -91,11 +91,30 @@ int board_eth_init(bd_t *bis)
return ret;
}
#define USDHC4_CD_GPIO IMX_GPIO_NR(2, 6)
static struct fsl_esdhc_cfg usdhc_cfg[2] = {
{USDHC3_BASE_ADDR},
{USDHC2_BASE_ADDR},
{USDHC3_BASE_ADDR, 0, 4},
{USDHC4_BASE_ADDR, 0, 4},
};
int board_mmc_getcd(struct mmc *mmc)
{
struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
int ret = 0;
switch (cfg->esdhc_base) {
case USDHC3_BASE_ADDR:
ret = 1; /* Assume eMMC is always present */
break;
case USDHC4_BASE_ADDR:
ret = !gpio_get_value(USDHC4_CD_GPIO);
break;
}
return ret;
}
int board_mmc_init(bd_t *bis)
{
u32 index = 0;
@ -112,12 +131,10 @@ int board_mmc_init(bd_t *bis)
case 0:
seco_mx6_setup_usdhc_iomux(3);
usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
usdhc_cfg[0].max_bus_width = 4;
break;
case 1:
seco_mx6_setup_usdhc_iomux(4);
usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
usdhc_cfg[1].max_bus_width = 4;
break;
default:

View File

@ -257,6 +257,17 @@ int board_mmc_init(bd_t *bis)
}
return 0;
}
/* set environment device to boot device when booting from SD */
int board_mmc_get_env_dev(int devno)
{
return devno - 1;
}
int board_mmc_get_env_part(int devno)
{
return (devno == 3) ? 1 : 0; /* part 0 for SD2 / SD3, part 1 for eMMC */
}
#endif /* CONFIG_FSL_ESDHC */
#ifdef CONFIG_VIDEO_IPUV3

View File

@ -1,6 +1,8 @@
CONFIG_ARM=y
CONFIG_ARCH_MX7=y
CONFIG_TARGET_MX7DSABRESD=y
CONFIG_IMX_RDC=y
CONFIG_IMX_BOOTAUX=y
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx7dsabresd/imximage.cfg,MX7D"
# CONFIG_CMD_BOOTD is not set
# CONFIG_CMD_IMI is not set

View File

@ -14,7 +14,7 @@
#include "jobdesc.h"
#include "rsa_caam.h"
#ifdef CONFIG_MX6
#if defined(CONFIG_MX6) || defined(CONFIG_MX7)
/*!
* Secure memory run command
*
@ -25,10 +25,14 @@ uint32_t secmem_set_cmd(uint32_t sec_mem_cmd)
{
uint32_t temp_reg;
sec_out32(CAAM_SMCJR0, sec_mem_cmd);
ccsr_sec_t *sec = (void *)CONFIG_SYS_FSL_SEC_ADDR;
uint32_t sm_vid = SM_VERSION(sec_in32(&sec->smvid));
uint32_t jr_id = 0;
sec_out32(CAAM_SMCJR(sm_vid, jr_id), sec_mem_cmd);
do {
temp_reg = sec_in32(CAAM_SMCSJR0);
temp_reg = sec_in32(CAAM_SMCSJR(sm_vid, jr_id));
} while (temp_reg & CMD_COMPLETE);
return temp_reg;
@ -51,6 +55,10 @@ int caam_page_alloc(uint8_t page_num, uint8_t partition_num)
{
uint32_t temp_reg;
ccsr_sec_t *sec = (void *)CONFIG_SYS_FSL_SEC_ADDR;
uint32_t sm_vid = SM_VERSION(sec_in32(&sec->smvid));
uint32_t jr_id = 0;
/*
* De-Allocate partition_num if already allocated to ARM core
*/
@ -64,9 +72,9 @@ int caam_page_alloc(uint8_t page_num, uint8_t partition_num)
}
/* set the access rights to allow full access */
sec_out32(CAAM_SMAG1JR0(partition_num), 0xF);
sec_out32(CAAM_SMAG2JR0(partition_num), 0xF);
sec_out32(CAAM_SMAPJR0(partition_num), 0xFF);
sec_out32(CAAM_SMAG1JR(sm_vid, jr_id, partition_num), 0xF);
sec_out32(CAAM_SMAG2JR(sm_vid, jr_id, partition_num), 0xF);
sec_out32(CAAM_SMAPJR(sm_vid, jr_id, partition_num), 0xFF);
/* Now need to allocate partition_num of secure RAM. */
/* De-Allocate page_num by starting with a page inquiry command */
@ -105,6 +113,10 @@ int caam_page_alloc(uint8_t page_num, uint8_t partition_num)
int inline_cnstr_jobdesc_blob_dek(uint32_t *desc, const uint8_t *plain_txt,
uint8_t *dek_blob, uint32_t in_sz)
{
ccsr_sec_t *sec = (void *)CONFIG_SYS_FSL_SEC_ADDR;
uint32_t sm_vid = SM_VERSION(sec_in32(&sec->smvid));
uint32_t jr_id = 0;
uint32_t ret = 0;
u32 aad_w1, aad_w2;
/* output blob will have 32 bytes key blob in beginning and
@ -133,9 +145,9 @@ int inline_cnstr_jobdesc_blob_dek(uint32_t *desc, const uint8_t *plain_txt,
flush_dcache_range(start, end);
/* Now configure the access rights of the partition */
sec_out32(CAAM_SMAG1JR0(PARTITION_1), KS_G1); /* set group 1 */
sec_out32(CAAM_SMAG2JR0(PARTITION_1), 0); /* clear group 2 */
sec_out32(CAAM_SMAPJR0(PARTITION_1), PERM); /* set perm & locks */
sec_out32(CAAM_SMAG1JR(sm_vid, jr_id, PARTITION_1), KS_G1);
sec_out32(CAAM_SMAG2JR(sm_vid, jr_id, PARTITION_1), 0);
sec_out32(CAAM_SMAPJR(sm_vid, jr_id, PARTITION_1), PERM);
/* construct aad for AES */
aad_w1 = (in_sz << OP_ALG_ALGSEL_SHIFT) | KEY_AES_SRC | LD_CCM_MODE;

View File

@ -143,6 +143,7 @@ config PIC32_PINCTRL
endif
source "drivers/pinctrl/nxp/Kconfig"
source "drivers/pinctrl/uniphier/Kconfig"
endmenu

View File

@ -5,6 +5,7 @@
obj-y += pinctrl-uclass.o
obj-$(CONFIG_$(SPL_)PINCTRL_GENERIC) += pinctrl-generic.o
obj-y += nxp/
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
obj-$(CONFIG_PINCTRL_SANDBOX) += pinctrl-sandbox.o

View File

@ -0,0 +1,30 @@
config PINCTRL_IMX
bool
config PINCTRL_IMX6
bool "IMX6 pinctrl driver"
depends on ARCH_MX6 && PINCTRL_FULL
select DEVRES
select PINCTRL_IMX
help
Say Y here to enable the imx6 pinctrl driver
This provides a simple pinctrl driver for i.MX6 SoC familiy,
i.MX6DQ/SL/SX/UL/DQP. This feature depends on device tree
configuration. This driver is different from the linux one,
this is a simple implementation, only parses the 'fsl,pins'
property and configure related registers.
config PINCTRL_IMX7
bool "IMX7 pinctrl driver"
depends on ARCH_MX7 && PINCTRL_FULL
select DEVRES
select PINCTRL_IMX
help
Say Y here to enable the imx7 pinctrl driver
This provides a simple pinctrl driver for i.MX7 SoC familiy,
i.MX7D. This feature depends on device tree
configuration. This driver is different from the linux one,
this is a simple implementation, only parses the 'fsl,pins'
property and configure related registers.

View File

@ -0,0 +1,3 @@
obj-$(CONFIG_PINCTRL_IMX) += pinctrl-imx.o
obj-$(CONFIG_PINCTRL_IMX6) += pinctrl-imx6.o
obj-$(CONFIG_PINCTRL_IMX7) += pinctrl-imx7.o

View File

@ -0,0 +1,241 @@
/*
* Copyright (C) 2016 Peng Fan <van.freenix@gmail.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <mapmem.h>
#include <linux/io.h>
#include <linux/err.h>
#include <dm/device.h>
#include <dm/pinctrl.h>
#include "pinctrl-imx.h"
DECLARE_GLOBAL_DATA_PTR;
static int imx_pinctrl_set_state(struct udevice *dev, struct udevice *config)
{
struct imx_pinctrl_priv *priv = dev_get_priv(dev);
struct imx_pinctrl_soc_info *info = priv->info;
int node = config->of_offset;
const struct fdt_property *prop;
u32 *pin_data;
int npins, size, pin_size;
int mux_reg, conf_reg, input_reg, input_val, mux_mode, config_val;
int i, j = 0;
dev_dbg(dev, "%s: %s\n", __func__, config->name);
if (info->flags & SHARE_MUX_CONF_REG)
pin_size = SHARE_FSL_PIN_SIZE;
else
pin_size = FSL_PIN_SIZE;
prop = fdt_getprop(gd->fdt_blob, node, "fsl,pins", &size);
if (!prop) {
dev_err(dev, "No fsl,pins property in node %s\n", config->name);
return -EINVAL;
}
if (!size || size % pin_size) {
dev_err(dev, "Invalid fsl,pins property in node %s\n",
config->name);
return -EINVAL;
}
pin_data = devm_kzalloc(dev, size, 0);
if (!pin_data)
return -ENOMEM;
if (fdtdec_get_int_array(gd->fdt_blob, node, "fsl,pins",
pin_data, size >> 2)) {
dev_err(dev, "Error reading pin data.\n");
return -EINVAL;
}
npins = size / pin_size;
/*
* Refer to linux documentation for details:
* Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt
*/
for (i = 0; i < npins; i++) {
mux_reg = pin_data[j++];
if (!(info->flags & ZERO_OFFSET_VALID) && !mux_reg)
mux_reg = -1;
if (info->flags & SHARE_MUX_CONF_REG) {
conf_reg = mux_reg;
} else {
conf_reg = pin_data[j++];
if (!(info->flags & ZERO_OFFSET_VALID) && !conf_reg)
conf_reg = -1;
}
if ((mux_reg == -1) || (conf_reg == -1)) {
dev_err(dev, "Error mux_reg or conf_reg\n");
return -EINVAL;
}
input_reg = pin_data[j++];
mux_mode = pin_data[j++];
input_val = pin_data[j++];
config_val = pin_data[j++];
dev_dbg(dev, "mux_reg 0x%x, conf_reg 0x%x, input_reg 0x%x, "
"mux_mode 0x%x, input_val 0x%x, config_val 0x%x\n",
mux_reg, conf_reg, input_reg, mux_mode, input_val,
config_val);
if (config_val & IMX_PAD_SION)
mux_mode |= IOMUXC_CONFIG_SION;
config_val &= ~IMX_PAD_SION;
/* Set Mux */
if (info->flags & SHARE_MUX_CONF_REG) {
clrsetbits_le32(info->base + mux_reg, 0x7 << 20,
mux_mode << 20);
} else {
writel(mux_mode, info->base + mux_reg);
}
dev_dbg(dev, "write mux: offset 0x%x val 0x%x\n", mux_reg,
mux_mode);
/*
* Set select input
*
* If the select input value begins with 0xff, it's a quirky
* select input and the value should be interpreted as below.
* 31 23 15 7 0
* | 0xff | shift | width | select |
* It's used to work around the problem that the select
* input for some pin is not implemented in the select
* input register but in some general purpose register.
* We encode the select input value, width and shift of
* the bit field into input_val cell of pin function ID
* in device tree, and then decode them here for setting
* up the select input bits in general purpose register.
*/
if (input_val >> 24 == 0xff) {
u32 val = input_val;
u8 select = val & 0xff;
u8 width = (val >> 8) & 0xff;
u8 shift = (val >> 16) & 0xff;
u32 mask = ((1 << width) - 1) << shift;
/*
* The input_reg[i] here is actually some IOMUXC general
* purpose register, not regular select input register.
*/
val = readl(info->base + input_reg);
val &= ~mask;
val |= select << shift;
writel(val, info->base + input_reg);
} else if (input_reg) {
/*
* Regular select input register can never be at offset
* 0, and we only print register value for regular case.
*/
if (info->input_sel_base)
writel(input_val, info->input_sel_base +
input_reg);
else
writel(input_val, info->base + input_reg);
dev_dbg(dev, "select_input: offset 0x%x val 0x%x\n",
input_reg, input_val);
}
/* Set config */
if (!(config_val & IMX_NO_PAD_CTL)) {
if (info->flags & SHARE_MUX_CONF_REG) {
clrsetbits_le32(info->base + conf_reg, 0xffff,
config_val);
} else {
writel(config_val, info->base + conf_reg);
}
dev_dbg(dev, "write config: offset 0x%x val 0x%x\n",
conf_reg, config_val);
}
}
return 0;
}
const struct pinctrl_ops imx_pinctrl_ops = {
.set_state = imx_pinctrl_set_state,
};
int imx_pinctrl_probe(struct udevice *dev,
struct imx_pinctrl_soc_info *info)
{
struct imx_pinctrl_priv *priv = dev_get_priv(dev);
int node = dev->of_offset, ret;
struct fdtdec_phandle_args arg;
fdt_addr_t addr;
fdt_size_t size;
if (!info) {
dev_err(dev, "wrong pinctrl info\n");
return -EINVAL;
}
priv->dev = dev;
priv->info = info;
addr = fdtdec_get_addr_size(gd->fdt_blob, dev->of_offset, "reg", &size);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
info->base = map_sysmem(addr, size);
if (!info->base)
return -ENOMEM;
priv->info = info;
/*
* Refer to linux documentation for details:
* Documentation/devicetree/bindings/pinctrl/fsl,imx7d-pinctrl.txt
*/
if (fdtdec_get_bool(gd->fdt_blob, node, "fsl,input-sel")) {
ret = fdtdec_parse_phandle_with_args(gd->fdt_blob,
node, "fsl,input-sel",
NULL, 0, 0, &arg);
if (ret) {
dev_err(dev, "iomuxc fsl,input-sel property not found\n");
return -EINVAL;
}
addr = fdtdec_get_addr_size(gd->fdt_blob, arg.node, "reg",
&size);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
info->input_sel_base = map_sysmem(addr, size);
if (!info->input_sel_base)
return -ENOMEM;
}
dev_info(dev, "initialized IMX pinctrl driver\n");
return 0;
}
int imx_pinctrl_remove(struct udevice *dev)
{
struct imx_pinctrl_priv *priv = dev_get_priv(dev);
struct imx_pinctrl_soc_info *info = priv->info;
if (info->input_sel_base)
unmap_sysmem(info->input_sel_base);
if (info->base)
unmap_sysmem(info->base);
return 0;
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (C) 2016 Peng Fan <van.freenix@gmail.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __DRIVERS_PINCTRL_IMX_H
#define __DRIVERS_PINCTRL_IMX_H
/**
* @base: the address to the controller in virtual memory
* @input_sel_base: the address of the select input in virtual memory.
* @flags: flags specific for each soc
*/
struct imx_pinctrl_soc_info {
void __iomem *base;
void __iomem *input_sel_base;
unsigned int flags;
};
/**
* @dev: a pointer back to containing device
* @info: the soc info
*/
struct imx_pinctrl_priv {
struct udevice *dev;
struct imx_pinctrl_soc_info *info;
};
extern const struct pinctrl_ops imx_pinctrl_ops;
#define IMX_NO_PAD_CTL 0x80000000 /* no pin config need */
#define IMX_PAD_SION 0x40000000 /* set SION */
/*
* Each pin represented in fsl,pins consists of 5 u32 PIN_FUNC_ID and
* 1 u32 CONFIG, so 24 types in total for each pin.
*/
#define FSL_PIN_SIZE 24
#define SHARE_FSL_PIN_SIZE 20
#define SHARE_MUX_CONF_REG 0x1
#define ZERO_OFFSET_VALID 0x2
#define IOMUXC_CONFIG_SION (0x1 << 4)
int imx_pinctrl_probe(struct udevice *dev, struct imx_pinctrl_soc_info *info);
int imx_pinctrl_remove(struct udevice *dev);
#endif /* __DRIVERS_PINCTRL_IMX_H */

View File

@ -0,0 +1,41 @@
/*
* Copyright (C) 2016 Peng Fan <van.freenix@gmail.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <dm/device.h>
#include <dm/pinctrl.h>
#include "pinctrl-imx.h"
static struct imx_pinctrl_soc_info imx6_pinctrl_soc_info;
static int imx6_pinctrl_probe(struct udevice *dev)
{
struct imx_pinctrl_soc_info *info =
(struct imx_pinctrl_soc_info *)dev_get_driver_data(dev);
return imx_pinctrl_probe(dev, info);
}
static const struct udevice_id imx6_pinctrl_match[] = {
{ .compatible = "fsl,imx6q-iomuxc", .data = (ulong)&imx6_pinctrl_soc_info },
{ .compatible = "fsl,imx6dl-iomuxc", .data = (ulong)&imx6_pinctrl_soc_info },
{ .compatible = "fsl,imx6sl-iomuxc", .data = (ulong)&imx6_pinctrl_soc_info },
{ .compatible = "fsl,imx6sx-iomuxc", .data = (ulong)&imx6_pinctrl_soc_info },
{ .compatible = "fsl,imx6ul-iomuxc", .data = (ulong)&imx6_pinctrl_soc_info },
{ /* sentinel */ }
};
U_BOOT_DRIVER(imx6_pinctrl) = {
.name = "imx6-pinctrl",
.id = UCLASS_PINCTRL,
.of_match = of_match_ptr(imx6_pinctrl_match),
.probe = imx6_pinctrl_probe,
.remove = imx_pinctrl_remove,
.priv_auto_alloc_size = sizeof(struct imx_pinctrl_priv),
.ops = &imx_pinctrl_ops,
.flags = DM_FLAG_PRE_RELOC,
};

View File

@ -0,0 +1,41 @@
/*
* Copyright (C) 2016 Peng Fan <van.freenix@gmail.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <dm/device.h>
#include <dm/pinctrl.h>
#include "pinctrl-imx.h"
static struct imx_pinctrl_soc_info imx7_pinctrl_soc_info;
static struct imx_pinctrl_soc_info imx7_lpsr_pinctrl_soc_info = {
.flags = ZERO_OFFSET_VALID,
};
static int imx7_pinctrl_probe(struct udevice *dev)
{
struct imx_pinctrl_soc_info *info =
(struct imx_pinctrl_soc_info *)dev_get_driver_data(dev);
return imx_pinctrl_probe(dev, info);
}
static const struct udevice_id imx7_pinctrl_match[] = {
{ .compatible = "fsl,imx7d-iomuxc", .data = (ulong)&imx7_pinctrl_soc_info },
{ .compatible = "fsl,imx7d-iomuxc-lpsr", .data = (ulong)&imx7_lpsr_pinctrl_soc_info },
{ /* sentinel */ }
};
U_BOOT_DRIVER(imx7_pinctrl) = {
.name = "imx7-pinctrl",
.id = UCLASS_PINCTRL,
.of_match = of_match_ptr(imx7_pinctrl_match),
.probe = imx7_pinctrl_probe,
.remove = imx_pinctrl_remove,
.priv_auto_alloc_size = sizeof(struct imx_pinctrl_priv),
.ops = &imx_pinctrl_ops,
.flags = DM_FLAG_PRE_RELOC,
};

View File

@ -26,7 +26,31 @@
#define CONFIG_MXC_UART
#define CONFIG_MXC_UART_BASE UART1_BASE
#ifdef CONFIG_IMX_BOOTAUX
/* Set to QSPI2 B flash at default */
#define CONFIG_SYS_AUXCORE_BOOTDATA 0x78000000
#define CONFIG_CMD_SETEXPR
#define UPDATE_M4_ENV \
"m4image=m4_qspi.bin\0" \
"loadm4image=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${m4image}\0" \
"update_m4_from_sd=" \
"if sf probe 1:0; then " \
"if run loadm4image; then " \
"setexpr fw_sz ${filesize} + 0xffff; " \
"setexpr fw_sz ${fw_sz} / 0x10000; " \
"setexpr fw_sz ${fw_sz} * 0x10000; " \
"sf erase 0x0 ${fw_sz}; " \
"sf write ${loadaddr} 0x0 ${filesize}; " \
"fi; " \
"fi\0" \
"m4boot=sf probe 1:0; bootaux "__stringify(CONFIG_SYS_AUXCORE_BOOTDATA)"\0"
#else
#define UPDATE_M4_ENV ""
#endif
#define CONFIG_EXTRA_ENV_SETTINGS \
UPDATE_M4_ENV \
"script=boot.scr\0" \
"image=zImage\0" \
"console=ttymxc0\0" \

View File

@ -195,6 +195,7 @@
#define CONFIG_CMD_CACHE
#endif
#define CONFIG_FSL_QSPI
#ifdef CONFIG_FSL_QSPI
#define CONFIG_CMD_SF
#define CONFIG_SPI_FLASH

View File

@ -57,6 +57,29 @@
#define CONFIG_SUPPORT_EMMC_BOOT /* eMMC specific */
#define CONFIG_SYS_MMC_IMG_LOAD_PART 1
#ifdef CONFIG_IMX_BOOTAUX
/* Set to QSPI1 A flash at default */
#define CONFIG_SYS_AUXCORE_BOOTDATA 0x60000000
#define CONFIG_CMD_SETEXPR
#define UPDATE_M4_ENV \
"m4image=m4_qspi.bin\0" \
"loadm4image=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${m4image}\0" \
"update_m4_from_sd=" \
"if sf probe 0:0; then " \
"if run loadm4image; then " \
"setexpr fw_sz ${filesize} + 0xffff; " \
"setexpr fw_sz ${fw_sz} / 0x10000; " \
"setexpr fw_sz ${fw_sz} * 0x10000; " \
"sf erase 0x0 ${fw_sz}; " \
"sf write ${loadaddr} 0x0 ${filesize}; " \
"fi; " \
"fi\0" \
"m4boot=sf probe 0:0; bootaux "__stringify(CONFIG_SYS_AUXCORE_BOOTDATA)"\0"
#else
#define UPDATE_M4_ENV ""
#endif
#define CONFIG_MFG_ENV_SETTINGS \
"mfgtool_args=setenv bootargs console=${console},${baudrate} " \
"rdinit=/linuxrc " \
@ -76,6 +99,7 @@
"rootfs part 0 2\0" \
#define CONFIG_EXTRA_ENV_SETTINGS \
UPDATE_M4_ENV \
CONFIG_MFG_ENV_SETTINGS \
CONFIG_DFU_ENV_SETTINGS \
"script=boot.scr\0" \

View File

@ -176,8 +176,8 @@
/* Environment organization */
#define CONFIG_ENV_IS_IN_MMC
#define CONFIG_SYS_MMC_ENV_DEV 2
#define CONFIG_SYS_MMC_ENV_PART 1
#define CONFIG_SYS_MMC_ENV_DEV 2 /* overwritten on SD boot */
#define CONFIG_SYS_MMC_ENV_PART 1 /* overwritten on SD boot */
#define CONFIG_ENV_SIZE (8 * 1024)
#define CONFIG_ENV_OFFSET (384 * 1024)
#define CONFIG_ENV_OVERWRITE

View File

@ -97,19 +97,20 @@ typedef struct ccsr_sec {
u32 drr; /* DECO Reset Register */
u8 res5[0x4d8];
struct rng4tst rng; /* RNG Registers */
u8 res11[0x8a0];
u8 res6[0x8a0];
u32 crnr_ms; /* CHA Revision Number Register, MS */
u32 crnr_ls; /* CHA Revision Number Register, LS */
u32 ctpr_ms; /* Compile Time Parameters Register, MS */
u32 ctpr_ls; /* Compile Time Parameters Register, LS */
u8 res6[0x10];
u8 res7[0x10];
u32 far_ms; /* Fault Address Register, MS */
u32 far_ls; /* Fault Address Register, LS */
u32 falr; /* Fault Address LIODN Register */
u32 fadr; /* Fault Address Detail Register */
u8 res7[0x4];
u8 res8[0x4];
u32 csta; /* CAAM Status Register */
u8 res8[0x8];
u32 smpart; /* Secure Memory Partition Parameters */
u32 smvid; /* Secure Memory Version ID */
u32 rvid; /* Run Time Integrity Checking Version ID Reg.*/
u32 ccbvid; /* CHA Cluster Block Version ID Register */
u32 chavid_ms; /* CHA Version ID Register, MS */
@ -147,7 +148,8 @@ typedef struct ccsr_sec {
#define CONFIG_JRSTARTR_JR0 0x00000001
struct jr_regs {
#if defined(CONFIG_SYS_FSL_SEC_LE) && !defined(CONFIG_MX6)
#if defined(CONFIG_SYS_FSL_SEC_LE) && \
!(defined(CONFIG_MX6) || defined(CONFIG_MX7))
u32 irba_l;
u32 irba_h;
#else
@ -160,7 +162,8 @@ struct jr_regs {
u32 irsa;
u32 rsvd3;
u32 irja;
#if defined(CONFIG_SYS_FSL_SEC_LE) && !defined(CONFIG_MX6)
#if defined(CONFIG_SYS_FSL_SEC_LE) && \
!(defined(CONFIG_MX6) || defined(CONFIG_MX7))
u32 orba_l;
u32 orba_h;
#else
@ -192,7 +195,8 @@ struct jr_regs {
* related information
*/
struct sg_entry {
#if defined(CONFIG_SYS_FSL_SEC_LE) && !defined(CONFIG_MX6)
#if defined(CONFIG_SYS_FSL_SEC_LE) && \
!(defined(CONFIG_MX6) || defined(CONFIG_MX7))
uint32_t addr_lo; /* Memory Address - lo */
uint32_t addr_hi; /* Memory Address of start of buffer - hi */
#else
@ -211,26 +215,43 @@ struct sg_entry {
#define SG_ENTRY_OFFSET_SHIFT 0
};
#ifdef CONFIG_MX6
#if defined(CONFIG_MX6) || defined(CONFIG_MX7)
/* Job Ring Base Address */
#define JR_BASE_ADDR(x) (CONFIG_SYS_FSL_SEC_ADDR + 0x1000 * (x + 1))
/* Secure Memory Offset varies accross versions */
#define SM_V1_OFFSET 0x0f4
#define SM_V2_OFFSET 0xa00
/*Secure Memory Versioning */
#define SMVID_V2 0x20105
#define SM_VERSION(x) (x < SMVID_V2 ? 1 : 2)
#define SM_OFFSET(x) (x == 1 ? SM_V1_OFFSET : SM_V2_OFFSET)
/* CAAM Job Ring 0 Registers */
/* Secure Memory Partition Owner register */
#define SMCSJR_PO (3 << 6)
/* JR Allocation Error */
#define SMCSJR_AERR (3 << 12)
/* Secure memory partition 0 page 0 owner register */
#define CAAM_SMPO_0 CONFIG_SYS_FSL_SEC_ADDR + 0x1FBC
#define CAAM_SMPO_0 (CONFIG_SYS_FSL_SEC_ADDR + 0x1FBC)
/* Secure memory command register */
#define CAAM_SMCJR0 CONFIG_SYS_FSL_SEC_ADDR + 0x10f4
#define CAAM_SMCJR(v, jr) (JR_BASE_ADDR(jr) + SM_OFFSET(v) + SM_CMD(v))
/* Secure memory command status register */
#define CAAM_SMCSJR0 CONFIG_SYS_FSL_SEC_ADDR + 0x10fc
#define CAAM_SMCSJR(v, jr) (JR_BASE_ADDR(jr) + SM_OFFSET(v) + SM_STATUS(v))
/* Secure memory access permissions register */
#define CAAM_SMAPJR0(y) (CONFIG_SYS_FSL_SEC_ADDR + 0x1104 + y*16)
#define CAAM_SMAPJR(v, jr, y) \
(JR_BASE_ADDR(jr) + SM_OFFSET(v) + SM_PERM(v) + y * 16)
/* Secure memory access group 2 register */
#define CAAM_SMAG2JR0(y) (CONFIG_SYS_FSL_SEC_ADDR + 0x1108 + y*16)
#define CAAM_SMAG2JR(v, jr, y) \
(JR_BASE_ADDR(jr) + SM_OFFSET(v) + SM_GROUP2(v) + y * 16)
/* Secure memory access group 1 register */
#define CAAM_SMAG1JR0(y) (CONFIG_SYS_FSL_SEC_ADDR + 0x110C + y*16)
#define CAAM_SMAG1JR(v, jr, y) \
(JR_BASE_ADDR(jr) + SM_OFFSET(v) + SM_GROUP1(v) + y * 16)
/* Commands and macros for secure memory */
#define SM_CMD(v) (v == 1 ? 0x0 : 0x1E4)
#define SM_STATUS(v) (v == 1 ? 0x8 : 0x1EC)
#define SM_PERM(v) (v == 1 ? 0x10 : 0x4)
#define SM_GROUP2(v) (v == 1 ? 0x14 : 0x8)
#define SM_GROUP1(v) (v == 1 ? 0x18 : 0xC)
#define CMD_PAGE_ALLOC 0x1
#define CMD_PAGE_DEALLOC 0x2
#define CMD_PART_DEALLOC 0x3

View File

@ -7,7 +7,6 @@
* SPDX-License-Identifier: GPL-2.0+
*/
#include <endian.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>