Hi Andreas, > I have tried to implement an AUART driver for i.MX28. > However for it to work I must print 1 character to the > debug UART via the serial_pl01x driver. If I do this > the AUART will start working. If I don't nothing will > be printed to the AUART. Anybody can see any obvious errors? > > Signed-off-by: Andreas Wass <andreas.w...@dalelven.com>
I have to wonder, is the AUART no standard UART IP ? Probably not as Linux also has a separate driver for this ... Lots of rambling follows below, but please dont be put off by it. Make sure to CC me and Fabio on the next submission. I can help you debugging the driver if you clean it up a bit. > drivers/serial/Makefile | 1 + > drivers/serial/mxs-regs-uartapp.h | 307 > +++++++++++++++++++++++++++++++++++++ drivers/serial/mxs_auart.c | > 161 +++++++++++++++++++ > drivers/serial/serial.c | 11 +- > drivers/serial/serial_pl01x.c | 19 ++- > 5 files changed, 492 insertions(+), 7 deletions(-) > create mode 100644 drivers/serial/mxs-regs-uartapp.h > create mode 100644 drivers/serial/mxs_auart.c > > diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile > index fbc4e97..f4e0d45 100644 > --- a/drivers/serial/Makefile > +++ b/drivers/serial/Makefile > @@ -52,6 +52,7 @@ COBJS-$(CONFIG_XILINX_UARTLITE) += serial_xuartlite.o > COBJS-$(CONFIG_SANDBOX_SERIAL) += sandbox.o > COBJS-$(CONFIG_SCIF_CONSOLE) += serial_sh.o > COBJS-$(CONFIG_ZYNQ_SERIAL) += serial_zynq.o > +COBJS-$(CONFIG_MXS_AUART) += mxs_auart.o > > ifndef CONFIG_SPL_BUILD > COBJS-$(CONFIG_USB_TTY) += usbtty.o > diff --git a/drivers/serial/mxs-regs-uartapp.h > b/drivers/serial/mxs-regs-uartapp.h new file mode 100644 > index 0000000..aad9a78 > --- /dev/null > +++ b/drivers/serial/mxs-regs-uartapp.h [...] Please follow the pattern of arch/arm/include/asm/arch-mxs/regs-*.h with regards to struct-based access and using (1 << n) to declare bits. > diff --git a/drivers/serial/mxs_auart.c b/drivers/serial/mxs_auart.c > new file mode 100644 > index 0000000..b9a4e82 [...] > +#include <common.h> > +#include <serial.h> > +#include <linux/compiler.h> > +#include "mxs-regs-uartapp.h" > + > +DECLARE_GLOBAL_DATA_PTR; > + > +#define REGS_UARTAPP3_BASE (0x80070000) Use arch/arm/include/asm/arch-mxs/regs-base.h , but since there are multiple, you can add a config option to select which AUART to use. > +#define REGS_UARTAPP_BASE REGS_UARTAPP3_BASE > +#define REG_RD(base, reg) \ > + (*(volatile unsigned int *)((base) + (reg))) > +#define REG_WR(base, reg, value) \ > + ((*(volatile unsigned int *)((base) + (reg))) = (value)) Use readl() / writel() / clrsetbits_le32() etc. > +/* HACK should be removed when issue is fixed! */ > +void dbg_puts(const char *s); > + > +static void mxs_auart_reset(void) mxs_reset_block(); [...] > +/* > + * Set baud rate. The settings are always 8n1 > + */ > +void mxs_auart_setbrg(void) > +{ > + u32 div; > + u32 linectrl = 0; > + > + div = (CONFIG_MXS_AUART_CLK * 32) / CONFIG_BAUDRATE; Does this not integrate with the MXS clock stuff in arch/arm/cpu/arm926ejs/mxs/clock.c ? You might want to implement a function there to govern the clock speed somehow. > + linectrl |= BF_UARTAPP_LINECTRL_BAUD_DIVFRAC(div & 0x3F); > + linectrl |= BF_UARTAPP_LINECTRL_BAUD_DIVINT(div >> 6); > + linectrl |= BF_UARTAPP_LINECTRL_WLEN(3); > + linectrl |= BM_UARTAPP_LINECTRL_FEN; > + > + REG_WR(REGS_UARTAPP_BASE, HW_UARTAPP_LINECTRL, linectrl); > +} > + > +void mxs_auart_init(void) > +{ > + mxs_auart_reset(); mxs_reset_block() and drop the above ;-) > + REG_WR(REGS_UARTAPP_BASE, HW_UARTAPP_INTR, 0); > + serial_setbrg(); > + > + REG_WR(REGS_UARTAPP_BASE, HW_UARTAPP_CTRL2_CLR, > + BM_UARTAPP_CTRL2_RTSEN | BM_UARTAPP_CTRL2_CTSEN | > + BM_UARTAPP_CTRL2_USE_LCR2); > + REG_WR(REGS_UARTAPP_BASE, HW_UARTAPP_CTRL2_SET, > + BM_UARTAPP_CTRL2_RXE | BM_UARTAPP_CTRL2_TXE | > + BM_UARTAPP_CTRL2_UARTEN); > + > + /* HACK, the driver will not work without this. > + * Don't know how to fix > + */ See http://www.denx.de/wiki/U-Boot/CodingStyle about the comments. > + dbg_puts("\n"); Is your AUART set as default uart ? Or how do you operate it ? > + return 0; > +} > + > +void mxs_auart_putc(const char c) > +{ > + while (REG_RD(REGS_UARTAPP_BASE, HW_UARTAPP_STAT) & > + BM_UARTAPP_STAT_TXFF) > + ; Careful about endless loop here. > + REG_WR(REGS_UARTAPP_BASE, HW_UARTAPP_DATA, c); > + if (c == '\n') > + mxs_auart_putc('\r'); > + > +} > + > +void mxs_auart_puts(const char *s) > +{ > + while (*s) > + mxs_auart_putc(*s++); Use default_serial_puts() > +} > + > +int mxs_auart_tstc(void) > +{ > + return !(REG_RD(REGS_UARTAPP_BASE, HW_UARTAPP_STAT) & > + BM_UARTAPP_STAT_RXFE); > +} > + > +int mxs_auart_getc(void) > +{ > + while (!mxs_auart_tstc()) > + ; > + > + return REG_RD(REGS_UARTAPP_BASE, HW_UARTAPP_DATA) & 0xff; > +} > + > +static struct serial_device mxs_auart_drv = { > + .name = "mxs_auart_serial", > + .start = mxs_auart_init, > + .stop = NULL, > + .setbrg = mxs_auart_setbrg, > + .putc = mxs_auart_putc, > + .puts = mxs_auart_puts, > + .getc = mxs_auart_getc, > + .tstc = mxs_auart_tstc, > +}; > + > +void mxs_auart_initialize(void) > +{ > + serial_register(&mxs_auart_drv); > +} > + > +__weak struct serial_device *default_serial_console(void) > +{ > + return &mxs_auart_drv; > +} [...] _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot