Add RaspberryPi5 basic support.

-----BEGIN PGP SIGNATURE-----
 
 iQJLBAABCAA1FiEEUdvKHhzqrUYPB/u8L21+TfbCqH4FAmW6e1wXHG1hdHRoaWFz
 LmJnZ0BnbWFpbC5jb20ACgkQL21+TfbCqH52xQ/8CFn5pp17a8hmC7Y/sCxTcG72
 HpgKgvmPDk859riCmwzGFQOzs4adOHP4q46xnh6t1Rx9oHWIqHfw9dadtT2yarIp
 NS57vpYWzl4KNmM3fsMIbt1KuuR+uczOq5kBnefI8SDLX1XE94Eo1pbaTyKWP967
 g3bE1M/ifdbduKbi+X0d0rocbc6EtTLOeaUVsSzP/6bYI7ky4TT8KUMXpeCnfOXe
 539+8AJhncVoY/ewVnEypAY3EFmQedol9mMAYSAR4RTUIsMMt+fjD7RMKy5ZUylF
 GDa26CKo79bUvrrjdafGP8Jywd/+t8LZgNwWsISvsMTDwE72whuUikOr4z+MnMaG
 ATWTpmW7sSnTnjASWpG1cgFwxsGu1u5Ylj2KemEL+HzTz5uVfOZnuW6OvNmVDZLV
 fcCH6tmbiCh0OaLwCYeyAQRfozrWatVwvB6eq2VrPvHeqgL9ulCFLoSeENsl63VV
 6imoFZlisUDK/9VEBMrAxnVYxgwf0unKgSQX5fpvX7olt66I4XDQiNwd/fjzZRhE
 vM62hO+vKGicHmdN2sxeU+0G04+4kBMZtHRMa+Jusvk7BAOesX5cgKWoJ/bLzW5d
 BveXcvvbQV3lqC7zS5WX8TvgaNQiPeyAuDn1hNNk22fMPhL5v2fevm2H9RCoF1fg
 w//cffQwFnxtM6rKz5g=
 =9V5z
 -----END PGP SIGNATURE-----

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>
This commit is contained in:
Tom Rini 2024-02-05 09:31:48 -05:00
commit 090d8463b0
10 changed files with 171 additions and 27 deletions

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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)

View File

@ -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];

View File

@ -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;
}

View File

@ -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;

View File

@ -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

View File

@ -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" },
{ }

View File

@ -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;