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, ®s->baudl); 42 writel((arc_console_baud & 0xff00) >> 8, ®s->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(®s->status) & UART_TXEMPTY)) 58 ; 59 60 writel(c, ®s->data); 61 } 62 63 static int arc_serial_tstc(void) 64 { 65 return !(readl(®s->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(®s->status) & UART_OVERFLOW_ERR) 75 return 0; 76 77 return readl(®s->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 } 106