summaryrefslogtreecommitdiff
path: root/board
diff options
context:
space:
mode:
Diffstat (limited to 'board')
-rw-r--r--board/samsung/e850-96/Makefile4
-rw-r--r--board/samsung/e850-96/e850-96.c6
-rw-r--r--board/samsung/e850-96/e850-96.env26
-rw-r--r--board/samsung/e850-96/fw.c131
-rw-r--r--board/samsung/e850-96/fw.h12
-rw-r--r--board/samsung/odroid/Makefile2
-rw-r--r--board/samsung/smdk5420/Kconfig2
7 files changed, 177 insertions, 6 deletions
diff --git a/board/samsung/e850-96/Makefile b/board/samsung/e850-96/Makefile
index 301c223371..71d46ea3d2 100644
--- a/board/samsung/e850-96/Makefile
+++ b/board/samsung/e850-96/Makefile
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0+
#
-# Copyright (C) 2020, Linaro Limited
+# Copyright (C) 2024, Linaro Limited
# Sam Protsenko <semen.protsenko@linaro.org>
-obj-y := e850-96.o
+obj-y := e850-96.o fw.o
diff --git a/board/samsung/e850-96/e850-96.c b/board/samsung/e850-96/e850-96.c
index a00d81b5d4..c5cef6f19d 100644
--- a/board/samsung/e850-96/e850-96.c
+++ b/board/samsung/e850-96/e850-96.c
@@ -1,10 +1,11 @@
// SPDX-License-Identifier: GPL-2.0+
/*
- * Copyright (C) 2020, Linaro Limited
- * Sam Protsenko <semen.protsenko@linaro.org>
+ * Copyright (c) 2024, Linaro Ltd.
+ * Author: Sam Protsenko <semen.protsenko@linaro.org>
*/
#include <init.h>
+#include "fw.h"
int dram_init(void)
{
@@ -18,5 +19,6 @@ int dram_init_banksize(void)
int board_init(void)
{
+ load_ldfw();
return 0;
}
diff --git a/board/samsung/e850-96/e850-96.env b/board/samsung/e850-96/e850-96.env
new file mode 100644
index 0000000000..f36f90be95
--- /dev/null
+++ b/board/samsung/e850-96/e850-96.env
@@ -0,0 +1,26 @@
+partitions=
+ uuid_disk=${uuid_gpt_disk};
+ name=efs,start=512K,size=20M,uuid=${uuid_gpt_efs};
+ name=env,size=16K,uuid=${uuid_gpt_env};
+ name=kernel,size=30M,uuid=${uuid_gpt_kernel};
+ name=ramdisk,size=26M,uuid=${uuid_gpt_ramdisk};
+ name=dtbo,size=1M,uuid=${uuid_gpt_dtbo};
+ name=ldfw,size=4016K,uuid=${uuid_gpt_ldfw};
+ name=keystorage,size=8K,uuid=${uuid_gpt_keystorage};
+ name=tzsw,size=1M,uuid=${uuid_gpt_tzsw};
+ name=harx,size=2M,uuid=${uuid_gpt_harx};
+ name=harx_rkp,size=2M,uuid=${uuid_gpt_harx_rkp};
+ name=logo,size=40M,uuid=${uuid_gpt_logo};
+ name=super,size=3600M,uuid=${uuid_gpt_super};
+ name=cache,size=300M,uuid=${uuid_gpt_cache};
+ name=modem,size=100M,uuid=${uuid_gpt_modem};
+ name=boot,size=100M,uuid=${uuid_gpt_boot};
+ name=persist,size=30M,uuid=${uuid_gpt_persist};
+ name=recovery,size=40M,uuid=${uuid_gpt_recovery};
+ name=misc,size=40M,uuid=${uuid_gpt_misc};
+ name=mnv,size=20M,uuid=${uuid_gpt_mnv};
+ name=frp,size=512K,uuid=${uuid_gpt_frp};
+ name=vbmeta,size=64K,uuid=${uuid_gpt_vbmeta};
+ name=metadata,size=16M,uuid=${uuid_gpt_metadata};
+ name=dtb,size=1M,uuid=${uuid_gpt_dtb};
+ name=userdata,size=-,uuid=${uuid_gpt_userdata}
diff --git a/board/samsung/e850-96/fw.c b/board/samsung/e850-96/fw.c
new file mode 100644
index 0000000000..82a0b224c6
--- /dev/null
+++ b/board/samsung/e850-96/fw.c
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2024 Linaro Ltd.
+ * Author: Sam Protsenko <semen.protsenko@linaro.org>
+ *
+ * Firmware loading code.
+ */
+
+#include <part.h>
+#include <linux/arm-smccc.h>
+#include "fw.h"
+
+#define EMMC_IFACE "mmc"
+#define EMMC_DEV_NUM 0
+
+/* LDFW constants */
+#define LDFW_PART_NAME "ldfw"
+#define LDFW_NWD_ADDR 0x88000000
+#define LDFW_MAGIC 0x10adab1e
+#define SMC_CMD_LOAD_LDFW -0x500
+#define SDM_HW_RESET_STATUS 0x1230
+#define SDM_SW_RESET_STATUS 0x1231
+#define SB_ERROR_PREFIX 0xfdaa0000
+
+struct ldfw_header {
+ u32 magic;
+ u32 size;
+ u32 init_entry;
+ u32 entry_point;
+ u32 suspend_entry;
+ u32 resume_entry;
+ u32 start_smc_id;
+ u32 version;
+ u32 set_runtime_entry;
+ u32 reserved[3];
+ char fw_name[16];
+};
+
+static int read_fw(const char *part_name, void *buf)
+{
+ struct blk_desc *blk_desc;
+ struct disk_partition part;
+ unsigned long cnt;
+ int part_num;
+
+ blk_desc = blk_get_dev(EMMC_IFACE, EMMC_DEV_NUM);
+ if (!blk_desc) {
+ debug("%s: Can't get eMMC device\n", __func__);
+ return -ENODEV;
+ }
+
+ part_num = part_get_info_by_name(blk_desc, part_name, &part);
+ if (part_num < 0) {
+ debug("%s: Can't get LDWF partition\n", __func__);
+ return -ENOENT;
+ }
+
+ cnt = blk_dread(blk_desc, part.start, part.size, buf);
+ if (cnt != part.size) {
+ debug("%s: Can't read LDFW partition\n", __func__);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int load_ldfw(void)
+{
+ const phys_addr_t addr = (phys_addr_t)LDFW_NWD_ADDR;
+ struct ldfw_header *hdr;
+ struct arm_smccc_res res;
+ void *buf = (void *)addr;
+ u64 size = 0;
+ int err, i;
+
+ /* Load LDFW from the block device partition into RAM buffer */
+ err = read_fw(LDFW_PART_NAME, buf);
+ if (err)
+ return err;
+
+ /* Validate LDFW by magic number in its header */
+ hdr = buf;
+ if (hdr->magic != LDFW_MAGIC) {
+ debug("%s: Wrong LDFW magic; is LDFW flashed?\n", __func__);
+ return -EINVAL;
+ }
+
+ /* Calculate actual total size of all LDFW blobs */
+ for (i = 0; hdr->magic == LDFW_MAGIC; ++i) {
+#ifdef DEBUG
+ char name[17] = { 0 };
+
+ strncpy(name, hdr->fw_name, 16);
+ debug("%s: ldfw #%d: version = 0x%x, name = %s\n", __func__, i,
+ hdr->version, name);
+#endif
+
+ size += (u64)hdr->size;
+ hdr = (struct ldfw_header *)((u64)hdr + (u64)hdr->size);
+ }
+ debug("%s: The whole size of all LDFWs: 0x%llx\n", __func__, size);
+
+ /* Load LDFW firmware to SWD (Secure World) memory via EL3 monitor */
+ arm_smccc_smc(SMC_CMD_LOAD_LDFW, addr, size, 0, 0, 0, 0, 0, &res);
+ err = (int)res.a0;
+ if (err == -1 || err == SDM_HW_RESET_STATUS) {
+ debug("%s: Can't load LDFW in dump_gpr state\n", __func__);
+ return -EIO;
+ } else if (err == SDM_SW_RESET_STATUS) {
+ debug("%s: Can't load LDFW in kernel panic (SW RESET) state\n",
+ __func__);
+ return -EIO;
+ } else if (err < 0 && (err & 0xffff0000) == SB_ERROR_PREFIX) {
+ debug("%s: LDFW signature is corrupted! ret=0x%x\n", __func__,
+ (u32)err);
+ return -EIO;
+ } else if (err == 0) {
+ debug("%s: No LDFW is inited\n", __func__);
+ return -EIO;
+ }
+
+#ifdef DEBUG
+ u32 tried = res.a0 & 0xffff;
+ u32 failed = (res.a0 >> 16) & 0xffff;
+
+ debug("%s: %d/%d LDFWs have been loaded successfully\n", __func__,
+ tried - failed, tried);
+#endif
+
+ return 0;
+}
diff --git a/board/samsung/e850-96/fw.h b/board/samsung/e850-96/fw.h
new file mode 100644
index 0000000000..472664e4ed
--- /dev/null
+++ b/board/samsung/e850-96/fw.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2024 Linaro Ltd.
+ * Sam Protsenko <semen.protsenko@linaro.org>
+ */
+
+#ifndef __E850_96_FW_H
+#define __E850_96_FW_H
+
+int load_ldfw(void);
+
+#endif /* __E850_96_FW_H */
diff --git a/board/samsung/odroid/Makefile b/board/samsung/odroid/Makefile
index 5bf48313de..615c99f501 100644
--- a/board/samsung/odroid/Makefile
+++ b/board/samsung/odroid/Makefile
@@ -3,4 +3,4 @@
# Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
# Przemyslaw Marczak <p.marczak@samsung.com>
-obj-y := odroid.o
+obj-$(CONFIG_TARGET_ODROID) := odroid.o
diff --git a/board/samsung/smdk5420/Kconfig b/board/samsung/smdk5420/Kconfig
index a9d62fffa5..37d6bbbed1 100644
--- a/board/samsung/smdk5420/Kconfig
+++ b/board/samsung/smdk5420/Kconfig
@@ -1,7 +1,7 @@
if TARGET_ODROID_XU3
config SYS_BOARD
- default "smdk5420"
+ default "odroid"
config SYS_VENDOR
default "samsung"