public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v6 06/10] ns16550: add support for mips
Date: Fri, 08 Jan 2016 17:23:46 +0100	[thread overview]
Message-ID: <1452270226.14012.36.camel@gmail.com> (raw)
In-Reply-To: <BLU436-SMTP726117884F5FCC94F2F72EFFF20@phx.gbl>

Am Montag, den 04.01.2016, 19:14 +0800 schrieb Wills Wang:
> MIPS archtecture have no "in_le32/in_be32/out_le32/out_be32" macro,
> but usually define CONFIG_SYS_BIG_ENDIAN, this patch use readl/writel
> for register operation in mips when define CONFIG_SYS_NS16550_MEM32.
> 
> Signed-off-by: Wills Wang <wills.wang@live.com>
> ---
> 
> Changes in v6: None
> Changes in v5: None
> Changes in v4: None
> Changes in v3: None
> Changes in v2: None
> 
>  drivers/serial/ns16550.c | 24 ++++++++++++++++--------
>  1 file changed, 16 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
> index 3fab3f1..3b24af0 100644
> --- a/drivers/serial/ns16550.c
> +++ b/drivers/serial/ns16550.c
> @@ -64,12 +64,16 @@ static inline void serial_out_shift(void *addr,
> int shift, int value)
>  {
>  #ifdef CONFIG_SYS_NS16550_PORT_MAPPED
>  	outb(value, (ulong)addr);
> -#elif defined(CONFIG_SYS_NS16550_MEM32) &&
> !defined(CONFIG_SYS_BIG_ENDIAN)
> -	out_le32(addr, value);
> -#elif defined(CONFIG_SYS_NS16550_MEM32) &&
> defined(CONFIG_SYS_BIG_ENDIAN)
> -	out_be32(addr, value);
>  #elif defined(CONFIG_SYS_NS16550_MEM32)
> +#ifdef CONFIG_MIPS
>  	writel(value, addr);
> +#else
> +#ifndef CONFIG_SYS_BIG_ENDIAN
> +	out_le32(addr, value);
> +#else
> +	out_be32(addr, value);
> +#endif
> +#endif
>  #elif defined(CONFIG_SYS_BIG_ENDIAN)
>  	writeb(value, addr + (1 << shift) - 1);
>  #else
> @@ -81,12 +85,16 @@ static inline int serial_in_shift(void *addr, int
> shift)
>  {
>  #ifdef CONFIG_SYS_NS16550_PORT_MAPPED
>  	return inb((ulong)addr);
> -#elif defined(CONFIG_SYS_NS16550_MEM32) &&
> !defined(CONFIG_SYS_BIG_ENDIAN)
> -	return in_le32(addr);
> -#elif defined(CONFIG_SYS_NS16550_MEM32) &&
> defined(CONFIG_SYS_BIG_ENDIAN)
> -	return in_be32(addr);
>  #elif defined(CONFIG_SYS_NS16550_MEM32)
> +#ifdef CONFIG_MIPS
>  	return readl(addr);
> +#else
> +#ifndef CONFIG_SYS_BIG_ENDIAN
> +	return in_le32(addr);
> +#else
> +	return in_be32(addr);
> +#endif
> +#endif
>  #elif defined(CONFIG_SYS_BIG_ENDIAN)
>  	return readb(addr + (1 << shift) - 1);
>  #else

Could you tell us, if you need port IO or MMIO. In case of MMIO do you
need 8 bit or 32 bit I/O access?

Becasue your CPU is running in Big Endian and the NS16550 is Little
Endian, you need endianess conversion in the 32 bit case.

The 8 bit access should already work without changing anything. The
MIPS Malta board also uses NS16550 and already works in Bit Endian
mode.

To make the 32 bit case working, you need to select
CONFIG_SWAP_IO_SPACE in your SoC Kconfig code. Then all readl/writel
accessors do an endianess conversion to Little Endian if the CPU is
running in Big Endian.

Anyway I think the current implementation is wrong:

static inline void serial_out_shift(void *addr, int shift, int value)
{
#ifdef CONFIG_SYS_NS16550_PORT_MAPPED
	outb(value, (ulong)addr);
#elif defined(CONFIG_SYS_NS16550_MEM32) &&
!defined(CONFIG_SYS_BIG_ENDIAN)
	out_le32(addr, value);
#elif defined(CONFIG_SYS_NS16550_MEM32) &&
defined(CONFIG_SYS_BIG_ENDIAN)
	out_be32(addr, value);
#elif defined(CONFIG_SYS_NS16550_MEM32)
	writel(value, addr);
#elif defined(CONFIG_SYS_BIG_ENDIAN)
	writeb(value, addr + (1 << shift) - 1);
#else
	writeb(value, addr);
#endif
}

The branch with writel() will never be taken because the two preceding
branches already catch all conditions for CONFIG_SYS_NS16550_MEM32.
Also if the NS16550 is Little Endian, the branch with out_be32 makes no
sense. All IO accessors must convert from CPU endianess to NS16550's
Little Endian, but out_be32 converts from CPU endianess to Big Endian. 

To handle port IO, 32 Bit MMIO and 8 Bit MMIO, following code should be
enough:

static inline void serial_out_shift(void *addr, int shift, int value)
{
#ifdef CONFIG_SYS_NS16550_PORT_MAPPED
	outb(value, (ulong)addr);
#elif defined(CONFIG_SYS_NS16550_MEM32)
	writel(value, addr);
#elif defined(CONFIG_SYS_BIG_ENDIAN)
	writeb(value, addr + (1 << shift) - 1);
#else
	writeb(value, addr);
#endif
}

The arch-specific implementation of readl/writel should be responsible
for the endianess conversion and not the driver. What do you think?

-- 
- Daniel

  parent reply	other threads:[~2016-01-08 16:23 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <1451906101-9801-2-git-send-email-wills.wang@live.com>
2016-01-04 11:14 ` [U-Boot] [PATCH v6 02/10] mips: add base support for QCA/Atheros ath79 SOCs Wills Wang
2016-01-04 11:14 ` [U-Boot] [PATCH v6 03/10] mips: ath79: add support for AR933x SOCs Wills Wang
2016-01-04 11:14 ` [U-Boot] [PATCH v6 04/10] mips: ath79: add support for QCA953x SOCs Wills Wang
2016-01-04 11:14 ` [U-Boot] [PATCH v6 05/10] mips: ath79: add serial driver for ar933x SOC Wills Wang
2016-01-04 12:52   ` Thomas Chou
2016-01-04 11:14 ` [U-Boot] [PATCH v6 06/10] ns16550: add support for mips Wills Wang
2016-01-04 13:12   ` Thomas Chou
2016-01-04 13:25     ` Marek Vasut
2016-01-04 13:56       ` Wills Wang
2016-01-08 16:23   ` Daniel Schwierzeck [this message]
2016-01-09 10:46     ` Wills Wang
2016-01-09 14:30       ` Daniel Schwierzeck
2016-01-16 16:15         ` Wills Wang
2016-01-16 16:26           ` Daniel Schwierzeck
2016-01-04 11:14 ` [U-Boot] [PATCH v6 07/10] ns16550: map register base address for debug UART Wills Wang
2016-01-04 13:07   ` Thomas Chou
2016-01-04 14:10     ` Wills Wang
2016-01-05 21:18     ` Daniel Schwierzeck
2016-01-06  2:50       ` Wills Wang
2016-01-04 11:14 ` [U-Boot] [PATCH v6 08/10] mips: ath79: add spi driver Wills Wang
2016-01-05  2:51   ` Thomas Chou
2016-01-06 12:16   ` Jagan Teki
2016-01-09 17:51     ` Wills Wang
2016-01-04 11:15 ` [U-Boot] [PATCH v6 09/10] mips: ath79: add AP121 reference board Wills Wang
2016-01-04 11:15 ` [U-Boot] [PATCH v6 10/10] mips: ath79: add AP143 " Wills Wang

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=1452270226.14012.36.camel@gmail.com \
    --to=daniel.schwierzeck@gmail.com \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox