blob: 2da868b89257def834407a1485c9225cc3cb14f5 [file] [log] [blame]
Vadim Bendeburyef77f872014-12-10 20:42:58 -08001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright 2014 Google Inc.
Vadim Bendebury6114c992014-12-16 14:34:28 -08005 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
Vadim Bendeburyef77f872014-12-10 20:42:58 -08006 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
Vadim Bendeburyef77f872014-12-10 20:42:58 -080015 */
16
Vadim Bendeburyef77f872014-12-10 20:42:58 -080017#include <arch/cache.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +020018#include <device/mmio.h>
Vadim Bendebury6114c992014-12-16 14:34:28 -080019#include <cbfs.h>
Vadim Bendeburyef77f872014-12-10 20:42:58 -080020#include <console/console.h>
Vadim Bendebury6114c992014-12-16 14:34:28 -080021#include <string.h>
22#include <timer.h>
23
24#include <soc/iomap.h>
25#include <soc/soc_services.h>
Vadim Bendeburyef77f872014-12-10 20:42:58 -080026
27#include "mbn_header.h"
28
Vikas Das08f249e2014-09-22 17:49:56 -070029static void *load_ipq_blob(const char *file_name)
Vadim Bendeburyef77f872014-12-10 20:42:58 -080030{
Vadim Bendeburyef77f872014-12-10 20:42:58 -080031 struct mbn_header *blob_mbn;
Vikas Das08f249e2014-09-22 17:49:56 -070032 void *blob_dest;
Aaron Durbin899d13d2015-05-15 23:39:23 -050033 size_t blob_size;
Vadim Bendeburyef77f872014-12-10 20:42:58 -080034
Aaron Durbin899d13d2015-05-15 23:39:23 -050035 blob_mbn = cbfs_boot_map_with_leak(file_name, CBFS_TYPE_RAW,
36 &blob_size);
37 if (!blob_mbn)
Vadim Bendeburyef77f872014-12-10 20:42:58 -080038 return NULL;
39
Vadim Bendeburyef77f872014-12-10 20:42:58 -080040 /* some sanity checks on the headers */
41 if ((blob_mbn->mbn_version != 3) ||
Aaron Durbin899d13d2015-05-15 23:39:23 -050042 (blob_mbn->mbn_total_size > blob_size))
Vadim Bendeburyef77f872014-12-10 20:42:58 -080043 return NULL;
44
Vikas Das08f249e2014-09-22 17:49:56 -070045 blob_dest = (void *) blob_mbn->mbn_destination;
46 if (blob_mbn->mbn_destination) {
47 /* Copy the blob to the appropriate memory location. */
48 memcpy(blob_dest, blob_mbn + 1, blob_mbn->mbn_total_size);
49 cache_sync_instructions();
50 return blob_dest;
51 }
52
53 /*
54 * The blob did not have to be relocated, return its address in CBFS
55 * cache.
56 */
57 return blob_mbn + 1;
Vadim Bendeburyef77f872014-12-10 20:42:58 -080058}
59
Vadim Bendeburyb16a6c42015-03-05 17:36:00 -080060#define DDR_VERSION() ((const char *)0x2a03f600)
61#define MAX_DDR_VERSION_SIZE 48
62
Vadim Bendeburyef77f872014-12-10 20:42:58 -080063int initialize_dram(void)
64{
Vikas Das08f249e2014-09-22 17:49:56 -070065 void *cdt;
Vadim Bendeburyef77f872014-12-10 20:42:58 -080066 int (*ddr_init_function)(void *cdt_header);
67
Vikas Das08f249e2014-09-22 17:49:56 -070068 cdt = load_ipq_blob("cdt.mbn");
69 ddr_init_function = load_ipq_blob("ddr.mbn");
Vadim Bendeburyef77f872014-12-10 20:42:58 -080070
Vikas Das08f249e2014-09-22 17:49:56 -070071 if (!cdt || !ddr_init_function) {
72 printk(BIOS_ERR, "cdt: %p, ddr_init_function: %p\n",
73 cdt, ddr_init_function);
Vadim Bendeburyef77f872014-12-10 20:42:58 -080074 die("could not find DDR initialization blobs\n");
75 }
76
Vikas Das08f249e2014-09-22 17:49:56 -070077 if (ddr_init_function(cdt) < 0)
Vadim Bendeburyef77f872014-12-10 20:42:58 -080078 die("Fail to Initialize DDR\n");
79
Vadim Bendeburyb16a6c42015-03-05 17:36:00 -080080 /*
Jonathan Neuschäfer5268b762018-02-12 12:24:25 +010081 * Once DDR initializer finished, its version can be found at a fixed
Vadim Bendeburyb16a6c42015-03-05 17:36:00 -080082 * address in SRAM.
83 */
84 printk(BIOS_INFO, "DDR version %.*s initialized\n",
85 MAX_DDR_VERSION_SIZE, DDR_VERSION());
Vadim Bendeburyef77f872014-12-10 20:42:58 -080086
87 return 0;
88}
Vikas Das08f249e2014-09-22 17:49:56 -070089
Vikas Das08f249e2014-09-22 17:49:56 -070090void start_tzbsp(void)
91{
92 void *tzbsp = load_ipq_blob("tz.mbn");
93
94 if (!tzbsp)
95 die("could not find or map TZBSP\n");
96
Vadim Bendebury6114c992014-12-16 14:34:28 -080097 printk(BIOS_INFO, "Starting TZBSP\n");
98
Vikas Das08f249e2014-09-22 17:49:56 -070099 tz_init_wrapper(0, 0, tzbsp);
100}
101
Vadim Bendeburyb16a6c42015-03-05 17:36:00 -0800102/* RPM version is encoded in a 32 bit word at the fixed address */
103#define RPM_VERSION() (*((u32 *)(0x00108008)))
Vadim Bendebury6114c992014-12-16 14:34:28 -0800104void start_rpm(void)
105{
106 u32 load_addr;
107 u32 ready_mask = 1 << 10;
Vadim Bendeburyb16a6c42015-03-05 17:36:00 -0800108 u32 rpm_version;
109
Vadim Bendebury6114c992014-12-16 14:34:28 -0800110 struct stopwatch sw;
111
Julius Werner2f37bd62015-02-19 14:51:15 -0800112 if (read32(RPM_SIGNAL_COOKIE) == RPM_FW_MAGIC_NUM) {
Vadim Bendebury6114c992014-12-16 14:34:28 -0800113 printk(BIOS_INFO, "RPM appears to have already started\n");
114 return;
115 }
116
117 load_addr = (u32) load_ipq_blob("rpm.mbn");
118 if (!load_addr)
119 die("could not find or map RPM code\n");
120
121 printk(BIOS_INFO, "Starting RPM\n");
122
123 /* Clear 'ready' indication. */
Sourabh Banerjee0bd22ce2015-04-24 22:54:18 +0530124 /*
125 * RPM_INT_ACK is clear-on-write type register,
126 * read-modify-write is not recommended.
127 */
128 write32(RPM_INT_ACK, ready_mask);
Vadim Bendebury6114c992014-12-16 14:34:28 -0800129
130 /* Set RPM entry address */
Julius Werner2f37bd62015-02-19 14:51:15 -0800131 write32(RPM_SIGNAL_ENTRY, load_addr);
Vadim Bendebury6114c992014-12-16 14:34:28 -0800132 /* Set cookie */
Julius Werner2f37bd62015-02-19 14:51:15 -0800133 write32(RPM_SIGNAL_COOKIE, RPM_FW_MAGIC_NUM);
Vadim Bendebury6114c992014-12-16 14:34:28 -0800134
135 /* Wait for RPM start indication, up to 100ms. */
136 stopwatch_init_usecs_expire(&sw, 100000);
Julius Werner2f37bd62015-02-19 14:51:15 -0800137 while (!(read32(RPM_INT) & ready_mask))
Vadim Bendebury6114c992014-12-16 14:34:28 -0800138 if (stopwatch_expired(&sw))
139 die("RPM Initialization failed\n");
140
141 /* Acknowledge RPM initialization */
Julius Werner2f37bd62015-02-19 14:51:15 -0800142 write32(RPM_INT_ACK, ready_mask);
Vadim Bendeburyb16a6c42015-03-05 17:36:00 -0800143
144 /* Report RPM version, it is encoded in a 32 bit value. */
145 rpm_version = RPM_VERSION();
146 printk(BIOS_INFO, "Started RPM version %d.%d.%d\n",
147 rpm_version >> 24,
148 (rpm_version >> 16) & 0xff,
149 rpm_version & 0xffff);
Vadim Bendebury6114c992014-12-16 14:34:28 -0800150}