mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-10 23:24:38 +00:00
ARM: rpi_b: detect board revision
Detect the board revision early during boot, and print the decoded model name. Eventually, this information can be used for tasks such as: - Allowing/preventing USB device mode; some models have a USB device on- board so only host mode makes sense. Others connect the SoC directly to the USB connector, so device-mode might make sense. - The on-board USB hub/Ethernet requires different GPIOs to enable it, although luckily the default appears to be fine so far. - The compute module contains an on-board eMMC device, so we could store the environment there. Other models use an SD card and so don't support saving the environment (unless we store it in a file on the FAT boot partition...) Set $fdtfile based on this information. At present, the mainline Linux kernel doesn't contain a separate DTB for most models, but I hope that will change soon. Signed-off-by: Stephen Warren <swarren@wwwdotorg.org> Reviewed-by: Simon Glass <sjg@chromium.org> Tested-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
4c5bbc2328
commit
6fe7845a98
3 changed files with 152 additions and 4 deletions
|
@ -119,6 +119,39 @@ struct bcm2835_mbox_tag_hdr {
|
|||
* };
|
||||
*/
|
||||
|
||||
#define BCM2835_MBOX_TAG_GET_BOARD_REV 0x00010002
|
||||
|
||||
/*
|
||||
* 0x2..0xf from:
|
||||
* http://raspberryalphaomega.org.uk/2013/02/06/automatic-raspberry-pi-board-revision-detection-model-a-b1-and-b2/
|
||||
* http://www.raspberrypi.org/forums/viewtopic.php?f=63&t=32733
|
||||
* 0x10, 0x11 from swarren's testing
|
||||
*/
|
||||
#define BCM2835_BOARD_REV_B_I2C0_2 0x2
|
||||
#define BCM2835_BOARD_REV_B_I2C0_3 0x3
|
||||
#define BCM2835_BOARD_REV_B_I2C1_4 0x4
|
||||
#define BCM2835_BOARD_REV_B_I2C1_5 0x5
|
||||
#define BCM2835_BOARD_REV_B_I2C1_6 0x6
|
||||
#define BCM2835_BOARD_REV_A_7 0x7
|
||||
#define BCM2835_BOARD_REV_A_8 0x8
|
||||
#define BCM2835_BOARD_REV_A_9 0x9
|
||||
#define BCM2835_BOARD_REV_B_REV2_d 0xd
|
||||
#define BCM2835_BOARD_REV_B_REV2_e 0xe
|
||||
#define BCM2835_BOARD_REV_B_REV2_f 0xf
|
||||
#define BCM2835_BOARD_REV_B_PLUS 0x10
|
||||
#define BCM2835_BOARD_REV_CM 0x11
|
||||
|
||||
struct bcm2835_mbox_tag_get_board_rev {
|
||||
struct bcm2835_mbox_tag_hdr tag_hdr;
|
||||
union {
|
||||
struct {
|
||||
} req;
|
||||
struct {
|
||||
u32 rev;
|
||||
} resp;
|
||||
} body;
|
||||
};
|
||||
|
||||
#define BCM2835_MBOX_TAG_GET_MAC_ADDRESS 0x00010003
|
||||
|
||||
struct bcm2835_mbox_tag_get_mac_address {
|
||||
|
|
|
@ -42,6 +42,12 @@ struct msg_get_arm_mem {
|
|||
u32 end_tag;
|
||||
};
|
||||
|
||||
struct msg_get_board_rev {
|
||||
struct bcm2835_mbox_hdr hdr;
|
||||
struct bcm2835_mbox_tag_get_board_rev get_board_rev;
|
||||
u32 end_tag;
|
||||
};
|
||||
|
||||
struct msg_get_mac_address {
|
||||
struct bcm2835_mbox_hdr hdr;
|
||||
struct bcm2835_mbox_tag_get_mac_address get_mac_address;
|
||||
|
@ -60,6 +66,67 @@ struct msg_get_clock_rate {
|
|||
u32 end_tag;
|
||||
};
|
||||
|
||||
/* See comments in mbox.h for data source */
|
||||
static const struct {
|
||||
const char *name;
|
||||
const char *fdtfile;
|
||||
} models[] = {
|
||||
[BCM2835_BOARD_REV_B_I2C0_2] = {
|
||||
"Model B (no P5)",
|
||||
"bcm2835-rpi-b-i2c0.dtb",
|
||||
},
|
||||
[BCM2835_BOARD_REV_B_I2C0_3] = {
|
||||
"Model B (no P5)",
|
||||
"bcm2835-rpi-b-i2c0.dtb",
|
||||
},
|
||||
[BCM2835_BOARD_REV_B_I2C1_4] = {
|
||||
"Model B",
|
||||
"bcm2835-rpi-b.dtb",
|
||||
},
|
||||
[BCM2835_BOARD_REV_B_I2C1_5] = {
|
||||
"Model B",
|
||||
"bcm2835-rpi-b.dtb",
|
||||
},
|
||||
[BCM2835_BOARD_REV_B_I2C1_6] = {
|
||||
"Model B",
|
||||
"bcm2835-rpi-b.dtb",
|
||||
},
|
||||
[BCM2835_BOARD_REV_A_7] = {
|
||||
"Model A",
|
||||
"bcm2835-rpi-a.dtb",
|
||||
},
|
||||
[BCM2835_BOARD_REV_A_8] = {
|
||||
"Model A",
|
||||
"bcm2835-rpi-a.dtb",
|
||||
},
|
||||
[BCM2835_BOARD_REV_A_9] = {
|
||||
"Model A",
|
||||
"bcm2835-rpi-a.dtb",
|
||||
},
|
||||
[BCM2835_BOARD_REV_B_REV2_d] = {
|
||||
"Model B rev2",
|
||||
"bcm2835-rpi-b-rev2.dtb",
|
||||
},
|
||||
[BCM2835_BOARD_REV_B_REV2_e] = {
|
||||
"Model B rev2",
|
||||
"bcm2835-rpi-b-rev2.dtb",
|
||||
},
|
||||
[BCM2835_BOARD_REV_B_REV2_f] = {
|
||||
"Model B rev2",
|
||||
"bcm2835-rpi-b-rev2.dtb",
|
||||
},
|
||||
[BCM2835_BOARD_REV_B_PLUS] = {
|
||||
"Model B+",
|
||||
"bcm2835-rpi-b-plus.dtb",
|
||||
},
|
||||
[BCM2835_BOARD_REV_CM] = {
|
||||
"Compute Module",
|
||||
"bcm2835-rpi-cm.dtb",
|
||||
},
|
||||
};
|
||||
|
||||
u32 rpi_board_rev = 0;
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
ALLOC_ALIGN_BUFFER(struct msg_get_arm_mem, msg, 1, 16);
|
||||
|
@ -79,13 +146,27 @@ int dram_init(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int misc_init_r(void)
|
||||
static void set_fdtfile(void)
|
||||
{
|
||||
const char *fdtfile;
|
||||
|
||||
if (getenv("fdtfile"))
|
||||
return;
|
||||
|
||||
fdtfile = models[rpi_board_rev].fdtfile;
|
||||
if (!fdtfile)
|
||||
fdtfile = "bcm2835-rpi-other.dtb";
|
||||
|
||||
setenv("fdtfile", fdtfile);
|
||||
}
|
||||
|
||||
static void set_usbethaddr(void)
|
||||
{
|
||||
ALLOC_ALIGN_BUFFER(struct msg_get_mac_address, msg, 1, 16);
|
||||
int ret;
|
||||
|
||||
if (getenv("usbethaddr"))
|
||||
return 0;
|
||||
return;
|
||||
|
||||
BCM2835_MBOX_INIT_HDR(msg);
|
||||
BCM2835_MBOX_INIT_TAG(&msg->get_mac_address, GET_MAC_ADDRESS);
|
||||
|
@ -94,11 +175,18 @@ int misc_init_r(void)
|
|||
if (ret) {
|
||||
printf("bcm2835: Could not query MAC address\n");
|
||||
/* Ignore error; not critical */
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
eth_setenv_enetaddr("usbethaddr", msg->get_mac_address.body.resp.mac);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int misc_init_r(void)
|
||||
{
|
||||
set_fdtfile();
|
||||
set_usbethaddr();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -126,8 +214,36 @@ static int power_on_module(u32 module)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void get_board_rev(void)
|
||||
{
|
||||
ALLOC_ALIGN_BUFFER(struct msg_get_board_rev, msg, 1, 16);
|
||||
int ret;
|
||||
const char *name;
|
||||
|
||||
BCM2835_MBOX_INIT_HDR(msg);
|
||||
BCM2835_MBOX_INIT_TAG(&msg->get_board_rev, GET_BOARD_REV);
|
||||
|
||||
ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg->hdr);
|
||||
if (ret) {
|
||||
printf("bcm2835: Could not query board revision\n");
|
||||
/* Ignore error; not critical */
|
||||
return;
|
||||
}
|
||||
|
||||
rpi_board_rev = msg->get_board_rev.body.resp.rev;
|
||||
if (rpi_board_rev >= ARRAY_SIZE(models))
|
||||
rpi_board_rev = 0;
|
||||
|
||||
name = models[rpi_board_rev].name;
|
||||
if (!name)
|
||||
name = "Unknown model";
|
||||
printf("RPI model: %s\n", name);
|
||||
}
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
get_board_rev();
|
||||
|
||||
gd->bd->bi_boot_params = 0x100;
|
||||
|
||||
return power_on_module(BCM2835_MBOX_POWER_DEVID_USB_HCD);
|
||||
|
|
|
@ -175,7 +175,6 @@
|
|||
"pxefile_addr_r=0x00100000\0" \
|
||||
"kernel_addr_r=0x01000000\0" \
|
||||
"fdt_addr_r=0x02000000\0" \
|
||||
"fdtfile=bcm2835-rpi-b.dtb\0" \
|
||||
"ramdisk_addr_r=0x02100000\0" \
|
||||
|
||||
#define BOOT_TARGET_DEVICES(func) \
|
||||
|
|
Loading…
Reference in a new issue