mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-25 14:56:03 +00:00
MP1:
_ Add OHCI HCD support for STM32MP15xx DHSOM _ Report OTP-CLOSED instead of rev.? on closed STM32MP15xx _ Initialize TAMP_SMCR BKP..PROT fields on STM32MP15xx _ Jump to ep on successful resume in PSCI suspend code _ Add FASTBOOT support for STM32MP13 _ Fix/Rework key and leds management for STM32MP13/15 _ net: dwc_eth_qos: Clean up STM32 glue code and add STM32MP13xx support MP2: _ Add stm32-fmc-ebi support _ Add: sdmmc2 support and fix AARCH64 compilation -----BEGIN PGP SIGNATURE----- iQJQBAABCgA6FiEEXyrViUccKBz9c35Jysd4L3sz/6YFAmYiQ/EcHHBhdHJpY2Uu Y2hvdGFyZEBmb3NzLnN0LmNvbQAKCRDKx3gvezP/ph+3D/4qsN+tYQYzBfCnhCjA eEHMHGS6wBUg4riF5bjvk68CEVDIxm7NARFJi0RodvYsOZF7kLLyELm9yyNcWb+1 gkqLNcLLWFRhLyAIfCTnl88+luR6F48TPdVIXw17Vb3n4Fc99ICaS2PHYbHeRbR+ d/oga0DBz2N21+scYrUjPQoeczdk/fui84AXF7u8/7zFdYY0p50wHItKQHt4KXMv TnM9KbeHGlxRdIiVR2Jvv5Q51mhwv8XczgOZdmGLDYBV3xKexacHsLgfVcwSM2C8 1YHFA6VWVAOcJyQ+VFKmQw0JoTUWueJCY21T6H6fsAnpMTc9tksu3nLJO0P8CCN0 IbI50trzLWPy/BZtqJwV67durp6ZA6hT5wQOTo7NHAFocql9hJKtDuhvTVHqmx6R 6SWpTWD24Mkgd9FrXk/yMEUOmihOB8U6q+GkyPf/yfWyZK93mUwiRStFkBwEz8QY AX5gNoQ7+zJhkfZ4VdsCsFaVJV7Y9vlN3hnNhqLVEhXJ9GvFOszAZOTuuO8rLAv7 i7HE8Hk7zv6j15qSUPKOQv8BO0eVFlLPzTXS9F/uzSlpjfpNIs7At3TyQ4pAukRo uHc7KjHpVAkC+7YeMuVR3VFQ/p2+5EyxMclKIvGlOxqD/+m1Keu+C4/gTkWYlIgx mWqsvZCAi2RmDcUWBBB2mHpswQ== =up9Y -----END PGP SIGNATURE----- Merge tag 'u-boot-stm32-20240419' of https://source.denx.de/u-boot/custodians/u-boot-stm MP1: _ Add OHCI HCD support for STM32MP15xx DHSOM _ Report OTP-CLOSED instead of rev.? on closed STM32MP15xx _ Initialize TAMP_SMCR BKP..PROT fields on STM32MP15xx _ Jump to ep on successful resume in PSCI suspend code _ Add FASTBOOT support for STM32MP13 _ Fix/Rework key and leds management for STM32MP13/15 _ net: dwc_eth_qos: Clean up STM32 glue code and add STM32MP13xx support MP2: _ Add stm32-fmc-ebi support _ Add: sdmmc2 support and fix AARCH64 compilation
This commit is contained in:
commit
af04f37a78
27 changed files with 1051 additions and 430 deletions
|
@ -16,11 +16,26 @@
|
||||||
u-boot,mmc-env-partition = "u-boot-env";
|
u-boot,mmc-env-partition = "u-boot-env";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
gpio-keys {
|
||||||
|
button-user-1 {
|
||||||
|
label = "User-1";
|
||||||
|
linux,code = <BTN_2>;
|
||||||
|
gpios = <&gpioa 14 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
|
||||||
|
};
|
||||||
|
|
||||||
|
button-user {
|
||||||
|
/* update label to match the label requested in board_key_check() */
|
||||||
|
label = "User-2";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
leds {
|
leds {
|
||||||
|
led-blue {
|
||||||
|
/delete-property/default-state;
|
||||||
|
};
|
||||||
|
|
||||||
led-red {
|
led-red {
|
||||||
color = <LED_COLOR_ID_RED>;
|
|
||||||
gpios = <&gpioa 13 GPIO_ACTIVE_LOW>;
|
gpios = <&gpioa 13 GPIO_ACTIVE_LOW>;
|
||||||
default-state = "off";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
* Copyright : STMicroelectronics 2022
|
* Copyright : STMicroelectronics 2022
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <dt-bindings/input/linux-event-codes.h>
|
||||||
#include "stm32mp15-scmi-u-boot.dtsi"
|
#include "stm32mp15-scmi-u-boot.dtsi"
|
||||||
|
|
||||||
/ {
|
/ {
|
||||||
|
@ -12,20 +13,35 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
config {
|
config {
|
||||||
u-boot,boot-led = "heartbeat";
|
u-boot,boot-led = "led-blue";
|
||||||
u-boot,error-led = "error";
|
u-boot,error-led = "led-red";
|
||||||
u-boot,mmc-env-partition = "u-boot-env";
|
u-boot,mmc-env-partition = "u-boot-env";
|
||||||
st,adc_usb_pd = <&adc1 18>, <&adc1 19>;
|
st,adc_usb_pd = <&adc1 18>, <&adc1 19>;
|
||||||
st,fastboot-gpios = <&gpioa 13 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
|
};
|
||||||
st,stm32prog-gpios = <&gpioa 14 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
|
|
||||||
|
gpio-keys {
|
||||||
|
compatible = "gpio-keys";
|
||||||
|
|
||||||
|
button-user-1 {
|
||||||
|
label = "User-1";
|
||||||
|
linux,code = <BTN_1>;
|
||||||
|
gpios = <&gpioa 14 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
|
||||||
|
};
|
||||||
|
|
||||||
|
button-user-2 {
|
||||||
|
label = "User-2";
|
||||||
|
linux,code = <BTN_2>;
|
||||||
|
gpios = <&gpioa 13 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
led {
|
led {
|
||||||
red {
|
led-blue {
|
||||||
label = "error";
|
/delete-property/label;
|
||||||
|
};
|
||||||
|
|
||||||
|
led-red {
|
||||||
gpios = <&gpioa 13 GPIO_ACTIVE_LOW>;
|
gpios = <&gpioa 13 GPIO_ACTIVE_LOW>;
|
||||||
default-state = "off";
|
|
||||||
status = "okay";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <dt-bindings/clock/stm32mp1-clksrc.h>
|
#include <dt-bindings/clock/stm32mp1-clksrc.h>
|
||||||
|
#include <dt-bindings/input/linux-event-codes.h>
|
||||||
#include "stm32mp15-u-boot.dtsi"
|
#include "stm32mp15-u-boot.dtsi"
|
||||||
#include "stm32mp15-ddr3-1x4Gb-1066-binG.dtsi"
|
#include "stm32mp15-ddr3-1x4Gb-1066-binG.dtsi"
|
||||||
|
|
||||||
|
@ -14,12 +15,10 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
config {
|
config {
|
||||||
u-boot,boot-led = "heartbeat";
|
u-boot,boot-led = "led-blue";
|
||||||
u-boot,error-led = "error";
|
u-boot,error-led = "led-red";
|
||||||
u-boot,mmc-env-partition = "fip";
|
u-boot,mmc-env-partition = "fip";
|
||||||
st,adc_usb_pd = <&adc1 18>, <&adc1 19>;
|
st,adc_usb_pd = <&adc1 18>, <&adc1 19>;
|
||||||
st,fastboot-gpios = <&gpioa 13 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
|
|
||||||
st,stm32prog-gpios = <&gpioa 14 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(CONFIG_STM32MP15X_STM32IMAGE) || defined(CONFIG_SPL)
|
#if defined(CONFIG_STM32MP15X_STM32IMAGE) || defined(CONFIG_SPL)
|
||||||
|
@ -48,12 +47,29 @@
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
gpio-keys {
|
||||||
|
compatible = "gpio-keys";
|
||||||
|
|
||||||
|
button-user-1 {
|
||||||
|
label = "User-1";
|
||||||
|
linux,code = <BTN_1>;
|
||||||
|
gpios = <&gpioa 14 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
|
||||||
|
};
|
||||||
|
|
||||||
|
button-user-2 {
|
||||||
|
label = "User-2";
|
||||||
|
linux,code = <BTN_2>;
|
||||||
|
gpios = <&gpioa 13 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
led {
|
led {
|
||||||
red {
|
led-blue {
|
||||||
label = "error";
|
/delete-property/label;
|
||||||
|
};
|
||||||
|
|
||||||
|
led-red {
|
||||||
gpios = <&gpioa 13 GPIO_ACTIVE_LOW>;
|
gpios = <&gpioa 13 GPIO_ACTIVE_LOW>;
|
||||||
default-state = "off";
|
|
||||||
status = "okay";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
* Copyright : STMicroelectronics 2022
|
* Copyright : STMicroelectronics 2022
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <dt-bindings/input/linux-event-codes.h>
|
||||||
#include "stm32mp15-scmi-u-boot.dtsi"
|
#include "stm32mp15-scmi-u-boot.dtsi"
|
||||||
|
|
||||||
/ {
|
/ {
|
||||||
|
@ -11,19 +12,36 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
config {
|
config {
|
||||||
u-boot,boot-led = "heartbeat";
|
u-boot,boot-led = "led-blue";
|
||||||
u-boot,error-led = "error";
|
u-boot,error-led = "led-red";
|
||||||
u-boot,mmc-env-partition = "u-boot-env";
|
u-boot,mmc-env-partition = "u-boot-env";
|
||||||
st,fastboot-gpios = <&gpioa 13 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
|
};
|
||||||
st,stm32prog-gpios = <&gpioa 14 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
|
|
||||||
|
gpio-keys {
|
||||||
|
compatible = "gpio-keys";
|
||||||
|
|
||||||
|
button-user-1 {
|
||||||
|
label = "User-1";
|
||||||
|
linux,code = <BTN_1>;
|
||||||
|
gpios = <&gpioa 14 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
|
||||||
|
};
|
||||||
|
|
||||||
|
button-user-2 {
|
||||||
|
label = "User-2";
|
||||||
|
linux,code = <BTN_2>;
|
||||||
|
gpios = <&gpioa 13 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
led {
|
led {
|
||||||
red {
|
compatible = "gpio-leds";
|
||||||
label = "error";
|
|
||||||
|
led-blue {
|
||||||
|
gpios = <&gpiod 9 GPIO_ACTIVE_HIGH>;
|
||||||
|
};
|
||||||
|
|
||||||
|
led-red {
|
||||||
gpios = <&gpioa 13 GPIO_ACTIVE_LOW>;
|
gpios = <&gpioa 13 GPIO_ACTIVE_LOW>;
|
||||||
default-state = "off";
|
|
||||||
status = "okay";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <dt-bindings/clock/stm32mp1-clksrc.h>
|
#include <dt-bindings/clock/stm32mp1-clksrc.h>
|
||||||
|
#include <dt-bindings/input/linux-event-codes.h>
|
||||||
#include "stm32mp15-u-boot.dtsi"
|
#include "stm32mp15-u-boot.dtsi"
|
||||||
#include "stm32mp15-ddr3-2x4Gb-1066-binG.dtsi"
|
#include "stm32mp15-ddr3-2x4Gb-1066-binG.dtsi"
|
||||||
|
|
||||||
|
@ -13,11 +14,9 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
config {
|
config {
|
||||||
u-boot,boot-led = "heartbeat";
|
u-boot,boot-led = "led-blue";
|
||||||
u-boot,error-led = "error";
|
u-boot,error-led = "led-red";
|
||||||
u-boot,mmc-env-partition = "fip";
|
u-boot,mmc-env-partition = "fip";
|
||||||
st,fastboot-gpios = <&gpioa 13 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
|
|
||||||
st,stm32prog-gpios = <&gpioa 14 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(CONFIG_STM32MP15X_STM32IMAGE) || defined(CONFIG_SPL)
|
#if defined(CONFIG_STM32MP15X_STM32IMAGE) || defined(CONFIG_SPL)
|
||||||
|
@ -43,12 +42,31 @@
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
gpio-keys {
|
||||||
|
compatible = "gpio-keys";
|
||||||
|
|
||||||
|
button-user-1 {
|
||||||
|
label = "User-1";
|
||||||
|
linux,code = <BTN_1>;
|
||||||
|
gpios = <&gpioa 14 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
|
||||||
|
};
|
||||||
|
|
||||||
|
button-user-2 {
|
||||||
|
label = "User-2";
|
||||||
|
linux,code = <BTN_2>;
|
||||||
|
gpios = <&gpioa 13 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
led {
|
led {
|
||||||
red {
|
compatible = "gpio-leds";
|
||||||
label = "error";
|
|
||||||
|
led-blue {
|
||||||
|
gpios = <&gpiod 9 GPIO_ACTIVE_HIGH>;
|
||||||
|
};
|
||||||
|
|
||||||
|
led-red {
|
||||||
gpios = <&gpioa 13 GPIO_ACTIVE_LOW>;
|
gpios = <&gpioa 13 GPIO_ACTIVE_LOW>;
|
||||||
default-state = "off";
|
|
||||||
status = "okay";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -33,11 +33,11 @@
|
||||||
label = "fsbl1";
|
label = "fsbl1";
|
||||||
reg = <0x00000000 0x00040000>;
|
reg = <0x00000000 0x00040000>;
|
||||||
};
|
};
|
||||||
partition@80000 {
|
partition@40000 {
|
||||||
label = "fsbl2";
|
label = "fsbl2";
|
||||||
reg = <0x00040000 0x00040000>;
|
reg = <0x00040000 0x00040000>;
|
||||||
};
|
};
|
||||||
partition@100000 {
|
partition@80000 {
|
||||||
label = "ssbl";
|
label = "ssbl";
|
||||||
reg = <0x00080000 0x00200000>;
|
reg = <0x00080000 0x00200000>;
|
||||||
};
|
};
|
||||||
|
@ -58,7 +58,7 @@
|
||||||
label = "fsbl2";
|
label = "fsbl2";
|
||||||
reg = <0x00040000 0x00040000>;
|
reg = <0x00040000 0x00040000>;
|
||||||
};
|
};
|
||||||
partition@100000 {
|
partition@80000 {
|
||||||
label = "fip";
|
label = "fip";
|
||||||
reg = <0x00080000 0x00400000>;
|
reg = <0x00080000 0x00400000>;
|
||||||
};
|
};
|
||||||
|
@ -112,7 +112,7 @@
|
||||||
label = "fip2";
|
label = "fip2";
|
||||||
reg = <0x00600000 0x00400000>;
|
reg = <0x00600000 0x00400000>;
|
||||||
};
|
};
|
||||||
partition@1200000 {
|
partition@a00000 {
|
||||||
label = "UBI";
|
label = "UBI";
|
||||||
reg = <0x00a00000 0x3f600000>;
|
reg = <0x00a00000 0x3f600000>;
|
||||||
};
|
};
|
||||||
|
|
|
@ -106,15 +106,15 @@
|
||||||
label = "fsbl2";
|
label = "fsbl2";
|
||||||
reg = <0x00040000 0x00040000>;
|
reg = <0x00040000 0x00040000>;
|
||||||
};
|
};
|
||||||
partition@500000 {
|
partition@80000 {
|
||||||
label = "uboot";
|
label = "uboot";
|
||||||
reg = <0x00080000 0x00160000>;
|
reg = <0x00080000 0x00160000>;
|
||||||
};
|
};
|
||||||
partition@900000 {
|
partition@1e0000 {
|
||||||
label = "env1";
|
label = "env1";
|
||||||
reg = <0x001E0000 0x00010000>;
|
reg = <0x001E0000 0x00010000>;
|
||||||
};
|
};
|
||||||
partition@980000 {
|
partition@1f0000 {
|
||||||
label = "env2";
|
label = "env2";
|
||||||
reg = <0x001F0000 0x00010000>;
|
reg = <0x001F0000 0x00010000>;
|
||||||
};
|
};
|
||||||
|
|
|
@ -42,15 +42,15 @@
|
||||||
label = "fsbl2";
|
label = "fsbl2";
|
||||||
reg = <0x00040000 0x00040000>;
|
reg = <0x00040000 0x00040000>;
|
||||||
};
|
};
|
||||||
partition@500000 {
|
partition@80000 {
|
||||||
label = "uboot";
|
label = "uboot";
|
||||||
reg = <0x00080000 0x00160000>;
|
reg = <0x00080000 0x00160000>;
|
||||||
};
|
};
|
||||||
partition@900000 {
|
partition@1e0000 {
|
||||||
label = "env1";
|
label = "env1";
|
||||||
reg = <0x001E0000 0x00010000>;
|
reg = <0x001E0000 0x00010000>;
|
||||||
};
|
};
|
||||||
partition@980000 {
|
partition@1f0000 {
|
||||||
label = "env2";
|
label = "env2";
|
||||||
reg = <0x001F0000 0x00010000>;
|
reg = <0x001F0000 0x00010000>;
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,6 +17,7 @@ config CMD_STM32PROG
|
||||||
config CMD_STM32PROG_USB
|
config CMD_STM32PROG_USB
|
||||||
bool "support stm32prog over USB"
|
bool "support stm32prog over USB"
|
||||||
depends on CMD_STM32PROG
|
depends on CMD_STM32PROG
|
||||||
|
depends on USB_GADGET_DOWNLOAD
|
||||||
default y
|
default y
|
||||||
help
|
help
|
||||||
activate the command "stm32prog usb" for STM32MP soc family
|
activate the command "stm32prog usb" for STM32MP soc family
|
||||||
|
|
|
@ -8,7 +8,6 @@ obj-y += cpu.o
|
||||||
obj-$(CONFIG_STM32MP13X) += stm32mp13x.o
|
obj-$(CONFIG_STM32MP13X) += stm32mp13x.o
|
||||||
obj-$(CONFIG_STM32MP15X) += stm32mp15x.o
|
obj-$(CONFIG_STM32MP15X) += stm32mp15x.o
|
||||||
|
|
||||||
obj-$(CONFIG_STM32_ECDSA_VERIFY) += ecdsa_romapi.o
|
|
||||||
ifdef CONFIG_SPL_BUILD
|
ifdef CONFIG_SPL_BUILD
|
||||||
obj-y += spl.o
|
obj-y += spl.o
|
||||||
obj-y += tzc400.o
|
obj-y += tzc400.o
|
||||||
|
|
|
@ -703,6 +703,8 @@ void __secure psci_system_suspend(u32 __always_unused function_id,
|
||||||
{
|
{
|
||||||
u32 saved_mcudivr, saved_pll3cr, saved_pll4cr, saved_mssckselr;
|
u32 saved_mcudivr, saved_pll3cr, saved_pll4cr, saved_mssckselr;
|
||||||
u32 gicd_addr = stm32mp_get_gicd_base_address();
|
u32 gicd_addr = stm32mp_get_gicd_base_address();
|
||||||
|
u32 cpu = psci_get_cpu_id();
|
||||||
|
u32 sp = (u32)__secure_stack_end - (cpu << ARM_PSCI_STACK_SHIFT);
|
||||||
bool iwdg1_wake = false;
|
bool iwdg1_wake = false;
|
||||||
bool iwdg2_wake = false;
|
bool iwdg2_wake = false;
|
||||||
bool other_wake = false;
|
bool other_wake = false;
|
||||||
|
@ -805,4 +807,16 @@ void __secure psci_system_suspend(u32 __always_unused function_id,
|
||||||
|
|
||||||
writel(SYSCFG_CMPENR_MPUEN, STM32_SYSCFG_BASE + SYSCFG_CMPENSETR);
|
writel(SYSCFG_CMPENR_MPUEN, STM32_SYSCFG_BASE + SYSCFG_CMPENSETR);
|
||||||
clrbits_le32(STM32_SYSCFG_BASE + SYSCFG_CMPCR, SYSCFG_CMPCR_SW_CTRL);
|
clrbits_le32(STM32_SYSCFG_BASE + SYSCFG_CMPCR, SYSCFG_CMPCR_SW_CTRL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The system has resumed successfully. Rewrite LR register stored
|
||||||
|
* on stack with 'ep' value, so that on return from this PSCI call,
|
||||||
|
* the code would jump to that 'ep' resume entry point code path
|
||||||
|
* instead of the previous 'lr' register content which (e.g. with
|
||||||
|
* Linux) points to resume failure code path.
|
||||||
|
*
|
||||||
|
* See arch/arm/cpu/armv7/psci.S _smc_psci: for the stack layout
|
||||||
|
* used here, SP-4 is PC, SP-8 is LR, SP-12 is R7, and so on.
|
||||||
|
*/
|
||||||
|
writel(ep, sp - 8);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <asm/arch/sys_proto.h>
|
#include <asm/arch/sys_proto.h>
|
||||||
#include <dm/device.h>
|
#include <dm/device.h>
|
||||||
#include <dm/uclass.h>
|
#include <dm/uclass.h>
|
||||||
|
#include <linux/bitfield.h>
|
||||||
|
|
||||||
/* RCC register */
|
/* RCC register */
|
||||||
#define RCC_TZCR (STM32_RCC_BASE + 0x00)
|
#define RCC_TZCR (STM32_RCC_BASE + 0x00)
|
||||||
|
@ -41,6 +42,9 @@
|
||||||
#define TZC_REGION_ID_ACCESS0 (STM32_TZC_BASE + 0x114)
|
#define TZC_REGION_ID_ACCESS0 (STM32_TZC_BASE + 0x114)
|
||||||
|
|
||||||
#define TAMP_CR1 (STM32_TAMP_BASE + 0x00)
|
#define TAMP_CR1 (STM32_TAMP_BASE + 0x00)
|
||||||
|
#define TAMP_SMCR (STM32_TAMP_BASE + 0x20)
|
||||||
|
#define TAMP_SMCR_BKPRWDPROT GENMASK(7, 0)
|
||||||
|
#define TAMP_SMCR_BKPWDPROT GENMASK(23, 16)
|
||||||
|
|
||||||
#define PWR_CR1 (STM32_PWR_BASE + 0x00)
|
#define PWR_CR1 (STM32_PWR_BASE + 0x00)
|
||||||
#define PWR_MCUCR (STM32_PWR_BASE + 0x14)
|
#define PWR_MCUCR (STM32_PWR_BASE + 0x14)
|
||||||
|
@ -136,6 +140,18 @@ static void security_init(void)
|
||||||
*/
|
*/
|
||||||
writel(0x0, TAMP_CR1);
|
writel(0x0, TAMP_CR1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TAMP: Configure non-zero secure protection settings. This is
|
||||||
|
* checked by BootROM function 35ac on OTP-CLOSED device during
|
||||||
|
* CPU core 1 release from endless loop. If secure protection
|
||||||
|
* fields are zero, the core 1 is not released from endless
|
||||||
|
* loop on second SGI0.
|
||||||
|
*/
|
||||||
|
clrsetbits_le32(TAMP_SMCR,
|
||||||
|
TAMP_SMCR_BKPRWDPROT | TAMP_SMCR_BKPWDPROT,
|
||||||
|
FIELD_PREP(TAMP_SMCR_BKPRWDPROT, 0x20) |
|
||||||
|
FIELD_PREP(TAMP_SMCR_BKPWDPROT, 0x20));
|
||||||
|
|
||||||
/* GPIOZ: deactivate the security */
|
/* GPIOZ: deactivate the security */
|
||||||
writel(BIT(0), RCC_MP_AHB5ENSETR);
|
writel(BIT(0), RCC_MP_AHB5ENSETR);
|
||||||
writel(0x0, GPIOZ_SECCFGR);
|
writel(0x0, GPIOZ_SECCFGR);
|
||||||
|
@ -322,8 +338,23 @@ void get_soc_name(char name[SOC_NAME_SIZE])
|
||||||
|
|
||||||
get_cpu_string_offsets(&type, &pkg, &rev);
|
get_cpu_string_offsets(&type, &pkg, &rev);
|
||||||
|
|
||||||
snprintf(name, SOC_NAME_SIZE, "STM32MP%s%s Rev.%s",
|
if (bsec_dbgswenable()) {
|
||||||
soc_type[type], soc_pkg[pkg], soc_rev[rev]);
|
snprintf(name, SOC_NAME_SIZE, "STM32MP%s%s Rev.%s",
|
||||||
|
soc_type[type], soc_pkg[pkg], soc_rev[rev]);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* SoC revision is only accessible via DBUMCU IDC register,
|
||||||
|
* which requires BSEC.DENABLE DBGSWENABLE bit to be set to
|
||||||
|
* make the register accessible, otherwise an access to the
|
||||||
|
* register triggers bus fault. As BSEC.DBGSWENABLE is zero
|
||||||
|
* in case of an OTP-CLOSED system, do NOT set DBGSWENABLE
|
||||||
|
* bit as this might open a brief window for timing attacks.
|
||||||
|
* Instead, report that this system is OTP-CLOSED and do not
|
||||||
|
* report any SoC revision to avoid confusing users.
|
||||||
|
*/
|
||||||
|
snprintf(name, SOC_NAME_SIZE, "STM32MP%s%s SEC/C",
|
||||||
|
soc_type[type], soc_pkg[pkg]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setup_soc_type_pkg_rev(void)
|
static void setup_soc_type_pkg_rev(void)
|
||||||
|
|
|
@ -48,12 +48,10 @@
|
||||||
|
|
||||||
/* SYSCFG registers */
|
/* SYSCFG registers */
|
||||||
#define SYSCFG_BOOTR 0x00
|
#define SYSCFG_BOOTR 0x00
|
||||||
#define SYSCFG_PMCSETR 0x04
|
|
||||||
#define SYSCFG_IOCTRLSETR 0x18
|
#define SYSCFG_IOCTRLSETR 0x18
|
||||||
#define SYSCFG_ICNR 0x1C
|
#define SYSCFG_ICNR 0x1C
|
||||||
#define SYSCFG_CMPCR 0x20
|
#define SYSCFG_CMPCR 0x20
|
||||||
#define SYSCFG_CMPENSETR 0x24
|
#define SYSCFG_CMPENSETR 0x24
|
||||||
#define SYSCFG_PMCCLRR 0x44
|
|
||||||
|
|
||||||
#define SYSCFG_BOOTR_BOOT_MASK GENMASK(2, 0)
|
#define SYSCFG_BOOTR_BOOT_MASK GENMASK(2, 0)
|
||||||
#define SYSCFG_BOOTR_BOOTPD_SHIFT 4
|
#define SYSCFG_BOOTR_BOOTPD_SHIFT 4
|
||||||
|
@ -69,16 +67,6 @@
|
||||||
|
|
||||||
#define SYSCFG_CMPENSETR_MPU_EN BIT(0)
|
#define SYSCFG_CMPENSETR_MPU_EN BIT(0)
|
||||||
|
|
||||||
#define SYSCFG_PMCSETR_ETH_CLK_SEL BIT(16)
|
|
||||||
#define SYSCFG_PMCSETR_ETH_REF_CLK_SEL BIT(17)
|
|
||||||
|
|
||||||
#define SYSCFG_PMCSETR_ETH_SELMII BIT(20)
|
|
||||||
|
|
||||||
#define SYSCFG_PMCSETR_ETH_SEL_MASK GENMASK(23, 21)
|
|
||||||
#define SYSCFG_PMCSETR_ETH_SEL_GMII_MII 0
|
|
||||||
#define SYSCFG_PMCSETR_ETH_SEL_RGMII BIT(21)
|
|
||||||
#define SYSCFG_PMCSETR_ETH_SEL_RMII BIT(23)
|
|
||||||
|
|
||||||
#define KS_CCR 0x08
|
#define KS_CCR 0x08
|
||||||
#define KS_CCR_EEPROM BIT(9)
|
#define KS_CCR_EEPROM BIT(9)
|
||||||
#define KS_BE0 BIT(12)
|
#define KS_BE0 BIT(12)
|
||||||
|
@ -685,76 +673,6 @@ void board_quiesce_devices(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* eth init function : weak called in eqos driver */
|
|
||||||
int board_interface_eth_init(struct udevice *dev,
|
|
||||||
phy_interface_t interface_type)
|
|
||||||
{
|
|
||||||
u8 *syscfg;
|
|
||||||
u32 value;
|
|
||||||
bool eth_clk_sel_reg = false;
|
|
||||||
bool eth_ref_clk_sel_reg = false;
|
|
||||||
|
|
||||||
/* Gigabit Ethernet 125MHz clock selection. */
|
|
||||||
eth_clk_sel_reg = dev_read_bool(dev, "st,eth-clk-sel");
|
|
||||||
|
|
||||||
/* Ethernet 50Mhz RMII clock selection */
|
|
||||||
eth_ref_clk_sel_reg =
|
|
||||||
dev_read_bool(dev, "st,eth-ref-clk-sel");
|
|
||||||
|
|
||||||
syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG);
|
|
||||||
|
|
||||||
if (!syscfg)
|
|
||||||
return -ENODEV;
|
|
||||||
|
|
||||||
switch (interface_type) {
|
|
||||||
case PHY_INTERFACE_MODE_MII:
|
|
||||||
value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII |
|
|
||||||
SYSCFG_PMCSETR_ETH_REF_CLK_SEL;
|
|
||||||
debug("%s: PHY_INTERFACE_MODE_MII\n", __func__);
|
|
||||||
break;
|
|
||||||
case PHY_INTERFACE_MODE_GMII:
|
|
||||||
if (eth_clk_sel_reg)
|
|
||||||
value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII |
|
|
||||||
SYSCFG_PMCSETR_ETH_CLK_SEL;
|
|
||||||
else
|
|
||||||
value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII;
|
|
||||||
debug("%s: PHY_INTERFACE_MODE_GMII\n", __func__);
|
|
||||||
break;
|
|
||||||
case PHY_INTERFACE_MODE_RMII:
|
|
||||||
if (eth_ref_clk_sel_reg)
|
|
||||||
value = SYSCFG_PMCSETR_ETH_SEL_RMII |
|
|
||||||
SYSCFG_PMCSETR_ETH_REF_CLK_SEL;
|
|
||||||
else
|
|
||||||
value = SYSCFG_PMCSETR_ETH_SEL_RMII;
|
|
||||||
debug("%s: PHY_INTERFACE_MODE_RMII\n", __func__);
|
|
||||||
break;
|
|
||||||
case PHY_INTERFACE_MODE_RGMII:
|
|
||||||
case PHY_INTERFACE_MODE_RGMII_ID:
|
|
||||||
case PHY_INTERFACE_MODE_RGMII_RXID:
|
|
||||||
case PHY_INTERFACE_MODE_RGMII_TXID:
|
|
||||||
if (eth_clk_sel_reg)
|
|
||||||
value = SYSCFG_PMCSETR_ETH_SEL_RGMII |
|
|
||||||
SYSCFG_PMCSETR_ETH_CLK_SEL;
|
|
||||||
else
|
|
||||||
value = SYSCFG_PMCSETR_ETH_SEL_RGMII;
|
|
||||||
debug("%s: PHY_INTERFACE_MODE_RGMII\n", __func__);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
debug("%s: Do not manage %d interface\n",
|
|
||||||
__func__, interface_type);
|
|
||||||
/* Do not manage others interfaces */
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clear and set ETH configuration bits */
|
|
||||||
writel(SYSCFG_PMCSETR_ETH_SEL_MASK | SYSCFG_PMCSETR_ETH_SELMII |
|
|
||||||
SYSCFG_PMCSETR_ETH_REF_CLK_SEL | SYSCFG_PMCSETR_ETH_CLK_SEL,
|
|
||||||
syscfg + SYSCFG_PMCCLRR);
|
|
||||||
writel(value, syscfg + SYSCFG_PMCSETR);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(CONFIG_OF_BOARD_SETUP)
|
#if defined(CONFIG_OF_BOARD_SETUP)
|
||||||
int ft_board_setup(void *blob, struct bd_info *bd)
|
int ft_board_setup(void *blob, struct bd_info *bd)
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <adc.h>
|
#include <adc.h>
|
||||||
#include <bootm.h>
|
#include <bootm.h>
|
||||||
|
#include <button.h>
|
||||||
#include <clk.h>
|
#include <clk.h>
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <dm.h>
|
#include <dm.h>
|
||||||
|
@ -38,6 +39,7 @@
|
||||||
#include <asm/gpio.h>
|
#include <asm/gpio.h>
|
||||||
#include <asm/arch/stm32.h>
|
#include <asm/arch/stm32.h>
|
||||||
#include <asm/arch/sys_proto.h>
|
#include <asm/arch/sys_proto.h>
|
||||||
|
#include <dm/device-internal.h>
|
||||||
#include <dm/ofnode.h>
|
#include <dm/ofnode.h>
|
||||||
#include <jffs2/load_kernel.h>
|
#include <jffs2/load_kernel.h>
|
||||||
#include <linux/bitops.h>
|
#include <linux/bitops.h>
|
||||||
|
@ -52,12 +54,10 @@
|
||||||
|
|
||||||
/* SYSCFG registers */
|
/* SYSCFG registers */
|
||||||
#define SYSCFG_BOOTR 0x00
|
#define SYSCFG_BOOTR 0x00
|
||||||
#define SYSCFG_PMCSETR 0x04
|
|
||||||
#define SYSCFG_IOCTRLSETR 0x18
|
#define SYSCFG_IOCTRLSETR 0x18
|
||||||
#define SYSCFG_ICNR 0x1C
|
#define SYSCFG_ICNR 0x1C
|
||||||
#define SYSCFG_CMPCR 0x20
|
#define SYSCFG_CMPCR 0x20
|
||||||
#define SYSCFG_CMPENSETR 0x24
|
#define SYSCFG_CMPENSETR 0x24
|
||||||
#define SYSCFG_PMCCLRR 0x44
|
|
||||||
|
|
||||||
#define SYSCFG_BOOTR_BOOT_MASK GENMASK(2, 0)
|
#define SYSCFG_BOOTR_BOOT_MASK GENMASK(2, 0)
|
||||||
#define SYSCFG_BOOTR_BOOTPD_SHIFT 4
|
#define SYSCFG_BOOTR_BOOTPD_SHIFT 4
|
||||||
|
@ -73,16 +73,6 @@
|
||||||
|
|
||||||
#define SYSCFG_CMPENSETR_MPU_EN BIT(0)
|
#define SYSCFG_CMPENSETR_MPU_EN BIT(0)
|
||||||
|
|
||||||
#define SYSCFG_PMCSETR_ETH_CLK_SEL BIT(16)
|
|
||||||
#define SYSCFG_PMCSETR_ETH_REF_CLK_SEL BIT(17)
|
|
||||||
|
|
||||||
#define SYSCFG_PMCSETR_ETH_SELMII BIT(20)
|
|
||||||
|
|
||||||
#define SYSCFG_PMCSETR_ETH_SEL_MASK GENMASK(23, 21)
|
|
||||||
#define SYSCFG_PMCSETR_ETH_SEL_GMII_MII 0
|
|
||||||
#define SYSCFG_PMCSETR_ETH_SEL_RGMII BIT(21)
|
|
||||||
#define SYSCFG_PMCSETR_ETH_SEL_RMII BIT(23)
|
|
||||||
|
|
||||||
#define USB_LOW_THRESHOLD_UV 200000
|
#define USB_LOW_THRESHOLD_UV 200000
|
||||||
#define USB_WARNING_LOW_THRESHOLD_UV 660000
|
#define USB_WARNING_LOW_THRESHOLD_UV 660000
|
||||||
#define USB_START_LOW_THRESHOLD_UV 1230000
|
#define USB_START_LOW_THRESHOLD_UV 1230000
|
||||||
|
@ -150,45 +140,55 @@ int checkboard(void)
|
||||||
|
|
||||||
static void board_key_check(void)
|
static void board_key_check(void)
|
||||||
{
|
{
|
||||||
ofnode node;
|
struct udevice *button1 = NULL, *button2 = NULL;
|
||||||
struct gpio_desc gpio;
|
|
||||||
enum forced_boot_mode boot_mode = BOOT_NORMAL;
|
enum forced_boot_mode boot_mode = BOOT_NORMAL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!IS_ENABLED(CONFIG_BUTTON))
|
||||||
|
return;
|
||||||
|
|
||||||
if (!IS_ENABLED(CONFIG_FASTBOOT) && !IS_ENABLED(CONFIG_CMD_STM32PROG))
|
if (!IS_ENABLED(CONFIG_FASTBOOT) && !IS_ENABLED(CONFIG_CMD_STM32PROG))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
node = ofnode_path("/config");
|
if (IS_ENABLED(CONFIG_CMD_STM32PROG))
|
||||||
if (!ofnode_valid(node)) {
|
button_get_by_label("User-1", &button1);
|
||||||
log_debug("no /config node?\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (IS_ENABLED(CONFIG_FASTBOOT)) {
|
|
||||||
if (gpio_request_by_name_nodev(node, "st,fastboot-gpios", 0,
|
|
||||||
&gpio, GPIOD_IS_IN)) {
|
|
||||||
log_debug("could not find a /config/st,fastboot-gpios\n");
|
|
||||||
} else {
|
|
||||||
udelay(20);
|
|
||||||
if (dm_gpio_get_value(&gpio)) {
|
|
||||||
log_notice("Fastboot key pressed, ");
|
|
||||||
boot_mode = BOOT_FASTBOOT;
|
|
||||||
}
|
|
||||||
|
|
||||||
dm_gpio_free(NULL, &gpio);
|
if (IS_ENABLED(CONFIG_FASTBOOT))
|
||||||
|
button_get_by_label("User-2", &button2);
|
||||||
|
|
||||||
|
if (!button1 && !button2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (button2) {
|
||||||
|
if (button_get_state(button2) == BUTTON_ON) {
|
||||||
|
log_notice("Fastboot key pressed, ");
|
||||||
|
boot_mode = BOOT_FASTBOOT;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* On some boards, same gpio is shared betwwen gpio-keys and
|
||||||
|
* leds, remove the button device to free the gpio for led
|
||||||
|
* usage
|
||||||
|
*/
|
||||||
|
ret = device_remove(button2, DM_REMOVE_NORMAL);
|
||||||
|
if (ret)
|
||||||
|
log_err("Can't remove button2 (%d)\n", ret);
|
||||||
}
|
}
|
||||||
if (IS_ENABLED(CONFIG_CMD_STM32PROG)) {
|
|
||||||
if (gpio_request_by_name_nodev(node, "st,stm32prog-gpios", 0,
|
if (button1) {
|
||||||
&gpio, GPIOD_IS_IN)) {
|
if (button_get_state(button1) == BUTTON_ON) {
|
||||||
log_debug("could not find a /config/st,stm32prog-gpios\n");
|
log_notice("STM32Programmer key pressed, ");
|
||||||
} else {
|
boot_mode = BOOT_STM32PROG;
|
||||||
udelay(20);
|
|
||||||
if (dm_gpio_get_value(&gpio)) {
|
|
||||||
log_notice("STM32Programmer key pressed, ");
|
|
||||||
boot_mode = BOOT_STM32PROG;
|
|
||||||
}
|
|
||||||
dm_gpio_free(NULL, &gpio);
|
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* On some boards, same gpio is shared betwwen gpio-keys and
|
||||||
|
* leds, remove the button device to free the gpio for led
|
||||||
|
* usage
|
||||||
|
*/
|
||||||
|
ret = device_remove(button1, DM_REMOVE_NORMAL);
|
||||||
|
if (ret)
|
||||||
|
log_err("Can't remove button1 (%d)\n", ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (boot_mode != BOOT_NORMAL) {
|
if (boot_mode != BOOT_NORMAL) {
|
||||||
log_notice("entering download mode...\n");
|
log_notice("entering download mode...\n");
|
||||||
clrsetbits_le32(TAMP_BOOT_CONTEXT,
|
clrsetbits_le32(TAMP_BOOT_CONTEXT,
|
||||||
|
@ -742,76 +742,6 @@ void board_quiesce_devices(void)
|
||||||
setup_led(LEDST_OFF);
|
setup_led(LEDST_OFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* eth init function : weak called in eqos driver */
|
|
||||||
int board_interface_eth_init(struct udevice *dev,
|
|
||||||
phy_interface_t interface_type)
|
|
||||||
{
|
|
||||||
u8 *syscfg;
|
|
||||||
u32 value;
|
|
||||||
bool eth_clk_sel_reg = false;
|
|
||||||
bool eth_ref_clk_sel_reg = false;
|
|
||||||
|
|
||||||
/* Gigabit Ethernet 125MHz clock selection. */
|
|
||||||
eth_clk_sel_reg = dev_read_bool(dev, "st,eth-clk-sel");
|
|
||||||
|
|
||||||
/* Ethernet 50Mhz RMII clock selection */
|
|
||||||
eth_ref_clk_sel_reg =
|
|
||||||
dev_read_bool(dev, "st,eth-ref-clk-sel");
|
|
||||||
|
|
||||||
syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG);
|
|
||||||
|
|
||||||
if (!syscfg)
|
|
||||||
return -ENODEV;
|
|
||||||
|
|
||||||
switch (interface_type) {
|
|
||||||
case PHY_INTERFACE_MODE_MII:
|
|
||||||
value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII |
|
|
||||||
SYSCFG_PMCSETR_ETH_REF_CLK_SEL;
|
|
||||||
log_debug("PHY_INTERFACE_MODE_MII\n");
|
|
||||||
break;
|
|
||||||
case PHY_INTERFACE_MODE_GMII:
|
|
||||||
if (eth_clk_sel_reg)
|
|
||||||
value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII |
|
|
||||||
SYSCFG_PMCSETR_ETH_CLK_SEL;
|
|
||||||
else
|
|
||||||
value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII;
|
|
||||||
log_debug("PHY_INTERFACE_MODE_GMII\n");
|
|
||||||
break;
|
|
||||||
case PHY_INTERFACE_MODE_RMII:
|
|
||||||
if (eth_ref_clk_sel_reg)
|
|
||||||
value = SYSCFG_PMCSETR_ETH_SEL_RMII |
|
|
||||||
SYSCFG_PMCSETR_ETH_REF_CLK_SEL;
|
|
||||||
else
|
|
||||||
value = SYSCFG_PMCSETR_ETH_SEL_RMII;
|
|
||||||
log_debug("PHY_INTERFACE_MODE_RMII\n");
|
|
||||||
break;
|
|
||||||
case PHY_INTERFACE_MODE_RGMII:
|
|
||||||
case PHY_INTERFACE_MODE_RGMII_ID:
|
|
||||||
case PHY_INTERFACE_MODE_RGMII_RXID:
|
|
||||||
case PHY_INTERFACE_MODE_RGMII_TXID:
|
|
||||||
if (eth_clk_sel_reg)
|
|
||||||
value = SYSCFG_PMCSETR_ETH_SEL_RGMII |
|
|
||||||
SYSCFG_PMCSETR_ETH_CLK_SEL;
|
|
||||||
else
|
|
||||||
value = SYSCFG_PMCSETR_ETH_SEL_RGMII;
|
|
||||||
log_debug("PHY_INTERFACE_MODE_RGMII\n");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
log_debug("Do not manage %d interface\n",
|
|
||||||
interface_type);
|
|
||||||
/* Do not manage others interfaces */
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clear and set ETH configuration bits */
|
|
||||||
writel(SYSCFG_PMCSETR_ETH_SEL_MASK | SYSCFG_PMCSETR_ETH_SELMII |
|
|
||||||
SYSCFG_PMCSETR_ETH_REF_CLK_SEL | SYSCFG_PMCSETR_ETH_CLK_SEL,
|
|
||||||
syscfg + SYSCFG_PMCCLRR);
|
|
||||||
writel(value, syscfg + SYSCFG_PMCSETR);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum env_location env_get_location(enum env_operation op, int prio)
|
enum env_location env_get_location(enum env_operation op, int prio)
|
||||||
{
|
{
|
||||||
u32 bootmode = get_bootmode();
|
u32 bootmode = get_bootmode();
|
||||||
|
|
|
@ -15,6 +15,7 @@ CONFIG_CMD_STM32PROG=y
|
||||||
CONFIG_SYS_LOAD_ADDR=0xc2000000
|
CONFIG_SYS_LOAD_ADDR=0xc2000000
|
||||||
CONFIG_SYS_MEMTEST_START=0xc0000000
|
CONFIG_SYS_MEMTEST_START=0xc0000000
|
||||||
CONFIG_SYS_MEMTEST_END=0xc4000000
|
CONFIG_SYS_MEMTEST_END=0xc4000000
|
||||||
|
# CONFIG_ANDROID_BOOT_IMAGE is not set
|
||||||
CONFIG_FIT=y
|
CONFIG_FIT=y
|
||||||
CONFIG_SYS_BOOTM_LEN=0x2000000
|
CONFIG_SYS_BOOTM_LEN=0x2000000
|
||||||
CONFIG_DISTRO_DEFAULTS=y
|
CONFIG_DISTRO_DEFAULTS=y
|
||||||
|
@ -51,8 +52,17 @@ CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
|
||||||
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
|
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
|
||||||
CONFIG_SYS_MMC_ENV_DEV=-1
|
CONFIG_SYS_MMC_ENV_DEV=-1
|
||||||
CONFIG_ENV_MMC_USE_DT=y
|
CONFIG_ENV_MMC_USE_DT=y
|
||||||
|
CONFIG_BUTTON=y
|
||||||
|
CONFIG_BUTTON_GPIO=y
|
||||||
CONFIG_CLK_SCMI=y
|
CONFIG_CLK_SCMI=y
|
||||||
CONFIG_SET_DFU_ALT_INFO=y
|
CONFIG_SET_DFU_ALT_INFO=y
|
||||||
|
CONFIG_USB_FUNCTION_FASTBOOT=y
|
||||||
|
CONFIG_FASTBOOT_BUF_ADDR=0xc0000000
|
||||||
|
CONFIG_FASTBOOT_BUF_SIZE=0x02000000
|
||||||
|
CONFIG_FASTBOOT_FLASH=y
|
||||||
|
CONFIG_FASTBOOT_FLASH_MMC_DEV=0
|
||||||
|
CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
|
||||||
|
CONFIG_FASTBOOT_CMD_OEM_PARTCONF=y
|
||||||
CONFIG_GPIO_HOG=y
|
CONFIG_GPIO_HOG=y
|
||||||
CONFIG_DM_I2C=y
|
CONFIG_DM_I2C=y
|
||||||
CONFIG_SYS_I2C_STM32F7=y
|
CONFIG_SYS_I2C_STM32F7=y
|
||||||
|
@ -92,7 +102,6 @@ CONFIG_USB_GADGET_MANUFACTURER="STMicroelectronics"
|
||||||
CONFIG_USB_GADGET_VENDOR_NUM=0x0483
|
CONFIG_USB_GADGET_VENDOR_NUM=0x0483
|
||||||
CONFIG_USB_GADGET_PRODUCT_NUM=0x5720
|
CONFIG_USB_GADGET_PRODUCT_NUM=0x5720
|
||||||
CONFIG_USB_GADGET_DWC2_OTG=y
|
CONFIG_USB_GADGET_DWC2_OTG=y
|
||||||
CONFIG_USB_GADGET_DOWNLOAD=y
|
|
||||||
CONFIG_ERRNO_STR=y
|
CONFIG_ERRNO_STR=y
|
||||||
# CONFIG_LMB_USE_MAX_REGIONS is not set
|
# CONFIG_LMB_USE_MAX_REGIONS is not set
|
||||||
CONFIG_LMB_MEMORY_REGIONS=2
|
CONFIG_LMB_MEMORY_REGIONS=2
|
||||||
|
|
|
@ -97,6 +97,8 @@ CONFIG_TFTP_TSIZE=y
|
||||||
CONFIG_USE_SERVERIP=y
|
CONFIG_USE_SERVERIP=y
|
||||||
CONFIG_SERVERIP="192.168.1.1"
|
CONFIG_SERVERIP="192.168.1.1"
|
||||||
CONFIG_STM32_ADC=y
|
CONFIG_STM32_ADC=y
|
||||||
|
CONFIG_BUTTON=y
|
||||||
|
CONFIG_BUTTON_GPIO=y
|
||||||
CONFIG_SET_DFU_ALT_INFO=y
|
CONFIG_SET_DFU_ALT_INFO=y
|
||||||
CONFIG_USB_FUNCTION_FASTBOOT=y
|
CONFIG_USB_FUNCTION_FASTBOOT=y
|
||||||
CONFIG_FASTBOOT_BUF_ADDR=0xC0000000
|
CONFIG_FASTBOOT_BUF_ADDR=0xC0000000
|
||||||
|
|
|
@ -69,6 +69,8 @@ CONFIG_TFTP_TSIZE=y
|
||||||
CONFIG_USE_SERVERIP=y
|
CONFIG_USE_SERVERIP=y
|
||||||
CONFIG_SERVERIP="192.168.1.1"
|
CONFIG_SERVERIP="192.168.1.1"
|
||||||
CONFIG_STM32_ADC=y
|
CONFIG_STM32_ADC=y
|
||||||
|
CONFIG_BUTTON=y
|
||||||
|
CONFIG_BUTTON_GPIO=y
|
||||||
CONFIG_CLK_SCMI=y
|
CONFIG_CLK_SCMI=y
|
||||||
CONFIG_SET_DFU_ALT_INFO=y
|
CONFIG_SET_DFU_ALT_INFO=y
|
||||||
CONFIG_USB_FUNCTION_FASTBOOT=y
|
CONFIG_USB_FUNCTION_FASTBOOT=y
|
||||||
|
|
|
@ -164,6 +164,8 @@ CONFIG_DM_USB_GADGET=y
|
||||||
CONFIG_SPL_DM_USB_GADGET=y
|
CONFIG_SPL_DM_USB_GADGET=y
|
||||||
CONFIG_USB_EHCI_HCD=y
|
CONFIG_USB_EHCI_HCD=y
|
||||||
CONFIG_USB_EHCI_GENERIC=y
|
CONFIG_USB_EHCI_GENERIC=y
|
||||||
|
CONFIG_USB_OHCI_HCD=y
|
||||||
|
CONFIG_USB_OHCI_GENERIC=y
|
||||||
CONFIG_USB_DWC2=y
|
CONFIG_USB_DWC2=y
|
||||||
CONFIG_USB_HOST_ETHER=y
|
CONFIG_USB_HOST_ETHER=y
|
||||||
CONFIG_USB_ETHER_ASIX=y
|
CONFIG_USB_ETHER_ASIX=y
|
||||||
|
|
|
@ -164,6 +164,8 @@ CONFIG_DM_USB_GADGET=y
|
||||||
CONFIG_SPL_DM_USB_GADGET=y
|
CONFIG_SPL_DM_USB_GADGET=y
|
||||||
CONFIG_USB_EHCI_HCD=y
|
CONFIG_USB_EHCI_HCD=y
|
||||||
CONFIG_USB_EHCI_GENERIC=y
|
CONFIG_USB_EHCI_GENERIC=y
|
||||||
|
CONFIG_USB_OHCI_HCD=y
|
||||||
|
CONFIG_USB_OHCI_GENERIC=y
|
||||||
CONFIG_USB_DWC2=y
|
CONFIG_USB_DWC2=y
|
||||||
CONFIG_USB_HOST_ETHER=y
|
CONFIG_USB_HOST_ETHER=y
|
||||||
CONFIG_USB_ETHER_ASIX=y
|
CONFIG_USB_ETHER_ASIX=y
|
||||||
|
|
|
@ -70,6 +70,8 @@ CONFIG_TFTP_TSIZE=y
|
||||||
CONFIG_USE_SERVERIP=y
|
CONFIG_USE_SERVERIP=y
|
||||||
CONFIG_SERVERIP="192.168.1.1"
|
CONFIG_SERVERIP="192.168.1.1"
|
||||||
CONFIG_STM32_ADC=y
|
CONFIG_STM32_ADC=y
|
||||||
|
CONFIG_BUTTON=y
|
||||||
|
CONFIG_BUTTON_GPIO=y
|
||||||
CONFIG_CLK_SCMI=y
|
CONFIG_CLK_SCMI=y
|
||||||
CONFIG_SET_DFU_ALT_INFO=y
|
CONFIG_SET_DFU_ALT_INFO=y
|
||||||
CONFIG_USB_FUNCTION_FASTBOOT=y
|
CONFIG_USB_FUNCTION_FASTBOOT=y
|
||||||
|
|
|
@ -22,8 +22,15 @@
|
||||||
#define FMC2_BCR(x) ((x) * 0x8 + FMC2_BCR1)
|
#define FMC2_BCR(x) ((x) * 0x8 + FMC2_BCR1)
|
||||||
#define FMC2_BTR(x) ((x) * 0x8 + FMC2_BTR1)
|
#define FMC2_BTR(x) ((x) * 0x8 + FMC2_BTR1)
|
||||||
#define FMC2_PCSCNTR 0x20
|
#define FMC2_PCSCNTR 0x20
|
||||||
|
#define FMC2_CFGR 0x20
|
||||||
|
#define FMC2_SR 0x84
|
||||||
#define FMC2_BWTR1 0x104
|
#define FMC2_BWTR1 0x104
|
||||||
#define FMC2_BWTR(x) ((x) * 0x8 + FMC2_BWTR1)
|
#define FMC2_BWTR(x) ((x) * 0x8 + FMC2_BWTR1)
|
||||||
|
#define FMC2_SECCFGR 0x300
|
||||||
|
#define FMC2_CIDCFGR0 0x30c
|
||||||
|
#define FMC2_CIDCFGR(x) ((x) * 0x8 + FMC2_CIDCFGR0)
|
||||||
|
#define FMC2_SEMCR0 0x310
|
||||||
|
#define FMC2_SEMCR(x) ((x) * 0x8 + FMC2_SEMCR0)
|
||||||
|
|
||||||
/* Register: FMC2_BCR1 */
|
/* Register: FMC2_BCR1 */
|
||||||
#define FMC2_BCR1_CCLKEN BIT(20)
|
#define FMC2_BCR1_CCLKEN BIT(20)
|
||||||
|
@ -44,6 +51,7 @@
|
||||||
#define FMC2_BCR_ASYNCWAIT BIT(15)
|
#define FMC2_BCR_ASYNCWAIT BIT(15)
|
||||||
#define FMC2_BCR_CPSIZE GENMASK(18, 16)
|
#define FMC2_BCR_CPSIZE GENMASK(18, 16)
|
||||||
#define FMC2_BCR_CBURSTRW BIT(19)
|
#define FMC2_BCR_CBURSTRW BIT(19)
|
||||||
|
#define FMC2_BCR_CSCOUNT GENMASK(21, 20)
|
||||||
#define FMC2_BCR_NBLSET GENMASK(23, 22)
|
#define FMC2_BCR_NBLSET GENMASK(23, 22)
|
||||||
|
|
||||||
/* Register: FMC2_BTRx/FMC2_BWTRx */
|
/* Register: FMC2_BTRx/FMC2_BWTRx */
|
||||||
|
@ -60,8 +68,28 @@
|
||||||
#define FMC2_PCSCNTR_CSCOUNT GENMASK(15, 0)
|
#define FMC2_PCSCNTR_CSCOUNT GENMASK(15, 0)
|
||||||
#define FMC2_PCSCNTR_CNTBEN(x) BIT((x) + 16)
|
#define FMC2_PCSCNTR_CNTBEN(x) BIT((x) + 16)
|
||||||
|
|
||||||
|
/* Register: FMC2_CFGR */
|
||||||
|
#define FMC2_CFGR_CLKDIV GENMASK(19, 16)
|
||||||
|
#define FMC2_CFGR_CCLKEN BIT(20)
|
||||||
|
#define FMC2_CFGR_FMC2EN BIT(31)
|
||||||
|
|
||||||
|
/* Register: FMC2_SR */
|
||||||
|
#define FMC2_SR_ISOST GENMASK(1, 0)
|
||||||
|
|
||||||
|
/* Register: FMC2_CIDCFGR */
|
||||||
|
#define FMC2_CIDCFGR_CFEN BIT(0)
|
||||||
|
#define FMC2_CIDCFGR_SEMEN BIT(1)
|
||||||
|
#define FMC2_CIDCFGR_SCID GENMASK(6, 4)
|
||||||
|
#define FMC2_CIDCFGR_SEMWLC1 BIT(17)
|
||||||
|
|
||||||
|
/* Register: FMC2_SEMCR */
|
||||||
|
#define FMC2_SEMCR_SEM_MUTEX BIT(0)
|
||||||
|
#define FMC2_SEMCR_SEMCID GENMASK(6, 4)
|
||||||
|
|
||||||
#define FMC2_MAX_EBI_CE 4
|
#define FMC2_MAX_EBI_CE 4
|
||||||
#define FMC2_MAX_BANKS 5
|
#define FMC2_MAX_BANKS 5
|
||||||
|
#define FMC2_MAX_RESOURCES 6
|
||||||
|
#define FMC2_CID1 1
|
||||||
|
|
||||||
#define FMC2_BCR_CPSIZE_0 0x0
|
#define FMC2_BCR_CPSIZE_0 0x0
|
||||||
#define FMC2_BCR_CPSIZE_128 0x1
|
#define FMC2_BCR_CPSIZE_128 0x1
|
||||||
|
@ -76,6 +104,11 @@
|
||||||
#define FMC2_BCR_MTYP_PSRAM 0x1
|
#define FMC2_BCR_MTYP_PSRAM 0x1
|
||||||
#define FMC2_BCR_MTYP_NOR 0x2
|
#define FMC2_BCR_MTYP_NOR 0x2
|
||||||
|
|
||||||
|
#define FMC2_BCR_CSCOUNT_0 0x0
|
||||||
|
#define FMC2_BCR_CSCOUNT_1 0x1
|
||||||
|
#define FMC2_BCR_CSCOUNT_64 0x2
|
||||||
|
#define FMC2_BCR_CSCOUNT_256 0x3
|
||||||
|
|
||||||
#define FMC2_BXTR_EXTMOD_A 0x0
|
#define FMC2_BXTR_EXTMOD_A 0x0
|
||||||
#define FMC2_BXTR_EXTMOD_B 0x1
|
#define FMC2_BXTR_EXTMOD_B 0x1
|
||||||
#define FMC2_BXTR_EXTMOD_C 0x2
|
#define FMC2_BXTR_EXTMOD_C 0x2
|
||||||
|
@ -90,6 +123,7 @@
|
||||||
#define FMC2_BTR_CLKDIV_MAX 0xf
|
#define FMC2_BTR_CLKDIV_MAX 0xf
|
||||||
#define FMC2_BTR_DATLAT_MAX 0xf
|
#define FMC2_BTR_DATLAT_MAX 0xf
|
||||||
#define FMC2_PCSCNTR_CSCOUNT_MAX 0xff
|
#define FMC2_PCSCNTR_CSCOUNT_MAX 0xff
|
||||||
|
#define FMC2_CFGR_CLKDIV_MAX 0xf
|
||||||
|
|
||||||
enum stm32_fmc2_ebi_bank {
|
enum stm32_fmc2_ebi_bank {
|
||||||
FMC2_EBI1 = 0,
|
FMC2_EBI1 = 0,
|
||||||
|
@ -103,7 +137,8 @@ enum stm32_fmc2_ebi_register_type {
|
||||||
FMC2_REG_BCR = 1,
|
FMC2_REG_BCR = 1,
|
||||||
FMC2_REG_BTR,
|
FMC2_REG_BTR,
|
||||||
FMC2_REG_BWTR,
|
FMC2_REG_BWTR,
|
||||||
FMC2_REG_PCSCNTR
|
FMC2_REG_PCSCNTR,
|
||||||
|
FMC2_REG_CFGR
|
||||||
};
|
};
|
||||||
|
|
||||||
enum stm32_fmc2_ebi_transaction_type {
|
enum stm32_fmc2_ebi_transaction_type {
|
||||||
|
@ -134,10 +169,30 @@ enum stm32_fmc2_ebi_cpsize {
|
||||||
FMC2_CPSIZE_1024 = 1024
|
FMC2_CPSIZE_1024 = 1024
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum stm32_fmc2_ebi_cscount {
|
||||||
|
FMC2_CSCOUNT_0 = 0,
|
||||||
|
FMC2_CSCOUNT_1 = 1,
|
||||||
|
FMC2_CSCOUNT_64 = 64,
|
||||||
|
FMC2_CSCOUNT_256 = 256
|
||||||
|
};
|
||||||
|
|
||||||
|
struct stm32_fmc2_ebi;
|
||||||
|
|
||||||
|
struct stm32_fmc2_ebi_data {
|
||||||
|
const struct stm32_fmc2_prop *child_props;
|
||||||
|
unsigned int nb_child_props;
|
||||||
|
u32 fmc2_enable_reg;
|
||||||
|
u32 fmc2_enable_bit;
|
||||||
|
int (*nwait_used_by_ctrls)(struct stm32_fmc2_ebi *ebi);
|
||||||
|
int (*check_rif)(struct stm32_fmc2_ebi *ebi, u32 resource);
|
||||||
|
};
|
||||||
|
|
||||||
struct stm32_fmc2_ebi {
|
struct stm32_fmc2_ebi {
|
||||||
struct clk clk;
|
struct clk clk;
|
||||||
fdt_addr_t io_base;
|
fdt_addr_t io_base;
|
||||||
|
const struct stm32_fmc2_ebi_data *data;
|
||||||
u8 bank_assigned;
|
u8 bank_assigned;
|
||||||
|
bool access_granted;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -209,6 +264,28 @@ static int stm32_fmc2_ebi_check_sync_trans(struct stm32_fmc2_ebi *ebi,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int stm32_fmc2_ebi_mp25_check_cclk(struct stm32_fmc2_ebi *ebi,
|
||||||
|
const struct stm32_fmc2_prop *prop,
|
||||||
|
int cs)
|
||||||
|
{
|
||||||
|
if (!ebi->access_granted)
|
||||||
|
return -EACCES;
|
||||||
|
|
||||||
|
return stm32_fmc2_ebi_check_sync_trans(ebi, prop, cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int stm32_fmc2_ebi_mp25_check_clk_period(struct stm32_fmc2_ebi *ebi,
|
||||||
|
const struct stm32_fmc2_prop *prop,
|
||||||
|
int cs)
|
||||||
|
{
|
||||||
|
u32 cfgr = readl(ebi->io_base + FMC2_CFGR);
|
||||||
|
|
||||||
|
if (cfgr & FMC2_CFGR_CCLKEN && !ebi->access_granted)
|
||||||
|
return -EACCES;
|
||||||
|
|
||||||
|
return stm32_fmc2_ebi_check_sync_trans(ebi, prop, cs);
|
||||||
|
}
|
||||||
|
|
||||||
static int stm32_fmc2_ebi_check_async_trans(struct stm32_fmc2_ebi *ebi,
|
static int stm32_fmc2_ebi_check_async_trans(struct stm32_fmc2_ebi *ebi,
|
||||||
const struct stm32_fmc2_prop *prop,
|
const struct stm32_fmc2_prop *prop,
|
||||||
int cs)
|
int cs)
|
||||||
|
@ -296,6 +373,24 @@ static u32 stm32_fmc2_ebi_ns_to_clk_period(struct stm32_fmc2_ebi *ebi,
|
||||||
return DIV_ROUND_UP(nb_clk_cycles, clk_period);
|
return DIV_ROUND_UP(nb_clk_cycles, clk_period);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u32 stm32_fmc2_ebi_mp25_ns_to_clk_period(struct stm32_fmc2_ebi *ebi,
|
||||||
|
int cs, u32 setup)
|
||||||
|
{
|
||||||
|
u32 nb_clk_cycles = stm32_fmc2_ebi_ns_to_clock_cycles(ebi, cs, setup);
|
||||||
|
u32 cfgr = readl(ebi->io_base + FMC2_CFGR);
|
||||||
|
u32 clk_period;
|
||||||
|
|
||||||
|
if (cfgr & FMC2_CFGR_CCLKEN) {
|
||||||
|
clk_period = FIELD_GET(FMC2_CFGR_CLKDIV, cfgr) + 1;
|
||||||
|
} else {
|
||||||
|
u32 btr = readl(ebi->io_base + FMC2_BTR(cs));
|
||||||
|
|
||||||
|
clk_period = FIELD_GET(FMC2_BTR_CLKDIV, btr) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DIV_ROUND_UP(nb_clk_cycles, clk_period);
|
||||||
|
}
|
||||||
|
|
||||||
static int stm32_fmc2_ebi_get_reg(int reg_type, int cs, u32 *reg)
|
static int stm32_fmc2_ebi_get_reg(int reg_type, int cs, u32 *reg)
|
||||||
{
|
{
|
||||||
switch (reg_type) {
|
switch (reg_type) {
|
||||||
|
@ -311,6 +406,9 @@ static int stm32_fmc2_ebi_get_reg(int reg_type, int cs, u32 *reg)
|
||||||
case FMC2_REG_PCSCNTR:
|
case FMC2_REG_PCSCNTR:
|
||||||
*reg = FMC2_PCSCNTR;
|
*reg = FMC2_PCSCNTR;
|
||||||
break;
|
break;
|
||||||
|
case FMC2_REG_CFGR:
|
||||||
|
*reg = FMC2_CFGR;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -649,6 +747,26 @@ static int stm32_fmc2_ebi_set_clk_period(struct stm32_fmc2_ebi *ebi,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int stm32_fmc2_ebi_mp25_set_clk_period(struct stm32_fmc2_ebi *ebi,
|
||||||
|
const struct stm32_fmc2_prop *prop,
|
||||||
|
int cs, u32 setup)
|
||||||
|
{
|
||||||
|
u32 cfgr = readl(ebi->io_base + FMC2_CFGR);
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
if (cfgr & FMC2_CFGR_CCLKEN) {
|
||||||
|
val = setup ? clamp_val(setup - 1, 1, FMC2_CFGR_CLKDIV_MAX) : 1;
|
||||||
|
val = FIELD_PREP(FMC2_CFGR_CLKDIV, val);
|
||||||
|
clrsetbits_le32(ebi->io_base + FMC2_CFGR, FMC2_CFGR_CLKDIV, val);
|
||||||
|
} else {
|
||||||
|
val = setup ? clamp_val(setup - 1, 1, FMC2_BTR_CLKDIV_MAX) : 1;
|
||||||
|
val = FIELD_PREP(FMC2_BTR_CLKDIV, val);
|
||||||
|
clrsetbits_le32(ebi->io_base + FMC2_BTR(cs), FMC2_BTR_CLKDIV, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int stm32_fmc2_ebi_set_data_latency(struct stm32_fmc2_ebi *ebi,
|
static int stm32_fmc2_ebi_set_data_latency(struct stm32_fmc2_ebi *ebi,
|
||||||
const struct stm32_fmc2_prop *prop,
|
const struct stm32_fmc2_prop *prop,
|
||||||
int cs, u32 setup)
|
int cs, u32 setup)
|
||||||
|
@ -689,6 +807,27 @@ static int stm32_fmc2_ebi_set_max_low_pulse(struct stm32_fmc2_ebi *ebi,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int stm32_fmc2_ebi_mp25_set_max_low_pulse(struct stm32_fmc2_ebi *ebi,
|
||||||
|
const struct stm32_fmc2_prop *prop,
|
||||||
|
int cs, u32 setup)
|
||||||
|
{
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
if (setup == FMC2_CSCOUNT_0)
|
||||||
|
val = FIELD_PREP(FMC2_BCR_CSCOUNT, FMC2_BCR_CSCOUNT_0);
|
||||||
|
else if (setup == FMC2_CSCOUNT_1)
|
||||||
|
val = FIELD_PREP(FMC2_BCR_CSCOUNT, FMC2_BCR_CSCOUNT_1);
|
||||||
|
else if (setup <= FMC2_CSCOUNT_64)
|
||||||
|
val = FIELD_PREP(FMC2_BCR_CSCOUNT, FMC2_BCR_CSCOUNT_64);
|
||||||
|
else
|
||||||
|
val = FIELD_PREP(FMC2_BCR_CSCOUNT, FMC2_BCR_CSCOUNT_256);
|
||||||
|
|
||||||
|
clrsetbits_le32(ebi->io_base + FMC2_BCR(cs),
|
||||||
|
FMC2_BCR_CSCOUNT, val);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct stm32_fmc2_prop stm32_fmc2_child_props[] = {
|
static const struct stm32_fmc2_prop stm32_fmc2_child_props[] = {
|
||||||
/* st,fmc2-ebi-cs-trans-type must be the first property */
|
/* st,fmc2-ebi-cs-trans-type must be the first property */
|
||||||
{
|
{
|
||||||
|
@ -854,6 +993,235 @@ static const struct stm32_fmc2_prop stm32_fmc2_child_props[] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct stm32_fmc2_prop stm32_fmc2_mp25_child_props[] = {
|
||||||
|
/* st,fmc2-ebi-cs-trans-type must be the first property */
|
||||||
|
{
|
||||||
|
.name = "st,fmc2-ebi-cs-transaction-type",
|
||||||
|
.mprop = true,
|
||||||
|
.set = stm32_fmc2_ebi_set_trans_type,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "st,fmc2-ebi-cs-cclk-enable",
|
||||||
|
.bprop = true,
|
||||||
|
.reg_type = FMC2_REG_CFGR,
|
||||||
|
.reg_mask = FMC2_CFGR_CCLKEN,
|
||||||
|
.check = stm32_fmc2_ebi_mp25_check_cclk,
|
||||||
|
.set = stm32_fmc2_ebi_set_bit_field,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "st,fmc2-ebi-cs-mux-enable",
|
||||||
|
.bprop = true,
|
||||||
|
.reg_type = FMC2_REG_BCR,
|
||||||
|
.reg_mask = FMC2_BCR_MUXEN,
|
||||||
|
.check = stm32_fmc2_ebi_check_mux,
|
||||||
|
.set = stm32_fmc2_ebi_set_bit_field,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "st,fmc2-ebi-cs-buswidth",
|
||||||
|
.reset_val = FMC2_BUSWIDTH_16,
|
||||||
|
.set = stm32_fmc2_ebi_set_buswidth,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "st,fmc2-ebi-cs-waitpol-high",
|
||||||
|
.bprop = true,
|
||||||
|
.reg_type = FMC2_REG_BCR,
|
||||||
|
.reg_mask = FMC2_BCR_WAITPOL,
|
||||||
|
.set = stm32_fmc2_ebi_set_bit_field,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "st,fmc2-ebi-cs-waitcfg-enable",
|
||||||
|
.bprop = true,
|
||||||
|
.reg_type = FMC2_REG_BCR,
|
||||||
|
.reg_mask = FMC2_BCR_WAITCFG,
|
||||||
|
.check = stm32_fmc2_ebi_check_waitcfg,
|
||||||
|
.set = stm32_fmc2_ebi_set_bit_field,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "st,fmc2-ebi-cs-wait-enable",
|
||||||
|
.bprop = true,
|
||||||
|
.reg_type = FMC2_REG_BCR,
|
||||||
|
.reg_mask = FMC2_BCR_WAITEN,
|
||||||
|
.check = stm32_fmc2_ebi_check_sync_trans,
|
||||||
|
.set = stm32_fmc2_ebi_set_bit_field,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "st,fmc2-ebi-cs-asyncwait-enable",
|
||||||
|
.bprop = true,
|
||||||
|
.reg_type = FMC2_REG_BCR,
|
||||||
|
.reg_mask = FMC2_BCR_ASYNCWAIT,
|
||||||
|
.check = stm32_fmc2_ebi_check_async_trans,
|
||||||
|
.set = stm32_fmc2_ebi_set_bit_field,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "st,fmc2-ebi-cs-cpsize",
|
||||||
|
.check = stm32_fmc2_ebi_check_cpsize,
|
||||||
|
.set = stm32_fmc2_ebi_set_cpsize,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "st,fmc2-ebi-cs-byte-lane-setup-ns",
|
||||||
|
.calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
|
||||||
|
.set = stm32_fmc2_ebi_set_bl_setup,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "st,fmc2-ebi-cs-address-setup-ns",
|
||||||
|
.reg_type = FMC2_REG_BTR,
|
||||||
|
.reset_val = FMC2_BXTR_ADDSET_MAX,
|
||||||
|
.check = stm32_fmc2_ebi_check_async_trans,
|
||||||
|
.calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
|
||||||
|
.set = stm32_fmc2_ebi_set_address_setup,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "st,fmc2-ebi-cs-address-hold-ns",
|
||||||
|
.reg_type = FMC2_REG_BTR,
|
||||||
|
.reset_val = FMC2_BXTR_ADDHLD_MAX,
|
||||||
|
.check = stm32_fmc2_ebi_check_address_hold,
|
||||||
|
.calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
|
||||||
|
.set = stm32_fmc2_ebi_set_address_hold,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "st,fmc2-ebi-cs-data-setup-ns",
|
||||||
|
.reg_type = FMC2_REG_BTR,
|
||||||
|
.reset_val = FMC2_BXTR_DATAST_MAX,
|
||||||
|
.check = stm32_fmc2_ebi_check_async_trans,
|
||||||
|
.calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
|
||||||
|
.set = stm32_fmc2_ebi_set_data_setup,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "st,fmc2-ebi-cs-bus-turnaround-ns",
|
||||||
|
.reg_type = FMC2_REG_BTR,
|
||||||
|
.reset_val = FMC2_BXTR_BUSTURN_MAX + 1,
|
||||||
|
.calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
|
||||||
|
.set = stm32_fmc2_ebi_set_bus_turnaround,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "st,fmc2-ebi-cs-data-hold-ns",
|
||||||
|
.reg_type = FMC2_REG_BTR,
|
||||||
|
.check = stm32_fmc2_ebi_check_async_trans,
|
||||||
|
.calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
|
||||||
|
.set = stm32_fmc2_ebi_set_data_hold,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "st,fmc2-ebi-cs-clk-period-ns",
|
||||||
|
.reset_val = FMC2_CFGR_CLKDIV_MAX + 1,
|
||||||
|
.check = stm32_fmc2_ebi_mp25_check_clk_period,
|
||||||
|
.calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
|
||||||
|
.set = stm32_fmc2_ebi_mp25_set_clk_period,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "st,fmc2-ebi-cs-data-latency-ns",
|
||||||
|
.check = stm32_fmc2_ebi_check_sync_trans,
|
||||||
|
.calculate = stm32_fmc2_ebi_mp25_ns_to_clk_period,
|
||||||
|
.set = stm32_fmc2_ebi_set_data_latency,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "st,fmc2-ebi-cs-write-address-setup-ns",
|
||||||
|
.reg_type = FMC2_REG_BWTR,
|
||||||
|
.reset_val = FMC2_BXTR_ADDSET_MAX,
|
||||||
|
.check = stm32_fmc2_ebi_check_async_trans,
|
||||||
|
.calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
|
||||||
|
.set = stm32_fmc2_ebi_set_address_setup,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "st,fmc2-ebi-cs-write-address-hold-ns",
|
||||||
|
.reg_type = FMC2_REG_BWTR,
|
||||||
|
.reset_val = FMC2_BXTR_ADDHLD_MAX,
|
||||||
|
.check = stm32_fmc2_ebi_check_address_hold,
|
||||||
|
.calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
|
||||||
|
.set = stm32_fmc2_ebi_set_address_hold,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "st,fmc2-ebi-cs-write-data-setup-ns",
|
||||||
|
.reg_type = FMC2_REG_BWTR,
|
||||||
|
.reset_val = FMC2_BXTR_DATAST_MAX,
|
||||||
|
.check = stm32_fmc2_ebi_check_async_trans,
|
||||||
|
.calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
|
||||||
|
.set = stm32_fmc2_ebi_set_data_setup,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "st,fmc2-ebi-cs-write-bus-turnaround-ns",
|
||||||
|
.reg_type = FMC2_REG_BWTR,
|
||||||
|
.reset_val = FMC2_BXTR_BUSTURN_MAX + 1,
|
||||||
|
.calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
|
||||||
|
.set = stm32_fmc2_ebi_set_bus_turnaround,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "st,fmc2-ebi-cs-write-data-hold-ns",
|
||||||
|
.reg_type = FMC2_REG_BWTR,
|
||||||
|
.check = stm32_fmc2_ebi_check_async_trans,
|
||||||
|
.calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
|
||||||
|
.set = stm32_fmc2_ebi_set_data_hold,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "st,fmc2-ebi-cs-max-low-pulse-ns",
|
||||||
|
.calculate = stm32_fmc2_ebi_ns_to_clock_cycles,
|
||||||
|
.set = stm32_fmc2_ebi_mp25_set_max_low_pulse,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int stm32_fmc2_ebi_mp25_check_rif(struct stm32_fmc2_ebi *ebi, u32 resource)
|
||||||
|
{
|
||||||
|
u32 seccfgr, cidcfgr, semcr;
|
||||||
|
int cid;
|
||||||
|
|
||||||
|
if (resource >= FMC2_MAX_RESOURCES)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
seccfgr = readl(ebi->io_base + FMC2_SECCFGR);
|
||||||
|
if (seccfgr & BIT(resource)) {
|
||||||
|
if (resource)
|
||||||
|
log_err("resource %d is configured as secure\n",
|
||||||
|
resource);
|
||||||
|
|
||||||
|
return -EACCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
cidcfgr = readl(ebi->io_base + FMC2_CIDCFGR(resource));
|
||||||
|
if (!(cidcfgr & FMC2_CIDCFGR_CFEN))
|
||||||
|
/* CID filtering is turned off: access granted */
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!(cidcfgr & FMC2_CIDCFGR_SEMEN)) {
|
||||||
|
/* Static CID mode */
|
||||||
|
cid = FIELD_GET(FMC2_CIDCFGR_SCID, cidcfgr);
|
||||||
|
if (cid != FMC2_CID1) {
|
||||||
|
if (resource)
|
||||||
|
log_err("static CID%d set for resource %d\n",
|
||||||
|
cid, resource);
|
||||||
|
|
||||||
|
return -EACCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pass-list with semaphore mode */
|
||||||
|
if (!(cidcfgr & FMC2_CIDCFGR_SEMWLC1)) {
|
||||||
|
if (resource)
|
||||||
|
log_err("CID1 is block-listed for resource %d\n",
|
||||||
|
resource);
|
||||||
|
|
||||||
|
return -EACCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
semcr = readl(ebi->io_base + FMC2_SEMCR(resource));
|
||||||
|
if (!(semcr & FMC2_SEMCR_SEM_MUTEX)) {
|
||||||
|
setbits_le32(ebi->io_base + FMC2_SEMCR(resource),
|
||||||
|
FMC2_SEMCR_SEM_MUTEX);
|
||||||
|
semcr = readl(ebi->io_base + FMC2_SEMCR(resource));
|
||||||
|
}
|
||||||
|
|
||||||
|
cid = FIELD_GET(FMC2_SEMCR_SEMCID, semcr);
|
||||||
|
if (cid != FMC2_CID1) {
|
||||||
|
if (resource)
|
||||||
|
log_err("resource %d is already used by CID%d\n",
|
||||||
|
resource, cid);
|
||||||
|
|
||||||
|
return -EACCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int stm32_fmc2_ebi_parse_prop(struct stm32_fmc2_ebi *ebi,
|
static int stm32_fmc2_ebi_parse_prop(struct stm32_fmc2_ebi *ebi,
|
||||||
ofnode node,
|
ofnode node,
|
||||||
const struct stm32_fmc2_prop *prop,
|
const struct stm32_fmc2_prop *prop,
|
||||||
|
@ -915,7 +1283,7 @@ static void stm32_fmc2_ebi_disable_bank(struct stm32_fmc2_ebi *ebi, int cs)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NWAIT signal can not be connected to EBI controller and NAND controller */
|
/* NWAIT signal can not be connected to EBI controller and NAND controller */
|
||||||
static bool stm32_fmc2_ebi_nwait_used_by_ctrls(struct stm32_fmc2_ebi *ebi)
|
static int stm32_fmc2_ebi_nwait_used_by_ctrls(struct stm32_fmc2_ebi *ebi)
|
||||||
{
|
{
|
||||||
unsigned int cs;
|
unsigned int cs;
|
||||||
u32 bcr;
|
u32 bcr;
|
||||||
|
@ -926,16 +1294,22 @@ static bool stm32_fmc2_ebi_nwait_used_by_ctrls(struct stm32_fmc2_ebi *ebi)
|
||||||
|
|
||||||
bcr = readl(ebi->io_base + FMC2_BCR(cs));
|
bcr = readl(ebi->io_base + FMC2_BCR(cs));
|
||||||
if ((bcr & FMC2_BCR_WAITEN || bcr & FMC2_BCR_ASYNCWAIT) &&
|
if ((bcr & FMC2_BCR_WAITEN || bcr & FMC2_BCR_ASYNCWAIT) &&
|
||||||
ebi->bank_assigned & BIT(FMC2_NAND))
|
ebi->bank_assigned & BIT(FMC2_NAND)) {
|
||||||
return true;
|
log_err("NWAIT signal connected to EBI and NAND controllers\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stm32_fmc2_ebi_enable(struct stm32_fmc2_ebi *ebi)
|
static void stm32_fmc2_ebi_enable(struct stm32_fmc2_ebi *ebi)
|
||||||
{
|
{
|
||||||
setbits_le32(ebi->io_base + FMC2_BCR1, FMC2_BCR1_FMC2EN);
|
if (!ebi->access_granted)
|
||||||
|
return;
|
||||||
|
|
||||||
|
setbits_le32(ebi->io_base + ebi->data->fmc2_enable_reg,
|
||||||
|
ebi->data->fmc2_enable_bit);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int stm32_fmc2_ebi_setup_cs(struct stm32_fmc2_ebi *ebi,
|
static int stm32_fmc2_ebi_setup_cs(struct stm32_fmc2_ebi *ebi,
|
||||||
|
@ -946,8 +1320,8 @@ static int stm32_fmc2_ebi_setup_cs(struct stm32_fmc2_ebi *ebi,
|
||||||
|
|
||||||
stm32_fmc2_ebi_disable_bank(ebi, cs);
|
stm32_fmc2_ebi_disable_bank(ebi, cs);
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(stm32_fmc2_child_props); i++) {
|
for (i = 0; i < ebi->data->nb_child_props; i++) {
|
||||||
const struct stm32_fmc2_prop *p = &stm32_fmc2_child_props[i];
|
const struct stm32_fmc2_prop *p = &ebi->data->child_props[i];
|
||||||
|
|
||||||
ret = stm32_fmc2_ebi_parse_prop(ebi, node, p, cs);
|
ret = stm32_fmc2_ebi_parse_prop(ebi, node, p, cs);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -987,6 +1361,14 @@ static int stm32_fmc2_ebi_parse_dt(struct udevice *dev,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ebi->data->check_rif) {
|
||||||
|
ret = ebi->data->check_rif(ebi, bank + 1);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(dev, "bank access failed: %d\n", bank);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (bank < FMC2_MAX_EBI_CE) {
|
if (bank < FMC2_MAX_EBI_CE) {
|
||||||
ret = stm32_fmc2_ebi_setup_cs(ebi, child, bank);
|
ret = stm32_fmc2_ebi_setup_cs(ebi, child, bank);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -1004,9 +1386,10 @@ static int stm32_fmc2_ebi_parse_dt(struct udevice *dev,
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stm32_fmc2_ebi_nwait_used_by_ctrls(ebi)) {
|
if (ebi->data->nwait_used_by_ctrls) {
|
||||||
dev_err(dev, "NWAIT signal connected to EBI and NAND controllers\n");
|
ret = ebi->data->nwait_used_by_ctrls(ebi);
|
||||||
return -EINVAL;
|
if (ret)
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
stm32_fmc2_ebi_enable(ebi);
|
stm32_fmc2_ebi_enable(ebi);
|
||||||
|
@ -1020,6 +1403,10 @@ static int stm32_fmc2_ebi_probe(struct udevice *dev)
|
||||||
struct reset_ctl reset;
|
struct reset_ctl reset;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
ebi->data = (void *)dev_get_driver_data(dev);
|
||||||
|
if (!ebi->data)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
ebi->io_base = dev_read_addr(dev);
|
ebi->io_base = dev_read_addr(dev);
|
||||||
if (ebi->io_base == FDT_ADDR_T_NONE)
|
if (ebi->io_base == FDT_ADDR_T_NONE)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -1039,11 +1426,49 @@ static int stm32_fmc2_ebi_probe(struct udevice *dev)
|
||||||
reset_deassert(&reset);
|
reset_deassert(&reset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if CFGR register can be modified */
|
||||||
|
ebi->access_granted = true;
|
||||||
|
if (ebi->data->check_rif) {
|
||||||
|
ret = ebi->data->check_rif(ebi, 0);
|
||||||
|
if (ret) {
|
||||||
|
ebi->access_granted = false;
|
||||||
|
|
||||||
|
/* In case of CFGR is secure, just check that the FMC2 is enabled */
|
||||||
|
if (readl(ebi->io_base + FMC2_SR) & FMC2_SR_ISOST) {
|
||||||
|
dev_err(dev, "FMC2 is not ready to be used.\n");
|
||||||
|
return -EACCES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return stm32_fmc2_ebi_parse_dt(dev, ebi);
|
return stm32_fmc2_ebi_parse_dt(dev, ebi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct stm32_fmc2_ebi_data stm32_fmc2_ebi_mp1_data = {
|
||||||
|
.child_props = stm32_fmc2_child_props,
|
||||||
|
.nb_child_props = ARRAY_SIZE(stm32_fmc2_child_props),
|
||||||
|
.fmc2_enable_reg = FMC2_BCR1,
|
||||||
|
.fmc2_enable_bit = FMC2_BCR1_FMC2EN,
|
||||||
|
.nwait_used_by_ctrls = stm32_fmc2_ebi_nwait_used_by_ctrls,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct stm32_fmc2_ebi_data stm32_fmc2_ebi_mp25_data = {
|
||||||
|
.child_props = stm32_fmc2_mp25_child_props,
|
||||||
|
.nb_child_props = ARRAY_SIZE(stm32_fmc2_mp25_child_props),
|
||||||
|
.fmc2_enable_reg = FMC2_CFGR,
|
||||||
|
.fmc2_enable_bit = FMC2_CFGR_FMC2EN,
|
||||||
|
.check_rif = stm32_fmc2_ebi_mp25_check_rif,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct udevice_id stm32_fmc2_ebi_match[] = {
|
static const struct udevice_id stm32_fmc2_ebi_match[] = {
|
||||||
{.compatible = "st,stm32mp1-fmc2-ebi"},
|
{
|
||||||
|
.compatible = "st,stm32mp1-fmc2-ebi",
|
||||||
|
.data = (ulong)&stm32_fmc2_ebi_mp1_data,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.compatible = "st,stm32mp25-fmc2-ebi",
|
||||||
|
.data = (ulong)&stm32_fmc2_ebi_mp25_data,
|
||||||
|
},
|
||||||
{ /* Sentinel */ }
|
{ /* Sentinel */ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -220,9 +220,9 @@ static void stm32_sdmmc2_start_data(struct udevice *dev,
|
||||||
|
|
||||||
if (data->flags & MMC_DATA_READ) {
|
if (data->flags & MMC_DATA_READ) {
|
||||||
data_ctrl |= SDMMC_DCTRL_DTDIR;
|
data_ctrl |= SDMMC_DCTRL_DTDIR;
|
||||||
idmabase0 = (u32)data->dest;
|
idmabase0 = (u32)(long)data->dest;
|
||||||
} else {
|
} else {
|
||||||
idmabase0 = (u32)data->src;
|
idmabase0 = (u32)(long)data->src;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the SDMMC DataLength value */
|
/* Set the SDMMC DataLength value */
|
||||||
|
@ -463,8 +463,8 @@ retry_cmd:
|
||||||
|
|
||||||
stm32_sdmmc2_start_cmd(dev, cmd, cmdat, &ctx);
|
stm32_sdmmc2_start_cmd(dev, cmd, cmdat, &ctx);
|
||||||
|
|
||||||
dev_dbg(dev, "send cmd %d data: 0x%x @ 0x%x\n",
|
dev_dbg(dev, "send cmd %d data: 0x%x @ 0x%p\n",
|
||||||
cmd->cmdidx, data ? ctx.data_length : 0, (unsigned int)data);
|
cmd->cmdidx, data ? ctx.data_length : 0, data);
|
||||||
|
|
||||||
ret = stm32_sdmmc2_end_cmd(dev, cmd, &ctx);
|
ret = stm32_sdmmc2_end_cmd(dev, cmd, &ctx);
|
||||||
|
|
||||||
|
@ -789,6 +789,7 @@ static int stm32_sdmmc2_bind(struct udevice *dev)
|
||||||
|
|
||||||
static const struct udevice_id stm32_sdmmc2_ids[] = {
|
static const struct udevice_id stm32_sdmmc2_ids[] = {
|
||||||
{ .compatible = "st,stm32-sdmmc2" },
|
{ .compatible = "st,stm32-sdmmc2" },
|
||||||
|
{ .compatible = "st,stm32mp25-sdmmc2" },
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
#define FMC2_RB_DELAY_US 30
|
#define FMC2_RB_DELAY_US 30
|
||||||
|
|
||||||
/* Max chip enable */
|
/* Max chip enable */
|
||||||
#define FMC2_MAX_CE 2
|
#define FMC2_MAX_CE 4
|
||||||
|
|
||||||
/* Timings */
|
/* Timings */
|
||||||
#define FMC2_THIZ 1
|
#define FMC2_THIZ 1
|
||||||
|
@ -160,6 +160,11 @@ static inline struct stm32_fmc2_nand *to_fmc2_nand(struct nand_chip *chip)
|
||||||
return container_of(chip, struct stm32_fmc2_nand, chip);
|
return container_of(chip, struct stm32_fmc2_nand, chip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct stm32_fmc2_nfc_data {
|
||||||
|
int max_ncs;
|
||||||
|
struct udevice *(*get_cdev)(struct udevice *dev);
|
||||||
|
};
|
||||||
|
|
||||||
struct stm32_fmc2_nfc {
|
struct stm32_fmc2_nfc {
|
||||||
struct nand_hw_control base;
|
struct nand_hw_control base;
|
||||||
struct stm32_fmc2_nand nand;
|
struct stm32_fmc2_nand nand;
|
||||||
|
@ -169,6 +174,7 @@ struct stm32_fmc2_nfc {
|
||||||
fdt_addr_t cmd_base[FMC2_MAX_CE];
|
fdt_addr_t cmd_base[FMC2_MAX_CE];
|
||||||
fdt_addr_t addr_base[FMC2_MAX_CE];
|
fdt_addr_t addr_base[FMC2_MAX_CE];
|
||||||
struct clk clk;
|
struct clk clk;
|
||||||
|
const struct stm32_fmc2_nfc_data *data;
|
||||||
|
|
||||||
u8 cs_assigned;
|
u8 cs_assigned;
|
||||||
int cs_sel;
|
int cs_sel;
|
||||||
|
@ -815,7 +821,7 @@ static int stm32_fmc2_nfc_parse_child(struct stm32_fmc2_nfc *nfc, ofnode node)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < nand->ncs; i++) {
|
for (i = 0; i < nand->ncs; i++) {
|
||||||
if (cs[i] >= FMC2_MAX_CE) {
|
if (cs[i] >= nfc->data->max_ncs) {
|
||||||
log_err("Invalid reg value: %d\n", nand->cs_used[i]);
|
log_err("Invalid reg value: %d\n", nand->cs_used[i]);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -906,10 +912,18 @@ static int stm32_fmc2_nfc_probe(struct udevice *dev)
|
||||||
spin_lock_init(&nfc->controller.lock);
|
spin_lock_init(&nfc->controller.lock);
|
||||||
init_waitqueue_head(&nfc->controller.wq);
|
init_waitqueue_head(&nfc->controller.wq);
|
||||||
|
|
||||||
cdev = stm32_fmc2_nfc_get_cdev(dev);
|
nfc->data = (void *)dev_get_driver_data(dev);
|
||||||
if (!cdev)
|
if (!nfc->data)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (nfc->data->get_cdev) {
|
||||||
|
cdev = nfc->data->get_cdev(dev);
|
||||||
|
if (!cdev)
|
||||||
|
return -EINVAL;
|
||||||
|
} else {
|
||||||
|
cdev = dev->parent;
|
||||||
|
}
|
||||||
|
|
||||||
ret = stm32_fmc2_nfc_parse_dt(dev, nfc);
|
ret = stm32_fmc2_nfc_parse_dt(dev, nfc);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -921,7 +935,7 @@ static int stm32_fmc2_nfc_probe(struct udevice *dev)
|
||||||
if (dev == cdev)
|
if (dev == cdev)
|
||||||
start_region = 1;
|
start_region = 1;
|
||||||
|
|
||||||
for (chip_cs = 0, mem_region = start_region; chip_cs < FMC2_MAX_CE;
|
for (chip_cs = 0, mem_region = start_region; chip_cs < nfc->data->max_ncs;
|
||||||
chip_cs++, mem_region += 3) {
|
chip_cs++, mem_region += 3) {
|
||||||
if (!(nfc->cs_assigned & BIT(chip_cs)))
|
if (!(nfc->cs_assigned & BIT(chip_cs)))
|
||||||
continue;
|
continue;
|
||||||
|
@ -1033,9 +1047,28 @@ static int stm32_fmc2_nfc_probe(struct udevice *dev)
|
||||||
return nand_register(0, mtd);
|
return nand_register(0, mtd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct stm32_fmc2_nfc_data stm32_fmc2_nfc_mp1_data = {
|
||||||
|
.max_ncs = 2,
|
||||||
|
.get_cdev = stm32_fmc2_nfc_get_cdev,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct stm32_fmc2_nfc_data stm32_fmc2_nfc_mp25_data = {
|
||||||
|
.max_ncs = 4,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct udevice_id stm32_fmc2_nfc_match[] = {
|
static const struct udevice_id stm32_fmc2_nfc_match[] = {
|
||||||
{ .compatible = "st,stm32mp15-fmc2" },
|
{
|
||||||
{ .compatible = "st,stm32mp1-fmc2-nfc" },
|
.compatible = "st,stm32mp15-fmc2",
|
||||||
|
.data = (ulong)&stm32_fmc2_nfc_mp1_data,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.compatible = "st,stm32mp1-fmc2-nfc",
|
||||||
|
.data = (ulong)&stm32_fmc2_nfc_mp1_data,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.compatible = "st,stm32mp25-fmc2-nfc",
|
||||||
|
.data = (ulong)&stm32_fmc2_nfc_mp25_data,
|
||||||
|
},
|
||||||
{ /* Sentinel */ }
|
{ /* Sentinel */ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ obj-$(CONFIG_DWC_ETH_QOS_IMX) += dwc_eth_qos_imx.o
|
||||||
obj-$(CONFIG_DWC_ETH_QOS_ROCKCHIP) += dwc_eth_qos_rockchip.o
|
obj-$(CONFIG_DWC_ETH_QOS_ROCKCHIP) += dwc_eth_qos_rockchip.o
|
||||||
obj-$(CONFIG_DWC_ETH_QOS_QCOM) += dwc_eth_qos_qcom.o
|
obj-$(CONFIG_DWC_ETH_QOS_QCOM) += dwc_eth_qos_qcom.o
|
||||||
obj-$(CONFIG_DWC_ETH_QOS_STARFIVE) += dwc_eth_qos_starfive.o
|
obj-$(CONFIG_DWC_ETH_QOS_STARFIVE) += dwc_eth_qos_starfive.o
|
||||||
|
obj-$(CONFIG_DWC_ETH_QOS_STM32) += dwc_eth_qos_stm32.o
|
||||||
obj-$(CONFIG_E1000) += e1000.o
|
obj-$(CONFIG_E1000) += e1000.o
|
||||||
obj-$(CONFIG_E1000_SPI) += e1000_spi.o
|
obj-$(CONFIG_E1000_SPI) += e1000_spi.o
|
||||||
obj-$(CONFIG_EEPRO100) += eepro100.o
|
obj-$(CONFIG_EEPRO100) += eepro100.o
|
||||||
|
|
|
@ -295,58 +295,6 @@ err:
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int eqos_start_clks_stm32(struct udevice *dev)
|
|
||||||
{
|
|
||||||
#ifdef CONFIG_CLK
|
|
||||||
struct eqos_priv *eqos = dev_get_priv(dev);
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
debug("%s(dev=%p):\n", __func__, dev);
|
|
||||||
|
|
||||||
ret = clk_enable(&eqos->clk_master_bus);
|
|
||||||
if (ret < 0) {
|
|
||||||
pr_err("clk_enable(clk_master_bus) failed: %d\n", ret);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = clk_enable(&eqos->clk_rx);
|
|
||||||
if (ret < 0) {
|
|
||||||
pr_err("clk_enable(clk_rx) failed: %d\n", ret);
|
|
||||||
goto err_disable_clk_master_bus;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = clk_enable(&eqos->clk_tx);
|
|
||||||
if (ret < 0) {
|
|
||||||
pr_err("clk_enable(clk_tx) failed: %d\n", ret);
|
|
||||||
goto err_disable_clk_rx;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (clk_valid(&eqos->clk_ck) && !eqos->clk_ck_enabled) {
|
|
||||||
ret = clk_enable(&eqos->clk_ck);
|
|
||||||
if (ret < 0) {
|
|
||||||
pr_err("clk_enable(clk_ck) failed: %d\n", ret);
|
|
||||||
goto err_disable_clk_tx;
|
|
||||||
}
|
|
||||||
eqos->clk_ck_enabled = true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
debug("%s: OK\n", __func__);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
#ifdef CONFIG_CLK
|
|
||||||
err_disable_clk_tx:
|
|
||||||
clk_disable(&eqos->clk_tx);
|
|
||||||
err_disable_clk_rx:
|
|
||||||
clk_disable(&eqos->clk_rx);
|
|
||||||
err_disable_clk_master_bus:
|
|
||||||
clk_disable(&eqos->clk_master_bus);
|
|
||||||
err:
|
|
||||||
debug("%s: FAILED: %d\n", __func__, ret);
|
|
||||||
return ret;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static int eqos_stop_clks_tegra186(struct udevice *dev)
|
static int eqos_stop_clks_tegra186(struct udevice *dev)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_CLK
|
#ifdef CONFIG_CLK
|
||||||
|
@ -365,22 +313,6 @@ static int eqos_stop_clks_tegra186(struct udevice *dev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int eqos_stop_clks_stm32(struct udevice *dev)
|
|
||||||
{
|
|
||||||
#ifdef CONFIG_CLK
|
|
||||||
struct eqos_priv *eqos = dev_get_priv(dev);
|
|
||||||
|
|
||||||
debug("%s(dev=%p):\n", __func__, dev);
|
|
||||||
|
|
||||||
clk_disable(&eqos->clk_tx);
|
|
||||||
clk_disable(&eqos->clk_rx);
|
|
||||||
clk_disable(&eqos->clk_master_bus);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
debug("%s: OK\n", __func__);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int eqos_start_resets_tegra186(struct udevice *dev)
|
static int eqos_start_resets_tegra186(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct eqos_priv *eqos = dev_get_priv(dev);
|
struct eqos_priv *eqos = dev_get_priv(dev);
|
||||||
|
@ -493,17 +425,6 @@ static ulong eqos_get_tick_clk_rate_tegra186(struct udevice *dev)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static ulong eqos_get_tick_clk_rate_stm32(struct udevice *dev)
|
|
||||||
{
|
|
||||||
#ifdef CONFIG_CLK
|
|
||||||
struct eqos_priv *eqos = dev_get_priv(dev);
|
|
||||||
|
|
||||||
return clk_get_rate(&eqos->clk_master_bus);
|
|
||||||
#else
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static int eqos_set_full_duplex(struct udevice *dev)
|
static int eqos_set_full_duplex(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct eqos_priv *eqos = dev_get_priv(dev);
|
struct eqos_priv *eqos = dev_get_priv(dev);
|
||||||
|
@ -1415,57 +1336,6 @@ err_free_reset_eqos:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int eqos_probe_resources_stm32(struct udevice *dev)
|
|
||||||
{
|
|
||||||
struct eqos_priv *eqos = dev_get_priv(dev);
|
|
||||||
int ret;
|
|
||||||
phy_interface_t interface;
|
|
||||||
|
|
||||||
debug("%s(dev=%p):\n", __func__, dev);
|
|
||||||
|
|
||||||
interface = eqos->config->interface(dev);
|
|
||||||
|
|
||||||
if (interface == PHY_INTERFACE_MODE_NA) {
|
|
||||||
pr_err("Invalid PHY interface\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = board_interface_eth_init(dev, interface);
|
|
||||||
if (ret)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
ret = clk_get_by_name(dev, "stmmaceth", &eqos->clk_master_bus);
|
|
||||||
if (ret) {
|
|
||||||
pr_err("clk_get_by_name(master_bus) failed: %d\n", ret);
|
|
||||||
goto err_probe;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = clk_get_by_name(dev, "mac-clk-rx", &eqos->clk_rx);
|
|
||||||
if (ret) {
|
|
||||||
pr_err("clk_get_by_name(rx) failed: %d\n", ret);
|
|
||||||
goto err_probe;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = clk_get_by_name(dev, "mac-clk-tx", &eqos->clk_tx);
|
|
||||||
if (ret) {
|
|
||||||
pr_err("clk_get_by_name(tx) failed: %d\n", ret);
|
|
||||||
goto err_probe;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get ETH_CLK clocks (optional) */
|
|
||||||
ret = clk_get_by_name(dev, "eth-ck", &eqos->clk_ck);
|
|
||||||
if (ret)
|
|
||||||
pr_warn("No phy clock provided %d", ret);
|
|
||||||
|
|
||||||
debug("%s: OK\n", __func__);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
err_probe:
|
|
||||||
|
|
||||||
debug("%s: returns %d\n", __func__, ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static phy_interface_t eqos_get_interface_tegra186(const struct udevice *dev)
|
static phy_interface_t eqos_get_interface_tegra186(const struct udevice *dev)
|
||||||
{
|
{
|
||||||
return PHY_INTERFACE_MODE_MII;
|
return PHY_INTERFACE_MODE_MII;
|
||||||
|
@ -1484,12 +1354,6 @@ static int eqos_remove_resources_tegra186(struct udevice *dev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int eqos_remove_resources_stm32(struct udevice *dev)
|
|
||||||
{
|
|
||||||
debug("%s(dev=%p):\n", __func__, dev);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int eqos_probe(struct udevice *dev)
|
static int eqos_probe(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct eqos_priv *eqos = dev_get_priv(dev);
|
struct eqos_priv *eqos = dev_get_priv(dev);
|
||||||
|
@ -1633,35 +1497,6 @@ static const struct eqos_config __maybe_unused eqos_tegra186_config = {
|
||||||
.ops = &eqos_tegra186_ops
|
.ops = &eqos_tegra186_ops
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct eqos_ops eqos_stm32_ops = {
|
|
||||||
.eqos_inval_desc = eqos_inval_desc_generic,
|
|
||||||
.eqos_flush_desc = eqos_flush_desc_generic,
|
|
||||||
.eqos_inval_buffer = eqos_inval_buffer_generic,
|
|
||||||
.eqos_flush_buffer = eqos_flush_buffer_generic,
|
|
||||||
.eqos_probe_resources = eqos_probe_resources_stm32,
|
|
||||||
.eqos_remove_resources = eqos_remove_resources_stm32,
|
|
||||||
.eqos_stop_resets = eqos_null_ops,
|
|
||||||
.eqos_start_resets = eqos_null_ops,
|
|
||||||
.eqos_stop_clks = eqos_stop_clks_stm32,
|
|
||||||
.eqos_start_clks = eqos_start_clks_stm32,
|
|
||||||
.eqos_calibrate_pads = eqos_null_ops,
|
|
||||||
.eqos_disable_calibration = eqos_null_ops,
|
|
||||||
.eqos_set_tx_clk_speed = eqos_null_ops,
|
|
||||||
.eqos_get_enetaddr = eqos_null_ops,
|
|
||||||
.eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_stm32
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct eqos_config __maybe_unused eqos_stm32_config = {
|
|
||||||
.reg_access_always_ok = false,
|
|
||||||
.mdio_wait = 10000,
|
|
||||||
.swr_wait = 50,
|
|
||||||
.config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_AV,
|
|
||||||
.config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_250_300,
|
|
||||||
.axi_bus_width = EQOS_AXI_WIDTH_64,
|
|
||||||
.interface = dev_read_phy_mode,
|
|
||||||
.ops = &eqos_stm32_ops
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct udevice_id eqos_ids[] = {
|
static const struct udevice_id eqos_ids[] = {
|
||||||
#if IS_ENABLED(CONFIG_DWC_ETH_QOS_TEGRA186)
|
#if IS_ENABLED(CONFIG_DWC_ETH_QOS_TEGRA186)
|
||||||
{
|
{
|
||||||
|
@ -1670,9 +1505,13 @@ static const struct udevice_id eqos_ids[] = {
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
#if IS_ENABLED(CONFIG_DWC_ETH_QOS_STM32)
|
#if IS_ENABLED(CONFIG_DWC_ETH_QOS_STM32)
|
||||||
|
{
|
||||||
|
.compatible = "st,stm32mp13-dwmac",
|
||||||
|
.data = (ulong)&eqos_stm32mp13_config
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.compatible = "st,stm32mp1-dwmac",
|
.compatible = "st,stm32mp1-dwmac",
|
||||||
.data = (ulong)&eqos_stm32_config
|
.data = (ulong)&eqos_stm32mp15_config
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
#if IS_ENABLED(CONFIG_DWC_ETH_QOS_IMX)
|
#if IS_ENABLED(CONFIG_DWC_ETH_QOS_IMX)
|
||||||
|
|
|
@ -290,4 +290,6 @@ int eqos_null_ops(struct udevice *dev);
|
||||||
extern struct eqos_config eqos_imx_config;
|
extern struct eqos_config eqos_imx_config;
|
||||||
extern struct eqos_config eqos_rockchip_config;
|
extern struct eqos_config eqos_rockchip_config;
|
||||||
extern struct eqos_config eqos_qcom_config;
|
extern struct eqos_config eqos_qcom_config;
|
||||||
|
extern struct eqos_config eqos_stm32mp13_config;
|
||||||
|
extern struct eqos_config eqos_stm32mp15_config;
|
||||||
extern struct eqos_config eqos_jh7110_config;
|
extern struct eqos_config eqos_jh7110_config;
|
||||||
|
|
325
drivers/net/dwc_eth_qos_stm32.c
Normal file
325
drivers/net/dwc_eth_qos_stm32.c
Normal file
|
@ -0,0 +1,325 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2024, Marek Vasut <marex@denx.de>
|
||||||
|
*
|
||||||
|
* This is code moved from drivers/net/dwc_eth_qos.c , which is:
|
||||||
|
* Copyright (c) 2016, NVIDIA CORPORATION.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <asm/cache.h>
|
||||||
|
#include <asm/gpio.h>
|
||||||
|
#include <asm/io.h>
|
||||||
|
#include <clk.h>
|
||||||
|
#include <cpu_func.h>
|
||||||
|
#include <dm.h>
|
||||||
|
#include <dm/device_compat.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <eth_phy.h>
|
||||||
|
#include <log.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <memalign.h>
|
||||||
|
#include <miiphy.h>
|
||||||
|
#include <net.h>
|
||||||
|
#include <netdev.h>
|
||||||
|
#include <phy.h>
|
||||||
|
#include <regmap.h>
|
||||||
|
#include <reset.h>
|
||||||
|
#include <syscon.h>
|
||||||
|
#include <wait_bit.h>
|
||||||
|
#include <linux/bitfield.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
|
||||||
|
#include "dwc_eth_qos.h"
|
||||||
|
|
||||||
|
/* SYSCFG registers */
|
||||||
|
#define SYSCFG_PMCSETR 0x04
|
||||||
|
#define SYSCFG_PMCCLRR_MP13 0x08
|
||||||
|
#define SYSCFG_PMCCLRR_MP15 0x44
|
||||||
|
|
||||||
|
#define SYSCFG_PMCSETR_ETH1_MASK GENMASK(23, 16)
|
||||||
|
#define SYSCFG_PMCSETR_ETH2_MASK GENMASK(31, 24)
|
||||||
|
|
||||||
|
#define SYSCFG_PMCSETR_ETH_CLK_SEL BIT(16)
|
||||||
|
#define SYSCFG_PMCSETR_ETH_REF_CLK_SEL BIT(17)
|
||||||
|
|
||||||
|
/* STM32MP15xx specific bit */
|
||||||
|
#define SYSCFG_PMCSETR_ETH_SELMII BIT(20)
|
||||||
|
|
||||||
|
#define SYSCFG_PMCSETR_ETH_SEL_MASK GENMASK(23, 21)
|
||||||
|
#define SYSCFG_PMCSETR_ETH_SEL_GMII_MII 0x0
|
||||||
|
#define SYSCFG_PMCSETR_ETH_SEL_RGMII 0x1
|
||||||
|
#define SYSCFG_PMCSETR_ETH_SEL_RMII 0x4
|
||||||
|
|
||||||
|
static ulong eqos_get_tick_clk_rate_stm32(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct eqos_priv __maybe_unused *eqos = dev_get_priv(dev);
|
||||||
|
|
||||||
|
if (!CONFIG_IS_ENABLED(CLK))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return clk_get_rate(&eqos->clk_master_bus);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int eqos_start_clks_stm32(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct eqos_priv __maybe_unused *eqos = dev_get_priv(dev);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!CONFIG_IS_ENABLED(CLK))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
dev_dbg(dev, "%s:\n", __func__);
|
||||||
|
|
||||||
|
ret = clk_enable(&eqos->clk_master_bus);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(dev, "clk_enable(clk_master_bus) failed: %d\n", ret);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = clk_enable(&eqos->clk_rx);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(dev, "clk_enable(clk_rx) failed: %d\n", ret);
|
||||||
|
goto err_disable_clk_master_bus;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = clk_enable(&eqos->clk_tx);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(dev, "clk_enable(clk_tx) failed: %d\n", ret);
|
||||||
|
goto err_disable_clk_rx;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clk_valid(&eqos->clk_ck) && !eqos->clk_ck_enabled) {
|
||||||
|
ret = clk_enable(&eqos->clk_ck);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(dev, "clk_enable(clk_ck) failed: %d\n", ret);
|
||||||
|
goto err_disable_clk_tx;
|
||||||
|
}
|
||||||
|
eqos->clk_ck_enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_dbg(dev, "%s: OK\n", __func__);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err_disable_clk_tx:
|
||||||
|
clk_disable(&eqos->clk_tx);
|
||||||
|
err_disable_clk_rx:
|
||||||
|
clk_disable(&eqos->clk_rx);
|
||||||
|
err_disable_clk_master_bus:
|
||||||
|
clk_disable(&eqos->clk_master_bus);
|
||||||
|
err:
|
||||||
|
dev_dbg(dev, "%s: FAILED: %d\n", __func__, ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int eqos_stop_clks_stm32(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct eqos_priv __maybe_unused *eqos = dev_get_priv(dev);
|
||||||
|
|
||||||
|
if (!CONFIG_IS_ENABLED(CLK))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
dev_dbg(dev, "%s:\n", __func__);
|
||||||
|
|
||||||
|
clk_disable(&eqos->clk_tx);
|
||||||
|
clk_disable(&eqos->clk_rx);
|
||||||
|
clk_disable(&eqos->clk_master_bus);
|
||||||
|
|
||||||
|
dev_dbg(dev, "%s: OK\n", __func__);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int eqos_probe_syscfg_stm32(struct udevice *dev,
|
||||||
|
phy_interface_t interface_type)
|
||||||
|
{
|
||||||
|
/* Ethernet 50MHz RMII clock selection. */
|
||||||
|
const bool eth_ref_clk_sel = dev_read_bool(dev, "st,eth-ref-clk-sel");
|
||||||
|
/* SoC is STM32MP13xx with two ethernet MACs */
|
||||||
|
const bool is_mp13 = device_is_compatible(dev, "st,stm32mp13-dwmac");
|
||||||
|
/* Gigabit Ethernet 125MHz clock selection. */
|
||||||
|
const bool eth_clk_sel = dev_read_bool(dev, "st,eth-clk-sel");
|
||||||
|
/* Ethernet clock source is RCC. */
|
||||||
|
const bool ext_phyclk = dev_read_bool(dev, "st,ext-phyclk");
|
||||||
|
struct regmap *regmap;
|
||||||
|
u32 regmap_mask;
|
||||||
|
u32 value;
|
||||||
|
|
||||||
|
regmap = syscon_regmap_lookup_by_phandle(dev, "st,syscon");
|
||||||
|
if (IS_ERR(regmap))
|
||||||
|
return PTR_ERR(regmap);
|
||||||
|
|
||||||
|
regmap_mask = dev_read_u32_index_default(dev, "st,syscon", 2,
|
||||||
|
SYSCFG_PMCSETR_ETH1_MASK);
|
||||||
|
|
||||||
|
switch (interface_type) {
|
||||||
|
case PHY_INTERFACE_MODE_MII:
|
||||||
|
dev_dbg(dev, "PHY_INTERFACE_MODE_MII\n");
|
||||||
|
value = FIELD_PREP(SYSCFG_PMCSETR_ETH_SEL_MASK,
|
||||||
|
SYSCFG_PMCSETR_ETH_SEL_GMII_MII);
|
||||||
|
/*
|
||||||
|
* STM32MP15xx supports both MII and GMII, STM32MP13xx MII only.
|
||||||
|
* SYSCFG_PMCSETR ETH_SELMII is present only on STM32MP15xx and
|
||||||
|
* acts as a selector between 0:GMII and 1:MII. As STM32MP13xx
|
||||||
|
* supports only MII, ETH_SELMII is not present.
|
||||||
|
*/
|
||||||
|
if (!is_mp13) /* Select MII mode on STM32MP15xx */
|
||||||
|
value |= SYSCFG_PMCSETR_ETH_SELMII;
|
||||||
|
break;
|
||||||
|
case PHY_INTERFACE_MODE_GMII: /* STM32MP15xx only */
|
||||||
|
dev_dbg(dev, "PHY_INTERFACE_MODE_GMII\n");
|
||||||
|
value = FIELD_PREP(SYSCFG_PMCSETR_ETH_SEL_MASK,
|
||||||
|
SYSCFG_PMCSETR_ETH_SEL_GMII_MII);
|
||||||
|
/*
|
||||||
|
* If eth_clk_sel is set, use internal ETH_CLKx clock from RCC,
|
||||||
|
* otherwise use external clock from IO pin (requires matching
|
||||||
|
* GPIO block AF setting of that pin).
|
||||||
|
*/
|
||||||
|
if (eth_clk_sel || ext_phyclk)
|
||||||
|
value |= SYSCFG_PMCSETR_ETH_CLK_SEL;
|
||||||
|
break;
|
||||||
|
case PHY_INTERFACE_MODE_RMII:
|
||||||
|
dev_dbg(dev, "PHY_INTERFACE_MODE_RMII\n");
|
||||||
|
value = FIELD_PREP(SYSCFG_PMCSETR_ETH_SEL_MASK,
|
||||||
|
SYSCFG_PMCSETR_ETH_SEL_RMII);
|
||||||
|
/*
|
||||||
|
* If eth_ref_clk_sel is set, use internal clock from RCC,
|
||||||
|
* otherwise use external clock from ETHn_RX_CLK/ETHn_REF_CLK
|
||||||
|
* IO pin (requires matching GPIO block AF setting of that
|
||||||
|
* pin).
|
||||||
|
*/
|
||||||
|
if (eth_ref_clk_sel || ext_phyclk)
|
||||||
|
value |= SYSCFG_PMCSETR_ETH_REF_CLK_SEL;
|
||||||
|
break;
|
||||||
|
case PHY_INTERFACE_MODE_RGMII:
|
||||||
|
case PHY_INTERFACE_MODE_RGMII_ID:
|
||||||
|
case PHY_INTERFACE_MODE_RGMII_RXID:
|
||||||
|
case PHY_INTERFACE_MODE_RGMII_TXID:
|
||||||
|
dev_dbg(dev, "PHY_INTERFACE_MODE_RGMII\n");
|
||||||
|
value = FIELD_PREP(SYSCFG_PMCSETR_ETH_SEL_MASK,
|
||||||
|
SYSCFG_PMCSETR_ETH_SEL_RGMII);
|
||||||
|
/*
|
||||||
|
* If eth_clk_sel is set, use internal ETH_CLKx clock from RCC,
|
||||||
|
* otherwise use external clock from ETHx_CLK125 pin (requires
|
||||||
|
* matching GPIO block AF setting of that pin).
|
||||||
|
*/
|
||||||
|
if (eth_clk_sel || ext_phyclk)
|
||||||
|
value |= SYSCFG_PMCSETR_ETH_CLK_SEL;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dev_dbg(dev, "Do not manage %d interface\n",
|
||||||
|
interface_type);
|
||||||
|
/* Do not manage others interfaces */
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Shift value at correct ethernet MAC offset in SYSCFG_PMCSETR */
|
||||||
|
value <<= ffs(regmap_mask) - ffs(SYSCFG_PMCSETR_ETH1_MASK);
|
||||||
|
|
||||||
|
/* Update PMCCLRR (clear register) */
|
||||||
|
regmap_write(regmap, is_mp13 ?
|
||||||
|
SYSCFG_PMCCLRR_MP13 : SYSCFG_PMCCLRR_MP15,
|
||||||
|
regmap_mask);
|
||||||
|
|
||||||
|
return regmap_update_bits(regmap, SYSCFG_PMCSETR, regmap_mask, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int eqos_probe_resources_stm32(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct eqos_priv *eqos = dev_get_priv(dev);
|
||||||
|
phy_interface_t interface;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
dev_dbg(dev, "%s:\n", __func__);
|
||||||
|
|
||||||
|
interface = eqos->config->interface(dev);
|
||||||
|
|
||||||
|
if (interface == PHY_INTERFACE_MODE_NA) {
|
||||||
|
dev_err(dev, "Invalid PHY interface\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = eqos_probe_syscfg_stm32(dev, interface);
|
||||||
|
if (ret)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
ret = clk_get_by_name(dev, "stmmaceth", &eqos->clk_master_bus);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(dev, "clk_get_by_name(master_bus) failed: %d\n", ret);
|
||||||
|
goto err_probe;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = clk_get_by_name(dev, "mac-clk-rx", &eqos->clk_rx);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(dev, "clk_get_by_name(rx) failed: %d\n", ret);
|
||||||
|
goto err_probe;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = clk_get_by_name(dev, "mac-clk-tx", &eqos->clk_tx);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(dev, "clk_get_by_name(tx) failed: %d\n", ret);
|
||||||
|
goto err_probe;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get ETH_CLK clocks (optional) */
|
||||||
|
ret = clk_get_by_name(dev, "eth-ck", &eqos->clk_ck);
|
||||||
|
if (ret)
|
||||||
|
dev_warn(dev, "No phy clock provided %d\n", ret);
|
||||||
|
|
||||||
|
dev_dbg(dev, "%s: OK\n", __func__);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err_probe:
|
||||||
|
|
||||||
|
dev_dbg(dev, "%s: returns %d\n", __func__, ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int eqos_remove_resources_stm32(struct udevice *dev)
|
||||||
|
{
|
||||||
|
dev_dbg(dev, "%s:\n", __func__);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct eqos_ops eqos_stm32_ops = {
|
||||||
|
.eqos_inval_desc = eqos_inval_desc_generic,
|
||||||
|
.eqos_flush_desc = eqos_flush_desc_generic,
|
||||||
|
.eqos_inval_buffer = eqos_inval_buffer_generic,
|
||||||
|
.eqos_flush_buffer = eqos_flush_buffer_generic,
|
||||||
|
.eqos_probe_resources = eqos_probe_resources_stm32,
|
||||||
|
.eqos_remove_resources = eqos_remove_resources_stm32,
|
||||||
|
.eqos_stop_resets = eqos_null_ops,
|
||||||
|
.eqos_start_resets = eqos_null_ops,
|
||||||
|
.eqos_stop_clks = eqos_stop_clks_stm32,
|
||||||
|
.eqos_start_clks = eqos_start_clks_stm32,
|
||||||
|
.eqos_calibrate_pads = eqos_null_ops,
|
||||||
|
.eqos_disable_calibration = eqos_null_ops,
|
||||||
|
.eqos_set_tx_clk_speed = eqos_null_ops,
|
||||||
|
.eqos_get_enetaddr = eqos_null_ops,
|
||||||
|
.eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_stm32
|
||||||
|
};
|
||||||
|
|
||||||
|
struct eqos_config __maybe_unused eqos_stm32mp13_config = {
|
||||||
|
.reg_access_always_ok = false,
|
||||||
|
.mdio_wait = 10000,
|
||||||
|
.swr_wait = 50,
|
||||||
|
.config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB,
|
||||||
|
.config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_250_300,
|
||||||
|
.axi_bus_width = EQOS_AXI_WIDTH_32,
|
||||||
|
.interface = dev_read_phy_mode,
|
||||||
|
.ops = &eqos_stm32_ops
|
||||||
|
};
|
||||||
|
|
||||||
|
struct eqos_config __maybe_unused eqos_stm32mp15_config = {
|
||||||
|
.reg_access_always_ok = false,
|
||||||
|
.mdio_wait = 10000,
|
||||||
|
.swr_wait = 50,
|
||||||
|
.config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_AV,
|
||||||
|
.config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_250_300,
|
||||||
|
.axi_bus_width = EQOS_AXI_WIDTH_64,
|
||||||
|
.interface = dev_read_phy_mode,
|
||||||
|
.ops = &eqos_stm32_ops
|
||||||
|
};
|
Loading…
Add table
Reference in a new issue