* };
  */
 
+#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 {
 
        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;
        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);
        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);
        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;
 }
 
        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);