[U-Boot] [PATCH 0/4] dm: rpi: Move Raspberry Pi to use driver model

This series adds driver model support to the GPIO and serial drivers used by Raspberry Pi, and moves Raspberry Pi over to driver model.
This requires adding driver model support to the pl01x serial driver, and replacing the bcm2835 GPIO driver with a driver model version (since there are no longer clients that don't use driver model).
See u-boot-dm.git branch rpi-working for the tree this is based on.
Simon Glass (4): dm: rpi: Convert GPIO driver to driver model dm: serial: Tidy up the pl01x driver dm: serial: Support driver model in pl01x driver dm: rpi: Move serial to driver model
arch/arm/include/asm/arch-bcm2835/gpio.h | 9 + board/raspberrypi/rpi_b/rpi_b.c | 23 ++ drivers/gpio/bcm2835_gpio.c | 180 ++++++++-- drivers/serial/Makefile | 5 +- drivers/serial/serial_pl01x.c | 373 +++++++++++++-------- .../{serial_pl01x.h => serial_pl01x_internal.h} | 0 include/configs/rpi_b.h | 11 +- include/serial_pl01x.h | 27 ++ 8 files changed, 462 insertions(+), 166 deletions(-) rename drivers/serial/{serial_pl01x.h => serial_pl01x_internal.h} (100%) create mode 100644 include/serial_pl01x.h

Convert the BCM2835 GPIO driver to use driver model, and switch over Raspberry Pi to use this, since it is the only board.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/arm/include/asm/arch-bcm2835/gpio.h | 9 ++ board/raspberrypi/rpi_b/rpi_b.c | 11 ++ drivers/gpio/bcm2835_gpio.c | 180 +++++++++++++++++++++++++++---- include/configs/rpi_b.h | 5 + 4 files changed, 182 insertions(+), 23 deletions(-)
diff --git a/arch/arm/include/asm/arch-bcm2835/gpio.h b/arch/arm/include/asm/arch-bcm2835/gpio.h index 9a49b6e..db42896 100644 --- a/arch/arm/include/asm/arch-bcm2835/gpio.h +++ b/arch/arm/include/asm/arch-bcm2835/gpio.h @@ -52,4 +52,13 @@ struct bcm2835_gpio_regs { u32 gppudclk[2]; };
+/** + * struct bcm2835_gpio_platdata - GPIO platform description + * + * @base: Base address of GPIO controller + */ +struct bcm2835_gpio_platdata { + unsigned long base; +}; + #endif /* _BCM2835_GPIO_H_ */ diff --git a/board/raspberrypi/rpi_b/rpi_b.c b/board/raspberrypi/rpi_b/rpi_b.c index 220bb90..447c940 100644 --- a/board/raspberrypi/rpi_b/rpi_b.c +++ b/board/raspberrypi/rpi_b/rpi_b.c @@ -16,15 +16,26 @@
#include <common.h> #include <config.h> +#include <dm.h> #include <fdt_support.h> #include <lcd.h> #include <mmc.h> +#include <asm/gpio.h> #include <asm/arch/mbox.h> #include <asm/arch/sdhci.h> #include <asm/global_data.h>
DECLARE_GLOBAL_DATA_PTR;
+static const struct bcm2835_gpio_platdata gpio_platdata = { + .base = BCM2835_GPIO_BASE, +}; + +U_BOOT_DEVICE(bcm2835_gpios) = { + .name = "gpio_bcm2835", + .platdata = &gpio_platdata, +}; + struct msg_get_arm_mem { struct bcm2835_mbox_hdr hdr; struct bcm2835_mbox_tag_get_arm_mem get_arm_mem; diff --git a/drivers/gpio/bcm2835_gpio.c b/drivers/gpio/bcm2835_gpio.c index 97b5137..332cfc2 100644 --- a/drivers/gpio/bcm2835_gpio.c +++ b/drivers/gpio/bcm2835_gpio.c @@ -6,73 +6,207 @@ */
#include <common.h> +#include <dm.h> +#include <errno.h> #include <asm/gpio.h> #include <asm/io.h>
-inline int gpio_is_valid(unsigned gpio) +#define GPIO_NAME_SIZE 20 + +struct bcm2835_gpios { + char label[BCM2835_GPIO_COUNT][GPIO_NAME_SIZE]; + struct bcm2835_gpio_regs *reg; +}; + +/** + * gpio_is_requested() - check if a GPIO has been requested + * + * @bank: Bank to check + * @offset: GPIO offset within bank to check + * @return true if marked as requested, false if not + */ +static inline bool gpio_is_requested(struct bcm2835_gpios *gpios, int offset) { - return (gpio < BCM2835_GPIO_COUNT); + return *gpios->label[offset] != '\0'; }
-int gpio_request(unsigned gpio, const char *label) +static int check_requested(struct udevice *dev, unsigned offset, + const char *func) { - return !gpio_is_valid(gpio); + struct bcm2835_gpios *gpios = dev_get_priv(dev); + struct gpio_dev_priv *uc_priv = dev->uclass_priv; + + if (!gpio_is_requested(gpios, offset)) { + printf("omap_gpio: %s: error: gpio %s%d not requested\n", + func, uc_priv->bank_name, offset); + return -EPERM; + } + + return 0; }
-int gpio_free(unsigned gpio) +static int bcm2835_gpio_request(struct udevice *dev, unsigned offset, + const char *label) { + struct bcm2835_gpios *gpios = dev_get_priv(dev); + + if (gpio_is_requested(gpios, offset)) + return -EBUSY; + + strncpy(gpios->label[offset], label, GPIO_NAME_SIZE); + gpios->label[offset][GPIO_NAME_SIZE - 1] = '\0'; + return 0; }
-int gpio_direction_input(unsigned gpio) +static int bcm2835_gpio_free(struct udevice *dev, unsigned offset) { - struct bcm2835_gpio_regs *reg = - (struct bcm2835_gpio_regs *)BCM2835_GPIO_BASE; + struct bcm2835_gpios *gpios = dev_get_priv(dev); + int ret; + + ret = check_requested(dev, offset, __func__); + if (ret) + return ret; + gpios->label[offset][0] = '\0'; + + return 0; +} + +static int bcm2835_gpio_direction_input(struct udevice *dev, unsigned gpio) +{ + struct bcm2835_gpios *gpios = dev_get_priv(dev); unsigned val;
- val = readl(®->gpfsel[BCM2835_GPIO_FSEL_BANK(gpio)]); + val = readl(&gpios->reg->gpfsel[BCM2835_GPIO_FSEL_BANK(gpio)]); val &= ~(BCM2835_GPIO_FSEL_MASK << BCM2835_GPIO_FSEL_SHIFT(gpio)); val |= (BCM2835_GPIO_INPUT << BCM2835_GPIO_FSEL_SHIFT(gpio)); - writel(val, ®->gpfsel[BCM2835_GPIO_FSEL_BANK(gpio)]); + writel(val, &gpios->reg->gpfsel[BCM2835_GPIO_FSEL_BANK(gpio)]);
return 0; }
-int gpio_direction_output(unsigned gpio, int value) +static int bcm2835_gpio_direction_output(struct udevice *dev, unsigned gpio, + int value) { - struct bcm2835_gpio_regs *reg = - (struct bcm2835_gpio_regs *)BCM2835_GPIO_BASE; + struct bcm2835_gpios *gpios = dev_get_priv(dev); unsigned val;
gpio_set_value(gpio, value);
- val = readl(®->gpfsel[BCM2835_GPIO_FSEL_BANK(gpio)]); + val = readl(&gpios->reg->gpfsel[BCM2835_GPIO_FSEL_BANK(gpio)]); val &= ~(BCM2835_GPIO_FSEL_MASK << BCM2835_GPIO_FSEL_SHIFT(gpio)); val |= (BCM2835_GPIO_OUTPUT << BCM2835_GPIO_FSEL_SHIFT(gpio)); - writel(val, ®->gpfsel[BCM2835_GPIO_FSEL_BANK(gpio)]); + writel(val, &gpios->reg->gpfsel[BCM2835_GPIO_FSEL_BANK(gpio)]);
return 0; }
-int gpio_get_value(unsigned gpio) +static bool bcm2835_gpio_is_output(const struct bcm2835_gpios *gpios, int gpio) +{ + u32 val; + + val = readl(&gpios->reg->gpfsel[BCM2835_GPIO_FSEL_BANK(gpio)]); + val &= BCM2835_GPIO_FSEL_MASK << BCM2835_GPIO_FSEL_SHIFT(gpio); + return val ? true : false; +} + +static int bcm2835_get_value(const struct bcm2835_gpios *gpios, unsigned gpio) { - struct bcm2835_gpio_regs *reg = - (struct bcm2835_gpio_regs *)BCM2835_GPIO_BASE; unsigned val;
- val = readl(®->gplev[BCM2835_GPIO_COMMON_BANK(gpio)]); + val = readl(&gpios->reg->gplev[BCM2835_GPIO_COMMON_BANK(gpio)]);
return (val >> BCM2835_GPIO_COMMON_SHIFT(gpio)) & 0x1; }
-int gpio_set_value(unsigned gpio, int value) +static int bcm2835_gpio_get_value(struct udevice *dev, unsigned gpio) { - struct bcm2835_gpio_regs *reg = - (struct bcm2835_gpio_regs *)BCM2835_GPIO_BASE; - u32 *output_reg = value ? reg->gpset : reg->gpclr; + const struct bcm2835_gpios *gpios = dev_get_priv(dev); + + return bcm2835_get_value(gpios, gpio); +} + +static int bcm2835_gpio_set_value(struct udevice *dev, unsigned gpio, + int value) +{ + struct bcm2835_gpios *gpios = dev_get_priv(dev); + u32 *output_reg = value ? gpios->reg->gpset : gpios->reg->gpclr;
writel(1 << BCM2835_GPIO_COMMON_SHIFT(gpio), &output_reg[BCM2835_GPIO_COMMON_BANK(gpio)]);
return 0; } + +static int bcm2835_gpio_get_function(struct udevice *dev, unsigned offset) +{ + struct bcm2835_gpios *gpios = dev_get_priv(dev); + + if (!gpio_is_requested(gpios, offset)) + return GPIOF_UNUSED; + + /* GPIOF_FUNC is not implemented yet */ + if (bcm2835_gpio_is_output(gpios, offset)) + return GPIOF_OUTPUT; + else + return GPIOF_INPUT; +} + +static int bcm2835_gpio_get_state(struct udevice *dev, unsigned int offset, + char *buf, int bufsize) +{ + struct gpio_dev_priv *uc_priv = dev->uclass_priv; + struct bcm2835_gpios *gpios = dev_get_priv(dev); + const char *label; + bool requested; + bool is_output; + int size; + + label = gpios->label[offset]; + is_output = bcm2835_gpio_is_output(gpios, offset); + size = snprintf(buf, bufsize, "%s%d: ", + uc_priv->bank_name ? uc_priv->bank_name : "", offset); + buf += size; + bufsize -= size; + requested = gpio_is_requested(gpios, offset); + snprintf(buf, bufsize, "%s: %d [%c]%s%s", + is_output ? "out" : " in", + bcm2835_get_value(gpios, offset), + requested ? 'x' : ' ', + requested ? " " : "", + label); + + return 0; +} + +static const struct dm_gpio_ops gpio_bcm2835_ops = { + .request = bcm2835_gpio_request, + .free = bcm2835_gpio_free, + .direction_input = bcm2835_gpio_direction_input, + .direction_output = bcm2835_gpio_direction_output, + .get_value = bcm2835_gpio_get_value, + .set_value = bcm2835_gpio_set_value, + .get_function = bcm2835_gpio_get_function, + .get_state = bcm2835_gpio_get_state, +}; + +static int bcm2835_gpio_probe(struct udevice *dev) +{ + struct bcm2835_gpios *gpios = dev_get_priv(dev); + struct bcm2835_gpio_platdata *plat = dev_get_platdata(dev); + struct gpio_dev_priv *uc_priv = dev->uclass_priv; + + uc_priv->bank_name = "GPIO"; + uc_priv->gpio_count = BCM2835_GPIO_COUNT; + gpios->reg = (struct bcm2835_gpio_regs *)plat->base; + + return 0; +} + +U_BOOT_DRIVER(gpio_bcm2835) = { + .name = "gpio_bcm2835", + .id = UCLASS_GPIO, + .ops = &gpio_bcm2835_ops, + .probe = bcm2835_gpio_probe, + .priv_auto_alloc_size = sizeof(struct bcm2835_gpios), +}; diff --git a/include/configs/rpi_b.h b/include/configs/rpi_b.h index 2d69809..d9475e9 100644 --- a/include/configs/rpi_b.h +++ b/include/configs/rpi_b.h @@ -31,6 +31,11 @@ */ #define CONFIG_MACH_TYPE MACH_TYPE_BCM2708
+/* Enable driver model */ +#define CONFIG_DM +#define CONFIG_CMD_DM +#define CONFIG_DM_GPIO + /* Memory layout */ #define CONFIG_NR_DRAM_BANKS 1 #define CONFIG_SYS_SDRAM_BASE 0x00000000

On 09/22/2014 05:30 PM, Simon Glass wrote:
Convert the BCM2835 GPIO driver to use driver model, and switch over Raspberry Pi to use this, since it is the only board.
diff --git a/drivers/gpio/bcm2835_gpio.c b/drivers/gpio/bcm2835_gpio.c
+static inline bool gpio_is_requested(struct bcm2835_gpios *gpios, int offset) {
- return *gpios->label[offset] != '\0';
}
+static int check_requested(struct udevice *dev, unsigned offset,
const char *func)
{
- struct bcm2835_gpios *gpios = dev_get_priv(dev);
- struct gpio_dev_priv *uc_priv = dev->uclass_priv;
- if (!gpio_is_requested(gpios, offset)) {
printf("omap_gpio: %s: error: gpio %s%d not requested\n",
func, uc_priv->bank_name, offset);
return -EPERM;
- }
- return 0;
}
It seems like the core GPIO layer should be doing the high-level management of GPIO requesting, so each driver doesn't have to duplicate the code?

Hi Stephen,
On 30 September 2014 19:40, Stephen Warren swarren@wwwdotorg.org wrote:
On 09/22/2014 05:30 PM, Simon Glass wrote:
Convert the BCM2835 GPIO driver to use driver model, and switch over Raspberry Pi to use this, since it is the only board.
diff --git a/drivers/gpio/bcm2835_gpio.c b/drivers/gpio/bcm2835_gpio.c
+static inline bool gpio_is_requested(struct bcm2835_gpios *gpios, int offset) {
return *gpios->label[offset] != '\0';
}
+static int check_requested(struct udevice *dev, unsigned offset,
const char *func)
{
struct bcm2835_gpios *gpios = dev_get_priv(dev);
struct gpio_dev_priv *uc_priv = dev->uclass_priv;
if (!gpio_is_requested(gpios, offset)) {
printf("omap_gpio: %s: error: gpio %s%d not requested\n",
func, uc_priv->bank_name, offset);
return -EPERM;
}
return 0;
}
It seems like the core GPIO layer should be doing the high-level management of GPIO requesting, so each driver doesn't have to duplicate the code?
Yes, agreed. I figured this was coming but took a conservative approach with the uclass to start with. I will be taking a look at moving this logic into the uclass soon. I've done enough GPIO drivers to prove this out.
Regards, Simon

On 22 September 2014 17:30, Simon Glass sjg@chromium.org wrote:
Convert the BCM2835 GPIO driver to use driver model, and switch over Raspberry Pi to use this, since it is the only board.
Signed-off-by: Simon Glass sjg@chromium.org
arch/arm/include/asm/arch-bcm2835/gpio.h | 9 ++ board/raspberrypi/rpi_b/rpi_b.c | 11 ++ drivers/gpio/bcm2835_gpio.c | 180 +++++++++++++++++++++++++++---- include/configs/rpi_b.h | 5 + 4 files changed, 182 insertions(+), 23 deletions(-)
Applied to u-boot-dm/master.

Adjust the driver so that leaf functions take a pointer to the serial port register base. Put all the global configuration in the init function, and use the same settings from then on.
This makes it much easier to move to driver model without duplicating the code, since with driver model we use platform data rather than global settings.
The driver is compiled with either the CONFIG_PL010_SERIAL or CONFIG_PL011_SERIAL option and this determines the uart type. With driver model this needs to come in from platform data, so create a new CONFIG_PL01X_SERIAL config which brings in the driver, and adjust the driver to support both peripheral variants.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/serial/Makefile | 5 +- drivers/serial/serial_pl01x.c | 300 +++++++++++---------- .../{serial_pl01x.h => serial_pl01x_internal.h} | 0 include/serial_pl01x.h | 27 ++ 4 files changed, 192 insertions(+), 140 deletions(-) rename drivers/serial/{serial_pl01x.h => serial_pl01x_internal.h} (100%) create mode 100644 include/serial_pl01x.h
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 9ac3496..edf6936 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -7,8 +7,11 @@
ifdef CONFIG_DM_SERIAL obj-y += serial-uclass.o +obj-$(CONFIG_PL01X_SERIAL) += serial_pl01x.o else obj-y += serial.o +obj-$(CONFIG_PL010_SERIAL) += serial_pl01x.o +obj-$(CONFIG_PL011_SERIAL) += serial_pl01x.o obj-$(CONFIG_SYS_NS16550_SERIAL) += serial_ns16550.o endif
@@ -25,8 +28,6 @@ obj-$(CONFIG_IMX_SERIAL) += serial_imx.o obj-$(CONFIG_KS8695_SERIAL) += serial_ks8695.o obj-$(CONFIG_MAX3100_SERIAL) += serial_max3100.o obj-$(CONFIG_MXC_UART) += serial_mxc.o -obj-$(CONFIG_PL010_SERIAL) += serial_pl01x.o -obj-$(CONFIG_PL011_SERIAL) += serial_pl01x.o obj-$(CONFIG_PXA_SERIAL) += serial_pxa.o obj-$(CONFIG_SA1100_SERIAL) += serial_sa1100.o obj-$(CONFIG_S3C24X0_SERIAL) += serial_s3c24x0.o diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c index dfb610e..665a0e4 100644 --- a/drivers/serial/serial_pl01x.c +++ b/drivers/serial/serial_pl01x.c @@ -12,125 +12,86 @@ /* Simple U-Boot driver for the PrimeCell PL010/PL011 UARTs */
#include <common.h> +#include <errno.h> #include <watchdog.h> #include <asm/io.h> #include <serial.h> +#include <serial_pl01x.h> #include <linux/compiler.h> -#include "serial_pl01x.h" +#include "serial_pl01x_internal.h"
-/* - * Integrator AP has two UARTs, we use the first one, at 38400-8-N-1 - * Integrator CP has two UARTs, use the first one, at 38400-8-N-1 - * Versatile PB has four UARTs. - */ -#define CONSOLE_PORT CONFIG_CONS_INDEX static volatile unsigned char *const port[] = CONFIG_PL01x_PORTS; +static enum pl01x_type pl01x_type __attribute__ ((section(".data"))); +static struct pl01x_regs *base_regs __attribute__ ((section(".data"))); #define NUM_PORTS (sizeof(port)/sizeof(port[0]))
-static void pl01x_putc (int portnum, char c); -static int pl01x_getc (int portnum); -static int pl01x_tstc (int portnum); -unsigned int baudrate = CONFIG_BAUDRATE; DECLARE_GLOBAL_DATA_PTR;
-static struct pl01x_regs *pl01x_get_regs(int portnum) +static int pl01x_putc(struct pl01x_regs *regs, char c) { - return (struct pl01x_regs *) port[portnum]; -} - -#ifdef CONFIG_PL010_SERIAL - -static int pl01x_serial_init(void) -{ - struct pl01x_regs *regs = pl01x_get_regs(CONSOLE_PORT); - unsigned int divisor; - - /* First, disable everything */ - writel(0, ®s->pl010_cr); + /* Wait until there is space in the FIFO */ + if (readl(®s->fr) & UART_PL01x_FR_TXFF) + return -EAGAIN;
- /* Set baud rate */ - switch (baudrate) { - case 9600: - divisor = UART_PL010_BAUD_9600; - break; + /* Send the character */ + writel(c, ®s->dr);
- case 19200: - divisor = UART_PL010_BAUD_9600; - break; + return 0; +}
- case 38400: - divisor = UART_PL010_BAUD_38400; - break; +static int pl01x_getc(struct pl01x_regs *regs) +{ + unsigned int data;
- case 57600: - divisor = UART_PL010_BAUD_57600; - break; + /* Wait until there is data in the FIFO */ + if (readl(®s->fr) & UART_PL01x_FR_RXFE) + return -EAGAIN;
- case 115200: - divisor = UART_PL010_BAUD_115200; - break; + data = readl(®s->dr);
- default: - divisor = UART_PL010_BAUD_38400; + /* Check for an error flag */ + if (data & 0xFFFFFF00) { + /* Clear the error */ + writel(0xFFFFFFFF, ®s->ecr); + return -1; }
- writel((divisor & 0xf00) >> 8, ®s->pl010_lcrm); - writel(divisor & 0xff, ®s->pl010_lcrl); - - /* Set the UART to be 8 bits, 1 stop bit, no parity, fifo enabled */ - writel(UART_PL010_LCRH_WLEN_8 | UART_PL010_LCRH_FEN, ®s->pl010_lcrh); - - /* Finally, enable the UART */ - writel(UART_PL010_CR_UARTEN, ®s->pl010_cr); - - return 0; + return (int) data; }
-#endif /* CONFIG_PL010_SERIAL */ - -#ifdef CONFIG_PL011_SERIAL +static int pl01x_tstc(struct pl01x_regs *regs) +{ + WATCHDOG_RESET(); + return !(readl(®s->fr) & UART_PL01x_FR_RXFE); +}
-static int pl01x_serial_init(void) +static int pl01x_generic_serial_init(struct pl01x_regs *regs, + enum pl01x_type type) { - struct pl01x_regs *regs = pl01x_get_regs(CONSOLE_PORT); - unsigned int temp; - unsigned int divider; - unsigned int remainder; - unsigned int fraction; unsigned int lcr;
#ifdef CONFIG_PL011_SERIAL_FLUSH_ON_INIT - /* Empty RX fifo if necessary */ - if (readl(®s->pl011_cr) & UART_PL011_CR_UARTEN) { - while (!(readl(®s->fr) & UART_PL01x_FR_RXFE)) - readl(®s->dr); + if (type == TYPE_PL011) { + /* Empty RX fifo if necessary */ + if (readl(®s->pl011_cr) & UART_PL011_CR_UARTEN) { + while (!(readl(®s->fr) & UART_PL01x_FR_RXFE)) + readl(®s->dr); + } } #endif
/* First, disable everything */ - writel(0, ®s->pl011_cr); - - /* - * Set baud rate - * - * IBRD = UART_CLK / (16 * BAUD_RATE) - * FBRD = RND((64 * MOD(UART_CLK,(16 * BAUD_RATE))) / (16 * BAUD_RATE)) - */ - temp = 16 * baudrate; - divider = CONFIG_PL011_CLOCK / temp; - remainder = CONFIG_PL011_CLOCK % temp; - temp = (8 * remainder) / baudrate; - fraction = (temp >> 1) + (temp & 1); - - writel(divider, ®s->pl011_ibrd); - writel(fraction, ®s->pl011_fbrd); + writel(0, ®s->pl010_cr);
/* Set the UART to be 8 bits, 1 stop bit, no parity, fifo enabled */ lcr = UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN; writel(lcr, ®s->pl011_lcrh);
+ switch (type) { + case TYPE_PL010: + break; + case TYPE_PL011: { #ifdef CONFIG_PL011_SERIAL_RLCR - { int i;
/* @@ -144,90 +105,151 @@ static int pl01x_serial_init(void) writel(lcr, ®s->pl011_rlcr); /* lcrh needs to be set again for change to be effective */ writel(lcr, ®s->pl011_lcrh); - } #endif - /* Finally, enable the UART */ - writel(UART_PL011_CR_UARTEN | UART_PL011_CR_TXE | UART_PL011_CR_RXE | - UART_PL011_CR_RTS, ®s->pl011_cr); + break; + } + default: + return -EINVAL; + }
return 0; }
-#endif /* CONFIG_PL011_SERIAL */ - -static void pl01x_serial_putc(const char c) +static int pl01x_generic_setbrg(struct pl01x_regs *regs, enum pl01x_type type, + int clock, int baudrate) { - if (c == '\n') - pl01x_putc (CONSOLE_PORT, '\r'); + switch (type) { + case TYPE_PL010: { + unsigned int divisor; + + switch (baudrate) { + case 9600: + divisor = UART_PL010_BAUD_9600; + break; + case 19200: + divisor = UART_PL010_BAUD_9600; + break; + case 38400: + divisor = UART_PL010_BAUD_38400; + break; + case 57600: + divisor = UART_PL010_BAUD_57600; + break; + case 115200: + divisor = UART_PL010_BAUD_115200; + break; + default: + divisor = UART_PL010_BAUD_38400; + } + + writel((divisor & 0xf00) >> 8, ®s->pl010_lcrm); + writel(divisor & 0xff, ®s->pl010_lcrl); + + /* Finally, enable the UART */ + writel(UART_PL010_CR_UARTEN, ®s->pl010_cr); + break; + } + case TYPE_PL011: { + unsigned int temp; + unsigned int divider; + unsigned int remainder; + unsigned int fraction;
- pl01x_putc (CONSOLE_PORT, c); -} + /* + * Set baud rate + * + * IBRD = UART_CLK / (16 * BAUD_RATE) + * FBRD = RND((64 * MOD(UART_CLK,(16 * BAUD_RATE))) + * / (16 * BAUD_RATE)) + */ + temp = 16 * baudrate; + divider = clock / temp; + remainder = clock % temp; + temp = (8 * remainder) / baudrate; + fraction = (temp >> 1) + (temp & 1); + + writel(divider, ®s->pl011_ibrd); + writel(fraction, ®s->pl011_fbrd); + + /* Finally, enable the UART */ + writel(UART_PL011_CR_UARTEN | UART_PL011_CR_TXE | + UART_PL011_CR_RXE | UART_PL011_CR_RTS, ®s->pl011_cr); + break; + } + default: + return -EINVAL; + }
-static int pl01x_serial_getc(void) -{ - return pl01x_getc (CONSOLE_PORT); + return 0; }
-static int pl01x_serial_tstc(void) +#ifndef CONFIG_DM_SERIAL +static void pl01x_serial_init_baud(int baudrate) { - return pl01x_tstc (CONSOLE_PORT); + int clock = 0; + +#if defined(CONFIG_PL010_SERIAL) + pl01x_type = TYPE_PL010; +#elif defined(CONFIG_PL011_SERIAL) + pl01x_type = TYPE_PL011; + clock = CONFIG_PL011_CLOCK; +#endif + base_regs = (struct pl01x_regs *)port[CONFIG_CONS_INDEX]; + + pl01x_generic_serial_init(base_regs, pl01x_type); + pl01x_generic_setbrg(base_regs, TYPE_PL010, clock, baudrate); }
-static void pl01x_serial_setbrg(void) +/* + * Integrator AP has two UARTs, we use the first one, at 38400-8-N-1 + * Integrator CP has two UARTs, use the first one, at 38400-8-N-1 + * Versatile PB has four UARTs. + */ +int pl01x_serial_init(void) { - struct pl01x_regs *regs = pl01x_get_regs(CONSOLE_PORT); + pl01x_serial_init_baud(CONFIG_BAUDRATE);
- baudrate = gd->baudrate; - /* - * Flush FIFO and wait for non-busy before changing baudrate to avoid - * crap in console - */ - while (!(readl(®s->fr) & UART_PL01x_FR_TXFE)) - WATCHDOG_RESET(); - while (readl(®s->fr) & UART_PL01x_FR_BUSY) - WATCHDOG_RESET(); - serial_init(); + return 0; }
-static void pl01x_putc (int portnum, char c) +static void pl01x_serial_putc(const char c) { - struct pl01x_regs *regs = pl01x_get_regs(portnum); - - /* Wait until there is space in the FIFO */ - while (readl(®s->fr) & UART_PL01x_FR_TXFF) - WATCHDOG_RESET(); + if (c == '\n') + while (pl01x_putc(base_regs, '\r') == -EAGAIN);
- /* Send the character */ - writel(c, ®s->dr); + while (pl01x_putc(base_regs, c) == -EAGAIN); }
-static int pl01x_getc (int portnum) +static int pl01x_serial_getc(void) { - struct pl01x_regs *regs = pl01x_get_regs(portnum); - unsigned int data; + while (1) { + int ch = pl01x_getc(base_regs);
- /* Wait until there is data in the FIFO */ - while (readl(®s->fr) & UART_PL01x_FR_RXFE) - WATCHDOG_RESET(); + if (ch == -EAGAIN) { + WATCHDOG_RESET(); + continue; + }
- data = readl(®s->dr); - - /* Check for an error flag */ - if (data & 0xFFFFFF00) { - /* Clear the error */ - writel(0xFFFFFFFF, ®s->ecr); - return -1; + return ch; } - - return (int) data; }
-static int pl01x_tstc (int portnum) +static int pl01x_serial_tstc(void) { - struct pl01x_regs *regs = pl01x_get_regs(portnum); + return pl01x_tstc(base_regs); +}
- WATCHDOG_RESET(); - return !(readl(®s->fr) & UART_PL01x_FR_RXFE); +static void pl01x_serial_setbrg(void) +{ + /* + * Flush FIFO and wait for non-busy before changing baudrate to avoid + * crap in console + */ + while (!(readl(&base_regs->fr) & UART_PL01x_FR_TXFE)) + WATCHDOG_RESET(); + while (readl(&base_regs->fr) & UART_PL01x_FR_BUSY) + WATCHDOG_RESET(); + pl01x_serial_init_baud(gd->baudrate); }
static struct serial_device pl01x_serial_drv = { @@ -250,3 +272,5 @@ __weak struct serial_device *default_serial_console(void) { return &pl01x_serial_drv; } + +#endif /* nCONFIG_DM_SERIAL */ diff --git a/drivers/serial/serial_pl01x.h b/drivers/serial/serial_pl01x_internal.h similarity index 100% rename from drivers/serial/serial_pl01x.h rename to drivers/serial/serial_pl01x_internal.h diff --git a/include/serial_pl01x.h b/include/serial_pl01x.h new file mode 100644 index 0000000..5e068f3 --- /dev/null +++ b/include/serial_pl01x.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2014 Google, Inc + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __serial_pl01x_h +#define __serial_pl01x_h + +enum pl01x_type { + TYPE_PL010, + TYPE_PL011, +}; + +/* + *Information about a serial port + * + * @base: Register base address + * @type: Port type + * @clock: Input clock rate, used for calculating the baud rate divisor + */ +struct pl01x_serial_platdata { + unsigned long base; + enum pl01x_type type; + unsigned int clock; +}; + +#endif

On 22 September 2014 17:30, Simon Glass sjg@chromium.org wrote:
Adjust the driver so that leaf functions take a pointer to the serial port register base. Put all the global configuration in the init function, and use the same settings from then on.
This makes it much easier to move to driver model without duplicating the code, since with driver model we use platform data rather than global settings.
The driver is compiled with either the CONFIG_PL010_SERIAL or CONFIG_PL011_SERIAL option and this determines the uart type. With driver model this needs to come in from platform data, so create a new CONFIG_PL01X_SERIAL config which brings in the driver, and adjust the driver to support both peripheral variants.
Signed-off-by: Simon Glass sjg@chromium.org
drivers/serial/Makefile | 5 +- drivers/serial/serial_pl01x.c | 300 +++++++++++---------- .../{serial_pl01x.h => serial_pl01x_internal.h} | 0 include/serial_pl01x.h | 27 ++ 4 files changed, 192 insertions(+), 140 deletions(-) rename drivers/serial/{serial_pl01x.h => serial_pl01x_internal.h} (100%) create mode 100644 include/serial_pl01x.h
Applied to u-boot-dm/master.

On Tue, Sep 23, 2014 at 1:30 AM, Simon Glass sjg@chromium.org wrote:
Adjust the driver so that leaf functions take a pointer to the serial port register base. Put all the global configuration in the init function, and use the same settings from then on.
This makes it much easier to move to driver model without duplicating the code, since with driver model we use platform data rather than global settings.
The driver is compiled with either the CONFIG_PL010_SERIAL or CONFIG_PL011_SERIAL option and this determines the uart type. With driver model this needs to come in from platform data, so create a new CONFIG_PL01X_SERIAL config which brings in the driver, and adjust the driver to support both peripheral variants.
Signed-off-by: Simon Glass sjg@chromium.org
Unfortunately this patch regresses PL010 (Integrator/AP), and I suspect it has never been tested on real-world PL010 hardware?
I'm hunting around to figure out what is causing it, any hints welcome.
Yours, Linus Walleij

On Tue, Apr 21, 2015 at 1:56 PM, Linus Walleij linus.walleij@linaro.org wrote:
On Tue, Sep 23, 2014 at 1:30 AM, Simon Glass sjg@chromium.org wrote:
Adjust the driver so that leaf functions take a pointer to the serial port register base. Put all the global configuration in the init function, and use the same settings from then on.
This makes it much easier to move to driver model without duplicating the code, since with driver model we use platform data rather than global settings.
The driver is compiled with either the CONFIG_PL010_SERIAL or CONFIG_PL011_SERIAL option and this determines the uart type. With driver model this needs to come in from platform data, so create a new CONFIG_PL01X_SERIAL config which brings in the driver, and adjust the driver to support both peripheral variants.
Signed-off-by: Simon Glass sjg@chromium.org
Unfortunately this patch regresses PL010 (Integrator/AP), and I suspect it has never been tested on real-world PL010 hardware?
I'm hunting around to figure out what is causing it, any hints welcome.
FYI: U-Boot does come up, but trying to switch baudrate from the default 38400 to 115200 with set baudrate 115200 hangs, it's as if the change never hits the hardware so the routine looking for a CR after the baudrate switch just waits. If I switch the terminal back to 38400 and hit enter it goes through and works again, and U-Boot thinks it has successfully switched to 115200, while it hasn't, really.
Kind of frustrating since I upload kernels over the serial port :P
Yours, Linus Walleij

Add driver model support in this driver, using platform data provided by the board.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/serial/serial_pl01x.c | 73 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+)
diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c index 665a0e4..e6313ad 100644 --- a/drivers/serial/serial_pl01x.c +++ b/drivers/serial/serial_pl01x.c @@ -12,6 +12,7 @@ /* Simple U-Boot driver for the PrimeCell PL010/PL011 UARTs */
#include <common.h> +#include <dm.h> #include <errno.h> #include <watchdog.h> #include <asm/io.h> @@ -20,12 +21,15 @@ #include <linux/compiler.h> #include "serial_pl01x_internal.h"
+#ifndef CONFIG_DM_SERIAL + static volatile unsigned char *const port[] = CONFIG_PL01x_PORTS; static enum pl01x_type pl01x_type __attribute__ ((section(".data"))); static struct pl01x_regs *base_regs __attribute__ ((section(".data"))); #define NUM_PORTS (sizeof(port)/sizeof(port[0]))
DECLARE_GLOBAL_DATA_PTR; +#endif
static int pl01x_putc(struct pl01x_regs *regs, char c) { @@ -274,3 +278,72 @@ __weak struct serial_device *default_serial_console(void) }
#endif /* nCONFIG_DM_SERIAL */ + +#ifdef CONFIG_DM_SERIAL + +struct pl01x_priv { + struct pl01x_regs *regs; + enum pl01x_type type; +}; + +static int pl01x_serial_setbrg(struct udevice *dev, int baudrate) +{ + struct pl01x_serial_platdata *plat = dev_get_platdata(dev); + struct pl01x_priv *priv = dev_get_priv(dev); + + pl01x_generic_setbrg(priv->regs, priv->type, plat->clock, baudrate); + + return 0; +} + +static int pl01x_serial_probe(struct udevice *dev) +{ + struct pl01x_serial_platdata *plat = dev_get_platdata(dev); + struct pl01x_priv *priv = dev_get_priv(dev); + + priv->regs = (struct pl01x_regs *)plat->base; + priv->type = plat->type; + return pl01x_generic_serial_init(priv->regs, priv->type); +} + +static int pl01x_serial_getc(struct udevice *dev) +{ + struct pl01x_priv *priv = dev_get_priv(dev); + + return pl01x_getc(priv->regs); +} + +static int pl01x_serial_putc(struct udevice *dev, const char ch) +{ + struct pl01x_priv *priv = dev_get_priv(dev); + + return pl01x_putc(priv->regs, ch); +} + +static int pl01x_serial_pending(struct udevice *dev, bool input) +{ + struct pl01x_priv *priv = dev_get_priv(dev); + unsigned int fr = readl(&priv->regs->fr); + + if (input) + return pl01x_tstc(priv->regs); + else + return fr & UART_PL01x_FR_TXFF ? 0 : 1; +} + +static const struct dm_serial_ops pl01x_serial_ops = { + .putc = pl01x_serial_putc, + .pending = pl01x_serial_pending, + .getc = pl01x_serial_getc, + .setbrg = pl01x_serial_setbrg, +}; + +U_BOOT_DRIVER(serial_pl01x) = { + .name = "serial_pl01x", + .id = UCLASS_SERIAL, + .probe = pl01x_serial_probe, + .ops = &pl01x_serial_ops, + .flags = DM_FLAG_PRE_RELOC, +}; + +#endif

On 22 September 2014 17:30, Simon Glass sjg@chromium.org wrote:
Add driver model support in this driver, using platform data provided by the board.
Signed-off-by: Simon Glass sjg@chromium.org
drivers/serial/serial_pl01x.c | 73 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+)
Applied to u-boot-dm/master.

