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
 -----BEGIN PGP SIGNATURE-----
 
 iG0EABECAC0WIQS2TmnA27QKhpKSZe309WXkmmjvpgUCYyhfUg8cc2JhYmljQGRl
 bnguZGUACgkQ9PVl5Jpo76bBfgCgkthrxcVGFDRGMqA2B4OkWjM7RjYAn0jn9dqO
 F1jZNNtXpdwDVljS1Xtv
 =Rnxw
 -----END PGP SIGNATURE-----

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:
Tom Rini 2022-09-19 08:38:32 -04:00
commit c1db6be55d
82 changed files with 9561 additions and 611 deletions

View file

@ -299,7 +299,7 @@ config SYS_MALLOC_F_LEN
default 0x4000 if SANDBOX || RISCV || ARCH_APPLE || ROCKCHIP_RK3368 || \
ROCKCHIP_RK3399
default 0x8000 if RCAR_GEN3
default 0x10000 if ARCH_IMX8 || (ARCH_IMX8M && !IMX8MQ)
default 0x10000 if ARCH_IMX8 || ARCH_IMX8M
default 0x2000
help
Before relocation, memory is very limited on many platforms. Still,
@ -325,6 +325,7 @@ config SPL_SYS_MALLOC_F_LEN
depends on SYS_MALLOC_F && SPL
default 0 if !SPL_FRAMEWORK
default 0x2800 if RCAR_GEN3
default 0x2000 if IMX8MQ
default SYS_MALLOC_F_LEN
help
In SPL memory is very limited on many platforms. Still,

View file

@ -264,6 +264,7 @@ F: arch/arm/include/asm/arch-mx*/
F: arch/arm/include/asm/arch-vf610/
F: arch/arm/include/asm/mach-imx/
F: board/freescale/*mx*/
F: drivers/serial/serial_mxc.c
ARM HISILICON
M: Peter Griffin <peter.griffin@linaro.org>

View file

@ -895,6 +895,7 @@ dtb-$(CONFIG_MX6ULL) += \
imx6ull-phytec-segin-ff-rdk-emmc.dtb \
imx6ull-dart-6ul.dtb \
imx6ull-somlabs-visionsom.dtb \
imx6ulz-bsh-smm-m2.dtb \
imx6ulz-14x14-evk.dtb
dtb-$(CONFIG_ARCH_MX6) += \
@ -974,13 +975,15 @@ dtb-$(CONFIG_ARCH_IMX8M) += \
imx8mp-venice-gw74xx.dtb \
imx8mp-verdin-wifi-dev.dtb \
imx8mq-pico-pi.dtb \
imx8mq-kontron-pitx-imx8m.dtb
imx8mq-kontron-pitx-imx8m.dtb \
imx8mq-librem5-r4.dtb
dtb-$(CONFIG_ARCH_IMX9) += \
imx93-11x11-evk.dtb
dtb-$(CONFIG_ARCH_IMXRT) += imxrt1050-evk.dtb \
imxrt1020-evk.dtb
imxrt1020-evk.dtb \
imxrt1170-evk.dtb \
dtb-$(CONFIG_RCAR_GEN2) += \
r8a7790-lager-u-boot.dtb \

View file

@ -0,0 +1,35 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2022 BSH Hausgeraete GmbH
*
* Author: Michael Trimarchi <michael@amarulasolutions.com>
*/
&{/soc} {
u-boot,dm-pre-reloc;
};
&aips2 {
u-boot,dm-pre-reloc;
};
&iomuxc {
u-boot,dm-pre-reloc;
};
&iomuxc_snvs {
u-boot,dm-pre-reloc;
};
&uart4 {
u-boot,dm-pre-reloc;
};
&pinctrl_uart4 {
u-boot,dm-pre-reloc;
};
&gpmi {
u-boot,dm-spl;
u-boot,dm-pre-reloc;
};

View file

@ -0,0 +1,146 @@
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/*
* Copyright (C) 2021 BSH Hausgeraete GmbH
*/
/dts-v1/;
#include <dt-bindings/input/input.h>
#include "imx6ulz.dtsi"
/ {
model = "BSH SMM M2";
compatible = "bsh,imx6ulz-bsh-smm-m2", "fsl,imx6ull", "fsl,imx6ulz";
chosen {
stdout-path = &uart4;
};
usdhc2_pwrseq: usdhc2-pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&gpio2 21 GPIO_ACTIVE_LOW>;
};
};
&gpmi {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpmi_nand>;
nand-on-flash-bbt;
status = "okay";
};
&uart3 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart3>;
uart-has-rtscts;
status = "okay";
bluetooth {
compatible = "brcm,bcm4330-bt";
max-speed = <3000000>;
shutdown-gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>;
device-wakeup-gpios = <&gpio2 17 GPIO_ACTIVE_HIGH>;
host-wakeup-gpios = <&gpio2 13 GPIO_ACTIVE_HIGH>;
};
};
&uart4 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart4>;
status = "okay";
};
&usbotg1 {
dr_mode = "peripheral";
srp-disable;
hnp-disable;
adp-disable;
status = "okay";
};
&usbphy1 {
fsl,tx-d-cal = <106>;
};
&usdhc2 {
#address-cells = <1>;
#size-cells = <0>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_wlan>;
bus-width = <4>;
no-1-8-v;
non-removable;
cap-power-off-card;
keep-power-in-suspend;
cap-sdio-irq;
mmc-pwrseq = <&usdhc2_pwrseq>;
status = "okay";
brcmf: wifi@1 {
reg = <1>;
compatible = "brcm,bcm4329-fmac";
interrupt-parent = <&gpio1>;
interrupts = <18 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "host-wake";
};
};
&wdog1 {
status = "okay";
};
&iomuxc {
pinctrl_gpmi_nand: gpmi-nand {
fsl,pins = <
MX6UL_PAD_NAND_CLE__RAWNAND_CLE 0xb0b1
MX6UL_PAD_NAND_ALE__RAWNAND_ALE 0xb0b1
MX6UL_PAD_NAND_WP_B__RAWNAND_WP_B 0xb0b1
MX6UL_PAD_NAND_READY_B__RAWNAND_READY_B 0xb000
MX6UL_PAD_NAND_CE0_B__RAWNAND_CE0_B 0xb0b1
MX6UL_PAD_NAND_RE_B__RAWNAND_RE_B 0xb0b1
MX6UL_PAD_NAND_WE_B__RAWNAND_WE_B 0xb0b1
MX6UL_PAD_NAND_DATA00__RAWNAND_DATA00 0xb0b1
MX6UL_PAD_NAND_DATA01__RAWNAND_DATA01 0xb0b1
MX6UL_PAD_NAND_DATA02__RAWNAND_DATA02 0xb0b1
MX6UL_PAD_NAND_DATA03__RAWNAND_DATA03 0xb0b1
MX6UL_PAD_NAND_DATA04__RAWNAND_DATA04 0xb0b1
MX6UL_PAD_NAND_DATA05__RAWNAND_DATA05 0xb0b1
MX6UL_PAD_NAND_DATA06__RAWNAND_DATA06 0xb0b1
MX6UL_PAD_NAND_DATA07__RAWNAND_DATA07 0xb0b1
>;
};
pinctrl_uart3: uart3grp {
fsl,pins = <
MX6UL_PAD_UART3_TX_DATA__UART3_DCE_TX 0x1b0b1
MX6UL_PAD_UART3_RX_DATA__UART3_DCE_RX 0x1b099
MX6UL_PAD_UART3_RTS_B__UART3_DCE_RTS 0x1b0b1
MX6UL_PAD_UART3_CTS_B__UART3_DCE_CTS 0x1b099
MX6UL_PAD_GPIO1_IO01__GPIO1_IO01 0x79 /* BT_REG_ON */
MX6UL_PAD_SD1_CLK__GPIO2_IO17 0x100b1 /* BT_DEV_WAKE out */
MX6UL_PAD_ENET2_TX_EN__GPIO2_IO13 0x1b0b0 /* BT_HOST_WAKE in */
>;
};
pinctrl_uart4: uart4grp {
fsl,pins = <
MX6UL_PAD_UART4_TX_DATA__UART4_DCE_TX 0x1b0b1
MX6UL_PAD_UART4_RX_DATA__UART4_DCE_RX 0x1b0b1
>;
};
pinctrl_wlan: wlangrp {
fsl,pins = <
MX6UL_PAD_CSI_HSYNC__USDHC2_CMD 0x17059
MX6UL_PAD_CSI_VSYNC__USDHC2_CLK 0x10059
MX6UL_PAD_CSI_DATA00__USDHC2_DATA0 0x17059
MX6UL_PAD_CSI_DATA01__USDHC2_DATA1 0x17059
MX6UL_PAD_CSI_DATA02__USDHC2_DATA2 0x17059
MX6UL_PAD_CSI_DATA03__USDHC2_DATA3 0x17059
MX6UL_PAD_SD1_DATA3__GPIO2_IO21 0x79 /* WL_REG_ON */
MX6UL_PAD_UART2_CTS_B__GPIO1_IO22 0x100b1 /* WL_DEV_WAKE - WiFi_GPIO_4 - WiFi FW UART */
MX6UL_PAD_UART1_CTS_B__GPIO1_IO18 0x1b0b1 /* WL_HOST_WAKE - WIFI_GPIO_0 - OOB IRQ */
MX6UL_PAD_ENET1_RX_EN__OSC32K_32K_OUT 0x4001b031 /* OSC 32Khz wifi clk in */
>;
};
};

View file

@ -106,6 +106,10 @@
u-boot,off-on-delay-us = <20000>;
};
&spba1 {
u-boot,dm-spl;
};
&uart2 {
u-boot,dm-spl;
};

View file

@ -3,139 +3,4 @@
* Copyright (C) 2022 Marek Vasut <marex@denx.de>
*/
#include "imx8mp-u-boot.dtsi"
/ {
aliases {
eeprom0 = &eeprom0;
eeprom1 = &eeprom1;
mmc0 = &usdhc2; /* MicroSD */
mmc1 = &usdhc3; /* eMMC */
mmc2 = &usdhc1; /* SDIO */
};
config {
dh,ram-coding-gpios = <&gpio3 22 0>, <&gpio3 23 0>, <&gpio3 24 0>;
};
wdt-reboot {
compatible = "wdt-reboot";
wdt = <&wdog1>;
u-boot,dm-spl;
};
};
&buck4 {
u-boot,dm-spl;
};
&buck5 {
u-boot,dm-spl;
};
&eqos {
/delete-property/ assigned-clocks;
/delete-property/ assigned-clock-parents;
/delete-property/ assigned-clock-rates;
};
&gpio1 {
u-boot,dm-spl;
};
&gpio2 {
u-boot,dm-spl;
};
&gpio3 {
u-boot,dm-spl;
};
&gpio4 {
u-boot,dm-spl;
};
&gpio5 {
u-boot,dm-spl;
};
&i2c3 {
u-boot,dm-spl;
};
&pinctrl_i2c3 {
u-boot,dm-spl;
};
&pinctrl_i2c3_gpio {
u-boot,dm-spl;
};
&pinctrl_pmic {
u-boot,dm-spl;
};
&pinctrl_uart1 {
u-boot,dm-spl;
};
&pinctrl_usdhc2 {
u-boot,dm-spl;
};
&pinctrl_usdhc2_100mhz {
u-boot,dm-spl;
};
&pinctrl_usdhc2_200mhz {
u-boot,dm-spl;
};
&pinctrl_usdhc2_vmmc {
u-boot,dm-spl;
};
&pinctrl_usdhc3 {
u-boot,dm-spl;
};
&pinctrl_usdhc3_100mhz {
u-boot,dm-spl;
};
&pinctrl_usdhc3_100mhz {
u-boot,dm-spl;
};
&pmic {
u-boot,dm-spl;
regulators {
u-boot,dm-spl;
};
};
&reg_usdhc2_vmmc {
u-boot,dm-spl;
};
&uart1 {
u-boot,dm-spl;
};
/* SDIO WiFi */
&usdhc1 {
status = "disabled";
};
&usdhc2 {
u-boot,dm-spl;
};
&usdhc3 {
u-boot,dm-spl;
};
&wdog1 {
u-boot,dm-spl;
};
#include "imx8mp-dhcom-u-boot.dtsi"

View file

@ -1,18 +1,23 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (C) 2022 Marek Vasut <marex@denx.de>
*
* DHCOM iMX8MP variant:
* DHCM-iMX8ML8-C160-R409-F1638-SPI16-GE-CAN2-SD-RTC-WBTA-ADC-T-RGB-CSI2-HS-I-01D2
* DHCOM PCB number: 660-100 or newer
* PDK2 PCB number: 516-400 or newer
*/
/dts-v1/;
#include <dt-bindings/leds/common.h>
#include <dt-bindings/net/qca-ar803x.h>
#include <dt-bindings/phy/phy-imx8-pcie.h>
#include "imx8mp-dhcom-som.dtsi"
/ {
model = "DH electronics i.MX8M Plus DHCOM Premium Developer Kit (2)";
compatible = "dh,imx8mp-dhcom-pdk2", "fsl,imx8mp";
compatible = "dh,imx8mp-dhcom-pdk2", "dh,imx8mp-dhcom-som",
"fsl,imx8mp";
chosen {
stdout-path = &uart1;

View file

@ -70,7 +70,7 @@
&ecspi1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ecspi1>;
cs-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>;
cs-gpios = <&gpio5 17 GPIO_ACTIVE_LOW>;
status = "disabled";
};
@ -415,8 +415,8 @@
pinctrl-names = "default", "gpio";
pinctrl-0 = <&pinctrl_i2c5>;
pinctrl-1 = <&pinctrl_i2c5_gpio>;
scl-gpios = <&gpio5 26 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
sda-gpios = <&gpio5 27 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
scl-gpios = <&gpio3 26 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
sda-gpios = <&gpio3 27 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
status = "okay";
};
@ -660,10 +660,10 @@
pinctrl_ecspi1: dhcom-ecspi1-grp {
fsl,pins = <
MX8MP_IOMUXC_ECSPI1_SCLK__ECSPI1_SCLK 0x44
MX8MP_IOMUXC_ECSPI1_MOSI__ECSPI1_MOSI 0x44
MX8MP_IOMUXC_ECSPI1_MISO__ECSPI1_MISO 0x44
MX8MP_IOMUXC_ECSPI1_SS0__GPIO5_IO09 0x40
MX8MP_IOMUXC_I2C1_SCL__ECSPI1_SCLK 0x44
MX8MP_IOMUXC_I2C1_SDA__ECSPI1_MOSI 0x44
MX8MP_IOMUXC_I2C2_SCL__ECSPI1_MISO 0x44
MX8MP_IOMUXC_I2C2_SDA__GPIO5_IO17 0x40
>;
};

View file

@ -0,0 +1,141 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (C) 2022 Marek Vasut <marex@denx.de>
*/
#include "imx8mp-u-boot.dtsi"
/ {
aliases {
eeprom0 = &eeprom0;
eeprom1 = &eeprom1;
mmc0 = &usdhc2; /* MicroSD */
mmc1 = &usdhc3; /* eMMC */
mmc2 = &usdhc1; /* SDIO */
};
config {
dh,ram-coding-gpios = <&gpio3 22 0>, <&gpio3 23 0>, <&gpio3 24 0>;
};
wdt-reboot {
compatible = "wdt-reboot";
wdt = <&wdog1>;
u-boot,dm-spl;
};
};
&buck4 {
u-boot,dm-spl;
};
&buck5 {
u-boot,dm-spl;
};
&eqos {
/delete-property/ assigned-clocks;
/delete-property/ assigned-clock-parents;
/delete-property/ assigned-clock-rates;
};
&gpio1 {
u-boot,dm-spl;
};
&gpio2 {
u-boot,dm-spl;
};
&gpio3 {
u-boot,dm-spl;
};
&gpio4 {
u-boot,dm-spl;
};
&gpio5 {
u-boot,dm-spl;
};
&i2c3 {
u-boot,dm-spl;
};
&pinctrl_i2c3 {
u-boot,dm-spl;
};
&pinctrl_i2c3_gpio {
u-boot,dm-spl;
};
&pinctrl_pmic {
u-boot,dm-spl;
};
&pinctrl_uart1 {
u-boot,dm-spl;
};
&pinctrl_usdhc2 {
u-boot,dm-spl;
};
&pinctrl_usdhc2_100mhz {
u-boot,dm-spl;
};
&pinctrl_usdhc2_200mhz {
u-boot,dm-spl;
};
&pinctrl_usdhc2_vmmc {
u-boot,dm-spl;
};
&pinctrl_usdhc3 {
u-boot,dm-spl;
};
&pinctrl_usdhc3_100mhz {
u-boot,dm-spl;
};
&pinctrl_usdhc3_100mhz {
u-boot,dm-spl;
};
&pmic {
u-boot,dm-spl;
regulators {
u-boot,dm-spl;
};
};
&reg_usdhc2_vmmc {
u-boot,dm-spl;
};
&uart1 {
u-boot,dm-spl;
};
/* SDIO WiFi */
&usdhc1 {
status = "disabled";
};
&usdhc2 {
u-boot,dm-spl;
};
&usdhc3 {
u-boot,dm-spl;
};
&wdog1 {
u-boot,dm-spl;
};

