blob: 20b5cf48f5587954030ad19f6f554a3795c3a9d7 [file] [log] [blame]
Stephen Warren0e012c32012-08-05 16:07:22 +00001/*
Stephen Warrend6f47c82016-03-24 22:15:20 -06002 * (C) Copyright 2012-2016 Stephen Warren
Stephen Warren0e012c32012-08-05 16:07:22 +00003 *
Stephen Warren29e494c2015-02-16 12:16:13 -07004 * SPDX-License-Identifier: GPL-2.0
Stephen Warren0e012c32012-08-05 16:07:22 +00005 */
6
7#include <common.h>
Lubomir Rintel7d33bb62016-02-22 22:06:47 +01008#include <inttypes.h>
Stephen Warrenaa44d532013-05-27 18:31:18 +00009#include <config.h>
Simon Glass74807622014-09-22 17:30:56 -060010#include <dm.h>
Jeroen Hofsteed5b2fed2014-07-13 22:01:51 +020011#include <fdt_support.h>
Nikita Kiryanovb071e4c2015-02-03 13:32:31 +020012#include <fdt_simplefb.h>
Stephen Warrenaa44d532013-05-27 18:31:18 +000013#include <lcd.h>
Simon Glass2dd337a2015-09-02 17:24:58 -060014#include <memalign.h>
Jeroen Hofsteed5b2fed2014-07-13 22:01:51 +020015#include <mmc.h>
Simon Glass74807622014-09-22 17:30:56 -060016#include <asm/gpio.h>
Stephen Warrenacc8bf42013-01-29 16:37:37 +000017#include <asm/arch/mbox.h>
Stephen Warrenc4ab9712013-01-29 16:37:42 +000018#include <asm/arch/sdhci.h>
Stephen Warren0e012c32012-08-05 16:07:22 +000019#include <asm/global_data.h>
Simon Glassf52cada2014-11-24 21:36:34 -070020#include <dm/platform_data/serial_pl01x.h>
Stephen Warrend6f47c82016-03-24 22:15:20 -060021#include <dm/platform_data/serial_bcm283x_mu.h>
Stephen Warren0e012c32012-08-05 16:07:22 +000022
23DECLARE_GLOBAL_DATA_PTR;
24
Simon Glass74807622014-09-22 17:30:56 -060025static const struct bcm2835_gpio_platdata gpio_platdata = {
26 .base = BCM2835_GPIO_BASE,
27};
28
29U_BOOT_DEVICE(bcm2835_gpios) = {
30 .name = "gpio_bcm2835",
31 .platdata = &gpio_platdata,
32};
33
Stephen Warrend6f47c82016-03-24 22:15:20 -060034#ifdef CONFIG_PL01X_SERIAL
Simon Glassf52cada2014-11-24 21:36:34 -070035static const struct pl01x_serial_platdata serial_platdata = {
Stephen Warren9d5990b2016-03-16 21:40:56 -060036#ifndef CONFIG_BCM2835
Stephen Warrendc7ea682015-02-16 12:16:15 -070037 .base = 0x3f201000,
38#else
Simon Glassf52cada2014-11-24 21:36:34 -070039 .base = 0x20201000,
Stephen Warrendc7ea682015-02-16 12:16:15 -070040#endif
Simon Glassf52cada2014-11-24 21:36:34 -070041 .type = TYPE_PL011,
Eric Anholtbe5a7dd2016-03-13 18:16:54 -070042 .skip_init = true,
Simon Glassf52cada2014-11-24 21:36:34 -070043};
44
45U_BOOT_DEVICE(bcm2835_serials) = {
46 .name = "serial_pl01x",
47 .platdata = &serial_platdata,
48};
Stephen Warrend6f47c82016-03-24 22:15:20 -060049#else
50static const struct bcm283x_mu_serial_platdata serial_platdata = {
51 .base = 0x3f215040,
52 .clock = 250000000,
53 .skip_init = true,
54};
55
56U_BOOT_DEVICE(bcm2837_serials) = {
57 .name = "serial_bcm283x_mu",
58 .platdata = &serial_platdata,
59};
60#endif
Simon Glassf52cada2014-11-24 21:36:34 -070061
Stephen Warrenacc8bf42013-01-29 16:37:37 +000062struct msg_get_arm_mem {
63 struct bcm2835_mbox_hdr hdr;
64 struct bcm2835_mbox_tag_get_arm_mem get_arm_mem;
65 u32 end_tag;
66};
67
Stephen Warrencd210c12014-11-18 21:40:21 -070068struct msg_get_board_rev {
69 struct bcm2835_mbox_hdr hdr;
70 struct bcm2835_mbox_tag_get_board_rev get_board_rev;
71 u32 end_tag;
72};
73
Lubomir Rintel7d33bb62016-02-22 22:06:47 +010074struct msg_get_board_serial {
75 struct bcm2835_mbox_hdr hdr;
76 struct bcm2835_mbox_tag_get_board_serial get_board_serial;
77 u32 end_tag;
78};
79
Stephen Warrenaf6e20d2014-09-26 20:51:39 -060080struct msg_get_mac_address {
81 struct bcm2835_mbox_hdr hdr;
82 struct bcm2835_mbox_tag_get_mac_address get_mac_address;
83 u32 end_tag;
84};
85
Stephen Warren8672d202014-01-13 19:50:11 -070086struct msg_set_power_state {
87 struct bcm2835_mbox_hdr hdr;
88 struct bcm2835_mbox_tag_set_power_state set_power_state;
89 u32 end_tag;
90};
91
Stephen Warrenc4ab9712013-01-29 16:37:42 +000092struct msg_get_clock_rate {
93 struct bcm2835_mbox_hdr hdr;
94 struct bcm2835_mbox_tag_get_clock_rate get_clock_rate;
95 u32 end_tag;
96};
97
Stephen Warrenbe8efec2015-12-04 22:07:44 -070098/*
99 * http://raspberryalphaomega.org.uk/2013/02/06/automatic-raspberry-pi-board-revision-detection-model-a-b1-and-b2/
100 * http://www.raspberrypi.org/forums/viewtopic.php?f=63&t=32733
Stephen Warren26683852015-12-04 22:07:45 -0700101 * http://git.drogon.net/?p=wiringPi;a=blob;f=wiringPi/wiringPi.c;h=503151f61014418b9c42f4476a6086f75cd4e64b;hb=refs/heads/master#l922
Stephen Warrena33dc8b2016-01-28 22:24:44 -0700102 *
103 * In http://lists.denx.de/pipermail/u-boot/2016-January/243752.html
104 * ("[U-Boot] [PATCH] rpi: fix up Model B entries") Dom Cobley at the RPi
105 * Foundation stated that the following source was accurate:
106 * https://github.com/AndrewFromMelbourne/raspberry_pi_revision
Stephen Warrenbe8efec2015-12-04 22:07:44 -0700107 */
Stephen Warren26683852015-12-04 22:07:45 -0700108struct rpi_model {
Stephen Warrencd210c12014-11-18 21:40:21 -0700109 const char *name;
110 const char *fdtfile;
Stephen Warrenb2fa38362014-12-05 20:56:46 -0700111 bool has_onboard_eth;
Stephen Warren26683852015-12-04 22:07:45 -0700112};
113
114static const struct rpi_model rpi_model_unknown = {
115 "Unknown model",
Stephen Warren93970ce2016-03-24 22:15:17 -0600116 "bcm283x-rpi-other.dtb",
Stephen Warren26683852015-12-04 22:07:45 -0700117 false,
118};
119
120static const struct rpi_model rpi_models_new_scheme[] = {
Stephen Warrenbe8efec2015-12-04 22:07:44 -0700121 [0x4] = {
Stephen Warrendc7ea682015-02-16 12:16:15 -0700122 "2 Model B",
123 "bcm2836-rpi-2-b.dtb",
124 true,
125 },
Stephen Warren303244a2016-03-24 22:15:18 -0600126 [0x8] = {
127 "3 Model B",
128 "bcm2837-rpi-3-b.dtb",
129 true,
130 },
Stephen Warren2f1f20b2015-12-04 22:07:46 -0700131 [0x9] = {
132 "Zero",
133 "bcm2835-rpi-zero.dtb",
134 false,
135 },
Stephen Warren26683852015-12-04 22:07:45 -0700136};
137
138static const struct rpi_model rpi_models_old_scheme[] = {
Stephen Warrenbe8efec2015-12-04 22:07:44 -0700139 [0x2] = {
Lubomir Rintelc44f76e2016-01-29 09:35:52 +0100140 "Model B",
141 "bcm2835-rpi-b.dtb",
Stephen Warrenb2fa38362014-12-05 20:56:46 -0700142 true,
Stephen Warrencd210c12014-11-18 21:40:21 -0700143 },
Stephen Warrenbe8efec2015-12-04 22:07:44 -0700144 [0x3] = {
Lubomir Rintelc44f76e2016-01-29 09:35:52 +0100145 "Model B",
146 "bcm2835-rpi-b.dtb",
Stephen Warrenb2fa38362014-12-05 20:56:46 -0700147 true,
Stephen Warrencd210c12014-11-18 21:40:21 -0700148 },
Stephen Warrenbe8efec2015-12-04 22:07:44 -0700149 [0x4] = {
Lubomir Rintelc44f76e2016-01-29 09:35:52 +0100150 "Model B rev2",
151 "bcm2835-rpi-b-rev2.dtb",
Stephen Warrenb2fa38362014-12-05 20:56:46 -0700152 true,
Stephen Warrencd210c12014-11-18 21:40:21 -0700153 },
Stephen Warrenbe8efec2015-12-04 22:07:44 -0700154 [0x5] = {
Lubomir Rintelc44f76e2016-01-29 09:35:52 +0100155 "Model B rev2",
156 "bcm2835-rpi-b-rev2.dtb",
Stephen Warrenb2fa38362014-12-05 20:56:46 -0700157 true,
Stephen Warrencd210c12014-11-18 21:40:21 -0700158 },
Stephen Warrenbe8efec2015-12-04 22:07:44 -0700159 [0x6] = {
Lubomir Rintelc44f76e2016-01-29 09:35:52 +0100160 "Model B rev2",
161 "bcm2835-rpi-b-rev2.dtb",
Stephen Warrenb2fa38362014-12-05 20:56:46 -0700162 true,
Stephen Warrencd210c12014-11-18 21:40:21 -0700163 },
Stephen Warrenbe8efec2015-12-04 22:07:44 -0700164 [0x7] = {
Stephen Warrencd210c12014-11-18 21:40:21 -0700165 "Model A",
166 "bcm2835-rpi-a.dtb",
Stephen Warrenb2fa38362014-12-05 20:56:46 -0700167 false,
Stephen Warrencd210c12014-11-18 21:40:21 -0700168 },
Stephen Warrenbe8efec2015-12-04 22:07:44 -0700169 [0x8] = {
Stephen Warrencd210c12014-11-18 21:40:21 -0700170 "Model A",
171 "bcm2835-rpi-a.dtb",
Stephen Warrenb2fa38362014-12-05 20:56:46 -0700172 false,
Stephen Warrencd210c12014-11-18 21:40:21 -0700173 },
Stephen Warrenbe8efec2015-12-04 22:07:44 -0700174 [0x9] = {
Stephen Warrencd210c12014-11-18 21:40:21 -0700175 "Model A",
176 "bcm2835-rpi-a.dtb",
Stephen Warrenb2fa38362014-12-05 20:56:46 -0700177 false,
Stephen Warrencd210c12014-11-18 21:40:21 -0700178 },
Stephen Warrenbe8efec2015-12-04 22:07:44 -0700179 [0xd] = {
Stephen Warrencd210c12014-11-18 21:40:21 -0700180 "Model B rev2",
181 "bcm2835-rpi-b-rev2.dtb",
Stephen Warrenb2fa38362014-12-05 20:56:46 -0700182 true,
Stephen Warrencd210c12014-11-18 21:40:21 -0700183 },
Stephen Warrenbe8efec2015-12-04 22:07:44 -0700184 [0xe] = {
Stephen Warrencd210c12014-11-18 21:40:21 -0700185 "Model B rev2",
186 "bcm2835-rpi-b-rev2.dtb",
Stephen Warrenb2fa38362014-12-05 20:56:46 -0700187 true,
Stephen Warrencd210c12014-11-18 21:40:21 -0700188 },
Stephen Warrenbe8efec2015-12-04 22:07:44 -0700189 [0xf] = {
Stephen Warrencd210c12014-11-18 21:40:21 -0700190 "Model B rev2",
191 "bcm2835-rpi-b-rev2.dtb",
Stephen Warrenb2fa38362014-12-05 20:56:46 -0700192 true,
Stephen Warrencd210c12014-11-18 21:40:21 -0700193 },
Stephen Warrenbe8efec2015-12-04 22:07:44 -0700194 [0x10] = {
Stephen Warrencd210c12014-11-18 21:40:21 -0700195 "Model B+",
196 "bcm2835-rpi-b-plus.dtb",
Stephen Warrenb2fa38362014-12-05 20:56:46 -0700197 true,
Stephen Warrencd210c12014-11-18 21:40:21 -0700198 },
Stephen Warrenbe8efec2015-12-04 22:07:44 -0700199 [0x11] = {
Stephen Warrencd210c12014-11-18 21:40:21 -0700200 "Compute Module",
201 "bcm2835-rpi-cm.dtb",
Stephen Warrenb2fa38362014-12-05 20:56:46 -0700202 false,
Stephen Warrencd210c12014-11-18 21:40:21 -0700203 },
Stephen Warrenbe8efec2015-12-04 22:07:44 -0700204 [0x12] = {
Stephen Warren18a5fc62014-12-23 20:01:43 -0700205 "Model A+",
206 "bcm2835-rpi-a-plus.dtb",
207 false,
208 },
Stephen Warrenbe8efec2015-12-04 22:07:44 -0700209 [0x13] = {
Stephen Warren3648a852015-04-12 21:43:25 -0600210 "Model B+",
211 "bcm2835-rpi-b-plus.dtb",
212 true,
213 },
Stephen Warrenbe8efec2015-12-04 22:07:44 -0700214 [0x14] = {
Stephen Warren3648a852015-04-12 21:43:25 -0600215 "Compute Module",
216 "bcm2835-rpi-cm.dtb",
217 false,
218 },
Stephen Warrenbe8efec2015-12-04 22:07:44 -0700219 [0x15] = {
Lubomir Rintelc87458c2015-10-14 17:17:54 +0200220 "Model A+",
221 "bcm2835-rpi-a-plus.dtb",
222 false,
223 },
Stephen Warrencd210c12014-11-18 21:40:21 -0700224};
225
Stephen Warren26683852015-12-04 22:07:45 -0700226static uint32_t revision;
227static uint32_t rev_scheme;
228static uint32_t rev_type;
229static const struct rpi_model *model;
Stephen Warrencd210c12014-11-18 21:40:21 -0700230
Stephen Warren0e012c32012-08-05 16:07:22 +0000231int dram_init(void)
232{
Alexander Steinc56c9472015-07-24 09:22:12 +0200233 ALLOC_CACHE_ALIGN_BUFFER(struct msg_get_arm_mem, msg, 1);
Stephen Warrenacc8bf42013-01-29 16:37:37 +0000234 int ret;
235
236 BCM2835_MBOX_INIT_HDR(msg);
237 BCM2835_MBOX_INIT_TAG(&msg->get_arm_mem, GET_ARM_MEMORY);
238
239 ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg->hdr);
240 if (ret) {
241 printf("bcm2835: Could not query ARM memory size\n");
242 return -1;
243 }
244
245 gd->ram_size = msg->get_arm_mem.body.resp.mem_size;
Stephen Warren0e012c32012-08-05 16:07:22 +0000246
247 return 0;
248}
249
Stephen Warrencd210c12014-11-18 21:40:21 -0700250static void set_fdtfile(void)
251{
252 const char *fdtfile;
253
254 if (getenv("fdtfile"))
255 return;
256
Stephen Warren26683852015-12-04 22:07:45 -0700257 fdtfile = model->fdtfile;
Stephen Warrencd210c12014-11-18 21:40:21 -0700258 setenv("fdtfile", fdtfile);
259}
260
261static void set_usbethaddr(void)
Stephen Warrenaf6e20d2014-09-26 20:51:39 -0600262{
Alexander Steinc56c9472015-07-24 09:22:12 +0200263 ALLOC_CACHE_ALIGN_BUFFER(struct msg_get_mac_address, msg, 1);
Stephen Warrenaf6e20d2014-09-26 20:51:39 -0600264 int ret;
265
Stephen Warren26683852015-12-04 22:07:45 -0700266 if (!model->has_onboard_eth)
Stephen Warrenb2fa38362014-12-05 20:56:46 -0700267 return;
268
Stephen Warrenaf6e20d2014-09-26 20:51:39 -0600269 if (getenv("usbethaddr"))
Stephen Warrencd210c12014-11-18 21:40:21 -0700270 return;
Stephen Warrenaf6e20d2014-09-26 20:51:39 -0600271
272 BCM2835_MBOX_INIT_HDR(msg);
273 BCM2835_MBOX_INIT_TAG(&msg->get_mac_address, GET_MAC_ADDRESS);
274
275 ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg->hdr);
276 if (ret) {
277 printf("bcm2835: Could not query MAC address\n");
278 /* Ignore error; not critical */
Stephen Warrencd210c12014-11-18 21:40:21 -0700279 return;
Stephen Warrenaf6e20d2014-09-26 20:51:39 -0600280 }
281
282 eth_setenv_enetaddr("usbethaddr", msg->get_mac_address.body.resp.mac);
283
Lubomir Rintel3ac09f82016-02-03 16:08:09 +0100284 if (!getenv("ethaddr"))
285 setenv("ethaddr", getenv("usbethaddr"));
286
Stephen Warrencd210c12014-11-18 21:40:21 -0700287 return;
288}
289
Guillaume GARDET25fa8602015-08-25 15:10:26 +0200290#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
291static void set_board_info(void)
292{
Stephen Warren26683852015-12-04 22:07:45 -0700293 char s[11];
294
295 snprintf(s, sizeof(s), "0x%X", revision);
296 setenv("board_revision", s);
297 snprintf(s, sizeof(s), "%d", rev_scheme);
298 setenv("board_rev_scheme", s);
299 /* Can't rename this to board_rev_type since it's an ABI for scripts */
300 snprintf(s, sizeof(s), "0x%X", rev_type);
301 setenv("board_rev", s);
302 setenv("board_name", model->name);
Guillaume GARDET25fa8602015-08-25 15:10:26 +0200303}
304#endif /* CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG */
305
Lubomir Rintel7d33bb62016-02-22 22:06:47 +0100306static void set_serial_number(void)
307{
308 ALLOC_CACHE_ALIGN_BUFFER(struct msg_get_board_serial, msg, 1);
309 int ret;
310 char serial_string[17] = { 0 };
311
312 if (getenv("serial#"))
313 return;
314
315 BCM2835_MBOX_INIT_HDR(msg);
316 BCM2835_MBOX_INIT_TAG_NO_REQ(&msg->get_board_serial, GET_BOARD_SERIAL);
317
318 ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg->hdr);
319 if (ret) {
320 printf("bcm2835: Could not query board serial\n");
321 /* Ignore error; not critical */
322 return;
323 }
324
325 snprintf(serial_string, sizeof(serial_string), "%016" PRIx64,
326 msg->get_board_serial.body.resp.serial);
327 setenv("serial#", serial_string);
328}
329
Stephen Warrencd210c12014-11-18 21:40:21 -0700330int misc_init_r(void)
331{
332 set_fdtfile();
333 set_usbethaddr();
Guillaume GARDET25fa8602015-08-25 15:10:26 +0200334#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
335 set_board_info();
336#endif
Lubomir Rintel7d33bb62016-02-22 22:06:47 +0100337 set_serial_number();
338
Stephen Warrenaf6e20d2014-09-26 20:51:39 -0600339 return 0;
340}
341
Stephen Warren8672d202014-01-13 19:50:11 -0700342static int power_on_module(u32 module)
343{
Alexander Steinc56c9472015-07-24 09:22:12 +0200344 ALLOC_CACHE_ALIGN_BUFFER(struct msg_set_power_state, msg_pwr, 1);
Stephen Warren8672d202014-01-13 19:50:11 -0700345 int ret;
346
347 BCM2835_MBOX_INIT_HDR(msg_pwr);
348 BCM2835_MBOX_INIT_TAG(&msg_pwr->set_power_state,
349 SET_POWER_STATE);
350 msg_pwr->set_power_state.body.req.device_id = module;
351 msg_pwr->set_power_state.body.req.state =
352 BCM2835_MBOX_SET_POWER_STATE_REQ_ON |
353 BCM2835_MBOX_SET_POWER_STATE_REQ_WAIT;
354
355 ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN,
356 &msg_pwr->hdr);
357 if (ret) {
358 printf("bcm2835: Could not set module %u power state\n",
359 module);
360 return -1;
361 }
362
363 return 0;
364}
365
Stephen Warrencd210c12014-11-18 21:40:21 -0700366static void get_board_rev(void)
367{
Alexander Steinc56c9472015-07-24 09:22:12 +0200368 ALLOC_CACHE_ALIGN_BUFFER(struct msg_get_board_rev, msg, 1);
Stephen Warrencd210c12014-11-18 21:40:21 -0700369 int ret;
Stephen Warren26683852015-12-04 22:07:45 -0700370 const struct rpi_model *models;
371 uint32_t models_count;
Stephen Warrencd210c12014-11-18 21:40:21 -0700372
373 BCM2835_MBOX_INIT_HDR(msg);
374 BCM2835_MBOX_INIT_TAG(&msg->get_board_rev, GET_BOARD_REV);
375
376 ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg->hdr);
377 if (ret) {
378 printf("bcm2835: Could not query board revision\n");
379 /* Ignore error; not critical */
380 return;
381 }
382
Stephen Warrendc7ea682015-02-16 12:16:15 -0700383 /*
384 * For details of old-vs-new scheme, see:
385 * https://github.com/pimoroni/RPi.version/blob/master/RPi/version.py
386 * http://www.raspberrypi.org/forums/viewtopic.php?f=63&t=99293&p=690282
387 * (a few posts down)
Stephen Warrenb834af82015-03-23 23:00:25 -0600388 *
389 * For the RPi 1, bit 24 is the "warranty bit", so we mask off just the
390 * lower byte to use as the board rev:
391 * http://www.raspberrypi.org/forums/viewtopic.php?f=63&t=98367&start=250
392 * http://www.raspberrypi.org/forums/viewtopic.php?f=31&t=20594
Stephen Warrendc7ea682015-02-16 12:16:15 -0700393 */
Stephen Warren26683852015-12-04 22:07:45 -0700394 revision = msg->get_board_rev.body.resp.rev;
395 if (revision & 0x800000) {
396 rev_scheme = 1;
397 rev_type = (revision >> 4) & 0xff;
398 models = rpi_models_new_scheme;
399 models_count = ARRAY_SIZE(rpi_models_new_scheme);
400 } else {
401 rev_scheme = 0;
402 rev_type = revision & 0xff;
403 models = rpi_models_old_scheme;
404 models_count = ARRAY_SIZE(rpi_models_old_scheme);
Stephen Warren18a5fc62014-12-23 20:01:43 -0700405 }
Stephen Warren26683852015-12-04 22:07:45 -0700406 if (rev_type >= models_count) {
407 printf("RPI: Board rev 0x%x outside known range\n", rev_type);
408 model = &rpi_model_unknown;
409 } else if (!models[rev_type].name) {
410 printf("RPI: Board rev 0x%x unknown\n", rev_type);
411 model = &rpi_model_unknown;
412 } else {
413 model = &models[rev_type];
Stephen Warren18a5fc62014-12-23 20:01:43 -0700414 }
Stephen Warrenc61dfd12014-12-23 20:01:44 -0700415
Stephen Warren26683852015-12-04 22:07:45 -0700416 printf("RPI %s (0x%x)\n", model->name, revision);
Stephen Warrencd210c12014-11-18 21:40:21 -0700417}
418
Stephen Warren0e012c32012-08-05 16:07:22 +0000419int board_init(void)
420{
Stephen Warrencd210c12014-11-18 21:40:21 -0700421 get_board_rev();
422
Stephen Warren0e012c32012-08-05 16:07:22 +0000423 gd->bd->bi_boot_params = 0x100;
424
Stephen Warren8672d202014-01-13 19:50:11 -0700425 return power_on_module(BCM2835_MBOX_POWER_DEVID_USB_HCD);
Stephen Warren0e012c32012-08-05 16:07:22 +0000426}
Stephen Warrenc4ab9712013-01-29 16:37:42 +0000427
Jeroen Hofsteed5b2fed2014-07-13 22:01:51 +0200428int board_mmc_init(bd_t *bis)
Stephen Warrenc4ab9712013-01-29 16:37:42 +0000429{
Alexander Steinc56c9472015-07-24 09:22:12 +0200430 ALLOC_CACHE_ALIGN_BUFFER(struct msg_get_clock_rate, msg_clk, 1);
Stephen Warrenc4ab9712013-01-29 16:37:42 +0000431 int ret;
432
Stephen Warren8672d202014-01-13 19:50:11 -0700433 power_on_module(BCM2835_MBOX_POWER_DEVID_SDHCI);
434
Stephen Warrenc4ab9712013-01-29 16:37:42 +0000435 BCM2835_MBOX_INIT_HDR(msg_clk);
436 BCM2835_MBOX_INIT_TAG(&msg_clk->get_clock_rate, GET_CLOCK_RATE);
437 msg_clk->get_clock_rate.body.req.clock_id = BCM2835_MBOX_CLOCK_ID_EMMC;
438
439 ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg_clk->hdr);
440 if (ret) {
441 printf("bcm2835: Could not query eMMC clock rate\n");
442 return -1;
443 }
444
445 return bcm2835_sdhci_init(BCM2835_SDHCI_BASE,
446 msg_clk->get_clock_rate.body.resp.rate_hz);
447}
Stephen Warrenaa44d532013-05-27 18:31:18 +0000448
Simon Glass2aec3cc2014-10-23 18:58:47 -0600449int ft_board_setup(void *blob, bd_t *bd)
Stephen Warrenaa44d532013-05-27 18:31:18 +0000450{
451 /*
452 * For now, we simply always add the simplefb DT node. Later, we
453 * should be more intelligent, and e.g. only do this if no enabled DT
454 * node exists for the "real" graphics driver.
455 */
456 lcd_dt_simplefb_add_node(blob);
Simon Glass2aec3cc2014-10-23 18:58:47 -0600457
458 return 0;
Stephen Warrenaa44d532013-05-27 18:31:18 +0000459}