summaryrefslogtreecommitdiff
path: root/core/drivers
diff options
context:
space:
mode:
authorr.tyminski <r.tyminski@partner.samsung.com>2017-06-05 12:44:25 +0200
committerr.tyminski <r.tyminski@partner.samsung.com>2017-06-05 12:44:25 +0200
commit146aec115cd05a164a88e6d7b07435c57a33817f (patch)
treed8099075c92576b1928069af274f9b833aca996e /core/drivers
parentf9a43781767007462965b21f3f518c4cfc0744c7 (diff)
downloadtef-optee_os-146aec115cd05a164a88e6d7b07435c57a33817f.tar.gz
tef-optee_os-146aec115cd05a164a88e6d7b07435c57a33817f.tar.bz2
tef-optee_os-146aec115cd05a164a88e6d7b07435c57a33817f.zip
Update from upstream to 2.4.0 versionupstream/2.4.0upstream
Change-Id: I2b3a30f20684d6629fe379d9cd7895aff759c301
Diffstat (limited to 'core/drivers')
-rw-r--r--core/drivers/cdns_uart.c79
-rw-r--r--core/drivers/hi16xx_uart.c82
-rw-r--r--core/drivers/imx_uart.c51
-rw-r--r--core/drivers/ns16550.c38
-rw-r--r--core/drivers/pl011.c83
-rw-r--r--core/drivers/pl050.c4
-rw-r--r--core/drivers/scif.c44
-rw-r--r--core/drivers/serial8250_uart.c73
-rw-r--r--core/drivers/sprd_uart.c59
-rw-r--r--core/drivers/stih_asc.c75
-rw-r--r--core/drivers/sub.mk1
-rw-r--r--core/drivers/sunxi_uart.c60
12 files changed, 486 insertions, 163 deletions
diff --git a/core/drivers/cdns_uart.c b/core/drivers/cdns_uart.c
index 3b4e4b9..8672093 100644
--- a/core/drivers/cdns_uart.c
+++ b/core/drivers/cdns_uart.c
@@ -24,9 +24,11 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <compiler.h>
+#include <assert.h>
#include <drivers/cdns_uart.h>
#include <io.h>
+#include <keep.h>
+#include <mm/core_mmu.h>
#include <util.h>
#define CDNS_UART_CONTROL 0
@@ -52,31 +54,44 @@
#define CDNS_UART_IRQ_RXTRIG BIT(0)
#define CDNS_UART_IRQ_RXTOUT BIT(8)
-void cdns_uart_flush(vaddr_t base)
+static vaddr_t chip_to_base(struct serial_chip *chip)
{
+ struct cdns_uart_data *pd =
+ container_of(chip, struct cdns_uart_data, chip);
+
+ return io_pa_or_va(&pd->base);
+}
+
+static void cdns_uart_flush(struct serial_chip *chip)
+{
+ vaddr_t base = chip_to_base(chip);
+
while (!(read32(base + CDNS_UART_CHANNEL_STATUS) &
- CDNS_UART_CHANNEL_STATUS_TEMPTY))
+ CDNS_UART_CHANNEL_STATUS_TEMPTY))
;
}
-/*
- * we rely on the bootloader having set up the HW correctly, we just enable
- * transmitter/receiver here, just in case.
- */
-void cdns_uart_init(vaddr_t base, uint32_t uart_clk, uint32_t baud_rate)
+static bool cdns_uart_have_rx_data(struct serial_chip *chip)
{
- if (!base || !uart_clk || !baud_rate)
- return;
+ vaddr_t base = chip_to_base(chip);
- /* Enable UART and RX/TX */
- write32(CDNS_UART_CONTROL_RXEN | CDNS_UART_CONTROL_TXEN,
- base + CDNS_UART_CONTROL);
+ return !(read32(base + CDNS_UART_CHANNEL_STATUS) &
+ CDNS_UART_CHANNEL_STATUS_REMPTY);
+}
+
+static int cdns_uart_getchar(struct serial_chip *chip)
+{
+ vaddr_t base = chip_to_base(chip);
- cdns_uart_flush(base);
+ while (!cdns_uart_have_rx_data(chip))
+ ;
+ return read32(base + CDNS_UART_FIFO) & 0xff;
}
-void cdns_uart_putc(int ch, vaddr_t base)
+static void cdns_uart_putc(struct serial_chip *chip, int ch)
{
+ vaddr_t base = chip_to_base(chip);
+
/* Wait until there is space in the FIFO */
while (read32(base + CDNS_UART_CHANNEL_STATUS) &
CDNS_UART_CHANNEL_STATUS_TFUL)
@@ -86,15 +101,31 @@ void cdns_uart_putc(int ch, vaddr_t base)
write32(ch, base + CDNS_UART_FIFO);
}
-bool cdns_uart_have_rx_data(vaddr_t base)
-{
- return !(read32(base + CDNS_UART_CHANNEL_STATUS) &
- CDNS_UART_CHANNEL_STATUS_REMPTY);
-}
-int cdns_uart_getchar(vaddr_t base)
+static const struct serial_ops cdns_uart_ops = {
+ .flush = cdns_uart_flush,
+ .getchar = cdns_uart_getchar,
+ .have_rx_data = cdns_uart_have_rx_data,
+ .putc = cdns_uart_putc,
+};
+KEEP_PAGER(cdns_uart_ops);
+
+/*
+ * we rely on the bootloader having set up the HW correctly, we just enable
+ * transmitter/receiver here, just in case.
+ */
+void cdns_uart_init(struct cdns_uart_data *pd, paddr_t base, uint32_t uart_clk,
+ uint32_t baud_rate)
{
- while (!cdns_uart_have_rx_data(base))
- ;
- return read32(base + CDNS_UART_FIFO) & 0xff;
+ pd->base.pa = base;
+ pd->chip.ops = &cdns_uart_ops;
+
+ if (!uart_clk || !baud_rate)
+ return;
+
+ /* Enable UART and RX/TX */
+ write32(CDNS_UART_CONTROL_RXEN | CDNS_UART_CONTROL_TXEN,
+ base + CDNS_UART_CONTROL);
+
+ cdns_uart_flush(&pd->chip);
}
diff --git a/core/drivers/hi16xx_uart.c b/core/drivers/hi16xx_uart.c
index 76e769d..3f8a3ca 100644
--- a/core/drivers/hi16xx_uart.c
+++ b/core/drivers/hi16xx_uart.c
@@ -24,8 +24,12 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include <assert.h>
#include <drivers/hi16xx_uart.h>
#include <io.h>
+#include <keep.h>
+#include <mm/core_mmu.h>
+#include <util.h>
/* Register offsets */
@@ -76,16 +80,66 @@
#define UART_USR_RFNE_BIT 3 /* Receive FIFO not empty bit */
#define UART_USR_RFF_BIT 4 /* Receive FIFO full bit */
-void hi16xx_uart_flush(vaddr_t base)
+static vaddr_t chip_to_base(struct serial_chip *chip)
{
+ struct hi16xx_uart_data *pd =
+ container_of(chip, struct hi16xx_uart_data, chip);
+
+ return io_pa_or_va(&pd->base);
+}
+
+static void hi16xx_uart_flush(struct serial_chip *chip)
+{
+ vaddr_t base = chip_to_base(chip);
+
+ while (!(read32(base + UART_USR) & UART_USR_TFE_BIT))
+ ;
+}
+
+static void hi16xx_uart_putc(struct serial_chip *chip, int ch)
+{
+ vaddr_t base = chip_to_base(chip);
+
+ /* Wait until TX FIFO is empty */
while (!(read32(base + UART_USR) & UART_USR_TFE_BIT))
;
+
+ /* Put character into TX FIFO */
+ write32(ch & 0xFF, base + UART_THR);
+}
+
+static bool hi16xx_uart_have_rx_data(struct serial_chip *chip)
+{
+ vaddr_t base = chip_to_base(chip);
+
+ return (read32(base + UART_USR) & UART_USR_RFNE_BIT);
+}
+
+static int hi16xx_uart_getchar(struct serial_chip *chip)
+{
+ vaddr_t base = chip_to_base(chip);
+
+ while (!hi16xx_uart_have_rx_data(chip))
+ ;
+ return read32(base + UART_RBR) & 0xFF;
}
-void hi16xx_uart_init(vaddr_t base, uint32_t uart_clk, uint32_t baud_rate)
+static const struct serial_ops hi16xx_uart_ops = {
+ .flush = hi16xx_uart_flush,
+ .getchar = hi16xx_uart_getchar,
+ .have_rx_data = hi16xx_uart_have_rx_data,
+ .putc = hi16xx_uart_putc,
+};
+KEEP_PAGER(hi16xx_uart_ops);
+
+void hi16xx_uart_init(struct hi16xx_uart_data *pd, paddr_t base,
+ uint32_t uart_clk, uint32_t baud_rate)
{
uint16_t freq_div = uart_clk / (16 * baud_rate);
+ pd->base.pa = base;
+ pd->chip.ops = &hi16xx_uart_ops;
+
/* Enable (and clear) FIFOs */
write32(UART_FCR_FIFO_EN, base + UART_FCR);
@@ -104,28 +158,6 @@ void hi16xx_uart_init(vaddr_t base, uint32_t uart_clk, uint32_t baud_rate)
/* Disable interrupt mode */
write32(0, base + UART_IEL);
- hi16xx_uart_flush(base);
-}
-
-void hi16xx_uart_putc(int ch, vaddr_t base)
-{
- /* Wait until TX FIFO is empty */
- while (!(read32(base + UART_USR) & UART_USR_TFE_BIT))
- ;
-
- /* Put character into TX FIFO */
- write32(ch & 0xFF, base + UART_THR);
-}
-
-bool hi16xx_uart_have_rx_data(vaddr_t base)
-{
- return (read32(base + UART_USR) & UART_USR_RFNE_BIT);
-}
-
-int hi16xx_uart_getchar(vaddr_t base)
-{
- while (!hi16xx_uart_have_rx_data(base))
- ;
- return read32(base + UART_RBR) & 0xFF;
+ hi16xx_uart_flush(&pd->chip);
}
diff --git a/core/drivers/imx_uart.c b/core/drivers/imx_uart.c
index b66d905..dd15ddb 100644
--- a/core/drivers/imx_uart.c
+++ b/core/drivers/imx_uart.c
@@ -25,12 +25,11 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <platform_config.h>
-
+#include <assert.h>
#include <drivers/imx_uart.h>
-#include <console.h>
#include <io.h>
-#include <compiler.h>
+#include <keep.h>
+#include <util.h>
/* Register definitions */
#define URXD 0x0 /* Receiver Register */
@@ -80,33 +79,57 @@
#define UTS_RXFULL (1<<3) /* RxFIFO full */
#define UTS_SOFTRST (1<<0) /* Software reset */
-void imx_uart_init(vaddr_t __unused vbase)
+static vaddr_t chip_to_base(struct serial_chip *chip)
{
- /*
- * Do nothing, debug uart(uart0) share with normal world,
- * everything for uart0 intialization is done in bootloader.
- */
+ struct imx_uart_data *pd =
+ container_of(chip, struct imx_uart_data, chip);
+
+ return io_pa_or_va(&pd->base);
}
-void imx_uart_flush_tx_fifo(vaddr_t base)
+static void imx_uart_flush(struct serial_chip *chip)
{
+ vaddr_t base = chip_to_base(chip);
+
while (!(read32(base + UTS) & UTS_TXEMPTY))
;
}
-int imx_uart_getchar(vaddr_t base)
+static int imx_uart_getchar(struct serial_chip *chip)
{
+ vaddr_t base = chip_to_base(chip);
+
while (read32(base + UTS) & UTS_RXEMPTY)
;
return (read32(base + URXD) & URXD_RX_DATA);
}
-void imx_uart_putc(const char c, vaddr_t base)
+static void imx_uart_putc(struct serial_chip *chip, int ch)
{
- write32(c, base + UTXD);
+ vaddr_t base = chip_to_base(chip);
+
+ write32(ch, base + UTXD);
- /* wait until sent */
+ /* Wait until sent */
while (!(read32(base + UTS) & UTS_TXEMPTY))
;
}
+
+static const struct serial_ops imx_uart_ops = {
+ .flush = imx_uart_flush,
+ .getchar = imx_uart_getchar,
+ .putc = imx_uart_putc,
+};
+KEEP_PAGER(imx_uart_ops);
+
+void imx_uart_init(struct imx_uart_data *pd, paddr_t base)
+{
+ pd->base.pa = base;
+ pd->chip.ops = &imx_uart_ops;
+
+ /*
+ * Do nothing, debug uart(uart0) share with normal world,
+ * everything for uart0 initialization is done in bootloader.
+ */
+}
diff --git a/core/drivers/ns16550.c b/core/drivers/ns16550.c
index 710b351..62c6d7f 100644
--- a/core/drivers/ns16550.c
+++ b/core/drivers/ns16550.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2015 Freescale Semiconductor, Inc.
+ * Copyright (c) 2017, Linaro Limited
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,6 +28,8 @@
#include <drivers/ns16550.h>
#include <io.h>
+#include <keep.h>
+#include <util.h>
/* uart register defines */
#define UART_RBR 0x0
@@ -42,16 +45,45 @@
/* uart status register bits */
#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
-void ns16550_flush(vaddr_t base)
+static vaddr_t chip_to_base(struct serial_chip *chip)
{
+ struct ns16550_data *pd =
+ container_of(chip, struct ns16550_data, chip);
+
+ return io_pa_or_va(&pd->base);
+}
+
+static void ns16550_flush(struct serial_chip *chip)
+{
+ vaddr_t base = chip_to_base(chip);
+
while ((read8(base + UART_LSR) & UART_LSR_THRE) == 0)
;
}
-void ns16550_putc(int ch, vaddr_t base)
+static void ns16550_putc(struct serial_chip *chip, int ch)
{
- ns16550_flush(base);
+ vaddr_t base = chip_to_base(chip);
+
+ ns16550_flush(chip);
/* write out charset to Transmit-hold-register */
write8(ch, base + UART_THR);
}
+
+static const struct serial_ops ns16550_ops = {
+ .flush = ns16550_flush,
+ .putc = ns16550_putc,
+};
+KEEP_PAGER(ns16550_ops);
+
+void ns16550_init(struct ns16550_data *pd, paddr_t base)
+{
+ pd->base.pa = base;
+ pd->chip.ops = &ns16550_ops;
+
+ /*
+ * Do nothing, uart driver shared with normal world,
+ * everything for uart driver initialization is done in bootloader.
+ */
+}
diff --git a/core/drivers/pl011.c b/core/drivers/pl011.c
index 8c03090..7263707 100644
--- a/core/drivers/pl011.c
+++ b/core/drivers/pl011.c
@@ -24,8 +24,11 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include <assert.h>
#include <drivers/pl011.h>
#include <io.h>
+#include <keep.h>
+#include <util.h>
#define UART_DR 0x00 /* data register */
#define UART_RSR_ECR 0x04 /* receive status or error clear */
@@ -89,14 +92,64 @@
#define UART_IMSC_RTIM (1 << 6)
#define UART_IMSC_RXIM (1 << 4)
-void pl011_flush(vaddr_t base)
+static vaddr_t chip_to_base(struct serial_chip *chip)
{
+ struct pl011_data *pd =
+ container_of(chip, struct pl011_data, chip);
+
+ return io_pa_or_va(&pd->base);
+}
+
+static void pl011_flush(struct serial_chip *chip)
+{
+ vaddr_t base = chip_to_base(chip);
+
while (!(read32(base + UART_FR) & UART_FR_TXFE))
;
}
-void pl011_init(vaddr_t base, uint32_t uart_clk, uint32_t baud_rate)
+static bool pl011_have_rx_data(struct serial_chip *chip)
+{
+ vaddr_t base = chip_to_base(chip);
+
+ return !(read32(base + UART_FR) & UART_FR_RXFE);
+}
+
+static int pl011_getchar(struct serial_chip *chip)
+{
+ vaddr_t base = chip_to_base(chip);
+
+ while (!pl011_have_rx_data(chip))
+ ;
+ return read32(base + UART_DR) & 0xff;
+}
+
+static void pl011_putc(struct serial_chip *chip, int ch)
+{
+ vaddr_t base = chip_to_base(chip);
+
+ /* Wait until there is space in the FIFO */
+ while (read32(base + UART_FR) & UART_FR_TXFF)
+ ;
+
+ /* Send the character */
+ write32(ch, base + UART_DR);
+}
+
+static const struct serial_ops pl011_ops = {
+ .flush = pl011_flush,
+ .getchar = pl011_getchar,
+ .have_rx_data = pl011_have_rx_data,
+ .putc = pl011_putc,
+};
+KEEP_PAGER(pl011_ops);
+
+void pl011_init(struct pl011_data *pd, paddr_t base, uint32_t uart_clk,
+ uint32_t baud_rate)
{
+ pd->base.pa = base;
+ pd->chip.ops = &pl011_ops;
+
/* Clear all errors */
write32(0, base + UART_RSR_ECR);
/* Disable everything */
@@ -118,30 +171,6 @@ void pl011_init(vaddr_t base, uint32_t uart_clk, uint32_t baud_rate)
/* Enable UART and RX/TX */
write32(UART_CR_UARTEN | UART_CR_TXE | UART_CR_RXE, base + UART_CR);
- pl011_flush(base);
-}
-
-void pl011_putc(int ch, vaddr_t base)
-{
- /*
- * Wait until there is space in the FIFO
- */
- while (read32(base + UART_FR) & UART_FR_TXFF)
- ;
-
- /* Send the character */
- write32(ch, base + UART_DR);
-}
-
-bool pl011_have_rx_data(vaddr_t base)
-{
- return !(read32(base + UART_FR) & UART_FR_RXFE);
-}
-
-int pl011_getchar(vaddr_t base)
-{
- while (!pl011_have_rx_data(base))
- ;
- return read32(base + UART_DR) & 0xff;
+ pl011_flush(&pd->chip);
}
diff --git a/core/drivers/pl050.c b/core/drivers/pl050.c
index fa5feab..aedaf71 100644
--- a/core/drivers/pl050.c
+++ b/core/drivers/pl050.c
@@ -26,8 +26,9 @@
*/
#include <compiler.h>
#include <drivers/pl050.h>
-#include <util.h>
#include <io.h>
+#include <keep.h>
+#include <util.h>
#define KMI_ICR 0x00
#define KMI_STAT 0x04
@@ -91,6 +92,7 @@ static const struct serial_ops pl050_ops = {
.have_rx_data = pl050_have_rx_data,
.getchar = pl050_getchar,
};
+KEEP_PAGER(pl050_ops);
void pl050_init(struct pl050_data *pd, vaddr_t base, uint32_t clk)
{
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);
+}
diff --git a/core/drivers/serial8250_uart.c b/core/drivers/serial8250_uart.c
index 1dd21de..5e86158 100644
--- a/core/drivers/serial8250_uart.c
+++ b/core/drivers/serial8250_uart.c
@@ -24,12 +24,13 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <platform_config.h>
-#include <drivers/serial8250_uart.h>
+#include <compiler.h>
#include <console.h>
+#include <drivers/serial8250_uart.h>
#include <io.h>
-#include <compiler.h>
+#include <keep.h>
+#include <util.h>
/* uart register defines */
#define UART_RHR 0x0
@@ -49,45 +50,73 @@
#define LSR_EMPTY (LSR_TEMT | LSR_THRE)
#define LSR_DR 0x01 /* DATA Ready */
-void serial8250_uart_init(vaddr_t __unused base,
- uint32_t __unused uart_clk, uint32_t __unused baud_rate)
+static vaddr_t chip_to_base(struct serial_chip *chip)
{
- /*
- * do nothing, debug uart(uart0) share with normal world,
- * everything for uart0 is ready now.
- */
+ struct serial8250_uart_data *pd =
+ container_of(chip, struct serial8250_uart_data, chip);
+
+ return io_pa_or_va(&pd->base);
}
-void serial8250_uart_flush_tx_fifo(vaddr_t base)
+static void serial8250_uart_flush(struct serial_chip *chip)
{
+ vaddr_t base = chip_to_base(chip);
+
while (1) {
uint8_t state = read8(base + UART_LSR);
- /* waiting transmit fifo empty */
+ /* Wait until transmit FIFO is empty */
if ((state & LSR_EMPTY) == LSR_EMPTY)
break;
}
}
-bool serial8250_uart_have_rx_data(vaddr_t base)
+static bool serial8250_uart_have_rx_data(struct serial_chip *chip)
{
+ vaddr_t base = chip_to_base(chip);
+
return (read32(base + UART_LSR) & LSR_DR);
}
-void serial8250_uart_putc(int ch, vaddr_t base)
+static int serial8250_uart_getchar(struct serial_chip *chip)
{
- serial8250_uart_flush_tx_fifo(base);
+ vaddr_t base = chip_to_base(chip);
- /* write out charset to transmit fifo */
- write8(ch, base + UART_THR);
-}
-
-int serial8250_uart_getchar(vaddr_t base)
-{
- while (!serial8250_uart_have_rx_data(base)) {
- /* transmit fifo is empty, waiting again. */
+ while (!serial8250_uart_have_rx_data(chip)) {
+ /* Transmit FIFO is empty, waiting again */
;
}
return read8(base + UART_RHR);
}
+static void serial8250_uart_putc(struct serial_chip *chip, int ch)
+{
+ vaddr_t base = chip_to_base(chip);
+
+ serial8250_uart_flush(chip);
+
+ /* Write out character to transmit FIFO */
+ write8(ch, base + UART_THR);
+}
+
+static const struct serial_ops serial8250_uart_ops = {
+ .flush = serial8250_uart_flush,
+ .getchar = serial8250_uart_getchar,
+ .have_rx_data = serial8250_uart_have_rx_data,
+ .putc = serial8250_uart_putc,
+};
+KEEP_PAGER(serial8250_uart_ops);
+
+void serial8250_uart_init(struct serial8250_uart_data *pd, paddr_t base,
+ uint32_t __unused uart_clk,
+ uint32_t __unused baud_rate)
+
+{
+ pd->base.pa = base;
+ pd->chip.ops = &serial8250_uart_ops;
+
+ /*
+ * do nothing, debug uart(uart0) share with normal world,
+ * everything for uart0 is ready now.
+ */
+}
diff --git a/core/drivers/sprd_uart.c b/core/drivers/sprd_uart.c
index fdaa1b6..c77f595 100644
--- a/core/drivers/sprd_uart.c
+++ b/core/drivers/sprd_uart.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2016, Spreadtrum Communications Inc.
+ * Copyright (c) 2017, Linaro Limited
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,8 +25,10 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <io.h>
#include <drivers/sprd_uart.h>
+#include <io.h>
+#include <keep.h>
+#include <util.h>
/* Register definitions */
#define UART_TXD 0x0000
@@ -36,43 +39,57 @@
#define STS1_RXF_CNT_MASK 0x00ff /* Rx FIFO data counter mask */
#define STS1_TXF_CNT_MASK 0xff00 /* Tx FIFO data counter mask */
-static uint32_t sprd_uart_read(vaddr_t base, uint32_t reg)
+static vaddr_t chip_to_base(struct serial_chip *chip)
{
- return read32(base + reg);
-}
+ struct sprd_uart_data *pd =
+ container_of(chip, struct sprd_uart_data, chip);
-static void sprd_uart_write(vaddr_t base, uint32_t reg, uint32_t value)
-{
- write32(value, base + reg);
+ return io_pa_or_va(&pd->base);
}
-static void sprd_uart_wait_xmit_done(vaddr_t base)
+static void sprd_uart_flush(struct serial_chip *chip)
{
- while (sprd_uart_read(base, UART_STS1) & STS1_TXF_CNT_MASK)
+ vaddr_t base = chip_to_base(chip);
+
+ while (read32(base + UART_STS1) & STS1_TXF_CNT_MASK)
;
}
-static void sprd_uart_wait_rx_data(vaddr_t base)
+static bool sprd_uart_have_rx_data(struct serial_chip *chip)
{
- while (!(sprd_uart_read(base, UART_STS1) & STS1_RXF_CNT_MASK))
- ;
+ vaddr_t base = chip_to_base(chip);
+
+ return !!(read32(base + UART_STS1) & STS1_RXF_CNT_MASK);
}
-void sprd_uart_flush(vaddr_t base)
+static void sprd_uart_putc(struct serial_chip *chip, int ch)
{
- sprd_uart_wait_xmit_done(base);
+ vaddr_t base = chip_to_base(chip);
+
+ sprd_uart_flush(chip);
+ write32(base + UART_TXD, ch);
}
-void sprd_uart_putc(vaddr_t base, unsigned char ch)
+static int sprd_uart_getchar(struct serial_chip *chip)
{
- sprd_uart_wait_xmit_done(base);
+ vaddr_t base = chip_to_base(chip);
+
+ while (!sprd_uart_have_rx_data(chip))
+ ;
- sprd_uart_write(base, UART_TXD, (uint32_t)ch);
+ return read32(base + UART_RXD) & 0xff;
}
-unsigned char sprd_uart_getc(vaddr_t base)
-{
- sprd_uart_wait_rx_data(base);
+static const struct serial_ops sprd_uart_ops = {
+ .flush = sprd_uart_flush,
+ .getchar = sprd_uart_getchar,
+ .have_rx_data = sprd_uart_have_rx_data,
+ .putc = sprd_uart_putc,
+};
+KEEP_PAGER(sprd_uart_ops);
- return sprd_uart_read(base, UART_RXD) & 0xff;
+void sprd_uart_init(struct sprd_uart_data *pd, paddr_t base)
+{
+ pd->base.pa = base;
+ pd->chip.ops = &sprd_uart_ops;
}
diff --git a/core/drivers/stih_asc.c b/core/drivers/stih_asc.c
new file mode 100644
index 0000000..7f69ce7
--- /dev/null
+++ b/core/drivers/stih_asc.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017, Linaro Limited
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <drivers/stih_asc.h>
+#include <io.h>
+#include <keep.h>
+#include <util.h>
+
+#define ASC_BAUDRATE 0x00
+#define ASC_TXBUFFER 0x04
+#define ASC_STATUS 0x14
+
+#define ASC_STATUS_TX_EMPTY BIT(1)
+#define ASC_STATUS_TX_HALF_EMPTY BIT(2)
+
+static vaddr_t chip_to_base(struct serial_chip *chip)
+{
+ struct stih_asc_pd *pd =
+ container_of(chip, struct stih_asc_pd, chip);
+
+ return io_pa_or_va(&pd->base);
+}
+
+static void stih_asc_flush(struct serial_chip *chip)
+{
+ vaddr_t base = chip_to_base(chip);
+
+ while (!(read32(base + ASC_STATUS) & ASC_STATUS_TX_EMPTY))
+ ;
+}
+
+static void stih_asc_putc(struct serial_chip *chip, int ch)
+{
+ vaddr_t base = chip_to_base(chip);
+
+ while (!(read32(base + ASC_STATUS) & ASC_STATUS_TX_HALF_EMPTY))
+ ;
+
+ write32(ch, base + ASC_TXBUFFER);
+}
+
+static const struct serial_ops stih_asc_ops = {
+ .flush = stih_asc_flush,
+ .putc = stih_asc_putc,
+};
+KEEP_PAGER(stih_asc_ops);
+
+void stih_asc_init(struct stih_asc_pd *pd, vaddr_t base)
+{
+ pd->base.pa = base;
+ pd->chip.ops = &stih_asc_ops;
+}
diff --git a/core/drivers/sub.mk b/core/drivers/sub.mk
index 609b378..015f5c3 100644
--- a/core/drivers/sub.mk
+++ b/core/drivers/sub.mk
@@ -17,3 +17,4 @@ srcs-$(CFG_HI16XX_UART) += hi16xx_uart.c
srcs-$(CFG_HI16XX_RNG) += hi16xx_rng.c
srcs-$(CFG_SCIF) += scif.c
srcs-$(CFG_DRA7_RNG) += dra7_rng.c
+srcs-$(CFG_STIH_UART) += stih_asc.c
diff --git a/core/drivers/sunxi_uart.c b/core/drivers/sunxi_uart.c
index 433c423..b83da02 100644
--- a/core/drivers/sunxi_uart.c
+++ b/core/drivers/sunxi_uart.c
@@ -24,11 +24,10 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <platform_config.h>
-
#include <drivers/sunxi_uart.h>
#include <io.h>
-#include <compiler.h>
+#include <keep.h>
+#include <util.h>
/* uart register defines */
#define UART_REG_RBR (0x00)
@@ -55,28 +54,46 @@
#define UART_REG_USR_RFNE (0x1 << 0x3)
#define UART_REG_USR_RFF (0x1 << 0x4)
-void sunxi_uart_init(vaddr_t __unused base)
+static vaddr_t chip_to_base(struct serial_chip *chip)
{
- /* do nothing, debug uart(uart0) share with normal world,
- * everything for uart0 is ready now.
- */
+ struct sunxi_uart_data *pd =
+ container_of(chip, struct sunxi_uart_data, chip);
+
+ return io_pa_or_va(&pd->base);
}
-void sunxi_uart_flush(vaddr_t base)
+static void sunxi_uart_flush(struct serial_chip *chip)
{
+ vaddr_t base = chip_to_base(chip);
+
while (read32(base + UART_REG_TFL)) {
/* waiting transmit fifo empty */
;
}
}
-bool sunxi_uart_have_rx_data(vaddr_t base)
+static bool sunxi_uart_have_rx_data(struct serial_chip *chip)
{
+ vaddr_t base = chip_to_base(chip);
+
return read32(base + UART_REG_RFL);
}
-void sunxi_uart_putc(int ch, vaddr_t base)
+static int sunxi_uart_getchar(struct serial_chip *chip)
+{
+ vaddr_t base = chip_to_base(chip);
+
+ while (!sunxi_uart_have_rx_data(chip)) {
+ /* transmit fifo is empty, waiting again. */
+ ;
+ }
+ return read32(base + UART_REG_RBR) & 0xff;
+}
+
+static void sunxi_uart_putc(struct serial_chip *chip, int ch)
{
+ vaddr_t base = chip_to_base(chip);
+
while (!(read32(base + UART_REG_USR) & UART_REG_USR_TFNF)) {
/* transmit fifo is full, waiting again. */
;
@@ -86,12 +103,21 @@ void sunxi_uart_putc(int ch, vaddr_t base)
write8(ch, base + UART_REG_THR);
}
-int sunxi_uart_getchar(vaddr_t base)
+static const struct serial_ops sunxi_uart_ops = {
+ .flush = sunxi_uart_flush,
+ .getchar = sunxi_uart_getchar,
+ .have_rx_data = sunxi_uart_have_rx_data,
+ .putc = sunxi_uart_putc,
+};
+KEEP_PAGER(sunxi_uart_ops);
+
+void sunxi_uart_init(struct sunxi_uart_data *pd, paddr_t base)
{
- while (!sunxi_uart_have_rx_data(base)) {
- /* transmit fifo is empty, waiting again. */
- ;
- }
- return read32(base + UART_REG_RBR) & 0xff;
-}
+ pd->base.pa = base;
+ pd->chip.ops = &sunxi_uart_ops;
+ /*
+ * Do nothing, debug uart(uart0) share with normal world,
+ * everything for uart0 is ready now.
+ */
+}