View file

@ -0,0 +1,24 @@
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
#include "imx8mq-u-boot.dtsi"
&pinctrl_uart1 {
u-boot,dm-spl;
};
&uart1 { /* console */
u-boot,dm-spl;
};
&binman {
/delete-node/ signed-hdmi;
signed-hdmi {
filename = "signed_hdmi.bin";
signed-dp-imx8m {
filename = "signed_dp_imx8m.bin";
type = "blob-ext";
};
};
};

View file

@ -0,0 +1,35 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
// Copyright (C) 2020 Purism SPC <kernel@puri.sm>
/dts-v1/;
#include "imx8mq-librem5.dtsi"
/ {
model = "Purism Librem 5r4";
compatible = "purism,librem5r4", "purism,librem5", "fsl,imx8mq";
};
&accel_gyro {
mount-matrix = "1", "0", "0",
"0", "1", "0",
"0", "0", "-1";
};
&bat {
maxim,rsns-microohm = <1667>;
};
&bq25895 {
ti,battery-regulation-voltage = <4200000>; /* uV */
ti,charge-current = <1500000>; /* uA */
ti,termination-current = <144000>; /* uA */
};
&led_backlight {
led-max-microamp = <25000>;
};
&proximity {
proximity-near-level = <10>;
};

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,94 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
* Copyright (C) 2022
* Author(s): Jesse Taube <Mr.Bossman075@gmail.com>
* Giulio Benetti <giulio.benetti@benettiengineering.com>
*/
/ {
chosen {
u-boot,dm-spl;
};
clocks {
u-boot,dm-spl;
};
soc {
u-boot,dm-spl;
};
};
&osc {
u-boot,dm-spl;
};
&rcosc16M {
u-boot,dm-spl;
};
&osc32k {
u-boot,dm-spl;
};
&clks {
u-boot,dm-spl;
};
&gpio1 {
u-boot,dm-spl;
};
&gpio2 {
u-boot,dm-spl;
};
&gpio3 {
u-boot,dm-spl;
};
&gpio4 {
u-boot,dm-spl;
};
&gpio5 {
u-boot,dm-spl;
};
&gpt1 {
u-boot,dm-spl;
};
&lpuart1 { /* console */
u-boot,dm-spl;
};
&semc {
u-boot,dm-spl;
bank1: bank@0 {
u-boot,dm-spl;
};
};
&iomuxc {
u-boot,dm-spl;
imxrt1170-evk {
u-boot,dm-spl;
pinctrl_lpuart1: lpuart1grp {
u-boot,dm-spl;
};
pinctrl_usdhc0: usdhc0grp {
u-boot,dm-spl;
};
pinctrl_semc: semcgrp {
u-boot,dm-spl;
};
};
};
&usdhc1 {
u-boot,dm-spl;
};

View file

@ -0,0 +1,250 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
* Copyright (C) 2022
* Author(s): Jesse Taube <Mr.Bossman075@gmail.com>
* Giulio Benetti <giulio.benetti@benettiengineering.com>
*/
/dts-v1/;
#include "imxrt1170.dtsi"
#include "imxrt1170-evk-u-boot.dtsi"
#include "imxrt1170-pinfunc.h"
/ {
model = "NXP imxrt1170-evk board";
compatible = "fsl,imxrt1170-evk", "fsl,imxrt1170";
chosen {
stdout-path = "serial0:115200n8";
tick-timer = &gpt1;
};
memory {
device_type = "memory";
reg = <0x20240000 0xf0000 0x80000000 0x4000000>;
ocram: ocram@20240000 {
device_type = "memory";
reg = <0x20240000 0xf0000>;
};
sdram: sdram@80000000 {
device_type = "memory";
reg = <0x80000000 0x4000000>;
};
};
};
&lpuart1 { /* console */
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_lpuart1>;
status = "okay";
};
&semc {
/*
* Memory configuration from sdram datasheet IS42S16160J-6BLI
*/
fsl,sdram-mux = /bits/ 8 <MUX_A8_SDRAM_A8
0
0
0
0
0>;
fsl,sdram-control = /bits/ 8 <MEM_WIDTH_32BITS
BL_8
COL_9BITS
CL_3>;
fsl,sdram-timing = /bits/ 8 <0x2
0x2
0xd
0x0
0x8
0x7
0x0d
0x0b
0x00
0x00
0x00
0x0A
0x08
0x09>;
bank1: bank@0 {
fsl,base-address = <0x80000000>;
fsl,memory-size = <MEM_SIZE_64M>;
};
};
&iomuxc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_lpuart1>;
imxrt1170-evk {
pinctrl_lpuart1: lpuart1grp {
fsl,pins = <
IOMUXC_GPIO_AD_24_LPUART1_TXD 0xf1
IOMUXC_GPIO_AD_25_LPUART1_RXD 0xf1
>;
};
pinctrl_usdhc0: usdhc0grp {
fsl,pins = <
IOMUXC_GPIO_AD_32_USDHC1_CD_B
0x1B000
IOMUXC_GPIO_AD_34_USDHC1_VSELECT
0xB069
IOMUXC_GPIO_SD_B1_00_USDHC1_CMD
0x17061
IOMUXC_GPIO_SD_B1_01_USDHC1_CLK
0x17061
IOMUXC_GPIO_SD_B1_05_USDHC1_DATA3
0x17061
IOMUXC_GPIO_SD_B1_04_USDHC1_DATA2
0x17061
IOMUXC_GPIO_SD_B1_03_USDHC1_DATA1
0x17061
IOMUXC_GPIO_SD_B1_02_USDHC1_DATA0
0x17061
>;
};
pinctrl_semc: semcgrp {
fsl,pins = <
IOMUXC_GPIO_EMC_B1_00_SEMC_DATA00
8 /* SEMC_D0 */
IOMUXC_GPIO_EMC_B1_01_SEMC_DATA01
8 /* SEMC_D1 */
IOMUXC_GPIO_EMC_B1_02_SEMC_DATA02
8 /* SEMC_D2 */
IOMUXC_GPIO_EMC_B1_03_SEMC_DATA03
8 /* SEMC_D3 */
IOMUXC_GPIO_EMC_B1_04_SEMC_DATA04
8 /* SEMC_D4 */
IOMUXC_GPIO_EMC_B1_05_SEMC_DATA05
8 /* SEMC_D5 */
IOMUXC_GPIO_EMC_B1_06_SEMC_DATA06
8 /* SEMC_D6 */
IOMUXC_GPIO_EMC_B1_07_SEMC_DATA07
8 /* SEMC_D7 */
IOMUXC_GPIO_EMC_B1_08_SEMC_DM00
8 /* SEMC_DM0 */
IOMUXC_GPIO_EMC_B1_09_SEMC_ADDR00
8 /* SEMC_A0 */
IOMUXC_GPIO_EMC_B1_10_SEMC_ADDR01
8 /* SEMC_A1 */
IOMUXC_GPIO_EMC_B1_11_SEMC_ADDR02
8 /* SEMC_A2 */
IOMUXC_GPIO_EMC_B1_12_SEMC_ADDR03
8 /* SEMC_A3 */
IOMUXC_GPIO_EMC_B1_13_SEMC_ADDR04
8 /* SEMC_A4 */
IOMUXC_GPIO_EMC_B1_14_SEMC_ADDR05
8 /* SEMC_A5 */
IOMUXC_GPIO_EMC_B1_15_SEMC_ADDR06
8 /* SEMC_A6 */
IOMUXC_GPIO_EMC_B1_16_SEMC_ADDR07
8 /* SEMC_A7 */
IOMUXC_GPIO_EMC_B1_17_SEMC_ADDR08
8 /* SEMC_A8 */
IOMUXC_GPIO_EMC_B1_18_SEMC_ADDR09
8 /* SEMC_A9 */
IOMUXC_GPIO_EMC_B1_19_SEMC_ADDR11
8 /* SEMC_A11 */
IOMUXC_GPIO_EMC_B1_20_SEMC_ADDR12
8 /* SEMC_A12 */
IOMUXC_GPIO_EMC_B1_21_SEMC_BA0
8 /* SEMC_BA0 */
IOMUXC_GPIO_EMC_B1_22_SEMC_BA1
8 /* SEMC_BA1 */
IOMUXC_GPIO_EMC_B1_23_SEMC_ADDR10
8 /* SEMC_A10 */
IOMUXC_GPIO_EMC_B1_24_SEMC_CAS
8 /* SEMC_CAS */
IOMUXC_GPIO_EMC_B1_25_SEMC_RAS
8 /* SEMC_RAS */
IOMUXC_GPIO_EMC_B1_26_SEMC_CLK
8 /* SEMC_CLK */
IOMUXC_GPIO_EMC_B1_27_SEMC_CKE
8 /* SEMC_CKE */
IOMUXC_GPIO_EMC_B1_28_SEMC_WE
8 /* SEMC_WE */
IOMUXC_GPIO_EMC_B1_29_SEMC_CS0
8 /* SEMC_CS0 */
IOMUXC_GPIO_EMC_B1_30_SEMC_DATA08
8 /* SEMC_D8 */
IOMUXC_GPIO_EMC_B1_31_SEMC_DATA09
8 /* SEMC_D9 */
IOMUXC_GPIO_EMC_B1_32_SEMC_DATA10
8 /* SEMC_D10 */
IOMUXC_GPIO_EMC_B1_33_SEMC_DATA11
8 /* SEMC_D11 */
IOMUXC_GPIO_EMC_B1_34_SEMC_DATA12
8 /* SEMC_D12 */
IOMUXC_GPIO_EMC_B1_35_SEMC_DATA13
8 /* SEMC_D13 */
IOMUXC_GPIO_EMC_B1_36_SEMC_DATA14
8 /* SEMC_D14 */
IOMUXC_GPIO_EMC_B1_37_SEMC_DATA15
8 /* SEMC_D15 */
IOMUXC_GPIO_EMC_B1_08_SEMC_DM00
8 /* SEMC_DM00 */
IOMUXC_GPIO_EMC_B1_38_SEMC_DM01
8 /* SEMC_DM01 */
IOMUXC_GPIO_EMC_B2_08_SEMC_DM02
4 /* SEMC_DM02 */
IOMUXC_GPIO_EMC_B2_17_SEMC_DM03
8 /* SEMC_DM03 */
IOMUXC_GPIO_EMC_B2_00_SEMC_DATA16
8 /* SEMC_D16 */
IOMUXC_GPIO_EMC_B2_01_SEMC_DATA17
8 /* SEMC_D17 */
IOMUXC_GPIO_EMC_B2_02_SEMC_DATA18
8 /* SEMC_D18 */
IOMUXC_GPIO_EMC_B2_03_SEMC_DATA19
8 /* SEMC_D19 */
IOMUXC_GPIO_EMC_B2_04_SEMC_DATA20
8 /* SEMC_D20 */
IOMUXC_GPIO_EMC_B2_05_SEMC_DATA21
8 /* SEMC_D21 */
IOMUXC_GPIO_EMC_B2_06_SEMC_DATA22
8 /* SEMC_D22 */
IOMUXC_GPIO_EMC_B2_07_SEMC_DATA23
8 /* SEMC_D23 */
IOMUXC_GPIO_EMC_B2_09_SEMC_DATA24
8 /* SEMC_D24 */
IOMUXC_GPIO_EMC_B2_10_SEMC_DATA25
8 /* SEMC_D25 */
IOMUXC_GPIO_EMC_B2_11_SEMC_DATA26
4 /* SEMC_D26 */
IOMUXC_GPIO_EMC_B2_12_SEMC_DATA27
8 /* SEMC_D27 */
IOMUXC_GPIO_EMC_B2_13_SEMC_DATA28
8 /* SEMC_D28 */
IOMUXC_GPIO_EMC_B2_14_SEMC_DATA29
8 /* SEMC_D29 */
IOMUXC_GPIO_EMC_B2_15_SEMC_DATA30
8 /* SEMC_D30 */
IOMUXC_GPIO_EMC_B2_16_SEMC_DATA31
8 /* SEMC_D31 */
IOMUXC_GPIO_EMC_B1_39_SEMC_DQS
(IMX_PAD_SION | 8) /* SEMC_DQS */
>;
};
};
};
&gpt1 {
status = "okay";
};
&usdhc1 {
pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep";
pinctrl-0 = <&pinctrl_usdhc0>;
pinctrl-1 = <&pinctrl_usdhc0>;
pinctrl-2 = <&pinctrl_usdhc0>;
pinctrl-3 = <&pinctrl_usdhc0>;
status = "okay";
broken-cd;
};

File diff suppressed because it is too large Load diff

257
arch/arm/dts/imxrt1170.dtsi Normal file
View file

