summaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorSiarhei Volkau <lis8215@gmail.com>2022-10-31 19:40:40 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-11-03 03:43:05 +0100
commite9c29d80278c0f5c6198ac741b10a534672042ca (patch)
tree4556667673d6a21c17a48961c9bc86e725a0d771 /drivers/tty
parentdt-bindings: serial: ingenic: Add support for the JZ4750/55 SoCs (diff)
downloadlinux-e9c29d80278c0f5c6198ac741b10a534672042ca.tar.xz
linux-e9c29d80278c0f5c6198ac741b10a534672042ca.zip
serial: 8250/ingenic: Add support for the JZ4750/JZ4755
JZ4750/55/60 (but not JZ4760b) have an optional /2 divider between the EXT oscillator and some peripherals including UART, which will be enabled if using a 24 MHz oscillator, and disabled when using a 12 MHz oscillator. This behavior relies on hardware differences: most boards (if not all) with those SoCs have 12 or 24 MHz oscillators but many peripherals want 12Mhz to operate properly (AIC and USB-PHY at least). The 16MHz threshold looks arbitrary but used in vendor's bootloader code for enable the divider. The patch doesn't affect JZ4760's behavior as it is subject for another patchset with re-classification of all supported ingenic UARTs. Link: https://github.com/carlos-wong/uboot_jz4755/blob/master/cpu/mips/jz_serial.c#L158 Signed-off-by: Siarhei Volkau <lis8215@gmail.com> Link: https://lore.kernel.org/r/20221031184041.1338129-3-lis8215@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/8250/8250_ingenic.c32
1 files changed, 29 insertions, 3 deletions
diff --git a/drivers/tty/serial/8250/8250_ingenic.c b/drivers/tty/serial/8250/8250_ingenic.c
index 2b2f5d8d24b9..617b8ce60d6b 100644
--- a/drivers/tty/serial/8250/8250_ingenic.c
+++ b/drivers/tty/serial/8250/8250_ingenic.c
@@ -87,7 +87,7 @@ static void __init ingenic_early_console_setup_clock(struct earlycon_device *dev
dev->port.uartclk = be32_to_cpup(prop);
}
-static int __init ingenic_early_console_setup(struct earlycon_device *dev,
+static int __init ingenic_earlycon_setup_tail(struct earlycon_device *dev,
const char *opt)
{
struct uart_port *port = &dev->port;
@@ -103,8 +103,6 @@ static int __init ingenic_early_console_setup(struct earlycon_device *dev,
uart_parse_options(opt, &baud, &parity, &bits, &flow);
}
- ingenic_early_console_setup_clock(dev);
-
if (dev->baud)
baud = dev->baud;
divisor = DIV_ROUND_CLOSEST(port->uartclk, 16 * baud);
@@ -129,9 +127,36 @@ static int __init ingenic_early_console_setup(struct earlycon_device *dev,
return 0;
}
+static int __init ingenic_early_console_setup(struct earlycon_device *dev,
+ const char *opt)
+{
+ ingenic_early_console_setup_clock(dev);
+
+ return ingenic_earlycon_setup_tail(dev, opt);
+}
+
+static int __init jz4750_early_console_setup(struct earlycon_device *dev,
+ const char *opt)
+{
+ /*
+ * JZ4750/55/60 have an optional /2 divider between the EXT
+ * oscillator and some peripherals including UART, which will
+ * be enabled if using a 24 MHz oscillator, and disabled when
+ * using a 12 MHz oscillator.
+ */
+ ingenic_early_console_setup_clock(dev);
+ if (dev->port.uartclk >= 16000000)
+ dev->port.uartclk /= 2;
+
+ return ingenic_earlycon_setup_tail(dev, opt);
+}
+
OF_EARLYCON_DECLARE(jz4740_uart, "ingenic,jz4740-uart",
ingenic_early_console_setup);
+OF_EARLYCON_DECLARE(jz4750_uart, "ingenic,jz4750-uart",
+ jz4750_early_console_setup);
+
OF_EARLYCON_DECLARE(jz4770_uart, "ingenic,jz4770-uart",
ingenic_early_console_setup);
@@ -328,6 +353,7 @@ static const struct ingenic_uart_config x1000_uart_config = {
static const struct of_device_id of_match[] = {
{ .compatible = "ingenic,jz4740-uart", .data = &jz4740_uart_config },
+ { .compatible = "ingenic,jz4750-uart", .data = &jz4760_uart_config },
{ .compatible = "ingenic,jz4760-uart", .data = &jz4760_uart_config },
{ .compatible = "ingenic,jz4770-uart", .data = &jz4760_uart_config },
{ .compatible = "ingenic,jz4775-uart", .data = &jz4760_uart_config },