i.MX for 2020.10

----------------
 
 - i.MX DDR driver fix/update for i.MX8M
 - i.MX pinctrl driver fix.
 - Use arm_smccc_smc to remove imx sip function
 - i.MX8M clk update
 - support booting aarch32 kernel on aarch64 hardware
 - fused part support for i.MX8MP
 - imx6: pcm058 to DM
 
 Travis: https://travis-ci.org/github/sbabic/u-boot-imx/builds/708734785
 -----BEGIN PGP SIGNATURE-----
 
 iG0EABECAC0WIQS2TmnA27QKhpKSZe309WXkmmjvpgUCXxCxWw8cc2JhYmljQGRl
 bnguZGUACgkQ9PVl5Jpo76bPyACcDZ8gD9jf1P/Zh+7kqrGdIWwURF8AnAiEtNnu
 FhE/WQQj4mAEWE4F2bFE
 =7ceG
 -----END PGP SIGNATURE-----

Merge tag 'u-boot-imx-20200716' of https://gitlab.denx.de/u-boot/custodians/u-boot-imx

i.MX for 2020.10
----------------

- i.MX DDR driver fix/update for i.MX8M
- i.MX pinctrl driver fix.
- Use arm_smccc_smc to remove imx sip function
- i.MX8M clk update
- support booting aarch32 kernel on aarch64 hardware
- fused part support for i.MX8MP
- imx6: pcm058 to DM

Travis: https://travis-ci.org/github/sbabic/u-boot-imx/builds/708734785
This commit is contained in:
Tom Rini 2020-07-17 08:04:28 -04:00
commit 42e7659db0
73 changed files with 2695 additions and 716 deletions

View File

@ -888,7 +888,7 @@ config ARCH_MX7
config ARCH_MX6
bool "Freescale MX6"
select CPU_V7A
select SYS_FSL_HAS_SEC if IMX_HAB
select SYS_FSL_HAS_SEC
select SYS_FSL_SEC_COMPAT_4
select SYS_FSL_SEC_LE
imply MXC_GPIO

View File

@ -678,6 +678,7 @@ dtb-y += \
imx6q-nitrogen6x.dtb \
imx6q-novena.dtb \
imx6q-pico.dtb \
imx6q-phytec-mira-rdk-nand.dtb \
imx6q-sabreauto.dtb \
imx6q-sabrelite.dtb \
imx6q-sabresd.dtb \

View File

@ -0,0 +1,42 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2020
* Niel Fourie, DENX Software Engineering, lusus@denx.de.
*/
#include "imx6qdl-u-boot.dtsi"
&gpio3 {
u-boot,dm-spl;
};
&gpio6 {
u-boot,dm-spl;
};
&pinctrl_uart2 {
u-boot,dm-spl;
};
&uart2 {
u-boot,dm-spl;
};
&usdhc1 {
u-boot,dm-spl;
};
&pinctrl_usdhc1 {
u-boot,dm-spl;
};
&ecspi1 {
u-boot,dm-spl;
};
&pinctrl_ecspi1 {
u-boot,dm-spl;
};
&m25p80 {
u-boot,dm-spl;
};

View File

@ -0,0 +1,72 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (C) 2018 PHYTEC Messtechnik GmbH
* Author: Christian Hemp <c.hemp@phytec.de>
*/
/dts-v1/;
#include "imx6q.dtsi"
#include "imx6qdl-phytec-phycore-som.dtsi"
#include "imx6qdl-phytec-mira.dtsi"
/ {
model = "PHYTEC phyBOARD-Mira Quad Carrier-Board with NAND";
compatible = "phytec,imx6q-pbac06-nand", "phytec,imx6q-pbac06",
"phytec,imx6qdl-pcm058", "fsl,imx6q";
chosen {
stdout-path = &uart2;
};
};
&can1 {
status = "okay";
};
&fec {
status = "okay";
};
&gpmi {
status = "okay";
};
&hdmi {
status = "okay";
};
&i2c1 {
status = "okay";
};
&i2c2 {
status = "okay";
};
&i2c_rtc {
status = "okay";
};
&m25p80 {
status = "okay";
};
&pcie {
status = "okay";
};
&uart3 {
status = "okay";
};
&usbh1 {
status = "okay";
};
&usbotg {
status = "okay";
};
&usdhc1 {
status = "okay";
};

View File

@ -0,0 +1,390 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (C) 2018 PHYTEC Messtechnik GmbH
* Author: Christian Hemp <c.hemp@phytec.de>
*/
/ {
aliases {
rtc0 = &i2c_rtc;
};
backlight: backlight {
compatible = "pwm-backlight";
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <7>;
power-supply = <&reg_backlight>;
pwms = <&pwm1 0 5000000>;
status = "okay";
};
gpio_leds: leds {
compatible = "gpio-leds";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpioleds>;
status = "disabled";
red {
label = "phyboard-mira:red";
gpios = <&gpio5 22 GPIO_ACTIVE_HIGH>;
};
green {
label = "phyboard-mira:green";
gpios = <&gpio5 23 GPIO_ACTIVE_HIGH>;
};
blue {
label = "phyboard-mira:blue";
gpios = <&gpio5 24 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "mmc0";
};
};
reg_backlight: regulator-backlight {
compatible = "regulator-fixed";
regulator-name = "backlight_3v3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
};
reg_en_switch: regulator-en-switch {
compatible = "regulator-fixed";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_en_switch>;
regulator-name = "Enable Switch";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
enable-active-high;
gpio = <&gpio3 4 GPIO_ACTIVE_HIGH>;
regulator-always-on;
};
reg_flexcan1: regulator-flexcan1 {
compatible = "regulator-fixed";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_flexcan1_en>;
regulator-name = "flexcan1-reg";
regulator-min-microvolt = <1500000>;
regulator-max-microvolt = <1500000>;
gpio = <&gpio2 20 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
reg_panel: regulator-panel {
compatible = "regulator-fixed";
regulator-name = "panel-power-supply";
regulator-min-microvolt = <12000000>;
regulator-max-microvolt = <12000000>;
regulator-always-on;
};
reg_pcie: regulator-pcie {
compatible = "regulator-fixed";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pcie_reg>;
regulator-name = "mPCIe_1V5";
regulator-min-microvolt = <1500000>;
regulator-max-microvolt = <1500000>;
gpio = <&gpio3 0 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
reg_usb_h1_vbus: usb-h1-vbus {
compatible = "regulator-fixed";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usbh1_vbus>;
regulator-name = "usb_h1_vbus";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
gpio = <&gpio2 18 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
reg_usbotg_vbus: usbotg-vbus {
compatible = "regulator-fixed";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usbotg_vbus>;
regulator-name = "usb_otg_vbus";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
panel {
compatible = "auo,g104sn02";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_panel_en>;
power-supply = <&reg_panel>;
enable-gpios = <&gpio2 28 GPIO_ACTIVE_LOW>;
backlight = <&backlight>;
port {
panel_in: endpoint {
remote-endpoint = <&lvds0_out>;
};
};
};
};
&can1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_flexcan1>;
xceiver-supply = <&reg_flexcan1>;
status = "disabled";
};
&hdmi {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_hdmicec>;
ddc-i2c-bus = <&i2c2>;
status = "disabled";
};
&i2c1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c1>;
clock-frequency = <400000>;
status = "disabled";
stmpe: touchctrl@44 {
compatible = "st,stmpe811";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_stmpe>;
reg = <0x44>;
interrupt-parent = <&gpio7>;
interrupts = <12 IRQ_TYPE_NONE>;
status = "disabled";
stmpe_touchscreen {
compatible = "st,stmpe-ts";
st,sample-time = <4>;
st,mod-12b = <1>;
st,ref-sel = <0>;
st,adc-freq = <1>;
st,ave-ctrl = <1>;
st,touch-det-delay = <2>;
st,settling = <2>;
st,fraction-z = <7>;
st,i-drive = <1>;
};
};
i2c_rtc: rtc@68 {
compatible = "microcrystal,rv4162";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_rtc_int>;
reg = <0x68>;
interrupt-parent = <&gpio7>;
interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
};
&i2c2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c2>;
clock-frequency = <100000>;
status = "disabled";
};
&ldb {
status = "okay";
lvds-channel@0 {
fsl,data-mapping = "spwg";
fsl,data-width = <24>;
status = "disabled";
port@4 {
reg = <4>;
lvds0_out: endpoint {
remote-endpoint = <&panel_in>;
};
};
};
};
&pcie {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pcie>;
reset-gpio = <&gpio2 25 GPIO_ACTIVE_LOW>;
vpcie-supply = <&reg_pcie>;
status = "disabled";
};
&pwm1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm1>;
status = "okay";
};
&uart2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart2>;
status = "okay";
};
&uart3 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart3>;
uart-has-rtscts;
status = "disabled";
};
&usbh1 {
vbus-supply = <&reg_usb_h1_vbus>;
disable-over-current;
status = "disabled";
};
&usbotg {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usbotg>;
vbus-supply = <&reg_usbotg_vbus>;
disable-over-current;
status = "disabled";
};
&usdhc1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usdhc1>;
cd-gpios = <&gpio6 31 GPIO_ACTIVE_LOW>;
no-1-8-v;
status = "disabled";
};
&iomuxc {
pinctrl_panel_en: panelen1grp {
fsl,pins = <
MX6QDL_PAD_EIM_EB0__GPIO2_IO28 0xb0b1
>;
};
pinctrl_en_switch: enswitchgrp {
fsl,pins = <
MX6QDL_PAD_EIM_DA4__GPIO3_IO04 0xb0b1
>;
};
pinctrl_flexcan1: flexcan1grp {
fsl,pins = <
MX6QDL_PAD_GPIO_7__FLEXCAN1_TX 0x1b0b0
MX6QDL_PAD_GPIO_8__FLEXCAN1_RX 0x1b0b0
>;
};
pinctrl_flexcan1_en: flexcan1engrp {
fsl,pins = <
MX6QDL_PAD_EIM_A18__GPIO2_IO20 0xb0b1
>;
};
pinctrl_gpioleds: gpioledsgrp {
fsl,pins = <
MX6QDL_PAD_CSI0_DAT4__GPIO5_IO22 0x1b0b0
MX6QDL_PAD_CSI0_DAT5__GPIO5_IO23 0x1b0b0
MX6QDL_PAD_CSI0_DAT6__GPIO5_IO24 0x1b0b0
>;
};
pinctrl_hdmicec: hdmicecgrp {
fsl,pins = <
MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x1f8b0
>;
};
pinctrl_i2c2: i2c2grp {
fsl,pins = <
MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
>;
};
pinctrl_i2c1: i2c1grp {
fsl,pins = <
MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
>;
};
pinctrl_pcie: pciegrp {
fsl,pins = <
MX6QDL_PAD_EIM_OE__GPIO2_IO25 0xb0b1
>;
};
pinctrl_pcie_reg: pciereggrp {
fsl,pins = <
MX6QDL_PAD_EIM_DA0__GPIO3_IO00 0xb0b1
>;
};
pinctrl_pwm1: pwm1grp {
fsl,pins = <
MX6QDL_PAD_GPIO_9__PWM1_OUT 0x1b0b1
>;
};
pinctrl_rtc_int: rtcintgrp {
fsl,pins = <
MX6QDL_PAD_SD3_RST__GPIO7_IO08 0x1b0b0
>;
};
pinctrl_stmpe: stmpegrp {
fsl,pins = <
MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x1b0b0
>;
};
pinctrl_uart2: uart2grp {
fsl,pins = <
MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1
MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1
>;
};
pinctrl_uart3: uart3grp {
fsl,pins = <
MX6QDL_PAD_EIM_EB3__UART3_CTS_B 0x1b0b1
MX6QDL_PAD_EIM_D23__UART3_RTS_B 0x1b0b1
MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1
MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1
>;
};
pinctrl_usbh1_vbus: usbh1vbusgrp {
fsl,pins = <
MX6QDL_PAD_EIM_A20__GPIO2_IO18 0xb0b1
>;
};
pinctrl_usbotg: usbotggrp {
fsl,pins = <
MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059
>;
};
pinctrl_usbotg_vbus: usbotgvbusgrp {
fsl,pins = <
MX6QDL_PAD_EIM_A19__GPIO2_IO19 0xb0b1
>;
};
pinctrl_usdhc1: usdhc1grp {
fsl,pins = <
MX6QDL_PAD_SD1_CMD__SD1_CMD 0x170f9
MX6QDL_PAD_SD1_CLK__SD1_CLK 0x100f9
MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x170f9
MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x170f9
MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x170f9
MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x170f9
MX6QDL_PAD_EIM_BCLK__GPIO6_IO31 0xb0b1 /* CD */
>;
};
};

View File

@ -0,0 +1,287 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (C) 2018 PHYTEC Messtechnik GmbH
* Author: Christian Hemp <c.hemp@phytec.de>
*/
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/regulator/dlg,da9063-regulator.h>
/ {
aliases {
rtc1 = &da9062_rtc;
rtc2 = &snvs_rtc;
};
/*
* Set the minimum memory size here and
* let the bootloader set the real size.
*/
memory@10000000 {
device_type = "memory";
reg = <0x10000000 0x8000000>;
};
gpio_leds_som: somleds {
compatible = "gpio-leds";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpioleds_som>;
som-led-green {
label = "phycore:green";
gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "heartbeat";
};
};
};
&ecspi1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ecspi1>;
cs-gpios = <&gpio3 19 GPIO_ACTIVE_LOW>;
status = "okay";
m25p80: flash@0 {
compatible = "jedec,spi-nor";
spi-max-frequency = <20000000>;
reg = <0>;
status = "disabled";
};
};
&fec {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet>;
phy-handle = <&ethphy>;
phy-mode = "rgmii";
phy-supply = <&vdd_eth_io>;
phy-reset-gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
status = "disabled";
mdio {
#address-cells = <1>;
#size-cells = <0>;
ethphy: ethernet-phy@3 {
reg = <3>;
txc-skew-ps = <1680>;
rxc-skew-ps = <1860>;
};
};
};
&gpmi {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpmi_nand>;
nand-on-flash-bbt;
status = "disabled";
};
&i2c3 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c3>;
clock-frequency = <400000>;
status = "okay";
eeprom@50 {
compatible = "atmel,24c32";
reg = <0x50>;
};
pmic@58 {
compatible = "dlg,da9062";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pmic>;
reg = <0x58>;
interrupt-parent = <&gpio1>;
interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
interrupt-controller;
da9062_rtc: rtc {
compatible = "dlg,da9062-rtc";
};
da9062_onkey: onkey {
compatible = "dlg,da9062-onkey";
};
watchdog {
compatible = "dlg,da9062-watchdog";
};
regulators {
vdd_arm: buck1 {
regulator-name = "vdd_arm";
regulator-min-microvolt = <925000>;
regulator-max-microvolt = <1380000>;
regulator-initial-mode = <DA9063_BUCK_MODE_SYNC>;
regulator-always-on;
};
vdd_soc: buck2 {
regulator-name = "vdd_soc";
regulator-min-microvolt = <1150000>;
regulator-max-microvolt = <1380000>;
regulator-initial-mode = <DA9063_BUCK_MODE_SYNC>;
regulator-always-on;
};
vdd_ddr3_1p5: buck3 {
regulator-name = "vdd_ddr3";
regulator-min-microvolt = <1500000>;
regulator-max-microvolt = <1500000>;
regulator-initial-mode = <DA9063_BUCK_MODE_SYNC>;
regulator-always-on;
};
vdd_eth_1p2: buck4 {
regulator-name = "vdd_eth";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
regulator-initial-mode = <DA9063_BUCK_MODE_SYNC>;
regulator-always-on;
};
vdd_snvs: ldo1 {
regulator-name = "vdd_snvs";
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
regulator-always-on;
};
vdd_high: ldo2 {
regulator-name = "vdd_high";
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
regulator-always-on;
};
vdd_eth_io: ldo3 {
regulator-name = "vdd_eth_io";
regulator-min-microvolt = <2500000>;
regulator-max-microvolt = <2500000>;
};
vdd_emmc_1p8: ldo4 {
regulator-name = "vdd_emmc";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
};
};
};
&reg_arm {
vin-supply = <&vdd_arm>;
};
&reg_pu {
vin-supply = <&vdd_soc>;
};
&reg_soc {
vin-supply = <&vdd_soc>;
};
&snvs_poweroff {
status = "okay";
};
&usdhc4 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usdhc4>;
bus-width = <8>;
non-removable;
status = "disabled";
};
&iomuxc {
pinctrl_enet: enetgrp {
fsl,pins = <
MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN 0x1b0b0
MX6QDL_PAD_SD2_DAT1__GPIO1_IO14 0x1b0b0
>;
};
pinctrl_gpioleds_som: gpioledssomgrp {
fsl,pins = <
MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x1b0b0
>;
};
pinctrl_gpmi_nand: gpminandgrp {
fsl,pins = <
MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
MX6QDL_PAD_NANDF_CS2__NAND_CE2_B 0xb0b1
MX6QDL_PAD_NANDF_CS3__NAND_CE3_B 0xb0b1
MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
MX6QDL_PAD_SD4_DAT0__NAND_DQS 0x00b1
>;
};
pinctrl_i2c3: i2c3grp {
fsl,pins = <
MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
MX6QDL_PAD_GPIO_5__I2C3_SCL 0x4001b8b1
>;
};
pinctrl_ecspi1: ecspi1grp {
fsl,pins = <
MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1
MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1
MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1
MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x1b0b0
>;
};
pinctrl_pmic: pmicgrp {
fsl,pins = <
MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x1b0b0
>;
};
pinctrl_usdhc4: usdhc4grp {
fsl,pins = <
MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059
MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059
MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059
MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059
>;
};
};

View File

@ -323,7 +323,7 @@
port {
tpiu_in_port: endpoint {
slave-mode;
remote-endpoint = <&replicator_out_port1>;
remote-endpoint = <&replicator_out_port0>;
};
};
};

View File

@ -41,6 +41,11 @@
#define MXC_CPU_IMX8MNDL 0x8f /* dummy ID */
#define MXC_CPU_IMX8MNSL 0x181 /* dummy ID */
#define MXC_CPU_IMX8MP 0x182/* dummy ID */
#define MXC_CPU_IMX8MP7 0x183 /* dummy ID */
#define MXC_CPU_IMX8MP6 0x184 /* dummy ID */
#define MXC_CPU_IMX8MP5 0x185 /* dummy ID */
#define MXC_CPU_IMX8MPL 0x186 /* dummy ID */
#define MXC_CPU_IMX8MPD 0x187 /* dummy ID */
#define MXC_CPU_IMX8QXP_A0 0x90 /* dummy ID */
#define MXC_CPU_IMX8QM 0x91 /* dummy ID */
#define MXC_CPU_IMX8QXP 0x92 /* dummy ID */

View File

