diff mbox

[6/8] tty/serial: pl011: add generic earlycon support

Message ID 1395436128-11244-7-git-send-email-robherring2@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Rob Herring March 21, 2014, 9:08 p.m. UTC
From: Rob Herring <robh@kernel.org>

Add earlycon support for the pl011 serial port. This allows enabling
the pl011 for console when early_params are processed. This is based
on the arm64 earlyprintk support and is intended to replace it.

Signed-off-by: Rob Herring <robh@kernel.org>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.cz>
---
 Documentation/kernel-parameters.txt |  5 +++--
 drivers/tty/serial/amba-pl011.c     | 30 +++++++++++++++++++++++++++++-
 2 files changed, 32 insertions(+), 3 deletions(-)

Comments

Catalin Marinas March 24, 2014, 11:28 a.m. UTC | #1
On Fri, Mar 21, 2014 at 09:08:46PM +0000, Rob Herring wrote:
> From: Rob Herring <robh@kernel.org>
> 
> Add earlycon support for the pl011 serial port. This allows enabling
> the pl011 for console when early_params are processed. This is based
> on the arm64 earlyprintk support and is intended to replace it.
> 
> Signed-off-by: Rob Herring <robh@kernel.org>
> Cc: Russell King <linux@arm.linux.org.uk>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Jiri Slaby <jslaby@suse.cz>
> ---
>  Documentation/kernel-parameters.txt |  5 +++--
>  drivers/tty/serial/amba-pl011.c     | 30 +++++++++++++++++++++++++++++-
>  2 files changed, 32 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
> index 5ce8b7a..81bdd52 100644
> --- a/Documentation/kernel-parameters.txt
> +++ b/Documentation/kernel-parameters.txt
> @@ -887,8 +887,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
>  		uart[8250],io,<addr>[,options]
>  		uart[8250],mmio,<addr>[,options]
>  		uart[8250],mmio32,<addr>[,options]
> -			Start an early, polled-mode console on the 8250/16550
> -			UART at the specified I/O port or MMIO address.
> +		pl011,<addr>
> +			Start an early, polled-mode console on a serial port
> +			at the specified I/O port or MMIO address. 8250
>  			MMIO inter-register address stride is either 8-bit
>  			(mmio) or 32-bit (mmio32).
>  			The options are the same as for ttyS, above.

I think the last line is a bit misleading. Or did you intend to leave it
with the uart[8250] parameter? See below:

> diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
> index d4eda24..4227c0a 100644
> --- a/drivers/tty/serial/amba-pl011.c
> +++ b/drivers/tty/serial/amba-pl011.c
[...]
> +static int __init pl011_early_console_setup(struct earlycon_device *device,
> +					    const char *opt)
> +{
> +	if (!device->port.membase)
> +		return -ENODEV;
> +
> +	device->con->write = pl011_early_write;
> +	return 0;
> +}
> +EARLYCON_DECLARE(pl011, pl011_early_console_setup);

Here we expect the PL011 to be already initialised by the boot loader
and the kernel continues using the same settings. So maybe clarify this
in the pl011 kernel parameter doc and we can add proper configuration
using a separate patch.
Rob Herring April 16, 2014, 10:14 p.m. UTC | #2
On Mon, Mar 24, 2014 at 6:28 AM, Catalin Marinas
<catalin.marinas@arm.com> wrote:
> On Fri, Mar 21, 2014 at 09:08:46PM +0000, Rob Herring wrote:
>> From: Rob Herring <robh@kernel.org>
>>
>> Add earlycon support for the pl011 serial port. This allows enabling
>> the pl011 for console when early_params are processed. This is based
>> on the arm64 earlyprintk support and is intended to replace it.
>>
>> Signed-off-by: Rob Herring <robh@kernel.org>
>> Cc: Russell King <linux@arm.linux.org.uk>
>> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
>> Cc: Jiri Slaby <jslaby@suse.cz>
>> ---
>>  Documentation/kernel-parameters.txt |  5 +++--
>>  drivers/tty/serial/amba-pl011.c     | 30 +++++++++++++++++++++++++++++-
>>  2 files changed, 32 insertions(+), 3 deletions(-)
>>
>> diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
>> index 5ce8b7a..81bdd52 100644
>> --- a/Documentation/kernel-parameters.txt
>> +++ b/Documentation/kernel-parameters.txt
>> @@ -887,8 +887,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
>>               uart[8250],io,<addr>[,options]
>>               uart[8250],mmio,<addr>[,options]
>>               uart[8250],mmio32,<addr>[,options]
>> -                     Start an early, polled-mode console on the 8250/16550
>> -                     UART at the specified I/O port or MMIO address.
>> +             pl011,<addr>
>> +                     Start an early, polled-mode console on a serial port
>> +                     at the specified I/O port or MMIO address. 8250
>>                       MMIO inter-register address stride is either 8-bit
>>                       (mmio) or 32-bit (mmio32).
>>                       The options are the same as for ttyS, above.
>
> I think the last line is a bit misleading. Or did you intend to leave it
> with the uart[8250] parameter? See below:

