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