aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arc/lib/start.S5
-rw-r--r--arch/arm/Kconfig4
-rw-r--r--arch/arm/Makefile1
-rw-r--r--arch/arm/cpu/armv7m/config.mk2
-rw-r--r--arch/arm/cpu/armv8/generic_timer.c7
-rw-r--r--arch/arm/dts/dragonboard410c.dts14
-rw-r--r--arch/arm/dts/dragonboard820c-uboot.dtsi14
-rw-r--r--arch/arm/dts/dragonboard820c.dts1
-rw-r--r--arch/arm/dts/stm32f429-disco-u-boot.dtsi2
-rw-r--r--arch/arm/dts/uniphier-ld11.dtsi7
-rw-r--r--arch/arm/dts/uniphier-ld20-ref.dts8
-rw-r--r--arch/arm/dts/uniphier-ld20.dtsi5
-rw-r--r--arch/arm/dts/uniphier-pro4.dtsi10
-rw-r--r--arch/arm/dts/uniphier-pxs2.dtsi3
-rw-r--r--arch/arm/dts/uniphier-pxs3.dtsi8
-rw-r--r--arch/arm/lib/interrupts.c25
-rw-r--r--arch/arm/mach-at91/spl.c4
-rw-r--r--arch/arm/mach-at91/spl_at91.c2
-rw-r--r--arch/arm/mach-at91/spl_atmel.c2
-rw-r--r--arch/arm/mach-snapdragon/Kconfig6
-rw-r--r--arch/arm/mach-snapdragon/Makefile2
-rw-r--r--arch/arm/mach-snapdragon/clock-apq8016.c23
-rw-r--r--arch/arm/mach-snapdragon/clock-apq8096.c4
-rw-r--r--arch/arm/mach-snapdragon/clock-snapdragon.c17
-rw-r--r--arch/arm/mach-snapdragon/clock-snapdragon.h10
-rw-r--r--arch/arm/mach-snapdragon/include/mach/sysmap-apq8016.h1
-rw-r--r--arch/arm/mach-snapdragon/pinctrl-apq8016.c62
-rw-r--r--arch/arm/mach-snapdragon/pinctrl-snapdragon.c128
-rw-r--r--arch/arm/mach-snapdragon/pinctrl-snapdragon.h30
-rw-r--r--arch/arm/mach-stm32mp/Kconfig15
-rw-r--r--arch/arm/mach-stm32mp/Makefile8
-rw-r--r--arch/arm/mach-stm32mp/bsec.c431
-rw-r--r--arch/arm/mach-stm32mp/cpu.c95
-rw-r--r--arch/arm/mach-stm32mp/include/mach/stm32.h17
-rw-r--r--arch/arm/mach-stm32mp/spl.c3
-rw-r--r--arch/arm/mach-uniphier/board_late_init.c4
-rw-r--r--arch/sandbox/dts/sandbox.dts4
-rw-r--r--arch/sandbox/dts/sandbox64.dts4
-rw-r--r--arch/sandbox/dts/test.dts4
39 files changed, 960 insertions, 32 deletions
diff --git a/arch/arc/lib/start.S b/arch/arc/lib/start.S
index 3fb05606c7..e573ce7718 100644
--- a/arch/arc/lib/start.S
+++ b/arch/arc/lib/start.S
@@ -75,6 +75,11 @@ ENTRY(_start)
/* Initialize reserved area - note: r0 already contains address */
bl board_init_f_init_reserve
+#ifdef CONFIG_DEBUG_UART
+ /* Earliest point to set up early debug uart */
+ bl debug_uart_init
+#endif
+
/* Zero the one and only argument of "board_init_f" */
mov_s %r0, 0
bl board_init_f
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 3e05f79f63..582e84cf40 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -221,6 +221,7 @@ config CPU_V7M
select THUMB2_KERNEL
select SYS_CACHE_SHIFT_5
select SYS_ARM_MPU
+ select SYS_THUMB_BUILD
config CPU_V7R
bool
@@ -393,7 +394,7 @@ choice
config ARCH_AT91
bool "Atmel AT91"
- select SPL_BOARD_INIT if SPL
+ select SPL_BOARD_INIT if SPL && !TARGET_SMARTWEB
config TARGET_EDB93XX
bool "Support edb93xx"
@@ -1224,6 +1225,7 @@ config ARCH_STM32MP
select DM_SERIAL
select OF_CONTROL
select OF_LIBFDT
+ select MISC
select PINCTRL
select REGMAP
select SUPPORT_SPL
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 4d6d276137..680c6e8516 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -16,6 +16,7 @@ arch-$(CONFIG_CPU_ARM1136) =-march=armv5
arch-$(CONFIG_CPU_ARM1176) =-march=armv5t
arch-$(CONFIG_CPU_V7A) =$(call cc-option, -march=armv7-a, \
$(call cc-option, -march=armv7, -march=armv5))
+arch-$(CONFIG_CPU_V7M) =-march=armv7-m
arch-$(CONFIG_CPU_V7R) =-march=armv7-r
arch-$(CONFIG_ARM64) =-march=armv8-a
diff --git a/arch/arm/cpu/armv7m/config.mk b/arch/arm/cpu/armv7m/config.mk
index 4e46df5a28..f50964cfb9 100644
--- a/arch/arm/cpu/armv7m/config.mk
+++ b/arch/arm/cpu/armv7m/config.mk
@@ -3,4 +3,4 @@
# (C) Copyright 2015
# Kamil Lulko, <kamil.lulko@gmail.com>
-PLATFORM_CPPFLAGS += -march=armv7-m -mthumb -mno-unaligned-access
+PLATFORM_CPPFLAGS += -mno-unaligned-access
diff --git a/arch/arm/cpu/armv8/generic_timer.c b/arch/arm/cpu/armv8/generic_timer.c
index 303ba3c00e..bf07a706a0 100644
--- a/arch/arm/cpu/armv8/generic_timer.c
+++ b/arch/arm/cpu/armv8/generic_timer.c
@@ -61,3 +61,10 @@ unsigned long usec2ticks(unsigned long usec)
return ticks;
}
+
+ulong timer_get_boot_us(void)
+{
+ u64 val = get_ticks() * 1000000;
+
+ return val / get_tbclk();
+}
diff --git a/arch/arm/dts/dragonboard410c.dts b/arch/arm/dts/dragonboard410c.dts
index d9d5831f4f..182a865b0a 100644
--- a/arch/arm/dts/dragonboard410c.dts
+++ b/arch/arm/dts/dragonboard410c.dts
@@ -8,6 +8,7 @@
/dts-v1/;
#include "skeleton64.dtsi"
+#include <dt-bindings/pinctrl/pinctrl-snapdragon.h>
/ {
model = "Qualcomm Technologies, Inc. Dragonboard 410c";
@@ -38,6 +39,17 @@
ranges = <0x0 0x0 0x0 0xffffffff>;
compatible = "simple-bus";
+ pinctrl: qcom,tlmm@1000000 {
+ compatible = "qcom,tlmm-apq8016";
+ reg = <0x1000000 0x400000>;
+
+ blsp1_uart: uart {
+ function = "blsp1_uart";
+ pins = "GPIO_4", "GPIO_5";
+ drive-strength = <DRIVE_STRENGTH_8MA>;
+ bias-disable;
+ };
+ };
clkc: qcom,gcc@1800000 {
compatible = "qcom,gcc-apq8016";
reg = <0x1800000 0x80000>;
@@ -49,6 +61,8 @@
compatible = "qcom,msm-uartdm-v1.4";
reg = <0x78b0000 0x200>;
clock = <&clkc 4>;
+ pinctrl-names = "uart";
+ pinctrl-0 = <&blsp1_uart>;
};
soc_gpios: pinctrl@1000000 {
diff --git a/arch/arm/dts/dragonboard820c-uboot.dtsi b/arch/arm/dts/dragonboard820c-uboot.dtsi
index 88312b3fa1..97394cc5b0 100644
--- a/arch/arm/dts/dragonboard820c-uboot.dtsi
+++ b/arch/arm/dts/dragonboard820c-uboot.dtsi
@@ -5,6 +5,20 @@
* (C) Copyright 2017 Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
*/
+/ {
+ soc {
+ u-boot,dm-pre-reloc;
+
+ clock-controller@300000 {
+ u-boot,dm-pre-reloc;
+ };
+
+ serial@75b0000 {
+ u-boot,dm-pre-reloc;
+ };
+ };
+};
+
&pm8994_pon {
key_vol_down {
gpios = <&pm8994_pon 1 0>;
diff --git a/arch/arm/dts/dragonboard820c.dts b/arch/arm/dts/dragonboard820c.dts
index 7bfae1c426..7457d7b7e3 100644
--- a/arch/arm/dts/dragonboard820c.dts
+++ b/arch/arm/dts/dragonboard820c.dts
@@ -50,6 +50,7 @@
blsp2_uart1: serial@75b0000 {
compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
reg = <0x75b0000 0x1000>;
+ clock = <&gcc 4>;
};
sdhc2: sdhci@74a4900 {
diff --git a/arch/arm/dts/stm32f429-disco-u-boot.dtsi b/arch/arm/dts/stm32f429-disco-u-boot.dtsi
index 8a0f642a93..10e09508aa 100644
--- a/arch/arm/dts/stm32f429-disco-u-boot.dtsi
+++ b/arch/arm/dts/stm32f429-disco-u-boot.dtsi
@@ -37,6 +37,8 @@
clocks = <&rcc 0 STM32F4_AHB3_CLOCK(FMC)>;
pinctrl-0 = <&fmc_pins>;
pinctrl-names = "default";
+ st,syscfg = <&syscfg>;
+ st,swp_fmc = <1>;
u-boot,dm-pre-reloc;
/*
diff --git a/arch/arm/dts/uniphier-ld11.dtsi b/arch/arm/dts/uniphier-ld11.dtsi
index bf3118eca3..e7514f01fa 100644
--- a/arch/arm/dts/uniphier-ld11.dtsi
+++ b/arch/arm/dts/uniphier-ld11.dtsi
@@ -418,7 +418,7 @@
mmc-ddr-1_8v;
mmc-hs200-1_8v;
mmc-pwrseq = <&emmc_pwrseq>;
- cdns,phy-input-delay-legacy = <4>;
+ cdns,phy-input-delay-legacy = <9>;
cdns,phy-input-delay-mmc-highspeed = <2>;
cdns,phy-input-delay-mmc-ddr = <3>;
cdns,phy-dll-delay-sdclk = <21>;
@@ -553,10 +553,13 @@
status = "disabled";
reg = <0x65000000 0x8500>;
interrupts = <0 66 4>;
+ clock-names = "ether";
clocks = <&sys_clk 6>;
+ reset-names = "ether";
resets = <&sys_rst 6>;
- phy-mode = "rmii";
+ phy-mode = "internal";
local-mac-address = [00 00 00 00 00 00];
+ socionext,syscon-phy-mode = <&soc_glue 0>;
mdio: mdio {
#address-cells = <1>;
diff --git a/arch/arm/dts/uniphier-ld20-ref.dts b/arch/arm/dts/uniphier-ld20-ref.dts
index 2c1a92fafb..440c2e6a63 100644
--- a/arch/arm/dts/uniphier-ld20-ref.dts
+++ b/arch/arm/dts/uniphier-ld20-ref.dts
@@ -67,3 +67,11 @@
reg = <0>;
};
};
+
+&pinctrl_ether_rgmii {
+ tx {
+ pins = "RGMII_TXCLK", "RGMII_TXD0", "RGMII_TXD1",
+ "RGMII_TXD2", "RGMII_TXD3", "RGMII_TXCTL";
+ drive-strength = <9>;
+ };
+};
diff --git a/arch/arm/dts/uniphier-ld20.dtsi b/arch/arm/dts/uniphier-ld20.dtsi
index b993df8a34..31bc124dfc 100644
--- a/arch/arm/dts/uniphier-ld20.dtsi
+++ b/arch/arm/dts/uniphier-ld20.dtsi
@@ -523,7 +523,7 @@
mmc-ddr-1_8v;
mmc-hs200-1_8v;
mmc-pwrseq = <&emmc_pwrseq>;
- cdns,phy-input-delay-legacy = <4>;
+ cdns,phy-input-delay-legacy = <9>;
cdns,phy-input-delay-mmc-highspeed = <2>;
cdns,phy-input-delay-mmc-ddr = <3>;
cdns,phy-dll-delay-sdclk = <21>;
@@ -622,10 +622,13 @@
interrupts = <0 66 4>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ether_rgmii>;
+ clock-names = "ether";
clocks = <&sys_clk 6>;
+ reset-names = "ether";
resets = <&sys_rst 6>;
phy-mode = "rgmii";
local-mac-address = [00 00 00 00 00 00];
+ socionext,syscon-phy-mode = <&soc_glue 0>;
mdio: mdio {
#address-cells = <1>;
diff --git a/arch/arm/dts/uniphier-pro4.dtsi b/arch/arm/dts/uniphier-pro4.dtsi
index 25c4b4f8fc..0004863589 100644
--- a/arch/arm/dts/uniphier-pro4.dtsi
+++ b/arch/arm/dts/uniphier-pro4.dtsi
@@ -342,7 +342,7 @@
has-transaction-translator;
};
- soc-glue@5f800000 {
+ soc_glue: soc-glue@5f800000 {
compatible = "socionext,uniphier-pro4-soc-glue",
"simple-mfd", "syscon";
reg = <0x5f800000 0x2000>;
@@ -427,10 +427,14 @@
interrupts = <0 66 4>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ether_rgmii>;
- clocks = <&sys_clk 6>;
- resets = <&sys_rst 6>;
+ clock-names = "gio", "ether", "ether-gb", "ether-phy";
+ clocks = <&sys_clk 12>, <&sys_clk 6>, <&sys_clk 7>,
+ <&sys_clk 10>;
+ reset-names = "gio", "ether";
+ resets = <&sys_rst 12>, <&sys_rst 6>;
phy-mode = "rgmii";
local-mac-address = [00 00 00 00 00 00];
+ socionext,syscon-phy-mode = <&soc_glue 0>;
mdio: mdio {
#address-cells = <1>;
diff --git a/arch/arm/dts/uniphier-pxs2.dtsi b/arch/arm/dts/uniphier-pxs2.dtsi
index 9760f79e7c..20f3935107 100644
--- a/arch/arm/dts/uniphier-pxs2.dtsi
+++ b/arch/arm/dts/uniphier-pxs2.dtsi
@@ -545,10 +545,13 @@
interrupts = <0 66 4>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ether_rgmii>;
+ clock-names = "ether";
clocks = <&sys_clk 6>;
+ reset-names = "ether";
resets = <&sys_rst 6>;
phy-mode = "rgmii";
local-mac-address = [00 00 00 00 00 00];
+ socionext,syscon-phy-mode = <&soc_glue 0>;
mdio: mdio {
#address-cells = <1>;
diff --git a/arch/arm/dts/uniphier-pxs3.dtsi b/arch/arm/dts/uniphier-pxs3.dtsi
index d4c458a211..ae867cbb0a 100644
--- a/arch/arm/dts/uniphier-pxs3.dtsi
+++ b/arch/arm/dts/uniphier-pxs3.dtsi
@@ -338,7 +338,7 @@
mmc-ddr-1_8v;
mmc-hs200-1_8v;
mmc-pwrseq = <&emmc_pwrseq>;
- cdns,phy-input-delay-legacy = <4>;
+ cdns,phy-input-delay-legacy = <9>;
cdns,phy-input-delay-mmc-highspeed = <2>;
cdns,phy-input-delay-mmc-ddr = <3>;
cdns,phy-dll-delay-sdclk = <21>;
@@ -430,10 +430,13 @@
interrupts = <0 66 4>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ether_rgmii>;
+ clock-names = "ether";
clocks = <&sys_clk 6>;
+ reset-names = "ether";
resets = <&sys_rst 6>;
phy-mode = "rgmii";
local-mac-address = [00 00 00 00 00 00];
+ socionext,syscon-phy-mode = <&soc_glue 0>;
mdio0: mdio {
#address-cells = <1>;
@@ -448,10 +451,13 @@
interrupts = <0 67 4>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ether1_rgmii>;
+ clock-names = "ether";
clocks = <&sys_clk 7>;
+ reset-names = "ether";
resets = <&sys_rst 7>;
phy-mode = "rgmii";
local-mac-address = [00 00 00 00 00 00];
+ socionext,syscon-phy-mode = <&soc_glue 1>;
mdio1: mdio {
#address-cells = <1>;
diff --git a/arch/arm/lib/interrupts.c b/arch/arm/lib/interrupts.c
index 28ba3f14f3..930b25ccb8 100644
--- a/arch/arm/lib/interrupts.c
+++ b/arch/arm/lib/interrupts.c
@@ -56,6 +56,30 @@ static void show_efi_loaded_images(struct pt_regs *regs)
efi_print_image_infos((void *)instruction_pointer(regs));
}
+static void dump_instr(struct pt_regs *regs)
+{
+ unsigned long addr = instruction_pointer(regs);
+ const int thumb = thumb_mode(regs);
+ const int width = thumb ? 4 : 8;
+ int i;
+
+ if (thumb)
+ addr &= ~1L;
+ else
+ addr &= ~3L;
+ printf("Code: ");
+ for (i = -4; i < 1 + !!thumb; i++) {
+ unsigned int val;
+
+ if (thumb)
+ val = ((u16 *)addr)[i];
+ else
+ val = ((u32 *)addr)[i];
+ printf(i == 0 ? "(%0*x) " : "%0*x ", width, val);
+ }
+ printf("\n");
+}
+
void show_regs (struct pt_regs *regs)
{
unsigned long __maybe_unused flags;
@@ -96,6 +120,7 @@ void show_regs (struct pt_regs *regs)
fast_interrupts_enabled (regs) ? "on" : "off",
processor_modes[processor_mode (regs)],
thumb_mode (regs) ? " (T)" : "");
+ dump_instr(regs);
}
/* fixup PC to point to the instruction leading to the exception */
diff --git a/arch/arm/mach-at91/spl.c b/arch/arm/mach-at91/spl.c
index 7cba3825e7..8bfb2a452b 100644
--- a/arch/arm/mach-at91/spl.c
+++ b/arch/arm/mach-at91/spl.c
@@ -11,9 +11,7 @@
#include <asm/arch/clk.h>
#include <spl.h>
-#if defined(CONFIG_AT91SAM9_WATCHDOG)
-void at91_disable_wdt(void) { }
-#else
+#if !defined(CONFIG_AT91SAM9_WATCHDOG)
void at91_disable_wdt(void)
{
struct at91_wdt *wdt = (struct at91_wdt *)ATMEL_BASE_WDT;
diff --git a/arch/arm/mach-at91/spl_at91.c b/arch/arm/mach-at91/spl_at91.c
index d701c3586d..8c368042a6 100644
--- a/arch/arm/mach-at91/spl_at91.c
+++ b/arch/arm/mach-at91/spl_at91.c
@@ -76,7 +76,9 @@ void __weak spl_board_init(void)
void board_init_f(ulong dummy)
{
lowlevel_clock_init();
+#if !defined(CONFIG_AT91SAM9_WATCHDOG)
at91_disable_wdt();
+#endif
/*
* At this stage the main oscillator is supposed to be enabled
diff --git a/arch/arm/mach-at91/spl_atmel.c b/arch/arm/mach-at91/spl_atmel.c
index 11db1e5f8c..597ff8c036 100644
--- a/arch/arm/mach-at91/spl_atmel.c
+++ b/arch/arm/mach-at91/spl_atmel.c
@@ -98,8 +98,10 @@ void board_init_f(ulong dummy)
configure_2nd_sram_as_l2_cache();
#endif
+#if !defined(CONFIG_AT91SAM9_WATCHDOG)
/* disable watchdog */
at91_disable_wdt();
+#endif
/* PMC configuration */
at91_pmc_init();
diff --git a/arch/arm/mach-snapdragon/Kconfig b/arch/arm/mach-snapdragon/Kconfig
index d55dc1aaa1..bfd99db6e2 100644
--- a/arch/arm/mach-snapdragon/Kconfig
+++ b/arch/arm/mach-snapdragon/Kconfig
@@ -3,6 +3,12 @@ if ARCH_SNAPDRAGON
config SYS_SOC
default "snapdragon"
+config SYS_MALLOC_F_LEN
+ default 0x2000
+
+config SPL_SYS_MALLOC_F_LEN
+ default 0x2000
+
choice
prompt "Snapdragon board select"
diff --git a/arch/arm/mach-snapdragon/Makefile b/arch/arm/mach-snapdragon/Makefile
index 1c23dc52cf..1d35fea912 100644
--- a/arch/arm/mach-snapdragon/Makefile
+++ b/arch/arm/mach-snapdragon/Makefile
@@ -6,4 +6,6 @@ obj-$(CONFIG_TARGET_DRAGONBOARD820C) += clock-apq8096.o
obj-$(CONFIG_TARGET_DRAGONBOARD820C) += sysmap-apq8096.o
obj-$(CONFIG_TARGET_DRAGONBOARD410C) += clock-apq8016.o
obj-$(CONFIG_TARGET_DRAGONBOARD410C) += sysmap-apq8016.o
+obj-$(CONFIG_TARGET_DRAGONBOARD410C) += pinctrl-apq8016.o
+obj-$(CONFIG_TARGET_DRAGONBOARD410C) += pinctrl-snapdragon.o
obj-y += clock-snapdragon.o
diff --git a/arch/arm/mach-snapdragon/clock-apq8016.c b/arch/arm/mach-snapdragon/clock-apq8016.c
index 9c0cc1c22c..6e4a0ccb90 100644
--- a/arch/arm/mach-snapdragon/clock-apq8016.c
+++ b/arch/arm/mach-snapdragon/clock-apq8016.c
@@ -17,7 +17,6 @@
/* GPLL0 clock control registers */
#define GPLL0_STATUS_ACTIVE BIT(17)
-#define APCS_GPLL_ENA_VOTE_GPLL0 BIT(0)
static const struct bcr_regs sdc_regs[] = {
{
@@ -36,11 +35,17 @@ static const struct bcr_regs sdc_regs[] = {
}
};
-static struct gpll0_ctrl gpll0_ctrl = {
+static struct pll_vote_clk gpll0_vote_clk = {
.status = GPLL0_STATUS,
.status_bit = GPLL0_STATUS_ACTIVE,
.ena_vote = APCS_GPLL_ENA_VOTE,
- .vote_bit = APCS_GPLL_ENA_VOTE_GPLL0,
+ .vote_bit = BIT(0),
+};
+
+static struct vote_clk gcc_blsp1_ahb_clk = {
+ .cbcr_reg = BLSP1_AHB_CBCR,
+ .ena_vote = APCS_CLOCK_BRANCH_ENA_VOTE,
+ .vote_bit = BIT(10),
};
/* SDHCI */
@@ -55,7 +60,7 @@ static int clk_init_sdc(struct msm_clk_priv *priv, int slot, uint rate)
/* 800Mhz/div, gpll0 */
clk_rcg_set_rate_mnd(priv->base, &sdc_regs[slot], div, 0, 0,
CFG_CLK_SRC_GPLL0);
- clk_enable_gpll0(priv->base, &gpll0_ctrl);
+ clk_enable_gpll0(priv->base, &gpll0_vote_clk);
clk_enable_cbc(priv->base + SDCC_APPS_CBCR(slot));
return rate;
@@ -72,12 +77,16 @@ static const struct bcr_regs uart2_regs = {
/* UART: 115200 */
static int clk_init_uart(struct msm_clk_priv *priv)
{
- /* Enable iface clk */
- clk_enable_cbc(priv->base + BLSP1_AHB_CBCR);
+ /* Enable AHB clock */
+ clk_enable_vote_clk(priv->base, &gcc_blsp1_ahb_clk);
+
/* 7372800 uart block clock @ GPLL0 */
clk_rcg_set_rate_mnd(priv->base, &uart2_regs, 1, 144, 15625,
CFG_CLK_SRC_GPLL0);
- clk_enable_gpll0(priv->base, &gpll0_ctrl);
+
+ /* Vote for gpll0 clock */
+ clk_enable_gpll0(priv->base, &gpll0_vote_clk);
+
/* Enable core clk */
clk_enable_cbc(priv->base + BLSP1_UART2_APPS_CBCR);
diff --git a/arch/arm/mach-snapdragon/clock-apq8096.c b/arch/arm/mach-snapdragon/clock-apq8096.c
index 008649a4c6..628c38785b 100644
--- a/arch/arm/mach-snapdragon/clock-apq8096.c
+++ b/arch/arm/mach-snapdragon/clock-apq8096.c
@@ -27,7 +27,7 @@ static const struct bcr_regs sdc_regs = {
.D = SDCC2_D,
};
-static const struct gpll0_ctrl gpll0_ctrl = {
+static const struct pll_vote_clk gpll0_vote_clk = {
.status = GPLL0_STATUS,
.status_bit = GPLL0_STATUS_ACTIVE,
.ena_vote = APCS_GPLL_ENA_VOTE,
@@ -41,7 +41,7 @@ static int clk_init_sdc(struct msm_clk_priv *priv, uint rate)
clk_enable_cbc(priv->base + SDCC2_AHB_CBCR);
clk_rcg_set_rate_mnd(priv->base, &sdc_regs, div, 0, 0,
CFG_CLK_SRC_GPLL0);
- clk_enable_gpll0(priv->base, &gpll0_ctrl);
+ clk_enable_gpll0(priv->base, &gpll0_vote_clk);
clk_enable_cbc(priv->base + SDCC2_APPS_CBCR);
return rate;
diff --git a/arch/arm/mach-snapdragon/clock-snapdragon.c b/arch/arm/mach-snapdragon/clock-snapdragon.c
index f738f57043..85526186c6 100644
--- a/arch/arm/mach-snapdragon/clock-snapdragon.c
+++ b/arch/arm/mach-snapdragon/clock-snapdragon.c
@@ -30,7 +30,7 @@ void clk_enable_cbc(phys_addr_t cbcr)
;
}
-void clk_enable_gpll0(phys_addr_t base, const struct gpll0_ctrl *gpll0)
+void clk_enable_gpll0(phys_addr_t base, const struct pll_vote_clk *gpll0)
{
if (readl(base + gpll0->status) & gpll0->status_bit)
return; /* clock already enabled */
@@ -41,6 +41,21 @@ void clk_enable_gpll0(phys_addr_t base, const struct gpll0_ctrl *gpll0)
;
}
+#define BRANCH_ON_VAL (0)
+#define BRANCH_NOC_FSM_ON_VAL BIT(29)
+#define BRANCH_CHECK_MASK GENMASK(31, 28)
+
+void clk_enable_vote_clk(phys_addr_t base, const struct vote_clk *vclk)
+{
+ u32 val;
+
+ setbits_le32(base + vclk->ena_vote, vclk->vote_bit);
+ do {
+ val = readl(base + vclk->cbcr_reg);
+ val &= BRANCH_CHECK_MASK;
+ } while ((val != BRANCH_ON_VAL) && (val != BRANCH_NOC_FSM_ON_VAL));
+}
+
#define APPS_CMD_RGCR_UPDATE BIT(0)
/* Update clock command via CMD_RGCR */
diff --git a/arch/arm/mach-snapdragon/clock-snapdragon.h b/arch/arm/mach-snapdragon/clock-snapdragon.h
index 2cff4f8a06..58fab40a2e 100644
--- a/arch/arm/mach-snapdragon/clock-snapdragon.h
+++ b/arch/arm/mach-snapdragon/clock-snapdragon.h
@@ -11,13 +11,18 @@
#define CFG_CLK_SRC_GPLL0 (1 << 8)
#define CFG_CLK_SRC_MASK (7 << 8)
-struct gpll0_ctrl {
+struct pll_vote_clk {
uintptr_t status;
int status_bit;
uintptr_t ena_vote;
int vote_bit;
};
+struct vote_clk {
+ uintptr_t cbcr_reg;
+ uintptr_t ena_vote;
+ int vote_bit;
+};
struct bcr_regs {
uintptr_t cfg_rcgr;
uintptr_t cmd_rcgr;
@@ -30,9 +35,10 @@ struct msm_clk_priv {
phys_addr_t base;
};
-void clk_enable_gpll0(phys_addr_t base, const struct gpll0_ctrl *pll0);
+void clk_enable_gpll0(phys_addr_t base, const struct pll_vote_clk *gpll0);
void clk_bcr_update(phys_addr_t apps_cmd_rgcr);
void clk_enable_cbc(phys_addr_t cbcr);
+void clk_enable_vote_clk(phys_addr_t base, const struct vote_clk *vclk);
void clk_rcg_set_rate_mnd(phys_addr_t base, const struct bcr_regs *regs,
int div, int m, int n, int source);
diff --git a/arch/arm/mach-snapdragon/include/mach/sysmap-apq8016.h b/arch/arm/mach-snapdragon/include/mach/sysmap-apq8016.h
index ae784387fa..520e2e6bd7 100644
--- a/arch/arm/mach-snapdragon/include/mach/sysmap-apq8016.h
+++ b/arch/arm/mach-snapdragon/include/mach/sysmap-apq8016.h
@@ -13,6 +13,7 @@
/* Clocks: (from CLK_CTL_BASE) */
#define GPLL0_STATUS (0x2101C)
#define APCS_GPLL_ENA_VOTE (0x45000)
+#define APCS_CLOCK_BRANCH_ENA_VOTE (0x45004)
#define SDCC_BCR(n) ((n * 0x1000) + 0x41000)
#define SDCC_CMD_RCGR(n) ((n * 0x1000) + 0x41004)
diff --git a/arch/arm/mach-snapdragon/pinctrl-apq8016.c b/arch/arm/mach-snapdragon/pinctrl-apq8016.c
new file mode 100644
index 0000000000..bdb755d0e4
--- /dev/null
+++ b/arch/arm/mach-snapdragon/pinctrl-apq8016.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Qualcomm APQ8016 pinctrl
+ *
+ * (C) Copyright 2018 Ramon Fried <ramon.fried@gmail.com>
+ *
+ */
+
+#include "pinctrl-snapdragon.h"
+#include <common.h>
+
+#define MAX_PIN_NAME_LEN 32
+static char pin_name[MAX_PIN_NAME_LEN];
+static const char * const msm_pinctrl_pins[] = {
+ "SDC1_CLK",
+ "SDC1_CMD",
+ "SDC1_DATA",
+ "SDC2_CLK",
+ "SDC2_CMD",
+ "SDC2_DATA",
+ "QDSD_CLK",
+ "QDSD_CMD",
+ "QDSD_DATA0",
+ "QDSD_DATA1",
+ "QDSD_DATA2",
+ "QDSD_DATA3",
+};
+
+static const struct pinctrl_function msm_pinctrl_functions[] = {
+ {"blsp1_uart", 2},
+};
+
+static const char *apq8016_get_function_name(struct udevice *dev,
+ unsigned int selector)
+{
+ return msm_pinctrl_functions[selector].name;
+}
+
+static const char *apq8016_get_pin_name(struct udevice *dev,
+ unsigned int selector)
+{
+ if (selector < 130) {
+ snprintf(pin_name, MAX_PIN_NAME_LEN, "GPIO_%u", selector);
+ return pin_name;
+ } else {
+ return msm_pinctrl_pins[selector - 130];
+ }
+}
+
+static unsigned int apq8016_get_function_mux(unsigned int selector)
+{
+ return msm_pinctrl_functions[selector].val;
+}
+
+struct msm_pinctrl_data apq8016_data = {
+ .pin_count = 140,
+ .functions_count = ARRAY_SIZE(msm_pinctrl_functions),
+ .get_function_name = apq8016_get_function_name,
+ .get_function_mux = apq8016_get_function_mux,
+ .get_pin_name = apq8016_get_pin_name,
+};
+
diff --git a/arch/arm/mach-snapdragon/pinctrl-snapdragon.c b/arch/arm/mach-snapdragon/pinctrl-snapdragon.c
new file mode 100644
index 0000000000..5365ccdb70
--- /dev/null
+++ b/arch/arm/mach-snapdragon/pinctrl-snapdragon.c
@@ -0,0 +1,128 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * TLMM driver for Qualcomm APQ8016, APQ8096
+ *
+ * (C) Copyright 2018 Ramon Fried <ramon.fried@gmail.com>
+ *
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <dm/pinctrl.h>
+#include "pinctrl-snapdragon.h"
+
+struct msm_pinctrl_priv {
+ phys_addr_t base;
+ struct msm_pinctrl_data *data;
+};
+
+#define GPIO_CONFIG_OFFSET(x) ((x) * 0x1000)
+#define TLMM_GPIO_PULL_MASK GENMASK(1, 0)
+#define TLMM_FUNC_SEL_MASK GENMASK(5, 2)
+#define TLMM_DRV_STRENGTH_MASK GENMASK(8, 6)
+#define TLMM_GPIO_ENABLE BIT(9)
+
+static const struct pinconf_param msm_conf_params[] = {
+ { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 3 },
+ { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
+};
+
+static int msm_get_functions_count(struct udevice *dev)
+{
+ struct msm_pinctrl_priv *priv = dev_get_priv(dev);
+
+ return priv->data->functions_count;
+}
+
+static int msm_get_pins_count(struct udevice *dev)
+{
+ struct msm_pinctrl_priv *priv = dev_get_priv(dev);
+
+ return priv->data->pin_count;
+}
+
+static const char *msm_get_function_name(struct udevice *dev,
+ unsigned int selector)
+{
+ struct msm_pinctrl_priv *priv = dev_get_priv(dev);
+
+ return priv->data->get_function_name(dev, selector);
+}
+
+static int msm_pinctrl_probe(struct udevice *dev)
+{
+ struct msm_pinctrl_priv *priv = dev_get_priv(dev);
+
+ priv->base = devfdt_get_addr(dev);
+ priv->data = (struct msm_pinctrl_data *)dev->driver_data;
+
+ return priv->base == FDT_ADDR_T_NONE ? -EINVAL : 0;
+}
+
+static const char *msm_get_pin_name(struct udevice *dev, unsigned int selector)
+{
+ struct msm_pinctrl_priv *priv = dev_get_priv(dev);
+
+ return priv->data->get_pin_name(dev, selector);
+}
+
+static int msm_pinmux_set(struct udevice *dev, unsigned int pin_selector,
+ unsigned int func_selector)
+{
+ struct msm_pinctrl_priv *priv = dev_get_priv(dev);
+
+ clrsetbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector),
+ TLMM_FUNC_SEL_MASK | TLMM_GPIO_ENABLE,
+ priv->data->get_function_mux(func_selector) << 2);
+ return 0;
+}
+
+static int msm_pinconf_set(struct udevice *dev, unsigned int pin_selector,
+ unsigned int param, unsigned int argument)
+{
+ struct msm_pinctrl_priv *priv = dev_get_priv(dev);
+
+ switch (param) {
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ clrsetbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector),
+ TLMM_DRV_STRENGTH_MASK, argument << 6);
+ break;
+ case PIN_CONFIG_BIAS_DISABLE:
+ clrbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector),
+ TLMM_GPIO_PULL_MASK);
+ break;
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
+static struct pinctrl_ops msm_pinctrl_ops = {
+ .get_pins_count = msm_get_pins_count,
+ .get_pin_name = msm_get_pin_name,
+ .set_state = pinctrl_generic_set_state,
+ .pinmux_set = msm_pinmux_set,
+ .pinconf_num_params = ARRAY_SIZE(msm_conf_params),
+ .pinconf_params = msm_conf_params,
+ .pinconf_set = msm_pinconf_set,
+ .get_functions_count = msm_get_functions_count,
+ .get_function_name = msm_get_function_name,
+};
+
+static const struct udevice_id msm_pinctrl_ids[] = {
+ { .compatible = "qcom,tlmm-msm8916", .data = (ulong)&apq8016_data },
+ { .compatible = "qcom,tlmm-apq8016", .data = (ulong)&apq8016_data },
+ { }
+};
+
+U_BOOT_DRIVER(pinctrl_snapdraon) = {
+ .name = "pinctrl_msm",
+ .id = UCLASS_PINCTRL,
+ .of_match = msm_pinctrl_ids,
+ .priv_auto_alloc_size = sizeof(struct msm_pinctrl_priv),
+ .ops = &msm_pinctrl_ops,
+ .probe = msm_pinctrl_probe,
+};
diff --git a/arch/arm/mach-snapdragon/pinctrl-snapdragon.h b/arch/arm/mach-snapdragon/pinctrl-snapdragon.h
new file mode 100644
index 0000000000..c47d988af4
--- /dev/null
+++ b/arch/arm/mach-snapdragon/pinctrl-snapdragon.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Qualcomm Pin control
+ *
+ * (C) Copyright 2018 Ramon Fried <ramon.fried@gmail.com>
+ *
+ */
+#ifndef _PINCTRL_SNAPDRAGON_H
+#define _PINCTRL_SNAPDRAGON_H
+
+#include <common.h>
+
+struct msm_pinctrl_data {
+ int pin_count;
+ int functions_count;
+ const char *(*get_function_name)(struct udevice *dev,
+ unsigned int selector);
+ unsigned int (*get_function_mux)(unsigned int selector);
+ const char *(*get_pin_name)(struct udevice *dev,
+ unsigned int selector);
+};
+
+struct pinctrl_function {
+ const char *name;
+ int val;
+};
+
+extern struct msm_pinctrl_data apq8016_data;
+
+#endif
diff --git a/arch/arm/mach-stm32mp/Kconfig b/arch/arm/mach-stm32mp/Kconfig
index ccbeb5c388..abceeded24 100644
--- a/arch/arm/mach-stm32mp/Kconfig
+++ b/arch/arm/mach-stm32mp/Kconfig
@@ -54,4 +54,19 @@ config SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION_MMC2
source "board/st/stm32mp1/Kconfig"
+# currently activated for debug / should be deactivated for real product
+if DEBUG_UART
+
+config DEBUG_UART_BOARD_INIT
+ default y
+
+# debug on UART4 by default
+config DEBUG_UART_BASE
+ default 0x40010000
+
+# clock source is HSI on reset
+config DEBUG_UART_CLOCK
+ default 64000000
+endif
+
endif
diff --git a/arch/arm/mach-stm32mp/Makefile b/arch/arm/mach-stm32mp/Makefile
index 08ee642d90..f59ced5ee1 100644
--- a/arch/arm/mach-stm32mp/Makefile
+++ b/arch/arm/mach-stm32mp/Makefile
@@ -1,4 +1,4 @@
-# SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (C) 2018, STMicroelectronics - All Rights Reserved
#
@@ -7,6 +7,10 @@ obj-y += cpu.o
obj-y += dram_init.o
obj-y += syscon.o
-obj-$(CONFIG_SPL_BUILD) += spl.o
+ifdef CONFIG_SPL_BUILD
+obj-y += spl.o
+else
+obj-y += bsec.o
+endif
obj-$(CONFIG_ARMV7_PSCI) += psci.o
obj-$(CONFIG_$(SPL_)DM_REGULATOR) += pwr_regulator.o
diff --git a/arch/arm/mach-stm32mp/bsec.c b/arch/arm/mach-stm32mp/bsec.c
new file mode 100644
index 0000000000..0e152efc04
--- /dev/null
+++ b/arch/arm/mach-stm32mp/bsec.c
@@ -0,0 +1,431 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <misc.h>
+#include <asm/io.h>
+#include <linux/iopoll.h>
+
+#define BSEC_OTP_MAX_VALUE 95
+
+#define BSEC_TIMEOUT_US 10000
+
+/* BSEC REGISTER OFFSET (base relative) */
+#define BSEC_OTP_CONF_OFF 0x000
+#define BSEC_OTP_CTRL_OFF 0x004
+#define BSEC_OTP_WRDATA_OFF 0x008
+#define BSEC_OTP_STATUS_OFF 0x00C
+#define BSEC_OTP_LOCK_OFF 0x010
+#define BSEC_DISTURBED_OFF 0x01C
+#define BSEC_ERROR_OFF 0x034
+#define BSEC_SPLOCK_OFF 0x064 /* Program safmem sticky lock */
+#define BSEC_SWLOCK_OFF 0x07C /* write in OTP sticky lock */
+#define BSEC_SRLOCK_OFF 0x094 /* shadowing sticky lock */
+#define BSEC_OTP_DATA_OFF 0x200
+
+/* BSEC_CONFIGURATION Register MASK */
+#define BSEC_CONF_POWER_UP 0x001
+
+/* BSEC_CONTROL Register */
+#define BSEC_READ 0x000
+#define BSEC_WRITE 0x100
+
+/* LOCK Register */
+#define OTP_LOCK_MASK 0x1F
+#define OTP_LOCK_BANK_SHIFT 0x05
+#define OTP_LOCK_BIT_MASK 0x01
+
+/* STATUS Register */
+#define BSEC_MODE_BUSY_MASK 0x08
+#define BSEC_MODE_PROGFAIL_MASK 0x10
+#define BSEC_MODE_PWR_MASK 0x20
+
+/*
+ * OTP Lock services definition
+ * Value must corresponding to the bit number in the register
+ */
+#define BSEC_LOCK_PROGRAM 0x04
+
+/**
+ * bsec_check_error() - Check status of one otp
+ * @base: base address of bsec IP
+ * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
+ * Return: 0 if no error, -EAGAIN or -ENOTSUPP
+ */
+static u32 bsec_check_error(u32 base, u32 otp)
+{
+ u32 bit;
+ u32 bank;
+
+ bit = 1 << (otp & OTP_LOCK_MASK);
+ bank = ((otp >> OTP_LOCK_BANK_SHIFT) & OTP_LOCK_MASK) * sizeof(u32);
+
+ if (readl(base + BSEC_DISTURBED_OFF + bank) & bit)
+ return -EAGAIN;
+ else if (readl(base + BSEC_ERROR_OFF + bank) & bit)
+ return -ENOTSUPP;
+
+ return 0;
+}
+
+/**
+ * bsec_lock() - manage lock for each type SR/SP/SW
+ * @address: address of bsec IP register
+ * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
+ * Return: true if locked else false
+ */
+static bool bsec_read_lock(u32 address, u32 otp)
+{
+ u32 bit;
+ u32 bank;
+
+ bit = 1 << (otp & OTP_LOCK_MASK);
+ bank = ((otp >> OTP_LOCK_BANK_SHIFT) & OTP_LOCK_MASK) * sizeof(u32);
+
+ return !!(readl(address + bank) & bit);
+}
+
+/**
+ * bsec_read_SR_lock() - read SR lock (Shadowing)
+ * @base: base address of bsec IP
+ * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
+ * Return: true if locked else false
+ */
+static bool bsec_read_SR_lock(u32 base, u32 otp)
+{
+ return bsec_read_lock(base + BSEC_SRLOCK_OFF, otp);
+}
+
+/**
+ * bsec_read_SP_lock() - read SP lock (program Lock)
+ * @base: base address of bsec IP
+ * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
+ * Return: true if locked else false
+ */
+static bool bsec_read_SP_lock(u32 base, u32 otp)
+{
+ return bsec_read_lock(base + BSEC_SPLOCK_OFF, otp);
+}
+
+/**
+ * bsec_SW_lock() - manage SW lock (Write in Shadow)
+ * @base: base address of bsec IP
+ * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
+ * Return: true if locked else false
+ */
+static bool bsec_read_SW_lock(u32 base, u32 otp)
+{
+ return bsec_read_lock(base + BSEC_SWLOCK_OFF, otp);
+}
+
+/**
+ * bsec_power_safmem() - Activate or deactivate safmem power
+ * @base: base address of bsec IP
+ * @power: true to power up , false to power down
+ * Return: 0 if succeed
+ */
+static int bsec_power_safmem(u32 base, bool power)
+{
+ u32 val;
+ u32 mask;
+
+ if (power) {
+ setbits_le32(base + BSEC_OTP_CONF_OFF, BSEC_CONF_POWER_UP);
+ mask = BSEC_MODE_PWR_MASK;
+ } else {
+ clrbits_le32(base + BSEC_OTP_CONF_OFF, BSEC_CONF_POWER_UP);
+ mask = 0;
+ }
+
+ /* waiting loop */
+ return readl_poll_timeout(base + BSEC_OTP_STATUS_OFF,
+ val, (val & BSEC_MODE_PWR_MASK) == mask,
+ BSEC_TIMEOUT_US);
+}
+
+/**
+ * bsec_shadow_register() - copy safmen otp to bsec data
+ * @base: base address of bsec IP
+ * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
+ * Return: 0 if no error
+ */
+static int bsec_shadow_register(u32 base, u32 otp)
+{
+ u32 val;
+ int ret;
+ bool power_up = false;
+
+ /* check if shadowing of otp is locked */
+ if (bsec_read_SR_lock(base, otp))
+ pr_debug("bsec : OTP %d is locked and refreshed with 0\n", otp);
+
+ /* check if safemem is power up */
+ val = readl(base + BSEC_OTP_STATUS_OFF);
+ if (!(val & BSEC_MODE_PWR_MASK)) {
+ ret = bsec_power_safmem(base, true);
+ if (ret)
+ return ret;
+ power_up = 1;
+ }
+ /* set BSEC_OTP_CTRL_OFF with the otp value*/
+ writel(otp | BSEC_READ, base + BSEC_OTP_CTRL_OFF);
+
+ /* check otp status*/
+ ret = readl_poll_timeout(base + BSEC_OTP_STATUS_OFF,
+ val, (val & BSEC_MODE_BUSY_MASK) == 0,
+ BSEC_TIMEOUT_US);
+ if (ret)
+ return ret;
+
+ ret = bsec_check_error(base, otp);
+
+ if (power_up)
+ bsec_power_safmem(base, false);
+
+ return ret;
+}
+
+/**
+ * bsec_read_shadow() - read an otp data value from shadow
+ * @base: base address of bsec IP
+ * @val: read value
+ * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
+ * Return: 0 if no error
+ */
+static int bsec_read_shadow(u32 base, u32 *val, u32 otp)
+{
+ *val = readl(base + BSEC_OTP_DATA_OFF + otp * sizeof(u32));
+
+ return bsec_check_error(base, otp);
+}
+
+/**
+ * bsec_write_shadow() - write value in BSEC data register in shadow
+ * @base: base address of bsec IP
+ * @val: value to write
+ * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
+ * Return: 0 if no error
+ */
+static int bsec_write_shadow(u32 base, u32 val, u32 otp)
+{
+ /* check if programming of otp is locked */
+ if (bsec_read_SW_lock(base, otp))
+ pr_debug("bsec : OTP %d is lock, write will be ignore\n", otp);
+
+ writel(val, base + BSEC_OTP_DATA_OFF + otp * sizeof(u32));
+
+ return bsec_check_error(base, otp);
+}
+
+/**
+ * bsec_program_otp() - program a bit in SAFMEM
+ * @base: base address of bsec IP
+ * @val: value to program
+ * @otp: otp number (0 - BSEC_OTP_MAX_VALUE)
+ * after the function the otp data is not refreshed in shadow
+ * Return: 0 if no error
+ */
+static int bsec_program_otp(long base, u32 val, u32 otp)
+{
+ u32 ret;
+ bool power_up = false;
+
+ if (bsec_read_SP_lock(base, otp))
+ pr_debug("bsec : OTP %d locked, prog will be ignore\n", otp);
+
+ if (readl(base + BSEC_OTP_LOCK_OFF) & (1 << BSEC_LOCK_PROGRAM))
+ pr_debug("bsec : Global lock, prog will be ignore\n");
+
+ /* check if safemem is power up */
+ if (!(readl(base + BSEC_OTP_STATUS_OFF) & BSEC_MODE_PWR_MASK)) {
+ ret = bsec_power_safmem(base, true);
+ if (ret)
+ return ret;
+
+ power_up = true;
+ }
+ /* set value in write register*/
+ writel(val, base + BSEC_OTP_WRDATA_OFF);
+
+ /* set BSEC_OTP_CTRL_OFF with the otp value */
+ writel(otp | BSEC_WRITE, base + BSEC_OTP_CTRL_OFF);
+
+ /* check otp status*/
+ ret = readl_poll_timeout(base + BSEC_OTP_STATUS_OFF,
+ val, (val & BSEC_MODE_BUSY_MASK) == 0,
+ BSEC_TIMEOUT_US);
+ if (ret)
+ return ret;
+
+ if (val & BSEC_MODE_PROGFAIL_MASK)
+ ret = -EACCES;
+ else
+ ret = bsec_check_error(base, otp);
+
+ if (power_up)
+ bsec_power_safmem(base, false);
+
+ return ret;
+}
+
+/* BSEC MISC driver *******************************************************/
+struct stm32mp_bsec_platdata {
+ u32 base;
+};
+
+static int stm32mp_bsec_read_otp(struct udevice *dev, u32 *val, u32 otp)
+{
+ struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
+ u32 tmp_data = 0;
+ int ret;
+
+ /* read current shadow value */
+ ret = bsec_read_shadow(plat->base, &tmp_data, otp);
+ if (ret)
+ return ret;
+
+ /* copy otp in shadow */
+ ret = bsec_shadow_register(plat->base, otp);
+ if (ret)
+ return ret;
+
+ ret = bsec_read_shadow(plat->base, val, otp);
+ if (ret)
+ return ret;
+
+ /* restore shadow value */
+ ret = bsec_write_shadow(plat->base, tmp_data, otp);
+ return ret;
+}
+
+static int stm32mp_bsec_read_shadow(struct udevice *dev, u32 *val, u32 otp)
+{
+ struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
+
+ return bsec_read_shadow(plat->base, val, otp);
+}
+
+static int stm32mp_bsec_write_otp(struct udevice *dev, u32 val, u32 otp)
+{
+ struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
+
+ return bsec_program_otp(plat->base, val, otp);
+}
+
+static int stm32mp_bsec_write_shadow(struct udevice *dev, u32 val, u32 otp)
+{
+ struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
+
+ return bsec_write_shadow(plat->base, val, otp);
+}
+
+static int stm32mp_bsec_read(struct udevice *dev, int offset,
+ void *buf, int size)
+{
+ int ret;
+ int i;
+ bool shadow = true;
+ int nb_otp = size / sizeof(u32);
+ int otp;
+
+ if (offset >= STM32_BSEC_OTP_OFFSET) {
+ offset -= STM32_BSEC_OTP_OFFSET;
+ shadow = false;
+ }
+ otp = offset / sizeof(u32);
+
+ if (otp < 0 || (otp + nb_otp - 1) > BSEC_OTP_MAX_VALUE) {
+ dev_err(dev, "wrong value for otp, max value : %i\n",
+ BSEC_OTP_MAX_VALUE);
+ return -EINVAL;
+ }
+
+ for (i = otp; i < (otp + nb_otp); i++) {
+ u32 *addr = &((u32 *)buf)[i - otp];
+
+ if (shadow)
+ ret = stm32mp_bsec_read_shadow(dev, addr, i);
+ else
+ ret = stm32mp_bsec_read_otp(dev, addr, i);
+
+ if (ret)
+ break;
+ }
+ return ret;
+}
+
+static int stm32mp_bsec_write(struct udevice *dev, int offset,
+ const void *buf, int size)
+{
+ int ret = 0;
+ int i;
+ bool shadow = true;
+ int nb_otp = size / sizeof(u32);
+ int otp;
+
+ if (offset >= STM32_BSEC_OTP_OFFSET) {
+ offset -= STM32_BSEC_OTP_OFFSET;
+ shadow = false;
+ }
+ otp = offset / sizeof(u32);
+
+ if (otp < 0 || (otp + nb_otp - 1) > BSEC_OTP_MAX_VALUE) {
+ dev_err(dev, "wrong value for otp, max value : %d\n",
+ BSEC_OTP_MAX_VALUE);
+ return -EINVAL;
+ }
+
+ for (i = otp; i < otp + nb_otp; i++) {
+ u32 *val = &((u32 *)buf)[i - otp];
+
+ if (shadow)
+ ret = stm32mp_bsec_write_shadow(dev, *val, i);
+ else
+ ret = stm32mp_bsec_write_otp(dev, *val, i);
+ if (ret)
+ break;
+ }
+ return ret;
+}
+
+static const struct misc_ops stm32mp_bsec_ops = {
+ .read = stm32mp_bsec_read,
+ .write = stm32mp_bsec_write,
+};
+
+static int stm32mp_bsec_ofdata_to_platdata(struct udevice *dev)
+{
+ struct stm32mp_bsec_platdata *plat = dev_get_platdata(dev);
+
+ plat->base = (u32)dev_read_addr_ptr(dev);
+
+ return 0;
+}
+
+static const struct udevice_id stm32mp_bsec_ids[] = {
+ { .compatible = "st,stm32mp-bsec" },
+ {}
+};
+
+U_BOOT_DRIVER(stm32mp_bsec) = {
+ .name = "stm32mp_bsec",
+ .id = UCLASS_MISC,
+ .of_match = stm32mp_bsec_ids,
+ .ofdata_to_platdata = stm32mp_bsec_ofdata_to_platdata,
+ .platdata_auto_alloc_size = sizeof(struct stm32mp_bsec_platdata),
+ .ops = &stm32mp_bsec_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+/* bsec IP is not present in device tee, manage IP address by platdata */
+static struct stm32mp_bsec_platdata stm32_bsec_platdata = {
+ .base = STM32_BSEC_BASE,
+};
+
+U_BOOT_DEVICE(stm32mp_bsec) = {
+ .name = "stm32mp_bsec",
+ .platdata = &stm32_bsec_platdata,
+};
diff --git a/arch/arm/mach-stm32mp/cpu.c b/arch/arm/mach-stm32mp/cpu.c
index dfcbbd2314..0e01f8e613 100644
--- a/arch/arm/mach-stm32mp/cpu.c
+++ b/arch/arm/mach-stm32mp/cpu.c
@@ -4,9 +4,13 @@
*/
#include <common.h>
#include <clk.h>
+#include <debug_uart.h>
+#include <environment.h>
+#include <misc.h>
#include <asm/io.h>
#include <asm/arch/stm32.h>
#include <asm/arch/sys_proto.h>
+#include <dm/device.h>
#include <dm/uclass.h>
/* RCC register */
@@ -50,6 +54,10 @@
#define BOOTROM_INSTANCE_MASK GENMASK(31, 16)
#define BOOTROM_INSTANCE_SHIFT 16
+/* BSEC OTP index */
+#define BSEC_OTP_SERIAL 13
+#define BSEC_OTP_MAC 57
+
#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)
static void security_init(void)
{
@@ -152,6 +160,8 @@ static u32 get_bootmode(void)
*/
int arch_cpu_init(void)
{
+ u32 boot_mode;
+
/* early armv7 timer init: needed for polling */
timer_init();
@@ -160,8 +170,17 @@ int arch_cpu_init(void)
security_init();
#endif
+
/* get bootmode from BootRom context: saved in TAMP register */
- get_bootmode();
+ boot_mode = get_bootmode();
+
+ if ((boot_mode & TAMP_BOOT_DEVICE_MASK) == BOOT_SERIAL_UART)
+ gd->flags |= GD_FLG_SILENT | GD_FLG_DISABLE_CONSOLE;
+#if defined(CONFIG_DEBUG_UART) && \
+ (!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD))
+ else
+ debug_uart_init();
+#endif
return 0;
}
@@ -262,9 +281,83 @@ static void setup_boot_mode(void)
}
}
+/*
+ * If there is no MAC address in the environment, then it will be initialized
+ * (silently) from the value in the OTP.
+ */
+static int setup_mac_address(void)
+{
+#if defined(CONFIG_NET)
+ int ret;
+ int i;
+ u32 otp[2];
+ uchar enetaddr[6];
+ struct udevice *dev;
+
+ /* MAC already in environment */
+ if (eth_env_get_enetaddr("ethaddr", enetaddr))
+ return 0;
+
+ ret = uclass_get_device_by_driver(UCLASS_MISC,
+ DM_GET_DRIVER(stm32mp_bsec),
+ &dev);
+ if (ret)
+ return ret;
+
+ ret = misc_read(dev, BSEC_OTP_MAC * 4 + STM32_BSEC_OTP_OFFSET,
+ otp, sizeof(otp));
+ if (ret)
+ return ret;
+
+ for (i = 0; i < 6; i++)
+ enetaddr[i] = ((uint8_t *)&otp)[i];
+
+ if (!is_valid_ethaddr(enetaddr)) {
+ pr_err("invalid MAC address in OTP %pM", enetaddr);
+ return -EINVAL;
+ }
+ pr_debug("OTP MAC address = %pM\n", enetaddr);
+ ret = !eth_env_set_enetaddr("ethaddr", enetaddr);
+ if (!ret)
+ pr_err("Failed to set mac address %pM from OTP: %d\n",
+ enetaddr, ret);
+#endif
+
+ return 0;
+}
+
+static int setup_serial_number(void)
+{
+ char serial_string[25];
+ u32 otp[3] = {0, 0, 0 };
+ struct udevice *dev;
+ int ret;
+
+ if (env_get("serial#"))
+ return 0;
+
+ ret = uclass_get_device_by_driver(UCLASS_MISC,
+ DM_GET_DRIVER(stm32mp_bsec),
+ &dev);
+ if (ret)
+ return ret;
+
+ ret = misc_read(dev, BSEC_OTP_SERIAL * 4 + STM32_BSEC_OTP_OFFSET,
+ otp, sizeof(otp));
+ if (ret)
+ return ret;
+
+ sprintf(serial_string, "%08x%08x%08x", otp[0], otp[1], otp[2]);
+ env_set("serial#", serial_string);
+
+ return 0;
+}
+
int arch_misc_init(void)
{
setup_boot_mode();
+ setup_mac_address();
+ setup_serial_number();
return 0;
}
diff --git a/arch/arm/mach-stm32mp/include/mach/stm32.h b/arch/arm/mach-stm32mp/include/mach/stm32.h
index a8142013b0..5d0bdca178 100644
--- a/arch/arm/mach-stm32mp/include/mach/stm32.h
+++ b/arch/arm/mach-stm32mp/include/mach/stm32.h
@@ -13,10 +13,23 @@
#define STM32_RCC_BASE 0x50000000
#define STM32_PWR_BASE 0x50001000
#define STM32_DBGMCU_BASE 0x50081000
+#define STM32_BSEC_BASE 0x5C005000
#define STM32_TZC_BASE 0x5C006000
#define STM32_ETZPC_BASE 0x5C007000
#define STM32_TAMP_BASE 0x5C00A000
+#ifdef CONFIG_DEBUG_UART_BASE
+/* hardcoded value can be only used for DEBUG UART */
+#define STM32_USART1_BASE 0x5C000000
+#define STM32_USART2_BASE 0x4000E000
+#define STM32_USART3_BASE 0x4000F000
+#define STM32_UART4_BASE 0x40010000
+#define STM32_UART5_BASE 0x40011000
+#define STM32_USART6_BASE 0x44003000
+#define STM32_UART7_BASE 0x40018000
+#define STM32_UART8_BASE 0x40019000
+#endif
+
#define STM32_SYSRAM_BASE 0x2FFC0000
#define STM32_SYSRAM_SIZE SZ_256K
@@ -83,5 +96,9 @@ enum boot_device {
#define TAMP_BOOT_DEVICE_MASK GENMASK(7, 4)
#define TAMP_BOOT_INSTANCE_MASK GENMASK(3, 0)
+/* offset used for BSEC driver: misc_read and misc_write */
+#define STM32_BSEC_SHADOW_OFFSET 0x0
+#define STM32_BSEC_OTP_OFFSET 0x80000000
+
#endif /* __ASSEMBLY__*/
#endif /* _MACH_STM32_H_ */
diff --git a/arch/arm/mach-stm32mp/spl.c b/arch/arm/mach-stm32mp/spl.c
index b56f0c5381..790973e8b6 100644
--- a/arch/arm/mach-stm32mp/spl.c
+++ b/arch/arm/mach-stm32mp/spl.c
@@ -14,9 +14,6 @@ u32 spl_boot_device(void)
boot_mode = (readl(TAMP_BOOT_CONTEXT) & TAMP_BOOT_MODE_MASK) >>
TAMP_BOOT_MODE_SHIFT;
- clrsetbits_le32(TAMP_BOOT_CONTEXT,
- TAMP_BOOT_MODE_MASK,
- boot_mode << TAMP_BOOT_MODE_SHIFT);
switch (boot_mode) {
case BOOT_FLASH_SD_1:
diff --git a/arch/arm/mach-uniphier/board_late_init.c b/arch/arm/mach-uniphier/board_late_init.c
index 9dff3f16a0..6a995728d4 100644
--- a/arch/arm/mach-uniphier/board_late_init.c
+++ b/arch/arm/mach-uniphier/board_late_init.c
@@ -38,7 +38,7 @@ static int uniphier_set_fdt_file(void)
char dtb_name[256];
int buf_len = sizeof(dtb_name);
- if (env_get("fdt_file"))
+ if (env_get("fdtfile"))
return 0; /* do nothing if it is already set */
compat = fdt_stringlist_get(gd->fdt_blob, 0, "compatible", 0, NULL);
@@ -56,7 +56,7 @@ static int uniphier_set_fdt_file(void)
strncat(dtb_name, ".dtb", buf_len);
- return env_set("fdt_file", dtb_name);
+ return env_set("fdtfile", dtb_name);
}
int board_late_init(void)
diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts
index 86680a6b11..0ea2452742 100644
--- a/arch/sandbox/dts/sandbox.dts
+++ b/arch/sandbox/dts/sandbox.dts
@@ -242,6 +242,10 @@
compatible = "google,sandbox-tpm";
};
+ tpm2 {
+ compatible = "sandbox,tpm2";
+ };
+
triangle {
compatible = "demo-shape";
colour = "cyan";
diff --git a/arch/sandbox/dts/sandbox64.dts b/arch/sandbox/dts/sandbox64.dts
index 8f707b47db..48e420e721 100644
--- a/arch/sandbox/dts/sandbox64.dts
+++ b/arch/sandbox/dts/sandbox64.dts
@@ -242,6 +242,10 @@
compatible = "google,sandbox-tpm";
};
+ tpm2 {
+ compatible = "sandbox,tpm2";
+ };
+
triangle {
compatible = "demo-shape";
colour = "cyan";
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 5a0f187d8b..f2e5d65dad 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -422,6 +422,10 @@
clock-frequency = <1000000>;
};
+ tpm2 {
+ compatible = "sandbox,tpm2";
+ };
+
uart0: serial {
compatible = "sandbox,serial";
u-boot,dm-pre-reloc;