svn commit: r272399 - head/sys/dev/uart

Ganbold Tsagaankhuu ganbold at FreeBSD.org
Thu Oct 2 08:12:43 UTC 2014


Author: ganbold
Date: Thu Oct  2 08:12:42 2014
New Revision: 272399
URL: https://svnweb.freebsd.org/changeset/base/272399

Log:
  Add uart driver for Qualcomm MSM 7000/8000 series chips.
  It is working on IFC6410 board which has Qualcomm Snapdragon SoC.
  
  Approved by:    stas (mentor)

Added:
  head/sys/dev/uart/uart_dev_msm.c   (contents, props changed)
  head/sys/dev/uart/uart_dev_msm.h   (contents, props changed)
Modified:
  head/sys/dev/uart/uart.h
  head/sys/dev/uart/uart_bus_fdt.c

Modified: head/sys/dev/uart/uart.h
==============================================================================
--- head/sys/dev/uart/uart.h	Thu Oct  2 06:29:49 2014	(r272398)
+++ head/sys/dev/uart/uart.h	Thu Oct  2 08:12:42 2014	(r272399)
@@ -65,6 +65,7 @@ struct uart_bas {
 struct uart_class;
 
 extern struct uart_class uart_imx_class __attribute__((weak));
+extern struct uart_class uart_msm_class __attribute__((weak));
 extern struct uart_class uart_ns8250_class __attribute__((weak));
 extern struct uart_class uart_quicc_class __attribute__((weak));
 extern struct uart_class uart_s3c2410_class __attribute__((weak));

Modified: head/sys/dev/uart/uart_bus_fdt.c
==============================================================================
--- head/sys/dev/uart/uart_bus_fdt.c	Thu Oct  2 06:29:49 2014	(r272398)
+++ head/sys/dev/uart/uart_bus_fdt.c	Thu Oct  2 08:12:42 2014	(r272399)
@@ -84,6 +84,7 @@ static struct ofw_compat_data compat_dat
 	{"fsl,imx21-uart",	(uintptr_t)&uart_imx_class},
 	{"fsl,mvf600-uart",	(uintptr_t)&uart_vybrid_class},
 	{"lpc,uart",		(uintptr_t)&uart_lpc_class},
+        {"qcom,uart-dm",        (uintptr_t)&uart_msm_class},
 	{"ti,ns16550",		(uintptr_t)&uart_ti8250_class},
 	{"ns16550",		(uintptr_t)&uart_ns8250_class},
 	{NULL,			(uintptr_t)NULL},

Added: head/sys/dev/uart/uart_dev_msm.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/dev/uart/uart_dev_msm.c	Thu Oct  2 08:12:42 2014	(r272399)
@@ -0,0 +1,568 @@
+/*-
+ * Copyright (c) 2014 Ganbold Tsagaankhuu <ganbold at freebsd.org>
+ * 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 AUTHOR ``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 AUTHOR 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.
+ */
+
+/* Qualcomm MSM7K/8K uart driver */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_ddb.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/kdb.h>
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_cpu.h>
+#include <dev/uart/uart_bus.h>
+#include <dev/uart/uart_dev_msm.h>
+
+#include "uart_if.h"
+
+#define	DEF_CLK		7372800
+
+#define	GETREG(bas, reg)	\
+    bus_space_read_4((bas)->bst, (bas)->bsh, (reg))
+#define	SETREG(bas, reg, value)	\
+    bus_space_write_4((bas)->bst, (bas)->bsh, (reg), (value))
+
+static int msm_uart_param(struct uart_bas *, int, int, int, int);
+
+/*
+ * Low-level UART interface.
+ */
+static int	msm_probe(struct uart_bas *bas);
+static void	msm_init(struct uart_bas *bas, int, int, int, int);
+static void	msm_term(struct uart_bas *bas);
+static void	msm_putc(struct uart_bas *bas, int);
+static int	msm_rxready(struct uart_bas *bas);
+static int	msm_getc(struct uart_bas *bas, struct mtx *mtx);
+
+extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs;
+
+static int
+msm_uart_param(struct uart_bas *bas, int baudrate, int databits,
+    int stopbits, int parity)
+{
+	int ulcon;
+
+	ulcon = 0;
+
+	switch (databits) {
+	case 5:
+		ulcon |= (UART_DM_5_BPS << 4);
+		break;
+	case 6:
+		ulcon |= (UART_DM_6_BPS << 4);
+		break;
+	case 7:
+		ulcon |= (UART_DM_7_BPS << 4);
+		break;
+	case 8:
+		ulcon |= (UART_DM_8_BPS << 4);
+		break;
+	default:
+		return (EINVAL);
+	}
+
+	switch (parity) {
+	case UART_PARITY_NONE:
+		ulcon |= UART_DM_NO_PARITY;
+		break;
+	case UART_PARITY_ODD:
+		ulcon |= UART_DM_ODD_PARITY;
+		break;
+	case UART_PARITY_EVEN:
+		ulcon |= UART_DM_EVEN_PARITY;
+		break;
+	case UART_PARITY_SPACE:
+		ulcon |= UART_DM_SPACE_PARITY;
+		break;
+	case UART_PARITY_MARK:
+	default:
+		return (EINVAL);
+	}
+
+	switch (stopbits) {
+	case 1:
+		ulcon |= (UART_DM_SBL_1 << 2);
+		break;
+	case 2:
+		ulcon |= (UART_DM_SBL_2 << 2);
+		break;
+	default:
+		return (EINVAL);
+	}
+	uart_setreg(bas, UART_DM_MR2, ulcon);
+
+	/* Set 115200 for both TX and RX. */;
+	uart_setreg(bas, UART_DM_CSR, UART_DM_CSR_115200);
+	uart_barrier(bas);
+
+	return (0);
+}
+
+struct uart_ops uart_msm_ops = {
+	.probe = msm_probe,
+	.init = msm_init,
+	.term = msm_term,
+	.putc = msm_putc,
+	.rxready = msm_rxready,
+	.getc = msm_getc,
+};
+
+static int
+msm_probe(struct uart_bas *bas)
+{
+
+	return (0);
+}
+
+static void
+msm_init(struct uart_bas *bas, int baudrate, int databits, int stopbits,
+    int parity)
+{
+
+	if (bas->rclk == 0)
+		bas->rclk = DEF_CLK;
+
+	KASSERT(bas->rclk != 0, ("msm_init: Invalid rclk"));
+
+	/* Set default parameters */
+	msm_uart_param(bas, baudrate, databits, stopbits, parity);
+
+	/*
+	 * Configure UART mode registers MR1 and MR2.
+	 * Hardware flow control isn't supported.
+	 */
+	uart_setreg(bas, UART_DM_MR1, 0x0);
+
+	/* Reset interrupt mask register. */
+	uart_setreg(bas, UART_DM_IMR, 0);
+
+	/*
+	 * Configure Tx and Rx watermarks configuration registers.
+	 * TX watermark value is set to 0 - interrupt is generated when
+	 * FIFO level is less than or equal to 0.
+	 */
+	uart_setreg(bas, UART_DM_TFWR, UART_DM_TFW_VALUE);
+
+	/* Set RX watermark value */
+	uart_setreg(bas, UART_DM_RFWR, UART_DM_RFW_VALUE);
+
+	/*
+	 * Configure Interrupt Programming Register.
+	 * Set initial Stale timeout value.
+	 */
+	uart_setreg(bas, UART_DM_IPR, UART_DM_STALE_TIMEOUT_LSB);
+
+	/* Disable IRDA mode */
+	uart_setreg(bas, UART_DM_IRDA, 0x0);
+
+	/*
+	 * Configure and enable sim interface if required.
+	 * Configure hunt character value in HCR register.
+	 * Keep it in reset state.
+	 */
+	uart_setreg(bas, UART_DM_HCR, 0x0);
+
+	/* Issue soft reset command */
+	SETREG(bas, UART_DM_CR, UART_DM_RESET_TX);
+	SETREG(bas, UART_DM_CR, UART_DM_RESET_RX);
+	SETREG(bas, UART_DM_CR, UART_DM_RESET_ERROR_STATUS);
+	SETREG(bas, UART_DM_CR, UART_DM_RESET_BREAK_INT);
+	SETREG(bas, UART_DM_CR, UART_DM_RESET_STALE_INT);
+
+	/* Enable/Disable Rx/Tx DM interfaces */
+	/* Disable Data Mover for now. */
+	uart_setreg(bas, UART_DM_DMEN, 0x0);
+
+	/* Enable transmitter and receiver */
+	uart_setreg(bas, UART_DM_CR, UART_DM_CR_RX_ENABLE);
+	uart_setreg(bas, UART_DM_CR, UART_DM_CR_TX_ENABLE);
+
+	uart_barrier(bas);
+}
+
+static void
+msm_term(struct uart_bas *bas)
+{
+
+	/* XXX */
+}
+
+static void
+msm_putc(struct uart_bas *bas, int c)
+{
+	int limit;
+
+	/*
+	 * Write to NO_CHARS_FOR_TX register the number of characters
+	 * to be transmitted. However, before writing TX_FIFO must
+	 * be empty as indicated by TX_READY interrupt in IMR register
+	 */
+
+	/*
+	 * Check if transmit FIFO is empty.
+	 * If not wait for TX_READY interrupt.
+	 */
+	limit = 1000;
+	if (!(uart_getreg(bas, UART_DM_SR) & UART_DM_SR_TXEMT)) {
+		while ((uart_getreg(bas, UART_DM_ISR) & UART_DM_TX_READY) == 0
+		    && --limit)
+			DELAY(4);
+	}
+	/* FIFO is ready, write number of characters to be written */
+	uart_setreg(bas, UART_DM_NO_CHARS_FOR_TX, 1);
+
+	/* Wait till TX FIFO has space */
+	while ((uart_getreg(bas, UART_DM_SR) & UART_DM_SR_TXRDY) == 0)
+		DELAY(4);
+
+	/* TX FIFO has space. Write char */
+	SETREG(bas, UART_DM_TF(0), (c & 0xff));
+}
+
+static int
+msm_rxready(struct uart_bas *bas)
+{
+
+	/* Wait for a character to come ready */
+	return ((uart_getreg(bas, UART_DM_SR) & UART_DM_SR_RXRDY) ==
+	    UART_DM_SR_RXRDY);
+}
+
+static int
+msm_getc(struct uart_bas *bas, struct mtx *mtx)
+{
+	int c;
+
+	uart_lock(mtx);
+
+	/* Wait for a character to come ready */
+	while ((uart_getreg(bas, UART_DM_SR) & UART_DM_SR_RXRDY) !=
+	    UART_DM_SR_RXRDY)
+		DELAY(4);
+
+	/* Check for Overrun error. If so reset Error Status */
+	if (uart_getreg(bas, UART_DM_SR) & UART_DM_SR_UART_OVERRUN)
+		uart_setreg(bas, UART_DM_CR, UART_DM_RESET_ERROR_STATUS);
+
+	/* Read char */
+	c = uart_getreg(bas, UART_DM_RF(0));
+
+	uart_unlock(mtx);
+
+	return (c);
+}
+
+/*
+ * High-level UART interface.
+ */
+struct msm_uart_softc {
+	struct uart_softc base;
+	uint32_t ier;
+};
+
+static int	msm_bus_probe(struct uart_softc *sc);
+static int	msm_bus_attach(struct uart_softc *sc);
+static int	msm_bus_flush(struct uart_softc *, int);
+static int	msm_bus_getsig(struct uart_softc *);
+static int	msm_bus_ioctl(struct uart_softc *, int, intptr_t);
+static int	msm_bus_ipend(struct uart_softc *);
+static int	msm_bus_param(struct uart_softc *, int, int, int, int);
+static int	msm_bus_receive(struct uart_softc *);
+static int	msm_bus_setsig(struct uart_softc *, int);
+static int	msm_bus_transmit(struct uart_softc *);
+static void	msm_bus_grab(struct uart_softc *);
+static void	msm_bus_ungrab(struct uart_softc *);
+
+static kobj_method_t msm_methods[] = {
+	KOBJMETHOD(uart_probe,		msm_bus_probe),
+	KOBJMETHOD(uart_attach, 	msm_bus_attach),
+	KOBJMETHOD(uart_flush,		msm_bus_flush),
+	KOBJMETHOD(uart_getsig,		msm_bus_getsig),
+	KOBJMETHOD(uart_ioctl,		msm_bus_ioctl),
+	KOBJMETHOD(uart_ipend,		msm_bus_ipend),
+	KOBJMETHOD(uart_param,		msm_bus_param),
+	KOBJMETHOD(uart_receive,	msm_bus_receive),
+	KOBJMETHOD(uart_setsig,		msm_bus_setsig),
+	KOBJMETHOD(uart_transmit,	msm_bus_transmit),
+	KOBJMETHOD(uart_grab,		msm_bus_grab),
+	KOBJMETHOD(uart_ungrab,		msm_bus_ungrab),
+	{0, 0 }
+};
+
+int
+msm_bus_probe(struct uart_softc *sc)
+{
+
+	sc->sc_txfifosz = 64;
+	sc->sc_rxfifosz = 64;
+
+	device_set_desc(sc->sc_dev, "Qualcomm HSUART");
+
+	return (0);
+}
+
+static int
+msm_bus_attach(struct uart_softc *sc)
+{
+	struct msm_uart_softc *u = (struct msm_uart_softc *)sc;
+	struct uart_bas *bas = &sc->sc_bas;
+
+	sc->sc_hwiflow = 0;
+	sc->sc_hwoflow = 0;
+
+	/* Set TX_READY, TXLEV, RXLEV, RXSTALE */
+	u->ier = UART_DM_IMR_ENABLED;
+
+	/* Configure Interrupt Mask register IMR */
+	uart_setreg(bas, UART_DM_IMR, u->ier);
+
+	return (0);
+}
+
+/*
+ * Write the current transmit buffer to the TX FIFO. 
+ */
+static int
+msm_bus_transmit(struct uart_softc *sc)
+{
+	struct msm_uart_softc *u = (struct msm_uart_softc *)sc;
+	struct uart_bas *bas = &sc->sc_bas;
+	int i;
+
+	uart_lock(sc->sc_hwmtx);
+
+	/* Write some data */
+	for (i = 0; i < sc->sc_txdatasz; i++) {
+		/* Write TX data */
+		msm_putc(bas, sc->sc_txbuf[i]);
+		uart_barrier(bas);
+	}
+
+	/* TX FIFO is empty now, enable TX_READY interrupt */
+	u->ier |= UART_DM_TX_READY;
+	SETREG(bas, UART_DM_IMR, u->ier);
+	uart_barrier(bas);
+
+	/*
+	 * Inform upper layer that it is transmitting data to hardware,
+	 * this will be cleared when TXIDLE interrupt occurs.
+	 */
+	sc->sc_txbusy = 1;
+	uart_unlock(sc->sc_hwmtx);
+
+	return (0);
+}
+
+static int
+msm_bus_setsig(struct uart_softc *sc, int sig)
+{
+
+	return (0);
+}
+
+static int
+msm_bus_receive(struct uart_softc *sc)
+{
+	struct msm_uart_softc *u = (struct msm_uart_softc *)sc;
+	struct uart_bas *bas;
+	int c;
+
+	bas = &sc->sc_bas;
+	uart_lock(sc->sc_hwmtx);
+
+	/* Initialize Receive Path and interrupt */
+	SETREG(bas, UART_DM_CR, UART_DM_RESET_STALE_INT);
+	SETREG(bas, UART_DM_CR, UART_DM_STALE_EVENT_ENABLE);
+	u->ier |= UART_DM_RXLEV;
+	SETREG(bas, UART_DM_IMR, u->ier);
+
+	/* Loop over until we are full, or no data is available */
+	while (uart_getreg(bas, UART_DM_SR) & UART_DM_SR_RXRDY) {
+		if (uart_rx_full(sc)) {
+			/* No space left in input buffer */
+			sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN;
+			break;
+		}
+
+		/* Read RX FIFO */
+		c = uart_getreg(bas, UART_DM_RF(0));
+		uart_barrier(bas);
+
+		uart_rx_put(sc, c);
+	}
+
+	uart_unlock(sc->sc_hwmtx);
+
+	return (0);
+}
+
+static int
+msm_bus_param(struct uart_softc *sc, int baudrate, int databits,
+    int stopbits, int parity)
+{
+	int error;
+
+	if (sc->sc_bas.rclk == 0)
+		sc->sc_bas.rclk = DEF_CLK;
+
+	KASSERT(sc->sc_bas.rclk != 0, ("msm_init: Invalid rclk"));
+
+	uart_lock(sc->sc_hwmtx);
+	error = msm_uart_param(&sc->sc_bas, baudrate, databits, stopbits,
+	    parity);
+	uart_unlock(sc->sc_hwmtx);
+
+	return (error);
+}
+
+static int
+msm_bus_ipend(struct uart_softc *sc)
+{
+	struct msm_uart_softc *u = (struct msm_uart_softc *)sc;
+	struct uart_bas *bas = &sc->sc_bas;
+	uint32_t isr;
+	int ipend;
+
+	uart_lock(sc->sc_hwmtx);
+
+	/* Get ISR status */
+	isr = GETREG(bas, UART_DM_MISR);
+
+	ipend = 0;
+
+	/* Uart RX starting, notify upper layer */
+	if (isr & UART_DM_RXLEV) {
+		u->ier &= ~UART_DM_RXLEV;
+		SETREG(bas, UART_DM_IMR, u->ier);
+		uart_barrier(bas);
+		ipend |= SER_INT_RXREADY;
+	}
+
+	/* Stale RX interrupt */
+	if (isr & UART_DM_RXSTALE) {
+		/* Disable and reset it */
+		SETREG(bas, UART_DM_CR, UART_DM_STALE_EVENT_DISABLE);
+		SETREG(bas, UART_DM_CR, UART_DM_RESET_STALE_INT);
+		uart_barrier(bas);
+		ipend |= SER_INT_RXREADY;
+	}
+
+	/* TX READY interrupt */
+	if (isr & UART_DM_TX_READY) {
+		/* Clear  TX Ready */
+		SETREG(bas, UART_DM_CR, UART_DM_CLEAR_TX_READY);
+
+		/* Disable TX_READY */
+		u->ier &= ~UART_DM_TX_READY;
+		SETREG(bas, UART_DM_IMR, u->ier);
+		uart_barrier(bas);
+
+		if (sc->sc_txbusy != 0)
+			ipend |= SER_INT_TXIDLE;
+	}
+
+	if (isr & UART_DM_TXLEV) {
+		/* TX FIFO is empty */
+		u->ier &= ~UART_DM_TXLEV;
+		SETREG(bas, UART_DM_IMR, u->ier);
+		uart_barrier(bas);
+
+		if (sc->sc_txbusy != 0)
+			ipend |= SER_INT_TXIDLE;
+	}
+
+	uart_unlock(sc->sc_hwmtx);
+	return (ipend);
+}
+
+static int
+msm_bus_flush(struct uart_softc *sc, int what)
+{
+
+	return (0);
+}
+
+static int
+msm_bus_getsig(struct uart_softc *sc)
+{
+
+	return (0);
+}
+
+static int
+msm_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
+{
+
+	return (EINVAL);
+}
+
+static void
+msm_bus_grab(struct uart_softc *sc)
+{
+	struct uart_bas *bas = &sc->sc_bas;
+
+	/*
+	 * XXX: Turn off all interrupts to enter polling mode. Leave the
+	 * saved mask alone. We'll restore whatever it was in ungrab.
+	 */
+	uart_lock(sc->sc_hwmtx);
+	SETREG(bas, UART_DM_CR, UART_DM_RESET_STALE_INT);
+	SETREG(bas, UART_DM_IMR, 0);
+	uart_barrier(bas);
+	uart_unlock(sc->sc_hwmtx);
+}
+
+static void
+msm_bus_ungrab(struct uart_softc *sc)
+{
+	struct msm_uart_softc *u = (struct msm_uart_softc *)sc;
+	struct uart_bas *bas = &sc->sc_bas;
+
+	/*
+	 * Restore previous interrupt mask
+	 */
+	uart_lock(sc->sc_hwmtx);
+	SETREG(bas, UART_DM_IMR, u->ier);
+	uart_barrier(bas);
+	uart_unlock(sc->sc_hwmtx);
+}
+
+struct uart_class uart_msm_class = {
+	"msm",
+	msm_methods,
+	sizeof(struct msm_uart_softc),
+	.uc_ops = &uart_msm_ops,
+	.uc_range = 8,
+	.uc_rclk = DEF_CLK,
+};

Added: head/sys/dev/uart/uart_dev_msm.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/dev/uart/uart_dev_msm.h	Thu Oct  2 08:12:42 2014	(r272399)
@@ -0,0 +1,229 @@
+/*-
+ * Copyright (c) 2014 Ganbold Tsagaankhuu <ganbold at freebsd.org>
+ * 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 AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef	_UART_DM_H_
+#define	_UART_DM_H_
+
+#define	UART_DM_EXTR_BITS(value, start_pos, end_pos) \
+	    ((value << (32 - end_pos)) >> (32 - (end_pos - start_pos)))
+
+/* UART Parity Mode */
+enum UART_DM_PARITY_MODE {
+	UART_DM_NO_PARITY,
+	UART_DM_ODD_PARITY,
+	UART_DM_EVEN_PARITY,
+	UART_DM_SPACE_PARITY
+};
+
+/* UART Stop Bit Length */
+enum UART_DM_STOP_BIT_LEN {
+	UART_DM_SBL_9_16,
+	UART_DM_SBL_1,
+	UART_DM_SBL_1_9_16,
+	UART_DM_SBL_2
+};
+
+/* UART Bits per Char */
+enum UART_DM_BITS_PER_CHAR {
+	UART_DM_5_BPS,
+	UART_DM_6_BPS,
+	UART_DM_7_BPS,
+	UART_DM_8_BPS
+};
+
+/* 8-N-1 Configuration */
+#define	UART_DM_8_N_1_MODE			(UART_DM_NO_PARITY | \
+						(UART_DM_SBL_1 << 2) | \
+						(UART_DM_8_BPS << 4))
+
+/* UART_DM Registers */
+
+/* UART Operational Mode Registers (HSUART) */
+#define	UART_DM_MR1				0x00
+#define	 UART_DM_MR1_AUTO_RFR_LEVEL1_BMSK	0xffffff00
+#define	 UART_DM_MR1_AUTO_RFR_LEVEL0_BMSK	0x3f
+#define	 UART_DM_MR1_CTS_CTL_BMSK		0x40
+#define	 UART_DM_MR1_RX_RDY_CTL_BMSK		0x80
+
+#define	UART_DM_MR2				0x04
+#define	 UART_DM_MR2_ERROR_MODE_BMSK		0x40
+#define	 UART_DM_MR2_BITS_PER_CHAR_BMSK		0x30
+#define	 UART_DM_MR2_STOP_BIT_LEN_BMSK		0x0c
+#define	 UART_DM_MR2_PARITY_MODE_BMSK		0x03
+#define	 UART_DM_RXBRK_ZERO_CHAR_OFF		(1 << 8)
+#define	 UART_DM_LOOPBACK			(1 << 7)
+
+/* UART Clock Selection Register, write only */
+#define	UART_DM_CSR				0x08
+#define	 UART_DM_CSR_115200			0xff
+#define	 UART_DM_CSR_57600			0xee
+#define	 UART_DM_CSR_38400			0xdd
+#define	 UART_DM_CSR_28800			0xcc
+#define	 UART_DM_CSR_19200			0xbb
+#define	 UART_DM_CSR_14400			0xaa
+#define	 UART_DM_CSR_9600			0x99
+#define	 UART_DM_CSR_7200			0x88
+#define	 UART_DM_CSR_4800			0x77
+#define	 UART_DM_CSR_3600			0x66
+#define	 UART_DM_CSR_2400			0x55
+#define	 UART_DM_CSR_1200			0x44
+#define	 UART_DM_CSR_600			0x33
+#define	 UART_DM_CSR_300			0x22
+#define	 UART_DM_CSR_150			0x11
+#define	 UART_DM_CSR_75				0x00
+
+/* UART DM TX FIFO Registers - 4, write only */
+#define	UART_DM_TF(x)				(0x70 + (4 * (x)))
+
+/* UART Command Register, write only */
+#define	UART_DM_CR				0x10
+#define	 UART_DM_CR_RX_ENABLE			(1 << 0)
+#define	 UART_DM_CR_RX_DISABLE			(1 << 1)
+#define	 UART_DM_CR_TX_ENABLE			(1 << 2)
+#define	 UART_DM_CR_TX_DISABLE			(1 << 3)
+
+/* UART_DM_CR channel command bit value (register field is bits 8:4) */
+#define	UART_DM_RESET_RX			0x10
+#define	UART_DM_RESET_TX			0x20
+#define	UART_DM_RESET_ERROR_STATUS		0x30
+#define	UART_DM_RESET_BREAK_INT			0x40
+#define	UART_DM_START_BREAK			0x50
+#define	UART_DM_STOP_BREAK			0x60
+#define	UART_DM_RESET_CTS			0x70
+#define	UART_DM_RESET_STALE_INT			0x80
+#define	UART_DM_RFR_LOW				0xD0
+#define	UART_DM_RFR_HIGH			0xE0
+#define	UART_DM_CR_PROTECTION_EN		0x100
+#define	UART_DM_STALE_EVENT_ENABLE		0x500
+#define	UART_DM_STALE_EVENT_DISABLE		0x600
+#define	UART_DM_FORCE_STALE_EVENT		0x400
+#define	UART_DM_CLEAR_TX_READY			0x300
+#define	UART_DM_RESET_TX_ERROR			0x800
+#define	UART_DM_RESET_TX_DONE			0x810
+
+/* UART Interrupt Mask Register */
+#define	UART_DM_IMR				0x14
+/* these can be used for both ISR and IMR registers */
+#define	UART_DM_TXLEV				(1 << 0)
+#define	UART_DM_RXHUNT				(1 << 1)
+#define	UART_DM_RXBRK_CHNG			(1 << 2)
+#define	UART_DM_RXSTALE				(1 << 3)
+#define	UART_DM_RXLEV				(1 << 4)
+#define	UART_DM_DELTA_CTS			(1 << 5)
+#define	UART_DM_CURRENT_CTS			(1 << 6)
+#define	UART_DM_TX_READY			(1 << 7)
+#define	UART_DM_TX_ERROR			(1 << 8)
+#define	UART_DM_TX_DONE				(1 << 9)
+#define	UART_DM_RXBREAK_START			(1 << 10)
+#define	UART_DM_RXBREAK_END			(1 << 11)
+#define	UART_DM_PAR_FRAME_ERR_IRQ		(1 << 12)
+
+#define	UART_DM_IMR_ENABLED			(UART_DM_TX_READY | \
+						UART_DM_TXLEV | \
+						UART_DM_RXLEV | \
+						UART_DM_RXSTALE)
+
+/* UART Interrupt Programming Register */
+#define	UART_DM_IPR				0x18
+#define	UART_DM_STALE_TIMEOUT_LSB		0x0f
+#define	UART_DM_STALE_TIMEOUT_MSB		0x00
+#define	UART_DM_IPR_STALE_TIMEOUT_MSB_BMSK	0xffffff80
+#define	UART_DM_IPR_STALE_LSB_BMSK		0x1f
+
+/* UART Transmit/Receive FIFO Watermark Register */
+#define	UART_DM_TFWR				0x1c
+/* Interrupt is generated when FIFO level is less than or equal to this value */
+#define	UART_DM_TFW_VALUE			0
+
+#define	UART_DM_RFWR				0x20
+/* Interrupt generated when no of words in RX FIFO is greater than this value */
+#define	UART_DM_RFW_VALUE			0
+
+/* UART Hunt Character Register */
+#define	UART_DM_HCR				0x24
+
+/* Used for RX transfer initialization */
+#define	UART_DM_DMRX				0x34
+/* Default DMRX value - any value bigger than FIFO size would be fine */
+#define	UART_DM_DMRX_DEF_VALUE			0x220
+
+/* Register to enable IRDA function */
+#define	UART_DM_IRDA				0x38
+
+/* UART Data Mover Enable Register */
+#define	UART_DM_DMEN				0x3c
+
+/* Number of characters for Transmission */
+#define	UART_DM_NO_CHARS_FOR_TX			0x40
+
+/* UART RX FIFO Base Address */
+#define	UART_DM_BADR				0x44
+
+#define	UART_DM_SIM_CFG_ADDR			0x80
+
+/* Read only registers */
+/* UART Status Register */
+#define	UART_DM_SR				0x08
+/* register field mask mapping */
+#define	 UART_DM_SR_RXRDY			(1 << 0)
+#define	 UART_DM_SR_RXFULL			(1 << 1)
+#define	 UART_DM_SR_TXRDY			(1 << 2)
+#define	 UART_DM_SR_TXEMT			(1 << 3)
+#define	 UART_DM_SR_UART_OVERRUN		(1 << 4)
+#define	 UART_DM_SR_PAR_FRAME_ERR		(1 << 5)
+#define	 UART_DM_RX_BREAK			(1 << 6)
+#define	 UART_DM_HUNT_CHAR			(1 << 7)
+#define	 UART_DM_RX_BRK_START_LAST		(1 << 8)
+
+/* UART Receive FIFO Registers - 4 in numbers */
+#define	UART_DM_RF(x)				(0x70 + (4 * (x)))
+
+/* UART Masked Interrupt Status Register */
+#define	UART_DM_MISR				0x10
+
+/* UART Interrupt Status Register */
+#define	UART_DM_ISR				0x14
+
+/* Number of characters received since the end of last RX transfer */
+#define	UART_DM_RX_TOTAL_SNAP			0x38
+
+/* UART TX FIFO Status Register */
+#define	UART_DM_TXFS				0x4c
+#define	 UART_DM_TXFS_STATE_LSB(x)		UART_DM_EXTR_BITS(x,0,6)
+#define	 UART_DM_TXFS_STATE_MSB(x)		UART_DM_EXTR_BITS(x,14,31)
+#define	 UART_DM_TXFS_BUF_STATE(x)		UART_DM_EXTR_BITS(x,7,9)
+#define	 UART_DM_TXFS_ASYNC_STATE(x)		UART_DM_EXTR_BITS(x,10,13)
+
+/* UART RX FIFO Status Register */
+#define	UART_DM_RXFS				0x50
+#define	 UART_DM_RXFS_STATE_LSB(x)		UART_DM_EXTR_BITS(x,0,6)
+#define	 UART_DM_RXFS_STATE_MSB(x)		UART_DM_EXTR_BITS(x,14,31)
+#define	 UART_DM_RXFS_BUF_STATE(x)		UART_DM_EXTR_BITS(x,7,9)
+#define	 UART_DM_RXFS_ASYNC_STATE(x)		UART_DM_EXTR_BITS(x,10,13)
+
+#endif	/* _UART_DM_H_ */


More information about the svn-src-all mailing list