@ -115,6 +115,7 @@ struct sc_rpc_msg_s {
#define MISC_FUNC_GET_TEMP 13U
#define MISC_FUNC_GET_BOOT_DEV 16U
#define MISC_FUNC_GET_BUTTON_STATUS 18U
#define MISC_FUNC_GET_BOOT_CONTAINER 36U
/* PAD RPC */
#define PAD_FUNC_UNKNOWN 0

View File

@ -82,6 +82,7 @@ int sc_misc_get_control(sc_ipc_t ipc, sc_rsrc_t resource, sc_ctrl_t ctrl,
u32 *val);
void sc_misc_get_boot_dev(sc_ipc_t ipc, sc_rsrc_t *boot_dev);
void sc_misc_boot_status(sc_ipc_t ipc, sc_misc_boot_status_t status);
int sc_misc_get_boot_container(sc_ipc_t ipc, u8 *idx);
void sc_misc_build_info(sc_ipc_t ipc, u32 *build, u32 *commit);
int sc_misc_otp_fuse_read(sc_ipc_t ipc, u32 word, u32 *val);
int sc_misc_get_temp(sc_ipc_t ipc, sc_rsrc_t resource, sc_misc_temp_t temp,

View File

@ -529,6 +529,8 @@ enum msg_response {
#define DDRC_SBRWDATA0(X) (DDRC_IPS_BASE_ADDR(X) + 0xf2c)
#define DDRC_SBRWDATA1(X) (DDRC_IPS_BASE_ADDR(X) + 0xf30)
#define DDRC_PDCH(X) (DDRC_IPS_BASE_ADDR(X) + 0xf34)
#define DDRC_SBRSTART0(X) (DDRC_IPS_BASE_ADDR(X) + 0xf38)
#define DDRC_SBRRANGE0(X) (DDRC_IPS_BASE_ADDR(X) + 0xf40)
#define DDRC_FREQ1_DERATEEN(X) (DDRC_IPS_BASE_ADDR(X) + 0x2020)
#define DDRC_FREQ1_DERATEINT(X) (DDRC_IPS_BASE_ADDR(X) + 0x2024)
@ -708,12 +710,20 @@ int ddr_cfg_phy(struct dram_timing_info *timing_info);
void load_lpddr4_phy_pie(void);
void ddrphy_trained_csr_save(struct dram_cfg_param *param, unsigned int num);
void dram_config_save(struct dram_timing_info *info, unsigned long base);
void board_dram_ecc_scrub(void);
void ddrc_inline_ecc_scrub(unsigned int start_address,
unsigned int range_address);
void ddrc_inline_ecc_scrub_end(unsigned int start_address,
unsigned int range_address);
/* utils function for ddr phy training */
int wait_ddrphy_training_complete(void);
void ddrphy_init_set_dfi_clk(unsigned int drate);
void ddrphy_init_read_msg_block(enum fw_type type);
void update_umctl2_rank_space_setting(unsigned int pstat_num);
void get_trained_CDD(unsigned int fsp);
static inline void reg32_write(unsigned long addr, u32 val)
{
writel(val, addr);

View File

@ -331,5 +331,163 @@ struct bootrom_sw_info {
#define ROM_SW_INFO_ADDR is_soc_rev(CHIP_REV_1_0) ? \
(struct bootrom_sw_info **)ROM_SW_INFO_ADDR_A0 : \
(struct bootrom_sw_info **)ROM_SW_INFO_ADDR_B0
struct gpc_reg {
u32 lpcr_bsc;
u32 lpcr_ad;
u32 lpcr_cpu1;
u32 lpcr_cpu2;
u32 lpcr_cpu3;
u32 slpcr;
u32 mst_cpu_mapping;
u32 mmdc_cpu_mapping;
u32 mlpcr;
u32 pgc_ack_sel;
u32 pgc_ack_sel_m4;
u32 gpc_misc;
u32 imr1_core0;
u32 imr2_core0;
u32 imr3_core0;
u32 imr4_core0;
u32 imr1_core1;
u32 imr2_core1;
u32 imr3_core1;
u32 imr4_core1;
u32 imr1_cpu1;
u32 imr2_cpu1;
u32 imr3_cpu1;
u32 imr4_cpu1;
u32 imr1_cpu3;
u32 imr2_cpu3;
u32 imr3_cpu3;
u32 imr4_cpu3;
u32 isr1_cpu0;
u32 isr2_cpu0;
u32 isr3_cpu0;
u32 isr4_cpu0;
u32 isr1_cpu1;
u32 isr2_cpu1;
u32 isr3_cpu1;
u32 isr4_cpu1;
u32 isr1_cpu2;
u32 isr2_cpu2;
u32 isr3_cpu2;
u32 isr4_cpu2;
u32 isr1_cpu3;
u32 isr2_cpu3;
u32 isr3_cpu3;
u32 isr4_cpu3;
u32 slt0_cfg;
u32 slt1_cfg;
u32 slt2_cfg;
u32 slt3_cfg;
u32 slt4_cfg;
u32 slt5_cfg;
u32 slt6_cfg;
u32 slt7_cfg;
u32 slt8_cfg;
u32 slt9_cfg;
u32 slt10_cfg;
u32 slt11_cfg;
u32 slt12_cfg;
u32 slt13_cfg;
u32 slt14_cfg;
u32 pgc_cpu_0_1_mapping;
u32 cpu_pgc_up_trg;
u32 mix_pgc_up_trg;
u32 pu_pgc_up_trg;
u32 cpu_pgc_dn_trg;
u32 mix_pgc_dn_trg;
u32 pu_pgc_dn_trg;
u32 lpcr_bsc2;
u32 pgc_cpu_2_3_mapping;
u32 lps_cpu0;
u32 lps_cpu1;
u32 lps_cpu2;
u32 lps_cpu3;
u32 gpc_gpr;
u32 gtor;
u32 debug_addr1;
u32 debug_addr2;
u32 cpu_pgc_up_status1;
u32 mix_pgc_up_status0;
u32 mix_pgc_up_status1;
u32 mix_pgc_up_status2;
u32 m4_mix_pgc_up_status0;
u32 m4_mix_pgc_up_status1;
u32 m4_mix_pgc_up_status2;
u32 pu_pgc_up_status0;
u32 pu_pgc_up_status1;
u32 pu_pgc_up_status2;
u32 m4_pu_pgc_up_status0;
u32 m4_pu_pgc_up_status1;
u32 m4_pu_pgc_up_status2;
u32 a53_lp_io_0;
u32 a53_lp_io_1;
u32 a53_lp_io_2;
u32 cpu_pgc_dn_status1;
u32 mix_pgc_dn_status0;
u32 mix_pgc_dn_status1;
u32 mix_pgc_dn_status2;
u32 m4_mix_pgc_dn_status0;
u32 m4_mix_pgc_dn_status1;
u32 m4_mix_pgc_dn_status2;
u32 pu_pgc_dn_status0;
u32 pu_pgc_dn_status1;
u32 pu_pgc_dn_status2;
u32 m4_pu_pgc_dn_status0;
u32 m4_pu_pgc_dn_status1;
u32 m4_pu_pgc_dn_status2;
u32 res[3];
u32 mix_pdn_flg;
u32 pu_pdn_flg;
u32 m4_mix_pdn_flg;
u32 m4_pu_pdn_flg;
u32 imr1_core2;
u32 imr2_core2;
u32 imr3_core2;
u32 imr4_core2;
u32 imr1_core3;
u32 imr2_core3;
u32 imr3_core3;
u32 imr4_core3;
u32 pgc_ack_sel_pu;
u32 pgc_ack_sel_m4_pu;
u32 slt15_cfg;
u32 slt16_cfg;
u32 slt17_cfg;
u32 slt18_cfg;
u32 slt19_cfg;
u32 gpc_pu_pwrhsk;
u32 slt0_cfg_pu;
u32 slt1_cfg_pu;
u32 slt2_cfg_pu;
u32 slt3_cfg_pu;
u32 slt4_cfg_pu;
u32 slt5_cfg_pu;
u32 slt6_cfg_pu;
u32 slt7_cfg_pu;
u32 slt8_cfg_pu;
u32 slt9_cfg_pu;
u32 slt10_cfg_pu;
u32 slt11_cfg_pu;
u32 slt12_cfg_pu;
u32 slt13_cfg_pu;
u32 slt14_cfg_pu;
u32 slt15_cfg_pu;
u32 slt16_cfg_pu;
u32 slt17_cfg_pu;
u32 slt18_cfg_pu;
u32 slt19_cfg_pu;
};
struct pgc_reg {
u32 pgcr;
u32 pgpupscr;
u32 pgpdnscr;
u32 pgsr;
u32 pgauxsw;
u32 pgdr;
};
#endif
#endif

View File

@ -66,7 +66,14 @@ struct bd_info;
#define is_imx8mnl() (is_cpu_type(MXC_CPU_IMX8MNL))
#define is_imx8mndl() (is_cpu_type(MXC_CPU_IMX8MNDL))
#define is_imx8mnsl() (is_cpu_type(MXC_CPU_IMX8MNSL))
#define is_imx8mp() (is_cpu_type(MXC_CPU_IMX8MP))
#define is_imx8mp() (is_cpu_type(MXC_CPU_IMX8MP) || is_cpu_type(MXC_CPU_IMX8MPD) || \
is_cpu_type(MXC_CPU_IMX8MPL) || is_cpu_type(MXC_CPU_IMX8MP7) || \
is_cpu_type(MXC_CPU_IMX8MP6) || is_cpu_type(MXC_CPU_IMX8MP5))
#define is_imx8mpd() (is_cpu_type(MXC_CPU_IMX8MPD))
#define is_imx8mpl() (is_cpu_type(MXC_CPU_IMX8MPL))
#define is_imx8mp7() (is_cpu_type(MXC_CPU_IMX8MP7))
#define is_imx8mp6() (is_cpu_type(MXC_CPU_IMX8MP6))
#define is_imx8mp5() (is_cpu_type(MXC_CPU_IMX8MP5))
#define is_imx8qxp() (is_cpu_type(MXC_CPU_IMX8QXP))

View File

@ -218,7 +218,7 @@ endif
targets += $(addprefix ../../../,SPL spl/u-boot-spl.cfgout u-boot-dtb.cfgout u-boot.cfgout u-boot.uim spl/u-boot-nand-spl.imx)
obj-$(CONFIG_ARM64) += lowlevel.o sip.o
obj-$(CONFIG_ARM64) += lowlevel.o
obj-$(CONFIG_MX5) += mx5/
obj-$(CONFIG_MX6) += mx6/

View File

@ -96,7 +96,17 @@ const char *get_imx_type(u32 imxtype)
{
switch (imxtype) {
case MXC_CPU_IMX8MP:
return "8MP"; /* Quad-core version of the imx8mp */
return "8MP[8]"; /* Quad-core version of the imx8mp */
case MXC_CPU_IMX8MPD:
return "8MP Dual[3]"; /* Dual-core version of the imx8mp */
case MXC_CPU_IMX8MPL:
return "8MP Lite[4]"; /* Quad-core Lite version of the imx8mp */
case MXC_CPU_IMX8MP7:
return "8MP[7]"; /* Quad-core version of the imx8mp, VPU fused */
case MXC_CPU_IMX8MP6:
return "8MP[6]"; /* Quad-core version of the imx8mp, NPU fused */
case MXC_CPU_IMX8MP5:
return "8MP[5]"; /* Quad-core version of the imx8mp, ISP fused */
case MXC_CPU_IMX8MN:
return "8MNano Quad"; /* Quad-core version */
case MXC_CPU_IMX8MND:

View File

@ -4,6 +4,7 @@
#include <asm/arch/sci/sci.h>
#include <asm/mach-imx/sys_proto.h>
#include <imx_sip.h>
#include <linux/arm-smccc.h>
int sc_pm_setup_uart(sc_rsrc_t uart_rsrc, sc_pm_clock_rate_t clk_rate)
{
@ -30,6 +31,7 @@ int sc_pm_setup_uart(sc_rsrc_t uart_rsrc, sc_pm_clock_rate_t clk_rate)
void build_info(void)
{
struct arm_smccc_res res;
u32 seco_build = 0, seco_commit = 0;
u32 sc_build = 0, sc_commit = 0;
ulong atf_commit = 0;
@ -50,8 +52,9 @@ void build_info(void)
}
/* Get ARM Trusted Firmware commit id */
atf_commit = call_imx_sip(IMX_SIP_BUILDINFO,
IMX_SIP_BUILDINFO_GET_COMMITHASH, 0, 0, 0);
arm_smccc_smc(IMX_SIP_BUILDINFO, IMX_SIP_BUILDINFO_GET_COMMITHASH,
0, 0, 0, 0, 0, 0, &res);
atf_commit = res.a0;
if (atf_commit == 0xffffffff) {
debug("ATF does not support build info\n");
atf_commit = 0x30; /* Display 0 */

View File

@ -19,6 +19,7 @@ DECLARE_GLOBAL_DATA_PTR;
static struct anamix_pll *ana_pll = (struct anamix_pll *)ANATOP_BASE_ADDR;
static u32 get_root_clk(enum clk_root_index clock_id);
void enable_ocotp_clk(unsigned char enable)
{
clock_enable(CCGR_OCOTP, !!enable);
@ -164,6 +165,109 @@ void dram_disable_bypass(void)
}
#endif
int intpll_configure(enum pll_clocks pll, ulong freq)
{
void __iomem *pll_gnrl_ctl, __iomem *pll_div_ctl;
u32 pll_div_ctl_val, pll_clke_masks;
switch (pll) {
case ANATOP_SYSTEM_PLL1:
pll_gnrl_ctl = &ana_pll->sys_pll1_gnrl_ctl;
pll_div_ctl = &ana_pll->sys_pll1_div_ctl;
pll_clke_masks = INTPLL_DIV20_CLKE_MASK |
INTPLL_DIV10_CLKE_MASK | INTPLL_DIV8_CLKE_MASK |
INTPLL_DIV6_CLKE_MASK | INTPLL_DIV5_CLKE_MASK |
INTPLL_DIV4_CLKE_MASK | INTPLL_DIV3_CLKE_MASK |
INTPLL_DIV2_CLKE_MASK | INTPLL_CLKE_MASK;
break;
case ANATOP_SYSTEM_PLL2:
pll_gnrl_ctl = &ana_pll->sys_pll2_gnrl_ctl;
pll_div_ctl = &ana_pll->sys_pll2_div_ctl;
pll_clke_masks = INTPLL_DIV20_CLKE_MASK |
INTPLL_DIV10_CLKE_MASK | INTPLL_DIV8_CLKE_MASK |
INTPLL_DIV6_CLKE_MASK | INTPLL_DIV5_CLKE_MASK |
INTPLL_DIV4_CLKE_MASK | INTPLL_DIV3_CLKE_MASK |
INTPLL_DIV2_CLKE_MASK | INTPLL_CLKE_MASK;
break;
case ANATOP_SYSTEM_PLL3:
pll_gnrl_ctl = &ana_pll->sys_pll3_gnrl_ctl;
pll_div_ctl = &ana_pll->sys_pll3_div_ctl;
pll_clke_masks = INTPLL_CLKE_MASK;
break;
case ANATOP_ARM_PLL:
pll_gnrl_ctl = &ana_pll->arm_pll_gnrl_ctl;
pll_div_ctl = &ana_pll->arm_pll_div_ctl;
pll_clke_masks = INTPLL_CLKE_MASK;
break;
case ANATOP_GPU_PLL:
pll_gnrl_ctl = &ana_pll->gpu_pll_gnrl_ctl;
pll_div_ctl = &ana_pll->gpu_pll_div_ctl;
pll_clke_masks = INTPLL_CLKE_MASK;
break;
case ANATOP_VPU_PLL:
pll_gnrl_ctl = &ana_pll->vpu_pll_gnrl_ctl;
pll_div_ctl = &ana_pll->vpu_pll_div_ctl;
pll_clke_masks = INTPLL_CLKE_MASK;
break;
default:
return -EINVAL;
};
switch (freq) {
case MHZ(600):
/* 24 * 0x12c / 3 / 2 ^ 2 */
pll_div_ctl_val = INTPLL_MAIN_DIV_VAL(0x12c) |
INTPLL_PRE_DIV_VAL(3) | INTPLL_POST_DIV_VAL(2);
break;
case MHZ(750):
/* 24 * 0xfa / 2 / 2 ^ 2 */
pll_div_ctl_val = INTPLL_MAIN_DIV_VAL(0xfa) |
INTPLL_PRE_DIV_VAL(2) | INTPLL_POST_DIV_VAL(2);
break;
case MHZ(800):
/* 24 * 0x190 / 3 / 2 ^ 2 */
pll_div_ctl_val = INTPLL_MAIN_DIV_VAL(0x190) |
INTPLL_PRE_DIV_VAL(3) | INTPLL_POST_DIV_VAL(2);
break;
case MHZ(1000):
/* 24 * 0xfa / 3 / 2 ^ 1 */
pll_div_ctl_val = INTPLL_MAIN_DIV_VAL(0xfa) |
INTPLL_PRE_DIV_VAL(3) | INTPLL_POST_DIV_VAL(1);
break;
case MHZ(1200):
/* 24 * 0xc8 / 2 / 2 ^ 1 */
pll_div_ctl_val = INTPLL_MAIN_DIV_VAL(0xc8) |
INTPLL_PRE_DIV_VAL(2) | INTPLL_POST_DIV_VAL(1);
break;
case MHZ(2000):
/* 24 * 0xfa / 3 / 2 ^ 0 */
pll_div_ctl_val = INTPLL_MAIN_DIV_VAL(0xfa) |
INTPLL_PRE_DIV_VAL(3) | INTPLL_POST_DIV_VAL(0);
break;
default:
return -EINVAL;
};
/* Bypass clock and set lock to pll output lock */
setbits_le32(pll_gnrl_ctl, INTPLL_BYPASS_MASK | INTPLL_LOCK_SEL_MASK);
/* Enable reset */
clrbits_le32(pll_gnrl_ctl, INTPLL_RST_MASK);
/* Configure */
writel(pll_div_ctl_val, pll_div_ctl);
__udelay(100);
/* Disable reset */
setbits_le32(pll_gnrl_ctl, INTPLL_RST_MASK);
/* Wait Lock */
while (!(readl(pll_gnrl_ctl) & INTPLL_LOCK_MASK))
;
/* Clear bypass */
clrbits_le32(pll_gnrl_ctl, INTPLL_BYPASS_MASK);
setbits_le32(pll_gnrl_ctl, pll_clke_masks);
return 0;
}
void init_uart_clk(u32 index)
{
/*
@ -213,6 +317,72 @@ void init_wdog_clk(void)
clock_enable(CCGR_WDOG3, 1);
}
void init_clk_usdhc(u32 index)
{
/*
* set usdhc clock root
* sys pll1 400M
*/
switch (index) {
case 0:
clock_enable(CCGR_USDHC1, 0);
clock_set_target_val(USDHC1_CLK_ROOT, CLK_ROOT_ON |
CLK_ROOT_SOURCE_SEL(1));
clock_enable(CCGR_USDHC1, 1);
return;
case 1:
clock_enable(CCGR_USDHC2, 0);
clock_set_target_val(USDHC2_CLK_ROOT, CLK_ROOT_ON |
CLK_ROOT_SOURCE_SEL(1));
clock_enable(CCGR_USDHC2, 1);
return;
case 2:
clock_enable(CCGR_USDHC3, 0);
clock_set_target_val(USDHC3_CLK_ROOT, CLK_ROOT_ON |
CLK_ROOT_SOURCE_SEL(1));
clock_enable(CCGR_USDHC3, 1);
return;
default:
printf("Invalid usdhc index\n");
return;
}
}
void init_clk_ecspi(u32 index)
{
switch (index) {
case 0:
clock_enable(CCGR_ECSPI1, 0);
clock_set_target_val(ECSPI1_CLK_ROOT, CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(0));
clock_enable(CCGR_ECSPI1, 1);
return;
case 1:
clock_enable(CCGR_ECSPI2, 0);
clock_set_target_val(ECSPI2_CLK_ROOT, CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(0));
clock_enable(CCGR_ECSPI2, 1);
case 2:
clock_enable(CCGR_ECSPI3, 0);
clock_set_target_val(ECSPI3_CLK_ROOT, CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(0));
clock_enable(CCGR_ECSPI3, 1);
return;
default:
printf("Invalid ecspi index\n");
return;
}
}
void init_nand_clk(void)
{
/*
* set rawnand root
* sys pll1 400M
*/
clock_enable(CCGR_RAWNAND, 0);
clock_set_target_val(NAND_CLK_ROOT, CLK_ROOT_ON |
CLK_ROOT_SOURCE_SEL(3) | CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV4)); /* 100M */
clock_enable(CCGR_RAWNAND, 1);
}
int clock_init(void)
{
u32 val_cfg0;
@ -240,11 +410,33 @@ int clock_init(void)
INTPLL_DIV20_CLKE_MASK;
writel(val_cfg0, &ana_pll->sys_pll2_gnrl_ctl);
/* Configure ARM at 1.2GHz */
clock_set_target_val(ARM_A53_CLK_ROOT, CLK_ROOT_ON |
CLK_ROOT_SOURCE_SEL(2));
intpll_configure(ANATOP_ARM_PLL, MHZ(1200));
/* Bypass CCM A53 ROOT, Switch to ARM PLL -> MUX-> CPU */
clock_set_target_val(CORE_SEL_CFG, CLK_ROOT_SOURCE_SEL(1));
if (is_imx8mn() || is_imx8mp())
intpll_configure(ANATOP_SYSTEM_PLL3, MHZ(600));
else
intpll_configure(ANATOP_SYSTEM_PLL3, MHZ(750));
#ifdef CONFIG_IMX8MP
/* 8MP ROM already set NOC to 800Mhz, only need to configure NOC_IO clk to 600Mhz */
/* 8MP ROM already set GIC to 400Mhz, system_pll1_800m with div = 2 */
clock_set_target_val(NOC_IO_CLK_ROOT, CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(2));
#else
clock_set_target_val(NOC_CLK_ROOT, CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(2));
/* config GIC to sys_pll2_100m */
clock_enable(CCGR_GIC, 0);
clock_set_target_val(GIC_CLK_ROOT, CLK_ROOT_ON |
CLK_ROOT_SOURCE_SEL(3));
clock_enable(CCGR_GIC, 1);
#endif
clock_set_target_val(NAND_USDHC_BUS_CLK_ROOT, CLK_ROOT_ON |
CLK_ROOT_SOURCE_SEL(1));
@ -519,6 +711,8 @@ static u32 get_root_src_clk(enum clk_root_src root_src)
case AUDIO_PLL2_CLK:
case VIDEO_PLL_CLK:
return decode_fracpll(root_src);
case ARM_A53_ALT_CLK:
return get_root_clk(ARM_A53_CLK_ROOT);
default:
return 0;
}
@ -548,13 +742,26 @@ static u32 get_root_clk(enum clk_root_index clock_id)
return root_src_clk / (post_podf + 1) / (pre_podf + 1);
}
u32 get_arm_core_clk(void)
{
enum clk_root_src root_src;
u32 root_src_clk;
if (clock_get_src(CORE_SEL_CFG, &root_src) < 0)
return 0;
root_src_clk = get_root_src_clk(root_src);
return root_src_clk;
}
u32 mxc_get_clock(enum mxc_clock clk)
{
u32 val;
switch (clk) {
case MXC_ARM_CLK:
return get_root_clk(ARM_A53_CLK_ROOT);
return get_arm_core_clk();
case MXC_IPG_CLK:
clock_get_target_val(IPG_CLK_ROOT, &val);
val = val & 0x3;
@ -581,6 +788,96 @@ u32 mxc_get_clock(enum mxc_clock clk)
return 0;
}
#ifdef CONFIG_DWC_ETH_QOS
int set_clk_eqos(enum enet_freq type)
{
u32 target;
u32 enet1_ref;
switch (type) {
case ENET_125MHZ:
enet1_ref = ENET1_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_125M_CLK;
break;
case ENET_50MHZ:
enet1_ref = ENET1_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_50M_CLK;
break;
case ENET_25MHZ:
enet1_ref = ENET1_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_25M_CLK;
break;
default:
return -EINVAL;
}
/* disable the clock first */
clock_enable(CCGR_QOS_ETHENET, 0);
clock_enable(CCGR_SDMA2, 0);
/* set enet axi clock 266Mhz */
target = CLK_ROOT_ON | ENET_AXI_CLK_ROOT_FROM_SYS1_PLL_266M |
CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1);
clock_set_target_val(ENET_AXI_CLK_ROOT, target);
target = CLK_ROOT_ON | enet1_ref |
CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1);
clock_set_target_val(ENET_QOS_CLK_ROOT, target);
target = CLK_ROOT_ON |
ENET1_TIME_CLK_ROOT_FROM_PLL_ENET_MAIN_100M_CLK |
CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV4);
clock_set_target_val(ENET_QOS_TIMER_CLK_ROOT, target);
/* enable clock */
clock_enable(CCGR_QOS_ETHENET, 1);
clock_enable(CCGR_SDMA2, 1);
return 0;
}
int imx_eqos_txclk_set_rate(u32 rate)
{
u32 val;
u32 eqos_post_div;
/* disable the clock first */
clock_enable(CCGR_QOS_ETHENET, 0);
clock_enable(CCGR_SDMA2, 0);
switch (rate) {
case 125000000:
eqos_post_div = 1;
break;
case 25000000:
eqos_post_div = 125000000 / 25000000;
break;
case 2500000:
eqos_post_div = 125000000 / 2500000;
break;
default:
return -EINVAL;
}
clock_get_target_val(ENET_QOS_CLK_ROOT, &val);
val &= ~(CLK_ROOT_PRE_DIV_MASK | CLK_ROOT_POST_DIV_MASK);
val |= CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) |
CLK_ROOT_POST_DIV(eqos_post_div - 1);
clock_set_target_val(ENET_QOS_CLK_ROOT, val);
/* enable clock */
clock_enable(CCGR_QOS_ETHENET, 1);
clock_enable(CCGR_SDMA2, 1);
return 0;
}
u32 imx_get_eqos_csr_clk(void)
{
return get_root_clk(ENET_AXI_CLK_ROOT);
}
#endif
#ifdef CONFIG_FEC_MXC
int set_clk_enet(enum enet_freq type)
{

View File

@ -60,3 +60,15 @@ restore_boot_params:
ldr x0, [x0]
mov sp, x0
ret
.global armv8_el2_to_aarch32
armv8_el2_to_aarch32:
cmp x0, #0
bne 0f
mov x3, x2
mov x2, x1
mov x1, x4
ldr x0, =0xc20000fd
0:
smc #0
ret

View File

@ -16,12 +16,17 @@
#include <asm/mach-imx/hab.h>
#include <asm/mach-imx/boot_mode.h>
#include <asm/mach-imx/syscounter.h>
#include <asm/ptrace.h>
#include <asm/armv8/mmu.h>
#include <dm/uclass.h>
#include <efi_loader.h>
#include <env.h>
#include <env_internal.h>
#include <errno.h>
#include <fdt_support.h>
#include <fsl_wdog.h>
#include <imx_sip.h>
#include <linux/arm-smccc.h>
#include <linux/bitops.h>
DECLARE_GLOBAL_DATA_PTR;
@ -137,6 +142,9 @@ static struct mm_region imx8m_mem_map[] = {
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_OUTER_SHARE
#endif
}, {
/* empty entrie to split table entry 5 if needed when TEEs are used */
0,
}, {
/* List terminator */
0,
@ -147,18 +155,123 @@ struct mm_region *mem_map = imx8m_mem_map;
void enable_caches(void)
{
/*
* If OPTEE runs, remove OPTEE memory from MMU table to
* avoid speculative prefetch. OPTEE runs at the top of
* the first memory bank
*/
if (rom_pointer[1])
imx8m_mem_map[5].size -= rom_pointer[1];
/* If OPTEE runs, remove OPTEE memory from MMU table to avoid speculative prefetch */
if (rom_pointer[1]) {
/*
* TEE are loaded, So the ddr bank structures
* have been modified update mmu table accordingly
*/
int i = 0;
/*
* please make sure that entry initial value matches
* imx8m_mem_map for DRAM1
*/
int entry = 5;
u64 attrs = imx8m_mem_map[entry].attrs;
while (i < CONFIG_NR_DRAM_BANKS && entry < 8) {
if (gd->bd->bi_dram[i].start == 0)
break;
imx8m_mem_map[entry].phys = gd->bd->bi_dram[i].start;
imx8m_mem_map[entry].virt = gd->bd->bi_dram[i].start;
imx8m_mem_map[entry].size = gd->bd->bi_dram[i].size;
imx8m_mem_map[entry].attrs = attrs;
debug("Added memory mapping (%d): %llx %llx\n", entry,
imx8m_mem_map[entry].phys, imx8m_mem_map[entry].size);
i++; entry++;
}
}
icache_enable();
dcache_enable();
}
__weak int board_phys_sdram_size(phys_size_t *size)
{
if (!size)
return -EINVAL;
*size = PHYS_SDRAM_SIZE;
return 0;
}
int dram_init(void)
{
phys_size_t sdram_size;
int ret;
ret = board_phys_sdram_size(&sdram_size);
if (ret)
return ret;
/* rom_pointer[1] contains the size of TEE occupies */
if (rom_pointer[1])
gd->ram_size = sdram_size - rom_pointer[1];
else
gd->ram_size = sdram_size;
#ifdef PHYS_SDRAM_2_SIZE
gd->ram_size += PHYS_SDRAM_2_SIZE;
#endif
return 0;
}
int dram_init_banksize(void)
{
int bank = 0;
int ret;
phys_size_t sdram_size;
ret = board_phys_sdram_size(&sdram_size);
if (ret)
return ret;
gd->bd->bi_dram[bank].start = PHYS_SDRAM;
if (rom_pointer[1]) {
phys_addr_t optee_start = (phys_addr_t)rom_pointer[0];
phys_size_t optee_size = (size_t)rom_pointer[1];
gd->bd->bi_dram[bank].size = optee_start - gd->bd->bi_dram[bank].start;
if ((optee_start + optee_size) < (PHYS_SDRAM + sdram_size)) {
if (++bank >= CONFIG_NR_DRAM_BANKS) {
puts("CONFIG_NR_DRAM_BANKS is not enough\n");
return -1;
}
gd->bd->bi_dram[bank].start = optee_start + optee_size;
gd->bd->bi_dram[bank].size = PHYS_SDRAM +
sdram_size - gd->bd->bi_dram[bank].start;
}
} else {
gd->bd->bi_dram[bank].size = sdram_size;
}
#ifdef PHYS_SDRAM_2_SIZE
if (++bank >= CONFIG_NR_DRAM_BANKS) {
puts("CONFIG_NR_DRAM_BANKS is not enough for SDRAM_2\n");
return -1;
}
gd->bd->bi_dram[bank].start = PHYS_SDRAM_2;
gd->bd->bi_dram[bank].size = PHYS_SDRAM_2_SIZE;
#endif
return 0;
}
phys_size_t get_effective_memsize(void)
{
/* return the first bank as effective memory */
if (rom_pointer[1])
return ((phys_addr_t)rom_pointer[0] - PHYS_SDRAM);
#ifdef PHYS_SDRAM_2_SIZE
return gd->ram_size - PHYS_SDRAM_2_SIZE;
#else
return gd->ram_size;
#endif
}
static u32 get_cpu_variant_type(u32 type)
{
struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
@ -208,6 +321,38 @@ static u32 get_cpu_variant_type(u32 type)
return MXC_CPU_IMX8MNL;
break;
}
} else if (type == MXC_CPU_IMX8MP) {
u32 value0 = readl(&fuse->tester3);
u32 flag = 0;
if ((value0 & 0xc0000) == 0x80000)
return MXC_CPU_IMX8MPD;
/* vpu disabled */
if ((value0 & 0x43000000) == 0x43000000)
flag = 1;
/* npu disabled*/
if ((value & 0x8) == 0x8)
flag |= (1 << 1);
/* isp disabled */
if ((value & 0x3) == 0x3)
flag |= (1 << 2);
switch (flag) {
case 7:
return MXC_CPU_IMX8MPL;
case 6:
return MXC_CPU_IMX8MP5;
case 2:
return MXC_CPU_IMX8MP6;
case 1:
return MXC_CPU_IMX8MP7;
default:
break;
}
}
return type;
@ -225,7 +370,7 @@ u32 get_cpu_rev(void)
/* iMX8MP */
if (major_low == 0x43) {
return (MXC_CPU_IMX8MP << 12) | reg;
type = get_cpu_variant_type(MXC_CPU_IMX8MP);
} else if (major_low == 0x42) {
/* iMX8MN */
type = get_cpu_variant_type(MXC_CPU_IMX8MN);
@ -307,6 +452,25 @@ int arch_cpu_init(void)
if (IS_ENABLED(CONFIG_SPL_BUILD)) {
clock_init();
imx_set_wdog_powerdown(false);
if (is_imx8md() || is_imx8mmd() || is_imx8mmdl() || is_imx8mms() ||
is_imx8mmsl() || is_imx8mnd() || is_imx8mndl() || is_imx8mns() ||
is_imx8mnsl() || is_imx8mpd()) {
/* Power down cpu core 1, 2 and 3 for iMX8M Dual core or Single core */
struct pgc_reg *pgc_core1 = (struct pgc_reg *)(GPC_BASE_ADDR + 0x840);
struct pgc_reg *pgc_core2 = (struct pgc_reg *)(GPC_BASE_ADDR + 0x880);
struct pgc_reg *pgc_core3 = (struct pgc_reg *)(GPC_BASE_ADDR + 0x8C0);
struct gpc_reg *gpc = (struct gpc_reg *)GPC_BASE_ADDR;
writel(0x1, &pgc_core2->pgcr);
writel(0x1, &pgc_core3->pgcr);
if (is_imx8mms() || is_imx8mmsl() || is_imx8mns() || is_imx8mnsl()) {
writel(0x1, &pgc_core1->pgcr);
writel(0xE, &gpc->cpu_pgc_dn_trg);
} else {
writel(0xC, &gpc->cpu_pgc_dn_trg);
}
}
}
if (is_imx8mq()) {
@ -372,11 +536,297 @@ bool is_usb_boot(void)
}
#ifdef CONFIG_OF_SYSTEM_SETUP
int ft_system_setup(void *blob, bd_t *bd)
bool check_fdt_new_path(void *blob)
{
const char *soc_path = "/soc@0";
int nodeoff;
nodeoff = fdt_path_offset(blob, soc_path);
if (nodeoff < 0)
return false;
return true;
}
static int disable_fdt_nodes(void *blob, const char *const nodes_path[], int size_array)
{
int i = 0;
int rc;
int nodeoff;
const char *status = "disabled";
for (i = 0; i < size_array; i++) {
nodeoff = fdt_path_offset(blob, nodes_path[i]);
if (nodeoff < 0)
continue; /* Not found, skip it */
printf("Found %s node\n", nodes_path[i]);
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",
nodes_path[i], "status", fdt_strerror(rc));
} else {
printf("Modify %s:%s disabled\n",
nodes_path[i], "status");
}
}
return 0;
}
#ifdef CONFIG_IMX8MQ
bool check_dcss_fused(void)
{
struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
struct fuse_bank *bank = &ocotp->bank[1];
struct fuse_bank1_regs *fuse =
(struct fuse_bank1_regs *)bank->fuse_regs;
u32 value = readl(&fuse->tester4);
if (value & 0x4000000)
return true;
return false;
}
static int disable_mipi_dsi_nodes(void *blob)
{
static const char * const nodes_path[] = {
"/mipi_dsi@30A00000",
"/mipi_dsi_bridge@30A00000",
"/dsi_phy@30A00300",
"/soc@0/bus@30800000/mipi_dsi@30a00000",
"/soc@0/bus@30800000/dphy@30a00300"
};
return disable_fdt_nodes(blob, nodes_path, ARRAY_SIZE(nodes_path));
}
static int disable_dcss_nodes(void *blob)
{
static const char * const nodes_path[] = {
"/dcss@0x32e00000",
"/dcss@32e00000",
"/hdmi@32c00000",
"/hdmi_cec@32c33800",
"/hdmi_drm@32c00000",
"/display-subsystem",
"/sound-hdmi",
"/sound-hdmi-arc",
"/soc@0/bus@32c00000/display-controller@32e00000",
"/soc@0/bus@32c00000/hdmi@32c00000",
};
return disable_fdt_nodes(blob, nodes_path, ARRAY_SIZE(nodes_path));
}
static int check_mipi_dsi_nodes(void *blob)
{
static const char * const lcdif_path[] = {
"/lcdif@30320000",
"/soc@0/bus@30000000/lcdif@30320000"
};
static const char * const mipi_dsi_path[] = {
"/mipi_dsi@30A00000",
"/soc@0/bus@30800000/mipi_dsi@30a00000"
};
static const char * const lcdif_ep_path[] = {
"/lcdif@30320000/port@0/mipi-dsi-endpoint",
"/soc@0/bus@30000000/lcdif@30320000/port@0/endpoint"
};
static const char * const mipi_dsi_ep_path[] = {
"/mipi_dsi@30A00000/port@1/endpoint",
"/soc@0/bus@30800000/mipi_dsi@30a00000/ports/port@0/endpoint"
};
int lookup_node;
int nodeoff;
bool new_path = check_fdt_new_path(blob);
int i = new_path ? 1 : 0;
nodeoff = fdt_path_offset(blob, lcdif_path[i]);
if (nodeoff < 0 || !fdtdec_get_is_enabled(blob, nodeoff)) {
/*
* If can't find lcdif node or lcdif node is disabled,
* then disable all mipi dsi, since they only can input
* from DCSS
*/
return disable_mipi_dsi_nodes(blob);
}
nodeoff = fdt_path_offset(blob, mipi_dsi_path[i]);
if (nodeoff < 0 || !fdtdec_get_is_enabled(blob, nodeoff))
return 0;
nodeoff = fdt_path_offset(blob, lcdif_ep_path[i]);
if (nodeoff < 0) {
/*
* If can't find lcdif endpoint, then disable all mipi dsi,
* since they only can input from DCSS
*/
return disable_mipi_dsi_nodes(blob);
}
lookup_node = fdtdec_lookup_phandle(blob, nodeoff, "remote-endpoint");
nodeoff = fdt_path_offset(blob, mipi_dsi_ep_path[i]);
if (nodeoff > 0 && nodeoff == lookup_node)
return 0;
return disable_mipi_dsi_nodes(blob);
}
#endif
int disable_vpu_nodes(void *blob)
{
static const char * const nodes_path_8mq[] = {
"/vpu@38300000",
"/soc@0/vpu@38300000"
};
static const char * const nodes_path_8mm[] = {
"/vpu_g1@38300000",
"/vpu_g2@38310000",
"/vpu_h1@38320000"
};
static const char * const nodes_path_8mp[] = {
"/vpu_g1@38300000",
"/vpu_g2@38310000",
"/vpu_vc8000e@38320000"
};
if (is_imx8mq())
return disable_fdt_nodes(blob, nodes_path_8mq, ARRAY_SIZE(nodes_path_8mq));
else if (is_imx8mm())
return disable_fdt_nodes(blob, nodes_path_8mm, ARRAY_SIZE(nodes_path_8mm));
else if (is_imx8mp())
return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
else
return -EPERM;
}
int disable_gpu_nodes(void *blob)
{
static const char * const nodes_path_8mn[] = {
"/gpu@38000000"
};
return disable_fdt_nodes(blob, nodes_path_8mn, ARRAY_SIZE(nodes_path_8mn));
}
int disable_npu_nodes(void *blob)
{
static const char * const nodes_path_8mp[] = {
"/vipsi@38500000"
};
return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
}
int disable_isp_nodes(void *blob)
{
static const char * const nodes_path_8mp[] = {
"/soc@0/bus@32c00000/camera/isp@32e10000",
"/soc@0/bus@32c00000/camera/isp@32e20000"
};
return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
}
int disable_dsp_nodes(void *blob)
{
static const char * const nodes_path_8mp[] = {
"/dsp@3b6e8000"
};
return disable_fdt_nodes(blob, nodes_path_8mp, ARRAY_SIZE(nodes_path_8mp));
}
static int disable_cpu_nodes(void *blob, u32 disabled_cores)
{
static const char * const nodes_path[] = {
"/cpus/cpu@1",
"/cpus/cpu@2",
"/cpus/cpu@3",
};
u32 i = 0;
int rc;
int nodeoff;
if (disabled_cores > 3)
return -EINVAL;
i = 3 - disabled_cores;
for (; i < 3; i++) {
nodeoff = fdt_path_offset(blob, nodes_path[i]);
if (nodeoff < 0)
continue; /* Not found, skip it */
debug("Found %s node\n", nodes_path[i]);
rc = fdt_del_node(blob, nodeoff);
if (rc < 0) {
printf("Unable to delete node %s, err=%s\n",
nodes_path[i], fdt_strerror(rc));
} else {
printf("Delete node %s\n", nodes_path[i]);
}
}
return 0;
}
int ft_system_setup(void *blob, bd_t *bd)
{
#ifdef CONFIG_IMX8MQ
int i = 0;
int rc;
int nodeoff;
if (get_boot_device() == USB_BOOT) {
disable_dcss_nodes(blob);
bool new_path = check_fdt_new_path(blob);
int v = new_path ? 1 : 0;
static const char * const usb_dwc3_path[] = {
"/usb@38100000/dwc3",
"/soc@0/usb@38100000"
};
nodeoff = fdt_path_offset(blob, usb_dwc3_path[v]);
if (nodeoff >= 0) {
const char *speed = "high-speed";
printf("Found %s node\n", usb_dwc3_path[v]);
usb_modify_speed:
rc = fdt_setprop(blob, nodeoff, "maximum-speed", speed, strlen(speed) + 1);
if (rc) {
if (rc == -FDT_ERR_NOSPACE) {
rc = fdt_increase_size(blob, 512);
if (!rc)
goto usb_modify_speed;
}
printf("Unable to set property %s:%s, err=%s\n",
usb_dwc3_path[v], "maximum-speed", fdt_strerror(rc));
} else {
printf("Modify %s:%s = %s\n",
usb_dwc3_path[v], "maximum-speed", speed);
}
} else {
printf("Can't found %s node\n", usb_dwc3_path[v]);
}
}
/* Disable the CPU idle for A0 chip since the HW does not support it */
if (is_soc_rev(CHIP_REV_1_0)) {
@ -408,6 +858,53 @@ int ft_system_setup(void *blob, bd_t *bd)
}
}
if (is_imx8mql()) {
disable_vpu_nodes(blob);
if (check_dcss_fused()) {
printf("DCSS is fused\n");
disable_dcss_nodes(blob);
check_mipi_dsi_nodes(blob);
}
}
if (is_imx8md())
disable_cpu_nodes(blob, 2);
#elif defined(CONFIG_IMX8MM)
if (is_imx8mml() || is_imx8mmdl() || is_imx8mmsl())
disable_vpu_nodes(blob);
if (is_imx8mmd() || is_imx8mmdl())
disable_cpu_nodes(blob, 2);
else if (is_imx8mms() || is_imx8mmsl())
disable_cpu_nodes(blob, 3);
#elif defined(CONFIG_IMX8MN)
if (is_imx8mnl() || is_imx8mndl() || is_imx8mnsl())
disable_gpu_nodes(blob);
if (is_imx8mnd() || is_imx8mndl())
disable_cpu_nodes(blob, 2);
else if (is_imx8mns() || is_imx8mnsl())
disable_cpu_nodes(blob, 3);
#elif defined(CONFIG_IMX8MP)
if (is_imx8mpl() || is_imx8mp7())
disable_vpu_nodes(blob);
if (is_imx8mpl() || is_imx8mp6() || is_imx8mp5())
disable_npu_nodes(blob);
if (is_imx8mpl() || is_imx8mp5())
disable_isp_nodes(blob);
if (is_imx8mpl() || is_imx8mp7() || is_imx8mp6() || is_imx8mp5())
disable_dsp_nodes(blob);
if (is_imx8mpd())
disable_cpu_nodes(blob, 2);
#endif
return 0;
}
#endif
@ -432,10 +929,12 @@ void reset_cpu(ulong addr)
static void acquire_buildinfo(void)
{
u64 atf_commit = 0;
struct arm_smccc_res res;
/* Get ARM Trusted Firmware commit id */
atf_commit = call_imx_sip(IMX_SIP_BUILDINFO,
IMX_SIP_BUILDINFO_GET_COMMITHASH, 0, 0, 0);
arm_smccc_smc(IMX_SIP_BUILDINFO, IMX_SIP_BUILDINFO_GET_COMMITHASH,
0, 0 , 0, 0, 0, 0, &res);
atf_commit = res.a0;
if (atf_commit == 0xffffffff) {
debug("ATF does not support build info\n");
atf_commit = 0x30; /* Display 0, 0 ascii is 0x30 */
@ -524,3 +1023,96 @@ void imx_tmu_arch_init(void *reg_base)
writel(tca40[0] | (tca40[1] << 16), (ulong)reg_base + 0x38);
#endif
}
#if defined(CONFIG_SPL_BUILD)
#if defined(CONFIG_IMX8MQ) || defined(CONFIG_IMX8MM) || defined(CONFIG_IMX8MN)
bool serror_need_skip = true;
void do_error(struct pt_regs *pt_regs, unsigned int esr)
{
/*
* If stack is still in ROM reserved OCRAM not switch to SPL,
* it is the ROM SError
*/
ulong sp;
asm volatile("mov %0, sp" : "=r"(sp) : );
if (serror_need_skip && sp < 0x910000 && sp >= 0x900000) {
/* Check for ERR050342, imx8mq HDCP enabled parts */
if (is_imx8mq() && !(readl(OCOTP_BASE_ADDR + 0x450) & 0x08000000)) {
serror_need_skip = false;
return; /* Do nothing skip the SError in ROM */
}
/* Check for ERR050350, field return mode for imx8mq, mm and mn */
if (readl(OCOTP_BASE_ADDR + 0x630) & 0x1) {
serror_need_skip = false;
return; /* Do nothing skip the SError in ROM */
}
}
efi_restore_gd();
printf("\"Error\" handler, esr 0x%08x\n", esr);
show_regs(pt_regs);
panic("Resetting CPU ...\n");
}
#endif
#endif
#if defined(CONFIG_IMX8MN) || defined(CONFIG_IMX8MP)
enum env_location env_get_location(enum env_operation op, int prio)
{
enum boot_device dev = get_boot_device();
enum env_location env_loc = ENVL_UNKNOWN;
if (prio)
return env_loc;
switch (dev) {
#ifdef CONFIG_ENV_IS_IN_SPI_FLASH
case QSPI_BOOT:
env_loc = ENVL_SPI_FLASH;
break;
#endif
#ifdef CONFIG_ENV_IS_IN_NAND
case NAND_BOOT:
env_loc = ENVL_NAND;
break;
#endif
#ifdef CONFIG_ENV_IS_IN_MMC
case SD1_BOOT:
case SD2_BOOT:
case SD3_BOOT:
case MMC1_BOOT:
case MMC2_BOOT:
case MMC3_BOOT:
env_loc = ENVL_MMC;
break;
#endif
default:
#if defined(CONFIG_ENV_IS_NOWHERE)
env_loc = ENVL_NOWHERE;
#endif
break;
}
return env_loc;
}
#ifndef ENV_IS_EMBEDDED
long long env_get_offset(long long defautl_offset)
{
enum boot_device dev = get_boot_device();
switch (dev) {
case NAND_BOOT:
return (60 << 20); /* 60MB offset for NAND */
default:
break;
}
return defautl_offset;
}
#endif
#endif

View File

@ -10,6 +10,7 @@
#include <command.h>
#include <elf.h>
#include <imx_sip.h>
#include <linux/arm-smccc.h>
#include <linux/compiler.h>
#include <cpu_func.h>
@ -55,7 +56,8 @@ int arch_auxiliary_core_up(u32 core_id, ulong addr)
/* Enable M4 */
#ifdef CONFIG_IMX8M
call_imx_sip(IMX_SIP_SRC, IMX_SIP_SRC_M4_START, 0, 0, 0);
arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_M4_START, 0, 0,
0, 0, 0, 0, NULL);
#else
clrsetbits_le32(SRC_BASE_ADDR + SRC_M4_REG_OFFSET,
SRC_M4C_NON_SCLR_RST_MASK, SRC_M4_ENABLE_MASK);
@ -67,7 +69,12 @@ int arch_auxiliary_core_up(u32 core_id, ulong addr)
int arch_auxiliary_core_check_up(u32 core_id)
{
#ifdef CONFIG_IMX8M
return call_imx_sip(IMX_SIP_SRC, IMX_SIP_SRC_M4_STARTED, 0, 0, 0);
struct arm_smccc_res res;
arm_smccc_smc(IMX_SIP_SRC, IMX_SIP_SRC_M4_STARTED, 0, 0,
0, 0, 0, 0, &res);
return res.a0;
#else
unsigned int val;

View File

@ -511,6 +511,10 @@ config TARGET_PCM058
bool "Phytec PCM058 i.MX6 Quad"
select BOARD_LATE_INIT
select SUPPORT_SPL
select MX6Q
select DM
select OF_CONTROL
imply CMD_DM
config TARGET_PFLA02
bool "Phytec PFLA02 (PhyFlex) i.MX6 Quad"

View File

@ -22,6 +22,7 @@
#include <asm/arch/mxc_hdmi.h>
#include <asm/arch/crm_regs.h>
#include <dm.h>
#include <fsl_sec.h>
#include <imx_thermal.h>
#include <mmc.h>
@ -691,6 +692,15 @@ void imx_setup_hdmi(void)
}
#endif
#ifdef CONFIG_ARCH_MISC_INIT
int arch_misc_init(void)
{
#ifdef CONFIG_FSL_CAAM
sec_init();
#endif
return 0;
}
#endif
/*
* gpr_init() function is common for boards using MX6S, MX6DL, MX6D,

View File

@ -1,48 +0,0 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2017 NXP
*/
#include <common.h>
#include <asm/arch/sys_proto.h>
#include <asm/cache.h>
#include <asm/ptrace.h>
unsigned long call_imx_sip(unsigned long id, unsigned long reg0,
unsigned long reg1, unsigned long reg2,
unsigned long reg3)
{
struct pt_regs regs;
regs.regs[0] = id;
regs.regs[1] = reg0;
regs.regs[2] = reg1;
regs.regs[3] = reg2;
regs.regs[4] = reg3;
smc_call(&regs);
return regs.regs[0];
}
/*
* Do an SMC call to return 2 registers by having reg1 passed in by reference
*/
unsigned long call_imx_sip_ret2(unsigned long id, unsigned long reg0,
unsigned long *reg1, unsigned long reg2,
unsigned long reg3)
{
struct pt_regs regs;
regs.regs[0] = id;
regs.regs[1] = reg0;
regs.regs[2] = *reg1;
regs.regs[3] = reg2;
regs.regs[4] = reg3;
smc_call(&regs);
*reg1 = regs.regs[1];
return regs.regs[0];
}

View File

@ -13,17 +13,6 @@
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)
{

View File

@ -15,17 +15,6 @@
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)
{

View File

@ -9,13 +9,6 @@
DECLARE_GLOBAL_DATA_PTR;
int dram_init(void)
{
gd->ram_size = PHYS_SDRAM_SIZE;
return 0;
}
int board_init(void)
{
return 0;

View File

@ -40,46 +40,6 @@ int board_early_init_f(void)
return 0;
}
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;
#if CONFIG_NR_DRAM_BANKS > 1
gd->ram_size += PHYS_SDRAM_2_SIZE;
#endif
return 0;
}
int dram_init_banksize(void)
{
gd->bd->bi_dram[0].start = PHYS_SDRAM;
if (rom_pointer[1])
gd->bd->bi_dram[0].size = PHYS_SDRAM_SIZE - rom_pointer[1];
else
gd->bd->bi_dram[0].size = PHYS_SDRAM_SIZE;
#if CONFIG_NR_DRAM_BANKS > 1
gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
#endif
return 0;
}
phys_size_t get_effective_memsize(void)
{
if (rom_pointer[1])
return (PHYS_SDRAM_SIZE - rom_pointer[1]);
else
return PHYS_SDRAM_SIZE;
}
int board_init(void)
{
return 0;

View File

@ -11,7 +11,7 @@ struct dram_cfg_param ddr_ddrc_cfg[] = {
{ 0x3d400304, 0x1 },
{ 0x3d400030, 0x1 },
{ 0x3d400000, 0xa3080020 },
{ 0x3d400020, 0x323 },
{ 0x3d400020, 0x1323 },
{ 0x3d400024, 0x1e84800 },
{ 0x3d400064, 0x7a0118 },
{ 0x3d4000d0, 0xc00307a3 },
@ -52,12 +52,13 @@ struct dram_cfg_param ddr_ddrc_cfg[] = {
{ 0x3d400214, 0x7070707 },
{ 0x3d400218, 0x68070707 },
{ 0x3d40021c, 0xf08 },
{ 0x3d400250, 0x29001701 },
{ 0x3d400250, 0x00001705 },
{ 0x3d400254, 0x2c },
{ 0x3d40025c, 0x4000030 },
{ 0x3d400264, 0x900093e7 },
{ 0x3d40026c, 0x2005574 },
{ 0x3d400400, 0x111 },
{ 0x3d400404, 0x72ff },
{ 0x3d400408, 0x72ff },
{ 0x3d400494, 0x2100e07 },
{ 0x3d400498, 0x620096 },

View File

@ -68,7 +68,7 @@ int power_init_board(void)
struct pmic *p;
int ret;
ret = power_pca9450b_init(I2C_PMIC);
ret = power_pca9450_init(I2C_PMIC);
if (ret)
printf("power init failed");
p = pmic_get("PCA9450");

View File

@ -53,17 +53,6 @@ int board_early_init_f(void)
return 0;
}
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;
}
#ifdef CONFIG_FEC_MXC
static int setup_fec(void)
{

View File

@ -48,17 +48,6 @@ int board_early_init_f(void)
return 0;
}
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;
}
#ifdef CONFIG_FEC_MXC
static int setup_fec(void)
{

View File

@ -116,6 +116,7 @@ void board_boot_order(u32 *spl_boot_list)
{
spl_boot_list[0] = BOOT_DEVICE_MMC1;
spl_boot_list[1] = BOOT_DEVICE_SPI;
spl_boot_list[2] = BOOT_DEVICE_UART;
}
int spl_start_uboot(void)

View File

@ -1,6 +1,7 @@
PHYTEC PHYBOARD MIRA
M: Stefano Babic <sbabic@denx.de>
M: Niel Fourie <lusus@denx.de>
S: Maintained
F: board/phytec/pcm058/
F: include/configs/pcm058.h
F: configs/pcm058_defconfig
F: arch/arm/dts/imx6q-phytec-mira-rdk-nand-u-boot.dtsi

View File

@ -33,3 +33,54 @@ is present, then the RBL tries to load SPL from the SD Card, if not,
RBL loads from SPI-NOR. The SPL tries then to load from the same
device where SPL was loaded (SD or SPI). Booting from NAND is
not supported.
Flashing U-Boot onto an SD card
-------------------------------
After a successful build, the generated SPL and U-boot binaries can be copied
to an SD card. Adjust the SD card device as necessary:
$ sudo dd if=u-boot-with-spl.imx of=/dev/mmcblk0 bs=1k seek=1
This is equivalent to separately copying the SPL and U-boot using:
$ sudo dd if=SPL of=/dev/mmcblk0 bs=1k seek=1
$ sudo dd if=u-boot-dtb.img of=/dev/mmcblk0 bs=1k seek=197
The default bootscripts expect a kernel fit-image file named "fitImage" in the
first partition and Linux ext4 rootfs in the second partition.
Flashing U-boot to the SPI Flash, for booting Linux from NAND
-------------------------------------------------------------
The SD card created above can also be used to install the SPL and U-boot into
the SPI flash. Boot U-boot from the SD card as above, and stop at the autoboot.
Then, clear the SPI flash:
=> sf probe
=> sf erase 0x0 0x1000000
Load the SPL from raw MMC into memory and copy to the SPI. The SPL is maximum
392*512-byte blocks in size therefore 0x188 blocks, totaling 0x31000 bytes:
=> mmc read ${loadaddr} 0x2 0x188
=> sf write ${loadaddr} 0x400 0x31000
Load the U-boot binary into memory and copy to the SPI. U-boot should fit into
640KiB, so 0x500 512-byte blocks, totalling 0xA0000 bytes:
=> mmc read ${loadaddr} 0x18a 0x500
=> sf write ${loadaddr} 0x40000 0xA0000
The default NAND bootscripts expect a single MTD partition named "rootfs",
which in turn contains the UBI volumes "fit" (which contains the kernel fit-
image) and "root" (which contains a ubifs root filesystem).
The "bootm_size" variable in the environment
--------------------------------------------
By default, U-boot relocates the device tree towards the upper end of the RAM,
which kernels using CONFIG_HIGHMEM=y may not be able to access during early
boot. With the bootm_size variable set to 0x30000000, U-boot relocates the
device tree to below this address instead.

View File

@ -12,60 +12,14 @@
#include <common.h>
#include <init.h>
#include <net.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
#include <asm/arch/imx-regs.h>
#include <asm/arch/crm_regs.h>
#include <asm/arch/mx6-ddr.h>
#include <asm/arch/iomux.h>
#include <asm/arch/mx6-pins.h>
#include <asm/mach-imx/iomux-v3.h>
#include <asm/mach-imx/boot_mode.h>
#include <asm/mach-imx/mxc_i2c.h>
#include <asm/mach-imx/spi.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <asm/gpio.h>
#include <mmc.h>
#include <i2c.h>
#include <fsl_esdhc_imx.h>
#include <nand.h>
#include <miiphy.h>
#include <netdev.h>
#include <asm/arch/sys_proto.h>
#include <asm/sections.h>
#include <dm.h>
DECLARE_GLOBAL_DATA_PTR;
#define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \
PAD_CTL_SRE_FAST | PAD_CTL_HYS)
#define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | \
PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm | \
PAD_CTL_SRE_FAST | PAD_CTL_HYS)
#define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
#define SPI_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_SPEED_MED | \
PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST)
#define I2C_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \
PAD_CTL_ODE | PAD_CTL_SRE_FAST)
#define I2C_PAD MUX_PAD_CTRL(I2C_PAD_CTRL)
#define ASRC_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | \
PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST)
#define NAND_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST)
#define ENET_PHY_RESET_GPIO IMX_GPIO_NR(1, 14)
#define USDHC1_CD_GPIO IMX_GPIO_NR(6, 31)
#define USER_LED IMX_GPIO_NR(1, 4)
#define IMX6Q_DRIVE_STRENGTH 0x30
int dram_init(void)
@ -74,229 +28,16 @@ int dram_init(void)
return 0;
}
void board_turn_off_led(void)
{
gpio_direction_output(USER_LED, 0);
}
static iomux_v3_cfg_t const uart1_pads[] = {
MX6_PAD_EIM_D26__UART2_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
MX6_PAD_EIM_D27__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
};
static iomux_v3_cfg_t const enet_pads[] = {
MX6_PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_SD2_DAT1__GPIO1_IO14 | MUX_PAD_CTRL(NO_PAD_CTRL),
};
static iomux_v3_cfg_t const ecspi1_pads[] = {
MX6_PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL),
MX6_PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL),
MX6_PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL),
MX6_PAD_EIM_D19__GPIO3_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL),
};
#ifdef CONFIG_CMD_NAND
/* NAND */
static iomux_v3_cfg_t const nfc_pads[] = {
MX6_PAD_NANDF_CLE__NAND_CLE | MUX_PAD_CTRL(NAND_PAD_CTRL),
MX6_PAD_NANDF_ALE__NAND_ALE | MUX_PAD_CTRL(NAND_PAD_CTRL),
MX6_PAD_NANDF_WP_B__NAND_WP_B | MUX_PAD_CTRL(NAND_PAD_CTRL),
MX6_PAD_NANDF_RB0__NAND_READY_B | MUX_PAD_CTRL(NAND_PAD_CTRL),
MX6_PAD_NANDF_CS0__NAND_CE0_B | MUX_PAD_CTRL(NAND_PAD_CTRL),
MX6_PAD_NANDF_CS1__NAND_CE1_B | MUX_PAD_CTRL(NAND_PAD_CTRL),
MX6_PAD_NANDF_CS2__NAND_CE2_B | MUX_PAD_CTRL(NAND_PAD_CTRL),
MX6_PAD_NANDF_CS3__NAND_CE3_B | MUX_PAD_CTRL(NAND_PAD_CTRL),
MX6_PAD_SD4_CMD__NAND_RE_B | MUX_PAD_CTRL(NAND_PAD_CTRL),
MX6_PAD_SD4_CLK__NAND_WE_B | MUX_PAD_CTRL(NAND_PAD_CTRL),
MX6_PAD_NANDF_D0__NAND_DATA00 | MUX_PAD_CTRL(NAND_PAD_CTRL),
MX6_PAD_NANDF_D1__NAND_DATA01 | MUX_PAD_CTRL(NAND_PAD_CTRL),
MX6_PAD_NANDF_D2__NAND_DATA02 | MUX_PAD_CTRL(NAND_PAD_CTRL),
MX6_PAD_NANDF_D3__NAND_DATA03 | MUX_PAD_CTRL(NAND_PAD_CTRL),
MX6_PAD_NANDF_D4__NAND_DATA04 | MUX_PAD_CTRL(NAND_PAD_CTRL),
MX6_PAD_NANDF_D5__NAND_DATA05 | MUX_PAD_CTRL(NAND_PAD_CTRL),
MX6_PAD_NANDF_D6__NAND_DATA06 | MUX_PAD_CTRL(NAND_PAD_CTRL),
MX6_PAD_NANDF_D7__NAND_DATA07 | MUX_PAD_CTRL(NAND_PAD_CTRL),
MX6_PAD_SD4_DAT0__NAND_DQS | MUX_PAD_CTRL(NAND_PAD_CTRL),
};
#endif
static struct i2c_pads_info i2c_pad_info2 = {
.scl = {
.i2c_mode = MX6_PAD_GPIO_5__I2C3_SCL | I2C_PAD,
.gpio_mode = MX6_PAD_GPIO_5__GPIO1_IO05 | I2C_PAD,
.gp = IMX_GPIO_NR(1, 5)
},
.sda = {
.i2c_mode = MX6_PAD_GPIO_6__I2C3_SDA | I2C_PAD,
.gpio_mode = MX6_PAD_GPIO_6__GPIO1_IO06 | I2C_PAD,
.gp = IMX_GPIO_NR(1, 6)
}
};
static struct fsl_esdhc_cfg usdhc_cfg[] = {
{.esdhc_base = USDHC1_BASE_ADDR,
.max_bus_width = 4},
#ifndef CONFIG_CMD_NAND
{USDHC4_BASE_ADDR},
#endif
};
static iomux_v3_cfg_t const usdhc1_pads[] = {
MX6_PAD_SD1_CLK__SD1_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
MX6_PAD_SD1_CMD__SD1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
MX6_PAD_SD1_DAT0__SD1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
MX6_PAD_SD1_DAT1__SD1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
MX6_PAD_SD1_DAT2__SD1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
MX6_PAD_SD1_DAT3__SD1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
MX6_PAD_EIM_BCLK__GPIO6_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
};
#if !defined(CONFIG_CMD_NAND) && !defined(CONFIG_SPL_BUILD)
static iomux_v3_cfg_t const usdhc4_pads[] = {
MX6_PAD_SD4_CLK__SD4_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
MX6_PAD_SD4_CMD__SD4_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
MX6_PAD_SD4_DAT0__SD4_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
MX6_PAD_SD4_DAT1__SD4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
MX6_PAD_SD4_DAT2__SD4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
MX6_PAD_SD4_DAT3__SD4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
MX6_PAD_SD4_DAT4__SD4_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
MX6_PAD_SD4_DAT5__SD4_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
MX6_PAD_SD4_DAT6__SD4_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
MX6_PAD_SD4_DAT7__SD4_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
};
#endif
int board_mmc_get_env_dev(int devno)
{
return devno - 1;
}
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 = !gpio_get_value(USDHC1_CD_GPIO);
break;
case USDHC4_BASE_ADDR:
ret = 1; /* eMMC/uSDHC4 is always present */
break;
}
return ret;
}
int board_mmc_init(bd_t *bis)
{
#ifndef CONFIG_SPL_BUILD
int ret;
int i;
for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) {
switch (i) {
case 0:
imx_iomux_v3_setup_multiple_pads(
usdhc1_pads, ARRAY_SIZE(usdhc1_pads));
gpio_direction_input(USDHC1_CD_GPIO);
usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
break;
#ifndef CONFIG_CMD_NAND
case 1:
imx_iomux_v3_setup_multiple_pads(
usdhc4_pads, ARRAY_SIZE(usdhc4_pads));
usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
break;
#endif
default:
printf("Warning: you configured more USDHC controllers"
"(%d) then supported by the board (%d)\n",
i + 1, CONFIG_SYS_FSL_USDHC_NUM);
return -EINVAL;
}
ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
if (ret)
return ret;
}
return 0;
#else
struct src *psrc = (struct src *)SRC_BASE_ADDR;
unsigned reg = readl(&psrc->sbmr1) >> 11;
/*
* Upon reading BOOT_CFG register the following map is done:
* Bit 11 and 12 of BOOT_CFG register can determine the current
* mmc port
* 0x1 SD1
* 0x2 SD2
* 0x3 SD4
*/
switch (reg & 0x3) {
case 0x0:
imx_iomux_v3_setup_multiple_pads(
usdhc1_pads, ARRAY_SIZE(usdhc1_pads));
gpio_direction_input(USDHC1_CD_GPIO);
usdhc_cfg[0].esdhc_base = USDHC1_BASE_ADDR;
usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
usdhc_cfg[0].max_bus_width = 4;
gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
break;
}
return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
#endif
}
static void setup_iomux_uart(void)
{
imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads));
}
static void setup_iomux_enet(void)
{
imx_iomux_v3_setup_multiple_pads(enet_pads, ARRAY_SIZE(enet_pads));
gpio_direction_output(ENET_PHY_RESET_GPIO, 0);
mdelay(10);
gpio_set_value(ENET_PHY_RESET_GPIO, 1);
mdelay(30);
}
static void setup_spi(void)
{
gpio_request(IMX_GPIO_NR(3, 19), "spi_cs0");
gpio_direction_output(IMX_GPIO_NR(3, 19), 1);
imx_iomux_v3_setup_multiple_pads(ecspi1_pads, ARRAY_SIZE(ecspi1_pads));
enable_spi_clk(true, 0);
}
#ifdef CONFIG_CMD_NAND
static void setup_gpmi_nand(void)
{
struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
/* config gpmi nand iomux */
imx_iomux_v3_setup_multiple_pads(nfc_pads, ARRAY_SIZE(nfc_pads));
/* gate ENFC_CLK_ROOT clock first,before clk source switch */
clrbits_le32(&mxc_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK);
@ -325,48 +66,17 @@ static void setup_gpmi_nand(void)
}
#endif
int board_spi_cs_gpio(unsigned bus, unsigned cs)
{
if (bus != 0 || (cs != 0))
return -EINVAL;
return IMX_GPIO_NR(3, 19);
}
int board_eth_init(bd_t *bis)
{
setup_iomux_enet();
return cpu_eth_init(bis);
}
int board_early_init_f(void)
{
setup_iomux_uart();
return 0;
}
int board_init(void)
{
/* address of boot parameters */
gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
#ifdef CONFIG_SYS_I2C_MXC
setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2);
#endif
#ifdef CONFIG_MXC_SPI
setup_spi();
#endif
#ifdef CONFIG_CMD_NAND
setup_gpmi_nand();
#endif
return 0;
}
#ifdef CONFIG_CMD_BMODE
/*
* BOOT_CFG1, BOOT_CFG2, BOOT_CFG3, BOOT_CFG4
@ -535,11 +245,6 @@ void board_boot_order(u32 *spl_boot_list)
void board_init_f(ulong dummy)
{
#ifdef CONFIG_CMD_NAND
/* Enable NAND */
setup_gpmi_nand();
#endif
/* setup clock gating */
ccgr_init();
@ -549,23 +254,33 @@ void board_init_f(ulong dummy)
/* setup AXI */
gpr_init();
board_early_init_f();
/* setup GP timer */
timer_init();
setup_spi();
/* UART clocks enabled and gd valid - init serial console */
preloader_console_init();
/* DDR initialization */
spl_dram_init();
/* Clear the BSS. */
memset(__bss_start, 0, __bss_end - __bss_start);
/* load/boot image from boot device */
board_init_r(NULL, 0);
/* Enable device tree and early DM support*/
spl_early_init();
/* UART clocks enabled and gd valid - init serial console */
preloader_console_init();
}
/*
* Manually probe the SPI bus devices, as this does not happen when the
* SPI Flash is probed, which then fails to find the bus.
*/
void spl_board_init(void)
{
struct udevice *udev;
int ret = uclass_get_device_by_name(UCLASS_SPI, "spi@2008000", &udev);
if (ret) {
printf("SPI bus probe failed, err = %d\n", ret);
};
}
#endif

