[U-Boot] [PATCH v2 0/3] Moving Uartlite to DM

Hi,
This patch series depends on microblaze cleanup series. All these patches will be available in git://git.denx.de/u-boot-microblaze.git also with patches which I am going to send now.
Thanks, Michal
Changes in v2: - Remove unneeded headers - Use get_dev_addr instead of fdtdec_get_addr - Use platdata instead of private data - Add opb compatible string to be in sync with Linux - Add binding documentation - Add needed header from the first patch - Remove WATCHDOG_RESET call - Extend commit description
Michal Simek (3): serial: uartlite: Move driver to DM serial: uartlite: Add support for debug console serial: uartlite: Add uartlite to Kconfig
arch/microblaze/Kconfig | 1 + board/xilinx/microblaze-generic/xparameters.h | 4 - configs/microblaze-generic_defconfig | 3 + .../serial/xilinx_uartlite.txt | 13 ++ doc/driver-model/serial-howto.txt | 1 - drivers/serial/Kconfig | 14 ++ drivers/serial/serial_xuartlite.c | 188 +++++++++------------ include/configs/microblaze-generic.h | 7 +- 8 files changed, 116 insertions(+), 115 deletions(-) create mode 100644 doc/device-tree-bindings/serial/xilinx_uartlite.txt