@ -0,0 +1,257 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
* Copyright (C) 2022
* Author(s): Jesse Taube <Mr.Bossman075@gmail.com>
* Giulio Benetti <giulio.benetti@benettiengineering.com>
*/
#include "armv7-m.dtsi"
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/imxrt1170-clock.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/memory/imxrt-sdram.h>
/ {
#address-cells = <1>;
#size-cells = <1>;
aliases {
gpio0 = &gpio1;
gpio1 = &gpio2;
gpio2 = &gpio3;
gpio3 = &gpio4;
gpio4 = &gpio5;
gpio5 = &gpio6;
gpio6 = &gpio7;
gpio7 = &gpio8;
gpio8 = &gpio9;
gpio9 = &gpio10;
gpio10 = &gpio11;
gpio11 = &gpio12;
gpio12 = &gpio13;
mmc0 = &usdhc1;
serial0 = &lpuart1;
};
clocks {
osc: osc {
compatible = "fsl,imx-osc", "fixed-clock";
#clock-cells = <0>;
clock-frequency = <24000000>;
};
rcosc16M: rcosc16M {
compatible = "fsl,imx-osc", "fixed-clock";
#clock-cells = <0>;
clock-frequency = <16000000>;
};
osc32k: osc32k {
compatible = "fsl,imx-osc", "fixed-clock";
#clock-cells = <0>;
clock-frequency = <32768>;
};
};
soc {
semc: semc@400d4000 {
compatible = "fsl,imxrt-semc";
reg = <0x400d4000 0x4000>;
interrupts = <132>;
clocks = <&clks IMXRT1170_CLK_SEMC>;
pinctrl-0 = <&pinctrl_semc>;
pinctrl-names = "default";
status = "okay";
};
lpuart1: serial@4007c000 {
compatible = "fsl,imxrt-lpuart";
reg = <0x4007c000 0x4000>;
interrupts = <20>;
clocks = <&clks IMXRT1170_CLK_LPUART1>;
clock-names = "per";
status = "disabled";
};
iomuxc: iomuxc@400e8000 {
compatible = "fsl,imxrt-iomuxc";
reg = <0x400e8000 0x4000>;
fsl,mux_mask = <0x7>;
};
anatop: anatop@40c84000 {
compatible = "fsl,imxrt-anatop";
reg = <0x40c84000 0x4000>;
};
clks: ccm@40cc0000 {
compatible = "fsl,imxrt1170-ccm";
reg = <0x40cc0000 0x4000>;
#clock-cells = <1>;
};
usdhc1: usdhc@40418000 {
compatible = "fsl,imxrt-usdhc";
reg = <0x40418000 0x10000>;
interrupts = <133>;
clocks = <&clks IMXRT1170_CLK_USDHC1>;
clock-names = "per";
bus-width = <4>;
fsl,tuning-start-tap = <20>;
fsl,tuning-step= <2>;
status = "disabled";
};
gpio1: gpio@4012c000 {
compatible = "fsl,imxrt-gpio", "fsl,imx35-gpio";
reg = <0x4012c000 0x4000>;
interrupts = <100>,
<101>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
gpio2: gpio@40130000 {
compatible = "fsl,imxrt-gpio", "fsl,imx35-gpio";
reg = <0x40130000 0x4000>;
interrupts = <102>,
<103>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
gpio3: gpio@40134000 {
compatible = "fsl,imxrt-gpio", "fsl,imx35-gpio";
reg = <0x40134000 0x4000>;
interrupts = <104>,
<105>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
gpio4: gpio@40138000 {
compatible = "fsl,imxrt-gpio", "fsl,imx35-gpio";
reg = <0x40138000 0x4000>;
interrupts = <106>,
<107>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
gpio5: gpio@4013c000 {
compatible = "fsl,imxrt-gpio", "fsl,imx35-gpio";
reg = <0x4013c000 0x4000>;
interrupts = <108>,
<109>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
gpio6: gpio@40140000 {
compatible = "fsl,imxrt-gpio", "fsl,imx35-gpio";
reg = <0x40140000 0x4000>;
interrupts = <61>,
<62>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
gpio7: gpio@40c5c000 {
compatible = "fsl,imxrt-gpio", "fsl,imx35-gpio";
reg = <0x40c5c000 0x4000>;
interrupts = <99>,
<99>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
gpio8: gpio@40c60000 {
compatible = "fsl,imxrt-gpio", "fsl,imx35-gpio";
reg = <0x40c60000 0x4000>;
interrupts = <99>,
<99>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
gpio9: gpio@40c64000 {
compatible = "fsl,imxrt-gpio", "fsl,imx35-gpio";
reg = <0x40c64000 0x4000>;
interrupts = <99>,
<99>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
gpio10: gpio@40c68000 {
compatible = "fsl,imxrt-gpio", "fsl,imx35-gpio";
reg = <0x40c68000 0x4000>;
interrupts = <99>,
<99>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
gpio11: gpio@40c6c000 {
compatible = "fsl,imxrt-gpio", "fsl,imx35-gpio";
reg = <0x40c6c000 0x4000>;
interrupts = <99>,
<99>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
gpio12: gpio@40c70000 {
compatible = "fsl,imxrt-gpio", "fsl,imx35-gpio";
reg = <0x40c70000 0x4000>;
interrupts = <61>,
<62>; // only cm4
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
gpio13: gpio@40ca0000 {
compatible = "fsl,imxrt-gpio", "fsl,imx35-gpio";
reg = <0x40ca0000 0x4000>;
interrupts = <93>,
<93>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
gpt1: gpt1@400ec000 {
compatible = "fsl,imxrt-gpt";
reg = <0x400ec000 0x4000>;
interrupts = <119>;
clocks = <&clks IMXRT1170_CLK_GPT1>;
status = "disabled";
};
};
};

View file

@ -56,6 +56,7 @@
#define MXC_CPU_IMXRT1020 0xB4 /* dummy ID */
#define MXC_CPU_IMXRT1050 0xB6 /* dummy ID */
#define MXC_CPU_IMXRT1170 0xBA /* dummy ID */
#define MXC_CPU_MX7ULP 0xE1 /* Temporally hard code */
#define MXC_CPU_VF610 0xF6 /* dummy ID */

View file

@ -269,6 +269,14 @@ config TARGET_IMX8MP_RSB3720A1_6G
select IMX8MP
select SUPPORT_SPL
select IMX8M_LPDDR4
config TARGET_LIBREM5
bool "Purism Librem5 Phone"
select BINMAN
select IMX8MQ
select SUPPORT_SPL
select IMX8M_LPDDR4
endchoice
source "board/advantech/imx8mp_rsb3720a1/Kconfig"
@ -290,6 +298,7 @@ source "board/kontron/sl-mx8mm/Kconfig"
source "board/menlo/mx8menlo/Kconfig"
source "board/phytec/phycore_imx8mm/Kconfig"
source "board/phytec/phycore_imx8mp/Kconfig"
source "board/purism/librem5/Kconfig"
source "board/ronetix/imx8mq-cm/Kconfig"
source "board/technexion/pico-imx8mq/Kconfig"
source "board/variscite/imx8mn_var_som/Kconfig"

View file

@ -12,6 +12,10 @@ config IMXRT1050
bool
select IMXRT
config IMXRT1170
bool
select IMXRT
config SYS_SOC
default "imxrt"
@ -27,9 +31,14 @@ config TARGET_IMXRT1050_EVK
bool "Support imxrt1050 EVK board"
select IMXRT1050
config TARGET_IMXRT1170_EVK
bool "Support imxrt1170 EVK board"
select IMXRT1170
endchoice
source "board/freescale/imxrt1020-evk/Kconfig"
source "board/freescale/imxrt1050-evk/Kconfig"
source "board/freescale/imxrt1170-evk/Kconfig"
endif

View file

@ -43,6 +43,8 @@ u32 get_cpu_rev(void)
return MXC_CPU_IMXRT1020 << 12;
#elif defined(CONFIG_IMXRT1050)
return MXC_CPU_IMXRT1050 << 12;
#elif defined(CONFIG_IMXRT1170)
return MXC_CPU_IMXRT1170 << 12;
#else
#error This IMXRT SoC is not supported
#endif

View file

@ -466,6 +466,17 @@ config TARGET_MX6ULL_14X14_EVK
select DM_THERMAL
imply CMD_DM
config TARGET_MX6ULZ_SMM_M2
bool "Support imx6ulz_smm_m2"
depends on MX6ULL
select DM
select DM_GPIO
select DM_I2C
select DM_SERIAL
select DM_MTD
select DM_THERMAL
select SUPPORT_SPL
config TARGET_MYS_6ULX
bool "MYiR MYS-6ULX"
depends on MX6ULL
@ -680,6 +691,7 @@ source "board/ge/b1x5v2/Kconfig"
source "board/aristainetos/Kconfig"
source "board/armadeus/opos6uldev/Kconfig"
source "board/boundary/nitrogen6x/Kconfig"
source "board/bsh/imx6ulz_smm_m2/Kconfig"
source "board/bticino/mamoj/Kconfig"
source "board/compulab/cm_fx6/Kconfig"
source "board/dhelectronics/dh_imx6/Kconfig"

View file

@ -288,7 +288,7 @@ static int spl_romapi_load_image_stream(struct spl_image_info *spl_image,
}
imagesize = img_info_size(phdr);
printf("Find img info 0x&%p, size %d\n", phdr, imagesize);
printf("Find img info 0x%p, size %d\n", phdr, imagesize);
if (p - phdr < imagesize) {
imagesize -= p - phdr;

View 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

View 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

View 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

View 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

View 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;
}

View 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)
{
}

View file

@ -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 },

View file

@ -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 },

View file

@ -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, },
};

View 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

View 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

View 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

View 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
*/

View 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;
}

View file

@ -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;

View file

@ -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

View file

@ -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));
}
}
}

View 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

View 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

View 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

View 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

View 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;
}

View 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

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

592
board/purism/librem5/spl.c Normal file
View 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();
}

View file

@ -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);

View file

@ -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();
}
}

View file

@ -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();
}
}

View file

@ -0,0 +1,80 @@
CONFIG_ARM=y
CONFIG_ARCH_MX6=y
CONFIG_SYS_TEXT_BASE=0x87800000
CONFIG_SYS_MALLOC_LEN=0x1000000
CONFIG_SYS_MALLOC_F_LEN=0x18000
CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
CONFIG_SPL_LIBGENERIC_SUPPORT=y
CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_SIZE=0x20000
CONFIG_ENV_OFFSET=0x400000
CONFIG_MX6ULL=y
CONFIG_TARGET_MX6ULZ_SMM_M2=y
CONFIG_DEFAULT_DEVICE_TREE="imx6ulz-bsh-smm-m2"
CONFIG_SPL_TEXT_BASE=0x00908000
CONFIG_SPL_SERIAL=y
CONFIG_SPL=y
CONFIG_DISTRO_DEFAULTS=y
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_BOOTDELAY=3
CONFIG_BOARD_LATE_INIT=y
CONFIG_SPL_BSS_START_ADDR=0x84100000
CONFIG_SYS_SPL_MALLOC=y
CONFIG_SPL_DMA=y
CONFIG_SPL_MTD_SUPPORT=y
CONFIG_SPL_NAND_SUPPORT=y
CONFIG_SPL_USB_HOST=y
CONFIG_SPL_USB_GADGET=y
CONFIG_SPL_USB_SDP_SUPPORT=y
CONFIG_SPL_WATCHDOG=y
CONFIG_CMD_DM=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_I2C=y
CONFIG_CMD_USB=y
CONFIG_CMD_USB_SDP=y
CONFIG_CMD_CACHE=y
CONFIG_CMD_MTDPARTS=y
CONFIG_MTDIDS_DEFAULT="nand0=gpmi-nand"
CONFIG_MTDPARTS_DEFAULT="mtdparts=gpmi-nand:4m(nandboot),1m(env),8m(kernel),1m(nanddtb),-(rootfs)"
CONFIG_CMD_UBI=y
# CONFIG_ISO_PARTITION is not set
CONFIG_OF_CONTROL=y
CONFIG_ENV_OVERWRITE=y
CONFIG_ENV_IS_IN_NAND=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
# CONFIG_NET is not set
CONFIG_BOUNCE_BUFFER=y
CONFIG_USB_FUNCTION_FASTBOOT=y
CONFIG_FASTBOOT_BUF_ADDR=0x82000000
CONFIG_FASTBOOT_FLASH=y
CONFIG_FASTBOOT_UUU_SUPPORT=y
CONFIG_FASTBOOT_FLASH_NAND=y
CONFIG_SYS_I2C_MXC=y
# CONFIG_MMC is not set
CONFIG_MTD=y
CONFIG_MTD_RAW_NAND=y
CONFIG_SYS_NAND_USE_FLASH_BBT=y
CONFIG_NAND_MXS=y
CONFIG_NAND_MXS_DT=y
CONFIG_SYS_NAND_ONFI_DETECTION=y
CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
CONFIG_SYS_NAND_U_BOOT_OFFS=0x111400
CONFIG_SYS_NAND_U_BOOT_OFFS_REDUND=0x291400
CONFIG_PINCTRL=y
CONFIG_PINCTRL_IMX6=y
CONFIG_DM_PMIC=y
CONFIG_DM_REGULATOR=y
CONFIG_DM_REGULATOR_FIXED=y
CONFIG_MXC_UART=y
CONFIG_IMX_THERMAL=y
CONFIG_USB=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="BSH"
CONFIG_USB_GADGET_VENDOR_NUM=0x0525
CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5
CONFIG_CI_UDC=y
CONFIG_SDP_LOADADDR=0x877fffc0

View file

@ -86,6 +86,7 @@ CONFIG_MD5SUM_VERIFY=y
CONFIG_CMD_MEMTEST=y
CONFIG_CMD_SHA1SUM=y
CONFIG_SHA1SUM_VERIFY=y
CONFIG_CMD_BIND=y
CONFIG_CMD_CLK=y
CONFIG_CMD_DFU=y
CONFIG_CMD_FUSE=y
@ -168,6 +169,7 @@ CONFIG_FASTBOOT_BUF_SIZE=0x20000000
CONFIG_FASTBOOT_FLASH=y
CONFIG_FASTBOOT_FLASH_MMC_DEV=0
CONFIG_GPIO_HOG=y
CONFIG_SPL_GPIO_HOG=y
CONFIG_MXC_GPIO=y
CONFIG_DM_I2C=y
# CONFIG_INPUT is not set
@ -238,20 +240,23 @@ CONFIG_DM_THERMAL=y
CONFIG_IMX_TMU=y
CONFIG_USB=y
# CONFIG_SPL_DM_USB is not set
CONFIG_DM_USB_GADGET=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_XHCI_DWC3_OF_SIMPLE=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_DWC3=y
# CONFIG_USB_DWC3_GADGET is not set
CONFIG_USB_DWC3_GENERIC=y
CONFIG_USB_STORAGE=y
CONFIG_USB_HOST_ETHER=y
CONFIG_USB_ETHER_ASIX=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="DH electronics"
CONFIG_USB_GADGET_VENDOR_NUM=0x0525
CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5
CONFIG_CI_UDC=y
CONFIG_SDP_LOADADDR=0x0
CONFIG_USB_FUNCTION_ACM=y
CONFIG_USB_ETHER=y
CONFIG_USB_ETH_CDC=y
CONFIG_IMX_WATCHDOG=y
CONFIG_OF_LIBFDT_OVERLAY=y

View file

@ -0,0 +1,70 @@
CONFIG_ARM=y
CONFIG_SYS_DCACHE_OFF=y
# CONFIG_SPL_SYS_DCACHE_OFF is not set
CONFIG_ARCH_IMXRT=y
CONFIG_SYS_TEXT_BASE=0x20240000
CONFIG_SYS_MALLOC_LEN=0x8000
CONFIG_SYS_MALLOC_F_LEN=0x8000
CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
CONFIG_SPL_LIBGENERIC_SUPPORT=y
CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_OFFSET=0x80000
CONFIG_DM_GPIO=y
CONFIG_DEFAULT_DEVICE_TREE="imxrt1170-evk"
CONFIG_SPL_TEXT_BASE=0x202C0000
CONFIG_TARGET_IMXRT1170_EVK=y
CONFIG_SPL_MMC=y
CONFIG_SPL_SERIAL=y
CONFIG_SPL_SIZE_LIMIT=0x20000
CONFIG_SPL=y
CONFIG_DISTRO_DEFAULTS=y
CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x20340000
CONFIG_SYS_LOAD_ADDR=0x202C0000
CONFIG_SD_BOOT=y
# CONFIG_USE_BOOTCOMMAND is not set
CONFIG_SYS_CONSOLE_ENV_OVERWRITE=y
# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_SPL_NO_BSS_LIMIT=y
CONFIG_SPL_BOARD_INIT=y
# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
CONFIG_SPL_SYS_MALLOC_SIMPLE=y
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x100
# CONFIG_SPL_CRC32 is not set
# CONFIG_BOOTM_NETBSD is not set
# CONFIG_BOOTM_PLAN9 is not set
# CONFIG_BOOTM_RTEMS is not set
# CONFIG_BOOTM_VXWORKS is not set
# CONFIG_CMD_MII is not set
# CONFIG_SPL_DOS_PARTITION is not set
# CONFIG_ISO_PARTITION is not set
# CONFIG_EFI_PARTITION is not set
CONFIG_OF_CONTROL=y
CONFIG_SPL_OF_CONTROL=y
CONFIG_ENV_IS_NOWHERE=y
CONFIG_ENV_IS_IN_MMC=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
CONFIG_SPL_DM=y
CONFIG_SPL_DM_SEQ_ALIAS=y
# CONFIG_OF_TRANSLATE is not set
CONFIG_SPL_CLK_COMPOSITE_CCF=y
CONFIG_CLK_COMPOSITE_CCF=y
CONFIG_SPL_CLK_IMXRT1170=y
CONFIG_CLK_IMXRT1170=y
# CONFIG_SPL_DM_GPIO is not set
CONFIG_MXC_GPIO=y
# CONFIG_INPUT is not set
CONFIG_FSL_USDHC=y
CONFIG_PINCTRL=y
CONFIG_SPL_PINCTRL=y
CONFIG_PINCTRL_IMXRT=y
CONFIG_RAM=y
CONFIG_SPL_RAM=y
CONFIG_IMXRT_SDRAM=y
CONFIG_FSL_LPUART=y
CONFIG_TIMER=y
CONFIG_SPL_TIMER=y
CONFIG_IMX_GPT_TIMER=y

152
configs/librem5_defconfig Normal file
View file

@ -0,0 +1,152 @@
CONFIG_ARM=y
CONFIG_ARCH_IMX8M=y
CONFIG_SYS_TEXT_BASE=0x40200000
CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
CONFIG_SPL_LIBGENERIC_SUPPORT=y
CONFIG_ENV_SIZE=0x2000
CONFIG_ENV_OFFSET=0x3FE000
CONFIG_SYS_I2C_MXC_I2C1=y
CONFIG_SYS_I2C_MXC_I2C2=y
CONFIG_SYS_I2C_MXC_I2C3=y
CONFIG_SYS_I2C_MXC_I2C4=y
CONFIG_DM_GPIO=y
CONFIG_DEFAULT_DEVICE_TREE="imx8mq-librem5-r4"
CONFIG_SPL_TEXT_BASE=0x7E1000
CONFIG_TARGET_LIBREM5=y
CONFIG_SPL_MMC=y
CONFIG_SPL_SERIAL=y
CONFIG_SPL_DRIVERS_MISC=y
CONFIG_SPL=y
CONFIG_IMX_BOOTAUX=y
CONFIG_SYS_LOAD_ADDR=0x40480000
CONFIG_DISTRO_DEFAULTS=y
CONFIG_REMAKE_ELF=y
CONFIG_FIT=y
CONFIG_FIT_EXTERNAL_OFFSET=0x3000
CONFIG_SPL_LOAD_FIT=y
# CONFIG_USE_SPL_FIT_GENERATOR is not set
CONFIG_OF_SYSTEM_SETUP=y
CONFIG_BOOTDELAY=0
CONFIG_SYS_CONSOLE_IS_IN_ENV=y
# CONFIG_SYS_DEVICE_NULLDEV is not set
CONFIG_ARCH_MISC_INIT=y
CONFIG_BOARD_EARLY_INIT_F=y
CONFIG_BOARD_LATE_INIT=y
CONFIG_SPL_MAX_SIZE=0x25000
CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
CONFIG_SPL_BSS_START_ADDR=0x180000
CONFIG_SPL_BSS_MAX_SIZE=0x2000
CONFIG_SPL_BOARD_INIT=y
# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
CONFIG_SPL_STACK=0x187ff0
CONFIG_SYS_SPL_MALLOC=y
CONFIG_HAS_CUSTOM_SPL_MALLOC_START=y
CONFIG_CUSTOM_SYS_SPL_MALLOC_ADDR=0x42200000
CONFIG_SYS_SPL_MALLOC_SIZE=0x80000
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x300
CONFIG_SPL_I2C=y
CONFIG_SPL_POWER=y
CONFIG_SPL_USB_GADGET=y
CONFIG_SPL_USB_SDP_SUPPORT=y
CONFIG_SPL_WATCHDOG=y
CONFIG_SYS_PROMPT="u-boot=> "
CONFIG_SYS_MAXARGS=64
CONFIG_SYS_PBSIZE=1050
CONFIG_CMD_MEMTEST=y
CONFIG_SYS_ALT_MEMTEST=y
CONFIG_CMD_CLK=y
CONFIG_CMD_FUSE=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
CONFIG_CMD_USB=y
CONFIG_CMD_USB_SDP=y
CONFIG_CMD_CACHE=y
CONFIG_CMD_REGULATOR=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_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
CONFIG_SPL_DM=y
CONFIG_DEVRES=y
# CONFIG_SPL_BLK is not set
CONFIG_BUTTON=y
CONFIG_BUTTON_GPIO=y
CONFIG_SAVED_DRAM_TIMING_BASE=0x40000000
CONFIG_DMA=y
CONFIG_DMA_CHANNELS=y
CONFIG_USB_FUNCTION_FASTBOOT=y
CONFIG_FASTBOOT_BUF_ADDR=0x43000000
CONFIG_FASTBOOT_BUF_SIZE=0x40000000
CONFIG_FASTBOOT_FLASH=y
CONFIG_FASTBOOT_UUU_SUPPORT=y
CONFIG_FASTBOOT_FLASH_MMC_DEV=0
CONFIG_FASTBOOT_MMC_BOOT_SUPPORT=y
CONFIG_FASTBOOT_MMC_USER_SUPPORT=y
CONFIG_FASTBOOT_CMD_OEM_PARTCONF=y
CONFIG_FASTBOOT_CMD_OEM_BOOTBUS=y
# CONFIG_SPL_DM_GPIO is not set
CONFIG_GPIO_HOG=y
CONFIG_DM_GPIO_LOOKUP_LABEL=y
CONFIG_MXC_GPIO=y
CONFIG_DM_I2C=y
# CONFIG_SPL_DM_I2C is not set
CONFIG_SPL_SYS_I2C_LEGACY=y
CONFIG_SYS_I2C_EARLY_INIT=y
CONFIG_SYS_MXC_I2C1_SPEED=50000
CONFIG_SYS_MXC_I2C2_SPEED=50000
CONFIG_SYS_MXC_I2C3_SPEED=50000
CONFIG_SYS_MXC_I2C4_SPEED=50000
CONFIG_SYS_I2C_SPEED=50000
CONFIG_LED=y
CONFIG_LED_BLINK=y
CONFIG_LED_GPIO=y
CONFIG_MISC=y
CONFIG_PWRSEQ=y
CONFIG_MMC_BROKEN_CD=y
# CONFIG_SPL_DM_MMC is not set
CONFIG_SUPPORT_EMMC_BOOT=y
CONFIG_MMC_IO_VOLTAGE=y
CONFIG_MMC_UHS_SUPPORT=y
CONFIG_MMC_HS400_ES_SUPPORT=y
CONFIG_MMC_HS400_SUPPORT=y
CONFIG_FSL_USDHC=y
CONFIG_DM_SPI_FLASH=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_SPI_FLASH_WINBOND=y
CONFIG_DM_ETH=y
CONFIG_PHY=y
CONFIG_PHY_IMX8MQ_USB=y
CONFIG_PINCTRL=y
CONFIG_PINCTRL_IMX8M=y
CONFIG_POWER_LEGACY=y
CONFIG_POWER_DOMAIN=y
CONFIG_IMX8M_POWER_DOMAIN=y
CONFIG_DM_REGULATOR=y
CONFIG_DM_REGULATOR_FIXED=y
CONFIG_DM_REGULATOR_GPIO=y
CONFIG_POWER_I2C=y
CONFIG_DM_RESET=y
CONFIG_MXC_UART=y
CONFIG_SPI=y
CONFIG_DM_SPI=y
CONFIG_MXC_SPI=y
CONFIG_DM_THERMAL=y
CONFIG_IMX_TMU=y
CONFIG_USB=y
CONFIG_DM_USB_GADGET=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_GENERIC=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Purism"
CONFIG_USB_GADGET_VENDOR_NUM=0x0525
CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5
CONFIG_SDP_LOADADDR=0x40400000
CONFIG_USB_FUNCTION_ACM=y

View file

@ -15,10 +15,14 @@ CONFIG_SYS_PROMPT="Verdin iMX8MM # "
CONFIG_SPL_MMC=y
CONFIG_SPL_SERIAL=y
CONFIG_SPL_DRIVERS_MISC=y
CONFIG_BOOTCOUNT_BOOTLIMIT=3
CONFIG_SYS_BOOTCOUNT_ADDR=0x30370090
CONFIG_SPL=y
CONFIG_SYS_LOAD_ADDR=0x40480000
CONFIG_SYS_BOOTCOUNT_SINGLEWORD=y
CONFIG_SYS_LOAD_ADDR=0x48280000
CONFIG_SYS_MEMTEST_START=0x40000000
CONFIG_SYS_MEMTEST_END=0x80000000
CONFIG_LTO=y
CONFIG_DISTRO_DEFAULTS=y
CONFIG_FIT=y
CONFIG_FIT_EXTERNAL_OFFSET=0x3000
@ -26,7 +30,7 @@ CONFIG_FIT_VERBOSE=y
CONFIG_SPL_LOAD_FIT=y
# CONFIG_USE_SPL_FIT_GENERATOR is not set
CONFIG_OF_SYSTEM_SETUP=y
# CONFIG_USE_BOOTCOMMAND is not set
CONFIG_BOOTDELAY=1
CONFIG_USE_PREBOOT=y
CONFIG_PREBOOT="test -n ${fdtfile} || setenv fdtfile imx8mm-verdin-${variant}-${fdt_board}.dtb"
CONFIG_LOG=y
@ -54,20 +58,26 @@ CONFIG_SYS_PBSIZE=2081
# CONFIG_BOOTM_NETBSD is not set
CONFIG_CMD_ASKENV=y
# CONFIG_CMD_EXPORTENV is not set
# CONFIG_CMD_CRC32 is not set
CONFIG_CRC32_VERIFY=y
CONFIG_CMD_MD5SUM=y
CONFIG_MD5SUM_VERIFY=y
CONFIG_CMD_MEMTEST=y
CONFIG_CMD_CLK=y
CONFIG_CMD_FUSE=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
CONFIG_CMD_READ=y
CONFIG_CMD_USB=y
CONFIG_CMD_BOOTCOUNT=y
CONFIG_CMD_CACHE=y
CONFIG_CMD_TIME=y
CONFIG_CMD_UUID=y
CONFIG_CMD_PMIC=y
CONFIG_CMD_REGULATOR=y
CONFIG_CMD_EXT4_WRITE=y
# CONFIG_ISO_PARTITION is not set
# CONFIG_EFI_PARTITION is not set
# CONFIG_SPL_EFI_PARTITION is not set
CONFIG_OF_CONTROL=y
CONFIG_SPL_OF_CONTROL=y
CONFIG_ENV_OVERWRITE=y
@ -76,11 +86,13 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_SYS_MMC_ENV_PART=1
CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
CONFIG_USE_ETHPRIME=y
CONFIG_ETHPRIME="FEC"
CONFIG_ETHPRIME="eth0"
CONFIG_VERSION_VARIABLE=y
CONFIG_IP_DEFRAG=y
CONFIG_TFTP_BLOCKSIZE=4096
CONFIG_SPL_DM=y
CONFIG_BOOTCOUNT_LIMIT=y
CONFIG_SYS_BOOTCOUNT_MAGIC=0xB0C40000
CONFIG_SPL_CLK_COMPOSITE_CCF=y
CONFIG_CLK_COMPOSITE_CCF=y
CONFIG_SPL_CLK_IMX8MM=y
@ -91,11 +103,21 @@ CONFIG_DM_I2C=y
CONFIG_MISC=y
CONFIG_I2C_EEPROM=y
CONFIG_SUPPORT_EMMC_BOOT=y
CONFIG_MMC_IO_VOLTAGE=y
CONFIG_SPL_MMC_IO_VOLTAGE=y
CONFIG_MMC_UHS_SUPPORT=y
CONFIG_SPL_MMC_UHS_SUPPORT=y
CONFIG_MMC_HS400_ES_SUPPORT=y
CONFIG_MMC_HS400_SUPPORT=y
CONFIG_SPL_MMC_HS400_SUPPORT=y
CONFIG_FSL_USDHC=y
CONFIG_PHYLIB=y
CONFIG_PHY_ADDR_ENABLE=y
CONFIG_PHY_MICREL=y
CONFIG_PHY_MICREL_KSZ90X1=y
CONFIG_PHY_FIXED=y
CONFIG_DM_ETH=y
CONFIG_DM_MDIO=y
CONFIG_FEC_MXC=y
CONFIG_MII=y
CONFIG_PINCTRL=y
@ -105,7 +127,6 @@ CONFIG_POWER_DOMAIN=y
CONFIG_IMX8M_POWER_DOMAIN=y
CONFIG_DM_PMIC=y
CONFIG_SPL_DM_PMIC_PCA9450=y
CONFIG_DM_PMIC_PFUZE100=y
CONFIG_DM_REGULATOR=y
CONFIG_DM_REGULATOR_FIXED=y
CONFIG_DM_REGULATOR_GPIO=y
@ -116,8 +137,11 @@ CONFIG_SPL_SYSRESET=y
CONFIG_SYSRESET_PSCI=y
CONFIG_SYSRESET_WATCHDOG=y
CONFIG_DM_THERMAL=y
CONFIG_IMX_TMU=y
CONFIG_USB=y
# CONFIG_SPL_DM_USB is not set
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_KEYBOARD=y
CONFIG_USB_HOST_ETHER=y
CONFIG_IMX_WATCHDOG=y
CONFIG_HEXDUMP=y
CONFIG_OF_LIBFDT_OVERLAY=y

View file

@ -22,7 +22,7 @@ CONFIG_SPL_DRIVERS_MISC=y
CONFIG_SPL=y
CONFIG_IMX_BOOTAUX=y
CONFIG_SPL_IMX_ROMAPI_LOADADDR=0x48000000
CONFIG_SYS_LOAD_ADDR=0x43500000
CONFIG_SYS_LOAD_ADDR=0x48280000
CONFIG_SYS_MEMTEST_START=0x40000000
CONFIG_SYS_MEMTEST_END=0x80000000
CONFIG_DISTRO_DEFAULTS=y

View file

@ -28,6 +28,7 @@ Board-specific doc
nokia/index
nxp/index
openpiton/index
purism/index
qualcomm/index
rockchip/index
samsung/index

View file

@ -0,0 +1,9 @@
.. SPDX-License-Identifier: GPL-2.0+
Purism SPC
==========
.. toctree::
:maxdepth: 2
librem5

View file

@ -0,0 +1,60 @@
.. SPDX-License-Identifier: GPL-2.0+
Librem5
==========
U-Boot for the Purism Librem5 phone
Quick Start
-----------
- Build the ARM Trusted firmware binary
- Get ddr and hdmi firmware
- Build U-Boot
Get and Build the ARM Trusted firmware
--------------------------------------
Note: srctree is U-Boot source directory
Get ATF from: https://source.puri.sm/Librem5/arm-trusted-firmware
branch: librem5
.. code-block:: bash
$ make PLAT=imx8mq CROSS_COMPILE=aarch64-linux-gnu- bl31
$ cp build/imx8mq/release/bl31.bin $(builddir)
Get the ddr and display port firmware
-------------------------------------
.. code-block:: bash
$ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.15.bin
$ chmod +x firmware-imx-8.15.bin
$ ./firmware-imx-8.15.bin
$ cp firmware-imx-8.15/firmware/hdmi/cadence/signed_dp_imx8m.bin $(builddir)
$ cp firmware-imx-8.15/firmware/ddr/synopsys/lpddr4*.bin $(builddir)
Build U-Boot
------------
.. code-block:: bash
$ export CROSS_COMPILE=aarch64-linux-gnu-
$ make librem5_defconfig
$ make ARCH=arm
Burn the flash.bin
------------------
Use uuu to burn flash.bin. Power on the phone while holding vol+ to get it
into uuu mode.
.. code-block:: bash
$ git clone https://source.puri.sm/Librem5/librem5-devkit-tools.git
$ cd librem5-devkit-tools
$ cp $(builddir)/flash.bin files/u-boot-librem5.imx
$ uuu uuu_scripts/u-boot_flash_librem5.lst
Reboot the phone.

View file