View File

@ -22,8 +22,8 @@ If the eMMC has already a U-Boot flashed with DFU support then
the user can go to step 2 below in order to update U-Boot.
Put pico board in USB download mode (refer to the document
http://www.wandboard.org/images/hobbit/hobbitboard-imx6ul-reva1.pdf
page 15).
https://www.nxp.com/files-static/32bit/doc/quick_start_guide/PICO-IMX6UL-QSG.pdf
Figure 6a at page 7).
Connect a USB to serial adapter between the host PC and pico.

View File

@ -51,24 +51,22 @@ int board_early_init_f(void)
return 0;
}
int dram_init(void)
int board_phys_sdram_size(phys_size_t *size)
{
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
if (ddr_size == 0x4) {
*size = 0x100000000;
} else if (ddr_size == 0x3) {
*size = 0xc0000000;
} else if (ddr_size == 0x2) {
*size = 0x80000000;
} else if (ddr_size == 0x1) {
*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 -1;
}
return 0;
}

View File

@ -14,17 +14,6 @@
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)
{

View File

@ -74,7 +74,6 @@ CONFIG_PHYLIB=y
CONFIG_PHY_MICREL=y
CONFIG_PHY_MICREL_KSZ90X1=y
CONFIG_DM_ETH=y
CONFIG_DM_MDIO=y
CONFIG_FEC_MXC=y
CONFIG_MII=y
CONFIG_PINCTRL=y

View File

@ -10,6 +10,7 @@ CONFIG_ENV_OFFSET_REDUND=0xE0000
CONFIG_IMX_HAB=y
# CONFIG_CMD_DEKBLOB is not set
# CONFIG_CMD_NANDBCB is not set
CONFIG_DEFAULT_DEVICE_TREE="imx6dl-aristainetos2_4"
CONFIG_FIT=y
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/aristainetos/aristainetos2.cfg"
CONFIG_BOOTDELAY=3
@ -53,7 +54,6 @@ CONFIG_CMD_FS_GENERIC=y
CONFIG_CMD_MTDPARTS=y
CONFIG_CMD_UBI=y
CONFIG_OF_CONTROL=y
CONFIG_DEFAULT_DEVICE_TREE="imx6dl-aristainetos2_4"
CONFIG_OF_LIST="imx6dl-aristainetos2_4 imx6dl-aristainetos2_7"
CONFIG_DTB_RESELECT=y
CONFIG_MULTI_DTB_FIT=y
@ -61,6 +61,7 @@ CONFIG_ENV_IS_IN_SPI_FLASH=y
CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_GPIO_HOG=y
CONFIG_DM_GPIO_LOOKUP_LABEL=y
CONFIG_DM_PCA953X=y
CONFIG_DM_I2C=y
CONFIG_LED=y

View File

@ -9,6 +9,7 @@ CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_OFFSET_REDUND=0xE0000
CONFIG_IMX_HAB=y
# CONFIG_CMD_DEKBLOB is not set
CONFIG_DEFAULT_DEVICE_TREE="imx6dl-aristainetos2b_4"
CONFIG_FIT=y
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/aristainetos/aristainetos2.cfg"
CONFIG_BOOTDELAY=3
@ -51,7 +52,6 @@ CONFIG_CMD_FS_GENERIC=y
CONFIG_CMD_MTDPARTS=y
CONFIG_CMD_UBI=y
CONFIG_OF_CONTROL=y
CONFIG_DEFAULT_DEVICE_TREE="imx6dl-aristainetos2b_4"
CONFIG_OF_LIST="imx6dl-aristainetos2b_4 imx6dl-aristainetos2b_7"
CONFIG_DTB_RESELECT=y
CONFIG_MULTI_DTB_FIT=y
@ -59,6 +59,7 @@ CONFIG_ENV_IS_IN_SPI_FLASH=y
CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_GPIO_HOG=y
CONFIG_DM_GPIO_LOOKUP_LABEL=y
CONFIG_DM_PCA953X=y
CONFIG_DM_I2C=y
CONFIG_LED=y

View File

@ -9,6 +9,7 @@ CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_OFFSET_REDUND=0xE0000
CONFIG_IMX_HAB=y
# CONFIG_CMD_DEKBLOB is not set
CONFIG_DEFAULT_DEVICE_TREE="imx6dl-aristainetos2b_csl_4"
CONFIG_FIT=y
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/aristainetos/aristainetos2.cfg"
CONFIG_BOOTDELAY=3
@ -51,7 +52,6 @@ CONFIG_CMD_FS_GENERIC=y
CONFIG_CMD_MTDPARTS=y
CONFIG_CMD_UBI=y
CONFIG_OF_CONTROL=y
CONFIG_DEFAULT_DEVICE_TREE="imx6dl-aristainetos2b_csl_4"
CONFIG_OF_LIST="imx6dl-aristainetos2b_csl_4 imx6dl-aristainetos2b_csl_7"
CONFIG_DTB_RESELECT=y
CONFIG_MULTI_DTB_FIT=y
@ -59,6 +59,7 @@ CONFIG_ENV_IS_IN_SPI_FLASH=y
CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_GPIO_HOG=y
CONFIG_DM_GPIO_LOOKUP_LABEL=y
CONFIG_DM_PCA953X=y
CONFIG_DM_I2C=y
CONFIG_LED=y

View File

@ -9,6 +9,7 @@ CONFIG_NR_DRAM_BANKS=1
CONFIG_ENV_OFFSET_REDUND=0xE0000
CONFIG_IMX_HAB=y
# CONFIG_CMD_DEKBLOB is not set
CONFIG_DEFAULT_DEVICE_TREE="imx6dl-aristainetos2c_4"
CONFIG_FIT=y
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/aristainetos/aristainetos2.cfg"
CONFIG_BOOTDELAY=3
@ -51,7 +52,6 @@ CONFIG_CMD_FS_GENERIC=y
CONFIG_CMD_MTDPARTS=y
CONFIG_CMD_UBI=y
CONFIG_OF_CONTROL=y
CONFIG_DEFAULT_DEVICE_TREE="imx6dl-aristainetos2c_4"
CONFIG_OF_LIST="imx6dl-aristainetos2c_4 imx6dl-aristainetos2c_7"
CONFIG_DTB_RESELECT=y
CONFIG_MULTI_DTB_FIT=y
@ -62,6 +62,7 @@ CONFIG_APBH_DMA=y
CONFIG_APBH_DMA_BURST=y
CONFIG_APBH_DMA_BURST8=y
CONFIG_GPIO_HOG=y
CONFIG_DM_GPIO_LOOKUP_LABEL=y
CONFIG_DM_PCA953X=y
CONFIG_DM_I2C=y
CONFIG_LED=y

View File

@ -73,7 +73,6 @@ CONFIG_PHYLIB=y
CONFIG_PHY_MICREL=y
CONFIG_PHY_MICREL_KSZ8XXX=y
CONFIG_DM_ETH=y
CONFIG_DM_MDIO=y
CONFIG_FEC_MXC=y
CONFIG_MII=y
CONFIG_PINCTRL=y

View File

@ -77,7 +77,6 @@ CONFIG_PHYLIB=y
CONFIG_PHY_MICREL=y
CONFIG_PHY_MICREL_KSZ90X1=y
CONFIG_DM_ETH=y
CONFIG_DM_MDIO=y
CONFIG_FEC_MXC=y
CONFIG_MII=y
CONFIG_PINCTRL=y

View File

@ -36,6 +36,7 @@ CONFIG_SPL_MMC_TINY=y
CONFIG_SPL_DM_SPI_FLASH=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_SPI_LOAD=y
CONFIG_SPL_YMODEM_SUPPORT=y
CONFIG_HUSH_PARSER=y
CONFIG_CMD_SPL=y
CONFIG_CMD_ASKENV=y

View File

@ -16,7 +16,6 @@ CONFIG_TARGET_IMX8MP_EVK=y
CONFIG_SPL_MMC_SUPPORT=y
CONFIG_SPL_SERIAL_SUPPORT=y
CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
CONFIG_NR_DRAM_BANKS=2
CONFIG_SPL=y
CONFIG_SPL_IMX_ROMAPI_LOADADDR=0x48000000
CONFIG_FIT=y

View File

@ -39,6 +39,7 @@ CONFIG_SYS_MEMTEST_END=0x20000000
CONFIG_CMD_CACHE=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
# CONFIG_NET is not set
CONFIG_DM=y
# CONFIG_MMC is not set
CONFIG_FSL_USDHC=y
CONFIG_USB=y
@ -47,4 +48,5 @@ CONFIG_USB_GADGET_MANUFACTURER="FSL"
CONFIG_USB_GADGET_VENDOR_NUM=0x0525
CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5
CONFIG_CI_UDC=y
CONFIG_REGEX=y
CONFIG_OF_LIBFDT=y
# CONFIG_EFI_LOADER is not set

View File

@ -76,7 +76,6 @@ CONFIG_SPI_FLASH_STMICRO=y
CONFIG_PHYLIB=y
CONFIG_PHY_ATHEROS=y
CONFIG_DM_ETH=y
CONFIG_DM_MDIO=y
CONFIG_FEC_MXC=y
CONFIG_RGMII=y
CONFIG_MII=y

View File

@ -83,7 +83,6 @@ CONFIG_SPI_FLASH_STMICRO=y
CONFIG_PHYLIB=y
CONFIG_PHY_ATHEROS=y
CONFIG_DM_ETH=y
CONFIG_DM_MDIO=y
CONFIG_FEC_MXC=y
CONFIG_RGMII=y
CONFIG_MII=y

View File

@ -7,9 +7,12 @@ CONFIG_SPL_LIBGENERIC_SUPPORT=y
CONFIG_ENV_SIZE=0x4000
CONFIG_ENV_OFFSET=0x100000
CONFIG_ENV_SECT_SIZE=0x10000
CONFIG_SYS_SPI_U_BOOT_OFFS=0x10000
CONFIG_SYS_SPI_U_BOOT_OFFS=0x40000
CONFIG_MX6_OCRAM_256KB=y
CONFIG_TARGET_PCM058=y
CONFIG_SPL_TEXT_BASE=0x00908000
CONFIG_DM_GPIO=y
CONFIG_SPL_DM_SPI=y
CONFIG_SPL_MMC_SUPPORT=y
CONFIG_SPL_SERIAL_SUPPORT=y
CONFIG_NR_DRAM_BANKS=1
@ -26,10 +29,11 @@ CONFIG_BOOTDELAY=3
# CONFIG_USE_BOOTCOMMAND is not set
CONFIG_DISPLAY_BOARDINFO_LATE=y
CONFIG_BOUNCE_BUFFER=y
CONFIG_BOARD_EARLY_INIT_F=y
CONFIG_SPL_BOARD_INIT=y
CONFIG_SPL_SEPARATE_BSS=y
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x18a
CONFIG_SPL_DMA=y
CONFIG_SPL_FS_EXT4=y
CONFIG_SPL_I2C_SUPPORT=y
CONFIG_SPL_SPI_LOAD=y
CONFIG_SPL_WATCHDOG_SUPPORT=y
CONFIG_SPL_YMODEM_SUPPORT=y
@ -38,33 +42,51 @@ CONFIG_CMD_GPIO=y
CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
CONFIG_CMD_NAND_TRIMFFS=y
CONFIG_CMD_SF=y
# CONFIG_CMD_PINMUX is not set
CONFIG_CMD_CACHE=y
CONFIG_CMD_EXT4_WRITE=y
CONFIG_CMD_MTDPARTS=y
CONFIG_MTDIDS_DEFAULT="nand0=nand"
CONFIG_MTDPARTS_DEFAULT="mtdparts=nand:16m(uboot),1m(env),-(rootfs)"
CONFIG_MTDIDS_DEFAULT="nand0=gpmi-nand"
CONFIG_MTDPARTS_DEFAULT="mtdparts=gpmi-nand:-(rootfs)"
CONFIG_CMD_UBI=y
# CONFIG_SPL_PARTITION_UUIDS is not set
CONFIG_SPL_OF_CONTROL=y
CONFIG_DEFAULT_DEVICE_TREE="imx6q-phytec-mira-rdk-nand"
CONFIG_ENV_IS_IN_SPI_FLASH=y
CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_DM=y
CONFIG_SPL_DM=y
CONFIG_DM_I2C=y
CONFIG_SYS_I2C_MXC=y
CONFIG_DM_MMC=y
CONFIG_FSL_USDHC=y
CONFIG_MTD=y
CONFIG_DM_MTD=y
CONFIG_MTD_RAW_NAND=y
CONFIG_SYS_NAND_USE_FLASH_BBT=y
CONFIG_NAND_MXS=y
CONFIG_SPI_FLASH=y
CONFIG_NAND_MXS_DT=y
CONFIG_DM_SPI_FLASH=y
CONFIG_SF_DEFAULT_MODE=0
CONFIG_SF_DEFAULT_SPEED=20000000
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_PHYLIB=y
CONFIG_PHY_MICREL=y
CONFIG_PHY_MICREL_KSZ90X1=y
CONFIG_DM_ETH=y
CONFIG_DM_MDIO=y
CONFIG_FEC_MXC=y
CONFIG_MII=y
CONFIG_PINCTRL=y
CONFIG_PINCONF=y
# CONFIG_PINCONF_RECURSIVE is not set
CONFIG_SPL_PINCTRL=y
CONFIG_SPL_PINCONF=y
# CONFIG_SPL_PINCONF_RECURSIVE is not set
CONFIG_PINCTRL_IMX6=y
CONFIG_DM_SERIAL=y
CONFIG_MXC_UART=y
CONFIG_SPI=y
CONFIG_DM_SPI=y
CONFIG_MXC_SPI=y
CONFIG_DM_THERMAL=y
CONFIG_OF_LIBFDT=y
# CONFIG_SPL_WDT is not set

View File

@ -95,6 +95,9 @@ static const char *imx8mm_enet_phy_sels[] = {"clock-osc-24m", "sys_pll2_50m", "s
static const char *imx8mm_nand_usdhc_sels[] = {"clock-osc-24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_200m",
"sys_pll1_133m", "sys_pll3_out", "sys_pll2_250m", "audio_pll1_out", };
static const char *imx8mm_usb_bus_sels[] = {"clock-osc-24m", "sys_pll2_500m", "sys_pll1_800m", "sys_pll2_100m",
"sys_pll2_200m", "clk_ext2", "clk_ext4", "audio_pll2_out", };
static const char *imx8mm_usdhc1_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
"sys_pll3_out", "sys_pll1_266m", "audio_pll2_out", "sys_pll1_100m", };
@ -119,6 +122,15 @@ static const char *imx8mm_wdog_sels[] = {"clock-osc-24m", "sys_pll1_133m", "sys_
static const char *imx8mm_usdhc3_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
"sys_pll3_out", "sys_pll1_266m", "audio_pll2_clk", "sys_pll1_100m", };
static const char *imx8mm_qspi_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll2_333m", "sys_pll2_500m",
"audio_pll2_out", "sys_pll1_266m", "sys_pll3_out", "sys_pll1_100m", };
static const char *imx8mm_usb_core_sels[] = {"clock-osc-24m", "sys_pll1_100m", "sys_pll1_40m", "sys_pll2_100m",
"sys_pll2_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", };
static const char *imx8mm_usb_phy_sels[] = {"clock-osc-24m", "sys_pll1_100m", "sys_pll1_40m", "sys_pll2_100m",
"sys_pll2_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", };
static ulong imx8mm_clk_get_rate(struct clk *clk)
{
struct clk *c;
@ -191,7 +203,10 @@ static int imx8mm_clk_set_parent(struct clk *clk, struct clk *parent)
if (ret)
return ret;
return clk_set_parent(c, cp);
ret = clk_set_parent(c, cp);
c->dev->parent = cp->dev;
return ret;
}
static struct clk_ops imx8mm_clk_ops = {
@ -349,6 +364,8 @@ static int imx8mm_clk_probe(struct udevice *dev)
imx8m_clk_composite_critical("nand_usdhc_bus",
imx8mm_nand_usdhc_sels,
base + 0x8900));
clk_dm(IMX8MM_CLK_USB_BUS,
imx8m_clk_composite("usb_bus", imx8mm_usb_bus_sels, base + 0x8b80));
/* IP */
clk_dm(IMX8MM_CLK_USDHC1,
@ -370,6 +387,12 @@ static int imx8mm_clk_probe(struct udevice *dev)
clk_dm(IMX8MM_CLK_USDHC3,
imx8m_clk_composite("usdhc3", imx8mm_usdhc3_sels,
base + 0xbc80));
clk_dm(IMX8MM_CLK_QSPI,
imx8m_clk_composite("qspi", imx8mm_qspi_sels, base + 0xab80));
clk_dm(IMX8MM_CLK_USB_CORE_REF,
imx8m_clk_composite("usb_core_ref", imx8mm_usb_core_sels, base + 0xb100));
clk_dm(IMX8MM_CLK_USB_PHY_REF,
imx8m_clk_composite("usb_phy_ref", imx8mm_usb_phy_sels, base + 0xb180));
clk_dm(IMX8MM_CLK_I2C1_ROOT,
imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0));
@ -393,6 +416,10 @@ static int imx8mm_clk_probe(struct udevice *dev)
imx_clk_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0));
clk_dm(IMX8MM_CLK_USDHC3_ROOT,
imx_clk_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0));
clk_dm(IMX8MM_CLK_QSPI_ROOT,
imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0));
clk_dm(IMX8MM_CLK_USB1_CTRL_ROOT,
imx_clk_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0));
/* clks not needed in SPL stage */
#ifndef CONFIG_SPL_BUILD
@ -410,40 +437,6 @@ static int imx8mm_clk_probe(struct udevice *dev)
base + 0x40a0, 0));
#endif
#ifdef CONFIG_SPL_BUILD
struct clk *clkp, *clkp1;
clk_get_by_id(IMX8MM_CLK_WDOG1_ROOT, &clkp);
clk_enable(clkp);
clk_get_by_id(IMX8MM_CLK_WDOG2_ROOT, &clkp);
clk_enable(clkp);
clk_get_by_id(IMX8MM_CLK_WDOG3_ROOT, &clkp);
clk_enable(clkp);
/* Configure SYS_PLL3 to 750MHz */
clk_get_by_id(IMX8MM_SYS_PLL3, &clkp);
clk_set_rate(clkp, 750000000UL);
clk_enable(clkp);
/* Configure ARM to sys_pll2_500m */
clk_get_by_id(IMX8MM_CLK_A53_SRC, &clkp);
clk_get_by_id(IMX8MM_SYS_PLL2_OUT, &clkp1);
clk_enable(clkp1);
clk_get_by_id(IMX8MM_SYS_PLL2_500M, &clkp1);
clk_set_parent(clkp, clkp1);
/* Configure ARM PLL to 1.2GHz */
clk_get_by_id(IMX8MM_ARM_PLL, &clkp1);
clk_set_rate(clkp1, 1200000000UL);
clk_get_by_id(IMX8MM_ARM_PLL_OUT, &clkp1);
clk_enable(clkp1);
clk_set_parent(clkp, clkp1);
/* Configure DIV to 1.2GHz */
clk_get_by_id(IMX8MM_CLK_A53_DIV, &clkp1);
clk_set_rate(clkp1, 1200000000UL);
#endif
return 0;
}

