Skip to content
This repository has been archived by the owner on Jan 31, 2021. It is now read-only.

Commit

Permalink
WIP: RPi 3 (32-bit) port
Browse files Browse the repository at this point in the history
FIXME:
- split up into n patches
- describe

Signed-off-by: Stephen Warren <[email protected]>
  • Loading branch information
swarren committed Mar 6, 2016
1 parent 8d505c1 commit 202d830
Show file tree
Hide file tree
Showing 18 changed files with 297 additions and 11 deletions.
6 changes: 6 additions & 0 deletions arch/arm/mach-bcm283x/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,16 @@ config TARGET_RPI_2
bool "Raspberry Pi 2"
select CPU_V7

config TARGET_RPI_3_32B
bool "Raspberry Pi 3 32-bit build"
select CPU_V7

endchoice

config SYS_BOARD
default "rpi" if TARGET_RPI
default "rpi_2" if TARGET_RPI_2
default "rpi_3_32b" if TARGET_RPI_3_32B

config SYS_VENDOR
default "raspberrypi"
Expand All @@ -28,5 +33,6 @@ config SYS_SOC
config SYS_CONFIG_NAME
default "rpi" if TARGET_RPI
default "rpi_2" if TARGET_RPI_2
default "rpi_3_32b" if TARGET_RPI_3_32B

endmenu
25 changes: 25 additions & 0 deletions arch/arm/mach-bcm283x/include/mach/aux.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* (C) Copyright 2016 Stephen Warren <[email protected]>
*
* SPDX-License-Identifier: GPL-2.0+
*/

#ifndef _BCM2835_AUX_H_
#define _BCM2835_AUX_H_

#ifndef CONFIG_BCM2835
#define BCM2835_AUX_BASE 0x3f215000
#else
#define BCM2835_AUX_BASE 0x20215000
#endif

#define BCM2835_AUX_ENABLES_SPI2 BIT(0)
#define BCM2835_AUX_ENABLES_SPI1 BIT(0)
#define BCM2835_AUX_ENABLES_MINI_UART BIT(0)

struct bcm2835_aux_regs {
u32 irq;
u32 enables;
};

#endif /* _BCM2835_AXU_H_ */
2 changes: 1 addition & 1 deletion arch/arm/mach-bcm283x/include/mach/gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#ifndef _BCM2835_GPIO_H_
#define _BCM2835_GPIO_H_

#ifdef CONFIG_BCM2836
#ifndef CONFIG_BCM2835
#define BCM2835_GPIO_BASE 0x3f200000
#else
#define BCM2835_GPIO_BASE 0x20200000
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/mach-bcm283x/include/mach/mbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@

/* Raw mailbox HW */

#ifdef CONFIG_BCM2836
#ifndef CONFIG_BCM2835
#define BCM2835_MBOX_PHYSADDR 0x3f00b880
#else
#define BCM2835_MBOX_PHYSADDR 0x2000b880
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/mach-bcm283x/include/mach/sdhci.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#ifndef _BCM2835_SDHCI_H_
#define _BCM2835_SDHCI_H_

#ifdef CONFIG_BCM2836
#ifndef CONFIG_BCM2835
#define BCM2835_SDHCI_BASE 0x3f300000
#else
#define BCM2835_SDHCI_BASE 0x20300000
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/mach-bcm283x/include/mach/timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#ifndef _BCM2835_TIMER_H
#define _BCM2835_TIMER_H

#ifdef CONFIG_BCM2836
#ifndef CONFIG_BCM2835
#define BCM2835_TIMER_PHYSADDR 0x3f003000
#else
#define BCM2835_TIMER_PHYSADDR 0x20003000
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/mach-bcm283x/include/mach/wdog.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#ifndef _BCM2835_WDOG_H
#define _BCM2835_WDOG_H

#ifdef CONFIG_BCM2836
#ifndef CONFIG_BCM2835
#define BCM2835_WDOG_PHYSADDR 0x3f100000
#else
#define BCM2835_WDOG_PHYSADDR 0x20100000
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/mach-bcm283x/phys2bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

