Subject: RE: [PATCH 3/3][POWERPC][V2] Xilinx: boot support for Xilinx uart 16550.

From: "John Linn" <[email-masked]>
Date: Thu, 3 Apr 2008 07:28:59 -0600

Hi Johann,

You're right about it being missing. I have another patch for virtex
specific initialization that handles that.  I have not submitted it yet
as I was trying to get these patches thru the system.

I have been told in this forum that the bootstrap loader should not be
setting up the baud rate and that normally the boot loader does it.

In the case of FPGAs, we don't always use a boot loader so we need this
to happen in the bootstrap loader.  I can forward that patch to you if
you're interested before it goes to this group.

Thanks,

John

________________________________

From: Johann Baudy [mailto:[email-masked]] 
Sent: Thursday, April 03, 2008 7:23 AM
To: John Linn
Cc: [email-masked]; [email-masked]
Subject: Re: [PATCH 3/3][POWERPC][V2] Xilinx: boot support for Xilinx
uart 16550.

Hi John,

I've a small question about ns16550 boot support.
I can't see any code related to either "clock-frequency" or
"current-speed" key words.
Such actions are performed in of_serial.c to get appropriate baud rate
(update of UART_DLL and UART_DLM).

Is it needed or is it a misunderstanding? 
Personally, I have added this below debug code (dirty :)) to make it
work.

diff --git a/arch/powerpc/boot/ns16550.c b/arch/powerpc/boot/ns16550.c
index f8f1b2f..850e223 100644
--- a/arch/powerpc/boot/ns16550.c
+++ b/arch/powerpc/boot/ns16550.c
@@ -26,6 +26,9 @@
 #define UART_MSR    6    /* In:  Modem Status Register */
 #define UART_SCR    7    /* I/O: Scratch Register */
 
+#define UART_LCR_DLAB 0x80      /* Divisor latch access */
+#define UART_LCR_8_DATA_BITS 0x03
+
 static unsigned char *reg_base;
 static u32 reg_shift;
 
@@ -56,6 +59,10 @@ int ns16550_console_init(void *devp, struct
serial_console_data *scdp)
 {
     int n;
     unsigned long reg_phys;
+  unsigned long divisor=0;
+  unsigned long spd=0, clk=0;
+
+
 
     n = getprop(devp, "virtual-reg", &reg_base, sizeof(reg_base));
     if (n != sizeof(reg_base)) {
@@ -75,5 +82,23 @@ int ns16550_console_init(void *devp, struct
serial_console_data *scdp)
     scdp->tstc = ns16550_tstc;
     scdp->close = NULL;
 
+    n = getprop(devp, "current-speed", &spd, sizeof(spd));
+
+
+    n = getprop(devp, "clock-frequency", &clk, sizeof(clk));
+
+
+  if(spd&&clk)
+  {
+
+     divisor = clk / (spd * 16UL);
+
+     out_8(reg_base + (UART_FCR << reg_shift), 0x06);
+     out_8(reg_base + (UART_LCR << reg_shift),
UART_LCR_8_DATA_BITS|UART_LCR_DLAB);
+     out_8(reg_base + (UART_DLL << reg_shift), divisor&0xff);
+     out_8(reg_base + (UART_DLM << reg_shift), (divisor>>8)&0xff);
+     out_8(reg_base + (UART_LCR << reg_shift), UART_LCR_8_DATA_BITS);
+
+  }
     return 0;
 
Best regards,
Johann

On Wed, Apr 2, 2008 at 4:52 PM, John Linn <[email-masked]> wrote:

The Xilinx 16550 uart core is not a standard 16550 because it uses
word-based addressing rather than byte-based adressing. With
additional properties it is compatible with the open firmware
'ns16550' compatible binding.

This code updates the ns16550 driver to use the reg-offset property
so that the Xilinx UART 16550 can be used with it. The reg-shift
was already being handled.

Signed-off-by: John Linn <[email-masked]>
---
 arch/powerpc/boot/ns16550.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/boot/ns16550.c b/arch/powerpc/boot/ns16550.c
index f8f1b2f..da9d2c2 100644
--- a/arch/powerpc/boot/ns16550.c
+++ b/arch/powerpc/boot/ns16550.c
@@ -56,6 +56,7 @@ int ns16550_console_init(void *devp, struct
serial_console_data *scdp)
 {
       int n;
       unsigned long reg_phys;
+       u32 reg_offset;

       n = getprop(devp, "virtual-reg", &reg_base, sizeof(reg_base));
       if (n != sizeof(reg_base)) {
@@ -65,6 +66,10 @@ int ns16550_console_init(void *devp, struct
serial_console_data *scdp)
               reg_base = (void *)reg_phys;
       }

+       n = getprop(devp, "reg-offset", &reg_offset,
sizeof(reg_offset));
+       if (n == sizeof(reg_offset))
+               reg_base += reg_offset;
+
       n = getprop(devp, "reg-shift", &reg_shift, sizeof(reg_shift));
       if (n != sizeof(reg_shift))
               reg_shift = 0;
--
1.5.2.1

_______________________________________________
Linuxppc-dev mailing list
[email-masked]
https://ozlabs.org/mailman/listinfo/linuxppc-dev

-- 
Johann Baudy
[email-masked]