nios2: Added support to YANU UART

Signed-off-by: Scott McNutt <smcnutt@psyent.com>
diff --git a/cpu/nios2/serial.c b/cpu/nios2/serial.c
index 8bbb803..6c835af 100644
--- a/cpu/nios2/serial.c
+++ b/cpu/nios2/serial.c
@@ -2,6 +2,9 @@
  * (C) Copyright 2004, Psyent Corporation <www.psyent.com>
  * Scott McNutt <smcnutt@psyent.com>
  *
+ * YANU Support:
+ * Copyright 2010, Renato Andreola <renato.andreola@imagos.it>
+ *
  * See file CREDITS for list of people who contributed to this
  * project.
  *
@@ -26,6 +29,7 @@
 #include <watchdog.h>
 #include <asm/io.h>
 #include <nios2-io.h>
+#include <nios2-yanu.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -74,10 +78,172 @@
 	return (c);
 }
 
+#elif defined(CONFIG_CONSOLE_YANU)
+/*-----------------------------------------------------------------*/
+/* YANU Imagos serial port */
+/*-----------------------------------------------------------------*/
+
+static yanu_uart_t *uart = (yanu_uart_t *)CONFIG_SYS_NIOS_CONSOLE;
+
+#if defined(CONFIG_SYS_NIOS_FIXEDBAUD)
+
+/* Everything's already setup for fixed-baud PTF assignment*/
+
+void serial_setbrg (void)
+{
+	int n, k;
+	const unsigned max_uns = 0xFFFFFFFF;
+	unsigned best_n, best_m, baud;
+
+	/* compute best N and M couple */
+	best_n = YANU_MAX_PRESCALER_N;
+	for (n = YANU_MAX_PRESCALER_N; n >= 0; n--) {
+		if ((unsigned)CONFIG_SYS_CLK_FREQ / (1 << (n + 4)) >=
+		    (unsigned)CONFIG_BAUDRATE) {
+			best_n = n;
+			break;
+		}
+	}
+	for (k = 0;; k++) {
+		if ((unsigned)CONFIG_BAUDRATE <= (max_uns >> (15+n-k)))
+			break;
+	}
+	best_m =
+	    ((unsigned)CONFIG_BAUDRATE * (1 << (15 + n - k))) /
+	    ((unsigned)CONFIG_SYS_CLK_FREQ >> k);
+
+	baud = best_m + best_n * YANU_BAUDE;
+	writel(&uart->baud, baud);
+
+	return;
+}
+
+#else
+
+void serial_setbrg (void)
+{	
+	int n, k;
+	const unsigned max_uns = 0xFFFFFFFF;
+	unsigned best_n, best_m, baud;
+
+	/* compute best N and M couple */
+	best_n = YANU_MAX_PRESCALER_N;
+	for (n = YANU_MAX_PRESCALER_N; n >= 0; n--) {
+		if ((unsigned)CONFIG_SYS_CLK_FREQ / (1 << (n + 4)) >=
+		    gd->baudrate) {
+			best_n = n;
+			break;
+		}
+	}
+	for (k = 0;; k++) {
+		if (gd->baudrate <= (max_uns >> (15+n-k)))
+			break;
+	}
+	best_m =
+	    (gd->baudrate * (1 << (15 + n - k))) /
+	    ((unsigned)CONFIG_SYS_CLK_FREQ >> k);
+
+	baud = best_m + best_n * YANU_BAUDE;
+	writel(&uart->baud, baud);
+
+	return;
+}
+
+
+#endif /* CONFIG_SYS_NIOS_FIXEDBAUD */
+
+int serial_init (void)
+{
+	unsigned action,control;
+
+	/* status register cleanup */
+	action =  YANU_ACTION_RRRDY     |
+		YANU_ACTION_RTRDY       |
+		YANU_ACTION_ROE         |
+		YANU_ACTION_RBRK        |
+		YANU_ACTION_RFE         |
+		YANU_ACTION_RPE         |
+	    YANU_ACTION_RFE | YANU_ACTION_RFIFO_CLEAR | YANU_ACTION_TFIFO_CLEAR;
+
+	writel(&uart->action, action);
+	
+	/*  control register cleanup */
+	/* no interrupts enabled */
+	/* one stop bit */
+	/* hardware flow control disabled */
+	/* 8 bits */
+	control = (0x7 << YANU_CONTROL_BITS_POS);
+	/* enven parity just to be clean */
+	control |= YANU_CONTROL_PAREVEN;
+	/* we set threshold for fifo */
+	control |= YANU_CONTROL_RDYDLY * YANU_RXFIFO_DLY;
+	control |= YANU_CONTROL_TXTHR *  YANU_TXFIFO_THR;
+
+	writel(&uart->control, control);
+
+	/* to set baud rate */
+	serial_setbrg();
+
+	return (0);
+}
+
+
+/*-----------------------------------------------------------------------
+ * YANU CONSOLE
+ *---------------------------------------------------------------------*/
+void serial_putc (char c)
+{
+	int tx_chars;
+	unsigned status;
+
+	if (c == '\n')
+		serial_putc ('\r');
+	
+	while (1) {
+		status = readl(&uart->status);
+		tx_chars = (status>>YANU_TFIFO_CHARS_POS)
+			& ((1<<YANU_TFIFO_CHARS_N)-1);
+		if (tx_chars < YANU_TXFIFO_SIZE-1)
+			break;
+		WATCHDOG_RESET ();
+	}
+
+	writel(&uart->data, (unsigned char)c);
+}
+
+void serial_puts (const char *s)
+{
+	while (*s != 0) {
+		serial_putc (*s++);
+	}
+}
+
+
+int serial_tstc(void)
+{
+	unsigned status ;
+
+	status = readl(&uart->status);
+	return (((status >> YANU_RFIFO_CHARS_POS) &
+		 ((1 << YANU_RFIFO_CHARS_N) - 1)) > 0);
+}	
+
+int serial_getc (void)
+{
+	while (serial_tstc() == 0)
+		WATCHDOG_RESET ();
+	
+	/* first we pull the char */
+	writel(&uart->action, YANU_ACTION_RFIFO_PULL);
+
+	return(readl(&uart->data) & YANU_DATA_CHAR_MASK);
+}
+
+#else /*CONFIG_CONSOLE_YANU*/
+
 /*------------------------------------------------------------------
  * UART the serial port
  *-----------------------------------------------------------------*/
-#else
 
 static nios_uart_t *uart = (nios_uart_t *) CONFIG_SYS_NIOS_CONSOLE;