Enable SPL DM too.
Signed-off-by: Michal Simek michal.simek@xilinx.com ---
Changes in v2: - Remove unneeded headers - Use get_dev_addr instead of fdtdec_get_addr - Use platdata instead of private data - Add opb compatible string to be in sync with Linux - Add binding documentation
arch/microblaze/Kconfig | 1 + configs/microblaze-generic_defconfig | 2 + .../serial/xilinx_uartlite.txt | 13 ++ doc/driver-model/serial-howto.txt | 1 - drivers/serial/serial_xuartlite.c | 170 ++++++++------------- 5 files changed, 78 insertions(+), 109 deletions(-) create mode 100644 doc/device-tree-bindings/serial/xilinx_uartlite.txt
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 604f6815af5b..30ea484f48aa 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -13,6 +13,7 @@ config TARGET_MICROBLAZE_GENERIC select SUPPORT_SPL select OF_CONTROL select DM + select DM_SERIAL
endchoice
diff --git a/configs/microblaze-generic_defconfig b/configs/microblaze-generic_defconfig index 54aa3ef3d26f..5df080b6a87c 100644 --- a/configs/microblaze-generic_defconfig +++ b/configs/microblaze-generic_defconfig @@ -1,9 +1,11 @@ CONFIG_MICROBLAZE=y CONFIG_SPL_SYS_MALLOC_SIMPLE=y +CONFIG_SPL_DM=y CONFIG_TARGET_MICROBLAZE_GENERIC=y CONFIG_DEFAULT_DEVICE_TREE="microblaze-generic" CONFIG_SPL=y CONFIG_SYS_PROMPT="U-Boot-mONStR> " CONFIG_CMD_GPIO=y # CONFIG_CMD_SETEXPR is not set +CONFIG_SPL_OF_CONTROL=y CONFIG_OF_EMBED=y diff --git a/doc/device-tree-bindings/serial/xilinx_uartlite.txt b/doc/device-tree-bindings/serial/xilinx_uartlite.txt new file mode 100644 index 000000000000..d15753c8c380 --- /dev/null +++ b/doc/device-tree-bindings/serial/xilinx_uartlite.txt @@ -0,0 +1,13 @@ +Binding for Xilinx Uartlite Controller + +Required properties: +- compatible : should be "xlnx,xps-uartlite-1.00.a", or "xlnx,opb-uartlite-1.00.b" +- reg: Should contain UART controller registers location and length. +- interrupts: Should contain UART controller interrupts. + +Example: + serial@40600000 { + compatible = "xlnx,xps-uartlite-1.00.a"; + interrupts = <1 0>; + reg = <0x40600000 0x10000>; + }; diff --git a/doc/driver-model/serial-howto.txt b/doc/driver-model/serial-howto.txt index 76ad629ef9cb..381a2a084562 100644 --- a/doc/driver-model/serial-howto.txt +++ b/doc/driver-model/serial-howto.txt @@ -18,7 +18,6 @@ is time for maintainers to start converting over the remaining serial drivers: serial_pxa.c serial_s3c24x0.c serial_sa1100.c - serial_xuartlite.c usbtty.c
You should complete this by the end of January 2016. diff --git a/drivers/serial/serial_xuartlite.c b/drivers/serial/serial_xuartlite.c index 988438e75471..8225d9a320a5 100644 --- a/drivers/serial/serial_xuartlite.c +++ b/drivers/serial/serial_xuartlite.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2008-2011 Michal Simek monstr@monstr.eu + * (C) Copyright 2008 - 2015 Michal Simek monstr@monstr.eu * Clean driver and add xilinx constant from header file * * (C) Copyright 2004 Atmark Techno, Inc. @@ -10,11 +10,15 @@
#include <config.h> #include <common.h> +#include <dm.h> #include <asm/io.h> #include <linux/compiler.h> #include <serial.h>
+DECLARE_GLOBAL_DATA_PTR; + #define SR_TX_FIFO_FULL 0x08 /* transmit FIFO full */ +#define SR_TX_FIFO_EMPTY 0x04 /* transmit FIFO empty */ #define SR_RX_FIFO_VALID_DATA 0x01 /* data in receive FIFO */ #define SR_RX_FIFO_FULL 0x02 /* receive FIFO full */
@@ -28,135 +32,85 @@ struct uartlite { unsigned int control; };
-static struct uartlite *userial_ports[4] = { -#ifdef XILINX_UARTLITE_BASEADDR - [0] = (struct uartlite *)XILINX_UARTLITE_BASEADDR, -#endif -#ifdef XILINX_UARTLITE_BASEADDR1 - [1] = (struct uartlite *)XILINX_UARTLITE_BASEADDR1, -#endif -#ifdef XILINX_UARTLITE_BASEADDR2 - [2] = (struct uartlite *)XILINX_UARTLITE_BASEADDR2, -#endif -#ifdef XILINX_UARTLITE_BASEADDR3 - [3] = (struct uartlite *)XILINX_UARTLITE_BASEADDR3 -#endif +struct uartlite_platdata { + struct uartlite *regs; };
-static void uartlite_serial_putc(const char c, const int port) +static int uartlite_serial_putc(struct udevice *dev, const char ch) { - struct uartlite *regs = userial_ports[port]; + struct uartlite_platdata *plat = dev_get_platdata(dev); + struct uartlite *regs = plat->regs;
- if (c == '\n') - uartlite_serial_putc('\r', port); + if (in_be32(®s->status) & SR_TX_FIFO_FULL) + return -EAGAIN;
- while (in_be32(®s->status) & SR_TX_FIFO_FULL) - ; - out_be32(®s->tx_fifo, c & 0xff); -} + out_be32(®s->tx_fifo, ch & 0xff);
-static void uartlite_serial_puts(const char *s, const int port) -{ - while (*s) - uartlite_serial_putc(*s++, port); + return 0; }
-static int uartlite_serial_getc(const int port) +static int uartlite_serial_getc(struct udevice *dev) { - struct uartlite *regs = userial_ports[port]; + struct uartlite_platdata *plat = dev_get_platdata(dev); + struct uartlite *regs = plat->regs; + + if (!(in_be32(®s->status) & SR_RX_FIFO_VALID_DATA)) + return -EAGAIN;
- while (!(in_be32(®s->status) & SR_RX_FIFO_VALID_DATA)) - ; return in_be32(®s->rx_fifo) & 0xff; }
-static int uartlite_serial_tstc(const int port) +static int uartlite_serial_pending(struct udevice *dev, bool input) { - struct uartlite *regs = userial_ports[port]; + struct uartlite_platdata *plat = dev_get_platdata(dev); + struct uartlite *regs = plat->regs;
- return in_be32(®s->status) & SR_RX_FIFO_VALID_DATA; + if (input) + return in_be32(®s->status) & SR_RX_FIFO_VALID_DATA; + + return in_be32(®s->status) & SR_TX_FIFO_EMPTY; }
-static int uartlite_serial_init(const int port) +static int uartlite_serial_probe(struct udevice *dev) { - struct uartlite *regs = userial_ports[port]; - - if (regs) { - out_be32(®s->control, 0); - out_be32(®s->control, - ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX); - in_be32(®s->control); - return 0; - } + struct uartlite_platdata *plat = dev_get_platdata(dev); + struct uartlite *regs = plat->regs;
- return -1; -} + out_be32(®s->control, 0); + out_be32(®s->control, ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX); + in_be32(®s->control);
-/* Multi serial device functions */ -#define DECLARE_ESERIAL_FUNCTIONS(port) \ - static int userial##port##_init(void) \ - { return uartlite_serial_init(port); } \ - static void userial##port##_setbrg(void) {} \ - static int userial##port##_getc(void) \ - { return uartlite_serial_getc(port); } \ - static int userial##port##_tstc(void) \ - { return uartlite_serial_tstc(port); } \ - static void userial##port##_putc(const char c) \ - { uartlite_serial_putc(c, port); } \ - static void userial##port##_puts(const char *s) \ - { uartlite_serial_puts(s, port); } - -/* Serial device descriptor */ -#define INIT_ESERIAL_STRUCTURE(port, __name) { \ - .name = __name, \ - .start = userial##port##_init, \ - .stop = NULL, \ - .setbrg = userial##port##_setbrg, \ - .getc = userial##port##_getc, \ - .tstc = userial##port##_tstc, \ - .putc = userial##port##_putc, \ - .puts = userial##port##_puts, \ + return 0; }
-DECLARE_ESERIAL_FUNCTIONS(0); -struct serial_device uartlite_serial0_device = - INIT_ESERIAL_STRUCTURE(0, "ttyUL0"); -DECLARE_ESERIAL_FUNCTIONS(1); -struct serial_device uartlite_serial1_device = - INIT_ESERIAL_STRUCTURE(1, "ttyUL1"); -DECLARE_ESERIAL_FUNCTIONS(2); -struct serial_device uartlite_serial2_device = - INIT_ESERIAL_STRUCTURE(2, "ttyUL2"); -DECLARE_ESERIAL_FUNCTIONS(3); -struct serial_device uartlite_serial3_device = - INIT_ESERIAL_STRUCTURE(3, "ttyUL3"); - -__weak struct serial_device *default_serial_console(void) +static int uartlite_serial_ofdata_to_platdata(struct udevice *dev) { - if (userial_ports[0]) - return &uartlite_serial0_device; - if (userial_ports[1]) - return &uartlite_serial1_device; - if (userial_ports[2]) - return &uartlite_serial2_device; - if (userial_ports[3]) - return &uartlite_serial3_device; - - return NULL; -} + struct uartlite_platdata *plat = dev_get_platdata(dev);
-void uartlite_serial_initialize(void) -{ -#ifdef XILINX_UARTLITE_BASEADDR - serial_register(&uartlite_serial0_device); -#endif /* XILINX_UARTLITE_BASEADDR */ -#ifdef XILINX_UARTLITE_BASEADDR1 - serial_register(&uartlite_serial1_device); -#endif /* XILINX_UARTLITE_BASEADDR1 */ -#ifdef XILINX_UARTLITE_BASEADDR2 - serial_register(&uartlite_serial2_device); -#endif /* XILINX_UARTLITE_BASEADDR2 */ -#ifdef XILINX_UARTLITE_BASEADDR3 - serial_register(&uartlite_serial3_device); -#endif /* XILINX_UARTLITE_BASEADDR3 */ + plat->regs = (struct uartlite *)dev_get_addr(dev); + + return 0; } + +static const struct dm_serial_ops uartlite_serial_ops = { + .putc = uartlite_serial_putc, + .pending = uartlite_serial_pending, + .getc = uartlite_serial_getc, +}; + +static const struct udevice_id uartlite_serial_ids[] = { + { .compatible = "xlnx,opb-uartlite-1.00.b", }, + { .compatible = "xlnx,xps-uartlite-1.00.a" }, + { } +}; + +U_BOOT_DRIVER(serial_uartlite) = { + .name = "serial_uartlite", + .id = UCLASS_SERIAL, + .of_match = uartlite_serial_ids, + .ofdata_to_platdata = uartlite_serial_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct uartlite_platdata), + .probe = uartlite_serial_probe, + .ops = &uartlite_serial_ops, + .flags = DM_FLAG_PRE_RELOC, +};

Hi Michal,
On 2015年12月17日 20:00, Michal Simek wrote:
Enable SPL DM too.
Signed-off-by: Michal Simek michal.simek@xilinx.com
Changes in v2:
Remove unneeded headers
Use get_dev_addr instead of fdtdec_get_addr
Use platdata instead of private data
Add opb compatible string to be in sync with Linux
Add binding documentation
arch/microblaze/Kconfig | 1 + configs/microblaze-generic_defconfig | 2 + .../serial/xilinx_uartlite.txt | 13 ++ doc/driver-model/serial-howto.txt | 1 - drivers/serial/serial_xuartlite.c | 170 ++++++++------------- 5 files changed, 78 insertions(+), 109 deletions(-) create mode 100644 doc/device-tree-bindings/serial/xilinx_uartlite.txt
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 604f6815af5b..30ea484f48aa 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -13,6 +13,7 @@ config TARGET_MICROBLAZE_GENERIC select SUPPORT_SPL select OF_CONTROL select DM
select DM_SERIAL
endchoice
diff --git a/configs/microblaze-generic_defconfig b/configs/microblaze-generic_defconfig index 54aa3ef3d26f..5df080b6a87c 100644 --- a/configs/microblaze-generic_defconfig +++ b/configs/microblaze-generic_defconfig @@ -1,9 +1,11 @@ CONFIG_MICROBLAZE=y CONFIG_SPL_SYS_MALLOC_SIMPLE=y +CONFIG_SPL_DM=y CONFIG_TARGET_MICROBLAZE_GENERIC=y CONFIG_DEFAULT_DEVICE_TREE="microblaze-generic" CONFIG_SPL=y CONFIG_SYS_PROMPT="U-Boot-mONStR> " CONFIG_CMD_GPIO=y # CONFIG_CMD_SETEXPR is not set +CONFIG_SPL_OF_CONTROL=y CONFIG_OF_EMBED=y diff --git a/doc/device-tree-bindings/serial/xilinx_uartlite.txt b/doc/device-tree-bindings/serial/xilinx_uartlite.txt new file mode 100644 index 000000000000..d15753c8c380 --- /dev/null +++ b/doc/device-tree-bindings/serial/xilinx_uartlite.txt @@ -0,0 +1,13 @@ +Binding for Xilinx Uartlite Controller
+Required properties: +- compatible : should be "xlnx,xps-uartlite-1.00.a", or "xlnx,opb-uartlite-1.00.b" +- reg: Should contain UART controller registers location and length. +- interrupts: Should contain UART controller interrupts.
+Example:
- serial@40600000 {
compatible = "xlnx,xps-uartlite-1.00.a";
interrupts = <1 0>;
reg = <0x40600000 0x10000>;
- };
diff --git a/doc/driver-model/serial-howto.txt b/doc/driver-model/serial-howto.txt index 76ad629ef9cb..381a2a084562 100644 --- a/doc/driver-model/serial-howto.txt +++ b/doc/driver-model/serial-howto.txt @@ -18,7 +18,6 @@ is time for maintainers to start converting over the remaining serial drivers: serial_pxa.c serial_s3c24x0.c serial_sa1100.c
serial_xuartlite.c usbtty.c
You should complete this by the end of January 2016.
diff --git a/drivers/serial/serial_xuartlite.c b/drivers/serial/serial_xuartlite.c index 988438e75471..8225d9a320a5 100644 --- a/drivers/serial/serial_xuartlite.c +++ b/drivers/serial/serial_xuartlite.c @@ -1,5 +1,5 @@ /*
- (C) Copyright 2008-2011 Michal Simek monstr@monstr.eu
- (C) Copyright 2008 - 2015 Michal Simek monstr@monstr.eu
- Clean driver and add xilinx constant from header file
- (C) Copyright 2004 Atmark Techno, Inc.
@@ -10,11 +10,15 @@
#include <config.h> #include <common.h> +#include <dm.h> #include <asm/io.h> #include <linux/compiler.h> #include <serial.h>
+DECLARE_GLOBAL_DATA_PTR;
- #define SR_TX_FIFO_FULL 0x08 /* transmit FIFO full */
+#define SR_TX_FIFO_EMPTY 0x04 /* transmit FIFO empty */ #define SR_RX_FIFO_VALID_DATA 0x01 /* data in receive FIFO */ #define SR_RX_FIFO_FULL 0x02 /* receive FIFO full */
@@ -28,135 +32,85 @@ struct uartlite { unsigned int control; };
-static struct uartlite *userial_ports[4] = { -#ifdef XILINX_UARTLITE_BASEADDR
- [0] = (struct uartlite *)XILINX_UARTLITE_BASEADDR,
-#endif -#ifdef XILINX_UARTLITE_BASEADDR1
- [1] = (struct uartlite *)XILINX_UARTLITE_BASEADDR1,
-#endif -#ifdef XILINX_UARTLITE_BASEADDR2
- [2] = (struct uartlite *)XILINX_UARTLITE_BASEADDR2,
-#endif -#ifdef XILINX_UARTLITE_BASEADDR3
- [3] = (struct uartlite *)XILINX_UARTLITE_BASEADDR3
-#endif +struct uartlite_platdata {
- struct uartlite *regs; };
-static void uartlite_serial_putc(const char c, const int port) +static int uartlite_serial_putc(struct udevice *dev, const char ch) {
- struct uartlite *regs = userial_ports[port];
- struct uartlite_platdata *plat = dev_get_platdata(dev);
- struct uartlite *regs = plat->regs;
- if (c == '\n')
uartlite_serial_putc('\r', port);
- if (in_be32(®s->status) & SR_TX_FIFO_FULL)
return -EAGAIN;
- while (in_be32(®s->status) & SR_TX_FIFO_FULL)
;
- out_be32(®s->tx_fifo, c & 0xff);
-}
- out_be32(®s->tx_fifo, ch & 0xff);
-static void uartlite_serial_puts(const char *s, const int port) -{
- while (*s)
uartlite_serial_putc(*s++, port);
- return 0; }
-static int uartlite_serial_getc(const int port) +static int uartlite_serial_getc(struct udevice *dev) {
- struct uartlite *regs = userial_ports[port];
- struct uartlite_platdata *plat = dev_get_platdata(dev);
- struct uartlite *regs = plat->regs;
- if (!(in_be32(®s->status) & SR_RX_FIFO_VALID_DATA))
return -EAGAIN;
- while (!(in_be32(®s->status) & SR_RX_FIFO_VALID_DATA))
return in_be32(®s->rx_fifo) & 0xff; };
-static int uartlite_serial_tstc(const int port) +static int uartlite_serial_pending(struct udevice *dev, bool input) {
- struct uartlite *regs = userial_ports[port];
- struct uartlite_platdata *plat = dev_get_platdata(dev);
- struct uartlite *regs = plat->regs;
- return in_be32(®s->status) & SR_RX_FIFO_VALID_DATA;
- if (input)
return in_be32(®s->status) & SR_RX_FIFO_VALID_DATA;
- return in_be32(®s->status) & SR_TX_FIFO_EMPTY;
Should be inversed.
Otherwise, Reviewed-by: Thomas Chou thomas@wytron.com.tw
}
-static int uartlite_serial_init(const int port) +static int uartlite_serial_probe(struct udevice *dev) {
- struct uartlite *regs = userial_ports[port];
- if (regs) {
out_be32(®s->control, 0);
out_be32(®s->control,
ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX);
in_be32(®s->control);
return 0;
- }
- struct uartlite_platdata *plat = dev_get_platdata(dev);
- struct uartlite *regs = plat->regs;
- return -1;
-}
- out_be32(®s->control, 0);
- out_be32(®s->control, ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX);
- in_be32(®s->control);
-/* Multi serial device functions */ -#define DECLARE_ESERIAL_FUNCTIONS(port) \
- static int userial##port##_init(void) \
{ return uartlite_serial_init(port); } \
- static void userial##port##_setbrg(void) {} \
- static int userial##port##_getc(void) \
{ return uartlite_serial_getc(port); } \
- static int userial##port##_tstc(void) \
{ return uartlite_serial_tstc(port); } \
- static void userial##port##_putc(const char c) \
{ uartlite_serial_putc(c, port); } \
- static void userial##port##_puts(const char *s) \
{ uartlite_serial_puts(s, port); }
-/* Serial device descriptor */ -#define INIT_ESERIAL_STRUCTURE(port, __name) { \
- .name = __name, \
- .start = userial##port##_init, \
- .stop = NULL, \
- .setbrg = userial##port##_setbrg, \
- .getc = userial##port##_getc, \
- .tstc = userial##port##_tstc, \
- .putc = userial##port##_putc, \
- .puts = userial##port##_puts, \
- return 0; }
-DECLARE_ESERIAL_FUNCTIONS(0); -struct serial_device uartlite_serial0_device =
- INIT_ESERIAL_STRUCTURE(0, "ttyUL0");
-DECLARE_ESERIAL_FUNCTIONS(1); -struct serial_device uartlite_serial1_device =
- INIT_ESERIAL_STRUCTURE(1, "ttyUL1");
-DECLARE_ESERIAL_FUNCTIONS(2); -struct serial_device uartlite_serial2_device =
- INIT_ESERIAL_STRUCTURE(2, "ttyUL2");
-DECLARE_ESERIAL_FUNCTIONS(3); -struct serial_device uartlite_serial3_device =
- INIT_ESERIAL_STRUCTURE(3, "ttyUL3");
-__weak struct serial_device *default_serial_console(void) +static int uartlite_serial_ofdata_to_platdata(struct udevice *dev) {
- if (userial_ports[0])
return &uartlite_serial0_device;
- if (userial_ports[1])
return &uartlite_serial1_device;
- if (userial_ports[2])
return &uartlite_serial2_device;
- if (userial_ports[3])
return &uartlite_serial3_device;
- return NULL;
-}
- struct uartlite_platdata *plat = dev_get_platdata(dev);
-void uartlite_serial_initialize(void) -{ -#ifdef XILINX_UARTLITE_BASEADDR
- serial_register(&uartlite_serial0_device);
-#endif /* XILINX_UARTLITE_BASEADDR */ -#ifdef XILINX_UARTLITE_BASEADDR1
- serial_register(&uartlite_serial1_device);
-#endif /* XILINX_UARTLITE_BASEADDR1 */ -#ifdef XILINX_UARTLITE_BASEADDR2
- serial_register(&uartlite_serial2_device);
-#endif /* XILINX_UARTLITE_BASEADDR2 */ -#ifdef XILINX_UARTLITE_BASEADDR3
- serial_register(&uartlite_serial3_device);
-#endif /* XILINX_UARTLITE_BASEADDR3 */
- plat->regs = (struct uartlite *)dev_get_addr(dev);
- return 0; }
+static const struct dm_serial_ops uartlite_serial_ops = {
- .putc = uartlite_serial_putc,
- .pending = uartlite_serial_pending,
- .getc = uartlite_serial_getc,
+};
+static const struct udevice_id uartlite_serial_ids[] = {
- { .compatible = "xlnx,opb-uartlite-1.00.b", },
- { .compatible = "xlnx,xps-uartlite-1.00.a" },
- { }
+};
+U_BOOT_DRIVER(serial_uartlite) = {
- .name = "serial_uartlite",
- .id = UCLASS_SERIAL,
- .of_match = uartlite_serial_ids,
- .ofdata_to_platdata = uartlite_serial_ofdata_to_platdata,
- .platdata_auto_alloc_size = sizeof(struct uartlite_platdata),
- .probe = uartlite_serial_probe,
- .ops = &uartlite_serial_ops,
- .flags = DM_FLAG_PRE_RELOC,
+};
Best regards, Thomas

On 17.12.2015 14:37, Thomas Chou wrote:
Hi Michal,
On 2015年12月17日 20:00, Michal Simek wrote:
Enable SPL DM too.
Signed-off-by: Michal Simek michal.simek@xilinx.com
Changes in v2:
Remove unneeded headers
Use get_dev_addr instead of fdtdec_get_addr
Use platdata instead of private data
Add opb compatible string to be in sync with Linux
Add binding documentation
arch/microblaze/Kconfig | 1 + configs/microblaze-generic_defconfig | 2 + .../serial/xilinx_uartlite.txt | 13 ++ doc/driver-model/serial-howto.txt | 1 - drivers/serial/serial_xuartlite.c | 170
++++++++------------- 5 files changed, 78 insertions(+), 109 deletions(-) create mode 100644 doc/device-tree-bindings/serial/xilinx_uartlite.txt
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 604f6815af5b..30ea484f48aa 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -13,6 +13,7 @@ config TARGET_MICROBLAZE_GENERIC select SUPPORT_SPL select OF_CONTROL select DM
select DM_SERIAL
endchoice
diff --git a/configs/microblaze-generic_defconfig b/configs/microblaze-generic_defconfig index 54aa3ef3d26f..5df080b6a87c 100644 --- a/configs/microblaze-generic_defconfig +++ b/configs/microblaze-generic_defconfig @@ -1,9 +1,11 @@ CONFIG_MICROBLAZE=y CONFIG_SPL_SYS_MALLOC_SIMPLE=y +CONFIG_SPL_DM=y CONFIG_TARGET_MICROBLAZE_GENERIC=y CONFIG_DEFAULT_DEVICE_TREE="microblaze-generic" CONFIG_SPL=y CONFIG_SYS_PROMPT="U-Boot-mONStR> " CONFIG_CMD_GPIO=y # CONFIG_CMD_SETEXPR is not set +CONFIG_SPL_OF_CONTROL=y CONFIG_OF_EMBED=y diff --git a/doc/device-tree-bindings/serial/xilinx_uartlite.txt b/doc/device-tree-bindings/serial/xilinx_uartlite.txt new file mode 100644 index 000000000000..d15753c8c380 --- /dev/null +++ b/doc/device-tree-bindings/serial/xilinx_uartlite.txt @@ -0,0 +1,13 @@ +Binding for Xilinx Uartlite Controller
+Required properties: +- compatible : should be "xlnx,xps-uartlite-1.00.a", or "xlnx,opb-uartlite-1.00.b" +- reg: Should contain UART controller registers location and length. +- interrupts: Should contain UART controller interrupts.
+Example:
- serial@40600000 {
compatible = "xlnx,xps-uartlite-1.00.a";
interrupts = <1 0>;
reg = <0x40600000 0x10000>;
- };
diff --git a/doc/driver-model/serial-howto.txt b/doc/driver-model/serial-howto.txt index 76ad629ef9cb..381a2a084562 100644 --- a/doc/driver-model/serial-howto.txt +++ b/doc/driver-model/serial-howto.txt @@ -18,7 +18,6 @@ is time for maintainers to start converting over the remaining serial drivers: serial_pxa.c serial_s3c24x0.c serial_sa1100.c
serial_xuartlite.c usbtty.c
You should complete this by the end of January 2016.
diff --git a/drivers/serial/serial_xuartlite.c b/drivers/serial/serial_xuartlite.c index 988438e75471..8225d9a320a5 100644 --- a/drivers/serial/serial_xuartlite.c +++ b/drivers/serial/serial_xuartlite.c @@ -1,5 +1,5 @@ /*
- (C) Copyright 2008-2011 Michal Simek monstr@monstr.eu
- (C) Copyright 2008 - 2015 Michal Simek monstr@monstr.eu
- Clean driver and add xilinx constant from header file
- (C) Copyright 2004 Atmark Techno, Inc.
@@ -10,11 +10,15 @@
#include <config.h> #include <common.h> +#include <dm.h> #include <asm/io.h> #include <linux/compiler.h> #include <serial.h>
+DECLARE_GLOBAL_DATA_PTR;
- #define SR_TX_FIFO_FULL 0x08 /* transmit FIFO full */
+#define SR_TX_FIFO_EMPTY 0x04 /* transmit FIFO empty */ #define SR_RX_FIFO_VALID_DATA 0x01 /* data in receive FIFO */ #define SR_RX_FIFO_FULL 0x02 /* receive FIFO full */
@@ -28,135 +32,85 @@ struct uartlite { unsigned int control; };
-static struct uartlite *userial_ports[4] = { -#ifdef XILINX_UARTLITE_BASEADDR
- [0] = (struct uartlite *)XILINX_UARTLITE_BASEADDR,
-#endif -#ifdef XILINX_UARTLITE_BASEADDR1
- [1] = (struct uartlite *)XILINX_UARTLITE_BASEADDR1,
-#endif -#ifdef XILINX_UARTLITE_BASEADDR2
- [2] = (struct uartlite *)XILINX_UARTLITE_BASEADDR2,
-#endif -#ifdef XILINX_UARTLITE_BASEADDR3
- [3] = (struct uartlite *)XILINX_UARTLITE_BASEADDR3
-#endif +struct uartlite_platdata {
- struct uartlite *regs; };
-static void uartlite_serial_putc(const char c, const int port) +static int uartlite_serial_putc(struct udevice *dev, const char ch) {
- struct uartlite *regs = userial_ports[port];
- struct uartlite_platdata *plat = dev_get_platdata(dev);
- struct uartlite *regs = plat->regs;
- if (c == '\n')
uartlite_serial_putc('\r', port);
- if (in_be32(®s->status) & SR_TX_FIFO_FULL)
return -EAGAIN;
- while (in_be32(®s->status) & SR_TX_FIFO_FULL)
;
- out_be32(®s->tx_fifo, c & 0xff);
-}
- out_be32(®s->tx_fifo, ch & 0xff);
-static void uartlite_serial_puts(const char *s, const int port) -{
- while (*s)
uartlite_serial_putc(*s++, port);
- return 0; }
-static int uartlite_serial_getc(const int port) +static int uartlite_serial_getc(struct udevice *dev) {
- struct uartlite *regs = userial_ports[port];
- struct uartlite_platdata *plat = dev_get_platdata(dev);
- struct uartlite *regs = plat->regs;
- if (!(in_be32(®s->status) & SR_RX_FIFO_VALID_DATA))
return -EAGAIN;
- while (!(in_be32(®s->status) & SR_RX_FIFO_VALID_DATA))
}; return in_be32(®s->rx_fifo) & 0xff;
-static int uartlite_serial_tstc(const int port) +static int uartlite_serial_pending(struct udevice *dev, bool input) {
- struct uartlite *regs = userial_ports[port];
- struct uartlite_platdata *plat = dev_get_platdata(dev);
- struct uartlite *regs = plat->regs;
- return in_be32(®s->status) & SR_RX_FIFO_VALID_DATA;
- if (input)
return in_be32(®s->status) & SR_RX_FIFO_VALID_DATA;
- return in_be32(®s->status) & SR_TX_FIFO_EMPTY;
Should be inversed.
Otherwise, Reviewed-by: Thomas Chou thomas@wytron.com.tw
Can you please tell me more about it? I was trying to understand logic of this function but pending function is called just from here. (maybe I missed other occurrences but drivers/serial/serial-uclass.c:157: if (ops->pending) drivers/serial/serial-uclass.c:158: return ops->pending(dev, true);
And not for output.
From docs
@return number of waiting characters, 0 for none, -ve on error
It means I do read status and mask it if tx fifo is empty or not. If it is empty I am returning 0, if it is not empty I do return non 0 value.
The similar logix is used for input.
Is this logic wrong?
Thanks, Michal

Hi Michal,
On 17 December 2015 at 06:58, Michal Simek michal.simek@xilinx.com wrote:
On 17.12.2015 14:37, Thomas Chou wrote:
Hi Michal,
On 2015年12月17日 20:00, Michal Simek wrote:
Enable SPL DM too.
Signed-off-by: Michal Simek michal.simek@xilinx.com
Changes in v2:
Remove unneeded headers
Use get_dev_addr instead of fdtdec_get_addr
Use platdata instead of private data
Add opb compatible string to be in sync with Linux
Add binding documentation
arch/microblaze/Kconfig | 1 + configs/microblaze-generic_defconfig | 2 + .../serial/xilinx_uartlite.txt | 13 ++ doc/driver-model/serial-howto.txt | 1 - drivers/serial/serial_xuartlite.c | 170
++++++++------------- 5 files changed, 78 insertions(+), 109 deletions(-) create mode 100644 doc/device-tree-bindings/serial/xilinx_uartlite.txt
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 604f6815af5b..30ea484f48aa 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -13,6 +13,7 @@ config TARGET_MICROBLAZE_GENERIC select SUPPORT_SPL select OF_CONTROL select DM
select DM_SERIAL
endchoice
diff --git a/configs/microblaze-generic_defconfig b/configs/microblaze-generic_defconfig index 54aa3ef3d26f..5df080b6a87c 100644 --- a/configs/microblaze-generic_defconfig +++ b/configs/microblaze-generic_defconfig @@ -1,9 +1,11 @@ CONFIG_MICROBLAZE=y CONFIG_SPL_SYS_MALLOC_SIMPLE=y +CONFIG_SPL_DM=y CONFIG_TARGET_MICROBLAZE_GENERIC=y CONFIG_DEFAULT_DEVICE_TREE="microblaze-generic" CONFIG_SPL=y CONFIG_SYS_PROMPT="U-Boot-mONStR> " CONFIG_CMD_GPIO=y # CONFIG_CMD_SETEXPR is not set +CONFIG_SPL_OF_CONTROL=y CONFIG_OF_EMBED=y diff --git a/doc/device-tree-bindings/serial/xilinx_uartlite.txt b/doc/device-tree-bindings/serial/xilinx_uartlite.txt new file mode 100644 index 000000000000..d15753c8c380 --- /dev/null +++ b/doc/device-tree-bindings/serial/xilinx_uartlite.txt @@ -0,0 +1,13 @@ +Binding for Xilinx Uartlite Controller
+Required properties: +- compatible : should be "xlnx,xps-uartlite-1.00.a", or "xlnx,opb-uartlite-1.00.b" +- reg: Should contain UART controller registers location and length. +- interrupts: Should contain UART controller interrupts.
+Example:
- serial@40600000 {
compatible = "xlnx,xps-uartlite-1.00.a";
interrupts = <1 0>;
reg = <0x40600000 0x10000>;
- };
diff --git a/doc/driver-model/serial-howto.txt b/doc/driver-model/serial-howto.txt index 76ad629ef9cb..381a2a084562 100644 --- a/doc/driver-model/serial-howto.txt +++ b/doc/driver-model/serial-howto.txt @@ -18,7 +18,6 @@ is time for maintainers to start converting over the remaining serial drivers: serial_pxa.c serial_s3c24x0.c serial_sa1100.c
serial_xuartlite.c usbtty.c
You should complete this by the end of January 2016.
diff --git a/drivers/serial/serial_xuartlite.c b/drivers/serial/serial_xuartlite.c index 988438e75471..8225d9a320a5 100644 --- a/drivers/serial/serial_xuartlite.c +++ b/drivers/serial/serial_xuartlite.c @@ -1,5 +1,5 @@ /*
- (C) Copyright 2008-2011 Michal Simek monstr@monstr.eu
- (C) Copyright 2008 - 2015 Michal Simek monstr@monstr.eu
- Clean driver and add xilinx constant from header file
- (C) Copyright 2004 Atmark Techno, Inc.
@@ -10,11 +10,15 @@
#include <config.h> #include <common.h> +#include <dm.h> #include <asm/io.h> #include <linux/compiler.h> #include <serial.h>
+DECLARE_GLOBAL_DATA_PTR;
- #define SR_TX_FIFO_FULL 0x08 /* transmit FIFO full */
+#define SR_TX_FIFO_EMPTY 0x04 /* transmit FIFO empty */ #define SR_RX_FIFO_VALID_DATA 0x01 /* data in receive FIFO */ #define SR_RX_FIFO_FULL 0x02 /* receive FIFO full */
@@ -28,135 +32,85 @@ struct uartlite { unsigned int control; };
-static struct uartlite *userial_ports[4] = { -#ifdef XILINX_UARTLITE_BASEADDR
- [0] = (struct uartlite *)XILINX_UARTLITE_BASEADDR,
-#endif -#ifdef XILINX_UARTLITE_BASEADDR1
- [1] = (struct uartlite *)XILINX_UARTLITE_BASEADDR1,
-#endif -#ifdef XILINX_UARTLITE_BASEADDR2
- [2] = (struct uartlite *)XILINX_UARTLITE_BASEADDR2,
-#endif -#ifdef XILINX_UARTLITE_BASEADDR3
- [3] = (struct uartlite *)XILINX_UARTLITE_BASEADDR3
-#endif +struct uartlite_platdata {
- struct uartlite *regs; };
-static void uartlite_serial_putc(const char c, const int port) +static int uartlite_serial_putc(struct udevice *dev, const char ch) {
- struct uartlite *regs = userial_ports[port];
- struct uartlite_platdata *plat = dev_get_platdata(dev);
- struct uartlite *regs = plat->regs;
- if (c == '\n')
uartlite_serial_putc('\r', port);
- if (in_be32(®s->status) & SR_TX_FIFO_FULL)
return -EAGAIN;
- while (in_be32(®s->status) & SR_TX_FIFO_FULL)
;
- out_be32(®s->tx_fifo, c & 0xff);
-}
- out_be32(®s->tx_fifo, ch & 0xff);
-static void uartlite_serial_puts(const char *s, const int port) -{
- while (*s)
uartlite_serial_putc(*s++, port);
- return 0; }
-static int uartlite_serial_getc(const int port) +static int uartlite_serial_getc(struct udevice *dev) {
- struct uartlite *regs = userial_ports[port];
- struct uartlite_platdata *plat = dev_get_platdata(dev);
- struct uartlite *regs = plat->regs;
- if (!(in_be32(®s->status) & SR_RX_FIFO_VALID_DATA))
return -EAGAIN;
- while (!(in_be32(®s->status) & SR_RX_FIFO_VALID_DATA))
}; return in_be32(®s->rx_fifo) & 0xff;
-static int uartlite_serial_tstc(const int port) +static int uartlite_serial_pending(struct udevice *dev, bool input) {
- struct uartlite *regs = userial_ports[port];
- struct uartlite_platdata *plat = dev_get_platdata(dev);
- struct uartlite *regs = plat->regs;
- return in_be32(®s->status) & SR_RX_FIFO_VALID_DATA;
- if (input)
return in_be32(®s->status) & SR_RX_FIFO_VALID_DATA;
- return in_be32(®s->status) & SR_TX_FIFO_EMPTY;
Should be inversed.
Otherwise, Reviewed-by: Thomas Chou thomas@wytron.com.tw
Can you please tell me more about it? I was trying to understand logic of this function but pending function is called just from here. (maybe I missed other occurrences but drivers/serial/serial-uclass.c:157: if (ops->pending) drivers/serial/serial-uclass.c:158: return ops->pending(dev, true);
And not for output.
From docs @return number of waiting characters, 0 for none, -ve on error
It means I do read status and mask it if tx fifo is empty or not. If it is empty I am returning 0, if it is not empty I do return non 0 value.
The similar logix is used for input.
Is this logic wrong?
Be careful to return 1 if you don't know how many characters are waiting. It looks like you return 'in_be32(®s->status) & SR_RX_FIFO_VALID_DATA' which could be >1.
Regards, Simon

On 17.12.2015 16:27, Simon Glass wrote:
Hi Michal,
On 17 December 2015 at 06:58, Michal Simek michal.simek@xilinx.com wrote:
On 17.12.2015 14:37, Thomas Chou wrote:
Hi Michal,
On 2015年12月17日 20:00, Michal Simek wrote:
Enable SPL DM too.
Signed-off-by: Michal Simek michal.simek@xilinx.com
Changes in v2:
Remove unneeded headers
Use get_dev_addr instead of fdtdec_get_addr
Use platdata instead of private data
Add opb compatible string to be in sync with Linux
Add binding documentation
arch/microblaze/Kconfig | 1 + configs/microblaze-generic_defconfig | 2 + .../serial/xilinx_uartlite.txt | 13 ++ doc/driver-model/serial-howto.txt | 1 - drivers/serial/serial_xuartlite.c | 170
++++++++------------- 5 files changed, 78 insertions(+), 109 deletions(-) create mode 100644 doc/device-tree-bindings/serial/xilinx_uartlite.txt
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 604f6815af5b..30ea484f48aa 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -13,6 +13,7 @@ config TARGET_MICROBLAZE_GENERIC select SUPPORT_SPL select OF_CONTROL select DM
select DM_SERIAL
endchoice
diff --git a/configs/microblaze-generic_defconfig b/configs/microblaze-generic_defconfig index 54aa3ef3d26f..5df080b6a87c 100644 --- a/configs/microblaze-generic_defconfig +++ b/configs/microblaze-generic_defconfig @@ -1,9 +1,11 @@ CONFIG_MICROBLAZE=y CONFIG_SPL_SYS_MALLOC_SIMPLE=y +CONFIG_SPL_DM=y CONFIG_TARGET_MICROBLAZE_GENERIC=y CONFIG_DEFAULT_DEVICE_TREE="microblaze-generic" CONFIG_SPL=y CONFIG_SYS_PROMPT="U-Boot-mONStR> " CONFIG_CMD_GPIO=y # CONFIG_CMD_SETEXPR is not set +CONFIG_SPL_OF_CONTROL=y CONFIG_OF_EMBED=y diff --git a/doc/device-tree-bindings/serial/xilinx_uartlite.txt b/doc/device-tree-bindings/serial/xilinx_uartlite.txt new file mode 100644 index 000000000000..d15753c8c380 --- /dev/null +++ b/doc/device-tree-bindings/serial/xilinx_uartlite.txt @@ -0,0 +1,13 @@ +Binding for Xilinx Uartlite Controller
+Required properties: +- compatible : should be "xlnx,xps-uartlite-1.00.a", or "xlnx,opb-uartlite-1.00.b" +- reg: Should contain UART controller registers location and length. +- interrupts: Should contain UART controller interrupts.
+Example:
- serial@40600000 {
compatible = "xlnx,xps-uartlite-1.00.a";
interrupts = <1 0>;
reg = <0x40600000 0x10000>;
- };
diff --git a/doc/driver-model/serial-howto.txt b/doc/driver-model/serial-howto.txt index 76ad629ef9cb..381a2a084562 100644 --- a/doc/driver-model/serial-howto.txt +++ b/doc/driver-model/serial-howto.txt @@ -18,7 +18,6 @@ is time for maintainers to start converting over the remaining serial drivers: serial_pxa.c serial_s3c24x0.c serial_sa1100.c
serial_xuartlite.c usbtty.c
You should complete this by the end of January 2016.
diff --git a/drivers/serial/serial_xuartlite.c b/drivers/serial/serial_xuartlite.c index 988438e75471..8225d9a320a5 100644 --- a/drivers/serial/serial_xuartlite.c +++ b/drivers/serial/serial_xuartlite.c @@ -1,5 +1,5 @@ /*
- (C) Copyright 2008-2011 Michal Simek monstr@monstr.eu
- (C) Copyright 2008 - 2015 Michal Simek monstr@monstr.eu
- Clean driver and add xilinx constant from header file
- (C) Copyright 2004 Atmark Techno, Inc.
@@ -10,11 +10,15 @@
#include <config.h> #include <common.h> +#include <dm.h> #include <asm/io.h> #include <linux/compiler.h> #include <serial.h>
+DECLARE_GLOBAL_DATA_PTR;
- #define SR_TX_FIFO_FULL 0x08 /* transmit FIFO full */
+#define SR_TX_FIFO_EMPTY 0x04 /* transmit FIFO empty */ #define SR_RX_FIFO_VALID_DATA 0x01 /* data in receive FIFO */ #define SR_RX_FIFO_FULL 0x02 /* receive FIFO full */
@@ -28,135 +32,85 @@ struct uartlite { unsigned int control; };
-static struct uartlite *userial_ports[4] = { -#ifdef XILINX_UARTLITE_BASEADDR
- [0] = (struct uartlite *)XILINX_UARTLITE_BASEADDR,
-#endif -#ifdef XILINX_UARTLITE_BASEADDR1
- [1] = (struct uartlite *)XILINX_UARTLITE_BASEADDR1,
-#endif -#ifdef XILINX_UARTLITE_BASEADDR2
- [2] = (struct uartlite *)XILINX_UARTLITE_BASEADDR2,
-#endif -#ifdef XILINX_UARTLITE_BASEADDR3
- [3] = (struct uartlite *)XILINX_UARTLITE_BASEADDR3
-#endif +struct uartlite_platdata {
- struct uartlite *regs; };
-static void uartlite_serial_putc(const char c, const int port) +static int uartlite_serial_putc(struct udevice *dev, const char ch) {
- struct uartlite *regs = userial_ports[port];
- struct uartlite_platdata *plat = dev_get_platdata(dev);
- struct uartlite *regs = plat->regs;
- if (c == '\n')
uartlite_serial_putc('\r', port);
- if (in_be32(®s->status) & SR_TX_FIFO_FULL)
return -EAGAIN;
- while (in_be32(®s->status) & SR_TX_FIFO_FULL)
;
- out_be32(®s->tx_fifo, c & 0xff);
-}
- out_be32(®s->tx_fifo, ch & 0xff);
-static void uartlite_serial_puts(const char *s, const int port) -{
- while (*s)
uartlite_serial_putc(*s++, port);
- return 0; }
-static int uartlite_serial_getc(const int port) +static int uartlite_serial_getc(struct udevice *dev) {
- struct uartlite *regs = userial_ports[port];
- struct uartlite_platdata *plat = dev_get_platdata(dev);
- struct uartlite *regs = plat->regs;
- if (!(in_be32(®s->status) & SR_RX_FIFO_VALID_DATA))
return -EAGAIN;
- while (!(in_be32(®s->status) & SR_RX_FIFO_VALID_DATA))
}; return in_be32(®s->rx_fifo) & 0xff;
-static int uartlite_serial_tstc(const int port) +static int uartlite_serial_pending(struct udevice *dev, bool input) {
- struct uartlite *regs = userial_ports[port];
- struct uartlite_platdata *plat = dev_get_platdata(dev);
- struct uartlite *regs = plat->regs;
- return in_be32(®s->status) & SR_RX_FIFO_VALID_DATA;
- if (input)
return in_be32(®s->status) & SR_RX_FIFO_VALID_DATA;
- return in_be32(®s->status) & SR_TX_FIFO_EMPTY;
Should be inversed.
Otherwise, Reviewed-by: Thomas Chou thomas@wytron.com.tw
Can you please tell me more about it? I was trying to understand logic of this function but pending function is called just from here. (maybe I missed other occurrences but drivers/serial/serial-uclass.c:157: if (ops->pending) drivers/serial/serial-uclass.c:158: return ops->pending(dev, true);
And not for output.
From docs @return number of waiting characters, 0 for none, -ve on error
It means I do read status and mask it if tx fifo is empty or not. If it is empty I am returning 0, if it is not empty I do return non 0 value.
The similar logix is used for input.
Is this logic wrong?
Be careful to return 1 if you don't know how many characters are waiting. It looks like you return 'in_be32(®s->status) & SR_RX_FIFO_VALID_DATA' which could be >1.
IP doesn't provide information how many chars is in FIFO. It can be 1 to 16. No problem to return just 1 for more than 1 char in FIFO. Is core working with that information?
Thanks, Michal

Hi Michal,
On 17 December 2015 at 11:52, Michal Simek michal.simek@xilinx.com wrote:
On 17.12.2015 16:27, Simon Glass wrote:
Hi Michal,
On 17 December 2015 at 06:58, Michal Simek michal.simek@xilinx.com wrote:
On 17.12.2015 14:37, Thomas Chou wrote:
Hi Michal,
On 2015年12月17日 20:00, Michal Simek wrote:
Enable SPL DM too.
Signed-off-by: Michal Simek michal.simek@xilinx.com
Changes in v2:
Remove unneeded headers
Use get_dev_addr instead of fdtdec_get_addr
Use platdata instead of private data
Add opb compatible string to be in sync with Linux
Add binding documentation
arch/microblaze/Kconfig | 1 + configs/microblaze-generic_defconfig | 2 + .../serial/xilinx_uartlite.txt | 13 ++ doc/driver-model/serial-howto.txt | 1 - drivers/serial/serial_xuartlite.c | 170
++++++++------------- 5 files changed, 78 insertions(+), 109 deletions(-) create mode 100644 doc/device-tree-bindings/serial/xilinx_uartlite.txt
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 604f6815af5b..30ea484f48aa 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -13,6 +13,7 @@ config TARGET_MICROBLAZE_GENERIC select SUPPORT_SPL select OF_CONTROL select DM
select DM_SERIAL
endchoice
diff --git a/configs/microblaze-generic_defconfig b/configs/microblaze-generic_defconfig index 54aa3ef3d26f..5df080b6a87c 100644 --- a/configs/microblaze-generic_defconfig +++ b/configs/microblaze-generic_defconfig @@ -1,9 +1,11 @@ CONFIG_MICROBLAZE=y CONFIG_SPL_SYS_MALLOC_SIMPLE=y +CONFIG_SPL_DM=y CONFIG_TARGET_MICROBLAZE_GENERIC=y CONFIG_DEFAULT_DEVICE_TREE="microblaze-generic" CONFIG_SPL=y CONFIG_SYS_PROMPT="U-Boot-mONStR> " CONFIG_CMD_GPIO=y # CONFIG_CMD_SETEXPR is not set +CONFIG_SPL_OF_CONTROL=y CONFIG_OF_EMBED=y diff --git a/doc/device-tree-bindings/serial/xilinx_uartlite.txt b/doc/device-tree-bindings/serial/xilinx_uartlite.txt new file mode 100644 index 000000000000..d15753c8c380 --- /dev/null +++ b/doc/device-tree-bindings/serial/xilinx_uartlite.txt @@ -0,0 +1,13 @@ +Binding for Xilinx Uartlite Controller
+Required properties: +- compatible : should be "xlnx,xps-uartlite-1.00.a", or "xlnx,opb-uartlite-1.00.b" +- reg: Should contain UART controller registers location and length. +- interrupts: Should contain UART controller interrupts.
+Example:
- serial@40600000 {
compatible = "xlnx,xps-uartlite-1.00.a";
interrupts = <1 0>;
reg = <0x40600000 0x10000>;
- };
diff --git a/doc/driver-model/serial-howto.txt b/doc/driver-model/serial-howto.txt index 76ad629ef9cb..381a2a084562 100644 --- a/doc/driver-model/serial-howto.txt +++ b/doc/driver-model/serial-howto.txt @@ -18,7 +18,6 @@ is time for maintainers to start converting over the remaining serial drivers: serial_pxa.c serial_s3c24x0.c serial_sa1100.c
serial_xuartlite.c usbtty.c
You should complete this by the end of January 2016.
diff --git a/drivers/serial/serial_xuartlite.c b/drivers/serial/serial_xuartlite.c index 988438e75471..8225d9a320a5 100644 --- a/drivers/serial/serial_xuartlite.c +++ b/drivers/serial/serial_xuartlite.c @@ -1,5 +1,5 @@ /*
- (C) Copyright 2008-2011 Michal Simek monstr@monstr.eu
- (C) Copyright 2008 - 2015 Michal Simek monstr@monstr.eu
- Clean driver and add xilinx constant from header file
- (C) Copyright 2004 Atmark Techno, Inc.
@@ -10,11 +10,15 @@
#include <config.h> #include <common.h> +#include <dm.h> #include <asm/io.h> #include <linux/compiler.h> #include <serial.h>
+DECLARE_GLOBAL_DATA_PTR;
- #define SR_TX_FIFO_FULL 0x08 /* transmit FIFO full */
+#define SR_TX_FIFO_EMPTY 0x04 /* transmit FIFO empty */ #define SR_RX_FIFO_VALID_DATA 0x01 /* data in receive FIFO */ #define SR_RX_FIFO_FULL 0x02 /* receive FIFO full */
@@ -28,135 +32,85 @@ struct uartlite { unsigned int control; };
-static struct uartlite *userial_ports[4] = { -#ifdef XILINX_UARTLITE_BASEADDR
- [0] = (struct uartlite *)XILINX_UARTLITE_BASEADDR,
-#endif -#ifdef XILINX_UARTLITE_BASEADDR1
- [1] = (struct uartlite *)XILINX_UARTLITE_BASEADDR1,
-#endif -#ifdef XILINX_UARTLITE_BASEADDR2
- [2] = (struct uartlite *)XILINX_UARTLITE_BASEADDR2,
-#endif -#ifdef XILINX_UARTLITE_BASEADDR3
- [3] = (struct uartlite *)XILINX_UARTLITE_BASEADDR3
-#endif +struct uartlite_platdata {
- struct uartlite *regs; };
-static void uartlite_serial_putc(const char c, const int port) +static int uartlite_serial_putc(struct udevice *dev, const char ch) {
- struct uartlite *regs = userial_ports[port];
- struct uartlite_platdata *plat = dev_get_platdata(dev);
- struct uartlite *regs = plat->regs;
- if (c == '\n')
uartlite_serial_putc('\r', port);
- if (in_be32(®s->status) & SR_TX_FIFO_FULL)
return -EAGAIN;
- while (in_be32(®s->status) & SR_TX_FIFO_FULL)
;
- out_be32(®s->tx_fifo, c & 0xff);
-}
- out_be32(®s->tx_fifo, ch & 0xff);
-static void uartlite_serial_puts(const char *s, const int port) -{
- while (*s)
uartlite_serial_putc(*s++, port);
- return 0; }
-static int uartlite_serial_getc(const int port) +static int uartlite_serial_getc(struct udevice *dev) {
- struct uartlite *regs = userial_ports[port];
- struct uartlite_platdata *plat = dev_get_platdata(dev);
- struct uartlite *regs = plat->regs;
- if (!(in_be32(®s->status) & SR_RX_FIFO_VALID_DATA))
return -EAGAIN;
- while (!(in_be32(®s->status) & SR_RX_FIFO_VALID_DATA))
}; return in_be32(®s->rx_fifo) & 0xff;
-static int uartlite_serial_tstc(const int port) +static int uartlite_serial_pending(struct udevice *dev, bool input) {
- struct uartlite *regs = userial_ports[port];
- struct uartlite_platdata *plat = dev_get_platdata(dev);
- struct uartlite *regs = plat->regs;
- return in_be32(®s->status) & SR_RX_FIFO_VALID_DATA;
- if (input)
return in_be32(®s->status) & SR_RX_FIFO_VALID_DATA;
- return in_be32(®s->status) & SR_TX_FIFO_EMPTY;
Should be inversed.
Otherwise, Reviewed-by: Thomas Chou thomas@wytron.com.tw
Can you please tell me more about it? I was trying to understand logic of this function but pending function is called just from here. (maybe I missed other occurrences but drivers/serial/serial-uclass.c:157: if (ops->pending) drivers/serial/serial-uclass.c:158: return ops->pending(dev, true);
And not for output.
From docs @return number of waiting characters, 0 for none, -ve on error
It means I do read status and mask it if tx fifo is empty or not. If it is empty I am returning 0, if it is not empty I do return non 0 value.
The similar logix is used for input.
Is this logic wrong?
Be careful to return 1 if you don't know how many characters are waiting. It looks like you return 'in_be32(®s->status) & SR_RX_FIFO_VALID_DATA' which could be >1.
IP doesn't provide information how many chars is in FIFO. It can be 1 to 16. No problem to return just 1 for more than 1 char in FIFO. Is core working with that information?
It has no effect right now, but in the future we might use it. If you know there is at least one character, it is safe to return 1.
I suppose the UART does not support reading a single byte?
Regards, Simon

On 18.12.2015 03:40, Simon Glass wrote:
Hi Michal,
On 17 December 2015 at 11:52, Michal Simek michal.simek@xilinx.com wrote:
On 17.12.2015 16:27, Simon Glass wrote:
Hi Michal,
On 17 December 2015 at 06:58, Michal Simek michal.simek@xilinx.com wrote:
On 17.12.2015 14:37, Thomas Chou wrote:
Hi Michal,
On 2015年12月17日 20:00, Michal Simek wrote:
Enable SPL DM too.
Signed-off-by: Michal Simek michal.simek@xilinx.com
Changes in v2:
Remove unneeded headers
Use get_dev_addr instead of fdtdec_get_addr
Use platdata instead of private data
Add opb compatible string to be in sync with Linux
Add binding documentation
arch/microblaze/Kconfig | 1 + configs/microblaze-generic_defconfig | 2 + .../serial/xilinx_uartlite.txt | 13 ++ doc/driver-model/serial-howto.txt | 1 - drivers/serial/serial_xuartlite.c | 170
++++++++------------- 5 files changed, 78 insertions(+), 109 deletions(-) create mode 100644 doc/device-tree-bindings/serial/xilinx_uartlite.txt
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 604f6815af5b..30ea484f48aa 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -13,6 +13,7 @@ config TARGET_MICROBLAZE_GENERIC select SUPPORT_SPL select OF_CONTROL select DM
select DM_SERIAL
endchoice
diff --git a/configs/microblaze-generic_defconfig b/configs/microblaze-generic_defconfig index 54aa3ef3d26f..5df080b6a87c 100644 --- a/configs/microblaze-generic_defconfig +++ b/configs/microblaze-generic_defconfig @@ -1,9 +1,11 @@ CONFIG_MICROBLAZE=y CONFIG_SPL_SYS_MALLOC_SIMPLE=y +CONFIG_SPL_DM=y CONFIG_TARGET_MICROBLAZE_GENERIC=y CONFIG_DEFAULT_DEVICE_TREE="microblaze-generic" CONFIG_SPL=y CONFIG_SYS_PROMPT="U-Boot-mONStR> " CONFIG_CMD_GPIO=y # CONFIG_CMD_SETEXPR is not set +CONFIG_SPL_OF_CONTROL=y CONFIG_OF_EMBED=y diff --git a/doc/device-tree-bindings/serial/xilinx_uartlite.txt b/doc/device-tree-bindings/serial/xilinx_uartlite.txt new file mode 100644 index 000000000000..d15753c8c380 --- /dev/null +++ b/doc/device-tree-bindings/serial/xilinx_uartlite.txt @@ -0,0 +1,13 @@ +Binding for Xilinx Uartlite Controller
+Required properties: +- compatible : should be "xlnx,xps-uartlite-1.00.a", or "xlnx,opb-uartlite-1.00.b" +- reg: Should contain UART controller registers location and length. +- interrupts: Should contain UART controller interrupts.
+Example:
- serial@40600000 {
compatible = "xlnx,xps-uartlite-1.00.a";
interrupts = <1 0>;
reg = <0x40600000 0x10000>;
- };
diff --git a/doc/driver-model/serial-howto.txt b/doc/driver-model/serial-howto.txt index 76ad629ef9cb..381a2a084562 100644 --- a/doc/driver-model/serial-howto.txt +++ b/doc/driver-model/serial-howto.txt @@ -18,7 +18,6 @@ is time for maintainers to start converting over the remaining serial drivers: serial_pxa.c serial_s3c24x0.c serial_sa1100.c
serial_xuartlite.c usbtty.c
You should complete this by the end of January 2016.
diff --git a/drivers/serial/serial_xuartlite.c b/drivers/serial/serial_xuartlite.c index 988438e75471..8225d9a320a5 100644 --- a/drivers/serial/serial_xuartlite.c +++ b/drivers/serial/serial_xuartlite.c @@ -1,5 +1,5 @@ /*
- (C) Copyright 2008-2011 Michal Simek monstr@monstr.eu
- (C) Copyright 2008 - 2015 Michal Simek monstr@monstr.eu
- Clean driver and add xilinx constant from header file
- (C) Copyright 2004 Atmark Techno, Inc.
@@ -10,11 +10,15 @@
#include <config.h> #include <common.h> +#include <dm.h> #include <asm/io.h> #include <linux/compiler.h> #include <serial.h>
+DECLARE_GLOBAL_DATA_PTR;
- #define SR_TX_FIFO_FULL 0x08 /* transmit FIFO full */
+#define SR_TX_FIFO_EMPTY 0x04 /* transmit FIFO empty */ #define SR_RX_FIFO_VALID_DATA 0x01 /* data in receive FIFO */ #define SR_RX_FIFO_FULL 0x02 /* receive FIFO full */
@@ -28,135 +32,85 @@ struct uartlite { unsigned int control; };
-static struct uartlite *userial_ports[4] = { -#ifdef XILINX_UARTLITE_BASEADDR
- [0] = (struct uartlite *)XILINX_UARTLITE_BASEADDR,
-#endif -#ifdef XILINX_UARTLITE_BASEADDR1
- [1] = (struct uartlite *)XILINX_UARTLITE_BASEADDR1,
-#endif -#ifdef XILINX_UARTLITE_BASEADDR2
- [2] = (struct uartlite *)XILINX_UARTLITE_BASEADDR2,
-#endif -#ifdef XILINX_UARTLITE_BASEADDR3
- [3] = (struct uartlite *)XILINX_UARTLITE_BASEADDR3
-#endif +struct uartlite_platdata {
- struct uartlite *regs; };
-static void uartlite_serial_putc(const char c, const int port) +static int uartlite_serial_putc(struct udevice *dev, const char ch) {
- struct uartlite *regs = userial_ports[port];
- struct uartlite_platdata *plat = dev_get_platdata(dev);
- struct uartlite *regs = plat->regs;
- if (c == '\n')
uartlite_serial_putc('\r', port);
- if (in_be32(®s->status) & SR_TX_FIFO_FULL)
return -EAGAIN;
- while (in_be32(®s->status) & SR_TX_FIFO_FULL)
;
- out_be32(®s->tx_fifo, c & 0xff);
-}
- out_be32(®s->tx_fifo, ch & 0xff);
-static void uartlite_serial_puts(const char *s, const int port) -{
- while (*s)
uartlite_serial_putc(*s++, port);
- return 0; }
-static int uartlite_serial_getc(const int port) +static int uartlite_serial_getc(struct udevice *dev) {
- struct uartlite *regs = userial_ports[port];
- struct uartlite_platdata *plat = dev_get_platdata(dev);
- struct uartlite *regs = plat->regs;
- if (!(in_be32(®s->status) & SR_RX_FIFO_VALID_DATA))
return -EAGAIN;
- while (!(in_be32(®s->status) & SR_RX_FIFO_VALID_DATA))
}; return in_be32(®s->rx_fifo) & 0xff;
-static int uartlite_serial_tstc(const int port) +static int uartlite_serial_pending(struct udevice *dev, bool input) {
- struct uartlite *regs = userial_ports[port];
- struct uartlite_platdata *plat = dev_get_platdata(dev);
- struct uartlite *regs = plat->regs;
- return in_be32(®s->status) & SR_RX_FIFO_VALID_DATA;
- if (input)
return in_be32(®s->status) & SR_RX_FIFO_VALID_DATA;
- return in_be32(®s->status) & SR_TX_FIFO_EMPTY;
Should be inversed.
Otherwise, Reviewed-by: Thomas Chou thomas@wytron.com.tw
Can you please tell me more about it? I was trying to understand logic of this function but pending function is called just from here. (maybe I missed other occurrences but drivers/serial/serial-uclass.c:157: if (ops->pending) drivers/serial/serial-uclass.c:158: return ops->pending(dev, true);
And not for output.
From docs @return number of waiting characters, 0 for none, -ve on error
It means I do read status and mask it if tx fifo is empty or not. If it is empty I am returning 0, if it is not empty I do return non 0 value.
The similar logix is used for input.
Is this logic wrong?
Be careful to return 1 if you don't know how many characters are waiting. It looks like you return 'in_be32(®s->status) & SR_RX_FIFO_VALID_DATA' which could be >1.
IP doesn't provide information how many chars is in FIFO. It can be 1 to 16. No problem to return just 1 for more than 1 char in FIFO. Is core working with that information?
It has no effect right now, but in the future we might use it. If you know there is at least one character, it is safe to return 1.
ok.
I suppose the UART does not support reading a single byte?
Based on http://www.xilinx.com/support/documentation/ip_documentation/axi_uartlite/v2...
data bits can be 5-8. 8 is standard setting. Regarding reading just single byte from IP. There shouldn't be any problem with reading just single byte from current version but the problem is that this is pretty old IP and IRC this is not supported in every IP version. Also there were LE/BE versions. That's why I think it is just safer to use 32bit read.
Thanks, Michal

Hi Michal,
On 2015年12月17日 21:58, Michal Simek wrote:
On 17.12.2015 14:37, Thomas Chou wrote:
Hi Michal,
On 2015年12月17日 20:00, Michal Simek wrote:
Enable SPL DM too.
Signed-off-by: Michal Simek michal.simek@xilinx.com
Changes in v2:
Remove unneeded headers
Use get_dev_addr instead of fdtdec_get_addr
Use platdata instead of private data
Add opb compatible string to be in sync with Linux
Add binding documentation
arch/microblaze/Kconfig | 1 + configs/microblaze-generic_defconfig | 2 + .../serial/xilinx_uartlite.txt | 13 ++ doc/driver-model/serial-howto.txt | 1 - drivers/serial/serial_xuartlite.c | 170
++++++++------------- 5 files changed, 78 insertions(+), 109 deletions(-) create mode 100644 doc/device-tree-bindings/serial/xilinx_uartlite.txt
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 604f6815af5b..30ea484f48aa 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -13,6 +13,7 @@ config TARGET_MICROBLAZE_GENERIC select SUPPORT_SPL select OF_CONTROL select DM
select DM_SERIAL
endchoice
diff --git a/configs/microblaze-generic_defconfig b/configs/microblaze-generic_defconfig index 54aa3ef3d26f..5df080b6a87c 100644 --- a/configs/microblaze-generic_defconfig +++ b/configs/microblaze-generic_defconfig @@ -1,9 +1,11 @@ CONFIG_MICROBLAZE=y CONFIG_SPL_SYS_MALLOC_SIMPLE=y +CONFIG_SPL_DM=y CONFIG_TARGET_MICROBLAZE_GENERIC=y CONFIG_DEFAULT_DEVICE_TREE="microblaze-generic" CONFIG_SPL=y CONFIG_SYS_PROMPT="U-Boot-mONStR> " CONFIG_CMD_GPIO=y # CONFIG_CMD_SETEXPR is not set +CONFIG_SPL_OF_CONTROL=y CONFIG_OF_EMBED=y diff --git a/doc/device-tree-bindings/serial/xilinx_uartlite.txt b/doc/device-tree-bindings/serial/xilinx_uartlite.txt new file mode 100644 index 000000000000..d15753c8c380 --- /dev/null +++ b/doc/device-tree-bindings/serial/xilinx_uartlite.txt @@ -0,0 +1,13 @@ +Binding for Xilinx Uartlite Controller
+Required properties: +- compatible : should be "xlnx,xps-uartlite-1.00.a", or "xlnx,opb-uartlite-1.00.b" +- reg: Should contain UART controller registers location and length. +- interrupts: Should contain UART controller interrupts.
+Example:
- serial@40600000 {
compatible = "xlnx,xps-uartlite-1.00.a";
interrupts = <1 0>;
reg = <0x40600000 0x10000>;
- };
diff --git a/doc/driver-model/serial-howto.txt b/doc/driver-model/serial-howto.txt index 76ad629ef9cb..381a2a084562 100644 --- a/doc/driver-model/serial-howto.txt +++ b/doc/driver-model/serial-howto.txt @@ -18,7 +18,6 @@ is time for maintainers to start converting over the remaining serial drivers: serial_pxa.c serial_s3c24x0.c serial_sa1100.c
serial_xuartlite.c usbtty.c
You should complete this by the end of January 2016.
diff --git a/drivers/serial/serial_xuartlite.c b/drivers/serial/serial_xuartlite.c index 988438e75471..8225d9a320a5 100644 --- a/drivers/serial/serial_xuartlite.c +++ b/drivers/serial/serial_xuartlite.c @@ -1,5 +1,5 @@ /*
- (C) Copyright 2008-2011 Michal Simek monstr@monstr.eu
- (C) Copyright 2008 - 2015 Michal Simek monstr@monstr.eu
- Clean driver and add xilinx constant from header file
- (C) Copyright 2004 Atmark Techno, Inc.
@@ -10,11 +10,15 @@
#include <config.h> #include <common.h> +#include <dm.h> #include <asm/io.h> #include <linux/compiler.h> #include <serial.h>
+DECLARE_GLOBAL_DATA_PTR;
- #define SR_TX_FIFO_FULL 0x08 /* transmit FIFO full */
+#define SR_TX_FIFO_EMPTY 0x04 /* transmit FIFO empty */ #define SR_RX_FIFO_VALID_DATA 0x01 /* data in receive FIFO */ #define SR_RX_FIFO_FULL 0x02 /* receive FIFO full */
@@ -28,135 +32,85 @@ struct uartlite { unsigned int control; };
-static struct uartlite *userial_ports[4] = { -#ifdef XILINX_UARTLITE_BASEADDR
- [0] = (struct uartlite *)XILINX_UARTLITE_BASEADDR,
-#endif -#ifdef XILINX_UARTLITE_BASEADDR1
- [1] = (struct uartlite *)XILINX_UARTLITE_BASEADDR1,
-#endif -#ifdef XILINX_UARTLITE_BASEADDR2
- [2] = (struct uartlite *)XILINX_UARTLITE_BASEADDR2,
-#endif -#ifdef XILINX_UARTLITE_BASEADDR3
- [3] = (struct uartlite *)XILINX_UARTLITE_BASEADDR3
-#endif +struct uartlite_platdata {
- struct uartlite *regs; };
-static void uartlite_serial_putc(const char c, const int port) +static int uartlite_serial_putc(struct udevice *dev, const char ch) {
- struct uartlite *regs = userial_ports[port];
- struct uartlite_platdata *plat = dev_get_platdata(dev);
- struct uartlite *regs = plat->regs;
- if (c == '\n')
uartlite_serial_putc('\r', port);
- if (in_be32(®s->status) & SR_TX_FIFO_FULL)
return -EAGAIN;
- while (in_be32(®s->status) & SR_TX_FIFO_FULL)
;
- out_be32(®s->tx_fifo, c & 0xff);
-}
- out_be32(®s->tx_fifo, ch & 0xff);
-static void uartlite_serial_puts(const char *s, const int port) -{
- while (*s)
uartlite_serial_putc(*s++, port);
- return 0; }
-static int uartlite_serial_getc(const int port) +static int uartlite_serial_getc(struct udevice *dev) {
- struct uartlite *regs = userial_ports[port];
- struct uartlite_platdata *plat = dev_get_platdata(dev);
- struct uartlite *regs = plat->regs;
- if (!(in_be32(®s->status) & SR_RX_FIFO_VALID_DATA))
return -EAGAIN;
- while (!(in_be32(®s->status) & SR_RX_FIFO_VALID_DATA))
}; return in_be32(®s->rx_fifo) & 0xff;
-static int uartlite_serial_tstc(const int port) +static int uartlite_serial_pending(struct udevice *dev, bool input) {
- struct uartlite *regs = userial_ports[port];
- struct uartlite_platdata *plat = dev_get_platdata(dev);
- struct uartlite *regs = plat->regs;
- return in_be32(®s->status) & SR_RX_FIFO_VALID_DATA;
- if (input)
return in_be32(®s->status) & SR_RX_FIFO_VALID_DATA;
- return in_be32(®s->status) & SR_TX_FIFO_EMPTY;
Should be inversed.
Otherwise, Reviewed-by: Thomas Chou thomas@wytron.com.tw
Can you please tell me more about it? I was trying to understand logic of this function but pending function is called just from here. (maybe I missed other occurrences but drivers/serial/serial-uclass.c:157: if (ops->pending) drivers/serial/serial-uclass.c:158: return ops->pending(dev, true);
And not for output.
From docs
@return number of waiting characters, 0 for none, -ve on error
It means I do read status and mask it if tx fifo is empty or not. If it is empty I am returning 0, if it is not empty I do return non 0 value.
The similar logix is used for input.
Is this logic wrong?
+ return in_be32(®s->status) & SR_TX_FIFO_EMPTY;
Yes, the logic is wrong. Your code return non 0 if empty, and 0 if not empty.
BTW, you might want to convert the following macros to BIT() with a follow-up.
#define SR_TX_FIFO_FULL 0x08 /* transmit FIFO full */ +#define SR_TX_FIFO_EMPTY 0x04 /* transmit FIFO empty */ #define SR_RX_FIFO_VALID_DATA 0x01 /* data in receive FIFO */ #define SR_RX_FIFO_FULL 0x02 /* receive FIFO full */
Best regards, Thomas
Thanks, Michal

On 18.12.2015 00:35, Thomas Chou wrote:
Hi Michal,
On 2015年12月17日 21:58, Michal Simek wrote:
On 17.12.2015 14:37, Thomas Chou wrote:
Hi Michal,
On 2015年12月17日 20:00, Michal Simek wrote:
Enable SPL DM too.
Signed-off-by: Michal Simek michal.simek@xilinx.com
Changes in v2:
Remove unneeded headers
Use get_dev_addr instead of fdtdec_get_addr
Use platdata instead of private data
Add opb compatible string to be in sync with Linux
Add binding documentation
arch/microblaze/Kconfig | 1 + configs/microblaze-generic_defconfig | 2 + .../serial/xilinx_uartlite.txt | 13 ++ doc/driver-model/serial-howto.txt | 1 - drivers/serial/serial_xuartlite.c | 170
++++++++------------- 5 files changed, 78 insertions(+), 109 deletions(-) create mode 100644 doc/device-tree-bindings/serial/xilinx_uartlite.txt
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 604f6815af5b..30ea484f48aa 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -13,6 +13,7 @@ config TARGET_MICROBLAZE_GENERIC select SUPPORT_SPL select OF_CONTROL select DM
select DM_SERIAL
endchoice
diff --git a/configs/microblaze-generic_defconfig b/configs/microblaze-generic_defconfig index 54aa3ef3d26f..5df080b6a87c 100644 --- a/configs/microblaze-generic_defconfig +++ b/configs/microblaze-generic_defconfig @@ -1,9 +1,11 @@ CONFIG_MICROBLAZE=y CONFIG_SPL_SYS_MALLOC_SIMPLE=y +CONFIG_SPL_DM=y CONFIG_TARGET_MICROBLAZE_GENERIC=y CONFIG_DEFAULT_DEVICE_TREE="microblaze-generic" CONFIG_SPL=y CONFIG_SYS_PROMPT="U-Boot-mONStR> " CONFIG_CMD_GPIO=y # CONFIG_CMD_SETEXPR is not set +CONFIG_SPL_OF_CONTROL=y CONFIG_OF_EMBED=y diff --git a/doc/device-tree-bindings/serial/xilinx_uartlite.txt b/doc/device-tree-bindings/serial/xilinx_uartlite.txt new file mode 100644 index 000000000000..d15753c8c380 --- /dev/null +++ b/doc/device-tree-bindings/serial/xilinx_uartlite.txt @@ -0,0 +1,13 @@ +Binding for Xilinx Uartlite Controller
+Required properties: +- compatible : should be "xlnx,xps-uartlite-1.00.a", or "xlnx,opb-uartlite-1.00.b" +- reg: Should contain UART controller registers location and length. +- interrupts: Should contain UART controller interrupts.
+Example:
- serial@40600000 {
compatible = "xlnx,xps-uartlite-1.00.a";
interrupts = <1 0>;
reg = <0x40600000 0x10000>;
- };
diff --git a/doc/driver-model/serial-howto.txt b/doc/driver-model/serial-howto.txt index 76ad629ef9cb..381a2a084562 100644 --- a/doc/driver-model/serial-howto.txt +++ b/doc/driver-model/serial-howto.txt @@ -18,7 +18,6 @@ is time for maintainers to start converting over the remaining serial drivers: serial_pxa.c serial_s3c24x0.c serial_sa1100.c
serial_xuartlite.c usbtty.c
You should complete this by the end of January 2016.
diff --git a/drivers/serial/serial_xuartlite.c b/drivers/serial/serial_xuartlite.c index 988438e75471..8225d9a320a5 100644 --- a/drivers/serial/serial_xuartlite.c +++ b/drivers/serial/serial_xuartlite.c @@ -1,5 +1,5 @@ /*
- (C) Copyright 2008-2011 Michal Simek monstr@monstr.eu
- (C) Copyright 2008 - 2015 Michal Simek monstr@monstr.eu
- Clean driver and add xilinx constant from header file
- (C) Copyright 2004 Atmark Techno, Inc.
@@ -10,11 +10,15 @@
#include <config.h> #include <common.h> +#include <dm.h> #include <asm/io.h> #include <linux/compiler.h> #include <serial.h>
+DECLARE_GLOBAL_DATA_PTR;
- #define SR_TX_FIFO_FULL 0x08 /* transmit FIFO full */
+#define SR_TX_FIFO_EMPTY 0x04 /* transmit FIFO empty */ #define SR_RX_FIFO_VALID_DATA 0x01 /* data in receive FIFO */ #define SR_RX_FIFO_FULL 0x02 /* receive FIFO full */
@@ -28,135 +32,85 @@ struct uartlite { unsigned int control; };
-static struct uartlite *userial_ports[4] = { -#ifdef XILINX_UARTLITE_BASEADDR
- [0] = (struct uartlite *)XILINX_UARTLITE_BASEADDR,
-#endif -#ifdef XILINX_UARTLITE_BASEADDR1
- [1] = (struct uartlite *)XILINX_UARTLITE_BASEADDR1,
-#endif -#ifdef XILINX_UARTLITE_BASEADDR2
- [2] = (struct uartlite *)XILINX_UARTLITE_BASEADDR2,
-#endif -#ifdef XILINX_UARTLITE_BASEADDR3
- [3] = (struct uartlite *)XILINX_UARTLITE_BASEADDR3
-#endif +struct uartlite_platdata {
- struct uartlite *regs; };
-static void uartlite_serial_putc(const char c, const int port) +static int uartlite_serial_putc(struct udevice *dev, const char ch) {
- struct uartlite *regs = userial_ports[port];
- struct uartlite_platdata *plat = dev_get_platdata(dev);
- struct uartlite *regs = plat->regs;
- if (c == '\n')
uartlite_serial_putc('\r', port);
- if (in_be32(®s->status) & SR_TX_FIFO_FULL)
return -EAGAIN;
- while (in_be32(®s->status) & SR_TX_FIFO_FULL)
;
- out_be32(®s->tx_fifo, c & 0xff);
-}
- out_be32(®s->tx_fifo, ch & 0xff);
-static void uartlite_serial_puts(const char *s, const int port) -{
- while (*s)
uartlite_serial_putc(*s++, port);
- return 0; }
-static int uartlite_serial_getc(const int port) +static int uartlite_serial_getc(struct udevice *dev) {
- struct uartlite *regs = userial_ports[port];
- struct uartlite_platdata *plat = dev_get_platdata(dev);
- struct uartlite *regs = plat->regs;
- if (!(in_be32(®s->status) & SR_RX_FIFO_VALID_DATA))
return -EAGAIN;
- while (!(in_be32(®s->status) & SR_RX_FIFO_VALID_DATA))
}; return in_be32(®s->rx_fifo) & 0xff;
-static int uartlite_serial_tstc(const int port) +static int uartlite_serial_pending(struct udevice *dev, bool input) {
- struct uartlite *regs = userial_ports[port];
- struct uartlite_platdata *plat = dev_get_platdata(dev);
- struct uartlite *regs = plat->regs;
- return in_be32(®s->status) & SR_RX_FIFO_VALID_DATA;
- if (input)
return in_be32(®s->status) & SR_RX_FIFO_VALID_DATA;
- return in_be32(®s->status) & SR_TX_FIFO_EMPTY;
Should be inversed.
Otherwise, Reviewed-by: Thomas Chou thomas@wytron.com.tw
Can you please tell me more about it? I was trying to understand logic of this function but pending function is called just from here. (maybe I missed other occurrences but drivers/serial/serial-uclass.c:157: if (ops->pending) drivers/serial/serial-uclass.c:158: return ops->pending(dev, true);
And not for output.
From docs
@return number of waiting characters, 0 for none, -ve on error
It means I do read status and mask it if tx fifo is empty or not. If it is empty I am returning 0, if it is not empty I do return non 0 value.
The similar logix is used for input.
Is this logic wrong?
- return in_be32(®s->status) & SR_TX_FIFO_EMPTY;
Yes, the logic is wrong. Your code return non 0 if empty, and 0 if not empty.
right.
return !in_be32(®s->status) & SR_TX_FIFO_EMPTY;
BTW, you might want to convert the following macros to BIT() with a follow-up.
#define SR_TX_FIFO_FULL 0x08 /* transmit FIFO full */ +#define SR_TX_FIFO_EMPTY 0x04 /* transmit FIFO empty */ #define SR_RX_FIFO_VALID_DATA 0x01 /* data in receive FIFO */ #define SR_RX_FIFO_FULL 0x02 /* receive FIFO full */
NP with that.
Thanks, Michal

Hi Michal,
On 2015年12月18日 15:52, Michal Simek wrote:
On 18.12.2015 00:35, Thomas Chou wrote:
Hi Michal,
On 2015年12月17日 21:58, Michal Simek wrote:
On 17.12.2015 14:37, Thomas Chou wrote:
Hi Michal,
On 2015年12月17日 20:00, Michal Simek wrote:
Enable SPL DM too.
Signed-off-by: Michal Simek michal.simek@xilinx.com
Changes in v2:
Remove unneeded headers
Use get_dev_addr instead of fdtdec_get_addr
Use platdata instead of private data
Add opb compatible string to be in sync with Linux
Add binding documentation
arch/microblaze/Kconfig | 1 + configs/microblaze-generic_defconfig | 2 + .../serial/xilinx_uartlite.txt | 13 ++ doc/driver-model/serial-howto.txt | 1 - drivers/serial/serial_xuartlite.c | 170
++++++++------------- 5 files changed, 78 insertions(+), 109 deletions(-) create mode 100644 doc/device-tree-bindings/serial/xilinx_uartlite.txt
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 604f6815af5b..30ea484f48aa 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -13,6 +13,7 @@ config TARGET_MICROBLAZE_GENERIC select SUPPORT_SPL select OF_CONTROL select DM
select DM_SERIAL
endchoice
diff --git a/configs/microblaze-generic_defconfig b/configs/microblaze-generic_defconfig index 54aa3ef3d26f..5df080b6a87c 100644 --- a/configs/microblaze-generic_defconfig +++ b/configs/microblaze-generic_defconfig @@ -1,9 +1,11 @@ CONFIG_MICROBLAZE=y CONFIG_SPL_SYS_MALLOC_SIMPLE=y +CONFIG_SPL_DM=y CONFIG_TARGET_MICROBLAZE_GENERIC=y CONFIG_DEFAULT_DEVICE_TREE="microblaze-generic" CONFIG_SPL=y CONFIG_SYS_PROMPT="U-Boot-mONStR> " CONFIG_CMD_GPIO=y # CONFIG_CMD_SETEXPR is not set +CONFIG_SPL_OF_CONTROL=y CONFIG_OF_EMBED=y diff --git a/doc/device-tree-bindings/serial/xilinx_uartlite.txt b/doc/device-tree-bindings/serial/xilinx_uartlite.txt new file mode 100644 index 000000000000..d15753c8c380 --- /dev/null +++ b/doc/device-tree-bindings/serial/xilinx_uartlite.txt @@ -0,0 +1,13 @@ +Binding for Xilinx Uartlite Controller
+Required properties: +- compatible : should be "xlnx,xps-uartlite-1.00.a", or "xlnx,opb-uartlite-1.00.b" +- reg: Should contain UART controller registers location and length. +- interrupts: Should contain UART controller interrupts.
+Example:
- serial@40600000 {
compatible = "xlnx,xps-uartlite-1.00.a";
interrupts = <1 0>;
reg = <0x40600000 0x10000>;
- };
diff --git a/doc/driver-model/serial-howto.txt b/doc/driver-model/serial-howto.txt index 76ad629ef9cb..381a2a084562 100644 --- a/doc/driver-model/serial-howto.txt +++ b/doc/driver-model/serial-howto.txt @@ -18,7 +18,6 @@ is time for maintainers to start converting over the remaining serial drivers: serial_pxa.c serial_s3c24x0.c serial_sa1100.c
serial_xuartlite.c usbtty.c
You should complete this by the end of January 2016.
diff --git a/drivers/serial/serial_xuartlite.c b/drivers/serial/serial_xuartlite.c index 988438e75471..8225d9a320a5 100644 --- a/drivers/serial/serial_xuartlite.c +++ b/drivers/serial/serial_xuartlite.c @@ -1,5 +1,5 @@ /*
- (C) Copyright 2008-2011 Michal Simek monstr@monstr.eu
- (C) Copyright 2008 - 2015 Michal Simek monstr@monstr.eu
- Clean driver and add xilinx constant from header file
- (C) Copyright 2004 Atmark Techno, Inc.
@@ -10,11 +10,15 @@
#include <config.h> #include <common.h>
+#include <dm.h> #include <asm/io.h> #include <linux/compiler.h> #include <serial.h>
+DECLARE_GLOBAL_DATA_PTR;
- #define SR_TX_FIFO_FULL 0x08 /* transmit FIFO full */
+#define SR_TX_FIFO_EMPTY 0x04 /* transmit FIFO empty */ #define SR_RX_FIFO_VALID_DATA 0x01 /* data in receive FIFO */ #define SR_RX_FIFO_FULL 0x02 /* receive FIFO full */
@@ -28,135 +32,85 @@ struct uartlite { unsigned int control; };
-static struct uartlite *userial_ports[4] = { -#ifdef XILINX_UARTLITE_BASEADDR
- [0] = (struct uartlite *)XILINX_UARTLITE_BASEADDR,
-#endif -#ifdef XILINX_UARTLITE_BASEADDR1
- [1] = (struct uartlite *)XILINX_UARTLITE_BASEADDR1,
-#endif -#ifdef XILINX_UARTLITE_BASEADDR2
- [2] = (struct uartlite *)XILINX_UARTLITE_BASEADDR2,
-#endif -#ifdef XILINX_UARTLITE_BASEADDR3
- [3] = (struct uartlite *)XILINX_UARTLITE_BASEADDR3
-#endif +struct uartlite_platdata {
- struct uartlite *regs; };
-static void uartlite_serial_putc(const char c, const int port) +static int uartlite_serial_putc(struct udevice *dev, const char ch) {
- struct uartlite *regs = userial_ports[port];
- struct uartlite_platdata *plat = dev_get_platdata(dev);
- struct uartlite *regs = plat->regs;
- if (c == '\n')
uartlite_serial_putc('\r', port);
- if (in_be32(®s->status) & SR_TX_FIFO_FULL)
return -EAGAIN;
- while (in_be32(®s->status) & SR_TX_FIFO_FULL)
;
- out_be32(®s->tx_fifo, c & 0xff);
-}
- out_be32(®s->tx_fifo, ch & 0xff);
-static void uartlite_serial_puts(const char *s, const int port) -{
- while (*s)
uartlite_serial_putc(*s++, port);
- return 0; }
-static int uartlite_serial_getc(const int port) +static int uartlite_serial_getc(struct udevice *dev) {
- struct uartlite *regs = userial_ports[port];
- struct uartlite_platdata *plat = dev_get_platdata(dev);
- struct uartlite *regs = plat->regs;
- if (!(in_be32(®s->status) & SR_RX_FIFO_VALID_DATA))
return -EAGAIN;
- while (!(in_be32(®s->status) & SR_RX_FIFO_VALID_DATA))
}; return in_be32(®s->rx_fifo) & 0xff;
-static int uartlite_serial_tstc(const int port) +static int uartlite_serial_pending(struct udevice *dev, bool input) {
- struct uartlite *regs = userial_ports[port];
- struct uartlite_platdata *plat = dev_get_platdata(dev);
- struct uartlite *regs = plat->regs;
- return in_be32(®s->status) & SR_RX_FIFO_VALID_DATA;
- if (input)
return in_be32(®s->status) & SR_RX_FIFO_VALID_DATA;
- return in_be32(®s->status) & SR_TX_FIFO_EMPTY;
Should be inversed.
Otherwise, Reviewed-by: Thomas Chou thomas@wytron.com.tw
Can you please tell me more about it? I was trying to understand logic of this function but pending function is called just from here. (maybe I missed other occurrences but drivers/serial/serial-uclass.c:157: if (ops->pending) drivers/serial/serial-uclass.c:158: return ops->pending(dev, true);
And not for output.
From docs
@return number of waiting characters, 0 for none, -ve on error
It means I do read status and mask it if tx fifo is empty or not. If it is empty I am returning 0, if it is not empty I do return non 0 value.
The similar logix is used for input.
Is this logic wrong?
- return in_be32(®s->status) & SR_TX_FIFO_EMPTY;
Yes, the logic is wrong. Your code return non 0 if empty, and 0 if not empty.
right.
return !in_be32(®s->status) & SR_TX_FIFO_EMPTY;
As suggested by Simon, it might be better to return 1 when we don't know the count of pending.
if (input) return (in_be32(®s->status) & SR_RX_FIFO_VALID_DATA) ? 1 : 0;
return (in_be32(®s->status) & SR_TX_FIFO_EMPTY) ? 0 : 1;
BTW, you might want to convert the following macros to BIT() with a follow-up.
#define SR_TX_FIFO_FULL 0x08 /* transmit FIFO full */
+#define SR_TX_FIFO_EMPTY 0x04 /* transmit FIFO empty */ #define SR_RX_FIFO_VALID_DATA 0x01 /* data in receive FIFO */ #define SR_RX_FIFO_FULL 0x02 /* receive FIFO full */
NP with that.
Best regards, Thomas

On 18.12.2015 09:12, Thomas Chou wrote:
Hi Michal,
On 2015年12月18日 15:52, Michal Simek wrote:
On 18.12.2015 00:35, Thomas Chou wrote:
Hi Michal,
On 2015年12月17日 21:58, Michal Simek wrote:
On 17.12.2015 14:37, Thomas Chou wrote:
Hi Michal,
On 2015年12月17日 20:00, Michal Simek wrote:
Enable SPL DM too.
Signed-off-by: Michal Simek michal.simek@xilinx.com
Changes in v2:
Remove unneeded headers
Use get_dev_addr instead of fdtdec_get_addr
Use platdata instead of private data
Add opb compatible string to be in sync with Linux
Add binding documentation
arch/microblaze/Kconfig | 1 + configs/microblaze-generic_defconfig | 2 + .../serial/xilinx_uartlite.txt | 13 ++ doc/driver-model/serial-howto.txt | 1 - drivers/serial/serial_xuartlite.c | 170
++++++++------------- 5 files changed, 78 insertions(+), 109 deletions(-) create mode 100644 doc/device-tree-bindings/serial/xilinx_uartlite.txt
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 604f6815af5b..30ea484f48aa 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -13,6 +13,7 @@ config TARGET_MICROBLAZE_GENERIC select SUPPORT_SPL select OF_CONTROL select DM
select DM_SERIAL
endchoice
diff --git a/configs/microblaze-generic_defconfig b/configs/microblaze-generic_defconfig index 54aa3ef3d26f..5df080b6a87c 100644 --- a/configs/microblaze-generic_defconfig +++ b/configs/microblaze-generic_defconfig @@ -1,9 +1,11 @@ CONFIG_MICROBLAZE=y CONFIG_SPL_SYS_MALLOC_SIMPLE=y +CONFIG_SPL_DM=y CONFIG_TARGET_MICROBLAZE_GENERIC=y CONFIG_DEFAULT_DEVICE_TREE="microblaze-generic" CONFIG_SPL=y CONFIG_SYS_PROMPT="U-Boot-mONStR> " CONFIG_CMD_GPIO=y # CONFIG_CMD_SETEXPR is not set +CONFIG_SPL_OF_CONTROL=y CONFIG_OF_EMBED=y diff --git a/doc/device-tree-bindings/serial/xilinx_uartlite.txt b/doc/device-tree-bindings/serial/xilinx_uartlite.txt new file mode 100644 index 000000000000..d15753c8c380 --- /dev/null +++ b/doc/device-tree-bindings/serial/xilinx_uartlite.txt @@ -0,0 +1,13 @@ +Binding for Xilinx Uartlite Controller
+Required properties: +- compatible : should be "xlnx,xps-uartlite-1.00.a", or "xlnx,opb-uartlite-1.00.b" +- reg: Should contain UART controller registers location and length. +- interrupts: Should contain UART controller interrupts.
+Example:
- serial@40600000 {
compatible = "xlnx,xps-uartlite-1.00.a";
interrupts = <1 0>;
reg = <0x40600000 0x10000>;
- };
diff --git a/doc/driver-model/serial-howto.txt b/doc/driver-model/serial-howto.txt index 76ad629ef9cb..381a2a084562 100644 --- a/doc/driver-model/serial-howto.txt +++ b/doc/driver-model/serial-howto.txt @@ -18,7 +18,6 @@ is time for maintainers to start converting over the remaining serial drivers: serial_pxa.c serial_s3c24x0.c serial_sa1100.c
serial_xuartlite.c usbtty.c
You should complete this by the end of January 2016.
diff --git a/drivers/serial/serial_xuartlite.c b/drivers/serial/serial_xuartlite.c index 988438e75471..8225d9a320a5 100644 --- a/drivers/serial/serial_xuartlite.c +++ b/drivers/serial/serial_xuartlite.c @@ -1,5 +1,5 @@ /*
- (C) Copyright 2008-2011 Michal Simek monstr@monstr.eu
- (C) Copyright 2008 - 2015 Michal Simek monstr@monstr.eu
- Clean driver and add xilinx constant from header file
- (C) Copyright 2004 Atmark Techno, Inc.
@@ -10,11 +10,15 @@
#include <config.h> #include <common.h>
+#include <dm.h> #include <asm/io.h> #include <linux/compiler.h> #include <serial.h>
+DECLARE_GLOBAL_DATA_PTR;
- #define SR_TX_FIFO_FULL 0x08 /* transmit FIFO full */
+#define SR_TX_FIFO_EMPTY 0x04 /* transmit FIFO empty */ #define SR_RX_FIFO_VALID_DATA 0x01 /* data in receive FIFO */ #define SR_RX_FIFO_FULL 0x02 /* receive FIFO full */
@@ -28,135 +32,85 @@ struct uartlite { unsigned int control; };
-static struct uartlite *userial_ports[4] = { -#ifdef XILINX_UARTLITE_BASEADDR
- [0] = (struct uartlite *)XILINX_UARTLITE_BASEADDR,
-#endif -#ifdef XILINX_UARTLITE_BASEADDR1
- [1] = (struct uartlite *)XILINX_UARTLITE_BASEADDR1,
-#endif -#ifdef XILINX_UARTLITE_BASEADDR2
- [2] = (struct uartlite *)XILINX_UARTLITE_BASEADDR2,
-#endif -#ifdef XILINX_UARTLITE_BASEADDR3
- [3] = (struct uartlite *)XILINX_UARTLITE_BASEADDR3
-#endif +struct uartlite_platdata {
- struct uartlite *regs; };
-static void uartlite_serial_putc(const char c, const int port) +static int uartlite_serial_putc(struct udevice *dev, const char ch) {
- struct uartlite *regs = userial_ports[port];
- struct uartlite_platdata *plat = dev_get_platdata(dev);
- struct uartlite *regs = plat->regs;
- if (c == '\n')
uartlite_serial_putc('\r', port);
- if (in_be32(®s->status) & SR_TX_FIFO_FULL)
return -EAGAIN;
- while (in_be32(®s->status) & SR_TX_FIFO_FULL)
;
- out_be32(®s->tx_fifo, c & 0xff);
-}
- out_be32(®s->tx_fifo, ch & 0xff);
-static void uartlite_serial_puts(const char *s, const int port) -{
- while (*s)
uartlite_serial_putc(*s++, port);
- return 0; }
-static int uartlite_serial_getc(const int port) +static int uartlite_serial_getc(struct udevice *dev) {
- struct uartlite *regs = userial_ports[port];
- struct uartlite_platdata *plat = dev_get_platdata(dev);
- struct uartlite *regs = plat->regs;
- if (!(in_be32(®s->status) & SR_RX_FIFO_VALID_DATA))
return -EAGAIN;
- while (!(in_be32(®s->status) & SR_RX_FIFO_VALID_DATA))
}; return in_be32(®s->rx_fifo) & 0xff;
-static int uartlite_serial_tstc(const int port) +static int uartlite_serial_pending(struct udevice *dev, bool input) {
- struct uartlite *regs = userial_ports[port];
- struct uartlite_platdata *plat = dev_get_platdata(dev);
- struct uartlite *regs = plat->regs;
- return in_be32(®s->status) & SR_RX_FIFO_VALID_DATA;
- if (input)
return in_be32(®s->status) & SR_RX_FIFO_VALID_DATA;
- return in_be32(®s->status) & SR_TX_FIFO_EMPTY;
Should be inversed.
Otherwise, Reviewed-by: Thomas Chou thomas@wytron.com.tw
Can you please tell me more about it? I was trying to understand logic of this function but pending function is called just from here. (maybe I missed other occurrences but drivers/serial/serial-uclass.c:157: if (ops->pending) drivers/serial/serial-uclass.c:158: return ops->pending(dev, true);
And not for output.
From docs
@return number of waiting characters, 0 for none, -ve on error
It means I do read status and mask it if tx fifo is empty or not. If it is empty I am returning 0, if it is not empty I do return non 0 value.
The similar logix is used for input.
Is this logic wrong?
- return in_be32(®s->status) & SR_TX_FIFO_EMPTY;
Yes, the logic is wrong. Your code return non 0 if empty, and 0 if not empty.
right.
return !in_be32(®s->status) & SR_TX_FIFO_EMPTY;
As suggested by Simon, it might be better to return 1 when we don't know the count of pending.
if (input) return (in_be32(®s->status) & SR_RX_FIFO_VALID_DATA) ? 1 : 0;
SR_RX_FIFO_VALID_DATA is 1 already that's why I haven't done this because it is not needed.
return (in_be32(®s->status) & SR_TX_FIFO_EMPTY) ? 0 : 1;
And here FIFO_EMPTY is BIT(2)
It means this should also work. return !(in_be32(®s->status) & SR_TX_FIFO_EMPTY);
Thanks, Michal

Add support for debug console.
Signed-off-by: Michal Simek michal.simek@xilinx.com ---
Changes in v2: - Add needed header from the first patch - Remove WATCHDOG_RESET call - Extend commit description
drivers/serial/Kconfig | 7 +++++++ drivers/serial/serial_xuartlite.c | 26 ++++++++++++++++++++++++++ 2 files changed, 33 insertions(+)
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 1fc287ee98ec..f1e221799b81 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -92,6 +92,13 @@ config DEBUG_UART_S5P will need to provide parameters to make this work. The driver will be available until the real driver-model serial is running.
+config DEBUG_UART_UARTLITE + bool "Xilinx Uartlite" + help + Select this to enable a debug UART using the serial_uartlite driver. + You will need to provide parameters to make this work. The driver will + be available until the real driver-model serial is running. + config DEBUG_UART_ZYNQ bool "Xilinx Zynq" help diff --git a/drivers/serial/serial_xuartlite.c b/drivers/serial/serial_xuartlite.c index 8225d9a320a5..f42b11eae102 100644 --- a/drivers/serial/serial_xuartlite.c +++ b/drivers/serial/serial_xuartlite.c @@ -114,3 +114,29 @@ U_BOOT_DRIVER(serial_uartlite) = { .ops = &uartlite_serial_ops, .flags = DM_FLAG_PRE_RELOC, }; + +#ifdef CONFIG_DEBUG_UART_UARTLITE + +#include <debug_uart.h> + +void _debug_uart_init(void) +{ + struct uartlite *regs = (struct uartlite *)CONFIG_DEBUG_UART_BASE; + + out_be32(®s->control, 0); + out_be32(®s->control, ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX); + in_be32(®s->control); +} + +static inline void _debug_uart_putc(int ch) +{ + struct uartlite *regs = (struct uartlite *)CONFIG_DEBUG_UART_BASE; + + while (in_be32(®s->status) & SR_TX_FIFO_FULL) + ; + + out_be32(®s->tx_fifo, ch & 0xff); +} + +DEBUG_UART_FUNCS +#endif

Hi Michal,
On 2015年12月17日 20:00, Michal Simek wrote:
Add support for debug console.
Signed-off-by: Michal Simek michal.simek@xilinx.com
Changes in v2:
Add needed header from the first patch
Remove WATCHDOG_RESET call
Extend commit description
drivers/serial/Kconfig | 7 +++++++ drivers/serial/serial_xuartlite.c | 26 ++++++++++++++++++++++++++ 2 files changed, 33 insertions(+)
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 1fc287ee98ec..f1e221799b81 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -92,6 +92,13 @@ config DEBUG_UART_S5P will need to provide parameters to make this work. The driver will be available until the real driver-model serial is running.
+config DEBUG_UART_UARTLITE
- bool "Xilinx Uartlite"
- help
Select this to enable a debug UART using the serial_uartlite driver.
You will need to provide parameters to make this work. The driver will
be available until the real driver-model serial is running.
- config DEBUG_UART_ZYNQ bool "Xilinx Zynq" help
diff --git a/drivers/serial/serial_xuartlite.c b/drivers/serial/serial_xuartlite.c index 8225d9a320a5..f42b11eae102 100644 --- a/drivers/serial/serial_xuartlite.c +++ b/drivers/serial/serial_xuartlite.c @@ -114,3 +114,29 @@ U_BOOT_DRIVER(serial_uartlite) = { .ops = &uartlite_serial_ops, .flags = DM_FLAG_PRE_RELOC, };
+#ifdef CONFIG_DEBUG_UART_UARTLITE
+#include <debug_uart.h>
+void _debug_uart_init(void)
Still missing, static inline
Otherwise, Reviewed-by: Thomas Chou thomas@wytron.com.tw
+{
- struct uartlite *regs = (struct uartlite *)CONFIG_DEBUG_UART_BASE;
- out_be32(®s->control, 0);
- out_be32(®s->control, ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX);
- in_be32(®s->control);
+}
+static inline void _debug_uart_putc(int ch) +{
- struct uartlite *regs = (struct uartlite *)CONFIG_DEBUG_UART_BASE;
- while (in_be32(®s->status) & SR_TX_FIFO_FULL)
;
- out_be32(®s->tx_fifo, ch & 0xff);
+}
+DEBUG_UART_FUNCS +#endif
Best regards, Thomas

On 17.12.2015 14:29, Thomas Chou wrote:
Hi Michal,
On 2015年12月17日 20:00, Michal Simek wrote:
Add support for debug console.
Signed-off-by: Michal Simek michal.simek@xilinx.com
Changes in v2:
Add needed header from the first patch
Remove WATCHDOG_RESET call
Extend commit description
drivers/serial/Kconfig | 7 +++++++ drivers/serial/serial_xuartlite.c | 26 ++++++++++++++++++++++++++ 2 files changed, 33 insertions(+)
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 1fc287ee98ec..f1e221799b81 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -92,6 +92,13 @@ config DEBUG_UART_S5P will need to provide parameters to make this work. The driver will be available until the real driver-model serial is running.
+config DEBUG_UART_UARTLITE
- bool "Xilinx Uartlite"
- help
Select this to enable a debug UART using the serial_uartlite
driver.
You will need to provide parameters to make this work. The
driver will
be available until the real driver-model serial is running.
- config DEBUG_UART_ZYNQ bool "Xilinx Zynq" help
diff --git a/drivers/serial/serial_xuartlite.c b/drivers/serial/serial_xuartlite.c index 8225d9a320a5..f42b11eae102 100644 --- a/drivers/serial/serial_xuartlite.c +++ b/drivers/serial/serial_xuartlite.c @@ -114,3 +114,29 @@ U_BOOT_DRIVER(serial_uartlite) = { .ops = &uartlite_serial_ops, .flags = DM_FLAG_PRE_RELOC, };
+#ifdef CONFIG_DEBUG_UART_UARTLITE
+#include <debug_uart.h>
+void _debug_uart_init(void)
Still missing, static inline
Otherwise, Reviewed-by: Thomas Chou thomas@wytron.com.tw
I have sent separate patch for it and keep it here unchanged that's why it is not here.
I can send you like if you like but I think you will find it out.
Thanks, Michal

- Move config option out of board file. - Remove uartlite address from config file
Signed-off-by: Michal Simek michal.simek@xilinx.com ---
Changes in v2: None
board/xilinx/microblaze-generic/xparameters.h | 4 ---- configs/microblaze-generic_defconfig | 1 + drivers/serial/Kconfig | 7 +++++++ include/configs/microblaze-generic.h | 7 +------ 4 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/board/xilinx/microblaze-generic/xparameters.h b/board/xilinx/microblaze-generic/xparameters.h index 8ba146cb88db..11b3c9a4846e 100644 --- a/board/xilinx/microblaze-generic/xparameters.h +++ b/board/xilinx/microblaze-generic/xparameters.h @@ -28,10 +28,6 @@ #define XILINX_TIMER_BASEADDR 0x41c00000 #define XILINX_TIMER_IRQ 0
-/* Uart pheriphery is RS232_Uart */ -#define XILINX_UARTLITE_BASEADDR 0x40600000 -#define XILINX_UARTLITE_BAUDRATE 115200 - /* IIC pheriphery is IIC_EEPROM */ #define XILINX_IIC_0_BASEADDR 0x40800000 #define XILINX_IIC_0_FREQ 100000 diff --git a/configs/microblaze-generic_defconfig b/configs/microblaze-generic_defconfig index 5df080b6a87c..9a7bb915466f 100644 --- a/configs/microblaze-generic_defconfig +++ b/configs/microblaze-generic_defconfig @@ -9,3 +9,4 @@ CONFIG_CMD_GPIO=y # CONFIG_CMD_SETEXPR is not set CONFIG_SPL_OF_CONTROL=y CONFIG_OF_EMBED=y +CONFIG_XILINX_UARTLITE=y diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index f1e221799b81..ddf49ba9cef3 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -230,4 +230,11 @@ config UNIPHIER_SERIAL If you have a UniPhier based board and want to use the on-chip serial ports, say Y to this option. If unsure, say N.
+config XILINX_UARTLITE + bool "Xilinx Uarlite support" + depends on DM_SERIAL && (MICROBLAZE || ARCH_ZYNQ || ARCH_ZYNQMP) + help + If you have a Xilinx based board and want to use the uartlite + serial ports, say Y to this option. If unsure, say N. + endmenu diff --git a/include/configs/microblaze-generic.h b/include/configs/microblaze-generic.h index 10ac8328b8ff..6e3c80b14350 100644 --- a/include/configs/microblaze-generic.h +++ b/include/configs/microblaze-generic.h @@ -37,10 +37,7 @@ # define CONFIG_SYS_BAUDRATE_TABLE \ {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400}
-#ifdef XILINX_UARTLITE_BASEADDR -# define CONFIG_XILINX_UARTLITE -# define CONFIG_SERIAL_BASE XILINX_UARTLITE_BASEADDR -#elif XILINX_UART16550_BASEADDR +#if XILINX_UART16550_BASEADDR # define CONFIG_SYS_NS16550_SERIAL # if defined(__MICROBLAZEEL__) # define CONFIG_SYS_NS16550_REG_SIZE -4 @@ -51,8 +48,6 @@ # define CONFIG_SYS_NS16550_COM1 \ ((XILINX_UART16550_BASEADDR & ~0xF) + 0x1000) # define CONFIG_SYS_NS16550_CLK XILINX_UART16550_CLOCK_HZ -#else -# error Undefined uart #endif
/* setting reset address */

Hi Michal,
On 2015年12月17日 20:00, Michal Simek wrote:
- Move config option out of board file.
- Remove uartlite address from config file
Signed-off-by: Michal Simek michal.simek@xilinx.com
Changes in v2: None
board/xilinx/microblaze-generic/xparameters.h | 4 ---- configs/microblaze-generic_defconfig | 1 + drivers/serial/Kconfig | 7 +++++++ include/configs/microblaze-generic.h | 7 +------ 4 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/board/xilinx/microblaze-generic/xparameters.h b/board/xilinx/microblaze-generic/xparameters.h index 8ba146cb88db..11b3c9a4846e 100644 --- a/board/xilinx/microblaze-generic/xparameters.h +++ b/board/xilinx/microblaze-generic/xparameters.h @@ -28,10 +28,6 @@ #define XILINX_TIMER_BASEADDR 0x41c00000 #define XILINX_TIMER_IRQ 0
-/* Uart pheriphery is RS232_Uart */ -#define XILINX_UARTLITE_BASEADDR 0x40600000 -#define XILINX_UARTLITE_BAUDRATE 115200
- /* IIC pheriphery is IIC_EEPROM */ #define XILINX_IIC_0_BASEADDR 0x40800000 #define XILINX_IIC_0_FREQ 100000
diff --git a/configs/microblaze-generic_defconfig b/configs/microblaze-generic_defconfig index 5df080b6a87c..9a7bb915466f 100644 --- a/configs/microblaze-generic_defconfig +++ b/configs/microblaze-generic_defconfig @@ -9,3 +9,4 @@ CONFIG_CMD_GPIO=y # CONFIG_CMD_SETEXPR is not set CONFIG_SPL_OF_CONTROL=y CONFIG_OF_EMBED=y +CONFIG_XILINX_UARTLITE=y diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index f1e221799b81..ddf49ba9cef3 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -230,4 +230,11 @@ config UNIPHIER_SERIAL If you have a UniPhier based board and want to use the on-chip serial ports, say Y to this option. If unsure, say N.
+config XILINX_UARTLITE
- bool "Xilinx Uarlite support"
- depends on DM_SERIAL && (MICROBLAZE || ARCH_ZYNQ || ARCH_ZYNQMP)
- help
If you have a Xilinx based board and want to use the uartlite
serial ports, say Y to this option. If unsure, say N.
- endmenu
diff --git a/include/configs/microblaze-generic.h b/include/configs/microblaze-generic.h index 10ac8328b8ff..6e3c80b14350 100644 --- a/include/configs/microblaze-generic.h +++ b/include/configs/microblaze-generic.h @@ -37,10 +37,7 @@ # define CONFIG_SYS_BAUDRATE_TABLE \ {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400}
-#ifdef XILINX_UARTLITE_BASEADDR -# define CONFIG_XILINX_UARTLITE -# define CONFIG_SERIAL_BASE XILINX_UARTLITE_BASEADDR -#elif XILINX_UART16550_BASEADDR +#if XILINX_UART16550_BASEADDR # define CONFIG_SYS_NS16550_SERIAL # if defined(__MICROBLAZEEL__) # define CONFIG_SYS_NS16550_REG_SIZE -4 @@ -51,8 +48,6 @@ # define CONFIG_SYS_NS16550_COM1 \ ((XILINX_UART16550_BASEADDR & ~0xF) + 0x1000) # define CONFIG_SYS_NS16550_CLK XILINX_UART16550_CLOCK_HZ -#else -# error Undefined uart #endif
/* setting reset address */
Reviewed-by: Thomas Chou thomas@wytron.com.tw
Best regards, Thomas
participants (3)
-
Michal Simek
-
Simon Glass
-
Thomas Chou