Message ID | 20221022165047.4020785-3-lis8215@gmail.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4242:0:0:0:0:0 with SMTP id s2csp1284655wrr; Sat, 22 Oct 2022 10:02:05 -0700 (PDT) X-Google-Smtp-Source: AMsMyM7nO5ArsavGYnxBibH+tqLbyvzd9XTtENegyv8eixDUUu6bMTObGDbkwK2nnCIHIPSJl8yj X-Received: by 2002:a17:90a:65c7:b0:20f:8385:cc18 with SMTP id i7-20020a17090a65c700b0020f8385cc18mr28830666pjs.235.1666458125430; Sat, 22 Oct 2022 10:02:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666458125; cv=none; d=google.com; s=arc-20160816; b=gg8Wwpn7A3Q/u3OwaUOl7cxUBVGZF24TABXD3bJbTIVJiwHVDGRXZvG0ArHRZmcDfi yM/6TBM6RFEdkQUKZQWp2qtaPQXgz9PoSINcPjK7okDt8tKpTJbsnCf26jTxZzf5MsBo Hqu30pjrh65b/1GaMlWsmiv+g1k+d2WXt+cxHAvKzcw7WEBEOXs0JJ7jDqNaJlsMaDFI pkv35mNvwDtWx6+3Uqrtw4WVO++GFKJcfSdo6bXgpFOx4bcM4wHbnlO3PUft0VX00mYE foRFdTQh79R35kFhe5c87voa1JBiC5oxXpOwd/Dp/vpQmWciQ7Iy3ie7oB8d80SFs4bE MO0w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:to:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:from :dkim-signature; bh=W9cJA/mlkjauolOlXzYfHnCzwud4m1S/AxeoQy1cW6k=; b=dIipBasrkvXPSyvDHsdAtqcfruvwGaLyXXJhtH2d11nVswPLi1T8R/3vItaIwSFVJ8 XK8dao711LMyzC8wvhJ3AW2ydBmY8FFvbT9Y8ErbdyxibcYLU5DGAFwtK76UM12qJlW4 155nmv29i8+m0W/Rh/9T/Ag6JK7QzQIFZNcGW9yCOSUzPIuUfC29nGzsOHwdKuVeRAca Lq7esqc8yxriKVLfb047ZOfMLGQs3oAd1QPBohzpz/3X22qqru5sM8fVie5nKYV2C1Jf jVre15b+xjFad4RlRbB7vi7G6FQKLVgmWO6QhbjkaMovDSLkMR8bJT1sT9hb6RnjXxFz m8ZA== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@gmail.com header.s=20210112 header.b=N4fQoqfC; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id s127-20020a632c85000000b004429ecbda9fsi28954389pgs.39.2022.10.22.10.01.40; Sat, 22 Oct 2022 10:02:05 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=fail header.i=@gmail.com header.s=20210112 header.b=N4fQoqfC; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229608AbiJVQvS (ORCPT <rfc822;pwkd43@gmail.com> + 99 others); Sat, 22 Oct 2022 12:51:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34250 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229908AbiJVQvE (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Sat, 22 Oct 2022 12:51:04 -0400 Received: from mail-wr1-x42f.google.com (mail-wr1-x42f.google.com [IPv6:2a00:1450:4864:20::42f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C8BF9196342; Sat, 22 Oct 2022 09:51:01 -0700 (PDT) Received: by mail-wr1-x42f.google.com with SMTP id l14so2366084wrw.2; Sat, 22 Oct 2022 09:51:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=W9cJA/mlkjauolOlXzYfHnCzwud4m1S/AxeoQy1cW6k=; b=N4fQoqfCmUImIBzGw5sWs02pmODNpEDlNS1IFSZHANlCiDPOF+lUr3And/jgxvsE3A cq3Qh4lqH1xZixBWKfJ9BavQMBbwVlNNmG2x8Fd2VmsuopFFELZHOc0PQ0Jh+UeLmiBV YSRfpPJQeTc9SVJCjhVSlKmtZ33LRvxdROpTeLKfYlzvHngM3T7kQAuU2ehzkdaIVDf5 k1Dv8CLcGaQS2oPcIl094tHGe+zdWh9a0UiWVe5Y59WWTXOQM7C7sOHCaxIJ056JdUW4 Vp7Cq1Uih10LtvkBXs3izaZeFryFf8qVfXmFPXBq+H1DB7GQ6FlBLy/nbYLgQxA2UHPY QSPQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=W9cJA/mlkjauolOlXzYfHnCzwud4m1S/AxeoQy1cW6k=; b=a+60Bln8rPu7UPWgiXsgrZvjPSVHWY/PF7xHclwTv76QGgtN0e0BWvKzkRoAUxz56z ZL3N8yUBzZPQUBf1sD+NbSEHlCK0AX2IRZYpWbeZzFrVYNZbV7rFfYC47ghJdnxJfOzc 7BIbQjcl2XvCjDv6A8psO6F7hPk4asXwCvesY2ZEJvUMtaS85b7yiR64ce8fVTUYvEXe +tPSMhSvEuds+f6GQarI1OW8LgGUZoA5UfzRyi4F17UQuf0+fHH1i2TexNWqA17QGGf+ Qv52qFzzs4fQ5UEyw6DEHEM4WcDQKtCYF/hYerEtQqXGrO/SDhnkNrU/ssPpoW1ew8uw /wOg== X-Gm-Message-State: ACrzQf2wKphj0g/4jzMjg2B+O4jJXSRqWOA0l0uJUYpOuLCSK7PujFle BZq4Pazp/7aJWl3CwE3SOXY= X-Received: by 2002:a05:6000:10c6:b0:236:6613:a7bd with SMTP id b6-20020a05600010c600b002366613a7bdmr552874wrx.570.1666457460408; Sat, 22 Oct 2022 09:51:00 -0700 (PDT) Received: from hp-power-15.localdomain (mm-133-18-212-37.vitebsk.dynamic.pppoe.byfly.by. [37.212.18.133]) by smtp.gmail.com with ESMTPSA id h22-20020a05600c351600b003c7084d072csm3196787wmq.28.2022.10.22.09.50.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 22 Oct 2022 09:50:59 -0700 (PDT) From: Siarhei Volkau <lis8215@gmail.com> Cc: Siarhei Volkau <lis8215@gmail.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Rob Herring <robh+dt@kernel.org>, Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>, Paul Cercueil <paul@crapouillou.net>, Jiri Slaby <jirislaby@kernel.org>, linux-serial@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mips@vger.kernel.org Subject: [PATCH v3 2/2] serial: 8250/ingenic: Add support for the JZ4750/JZ4755 Date: Sat, 22 Oct 2022 19:50:47 +0300 Message-Id: <20221022165047.4020785-3-lis8215@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20221022165047.4020785-1-lis8215@gmail.com> References: <20221022165047.4020785-1-lis8215@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-1.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net To: unlisted-recipients:; (no To-header on input) Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1747407995209071627?= X-GMAIL-MSGID: =?utf-8?q?1747407995209071627?= |
Series |
serial: 8250/ingenic: Add support for the JZ4750
|
|
Commit Message
Siarhei Volkau
Oct. 22, 2022, 4:50 p.m. UTC
JZ4750/55/60 (but not JZ4760b) have an extra divisor in between extclk
and peripheral clock, called CPCCR.ECS, the driver can't figure out the
real state of the divisor without dirty hack - peek CGU CPCCR register.
However, we can rely on a vendor's bootloader (u-boot 1.1.6) behavior:
if (extclk > 16MHz)
the divisor is enabled, so the UART driving clock is extclk/2.
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 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>
---
drivers/tty/serial/8250/8250_ingenic.c | 48 ++++++++++++++++++++++----
1 file changed, 42 insertions(+), 6 deletions(-)
Comments
Hi Siarhei, Le sam. 22 oct. 2022 à 19:50:47 +0300, Siarhei Volkau <lis8215@gmail.com> a écrit : > JZ4750/55/60 (but not JZ4760b) have an extra divisor in between extclk > and peripheral clock, called CPCCR.ECS, the driver can't figure out > the > real state of the divisor without dirty hack - peek CGU CPCCR > register. > However, we can rely on a vendor's bootloader (u-boot 1.1.6) behavior: > if (extclk > 16MHz) > the divisor is enabled, so the UART driving clock is extclk/2. > > 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 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> > --- > drivers/tty/serial/8250/8250_ingenic.c | 48 > ++++++++++++++++++++++---- > 1 file changed, 42 insertions(+), 6 deletions(-) > > diff --git a/drivers/tty/serial/8250/8250_ingenic.c > b/drivers/tty/serial/8250/8250_ingenic.c > index 2b2f5d8d2..744705467 100644 > --- a/drivers/tty/serial/8250/8250_ingenic.c > +++ b/drivers/tty/serial/8250/8250_ingenic.c > @@ -87,24 +87,19 @@ 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; > unsigned int divisor; > int baud = 115200; > > - if (!dev->port.membase) > - return -ENODEV; > - > if (opt) { > unsigned int parity, bits, flow; /* unused for now */ > > 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 +124,49 @@ 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) > +{ > + if (!dev->port.membase) > + return -ENODEV; > + > + 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) > +{ > + if (!dev->port.membase) > + return -ENODEV; > + > + /* > + * JZ4750/55/60 (not JZ4760b) have an extra divisor > + * between extclk and peripheral clock, the > + * driver can't figure out the real state of the > + * divisor without dirty hacks (peek CGU register). > + * However, we can rely on a vendor's behavior: > + * if (extclk > 16MHz) > + * the divisor is enabled. > + * This behavior relies on hardware differences: > + * most boards with those SoCs have 12 or 24 MHz > + * oscillators but many peripherals want 12Mhz > + * to operate properly (AIC and USB-phy at least). > + */ > + ingenic_early_console_setup_clock(dev); > + if (dev->port.uartclk > 16000000) > + dev->port.uartclk /= 2; I don't understand, didn't we came up to the conclusion in your V1 that it was better to force-enable the EXT/2 divider in the ingenic init code? -Paul > + > + 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 +363,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 >
сб, 22 окт. 2022 г. в 23:07, Paul Cercueil <paul@crapouillou.net>: > > Hi Siarhei, > > Le sam. 22 oct. 2022 à 19:50:47 +0300, Siarhei Volkau > <lis8215@gmail.com> a écrit : > > JZ4750/55/60 (but not JZ4760b) have an extra divisor in between extclk > > and peripheral clock, called CPCCR.ECS, the driver can't figure out > > the > > real state of the divisor without dirty hack - peek CGU CPCCR > > register. > > However, we can rely on a vendor's bootloader (u-boot 1.1.6) behavior: > > if (extclk > 16MHz) > > the divisor is enabled, so the UART driving clock is extclk/2. > > > > 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 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> > > --- > > drivers/tty/serial/8250/8250_ingenic.c | 48 > > ++++++++++++++++++++++---- > > 1 file changed, 42 insertions(+), 6 deletions(-) > > > > diff --git a/drivers/tty/serial/8250/8250_ingenic.c > > b/drivers/tty/serial/8250/8250_ingenic.c > > index 2b2f5d8d2..744705467 100644 > > --- a/drivers/tty/serial/8250/8250_ingenic.c > > +++ b/drivers/tty/serial/8250/8250_ingenic.c > > @@ -87,24 +87,19 @@ 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; > > unsigned int divisor; > > int baud = 115200; > > > > - if (!dev->port.membase) > > - return -ENODEV; > > - > > if (opt) { > > unsigned int parity, bits, flow; /* unused for now */ > > > > 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 +124,49 @@ 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) > > +{ > > + if (!dev->port.membase) > > + return -ENODEV; > > + > > + 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) > > +{ > > + if (!dev->port.membase) > > + return -ENODEV; > > + > > + /* > > + * JZ4750/55/60 (not JZ4760b) have an extra divisor > > + * between extclk and peripheral clock, the > > + * driver can't figure out the real state of the > > + * divisor without dirty hacks (peek CGU register). > > + * However, we can rely on a vendor's behavior: > > + * if (extclk > 16MHz) > > + * the divisor is enabled. > > + * This behavior relies on hardware differences: > > + * most boards with those SoCs have 12 or 24 MHz > > + * oscillators but many peripherals want 12Mhz > > + * to operate properly (AIC and USB-phy at least). > > + */ > > + ingenic_early_console_setup_clock(dev); > > + if (dev->port.uartclk > 16000000) > > + dev->port.uartclk /= 2; > > I don't understand, didn't we came up to the conclusion in your V1 that > it was better to force-enable the EXT/2 divider in the ingenic init > code? > > -Paul > That was better at that moment. I dived deeper in the situation and found a more simple and universal solution, as I think. Your proposal doesn't cover following situations: - JZ475x with 12MHz crystal - JZ4760 with 24MHz crystal which are legal and might appear in some hardware. > > + > > + 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 +363,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 > > > >
Hi, Le dim. 23 oct. 2022 à 08:29:45 +0300, Siarhei Volkau <lis8215@gmail.com> a écrit : > сб, 22 окт. 2022 г. в 23:07, Paul Cercueil > <paul@crapouillou.net>: >> >> Hi Siarhei, >> >> Le sam. 22 oct. 2022 à 19:50:47 +0300, Siarhei Volkau >> <lis8215@gmail.com> a écrit : >> > JZ4750/55/60 (but not JZ4760b) have an extra divisor in between >> extclk >> > and peripheral clock, called CPCCR.ECS, the driver can't figure >> out >> > the >> > real state of the divisor without dirty hack - peek CGU CPCCR >> > register. >> > However, we can rely on a vendor's bootloader (u-boot 1.1.6) >> behavior: >> > if (extclk > 16MHz) >> > the divisor is enabled, so the UART driving clock is extclk/2. >> > >> > 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 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> >> > --- >> > drivers/tty/serial/8250/8250_ingenic.c | 48 >> > ++++++++++++++++++++++---- >> > 1 file changed, 42 insertions(+), 6 deletions(-) >> > >> > diff --git a/drivers/tty/serial/8250/8250_ingenic.c >> > b/drivers/tty/serial/8250/8250_ingenic.c >> > index 2b2f5d8d2..744705467 100644 >> > --- a/drivers/tty/serial/8250/8250_ingenic.c >> > +++ b/drivers/tty/serial/8250/8250_ingenic.c >> > @@ -87,24 +87,19 @@ 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; >> > unsigned int divisor; >> > int baud = 115200; >> > >> > - if (!dev->port.membase) >> > - return -ENODEV; >> > - >> > if (opt) { >> > unsigned int parity, bits, flow; /* unused for now >> */ >> > >> > 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 +124,49 @@ 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) >> > +{ >> > + if (!dev->port.membase) >> > + return -ENODEV; >> > + >> > + 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) >> > +{ >> > + if (!dev->port.membase) >> > + return -ENODEV; >> > + >> > + /* >> > + * JZ4750/55/60 (not JZ4760b) have an extra divisor >> > + * between extclk and peripheral clock, the >> > + * driver can't figure out the real state of the >> > + * divisor without dirty hacks (peek CGU register). >> > + * However, we can rely on a vendor's behavior: >> > + * if (extclk > 16MHz) >> > + * the divisor is enabled. >> > + * This behavior relies on hardware differences: >> > + * most boards with those SoCs have 12 or 24 MHz >> > + * oscillators but many peripherals want 12Mhz >> > + * to operate properly (AIC and USB-phy at least). >> > + */ >> > + ingenic_early_console_setup_clock(dev); >> > + if (dev->port.uartclk > 16000000) >> > + dev->port.uartclk /= 2; >> >> I don't understand, didn't we came up to the conclusion in your V1 >> that >> it was better to force-enable the EXT/2 divider in the ingenic init >> code? >> >> -Paul >> > > That was better at that moment. I dived deeper in the situation and > found > a more simple and universal solution, as I think. > Your proposal doesn't cover following situations: > - JZ475x with 12MHz crystal > - JZ4760 with 24MHz crystal > which are legal and might appear in some hardware. Do you have such hardware? Don't add support for cases you can't test. For what we know - all JZ475x use a 24 MHz crystal and all JZ4760(B) use a 12 MHz crystal, until proven otherwise. -Paul >> > + >> > + 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 +363,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 >> > >> >>
вс, 23 окт. 2022 г. в 12:16, Paul Cercueil <paul@crapouillou.net>: > Do you have such hardware? No > Don't add support for cases you can't test. It's just a side effect of that approach. > For what we know - all JZ475x use a 24 MHz crystal and all JZ4760(B) > use a 12 MHz crystal, until proven otherwise. Ouf course it just confirms the rule but I found one exception: JZ4750 & 12MHz Link: https://github.com/carlos-wong/uboot_jz4755/blob/master/include/configs/lib4750.h Regarding your proposal: In my opinion enabling the divisor unconditionally is a bad practice, as it's already enabled (or not) by the bootloader, with respect to the hardware capabilities.I think it's better to keep the driver as it is than adding such things. BR, Siarhei
Le dim. 23 oct. 2022 à 17:04:49 +0300, Siarhei Volkau <lis8215@gmail.com> a écrit : > вс, 23 окт. 2022 г. в 12:16, Paul Cercueil > <paul@crapouillou.net>: >> Do you have such hardware? > > No > >> Don't add support for cases you can't test. > > It's just a side effect of that approach. > >> For what we know - all JZ475x use a 24 MHz crystal and all JZ4760(B) >> use a 12 MHz crystal, until proven otherwise. > > Ouf course it just confirms the rule but I found one exception: > JZ4750 & 12MHz > Link: > https://github.com/carlos-wong/uboot_jz4755/blob/master/include/configs/lib4750.h Then when this board is upstreamed it will declare a 12 MHz oscillator in its DT, and the ingenic init code won't have to enable the /2 divider for that particular board. > Regarding your proposal: > In my opinion enabling the divisor unconditionally is a bad practice, > as it's already enabled (or not) by the bootloader, with respect to > the > hardware capabilities.I think it's better to keep the driver as it is > than > adding such things. Well, I disagree. Linux should not depend on whatever the bootloader configures. -Paul
Hi Siarhei, Le sam. 22 oct. 2022 à 19:50:47 +0300, Siarhei Volkau <lis8215@gmail.com> a écrit : > JZ4750/55/60 (but not JZ4760b) have an extra divisor in between extclk > and peripheral clock, called CPCCR.ECS, the driver can't figure out > the > real state of the divisor without dirty hack - peek CGU CPCCR > register. > However, we can rely on a vendor's bootloader (u-boot 1.1.6) behavior: > if (extclk > 16MHz) > the divisor is enabled, so the UART driving clock is extclk/2. > > 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 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> > --- > drivers/tty/serial/8250/8250_ingenic.c | 48 > ++++++++++++++++++++++---- > 1 file changed, 42 insertions(+), 6 deletions(-) > > diff --git a/drivers/tty/serial/8250/8250_ingenic.c > b/drivers/tty/serial/8250/8250_ingenic.c > index 2b2f5d8d2..744705467 100644 > --- a/drivers/tty/serial/8250/8250_ingenic.c > +++ b/drivers/tty/serial/8250/8250_ingenic.c > @@ -87,24 +87,19 @@ 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; > unsigned int divisor; > int baud = 115200; > > - if (!dev->port.membase) > - return -ENODEV; Again, as I said on your v2, you can keep this here. Then you won't have to duplicate code. > - > if (opt) { > unsigned int parity, bits, flow; /* unused for now */ > > 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 +124,49 @@ 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) > +{ > + if (!dev->port.membase) > + return -ENODEV; > + > + 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) > +{ > + if (!dev->port.membase) > + return -ENODEV; > + > + /* > + * JZ4750/55/60 (not JZ4760b) have an extra divisor > + * between extclk and peripheral clock, the > + * driver can't figure out the real state of the > + * divisor without dirty hacks (peek CGU register). > + * However, we can rely on a vendor's behavior: > + * if (extclk > 16MHz) > + * the divisor is enabled. > + * This behavior relies on hardware differences: > + * most boards with those SoCs have 12 or 24 MHz > + * oscillators but many peripherals want 12Mhz > + * to operate properly (AIC and USB-phy at least). > + */ > + ingenic_early_console_setup_clock(dev); > + if (dev->port.uartclk > 16000000) > + dev->port.uartclk /= 2; I'm OK with this code, but the comment is not very clear. What about: "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." Cheers, -Paul > + > + 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 +363,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 >
diff --git a/drivers/tty/serial/8250/8250_ingenic.c b/drivers/tty/serial/8250/8250_ingenic.c index 2b2f5d8d2..744705467 100644 --- a/drivers/tty/serial/8250/8250_ingenic.c +++ b/drivers/tty/serial/8250/8250_ingenic.c @@ -87,24 +87,19 @@ 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; unsigned int divisor; int baud = 115200; - if (!dev->port.membase) - return -ENODEV; - if (opt) { unsigned int parity, bits, flow; /* unused for now */ 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 +124,49 @@ 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) +{ + if (!dev->port.membase) + return -ENODEV; + + 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) +{ + if (!dev->port.membase) + return -ENODEV; + + /* + * JZ4750/55/60 (not JZ4760b) have an extra divisor + * between extclk and peripheral clock, the + * driver can't figure out the real state of the + * divisor without dirty hacks (peek CGU register). + * However, we can rely on a vendor's behavior: + * if (extclk > 16MHz) + * the divisor is enabled. + * This behavior relies on hardware differences: + * most boards with those SoCs have 12 or 24 MHz + * oscillators but many peripherals want 12Mhz + * to operate properly (AIC and USB-phy at least). + */ + 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 +363,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 },