unsigned long phys_to_bus(unsigned long phys)
{
#ifdef CONFIG_BCM2836
#ifndef CONFIG_BCM2835
return 0xc0000000 | phys;
#else
return 0x40000000 | phys;
Expand Down
51 changes: 49 additions & 2 deletions board/raspberrypi/rpi/rpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@
#include <lcd.h>
#include <memalign.h>
#include <mmc.h>
#include <asm/io.h>
#include <asm/gpio.h>
#include <asm/arch/aux.h>
#include <asm/arch/mbox.h>
#include <asm/arch/sdhci.h>
#include <asm/global_data.h>
#include <dm/platform_data/serial_pl01x.h>
#include <dm/platform_data/serial_bcm283x_mu.h>

DECLARE_GLOBAL_DATA_PTR;

Expand All @@ -30,8 +33,9 @@ U_BOOT_DEVICE(bcm2835_gpios) = {
.platdata = &gpio_platdata,
};

#if defined(CONFIG_BCM2835) || defined(CONFIG_BCM2836)
static const struct pl01x_serial_platdata serial_platdata = {
#ifdef CONFIG_BCM2836
#ifndef CONFIG_BCM2835
.base = 0x3f201000,
#else
.base = 0x20201000,
Expand All @@ -43,6 +47,16 @@ U_BOOT_DEVICE(bcm2835_serials) = {
.name = "serial_pl01x",
.platdata = &serial_platdata,
};
#else
static const struct bcm283x_mu_serial_platdata serial_platdata = {
.base = 0x3f215040,
};

U_BOOT_DEVICE(bcm2837_serials) = {
.name = "serial_bcm283x_mu",
.platdata = &serial_platdata,
};
#endif

struct msg_get_arm_mem {
struct bcm2835_mbox_hdr hdr;
Expand Down Expand Up @@ -98,7 +112,9 @@ struct rpi_model {

static const struct rpi_model rpi_model_unknown = {
"Unknown model",
#ifdef CONFIG_BCM2836
#if defined(CONFIG_BCM2837)
"bcm2837-rpi-other.dtb",
#elif defined(CONFIG_BCM2836)
"bcm2836-rpi-other.dtb",
#else
"bcm2835-rpi-other.dtb",
Expand All @@ -112,6 +128,11 @@ static const struct rpi_model rpi_models_new_scheme[] = {
"bcm2836-rpi-2-b.dtb",
true,
},
[0x8] = {
"3 Model B",
"bcm2837-rpi-3-b.dtb",
true,
},
[0x9] = {
"Zero",
"bcm2835-rpi-zero.dtb",
Expand Down Expand Up @@ -212,6 +233,32 @@ static uint32_t rev_scheme;
static uint32_t rev_type;
static const struct rpi_model *model;

#ifdef CONFIG_BCM2837
int board_early_init_f(void)
{
struct bcm2835_gpio_regs *gpior =
(struct bcm2835_gpio_regs *)BCM2835_GPIO_BASE;
struct bcm2835_aux_regs *auxr =
(struct bcm2835_aux_regs *)BCM2835_AUX_BASE;
u32 val;

/* Route mini UART to header UART pins */
val = readl(&gpior->gpfsel[BCM2835_GPIO_FSEL_BANK(14)]);
val &= ~(BCM2835_GPIO_FSEL_MASK << BCM2835_GPIO_FSEL_SHIFT(14));
val |= (BCM2835_GPIO_ALT5 << BCM2835_GPIO_FSEL_SHIFT(14));
val &= ~(BCM2835_GPIO_FSEL_MASK << BCM2835_GPIO_FSEL_SHIFT(15));
val |= (BCM2835_GPIO_ALT5 << BCM2835_GPIO_FSEL_SHIFT(15));
writel(val, &gpior->gpfsel[BCM2835_GPIO_FSEL_BANK(14)]);

/* Enable mini UART HW module */
val = readl(&auxr->enables);
val |= BCM2835_AUX_ENABLES_MINI_UART;
writel(val, &auxr->enables);

return 0;
}
#endif

int dram_init(void)
{
ALLOC_CACHE_ALIGN_BUFFER(struct msg_get_arm_mem, msg, 1);
Expand Down
6 changes: 6 additions & 0 deletions board/raspberrypi/rpi_3_32b/MAINTAINERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
RPI_3_32B BOARD
M: Stephen Warren <[email protected]>
S: Maintained
F: board/raspberrypi/rpi_3_32b/
F: include/configs/rpi_3_32b.h
F: configs/rpi_3_32b_defconfig
7 changes: 7 additions & 0 deletions board/raspberrypi/rpi_3_32b/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#
# (C) Copyright 2012,2015 Stephen Warren <[email protected]>
#
# SPDX-License-Identifier: GPL-2.0
#

obj-y := ../rpi/rpi.o
9 changes: 9 additions & 0 deletions configs/rpi_3_32b_defconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
CONFIG_ARM=y
CONFIG_ARCH_BCM283X=y
CONFIG_TARGET_RPI_3_32B=y
CONFIG_SYS_PROMPT="U-Boot> "
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
CONFIG_CMD_GPIO=y
CONFIG_PHYS_TO_BUS=y
1 change: 1 addition & 0 deletions drivers/serial/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ obj-$(CONFIG_UNIPHIER_SERIAL) += serial_uniphier.o
obj-$(CONFIG_STM32_SERIAL) += serial_stm32.o
obj-$(CONFIG_PIC32_SERIAL) += serial_pic32.o
obj-$(CONFIG_STM32X7_SERIAL) += serial_stm32x7.o
obj-$(CONFIG_BCM283X_MU_SERIAL) += serial_bcm283x_mu.o

ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_USB_TTY) += usbtty.o
Expand Down
138 changes: 138 additions & 0 deletions drivers/serial/serial_bcm283x_mu.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/*
* (C) Copyright 2016 Stephen Warren <[email protected]>
*
* Derived from pl01x code:
*
* (C) Copyright 2000
* Rob Taylor, Flying Pig Systems. [email protected].
*
* (C) Copyright 2004
* ARM Ltd.
* Philippe Robin, <[email protected]>
*
* SPDX-License-Identifier: GPL-2.0+
*/

/* Simple U-Boot driver for the BCM283x mini UART */

#include <common.h>
#include <dm.h>
#include <errno.h>
#include <watchdog.h>
#include <asm/io.h>
#include <serial.h>
#include <dm/platform_data/serial_bcm283x_mu.h>
#include <linux/compiler.h>
#include <fdtdec.h>

struct bcm283x_mu_regs {
u32 io;
u32 iir;
u32 ier;
u32 lcr;
u32 mcr;
u32 lsr;
u32 msr;
u32 scratch;
u32 cntl;
u32 stat;
u32 baud;
};

#define BCM283X_MU_LCR_DATA_SIZE_8 3

#define BCM283X_MU_LSR_TX_IDLE BIT(6)
/* This actually means not full, but is named not empty in the docs */
#define BCM283X_MU_LSR_TX_EMPTY BIT(5)
#define BCM283X_MU_LSR_RX_READY BIT(0)

struct bcm283x_mu_priv {
struct bcm283x_mu_regs *regs;
};

static int bcm283x_mu_serial_setbrg(struct udevice *dev, int baudrate)
{
struct bcm283x_mu_priv *priv = dev_get_priv(dev);
struct bcm283x_mu_regs *regs = priv->regs;
/* FIXME: Get this from plat data later */
u32 clock_rate = 250000000;
u32 divider;

divider = clock_rate / (baudrate * 8);

writel(BCM283X_MU_LCR_DATA_SIZE_8, &regs->lcr);
writel(divider - 1, &regs->baud);

return 0;
}

static int bcm283x_mu_serial_probe(struct udevice *dev)
{
struct bcm283x_mu_serial_platdata *plat = dev_get_platdata(dev);
struct bcm283x_mu_priv *priv = dev_get_priv(dev);

priv->regs = (struct bcm283x_mu_regs *)plat->base;

return 0;
}

static int bcm283x_mu_serial_getc(struct udevice *dev)
{
struct bcm283x_mu_priv *priv = dev_get_priv(dev);
struct bcm283x_mu_regs *regs = priv->regs;
u32 data;

/* Wait until there is data in the FIFO */
if (!(readl(&regs->lsr) & BCM283X_MU_LSR_RX_READY))
return -EAGAIN;

data = readl(&regs->io);

return (int)data;
}

static int bcm283x_mu_serial_putc(struct udevice *dev, const char data)
{
struct bcm283x_mu_priv *priv = dev_get_priv(dev);
struct bcm283x_mu_regs *regs = priv->regs;

/* Wait until there is space in the FIFO */
if (!(readl(&regs->lsr) & BCM283X_MU_LSR_TX_EMPTY))
return -EAGAIN;

/* Send the character */
writel(data, &regs->io);

return 0;
}

static int bcm283x_mu_serial_pending(struct udevice *dev, bool input)
{
struct bcm283x_mu_priv *priv = dev_get_priv(dev);
struct bcm283x_mu_regs *regs = priv->regs;
unsigned int lsr = readl(&regs->lsr);

if (input) {
WATCHDOG_RESET();
return lsr & BCM283X_MU_LSR_RX_READY;
} else {
return !(lsr & BCM283X_MU_LSR_TX_IDLE);
}
}

static const struct dm_serial_ops bcm283x_mu_serial_ops = {
.putc = bcm283x_mu_serial_putc,
.pending = bcm283x_mu_serial_pending,
.getc = bcm283x_mu_serial_getc,
.setbrg = bcm283x_mu_serial_setbrg,
};

U_BOOT_DRIVER(serial_bcm283x_mu) = {
.name = "serial_bcm283x_mu",
.id = UCLASS_SERIAL,
.platdata_auto_alloc_size = sizeof(struct bcm283x_mu_serial_platdata),
.probe = bcm283x_mu_serial_probe,
.ops = &bcm283x_mu_serial_ops,
.flags = DM_FLAG_PRE_RELOC,
.priv_auto_alloc_size = sizeof(struct bcm283x_mu_priv),
};
Loading

5 comments on commit 202d830

@msperl
Copy link

@msperl msperl commented on 202d830 Mar 6, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we just continue to use the PL011 implementation (remapping the pins to the correct ALT)?

The big advantage is that this way we are always sure about the clock - the firmware can not easily change the clock behind the scenes impacting the serial console...

So we only would need: board_early_init_f.

Just some ideas...

@swarren
Copy link
Owner Author

@swarren swarren commented on 202d830 Mar 6, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PL011 is to be used by Bluetooth, so we have to use the mini UART for the console now. See pelwell's comment at RPi-Distro/repo#22 (search for "bluetooth") for background. Hopefully the FW will soon replace the board_early_init_f() function; see raspberrypi/firmware#553.

@msperl
Copy link

@msperl msperl commented on 202d830 Mar 6, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess there are several such tickets - I opened one just today as well for the downstream kernel...

But still - people may want to run their terminal with ttyAMA - especially when you run on a Compute Module, where you have access to both ttys - and they promise a CM with the bcm2837...

Note that the CM has an ID of 0x20 - you may want to add that to u-boot as well:

U-Boot 2015.04-rc2-gc191763 (Mar 01 2015 - 19:50:51)

DRAM:  448 MiB
WARNING: Caches not enabled
RPI: Board rev 20 outside known range
RPI Unknown model
MMC:   bcm2835_sdhci: 0
reading uboot.env
In:    serial
Out:   lcd
Err:   lcd
Net:   Net Initialization Skipped
No ethernet found.
Hit any key to stop autoboot:  0

@swarren
Copy link
Owner Author

@swarren swarren commented on 202d830 Mar 6, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd expect the default configuration in U-Boot to be coded to match the RPi Foundation's decisions regarding how they expect the HW to be used by default. People can certainly adjust the code locally if they want to assign the UARTs differently, or we could add some more U-Boot defconfigs (and/or perhaps request additional VC FW config.txt options?) to support people who want to use non-default configurations.

I suggest sending a patch for the new CM board ID; the CM I have has either ID 0x11 or 0x14. Do you have a board yourself that has 0x20 ID? If not, where do you get that information? FWIW, the data sources used to construct the existing table in U-Boot are:

/*
 * http://raspberryalphaomega.org.uk/2013/02/06/automatic-raspberry-pi-board-revision-d
etection-model-a-b1-and-b2/
 * http://www.raspberrypi.org/forums/viewtopic.php?f=63&t=32733
 * http://git.drogon.net/?p=wiringPi;a=blob;f=wiringPi/wiringPi.c;h=503151f61014418b9c4
2f4476a6086f75cd4e64b;hb=refs/heads/master#l922
 *
 * In http://lists.denx.de/pipermail/u-boot/2016-January/243752.html
 * ("[U-Boot] [PATCH] rpi: fix up Model B entries") Dom Cobley at the RPi
 * Foundation stated that the following source was accurate:
 * https://github.com/AndrewFromMelbourne/raspberry_pi_revision
 */

@msperl
Copy link

@msperl msperl commented on 202d830 Mar 6, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes - i got that board myself - I just rebooted it that way to get that output...

Please sign in to comment.