Adjust the configuration to use the driver model version of the pl01x serial driver. Add the required platform data.
Signed-off-by: Simon Glass sjg@chromium.org ---
board/raspberrypi/rpi_b/rpi_b.c | 12 ++++++++++++ include/configs/rpi_b.h | 6 +++--- 2 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/board/raspberrypi/rpi_b/rpi_b.c b/board/raspberrypi/rpi_b/rpi_b.c index 447c940..d009abe 100644 --- a/board/raspberrypi/rpi_b/rpi_b.c +++ b/board/raspberrypi/rpi_b/rpi_b.c @@ -20,6 +20,7 @@ #include <fdt_support.h> #include <lcd.h> #include <mmc.h> +#include <serial_pl01x.h> #include <asm/gpio.h> #include <asm/arch/mbox.h> #include <asm/arch/sdhci.h> @@ -36,6 +37,17 @@ U_BOOT_DEVICE(bcm2835_gpios) = { .platdata = &gpio_platdata, };
+static const struct pl01x_serial_platdata serial_platdata = { + .base = 0x20201000, + .type = TYPE_PL011, + .clock = 3000000, +}; + +U_BOOT_DEVICE(bcm2835_serials) = { + .name = "serial_pl01x", + .platdata = &serial_platdata, +}; + struct msg_get_arm_mem { struct bcm2835_mbox_hdr hdr; struct bcm2835_mbox_tag_get_arm_mem get_arm_mem; diff --git a/include/configs/rpi_b.h b/include/configs/rpi_b.h index d9475e9..42e3a63 100644 --- a/include/configs/rpi_b.h +++ b/include/configs/rpi_b.h @@ -35,6 +35,7 @@ #define CONFIG_DM #define CONFIG_CMD_DM #define CONFIG_DM_GPIO +#define CONFIG_DM_SERIAL
/* Memory layout */ #define CONFIG_NR_DRAM_BANKS 1 @@ -52,6 +53,7 @@ CONFIG_SYS_SDRAM_SIZE - \ GENERATED_GBL_DATA_SIZE) #define CONFIG_SYS_MALLOC_LEN SZ_4M +#define CONFIG_SYS_MALLOC_F_LEN (1 << 10) #define CONFIG_SYS_MEMTEST_START 0x00100000 #define CONFIG_SYS_MEMTEST_END 0x00200000 #define CONFIG_LOADADDR 0x00200000 @@ -83,9 +85,7 @@ #define CONFIG_BCM2835_SDHCI
/* Console UART */ -#define CONFIG_PL011_SERIAL -#define CONFIG_PL011_CLOCK 3000000 -#define CONFIG_PL01x_PORTS { (void *)0x20201000 } +#define CONFIG_PL01X_SERIAL #define CONFIG_CONS_INDEX 0 #define CONFIG_BAUDRATE 115200

On 09/22/2014 05:30 PM, Simon Glass wrote:
This series adds driver model support to the GPIO and serial drivers used by Raspberry Pi, and moves Raspberry Pi over to driver model.
This requires adding driver model support to the pl01x serial driver, and replacing the bcm2835 GPIO driver with a driver model version (since there are no longer clients that don't use driver model).
See u-boot-dm.git branch rpi-working for the tree this is based on.
The series, Tested-by: Stephen Warren swarren@wwwdotorg.org
It threw me for a while that this series changes the command-line syntax from:
gpio input 18
to:
gpio input GPIO18
Hopefully that won't annoy anyone who has scripts that need to be modified... Still, that's quite minor, so the two RPi patches,
Acked-by: Stephen Warren swarren@wwwdotorg.org

Hi Stephen,
On 30 September 2014 19:41, Stephen Warren swarren@wwwdotorg.org wrote:
On 09/22/2014 05:30 PM, Simon Glass wrote:
This series adds driver model support to the GPIO and serial drivers used by Raspberry Pi, and moves Raspberry Pi over to driver model.
This requires adding driver model support to the pl01x serial driver, and replacing the bcm2835 GPIO driver with a driver model version (since there are no longer clients that don't use driver model).
See u-boot-dm.git branch rpi-working for the tree this is based on.
The series, Tested-by: Stephen Warren swarren@wwwdotorg.org
It threw me for a while that this series changes the command-line syntax from:
gpio input 18
to:
gpio input GPIO18
Hopefully that won't annoy anyone who has scripts that need to be modified... Still, that's quite minor, so the two RPi patches,
Acked-by: Stephen Warren swarren@wwwdotorg.org
Thanks for looking at this. Re the issue you raise, there is a patch for this here, part of the omap3 series:
http://patchwork.ozlabs.org/patch/392039/
Regards, Simon

On 09/30/2014 07:41 PM, Stephen Warren wrote:
On 09/22/2014 05:30 PM, Simon Glass wrote:
This series adds driver model support to the GPIO and serial drivers used by Raspberry Pi, and moves Raspberry Pi over to driver model.
This requires adding driver model support to the pl01x serial driver, and replacing the bcm2835 GPIO driver with a driver model version (since there are no longer clients that don't use driver model).
See u-boot-dm.git branch rpi-working for the tree this is based on.
The series, Tested-by: Stephen Warren swarren@wwwdotorg.org
Hmm. I take that back. Patch 4 causes a problem, at least when applied on top of u-boot/master from today.
Basic serial output works just fine, and I can interact with U-Boot without issue. However, when the boot scripts execute and load an extlinux.conf, U-Boot hangs. Up to patch 3, everything is fine.
U-Boot 2014.10-00004-g7830ed7 (Oct 17 2014 - 20:47:19)
DRAM: 480 MiB WARNING: Caches not enabled MMC: bcm2835_sdhci: 0 Using default environment
In: serial Out: lcd Err: lcd reading /uEnv.txt 24 bytes read in 14 ms (1000 Bytes/s) Hit any key to stop autoboot: 0 switch to partitions #0, OK mmc0 is current device Scanning mmc 0... Found /extlinux/extlinux.conf Retrieving file: /extlinux/extlinux.conf reading /extlinux/extlinux.conf (U-Boot hangs here)

Hi Stephen,
On 17 October 2014 20:51, Stephen Warren swarren@wwwdotorg.org wrote:
On 09/30/2014 07:41 PM, Stephen Warren wrote:
On 09/22/2014 05:30 PM, Simon Glass wrote:
This series adds driver model support to the GPIO and serial drivers used by Raspberry Pi, and moves Raspberry Pi over to driver model.
This requires adding driver model support to the pl01x serial driver, and replacing the bcm2835 GPIO driver with a driver model version (since there are no longer clients that don't use driver model).
See u-boot-dm.git branch rpi-working for the tree this is based on.
The series, Tested-by: Stephen Warren swarren@wwwdotorg.org
Hmm. I take that back. Patch 4 causes a problem, at least when applied on top of u-boot/master from today.
Basic serial output works just fine, and I can interact with U-Boot without issue. However, when the boot scripts execute and load an extlinux.conf, U-Boot hangs. Up to patch 3, everything is fine.
U-Boot 2014.10-00004-g7830ed7 (Oct 17 2014 - 20:47:19)
DRAM: 480 MiB WARNING: Caches not enabled MMC: bcm2835_sdhci: 0 Using default environment
In: serial Out: lcd Err: lcd reading /uEnv.txt 24 bytes read in 14 ms (1000 Bytes/s) Hit any key to stop autoboot: 0 switch to partitions #0, OK mmc0 is current device Scanning mmc 0... Found /extlinux/extlinux.conf Retrieving file: /extlinux/extlinux.conf reading /extlinux/extlinux.conf (U-Boot hangs here)
Can you please point me to where I can get an image to try this with? Also did you check with dm/next? There may be dependent patches, although the nature of the problem suggests not.
Regards, Simon

On 10/19/2014 09:14 PM, Simon Glass wrote:
Hi Stephen,
On 17 October 2014 20:51, Stephen Warren swarren@wwwdotorg.org wrote:
On 09/30/2014 07:41 PM, Stephen Warren wrote:
On 09/22/2014 05:30 PM, Simon Glass wrote:
This series adds driver model support to the GPIO and serial drivers used by Raspberry Pi, and moves Raspberry Pi over to driver model.
This requires adding driver model support to the pl01x serial driver, and replacing the bcm2835 GPIO driver with a driver model version (since there are no longer clients that don't use driver model).
See u-boot-dm.git branch rpi-working for the tree this is based on.
The series, Tested-by: Stephen Warren swarren@wwwdotorg.org
Hmm. I take that back. Patch 4 causes a problem, at least when applied on top of u-boot/master from today.
Basic serial output works just fine, and I can interact with U-Boot without issue. However, when the boot scripts execute and load an extlinux.conf, U-Boot hangs. Up to patch 3, everything is fine.
U-Boot 2014.10-00004-g7830ed7 (Oct 17 2014 - 20:47:19)
DRAM: 480 MiB WARNING: Caches not enabled MMC: bcm2835_sdhci: 0 Using default environment
In: serial Out: lcd Err: lcd reading /uEnv.txt 24 bytes read in 14 ms (1000 Bytes/s) Hit any key to stop autoboot: 0 switch to partitions #0, OK mmc0 is current device Scanning mmc 0... Found /extlinux/extlinux.conf Retrieving file: /extlinux/extlinux.conf reading /extlinux/extlinux.conf (U-Boot hangs here)
Can you please point me to where I can get an image to try this with? Also did you check with dm/next? There may be dependent patches, although the nature of the problem suggests not.
I use (a pretty old version of, but I doubt that matters) RPi Foundation's Raspbian image, and compiled the kernel and U-Boot according to:
http://elinux.org/index.php?title=RPi_Upstream_Kernel_Compilation&oldid=...

Hi Stephen,
On 20 October 2014 20:23, Stephen Warren swarren@wwwdotorg.org wrote:
On 10/19/2014 09:14 PM, Simon Glass wrote:
Hi Stephen,
On 17 October 2014 20:51, Stephen Warren swarren@wwwdotorg.org wrote:
On 09/30/2014 07:41 PM, Stephen Warren wrote:
On 09/22/2014 05:30 PM, Simon Glass wrote:
This series adds driver model support to the GPIO and serial drivers used by Raspberry Pi, and moves Raspberry Pi over to driver model.
This requires adding driver model support to the pl01x serial driver, and replacing the bcm2835 GPIO driver with a driver model version (since there are no longer clients that don't use driver model).
See u-boot-dm.git branch rpi-working for the tree this is based on.
The series, Tested-by: Stephen Warren swarren@wwwdotorg.org
Hmm. I take that back. Patch 4 causes a problem, at least when applied on top of u-boot/master from today.
Basic serial output works just fine, and I can interact with U-Boot without issue. However, when the boot scripts execute and load an extlinux.conf, U-Boot hangs. Up to patch 3, everything is fine.
U-Boot 2014.10-00004-g7830ed7 (Oct 17 2014 - 20:47:19)
DRAM: 480 MiB WARNING: Caches not enabled MMC: bcm2835_sdhci: 0 Using default environment
In: serial Out: lcd Err: lcd reading /uEnv.txt 24 bytes read in 14 ms (1000 Bytes/s) Hit any key to stop autoboot: 0 switch to partitions #0, OK mmc0 is current device Scanning mmc 0... Found /extlinux/extlinux.conf Retrieving file: /extlinux/extlinux.conf reading /extlinux/extlinux.conf (U-Boot hangs here)
Can you please point me to where I can get an image to try this with? Also did you check with dm/next? There may be dependent patches, although the nature of the problem suggests not.
I use (a pretty old version of, but I doubt that matters) RPi Foundation's Raspbian image, and compiled the kernel and U-Boot according to:
http://elinux.org/index.php?title=RPi_Upstream_Kernel_Compilation&oldid=...
I installed the Raspbian image but I don't get uImg.txt nor the same boot sequence. I am able to boot a kernel though.
Do you have your settings or images uploaded somewhere? Also please confirm you used dm/next.
Regards, Simon

Hi Stephen,
On 21 October 2014 20:04, Simon Glass sjg@chromium.org wrote:
Hi Stephen,
On 20 October 2014 20:23, Stephen Warren swarren@wwwdotorg.org wrote:
On 10/19/2014 09:14 PM, Simon Glass wrote:
Hi Stephen,
On 17 October 2014 20:51, Stephen Warren swarren@wwwdotorg.org wrote:
On 09/30/2014 07:41 PM, Stephen Warren wrote:
On 09/22/2014 05:30 PM, Simon Glass wrote:
This series adds driver model support to the GPIO and serial drivers used by Raspberry Pi, and moves Raspberry Pi over to driver model.
This requires adding driver model support to the pl01x serial driver, and replacing the bcm2835 GPIO driver with a driver model version (since there are no longer clients that don't use driver model).
See u-boot-dm.git branch rpi-working for the tree this is based on.
The series, Tested-by: Stephen Warren swarren@wwwdotorg.org
Hmm. I take that back. Patch 4 causes a problem, at least when applied on top of u-boot/master from today.
Basic serial output works just fine, and I can interact with U-Boot without issue. However, when the boot scripts execute and load an extlinux.conf, U-Boot hangs. Up to patch 3, everything is fine.
U-Boot 2014.10-00004-g7830ed7 (Oct 17 2014 - 20:47:19)
DRAM: 480 MiB WARNING: Caches not enabled MMC: bcm2835_sdhci: 0 Using default environment
In: serial Out: lcd Err: lcd reading /uEnv.txt 24 bytes read in 14 ms (1000 Bytes/s) Hit any key to stop autoboot: 0 switch to partitions #0, OK mmc0 is current device Scanning mmc 0... Found /extlinux/extlinux.conf Retrieving file: /extlinux/extlinux.conf reading /extlinux/extlinux.conf (U-Boot hangs here)
Can you please point me to where I can get an image to try this with? Also did you check with dm/next? There may be dependent patches, although the nature of the problem suggests not.
I use (a pretty old version of, but I doubt that matters) RPi Foundation's Raspbian image, and compiled the kernel and U-Boot according to:
http://elinux.org/index.php?title=RPi_Upstream_Kernel_Compilation&oldid=...
I installed the Raspbian image but I don't get uImg.txt nor the same boot sequence. I am able to boot a kernel though.
Do you have your settings or images uploaded somewhere? Also please confirm you used dm/next.
I've had to leave this last (4/4) patch out of the pull request for now. See u-boot-dm/rpi_working if you would like to try it again.
Regards, Simon

On 10/21/2014 08:04 PM, Simon Glass wrote:
Hi Stephen,
On 20 October 2014 20:23, Stephen Warren swarren@wwwdotorg.org wrote:
On 10/19/2014 09:14 PM, Simon Glass wrote:
Hi Stephen,
On 17 October 2014 20:51, Stephen Warren swarren@wwwdotorg.org wrote:
On 09/30/2014 07:41 PM, Stephen Warren wrote:
On 09/22/2014 05:30 PM, Simon Glass wrote:
This series adds driver model support to the GPIO and serial drivers used by Raspberry Pi, and moves Raspberry Pi over to driver model.
This requires adding driver model support to the pl01x serial driver, and replacing the bcm2835 GPIO driver with a driver model version (since there are no longer clients that don't use driver model).
See u-boot-dm.git branch rpi-working for the tree this is based on.
The series, Tested-by: Stephen Warren swarren@wwwdotorg.org
Hmm. I take that back. Patch 4 causes a problem, at least when applied on top of u-boot/master from today.
Basic serial output works just fine, and I can interact with U-Boot without issue. However, when the boot scripts execute and load an extlinux.conf, U-Boot hangs. Up to patch 3, everything is fine.
U-Boot 2014.10-00004-g7830ed7 (Oct 17 2014 - 20:47:19)
DRAM: 480 MiB WARNING: Caches not enabled MMC: bcm2835_sdhci: 0 Using default environment
In: serial Out: lcd Err: lcd reading /uEnv.txt 24 bytes read in 14 ms (1000 Bytes/s) Hit any key to stop autoboot: 0 switch to partitions #0, OK mmc0 is current device Scanning mmc 0... Found /extlinux/extlinux.conf Retrieving file: /extlinux/extlinux.conf reading /extlinux/extlinux.conf (U-Boot hangs here)
Can you please point me to where I can get an image to try this with? Also did you check with dm/next? There may be dependent patches, although the nature of the problem suggests not.
I use (a pretty old version of, but I doubt that matters) RPi Foundation's Raspbian image, and compiled the kernel and U-Boot according to:
http://elinux.org/index.php?title=RPi_Upstream_Kernel_Compilation&oldid=...
I installed the Raspbian image but I don't get uImg.txt nor the same boot sequence. I am able to boot a kernel though.
The RPi Foundation images boot their kernel directly from their binary firmware, and hence don't include any U-Boot or U-Boot boot scripts.
I haven't used boot.scr for a while, but this is apparently what's in mine:
load ${devtype} ${devnum}:1 ${kernel_addr_r} /zImage load ${devtype} ${devnum}:1 ${fdt_addr_r} /${fdtfile} setenv bootargs "earlyprintk loglevel=8 console=ttyAMA0 console=tty1 \ verbose rootwait root=/dev/mmcblk0p2 rw" bootz ${kernel_addr_r} - ${fdt_addr_r}
I use extlinux/extlinux.conf now, with the following content:
TIMEOUT 100 DEFAULT default MENU TITLE Boot menu
LABEL default MENU LABEL Default kernel LINUX ../zImage FDTDIR ../ APPEND earlyprintk loglevel=8 console=ttyAMA0 console=tty1 verbose \ rootwait root=/dev/mmcblk0p2 rw
LABEL fallback MENU LABEL Backup kernel LINUX ../backup/zImage FDTDIR ../backup/ APPEND earlyprintk loglevel=8 console=ttyAMA0 console=tty1 verbose \ rootwait root=/dev/mmcblk0p2 rw
(in both cases, the continuation lines are all on one line; I only split them for email purposes)

On 10/21/2014 08:04 PM, Simon Glass wrote:
Hi Stephen,
On 20 October 2014 20:23, Stephen Warren swarren@wwwdotorg.org wrote:
On 10/19/2014 09:14 PM, Simon Glass wrote:
Hi Stephen,
On 17 October 2014 20:51, Stephen Warren swarren@wwwdotorg.org wrote:
On 09/30/2014 07:41 PM, Stephen Warren wrote:
On 09/22/2014 05:30 PM, Simon Glass wrote:
This series adds driver model support to the GPIO and serial drivers used by Raspberry Pi, and moves Raspberry Pi over to driver model.
This requires adding driver model support to the pl01x serial driver, and replacing the bcm2835 GPIO driver with a driver model version (since there are no longer clients that don't use driver model).
See u-boot-dm.git branch rpi-working for the tree this is based on.
The series, Tested-by: Stephen Warren swarren@wwwdotorg.org
Hmm. I take that back. Patch 4 causes a problem, at least when applied on top of u-boot/master from today.
Basic serial output works just fine, and I can interact with U-Boot without issue. However, when the boot scripts execute and load an extlinux.conf, U-Boot hangs. Up to patch 3, everything is fine.
U-Boot 2014.10-00004-g7830ed7 (Oct 17 2014 - 20:47:19)
DRAM: 480 MiB WARNING: Caches not enabled MMC: bcm2835_sdhci: 0 Using default environment
In: serial Out: lcd Err: lcd reading /uEnv.txt 24 bytes read in 14 ms (1000 Bytes/s) Hit any key to stop autoboot: 0 switch to partitions #0, OK mmc0 is current device Scanning mmc 0... Found /extlinux/extlinux.conf Retrieving file: /extlinux/extlinux.conf reading /extlinux/extlinux.conf (U-Boot hangs here)
Can you please point me to where I can get an image to try this with? Also did you check with dm/next? There may be dependent patches, although the nature of the problem suggests not.
I use (a pretty old version of, but I doubt that matters) RPi Foundation's Raspbian image, and compiled the kernel and U-Boot according to:
http://elinux.org/index.php?title=RPi_Upstream_Kernel_Compilation&oldid=...
I installed the Raspbian image but I don't get uImg.txt nor the same boot sequence. I am able to boot a kernel though.
Do you have your settings or images uploaded somewhere? Also please confirm you used dm/next.
FWIW, the content in the following branches does seem to work:
u-boot/master 5b3ee38 kbuild: clear VENDOR variable to fix build error on tcsh
u-boot-dm/master c2ded96 serial: remove uniphier_serial_initialize() call

Hi Stephen,
On Oct 25, 2014 9:43 PM, "Stephen Warren" swarren@wwwdotorg.org wrote:
On 10/21/2014 08:04 PM, Simon Glass wrote:
Hi Stephen,
On 20 October 2014 20:23, Stephen Warren swarren@wwwdotorg.org wrote:
On 10/19/2014 09:14 PM, Simon Glass wrote:
Hi Stephen,
On 17 October 2014 20:51, Stephen Warren swarren@wwwdotorg.org
wrote:
On 09/30/2014 07:41 PM, Stephen Warren wrote:
On 09/22/2014 05:30 PM, Simon Glass wrote: > This series adds driver model support to the GPIO and serial
drivers used
> by Raspberry Pi, and moves Raspberry Pi over to driver model. > > This requires adding driver model support to the pl01x serial
driver, and
> replacing the bcm2835 GPIO driver with a driver model version
(since there
> are no longer clients that don't use driver model). > > See u-boot-dm.git branch rpi-working for the tree this is based on.
The series, Tested-by: Stephen Warren swarren@wwwdotorg.org
Hmm. I take that back. Patch 4 causes a problem, at least when
applied
on top of u-boot/master from today.
Basic serial output works just fine, and I can interact with U-Boot without issue. However, when the boot scripts execute and load an extlinux.conf, U-Boot hangs. Up to patch 3, everything is fine.
U-Boot 2014.10-00004-g7830ed7 (Oct 17 2014 - 20:47:19)
DRAM: 480 MiB WARNING: Caches not enabled MMC: bcm2835_sdhci: 0 Using default environment
In: serial Out: lcd Err: lcd reading /uEnv.txt 24 bytes read in 14 ms (1000 Bytes/s) Hit any key to stop autoboot: 0 switch to partitions #0, OK mmc0 is current device Scanning mmc 0... Found /extlinux/extlinux.conf Retrieving file: /extlinux/extlinux.conf reading /extlinux/extlinux.conf (U-Boot hangs here)
Can you please point me to where I can get an image to try this with? Also did you check with dm/next? There may be dependent patches, although the nature of the problem suggests not.
I use (a pretty old version of, but I doubt that matters) RPi Foundation's Raspbian image, and compiled the kernel and U-Boot according to:
http://elinux.org/index.php?title=RPi_Upstream_Kernel_Compilation&oldid=...
I installed the Raspbian image but I don't get uImg.txt nor the same boot sequence. I am able to boot a kernel though.
Do you have your settings or images uploaded somewhere? Also please confirm you used dm/next.
FWIW, the content in the following branches does seem to work:
u-boot/master 5b3ee38 kbuild: clear VENDOR variable to fix build error on tcsh
u-boot-dm/master c2ded96 serial: remove uniphier_serial_initialize() call
In what way?
Regards, Simon

On 10/25/2014 09:47 PM, Simon Glass wrote:
Hi Stephen,
On Oct 25, 2014 9:43 PM, "Stephen Warren" <swarren@wwwdotorg.org mailto:swarren@wwwdotorg.org> wrote:
On 10/21/2014 08:04 PM, Simon Glass wrote:
Hi Stephen,
On 20 October 2014 20:23, Stephen Warren <swarren@wwwdotorg.org
mailto:swarren@wwwdotorg.org> wrote:
On 10/19/2014 09:14 PM, Simon Glass wrote:
Hi Stephen,
On 17 October 2014 20:51, Stephen Warren <swarren@wwwdotorg.org
mailto:swarren@wwwdotorg.org> wrote:
On 09/30/2014 07:41 PM, Stephen Warren wrote: > On 09/22/2014 05:30 PM, Simon Glass wrote: >> This series adds driver model support to the GPIO and serial
drivers used
>> by Raspberry Pi, and moves Raspberry Pi over to driver model. >> >> This requires adding driver model support to the pl01x serial
driver, and
>> replacing the bcm2835 GPIO driver with a driver model version
(since there
>> are no longer clients that don't use driver model). >> >> See u-boot-dm.git branch rpi-working for the tree this is based on. > > The series, > Tested-by: Stephen Warren <swarren@wwwdotorg.org
Hmm. I take that back. Patch 4 causes a problem, at least when
applied
on top of u-boot/master from today.
Basic serial output works just fine, and I can interact with U-Boot without issue. However, when the boot scripts execute and load an extlinux.conf, U-Boot hangs. Up to patch 3, everything is fine.
U-Boot 2014.10-00004-g7830ed7 (Oct 17 2014 - 20:47:19)
DRAM: 480 MiB WARNING: Caches not enabled MMC: bcm2835_sdhci: 0 Using default environment
In: serial Out: lcd Err: lcd reading /uEnv.txt 24 bytes read in 14 ms (1000 Bytes/s) Hit any key to stop autoboot: 0 switch to partitions #0, OK mmc0 is current device Scanning mmc 0... Found /extlinux/extlinux.conf Retrieving file: /extlinux/extlinux.conf reading /extlinux/extlinux.conf (U-Boot hangs here)
Can you please point me to where I can get an image to try this with? Also did you check with dm/next? There may be dependent patches, although the nature of the problem suggests not.
I use (a pretty old version of, but I doubt that matters) RPi Foundation's Raspbian image, and compiled the kernel and U-Boot according to:
http://elinux.org/index.php?title=RPi_Upstream_Kernel_Compilation&oldid=...
I installed the Raspbian image but I don't get uImg.txt nor the same boot sequence. I am able to boot a kernel though.
Do you have your settings or images uploaded somewhere? Also please confirm you used dm/next.
FWIW, the content in the following branches does seem to work:
u-boot/master 5b3ee38 kbuild: clear VENDOR variable to fix build error on tcsh
u-boot-dm/master c2ded96 serial: remove uniphier_serial_initialize() call
In what way?
I ran U-Boot, and let it boot a kernel via extlinux.conf.
Note that I said it worked, not that it failed.

Hi Stephen,
On 25 Oct 2014 23:08, "Stephen Warren" swarren@wwwdotorg.org wrote:
On 10/25/2014 09:47 PM, Simon Glass wrote:
Hi Stephen,
On Oct 25, 2014 9:43 PM, "Stephen Warren" <swarren@wwwdotorg.org mailto:swarren@wwwdotorg.org> wrote:
On 10/21/2014 08:04 PM, Simon Glass wrote:
Hi Stephen,
On 20 October 2014 20:23, Stephen Warren <swarren@wwwdotorg.org
mailto:swarren@wwwdotorg.org> wrote:
On 10/19/2014 09:14 PM, Simon Glass wrote:
Hi Stephen,
On 17 October 2014 20:51, Stephen Warren <swarren@wwwdotorg.org
mailto:swarren@wwwdotorg.org> wrote:
> On 09/30/2014 07:41 PM, Stephen Warren wrote: >> On 09/22/2014 05:30 PM, Simon Glass wrote: >>> This series adds driver model support to the GPIO and serial
drivers used
>>> by Raspberry Pi, and moves Raspberry Pi over to driver model. >>> >>> This requires adding driver model support to the pl01x serial
driver, and
>>> replacing the bcm2835 GPIO driver with a driver model version
(since there
>>> are no longer clients that don't use driver model). >>> >>> See u-boot-dm.git branch rpi-working for the tree this is based
on.
>> >> The series, >> Tested-by: Stephen Warren <swarren@wwwdotorg.org
> > Hmm. I take that back. Patch 4 causes a problem, at least when
applied
> on top of u-boot/master from today. > > Basic serial output works just fine, and I can interact with
U-Boot
> without issue. However, when the boot scripts execute and load an > extlinux.conf, U-Boot hangs. Up to patch 3, everything is fine. > > U-Boot 2014.10-00004-g7830ed7 (Oct 17 2014 - 20:47:19) > > DRAM: 480 MiB > WARNING: Caches not enabled > MMC: bcm2835_sdhci: 0 > Using default environment > > In: serial > Out: lcd > Err: lcd > reading /uEnv.txt > 24 bytes read in 14 ms (1000 Bytes/s) > Hit any key to stop autoboot: 0 > switch to partitions #0, OK > mmc0 is current device > Scanning mmc 0... > Found /extlinux/extlinux.conf > Retrieving file: /extlinux/extlinux.conf > reading /extlinux/extlinux.conf > (U-Boot hangs here) >
Can you please point me to where I can get an image to try this
with?
Also did you check with dm/next? There may be dependent patches, although the nature of the problem suggests not.
I use (a pretty old version of, but I doubt that matters) RPi Foundation's Raspbian image, and compiled the kernel and U-Boot according to:
http://elinux.org/index.php?title=RPi_Upstream_Kernel_Compilation&oldid=...
I installed the Raspbian image but I don't get uImg.txt nor the same boot sequence. I am able to boot a kernel though.
Do you have your settings or images uploaded somewhere? Also please confirm you used dm/next.
FWIW, the content in the following branches does seem to work:
u-boot/master 5b3ee38 kbuild: clear VENDOR variable to fix build error on tcsh
u-boot-dm/master c2ded96 serial: remove uniphier_serial_initialize() call
In what way?
I ran U-Boot, and let it boot a kernel via extlinux.conf.
Ok that is probably just because I didn't pull in the patch you said was a problem.
Note that I said it worked, not that it failed.
I did misread this...
Regards, Simon

Hi,
On 25 October 2014 at 23:10, Simon Glass sjg@chromium.org wrote:
Hi Stephen,
On 25 Oct 2014 23:08, "Stephen Warren" swarren@wwwdotorg.org wrote:
On 10/25/2014 09:47 PM, Simon Glass wrote:
Hi Stephen,
On Oct 25, 2014 9:43 PM, "Stephen Warren" <swarren@wwwdotorg.org mailto:swarren@wwwdotorg.org> wrote:
On 10/21/2014 08:04 PM, Simon Glass wrote:
Hi Stephen,
On 20 October 2014 20:23, Stephen Warren <swarren@wwwdotorg.org
mailto:swarren@wwwdotorg.org> wrote:
On 10/19/2014 09:14 PM, Simon Glass wrote: > Hi Stephen, > > On 17 October 2014 20:51, Stephen Warren <swarren@wwwdotorg.org
mailto:swarren@wwwdotorg.org> wrote:
>> On 09/30/2014 07:41 PM, Stephen Warren wrote: >>> On 09/22/2014 05:30 PM, Simon Glass wrote: >>>> This series adds driver model support to the GPIO and serial
drivers used
>>>> by Raspberry Pi, and moves Raspberry Pi over to driver model. >>>> >>>> This requires adding driver model support to the pl01x serial
driver, and
>>>> replacing the bcm2835 GPIO driver with a driver model version
(since there
>>>> are no longer clients that don't use driver model). >>>> >>>> See u-boot-dm.git branch rpi-working for the tree this is based >>>> on. >>> >>> The series, >>> Tested-by: Stephen Warren <swarren@wwwdotorg.org
>> >> Hmm. I take that back. Patch 4 causes a problem, at least when
applied
>> on top of u-boot/master from today. >> >> Basic serial output works just fine, and I can interact with >> U-Boot >> without issue. However, when the boot scripts execute and load an >> extlinux.conf, U-Boot hangs. Up to patch 3, everything is fine. >> >> U-Boot 2014.10-00004-g7830ed7 (Oct 17 2014 - 20:47:19) >> >> DRAM: 480 MiB >> WARNING: Caches not enabled >> MMC: bcm2835_sdhci: 0 >> Using default environment >> >> In: serial >> Out: lcd >> Err: lcd >> reading /uEnv.txt >> 24 bytes read in 14 ms (1000 Bytes/s) >> Hit any key to stop autoboot: 0 >> switch to partitions #0, OK >> mmc0 is current device >> Scanning mmc 0... >> Found /extlinux/extlinux.conf >> Retrieving file: /extlinux/extlinux.conf >> reading /extlinux/extlinux.conf >> (U-Boot hangs here) >> > > Can you please point me to where I can get an image to try this > with? > Also did you check with dm/next? There may be dependent patches, > although the nature of the problem suggests not.
I use (a pretty old version of, but I doubt that matters) RPi Foundation's Raspbian image, and compiled the kernel and U-Boot according to:
http://elinux.org/index.php?title=RPi_Upstream_Kernel_Compilation&oldid=...
I installed the Raspbian image but I don't get uImg.txt nor the same boot sequence. I am able to boot a kernel though.
Do you have your settings or images uploaded somewhere? Also please confirm you used dm/next.
FWIW, the content in the following branches does seem to work:
u-boot/master 5b3ee38 kbuild: clear VENDOR variable to fix build error on tcsh
u-boot-dm/master c2ded96 serial: remove uniphier_serial_initialize() call
In what way?
I ran U-Boot, and let it boot a kernel via extlinux.conf.
Ok that is probably just because I didn't pull in the patch you said was a problem.
Note that I said it worked, not that it failed.
I did misread this...
Regards, Simon
I started a new thread here:
http://u-boot.10912.n7.nabble.com/Raspberry-Pi-with-driver-model-td197255.ht...
Regards, Simon
participants (3)
-
Linus Walleij
-
Simon Glass
-
Stephen Warren