diff mbox

[U-Boot] Implement AUART for i.MX28

Message ID 74CACEF26F2B2D418C5EDD0CCC0D2BECF60A51@DALELVENSRV1.dalelven.local
State Changes Requested
Delegated to: Stefano Babic
Headers show

Commit Message

Andreas Wass July 9, 2013, 6 a.m. UTC
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.wass@dalelven.com>
---
 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

Comments

Marek Vasut July 9, 2013, 10:46 p.m. UTC | #1
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.wass@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;
> +}

[...]
Marek Vasut Aug. 3, 2013, 6:35 p.m. UTC | #2
> 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.wass@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.

Bump, is there any progress here?

Best regards,
Marek Vasut
Andreas Wass Aug. 4, 2013, 9:10 a.m. UTC | #3
Hi

Sorry for not responding, work and vacation came in the way. 

No further work has been done, ill see if i can do some next week.

Kind regards
Andreas

3 aug 2013 kl. 20:35 skrev "Marek Vasut" <marex@denx.de>:

>> 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.wass@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.
> 
> Bump, is there any progress here?
> 
> Best regards,
> Marek Vasut
Marek Vasut Aug. 4, 2013, 11:10 a.m. UTC | #4
Hello Andreas,

> Hi
> 
> Sorry for not responding, work and vacation came in the way.
> 
> No further work has been done, ill see if i can do some next week.

OK

Best regards,
Marek Vasut
diff mbox

