diff options
author | Tom Rini <trini@konsulko.com> | 2022-04-21 11:44:54 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2022-04-21 11:44:54 -0400 |
commit | e50f66e364be80e02dd0834b84b830f3aade82ea (patch) | |
tree | cd44087cdc8180618f31faae2eb49598cb3ec5c5 /arch/arm | |
parent | feeacc7ec70560c535c0eb7a4d847ad17cacbeff (diff) | |
parent | ac47bd230cd3430589c63f81e57b3d30e0abe0db (diff) | |
download | u-boot-e50f66e364be80e02dd0834b84b830f3aade82ea.zip u-boot-e50f66e364be80e02dd0834b84b830f3aade82ea.tar.gz u-boot-e50f66e364be80e02dd0834b84b830f3aade82ea.tar.bz2 |
Merge https://source.denx.de/u-boot/custodians/u-boot-marvellWIP/21Apr2022
- mrvl_uart.sh: Remove script (Pali)
- Fix Espressobin build for configs where ENV is not in SPI (Rogier)
- mvebu: a37xx: Add support for reading OTP (Pali)
- mvebu: uDPU: Ethernet fixes and misc DT and defconfig changes (Robert)
- mvebu: Add support for reading LD0 and LD1 eFuse (Pali)
- kwboot: Replace fstat()+st_size by lseek()+SEEK_END (Pali)
- mvebu: turris_omnia: Enable CONFIG_CMD_FUSE (Pali)
- arm: Add CONFIG_SPL_SYS_NO_VECTOR_TABLE used on 32bit MVEBU (Pali)
- mvebu: a37xx: Add support for writing Security OTP values (Pali)
- mvebu: turris: Misc enhancements and cleanups / fixes (Pali)
- Sheevaplug : Use Marvell uclass mvgbe and PHY driver for Ethernet (Tony)
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/Kconfig | 4 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/start.S | 4 | ||||
-rw-r--r-- | arch/arm/dts/armada-3720-uDPU-u-boot.dtsi | 24 | ||||
-rw-r--r-- | arch/arm/dts/armada-3720-uDPU.dts | 21 | ||||
-rw-r--r-- | arch/arm/dts/armada-385-turris-omnia-u-boot.dtsi | 4 | ||||
-rw-r--r-- | arch/arm/lib/vectors.S | 6 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/Kconfig | 2 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/Makefile | 3 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/armada3700/Makefile | 3 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/armada3700/efuse.c | 217 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/armada3700/mbox.c | 83 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/efuse.c | 28 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/include/mach/efuse.h | 5 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/include/mach/mbox.h | 40 | ||||
-rw-r--r-- | arch/arm/mach-omap2/Kconfig | 1 |
15 files changed, 432 insertions, 13 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 342652e..9470122 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -58,6 +58,10 @@ config SYS_INIT_SP_BSS_OFFSET that the early malloc region, global data (gd), and early stack usage do not overlap any appended DTB. +config SPL_SYS_NO_VECTOR_TABLE + depends on SPL + bool + config LINUX_KERNEL_IMAGE_HEADER depends on ARM64 bool diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S index af87a54..3703612 100644 --- a/arch/arm/cpu/armv7/start.S +++ b/arch/arm/cpu/armv7/start.S @@ -97,12 +97,10 @@ switch_to_hypervisor_ret: orr r0, r0, #0xc0 @ disable FIQ and IRQ msr cpsr,r0 +#if !CONFIG_IS_ENABLED(SYS_NO_VECTOR_TABLE) /* * Setup vector: - * (OMAP4 spl TEXT_BASE is not 32 byte aligned. - * Continue to use ROM code vector only in OMAP4 spl) */ -#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD)) /* Set V=0 in CP15 SCTLR register - for VBAR to point to vector */ mrc p15, 0, r0, c1, c0, 0 @ Read CP15 SCTLR Register bic r0, #CR_V @ V = 0 diff --git a/arch/arm/dts/armada-3720-uDPU-u-boot.dtsi b/arch/arm/dts/armada-3720-uDPU-u-boot.dtsi index cf8ae44..47d87d4 100644 --- a/arch/arm/dts/armada-3720-uDPU-u-boot.dtsi +++ b/arch/arm/dts/armada-3720-uDPU-u-boot.dtsi @@ -31,3 +31,27 @@ &sdhci0 { u-boot,dm-pre-reloc; }; + +&pinctrl_sb { + sfp_pin: sfp-pin { + groups = "pcie1_clkreq"; + function = "gpio"; + }; +}; + +ð0 { + pinctrl-names = "default"; + pinctrl-0 = <&sfp_pin>; + + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +ð1 { + fixed-link { + speed = <1000>; + full-duplex; + }; +}; diff --git a/arch/arm/dts/armada-3720-uDPU.dts b/arch/arm/dts/armada-3720-uDPU.dts index 95d46e8..1f534c0 100644 --- a/arch/arm/dts/armada-3720-uDPU.dts +++ b/arch/arm/dts/armada-3720-uDPU.dts @@ -99,7 +99,7 @@ pinctrl-names = "default"; pinctrl-0 = <&spi_quad_pins>; - m25p80@0 { + spi-flash@0 { compatible = "jedec,spi-nor"; reg = <0>; spi-max-frequency = <54000000>; @@ -108,10 +108,15 @@ compatible = "fixed-partitions"; #address-cells = <1>; #size-cells = <1>; - /* only bootloader is located on the SPI */ + partition@0 { - label = "uboot"; - reg = <0 0x400000>; + label = "firmware"; + reg = <0x0 0x180000>; + }; + + partition@180000 { + label = "u-boot-env"; + reg = <0x180000 0x10000>; }; }; }; @@ -148,15 +153,15 @@ scl-gpios = <&gpionb 2 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; sda-gpios = <&gpionb 3 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; - lm75@48 { + nct375@48 { status = "okay"; - compatible = "lm75"; + compatible = "ti,tmp75c"; reg = <0x48>; }; - lm75@49 { + nct375@49 { status = "okay"; - compatible = "lm75"; + compatible = "ti,tmp75c"; reg = <0x49>; }; }; diff --git a/arch/arm/dts/armada-385-turris-omnia-u-boot.dtsi b/arch/arm/dts/armada-385-turris-omnia-u-boot.dtsi index 3ff76c9..64ebe2c 100644 --- a/arch/arm/dts/armada-385-turris-omnia-u-boot.dtsi +++ b/arch/arm/dts/armada-385-turris-omnia-u-boot.dtsi @@ -29,7 +29,7 @@ u-boot,dm-pre-reloc; /* ATSHA204A at address 0x64 */ - atsha204a@64 { + crypto@64 { u-boot,dm-pre-reloc; compatible = "atmel,atsha204a"; reg = <0x64>; @@ -38,6 +38,7 @@ }; }; +#ifdef CONFIG_ENV_IS_IN_SPI_FLASH &spi0 { u-boot,dm-pre-reloc; @@ -56,6 +57,7 @@ }; }; }; +#endif &uart0 { u-boot,dm-pre-reloc; diff --git a/arch/arm/lib/vectors.S b/arch/arm/lib/vectors.S index 56f3681..a54c84b 100644 --- a/arch/arm/lib/vectors.S +++ b/arch/arm/lib/vectors.S @@ -24,6 +24,7 @@ #else b reset #endif +#if !CONFIG_IS_ENABLED(SYS_NO_VECTOR_TABLE) ldr pc, _undefined_instruction ldr pc, _software_interrupt ldr pc, _prefetch_abort @@ -31,6 +32,7 @@ ldr pc, _not_used ldr pc, _irq ldr pc, _fiq +#endif .endm @@ -87,6 +89,7 @@ _start: ARM_VECTORS #endif /* !defined(CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK) */ +#if !CONFIG_IS_ENABLED(SYS_NO_VECTOR_TABLE) /* ************************************************************************* * @@ -118,6 +121,7 @@ _irq: .word irq _fiq: .word fiq .balignl 16,0xdeadbeef +#endif /* ************************************************************************* @@ -131,6 +135,7 @@ _fiq: .word fiq #ifdef CONFIG_SPL_BUILD +#if !CONFIG_IS_ENABLED(SYS_NO_VECTOR_TABLE) .align 5 undefined_instruction: software_interrupt: @@ -141,6 +146,7 @@ irq: fiq: 1: b 1b /* hang and never return */ +#endif #else /* !CONFIG_SPL_BUILD */ diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index 21d9db2..a3f273f 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -15,6 +15,7 @@ config ARMADA_32BIT select SPL_SIMPLE_BUS if SPL select SUPPORT_SPL select TRANSLATION_OFFSET + select SPL_SYS_NO_VECTOR_TABLE if SPL config ARMADA_64BIT bool @@ -44,6 +45,7 @@ config ARMADA_XP config ARMADA_3700 bool select ARM64 + select HAVE_MVEBU_EFUSE # Armada 7K and 8K are very similar - use only one Kconfig symbol for both config ARMADA_8K diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile index a5a2087..1b45188 100644 --- a/arch/arm/mach-mvebu/Makefile +++ b/arch/arm/mach-mvebu/Makefile @@ -27,7 +27,10 @@ obj-$(CONFIG_ARMADA_375) += ../../../drivers/ddr/marvell/axp/xor.o obj-$(CONFIG_ARMADA_38X) += ../../../drivers/ddr/marvell/a38x/xor.o obj-$(CONFIG_ARMADA_XP) += ../../../drivers/ddr/marvell/axp/xor.o obj-$(CONFIG_ARMADA_MSYS) += ../../../drivers/ddr/marvell/axp/xor.o + +ifdef CONFIG_ARMADA_38X obj-$(CONFIG_MVEBU_EFUSE) += efuse.o +endif extra-y += kwbimage.cfg diff --git a/arch/arm/mach-mvebu/armada3700/Makefile b/arch/arm/mach-mvebu/armada3700/Makefile index 031b3e8..98350a4 100644 --- a/arch/arm/mach-mvebu/armada3700/Makefile +++ b/arch/arm/mach-mvebu/armada3700/Makefile @@ -2,4 +2,5 @@ # # Copyright (C) 2016 Stefan Roese <sr@denx.de> -obj-y = cpu.o +obj-y = cpu.o mbox.o +obj-$(CONFIG_MVEBU_EFUSE) += efuse.o diff --git a/arch/arm/mach-mvebu/armada3700/efuse.c b/arch/arm/mach-mvebu/armada3700/efuse.c new file mode 100644 index 0000000..07d5f39 --- /dev/null +++ b/arch/arm/mach-mvebu/armada3700/efuse.c @@ -0,0 +1,217 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) 2017 Marvell International Ltd. + * (C) 2021 Pali Rohár <pali@kernel.org> + */ + +#include <config.h> +#include <common.h> +#include <asm/io.h> +#include <linux/delay.h> +#include <mach/mbox.h> +#include <mach/soc.h> + +#define OTP_NB_REG_BASE ((void __iomem *)MVEBU_REGISTER(0x12600)) +#define OTP_SB_REG_BASE ((void __iomem *)MVEBU_REGISTER(0x1A200)) + +#define OTP_CONTROL_OFF 0x00 +#define OTP_MODE_BIT BIT(15) +#define OTP_RPTR_RST_BIT BIT(14) +#define OTP_POR_B_BIT BIT(13) +#define OTP_PRDT_BIT BIT(3) +#define OTP_READ_PORT_OFF 0x04 +#define OTP_READ_POINTER_OFF 0x08 +#define OTP_PTR_INC_BIT BIT(8) + +static void otp_read_parallel(void __iomem *base, u32 *data, u32 count) +{ + u32 regval; + + /* 1. Clear OTP_MODE_NB to parallel mode */ + regval = readl(base + OTP_CONTROL_OFF); + regval &= ~OTP_MODE_BIT; + writel(regval, base + OTP_CONTROL_OFF); + + /* 2. Set OTP_POR_B_NB enter normal operation */ + regval = readl(base + OTP_CONTROL_OFF); + regval |= OTP_POR_B_BIT; + writel(regval, base + OTP_CONTROL_OFF); + + /* 3. Set OTP_PTR_INC_NB to auto-increment pointer after each read */ + regval = readl(base + OTP_READ_POINTER_OFF); + regval |= OTP_PTR_INC_BIT; + writel(regval, base + OTP_READ_POINTER_OFF); + + /* 4. Set OTP_RPTR_RST_NB, then clear the same field */ + regval = readl(base + OTP_CONTROL_OFF); + regval |= OTP_RPTR_RST_BIT; + writel(regval, base + OTP_CONTROL_OFF); + + regval = readl(base + OTP_CONTROL_OFF); + regval &= ~OTP_RPTR_RST_BIT; + writel(regval, base + OTP_CONTROL_OFF); + + /* 5. Toggle OTP_PRDT_NB + * a. Set OTP_PRDT_NB to 1. + * b. Clear OTP_PRDT_NB to 0. + * c. Wait for a minimum of 100 ns. + * d. Set OTP_PRDT_NB to 1 + */ + regval = readl(base + OTP_CONTROL_OFF); + regval |= OTP_PRDT_BIT; + writel(regval, base + OTP_CONTROL_OFF); + + regval = readl(base + OTP_CONTROL_OFF); + regval &= ~OTP_PRDT_BIT; + writel(regval, base + OTP_CONTROL_OFF); + + ndelay(100); + + regval = readl(base + OTP_CONTROL_OFF); + regval |= OTP_PRDT_BIT; + writel(regval, base + OTP_CONTROL_OFF); + + while (count-- > 0) { + /* 6. Read the content of OTP 32-bits at a time */ + ndelay(100000); + *(data++) = readl(base + OTP_READ_PORT_OFF); + } +} + +static int rwtm_otp_read(u8 row, u32 word, u32 *data) +{ + u32 out[3]; + u32 in[2]; + int res = -EINVAL; + + if (word < 2) { + /* + * MBOX_CMD_OTP_READ_32B command is supported by Marvell + * fuse.bin firmware and also by new CZ.NIC wtmi firmware. + * This command returns raw bits without ECC corrections. + * It does not provide access to the lock bit. + */ + in[0] = row; + in[1] = word * 32; + res = mbox_do_cmd(MBOX_CMD_OTP_READ_32B, in, 2, out, 1); + if (!res) + *data = out[0]; + } else if (word == 2) { + /* + * MBOX_CMD_OTP_READ command is supported only by new CZ.NIC + * wtmi firmware and provides access to all bits, including + * lock bit without doing ECC corrections. For compatibility + * with Marvell fuse.bin firmware, use this command only for + * accessing lock bit. + */ + in[0] = row; + res = mbox_do_cmd(MBOX_CMD_OTP_READ, in, 1, out, 3); + if (!res) + *data = out[2]; + } + + return res; +} + +static int rwtm_otp_write(u8 row, u32 word, u32 data) +{ + u32 in[4]; + int res = -EINVAL; + + if (word < 2) { + /* + * MBOX_CMD_OTP_WRITE_32B command is supported by Marvell + * fuse.bin firmware and also by new CZ.NIC wtmi firmware. + * This command writes only selected bits to OTP and does + * not calculate ECC bits. It does not allow to write the + * lock bit. + */ + in[0] = row; + in[1] = word * 32; + in[2] = data; + res = mbox_do_cmd(MBOX_CMD_OTP_WRITE_32B, in, 3, NULL, 0); + } else if (word == 2 && !(data & ~0x1)) { + /* + * MBOX_CMD_OTP_WRITE command is supported only by new CZ.NIC + * wtmi firmware and allows to write any bit to OTP, including + * the lock bit. It does not calculate or write ECC bits too. + * For compatibility with Marvell fuse.bin firmware, use this + * command only for writing the lock bit. + */ + in[0] = row; + in[1] = 0; + in[2] = 0; + in[3] = data; + res = mbox_do_cmd(MBOX_CMD_OTP_WRITE, in, 4, NULL, 0); + } + + return res; +} + +/* + * Banks 0-43 are used for accessing Security OTP (44 rows with 67 bits via 44 banks and words 0-2) + * Bank 44 is used for accessing North Bridge OTP (69 bits via words 0-2) + * Bank 45 is used for accessing South Bridge OTP (97 bits via words 0-3) + */ + +#define RWTM_ROWS 44 +#define RWTM_MAX_BANK (RWTM_ROWS - 1) +#define RWTM_ROW_WORDS 3 +#define OTP_NB_BANK RWTM_ROWS +#define OTP_NB_WORDS 3 +#define OTP_SB_BANK (RWTM_ROWS + 1) +#define OTP_SB_WORDS 4 + +int fuse_read(u32 bank, u32 word, u32 *val) +{ + if (bank <= RWTM_MAX_BANK) { + if (word >= RWTM_ROW_WORDS) + return -EINVAL; + return rwtm_otp_read(bank, word, val); + } else if (bank == OTP_NB_BANK) { + u32 data[OTP_NB_WORDS]; + if (word >= OTP_NB_WORDS) + return -EINVAL; + otp_read_parallel(OTP_NB_REG_BASE, data, OTP_NB_WORDS); + *val = data[word]; + return 0; + } else if (bank == OTP_SB_BANK) { + u32 data[OTP_SB_WORDS]; + if (word >= OTP_SB_WORDS) + return -EINVAL; + otp_read_parallel(OTP_SB_REG_BASE, data, OTP_SB_WORDS); + *val = data[word]; + return 0; + } else { + return -EINVAL; + } +} + +int fuse_prog(u32 bank, u32 word, u32 val) +{ + if (bank <= RWTM_MAX_BANK) { + if (word >= RWTM_ROW_WORDS) + return -EINVAL; + return rwtm_otp_write(bank, word, val); + } else if (bank == OTP_NB_BANK) { + /* TODO: not implemented yet */ + return -ENOSYS; + } else if (bank == OTP_SB_BANK) { + /* TODO: not implemented yet */ + return -ENOSYS; + } else { + return -EINVAL; + } +} + +int fuse_sense(u32 bank, u32 word, u32 *val) +{ + /* not supported */ + return -ENOSYS; +} + +int fuse_override(u32 bank, u32 word, u32 val) +{ + /* not supported */ + return -ENOSYS; +} diff --git a/arch/arm/mach-mvebu/armada3700/mbox.c b/arch/arm/mach-mvebu/armada3700/mbox.c new file mode 100644 index 0000000..eb1f828 --- /dev/null +++ b/arch/arm/mach-mvebu/armada3700/mbox.c @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Marek Behun <marek.behun@nic.cz> + * Copyright (C) 2021 Pali Rohár <pali@kernel.org> + */ + +#include <common.h> +#include <asm/arch/soc.h> +#include <asm/io.h> +#include <linux/bitops.h> +#include <linux/delay.h> +#include <mach/mbox.h> + +#define RWTM_BASE (MVEBU_REGISTER(0xb0000)) +#define RWTM_CMD_PARAM(i) (size_t)(RWTM_BASE + (i) * 4) +#define RWTM_CMD (RWTM_BASE + 0x40) +#define RWTM_CMD_RETSTATUS (RWTM_BASE + 0x80) +#define RWTM_CMD_STATUS(i) (size_t)(RWTM_BASE + 0x84 + (i) * 4) +#define MAX_ARGS 16 + +#define RWTM_HOST_INT_RESET (RWTM_BASE + 0xc8) +#define RWTM_HOST_INT_MASK (RWTM_BASE + 0xcc) +#define SP_CMD_COMPLETE BIT(0) + +#define MBOX_STS_SUCCESS (0x0 << 30) +#define MBOX_STS_FAIL (0x1 << 30) +#define MBOX_STS_BADCMD (0x2 << 30) +#define MBOX_STS_LATER (0x3 << 30) +#define MBOX_STS_ERROR(s) ((s) & (3 << 30)) +#define MBOX_STS_VALUE(s) (((s) >> 10) & 0xfffff) +#define MBOX_STS_CMD(s) ((s) & 0x3ff) +#define MBOX_STS_MARVELL_ERROR(s) ((s) == 0 ? 0 : \ + (s) == 2 ? ETIMEDOUT : \ + (s) == 3 ? EINVAL : \ + (s) == 4 ? ENOSYS : \ + EIO) + +int mbox_do_cmd(enum mbox_cmd cmd, u32 *in, int nin, u32 *out, int nout) +{ + const int tries = 50; + int i; + u32 status; + + if (nin > MAX_ARGS || nout > MAX_ARGS) + return -EINVAL; + + clrbits_le32(RWTM_HOST_INT_MASK, SP_CMD_COMPLETE); + + for (i = 0; i < nin; i++) + writel(in[i], RWTM_CMD_PARAM(i)); + for (; i < MAX_ARGS; i++) + writel(0x0, RWTM_CMD_PARAM(i)); + writel(cmd, RWTM_CMD); + + for (i = 0; i < tries; ++i) { + mdelay(10); + if (readl(RWTM_HOST_INT_RESET) & SP_CMD_COMPLETE) + break; + } + + if (i == tries) { + /* if timed out, don't read status */ + setbits_le32(RWTM_HOST_INT_RESET, SP_CMD_COMPLETE); + return -ETIMEDOUT; + } + + for (i = 0; i < nout; ++i) + out[i] = readl(RWTM_CMD_STATUS(i)); + status = readl(RWTM_CMD_RETSTATUS); + + setbits_le32(RWTM_HOST_INT_RESET, SP_CMD_COMPLETE); + + if (MBOX_STS_CMD(status) != cmd) + return -MBOX_STS_MARVELL_ERROR(status); + else if (MBOX_STS_ERROR(status) == MBOX_STS_FAIL) + return -(int)MBOX_STS_VALUE(status); + else if (MBOX_STS_ERROR(status) == MBOX_STS_BADCMD) + return -ENOSYS; + else if (MBOX_STS_ERROR(status) != MBOX_STS_SUCCESS) + return -EIO; + else + return MBOX_STS_VALUE(status); +} diff --git a/arch/arm/mach-mvebu/efuse.c b/arch/arm/mach-mvebu/efuse.c index c79eee9..80318c3 100644 --- a/arch/arm/mach-mvebu/efuse.c +++ b/arch/arm/mach-mvebu/efuse.c @@ -27,6 +27,7 @@ enum { MVEBU_EFUSE_CTRL_PROGRAM_ENABLE = (1 << 31), + MVEBU_EFUSE_LD1_SELECT = (1 << 6), }; struct mvebu_hd_efuse { @@ -39,8 +40,10 @@ struct mvebu_hd_efuse { #ifndef DRY_RUN static struct mvebu_hd_efuse *efuses = (struct mvebu_hd_efuse *)(MBUS_EFUSE_BASE + 0xF9000); +static u32 *ld_efuses = (void *)MBUS_EFUSE_BASE + 0xF8F00; #else static struct mvebu_hd_efuse efuses[EFUSE_LINE_MAX + 1]; +static u32 ld_efuses[EFUSE_LD_WORDS]; #endif static int efuse_initialised; @@ -169,6 +172,21 @@ int mvebu_read_efuse(int nr, struct efuse_val *val) return 0; } +void mvebu_read_ld_efuse(int ld1, u32 *line) +{ + int i; + +#ifndef DRY_RUN + if (ld1) + setbits_le32(MVEBU_EFUSE_CONTROL, MVEBU_EFUSE_LD1_SELECT); + else + clrbits_le32(MVEBU_EFUSE_CONTROL, MVEBU_EFUSE_LD1_SELECT); +#endif + + for (i = 0; i < EFUSE_LD_WORDS; i++) + line[i] = readl(ld_efuses + i); +} + int mvebu_write_efuse(int nr, struct efuse_val *val) { return prog_efuse(nr, val, ~0, ~0); @@ -199,8 +217,18 @@ static int valid_prog_words; int fuse_read(u32 bank, u32 word, u32 *val) { struct efuse_val fuse_line; + u32 ld_line[EFUSE_LD_WORDS]; int res; + if ((bank == EFUSE_LD0_LINE || bank == EFUSE_LD1_LINE) && word < EFUSE_LD_WORDS) { + res = mvebu_efuse_init_hw(); + if (res) + return res; + mvebu_read_ld_efuse(bank == EFUSE_LD1_LINE, ld_line); + *val = ld_line[word]; + return 0; + } + if (bank < EFUSE_LINE_MIN || bank > EFUSE_LINE_MAX || word > 2) return -EINVAL; diff --git a/arch/arm/mach-mvebu/include/mach/efuse.h b/arch/arm/mach-mvebu/include/mach/efuse.h index bbc5844..122e735 100644 --- a/arch/arm/mach-mvebu/include/mach/efuse.h +++ b/arch/arm/mach-mvebu/include/mach/efuse.h @@ -53,8 +53,13 @@ enum efuse_line { EFUSE_LINE_MIN = 0, EFUSE_LINE_MAX = 63, + + EFUSE_LD0_LINE = 64, + EFUSE_LD1_LINE = 65, }; +#define EFUSE_LD_WORDS 9 + #endif int mvebu_efuse_init_hw(void); diff --git a/arch/arm/mach-mvebu/include/mach/mbox.h b/arch/arm/mach-mvebu/include/mach/mbox.h new file mode 100644 index 0000000..f1cb55f --- /dev/null +++ b/arch/arm/mach-mvebu/include/mach/mbox.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2018 Marek Behun <marek.behun@nic.cz> + * Copyright (C) 2021 Pali Rohár <pali@kernel.org> + */ + +#ifndef _MVEBU_MBOX_H +#define _MVEBU_MBOX_H + +enum mbox_cmd { + MBOX_CMD_GET_RANDOM = 1, + MBOX_CMD_BOARD_INFO, + MBOX_CMD_ECDSA_PUB_KEY, + MBOX_CMD_HASH, + MBOX_CMD_SIGN, + MBOX_CMD_VERIFY, + + MBOX_CMD_OTP_READ, + MBOX_CMD_OTP_WRITE, + + MBOX_CMD_REBOOT, + + /* OTP read commands supported by Marvell fuse.bin firmware */ + MBOX_CMD_OTP_READ_1B = 257, + MBOX_CMD_OTP_READ_8B, + MBOX_CMD_OTP_READ_32B, + MBOX_CMD_OTP_READ_64B, + MBOX_CMD_OTP_READ_256B, + + /* OTP write commands supported by Marvell fuse.bin firmware */ + MBOX_CMD_OTP_WRITE_1B = 513, + MBOX_CMD_OTP_WRITE_8B, + MBOX_CMD_OTP_WRITE_32B, + MBOX_CMD_OTP_WRITE_64B, + MBOX_CMD_OTP_WRITE_256B, +}; + +int mbox_do_cmd(enum mbox_cmd cmd, u32 *in, int nin, u32 *out, int nout); + +#endif diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 2631426..e1b9180 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -32,6 +32,7 @@ config OMAP34XX config OMAP44XX bool "OMAP44XX SoC" select SPL_USE_TINY_PRINTF + select SPL_SYS_NO_VECTOR_TABLE if SPL imply NAND_OMAP_ELM imply NAND_OMAP_GPMC imply SPL_DISPLAY_PRINT |