public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Marek Vasut <marex@denx.de>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v2 3/4] mips: ath79: add serial driver for ar933x SOC
Date: Tue, 22 Dec 2015 15:54:32 +0100	[thread overview]
Message-ID: <201512221554.32122.marex@denx.de> (raw)
In-Reply-To: <BLU436-SMTP260BDE735874DAF843DDEBDFFE50@phx.gbl>

On Tuesday, December 22, 2015 at 08:44:44 AM, Wills Wang wrote:
> Signed-off-by: Wills Wang <wills.wang@live.com>
> ---
> 
>  drivers/serial/Makefile        |   1 +
>  drivers/serial/serial_ar933x.c | 337
> +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 338
> insertions(+)
>  create mode 100644 drivers/serial/serial_ar933x.c
> 
> diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
> index dd87147..9a7ad89 100644
> --- a/drivers/serial/Makefile
> +++ b/drivers/serial/Makefile
> @@ -17,6 +17,7 @@ endif
> 
>  obj-$(CONFIG_ALTERA_UART) += altera_uart.o
>  obj-$(CONFIG_ALTERA_JTAG_UART) += altera_jtag_uart.o
> +obj-$(CONFIG_AR933X_SERIAL) += serial_ar933x.o
>  obj-$(CONFIG_ARM_DCC) += arm_dcc.o
>  obj-$(CONFIG_ATMEL_USART) += atmel_usart.o
>  obj-$(CONFIG_EFI_APP) += serial_efi.o
> diff --git a/drivers/serial/serial_ar933x.c
> b/drivers/serial/serial_ar933x.c new file mode 100644
> index 0000000..6ea500a
> --- /dev/null
> +++ b/drivers/serial/serial_ar933x.c
> @@ -0,0 +1,337 @@
> +/*
> + * (C) Copyright 2015
> + * Wills Wang, <wills.wang@live.com>
> + *
> + * SPDX-License-Identifier:	GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <asm/io.h>
> +#include <asm/addrspace.h>
> +#include <asm/types.h>
> +#include <config.h>
> +#include <serial.h>
> +#include <asm/arch/ar71xx_regs.h>
> +#include <asm/arch/ar933x_uart.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +#define REG_READ(b, o)      readl(KSEG1ADDR(b + o))
> +#define REG_WRITE(b, o, v)  writel(v, KSEG1ADDR((b + o)))
> +#define UART_READ(a)        REG_READ(AR933X_UART_BASE, a)
> +#define UART_WRITE(a, v)    REG_WRITE(AR933X_UART_BASE, a, v)

Please remove these macros (see below)

> +static void ar933x_serial_get_scale_step(u32 *uart_scale, u32 *uart_step)
> +{
> +	u32 val;
> +
> +	val = REG_READ(AR71XX_RESET_BASE, AR933X_RESET_REG_BOOTSTRAP);
> +	if (val & AR933X_BOOTSTRAP_REF_CLK_40) {
> +		switch (gd->baudrate) {
> +		case 600:
> +			*uart_scale = 255;
> +			*uart_step  = 503;
> +			break;
> +		case 1200:
> +			*uart_scale = 249;
> +			*uart_step  = 983;

I suppose this cannot be calculated, right ? What about making this into a
table, something like:

struct {
	u16 baudrate;
	u16 scale;
	u16 step;
} uart_something[] {
	{ 600, 255, 503 },
	{ 1200, .... },
	....
};

and then look things up:

for (i = 0; i < ARRAY_SIZE(uart_something); i++)
	if (gd->baudrate == uart_something[i].baudrate)
		break;

if (i == ARRAY_SIZE(uart_something))
	do default handling here
[...]

> +		default:
> +			*uart_scale = (40000000 / (16 * gd->baudrate)) - 1;
> +			*uart_step = 8192;
> +		}
> +	} else {
> +		switch (gd->baudrate) {
> +		case 600:
> +			*uart_scale = 255;
> +			*uart_step  = 805;
> +			break;

You can wrap this part into the table as well then, quite easily.

[...]

> +static void ar933x_serial_setbrg(void)
> +{
> +	/* TODO: better clock calculation, baudrate, etc. */
> +	u32 val, scale, step;
> +
> +	ar933x_serial_get_scale_step(&scale, &step);
> +	val  = ((scale & AR933X_UART_CLOCK_SCALE_M)
> +			<< AR933X_UART_CLOCK_SCALE_S);
> +	val |= ((step & AR933X_UART_CLOCK_STEP_M)
> +			<< AR933X_UART_CLOCK_STEP_S);

Drop the extraneous parenthesis around the statement please.

> +	UART_WRITE(AR933X_UART_CLOCK_REG, val);