View File

@ -81,9 +81,24 @@ static const char *imx8mn_ahb_sels[] = {"clock-osc-24m", "sys_pll1_133m", "sys_p
static const char *imx8mn_enet_axi_sels[] = {"clock-osc-24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_250m",
"sys_pll2_200m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", };
#ifndef CONFIG_SPL_BUILD
static const char *imx8mn_enet_ref_sels[] = {"clock-osc-24m", "sys_pll2_125m", "sys_pll2_50m", "sys_pll2_100m",
"sys_pll1_160m", "audio_pll1_out", "video_pll1_out", "clk_ext4", };
static const char *imx8mn_enet_timer_sels[] = {"clock-osc-24m", "sys_pll2_100m", "audio_pll1_out", "clk_ext1", "clk_ext2",
"clk_ext3", "clk_ext4", "video_pll1_out", };
static const char *imx8mn_enet_phy_sels[] = {"clock-osc-24m", "sys_pll2_50m", "sys_pll2_125m", "sys_pll2_200m",
"sys_pll2_500m", "video_pll1_out", "audio_pll2_out", };
#endif
static const char *imx8mn_nand_usdhc_sels[] = {"clock-osc-24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_200m",
"sys_pll1_133m", "sys_pll3_out", "sys_pll2_250m", "audio_pll1_out", };
static const char * const imx8mn_usb_bus_sels[] = {"clock-osc-24m", "sys_pll2_500m", "sys_pll1_800m",
"sys_pll2_100m", "sys_pll2_200m", "clk_ext2",
"clk_ext4", "audio_pll2_out", };
static const char *imx8mn_usdhc1_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
"sys_pll3_out", "sys_pll1_266m", "audio_pll2_out", "sys_pll1_100m", };
@ -108,6 +123,17 @@ static const char *imx8mn_wdog_sels[] = {"clock-osc-24m", "sys_pll1_133m", "sys_
static const char *imx8mn_usdhc3_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m",
"sys_pll3_out", "sys_pll1_266m", "audio_pll2_clk", "sys_pll1_100m", };
static const char *imx8mn_qspi_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll2_333m", "sys_pll2_500m",
"audio_pll2_out", "sys_pll1_266m", "sys_pll3_out", "sys_pll1_100m", };
static const char * const imx8mn_usb_core_sels[] = {"clock-osc-24m", "sys_pll1_100m", "sys_pll1_40m",
"sys_pll2_100m", "sys_pll2_200m", "clk_ext2",
"clk_ext3", "audio_pll2_out", };
static const char * const imx8mn_usb_phy_sels[] = {"clock-osc-24m", "sys_pll1_100m", "sys_pll1_40m",
"sys_pll2_100m", "sys_pll2_200m", "clk_ext2",
"clk_ext3", "audio_pll2_out", };
static ulong imx8mn_clk_get_rate(struct clk *clk)
{
struct clk *c;
@ -165,11 +191,33 @@ static int imx8mn_clk_enable(struct clk *clk)
return __imx8mn_clk_enable(clk, 1);
}
static int imx8mn_clk_set_parent(struct clk *clk, struct clk *parent)
{
struct clk *c, *cp;
int ret;
debug("%s(#%lu), parent: %lu\n", __func__, clk->id, parent->id);
ret = clk_get_by_id(clk->id, &c);
if (ret)
return ret;
ret = clk_get_by_id(parent->id, &cp);
if (ret)
return ret;
ret = clk_set_parent(c, cp);
c->dev->parent = cp->dev;
return ret;
}
static struct clk_ops imx8mn_clk_ops = {
.set_rate = imx8mn_clk_set_rate,
.get_rate = imx8mn_clk_get_rate,
.enable = imx8mn_clk_enable,
.disable = imx8mn_clk_disable,
.set_parent = imx8mn_clk_set_parent,
};
static int imx8mn_clk_probe(struct udevice *dev)
@ -319,6 +367,8 @@ static int imx8mn_clk_probe(struct udevice *dev)
imx8m_clk_composite_critical("nand_usdhc_bus",
imx8mn_nand_usdhc_sels,
base + 0x8900));
clk_dm(IMX8MN_CLK_USB_BUS,
imx8m_clk_composite("usb_bus", imx8mn_usb_bus_sels, base + 0x8b80));
/* IP */
clk_dm(IMX8MN_CLK_USDHC1,
@ -340,6 +390,12 @@ static int imx8mn_clk_probe(struct udevice *dev)
clk_dm(IMX8MN_CLK_USDHC3,
imx8m_clk_composite("usdhc3", imx8mn_usdhc3_sels,
base + 0xbc80));
clk_dm(IMX8MN_CLK_QSPI,
imx8m_clk_composite("qspi", imx8mn_qspi_sels, base + 0xab80));
clk_dm(IMX8MN_CLK_USB_CORE_REF,
imx8m_clk_composite("usb_core_ref", imx8mn_usb_core_sels, base + 0xb100));
clk_dm(IMX8MN_CLK_USB_PHY_REF,
imx8m_clk_composite("usb_phy_ref", imx8mn_usb_phy_sels, base + 0xb180));
clk_dm(IMX8MN_CLK_I2C1_ROOT,
imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0));
@ -363,39 +419,25 @@ static int imx8mn_clk_probe(struct udevice *dev)
imx_clk_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0));
clk_dm(IMX8MN_CLK_USDHC3_ROOT,
imx_clk_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0));
clk_dm(IMX8MN_CLK_QSPI_ROOT,
imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0));
clk_dm(IMX8MN_CLK_USB1_CTRL_ROOT,
imx_clk_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0));
#ifdef CONFIG_SPL_BUILD
struct clk *clkp, *clkp1;
clk_get_by_id(IMX8MN_CLK_WDOG1_ROOT, &clkp);
clk_enable(clkp);
clk_get_by_id(IMX8MN_CLK_WDOG2_ROOT, &clkp);
clk_enable(clkp);
clk_get_by_id(IMX8MN_CLK_WDOG3_ROOT, &clkp);
clk_enable(clkp);
/* Configure SYS_PLL3 to 600MHz */
clk_get_by_id(IMX8MN_SYS_PLL3, &clkp);
clk_set_rate(clkp, 600000000UL);
clk_enable(clkp);
/* Configure ARM to sys_pll2_500m */
clk_get_by_id(IMX8MN_CLK_A53_SRC, &clkp);
clk_get_by_id(IMX8MN_SYS_PLL2_OUT, &clkp1);
clk_enable(clkp1);
clk_get_by_id(IMX8MN_SYS_PLL2_500M, &clkp1);
clk_set_parent(clkp, clkp1);
/* Configure ARM PLL to 1.2GHz */
clk_get_by_id(IMX8MN_ARM_PLL, &clkp1);
clk_set_rate(clkp1, 1200000000UL);
clk_get_by_id(IMX8MN_ARM_PLL_OUT, &clkp1);
clk_enable(clkp1);
clk_set_parent(clkp, clkp1);
/* Configure DIV to 1.2GHz */
clk_get_by_id(IMX8MN_CLK_A53_DIV, &clkp1);
clk_set_rate(clkp1, 1200000000UL);
/* clks not needed in SPL stage */
#ifndef CONFIG_SPL_BUILD
clk_dm(IMX8MN_CLK_ENET_REF,
imx8m_clk_composite("enet_ref", imx8mn_enet_ref_sels,
base + 0xa980));
clk_dm(IMX8MN_CLK_ENET_TIMER,
imx8m_clk_composite("enet_timer", imx8mn_enet_timer_sels,
base + 0xaa00));
clk_dm(IMX8MN_CLK_ENET_PHY_REF,
imx8m_clk_composite("enet_phy", imx8mn_enet_phy_sels,
base + 0xaa80));
clk_dm(IMX8MN_CLK_ENET1_ROOT,
imx_clk_gate4("enet1_root_clk", "enet_axi",
base + 0x40a0, 0));
#endif
return 0;

