From: "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>
To: linux-serial@vger.kernel.org, Jiri Slaby <jirislaby@kernel.org>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: linux-kernel@vger.kernel.org, "Lukas Wunner" <lukas@wunner.de>,
"Johan Hovold" <johan@kernel.org>,
"Andy Shevchenko" <andriy.shevchenko@linux.intel.com>,
"Heikki Krogerus" <heikki.krogerus@linux.intel.com>,
"Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>,
"Raymond Tan" <raymond.tan@intel.com>
Subject: [PATCH 1/7] serial: 8250_dwlib: RS485 HW half duplex support
Date: Wed, 2 Mar 2022 11:56:00 +0200 [thread overview]
Message-ID: <20220302095606.14818-2-ilpo.jarvinen@linux.intel.com> (raw)
In-Reply-To: <20220302095606.14818-1-ilpo.jarvinen@linux.intel.com>
The Synopsys DesignWare UART has a build-in support for the
RS485 protocol from IP version 4.0 onward. This commit
enables basic hardware-controlled half duplex mode support
for it.
HW will take care of managing DE and RE, the driver just gives
it permission to use either by setting both to 1.
Co-developed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Co-developed-by: Raymond Tan <raymond.tan@intel.com>
Signed-off-by: Raymond Tan <raymond.tan@intel.com>
Co-developed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
---
drivers/tty/serial/8250/8250_dwlib.c | 67 +++++++++++++++++++++++++++-
drivers/tty/serial/8250/8250_dwlib.h | 3 ++
2 files changed, 68 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/serial/8250/8250_dwlib.c b/drivers/tty/serial/8250/8250_dwlib.c
index 622d3b0d89e7..a4f09a95049b 100644
--- a/drivers/tty/serial/8250/8250_dwlib.c
+++ b/drivers/tty/serial/8250/8250_dwlib.c
@@ -2,19 +2,33 @@
/* Synopsys DesignWare 8250 library. */
#include <linux/bitops.h>
+#include <linux/bitfield.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/kernel.h>
+#include <linux/property.h>
#include <linux/serial_8250.h>
#include <linux/serial_core.h>
#include "8250_dwlib.h"
/* Offsets for the DesignWare specific registers */
+#define DW_UART_TCR 0xac /* Transceiver Control Register (RS485) */
+#define DW_UART_DE_EN 0xb0 /* Driver Output Enable Register */
+#define DW_UART_RE_EN 0xb4 /* Receiver Output Enable Register */
#define DW_UART_DLF 0xc0 /* Divisor Latch Fraction Register */
#define DW_UART_CPR 0xf4 /* Component Parameter Register */
#define DW_UART_UCV 0xf8 /* UART Component Version */
+/* Transceiver Control Register bits */
+#define DW_UART_TCR_RS485_EN BIT(0)
+#define DW_UART_TCR_RE_POL BIT(1)
+#define DW_UART_TCR_DE_POL BIT(2)
+#define DW_UART_TCR_XFER_MODE GENMASK(4, 3)
+#define DW_UART_TCR_XFER_MODE_DE_DURING_RE FIELD_PREP(DW_UART_TCR_XFER_MODE, 0)
+#define DW_UART_TCR_XFER_MODE_SW_DE_OR_RE FIELD_PREP(DW_UART_TCR_XFER_MODE, 1)
+#define DW_UART_TCR_XFER_MODE_DE_OR_RE FIELD_PREP(DW_UART_TCR_XFER_MODE, 2)
+
/* Component Parameter Register bits */
#define DW_UART_CPR_ABP_DATA_WIDTH (3 << 0)
#define DW_UART_CPR_AFCE_MODE (1 << 4)
@@ -87,11 +101,62 @@ void dw8250_do_set_termios(struct uart_port *p, struct ktermios *termios, struct
}
EXPORT_SYMBOL_GPL(dw8250_do_set_termios);
+static int dw8250_rs485_config(struct uart_port *p, struct serial_rs485 *rs485)
+{
+ u32 tcr;
+
+ tcr = dw8250_readl_ext(p, DW_UART_TCR);
+ tcr &= ~DW_UART_TCR_XFER_MODE;
+
+ if (rs485->flags & SER_RS485_ENABLED) {
+ /* Clearing unsupported flags. */
+ rs485->flags &= SER_RS485_ENABLED;
+
+ tcr |= DW_UART_TCR_RS485_EN | DW_UART_TCR_XFER_MODE_DE_OR_RE;
+ dw8250_writel_ext(p, DW_UART_DE_EN, 1);
+ dw8250_writel_ext(p, DW_UART_RE_EN, 1);
+ } else {
+ rs485->flags = 0;
+
+ tcr &= ~DW_UART_TCR_RS485_EN;
+ dw8250_writel_ext(p, DW_UART_DE_EN, 0);
+ dw8250_writel_ext(p, DW_UART_RE_EN, 0);
+ }
+
+ /* Resetting the default DE_POL & RE_POL */
+ tcr &= ~(DW_UART_TCR_DE_POL | DW_UART_TCR_RE_POL);
+
+ if (device_property_read_bool(p->dev, "snps,de-active-high"))
+ tcr |= DW_UART_TCR_DE_POL;
+ if (device_property_read_bool(p->dev, "snps,re-active-high"))
+ tcr |= DW_UART_TCR_RE_POL;
+
+ dw8250_writel_ext(p, DW_UART_TCR, tcr);
+
+ /*
+ * XXX: Though we could interpret the "RTS" timings as Driver Enable
+ * (DE) assertion/de-assertion timings, initially not supporting that.
+ * Ideally we should have timing values for the Driver instead of the
+ * RTS signal.
+ */
+ rs485->delay_rts_before_send = 0;
+ rs485->delay_rts_after_send = 0;
+
+ p->rs485 = *rs485;
+
+ return 0;
+}
+
void dw8250_setup_port(struct uart_port *p)
{
+ struct dw8250_port_data *d = p->private_data;
struct uart_8250_port *up = up_to_u8250p(p);
u32 reg;
+ d->hw_rs485_support = device_property_read_bool(p->dev, "snps,rs485-interface-en");
+ if (d->hw_rs485_support)
+ p->rs485_config = dw8250_rs485_config;
+
/*
* If the Component Version Register returns zero, we know that
* ADDITIONAL_FEATURES are not enabled. No need to go any further.
@@ -108,8 +173,6 @@ void dw8250_setup_port(struct uart_port *p)
dw8250_writel_ext(p, DW_UART_DLF, 0);
if (reg) {
- struct dw8250_port_data *d = p->private_data;
-
d->dlf_size = fls(reg);
p->get_divisor = dw8250_get_divisor;
p->set_divisor = dw8250_set_divisor;
diff --git a/drivers/tty/serial/8250/8250_dwlib.h b/drivers/tty/serial/8250/8250_dwlib.h
index 83d528e5cc21..a8fa020ca544 100644
--- a/drivers/tty/serial/8250/8250_dwlib.h
+++ b/drivers/tty/serial/8250/8250_dwlib.h
@@ -14,6 +14,9 @@ struct dw8250_port_data {
/* Hardware configuration */
u8 dlf_size;
+
+ /* RS485 variables */
+ bool hw_rs485_support;
};
void dw8250_do_set_termios(struct uart_port *p, struct ktermios *termios, struct ktermios *old);
--
2.30.2
next prev parent reply other threads:[~2022-03-02 9:57 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-02 9:55 [PATCH 0/7] Add RS485 support to DW UART Ilpo Järvinen
2022-03-02 9:56 ` Ilpo Järvinen [this message]
2022-03-06 18:48 ` [PATCH 1/7] serial: 8250_dwlib: RS485 HW half duplex support Lukas Wunner
2022-03-06 22:07 ` Andy Shevchenko
2022-03-07 9:19 ` Ilpo Järvinen
2022-03-07 19:18 ` Lukas Wunner
2022-03-07 19:39 ` Andy Shevchenko
2022-03-08 12:16 ` Ilpo Järvinen
2022-03-08 12:22 ` Lukas Wunner
2022-03-08 12:59 ` Ilpo Järvinen
2022-03-08 14:50 ` Lukas Wunner
2022-03-08 14:53 ` Andy Shevchenko
2022-03-08 20:30 ` Lukas Wunner
2022-03-09 9:51 ` Ilpo Järvinen
2022-03-07 10:54 ` Ilpo Järvinen
2022-03-09 8:52 ` Lukas Wunner
2022-03-09 12:19 ` Ilpo Järvinen
2022-03-09 12:59 ` Lukas Wunner
2022-03-02 9:56 ` [PATCH 2/7] serial: 8250_dwlib: RS485 HW full " Ilpo Järvinen
2022-03-06 18:51 ` Lukas Wunner
2022-03-07 9:22 ` Ilpo Järvinen
2022-03-02 9:56 ` [RFC PATCH 3/7] serial: 8250_dwlib: Implement SW half " Ilpo Järvinen
2022-03-06 19:21 ` Lukas Wunner
2022-03-06 22:13 ` Andy Shevchenko
2022-03-02 9:56 ` [PATCH 4/7] dt_bindings: snps-dw-apb-uart: Add RS485 Ilpo Järvinen
2022-03-02 17:47 ` Rob Herring
2022-03-02 9:56 ` [RFC PATCH 5/7] serial: termbits: ADDRB to indicate 9th bit addressing mode Ilpo Järvinen
2022-03-02 9:56 ` [RFC PATCH 6/7] serial: General support for multipoint addresses Ilpo Järvinen
2022-03-06 19:40 ` Lukas Wunner
2022-03-07 9:48 ` Ilpo Järvinen
2022-03-09 19:05 ` Lukas Wunner
2022-03-10 12:29 ` Ilpo Järvinen
2022-03-10 14:09 ` Andy Shevchenko
2022-03-02 9:56 ` [RFC PATCH 7/7] serial: 8250_dwlib: Support for 9th bit multipoint addressing Ilpo Järvinen
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=20220302095606.14818-2-ilpo.jarvinen@linux.intel.com \
--to=ilpo.jarvinen@linux.intel.com \
--cc=andriy.shevchenko@linux.intel.com \
--cc=gregkh@linuxfoundation.org \
--cc=heikki.krogerus@linux.intel.com \
--cc=jirislaby@kernel.org \
--cc=johan@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-serial@vger.kernel.org \
--cc=lukas@wunner.de \
--cc=raymond.tan@intel.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).