Commit 22a240c32c1340183fce12867ae5f8736b92a638

Authored by Alexey Brodkin
Committed by Tom Rini
1 parent 1a78d28d02

serial/serial_arc - add driver for ARC UART

Driver for non-standard on-chip UART, instantiated in the ARC (Synopsys)
FPGA Boards such as ARCAngel4/ML50x

Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>

Cc: Mischa Jonker <mjonker@synopsys.com>
Cc: Francois Bedard <fbedard@synopsys.com>
Cc: Tom Rini <trini@ti.com>
Cc: Wolfgang Denk <wd@denx.de>
Cc: Stefano Babic <sbabic@denx.de>

Showing 3 changed files with 108 additions and 0 deletions Side-by-side Diff

drivers/serial/Makefile
... ... @@ -34,6 +34,7 @@
34 34 obj-$(CONFIG_BFIN_SERIAL) += serial_bfin.o
35 35 obj-$(CONFIG_FSL_LPUART) += serial_lpuart.o
36 36 obj-$(CONFIG_MXS_AUART) += mxs_auart.o
  37 +obj-$(CONFIG_ARC_SERIAL) += serial_arc.o
37 38  
38 39 ifndef CONFIG_SPL_BUILD
39 40 obj-$(CONFIG_USB_TTY) += usbtty.o
drivers/serial/serial.c
... ... @@ -160,6 +160,7 @@
160 160 serial_initfunc(sh_serial_initialize);
161 161 serial_initfunc(arm_dcc_initialize);
162 162 serial_initfunc(mxs_auart_initialize);
  163 +serial_initfunc(arc_serial_initialize);
163 164  
164 165 /**
165 166 * serial_register() - Register serial driver with serial driver core
... ... @@ -253,6 +254,7 @@
253 254 sh_serial_initialize();
254 255 arm_dcc_initialize();
255 256 mxs_auart_initialize();
  257 + arc_serial_initialize();
256 258  
257 259 serial_assign(default_serial_console()->name);
258 260 }
drivers/serial/serial_arc.c
  1 +/*
  2 + * Copyright (C) 2013 Synopsys, Inc. (www.synopsys.com)
  3 + *
  4 + * This program is free software; you can redistribute it and/or modify
  5 + * it under the terms of the GNU General Public License version 2 as
  6 + * published by the Free Software Foundation.
  7 + *
  8 + */
  9 +
  10 +#include <common.h>
  11 +#include <serial.h>
  12 +
  13 +DECLARE_GLOBAL_DATA_PTR;
  14 +
  15 +struct arc_serial_regs {
  16 + unsigned int id0;
  17 + unsigned int id1;
  18 + unsigned int id2;
  19 + unsigned int id3;
  20 + unsigned int data;
  21 + unsigned int status;
  22 + unsigned int baudl;
  23 + unsigned int baudh;
  24 +};
  25 +
  26 +/* Bit definitions of STATUS register */
  27 +#define UART_RXEMPTY (1 << 5)
  28 +#define UART_OVERFLOW_ERR (1 << 1)
  29 +#define UART_TXEMPTY (1 << 7)
  30 +
  31 +struct arc_serial_regs *regs;
  32 +
  33 +static void arc_serial_setbrg(void)
  34 +{
  35 + int arc_console_baud;
  36 +
  37 + if (!gd->baudrate)
  38 + gd->baudrate = CONFIG_BAUDRATE;
  39 +
  40 + arc_console_baud = gd->cpu_clk / (gd->baudrate * 4) - 1;
  41 + writel(arc_console_baud & 0xff, &regs->baudl);
  42 + writel((arc_console_baud & 0xff00) >> 8, &regs->baudh);
  43 +}
  44 +
  45 +static int arc_serial_init(void)
  46 +{
  47 + regs = (struct arc_serial_regs *)CONFIG_ARC_UART_BASE;
  48 + serial_setbrg();
  49 + return 0;
  50 +}
  51 +
  52 +static void arc_serial_putc(const char c)
  53 +{
  54 + if (c == '\n')
  55 + arc_serial_putc('\r');
  56 +
  57 + while (!(readl(&regs->status) & UART_TXEMPTY))
  58 + ;
  59 +
  60 + writel(c, &regs->data);
  61 +}
  62 +
  63 +static int arc_serial_tstc(void)
  64 +{
  65 + return !(readl(&regs->status) & UART_RXEMPTY);
  66 +}
  67 +
  68 +static int arc_serial_getc(void)
  69 +{
  70 + while (!arc_serial_tstc())
  71 + ;
  72 +
  73 + /* Check for overflow errors */
  74 + if (readl(&regs->status) & UART_OVERFLOW_ERR)
  75 + return 0;
  76 +
  77 + return readl(&regs->data) & 0xFF;
  78 +}
  79 +
  80 +static void arc_serial_puts(const char *s)
  81 +{
  82 + while (*s)
  83 + arc_serial_putc(*s++);
  84 +}
  85 +
  86 +static struct serial_device arc_serial_drv = {
  87 + .name = "arc_serial",
  88 + .start = arc_serial_init,
  89 + .stop = NULL,
  90 + .setbrg = arc_serial_setbrg,
  91 + .putc = arc_serial_putc,
  92 + .puts = arc_serial_puts,
  93 + .getc = arc_serial_getc,
  94 + .tstc = arc_serial_tstc,
  95 +};
  96 +
  97 +void arc_serial_initialize(void)
  98 +{
  99 + serial_register(&arc_serial_drv);
  100 +}
  101 +
  102 +__weak struct serial_device *default_serial_console(void)
  103 +{
  104 + return &arc_serial_drv;
  105 +}