mirror of
https://github.com/AsahiLinux/u-boot
synced 2025-02-17 22:49:02 +00:00
arm: imx8m: add support for Compulab iot-gate-imx8 (imx8mm-cl-iot-gate)
Add initial support for Compulab iot-gate-imx8 board (imx8mm-cl-iot-gate). The initial support includes: - MMC - eMMC - I2C - FEC - Serial console Signed-off-by: Kirill Kapranov <kirill.kapranov@compulab.co.il> Signed-off-by: Uri Mashiach <uri.mashiach@compulab.co.il> Signed-off-by: Valentin Raevsky <valentin@compulab.co.il> Signed-off-by: Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org> Cc: Peter Robinson <pbrobinson@gmail.com>
This commit is contained in:
parent
8350211af4
commit
53b516c58d
16 changed files with 8289 additions and 0 deletions
|
@ -124,6 +124,13 @@ config TARGET_PHYCORE_IMX8MP
|
|||
select IMX8MP
|
||||
select SUPPORT_SPL
|
||||
select IMX8M_LPDDR4
|
||||
|
||||
config TARGET_IMX8MM_CL_IOT_GATE
|
||||
bool "CompuLab iot-gate-imx8"
|
||||
select BINMAN
|
||||
select IMX8MM
|
||||
select SUPPORT_SPL
|
||||
select IMX8M_LPDDR4
|
||||
endchoice
|
||||
|
||||
source "board/engicam/imx8mm/Kconfig"
|
||||
|
@ -139,5 +146,6 @@ source "board/beacon/imx8mm/Kconfig"
|
|||
source "board/beacon/imx8mn/Kconfig"
|
||||
source "board/phytec/phycore_imx8mm/Kconfig"
|
||||
source "board/phytec/phycore_imx8mp/Kconfig"
|
||||
source "board/compulab/imx8mm-cl-iot-gate/Kconfig"
|
||||
|
||||
endif
|
||||
|
|
12
board/compulab/imx8mm-cl-iot-gate/Kconfig
Normal file
12
board/compulab/imx8mm-cl-iot-gate/Kconfig
Normal file
|
@ -0,0 +1,12 @@
|
|||
if TARGET_IMX8MM_CL_IOT_GATE
|
||||
|
||||
config SYS_BOARD
|
||||
default "imx8mm-cl-iot-gate"
|
||||
|
||||
config SYS_VENDOR
|
||||
default "compulab"
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
default "imx8mm-cl-iot-gate"
|
||||
|
||||
endif
|
6
board/compulab/imx8mm-cl-iot-gate/MAINTAINERS
Normal file
6
board/compulab/imx8mm-cl-iot-gate/MAINTAINERS
Normal file
|
@ -0,0 +1,6 @@
|
|||
Compulab IOT-GATE-iMX8 BOARD
|
||||
M: Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
|
||||
S: Maintained
|
||||
F: board/compulab/imx8mm-cl-iot-gate/
|
||||
F: include/configs/imx8mm-cl-iot-gate.h
|
||||
F: configs/imx8mm-cl-iot-gate_defconfig
|
13
board/compulab/imx8mm-cl-iot-gate/Makefile
Normal file
13
board/compulab/imx8mm-cl-iot-gate/Makefile
Normal file
|
@ -0,0 +1,13 @@
|
|||
#
|
||||
# Copyright 2018 NXP
|
||||
# Copyright 2020 Linaro
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-y += imx8mm-cl-iot-gate.o
|
||||
|
||||
ifdef CONFIG_SPL_BUILD
|
||||
obj-y += spl.o
|
||||
obj-y += ddr/
|
||||
endif
|
8
board/compulab/imx8mm-cl-iot-gate/ddr/Makefile
Normal file
8
board/compulab/imx8mm-cl-iot-gate/ddr/Makefile
Normal file
|
@ -0,0 +1,8 @@
|
|||
obj-y += ddr.o
|
||||
obj-y += lpddr4_timing_ff020008.o
|
||||
obj-y += lpddr4_timing_ff000110.o
|
||||
ifdef CONFIG_TARGET_MCM_IMX8M_MINI
|
||||
obj-y += lpddr4_timing_01061010.o
|
||||
else
|
||||
obj-y += lpddr4_timing_01061010.1_2.o
|
||||
endif
|
211
board/compulab/imx8mm-cl-iot-gate/ddr/ddr.c
Normal file
211
board/compulab/imx8mm-cl-iot-gate/ddr/ddr.c
Normal file
|
@ -0,0 +1,211 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2017 NXP
|
||||
* Copyright 2020 Linaro
|
||||
*
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <spl.h>
|
||||
#include <asm/io.h>
|
||||
#include <errno.h>
|
||||
#include <command.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/lpddr4_define.h>
|
||||
#include <asm/mach-imx/iomux-v3.h>
|
||||
#include <asm/mach-imx/gpio.h>
|
||||
#include <asm-generic/gpio.h>
|
||||
#include <asm/arch/ddr.h>
|
||||
#include <asm/arch/imx8mq_pins.h>
|
||||
#include <asm/arch/sys_proto.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/mach-imx/gpio.h>
|
||||
#include "ddr.h"
|
||||
|
||||
static unsigned int lpddr4_mr_read(unsigned int mr_rank, unsigned int mr_addr)
|
||||
{
|
||||
unsigned int tmp;
|
||||
|
||||
reg32_write(DRC_PERF_MON_MRR0_DAT(0), 0x1);
|
||||
do {
|
||||
tmp = reg32_read(DDRC_MRSTAT(0));
|
||||
} while (tmp & 0x1);
|
||||
|
||||
reg32_write(DDRC_MRCTRL0(0), (mr_rank << 4) | 0x1);
|
||||
reg32_write(DDRC_MRCTRL1(0), (mr_addr << 8));
|
||||
reg32setbit(DDRC_MRCTRL0(0), 31);
|
||||
do {
|
||||
tmp = reg32_read(DRC_PERF_MON_MRR0_DAT(0));
|
||||
} while ((tmp & 0x8) == 0);
|
||||
tmp = reg32_read(DRC_PERF_MON_MRR1_DAT(0));
|
||||
reg32_write(DRC_PERF_MON_MRR0_DAT(0), 0x4);
|
||||
while (tmp) { //try to find a significant byte in the word
|
||||
if (tmp & 0xff) {
|
||||
tmp &= 0xff;
|
||||
break;
|
||||
}
|
||||
tmp >>= 8;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
struct lpddr4_desc {
|
||||
char name[16];
|
||||
unsigned int id;
|
||||
unsigned int size;
|
||||
unsigned int count;
|
||||
/* an optional field
|
||||
* use it if default is not the
|
||||
* 1-st array entry
|
||||
*/
|
||||
unsigned int _default;
|
||||
/* An optional field to distiguish DRAM chips that
|
||||
* have different geometry, though return the same MRR.
|
||||
* Default value 0xff
|
||||
*/
|
||||
u8 subind;
|
||||
struct dram_timing_info *timing;
|
||||
char *desc[4];
|
||||
};
|
||||
|
||||
#define DEFAULT (('D' << 24) + ('E' << 16) + ('F' << 8) + 'A')
|
||||
static const struct lpddr4_desc lpddr4_array[] = {
|
||||
{ .name = "Nanya", .id = 0x05000010, .subind = 0xff,
|
||||
.size = 2048, .count = 1, .timing = &ucm_dram_timing_01061010},
|
||||
{ .name = "Samsung", .id = 0x01061010, .subind = 0xff,
|
||||
.size = 2048, .count = 1, .timing = &ucm_dram_timing_01061010},
|
||||
{ .name = "Kingston", .id = 0xff000010, .subind = 0x04,
|
||||
.size = 4096, .count = 1, .timing = &ucm_dram_timing_ff000110},
|
||||
{ .name = "Kingston", .id = 0xff000010, .subind = 0x02,
|
||||
.size = 2048, .count = 1, .timing = &ucm_dram_timing_01061010},
|
||||
{ .name = "Micron", .id = 0xff020008, .subind = 0xff,
|
||||
.size = 2048, .count = 1, .timing = &ucm_dram_timing_ff020008},
|
||||
{ .name = "Micron", .id = 0xff000110, .subind = 0xff,
|
||||
.size = 4096, .count = 1, .timing = &ucm_dram_timing_ff000110},
|
||||
};
|
||||
|
||||
static unsigned int lpddr4_get_mr(void)
|
||||
{
|
||||
int i = 0, attempts = 5;
|
||||
unsigned int ddr_info = 0;
|
||||
unsigned int regs[] = { 5, 6, 7, 8 };
|
||||
|
||||
do {
|
||||
for (i = 0 ; i < ARRAY_SIZE(regs) ; i++) {
|
||||
unsigned int data = 0;
|
||||
|
||||
data = lpddr4_mr_read(0xF, regs[i]);
|
||||
ddr_info <<= 8;
|
||||
ddr_info += (data & 0xFF);
|
||||
}
|
||||
if (ddr_info != 0xFFFFFFFF && ddr_info != 0)
|
||||
break; // The attempt was successful
|
||||
} while (--attempts);
|
||||
return ddr_info;
|
||||
}
|
||||
|
||||
static void spl_tcm_init(struct lpddr4_tcm_desc *lpddr4_tcm_desc)
|
||||
{
|
||||
if (lpddr4_tcm_desc->sign == DEFAULT)
|
||||
return;
|
||||
|
||||
lpddr4_tcm_desc->sign = DEFAULT;
|
||||
lpddr4_tcm_desc->index = 0;
|
||||
}
|
||||
|
||||
static void spl_tcm_fini(struct lpddr4_tcm_desc *lpddr4_tcm_desc)
|
||||
{
|
||||
if (lpddr4_tcm_desc->sign != DEFAULT)
|
||||
return;
|
||||
|
||||
lpddr4_tcm_desc->sign = ~DEFAULT;
|
||||
lpddr4_tcm_desc->index = 0;
|
||||
}
|
||||
|
||||
#define SPL_TCM_DATA 0x7e0000
|
||||
#define SPL_TCM_INIT spl_tcm_init(lpddr4_tcm_desc)
|
||||
#define SPL_TCM_FINI spl_tcm_fini(lpddr4_tcm_desc)
|
||||
|
||||
void spl_dram_init_compulab(void)
|
||||
{
|
||||
unsigned int ddr_info = 0xdeadbeef;
|
||||
unsigned int ddr_info_mrr = 0xdeadbeef;
|
||||
unsigned int ddr_found = 0;
|
||||
int i = 0;
|
||||
|
||||
struct lpddr4_tcm_desc *lpddr4_tcm_desc =
|
||||
(struct lpddr4_tcm_desc *)SPL_TCM_DATA;
|
||||
|
||||
if (lpddr4_tcm_desc->sign != DEFAULT) {
|
||||
/* if not in tcm scan mode */
|
||||
for (i = 0; i < ARRAY_SIZE(lpddr4_array); i++) {
|
||||
if (lpddr4_array[i].id == ddr_info &&
|
||||
lpddr4_array[i].subind == 0xff) {
|
||||
ddr_found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Walk trought all available ddr ids and apply
|
||||
* one by one. Save the index at the tcm memory that
|
||||
* persists after the reset.
|
||||
*/
|
||||
if (ddr_found == 0) {
|
||||
SPL_TCM_INIT;
|
||||
|
||||
if (lpddr4_tcm_desc->index < ARRAY_SIZE(lpddr4_array)) {
|
||||
printf("DDRINFO: Cfg attempt: [ %d/%lu ]\n",
|
||||
lpddr4_tcm_desc->index + 1,
|
||||
ARRAY_SIZE(lpddr4_array));
|
||||
i = lpddr4_tcm_desc->index;
|
||||
lpddr4_tcm_desc->index += 1;
|
||||
} else {
|
||||
/* Ran out all available ddr setings */
|
||||
printf("DDRINFO: Ran out all [ %lu ] cfg attempts. A non supported configuration.\n",
|
||||
ARRAY_SIZE(lpddr4_array));
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
ddr_info = lpddr4_array[i].id;
|
||||
} else {
|
||||
printf("DDRINFO(%s): %s %dG\n", (ddr_found ? "D" : "?"),
|
||||
lpddr4_array[i].name,
|
||||
lpddr4_array[i].size);
|
||||
}
|
||||
|
||||
if (ddr_init(lpddr4_array[i].timing)) {
|
||||
SPL_TCM_INIT;
|
||||
do_reset(NULL, 0, 0, NULL);
|
||||
}
|
||||
|
||||
ddr_info_mrr = lpddr4_get_mr();
|
||||
if (ddr_info_mrr == 0xFFFFFFFF) {
|
||||
printf("DDRINFO(M): mr5-8 [ 0x%x ] is invalid; reset\n",
|
||||
ddr_info_mrr);
|
||||
SPL_TCM_INIT;
|
||||
do_reset(NULL, 0, 0, NULL);
|
||||
}
|
||||
|
||||
printf("DDRINFO(M): mr5-8 [ 0x%x ]\n", ddr_info_mrr);
|
||||
printf("DDRINFO(%s): mr5-8 [ 0x%x ]\n", (ddr_found ? "E" : "T"),
|
||||
ddr_info);
|
||||
|
||||
if (ddr_info_mrr != ddr_info) {
|
||||
SPL_TCM_INIT;
|
||||
do_reset(NULL, 0, 0, NULL);
|
||||
}
|
||||
|
||||
SPL_TCM_FINI;
|
||||
|
||||
/* Pass the dram size to th U-Boot through the tcm memory */
|
||||
{ /* To figure out what to store into the TCM buffer */
|
||||
/* For debug purpouse only. To override the real memsize */
|
||||
unsigned int ddr_tcm_size = 0;
|
||||
|
||||
if (ddr_tcm_size == 0 || ddr_tcm_size == -1)
|
||||
ddr_tcm_size = lpddr4_array[i].size;
|
||||
|
||||
lpddr4_tcm_desc->size = ddr_tcm_size;
|
||||
}
|
||||
}
|
26
board/compulab/imx8mm-cl-iot-gate/ddr/ddr.h
Normal file
26
board/compulab/imx8mm-cl-iot-gate/ddr/ddr.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2017 NXP
|
||||
* Copyright 2020 Linaro
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __COMPULAB_DDR_H__
|
||||
#define __COMPULAB_DDR_H__
|
||||
|
||||
extern struct dram_timing_info ucm_dram_timing_ff020008;
|
||||
extern struct dram_timing_info ucm_dram_timing_ff000110;
|
||||
extern struct dram_timing_info ucm_dram_timing_01061010;
|
||||
|
||||
void spl_dram_init_compulab(void);
|
||||
|
||||
#define TCM_DATA_CFG 0x7e0000
|
||||
|
||||
struct lpddr4_tcm_desc {
|
||||
unsigned int size;
|
||||
unsigned int sign;
|
||||
unsigned int index;
|
||||
unsigned int count;
|
||||
};
|
||||
|
||||
#endif
|
1848
board/compulab/imx8mm-cl-iot-gate/ddr/lpddr4_timing_01061010.1_2.c
Normal file
1848
board/compulab/imx8mm-cl-iot-gate/ddr/lpddr4_timing_01061010.1_2.c
Normal file
File diff suppressed because it is too large
Load diff
1847
board/compulab/imx8mm-cl-iot-gate/ddr/lpddr4_timing_01061010.c
Normal file
1847
board/compulab/imx8mm-cl-iot-gate/ddr/lpddr4_timing_01061010.c
Normal file
File diff suppressed because it is too large
Load diff
1847
board/compulab/imx8mm-cl-iot-gate/ddr/lpddr4_timing_ff000110.c
Normal file
1847
board/compulab/imx8mm-cl-iot-gate/ddr/lpddr4_timing_ff000110.c
Normal file
File diff suppressed because it is too large
Load diff
1847
board/compulab/imx8mm-cl-iot-gate/ddr/lpddr4_timing_ff020008.c
Normal file
1847
board/compulab/imx8mm-cl-iot-gate/ddr/lpddr4_timing_ff020008.c
Normal file
File diff suppressed because it is too large
Load diff
71
board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c
Normal file
71
board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c
Normal file
|
@ -0,0 +1,71 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2018 NXP
|
||||
* Copyright 2020 Linaro
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <env.h>
|
||||
#include <init.h>
|
||||
#include <miiphy.h>
|
||||
#include <netdev.h>
|
||||
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/sys_proto.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static int setup_fec(void)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_FEC_MXC)) {
|
||||
struct iomuxc_gpr_base_regs *gpr =
|
||||
(struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR;
|
||||
|
||||
/* Use 125M anatop REF_CLK1 for ENET1, not from external */
|
||||
clrsetbits_le32(&gpr->gpr[1], 0x2000, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_phy_config(struct phy_device *phydev)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_FEC_MXC)) {
|
||||
/* enable rgmii rxc skew and phy mode select to RGMII copper */
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f);
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8);
|
||||
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x00);
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x82ee);
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05);
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100);
|
||||
|
||||
if (phydev->drv->config)
|
||||
phydev->drv->config(phydev);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_FEC_MXC))
|
||||
setup_fec();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_mmc_get_env_dev(int devno)
|
||||
{
|
||||
return devno;
|
||||
}
|
||||
|
||||
int board_late_init(void)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG)) {
|
||||
env_set("board_name", "IOT-GATE-IMX8");
|
||||
env_set("board_rev", "SBC-IOTMX8");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2021 NXP
|
||||
*/
|
||||
|
||||
#define __ASSEMBLY__
|
||||
|
||||
BOOT_FROM sd
|
||||
LOADER mkimage.flash.mkimage 0x7E1000
|
187
board/compulab/imx8mm-cl-iot-gate/spl.c
Normal file
187
board/compulab/imx8mm-cl-iot-gate/spl.c
Normal file
|
@ -0,0 +1,187 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2019 NXP
|
||||
* Copyright 2020 Linaro
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <cpu_func.h>
|
||||
#include <hang.h>
|
||||
#include <image.h>
|
||||
#include <init.h>
|
||||
#include <log.h>
|
||||
#include <spl.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/mach-imx/iomux-v3.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/imx8mm_pins.h>
|
||||
#include <asm/arch/sys_proto.h>
|
||||
#include <asm/mach-imx/boot_mode.h>
|
||||
#include <asm/mach-imx/mxc_i2c.h>
|
||||
#include <asm/mach-imx/gpio.h>
|
||||
#include <asm/arch/ddr.h>
|
||||
|
||||
#include <dm/uclass.h>
|
||||
#include <dm/device.h>
|
||||
#include <dm/uclass-internal.h>
|
||||
#include <dm/device-internal.h>
|
||||
|
||||
#include <power/pmic.h>
|
||||
#include <power/bd71837.h>
|
||||
|
||||
#include "ddr/ddr.h"
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int spl_board_boot_device(enum boot_device boot_dev_spl)
|
||||
{
|
||||
switch (boot_dev_spl) {
|
||||
case SD2_BOOT:
|
||||
case MMC2_BOOT:
|
||||
return BOOT_DEVICE_MMC1;
|
||||
case SD3_BOOT:
|
||||
case MMC3_BOOT:
|
||||
return BOOT_DEVICE_MMC2;
|
||||
default:
|
||||
return BOOT_DEVICE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
#define I2C_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_HYS | PAD_CTL_PUE | PAD_CTL_PE)
|
||||
#define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
|
||||
struct i2c_pads_info i2c_pad_info1 = {
|
||||
.scl = {
|
||||
.i2c_mode = IMX8MM_PAD_I2C2_SCL_I2C2_SCL | PC,
|
||||
.gpio_mode = IMX8MM_PAD_I2C2_SCL_GPIO5_IO16 | PC,
|
||||
.gp = IMX_GPIO_NR(5, 16),
|
||||
},
|
||||
.sda = {
|
||||
.i2c_mode = IMX8MM_PAD_I2C2_SDA_I2C2_SDA | PC,
|
||||
.gpio_mode = IMX8MM_PAD_I2C2_SDA_GPIO5_IO17 | PC,
|
||||
.gp = IMX_GPIO_NR(5, 17),
|
||||
},
|
||||
};
|
||||
|
||||
static void spl_dram_init(void)
|
||||
{
|
||||
spl_dram_init_compulab();
|
||||
}
|
||||
|
||||
void spl_board_init(void)
|
||||
{
|
||||
puts("Normal Boot\n");
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SPL_LOAD_FIT
|
||||
int board_fit_config_name_match(const char *name)
|
||||
{
|
||||
/* Just empty function now - can't decide what to choose */
|
||||
debug("%s: %s\n", __func__, name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define UART_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_FSEL1)
|
||||
#define WDOG_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_ODE | PAD_CTL_PUE | PAD_CTL_PE)
|
||||
|
||||
static iomux_v3_cfg_t const uart_pads[] = {
|
||||
IMX8MM_PAD_UART3_RXD_UART3_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
|
||||
IMX8MM_PAD_UART3_TXD_UART3_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
|
||||
};
|
||||
|
||||
static iomux_v3_cfg_t const wdog_pads[] = {
|
||||
IMX8MM_PAD_GPIO1_IO02_WDOG1_WDOG_B | MUX_PAD_CTRL(WDOG_PAD_CTRL),
|
||||
};
|
||||
|
||||
int board_early_init_f(void)
|
||||
{
|
||||
struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR;
|
||||
|
||||
imx_iomux_v3_setup_multiple_pads(wdog_pads, ARRAY_SIZE(wdog_pads));
|
||||
|
||||
set_wdog_reset(wdog);
|
||||
|
||||
imx_iomux_v3_setup_multiple_pads(uart_pads, ARRAY_SIZE(uart_pads));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int power_init_board(void)
|
||||
{
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
|
||||
ret = pmic_get("pmic@4b", &dev);
|
||||
if (ret == -ENODEV) {
|
||||
puts("No pmic\n");
|
||||
return 0;
|
||||
}
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
/* decrease RESET key long push time from the default 10s to 10ms */
|
||||
pmic_reg_write(dev, BD718XX_PWRONCONFIG1, 0x0);
|
||||
|
||||
/* unlock the PMIC regs */
|
||||
pmic_reg_write(dev, BD718XX_REGLOCK, 0x1);
|
||||
|
||||
/* increase VDD_SOC to typical value 0.85v before first DRAM access */
|
||||
pmic_reg_write(dev, BD718XX_BUCK1_VOLT_RUN, 0x0f);
|
||||
|
||||
/* increase VDD_DRAM to 0.975v for 3Ghz DDR */
|
||||
pmic_reg_write(dev, BD718XX_1ST_NODVS_BUCK_VOLT, 0x83);
|
||||
|
||||
/* increase NVCC_DRAM_1V2 to 1.2v for DDR4 */
|
||||
pmic_reg_write(dev, BD718XX_4TH_NODVS_BUCK_VOLT, 0x28);
|
||||
|
||||
/* lock the PMIC regs */
|
||||
pmic_reg_write(dev, BD718XX_REGLOCK, 0x11);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void board_init_f(ulong dummy)
|
||||
{
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
|
||||
arch_cpu_init();
|
||||
|
||||
board_early_init_f();
|
||||
|
||||
init_uart_clk(2);
|
||||
|
||||
timer_init();
|
||||
|
||||
preloader_console_init();
|
||||
|
||||
/* Clear the BSS. */
|
||||
memset(__bss_start, 0, __bss_end - __bss_start);
|
||||
|
||||
ret = spl_early_init();
|
||||
if (ret) {
|
||||
debug("spl_early_init() failed: %d\n", ret);
|
||||
hang();
|
||||
}
|
||||
|
||||
ret = uclass_get_device_by_name(UCLASS_CLK,
|
||||
"clock-controller@30380000",
|
||||
&dev);
|
||||
if (ret < 0) {
|
||||
printf("Failed to find clock node. Check device tree\n");
|
||||
hang();
|
||||
}
|
||||
|
||||
enable_tzc380();
|
||||
|
||||
setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
|
||||
|
||||
power_init_board();
|
||||
|
||||
/* DDR initialization */
|
||||
spl_dram_init();
|
||||
|
||||
board_init_r(NULL, 0);
|
||||
}
|
153
configs/imx8mm-cl-iot-gate_defconfig
Normal file
153
configs/imx8mm-cl-iot-gate_defconfig
Normal file
|
@ -0,0 +1,153 @@
|
|||
CONFIG_ARM=y
|
||||
CONFIG_SPL_SYS_ICACHE_OFF=y
|
||||
CONFIG_SPL_SYS_DCACHE_OFF=y
|
||||
CONFIG_ARCH_IMX8M=y
|
||||
CONFIG_SYS_TEXT_BASE=0x40200000
|
||||
CONFIG_SPL_GPIO_SUPPORT=y
|
||||
CONFIG_SPL_LIBCOMMON_SUPPORT=y
|
||||
CONFIG_SPL_LIBGENERIC_SUPPORT=y
|
||||
CONFIG_SYS_MALLOC_F_LEN=0x10000
|
||||
CONFIG_ENV_SIZE=0x4000
|
||||
CONFIG_ENV_OFFSET=0x4400
|
||||
CONFIG_SYS_I2C_MXC_I2C1=y
|
||||
CONFIG_SYS_I2C_MXC_I2C2=y
|
||||
CONFIG_SYS_I2C_MXC_I2C3=y
|
||||
CONFIG_DM_GPIO=y
|
||||
CONFIG_SPL_TEXT_BASE=0x7E1000
|
||||
CONFIG_TARGET_IMX8MM_CL_IOT_GATE=y
|
||||
CONFIG_SPL_MMC_SUPPORT=y
|
||||
CONFIG_SPL_SERIAL_SUPPORT=y
|
||||
CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
|
||||
CONFIG_SPL=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="imx8mm-cl-iot-gate"
|
||||
CONFIG_DISTRO_DEFAULTS=y
|
||||
CONFIG_FIT=y
|
||||
CONFIG_FIT_EXTERNAL_OFFSET=0x3000
|
||||
CONFIG_FIT_SIGNATURE=y
|
||||
CONFIG_SPL_LOAD_FIT=y
|
||||
# CONFIG_USE_SPL_FIT_GENERATOR is not set
|
||||
CONFIG_OF_SYSTEM_SETUP=y
|
||||
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/compulab/imx8mm-cl-iot-gate/imximage-8mm-lpddr4.cfg"
|
||||
CONFIG_BOARD_LATE_INIT=y
|
||||
CONFIG_SPL_BOARD_INIT=y
|
||||
CONFIG_SPL_SEPARATE_BSS=y
|
||||
CONFIG_SPL_I2C_SUPPORT=y
|
||||
CONFIG_SPL_POWER_SUPPORT=y
|
||||
CONFIG_SPL_WATCHDOG_SUPPORT=y
|
||||
CONFIG_SYS_PROMPT="u-boot=> "
|
||||
CONFIG_CMD_BOOTEFI_SELFTEST=y
|
||||
CONFIG_CMD_NVEDIT_EFI=y
|
||||
CONFIG_CMD_EEPROM=y
|
||||
CONFIG_CMD_SHA1SUM=y
|
||||
CONFIG_CMD_BIND=y
|
||||
CONFIG_CMD_CLK=y
|
||||
CONFIG_CMD_DFU=y
|
||||
CONFIG_CMD_FUSE=y
|
||||
CONFIG_CMD_GPIO=y
|
||||
CONFIG_CMD_GPT=y
|
||||
CONFIG_CMD_I2C=y
|
||||
CONFIG_CMD_MMC=y
|
||||
CONFIG_CMD_USB=y
|
||||
CONFIG_CMD_USB_MASS_STORAGE=y
|
||||
CONFIG_CMD_SNTP=y
|
||||
CONFIG_CMD_CACHE=y
|
||||
CONFIG_CMD_EFIDEBUG=y
|
||||
CONFIG_CMD_RTC=y
|
||||
CONFIG_CMD_TIME=y
|
||||
CONFIG_CMD_GETTIME=y
|
||||
CONFIG_CMD_TIMER=y
|
||||
CONFIG_CMD_REGULATOR=y
|
||||
CONFIG_CMD_TPM=y
|
||||
CONFIG_CMD_EXT4_WRITE=y
|
||||
CONFIG_OF_CONTROL=y
|
||||
CONFIG_SPL_OF_CONTROL=y
|
||||
CONFIG_ENV_OVERWRITE=y
|
||||
CONFIG_ENV_IS_IN_MMC=y
|
||||
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
|
||||
CONFIG_SYS_MMC_ENV_DEV=2
|
||||
CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
|
||||
CONFIG_NET_RANDOM_ETHADDR=y
|
||||
CONFIG_SPL_DM=y
|
||||
CONFIG_SPL_CLK_COMPOSITE_CCF=y
|
||||
CONFIG_CLK_COMPOSITE_CCF=y
|
||||
CONFIG_SPL_CLK_IMX8MM=y
|
||||
CONFIG_CLK_IMX8MM=y
|
||||
CONFIG_DFU_TFTP=y
|
||||
CONFIG_DFU_MMC=y
|
||||
CONFIG_DFU_RAM=y
|
||||
CONFIG_DFU_SF=y
|
||||
CONFIG_UDP_FUNCTION_FASTBOOT=y
|
||||
CONFIG_FASTBOOT_BUF_ADDR=0x44000000
|
||||
CONFIG_FASTBOOT_BUF_SIZE=0x5000000
|
||||
CONFIG_FASTBOOT_FLASH=y
|
||||
CONFIG_FASTBOOT_FLASH_MMC_DEV=2
|
||||
CONFIG_MXC_GPIO=y
|
||||
CONFIG_DM_I2C=y
|
||||
CONFIG_SYS_I2C_MXC=y
|
||||
CONFIG_DM_KEYBOARD=y
|
||||
CONFIG_DM_MMC=y
|
||||
CONFIG_SUPPORT_EMMC_RPMB=y
|
||||
CONFIG_SUPPORT_EMMC_BOOT=y
|
||||
CONFIG_FSL_ESDHC_IMX=y
|
||||
CONFIG_DM_SPI_FLASH=y
|
||||
CONFIG_PHYLIB=y
|
||||
CONFIG_PHY_ATHEROS=y
|
||||
CONFIG_DM_ETH=y
|
||||
CONFIG_PHY_GIGE=y
|
||||
CONFIG_FEC_MXC=y
|
||||
CONFIG_MII=y
|
||||
CONFIG_PCI_ENDPOINT=y
|
||||
CONFIG_PINCTRL=y
|
||||
CONFIG_SPL_PINCTRL=y
|
||||
CONFIG_PINCTRL_IMX8M=y
|
||||
CONFIG_POWER_DOMAIN=y
|
||||
CONFIG_IMX8M_POWER_DOMAIN=y
|
||||
CONFIG_DM_PMIC=y
|
||||
CONFIG_DM_PMIC_BD71837=y
|
||||
CONFIG_SPL_DM_PMIC_BD71837=y
|
||||
CONFIG_DM_REGULATOR=y
|
||||
CONFIG_DM_REGULATOR_BD71837=y
|
||||
CONFIG_DM_REGULATOR_FIXED=y
|
||||
CONFIG_DM_REGULATOR_GPIO=y
|
||||
CONFIG_DM_RTC=y
|
||||
CONFIG_RTC_ABX80X=y
|
||||
CONFIG_MXC_UART=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_DM_SPI=y
|
||||
CONFIG_SYSRESET=y
|
||||
CONFIG_SPL_SYSRESET=y
|
||||
CONFIG_SYSRESET_PSCI=y
|
||||
CONFIG_SYSRESET_WATCHDOG=y
|
||||
CONFIG_TEE=y
|
||||
CONFIG_OPTEE=y
|
||||
CONFIG_DM_THERMAL=y
|
||||
CONFIG_TPM2_TIS_SPI=y
|
||||
CONFIG_TPM2_FTPM_TEE=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_DM_USB=y
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
CONFIG_USB_EHCI_GENERIC=y
|
||||
CONFIG_USB_GADGET=y
|
||||
CONFIG_USB_GADGET_MANUFACTURER="FSL"
|
||||
CONFIG_USB_GADGET_VENDOR_NUM=0x0525
|
||||
CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5
|
||||
CONFIG_CI_UDC=y
|
||||
CONFIG_SDP_LOADADDR=0x40400000
|
||||
CONFIG_USB_GADGET_DOWNLOAD=y
|
||||
CONFIG_USB_HOST_ETHER=y
|
||||
CONFIG_USB_ETHER_ASIX88179=y
|
||||
CONFIG_IMX_WATCHDOG=y
|
||||
CONFIG_SPL_TINY_MEMSET=y
|
||||
CONFIG_TPM=y
|
||||
CONFIG_SHA512_ALGO=y
|
||||
CONFIG_SHA512=y
|
||||
CONFIG_SHA384=y
|
||||
CONFIG_LZO=y
|
||||
CONFIG_BZIP2=y
|
||||
CONFIG_OF_LIBFDT_OVERLAY=y
|
||||
CONFIG_EFI_SET_TIME=y
|
||||
CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y
|
||||
CONFIG_EFI_CAPSULE_ON_DISK=y
|
||||
CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y
|
||||
CONFIG_EFI_TCG2_PROTOCOL=y
|
||||
CONFIG_EFI_SECURE_BOOT=y
|
196
include/configs/imx8mm-cl-iot-gate.h
Normal file
196
include/configs/imx8mm-cl-iot-gate.h
Normal file
|
@ -0,0 +1,196 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2019 NXP
|
||||
*/
|
||||
|
||||
#ifndef __IMX8MM_CL_IOT_GATE_H
|
||||
#define __IMX8MM_CL_IOT_GATE_H
|
||||
|
||||
#include <linux/sizes.h>
|
||||
#include <linux/stringify.h>
|
||||
#include <asm/arch/imx-regs.h>
|
||||
#include <config_distro_bootcmd.h>
|
||||
|
||||
#define CONFIG_SYS_BOOTM_LEN (32 * SZ_1M)
|
||||
#define CONFIG_SPL_MAX_SIZE (148 * 1024)
|
||||
#define CONFIG_SYS_MONITOR_LEN SZ_512K
|
||||
#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
|
||||
#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 0x300
|
||||
#define CONFIG_SYS_UBOOT_BASE \
|
||||
(QSPI0_AMBA_BASE + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR * 512)
|
||||
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
#define CONFIG_SPL_STACK 0x920000
|
||||
#define CONFIG_SPL_BSS_START_ADDR 0x910000
|
||||
#define CONFIG_SPL_BSS_MAX_SIZE SZ_8K /* 8 KB */
|
||||
#define CONFIG_SYS_SPL_MALLOC_START 0x42200000
|
||||
#define CONFIG_SYS_SPL_MALLOC_SIZE SZ_512K /* 512 KB */
|
||||
|
||||
/* malloc f used before GD_FLG_FULL_MALLOC_INIT set */
|
||||
#define CONFIG_MALLOC_F_ADDR 0x912000
|
||||
/* For RAW image gives a error info not panic */
|
||||
#define CONFIG_SPL_ABORT_ON_RAW_IMAGE
|
||||
|
||||
#endif
|
||||
|
||||
#if CONFIG_IS_ENABLED(CMD_MMC)
|
||||
# define BOOT_TARGET_MMC(func) \
|
||||
func(MMC, mmc, 2) \
|
||||
func(MMC, mmc, 0)
|
||||
#else
|
||||
# define BOOT_TARGET_MMC(func)
|
||||
#endif
|
||||
|
||||
#if CONFIG_IS_ENABLED(CMD_USB)
|
||||
# define BOOT_TARGET_USB(func) func(USB, usb, 0)
|
||||
#else
|
||||
# define BOOT_TARGET_USB(func)
|
||||
#endif
|
||||
|
||||
#if CONFIG_IS_ENABLED(CMD_PXE)
|
||||
# define BOOT_TARGET_PXE(func) func(PXE, pxe, na)
|
||||
#else
|
||||
# define BOOT_TARGET_PXE(func)
|
||||
#endif
|
||||
|
||||
#if CONFIG_IS_ENABLED(CMD_DHCP)
|
||||
# define BOOT_TARGET_DHCP(func) func(DHCP, dhcp, na)
|
||||
#else
|
||||
# define BOOT_TARGET_DHCP(func)
|
||||
#endif
|
||||
|
||||
#define BOOT_TARGET_DEVICES(func) \
|
||||
BOOT_TARGET_USB(func) \
|
||||
BOOT_TARGET_MMC(func) \
|
||||
BOOT_TARGET_PXE(func) \
|
||||
BOOT_TARGET_DHCP(func)
|
||||
|
||||
/* Initial environment variables */
|
||||
#define CONFIG_EXTRA_ENV_SETTINGS \
|
||||
BOOTENV \
|
||||
"script=boot.scr\0" \
|
||||
"image=Image\0" \
|
||||
"console=ttymxc2,115200 earlycon=ec_imx6q,0x30880000,115200\0" \
|
||||
"fdt_addr=0x43000000\0" \
|
||||
"fdt_addr_r=0x43000000\0" \
|
||||
"boot_fit=no\0" \
|
||||
"dfu_alt_info=mmc 2=flash-bin raw 0x42 0x250 mmcpart 1;" \
|
||||
"u-boot-itb raw 0x300 0x1B00 mmcpart 1\0" \
|
||||
"fdt_file=sb-iotgimx8.dtb\0" \
|
||||
"fdtfile=sb-iotgimx8.dtb\0" \
|
||||
"initrd_addr=0x43800000\0" \
|
||||
"bootm_size=0x10000000\0" \
|
||||
"mmcdev=" __stringify(CONFIG_SYS_MMC_ENV_DEV) "\0" \
|
||||
"mmcpart=" __stringify(CONFIG_SYS_MMC_IMG_LOAD_PART) "\0" \
|
||||
"mmcroot=" CONFIG_MMCROOT " rootwait rw\0" \
|
||||
"mmcautodetect=yes\0" \
|
||||
"mmcargs=setenv bootargs console=${console} root=${mmcroot}\0 " \
|
||||
"loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\0" \
|
||||
"bootscript=echo Running bootscript from mmc ...; " \
|
||||
"source\0" \
|
||||
"loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}\0" \
|
||||
"loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}\0" \
|
||||
"kernel_addr_r=0x40480000\0" \
|
||||
"pxefile_addr_r=0x40480000\0" \
|
||||
"ramdisk_addr_r=0x43800000\0" \
|
||||
"mmcboot=echo Booting from mmc ...; " \
|
||||
"run mmcargs; " \
|
||||
"if test ${boot_fit} = yes || test ${boot_fit} = try; then " \
|
||||
"bootm ${loadaddr}; " \
|
||||
"else " \
|
||||
"if run loadfdt; then " \
|
||||
"booti ${loadaddr} - ${fdt_addr}; " \
|
||||
"else " \
|
||||
"echo WARN: Cannot load the DT; " \
|
||||
"fi; " \
|
||||
"fi;\0" \
|
||||
"netargs=setenv bootargs console=${console} " \
|
||||
"root=/dev/nfs " \
|
||||
"ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp\0" \
|
||||
"netboot=echo Booting from net ...; " \
|
||||
"run netargs; " \
|
||||
"if test ${ip_dyn} = yes; then " \
|
||||
"setenv get_cmd dhcp; " \
|
||||
"else " \
|
||||
"setenv get_cmd tftp; " \
|
||||
"fi; " \
|
||||
"${get_cmd} ${loadaddr} ${image}; " \
|
||||
"if test ${boot_fit} = yes || test ${boot_fit} = try; then " \
|
||||
"bootm ${loadaddr}; " \
|
||||
"else " \
|
||||
"if ${get_cmd} ${fdt_addr} ${fdt_file}; then " \
|
||||
"booti ${loadaddr} - ${fdt_addr}; " \
|
||||
"else " \
|
||||
"echo WARN: Cannot load the DT; " \
|
||||
"fi; " \
|
||||
"fi;\0"
|
||||
|
||||
#ifndef CONFIG_BOOTCOMMAND
|
||||
#define CONFIG_BOOTCOMMAND \
|
||||
"mmc dev ${mmcdev}; if mmc rescan; then " \
|
||||
"if run loadbootscript; then " \
|
||||
"run bootscript; " \
|
||||
"else " \
|
||||
"if run loadimage; then " \
|
||||
"run mmcboot; " \
|
||||
"else run netboot; " \
|
||||
"fi; " \
|
||||
"fi; " \
|
||||
"fi;"
|
||||
#endif
|
||||
|
||||
/* Link Definitions */
|
||||
#define CONFIG_LOADADDR 0x40480000
|
||||
|
||||
#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
|
||||
|
||||
#define CONFIG_SYS_INIT_RAM_ADDR 0x40000000
|
||||
#define CONFIG_SYS_INIT_RAM_SIZE 0x80000
|
||||
#define CONFIG_SYS_INIT_SP_OFFSET \
|
||||
(CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE)
|
||||
#define CONFIG_SYS_INIT_SP_ADDR \
|
||||
(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET)
|
||||
|
||||
#define CONFIG_MMCROOT "/dev/mmcblk1p2" /* USDHC2 */
|
||||
|
||||
/* Size of malloc() pool */
|
||||
#define CONFIG_SYS_MALLOC_LEN SZ_32M
|
||||
|
||||
#define CONFIG_SYS_SDRAM_BASE 0x40000000
|
||||
#define PHYS_SDRAM 0x40000000
|
||||
#define PHYS_SDRAM_SIZE 0x80000000 /* 2GB DDR */
|
||||
|
||||
#define CONFIG_MXC_UART_BASE UART3_BASE_ADDR
|
||||
|
||||
/* Monitor Command Prompt */
|
||||
#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
|
||||
#define CONFIG_SYS_CBSIZE 2048
|
||||
#define CONFIG_SYS_MAXARGS 64
|
||||
#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
|
||||
#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
|
||||
sizeof(CONFIG_SYS_PROMPT) + 16)
|
||||
|
||||
/* USDHC */
|
||||
#define CONFIG_FSL_USDHC
|
||||
|
||||
#define CONFIG_SYS_FSL_USDHC_NUM 2
|
||||
#define CONFIG_SYS_FSL_ESDHC_ADDR 0
|
||||
|
||||
#define CONFIG_SYS_MMC_IMG_LOAD_PART 1
|
||||
|
||||
#define CONFIG_SYS_I2C_SPEED 100000
|
||||
|
||||
#define CONFIG_ETHPRIME "FEC"
|
||||
|
||||
#define CONFIG_FEC_XCV_TYPE RGMII
|
||||
#define CONFIG_FEC_MXC_PHYADDR 0
|
||||
#define FEC_QUIRK_ENET_MAC
|
||||
|
||||
#define IMX_FEC_BASE 0x30BE0000
|
||||
|
||||
/* USB Configs */
|
||||
#define CONFIG_EHCI_HCD_INIT_AFTER_RESET
|
||||
#define CONFIG_MXC_USB_PORTSC (PORT_PTS_UTMI | PORT_PTS_PTW)
|
||||
#define CONFIG_USB_MAX_CONTROLLER_COUNT 2
|
||||
|
||||
#endif /*__IMX8MM_CL_IOT_GATE_H*/
|
Loading…
Add table
Reference in a new issue