Skip to content

Commit

Permalink
powerpc/virtex: Fix booting of Xilinx FPGAs with 16550 for 405 and 440
Browse files Browse the repository at this point in the history
The following changes add processing to initialize the Xilinx 16550 UART
in the boot wrapper for Virtex targets without firmware.  Normally the
boot wrapper assumes that the serial port has already been initialized by
firmware.

The wrapper was also modified to add the 440 build.

Signed-off-by: John Linn <john.linn@xilinx.com>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
  • Loading branch information
John Linn authored and Grant Likely committed Jul 4, 2008
1 parent dc568ec commit d58577d
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 2 deletions.
2 changes: 1 addition & 1 deletion arch/powerpc/boot/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ src-plat := of.c cuboot-52xx.c cuboot-824x.c cuboot-83xx.c cuboot-85xx.c holly.c
fixed-head.S ep88xc.c ep405.c cuboot-c2k.c \
cuboot-katmai.c cuboot-rainier.c redboot-8xx.c ep8248e.c \
cuboot-warp.c cuboot-85xx-cpm2.c cuboot-yosemite.c simpleboot.c \
virtex405-head.S redboot-83xx.c cuboot-sam440ep.c
virtex405-head.S virtex.c redboot-83xx.c cuboot-sam440ep.c
src-boot := $(src-wlib) $(src-plat) empty.c

src-boot := $(addprefix $(obj)/, $(src-boot))
Expand Down
6 changes: 6 additions & 0 deletions arch/powerpc/boot/simpleboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@

BSS_STACK(4*1024);

extern int platform_specific_init(void) __attribute__((weak));

void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7)
{
Expand Down Expand Up @@ -80,5 +82,9 @@ void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,

/* prepare the device tree and find the console */
fdt_init(_dtb_start);

if (platform_specific_init)
platform_specific_init();

serial_console_init();
}
100 changes: 100 additions & 0 deletions arch/powerpc/boot/virtex.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* The platform specific code for virtex devices since a boot loader is not
* always used.
*
* (C) Copyright 2008 Xilinx, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*/

#include "ops.h"
#include "io.h"
#include "stdio.h"

#define UART_DLL 0 /* Out: Divisor Latch Low */
#define UART_DLM 1 /* Out: Divisor Latch High */
#define UART_FCR 2 /* Out: FIFO Control Register */
#define UART_FCR_CLEAR_RCVR 0x02 /* Clear the RCVR FIFO */
#define UART_FCR_CLEAR_XMIT 0x04 /* Clear the XMIT FIFO */
#define UART_LCR 3 /* Out: Line Control Register */
#define UART_MCR 4 /* Out: Modem Control Register */
#define UART_MCR_RTS 0x02 /* RTS complement */
#define UART_MCR_DTR 0x01 /* DTR complement */
#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */
#define UART_LCR_WLEN8 0x03 /* Wordlength: 8 bits */

static int virtex_ns16550_console_init(void *devp)
{
unsigned char *reg_base;
u32 reg_shift, reg_offset, clk, spd;
u16 divisor;
int n;

if (dt_get_virtual_reg(devp, (void **)&reg_base, 1) < 1)
return -1;

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;

n = getprop(devp, "current-speed", (void *)&spd, sizeof(spd));
if (n != sizeof(spd))
spd = 9600;

/* should there be a default clock rate?*/
n = getprop(devp, "clock-frequency", (void *)&clk, sizeof(clk));
if (n != sizeof(clk))
return -1;

divisor = clk / (16 * spd);

/* Access baud rate */
out_8(reg_base + (UART_LCR << reg_shift), UART_LCR_DLAB);

/* Baud rate based on input clock */
out_8(reg_base + (UART_DLL << reg_shift), divisor & 0xFF);
out_8(reg_base + (UART_DLM << reg_shift), divisor >> 8);

/* 8 data, 1 stop, no parity */
out_8(reg_base + (UART_LCR << reg_shift), UART_LCR_WLEN8);

/* RTS/DTR */
out_8(reg_base + (UART_MCR << reg_shift), UART_MCR_RTS | UART_MCR_DTR);

/* Clear transmitter and receiver */
out_8(reg_base + (UART_FCR << reg_shift),
UART_FCR_CLEAR_XMIT | UART_FCR_CLEAR_RCVR);
return 0;
}

/* For virtex, the kernel may be loaded without using a bootloader and if so
some UARTs need more setup than is provided in the normal console init
*/
int platform_specific_init(void)
{
void *devp;
char devtype[MAX_PROP_LEN];
char path[MAX_PATH_LEN];

devp = finddevice("/chosen");
if (devp == NULL)
return -1;

if (getprop(devp, "linux,stdout-path", path, MAX_PATH_LEN) > 0) {
devp = finddevice(path);
if (devp == NULL)
return -1;

if ((getprop(devp, "device_type", devtype, sizeof(devtype)) > 0)
&& !strcmp(devtype, "serial")
&& (dt_is_compatible(devp, "ns16550")))
virtex_ns16550_console_init(devp);
}
return 0;
}
6 changes: 5 additions & 1 deletion arch/powerpc/boot/wrapper
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,11 @@ adder875-redboot)
binary=y
;;
simpleboot-virtex405-*)
platformo="$object/virtex405-head.o $object/simpleboot.o"
platformo="$object/virtex405-head.o $object/simpleboot.o $object/virtex.o"
binary=y
;;
simpleboot-virtex440-*)
platformo="$object/simpleboot.o $object/virtex.o"
binary=y
;;
asp834x-redboot)
Expand Down

0 comments on commit d58577d

Please sign in to comment.