aboutsummaryrefslogtreecommitdiff
path: root/src/soc/qualcomm/ipq806x
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/qualcomm/ipq806x')
-rw-r--r--src/soc/qualcomm/ipq806x/blobs_init.c45
-rw-r--r--src/soc/qualcomm/ipq806x/include/soc/iomap.h8
-rw-r--r--src/soc/qualcomm/ipq806x/include/soc/soc_services.h4
3 files changed, 54 insertions, 3 deletions
diff --git a/src/soc/qualcomm/ipq806x/blobs_init.c b/src/soc/qualcomm/ipq806x/blobs_init.c
index 0f3a99a7cc..a3c0cfa28e 100644
--- a/src/soc/qualcomm/ipq806x/blobs_init.c
+++ b/src/soc/qualcomm/ipq806x/blobs_init.c
@@ -2,6 +2,7 @@
* This file is part of the coreboot project.
*
* Copyright 2014 Google Inc.
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,14 +18,16 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <arch/cache.h>
+#include <arch/io.h>
#include <cbfs.h>
+#include <console/console.h>
#include <string.h>
-#include <arch/cache.h>
+#include <timer.h>
+#include <soc/iomap.h>
#include <soc/soc_services.h>
-#include <console/console.h>
-
#include "mbn_header.h"
static void *load_ipq_blob(const char *file_name)
@@ -93,7 +96,43 @@ void start_tzbsp(void)
if (!tzbsp)
die("could not find or map TZBSP\n");
+ printk(BIOS_INFO, "Starting TZBSP\n");
+
tz_init_wrapper(0, 0, tzbsp);
}
+void start_rpm(void)
+{
+ u32 load_addr;
+ u32 ready_mask = 1 << 10;
+ struct stopwatch sw;
+
+ if (readl(RPM_SIGNAL_COOKIE) == RPM_FW_MAGIC_NUM) {
+ printk(BIOS_INFO, "RPM appears to have already started\n");
+ return;
+ }
+
+ load_addr = (u32) load_ipq_blob("rpm.mbn");
+ if (!load_addr)
+ die("could not find or map RPM code\n");
+
+ printk(BIOS_INFO, "Starting RPM\n");
+
+ /* Clear 'ready' indication. */
+ writel(readl(RPM_INT_ACK) & ~ready_mask, RPM_INT_ACK);
+
+ /* Set RPM entry address */
+ writel(load_addr, RPM_SIGNAL_ENTRY);
+ /* Set cookie */
+ writel(RPM_FW_MAGIC_NUM, RPM_SIGNAL_COOKIE);
+
+ /* Wait for RPM start indication, up to 100ms. */
+ stopwatch_init_usecs_expire(&sw, 100000);
+ while (!(readl(RPM_INT) & ready_mask))
+ if (stopwatch_expired(&sw))
+ die("RPM Initialization failed\n");
+
+ /* Acknowledge RPM initialization */
+ writel(ready_mask, RPM_INT_ACK);
+}
#endif /* !__PRE_RAM__ */
diff --git a/src/soc/qualcomm/ipq806x/include/soc/iomap.h b/src/soc/qualcomm/ipq806x/include/soc/iomap.h
index 129b17700c..76131805d4 100644
--- a/src/soc/qualcomm/ipq806x/include/soc/iomap.h
+++ b/src/soc/qualcomm/ipq806x/include/soc/iomap.h
@@ -81,6 +81,13 @@
#define DGT_CLEAR DGT_REG(0x000C)
#define DGT_CLK_CTL DGT_REG(0x0010)
+/* RPM interface constants */
+#define RPM_INT ((void *)0x63020)
+#define RPM_INT_ACK ((void *)0x63060)
+#define RPM_SIGNAL_COOKIE ((void *)0x47C20)
+#define RPM_SIGNAL_ENTRY ((void *)0x47C24)
+#define RPM_FW_MAGIC_NUM 0x4D505242
+
#define TLMM_BASE_ADDR ((char *)0x00800000)
#define GPIO_CONFIG_ADDR(x) (TLMM_BASE_ADDR + 0x1000 + (x)*0x10)
#define GPIO_IN_OUT_ADDR(x) (GPIO_CONFIG_ADDR(x) + 4)
@@ -114,4 +121,5 @@
#define GSBI_QUP5_BASE 0x1A280000
#define GSBI_QUP6_BASE 0x16580000
#define GSBI_QUP7_BASE 0x16680000
+
#endif // __SOC_QUALCOMM_IPQ806X_IOMAP_H_
diff --git a/src/soc/qualcomm/ipq806x/include/soc/soc_services.h b/src/soc/qualcomm/ipq806x/include/soc/soc_services.h
index b852d7f37e..6aefb72572 100644
--- a/src/soc/qualcomm/ipq806x/include/soc/soc_services.h
+++ b/src/soc/qualcomm/ipq806x/include/soc/soc_services.h
@@ -30,6 +30,10 @@ int initialize_dram(void);
/* Loads and runs TZBSP, switches into user mode. */
void start_tzbsp(void);
+/* A helper function needed to start TZBSP properly. */
int tz_init_wrapper(int, int, void *);
+/* Load RPM code into memory and trigger its execution. */
+void start_rpm(void);
+
#endif