All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Eddy Petrișor" <eddy.petrisor@gmail.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v3 1/2] serial: Introduce linflex uart support
Date: Sat, 28 May 2016 12:56:14 +0300	[thread overview]
Message-ID: <1464429375-6191-2-git-send-email-eddy.petrisor@gmail.com> (raw)
In-Reply-To: <1464429375-6191-1-git-send-email-eddy.petrisor@gmail.com>

From: Stoica Cosmin-Stefan <cosminstefan.stoica@freescale.com>

The Linflex module is integrated on some NXP automotive SoCs part of the former
Freescale portfolio, like S32V234, an SoC for Advanced Driver Assistance
Systems.

Original-signed-off-by: Stoica Cosmin-Stefan <cosminstefan.stoica@freescale.com>
Original-signed-off-by: Chircu Bogdan <Bogdan.Chircu@freescale.com>
Original-signed-off-by: Depons Eric <eric.depons@freescale.com>
Original-signed-off-by: Eddy Petri?or <eddy.petrisor@gmail.com>

Signed-off-by: Eddy Petri?or <eddy.petrisor@gmail.com>
---

Notes:
    Changes in v2:
    Added support for device model. Compatibility with non-DM code is kept
    for easier synchronization with the code on the vendor branch where the
    conversion to DM is not done for all boards.
    
    Changes in v3:
    Removed non-DM compatibility, as requested.

 drivers/serial/Makefile             |   1 +
 drivers/serial/serial_linflexuart.c | 221 ++++++++++++++++++++++++++++++++++++
 2 files changed, 222 insertions(+)
 create mode 100644 drivers/serial/serial_linflexuart.c

diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 9def128..c45cf5d 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_SCIF_CONSOLE) += serial_sh.o
 obj-$(CONFIG_ZYNQ_SERIAL) += serial_zynq.o
 obj-$(CONFIG_BFIN_SERIAL) += serial_bfin.o
 obj-$(CONFIG_FSL_LPUART) += serial_lpuart.o
+obj-$(CONFIG_FSL_LINFLEXUART) += serial_linflexuart.o
 obj-$(CONFIG_ARC_SERIAL) += serial_arc.o
 obj-$(CONFIG_UNIPHIER_SERIAL) += serial_uniphier.o
 obj-$(CONFIG_STM32_SERIAL) += serial_stm32.o
