mirror of
https://github.com/u-boot/u-boot.git
synced 2024-12-04 10:03:41 +08:00
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:
commit
090d8463b0
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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];
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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" },
|
||||
{ }
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user