diff options
Diffstat (limited to 'u-boot/board/linkstation')
-rw-r--r-- | u-boot/board/linkstation/Makefile | 43 | ||||
-rw-r--r-- | u-boot/board/linkstation/avr.c | 293 | ||||
-rw-r--r-- | u-boot/board/linkstation/hwctl.c | 135 | ||||
-rw-r--r-- | u-boot/board/linkstation/ide.c | 101 | ||||
-rw-r--r-- | u-boot/board/linkstation/linkstation.c | 137 |
5 files changed, 709 insertions, 0 deletions
diff --git a/u-boot/board/linkstation/Makefile b/u-boot/board/linkstation/Makefile new file mode 100644 index 0000000..55674b7 --- /dev/null +++ b/u-boot/board/linkstation/Makefile @@ -0,0 +1,43 @@ +# +# (C) Copyright 2001 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(BOARD).o + +OBJS = $(BOARD).o ide.o hwctl.o avr.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(OBJS)) + +$(LIB): $(obj).depend $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/u-boot/board/linkstation/avr.c b/u-boot/board/linkstation/avr.c new file mode 100644 index 0000000..ec6d400 --- /dev/null +++ b/u-boot/board/linkstation/avr.c @@ -0,0 +1,293 @@ +/* + * avr.c + * + * AVR functions + * + * Copyright (C) 2006 Mihai Georgian <u-boot@linuxnotincluded.org.uk> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include <common.h> +#include <ns16550.h> +#include <stdio_dev.h> + +/* Button codes from the AVR */ +#define PWRR 0x20 /* Power button release */ +#define PWRP 0x21 /* Power button push */ +#define RESR 0x22 /* Reset button release */ +#define RESP 0x23 /* Reset button push */ +#define AVRINIT 0x33 /* Init complete */ +#define AVRRESET 0x31 /* Reset request */ + +/* LED commands */ +#define PWRBLINKSTRT '[' /* Blink power LED */ +#define PWRBLINKSTOP 'Z' /* Solid power LED */ +#define HDDLEDON 'W' /* HDD LED on */ +#define HDDLEDOFF 'V' /* HDD LED off */ +#define HDDBLINKSTRT 'Y' /* HDD LED start blink */ +#define HDDBLINKSTOP 'X' /* HDD LED stop blink */ + +/* Timings for LEDs blinking to show choice */ +#define PULSETIME 250 /* msecs */ +#define LONGPAUSE (5 * PULSETIME) + +/* Button press times */ +#define PUSHHOLD 1000 /* msecs */ +#define NOBUTTON (6 * (LONGPAUSE+PULSETIME)) + +/* Boot and console choices */ +#define MAX_BOOT_CHOICE 3 + +static char *consoles[] = { + "serial", +#if defined(CONFIG_NETCONSOLE) + "nc", +#endif +}; +#define MAX_CONS_CHOICE (sizeof(consoles)/sizeof(char *)) + +#if !defined(CONFIG_NETCONSOLE) +#define DEF_CONS_CHOICE 0 +#else +#define DEF_CONS_CHOICE 1 +#endif + +#define perror(fmt, args...) printf("%s: " fmt, __FUNCTION__ , ##args) + +extern void miconCntl_SendCmd(unsigned char dat); +extern void miconCntl_DisWDT(void); + +static int boot_stop; + +static int boot_choice = 1; +static int cons_choice = DEF_CONS_CHOICE; + +static char envbuffer[16]; + +void init_AVR_DUART (void) +{ + NS16550_t AVR_port = (NS16550_t) CONFIG_SYS_NS16550_COM2; + int clock_divisor = CONFIG_SYS_NS16550_CLK / 16 / 9600; + + /* + * AVR port init sequence taken from + * the original Linkstation init code + * Normal U-Boot serial reinit doesn't + * work because the AVR uses even parity + */ + AVR_port->lcr = 0x00; + AVR_port->ier = 0x00; + AVR_port->lcr = UART_LCR_BKSE; + AVR_port->dll = clock_divisor & 0xff; + AVR_port->dlm = (clock_divisor >> 8) & 0xff; + AVR_port->lcr = UART_LCR_WLS_8 | UART_LCR_PEN | UART_LCR_EPS; + AVR_port->mcr = 0x00; + AVR_port->fcr = UART_FCR_FIFO_EN | UART_FCR_RXSR | UART_FCR_TXSR; + + miconCntl_DisWDT(); + + boot_stop = 0; + miconCntl_SendCmd(PWRBLINKSTRT); +} + +static inline int avr_tstc(void) +{ + return (NS16550_tstc((NS16550_t)CONFIG_SYS_NS16550_COM2)); +} + +static inline char avr_getc(void) +{ + return (NS16550_getc((NS16550_t)CONFIG_SYS_NS16550_COM2)); +} + +static int push_timeout(char button_code) +{ + ulong push_start = get_timer(0); + while (get_timer(push_start) <= PUSHHOLD) + if (avr_tstc() && avr_getc() == button_code) + return 0; + return 1; +} + +static void next_boot_choice(void) +{ + ulong return_start; + ulong pulse_start; + int on_times; + int button_on; + int led_state; + char c; + + button_on = 0; + return_start = get_timer(0); + + on_times = boot_choice; + led_state = 0; + miconCntl_SendCmd(HDDLEDOFF); + pulse_start = get_timer(0); + + while (get_timer(return_start) <= NOBUTTON || button_on) { + if (avr_tstc()) { + c = avr_getc(); + if (c == PWRP) + button_on = 1; + else if (c == PWRR) { + button_on = 0; + return_start = get_timer(0); + if (++boot_choice > MAX_BOOT_CHOICE) + boot_choice = 1; + sprintf(envbuffer, "bootcmd%d", boot_choice); + if (getenv(envbuffer)) { + sprintf(envbuffer, "run bootcmd%d", boot_choice); + setenv("bootcmd", envbuffer); + } + on_times = boot_choice; + led_state = 1; + miconCntl_SendCmd(HDDLEDON); + pulse_start = get_timer(0); + } else { + perror("Unexpected code: 0x%02X\n", c); + } + } + if (on_times && get_timer(pulse_start) > PULSETIME) { + if (led_state == 1) { + --on_times; + led_state = 0; + miconCntl_SendCmd(HDDLEDOFF); + } else { + led_state = 1; + miconCntl_SendCmd(HDDLEDON); + } + pulse_start = get_timer(0); + } + if (!on_times && get_timer(pulse_start) > LONGPAUSE) { + on_times = boot_choice; + led_state = 1; + miconCntl_SendCmd(HDDLEDON); + pulse_start = get_timer(0); + } + } + if (led_state) + miconCntl_SendCmd(HDDLEDOFF); +} + +void next_cons_choice(int console) +{ + ulong return_start; + ulong pulse_start; + int on_times; + int button_on; + int led_state; + char c; + + button_on = 0; + cons_choice = console; + return_start = get_timer(0); + + on_times = cons_choice+1; + led_state = 1; + miconCntl_SendCmd(HDDLEDON); + pulse_start = get_timer(0); + + while (get_timer(return_start) <= NOBUTTON || button_on) { + if (avr_tstc()) { + c = avr_getc(); + if (c == RESP) + button_on = 1; + else if (c == RESR) { + button_on = 0; + return_start = get_timer(0); + cons_choice = (cons_choice + 1) % MAX_CONS_CHOICE; + console_assign(stdin, consoles[cons_choice]); + console_assign(stdout, consoles[cons_choice]); + console_assign(stderr, consoles[cons_choice]); + on_times = cons_choice+1; + led_state = 0; + miconCntl_SendCmd(HDDLEDOFF); + pulse_start = get_timer(0); + } else { + perror("Unexpected code: 0x%02X\n", c); + } + } + if (on_times && get_timer(pulse_start) > PULSETIME) { + if (led_state == 0) { + --on_times; + led_state = 1; + miconCntl_SendCmd(HDDLEDON); + } else { + led_state = 0; + miconCntl_SendCmd(HDDLEDOFF); + } + pulse_start = get_timer(0); + } + if (!on_times && get_timer(pulse_start) > LONGPAUSE) { + on_times = cons_choice+1; + led_state = 0; + miconCntl_SendCmd(HDDLEDOFF); + pulse_start = get_timer(0); + } + } + if (led_state); + miconCntl_SendCmd(HDDLEDOFF); +} + +int avr_input(void) +{ + char avr_button; + + if (!avr_tstc()) + return 0; + + avr_button = avr_getc(); + switch (avr_button) { + case PWRP: + if (push_timeout(PWRR)) { + /* Timeout before power button release */ + boot_stop = ~boot_stop; + if (boot_stop) + miconCntl_SendCmd(PWRBLINKSTOP); + else + miconCntl_SendCmd(PWRBLINKSTRT); + /* Wait for power button release */ + while (avr_getc() != PWRR) + ; + } else + /* Power button released */ + next_boot_choice(); + break; + case RESP: + /* Wait for Reset button release */ + while (avr_getc() != RESR) + ; + next_cons_choice(cons_choice); + break; + case AVRINIT: + return 0; + default: + perror("Unexpected code: 0x%02X\n", avr_button); + return 0; + } + if (boot_stop) + return (-3); + else + return (-2); +} + +void avr_StopBoot(void) +{ + boot_stop = ~0; + miconCntl_SendCmd(PWRBLINKSTOP); +} diff --git a/u-boot/board/linkstation/hwctl.c b/u-boot/board/linkstation/hwctl.c new file mode 100644 index 0000000..9fd56ae --- /dev/null +++ b/u-boot/board/linkstation/hwctl.c @@ -0,0 +1,135 @@ +/* + * hwctl.c + * + * LinkStation HW Control Driver + * + * Copyright (C) 2001-2004 BUFFALO INC. + * + * This software may be used and distributed according to the terms of + * the GNU General Public License (GPL), incorporated herein by reference. + * Drivers based on or derived from this code fall under the GPL and must + * retain the authorship, copyright and license notice. This file is not + * a complete program and may only be used when the entire operating + * system is licensed under the GPL. + * + */ + +#include <config.h> +#include <common.h> +#include <command.h> +#include <asm/io.h> + +#define mdelay(n) udelay((n)*1000) + +#define AVR_PORT CONFIG_SYS_NS16550_COM2 + +/* 2005.5.10 BUFFALO add */ +/*--------------------------------------------------------------*/ +static inline void miconCntl_SendUart(unsigned char dat) +{ + out_8((unsigned char *)AVR_PORT, dat); + mdelay(1); +} + +/*--------------------------------------------------------------*/ +void miconCntl_SendCmd(unsigned char dat) +{ + int i; + + for (i=0; i<4; i++){ + miconCntl_SendUart(dat); + } +} + +/*--------------------------------------------------------------*/ +void miconCntl_FanLow(void) +{ +#ifdef CONFIG_HTGL + miconCntl_SendCmd(0x5C); +#endif +} + +/*--------------------------------------------------------------*/ +void miconCntl_FanHigh(void) +{ +#ifdef CONFIG_HTGL + miconCntl_SendCmd(0x5D); +#endif +} + +/*--------------------------------------------------------------*/ +/* 1000Mbps */ +void miconCntl_Eth1000M(int up) +{ +#ifdef CONFIG_HTGL + if (up) + miconCntl_SendCmd(0x93); + else + miconCntl_SendCmd(0x92); +#else + if (up) + miconCntl_SendCmd(0x5D); + else + miconCntl_SendCmd(0x5C); +#endif +} + +/*--------------------------------------------------------------*/ +/* 100Mbps */ +void miconCntl_Eth100M(int up) +{ +#ifdef CONFIG_HTGL + if (up) + miconCntl_SendCmd(0x91); + else + miconCntl_SendCmd(0x90); +#else + if (up) + miconCntl_SendCmd(0x5C); +#endif +} + +/*--------------------------------------------------------------*/ +/* 10Mbps */ +void miconCntl_Eth10M(int up) +{ +#ifdef CONFIG_HTGL + if (up) + miconCntl_SendCmd(0x8F); + else + miconCntl_SendCmd(0x8E); +#else + if (up) + miconCntl_SendCmd(0x5C); +#endif +} + +/*--------------------------------------------------------------*/ +/* */ +void miconCntl_5f(void) +{ + miconCntl_SendCmd(0x5F); + mdelay(100); +} + +/*--------------------------------------------------------------*/ +/* "reboot start" signal */ +void miconCntl_Reboot(void) +{ + miconCntl_SendCmd(0x43); +} + +/*--------------------------------------------------------------*/ +/* Disable watchdog timer */ +void miconCntl_DisWDT(void) +{ + miconCntl_SendCmd(0x41); /* A */ + miconCntl_SendCmd(0x46); /* F */ + miconCntl_SendCmd(0x4A); /* J */ + miconCntl_SendCmd(0x3E); /* > */ + miconCntl_SendCmd(0x56); /* V */ + miconCntl_SendCmd(0x3E); /* > */ + miconCntl_SendCmd(0x5A); /* Z */ + miconCntl_SendCmd(0x56); /* V */ + miconCntl_SendCmd(0x4B); /* K */ +} diff --git a/u-boot/board/linkstation/ide.c b/u-boot/board/linkstation/ide.c new file mode 100644 index 0000000..568fdf5 --- /dev/null +++ b/u-boot/board/linkstation/ide.c @@ -0,0 +1,101 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ +/* ide.c - ide support functions */ + + +#include <common.h> + +#ifdef CONFIG_CMD_IDE +#include <ata.h> +#include <ide.h> +#include <pci.h> + +#define IT8212_PCI_CpuCONTROL 0x5e +#define IT8212_PCI_PciModeCONTROL 0x50 +#define IT8212_PCI_IdeIoCONFIG 0x40 +#define IT8212_PCI_IdeBusSkewCONTROL 0x4c +#define IT8212_PCI_IdeDrivingCURRENT 0x42 + +extern ulong ide_bus_offset[CONFIG_SYS_IDE_MAXBUS]; +extern struct pci_controller hose; + +int ide_preinit (void) +{ + int status; + pci_dev_t devbusfn; + int l; + + status = 1; + for (l = 0; l < CONFIG_SYS_IDE_MAXBUS; l++) { + ide_bus_offset[l] = -ATA_STATUS; + } + devbusfn = pci_find_device(PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_680, 0); + if (devbusfn == -1) + devbusfn = pci_find_device(PCI_VENDOR_ID_ITE,PCI_DEVICE_ID_ITE_8212,0); + if (devbusfn != -1) { + u32 ide_bus_offset32; + + status = 0; + + pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_0, + &ide_bus_offset32); + ide_bus_offset[0] = ide_bus_offset32 & 0xfffffffe; + ide_bus_offset[0] = pci_hose_bus_to_phys(&hose, + ide_bus_offset[0] & 0xfffffffe, + PCI_REGION_IO); + pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_2, + (u32 *) &ide_bus_offset[1]); + ide_bus_offset[1] &= 0xfffffffe; + ide_bus_offset[1] = pci_hose_bus_to_phys(&hose, + ide_bus_offset[1] & 0xfffffffe, + PCI_REGION_IO); + } + + if (pci_find_device (PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8212, 0) != -1) { + pci_write_config_byte(devbusfn, IT8212_PCI_CpuCONTROL, 0x01); + pci_write_config_byte(devbusfn, IT8212_PCI_PciModeCONTROL, 0x00); + pci_write_config_word(devbusfn, PCI_COMMAND, 0x0047); +#ifdef CONFIG_IT8212_SECONDARY_ENABLE + pci_write_config_word(devbusfn, IT8212_PCI_IdeIoCONFIG, 0xA0F3); +#else + pci_write_config_word(devbusfn, IT8212_PCI_IdeIoCONFIG, 0x8031); +#endif + pci_write_config_dword(devbusfn, IT8212_PCI_IdeBusSkewCONTROL, 0x02040204); +/* __LS_COMMENT__ BUFFALO changed 2004.11.10 changed for EMI */ + pci_write_config_byte(devbusfn, IT8212_PCI_IdeDrivingCURRENT, 0x36); /* 10mA */ +/* pci_write_config_byte(dev, IT8212_PCI_IdeDrivingCURRENT, 0x09); */ /* 4mA */ +/* pci_write_config_byte(dev, IT8212_PCI_IdeDrivingCURRENT, 0x12); */ /* 6mA */ +/* pci_write_config_byte(dev, IT8212_PCI_IdeDrivingCURRENT, 0x24); */ /* 6mA,2mA */ +/* pci_write_config_byte(dev, IT8212_PCI_IdeDrivingCURRENT, 0x2D); */ /* 8mA,4mA */ + pci_write_config_byte(devbusfn, PCI_LATENCY_TIMER, 0x00); + } + + return (status); +} + +void ide_set_reset (int flag) { + return; +} + +#endif /* CONFIG_CMD_IDE */ diff --git a/u-boot/board/linkstation/linkstation.c b/u-boot/board/linkstation/linkstation.c new file mode 100644 index 0000000..e564e50 --- /dev/null +++ b/u-boot/board/linkstation/linkstation.c @@ -0,0 +1,137 @@ +/* + * linkstation.c + * + * Misc LinkStation specific functions + * + * Copyright (C) 2006 Mihai Georgian <u-boot@linuxnotincluded.org.uk> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <version.h> +#include <common.h> +#include <mpc824x.h> +#include <asm/io.h> +#include <ns16550.h> +#include <netdev.h> + +#ifdef CONFIG_PCI +#include <pci.h> +#endif + +DECLARE_GLOBAL_DATA_PTR; + +extern void init_AVR_DUART(void); + +int checkboard (void) +{ + char *p; + bd_t *bd = gd->bd; + + init_AVR_DUART(); + + if ((p = getenv ("console_nr")) != NULL) { + unsigned long con_nr = simple_strtoul (p, NULL, 10) & 3; + + bd->bi_baudrate &= ~3; + bd->bi_baudrate |= con_nr & 3; + } + return 0; +} + +phys_size_t initdram (int board_type) +{ + return (get_ram_size(CONFIG_SYS_SDRAM_BASE, CONFIG_SYS_MAX_RAM_SIZE)); +} + +/* + * Initialize PCI Devices + */ +#ifdef CONFIG_PCI + +#ifndef CONFIG_PCI_PNP + +static struct pci_config_table pci_linkstation_config_table[] = { + /* vendor, device, class */ + /* bus, dev, func */ + { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, + PCI_ANY_ID, 0x0b, 0, /* AN983B or RTL8110S */ + /* ethernet controller */ + pci_cfgfunc_config_device, { PCI_ETH_IOADDR, + PCI_ETH_MEMADDR, + PCI_COMMAND_IO | + PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER }}, + { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, + PCI_ANY_ID, 0x0c, 0, /* SII680 or IT8211AF */ + /* ide controller */ + pci_cfgfunc_config_device, { PCI_IDE_IOADDR, + PCI_IDE_MEMADDR, + PCI_COMMAND_IO | + PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER }}, + { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, + PCI_ANY_ID, 0x0e, 0, /* D720101 USB controller, 1st USB 1.1 */ + pci_cfgfunc_config_device, { PCI_USB0_IOADDR, + PCI_USB0_MEMADDR, + PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER }}, + { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, + PCI_ANY_ID, 0x0e, 1, /* D720101 USB controller, 2nd USB 1.1 */ + pci_cfgfunc_config_device, { PCI_USB1_IOADDR, + PCI_USB1_MEMADDR, + PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER }}, + { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, + PCI_ANY_ID, 0x0e, 2, /* D720101 USB controller, USB 2.0 */ + pci_cfgfunc_config_device, { PCI_USB2_IOADDR, + PCI_USB2_MEMADDR, + PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER }}, + { } +}; +#endif + +struct pci_controller hose = { +#ifndef CONFIG_PCI_PNP + config_table:pci_linkstation_config_table, +#endif +}; + +void pci_init_board (void) +{ + pci_mpc824x_init (&hose); + + /* Reset USB 1.1 */ + /* Haven't seen any change without these on a HG, maybe it is + * needed on other models */ + out_le32((volatile unsigned*)(PCI_USB0_MEMADDR + 8), 1); + out_le32((volatile unsigned*)(PCI_USB1_MEMADDR + 8), 1); +} +#endif /* CONFIG_PCI */ + +#define UART_DCR 0x80004511 +int board_early_init_f (void) +{ + /* set DUART mode */ + out_8((volatile u8*)UART_DCR, 1); + return 0; +} + +int board_eth_init(bd_t *bis) +{ + return pci_eth_init(bis); +} |