summaryrefslogtreecommitdiff
path: root/core/drivers/scif.c
diff options
context:
space:
mode:
Diffstat (limited to 'core/drivers/scif.c')
-rw-r--r--core/drivers/scif.c44
1 files changed, 35 insertions, 9 deletions
diff --git a/core/drivers/scif.c b/core/drivers/scif.c
index 02fd49d..ff0cec8 100644
--- a/core/drivers/scif.c
+++ b/core/drivers/scif.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2016, GlobalLogic
+ * Copyright (c) 2017, Linaro Limited
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,16 +25,18 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <compiler.h>
+#include <drivers/scif.h>
#include <io.h>
+#include <keep.h>
#include <util.h>
-#include <drivers/scif.h>
+#define SCIF_SCSCR (0x08)
#define SCIF_SCFSR (0x10)
#define SCIF_SCFTDR (0x0C)
#define SCIF_SCFCR (0x18)
#define SCIF_SCFDR (0x1C)
+#define SCSCR_TE BIT(5)
#define SCFSR_TDFE BIT(5)
#define SCFSR_TEND BIT(6)
@@ -41,20 +44,26 @@
#define SCIF_TX_FIFO_SIZE 16
-void scif_uart_flush(vaddr_t base)
+static vaddr_t chip_to_base(struct serial_chip *chip)
{
- while (!(read16(base + SCIF_SCFSR) & SCFSR_TEND))
- ;
+ struct scif_uart_data *pd =
+ container_of(chip, struct scif_uart_data, chip);
+
+ return io_pa_or_va(&pd->base);
}
-void scif_uart_init(vaddr_t base)
+static void scif_uart_flush(struct serial_chip *chip)
{
- /* Bootloader should initialize device for us */
- scif_uart_flush(base);
+ vaddr_t base = chip_to_base(chip);
+
+ while (!(read16(base + SCIF_SCFSR) & SCFSR_TEND))
+ ;
}
-void scif_uart_putc(int ch, vaddr_t base)
+static void scif_uart_putc(struct serial_chip *chip, int ch)
{
+ vaddr_t base = chip_to_base(chip);
+
/* Wait until there is space in the FIFO */
while ((read16(base + SCIF_SCFDR) >> SCFDR_T_SHIFT) >=
SCIF_TX_FIFO_SIZE)
@@ -63,3 +72,20 @@ void scif_uart_putc(int ch, vaddr_t base)
write16(read16(base + SCIF_SCFSR) & ~(SCFSR_TEND | SCFSR_TDFE),
base + SCIF_SCFSR);
}
+
+static const struct serial_ops scif_uart_ops = {
+ .flush = scif_uart_flush,
+ .putc = scif_uart_putc,
+};
+KEEP_PAGER(scif_uart_ops);
+
+void scif_uart_init(struct scif_uart_data *pd, paddr_t base)
+{
+ pd->base.pa = base;
+ pd->chip.ops = &scif_uart_ops;
+
+ /* Set Transmit Enable in Control register */
+ write16(read16(base + SCIF_SCSCR) | SCSCR_TE, base + SCIF_SCSCR);
+
+ scif_uart_flush(&pd->chip);
+}