How about this (excuse the gmail lack of tabs):

earlycon= [KNL] Output early console device and options.

 uart[8250],io,<addr>[,options]
 uart[8250],mmio,<addr>[,options]
 uart[8250],mmio32,<addr>[,options]
  Start an early, polled-mode console on an 8250 serial
  port at the specified I/O port or MMIO address. 8250
  MMIO inter-register address stride is either 8-bit
  (mmio) or 32-bit (mmio32).

  The options are the same as for ttyS, above.

 pl011,<addr>
  Start an early, polled-mode console on a pl011 serial
  port at the specified address. The pl011 serial port
  must already be setup and configured. Options are not
  yet supported.

 smh Use ARM semihosting calls for early console.


>
>> diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
>> index d4eda24..4227c0a 100644
>> --- a/drivers/tty/serial/amba-pl011.c
>> +++ b/drivers/tty/serial/amba-pl011.c
> [...]
>> +static int __init pl011_early_console_setup(struct earlycon_device *device,
>> +                                         const char *opt)
>> +{
>> +     if (!device->port.membase)
>> +             return -ENODEV;
>> +
>> +     device->con->write = pl011_early_write;
>> +     return 0;
>> +}
>> +EARLYCON_DECLARE(pl011, pl011_early_console_setup);
>
> Here we expect the PL011 to be already initialised by the boot loader
> and the kernel continues using the same settings. So maybe clarify this
> in the pl011 kernel parameter doc and we can add proper configuration
> using a separate patch.

Enabling and setup would not be too hard, but either baud rate will
always have to be configured or we'll have to specify the input clock
rate too. The 8250 driver basically does the former or assumes a fixed
clock.

Adding any setup will also break any non-pl011 based SBSA compliant
uart since the configuration registers are not standardized. I guess
we can add "sbsauart" when/if that happens.

Rob
Catalin Marinas April 23, 2014, 4:39 p.m. UTC | #3
On Wed, Apr 16, 2014 at 11:14:28PM +0100, Rob Herring wrote:
> On Mon, Mar 24, 2014 at 6:28 AM, Catalin Marinas
> <catalin.marinas@arm.com> wrote:
> > On Fri, Mar 21, 2014 at 09:08:46PM +0000, Rob Herring wrote:
> >> From: Rob Herring <robh@kernel.org>
> >>
> >> Add earlycon support for the pl011 serial port. This allows enabling
> >> the pl011 for console when early_params are processed. This is based
> >> on the arm64 earlyprintk support and is intended to replace it.
> >>
> >> Signed-off-by: Rob Herring <robh@kernel.org>
> >> Cc: Russell King <linux@arm.linux.org.uk>
> >> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> >> Cc: Jiri Slaby <jslaby@suse.cz>
> >> ---
> >>  Documentation/kernel-parameters.txt |  5 +++--
> >>  drivers/tty/serial/amba-pl011.c     | 30 +++++++++++++++++++++++++++++-
> >>  2 files changed, 32 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
> >> index 5ce8b7a..81bdd52 100644
> >> --- a/Documentation/kernel-parameters.txt
> >> +++ b/Documentation/kernel-parameters.txt
> >> @@ -887,8 +887,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
> >>               uart[8250],io,<addr>[,options]
> >>               uart[8250],mmio,<addr>[,options]
> >>               uart[8250],mmio32,<addr>[,options]
> >> -                     Start an early, polled-mode console on the 8250/16550
> >> -                     UART at the specified I/O port or MMIO address.
> >> +             pl011,<addr>
> >> +                     Start an early, polled-mode console on a serial port
> >> +                     at the specified I/O port or MMIO address. 8250
> >>                       MMIO inter-register address stride is either 8-bit
> >>                       (mmio) or 32-bit (mmio32).
> >>                       The options are the same as for ttyS, above.
> >
> > I think the last line is a bit misleading. Or did you intend to leave it
> > with the uart[8250] parameter? See below:
> 
> How about this (excuse the gmail lack of tabs):
> 
> earlycon= [KNL] Output early console device and options.
> 
>  uart[8250],io,<addr>[,options]
>  uart[8250],mmio,<addr>[,options]
>  uart[8250],mmio32,<addr>[,options]
>   Start an early, polled-mode console on an 8250 serial
>   port at the specified I/O port or MMIO address. 8250
>   MMIO inter-register address stride is either 8-bit
>   (mmio) or 32-bit (mmio32).
> 
>   The options are the same as for ttyS, above.
> 
>  pl011,<addr>
>   Start an early, polled-mode console on a pl011 serial
>   port at the specified address. The pl011 serial port
>   must already be setup and configured. Options are not
>   yet supported.
> 
>  smh Use ARM semihosting calls for early console.

