2015-09-02 18:54:19 +00:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2015 Freescale Semiconductor, Inc.
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: GPL-2.0+
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <common.h>
|
|
|
|
#include <asm/io.h>
|
|
|
|
#include <asm/arch/imx-regs.h>
|
|
|
|
#include <asm/arch/clock.h>
|
|
|
|
#include <asm/arch/sys_proto.h>
|
2017-06-29 08:16:06 +00:00
|
|
|
#include <asm/mach-imx/boot_mode.h>
|
|
|
|
#include <asm/mach-imx/dma.h>
|
|
|
|
#include <asm/mach-imx/hab.h>
|
|
|
|
#include <asm/mach-imx/rdc-sema.h>
|
imx: mx7d: isolate resources to domain 0 for A7 core
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. We will have a risk that, if A7 enter wait,
M4 enter stop, peripheral will have chance to get ipg_stop and ipg_wait
asserted same time. Also if M4 enters stop mode, A7 will have no
chance to access the peripheral.
There are 26 peripherals affected 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:
The solution is to set the peripherals to Domain0 by A core, since A core
in Domain0. The peripherals which will be used by M4, will be set to Domain1
by M4.
For example, A core set WDOG4 to domain0, but when M4 boots up, M4 will
set WDOG4 to domain1, because M4 will use WDOG4.
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 image will set the M4 to domain 1 and
set peripheral which it will use to domain 1.
This patch enables the CONFIG_IMX_RDC and CONFIG_IMX_BOOTAUX for
i.MX7D SABRESD board, and setup the 26 IP resources to domain 0.
Signed-off-by: Ye.Li <ye.li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
2016-01-28 08:55:09 +00:00
|
|
|
#include <asm/arch/imx-rdc.h>
|
2015-09-02 18:54:19 +00:00
|
|
|
#include <asm/arch/crm_regs.h>
|
|
|
|
#include <dm.h>
|
|
|
|
#include <imx_thermal.h>
|
2018-01-26 16:27:58 +00:00
|
|
|
#include <fsl_sec.h>
|
2015-09-02 18:54:19 +00:00
|
|
|
|
|
|
|
#if defined(CONFIG_IMX_THERMAL)
|
|
|
|
static const struct imx_thermal_plat imx7_thermal_plat = {
|
|
|
|
.regs = (void *)ANATOP_BASE_ADDR,
|
|
|
|
.fuse_bank = 3,
|
|
|
|
.fuse_word = 3,
|
|
|
|
};
|
|
|
|
|
|
|
|
U_BOOT_DEVICE(imx7_thermal) = {
|
|
|
|
.name = "imx_thermal",
|
|
|
|
.platdata = &imx7_thermal_plat,
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2017-08-12 14:10:57 +00:00
|
|
|
#if CONFIG_IS_ENABLED(IMX_RDC)
|
imx: mx7d: isolate resources to domain 0 for A7 core
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. We will have a risk that, if A7 enter wait,
M4 enter stop, peripheral will have chance to get ipg_stop and ipg_wait
asserted same time. Also if M4 enters stop mode, A7 will have no
chance to access the peripheral.
There are 26 peripherals affected 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:
The solution is to set the peripherals to Domain0 by A core, since A core
in Domain0. The peripherals which will be used by M4, will be set to Domain1
by M4.
For example, A core set WDOG4 to domain0, but when M4 boots up, M4 will
set WDOG4 to domain1, because M4 will use WDOG4.
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 image will set the M4 to domain 1 and
set peripheral which it will use to domain 1.
This patch enables the CONFIG_IMX_RDC and CONFIG_IMX_BOOTAUX for
i.MX7D SABRESD board, and setup the 26 IP resources to domain 0.
Signed-off-by: Ye.Li <ye.li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
2016-01-28 08:55:09 +00:00
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
|
2015-10-12 18:48:13 +00:00
|
|
|
#if defined(CONFIG_SECURE_BOOT)
|
|
|
|
struct imx_sec_config_fuse_t const imx_sec_config_fuse = {
|
|
|
|
.bank = 1,
|
|
|
|
.word = 3,
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2016-02-28 15:33:17 +00:00
|
|
|
static bool is_mx7d(void)
|
|
|
|
{
|
|
|
|
struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
|
|
|
|
struct fuse_bank *bank = &ocotp->bank[1];
|
|
|
|
struct fuse_bank1_regs *fuse =
|
|
|
|
(struct fuse_bank1_regs *)bank->fuse_regs;
|
|
|
|
int val;
|
|
|
|
|
|
|
|
val = readl(&fuse->tester4);
|
|
|
|
if (val & 1)
|
|
|
|
return false;
|
|
|
|
else
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-09-02 18:54:19 +00:00
|
|
|
u32 get_cpu_rev(void)
|
|
|
|
{
|
|
|
|
struct mxc_ccm_anatop_reg *ccm_anatop = (struct mxc_ccm_anatop_reg *)
|
|
|
|
ANATOP_BASE_ADDR;
|
|
|
|
u32 reg = readl(&ccm_anatop->digprog);
|
|
|
|
u32 type = (reg >> 16) & 0xff;
|
|
|
|
|
2016-02-28 15:33:17 +00:00
|
|
|
if (!is_mx7d())
|
|
|
|
type = MXC_CPU_MX7S;
|
|
|
|
|
2015-09-02 18:54:19 +00:00
|
|
|
reg &= 0xff;
|
|
|
|
return (type << 12) | reg;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef CONFIG_REVISION_TAG
|
|
|
|
u32 __weak get_board_rev(void)
|
|
|
|
{
|
|
|
|
return get_cpu_rev();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-10-23 02:13:04 +00:00
|
|
|
/* enable all periherial can be accessed in nosec mode */
|
|
|
|
static void init_csu(void)
|
|
|
|
{
|
|
|
|
int i = 0;
|
|
|
|
for (i = 0; i < CSU_NUM_REGS; i++)
|
|
|
|
writel(CSU_INIT_SEC_LEVEL0, CSU_IPS_BASE_ADDR + i * 4);
|
|
|
|
}
|
|
|
|
|
2016-01-04 05:16:41 +00:00
|
|
|
static void imx_enet_mdio_fixup(void)
|
|
|
|
{
|
|
|
|
struct iomuxc_gpr_base_regs *gpr_regs =
|
|
|
|
(struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The management data input/output (MDIO) requires open-drain,
|
|
|
|
* i.MX7D TO1.0 ENET MDIO pin has no open drain, but TO1.1 supports
|
|
|
|
* this feature. So to TO1.1, need to enable open drain by setting
|
|
|
|
* bits GPR0[8:7].
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (soc_rev() >= CHIP_REV_1_1) {
|
|
|
|
setbits_le32(&gpr_regs->gpr[0],
|
|
|
|
IOMUXC_GPR_GPR0_ENET_MDIO_OPEN_DRAIN_MASK);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-02 18:54:19 +00:00
|
|
|
int arch_cpu_init(void)
|
|
|
|
{
|
|
|
|
init_aips();
|
|
|
|
|
2015-10-23 02:13:04 +00:00
|
|
|
init_csu();
|
2015-09-02 18:54:19 +00:00
|
|
|
/* Disable PDE bit of WMCR register */
|
2017-11-23 12:55:33 +00:00
|
|
|
imx_wdog_disable_powerdown();
|
2015-09-02 18:54:19 +00:00
|
|
|
|
2016-01-04 05:16:41 +00:00
|
|
|
imx_enet_mdio_fixup();
|
|
|
|
|
2015-09-02 18:54:19 +00:00
|
|
|
#ifdef CONFIG_APBH_DMA
|
|
|
|
/* Start APBH DMA */
|
|
|
|
mxs_dma_init();
|
|
|
|
#endif
|
|
|
|
|
2017-08-12 14:10:57 +00:00
|
|
|
#if CONFIG_IS_ENABLED(IMX_RDC)
|
|
|
|
isolate_resource();
|
|
|
|
#endif
|
imx: mx7d: isolate resources to domain 0 for A7 core
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. We will have a risk that, if A7 enter wait,
M4 enter stop, peripheral will have chance to get ipg_stop and ipg_wait
asserted same time. Also if M4 enters stop mode, A7 will have no
chance to access the peripheral.
There are 26 peripherals affected 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:
The solution is to set the peripherals to Domain0 by A core, since A core
in Domain0. The peripherals which will be used by M4, will be set to Domain1
by M4.
For example, A core set WDOG4 to domain0, but when M4 boots up, M4 will
set WDOG4 to domain1, because M4 will use WDOG4.
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 image will set the M4 to domain 1 and
set peripheral which it will use to domain 1.
This patch enables the CONFIG_IMX_RDC and CONFIG_IMX_BOOTAUX for
i.MX7D SABRESD board, and setup the 26 IP resources to domain 0.
Signed-off-by: Ye.Li <ye.li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
2016-01-28 08:55:09 +00:00
|
|
|
|
2015-09-02 18:54:19 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-07-13 07:25:39 +00:00
|
|
|
#ifdef CONFIG_ARCH_MISC_INIT
|
|
|
|
int arch_misc_init(void)
|
|
|
|
{
|
|
|
|
#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
|
|
|
|
if (is_mx7d())
|
2017-08-03 18:22:09 +00:00
|
|
|
env_set("soc", "imx7d");
|
2016-07-13 07:25:39 +00:00
|
|
|
else
|
2017-08-03 18:22:09 +00:00
|
|
|
env_set("soc", "imx7s");
|
2016-07-13 07:25:39 +00:00
|
|
|
#endif
|
|
|
|
|
2018-01-26 16:27:58 +00:00
|
|
|
#ifdef CONFIG_FSL_CAAM
|
|
|
|
sec_init();
|
|
|
|
#endif
|
|
|
|
|
2016-07-13 07:25:39 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-09-02 18:54:19 +00:00
|
|
|
#ifdef CONFIG_SERIAL_TAG
|
|
|
|
void get_board_serial(struct tag_serialnr *serialnr)
|
|
|
|
{
|
|
|
|
struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
|
|
|
|
struct fuse_bank *bank = &ocotp->bank[0];
|
|
|
|
struct fuse_bank0_regs *fuse =
|
|
|
|
(struct fuse_bank0_regs *)bank->fuse_regs;
|
|
|
|
|
|
|
|
serialnr->low = fuse->tester0;
|
|
|
|
serialnr->high = fuse->tester1;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void set_wdog_reset(struct wdog_regs *wdog)
|
|
|
|
{
|
|
|
|
u32 reg = readw(&wdog->wcr);
|
|
|
|
/*
|
|
|
|
* Output WDOG_B signal to reset external pmic or POR_B decided by
|
|
|
|
* the board desgin. Without external reset, the peripherals/DDR/
|
|
|
|
* PMIC are not reset, that may cause system working abnormal.
|
|
|
|
*/
|
|
|
|
reg = readw(&wdog->wcr);
|
|
|
|
reg |= 1 << 3;
|
|
|
|
/*
|
|
|
|
* WDZST bit is write-once only bit. Align this bit in kernel,
|
|
|
|
* otherwise kernel code will have no chance to set this bit.
|
|
|
|
*/
|
|
|
|
reg |= 1 << 0;
|
|
|
|
writew(reg, &wdog->wcr);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* cfg_val will be used for
|
|
|
|
* Boot_cfg4[7:0]:Boot_cfg3[7:0]:Boot_cfg2[7:0]:Boot_cfg1[7:0]
|
|
|
|
* After reset, if GPR10[28] is 1, ROM will copy GPR9[25:0]
|
|
|
|
* to SBMR1, which will determine the boot device.
|
|
|
|
*/
|
|
|
|
const struct boot_mode soc_boot_modes[] = {
|
|
|
|
{"ecspi1:0", MAKE_CFGVAL(0x00, 0x60, 0x00, 0x00)},
|
|
|
|
{"ecspi1:1", MAKE_CFGVAL(0x40, 0x62, 0x00, 0x00)},
|
|
|
|
{"ecspi1:2", MAKE_CFGVAL(0x80, 0x64, 0x00, 0x00)},
|
|
|
|
{"ecspi1:3", MAKE_CFGVAL(0xc0, 0x66, 0x00, 0x00)},
|
|
|
|
|
|
|
|
{"weim", MAKE_CFGVAL(0x00, 0x50, 0x00, 0x00)},
|
|
|
|
{"qspi1", MAKE_CFGVAL(0x10, 0x40, 0x00, 0x00)},
|
|
|
|
/* 4 bit bus width */
|
|
|
|
{"usdhc1", MAKE_CFGVAL(0x10, 0x10, 0x00, 0x00)},
|
|
|
|
{"usdhc2", MAKE_CFGVAL(0x10, 0x14, 0x00, 0x00)},
|
|
|
|
{"usdhc3", MAKE_CFGVAL(0x10, 0x18, 0x00, 0x00)},
|
|
|
|
{"mmc1", MAKE_CFGVAL(0x10, 0x20, 0x00, 0x00)},
|
|
|
|
{"mmc2", MAKE_CFGVAL(0x10, 0x24, 0x00, 0x00)},
|
|
|
|
{"mmc3", MAKE_CFGVAL(0x10, 0x28, 0x00, 0x00)},
|
|
|
|
{NULL, 0},
|
|
|
|
};
|
|
|
|
|
|
|
|
void s_init(void)
|
|
|
|
{
|
|
|
|
#if !defined CONFIG_SPL_BUILD
|
|
|
|
/* Enable SMP mode for CPU0, by setting bit 6 of Auxiliary Ctl reg */
|
|
|
|
asm volatile(
|
|
|
|
"mrc p15, 0, r0, c1, c0, 1\n"
|
|
|
|
"orr r0, r0, #1 << 6\n"
|
|
|
|
"mcr p15, 0, r0, c1, c0, 1\n");
|
|
|
|
#endif
|
|
|
|
/* clock configuration. */
|
|
|
|
clock_init();
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
2016-05-19 05:02:16 +00:00
|
|
|
|
|
|
|
void reset_misc(void)
|
|
|
|
{
|
|
|
|
#ifdef CONFIG_VIDEO_MXS
|
|
|
|
lcdif_power_down();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|