diff --git a/src/mainboard/google/storm/mainboard.c b/src/mainboard/google/storm/mainboard.c index 5abf2f7646..e69a1ea894 100644 --- a/src/mainboard/google/storm/mainboard.c +++ b/src/mainboard/google/storm/mainboard.c @@ -111,6 +111,7 @@ static void assert_sw_reset(void) static void mainboard_init(device_t dev) { start_tzbsp(); + start_rpm(); setup_mmu(); setup_usb(); assert_sw_reset(); 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,13 +18,15 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include #include - -#include - +#include +#include #include +#include +#include + +#include +#include #include "mbn_header.h" @@ -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