diff --git a/drivers/serial/serial_linflexuart.c b/drivers/serial/serial_linflexuart.c
new file mode 100644
index 0000000..771d0bd
--- /dev/null
+++ b/drivers/serial/serial_linflexuart.c
@@ -0,0 +1,221 @@
+/*
+ * (C) Copyright 2013-2016 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <watchdog.h>
+#include <asm/io.h>
+#include <serial.h>
+#include <linux/compiler.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/clock.h>
+
+#define US1_TDRE            (1 << 7)
+#define US1_RDRF            (1 << 5)
+#define UC2_TE              (1 << 3)
+#define LINCR1_INIT         (1 << 0)
+#define LINCR1_MME          (1 << 4)
+#define LINCR1_BF           (1 << 7)
+#define LINSR_LINS_INITMODE (0x00001000)
+#define LINSR_LINS_MASK     (0x0000F000)
+#define UARTCR_UART         (1 << 0)
+#define UARTCR_WL0          (1 << 1)
+#define UARTCR_PCE          (1 << 2)
+#define UARTCR_PC0          (1 << 3)
+#define UARTCR_TXEN         (1 << 4)
+#define UARTCR_RXEN         (1 << 5)
+#define UARTCR_PC1          (1 << 6)
+#define UARTSR_DTF          (1 << 1)
+#define UARTSR_DRF          (1 << 2)
+#define UARTSR_RMB          (1 << 9)
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifndef CONFIG_DM_SERIAL
+#error "The linflex serial driver does not have non-DM support."
+#endif
+
+static void _linflex_serial_setbrg(struct linflex_fsl *base, int baudrate)
+{
+	u32 clk = mxc_get_clock(MXC_UART_CLK);
+	u32 ibr, fbr;
+
+	if (!baudrate)
+		baudrate = CONFIG_BAUDRATE;
+
+	ibr = (u32) (clk / (16 * gd->baudrate));
+	fbr = (u32) (clk % (16 * gd->baudrate)) * 16;
+
+	__raw_writel(ibr, &base->linibrr);
+	__raw_writel(fbr, &base->linfbrr);
+}
+
+static int _linflex_serial_getc(struct linflex_fsl *base)
+{
+	char c;
+
+	if (!(__raw_readb(&base->uartsr) & UARTSR_DRF))
+		return -EAGAIN;
+
+	if (!(__raw_readl(&base->uartsr) & UARTSR_RMB))
+		return -EAGAIN;
+
+	c = __raw_readl(&base->bdrm);
+	__raw_writeb((__raw_readb(&base->uartsr) | (UARTSR_DRF | UARTSR_RMB)),
+		     &base->uartsr);
+	return c;
+}
+
+static int _linflex_serial_putc(struct linflex_fsl *base, const char c)
+{
+	__raw_writeb(c, &base->bdrl);
+
+
+	if (!(__raw_readb(&base->uartsr) & UARTSR_DTF))
+		return -EAGAIN;
+
+	__raw_writeb((__raw_readb(&base->uartsr) | UARTSR_DTF), &base->uartsr);
+
+	return 0;
+}
+
+/*
+ * Initialise the serial port with the given baudrate. The settings
+ * are always 8 data bits, no parity, 1 stop bit, no start bits.
+ */
+static int _linflex_serial_init(struct linflex_fsl *base)
+{
+	volatile u32 ctrl;
+
+	/* set the Linflex in master mode amd activate by-pass filter */
+	ctrl = LINCR1_BF | LINCR1_MME;
+	__raw_writel(ctrl, &base->lincr1);
+
+	/* init mode */
+	ctrl |= LINCR1_INIT;
+	__raw_writel(ctrl, &base->lincr1);
+
+	/* waiting for init mode entry - TODO: add a timeout */
+	while ((__raw_readl(&base->linsr) & LINSR_LINS_MASK) !=
+	       LINSR_LINS_INITMODE);
+
+	/* set UART bit to allow writing other bits */
+	__raw_writel(UARTCR_UART, &base->uartcr);
+
+	/* provide data bits, parity, stop bit, etc */
+	serial_setbrg();
+
+	/* 8 bit data, no parity, Tx and Rx enabled, UART mode */
+	__raw_writel(UARTCR_PC1 | UARTCR_RXEN | UARTCR_TXEN | UARTCR_PC0
+		     | UARTCR_WL0 | UARTCR_UART, &base->uartcr);
+
+	ctrl = __raw_readl(&base->lincr1);
+	ctrl &= ~LINCR1_INIT;
+	__raw_writel(ctrl, &base->lincr1);	/* end init mode */
+
+	return 0;
+}
+
+struct linflex_serial_platdata {
+	struct linflex_fsl *base_addr;
+	u8 port_id; /* do we need this? */
+};
+
+struct linflex_serial_priv {
+	struct linflex_fsl *lfuart;
+};
+
+int linflex_serial_setbrg(struct udevice *dev, int baudrate)
+{
+	struct linflex_serial_priv *priv = dev_get_priv(dev);
+
+	_linflex_serial_setbrg(priv->lfuart, baudrate);
+
+	return 0;
+}
+
+static int linflex_serial_getc(struct udevice *dev)
+{
+	struct linflex_serial_priv *priv = dev_get_priv(dev);
+
+	return _linflex_serial_getc(priv->lfuart);
+}
+
+static int linflex_serial_putc(struct udevice *dev, const char ch)
+{
+
+	struct linflex_serial_priv *priv = dev_get_priv(dev);
+
+	return _linflex_serial_putc(priv->lfuart, ch);
+}
+
+static int linflex_serial_pending(struct udevice *dev, bool input)
+{
+	struct linflex_serial_priv *priv = dev_get_priv(dev);
+	uint32_t uartsr = __raw_readl(&priv->lfuart->uartsr);
+
+	if (input)
+		return ((uartsr & UARTSR_DRF) && (uartsr & UARTSR_RMB)) ? 1 : 0;
+	else
+		return uartsr & UARTSR_DTF ? 0 : 1;
+}
+
+static void linflex_serial_init_internal(struct linflex_fsl *lfuart)
+{
+	_linflex_serial_init(lfuart);
+	_linflex_serial_setbrg(lfuart, CONFIG_BAUDRATE);
+	return;
+}
+
+static int linflex_serial_probe(struct udevice *dev)
+{
+	struct linflex_serial_platdata *plat = dev->platdata;
+	struct linflex_serial_priv *priv = dev_get_priv(dev);
+
+	priv->lfuart = (struct linflex_fsl *)plat->base_addr;
+	linflex_serial_init_internal(priv->lfuart);
+
+	return 0;
+}
+
+static const struct dm_serial_ops linflex_serial_ops = {
+	.putc = linflex_serial_putc,
+	.pending = linflex_serial_pending,
+	.getc = linflex_serial_getc,
+	.setbrg = linflex_serial_setbrg,
+};
+
+U_BOOT_DRIVER(serial_linflex) = {
+	.name	= "serial_linflex",
+	.id	= UCLASS_SERIAL,
+	.probe = linflex_serial_probe,
+	.ops	= &linflex_serial_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+	.priv_auto_alloc_size	= sizeof(struct linflex_serial_priv),
+};
+
+#ifdef CONFIG_DEBUG_UART_LINFLEXUART
+
+#include <debug_uart.h>
+
+
+static inline void _debUG_uart_init(void)
+{
+	struct linflex_fsl *base = (struct linflex_fsl *)CONFIG_DEBUG_UART_BASE;
+
+	linflex_serial_init_internal(base);
+}
+
+static inline void _debug_uart_putc(int ch)
+{
+	struct linflex_fsl *base = (struct linflex_fsl *)CONFIG_DEBUG_UART_BASE;
+
+	/* XXX: Is this OK? Should this use the non-DM version? */
+	_linflex_serial_putc(base, ch);
+}
+
+#endif /* CONFIG_DEBUG_UART_LINFLEXUART */
-- 
2.5.0

  reply	other threads:[~2016-05-28  9:56 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-04-03  0:10 [U-Boot] [PATCH 1/2] serial: Introduce linflex uart support Eddy Petrișor
2016-04-03  0:10 ` [U-Boot] [PATCH 2/2] armv8: s32v234: Introduce basic support for s32v234evb Eddy Petrișor
2016-04-19 16:53   ` Tom Rini
2016-04-21 16:03     ` Eddy Petrișor
2016-04-21 16:28       ` Tom Rini
2016-04-04  3:22 ` [U-Boot] [PATCH 1/2] serial: Introduce linflex uart support Bin Meng
2016-04-04 14:22   ` Eddy Petrișor
2016-04-05  1:43     ` Bin Meng
2016-04-27 22:07       ` [U-Boot] [PATCH v2 " Eddy Petrișor
2016-05-07 14:56         ` Bin Meng
2016-05-08  0:05           ` Eddy Petrișor
2016-04-27 21:39 ` [U-Boot] [PATCH 0/2] Initial support for S32V234 - version 2 Eddy Petrișor
2016-04-27 21:39 ` [U-Boot] [PATCH 1/2] serial: Introduce linflex uart support Eddy Petrișor
2016-04-27 21:39 ` [U-Boot] [PATCH 2/2] armv8: s32v234: Introduce basic support for s32v234evb Eddy Petrișor
2016-04-27 22:07 ` [U-Boot] [PATCH v2 0/2] Initial S32V234 support - version 2 (with notes now) Eddy Petrișor
2016-05-28  9:56   ` [U-Boot] [PATCH v3 0/2] Initial support for S32V234 - version 3 Eddy Petrișor
2016-05-28  9:56     ` Eddy Petrișor [this message]
2016-05-28  9:56     ` [U-Boot] [PATCH v3 2/2] armv8: s32v234: Introduce basic support for s32v234evb Eddy Petrișor
2016-05-28 10:10       ` Alexander Graf
2016-05-28 10:51     ` [U-Boot] [PATCH v4 0/2] Initial support for s32v234 Eddy Petrișor
2016-05-28 10:51       ` [U-Boot] [PATCH v4 1/2] serial: Introduce linflex uart support Eddy Petrișor
2016-05-28 10:51       ` [U-Boot] [PATCH v4 2/2] armv8: s32v234: Introduce basic support for s32v234evb Eddy Petrișor
2016-06-04 19:18     ` [U-Boot] [PATCH v5 0/2] Initial support for s32v234 Eddy Petrișor
2016-06-04 19:18       ` [U-Boot] [PATCH v5 1/2] serial: Introduce linflex uart support Eddy Petrișor
2016-06-04 19:18       ` [U-Boot] [PATCH v5 2/2] armv8: s32v234: Introduce basic support for s32v234evb Eddy Petrișor
2016-06-04 22:23       ` [U-Boot] [PATCH v5 0/2] Initial support for s32v234 Fabio Estevam
2016-06-04 23:59         ` Eddy Petrișor
2016-06-05  0:52           ` Fabio Estevam
2016-06-05  1:15             ` Eddy Petrișor
2016-06-05  0:42       ` [U-Boot] [PATCH v6 " Eddy Petrișor
2016-06-05  0:42         ` [U-Boot] [PATCH v6 1/2] serial: Introduce linflex uart support Eddy Petrișor
2016-06-19 14:10           ` [U-Boot] [U-Boot, v6, " Tom Rini
2016-06-19 20:41             ` Eddy Petrișor
2016-06-05  0:43         ` [U-Boot] [PATCH v6 2/2] armv8: s32v234: Introduce basic support for s32v234evb Eddy Petrișor
2016-06-19 14:10           ` [U-Boot] [U-Boot, v6, " Tom Rini
2016-06-19 20:51             ` Eddy Petrișor
2016-04-27 22:07 ` [U-Boot] [PATCH v2 " Eddy Petrișor
2016-05-07 16:22   ` Alexander Graf
2016-05-07 23:59     ` Eddy Petrișor
2016-05-08  7:21       ` Alexander Graf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1464429375-6191-2-git-send-email-eddy.petrisor@gmail.com \
    --to=eddy.petrisor@gmail.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.