Patch

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
@@ -0,0 +1,307 @@ 
+/*
+ * Freescale UARTAPP Register Definitions
+ *
+ * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ * This file is created by xml file. Don't Edit it.
+ *
+ * Xml Revision: 1.42
+ * Template revision: 26195
+ */
+
+#ifndef __ARCH_ARM___UARTAPP_H
+#define __ARCH_ARM___UARTAPP_H
+
+
+#define HW_UARTAPP_CTRL0	(0x00000000)
+#define HW_UARTAPP_CTRL0_SET	(0x00000004)
+#define HW_UARTAPP_CTRL0_CLR	(0x00000008)
+#define HW_UARTAPP_CTRL0_TOG	(0x0000000c)
+
+#define BM_UARTAPP_CTRL0_SFTRST	0x80000000
+#define BM_UARTAPP_CTRL0_CLKGATE	0x40000000
+#define BM_UARTAPP_CTRL0_RUN	0x20000000
+#define BM_UARTAPP_CTRL0_RX_SOURCE	0x10000000
+#define BM_UARTAPP_CTRL0_RXTO_ENABLE	0x08000000
+#define BP_UARTAPP_CTRL0_RXTIMEOUT	16
+#define BM_UARTAPP_CTRL0_RXTIMEOUT	0x07FF0000
+#define BF_UARTAPP_CTRL0_RXTIMEOUT(v)  \
+		(((v) << 16) & BM_UARTAPP_CTRL0_RXTIMEOUT)
+#define BP_UARTAPP_CTRL0_XFER_COUNT	0
+#define BM_UARTAPP_CTRL0_XFER_COUNT	0x0000FFFF
+#define BF_UARTAPP_CTRL0_XFER_COUNT(v)  \
+		(((v) << 0) & BM_UARTAPP_CTRL0_XFER_COUNT)
+
+#define HW_UARTAPP_CTRL1	(0x00000010)
+#define HW_UARTAPP_CTRL1_SET	(0x00000014)
+#define HW_UARTAPP_CTRL1_CLR	(0x00000018)
+#define HW_UARTAPP_CTRL1_TOG	(0x0000001c)
+
+#define BP_UARTAPP_CTRL1_RSVD2	29
+#define BM_UARTAPP_CTRL1_RSVD2	0xE0000000
+#define BF_UARTAPP_CTRL1_RSVD2(v) \
+		(((v) << 29) & BM_UARTAPP_CTRL1_RSVD2)
+#define BM_UARTAPP_CTRL1_RUN	0x10000000
+#define BP_UARTAPP_CTRL1_RSVD1	16
+#define BM_UARTAPP_CTRL1_RSVD1	0x0FFF0000
+#define BF_UARTAPP_CTRL1_RSVD1(v)  \
+		(((v) << 16) & BM_UARTAPP_CTRL1_RSVD1)
+#define BP_UARTAPP_CTRL1_XFER_COUNT	0
+#define BM_UARTAPP_CTRL1_XFER_COUNT	0x0000FFFF
+#define BF_UARTAPP_CTRL1_XFER_COUNT(v)  \
+		(((v) << 0) & BM_UARTAPP_CTRL1_XFER_COUNT)
+
+#define HW_UARTAPP_CTRL2	(0x00000020)
+#define HW_UARTAPP_CTRL2_SET	(0x00000024)
+#define HW_UARTAPP_CTRL2_CLR	(0x00000028)
+#define HW_UARTAPP_CTRL2_TOG	(0x0000002c)
+
+#define BM_UARTAPP_CTRL2_INVERT_RTS	0x80000000
+#define BM_UARTAPP_CTRL2_INVERT_CTS	0x40000000
+#define BM_UARTAPP_CTRL2_INVERT_TX	0x20000000
+#define BM_UARTAPP_CTRL2_INVERT_RX	0x10000000
+#define BM_UARTAPP_CTRL2_RTS_SEMAPHORE	0x08000000
+#define BM_UARTAPP_CTRL2_DMAONERR	0x04000000
+#define BM_UARTAPP_CTRL2_TXDMAE	0x02000000
+#define BM_UARTAPP_CTRL2_RXDMAE	0x01000000
+#define BM_UARTAPP_CTRL2_RSVD2	0x00800000
+#define BP_UARTAPP_CTRL2_RXIFLSEL	20
+#define BM_UARTAPP_CTRL2_RXIFLSEL	0x00700000
+#define BF_UARTAPP_CTRL2_RXIFLSEL(v)  \
+		(((v) << 20) & BM_UARTAPP_CTRL2_RXIFLSEL)
+#define BV_UARTAPP_CTRL2_RXIFLSEL__NOT_EMPTY      0x0
+#define BV_UARTAPP_CTRL2_RXIFLSEL__ONE_QUARTER    0x1
+#define BV_UARTAPP_CTRL2_RXIFLSEL__ONE_HALF       0x2
+#define BV_UARTAPP_CTRL2_RXIFLSEL__THREE_QUARTERS 0x3
+#define BV_UARTAPP_CTRL2_RXIFLSEL__SEVEN_EIGHTHS  0x4
+#define BV_UARTAPP_CTRL2_RXIFLSEL__INVALID5       0x5
+#define BV_UARTAPP_CTRL2_RXIFLSEL__INVALID6       0x6
+#define BV_UARTAPP_CTRL2_RXIFLSEL__INVALID7       0x7
+#define BM_UARTAPP_CTRL2_RSVD3	0x00080000
+#define BP_UARTAPP_CTRL2_TXIFLSEL	16
+#define BM_UARTAPP_CTRL2_TXIFLSEL	0x00070000
+#define BF_UARTAPP_CTRL2_TXIFLSEL(v)  \
+		(((v) << 16) & BM_UARTAPP_CTRL2_TXIFLSEL)
+#define BV_UARTAPP_CTRL2_TXIFLSEL__EMPTY          0x0
+#define BV_UARTAPP_CTRL2_TXIFLSEL__ONE_QUARTER    0x1
+#define BV_UARTAPP_CTRL2_TXIFLSEL__ONE_HALF       0x2
+#define BV_UARTAPP_CTRL2_TXIFLSEL__THREE_QUARTERS 0x3
+#define BV_UARTAPP_CTRL2_TXIFLSEL__SEVEN_EIGHTHS  0x4
+#define BV_UARTAPP_CTRL2_TXIFLSEL__INVALID5       0x5
+#define BV_UARTAPP_CTRL2_TXIFLSEL__INVALID6       0x6
+#define BV_UARTAPP_CTRL2_TXIFLSEL__INVALID7       0x7
+#define BM_UARTAPP_CTRL2_CTSEN	0x00008000
+#define BM_UARTAPP_CTRL2_RTSEN	0x00004000
+#define BM_UARTAPP_CTRL2_OUT2	0x00002000
+#define BM_UARTAPP_CTRL2_OUT1	0x00001000
+#define BM_UARTAPP_CTRL2_RTS	0x00000800
+#define BM_UARTAPP_CTRL2_DTR	0x00000400
+#define BM_UARTAPP_CTRL2_RXE	0x00000200
+#define BM_UARTAPP_CTRL2_TXE	0x00000100
+#define BM_UARTAPP_CTRL2_LBE	0x00000080
+#define BM_UARTAPP_CTRL2_USE_LCR2	0x00000040
+#define BP_UARTAPP_CTRL2_RSVD4	3
+#define BM_UARTAPP_CTRL2_RSVD4	0x00000038
+#define BF_UARTAPP_CTRL2_RSVD4(v)  \
+		(((v) << 3) & BM_UARTAPP_CTRL2_RSVD4)
+#define BM_UARTAPP_CTRL2_SIRLP	0x00000004
+#define BM_UARTAPP_CTRL2_SIREN	0x00000002
+#define BM_UARTAPP_CTRL2_UARTEN	0x00000001
+
+#define HW_UARTAPP_LINECTRL	(0x00000030)
+#define HW_UARTAPP_LINECTRL_SET	(0x00000034)
+#define HW_UARTAPP_LINECTRL_CLR	(0x00000038)
+#define HW_UARTAPP_LINECTRL_TOG	(0x0000003c)
+
+#define BP_UARTAPP_LINECTRL_BAUD_DIVINT	16
+#define BM_UARTAPP_LINECTRL_BAUD_DIVINT	0xFFFF0000
+#define BF_UARTAPP_LINECTRL_BAUD_DIVINT(v) \
+		(((v) << 16) & BM_UARTAPP_LINECTRL_BAUD_DIVINT)
+#define BP_UARTAPP_LINECTRL_RSVD	14
+#define BM_UARTAPP_LINECTRL_RSVD	0x0000C000
+#define BF_UARTAPP_LINECTRL_RSVD(v)  \
+		(((v) << 14) & BM_UARTAPP_LINECTRL_RSVD)
+#define BP_UARTAPP_LINECTRL_BAUD_DIVFRAC	8
+#define BM_UARTAPP_LINECTRL_BAUD_DIVFRAC	0x00003F00
+#define BF_UARTAPP_LINECTRL_BAUD_DIVFRAC(v)  \
+		(((v) << 8) & BM_UARTAPP_LINECTRL_BAUD_DIVFRAC)
+#define BM_UARTAPP_LINECTRL_SPS	0x00000080
+#define BP_UARTAPP_LINECTRL_WLEN	5
+#define BM_UARTAPP_LINECTRL_WLEN	0x00000060
+#define BF_UARTAPP_LINECTRL_WLEN(v)  \
+		(((v) << 5) & BM_UARTAPP_LINECTRL_WLEN)
+#define BM_UARTAPP_LINECTRL_FEN	0x00000010
+#define BM_UARTAPP_LINECTRL_STP2	0x00000008
+#define BM_UARTAPP_LINECTRL_EPS	0x00000004
+#define BM_UARTAPP_LINECTRL_PEN	0x00000002
+#define BM_UARTAPP_LINECTRL_BRK	0x00000001
+
+#define HW_UARTAPP_LINECTRL2	(0x00000040)
+#define HW_UARTAPP_LINECTRL2_SET	(0x00000044)
+#define HW_UARTAPP_LINECTRL2_CLR	(0x00000048)
+#define HW_UARTAPP_LINECTRL2_TOG	(0x0000004c)
+
+#define BP_UARTAPP_LINECTRL2_BAUD_DIVINT	16
+#define BM_UARTAPP_LINECTRL2_BAUD_DIVINT	0xFFFF0000
+#define BF_UARTAPP_LINECTRL2_BAUD_DIVINT(v) \
+		(((v) << 16) & BM_UARTAPP_LINECTRL2_BAUD_DIVINT)
+#define BP_UARTAPP_LINECTRL2_RSVD	14
+#define BM_UARTAPP_LINECTRL2_RSVD	0x0000C000
+#define BF_UARTAPP_LINECTRL2_RSVD(v)  \
+		(((v) << 14) & BM_UARTAPP_LINECTRL2_RSVD)
+#define BP_UARTAPP_LINECTRL2_BAUD_DIVFRAC	8
+#define BM_UARTAPP_LINECTRL2_BAUD_DIVFRAC	0x00003F00
+#define BF_UARTAPP_LINECTRL2_BAUD_DIVFRAC(v)  \
+		(((v) << 8) & BM_UARTAPP_LINECTRL2_BAUD_DIVFRAC)
+#define BM_UARTAPP_LINECTRL2_SPS	0x00000080
+#define BP_UARTAPP_LINECTRL2_WLEN	5
+#define BM_UARTAPP_LINECTRL2_WLEN	0x00000060
+#define BF_UARTAPP_LINECTRL2_WLEN(v)  \
+		(((v) << 5) & BM_UARTAPP_LINECTRL2_WLEN)
+#define BM_UARTAPP_LINECTRL2_FEN	0x00000010
+#define BM_UARTAPP_LINECTRL2_STP2	0x00000008
+#define BM_UARTAPP_LINECTRL2_EPS	0x00000004
+#define BM_UARTAPP_LINECTRL2_PEN	0x00000002
+#define BM_UARTAPP_LINECTRL2_RSVD1	0x00000001
+
+#define HW_UARTAPP_INTR	(0x00000050)
+#define HW_UARTAPP_INTR_SET	(0x00000054)
+#define HW_UARTAPP_INTR_CLR	(0x00000058)
+#define HW_UARTAPP_INTR_TOG	(0x0000005c)
+
+#define BP_UARTAPP_INTR_RSVD1	28
+#define BM_UARTAPP_INTR_RSVD1	0xF0000000
+#define BF_UARTAPP_INTR_RSVD1(v) \
+		(((v) << 28) & BM_UARTAPP_INTR_RSVD1)
+#define BM_UARTAPP_INTR_ABDIEN	0x08000000
+#define BM_UARTAPP_INTR_OEIEN	0x04000000
+#define BM_UARTAPP_INTR_BEIEN	0x02000000
+#define BM_UARTAPP_INTR_PEIEN	0x01000000
+#define BM_UARTAPP_INTR_FEIEN	0x00800000
+#define BM_UARTAPP_INTR_RTIEN	0x00400000
+#define BM_UARTAPP_INTR_TXIEN	0x00200000
+#define BM_UARTAPP_INTR_RXIEN	0x00100000
+#define BM_UARTAPP_INTR_DSRMIEN	0x00080000
+#define BM_UARTAPP_INTR_DCDMIEN	0x00040000
+#define BM_UARTAPP_INTR_CTSMIEN	0x00020000
+#define BM_UARTAPP_INTR_RIMIEN	0x00010000
+#define BP_UARTAPP_INTR_RSVD2	12
+#define BM_UARTAPP_INTR_RSVD2	0x0000F000
+#define BF_UARTAPP_INTR_RSVD2(v)  \
+		(((v) << 12) & BM_UARTAPP_INTR_RSVD2)
+#define BM_UARTAPP_INTR_ABDIS	0x00000800
+#define BM_UARTAPP_INTR_OEIS	0x00000400
+#define BM_UARTAPP_INTR_BEIS	0x00000200
+#define BM_UARTAPP_INTR_PEIS	0x00000100
+#define BM_UARTAPP_INTR_FEIS	0x00000080
+#define BM_UARTAPP_INTR_RTIS	0x00000040
+#define BM_UARTAPP_INTR_TXIS	0x00000020
+#define BM_UARTAPP_INTR_RXIS	0x00000010
+#define BM_UARTAPP_INTR_DSRMIS	0x00000008
+#define BM_UARTAPP_INTR_DCDMIS	0x00000004
+#define BM_UARTAPP_INTR_CTSMIS	0x00000002
+#define BM_UARTAPP_INTR_RIMIS	0x00000001
+
+#define HW_UARTAPP_DATA	(0x00000060)
+
+#define BP_UARTAPP_DATA_DATA	0
+#define BM_UARTAPP_DATA_DATA	0xFFFFFFFF
+#define BF_UARTAPP_DATA_DATA(v)	(v)
+
+#define HW_UARTAPP_STAT	(0x00000070)
+
+#define BM_UARTAPP_STAT_PRESENT	0x80000000
+#define BV_UARTAPP_STAT_PRESENT__UNAVAILABLE 0x0
+#define BV_UARTAPP_STAT_PRESENT__AVAILABLE   0x1
+#define BM_UARTAPP_STAT_HISPEED	0x40000000
+#define BV_UARTAPP_STAT_HISPEED__UNAVAILABLE 0x0
+#define BV_UARTAPP_STAT_HISPEED__AVAILABLE   0x1
+#define BM_UARTAPP_STAT_BUSY	0x20000000
+#define BM_UARTAPP_STAT_CTS	0x10000000
+#define BM_UARTAPP_STAT_TXFE	0x08000000
+#define BM_UARTAPP_STAT_RXFF	0x04000000
+#define BM_UARTAPP_STAT_TXFF	0x02000000
+#define BM_UARTAPP_STAT_RXFE	0x01000000
+#define BP_UARTAPP_STAT_RXBYTE_INVALID	20
+#define BM_UARTAPP_STAT_RXBYTE_INVALID	0x00F00000
+#define BF_UARTAPP_STAT_RXBYTE_INVALID(v)  \
+		(((v) << 20) & BM_UARTAPP_STAT_RXBYTE_INVALID)
+#define BM_UARTAPP_STAT_OERR	0x00080000
+#define BM_UARTAPP_STAT_BERR	0x00040000
+#define BM_UARTAPP_STAT_PERR	0x00020000
+#define BM_UARTAPP_STAT_FERR	0x00010000
+#define BP_UARTAPP_STAT_RXCOUNT	0
+#define BM_UARTAPP_STAT_RXCOUNT	0x0000FFFF
+#define BF_UARTAPP_STAT_RXCOUNT(v)  \
+		(((v) << 0) & BM_UARTAPP_STAT_RXCOUNT)
+
+#define HW_UARTAPP_DEBUG	(0x00000080)
+
+#define BP_UARTAPP_DEBUG_RXIBAUD_DIV	16
+#define BM_UARTAPP_DEBUG_RXIBAUD_DIV	0xFFFF0000
+#define BF_UARTAPP_DEBUG_RXIBAUD_DIV(v) \
+		(((v) << 16) & BM_UARTAPP_DEBUG_RXIBAUD_DIV)
+#define BP_UARTAPP_DEBUG_RXFBAUD_DIV	10
+#define BM_UARTAPP_DEBUG_RXFBAUD_DIV	0x0000FC00
+#define BF_UARTAPP_DEBUG_RXFBAUD_DIV(v)  \
+		(((v) << 10) & BM_UARTAPP_DEBUG_RXFBAUD_DIV)
+#define BP_UARTAPP_DEBUG_RSVD1	6
+#define BM_UARTAPP_DEBUG_RSVD1	0x000003C0
+#define BF_UARTAPP_DEBUG_RSVD1(v)  \
+		(((v) << 6) & BM_UARTAPP_DEBUG_RSVD1)
+#define BM_UARTAPP_DEBUG_TXDMARUN	0x00000020
+#define BM_UARTAPP_DEBUG_RXDMARUN	0x00000010
+#define BM_UARTAPP_DEBUG_TXCMDEND	0x00000008
+#define BM_UARTAPP_DEBUG_RXCMDEND	0x00000004
+#define BM_UARTAPP_DEBUG_TXDMARQ	0x00000002
+#define BM_UARTAPP_DEBUG_RXDMARQ	0x00000001
+
+#define HW_UARTAPP_VERSION	(0x00000090)
+
+#define BP_UARTAPP_VERSION_MAJOR	24
+#define BM_UARTAPP_VERSION_MAJOR	0xFF000000
+#define BF_UARTAPP_VERSION_MAJOR(v) \
+		(((v) << 24) & BM_UARTAPP_VERSION_MAJOR)
+#define BP_UARTAPP_VERSION_MINOR	16
+#define BM_UARTAPP_VERSION_MINOR	0x00FF0000
+#define BF_UARTAPP_VERSION_MINOR(v)  \
+		(((v) << 16) & BM_UARTAPP_VERSION_MINOR)
+#define BP_UARTAPP_VERSION_STEP	0
+#define BM_UARTAPP_VERSION_STEP	0x0000FFFF
+#define BF_UARTAPP_VERSION_STEP(v)  \
+		(((v) << 0) & BM_UARTAPP_VERSION_STEP)
+
+#define HW_UARTAPP_AUTOBAUD	(0x000000a0)
+
+#define BP_UARTAPP_AUTOBAUD_REFCHAR1	24
+#define BM_UARTAPP_AUTOBAUD_REFCHAR1	0xFF000000
+#define BF_UARTAPP_AUTOBAUD_REFCHAR1(v) \
+		(((v) << 24) & BM_UARTAPP_AUTOBAUD_REFCHAR1)
+#define BP_UARTAPP_AUTOBAUD_REFCHAR0	16
+#define BM_UARTAPP_AUTOBAUD_REFCHAR0	0x00FF0000
+#define BF_UARTAPP_AUTOBAUD_REFCHAR0(v)  \
+		(((v) << 16) & BM_UARTAPP_AUTOBAUD_REFCHAR0)
+#define BP_UARTAPP_AUTOBAUD_RSVD1	5
+#define BM_UARTAPP_AUTOBAUD_RSVD1	0x0000FFE0
+#define BF_UARTAPP_AUTOBAUD_RSVD1(v)  \
+		(((v) << 5) & BM_UARTAPP_AUTOBAUD_RSVD1)
+#define BM_UARTAPP_AUTOBAUD_UPDATE_TX	0x00000010
+#define BM_UARTAPP_AUTOBAUD_TWO_REF_CHARS	0x00000008
+#define BM_UARTAPP_AUTOBAUD_START_WITH_RUNBIT	0x00000004
+#define BM_UARTAPP_AUTOBAUD_START_BAUD_DETECT	0x00000002
+#define BM_UARTAPP_AUTOBAUD_BAUD_DETECT_ENABLE	0x00000001
+#endif /* __ARCH_ARM___UARTAPP_H */
diff --git a/drivers/serial/mxs_auart.c b/drivers/serial/mxs_auart.c
new file mode 100644
index 0000000..b9a4e82
--- /dev/null
+++ b/drivers/serial/mxs_auart.c
@@ -0,0 +1,161 @@ 
+/*
+ * (c) 2013 Andreas Wass <andreas.wass@dalelven.com>
+ *
+ * Based on an mx28 AUART implementation from the 2009 U-Boot:
+ *
+ * (c) 2011 Wolfgang Ocker <weo@reccoware.de>
+ *
+ * Further based on the standard DUART serial driver:
+ *
+ * (c) 2007 Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * (C) Copyright 2009-2010 Freescale Semiconductor, Inc.
+ *
+ * Further based on the Linux mxs-auart.c driver:
+ *
+ * Freescale STMP37XX/STMP378X Application UART driver
+ *
+ * Author: dmitry pervushin <dimka@embeddedalley.com>
+ *
+ * Copyright 2008-2010 Freescale Semiconductor, Inc.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+#include <common.h>
+#include <serial.h>
+#include <linux/compiler.h>
+#include "mxs-regs-uartapp.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define REGS_UARTAPP3_BASE	(0x80070000)
+#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))
+
+/* HACK should be removed when issue is fixed! */
+void dbg_puts(const char *s);
+
+static void mxs_auart_reset(void)
+{
+	int i;
+
+	REG_WR(REGS_UARTAPP_BASE, HW_UARTAPP_CTRL0_CLR,
+			BM_UARTAPP_CTRL0_SFTRST);
+
+	for (i = 0; i < 10000; i++) {
+		unsigned int reg = REG_RD(REGS_UARTAPP_BASE, HW_UARTAPP_CTRL0);
+		if (!(reg & BM_UARTAPP_CTRL0_SFTRST))
+			break;
+		udelay(3);
+	}
+
+	REG_WR(REGS_UARTAPP_BASE, HW_UARTAPP_CTRL0_CLR,
+			BM_UARTAPP_CTRL0_CLKGATE);
+}
+
+/*
+ * 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;
+	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();
+	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
+	 */
+	dbg_puts("\n");
+	return 0;
+}
+
+void mxs_auart_putc(const char c)
+{
+	while (REG_RD(REGS_UARTAPP_BASE, HW_UARTAPP_STAT) &
+			BM_UARTAPP_STAT_TXFF)
+		;
+
+	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++);
+}
+
+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;
+}
diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c
index 9f04643..5531604 100644
--- a/drivers/serial/serial.c
+++ b/drivers/serial/serial.c
@@ -177,6 +177,7 @@  serial_initfunc(pl01x_serial_initialize);
 serial_initfunc(s3c44b0_serial_initialize);
 serial_initfunc(sa1100_serial_initialize);
 serial_initfunc(sh_serial_initialize);
