commit
595af9db24
@ -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", |
||||
"" |
||||
); |
@ -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; |
||||
} |
@ -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__*/ |
@ -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__*/ |
@ -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__*/ |
@ -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__*/ |
@ -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__*/ |
@ -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. |
@ -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
|
@ -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; |
||||
} |
@ -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 */ |
@ -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, |
||||
}; |
@ -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, |
||||
}; |
Loading…
Reference in new issue