2022-10-31 18:52:29

by Siarhei Volkau

[permalink] [raw]
Subject: [PATCH v4 0/2] serial: 8250/ingenic: Add support for the JZ4750

JZ4750 and JZ4755 have an extra clock divisor in CGU called CPCCR.ECS.
It needs to be handled properly in the early console driver.

v4:
- move duplicate code
- apply Paul's description for the quirk & commit msg
v3:
- fix build errors
v2:
- serial moved into separate patchset
- code refactored to avoid peek in CGU register
- Krzysztof's ack picked
v1:
- big patchset for the whole JZ4755 support

Siarhei Volkau (2):
dt-bindings: serial: ingenic: Add support for the JZ4750/55 SoCs
serial: 8250/ingenic: Add support for the JZ4750/JZ4755

.../bindings/serial/ingenic,uart.yaml | 4 +++
drivers/tty/serial/8250/8250_ingenic.c | 32 +++++++++++++++++--
2 files changed, 33 insertions(+), 3 deletions(-)

--
2.36.1



2022-10-31 19:03:55

by Siarhei Volkau

[permalink] [raw]
Subject: [PATCH v4 2/2] 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 <[email protected]>
---
drivers/tty/serial/8250/8250_ingenic.c | 32 +++++++++++++++++++++++---
1 file changed, 29 insertions(+), 3 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_ingenic.c b/drivers/tty/serial/8250/8250_ingenic.c
index 2b2f5d8d2..617b8ce60 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 },
--
2.36.1


2022-10-31 19:27:47

by Siarhei Volkau

[permalink] [raw]
Subject: [PATCH v4 1/2] dt-bindings: serial: ingenic: Add support for the JZ4750/55 SoCs

These SoCs UART block are the same as JZ4725b' one, the difference is
outside of the block - it is in the clock generation unit (CGU).
The difference requires to make a quirk for early console init.

Acked-by: Krzysztof Kozlowski <[email protected]>
Signed-off-by: Siarhei Volkau <[email protected]>
---
Documentation/devicetree/bindings/serial/ingenic,uart.yaml | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/serial/ingenic,uart.yaml b/Documentation/devicetree/bindings/serial/ingenic,uart.yaml
index 9ca7a18ec..315ceb722 100644
--- a/Documentation/devicetree/bindings/serial/ingenic,uart.yaml
+++ b/Documentation/devicetree/bindings/serial/ingenic,uart.yaml
@@ -20,6 +20,7 @@ properties:
oneOf:
- enum:
- ingenic,jz4740-uart
+ - ingenic,jz4750-uart
- ingenic,jz4760-uart
- ingenic,jz4780-uart
- ingenic,x1000-uart
@@ -31,6 +32,9 @@ properties:
- items:
- const: ingenic,jz4725b-uart
- const: ingenic,jz4740-uart
+ - items:
+ - const: ingenic,jz4755-uart
+ - const: ingenic,jz4750-uart

reg:
maxItems: 1
--
2.36.1