+serial_initfunc(mxs_auart_initialize);
 
 /**
  * serial_register() - Register serial driver with serial driver core
@@ -270,6 +271,7 @@  void serial_initialize(void)
 	s3c44b0_serial_initialize();
 	sa1100_serial_initialize();
 	sh_serial_initialize();
+	mxs_auart_initialize();
 
 	serial_assign(default_serial_console()->name);
 }
@@ -552,10 +554,11 @@  int uart_post_test(int flags)
 
 			/*
 			 * Stick to printable chars to avoid issues:
-			 *  - terminal corruption
-			 *  - serial program reacting to sequences and sending
-			 *    back random extra data
-			 *  - most serial drivers add in extra chars (like \r\n)
+			 *	- terminal corruption
+			 *	- serial program reacting to sequences
+			 *	  and sending back random extra data
+			 *	- most serial drivers add in extra chars
+			 *	  (like \r\n)
 			 */
 			for (c = 0x20; c < 0x7f; ++c) {
 				/* Send it out */
diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c
index dfdba9f..6c478a6 100644
--- a/drivers/serial/serial_pl01x.c
+++ b/drivers/serial/serial_pl01x.c
@@ -164,7 +164,7 @@  static int pl01x_serial_init(void)
 #endif
 	/* Finally, enable the UART */
 	writel(UART_PL011_CR_UARTEN | UART_PL011_CR_TXE | UART_PL011_CR_RXE |
-	       UART_PL011_CR_RTS, &regs->pl011_cr);
+		   UART_PL011_CR_RTS, &regs->pl011_cr);
 
 	return 0;
 }
@@ -261,8 +261,21 @@  void pl01x_serial_initialize(void)
 {
 	serial_register(&pl01x_serial_drv);
 }
+/*
+ * HACK! This is used once by the MXS AUART driver. Without this
+ * the AUART driver will not work.
+ */
+void dbg_puts(const char *s)
+{
+	while (*s)
+		pl01x_serial_putc(*s++);
+}
 
-__weak struct serial_device *default_serial_console(void)
+/*
+ * This driver has to be used once for the MXS AUART driver to work
+ * However it should not be the default_serial_console
+ */
+/*__weak struct serial_device *default_serial_console(void)
 {
 	return &pl01x_serial_drv;
-}
+}*/