diff options
Diffstat (limited to 'qemu/roms/u-boot/board/jse')
-rw-r--r-- | qemu/roms/u-boot/board/jse/Makefile | 12 | ||||
-rw-r--r-- | qemu/roms/u-boot/board/jse/README.txt | 48 | ||||
-rw-r--r-- | qemu/roms/u-boot/board/jse/flash.c | 491 | ||||
-rw-r--r-- | qemu/roms/u-boot/board/jse/host_bridge.c | 77 | ||||
-rw-r--r-- | qemu/roms/u-boot/board/jse/init.S | 75 | ||||
-rw-r--r-- | qemu/roms/u-boot/board/jse/jse.c | 147 | ||||
-rw-r--r-- | qemu/roms/u-boot/board/jse/jse_priv.h | 12 | ||||
-rw-r--r-- | qemu/roms/u-boot/board/jse/sdram.c | 169 |
8 files changed, 1031 insertions, 0 deletions
diff --git a/qemu/roms/u-boot/board/jse/Makefile b/qemu/roms/u-boot/board/jse/Makefile new file mode 100644 index 000000000..feac3a883 --- /dev/null +++ b/qemu/roms/u-boot/board/jse/Makefile @@ -0,0 +1,12 @@ +# +# (C) Copyright 2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# Copyright 2004 Picture Elements, Inc. +# Stephen Williams <steve@icarus.com> +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y = jse.o sdram.o flash.o host_bridge.o +obj-y += init.o diff --git a/qemu/roms/u-boot/board/jse/README.txt b/qemu/roms/u-boot/board/jse/README.txt new file mode 100644 index 000000000..84497db70 --- /dev/null +++ b/qemu/roms/u-boot/board/jse/README.txt @@ -0,0 +1,48 @@ +JSE Configuration Details + +Memory Bank 0 -- Flash chip +--------------------------- + +0xfff00000 - 0xffffffff + +The flash chip is really only 512Kbytes, but the high address bit of +the 1Meg region is ignored, so the flash is replicated through the +region. Thus, this is consistent with a flash base address 0xfff80000. + +The placement at the end is to be consistent with reset behavior, +where the processor itself initially uses this bus to load the branch +vector and start running. + +On-Chip Memory +-------------- + +0xf4000000 - 0xf4000fff + +The 405GPr includes a 4K on-chip memory that can be placed however +software chooses. I choose to place the memory at this address, to +keep it out of the cachable areas. + + +Memory Bank 1 -- SystemACE Controller +------------------------------------- + +0xf0000000 - 0xf00fffff + +The SystemACE chip is along on peripheral bank CS#1. We don't need +much space, but 1Meg is the smallest we can configure the chip to +allocate. We need it far away from the flash region, because this +region is set to be non-cached. + + +Internal Peripherals +-------------------- + +0xef600300 - 0xef6008ff + +These are scattered various peripherals internal to the PPC405GPr +chip. + +SDRAM +----- + +0x00000000 - 0x07ffffff (128 MBytes) diff --git a/qemu/roms/u-boot/board/jse/flash.c b/qemu/roms/u-boot/board/jse/flash.c new file mode 100644 index 000000000..a550f7d03 --- /dev/null +++ b/qemu/roms/u-boot/board/jse/flash.c @@ -0,0 +1,491 @@ +/* + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * Modified 4/5/2001 + * Wait for completion of each sector erase command issued + * 4/5/2001 + * Chris Hallinan - DS4.COM, Inc. - clh@net1plus.com + */ + +#include <common.h> +#include <asm/ppc4xx.h> +#include <asm/processor.h> + +#if CONFIG_SYS_MAX_FLASH_BANKS != 1 +#error "CONFIG_SYS_MAX_FLASH_BANKS must be 1" +#endif +flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */ + +/*----------------------------------------------------------------------- + * Functions + */ +static ulong flash_get_size (vu_long * addr, flash_info_t * info); +static int write_word (flash_info_t * info, ulong dest, ulong data); +static void flash_get_offsets (ulong base, flash_info_t * info); + +#define ADDR0 0x5555 +#define ADDR1 0x2aaa +#define FLASH_WORD_SIZE unsigned char + +/*----------------------------------------------------------------------- + */ + +unsigned long flash_init (void) +{ + unsigned long size_b0; + + /* Init: no FLASHes known */ + flash_info[0].flash_id = FLASH_UNKNOWN; + + /* Static FLASH Bank configuration here - FIXME XXX */ + + size_b0 = flash_get_size ((vu_long *) FLASH_BASE0_PRELIM, &flash_info[0]); + + if (flash_info[0].flash_id == FLASH_UNKNOWN) { + printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n", + size_b0, size_b0 << 20); + } + + /* Only one bank */ + /* Setup offsets */ + flash_get_offsets (FLASH_BASE0_PRELIM, &flash_info[0]); + + /* Monitor protection ON by default */ + (void) flash_protect (FLAG_PROTECT_SET, + FLASH_BASE0_PRELIM, + FLASH_BASE0_PRELIM + monitor_flash_len - 1, + &flash_info[0]); + flash_info[0].size = size_b0; + + return size_b0; +} + + +/*----------------------------------------------------------------------- + */ +/* + * This implementation assumes that the flash chips are uniform sector + * devices. This is true for all likely JSE devices. + */ +static void flash_get_offsets (ulong base, flash_info_t * info) +{ + unsigned idx; + unsigned long sector_size = info->size / info->sector_count; + + for (idx = 0; idx < info->sector_count; idx += 1) { + info->start[idx] = base + (idx * sector_size); + } +} + +/*----------------------------------------------------------------------- + */ +void flash_print_info (flash_info_t * info) +{ + int i; + int k; + int size; + int erased; + volatile unsigned long *flash; + + if (info->flash_id == FLASH_UNKNOWN) { + printf ("missing or unknown FLASH type\n"); + return; + } + + switch (info->flash_id & FLASH_VENDMASK) { + case FLASH_MAN_AMD: + printf ("AMD "); + break; + case FLASH_MAN_FUJ: + printf ("FUJITSU "); + break; + case FLASH_MAN_SST: + printf ("SST "); + break; + case FLASH_MAN_STM: + printf ("ST Micro "); + break; + default: + printf ("Unknown Vendor "); + break; + } + + /* (Reduced table of only parts expected in JSE boards.) */ + switch (info->flash_id) { + case FLASH_MAN_AMD | FLASH_AM040: + printf ("AM29F040 (512 Kbit, uniform sector size)\n"); + break; + case FLASH_MAN_STM | FLASH_AM040: + printf ("MM29W040W (512 Kbit, uniform sector size)\n"); + break; + default: + printf ("Unknown Chip Type\n"); + break; + } + + printf (" Size: %ld KB in %d Sectors\n", + info->size >> 10, info->sector_count); + + printf (" Sector Start Addresses:"); + for (i = 0; i < info->sector_count; ++i) { + /* + * Check if whole sector is erased + */ + if (i != (info->sector_count - 1)) + size = info->start[i + 1] - info->start[i]; + else + size = info->start[0] + info->size - info->start[i]; + erased = 1; + flash = (volatile unsigned long *) info->start[i]; + size = size >> 2; /* divide by 4 for longword access */ + for (k = 0; k < size; k++) { + if (*flash++ != 0xffffffff) { + erased = 0; + break; + } + } + + if ((i % 5) == 0) + printf ("\n "); + printf (" %08lX%s%s", + info->start[i], + erased ? " E" : " ", info->protect[i] ? "RO " : " " + ); + } + printf ("\n"); + return; +} + +/*----------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------- + */ + +/* + * The following code cannot be run from FLASH! + */ +static ulong flash_get_size (vu_long * addr, flash_info_t * info) +{ + short i; + FLASH_WORD_SIZE value; + ulong base = (ulong) addr; + volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *) addr; + + /* Write auto select command: read Manufacturer ID */ + addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA; + addr2[ADDR1] = (FLASH_WORD_SIZE) 0x00550055; + addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00900090; + + value = addr2[0]; + + switch (value) { + case (FLASH_WORD_SIZE) AMD_MANUFACT: + info->flash_id = FLASH_MAN_AMD; + break; + case (FLASH_WORD_SIZE) FUJ_MANUFACT: + info->flash_id = FLASH_MAN_FUJ; + break; + case (FLASH_WORD_SIZE) SST_MANUFACT: + info->flash_id = FLASH_MAN_SST; + break; + case (FLASH_WORD_SIZE)STM_MANUFACT: + info->flash_id = FLASH_MAN_STM; + break; + default: + info->flash_id = FLASH_UNKNOWN; + info->sector_count = 0; + info->size = 0; + printf("Unknown flash manufacturer code: 0x%x\n", value); + return (0); /* no or unknown flash */ + } + + value = addr2[1]; /* device ID */ + + switch (value) { + case (FLASH_WORD_SIZE) AMD_ID_F040B: + info->flash_id += FLASH_AM040; + info->sector_count = 8; + info->size = 0x0080000; /* => 512 ko */ + break; + case (FLASH_WORD_SIZE) AMD_ID_LV040B: + info->flash_id += FLASH_AM040; + info->sector_count = 8; + info->size = 0x0080000; /* => 512 ko */ + break; + case (FLASH_WORD_SIZE)STM_ID_M29W040B: /* most likele JSE chip */ + info->flash_id += FLASH_AM040; + info->sector_count = 8; + info->size = 0x0080000; /* => 512 ko */ + break; + default: + info->flash_id = FLASH_UNKNOWN; + return (0); /* => no or unknown flash */ + + } + + /* Calculate the sector offsets (Use JSE Optimized code). */ + flash_get_offsets(base, info); + + /* check for protected sectors */ + for (i = 0; i < info->sector_count; i++) { + /* read sector protection at sector address, (A7 .. A0) = 0x02 */ + /* D0 = 1 if protected */ + addr2 = (volatile FLASH_WORD_SIZE *) (info->start[i]); + if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) + info->protect[i] = 0; + else + info->protect[i] = addr2[2] & 1; + } + + /* + * Prevent writes to uninitialized FLASH. + */ + if (info->flash_id != FLASH_UNKNOWN) { + addr2 = (FLASH_WORD_SIZE *) info->start[0]; + *addr2 = (FLASH_WORD_SIZE) 0x00F000F0; /* reset bank */ + } + + return (info->size); +} + +int wait_for_DQ7 (flash_info_t * info, int sect) +{ + ulong start, now, last; + volatile FLASH_WORD_SIZE *addr = + (FLASH_WORD_SIZE *) (info->start[sect]); + + start = get_timer (0); + last = start; + while ((addr[0] & (FLASH_WORD_SIZE) 0x00800080) != + (FLASH_WORD_SIZE) 0x00800080) { + if ((now = get_timer (start)) > CONFIG_SYS_FLASH_ERASE_TOUT) { + printf ("Timeout\n"); + return -1; + } + /* show that we're waiting */ + if ((now - last) > 1000) { /* every second */ + putc ('.'); + last = now; + } + } + return 0; +} + +/*----------------------------------------------------------------------- + */ + +int flash_erase (flash_info_t * info, int s_first, int s_last) +{ + volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *) (info->start[0]); + volatile FLASH_WORD_SIZE *addr2; + int flag, prot, sect; + int i; + + if ((s_first < 0) || (s_first > s_last)) { + if (info->flash_id == FLASH_UNKNOWN) { + printf ("- missing\n"); + } else { + printf ("- no sectors to erase\n"); + } + return 1; + } + + if (info->flash_id == FLASH_UNKNOWN) { + printf ("Can't erase unknown flash type - aborted\n"); + return 1; + } + + prot = 0; + for (sect = s_first; sect <= s_last; ++sect) { + if (info->protect[sect]) { + prot++; + } + } + + if (prot) { + printf ("- Warning: %d protected sectors will not be erased!\n", prot); + } else { + printf ("\n"); + } + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts (); + + /* Start erase on unprotected sectors */ + for (sect = s_first; sect <= s_last; sect++) { + if (info->protect[sect] == 0) { /* not protected */ + addr2 = (FLASH_WORD_SIZE *) (info->start[sect]); + printf ("Erasing sector %p\n", addr2); /* CLH */ + + if ((info->flash_id & FLASH_VENDMASK) == + FLASH_MAN_SST) { + addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA; + addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055; + addr[ADDR0] = (FLASH_WORD_SIZE) 0x00800080; + addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA; + addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055; + addr2[0] = (FLASH_WORD_SIZE) 0x00500050; /* block erase */ + for (i = 0; i < 50; i++) + udelay (1000); /* wait 1 ms */ + } else { + addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA; + addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055; + addr[ADDR0] = (FLASH_WORD_SIZE) 0x00800080; + addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA; + addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055; + addr2[0] = (FLASH_WORD_SIZE) 0x00300030; /* sector erase */ + } + /* + * Wait for each sector to complete, it's more + * reliable. According to AMD Spec, you must + * issue all erase commands within a specified + * timeout. This has been seen to fail, especially + * if printf()s are included (for debug)!! + */ + wait_for_DQ7 (info, sect); + } + } + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts (); + + /* wait at least 80us - let's wait 1 ms */ + udelay (1000); + + /* reset to read mode */ + addr = (FLASH_WORD_SIZE *) info->start[0]; + addr[0] = (FLASH_WORD_SIZE) 0x00F000F0; /* reset bank */ + + printf (" done\n"); + return 0; +} + +/*----------------------------------------------------------------------- + * Copy memory to flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ + +int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) +{ + ulong cp, wp, data; + int i, l, 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 < l; ++i, ++cp) { + data = (data << 8) | (*(uchar *) cp); + } + for (; i < 4 && cnt > 0; ++i) { + data = (data << 8) | *src++; + --cnt; + ++cp; + } + for (; cnt == 0 && i < 4; ++i, ++cp) { + data = (data << 8) | (*(uchar *) cp); + } + + if ((rc = write_word (info, wp, data)) != 0) { + return (rc); + } + wp += 4; + } + + /* + * handle word aligned part + */ + while (cnt >= 4) { + data = 0; + for (i = 0; i < 4; ++i) { + data = (data << 8) | *src++; + } + if ((rc = write_word (info, wp, data)) != 0) { + return (rc); + } + wp += 4; + cnt -= 4; + } + + if (cnt == 0) { + return (0); + } + + /* + * handle unaligned tail bytes + */ + data = 0; + for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) { + data = (data << 8) | *src++; + --cnt; + } + for (; i < 4; ++i, ++cp) { + data = (data << 8) | (*(uchar *) cp); + } + + return (write_word (info, wp, data)); +} + +/*----------------------------------------------------------------------- + * Write a word to Flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ +static int write_word (flash_info_t * info, ulong dest, ulong data) +{ + volatile FLASH_WORD_SIZE *addr2 = + (FLASH_WORD_SIZE *) (info->start[0]); + volatile FLASH_WORD_SIZE *dest2 = (FLASH_WORD_SIZE *) dest; + volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *) & data; + ulong start; + int i; + + /* Check if Flash is (sufficiently) erased */ + if ((*((volatile FLASH_WORD_SIZE *) dest) & + (FLASH_WORD_SIZE) data) != (FLASH_WORD_SIZE) data) { + return (2); + } + + for (i = 0; i < 4 / sizeof (FLASH_WORD_SIZE); i++) { + int flag; + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts (); + + addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA; + addr2[ADDR1] = (FLASH_WORD_SIZE) 0x00550055; + addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00A000A0; + + dest2[i] = data2[i]; + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts (); + + /* data polling for D7 */ + start = get_timer (0); + while ((dest2[i] & (FLASH_WORD_SIZE) 0x00800080) != + (data2[i] & (FLASH_WORD_SIZE) 0x00800080)) { + + if (get_timer (start) > CONFIG_SYS_FLASH_WRITE_TOUT) { + return (1); + } + } + } + + return (0); +} diff --git a/qemu/roms/u-boot/board/jse/host_bridge.c b/qemu/roms/u-boot/board/jse/host_bridge.c new file mode 100644 index 000000000..76c07b0c3 --- /dev/null +++ b/qemu/roms/u-boot/board/jse/host_bridge.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2004 Picture Elements, Inc. + * Stephen Williams (steve@icarus.com) + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ident "$Id:$" + +# include <common.h> +# include <pci.h> +# include "jse_priv.h" + +/* + * The JSE board has an Intel 21555 non-transparent bridge for + * communication with the host. We need to render it harmless on the + * JSE side, but leave it alone on the host (primary) side. Normally, + * this will all be done before the host BIOS can gain access to the + * board, due to the Primary Access Lockout bit. + * + * The host_bridge_init function is called as a late initialization + * function, after most of the board is set up, including a PCI scan. + */ + +void host_bridge_init (void) +{ + /* The bridge chip is at a fixed location. */ + pci_dev_t dev = PCI_BDF (0, 10, 0); + + /* Set PCI Class code -- + The primary side sees this class code at 0x08 in the + primary config space. This must be something other then a + bridge, or MS Windows starts doing weird stuff to me. */ + pci_write_config_dword (dev, 0x48, 0x04800000); + + /* Set subsystem ID -- + The primary side sees this value at 0x2c. We set it here so + that the host can tell what sort of device this is: + We are a Picture Elements [0x12c5] JSE [0x008a]. */ + pci_write_config_dword (dev, 0x6c, 0x008a12c5); + + /* Downstream (Primary-to-Secondary) BARs are set up mostly + off. We need only the Memory-0 Bar so that the host can get + at the CSR region to set up tables and the lot. */ + + /* Downstream Memory 0 setup (4K for CSR) */ + pci_write_config_dword (dev, 0xac, 0xfffff000); + /* Downstream Memory 1 setup (off) */ + pci_write_config_dword (dev, 0xb0, 0x00000000); + /* Downstream Memory 2 setup (off) */ + pci_write_config_dword (dev, 0xb4, 0x00000000); + /* Downstream Memory 3 setup (off) */ + pci_write_config_dword (dev, 0xb8, 0x00000000); + + /* Upstream (Secondary-to-Primary) BARs are used to get at + host memory from the JSE card. Create two regions: a small + one to manage individual word reads/writes, and a larger + one for doing bulk frame moves. */ + + /* Upstream Memory 0 Setup -- (BAR2) 4K non-prefetchable */ + pci_write_config_dword (dev, 0xc4, 0xfffff000); + /* Upstream Memory 1 setup -- (BAR3) 4K non-prefetchable */ + pci_write_config_dword (dev, 0xc8, 0xfffff000); + + /* Upstream Memory 2 (BAR4) uses page translation, and is set + up in CCR1. Configure for 4K pages. */ + + /* Set CCR1,0 reigsters. This clears the Primary PCI Lockout + bit as well, so we are done configuring after this + point. Therefore, this must be the last step. + + CC1[15:12]= 0 (disable I2O message unit) + CC1[11:8] = 0x5 (4K page size) + CC0[11] = 1 (Secondary Clock Disable: disable clock) + CC0[10] = 0 (Primary Access Lockout: allow primary access) + */ + pci_write_config_dword (dev, 0xcc, 0x05000800); +} diff --git a/qemu/roms/u-boot/board/jse/init.S b/qemu/roms/u-boot/board/jse/init.S new file mode 100644 index 000000000..4e449fef2 --- /dev/null +++ b/qemu/roms/u-boot/board/jse/init.S @@ -0,0 +1,75 @@ +/* + * SPDX-License-Identifier: GPL-2.0 IBM-pibs + */ +/*------------------------------------------------------------------------- */ +/* Function: ext_bus_cntlr_init */ +/* Description: Initializes the External Bus Controller for the external */ +/* peripherals. IMPORTANT: For pass1 this code must run from */ +/* cache since you can not reliably change a peripheral banks */ +/* timing register (pbxap) while running code from that bank. */ +/* For ex., since we are running from ROM on bank 0, we can NOT */ +/* execute the code that modifies bank 0 timings from ROM, so */ +/* we run it from cache. */ +/* */ +/* */ +/* The layout for the PEI JSE board: */ +/* Bank 0 - Flash and SRAM */ +/* Bank 1 - SystemACE */ +/* Bank 2 - not used */ +/* Bank 3 - not used */ +/* Bank 4 - not used */ +/* Bank 5 - not used */ +/* Bank 6 - not used */ +/* Bank 7 - not used */ +/*------------------------------------------------------------------------- */ +#include <asm/ppc4xx.h> + +#include <ppc_asm.tmpl> +#include <ppc_defs.h> + +#include <asm/cache.h> +#include <asm/mmu.h> + + .globl ext_bus_cntlr_init +ext_bus_cntlr_init: + mflr r4 /* save link register */ + bl ..getAddr +..getAddr: + mflr r3 /* get address of ..getAddr */ + mtlr r4 /* restore link register */ + addi r4,0,14 /* set ctr to 10; used to prefetch */ + mtctr r4 /* 10 cache lines to fit this function */ + /* in cache (gives us 8x10=80 instrctns) */ +..ebcloop: + icbt r0,r3 /* prefetch cache line for addr in r3 */ + addi r3,r3,32 /* move to next cache line */ + bdnz ..ebcloop /* continue for 10 cache lines */ + + /*----------------------------------------------------------------- */ + /* Delay to ensure all accesses to ROM are complete before changing */ + /* bank 0 timings. 200usec should be enough. */ + /* 200,000,000 (cycles/sec) X .000200 (sec) = 0x9C40 cycles */ + /*----------------------------------------------------------------- */ + addis r3,0,0x0 + ori r3,r3,0xA000 /* ensure 200usec have passed since reset */ + mtctr r3 +..spinlp: + bdnz ..spinlp /* spin loop */ + + /*----------------------------------------------------------------- */ + /* Memory Bank 0 (Flash) initialization */ + /*----------------------------------------------------------------- */ + + addi r4,0,PB1AP + mtdcr EBC0_CFGADDR,r4 + addis r4,0,0x9B01 + ori r4,r4,0x5480 + mtdcr EBC0_CFGDATA,r4 + + addi r4,0,PB0CR + mtdcr EBC0_CFGADDR,r4 + addis r4,0,0xFFF1 /* BAS=0xFFF,BS=0x0(1MB),BU=0x3(R/W), */ + ori r4,r4,0x8000 /* BW=0x0( 8 bits) */ + mtdcr EBC0_CFGDATA,r4 + + blr diff --git a/qemu/roms/u-boot/board/jse/jse.c b/qemu/roms/u-boot/board/jse/jse.c new file mode 100644 index 000000000..a0913c33f --- /dev/null +++ b/qemu/roms/u-boot/board/jse/jse.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2004 Picture Elements, Inc. + * Stephen Williams (steve@icarus.com) + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +# include <common.h> +# include <asm/ppc4xx.h> +# include <asm/processor.h> +# include <asm/io.h> +# include "jse_priv.h" + +/* + * This function is run very early, out of flash, and before devices are + * initialized. It is called by arch/powerpc/lib/board.c:board_init_f by virtue + * of being in the init_sequence array. + * + * The SDRAM has been initialized already -- start.S:start called + * init.S:init_sdram early on -- but it is not yet being used for + * anything, not even stack. So be careful. + */ +int board_early_init_f (void) +{ + /*-------------------------------------------------------------------------+ + | Interrupt controller setup for the JSE board. + | Note: IRQ 0-15 405GP internally generated; active high; level sensitive + | IRQ 16 405GP internally generated; active low; level sensitive + | IRQ 17-24 RESERVED/UNUSED + | IRQ 25 (EXT IRQ 0) PCI SLOT 0; active low; level sensitive + | IRQ 26 (EXT IRQ 1) PCI SLOT 1; active low; level sensitive + | IRQ 27 (EXT IRQ 2) JP2C CHIP ; active low; level sensitive + | IRQ 28 (EXT IRQ 3) PCI bridge; active low; level sensitive + | IRQ 29 (EXT IRQ 4) SystemACE IRQ; active high + | IRQ 30 (EXT IRQ 5) SystemACE BRdy (unused) + | IRQ 31 (EXT IRQ 6) (unused) + +-------------------------------------------------------------------------*/ + mtdcr (UIC0SR, 0xFFFFFFFF); /* clear all ints */ + mtdcr (UIC0ER, 0x00000000); /* disable all ints */ + mtdcr (UIC0CR, 0x00000000); /* set all to be non-critical */ + mtdcr (UIC0PR, 0xFFFFFF87); /* set int polarities */ + mtdcr (UIC0TR, 0x10000000); /* set int trigger levels */ + mtdcr (UIC0SR, 0xFFFFFFFF); /* clear all ints */ + + /* Configure the interface to the SystemACE MCU port. + The SystemACE is fast, but there is no reason to have + excessivly tight timings. So the settings are slightly + generous. */ + + /* EBC0_B1AP: BME=1, TWT=2, CSN=0, OEN=1, + WBN=0, WBF=1, TH=0, RE=0, SOR=0, BEM=0, PEN=0 */ + mtdcr (EBC0_CFGADDR, PB1AP); + mtdcr (EBC0_CFGDATA, 0x01011000); + + /* EBC0_B1CR: BAS=x, BS=0(1MB), BU=3(R/W), BW=0(8bits) */ + mtdcr (EBC0_CFGADDR, PB1CR); + mtdcr (EBC0_CFGDATA, CONFIG_SYS_SYSTEMACE_BASE | 0x00018000); + + /* Enable the /PerWE output as /PerWE, instead of /PCIINT. */ + /* CPC0_CR1 |= PCIPW */ + mtdcr (0xb2, mfdcr (0xb2) | 0x00004000); + + return 0; +} + +#ifdef CONFIG_BOARD_PRE_INIT +int board_pre_init (void) +{ + return board_early_init_f (); +} + +#endif + +/* + * This function is also called by arch/powerpc/lib/board.c:board_init_f (it is + * also in the init_sequence array) but later. Many more things are + * configured, but we are still running from flash. + */ +int checkboard (void) +{ + unsigned vers, status; + + /* check that the SystemACE chip is alive. */ + printf ("ACE: "); + vers = readw (CONFIG_SYS_SYSTEMACE_BASE + 0x16); + printf ("SystemACE %u.%u (build %u)", + (vers >> 12) & 0x0f, (vers >> 8) & 0x0f, vers & 0xff); + + status = readl (CONFIG_SYS_SYSTEMACE_BASE + 0x04); +#ifdef DEBUG + printf (" STATUS=0x%08x", status); +#endif + /* If the flash card is present and there is an initial error, + then force a restart of the program. */ + if (status & 0x00000010) { + printf (" CFDETECT"); + + if (status & 0x04) { + /* CONTROLREG = CFGPROG */ + writew (0x1000, CONFIG_SYS_SYSTEMACE_BASE + 0x18); + udelay (500); + /* CONTROLREG = CFGRESET */ + writew (0x0080, CONFIG_SYS_SYSTEMACE_BASE + 0x18); + udelay (500); + writew (0x0000, CONFIG_SYS_SYSTEMACE_BASE + 0x18); + /* CONTROLREG = CFGSTART */ + writew (0x0020, CONFIG_SYS_SYSTEMACE_BASE + 0x18); + + status = readl (CONFIG_SYS_SYSTEMACE_BASE + 0x04); + } + } + + /* Wait for the SystemACE to program its chain of devices. */ + while ((status & 0x84) == 0x00) { + udelay (500); + status = readl (CONFIG_SYS_SYSTEMACE_BASE + 0x04); + } + + if (status & 0x04) + printf (" CFG-ERROR"); + if (status & 0x80) + printf (" CFGDONE"); + + printf ("\n"); + + /* Force /RTS to active. The board it not wired quite + correctly to use cts/rtc flow control, so just force the + /RST active and forget about it. */ + writeb (readb (0xef600404) | 0x03, 0xef600404); + + printf ("JSE: ready\n"); + + return 0; +} + +/* **** No more functions called by board_init_f. **** */ + +/* + * This function is called by arch/powerpc/lib/board.c:board_init_r. At this + * point, basic setup is done, U-Boot has been moved into SDRAM and + * PCI has been set up. From here we done late setup. + */ +int misc_init_r (void) +{ + host_bridge_init (); + return 0; +} diff --git a/qemu/roms/u-boot/board/jse/jse_priv.h b/qemu/roms/u-boot/board/jse/jse_priv.h new file mode 100644 index 000000000..f61204bba --- /dev/null +++ b/qemu/roms/u-boot/board/jse/jse_priv.h @@ -0,0 +1,12 @@ +#ifndef __jse_priv_H +#define __jse_prov_H +/* + * Copyright (c) 2004 Picture Elements, Inc. + * Stephen Williams (steve@icarus.com) + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +extern void host_bridge_init(void); + +#endif diff --git a/qemu/roms/u-boot/board/jse/sdram.c b/qemu/roms/u-boot/board/jse/sdram.c new file mode 100644 index 000000000..5639beddc --- /dev/null +++ b/qemu/roms/u-boot/board/jse/sdram.c @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2004 Picture Elements, Inc. + * Stephen Williams (steve@icarus.com) + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/ppc4xx.h> +#include <asm/processor.h> + +# define SDRAM_LEN 0x08000000 + +/* + * this is even after checkboard. It returns the size of the SDRAM + * that we have installed. This function is called by board_init_f + * in arch/powerpc/lib/board.c to initialize the memory and return what I + * found. + */ +phys_size_t initdram (int board_type) +{ + /* Configure the SDRAMS */ + + /* disable memory controller */ + mtdcr (SDRAM0_CFGADDR, SDRAM0_CFG); + mtdcr (SDRAM0_CFGDATA, 0x00000000); + + udelay (500); + + /* Clear SDRAM0_BESR0 (Bus Error Syndrome Register) */ + mtdcr (SDRAM0_CFGADDR, SDRAM0_BESR0); + mtdcr (SDRAM0_CFGDATA, 0xffffffff); + + /* Clear SDRAM0_BESR1 (Bus Error Syndrome Register) */ + mtdcr (SDRAM0_CFGADDR, SDRAM0_BESR1); + mtdcr (SDRAM0_CFGDATA, 0xffffffff); + + /* Clear SDRAM0_ECCCFG (disable ECC) */ + mtdcr (SDRAM0_CFGADDR, SDRAM0_ECCCFG); + mtdcr (SDRAM0_CFGDATA, 0x00000000); + + /* Clear SDRAM0_ECCESR (ECC Error Syndrome Register) */ + mtdcr (SDRAM0_CFGADDR, SDRAM0_ECCESR); + mtdcr (SDRAM0_CFGDATA, 0xffffffff); + + /* Timing register: CASL=2, PTA=2, CTP=2, LDF=1, RFTA=5, RCD=2 */ + mtdcr (SDRAM0_CFGADDR, SDRAM0_TR); + mtdcr (SDRAM0_CFGDATA, 0x010a4016); + + /* Memory Bank 0 Config == BA=0x00000000, SZ=64M, AM=3, BE=1 */ + mtdcr (SDRAM0_CFGADDR, SDRAM0_B0CR); + mtdcr (SDRAM0_CFGDATA, 0x00084001); + + /* Memory Bank 1 Config == BA=0x04000000, SZ=64M, AM=3, BE=1 */ + mtdcr (SDRAM0_CFGADDR, SDRAM0_B1CR); + mtdcr (SDRAM0_CFGDATA, 0x04084001); + + /* Memory Bank 2 Config == BE=0 */ + mtdcr (SDRAM0_CFGADDR, SDRAM0_B2CR); + mtdcr (SDRAM0_CFGDATA, 0x00000000); + + /* Memory Bank 3 Config == BE=0 */ + mtdcr (SDRAM0_CFGADDR, SDRAM0_B3CR); + mtdcr (SDRAM0_CFGDATA, 0x00000000); + + /* refresh timer = 0x400 */ + mtdcr (SDRAM0_CFGADDR, SDRAM0_RTR); + mtdcr (SDRAM0_CFGDATA, 0x04000000); + + /* Power management idle timer set to the default. */ + mtdcr (SDRAM0_CFGADDR, SDRAM0_PMIT); + mtdcr (SDRAM0_CFGDATA, 0x07c00000); + + udelay (500); + + /* Enable banks (DCE=1, BPRF=1, ECCDD=1, EMDUL=1) */ + mtdcr (SDRAM0_CFGADDR, SDRAM0_CFG); + mtdcr (SDRAM0_CFGDATA, 0x80e00000); + + return SDRAM_LEN; +} + +/* + * The U-Boot core, as part of the initialization to prepare for + * loading the monitor into SDRAM, requests of this function that the + * memory be tested. Return 0 if the memory tests OK. + */ +int testdram (void) +{ + unsigned long idx; + unsigned val; + unsigned errors; + volatile unsigned long *sdram; + +#ifdef DEBUG + printf ("SDRAM Controller Registers --\n"); + + mtdcr (SDRAM0_CFGADDR, SDRAM0_CFG); + val = mfdcr (SDRAM0_CFGDATA); + printf (" SDRAM0_CFG : 0x%08x\n", val); + + mtdcr (SDRAM0_CFGADDR, 0x24); + val = mfdcr (SDRAM0_CFGDATA); + printf (" SDRAM0_STATUS: 0x%08x\n", val); + + mtdcr (SDRAM0_CFGADDR, SDRAM0_B0CR); + val = mfdcr (SDRAM0_CFGDATA); + printf (" SDRAM0_B0CR : 0x%08x\n", val); + + mtdcr (SDRAM0_CFGADDR, SDRAM0_B1CR); + val = mfdcr (SDRAM0_CFGDATA); + printf (" SDRAM0_B1CR : 0x%08x\n", val); + + mtdcr (SDRAM0_CFGADDR, SDRAM0_TR); + val = mfdcr (SDRAM0_CFGDATA); + printf (" SDRAM0_TR : 0x%08x\n", val); + + mtdcr (SDRAM0_CFGADDR, SDRAM0_RTR); + val = mfdcr (SDRAM0_CFGDATA); + printf (" SDRAM0_RTR : 0x%08x\n", val); +#endif + + /* Wait for memory to be ready by testing MRSCMPbit + bit. Really, there should already have been plenty of time, + given it was started long ago. But, best to check. */ + for (idx = 0; idx < 1000000; idx += 1) { + mtdcr (SDRAM0_CFGADDR, 0x24); + val = mfdcr (SDRAM0_CFGDATA); + if (val & 0x80000000) + break; + } + + if (!(val & 0x80000000)) { + printf ("SDRAM ERROR: SDRAM0_STATUS never set!\n"); + return 1; + } + + /* Start memory test. */ + printf ("test: %u MB - ", SDRAM_LEN / 1048576); + + sdram = (unsigned long *) CONFIG_SYS_SDRAM_BASE; + + printf ("write - "); + for (idx = 2; idx < SDRAM_LEN / 4; idx += 2) { + sdram[idx + 0] = idx; + sdram[idx + 1] = ~idx; + } + + printf ("read - "); + errors = 0; + for (idx = 2; idx < SDRAM_LEN / 4; idx += 2) { + if (sdram[idx + 0] != idx) + errors += 1; + if (sdram[idx + 1] != ~idx) + errors += 1; + if (errors > 0) + break; + } + + if (errors > 0) { + printf ("NOT OK\n"); + printf ("FIRST ERROR at %p: 0x%08lx:0x%08lx != 0x%08lx:0x%08lx\n", + sdram + idx, sdram[idx + 0], sdram[idx + 1], idx, ~idx); + return 1; + } + + printf ("ok\n"); + return 0; +} |