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] [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 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.