@ -0,0 +1,77 @@
#!/bin/sh
# 0) Generate keys
#
# WARNING: ECDSA keys are only supported by HAB 4.5 and newer (i.e. i.MX8M Plus)
#
# cd /path/to/cst-3.3.1/keys/
# ./hab4_pki_tree.sh -existing-ca n -use-ecc n -kl 4096 -duration 10 -num-srk 4 -srk-ca y
# cd /path/to/cst-3.3.1/crts/
# ../linux64/bin/srktool -h 4 -t SRK_1_2_3_4_table.bin -e SRK_1_2_3_4_fuse.bin -d sha256 -c ./SRK1_sha256_4096_65537_v3_ca_crt.pem,./SRK2_sha256_4096_65537_v3_ca_crt.pem,./SRK3_sha256_4096_65537_v3_ca_crt.pem,./SRK4_sha256_4096_65537_v3_ca_crt.pem -f 1
# 1) Build U-Boot (e.g. for i.MX8MM)
#
# export ATF_LOAD_ADDR=0x920000
# cp -Lv /path/to/arm-trusted-firmware/build/imx8mm/release/bl31.bin .
# cp -Lv /path/to/firmware-imx-8.14/firmware/ddr/synopsys/ddr3* .
# make -j imx8mm_board_defconfig
# make -j`nproc` flash.bin
# 2) Sign SPL and DRAM blobs
cp doc/imx/habv4/csf_examples/mx8m/csf_spl.txt csf_spl.tmp
cp doc/imx/habv4/csf_examples/mx8m/csf_fit.txt csf_fit.tmp
spl_block_base=$(printf "0x%x" $(( $(sed -n "/CONFIG_SPL_TEXT_BASE=/ s@.*=@@p" .config) - 0x40)) )
spl_block_size=$(printf "0x%x" $(stat -tc %s u-boot-spl-ddr.bin))
sed -i "/Blocks = / s@.*@ Blocks = $spl_block_base 0x0 $spl_block_size \"flash.bin\"@" csf_spl.tmp
# Generate CSF blob
cst -i csf_spl.tmp -o csf_spl.bin
# Patch CSF blob into flash.bin
spl_csf_offset=$(xxd -s 24 -l 4 -e flash.bin | cut -d " " -f 2 | sed "s@^@0x@")
spl_bin_offset=$(xxd -s 4 -l 4 -e flash.bin | cut -d " " -f 2 | sed "s@^@0x@")
spl_dd_offset=$((${spl_csf_offset} - ${spl_bin_offset} + 0x40))
dd if=csf_spl.bin of=flash.bin bs=1 seek=${spl_dd_offset} conv=notrunc
# 3) Sign u-boot.itb
# fitImage tree
fit_block_base=$(printf "0x%x" $(( $(sed -n "/CONFIG_SYS_TEXT_BASE=/ s@.*=@@p" .config) - $(sed -n "/CONFIG_FIT_EXTERNAL_OFFSET=/ s@.*=@@p" .config) - 0x200 - 0x40)) )
fit_block_offset=$(printf "0x%s" $(fdtget -t x u-boot.dtb /binman/imx-boot/uboot offset))
fit_block_size=$(printf "0x%x" $(( ( $(fdtdump u-boot.itb 2>/dev/null | sed -n "/^...totalsize:/ s@.*\(0x[0-9a-f]\+\).*@\1@p") + 0x1000 - 0x1 ) & ~(0x1000 - 0x1) + 0x20 )) )
sed -i "/Blocks = / s@.*@ Blocks = $fit_block_base $fit_block_offset $fit_block_size \"flash.bin\", \\\\@" csf_fit.tmp
# U-Boot
uboot_block_base=$(printf "0x%s" $(fdtget -t x u-boot.itb /images/uboot load))
uboot_block_offset=$(printf "0x%x" $(( $(printf "0x%s" $(fdtget -t x u-boot.itb /images/uboot data-position)) + ${fit_block_offset} )))
uboot_block_size=$(printf "0x%s" $(fdtget -t x u-boot.itb /images/uboot data-size))
sed -i "/0xuuuu/ s@.*@ $uboot_block_base $uboot_block_offset $uboot_block_size \"flash.bin\", \\\\@" csf_fit.tmp
# ATF
atf_block_base=$(printf "0x%s" $(fdtget -t x u-boot.itb /images/atf load))
atf_block_offset=$(printf "0x%x" $(( $(printf "0x%s" $(fdtget -t x u-boot.itb /images/atf data-position)) + ${fit_block_offset} )))
atf_block_size=$(printf "0x%s" $(fdtget -t x u-boot.itb /images/atf data-size))
sed -i "/0xaaaa/ s@.*@ $atf_block_base $atf_block_offset $atf_block_size \"flash.bin\", \\\\@" csf_fit.tmp
# DTB
dtb_block_base=$(printf "0x%x" $(( ${uboot_block_base} + ${uboot_block_size} )))
dtb_block_offset=$(printf "0x%x" $(( $(printf "0x%s" $(fdtget -t x u-boot.itb /images/fdt-1 data-position)) + ${fit_block_offset} )))
dtb_block_size=$(printf "0x%s" $(fdtget -t x u-boot.itb /images/fdt-1 data-size))
sed -i "/0xdddd/ s@.*@ $dtb_block_base $dtb_block_offset $dtb_block_size \"flash.bin\"@" csf_fit.tmp
# IVT
ivt_ptr_base=$(printf "%08x" ${fit_block_base} | sed "s@\(..\)\(..\)\(..\)\(..\)@0x\4\3\2\1@")
ivt_block_base=$(printf "%08x" $(( ${fit_block_base} + ${fit_block_size} - 0x20 )) | sed "s@\(..\)\(..\)\(..\)\(..\)@0x\4\3\2\1@")
csf_block_base=$(printf "%08x" $(( ${fit_block_base} + ${fit_block_size} )) | sed "s@\(..\)\(..\)\(..\)\(..\)@0x\4\3\2\1@")
ivt_block_offset=$((${fit_block_offset} + ${fit_block_size} - 0x20))
csf_block_offset=$((${ivt_block_offset} + 0x20))
echo "0xd1002041 ${ivt_ptr_base} 0x00000000 0x00000000 0x00000000 ${ivt_block_base} ${csf_block_base} 0x00000000" | xxd -r -p > ivt.bin
dd if=ivt.bin of=flash.bin bs=1 seek=${ivt_block_offset} conv=notrunc
# Generate CSF blob
cst -i csf_fit.tmp -o csf_fit.bin
# Patch CSF blob into flash.bin
dd if=csf_fit.bin of=flash.bin bs=1 seek=${csf_block_offset} conv=notrunc

View file

@ -0,0 +1,36 @@
[Header]
Version = 4.3
Hash Algorithm = sha256
Engine = CAAM
Engine Configuration = 0
Certificate Format = X509
Signature Format = CMS
[Install SRK]
# FIXME: Adjust path here
File = "/path/to/cst-3.3.1/crts/SRK_1_2_3_4_table.bin"
Source index = 0
[Install CSFK]
# FIXME: Adjust path here
File = "/path/to/cst-3.3.1/crts/CSF1_1_sha256_4096_65537_v3_usr_crt.pem"
[Authenticate CSF]
[Install Key]
Verification index = 0
Target Index = 2
# FIXME: Adjust path here
File = "/path/to/cst-3.3.1/crts/IMG1_1_sha256_4096_65537_v3_usr_crt.pem"
[Authenticate Data]
Verification index = 2
# FIXME:
# Line 1 -- fitImage tree
# Line 2 -- U-Boot u-boot-nodtb.bin blob
# Line 3 -- ATF BL31 blob
# Line 4 -- DT blob
Blocks = 0x401fcdc0 0x57c00 0xffff "flash.bin", \
0x40200000 0x62c00 0xuuuu "flash.bin", \
0x920000 0x00000 0xaaaa "flash.bin", \
0x40200000 0x00000 0xdddd "flash.bin"

View file

@ -0,0 +1,33 @@
[Header]
Version = 4.3
Hash Algorithm = sha256
Engine = CAAM
Engine Configuration = 0
Certificate Format = X509
Signature Format = CMS
[Install SRK]
# FIXME: Adjust path here
File = "/path/to/cst-3.3.1/crts/SRK_1_2_3_4_table.bin"
Source index = 0
[Install CSFK]
# FIXME: Adjust path here
File = "/path/to/cst-3.3.1/crts/CSF1_1_sha256_4096_65537_v3_usr_crt.pem"
[Authenticate CSF]
[Unlock]
Engine = CAAM
Features = MID
[Install Key]
Verification index = 0
Target Index = 2
# FIXME: Adjust path here
File = "/path/to/cst-3.3.1/crts/IMG1_1_sha256_4096_65537_v3_usr_crt.pem"
[Authenticate Data]
Verification index = 2
# FIXME: Adjust start (first column) and size (third column) here
Blocks = 0x7e0fc0 0x0 0x306f0 "flash.bin"

View file