View File

@ -80,6 +80,10 @@ static const char *imx8mp_main_axi_sels[] = {"clock-osc-24m", "sys_pll2_333m", "
"sys_pll2_250m", "sys_pll2_1000m", "audio_pll1_out",
"video_pll1_out", "sys_pll1_100m",};
static const char *imx8mp_enet_axi_sels[] = {"clock-osc-24m", "sys_pll1_266m", "sys_pll1_800m",
"sys_pll2_250m", "sys_pll2_200m", "audio_pll1_out",
"video_pll1_out", "sys_pll3_out", };
static const char *imx8mp_nand_usdhc_sels[] = {"clock-osc-24m", "sys_pll1_266m", "sys_pll1_800m",
"sys_pll2_200m", "sys_pll1_133m", "sys_pll3_out",
"sys_pll2_250m", "audio_pll1_out", };
@ -160,10 +164,26 @@ static const char *imx8mp_wdog_sels[] = {"clock-osc-24m", "sys_pll1_133m", "sys_
"vpu_pll_out", "sys_pll2_125m", "sys_pll3_out",
"sys_pll1_80m", "sys_pll2_166m" };
static const char *imx8mp_qspi_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll2_333m",
"sys_pll2_500m", "audio_pll2_out", "sys_pll1_266m",
"sys_pll3_out", "sys_pll1_100m", };
static const char *imx8mp_usdhc3_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll1_800m",
"sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m",
"audio_pll2_out", "sys_pll1_100m", };
static const char *imx8mp_enet_ref_sels[] = {"clock-osc-24m", "sys_pll2_125m", "sys_pll2_50m",
"sys_pll2_100m", "sys_pll1_160m", "audio_pll1_out",
"video_pll1_out", "clk_ext4", };
static const char *imx8mp_enet_timer_sels[] = {"clock-osc-24m", "sys_pll2_100m", "audio_pll1_out",
"clk_ext1", "clk_ext2", "clk_ext3",
"clk_ext4", "video_pll1_out", };
static const char *imx8mp_enet_phy_ref_sels[] = {"clock-osc-24m", "sys_pll2_50m", "sys_pll2_125m",
"sys_pll2_200m", "sys_pll2_500m", "audio_pll1_out",
"video_pll1_out", "audio_pll2_out", };
static const char *imx8mp_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", };
@ -224,11 +244,34 @@ static int imx8mp_clk_enable(struct clk *clk)
return __imx8mp_clk_enable(clk, 1);
}
static int imx8mp_clk_set_parent(struct clk *clk, struct clk *parent)
{
struct clk *c, *cp;
int ret;
debug("%s(#%lu), parent: %lu\n", __func__, clk->id, parent->id);
ret = clk_get_by_id(clk->id, &c);
if (ret)
return ret;
ret = clk_get_by_id(parent->id, &cp);
if (ret)
return ret;
ret = clk_set_parent(c, cp);
c->dev->parent = cp->dev;
return ret;
}
static struct clk_ops imx8mp_clk_ops = {
.set_rate = imx8mp_clk_set_rate,
.get_rate = imx8mp_clk_get_rate,
.enable = imx8mp_clk_enable,
.disable = imx8mp_clk_disable,
.set_parent = imx8mp_clk_set_parent,
};
static int imx8mp_clk_probe(struct udevice *dev)
@ -290,6 +333,7 @@ static int imx8mp_clk_probe(struct udevice *dev)
clk_dm(IMX8MP_CLK_A53_DIV, imx_clk_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3));
clk_dm(IMX8MP_CLK_MAIN_AXI, imx8m_clk_composite_critical("main_axi", imx8mp_main_axi_sels, base + 0x8800));
clk_dm(IMX8MP_CLK_ENET_AXI, imx8m_clk_composite_critical("enet_axi", imx8mp_enet_axi_sels, base + 0x8880));
clk_dm(IMX8MP_CLK_NAND_USDHC_BUS, imx8m_clk_composite_critical("nand_usdhc_bus", imx8mp_nand_usdhc_sels, base + 0x8900));
clk_dm(IMX8MP_CLK_NOC, imx8m_clk_composite_critical("noc", imx8mp_noc_sels, base + 0x8d00));
clk_dm(IMX8MP_CLK_NOC_IO, imx8m_clk_composite_critical("noc_io", imx8mp_noc_io_sels, base + 0x8d80));
@ -302,6 +346,10 @@ static int imx8mp_clk_probe(struct udevice *dev)
clk_dm(IMX8MP_CLK_DRAM_APB, imx8m_clk_composite_critical("dram_apb", imx8mp_dram_apb_sels, base + 0xa080));
clk_dm(IMX8MP_CLK_I2C5, imx8m_clk_composite("i2c5", imx8mp_i2c5_sels, base + 0xa480));
clk_dm(IMX8MP_CLK_I2C6, imx8m_clk_composite("i2c6", imx8mp_i2c6_sels, base + 0xa500));
clk_dm(IMX8MP_CLK_ENET_REF, imx8m_clk_composite("enet_ref", imx8mp_enet_ref_sels, base + 0xa980));
clk_dm(IMX8MP_CLK_ENET_TIMER, imx8m_clk_composite("enet_timer", imx8mp_enet_timer_sels, base + 0xaa00));
clk_dm(IMX8MP_CLK_ENET_PHY_REF, imx8m_clk_composite("enet_phy_ref", imx8mp_enet_phy_ref_sels, base + 0xaa80));
clk_dm(IMX8MP_CLK_QSPI, imx8m_clk_composite("qspi", imx8mp_qspi_sels, base + 0xab80));
clk_dm(IMX8MP_CLK_USDHC1, imx8m_clk_composite("usdhc1", imx8mp_usdhc1_sels, base + 0xac00));
clk_dm(IMX8MP_CLK_USDHC2, imx8m_clk_composite("usdhc2", imx8mp_usdhc2_sels, base + 0xac80));
clk_dm(IMX8MP_CLK_I2C1, imx8m_clk_composite("i2c1", imx8mp_i2c1_sels, base + 0xad00));
@ -322,6 +370,8 @@ static int imx8mp_clk_probe(struct udevice *dev)
clk_dm(IMX8MP_CLK_DRAM_CORE, imx_clk_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mp_dram_core_sels, ARRAY_SIZE(imx8mp_dram_core_sels), CLK_IS_CRITICAL));
clk_dm(IMX8MP_CLK_DRAM1_ROOT, imx_clk_gate4_flags("dram1_root_clk", "dram_core_clk", base + 0x4050, 0, CLK_IS_CRITICAL));
clk_dm(IMX8MP_CLK_ENET1_ROOT, imx_clk_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0));
clk_dm(IMX8MP_CLK_GPIO1_ROOT, imx_clk_gate4("gpio1_root_clk", "ipg_root", base + 0x40b0, 0));
clk_dm(IMX8MP_CLK_GPIO2_ROOT, imx_clk_gate4("gpio2_root_clk", "ipg_root", base + 0x40c0, 0));
clk_dm(IMX8MP_CLK_GPIO3_ROOT, imx_clk_gate4("gpio3_root_clk", "ipg_root", base + 0x40d0, 0));
@ -331,8 +381,10 @@ static int imx8mp_clk_probe(struct udevice *dev)
clk_dm(IMX8MP_CLK_I2C2_ROOT, imx_clk_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0));
clk_dm(IMX8MP_CLK_I2C3_ROOT, imx_clk_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0));
clk_dm(IMX8MP_CLK_I2C4_ROOT, imx_clk_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0));
clk_dm(IMX8MP_CLK_QSPI_ROOT, imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0));
clk_dm(IMX8MP_CLK_I2C5_ROOT, imx_clk_gate2("i2c5_root_clk", "i2c5", base + 0x4330, 0));
clk_dm(IMX8MP_CLK_I2C6_ROOT, imx_clk_gate2("i2c6_root_clk", "i2c6", base + 0x4340, 0));
clk_dm(IMX8MP_CLK_SIM_ENET_ROOT, imx_clk_gate4("sim_enet_root_clk", "enet_axi", base + 0x4400, 0));
clk_dm(IMX8MP_CLK_UART1_ROOT, imx_clk_gate4("uart1_root_clk", "uart1", base + 0x4490, 0));
clk_dm(IMX8MP_CLK_UART2_ROOT, imx_clk_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0));
clk_dm(IMX8MP_CLK_UART3_ROOT, imx_clk_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0));

