blob: 89c26b5834288e00f2b5b4fa7ff9fc4f4f4c7e78 [file] [log] [blame]
Angel Pons7c1d70e2020-04-04 18:51:19 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Vadim Bendeburyef77f872014-12-10 20:42:58 -08002
Vadim Bendeburyef77f872014-12-10 20:42:58 -08003#include <arch/cache.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +02004#include <device/mmio.h>
Vadim Bendebury6114c992014-12-16 14:34:28 -08005#include <cbfs.h>
Vadim Bendeburyef77f872014-12-10 20:42:58 -08006#include <console/console.h>
Vadim Bendebury6114c992014-12-16 14:34:28 -08007#include <string.h>
8#include <timer.h>
9
10#include <soc/iomap.h>
11#include <soc/soc_services.h>
Vadim Bendeburyef77f872014-12-10 20:42:58 -080012
13#include "mbn_header.h"
14
Vikas Das08f249e2014-09-22 17:49:56 -070015static void *load_ipq_blob(const char *file_name)
Vadim Bendeburyef77f872014-12-10 20:42:58 -080016{
Vadim Bendeburyef77f872014-12-10 20:42:58 -080017 struct mbn_header *blob_mbn;
Vikas Das08f249e2014-09-22 17:49:56 -070018 void *blob_dest;
Aaron Durbin899d13d2015-05-15 23:39:23 -050019 size_t blob_size;
Vadim Bendeburyef77f872014-12-10 20:42:58 -080020
Aaron Durbin899d13d2015-05-15 23:39:23 -050021 blob_mbn = cbfs_boot_map_with_leak(file_name, CBFS_TYPE_RAW,
22 &blob_size);
23 if (!blob_mbn)
Vadim Bendeburyef77f872014-12-10 20:42:58 -080024 return NULL;
25
Vadim Bendeburyef77f872014-12-10 20:42:58 -080026 /* some sanity checks on the headers */
27 if ((blob_mbn->mbn_version != 3) ||
Aaron Durbin899d13d2015-05-15 23:39:23 -050028 (blob_mbn->mbn_total_size > blob_size))
Vadim Bendeburyef77f872014-12-10 20:42:58 -080029 return NULL;
30
Vikas Das08f249e2014-09-22 17:49:56 -070031 blob_dest = (void *) blob_mbn->mbn_destination;
32 if (blob_mbn->mbn_destination) {
33 /* Copy the blob to the appropriate memory location. */
34 memcpy(blob_dest, blob_mbn + 1, blob_mbn->mbn_total_size);
35 cache_sync_instructions();
36 return blob_dest;
37 }
38
39 /*
40 * The blob did not have to be relocated, return its address in CBFS
41 * cache.
42 */
43 return blob_mbn + 1;
Vadim Bendeburyef77f872014-12-10 20:42:58 -080044}
45
Vadim Bendeburyb16a6c42015-03-05 17:36:00 -080046#define DDR_VERSION() ((const char *)0x2a03f600)
47#define MAX_DDR_VERSION_SIZE 48
48
Vadim Bendeburyef77f872014-12-10 20:42:58 -080049int initialize_dram(void)
50{
Vikas Das08f249e2014-09-22 17:49:56 -070051 void *cdt;
Vadim Bendeburyef77f872014-12-10 20:42:58 -080052 int (*ddr_init_function)(void *cdt_header);
53
Vikas Das08f249e2014-09-22 17:49:56 -070054 cdt = load_ipq_blob("cdt.mbn");
55 ddr_init_function = load_ipq_blob("ddr.mbn");
Vadim Bendeburyef77f872014-12-10 20:42:58 -080056
Vikas Das08f249e2014-09-22 17:49:56 -070057 if (!cdt || !ddr_init_function) {
58 printk(BIOS_ERR, "cdt: %p, ddr_init_function: %p\n",
59 cdt, ddr_init_function);
Vadim Bendeburyef77f872014-12-10 20:42:58 -080060 die("could not find DDR initialization blobs\n");
61 }
62
Vikas Das08f249e2014-09-22 17:49:56 -070063 if (ddr_init_function(cdt) < 0)
Vadim Bendeburyef77f872014-12-10 20:42:58 -080064 die("Fail to Initialize DDR\n");
65
Vadim Bendeburyb16a6c42015-03-05 17:36:00 -080066 /*
Jonathan Neuschäfer5268b762018-02-12 12:24:25 +010067 * Once DDR initializer finished, its version can be found at a fixed
Vadim Bendeburyb16a6c42015-03-05 17:36:00 -080068 * address in SRAM.
69 */
70 printk(BIOS_INFO, "DDR version %.*s initialized\n",
71 MAX_DDR_VERSION_SIZE, DDR_VERSION());
Vadim Bendeburyef77f872014-12-10 20:42:58 -080072
73 return 0;
74}
Vikas Das08f249e2014-09-22 17:49:56 -070075
Vikas Das08f249e2014-09-22 17:49:56 -070076void start_tzbsp(void)
77{
78 void *tzbsp = load_ipq_blob("tz.mbn");
79
80 if (!tzbsp)
81 die("could not find or map TZBSP\n");
82
Vadim Bendebury6114c992014-12-16 14:34:28 -080083 printk(BIOS_INFO, "Starting TZBSP\n");
84
Vikas Das08f249e2014-09-22 17:49:56 -070085 tz_init_wrapper(0, 0, tzbsp);
86}
87
Vadim Bendeburyb16a6c42015-03-05 17:36:00 -080088/* RPM version is encoded in a 32 bit word at the fixed address */
89#define RPM_VERSION() (*((u32 *)(0x00108008)))
Vadim Bendebury6114c992014-12-16 14:34:28 -080090void start_rpm(void)
91{
92 u32 load_addr;
93 u32 ready_mask = 1 << 10;
Vadim Bendeburyb16a6c42015-03-05 17:36:00 -080094 u32 rpm_version;
95
Vadim Bendebury6114c992014-12-16 14:34:28 -080096 struct stopwatch sw;
97
Julius Werner2f37bd62015-02-19 14:51:15 -080098 if (read32(RPM_SIGNAL_COOKIE) == RPM_FW_MAGIC_NUM) {
Vadim Bendebury6114c992014-12-16 14:34:28 -080099 printk(BIOS_INFO, "RPM appears to have already started\n");
100 return;
101 }
102
103 load_addr = (u32) load_ipq_blob("rpm.mbn");
104 if (!load_addr)
105 die("could not find or map RPM code\n");
106
107 printk(BIOS_INFO, "Starting RPM\n");
108
109 /* Clear 'ready' indication. */
Sourabh Banerjee0bd22ce2015-04-24 22:54:18 +0530110 /*
111 * RPM_INT_ACK is clear-on-write type register,
112 * read-modify-write is not recommended.
113 */
114 write32(RPM_INT_ACK, ready_mask);
Vadim Bendebury6114c992014-12-16 14:34:28 -0800115
116 /* Set RPM entry address */
Julius Werner2f37bd62015-02-19 14:51:15 -0800117 write32(RPM_SIGNAL_ENTRY, load_addr);
Vadim Bendebury6114c992014-12-16 14:34:28 -0800118 /* Set cookie */
Julius Werner2f37bd62015-02-19 14:51:15 -0800119 write32(RPM_SIGNAL_COOKIE, RPM_FW_MAGIC_NUM);
Vadim Bendebury6114c992014-12-16 14:34:28 -0800120
121 /* Wait for RPM start indication, up to 100ms. */
122 stopwatch_init_usecs_expire(&sw, 100000);
Julius Werner2f37bd62015-02-19 14:51:15 -0800123 while (!(read32(RPM_INT) & ready_mask))
Vadim Bendebury6114c992014-12-16 14:34:28 -0800124 if (stopwatch_expired(&sw))
125 die("RPM Initialization failed\n");
126
127 /* Acknowledge RPM initialization */
Julius Werner2f37bd62015-02-19 14:51:15 -0800128 write32(RPM_INT_ACK, ready_mask);
Vadim Bendeburyb16a6c42015-03-05 17:36:00 -0800129
130 /* Report RPM version, it is encoded in a 32 bit value. */
131 rpm_version = RPM_VERSION();
132 printk(BIOS_INFO, "Started RPM version %d.%d.%d\n",
133 rpm_version >> 24,
134 (rpm_version >> 16) & 0xff,
135 rpm_version & 0xffff);
Vadim Bendebury6114c992014-12-16 14:34:28 -0800136}