@ -0,0 +1,265 @@
+=========================================================+
+ i.MX8M U-Boot HABv4 Secure Boot guide for SPL targets +
+=========================================================+
1. HABv4 secure boot process
-----------------------------
This document is an addendum of mx6_mx7_spl_secure_boot.txt guide describing
a step-by-step procedure on how to sign and securely boot an U-Boot image for
SPL targets on i.MX8M, i.MX8M Mini, i.MX8M Nano, i.MX8M Plus.
Details about HAB can be found in the application note AN4581[1] and in the
introduction_habv4.txt document.
1.1 Building a SPL target supporting secure boot
-------------------------------------------------
The U-Boot build for i.MX8M SoC makes use of Second Program Loader (SPL)
support, fitImage support and custom i.MX8M specific flash.bin container.
This leads to a generation of multiple intermediate build artifacts, the
U-Boot SPL, U-Boot binary, DT blob. These later two artifacts are bundled
with external ATF BL31 blob to form a fitImage. The fitImage is bundled
with SPL and external DDR and optional HDMI PHY initialization blobs to
form the final flash.bin container. The HABv4 can be used to authenticate
all of the input binaries separately.
Out of reset the ROM code authenticates the SPL and PHY initialization
blobs, combination of which is responsible for initializing essential
features such as DDR, UART, PMIC and clock enablement. Once the DDR is
available, the SPL code loads the secondary fitImage to its specific
address and call the HAB APIs to extend the root of trust on its
components.
The U-Boot SPL provides support to secure boot configuration and also
provide access to the HAB APIs exposed by the ROM vector table, the
U-Boot provides access to HAB APIs via SMC calls to ATF. The support
is enabled by selecting the CONFIG_IMX_HAB option.
When built with this configuration the U-Boot correctly pads combined
SPL and PHY initialization blob image, called u-boot-spl-ddr.bin, by
aligning to the next 0xC00 address, so the CSF signature data generated
by CST can be concatenated to the image.
The U-Boot also reserves space in the fitImage binary (u-boot.itb) between
the fitImage tree and external blobs included in it, so it can be used to
inject IVT and CST signatures used by SPL HAB calls to authenticate the
fitImage components.
The diagram below illustrate a signed SPL combined with DDR PHY
initialization firmware blobs part of flash.bin container layout.
This part is loaded to memory address ( CONFIG_SPL_TEXT_BASE - 0x40 ) and
authenticated the BootROM. The reason for the offset is so that the *entry
would be at memory address CONFIG_SPL_TEXT_BASE when BootROM executes the
code within it:
------- +-----------------------------+ <-- *start
^ | Image Vector Table |
| | (0x20 bytes) |
| +-----------------------------+ <-- *boot_data
| | Boot Data |
| +-----------------------------+
| | Padding |
Signed | | to 0x40 bytes from *start |
Data | +-----------------------------+ <-- *entry
| | |
| | SPL combined with DDR PHY |
| | initialization blobs |
| | (u-boot-spl-ddr.bin) |
| | |
| +-----------------------------+
v | Padding |
------- +-----------------------------+ <-- *csf
| |
| Command Sequence File (CSF) |
| |
+-----------------------------+
| Padding (optional) |
+-----------------------------+
The diagram below illustrate a signed U-Boot binary, DT blob and external
ATF BL31 blob combined to form fitImage part of flash.bin container layout.
The *load_address is derived from CONFIG_SYS_TEXT_BASE such that the U-Boot
binary *start is placed exactly at CONFIG_SPL_TEXT_BASE in DRAM, however the
SPL moves the fitImage tree further to location:
*load_address = CONFIG_SPL_TEXT_BASE - CONFIG_FIT_EXTERNAL_OFFSET (=12kiB) -
512 Byte sector - sizeof(mkimage header)
------- +-----------------------------+ <-- *load_address
^ | |
| | fitImage tree |
| | with external data at |
| | offset 12 kiB from tree |
| | (cca. 1 kiB) |
Signed | | |
.----- Tree | +-----------------------------+
| Data | | Padding to next 4k aligned |
| | | from *load_address |
| | +-----------------------------+ <-- *ivt
| | | Image Vector Table |
| v | (0x20 bytes) |
| ------- +-----------------------------+ <-- *csf
| | Command Sequence File (CSF) |
| | for all signed entries in |
>--------------->| the fitImage, tree and data |
| | (cca 6-7 kiB) |
| +-----------------------------+
| | Padding to 12 kiB offset |
| | from *load_address |
| ------- +-----------------------------+ <-- *start
| ^ | |
| Signed | | |
|---- Payload | | U-Boot external data blob |
| Data | | |
| v | |
| ------- +-----------------------------+
| | Padding to 4 Bytes |
| ------- +-----------------------------+
| ^ | |
| Signed | | |
|---- Payload | | ATF external data blob |
| Data | | |
| v | |
| ------- +-----------------------------+
| | Padding to 4 Bytes |
| ------- +-----------------------------+
| ^ | |
| Signed | | |
'---- Payload | | DTB external data blob |
Data | | |
v | |
------- +-----------------------------+
The diagram below illustrate a combined flash.bin container layout:
+-----------------------------+
| Signed SPL part |
+-----------------------------+
| Signed fitImage part |
+-----------------------------+
1.2 Enabling the secure boot support
-------------------------------------
The first step is to generate an U-Boot image supporting the HAB features
mentioned above, this can be achieved by adding CONFIG_IMX_HAB to the
build configuration:
- Defconfig:
CONFIG_IMX_HAB=y
- Kconfig:
ARM architecture -> Support i.MX HAB features
1.3 Signing the images
-----------------------
The CSF contains all the commands that the HAB executes during the secure
boot. These commands instruct the HAB code on which memory areas of the image
to authenticate, which keys to install, use and etc.
CSF examples are available under doc/imx/habv4/csf_examples/ directory.
CSF "Blocks" line for csf_spl.txt can be generated as follows:
```
spl_block_base=$(printf "0x%x" $(( $(sed -n "/CONFIG_SPL_TEXT_BASE=/ s@.*=@@p" .config) - 0x40)) )
spl_block_size=$(printf "0x%x" $(stat -tc %s u-boot-spl-ddr.bin))
sed -i "/Blocks = / s@.*@ Blocks = $spl_block_base 0x0 $spl_block_size \"flash.bin\"@" csf_spl.txt
```
The resulting line looks as follows:
```
Blocks = 0x7e0fc0 0x0 0x306f0 "flash.bin"
```
The columns mean:
- CONFIG_SPL_TEXT_BASE - 0x40 -- Start address of signed data, in DRAM
- 0x0 -- Start address of signed data, in "flash.bin"
- 0x306f0 -- Length of signed data, in "flash.bin"
- Filename -- "flash.bin"
To generate signature for the SPL part of flash.bin container, use CST:
```
cst -i csf_spl.tmp -o csf_spl.bin
```
The newly generated CST blob has to be patched into existing flash.bin
container. Conveniently, flash.bin IVT contains physical address of the
CSF blob. Remember, the SPL part of flash.bin container is loaded by the
BootROM at CONFIG_SPL_TEXT_BASE - 0x40 , so the offset of CSF blob in
the fitImage can be calculated and inserted into the flash.bin in the
correct location as follows:
```
# offset = IVT_HEADER[6 = CSF address] - CONFIG_SPL_TEXT_BASE - 0x40
spl_csf_offset=$(xxd -s 24 -l 4 -e flash.bin | cut -d " " -f 2 | sed "s@^@0x@")
spl_bin_offset=$(xxd -s 4 -l 4 -e flash.bin | cut -d " " -f 2 | sed "s@^@0x@")
spl_dd_offset=$((${spl_csf_offset} - ${spl_bin_offset} + 0x40))
dd if=csf_spl.bin of=flash.bin bs=1 seek=${spl_dd_offset} conv=notrunc
```
CSF "Blocks" line for csf_fit.txt can be generated as follows:
```
# fitImage tree
fit_block_base=$(printf "0x%x" $(( $(sed -n "/CONFIG_SYS_TEXT_BASE=/ s@.*=@@p" .config) - $(sed -n "/CONFIG_FIT_EXTERNAL_OFFSET=/ s@.*=@@p" .config) - 0x200 - 0x40)) )
fit_block_offset=$(printf "0x%s" $(fdtget -t x u-boot.dtb /binman/imx-boot/uboot offset))
fit_block_size=$(printf "0x%x" $(( ( $(fdtdump u-boot.itb 2>/dev/null | sed -n "/^...totalsize:/ s@.*\(0x[0-9a-f]\+\).*@\1@p") + 0x1000 - 0x1 ) & ~(0x1000 - 0x1) + 0x20 )) )
sed -i "/Blocks = / s@.*@ Blocks = $fit_block_base $fit_block_offset $fit_block_size \"flash.bin\", \\\\@" csf_fit.tmp
# U-Boot
uboot_block_base=$(printf "0x%s" $(fdtget -t x u-boot.itb /images/uboot load))
uboot_block_offset=$(printf "0x%x" $(( $(printf "0x%s" $(fdtget -t x u-boot.itb /images/uboot data-position)) + ${fit_block_offset} )))
uboot_block_size=$(printf "0x%s" $(fdtget -t x u-boot.itb /images/uboot data-size))
sed -i "/0xuuuu/ s@.*@ $uboot_block_base $uboot_block_offset $uboot_block_size \"flash.bin\", \\\\@" csf_fit.tmp
# ATF
atf_block_base=$(printf "0x%s" $(fdtget -t x u-boot.itb /images/atf load))
atf_block_offset=$(printf "0x%x" $(( $(printf "0x%s" $(fdtget -t x u-boot.itb /images/atf data-position)) + ${fit_block_offset} )))
atf_block_size=$(printf "0x%s" $(fdtget -t x u-boot.itb /images/atf data-size))
sed -i "/0xaaaa/ s@.*@ $atf_block_base $atf_block_offset $atf_block_size \"flash.bin\", \\\\@" csf_fit.tmp
# DTB
dtb_block_base=$(printf "0x%x" $(( ${uboot_block_base} + ${uboot_block_size} )))
dtb_block_offset=$(printf "0x%x" $(( $(printf "0x%s" $(fdtget -t x u-boot.itb /images/fdt-1 data-position)) + ${fit_block_offset} )))
dtb_block_size=$(printf "0x%s" $(fdtget -t x u-boot.itb /images/fdt-1 data-size))
sed -i "/0xdddd/ s@.*@ $dtb_block_base $dtb_block_offset $dtb_block_size \"flash.bin\"@" csf_fit.tmp
```
The fitImage part of flash.bin requires separate IVT. Generate the IVT and
patch it into the correct aligned location of flash.bin as follows:
```
# IVT
ivt_ptr_base=$(printf "%08x" ${fit_block_base} | sed "s@\(..\)\(..\)\(..\)\(..\)@0x\4\3\2\1@")
ivt_block_base=$(printf "%08x" $(( ${fit_block_base} + ${fit_block_size} - 0x20 )) | sed "s@\(..\)\(..\)\(..\)\(..\)@0x\4\3\2\1@")
csf_block_base=$(printf "%08x" $(( ${fit_block_base} + ${fit_block_size} )) | sed "s@\(..\)\(..\)\(..\)\(..\)@0x\4\3\2\1@")
ivt_block_offset=$((${fit_block_offset} + ${fit_block_size} - 0x20))
csf_block_offset=$((${ivt_block_offset} + 0x20))
echo "0xd1002041 ${ivt_ptr_base} 0x00000000 0x00000000 0x00000000 ${ivt_block_base} ${csf_block_base} 0x00000000" | xxd -r -p > ivt.bin
dd if=ivt.bin of=flash.bin bs=1 seek=${ivt_block_offset} conv=notrunc
To generate CSF signature for the fitImage part of flash.bin container, use CST:
```
cst -i csf_fit.tmp -o csf_fit.bin
```
Finally, patch the CSF signature into the fitImage right past the IVT:
```
dd if=csf_fit.bin of=flash.bin bs=1 seek=${csf_block_offset} conv=notrunc
```
The entire script is available in doc/imx/habv4/csf_examples/mx8m/csf.sh
1.4 Closing the device
-----------------------
The procedure for closing the device is similar as in Non-SPL targets, for a
complete procedure please refer to section "1.5 Programming SRK Hash" in
mx6_mx7_secure_boot.txt document available under doc/imx/habv4/guides/
directory.
References:
[1] AN4581: "Secure Boot on i.MX 50, i.MX 53, i.MX 6 and i.MX 7 Series using
HABv4" - Rev 2.

View file

@ -124,3 +124,19 @@ config CLK_IMXRT1050
select CLK_COMPOSITE_CCF
help
This enables support clock driver for i.MXRT1050 platforms.
config SPL_CLK_IMXRT1170
bool "SPL clock support for i.MXRT1170"
depends on ARCH_IMXRT && SPL
select SPL_CLK
select SPL_CLK_CCF
help
This enables SPL DM/DTS support for clock driver in i.MXRT1170.
config CLK_IMXRT1170
bool "Clock support for i.MXRT1170"
depends on ARCH_IMXRT
select CLK
select CLK_CCF
help
This enables support clock driver for i.MXRT1170 platforms.

View file

@ -21,3 +21,4 @@ obj-$(CONFIG_$(SPL_TPL_)CLK_IMX8MQ) += clk-imx8mq.o clk-pll14xx.o \
obj-$(CONFIG_$(SPL_TPL_)CLK_IMXRT1020) += clk-imxrt1020.o
obj-$(CONFIG_$(SPL_TPL_)CLK_IMXRT1050) += clk-imxrt1050.o
obj-$(CONFIG_$(SPL_TPL_)CLK_IMXRT1170) += clk-imxrt1170.o

View file

@ -0,0 +1,221 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2022
* Author(s): Jesse Taube <Mr.Bossman075@gmail.com>
*/
#include <common.h>
#include <clk.h>
#include <clk-uclass.h>
#include <dm.h>
#include <log.h>
#include <asm/arch/clock.h>
#include <asm/arch/imx-regs.h>
#include <dt-bindings/clock/imxrt1170-clock.h>
#include "clk.h"
static ulong imxrt1170_clk_get_rate(struct clk *clk)
{
struct clk *c;
int ret;
debug("%s(#%lu)\n", __func__, clk->id);
ret = clk_get_by_id(clk->id, &c);
if (ret)
return ret;
return clk_get_rate(c);
}
static ulong imxrt1170_clk_set_rate(struct clk *clk, ulong rate)
{
struct clk *c;
int ret;
debug("%s(#%lu), rate: %lu\n", __func__, clk->id, rate);
ret = clk_get_by_id(clk->id, &c);
if (ret)
return ret;
return clk_set_rate(c, rate);
}
static int __imxrt1170_clk_enable(struct clk *clk, bool enable)
{
struct clk *c;
int ret;
debug("%s(#%lu) en: %d\n", __func__, clk->id, enable);
ret = clk_get_by_id(clk->id, &c);
if (ret)
return ret;
if (enable)
ret = clk_enable(c);
else
ret = clk_disable(c);
return ret;
}
static int imxrt1170_clk_disable(struct clk *clk)
{
return __imxrt1170_clk_enable(clk, 0);
}
static int imxrt1170_clk_enable(struct clk *clk)
{
return __imxrt1170_clk_enable(clk, 1);
}
static int imxrt1170_clk_set_parent(struct clk *clk, struct clk *parent)
{
struct clk *c, *cp;
int ret;
debug("%s(#%lu), parent: %lu\n", __func__, clk->id, parent->id);
ret = clk_get_by_id(clk->id, &c);
if (ret)
return ret;
ret = clk_get_by_id(parent->id, &cp);
if (ret)
return ret;
return clk_set_parent(c, cp);
}
static struct clk_ops imxrt1170_clk_ops = {
.set_rate = imxrt1170_clk_set_rate,
.get_rate = imxrt1170_clk_get_rate,
.enable = imxrt1170_clk_enable,
.disable = imxrt1170_clk_disable,
.set_parent = imxrt1170_clk_set_parent,
};
static const char * const lpuart1_sels[] = {"rcosc48M_div2", "osc", "rcosc400M", "rcosc16M",
"pll3_div2", "pll1_div5", "pll2_sys", "pll2_pfd3"};
static const char * const gpt1_sels[] = {"rcosc48M_div2", "osc", "rcosc400M", "rcosc16M",
"pll3_div2", "pll1_div5", "pll3_pfd2", "pll3_pfd3"};
static const char * const usdhc1_sels[] = {"rcosc48M_div2", "osc", "rcosc400M", "rcosc16M",
"pll2_pfd2", "pll2_pfd0", "pll1_div5", "pll_arm"};
static const char * const semc_sels[] = {"rcosc48M_div2", "osc", "rcosc400M", "rcosc16M",
"pll1_div5", "pll2_sys", "pll2_pfd2", "pll3_pfd0"};
static int imxrt1170_clk_probe(struct udevice *dev)
{
void *base;
/* Anatop clocks */
base = (void *)ofnode_get_addr(ofnode_by_compatible(ofnode_null(), "fsl,imxrt-anatop"));
clk_dm(IMXRT1170_CLK_RCOSC_48M,
imx_clk_fixed_factor("rcosc48M", "rcosc16M", 3, 1));
clk_dm(IMXRT1170_CLK_RCOSC_400M,
imx_clk_fixed_factor("rcosc400M", "rcosc16M", 25, 1));
clk_dm(IMXRT1170_CLK_RCOSC_48M_DIV2,
imx_clk_fixed_factor("rcosc48M_div2", "rcosc48M", 1, 2));
clk_dm(IMXRT1170_CLK_PLL_ARM,
imx_clk_pllv3(IMX_PLLV3_SYS, "pll_arm", "osc",
base + 0x200, 0xff));
clk_dm(IMXRT1170_CLK_PLL3,
imx_clk_pllv3(IMX_PLLV3_GENERICV2, "pll3_sys", "osc",
base + 0x210, 1));
clk_dm(IMXRT1170_CLK_PLL2,
imx_clk_pllv3(IMX_PLLV3_GENERICV2, "pll2_sys", "osc",
base + 0x240, 1));
clk_dm(IMXRT1170_CLK_PLL3_PFD0,
imx_clk_pfd("pll3_pfd0", "pll3_sys", base + 0x230, 0));
clk_dm(IMXRT1170_CLK_PLL3_PFD1,
imx_clk_pfd("pll3_pfd1", "pll3_sys", base + 0x230, 1));
clk_dm(IMXRT1170_CLK_PLL3_PFD2,
imx_clk_pfd("pll3_pfd2", "pll3_sys", base + 0x230, 2));
clk_dm(IMXRT1170_CLK_PLL3_PFD3,
imx_clk_pfd("pll3_pfd3", "pll3_sys", base + 0x230, 3));
clk_dm(IMXRT1170_CLK_PLL2_PFD0,
imx_clk_pfd("pll2_pfd0", "pll2_sys", base + 0x270, 0));
clk_dm(IMXRT1170_CLK_PLL2_PFD1,
imx_clk_pfd("pll2_pfd1", "pll2_sys", base + 0x270, 1));
clk_dm(IMXRT1170_CLK_PLL2_PFD2,
imx_clk_pfd("pll2_pfd2", "pll2_sys", base + 0x270, 2));
clk_dm(IMXRT1170_CLK_PLL2_PFD3,
imx_clk_pfd("pll2_pfd3", "pll2_sys", base + 0x270, 3));
clk_dm(IMXRT1170_CLK_PLL3_DIV2,
imx_clk_fixed_factor("pll3_div2", "pll3_sys", 1, 2));
/* CCM clocks */
base = dev_read_addr_ptr(dev);
if (base == (void *)FDT_ADDR_T_NONE)
return -EINVAL;
clk_dm(IMXRT1170_CLK_LPUART1_SEL,
imx_clk_mux("lpuart1_sel", base + (25 * 0x80), 8, 3,
lpuart1_sels, ARRAY_SIZE(lpuart1_sels)));
clk_dm(IMXRT1170_CLK_LPUART1,
imx_clk_divider("lpuart1", "lpuart1_sel",
base + (25 * 0x80), 0, 8));
clk_dm(IMXRT1170_CLK_USDHC1_SEL,
imx_clk_mux("usdhc1_sel", base + (58 * 0x80), 8, 3,
usdhc1_sels, ARRAY_SIZE(usdhc1_sels)));
clk_dm(IMXRT1170_CLK_USDHC1,
imx_clk_divider("usdhc1", "usdhc1_sel",
base + (58 * 0x80), 0, 8));
clk_dm(IMXRT1170_CLK_GPT1_SEL,
imx_clk_mux("gpt1_sel", base + (14 * 0x80), 8, 3,
gpt1_sels, ARRAY_SIZE(gpt1_sels)));
clk_dm(IMXRT1170_CLK_GPT1,
imx_clk_divider("gpt1", "gpt1_sel",
base + (14 * 0x80), 0, 8));
clk_dm(IMXRT1170_CLK_SEMC_SEL,
imx_clk_mux("semc_sel", base + (4 * 0x80), 8, 3,
semc_sels, ARRAY_SIZE(semc_sels)));
clk_dm(IMXRT1170_CLK_SEMC,
imx_clk_divider("semc", "semc_sel",
base + (4 * 0x80), 0, 8));
struct clk *clk, *clk1;
clk_get_by_id(IMXRT1170_CLK_PLL2_PFD2, &clk);
clk_get_by_id(IMXRT1170_CLK_SEMC_SEL, &clk1);
clk_enable(clk1);
clk_set_parent(clk1, clk);
clk_get_by_id(IMXRT1170_CLK_SEMC, &clk);
clk_enable(clk);
clk_set_rate(clk, 132000000UL);
clk_get_by_id(IMXRT1170_CLK_GPT1, &clk);
clk_enable(clk);
clk_set_rate(clk, 32000000UL);
return 0;
}
static const struct udevice_id imxrt1170_clk_ids[] = {
{ .compatible = "fsl,imxrt1170-ccm" },
{ },
};
U_BOOT_DRIVER(imxrt1170_clk) = {
.name = "clk_imxrt1170",
.id = UCLASS_CLK,
.of_match = imxrt1170_clk_ids,
.ops = &imxrt1170_clk_ops,
.probe = imxrt1170_clk_probe,
.flags = DM_FLAG_PRE_RELOC,
};

View file

@ -21,19 +21,23 @@
#define UBOOT_DM_CLK_IMX_PLLV3_USB "imx_clk_pllv3_usb"
#define UBOOT_DM_CLK_IMX_PLLV3_AV "imx_clk_pllv3_av"
#define UBOOT_DM_CLK_IMX_PLLV3_ENET "imx_clk_pllv3_enet"
#define UBOOT_DM_CLK_IMX_PLLV3_GENV2 "imx_clk_pllv3_genericv2"
#define PLL_NUM_OFFSET 0x10
#define PLL_DENOM_OFFSET 0x20
#define BM_PLL_POWER (0x1 << 12)
#define BM_PLL_POWER_V2 (0x1 << 21)
#define BM_PLL_ENABLE (0x1 << 13)
#define BM_PLL_LOCK (0x1 << 31)
#define BM_PLL_LOCK_V2 (0x1 << 29)
struct clk_pllv3 {
struct clk clk;
void __iomem *base;
u32 power_bit;
bool powerup_set;
u32 lock_bit;
u32 enable_bit;
u32 div_mask;
u32 div_shift;
@ -42,6 +46,30 @@ struct clk_pllv3 {
#define to_clk_pllv3(_clk) container_of(_clk, struct clk_pllv3, clk)
static ulong clk_pllv3_genericv2_get_rate(struct clk *clk)
{
struct clk_pllv3 *pll = to_clk_pllv3(dev_get_clk_ptr(clk->dev));
unsigned long parent_rate = clk_get_parent_rate(clk);
u32 div = (readl(pll->base) >> pll->div_shift) & pll->div_mask;
return (div == 0) ? parent_rate * 22 : parent_rate * 20;
}
static ulong clk_pllv3_genericv2_set_rate(struct clk *clk, ulong rate)
{
struct clk_pllv3 *pll = to_clk_pllv3(clk);
unsigned long parent_rate = clk_get_parent_rate(clk);
u32 div = (readl(pll->base) >> pll->div_shift) & pll->div_mask;
u32 val = (div == 0) ? parent_rate * 22 : parent_rate * 20;
if (rate == val)
return 0;
return -EINVAL;
}
static ulong clk_pllv3_generic_get_rate(struct clk *clk)
{
struct clk_pllv3 *pll = to_clk_pllv3(dev_get_clk_ptr(clk->dev));
@ -71,7 +99,7 @@ static ulong clk_pllv3_generic_set_rate(struct clk *clk, ulong rate)
writel(val, pll->base);
/* Wait for PLL to lock */
while (!(readl(pll->base) & BM_PLL_LOCK))
while (!(readl(pll->base) & pll->lock_bit))
;
return 0;
@ -120,6 +148,13 @@ static const struct clk_ops clk_pllv3_generic_ops = {
.set_rate = clk_pllv3_generic_set_rate,
};
static const struct clk_ops clk_pllv3_genericv2_ops = {
.get_rate = clk_pllv3_genericv2_get_rate,
.enable = clk_pllv3_generic_enable,
.disable = clk_pllv3_generic_disable,
.set_rate = clk_pllv3_genericv2_set_rate,
};
static ulong clk_pllv3_sys_get_rate(struct clk *clk)
{
struct clk_pllv3 *pll = to_clk_pllv3(clk);
@ -153,7 +188,7 @@ static ulong clk_pllv3_sys_set_rate(struct clk *clk, ulong rate)
writel(val, pll->base);
/* Wait for PLL to lock */
while (!(readl(pll->base) & BM_PLL_LOCK))
while (!(readl(pll->base) & pll->lock_bit))
;
return 0;
@ -221,7 +256,7 @@ static ulong clk_pllv3_av_set_rate(struct clk *clk, ulong rate)
writel(mfd, pll->base + PLL_DENOM_OFFSET);
/* Wait for PLL to lock */
while (!(readl(pll->base) & BM_PLL_LOCK))
while (!(readl(pll->base) & pll->lock_bit))
;
return 0;
@ -262,6 +297,7 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
pll->power_bit = BM_PLL_POWER;
pll->enable_bit = BM_PLL_ENABLE;
pll->lock_bit = BM_PLL_LOCK;
switch (type) {
case IMX_PLLV3_GENERIC:
@ -269,6 +305,13 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
pll->div_shift = 0;
pll->powerup_set = false;
break;
case IMX_PLLV3_GENERICV2:
pll->power_bit = BM_PLL_POWER_V2;
pll->lock_bit = BM_PLL_LOCK_V2;
drv_name = UBOOT_DM_CLK_IMX_PLLV3_GENV2;
pll->div_shift = 0;
pll->powerup_set = false;
break;
case IMX_PLLV3_SYS:
drv_name = UBOOT_DM_CLK_IMX_PLLV3_SYS;
pll->div_shift = 0;
@ -313,6 +356,13 @@ U_BOOT_DRIVER(clk_pllv3_generic) = {
.flags = DM_FLAG_PRE_RELOC,
};
U_BOOT_DRIVER(clk_pllv3_genericv2) = {
.name = UBOOT_DM_CLK_IMX_PLLV3_GENV2,
.id = UCLASS_CLK,
.ops = &clk_pllv3_genericv2_ops,
.flags = DM_FLAG_PRE_RELOC,
};
U_BOOT_DRIVER(clk_pllv3_sys) = {
.name = UBOOT_DM_CLK_IMX_PLLV3_SYS,
.id = UCLASS_CLK,

View file

@ -10,6 +10,7 @@
enum imx_pllv3_type {
IMX_PLLV3_GENERIC,
IMX_PLLV3_GENERICV2,
IMX_PLLV3_SYS,
IMX_PLLV3_USB,
IMX_PLLV3_USB_VF610,

View file

@ -131,25 +131,35 @@ static int caam_hash_update(void *hash_ctx, const void *buf,
static int caam_hash_finish(void *hash_ctx, void *dest_buf,
int size, enum caam_hash_algos caam_algo)
{
uint32_t len = 0;
uint32_t len = 0, sg_entry_len;
struct sha_ctx *ctx = hash_ctx;
int i = 0, ret = 0;
caam_dma_addr_t addr;
if (size < driver_hash[caam_algo].digestsize) {
return -EINVAL;
}
for (i = 0; i < ctx->sg_num; i++)
len += (sec_in32(&ctx->sg_tbl[i].len_flag) &
flush_dcache_range((ulong)ctx->sg_tbl,
(ulong)(ctx->sg_tbl) + (ctx->sg_num * sizeof(struct sg_entry)));
for (i = 0; i < ctx->sg_num; i++) {
sg_entry_len = (sec_in32(&ctx->sg_tbl[i].len_flag) &
SG_ENTRY_LENGTH_MASK);
len += sg_entry_len;
#ifdef CONFIG_CAAM_64BIT
addr = sec_in32(&ctx->sg_tbl[i].addr_hi);
addr = (addr << 32) | sec_in32(&ctx->sg_tbl[i].addr_lo);
#else
addr = sec_in32(&ctx->sg_tbl[i].addr_lo);
#endif
flush_dcache_range(addr, addr + sg_entry_len);
}
inline_cnstr_jobdesc_hash(ctx->sha_desc, (uint8_t *)ctx->sg_tbl, len,
ctx->hash,
driver_hash[caam_algo].alg_type,
driver_hash[caam_algo].digestsize,
1);
flush_dcache_range((ulong)ctx->sg_tbl, (ulong)(ctx->sg_tbl) + len);
flush_dcache_range((ulong)ctx->sha_desc,
(ulong)(ctx->sha_desc) + (sizeof(uint32_t) * MAX_CAAM_DESCSIZE));
flush_dcache_range((ulong)ctx->hash,

View file

@ -1,369 +0,0 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2018 NXP
*/
#include <common.h>
#include <errno.h>
#include <log.h>
#include <asm/io.h>
#include <asm/arch/ddr.h>
#include <asm/arch/clock.h>
#include <asm/arch/ddr.h>
#include <asm/arch/lpddr4_define.h>
#include <asm/arch/sys_proto.h>
static unsigned int g_cdd_rr_max[4];
static unsigned int g_cdd_rw_max[4];
static unsigned int g_cdd_wr_max[4];
static unsigned int g_cdd_ww_max[4];
static inline void poll_pmu_message_ready(void)
{
unsigned int reg;
do {
reg = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0004);
} while (reg & 0x1);
}
static inline void ack_pmu_message_receive(void)
{
unsigned int reg;
reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0031, 0x0);
do {
reg = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0004);
} while (!(reg & 0x1));
reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0031, 0x1);
}
static inline unsigned int get_mail(void)
{
unsigned int reg;
poll_pmu_message_ready();
reg = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0032);
ack_pmu_message_receive();
return reg;
}
static inline unsigned int get_stream_message(void)
{
unsigned int reg, reg2;
poll_pmu_message_ready();
reg = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0032);
reg2 = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + 4 * 0xd0034);
reg2 = (reg2 << 16) | reg;
ack_pmu_message_receive();
return reg2;
}
static inline void decode_major_message(unsigned int mail)
{
debug("[PMU Major message = 0x%08x]\n", mail);
}
static inline void decode_streaming_message(void)
{
unsigned int string_index, arg __maybe_unused;
int i = 0;
string_index = get_stream_message();
debug("PMU String index = 0x%08x\n", string_index);
while (i < (string_index & 0xffff)) {
arg = get_stream_message();
debug("arg[%d] = 0x%08x\n", i, arg);
i++;
}
debug("\n");
}
int wait_ddrphy_training_complete(void)
{
unsigned int mail;
while (1) {
mail = get_mail();
decode_major_message(mail);
if (mail == 0x08) {
decode_streaming_message();
} else if (mail == 0x07) {
debug("Training PASS\n");
return 0;
} else if (mail == 0xff) {
debug("Training FAILED\n");
return -1;
}
}
}
void ddrphy_init_set_dfi_clk(unsigned int drate)
{
switch (drate) {
case 4000:
dram_pll_init(MHZ(1000));
dram_disable_bypass();
break;
case 3732:
dram_pll_init(MHZ(933));
dram_disable_bypass();
break;
case 3200:
dram_pll_init(MHZ(800));
dram_disable_bypass();
break;
case 3000:
dram_pll_init(MHZ(750));
dram_disable_bypass();
break;
case 2400:
dram_pll_init(MHZ(600));
dram_disable_bypass();
break;
case 1600:
dram_pll_init(MHZ(400));
dram_disable_bypass();
break;
case 1066:
dram_pll_init(MHZ(266));
dram_disable_bypass();
break;
case 667:
dram_pll_init(MHZ(167));
dram_disable_bypass();
break;
case 400:
dram_enable_bypass(MHZ(400));
break;
case 100:
dram_enable_bypass(MHZ(100));
break;
default:
return;
}
}
void ddrphy_init_read_msg_block(enum fw_type type)
{
}
void lpddr4_mr_write(unsigned int mr_rank, unsigned int mr_addr,
unsigned int mr_data)
{
unsigned int tmp;
/*
* 1. Poll MRSTAT.mr_wr_busy until it is 0.
* This checks that there is no outstanding MR transaction.
* No writes should be performed to MRCTRL0 and MRCTRL1 if
* MRSTAT.mr_wr_busy = 1.
*/
do {
tmp = reg32_read(DDRC_MRSTAT(0));
} while (tmp & 0x1);
/*
* 2. Write the MRCTRL0.mr_type, MRCTRL0.mr_addr, MRCTRL0.mr_rank and
* (for MRWs) MRCTRL1.mr_data to define the MR transaction.
*/
reg32_write(DDRC_MRCTRL0(0), (mr_rank << 4));
reg32_write(DDRC_MRCTRL1(0), (mr_addr << 8) | mr_data);
reg32setbit(DDRC_MRCTRL0(0), 31);
}
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;
}
unsigned int look_for_max(unsigned int data[],
unsigned int addr_start, unsigned int addr_end)
{
unsigned int i, imax = 0;
for (i = addr_start; i <= addr_end; i++) {
if (((data[i] >> 7) == 0) && (data[i] > imax))
imax = data[i];
}
return imax;
}
void get_trained_CDD(u32 fsp)
{
unsigned int i, ddr_type, tmp;
unsigned int cdd_cha[12], cdd_chb[12];
unsigned int cdd_cha_rr_max, cdd_cha_rw_max, cdd_cha_wr_max, cdd_cha_ww_max;
unsigned int cdd_chb_rr_max, cdd_chb_rw_max, cdd_chb_wr_max, cdd_chb_ww_max;
ddr_type = reg32_read(DDRC_MSTR(0)) & 0x3f;
if (ddr_type == 0x20) {
for (i = 0; i < 6; i++) {
tmp = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + (0x54013 + i) * 4);
cdd_cha[i * 2] = tmp & 0xff;
cdd_cha[i * 2 + 1] = (tmp >> 8) & 0xff;
}
for (i = 0; i < 7; i++) {
tmp = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + (0x5402c + i) * 4);
if (i == 0) {
cdd_cha[0] = (tmp >> 8) & 0xff;
} else if (i == 6) {
cdd_cha[11] = tmp & 0xff;
} else {
cdd_chb[i * 2 - 1] = tmp & 0xff;
cdd_chb[i * 2] = (tmp >> 8) & 0xff;
}
}
cdd_cha_rr_max = look_for_max(cdd_cha, 0, 1);
cdd_cha_rw_max = look_for_max(cdd_cha, 2, 5);
cdd_cha_wr_max = look_for_max(cdd_cha, 6, 9);
cdd_cha_ww_max = look_for_max(cdd_cha, 10, 11);
cdd_chb_rr_max = look_for_max(cdd_chb, 0, 1);
cdd_chb_rw_max = look_for_max(cdd_chb, 2, 5);
cdd_chb_wr_max = look_for_max(cdd_chb, 6, 9);
cdd_chb_ww_max = look_for_max(cdd_chb, 10, 11);
g_cdd_rr_max[fsp] = cdd_cha_rr_max > cdd_chb_rr_max ? cdd_cha_rr_max : cdd_chb_rr_max;
g_cdd_rw_max[fsp] = cdd_cha_rw_max > cdd_chb_rw_max ? cdd_cha_rw_max : cdd_chb_rw_max;
g_cdd_wr_max[fsp] = cdd_cha_wr_max > cdd_chb_wr_max ? cdd_cha_wr_max : cdd_chb_wr_max;
g_cdd_ww_max[fsp] = cdd_cha_ww_max > cdd_chb_ww_max ? cdd_cha_ww_max : cdd_chb_ww_max;
} else {
unsigned int ddr4_cdd[64];
for (i = 0; i < 29; i++) {
tmp = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + (0x54012 + i) * 4);
ddr4_cdd[i * 2] = tmp & 0xff;
ddr4_cdd[i * 2 + 1] = (tmp >> 8) & 0xff;
}
g_cdd_rr_max[fsp] = look_for_max(ddr4_cdd, 1, 12);
g_cdd_ww_max[fsp] = look_for_max(ddr4_cdd, 13, 24);
g_cdd_rw_max[fsp] = look_for_max(ddr4_cdd, 25, 40);
g_cdd_wr_max[fsp] = look_for_max(ddr4_cdd, 41, 56);
}
}
void update_umctl2_rank_space_setting(unsigned int pstat_num)
{
unsigned int i, ddr_type;
unsigned int addr_slot, rdata, tmp, tmp_t;
unsigned int ddrc_w2r, ddrc_r2w, ddrc_wr_gap, ddrc_rd_gap;
ddr_type = reg32_read(DDRC_MSTR(0)) & 0x3f;
for (i = 0; i < pstat_num; i++) {
addr_slot = i ? (i + 1) * 0x1000 : 0;
if (ddr_type == 0x20) {
/* update r2w:[13:8], w2r:[5:0] */
rdata = reg32_read(DDRC_DRAMTMG2(0) + addr_slot);
ddrc_w2r = rdata & 0x3f;
if (is_imx8mp())
tmp = ddrc_w2r + (g_cdd_wr_max[i] >> 1);
else
tmp = ddrc_w2r + (g_cdd_wr_max[i] >> 1) + 1;
ddrc_w2r = (tmp > 0x3f) ? 0x3f : tmp;
ddrc_r2w = (rdata >> 8) & 0x3f;
if (is_imx8mp())
tmp = ddrc_r2w + (g_cdd_rw_max[i] >> 1);
else
tmp = ddrc_r2w + (g_cdd_rw_max[i] >> 1) + 1;
ddrc_r2w = (tmp > 0x3f) ? 0x3f : tmp;
tmp_t = (rdata & 0xffffc0c0) | (ddrc_r2w << 8) | ddrc_w2r;
reg32_write((DDRC_DRAMTMG2(0) + addr_slot), tmp_t);
} else {
/* update w2r:[5:0] */
rdata = reg32_read(DDRC_DRAMTMG9(0) + addr_slot);
ddrc_w2r = rdata & 0x3f;
if (is_imx8mp())
tmp = ddrc_w2r + (g_cdd_wr_max[i] >> 1);
else
tmp = ddrc_w2r + (g_cdd_wr_max[i] >> 1) + 1;
ddrc_w2r = (tmp > 0x3f) ? 0x3f : tmp;
tmp_t = (rdata & 0xffffffc0) | ddrc_w2r;
reg32_write((DDRC_DRAMTMG9(0) + addr_slot), tmp_t);
/* update r2w:[13:8] */
rdata = reg32_read(DDRC_DRAMTMG2(0) + addr_slot);
ddrc_r2w = (rdata >> 8) & 0x3f;
if (is_imx8mp())
tmp = ddrc_r2w + (g_cdd_rw_max[i] >> 1);
else
tmp = ddrc_r2w + (g_cdd_rw_max[i] >> 1) + 1;
ddrc_r2w = (tmp > 0x3f) ? 0x3f : tmp;
tmp_t = (rdata & 0xffffc0ff) | (ddrc_r2w << 8);
reg32_write((DDRC_DRAMTMG2(0) + addr_slot), tmp_t);
}
if (!is_imx8mq()) {
/* update rankctl: wr_gap:11:8; rd:gap:7:4; quasi-dymic, doc wrong(static) */
rdata = reg32_read(DDRC_RANKCTL(0) + addr_slot);
ddrc_wr_gap = (rdata >> 8) & 0xf;
if (is_imx8mp())
tmp = ddrc_wr_gap + (g_cdd_ww_max[i] >> 1);
else
tmp = ddrc_wr_gap + (g_cdd_ww_max[i] >> 1) + 1;
ddrc_wr_gap = (tmp > 0xf) ? 0xf : tmp;
ddrc_rd_gap = (rdata >> 4) & 0xf;
if (is_imx8mp())
tmp = ddrc_rd_gap + (g_cdd_rr_max[i] >> 1);
else
tmp = ddrc_rd_gap + (g_cdd_rr_max[i] >> 1) + 1;
ddrc_rd_gap = (tmp > 0xf) ? 0xf : tmp;
tmp_t = (rdata & 0xfffff00f) | (ddrc_wr_gap << 8) | (ddrc_rd_gap << 4);
reg32_write((DDRC_RANKCTL(0) + addr_slot), tmp_t);
}
}
if (is_imx8mq()) {
/* update rankctl: wr_gap:11:8; rd:gap:7:4; quasi-dymic, doc wrong(static) */
rdata = reg32_read(DDRC_RANKCTL(0));
ddrc_wr_gap = (rdata >> 8) & 0xf;
tmp = ddrc_wr_gap + (g_cdd_ww_max[0] >> 1) + 1;
ddrc_wr_gap = (tmp > 0xf) ? 0xf : tmp;
ddrc_rd_gap = (rdata >> 4) & 0xf;
tmp = ddrc_rd_gap + (g_cdd_rr_max[0] >> 1) + 1;
ddrc_rd_gap = (tmp > 0xf) ? 0xf : tmp;
tmp_t = (rdata & 0xfffff00f) | (ddrc_wr_gap << 8) | (ddrc_rd_gap << 4);
reg32_write(DDRC_RANKCTL(0), tmp_t);
}
}

View file

@ -87,12 +87,21 @@ struct imxrt_semc_regs {
u32 sts[16];
};
#if !defined(TARGET_IMXRT1170_EVK)
#define SEMC_IOCR_MUX_A8_SHIFT 0
#define SEMC_IOCR_MUX_CSX0_SHIFT 3
#define SEMC_IOCR_MUX_CSX1_SHIFT 6
#define SEMC_IOCR_MUX_CSX2_SHIFT 9
#define SEMC_IOCR_MUX_CSX3_SHIFT 12
#define SEMC_IOCR_MUX_RDY_SHIFT 15
#else
#define SEMC_IOCR_MUX_A8_SHIFT 0
#define SEMC_IOCR_MUX_CSX0_SHIFT 4
#define SEMC_IOCR_MUX_CSX1_SHIFT 8
#define SEMC_IOCR_MUX_CSX2_SHIFT 12
#define SEMC_IOCR_MUX_CSX3_SHIFT 16
#define SEMC_IOCR_MUX_RDY_SHIFT 20
#endif
struct imxrt_sdram_mux {
u8 a8;

View file

@ -61,6 +61,11 @@
#define UCR3_AWAKEN (1<<4) /* Async wake interrupt enable */
#define UCR3_REF25 (1<<3) /* Ref freq 25 MHz */
#define UCR3_REF30 (1<<2) /* Ref Freq 30 MHz */
/* imx8 names these bitsfields instead: */
#define UCR3_DTRDEN BIT(3) /* bit not used in this chip */
#define UCR3_RXDMUXSEL BIT(2) /* RXD muxed input selected; 'should always be set' */
#define UCR3_INVT (1<<1) /* Inverted Infrared transmission */
#define UCR3_BPEN (1<<0) /* Preset registers enable */
#define UCR4_CTSTL_32 (32<<10) /* CTS trigger level (32 chars) */
@ -176,6 +181,14 @@ static void _mxc_serial_setbrg(struct mxc_uart *base, unsigned long clk,
writel(UCR2_WS | UCR2_IRTS | UCR2_RXEN | UCR2_TXEN | UCR2_SRST,
&base->cr2);
/*
* setting the baudrate triggers a reset, returning cr3 to its
* reset value but UCR3_RXDMUXSEL "should always be set."
* according to the imx8 reference-manual
*/
writel(readl(&base->cr3) | UCR3_RXDMUXSEL, &base->cr3);
writel(UCR1_UARTEN, &base->cr1);
}
@ -298,7 +311,7 @@ static int mxc_serial_putc(struct udevice *dev, const char ch)
struct mxc_serial_plat *plat = dev_get_plat(dev);
struct mxc_uart *const uart = plat->reg;
if (!(readl(&uart->ts) & UTS_TXEMPTY))
if (readl(&uart->ts) & UTS_TXFULL)
return -EAGAIN;
writel(ch, &uart->txd);

View file

@ -60,7 +60,7 @@
"fdtfile=imx6q-dhcom-pdk2.dtb\0"\
"update_sf=" /* Erase SPI NOR and install U-Boot from SD */ \
"load mmc 0:1 ${loadaddr} /boot/u-boot-with-spl.imx && "\
"sf probe && sf erase 0x0 0xa0000 && " \
"sf probe && sf erase 0x0 0x100000 && " \
"sf write ${loadaddr} 0x400 ${filesize}\0" \
BOOTENV

View file

@ -0,0 +1,78 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2021 Amarula Solutions B.V.
*
*/
#ifndef __IMX6ULZ_SMM_M2_CONFIG_H
#define __IMX6ULZ_SMM_M2_CONFIG_H
#include "mx6_common.h"
#include <asm/arch/imx-regs.h>
#include <linux/sizes.h>
#include <linux/stringify.h>
/* SPL options */
#include "imx6_spl.h"
#define CONFIG_MXC_UART_BASE UART4_BASE
#ifndef CONFIG_SPL_BUILD
#define BOOT_TARGET_DEVICES(func) \
func(NAND, nand, 0) \
#include <config_distro_bootcmd.h>
#endif /* !CONFIG_SPL_BUILD */
#define MEM_LAYOUT_ENV_SETTINGS \
"scriptaddr=" __stringify(CONFIG_SYS_LOAD_ADDR) "\0" \
"kernel_addr_r=" __stringify(CONFIG_SYS_LOAD_ADDR) "\0" \
"fdt_addr_r=0x81000000\0" \
"fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0" \
"bootcmd_mfg=echo Running fastboot mode; fastboot usb 0\0" \
#define NANDARGS \
"mtdids=" CONFIG_MTDIDS_DEFAULT "\0" \
CONFIG_MTDPARTS_DEFAULT "\0" \
"nandargs=setenv bootargs " \
"${optargs} " \
"mtdparts=${mtdparts} " \
"root=${nandroot} " \
"rootfstype=${nandrootfstype}\0" \
"nandroot=ubi0:root rw ubi.mtd=rootfs\0" \
"nandrootfstype=ubifs rootwait=1\0" \
"nandboot=echo Booting from nand ...; " \
"run nandargs; " \
"nand read ${fdt_addr_r} nanddtb; " \
"nand read ${loadaddr} kernel; " \
"bootz ${loadaddr} - ${fdt_addr_r}\0"
#define BOOTENV_DEV_NAND(devtypeu, devtypel, instance) \
"bootcmd_" #devtypel #instance "=" \
"run nandboot\0"
#define BOOTENV_DEV_NAME_NAND(devtypeu, devtypel, instance) \
#devtypel #instance " "
/* Initial environment variables */
#define CONFIG_EXTRA_ENV_SETTINGS \
MEM_LAYOUT_ENV_SETTINGS \
NANDARGS \
BOOTENV
/* Physical Memory Map */
#define PHYS_SDRAM MMDC0_ARB_BASE_ADDR
#define PHYS_SDRAM_SIZE SZ_128M
#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM
#define CONFIG_SYS_INIT_RAM_ADDR IRAM_BASE_ADDR
#define CONFIG_SYS_INIT_RAM_SIZE IRAM_SIZE
/* NAND */
#define CONFIG_SYS_MAX_NAND_DEVICE 1
#define CONFIG_SYS_NAND_BASE 0x20000000
#endif

View file

@ -0,0 +1,29 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2022
* Author(s): Jesse Taube <Mr.Bossman075@gmail.com>
* Giulio Benetti <giulio.benetti@benettiengineering.com>
*/
#ifndef __IMXRT1170_EVK_H
#define __IMXRT1170_EVK_H
#include <asm/arch/imx-regs.h>
#define ESDHCI_QUIRK_BROKEN_TIMEOUT_VALUE 1
/*
* Configuration of the external SDRAM memory
*/
#define PHYS_SDRAM 0x80000000
#define PHYS_SDRAM_SIZE (64 * 1024 * 1024)
#define DMAMEM_SZ_ALL (1 * 1024 * 1024)
#define DMAMEM_BASE (PHYS_SDRAM + PHYS_SDRAM_SIZE - \
DMAMEM_SZ_ALL)
/* For SPL */
#define CONFIG_SYS_UBOOT_START 0x202403FD
/* For SPL ends */
#endif /* __IMXRT1170_EVK_H */

95
include/configs/librem5.h Normal file
View file

@ -0,0 +1,95 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2017 NXP
* Copyright 2018 Emcraft Systems
* Copyright 2022 Purism
*
*/
#ifndef __LIBREM5_H
#define __LIBREM5_H
/* #define DEBUG */
#include <version.h>
#include <linux/sizes.h>
#include <asm/arch/imx-regs.h>
#define CONFIG_SYS_MONITOR_LEN (512 * 1024)
#ifdef CONFIG_SPL_BUILD
#define CONFIG_SPL_ABORT_ON_RAW_IMAGE /* For RAW image gives a error info not panic */
#define CONFIG_POWER_BD71837
#define CONFIG_POWER_BD71837_I2C_BUS 0
#define CONFIG_POWER_BD71837_I2C_ADDR 0x4B
#endif /* CONFIG_SPL_BUILD*/
#define CONFIG_SYS_FSL_USDHC_NUM 2
#define CONFIG_USBD_HS
#define CONSOLE_ON_UART1
#ifdef CONSOLE_ON_UART1
#define CONFIG_MXC_UART_BASE UART1_BASE_ADDR
#define CONSOLE_UART_CLK 0
#define CONSOLE "ttymxc0"
#elif defined(CONSOLE_ON_UART2)
#define CONFIG_MXC_UART_BASE UART2_BASE_ADDR
#define CONSOLE_UART_CLK 1
#define CONSOLE "ttymxc1"
#elif defined(CONSOLE_ON_UART3)
#define CONFIG_MXC_UART_BASE UART3_BASE_ADDR
#define CONSOLE_UART_CLK 2
#define CONSOLE "ttymxc2"
#elif defined(CONSOLE_ON_UART4)
#define CONFIG_MXC_UART_BASE UART4_BASE_ADDR
#define CONSOLE_UART_CLK 3
#define CONSOLE "ttymxc3"
#else
#define CONFIG_MXC_UART_BASE UART1_BASE_ADDR
#define CONSOLE_UART_CLK 0
#define CONSOLE "ttymxc0"
#endif
#ifndef CONFIG_SPL_BUILD
#define BOOT_TARGET_DEVICES(func) \
func(MMC, mmc, 0) \
func(USB, usb, 0) \
func(DHCP, dhcp, na)
#include <config_distro_bootcmd.h>
#else
#define BOOTENV
#endif
/* Initial environment variables */
#define CONFIG_EXTRA_ENV_SETTINGS \
"scriptaddr=0x80000000\0" \
"pxefile_addr_r=0x80100000\0" \
"kernel_addr_r=0x80800000\0" \
"fdt_addr_r=0x84800000\0" \
"ramdisk_addr_r=0x85000000\0" \
"console=" CONSOLE ",115200\0" \
"bootargs=u_boot_version=" PLAIN_VERSION "\0" \
"stdin=usbacm,serial\0" \
"stdout=usbacm,serial\0" \
"stderr=usbacm,serial\0" \
BOOTENV
/* Link Definitions */
#define CONFIG_SYS_INIT_RAM_ADDR 0x40000000
#define CONFIG_SYS_INIT_RAM_SIZE 0x80000
#define CONFIG_SYS_SDRAM_BASE 0x40000000
#define PHYS_SDRAM 0x40000000
#define PHYS_SDRAM_SIZE 0xc0000000 /* 3GB LPDDR4 one Rank */
/* Monitor Command Prompt */
#define CONFIG_SYS_FSL_ESDHC_ADDR 0
#endif

View file

@ -20,10 +20,12 @@
#endif
#define MEM_LAYOUT_ENV_SETTINGS \
"fdt_addr_r=0x44000000\0" \
"kernel_addr_r=0x42000000\0" \
"ramdisk_addr_r=0x46400000\0" \
"scriptaddr=0x46000000\0"
"fdt_addr_r=0x50200000\0" \
"kernel_addr_r=" __stringify(CONFIG_SYS_LOAD_ADDR) "\0" \
"kernel_comp_addr_r=0x40200000\0" \
"kernel_comp_size=0x08080000\0" \
"ramdisk_addr_r=0x50300000\0" \
"scriptaddr=0x50280000\0"
/* Enable Distro Boot */
#define BOOT_TARGET_DEVICES(func) \

View file

@ -34,10 +34,12 @@
#endif /* CONFIG_CMD_NET */
#define MEM_LAYOUT_ENV_SETTINGS \
"fdt_addr_r=0x43000000\0" \
"kernel_addr_r=0x40000000\0" \
"ramdisk_addr_r=0x46400000\0" \
"scriptaddr=0x46000000\0"
"fdt_addr_r=0x50200000\0" \
"kernel_addr_r=" __stringify(CONFIG_SYS_LOAD_ADDR) "\0" \
"kernel_comp_addr_r=0x40200000\0" \
"kernel_comp_size=0x08080000\0" \
"ramdisk_addr_r=0x50300000\0" \
"scriptaddr=0x50280000\0"
/* Enable Distro Boot */
#define BOOT_TARGET_DEVICES(func) \

View file

@ -0,0 +1,48 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2022
* Author(s): Jesse Taube <Mr.Bossman075@gmail.com>
*/
#ifndef __DT_BINDINGS_CLOCK_IMXRT1170_H
#define __DT_BINDINGS_CLOCK_IMXRT1170_H
#define IMXRT1170_CLK_DUMMY 0
#define IMXRT1170_CLK_OSC 1
#define IMXRT1170_CLK_OSC_32K 2
#define IMXRT1170_CLK_RCOSC_16M 3
#define IMXRT1170_CLK_RCOSC_48M 4
#define IMXRT1170_CLK_RCOSC_48M_DIV2 5
#define IMXRT1170_CLK_RCOSC_400M 6
#define IMXRT1170_CLK_PLL_ARM 7
#define IMXRT1170_CLK_PLL_AUDIO 8
#define IMXRT1170_CLK_PLL_VIDEO 9
#define IMXRT1170_CLK_PLL1 10
#define IMXRT1170_CLK_PLL1_DIV2 11
#define IMXRT1170_CLK_PLL1_DIV5 12
#define IMXRT1170_CLK_PLL2 13
#define IMXRT1170_CLK_PLL2_PFD0 14
#define IMXRT1170_CLK_PLL2_PFD1 15
#define IMXRT1170_CLK_PLL2_PFD2 16
#define IMXRT1170_CLK_PLL2_PFD3 17
#define IMXRT1170_CLK_PLL3 18
#define IMXRT1170_CLK_PLL3_DIV2 19
#define IMXRT1170_CLK_PLL3_PFD0 20
#define IMXRT1170_CLK_PLL3_PFD1 21
#define IMXRT1170_CLK_PLL3_PFD2 22
#define IMXRT1170_CLK_PLL3_PFD3 23
#define IMXRT1170_CLK_M7 24
#define IMXRT1170_CLK_M4 25
#define IMXRT1170_CLK_BUS 26
#define IMXRT1170_CLK_BUS_LPSR 27
#define IMXRT1170_CLK_LPUART1_SEL 28
#define IMXRT1170_CLK_LPUART1 29
#define IMXRT1170_CLK_USDHC1_SEL 30
#define IMXRT1170_CLK_USDHC1 31
#define IMXRT1170_CLK_GPT1_SEL 32
#define IMXRT1170_CLK_GPT1 33
#define IMXRT1170_CLK_SEMC_SEL 34
#define IMXRT1170_CLK_SEMC 35
#define IMXRT1170_CLK_END 36
#endif /* __DT_BINDINGS_CLOCK_IMXRT1170_H */

View file

@ -82,6 +82,7 @@
#define MEM_WIDTH_8BITS 0x0
#define MEM_WIDTH_16BITS 0x1
#define MEM_WIDTH_32BITS 0x2
#define BL_1 0x0
#define BL_2 0x1