Merge tag 'u-boot-imx-20220919' of https://gitlab.denx.de/u-boot/custodians/u-boot-imx
u-boot-imx-20220919 ------------------- CI: https://source.denx.de/u-boot/custodians/u-boot-imx/-/pipelines/13500 - Fix imx8mn-beacon-kit-u-boot - Merged Purism - imxrt1170 (already merged in u-boot-imx) - Fixes in crypto FSL - Toradex : fixes Verdin - Serial Driver: fixes when not used as console - DH Boards : fixes + USB - Fix CONFIG_SYS_MALLOC_F_LEN (Kconfig) - Add imx6ulz_smm_m2
This commit is contained in:
12
board/bsh/imx6ulz_smm_m2/Kconfig
Normal file
12
board/bsh/imx6ulz_smm_m2/Kconfig
Normal file
@@ -0,0 +1,12 @@
|
||||
if TARGET_MX6ULZ_SMM_M2
|
||||
|
||||
config SYS_BOARD
|
||||
default "imx6ulz_smm_m2"
|
||||
|
||||
config SYS_VENDOR
|
||||
default "bsh"
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
default "imx6ulz_smm_m2"
|
||||
|
||||
endif
|
||||
6
board/bsh/imx6ulz_smm_m2/MAINTAINERS
Normal file
6
board/bsh/imx6ulz_smm_m2/MAINTAINERS
Normal file
@@ -0,0 +1,6 @@
|
||||
MX6ULZ_SMM_M2 BOARD
|
||||
M: Michael Trimarchi <michael@amarulasolutions.com>
|
||||
S: Maintained
|
||||
F: board/bsh/mx6ulz_smm_m2/
|
||||
F: include/configs/imx6ulz_smm_m2.h
|
||||
F: configs/imx6ulz_smm_m2_defconfig
|
||||
6
board/bsh/imx6ulz_smm_m2/Makefile
Normal file
6
board/bsh/imx6ulz_smm_m2/Makefile
Normal file
@@ -0,0 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
# (C) Copyright 2021 Amarula Solutions B.V.
|
||||
|
||||
obj-y := imx6ulz_smm_m2.o
|
||||
obj-$(CONFIG_SPL_BUILD) += spl.o
|
||||
|
||||
67
board/bsh/imx6ulz_smm_m2/README
Normal file
67
board/bsh/imx6ulz_smm_m2/README
Normal file
@@ -0,0 +1,67 @@
|
||||
How to Update U-Boot on imx6ulz_smm_m2 board
|
||||
--------------------------------------------
|
||||
|
||||
Required software on the host PC:
|
||||
|
||||
- UUU: https://github.com/NXPmicro/mfgtools
|
||||
|
||||
Build U-Boot for m2:
|
||||
|
||||
$ make mrproper
|
||||
$ make imx6ulz_smm_m2_defconfig
|
||||
$ make
|
||||
|
||||
This generates the SPL and u-boot-dtb.img binaries.
|
||||
|
||||
1. Loading U-Boot via USB Serial Download Protocol
|
||||
|
||||
Copy SPL and u-boot-dtb.img to the uuu folder.
|
||||
|
||||
Load the U-Boot via USB:
|
||||
|
||||
$ sudo uuu -v -b nand_script.lst u-boot-with-spl.imx
|
||||
|
||||
where nand_script.lst contains the following:
|
||||
|
||||
uuu_version 1.2.39
|
||||
|
||||
# @_flash.bin | bootloader
|
||||
# @_image [_flash.bin] | image burn to nand, default is the same as bootloader
|
||||
|
||||
# This command will be run when i.MX6/7 i.MX8MM, i.MX8MQ
|
||||
SDP: boot -f _flash.bin
|
||||
|
||||
# This command will be run when ROM support stream mode
|
||||
# i.MX8QXP, i.MX8QM
|
||||
SDPS: boot -f _flash.bin
|
||||
|
||||
# These commands will be run when use SPL and will be skipped if no spl
|
||||
# SDPU will be deprecated. please use SDPV instead of SDPU
|
||||
# {
|
||||
SDPU: delay 1000
|
||||
SDPU: write -f _flash.bin -offset 0x57c00
|
||||
SDPU: jump
|
||||
# }
|
||||
|
||||
# These commands will be run when use SPL and will be skipped if no spl
|
||||
# if (SPL support SDPV)
|
||||
# {
|
||||
SDPV: delay 1000
|
||||
SDPV: write -f _flash.bin -offset 0x11000
|
||||
SDPV: jump
|
||||
# }
|
||||
|
||||
FB: ucmd setenv fastboot_buffer ${loadaddr}
|
||||
FB: download -f _image
|
||||
FB: ucmd if test ! -n "$fastboot_bytes"; then setenv fastboot_bytes $filesize; else true; fi
|
||||
# Burn image to nandfit partition if needed
|
||||
FB: ucmd if env exists nandfit_part; then nand erase.part nandfit; nand write ${fastboot_buffer} nandfit ${fastboot_bytes}; else true; fi;
|
||||
FB: ucmd nandbcb init ${fastboot_buffer} nandboot ${fastboot_bytes}
|
||||
FB: Done
|
||||
|
||||
Then U-Boot starts and its messages appear in the console program.
|
||||
|
||||
Use the default environment variables:
|
||||
|
||||
=> env default -f -a
|
||||
=> saveenv
|
||||
53
board/bsh/imx6ulz_smm_m2/imx6ulz_smm_m2.c
Normal file
53
board/bsh/imx6ulz_smm_m2/imx6ulz_smm_m2.c
Normal file
@@ -0,0 +1,53 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
*
|
||||
* Copyright (C) 2021 BSH Hausgeraete GmbH
|
||||
*/
|
||||
|
||||
#include <init.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/iomux.h>
|
||||
#include <asm/arch/imx-regs.h>
|
||||
#include <asm/arch/crm_regs.h>
|
||||
#include <asm/arch/mx6-pins.h>
|
||||
#include <asm/arch/sys_proto.h>
|
||||
#include <asm/mach-imx/boot_mode.h>
|
||||
#include <asm/global_data.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <common.h>
|
||||
#include <env.h>
|
||||
#include <linux/sizes.h>
|
||||
|
||||
static void setup_gpmi_nand(void)
|
||||
{
|
||||
setup_gpmi_io_clk((MXC_CCM_CS2CDR_ENFC_CLK_PODF(0) |
|
||||
MXC_CCM_CS2CDR_ENFC_CLK_PRED(3) |
|
||||
MXC_CCM_CS2CDR_ENFC_CLK_SEL(3)));
|
||||
};
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
gd->ram_size = imx_ddr_size();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
/* Address of boot parameters */
|
||||
gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
|
||||
|
||||
setup_gpmi_nand();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_late_init(void)
|
||||
{
|
||||
if (is_boot_from_usb()) {
|
||||
env_set("bootcmd", "run bootcmd_mfg");
|
||||
env_set("bootdelay", "0");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
130
board/bsh/imx6ulz_smm_m2/spl.c
Normal file
130
board/bsh/imx6ulz_smm_m2/spl.c
Normal file
@@ -0,0 +1,130 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
#include <common.h>
|
||||
#include <cpu_func.h>
|
||||
#include <hang.h>
|
||||
#include <init.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/iomux.h>
|
||||
#include <asm/arch/imx-regs.h>
|
||||
#include <asm/arch/crm_regs.h>
|
||||
#include <asm/arch/mx6ull_pins.h>
|
||||
#include <asm/arch/mx6-pins.h>
|
||||
#include <asm/arch/sys_proto.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <asm/mach-imx/iomux-v3.h>
|
||||
#include <asm/mach-imx/boot_mode.h>
|
||||
#include <linux/libfdt.h>
|
||||
#include <spl.h>
|
||||
#include <asm/arch/mx6-ddr.h>
|
||||
|
||||
#define UART_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
|
||||
PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
|
||||
PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
|
||||
|
||||
static const iomux_v3_cfg_t uart4_pads[] = {
|
||||
MX6_PAD_UART4_TX_DATA__UART4_DCE_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
|
||||
MX6_PAD_UART4_RX_DATA__UART4_DCE_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
|
||||
};
|
||||
|
||||
static void setup_iomux_uart(void)
|
||||
{
|
||||
imx_iomux_v3_setup_multiple_pads(uart4_pads, ARRAY_SIZE(uart4_pads));
|
||||
}
|
||||
|
||||
static struct mx6ul_iomux_grp_regs mx6_grp_ioregs = {
|
||||
.grp_addds = 0x00000028,
|
||||
.grp_ddrmode_ctl = 0x00020000,
|
||||
.grp_b0ds = 0x00000028,
|
||||
.grp_ctlds = 0x00000028,
|
||||
.grp_b1ds = 0x00000028,
|
||||
.grp_ddrpke = 0x00000000,
|
||||
.grp_ddrmode = 0x00020000,
|
||||
.grp_ddr_type = 0x000c0000,
|
||||
};
|
||||
|
||||
static struct mx6ul_iomux_ddr_regs mx6_ddr_ioregs = {
|
||||
.dram_dqm0 = 0x00000028,
|
||||
.dram_dqm1 = 0x00000028,
|
||||
.dram_ras = 0x00000028,
|
||||
.dram_cas = 0x00000028,
|
||||
.dram_odt0 = 0x00000028,
|
||||
.dram_odt1 = 0x00000028,
|
||||
.dram_sdba2 = 0x00000000,
|
||||
.dram_sdclk_0 = 0x00000028,
|
||||
.dram_sdqs0 = 0x00000028,
|
||||
.dram_sdqs1 = 0x00000028,
|
||||
.dram_reset = 0x000c0028,
|
||||
};
|
||||
|
||||
static struct mx6_mmdc_calibration mx6_mmcd_calib = {
|
||||
.p0_mpwldectrl0 = 0x00000000,
|
||||
.p0_mpwldectrl1 = 0x00100010,
|
||||
.p0_mpdgctrl0 = 0x414c014c,
|
||||
.p0_mpdgctrl1 = 0x00000000,
|
||||
.p0_mprddlctl = 0x40403a42,
|
||||
.p0_mpwrdlctl = 0x4040342e,
|
||||
};
|
||||
|
||||
static struct mx6_ddr_sysinfo ddr_sysinfo = {
|
||||
.dsize = 0,
|
||||
.cs1_mirror = 0,
|
||||
.cs_density = 32,
|
||||
.ncs = 1,
|
||||
.bi_on = 1,
|
||||
.rtt_nom = 1,
|
||||
.rtt_wr = 0,
|
||||
.ralat = 5,
|
||||
.walat = 1,
|
||||
.mif3_mode = 3,
|
||||
.rst_to_cke = 0x23, /* 33 cycles (JEDEC value for DDR3) - total of 500 us */
|
||||
.sde_to_rst = 0x10, /* 14 cycles (JEDEC value for DDR3) - total of 200 us */
|
||||
.refsel = 1,
|
||||
.refr = 3,
|
||||
};
|
||||
|
||||
static struct mx6_ddr3_cfg mem_ddr = {
|
||||
.mem_speed = 1333,
|
||||
.density = 2,
|
||||
.width = 16,
|
||||
.banks = 8,
|
||||
.rowaddr = 13,
|
||||
.coladdr = 10,
|
||||
.pagesz = 2,
|
||||
.trcd = 1350,
|
||||
.trcmin = 4950,
|
||||
.trasmin = 3600,
|
||||
};
|
||||
|
||||
static void ccgr_init(void)
|
||||
{
|
||||
struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
|
||||
|
||||
writel(0xFFFFFFFF, &ccm->CCGR0);
|
||||
writel(0xFFFFFFFF, &ccm->CCGR1);
|
||||
writel(0xFFFFFFFF, &ccm->CCGR2);
|
||||
writel(0xFFFFFFFF, &ccm->CCGR3);
|
||||
writel(0xFFFFFFFF, &ccm->CCGR4);
|
||||
writel(0xFFFFFFFF, &ccm->CCGR5);
|
||||
writel(0xFFFFFFFF, &ccm->CCGR6);
|
||||
}
|
||||
|
||||
static void imx6ul_spl_dram_cfg(void)
|
||||
{
|
||||
mx6ul_dram_iocfg(mem_ddr.width, &mx6_ddr_ioregs, &mx6_grp_ioregs);
|
||||
mx6_dram_cfg(&ddr_sysinfo, &mx6_mmcd_calib, &mem_ddr);
|
||||
}
|
||||
|
||||
void board_init_f(ulong dummy)
|
||||
{
|
||||
ccgr_init();
|
||||
arch_cpu_init();
|
||||
timer_init();
|
||||
setup_iomux_uart();
|
||||
preloader_console_init();
|
||||
imx6ul_spl_dram_cfg();
|
||||
}
|
||||
|
||||
void reset_cpu(void)
|
||||
{
|
||||
}
|
||||
@@ -22,7 +22,7 @@ static struct dram_cfg_param ddr_ddrc_cfg[] = {
|
||||
{ 0x3d4000d4, 0x940000 },
|
||||
{ 0x3d4000dc, 0xd4002d },
|
||||
{ 0x3d4000e0, 0x310000 },
|
||||
{ 0x3d4000e8, 0x66004d },
|
||||
{ 0x3d4000e8, 0x36004d },
|
||||
{ 0x3d4000ec, 0x16004d },
|
||||
{ 0x3d400100, 0x191e1920 },
|
||||
{ 0x3d400104, 0x60630 },
|
||||
@@ -55,6 +55,7 @@ static struct dram_cfg_param ddr_ddrc_cfg[] = {
|
||||
{ 0x3d400204, 0x80808 },
|
||||
{ 0x3d400214, 0x7070707 },
|
||||
{ 0x3d400218, 0x7070707 },
|
||||
{ 0x3d40021c, 0xf0f },
|
||||
{ 0x3d400250, 0x29001701 },
|
||||
{ 0x3d400254, 0x2c },
|
||||
{ 0x3d40025c, 0x4000030 },
|
||||
@@ -72,7 +73,7 @@ static struct dram_cfg_param ddr_ddrc_cfg[] = {
|
||||
{ 0x3d402064, 0xc001c },
|
||||
{ 0x3d4020dc, 0x840000 },
|
||||
{ 0x3d4020e0, 0x310000 },
|
||||
{ 0x3d4020e8, 0x66004d },
|
||||
{ 0x3d4020e8, 0x36004d },
|
||||
{ 0x3d4020ec, 0x16004d },
|
||||
{ 0x3d402100, 0xa040305 },
|
||||
{ 0x3d402104, 0x30407 },
|
||||
@@ -97,7 +98,7 @@ static struct dram_cfg_param ddr_ddrc_cfg[] = {
|
||||
{ 0x3d403064, 0x30007 },
|
||||
{ 0x3d4030dc, 0x840000 },
|
||||
{ 0x3d4030e0, 0x310000 },
|
||||
{ 0x3d4030e8, 0x66004d },
|
||||
{ 0x3d4030e8, 0x36004d },
|
||||
{ 0x3d4030ec, 0x16004d },
|
||||
{ 0x3d403100, 0xa010102 },
|
||||
{ 0x3d403104, 0x30404 },
|
||||
@@ -1059,25 +1060,25 @@ static struct dram_cfg_param ddr_fsp0_cfg[] = {
|
||||
{ 0x54012, 0x110 },
|
||||
{ 0x54019, 0x2dd4 },
|
||||
{ 0x5401a, 0x31 },
|
||||
{ 0x5401b, 0x4d66 },
|
||||
{ 0x5401b, 0x4d36 },
|
||||
{ 0x5401c, 0x4d00 },
|
||||
{ 0x5401e, 0x16 },
|
||||
{ 0x5401f, 0x2dd4 },
|
||||
{ 0x54020, 0x31 },
|
||||
{ 0x54021, 0x4d66 },
|
||||
{ 0x54021, 0x4d36 },
|
||||
{ 0x54022, 0x4d00 },
|
||||
{ 0x54024, 0x16 },
|
||||
{ 0x5402b, 0x1000 },
|
||||
{ 0x5402c, 0x1 },
|
||||
{ 0x54032, 0xd400 },
|
||||
{ 0x54033, 0x312d },
|
||||
{ 0x54034, 0x6600 },
|
||||
{ 0x54034, 0x3600 },
|
||||
{ 0x54035, 0x4d },
|
||||
{ 0x54036, 0x4d },
|
||||
{ 0x54037, 0x1600 },
|
||||
{ 0x54038, 0xd400 },
|
||||
{ 0x54039, 0x312d },
|
||||
{ 0x5403a, 0x6600 },
|
||||
{ 0x5403a, 0x3600 },
|
||||
{ 0x5403b, 0x4d },
|
||||
{ 0x5403c, 0x4d },
|
||||
{ 0x5403d, 0x1600 },
|
||||
@@ -1098,25 +1099,25 @@ static struct dram_cfg_param ddr_fsp1_cfg[] = {
|
||||
{ 0x54012, 0x110 },
|
||||
{ 0x54019, 0x84 },
|
||||
{ 0x5401a, 0x31 },
|
||||
{ 0x5401b, 0x4d66 },
|
||||
{ 0x5401b, 0x4d36 },
|
||||
{ 0x5401c, 0x4d00 },
|
||||
{ 0x5401e, 0x16 },
|
||||
{ 0x5401f, 0x84 },
|
||||
{ 0x54020, 0x31 },
|
||||
{ 0x54021, 0x4d66 },
|
||||
{ 0x54021, 0x4d36 },
|
||||
{ 0x54022, 0x4d00 },
|
||||
{ 0x54024, 0x16 },
|
||||
{ 0x5402b, 0x1000 },
|
||||
{ 0x5402c, 0x1 },
|
||||
{ 0x54032, 0x8400 },
|
||||
{ 0x54033, 0x3100 },
|
||||
{ 0x54034, 0x6600 },
|
||||
{ 0x54034, 0x3600 },
|
||||
{ 0x54035, 0x4d },
|
||||
{ 0x54036, 0x4d },
|
||||
{ 0x54037, 0x1600 },
|
||||
{ 0x54038, 0x8400 },
|
||||
{ 0x54039, 0x3100 },
|
||||
{ 0x5403a, 0x6600 },
|
||||
{ 0x5403a, 0x3600 },
|
||||
{ 0x5403b, 0x4d },
|
||||
{ 0x5403c, 0x4d },
|
||||
{ 0x5403d, 0x1600 },
|
||||
@@ -1137,25 +1138,25 @@ static struct dram_cfg_param ddr_fsp2_cfg[] = {
|
||||
{ 0x54012, 0x110 },
|
||||
{ 0x54019, 0x84 },
|
||||
{ 0x5401a, 0x31 },
|
||||
{ 0x5401b, 0x4d66 },
|
||||
{ 0x5401b, 0x4d36 },
|
||||
{ 0x5401c, 0x4d00 },
|
||||
{ 0x5401e, 0x16 },
|
||||
{ 0x5401f, 0x84 },
|
||||
{ 0x54020, 0x31 },
|
||||
{ 0x54021, 0x4d66 },
|
||||
{ 0x54021, 0x4d36 },
|
||||
{ 0x54022, 0x4d00 },
|
||||
{ 0x54024, 0x16 },
|
||||
{ 0x5402b, 0x1000 },
|
||||
{ 0x5402c, 0x1 },
|
||||
{ 0x54032, 0x8400 },
|
||||
{ 0x54033, 0x3100 },
|
||||
{ 0x54034, 0x6600 },
|
||||
{ 0x54034, 0x3600 },
|
||||
{ 0x54035, 0x4d },
|
||||
{ 0x54036, 0x4d },
|
||||
{ 0x54037, 0x1600 },
|
||||
{ 0x54038, 0x8400 },
|
||||
{ 0x54039, 0x3100 },
|
||||
{ 0x5403a, 0x6600 },
|
||||
{ 0x5403a, 0x3600 },
|
||||
{ 0x5403b, 0x4d },
|
||||
{ 0x5403c, 0x4d },
|
||||
{ 0x5403d, 0x1600 },
|
||||
@@ -1177,25 +1178,25 @@ static struct dram_cfg_param ddr_fsp0_2d_cfg[] = {
|
||||
{ 0x54012, 0x110 },
|
||||
{ 0x54019, 0x2dd4 },
|
||||
{ 0x5401a, 0x31 },
|
||||
{ 0x5401b, 0x4d66 },
|
||||
{ 0x5401b, 0x4d36 },
|
||||
{ 0x5401c, 0x4d00 },
|
||||
{ 0x5401e, 0x16 },
|
||||
{ 0x5401f, 0x2dd4 },
|
||||
{ 0x54020, 0x31 },
|
||||
{ 0x54021, 0x4d66 },
|
||||
{ 0x54021, 0x4d36 },
|
||||
{ 0x54022, 0x4d00 },
|
||||
{ 0x54024, 0x16 },
|
||||
{ 0x5402b, 0x1000 },
|
||||
{ 0x5402c, 0x1 },
|
||||
{ 0x54032, 0xd400 },
|
||||
{ 0x54033, 0x312d },
|
||||
{ 0x54034, 0x6600 },
|
||||
{ 0x54034, 0x3600 },
|
||||
{ 0x54035, 0x4d },
|
||||
{ 0x54036, 0x4d },
|
||||
{ 0x54037, 0x1600 },
|
||||
{ 0x54038, 0xd400 },
|
||||
{ 0x54039, 0x312d },
|
||||
{ 0x5403a, 0x6600 },
|
||||
{ 0x5403a, 0x3600 },
|
||||
{ 0x5403b, 0x4d },
|
||||
{ 0x5403c, 0x4d },
|
||||
{ 0x5403d, 0x1600 },
|
||||
@@ -1692,15 +1693,15 @@ static struct dram_cfg_param ddr_phy_pie[] = {
|
||||
{ 0x400d6, 0x20a },
|
||||
{ 0x400d7, 0x20b },
|
||||
{ 0x2003a, 0x2 },
|
||||
{ 0x2000b, 0x5d },
|
||||
{ 0x2000b, 0x34b },
|
||||
{ 0x2000c, 0xbb },
|
||||
{ 0x2000d, 0x753 },
|
||||
{ 0x2000e, 0x2c },
|
||||
{ 0x12000b, 0xc },
|
||||
{ 0x12000b, 0x70 },
|
||||
{ 0x12000c, 0x19 },
|
||||
{ 0x12000d, 0xfa },
|
||||
{ 0x12000e, 0x10 },
|
||||
{ 0x22000b, 0x3 },
|
||||
{ 0x22000b, 0x1c },
|
||||
{ 0x22000c, 0x6 },
|
||||
{ 0x22000d, 0x3e },
|
||||
{ 0x22000e, 0x10 },
|
||||
|
||||
@@ -22,7 +22,7 @@ static struct dram_cfg_param ddr_ddrc_cfg[] = {
|
||||
{ 0x3d4000d4, 0x940000 },
|
||||
{ 0x3d4000dc, 0xd4002d },
|
||||
{ 0x3d4000e0, 0x310000 },
|
||||
{ 0x3d4000e8, 0x66004d },
|
||||
{ 0x3d4000e8, 0x36004d },
|
||||
{ 0x3d4000ec, 0x16004d },
|
||||
{ 0x3d400100, 0x191e1920 },
|
||||
{ 0x3d400104, 0x60630 },
|
||||
@@ -55,6 +55,7 @@ static struct dram_cfg_param ddr_ddrc_cfg[] = {
|
||||
{ 0x3d400204, 0x80808 },
|
||||
{ 0x3d400214, 0x7070707 },
|
||||
{ 0x3d400218, 0x7070707 },
|
||||
{ 0x3d40021c, 0xf0f },
|
||||
{ 0x3d400250, 0x29001701 },
|
||||
{ 0x3d400254, 0x2c },
|
||||
{ 0x3d40025c, 0x4000030 },
|
||||
@@ -72,7 +73,7 @@ static struct dram_cfg_param ddr_ddrc_cfg[] = {
|
||||
{ 0x3d402064, 0xc001c },
|
||||
{ 0x3d4020dc, 0x840000 },
|
||||
{ 0x3d4020e0, 0x310000 },
|
||||
{ 0x3d4020e8, 0x66004d },
|
||||
{ 0x3d4020e8, 0x36004d },
|
||||
{ 0x3d4020ec, 0x16004d },
|
||||
{ 0x3d402100, 0xa040305 },
|
||||
{ 0x3d402104, 0x30407 },
|
||||
@@ -1059,25 +1060,25 @@ static struct dram_cfg_param ddr_fsp0_cfg[] = {
|
||||
{ 0x54012, 0x310 },
|
||||
{ 0x54019, 0x2dd4 },
|
||||
{ 0x5401a, 0x31 },
|
||||
{ 0x5401b, 0x4d66 },
|
||||
{ 0x5401b, 0x4d36 },
|
||||
{ 0x5401c, 0x4d00 },
|
||||
{ 0x5401e, 0x16 },
|
||||
{ 0x5401f, 0x2dd4 },
|
||||
{ 0x54020, 0x31 },
|
||||
{ 0x54021, 0x4d66 },
|
||||
{ 0x54021, 0x4d36 },
|
||||
{ 0x54022, 0x4d00 },
|
||||
{ 0x54024, 0x16 },
|
||||
{ 0x5402b, 0x1000 },
|
||||
{ 0x5402c, 0x3 },
|
||||
{ 0x54032, 0xd400 },
|
||||
{ 0x54033, 0x312d },
|
||||
{ 0x54034, 0x6600 },
|
||||
{ 0x54034, 0x3600 },
|
||||
{ 0x54035, 0x4d },
|
||||
{ 0x54036, 0x4d },
|
||||
{ 0x54037, 0x1600 },
|
||||
{ 0x54038, 0xd400 },
|
||||
{ 0x54039, 0x312d },
|
||||
{ 0x5403a, 0x6600 },
|
||||
{ 0x5403a, 0x3600 },
|
||||
{ 0x5403b, 0x4d },
|
||||
{ 0x5403c, 0x4d },
|
||||
{ 0x5403d, 0x1600 },
|
||||
@@ -1098,25 +1099,25 @@ static struct dram_cfg_param ddr_fsp1_cfg[] = {
|
||||
{ 0x54012, 0x310 },
|
||||
{ 0x54019, 0x84 },
|
||||
{ 0x5401a, 0x31 },
|
||||
{ 0x5401b, 0x4d66 },
|
||||
{ 0x5401b, 0x4d36 },
|
||||
{ 0x5401c, 0x4d00 },
|
||||
{ 0x5401e, 0x16 },
|
||||
{ 0x5401f, 0x84 },
|
||||
{ 0x54020, 0x31 },
|
||||
{ 0x54021, 0x4d66 },
|
||||
{ 0x54021, 0x4d36 },
|
||||
{ 0x54022, 0x4d00 },
|
||||
{ 0x54024, 0x16 },
|
||||
{ 0x5402b, 0x1000 },
|
||||
{ 0x5402c, 0x3 },
|
||||
{ 0x54032, 0x8400 },
|
||||
{ 0x54033, 0x3100 },
|
||||
{ 0x54034, 0x6600 },
|
||||
{ 0x54034, 0x3600 },
|
||||
{ 0x54035, 0x4d },
|
||||
{ 0x54036, 0x4d },
|
||||
{ 0x54037, 0x1600 },
|
||||
{ 0x54038, 0x8400 },
|
||||
{ 0x54039, 0x3100 },
|
||||
{ 0x5403a, 0x6600 },
|
||||
{ 0x5403a, 0x3600 },
|
||||
{ 0x5403b, 0x4d },
|
||||
{ 0x5403c, 0x4d },
|
||||
{ 0x5403d, 0x1600 },
|
||||
@@ -1172,31 +1173,30 @@ static struct dram_cfg_param ddr_fsp0_2d_cfg[] = {
|
||||
{ 0x54008, 0x61 },
|
||||
{ 0x54009, 0xc8 },
|
||||
{ 0x5400b, 0x2 },
|
||||
{ 0x5400d, 0x100 },
|
||||
{ 0x5400f, 0x100 },
|
||||
{ 0x54010, 0x1f7f },
|
||||
{ 0x54012, 0x310 },
|
||||
{ 0x54019, 0x2dd4 },
|
||||
{ 0x5401a, 0x31 },
|
||||
{ 0x5401b, 0x4d66 },
|
||||
{ 0x5401b, 0x4d36 },
|
||||
{ 0x5401c, 0x4d00 },
|
||||
{ 0x5401e, 0x16 },
|
||||
{ 0x5401f, 0x2dd4 },
|
||||
{ 0x54020, 0x31 },
|
||||
{ 0x54021, 0x4d66 },
|
||||
{ 0x54021, 0x4d36 },
|
||||
{ 0x54022, 0x4d00 },
|
||||
{ 0x54024, 0x16 },
|
||||
{ 0x5402b, 0x1000 },
|
||||
{ 0x5402c, 0x3 },
|
||||
{ 0x54032, 0xd400 },
|
||||
{ 0x54033, 0x312d },
|
||||
{ 0x54034, 0x6600 },
|
||||
{ 0x54034, 0x3600 },
|
||||
{ 0x54035, 0x4d },
|
||||
{ 0x54036, 0x4d },
|
||||
{ 0x54037, 0x1600 },
|
||||
{ 0x54038, 0xd400 },
|
||||
{ 0x54039, 0x312d },
|
||||
{ 0x5403a, 0x6600 },
|
||||
{ 0x5403a, 0x3600 },
|
||||
{ 0x5403b, 0x4d },
|
||||
{ 0x5403c, 0x4d },
|
||||
{ 0x5403d, 0x1600 },
|
||||
@@ -1693,15 +1693,15 @@ static struct dram_cfg_param ddr_phy_pie[] = {
|
||||
{ 0x400d6, 0x20a },
|
||||
{ 0x400d7, 0x20b },
|
||||
{ 0x2003a, 0x2 },
|
||||
{ 0x2000b, 0x5d },
|
||||
{ 0x2000b, 0x34b },
|
||||
{ 0x2000c, 0xbb },
|
||||
{ 0x2000d, 0x753 },
|
||||
{ 0x2000e, 0x2c },
|
||||
{ 0x12000b, 0xc },
|
||||
{ 0x12000b, 0x70 },
|
||||
{ 0x12000c, 0x19 },
|
||||
{ 0x12000d, 0xfa },
|
||||
{ 0x12000e, 0x10 },
|
||||
{ 0x22000b, 0x3 },
|
||||
{ 0x22000b, 0x1c },
|
||||
{ 0x22000c, 0x6 },
|
||||
{ 0x22000d, 0x3e },
|
||||
{ 0x22000e, 0x10 },
|
||||
@@ -1715,6 +1715,10 @@ static struct dram_cfg_param ddr_phy_pie[] = {
|
||||
{ 0x90013, 0x6152 },
|
||||
{ 0x20010, 0x5a },
|
||||
{ 0x20011, 0x3 },
|
||||
{ 0x120010, 0x5a },
|
||||
{ 0x120011, 0x3 },
|
||||
{ 0x220010, 0x5a },
|
||||
{ 0x220011, 0x3 },
|
||||
{ 0x40080, 0xe0 },
|
||||
{ 0x40081, 0x12 },
|
||||
{ 0x40082, 0xe0 },
|
||||
|
||||
@@ -1799,8 +1799,8 @@ static struct dram_cfg_param ddr_phy_pie[] = {
|
||||
|
||||
static struct dram_fsp_msg ddr_dram_fsp_msg[] = {
|
||||
{
|
||||
/* P0 3732mts 1D */
|
||||
.drate = 3732,
|
||||
/* P0 3733mts 1D */
|
||||
.drate = 3733,
|
||||
.fw_type = FW_1D_IMAGE,
|
||||
.fsp_cfg = ddr_fsp0_cfg,
|
||||
.fsp_cfg_num = ARRAY_SIZE(ddr_fsp0_cfg),
|
||||
@@ -1820,8 +1820,8 @@ static struct dram_fsp_msg ddr_dram_fsp_msg[] = {
|
||||
.fsp_cfg_num = ARRAY_SIZE(ddr_fsp2_cfg),
|
||||
},
|
||||
{
|
||||
/* P0 3732mts 2D */
|
||||
.drate = 3732,
|
||||
/* P0 3733mts 2D */
|
||||
.drate = 3733,
|
||||
.fw_type = FW_2D_IMAGE,
|
||||
.fsp_cfg = ddr_fsp0_2d_cfg,
|
||||
.fsp_cfg_num = ARRAY_SIZE(ddr_fsp0_2d_cfg),
|
||||
@@ -1840,5 +1840,5 @@ struct dram_timing_info dh_imx8mp_dhcom_dram_timing_32g_x32 = {
|
||||
.ddrphy_trained_csr_num = ARRAY_SIZE(ddr_ddrphy_trained_csr),
|
||||
.ddrphy_pie = ddr_phy_pie,
|
||||
.ddrphy_pie_num = ARRAY_SIZE(ddr_phy_pie),
|
||||
.fsp_table = { 3732, 400, 100, },
|
||||
.fsp_table = { 3733, 400, 100, },
|
||||
};
|
||||
|
||||
22
board/freescale/imxrt1170-evk/Kconfig
Normal file
22
board/freescale/imxrt1170-evk/Kconfig
Normal file
@@ -0,0 +1,22 @@
|
||||
if TARGET_IMXRT1170_EVK
|
||||
|
||||
config SYS_BOARD
|
||||
string
|
||||
default "imxrt1170-evk"
|
||||
|
||||
config SYS_VENDOR
|
||||
string
|
||||
default "freescale"
|
||||
|
||||
config SYS_SOC
|
||||
string
|
||||
default "imxrt1170"
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
string
|
||||
default "imxrt1170-evk"
|
||||
|
||||
config IMX_CONFIG
|
||||
default "board/freescale/imxrt1170-evk/imximage.cfg"
|
||||
|
||||
endif
|
||||
7
board/freescale/imxrt1170-evk/MAINTAINERS
Normal file
7
board/freescale/imxrt1170-evk/MAINTAINERS
Normal file
@@ -0,0 +1,7 @@
|
||||
IMXRT1170 EVALUATION KIT
|
||||
M: Giulio Benetti <giulio.benetti@benettiengineering.com>
|
||||
M: Jesse Taube <Mr.Bossman075@gmail.com>
|
||||
S: Maintained
|
||||
F: board/freescale/imxrt1170-evk
|
||||
F: include/configs/imxrt1170-evk.h
|
||||
F: configs/imxrt1170-evk_defconfig
|
||||
6
board/freescale/imxrt1170-evk/Makefile
Normal file
6
board/freescale/imxrt1170-evk/Makefile
Normal file
@@ -0,0 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
# Copyright (C) 2019
|
||||
# Author(s): Giulio Benetti <giulio.benetti@benettiengineering.com>
|
||||
|
||||
obj-y := imxrt1170-evk.o
|
||||
31
board/freescale/imxrt1170-evk/imximage.cfg
Normal file
31
board/freescale/imxrt1170-evk/imximage.cfg
Normal file
@@ -0,0 +1,31 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (C) 2022
|
||||
* Author(s): Jesse Taube <Mr.Bossman075@gmail.com>
|
||||
* Giulio Benetti <giulio.benetti@benettiengineering.com>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* image version */
|
||||
|
||||
IMAGE_VERSION 2
|
||||
|
||||
/*
|
||||
* Boot Device : one of
|
||||
* spi/sd/nand/onenand, qspi/nor
|
||||
*/
|
||||
|
||||
BOOT_FROM sd
|
||||
|
||||
/*
|
||||
* Device Configuration Data (DCD)
|
||||
*
|
||||
* Each entry must have the format:
|
||||
* Addr-type Address Value
|
||||
*
|
||||
* where:
|
||||
* Addr-type register length (1,2 or 4 bytes)
|
||||
* Address absolute address of the register
|
||||
* value value to be stored in the register
|
||||
*/
|
||||
80
board/freescale/imxrt1170-evk/imxrt1170-evk.c
Normal file
80
board/freescale/imxrt1170-evk/imxrt1170-evk.c
Normal file
@@ -0,0 +1,80 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2019
|
||||
* Author(s): Giulio Benetti <giulio.benetti@benettiengineering.com>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <init.h>
|
||||
#include <log.h>
|
||||
#include <ram.h>
|
||||
#include <spl.h>
|
||||
#include <asm/global_data.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/armv7m.h>
|
||||
#include <serial.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
#ifndef CONFIG_SUPPORT_SPL
|
||||
int rv;
|
||||
struct udevice *dev;
|
||||
|
||||
rv = uclass_get_device(UCLASS_RAM, 0, &dev);
|
||||
if (rv) {
|
||||
debug("DRAM init failed: %d\n", rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
#endif
|
||||
return fdtdec_setup_mem_size_base();
|
||||
}
|
||||
|
||||
int dram_init_banksize(void)
|
||||
{
|
||||
return fdtdec_setup_memory_banksize();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
#ifdef CONFIG_SPL_OS_BOOT
|
||||
int spl_start_uboot(void)
|
||||
{
|
||||
debug("SPL: booting kernel\n");
|
||||
/* break into full u-boot on 'c' */
|
||||
return serial_tstc() && serial_getc() == 'c';
|
||||
}
|
||||
#endif
|
||||
|
||||
int spl_dram_init(void)
|
||||
{
|
||||
struct udevice *dev;
|
||||
int rv;
|
||||
|
||||
rv = uclass_get_device(UCLASS_RAM, 0, &dev);
|
||||
if (rv)
|
||||
debug("DRAM init failed: %d\n", rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
void spl_board_init(void)
|
||||
{
|
||||
preloader_console_init();
|
||||
spl_dram_init();
|
||||
arch_cpu_init(); /* to configure mpu for sdram rw permissions */
|
||||
}
|
||||
|
||||
u32 spl_boot_device(void)
|
||||
{
|
||||
return BOOT_DEVICE_MMC1;
|
||||
}
|
||||
#endif
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
gd->bd->bi_boot_params = gd->bd->bi_dram[0].start + 0x100;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -20,6 +20,7 @@
|
||||
struct venice_board_info som_info;
|
||||
struct venice_board_info base_info;
|
||||
char venice_model[32];
|
||||
char venice_baseboard_model[32];
|
||||
u32 venice_serial;
|
||||
|
||||
/* return a mac address from EEPROM info */
|
||||
@@ -321,6 +322,7 @@ int eeprom_init(int quiet)
|
||||
base_info.model[3], /* baseboard */
|
||||
base_info.model[4], base_info.model[5], /* subload of baseboard */
|
||||
som_info.model[4], som_info.model[5]); /* last 2digits of SOM */
|
||||
strlcpy(venice_baseboard_model, base_info.model, sizeof(venice_baseboard_model));
|
||||
|
||||
/* baseboard revision */
|
||||
rev_pcb = get_pcb_rev(base_info.model);
|
||||
@@ -357,6 +359,11 @@ const char *eeprom_get_model(void)
|
||||
return venice_model;
|
||||
}
|
||||
|
||||
const char *eeprom_get_baseboard_model(void)
|
||||
{
|
||||
return venice_baseboard_model;
|
||||
}
|
||||
|
||||
u32 eeprom_get_serial(void)
|
||||
{
|
||||
return venice_serial;
|
||||
|
||||
@@ -26,8 +26,11 @@ struct venice_board_info {
|
||||
|
||||
int eeprom_init(int quiet);
|
||||
const char *eeprom_get_model(void);
|
||||
const char *eeprom_get_baseboard_model(void);
|
||||
const char *eeprom_get_dtb_name(int level, char *buf, int len);
|
||||
int eeprom_getmac(int index, uint8_t *enetaddr);
|
||||
uint32_t eeprom_get_serial(void);
|
||||
int get_bom_rev(const char *str);
|
||||
char get_pcb_rev(const char *str);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
* Copyright 2021 Gateworks Corporation
|
||||
*/
|
||||
|
||||
#include <fdt_support.h>
|
||||
#include <init.h>
|
||||
#include <led.h>
|
||||
#include <miiphy.h>
|
||||
@@ -169,26 +170,54 @@ int board_mmc_get_env_dev(int devno)
|
||||
return devno;
|
||||
}
|
||||
|
||||
int ft_board_setup(void *blob, struct bd_info *bd)
|
||||
int ft_board_setup(void *fdt, struct bd_info *bd)
|
||||
{
|
||||
const char *base_model = eeprom_get_baseboard_model();
|
||||
char pcbrev;
|
||||
int off;
|
||||
|
||||
/* set board model dt prop */
|
||||
fdt_setprop_string(blob, 0, "board", eeprom_get_model());
|
||||
fdt_setprop_string(fdt, 0, "board", eeprom_get_model());
|
||||
|
||||
/* update temp thresholds */
|
||||
off = fdt_path_offset(blob, "/thermal-zones/cpu-thermal/trips");
|
||||
off = fdt_path_offset(fdt, "/thermal-zones/cpu-thermal/trips");
|
||||
if (off >= 0) {
|
||||
int minc, maxc, prop;
|
||||
|
||||
get_cpu_temp_grade(&minc, &maxc);
|
||||
fdt_for_each_subnode(prop, blob, off) {
|
||||
const char *type = fdt_getprop(blob, prop, "type", NULL);
|
||||
fdt_for_each_subnode(prop, fdt, off) {
|
||||
const char *type = fdt_getprop(fdt, prop, "type", NULL);
|
||||
|
||||
if (type && (!strcmp("critical", type)))
|
||||
fdt_setprop_u32(blob, prop, "temperature", maxc * 1000);
|
||||
fdt_setprop_u32(fdt, prop, "temperature", maxc * 1000);
|
||||
else if (type && (!strcmp("passive", type)))
|
||||
fdt_setprop_u32(blob, prop, "temperature", (maxc - 10) * 1000);
|
||||
fdt_setprop_u32(fdt, prop, "temperature", (maxc - 10) * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
if (!strncmp(base_model, "GW73", 4)) {
|
||||
pcbrev = get_pcb_rev(base_model);
|
||||
|
||||
if (pcbrev > 'B') {
|
||||
printf("adjusting dt for %s\n", base_model);
|
||||
|
||||
/*
|
||||
* revC replaced PCIe 5-port switch with 4-port
|
||||
* which changed ethernet1 PCIe GbE
|
||||
* from: pcie@0,0/pcie@1,0/pcie@2,4/pcie@6.0
|
||||
* to: pcie@0,0/pcie@1,0/pcie@2,3/pcie@5.0
|
||||
*/
|
||||
off = fdt_path_offset(fdt, "ethernet1");
|
||||
if (off > 0) {
|
||||
u32 reg[5];
|
||||
|
||||
fdt_set_name(fdt, off, "pcie@5,0");
|
||||
off = fdt_parent_offset(fdt, off);
|
||||
fdt_set_name(fdt, off, "pcie@2,3");
|
||||
memset(reg, 0, sizeof(reg));
|
||||
reg[0] = cpu_to_fdt32(PCI_DEVFN(3, 0));
|
||||
fdt_setprop(fdt, off, "reg", reg, sizeof(reg));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
15
board/purism/librem5/Kconfig
Normal file
15
board/purism/librem5/Kconfig
Normal file
@@ -0,0 +1,15 @@
|
||||
if TARGET_LIBREM5
|
||||
|
||||
config SYS_BOARD
|
||||
default "librem5"
|
||||
|
||||
config SYS_VENDOR
|
||||
default "purism"
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
default "librem5"
|
||||
|
||||
config IMX_CONFIG
|
||||
default "board/purism/librem5/imximage-8mq-lpddr4.cfg"
|
||||
|
||||
endif
|
||||
8
board/purism/librem5/MAINTAINERS
Normal file
8
board/purism/librem5/MAINTAINERS
Normal file
@@ -0,0 +1,8 @@
|
||||
PURISM LIBREM5 PHONE
|
||||
M: Angus Ainslie <angus@akkea.ca>
|
||||
R: kernel@puri.sm
|
||||
S: Supported
|
||||
F: arch/arm/dts/imx8mq-librem5*
|
||||
F: board/purism/librem5/
|
||||
F: configs/librem5_defconfig
|
||||
F: include/configs/librem5.h
|
||||
13
board/purism/librem5/Makefile
Normal file
13
board/purism/librem5/Makefile
Normal file
@@ -0,0 +1,13 @@
|
||||
#
|
||||
# Copyright 2017 NXP
|
||||
# Copyright 2019 Purism
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-y += librem5.o
|
||||
|
||||
ifdef CONFIG_SPL_BUILD
|
||||
obj-y += spl.o
|
||||
obj-$(CONFIG_IMX8M_LPDDR4) += lpddr4_timing.o lpddr4_timing_b0.o
|
||||
endif
|
||||
9
board/purism/librem5/imximage-8mq-lpddr4.cfg
Normal file
9
board/purism/librem5/imximage-8mq-lpddr4.cfg
Normal file
@@ -0,0 +1,9 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2021 NXP
|
||||
*/
|
||||
|
||||
FIT
|
||||
BOOT_FROM sd
|
||||
SIGNED_HDMI signed_hdmi.bin
|
||||
LOADER u-boot-spl-ddr.bin 0x7E1000
|
||||
425
board/purism/librem5/librem5.c
Normal file
425
board/purism/librem5/librem5.c
Normal file
@@ -0,0 +1,425 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2018 NXP
|
||||
* Copyright 2021 Purism
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <malloc.h>
|
||||
#include <errno.h>
|
||||
#include <asm/io.h>
|
||||
#include <miiphy.h>
|
||||
#include <asm/mach-imx/iomux-v3.h>
|
||||
#include <asm-generic/gpio.h>
|
||||
#include <asm/arch/sys_proto.h>
|
||||
#include <fsl_esdhc.h>
|
||||
#include <mmc.h>
|
||||
#include <asm/arch/imx8mq_pins.h>
|
||||
#include <asm/arch/sys_proto.h>
|
||||
#include <asm/mach-imx/gpio.h>
|
||||
#include <asm/mach-imx/mxc_i2c.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/mach-imx/video.h>
|
||||
#include <fuse.h>
|
||||
#include <i2c.h>
|
||||
#include <spl.h>
|
||||
#include <usb.h>
|
||||
#include <dwc3-uboot.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <power/regulator.h>
|
||||
#include <usb/xhci.h>
|
||||
#include "librem5.h"
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int board_early_init_f(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_LOAD_ENV_FROM_MMC_BOOT_PARTITION)
|
||||
uint board_mmc_get_env_part(struct mmc *mmc)
|
||||
{
|
||||
uint part = (mmc->part_config >> 3) & PART_ACCESS_MASK;
|
||||
|
||||
if (part == 7)
|
||||
part = 0;
|
||||
return part;
|
||||
}
|
||||
#endif
|
||||
|
||||
int tps65982_wait_for_app(int timeout, int timeout_step)
|
||||
{
|
||||
int ret;
|
||||
char response[6];
|
||||
struct udevice *udev, *bus;
|
||||
|
||||
log_debug("%s: starting\n", __func__);
|
||||
|
||||
/* Set the i2c bus */
|
||||
ret = uclass_get_device_by_seq(UCLASS_I2C, 0, &bus);
|
||||
if (ret) {
|
||||
log_err("%s: No bus %d\n", __func__, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ret = i2c_get_chip(bus, 0x3f, 1, &udev);
|
||||
if (ret) {
|
||||
log_err("%s: setting chip offset failed %d\n", __func__, ret);
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (timeout > 0) {
|
||||
ret = dm_i2c_read(udev, 0x03, (u8 *)response, 5);
|
||||
log_debug("tps65982 mode %s\n", response);
|
||||
if (response[1] == 'A')
|
||||
return 0;
|
||||
mdelay(timeout_step);
|
||||
timeout -= timeout_step;
|
||||
log_debug("tps65982 waited %d ms %c\n", timeout_step, response[1]);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tps65982_clear_dead_battery(void)
|
||||
{
|
||||
int ret;
|
||||
char cmd[5] = "\04DBfg";
|
||||
struct udevice *udev, *bus;
|
||||
|
||||
log_debug("%s: starting\n", __func__);
|
||||
|
||||
/* Set the i2c bus */
|
||||
ret = uclass_get_device_by_seq(UCLASS_I2C, 0, &bus);
|
||||
if (ret) {
|
||||
log_err("%s: No bus %d\n", __func__, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ret = i2c_get_chip(bus, 0x3f, 1, &udev);
|
||||
if (ret) {
|
||||
log_err("%s: setting chip offset failed %d\n", __func__, ret);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* clearing the dead battery flag when not in dead battery condition
|
||||
* is a no-op, so there's no need to check if it's in effect
|
||||
*/
|
||||
ret = dm_i2c_write(udev, 0x08, cmd, 5);
|
||||
if (ret) {
|
||||
log_err("%s: writing 4CC command failed %d", __func__, ret);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define TPS_POWER_STATUS_PWROPMODE(x) FIELD_GET(GENMASK(3, 2), x)
|
||||
|
||||
#define TPS_PDO_CONTRACT_TYPE(x) FIELD_GET(GENMASK(31, 30), x)
|
||||
#define TPS_PDO_CONTRACT_FIXED 0
|
||||
#define TPS_PDO_CONTRACT_BATTERY 1
|
||||
#define TPS_PDO_CONTRACT_VARIABLE 2
|
||||
|
||||
#define TPS_TYPEC_PWR_MODE_USB 0
|
||||
#define TPS_TYPEC_PWR_MODE_1_5A 1
|
||||
#define TPS_TYPEC_PWR_MODE_3_0A 2
|
||||
#define TPS_TYPEC_PWR_MODE_PD 3
|
||||
|
||||
#define TPS_PDO_FIXED_CONTRACT_MAX_CURRENT(x) (FIELD_GET(GENMASK(9, 0), x) * 10)
|
||||
#define TPS_PDO_VAR_CONTRACT_MAX_CURRENT(x) (FIELD_GET(GENMASK(9, 0), x) * 10)
|
||||
#define TPS_PDO_BAT_CONTRACT_MAX_VOLTAGE(x) (FIELD_GET(GENMASK(29, 20), x) * 50)
|
||||
#define TPS_PDO_BAT_CONTRACT_MAX_POWER(x) (FIELD_GET(GENMASK(9, 0), x) * 250)
|
||||
|
||||
int tps65982_get_max_current(void)
|
||||
{
|
||||
int ret;
|
||||
u8 buf[7];
|
||||
u8 pwr_status;
|
||||
u32 contract;
|
||||
int type, mode;
|
||||
struct udevice *udev, *bus;
|
||||
|
||||
log_debug("%s: starting\n", __func__);
|
||||
|
||||
/* Set the i2c bus */
|
||||
ret = uclass_get_device_by_seq(UCLASS_I2C, 0, &bus);
|
||||
if (ret) {
|
||||
log_debug("%s: No bus %d\n", __func__, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = i2c_get_chip(bus, 0x3f, 1, &udev);
|
||||
if (ret) {
|
||||
log_debug("%s: setting chip offset failed %d\n", __func__, ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = dm_i2c_read(udev, 0x3f, buf, 3);
|
||||
if (ret) {
|
||||
log_debug("%s: reading pwr_status failed %d\n", __func__, ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pwr_status = buf[1];
|
||||
|
||||
if (!(pwr_status & 1))
|
||||
return 0;
|
||||
|
||||
mode = TPS_POWER_STATUS_PWROPMODE(pwr_status);
|
||||
switch (mode) {
|
||||
case TPS_TYPEC_PWR_MODE_1_5A:
|
||||
return 1500;
|
||||
case TPS_TYPEC_PWR_MODE_3_0A:
|
||||
return 3000;
|
||||
case TPS_TYPEC_PWR_MODE_PD:
|
||||
ret = dm_i2c_read(udev, 0x34, buf, 7);
|
||||
if (ret) {
|
||||
log_debug("%s: reading active contract failed %d\n", __func__, ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
contract = buf[1] + (buf[2] << 8) + (buf[3] << 16) + (buf[4] << 24);
|
||||
|
||||
type = TPS_PDO_CONTRACT_TYPE(contract);
|
||||
|
||||
switch (type) {
|
||||
case TPS_PDO_CONTRACT_FIXED:
|
||||
return TPS_PDO_FIXED_CONTRACT_MAX_CURRENT(contract);
|
||||
case TPS_PDO_CONTRACT_BATTERY:
|
||||
return 1000 * TPS_PDO_BAT_CONTRACT_MAX_POWER(contract)
|
||||
/ TPS_PDO_BAT_CONTRACT_MAX_VOLTAGE(contract);
|
||||
case TPS_PDO_CONTRACT_VARIABLE:
|
||||
return TPS_PDO_VAR_CONTRACT_MAX_CURRENT(contract);
|
||||
default:
|
||||
log_debug("Unknown contract type: %d\n", type);
|
||||
return -1;
|
||||
}
|
||||
case TPS_TYPEC_PWR_MODE_USB:
|
||||
return 500;
|
||||
default:
|
||||
log_debug("Unknown power mode: %d\n", mode);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int init_tps65982(void)
|
||||
{
|
||||
log_debug("%s: starting\n", __func__);
|
||||
|
||||
if (tps65982_wait_for_app(500, 100)) {
|
||||
log_err("tps65982 APP boot failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
log_info("tps65982 boot successful\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bq25895_set_iinlim(int current)
|
||||
{
|
||||
u8 val, iinlim;
|
||||
int ret;
|
||||
struct udevice *udev, *bus;
|
||||
|
||||
/* Set the i2c bus */
|
||||
ret = uclass_get_device_by_seq(UCLASS_I2C, 3, &bus);
|
||||
if (ret) {
|
||||
log_err("%s: No bus 3\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = i2c_get_chip(bus, 0x6a, 1, &udev);
|
||||
if (ret) {
|
||||
log_err("%s: setting chip offset failed %d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (current > 3250)
|
||||
current = 3250;
|
||||
if (current < 100)
|
||||
current = 100;
|
||||
|
||||
val = dm_i2c_reg_read(udev, 0x00);
|
||||
iinlim = ((current - 100) / 50) & 0x3f;
|
||||
val = (val & 0xc0) | iinlim;
|
||||
dm_i2c_reg_write(udev, 0x00, val);
|
||||
log_debug("REG00 0x%x\n", val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool bq25895_battery_present(void)
|
||||
{
|
||||
u8 val;
|
||||
int ret;
|
||||
struct udevice *udev, *bus;
|
||||
|
||||
/* Set the i2c bus */
|
||||
ret = uclass_get_device_by_seq(UCLASS_I2C, 3, &bus);
|
||||
if (ret) {
|
||||
log_err("%s: No bus 3\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = i2c_get_chip(bus, 0x6a, 1, &udev);
|
||||
if (ret) {
|
||||
log_err("%s: setting chip offset failed %d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* note that this may return false negatives when there's
|
||||
* no external power applied and the battery voltage is below
|
||||
* Vsys. this isn't a problem when used for clearing the dead
|
||||
* battery flag though, since it's certain that there's an external
|
||||
* power applied in this case
|
||||
*/
|
||||
val = dm_i2c_reg_read(udev, 0x0e) & 0x7f;
|
||||
if (val == 0x00 || val == 0x7f)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* set some safe defaults for the battery charger
|
||||
*/
|
||||
int init_charger_bq25895(void)
|
||||
{
|
||||
u8 val;
|
||||
int iinlim, ret;
|
||||
struct udevice *udev, *bus;
|
||||
|
||||
/* Set the i2c bus */
|
||||
ret = uclass_get_device_by_seq(UCLASS_I2C, 3, &bus);
|
||||
if (ret) {
|
||||
log_debug("%s: No bus 3\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = i2c_get_chip(bus, 0x6a, 1, &udev);
|
||||
if (ret) {
|
||||
log_debug("%s: setting chip offset failed %d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
val = dm_i2c_reg_read(udev, 0x0b);
|
||||
log_debug("REG0B 0x%x\n", val);
|
||||
|
||||
log_debug("VBUS_STAT 0x%x\n", val >> 5);
|
||||
switch (val >> 5) {
|
||||
case 0:
|
||||
log_debug("VBUS not detected\n");
|
||||
break;
|
||||
case 1:
|
||||
log_debug("USB SDP IINLIM 500mA\n");
|
||||
break;
|
||||
case 2:
|
||||
log_debug("USB CDP IINLIM 1500mA\n");
|
||||
break;
|
||||
case 3:
|
||||
log_debug("USB DCP IINLIM 3500mA\n");
|
||||
break;
|
||||
case 4:
|
||||
log_debug("MAXCHARGE IINLIM 1500mA\n");
|
||||
break;
|
||||
case 5:
|
||||
log_debug("Unknown IINLIM 500mA\n");
|
||||
break;
|
||||
case 6:
|
||||
log_debug("DIVIDER IINLIM > 1000mA\n");
|
||||
break;
|
||||
case 7:
|
||||
log_debug("OTG\n");
|
||||
break;
|
||||
};
|
||||
|
||||
log_debug("CHRG_STAT 0x%x\n", (val >> 3) & 0x3);
|
||||
log_debug("PG_STAT 0x%x\n", (val >> 2) & 1);
|
||||
log_debug("SDP_STAT 0x%x\n", (val >> 1) & 1);
|
||||
log_debug("VSYS_STAT 0x%x\n", val & 1);
|
||||
|
||||
val = dm_i2c_reg_read(udev, 0x00);
|
||||
log_debug("REG00 0x%x\n", val);
|
||||
iinlim = 100 + (val & 0x3f) * 50;
|
||||
log_debug("IINLIM %d mA\n", iinlim);
|
||||
log_debug("EN_HIZ 0x%x\n", (val >> 7) & 1);
|
||||
log_debug("EN_ILIM 0x%x\n", (val >> 6) & 1);
|
||||
|
||||
/* set 1.6A charge limit */
|
||||
dm_i2c_reg_write(udev, 0x04, 0x19);
|
||||
|
||||
/* re-enable charger */
|
||||
val = dm_i2c_reg_read(udev, 0x03);
|
||||
val = val | 0x10;
|
||||
dm_i2c_reg_write(udev, 0x03, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
struct udevice *dev;
|
||||
int tps_ret;
|
||||
|
||||
if (IS_ENABLED(CONFIG_USB_DWC3) || IS_ENABLED(CONFIG_USB_XHCI_IMX8M)) {
|
||||
log_debug("%s: initializing USB clk\n", __func__);
|
||||
|
||||
/* init_usb_clk won't enable the second clock if it's a USB boot */
|
||||
if (is_usb_boot()) {
|
||||
clock_enable(CCGR_USB_CTRL2, 1);
|
||||
clock_enable(CCGR_USB_PHY2, 1);
|
||||
}
|
||||
|
||||
printf("Enabling regulator-hub\n");
|
||||
if (!regulator_get_by_devname("regulator-hub", &dev)) {
|
||||
if (regulator_set_enable(dev, true))
|
||||
pr_err("Failed to enable regulator-hub\n");
|
||||
}
|
||||
}
|
||||
|
||||
tps_ret = init_tps65982();
|
||||
init_charger_bq25895();
|
||||
|
||||
if (!tps_ret) {
|
||||
int current = tps65982_get_max_current();
|
||||
|
||||
if (current > 500)
|
||||
bq25895_set_iinlim(current);
|
||||
|
||||
if (bq25895_battery_present())
|
||||
tps65982_clear_dead_battery();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_late_init(void)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG)) {
|
||||
u32 rev;
|
||||
char rev_str[3];
|
||||
|
||||
env_set("board_name", "librem5");
|
||||
if (fuse_read(9, 0, &rev)) {
|
||||
env_set("board_rev", BOARD_REV_ERROR);
|
||||
} else if (rev == 0) {
|
||||
env_set("board_rev", BOARD_REV_UNKNOWN);
|
||||
} else if (rev > 0) {
|
||||
sprintf(rev_str, "%u", rev);
|
||||
env_set("board_rev", rev_str);
|
||||
}
|
||||
|
||||
printf("Board name: %s\n", env_get("board_name"));
|
||||
printf("Board rev: %s\n", env_get("board_rev"));
|
||||
}
|
||||
|
||||
if (is_usb_boot()) {
|
||||
puts("USB Boot\n");
|
||||
env_set("bootcmd", "fastboot 0");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
181
board/purism/librem5/librem5.h
Normal file
181
board/purism/librem5/librem5.h
Normal file
@@ -0,0 +1,181 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2021 Purism
|
||||
*/
|
||||
|
||||
#ifndef __LIBREM5_H__
|
||||
#define __LIBREM5_H__
|
||||
|
||||
#define CAMERA_EN IMX_GPIO_NR(1, 0)
|
||||
#define SD_EN IMX_GPIO_NR(1, 3)
|
||||
#define AUDIO_EN IMX_GPIO_NR(1, 4)
|
||||
#define DSI_EN IMX_GPIO_NR(1, 5)
|
||||
#define SMC_EN IMX_GPIO_NR(1, 6)
|
||||
#define TYPEC_MUX_EN IMX_GPIO_NR(1, 11)
|
||||
#define HUB_NRESET IMX_GPIO_NR(1, 12)
|
||||
#define HUB_EN IMX_GPIO_NR(1, 14)
|
||||
#define VOL_UP IMX_GPIO_NR(1, 16)
|
||||
#define VOL_DOWN IMX_GPIO_NR(1, 17)
|
||||
#define DSI_BIAS_EN IMX_GPIO_NR(1, 20)
|
||||
#define FLASH_EN IMX_GPIO_NR(1, 23)
|
||||
#define WWAN_NRESET IMX_GPIO_NR(3, 1)
|
||||
#define CHG_EN IMX_GPIO_NR(3, 2)
|
||||
#define CHG_OTG_OUT_EN IMX_GPIO_NR(3, 4)
|
||||
#define WIFI_EN IMX_GPIO_NR(3, 10)
|
||||
#define GPS_EN IMX_GPIO_NR(3, 12)
|
||||
#define BL_EN IMX_GPIO_NR(3, 14)
|
||||
#define WWAN_EN IMX_GPIO_NR(3, 18)
|
||||
#define NFC_EN IMX_GPIO_NR(4, 28)
|
||||
#define LED_G IMX_GPIO_NR(5, 2)
|
||||
#define LED_R IMX_GPIO_NR(5, 3)
|
||||
#define LED_B IMX_GPIO_NR(1, 13)
|
||||
#define MOTO IMX_GPIO_NR(5, 5)
|
||||
#define SPI1_SCLK IMX_GPIO_NR(5, 6)
|
||||
#define SPI1_MOSI IMX_GPIO_NR(5, 7)
|
||||
#define SPI1_MISO IMX_GPIO_NR(5, 8)
|
||||
#define SPI1_SS0 IMX_GPIO_NR(5, 9)
|
||||
|
||||
#define UART1_TX IMX_GPIO_NR(5, 23)
|
||||
#define UART1_RX IMX_GPIO_NR(5, 22)
|
||||
#define UART2_TX IMX_GPIO_NR(5, 25)
|
||||
#define UART2_RX IMX_GPIO_NR(5, 24)
|
||||
#define UART3_TX IMX_GPIO_NR(5, 27)
|
||||
#define UART3_RX IMX_GPIO_NR(5, 26)
|
||||
#define UART4_TX IMX_GPIO_NR(5, 11)
|
||||
#define UART4_RX IMX_GPIO_NR(5, 10)
|
||||
|
||||
#define TPS_RESET IMX_GPIO_NR(3, 24)
|
||||
|
||||
#define PURISM_VID 0x316d
|
||||
#define PURISM_PID 0x4c05
|
||||
|
||||
#define BOARD_REV_ERROR "unknown"
|
||||
#define BOARD_REV_BIRCH "1"
|
||||
#define BOARD_REV_CHESTNUT "2"
|
||||
#define BOARD_REV_DOGWOOD "3"
|
||||
#define BOARD_REV_EVERGREEN "4"
|
||||
/* Could be ASPEN, BIRCH or CHESTNUT. assume CHESTNUT */
|
||||
#define BOARD_REV_UNKNOWN BOARD_REV_CHESTNUT
|
||||
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
static const iomux_v3_cfg_t configure_pads[] = {
|
||||
IMX8MQ_PAD_GPIO1_IO00__GPIO1_IO0 | MUX_PAD_CTRL(PAD_CTL_DSE6),
|
||||
IMX8MQ_PAD_GPIO1_IO03__GPIO1_IO3 | MUX_PAD_CTRL(PAD_CTL_DSE6) | MUX_MODE_SION,
|
||||
IMX8MQ_PAD_GPIO1_IO04__GPIO1_IO4 | MUX_PAD_CTRL(PAD_CTL_DSE6),
|
||||
IMX8MQ_PAD_GPIO1_IO05__GPIO1_IO5 | MUX_PAD_CTRL(PAD_CTL_DSE6) | MUX_MODE_SION,
|
||||
IMX8MQ_PAD_GPIO1_IO06__GPIO1_IO6 | MUX_PAD_CTRL(PAD_CTL_DSE6),
|
||||
IMX8MQ_PAD_GPIO1_IO11__GPIO1_IO11 | MUX_PAD_CTRL(PAD_CTL_DSE6),
|
||||
IMX8MQ_PAD_GPIO1_IO12__GPIO1_IO12 | MUX_PAD_CTRL(PAD_CTL_DSE6) | MUX_MODE_SION,
|
||||
IMX8MQ_PAD_GPIO1_IO13__GPIO1_IO13 | MUX_PAD_CTRL(PAD_CTL_DSE6) | MUX_MODE_SION,
|
||||
IMX8MQ_PAD_GPIO1_IO14__GPIO1_IO14 | MUX_PAD_CTRL(PAD_CTL_DSE6) | MUX_MODE_SION,
|
||||
IMX8MQ_PAD_ENET_MDC__GPIO1_IO16 | MUX_PAD_CTRL(PAD_CTL_PUE),
|
||||
IMX8MQ_PAD_ENET_MDIO__GPIO1_IO17 | MUX_PAD_CTRL(PAD_CTL_PUE),
|
||||
IMX8MQ_PAD_ENET_TD1__GPIO1_IO20 | MUX_PAD_CTRL(PAD_CTL_DSE6),
|
||||
IMX8MQ_PAD_ENET_TXC__GPIO1_IO23 | MUX_PAD_CTRL(PAD_CTL_DSE6),
|
||||
IMX8MQ_PAD_NAND_CE0_B__GPIO3_IO1 | MUX_PAD_CTRL(PAD_CTL_DSE6),
|
||||
IMX8MQ_PAD_NAND_CE1_B__GPIO3_IO2 | MUX_PAD_CTRL(PAD_CTL_DSE6),
|
||||
IMX8MQ_PAD_NAND_CE3_B__GPIO3_IO4 | MUX_PAD_CTRL(PAD_CTL_DSE6),
|
||||
IMX8MQ_PAD_NAND_DATA04__GPIO3_IO10 | MUX_PAD_CTRL(PAD_CTL_DSE6),
|
||||
IMX8MQ_PAD_NAND_DATA06__GPIO3_IO12 | MUX_PAD_CTRL(PAD_CTL_DSE6),
|
||||
IMX8MQ_PAD_NAND_DQS__GPIO3_IO14 | MUX_PAD_CTRL(PAD_CTL_DSE6),
|
||||
IMX8MQ_PAD_NAND_WP_B__GPIO3_IO18 | MUX_PAD_CTRL(PAD_CTL_DSE6),
|
||||
IMX8MQ_PAD_SAI3_RXFS__GPIO4_IO28 | MUX_PAD_CTRL(PAD_CTL_DSE6),
|
||||
IMX8MQ_PAD_SAI3_MCLK__GPIO5_IO2 | MUX_PAD_CTRL(PAD_CTL_DSE6) | MUX_MODE_SION,
|
||||
IMX8MQ_PAD_SPDIF_TX__GPIO5_IO3 | MUX_PAD_CTRL(PAD_CTL_DSE6) | MUX_MODE_SION,
|
||||
IMX8MQ_PAD_SAI5_RXD3__GPIO3_IO24 | MUX_PAD_CTRL(PAD_CTL_DSE6) | MUX_MODE_SION,
|
||||
};
|
||||
|
||||
static inline void init_pinmux(void)
|
||||
{
|
||||
imx_iomux_v3_setup_multiple_pads(configure_pads, ARRAY_SIZE(configure_pads));
|
||||
|
||||
gpio_request(LED_R, "LED_R");
|
||||
gpio_request(LED_G, "LED_G");
|
||||
gpio_request(LED_B, "LED_B");
|
||||
gpio_request(VOL_UP, "VOL_UP");
|
||||
gpio_request(VOL_DOWN, "VOL_DOWN");
|
||||
|
||||
gpio_request(NFC_EN, "NFC_EN");
|
||||
gpio_request(CHG_EN, "CHG_EN");
|
||||
gpio_request(CHG_OTG_OUT_EN, "CHG_OTG_OUT_EN");
|
||||
|
||||
gpio_request(TYPEC_MUX_EN, "TYPEC_MUX_EN");
|
||||
|
||||
gpio_request(TPS_RESET, "TPS_RESET");
|
||||
|
||||
gpio_request(WWAN_EN, "WWAN_EN");
|
||||
gpio_request(WWAN_NRESET, "WWAN_NRESET");
|
||||
|
||||
gpio_request(HUB_EN, "HUB_EN");
|
||||
gpio_request(HUB_NRESET, "HUB_NRESET");
|
||||
gpio_request(SD_EN, "SD_EN");
|
||||
gpio_request(AUDIO_EN, "AUDIO_EN");
|
||||
gpio_request(DSI_EN, "DSI_EN");
|
||||
gpio_request(SMC_EN, "SMC_EN");
|
||||
gpio_request(CAMERA_EN, "CAMERA_EN");
|
||||
gpio_request(FLASH_EN, "FLASH_EN");
|
||||
gpio_request(DSI_BIAS_EN, "DSI_BIAS_EN");
|
||||
gpio_request(GPS_EN, "GPS_EN");
|
||||
gpio_request(BL_EN, "BL_EN");
|
||||
#ifndef CONSOLE_ON_UART4
|
||||
gpio_request(WIFI_EN, "WIFI_EN");
|
||||
gpio_direction_output(WIFI_EN, 0);
|
||||
#endif /* CONSOLE_ON_UART4 */
|
||||
gpio_direction_input(VOL_UP);
|
||||
gpio_direction_input(VOL_DOWN);
|
||||
|
||||
/* ensure charger is in the automated mode */
|
||||
gpio_direction_output(NFC_EN, 0);
|
||||
gpio_direction_output(CHG_EN, 0);
|
||||
gpio_direction_output(CHG_OTG_OUT_EN, 0);
|
||||
|
||||
gpio_direction_input(TYPEC_MUX_EN);
|
||||
|
||||
gpio_direction_output(TPS_RESET, 0);
|
||||
|
||||
gpio_direction_output(WWAN_EN, 0);
|
||||
gpio_direction_output(WWAN_NRESET, 1);
|
||||
|
||||
gpio_direction_output(HUB_EN, 1);
|
||||
gpio_direction_output(HUB_NRESET, 1);
|
||||
mdelay(10);
|
||||
gpio_direction_output(SD_EN, 1);
|
||||
gpio_direction_output(SMC_EN, 0);
|
||||
gpio_direction_output(CAMERA_EN, 0);
|
||||
gpio_direction_output(FLASH_EN, 0);
|
||||
gpio_direction_output(DSI_BIAS_EN, 0);
|
||||
gpio_direction_output(GPS_EN, 0);
|
||||
gpio_direction_output(BL_EN, 0);
|
||||
|
||||
/* turn these on for i2c busses */
|
||||
gpio_direction_output(AUDIO_EN, 1);
|
||||
gpio_direction_output(DSI_EN, 1);
|
||||
}
|
||||
#endif /* CONFIG_SPL_BUILD */
|
||||
|
||||
#define USB1_BASE_ADDR 0x38100000
|
||||
#define USB2_BASE_ADDR 0x38200000
|
||||
#define USB1_PHY_BASE_ADDR 0x381F0000
|
||||
#define USB2_PHY_BASE_ADDR 0x382F0000
|
||||
|
||||
#define USB_PHY_CTRL0 0xF0040
|
||||
#define USB_PHY_CTRL0_REF_SSP_EN BIT(2)
|
||||
#define USB_PHY_CTRL0_SSC_RANGE_MASK GENMASK(23, 21)
|
||||
#define USB_PHY_CTRL0_SSC_RANGE_4003PPM (0x2 << 21)
|
||||
|
||||
#define USB_PHY_CTRL1 0xF0044
|
||||
#define USB_PHY_CTRL1_RESET BIT(0)
|
||||
#define USB_PHY_CTRL1_COMMONONN BIT(1)
|
||||
#define USB_PHY_CTRL1_ATERESET BIT(3)
|
||||
#define USB_PHY_CTRL1_VDATSRCENB0 BIT(19)
|
||||
#define USB_PHY_CTRL1_VDATDETENB0 BIT(20)
|
||||
|
||||
#define USB_PHY_CTRL2 0xF0048
|
||||
#define USB_PHY_CTRL2_TXENABLEN0 BIT(8)
|
||||
|
||||
#define USB_PHY_CTRL6 0x18
|
||||
#define USB_PHY_CTRL6_RXTERM_OVERRIDE_SEL BIT(29)
|
||||
|
||||
extern struct dram_timing_info dram_timing_b0;
|
||||
|
||||
#endif
|
||||
1324
board/purism/librem5/lpddr4_timing.c
Normal file
1324
board/purism/librem5/lpddr4_timing.c
Normal file
File diff suppressed because it is too large
Load Diff
1191
board/purism/librem5/lpddr4_timing_b0.c
Normal file
1191
board/purism/librem5/lpddr4_timing_b0.c
Normal file
File diff suppressed because it is too large
Load Diff
592
board/purism/librem5/spl.c
Normal file
592
board/purism/librem5/spl.c
Normal file
@@ -0,0 +1,592 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2018 NXP
|
||||
* Copyright 2021 Purism
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <errno.h>
|
||||
#include <asm/io.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/boot_mode.h>
|
||||
#include <asm/mach-imx/iomux-v3.h>
|
||||
#include <asm/mach-imx/gpio.h>
|
||||
#include <asm/mach-imx/mxc_i2c.h>
|
||||
#include <fsl_esdhc_imx.h>
|
||||
#include <mmc.h>
|
||||
#include <power/pmic.h>
|
||||
#include <power/bd71837.h>
|
||||
#include <hang.h>
|
||||
#include <init.h>
|
||||
#include <spl.h>
|
||||
#include <usb.h>
|
||||
#include <dwc3-uboot.h>
|
||||
#include <linux/delay.h>
|
||||
#include "librem5.h"
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
void spl_dram_init(void)
|
||||
{
|
||||
/* ddr init */
|
||||
if ((get_cpu_rev() & 0xfff) == CHIP_REV_2_1)
|
||||
ddr_init(&dram_timing);
|
||||
else
|
||||
ddr_init(&dram_timing_b0);
|
||||
}
|
||||
|
||||
int spl_board_boot_device(enum boot_device boot_dev_spl)
|
||||
{
|
||||
log_debug("%s : starting\n", __func__);
|
||||
|
||||
switch (boot_dev_spl) {
|
||||
case SD1_BOOT:
|
||||
case MMC1_BOOT:
|
||||
return BOOT_DEVICE_MMC1;
|
||||
case USB_BOOT:
|
||||
return BOOT_DEVICE_BOARD;
|
||||
default:
|
||||
return BOOT_DEVICE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
#define ECSPI_PAD_CTRL (PAD_CTL_DSE2 | PAD_CTL_HYS)
|
||||
|
||||
static const iomux_v3_cfg_t ecspi_pads[] = {
|
||||
IMX8MQ_PAD_ECSPI1_SCLK__ECSPI1_SCLK | MUX_PAD_CTRL(ECSPI_PAD_CTRL),
|
||||
IMX8MQ_PAD_ECSPI1_SS0__GPIO5_IO9 | MUX_PAD_CTRL(ECSPI_PAD_CTRL),
|
||||
IMX8MQ_PAD_ECSPI1_MOSI__ECSPI1_MOSI | MUX_PAD_CTRL(ECSPI_PAD_CTRL),
|
||||
IMX8MQ_PAD_ECSPI1_MISO__ECSPI1_MISO | MUX_PAD_CTRL(ECSPI_PAD_CTRL),
|
||||
};
|
||||
|
||||
int board_ecspi_init(void)
|
||||
{
|
||||
imx_iomux_v3_setup_multiple_pads(ecspi_pads, ARRAY_SIZE(ecspi_pads));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_spi_cs_gpio(unsigned int bus, unsigned int cs)
|
||||
{
|
||||
return (bus == 0 && cs == 0) ? (SPI1_SS0) : -1;
|
||||
}
|
||||
|
||||
#define I2C_PAD_CTRL (PAD_CTL_PUE | PAD_CTL_ODE | PAD_CTL_DSE7 | PAD_CTL_FSEL3)
|
||||
#define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
|
||||
struct i2c_pads_info i2c_pad_info1 = {
|
||||
.scl = {
|
||||
.i2c_mode = IMX8MQ_PAD_I2C1_SCL__I2C1_SCL | PC,
|
||||
.gpio_mode = IMX8MQ_PAD_I2C1_SCL__GPIO5_IO14 | PC,
|
||||
.gp = IMX_GPIO_NR(5, 14),
|
||||
},
|
||||
.sda = {
|
||||
.i2c_mode = IMX8MQ_PAD_I2C1_SDA__I2C1_SDA | PC,
|
||||
.gpio_mode = IMX8MQ_PAD_I2C1_SDA__GPIO5_IO15 | PC,
|
||||
.gp = IMX_GPIO_NR(5, 15),
|
||||
},
|
||||
};
|
||||
|
||||
struct i2c_pads_info i2c_pad_info2 = {
|
||||
.scl = {
|
||||
.i2c_mode = IMX8MQ_PAD_I2C2_SCL__I2C2_SCL | PC,
|
||||
.gpio_mode = IMX8MQ_PAD_I2C2_SCL__GPIO5_IO16 | PC,
|
||||
.gp = IMX_GPIO_NR(5, 16),
|
||||
},
|
||||
.sda = {
|
||||
.i2c_mode = IMX8MQ_PAD_I2C2_SDA__I2C2_SDA | PC,
|
||||
.gpio_mode = IMX8MQ_PAD_I2C2_SDA__GPIO5_IO17 | PC,
|
||||
.gp = IMX_GPIO_NR(5, 17),
|
||||
},
|
||||
};
|
||||
|
||||
struct i2c_pads_info i2c_pad_info3 = {
|
||||
.scl = {
|
||||
.i2c_mode = IMX8MQ_PAD_I2C3_SCL__I2C3_SCL | PC,
|
||||
.gpio_mode = IMX8MQ_PAD_I2C3_SCL__GPIO5_IO18 | PC,
|
||||
.gp = IMX_GPIO_NR(5, 18),
|
||||
},
|
||||
.sda = {
|
||||
.i2c_mode = IMX8MQ_PAD_I2C3_SDA__I2C3_SDA | PC,
|
||||
.gpio_mode = IMX8MQ_PAD_I2C3_SDA__GPIO5_IO19 | PC,
|
||||
.gp = IMX_GPIO_NR(5, 19),
|
||||
},
|
||||
};
|
||||
|
||||
struct i2c_pads_info i2c_pad_info4 = {
|
||||
.scl = {
|
||||
.i2c_mode = IMX8MQ_PAD_I2C4_SCL__I2C4_SCL | PC,
|
||||
.gpio_mode = IMX8MQ_PAD_I2C4_SCL__GPIO5_IO20 | PC,
|
||||
.gp = IMX_GPIO_NR(5, 20),
|
||||
},
|
||||
.sda = {
|
||||
.i2c_mode = IMX8MQ_PAD_I2C4_SDA__I2C4_SDA | PC,
|
||||
.gpio_mode = IMX8MQ_PAD_I2C4_SDA__GPIO5_IO21 | PC,
|
||||
.gp = IMX_GPIO_NR(5, 21),
|
||||
},
|
||||
};
|
||||
|
||||
#define UART_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_FSEL1)
|
||||
|
||||
static const iomux_v3_cfg_t uart_pads[] = {
|
||||
IMX8MQ_PAD_UART1_RXD__UART1_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
|
||||
IMX8MQ_PAD_UART1_TXD__UART1_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
|
||||
IMX8MQ_PAD_UART2_RXD__UART2_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
|
||||
IMX8MQ_PAD_UART2_TXD__UART2_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
|
||||
IMX8MQ_PAD_UART3_RXD__UART3_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
|
||||
IMX8MQ_PAD_UART3_TXD__UART3_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
|
||||
IMX8MQ_PAD_ECSPI2_SCLK__UART4_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
|
||||
IMX8MQ_PAD_ECSPI2_MOSI__UART4_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
|
||||
};
|
||||
|
||||
#define USDHC1_PWR_GPIO IMX_GPIO_NR(2, 10)
|
||||
#define USDHC2_PWR_GPIO IMX_GPIO_NR(2, 19)
|
||||
|
||||
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 USDHC1_BASE_ADDR:
|
||||
ret = 1;
|
||||
break;
|
||||
case USDHC2_BASE_ADDR:
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define USDHC_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_HYS | PAD_CTL_PUE | \
|
||||
PAD_CTL_FSEL1)
|
||||
#define USDHC_GPIO_PAD_CTRL (PAD_CTL_PUE | PAD_CTL_DSE1)
|
||||
|
||||
static const iomux_v3_cfg_t usdhc1_pads[] = {
|
||||
IMX8MQ_PAD_SD1_CLK__USDHC1_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
|
||||
IMX8MQ_PAD_SD1_CMD__USDHC1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
|
||||
IMX8MQ_PAD_SD1_DATA0__USDHC1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
|
||||
IMX8MQ_PAD_SD1_DATA1__USDHC1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
|
||||
IMX8MQ_PAD_SD1_DATA2__USDHC1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
|
||||
IMX8MQ_PAD_SD1_DATA3__USDHC1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
|
||||
IMX8MQ_PAD_SD1_DATA4__USDHC1_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
|
||||
IMX8MQ_PAD_SD1_DATA5__USDHC1_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
|
||||
IMX8MQ_PAD_SD1_DATA6__USDHC1_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
|
||||
IMX8MQ_PAD_SD1_DATA7__USDHC1_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
|
||||
IMX8MQ_PAD_SD1_RESET_B__GPIO2_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL),
|
||||
};
|
||||
|
||||
static const iomux_v3_cfg_t usdhc2_pads[] = {
|
||||
IMX8MQ_PAD_SD2_CLK__USDHC2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0xd6 */
|
||||
IMX8MQ_PAD_SD2_CMD__USDHC2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0xd6 */
|
||||
IMX8MQ_PAD_SD2_DATA0__USDHC2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0xd6 */
|
||||
IMX8MQ_PAD_SD2_DATA1__USDHC2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0xd6 */
|
||||
IMX8MQ_PAD_SD2_DATA2__USDHC2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0x16 */
|
||||
IMX8MQ_PAD_SD2_DATA3__USDHC2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), /* 0xd6 */
|
||||
IMX8MQ_PAD_SD2_RESET_B__GPIO2_IO19 | MUX_PAD_CTRL(USDHC_GPIO_PAD_CTRL),
|
||||
};
|
||||
|
||||
static struct fsl_esdhc_cfg usdhc_cfg[2] = {
|
||||
{USDHC1_BASE_ADDR, 0, 8},
|
||||
{USDHC2_BASE_ADDR, 0, 4},
|
||||
};
|
||||
|
||||
int board_mmc_init(struct bd_info *bis)
|
||||
{
|
||||
int i, ret;
|
||||
/*
|
||||
* According to the board_mmc_init() the following map is done:
|
||||
* (U-Boot device node) (Physical Port)
|
||||
* mmc0 USDHC1
|
||||
* mmc1 USDHC2
|
||||
*/
|
||||
for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) {
|
||||
log_debug("Initializing FSL USDHC port %d\n", i);
|
||||
switch (i) {
|
||||
case 0:
|
||||
init_clk_usdhc(0);
|
||||
usdhc_cfg[0].sdhc_clk = mxc_get_clock(USDHC1_CLK_ROOT);
|
||||
imx_iomux_v3_setup_multiple_pads(usdhc1_pads,
|
||||
ARRAY_SIZE(usdhc1_pads));
|
||||
gpio_request(USDHC1_PWR_GPIO, "usdhc1_reset");
|
||||
gpio_direction_output(USDHC1_PWR_GPIO, 0);
|
||||
udelay(500);
|
||||
gpio_direction_output(USDHC1_PWR_GPIO, 1);
|
||||
break;
|
||||
case 1:
|
||||
init_clk_usdhc(1);
|
||||
usdhc_cfg[1].sdhc_clk = mxc_get_clock(USDHC2_CLK_ROOT);
|
||||
imx_iomux_v3_setup_multiple_pads(usdhc2_pads,
|
||||
ARRAY_SIZE(usdhc2_pads));
|
||||
gpio_request(USDHC2_PWR_GPIO, "usdhc2_reset");
|
||||
gpio_direction_output(USDHC2_PWR_GPIO, 0);
|
||||
udelay(500);
|
||||
gpio_direction_output(USDHC2_PWR_GPIO, 1);
|
||||
break;
|
||||
default:
|
||||
log_err("Warning: USDHC controller(%d) not supported\n", i + 1);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define LDO_VOLT_EN BIT(6)
|
||||
|
||||
/*
|
||||
* Disable the charger - it will be re-enabled in u-boot
|
||||
*/
|
||||
void disable_charger_bq25895(void)
|
||||
{
|
||||
u8 val;
|
||||
int timeout = 1000; // ms
|
||||
|
||||
/* Set the i2c bus */
|
||||
i2c_set_bus_num(3);
|
||||
|
||||
/* disable ship mode if BATFET_DLY is set */
|
||||
val = i2c_reg_read(0x6a, 0x09);
|
||||
log_debug("REG09 0x%x\n", val);
|
||||
if (val & 0x28) {
|
||||
val = val & ~0x28;
|
||||
i2c_reg_write(0x6a, 0x09, val);
|
||||
}
|
||||
|
||||
/* disable and trigger DPDM, ICO, HVDCP and MaxCharge */
|
||||
val = i2c_reg_read(0x6a, 0x02);
|
||||
log_debug("REG02 0x%x\n", val);
|
||||
val &= 0xe0;
|
||||
i2c_reg_write(0x6a, 0x02, val);
|
||||
|
||||
/* disable charger and enable BAT_LOADEN */
|
||||
val = i2c_reg_read(0x6a, 0x03);
|
||||
log_debug("REG03 0x%x\n", val);
|
||||
val = (val | 0x80) & ~0x10;
|
||||
i2c_reg_write(0x6a, 0x03, val);
|
||||
|
||||
mdelay(10);
|
||||
|
||||
/* force ADC conversions */
|
||||
val = i2c_reg_read(0x6a, 0x02);
|
||||
log_debug("REG02 0x%x\n", val);
|
||||
val = (val | 0x80) & ~0x40;
|
||||
i2c_reg_write(0x6a, 0x02, val);
|
||||
|
||||
do {
|
||||
mdelay(10);
|
||||
timeout -= 10;
|
||||
} while ((i2c_reg_read(0x6a, 0x02) & 0x80) && (timeout > 0));
|
||||
|
||||
/* enable STAT pin */
|
||||
val = i2c_reg_read(0x6a, 0x07);
|
||||
log_debug("REG07 0x%x\n", val);
|
||||
val = val & ~0x40;
|
||||
i2c_reg_write(0x6a, 0x07, val);
|
||||
|
||||
/* check VBUS */
|
||||
val = i2c_reg_read(0x6a, 0x11);
|
||||
log_debug("VBUS good %d\n", (val >> 7) & 1);
|
||||
log_debug("VBUS mV %d\n", (val & 0x7f) * 100 + 2600);
|
||||
|
||||
/* check VBAT */
|
||||
val = i2c_reg_read(0x6a, 0x0e);
|
||||
log_debug("VBAT mV %d\n", (val & 0x7f) * 20 + 2304);
|
||||
|
||||
/* limit the VINDPM to 3.9V */
|
||||
i2c_reg_write(0x6a, 0x0d, 0x8d);
|
||||
|
||||
/* set the max voltage to 4.192V */
|
||||
val = i2c_reg_read(0x6a, 0x6);
|
||||
val = (val & ~0xFC) | 0x16 << 2;
|
||||
i2c_reg_write(0x6a, 0x6, val);
|
||||
|
||||
/* set the SYS_MIN to 3.7V */
|
||||
val = i2c_reg_read(0x6a, 0x3);
|
||||
val = val | 0xE;
|
||||
i2c_reg_write(0x6a, 0x3, val);
|
||||
|
||||
/* disable BAT_LOADEN */
|
||||
val = i2c_reg_read(0x6a, 0x03);
|
||||
log_debug("REG03 0x%x\n", val);
|
||||
val = val & ~0x80;
|
||||
i2c_reg_write(0x6a, 0x03, val);
|
||||
}
|
||||
|
||||
#define I2C_PMIC 0
|
||||
|
||||
int power_bd71837_init(unsigned char bus)
|
||||
{
|
||||
static const char name[] = BD718XX_REGULATOR_DRIVER;
|
||||
struct pmic *p = pmic_alloc();
|
||||
|
||||
if (!p) {
|
||||
log_err("%s: POWER allocation error!\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
p->name = name;
|
||||
p->interface = I2C_PMIC;
|
||||
p->number_of_regs = BD718XX_MAX_REGISTER;
|
||||
p->hw.i2c.addr = CONFIG_POWER_BD71837_I2C_ADDR;
|
||||
p->hw.i2c.tx_num = 1;
|
||||
p->bus = bus;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int power_init_board(void)
|
||||
{
|
||||
struct pmic *p;
|
||||
int ldo[] = {BD718XX_LDO5_VOLT, BD718XX_LDO6_VOLT,
|
||||
BD71837_LDO7_VOLT};
|
||||
u32 val;
|
||||
int i, rv;
|
||||
|
||||
/* Set the i2c bus */
|
||||
setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
|
||||
|
||||
/*
|
||||
* Init PMIC
|
||||
*/
|
||||
rv = power_bd71837_init(CONFIG_POWER_BD71837_I2C_BUS);
|
||||
if (rv) {
|
||||
log_err("%s: power_bd71837_init(%d) error %d\n", __func__,
|
||||
CONFIG_POWER_BD71837_I2C_BUS, rv);
|
||||
goto out;
|
||||
}
|
||||
|
||||
p = pmic_get(BD718XX_REGULATOR_DRIVER);
|
||||
if (!p) {
|
||||
log_err("%s: pmic_get(%s) failed\n", __func__, BD718XX_REGULATOR_DRIVER);
|
||||
rv = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rv = pmic_probe(p);
|
||||
if (rv) {
|
||||
log_err("%s: pmic_probe() error %d\n", __func__, rv);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unlock all regs
|
||||
*/
|
||||
pmic_reg_write(p, BD718XX_REGLOCK, 0);
|
||||
|
||||
/* find the reset cause */
|
||||
pmic_reg_read(p, 0x29, &val);
|
||||
log_debug("%s: reset cause %d\n", __func__, val);
|
||||
|
||||
/*
|
||||
* Reconfigure default voltages and disable:
|
||||
* - BUCK3: VDD_GPU_0V9 (1.00 -> 0.90)
|
||||
* - BUCK4: VDD_VPU_0V9 (1.00 -> 0.90)
|
||||
*/
|
||||
pmic_reg_write(p, BD71837_BUCK3_VOLT_RUN, 0x14);
|
||||
pmic_reg_write(p, BD71837_BUCK4_VOLT_RUN, 0x14);
|
||||
|
||||
/*
|
||||
* Enable PHYs voltages: LDO5-7
|
||||
*/
|
||||
for (i = 0; i < ARRAY_SIZE(ldo); i++) {
|
||||
rv = pmic_reg_read(p, ldo[i], &val);
|
||||
if (rv) {
|
||||
log_err("%s: pmic_read(%x) error %d\n", __func__,
|
||||
ldo[i], rv);
|
||||
continue;
|
||||
}
|
||||
|
||||
pmic_reg_write(p, ldo[i], val | LDO_VOLT_EN);
|
||||
}
|
||||
|
||||
udelay(500);
|
||||
|
||||
rv = 0;
|
||||
out:
|
||||
return rv;
|
||||
}
|
||||
|
||||
int usb_gadget_handle_interrupts(void)
|
||||
{
|
||||
dwc3_uboot_handle_interrupt(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dwc3_nxp_usb_phy_init(struct dwc3_device *dwc3)
|
||||
{
|
||||
u32 RegData;
|
||||
|
||||
RegData = readl(dwc3->base + USB_PHY_CTRL1);
|
||||
RegData &= ~(USB_PHY_CTRL1_VDATSRCENB0 | USB_PHY_CTRL1_VDATDETENB0 |
|
||||
USB_PHY_CTRL1_COMMONONN);
|
||||
RegData |= USB_PHY_CTRL1_RESET | USB_PHY_CTRL1_ATERESET;
|
||||
writel(RegData, dwc3->base + USB_PHY_CTRL1);
|
||||
|
||||
RegData = readl(dwc3->base + USB_PHY_CTRL0);
|
||||
RegData |= USB_PHY_CTRL0_REF_SSP_EN;
|
||||
RegData &= ~USB_PHY_CTRL0_SSC_RANGE_MASK;
|
||||
RegData |= USB_PHY_CTRL0_SSC_RANGE_4003PPM;
|
||||
writel(RegData, dwc3->base + USB_PHY_CTRL0);
|
||||
|
||||
RegData = readl(dwc3->base + USB_PHY_CTRL2);
|
||||
RegData |= USB_PHY_CTRL2_TXENABLEN0;
|
||||
writel(RegData, dwc3->base + USB_PHY_CTRL2);
|
||||
|
||||
RegData = readl(dwc3->base + USB_PHY_CTRL1);
|
||||
RegData &= ~(USB_PHY_CTRL1_RESET | USB_PHY_CTRL1_ATERESET);
|
||||
writel(RegData, dwc3->base + USB_PHY_CTRL1);
|
||||
|
||||
/* Disable rx term override */
|
||||
RegData = readl(dwc3->base + USB_PHY_CTRL6);
|
||||
RegData &= ~USB_PHY_CTRL6_RXTERM_OVERRIDE_SEL;
|
||||
writel(RegData, dwc3->base + USB_PHY_CTRL6);
|
||||
}
|
||||
|
||||
static struct dwc3_device dwc3_device0_data = {
|
||||
.maximum_speed = USB_SPEED_HIGH,
|
||||
.base = USB1_BASE_ADDR,
|
||||
.dr_mode = USB_DR_MODE_PERIPHERAL,
|
||||
.index = 0,
|
||||
};
|
||||
|
||||
static struct dwc3_device dwc3_device1_data = {
|
||||
.maximum_speed = USB_SPEED_HIGH,
|
||||
.base = USB2_BASE_ADDR,
|
||||
.dr_mode = USB_DR_MODE_HOST,
|
||||
.index = 1,
|
||||
};
|
||||
|
||||
int board_usb_init(int index, enum usb_init_type init)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
printf("%s : index %d type %d\n", __func__, index, init);
|
||||
|
||||
if (index == 0 && init == USB_INIT_DEVICE) {
|
||||
dwc3_nxp_usb_phy_init(&dwc3_device0_data);
|
||||
ret = dwc3_uboot_init(&dwc3_device0_data);
|
||||
}
|
||||
if (index == 1 && init == USB_INIT_HOST) {
|
||||
dwc3_nxp_usb_phy_init(&dwc3_device1_data);
|
||||
ret = dwc3_uboot_init(&dwc3_device1_data);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int board_usb_cleanup(int index, enum usb_init_type init)
|
||||
{
|
||||
u32 RegData;
|
||||
struct dwc3_device *dwc3;
|
||||
|
||||
printf("%s : %d\n", __func__, index);
|
||||
|
||||
if (index == 0 && init == USB_INIT_DEVICE)
|
||||
dwc3 = &dwc3_device0_data;
|
||||
if (index == 1 && init == USB_INIT_HOST)
|
||||
dwc3 = &dwc3_device1_data;
|
||||
|
||||
dwc3_uboot_exit(index);
|
||||
|
||||
/* reset the phy */
|
||||
RegData = readl(dwc3->base + USB_PHY_CTRL1);
|
||||
RegData &= ~(USB_PHY_CTRL1_VDATSRCENB0 | USB_PHY_CTRL1_VDATDETENB0 |
|
||||
USB_PHY_CTRL1_COMMONONN);
|
||||
RegData |= USB_PHY_CTRL1_RESET | USB_PHY_CTRL1_ATERESET;
|
||||
writel(RegData, dwc3->base + USB_PHY_CTRL1);
|
||||
|
||||
/* enable rx term override */
|
||||
RegData = readl(dwc3->base + USB_PHY_CTRL6);
|
||||
RegData |= USB_PHY_CTRL6_RXTERM_OVERRIDE_SEL;
|
||||
writel(RegData, dwc3->base + USB_PHY_CTRL6);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void spl_board_init(void)
|
||||
{
|
||||
if (is_usb_boot())
|
||||
puts("USB Boot\n");
|
||||
else
|
||||
puts("Normal Boot\n");
|
||||
}
|
||||
|
||||
void board_boot_order(u32 *spl_boot_list)
|
||||
{
|
||||
if (is_usb_boot())
|
||||
spl_boot_list[0] = BOOT_DEVICE_BOARD;
|
||||
else
|
||||
spl_boot_list[0] = BOOT_DEVICE_MMC1;
|
||||
}
|
||||
|
||||
#define WDOG_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_HYS | PAD_CTL_PUE)
|
||||
|
||||
static const iomux_v3_cfg_t wdog_pads[] = {
|
||||
IMX8MQ_PAD_GPIO1_IO02__WDOG1_WDOG_B | MUX_PAD_CTRL(WDOG_PAD_CTRL),
|
||||
};
|
||||
|
||||
void board_init_f(ulong dummy)
|
||||
{
|
||||
int ret;
|
||||
struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR;
|
||||
|
||||
arch_cpu_init();
|
||||
|
||||
imx_iomux_v3_setup_multiple_pads(wdog_pads, ARRAY_SIZE(wdog_pads));
|
||||
set_wdog_reset(wdog);
|
||||
|
||||
init_uart_clk(CONSOLE_UART_CLK);
|
||||
imx_iomux_v3_setup_multiple_pads(uart_pads, ARRAY_SIZE(uart_pads));
|
||||
|
||||
#ifdef CONSOLE_ON_UART4
|
||||
gpio_request(WIFI_EN, "WIFI_EN");
|
||||
gpio_direction_output(WIFI_EN, 1);
|
||||
#endif
|
||||
|
||||
board_early_init_f();
|
||||
|
||||
timer_init();
|
||||
|
||||
preloader_console_init();
|
||||
|
||||
ret = spl_init();
|
||||
if (ret) {
|
||||
log_err("spl_init() failed: %d\n", ret);
|
||||
hang();
|
||||
}
|
||||
|
||||
enable_tzc380();
|
||||
|
||||
printf("Initializing pinmux\n");
|
||||
init_pinmux();
|
||||
gpio_direction_output(LED_G, 1);
|
||||
gpio_direction_output(MOTO, 1);
|
||||
mdelay(50);
|
||||
gpio_direction_output(MOTO, 0);
|
||||
|
||||
/* Enable and configure i2c buses not used below */
|
||||
setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2);
|
||||
setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info3);
|
||||
setup_i2c(3, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info4);
|
||||
|
||||
power_init_board();
|
||||
|
||||
disable_charger_bq25895();
|
||||
|
||||
/* initialize this for M4 even if u-boot doesn't have SF_CMD */
|
||||
printf("Initializing ECSPI\n");
|
||||
board_ecspi_init();
|
||||
|
||||
/* DDR initialization */
|
||||
printf("Initializing DRAM\n");
|
||||
spl_dram_init();
|
||||
}
|
||||
@@ -34,14 +34,11 @@ DECLARE_GLOBAL_DATA_PTR;
|
||||
int spl_board_boot_device(enum boot_device boot_dev_spl)
|
||||
{
|
||||
switch (boot_dev_spl) {
|
||||
case MMC1_BOOT:
|
||||
case MMC1_BOOT: /* eMMC */
|
||||
return BOOT_DEVICE_MMC1;
|
||||
case SD2_BOOT:
|
||||
case SD2_BOOT: /* SD card */
|
||||
case MMC2_BOOT:
|
||||
return BOOT_DEVICE_MMC2;
|
||||
case SD3_BOOT:
|
||||
case MMC3_BOOT:
|
||||
return BOOT_DEVICE_MMC1;
|
||||
case USB_BOOT:
|
||||
return BOOT_DEVICE_BOARD;
|
||||
default:
|
||||
@@ -56,6 +53,15 @@ void spl_dram_init(void)
|
||||
|
||||
void spl_board_init(void)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_FSL_CAAM)) {
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
|
||||
ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(caam_jr), &dev);
|
||||
if (ret)
|
||||
printf("Failed to initialize %s: %d\n", dev->name, ret);
|
||||
}
|
||||
|
||||
/* Serial download mode */
|
||||
if (is_usb_boot()) {
|
||||
puts("Back to ROM, SDP\n");
|
||||
@@ -74,7 +80,6 @@ int board_fit_config_name_match(const char *name)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
__weak void board_early_init(void)
|
||||
{
|
||||
init_uart_clk(0);
|
||||
|
||||
@@ -102,9 +102,6 @@ static void select_dt_from_module_version(void)
|
||||
if (strcmp(variant, env_variant)) {
|
||||
printf("Setting variant to %s\n", variant);
|
||||
env_set("variant", variant);
|
||||
|
||||
if (IS_ENABLED(CONFIG_ENV_IS_NOWHERE))
|
||||
env_save();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -108,9 +108,6 @@ static void select_dt_from_module_version(void)
|
||||
if (strcmp(variant, env_variant)) {
|
||||
printf("Setting variant to %s\n", variant);
|
||||
env_set("variant", variant);
|
||||
|
||||
if (IS_ENABLED(CONFIG_ENV_IS_NOWHERE))
|
||||
env_save();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user