aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2024-02-05 09:31:48 -0500
committerTom Rini <trini@konsulko.com>2024-02-05 09:31:48 -0500
commit090d8463b07c9c48f76f3cd14cf0e4bb8f884825 (patch)
tree37dba40481cf3af41ceeeeccfbebf3b3d6b3f99f
parent819abd0a1eaff9a921f5b917e152b85dab302e33 (diff)
parent12d479d01849c164020e17c3ae921f974b96372d (diff)
downloadu-boot-090d8463b07c9c48f76f3cd14cf0e4bb8f884825.zip
u-boot-090d8463b07c9c48f76f3cd14cf0e4bb8f884825.tar.gz
u-boot-090d8463b07c9c48f76f3cd14cf0e4bb8f884825.tar.bz2
Merge tag 'rpi-next-2024.04' of https://source.denx.de/u-boot/custodians/u-boot-raspberrypi
Add RaspberryPi5 basic support. Acked-by: Peter Robinson <pbrobinson@gmail.com>
-rw-r--r--arch/arm/mach-bcm283x/include/mach/base.h5
-rw-r--r--arch/arm/mach-bcm283x/include/mach/mbox.h3
-rw-r--r--arch/arm/mach-bcm283x/include/mach/sdhci.h3
-rw-r--r--arch/arm/mach-bcm283x/include/mach/timer.h3
-rw-r--r--arch/arm/mach-bcm283x/include/mach/wdog.h3
-rw-r--r--arch/arm/mach-bcm283x/init.c74
-rw-r--r--board/raspberrypi/rpi/rpi.c22
-rw-r--r--configs/rpi_arm64_defconfig3
-rw-r--r--drivers/mmc/bcmstb_sdhci.c64
-rw-r--r--drivers/video/bcm2835.c18
10 files changed, 171 insertions, 27 deletions
diff --git a/arch/arm/mach-bcm283x/include/mach/base.h b/arch/arm/mach-bcm283x/include/mach/base.h
index 4ccaf69..6de99e7 100644
--- a/arch/arm/mach-bcm283x/include/mach/base.h
+++ b/arch/arm/mach-bcm283x/include/mach/base.h
@@ -6,7 +6,10 @@
#ifndef _BCM283x_BASE_H_
#define _BCM283x_BASE_H_
-extern unsigned long rpi_bcm283x_base;
+extern unsigned long rpi_mbox_base;
+extern unsigned long rpi_timer_base;
+extern unsigned long rpi_sdhci_base;
+extern unsigned long rpi_wdog_base;
#ifdef CONFIG_ARMV7_LPAE
#ifdef CONFIG_TARGET_RPI_4_32B
diff --git a/arch/arm/mach-bcm283x/include/mach/mbox.h b/arch/arm/mach-bcm283x/include/mach/mbox.h
index 490664f..35d4e2f 100644
--- a/arch/arm/mach-bcm283x/include/mach/mbox.h
+++ b/arch/arm/mach-bcm283x/include/mach/mbox.h
@@ -38,8 +38,7 @@
/* Raw mailbox HW */
-#define BCM2835_MBOX_PHYSADDR ({ BUG_ON(!rpi_bcm283x_base); \
- rpi_bcm283x_base + 0x0000b880; })
+#define BCM2835_MBOX_PHYSADDR rpi_mbox_base
struct bcm2835_mbox_regs {
u32 read;
diff --git a/arch/arm/mach-bcm283x/include/mach/sdhci.h b/arch/arm/mach-bcm283x/include/mach/sdhci.h
index 7323690..e837c67 100644
--- a/arch/arm/mach-bcm283x/include/mach/sdhci.h
+++ b/arch/arm/mach-bcm283x/include/mach/sdhci.h
@@ -8,8 +8,7 @@
#include <asm/arch/base.h>
-#define BCM2835_SDHCI_PHYSADDR ({ BUG_ON(!rpi_bcm283x_base); \
- rpi_bcm283x_base + 0x00300000; })
+#define BCM2835_SDHCI_PHYSADDR rpi_sdhci_base
int bcm2835_sdhci_init(u32 regbase, u32 emmc_freq);
diff --git a/arch/arm/mach-bcm283x/include/mach/timer.h b/arch/arm/mach-bcm283x/include/mach/timer.h
index 5567dbd..60500a2 100644
--- a/arch/arm/mach-bcm283x/include/mach/timer.h
+++ b/arch/arm/mach-bcm283x/include/mach/timer.h
@@ -11,8 +11,7 @@
#include <linux/bug.h>
#endif
-#define BCM2835_TIMER_PHYSADDR ({ BUG_ON(!rpi_bcm283x_base); \
- rpi_bcm283x_base + 0x00003000; })
+#define BCM2835_TIMER_PHYSADDR rpi_timer_base
#define BCM2835_TIMER_CS_M3 (1 << 3)
#define BCM2835_TIMER_CS_M2 (1 << 2)
diff --git a/arch/arm/mach-bcm283x/include/mach/wdog.h b/arch/arm/mach-bcm283x/include/mach/wdog.h
index 9942666..b950560 100644
--- a/arch/arm/mach-bcm283x/include/mach/wdog.h
+++ b/arch/arm/mach-bcm283x/include/mach/wdog.h
@@ -8,8 +8,7 @@
#include <asm/arch/base.h>
-#define BCM2835_WDOG_PHYSADDR ({ BUG_ON(!rpi_bcm283x_base); \
- rpi_bcm283x_base + 0x00100000; })
+#define BCM2835_WDOG_PHYSADDR rpi_wdog_base
struct bcm2835_wdog_regs {
u32 unknown0[7];
diff --git a/arch/arm/mach-bcm283x/init.c b/arch/arm/mach-bcm283x/init.c
index 7265faf..016bc1e 100644
--- a/arch/arm/mach-bcm283x/init.c
+++ b/arch/arm/mach-bcm283x/init.c
@@ -68,6 +68,36 @@ static struct mm_region bcm2711_mem_map[MEM_MAP_MAX_ENTRIES] = {
}
};
+static struct mm_region bcm2712_mem_map[MEM_MAP_MAX_ENTRIES] = {
+ {
+ /* First 1GB of DRAM */
+ .virt = 0x00000000UL,
+ .phys = 0x00000000UL,
+ .size = 0x40000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_INNER_SHARE
+ }, {
+ /* Beginning of AXI bus where uSD controller lives */
+ .virt = 0x1000000000UL,
+ .phys = 0x1000000000UL,
+ .size = 0x0002000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ }, {
+ /* SoC bus */
+ .virt = 0x107c000000UL,
+ .phys = 0x107c000000UL,
+ .size = 0x0004000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ }, {
+ /* List terminator */
+ 0,
+ }
+};
+
struct mm_region *mem_map = bcm283x_mem_map;
/*
@@ -78,6 +108,7 @@ static const struct udevice_id board_ids[] = {
{ .compatible = "brcm,bcm2837", .data = (ulong)&bcm283x_mem_map},
{ .compatible = "brcm,bcm2838", .data = (ulong)&bcm2711_mem_map},
{ .compatible = "brcm,bcm2711", .data = (ulong)&bcm2711_mem_map},
+ { .compatible = "brcm,bcm2712", .data = (ulong)&bcm2712_mem_map},
{ },
};
@@ -115,7 +146,11 @@ static void rpi_update_mem_map(void)
static void rpi_update_mem_map(void) {}
#endif
-unsigned long rpi_bcm283x_base = 0x3f000000;
+/* Default bcm283x devices addresses */
+unsigned long rpi_mbox_base = 0x3f00b880;
+unsigned long rpi_sdhci_base = 0x3f300000;
+unsigned long rpi_wdog_base = 0x3f100000;
+unsigned long rpi_timer_base = 0x3f003000;
int arch_cpu_init(void)
{
@@ -126,22 +161,45 @@ int arch_cpu_init(void)
int mach_cpu_init(void)
{
- int ret, soc_offset;
+ int ret, soc, offset;
u64 io_base, size;
rpi_update_mem_map();
/* Get IO base from device tree */
- soc_offset = fdt_path_offset(gd->fdt_blob, "/soc");
- if (soc_offset < 0)
- return soc_offset;
+ soc = fdt_path_offset(gd->fdt_blob, "/soc");
+ if (soc < 0)
+ return soc;
- ret = fdt_read_range((void *)gd->fdt_blob, soc_offset, 0, NULL,
- &io_base, &size);
+ ret = fdt_read_range((void *)gd->fdt_blob, soc, 0, NULL,
+ &io_base, &size);
if (ret)
return ret;
- rpi_bcm283x_base = io_base;
+ rpi_mbox_base = io_base + 0x00b880;
+ rpi_sdhci_base = io_base + 0x300000;
+ rpi_wdog_base = io_base + 0x100000;
+ rpi_timer_base = io_base + 0x003000;
+
+ offset = fdt_node_offset_by_compatible(gd->fdt_blob, soc,
+ "brcm,bcm2835-mbox");
+ if (offset > soc)
+ rpi_mbox_base = fdt_get_base_address(gd->fdt_blob, offset);
+
+ offset = fdt_node_offset_by_compatible(gd->fdt_blob, soc,
+ "brcm,bcm2835-sdhci");
+ if (offset > soc)
+ rpi_sdhci_base = fdt_get_base_address(gd->fdt_blob, offset);
+
+ offset = fdt_node_offset_by_compatible(gd->fdt_blob, soc,
+ "brcm,bcm2835-system-timer");
+ if (offset > soc)
+ rpi_timer_base = fdt_get_base_address(gd->fdt_blob, offset);
+
+ offset = fdt_node_offset_by_compatible(gd->fdt_blob, soc,
+ "brcm,bcm2712-pm");
+ if (offset > soc)
+ rpi_wdog_base = fdt_get_base_address(gd->fdt_blob, offset);
return 0;
}
diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c
index cd823ad..2851ebc 100644
--- a/board/raspberrypi/rpi/rpi.c
+++ b/board/raspberrypi/rpi/rpi.c
@@ -171,6 +171,11 @@ static const struct rpi_model rpi_models_new_scheme[] = {
DTB_DIR "bcm2711-rpi-cm4.dtb",
true,
},
+ [0x17] = {
+ "5 Model B",
+ DTB_DIR "bcm2712-rpi-5-b.dtb",
+ true,
+ },
};
static const struct rpi_model rpi_models_old_scheme[] = {
@@ -429,15 +434,27 @@ static void get_board_revision(void)
int ret;
const struct rpi_model *models;
uint32_t models_count;
+ ofnode node;
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;
+ node = ofnode_path("/system");
+ if (!ofnode_valid(node)) {
+ printf("bcm2835: Could not find /system node\n");
+ return;
+ }
+
+ ret = ofnode_read_u32(node, "linux,revision", &revision);
+ if (ret) {
+ printf("bcm2835: Could not find linux,revision\n");
+ return;
+ }
+ } else {
+ revision = msg->get_board_rev.body.resp.rev;
}
/*
@@ -451,7 +468,6 @@ static void get_board_revision(void)
* http://www.raspberrypi.org/forums/viewtopic.php?f=63&t=98367&start=250
* http://www.raspberrypi.org/forums/viewtopic.php?f=31&t=20594
*/
- revision = msg->get_board_rev.body.resp.rev;
if (revision & 0x800000) {
rev_scheme = 1;
rev_type = (revision >> 4) & 0xff;
diff --git a/configs/rpi_arm64_defconfig b/configs/rpi_arm64_defconfig
index 08bb30b..e4c4aef 100644
--- a/configs/rpi_arm64_defconfig
+++ b/configs/rpi_arm64_defconfig
@@ -1,6 +1,6 @@
CONFIG_ARM=y
CONFIG_ARCH_BCM283X=y
-CONFIG_TEXT_BASE=0x00080000
+CONFIG_POSITION_INDEPENDENT=y
CONFIG_TARGET_RPI_ARM64=y
CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x7fffe30
@@ -33,6 +33,7 @@ CONFIG_BCM2835_GPIO=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_SDMA=y
CONFIG_MMC_SDHCI_BCM2835=y
+CONFIG_MMC_SDHCI_BCMSTB=y
CONFIG_BCMGENET=y
CONFIG_PCI_BRCMSTB=y
CONFIG_PINCTRL=y
diff --git a/drivers/mmc/bcmstb_sdhci.c b/drivers/mmc/bcmstb_sdhci.c
index dc96818..49846ad 100644
--- a/drivers/mmc/bcmstb_sdhci.c
+++ b/drivers/mmc/bcmstb_sdhci.c
@@ -38,15 +38,52 @@
*/
#define BCMSTB_SDHCI_MINIMUM_CLOCK_FREQUENCY 400000
-/*
- * This driver has only been tested with eMMC devices; SD devices may
- * not work.
- */
+#define SDIO_CFG_CTRL 0x0
+#define SDIO_CFG_CTRL_SDCD_N_TEST_EN BIT(31)
+#define SDIO_CFG_CTRL_SDCD_N_TEST_LEV BIT(30)
+
+#define SDIO_CFG_SD_PIN_SEL 0x44
+#define SDIO_CFG_SD_PIN_SEL_MASK 0x3
+#define SDIO_CFG_SD_PIN_SEL_CARD BIT(1)
+
struct sdhci_bcmstb_plat {
struct mmc_config cfg;
struct mmc mmc;
};
+struct sdhci_brcmstb_dev_priv {
+ int (*init)(struct udevice *dev);
+};
+
+static int sdhci_brcmstb_init_2712(struct udevice *dev)
+{
+ struct sdhci_host *host = dev_get_priv(dev);
+ void *cfg_regs;
+ u32 reg;
+
+ /* Map in the non-standard CFG registers */
+ cfg_regs = dev_remap_addr_name(dev, "cfg");
+ if (!cfg_regs)
+ return -ENOENT;
+
+ if ((host->mmc->host_caps & MMC_CAP_NONREMOVABLE) ||
+ (host->mmc->host_caps & MMC_CAP_NEEDS_POLL)) {
+ /* Force presence */
+ reg = readl(cfg_regs + SDIO_CFG_CTRL);
+ reg &= ~SDIO_CFG_CTRL_SDCD_N_TEST_LEV;
+ reg |= SDIO_CFG_CTRL_SDCD_N_TEST_EN;
+ writel(reg, cfg_regs + SDIO_CFG_CTRL);
+ } else {
+ /* Enable card detection line */
+ reg = readl(cfg_regs + SDIO_CFG_SD_PIN_SEL);
+ reg &= ~SDIO_CFG_SD_PIN_SEL_MASK;
+ reg |= SDIO_CFG_SD_PIN_SEL_CARD;
+ writel(reg, cfg_regs + SDIO_CFG_SD_PIN_SEL);
+ }
+
+ return 0;
+}
+
static int sdhci_bcmstb_bind(struct udevice *dev)
{
struct sdhci_bcmstb_plat *plat = dev_get_plat(dev);
@@ -54,14 +91,20 @@ static int sdhci_bcmstb_bind(struct udevice *dev)
return sdhci_bind(dev, &plat->mmc, &plat->cfg);
}
+/* No specific SDHCI operations are required */
+static const struct sdhci_ops bcmstb_sdhci_ops = { 0 };
+
static int sdhci_bcmstb_probe(struct udevice *dev)
{
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
struct sdhci_bcmstb_plat *plat = dev_get_plat(dev);
struct sdhci_host *host = dev_get_priv(dev);
+ struct sdhci_brcmstb_dev_priv *dev_priv;
fdt_addr_t base;
int ret;
+ dev_priv = (struct sdhci_brcmstb_dev_priv *)dev_get_driver_data(dev);
+
base = dev_read_addr(dev);
if (base == FDT_ADDR_T_NONE)
return -EINVAL;
@@ -75,6 +118,8 @@ static int sdhci_bcmstb_probe(struct udevice *dev)
host->mmc = &plat->mmc;
host->mmc->dev = dev;
+ host->ops = &bcmstb_sdhci_ops;
+
ret = sdhci_setup_cfg(&plat->cfg, host,
BCMSTB_SDHCI_MAXIMUM_CLOCK_FREQUENCY,
BCMSTB_SDHCI_MINIMUM_CLOCK_FREQUENCY);
@@ -84,10 +129,21 @@ static int sdhci_bcmstb_probe(struct udevice *dev)
upriv->mmc = &plat->mmc;
host->mmc->priv = host;
+ if (dev_priv && dev_priv->init) {
+ ret = dev_priv->init(dev);
+ if (ret)
+ return ret;
+ }
+
return sdhci_probe(dev);
}
+static const struct sdhci_brcmstb_dev_priv match_priv_2712 = {
+ .init = sdhci_brcmstb_init_2712,
+};
+
static const struct udevice_id sdhci_bcmstb_match[] = {
+ { .compatible = "brcm,bcm2712-sdhci", .data = (ulong)&match_priv_2712 },
{ .compatible = "brcm,bcm7425-sdhci" },
{ .compatible = "brcm,sdhci-brcmstb" },
{ }
diff --git a/drivers/video/bcm2835.c b/drivers/video/bcm2835.c
index 1494252..63efa76 100644
--- a/drivers/video/bcm2835.c
+++ b/drivers/video/bcm2835.c
@@ -16,7 +16,7 @@ static int bcm2835_video_probe(struct udevice *dev)
struct video_uc_plat *plat = dev_get_uclass_plat(dev);
struct video_priv *uc_priv = dev_get_uclass_priv(dev);
int ret;
- int w, h, pitch;
+ int w, h, pitch, bpp;
ulong fb_base, fb_size, fb_start, fb_end;
debug("bcm2835: Query resolution...\n");
@@ -41,9 +41,23 @@ static int bcm2835_video_probe(struct udevice *dev)
DCACHE_WRITEBACK);
video_set_flush_dcache(dev, true);
+ bpp = pitch / w;
+ switch (bpp) {
+ case 2:
+ uc_priv->bpix = VIDEO_BPP16;
+ break;
+ case 4:
+ uc_priv->bpix = VIDEO_BPP32;
+ break;
+ default:
+ printf("bcm2835: unexpected bpp %d, pitch %d, width %d\n",
+ bpp, pitch, w);
+ uc_priv->bpix = VIDEO_BPP32;
+ break;
+ }
+
uc_priv->xsize = w;
uc_priv->ysize = h;
- uc_priv->bpix = VIDEO_BPP32;
plat->base = fb_base;
plat->size = fb_size;