summaryrefslogtreecommitdiff
path: root/board/samsung/e850-96/e850-96.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/samsung/e850-96/e850-96.c')
-rw-r--r--board/samsung/e850-96/e850-96.c97
1 files changed, 87 insertions, 10 deletions
diff --git a/board/samsung/e850-96/e850-96.c b/board/samsung/e850-96/e850-96.c
index a6c264d1248..3df241edde2 100644
--- a/board/samsung/e850-96/e850-96.c
+++ b/board/samsung/e850-96/e850-96.c
@@ -8,13 +8,28 @@
#include <env.h>
#include <init.h>
#include <mapmem.h>
+#include <net.h>
+#include <usb.h>
#include <asm/io.h>
#include "fw.h"
+#include "pmic.h"
/* OTP Controller base address and register offsets */
-#define EXYNOS850_OTP_BASE 0x10000000
-#define OTP_CHIPID0 0x4
-#define OTP_CHIPID1 0x8
+#define EXYNOS850_OTP_BASE 0x10000000
+#define OTP_CHIPID0 0x4
+#define OTP_CHIPID1 0x8
+
+/* ACPM and PMIC definitions */
+#define EXYNOS850_MBOX_APM2AP_BASE 0x11900000
+#define EXYNOS850_APM_SRAM_BASE 0x02039000 /* in iRAM */
+#define EXYNOS850_APM_SHMEM_OFFSET 0x3200
+#define EXYNOS850_IPC_AP_I3C 10
+
+/* LDFW firmware definitions */
+#define LDFW_NWD_ADDR 0x88000000
+#define EMMC_IFNAME "mmc"
+#define EMMC_DEV_NUM 0
+#define EMMC_ESP_PART 1
struct efi_fw_image fw_images[] = {
{
@@ -55,6 +70,13 @@ struct efi_capsule_update_info update_info = {
.images = fw_images,
};
+static struct acpm acpm = {
+ .mbox_base = (void __iomem *)EXYNOS850_MBOX_APM2AP_BASE,
+ .sram_base = (void __iomem *)(EXYNOS850_APM_SRAM_BASE +
+ EXYNOS850_APM_SHMEM_OFFSET),
+ .ipc_ch = EXYNOS850_IPC_AP_I3C,
+};
+
int dram_init(void)
{
return fdtdec_setup_mem_size_base();
@@ -92,19 +114,74 @@ static void setup_serial(void)
env_set("serial#", serial_str);
}
-int board_late_init(void)
+static void setup_ethaddr(void)
+{
+ u64 serial_num;
+ u32 mac_hi, mac_lo;
+ u8 mac_addr[6];
+
+ if (env_get("ethaddr"))
+ return;
+
+ serial_num = get_chip_id();
+ mac_lo = (u32)serial_num; /* OTP_CHIPID0 */
+ mac_hi = (u32)(serial_num >> 32UL); /* OTP_CHIPID1 */
+ mac_addr[0] = (mac_hi >> 8) & 0xff;
+ mac_addr[1] = mac_hi & 0xff;
+ mac_addr[2] = (mac_lo >> 24) & 0xff;
+ mac_addr[3] = (mac_lo >> 16) & 0xff;
+ mac_addr[4] = (mac_lo >> 8) & 0xff;
+ mac_addr[5] = mac_lo & 0xff;
+ mac_addr[0] &= ~0x1; /* make sure it's not a multicast address */
+ if (is_valid_ethaddr(mac_addr))
+ eth_env_set_enetaddr("ethaddr", mac_addr);
+}
+
+/*
+ * Call this in board_late_init() to avoid probing block devices before
+ * efi_init_early().
+ */
+void load_firmware(void)
{
+ const char *ifname;
+ ulong dev, part;
int err;
+ ifname = env_get("bootdev");
+ if (!ifname)
+ ifname = EMMC_IFNAME;
+ dev = env_get_ulong("bootdevnum", 10, EMMC_DEV_NUM);
+ part = env_get_ulong("bootdevpart", 10, EMMC_ESP_PART);
+
+ if (!strcmp(ifname, "usb")) {
+ printf("Starting USB (bootdev=usb)...\n");
+ err = usb_init();
+ if (err)
+ return;
+ }
+
+ printf("Loading LDFW firmware (from %s %ld)...\n", ifname, dev);
+ err = load_ldfw(ifname, dev, part, LDFW_NWD_ADDR);
+ if (err)
+ printf("ERROR: LDFW loading failed (%d)\n", err);
+}
+
+int board_late_init(void)
+{
setup_serial();
+ setup_ethaddr();
+ load_firmware();
- /*
- * Do this in board_late_init() to make sure MMC is not probed before
- * efi_init_early().
- */
- err = load_ldfw();
+ return 0;
+}
+
+int power_init_board(void)
+{
+ int err;
+
+ err = pmic_init(&acpm);
if (err)
- printf("ERROR: LDFW loading failed (%d)\n", err);
+ printf("ERROR: Failed to configure PMIC (%d)\n", err);
return 0;
}