All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stefan Roese <sr@denx.de>
To: "Marek Behún" <marek.behun@nic.cz>, u-boot@lists.denx.de
Cc: "Pali Rohár" <pali@kernel.org>
Subject: Re: [PATCH u-boot-marvell 4/5] serial: a37xx: Switch to XTAL clock when booting Linux kernel
Date: Thu, 27 May 2021 08:17:41 +0200	[thread overview]
Message-ID: <b6cd7356-9ec5-9e86-e747-1e58b7b82a15@denx.de> (raw)
In-Reply-To: <20210525174242.27509-5-marek.behun@nic.cz>

On 25.05.21 19:42, Marek Behún wrote:
> From: Pali Rohár <pali@kernel.org>
> 
> Unfortunately the UART driver in current Linux for Armada 3700 expects
> UART's parent clock to be XTAL and calculats baudrate divisor according
> to XTAL clock. Therefore we must switch back to XTAL clock before
> booting kernel.

Do you plan to enhance the Linux driver as well to support TBG as
clock in input at some time?

> Implement .remove method for this driver with DM_FLAG_OS_PREPARE flag
> set.
> 
> If current baudrate is unsuitable for XTAL clock then we do not change
> anything. This can only happen if the user either configured unsupported
> settings or knows what they are doing and has kernel patches which allow
> usage of non-XTAL parent clock.
> 
> Signed-off-by: Pali Rohár <pali@kernel.org>
> Reviewed-by: Marek Behún <marek.behun@nic.cz>

Reviewed-by: Stefan Roese <sr@denx.de>

Thanks,
Stefan

> ---
>   drivers/serial/serial_mvebu_a3700.c | 67 +++++++++++++++++++++++++++++
>   1 file changed, 67 insertions(+)
> 
> diff --git a/drivers/serial/serial_mvebu_a3700.c b/drivers/serial/serial_mvebu_a3700.c
> index ba2ac5917f..c7e66fef87 100644
> --- a/drivers/serial/serial_mvebu_a3700.c
> +++ b/drivers/serial/serial_mvebu_a3700.c
> @@ -204,6 +204,71 @@ static int mvebu_serial_probe(struct udevice *dev)
>   	return 0;
>   }
>   
> +static int mvebu_serial_remove(struct udevice *dev)
> +{
> +	struct mvebu_plat *plat = dev_get_plat(dev);
> +	void __iomem *base = plat->base;
> +	ulong new_parent_rate, parent_rate;
> +	u32 new_divider, divider;
> +	u32 new_oversampling;
> +	u32 oversampling;
> +	u32 d1, d2;
> +
> +	/*
> +	 * Switch UART base clock back to XTAL because older Linux kernel
> +	 * expects it. Otherwise it does not calculate UART divisor correctly
> +	 * and therefore UART does not work in kernel.
> +	 */
> +	divider = readl(base + UART_BAUD_REG);
> +	if (!(divider & BIT(19))) /* UART already uses XTAL */
> +		return 0;
> +
> +	/* Read current divisors settings */
> +	d1 = (divider >> 15) & 7;
> +	d2 = (divider >> 12) & 7;
> +	parent_rate = plat->tbg_rate;
> +	divider &= 1023;
> +	oversampling = readl(base + UART_POSSR_REG) & 63;
> +	if (!oversampling)
> +		oversampling = 16;
> +
> +	/* Calculate new divisor against XTAL clock without changing baudrate */
> +	new_oversampling = 0;
> +	new_parent_rate = get_ref_clk() * 1000000;
> +	new_divider = DIV_ROUND_CLOSEST(new_parent_rate * divider * d1 * d2 *
> +					oversampling, parent_rate * 16);
> +
> +	/*
> +	 * UART does not work reliably when XTAL divisor is smaller than 4.
> +	 * In this case we do not switch UART parent to XTAL. User either
> +	 * configured unsupported settings or has newer kernel with patches
> +	 * which allow usage of non-XTAL clock as a parent clock.
> +	 */
> +	if (new_divider < 4)
> +		return 0;
> +
> +	/*
> +	 * If new divisor is larger than maximal supported, try to switch
> +	 * from default x16 scheme to oversampling with maximal factor 63.
> +	 */
> +	if (new_divider > 1023) {
> +		new_oversampling = 63;
> +		new_divider = DIV_ROUND_CLOSEST(new_parent_rate * divider * d1 *
> +						d2 * oversampling,
> +						parent_rate * new_oversampling);
> +		if (new_divider < 4 || new_divider > 1023)
> +			return 0;
> +	}
> +
> +	while (!(readl(base + UART_STATUS_REG) & UART_STATUS_TX_EMPTY))
> +		;
> +
> +	writel(new_divider, base + UART_BAUD_REG);
> +	writel(new_oversampling, base + UART_POSSR_REG);
> +
> +	return 0;
> +}
> +
>   static int mvebu_serial_of_to_plat(struct udevice *dev)
>   {
>   	struct mvebu_plat *plat = dev_get_plat(dev);
> @@ -232,6 +297,8 @@ U_BOOT_DRIVER(serial_mvebu) = {
>   	.of_to_plat = mvebu_serial_of_to_plat,
>   	.plat_auto	= sizeof(struct mvebu_plat),
>   	.probe	= mvebu_serial_probe,
> +	.remove	= mvebu_serial_remove,
> +	.flags	= DM_FLAG_OS_PREPARE,
>   	.ops	= &mvebu_serial_ops,
>   };
>   
> 


Viele Grüße,
Stefan

-- 
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-51 Fax: (+49)-8142-66989-80 Email: sr@denx.de

  reply	other threads:[~2021-05-27  6:17 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-25 17:42 [PATCH u-boot-marvell 0/5] Support higher baudrates on Armada 3720 UART Marek Behún
2021-05-25 17:42 ` [PATCH u-boot-marvell 1/5] serial: a37xx: Fix parent clock rate value and divider calculation Marek Behún
2021-05-27  6:13   ` Stefan Roese
2021-05-25 17:42 ` [PATCH u-boot-marvell 2/5] clk: armada-37xx: Set DM_FLAG_PRE_RELOC Marek Behún
2021-05-27  6:14   ` Stefan Roese
2021-05-25 17:42 ` [PATCH u-boot-marvell 3/5] serial: a37xx: Use TBG as parent clock Marek Behún
2021-05-27  6:15   ` Stefan Roese
2021-05-25 17:42 ` [PATCH u-boot-marvell 4/5] serial: a37xx: Switch to XTAL clock when booting Linux kernel Marek Behún
2021-05-27  6:17   ` Stefan Roese [this message]
2021-05-27  8:17     ` Pali Rohár
2021-06-25 12:04       ` Pali Rohár
2021-05-25 17:42 ` [PATCH u-boot-marvell 5/5] arm: mvebu: a37xx: Enable more baudrates Marek Behún
2021-05-27  6:18   ` Stefan Roese
2021-07-09  5:18 ` [PATCH u-boot-marvell 0/5] Support higher baudrates on Armada 3720 UART Stefan Roese

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=b6cd7356-9ec5-9e86-e747-1e58b7b82a15@denx.de \
    --to=sr@denx.de \
    --cc=marek.behun@nic.cz \
    --cc=pali@kernel.org \
    --cc=u-boot@lists.denx.de \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.