U-Boot
Threads by month
- ----- 2025 -----
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2000 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
April 2024
- 191 participants
- 585 discussions

[PATCH v3] tpm-v2: allow algoirthm name to be configured for pcr_read and pcr_extend
by Tim Harvey 21 May '24
by Tim Harvey 21 May '24
21 May '24
For pcr_read and pcr_extend commands allow the digest algorithm to be
specified by an additional argument. If not specified it will default to
SHA256 for backwards compatibility.
A follow-on to this could be to extend all PCR banks with the detected
algo when the <digest_algo> argument is 'auto'.
Signed-off-by: Tim Harvey <tharvey(a)gateworks.com>
---
v3:
- replace tpm2_supported_algorithms with struct and use this to relate hash algoirthm
details
v2:
- use tpm2_algorithm_to_len
- use enum tpm2_algorithms
- make function names and parameter names more consistent with existing
tpm-v2 functions
- fix various spelling errors
---
cmd/tpm-v2.c | 49 ++++++++++++++++++++--------
include/tpm-v2.h | 67 ++++++++++++++++++++++++++++++++++++++-
lib/efi_loader/efi_tcg2.c | 4 +--
lib/tpm-v2.c | 62 +++++++++++++++++++++++-------------
4 files changed, 143 insertions(+), 39 deletions(-)
diff --git a/cmd/tpm-v2.c b/cmd/tpm-v2.c
index 7e479b9dfe36..2343b4d9cb9e 100644
--- a/cmd/tpm-v2.c
+++ b/cmd/tpm-v2.c
@@ -99,11 +99,19 @@ static int do_tpm2_pcr_extend(struct cmd_tbl *cmdtp, int flag, int argc,
struct tpm_chip_priv *priv;
u32 index = simple_strtoul(argv[1], NULL, 0);
void *digest = map_sysmem(simple_strtoul(argv[2], NULL, 0), 0);
+ int algo = TPM2_ALG_SHA256;
+ int algo_len;
int ret;
u32 rc;
- if (argc != 3)
+ if (argc < 3 || argc > 4)
return CMD_RET_USAGE;
+ if (argc == 4) {
+ algo = tpm2_name_to_algorithm(argv[3]);
+ if (algo < 0)
+ return CMD_RET_FAILURE;
+ }
+ algo_len = tpm2_algorithm_to_len(algo);
ret = get_tpm(&dev);
if (ret)
@@ -116,8 +124,12 @@ static int do_tpm2_pcr_extend(struct cmd_tbl *cmdtp, int flag, int argc,
if (index >= priv->pcr_count)
return -EINVAL;
- rc = tpm2_pcr_extend(dev, index, TPM2_ALG_SHA256, digest,
- TPM2_DIGEST_LEN);
+ rc = tpm2_pcr_extend(dev, index, algo, digest, algo_len);
+ if (!rc) {
+ printf("PCR #%u extended with %d byte %s digest\n", index,
+ algo_len, tpm2_algorithm_name(algo));
+ print_byte_string(digest, algo_len);
+ }
unmap_sysmem(digest);
@@ -127,15 +139,23 @@ static int do_tpm2_pcr_extend(struct cmd_tbl *cmdtp, int flag, int argc,
static int do_tpm_pcr_read(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
+ enum tpm2_algorithms algo = TPM2_ALG_SHA256;
struct udevice *dev;
struct tpm_chip_priv *priv;
u32 index, rc;
+ int algo_len;
unsigned int updates;
void *data;
int ret;
- if (argc != 3)
+ if (argc < 3 || argc > 4)
return CMD_RET_USAGE;
+ if (argc == 4) {
+ algo = tpm2_name_to_algorithm(argv[3]);
+ if (algo < 0)
+ return CMD_RET_FAILURE;
+ }
+ algo_len = tpm2_algorithm_to_len(algo);
ret = get_tpm(&dev);
if (ret)
@@ -151,11 +171,12 @@ static int do_tpm_pcr_read(struct cmd_tbl *cmdtp, int flag, int argc,
data = map_sysmem(simple_strtoul(argv[2], NULL, 0), 0);
- rc = tpm2_pcr_read(dev, index, priv->pcr_select_min, TPM2_ALG_SHA256,
- data, TPM2_DIGEST_LEN, &updates);
+ rc = tpm2_pcr_read(dev, index, priv->pcr_select_min, algo,
+ data, algo_len, &updates);
if (!rc) {
- printf("PCR #%u content (%u known updates):\n", index, updates);
- print_byte_string(data, TPM2_DIGEST_LEN);
+ printf("PCR #%u %s %d byte content (%u known updates):\n", index,
+ tpm2_algorithm_name(algo), algo_len, updates);
+ print_byte_string(data, algo_len);
}
unmap_sysmem(data);
@@ -415,14 +436,14 @@ U_BOOT_CMD(tpm2, CONFIG_SYS_MAXARGS, 1, do_tpm, "Issue a TPMv2.x command",
" <hierarchy> is one of:\n"
" * TPM2_RH_LOCKOUT\n"
" * TPM2_RH_PLATFORM\n"
-"pcr_extend <pcr> <digest_addr>\n"
-" Extend PCR #<pcr> with digest at <digest_addr>.\n"
+"pcr_extend <pcr> <digest_addr> [<digest_algo>]\n"
+" Extend PCR #<pcr> with digest at <digest_addr> with digest_algo.\n"
" <pcr>: index of the PCR\n"
-" <digest_addr>: address of a 32-byte SHA256 digest\n"
-"pcr_read <pcr> <digest_addr>\n"
-" Read PCR #<pcr> to memory address <digest_addr>.\n"
+" <digest_addr>: address of digest of digest_algo type (defaults to SHA256)\n"
+"pcr_read <pcr> <digest_addr> [<digest_algo>]\n"
+" Read PCR #<pcr> to memory address <digest_addr> with <digest_algo>.\n"
" <pcr>: index of the PCR\n"
-" <digest_addr>: address to store the a 32-byte SHA256 digest\n"
+" <digest_addr>: address of digest of digest_algo type (defaults to SHA256)\n"
"get_capability <capability> <property> <addr> <count>\n"
" Read and display <count> entries indexed by <capability>/<property>.\n"
" Values are 4 bytes long and are written at <addr>.\n"
diff --git a/include/tpm-v2.h b/include/tpm-v2.h
index 33dd103767c4..263f9529e55d 100644
--- a/include/tpm-v2.h
+++ b/include/tpm-v2.h
@@ -386,7 +386,54 @@ enum tpm2_algorithms {
TPM2_ALG_SM3_256 = 0x12,
};
-extern const enum tpm2_algorithms tpm2_supported_algorithms[4];
+/**
+ * struct digest_info - details of supported digests
+ *
+ * @hash_name: hash name
+ * @hash_alg: hash algorithm id
+ * @hash_mask: hash registry mask
+ * @hash_len: hash digest length
+ */
+struct digest_info {
+ const char *hash_name;
+ u16 hash_alg;
+ u32 hash_mask;
+ u16 hash_len;
+};
+
+/* Algorithm Registry */
+#define TCG2_BOOT_HASH_ALG_SHA1 0x00000001
+#define TCG2_BOOT_HASH_ALG_SHA256 0x00000002
+#define TCG2_BOOT_HASH_ALG_SHA384 0x00000004
+#define TCG2_BOOT_HASH_ALG_SHA512 0x00000008
+#define TCG2_BOOT_HASH_ALG_SM3_256 0x00000010
+
+static const struct digest_info hash_algo_list[] = {
+ {
+ "sha1",
+ TPM2_ALG_SHA1,
+ TCG2_BOOT_HASH_ALG_SHA1,
+ TPM2_SHA1_DIGEST_SIZE,
+ },
+ {
+ "sha256",
+ TPM2_ALG_SHA256,
+ TCG2_BOOT_HASH_ALG_SHA256,
+ TPM2_SHA256_DIGEST_SIZE,
+ },
+ {
+ "sha384",
+ TPM2_ALG_SHA384,
+ TCG2_BOOT_HASH_ALG_SHA384,
+ TPM2_SHA384_DIGEST_SIZE,
+ },
+ {
+ "sha512",
+ TPM2_ALG_SHA512,
+ TCG2_BOOT_HASH_ALG_SHA512,
+ TPM2_SHA512_DIGEST_SIZE,
+ },
+};
static inline u16 tpm2_algorithm_to_len(enum tpm2_algorithms a)
{
@@ -965,4 +1012,22 @@ u32 tpm2_enable_nvcommits(struct udevice *dev, uint vendor_cmd,
*/
u32 tpm2_auto_start(struct udevice *dev);
+/**
+ * tpm2_name_to_algorithm() - Return an algorithm id given a supported
+ * algorithm name
+ *
+ * @name: algorithm name
+ * Return: enum tpm2_algorithms or -EINVAL
+ */
+enum tpm2_algorithms tpm2_name_to_algorithm(const char *name);
+
+/**
+ * tpm2_algorithm_name() - Return an algorithm name string for a
+ * supported algorithm id
+ *
+ * @algorithm_id: algorithm defined in enum tpm2_algorithms
+ * Return: algorithm name string or ""
+ */
+const char *tpm2_algorithm_name(enum tpm2_algorithms);
+
#endif /* __TPM_V2_H */
diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c
index b07e0099c27e..cf5d8de018a7 100644
--- a/lib/efi_loader/efi_tcg2.c
+++ b/lib/efi_loader/efi_tcg2.c
@@ -414,8 +414,8 @@ static efi_status_t tcg2_hash_pe_image(void *efi, u64 efi_size,
}
digest_list->count = 0;
- for (i = 0; i < ARRAY_SIZE(tpm2_supported_algorithms); i++) {
- u16 hash_alg = tpm2_supported_algorithms[i];
+ for (i = 0; i < ARRAY_SIZE(hash_algo_list); i++) {
+ u16 hash_alg = hash_algo_list[i].hash_alg;
if (!(active & tpm2_algorithm_to_mask(hash_alg)))
continue;
diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c
index 68eaaa639f89..83f490c82541 100644
--- a/lib/tpm-v2.c
+++ b/lib/tpm-v2.c
@@ -22,13 +22,6 @@
#include "tpm-utils.h"
-const enum tpm2_algorithms tpm2_supported_algorithms[4] = {
- TPM2_ALG_SHA1,
- TPM2_ALG_SHA256,
- TPM2_ALG_SHA384,
- TPM2_ALG_SHA512,
-};
-
int tcg2_get_active_pcr_banks(struct udevice *dev, u32 *active_pcr_banks)
{
u32 supported = 0;
@@ -82,14 +75,14 @@ int tcg2_create_digest(struct udevice *dev, const u8 *input, u32 length,
return rc;
digest_list->count = 0;
- for (i = 0; i < ARRAY_SIZE(tpm2_supported_algorithms); ++i) {
+ for (i = 0; i < ARRAY_SIZE(hash_algo_list); ++i) {
u32 mask =
- tpm2_algorithm_to_mask(tpm2_supported_algorithms[i]);
+ tpm2_algorithm_to_mask(hash_algo_list[i].hash_alg);
if (!(active & mask))
continue;
- switch (tpm2_supported_algorithms[i]) {
+ switch (hash_algo_list[i].hash_alg) {
case TPM2_ALG_SHA1:
sha1_starts(&ctx);
sha1_update(&ctx, input, length);
@@ -116,12 +109,12 @@ int tcg2_create_digest(struct udevice *dev, const u8 *input, u32 length,
break;
default:
printf("%s: unsupported algorithm %x\n", __func__,
- tpm2_supported_algorithms[i]);
+ hash_algo_list[i].hash_alg);
continue;
}
digest_list->digests[digest_list->count].hash_alg =
- tpm2_supported_algorithms[i];
+ hash_algo_list[i].hash_alg;
memcpy(&digest_list->digests[digest_list->count].digest, final,
len);
digest_list->count++;
@@ -208,13 +201,13 @@ static int tcg2_log_init(struct udevice *dev, struct tcg2_event_log *elog)
return rc;
event_size = offsetof(struct tcg_efi_spec_id_event, digest_sizes);
- for (i = 0; i < ARRAY_SIZE(tpm2_supported_algorithms); ++i) {
- mask = tpm2_algorithm_to_mask(tpm2_supported_algorithms[i]);
+ for (i = 0; i < ARRAY_SIZE(hash_algo_list); ++i) {
+ mask = tpm2_algorithm_to_mask(hash_algo_list[i].hash_alg);
if (!(active & mask))
continue;
- switch (tpm2_supported_algorithms[i]) {
+ switch (hash_algo_list[i].hash_alg) {
case TPM2_ALG_SHA1:
case TPM2_ALG_SHA256:
case TPM2_ALG_SHA384:
@@ -253,17 +246,17 @@ static int tcg2_log_init(struct udevice *dev, struct tcg2_event_log *elog)
put_unaligned_le32(count, &ev->number_of_algorithms);
count = 0;
- for (i = 0; i < ARRAY_SIZE(tpm2_supported_algorithms); ++i) {
- mask = tpm2_algorithm_to_mask(tpm2_supported_algorithms[i]);
+ for (i = 0; i < ARRAY_SIZE(hash_algo_list); ++i) {
+ mask = tpm2_algorithm_to_mask(hash_algo_list[i].hash_alg);
if (!(active & mask))
continue;
- len = tpm2_algorithm_to_len(tpm2_supported_algorithms[i]);
+ len = hash_algo_list[i].hash_len;
if (!len)
continue;
- put_unaligned_le16(tpm2_supported_algorithms[i],
+ put_unaligned_le16(hash_algo_list[i].hash_alg,
&ev->digest_sizes[count].algorithm_id);
put_unaligned_le16(len, &ev->digest_sizes[count].digest_size);
count++;
@@ -304,7 +297,7 @@ static int tcg2_replay_eventlog(struct tcg2_event_log *elog,
pos = offsetof(struct tcg_pcr_event2, digests) +
offsetof(struct tpml_digest_values, count);
count = get_unaligned_le32(log + pos);
- if (count > ARRAY_SIZE(tpm2_supported_algorithms) ||
+ if (count > ARRAY_SIZE(hash_algo_list) ||
(digest_list->count && digest_list->count != count))
return 0;
@@ -407,7 +400,7 @@ static int tcg2_log_parse(struct udevice *dev, struct tcg2_event_log *elog)
return 0;
count = get_unaligned_le32(&event->number_of_algorithms);
- if (count > ARRAY_SIZE(tpm2_supported_algorithms))
+ if (count > ARRAY_SIZE(hash_algo_list))
return 0;
calc_size = offsetof(struct tcg_efi_spec_id_event, digest_sizes) +
@@ -1110,7 +1103,7 @@ int tpm2_get_pcr_info(struct udevice *dev, u32 *supported_pcr, u32 *active_pcr,
* We only support 5 algorithms for now so check against that
* instead of TPM2_NUM_PCR_BANKS
*/
- if (pcrs.count > ARRAY_SIZE(tpm2_supported_algorithms) ||
+ if (pcrs.count > ARRAY_SIZE(hash_algo_list) ||
pcrs.count < 1) {
printf("%s: too many pcrs: %u\n", __func__, pcrs.count);
return -EMSGSIZE;
@@ -1555,3 +1548,28 @@ u32 tpm2_enable_nvcommits(struct udevice *dev, uint vendor_cmd,
return 0;
}
+
+enum tpm2_algorithms tpm2_name_to_algorithm(const char *name)
+{
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(hash_algo_list); ++i) {
+ if (!strcasecmp(name, hash_algo_list[i].hash_name))
+ return hash_algo_list[i].hash_alg;
+ }
+ printf("%s: unsupported algorithm %s\n", __func__, name);
+
+ return -EINVAL;
+}
+
+const char *tpm2_algorithm_name(enum tpm2_algorithms algo)
+{
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(hash_algo_list); ++i) {
+ if (hash_algo_list[i].hash_alg == algo)
+ return hash_algo_list[i].hash_name;
+ }
+
+ return "";
+}
--
2.25.1
2
11
Number of Qualcomm ARMv7 SoC-s did not use PSCI but rather used PSHOLD
(Qualcomm Power Supply Hold Reset) bit to trigger reset or poweroff.
Qualcomm IPQ40XX is one of them, so provide a simple sysreset driver based
on the upstream Linux one, it is DT compatible as well.
Signed-off-by: Robert Marko <robert.marko(a)sartura.hr>
Reviewed-by: Caleb Connolly <caleb.connolly(a)linaro.org>
---
Changes in v2:
* Use QCOM instead of MSM naming
drivers/sysreset/Kconfig | 6 +++
drivers/sysreset/Makefile | 1 +
drivers/sysreset/sysreset_qcom-pshold.c | 56 +++++++++++++++++++++++++
3 files changed, 63 insertions(+)
create mode 100644 drivers/sysreset/sysreset_qcom-pshold.c
diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig
index 49c0787b26..920dceb70b 100644
--- a/drivers/sysreset/Kconfig
+++ b/drivers/sysreset/Kconfig
@@ -235,6 +235,12 @@ config SYSRESET_RAA215300
help
Add support for the system reboot via the Renesas RAA215300 PMIC.
+config SYSRESET_QCOM_PSHOLD
+ bool "Support sysreset for Qualcomm SoCs via PSHOLD"
+ depends on ARCH_IPQ40XX
+ help
+ Add support for the system reboot on Qualcomm SoCs via PSHOLD.
+
endif
endmenu
diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile
index e0e732205d..f0620c391e 100644
--- a/drivers/sysreset/Makefile
+++ b/drivers/sysreset/Makefile
@@ -28,4 +28,5 @@ obj-$(CONFIG_SYSRESET_RESETCTL) += sysreset_resetctl.o
obj-$(CONFIG_$(SPL_TPL_)SYSRESET_AT91) += sysreset_at91.o
obj-$(CONFIG_$(SPL_TPL_)SYSRESET_X86) += sysreset_x86.o
obj-$(CONFIG_SYSRESET_RAA215300) += sysreset_raa215300.o
+obj-$(CONFIG_SYSRESET_QCOM_PSHOLD) += sysreset_qcom-pshold.o
obj-$(CONFIG_TARGET_XTFPGA) += sysreset_xtfpga.o
diff --git a/drivers/sysreset/sysreset_qcom-pshold.c b/drivers/sysreset/sysreset_qcom-pshold.c
new file mode 100644
index 0000000000..25231cf5e2
--- /dev/null
+++ b/drivers/sysreset/sysreset_qcom-pshold.c
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Qualcomm PSHOLD reset driver
+ *
+ * Copyright (c) 2024 Sartura Ltd.
+ *
+ * Author: Robert Marko <robert.marko(a)sartura.hr>
+ * Based on the Linux msm-poweroff driver.
+ *
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <sysreset.h>
+#include <asm/io.h>
+#include <linux/delay.h>
+
+struct qcom_pshold_priv {
+ phys_addr_t base;
+};
+
+static int qcom_pshold_request(struct udevice *dev, enum sysreset_t type)
+{
+ struct qcom_pshold_priv *priv = dev_get_priv(dev);
+
+ writel(0, priv->base);
+ mdelay(10000);
+
+ return 0;
+}
+
+static struct sysreset_ops qcom_pshold_ops = {
+ .request = qcom_pshold_request,
+};
+
+static int qcom_pshold_probe(struct udevice *dev)
+{
+ struct qcom_pshold_priv *priv = dev_get_priv(dev);
+
+ priv->base = dev_read_addr(dev);
+ return priv->base == FDT_ADDR_T_NONE ? -EINVAL : 0;
+}
+
+static const struct udevice_id qcom_pshold_ids[] = {
+ { .compatible = "qcom,pshold", },
+ { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(qcom_pshold) = {
+ .name = "qcom_pshold",
+ .id = UCLASS_SYSRESET,
+ .of_match = qcom_pshold_ids,
+ .probe = qcom_pshold_probe,
+ .priv_auto = sizeof(struct qcom_pshold_priv),
+ .ops = &qcom_pshold_ops,
+};
--
2.44.0
2
1

20 May '24
Luka Kovacic is no longer at Sartura, so remove him as one of IPQ40xx
maintainers.
Signed-off-by: Robert Marko <robert.marko(a)sartura.hr>
---
MAINTAINERS | 1 -
1 file changed, 1 deletion(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index d0a4a28b40..8691500d28 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -334,7 +334,6 @@ F: drivers/spi/gxp_spi.c
ARM IPQ40XX
M: Robert Marko <robert.marko(a)sartura.hr>
-M: Luka Kovacic <luka.kovacic(a)sartura.hr>
M: Luka Perkov <luka.perkov(a)sartura.hr>
S: Maintained
F: arch/arm/mach-ipq40xx/
--
2.44.0
2
4
This little series reprises the EFI-video fix, fixes a USB problem and
enables a boot script for coreboot.
It also moves to truetype fonts for coreboot and qemu-x86, since the
menus look much better and there are no strong size constraints.
With these changes it is possible to boot a Linux distro automatically
with U-Boot on x86, including when U-Boot is the second-stage
bootloader.
Changes in v5:
- Adjust motivation for patch, since the EFI hang is fixed
Changes in v4:
- Don't rename the legacy-USB functions
- Add a bit more detail to the comment
- Use a Kconfig option
Changes in v3:
- Add new patch to refactor mmc prep to allow a different scan
- Add missing word 'function' in the commit message
- Clear the screen before booting
- Add new patch to drop unnecessary truetype operations from SPL
- Add new patch to enable truetype fonts in coreboot
- Add new patch to enable truetype fonts in qemu-x86 and qemu-x86_64
Changes in v2:
- Rebase to -next
- Add some more comments to the header file
- Add fixes tag
- Add new patch to add a return code to bootflow menu
- Add new patch to add a coreboot boot script
- Add new patch to avoid unbinding devices in use by bootflows
Simon Glass (12):
efi: Correct handling of frame buffer
bootstd: Refactor mmc prep to allow a different scan
bootstd: Add a return code to bootflow menu
x86: coreboot: Add a boot script
usb: Avoid unbinding devices in use by bootflows
expo: Correct background colour
video: Correct setting of cursor position
video: Drop unnecessary truetype operations from SPL
x86: Enable SSE in 64-bit mode
x86: coreboot: Enable truetype fonts
x86: qemu: Expand ROM size
x86: qemu: Enable truetype fonts
arch/x86/Kconfig | 8 ++++
arch/x86/config.mk | 4 ++
arch/x86/cpu/x86_64/cpu.c | 12 ++++++
arch/x86/dts/coreboot.dts | 10 +++++
board/emulation/qemu-x86/Kconfig | 3 +-
boot/bootm.c | 2 +-
boot/expo.c | 4 +-
cmd/bootflow.c | 53 ++++++++++++++++++------
common/usb.c | 5 +++
configs/coreboot64_defconfig | 2 +
configs/coreboot_defconfig | 2 +
configs/qemu-x86_64_defconfig | 5 ++-
configs/qemu-x86_defconfig | 1 +
doc/usage/cmd/bootflow.rst | 67 +++++++++++++++++++++++++++++++
drivers/usb/host/usb-uclass.c | 14 ++++++-
drivers/video/Kconfig | 1 +
drivers/video/console_truetype.c | 10 +++++
drivers/video/vidconsole-uclass.c | 15 +++----
include/usb.h | 21 +++++++++-
include/video.h | 9 +++--
lib/efi_loader/efi_gop.c | 12 +++---
test/boot/bootflow.c | 64 ++++++++++++++++++++++++-----
22 files changed, 280 insertions(+), 44 deletions(-)
--
2.43.0.rc0.421.g78406f8d94-goog
5
19

[PATCH v2] rockchip: add support for Theobroma Systems SOM-RK3588-Q7 Tiger module
by Quentin Schulz 16 May '24
by Quentin Schulz 16 May '24
16 May '24
From: Quentin Schulz <quentin.schulz(a)theobroma-systems.com>
The RK3588-Q7 SoM is a Qseven-compatible (70mm x 70mm, MXM-230
connector) system-on-module from Theobroma Systems, featuring the
Rockchip RK3588.
It provides the following feature set:
* up to 16GB LPDDR4x
* on-module eMMC
* SD card (on a baseboard) via edge connector
* Gigabit Ethernet with on-module GbE PHY
* HDMI/eDP
* MIPI-DSI
* 4x MIPI-CSI (3x on FPC connectors, 1x over Q7)
* HDMI input over FPC connector
* CAN
* USB
- 1x USB 3.0 dual-role (direct connection)
- 2x USB 3.0 host + 1x USB 2.0 host
* PCIe
- 1x PCIe 2.1 Gen3, 4 lanes
- 2xSATA / 2x PCIe 2.1 Gen1, 2 lanes
* on-module ATtiny816 companion controller, implementing:
- low-power RTC functionality (ISL1208 emulation)
- fan controller (AMC6821 emulation)
* on-module Secure Element with Global Platform 2.2.1 compliant
JavaCard environment
The support is added for Tiger on Haikou devkit, similarly to RK3399
Puma and PX30 Ringneck.
The DTS and DTSI are taken from upstream Linux kernel v6.9-rc4.
Cc: Quentin Schulz <foss+uboot(a)0leil.net>
Signed-off-by: Quentin Schulz <quentin.schulz(a)theobroma-systems.com>
---
This has a light dependency on
https://lore.kernel.org/u-boot/20240415-rk35xx-dram-atags-v3-0-5bc5475b3c0d…
(the Tiger defconfig can be updated to remove the dependency if required)
To: Tom Rini <trini(a)konsulko.com>
To: Klaus Goger <klaus.goger(a)theobroma-systems.com>
To: Heiko Stuebner <heiko.stuebner(a)cherry.de>
To: Simon Glass <sjg(a)chromium.org>
To: Philipp Tomsich <philipp.tomsich(a)vrull.eu>
To: Kever Yang <kever.yang(a)rock-chips.com>
Cc: u-boot(a)lists.denx.de
Signed-off-by: Quentin Schulz <quentin.schulz(a)theobroma-systems.com>
Changes in v2:
- removed uart controller muxing patch as not necessary until we get
open-source DRAM init,
- disabled DEBUG_UART_BOARD_INIT as it's only used for muxing the UART
controller and it's not necessary since DDR bin does this for us
already,
- added missing uart2 mux bootph in U-Boot dtsi (though not required
yet),
- switched to USB_DWC3_GENERIC from USB_XHCI_DWC3 as requested by Jonas,
- Link to v1: https://lore.kernel.org/r/20240422-tiger-v1-0-8816b070d748@theobroma-system…
---
arch/arm/dts/Makefile | 1 +
arch/arm/dts/rk3588-tiger-haikou-u-boot.dtsi | 59 ++
arch/arm/dts/rk3588-tiger-haikou.dts | 266 ++++++++
arch/arm/dts/rk3588-tiger.dtsi | 690 +++++++++++++++++++++
arch/arm/mach-rockchip/rk3588/Kconfig | 31 +
board/theobroma-systems/tiger_rk3588/Kconfig | 16 +
board/theobroma-systems/tiger_rk3588/MAINTAINERS | 13 +
board/theobroma-systems/tiger_rk3588/Makefile | 10 +
.../theobroma-systems/tiger_rk3588/tiger_rk3588.c | 53 ++
configs/tiger-rk3588_defconfig | 114 ++++
doc/board/rockchip/rockchip.rst | 1 +
doc/board/theobroma-systems/index.rst | 1 +
doc/board/theobroma-systems/tiger_rk3588.rst | 102 +++
include/configs/tiger_rk3588.h | 15 +
14 files changed, 1372 insertions(+)
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index b1c9c6222e5..ef901642a0a 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -180,6 +180,7 @@ dtb-$(CONFIG_ROCKCHIP_RK3588) += \
rk3588-quartzpro64.dtb \
rk3588s-rock-5a.dtb \
rk3588-rock-5b.dtb \
+ rk3588-tiger-haikou.dtb \
rk3588-turing-rk1.dtb
dtb-$(CONFIG_ROCKCHIP_RV1108) += \
diff --git a/arch/arm/dts/rk3588-tiger-haikou-u-boot.dtsi b/arch/arm/dts/rk3588-tiger-haikou-u-boot.dtsi
new file mode 100644
index 00000000000..bfcefe256b0
--- /dev/null
+++ b/arch/arm/dts/rk3588-tiger-haikou-u-boot.dtsi
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2024 Theobroma Systems Design und Consulting GmbH
+ */
+
+#include "rk3588-u-boot.dtsi"
+
+/ {
+ chosen {
+ u-boot,spl-boot-order = "same-as-spl", &sdhci, &sdmmc;
+ };
+};
+
+&emmc_pwrseq {
+ bootph-pre-ram;
+ bootph-some-ram;
+};
+
+&emmc_reset {
+ bootph-pre-ram;
+ bootph-some-ram;
+};
+
+&gpio2 {
+ bootph-pre-ram;
+ bootph-some-ram;
+};
+
+&sdhci {
+ /* U-Boot currently cannot handle anything below HS200 for eMMC on RK3588 */
+ /delete-property/ mmc-ddr-1_8v;
+ /delete-property/ cap-mmc-highspeed;
+};
+
+/* Q7 USB P0 */
+&u2phy1 {
+ status = "okay";
+};
+
+&u2phy1_otg {
+ status = "okay";
+};
+
+&uart2m2_xfer {
+ bootph-all;
+};
+
+/* Q7 USB P0 */
+&usbdp_phy1 {
+ status = "okay";
+};
+
+&usbdp_phy1_u3 {
+ status = "okay";
+};
+
+&usb_host1_xhci {
+ status = "okay";
+};
diff --git a/arch/arm/dts/rk3588-tiger-haikou.dts b/arch/arm/dts/rk3588-tiger-haikou.dts
new file mode 100644
index 00000000000..d672198c6b6
--- /dev/null
+++ b/arch/arm/dts/rk3588-tiger-haikou.dts
@@ -0,0 +1,266 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 Theobroma Systems Design und Consulting GmbH
+ */
+
+/dts-v1/;
+#include <dt-bindings/input/input.h>
+#include "rk3588-tiger.dtsi"
+
+/ {
+ model = "Theobroma Systems RK3588-Q7 SoM on Haikou devkit";
+ compatible = "tsd,rk3588-tiger-haikou", "tsd,rk3588-tiger", "rockchip,rk3588";
+
+ aliases {
+ ethernet0 = &gmac0;
+ mmc1 = &sdmmc;
+ };
+
+ chosen {
+ stdout-path = "serial2:115200n8";
+ };
+
+ dc_12v: dc-12v-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "dc_12v";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&haikou_keys_pin>;
+
+ button-batlow-n {
+ label = "BATLOW#";
+ linux,code = <KEY_BATTERY>;
+ gpios = <&gpio3 RK_PB5 GPIO_ACTIVE_LOW>;
+ };
+
+ button-slp-btn-n {
+ label = "SLP_BTN#";
+ linux,code = <KEY_SLEEP>;
+ gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_LOW>;
+ };
+
+ button-wake-n {
+ label = "WAKE#";
+ linux,code = <KEY_WAKEUP>;
+ gpios = <&gpio3 RK_PC6 GPIO_ACTIVE_LOW>;
+ wakeup-source;
+ };
+
+ switch-lid-btn-n {
+ label = "LID_BTN#";
+ linux,code = <SW_LID>;
+ linux,input-type = <EV_SW>;
+ gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ i2s3-sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,name = "Haikou,I2S-codec";
+ simple-audio-card,mclk-fs = <512>;
+ simple-audio-card,frame-master = <&sgtl5000_codec>;
+ simple-audio-card,bitclock-master = <&sgtl5000_codec>;
+
+ sgtl5000_codec: simple-audio-card,codec {
+ sound-dai = <&sgtl5000>;
+ };
+
+ simple-audio-card,cpu {
+ sound-dai = <&i2s3_2ch>;
+ };
+ };
+
+ sgtl5000_clk: sgtl5000-oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24576000>;
+ };
+
+ vcc3v3_baseboard: vcc3v3-baseboard-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_baseboard";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&dc_12v>;
+ };
+
+ vcc3v3_low_noise: vcc3v3-low-noise-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_low_noise";
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc5v0_usb>;
+ };
+
+ vcc5v0_baseboard: vcc5v0-baseboard-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_baseboard";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&dc_12v>;
+ };
+
+ vcc5v0_usb: vcc5v0-usb-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_usb";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&dc_12v>;
+ };
+
+ vddd_audio_1v6: vddd-audio-1v6-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vddd_audio_1v6";
+ regulator-boot-on;
+ regulator-min-microvolt = <1600000>;
+ regulator-max-microvolt = <1600000>;
+ vin-supply = <&vcc5v0_usb>;
+ };
+};
+
+&combphy2_psu {
+ status = "okay";
+};
+
+&gmac0 {
+ status = "okay";
+};
+
+&i2c1 {
+ status = "okay";
+
+ eeprom@50 {
+ reg = <0x50>;
+ compatible = "atmel,24c01";
+ pagesize = <8>;
+ size = <128>;
+ vcc-supply = <&vcc3v3_baseboard>;
+ };
+};
+
+&i2c5 {
+ clock-frequency = <400000>;
+ status = "okay";
+
+ sgtl5000: codec@a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ clocks = <&sgtl5000_clk>;
+ #sound-dai-cells = <0>;
+ VDDA-supply = <&vcc3v3_low_noise>;
+ VDDIO-supply = <&vcc3v3_baseboard>;
+ VDDD-supply = <&vddd_audio_1v6>;
+ };
+};
+
+&i2c8 {
+ status = "okay";
+};
+
+&i2s3_2ch {
+ status = "okay";
+};
+
+&pcie30phy {
+ status = "okay";
+};
+
+&pcie3x4 {
+ vpcie3v3-supply = <&vcc3v3_baseboard>;
+ status = "okay";
+};
+
+&pinctrl {
+ haikou {
+ haikou_keys_pin: haikou-keys-pin {
+ rockchip,pins =
+ /* BATLOW# */
+ <3 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>,
+ /* SLP_BTN# */
+ <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_up>,
+ /* WAKE# */
+ <3 RK_PC6 RK_FUNC_GPIO &pcfg_pull_up>,
+ /* LID_BTN */
+ <3 RK_PD5 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+};
+
+&sdmmc {
+ /* while the same pin, sdmmc_det does not detect card changes */
+ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
+ disable-wp;
+ pinctrl-0 = <&sdmmc_bus4 &sdmmc_cmd &sdmmc_clk>;
+ sd-uhs-sdr12;
+ sd-uhs-sdr25;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
+ vmmc-supply = <&vcc3v3_baseboard>;
+ status = "okay";
+};
+
+&u2phy2 {
+ status = "okay";
+};
+
+&u2phy2_host {
+ status = "okay";
+};
+
+&u2phy3 {
+ status = "okay";
+};
+
+&u2phy3_host {
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-0 = <&uart2m2_xfer>;
+ status = "okay";
+};
+
+&uart5 {
+ rts-gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+/* host0 on Q7_USB_P2, lower usb3 port */
+&usb_host0_ehci {
+ status = "okay";
+};
+
+/* host0 on Q7_USB_P2, lower usb3 port */
+&usb_host0_ohci {
+ status = "okay";
+};
+
+/* host1 on Q7_USB_P3, usb2 port */
+&usb_host1_ehci {
+ status = "okay";
+};
+
+/* host1 on Q7_USB_P3, usb2 port */
+&usb_host1_ohci {
+ status = "okay";
+};
+
+/* host2 on Q7_USB_P2, lower usb3 port */
+&usb_host2_xhci {
+ status = "okay";
+};
diff --git a/arch/arm/dts/rk3588-tiger.dtsi b/arch/arm/dts/rk3588-tiger.dtsi
new file mode 100644
index 00000000000..1eb2543a5fd
--- /dev/null
+++ b/arch/arm/dts/rk3588-tiger.dtsi
@@ -0,0 +1,690 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 Theobroma Systems Design und Consulting GmbH
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "rk3588.dtsi"
+
+/ {
+ compatible = "tsd,rk3588-tiger", "rockchip,rk3588";
+
+ aliases {
+ mmc0 = &sdhci;
+ rtc0 = &rtc_twi;
+ };
+
+ emmc_pwrseq: emmc-pwrseq {
+ compatible = "mmc-pwrseq-emmc";
+ pinctrl-0 = <&emmc_reset>;
+ pinctrl-names = "default";
+ reset-gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_HIGH>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&module_led_pin>;
+
+ /* Named LED1 on the board */
+ led-1 {
+ gpios = <&gpio1 RK_PD3 GPIO_ACTIVE_HIGH>;
+ function = LED_FUNCTION_HEARTBEAT;
+ linux,default-trigger = "heartbeat";
+ color = <LED_COLOR_ID_AMBER>;
+ };
+ };
+
+ /*
+ * 100MHz reference clock for PCIe peripherals from PI6C557-05BLE
+ * clock generator.
+ * The clock output is gated via the OE pin on the clock generator.
+ * This is modeled as a fixed-clock plus a gpio-gate-clock.
+ */
+ pcie_refclk_gen: pcie-refclk-gen-clock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <1000000000>;
+ };
+
+ pcie_refclk: pcie-refclk-clock {
+ compatible = "gpio-gate-clock";
+ clocks = <&pcie_refclk_gen>;
+ #clock-cells = <0>;
+ enable-gpios = <&gpio4 RK_PB4 GPIO_ACTIVE_HIGH>; /* PCIE30X4_CLKREQN_M1_L */
+ };
+
+ vcc_1v1_nldo_s3: vcc-1v1-nldo-s3-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_1v1_nldo_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc_1v2_s3: vcc-1v2-s3-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_1v2_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc5v0_sys: vcc5v0-sys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v0_baseboard>;
+ };
+};
+
+&cpu_b0 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b1 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b2 {
+ cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_b3 {
+ cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_l0 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l1 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l2 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l3 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&gmac0 {
+ clock_in_out = "output";
+ phy-handle = <&rgmii_phy>;
+ phy-mode = "rgmii";
+ phy-supply = <&vcc_1v2_s3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac0_miim
+ &gmac0_rx_bus2
+ &gmac0_tx_bus2
+ &gmac0_rgmii_clk
+ &gmac0_rgmii_bus
+ ð0_pins
+ ð_reset>;
+ tx_delay = <0x10>;
+ rx_delay = <0x10>;
+ snps,reset-gpio = <&gpio4 RK_PC3 GPIO_ACTIVE_LOW>;
+ snps,reset-active-low;
+ snps,reset-delays-us = <0 10000 100000>;
+};
+
+&i2c1 {
+ pinctrl-0 = <&i2c1m0_xfer>;
+};
+
+&i2c1m0_xfer {
+ rockchip,pins =
+ /* i2c1_scl_m0 */
+ <0 RK_PB5 9 &pcfg_pull_none_drv_level_0>,
+ /* i2c1_sda_m0 */
+ <0 RK_PB6 9 &pcfg_pull_none_drv_level_0>;
+};
+
+&i2c2 {
+ pinctrl-0 = <&i2c2m3_xfer>;
+ status = "okay";
+};
+
+&i2c2m3_xfer {
+ rockchip,pins =
+ /* i2c2_scl_m3 */
+ <1 RK_PC5 9 &pcfg_pull_none_drv_level_0>,
+ /* i2c2_sda_m3 */
+ <1 RK_PC4 9 &pcfg_pull_none_drv_level_0>;
+};
+
+&i2c3 {
+ pinctrl-0 = <&i2c3m0_xfer>;
+};
+
+&i2c4 {
+ pinctrl-0 = <&i2c4m4_xfer>;
+ status = "okay";
+
+ vdd_npu_s0: regulator@42 {
+ compatible = "rockchip,rk8602";
+ reg = <0x42>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_npu_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc5v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
+
+&i2c5 {
+ pinctrl-0 = <&i2c5m1_xfer>;
+};
+
+&i2c5m1_xfer {
+ rockchip,pins =
+ /* i2c5_scl_m1 */
+ <4 RK_PB6 9 &pcfg_pull_none_drv_level_0>,
+ /* i2c5_sda_m1 */
+ <4 RK_PB7 9 &pcfg_pull_none_drv_level_0>;
+};
+
+&i2c6 {
+ /*
+ * Mule-ATtiny can handle up to Fast mode Plus (1MHz) on I2C bus,
+ * but SOC can handle only up to (400kHz).
+ */
+ clock-frequency = <400000>;
+ status = "okay";
+
+ fan@18 {
+ compatible = "ti,amc6821";
+ reg = <0x18>;
+ };
+
+ rtc_twi: rtc@6f {
+ compatible = "isil,isl1208";
+ reg = <0x6f>;
+ };
+};
+
+&i2c6m0_xfer {
+ rockchip,pins =
+ /* i2c6_scl_m0 */
+ <0 RK_PD0 9 &pcfg_pull_none_drv_level_0>,
+ /* i2c6_sda_m0 */
+ <0 RK_PC7 9 &pcfg_pull_none_drv_level_0>;
+};
+
+&i2c7 {
+ status = "okay";
+
+ vdd_cpu_big0_s0: regulator@42 {
+ compatible = "rockchip,rk8602";
+ reg = <0x42>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu_big0_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc5v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_big1_s0: regulator@43 {
+ compatible = "rockchip,rk8603", "rockchip,rk8602";
+ reg = <0x43>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu_big1_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc5v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
+
+&i2c7m0_xfer {
+ rockchip,pins =
+ /* i2c7_scl_m0 */
+ <1 RK_PD0 9 &pcfg_pull_none_drv_level_0>,
+ /* i2c7_sda_m0 */
+ <1 RK_PD1 9 &pcfg_pull_none_drv_level_0>;
+};
+
+&i2c8 {
+ pinctrl-0 = <&i2c8m2_xfer>;
+};
+
+&mdio0 {
+ rgmii_phy: ethernet-phy@6 {
+ /* KSZ9031 or KSZ9131 */
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x6>;
+ clocks = <&cru REFCLKO25M_ETH0_OUT>;
+ };
+};
+
+&pcie3x4 {
+ /*
+ * The board has a gpio-controlled "pcie_refclk" generator,
+ * so add it to the list of clocks.
+ */
+ clocks = <&cru ACLK_PCIE_4L_MSTR>, <&cru ACLK_PCIE_4L_SLV>,
+ <&cru ACLK_PCIE_4L_DBI>, <&cru PCLK_PCIE_4L>,
+ <&cru CLK_PCIE_AUX0>, <&cru CLK_PCIE4L_PIPE>,
+ <&pcie_refclk>;
+ clock-names = "aclk_mst", "aclk_slv",
+ "aclk_dbi", "pclk",
+ "aux", "pipe",
+ "ref";
+ reset-gpios = <&gpio3 RK_PB6 GPIO_ACTIVE_HIGH>;
+};
+
+&pinctrl {
+ emmc {
+ emmc_reset: emmc-reset {
+ rockchip,pins = <2 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ ethernet {
+ eth_reset: eth-reset {
+ rockchip,pins = <4 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ leds {
+ module_led_pin: module-led-pin {
+ rockchip,pins = <1 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&saradc {
+ vref-supply = <&vcc_1v8_s0>;
+ status = "okay";
+};
+
+&sdhci {
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
+ mmc-hs400-1_8v;
+ mmc-hs400-enhanced-strobe;
+ mmc-pwrseq = <&emmc_pwrseq>;
+ no-sdio;
+ no-sd;
+ non-removable;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_bus8 &emmc_cmd &emmc_clk &emmc_data_strobe>;
+ supports-cqe;
+ vmmc-supply = <&vcc_3v3_s3>;
+ vqmmc-supply = <&vcc_1v8_s3>;
+ status = "okay";
+};
+
+&sdmmc {
+ bus-width = <4>;
+ cap-sd-highspeed;
+ max-frequency = <150000000>;
+ vqmmc-supply = <&vccio_sd_s0>;
+};
+
+&spi0 {
+ pinctrl-0 = <&spi0m1_cs0 &spi0m1_cs1 &spi0m3_pins>;
+};
+
+&spi2 {
+ assigned-clocks = <&cru CLK_SPI2>;
+ assigned-clock-rates = <200000000>;
+ num-cs = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
+ status = "okay";
+
+ pmic@0 {
+ compatible = "rockchip,rk806";
+ reg = <0x0>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
+ <&rk806_dvs2_null>, <&rk806_dvs3_null>;
+ spi-max-frequency = <1000000>;
+ system-power-controller;
+ vcc1-supply = <&vcc5v0_sys>;
+ vcc2-supply = <&vcc5v0_sys>;
+ vcc3-supply = <&vcc5v0_sys>;
+ vcc4-supply = <&vcc5v0_sys>;
+ vcc5-supply = <&vcc5v0_sys>;
+ vcc6-supply = <&vcc5v0_sys>;
+ vcc7-supply = <&vcc5v0_sys>;
+ vcc8-supply = <&vcc5v0_sys>;
+ vcc9-supply = <&vcc5v0_sys>;
+ vcc10-supply = <&vcc5v0_sys>;
+ vcc11-supply = <&vcc_2v0_pldo_s3>;
+ vcc12-supply = <&vcc5v0_sys>;
+ vcc13-supply = <&vcc_1v1_nldo_s3>;
+ vcc14-supply = <&vcc_1v1_nldo_s3>;
+ vcca-supply = <&vcc5v0_sys>;
+
+ rk806_dvs1_null: dvs1-null-pins {
+ pins = "gpio_pwrctrl2";
+ function = "pin_fun0";
+ };
+
+ rk806_dvs2_null: dvs2-null-pins {
+ pins = "gpio_pwrctrl2";
+ function = "pin_fun0";
+ };
+
+ rk806_dvs3_null: dvs3-null-pins {
+ pins = "gpio_pwrctrl3";
+ function = "pin_fun0";
+ };
+
+ regulators {
+ vdd_gpu_s0: dcdc-reg1 {
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_gpu_s0";
+ regulator-enable-ramp-delay = <400>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_lit_s0: dcdc-reg2 {
+ regulator-name = "vdd_cpu_lit_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_log_s0: dcdc-reg3 {
+ regulator-name = "vdd_log_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <750000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ vdd_vdenc_s0: dcdc-reg4 {
+ regulator-name = "vdd_vdenc_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_ddr_s0: dcdc-reg5 {
+ regulator-name = "vdd_ddr_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <900000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ vdd2_ddr_s3: dcdc-reg6 {
+ regulator-name = "vdd2_ddr_s3";
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_2v0_pldo_s3: dcdc-reg7 {
+ regulator-name = "vcc_2v0_pldo_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <2000000>;
+ };
+ };
+
+ vcc_3v3_s3: dcdc-reg8 {
+ regulator-name = "vcc_3v3_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vddq_ddr_s0: dcdc-reg9 {
+ regulator-name = "vddq_ddr_s0";
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8_s3: dcdc-reg10 {
+ regulator-name = "vcc_1v8_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vcca_1v8_s0: pldo-reg1 {
+ regulator-name = "vcca_1v8_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8_s0: pldo-reg2 {
+ regulator-name = "vcc_1v8_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vdda_1v2_s0: pldo-reg3 {
+ regulator-name = "vdda_1v2_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcca_3v3_s0: pldo-reg4 {
+ regulator-name = "vcca_3v3_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vccio_sd_s0: pldo-reg5 {
+ regulator-name = "vccio_sd_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ pldo6_s3: pldo-reg6 {
+ regulator-name = "pldo6_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vdd_0v75_s3: nldo-reg1 {
+ regulator-name = "vdd_0v75_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ vdda_ddr_pll_s0: nldo-reg2 {
+ regulator-name = "vdda_ddr_pll_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ vdda_0v75_s0: nldo-reg3 {
+ regulator-name = "vdda_0v75_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdda_0v85_s0: nldo-reg4 {
+ regulator-name = "vdda_0v85_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_0v75_s0: nldo-reg5 {
+ regulator-name = "vdd_0v75_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+ };
+};
+
+&tsadc {
+ status = "okay";
+};
+
+/* Mule-ATtiny UPDI */
+&uart4 {
+ pinctrl-0 = <&uart4m2_xfer>;
+ status = "okay";
+};
diff --git a/arch/arm/mach-rockchip/rk3588/Kconfig b/arch/arm/mach-rockchip/rk3588/Kconfig
index d7e4af31f24..f442f797970 100644
--- a/arch/arm/mach-rockchip/rk3588/Kconfig
+++ b/arch/arm/mach-rockchip/rk3588/Kconfig
@@ -159,6 +159,36 @@ config TARGET_QUARTZPRO64_RK3588
Pine64 QuartzPro64 is a Rockchip RK3588 based SBC (Single Board
Computer) by Pine64.
+config TARGET_TIGER_RK3588
+ bool "Theobroma Systems SOM-RK3588-Q7 (Tiger)"
+ select BOARD_LATE_INIT
+ help
+ The RK3588-Q7 SoM is a Qseven-compatible (70mm x 70mm, MXM-230
+ connector) system-on-module from Theobroma Systems, featuring the
+ Rockchip RK3588.
+
+ It provides the following feature set:
+ * up to 16GB LPDDR4x
+ * on-module eMMC
+ * SD card (on a baseboard) via edge connector
+ * Gigabit Ethernet with on-module GbE PHY
+ * HDMI/eDP
+ * MIPI-DSI
+ * 4x MIPI-CSI (3x on FPC connectors, 1x over Q7)
+ * HDMI input over FPC connector
+ * CAN
+ * USB
+ - 1x USB 3.0 dual-role (direct connection)
+ - 2x USB 3.0 host + 1x USB 2.0 host
+ * PCIe
+ - 1x PCIe 2.1 Gen3, 4 lanes
+ - 2xSATA / 2x PCIe 2.1 Gen1, 2 lanes
+ * on-module ATtiny816 companion controller, implementing:
+ - low-power RTC functionality (ISL1208 emulation)
+ - fan controller (AMC6821 emulation)
+ * on-module Secure Element with Global Platform 2.2.1 compliant
+ JavaCard environment
+
config TARGET_TURINGRK1_RK3588
bool "Turing Machines RK1 RK3588 board"
select BOARD_LATE_INIT
@@ -230,5 +260,6 @@ source board/radxa/rock5b-rk3588/Kconfig
source board/rockchip/evb_rk3588/Kconfig
source board/rockchip/toybrick_rk3588/Kconfig
source board/theobroma-systems/jaguar_rk3588/Kconfig
+source board/theobroma-systems/tiger_rk3588/Kconfig
endif
diff --git a/board/theobroma-systems/tiger_rk3588/Kconfig b/board/theobroma-systems/tiger_rk3588/Kconfig
new file mode 100644
index 00000000000..2c6ac6a9a83
--- /dev/null
+++ b/board/theobroma-systems/tiger_rk3588/Kconfig
@@ -0,0 +1,16 @@
+if TARGET_TIGER_RK3588
+
+config SYS_BOARD
+ default "tiger_rk3588"
+
+config SYS_VENDOR
+ default "theobroma-systems"
+
+config SYS_CONFIG_NAME
+ default "tiger_rk3588"
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+ def_bool y
+ select ENV_IS_NOWHERE
+
+endif
diff --git a/board/theobroma-systems/tiger_rk3588/MAINTAINERS b/board/theobroma-systems/tiger_rk3588/MAINTAINERS
new file mode 100644
index 00000000000..02a2d09fe69
--- /dev/null
+++ b/board/theobroma-systems/tiger_rk3588/MAINTAINERS
@@ -0,0 +1,13 @@
+TIGER-RK3588 (SOM-RK3588-Q7)
+M: Klaus Goger <klaus.goger(a)theobroma-systems.com>
+M: Quentin Schulz <quentin.schulz(a)theobroma-systems.com>
+M: Heiko Stuebner <heiko.stuebner(a)cherry.de>
+S: Maintained
+F: board/theobroma-systems/tiger_rk3588
+F: board/theobroma-systems/common
+F: doc/board/theobroma-systems/
+F: include/configs/tiger_rk3588.h
+F: arch/arm/dts/rk3588-tiger*
+F: configs/tiger-rk3588_defconfig
+W: https://theobroma-systems.com/product/tiger-som-rk3588-q7/
+T: git git://git.theobroma-systems.com/tiger-u-boot.git
diff --git a/board/theobroma-systems/tiger_rk3588/Makefile b/board/theobroma-systems/tiger_rk3588/Makefile
new file mode 100644
index 00000000000..5c4c484657a
--- /dev/null
+++ b/board/theobroma-systems/tiger_rk3588/Makefile
@@ -0,0 +1,10 @@
+#
+# Copyright (c) 2024 Theobroma Systems Design und Consulting GmbH
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += tiger_rk3588.o
+ifneq ($(CONFIG_SPL_BUILD),y)
+obj-y += ../common/common.o
+endif
diff --git a/board/theobroma-systems/tiger_rk3588/tiger_rk3588.c b/board/theobroma-systems/tiger_rk3588/tiger_rk3588.c
new file mode 100644
index 00000000000..a6d44f10db3
--- /dev/null
+++ b/board/theobroma-systems/tiger_rk3588/tiger_rk3588.c
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2023 Theobroma Systems Design und Consulting GmbH
+ */
+
+#include <phy.h>
+#include <eth_phy.h>
+
+#include <asm/types.h>
+#include <asm/arch-rockchip/cru_rk3588.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <asm/arch-rockchip/ioc_rk3588.h>
+#include <asm-generic/u-boot.h>
+#include <dm/device.h>
+#include <dm/uclass-id.h>
+#include <linux/bitfield.h>
+
+#include "../common/common.h"
+
+#define GPIO2C3_SEL_MASK GENMASK(15, 12)
+#define GPIO2C3_ETH0_REFCLKO_25M FIELD_PREP(GPIO2C3_SEL_MASK, 1)
+
+#define REFCLKO25M_ETH0_OUT_SEL_MASK BIT(15)
+#define REFCLKO25M_ETH0_OUT_SEL_CPLL FIELD_PREP(REFCLKO25M_ETH0_OUT_SEL_MASK, 1)
+#define REFCLKO25M_ETH0_OUT_DIV_MASK GENMASK(14, 8)
+#define REFCLKO25M_ETH0_OUT_DIV(x) FIELD_PREP(REFCLKO25M_ETH0_OUT_DIV_MASK, (x) - 1)
+
+#define REFCLKO25M_ETH0_OUT_EN BIT(4)
+
+void setup_eth0refclko(void)
+{
+ /* Configure and enable ETH0_REFCLKO_25MHz */
+ static struct rk3588_bus_ioc * const bus_ioc = (void *)BUS_IOC_BASE;
+ static struct rk3588_cru * const cru = (void *)CRU_BASE;
+
+ /* 1. Pinmux */
+ rk_clrsetreg(&bus_ioc->gpio2c_iomux_sel_l, GPIO2C3_SEL_MASK, GPIO2C3_ETH0_REFCLKO_25M);
+ /* 2. Parent clock selection + divider => CPLL (1.5GHz) / 60 => 25MHz */
+ rk_clrsetreg(&cru->clksel_con[15],
+ REFCLKO25M_ETH0_OUT_SEL_MASK | REFCLKO25M_ETH0_OUT_DIV_MASK,
+ REFCLKO25M_ETH0_OUT_SEL_CPLL | REFCLKO25M_ETH0_OUT_DIV(60));
+ /* 3. Enable clock */
+ rk_clrreg(&cru->clkgate_con[5], REFCLKO25M_ETH0_OUT_EN);
+}
+
+int rockchip_early_misc_init_r(void)
+{
+ setup_boottargets();
+
+ setup_eth0refclko();
+
+ return 0;
+}
diff --git a/configs/tiger-rk3588_defconfig b/configs/tiger-rk3588_defconfig
new file mode 100644
index 00000000000..e532b5e07c7
--- /dev/null
+++ b/configs/tiger-rk3588_defconfig
@@ -0,0 +1,114 @@
+CONFIG_ARM=y
+CONFIG_SKIP_LOWLEVEL_INIT=y
+CONFIG_COUNTER_FREQUENCY=24000000
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_SPL_GPIO=y
+CONFIG_SF_DEFAULT_SPEED=24000000
+CONFIG_SF_DEFAULT_MODE=0x2000
+CONFIG_ENV_SIZE=0x1f000
+CONFIG_DEFAULT_DEVICE_TREE="rk3588-tiger-haikou"
+CONFIG_ROCKCHIP_RK3588=y
+CONFIG_ROCKCHIP_BOOT_MODE_REG=0x0
+CONFIG_SPL_SERIAL=y
+CONFIG_TARGET_TIGER_RK3588=y
+CONFIG_DEBUG_UART_BASE=0xfeb50000
+CONFIG_DEBUG_UART_CLOCK=24000000
+# CONFIG_DEBUG_UART_BOARD_INIT is not set
+CONFIG_SYS_LOAD_ADDR=0xc00800
+CONFIG_DEBUG_UART=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_SPL_FIT_SIGNATURE=y
+CONFIG_SPL_LOAD_FIT=y
+# CONFIG_BOOTMETH_VBE is not set
+CONFIG_LEGACY_IMAGE_FORMAT=y
+CONFIG_DEFAULT_FDT_FILE="rockchip/rk3588-tiger-haikou.dtb"
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_CYCLIC=y
+CONFIG_SPL_MAX_SIZE=0x40000
+CONFIG_SPL_PAD_TO=0x7f8000
+# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
+CONFIG_SPL_ATF=y
+# CONFIG_BOOTM_NETBSD is not set
+# CONFIG_BOOTM_PLAN9 is not set
+# CONFIG_BOOTM_RTEMS is not set
+# CONFIG_BOOTM_VXWORKS is not set
+# CONFIG_CMD_ELF is not set
+CONFIG_CMD_ADC=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_I2C=y
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_MMC=y
+# CONFIG_CMD_SF is not set
+CONFIG_CMD_USB=y
+# CONFIG_CMD_SETEXPR is not set
+# CONFIG_CMD_MII is not set
+# CONFIG_CMD_BLOCK_CACHE is not set
+# CONFIG_CMD_EFICONFIG is not set
+CONFIG_CMD_PMIC=y
+CONFIG_CMD_REGULATOR=y
+CONFIG_CMD_EROFS=y
+CONFIG_CMD_SQUASHFS=y
+# CONFIG_SPL_DOS_PARTITION is not set
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_LIVE=y
+# CONFIG_OF_TAG_MIGRATE is not set
+CONFIG_OF_SPL_REMOVE_PROPS="interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
+CONFIG_ENV_OVERWRITE=y
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_SPL_REGMAP=y
+CONFIG_SPL_SYSCON=y
+CONFIG_BUTTON=y
+CONFIG_BUTTON_GPIO=y
+CONFIG_SPL_CLK=y
+CONFIG_CLK_GPIO=y
+CONFIG_ROCKCHIP_GPIO=y
+CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_MISC=y
+CONFIG_SUPPORT_EMMC_RPMB=y
+CONFIG_MMC_IO_VOLTAGE=y
+CONFIG_SPL_MMC_IO_VOLTAGE=y
+CONFIG_MMC_UHS_SUPPORT=y
+CONFIG_SPL_MMC_UHS_SUPPORT=y
+CONFIG_MMC_HS400_ES_SUPPORT=y
+CONFIG_SPL_MMC_HS400_ES_SUPPORT=y
+CONFIG_MMC_HS400_SUPPORT=y
+CONFIG_SPL_MMC_HS400_SUPPORT=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_SDMA=y
+CONFIG_MMC_SDHCI_ROCKCHIP=y
+# CONFIG_SPI_FLASH is not set
+CONFIG_SF_DEFAULT_BUS=5
+CONFIG_PHY_MICREL=y
+CONFIG_PHY_MICREL_KSZ90X1=y
+CONFIG_DWC_ETH_QOS=y
+CONFIG_DWC_ETH_QOS_ROCKCHIP=y
+CONFIG_PHY_ROCKCHIP_INNO_USB2=y
+CONFIG_PHY_ROCKCHIP_NANENG_COMBOPHY=y
+CONFIG_PHY_ROCKCHIP_USBDP=y
+CONFIG_SPL_PINCTRL=y
+CONFIG_DM_PMIC=y
+CONFIG_PMIC_RK8XX=y
+CONFIG_REGULATOR_RK8XX=y
+CONFIG_SPL_RAM=y
+CONFIG_SCSI=y
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYS_NS16550_MEM32=y
+CONFIG_ROCKCHIP_SPI=y
+CONFIG_SYSRESET=y
+CONFIG_USB=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_GENERIC=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_DWC3_GENERIC=y
+CONFIG_ERRNO_STR=y
diff --git a/doc/board/rockchip/rockchip.rst b/doc/board/rockchip/rockchip.rst
index 5dd5ea7f1e2..f5a05596f57 100644
--- a/doc/board/rockchip/rockchip.rst
+++ b/doc/board/rockchip/rockchip.rst
@@ -128,6 +128,7 @@ List of mainline supported Rockchip boards:
- Radxa ROCK 5B (rock5b-rk3588)
- Rockchip Toybrick TB-RK3588X (toybrick-rk3588)
- Theobroma Systems RK3588-SBC Jaguar (jaguar-rk3588)
+ - Theobroma Systems SOM-RK3588-Q7 - Tiger (tiger-rk3588)
- Turing Machines RK1 (turing-rk1-rk3588)
- Xunlong Orange Pi 5 (orangepi-5-rk3588s)
- Xunlong Orange Pi 5 Plus (orangepi-5-plus-rk3588)
diff --git a/doc/board/theobroma-systems/index.rst b/doc/board/theobroma-systems/index.rst
index b4da2616c37..73e07f7ebfa 100644
--- a/doc/board/theobroma-systems/index.rst
+++ b/doc/board/theobroma-systems/index.rst
@@ -9,3 +9,4 @@ Theobroma Systems
jaguar_rk3588
puma_rk3399
ringneck_px30
+ tiger_rk3588
diff --git a/doc/board/theobroma-systems/tiger_rk3588.rst b/doc/board/theobroma-systems/tiger_rk3588.rst
new file mode 100644
index 00000000000..a73eec7fb9b
--- /dev/null
+++ b/doc/board/theobroma-systems/tiger_rk3588.rst
@@ -0,0 +1,102 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+SOM-RK3588-Q7 Tiger
+===================
+
+The RK3588-Q7 SoM is a Qseven-compatible (70mm x 70mm, MXM-230
+connector) system-on-module from Theobroma Systems, featuring the
+Rockchip RK3588.
+
+It provides the following feature set:
+ * up to 16GB LPDDR4x
+ * on-module eMMC
+ * SD card (on a baseboard) via edge connector
+ * Gigabit Ethernet with on-module GbE PHY
+ * HDMI/eDP
+ * MIPI-DSI
+ * 4x MIPI-CSI (3x on FPC connectors, 1x over Q7)
+ * HDMI input over FPC connector
+ * CAN
+ * USB
+ - 1x USB 3.0 dual-role (direct connection)
+ - 2x USB 3.0 host + 1x USB 2.0 host
+ * PCIe
+ - 1x PCIe 2.1 Gen3, 4 lanes
+ - 2xSATA / 2x PCIe 2.1 Gen1, 2 lanes
+ * on-module ATtiny816 companion controller, implementing:
+ - low-power RTC functionality (ISL1208 emulation)
+ - fan controller (AMC6821 emulation)
+ * on-module Secure Element with Global Platform 2.2.1 compliant
+ JavaCard environment
+
+Here is the step-by-step to boot to U-Boot on SOM-RK3588-Q7 Tiger from Theobroma
+Systems.
+
+Get the TF-A and DDR init (TPL) binaries
+----------------------------------------
+
+.. prompt:: bash
+
+ git clone https://github.com/rockchip-linux/rkbin
+ cd rkbin
+ export RKBIN=$(pwd)
+ export BL31=$RKBIN/bin/rk35/rk3588_bl31_v1.38.elf
+ export ROCKCHIP_TPL=$RKBIN/bin/rk35/rk3588_ddr_lp4_2112MHz_lp5_2736MHz_v1.11.bin
+ sed -i 's/^uart baudrate=.*$/uart baudrate=115200/' tools/ddrbin_param.txt
+ sed -i 's/^uart iomux=.*$/uart iomux=2/' tools/ddrbin_param.txt
+ ./tools/ddrbin_tool tools/ddrbin_param.txt "$ROCKCHIP_TPL"
+ ./tools/boot_merger RKBOOT/RK3588MINIALL.ini
+ export RKDB=$RKBIN/rk3588_spl_loader_v1.11.112.bin
+
+This will setup all required external dependencies for compiling U-Boot. This will
+be updated in the future once upstream Trusted-Firmware-A supports RK3588 or U-Boot
+gains support for open-source DRAM initialization in TPL.
+
+Build U-Boot
+------------
+
+.. prompt:: bash
+
+ cd ../u-boot
+ make CROSS_COMPILE=aarch64-linux-gnu- tiger-rk3588_defconfig all
+
+This will build ``u-boot-rockchip.bin`` which can be written to an MMC device
+(eMMC or SD card).
+
+Flash the image
+---------------
+
+Copy ``u-boot-rockchip.bin`` to offset 32k for SD/eMMC.
+
+SD-Card
+~~~~~~~
+
+.. prompt:: bash
+
+ dd if=u-boot-rockchip.bin of=/dev/sdX seek=64
+
+.. note::
+
+ Replace ``/dev/sdX`` to match your SD card kernel device.
+
+eMMC
+~~~~
+
+``rkdeveloptool`` allows to flash the on-board eMMC via the USB OTG interface
+with help of the Rockchip loader binary.
+
+To enter the USB flashing mode on Haikou baseboard, remove any SD card, insert a
+micro-USB cable in the ``Q7 USB P1`` connector (P8), move ``SW5`` switch into
+``BIOS Disable`` mode, power cycle or reset the board and move ``SW5`` switch
+back to ``Normal Boot`` mode. A new USB device should have appeared on your PC
+(check with ``lsusb -d 2207:350b``).
+
+To flash U-Boot on the eMMC with ``rkdeveloptool``:
+
+.. prompt:: bash
+
+ git clone https://github.com/rockchip-linux/rkdeveloptool
+ cd rkdeveloptool
+ autoreconf -i && CPPFLAGS=-Wno-format-truncation ./configure && make
+ ./rkdeveloptool db "$RKDB"
+ ./rkdeveloptool wl 64 ../u-boot-rockchip.bin
diff --git a/include/configs/tiger_rk3588.h b/include/configs/tiger_rk3588.h
new file mode 100644
index 00000000000..7a32adfaf2a
--- /dev/null
+++ b/include/configs/tiger_rk3588.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2023 Theobroma Systems Design und Consulting GmbH
+ */
+
+#ifndef __TIGER_RK3588_H
+#define __TIGER_RK3588_H
+
+#define ROCKCHIP_DEVICE_SETTINGS \
+ "stdout=serial,vidconsole\0" \
+ "stderr=serial,vidconsole\0"
+
+#include <configs/rk3588_common.h>
+
+#endif /* __TIGER_RK3588_H */
---
base-commit: 5fb840ed8339cae3915ea1528a4bfa3e587540e6
change-id: 20240418-tiger-d1531308c9a0
Best regards,
--
Quentin Schulz <quentin.schulz(a)theobroma-systems.com>
4
4
From: Alexander Sverdlin <alexander.sverdlin(a)siemens.com>
While there are happy users who successfully have been using DFU on TI
AM62x [1][2], there are also others who were not so lucky up to now [3].
I felt into latter category and was wondering why I observe this:
--
U-Boot SPL 2024.04-61876f393762 (Apr 11 2024 - 09:27:15 +0000)
...
Trying to boot from DFU
dwc3-generic-peripheral usb@31000000: found 16 IN and 16 OUT endpoints
dwc3-generic-peripheral usb@31000000: Event buf 81e0a200 dma 00000000x length -2115984896
...
dwc3-generic-peripheral usb@31000000: initializing ep0out
...
dwc3-generic-peripheral usb@31000000: initializing ep15in
registering UDC driver []
dwc3-generic-peripheral usb@31000000: gadget no-function data soft-connect
dwc3-generic-peripheral usb@31000000: Enabling ep0out
dwc3-generic-peripheral usb@31000000: Command Complete --> 0
dwc3-generic-peripheral usb@31000000: failed to enable ep0out
failed to start : -110
g_dnl_register: failed!, error: -110
g_dnl_register failedSPL: failed to boot from all boot devices
### ERROR ### Please RESET the board ###
--
It turned out the timeout happened in dwc3_send_gadget_ep_cmd() on
DWC3_DEPCMD_SETEPCONFIG command and while the "timeout" has been increased
in Linux from 500 to 1000 and later 5000, in my case it took more than
77000 1us cycles to successfully complete.
It turns out that Linux DWC3 gadget code has been improved in the meanwhile
to follow DWC3 programming guide more precisely. Porting the following
Linux patches solved the timeout issue in U-Boot SPL on TI AM6232.
Strictly speaking
"usb: dwc3: gadget: Disable GUSB2PHYCFG.SUSPHY for End Transfer" and
"usb: dwc3: gadget: properly check ep cmd" are not required to tackle
the observed timeout, but it keeps the whole code block in sync with
Linux v6.8.
Felipe Balbi (4):
usb: dwc3: gadget: combine return points into a single one
usb: dwc3: gadget: clear SUSPHY bit before ep cmds
usb: dwc3: gadget: only resume USB2 PHY in <=HIGHSPEED
usb: dwc3: gadget: properly check ep cmd
Thinh Nguyen (2):
usb: dwc3: gadget: Check ENBLSLPM before sending ep command
usb: dwc3: gadget: Disable GUSB2PHYCFG.SUSPHY for End Transfer
drivers/usb/dwc3/core.h | 2 ++
drivers/usb/dwc3/gadget.c | 47 ++++++++++++++++++++++++++++++++++++---
2 files changed, 46 insertions(+), 3 deletions(-)
1: https://git.ti.com/cgit/ti-u-boot/ti-u-boot/tree/configs/am62x_evm_r5_usbdf…
2: https://lore.kernel.org/all/20240112085317.1866449-1-sjoerd@collabora.com/T/
3: https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1…
--
2.44.0
3
14

[PATCH 1/5] net: eth-uclass: guard against reentrant eth_init()/eth_halt() calls
by Matthias Schiffer 16 May '24
by Matthias Schiffer 16 May '24
16 May '24
With netconsole, any log message can result in an eth_init(), possibly
causing an reentrant call into eth_init() if a driver's ops print
anything:
eth_init() -> driver.start() -> printf() -> netconsole -> eth_init()
eth_halt() -> driver.stop() -> printf() -> netconsole -> eth_init()
Rather than expecting every single Ethernet driver to handle this case,
prevent the reentrant calls in eth_init() and eth_halt().
The issue was noticed on an AM62x board, where a bootm after
simultaneous netconsole and TFTP would result in a crash.
Signed-off-by: Matthias Schiffer <matthias.schiffer(a)ew.tq-group.com>
---
net/eth-uclass.c | 40 ++++++++++++++++++++++++++++++++--------
1 file changed, 32 insertions(+), 8 deletions(-)
diff --git a/net/eth-uclass.c b/net/eth-uclass.c
index 3d0ec91dfa4..193218a328b 100644
--- a/net/eth-uclass.c
+++ b/net/eth-uclass.c
@@ -48,6 +48,8 @@ struct eth_uclass_priv {
/* eth_errno - This stores the most recent failure code from DM functions */
static int eth_errno;
+/* Are we currently in eth_init() or eth_halt()? */
+static bool in_init_halt;
/* board-specific Ethernet Interface initializations. */
__weak int board_interface_eth_init(struct udevice *dev,
@@ -285,11 +287,19 @@ U_BOOT_ENV_CALLBACK(ethaddr, on_ethaddr);
int eth_init(void)
{
- char *ethact = env_get("ethact");
- char *ethrotate = env_get("ethrotate");
struct udevice *current = NULL;
struct udevice *old_current;
int ret = -ENODEV;
+ char *ethrotate;
+ char *ethact;
+
+ if (in_init_halt)
+ return -EBUSY;
+
+ in_init_halt = true;
+
+ ethact = env_get("ethact");
+ ethrotate = env_get("ethrotate");
/*
* When 'ethrotate' variable is set to 'no' and 'ethact' variable
@@ -298,8 +308,10 @@ int eth_init(void)
if ((ethrotate != NULL) && (strcmp(ethrotate, "no") == 0)) {
if (ethact) {
current = eth_get_dev_by_name(ethact);
- if (!current)
- return -EINVAL;
+ if (!current) {
+ ret = -EINVAL;
+ goto end;
+ }
}
}
@@ -307,7 +319,8 @@ int eth_init(void)
current = eth_get_dev();
if (!current) {
log_err("No ethernet found.\n");
- return -ENODEV;
+ ret = -ENODEV;
+ goto end;
}
}
@@ -324,7 +337,8 @@ int eth_init(void)
priv->state = ETH_STATE_ACTIVE;
priv->running = true;
- return 0;
+ ret = 0;
+ goto end;
}
} else {
ret = eth_errno;
@@ -344,6 +358,8 @@ int eth_init(void)
current = eth_get_dev();
} while (old_current != current);
+end:
+ in_init_halt = false;
return ret;
}
@@ -352,17 +368,25 @@ void eth_halt(void)
struct udevice *current;
struct eth_device_priv *priv;
+ if (in_init_halt)
+ return;
+
+ in_init_halt = true;
+
current = eth_get_dev();
if (!current)
- return;
+ goto end;
priv = dev_get_uclass_priv(current);
if (!priv || !priv->running)
- return;
+ goto end;
eth_get_ops(current)->stop(current);
priv->state = ETH_STATE_PASSIVE;
priv->running = false;
+
+end:
+ in_init_halt = false;
}
int eth_is_active(struct udevice *dev)
--
TQ-Systems GmbH | Mühlstraße 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht München, HRB 105018
Geschäftsführer: Detlef Schneider, Rüdiger Stahl, Stefan Schneider
https://www.tq-group.com/
4
7
Hi Stefan,
this series adds some changes to DDR3 training for Armada 38x and
Turris Omnia.
- patches 1-4 are meant to allow for reducing another 10 KiB in the
SPL binary. They were also sent to mv-ddr-marvell, via PR on github,
https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell/pull/45/
but I am told that Armada team has left Marvell, so who knows if this
will ever be merged there
- patch 5 enables this reduction for Turris Omnia
- patches 6-8 import old DDR3 training code and make some changes so
that it works with U-Boot. The reason why this is being done is
explained in patch 6
- patch 9 glues the old DDR3 training code to current U-Boot
- patch 10 allows for dynamic selection of old DDR3 training code on
Turris Omnia, via an U-Boot environment variable
Marek
Marek Behún (10):
ddr: marvell: a38x: debug: return from ddr3_tip_print_log() early if
we won't print anything
ddr: marvell: a38x: debug: Remove unused variables
ddr: marvell: a38x: debug: Define DDR_VIEWER_TOOL variables only if
needed, and make them static
ddr: marvell: a38x: debug: Allow compiling with immutable debug
settings to reduce binary size
arm: mvebu: turris_omnia: Enable immutable debug settings in DDR3
training by default
ddr: marvell: a38x: Import old DDR training code from 2017 version of
U-Boot
ddr: marvell: a38x: old: Fix some compiler warning of the old code
ddr: marvell: a38x: old: Backport immutable debug settings
arm: mvebu: a38x: Add optional support for using old DDR3 training
code
arm: mvebu: turris_omnia: Support old DDR3 training, selectable via
env var
arch/arm/mach-mvebu/Kconfig | 15 +
arch/arm/mach-mvebu/include/mach/cpu.h | 1 +
arch/arm/mach-mvebu/spl.c | 37 +-
board/CZ.NIC/turris_omnia/Makefile | 1 +
board/CZ.NIC/turris_omnia/old_ddr3_training.c | 79 +
board/CZ.NIC/turris_omnia/turris_omnia.c | 2 +-
configs/turris_omnia_defconfig | 1 +
drivers/ddr/marvell/a38x/Makefile | 2 +
drivers/ddr/marvell/a38x/ddr3_debug.c | 30 +-
drivers/ddr/marvell/a38x/ddr3_init.c | 3 +-
drivers/ddr/marvell/a38x/ddr3_init.h | 43 +-
drivers/ddr/marvell/a38x/old/Makefile | 29 +
drivers/ddr/marvell/a38x/old/ddr3_a38x.c | 738 +++++
drivers/ddr/marvell/a38x/old/ddr3_a38x.h | 93 +
.../marvell/a38x/old/ddr3_a38x_mc_static.h | 226 ++
.../ddr/marvell/a38x/old/ddr3_a38x_topology.h | 22 +
.../ddr/marvell/a38x/old/ddr3_a38x_training.c | 40 +
drivers/ddr/marvell/a38x/old/ddr3_debug.c | 1545 ++++++++++
.../marvell/a38x/old/ddr3_hws_hw_training.c | 148 +
.../marvell/a38x/old/ddr3_hws_hw_training.h | 49 +
.../a38x/old/ddr3_hws_hw_training_def.h | 464 +++
.../marvell/a38x/old/ddr3_hws_sil_training.h | 17 +
drivers/ddr/marvell/a38x/old/ddr3_init.c | 770 +++++
drivers/ddr/marvell/a38x/old/ddr3_init.h | 405 +++
.../ddr/marvell/a38x/old/ddr3_logging_def.h | 101 +
.../marvell/a38x/old/ddr3_patterns_64bit.h | 924 ++++++
.../ddr/marvell/a38x/old/ddr3_topology_def.h | 76 +
drivers/ddr/marvell/a38x/old/ddr3_training.c | 2651 +++++++++++++++++
.../ddr/marvell/a38x/old/ddr3_training_bist.c | 289 ++
.../a38x/old/ddr3_training_centralization.c | 712 +++++
.../ddr/marvell/a38x/old/ddr3_training_db.c | 652 ++++
.../marvell/a38x/old/ddr3_training_hw_algo.c | 686 +++++
.../marvell/a38x/old/ddr3_training_hw_algo.h | 14 +
.../ddr/marvell/a38x/old/ddr3_training_ip.h | 178 ++
.../marvell/a38x/old/ddr3_training_ip_bist.h | 54 +
.../old/ddr3_training_ip_centralization.h | 15 +
.../marvell/a38x/old/ddr3_training_ip_db.h | 34 +
.../marvell/a38x/old/ddr3_training_ip_def.h | 173 ++
.../a38x/old/ddr3_training_ip_engine.c | 1355 +++++++++
.../a38x/old/ddr3_training_ip_engine.h | 85 +
.../marvell/a38x/old/ddr3_training_ip_flow.h | 349 +++
.../marvell/a38x/old/ddr3_training_ip_pbs.h | 41 +
.../a38x/old/ddr3_training_ip_prv_if.h | 107 +
.../a38x/old/ddr3_training_ip_static.h | 31 +
.../marvell/a38x/old/ddr3_training_leveling.c | 1837 ++++++++++++
.../marvell/a38x/old/ddr3_training_leveling.h | 17 +
.../ddr/marvell/a38x/old/ddr3_training_pbs.c | 995 +++++++
.../marvell/a38x/old/ddr3_training_static.c | 538 ++++
.../ddr/marvell/a38x/old/ddr_topology_def.h | 121 +
.../ddr/marvell/a38x/old/ddr_training_ip_db.h | 16 +
.../marvell/a38x/old/glue_symbol_renames.h | 247 ++
drivers/ddr/marvell/a38x/old/silicon_if.h | 17 +
drivers/ddr/marvell/a38x/old/xor.h | 92 +
53 files changed, 17138 insertions(+), 29 deletions(-)
create mode 100644 board/CZ.NIC/turris_omnia/old_ddr3_training.c
create mode 100644 drivers/ddr/marvell/a38x/old/Makefile
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_a38x.c
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_a38x.h
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_a38x_mc_static.h
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_a38x_topology.h
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_a38x_training.c
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_debug.c
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_hws_hw_training.c
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_hws_hw_training.h
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_hws_hw_training_def.h
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_hws_sil_training.h
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_init.c
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_init.h
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_logging_def.h
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_patterns_64bit.h
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_topology_def.h
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_training.c
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_training_bist.c
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_training_centralization.c
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_training_db.c
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_training_hw_algo.c
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_training_hw_algo.h
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_training_ip.h
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_training_ip_bist.h
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_training_ip_centralization.h
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_training_ip_db.h
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_training_ip_def.h
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_training_ip_engine.c
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_training_ip_engine.h
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_training_ip_flow.h
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_training_ip_pbs.h
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_training_ip_prv_if.h
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_training_ip_static.h
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_training_leveling.c
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_training_leveling.h
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_training_pbs.c
create mode 100644 drivers/ddr/marvell/a38x/old/ddr3_training_static.c
create mode 100644 drivers/ddr/marvell/a38x/old/ddr_topology_def.h
create mode 100644 drivers/ddr/marvell/a38x/old/ddr_training_ip_db.h
create mode 100644 drivers/ddr/marvell/a38x/old/glue_symbol_renames.h
create mode 100644 drivers/ddr/marvell/a38x/old/silicon_if.h
create mode 100644 drivers/ddr/marvell/a38x/old/xor.h
--
2.43.2
3
18

14 May '24
eMMC devices have hardware partitions such as user, boot0, and boot1.
Add an enumerated type defining the hardware partition values and an
array of names describing them by name that can be used throughout
U-Boot.
Allow these names to be displayed when reading and used when setting
the mmc PARTITION_CONFIG field via 'mmc partconf'.
Before:
u-boot=> mmc partconf 2 1 1 0 && mmc partconf 2
EXT_CSD[179], PARTITION_CONFIG:
BOOT_ACK: 0x1
BOOT_PARTITION_ENABLE: 0x2
PARTITION_ACCESS: 0x0
After:
u-boot=> mmc partconf 2 1 1 0 && mmc partconf 2
EXT_CSD[179], PARTITION_CONFIG:
BOOT_ACK: 0x1
BOOT_PARTITION_ENABLE: 0x1 (boot0)
PARTITION_ACCESS: 0x0
u-boot=> mmc partconf 2 1 boot1 0 && mmc partconf 2
EXT_CSD[179], PARTITION_CONFIG:
BOOT_ACK: 0x1
BOOT_PARTITION_ENABLE: 0x2 (boot1)
PARTITION_ACCESS: 0x0
Signed-off-by: Tim Harvey <tharvey(a)gateworks.com>
---
v3:
- define partition names and values in mmc.h/mmc.c for others to use
v2:
- fix typo in subject
- add names for gp1..gp4
---
cmd/mmc.c | 14 +++++++++++---
drivers/mmc/mmc.c | 11 +++++++++++
include/mmc.h | 15 +++++++++++++++
3 files changed, 37 insertions(+), 3 deletions(-)
diff --git a/cmd/mmc.c b/cmd/mmc.c
index 2d5430a53079..26ab4450816b 100644
--- a/cmd/mmc.c
+++ b/cmd/mmc.c
@@ -14,6 +14,7 @@
#include <part.h>
#include <sparse_format.h>
#include <image-sparse.h>
+#include <linux/ctype.h>
static int curr_device = -1;
@@ -918,8 +919,8 @@ static int mmc_partconf_print(struct mmc *mmc, const char *varname)
printf("EXT_CSD[179], PARTITION_CONFIG:\n"
"BOOT_ACK: 0x%x\n"
- "BOOT_PARTITION_ENABLE: 0x%x\n"
- "PARTITION_ACCESS: 0x%x\n", ack, part, access);
+ "BOOT_PARTITION_ENABLE: 0x%x (%s)\n"
+ "PARTITION_ACCESS: 0x%x\n", ack, part, emmc_hwpart_names[part], access);
return CMD_RET_SUCCESS;
}
@@ -949,7 +950,14 @@ static int do_mmc_partconf(struct cmd_tbl *cmdtp, int flag,
return mmc_partconf_print(mmc, cmd_arg2(argc, argv));
ack = dectoul(argv[2], NULL);
- part_num = dectoul(argv[3], NULL);
+ if (!isdigit(*argv[3])) {
+ for (part_num = 0; part_num <= EMMC_HWPART_USER; part_num++) {
+ if (!strcmp(argv[3], emmc_hwpart_names[part_num]))
+ break;
+ }
+ } else {
+ part_num = dectoul(argv[3], NULL);
+ }
access = dectoul(argv[4], NULL);
/* acknowledge to be sent during boot operation */
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 7b068c71ff37..132afe1b8a29 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -29,6 +29,17 @@
#define DEFAULT_CMD6_TIMEOUT_MS 500
+const char *emmc_hwpart_names[] = {
+ "user",
+ "boot0",
+ "boot1",
+ "gp1",
+ "gp2",
+ "gp3",
+ "gp4",
+ "user",
+};
+
static int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage);
#if !CONFIG_IS_ENABLED(DM_MMC)
diff --git a/include/mmc.h b/include/mmc.h
index 4b8327f1f93b..7243bd761202 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -381,6 +381,21 @@ enum mmc_voltage {
#define MMC_TIMING_MMC_HS200 9
#define MMC_TIMING_MMC_HS400 10
+/* emmc hardware partition values */
+enum emmc_hwpart {
+ EMMC_HWPART_DEFAULT = 0,
+ EMMC_HWPART_BOOT0 = 1,
+ EMMC_HWPART_BOOT1 = 2,
+ EMMC_HWPART_GP1 = 3,
+ EMMC_HWPART_GP2 = 4,
+ EMMC_HWPART_GP3 = 5,
+ EMMC_HWPART_GP4 = 6,
+ EMMC_HWPART_USER = 7,
+};
+
+/* emmc hardware partition names */
+extern const char *emmc_hwpart_names[];
+
/* Driver model support */
/**
--
2.25.1
4
12
1. Use vendor naming rule to rename each function
2. add SHA 384/512 support
Signed-off-by: Jim Liu <JJLIU0(a)nuvoton.com>
---
drivers/crypto/nuvoton/npcm_sha.c | 1024 +++++++----------------------
1 file changed, 252 insertions(+), 772 deletions(-)
diff --git a/drivers/crypto/nuvoton/npcm_sha.c b/drivers/crypto/nuvoton/npcm_sha.c
index 7ebdfa16f4..2a5e672688 100644
--- a/drivers/crypto/nuvoton/npcm_sha.c
+++ b/drivers/crypto/nuvoton/npcm_sha.c
@@ -1,868 +1,345 @@
// SPDX-License-Identifier: GPL-2.0+
/*
- * Copyright (c) 2022 Nuvoton Technology Corp.
+ * Copyright (c) 2024 Nuvoton Technology Corp.
*/
#include <common.h>
#include <dm.h>
#include <hash.h>
#include <malloc.h>
-#include <uboot_aes.h>
#include <asm/io.h>
+#include <linux/iopoll.h>
-#define HASH_DIG_H_NUM 8
+#define SHA512_BLOCK_LENGTH (1024 / 8)
+/* Register fields */
#define HASH_CTR_STS_SHA_EN BIT(0)
#define HASH_CTR_STS_SHA_BUSY BIT(1)
#define HASH_CTR_STS_SHA_RST BIT(2)
#define HASH_CFG_SHA1_SHA2 BIT(0)
-
-/* SHA type */
-enum npcm_sha_type {
- npcm_sha_type_sha2 = 0,
- npcm_sha_type_sha1,
- npcm_sha_type_num
+#define SHA512_CMD_SHA_512 BIT(3)
+#define SHA512_CMD_INTERNAL_ROUND BIT(2)
+#define SHA512_CMD_WRITE BIT(1)
+#define SHA512_CMD_READ BIT(0)
+
+enum {
+ type_sha1 = 0,
+ type_sha256,
+ type_sha384,
+ type_sha512,
};
struct npcm_sha_regs {
- unsigned int hash_data_in;
- unsigned char hash_ctr_sts;
- unsigned char reserved_0[0x03];
- unsigned char hash_cfg;
- unsigned char reserved_1[0x03];
- unsigned char hash_ver;
- unsigned char reserved_2[0x13];
- unsigned int hash_dig[HASH_DIG_H_NUM];
+ u8 data_in;
+ u8 data_out;
+ u8 ctr_sts;
+ u8 hash_cfg;
+ u8 sha512_cmd;
};
-struct npcm_sha_priv {
- struct npcm_sha_regs *regs;
+struct hash_info {
+ u32 block_sz;
+ u32 digest_len;
+ u8 length_bytes;
+ u8 type;
};
-static struct npcm_sha_priv *sha_priv;
+struct message_block {
+ u64 length[2];
+ u64 nonhash_sz;
+ u8 buffer[SHA512_BLOCK_LENGTH * 2];
+};
-#ifdef SHA_DEBUG_MODULE
-#define sha_print(fmt, args...) printf(fmt, ##args)
-#else
-#define sha_print(fmt, args...) (void)0
-#endif
-
-#define SHA_BLOCK_LENGTH (512 / 8)
-#define SHA_2_HASH_LENGTH (256 / 8)
-#define SHA_1_HASH_LENGTH (160 / 8)
-#define SHA_HASH_LENGTH(type) ((type == npcm_sha_type_sha2) ? \
- (SHA_2_HASH_LENGTH) : (SHA_1_HASH_LENGTH))
-
-#define SHA_SECRUN_BUFF_SIZE 64
-#define SHA_TIMEOUT 100
-#define SHA_DATA_LAST_BYTE 0x80
-
-#define SHA2_NUM_OF_SELF_TESTS 3
-#define SHA1_NUM_OF_SELF_TESTS 4
-
-#define NUVOTON_ALIGNMENT 4
-
-/*-----------------------------------------------------------------------------*/
-/* SHA instance struct handler */
-/*-----------------------------------------------------------------------------*/
-struct SHA_HANDLE_T {
- u32 hv[SHA_2_HASH_LENGTH / sizeof(u32)];
- u32 length0;
- u32 length1;
- u32 block[SHA_BLOCK_LENGTH / sizeof(u32)];
- u8 type;
- bool active;
+struct npcm_sha_priv {
+ void *base;
+ struct npcm_sha_regs *regs;
+ struct hash_info *hash;
+ struct message_block block;
+ bool internal_round;
+ bool support_sha512;
};
-// The # of bytes currently in the sha block buffer
-#define SHA_BUFF_POS(length) ((length) & (SHA_BLOCK_LENGTH - 1))
-
-// The # of free bytes in the sha block buffer
-#define SHA_BUFF_FREE(length) (SHA_BLOCK_LENGTH - SHA_BUFF_POS(length))
-
-static void SHA_FlushLocalBuffer_l(const u32 *buff);
-static int SHA_BusyWait_l(void);
-static void SHA_GetShaDigest_l(u8 *hashdigest, u8 type);
-static void SHA_SetShaDigest_l(const u32 *hashdigest, u8 type);
-static void SHA_SetBlock_l(const u8 *data, u32 len, u16 position, u32 *block);
-static void SHA_ClearBlock_l(u16 len, u16 position, u32 *block);
-static void SHA_SetLength32_l(struct SHA_HANDLE_T *handleptr, u32 *block);
-
-static int SHA_Init(struct SHA_HANDLE_T *handleptr);
-static int SHA_Start(struct SHA_HANDLE_T *handleptr, u8 type);
-static int SHA_Update(struct SHA_HANDLE_T *handleptr, const u8 *buffer, u32 len);
-static int SHA_Finish(struct SHA_HANDLE_T *handleptr, u8 *hashdigest);
-static int SHA_Reset(void);
-static int SHA_Power(bool on);
-#ifdef SHA_PRINT
-static void SHA_PrintRegs(void);
-static void SHA_PrintVersion(void);
-#endif
-
-static struct SHA_HANDLE_T sha_handle;
-
-/*----------------------------------------------------------------------------*/
-/* Checks if give function returns int error, and returns the error */
-/* immediately after SHA disabling */
-/*----------------------------------------------------------------------------*/
-int npcm_sha_check(int status)
-{
- if (status != 0) {
- SHA_Power(false);
- return status;
- }
- return 0;
-}
+static struct npcm_sha_regs npcm_sha_reg_tbl[] = {
+ { .data_in = 0x0, .data_out = 0x20, .ctr_sts = 0x4, .hash_cfg = 0x8 },
+ { .data_in = 0x10, .data_out = 0x1c, .ctr_sts = 0x14, .sha512_cmd = 0x18 },
+};
-/*----------------------------------------------------------------------------*/
-/* Function: npcm_sha_calc */
-/* */
-/* Parameters: type - SHA module type */
-/* inBuff - Pointer to a buffer containing the data to */
-/* be hashed */
-/* len - Length of the data to hash */
-/* hashDigest - Pointer to a buffer where the reseulting */
-/* digest will be copied to */
-/* */
-/* Returns: 0 on success or other int error code on error */
-/* Side effects: */
-/* Description: */
-/* This routine performs complete SHA calculation in one */
-/* step */
-/*----------------------------------------------------------------------------*/
-int npcm_sha_calc(u8 type, const u8 *inbuff, u32 len, u8 *hashdigest)
-{
- int status;
- struct SHA_HANDLE_T handle;
-
- SHA_Init(&handle);
- SHA_Power(true);
- SHA_Reset();
- SHA_Start(&handle, type);
- status = SHA_Update(&handle, inbuff, len);
- npcm_sha_check(status);
- status = SHA_Finish(&handle, hashdigest);
- npcm_sha_check(status);
- SHA_Power(false);
+static struct hash_info npcm_hash_tbl[] = {
+ { .type = type_sha1, .block_sz = 64, .digest_len = 160, .length_bytes = 8 },
+ { .type = type_sha256, .block_sz = 64, .digest_len = 256, .length_bytes = 8 },
+ { .type = type_sha384, .block_sz = 128, .digest_len = 384, .length_bytes = 16 },
+ { .type = type_sha512, .block_sz = 128, .digest_len = 512, .length_bytes = 16 },
+};
- return 0;
-}
+static struct npcm_sha_priv *sha_priv;
-/*
- * Computes hash value of input pbuf using h/w acceleration
- *
- * @param in_addr A pointer to the input buffer
- * @param bufleni Byte length of input buffer
- * @param out_addr A pointer to the output buffer. When complete
- * 32 bytes are copied to pout[0]...pout[31]. Thus, a user
- * should allocate at least 32 bytes at pOut in advance.
- * @param chunk_size chunk size for sha256
- */
-void hw_sha256(const uchar *in_addr, uint buflen, uchar *out_addr, uint chunk_size)
+static int npcm_sha_init(u8 type)
{
- puts("\nhw_sha256 using BMC HW accelerator\t");
- npcm_sha_calc(npcm_sha_type_sha2, (u8 *)in_addr, buflen, (u8 *)out_addr);
-}
+ struct message_block *block = &sha_priv->block;
-/*
- * Computes hash value of input pbuf using h/w acceleration
- *
- * @param in_addr A pointer to the input buffer
- * @param bufleni Byte length of input buffer
- * @param out_addr A pointer to the output buffer. When complete
- * 32 bytes are copied to pout[0]...pout[31]. Thus, a user
- * should allocate at least 32 bytes at pOut in advance.
- * @param chunk_size chunk_size for sha1
- */
-void hw_sha1(const uchar *in_addr, uint buflen, uchar *out_addr, uint chunk_size)
-{
- puts("\nhw_sha1 using BMC HW accelerator\t");
- npcm_sha_calc(npcm_sha_type_sha1, (u8 *)in_addr, buflen, (u8 *)out_addr);
-}
+ if (type > type_sha512 ||
+ (!sha_priv->support_sha512 &&
+ (type == type_sha384 || type == type_sha512)))
+ return -ENOTSUPP;
-/*
- * Create the context for sha progressive hashing using h/w acceleration
- *
- * @algo: Pointer to the hash_algo struct
- * @ctxp: Pointer to the pointer of the context for hashing
- * @return 0 if ok, -ve on error
- */
-int hw_sha_init(struct hash_algo *algo, void **ctxp)
-{
- const char *algo_name1 = "sha1";
- const char *algo_name2 = "sha256";
-
- SHA_Init(&sha_handle);
- SHA_Power(true);
- SHA_Reset();
- if (!strcmp(algo_name1, algo->name))
- return SHA_Start(&sha_handle, npcm_sha_type_sha1);
- else if (!strcmp(algo_name2, algo->name))
- return SHA_Start(&sha_handle, npcm_sha_type_sha2);
- else
- return -EPROTO;
-}
+ sha_priv->regs = &npcm_sha_reg_tbl[type / 2];
+ sha_priv->hash = &npcm_hash_tbl[type];
+ block->length[0] = 0;
+ block->length[1] = 0;
+ block->nonhash_sz = 0;
+ sha_priv->internal_round = false;
-/*
- * Update buffer for sha progressive hashing using h/w acceleration
- *
- * The context is freed by this function if an error occurs.
- *
- * @algo: Pointer to the hash_algo struct
- * @ctx: Pointer to the context for hashing
- * @buf: Pointer to the buffer being hashed
- * @size: Size of the buffer being hashed
- * @is_last: 1 if this is the last update; 0 otherwise
- * @return 0 if ok, -ve on error
- */
-int hw_sha_update(struct hash_algo *algo, void *ctx, const void *buf,
- unsigned int size, int is_last)
-{
- return SHA_Update(&sha_handle, buf, size);
+ return 0;
}
-/*
- * Copy sha hash result at destination location
- *
- * The context is freed after completion of hash operation or after an error.
- *
- * @algo: Pointer to the hash_algo struct
- * @ctx: Pointer to the context for hashing
- * @dest_buf: Pointer to the destination buffer where hash is to be copied
- * @size: Size of the buffer being hashed
- * @return 0 if ok, -ve on error
- */
-int hw_sha_finish(struct hash_algo *algo, void *ctx, void *dest_buf, int size)
+static void npcm_sha_reset(void)
{
- int status;
-
- status = SHA_Finish(&sha_handle, dest_buf);
- npcm_sha_check(status);
- return SHA_Power(false);
+ struct npcm_sha_regs *regs = sha_priv->regs;
+ struct hash_info *hash = sha_priv->hash;
+ u8 val;
+
+ if (hash->type == type_sha1)
+ writeb(HASH_CFG_SHA1_SHA2, sha_priv->base + regs->hash_cfg);
+ else if (hash->type == type_sha256)
+ writeb(0, sha_priv->base + regs->hash_cfg);
+ else if (hash->type == type_sha384)
+ writeb(0, sha_priv->base + regs->sha512_cmd);
+ else if (hash->type == type_sha512)
+ writeb(SHA512_CMD_SHA_512, sha_priv->base + regs->sha512_cmd);
+
+ val = readb(sha_priv->base + regs->ctr_sts) & ~HASH_CTR_STS_SHA_EN;
+ writeb(val | HASH_CTR_STS_SHA_RST, sha_priv->base + regs->ctr_sts);
}
-/*----------------------------------------------------------------------------*/
-/* Function: SHA_Init */
-/* */
-/* Parameters: handlePtr - SHA processing handle pointer */
-/* Returns: 0 on success or other int error code on error. */
-/* Side effects: */
-/* Description: */
-/* This routine initialize the SHA module */
-/*----------------------------------------------------------------------------*/
-static int SHA_Init(struct SHA_HANDLE_T *handleptr)
+static void npcm_sha_enable(bool on)
{
- handleptr->active = false;
+ struct npcm_sha_regs *regs = sha_priv->regs;
+ u8 val;
- return 0;
+ val = readb(sha_priv->base + regs->ctr_sts) & ~HASH_CTR_STS_SHA_EN;
+ val |= on;
+ writeb(val | on, sha_priv->base + regs->ctr_sts);
}
-/*----------------------------------------------------------------------------*/
-/* Function: SHA_Start */
-/* */
-/* Parameters: handlePtr - SHA processing handle pointer */
-/* type - SHA module type */
-/* */
-/* Returns: 0 on success or other int error code on error. */
-/* Side effects: */
-/* Description: */
-/* This routine start a single SHA process */
-/*----------------------------------------------------------------------------*/
-static int SHA_Start(struct SHA_HANDLE_T *handleptr, u8 type)
+static int npcm_sha_flush_block(u8 *block)
{
struct npcm_sha_regs *regs = sha_priv->regs;
+ struct hash_info *hash = sha_priv->hash;
+ u32 *blk_dw = (u32 *)block;
+ u8 val;
+ int i;
+
+ if (readb_poll_timeout(sha_priv->base + regs->ctr_sts, val,
+ !(val & HASH_CTR_STS_SHA_BUSY), 100))
+ return -ETIMEDOUT;
+
+ if (hash->type == type_sha384 || hash->type == type_sha512) {
+ val = SHA512_CMD_WRITE;
+ if (hash->type == type_sha512)
+ val |= SHA512_CMD_SHA_512;
+ if (sha_priv->internal_round)
+ val |= SHA512_CMD_INTERNAL_ROUND;
+ writeb(val, sha_priv->base + regs->sha512_cmd);
+ }
+ for (i = 0; i < (hash->block_sz / sizeof(u32)); i++)
+ writel(blk_dw[i], sha_priv->base + regs->data_in);
- // Initialize handle
- handleptr->length0 = 0;
- handleptr->length1 = 0;
- handleptr->type = type;
- handleptr->active = true;
-
- // Set SHA type
- writeb(handleptr->type & HASH_CFG_SHA1_SHA2, ®s->hash_cfg);
-
- // Reset SHA hardware
- SHA_Reset();
-
- /* The handlePtr->hv is initialized with the correct IV as the SHA engine
- * automatically fill the HASH_DIG_Hn registers according to SHA spec
- * (following SHA_RST assertion)
- */
- SHA_GetShaDigest_l((u8 *)handleptr->hv, type);
-
- // Init block with zeros
- memset(handleptr->block, 0, sizeof(handleptr->block));
+ sha_priv->internal_round = true;
return 0;
}
-/*----------------------------------------------------------------------------*/
-/* Function: SHA_Update */
-/* */
-/* Parameters: handlePtr - SHA processing handle pointer */
-/* buffer - Pointer to the data that will be added to */
-/* the hash calculation */
-/* len - Length of data to add to SHA calculation */
-/* */
-/* */
-/* Returns: 0 on success or other int error code on error */
-/* Side effects: */
-/* Description: */
-/* This routine adds data to previously started SHA */
-/* calculation */
-/*----------------------------------------------------------------------------*/
-static int SHA_Update(struct SHA_HANDLE_T *handleptr, const u8 *buffer, u32 len)
+static int npcm_sha_update_block(const u8 *in, u32 len)
{
- struct npcm_sha_regs *regs = sha_priv->regs;
- u32 localbuffer[SHA_SECRUN_BUFF_SIZE / sizeof(u32)];
- u32 bufferlen = len;
- u16 pos = 0;
- u8 *blockptr;
- int status;
-
- // Error check
- if (!handleptr->active)
- return -EPROTO;
-
- // Wait till SHA is not busy
- status = SHA_BusyWait_l();
- npcm_sha_check(status);
-
- // Set SHA type
- writeb(handleptr->type & HASH_CFG_SHA1_SHA2, ®s->hash_cfg);
-
- // Write SHA latest digest into SHA module
- SHA_SetShaDigest_l(handleptr->hv, handleptr->type);
-
- // Set number of unhashed bytes which remained from last update
- pos = SHA_BUFF_POS(handleptr->length0);
-
- // Copy unhashed bytes which remained from last update to secrun buffer
- SHA_SetBlock_l((u8 *)handleptr->block, pos, 0, localbuffer);
-
- while (len) {
- // Wait for the hardware to be available (in case we are hashing)
- status = SHA_BusyWait_l();
- npcm_sha_check(status);
-
- // Move as much bytes as we can into the secrun buffer
- bufferlen = min(len, SHA_BUFF_FREE(handleptr->length0));
-
- // Copy current given buffer to the secrun buffer
- SHA_SetBlock_l((u8 *)buffer, bufferlen, pos, localbuffer);
-
- // Update size of hashed bytes
- handleptr->length0 += bufferlen;
-
- if (handleptr->length0 < bufferlen)
- handleptr->length1++;
-
- // Update length of data left to digest
- len -= bufferlen;
-
- // Update given buffer pointer
- buffer += bufferlen;
-
- // If secrun buffer is full
- if (SHA_BUFF_POS(handleptr->length0) == 0) {
- /* We just filled up the buffer perfectly, so let it hash (we'll
- * unload the hash only when we are done with all hashing)
- */
- SHA_FlushLocalBuffer_l(localbuffer);
-
- pos = 0;
- bufferlen = 0;
- }
+ struct message_block *block = &sha_priv->block;
+ struct hash_info *hash = sha_priv->hash;
+ u8 *buffer = &block->buffer[0];
+ u32 block_sz = hash->block_sz;
+ u32 hash_sz;
+
+ hash_sz = (block->nonhash_sz + len) > block_sz ?
+ (block_sz - block->nonhash_sz) : len;
+ memcpy(buffer + block->nonhash_sz, in, hash_sz);
+ block->nonhash_sz += hash_sz;
+ block->length[0] += hash_sz;
+ if (block->length[0] < hash_sz)
+ block->length[1]++;
+
+ if (block->nonhash_sz == block_sz) {
+ block->nonhash_sz = 0;
+ if (npcm_sha_flush_block(buffer))
+ return -EBUSY;
}
- // Wait till SHA is not busy
- status = SHA_BusyWait_l();
- npcm_sha_check(status);
-
- /* Copy unhashed bytes from given buffer to handle block for next update/finish */
- blockptr = (u8 *)handleptr->block;
- while (bufferlen)
- blockptr[--bufferlen + pos] = *(--buffer);
-
- // Save SHA current digest
- SHA_GetShaDigest_l((u8 *)handleptr->hv, handleptr->type);
-
- return 0;
+ return hash_sz;
}
-/*----------------------------------------------------------------------------*/
-/* Function: SHA_Finish */
-/* */
-/* Parameters: handlePtr - SHA processing handle pointer */
-/* hashDigest - Pointer to a buffer where the final digest */
-/* will be copied to */
-/* */
-/* Returns: 0 on success or other int error code on error */
-/* Side effects: */
-/* Description: */
-/* This routine finish SHA calculation and get */
-/* the resulting SHA digest */
-/*----------------------------------------------------------------------------*/
-static int SHA_Finish(struct SHA_HANDLE_T *handleptr, u8 *hashdigest)
+static int npcm_sha_update(const u8 *input, u32 len)
{
- struct npcm_sha_regs *regs = sha_priv->regs;
- u32 localbuffer[SHA_SECRUN_BUFF_SIZE / sizeof(u32)];
- const u8 lastbyte = SHA_DATA_LAST_BYTE;
- u16 pos;
- int status;
-
- // Error check
- if (!handleptr->active)
- return -EPROTO;
-
- // Set SHA type
- writeb(handleptr->type & HASH_CFG_SHA1_SHA2, ®s->hash_cfg);
-
- // Wait till SHA is not busy
- status = SHA_BusyWait_l();
- npcm_sha_check(status);
-
- // Finish off the current buffer with the SHA spec'ed padding
- pos = SHA_BUFF_POS(handleptr->length0);
-
- // Init SHA digest
- SHA_SetShaDigest_l(handleptr->hv, handleptr->type);
-
- // Load data into secrun buffer
- SHA_SetBlock_l((u8 *)handleptr->block, pos, 0, localbuffer);
-
- // Set data last byte as in SHA algorithm spec
- SHA_SetBlock_l(&lastbyte, 1, pos++, localbuffer);
+ int hash_sz;
- // If the remainder of data is longer then one block
- if (pos > (SHA_BLOCK_LENGTH - 8)) {
- /* The length will be in the next block Pad the rest of the last block with 0's */
- SHA_ClearBlock_l((SHA_BLOCK_LENGTH - pos), pos, localbuffer);
-
- // Hash the current block
- SHA_FlushLocalBuffer_l(localbuffer);
-
- pos = 0;
-
- // Wait till SHA is not busy
- status = SHA_BusyWait_l();
- npcm_sha_check(status);
+ while (len) {
+ hash_sz = npcm_sha_update_block(input, len);
+ if (hash_sz < 0) {
+ printf("SHA512 module busy\n");
+ return -EBUSY;
+ }
+ len -= hash_sz;
+ input += hash_sz;
}
- // Pad the rest of the last block with 0's except for the last 8-3 bytes
- SHA_ClearBlock_l((SHA_BLOCK_LENGTH - (8 - 3)) - pos, pos, localbuffer);
-
- /* The last 8-3 bytes are set to the bit-length of the message in big-endian form */
- SHA_SetLength32_l(handleptr, localbuffer);
-
- // Hash all that, and save the hash for the caller
- SHA_FlushLocalBuffer_l(localbuffer);
-
- // Wait till SHA is not busy
- status = SHA_BusyWait_l();
- npcm_sha_check(status);
-
- // Save SHA final digest into given buffer
- SHA_GetShaDigest_l(hashdigest, handleptr->type);
-
- // Free handle
- handleptr->active = false;
-
return 0;
}
-/*----------------------------------------------------------------------------*/
-/* Function: SHA_Reset */
-/* */
-/* Parameters: none */
-/* Returns: none */
-/* Side effects: */
-/* Description: */
-/* This routine reset SHA module */
-/*----------------------------------------------------------------------------*/
-static int SHA_Reset(void)
+static int npcm_sha_finish(u8 *out)
{
struct npcm_sha_regs *regs = sha_priv->regs;
-
- writel(readl(®s->hash_ctr_sts) | HASH_CTR_STS_SHA_RST, ®s->hash_ctr_sts);
+ struct message_block *block = &sha_priv->block;
+ struct hash_info *hash = sha_priv->hash;
+ u8 *buffer = &block->buffer[0];
+ u32 block_sz = hash->block_sz;
+ u32 *out32 = (u32 *)out;
+ u32 zero_len, val;
+ u64 *length;
+ u8 reg_data_out;
+ int i;
+
+ /* Padding, minimal padding size is last_byte+length_bytes */
+ if ((block_sz - block->nonhash_sz) >= (hash->length_bytes + 1))
+ zero_len = block_sz - block->nonhash_sz - (hash->length_bytes + 1);
+ else
+ zero_len = block_sz * 2 - block->nonhash_sz - (hash->length_bytes + 1);
+ /* Last byte */
+ buffer[block->nonhash_sz++] = 0x80;
+ /* Zero bits padding */
+ memset(&buffer[block->nonhash_sz], 0, zero_len);
+ block->nonhash_sz += zero_len;
+ /* Message length */
+ length = (u64 *)&buffer[block->nonhash_sz];
+ if (hash->length_bytes == 16) {
+ *length++ = cpu_to_be64(block->length[1] << 3 | block->length[0] >> 61);
+ block->nonhash_sz += 8;
+ }
+ *length = cpu_to_be64(block->length[0] << 3);
+ block->nonhash_sz += 8;
+ if (npcm_sha_flush_block(&block->buffer[0]))
+ return -ETIMEDOUT;
+
+ /* After padding, the last message may produce 2 blocks */
+ if (block->nonhash_sz > block_sz) {
+ if (npcm_sha_flush_block(&block->buffer[block_sz]))
+ return -ETIMEDOUT;
+ }
+ /* Read digest */
+ if (readb_poll_timeout(sha_priv->base + regs->ctr_sts, val,
+ !(val & HASH_CTR_STS_SHA_BUSY), 100))
+ return -ETIMEDOUT;
+ if (hash->type == type_sha384)
+ writeb(SHA512_CMD_READ, sha_priv->base + regs->sha512_cmd);
+ else if (hash->type == type_sha512)
+ writeb(SHA512_CMD_SHA_512 | SHA512_CMD_READ,
+ sha_priv->base + regs->sha512_cmd);
+
+ reg_data_out = regs->data_out;
+ for (i = 0; i < (hash->digest_len / 32); i++) {
+ *out32 = readl(sha_priv->base + reg_data_out);
+ out32++;
+ if (hash->type == type_sha1 || hash->type == type_sha256)
+ reg_data_out += 4;
+ }
return 0;
}
-/*----------------------------------------------------------------------------*/
-/* Function: SHA_Power */
-/* */
-/* Parameters: on - true enable the module, false disable the module */
-/* Returns: none */
-/* Side effects: */
-/* Description: */
-/* This routine set SHA module power on/off */
-/*----------------------------------------------------------------------------*/
-static int SHA_Power(bool on)
+int npcm_sha_calc(const u8 *input, u32 len, u8 *output, u8 type)
{
- struct npcm_sha_regs *regs = sha_priv->regs;
- u8 hash_sts;
-
- hash_sts = readb(®s->hash_ctr_sts) & ~HASH_CTR_STS_SHA_EN;
- writeb(hash_sts | (on & HASH_CTR_STS_SHA_EN), ®s->hash_ctr_sts);
+ if (npcm_sha_init(type))
+ return -ENOTSUPP;
+ npcm_sha_reset();
+ npcm_sha_enable(true);
+ npcm_sha_update(input, len);
+ npcm_sha_finish(output);
+ npcm_sha_enable(false);
return 0;
}
-#ifdef SHA_PRINT
-/*----------------------------------------------------------------------------*/
-/* Function: SHA_PrintRegs */
-/* */
-/* Parameters: none */
-/* Returns: none */
-/* Side effects: */
-/* Description: */
-/* This routine prints the module registers */
-/*----------------------------------------------------------------------------*/
-static void SHA_PrintRegs(void)
+void hw_sha512(const unsigned char *input, unsigned int len,
+ unsigned char *output, unsigned int chunk_sz)
{
-#ifdef SHA_DEBUG_MODULE
- struct npcm_sha_regs *regs = sha_priv->regs;
-#endif
- unsigned int i;
-
- sha_print("/*--------------*/\n");
- sha_print("/* SHA */\n");
- sha_print("/*--------------*/\n\n");
-
- sha_print("HASH_CTR_STS = 0x%02X\n", readb(®s->hash_ctr_sts));
- sha_print("HASH_CFG = 0x%02X\n", readb(®s->hash_cfg));
-
- for (i = 0; i < HASH_DIG_H_NUM; i++)
- sha_print("HASH_DIG_H%d = 0x%08X\n", i, readl(®s->hash_dig[i]));
-
- sha_print("HASH_VER = 0x%08X\n", readb(®s->hash_ver));
-
- sha_print("\n");
+ if (!sha_priv->support_sha512) {
+ puts(" HW accelerator not support\n");
+ return;
+ }
+ puts(" using BMC HW accelerator\n");
+ npcm_sha_calc(input, len, output, type_sha512);
}
-/*----------------------------------------------------------------------------*/
-/* Function: SHA_PrintVersion */
-/* */
-/* Parameters: none */
-/* Returns: none */
-/* Side effects: */
-/* Description: */
-/* This routine prints the module version */
-/*----------------------------------------------------------------------------*/
-static void SHA_PrintVersion(void)
-{
- struct npcm_sha_regs *regs = sha_priv->regs;
-
- printf("SHA MODULE VER = %d\n", readb(®s->hash_ver));
-}
-#endif
-
-/*----------------------------------------------------------------------------*/
-/* Function: npcm_sha_selftest */
-/* */
-/* Parameters: type - SHA module type */
-/* Returns: 0 on success or other int error code on error */
-/* Side effects: */
-/* Description: */
-/* This routine performs various tests on the SHA HW and SW */
-/*----------------------------------------------------------------------------*/
-int npcm_sha_selftest(u8 type)
+void hw_sha384(const unsigned char *input, unsigned int len,
+ unsigned char *output, unsigned int chunk_sz)
{
- int status;
- struct SHA_HANDLE_T handle;
- u8 hashdigest[max(SHA_1_HASH_LENGTH, SHA_2_HASH_LENGTH)];
- u16 i, j;
-
- /*------------------------------------------------------------------------*/
- /* SHA1 tests info */
- /*------------------------------------------------------------------------*/
-
- static const u8 sha1selftestbuff[SHA1_NUM_OF_SELF_TESTS][94] = {
- {"abc"},
- {"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"},
- {"0123456789012345678901234567890123456789012345678901234567890123"},
- {0x30, 0x5c, 0x30, 0x2c, 0x02, 0x01, 0x00, 0x30, 0x09, 0x06, 0x05, 0x2b,
- 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x30, 0x06, 0x06, 0x04, 0x67, 0x2a,
- 0x01, 0x0c, 0x04, 0x14, 0xe1, 0xb6, 0x93, 0xfe, 0x33, 0x43, 0xc1, 0x20,
- 0x5d, 0x4b, 0xaa, 0xb8, 0x63, 0xfb, 0xcf, 0x6c, 0x46, 0x1e, 0x88, 0x04,
- 0x30, 0x2c, 0x02, 0x01, 0x00, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
- 0x02, 0x1a, 0x05, 0x00, 0x30, 0x06, 0x06, 0x04, 0x67, 0x2a, 0x01, 0x0c,
- 0x04, 0x14, 0x13, 0xc1, 0x0c, 0xfc, 0xc8, 0x92, 0xd7, 0xde, 0x07, 0x1c,
- 0x40, 0xde, 0x4f, 0xcd, 0x07, 0x5b, 0x68, 0x20, 0x5a, 0x6c}
- };
-
- static const u8 sha1selftestbufflen[SHA1_NUM_OF_SELF_TESTS] = {
- 3, 56, 64, 94
- };
-
- static const u8 sha1selftestexpres[SHA1_NUM_OF_SELF_TESTS][SHA_1_HASH_LENGTH] = {
- {0xA9, 0x99, 0x3E, 0x36,
- 0x47, 0x06, 0x81, 0x6A,
- 0xBA, 0x3E, 0x25, 0x71,
- 0x78, 0x50, 0xC2, 0x6C,
- 0x9C, 0xD0, 0xD8, 0x9D},
- {0x84, 0x98, 0x3E, 0x44,
- 0x1C, 0x3B, 0xD2, 0x6E,
- 0xBA, 0xAE, 0x4A, 0xA1,
- 0xF9, 0x51, 0x29, 0xE5,
- 0xE5, 0x46, 0x70, 0xF1},
- {0xCF, 0x08, 0x00, 0xF7,
- 0x64, 0x4A, 0xCE, 0x3C,
- 0xB4, 0xC3, 0xFA, 0x33,
- 0x38, 0x8D, 0x3B, 0xA0,
- 0xEA, 0x3C, 0x8B, 0x6E},
- {0xc9, 0x84, 0x45, 0xc8,
- 0x64, 0x04, 0xb1, 0xe3,
- 0x3c, 0x6b, 0x0a, 0x8c,
- 0x8b, 0x80, 0x94, 0xfc,
- 0xf3, 0xc9, 0x98, 0xab}
- };
-
- /*------------------------------------------------------------------------*/
- /* SHA2 tests info */
- /*------------------------------------------------------------------------*/
-
- static const u8 sha2selftestbuff[SHA2_NUM_OF_SELF_TESTS][100] = {
- { "abc" },
- { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
- {'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
- 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
- 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
- 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
- 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
- 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
- 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
- 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
- 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
- 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a'}
- };
-
- static const u8 sha2selftestbufflen[SHA2_NUM_OF_SELF_TESTS] = {
- 3, 56, 100
- };
-
- static const u8 sha2selftestexpres[SHA2_NUM_OF_SELF_TESTS][SHA_2_HASH_LENGTH] = {
- /*
- * SHA-256 test vectors
- */
- { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
- 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
- 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
- 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
- { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
- 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
- 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
- 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
- { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
- 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
- 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
- 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 },
- };
-
- if (type == npcm_sha_type_sha1) {
- /*--------------------------------------------------------------------*/
- /* SHA 1 TESTS */
- /*--------------------------------------------------------------------*/
- for (i = 0; i < SHA1_NUM_OF_SELF_TESTS; i++) {
- if (i != 3) {
- status = npcm_sha_calc(npcm_sha_type_sha1, sha1selftestbuff[i], sha1selftestbufflen[i], hashdigest);
- npcm_sha_check(status);
- } else {
- SHA_Power(true);
- SHA_Reset();
- status = SHA_Start(&handle, npcm_sha_type_sha1);
- npcm_sha_check(status);
- status = SHA_Update(&handle, sha1selftestbuff[i], 73);
- npcm_sha_check(status);
- status = SHA_Update(&handle, &sha1selftestbuff[i][73], sha1selftestbufflen[i] - 73);
- npcm_sha_check(status);
- status = SHA_Finish(&handle, hashdigest);
- npcm_sha_check(status);
- SHA_Power(false);
- }
-
- if (memcmp(hashdigest, sha1selftestexpres[i], SHA_1_HASH_LENGTH))
- return -1;
- }
-
- } else {
- /*--------------------------------------------------------------------*/
- /* SHA 2 TESTS */
- /*--------------------------------------------------------------------*/
- for (i = 0; i < SHA2_NUM_OF_SELF_TESTS; i++) {
- SHA_Power(true);
- SHA_Reset();
- status = SHA_Start(&handle, npcm_sha_type_sha2);
- npcm_sha_check(status);
- if (i == 2) {
- for (j = 0; j < 10000; j++) { //not working
- status = SHA_Update(&handle, sha2selftestbuff[i], sha2selftestbufflen[i]);
- npcm_sha_check(status);
- }
- } else {
- status = SHA_Update(&handle, sha2selftestbuff[i], sha2selftestbufflen[i]);
- npcm_sha_check(status);
- }
-
- status = SHA_Finish(&handle, hashdigest);
- npcm_sha_check(status);
- SHA_Power(false);
- if (memcmp(hashdigest, sha2selftestexpres[i], SHA_2_HASH_LENGTH))
- return -1;
-
- npcm_sha_calc(npcm_sha_type_sha2, sha2selftestbuff[i], sha2selftestbufflen[i], hashdigest);
- if (memcmp(hashdigest, sha2selftestexpres[i], SHA_2_HASH_LENGTH))
- return -1;
- }
+ if (!sha_priv->support_sha512) {
+ puts(" HW accelerator not support\n");
+ return;
}
-
- return 0;
+ puts(" using BMC HW accelerator\n");
+ npcm_sha_calc(input, len, output, type_sha384);
}
-/*----------------------------------------------------------------------------*/
-/* Function: SHA_FlushLocalBuffer_l */
-/* */
-/* Parameters: */
-/* Returns: none */
-/* Side effects: */
-/* Description: This routine flush secrun buffer to SHA module */
-/*----------------------------------------------------------------------------*/
-static void SHA_FlushLocalBuffer_l(const u32 *buff)
+void hw_sha256(const unsigned char *input, unsigned int len,
+ unsigned char *output, unsigned int chunk_sz)
{
- struct npcm_sha_regs *regs = sha_priv->regs;
- u32 i;
-
- for (i = 0; i < (SHA_BLOCK_LENGTH / sizeof(u32)); i++)
- writel(buff[i], ®s->hash_data_in);
+ puts(" using BMC HW accelerator\n");
+ npcm_sha_calc(input, len, output, type_sha256);
}
-/*----------------------------------------------------------------------------*/
-/* Function: SHA_BusyWait_l */
-/* */
-/* Parameters: */
-/* Returns: 0 if no error was found or DEFS_STATUS_ERROR otherwise */
-/* Side effects: */
-/* Description: This routine wait for SHA unit to no longer be busy */
-/*----------------------------------------------------------------------------*/
-static int SHA_BusyWait_l(void)
+void hw_sha1(const unsigned char *input, unsigned int len,
+ unsigned char *output, unsigned int chunk_sz)
{
- struct npcm_sha_regs *regs = sha_priv->regs;
- u32 timeout = SHA_TIMEOUT;
-
- do {
- if (timeout-- == 0)
- return -ETIMEDOUT;
- } while ((readb(®s->hash_ctr_sts) & HASH_CTR_STS_SHA_BUSY)
- == HASH_CTR_STS_SHA_BUSY);
-
- return 0;
+ puts(" using BMC HW accelerator\n");
+ npcm_sha_calc(input, len, output, type_sha1);
}
-/*----------------------------------------------------------------------------*/
-/* Function: SHA_GetShaDigest_l */
-/* */
-/* Parameters: hashDigest - buffer for the hash output. */
-/* type - SHA module type */
-/* Returns: none */
-/* Side effects: */
-/* Description: This routine copy the hash digest from the hardware */
-/* and into given buffer (in ram) */
-/*----------------------------------------------------------------------------*/
-static void SHA_GetShaDigest_l(u8 *hashdigest, u8 type)
+int hw_sha_init(struct hash_algo *algo, void **ctxp)
{
- struct npcm_sha_regs *regs = sha_priv->regs;
- u16 j;
- u8 len = SHA_HASH_LENGTH(type) / sizeof(u32);
-
- // Copy Bytes from SHA module to given buffer
- for (j = 0; j < len; j++)
- ((u32 *)hashdigest)[j] = readl(®s->hash_dig[j]);
-}
+ if (!strcmp("sha1", algo->name)) {
+ npcm_sha_init(type_sha1);
+ } else if (!strcmp("sha256", algo->name)) {
+ npcm_sha_init(type_sha256);
+ } else if (!strcmp("sha384", algo->name)) {
+ if (!sha_priv->support_sha512)
+ return -ENOTSUPP;
+ npcm_sha_init(type_sha384);
+ } else if (!strcmp("sha512", algo->name)) {
+ if (!sha_priv->support_sha512)
+ return -ENOTSUPP;
+ npcm_sha_init(type_sha512);
+ } else {
+ return -ENOTSUPP;
+ }
-/*----------------------------------------------------------------------------*/
-/* Function: SHA_SetShaDigest_l */
-/* */
-/* Parameters: hashDigest - input buffer to set as hash digest */
-/* type - SHA module type */
-/* Returns: none */
-/* Side effects: */
-/* Description: This routine set the hash digest in the hardware from */
-/* a given buffer (in ram) */
-/*----------------------------------------------------------------------------*/
-static void SHA_SetShaDigest_l(const u32 *hashdigest, u8 type)
-{
- struct npcm_sha_regs *regs = sha_priv->regs;
- u16 j;
- u8 len = SHA_HASH_LENGTH(type) / sizeof(u32);
+ printf("Using npcm SHA engine\n");
+ npcm_sha_reset();
+ npcm_sha_enable(true);
- // Copy Bytes from given buffer to SHA module
- for (j = 0; j < len; j++)
- writel(hashdigest[j], ®s->hash_dig[j]);
+ return 0;
}
-/*----------------------------------------------------------------------------*/
-/* Function: SHA_SetBlock_l */
-/* */
-/* Parameters: data - data to copy */
-/* len - size of data */
-/* position - byte offset into the block at which data */
-/* should be placed */
-/* block - block buffer */
-/* Returns: none */
-/* Side effects: */
-/* Description: This routine load bytes into block buffer */
-/*----------------------------------------------------------------------------*/
-static void SHA_SetBlock_l(const u8 *data, u32 len, u16 position, u32 *block)
+int hw_sha_update(struct hash_algo *algo, void *ctx, const void *buf,
+ unsigned int size, int is_last)
{
- u8 *dest = (u8 *)block;
-
- memcpy(dest + position, data, len);
+ return npcm_sha_update(buf, size);
}
-/*----------------------------------------------------------------------------*/
-/* Function: SHA_SetBlock_l */
-/* */
-/* Parameters: */
-/* len - size of data */
-/* position - byte offset into the block at which data */
-/* should be placed */
-/* block - block buffer */
-/* Returns: none */
-/* Side effects: */
-/* Description: This routine load zero's into the block buffer */
-/*----------------------------------------------------------------------------*/
-static void SHA_ClearBlock_l(u16 len, u16 position, u32 *block)
+int hw_sha_finish(struct hash_algo *algo, void *ctx, void *dest_buf,
+ int size)
{
- u8 *dest = (u8 *)block;
+ int ret;
- memset(dest + position, 0, len);
-}
+ ret = npcm_sha_finish(dest_buf);
+ npcm_sha_enable(false);
-/*----------------------------------------------------------------------------*/
-/* Function: SHA_SetLength32_l */
-/* */
-/* Parameters: */
-/* handlePtr - SHA processing handle pointer */
-/* block - block buffer */
-/* Returns: none */
-/* Side effects: */
-/* Description: This routine set the length of the hash's data */
-/* len is the 32-bit byte length of the message */
-/*lint -efunc(734,SHA_SetLength32_l) Supperess loss of percision lint warning */
-/*----------------------------------------------------------------------------*/
-static void SHA_SetLength32_l(struct SHA_HANDLE_T *handleptr, u32 *block)
-{
- u16 *secrunbufferswappedptr = (u16 *)(void *)(block);
-
- secrunbufferswappedptr[(SHA_BLOCK_LENGTH / sizeof(u16)) - 1] = (u16)
- ((handleptr->length0 << 3) << 8) | ((u16)(handleptr->length0 << 3) >> 8);
- secrunbufferswappedptr[(SHA_BLOCK_LENGTH / sizeof(u16)) - 2] = (u16)
- ((handleptr->length0 >> (16 - 3)) >> 8) | ((u16)(handleptr->length0 >> (16 - 3)) << 8);
- secrunbufferswappedptr[(SHA_BLOCK_LENGTH / sizeof(u16)) - 3] = (u16)
- ((handleptr->length1 << 3) << 8) | ((u16)(handleptr->length1 << 3) >> 8);
- secrunbufferswappedptr[(SHA_BLOCK_LENGTH / sizeof(u16)) - 4] = (u16)
- ((handleptr->length1 >> (16 - 3)) >> 8) | ((u16)(handleptr->length1 >> (16 - 3)) << 8);
+ return ret;
}
static int npcm_sha_bind(struct udevice *dev)
@@ -871,12 +348,15 @@ static int npcm_sha_bind(struct udevice *dev)
if (!sha_priv)
return -ENOMEM;
- sha_priv->regs = dev_remap_addr_index(dev, 0);
- if (!sha_priv->regs) {
+ sha_priv->base = dev_read_addr_ptr(dev);
+ if (!sha_priv->base) {
printf("Cannot find sha reg address, binding failed\n");
return -EINVAL;
}
+ if (IS_ENABLED(CONFIG_ARCH_NPCM8XX))
+ sha_priv->support_sha512 = true;
+
printf("SHA: NPCM SHA module bind OK\n");
return 0;
--
2.25.1
2
1