All of lore.kernel.org
 help / color / mirror / Atom feed
From: Marek Vasut <marex@denx.de>
To: u-boot@lists.denx.de
Subject: [U-Boot] Implement AUART for i.MX28
Date: Wed, 10 Jul 2013 00:46:31 +0200	[thread overview]
Message-ID: <201307100046.31420.marex@denx.de> (raw)
In-Reply-To: <74CACEF26F2B2D418C5EDD0CCC0D2BECF60A51@DALELVENSRV1.dalelven.local>

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;
> +}

[...]

  reply	other threads:[~2013-07-09 22:46 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-07-09  6:00 [U-Boot] Implement AUART for i.MX28 Andreas Wass
2013-07-09 22:46 ` Marek Vasut [this message]
2013-08-03 18:35   ` Marek Vasut
2013-08-04  9:10     ` Andreas Wass
2013-08-04 11:10       ` Marek Vasut

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=201307100046.31420.marex@denx.de \
    --to=marex@denx.de \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.