Skip to content

Commit

Permalink
serial: 8250/ingenic: Add support for the JZ4750/JZ4755
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Siarhei Volkau authored and Greg Kroah-Hartman committed Nov 3, 2022
1 parent 0c3c184 commit e9c29d8
Showing 1 changed file with 29 additions and 3 deletions.
32 changes: 29 additions & 3 deletions drivers/tty/serial/8250/8250_ingenic.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -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);

Expand Down Expand Up @@ -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 },
Expand Down

0 comments on commit e9c29d8

Please sign in to comment.