View File

@ -29,4 +29,11 @@ config SAVED_DRAM_TIMING_BASE
info into memory for low power use. OCRAM_S is used for this
purpose on i.MX8MM.
default 0x180000
config IMX8M_DRAM_INLINE_ECC
bool "imx8mp inline ECC"
depends on IMX8MP && IMX8M_LPDDR4
help
Select this config if you want to use inline ecc feature for
imx8mp-evk board.
endmenu

View File

@ -21,6 +21,76 @@ void ddr_cfg_umctl2(struct dram_cfg_param *ddrc_cfg, int num)
}
}
#ifdef CONFIG_IMX8M_DRAM_INLINE_ECC
void ddrc_inline_ecc_scrub(unsigned int start_address,
unsigned int range_address)
{
unsigned int tmp;
/* Step1: Enable quasi-dynamic programming */
reg32_write(DDRC_SWCTL(0), 0x00000000);
/* Step2: Set ECCCFG1.ecc_parity_region_lock to 1 */
reg32setbit(DDRC_ECCCFG1(0), 0x4);
/* Step3: Block the AXI ports from taking the transaction */
reg32_write(DDRC_PCTRL_0(0), 0x0);
/* Step4: Set scrub start address */
reg32_write(DDRC_SBRSTART0(0), start_address);
/* Step5: Set scrub range address */
reg32_write(DDRC_SBRRANGE0(0), range_address);
/* Step6: Set scrub_mode to write */
reg32_write(DDRC_SBRCTL(0), 0x00000014);
/* Step7: Set the desired pattern through SBRWDATA0 registers */
reg32_write(DDRC_SBRWDATA0(0), 0x55aa55aa);
/* Step8: Enable the SBR by programming SBRCTL.scrub_en=1 */
reg32setbit(DDRC_SBRCTL(0), 0x0);
/* Step9: Poll SBRSTAT.scrub_done=1 */
tmp = reg32_read(DDRC_SBRSTAT(0));
while (tmp != 0x00000002)
tmp = reg32_read(DDRC_SBRSTAT(0)) & 0x2;
/* Step10: Poll SBRSTAT.scrub_busy=0 */
tmp = reg32_read(DDRC_SBRSTAT(0));
while (tmp != 0x0)
tmp = reg32_read(DDRC_SBRSTAT(0)) & 0x1;
/* Step11: Disable SBR by programming SBRCTL.scrub_en=0 */
clrbits_le32(DDRC_SBRCTL(0), 0x1);
/* Step12: Prepare for normal scrub operation(Read) and set scrub_interval*/
reg32_write(DDRC_SBRCTL(0), 0x100);
/* Step13: Enable the SBR by programming SBRCTL.scrub_en=1 */
reg32_write(DDRC_SBRCTL(0), 0x101);
/* Step14: Enable AXI ports by programming */
reg32_write(DDRC_PCTRL_0(0), 0x1);
/* Step15: Disable quasi-dynamic programming */
reg32_write(DDRC_SWCTL(0), 0x00000001);
}
void ddrc_inline_ecc_scrub_end(unsigned int start_address,
unsigned int range_address)
{
/* Step1: Enable quasi-dynamic programming */
reg32_write(DDRC_SWCTL(0), 0x00000000);
/* Step2: Block the AXI ports from taking the transaction */
reg32_write(DDRC_PCTRL_0(0), 0x0);
/* Step3: Set scrub start address */
reg32_write(DDRC_SBRSTART0(0), start_address);
/* Step4: Set scrub range address */
reg32_write(DDRC_SBRRANGE0(0), range_address);
/* Step5: Disable SBR by programming SBRCTL.scrub_en=0 */
clrbits_le32(DDRC_SBRCTL(0), 0x1);
/* Step6: Prepare for normal scrub operation(Read) and set scrub_interval */
reg32_write(DDRC_SBRCTL(0), 0x100);
/* Step7: Enable the SBR by programming SBRCTL.scrub_en=1 */
reg32_write(DDRC_SBRCTL(0), 0x101);
/* Step8: Enable AXI ports by programming */
reg32_write(DDRC_PCTRL_0(0), 0x1);
/* Step9: Disable quasi-dynamic programming */
reg32_write(DDRC_SWCTL(0), 0x00000001);
}
#endif
void __weak board_dram_ecc_scrub(void)
{
}
int ddr_init(struct dram_timing_info *dram_timing)
{
unsigned int tmp, initial_drate, target_freq;
@ -74,7 +144,7 @@ int ddr_init(struct dram_timing_info *dram_timing)
/* if ddr type is LPDDR4, do it */
tmp = reg32_read(DDRC_MSTR(0));
if (tmp & (0x1 << 5))
if (tmp & (0x1 << 5) && !is_imx8mn())
reg32_write(DDRC_DDR_SS_GPR0, 0x01); /* LPDDR4 mode */
/* determine the initial boot frequency */
@ -120,6 +190,9 @@ int ddr_init(struct dram_timing_info *dram_timing)
/* Step15: Set SWCTL.sw_done to 0 */
reg32_write(DDRC_SWCTL(0), 0x00000000);
/* Apply rank-to-rank workaround */
update_umctl2_rank_space_setting(dram_timing->fsp_msg_num - 1);
/* Step16: Set DFIMISC.dfi_init_start to 1 */
setbits_le32(DDRC_DFIMISC(0), (0x1 << 5));
@ -163,12 +236,14 @@ int ddr_init(struct dram_timing_info *dram_timing)
/* Step26: Set back register in Step4 to the original values if desired */
reg32_write(DDRC_RFSHCTL3(0), 0x0000000);
/* enable selfref_en by default */
setbits_le32(DDRC_PWRCTL(0), 0x1 << 3);
setbits_le32(DDRC_PWRCTL(0), 0x1);
/* enable port 0 */
reg32_write(DDRC_PCTRL_0(0), 0x00000001);
debug("DDRINFO: ddrmix config done\n");
board_dram_ecc_scrub();
/* save the dram timing config into memory */
dram_config_save(dram_timing, CONFIG_SAVED_DRAM_TIMING_BASE);

View File

@ -8,6 +8,7 @@
#include <linux/kernel.h>
#include <asm/arch/ddr.h>
#include <asm/arch/lpddr4_define.h>
#include <asm/arch/sys_proto.h>
int ddr_cfg_phy(struct dram_timing_info *dram_timing)
{
@ -71,9 +72,15 @@ int ddr_cfg_phy(struct dram_timing_info *dram_timing)
/* Read the Message Block results */
dwc_ddrphy_apb_wr(0xd0000, 0x0);
ddrphy_init_read_msg_block(fsp_msg->fw_type);
if(fsp_msg->fw_type != FW_2D_IMAGE)
get_trained_CDD(i);
dwc_ddrphy_apb_wr(0xd0000, 0x1);
fsp_msg++;
}

View File

@ -11,6 +11,12 @@
#include <asm/arch/clock.h>
#include <asm/arch/ddr.h>
#include <asm/arch/lpddr4_define.h>
#include <asm/arch/sys_proto.h>
static unsigned int g_cdd_rr_max[4];
static unsigned int g_cdd_rw_max[4];
static unsigned int g_cdd_wr_max[4];
static unsigned int g_cdd_ww_max[4];
static inline void poll_pmu_message_ready(void)
{
@ -193,3 +199,161 @@ unsigned int lpddr4_mr_read(unsigned int mr_rank, unsigned int mr_addr)
return tmp;
}
unsigned int look_for_max(unsigned int data[],
unsigned int addr_start, unsigned int addr_end)
{
unsigned int i, imax = 0;
for (i = addr_start; i <= addr_end; i++) {
if (((data[i] >> 7) == 0) && (data[i] > imax))
imax = data[i];
}
return imax;
}
void get_trained_CDD(u32 fsp)
{
unsigned int i, ddr_type, tmp;
unsigned int cdd_cha[12], cdd_chb[12];
unsigned int cdd_cha_rr_max, cdd_cha_rw_max, cdd_cha_wr_max, cdd_cha_ww_max;
unsigned int cdd_chb_rr_max, cdd_chb_rw_max, cdd_chb_wr_max, cdd_chb_ww_max;
ddr_type = reg32_read(DDRC_MSTR(0)) & 0x3f;
if (ddr_type == 0x20) {
for (i = 0; i < 6; i++) {
tmp = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + (0x54013 + i) * 4);
cdd_cha[i * 2] = tmp & 0xff;
cdd_cha[i * 2 + 1] = (tmp >> 8) & 0xff;
}
for (i = 0; i < 7; i++) {
tmp = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + (0x5402c + i) * 4);
if (i == 0) {
cdd_cha[0] = (tmp >> 8) & 0xff;
} else if (i == 6) {
cdd_cha[11]=tmp & 0xff;
} else {
cdd_chb[ i * 2 - 1] = tmp & 0xff;
cdd_chb[i * 2] = (tmp >> 8) & 0xff;
}
}
cdd_cha_rr_max = look_for_max(cdd_cha, 0, 1);
cdd_cha_rw_max = look_for_max(cdd_cha, 2, 5);
cdd_cha_wr_max = look_for_max(cdd_cha, 6, 9);
cdd_cha_ww_max = look_for_max(cdd_cha, 10, 11);
cdd_chb_rr_max = look_for_max(cdd_chb, 0, 1);
cdd_chb_rw_max = look_for_max(cdd_chb, 2, 5);
cdd_chb_wr_max = look_for_max(cdd_chb, 6, 9);
cdd_chb_ww_max = look_for_max(cdd_chb, 10, 11);
g_cdd_rr_max[fsp] = cdd_cha_rr_max > cdd_chb_rr_max ? cdd_cha_rr_max : cdd_chb_rr_max;
g_cdd_rw_max[fsp] = cdd_cha_rw_max > cdd_chb_rw_max ? cdd_cha_rw_max : cdd_chb_rw_max;
g_cdd_wr_max[fsp] = cdd_cha_wr_max > cdd_chb_wr_max ? cdd_cha_wr_max : cdd_chb_wr_max;
g_cdd_ww_max[fsp] = cdd_cha_ww_max > cdd_chb_ww_max ? cdd_cha_ww_max : cdd_chb_ww_max;
} else {
unsigned int ddr4_cdd[64];
for( i = 0; i < 29; i++) {
tmp = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + (0x54012 + i) * 4);
ddr4_cdd[i * 2] = tmp & 0xff;
ddr4_cdd[i * 2 + 1] = (tmp >> 8) & 0xff;
}
g_cdd_rr_max[fsp] = look_for_max(ddr4_cdd, 1, 12);
g_cdd_ww_max[fsp] = look_for_max(ddr4_cdd, 13, 24);
g_cdd_rw_max[fsp] = look_for_max(ddr4_cdd, 25, 40);
g_cdd_wr_max[fsp] = look_for_max(ddr4_cdd, 41, 56);
}
}
void update_umctl2_rank_space_setting(unsigned int pstat_num)
{
unsigned int i,ddr_type;
unsigned int addr_slot, rdata, tmp, tmp_t;
unsigned int ddrc_w2r,ddrc_r2w,ddrc_wr_gap,ddrc_rd_gap;
ddr_type = reg32_read(DDRC_MSTR(0)) & 0x3f;
for (i = 0; i < pstat_num; i++) {
addr_slot = i ? (i + 1) * 0x1000 : 0;
if (ddr_type == 0x20) {
/* update r2w:[13:8], w2r:[5:0] */
rdata=reg32_read(DDRC_DRAMTMG2(0) + addr_slot);
ddrc_w2r = rdata & 0x3f;
if(is_imx8mp())
tmp = ddrc_w2r + (g_cdd_wr_max[i] >> 1);
else
tmp = ddrc_w2r + (g_cdd_wr_max[i] >> 1) + 1;
ddrc_w2r = (tmp > 0x3f) ? 0x3f : tmp;
ddrc_r2w = (rdata >> 8) & 0x3f;
if (is_imx8mp())
tmp = ddrc_r2w + (g_cdd_rw_max[i] >> 1);
else
tmp = ddrc_r2w + (g_cdd_rw_max[i] >> 1) + 1;
ddrc_r2w = (tmp > 0x3f) ? 0x3f : tmp;
tmp_t = (rdata & 0xffffc0c0) | (ddrc_r2w << 8) | ddrc_w2r;
reg32_write((DDRC_DRAMTMG2(0) + addr_slot), tmp_t);
} else {
/* update w2r:[5:0] */
rdata=reg32_read(DDRC_DRAMTMG9(0) + addr_slot);
ddrc_w2r = rdata & 0x3f;
if (is_imx8mp())
tmp = ddrc_w2r + (g_cdd_wr_max[i] >> 1);
else
tmp = ddrc_w2r + (g_cdd_wr_max[i] >> 1) + 1;
ddrc_w2r = (tmp > 0x3f) ? 0x3f : tmp;
tmp_t = (rdata & 0xffffffc0) | ddrc_w2r;
reg32_write((DDRC_DRAMTMG9(0) + addr_slot), tmp_t);
/* update r2w:[13:8] */
rdata = reg32_read(DDRC_DRAMTMG2(0) + addr_slot);
ddrc_r2w = (rdata >> 8) & 0x3f;
if(is_imx8mp())
tmp = ddrc_r2w + (g_cdd_rw_max[i] >> 1);
else
tmp = ddrc_r2w + (g_cdd_rw_max[i] >> 1) + 1;
ddrc_r2w = (tmp > 0x3f) ? 0x3f : tmp;
tmp_t = (rdata & 0xffffc0ff) | (ddrc_r2w << 8);
reg32_write((DDRC_DRAMTMG2(0) + addr_slot), tmp_t);
}
if (!is_imx8mq()) {
/* update rankctl: wr_gap:11:8; rd:gap:7:4; quasi-dymic, doc wrong(static) */
rdata = reg32_read(DDRC_RANKCTL(0) + addr_slot);
ddrc_wr_gap = (rdata >> 8) & 0xf;
if(is_imx8mp())
tmp = ddrc_wr_gap + (g_cdd_ww_max[i] >> 1);
else
tmp = ddrc_wr_gap + (g_cdd_ww_max[i] >> 1) + 1;
ddrc_wr_gap = (tmp > 0xf) ? 0xf : tmp;
ddrc_rd_gap = (rdata >> 4) & 0xf;
if (is_imx8mp())
tmp = ddrc_rd_gap + (g_cdd_rr_max[i] >> 1);
else
tmp = ddrc_rd_gap + (g_cdd_rr_max[i] >> 1) + 1;
ddrc_rd_gap = (tmp > 0xf) ? 0xf : tmp;
tmp_t = (rdata & 0xfffff00f) | (ddrc_wr_gap << 8) | (ddrc_rd_gap << 4);
reg32_write((DDRC_RANKCTL(0) + addr_slot), tmp_t);
}
}
if(is_imx8mq()) {
/* update rankctl: wr_gap:11:8; rd:gap:7:4; quasi-dymic, doc wrong(static) */
rdata = reg32_read(DDRC_RANKCTL(0));
ddrc_wr_gap = (rdata >> 8) & 0xf;
tmp = ddrc_wr_gap + (g_cdd_ww_max[0] >> 1) + 1;
ddrc_wr_gap = (tmp > 0xf) ? 0xf : tmp;
ddrc_rd_gap = (rdata >> 4) & 0xf;
tmp = ddrc_rd_gap + (g_cdd_rr_max[0] >> 1) + 1;
ddrc_rd_gap = (tmp > 0xf) ? 0xf : tmp;
tmp_t = (rdata & 0xfffff00f) | (ddrc_wr_gap << 8) | (ddrc_rd_gap << 4);
reg32_write(DDRC_RANKCTL(0), tmp_t);
}
}

