Message ID | 1427797085-30884-1-git-send-email-abrodkin@synopsys.com |
---|---|
State | Accepted, archived |
Delegated to: | Alexey Brodkin |
Headers | show |
On Tue, 2015-03-31 at 13:18 +0300, Alexey Brodkin wrote: > Now when all infrastructure in ARC is ready for it let's switch ARC UART > to driver model. > > Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com> > Cc: Masahiro Yamada <yamada.masahiro@socionext.com> > Cc: Simon Glass <sjg@chromium.org> Applied, thanks. -Alexey
Hi Alexey, On 31 March 2015 at 04:18, Alexey Brodkin <Alexey.Brodkin@synopsys.com> wrote: > > Now when all infrastructure in ARC is ready for it let's switch ARC UART > to driver model. > > Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com> > Cc: Masahiro Yamada <yamada.masahiro@socionext.com> > Cc: Simon Glass <sjg@chromium.org> > --- > arch/Kconfig | 1 + > arch/arc/dts/Makefile | 11 +++++ > arch/arc/dts/arcangel4.dts | 24 ++++++++++ > arch/arc/dts/skeleton.dtsi | 13 ++++++ > configs/arcangel4-be_defconfig | 5 ++ > configs/arcangel4_defconfig | 5 ++ > drivers/serial/serial_arc.c | 102 ++++++++++++++++++++++++++++------------- > 7 files changed, 129 insertions(+), 32 deletions(-) > create mode 100644 arch/arc/dts/Makefile > create mode 100644 arch/arc/dts/arcangel4.dts > create mode 100644 arch/arc/dts/skeleton.dtsi > > diff --git a/arch/Kconfig b/arch/Kconfig > index ca617e7..2ca5305 100644 > --- a/arch/Kconfig > +++ b/arch/Kconfig > @@ -14,6 +14,7 @@ config ARC > select HAVE_PRIVATE_LIBGCC > select HAVE_GENERIC_BOARD > select SYS_GENERIC_BOARD > + select SUPPORT_OF_CONTROL > > config ARM > bool "ARM architecture" > diff --git a/arch/arc/dts/Makefile b/arch/arc/dts/Makefile > new file mode 100644 > index 0000000..a155311 > --- /dev/null > +++ b/arch/arc/dts/Makefile > @@ -0,0 +1,11 @@ > +dtb-$(CONFIG_TARGET_ARCANGEL4) += arcangel4.dtb > + > +targets += $(dtb-y) > + > +DTC_FLAGS += -R 4 -p 0x1000 > + > +PHONY += dtbs > +dtbs: $(addprefix $(obj)/, $(dtb-y)) > + @: > + > +clean-files := *.dtb > diff --git a/arch/arc/dts/arcangel4.dts b/arch/arc/dts/arcangel4.dts > new file mode 100644 > index 0000000..bfcb9d8 > --- /dev/null > +++ b/arch/arc/dts/arcangel4.dts > @@ -0,0 +1,24 @@ > +/* > + * Copyright (C) 2015 Synopsys, Inc. (www.synopsys.com) > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > +/dts-v1/; > + > +#include "skeleton.dtsi" > + > +/ { > + #address-cells = <1>; > + #size-cells = <1>; > + > + aliases { > + console = &arcuart0; > + }; > + > + arcuart0: serial@0xc0fc1000 { > + compatible = "snps,arc-uart"; > + reg = <0xc0fc1000 0x100>; > + clock-frequency = <80000000>; > + }; > + > +}; > diff --git a/arch/arc/dts/skeleton.dtsi b/arch/arc/dts/skeleton.dtsi > new file mode 100644 > index 0000000..b41d241 > --- /dev/null > +++ b/arch/arc/dts/skeleton.dtsi > @@ -0,0 +1,13 @@ > +/* > + * Skeleton device tree; the bare minimum needed to boot; just include and > + * add a compatible value. The bootloader will typically populate the memory > + * node. > + */ > + > +/ { > + #address-cells = <1>; > + #size-cells = <1>; > + chosen { }; > + aliases { }; > + memory { device_type = "memory"; reg = <0 0>; }; > +}; > diff --git a/configs/arcangel4-be_defconfig b/configs/arcangel4-be_defconfig > index 990c74a..36ea6be 100644 > --- a/configs/arcangel4-be_defconfig > +++ b/configs/arcangel4-be_defconfig > @@ -1,5 +1,10 @@ > CONFIG_ARC=y > CONFIG_CPU_BIG_ENDIAN=y > CONFIG_TARGET_ARCANGEL4=y > +CONFIG_DM=y > +CONFIG_DM_SERIAL=y > +CONFIG_DEFAULT_DEVICE_TREE="arcangel4" > CONFIG_SYS_TEXT_BASE=0x81000000 > CONFIG_SYS_CLK_FREQ=70000000 > +CONFIG_OF_CONTROL=y > +CONFIG_OF_EMBED=y > diff --git a/configs/arcangel4_defconfig b/configs/arcangel4_defconfig > index fbc0ffe..75a91c8 100644 > --- a/configs/arcangel4_defconfig > +++ b/configs/arcangel4_defconfig > @@ -1,4 +1,9 @@ > CONFIG_ARC=y > CONFIG_TARGET_ARCANGEL4=y > +CONFIG_DM=y > +CONFIG_DM_SERIAL=y > +CONFIG_DEFAULT_DEVICE_TREE="arcangel4" > CONFIG_SYS_TEXT_BASE=0x81000000 > CONFIG_SYS_CLK_FREQ=70000000 > +CONFIG_OF_CONTROL=y > +CONFIG_OF_EMBED=y > diff --git a/drivers/serial/serial_arc.c b/drivers/serial/serial_arc.c > index 0ee8ce5..54e596c 100644 > --- a/drivers/serial/serial_arc.c > +++ b/drivers/serial/serial_arc.c > @@ -8,6 +8,7 @@ > */ > > #include <common.h> > +#include <dm.h> > #include <serial.h> > > DECLARE_GLOBAL_DATA_PTR; > @@ -23,21 +24,23 @@ struct arc_serial_regs { > unsigned int baudh; > }; > > + > +struct arc_serial_platdata { > + struct arc_serial_regs *reg; > + unsigned int uartclk; > +}; > + > /* Bit definitions of STATUS register */ > #define UART_RXEMPTY (1 << 5) > #define UART_OVERFLOW_ERR (1 << 1) > #define UART_TXEMPTY (1 << 7) > > -struct arc_serial_regs *regs = (struct arc_serial_regs *)CONFIG_ARC_UART_BASE; > - > -static void arc_serial_setbrg(void) > +static int arc_serial_setbrg(struct udevice *dev, int baudrate) > { > - int arc_console_baud; > + struct arc_serial_platdata *plat = dev->platdata; > + struct arc_serial_regs *const regs = plat->reg; > + int arc_console_baud = gd->cpu_clk / (baudrate * 4) - 1; > > - if (!gd->baudrate) > - gd->baudrate = CONFIG_BAUDRATE; > - > - arc_console_baud = gd->cpu_clk / (gd->baudrate * 4) - 1; > writeb(arc_console_baud & 0xff, ®s->baudl); > > #ifdef CONFIG_ARC > @@ -56,33 +59,49 @@ static void arc_serial_setbrg(void) > #else > writeb((arc_console_baud & 0xff00) >> 8, ®s->baudh); > #endif > -} > > -static int arc_serial_init(void) > -{ > - serial_setbrg(); > return 0; > } > > -static void arc_serial_putc(const char c) > +static int arc_serial_putc(struct udevice *dev, const char c) > { > + struct arc_serial_platdata *plat = dev->platdata; > + struct arc_serial_regs *const regs = plat->reg; > + > if (c == '\n') > - arc_serial_putc('\r'); > + arc_serial_putc(dev, '\r'); In the driver model case this is done in the uclass. > > while (!(readb(®s->status) & UART_TXEMPTY)) > ; > > writeb(c, ®s->data); > + > + return 0; > } > > -static int arc_serial_tstc(void) > +static int arc_serial_tstc(struct arc_serial_regs *const regs) > { > return !(readb(®s->status) & UART_RXEMPTY); > } > > -static int arc_serial_getc(void) > +static int arc_serial_pending(struct udevice *dev, bool input) > +{ > + struct arc_serial_platdata *plat = dev->platdata; > + struct arc_serial_regs *const regs = plat->reg; > + uint32_t status = readb(®s->status); > + > + if (input) > + return status & UART_RXEMPTY ? 0 : 1; > + else > + return status & UART_TXEMPTY ? 0 : 1; > +} > + > +static int arc_serial_getc(struct udevice *dev) > { > - while (!arc_serial_tstc()) > + struct arc_serial_platdata *plat = dev->platdata; > + struct arc_serial_regs *const regs = plat->reg; > + > + while (!arc_serial_tstc(regs)) > ; This should return -EAGAIN and should not have a loop here. > > /* Check for overflow errors */ > @@ -92,23 +111,42 @@ static int arc_serial_getc(void) > return readb(®s->data) & 0xFF; > } > > -static struct serial_device arc_serial_drv = { > - .name = "arc_serial", > - .start = arc_serial_init, > - .stop = NULL, > - .setbrg = arc_serial_setbrg, > - .putc = arc_serial_putc, > - .puts = default_serial_puts, > - .getc = arc_serial_getc, > - .tstc = arc_serial_tstc, > -}; > - > -void arc_serial_initialize(void) > +static int arc_serial_probe(struct udevice *dev) > { > - serial_register(&arc_serial_drv); > + return 0; > } > > -__weak struct serial_device *default_serial_console(void) > +static const struct dm_serial_ops arc_serial_ops = { > + .putc = arc_serial_putc, > + .pending = arc_serial_pending, > + .getc = arc_serial_getc, > + .setbrg = arc_serial_setbrg, > +}; > + > +static const struct udevice_id arc_serial_ids[] = { > + { .compatible = "snps,arc-uart" }, > + { } > +}; > + > +static int arc_serial_ofdata_to_platdata(struct udevice *dev) > { > - return &arc_serial_drv; > + struct arc_serial_platdata *plat = dev_get_platdata(dev); > + DECLARE_GLOBAL_DATA_PTR; > + > + plat->reg = (struct arc_serial_regs *)fdtdec_get_addr(gd->fdt_blob, > + dev->of_offset, "reg"); > + plat->uartclk = fdtdec_get_int(gd->fdt_blob, dev->of_offset, > + "clock-frequency", 0); > + > + return 0; > } > + > +U_BOOT_DRIVER(serial_arc) = { > + .name = "serial_arc", > + .id = UCLASS_SERIAL, > + .of_match = arc_serial_ids, > + .ofdata_to_platdata = arc_serial_ofdata_to_platdata, > + .probe = arc_serial_probe, > + .ops = &arc_serial_ops, > + .flags = DM_FLAG_PRE_RELOC, > +}; > -- > 2.1.0 > Regards, Simon
diff --git a/arch/Kconfig b/arch/Kconfig index ca617e7..2ca5305 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -14,6 +14,7 @@ config ARC select HAVE_PRIVATE_LIBGCC select HAVE_GENERIC_BOARD select SYS_GENERIC_BOARD + select SUPPORT_OF_CONTROL config ARM bool "ARM architecture" diff --git a/arch/arc/dts/Makefile b/arch/arc/dts/Makefile new file mode 100644 index 0000000..a155311 --- /dev/null +++ b/arch/arc/dts/Makefile @@ -0,0 +1,11 @@ +dtb-$(CONFIG_TARGET_ARCANGEL4) += arcangel4.dtb + +targets += $(dtb-y) + +DTC_FLAGS += -R 4 -p 0x1000 + +PHONY += dtbs +dtbs: $(addprefix $(obj)/, $(dtb-y)) + @: + +clean-files := *.dtb diff --git a/arch/arc/dts/arcangel4.dts b/arch/arc/dts/arcangel4.dts new file mode 100644 index 0000000..bfcb9d8 --- /dev/null +++ b/arch/arc/dts/arcangel4.dts @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2015 Synopsys, Inc. (www.synopsys.com) + * + * SPDX-License-Identifier: GPL-2.0+ + */ +/dts-v1/; + +#include "skeleton.dtsi" + +/ { + #address-cells = <1>; + #size-cells = <1>; + + aliases { + console = &arcuart0; + }; + + arcuart0: serial@0xc0fc1000 { + compatible = "snps,arc-uart"; + reg = <0xc0fc1000 0x100>; + clock-frequency = <80000000>; + }; + +}; diff --git a/arch/arc/dts/skeleton.dtsi b/arch/arc/dts/skeleton.dtsi new file mode 100644 index 0000000..b41d241 --- /dev/null +++ b/arch/arc/dts/skeleton.dtsi @@ -0,0 +1,13 @@ +/* + * Skeleton device tree; the bare minimum needed to boot; just include and + * add a compatible value. The bootloader will typically populate the memory + * node. + */ + +/ { + #address-cells = <1>; + #size-cells = <1>; + chosen { }; + aliases { }; + memory { device_type = "memory"; reg = <0 0>; }; +}; diff --git a/configs/arcangel4-be_defconfig b/configs/arcangel4-be_defconfig index 990c74a..36ea6be 100644 --- a/configs/arcangel4-be_defconfig +++ b/configs/arcangel4-be_defconfig @@ -1,5 +1,10 @@ CONFIG_ARC=y CONFIG_CPU_BIG_ENDIAN=y CONFIG_TARGET_ARCANGEL4=y +CONFIG_DM=y +CONFIG_DM_SERIAL=y +CONFIG_DEFAULT_DEVICE_TREE="arcangel4" CONFIG_SYS_TEXT_BASE=0x81000000 CONFIG_SYS_CLK_FREQ=70000000 +CONFIG_OF_CONTROL=y +CONFIG_OF_EMBED=y diff --git a/configs/arcangel4_defconfig b/configs/arcangel4_defconfig index fbc0ffe..75a91c8 100644 --- a/configs/arcangel4_defconfig +++ b/configs/arcangel4_defconfig @@ -1,4 +1,9 @@ CONFIG_ARC=y CONFIG_TARGET_ARCANGEL4=y +CONFIG_DM=y +CONFIG_DM_SERIAL=y +CONFIG_DEFAULT_DEVICE_TREE="arcangel4" CONFIG_SYS_TEXT_BASE=0x81000000 CONFIG_SYS_CLK_FREQ=70000000 +CONFIG_OF_CONTROL=y +CONFIG_OF_EMBED=y diff --git a/drivers/serial/serial_arc.c b/drivers/serial/serial_arc.c index 0ee8ce5..54e596c 100644 --- a/drivers/serial/serial_arc.c +++ b/drivers/serial/serial_arc.c @@ -8,6 +8,7 @@ */ #include <common.h> +#include <dm.h> #include <serial.h> DECLARE_GLOBAL_DATA_PTR; @@ -23,21 +24,23 @@ struct arc_serial_regs { unsigned int baudh; }; + +struct arc_serial_platdata { + struct arc_serial_regs *reg; + unsigned int uartclk; +}; + /* Bit definitions of STATUS register */ #define UART_RXEMPTY (1 << 5) #define UART_OVERFLOW_ERR (1 << 1) #define UART_TXEMPTY (1 << 7) -struct arc_serial_regs *regs = (struct arc_serial_regs *)CONFIG_ARC_UART_BASE; - -static void arc_serial_setbrg(void) +static int arc_serial_setbrg(struct udevice *dev, int baudrate) { - int arc_console_baud; + struct arc_serial_platdata *plat = dev->platdata; + struct arc_serial_regs *const regs = plat->reg; + int arc_console_baud = gd->cpu_clk / (baudrate * 4) - 1; - if (!gd->baudrate) - gd->baudrate = CONFIG_BAUDRATE; - - arc_console_baud = gd->cpu_clk / (gd->baudrate * 4) - 1; writeb(arc_console_baud & 0xff, ®s->baudl); #ifdef CONFIG_ARC @@ -56,33 +59,49 @@ static void arc_serial_setbrg(void) #else writeb((arc_console_baud & 0xff00) >> 8, ®s->baudh); #endif -} -static int arc_serial_init(void) -{ - serial_setbrg(); return 0; } -static void arc_serial_putc(const char c) +static int arc_serial_putc(struct udevice *dev, const char c) { + struct arc_serial_platdata *plat = dev->platdata; + struct arc_serial_regs *const regs = plat->reg; + if (c == '\n') - arc_serial_putc('\r'); + arc_serial_putc(dev, '\r'); while (!(readb(®s->status) & UART_TXEMPTY)) ; writeb(c, ®s->data); + + return 0; } -static int arc_serial_tstc(void) +static int arc_serial_tstc(struct arc_serial_regs *const regs) { return !(readb(®s->status) & UART_RXEMPTY); } -static int arc_serial_getc(void) +static int arc_serial_pending(struct udevice *dev, bool input) +{ + struct arc_serial_platdata *plat = dev->platdata; + struct arc_serial_regs *const regs = plat->reg; + uint32_t status = readb(®s->status); + + if (input) + return status & UART_RXEMPTY ? 0 : 1; + else + return status & UART_TXEMPTY ? 0 : 1; +} + +static int arc_serial_getc(struct udevice *dev) { - while (!arc_serial_tstc()) + struct arc_serial_platdata *plat = dev->platdata; + struct arc_serial_regs *const regs = plat->reg; + + while (!arc_serial_tstc(regs)) ; /* Check for overflow errors */ @@ -92,23 +111,42 @@ static int arc_serial_getc(void) return readb(®s->data) & 0xFF; } -static struct serial_device arc_serial_drv = { - .name = "arc_serial", - .start = arc_serial_init, - .stop = NULL, - .setbrg = arc_serial_setbrg, - .putc = arc_serial_putc, - .puts = default_serial_puts, - .getc = arc_serial_getc, - .tstc = arc_serial_tstc, -}; - -void arc_serial_initialize(void) +static int arc_serial_probe(struct udevice *dev) { - serial_register(&arc_serial_drv); + return 0; } -__weak struct serial_device *default_serial_console(void) +static const struct dm_serial_ops arc_serial_ops = { + .putc = arc_serial_putc, + .pending = arc_serial_pending, + .getc = arc_serial_getc, + .setbrg = arc_serial_setbrg, +}; + +static const struct udevice_id arc_serial_ids[] = { + { .compatible = "snps,arc-uart" }, + { } +}; + +static int arc_serial_ofdata_to_platdata(struct udevice *dev) { - return &arc_serial_drv; + struct arc_serial_platdata *plat = dev_get_platdata(dev); + DECLARE_GLOBAL_DATA_PTR; + + plat->reg = (struct arc_serial_regs *)fdtdec_get_addr(gd->fdt_blob, + dev->of_offset, "reg"); + plat->uartclk = fdtdec_get_int(gd->fdt_blob, dev->of_offset, + "clock-frequency", 0); + + return 0; } + +U_BOOT_DRIVER(serial_arc) = { + .name = "serial_arc", + .id = UCLASS_SERIAL, + .of_match = arc_serial_ids, + .ofdata_to_platdata = arc_serial_ofdata_to_platdata, + .probe = arc_serial_probe, + .ops = &arc_serial_ops, + .flags = DM_FLAG_PRE_RELOC, +};
Now when all infrastructure in ARC is ready for it let's switch ARC UART to driver model. Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com> Cc: Masahiro Yamada <yamada.masahiro@socionext.com> Cc: Simon Glass <sjg@chromium.org> --- arch/Kconfig | 1 + arch/arc/dts/Makefile | 11 +++++ arch/arc/dts/arcangel4.dts | 24 ++++++++++ arch/arc/dts/skeleton.dtsi | 13 ++++++ configs/arcangel4-be_defconfig | 5 ++ configs/arcangel4_defconfig | 5 ++ drivers/serial/serial_arc.c | 102 ++++++++++++++++++++++++++++------------- 7 files changed, 129 insertions(+), 32 deletions(-) create mode 100644 arch/arc/dts/Makefile create mode 100644 arch/arc/dts/arcangel4.dts create mode 100644 arch/arc/dts/skeleton.dtsi