It looks fine.

> >> diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
> >> index d4eda24..4227c0a 100644
> >> --- a/drivers/tty/serial/amba-pl011.c
> >> +++ b/drivers/tty/serial/amba-pl011.c
> > [...]
> >> +static int __init pl011_early_console_setup(struct earlycon_device *device,
> >> +                                         const char *opt)
> >> +{
> >> +     if (!device->port.membase)
> >> +             return -ENODEV;
> >> +
> >> +     device->con->write = pl011_early_write;
> >> +     return 0;
> >> +}
> >> +EARLYCON_DECLARE(pl011, pl011_early_console_setup);
> >
> > Here we expect the PL011 to be already initialised by the boot loader
> > and the kernel continues using the same settings. So maybe clarify this
> > in the pl011 kernel parameter doc and we can add proper configuration
> > using a separate patch.
> 
> Enabling and setup would not be too hard, but either baud rate will
> always have to be configured or we'll have to specify the input clock
> rate too. The 8250 driver basically does the former or assumes a fixed
> clock.
> 
> Adding any setup will also break any non-pl011 based SBSA compliant
> uart since the configuration registers are not standardized. I guess
> we can add "sbsauart" when/if that happens.

I think for now we can assume that the pl011 is initialised at the
right baud rate prior to starting the kernel.
diff mbox

Patch

diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 5ce8b7a..81bdd52 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -887,8 +887,9 @@  bytes respectively. Such letter suffixes can also be entirely omitted.
 		uart[8250],io,<addr>[,options]
 		uart[8250],mmio,<addr>[,options]
 		uart[8250],mmio32,<addr>[,options]
-			Start an early, polled-mode console on the 8250/16550
-			UART at the specified I/O port or MMIO address.
+		pl011,<addr>
+			Start an early, polled-mode console on a serial port
+			at the specified I/O port or MMIO address. 8250
 			MMIO inter-register address stride is either 8-bit
 			(mmio) or 32-bit (mmio32).
 			The options are the same as for ttyS, above.
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index d4eda24..4227c0a 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -303,7 +303,7 @@  static void pl011_dma_probe_initcall(struct device *dev, struct uart_amba_port *
 
 	/* Optionally make use of an RX channel as well */
 	chan = dma_request_slave_channel(dev, "rx");
-	
+
 	if (!chan && plat->dma_rx_param) {
 		chan = dma_request_channel(mask, plat->dma_filter, plat->dma_rx_param);
 
@@ -2045,6 +2045,34 @@  static struct console amba_console = {
 };
 
 #define AMBA_CONSOLE	(&amba_console)
+
+static void pl011_putc(struct uart_port *port, int c)
+{
+	while (readl(port->membase + UART01x_FR) & UART01x_FR_TXFF)
+		;
+	writeb(c, port->membase + UART01x_DR);
+	while (readl(port->membase + UART01x_FR) & UART01x_FR_BUSY)
+		;
+}
+
+static void pl011_early_write(struct console *con, const char *s, unsigned n)
+{
+	struct earlycon_device *dev = con->data;
+
+	uart_console_write(&dev->port, s, n, pl011_putc);
+}
+
+static int __init pl011_early_console_setup(struct earlycon_device *device,
+					    const char *opt)
+{
+	if (!device->port.membase)
+		return -ENODEV;
+
+	device->con->write = pl011_early_write;
+	return 0;
+}
+EARLYCON_DECLARE(pl011, pl011_early_console_setup);
+
 #else
 #define AMBA_CONSOLE	NULL
 #endif