This should be just writel().

> +}
> +
> +int ar933x_serial_init(void)
> +{
> +	u32 val;
> +
> +	/*
> +	 * Set GPIO10 (UART_SO) as output and enable UART,
> +	 * BIT(15) in GPIO_FUNCTION_1 register must be written with 1
> +	 */
> +	val = REG_READ(AR71XX_GPIO_BASE, AR71XX_GPIO_REG_OE);
> +	val |= BIT(10);
> +	REG_WRITE(AR71XX_GPIO_BASE, AR71XX_GPIO_REG_OE, val);

Use setbits_le32()

> +	val = REG_READ(AR71XX_GPIO_BASE, AR71XX_GPIO_REG_FUNC);
> +	val |= (AR933X_GPIO_FUNC_UART_EN | BIT(15));
> +	REG_WRITE(AR71XX_GPIO_BASE, AR71XX_GPIO_REG_FUNC, val);

Same here.

> +	/*
> +	 * UART controller configuration:
> +	 * - no DMA
> +	 * - no interrupt
> +	 * - DCE mode
> +	 * - no flow control
> +	 * - set RX ready oride
> +	 * - set TX ready oride
> +	 */
> +	val = AR933X_UART_CS_TX_READY_ORIDE | AR933X_UART_CS_RX_READY_ORIDE
> +		| (AR933X_UART_CS_IF_MODE_DCE << AR933X_UART_CS_IF_MODE_S);
> +	UART_WRITE(AR933X_UART_CS_REG, val);
> +	ar933x_serial_setbrg();
> +
> +	return 0;
> +}
> +
> +void ar933x_serial_putc(const char c)
> +{
> +	u32 data;
> +
> +	if (c == '\n')
> +		ar933x_serial_putc('\r');
> +
> +	do {
> +		data = UART_READ(AR933X_UART_DATA_REG);
> +	} while (!(data & AR933X_UART_DATA_TX_CSR));
> +
> +	data  = (u32)c | AR933X_UART_DATA_TX_CSR;

$c is already u32, no need for the cast.

> +	UART_WRITE(AR933X_UART_DATA_REG, data);
> +}
> +
> +static int ar933x_serial_getc(void)
> +{
> +	u32 data;
> +
> +	do {
> +		data = UART_READ(AR933X_UART_DATA_REG);
> +	} while (!(data & AR933X_UART_DATA_RX_CSR));
> +
> +	data = UART_READ(AR933X_UART_DATA_REG);
> +	UART_WRITE(AR933X_UART_DATA_REG, AR933X_UART_DATA_RX_CSR);
> +	return (int)(data & AR933X_UART_DATA_TX_RX_MASK);

Please drop all the casts, they are useless.

> +}
> +
> +static int ar933x_serial_tstc(void)
> +{
> +	u32 data;
> +
> +	data = UART_READ(AR933X_UART_DATA_REG);
> +	return (data & AR933X_UART_DATA_RX_CSR) ? 1 : 0;
> +}
> +
> +static struct serial_device ar933x_serial_drv = {
> +	.name	= "ar933x_serial",
> +	.start	= ar933x_serial_init,
> +	.stop	= NULL,
> +	.setbrg	= ar933x_serial_setbrg,
> +	.putc	= ar933x_serial_putc,
> +	.puts	= default_serial_puts,
> +	.getc	= ar933x_serial_getc,
> +	.tstc	= ar933x_serial_tstc,
> +};
> +
> +void ar933x_serial_initialize(void)
> +{
> +	serial_register(&ar933x_serial_drv);
> +}
> +
> +__weak struct serial_device *default_serial_console(void)
> +{
> +	return &ar933x_serial_drv;
> +}

  parent reply	other threads:[~2015-12-22 14:54 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <1450770285-14566-1-git-send-email-wills.wang@live.com>
2015-12-22  7:44 ` [U-Boot] [PATCH v2 1/4] mips: add base support for atheros ath79 based SOCs Wills Wang
2015-12-22 14:34   ` Daniel Schwierzeck
2015-12-22  7:44 ` [U-Boot] [PATCH v2 2/4] mips: ath79: add spi driver Wills Wang
2015-12-22  8:03   ` Jagan Teki
2015-12-22  7:44 ` [U-Boot] [PATCH v2 3/4] mips: ath79: add serial driver for ar933x SOC Wills Wang
2015-12-22 13:03   ` Thomas Chou
2015-12-22 14:54   ` Marek Vasut [this message]
2015-12-22  7:44 ` [U-Boot] [PATCH v2 4/4] mips: ath79: add AP121 reference board Wills Wang

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=201512221554.32122.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox