Angel Pons | 7c1d70e | 2020-04-04 18:51:19 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
Vadim Bendebury | ef77f87 | 2014-12-10 20:42:58 -0800 | [diff] [blame] | 2 | |
Vadim Bendebury | ef77f87 | 2014-12-10 20:42:58 -0800 | [diff] [blame] | 3 | #include <arch/cache.h> |
Kyösti Mälkki | 13f6650 | 2019-03-03 08:01:05 +0200 | [diff] [blame] | 4 | #include <device/mmio.h> |
Vadim Bendebury | 6114c99 | 2014-12-16 14:34:28 -0800 | [diff] [blame] | 5 | #include <cbfs.h> |
Vadim Bendebury | ef77f87 | 2014-12-10 20:42:58 -0800 | [diff] [blame] | 6 | #include <console/console.h> |
Vadim Bendebury | 6114c99 | 2014-12-16 14:34:28 -0800 | [diff] [blame] | 7 | #include <string.h> |
| 8 | #include <timer.h> |
| 9 | |
| 10 | #include <soc/iomap.h> |
| 11 | #include <soc/soc_services.h> |
Vadim Bendebury | ef77f87 | 2014-12-10 20:42:58 -0800 | [diff] [blame] | 12 | |
| 13 | #include "mbn_header.h" |
| 14 | |
Vikas Das | 08f249e | 2014-09-22 17:49:56 -0700 | [diff] [blame] | 15 | static void *load_ipq_blob(const char *file_name) |
Vadim Bendebury | ef77f87 | 2014-12-10 20:42:58 -0800 | [diff] [blame] | 16 | { |
Vadim Bendebury | ef77f87 | 2014-12-10 20:42:58 -0800 | [diff] [blame] | 17 | struct mbn_header *blob_mbn; |
Vikas Das | 08f249e | 2014-09-22 17:49:56 -0700 | [diff] [blame] | 18 | void *blob_dest; |
Aaron Durbin | 899d13d | 2015-05-15 23:39:23 -0500 | [diff] [blame] | 19 | size_t blob_size; |
Vadim Bendebury | ef77f87 | 2014-12-10 20:42:58 -0800 | [diff] [blame] | 20 | |
Julius Werner | 834b3ec | 2020-03-04 16:52:08 -0800 | [diff] [blame] | 21 | blob_mbn = cbfs_map(file_name, &blob_size); |
Aaron Durbin | 899d13d | 2015-05-15 23:39:23 -0500 | [diff] [blame] | 22 | if (!blob_mbn) |
Vadim Bendebury | ef77f87 | 2014-12-10 20:42:58 -0800 | [diff] [blame] | 23 | return NULL; |
| 24 | |
Vadim Bendebury | ef77f87 | 2014-12-10 20:42:58 -0800 | [diff] [blame] | 25 | /* some sanity checks on the headers */ |
| 26 | if ((blob_mbn->mbn_version != 3) || |
Aaron Durbin | 899d13d | 2015-05-15 23:39:23 -0500 | [diff] [blame] | 27 | (blob_mbn->mbn_total_size > blob_size)) |
Vadim Bendebury | ef77f87 | 2014-12-10 20:42:58 -0800 | [diff] [blame] | 28 | return NULL; |
| 29 | |
Elyes Haouas | 9776738 | 2022-11-18 15:08:13 +0100 | [diff] [blame] | 30 | blob_dest = (void *)blob_mbn->mbn_destination; |
Vikas Das | 08f249e | 2014-09-22 17:49:56 -0700 | [diff] [blame] | 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 Bendebury | ef77f87 | 2014-12-10 20:42:58 -0800 | [diff] [blame] | 43 | } |
| 44 | |
Vadim Bendebury | b16a6c4 | 2015-03-05 17:36:00 -0800 | [diff] [blame] | 45 | #define DDR_VERSION() ((const char *)0x2a03f600) |
| 46 | #define MAX_DDR_VERSION_SIZE 48 |
| 47 | |
Vadim Bendebury | ef77f87 | 2014-12-10 20:42:58 -0800 | [diff] [blame] | 48 | int initialize_dram(void) |
| 49 | { |
Vikas Das | 08f249e | 2014-09-22 17:49:56 -0700 | [diff] [blame] | 50 | void *cdt; |
Vadim Bendebury | ef77f87 | 2014-12-10 20:42:58 -0800 | [diff] [blame] | 51 | int (*ddr_init_function)(void *cdt_header); |
| 52 | |
Vikas Das | 08f249e | 2014-09-22 17:49:56 -0700 | [diff] [blame] | 53 | cdt = load_ipq_blob("cdt.mbn"); |
| 54 | ddr_init_function = load_ipq_blob("ddr.mbn"); |
Vadim Bendebury | ef77f87 | 2014-12-10 20:42:58 -0800 | [diff] [blame] | 55 | |
Vikas Das | 08f249e | 2014-09-22 17:49:56 -0700 | [diff] [blame] | 56 | if (!cdt || !ddr_init_function) { |
| 57 | printk(BIOS_ERR, "cdt: %p, ddr_init_function: %p\n", |
| 58 | cdt, ddr_init_function); |
Vadim Bendebury | ef77f87 | 2014-12-10 20:42:58 -0800 | [diff] [blame] | 59 | die("could not find DDR initialization blobs\n"); |
| 60 | } |
| 61 | |
Vikas Das | 08f249e | 2014-09-22 17:49:56 -0700 | [diff] [blame] | 62 | if (ddr_init_function(cdt) < 0) |
Vadim Bendebury | ef77f87 | 2014-12-10 20:42:58 -0800 | [diff] [blame] | 63 | die("Fail to Initialize DDR\n"); |
| 64 | |
Vadim Bendebury | b16a6c4 | 2015-03-05 17:36:00 -0800 | [diff] [blame] | 65 | /* |
Jonathan Neuschäfer | 5268b76 | 2018-02-12 12:24:25 +0100 | [diff] [blame] | 66 | * Once DDR initializer finished, its version can be found at a fixed |
Vadim Bendebury | b16a6c4 | 2015-03-05 17:36:00 -0800 | [diff] [blame] | 67 | * address in SRAM. |
| 68 | */ |
| 69 | printk(BIOS_INFO, "DDR version %.*s initialized\n", |
| 70 | MAX_DDR_VERSION_SIZE, DDR_VERSION()); |
Vadim Bendebury | ef77f87 | 2014-12-10 20:42:58 -0800 | [diff] [blame] | 71 | |
| 72 | return 0; |
| 73 | } |
Vikas Das | 08f249e | 2014-09-22 17:49:56 -0700 | [diff] [blame] | 74 | |
Vikas Das | 08f249e | 2014-09-22 17:49:56 -0700 | [diff] [blame] | 75 | void 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 Bendebury | 6114c99 | 2014-12-16 14:34:28 -0800 | [diff] [blame] | 82 | printk(BIOS_INFO, "Starting TZBSP\n"); |
| 83 | |
Vikas Das | 08f249e | 2014-09-22 17:49:56 -0700 | [diff] [blame] | 84 | tz_init_wrapper(0, 0, tzbsp); |
| 85 | } |
| 86 | |
Vadim Bendebury | b16a6c4 | 2015-03-05 17:36:00 -0800 | [diff] [blame] | 87 | /* RPM version is encoded in a 32 bit word at the fixed address */ |
| 88 | #define RPM_VERSION() (*((u32 *)(0x00108008))) |
Vadim Bendebury | 6114c99 | 2014-12-16 14:34:28 -0800 | [diff] [blame] | 89 | void start_rpm(void) |
| 90 | { |
| 91 | u32 load_addr; |
| 92 | u32 ready_mask = 1 << 10; |
Vadim Bendebury | b16a6c4 | 2015-03-05 17:36:00 -0800 | [diff] [blame] | 93 | u32 rpm_version; |
| 94 | |
Vadim Bendebury | 6114c99 | 2014-12-16 14:34:28 -0800 | [diff] [blame] | 95 | struct stopwatch sw; |
| 96 | |
Julius Werner | 2f37bd6 | 2015-02-19 14:51:15 -0800 | [diff] [blame] | 97 | if (read32(RPM_SIGNAL_COOKIE) == RPM_FW_MAGIC_NUM) { |
Vadim Bendebury | 6114c99 | 2014-12-16 14:34:28 -0800 | [diff] [blame] | 98 | printk(BIOS_INFO, "RPM appears to have already started\n"); |
| 99 | return; |
| 100 | } |
| 101 | |
Elyes Haouas | 9776738 | 2022-11-18 15:08:13 +0100 | [diff] [blame] | 102 | load_addr = (u32)load_ipq_blob("rpm.mbn"); |
Vadim Bendebury | 6114c99 | 2014-12-16 14:34:28 -0800 | [diff] [blame] | 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 Banerjee | 0bd22ce | 2015-04-24 22:54:18 +0530 | [diff] [blame] | 109 | /* |
| 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 Bendebury | 6114c99 | 2014-12-16 14:34:28 -0800 | [diff] [blame] | 114 | |
| 115 | /* Set RPM entry address */ |
Julius Werner | 2f37bd6 | 2015-02-19 14:51:15 -0800 | [diff] [blame] | 116 | write32(RPM_SIGNAL_ENTRY, load_addr); |
Vadim Bendebury | 6114c99 | 2014-12-16 14:34:28 -0800 | [diff] [blame] | 117 | /* Set cookie */ |
Julius Werner | 2f37bd6 | 2015-02-19 14:51:15 -0800 | [diff] [blame] | 118 | write32(RPM_SIGNAL_COOKIE, RPM_FW_MAGIC_NUM); |
Vadim Bendebury | 6114c99 | 2014-12-16 14:34:28 -0800 | [diff] [blame] | 119 | |
| 120 | /* Wait for RPM start indication, up to 100ms. */ |
| 121 | stopwatch_init_usecs_expire(&sw, 100000); |
Julius Werner | 2f37bd6 | 2015-02-19 14:51:15 -0800 | [diff] [blame] | 122 | while (!(read32(RPM_INT) & ready_mask)) |
Vadim Bendebury | 6114c99 | 2014-12-16 14:34:28 -0800 | [diff] [blame] | 123 | if (stopwatch_expired(&sw)) |
| 124 | die("RPM Initialization failed\n"); |
| 125 | |
| 126 | /* Acknowledge RPM initialization */ |
Julius Werner | 2f37bd6 | 2015-02-19 14:51:15 -0800 | [diff] [blame] | 127 | write32(RPM_INT_ACK, ready_mask); |
Vadim Bendebury | b16a6c4 | 2015-03-05 17:36:00 -0800 | [diff] [blame] | 128 | |
| 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 Bendebury | 6114c99 | 2014-12-16 14:34:28 -0800 | [diff] [blame] | 135 | } |