diff --git a/Documentation/boards/bcm2835.rst b/Documentation/boards/bcm2835.rst index 79ea0ff..ea80d58 100644 --- a/Documentation/boards/bcm2835.rst +++ b/Documentation/boards/bcm2835.rst @@ -22,7 +22,6 @@ kernel=barebox.img enable_uart=1 - dtoverlay=pi3-miniuart-bt (For more information, refer to the `documentation for config.txt`_.) diff --git a/arch/arm/boards/raspberry-pi/rpi-common.c b/arch/arm/boards/raspberry-pi/rpi-common.c index b2febec..b5d16a1 100644 --- a/arch/arm/boards/raspberry-pi/rpi-common.c +++ b/arch/arm/boards/raspberry-pi/rpi-common.c @@ -73,7 +73,7 @@ return 0; } -static struct clk *rpi_register_firmare_clock(u32 clock_id, const char *name) +static struct clk *rpi_register_firmware_clock(u32 clock_id, const char *name) { BCM2835_MBOX_STACK_ALIGN(struct msg_get_clock_rate, msg); int ret; @@ -121,7 +121,7 @@ }, }; -void rpi_add_led(void) +static void rpi_add_led(void) { int i; struct gpio_led *l; @@ -138,14 +138,14 @@ led_set_trigger(LED_TRIGGER_HEARTBEAT, &l->led); } -void rpi_b_init(void) +static void rpi_b_init(void) { rpi_leds[0].gpio = 16; rpi_leds[0].active_low = 1; rpi_set_usbethaddr(); } -void rpi_b_plus_init(void) +static void rpi_b_plus_init(void) { rpi_leds[0].gpio = 47; rpi_leds[1].gpio = 35; @@ -166,17 +166,30 @@ RPI_MODEL(BCM2835_BOARD_REV_B_REV2_d, "Model B rev2", rpi_b_init), RPI_MODEL(BCM2835_BOARD_REV_B_REV2_e, "Model B rev2", rpi_b_init), RPI_MODEL(BCM2835_BOARD_REV_B_REV2_f, "Model B rev2", rpi_b_init), - RPI_MODEL(BCM2835_BOARD_REV_B_PLUS, "Model B+", rpi_b_plus_init), - RPI_MODEL(BCM2835_BOARD_REV_CM, "Compute Module", NULL), - RPI_MODEL(BCM2835_BOARD_REV_A_PLUS, "Model A+", NULL), + RPI_MODEL(BCM2835_BOARD_REV_B_PLUS_10, "Model B+", rpi_b_plus_init), + RPI_MODEL(BCM2835_BOARD_REV_CM_11, "Compute Module", NULL), + RPI_MODEL(BCM2835_BOARD_REV_A_PLUS_12, "Model A+", NULL), + RPI_MODEL(BCM2835_BOARD_REV_B_PLUS_13, "Model B+", rpi_b_plus_init), + RPI_MODEL(BCM2835_BOARD_REV_CM_14, "Compute Module", NULL), + RPI_MODEL(BCM2835_BOARD_REV_A_PLUS_15, "Model A+", NULL), }; const struct rpi_model rpi_models_new_scheme[] = { - RPI_MODEL(0, "Unknown model", NULL), - RPI_MODEL(BCM2836_BOARD_REV_2_B, "2 Model B", rpi_b_plus_init), - RPI_MODEL(BCM2837_BOARD_REV_3_B, "3 Model B", rpi_b_plus_init), - RPI_MODEL(BCM2835_BOARD_REV_ZERO, "Zero", rpi_b_plus_init), - RPI_MODEL(BCM2835_BOARD_REV_ZERO_W, "Zero W", rpi_b_plus_init), + RPI_MODEL(BCM2835_BOARD_REV_A, "Model A", NULL ), + RPI_MODEL(BCM2835_BOARD_REV_B, "Model B", rpi_b_init ), + RPI_MODEL(BCM2835_BOARD_REV_A_PLUS, "Model A+", NULL ), + RPI_MODEL(BCM2835_BOARD_REV_B_PLUS, "Model B+", rpi_b_plus_init ), + RPI_MODEL(BCM2836_BOARD_REV_2_B, "Model 2B", rpi_b_plus_init), + RPI_MODEL(BCM283x_BOARD_REV_Alpha, "Alpha", NULL), + RPI_MODEL(BCM2835_BOARD_REV_CM1, "Compute Module", NULL ), + RPI_MODEL(0x7, "Unknown model", NULL), + RPI_MODEL(BCM2837_BOARD_REV_3_B, "Model 3B", rpi_b_init ), + RPI_MODEL(BCM2835_BOARD_REV_ZERO, "Zero", rpi_b_plus_init), + RPI_MODEL(BCM2837_BOARD_REV_CM3, "Compute Module 3", NULL ), + RPI_MODEL(0xb, "Unknown model", NULL), + RPI_MODEL(BCM2835_BOARD_REV_ZERO_W, "Zero W", rpi_b_plus_init), + RPI_MODEL(BCM2837B0_BOARD_REV_3B_PLUS, "Model 3 B+", rpi_b_plus_init ), + RPI_MODEL(BCM2837B0_BOARD_REV_3A_PLUS, "Nodel 3 A+", rpi_b_plus_init), }; static int rpi_board_rev = 0; @@ -289,7 +302,7 @@ { struct clk *clk; - clk = rpi_register_firmare_clock(BCM2835_MBOX_CLOCK_ID_EMMC, + clk = rpi_register_firmware_clock(BCM2835_MBOX_CLOCK_ID_EMMC, "bcm2835_mci0"); if (IS_ERR(clk)) return PTR_ERR(clk); @@ -301,6 +314,36 @@ } postconsole_initcall(rpi_clock_init); +#define BCM2835_PL011_BASE 0x20201000 +#define BCM2836_PL011_BASE 0x3f201000 +#define BCM2836_MINIUART_BASE 0x3f215040 + +static int rpi_console_clock_init(void) +{ + struct clk *clk; + + clk = clk_fixed("apb_pclk", 0); + clk_register_clkdev(clk, "apb_pclk", NULL); + + clk = clk_fixed("uart0-pl0110", 3 * 1000 * 1000); + clk_register_clkdev(clk, NULL, "uart0-pl0110"); + clkdev_add_physbase(clk, BCM2835_PL011_BASE, NULL); + clkdev_add_physbase(clk, BCM2836_PL011_BASE, NULL); + + clk = rpi_register_firmware_clock(BCM2835_MBOX_CLOCK_ID_CORE, + "uart1-8250"); + if (IS_ERR(clk)) + return PTR_ERR(clk); + + clkdev_add_physbase(clk, BCM2836_MINIUART_BASE, NULL); + + clk = clk_fixed("bcm2835-cs", 1 * 1000 * 1000); + clk_register_clkdev(clk, NULL, "bcm2835-cs"); + + return 0; +} +postcore_initcall(rpi_console_clock_init); + static int rpi_env_init(void) { struct stat s; diff --git a/arch/arm/boards/raspberry-pi/rpi.h b/arch/arm/boards/raspberry-pi/rpi.h index dd32fee..b2a0401 100644 --- a/arch/arm/boards/raspberry-pi/rpi.h +++ b/arch/arm/boards/raspberry-pi/rpi.h @@ -19,7 +19,6 @@ extern struct gpio_led rpi_leds[]; -void rpi_b_plus_init(void); void rpi_set_usbethaddr(void); #endif /* __ARCH_ARM_BOARDS_RPI_H__ */ diff --git a/arch/arm/configs/rpi_defconfig b/arch/arm/configs/rpi_defconfig index 2bb6158..dc5ab1f 100644 --- a/arch/arm/configs/rpi_defconfig +++ b/arch/arm/configs/rpi_defconfig @@ -63,6 +63,7 @@ CONFIG_CMD_OFTREE=y CONFIG_CMD_TIME=y CONFIG_SERIAL_AMBA_PL011=y +CONFIG_DRIVER_SERIAL_NS16550=y CONFIG_MCI=y CONFIG_MCI_BCM283X=y CONFIG_LED=y diff --git a/arch/arm/dts/bcm2837-rpi-3.dts b/arch/arm/dts/bcm2837-rpi-3.dts index d6ffc36..194b41c 100644 --- a/arch/arm/dts/bcm2837-rpi-3.dts +++ b/arch/arm/dts/bcm2837-rpi-3.dts @@ -2,15 +2,10 @@ / { chosen { - stdout-path = &uart0; + stdout-path = &uart1; }; memory { reg = <0x0 0x0>; }; }; - -&uart0 { - status = "okay"; - /delete-node/ bluetooth; -}; diff --git a/arch/arm/mach-bcm283x/core.c b/arch/arm/mach-bcm283x/core.c index f1dcda8..f2528cf 100644 --- a/arch/arm/mach-bcm283x/core.c +++ b/arch/arm/mach-bcm283x/core.c @@ -31,25 +31,6 @@ #include #include -static int bcm2835_clk_init(void) -{ - struct clk *clk; - - clk = clk_fixed("apb_pclk", 0); - clk_register_clkdev(clk, "apb_pclk", NULL); - - clk = clk_fixed("uart0-pl0110", 3 * 1000 * 1000); - clk_register_clkdev(clk, NULL, "uart0-pl0110"); - clkdev_add_physbase(clk, 0x20201000, NULL); - clkdev_add_physbase(clk, 0x3f201000, NULL); - - clk = clk_fixed("bcm2835-cs", 1 * 1000 * 1000); - clk_register_clkdev(clk, NULL, "bcm2835-cs"); - - return 0; -} -postcore_initcall(bcm2835_clk_init); - void bcm2835_add_device_sdram(u32 size) { if (!size) diff --git a/arch/arm/mach-bcm283x/include/mach/mbox.h b/arch/arm/mach-bcm283x/include/mach/mbox.h index 76b573f..e4f6cb6 100644 --- a/arch/arm/mach-bcm283x/include/mach/mbox.h +++ b/arch/arm/mach-bcm283x/include/mach/mbox.h @@ -127,20 +127,12 @@ #define BCM2835_MBOX_TAG_GET_BOARD_REV 0x00010002 -/* RPi 2 */ -#define BCM2836_BOARD_REV_2_B 0x4 -/* RPi 3 */ -#define BCM2837_BOARD_REV_3_B 0x8 -/* Zero */ -#define BCM2835_BOARD_REV_ZERO 0x9 -/* Zero W */ -#define BCM2835_BOARD_REV_ZERO_W 0xc - /* - * 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 + * ids + * https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md + * cpu info + * https://en.wikipedia.org/wiki/Raspberry_Pi#Processor + * */ #define BCM2835_BOARD_REV_B_I2C0_2 0x2 #define BCM2835_BOARD_REV_B_I2C0_3 0x3 @@ -153,9 +145,27 @@ #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 -#define BCM2835_BOARD_REV_A_PLUS 0x12 +#define BCM2835_BOARD_REV_B_PLUS_10 0x10 +#define BCM2835_BOARD_REV_CM_11 0x11 +#define BCM2835_BOARD_REV_A_PLUS_12 0x12 +#define BCM2835_BOARD_REV_B_PLUS_13 0x13 +#define BCM2835_BOARD_REV_CM_14 0x14 +#define BCM2835_BOARD_REV_A_PLUS_15 0x15 + + +#define BCM2835_BOARD_REV_A 0x00 +#define BCM2835_BOARD_REV_B 0x01 +#define BCM2835_BOARD_REV_A_PLUS 0x02 +#define BCM2835_BOARD_REV_B_PLUS 0x03 +#define BCM2836_BOARD_REV_2_B 0x04 +#define BCM283x_BOARD_REV_Alpha 0x05 +#define BCM2835_BOARD_REV_CM1 0x06 +#define BCM2837_BOARD_REV_3_B 0x08 +#define BCM2835_BOARD_REV_ZERO 0x09 +#define BCM2837_BOARD_REV_CM3 0x0a +#define BCM2835_BOARD_REV_ZERO_W 0x0c +#define BCM2837B0_BOARD_REV_3B_PLUS 0x0d +#define BCM2837B0_BOARD_REV_3A_PLUS 0x0e struct bcm2835_mbox_tag_get_board_rev { struct bcm2835_mbox_tag_hdr tag_hdr; diff --git a/drivers/mci/mci-bcm2835.c b/drivers/mci/mci-bcm2835.c index daf7719..9438e66 100644 --- a/drivers/mci/mci-bcm2835.c +++ b/drivers/mci/mci-bcm2835.c @@ -53,7 +53,7 @@ uint64_t last_write; }; -void bcm2835_mci_write(struct bcm2835_mci_host *host, u32 reg, u32 val) +static void bcm2835_mci_write(struct bcm2835_mci_host *host, u32 reg, u32 val) { /* * The Arasan has a bugette whereby it may lose the content of @@ -71,7 +71,7 @@ writel(val, host->regs + reg); } -u32 bcm2835_mci_read(struct bcm2835_mci_host *host, u32 reg) +static u32 bcm2835_mci_read(struct bcm2835_mci_host *host, u32 reg) { return readl(host->regs + reg); } @@ -80,13 +80,13 @@ * register is not affected by the twoticks_delay bug * and we can thus get better speed here */ -void bcm2835_mci_write_data(struct bcm2835_mci_host *host, u32 *p) +static void bcm2835_mci_write_data(struct bcm2835_mci_host *host, u32 *p) { writel(*p, host->regs + SDHCI_BUFFER); } /* Make a read data functions as well just to keep structure */ -void bcm2835_mci_read_data(struct bcm2835_mci_host *host, u32 *p) +static void bcm2835_mci_read_data(struct bcm2835_mci_host *host, u32 *p) { *p = readl(host->regs + SDHCI_BUFFER); } @@ -416,7 +416,7 @@ host->bus_width, host->clock); } -int bcm2835_mci_reset(struct mci_host *mci, struct device_d *mci_dev) +static int bcm2835_mci_reset(struct mci_host *mci, struct device_d *mci_dev) { struct bcm2835_mci_host *host; u32 ret = 0; diff --git a/drivers/serial/serial_ns16550.c b/drivers/serial/serial_ns16550.c index 4d73ea8..ccd082e 100644 --- a/drivers/serial/serial_ns16550.c +++ b/drivers/serial/serial_ns16550.c @@ -253,6 +253,23 @@ ns16550_serial_init_port(cdev); } +#define BCM2836_AUX_CLOCK_ENB 0x3f215004 /* BCM2835 AUX Clock enable register */ +#define BCM2836_AUX_CLOCK_EN_UART BIT(0) /* Bit 0 enables the Miniuart */ + +static void rpi_init_port(struct console_device *cdev) +{ + struct ns16550_priv *priv = to_ns16550_priv(cdev); + + writeb(BCM2836_AUX_CLOCK_EN_UART, BCM2836_AUX_CLOCK_ENB); + priv->plat.shift = 2; + /* + * We double the clock rate since the 16550 will divide by 16 + * (instead of 8 required by the BCM2835 peripheral manual) + */ + priv->plat.clock = priv->plat.clock*2; + ns16550_serial_init_port(cdev); +} + /*********** Exposed Functions **********************************/ /** @@ -297,36 +314,36 @@ static void ns16550_probe_dt(struct device_d *dev, struct ns16550_priv *priv) { struct device_node *np = dev->device_node; - u32 width; + u32 width = 1; if (!IS_ENABLED(CONFIG_OFDEVICE)) return; of_property_read_u32(np, "clock-frequency", &priv->plat.clock); of_property_read_u32(np, "reg-shift", &priv->plat.shift); - if (!of_property_read_u32(np, "reg-io-width", &width)) - switch (width) { - case 1: - priv->read_reg = ns16550_read_reg_mmio_8; - priv->write_reg = ns16550_write_reg_mmio_8; - break; - case 2: - priv->read_reg = ns16550_read_reg_mmio_16; - priv->write_reg = ns16550_write_reg_mmio_16; - break; - case 4: - if (of_device_is_big_endian(np)) { - priv->read_reg = ns16550_read_reg_mmio_32be; - priv->write_reg = ns16550_write_reg_mmio_32be; - } else { - priv->read_reg = ns16550_read_reg_mmio_32; - priv->write_reg = ns16550_write_reg_mmio_32; - } - break; - default: - dev_err(dev, "unsupported reg-io-width (%d)\n", - width); + of_property_read_u32(np, "reg-io-width", &width); + switch (width) { + case 1: + priv->read_reg = ns16550_read_reg_mmio_8; + priv->write_reg = ns16550_write_reg_mmio_8; + break; + case 2: + priv->read_reg = ns16550_read_reg_mmio_16; + priv->write_reg = ns16550_write_reg_mmio_16; + break; + case 4: + if (of_device_is_big_endian(np)) { + priv->read_reg = ns16550_read_reg_mmio_32be; + priv->write_reg = ns16550_write_reg_mmio_32be; + } else { + priv->read_reg = ns16550_read_reg_mmio_32; + priv->write_reg = ns16550_write_reg_mmio_32; } + break; + default: + dev_err(dev, "unsupported reg-io-width (%d)\n", + width); + } } static struct ns16550_drvdata ns16450_drvdata = { @@ -353,6 +370,11 @@ .linux_console_name = "ttyS", }; +static __maybe_unused struct ns16550_drvdata rpi_drvdata = { + .init_port = rpi_init_port, + .linux_console_name = "ttyS", +}; + static int ns16550_init_iomem(struct device_d *dev, struct ns16550_priv *priv) { struct resource *iores; @@ -528,6 +550,12 @@ .data = &jz_drvdata, }, #endif +#if IS_ENABLED(CONFIG_MACH_RPI_COMMON) + { + .compatible = "brcm,bcm2835-aux-uart", + .data = &rpi_drvdata, + }, +#endif { /* sentinel */ },