View File

@ -295,46 +295,26 @@ static int mxc_gpio_probe(struct udevice *dev)
return 0;
}
static int mxc_gpio_bind(struct udevice *dev)
static int mxc_gpio_ofdata_to_platdata(struct udevice *dev)
{
struct mxc_gpio_plat *plat = dev->platdata;
fdt_addr_t addr;
/*
* If platdata already exsits, directly return.
* Actually only when DT is not supported, platdata
* is statically initialized in U_BOOT_DEVICES.Here
* will return.
*/
if (plat)
return 0;
struct mxc_gpio_plat *plat = dev_get_platdata(dev);
addr = devfdt_get_addr(dev);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
/*
* TODO:
* When every board is converted to driver model and DT is supported,
* this can be done by auto-alloc feature, but not using calloc
* to alloc memory for platdata.
*
* For example mxc_plat below uses platform data rather than device
* tree.
*
* NOTE: DO NOT COPY this code if you are using device tree.
*/
plat = calloc(1, sizeof(*plat));
if (!plat)
return -ENOMEM;
plat->regs = (struct gpio_regs *)addr;
plat->bank_index = dev->req_seq;
dev->platdata = plat;
return 0;
}
static int mxc_gpio_bind(struct udevice *dev)
{
return 0;
}
static const struct udevice_id mxc_gpio_ids[] = {
{ .compatible = "fsl,imx35-gpio" },
{ }
@ -345,6 +325,8 @@ U_BOOT_DRIVER(gpio_mxc) = {
.id = UCLASS_GPIO,
.ops = &gpio_mxc_ops,
.probe = mxc_gpio_probe,
.ofdata_to_platdata = mxc_gpio_ofdata_to_platdata,
.platdata_auto_alloc_size = sizeof(struct mxc_gpio_plat),
.priv_auto_alloc_size = sizeof(struct mxc_bank_info),
.of_match = mxc_gpio_ids,
.bind = mxc_gpio_bind,

View File

@ -9,6 +9,7 @@
#include <fuse.h>
#include <asm/arch/sci/sci.h>
#include <asm/arch/sys_proto.h>
#include <linux/arm-smccc.h>
DECLARE_GLOBAL_DATA_PTR;
@ -36,22 +37,24 @@ int fuse_read(u32 bank, u32 word, u32 *val)
int fuse_sense(u32 bank, u32 word, u32 *val)
{
unsigned long ret = 0, value = 0;
struct arm_smccc_res res;
if (bank != 0) {
printf("Invalid bank argument, ONLY bank 0 is supported\n");
return -EINVAL;
}
ret = call_imx_sip_ret2(FSL_SIP_OTP_READ, (unsigned long)word, &value,
0, 0);
*val = (u32)value;
arm_smccc_smc(FSL_SIP_OTP_READ, (unsigned long)word, 0, 0,
0, 0, 0, 0, &res);
*val = (u32)res.a1;
return ret;
return res.a0;
}
int fuse_prog(u32 bank, u32 word, u32 val)
{
struct arm_smccc_res res;
if (bank != 0) {
printf("Invalid bank argument, ONLY bank 0 is supported\n");
return -EINVAL;
@ -78,8 +81,10 @@ int fuse_prog(u32 bank, u32 word, u32 val)
}
}
return call_imx_sip(FSL_SIP_OTP_WRITE, (unsigned long)word,
(unsigned long)val, 0, 0);
arm_smccc_smc(FSL_SIP_OTP_WRITE, (unsigned long)word,
(unsigned long)val, 0, 0, 0, 0, 0, &res);
return res.a0;
}
int fuse_override(u32 bank, u32 word, u32 val)

View File

@ -374,6 +374,31 @@ void sc_misc_boot_status(sc_ipc_t ipc, sc_misc_boot_status_t status)
__func__, status, RPC_R8(&msg));
}
int sc_misc_get_boot_container(sc_ipc_t ipc, u8 *idx)
{
struct udevice *dev = gd->arch.scu_dev;
int size = sizeof(struct sc_rpc_msg_s);
struct sc_rpc_msg_s msg;
int ret;
if (!dev)
hang();
RPC_VER(&msg) = SC_RPC_VERSION;
RPC_SIZE(&msg) = 1U;
RPC_SVC(&msg) = (u8)SC_RPC_SVC_MISC;
RPC_FUNC(&msg) = (u8)MISC_FUNC_GET_BOOT_CONTAINER;
ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
if (ret < 0)
return ret;
if (idx)
*idx = (u8)RPC_U8(&msg, 0U);
return 0;
}
void sc_misc_build_info(sc_ipc_t ipc, u32 *build, u32 *commit)
{
struct udevice *dev = gd->arch.scu_dev;

View File

@ -10,7 +10,7 @@
#include "pinctrl-imx.h"
static struct imx_pinctrl_soc_info imx5_pinctrl_soc_info;
static struct imx_pinctrl_soc_info imx5_pinctrl_soc_info __attribute__((section(".data")));
static int imx5_pinctrl_probe(struct udevice *dev)
{

View File

@ -9,7 +9,7 @@
#include "pinctrl-imx.h"
static struct imx_pinctrl_soc_info imx7_pinctrl_soc_info;
static struct imx_pinctrl_soc_info imx7_pinctrl_soc_info __attribute__((section(".data")));
static struct imx_pinctrl_soc_info imx7_lpsr_pinctrl_soc_info = {
.flags = ZERO_OFFSET_VALID,

View File

@ -8,7 +8,7 @@
#include "pinctrl-imx.h"
static struct imx_pinctrl_soc_info imx8mq_pinctrl_soc_info;
static struct imx_pinctrl_soc_info imx8mq_pinctrl_soc_info __attribute__((section(".data")));
static int imx8mq_pinctrl_probe(struct udevice *dev)
{

View File

@ -13,6 +13,7 @@
#include <dm/device-internal.h>
#include <dm/device.h>
#include <imx_sip.h>
#include <linux/arm-smccc.h>
DECLARE_GLOBAL_DATA_PTR;
@ -30,6 +31,7 @@ static int imx8m_power_domain_on(struct power_domain *power_domain)
{
struct udevice *dev = power_domain->dev;
struct imx8m_power_domain_platdata *pdata;
pdata = dev_get_platdata(dev);
if (pdata->resource_id < 0)
@ -38,8 +40,8 @@ static int imx8m_power_domain_on(struct power_domain *power_domain)
if (pdata->has_pd)
power_domain_on(&pdata->pd);
call_imx_sip(IMX_SIP_GPC, IMX_SIP_GPC_PM_DOMAIN,
pdata->resource_id, 1, 0);
arm_smccc_smc(IMX_SIP_GPC, IMX_SIP_GPC_PM_DOMAIN,
pdata->resource_id, 1, 0, 0, 0, 0, NULL);
return 0;
}
@ -53,8 +55,8 @@ static int imx8m_power_domain_off(struct power_domain *power_domain)
if (pdata->resource_id < 0)
return -EINVAL;
call_imx_sip(IMX_SIP_GPC, IMX_SIP_GPC_PM_DOMAIN,
pdata->resource_id, 0, 0);
arm_smccc_smc(IMX_SIP_GPC, IMX_SIP_GPC_PM_DOMAIN,
pdata->resource_id, 0, 0, 0, 0, 0, NULL);
if (pdata->has_pd)
power_domain_off(&pdata->pd);

View File

@ -11,26 +11,7 @@
static const char pca9450_name[] = "PCA9450";
int power_pca9450a_init(unsigned char bus)
{
struct pmic *p = pmic_alloc();
if (!p) {
printf("%s: POWER allocation error!\n", __func__);
return -ENOMEM;
}
p->name = pca9450_name;
p->interface = PMIC_I2C;
p->number_of_regs = PCA9450_REG_NUM;
p->hw.i2c.addr = 0x35;
p->hw.i2c.tx_num = 1;
p->bus = bus;
return 0;
}
int power_pca9450b_init(unsigned char bus)
int power_pca9450_init(unsigned char bus)
{
struct pmic *p = pmic_alloc();

View File

@ -155,6 +155,14 @@ config FSL_QSPI
used to access the SPI NOR flash on platforms embedding this
Freescale IP core.
config FSL_QSPI_AHB_FULL_MAP
bool "Use full AHB memory map space"
depends on FSL_QSPI
default y if ARCH_MX6 || ARCH_MX7 || ARCH_MX7ULP || ARCH_IMX8M
help
Enable the Freescale QSPI driver to use full AHB memory map space for
flash access.
config ICH_SPI
bool "Intel ICH SPI driver"
help

View File

@ -46,6 +46,7 @@ DECLARE_GLOBAL_DATA_PTR;
* read operation, so let's use the last entry (15).
*/
#define SEQID_LUT 15
#define SEQID_LUT_AHB 14
/* Registers used by the driver */
#define QUADSPI_MCR 0x00
@ -122,6 +123,10 @@ DECLARE_GLOBAL_DATA_PTR;
#define QUADSPI_LUT_REG(idx) \
(QUADSPI_LUT_BASE + QUADSPI_LUT_OFFSET + (idx) * 4)
#define QUADSPI_AHB_LUT_OFFSET (SEQID_LUT_AHB * 4 * 4)
#define QUADSPI_AHB_LUT_REG(idx) \
(QUADSPI_LUT_BASE + QUADSPI_AHB_LUT_OFFSET + (idx) * 4)
/* Instruction set for the LUT register */
#define LUT_STOP 0
#define LUT_CMD 1
@ -189,6 +194,11 @@ DECLARE_GLOBAL_DATA_PTR;
*/
#define QUADSPI_QUIRK_USE_TDH_SETTING BIT(5)
/*
* Controller only has Two CS on flash A, no flash B port
*/
#define QUADSPI_QUIRK_SINGLE_BUS BIT(6)
struct fsl_qspi_devtype_data {
unsigned int rxfifo;
unsigned int txfifo;
@ -231,6 +241,15 @@ static const struct fsl_qspi_devtype_data imx6ul_data = {
.little_endian = true,
};
static const struct fsl_qspi_devtype_data imx7ulp_data = {
.rxfifo = SZ_64,
.txfifo = SZ_64,
.ahb_buf_size = SZ_128,
.quirks = QUADSPI_QUIRK_TKT253890 | QUADSPI_QUIRK_4X_INT_CLK |
QUADSPI_QUIRK_USE_TDH_SETTING | QUADSPI_QUIRK_SINGLE_BUS,
.little_endian = true,
};
static const struct fsl_qspi_devtype_data ls1021a_data = {
.rxfifo = SZ_128,
.txfifo = SZ_64,
@ -260,6 +279,7 @@ struct fsl_qspi {
void __iomem *iobase;
void __iomem *ahb_addr;
u32 memmap_phy;
u32 memmap_size;
const struct fsl_qspi_devtype_data *devtype_data;
int selected;
};
@ -294,6 +314,11 @@ static inline int needs_tdh_setting(struct fsl_qspi *q)
return q->devtype_data->quirks & QUADSPI_QUIRK_USE_TDH_SETTING;
}
static inline int needs_single_bus(struct fsl_qspi *q)
{
return q->devtype_data->quirks & QUADSPI_QUIRK_SINGLE_BUS;
}
/*
* An IC bug makes it necessary to rearrange the 32-bit data.
* Later chips, such as IMX6SLX, have fixed this bug.
@ -396,18 +421,27 @@ static void fsl_qspi_prepare_lut(struct fsl_qspi *q,
lutval[0] |= LUT_DEF(0, LUT_CMD, LUT_PAD(op->cmd.buswidth),
op->cmd.opcode);
/*
* For some unknown reason, using LUT_ADDR doesn't work in some
* cases (at least with only one byte long addresses), so
* let's use LUT_MODE to write the address bytes one by one
*/
for (i = 0; i < op->addr.nbytes; i++) {
u8 addrbyte = op->addr.val >> (8 * (op->addr.nbytes - i - 1));
if (IS_ENABLED(CONFIG_FSL_QSPI_AHB_FULL_MAP)) {
if (op->addr.nbytes) {
lutval[lutidx / 2] |= LUT_DEF(lutidx, LUT_ADDR,
LUT_PAD(op->addr.buswidth),
(op->addr.nbytes == 4) ? 0x20 : 0x18);
lutidx++;
}
} else {
/*
* For some unknown reason, using LUT_ADDR doesn't work in some
* cases (at least with only one byte long addresses), so
* let's use LUT_MODE to write the address bytes one by one
*/
for (i = 0; i < op->addr.nbytes; i++) {
u8 addrbyte = op->addr.val >> (8 * (op->addr.nbytes - i - 1));
lutval[lutidx / 2] |= LUT_DEF(lutidx, LUT_MODE,
LUT_PAD(op->addr.buswidth),
addrbyte);
lutidx++;
lutval[lutidx / 2] |= LUT_DEF(lutidx, LUT_MODE,
LUT_PAD(op->addr.buswidth),
addrbyte);
lutidx++;
}
}
if (op->dummy.nbytes) {
@ -440,6 +474,14 @@ static void fsl_qspi_prepare_lut(struct fsl_qspi *q,
for (i = 0; i < ARRAY_SIZE(lutval); i++)
qspi_writel(q, lutval[i], base + QUADSPI_LUT_REG(i));
if (IS_ENABLED(CONFIG_FSL_QSPI_AHB_FULL_MAP)) {
if (op->data.nbytes && op->data.dir == SPI_MEM_DATA_IN &&
op->addr.nbytes) {
for (i = 0; i < ARRAY_SIZE(lutval); i++)
qspi_writel(q, lutval[i], base + QUADSPI_AHB_LUT_REG(i));
}
}
/* lock LUT */
qspi_writel(q, QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY);
qspi_writel(q, QUADSPI_LCKER_LOCK, q->iobase + QUADSPI_LCKCR);
@ -482,10 +524,29 @@ static void fsl_qspi_select_mem(struct fsl_qspi *q, struct spi_slave *slave)
fsl_qspi_invalidate(q);
}
static u32 fsl_qspi_memsize_per_cs(struct fsl_qspi *q)
{
if (IS_ENABLED(CONFIG_FSL_QSPI_AHB_FULL_MAP)) {
if (needs_single_bus(q))
return q->memmap_size / 2;
else
return q->memmap_size / 4;
} else {
return ALIGN(q->devtype_data->ahb_buf_size, 0x400);
}
}
static void fsl_qspi_read_ahb(struct fsl_qspi *q, const struct spi_mem_op *op)
{
void __iomem *ahb_read_addr = q->ahb_addr;
if (IS_ENABLED(CONFIG_FSL_QSPI_AHB_FULL_MAP)) {
if (op->addr.nbytes)
ahb_read_addr += op->addr.val;
}
memcpy_fromio(op->data.buf.in,
q->ahb_addr + q->selected * q->devtype_data->ahb_buf_size,
ahb_read_addr + q->selected * fsl_qspi_memsize_per_cs(q),
op->data.nbytes);
}
@ -588,8 +649,13 @@ static int fsl_qspi_exec_op(struct spi_slave *slave,
if (needs_amba_base_offset(q))
addr_offset = q->memmap_phy;
if (IS_ENABLED(CONFIG_FSL_QSPI_AHB_FULL_MAP)) {
if (op->addr.nbytes)
addr_offset += op->addr.val;
}
qspi_writel(q,
q->selected * q->devtype_data->ahb_buf_size + addr_offset,
q->selected * fsl_qspi_memsize_per_cs(q) + addr_offset,
base + QUADSPI_SFAR);
qspi_writel(q, qspi_readl(q, base + QUADSPI_MCR) |
@ -646,7 +712,7 @@ static int fsl_qspi_adjust_op_size(struct spi_slave *slave,
static int fsl_qspi_default_setup(struct fsl_qspi *q)
{
void __iomem *base = q->iobase;
u32 reg, addr_offset = 0;
u32 reg, addr_offset = 0, memsize_cs;
/* Reset the module */
qspi_writel(q, QUADSPI_MCR_SWRSTSD_MASK | QUADSPI_MCR_SWRSTHD_MASK,
@ -678,8 +744,13 @@ static int fsl_qspi_default_setup(struct fsl_qspi *q)
qspi_writel(q, 0, base + QUADSPI_BUF1IND);
qspi_writel(q, 0, base + QUADSPI_BUF2IND);
qspi_writel(q, QUADSPI_BFGENCR_SEQID(SEQID_LUT),
q->iobase + QUADSPI_BFGENCR);
if (IS_ENABLED(CONFIG_FSL_QSPI_AHB_FULL_MAP))
qspi_writel(q, QUADSPI_BFGENCR_SEQID(SEQID_LUT_AHB),
q->iobase + QUADSPI_BFGENCR);
else
qspi_writel(q, QUADSPI_BFGENCR_SEQID(SEQID_LUT),
q->iobase + QUADSPI_BFGENCR);
qspi_writel(q, QUADSPI_RBCT_WMRK_MASK, base + QUADSPI_RBCT);
qspi_writel(q, QUADSPI_BUF3CR_ALLMST_MASK |
QUADSPI_BUF3CR_ADATSZ(q->devtype_data->ahb_buf_size / 8),
@ -695,14 +766,17 @@ static int fsl_qspi_default_setup(struct fsl_qspi *q)
* We use ahb_buf_size for each chip and set SFA1AD, SFA2AD, SFB1AD,
* SFB2AD accordingly.
*/
qspi_writel(q, q->devtype_data->ahb_buf_size + addr_offset,
memsize_cs = fsl_qspi_memsize_per_cs(q);
qspi_writel(q, memsize_cs + addr_offset,
base + QUADSPI_SFA1AD);
qspi_writel(q, q->devtype_data->ahb_buf_size * 2 + addr_offset,
qspi_writel(q, memsize_cs * 2 + addr_offset,
base + QUADSPI_SFA2AD);
qspi_writel(q, q->devtype_data->ahb_buf_size * 3 + addr_offset,
base + QUADSPI_SFB1AD);
qspi_writel(q, q->devtype_data->ahb_buf_size * 4 + addr_offset,
base + QUADSPI_SFB2AD);
if (!needs_single_bus(q)) {
qspi_writel(q, memsize_cs * 3 + addr_offset,
base + QUADSPI_SFB1AD);
qspi_writel(q, memsize_cs * 4 + addr_offset,
base + QUADSPI_SFB2AD);
}
q->selected = -1;
@ -750,6 +824,7 @@ static int fsl_qspi_probe(struct udevice *bus)
q->ahb_addr = map_physmem(res.start, res.end - res.start, MAP_NOCACHE);
q->memmap_phy = res.start;
q->memmap_size = res.end - res.start;
dm_bus->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency",
66000000);
@ -799,6 +874,7 @@ static const struct udevice_id fsl_qspi_ids[] = {
{ .compatible = "fsl,imx6sx-qspi", .data = (ulong)&imx6sx_data, },
{ .compatible = "fsl,imx6ul-qspi", .data = (ulong)&imx6ul_data, },
{ .compatible = "fsl,imx7d-qspi", .data = (ulong)&imx7d_data, },
{ .compatible = "fsl,imx7ulp-qspi", .data = (ulong)&imx7ulp_data, },
{ .compatible = "fsl,ls1021a-qspi", .data = (ulong)&ls1021a_data, },
{ .compatible = "fsl,ls1088a-qspi", .data = (ulong)&ls1088a_data, },
{ .compatible = "fsl,ls2080a-qspi", .data = (ulong)&ls2080a_data, },

View File

@ -16,6 +16,10 @@
#include <asm/arch/immap_lsch2.h>
#endif
#include <fsl_wdog.h>
#include <div64.h>
#define TIMEOUT_MAX 128000
#define TIMEOUT_MIN 500
static void imx_watchdog_expire_now(struct watchdog_regs *wdog, bool ext_reset)
{
@ -57,9 +61,9 @@ static void imx_watchdog_reset(struct watchdog_regs *wdog)
#endif /* CONFIG_WATCHDOG_RESET_DISABLE*/
}
static void imx_watchdog_init(struct watchdog_regs *wdog, bool ext_reset)
static void imx_watchdog_init(struct watchdog_regs *wdog, bool ext_reset,
u64 timeout)
{
u16 timeout;
u16 wcr;
/*
@ -70,7 +74,11 @@ static void imx_watchdog_init(struct watchdog_regs *wdog, bool ext_reset)
#ifndef CONFIG_WATCHDOG_TIMEOUT_MSECS
#define CONFIG_WATCHDOG_TIMEOUT_MSECS 128000
#endif
timeout = (CONFIG_WATCHDOG_TIMEOUT_MSECS / 500) - 1;
timeout = max_t(u64, timeout, TIMEOUT_MIN);
timeout = min_t(u64, timeout, TIMEOUT_MAX);
timeout = lldiv(timeout, 500) - 1;
#ifdef CONFIG_FSL_LSCH2
wcr = (WCR_WDA | WCR_SRS | WCR_WDE) << 8 | timeout;
#else
@ -95,7 +103,7 @@ void hw_watchdog_init(void)
{
struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
imx_watchdog_init(wdog, true);
imx_watchdog_init(wdog, true, CONFIG_WATCHDOG_TIMEOUT_MSECS);
}
#else
struct imx_wdt_priv {
@ -126,7 +134,7 @@ static int imx_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
{
struct imx_wdt_priv *priv = dev_get_priv(dev);
imx_watchdog_init(priv->base, priv->ext_reset);
imx_watchdog_init(priv->base, priv->ext_reset, timeout);
return 0;
}

View File

@ -10,6 +10,7 @@
#include <linux/stringify.h>
#include <asm/arch/imx-regs.h>
#define CONFIG_SYS_BOOTM_LEN (32 * SZ_1M)
#define CONFIG_SPL_MAX_SIZE (148 * 1024)
#define CONFIG_SYS_MONITOR_LEN SZ_512K
#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR

View File

@ -3,7 +3,6 @@
* Copyright (C) Stefano Babic <sbabic@denx.de>
*/
#ifndef __PCM058_CONFIG_H
#define __PCM058_CONFIG_H
@ -13,48 +12,13 @@
#include "mx6_common.h"
/* Thermal */
#define CONFIG_IMX_THERMAL
/* Serial */
#define CONFIG_MXC_UART
#define CONFIG_MXC_UART_BASE UART2_BASE
#define CONSOLE_DEV "ttymxc1"
#define PHYS_SDRAM_SIZE (1u * 1024 * 1024 * 1024)
/* Early setup */
/* Size of malloc() pool */
#define CONFIG_SYS_MALLOC_LEN (8 * SZ_1M)
/* Ethernet */
#define CONFIG_FEC_MXC
#define IMX_FEC_BASE ENET_BASE_ADDR
#define CONFIG_FEC_XCV_TYPE RGMII
#define CONFIG_ETHPRIME "FEC"
#define CONFIG_FEC_MXC_PHYADDR 3
/* SPI Flash */
/* I2C Configs */
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_MXC
#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 2 */
#define CONFIG_SYS_I2C_SPEED 100000
#ifndef CONFIG_SPL_BUILD
/* Enable NAND support */
#define CONFIG_SYS_MAX_NAND_DEVICE 1
#define CONFIG_SYS_NAND_BASE 0x40000000
#define CONFIG_SYS_NAND_5_ADDR_CYCLE
#define CONFIG_SYS_NAND_ONFI_DETECTION
#endif
/* DMA stuff, needed for GPMI/MXS NAND support */
/* Filesystem support */
/* Physical Memory Map */
#define PHYS_SDRAM MMDC0_ARB_BASE_ADDR
@ -68,10 +32,33 @@
#define CONFIG_SYS_INIT_SP_ADDR \
(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET)
/* MMC Configs */
#define CONFIG_SYS_FSL_ESDHC_ADDR 0
#define CONFIG_SYS_FSL_USDHC_NUM 1
/* Environment organization */
#define ENV_MMC \
"mmcdev=0\0" \
"mmcpart=2\0" \
"fitpart=1\0" \
"mmcrootfstype=ext4\0" \
"fitname=fitImage\0" \
"mmcloadfit=load mmc ${mmcdev}:${fitpart} ${loadaddr} ${fitname}\0" \
"mmcargs=setenv bootargs root=/dev/mmcblk${mmcdev}p${mmcpart} " \
"rootfstype=${mmcrootfstype} ${optargs}\0" \
"mmcboot=run mmcloadfit;run mmcargs;bootm ${loadaddr}\0"
#define ENV_NAND \
"mtdids=" CONFIG_MTDIDS_DEFAULT "\0" \
"mtdparts=" CONFIG_MTDPARTS_DEFAULT "\0" \
"nandroot=ubi0:root ubi.mtd=rootfs\0" \
"nandrootfstype=ubifs\0" \
"nandargs=setenv bootargs root=${nandroot} " \
"rootfstype=${nandrootfstype} ${mtdparts} ${optargs}\0" \
"nandloadfit=ubi part rootfs;ubi readvol ${loadaddr} fit\0" \
"nandboot=run nandloadfit;run nandargs;bootm ${loadaddr}\0"
#define CONFIG_EXTRA_ENV_SETTINGS \
"bootm_size=0x30000000\0" \
"optargs=rw rootwait\0" \
ENV_MMC \
ENV_NAND
#define CONFIG_BOOTCOMMAND "run mmcboot;run nandboot"
#endif

View File

@ -0,0 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _DT_BINDINGS_REGULATOR_DLG_DA9063_H
#define _DT_BINDINGS_REGULATOR_DLG_DA9063_H
/*
* These buck mode constants may be used to specify values in device tree
* properties (e.g. regulator-initial-mode).
* A description of the following modes is in the manufacturers datasheet.
*/
#define DA9063_BUCK_MODE_SLEEP 1
#define DA9063_BUCK_MODE_SYNC 2
#define DA9063_BUCK_MODE_AUTO 3
#endif

View File

@ -54,7 +54,6 @@ enum {
PCA9450_REG_NUM,
};
int power_pca9450a_init(unsigned char bus);
int power_pca9450b_init(unsigned char bus);
int power_pca9450_init(unsigned char bus);
#endif