From 2262cfeef91458b01a1bfe3812ccbbfdf8b82807 Mon Sep 17 00:00:00 2001 From: wdenk Date: Mon, 18 Nov 2002 00:14:45 +0000 Subject: * Patch by Daniel Engström, 13 Nov 2002: Add support for i386 architecture and AMD SC520 board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Patch by Pierre Aubert, 12 Nov 2002: Add support for DOS filesystem and booting from DOS floppy disk --- board/sc520_cdp/Makefile | 47 ++++ board/sc520_cdp/config.mk | 25 +++ board/sc520_cdp/flash.c | 449 ++++++++++++++++++++++++++++++++++++++ board/sc520_cdp/sc520_cdp.c | 288 ++++++++++++++++++++++++ board/sc520_cdp/sc520_cdp_asm.S | 86 ++++++++ board/sc520_cdp/sc520_cdp_asm16.S | 62 ++++++ board/sc520_cdp/u-boot.lds | 85 ++++++++ 7 files changed, 1042 insertions(+) create mode 100644 board/sc520_cdp/Makefile create mode 100644 board/sc520_cdp/config.mk create mode 100644 board/sc520_cdp/flash.c create mode 100644 board/sc520_cdp/sc520_cdp.c create mode 100644 board/sc520_cdp/sc520_cdp_asm.S create mode 100644 board/sc520_cdp/sc520_cdp_asm16.S create mode 100644 board/sc520_cdp/u-boot.lds (limited to 'board') diff --git a/board/sc520_cdp/Makefile b/board/sc520_cdp/Makefile new file mode 100644 index 0000000000..0f50393468 --- /dev/null +++ b/board/sc520_cdp/Makefile @@ -0,0 +1,47 @@ +# +# (C) Copyright 2002 +# Daniel Engström, Omicron Ceti AB, daniel@omicron.se. +# +# 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 = lib$(BOARD).a + +OBJS := sc520_cdp.o flash.o +SOBJS := sc520_cdp_asm.o sc520_cdp_asm16.o + +$(LIB): $(OBJS) $(SOBJS) + $(AR) crv $@ $^ + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak .depend + +######################################################################### + +.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) + $(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@ + +-include .depend + +######################################################################### diff --git a/board/sc520_cdp/config.mk b/board/sc520_cdp/config.mk new file mode 100644 index 0000000000..d4cd9986d6 --- /dev/null +++ b/board/sc520_cdp/config.mk @@ -0,0 +1,25 @@ +# +# (C) Copyright 2002 +# Daniel Engström, Omicron Ceti AB, daniel@omicron.se. +# +# 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 +# + + +TEXT_BASE = 0x387e0000 diff --git a/board/sc520_cdp/flash.c b/board/sc520_cdp/flash.c new file mode 100644 index 0000000000..e43451286f --- /dev/null +++ b/board/sc520_cdp/flash.c @@ -0,0 +1,449 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * 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 + +ulong myflush(void); + + +#define FLASH_BANK_SIZE 0x400000 /* 4 MB */ +#define MAIN_SECT_SIZE 0x20000 /* 128 KB */ + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; + + +#define CMD_READ_ARRAY 0x00F000F0 +#define CMD_UNLOCK1 0x00AA00AA +#define CMD_UNLOCK2 0x00550055 +#define CMD_ERASE_SETUP 0x00800080 +#define CMD_ERASE_CONFIRM 0x00300030 +#define CMD_PROGRAM 0x00A000A0 +#define CMD_UNLOCK_BYPASS 0x00200020 + +#define MEM_FLASH_ADDR1 (*(volatile u32 *)(CFG_FLASH_BASE + (0x00000555 << 2))) +#define MEM_FLASH_ADDR2 (*(volatile u32 *)(CFG_FLASH_BASE + (0x000002AA << 2))) + +#define BIT_ERASE_DONE 0x00800080 +#define BIT_RDY_MASK 0x00800080 +#define BIT_PROGRAM_ERROR 0x00200020 +#define BIT_TIMEOUT 0x80000000 /* our flag */ + +#define READY 1 +#define ERR 2 +#define TMO 4 + +/*----------------------------------------------------------------------- + */ + +ulong flash_init(void) +{ + int i, j; + ulong size = 0; + + for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) + { + ulong flashbase = 0; + flash_info[i].flash_id = + (AMD_MANUFACT & FLASH_VENDMASK) | + (AMD_ID_LV160B & FLASH_TYPEMASK); + flash_info[i].size = FLASH_BANK_SIZE; + flash_info[i].sector_count = CFG_MAX_FLASH_SECT; + memset(flash_info[i].protect, 0, CFG_MAX_FLASH_SECT); + if (i == 0) + flashbase = PHYS_FLASH_1; + else + panic("configured to many flash banks!\n"); + for (j = 0; j < flash_info[i].sector_count; j++) + { + + if (j <= 3) + { + /* 1st one is 32 KB */ + if (j == 0) + { + flash_info[i].start[j] = flashbase + 0; + } + + /* 2nd and 3rd are both 16 KB */ + if ((j == 1) || (j == 2)) + { + flash_info[i].start[j] = flashbase + 0x8000 + (j-1)*0x4000; + } + + /* 4th 64 KB */ + if (j == 3) + { + flash_info[i].start[j] = flashbase + 0x10000; + } + } + else + { + flash_info[i].start[j] = flashbase + (j - 3)*MAIN_SECT_SIZE; + } + } + size += flash_info[i].size; + } + + /* + * Protect monitor and environment sectors + */ + flash_protect(FLAG_PROTECT_SET, + i386boot_start-CFG_FLASH_BASE, + i386boot_end-CFG_FLASH_BASE, + &flash_info[0]); + + flash_protect(FLAG_PROTECT_SET, + CFG_ENV_ADDR, + CFG_ENV_ADDR + CFG_ENV_SIZE - 1, + &flash_info[0]); + return size; +} + +/*----------------------------------------------------------------------- + */ +void flash_print_info (flash_info_t *info) +{ + int i; + + switch (info->flash_id & FLASH_VENDMASK) + { + case (AMD_MANUFACT & FLASH_VENDMASK): + printf("AMD: "); + break; + default: + printf("Unknown Vendor "); + break; + } + + switch (info->flash_id & FLASH_TYPEMASK) + { + case (AMD_ID_LV160B & FLASH_TYPEMASK): + printf("2x Amd29F160BB (16Mbit)\n"); + break; + default: + printf("Unknown Chip Type\n"); + goto Done; + break; + } + + printf(" Size: %ld MB in %d Sectors\n", + info->size >> 20, info->sector_count); + + printf(" Sector Start Addresses:"); + for (i = 0; i < info->sector_count; i++) + { + if ((i % 5) == 0) + { + printf ("\n "); + } + printf (" %08lX%s", info->start[i], + info->protect[i] ? " (RO)" : " "); + } + printf ("\n"); + +Done: +} + +/*----------------------------------------------------------------------- + */ + +int flash_erase (flash_info_t *info, int s_first, int s_last) +{ + ulong result; + int iflag, cflag, prot, sect; + int rc = ERR_OK; + int chip1, chip2; + + /* first look for protection bits */ + + if (info->flash_id == FLASH_UNKNOWN) + return ERR_UNKNOWN_FLASH_TYPE; + + if ((s_first < 0) || (s_first > s_last)) { + return ERR_INVAL; + } + + if ((info->flash_id & FLASH_VENDMASK) != + (AMD_MANUFACT & FLASH_VENDMASK)) { + return ERR_UNKNOWN_FLASH_VENDOR; + } + + prot = 0; + for (sect=s_first; sect<=s_last; ++sect) { + if (info->protect[sect]) { + prot++; + } + } + if (prot) + return ERR_PROTECTED; + + /* + * Disable interrupts which might cause a timeout + * here. Remember that our exception vectors are + * at address 0 in the flash, and we don't want a + * (ticker) exception to happen while the flash + * chip is in programming mode. + */ + iflag = disable_interrupts(); + + /* Start erase on unprotected sectors */ + for (sect = s_first; sect<=s_last && !ctrlc(); sect++) + { + printf("Erasing sector %2d ... ", sect); + + /* arm simple, non interrupt dependent timer */ + reset_timer(); + + if (info->protect[sect] == 0) + { /* not protected */ + vu_long *addr = (vu_long *)(info->start[sect]); + + MEM_FLASH_ADDR1 = CMD_UNLOCK1; + MEM_FLASH_ADDR2 = CMD_UNLOCK2; + MEM_FLASH_ADDR1 = CMD_ERASE_SETUP; + + MEM_FLASH_ADDR1 = CMD_UNLOCK1; + MEM_FLASH_ADDR2 = CMD_UNLOCK2; + *addr = CMD_ERASE_CONFIRM; + + /* wait until flash is ready */ + chip1 = chip2 = 0; + + do + { + result = *addr; + + /* check timeout */ + if (get_timer(0) > CFG_FLASH_ERASE_TOUT) + { + MEM_FLASH_ADDR1 = CMD_READ_ARRAY; + chip1 = TMO; + break; + } + + if (!chip1 && (result & 0xFFFF) & BIT_ERASE_DONE) + chip1 = READY; + + if (!chip1 && (result & 0xFFFF) & BIT_PROGRAM_ERROR) + chip1 = ERR; + + if (!chip2 && (result >> 16) & BIT_ERASE_DONE) + chip2 = READY; + + if (!chip2 && (result >> 16) & BIT_PROGRAM_ERROR) + chip2 = ERR; + + } while (!chip1 || !chip2); + + MEM_FLASH_ADDR1 = CMD_READ_ARRAY; + + if (chip1 == ERR || chip2 == ERR) + { + rc = ERR_PROG_ERROR; + goto outahere; + } + if (chip1 == TMO) + { + rc = ERR_TIMOUT; + goto outahere; + } + + printf("ok.\n"); + } + else /* it was protected */ + { + printf("protected!\n"); + } + } + + if (ctrlc()) + printf("User Interrupt!\n"); + +outahere: + /* allow flash to settle - wait 10 ms */ + udelay(10000); + + if (iflag) + enable_interrupts(); + + + return rc; +} + +/*----------------------------------------------------------------------- + * Copy memory to flash + */ + +volatile static int write_word (flash_info_t *info, ulong dest, ulong data) +{ + vu_long *addr = (vu_long *)dest; + ulong result; + int rc = ERR_OK; + int iflag; + int chip1, chip2; + + /* + * Check if Flash is (sufficiently) erased + */ + result = *addr; + if ((result & data) != data) + return ERR_NOT_ERASED; + + + /* + * Disable interrupts which might cause a timeout + * here. Remember that our exception vectors are + * at address 0 in the flash, and we don't want a + * (ticker) exception to happen while the flash + * chip is in programming mode. + */ + iflag = disable_interrupts(); + + MEM_FLASH_ADDR1 = CMD_UNLOCK1; + MEM_FLASH_ADDR2 = CMD_UNLOCK2; + MEM_FLASH_ADDR1 = CMD_UNLOCK_BYPASS; + *addr = CMD_PROGRAM; + *addr = data; + + /* arm simple, non interrupt dependent timer */ + reset_timer(); + + /* wait until flash is ready */ + chip1 = chip2 = 0; + do + { + result = *addr; + + /* check timeout */ + if (get_timer(0) > CFG_FLASH_ERASE_TOUT) + { + chip1 = ERR | TMO; + break; + } + if (!chip1 && ((result & 0x80) == (data & 0x80))) + chip1 = READY; + + if (!chip1 && ((result & 0xFFFF) & BIT_PROGRAM_ERROR)) + { + result = *addr; + + if ((result & 0x80) == (data & 0x80)) + chip1 = READY; + else + chip1 = ERR; + } + + if (!chip2 && ((result & (0x80 << 16)) == (data & (0x80 << 16)))) + chip2 = READY; + + if (!chip2 && ((result >> 16) & BIT_PROGRAM_ERROR)) + { + result = *addr; + + if ((result & (0x80 << 16)) == (data & (0x80 << 16))) + chip2 = READY; + else + chip2 = ERR; + } + + } while (!chip1 || !chip2); + + *addr = CMD_READ_ARRAY; + + if (chip1 == ERR || chip2 == ERR || *addr != data) + rc = ERR_PROG_ERROR; + + if (iflag) + enable_interrupts(); + + + return rc; +} + +/*----------------------------------------------------------------------- + * Copy memory to flash. + */ + +int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) +{ + ulong cp, wp, data; + int l; + int i, rc; + + wp = (addr & ~3); /* get lower word aligned address */ + + /* + * handle unaligned start bytes + */ + if ((l = addr - wp) != 0) { + data = 0; + for (i=0, cp=wp; i> 8) | (*(uchar *)cp << 24); + } + for (; i<4 && cnt>0; ++i) { + data = (data >> 8) | (*src++ << 24); + --cnt; + ++cp; + } + for (; cnt==0 && i<4; ++i, ++cp) { + data = (data >> 8) | (*(uchar *)cp << 24); + } + + if ((rc = write_word(info, wp, data)) != 0) { + return (rc); + } + wp += 4; + } + + /* + * handle word aligned part + */ + while (cnt >= 4) { + data = *((vu_long*)src); + if ((rc = write_word(info, wp, data)) != 0) { + return (rc); + } + src += 4; + wp += 4; + cnt -= 4; + } + + if (cnt == 0) { + return ERR_OK; + } + + /* + * handle unaligned tail bytes + */ + data = 0; + for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) { + data = (data >> 8) | (*src++ << 24); + --cnt; + } + for (; i<4; ++i, ++cp) { + data = (data >> 8) | (*(uchar *)cp << 24); + } + + return write_word(info, wp, data); +} diff --git a/board/sc520_cdp/sc520_cdp.c b/board/sc520_cdp/sc520_cdp.c new file mode 100644 index 0000000000..cc818d2660 --- /dev/null +++ b/board/sc520_cdp/sc520_cdp.c @@ -0,0 +1,288 @@ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB . + * + * 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 +#include +#include +#include +#include + +/* ------------------------------------------------------------------------- */ + +static void irq_init(void) +{ + + /* disable global interrupt mode */ + write_mmcr_byte(SC520_PICICR, 0x40); + + /* set irq0-7 to edge */ + write_mmcr_byte(SC520_MPICMODE, 0x00); + + /* set irq9-12 to level, all the other (8, 13-15) are edge */ + write_mmcr_byte(SC520_SL1PICMODE, 0x1e); + + /* set irq16-24 (unused slave pic2) to level */ + write_mmcr_byte(SC520_SL2PICMODE, 0xff); + + /* active low polarity on PIC interrupt pins, + active high polarity on all other irq pins */ + write_mmcr_word(SC520_INTPINPOL, 0); + + /* set irq number mapping */ + write_mmcr_byte(SC520_GPTMR0MAP,0); /* disable GP timer 0 INT */ + write_mmcr_byte(SC520_GPTMR1MAP,0); /* disable GP timer 1 INT */ + write_mmcr_byte(SC520_GPTMR2MAP,0); /* disable GP timer 2 INT */ + write_mmcr_byte(SC520_PIT0MAP,0x1); /* Set PIT timer 0 INT to IRQ0 */ + write_mmcr_byte(SC520_PIT1MAP,0); /* diable PIT timer 1 INT */ + write_mmcr_byte(SC520_PIT2MAP,0); /* diable PIT timer 2 INT */ + write_mmcr_byte(SC520_PCIINTAMAP,0x4); /* Set PCI INT A to IRQ9 */ + write_mmcr_byte(SC520_PCIINTBMAP,0x5); /* Set PCI INT B to IRQ10 */ + write_mmcr_byte(SC520_PCIINTCMAP,0x6); /* Set PCI INT C to IRQ11 */ + write_mmcr_byte(SC520_PCIINTDMAP,0x7); /* Set PCI INT D to IRQ12 */ + write_mmcr_byte(SC520_DMABCINTMAP,0); /* disable DMA INT */ + write_mmcr_byte(SC520_SSIMAP,0); /* disable Synchronius serial INT */ + write_mmcr_byte(SC520_WDTMAP,0); /* disable Watchdor INT */ + write_mmcr_byte(SC520_RTCMAP,0x3); /* Set RTC int to 8 */ + write_mmcr_byte(SC520_WPVMAP,0); /* disable write protect INT */ + write_mmcr_byte(SC520_ICEMAP,0x2); /* Set ICE Debug Serielport INT to IRQ1 */ + write_mmcr_byte(SC520_FERRMAP,0x8); /* Set FP error INT to IRQ13 */ + write_mmcr_byte(SC520_GP0IMAP,6); /* Set GPIRQ0 (ISA IRQ2) to IRQ9 */ + write_mmcr_byte(SC520_GP1IMAP,2); /* Set GPIRQ1 (SIO IRQ1) to IRQ1 */ + write_mmcr_byte(SC520_GP2IMAP,7); /* Set GPIRQ2 (ISA IRQ12) to IRQ12 */ + + if (CFG_USE_SIO_UART) { + write_mmcr_byte(SC520_UART1MAP,0); /* disable internal UART1 INT */ + write_mmcr_byte(SC520_UART2MAP,0); /* disable internal UART2 INT */ + write_mmcr_byte(SC520_GP3IMAP,11); /* Set GPIRQ3 (ISA IRQ3) to IRQ3 */ + write_mmcr_byte(SC520_GP4IMAP,12); /* Set GPIRQ4 (ISA IRQ4) to IRQ4 */ + } else { + write_mmcr_byte(SC520_UART1MAP,12); /* Set internal UART2 INT to IRQ4 */ + write_mmcr_byte(SC520_UART2MAP,11); /* Set internal UART2 INT to IRQ3 */ + write_mmcr_byte(SC520_GP3IMAP,0); /* disable GPIRQ3 (ISA IRQ3) */ + write_mmcr_byte(SC520_GP4IMAP,0); /* disable GPIRQ4 (ISA IRQ4) */ + } + + write_mmcr_byte(SC520_GP5IMAP,13); /* Set GPIRQ5 (ISA IRQ5) to IRQ5 */ + write_mmcr_byte(SC520_GP6IMAP,21); /* Set GPIRQ6 (ISA IRQ6) to IRQ6 */ + write_mmcr_byte(SC520_GP7IMAP,22); /* Set GPIRQ7 (ISA IRQ7) to IRQ7 */ + write_mmcr_byte(SC520_GP8IMAP,3); /* Set GPIRQ8 (SIO IRQ8) to IRQ8 */ + write_mmcr_byte(SC520_GP9IMAP,4); /* Set GPIRQ9 (ISA IRQ9) to IRQ9 */ + write_mmcr_byte(SC520_GP10IMAP,9); /* Set GPIRQ10 (ISA IRQ10) to IRQ10 */ + write_mmcr_word(SC520_PCIHOSTMAP,0x11f); /* Map PCI hostbridge INT to NMI */ + write_mmcr_word(SC520_ECCMAP,0x100); /* Map SDRAM ECC failure INT to NMI */ + +} + +/* PCI stuff */ +static void pci_sc520_cdp_fixup_irq(struct pci_controller *hose, pci_dev_t dev) +{ + char pin; + int irq; + + + pci_hose_read_config_byte(hose, dev, PCI_INTERRUPT_PIN, &pin); + irq = pin-1; + + switch (PCI_DEV(dev)) { + case 20: + break; + case 19: + irq+=1; + break; + case 18: + irq+=2; + break; + case 17: + irq+=3; + break; + default: + return; + } + + irq&=3; /* wrap around */ + irq+=9; /* lowest IRQ is 9 */ + + pci_hose_write_config_byte(hose, dev, PCI_INTERRUPT_LINE, irq); +#if 0 + printf("fixup_irq: device %d pin %c irq %d\n", + PCI_DEV(dev), 'A' + pin -1, irq); +#endif +} + +static struct pci_controller sc520_cdp_hose = { + fixup_irq: pci_sc520_cdp_fixup_irq, +}; + +void pci_init(void) +{ + pci_sc520_init(&sc520_cdp_hose); +} + + +static void silence_uart(int port) +{ + outb(0, port+1); +} + +void setup_ali_sio(int uart_primary) +{ + ali512x_init(); + + ali512x_set_fdc(ALI_ENABLED, 0x3f2, 6, 0); + ali512x_set_pp(ALI_ENABLED, 0x278, 7, 3); + ali512x_set_uart(ALI_ENABLED, ALI_UART1, uart_primary?0x3f8:0x3e8, 4); + ali512x_set_uart(ALI_ENABLED, ALI_UART2, uart_primary?0x2f8:0x2e8, 3); + ali512x_set_rtc(ALI_DISABLED, 0, 0); + ali512x_set_kbc(ALI_ENABLED, 1, 12); + ali512x_set_cio(ALI_ENABLED); + + /* IrDa pins */ + ali512x_cio_function(12, 1, 0, 0); + ali512x_cio_function(13, 1, 0, 0); + + /* SSI chip select pins */ + ali512x_cio_function(14, 0, 0, 0); /* SSI_CS */ + ali512x_cio_function(15, 0, 0, 0); /* SSI_MV */ + ali512x_cio_function(16, 0, 1, 0); /* SSI_SPI# (inverted) */ + + /* Board REV pins */ + ali512x_cio_function(20, 0, 0, 1); + ali512x_cio_function(21, 0, 0, 1); + ali512x_cio_function(22, 0, 0, 1); + ali512x_cio_function(23, 0, 0, 1); +} + + +/* set up the ISA bus timing and system address mappings */ +static void bus_init(void) +{ + + /* set up the GP IO pins */ + write_mmcr_word(SC520_PIOPFS31_16, 0xf7ff); /* set the GPIO pin function 31-16 reg */ + write_mmcr_word(SC520_PIOPFS15_0, 0xffff); /* set the GPIO pin function 15-0 reg */ + write_mmcr_byte(SC520_CSPFS, 0xf8); /* set the CS pin function reg */ + write_mmcr_byte(SC520_CLKSEL, 0x70); + + + write_mmcr_byte(SC520_GPCSRT, 1); /* set the GP CS offset */ + write_mmcr_byte(SC520_GPCSPW, 3); /* set the GP CS pulse width */ + write_mmcr_byte(SC520_GPCSOFF, 1); /* set the GP CS offset */ + write_mmcr_byte(SC520_GPRDW, 3); /* set the RD pulse width */ + write_mmcr_byte(SC520_GPRDOFF, 1); /* set the GP RD offset */ + write_mmcr_byte(SC520_GPWRW, 3); /* set the GP WR pulse width */ + write_mmcr_byte(SC520_GPWROFF, 1); /* set the GP WR offset */ + + write_mmcr_word(SC520_BOOTCSCTL, 0x1823); /* set up timing of BOOTCS */ + write_mmcr_word(SC520_ROMCS1CTL, 0x1823); /* set up timing of ROMCS1 */ + write_mmcr_word(SC520_ROMCS2CTL, 0x1823); /* set up timing of ROMCS2 */ + + /* adjust the memory map: + * by default the first 256MB (0x00000000 - 0x0fffffff) is mapped to SDRAM + * and 256MB to 1G-128k (0x1000000 - 0x37ffffff) is mapped to PCI mmio + * we need to map 1G-128k - 1G (0x38000000 - 0x3fffffff) to CS1 */ + + + /* SRAM = GPCS3 128k @ d0000-effff*/ + write_mmcr_long(SC520_PAR2, 0x4e00400d); + + /* IDE0 = GPCS6 1f0-1f7 */ + write_mmcr_long(SC520_PAR3, 0x380801f0); + + /* IDE1 = GPCS7 3f6 */ + write_mmcr_long(SC520_PAR4, 0x3c0003f6); + /* bootcs */ + write_mmcr_long(SC520_PAR12, 0x8bffe800); + /* romcs2 */ + write_mmcr_long(SC520_PAR13, 0xcbfff000); + /* romcs1 */ + write_mmcr_long(SC520_PAR14, 0xabfff800); + /* 680 LEDS */ + write_mmcr_long(SC520_PAR15, 0x30000640); + + asm ("wbinvd\n"); /* Flush cache, req. after setting the unchached attribute ona PAR */ + + if (CFG_USE_SIO_UART) { + write_mmcr_byte(SC520_ADDDECCTL, read_mmcr_byte(SC520_ADDDECCTL) | UART2_DIS|UART1_DIS); + setup_ali_sio(1); + } else { + write_mmcr_byte(SC520_ADDDECCTL, read_mmcr_byte(SC520_ADDDECCTL) & ~(UART2_DIS|UART1_DIS)); + setup_ali_sio(0); + silence_uart(0x3e8); + silence_uart(0x2e8); + } + +} + + + +/* + * Miscelaneous platform dependent initialisations + */ + +int board_init(void) +{ + DECLARE_GLOBAL_DATA_PTR; + + init_sc520(); + bus_init(); + irq_init(); + + /* max drive current on SDRAM */ + write_mmcr_word(SC520_DSCTL, 0x0100); + + /* enter debug mode after next reset (only if jumper is also set) */ + write_mmcr_byte(SC520_RESCFG, 0x08); + + /* configure the software timer to 33.333MHz */ + write_mmcr_byte(SC520_SWTMRCFG, 0); + gd->bus_clk = 33333000; + + return 0; +} + +int dram_init(void) +{ + init_sc520_dram(); + return 0; +} + +void show_boot_progress(int val) +{ + outb(val&0xff, 0x80); + outb((val&0xff00)>>8, 0x680); +} + + +int last_stage_init(void) +{ + int minor; + int major; + + major = minor = 0; + major |= ali512x_cio_in(23)?2:0; + major |= ali512x_cio_in(22)?1:0; + minor |= ali512x_cio_in(21)?2:0; + minor |= ali512x_cio_in(20)?1:0; + + printf("AMD SC520 CDP revision %d.%d\n", major, minor); +} diff --git a/board/sc520_cdp/sc520_cdp_asm.S b/board/sc520_cdp/sc520_cdp_asm.S new file mode 100644 index 0000000000..1e255fab2e --- /dev/null +++ b/board/sc520_cdp/sc520_cdp_asm.S @@ -0,0 +1,86 @@ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB . + * + * 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 + */ + +/* now setup the General purpose bus to give us access to the LEDs. + * We can then use the leds to display status information. + */ + +sc520_cdp_registers: +/* size offset value */ +.word 1 ; .word 0x040 ; .long 0x00 /* SDRAM buffer control */ +.word 2 ; .word 0xc08 ; .long 0x0001 /* GP CS offset */ +.word 2 ; .word 0xc09 ; .long 0x0003 /* GP CS width */ +.word 2 ; .word 0xc0a ; .long 0x0001 /* GP CS width */ +.word 2 ; .word 0xc0b ; .long 0x0003 /* GP RD pulse width */ +.word 2 ; .word 0xc0c ; .long 0x0001 /* GP RD offse */ +.word 2 ; .word 0xc0d ; .long 0x0003 /* GP WR pulse width */ +.word 2 ; .word 0xc0e ; .long 0x0001 /* GP WR offset */ +.word 2 ; .word 0xc2c ; .long 0x0000 /* GPIO directionreg */ +.word 2 ; .word 0xc2a ; .long 0x0000 /* GPIO directionreg */ +.word 2 ; .word 0xc22 ; .long 0xffff /* GPIO pin function 31-16 reg */ +.word 2 ; .word 0xc20 ; .long 0xffff /* GPIO pin function 15-0 reg */ +.word 2 ; .word 0x0c4 ; .long 0x28000680 /* PAR 15 for access to led 680 */ +.word 0 ; .word 0x000 ; .long 0x00 + +/* board early intialization */ +.globl early_board_init +early_board_init: + movl $sc520_cdp_registers,%esi +init_loop: + movl $0xfffef000,%edi /* MMCR base to edi */ + movw (%esi), %bx /* load sizer to bx */ + cmpw $0, %bx /* if sie is 0 we're done */ + je done + xorl %edx,%edx + movw 2(%esi), %dx /* load MMCR offset to dx */ + addl %edx, %edi /* add offset to base in edi */ + movl 4(%esi), %eax /* load value in eax */ + cmpw $1, %bx + je byte /* byte op? */ + cmpw $2, %bx + je word /* word op? */ + movl %eax, (%edi) /* must be long, then */ + jmp next +byte: movb %al,(%edi) + jmp next +word: movw %ax,(%edi) +next: addl $8, %esi /* advance esi */ + jmp init_loop + + /* the leds ad 0x80 and 0x680 should now work */ +done: movb $0x88, %al + out %al, $0x80 + movw $0x680, %dx + out %al, %dx + + jmp *%ebp /* return to caller */ + + +.globl __show_boot_progress +__show_boot_progress: + out %al, $0x80 + xchg %al, %ah + movw $0x680, %dx + out %al, %dx + jmp *%ebp + diff --git a/board/sc520_cdp/sc520_cdp_asm16.S b/board/sc520_cdp/sc520_cdp_asm16.S new file mode 100644 index 0000000000..a3cadcfa54 --- /dev/null +++ b/board/sc520_cdp/sc520_cdp_asm16.S @@ -0,0 +1,62 @@ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB . + * + * 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 + */ + +/* + * 16bit initialization code. + * This code have to map the area of the boot flash + * that is used by U-boot to its final destination. + */ + +.text +.section .start16, "ax" +.code16 +.globl board_init16 +board_init16: + /* Alias MMCR to 0xdf000 */ + movw $0xfffc, %dx + movl $0x800df0cb, %eax + outl %eax, %dx + + /* Set ds to point to MMCR alias */ + movw $0xdf00, %ax + movw %ax, %ds + + /* Map the entire flash at 0x38000000 + * (with BOOTCS and PAR14, use 0xabfff800 for ROMCS1) */ + movl $0xc0, %edi + movl $0x8bfff800, %eax + movl %eax, (%di) + + /* Disable SDRAM write buffer */ + movw $0x40,%di + xorw %ax,%ax + movb %al, (%di) + + /* Disabe MMCR alias */ + movw $0xfffc, %dx + movl $0x000000cb, %eax + outl %eax, %dx + + /* the return address is tored in bp */ + jmp *%bp + diff --git a/board/sc520_cdp/u-boot.lds b/board/sc520_cdp/u-boot.lds new file mode 100644 index 0000000000..ac8d3dbecd --- /dev/null +++ b/board/sc520_cdp/u-boot.lds @@ -0,0 +1,85 @@ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, daniel@omicron.se. + * + * 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 + */ + +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") +OUTPUT_ARCH(i386) +ENTRY(_start) + +SECTIONS +{ + . = 0x387e0000; /* Where bootcode in the flash is mapped */ + .text : { *(.text); } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = 0x400000; /* Ram data segment to use */ + _i386boot_romdata_dest = ABSOLUTE(.); + .data : AT ( LOADADDR(.rodata) + SIZEOF(.rodata) ) { *(.data) } + _i386boot_romdata_start = LOADADDR(.data); + + . = ALIGN(4); + .got : AT ( LOADADDR(.data) + SIZEOF(.data) ) { *(.got) } + _i386boot_romdata_size = SIZEOF(.data) + SIZEOF(.got); + + + . = ALIGN(4); + _i386boot_bss_start = ABSOLUTE(.); + .bss : { *(.bss) } + _i386boot_bss_size = SIZEOF(.bss); + + + /* 16bit realmode trampoline code */ + .realmode 0x7c0 : AT ( LOADADDR(.got) + SIZEOF(.got) ) { *(.realmode) } + + _i386boot_realmode = LOADADDR(.realmode); + _i386boot_realmode_size = SIZEOF(.realmode); + + /* 16bit BIOS emulation code (just enough to boot Linux) */ + .bios 0 : AT ( LOADADDR(.realmode) + SIZEOF(.realmode) ) { *(.bios) } + + _i386boot_bios = LOADADDR(.bios); + _i386boot_bios_size = SIZEOF(.bios); + + + /* The load addresses below assumes that the flash + * will be mapped so that 0x387f0000 == 0xffff0000 + * at reset time + * + * The fe00 and ff00 offsets of the start32 and start16 + * segments are arbitrary, the just have to be mapped + * at reset and the code have to fit. + * The fff0 offset of reset is important, however. + */ + + + . = 0xfffffe00; + .start32 : AT (0x387ffe00) { *(.start32); } + + . = 0xff00; + .start16 : AT (0x387fff00) { *(.start16); } + + . = 0xfff0; + .reset : AT (0x387ffff0) { *(.reset); } + _i386boot_end = (LOADADDR(.reset) + SIZEOF(.reset) ); +} -- cgit