mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-11 07:34:31 +00:00
i.MX for 2020.07
---------------- - i.MX NAND and nandbxb for i.MX8M - imx8MM : new beacon devkit - imx8MQ : new pico-imx8MQ - imx8QXP : extend to enable M4, fixes - add thermal support - caches in SPL (missing board) - Fixes Travis: https://travis-ci.org/github/sbabic/u-boot-imx/builds/685391011 -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQS2TmnA27QKhpKSZe309WXkmmjvpgUCXrklRA8cc2JhYmljQGRl bnguZGUACgkQ9PVl5Jpo76bO5ACdH8huXVOBT5dHlzJYJcHo1YaLh9sAmwezO44z oNDJdyyEugycwU3zpqyd =e0Zc -----END PGP SIGNATURE----- Merge tag 'u-boot-imx-20200511' of https://gitlab.denx.de/u-boot/custodians/u-boot-imx i.MX for 2020.07 ---------------- - i.MX NAND and nandbxb for i.MX8M - imx8MM : new beacon devkit - imx8MQ : new pico-imx8MQ - imx8QXP : extend to enable M4, fixes - add thermal support - caches in SPL (missing board) - Fixes Travis: https://travis-ci.org/github/sbabic/u-boot-imx/builds/685391011
This commit is contained in:
commit
1bccb23b7b
99 changed files with 14975 additions and 378 deletions
|
@ -76,6 +76,12 @@ config SPL_ARMV8_SEC_FIRMWARE_SUPPORT
|
|||
help
|
||||
Say Y here to support this framework in SPL phase.
|
||||
|
||||
config SPL_RECOVER_DATA_SECTION
|
||||
bool "save/restore SPL data section"
|
||||
help
|
||||
Say Y here to save SPL data section for cold boot, and restore
|
||||
at warm boot in SPL phase.
|
||||
|
||||
config SEC_FIRMWARE_ARMV8_PSCI
|
||||
bool "PSCI implementation in secure monitor firmware"
|
||||
depends on ARMV8_SEC_FIRMWARE_SUPPORT || SPL_ARMV8_SEC_FIRMWARE_SUPPORT
|
||||
|
|
|
@ -30,6 +30,10 @@ obj-$(CONFIG_ARMV8_SPIN_TABLE) += spin_table.o spin_table_v8.o
|
|||
endif
|
||||
obj-$(CONFIG_$(SPL_)ARMV8_SEC_FIRMWARE_SUPPORT) += sec_firmware.o sec_firmware_asm.o
|
||||
|
||||
ifdef CONFIG_SPL_BUILD
|
||||
obj-$(CONFIG_SPL_RECOVER_DATA_SECTION) += spl_data.o
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_FSL_LAYERSCAPE) += fsl-layerscape/
|
||||
obj-$(CONFIG_S32V234) += s32v234/
|
||||
obj-$(CONFIG_TARGET_HIKEY) += hisilicon/
|
||||
|
|
29
arch/arm/cpu/armv8/spl_data.c
Normal file
29
arch/arm/cpu/armv8/spl_data.c
Normal file
|
@ -0,0 +1,29 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2020 NXP
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <spl.h>
|
||||
|
||||
char __data_save_start[0] __section(.__data_save_start);
|
||||
char __data_save_end[0] __section(.__data_save_end);
|
||||
|
||||
u32 cold_reboot_flag = 1;
|
||||
|
||||
void spl_save_restore_data(void)
|
||||
{
|
||||
u32 data_size = __data_save_end - __data_save_start;
|
||||
|
||||
if (cold_reboot_flag == 1) {
|
||||
/* Save data section to data_save section */
|
||||
memcpy(__data_save_start, __data_save_start - data_size,
|
||||
data_size);
|
||||
} else {
|
||||
/* Restore the data_save section to data section */
|
||||
memcpy(__data_save_start - data_size, __data_save_start,
|
||||
data_size);
|
||||
}
|
||||
|
||||
cold_reboot_flag++;
|
||||
}
|
|
@ -38,6 +38,14 @@ SECTIONS
|
|||
*(.data*)
|
||||
} >.sram
|
||||
|
||||
#ifdef CONFIG_SPL_RECOVER_DATA_SECTION
|
||||
.data_save : {
|
||||
*(.__data_save_start)
|
||||
. = SIZEOF(.data);
|
||||
*(.__data_save_end)
|
||||
} >.sram
|
||||
#endif
|
||||
|
||||
.u_boot_list : {
|
||||
. = ALIGN(8);
|
||||
KEEP(*(SORT(.u_boot_list*)));
|
||||
|
|
|
@ -736,8 +736,10 @@ dtb-$(CONFIG_ARCH_IMX8M) += \
|
|||
imx8mm-verdin.dtb \
|
||||
imx8mn-ddr4-evk.dtb \
|
||||
imx8mq-evk.dtb \
|
||||
imx8mm-beacon-kit.dtb \
|
||||
imx8mq-phanbell.dtb \
|
||||
imx8mp-evk.dtb
|
||||
imx8mp-evk.dtb \
|
||||
imx8mq-pico-pi.dtb
|
||||
|
||||
dtb-$(CONFIG_ARCH_IMXRT) += imxrt1050-evk.dtb \
|
||||
imxrt1020-evk.dtb
|
||||
|
|
|
@ -131,7 +131,7 @@
|
|||
|
||||
pd_lsio: PD_LSIO {
|
||||
compatible = "nxp,imx8-pd";
|
||||
reg = <SC_R_LAST>;
|
||||
reg = <SC_R_NONE>;
|
||||
#power-domain-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
@ -180,7 +180,7 @@
|
|||
|
||||
pd_conn: PD_CONN {
|
||||
compatible = "nxp,imx8-pd";
|
||||
reg = <SC_R_LAST>;
|
||||
reg = <SC_R_NONE>;
|
||||
#power-domain-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
@ -214,7 +214,7 @@
|
|||
|
||||
pd_dma: PD_DMA {
|
||||
compatible = "nxp,imx8-pd";
|
||||
reg = <SC_R_LAST>;
|
||||
reg = <SC_R_NONE>;
|
||||
#power-domain-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
|
|
@ -88,7 +88,7 @@
|
|||
|
||||
pd_lsio: PD_LSIO {
|
||||
compatible = "nxp,imx8-pd";
|
||||
reg = <SC_R_LAST>;
|
||||
reg = <SC_R_NONE>;
|
||||
#power-domain-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
@ -137,7 +137,7 @@
|
|||
|
||||
pd_conn: PD_CONN {
|
||||
compatible = "nxp,imx8-pd";
|
||||
reg = <SC_R_LAST>;
|
||||
reg = <SC_R_NONE>;
|
||||
#power-domain-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
@ -173,7 +173,7 @@
|
|||
|
||||
pd_dma: PD_DMA {
|
||||
compatible = "nxp,imx8-pd";
|
||||
reg = <SC_R_LAST>;
|
||||
reg = <SC_R_NONE>;
|
||||
#power-domain-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
|
285
arch/arm/dts/imx8mm-beacon-baseboard.dtsi
Normal file
285
arch/arm/dts/imx8mm-beacon-baseboard.dtsi
Normal file
|
@ -0,0 +1,285 @@
|
|||
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
|
||||
/*
|
||||
* Copyright 2020 Compass Electronics Group, LLC
|
||||
*/
|
||||
|
||||
/ {
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
led0 {
|
||||
label = "gen_led0";
|
||||
gpios = <&pca6416_1 4 GPIO_ACTIVE_HIGH>;
|
||||
default-state = "none";
|
||||
};
|
||||
|
||||
led1 {
|
||||
label = "gen_led1";
|
||||
gpios = <&pca6416_1 5 GPIO_ACTIVE_HIGH>;
|
||||
default-state = "none";
|
||||
};
|
||||
|
||||
led2 {
|
||||
label = "gen_led2";
|
||||
gpios = <&pca6416_1 6 GPIO_ACTIVE_HIGH>;
|
||||
default-state = "none";
|
||||
};
|
||||
|
||||
led3 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_led3>;
|
||||
label = "heartbeat";
|
||||
gpios = <&gpio4 28 GPIO_ACTIVE_HIGH>;
|
||||
linux,default-trigger = "heartbeat";
|
||||
};
|
||||
};
|
||||
|
||||
reg_audio: regulator-audio {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "3v3_aud";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
gpio = <&pca6416_1 11 GPIO_ACTIVE_HIGH>;
|
||||
enable-active-high;
|
||||
};
|
||||
|
||||
reg_usdhc2_vmmc: regulator-usdhc2 {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "VSD_3V3";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>;
|
||||
enable-active-high;
|
||||
};
|
||||
|
||||
sound {
|
||||
compatible = "fsl,imx-audio-wm8962";
|
||||
model = "wm8962-audio";
|
||||
audio-cpu = <&sai3>;
|
||||
audio-codec = <&wm8962>;
|
||||
audio-routing =
|
||||
"Headphone Jack", "HPOUTL",
|
||||
"Headphone Jack", "HPOUTR",
|
||||
"Ext Spk", "SPKOUTL",
|
||||
"Ext Spk", "SPKOUTR",
|
||||
"AMIC", "MICBIAS",
|
||||
"IN3R", "AMIC";
|
||||
};
|
||||
};
|
||||
|
||||
&ecspi2 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_espi2>;
|
||||
cs-gpios = <&gpio5 9 0>;
|
||||
status = "okay";
|
||||
|
||||
eeprom@0 {
|
||||
compatible = "microchip,at25160bn", "atmel,at25";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <5000000>;
|
||||
spi-cpha;
|
||||
spi-cpol;
|
||||
pagesize = <32>;
|
||||
size = <2048>;
|
||||
address-width = <16>;
|
||||
};
|
||||
};
|
||||
|
||||
&i2c2 {
|
||||
clock-frequency = <400000>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_i2c2>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2c4 {
|
||||
clock-frequency = <400000>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_i2c4>;
|
||||
status = "okay";
|
||||
|
||||
wm8962: audio-codec@1a {
|
||||
compatible = "wlf,wm8962";
|
||||
reg = <0x1a>;
|
||||
clocks = <&clk IMX8MM_CLK_SAI3_ROOT>;
|
||||
clock-names = "xclk";
|
||||
DCVDD-supply = <®_audio>;
|
||||
DBVDD-supply = <®_audio>;
|
||||
AVDD-supply = <®_audio>;
|
||||
CPVDD-supply = <®_audio>;
|
||||
MICVDD-supply = <®_audio>;
|
||||
PLLVDD-supply = <®_audio>;
|
||||
SPKVDD1-supply = <®_audio>;
|
||||
SPKVDD2-supply = <®_audio>;
|
||||
gpio-cfg = <
|
||||
0x0000 /* 0:Default */
|
||||
0x0000 /* 1:Default */
|
||||
0x0000 /* 2:FN_DMICCLK */
|
||||
0x0000 /* 3:Default */
|
||||
0x0000 /* 4:FN_DMICCDAT */
|
||||
0x0000 /* 5:Default */
|
||||
>;
|
||||
};
|
||||
|
||||
pca6416_0: gpio@20 {
|
||||
compatible = "nxp,pcal6416";
|
||||
reg = <0x20>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_pcal6414>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
interrupt-parent = <&gpio4>;
|
||||
interrupts = <27 IRQ_TYPE_LEVEL_LOW>;
|
||||
};
|
||||
|
||||
pca6416_1: gpio@21 {
|
||||
compatible = "nxp,pcal6416";
|
||||
reg = <0x21>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
interrupt-parent = <&gpio4>;
|
||||
interrupts = <27 IRQ_TYPE_LEVEL_LOW>;
|
||||
};
|
||||
};
|
||||
|
||||
&sai3 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_sai3>;
|
||||
assigned-clocks = <&clk IMX8MM_CLK_SAI3>;
|
||||
assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
|
||||
assigned-clock-rates = <24576000>;
|
||||
fsl,sai-mclk-direction-output;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&snvs_pwrkey {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&uart2 { /* console */
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_uart2>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&uart3 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_uart3>;
|
||||
assigned-clocks = <&clk IMX8MM_CLK_UART3>;
|
||||
assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_80M>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usdhc2 {
|
||||
pinctrl-names = "default", "state_100mhz", "state_200mhz";
|
||||
pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
|
||||
pinctrl-1 = <&pinctrl_usdhc2_100mhz>;
|
||||
pinctrl-2 = <&pinctrl_usdhc2_200mhz>;
|
||||
bus-width = <4>;
|
||||
vmmc-supply = <®_usdhc2_vmmc>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&iomuxc {
|
||||
pinctrl_espi2: espi2grp {
|
||||
fsl,pins = <
|
||||
MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK 0x82
|
||||
MX8MM_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI 0x82
|
||||
MX8MM_IOMUXC_ECSPI2_MISO_ECSPI2_MISO 0x82
|
||||
MX8MM_IOMUXC_ECSPI1_SS0_GPIO5_IO9 0x41
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_i2c2: i2c2grp {
|
||||
fsl,pins = <
|
||||
MX8MM_IOMUXC_I2C2_SCL_I2C2_SCL 0x400001c3
|
||||
MX8MM_IOMUXC_I2C2_SDA_I2C2_SDA 0x400001c3
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_i2c4: i2c4grp {
|
||||
fsl,pins = <
|
||||
MX8MM_IOMUXC_I2C4_SCL_I2C4_SCL 0x400001c3
|
||||
MX8MM_IOMUXC_I2C4_SDA_I2C4_SDA 0x400001c3
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_led3: led3grp {
|
||||
fsl,pins = <
|
||||
MX8MM_IOMUXC_SAI3_RXFS_GPIO4_IO28 0x41
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_pcal6414: pcal6414-gpio {
|
||||
fsl,pins = <
|
||||
MX8MM_IOMUXC_SAI2_MCLK_GPIO4_IO27 0x19
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_sai3: sai3grp {
|
||||
fsl,pins = <
|
||||
MX8MM_IOMUXC_SAI3_TXFS_SAI3_TX_SYNC 0xd6
|
||||
MX8MM_IOMUXC_SAI3_TXC_SAI3_TX_BCLK 0xd6
|
||||
MX8MM_IOMUXC_SAI3_MCLK_SAI3_MCLK 0xd6
|
||||
MX8MM_IOMUXC_SAI3_TXD_SAI3_TX_DATA0 0xd6
|
||||
MX8MM_IOMUXC_SAI3_RXD_SAI3_RX_DATA0 0xd6
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_uart2: uart2grp {
|
||||
fsl,pins = <
|
||||
MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX 0x140
|
||||
MX8MM_IOMUXC_UART2_TXD_UART2_DCE_TX 0x140
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_uart3: uart3grp {
|
||||
fsl,pins = <
|
||||
MX8MM_IOMUXC_ECSPI1_SCLK_UART3_DCE_RX 0x40
|
||||
MX8MM_IOMUXC_ECSPI1_MOSI_UART3_DCE_TX 0x40
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_usdhc2_gpio: usdhc2grpgpio {
|
||||
fsl,pins = <
|
||||
MX8MM_IOMUXC_SD2_CD_B_USDHC2_CD_B 0x41
|
||||
MX8MM_IOMUXC_SD2_RESET_B_GPIO2_IO19 0x41
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_usdhc2: usdhc2grp {
|
||||
fsl,pins = <
|
||||
MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x190
|
||||
MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d0
|
||||
MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d0
|
||||
MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d0
|
||||
MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d0
|
||||
MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d0
|
||||
MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
|
||||
fsl,pins = <
|
||||
MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x194
|
||||
MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d4
|
||||
MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d4
|
||||
MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d4
|
||||
MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d4
|
||||
MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d4
|
||||
MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
|
||||
fsl,pins = <
|
||||
MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x196
|
||||
MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d6
|
||||
MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d6
|
||||
MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d6
|
||||
MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d6
|
||||
MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d6
|
||||
MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
|
||||
>;
|
||||
};
|
||||
};
|
131
arch/arm/dts/imx8mm-beacon-kit-u-boot.dtsi
Normal file
131
arch/arm/dts/imx8mm-beacon-kit-u-boot.dtsi
Normal file
|
@ -0,0 +1,131 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2020 Compass Electronics Group, LLC
|
||||
*/
|
||||
|
||||
/ {
|
||||
wdt-reboot {
|
||||
compatible = "wdt-reboot";
|
||||
wdt = <&wdog1>;
|
||||
u-boot,dm-spl;
|
||||
};
|
||||
};
|
||||
|
||||
&{/soc@0} {
|
||||
u-boot,dm-pre-reloc;
|
||||
u-boot,dm-spl;
|
||||
};
|
||||
|
||||
&aips1 {
|
||||
u-boot,dm-spl;
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
&aips2 {
|
||||
u-boot,dm-spl;
|
||||
};
|
||||
|
||||
&aips3 {
|
||||
u-boot,dm-spl;
|
||||
};
|
||||
|
||||
&clk {
|
||||
u-boot,dm-spl;
|
||||
u-boot,dm-pre-reloc;
|
||||
/delete-property/ assigned-clocks;
|
||||
/delete-property/ assigned-clock-parents;
|
||||
/delete-property/ assigned-clock-rates;
|
||||
};
|
||||
|
||||
&fec1 {
|
||||
phy-reset-gpios = <&gpio4 22 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
&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;
|
||||
};
|
||||
|
||||
&iomuxc {
|
||||
u-boot,dm-spl;
|
||||
};
|
||||
|
||||
&osc_24m {
|
||||
u-boot,dm-spl;
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
&pca6416_0 {
|
||||
compatible = "ti,tca6416";
|
||||
};
|
||||
|
||||
&pca6416_1 {
|
||||
compatible = "ti,tca6416";
|
||||
};
|
||||
|
||||
&pinctrl_i2c1 {
|
||||
u-boot,dm-spl;
|
||||
};
|
||||
|
||||
&pinctrl_pmic {
|
||||
u-boot,dm-spl;
|
||||
};
|
||||
|
||||
&pinctrl_uart2 {
|
||||
u-boot,dm-spl;
|
||||
};
|
||||
|
||||
&pinctrl_usdhc2_gpio {
|
||||
u-boot,dm-spl;
|
||||
};
|
||||
|
||||
&pinctrl_usdhc2 {
|
||||
u-boot,dm-spl;
|
||||
};
|
||||
|
||||
&pinctrl_usdhc3 {
|
||||
u-boot,dm-spl;
|
||||
};
|
||||
|
||||
&uart2 {
|
||||
u-boot,dm-spl;
|
||||
};
|
||||
|
||||
&usdhc2 {
|
||||
u-boot,dm-spl;
|
||||
};
|
||||
|
||||
&usdhc3 {
|
||||
u-boot,dm-spl;
|
||||
};
|
||||
|
||||
&i2c1 {
|
||||
u-boot,dm-spl;
|
||||
};
|
||||
|
||||
&{/soc@0/bus@30800000/i2c@30a20000/pmic@4b} {
|
||||
u-boot,dm-spl;
|
||||
};
|
||||
|
||||
&{/soc@0/bus@30800000/i2c@30a20000/pmic@4b/regulators} {
|
||||
u-boot,dm-spl;
|
||||
};
|
||||
|
||||
&wdog1 {
|
||||
u-boot,dm-spl;
|
||||
};
|
19
arch/arm/dts/imx8mm-beacon-kit.dts
Normal file
19
arch/arm/dts/imx8mm-beacon-kit.dts
Normal file
|
@ -0,0 +1,19 @@
|
|||
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
|
||||
/*
|
||||
* Copyright 2020 Compass Electronics Group, LLC
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include "imx8mm.dtsi"
|
||||
#include "imx8mm-beacon-som.dtsi"
|
||||
#include "imx8mm-beacon-baseboard.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Beacon EmbeddedWorks i.MX8M Mini Development Kit";
|
||||
compatible = "beacon,imx8mm-beacon-kit", "fsl,imx8mm";
|
||||
|
||||
chosen {
|
||||
stdout-path = &uart2;
|
||||
};
|
||||
};
|
390
arch/arm/dts/imx8mm-beacon-som.dtsi
Normal file
390
arch/arm/dts/imx8mm-beacon-som.dtsi
Normal file
|
@ -0,0 +1,390 @@
|
|||
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
|
||||
/*
|
||||
* Copyright 2020 Compass Electronics Group, LLC
|
||||
*/
|
||||
|
||||
/ {
|
||||
usdhc1_pwrseq: usdhc1_pwrseq {
|
||||
compatible = "mmc-pwrseq-simple";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usdhc1_gpio>;
|
||||
reset-gpios = <&gpio2 10 GPIO_ACTIVE_LOW>;
|
||||
clocks = <&osc_32k>;
|
||||
clock-names = "ext_clock";
|
||||
post-power-on-delay-ms = <80>;
|
||||
};
|
||||
|
||||
memory@40000000 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x40000000 0 0x80000000>;
|
||||
};
|
||||
};
|
||||
|
||||
&A53_0 {
|
||||
cpu-supply = <&buck2_reg>;
|
||||
};
|
||||
|
||||
&fec1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_fec1>;
|
||||
phy-mode = "rgmii-id";
|
||||
phy-handle = <ðphy0>;
|
||||
fsl,magic-packet;
|
||||
status = "okay";
|
||||
|
||||
mdio {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ethphy0: ethernet-phy@0 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&i2c1 {
|
||||
clock-frequency = <400000>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_i2c1>;
|
||||
status = "okay";
|
||||
|
||||
pmic@4b {
|
||||
compatible = "rohm,bd71847";
|
||||
reg = <0x4b>;
|
||||
pinctrl-0 = <&pinctrl_pmic>;
|
||||
interrupt-parent = <&gpio1>;
|
||||
interrupts = <3 GPIO_ACTIVE_LOW>;
|
||||
rohm,reset-snvs-powered;
|
||||
|
||||
regulators {
|
||||
buck1_reg: BUCK1 {
|
||||
regulator-name = "buck1";
|
||||
regulator-min-microvolt = <700000>;
|
||||
regulator-max-microvolt = <1300000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
regulator-ramp-delay = <1250>;
|
||||
};
|
||||
|
||||
buck2_reg: BUCK2 {
|
||||
regulator-name = "buck2";
|
||||
regulator-min-microvolt = <700000>;
|
||||
regulator-max-microvolt = <1300000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
regulator-ramp-delay = <1250>;
|
||||
rohm,dvs-run-voltage = <1000000>;
|
||||
rohm,dvs-idle-voltage = <900000>;
|
||||
};
|
||||
|
||||
buck3_reg: BUCK3 {
|
||||
// BUCK5 in datasheet
|
||||
regulator-name = "buck3";
|
||||
regulator-min-microvolt = <700000>;
|
||||
regulator-max-microvolt = <1350000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
buck4_reg: BUCK4 {
|
||||
// BUCK6 in datasheet
|
||||
regulator-name = "buck4";
|
||||
regulator-min-microvolt = <3000000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
buck5_reg: BUCK5 {
|
||||
// BUCK7 in datasheet
|
||||
regulator-name = "buck5";
|
||||
regulator-min-microvolt = <1605000>;
|
||||
regulator-max-microvolt = <1995000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
buck6_reg: BUCK6 {
|
||||
// BUCK8 in datasheet
|
||||
regulator-name = "buck6";
|
||||
regulator-min-microvolt = <800000>;
|
||||
regulator-max-microvolt = <1400000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
ldo1_reg: LDO1 {
|
||||
regulator-name = "ldo1";
|
||||
regulator-min-microvolt = <3000000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
ldo2_reg: LDO2 {
|
||||
regulator-name = "ldo2";
|
||||
regulator-min-microvolt = <900000>;
|
||||
regulator-max-microvolt = <900000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
ldo3_reg: LDO3 {
|
||||
regulator-name = "ldo3";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
ldo4_reg: LDO4 {
|
||||
regulator-name = "ldo4";
|
||||
regulator-min-microvolt = <900000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
ldo6_reg: LDO6 {
|
||||
regulator-name = "ldo6";
|
||||
regulator-min-microvolt = <900000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&i2c3 {
|
||||
clock-frequency = <400000>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_i2c3>;
|
||||
status = "okay";
|
||||
|
||||
eeprom@50 {
|
||||
compatible = "microchip, at24c64d", "atmel,24c64";
|
||||
pagesize = <32>;
|
||||
read-only; /* Manufacturing EEPROM programmed at factory */
|
||||
reg = <0x50>;
|
||||
};
|
||||
|
||||
rtc@51 {
|
||||
compatible = "nxp,pcf85263";
|
||||
reg = <0x51>;
|
||||
};
|
||||
};
|
||||
|
||||
&uart1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_uart1>;
|
||||
assigned-clocks = <&clk IMX8MM_CLK_UART1>;
|
||||
assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_80M>;
|
||||
uart-has-rtscts;
|
||||
status = "okay";
|
||||
|
||||
bluetooth {
|
||||
compatible = "brcm,bcm43438-bt";
|
||||
shutdown-gpios = <&gpio2 6 GPIO_ACTIVE_HIGH>;
|
||||
host-wakeup-gpios = <&gpio2 8 GPIO_ACTIVE_HIGH>;
|
||||
device-wakeup-gpios = <&gpio2 7 GPIO_ACTIVE_HIGH>;
|
||||
clocks = <&osc_32k>;
|
||||
clock-names = "extclk";
|
||||
};
|
||||
};
|
||||
|
||||
&usdhc1 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usdhc1>;
|
||||
bus-width = <4>;
|
||||
non-removable;
|
||||
cap-power-off-card;
|
||||
pm-ignore-notify;
|
||||
keep-power-in-suspend;
|
||||
mmc-pwrseq = <&usdhc1_pwrseq>;
|
||||
status = "okay";
|
||||
|
||||
brcmf: bcrmf@1 {
|
||||
reg = <1>;
|
||||
compatible = "brcm,bcm4329-fmac";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_wlan>;
|
||||
interrupt-parent = <&gpio2>;
|
||||
interrupts = <9 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "host-wake";
|
||||
};
|
||||
};
|
||||
|
||||
&usdhc3 {
|
||||
pinctrl-names = "default", "state_100mhz", "state_200mhz";
|
||||
pinctrl-0 = <&pinctrl_usdhc3>;
|
||||
pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
|
||||
pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
|
||||
bus-width = <8>;
|
||||
non-removable;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&wdog1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_wdog>;
|
||||
fsl,ext-reset-output;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&iomuxc {
|
||||
pinctrl_fec1: fec1grp {
|
||||
fsl,pins = <
|
||||
MX8MM_IOMUXC_ENET_MDC_ENET1_MDC 0x3
|
||||
MX8MM_IOMUXC_ENET_MDIO_ENET1_MDIO 0x3
|
||||
MX8MM_IOMUXC_ENET_TD3_ENET1_RGMII_TD3 0x1f
|
||||
MX8MM_IOMUXC_ENET_TD2_ENET1_RGMII_TD2 0x1f
|
||||
MX8MM_IOMUXC_ENET_TD1_ENET1_RGMII_TD1 0x1f
|
||||
MX8MM_IOMUXC_ENET_TD0_ENET1_RGMII_TD0 0x1f
|
||||
MX8MM_IOMUXC_ENET_RD3_ENET1_RGMII_RD3 0x91
|
||||
MX8MM_IOMUXC_ENET_RD2_ENET1_RGMII_RD2 0x91
|
||||
MX8MM_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x91
|
||||
MX8MM_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x91
|
||||
MX8MM_IOMUXC_ENET_TXC_ENET1_RGMII_TXC 0x1f
|
||||
MX8MM_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x91
|
||||
MX8MM_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91
|
||||
MX8MM_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f
|
||||
MX8MM_IOMUXC_SAI2_RXC_GPIO4_IO22 0x19
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_i2c1: i2c1grp {
|
||||
fsl,pins = <
|
||||
MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x400001c3
|
||||
MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x400001c3
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_i2c3: i2c3grp {
|
||||
fsl,pins = <
|
||||
MX8MM_IOMUXC_I2C3_SCL_I2C3_SCL 0x400001c3
|
||||
MX8MM_IOMUXC_I2C3_SDA_I2C3_SDA 0x400001c3
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_pmic: pmicirq {
|
||||
fsl,pins = <
|
||||
MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x41
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_uart1: uart1grp {
|
||||
fsl,pins = <
|
||||
MX8MM_IOMUXC_UART1_RXD_UART1_DCE_RX 0x140
|
||||
MX8MM_IOMUXC_UART1_TXD_UART1_DCE_TX 0x140
|
||||
MX8MM_IOMUXC_UART3_RXD_UART1_DCE_CTS_B 0x140
|
||||
MX8MM_IOMUXC_UART3_TXD_UART1_DCE_RTS_B 0x140
|
||||
MX8MM_IOMUXC_SD1_DATA4_GPIO2_IO6 0x19
|
||||
MX8MM_IOMUXC_SD1_DATA5_GPIO2_IO7 0x19
|
||||
MX8MM_IOMUXC_SD1_DATA6_GPIO2_IO8 0x19
|
||||
MX8MM_IOMUXC_GPIO1_IO00_ANAMIX_REF_CLK_32K 0x141
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_usdhc1_gpio: usdhc1grpgpio {
|
||||
fsl,pins = <
|
||||
MX8MM_IOMUXC_SD1_RESET_B_GPIO2_IO10 0x41
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_usdhc1: usdhc1grp {
|
||||
fsl,pins = <
|
||||
MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x190
|
||||
MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d0
|
||||
MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d0
|
||||
MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d0
|
||||
MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d0
|
||||
MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d0
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
|
||||
fsl,pins = <
|
||||
MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x194
|
||||
MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d4
|
||||
MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d4
|
||||
MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d4
|
||||
MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d4
|
||||
MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d4
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
|
||||
fsl,pins = <
|
||||
MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x196
|
||||
MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d6
|
||||
MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d6
|
||||
MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d6
|
||||
MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d6
|
||||
MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d6
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_usdhc3: usdhc3grp {
|
||||
fsl,pins = <
|
||||
MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x190
|
||||
MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d0
|
||||
MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d0
|
||||
MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d0
|
||||
MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d0
|
||||
MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d0
|
||||
MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x1d0
|
||||
MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x1d0
|
||||
MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x1d0
|
||||
MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7 0x1d0
|
||||
MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x190
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_usdhc3_100mhz: usdhc3grp100mhz {
|
||||
fsl,pins = <
|
||||
MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x194
|
||||
MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d4
|
||||
MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d4
|
||||
MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d4
|
||||
MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d4
|
||||
MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d4
|
||||
MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x1d4
|
||||
MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x1d4
|
||||
MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x1d4
|
||||
MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7 0x1d4
|
||||
MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x194
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_usdhc3_200mhz: usdhc3grp200mhz {
|
||||
fsl,pins = <
|
||||
MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x196
|
||||
MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d6
|
||||
MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d6
|
||||
MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d6
|
||||
MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d6
|
||||
MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d6
|
||||
MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x1d6
|
||||
MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x1d6
|
||||
MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x1d6
|
||||
MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7 0x1d6
|
||||
MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x196
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_wdog: wdoggrp {
|
||||
fsl,pins = <
|
||||
MX8MM_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0xc6
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_wlan: wlangrp {
|
||||
fsl,pins = <
|
||||
MX8MM_IOMUXC_SD1_DATA7_GPIO2_IO9 0x111
|
||||
>;
|
||||
};
|
||||
};
|
420
arch/arm/dts/imx8mq-pico-pi.dts
Normal file
420
arch/arm/dts/imx8mq-pico-pi.dts
Normal file
|
@ -0,0 +1,420 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2018 Wandboard, Org.
|
||||
* Copyright 2017 NXP
|
||||
*
|
||||
* Author: Richard Hu <hakahu@gmail.com>
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include "imx8mq.dtsi"
|
||||
|
||||
/ {
|
||||
model = "TechNexion PICO-PI-8M";
|
||||
compatible = "technexion,pico-pi-imx8m", "fsl,imx8mq";
|
||||
|
||||
chosen {
|
||||
stdout-path = &uart1;
|
||||
};
|
||||
|
||||
pmic_osc: clock-pmic {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <32768>;
|
||||
clock-output-names = "pmic_osc";
|
||||
};
|
||||
|
||||
reg_usb_otg_vbus: regulator-usb-otg-vbus {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_otg_vbus>;
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "usb_otg_vbus";
|
||||
regulator-min-microvolt = <5000000>;
|
||||
regulator-max-microvolt = <5000000>;
|
||||
gpio = <&gpio3 14 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
reg_eth_phy: eth_phy {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "eth_phy_pwr";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
gpio = <&gpio1 0 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
|
||||
&fec1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_fec1>;
|
||||
phy-mode = "rgmii-id";
|
||||
phy-handle = <ðphy0>;
|
||||
phy-supply = <®_eth_phy>;
|
||||
phy-reset-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
|
||||
phy-reset-duration = <100>;
|
||||
phy-reset-post-delay = <100>;
|
||||
fsl,magic-packet;
|
||||
status = "okay";
|
||||
|
||||
mdio {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ethphy0: ethernet-phy@1 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&i2c1 {
|
||||
clock-frequency = <100000>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_i2c1>;
|
||||
status = "okay";
|
||||
|
||||
pmic: pmic@4b {
|
||||
reg = <0x4b>;
|
||||
compatible = "rohm,bd71837";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_pmic>;
|
||||
clocks = <&pmic_osc>;
|
||||
clock-names = "osc";
|
||||
clock-output-names = "pmic_clk";
|
||||
interrupt-parent = <&gpio1>;
|
||||
interrupts = <3 GPIO_ACTIVE_LOW>;
|
||||
interrupt-names = "irq";
|
||||
|
||||
regulators {
|
||||
buck1: BUCK1 {
|
||||
regulator-name = "buck1";
|
||||
regulator-min-microvolt = <700000>;
|
||||
regulator-max-microvolt = <1300000>;
|
||||
regulator-boot-on;
|
||||
regulator-ramp-delay = <1250>;
|
||||
rohm,dvs-run-voltage = <900000>;
|
||||
rohm,dvs-idle-voltage = <850000>;
|
||||
rohm,dvs-suspend-voltage = <800000>;
|
||||
};
|
||||
|
||||
buck2: BUCK2 {
|
||||
regulator-name = "buck2";
|
||||
regulator-min-microvolt = <700000>;
|
||||
regulator-max-microvolt = <1300000>;
|
||||
regulator-boot-on;
|
||||
regulator-ramp-delay = <1250>;
|
||||
rohm,dvs-run-voltage = <1000000>;
|
||||
rohm,dvs-idle-voltage = <900000>;
|
||||
};
|
||||
|
||||
buck3: BUCK3 {
|
||||
regulator-name = "buck3";
|
||||
regulator-min-microvolt = <700000>;
|
||||
regulator-max-microvolt = <1300000>;
|
||||
regulator-boot-on;
|
||||
rohm,dvs-run-voltage = <1000000>;
|
||||
};
|
||||
|
||||
buck4: BUCK4 {
|
||||
regulator-name = "buck4";
|
||||
regulator-min-microvolt = <700000>;
|
||||
regulator-max-microvolt = <1300000>;
|
||||
regulator-boot-on;
|
||||
rohm,dvs-run-voltage = <1000000>;
|
||||
};
|
||||
|
||||
buck5: BUCK5 {
|
||||
regulator-name = "buck5";
|
||||
regulator-min-microvolt = <700000>;
|
||||
regulator-max-microvolt = <1350000>;
|
||||
regulator-boot-on;
|
||||
};
|
||||
|
||||
buck6: BUCK6 {
|
||||
regulator-name = "buck6";
|
||||
regulator-min-microvolt = <3000000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-boot-on;
|
||||
};
|
||||
|
||||
buck7: BUCK7 {
|
||||
regulator-name = "buck7";
|
||||
regulator-min-microvolt = <1605000>;
|
||||
regulator-max-microvolt = <1995000>;
|
||||
regulator-boot-on;
|
||||
};
|
||||
|
||||
buck8: BUCK8 {
|
||||
regulator-name = "buck8";
|
||||
regulator-min-microvolt = <800000>;
|
||||
regulator-max-microvolt = <1400000>;
|
||||
regulator-boot-on;
|
||||
};
|
||||
|
||||
ldo1: LDO1 {
|
||||
regulator-name = "ldo1";
|
||||
regulator-min-microvolt = <3000000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
ldo2: LDO2 {
|
||||
regulator-name = "ldo2";
|
||||
regulator-min-microvolt = <900000>;
|
||||
regulator-max-microvolt = <900000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
ldo3: LDO3 {
|
||||
regulator-name = "ldo3";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-boot-on;
|
||||
};
|
||||
|
||||
ldo4: LDO4 {
|
||||
regulator-name = "ldo4";
|
||||
regulator-min-microvolt = <900000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
regulator-boot-on;
|
||||
};
|
||||
|
||||
ldo5: LDO5 {
|
||||
regulator-name = "ldo5";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-boot-on;
|
||||
};
|
||||
|
||||
ldo6: LDO6 {
|
||||
regulator-name = "ldo6";
|
||||
regulator-min-microvolt = <900000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
regulator-boot-on;
|
||||
};
|
||||
|
||||
ldo7: LDO7 {
|
||||
regulator-name = "ldo7";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-boot-on;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&i2c2 {
|
||||
clock-frequency = <100000>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_i2c2>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&uart1 { /* console */
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_uart1>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usdhc1 {
|
||||
pinctrl-names = "default", "state_100mhz", "state_200mhz";
|
||||
pinctrl-0 = <&pinctrl_usdhc1>;
|
||||
pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
|
||||
pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
|
||||
bus-width = <8>;
|
||||
non-removable;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usdhc2 {
|
||||
pinctrl-names = "default", "state_100mhz", "state_200mhz";
|
||||
pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
|
||||
pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
|
||||
pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
|
||||
bus-width = <4>;
|
||||
cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usb3_phy0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usb3_phy1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usb_dwc3_1 {
|
||||
dr_mode = "host";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&wdog1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_wdog>;
|
||||
fsl,ext-reset-output;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&iomuxc {
|
||||
pinctrl_fec1: fec1grp {
|
||||
fsl,pins = <
|
||||
MX8MQ_IOMUXC_ENET_MDC_ENET1_MDC 0x3
|
||||
MX8MQ_IOMUXC_ENET_MDIO_ENET1_MDIO 0x23
|
||||
MX8MQ_IOMUXC_ENET_TD3_ENET1_RGMII_TD3 0x1f
|
||||
MX8MQ_IOMUXC_ENET_TD2_ENET1_RGMII_TD2 0x1f
|
||||
MX8MQ_IOMUXC_ENET_TD1_ENET1_RGMII_TD1 0x1f
|
||||
MX8MQ_IOMUXC_ENET_TD0_ENET1_RGMII_TD0 0x1f
|
||||
MX8MQ_IOMUXC_ENET_RD3_ENET1_RGMII_RD3 0x91
|
||||
MX8MQ_IOMUXC_ENET_RD2_ENET1_RGMII_RD2 0x91
|
||||
MX8MQ_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x91
|
||||
MX8MQ_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x91
|
||||
MX8MQ_IOMUXC_ENET_TXC_ENET1_RGMII_TXC 0x1f
|
||||
MX8MQ_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x91
|
||||
MX8MQ_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91
|
||||
MX8MQ_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f
|
||||
MX8MQ_IOMUXC_GPIO1_IO00_GPIO1_IO0 0x19
|
||||
MX8MQ_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x19
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_i2c1: i2c1grp {
|
||||
fsl,pins = <
|
||||
MX8MQ_IOMUXC_I2C1_SCL_I2C1_SCL 0x4000007f
|
||||
MX8MQ_IOMUXC_I2C1_SDA_I2C1_SDA 0x4000007f
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_i2c2: i2c2grp {
|
||||
fsl,pins = <
|
||||
MX8MQ_IOMUXC_I2C2_SCL_I2C2_SCL 0x4000007f
|
||||
MX8MQ_IOMUXC_I2C2_SDA_I2C2_SDA 0x4000007f
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_otg_vbus: otgvbusgrp {
|
||||
fsl,pins = <
|
||||
MX8MQ_IOMUXC_NAND_DQS_GPIO3_IO14 0x19 /* USB OTG VBUS Enable */
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_pmic: pmicirq {
|
||||
fsl,pins = <
|
||||
MX8MQ_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x41
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_uart1: uart1grp {
|
||||
fsl,pins = <
|
||||
MX8MQ_IOMUXC_UART1_RXD_UART1_DCE_RX 0x49
|
||||
MX8MQ_IOMUXC_UART1_TXD_UART1_DCE_TX 0x49
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_uart2: uart2grp {
|
||||
fsl,pins = <
|
||||
MX8MQ_IOMUXC_UART2_RXD_UART2_DCE_RX 0x49
|
||||
MX8MQ_IOMUXC_UART2_TXD_UART2_DCE_TX 0x49
|
||||
MX8MQ_IOMUXC_UART4_RXD_UART2_DCE_CTS_B 0x49
|
||||
MX8MQ_IOMUXC_UART4_TXD_UART2_DCE_RTS_B 0x49
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_usdhc1: usdhc1grp {
|
||||
fsl,pins = <
|
||||
MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x83
|
||||
MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xc3
|
||||
MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xc3
|
||||
MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xc3
|
||||
MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xc3
|
||||
MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xc3
|
||||
MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xc3
|
||||
MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xc3
|
||||
MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xc3
|
||||
MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xc3
|
||||
MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x83
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
|
||||
fsl,pins = <
|
||||
MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x85
|
||||
MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xc5
|
||||
MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xc5
|
||||
MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xc5
|
||||
MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xc5
|
||||
MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xc5
|
||||
MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xc5
|
||||
MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xc5
|
||||
MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xc5
|
||||
MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xc5
|
||||
MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x85
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
|
||||
fsl,pins = <
|
||||
MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x87
|
||||
MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xc7
|
||||
MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xc7
|
||||
MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xc7
|
||||
MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xc7
|
||||
MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xc7
|
||||
MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xc7
|
||||
MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xc7
|
||||
MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xc7
|
||||
MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xc7
|
||||
MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x87
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_usdhc2_gpio: usdhc2grpgpio {
|
||||
fsl,pins = <
|
||||
MX8MQ_IOMUXC_SD2_CD_B_GPIO2_IO12 0x41
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_usdhc2: usdhc2grp {
|
||||
fsl,pins = <
|
||||
MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x83
|
||||
MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xc3
|
||||
MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xc3
|
||||
MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xc3
|
||||
MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xc3
|
||||
MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xc3
|
||||
MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xc1
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
|
||||
fsl,pins = <
|
||||
MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x85
|
||||
MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xc5
|
||||
MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xc5
|
||||
MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xc5
|
||||
MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xc5
|
||||
MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xc5
|
||||
MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xc1
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
|
||||
fsl,pins = <
|
||||
MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x87
|
||||
MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xc7
|
||||
MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xc7
|
||||
MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xc7
|
||||
MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xc7
|
||||
MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xc7
|
||||
MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xc1
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_wdog: wdoggrp {
|
||||
fsl,pins = <
|
||||
MX8MQ_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0xc6
|
||||
>;
|
||||
};
|
||||
};
|
|
@ -64,6 +64,7 @@
|
|||
|
||||
#define CHIP_REV_A 0x0
|
||||
#define CHIP_REV_B 0x1
|
||||
#define CHIP_REV_C 0x2
|
||||
|
||||
#define BOARD_REV_1_0 0x0
|
||||
#define BOARD_REV_2_0 0x1
|
||||
|
|
|
@ -5,6 +5,11 @@
|
|||
|
||||
#include <asm/arch/sci/sci.h>
|
||||
#include <asm/mach-imx/sys_proto.h>
|
||||
#include <asm/arch/power-domain.h>
|
||||
#include <dm/platdata.h>
|
||||
#include <dm/device-internal.h>
|
||||
#include <dm/device.h>
|
||||
#include <power-domain.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
struct pass_over_info_t {
|
||||
|
@ -21,3 +26,7 @@ void build_info(void);
|
|||
enum boot_device get_boot_device(void);
|
||||
int print_bootinfo(void);
|
||||
int sc_pm_setup_uart(sc_rsrc_t uart_rsrc, sc_pm_clock_rate_t clk_rate);
|
||||
int imx8_power_domain_lookup_name(const char *name,
|
||||
struct power_domain *power_domain);
|
||||
void imx8_power_off_pd_devices(const char *permanent_on_devices[], int size);
|
||||
bool m4_parts_booted(void);
|
||||
|
|
|
@ -137,6 +137,40 @@ struct fuse_bank1_regs {
|
|||
u32 rsvd3[3];
|
||||
};
|
||||
|
||||
struct fuse_bank3_regs {
|
||||
u32 mem_trim0;
|
||||
u32 rsvd0[3];
|
||||
u32 mem_trim1;
|
||||
u32 rsvd1[3];
|
||||
u32 mem_trim2;
|
||||
u32 rsvd2[3];
|
||||
u32 ana0;
|
||||
u32 rsvd3[3];
|
||||
};
|
||||
|
||||
struct fuse_bank9_regs {
|
||||
u32 mac_addr0;
|
||||
u32 rsvd0[3];
|
||||
u32 mac_addr1;
|
||||
u32 rsvd1[11];
|
||||
};
|
||||
|
||||
struct fuse_bank38_regs {
|
||||
u32 ana_trim1; /* trim0 is at 0xD70, bank 37*/
|
||||
u32 rsvd0[3];
|
||||
u32 ana_trim2;
|
||||
u32 rsvd1[3];
|
||||
u32 ana_trim3;
|
||||
u32 rsvd2[3];
|
||||
u32 ana_trim4;
|
||||
u32 rsvd3[3];
|
||||
};
|
||||
|
||||
struct fuse_bank39_regs {
|
||||
u32 ana_trim5;
|
||||
u32 rsvd[15];
|
||||
};
|
||||
|
||||
#ifdef CONFIG_IMX8MQ
|
||||
struct anamix_pll {
|
||||
u32 audio_pll1_cfg0;
|
||||
|
@ -227,13 +261,6 @@ struct anamix_pll {
|
|||
};
|
||||
#endif
|
||||
|
||||
struct fuse_bank9_regs {
|
||||
u32 mac_addr0;
|
||||
u32 rsvd0[3];
|
||||
u32 mac_addr1;
|
||||
u32 rsvd1[11];
|
||||
};
|
||||
|
||||
/* System Reset Controller (SRC) */
|
||||
struct src {
|
||||
u32 scr;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Based on code from LTIB:
|
||||
* Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
* Copyright 2020 NXP
|
||||
*/
|
||||
|
||||
#ifndef __DMA_H__
|
||||
|
@ -53,7 +54,7 @@ enum {
|
|||
MXS_DMA_CHANNEL_AHB_APBH_RESERVED1,
|
||||
MXS_MAX_DMA_CHANNELS,
|
||||
};
|
||||
#elif defined(CONFIG_MX6) || defined(CONFIG_MX7)
|
||||
#else
|
||||
enum {
|
||||
MXS_DMA_CHANNEL_AHB_APBH_GPMI0 = 0,
|
||||
MXS_DMA_CHANNEL_AHB_APBH_GPMI1,
|
||||
|
@ -95,13 +96,13 @@ enum {
|
|||
#define MXS_DMA_DESC_BYTES_OFFSET 16
|
||||
|
||||
struct mxs_dma_cmd {
|
||||
unsigned long next;
|
||||
unsigned long data;
|
||||
u32 next;
|
||||
u32 data;
|
||||
union {
|
||||
dma_addr_t address;
|
||||
unsigned long alternate;
|
||||
u32 address;
|
||||
u32 alternate;
|
||||
};
|
||||
unsigned long pio_words[DMA_PIO_WORDS];
|
||||
u32 pio_words[DMA_PIO_WORDS];
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -117,7 +118,7 @@ struct mxs_dma_cmd {
|
|||
struct mxs_dma_desc {
|
||||
struct mxs_dma_cmd cmd;
|
||||
unsigned int flags;
|
||||
dma_addr_t address;
|
||||
u32 address;
|
||||
void *buffer;
|
||||
struct list_head node;
|
||||
} __aligned(MXS_DMA_ALIGNMENT);
|
||||
|
|
|
@ -9,9 +9,11 @@
|
|||
|
||||
#define FCB_FINGERPRINT 0x20424346 /* 'FCB' */
|
||||
#define FCB_VERSION_1 0x01000000
|
||||
#define FCB_FINGERPRINT_OFF 0x4 /* FCB fingerprint offset*/
|
||||
|
||||
#define DBBT_FINGERPRINT2 0x54424244 /* 'DBBT' */
|
||||
#define DBBT_FINGERPRINT 0x54424244 /* 'DBBT' */
|
||||
#define DBBT_VERSION_1 0x01000000
|
||||
#define DBBT_FINGERPRINT_OFF 0x4 /* DBBT fingerprint offset*/
|
||||
|
||||
struct dbbt_block {
|
||||
u32 checksum; /* reserved on i.MX6 */
|
||||
|
|
127
arch/arm/include/asm/mach-imx/module_fuse.h
Normal file
127
arch/arm/include/asm/mach-imx/module_fuse.h
Normal file
|
@ -0,0 +1,127 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2019 NXP
|
||||
*/
|
||||
|
||||
#ifndef __MODULE_FUSE_H__
|
||||
#define __MODULE_FUSE_H__
|
||||
|
||||
enum fuse_module_type {
|
||||
MODULE_TSC,
|
||||
MODULE_ADC1,
|
||||
MODULE_ADC2,
|
||||
MODULE_SIM1,
|
||||
MODULE_SIM2,
|
||||
MODULE_FLEXCAN1,
|
||||
MODULE_FLEXCAN2,
|
||||
MODULE_SPDIF,
|
||||
MODULE_EIM,
|
||||
MODULE_SD1,
|
||||
MODULE_SD2,
|
||||
MODULE_SD3,
|
||||
MODULE_SD4,
|
||||
MODULE_QSPI1,
|
||||
MODULE_QSPI2,
|
||||
MODULE_GPMI,
|
||||
MODULE_APBHDMA,
|
||||
MODULE_LCDIF,
|
||||
MODULE_PXP,
|
||||
MODULE_CSI,
|
||||
MODULE_ENET1,
|
||||
MODULE_ENET2,
|
||||
MODULE_CAAM,
|
||||
MODULE_USB_OTG1,
|
||||
MODULE_USB_OTG2,
|
||||
MODULE_SAI2,
|
||||
MODULE_SAI3,
|
||||
MODULE_BEE,
|
||||
MODULE_UART1,
|
||||
MODULE_UART2,
|
||||
MODULE_UART3,
|
||||
MODULE_UART4,
|
||||
MODULE_UART5,
|
||||
MODULE_UART6,
|
||||
MODULE_UART7,
|
||||
MODULE_UART8,
|
||||
MODULE_PWM5,
|
||||
MODULE_PWM6,
|
||||
MODULE_PWM7,
|
||||
MODULE_PWM8,
|
||||
MODULE_ECSPI1,
|
||||
MODULE_ECSPI2,
|
||||
MODULE_ECSPI3,
|
||||
MODULE_ECSPI4,
|
||||
MODULE_ECSPI5,
|
||||
MODULE_I2C1,
|
||||
MODULE_I2C2,
|
||||
MODULE_I2C3,
|
||||
MODULE_I2C4,
|
||||
MODULE_GPT1,
|
||||
MODULE_GPT2,
|
||||
MODULE_EPIT1,
|
||||
MODULE_EPIT2,
|
||||
MODULE_EPDC,
|
||||
MODULE_ESAI,
|
||||
MODULE_DCP,
|
||||
MODULE_DCP_CRYPTO,
|
||||
};
|
||||
|
||||
struct fuse_entry_desc {
|
||||
enum fuse_module_type module;
|
||||
const char *node_path;
|
||||
u32 fuse_word_offset;
|
||||
u32 fuse_bit_offset;
|
||||
u32 status;
|
||||
};
|
||||
|
||||
#if !CONFIG_IS_ENABLED(IMX_MODULE_FUSE)
|
||||
static inline u32 check_module_fused(enum fuse_module_type module)
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
|
||||
static inline u32 esdhc_fused(ulong base_addr)
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
|
||||
static inline u32 ecspi_fused(ulong base_addr)
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
|
||||
static inline u32 uart_fused(ulong base_addr)
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
|
||||
static inline u32 usb_fused(ulong base_addr)
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
|
||||
static inline u32 qspi_fused(ulong base_addr)
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
|
||||
static inline u32 i2c_fused(ulong base_addr)
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
|
||||
static inline u32 enet_fused(ulong base_addr)
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
#else
|
||||
u32 check_module_fused(enum fuse_module_type module);
|
||||
u32 esdhc_fused(ulong base_addr);
|
||||
u32 ecspi_fused(ulong base_addr);
|
||||
u32 uart_fused(ulong base_addr);
|
||||
u32 usb_fused(ulong base_addr);
|
||||
u32 qspi_fused(ulong base_addr);
|
||||
u32 i2c_fused(ulong base_addr);
|
||||
u32 enet_fused(ulong base_addr);
|
||||
#endif
|
||||
#endif /* __MODULE_FUSE_H__ */
|
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Based on code from LTIB:
|
||||
* Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
* Copyright 2020 NXP
|
||||
*/
|
||||
|
||||
#ifndef __REGS_APBH_H__
|
||||
|
@ -95,7 +96,7 @@ struct mxs_apbh_regs {
|
|||
mxs_reg_32(hw_apbh_version)
|
||||
};
|
||||
|
||||
#elif (defined(CONFIG_MX28) || defined(CONFIG_MX6) || defined(CONFIG_MX7))
|
||||
#else
|
||||
struct mxs_apbh_regs {
|
||||
mxs_reg_32(hw_apbh_ctrl0)
|
||||
mxs_reg_32(hw_apbh_ctrl1)
|
||||
|
@ -274,7 +275,7 @@ struct mxs_apbh_regs {
|
|||
#define APBH_CTRL0_CLKGATE_CHANNEL_NAND7 0x0800
|
||||
#define APBH_CTRL0_CLKGATE_CHANNEL_HSADC 0x1000
|
||||
#define APBH_CTRL0_CLKGATE_CHANNEL_LCDIF 0x2000
|
||||
#elif (defined(CONFIG_MX6) || defined(CONFIG_MX7))
|
||||
#elif (defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8) || defined(CONFIG_IMX8M))
|
||||
#define APBH_CTRL0_CLKGATE_CHANNEL_OFFSET 0
|
||||
#define APBH_CTRL0_CLKGATE_CHANNEL_NAND0 0x0001
|
||||
#define APBH_CTRL0_CLKGATE_CHANNEL_NAND1 0x0002
|
||||
|
@ -357,7 +358,6 @@ struct mxs_apbh_regs {
|
|||
|
||||
#if defined(CONFIG_MX28)
|
||||
#define APBH_CHANNEL_CTRL_RESET_CHANNEL_MASK (0xffff << 16)
|
||||
#define APBH_CHANNEL_CTRL_RESET_CHANNEL_OFFSET 16
|
||||
#define APBH_CHANNEL_CTRL_RESET_CHANNEL_SSP0 (0x0001 << 16)
|
||||
#define APBH_CHANNEL_CTRL_RESET_CHANNEL_SSP1 (0x0002 << 16)
|
||||
#define APBH_CHANNEL_CTRL_RESET_CHANNEL_SSP2 (0x0004 << 16)
|
||||
|
@ -390,9 +390,8 @@ struct mxs_apbh_regs {
|
|||
#define APBH_CHANNEL_CTRL_FREEZE_CHANNEL_LCDIF 0x2000
|
||||
#endif
|
||||
|
||||
#if (defined(CONFIG_MX6) || defined(CONFIG_MX7))
|
||||
/* Not on i.MX23 */
|
||||
#define APBH_CHANNEL_CTRL_RESET_CHANNEL_OFFSET 16
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MX23)
|
||||
#define APBH_DEVSEL_CH7_MASK (0xf << 28)
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
* on behalf of DENX Software Engineering GmbH
|
||||
*
|
||||
* Based on code from LTIB:
|
||||
* Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
* Copyright 2008-2010, 2016 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
* Copyright 2020 NXP
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MX28_REGS_BCH_H__
|
||||
|
@ -40,6 +42,7 @@ struct mxs_bch_regs {
|
|||
mxs_reg_32(hw_bch_dbgahbmread)
|
||||
mxs_reg_32(hw_bch_blockname)
|
||||
mxs_reg_32(hw_bch_version)
|
||||
mxs_reg_32(hw_bch_debug1)
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -75,6 +78,9 @@ struct mxs_bch_regs {
|
|||
|
||||
#define BCH_MODE_ERASE_THRESHOLD_MASK 0xff
|
||||
#define BCH_MODE_ERASE_THRESHOLD_OFFSET 0
|
||||
#define BCH_MODE_ERASE_THRESHOLD(v) \
|
||||
(((v) << BCH_MODE_ERASE_THRESHOLD_OFFSET) & \
|
||||
BCH_MODE_ERASE_THRESHOLD_MASK)
|
||||
|
||||
#define BCH_ENCODEPTR_ADDR_MASK 0xffffffff
|
||||
#define BCH_ENCODEPTR_ADDR_OFFSET 0
|
||||
|
@ -122,7 +128,7 @@ struct mxs_bch_regs {
|
|||
#define BCH_FLASHLAYOUT0_NBLOCKS_OFFSET 24
|
||||
#define BCH_FLASHLAYOUT0_META_SIZE_MASK (0xff << 16)
|
||||
#define BCH_FLASHLAYOUT0_META_SIZE_OFFSET 16
|
||||
#if (defined(CONFIG_MX6) || defined(CONFIG_MX7))
|
||||
#if (defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8) || defined(CONFIG_IMX8M))
|
||||
#define BCH_FLASHLAYOUT0_ECC0_MASK (0x1f << 11)
|
||||
#define BCH_FLASHLAYOUT0_ECC0_OFFSET 11
|
||||
#else
|
||||
|
@ -146,14 +152,14 @@ struct mxs_bch_regs {
|
|||
#define BCH_FLASHLAYOUT0_ECC0_ECC28 (0xe << 12)
|
||||
#define BCH_FLASHLAYOUT0_ECC0_ECC30 (0xf << 12)
|
||||
#define BCH_FLASHLAYOUT0_ECC0_ECC32 (0x10 << 12)
|
||||
#define BCH_FLASHLAYOUT0_GF13_0_GF14_1 (1 << 10)
|
||||
#define BCH_FLASHLAYOUT0_GF13_0_GF14_1_MASK BIT(10)
|
||||
#define BCH_FLASHLAYOUT0_GF13_0_GF14_1_OFFSET 10
|
||||
#define BCH_FLASHLAYOUT0_DATA0_SIZE_MASK 0xfff
|
||||
#define BCH_FLASHLAYOUT0_DATA0_SIZE_MASK 0x3ff
|
||||
#define BCH_FLASHLAYOUT0_DATA0_SIZE_OFFSET 0
|
||||
|
||||
#define BCH_FLASHLAYOUT1_PAGE_SIZE_MASK (0xffff << 16)
|
||||
#define BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET 16
|
||||
#if (defined(CONFIG_MX6) || defined(CONFIG_MX7))
|
||||
#if (defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8) || defined(CONFIG_IMX8M))
|
||||
#define BCH_FLASHLAYOUT1_ECCN_MASK (0x1f << 11)
|
||||
#define BCH_FLASHLAYOUT1_ECCN_OFFSET 11
|
||||
#else
|
||||
|
@ -177,9 +183,9 @@ struct mxs_bch_regs {
|
|||
#define BCH_FLASHLAYOUT1_ECCN_ECC28 (0xe << 12)
|
||||
#define BCH_FLASHLAYOUT1_ECCN_ECC30 (0xf << 12)
|
||||
#define BCH_FLASHLAYOUT1_ECCN_ECC32 (0x10 << 12)
|
||||
#define BCH_FLASHLAYOUT1_GF13_0_GF14_1 (1 << 10)
|
||||
#define BCH_FLASHLAYOUT1_GF13_0_GF14_1_MASK BIT(10)
|
||||
#define BCH_FLASHLAYOUT1_GF13_0_GF14_1_OFFSET 10
|
||||
#define BCH_FLASHLAYOUT1_DATAN_SIZE_MASK 0xfff
|
||||
#define BCH_FLASHLAYOUT1_DATAN_SIZE_MASK 0x3ff
|
||||
#define BCH_FLASHLAYOUT1_DATAN_SIZE_OFFSET 0
|
||||
|
||||
#define BCH_DEBUG0_RSVD1_MASK (0x1f << 27)
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <asm/io.h>
|
||||
#include <asm/mach-imx/regs-common.h>
|
||||
#include <asm/mach-imx/module_fuse.h>
|
||||
#include <common.h>
|
||||
#include "../arch-imx/cpu.h"
|
||||
|
||||
|
@ -197,4 +198,6 @@ unsigned long call_imx_sip(unsigned long id, unsigned long reg0,
|
|||
unsigned long call_imx_sip_ret2(unsigned long id, unsigned long reg0,
|
||||
unsigned long *reg1, unsigned long reg2,
|
||||
unsigned long reg3);
|
||||
|
||||
void imx_get_mac_from_fuse(int dev_id, unsigned char *mac);
|
||||
#endif
|
||||
|
|
|
@ -27,6 +27,13 @@ config IMX_BOOTAUX
|
|||
help
|
||||
bootaux [addr] to boot auxiliary core.
|
||||
|
||||
config IMX_MODULE_FUSE
|
||||
bool "i.MX Module Fuse"
|
||||
depends on ARCH_MX6
|
||||
help
|
||||
i.MX module fuse to runtime disable some driver, including
|
||||
Linux OS device node.
|
||||
|
||||
config USE_IMXIMG_PLUGIN
|
||||
bool "Use imximage plugin code"
|
||||
depends on ARCH_MX7 || ARCH_MX6 || ARCH_MX7ULP
|
||||
|
@ -82,7 +89,7 @@ config CMD_NANDBCB
|
|||
bool "i.MX6 NAND Boot Control Block(BCB) command"
|
||||
depends on MTD_RAW_NAND && CMD_MTDPARTS
|
||||
select BCH if MX6UL || MX6ULL
|
||||
default y if (ARCH_MX6 && NAND_MXS) || (ARCH_MX7 && NAND_MXS)
|
||||
default y if ((ARCH_MX6 || ARCH_MX7 || ARCH_IMX8M) && NAND_MXS)
|
||||
help
|
||||
Unlike normal 'nand write/erase' commands, this command update
|
||||
Boot Control Block(BCB) for i.MX6 platform NAND IP's.
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -168,7 +168,7 @@ int print_cpuinfo(void)
|
|||
|
||||
cpurev = get_cpu_rev();
|
||||
|
||||
#if defined(CONFIG_IMX_THERMAL)
|
||||
#if defined(CONFIG_IMX_THERMAL) || defined(CONFIG_IMX_TMU)
|
||||
struct udevice *thermal_dev;
|
||||
int cpu_tmp, minc, maxc, ret;
|
||||
|
||||
|
@ -191,7 +191,7 @@ int print_cpuinfo(void)
|
|||
mxc_get_clock(MXC_ARM_CLK) / 1000000);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_IMX_THERMAL)
|
||||
#if defined(CONFIG_IMX_THERMAL) || defined(CONFIG_IMX_TMU)
|
||||
puts("CPU: ");
|
||||
switch (get_cpu_temp_grade(&minc, &maxc)) {
|
||||
case TEMP_AUTOMOTIVE:
|
||||
|
|
|
@ -18,11 +18,13 @@ config MU_BASE_SPL
|
|||
config IMX8QM
|
||||
select IMX8
|
||||
select SUPPORT_SPL
|
||||
select SPL_RECOVER_DATA_SECTION
|
||||
bool
|
||||
|
||||
config IMX8QXP
|
||||
select IMX8
|
||||
select SUPPORT_SPL
|
||||
select SPL_RECOVER_DATA_SECTION
|
||||
bool
|
||||
|
||||
config SYS_SOC
|
||||
|
@ -41,6 +43,14 @@ config IMX_CONTAINER_CFG
|
|||
This is to specific the cfg file for generating container
|
||||
image which will be loaded by SPL.
|
||||
|
||||
config BOOTAUX_RESERVED_MEM_BASE
|
||||
hex "i.MX auxiliary core dram memory base"
|
||||
default 0
|
||||
|
||||
config BOOTAUX_RESERVED_MEM_SIZE
|
||||
hex "i.MX auxiliary core dram memory size"
|
||||
default 0
|
||||
|
||||
choice
|
||||
prompt "i.MX8 board select"
|
||||
optional
|
||||
|
|
|
@ -13,13 +13,16 @@
|
|||
#include <dm/lists.h>
|
||||
#include <dm/uclass.h>
|
||||
#include <errno.h>
|
||||
#include <spl.h>
|
||||
#include <thermal.h>
|
||||
#include <asm/arch/sci/sci.h>
|
||||
#include <asm/arch/sys_proto.h>
|
||||
#include <asm/arch-imx/cpu.h>
|
||||
#include <asm/armv8/cpu.h>
|
||||
#include <asm/armv8/mmu.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/mach-imx/boot_mode.h>
|
||||
#include <spl.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
|
@ -38,6 +41,10 @@ struct pass_over_info_t *get_pass_over_info(void)
|
|||
|
||||
int arch_cpu_init(void)
|
||||
{
|
||||
#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_RECOVER_DATA_SECTION)
|
||||
spl_save_restore_data();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
struct pass_over_info_t *pass_over;
|
||||
|
||||
|
@ -162,6 +169,37 @@ enum boot_device get_boot_device(void)
|
|||
return boot_dev;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SERIAL_TAG
|
||||
#define FUSE_UNIQUE_ID_WORD0 16
|
||||
#define FUSE_UNIQUE_ID_WORD1 17
|
||||
void get_board_serial(struct tag_serialnr *serialnr)
|
||||
{
|
||||
sc_err_t err;
|
||||
u32 val1 = 0, val2 = 0;
|
||||
u32 word1, word2;
|
||||
|
||||
if (!serialnr)
|
||||
return;
|
||||
|
||||
word1 = FUSE_UNIQUE_ID_WORD0;
|
||||
word2 = FUSE_UNIQUE_ID_WORD1;
|
||||
|
||||
err = sc_misc_otp_fuse_read(-1, word1, &val1);
|
||||
if (err != SC_ERR_NONE) {
|
||||
printf("%s fuse %d read error: %d\n", __func__, word1, err);
|
||||
return;
|
||||
}
|
||||
|
||||
err = sc_misc_otp_fuse_read(-1, word2, &val2);
|
||||
if (err != SC_ERR_NONE) {
|
||||
printf("%s fuse %d read error: %d\n", __func__, word2, err);
|
||||
return;
|
||||
}
|
||||
serialnr->low = val1;
|
||||
serialnr->high = val2;
|
||||
}
|
||||
#endif /*CONFIG_SERIAL_TAG*/
|
||||
|
||||
#ifdef CONFIG_ENV_IS_IN_MMC
|
||||
__weak int board_mmc_get_env_dev(int devno)
|
||||
{
|
||||
|
@ -223,7 +261,7 @@ static int get_owned_memreg(sc_rm_mr_t mr, sc_faddr_t *addr_start,
|
|||
phys_size_t get_effective_memsize(void)
|
||||
{
|
||||
sc_rm_mr_t mr;
|
||||
sc_faddr_t start, end, end1;
|
||||
sc_faddr_t start, end, end1, start_aligned;
|
||||
int err;
|
||||
|
||||
end1 = (sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE;
|
||||
|
@ -231,9 +269,9 @@ phys_size_t get_effective_memsize(void)
|
|||
for (mr = 0; mr < 64; mr++) {
|
||||
err = get_owned_memreg(mr, &start, &end);
|
||||
if (!err) {
|
||||
start = roundup(start, MEMSTART_ALIGNMENT);
|
||||
start_aligned = roundup(start, MEMSTART_ALIGNMENT);
|
||||
/* Too small memory region, not use it */
|
||||
if (start > end)
|
||||
if (start_aligned > end)
|
||||
continue;
|
||||
|
||||
/* Find the memory region runs the U-Boot */
|
||||
|
@ -537,3 +575,43 @@ u32 get_cpu_rev(void)
|
|||
return (id << 12) | rev;
|
||||
}
|
||||
|
||||
void board_boot_order(u32 *spl_boot_list)
|
||||
{
|
||||
spl_boot_list[0] = spl_boot_device();
|
||||
|
||||
if (spl_boot_list[0] == BOOT_DEVICE_SPI) {
|
||||
/* Check whether we own the flexspi0, if not, use NOR boot */
|
||||
if (!sc_rm_is_resource_owned(-1, SC_R_FSPI_0))
|
||||
spl_boot_list[0] = BOOT_DEVICE_NOR;
|
||||
}
|
||||
}
|
||||
|
||||
bool m4_parts_booted(void)
|
||||
{
|
||||
sc_rm_pt_t m4_parts[2];
|
||||
int err;
|
||||
|
||||
err = sc_rm_get_resource_owner(-1, SC_R_M4_0_PID0, &m4_parts[0]);
|
||||
if (err) {
|
||||
printf("%s get resource [%d] owner error: %d\n", __func__,
|
||||
SC_R_M4_0_PID0, err);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sc_pm_is_partition_started(-1, m4_parts[0]))
|
||||
return true;
|
||||
|
||||
if (is_imx8qm()) {
|
||||
err = sc_rm_get_resource_owner(-1, SC_R_M4_1_PID0, &m4_parts[1]);
|
||||
if (err) {
|
||||
printf("%s get resource [%d] owner error: %d\n",
|
||||
__func__, SC_R_M4_1_PID0, err);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sc_pm_is_partition_started(-1, m4_parts[1]))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <asm/arch/sys_proto.h>
|
||||
#include <dm/ofnode.h>
|
||||
#include <fdt_support.h>
|
||||
#include <linux/libfdt.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
|
@ -105,13 +106,13 @@ static int config_smmu_resource_sid(int rsrc, int sid)
|
|||
{
|
||||
int err;
|
||||
|
||||
if (!check_owned_resource(rsrc)) {
|
||||
printf("%s rsrc[%d] not owned\n", __func__, rsrc);
|
||||
return -1;
|
||||
}
|
||||
err = sc_rm_set_master_sid(-1, rsrc, sid);
|
||||
debug("set_master_sid rsrc=%d sid=0x%x err=%d\n", rsrc, sid, err);
|
||||
if (err != SC_ERR_NONE) {
|
||||
if (!check_owned_resource(rsrc)) {
|
||||
printf("%s rsrc[%d] not owned\n", __func__, rsrc);
|
||||
return -1;
|
||||
}
|
||||
pr_err("fail set_master_sid rsrc=%d sid=0x%x err=%d\n", rsrc, sid, err);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -279,6 +280,15 @@ static int ft_add_optee_node(void *fdt, bd_t *bd)
|
|||
int ft_system_setup(void *blob, bd_t *bd)
|
||||
{
|
||||
int ret;
|
||||
int off;
|
||||
|
||||
if (CONFIG_BOOTAUX_RESERVED_MEM_BASE) {
|
||||
off = fdt_add_mem_rsv(blob, CONFIG_BOOTAUX_RESERVED_MEM_BASE,
|
||||
CONFIG_BOOTAUX_RESERVED_MEM_SIZE);
|
||||
if (off < 0)
|
||||
printf("Failed to reserve memory for bootaux: %s\n",
|
||||
fdt_strerror(off));
|
||||
}
|
||||
|
||||
update_fdt_with_owned_resources(blob);
|
||||
|
||||
|
|
|
@ -55,12 +55,23 @@ config TARGET_IMX8MP_EVK
|
|||
select SUPPORT_SPL
|
||||
select IMX8M_LPDDR4
|
||||
|
||||
config TARGET_PICO_IMX8MQ
|
||||
bool "Support Technexion Pico iMX8MQ"
|
||||
select IMX8MQ
|
||||
select IMX8M_LPDDR4
|
||||
|
||||
config TARGET_VERDIN_IMX8MM
|
||||
bool "Support Toradex Verdin iMX8M Mini module"
|
||||
select IMX8MM
|
||||
select SUPPORT_SPL
|
||||
select IMX8M_LPDDR4
|
||||
|
||||
config TARGET_IMX8MM_BEACON
|
||||
bool "imx8mm Beacon Embedded devkit"
|
||||
select IMX8MM
|
||||
select SUPPORT_SPL
|
||||
select IMX8M_LPDDR4
|
||||
|
||||
endchoice
|
||||
|
||||
source "board/freescale/imx8mq_evk/Kconfig"
|
||||
|
@ -68,6 +79,8 @@ source "board/freescale/imx8mm_evk/Kconfig"
|
|||
source "board/freescale/imx8mn_evk/Kconfig"
|
||||
source "board/freescale/imx8mp_evk/Kconfig"
|
||||
source "board/google/imx8mq_phanbell/Kconfig"
|
||||
source "board/technexion/pico-imx8mq/Kconfig"
|
||||
source "board/toradex/verdin-imx8mm/Kconfig"
|
||||
source "board/beacon/imx8mm/Kconfig"
|
||||
|
||||
endif
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2017 NXP
|
||||
* Copyright 2017-2019 NXP
|
||||
*
|
||||
* Peng Fan <peng.fan@nxp.com>
|
||||
*/
|
||||
|
@ -448,3 +448,76 @@ int arch_misc_init(void)
|
|||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void imx_tmu_arch_init(void *reg_base)
|
||||
{
|
||||
if (is_imx8mm() || is_imx8mn()) {
|
||||
/* Load TCALIV and TASR from fuses */
|
||||
struct ocotp_regs *ocotp =
|
||||
(struct ocotp_regs *)OCOTP_BASE_ADDR;
|
||||
struct fuse_bank *bank = &ocotp->bank[3];
|
||||
struct fuse_bank3_regs *fuse =
|
||||
(struct fuse_bank3_regs *)bank->fuse_regs;
|
||||
|
||||
u32 tca_rt, tca_hr, tca_en;
|
||||
u32 buf_vref, buf_slope;
|
||||
|
||||
tca_rt = fuse->ana0 & 0xFF;
|
||||
tca_hr = (fuse->ana0 & 0xFF00) >> 8;
|
||||
tca_en = (fuse->ana0 & 0x2000000) >> 25;
|
||||
|
||||
buf_vref = (fuse->ana0 & 0x1F00000) >> 20;
|
||||
buf_slope = (fuse->ana0 & 0xF0000) >> 16;
|
||||
|
||||
writel(buf_vref | (buf_slope << 16), (ulong)reg_base + 0x28);
|
||||
writel((tca_en << 31) | (tca_hr << 16) | tca_rt,
|
||||
(ulong)reg_base + 0x30);
|
||||
}
|
||||
#ifdef CONFIG_IMX8MP
|
||||
/* Load TCALIV0/1/m40 and TRIM from fuses */
|
||||
struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
|
||||
struct fuse_bank *bank = &ocotp->bank[38];
|
||||
struct fuse_bank38_regs *fuse =
|
||||
(struct fuse_bank38_regs *)bank->fuse_regs;
|
||||
struct fuse_bank *bank2 = &ocotp->bank[39];
|
||||
struct fuse_bank39_regs *fuse2 =
|
||||
(struct fuse_bank39_regs *)bank2->fuse_regs;
|
||||
u32 buf_vref, buf_slope, bjt_cur, vlsb, bgr;
|
||||
u32 reg;
|
||||
u32 tca40[2], tca25[2], tca105[2];
|
||||
|
||||
/* For blank sample */
|
||||
if (!fuse->ana_trim2 && !fuse->ana_trim3 &&
|
||||
!fuse->ana_trim4 && !fuse2->ana_trim5) {
|
||||
/* Use a default 25C binary codes */
|
||||
tca25[0] = 1596;
|
||||
tca25[1] = 1596;
|
||||
writel(tca25[0], (ulong)reg_base + 0x30);
|
||||
writel(tca25[1], (ulong)reg_base + 0x34);
|
||||
return;
|
||||
}
|
||||
|
||||
buf_vref = (fuse->ana_trim2 & 0xc0) >> 6;
|
||||
buf_slope = (fuse->ana_trim2 & 0xF00) >> 8;
|
||||
bjt_cur = (fuse->ana_trim2 & 0xF000) >> 12;
|
||||
bgr = (fuse->ana_trim2 & 0xF0000) >> 16;
|
||||
vlsb = (fuse->ana_trim2 & 0xF00000) >> 20;
|
||||
writel(buf_vref | (buf_slope << 16), (ulong)reg_base + 0x28);
|
||||
|
||||
reg = (bgr << 28) | (bjt_cur << 20) | (vlsb << 12) | (1 << 7);
|
||||
writel(reg, (ulong)reg_base + 0x3c);
|
||||
|
||||
tca40[0] = (fuse->ana_trim3 & 0xFFF0000) >> 16;
|
||||
tca25[0] = (fuse->ana_trim3 & 0xF0000000) >> 28;
|
||||
tca25[0] |= ((fuse->ana_trim4 & 0xFF) << 4);
|
||||
tca105[0] = (fuse->ana_trim4 & 0xFFF00) >> 8;
|
||||
tca40[1] = (fuse->ana_trim4 & 0xFFF00000) >> 20;
|
||||
tca25[1] = fuse2->ana_trim5 & 0xFFF;
|
||||
tca105[1] = (fuse2->ana_trim5 & 0xFFF000) >> 12;
|
||||
|
||||
/* use 25c for 1p calibration */
|
||||
writel(tca25[0] | (tca105[0] << 16), (ulong)reg_base + 0x30);
|
||||
writel(tca25[1] | (tca105[1] << 16), (ulong)reg_base + 0x34);
|
||||
writel(tca40[0] | (tca40[1] << 16), (ulong)reg_base + 0x38);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
# (C) Copyright 2011 Freescale Semiconductor, Inc.
|
||||
|
||||
obj-y := soc.o clock.o
|
||||
obj-$(CONFIG_IMX_MODULE_FUSE) += module_fuse.o
|
||||
obj-$(CONFIG_SPL_BUILD) += ddr.o
|
||||
obj-$(CONFIG_MP) += mp.o
|
||||
obj-$(CONFIG_MX6UL_LITESOM) += litesom.o
|
||||
|
|
322
arch/arm/mach-imx/mx6/module_fuse.c
Normal file
322
arch/arm/mach-imx/mx6/module_fuse.c
Normal file
|
@ -0,0 +1,322 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2019 NXP
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <fdt_support.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/sys_proto.h>
|
||||
#include <asm/arch/imx-regs.h>
|
||||
#include <asm/mach-imx/module_fuse.h>
|
||||
#include <linux/errno.h>
|
||||
|
||||
static struct fuse_entry_desc mx6_fuse_descs[] = {
|
||||
#if defined(CONFIG_MX6ULL)
|
||||
{MODULE_TSC, "/soc/aips-bus@2000000/tsc@2040000", 0x430, 22},
|
||||
{MODULE_ADC2, "/soc/aips-bus@2100000/adc@219c000", 0x430, 23},
|
||||
{MODULE_EPDC, "/soc/aips-bus@2200000/epdc@228c000", 0x430, 24},
|
||||
{MODULE_ESAI, "/soc/aips-bus@2000000/spba-bus@2000000/esai@2024000", 0x430, 25},
|
||||
{MODULE_FLEXCAN1, "/soc/aips-bus@2000000/can@2090000", 0x430, 26},
|
||||
{MODULE_FLEXCAN2, "/soc/aips-bus@2000000/can@2094000", 0x430, 27},
|
||||
{MODULE_SPDIF, "/soc/aips-bus@2000000/spba-bus@2000000/spdif@2004000", 0x440, 2},
|
||||
{MODULE_EIM, "/soc/aips-bus@2100000/weim@21b8000", 0x440, 3},
|
||||
{MODULE_SD1, "/soc/aips-bus@2100000/usdhc@2190000", 0x440, 4},
|
||||
{MODULE_SD2, "/soc/aips-bus@2100000/usdhc@2194000", 0x440, 5},
|
||||
{MODULE_QSPI1, "/soc/aips-bus@2100000/qspi@21e0000", 0x440, 6},
|
||||
{MODULE_GPMI, "/soc/gpmi-nand@1806000", 0x440, 7},
|
||||
{MODULE_APBHDMA, "/soc/dma-apbh@1804000", 0x440, 7},
|
||||
{MODULE_LCDIF, "/soc/aips-bus@2100000/lcdif@21c8000", 0x440, 8},
|
||||
{MODULE_PXP, "/soc/aips-bus@2100000/pxp@21cc000", 0x440, 9},
|
||||
{MODULE_CSI, "/soc/aips-bus@2100000/csi@21c4000", 0x440, 10},
|
||||
{MODULE_ADC1, "/soc/aips-bus@2100000/adc@2198000", 0x440, 11},
|
||||
{MODULE_ENET1, "/soc/aips-bus@2100000/ethernet@2188000", 0x440, 12},
|
||||
{MODULE_ENET2, "/soc/aips-bus@2000000/ethernet@20b4000", 0x440, 13},
|
||||
{MODULE_DCP, "/soc/aips-bus@2200000/dcp@2280000", 0x440, 14},
|
||||
{MODULE_USB_OTG2, "/soc/aips-bus@2100000/usb@2184200", 0x440, 15},
|
||||
{MODULE_SAI2, "/soc/aips-bus@2000000/spba-bus@2000000/sai@202c000", 0x440, 24},
|
||||
{MODULE_SAI3, "/soc/aips-bus@2000000/spba-bus@2000000/sai@2030000", 0x440, 24},
|
||||
{MODULE_DCP_CRYPTO, "/soc/aips-bus@2200000/dcp@2280000", 0x440, 25},
|
||||
{MODULE_UART5, "/soc/aips-bus@2100000/serial@21f4000", 0x440, 26},
|
||||
{MODULE_UART6, "/soc/aips-bus@2100000/serial@21fc000", 0x440, 26},
|
||||
{MODULE_UART7, "/soc/aips-bus@2000000/spba-bus@2000000/serial@2018000", 0x440, 26},
|
||||
{MODULE_UART8, "/soc/aips-bus@2200000/serial@2288000", 0x440, 26},
|
||||
{MODULE_PWM5, "/soc/aips-bus@2000000/pwm@20f0000", 0x440, 27},
|
||||
{MODULE_PWM6, "/soc/aips-bus@2000000/pwm@20f4000", 0x440, 27},
|
||||
{MODULE_PWM7, "/soc/aips-bus@2000000/pwm@20f8000", 0x440, 27},
|
||||
{MODULE_PWM8, "/soc/aips-bus@2000000/pwm@20fc000", 0x440, 27},
|
||||
{MODULE_ECSPI3, "/soc/aips-bus@2000000/spba-bus@2000000/ecspi@2010000", 0x440, 28},
|
||||
{MODULE_ECSPI4, "/soc/aips-bus@2000000/spba-bus@2000000/ecspi@2014000", 0x440, 28},
|
||||
{MODULE_I2C3, "/soc/aips-bus@2100000/i2c@21a8000", 0x440, 29},
|
||||
{MODULE_I2C4, "/soc/aips-bus@2100000/i2c@21f8000", 0x440, 29},
|
||||
{MODULE_GPT2, "/soc/aips-bus@2000000/gpt@20e8000", 0x440, 30},
|
||||
{MODULE_EPIT2, "/soc/aips-bus@2000000/epit@20d4000", 0x440, 31},
|
||||
/* Paths for older imx tree: */
|
||||
{MODULE_TSC, "/soc/aips-bus@02000000/tsc@02040000", 0x430, 22},
|
||||
{MODULE_ADC2, "/soc/aips-bus@02100000/adc@0219c000", 0x430, 23},
|
||||
{MODULE_EPDC, "/soc/aips-bus@02200000/epdc@0228c000", 0x430, 24},
|
||||
{MODULE_ESAI, "/soc/aips-bus@02000000/spba-bus@02000000/esai@02024000", 0x430, 25},
|
||||
{MODULE_FLEXCAN1, "/soc/aips-bus@02000000/can@02090000", 0x430, 26},
|
||||
{MODULE_FLEXCAN2, "/soc/aips-bus@02000000/can@02094000", 0x430, 27},
|
||||
{MODULE_SPDIF, "/soc/aips-bus@02000000/spba-bus@02000000/spdif@02004000", 0x440, 2},
|
||||
{MODULE_EIM, "/soc/aips-bus@02100000/weim@021b8000", 0x440, 3},
|
||||
{MODULE_SD1, "/soc/aips-bus@02100000/usdhc@02190000", 0x440, 4},
|
||||
{MODULE_SD2, "/soc/aips-bus@02100000/usdhc@02194000", 0x440, 5},
|
||||
{MODULE_QSPI1, "/soc/aips-bus@02100000/qspi@021e0000", 0x440, 6},
|
||||
{MODULE_GPMI, "/soc/gpmi-nand@01806000", 0x440, 7},
|
||||
{MODULE_APBHDMA, "/soc/dma-apbh@01804000", 0x440, 7},
|
||||
{MODULE_LCDIF, "/soc/aips-bus@02100000/lcdif@021c8000", 0x440, 8},
|
||||
{MODULE_PXP, "/soc/aips-bus@02100000/pxp@021cc000", 0x440, 9},
|
||||
{MODULE_CSI, "/soc/aips-bus@02100000/csi@021c4000", 0x440, 10},
|
||||
{MODULE_ADC1, "/soc/aips-bus@02100000/adc@02198000", 0x440, 11},
|
||||
{MODULE_ENET1, "/soc/aips-bus@02100000/ethernet@02188000", 0x440, 12},
|
||||
{MODULE_ENET2, "/soc/aips-bus@02000000/ethernet@020b4000", 0x440, 13},
|
||||
{MODULE_DCP, "/soc/aips-bus@02200000/dcp@02280000", 0x440, 14},
|
||||
{MODULE_USB_OTG2, "/soc/aips-bus@02100000/usb@02184200", 0x440, 15},
|
||||
{MODULE_SAI2, "/soc/aips-bus@02000000/spba-bus@02000000/sai@0202c000", 0x440, 24},
|
||||
{MODULE_SAI3, "/soc/aips-bus@02000000/spba-bus@02000000/sai@02030000", 0x440, 24},
|
||||
{MODULE_DCP_CRYPTO, "/soc/aips-bus@02200000/dcp@02280000", 0x440, 25},
|
||||
{MODULE_UART5, "/soc/aips-bus@02100000/serial@021f4000", 0x440, 26},
|
||||
{MODULE_UART6, "/soc/aips-bus@02100000/serial@021fc000", 0x440, 26},
|
||||
{MODULE_UART7, "/soc/aips-bus@02000000/spba-bus@02000000/serial@02018000", 0x440, 26},
|
||||
{MODULE_UART8, "/soc/aips-bus@02200000/serial@02288000", 0x440, 26},
|
||||
{MODULE_PWM5, "/soc/aips-bus@02000000/pwm@020f0000", 0x440, 27},
|
||||
{MODULE_PWM6, "/soc/aips-bus@02000000/pwm@020f4000", 0x440, 27},
|
||||
{MODULE_PWM7, "/soc/aips-bus@02000000/pwm@020f8000", 0x440, 27},
|
||||
{MODULE_PWM8, "/soc/aips-bus@02000000/pwm@020fc000", 0x440, 27},
|
||||
{MODULE_ECSPI3, "/soc/aips-bus@02000000/spba-bus@02000000/ecspi@02010000", 0x440, 28},
|
||||
{MODULE_ECSPI4, "/soc/aips-bus@02000000/spba-bus@02000000/ecspi@02014000", 0x440, 28},
|
||||
{MODULE_I2C3, "/soc/aips-bus@02100000/i2c@021a8000", 0x440, 29},
|
||||
{MODULE_I2C4, "/soc/aips-bus@02100000/i2c@021f8000", 0x440, 29},
|
||||
{MODULE_GPT2, "/soc/aips-bus@02000000/gpt@020e8000", 0x440, 30},
|
||||
{MODULE_EPIT2, "/soc/aips-bus@02000000/epit@020d4000", 0x440, 31},
|
||||
#elif defined(CONFIG_MX6UL)
|
||||
{MODULE_TSC, "/soc/aips-bus@2000000/tsc@2040000", 0x430, 22},
|
||||
{MODULE_ADC2, "/soc/aips-bus@2100000/adc@219c000", 0x430, 23},
|
||||
{MODULE_SIM1, "/soc/aips-bus@2100000/sim@218c000", 0x430, 24},
|
||||
{MODULE_SIM2, "/soc/aips-bus@2100000/sim@21b4000", 0x430, 25},
|
||||
{MODULE_FLEXCAN1, "/soc/aips-bus@2000000/can@2090000", 0x430, 26},
|
||||
{MODULE_FLEXCAN2, "/soc/aips-bus@2000000/can@2094000", 0x430, 27},
|
||||
{MODULE_SPDIF, "/soc/aips-bus@2000000/spba-bus@2000000/spdif@2004000", 0x440, 2},
|
||||
{MODULE_EIM, "/soc/aips-bus@2100000/weim@21b8000", 0x440, 3},
|
||||
{MODULE_SD1, "/soc/aips-bus@2100000/usdhc@2190000", 0x440, 4},
|
||||
{MODULE_SD2, "/soc/aips-bus@2100000/usdhc@2194000", 0x440, 5},
|
||||
{MODULE_QSPI1, "/soc/aips-bus@2100000/qspi@21e0000", 0x440, 6},
|
||||
{MODULE_GPMI, "/soc/gpmi-nand@1806000", 0x440, 7},
|
||||
{MODULE_APBHDMA, "/soc/dma-apbh@1804000", 0x440, 7},
|
||||
{MODULE_LCDIF, "/soc/aips-bus@2100000/lcdif@21c8000", 0x440, 8},
|
||||
{MODULE_PXP, "/soc/aips-bus@2100000/pxp@21cc000", 0x440, 9},
|
||||
{MODULE_CSI, "/soc/aips-bus@2100000/csi@21c4000", 0x440, 10},
|
||||
{MODULE_ADC1, "/soc/aips-bus@2100000/adc@2198000", 0x440, 11},
|
||||
{MODULE_ENET1, "/soc/aips-bus@2100000/ethernet@2188000", 0x440, 12},
|
||||
{MODULE_ENET2, "/soc/aips-bus@2000000/ethernet@20b4000", 0x440, 13},
|
||||
{MODULE_CAAM, "/soc/aips-bus@2100000/caam@2140000", 0x440, 14},
|
||||
{MODULE_USB_OTG2, "/soc/aips-bus@2100000/usb@2184200", 0x440, 15},
|
||||
{MODULE_SAI2, "/soc/aips-bus@2000000/spba-bus@2000000/sai@202c000", 0x440, 24},
|
||||
{MODULE_SAI3, "/soc/aips-bus@2000000/spba-bus@2000000/sai@2030000", 0x440, 24},
|
||||
{MODULE_BEE, "/soc/aips-bus@2000000/bee@2044000", 0x440, 25},
|
||||
{MODULE_UART5, "/soc/aips-bus@2100000/serial@21f4000", 0x440, 26},
|
||||
{MODULE_UART6, "/soc/aips-bus@2100000/serial@21fc000", 0x440, 26},
|
||||
{MODULE_UART7, "/soc/aips-bus@2000000/spba-bus@2000000/serial@2018000", 0x440, 26},
|
||||
{MODULE_UART8, "/soc/aips-bus@2000000/spba-bus@2000000/serial@2024000", 0x440, 26},
|
||||
{MODULE_PWM5, "/soc/aips-bus@2000000/pwm@20f0000", 0x440, 27},
|
||||
{MODULE_PWM6, "/soc/aips-bus@2000000/pwm@20f4000", 0x440, 27},
|
||||
{MODULE_PWM7, "/soc/aips-bus@2000000/pwm@20f8000", 0x440, 27},
|
||||
{MODULE_PWM8, "/soc/aips-bus@2000000/pwm@20fc000", 0x440, 27},
|
||||
{MODULE_ECSPI3, "/soc/aips-bus@2000000/spba-bus@2000000/ecspi@2010000", 0x440, 28},
|
||||
{MODULE_ECSPI4, "/soc/aips-bus@2000000/spba-bus@2000000/ecspi@2014000", 0x440, 28},
|
||||
{MODULE_I2C3, "/soc/aips-bus@2100000/i2c@21a8000", 0x440, 29},
|
||||
{MODULE_I2C4, "/soc/aips-bus@2100000/i2c@21f8000", 0x440, 29},
|
||||
{MODULE_GPT2, "/soc/aips-bus@2000000/gpt@20e8000", 0x440, 30},
|
||||
{MODULE_EPIT2, "/soc/aips-bus@2000000/epit@20d4000", 0x440, 31},
|
||||
/* Paths for older imx tree: */
|
||||
{MODULE_TSC, "/soc/aips-bus@02000000/tsc@02040000", 0x430, 22},
|
||||
{MODULE_ADC2, "/soc/aips-bus@02100000/adc@0219c000", 0x430, 23},
|
||||
{MODULE_SIM1, "/soc/aips-bus@02100000/sim@0218c000", 0x430, 24},
|
||||
{MODULE_SIM2, "/soc/aips-bus@02100000/sim@021b4000", 0x430, 25},
|
||||
{MODULE_FLEXCAN1, "/soc/aips-bus@02000000/can@02090000", 0x430, 26},
|
||||
{MODULE_FLEXCAN2, "/soc/aips-bus@02000000/can@02094000", 0x430, 27},
|
||||
{MODULE_SPDIF, "/soc/aips-bus@02000000/spba-bus@02000000/spdif@02004000", 0x440, 2},
|
||||
{MODULE_EIM, "/soc/aips-bus@02100000/weim@021b8000", 0x440, 3},
|
||||
{MODULE_SD1, "/soc/aips-bus@02100000/usdhc@02190000", 0x440, 4},
|
||||
{MODULE_SD2, "/soc/aips-bus@02100000/usdhc@02194000", 0x440, 5},
|
||||
{MODULE_QSPI1, "/soc/aips-bus@02100000/qspi@021e0000", 0x440, 6},
|
||||
{MODULE_GPMI, "/soc/gpmi-nand@01806000", 0x440, 7},
|
||||
{MODULE_APBHDMA, "/soc/dma-apbh@01804000", 0x440, 7},
|
||||
{MODULE_LCDIF, "/soc/aips-bus@02100000/lcdif@021c8000", 0x440, 8},
|
||||
{MODULE_PXP, "/soc/aips-bus@02100000/pxp@021cc000", 0x440, 9},
|
||||
{MODULE_CSI, "/soc/aips-bus@02100000/csi@021c4000", 0x440, 10},
|
||||
{MODULE_ADC1, "/soc/aips-bus@02100000/adc@02198000", 0x440, 11},
|
||||
{MODULE_ENET1, "/soc/aips-bus@02100000/ethernet@02188000", 0x440, 12},
|
||||
{MODULE_ENET2, "/soc/aips-bus@02000000/ethernet@020b4000", 0x440, 13},
|
||||
{MODULE_CAAM, "/soc/aips-bus@02100000/caam@2140000", 0x440, 14},
|
||||
{MODULE_USB_OTG2, "/soc/aips-bus@02100000/usb@02184200", 0x440, 15},
|
||||
{MODULE_SAI2, "/soc/aips-bus@02000000/spba-bus@02000000/sai@0202c000", 0x440, 24},
|
||||
{MODULE_SAI3, "/soc/aips-bus@02000000/spba-bus@02000000/sai@02030000", 0x440, 24},
|
||||
{MODULE_BEE, "/soc/aips-bus@02000000/bee@02044000", 0x440, 25},
|
||||
{MODULE_UART5, "/soc/aips-bus@02100000/serial@021f4000", 0x440, 26},
|
||||
{MODULE_UART6, "/soc/aips-bus@02100000/serial@021fc000", 0x440, 26},
|
||||
{MODULE_UART7, "/soc/aips-bus@02000000/spba-bus@02000000/serial@02018000", 0x440, 26},
|
||||
{MODULE_UART8, "/soc/aips-bus@02000000/spba-bus@02000000/serial@02024000", 0x440, 26},
|
||||
{MODULE_PWM5, "/soc/aips-bus@02000000/pwm@020f0000", 0x440, 27},
|
||||
{MODULE_PWM6, "/soc/aips-bus@02000000/pwm@020f4000", 0x440, 27},
|
||||
{MODULE_PWM7, "/soc/aips-bus@02000000/pwm@020f8000", 0x440, 27},
|
||||
{MODULE_PWM8, "/soc/aips-bus@02000000/pwm@020fc000", 0x440, 27},
|
||||
{MODULE_ECSPI3, "/soc/aips-bus@02000000/spba-bus@02000000/ecspi@02010000", 0x440, 28},
|
||||
{MODULE_ECSPI4, "/soc/aips-bus@02000000/spba-bus@02000000/ecspi@02014000", 0x440, 28},
|
||||
{MODULE_I2C3, "/soc/aips-bus@02100000/i2c@021a8000", 0x440, 29},
|
||||
{MODULE_I2C4, "/soc/aips-bus@02100000/i2c@021f8000", 0x440, 29},
|
||||
{MODULE_GPT2, "/soc/aips-bus@02000000/gpt@020e8000", 0x440, 30},
|
||||
{MODULE_EPIT2, "/soc/aips-bus@02000000/epit@020d4000", 0x440, 31},
|
||||
#endif
|
||||
};
|
||||
|
||||
u32 check_module_fused(enum fuse_module_type module)
|
||||
{
|
||||
u32 i, reg;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mx6_fuse_descs); i++) {
|
||||
if (mx6_fuse_descs[i].module == module) {
|
||||
reg = readl(OCOTP_BASE_ADDR +
|
||||
mx6_fuse_descs[i].fuse_word_offset);
|
||||
if (reg & BIT(mx6_fuse_descs[i].fuse_bit_offset))
|
||||
return 1; /* disabled */
|
||||
else
|
||||
return 0; /* enabled */
|
||||
}
|
||||
}
|
||||
|
||||
return 0; /* Not has a fuse, always enabled */
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF_SYSTEM_SETUP
|
||||
int ft_system_setup(void *blob, bd_t *bd)
|
||||
{
|
||||
const char *status = "disabled";
|
||||
u32 i, reg;
|
||||
int rc, off;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mx6_fuse_descs); i++) {
|
||||
reg = readl(OCOTP_BASE_ADDR +
|
||||
mx6_fuse_descs[i].fuse_word_offset);
|
||||
if (reg & BIT(mx6_fuse_descs[i].fuse_bit_offset)) {
|
||||
off = fdt_path_offset(blob,
|
||||
mx6_fuse_descs[i].node_path);
|
||||
|
||||
if (off < 0)
|
||||
continue; /* Not found, skip it */
|
||||
add_status:
|
||||
rc = fdt_setprop(blob, nodeoff, "status", status,
|
||||
strlen(status) + 1);
|
||||
if (rc) {
|
||||
if (rc == -FDT_ERR_NOSPACE) {
|
||||
rc = fdt_increase_size(blob, 512);
|
||||
if (!rc)
|
||||
goto add_status;
|
||||
}
|
||||
printf("Unable to update property %s:%s, err=%s\n", mx6_fuse_descs[i].node_path, "status", fdt_strerror(rc));
|
||||
} else {
|
||||
printf("Modify %s disabled\n", mx6_fuse_descs[i].node_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
u32 esdhc_fused(ulong base_addr)
|
||||
{
|
||||
switch (base_addr) {
|
||||
case USDHC1_BASE_ADDR:
|
||||
return check_module_fused(MODULE_SD1);
|
||||
case USDHC2_BASE_ADDR:
|
||||
return check_module_fused(MODULE_SD2);
|
||||
#ifdef USDHC3_BASE_ADDR
|
||||
case USDHC3_BASE_ADDR:
|
||||
return check_module_fused(MODULE_SD3);
|
||||
#endif
|
||||
#ifdef USDHC4_BASE_ADDR
|
||||
case USDHC4_BASE_ADDR:
|
||||
return check_module_fused(MODULE_SD4);
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
u32 ecspi_fused(ulong base_addr)
|
||||
{
|
||||
switch (base_addr) {
|
||||
case ECSPI1_BASE_ADDR:
|
||||
return check_module_fused(MODULE_ECSPI1);
|
||||
case ECSPI2_BASE_ADDR:
|
||||
return check_module_fused(MODULE_ECSPI2);
|
||||
case ECSPI3_BASE_ADDR:
|
||||
return check_module_fused(MODULE_ECSPI3);
|
||||
case ECSPI4_BASE_ADDR:
|
||||
return check_module_fused(MODULE_ECSPI4);
|
||||
#ifdef ECSPI5_BASE_ADDR
|
||||
case ECSPI5_BASE_ADDR:
|
||||
return check_module_fused(MODULE_ECSPI5);
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
u32 usb_fused(ulong base_addr)
|
||||
{
|
||||
int i = (base_addr - USB_BASE_ADDR) / 0x200;
|
||||
|
||||
return check_module_fused(MODULE_USB_OTG1 + i);
|
||||
}
|
||||
|
||||
u32 qspi_fused(ulong base_addr)
|
||||
{
|
||||
switch (base_addr) {
|
||||
#ifdef QSPI1_BASE_ADDR
|
||||
case QSPI1_BASE_ADDR:
|
||||
return check_module_fused(MODULE_QSPI1);
|
||||
#endif
|
||||
|
||||
#ifdef QSPI2_BASE_ADDR
|
||||
case QSPI2_BASE_ADDR:
|
||||
return check_module_fused(MODULE_QSPI2);
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
u32 i2c_fused(ulong base_addr)
|
||||
{
|
||||
switch (base_addr) {
|
||||
case I2C1_BASE_ADDR:
|
||||
return check_module_fused(MODULE_I2C1);
|
||||
case I2C2_BASE_ADDR:
|
||||
return check_module_fused(MODULE_I2C2);
|
||||
case I2C3_BASE_ADDR:
|
||||
return check_module_fused(MODULE_I2C3);
|
||||
#ifdef I2C4_BASE_ADDR
|
||||
case I2C4_BASE_ADDR:
|
||||
return check_module_fused(MODULE_I2C4);
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 enet_fused(ulong base_addr)
|
||||
{
|
||||
switch (base_addr) {
|
||||
case ENET_BASE_ADDR:
|
||||
return check_module_fused(MODULE_ENET1);
|
||||
#ifdef ENET2_BASE_ADDR
|
||||
case ENET2_BASE_ADDR:
|
||||
return check_module_fused(MODULE_ENET2);
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
14
board/beacon/imx8mm/Kconfig
Normal file
14
board/beacon/imx8mm/Kconfig
Normal file
|
@ -0,0 +1,14 @@
|
|||
if TARGET_IMX8MM_BEACON
|
||||
|
||||
config SYS_BOARD
|
||||
default "imx8mm"
|
||||
|
||||
config SYS_VENDOR
|
||||
default "beacon"
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
default "imx8mm_beacon"
|
||||
|
||||
source "board/freescale/common/Kconfig"
|
||||
|
||||
endif
|
7
board/beacon/imx8mm/MAINTAINERS
Normal file
7
board/beacon/imx8mm/MAINTAINERS
Normal file
|
@ -0,0 +1,7 @@
|
|||
i.MX8MM Beacon EmbeddedWorks Devkit
|
||||
|
||||
M: Adam Ford <aford173@gmail.com>
|
||||
S: Maintained
|
||||
F: board/beacon/imx8mm/
|
||||
F: include/configs/imx8mm_beacon.h
|
||||
F: configs/imx8mm_beacon_defconfig
|
13
board/beacon/imx8mm/Makefile
Normal file
13
board/beacon/imx8mm/Makefile
Normal file
|
@ -0,0 +1,13 @@
|
|||
#
|
||||
# Copyright 2020 Compass Electronics Group, LLC
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-y += imx8mm_beacon.o
|
||||
obj-y += ../../freescale/common/
|
||||
|
||||
ifdef CONFIG_SPL_BUILD
|
||||
obj-y += spl.o
|
||||
obj-y += lpddr4_timing.o
|
||||
endif
|
37
board/beacon/imx8mm/README
Normal file
37
board/beacon/imx8mm/README
Normal file
|
@ -0,0 +1,37 @@
|
|||
U-Boot for the Beacon EmbeddedWorks Devkit
|
||||
|
||||
Quick Start
|
||||
===========
|
||||
- Build the ARM Trusted firmware binary
|
||||
- Get ddr firmware
|
||||
- Build U-Boot
|
||||
- Boot
|
||||
|
||||
Get and Build the ARM Trusted firmware
|
||||
======================================
|
||||
Note: $(srctree) is U-Boot source directory
|
||||
|
||||
$ git clone https://source.codeaurora.org/external/imx/imx-atf
|
||||
$ git checkout imx_4.19.35_1.0.0
|
||||
$ make PLAT=imx8mm bl31 ARCH=arm CROSS_COMPILE=aarch64-linux-gnu-
|
||||
$ cp build/imx8mm/release/bl31.bin $(srctree)
|
||||
|
||||
Get the DDR firmware
|
||||
====================
|
||||
$ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.5.bin
|
||||
$ chmod +x firmware-imx-8.5.bin
|
||||
$ ./firmware-imx-8.5
|
||||
$ cp firmware-imx-8.5/firmware/ddr/synopsys/lpddr4*.bin $(srctree)
|
||||
|
||||
Build U-Boot
|
||||
============
|
||||
$ make imx8mm_beacon_defconfig
|
||||
$ make flash.bin ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- ATF_LOAD_ADDR=0x920000
|
||||
|
||||
Burn U-Boot to microSD Card
|
||||
===========================
|
||||
$ sudo dd if=flash.bin of=/dev/sd[x] bs=1024 seek=33
|
||||
|
||||
Boot
|
||||
====
|
||||
Set Boot switch to SD boot
|
67
board/beacon/imx8mm/imx8mm_beacon.c
Normal file
67
board/beacon/imx8mm/imx8mm_beacon.c
Normal file
|
@ -0,0 +1,67 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2020 Compass Electronics Group, LLC
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <miiphy.h>
|
||||
#include <netdev.h>
|
||||
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/sys_proto.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
/* rom_pointer[1] contains the size of TEE occupies */
|
||||
if (rom_pointer[1])
|
||||
gd->ram_size = PHYS_SDRAM_SIZE - rom_pointer[1];
|
||||
else
|
||||
gd->ram_size = PHYS_SDRAM_SIZE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_FEC_MXC)
|
||||
static int setup_fec(void)
|
||||
{
|
||||
struct iomuxc_gpr_base_regs *gpr =
|
||||
(struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR;
|
||||
|
||||
/* Use 125M anatop REF_CLK1 for ENET1, not from external */
|
||||
clrsetbits_le32(&gpr->gpr[1], 0x2000, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_phy_config(struct phy_device *phydev)
|
||||
{
|
||||
/* enable rgmii rxc skew and phy mode select to RGMII copper */
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f);
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8);
|
||||
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x00);
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x82ee);
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05);
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100);
|
||||
|
||||
if (phydev->drv->config)
|
||||
phydev->drv->config(phydev);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_FEC_MXC))
|
||||
setup_fec();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_mmc_get_env_dev(int devno)
|
||||
{
|
||||
return devno;
|
||||
}
|
1980
board/beacon/imx8mm/lpddr4_timing.c
Normal file
1980
board/beacon/imx8mm/lpddr4_timing.c
Normal file
File diff suppressed because it is too large
Load diff
155
board/beacon/imx8mm/spl.c
Normal file
155
board/beacon/imx8mm/spl.c
Normal file
|
@ -0,0 +1,155 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
#include <common.h>
|
||||
#include <cpu_func.h>
|
||||
#include <hang.h>
|
||||
#include <spl.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/mach-imx/iomux-v3.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/imx8mm_pins.h>
|
||||
#include <asm/arch/sys_proto.h>
|
||||
#include <asm/mach-imx/boot_mode.h>
|
||||
#include <asm/arch/ddr.h>
|
||||
|
||||
#include <dm/uclass.h>
|
||||
#include <dm/device.h>
|
||||
#include <dm/uclass-internal.h>
|
||||
#include <dm/device-internal.h>
|
||||
|
||||
#include <power/pmic.h>
|
||||
#include <power/bd71837.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int spl_board_boot_device(enum boot_device boot_dev_spl)
|
||||
{
|
||||
switch (boot_dev_spl) {
|
||||
case SD2_BOOT:
|
||||
case MMC2_BOOT:
|
||||
return BOOT_DEVICE_MMC1;
|
||||
case SD3_BOOT:
|
||||
case MMC3_BOOT:
|
||||
return BOOT_DEVICE_MMC2;
|
||||
default:
|
||||
return BOOT_DEVICE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
static void spl_dram_init(void)
|
||||
{
|
||||
ddr_init(&dram_timing);
|
||||
}
|
||||
|
||||
void spl_board_init(void)
|
||||
{
|
||||
debug("Normal Boot\n");
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SPL_LOAD_FIT
|
||||
int board_fit_config_name_match(const char *name)
|
||||
{
|
||||
/* Just empty function now - can't decide what to choose */
|
||||
debug("%s: %s\n", __func__, name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define UART_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_FSEL1)
|
||||
#define WDOG_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_ODE | PAD_CTL_PUE | PAD_CTL_PE)
|
||||
|
||||
static iomux_v3_cfg_t const uart_pads[] = {
|
||||
IMX8MM_PAD_UART2_RXD_UART2_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
|
||||
IMX8MM_PAD_UART2_TXD_UART2_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
|
||||
};
|
||||
|
||||
static iomux_v3_cfg_t const wdog_pads[] = {
|
||||
IMX8MM_PAD_GPIO1_IO02_WDOG1_WDOG_B | MUX_PAD_CTRL(WDOG_PAD_CTRL),
|
||||
};
|
||||
|
||||
int board_early_init_f(void)
|
||||
{
|
||||
struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR;
|
||||
|
||||
imx_iomux_v3_setup_multiple_pads(wdog_pads, ARRAY_SIZE(wdog_pads));
|
||||
|
||||
set_wdog_reset(wdog);
|
||||
|
||||
imx_iomux_v3_setup_multiple_pads(uart_pads, ARRAY_SIZE(uart_pads));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int power_init_board(void)
|
||||
{
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
|
||||
ret = pmic_get("pmic@4b", &dev);
|
||||
if (ret == -ENODEV) {
|
||||
puts("No pmic\n");
|
||||
return 0;
|
||||
}
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
/* decrease RESET key long push time from the default 10s to 10ms */
|
||||
pmic_reg_write(dev, BD718XX_PWRONCONFIG1, 0x0);
|
||||
|
||||
/* unlock the PMIC regs */
|
||||
pmic_reg_write(dev, BD718XX_REGLOCK, 0x1);
|
||||
|
||||
/* increase VDD_SOC to typical value 0.85v before first DRAM access */
|
||||
pmic_reg_write(dev, BD718XX_BUCK1_VOLT_RUN, 0x0f);
|
||||
|
||||
/* increase VDD_DRAM to 0.975v for 3Ghz DDR */
|
||||
pmic_reg_write(dev, BD718XX_1ST_NODVS_BUCK_VOLT, 0x83);
|
||||
|
||||
/* lock the PMIC regs */
|
||||
pmic_reg_write(dev, BD718XX_REGLOCK, 0x11);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void board_init_f(ulong dummy)
|
||||
{
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
|
||||
arch_cpu_init();
|
||||
|
||||
init_uart_clk(1);
|
||||
|
||||
board_early_init_f();
|
||||
|
||||
timer_init();
|
||||
|
||||
preloader_console_init();
|
||||
|
||||
/* Clear the BSS. */
|
||||
memset(__bss_start, 0, __bss_end - __bss_start);
|
||||
|
||||
ret = spl_early_init();
|
||||
if (ret) {
|
||||
debug("spl_early_init() failed: %d\n", ret);
|
||||
hang();
|
||||
}
|
||||
|
||||
ret = uclass_get_device_by_name(UCLASS_CLK,
|
||||
"clock-controller@30380000",
|
||||
&dev);
|
||||
if (ret < 0) {
|
||||
printf("Failed to find clock node. Check device tree\n");
|
||||
hang();
|
||||
}
|
||||
|
||||
enable_tzc380();
|
||||
|
||||
power_init_board();
|
||||
|
||||
/* DDR initialization */
|
||||
spl_dram_init();
|
||||
|
||||
board_init_r(NULL, 0);
|
||||
}
|
|
@ -123,10 +123,23 @@ int board_mmc_get_env_dev(int devno)
|
|||
|
||||
int board_late_init(void)
|
||||
{
|
||||
char *fdt_file;
|
||||
bool m4_booted;
|
||||
|
||||
#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
|
||||
env_set("board_name", "MEK");
|
||||
env_set("board_rev", "iMX8QM");
|
||||
#endif
|
||||
|
||||
fdt_file = env_get("fdt_file");
|
||||
m4_booted = m4_parts_booted();
|
||||
|
||||
if (fdt_file && !strcmp(fdt_file, "undefined")) {
|
||||
if (m4_booted)
|
||||
env_set("fdt_file", "imx8qm-mek-rpmsg.dtb");
|
||||
else
|
||||
env_set("fdt_file", "imx8qm-mek.dtb");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <dm/uclass-internal.h>
|
||||
#include <dm/device-internal.h>
|
||||
#include <dm/lists.h>
|
||||
#include <asm/arch/sys_proto.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
|
@ -37,6 +38,11 @@ void spl_board_init(void)
|
|||
puts("Normal Boot\n");
|
||||
}
|
||||
|
||||
void spl_board_prepare_for_boot(void)
|
||||
{
|
||||
imx8_power_off_pd_devices(NULL, 0);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SPL_LOAD_FIT
|
||||
int board_fit_config_name_match(const char *name)
|
||||
{
|
||||
|
|
|
@ -146,10 +146,23 @@ int board_mmc_get_env_dev(int devno)
|
|||
|
||||
int board_late_init(void)
|
||||
{
|
||||
char *fdt_file;
|
||||
bool m4_booted;
|
||||
|
||||
#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
|
||||
env_set("board_name", "MEK");
|
||||
env_set("board_rev", "iMX8QXP");
|
||||
#endif
|
||||
|
||||
fdt_file = env_get("fdt_file");
|
||||
m4_booted = m4_parts_booted();
|
||||
|
||||
if (fdt_file && !strcmp(fdt_file, "undefined")) {
|
||||
if (m4_booted)
|
||||
env_set("fdt_file", "imx8qxp-mek-rpmsg.dtb");
|
||||
else
|
||||
env_set("fdt_file", "imx8qxp-mek.dtb");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <asm/arch/sci/sci.h>
|
||||
#include <asm/arch/imx8-pins.h>
|
||||
#include <asm/arch/iomux.h>
|
||||
#include <asm/arch/sys_proto.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
|
@ -55,6 +56,11 @@ void spl_board_init(void)
|
|||
puts("Normal Boot\n");
|
||||
}
|
||||
|
||||
void spl_board_prepare_for_boot(void)
|
||||
{
|
||||
imx8_power_off_pd_devices(NULL, 0);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SPL_LOAD_FIT
|
||||
int board_fit_config_name_match(const char *name)
|
||||
{
|
||||
|
|
12
board/technexion/pico-imx8mq/Kconfig
Normal file
12
board/technexion/pico-imx8mq/Kconfig
Normal file
|
@ -0,0 +1,12 @@
|
|||
if TARGET_PICO_IMX8MQ
|
||||
|
||||
config SYS_BOARD
|
||||
default "pico-imx8mq"
|
||||
|
||||
config SYS_VENDOR
|
||||
default "technexion"
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
default "pico-imx8mq"
|
||||
|
||||
endif
|
6
board/technexion/pico-imx8mq/MAINTAINERS
Normal file
6
board/technexion/pico-imx8mq/MAINTAINERS
Normal file
|
@ -0,0 +1,6 @@
|
|||
PICOPI IMX8MQ BOARD
|
||||
M: Marek Vasut <marek.vasut@gmail.com>
|
||||
S: Maintained
|
||||
F: board/technexion/pico-imx8mq/
|
||||
F: include/configs/pico-imx8mq.h
|
||||
F: configs/pico-imx8mq_defconfig
|
12
board/technexion/pico-imx8mq/Makefile
Normal file
12
board/technexion/pico-imx8mq/Makefile
Normal file
|
@ -0,0 +1,12 @@
|
|||
#
|
||||
# Copyright 2017 NXP
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-y += pico-imx8mq.o
|
||||
|
||||
ifdef CONFIG_SPL_BUILD
|
||||
obj-y += spl.o
|
||||
obj-$(CONFIG_IMX8M_LPDDR4) += lpddr4_timing_1gb.o lpddr4_timing_2gb.o lpddr4_timing_3gb.o lpddr4_timing_4gb.o
|
||||
endif
|
52
board/technexion/pico-imx8mq/README
Normal file
52
board/technexion/pico-imx8mq/README
Normal file
|
@ -0,0 +1,52 @@
|
|||
U-Boot for the Technexion Pico i.MX8MQ
|
||||
|
||||
Quick Start
|
||||
===========
|
||||
- Build the TFA binary
|
||||
- Get DDR and HDMI firmware
|
||||
- Build U-Boot
|
||||
- Boot
|
||||
|
||||
Get and Build the TFA blob
|
||||
==========================
|
||||
Note: srctree is U-Boot source directory
|
||||
Get ATF from: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git
|
||||
branch: master
|
||||
$ CROSS_COMPILE=aarch64-linux-gnu- make PLAT=imx8mq bl31
|
||||
$ cp build/imx8mq/release/bl31.bin $(builddir)
|
||||
|
||||
Get the DDR and HDMI firmware
|
||||
=============================
|
||||
$ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-7.9.bin
|
||||
$ chmod +x firmware-imx-7.9.bin
|
||||
$ ./firmware-imx-7.9.bin
|
||||
# Or use this to avoid running random scripts from the internet,
|
||||
# but note that you must agree to the license the script displays:
|
||||
# $ dd if=firmware-imx-7.9.bin of=firmware-imx-7.9.tar.bz2 bs=38868 skip=1
|
||||
# $ tar -xf firmware-imx-7.9.tar.bz2
|
||||
$ cp firmware-imx-7.9/firmware/hdmi/cadence/signed_hdmi_imx8m.bin $(builddir)
|
||||
$ cp firmware-imx-7.9/firmware/ddr/synopsys/lpddr4*.bin $(builddir)
|
||||
|
||||
Build U-Boot
|
||||
============
|
||||
$ export CROSS_COMPILE=aarch64-poky-linux-
|
||||
$ make pico-imx8mq_defconfig
|
||||
$ make flash.bin
|
||||
|
||||
Burn the flash.bin to MicroSD card offset 33KB
|
||||
$ dd if=flash.bin of=/dev/mmcblkX bs=1024 seek=33
|
||||
Or into eMMC from a running system
|
||||
$ dhcp flash.bin && mmc write $loadaddr 0x42 0x800
|
||||
|
||||
Boot
|
||||
====
|
||||
"o" denotes a pin
|
||||
"[]" denotes two pins bridged by a jumper
|
||||
|
||||
eMMC boot:
|
||||
J1 o[] []o J2
|
||||
[]o o[]
|
||||
|
||||
USB upload via USB-C connector:
|
||||
J1 ooo ooo J2
|
||||
o[] []o
|
14
board/technexion/pico-imx8mq/lpddr4_timing.h
Normal file
14
board/technexion/pico-imx8mq/lpddr4_timing.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2020 Marek Vasut <marek.vasut@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __LPDDR4_TIMING_H__
|
||||
#define __LPDDR4_TIMING_H__
|
||||
|
||||
extern struct dram_timing_info dram_timing_1gb;
|
||||
extern struct dram_timing_info dram_timing_2gb;
|
||||
extern struct dram_timing_info dram_timing_3gb;
|
||||
extern struct dram_timing_info dram_timing_4gb;
|
||||
|
||||
#endif /* __LPDDR4_TIMING_H__ */
|
1734
board/technexion/pico-imx8mq/lpddr4_timing_1gb.c
Normal file
1734
board/technexion/pico-imx8mq/lpddr4_timing_1gb.c
Normal file
File diff suppressed because it is too large
Load diff
1734
board/technexion/pico-imx8mq/lpddr4_timing_2gb.c
Normal file
1734
board/technexion/pico-imx8mq/lpddr4_timing_2gb.c
Normal file
File diff suppressed because it is too large
Load diff
1734
board/technexion/pico-imx8mq/lpddr4_timing_3gb.c
Normal file
1734
board/technexion/pico-imx8mq/lpddr4_timing_3gb.c
Normal file
File diff suppressed because it is too large
Load diff
1734
board/technexion/pico-imx8mq/lpddr4_timing_4gb.c
Normal file
1734
board/technexion/pico-imx8mq/lpddr4_timing_4gb.c
Normal file
File diff suppressed because it is too large
Load diff
146
board/technexion/pico-imx8mq/pico-imx8mq.c
Normal file
146
board/technexion/pico-imx8mq/pico-imx8mq.c
Normal file
|
@ -0,0 +1,146 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2018 NXP
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <env.h>
|
||||
#include <init.h>
|
||||
#include <malloc.h>
|
||||
#include <errno.h>
|
||||
#include <asm/io.h>
|
||||
#include <miiphy.h>
|
||||
#include <netdev.h>
|
||||
#include <asm/mach-imx/iomux-v3.h>
|
||||
#include <asm-generic/gpio.h>
|
||||
#include <fsl_esdhc_imx.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 <spl.h>
|
||||
#include <power/pmic.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define UART_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_FSEL1)
|
||||
|
||||
#define WDOG_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_HYS | PAD_CTL_PUE)
|
||||
|
||||
static iomux_v3_cfg_t const wdog_pads[] = {
|
||||
IMX8MQ_PAD_GPIO1_IO02__WDOG1_WDOG_B | MUX_PAD_CTRL(WDOG_PAD_CTRL),
|
||||
};
|
||||
|
||||
static iomux_v3_cfg_t const 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),
|
||||
};
|
||||
|
||||
int board_early_init_f(void)
|
||||
{
|
||||
struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR;
|
||||
|
||||
imx_iomux_v3_setup_multiple_pads(wdog_pads, ARRAY_SIZE(wdog_pads));
|
||||
set_wdog_reset(wdog);
|
||||
|
||||
imx_iomux_v3_setup_multiple_pads(uart_pads, ARRAY_SIZE(uart_pads));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
int ddr_size = readl(M4_BOOTROM_BASE_ADDR);
|
||||
|
||||
if (ddr_size == 0x4)
|
||||
gd->ram_size = 0x100000000;
|
||||
else if (ddr_size == 0x3)
|
||||
gd->ram_size = 0xc0000000;
|
||||
else if (ddr_size == 0x2)
|
||||
gd->ram_size = 0x80000000;
|
||||
else if (ddr_size == 0x1)
|
||||
gd->ram_size = 0x40000000;
|
||||
else
|
||||
printf("Unknown DDR type!!!\n");
|
||||
|
||||
/* rom_pointer[1] contains the size of TEE occupies */
|
||||
if (rom_pointer[1])
|
||||
gd->ram_size -= rom_pointer[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FEC_MXC
|
||||
#define FEC_RST_PAD IMX_GPIO_NR(1, 9)
|
||||
#define FEC_PWR_PAD IMX_GPIO_NR(1, 0)
|
||||
static iomux_v3_cfg_t const fec1_pads[] = {
|
||||
/* Reset */
|
||||
IMX8MQ_PAD_GPIO1_IO09__GPIO1_IO9 | MUX_PAD_CTRL(NO_PAD_CTRL),
|
||||
/* Power */
|
||||
IMX8MQ_PAD_GPIO1_IO00__GPIO1_IO0 | MUX_PAD_CTRL(NO_PAD_CTRL),
|
||||
};
|
||||
|
||||
static void setup_iomux_fec(void)
|
||||
{
|
||||
imx_iomux_v3_setup_multiple_pads(fec1_pads, ARRAY_SIZE(fec1_pads));
|
||||
|
||||
gpio_request(IMX_GPIO_NR(1, 0), "fec1_pwr");
|
||||
gpio_direction_output(IMX_GPIO_NR(1, 0), 1);
|
||||
udelay(500);
|
||||
|
||||
gpio_request(IMX_GPIO_NR(1, 9), "fec1_rst");
|
||||
gpio_direction_output(IMX_GPIO_NR(1, 9), 0);
|
||||
udelay(500);
|
||||
gpio_direction_output(IMX_GPIO_NR(1, 9), 1);
|
||||
}
|
||||
|
||||
static int setup_fec(void)
|
||||
{
|
||||
struct iomuxc_gpr_base_regs *gpr =
|
||||
(struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR;
|
||||
|
||||
setup_iomux_fec();
|
||||
|
||||
/* Use 125M anatop REF_CLK1 for ENET1, not from external */
|
||||
clrsetbits_le32(&gpr->gpr[1], BIT(13) | BIT(17), 0);
|
||||
return set_clk_enet(ENET_125MHZ);
|
||||
}
|
||||
|
||||
int board_phy_config(struct phy_device *phydev)
|
||||
{
|
||||
/* enable rgmii rxc skew and phy mode select to RGMII copper */
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f);
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8);
|
||||
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05);
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100);
|
||||
|
||||
if (phydev->drv->config)
|
||||
phydev->drv->config(phydev);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
#ifdef CONFIG_FEC_MXC
|
||||
setup_fec();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_mmc_get_env_dev(int devno)
|
||||
{
|
||||
return devno;
|
||||
}
|
||||
|
||||
int board_late_init(void)
|
||||
{
|
||||
#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
|
||||
env_set("board_rev", "iMX8MQ");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
223
board/technexion/pico-imx8mq/spl.c
Normal file
223
board/technexion/pico-imx8mq/spl.c
Normal file
|
@ -0,0 +1,223 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2018 NXP
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <hang.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/ddr.h>
|
||||
#include <asm/arch/imx8mq_pins.h>
|
||||
#include <asm/arch/sys_proto.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/mach-imx/gpio.h>
|
||||
#include <asm/mach-imx/iomux-v3.h>
|
||||
#include <asm/mach-imx/mxc_i2c.h>
|
||||
#include <errno.h>
|
||||
#include <fsl_esdhc_imx.h>
|
||||
#include <mmc.h>
|
||||
#include <spl.h>
|
||||
|
||||
#include "lpddr4_timing.h"
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define DDR_DET_1 IMX_GPIO_NR(3, 11)
|
||||
#define DDR_DET_2 IMX_GPIO_NR(3, 12)
|
||||
#define DDR_DET_3 IMX_GPIO_NR(3, 13)
|
||||
|
||||
static iomux_v3_cfg_t const verdet_pads[] = {
|
||||
IMX8MQ_PAD_NAND_DATA01__GPIO3_IO7 | MUX_PAD_CTRL(NO_PAD_CTRL),
|
||||
IMX8MQ_PAD_NAND_DATA02__GPIO3_IO8 | MUX_PAD_CTRL(NO_PAD_CTRL),
|
||||
IMX8MQ_PAD_NAND_DATA03__GPIO3_IO9 | MUX_PAD_CTRL(NO_PAD_CTRL),
|
||||
IMX8MQ_PAD_NAND_DATA04__GPIO3_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL),
|
||||
IMX8MQ_PAD_NAND_DATA05__GPIO3_IO11 | MUX_PAD_CTRL(NO_PAD_CTRL),
|
||||
IMX8MQ_PAD_NAND_DATA06__GPIO3_IO12 | MUX_PAD_CTRL(NO_PAD_CTRL),
|
||||
IMX8MQ_PAD_NAND_DATA07__GPIO3_IO13 | MUX_PAD_CTRL(NO_PAD_CTRL),
|
||||
};
|
||||
|
||||
/*
|
||||
* DDR_DET_1 DDR_DET_2 DDR_DET_3
|
||||
* 0 0 1 4G LPDDR4
|
||||
* 1 1 1 3G LPDDR4
|
||||
* 1 1 0 2G LPDDR4
|
||||
* 1 0 1 1G LPDDR4
|
||||
*/
|
||||
static void spl_dram_init(void)
|
||||
{
|
||||
struct dram_timing_info *dram_timing;
|
||||
u8 ddr = 0, size;
|
||||
|
||||
imx_iomux_v3_setup_multiple_pads(verdet_pads, ARRAY_SIZE(verdet_pads));
|
||||
|
||||
gpio_request(DDR_DET_1, "ddr_det_1");
|
||||
gpio_direction_input(DDR_DET_1);
|
||||
gpio_request(DDR_DET_2, "ddr_det_2");
|
||||
gpio_direction_input(DDR_DET_2);
|
||||
gpio_request(DDR_DET_3, "ddr_det_3");
|
||||
gpio_direction_input(DDR_DET_3);
|
||||
|
||||
ddr |= !!gpio_get_value(DDR_DET_3) << 0;
|
||||
ddr |= !!gpio_get_value(DDR_DET_2) << 1;
|
||||
ddr |= !!gpio_get_value(DDR_DET_1) << 2;
|
||||
|
||||
switch (ddr) {
|
||||
case 0x1:
|
||||
size = 4;
|
||||
dram_timing = &dram_timing_4gb;
|
||||
break;
|
||||
case 0x7:
|
||||
size = 3;
|
||||
dram_timing = &dram_timing_3gb;
|
||||
break;
|
||||
case 0x6:
|
||||
size = 2;
|
||||
dram_timing = &dram_timing_2gb;
|
||||
break;
|
||||
case 0x5:
|
||||
size = 1;
|
||||
dram_timing = &dram_timing_1gb;
|
||||
break;
|
||||
default:
|
||||
puts("Unknown DDR type!!!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("%s: LPDDR4 %d GiB\n", __func__, size);
|
||||
ddr_init(dram_timing);
|
||||
writel(size, M4_BOOTROM_BASE_ADDR);
|
||||
}
|
||||
|
||||
#define USDHC2_CD_GPIO IMX_GPIO_NR(2, 12)
|
||||
#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 = !gpio_get_value(USDHC2_CD_GPIO);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define USDHC_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_HYS | PAD_CTL_PUE | \
|
||||
PAD_CTL_FSEL2)
|
||||
#define USDHC_GPIO_PAD_CTRL (PAD_CTL_PUE | PAD_CTL_DSE1)
|
||||
|
||||
static iomux_v3_cfg_t const 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 iomux_v3_cfg_t const usdhc2_pads[] = {
|
||||
IMX8MQ_PAD_SD2_CLK__USDHC2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
|
||||
IMX8MQ_PAD_SD2_CMD__USDHC2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
|
||||
IMX8MQ_PAD_SD2_DATA0__USDHC2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
|
||||
IMX8MQ_PAD_SD2_DATA1__USDHC2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
|
||||
IMX8MQ_PAD_SD2_DATA2__USDHC2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
|
||||
IMX8MQ_PAD_SD2_DATA3__USDHC2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
|
||||
IMX8MQ_PAD_SD2_CD_B__GPIO2_IO12 | MUX_PAD_CTRL(USDHC_GPIO_PAD_CTRL),
|
||||
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(bd_t *bis)
|
||||
{
|
||||
int ret;
|
||||
/*
|
||||
* According to the board_mmc_init() the following map is done:
|
||||
* (U-Boot device node) (Physical Port)
|
||||
* mmc0 USDHC1
|
||||
* mmc1 USDHC2
|
||||
*/
|
||||
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);
|
||||
ret = fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
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);
|
||||
return fsl_esdhc_initialize(bis, &usdhc_cfg[1]);
|
||||
}
|
||||
|
||||
void spl_board_init(void)
|
||||
{
|
||||
puts("Normal Boot\n");
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SPL_LOAD_FIT
|
||||
int board_fit_config_name_match(const char *name)
|
||||
{
|
||||
/* Just empty function now - can't decide what to choose */
|
||||
debug("%s: %s\n", __func__, name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void board_init_f(ulong dummy)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Clear global data */
|
||||
memset((void *)gd, 0, sizeof(gd_t));
|
||||
|
||||
arch_cpu_init();
|
||||
|
||||
init_uart_clk(0);
|
||||
|
||||
board_early_init_f();
|
||||
|
||||
timer_init();
|
||||
|
||||
preloader_console_init();
|
||||
|
||||
/* Clear the BSS. */
|
||||
memset(__bss_start, 0, __bss_end - __bss_start);
|
||||
|
||||
ret = spl_init();
|
||||
if (ret) {
|
||||
debug("spl_init() failed: %d\n", ret);
|
||||
hang();
|
||||
}
|
||||
|
||||
enable_tzc380();
|
||||
|
||||
/* DDR initialization */
|
||||
spl_dram_init();
|
||||
|
||||
board_init_r(NULL, 0);
|
||||
}
|
|
@ -183,11 +183,11 @@ static int print_cpuinfo(void)
|
|||
char desc[512];
|
||||
int ret;
|
||||
|
||||
ret = uclass_first_device_err(UCLASS_CPU, &dev);
|
||||
if (ret) {
|
||||
debug("%s: Could not get CPU device (err = %d)\n",
|
||||
__func__, ret);
|
||||
return ret;
|
||||
dev = cpu_get_current_dev();
|
||||
if (!dev) {
|
||||
debug("%s: Could not get CPU device\n",
|
||||
__func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = cpu_get_desc(dev, desc, sizeof(desc));
|
||||
|
|
|
@ -1172,6 +1172,14 @@ config SPL_USB_SDP_SUPPORT
|
|||
Enable Serial Download Protocol (SDP) device support in SPL. This
|
||||
allows to download images into memory and execute (jump to) them
|
||||
using the same protocol as implemented by the i.MX family's boot ROM.
|
||||
|
||||
config SPL_SDP_USB_DEV
|
||||
int "SDP USB controller index"
|
||||
default 0
|
||||
depends on SPL_USB_SDP_SUPPORT
|
||||
help
|
||||
Some boards have USB controller other than 0. Define this option
|
||||
so it can be used in compiled environment.
|
||||
endif
|
||||
|
||||
config SPL_WATCHDOG_SUPPORT
|
||||
|
|
|
@ -14,7 +14,9 @@ static int spl_sdp_load_image(struct spl_image_info *spl_image,
|
|||
struct spl_boot_device *bootdev)
|
||||
{
|
||||
int ret;
|
||||
const int controller_index = 0;
|
||||
const int controller_index = CONFIG_SPL_SDP_USB_DEV;
|
||||
|
||||
usb_gadget_initialize(controller_index);
|
||||
|
||||
g_dnl_clear_detach();
|
||||
ret = g_dnl_register("usb_dnl_sdp");
|
||||
|
@ -37,6 +39,7 @@ static int spl_sdp_load_image(struct spl_image_info *spl_image,
|
|||
ret = spl_sdp_handle(controller_index, spl_image);
|
||||
debug("SDP ended\n");
|
||||
|
||||
usb_gadget_release(controller_index);
|
||||
return ret;
|
||||
}
|
||||
SPL_LOAD_IMAGE_METHOD("USB SDP", 0, BOOT_DEVICE_BOARD, spl_sdp_load_image);
|
||||
|
|
104
configs/imx8mm_beacon_defconfig
Normal file
104
configs/imx8mm_beacon_defconfig
Normal file
|
@ -0,0 +1,104 @@
|
|||
CONFIG_ARM=y
|
||||
CONFIG_ARCH_IMX8M=y
|
||||
CONFIG_SYS_TEXT_BASE=0x40200000
|
||||
CONFIG_SPL_GPIO_SUPPORT=y
|
||||
CONFIG_SPL_LIBCOMMON_SUPPORT=y
|
||||
CONFIG_SPL_LIBGENERIC_SUPPORT=y
|
||||
CONFIG_SYS_MALLOC_F_LEN=0x10000
|
||||
CONFIG_ENV_SIZE=0x1000
|
||||
CONFIG_ENV_OFFSET=0x400000
|
||||
CONFIG_SYS_I2C_MXC_I2C1=y
|
||||
CONFIG_SYS_I2C_MXC_I2C2=y
|
||||
CONFIG_SYS_I2C_MXC_I2C3=y
|
||||
CONFIG_DM_GPIO=y
|
||||
CONFIG_TARGET_IMX8MM_BEACON=y
|
||||
CONFIG_SPL_MMC_SUPPORT=y
|
||||
CONFIG_SPL_SERIAL_SUPPORT=y
|
||||
CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
|
||||
CONFIG_SPL=y
|
||||
CONFIG_SPL_TEXT_BASE=0x7E1000
|
||||
CONFIG_FIT=y
|
||||
CONFIG_FIT_EXTERNAL_OFFSET=0x3000
|
||||
CONFIG_SPL_LOAD_FIT=y
|
||||
CONFIG_SPL_FIT_GENERATOR="arch/arm/mach-imx/mkimage_fit_atf.sh"
|
||||
CONFIG_OF_SYSTEM_SETUP=y
|
||||
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/imx8m/imximage-8mm-lpddr4.cfg"
|
||||
CONFIG_DEFAULT_FDT_FILE="imx8mm-beacon-kit.dtb"
|
||||
CONFIG_SPL_BOARD_INIT=y
|
||||
CONFIG_SPL_SEPARATE_BSS=y
|
||||
CONFIG_SPL_I2C_SUPPORT=y
|
||||
CONFIG_SPL_POWER_SUPPORT=y
|
||||
CONFIG_SPL_WATCHDOG_SUPPORT=y
|
||||
CONFIG_HUSH_PARSER=y
|
||||
CONFIG_SYS_PROMPT="u-boot=> "
|
||||
# CONFIG_CMD_EXPORTENV is not set
|
||||
# CONFIG_CMD_IMPORTENV is not set
|
||||
# CONFIG_CMD_CRC32 is not set
|
||||
CONFIG_CMD_CLK=y
|
||||
CONFIG_CMD_FUSE=y
|
||||
CONFIG_CMD_GPIO=y
|
||||
CONFIG_CMD_I2C=y
|
||||
CONFIG_CMD_MMC=y
|
||||
CONFIG_CMD_PART=y
|
||||
CONFIG_CMD_DHCP=y
|
||||
CONFIG_CMD_MII=y
|
||||
CONFIG_CMD_PING=y
|
||||
CONFIG_CMD_CACHE=y
|
||||
CONFIG_CMD_PMIC=y
|
||||
CONFIG_CMD_REGULATOR=y
|
||||
CONFIG_CMD_EXT2=y
|
||||
CONFIG_CMD_EXT4=y
|
||||
CONFIG_CMD_EXT4_WRITE=y
|
||||
CONFIG_CMD_FAT=y
|
||||
CONFIG_OF_CONTROL=y
|
||||
CONFIG_SPL_OF_CONTROL=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="imx8mm-beacon-kit"
|
||||
CONFIG_ENV_IS_IN_MMC=y
|
||||
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
|
||||
CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
|
||||
CONFIG_NET_RANDOM_ETHADDR=y
|
||||
CONFIG_SPL_DM=y
|
||||
CONFIG_SPL_CLK_COMPOSITE_CCF=y
|
||||
CONFIG_CLK_COMPOSITE_CCF=y
|
||||
CONFIG_SPL_CLK_IMX8MM=y
|
||||
CONFIG_CLK_IMX8MM=y
|
||||
CONFIG_MXC_GPIO=y
|
||||
CONFIG_DM_PCA953X=y
|
||||
CONFIG_DM_I2C=y
|
||||
CONFIG_SYS_I2C_MXC=y
|
||||
CONFIG_DM_MMC=y
|
||||
CONFIG_SUPPORT_EMMC_BOOT=y
|
||||
CONFIG_FSL_USDHC=y
|
||||
CONFIG_PHYLIB=y
|
||||
CONFIG_PHY_ATHEROS=y
|
||||
CONFIG_DM_ETH=y
|
||||
CONFIG_PHY_GIGE=y
|
||||
CONFIG_FEC_MXC=y
|
||||
CONFIG_MII=y
|
||||
CONFIG_PINCTRL=y
|
||||
CONFIG_SPL_PINCTRL=y
|
||||
CONFIG_PINCTRL_IMX8M=y
|
||||
CONFIG_DM_PMIC=y
|
||||
CONFIG_DM_PMIC_BD71837=y
|
||||
CONFIG_SPL_DM_PMIC_BD71837=y
|
||||
CONFIG_DM_REGULATOR=y
|
||||
CONFIG_SPL_DM_REGULATOR=y
|
||||
CONFIG_DM_REGULATOR_BD71837=y
|
||||
CONFIG_SPL_DM_REGULATOR_BD71837=y
|
||||
CONFIG_DM_REGULATOR_FIXED=y
|
||||
CONFIG_DM_REGULATOR_GPIO=y
|
||||
CONFIG_CONS_INDEX=2
|
||||
CONFIG_DM_SERIAL=y
|
||||
# CONFIG_SPL_DM_SERIAL is not set
|
||||
CONFIG_MXC_UART=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_DM_SPI=y
|
||||
CONFIG_SPI_MEM=y
|
||||
CONFIG_NXP_FSPI=y
|
||||
CONFIG_SYSRESET=y
|
||||
CONFIG_SPL_SYSRESET=y
|
||||
CONFIG_SYSRESET_PSCI=y
|
||||
CONFIG_SYSRESET_WATCHDOG=y
|
||||
CONFIG_DM_THERMAL=y
|
||||
# CONFIG_WATCHDOG is not set
|
||||
CONFIG_IMX_WATCHDOG=y
|
|
@ -1,6 +1,4 @@
|
|||
CONFIG_ARM=y
|
||||
CONFIG_SPL_SYS_ICACHE_OFF=y
|
||||
CONFIG_SPL_SYS_DCACHE_OFF=y
|
||||
CONFIG_ARCH_IMX8M=y
|
||||
CONFIG_SYS_TEXT_BASE=0x40200000
|
||||
CONFIG_SYS_MALLOC_F_LEN=0x4000
|
||||
|
|
47
configs/pico-imx8mq_defconfig
Normal file
47
configs/pico-imx8mq_defconfig
Normal file
|
@ -0,0 +1,47 @@
|
|||
CONFIG_ARM=y
|
||||
CONFIG_ARCH_IMX8M=y
|
||||
CONFIG_SYS_TEXT_BASE=0x40200000
|
||||
CONFIG_ENV_SIZE=0x1000
|
||||
CONFIG_ENV_OFFSET=0x400000
|
||||
CONFIG_DM_GPIO=y
|
||||
CONFIG_TARGET_PICO_IMX8MQ=y
|
||||
CONFIG_SPL_SERIAL_SUPPORT=y
|
||||
CONFIG_SPL=y
|
||||
CONFIG_CSF_SIZE=0x2000
|
||||
CONFIG_SPL_TEXT_BASE=0x7E1000
|
||||
CONFIG_FIT=y
|
||||
CONFIG_FIT_EXTERNAL_OFFSET=0x3000
|
||||
CONFIG_SPL_LOAD_FIT=y
|
||||
CONFIG_SPL_FIT_GENERATOR="arch/arm/mach-imx/mkimage_fit_atf.sh"
|
||||
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/imx8m/imximage.cfg"
|
||||
CONFIG_SPL_BOARD_INIT=y
|
||||
CONFIG_HUSH_PARSER=y
|
||||
# CONFIG_BOOTM_NETBSD is not set
|
||||
CONFIG_CMD_GPIO=y
|
||||
CONFIG_CMD_I2C=y
|
||||
CONFIG_CMD_CACHE=y
|
||||
CONFIG_CMD_REGULATOR=y
|
||||
CONFIG_CMD_EXT2=y
|
||||
CONFIG_CMD_EXT4=y
|
||||
CONFIG_CMD_EXT4_WRITE=y
|
||||
CONFIG_CMD_FAT=y
|
||||
CONFIG_OF_CONTROL=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="imx8mq-pico-pi"
|
||||
CONFIG_ENV_IS_IN_MMC=y
|
||||
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
|
||||
CONFIG_SAVED_DRAM_TIMING_BASE=0x40000000
|
||||
CONFIG_DM_I2C=y
|
||||
CONFIG_SYS_I2C_MXC=y
|
||||
CONFIG_DM_MMC=y
|
||||
CONFIG_SUPPORT_EMMC_BOOT=y
|
||||
CONFIG_FSL_USDHC=y
|
||||
CONFIG_DM_ETH=y
|
||||
CONFIG_PINCTRL=y
|
||||
CONFIG_PINCTRL_IMX8M=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_DM_RESET=y
|
||||
CONFIG_DM_THERMAL=y
|
|
@ -10,6 +10,7 @@
|
|||
#include <errno.h>
|
||||
#include <dm/lists.h>
|
||||
#include <dm/root.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
int cpu_probe_all(void)
|
||||
{
|
||||
|
@ -34,6 +35,39 @@ int cpu_probe_all(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int cpu_is_current(struct udevice *cpu)
|
||||
{
|
||||
struct cpu_ops *ops = cpu_get_ops(cpu);
|
||||
|
||||
if (ops->is_current) {
|
||||
if (ops->is_current(cpu))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
struct udevice *cpu_get_current_dev(void)
|
||||
{
|
||||
struct udevice *cpu;
|
||||
int ret;
|
||||
|
||||
uclass_foreach_dev_probe(UCLASS_CPU, cpu) {
|
||||
if (cpu_is_current(cpu) > 0)
|
||||
return cpu;
|
||||
}
|
||||
|
||||
/* If can't find current cpu device, use the first dev instead */
|
||||
ret = uclass_first_device_err(UCLASS_CPU, &cpu);
|
||||
if (ret) {
|
||||
debug("%s: Could not get CPU device (err = %d)\n",
|
||||
__func__, ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return cpu;
|
||||
}
|
||||
|
||||
int cpu_get_desc(struct udevice *dev, char *buf, int size)
|
||||
{
|
||||
struct cpu_ops *ops = cpu_get_ops(dev);
|
||||
|
|
|
@ -36,11 +36,20 @@ int cpu_sandbox_get_vendor(struct udevice *dev, char *buf, int size)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int cpu_sandbox_is_current(struct udevice *dev)
|
||||
{
|
||||
if (!strcmp(dev->name, "cpu-test1"))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct cpu_ops cpu_sandbox_ops = {
|
||||
.get_desc = cpu_sandbox_get_desc,
|
||||
.get_info = cpu_sandbox_get_info,
|
||||
.get_count = cpu_sandbox_get_count,
|
||||
.get_vendor = cpu_sandbox_get_vendor,
|
||||
.is_current = cpu_sandbox_is_current,
|
||||
};
|
||||
|
||||
int cpu_sandbox_probe(struct udevice *dev)
|
||||
|
|
|
@ -20,6 +20,7 @@ struct cpu_imx_platdata {
|
|||
const char *type;
|
||||
u32 cpurev;
|
||||
u32 freq_mhz;
|
||||
u32 mpidr;
|
||||
};
|
||||
|
||||
const char *get_imx8_type(u32 imxtype)
|
||||
|
@ -42,31 +43,35 @@ const char *get_imx8_rev(u32 rev)
|
|||
return "A";
|
||||
case CHIP_REV_B:
|
||||
return "B";
|
||||
case CHIP_REV_C:
|
||||
return "C";
|
||||
default:
|
||||
return "?";
|
||||
}
|
||||
}
|
||||
|
||||
const char *get_core_name(void)
|
||||
const char *get_core_name(struct udevice *dev)
|
||||
{
|
||||
if (is_cortex_a35())
|
||||
if (!device_is_compatible(dev, "arm,cortex-a35"))
|
||||
return "A35";
|
||||
else if (is_cortex_a53())
|
||||
else if (!device_is_compatible(dev, "arm,cortex-a53"))
|
||||
return "A53";
|
||||
else if (is_cortex_a72())
|
||||
else if (!device_is_compatible(dev, "arm,cortex-a72"))
|
||||
return "A72";
|
||||
else
|
||||
return "?";
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_IMX_SCU_THERMAL)
|
||||
static int cpu_imx_get_temp(void)
|
||||
static int cpu_imx_get_temp(struct cpu_imx_platdata *plat)
|
||||
{
|
||||
struct udevice *thermal_dev;
|
||||
int cpu_tmp, ret;
|
||||
|
||||
ret = uclass_get_device_by_name(UCLASS_THERMAL, "cpu-thermal0",
|
||||
&thermal_dev);
|
||||
if (!strcmp(plat->name, "A72"))
|
||||
ret = uclass_get_device(UCLASS_THERMAL, 1, &thermal_dev);
|
||||
else
|
||||
ret = uclass_get_device(UCLASS_THERMAL, 0, &thermal_dev);
|
||||
|
||||
if (!ret) {
|
||||
ret = thermal_get_temp(thermal_dev, &cpu_tmp);
|
||||
|
@ -79,7 +84,7 @@ static int cpu_imx_get_temp(void)
|
|||
return cpu_tmp;
|
||||
}
|
||||
#else
|
||||
static int cpu_imx_get_temp(void)
|
||||
static int cpu_imx_get_temp(struct cpu_imx_platdata *plat)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -88,7 +93,7 @@ static int cpu_imx_get_temp(void)
|
|||
int cpu_imx_get_desc(struct udevice *dev, char *buf, int size)
|
||||
{
|
||||
struct cpu_imx_platdata *plat = dev_get_platdata(dev);
|
||||
int ret;
|
||||
int ret, temp;
|
||||
|
||||
if (size < 100)
|
||||
return -ENOSPC;
|
||||
|
@ -97,9 +102,13 @@ int cpu_imx_get_desc(struct udevice *dev, char *buf, int size)
|
|||
plat->type, plat->rev, plat->name, plat->freq_mhz);
|
||||
|
||||
if (IS_ENABLED(CONFIG_IMX_SCU_THERMAL)) {
|
||||
temp = cpu_imx_get_temp(plat);
|
||||
buf = buf + ret;
|
||||
size = size - ret;
|
||||
ret = snprintf(buf, size, " at %dC", cpu_imx_get_temp());
|
||||
if (temp != 0xdeadbeef)
|
||||
ret = snprintf(buf, size, " at %dC", temp);
|
||||
else
|
||||
ret = snprintf(buf, size, " - invalid sensor data");
|
||||
}
|
||||
|
||||
snprintf(buf + ret, size - ret, "\n");
|
||||
|
@ -118,7 +127,24 @@ static int cpu_imx_get_info(struct udevice *dev, struct cpu_info *info)
|
|||
|
||||
static int cpu_imx_get_count(struct udevice *dev)
|
||||
{
|
||||
return 4;
|
||||
ofnode node;
|
||||
int num = 0;
|
||||
|
||||
ofnode_for_each_subnode(node, dev_ofnode(dev->parent)) {
|
||||
const char *device_type;
|
||||
|
||||
if (!ofnode_is_available(node))
|
||||
continue;
|
||||
|
||||
device_type = ofnode_read_string(node, "device_type");
|
||||
if (!device_type)
|
||||
continue;
|
||||
|
||||
if (!strcmp(device_type, "cpu"))
|
||||
num++;
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
static int cpu_imx_get_vendor(struct udevice *dev, char *buf, int size)
|
||||
|
@ -127,25 +153,44 @@ static int cpu_imx_get_vendor(struct udevice *dev, char *buf, int size)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cpu_imx_is_current(struct udevice *dev)
|
||||
{
|
||||
struct cpu_imx_platdata *plat = dev_get_platdata(dev);
|
||||
|
||||
if (plat->mpidr == (read_mpidr() & 0xffff))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct cpu_ops cpu_imx8_ops = {
|
||||
.get_desc = cpu_imx_get_desc,
|
||||
.get_info = cpu_imx_get_info,
|
||||
.get_count = cpu_imx_get_count,
|
||||
.get_vendor = cpu_imx_get_vendor,
|
||||
.is_current = cpu_imx_is_current,
|
||||
};
|
||||
|
||||
static const struct udevice_id cpu_imx8_ids[] = {
|
||||
{ .compatible = "arm,cortex-a35" },
|
||||
{ .compatible = "arm,cortex-a53" },
|
||||
{ .compatible = "arm,cortex-a72" },
|
||||
{ }
|
||||
};
|
||||
|
||||
static ulong imx8_get_cpu_rate(void)
|
||||
static ulong imx8_get_cpu_rate(struct udevice *dev)
|
||||
{
|
||||
ulong rate;
|
||||
int ret;
|
||||
int type = is_cortex_a35() ? SC_R_A35 : is_cortex_a53() ?
|
||||
SC_R_A53 : SC_R_A72;
|
||||
int ret, type;
|
||||
|
||||
if (!device_is_compatible(dev, "arm,cortex-a35"))
|
||||
type = SC_R_A35;
|
||||
else if (!device_is_compatible(dev, "arm,cortex-a53"))
|
||||
type = SC_R_A53;
|
||||
else if (!device_is_compatible(dev, "arm,cortex-a72"))
|
||||
type = SC_R_A72;
|
||||
else
|
||||
return 0;
|
||||
|
||||
ret = sc_pm_get_clock_rate(-1, type, SC_PM_CLK_CPU,
|
||||
(sc_pm_clock_rate_t *)&rate);
|
||||
|
@ -164,10 +209,16 @@ static int imx8_cpu_probe(struct udevice *dev)
|
|||
|
||||
cpurev = get_cpu_rev();
|
||||
plat->cpurev = cpurev;
|
||||
plat->name = get_core_name();
|
||||
plat->name = get_core_name(dev);
|
||||
plat->rev = get_imx8_rev(cpurev & 0xFFF);
|
||||
plat->type = get_imx8_type((cpurev & 0xFF000) >> 12);
|
||||
plat->freq_mhz = imx8_get_cpu_rate() / 1000000;
|
||||
plat->freq_mhz = imx8_get_cpu_rate(dev) / 1000000;
|
||||
plat->mpidr = dev_read_addr(dev);
|
||||
if (plat->mpidr == FDT_ADDR_T_NONE) {
|
||||
printf("%s: Failed to get CPU reg property\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ config TI_EDMA3
|
|||
|
||||
config APBH_DMA
|
||||
bool "Support APBH DMA"
|
||||
depends on MX23 || MX28 || MX6 || MX7
|
||||
depends on MX23 || MX28 || MX6 || MX7 || IMX8 || IMX8M
|
||||
help
|
||||
Enable APBH DMA driver.
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
*
|
||||
* Based on code from LTIB:
|
||||
* Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
* Copyright 2017 NXP
|
||||
*
|
||||
*/
|
||||
|
||||
#include <cpu_func.h>
|
||||
|
@ -88,7 +90,7 @@ void mxs_dma_flush_desc(struct mxs_dma_desc *desc)
|
|||
uint32_t addr;
|
||||
uint32_t size;
|
||||
|
||||
addr = (uint32_t)desc;
|
||||
addr = (uintptr_t)desc;
|
||||
size = roundup(sizeof(struct mxs_dma_desc), MXS_DMA_ALIGNMENT);
|
||||
|
||||
flush_dcache_range(addr, addr + size);
|
||||
|
@ -215,16 +217,17 @@ static int mxs_dma_reset(int channel)
|
|||
#if defined(CONFIG_MX23)
|
||||
uint32_t setreg = (uint32_t)(&apbh_regs->hw_apbh_ctrl0_set);
|
||||
uint32_t offset = APBH_CTRL0_RESET_CHANNEL_OFFSET;
|
||||
#elif (defined(CONFIG_MX28) || defined(CONFIG_MX6) || defined(CONFIG_MX7))
|
||||
uint32_t setreg = (uint32_t)(&apbh_regs->hw_apbh_channel_ctrl_set);
|
||||
uint32_t offset = APBH_CHANNEL_CTRL_RESET_CHANNEL_OFFSET;
|
||||
#elif defined(CONFIG_MX28) || defined(CONFIG_MX6) || defined(CONFIG_MX7) || \
|
||||
defined(CONFIG_IMX8) || defined(CONFIG_IMX8M)
|
||||
u32 setreg = (uintptr_t)(&apbh_regs->hw_apbh_channel_ctrl_set);
|
||||
u32 offset = APBH_CHANNEL_CTRL_RESET_CHANNEL_OFFSET;
|
||||
#endif
|
||||
|
||||
ret = mxs_dma_validate_chan(channel);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
writel(1 << (channel + offset), setreg);
|
||||
writel(1 << (channel + offset), (uintptr_t)setreg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <dm/device_compat.h>
|
||||
#include <linux/errno.h>
|
||||
#include <asm/mach-imx/mxc_i2c.h>
|
||||
#include <asm/mach-imx/sys_proto.h>
|
||||
#include <asm/io.h>
|
||||
#include <i2c.h>
|
||||
#include <watchdog.h>
|
||||
|
@ -747,6 +748,14 @@ void bus_i2c_init(int index, int speed, int unused,
|
|||
return;
|
||||
}
|
||||
|
||||
if (CONFIG_IS_ENABLED(IMX_MODULE_FUSE)) {
|
||||
if (i2c_fused((ulong)mxc_i2c_buses[index].base)) {
|
||||
printf("SoC fuse indicates I2C@0x%lx is unavailable.\n",
|
||||
(ulong)mxc_i2c_buses[index].base);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Warning: Be careful to allow the assignment to a static
|
||||
* variable here. This function could be called while U-Boot is
|
||||
|
@ -892,6 +901,14 @@ static int mxc_i2c_probe(struct udevice *bus)
|
|||
if (addr == FDT_ADDR_T_NONE)
|
||||
return -EINVAL;
|
||||
|
||||
if (CONFIG_IS_ENABLED(IMX_MODULE_FUSE)) {
|
||||
if (i2c_fused((ulong)addr)) {
|
||||
printf("SoC fuse indicates I2C@0x%lx is unavailable.\n",
|
||||
(ulong)addr);
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
i2c_bus->base = addr;
|
||||
i2c_bus->index = bus->seq;
|
||||
i2c_bus->bus = bus;
|
||||
|
|
|
@ -15,8 +15,13 @@ DECLARE_GLOBAL_DATA_PTR;
|
|||
#define FSL_ECC_WORD_START_1 0x10
|
||||
#define FSL_ECC_WORD_END_1 0x10F
|
||||
|
||||
#ifdef CONFIG_IMX8QM
|
||||
#define FSL_ECC_WORD_START_2 0x1A0
|
||||
#define FSL_ECC_WORD_END_2 0x1FF
|
||||
#elif defined(CONFIG_IMX8QXP)
|
||||
#define FSL_ECC_WORD_START_2 0x220
|
||||
#define FSL_ECC_WORD_END_2 0x31F
|
||||
#endif
|
||||
|
||||
#define FSL_QXP_FUSE_GAP_START 0x110
|
||||
#define FSL_QXP_FUSE_GAP_END 0x21F
|
||||
|
|
|
@ -74,7 +74,7 @@ static int mu_hal_receivemsg(struct mu_type *base, u32 reg_index, u32 *msg)
|
|||
assert(reg_index < MU_TR_COUNT);
|
||||
|
||||
/* Wait RX register to be full. */
|
||||
ret = readl_poll_timeout(&base->sr, val, val & mask, 10000);
|
||||
ret = readl_poll_timeout(&base->sr, val, val & mask, 1000000);
|
||||
if (ret < 0) {
|
||||
printf("%s timeout\n", __func__);
|
||||
return -ETIMEDOUT;
|
||||
|
|
|
@ -259,12 +259,12 @@ config NAND_MXC
|
|||
|
||||
config NAND_MXS
|
||||
bool "MXS NAND support"
|
||||
depends on MX23 || MX28 || MX6 || MX7
|
||||
depends on MX23 || MX28 || MX6 || MX7 || IMX8 || IMX8M
|
||||
select SYS_NAND_SELF_INIT
|
||||
imply CMD_NAND
|
||||
select APBH_DMA
|
||||
select APBH_DMA_BURST if ARCH_MX6 || ARCH_MX7
|
||||
select APBH_DMA_BURST8 if ARCH_MX6 || ARCH_MX7
|
||||
select APBH_DMA_BURST if ARCH_MX6 || ARCH_MX7 || ARCH_IMX8 || ARCH_IMX8M
|
||||
select APBH_DMA_BURST8 if ARCH_MX6 || ARCH_MX7 || ARCH_IMX8 || ARCH_IMX8M
|
||||
help
|
||||
This enables NAND driver for the NAND flash controller on the
|
||||
MXS processors.
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
*
|
||||
* Copyright (C) 2010 Freescale Semiconductor, Inc.
|
||||
* Copyright (C) 2008 Embedded Alley Solutions, Inc.
|
||||
* Copyright 2017-2019 NXP
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
@ -30,7 +31,8 @@
|
|||
|
||||
#define MXS_NAND_DMA_DESCRIPTOR_COUNT 4
|
||||
|
||||
#if (defined(CONFIG_MX6) || defined(CONFIG_MX7))
|
||||
#if defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8) || \
|
||||
defined(CONFIG_IMX8M)
|
||||
#define MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT 2
|
||||
#else
|
||||
#define MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT 0
|
||||
|
@ -54,21 +56,21 @@ struct nand_ecclayout fake_ecc_layout;
|
|||
#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
|
||||
static void mxs_nand_flush_data_buf(struct mxs_nand_info *info)
|
||||
{
|
||||
uint32_t addr = (uint32_t)info->data_buf;
|
||||
uint32_t addr = (uintptr_t)info->data_buf;
|
||||
|
||||
flush_dcache_range(addr, addr + info->data_buf_size);
|
||||
}
|
||||
|
||||
static void mxs_nand_inval_data_buf(struct mxs_nand_info *info)
|
||||
{
|
||||
uint32_t addr = (uint32_t)info->data_buf;
|
||||
uint32_t addr = (uintptr_t)info->data_buf;
|
||||
|
||||
invalidate_dcache_range(addr, addr + info->data_buf_size);
|
||||
}
|
||||
|
||||
static void mxs_nand_flush_cmd_buf(struct mxs_nand_info *info)
|
||||
{
|
||||
uint32_t addr = (uint32_t)info->cmd_buf;
|
||||
uint32_t addr = (uintptr_t)info->cmd_buf;
|
||||
|
||||
flush_dcache_range(addr, addr + MXS_NAND_COMMAND_BUFFER_SIZE);
|
||||
}
|
||||
|
@ -112,53 +114,32 @@ static uint32_t mxs_nand_aux_status_offset(void)
|
|||
return (MXS_NAND_METADATA_SIZE + 0x3) & ~0x3;
|
||||
}
|
||||
|
||||
static inline int mxs_nand_calc_mark_offset(struct bch_geometry *geo,
|
||||
uint32_t page_data_size)
|
||||
static inline bool mxs_nand_bbm_in_data_chunk(struct bch_geometry *geo, struct mtd_info *mtd,
|
||||
unsigned int *chunk_num)
|
||||
{
|
||||
uint32_t chunk_data_size_in_bits = geo->ecc_chunk_size * 8;
|
||||
uint32_t chunk_ecc_size_in_bits = geo->ecc_strength * geo->gf_len;
|
||||
uint32_t chunk_total_size_in_bits;
|
||||
uint32_t block_mark_chunk_number;
|
||||
uint32_t block_mark_chunk_bit_offset;
|
||||
uint32_t block_mark_bit_offset;
|
||||
unsigned int i, j;
|
||||
|
||||
chunk_total_size_in_bits =
|
||||
chunk_data_size_in_bits + chunk_ecc_size_in_bits;
|
||||
if (geo->ecc_chunk0_size != geo->ecc_chunkn_size) {
|
||||
dev_err(this->dev, "The size of chunk0 must equal to chunkn\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Compute the bit offset of the block mark within the physical page. */
|
||||
block_mark_bit_offset = page_data_size * 8;
|
||||
i = (mtd->writesize * 8 - MXS_NAND_METADATA_SIZE * 8) /
|
||||
(geo->gf_len * geo->ecc_strength +
|
||||
geo->ecc_chunkn_size * 8);
|
||||
|
||||
/* Subtract the metadata bits. */
|
||||
block_mark_bit_offset -= MXS_NAND_METADATA_SIZE * 8;
|
||||
j = (mtd->writesize * 8 - MXS_NAND_METADATA_SIZE * 8) -
|
||||
(geo->gf_len * geo->ecc_strength +
|
||||
geo->ecc_chunkn_size * 8) * i;
|
||||
|
||||
/*
|
||||
* Compute the chunk number (starting at zero) in which the block mark
|
||||
* appears.
|
||||
*/
|
||||
block_mark_chunk_number =
|
||||
block_mark_bit_offset / chunk_total_size_in_bits;
|
||||
if (j < geo->ecc_chunkn_size * 8) {
|
||||
*chunk_num = i + 1;
|
||||
dev_dbg(this->dev, "Set ecc to %d and bbm in chunk %d\n",
|
||||
geo->ecc_strength, *chunk_num);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the bit offset of the block mark within its chunk, and
|
||||
* validate it.
|
||||
*/
|
||||
block_mark_chunk_bit_offset = block_mark_bit_offset -
|
||||
(block_mark_chunk_number * chunk_total_size_in_bits);
|
||||
|
||||
if (block_mark_chunk_bit_offset > chunk_data_size_in_bits)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Now that we know the chunk number in which the block mark appears,
|
||||
* we can subtract all the ECC bits that appear before it.
|
||||
*/
|
||||
block_mark_bit_offset -=
|
||||
block_mark_chunk_number * chunk_ecc_size_in_bits;
|
||||
|
||||
geo->block_mark_byte_offset = block_mark_bit_offset >> 3;
|
||||
geo->block_mark_bit_offset = block_mark_bit_offset & 0x7;
|
||||
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline int mxs_nand_calc_ecc_layout_by_info(struct bch_geometry *geo,
|
||||
|
@ -168,6 +149,7 @@ static inline int mxs_nand_calc_ecc_layout_by_info(struct bch_geometry *geo,
|
|||
{
|
||||
struct nand_chip *chip = mtd_to_nand(mtd);
|
||||
struct mxs_nand_info *nand_info = nand_get_controller_data(chip);
|
||||
unsigned int block_mark_bit_offset;
|
||||
|
||||
switch (ecc_step) {
|
||||
case SZ_512:
|
||||
|
@ -180,45 +162,51 @@ static inline int mxs_nand_calc_ecc_layout_by_info(struct bch_geometry *geo,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
geo->ecc_chunk_size = ecc_step;
|
||||
geo->ecc_chunk0_size = ecc_step;
|
||||
geo->ecc_chunkn_size = ecc_step;
|
||||
geo->ecc_strength = round_up(ecc_strength, 2);
|
||||
|
||||
/* Keep the C >= O */
|
||||
if (geo->ecc_chunk_size < mtd->oobsize)
|
||||
if (geo->ecc_chunkn_size < mtd->oobsize)
|
||||
return -EINVAL;
|
||||
|
||||
if (geo->ecc_strength > nand_info->max_ecc_strength_supported)
|
||||
return -EINVAL;
|
||||
|
||||
geo->ecc_chunk_count = mtd->writesize / geo->ecc_chunk_size;
|
||||
geo->ecc_chunk_count = mtd->writesize / geo->ecc_chunkn_size;
|
||||
|
||||
/* For bit swap. */
|
||||
block_mark_bit_offset = mtd->writesize * 8 -
|
||||
(geo->ecc_strength * geo->gf_len * (geo->ecc_chunk_count - 1)
|
||||
+ MXS_NAND_METADATA_SIZE * 8);
|
||||
|
||||
geo->block_mark_byte_offset = block_mark_bit_offset / 8;
|
||||
geo->block_mark_bit_offset = block_mark_bit_offset % 8;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int mxs_nand_calc_ecc_layout(struct bch_geometry *geo,
|
||||
static inline int mxs_nand_legacy_calc_ecc_layout(struct bch_geometry *geo,
|
||||
struct mtd_info *mtd)
|
||||
{
|
||||
struct nand_chip *chip = mtd_to_nand(mtd);
|
||||
struct mxs_nand_info *nand_info = nand_get_controller_data(chip);
|
||||
unsigned int block_mark_bit_offset;
|
||||
|
||||
/* The default for the length of Galois Field. */
|
||||
geo->gf_len = 13;
|
||||
|
||||
/* The default for chunk size. */
|
||||
geo->ecc_chunk_size = 512;
|
||||
geo->ecc_chunk0_size = 512;
|
||||
geo->ecc_chunkn_size = 512;
|
||||
|
||||
if (geo->ecc_chunk_size < mtd->oobsize) {
|
||||
if (geo->ecc_chunkn_size < mtd->oobsize) {
|
||||
geo->gf_len = 14;
|
||||
geo->ecc_chunk_size *= 2;
|
||||
geo->ecc_chunk0_size *= 2;
|
||||
geo->ecc_chunkn_size *= 2;
|
||||
}
|
||||
|
||||
if (mtd->oobsize > geo->ecc_chunk_size) {
|
||||
printf("Not support the NAND chips whose oob size is larger then %d bytes!\n",
|
||||
geo->ecc_chunk_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
geo->ecc_chunk_count = mtd->writesize / geo->ecc_chunk_size;
|
||||
geo->ecc_chunk_count = mtd->writesize / geo->ecc_chunkn_size;
|
||||
|
||||
/*
|
||||
* Determine the ECC layout with the formula:
|
||||
|
@ -234,6 +222,84 @@ static inline int mxs_nand_calc_ecc_layout(struct bch_geometry *geo,
|
|||
geo->ecc_strength = min(round_down(geo->ecc_strength, 2),
|
||||
nand_info->max_ecc_strength_supported);
|
||||
|
||||
block_mark_bit_offset = mtd->writesize * 8 -
|
||||
(geo->ecc_strength * geo->gf_len * (geo->ecc_chunk_count - 1)
|
||||
+ MXS_NAND_METADATA_SIZE * 8);
|
||||
|
||||
geo->block_mark_byte_offset = block_mark_bit_offset / 8;
|
||||
geo->block_mark_bit_offset = block_mark_bit_offset % 8;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int mxs_nand_calc_ecc_for_large_oob(struct bch_geometry *geo,
|
||||
struct mtd_info *mtd)
|
||||
{
|
||||
struct nand_chip *chip = mtd_to_nand(mtd);
|
||||
struct mxs_nand_info *nand_info = nand_get_controller_data(chip);
|
||||
unsigned int block_mark_bit_offset;
|
||||
unsigned int max_ecc;
|
||||
unsigned int bbm_chunk;
|
||||
unsigned int i;
|
||||
|
||||
/* sanity check for the minimum ecc nand required */
|
||||
if (!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0))
|
||||
return -EINVAL;
|
||||
geo->ecc_strength = chip->ecc_strength_ds;
|
||||
|
||||
/* calculate the maximum ecc platform can support*/
|
||||
geo->gf_len = 14;
|
||||
geo->ecc_chunk0_size = 1024;
|
||||
geo->ecc_chunkn_size = 1024;
|
||||
geo->ecc_chunk_count = mtd->writesize / geo->ecc_chunkn_size;
|
||||
max_ecc = ((mtd->oobsize - MXS_NAND_METADATA_SIZE) * 8)
|
||||
/ (geo->gf_len * geo->ecc_chunk_count);
|
||||
max_ecc = min(round_down(max_ecc, 2),
|
||||
nand_info->max_ecc_strength_supported);
|
||||
|
||||
|
||||
/* search a supported ecc strength that makes bbm */
|
||||
/* located in data chunk */
|
||||
geo->ecc_strength = chip->ecc_strength_ds;
|
||||
while (!(geo->ecc_strength > max_ecc)) {
|
||||
if (mxs_nand_bbm_in_data_chunk(geo, mtd, &bbm_chunk))
|
||||
break;
|
||||
geo->ecc_strength += 2;
|
||||
}
|
||||
|
||||
/* if none of them works, keep using the minimum ecc */
|
||||
/* nand required but changing ecc page layout */
|
||||
if (geo->ecc_strength > max_ecc) {
|
||||
geo->ecc_strength = chip->ecc_strength_ds;
|
||||
/* add extra ecc for meta data */
|
||||
geo->ecc_chunk0_size = 0;
|
||||
geo->ecc_chunk_count = (mtd->writesize / geo->ecc_chunkn_size) + 1;
|
||||
geo->ecc_for_meta = 1;
|
||||
/* check if oob can afford this extra ecc chunk */
|
||||
if (mtd->oobsize * 8 < MXS_NAND_METADATA_SIZE * 8 +
|
||||
geo->gf_len * geo->ecc_strength
|
||||
* geo->ecc_chunk_count) {
|
||||
printf("unsupported NAND chip with new layout\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* calculate in which chunk bbm located */
|
||||
bbm_chunk = (mtd->writesize * 8 - MXS_NAND_METADATA_SIZE * 8 -
|
||||
geo->gf_len * geo->ecc_strength) /
|
||||
(geo->gf_len * geo->ecc_strength +
|
||||
geo->ecc_chunkn_size * 8) + 1;
|
||||
}
|
||||
|
||||
/* calculate the number of ecc chunk behind the bbm */
|
||||
i = (mtd->writesize / geo->ecc_chunkn_size) - bbm_chunk + 1;
|
||||
|
||||
block_mark_bit_offset = mtd->writesize * 8 -
|
||||
(geo->ecc_strength * geo->gf_len * (geo->ecc_chunk_count - i)
|
||||
+ MXS_NAND_METADATA_SIZE * 8);
|
||||
|
||||
geo->block_mark_byte_offset = block_mark_bit_offset / 8;
|
||||
geo->block_mark_bit_offset = block_mark_bit_offset % 8;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -548,6 +614,45 @@ static uint8_t mxs_nand_read_byte(struct mtd_info *mtd)
|
|||
return buf;
|
||||
}
|
||||
|
||||
static bool mxs_nand_erased_page(struct mtd_info *mtd, struct nand_chip *nand,
|
||||
u8 *buf, int chunk, int page)
|
||||
{
|
||||
struct mxs_nand_info *nand_info = nand_get_controller_data(nand);
|
||||
struct bch_geometry *geo = &nand_info->bch_geometry;
|
||||
unsigned int flip_bits = 0, flip_bits_noecc = 0;
|
||||
unsigned int threshold;
|
||||
unsigned int base = geo->ecc_chunkn_size * chunk;
|
||||
u32 *dma_buf = (u32 *)buf;
|
||||
int i;
|
||||
|
||||
threshold = geo->gf_len / 2;
|
||||
if (threshold > geo->ecc_strength)
|
||||
threshold = geo->ecc_strength;
|
||||
|
||||
for (i = 0; i < geo->ecc_chunkn_size; i++) {
|
||||
flip_bits += hweight8(~buf[base + i]);
|
||||
if (flip_bits > threshold)
|
||||
return false;
|
||||
}
|
||||
|
||||
nand->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
|
||||
nand->read_buf(mtd, buf, mtd->writesize);
|
||||
|
||||
for (i = 0; i < mtd->writesize / 4; i++) {
|
||||
flip_bits_noecc += hweight32(~dma_buf[i]);
|
||||
if (flip_bits_noecc > threshold)
|
||||
return false;
|
||||
}
|
||||
|
||||
mtd->ecc_stats.corrected += flip_bits;
|
||||
|
||||
memset(buf, 0xff, mtd->writesize);
|
||||
|
||||
printf("The page(%d) is an erased page(%d,%d,%d,%d).\n", page, chunk, threshold, flip_bits, flip_bits_noecc);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a page from NAND.
|
||||
*/
|
||||
|
@ -557,11 +662,13 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand,
|
|||
{
|
||||
struct mxs_nand_info *nand_info = nand_get_controller_data(nand);
|
||||
struct bch_geometry *geo = &nand_info->bch_geometry;
|
||||
struct mxs_bch_regs *bch_regs = nand_info->bch_regs;
|
||||
struct mxs_dma_desc *d;
|
||||
uint32_t channel = MXS_DMA_CHANNEL_AHB_APBH_GPMI0 + nand_info->cur_chip;
|
||||
uint32_t corrected = 0, failed = 0;
|
||||
uint8_t *status;
|
||||
int i, ret;
|
||||
int flag = 0;
|
||||
|
||||
/* Compile the DMA descriptor - wait for ready. */
|
||||
d = mxs_nand_get_dma_desc(nand_info);
|
||||
|
@ -603,6 +710,12 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand,
|
|||
d->cmd.pio_words[4] = (dma_addr_t)nand_info->data_buf;
|
||||
d->cmd.pio_words[5] = (dma_addr_t)nand_info->oob_buf;
|
||||
|
||||
if (nand_info->en_randomizer) {
|
||||
d->cmd.pio_words[2] |= GPMI_ECCCTRL_RANDOMIZER_ENABLE |
|
||||
GPMI_ECCCTRL_RANDOMIZER_TYPE2;
|
||||
d->cmd.pio_words[3] |= (page % 256) << 16;
|
||||
}
|
||||
|
||||
mxs_dma_desc_append(channel, d);
|
||||
|
||||
/* Compile the DMA descriptor - disable the BCH block. */
|
||||
|
@ -651,6 +764,8 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand,
|
|||
goto rtn;
|
||||
}
|
||||
|
||||
mxs_nand_return_dma_descs(nand_info);
|
||||
|
||||
/* Invalidate caches */
|
||||
mxs_nand_inval_data_buf(nand_info);
|
||||
|
||||
|
@ -663,10 +778,19 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand,
|
|||
if (status[i] == 0x00)
|
||||
continue;
|
||||
|
||||
if (status[i] == 0xff)
|
||||
if (status[i] == 0xff) {
|
||||
if (!nand_info->en_randomizer &&
|
||||
(is_mx6dqp() || is_mx7() || is_mx6ul() ||
|
||||
is_imx8() || is_imx8m()))
|
||||
if (readl(&bch_regs->hw_bch_debug1))
|
||||
flag = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (status[i] == 0xfe) {
|
||||
if (mxs_nand_erased_page(mtd, nand,
|
||||
nand_info->data_buf, i, page))
|
||||
break;
|
||||
failed++;
|
||||
continue;
|
||||
}
|
||||
|
@ -693,6 +817,8 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand,
|
|||
|
||||
memcpy(buf, nand_info->data_buf, mtd->writesize);
|
||||
|
||||
if (flag)
|
||||
memset(buf, 0xff, mtd->writesize);
|
||||
rtn:
|
||||
mxs_nand_return_dma_descs(nand_info);
|
||||
|
||||
|
@ -741,7 +867,7 @@ static int mxs_nand_ecc_write_page(struct mtd_info *mtd,
|
|||
d->cmd.pio_words[4] = (dma_addr_t)nand_info->data_buf;
|
||||
d->cmd.pio_words[5] = (dma_addr_t)nand_info->oob_buf;
|
||||
|
||||
if (is_mx7() && nand_info->en_randomizer) {
|
||||
if (nand_info->en_randomizer) {
|
||||
d->cmd.pio_words[2] |= GPMI_ECCCTRL_RANDOMIZER_ENABLE |
|
||||
GPMI_ECCCTRL_RANDOMIZER_TYPE2;
|
||||
/*
|
||||
|
@ -751,7 +877,7 @@ static int mxs_nand_ecc_write_page(struct mtd_info *mtd,
|
|||
* The value is between 0-255. For additional details
|
||||
* check 9.6.6.4 of i.MX7D Applications Processor reference
|
||||
*/
|
||||
d->cmd.pio_words[3] |= (page % 255) << 16;
|
||||
d->cmd.pio_words[3] |= (page % 256) << 16;
|
||||
}
|
||||
|
||||
mxs_dma_desc_append(channel, d);
|
||||
|
@ -983,19 +1109,24 @@ static int mxs_nand_set_geometry(struct mtd_info *mtd, struct bch_geometry *geo)
|
|||
struct nand_chip *nand = mtd_to_nand(mtd);
|
||||
struct mxs_nand_info *nand_info = nand_get_controller_data(nand);
|
||||
|
||||
if (chip->ecc.strength > 0 && chip->ecc.size > 0)
|
||||
return mxs_nand_calc_ecc_layout_by_info(geo, mtd,
|
||||
chip->ecc.strength, chip->ecc.size);
|
||||
|
||||
if (nand_info->use_minimum_ecc ||
|
||||
mxs_nand_calc_ecc_layout(geo, mtd)) {
|
||||
if (!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0))
|
||||
return -EINVAL;
|
||||
|
||||
return mxs_nand_calc_ecc_layout_by_info(geo, mtd,
|
||||
chip->ecc_strength_ds, chip->ecc_step_ds);
|
||||
if (chip->ecc_strength_ds > nand_info->max_ecc_strength_supported) {
|
||||
printf("unsupported NAND chip, minimum ecc required %d\n"
|
||||
, chip->ecc_strength_ds);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0) &&
|
||||
mtd->oobsize < 1024) || nand_info->legacy_bch_geometry) {
|
||||
dev_warn(this->dev, "use legacy bch geometry\n");
|
||||
return mxs_nand_legacy_calc_ecc_layout(geo, mtd);
|
||||
}
|
||||
|
||||
if (mtd->oobsize > 1024 || chip->ecc_step_ds < mtd->oobsize)
|
||||
return mxs_nand_calc_ecc_for_large_oob(geo, mtd);
|
||||
|
||||
return mxs_nand_calc_ecc_layout_by_info(geo, mtd,
|
||||
chip->ecc_strength_ds, chip->ecc_step_ds);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1025,8 +1156,6 @@ int mxs_nand_setup_ecc(struct mtd_info *mtd)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
mxs_nand_calc_mark_offset(geo, mtd->writesize);
|
||||
|
||||
/* Configure BCH and set NFC geometry */
|
||||
mxs_reset_block(&bch_regs->hw_bch_ctrl_reg);
|
||||
|
||||
|
@ -1034,7 +1163,7 @@ int mxs_nand_setup_ecc(struct mtd_info *mtd)
|
|||
tmp = (geo->ecc_chunk_count - 1) << BCH_FLASHLAYOUT0_NBLOCKS_OFFSET;
|
||||
tmp |= MXS_NAND_METADATA_SIZE << BCH_FLASHLAYOUT0_META_SIZE_OFFSET;
|
||||
tmp |= (geo->ecc_strength >> 1) << BCH_FLASHLAYOUT0_ECC0_OFFSET;
|
||||
tmp |= geo->ecc_chunk_size >> MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT;
|
||||
tmp |= geo->ecc_chunk0_size >> MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT;
|
||||
tmp |= (geo->gf_len == 14 ? 1 : 0) <<
|
||||
BCH_FLASHLAYOUT0_GF13_0_GF14_1_OFFSET;
|
||||
writel(tmp, &bch_regs->hw_bch_flash0layout0);
|
||||
|
@ -1043,12 +1172,18 @@ int mxs_nand_setup_ecc(struct mtd_info *mtd)
|
|||
tmp = (mtd->writesize + mtd->oobsize)
|
||||
<< BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET;
|
||||
tmp |= (geo->ecc_strength >> 1) << BCH_FLASHLAYOUT1_ECCN_OFFSET;
|
||||
tmp |= geo->ecc_chunk_size >> MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT;
|
||||
tmp |= geo->ecc_chunkn_size >> MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT;
|
||||
tmp |= (geo->gf_len == 14 ? 1 : 0) <<
|
||||
BCH_FLASHLAYOUT1_GF13_0_GF14_1_OFFSET;
|
||||
writel(tmp, &bch_regs->hw_bch_flash0layout1);
|
||||
nand_info->bch_flash0layout1 = tmp;
|
||||
|
||||
/* Set erase threshold to ecc strength for mx6ul, mx6qp and mx7 */
|
||||
if (is_mx6dqp() || is_mx7() ||
|
||||
is_mx6ul() || is_imx8() || is_imx8m())
|
||||
writel(BCH_MODE_ERASE_THRESHOLD(geo->ecc_strength),
|
||||
&bch_regs->hw_bch_mode);
|
||||
|
||||
/* Set *all* chip selects to use layout 0 */
|
||||
writel(0, &bch_regs->hw_bch_layoutselect);
|
||||
|
||||
|
@ -1184,7 +1319,7 @@ int mxs_nand_init_spl(struct nand_chip *nand)
|
|||
nand_info->gpmi_regs = (struct mxs_gpmi_regs *)MXS_GPMI_BASE;
|
||||
nand_info->bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE;
|
||||
|
||||
if (is_mx6sx() || is_mx7())
|
||||
if (is_mx6sx() || is_mx7() || is_imx8() || is_imx8m())
|
||||
nand_info->max_ecc_strength_supported = 62;
|
||||
else
|
||||
nand_info->max_ecc_strength_supported = 40;
|
||||
|
@ -1268,7 +1403,7 @@ int mxs_nand_init_ctrl(struct mxs_nand_info *nand_info)
|
|||
|
||||
nand->ecc.layout = &fake_ecc_layout;
|
||||
nand->ecc.mode = NAND_ECC_HW;
|
||||
nand->ecc.size = nand_info->bch_geometry.ecc_chunk_size;
|
||||
nand->ecc.size = nand_info->bch_geometry.ecc_chunkn_size;
|
||||
nand->ecc.strength = nand_info->bch_geometry.ecc_strength;
|
||||
|
||||
/* second phase scan */
|
||||
|
@ -1347,12 +1482,14 @@ void mxs_nand_get_layout(struct mtd_info *mtd, struct mxs_nand_layout *l)
|
|||
BCH_FLASHLAYOUT1_DATAN_SIZE_OFFSET);
|
||||
l->eccn = (tmp & BCH_FLASHLAYOUT1_ECCN_MASK) >>
|
||||
BCH_FLASHLAYOUT1_ECCN_OFFSET;
|
||||
l->gf_len = (tmp & BCH_FLASHLAYOUT1_GF13_0_GF14_1_MASK) >>
|
||||
BCH_FLASHLAYOUT1_GF13_0_GF14_1_OFFSET;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set BCH to specific layout used by ROM bootloader to read FCB.
|
||||
*/
|
||||
void mxs_nand_mode_fcb(struct mtd_info *mtd)
|
||||
void mxs_nand_mode_fcb_62bit(struct mtd_info *mtd)
|
||||
{
|
||||
u32 tmp;
|
||||
struct mxs_bch_regs *bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE;
|
||||
|
@ -1385,6 +1522,43 @@ void mxs_nand_mode_fcb(struct mtd_info *mtd)
|
|||
writel(tmp, &bch_regs->hw_bch_flash0layout1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set BCH to specific layout used by ROM bootloader to read FCB.
|
||||
*/
|
||||
void mxs_nand_mode_fcb_40bit(struct mtd_info *mtd)
|
||||
{
|
||||
u32 tmp;
|
||||
struct mxs_bch_regs *bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE;
|
||||
struct nand_chip *nand = mtd_to_nand(mtd);
|
||||
struct mxs_nand_info *nand_info = nand_get_controller_data(nand);
|
||||
|
||||
/* no randomizer in this setting*/
|
||||
nand_info->en_randomizer = 0;
|
||||
|
||||
mtd->writesize = 1024;
|
||||
mtd->oobsize = 1576 - 1024;
|
||||
|
||||
/* 8 ecc_chunks_*/
|
||||
tmp = 7 << BCH_FLASHLAYOUT0_NBLOCKS_OFFSET;
|
||||
/* 32 bytes for metadata */
|
||||
tmp |= 32 << BCH_FLASHLAYOUT0_META_SIZE_OFFSET;
|
||||
/* using ECC40 level to be performed */
|
||||
tmp |= 0x14 << BCH_FLASHLAYOUT0_ECC0_OFFSET;
|
||||
/* 0x20 * 4 bytes of the data0 block */
|
||||
tmp |= 0x20 << BCH_FLASHLAYOUT0_DATA0_SIZE_OFFSET;
|
||||
tmp |= 0 << BCH_FLASHLAYOUT0_GF13_0_GF14_1_OFFSET;
|
||||
writel(tmp, &bch_regs->hw_bch_flash0layout0);
|
||||
|
||||
/* 1024 for data + 552 for OOB */
|
||||
tmp = 1576 << BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET;
|
||||
/* using ECC40 level to be performed */
|
||||
tmp |= 0x14 << BCH_FLASHLAYOUT1_ECCN_OFFSET;
|
||||
/* 0x20 * 4 bytes of the data0 block */
|
||||
tmp |= 0x20 << BCH_FLASHLAYOUT1_DATAN_SIZE_OFFSET;
|
||||
tmp |= 0 << BCH_FLASHLAYOUT1_GF13_0_GF14_1_OFFSET;
|
||||
writel(tmp, &bch_regs->hw_bch_flash0layout1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Restore BCH to normal settings.
|
||||
*/
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
* NXP GPMI NAND flash driver (DT initialization)
|
||||
*
|
||||
* Copyright (C) 2018 Toradex
|
||||
* Copyright 2019 NXP
|
||||
*
|
||||
* Authors:
|
||||
* Stefan Agner <stefan.agner@toradex.com>
|
||||
*
|
||||
|
@ -14,6 +16,7 @@
|
|||
#include <linux/io.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/printk.h>
|
||||
#include <clk.h>
|
||||
|
||||
#include <mxs_nand.h>
|
||||
|
||||
|
@ -25,19 +28,39 @@ static const struct mxs_nand_dt_data mxs_nand_imx6q_data = {
|
|||
.max_ecc_strength_supported = 40,
|
||||
};
|
||||
|
||||
static const struct mxs_nand_dt_data mxs_nand_imx6sx_data = {
|
||||
.max_ecc_strength_supported = 62,
|
||||
};
|
||||
|
||||
static const struct mxs_nand_dt_data mxs_nand_imx7d_data = {
|
||||
.max_ecc_strength_supported = 62,
|
||||
};
|
||||
|
||||
static const struct mxs_nand_dt_data mxs_nand_imx8qxp_data = {
|
||||
.max_ecc_strength_supported = 62,
|
||||
};
|
||||
|
||||
static const struct udevice_id mxs_nand_dt_ids[] = {
|
||||
{
|
||||
.compatible = "fsl,imx6q-gpmi-nand",
|
||||
.data = (unsigned long)&mxs_nand_imx6q_data,
|
||||
},
|
||||
{
|
||||
.compatible = "fsl,imx6qp-gpmi-nand",
|
||||
.data = (unsigned long)&mxs_nand_imx6q_data,
|
||||
},
|
||||
{
|
||||
.compatible = "fsl,imx6sx-gpmi-nand",
|
||||
.data = (unsigned long)&mxs_nand_imx6sx_data,
|
||||
},
|
||||
{
|
||||
.compatible = "fsl,imx7d-gpmi-nand",
|
||||
.data = (unsigned long)&mxs_nand_imx7d_data,
|
||||
},
|
||||
{
|
||||
.compatible = "fsl,imx8qxp-gpmi-nand",
|
||||
.data = (unsigned long)&mxs_nand_imx8qxp_data,
|
||||
},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
|
@ -69,6 +92,74 @@ static int mxs_nand_dt_probe(struct udevice *dev)
|
|||
|
||||
info->use_minimum_ecc = dev_read_bool(dev, "fsl,use-minimum-ecc");
|
||||
|
||||
info->legacy_bch_geometry = dev_read_bool(dev, "fsl,legacy-bch-geometry");
|
||||
|
||||
if (IS_ENABLED(CONFIG_CLK) && IS_ENABLED(CONFIG_IMX8)) {
|
||||
/* Assigned clock already set clock */
|
||||
struct clk gpmi_clk;
|
||||
|
||||
ret = clk_get_by_name(dev, "gpmi_io", &gpmi_clk);
|
||||
if (ret < 0) {
|
||||
debug("Can't get gpmi io clk: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = clk_enable(&gpmi_clk);
|
||||
if (ret < 0) {
|
||||
debug("Can't enable gpmi io clk: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = clk_get_by_name(dev, "gpmi_apb", &gpmi_clk);
|
||||
if (ret < 0) {
|
||||
debug("Can't get gpmi_apb clk: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = clk_enable(&gpmi_clk);
|
||||
if (ret < 0) {
|
||||
debug("Can't enable gpmi_apb clk: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = clk_get_by_name(dev, "gpmi_bch", &gpmi_clk);
|
||||
if (ret < 0) {
|
||||
debug("Can't get gpmi_bch clk: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = clk_enable(&gpmi_clk);
|
||||
if (ret < 0) {
|
||||
debug("Can't enable gpmi_bch clk: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = clk_get_by_name(dev, "gpmi_apb_bch", &gpmi_clk);
|
||||
if (ret < 0) {
|
||||
debug("Can't get gpmi_apb_bch clk: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = clk_enable(&gpmi_clk);
|
||||
if (ret < 0) {
|
||||
debug("Can't enable gpmi_apb_bch clk: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* this clock is used for apbh_dma, since the apbh dma does not support DM,
|
||||
* we optionally enable it here
|
||||
*/
|
||||
ret = clk_get_by_name(dev, "gpmi_apbh_dma", &gpmi_clk);
|
||||
if (ret < 0) {
|
||||
debug("Can't get gpmi_apbh_dma clk: %d\n", ret);
|
||||
} else {
|
||||
ret = clk_enable(&gpmi_clk);
|
||||
if (ret < 0) {
|
||||
debug("Can't enable gpmi_apbh_dma clk: %d\n", ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mxs_nand_init_ctrl(info);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2014 Gateworks Corporation
|
||||
* Copyright 2019 NXP
|
||||
* Author: Tim Harvey <tharvey@gateworks.com>
|
||||
*/
|
||||
#include <common.h>
|
||||
|
@ -38,6 +39,12 @@ static void mxs_nand_command(struct mtd_info *mtd, unsigned int command,
|
|||
if (command == NAND_CMD_READ0) {
|
||||
chip->cmd_ctrl(mtd, NAND_CMD_READSTART, NAND_CLE);
|
||||
chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0);
|
||||
} else if (command == NAND_CMD_RNDOUT) {
|
||||
/* No ready / busy check necessary */
|
||||
chip->cmd_ctrl(mtd, NAND_CMD_RNDOUTSTART,
|
||||
NAND_NCE | NAND_CLE);
|
||||
chip->cmd_ctrl(mtd, NAND_CMD_NONE,
|
||||
NAND_NCE);
|
||||
}
|
||||
|
||||
/* wait for nand ready */
|
||||
|
@ -212,23 +219,39 @@ int nand_spl_load_image(uint32_t offs, unsigned int size, void *buf)
|
|||
unsigned int page;
|
||||
unsigned int nand_page_per_block;
|
||||
unsigned int sz = 0;
|
||||
u8 *page_buf = NULL;
|
||||
u32 page_off;
|
||||
|
||||
chip = mtd_to_nand(mtd);
|
||||
if (!chip->numchips)
|
||||
return -ENODEV;
|
||||
|
||||
page_buf = malloc(mtd->writesize);
|
||||
if (!page_buf)
|
||||
return -ENOMEM;
|
||||
|
||||
page = offs >> chip->page_shift;
|
||||
page_off = offs & (mtd->writesize - 1);
|
||||
nand_page_per_block = mtd->erasesize / mtd->writesize;
|
||||
|
||||
debug("%s offset:0x%08x len:%d page:%d\n", __func__, offs, size, page);
|
||||
debug("%s offset:0x%08x len:%d page:%x\n", __func__, offs, size, page);
|
||||
|
||||
size = roundup(size, mtd->writesize);
|
||||
while (sz < size) {
|
||||
if (mxs_read_page_ecc(mtd, buf, page) < 0)
|
||||
while (size) {
|
||||
if (mxs_read_page_ecc(mtd, page_buf, page) < 0)
|
||||
return -1;
|
||||
sz += mtd->writesize;
|
||||
|
||||
if (size > (mtd->writesize - page_off))
|
||||
sz = (mtd->writesize - page_off);
|
||||
else
|
||||
sz = size;
|
||||
|
||||
memcpy(buf, page_buf + page_off, sz);
|
||||
|
||||
offs += mtd->writesize;
|
||||
page++;
|
||||
buf += mtd->writesize;
|
||||
buf += (mtd->writesize - page_off);
|
||||
page_off = 0;
|
||||
size -= sz;
|
||||
|
||||
/*
|
||||
* Check if we have crossed a block boundary, and if so
|
||||
|
@ -242,12 +265,16 @@ int nand_spl_load_image(uint32_t offs, unsigned int size, void *buf)
|
|||
while (is_badblock(mtd, offs, 1)) {
|
||||
page = page + nand_page_per_block;
|
||||
/* Check i we've reached the end of flash. */
|
||||
if (page >= mtd->size >> chip->page_shift)
|
||||
if (page >= mtd->size >> chip->page_shift) {
|
||||
free(page_buf);
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(page_buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -57,6 +57,12 @@ config MDIO_MUX_SANDBOX
|
|||
|
||||
This driver is used for testing in test/dm/mdio.c
|
||||
|
||||
config DM_ETH_PHY
|
||||
bool "Enable Driver Model for Ethernet Generic PHY drivers"
|
||||
depends on DM
|
||||
help
|
||||
Enable driver model for Ethernet Generic PHY .
|
||||
|
||||
menuconfig NETDEVICES
|
||||
bool "Network device support"
|
||||
depends on NET
|
||||
|
|
|
@ -20,6 +20,7 @@ obj-$(CONFIG_ETH_DESIGNWARE) += designware.o
|
|||
obj-$(CONFIG_ETH_DESIGNWARE_SOCFPGA) += dwmac_socfpga.o
|
||||
obj-$(CONFIG_DRIVER_DM9000) += dm9000x.o
|
||||
obj-$(CONFIG_DNET) += dnet.o
|
||||
obj-$(CONFIG_DM_ETH_PHY) += eth-phy-uclass.o
|
||||
obj-$(CONFIG_E1000) += e1000.o
|
||||
obj-$(CONFIG_E1000_SPI) += e1000_spi.o
|
||||
obj-$(CONFIG_EEPRO100) += eepro100.o
|
||||
|
|
|
@ -41,6 +41,11 @@
|
|||
#include <wait_bit.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <asm/io.h>
|
||||
#include <eth_phy.h>
|
||||
#ifdef CONFIG_ARCH_IMX8M
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/mach-imx/sys_proto.h>
|
||||
#endif
|
||||
|
||||
/* Core registers */
|
||||
|
||||
|
@ -80,6 +85,7 @@ struct eqos_mac_regs {
|
|||
#define EQOS_MAC_CONFIGURATION_PS BIT(15)
|
||||
#define EQOS_MAC_CONFIGURATION_FES BIT(14)
|
||||
#define EQOS_MAC_CONFIGURATION_DM BIT(13)
|
||||
#define EQOS_MAC_CONFIGURATION_LM BIT(12)
|
||||
#define EQOS_MAC_CONFIGURATION_TE BIT(1)
|
||||
#define EQOS_MAC_CONFIGURATION_RE BIT(0)
|
||||
|
||||
|
@ -101,11 +107,19 @@ struct eqos_mac_regs {
|
|||
#define EQOS_MAC_RXQ_CTRL2_PSRQ0_SHIFT 0
|
||||
#define EQOS_MAC_RXQ_CTRL2_PSRQ0_MASK 0xff
|
||||
|
||||
#define EQOS_MAC_HW_FEATURE0_MMCSEL_SHIFT 8
|
||||
#define EQOS_MAC_HW_FEATURE0_HDSEL_SHIFT 2
|
||||
#define EQOS_MAC_HW_FEATURE0_GMIISEL_SHIFT 1
|
||||
#define EQOS_MAC_HW_FEATURE0_MIISEL_SHIFT 0
|
||||
|
||||
#define EQOS_MAC_HW_FEATURE1_TXFIFOSIZE_SHIFT 6
|
||||
#define EQOS_MAC_HW_FEATURE1_TXFIFOSIZE_MASK 0x1f
|
||||
#define EQOS_MAC_HW_FEATURE1_RXFIFOSIZE_SHIFT 0
|
||||
#define EQOS_MAC_HW_FEATURE1_RXFIFOSIZE_MASK 0x1f
|
||||
|
||||
#define EQOS_MAC_HW_FEATURE3_ASP_SHIFT 28
|
||||
#define EQOS_MAC_HW_FEATURE3_ASP_MASK 0x3
|
||||
|
||||
#define EQOS_MAC_MDIO_ADDRESS_PA_SHIFT 21
|
||||
#define EQOS_MAC_MDIO_ADDRESS_RDA_SHIFT 16
|
||||
#define EQOS_MAC_MDIO_ADDRESS_CR_SHIFT 8
|
||||
|
@ -153,6 +167,8 @@ struct eqos_mtl_regs {
|
|||
#define EQOS_MTL_RXQ0_OPERATION_MODE_RFA_MASK 0x3f
|
||||
#define EQOS_MTL_RXQ0_OPERATION_MODE_EHFC BIT(7)
|
||||
#define EQOS_MTL_RXQ0_OPERATION_MODE_RSF BIT(5)
|
||||
#define EQOS_MTL_RXQ0_OPERATION_MODE_FEP BIT(4)
|
||||
#define EQOS_MTL_RXQ0_OPERATION_MODE_FUP BIT(3)
|
||||
|
||||
#define EQOS_MTL_RXQ0_DEBUG_PRXQ_SHIFT 16
|
||||
#define EQOS_MTL_RXQ0_DEBUG_PRXQ_MASK 0x7fff
|
||||
|
@ -367,7 +383,7 @@ static void eqos_inval_desc_tegra186(void *desc)
|
|||
#endif
|
||||
}
|
||||
|
||||
static void eqos_inval_desc_stm32(void *desc)
|
||||
static void eqos_inval_desc_generic(void *desc)
|
||||
{
|
||||
#ifndef CONFIG_SYS_NONCACHED_MEMORY
|
||||
unsigned long start = rounddown((unsigned long)desc, ARCH_DMA_MINALIGN);
|
||||
|
@ -385,7 +401,7 @@ static void eqos_flush_desc_tegra186(void *desc)
|
|||
#endif
|
||||
}
|
||||
|
||||
static void eqos_flush_desc_stm32(void *desc)
|
||||
static void eqos_flush_desc_generic(void *desc)
|
||||
{
|
||||
#ifndef CONFIG_SYS_NONCACHED_MEMORY
|
||||
unsigned long start = rounddown((unsigned long)desc, ARCH_DMA_MINALIGN);
|
||||
|
@ -404,7 +420,7 @@ static void eqos_inval_buffer_tegra186(void *buf, size_t size)
|
|||
invalidate_dcache_range(start, end);
|
||||
}
|
||||
|
||||
static void eqos_inval_buffer_stm32(void *buf, size_t size)
|
||||
static void eqos_inval_buffer_generic(void *buf, size_t size)
|
||||
{
|
||||
unsigned long start = rounddown((unsigned long)buf, ARCH_DMA_MINALIGN);
|
||||
unsigned long end = roundup((unsigned long)buf + size,
|
||||
|
@ -418,7 +434,7 @@ static void eqos_flush_buffer_tegra186(void *buf, size_t size)
|
|||
flush_cache((unsigned long)buf, size);
|
||||
}
|
||||
|
||||
static void eqos_flush_buffer_stm32(void *buf, size_t size)
|
||||
static void eqos_flush_buffer_generic(void *buf, size_t size)
|
||||
{
|
||||
unsigned long start = rounddown((unsigned long)buf, ARCH_DMA_MINALIGN);
|
||||
unsigned long end = roundup((unsigned long)buf + size,
|
||||
|
@ -521,6 +537,7 @@ static int eqos_mdio_write(struct mii_dev *bus, int mdio_addr, int mdio_devad,
|
|||
|
||||
static int eqos_start_clks_tegra186(struct udevice *dev)
|
||||
{
|
||||
#ifdef CONFIG_CLK
|
||||
struct eqos_priv *eqos = dev_get_priv(dev);
|
||||
int ret;
|
||||
|
||||
|
@ -561,10 +578,12 @@ static int eqos_start_clks_tegra186(struct udevice *dev)
|
|||
pr_err("clk_enable(clk_tx) failed: %d", ret);
|
||||
goto err_disable_clk_ptp_ref;
|
||||
}
|
||||
#endif
|
||||
|
||||
debug("%s: OK\n", __func__);
|
||||
return 0;
|
||||
|
||||
#ifdef CONFIG_CLK
|
||||
err_disable_clk_ptp_ref:
|
||||
clk_disable(&eqos->clk_ptp_ref);
|
||||
err_disable_clk_rx:
|
||||
|
@ -576,10 +595,12 @@ err_disable_clk_slave_bus:
|
|||
err:
|
||||
debug("%s: FAILED: %d\n", __func__, ret);
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int eqos_start_clks_stm32(struct udevice *dev)
|
||||
{
|
||||
#ifdef CONFIG_CLK
|
||||
struct eqos_priv *eqos = dev_get_priv(dev);
|
||||
int ret;
|
||||
|
||||
|
@ -610,10 +631,12 @@ static int eqos_start_clks_stm32(struct udevice *dev)
|
|||
goto err_disable_clk_tx;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
debug("%s: OK\n", __func__);
|
||||
return 0;
|
||||
|
||||
#ifdef CONFIG_CLK
|
||||
err_disable_clk_tx:
|
||||
clk_disable(&eqos->clk_tx);
|
||||
err_disable_clk_rx:
|
||||
|
@ -623,10 +646,17 @@ err_disable_clk_master_bus:
|
|||
err:
|
||||
debug("%s: FAILED: %d\n", __func__, ret);
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int eqos_start_clks_imx(struct udevice *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void eqos_stop_clks_tegra186(struct udevice *dev)
|
||||
{
|
||||
#ifdef CONFIG_CLK
|
||||
struct eqos_priv *eqos = dev_get_priv(dev);
|
||||
|
||||
debug("%s(dev=%p):\n", __func__, dev);
|
||||
|
@ -636,12 +666,14 @@ static void eqos_stop_clks_tegra186(struct udevice *dev)
|
|||
clk_disable(&eqos->clk_rx);
|
||||
clk_disable(&eqos->clk_master_bus);
|
||||
clk_disable(&eqos->clk_slave_bus);
|
||||
#endif
|
||||
|
||||
debug("%s: OK\n", __func__);
|
||||
}
|
||||
|
||||
static void eqos_stop_clks_stm32(struct udevice *dev)
|
||||
{
|
||||
#ifdef CONFIG_CLK
|
||||
struct eqos_priv *eqos = dev_get_priv(dev);
|
||||
|
||||
debug("%s(dev=%p):\n", __func__, dev);
|
||||
|
@ -651,10 +683,16 @@ static void eqos_stop_clks_stm32(struct udevice *dev)
|
|||
clk_disable(&eqos->clk_master_bus);
|
||||
if (clk_valid(&eqos->clk_ck))
|
||||
clk_disable(&eqos->clk_ck);
|
||||
#endif
|
||||
|
||||
debug("%s: OK\n", __func__);
|
||||
}
|
||||
|
||||
static void eqos_stop_clks_imx(struct udevice *dev)
|
||||
{
|
||||
/* empty */
|
||||
}
|
||||
|
||||
static int eqos_start_resets_tegra186(struct udevice *dev)
|
||||
{
|
||||
struct eqos_priv *eqos = dev_get_priv(dev);
|
||||
|
@ -722,6 +760,11 @@ static int eqos_start_resets_stm32(struct udevice *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int eqos_start_resets_imx(struct udevice *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int eqos_stop_resets_tegra186(struct udevice *dev)
|
||||
{
|
||||
struct eqos_priv *eqos = dev_get_priv(dev);
|
||||
|
@ -749,6 +792,11 @@ static int eqos_stop_resets_stm32(struct udevice *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int eqos_stop_resets_imx(struct udevice *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int eqos_calibrate_pads_tegra186(struct udevice *dev)
|
||||
{
|
||||
struct eqos_priv *eqos = dev_get_priv(dev);
|
||||
|
@ -803,16 +851,38 @@ static int eqos_disable_calibration_tegra186(struct udevice *dev)
|
|||
|
||||
static ulong eqos_get_tick_clk_rate_tegra186(struct udevice *dev)
|
||||
{
|
||||
#ifdef CONFIG_CLK
|
||||
struct eqos_priv *eqos = dev_get_priv(dev);
|
||||
|
||||
return clk_get_rate(&eqos->clk_slave_bus);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static ulong eqos_get_tick_clk_rate_stm32(struct udevice *dev)
|
||||
{
|
||||
#ifdef CONFIG_CLK
|
||||
struct eqos_priv *eqos = dev_get_priv(dev);
|
||||
|
||||
return clk_get_rate(&eqos->clk_master_bus);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
__weak u32 imx_get_eqos_csr_clk(void)
|
||||
{
|
||||
return 100 * 1000000;
|
||||
}
|
||||
__weak int imx_eqos_txclk_set_rate(unsigned long rate)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ulong eqos_get_tick_clk_rate_imx(struct udevice *dev)
|
||||
{
|
||||
return imx_get_eqos_csr_clk();
|
||||
}
|
||||
|
||||
static int eqos_calibrate_pads_stm32(struct udevice *dev)
|
||||
|
@ -820,11 +890,21 @@ static int eqos_calibrate_pads_stm32(struct udevice *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int eqos_calibrate_pads_imx(struct udevice *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int eqos_disable_calibration_stm32(struct udevice *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int eqos_disable_calibration_imx(struct udevice *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int eqos_set_full_duplex(struct udevice *dev)
|
||||
{
|
||||
struct eqos_priv *eqos = dev_get_priv(dev);
|
||||
|
@ -889,6 +969,7 @@ static int eqos_set_mii_speed_10(struct udevice *dev)
|
|||
|
||||
static int eqos_set_tx_clk_speed_tegra186(struct udevice *dev)
|
||||
{
|
||||
#ifdef CONFIG_CLK
|
||||
struct eqos_priv *eqos = dev_get_priv(dev);
|
||||
ulong rate;
|
||||
int ret;
|
||||
|
@ -915,6 +996,7 @@ static int eqos_set_tx_clk_speed_tegra186(struct udevice *dev)
|
|||
pr_err("clk_set_rate(tx_clk, %lu) failed: %d", rate, ret);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -924,6 +1006,38 @@ static int eqos_set_tx_clk_speed_stm32(struct udevice *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int eqos_set_tx_clk_speed_imx(struct udevice *dev)
|
||||
{
|
||||
struct eqos_priv *eqos = dev_get_priv(dev);
|
||||
ulong rate;
|
||||
int ret;
|
||||
|
||||
debug("%s(dev=%p):\n", __func__, dev);
|
||||
|
||||
switch (eqos->phy->speed) {
|
||||
case SPEED_1000:
|
||||
rate = 125 * 1000 * 1000;
|
||||
break;
|
||||
case SPEED_100:
|
||||
rate = 25 * 1000 * 1000;
|
||||
break;
|
||||
case SPEED_10:
|
||||
rate = 2.5 * 1000 * 1000;
|
||||
break;
|
||||
default:
|
||||
pr_err("invalid speed %d", eqos->phy->speed);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = imx_eqos_txclk_set_rate(rate);
|
||||
if (ret < 0) {
|
||||
pr_err("imx (tx_clk, %lu) failed: %d", rate, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int eqos_adjust_link(struct udevice *dev)
|
||||
{
|
||||
struct eqos_priv *eqos = dev_get_priv(dev);
|
||||
|
@ -1031,6 +1145,16 @@ static int eqos_write_hwaddr(struct udevice *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int eqos_read_rom_hwaddr(struct udevice *dev)
|
||||
{
|
||||
struct eth_pdata *pdata = dev_get_platdata(dev);
|
||||
|
||||
#ifdef CONFIG_ARCH_IMX8M
|
||||
imx_get_mac_from_fuse(dev->req_seq, pdata->enetaddr);
|
||||
#endif
|
||||
return !is_valid_ethaddr(pdata->enetaddr);
|
||||
}
|
||||
|
||||
static int eqos_start(struct udevice *dev)
|
||||
{
|
||||
struct eqos_priv *eqos = dev_get_priv(dev);
|
||||
|
@ -1083,7 +1207,14 @@ static int eqos_start(struct udevice *dev)
|
|||
* don't need to reconnect/reconfigure again
|
||||
*/
|
||||
if (!eqos->phy) {
|
||||
eqos->phy = phy_connect(eqos->mii, eqos->phyaddr, dev,
|
||||
int addr = -1;
|
||||
#ifdef CONFIG_DM_ETH_PHY
|
||||
addr = eth_phy_get_addr(dev);
|
||||
#endif
|
||||
#ifdef DWC_NET_PHYADDR
|
||||
addr = DWC_NET_PHYADDR;
|
||||
#endif
|
||||
eqos->phy = phy_connect(eqos->mii, addr, dev,
|
||||
eqos->config->interface(dev));
|
||||
if (!eqos->phy) {
|
||||
pr_err("phy_connect() failed");
|
||||
|
@ -1123,6 +1254,7 @@ static int eqos_start(struct udevice *dev)
|
|||
}
|
||||
|
||||
/* Configure MTL */
|
||||
writel(0x60, &eqos->mtl_regs->txq0_quantum_weight - 0x100);
|
||||
|
||||
/* Enable Store and Forward mode for TX */
|
||||
/* Program Tx operating mode */
|
||||
|
@ -1136,7 +1268,9 @@ static int eqos_start(struct udevice *dev)
|
|||
|
||||
/* Enable Store and Forward mode for RX, since no jumbo frame */
|
||||
setbits_le32(&eqos->mtl_regs->rxq0_operation_mode,
|
||||
EQOS_MTL_RXQ0_OPERATION_MODE_RSF);
|
||||
EQOS_MTL_RXQ0_OPERATION_MODE_RSF |
|
||||
EQOS_MTL_RXQ0_OPERATION_MODE_FEP |
|
||||
EQOS_MTL_RXQ0_OPERATION_MODE_FUP);
|
||||
|
||||
/* Transmit/Receive queue fifo size; use all RAM for 1 queue */
|
||||
val = readl(&eqos->mac_regs->hw_feature1);
|
||||
|
@ -1212,6 +1346,19 @@ static int eqos_start(struct udevice *dev)
|
|||
eqos->config->config_mac <<
|
||||
EQOS_MAC_RXQ_CTRL0_RXQ0EN_SHIFT);
|
||||
|
||||
clrsetbits_le32(&eqos->mac_regs->rxq_ctrl0,
|
||||
EQOS_MAC_RXQ_CTRL0_RXQ0EN_MASK <<
|
||||
EQOS_MAC_RXQ_CTRL0_RXQ0EN_SHIFT,
|
||||
0x2 <<
|
||||
EQOS_MAC_RXQ_CTRL0_RXQ0EN_SHIFT);
|
||||
|
||||
/* Multicast and Broadcast Queue Enable */
|
||||
setbits_le32(&eqos->mac_regs->unused_0a4,
|
||||
0x00100000);
|
||||
/* enable promise mode */
|
||||
setbits_le32(&eqos->mac_regs->unused_004[1],
|
||||
0x1);
|
||||
|
||||
/* Set TX flow control parameters */
|
||||
/* Set Pause Time */
|
||||
setbits_le32(&eqos->mac_regs->q0_tx_flow_ctrl,
|
||||
|
@ -1289,7 +1436,11 @@ static int eqos_start(struct udevice *dev)
|
|||
rx_desc->des0 = (u32)(ulong)(eqos->rx_dma_buf +
|
||||
(i * EQOS_MAX_PACKET_SIZE));
|
||||
rx_desc->des3 = EQOS_DESC3_OWN | EQOS_DESC3_BUF1V;
|
||||
mb();
|
||||
eqos->config->ops->eqos_flush_desc(rx_desc);
|
||||
eqos->config->ops->eqos_inval_buffer(eqos->rx_dma_buf +
|
||||
(i * EQOS_MAX_PACKET_SIZE),
|
||||
EQOS_MAX_PACKET_SIZE);
|
||||
}
|
||||
|
||||
writel(0, &eqos->dma_regs->ch0_txdesc_list_haddress);
|
||||
|
@ -1303,14 +1454,12 @@ static int eqos_start(struct udevice *dev)
|
|||
&eqos->dma_regs->ch0_rxdesc_ring_length);
|
||||
|
||||
/* Enable everything */
|
||||
|
||||
setbits_le32(&eqos->mac_regs->configuration,
|
||||
EQOS_MAC_CONFIGURATION_TE | EQOS_MAC_CONFIGURATION_RE);
|
||||
|
||||
setbits_le32(&eqos->dma_regs->ch0_tx_control,
|
||||
EQOS_DMA_CH0_TX_CONTROL_ST);
|
||||
setbits_le32(&eqos->dma_regs->ch0_rx_control,
|
||||
EQOS_DMA_CH0_RX_CONTROL_SR);
|
||||
setbits_le32(&eqos->mac_regs->configuration,
|
||||
EQOS_MAC_CONFIGURATION_TE | EQOS_MAC_CONFIGURATION_RE);
|
||||
|
||||
/* TX tail pointer not written until we need to TX a packet */
|
||||
/*
|
||||
|
@ -1475,6 +1624,8 @@ static int eqos_free_pkt(struct udevice *dev, uchar *packet, int length)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
eqos->config->ops->eqos_inval_buffer(packet, length);
|
||||
|
||||
rx_desc = &(eqos->rx_descs[eqos->rx_desc_idx]);
|
||||
|
||||
rx_desc->des0 = 0;
|
||||
|
@ -1751,17 +1902,52 @@ static phy_interface_t eqos_get_interface_tegra186(struct udevice *dev)
|
|||
return PHY_INTERFACE_MODE_MII;
|
||||
}
|
||||
|
||||
static int eqos_probe_resources_imx(struct udevice *dev)
|
||||
{
|
||||
struct eqos_priv *eqos = dev_get_priv(dev);
|
||||
phy_interface_t interface;
|
||||
|
||||
debug("%s(dev=%p):\n", __func__, dev);
|
||||
|
||||
interface = eqos->config->interface(dev);
|
||||
|
||||
if (interface == PHY_INTERFACE_MODE_NONE) {
|
||||
pr_err("Invalid PHY interface\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
debug("%s: OK\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static phy_interface_t eqos_get_interface_imx(struct udevice *dev)
|
||||
{
|
||||
const char *phy_mode;
|
||||
phy_interface_t interface = PHY_INTERFACE_MODE_NONE;
|
||||
|
||||
debug("%s(dev=%p):\n", __func__, dev);
|
||||
|
||||
phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode",
|
||||
NULL);
|
||||
if (phy_mode)
|
||||
interface = phy_get_interface_by_name(phy_mode);
|
||||
|
||||
return interface;
|
||||
}
|
||||
|
||||
static int eqos_remove_resources_tegra186(struct udevice *dev)
|
||||
{
|
||||
struct eqos_priv *eqos = dev_get_priv(dev);
|
||||
|
||||
debug("%s(dev=%p):\n", __func__, dev);
|
||||
|
||||
#ifdef CONFIG_CLK
|
||||
clk_free(&eqos->clk_tx);
|
||||
clk_free(&eqos->clk_ptp_ref);
|
||||
clk_free(&eqos->clk_rx);
|
||||
clk_free(&eqos->clk_slave_bus);
|
||||
clk_free(&eqos->clk_master_bus);
|
||||
#endif
|
||||
dm_gpio_free(dev, &eqos->phy_reset_gpio);
|
||||
reset_free(&eqos->reset_ctl);
|
||||
|
||||
|
@ -1771,6 +1957,7 @@ static int eqos_remove_resources_tegra186(struct udevice *dev)
|
|||
|
||||
static int eqos_remove_resources_stm32(struct udevice *dev)
|
||||
{
|
||||
#ifdef CONFIG_CLK
|
||||
struct eqos_priv *eqos = dev_get_priv(dev);
|
||||
|
||||
debug("%s(dev=%p):\n", __func__, dev);
|
||||
|
@ -1780,6 +1967,7 @@ static int eqos_remove_resources_stm32(struct udevice *dev)
|
|||
clk_free(&eqos->clk_master_bus);
|
||||
if (clk_valid(&eqos->clk_ck))
|
||||
clk_free(&eqos->clk_ck);
|
||||
#endif
|
||||
|
||||
if (dm_gpio_is_valid(&eqos->phy_reset_gpio))
|
||||
dm_gpio_free(dev, &eqos->phy_reset_gpio);
|
||||
|
@ -1788,6 +1976,11 @@ static int eqos_remove_resources_stm32(struct udevice *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int eqos_remove_resources_imx(struct udevice *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int eqos_probe(struct udevice *dev)
|
||||
{
|
||||
struct eqos_priv *eqos = dev_get_priv(dev);
|
||||
|
@ -1820,23 +2013,32 @@ static int eqos_probe(struct udevice *dev)
|
|||
goto err_remove_resources_core;
|
||||
}
|
||||
|
||||
eqos->mii = mdio_alloc();
|
||||
#ifdef CONFIG_DM_ETH_PHY
|
||||
eqos->mii = eth_phy_get_mdio_bus(dev);
|
||||
#endif
|
||||
if (!eqos->mii) {
|
||||
pr_err("mdio_alloc() failed");
|
||||
ret = -ENOMEM;
|
||||
goto err_remove_resources_tegra;
|
||||
}
|
||||
eqos->mii->read = eqos_mdio_read;
|
||||
eqos->mii->write = eqos_mdio_write;
|
||||
eqos->mii->priv = eqos;
|
||||
strcpy(eqos->mii->name, dev->name);
|
||||
eqos->mii = mdio_alloc();
|
||||
if (!eqos->mii) {
|
||||
pr_err("mdio_alloc() failed");
|
||||
ret = -ENOMEM;
|
||||
goto err_remove_resources_tegra;
|
||||
}
|
||||
eqos->mii->read = eqos_mdio_read;
|
||||
eqos->mii->write = eqos_mdio_write;
|
||||
eqos->mii->priv = eqos;
|
||||
strcpy(eqos->mii->name, dev->name);
|
||||
|
||||
ret = mdio_register(eqos->mii);
|
||||
if (ret < 0) {
|
||||
pr_err("mdio_register() failed: %d", ret);
|
||||
goto err_free_mdio;
|
||||
ret = mdio_register(eqos->mii);
|
||||
if (ret < 0) {
|
||||
pr_err("mdio_register() failed: %d", ret);
|
||||
goto err_free_mdio;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DM_ETH_PHY
|
||||
eth_phy_set_mdio_bus(dev, eqos->mii);
|
||||
#endif
|
||||
|
||||
debug("%s: OK\n", __func__);
|
||||
return 0;
|
||||
|
||||
|
@ -1874,6 +2076,7 @@ static const struct eth_ops eqos_ops = {
|
|||
.recv = eqos_recv,
|
||||
.free_pkt = eqos_free_pkt,
|
||||
.write_hwaddr = eqos_write_hwaddr,
|
||||
.read_rom_hwaddr = eqos_read_rom_hwaddr,
|
||||
};
|
||||
|
||||
static struct eqos_ops eqos_tegra186_ops = {
|
||||
|
@ -1904,10 +2107,10 @@ static const struct eqos_config eqos_tegra186_config = {
|
|||
};
|
||||
|
||||
static struct eqos_ops eqos_stm32_ops = {
|
||||
.eqos_inval_desc = eqos_inval_desc_stm32,
|
||||
.eqos_flush_desc = eqos_flush_desc_stm32,
|
||||
.eqos_inval_buffer = eqos_inval_buffer_stm32,
|
||||
.eqos_flush_buffer = eqos_flush_buffer_stm32,
|
||||
.eqos_inval_desc = eqos_inval_desc_generic,
|
||||
.eqos_flush_desc = eqos_flush_desc_generic,
|
||||
.eqos_inval_buffer = eqos_inval_buffer_generic,
|
||||
.eqos_flush_buffer = eqos_flush_buffer_generic,
|
||||
.eqos_probe_resources = eqos_probe_resources_stm32,
|
||||
.eqos_remove_resources = eqos_remove_resources_stm32,
|
||||
.eqos_stop_resets = eqos_stop_resets_stm32,
|
||||
|
@ -1930,6 +2133,33 @@ static const struct eqos_config eqos_stm32_config = {
|
|||
.ops = &eqos_stm32_ops
|
||||
};
|
||||
|
||||
static struct eqos_ops eqos_imx_ops = {
|
||||
.eqos_inval_desc = eqos_inval_desc_generic,
|
||||
.eqos_flush_desc = eqos_flush_desc_generic,
|
||||
.eqos_inval_buffer = eqos_inval_buffer_generic,
|
||||
.eqos_flush_buffer = eqos_flush_buffer_generic,
|
||||
.eqos_probe_resources = eqos_probe_resources_imx,
|
||||
.eqos_remove_resources = eqos_remove_resources_imx,
|
||||
.eqos_stop_resets = eqos_stop_resets_imx,
|
||||
.eqos_start_resets = eqos_start_resets_imx,
|
||||
.eqos_stop_clks = eqos_stop_clks_imx,
|
||||
.eqos_start_clks = eqos_start_clks_imx,
|
||||
.eqos_calibrate_pads = eqos_calibrate_pads_imx,
|
||||
.eqos_disable_calibration = eqos_disable_calibration_imx,
|
||||
.eqos_set_tx_clk_speed = eqos_set_tx_clk_speed_imx,
|
||||
.eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_imx
|
||||
};
|
||||
|
||||
struct eqos_config eqos_imx_config = {
|
||||
.reg_access_always_ok = false,
|
||||
.mdio_wait = 10000,
|
||||
.swr_wait = 50,
|
||||
.config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB,
|
||||
.config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_250_300,
|
||||
.interface = eqos_get_interface_imx,
|
||||
.ops = &eqos_imx_ops
|
||||
};
|
||||
|
||||
static const struct udevice_id eqos_ids[] = {
|
||||
{
|
||||
.compatible = "nvidia,tegra186-eqos",
|
||||
|
@ -1939,6 +2169,10 @@ static const struct udevice_id eqos_ids[] = {
|
|||
.compatible = "snps,dwmac-4.20a",
|
||||
.data = (ulong)&eqos_stm32_config
|
||||
},
|
||||
{
|
||||
.compatible = "fsl,imx-eqos",
|
||||
.data = (ulong)&eqos_imx_config
|
||||
},
|
||||
|
||||
{ }
|
||||
};
|
||||
|
@ -1946,7 +2180,7 @@ static const struct udevice_id eqos_ids[] = {
|
|||
U_BOOT_DRIVER(eth_eqos) = {
|
||||
.name = "eth_eqos",
|
||||
.id = UCLASS_ETH,
|
||||
.of_match = eqos_ids,
|
||||
.of_match = of_match_ptr(eqos_ids),
|
||||
.probe = eqos_probe,
|
||||
.remove = eqos_remove,
|
||||
.ops = &eqos_ops,
|
||||
|
|
122
drivers/net/eth-phy-uclass.c
Normal file
122
drivers/net/eth-phy-uclass.c
Normal file
|
@ -0,0 +1,122 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2020 NXP
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <net.h>
|
||||
#include <dm/device-internal.h>
|
||||
#include <dm/uclass-internal.h>
|
||||
#include <dm/lists.h>
|
||||
|
||||
struct eth_phy_device_priv {
|
||||
struct mii_dev *mdio_bus;
|
||||
};
|
||||
|
||||
int eth_phy_binds_nodes(struct udevice *eth_dev)
|
||||
{
|
||||
ofnode mdio_node, phy_node;
|
||||
const char *node_name;
|
||||
int ret;
|
||||
|
||||
mdio_node = dev_read_subnode(eth_dev, "mdio");
|
||||
if (!ofnode_valid(mdio_node)) {
|
||||
debug("%s: %s mdio subnode not found!", __func__,
|
||||
eth_dev->name);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
ofnode_for_each_subnode(phy_node, mdio_node) {
|
||||
node_name = ofnode_get_name(phy_node);
|
||||
|
||||
debug("* Found child node: '%s'\n", node_name);
|
||||
|
||||
ret = device_bind_driver_to_node(eth_dev,
|
||||
"eth_phy_generic_drv",
|
||||
node_name, phy_node, NULL);
|
||||
if (ret) {
|
||||
debug(" - Eth phy binding error: %d\n", ret);
|
||||
continue;
|
||||
}
|
||||
|
||||
debug(" - bound phy device: '%s'\n", node_name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int eth_phy_set_mdio_bus(struct udevice *eth_dev, struct mii_dev *mdio_bus)
|
||||
{
|
||||
struct udevice *dev;
|
||||
struct eth_phy_device_priv *uc_priv;
|
||||
|
||||
for (uclass_first_device(UCLASS_ETH_PHY, &dev); dev;
|
||||
uclass_next_device(&dev)) {
|
||||
if (dev->parent == eth_dev) {
|
||||
uc_priv = (struct eth_phy_device_priv *)(dev->uclass_priv);
|
||||
|
||||
if (!uc_priv->mdio_bus)
|
||||
uc_priv->mdio_bus = mdio_bus;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct mii_dev *eth_phy_get_mdio_bus(struct udevice *eth_dev)
|
||||
{
|
||||
int ret;
|
||||
struct udevice *phy_dev;
|
||||
struct eth_phy_device_priv *uc_priv;
|
||||
|
||||
/* Will probe the parent of phy device, then phy device */
|
||||
ret = uclass_get_device_by_phandle(UCLASS_ETH_PHY, eth_dev,
|
||||
"phy-handle", &phy_dev);
|
||||
if (!ret) {
|
||||
if (eth_dev != phy_dev->parent) {
|
||||
/*
|
||||
* phy_dev is shared and controlled by
|
||||
* other eth controller
|
||||
*/
|
||||
uc_priv = (struct eth_phy_device_priv *)(phy_dev->uclass_priv);
|
||||
if (uc_priv->mdio_bus)
|
||||
printf("Get shared mii bus on %s\n", eth_dev->name);
|
||||
else
|
||||
printf("Can't get shared mii bus on %s\n", eth_dev->name);
|
||||
|
||||
return uc_priv->mdio_bus;
|
||||
}
|
||||
} else {
|
||||
printf("FEC: can't find phy-handle\n");
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int eth_phy_get_addr(struct udevice *dev)
|
||||
{
|
||||
struct ofnode_phandle_args phandle_args;
|
||||
int reg;
|
||||
|
||||
if (dev_read_phandle_with_args(dev, "phy-handle", NULL, 0, 0,
|
||||
&phandle_args)) {
|
||||
debug("Failed to find phy-handle");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
reg = ofnode_read_u32_default(phandle_args.node, "reg", 0);
|
||||
|
||||
return reg;
|
||||
}
|
||||
|
||||
UCLASS_DRIVER(eth_phy_generic) = {
|
||||
.id = UCLASS_ETH_PHY,
|
||||
.name = "eth_phy_generic",
|
||||
.per_device_auto_alloc_size = sizeof(struct eth_phy_device_priv),
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(eth_phy_generic_drv) = {
|
||||
.name = "eth_phy_generic_drv",
|
||||
.id = UCLASS_ETH_PHY,
|
||||
};
|
|
@ -28,6 +28,7 @@
|
|||
#include <asm-generic/gpio.h>
|
||||
|
||||
#include "fec_mxc.h"
|
||||
#include <eth_phy.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
|
@ -1204,6 +1205,13 @@ int fecmxc_initialize_multi(bd_t *bd, int dev_id, int phy_id, uint32_t addr)
|
|||
#endif
|
||||
int ret;
|
||||
|
||||
if (CONFIG_IS_ENABLED(IMX_MODULE_FUSE)) {
|
||||
if (enet_fused((ulong)addr)) {
|
||||
printf("SoC fuse indicates Ethernet@0x%x is unavailable.\n", addr);
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FEC_MXC_MDIO_BASE
|
||||
/*
|
||||
* The i.MX28 has two ethernet interfaces, but they are not equal.
|
||||
|
@ -1342,6 +1350,13 @@ static int fecmxc_probe(struct udevice *dev)
|
|||
uint32_t start;
|
||||
int ret;
|
||||
|
||||
if (CONFIG_IS_ENABLED(IMX_MODULE_FUSE)) {
|
||||
if (enet_fused((ulong)priv->eth)) {
|
||||
printf("SoC fuse indicates Ethernet@0x%lx is unavailable.\n", (ulong)priv->eth);
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_IMX8)) {
|
||||
ret = clk_get_by_name(dev, "ipg", &priv->ipg_clk);
|
||||
if (ret < 0) {
|
||||
|
@ -1430,16 +1445,27 @@ static int fecmxc_probe(struct udevice *dev)
|
|||
fec_reg_setup(priv);
|
||||
|
||||
priv->dev_id = dev->seq;
|
||||
#ifdef CONFIG_FEC_MXC_MDIO_BASE
|
||||
bus = fec_get_miibus((ulong)CONFIG_FEC_MXC_MDIO_BASE, dev->seq);
|
||||
#else
|
||||
bus = fec_get_miibus((ulong)priv->eth, dev->seq);
|
||||
|
||||
#ifdef CONFIG_DM_ETH_PHY
|
||||
bus = eth_phy_get_mdio_bus(dev);
|
||||
#endif
|
||||
|
||||
if (!bus) {
|
||||
#ifdef CONFIG_FEC_MXC_MDIO_BASE
|
||||
bus = fec_get_miibus((ulong)CONFIG_FEC_MXC_MDIO_BASE, dev->seq);
|
||||
#else
|
||||
bus = fec_get_miibus((ulong)priv->eth, dev->seq);
|
||||
#endif
|
||||
}
|
||||
if (!bus) {
|
||||
ret = -ENOMEM;
|
||||
goto err_mii;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DM_ETH_PHY
|
||||
eth_phy_set_mdio_bus(dev, bus);
|
||||
#endif
|
||||
|
||||
priv->bus = bus;
|
||||
priv->interface = pdata->phy_interface;
|
||||
switch (priv->interface) {
|
||||
|
|
|
@ -273,8 +273,6 @@ struct fec_priv {
|
|||
u32 clk_rate;
|
||||
};
|
||||
|
||||
void imx_get_mac_from_fuse(int dev_id, unsigned char *mac);
|
||||
|
||||
/**
|
||||
* @brief Numbers of buffer descriptors for receiving
|
||||
*
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
|
||||
#define MIIM_RTL8211F_PAGE_SELECT 0x1f
|
||||
#define MIIM_RTL8211F_TX_DELAY 0x100
|
||||
#define MIIM_RTL8211F_RX_DELAY 0x8
|
||||
#define MIIM_RTL8211F_LCR 0x10
|
||||
|
||||
static int rtl8211f_phy_extread(struct phy_device *phydev, int addr,
|
||||
|
@ -183,6 +184,16 @@ static int rtl8211f_config(struct phy_device *phydev)
|
|||
reg &= ~MIIM_RTL8211F_TX_DELAY;
|
||||
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, 0x11, reg);
|
||||
|
||||
/* enable RX-delay for rgmii-id and rgmii-rxid, otherwise disable it */
|
||||
reg = phy_read(phydev, MDIO_DEVAD_NONE, 0x15);
|
||||
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
|
||||
phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
|
||||
reg |= MIIM_RTL8211F_RX_DELAY;
|
||||
else
|
||||
reg &= ~MIIM_RTL8211F_RX_DELAY;
|
||||
phy_write(phydev, MDIO_DEVAD_NONE, 0x15, reg);
|
||||
|
||||
/* restore to default page 0 */
|
||||
phy_write(phydev, MDIO_DEVAD_NONE,
|
||||
MIIM_RTL8211F_PAGE_SELECT, 0x0);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2018 NXP
|
||||
* Copyright 2018-2019 NXP
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
@ -29,6 +29,11 @@ static int imx_pinconf_scu_set(struct imx_pinctrl_soc_info *info, u32 pad,
|
|||
* to handle that in scfw, so config it in pad conf func
|
||||
*/
|
||||
|
||||
if (!sc_rm_is_pad_owned(-1, pad)) {
|
||||
debug("Pad[%u] is not owned by curr partition\n", pad);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
val |= PADRING_IFMUX_EN_MASK;
|
||||
val |= PADRING_GP_EN_MASK;
|
||||
val |= (mux << PADRING_IFMUX_SHIFT) & PADRING_IFMUX_MASK;
|
||||
|
@ -57,7 +62,7 @@ int imx_pinctrl_scu_conf_pins(struct imx_pinctrl_soc_info *info, u32 *pin_data,
|
|||
config_val = pin_data[j++];
|
||||
|
||||
ret = imx_pinconf_scu_set(info, pin_id, mux, config_val);
|
||||
if (ret)
|
||||
if (ret && ret != -EPERM)
|
||||
printf("Set pin %d, mux %d, val %d, error\n", pin_id,
|
||||
mux, config_val);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <asm/arch/power-domain.h>
|
||||
#include <dm/device-internal.h>
|
||||
#include <dm/device.h>
|
||||
#include <dm/uclass-internal.h>
|
||||
#include <asm/arch/sci/sci.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
@ -19,6 +20,68 @@ struct imx8_power_domain_priv {
|
|||
bool state_on;
|
||||
};
|
||||
|
||||
static bool check_device_power_off(struct udevice *dev,
|
||||
const char *permanent_on_devices[],
|
||||
int size)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
if (!strcmp(dev->name, permanent_on_devices[i]))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void imx8_power_off_pd_devices(const char *permanent_on_devices[], int size)
|
||||
{
|
||||
struct udevice *dev;
|
||||
struct power_domain pd;
|
||||
|
||||
for (uclass_find_first_device(UCLASS_POWER_DOMAIN, &dev); dev;
|
||||
uclass_find_next_device(&dev)) {
|
||||
if (!device_active(dev))
|
||||
continue;
|
||||
/*
|
||||
* Power off active pd devices except the permanent
|
||||
* power on devices
|
||||
*/
|
||||
if (check_device_power_off(dev, permanent_on_devices, size)) {
|
||||
pd.dev = dev;
|
||||
power_domain_off(&pd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int imx8_power_domain_lookup_name(const char *name,
|
||||
struct power_domain *power_domain)
|
||||
{
|
||||
struct udevice *dev;
|
||||
struct power_domain_ops *ops;
|
||||
int ret;
|
||||
|
||||
debug("%s(power_domain=%p name=%s)\n", __func__, power_domain, name);
|
||||
|
||||
ret = uclass_get_device_by_name(UCLASS_POWER_DOMAIN, name, &dev);
|
||||
if (ret) {
|
||||
printf("%s fail: %s, ret = %d\n", __func__, name, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ops = (struct power_domain_ops *)dev->driver->ops;
|
||||
power_domain->dev = dev;
|
||||
ret = ops->request(power_domain);
|
||||
if (ret) {
|
||||
debug("ops->request() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
debug("%s ok: %s\n", __func__, dev->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int imx8_power_domain_request(struct power_domain *power_domain)
|
||||
{
|
||||
debug("%s(power_domain=%p)\n", __func__, power_domain);
|
||||
|
@ -62,7 +125,10 @@ static int imx8_power_domain_on(struct power_domain *power_domain)
|
|||
if (ppriv->state_on)
|
||||
return 0;
|
||||
|
||||
if (pdata->resource_id != SC_R_LAST) {
|
||||
if (pdata->resource_id != SC_R_NONE) {
|
||||
if (!sc_rm_is_resource_owned(-1, pdata->resource_id))
|
||||
printf("%s [%d] not owned by curr partition\n", dev->name, pdata->resource_id);
|
||||
|
||||
ret = sc_pm_set_resource_power_mode(-1, pdata->resource_id,
|
||||
SC_PM_PW_MODE_ON);
|
||||
if (ret) {
|
||||
|
@ -108,14 +174,14 @@ static int imx8_power_domain_off_node(struct power_domain *power_domain)
|
|||
}
|
||||
}
|
||||
|
||||
if (pdata->resource_id != SC_R_LAST) {
|
||||
if (!sc_rm_is_resource_owned(-1, pdata->resource_id)) {
|
||||
printf("%s not owned by curr partition\n", dev->name);
|
||||
return 0;
|
||||
}
|
||||
if (pdata->resource_id != SC_R_NONE) {
|
||||
ret = sc_pm_set_resource_power_mode(-1, pdata->resource_id,
|
||||
SC_PM_PW_MODE_OFF);
|
||||
if (ret) {
|
||||
if (!sc_rm_is_resource_owned(-1, pdata->resource_id)) {
|
||||
printf("%s not owned by curr partition %d\n", dev->name, pdata->resource_id);
|
||||
return 0;
|
||||
}
|
||||
printf("Error: %s Power off failed! (error = %d)\n",
|
||||
dev->name, ret);
|
||||
return -EIO;
|
||||
|
@ -171,7 +237,7 @@ static int imx8_power_domain_off_parentnodes(struct power_domain *power_domain)
|
|||
}
|
||||
|
||||
/* power off parent */
|
||||
if (pdata->resource_id != SC_R_LAST) {
|
||||
if (pdata->resource_id != SC_R_NONE) {
|
||||
ret = sc_pm_set_resource_power_mode(-1,
|
||||
pdata->resource_id,
|
||||
SC_PM_PW_MODE_OFF);
|
||||
|
@ -313,4 +379,5 @@ U_BOOT_DRIVER(imx8_power_domain) = {
|
|||
.platdata_auto_alloc_size = sizeof(struct imx8_power_domain_platdata),
|
||||
.priv_auto_alloc_size = sizeof(struct imx8_power_domain_priv),
|
||||
.ops = &imx8_power_domain_ops,
|
||||
.flags = DM_FLAG_DEFAULT_PD_CTRL_OFF,
|
||||
};
|
||||
|
|
|
@ -26,6 +26,15 @@ config IMX_SCU_THERMAL
|
|||
boot is hold to the cool device to throttle CPUs when the passive
|
||||
trip is crossed
|
||||
|
||||
config IMX_TMU
|
||||
bool "Thermal Management Unit driver for NXP i.MX8M"
|
||||
depends on ARCH_IMX8M
|
||||
help
|
||||
Support for Temperature sensors on NXP i.MX8M.
|
||||
It supports one critical trip point and one passive trip point.
|
||||
The boot is hold to the cool device to throttle CPUs when the
|
||||
passive trip is crossed
|
||||
|
||||
config TI_DRA7_THERMAL
|
||||
bool "Temperature sensor driver for TI dra7xx SOCs"
|
||||
help
|
||||
|
|
|
@ -7,3 +7,4 @@ obj-$(CONFIG_DM_THERMAL) += thermal-uclass.o
|
|||
obj-$(CONFIG_IMX_THERMAL) += imx_thermal.o
|
||||
obj-$(CONFIG_IMX_SCU_THERMAL) += imx_scu_thermal.o
|
||||
obj-$(CONFIG_TI_DRA7_THERMAL) += ti-bandgap.o
|
||||
obj-$(CONFIG_IMX_TMU) += imx_tmu.o
|
||||
|
|
|
@ -179,12 +179,20 @@ static int imx_sc_thermal_ofdata_to_platdata(struct udevice *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const sc_rsrc_t imx8qm_sensor_rsrc[] = {
|
||||
SC_R_A53, SC_R_A72, SC_R_GPU_0_PID0, SC_R_GPU_1_PID0,
|
||||
SC_R_DRC_0, SC_R_DRC_1, SC_R_VPU_PID0, SC_R_PMIC_0,
|
||||
SC_R_PMIC_1, SC_R_PMIC_2,
|
||||
};
|
||||
|
||||
static const sc_rsrc_t imx8qxp_sensor_rsrc[] = {
|
||||
SC_R_SYSTEM, SC_R_DRC_0, SC_R_PMIC_0,
|
||||
SC_R_PMIC_1, SC_R_PMIC_2,
|
||||
};
|
||||
|
||||
static const struct udevice_id imx_sc_thermal_ids[] = {
|
||||
{ .compatible = "nxp,imx8qm-sc-tsens", .data =
|
||||
(ulong)&imx8qm_sensor_rsrc, },
|
||||
{ .compatible = "nxp,imx8qxp-sc-tsens", .data =
|
||||
(ulong)&imx8qxp_sensor_rsrc, },
|
||||
{ }
|
||||
|
|
467
drivers/thermal/imx_tmu.c
Normal file
467
drivers/thermal/imx_tmu.c
Normal file
|
@ -0,0 +1,467 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2017~2020 NXP
|
||||
*
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/sys_proto.h>
|
||||
#include <dm.h>
|
||||
#include <dm/device-internal.h>
|
||||
#include <dm/device.h>
|
||||
#include <errno.h>
|
||||
#include <fuse.h>
|
||||
#include <malloc.h>
|
||||
#include <thermal.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define SITES_MAX 16
|
||||
#define FLAGS_VER2 0x1
|
||||
#define FLAGS_VER3 0x2
|
||||
|
||||
#define TMR_DISABLE 0x0
|
||||
#define TMR_ME 0x80000000
|
||||
#define TMR_ALPF 0x0c000000
|
||||
#define TMTMIR_DEFAULT 0x00000002
|
||||
#define TIER_DISABLE 0x0
|
||||
|
||||
#define TER_EN 0x80000000
|
||||
#define TER_ADC_PD 0x40000000
|
||||
#define TER_ALPF 0x3
|
||||
|
||||
/*
|
||||
* i.MX TMU Registers
|
||||
*/
|
||||
struct imx_tmu_site_regs {
|
||||
u32 tritsr; /* Immediate Temperature Site Register */
|
||||
u32 tratsr; /* Average Temperature Site Register */
|
||||
u8 res0[0x8];
|
||||
};
|
||||
|
||||
struct imx_tmu_regs {
|
||||
u32 tmr; /* Mode Register */
|
||||
u32 tsr; /* Status Register */
|
||||
u32 tmtmir; /* Temperature measurement interval Register */
|
||||
u8 res0[0x14];
|
||||
u32 tier; /* Interrupt Enable Register */
|
||||
u32 tidr; /* Interrupt Detect Register */
|
||||
u32 tiscr; /* Interrupt Site Capture Register */
|
||||
u32 ticscr; /* Interrupt Critical Site Capture Register */
|
||||
u8 res1[0x10];
|
||||
u32 tmhtcrh; /* High Temperature Capture Register */
|
||||
u32 tmhtcrl; /* Low Temperature Capture Register */
|
||||
u8 res2[0x8];
|
||||
u32 tmhtitr; /* High Temperature Immediate Threshold */
|
||||
u32 tmhtatr; /* High Temperature Average Threshold */
|
||||
u32 tmhtactr; /* High Temperature Average Crit Threshold */
|
||||
u8 res3[0x24];
|
||||
u32 ttcfgr; /* Temperature Configuration Register */
|
||||
u32 tscfgr; /* Sensor Configuration Register */
|
||||
u8 res4[0x78];
|
||||
struct imx_tmu_site_regs site[SITES_MAX];
|
||||
u8 res5[0x9f8];
|
||||
u32 ipbrr0; /* IP Block Revision Register 0 */
|
||||
u32 ipbrr1; /* IP Block Revision Register 1 */
|
||||
u8 res6[0x310];
|
||||
u32 ttr0cr; /* Temperature Range 0 Control Register */
|
||||
u32 ttr1cr; /* Temperature Range 1 Control Register */
|
||||
u32 ttr2cr; /* Temperature Range 2 Control Register */
|
||||
u32 ttr3cr; /* Temperature Range 3 Control Register */
|
||||
};
|
||||
|
||||
struct imx_tmu_regs_v2 {
|
||||
u32 ter; /* TMU enable Register */
|
||||
u32 tsr; /* Status Register */
|
||||
u32 tier; /* Interrupt enable register */
|
||||
u32 tidr; /* Interrupt detect register */
|
||||
u32 tmhtitr; /* Monitor high temperature immediate threshold register */
|
||||
u32 tmhtatr; /* Monitor high temperature average threshold register */
|
||||
u32 tmhtactr; /* TMU monitor high temperature average critical threshold register */
|
||||
u32 tscr; /* Sensor value capture register */
|
||||
u32 tritsr; /* Report immediate temperature site register 0 */
|
||||
u32 tratsr; /* Report average temperature site register 0 */
|
||||
u32 tasr; /* Amplifier setting register */
|
||||
u32 ttmc; /* Test MUX control */
|
||||
u32 tcaliv;
|
||||
};
|
||||
|
||||
struct imx_tmu_regs_v3 {
|
||||
u32 ter; /* TMU enable Register */
|
||||
u32 tps; /* Status Register */
|
||||
u32 tier; /* Interrupt enable register */
|
||||
u32 tidr; /* Interrupt detect register */
|
||||
u32 tmhtitr; /* Monitor high temperature immediate threshold register */
|
||||
u32 tmhtatr; /* Monitor high temperature average threshold register */
|
||||
u32 tmhtactr; /* TMU monitor high temperature average critical threshold register */
|
||||
u32 tscr; /* Sensor value capture register */
|
||||
u32 tritsr; /* Report immediate temperature site register 0 */
|
||||
u32 tratsr; /* Report average temperature site register 0 */
|
||||
u32 tasr; /* Amplifier setting register */
|
||||
u32 ttmc; /* Test MUX control */
|
||||
u32 tcaliv0;
|
||||
u32 tcaliv1;
|
||||
u32 tcaliv_m40;
|
||||
u32 trim;
|
||||
};
|
||||
|
||||
union tmu_regs {
|
||||
struct imx_tmu_regs regs_v1;
|
||||
struct imx_tmu_regs_v2 regs_v2;
|
||||
struct imx_tmu_regs_v3 regs_v3;
|
||||
};
|
||||
|
||||
struct imx_tmu_plat {
|
||||
int critical;
|
||||
int alert;
|
||||
int polling_delay;
|
||||
int id;
|
||||
bool zone_node;
|
||||
union tmu_regs *regs;
|
||||
};
|
||||
|
||||
static int read_temperature(struct udevice *dev, int *temp)
|
||||
{
|
||||
struct imx_tmu_plat *pdata = dev_get_platdata(dev);
|
||||
ulong drv_data = dev_get_driver_data(dev);
|
||||
u32 val;
|
||||
u32 retry = 10;
|
||||
u32 valid = 0;
|
||||
|
||||
do {
|
||||
mdelay(100);
|
||||
retry--;
|
||||
|
||||
if (drv_data & FLAGS_VER3) {
|
||||
val = readl(&pdata->regs->regs_v3.tritsr);
|
||||
valid = val & (1 << (30 + pdata->id));
|
||||
} else if (drv_data & FLAGS_VER2) {
|
||||
val = readl(&pdata->regs->regs_v2.tritsr);
|
||||
/*
|
||||
* Check if TEMP is in valid range, the V bit in TRITSR
|
||||
* only reflects the RAW uncalibrated data
|
||||
*/
|
||||
valid = ((val & 0xff) < 10 || (val & 0xff) > 125) ? 0 : 1;
|
||||
} else {
|
||||
val = readl(&pdata->regs->regs_v1.site[pdata->id].tritsr);
|
||||
valid = val & 0x80000000;
|
||||
}
|
||||
} while (!valid && retry > 0);
|
||||
|
||||
if (retry > 0) {
|
||||
if (drv_data & FLAGS_VER3) {
|
||||
val = (val >> (pdata->id * 16)) & 0xff;
|
||||
if (val & 0x80) /* Negative */
|
||||
val = (~(val & 0x7f) + 1);
|
||||
|
||||
*temp = val;
|
||||
if (*temp < -40 || *temp > 125) /* Check the range */
|
||||
return -EINVAL;
|
||||
|
||||
*temp *= 1000;
|
||||
} else {
|
||||
*temp = (val & 0xff) * 1000;
|
||||
}
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int imx_tmu_get_temp(struct udevice *dev, int *temp)
|
||||
{
|
||||
struct imx_tmu_plat *pdata = dev_get_platdata(dev);
|
||||
int cpu_tmp = 0;
|
||||
int ret;
|
||||
|
||||
ret = read_temperature(dev, &cpu_tmp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
while (cpu_tmp >= pdata->alert) {
|
||||
printf("CPU Temperature (%dC) has beyond alert (%dC), close to critical (%dC)", cpu_tmp, pdata->alert, pdata->critical);
|
||||
puts(" waiting...\n");
|
||||
mdelay(pdata->polling_delay);
|
||||
ret = read_temperature(dev, &cpu_tmp);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
*temp = cpu_tmp / 1000;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dm_thermal_ops imx_tmu_ops = {
|
||||
.get_temp = imx_tmu_get_temp,
|
||||
};
|
||||
|
||||
static int imx_tmu_calibration(struct udevice *dev)
|
||||
{
|
||||
int i, val, len, ret;
|
||||
u32 range[4];
|
||||
const fdt32_t *calibration;
|
||||
struct imx_tmu_plat *pdata = dev_get_platdata(dev);
|
||||
ulong drv_data = dev_get_driver_data(dev);
|
||||
|
||||
debug("%s\n", __func__);
|
||||
|
||||
if (drv_data & (FLAGS_VER2 | FLAGS_VER3))
|
||||
return 0;
|
||||
|
||||
ret = dev_read_u32_array(dev, "fsl,tmu-range", range, 4);
|
||||
if (ret) {
|
||||
printf("TMU: missing calibration range, ret = %d.\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Init temperature range registers */
|
||||
writel(range[0], &pdata->regs->regs_v1.ttr0cr);
|
||||
writel(range[1], &pdata->regs->regs_v1.ttr1cr);
|
||||
writel(range[2], &pdata->regs->regs_v1.ttr2cr);
|
||||
writel(range[3], &pdata->regs->regs_v1.ttr3cr);
|
||||
|
||||
calibration = dev_read_prop(dev, "fsl,tmu-calibration", &len);
|
||||
if (!calibration || len % 8) {
|
||||
printf("TMU: invalid calibration data.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
for (i = 0; i < len; i += 8, calibration += 2) {
|
||||
val = fdt32_to_cpu(*calibration);
|
||||
writel(val, &pdata->regs->regs_v1.ttcfgr);
|
||||
val = fdt32_to_cpu(*(calibration + 1));
|
||||
writel(val, &pdata->regs->regs_v1.tscfgr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __weak imx_tmu_arch_init(void *reg_base)
|
||||
{
|
||||
}
|
||||
|
||||
static void imx_tmu_init(struct udevice *dev)
|
||||
{
|
||||
struct imx_tmu_plat *pdata = dev_get_platdata(dev);
|
||||
ulong drv_data = dev_get_driver_data(dev);
|
||||
|
||||
debug("%s\n", __func__);
|
||||
|
||||
if (drv_data & FLAGS_VER3) {
|
||||
/* Disable monitoring */
|
||||
writel(0x0, &pdata->regs->regs_v3.ter);
|
||||
|
||||
/* Disable interrupt, using polling instead */
|
||||
writel(0x0, &pdata->regs->regs_v3.tier);
|
||||
|
||||
} else if (drv_data & FLAGS_VER2) {
|
||||
/* Disable monitoring */
|
||||
writel(0x0, &pdata->regs->regs_v2.ter);
|
||||
|
||||
/* Disable interrupt, using polling instead */
|
||||
writel(0x0, &pdata->regs->regs_v2.tier);
|
||||
} else {
|
||||
/* Disable monitoring */
|
||||
writel(TMR_DISABLE, &pdata->regs->regs_v1.tmr);
|
||||
|
||||
/* Disable interrupt, using polling instead */
|
||||
writel(TIER_DISABLE, &pdata->regs->regs_v1.tier);
|
||||
|
||||
/* Set update_interval */
|
||||
writel(TMTMIR_DEFAULT, &pdata->regs->regs_v1.tmtmir);
|
||||
}
|
||||
|
||||
imx_tmu_arch_init((void *)pdata->regs);
|
||||
}
|
||||
|
||||
static int imx_tmu_enable_msite(struct udevice *dev)
|
||||
{
|
||||
struct imx_tmu_plat *pdata = dev_get_platdata(dev);
|
||||
ulong drv_data = dev_get_driver_data(dev);
|
||||
u32 reg;
|
||||
|
||||
debug("%s\n", __func__);
|
||||
|
||||
if (!pdata->regs)
|
||||
return -EIO;
|
||||
|
||||
if (drv_data & FLAGS_VER3) {
|
||||
reg = readl(&pdata->regs->regs_v3.ter);
|
||||
reg &= ~TER_EN;
|
||||
writel(reg, &pdata->regs->regs_v3.ter);
|
||||
|
||||
writel(pdata->id << 30, &pdata->regs->regs_v3.tps);
|
||||
|
||||
reg &= ~TER_ALPF;
|
||||
reg |= 0x1;
|
||||
reg &= ~TER_ADC_PD;
|
||||
writel(reg, &pdata->regs->regs_v3.ter);
|
||||
|
||||
/* Enable monitor */
|
||||
reg |= TER_EN;
|
||||
writel(reg, &pdata->regs->regs_v3.ter);
|
||||
} else if (drv_data & FLAGS_VER2) {
|
||||
reg = readl(&pdata->regs->regs_v2.ter);
|
||||
reg &= ~TER_EN;
|
||||
writel(reg, &pdata->regs->regs_v2.ter);
|
||||
|
||||
reg &= ~TER_ALPF;
|
||||
reg |= 0x1;
|
||||
writel(reg, &pdata->regs->regs_v2.ter);
|
||||
|
||||
/* Enable monitor */
|
||||
reg |= TER_EN;
|
||||
writel(reg, &pdata->regs->regs_v2.ter);
|
||||
} else {
|
||||
/* Clear the ME before setting MSITE and ALPF*/
|
||||
reg = readl(&pdata->regs->regs_v1.tmr);
|
||||
reg &= ~TMR_ME;
|
||||
writel(reg, &pdata->regs->regs_v1.tmr);
|
||||
|
||||
reg |= 1 << (15 - pdata->id);
|
||||
reg |= TMR_ALPF;
|
||||
writel(reg, &pdata->regs->regs_v1.tmr);
|
||||
|
||||
/* Enable ME */
|
||||
reg |= TMR_ME;
|
||||
writel(reg, &pdata->regs->regs_v1.tmr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int imx_tmu_bind(struct udevice *dev)
|
||||
{
|
||||
struct imx_tmu_plat *pdata = dev_get_platdata(dev);
|
||||
int ret;
|
||||
ofnode node, offset;
|
||||
const char *name;
|
||||
const void *prop;
|
||||
|
||||
debug("%s dev name %s\n", __func__, dev->name);
|
||||
|
||||
prop = dev_read_prop(dev, "compatible", NULL);
|
||||
if (!prop)
|
||||
return 0;
|
||||
|
||||
pdata->zone_node = 1;
|
||||
|
||||
node = ofnode_path("/thermal-zones");
|
||||
ofnode_for_each_subnode(offset, node) {
|
||||
/* Bind the subnode to this driver */
|
||||
name = ofnode_get_name(offset);
|
||||
|
||||
ret = device_bind_with_driver_data(dev, dev->driver, name,
|
||||
dev->driver_data, offset,
|
||||
NULL);
|
||||
if (ret)
|
||||
printf("Error binding driver '%s': %d\n",
|
||||
dev->driver->name, ret);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int imx_tmu_parse_fdt(struct udevice *dev)
|
||||
{
|
||||
struct imx_tmu_plat *pdata = dev_get_platdata(dev), *p_parent_data;
|
||||
struct ofnode_phandle_args args;
|
||||
ofnode trips_np;
|
||||
int ret;
|
||||
|
||||
debug("%s dev name %s\n", __func__, dev->name);
|
||||
|
||||
if (pdata->zone_node) {
|
||||
pdata->regs = (union tmu_regs *)dev_read_addr_ptr(dev);
|
||||
|
||||
if (!pdata->regs)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
p_parent_data = dev_get_platdata(dev->parent);
|
||||
if (p_parent_data->zone_node)
|
||||
pdata->regs = p_parent_data->regs;
|
||||
|
||||
ret = dev_read_phandle_with_args(dev, "thermal-sensors",
|
||||
"#thermal-sensor-cells",
|
||||
0, 0, &args);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!ofnode_equal(args.node, dev_ofnode(dev->parent)))
|
||||
return -EFAULT;
|
||||
|
||||
if (args.args_count >= 1)
|
||||
pdata->id = args.args[0];
|
||||
else
|
||||
pdata->id = 0;
|
||||
|
||||
debug("args.args_count %d, id %d\n", args.args_count, pdata->id);
|
||||
|
||||
pdata->polling_delay = dev_read_u32_default(dev, "polling-delay", 1000);
|
||||
|
||||
trips_np = ofnode_path("/thermal-zones/cpu-thermal/trips");
|
||||
ofnode_for_each_subnode(trips_np, trips_np) {
|
||||
const char *type;
|
||||
|
||||
type = ofnode_get_property(trips_np, "type", NULL);
|
||||
if (!type)
|
||||
continue;
|
||||
if (!strcmp(type, "critical"))
|
||||
pdata->critical = ofnode_read_u32_default(trips_np, "temperature", 85);
|
||||
else if (strcmp(type, "passive") == 0)
|
||||
pdata->alert = ofnode_read_u32_default(trips_np, "temperature", 80);
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
debug("id %d polling_delay %d, critical %d, alert %d\n",
|
||||
pdata->id, pdata->polling_delay, pdata->critical, pdata->alert);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int imx_tmu_probe(struct udevice *dev)
|
||||
{
|
||||
struct imx_tmu_plat *pdata = dev_get_platdata(dev);
|
||||
int ret;
|
||||
|
||||
ret = imx_tmu_parse_fdt(dev);
|
||||
if (ret) {
|
||||
printf("Error in parsing TMU FDT %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (pdata->zone_node) {
|
||||
imx_tmu_init(dev);
|
||||
imx_tmu_calibration(dev);
|
||||
} else {
|
||||
imx_tmu_enable_msite(dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct udevice_id imx_tmu_ids[] = {
|
||||
{ .compatible = "fsl,imx8mq-tmu", },
|
||||
{ .compatible = "fsl,imx8mm-tmu", .data = FLAGS_VER2, },
|
||||
{ .compatible = "fsl,imx8mp-tmu", .data = FLAGS_VER3, },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(imx_tmu) = {
|
||||
.name = "imx_tmu",
|
||||
.id = UCLASS_THERMAL,
|
||||
.ops = &imx_tmu_ops,
|
||||
.of_match = imx_tmu_ids,
|
||||
.bind = imx_tmu_bind,
|
||||
.probe = imx_tmu_probe,
|
||||
.platdata_auto_alloc_size = sizeof(struct imx_tmu_plat),
|
||||
.flags = DM_FLAG_PRE_RELOC,
|
||||
};
|
|
@ -122,6 +122,10 @@ config USB_GADGET_VBUS_DRAW
|
|||
This value will be used except for system-specific gadget
|
||||
drivers that have more specific information.
|
||||
|
||||
config SDP_LOADADDR
|
||||
hex "Default load address at SDP_WRITE and SDP_JUMP"
|
||||
default 0
|
||||
|
||||
# Selected by UDC drivers that support high-speed operation.
|
||||
config USB_GADGET_DUALSPEED
|
||||
bool
|
||||
|
|
|
@ -276,7 +276,7 @@ static void sdp_rx_command_complete(struct usb_ep *ep, struct usb_request *req)
|
|||
sdp->error_status = SDP_WRITE_FILE_COMPLETE;
|
||||
|
||||
sdp->state = SDP_STATE_RX_FILE_DATA;
|
||||
sdp->dnl_address = be32_to_cpu(cmd->addr);
|
||||
sdp->dnl_address = cmd->addr ? be32_to_cpu(cmd->addr) : CONFIG_SDP_LOADADDR;
|
||||
sdp->dnl_bytes_remaining = be32_to_cpu(cmd->cnt);
|
||||
sdp->dnl_bytes = sdp->dnl_bytes_remaining;
|
||||
sdp->next_state = SDP_STATE_IDLE;
|
||||
|
@ -304,7 +304,7 @@ static void sdp_rx_command_complete(struct usb_ep *ep, struct usb_request *req)
|
|||
sdp->always_send_status = false;
|
||||
sdp->error_status = 0;
|
||||
|
||||
sdp->jmp_address = be32_to_cpu(cmd->addr);
|
||||
sdp->jmp_address = cmd->addr ? be32_to_cpu(cmd->addr) : CONFIG_SDP_LOADADDR;
|
||||
sdp->state = SDP_STATE_TX_SEC_CONF;
|
||||
sdp->next_state = SDP_STATE_JUMP;
|
||||
break;
|
||||
|
|
|
@ -380,6 +380,14 @@ int ehci_hcd_init(int index, enum usb_init_type init,
|
|||
if (index > 3)
|
||||
return -EINVAL;
|
||||
|
||||
if (CONFIG_IS_ENABLED(IMX_MODULE_FUSE)) {
|
||||
if (usb_fused((ulong)ehci)) {
|
||||
printf("SoC fuse indicates USB@0x%lx is unavailable.\n",
|
||||
(ulong)ehci);
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
ret = ehci_mx6_common_init(ehci, index);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -577,6 +585,14 @@ static int ehci_usb_probe(struct udevice *dev)
|
|||
struct ehci_hcor *hcor;
|
||||
int ret;
|
||||
|
||||
if (CONFIG_IS_ENABLED(IMX_MODULE_FUSE)) {
|
||||
if (usb_fused((ulong)ehci)) {
|
||||
printf("SoC fuse indicates USB@0x%lx is unavailable.\n",
|
||||
(ulong)ehci);
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
priv->ehci = ehci;
|
||||
priv->portnr = dev->seq;
|
||||
priv->init_type = type;
|
||||
|
|
152
include/configs/imx8mm_beacon.h
Normal file
152
include/configs/imx8mm_beacon.h
Normal file
|
@ -0,0 +1,152 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2020 Compass Electronics Group, LLC
|
||||
*/
|
||||
|
||||
#ifndef __IMX8MM_BEACON_H
|
||||
#define __IMX8MM_BEACON_H
|
||||
|
||||
#include <linux/sizes.h>
|
||||
#include <asm/arch/imx-regs.h>
|
||||
|
||||
#ifdef CONFIG_SECURE_BOOT
|
||||
#define CONFIG_CSF_SIZE SZ_8K
|
||||
#endif
|
||||
|
||||
#define CONFIG_SPL_MAX_SIZE (148 * 1024)
|
||||
#define CONFIG_SYS_MONITOR_LEN SZ_512K
|
||||
#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
|
||||
#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 0x300
|
||||
#define CONFIG_SYS_MMCSD_FS_BOOT_PARTITION 1
|
||||
#define CONFIG_SYS_UBOOT_BASE \
|
||||
(QSPI0_AMBA_BASE + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR * 512)
|
||||
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
#define CONFIG_SPL_STACK 0x920000
|
||||
#define CONFIG_SPL_BSS_START_ADDR 0x910000
|
||||
#define CONFIG_SPL_BSS_MAX_SIZE SZ_8K /* 8 KB */
|
||||
#define CONFIG_SYS_SPL_MALLOC_START 0x42200000
|
||||
#define CONFIG_SYS_SPL_MALLOC_SIZE SZ_512K /* 512 KB */
|
||||
|
||||
/* malloc f used before GD_FLG_FULL_MALLOC_INIT set */
|
||||
#define CONFIG_MALLOC_F_ADDR 0x930000
|
||||
/* For RAW image gives a error info not panic */
|
||||
#define CONFIG_SPL_ABORT_ON_RAW_IMAGE
|
||||
|
||||
#endif
|
||||
|
||||
/* Initial environment variables */
|
||||
#define CONFIG_EXTRA_ENV_SETTINGS \
|
||||
"script=boot.scr\0" \
|
||||
"image=Image\0" \
|
||||
"console=ttymxc1,115200\0" \
|
||||
"fdt_addr=0x43000000\0" \
|
||||
"fdt_high=0xffffffffffffffff\0" \
|
||||
"boot_fit=try\0" \
|
||||
"fdt_file=" CONFIG_DEFAULT_FDT_FILE "\0" \
|
||||
"initrd_addr=0x43800000\0" \
|
||||
"initrd_high=0xffffffffffffffff\0" \
|
||||
"mmcdev=" __stringify(CONFIG_SYS_MMC_ENV_DEV) "\0" \
|
||||
"mmcpart=" __stringify(CONFIG_SYS_MMC_IMG_LOAD_PART) "\0" \
|
||||
"finduuid=part uuid mmc ${mmcdev}:2 uuid\0" \
|
||||
"mmcautodetect=yes\0" \
|
||||
"mmcargs=setenv bootargs console=${console},${baudrate}" \
|
||||
" root=PARTUUID=${uuid} rootwait rw ${mtdparts} ${optargs}\0" \
|
||||
"loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr}" \
|
||||
" ${script};\0" \
|
||||
"bootscript=echo Running bootscript from mmc ...; " \
|
||||
"source\0" \
|
||||
"loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}\0" \
|
||||
"loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}\0" \
|
||||
"mmcboot=echo Booting from mmc ...; " \
|
||||
"run finduuid; " \
|
||||
"run mmcargs; " \
|
||||
"if run loadfdt; then " \
|
||||
"booti ${loadaddr} - ${fdt_addr}; " \
|
||||
"else " \
|
||||
"echo WARN: Cannot load the DT; " \
|
||||
"fi; " \
|
||||
"netargs=setenv bootargs console=${console} " \
|
||||
"root=/dev/nfs " \
|
||||
"ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp\0" \
|
||||
"netboot=echo Booting from net ...; " \
|
||||
"run netargs; " \
|
||||
"if test ${ip_dyn} = yes; then " \
|
||||
"setenv get_cmd dhcp; " \
|
||||
"else " \
|
||||
"setenv get_cmd tftp; " \
|
||||
"fi; " \
|
||||
"${get_cmd} ${loadaddr} ${image}; " \
|
||||
"if test ${boot_fit} = yes || test ${boot_fit} = try; then " \
|
||||
"bootm ${loadaddr}; " \
|
||||
"else " \
|
||||
"if ${get_cmd} ${fdt_addr} ${fdt_file}; then " \
|
||||
"booti ${loadaddr} - ${fdt_addr}; " \
|
||||
"else " \
|
||||
"echo WARN: Cannot load the DT; " \
|
||||
"fi; " \
|
||||
"fi;\0"
|
||||
|
||||
#define CONFIG_BOOTCOMMAND \
|
||||
"mmc dev ${mmcdev}; if mmc rescan; then " \
|
||||
"if run loadbootscript; then " \
|
||||
"run bootscript; " \
|
||||
"else " \
|
||||
"if run loadimage; then " \
|
||||
"run mmcboot; " \
|
||||
"else run netboot; " \
|
||||
"fi; " \
|
||||
"fi; " \
|
||||
"fi;"
|
||||
|
||||
/* Link Definitions */
|
||||
#define CONFIG_LOADADDR 0x40480000
|
||||
|
||||
#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
|
||||
|
||||
#define CONFIG_SYS_INIT_RAM_ADDR 0x40000000
|
||||
#define CONFIG_SYS_INIT_RAM_SIZE 0x200000
|
||||
#define CONFIG_SYS_INIT_SP_OFFSET \
|
||||
(CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE)
|
||||
#define CONFIG_SYS_INIT_SP_ADDR \
|
||||
(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET)
|
||||
|
||||
#define CONFIG_ENV_OVERWRITE
|
||||
#define CONFIG_SYS_MMC_ENV_DEV 1 /* USDHC2 */
|
||||
|
||||
/* Size of malloc() pool */
|
||||
#define CONFIG_SYS_MALLOC_LEN SZ_32M
|
||||
|
||||
#define CONFIG_SYS_SDRAM_BASE 0x40000000
|
||||
#define PHYS_SDRAM 0x40000000
|
||||
#define PHYS_SDRAM_SIZE 0x80000000 /* 2GB DDR */
|
||||
|
||||
#define CONFIG_SYS_MEMTEST_START PHYS_SDRAM
|
||||
#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_MEMTEST_START + (PHYS_SDRAM_SIZE >> 1))
|
||||
|
||||
#define CONFIG_MXC_UART_BASE UART2_BASE_ADDR
|
||||
|
||||
/* Monitor Command Prompt */
|
||||
#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
|
||||
#define CONFIG_SYS_CBSIZE 2048
|
||||
#define CONFIG_SYS_MAXARGS 64
|
||||
#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
|
||||
#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
|
||||
sizeof(CONFIG_SYS_PROMPT) + 16)
|
||||
|
||||
/* USDHC */
|
||||
#define CONFIG_SYS_FSL_USDHC_NUM 2
|
||||
#define CONFIG_SYS_FSL_ESDHC_ADDR 0
|
||||
#define CONFIG_SYS_MMC_IMG_LOAD_PART 1
|
||||
|
||||
/* I2C */
|
||||
#define CONFIG_SYS_I2C_SPEED 100000
|
||||
|
||||
/* FEC*/
|
||||
#define CONFIG_ETHPRIME "FEC"
|
||||
#define CONFIG_FEC_XCV_TYPE RGMII
|
||||
#define CONFIG_FEC_MXC_PHYADDR 0
|
||||
#define FEC_QUIRK_ENET_MAC
|
||||
#define IMX_FEC_BASE 0x30BE0000
|
||||
|
||||
#endif
|
|
@ -70,7 +70,7 @@
|
|||
"fdt_addr=0x83000000\0" \
|
||||
"fdt_high=0xffffffffffffffff\0" \
|
||||
"boot_fdt=try\0" \
|
||||
"fdt_file=imx8qm-mek.dtb\0" \
|
||||
"fdt_file=undefined\0" \
|
||||
"initrd_addr=0x83800000\0" \
|
||||
"initrd_high=0xffffffffffffffff\0" \
|
||||
"mmcdev="__stringify(CONFIG_SYS_MMC_ENV_DEV)"\0" \
|
||||
|
|
|
@ -69,7 +69,7 @@
|
|||
"fdt_addr=0x83000000\0" \
|
||||
"fdt_high=0xffffffffffffffff\0" \
|
||||
"boot_fdt=try\0" \
|
||||
"fdt_file=imx8qxp-mek.dtb\0" \
|
||||
"fdt_file=undefined\0" \
|
||||
"initrd_addr=0x83800000\0" \
|
||||
"initrd_high=0xffffffffffffffff\0" \
|
||||
"mmcdev="__stringify(CONFIG_SYS_MMC_ENV_DEV)"\0" \
|
||||
|
|
199
include/configs/pico-imx8mq.h
Normal file
199
include/configs/pico-imx8mq.h
Normal file
|
@ -0,0 +1,199 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2018 NXP
|
||||
*/
|
||||
|
||||
#ifndef __IMX8M_PICOPI_H
|
||||
#define __IMX8M_PICOPI_H
|
||||
|
||||
#include <linux/sizes.h>
|
||||
#include <asm/arch/imx-regs.h>
|
||||
|
||||
#define CONFIG_SPL_MAX_SIZE (124 * 1024)
|
||||
#define CONFIG_SYS_MONITOR_LEN (512 * 1024)
|
||||
#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
|
||||
#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 0x300
|
||||
#define CONFIG_SYS_MMCSD_FS_BOOT_PARTITION 1
|
||||
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
/*#define CONFIG_ENABLE_DDR_TRAINING_DEBUG*/
|
||||
#define CONFIG_SPL_WATCHDOG_SUPPORT
|
||||
#define CONFIG_SPL_DRIVERS_MISC_SUPPORT
|
||||
#define CONFIG_SPL_POWER_SUPPORT
|
||||
#define CONFIG_SPL_I2C_SUPPORT
|
||||
#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv8/u-boot-spl.lds"
|
||||
#define CONFIG_SPL_STACK 0x187FF0
|
||||
#define CONFIG_SPL_LIBCOMMON_SUPPORT
|
||||
#define CONFIG_SPL_LIBGENERIC_SUPPORT
|
||||
#define CONFIG_SPL_GPIO_SUPPORT
|
||||
#define CONFIG_SPL_MMC_SUPPORT
|
||||
#define CONFIG_SPL_BSS_START_ADDR 0x00180000
|
||||
#define CONFIG_SPL_BSS_MAX_SIZE 0x2000 /* 8 KB */
|
||||
#define CONFIG_SYS_SPL_MALLOC_START 0x42200000
|
||||
#define CONFIG_SYS_SPL_MALLOC_SIZE 0x80000 /* 512 KB */
|
||||
#define CONFIG_SYS_SPL_PTE_RAM_BASE 0x41580000
|
||||
|
||||
/* malloc f used before GD_FLG_FULL_MALLOC_INIT set */
|
||||
#define CONFIG_MALLOC_F_ADDR 0x182000
|
||||
/* For RAW image gives a error info not panic */
|
||||
#define CONFIG_SPL_ABORT_ON_RAW_IMAGE
|
||||
|
||||
#undef CONFIG_DM_MMC
|
||||
#undef CONFIG_DM_PMIC
|
||||
|
||||
#define CONFIG_SYS_I2C
|
||||
#define CONFIG_SYS_I2C_MXC_I2C1 /* enable I2C bus 1 */
|
||||
#define CONFIG_SYS_I2C_MXC_I2C2 /* enable I2C bus 2 */
|
||||
#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */
|
||||
|
||||
#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
|
||||
|
||||
#define CONFIG_POWER
|
||||
#define CONFIG_POWER_I2C
|
||||
#endif
|
||||
|
||||
#define CONFIG_REMAKE_ELF
|
||||
|
||||
#define CONFIG_BOARD_EARLY_INIT_F
|
||||
#define CONFIG_BOARD_LATE_INIT
|
||||
|
||||
#undef CONFIG_CMD_EXPORTENV
|
||||
#undef CONFIG_CMD_IMPORTENV
|
||||
#undef CONFIG_CMD_IMLS
|
||||
|
||||
#undef CONFIG_CMD_CRC32
|
||||
|
||||
/* ENET Config */
|
||||
/* ENET1 */
|
||||
#if defined(CONFIG_CMD_NET)
|
||||
#define CONFIG_CMD_PING
|
||||
#define CONFIG_CMD_DHCP
|
||||
#define CONFIG_CMD_MII
|
||||
#define CONFIG_MII
|
||||
#define CONFIG_ETHPRIME "FEC"
|
||||
|
||||
#define CONFIG_FEC_MXC
|
||||
#define CONFIG_FEC_XCV_TYPE RGMII
|
||||
#define CONFIG_FEC_MXC_PHYADDR 1
|
||||
#define FEC_QUIRK_ENET_MAC
|
||||
|
||||
#define CONFIG_PHY_GIGE
|
||||
#define IMX_FEC_BASE 0x30BE0000
|
||||
|
||||
#define CONFIG_PHYLIB
|
||||
#define CONFIG_PHY_ATHEROS
|
||||
#endif
|
||||
|
||||
/* Initial environment variables */
|
||||
#define CONFIG_EXTRA_ENV_SETTINGS \
|
||||
"script=boot.scr\0" \
|
||||
"image=Image\0" \
|
||||
"console=ttymxc0,115200\0" \
|
||||
"fdt_addr=0x43000000\0" \
|
||||
"fdt_high=0xffffffffffffffff\0" \
|
||||
"fdt_file=imx8mq-pico-pi.dtb\0" \
|
||||
"initrd_addr=0x43800000\0" \
|
||||
"initrd_high=0xffffffffffffffff\0" \
|
||||
"mmcdev=" __stringify(CONFIG_SYS_MMC_ENV_DEV) "\0" \
|
||||
"mmcpart=" __stringify(CONFIG_SYS_MMC_IMG_LOAD_PART) "\0" \
|
||||
"mmcroot=" CONFIG_MMCROOT " rootwait rw\0" \
|
||||
"mmcautodetect=yes\0" \
|
||||
"mmcargs=setenv bootargs console=${console} root=${mmcroot}\0 " \
|
||||
"loadbootscript=" \
|
||||
"fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\0" \
|
||||
"bootscript=echo Running bootscript from mmc ...; source\0" \
|
||||
"loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}\0" \
|
||||
"loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}\0" \
|
||||
"mmcboot=echo Booting from mmc ...; " \
|
||||
"run mmcargs; " \
|
||||
"echo wait for boot; " \
|
||||
"fi;\0" \
|
||||
"netargs=setenv bootargs console=${console} " \
|
||||
"root=/dev/nfs " \
|
||||
"ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp\0" \
|
||||
"netboot=echo Booting from net ...; " \
|
||||
"run netargs; " \
|
||||
"if test ${ip_dyn} = yes; then " \
|
||||
"setenv get_cmd dhcp; " \
|
||||
"else " \
|
||||
"setenv get_cmd tftp; " \
|
||||
"fi; " \
|
||||
"${get_cmd} ${loadaddr} ${image}; " \
|
||||
"booti; "
|
||||
|
||||
#define CONFIG_BOOTCOMMAND \
|
||||
"mmc dev ${mmcdev}; if mmc rescan; then " \
|
||||
"if run loadbootscript; then " \
|
||||
"run bootscript; " \
|
||||
"else " \
|
||||
"if run loadimage; then " \
|
||||
"run mmcboot; " \
|
||||
"else run netboot; " \
|
||||
"fi; " \
|
||||
"fi; " \
|
||||
"else booti ${loadaddr} - ${fdt_addr}; fi"
|
||||
|
||||
/* Link Definitions */
|
||||
#define CONFIG_LOADADDR 0x40480000
|
||||
|
||||
#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
|
||||
|
||||
#define CONFIG_SYS_INIT_RAM_ADDR 0x40000000
|
||||
#define CONFIG_SYS_INIT_RAM_SIZE 0x80000
|
||||
#define CONFIG_SYS_INIT_SP_OFFSET \
|
||||
(CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE)
|
||||
#define CONFIG_SYS_INIT_SP_ADDR \
|
||||
(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET)
|
||||
|
||||
#define CONFIG_ENV_OVERWRITE
|
||||
#define CONFIG_SYS_MMC_ENV_DEV 1 /* USDHC2 */
|
||||
#define CONFIG_MMCROOT "/dev/mmcblk1p2" /* USDHC2 */
|
||||
|
||||
/* Size of malloc() pool */
|
||||
#define CONFIG_SYS_MALLOC_LEN ((CONFIG_ENV_SIZE + (2 * 1024)) * 1024)
|
||||
|
||||
#define CONFIG_SYS_SDRAM_BASE 0x40000000
|
||||
#define PHYS_SDRAM 0x40000000
|
||||
#define PHYS_SDRAM_SIZE 0x80000000 /* 2 GiB DDR */
|
||||
|
||||
#define CONFIG_SYS_MEMTEST_START PHYS_SDRAM
|
||||
#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_MEMTEST_START + \
|
||||
(PHYS_SDRAM_SIZE >> 1))
|
||||
|
||||
#define CONFIG_BAUDRATE 115200
|
||||
|
||||
#define CONFIG_MXC_UART
|
||||
#define CONFIG_MXC_UART_BASE UART1_BASE_ADDR
|
||||
|
||||
/* Monitor Command Prompt */
|
||||
#define CONFIG_SYS_CBSIZE 1024
|
||||
#define CONFIG_SYS_MAXARGS 64
|
||||
#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
|
||||
#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
|
||||
sizeof(CONFIG_SYS_PROMPT) + 16)
|
||||
|
||||
#define CONFIG_IMX_BOOTAUX
|
||||
|
||||
#define CONFIG_CMD_MMC
|
||||
|
||||
#define CONFIG_SYS_FSL_USDHC_NUM 2
|
||||
#define CONFIG_SYS_FSL_ESDHC_ADDR 0
|
||||
|
||||
#define CONFIG_SYS_MMC_IMG_LOAD_PART 1
|
||||
|
||||
#define CONFIG_MXC_GPIO
|
||||
|
||||
#define CONFIG_CMD_FUSE
|
||||
|
||||
/* I2C Configs */
|
||||
#define CONFIG_SYS_I2C_SPEED 100000
|
||||
|
||||
#define CONFIG_OF_SYSTEM_SETUP
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
#define CONFIG_DM_PMIC
|
||||
#endif
|
||||
|
||||
#define CONFIG_SYS_BOOTM_LEN SZ_128M
|
||||
|
||||
#endif
|
|
@ -89,6 +89,15 @@ struct cpu_ops {
|
|||
* @return 0 if OK, -ENOSPC if buffer is too small, other -ve on error
|
||||
*/
|
||||
int (*get_vendor)(struct udevice *dev, char *buf, int size);
|
||||
|
||||
/**
|
||||
* is_current() - Check if the CPU that U-Boot is currently running from
|
||||
*
|
||||
* @dev: Device to check (UCLASS_CPU)
|
||||
* @return 1 if the CPU that U-Boot is currently running from, 0
|
||||
* if not.
|
||||
*/
|
||||
int (*is_current)(struct udevice *dev);
|
||||
};
|
||||
|
||||
#define cpu_get_ops(dev) ((struct cpu_ops *)(dev)->driver->ops)
|
||||
|
@ -137,4 +146,18 @@ int cpu_get_vendor(struct udevice *dev, char *buf, int size);
|
|||
*/
|
||||
int cpu_probe_all(void);
|
||||
|
||||
/**
|
||||
* cpu_is_current() - Check if the CPU that U-Boot is currently running from
|
||||
*
|
||||
* Return: 1 if yes, - 0 if not
|
||||
*/
|
||||
int cpu_is_current(struct udevice *cpu);
|
||||
|
||||
/**
|
||||
* cpu_get_current_dev() - Get CPU udevice for current CPU
|
||||
*
|
||||
* Return: udevice if OK, - NULL on error
|
||||
*/
|
||||
struct udevice *cpu_get_current_dev(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -47,6 +47,7 @@ enum uclass_id {
|
|||
UCLASS_DMA, /* Direct Memory Access */
|
||||
UCLASS_EFI, /* EFI managed devices */
|
||||
UCLASS_ETH, /* Ethernet device */
|
||||
UCLASS_ETH_PHY, /* Ethernet PHY device */
|
||||
UCLASS_FIRMWARE, /* Firmware */
|
||||
UCLASS_FS_FIRMWARE_LOADER, /* Generic loader */
|
||||
UCLASS_GPIO, /* Bank of general-purpose I/O pins */
|
||||
|
|
|
@ -553,5 +553,6 @@
|
|||
#define SC_R_VPU_ENC_1 539
|
||||
#define SC_R_VPU 540
|
||||
#define SC_R_LAST 541
|
||||
#define SC_R_NONE 0xFFF0
|
||||
|
||||
#endif /* DT_BINDINGS_RSCRC_IMX_H */
|
||||
|
|
17
include/eth_phy.h
Normal file
17
include/eth_phy.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2020 NXP
|
||||
*/
|
||||
|
||||
#ifndef _eth_phy_h_
|
||||
#define _eth_phy_h_
|
||||
|
||||
#include <dm.h>
|
||||
#include <phy.h>
|
||||
|
||||
int eth_phy_binds_nodes(struct udevice *eth_dev);
|
||||
int eth_phy_set_mdio_bus(struct udevice *eth_dev, struct mii_dev *mdio_bus);
|
||||
struct mii_dev *eth_phy_get_mdio_bus(struct udevice *eth_dev);
|
||||
int eth_phy_get_addr(struct udevice *dev);
|
||||
|
||||
#endif
|
|
@ -16,22 +16,26 @@
|
|||
* @gf_len: The length of Galois Field. (e.g., 13 or 14)
|
||||
* @ecc_strength: A number that describes the strength of the ECC
|
||||
* algorithm.
|
||||
* @ecc_chunk_size: The size, in bytes, of a single ECC chunk. Note
|
||||
* the first chunk in the page includes both data and
|
||||
* metadata, so it's a bit larger than this value.
|
||||
* @ecc_chunk0_size: The size, in bytes, of a first ECC chunk.
|
||||
* @ecc_chunkn_size: The size, in bytes, of a single ECC chunk after
|
||||
* the first chunk in the page.
|
||||
* @ecc_chunk_count: The number of ECC chunks in the page,
|
||||
* @block_mark_byte_offset: The byte offset in the ECC-based page view at
|
||||
* which the underlying physical block mark appears.
|
||||
* @block_mark_bit_offset: The bit offset into the ECC-based page view at
|
||||
* which the underlying physical block mark appears.
|
||||
* @ecc_for_meta: The flag to indicate if there is a dedicate ecc
|
||||
* for meta.
|
||||
*/
|
||||
struct bch_geometry {
|
||||
unsigned int gf_len;
|
||||
unsigned int ecc_strength;
|
||||
unsigned int ecc_chunk_size;
|
||||
unsigned int ecc_chunk0_size;
|
||||
unsigned int ecc_chunkn_size;
|
||||
unsigned int ecc_chunk_count;
|
||||
unsigned int block_mark_byte_offset;
|
||||
unsigned int block_mark_bit_offset;
|
||||
unsigned int ecc_for_meta; /* ECC for meta data */
|
||||
};
|
||||
|
||||
struct mxs_nand_info {
|
||||
|
@ -39,6 +43,8 @@ struct mxs_nand_info {
|
|||
struct udevice *dev;
|
||||
unsigned int max_ecc_strength_supported;
|
||||
bool use_minimum_ecc;
|
||||
/* legacy bch geometry flag */
|
||||
bool legacy_bch_geometry;
|
||||
int cur_chip;
|
||||
|
||||
uint32_t cmd_queue_len;
|
||||
|
@ -82,13 +88,15 @@ struct mxs_nand_layout {
|
|||
u32 ecc0;
|
||||
u32 datan_size;
|
||||
u32 eccn;
|
||||
u32 gf_len;
|
||||
};
|
||||
|
||||
int mxs_nand_init_ctrl(struct mxs_nand_info *nand_info);
|
||||
int mxs_nand_init_spl(struct nand_chip *nand);
|
||||
int mxs_nand_setup_ecc(struct mtd_info *mtd);
|
||||
|
||||
void mxs_nand_mode_fcb(struct mtd_info *mtd);
|
||||
void mxs_nand_mode_fcb_62bit(struct mtd_info *mtd);
|
||||
void mxs_nand_mode_fcb_40bit(struct mtd_info *mtd);
|
||||
void mxs_nand_mode_normal(struct mtd_info *mtd);
|
||||
u32 mxs_nand_mark_byte_offset(struct mtd_info *mtd);
|
||||
u32 mxs_nand_mark_bit_offset(struct mtd_info *mtd);
|
||||
|
|
|
@ -582,4 +582,5 @@ void spl_perform_fixups(struct spl_image_info *spl_image);
|
|||
*/
|
||||
struct image_header *spl_get_load_buffer(ssize_t offset, size_t size);
|
||||
|
||||
void spl_save_restore_data(void);
|
||||
#endif
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <dm/uclass-internal.h>
|
||||
#include <net/pcap.h>
|
||||
#include "eth_internal.h"
|
||||
#include <eth_phy.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
|
@ -40,8 +41,12 @@ static int eth_errno;
|
|||
static struct eth_uclass_priv *eth_get_uclass_priv(void)
|
||||
{
|
||||
struct uclass *uc;
|
||||
int ret;
|
||||
|
||||
ret = uclass_get(UCLASS_ETH, &uc);
|
||||
if (ret)
|
||||
return NULL;
|
||||
|
||||
uclass_get(UCLASS_ETH, &uc);
|
||||
assert(uc);
|
||||
return uc->priv;
|
||||
}
|
||||
|
@ -102,6 +107,7 @@ struct udevice *eth_get_dev_by_name(const char *devname)
|
|||
struct udevice *it;
|
||||
struct uclass *uc;
|
||||
int len = strlen("eth");
|
||||
int ret;
|
||||
|
||||
/* Must be longer than 3 to be an alias */
|
||||
if (!strncmp(devname, "eth", len) && strlen(devname) > len) {
|
||||
|
@ -109,7 +115,10 @@ struct udevice *eth_get_dev_by_name(const char *devname)
|
|||
seq = simple_strtoul(startp, &endp, 10);
|
||||
}
|
||||
|
||||
uclass_get(UCLASS_ETH, &uc);
|
||||
ret = uclass_get(UCLASS_ETH, &uc);
|
||||
if (ret)
|
||||
return NULL;
|
||||
|
||||
uclass_foreach_dev(it, uc) {
|
||||
/*
|
||||
* We need the seq to be valid, so try to probe it.
|
||||
|
@ -453,6 +462,10 @@ static int eth_post_bind(struct udevice *dev)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DM_ETH_PHY
|
||||
eth_phy_binds_nodes(dev);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@ static int dm_test_cpu(struct unit_test_state *uts)
|
|||
ut_assert(dev->flags & DM_FLAG_ACTIVATED);
|
||||
|
||||
ut_assertok(uclass_get_device_by_name(UCLASS_CPU, "cpu-test1", &dev));
|
||||
ut_asserteq_ptr(cpu_get_current_dev(), dev);
|
||||
ut_asserteq(cpu_is_current(dev), 1);
|
||||
|
||||
ut_assertok(cpu_get_desc(dev, text, sizeof(text)));
|
||||
ut_assertok(strcmp(text, "LEG Inc. SuperMegaUltraTurbo CPU No. 1"));
|
||||
|
|
Loading…
Reference in a new issue