blob: 15068a59de630a463e8df4b1f1b68271bc6703b0 [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
Julius Werner834b3ec2020-03-04 16:52:08 -080021 blob_mbn = cbfs_map(file_name, &blob_size);
Aaron Durbin899d13d2015-05-15 23:39:23 -050022 if (!blob_mbn)
Vadim Bendeburyef77f872014-12-10 20:42:58 -080023 return NULL;
24
Vadim Bendeburyef77f872014-12-10 20:42:58 -080025 /* some sanity checks on the headers */
26 if ((blob_mbn->mbn_version != 3) ||
Aaron Durbin899d13d2015-05-15 23:39:23 -050027 (blob_mbn->mbn_total_size > blob_size))
Vadim Bendeburyef77f872014-12-10 20:42:58 -080028 return NULL;
29
Vikas Das08f249e2014-09-22 17:49:56 -070030 blob_dest = (void *) blob_mbn->mbn_destination;
31 if (blob_mbn->mbn_destination) {
32 /* Copy the blob to the appropriate memory location. */
33 memcpy(blob_dest, blob_mbn + 1, blob_mbn->mbn_total_size);
34 cache_sync_instructions();
35 return blob_dest;
36 }
37
38 /*
39 * The blob did not have to be relocated, return its address in CBFS
40 * cache.
41 */
42 return blob_mbn + 1;
Vadim Bendeburyef77f872014-12-10 20:42:58 -080043}
44
Vadim Bendeburyb16a6c42015-03-05 17:36:00 -080045#define DDR_VERSION() ((const char *)0x2a03f600)
46#define MAX_DDR_VERSION_SIZE 48
47
Vadim Bendeburyef77f872014-12-10 20:42:58 -080048int initialize_dram(void)
49{
Vikas Das08f249e2014-09-22 17:49:56 -070050 void *cdt;
Vadim Bendeburyef77f872014-12-10 20:42:58 -080051 int (*ddr_init_function)(void *cdt_header);
52
Vikas Das08f249e2014-09-22 17:49:56 -070053 cdt = load_ipq_blob("cdt.mbn");
54 ddr_init_function = load_ipq_blob("ddr.mbn");
Vadim Bendeburyef77f872014-12-10 20:42:58 -080055
Vikas Das08f249e2014-09-22 17:49:56 -070056 if (!cdt || !ddr_init_function) {
57 printk(BIOS_ERR, "cdt: %p, ddr_init_function: %p\n",
58 cdt, ddr_init_function);
Vadim Bendeburyef77f872014-12-10 20:42:58 -080059 die("could not find DDR initialization blobs\n");
60 }
61
Vikas Das08f249e2014-09-22 17:49:56 -070062 if (ddr_init_function(cdt) < 0)
Vadim Bendeburyef77f872014-12-10 20:42:58 -080063 die("Fail to Initialize DDR\n");
64
Vadim Bendeburyb16a6c42015-03-05 17:36:00 -080065 /*
Jonathan Neuschäfer5268b762018-02-12 12:24:25 +010066 * Once DDR initializer finished, its version can be found at a fixed
Vadim Bendeburyb16a6c42015-03-05 17:36:00 -080067 * address in SRAM.
68 */
69 printk(BIOS_INFO, "DDR version %.*s initialized\n",
70 MAX_DDR_VERSION_SIZE, DDR_VERSION());
Vadim Bendeburyef77f872014-12-10 20:42:58 -080071
72 return 0;
73}
Vikas Das08f249e2014-09-22 17:49:56 -070074
Vikas Das08f249e2014-09-22 17:49:56 -070075void start_tzbsp(void)
76{
77 void *tzbsp = load_ipq_blob("tz.mbn");
78
79 if (!tzbsp)
80 die("could not find or map TZBSP\n");
81
Vadim Bendebury6114c992014-12-16 14:34:28 -080082 printk(BIOS_INFO, "Starting TZBSP\n");
83
Vikas Das08f249e2014-09-22 17:49:56 -070084 tz_init_wrapper(0, 0, tzbsp);
85}
86
Vadim Bendeburyb16a6c42015-03-05 17:36:00 -080087/* RPM version is encoded in a 32 bit word at the fixed address */
88#define RPM_VERSION() (*((u32 *)(0x00108008)))
Vadim Bendebury6114c992014-12-16 14:34:28 -080089void start_rpm(void)
90{
91 u32 load_addr;
92 u32 ready_mask = 1 << 10;
Vadim Bendeburyb16a6c42015-03-05 17:36:00 -080093 u32 rpm_version;
94
Vadim Bendebury6114c992014-12-16 14:34:28 -080095 struct stopwatch sw;
96
Julius Werner2f37bd62015-02-19 14:51:15 -080097 if (read32(RPM_SIGNAL_COOKIE) == RPM_FW_MAGIC_NUM) {
Vadim Bendebury6114c992014-12-16 14:34:28 -080098 printk(BIOS_INFO, "RPM appears to have already started\n");
99 return;
100 }
101
102 load_addr = (u32) load_ipq_blob("rpm.mbn");
103 if (!load_addr)
104 die("could not find or map RPM code\n");
105
106 printk(BIOS_INFO, "Starting RPM\n");
107
108 /* Clear 'ready' indication. */
Sourabh Banerjee0bd22ce2015-04-24 22:54:18 +0530109 /*
110 * RPM_INT_ACK is clear-on-write type register,
111 * read-modify-write is not recommended.
112 */
113 write32(RPM_INT_ACK, ready_mask);
Vadim Bendebury6114c992014-12-16 14:34:28 -0800114
115 /* Set RPM entry address */
Julius Werner2f37bd62015-02-19 14:51:15 -0800116 write32(RPM_SIGNAL_ENTRY, load_addr);
Vadim Bendebury6114c992014-12-16 14:34:28 -0800117 /* Set cookie */
Julius Werner2f37bd62015-02-19 14:51:15 -0800118 write32(RPM_SIGNAL_COOKIE, RPM_FW_MAGIC_NUM);
Vadim Bendebury6114c992014-12-16 14:34:28 -0800119
120 /* Wait for RPM start indication, up to 100ms. */
121 stopwatch_init_usecs_expire(&sw, 100000);
Julius Werner2f37bd62015-02-19 14:51:15 -0800122 while (!(read32(RPM_INT) & ready_mask))
Vadim Bendebury6114c992014-12-16 14:34:28 -0800123 if (stopwatch_expired(&sw))
124 die("RPM Initialization failed\n");
125
126 /* Acknowledge RPM initialization */
Julius Werner2f37bd62015-02-19 14:51:15 -0800127 write32(RPM_INT_ACK, ready_mask);
Vadim Bendeburyb16a6c42015-03-05 17:36:00 -0800128
129 /* Report RPM version, it is encoded in a 32 bit value. */
130 rpm_version = RPM_VERSION();
131 printk(BIOS_INFO, "Started RPM version %d.%d.%d\n",
132 rpm_version >> 24,
133 (rpm_version >> 16) & 0xff,
134 rpm_version & 0xffff);
Vadim Bendebury6114c992014-12-16 14:34:28 -0800135}