summaryrefslogtreecommitdiff
path: root/board/evb64260
diff options
context:
space:
mode:
authorwdenk <wdenk>2002-11-02 23:17:16 +0000
committerwdenk <wdenk>2002-11-02 23:17:16 +0000
commit7ebf7443ad018a0647f549a835a55f0c08d7a15d (patch)
treeb055053545c714a70bae1cff0745f45acc3ec94e /board/evb64260
parentcc1c8a136f9813d0a9cb9a94d2f12206873ddc4e (diff)
downloadu-boot-imx-7ebf7443ad018a0647f549a835a55f0c08d7a15d.zip
u-boot-imx-7ebf7443ad018a0647f549a835a55f0c08d7a15d.tar.gz
u-boot-imx-7ebf7443ad018a0647f549a835a55f0c08d7a15d.tar.bz2
Initial revision
Diffstat (limited to 'board/evb64260')
-rw-r--r--board/evb64260/evb64260.c437
-rw-r--r--board/evb64260/flash.c805
-rw-r--r--board/evb64260/memory.c457
-rw-r--r--board/evb64260/u-boot.lds129
4 files changed, 1828 insertions, 0 deletions
diff --git a/board/evb64260/evb64260.c b/board/evb64260/evb64260.c
new file mode 100644
index 0000000..1c02e32
--- /dev/null
+++ b/board/evb64260/evb64260.c
@@ -0,0 +1,437 @@
+/*
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
+ *
+ * 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
+ */
+
+/*
+ * evb64260.c - main board support/init for the Galileo Eval board.
+ */
+
+#include <common.h>
+#include <74xx_7xx.h>
+#include <galileo/memory.h>
+#include <galileo/pci.h>
+#include <galileo/gt64260R.h>
+#include <net.h>
+
+#include <asm/io.h>
+#include "eth.h"
+#include "mpsc.h"
+#include "i2c.h"
+#include "64260.h"
+#ifdef CONFIG_ZUMA_V2
+extern void zuma_mbox_init(void);
+#endif
+
+#undef DEBUG
+#define MAP_PCI
+
+#ifdef DEBUG
+#define DP(x) x
+#else
+#define DP(x)
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+/* this is the current GT register space location */
+/* it starts at CFG_DFL_GT_REGS but moves later to CFG_GT_REGS */
+
+/* Unfortunately, we cant change it while we are in flash, so we initialize it
+ * to the "final" value. This means that any debug_led calls before
+ * board_pre_init wont work right (like in cpu_init_f).
+ * See also my_remap_gt_regs below. (NTL)
+ */
+
+unsigned int INTERNAL_REG_BASE_ADDR = CFG_GT_REGS;
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * This is a version of the GT register space remapping function that
+ * doesn't touch globals (meaning, it's ok to run from flash.)
+ *
+ * Unfortunately, this has the side effect that a writable
+ * INTERNAL_REG_BASE_ADDR is impossible. Oh well.
+ */
+
+void
+my_remap_gt_regs(u32 cur_loc, u32 new_loc)
+{
+ u32 temp;
+
+ /* check and see if it's already moved */
+ temp = in_le32((u32 *)(new_loc + INTERNAL_SPACE_DECODE));
+ if ((temp & 0xffff) == new_loc >> 20)
+ return;
+
+ temp = (in_le32((u32 *)(cur_loc + INTERNAL_SPACE_DECODE)) &
+ 0xffff0000) | (new_loc >> 20);
+
+ out_le32((u32 *)(cur_loc + INTERNAL_SPACE_DECODE), temp);
+
+ while (GTREGREAD(INTERNAL_SPACE_DECODE) != temp);
+}
+
+static void
+gt_pci_config(void)
+{
+ /* move PCI stuff out of the way - NTL */
+ /* map PCI Host 0 */
+ pciMapSpace(PCI_HOST0, PCI_REGION0, CFG_PCI0_0_MEM_SPACE,
+ CFG_PCI0_0_MEM_SPACE, CFG_PCI0_MEM_SIZE);
+
+ pciMapSpace(PCI_HOST0, PCI_REGION1, 0, 0, 0);
+ pciMapSpace(PCI_HOST0, PCI_REGION2, 0, 0, 0);
+ pciMapSpace(PCI_HOST0, PCI_REGION3, 0, 0, 0);
+
+ pciMapSpace(PCI_HOST0, PCI_IO, CFG_PCI0_IO_SPACE_PCI,
+ CFG_PCI0_IO_SPACE, CFG_PCI0_IO_SIZE);
+
+ /* map PCI Host 1 */
+ pciMapSpace(PCI_HOST1, PCI_REGION0, CFG_PCI1_0_MEM_SPACE,
+ CFG_PCI1_0_MEM_SPACE, CFG_PCI1_MEM_SIZE);
+
+ pciMapSpace(PCI_HOST1, PCI_REGION1, 0, 0, 0);
+ pciMapSpace(PCI_HOST1, PCI_REGION2, 0, 0, 0);
+ pciMapSpace(PCI_HOST1, PCI_REGION3, 0, 0, 0);
+
+ pciMapSpace(PCI_HOST1, PCI_IO, CFG_PCI1_IO_SPACE_PCI,
+ CFG_PCI1_IO_SPACE, CFG_PCI1_IO_SIZE);
+
+ /* PCI interface settings */
+ GT_REG_WRITE(PCI_0TIMEOUT_RETRY, 0xffff);
+ GT_REG_WRITE(PCI_1TIMEOUT_RETRY, 0xffff);
+ GT_REG_WRITE(PCI_0BASE_ADDRESS_REGISTERS_ENABLE, 0xfffff80e);
+ GT_REG_WRITE(PCI_1BASE_ADDRESS_REGISTERS_ENABLE, 0xfffff80e);
+
+
+}
+
+/* Setup CPU interface paramaters */
+static void
+gt_cpu_config(void)
+{
+ cpu_t cpu = get_cpu_type();
+ ulong tmp;
+
+ /* cpu configuration register */
+ tmp = GTREGREAD(CPU_CONFIGURATION);
+
+ /* set the AACK delay bit
+ * see Res#14 */
+ tmp |= CPU_CONF_AACK_DELAY;
+ tmp &= ~CPU_CONF_AACK_DELAY_2; /* New RGF */
+
+ /* Galileo claims this is necessary for all busses >= 100 MHz */
+ tmp |= CPU_CONF_FAST_CLK;
+
+ if (cpu == CPU_750CX) {
+ tmp &= ~CPU_CONF_DP_VALID; /* Safer, needed for CXe. RGF */
+ tmp &= ~CPU_CONF_AP_VALID;
+ } else {
+ tmp |= CPU_CONF_DP_VALID;
+ tmp |= CPU_CONF_AP_VALID;
+ }
+
+ /* this only works with the MPX bus */
+ tmp &= ~CPU_CONF_RD_OOO; /* Safer RGF */
+ tmp |= CPU_CONF_PIPELINE;
+ tmp |= CPU_CONF_TA_DELAY;
+
+ GT_REG_WRITE(CPU_CONFIGURATION, tmp);
+
+ /* CPU master control register */
+ tmp = GTREGREAD(CPU_MASTER_CONTROL);
+
+ tmp |= CPU_MAST_CTL_ARB_EN;
+
+ if ((cpu == CPU_7400) ||
+ (cpu == CPU_7410) ||
+ (cpu == CPU_7450)) {
+
+ tmp |= CPU_MAST_CTL_CLEAN_BLK;
+ tmp |= CPU_MAST_CTL_FLUSH_BLK;
+
+ } else {
+ /* cleanblock must be cleared for CPUs
+ * that do not support this command
+ * see Res#1 */
+ tmp &= ~CPU_MAST_CTL_CLEAN_BLK;
+ tmp &= ~CPU_MAST_CTL_FLUSH_BLK;
+ }
+ GT_REG_WRITE(CPU_MASTER_CONTROL, tmp);
+}
+
+/*
+ * board_pre_init.
+ *
+ * set up gal. device mappings, etc.
+ */
+int board_pre_init (void)
+{
+ uchar sram_boot = 0;
+
+ /*
+ * set up the GT the way the kernel wants it
+ * the call to move the GT register space will obviously
+ * fail if it has already been done, but we're going to assume
+ * that if it's not at the power-on location, it's where we put
+ * it last time. (huber)
+ */
+ my_remap_gt_regs(CFG_DFL_GT_REGS, CFG_GT_REGS);
+
+ gt_pci_config();
+
+ /* mask all external interrupt sources */
+ GT_REG_WRITE(CPU_INTERRUPT_MASK_REGISTER_LOW, 0);
+ GT_REG_WRITE(CPU_INTERRUPT_MASK_REGISTER_HIGH, 0);
+ GT_REG_WRITE(PCI_0INTERRUPT_CAUSE_MASK_REGISTER_LOW, 0);
+ GT_REG_WRITE(PCI_0INTERRUPT_CAUSE_MASK_REGISTER_HIGH, 0);
+ GT_REG_WRITE(PCI_1INTERRUPT_CAUSE_MASK_REGISTER_LOW, 0);
+ GT_REG_WRITE(PCI_1INTERRUPT_CAUSE_MASK_REGISTER_HIGH, 0);
+ GT_REG_WRITE(CPU_INT_0_MASK, 0);
+ GT_REG_WRITE(CPU_INT_1_MASK, 0);
+ GT_REG_WRITE(CPU_INT_2_MASK, 0);
+ GT_REG_WRITE(CPU_INT_3_MASK, 0);
+
+ /* now, onto the configuration */
+ GT_REG_WRITE(SDRAM_CONFIGURATION, CFG_SDRAM_CONFIG);
+
+ /* ----- DEVICE BUS SETTINGS ------ */
+
+ /*
+ * EVB
+ * 0 - SRAM
+ * 1 - RTC
+ * 2 - UART
+ * 3 - Flash
+ * boot - BootCS
+ *
+ * Zuma
+ * 0 - Flash
+ * boot - BootCS
+ */
+
+ /*
+ * the dual 7450 module requires burst access to the boot
+ * device, so the serial rom copies the boot device to the
+ * on-board sram on the eval board, and updates the correct
+ * registers to boot from the sram. (device0)
+ */
+#ifdef CONFIG_ZUMA_V2
+ /* Zuma has no SRAM */
+ sram_boot = 0;
+#else
+ if (memoryGetDeviceBaseAddress(DEVICE0) && 0xfff00000 == CFG_MONITOR_BASE)
+ sram_boot = 1;
+#endif
+
+ if (!sram_boot)
+ memoryMapDeviceSpace(DEVICE0, CFG_DEV0_SPACE, CFG_DEV0_SIZE);
+
+ memoryMapDeviceSpace(DEVICE1, CFG_DEV1_SPACE, CFG_DEV1_SIZE);
+ memoryMapDeviceSpace(DEVICE2, CFG_DEV2_SPACE, CFG_DEV2_SIZE);
+ memoryMapDeviceSpace(DEVICE3, CFG_DEV3_SPACE, CFG_DEV3_SIZE);
+
+ /* configure device timing */
+#ifdef CFG_DEV0_PAR
+ if (!sram_boot)
+ GT_REG_WRITE(DEVICE_BANK0PARAMETERS, CFG_DEV0_PAR);
+#endif
+
+#ifdef CFG_DEV1_PAR
+ GT_REG_WRITE(DEVICE_BANK1PARAMETERS, CFG_DEV1_PAR);
+#endif
+#ifdef CFG_DEV2_PAR
+ GT_REG_WRITE(DEVICE_BANK2PARAMETERS, CFG_DEV2_PAR);
+#endif
+
+#ifdef CFG_32BIT_BOOT_PAR
+ /* detect if we are booting from the 32 bit flash */
+ if (GTREGREAD(DEVICE_BOOT_BANK_PARAMETERS) & (0x3 << 20)) {
+ /* 32 bit boot flash */
+ GT_REG_WRITE(DEVICE_BANK3PARAMETERS, CFG_8BIT_BOOT_PAR);
+ GT_REG_WRITE(DEVICE_BOOT_BANK_PARAMETERS, CFG_32BIT_BOOT_PAR);
+ } else {
+ /* 8 bit boot flash */
+ GT_REG_WRITE(DEVICE_BANK3PARAMETERS, CFG_32BIT_BOOT_PAR);
+ GT_REG_WRITE(DEVICE_BOOT_BANK_PARAMETERS, CFG_8BIT_BOOT_PAR);
+ }
+#else
+ /* 8 bit boot flash only */
+ GT_REG_WRITE(DEVICE_BOOT_BANK_PARAMETERS, CFG_8BIT_BOOT_PAR);
+#endif
+
+ gt_cpu_config();
+
+ /* MPP setup */
+ GT_REG_WRITE(MPP_CONTROL0, CFG_MPP_CONTROL_0);
+ GT_REG_WRITE(MPP_CONTROL1, CFG_MPP_CONTROL_1);
+ GT_REG_WRITE(MPP_CONTROL2, CFG_MPP_CONTROL_2);
+ GT_REG_WRITE(MPP_CONTROL3, CFG_MPP_CONTROL_3);
+
+ GT_REG_WRITE(GPP_LEVEL_CONTROL, CFG_GPP_LEVEL_CONTROL);
+ GT_REG_WRITE(SERIAL_PORT_MULTIPLEX, CFG_SERIAL_PORT_MUX);
+
+ return 0;
+}
+
+/* various things to do after relocation */
+
+int misc_init_r (void)
+{
+ icache_enable();
+#ifdef CFG_L2
+ l2cache_enable();
+#endif
+
+#ifdef CONFIG_MPSC
+ mpsc_init2();
+#endif
+
+#ifdef CONFIG_ZUMA_V2
+ zuma_mbox_init();
+#endif
+ return (0);
+}
+
+void
+after_reloc(gd_t *gd, ulong dest_addr)
+{
+ /* check to see if we booted from the sram. If so, move things
+ * back to the way they should be. (we're running from main
+ * memory at this point now */
+
+ if (memoryGetDeviceBaseAddress(DEVICE0) == CFG_MONITOR_BASE) {
+ memoryMapDeviceSpace(DEVICE0, CFG_DEV0_SPACE, CFG_DEV0_SIZE);
+ memoryMapDeviceSpace(BOOT_DEVICE, CFG_FLASH_BASE, _1M);
+ }
+
+ /* now, jump to the main U-Boot board init code */
+ board_init_r (gd, dest_addr);
+
+ /* NOTREACHED */
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Check Board Identity:
+ */
+
+int
+checkboard (void)
+{
+ puts ("Board: " CFG_BOARD_NAME "\n");
+ return (0);
+}
+
+/* utility functions */
+void
+debug_led(int led, int mode)
+{
+#ifndef CONFIG_ZUMA_V2
+ volatile int *addr = NULL;
+ int dummy;
+
+ if (mode == 1) {
+ switch (led) {
+ case 0:
+ addr = (int *)((unsigned int)CFG_DEV1_SPACE | 0x08000);
+ break;
+
+ case 1:
+ addr = (int *)((unsigned int)CFG_DEV1_SPACE | 0x0c000);
+ break;
+
+ case 2:
+ addr = (int *)((unsigned int)CFG_DEV1_SPACE | 0x10000);
+ break;
+ }
+ } else if (mode == 0) {
+ switch (led) {
+ case 0:
+ addr = (int *)((unsigned int)CFG_DEV1_SPACE | 0x14000);
+ break;
+
+ case 1:
+ addr = (int *)((unsigned int)CFG_DEV1_SPACE | 0x18000);
+ break;
+
+ case 2:
+ addr = (int *)((unsigned int)CFG_DEV1_SPACE | 0x1c000);
+ break;
+ }
+ }
+ WRITE_CHAR(addr, 0);
+ dummy = *addr;
+#endif /* CONFIG_ZUMA_V2 */
+}
+
+void
+display_mem_map(void)
+{
+ int i,j;
+ unsigned int base,size,width;
+ /* SDRAM */
+ printf("SDRAM\n");
+ for(i=0;i<=BANK3;i++) {
+ base = memoryGetBankBaseAddress(i);
+ size = memoryGetBankSize(i);
+ if(size !=0)
+ {
+ printf("BANK%d: base - 0x%08x\tsize - %dM bytes\n",i,base,size>>20);
+ }
+ }
+
+ /* CPU's PCI windows */
+ for(i=0;i<=PCI_HOST1;i++) {
+ printf("\nCPU's PCI %d windows\n", i);
+ base=pciGetSpaceBase(i,PCI_IO);
+ size=pciGetSpaceSize(i,PCI_IO);
+ printf(" IO: base - 0x%08x\tsize - %dM bytes\n",base,size>>20);
+ for(j=0;j<=PCI_REGION3;j++) {
+ base = pciGetSpaceBase(i,j);
+ size = pciGetSpaceSize(i,j);
+ printf("MEMORY %d: base - 0x%08x\tsize - %dM bytes\n",j,base,
+ size>>20);
+ }
+ }
+
+ /* Devices */
+ printf("\nDEVICES\n");
+ for(i=0;i<=DEVICE3;i++) {
+ base = memoryGetDeviceBaseAddress(i);
+ size = memoryGetDeviceSize(i);
+ width= memoryGetDeviceWidth(i) * 8;
+ printf("DEV %d: base - 0x%08x\tsize - %dM bytes\twidth - %d bits\n",
+ i, base, size>>20, width);
+ }
+
+ /* Bootrom */
+ base = memoryGetDeviceBaseAddress(BOOT_DEVICE); /* Boot */
+ size = memoryGetDeviceSize(BOOT_DEVICE);
+ width= memoryGetDeviceWidth(BOOT_DEVICE) * 8;
+ printf(" BOOT: base - 0x%08x\tsize - %dM bytes\twidth - %d bits\n",
+ base, size>>20, width);
+}
+
diff --git a/board/evb64260/flash.c b/board/evb64260/flash.c
new file mode 100644
index 0000000..2d2bf1c
--- /dev/null
+++ b/board/evb64260/flash.c
@@ -0,0 +1,805 @@
+/*
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
+ *
+ * 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
+ */
+
+/*
+ * flash.c - flash support for the 512k, 8bit boot flash on the GEVB
+ * most of this file was based on the existing U-Boot
+ * flash drivers.
+ */
+
+#include <common.h>
+#include <mpc8xx.h>
+#include <galileo/gt64260R.h>
+#include <galileo/memory.h>
+#include "intel_flash.h"
+
+#define FLASH_ROM 0xFFFD /* unknown flash type */
+#define FLASH_RAM 0xFFFE /* unknown flash type */
+#define FLASH_MAN_UNKNOWN 0xFFFF0000
+
+/* #define DEBUG */
+/* #define FLASH_ID_OVERRIDE */ /* Hack to set type to 040B if ROM emulator is installed.
+ * Can be used to program a ROM in circuit if a programmer
+ * is not available by swapping the rom out. */
+
+/* Intel flash commands */
+int flash_erase_intel(flash_info_t *info, int s_first, int s_last);
+int write_word_intel(bank_addr_t addr, bank_word_t value);
+
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+static ulong flash_get_size (int portwidth, 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);
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long
+flash_init (void)
+{
+ unsigned int i;
+ unsigned long size_b0 = 0, size_b1 = 0;
+ unsigned long base, flash_size;
+
+ /* Init: no FLASHes known */
+ for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
+ flash_info[i].flash_id = FLASH_UNKNOWN;
+ }
+
+ /* the boot flash */
+ base = CFG_FLASH_BASE;
+ size_b0 = flash_get_size(1, (vu_long *)base, &flash_info[0]);
+
+ printf("[%ldkB@%lx] ", size_b0/1024, base);
+
+ if (flash_info[0].flash_id == FLASH_UNKNOWN) {
+ printf ("## Unknown FLASH at %08lx: Size = 0x%08lx = %ld MB\n",
+ base, size_b0, size_b0<<20);
+ }
+
+ base = memoryGetDeviceBaseAddress(CFG_EXTRA_FLASH_DEVICE);
+ for(i=1;i<CFG_MAX_FLASH_BANKS;i++) {
+ unsigned long size = flash_get_size(CFG_EXTRA_FLASH_WIDTH, (vu_long *)base, &flash_info[i]);
+
+ printf("[%ldMB@%lx] ", size>>20, base);
+
+ if (flash_info[i].flash_id == FLASH_UNKNOWN) {
+ if(i==1) {
+ printf ("## Unknown FLASH at %08lx: Size = 0x%08lx = %ld MB\n",
+ base, size_b1, size_b1<<20);
+ }
+ break;
+ }
+ size_b1+=size;
+ base+=size;
+ }
+
+ flash_size = size_b0 + size_b1;
+ return flash_size;
+}
+
+/*-----------------------------------------------------------------------
+ */
+static void
+flash_get_offsets (ulong base, flash_info_t *info)
+{
+ int i;
+ int sector_size;
+
+ if(!info->sector_count) return;
+
+ /* set up sector start address table */
+ switch(info->flash_id & FLASH_TYPEMASK) {
+ case FLASH_AM040:
+ case FLASH_28F128J3A:
+ case FLASH_28F640J3A:
+ case FLASH_RAM:
+ /* this chip has uniformly spaced sectors */
+ sector_size=info->size/info->sector_count;
+ for (i = 0; i < info->sector_count; i++)
+ info->start[i] = base + (i * sector_size);
+ break;
+ default:
+ if (info->flash_id & FLASH_BTYPE) {
+ /* set sector offsets for bottom boot block type */
+ info->start[0] = base + 0x00000000;
+ info->start[1] = base + 0x00008000;
+ info->start[2] = base + 0x0000C000;
+ info->start[3] = base + 0x00010000;
+ for (i = 4; i < info->sector_count; i++) {
+ info->start[i] = base + (i * 0x00020000) - 0x00060000;
+ }
+ } else {
+ /* set sector offsets for top boot block type */
+ i = info->sector_count - 1;
+ info->start[i--] = base + info->size - 0x00008000;
+ info->start[i--] = base + info->size - 0x0000C000;
+ info->start[i--] = base + info->size - 0x00010000;
+ for (; i >= 0; i--) {
+ info->start[i] = base + i * 0x00020000;
+ }
+ }
+ }
+}
+
+/*-----------------------------------------------------------------------
+ */
+void
+flash_print_info (flash_info_t *info)
+{
+ int i;
+
+ 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_INTEL: printf ("INTEL "); break;
+ default: printf ("Unknown Vendor "); break;
+ }
+
+ switch (info->flash_id & FLASH_TYPEMASK) {
+ case FLASH_AM040:
+ printf ("AM29LV040B (4 Mbit, bottom boot sect)\n");
+ break;
+ case FLASH_AM400B:
+ printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
+ break;
+ case FLASH_AM400T:
+ printf ("AM29LV400T (4 Mbit, top boot sector)\n");
+ break;
+ case FLASH_AM800B:
+ printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
+ break;
+ case FLASH_AM800T:
+ printf ("AM29LV800T (8 Mbit, top boot sector)\n");
+ break;
+ case FLASH_AM160B:
+ printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
+ break;
+ case FLASH_AM160T:
+ printf ("AM29LV160T (16 Mbit, top boot sector)\n");
+ break;
+ case FLASH_AM320B:
+ printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
+ break;
+ case FLASH_AM320T:
+ printf ("AM29LV320T (32 Mbit, top boot sector)\n");
+ break;
+ case FLASH_28F640J3A:
+ printf ("28F640J3A (64 Mbit)\n");
+ break;
+ case FLASH_28F128J3A:
+ printf ("28F128J3A (128 Mbit)\n");
+ break;
+ case FLASH_ROM:
+ printf ("ROM\n");
+ break;
+ case FLASH_RAM:
+ printf ("RAM\n");
+ break;
+ default:
+ printf ("Unknown Chip Type\n");
+ break;
+ }
+
+ puts (" Size: ");
+ print_size (info->size, "");
+ printf (" in %d Sectors\n", 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");
+ return;
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+
+/*-----------------------------------------------------------------------
+ */
+
+/*
+ * The following code cannot be run from FLASH!
+ */
+
+static inline void flash_cmd(int width, volatile unsigned char *addr, int offset, unsigned char cmd)
+{
+ /* supports 1x8, 1x16, and 2x16 */
+ /* 2x8 and 4x8 are not supported */
+ if(width==4) {
+ /* assuming chips are in 16 bit mode */
+ /* 2x16 */
+ unsigned long cmd32=(cmd<<16)|cmd;
+ *(volatile unsigned long *)(addr+offset*2)=cmd32;
+ } else {
+ /* 1x16 or 1x8 */
+ *(volatile unsigned char *)(addr+offset)=cmd;
+ }
+}
+
+static ulong
+flash_get_size (int portwidth, vu_long *addr, flash_info_t *info)
+{
+ short i;
+ volatile unsigned char *caddr = (unsigned char *)addr;
+ volatile unsigned short *saddr = (unsigned short *)addr;
+ volatile unsigned long *laddr = (unsigned long *)addr;
+ char old[2], save;
+ ulong id, manu, base = (ulong)addr;
+
+ info->portwidth=portwidth;
+
+ save = *caddr;
+
+ flash_cmd(portwidth,caddr,0,0xf0);
+ flash_cmd(portwidth,caddr,0,0xf0);
+
+ udelay(10);
+
+ old[0] = caddr[0];
+ old[1] = caddr[1];
+
+
+ if(old[0]!=0xf0) {
+ flash_cmd(portwidth,caddr,0,0xf0);
+ flash_cmd(portwidth,caddr,0,0xf0);
+
+ udelay(10);
+
+ if(*caddr==0xf0) {
+ /* this area is ROM */
+ *caddr=save;
+#ifndef FLASH_ID_OVERRIDE
+ info->flash_id = FLASH_ROM + FLASH_MAN_UNKNOWN;
+ info->sector_count = 8;
+ info->size = 0x80000;
+#else
+ info->flash_id = FLASH_MAN_AMD + FLASH_AM040;
+ info->sector_count = 8;
+ info->size = 0x80000;
+ info->chipwidth=1;
+#endif
+ flash_get_offsets(base, info);
+ return info->size;
+ }
+ } else {
+ *caddr=0;
+
+ udelay(10);
+
+ if(*caddr==0) {
+ /* this area is RAM */
+ *caddr=save;
+ info->flash_id = FLASH_RAM + FLASH_MAN_UNKNOWN;
+ info->sector_count = 8;
+ info->size = 0x80000;
+ flash_get_offsets(base, info);
+ return info->size;
+ }
+ flash_cmd(portwidth,caddr,0,0xf0);
+
+ udelay(10);
+ }
+
+ /* Write auto select command: read Manufacturer ID */
+ flash_cmd(portwidth,caddr,0x555,0xAA);
+ flash_cmd(portwidth,caddr,0x2AA,0x55);
+ flash_cmd(portwidth,caddr,0x555,0x90);
+
+ udelay(10);
+
+ if ((caddr[0] == old[0]) &&
+ (caddr[1] == old[1])) {
+
+ /* this area is ROM */
+#ifndef FLASH_ID_OVERRIDE
+ info->flash_id = FLASH_ROM + FLASH_MAN_UNKNOWN;
+ info->sector_count = 8;
+ info->size = 0x80000;
+#else
+ info->flash_id = FLASH_MAN_AMD + FLASH_AM040;
+ info->sector_count = 8;
+ info->size = 0x80000;
+ info->chipwidth=1;
+#endif
+ flash_get_offsets(base, info);
+ return info->size;
+#ifdef DEBUG
+ } else {
+ printf("%px%d: %02x:%02x -> %02x:%02x\n",
+ caddr, portwidth, old[0], old[1],
+ caddr[0], caddr[1]);
+#endif
+ }
+
+ switch(portwidth) {
+ case 1:
+ manu = caddr[0];
+ manu |= manu<<16;
+ id = caddr[1];
+ break;
+ case 2:
+ manu = saddr[0];
+ manu |= manu<<16;
+ id = saddr[1];
+ id |= id<<16;
+ break;
+ case 4:
+ manu = laddr[0];
+ id = laddr[1];
+ break;
+ default:
+ id = manu = -1;
+ break;
+ }
+
+#ifdef DEBUG
+ printf("\n%08lx:%08lx:%08lx\n", base, manu, id);
+ printf("%08lx %08lx %08lx %08lx\n",
+ laddr[0],laddr[1],laddr[2],laddr[3]);
+#endif
+
+ switch (manu) {
+ case AMD_MANUFACT:
+ info->flash_id = FLASH_MAN_AMD;
+ break;
+ case FUJ_MANUFACT:
+ info->flash_id = FLASH_MAN_FUJ;
+ break;
+ case INTEL_MANUFACT:
+ info->flash_id = FLASH_MAN_INTEL;
+ break;
+ default:
+ printf("Unknown Mfr [%08lx]:%08lx\n", manu, id);
+ info->flash_id = FLASH_UNKNOWN;
+ info->sector_count = 0;
+ info->size = 0;
+ return (0); /* no or unknown flash */
+ }
+
+ switch (id) {
+ case AMD_ID_LV400T:
+ info->flash_id += FLASH_AM400T;
+ info->sector_count = 11;
+ info->size = 0x00100000;
+ info->chipwidth=1;
+ break; /* => 1 MB */
+
+ case AMD_ID_LV400B:
+ info->flash_id += FLASH_AM400B;
+ info->sector_count = 11;
+ info->size = 0x00100000;
+ info->chipwidth=1;
+ break; /* => 1 MB */
+
+ case AMD_ID_LV800T:
+ info->flash_id += FLASH_AM800T;
+ info->sector_count = 19;
+ info->size = 0x00200000;
+ info->chipwidth=1;
+ break; /* => 2 MB */
+
+ case AMD_ID_LV800B:
+ info->flash_id += FLASH_AM800B;
+ info->sector_count = 19;
+ info->size = 0x00200000;
+ info->chipwidth=1;
+ break; /* => 2 MB */
+
+ case AMD_ID_LV160T:
+ info->flash_id += FLASH_AM160T;
+ info->sector_count = 35;
+ info->size = 0x00400000;
+ info->chipwidth=1;
+ break; /* => 4 MB */
+
+ case AMD_ID_LV160B:
+ info->flash_id += FLASH_AM160B;
+ info->sector_count = 35;
+ info->size = 0x00400000;
+ info->chipwidth=1;
+ break; /* => 4 MB */
+#if 0 /* enable when device IDs are available */
+ case AMD_ID_LV320T:
+ info->flash_id += FLASH_AM320T;
+ info->sector_count = 67;
+ info->size = 0x00800000;
+ break; /* => 8 MB */
+
+ case AMD_ID_LV320B:
+ info->flash_id += FLASH_AM320B;
+ info->sector_count = 67;
+ info->size = 0x00800000;
+ break; /* => 8 MB */
+#endif
+ case AMD_ID_LV040B:
+ info->flash_id += FLASH_AM040;
+ info->sector_count = 8;
+ info->size = 0x80000;
+ info->chipwidth=1;
+ break;
+
+ case INTEL_ID_28F640J3A:
+ info->flash_id += FLASH_28F640J3A;
+ info->sector_count = 64;
+ info->size = 128*1024 * 64; /* 128kbytes x 64 blocks */
+ info->chipwidth=2;
+ if(portwidth==4) info->size*=2; /* 2x16 */
+ break;
+
+ case INTEL_ID_28F128J3A:
+ info->flash_id += FLASH_28F128J3A;
+ info->sector_count = 128;
+ info->size = 128*1024 * 128; /* 128kbytes x 128 blocks */
+ info->chipwidth=2;
+ if(portwidth==4) info->size*=2; /* 2x16 */
+ break;
+
+ default:
+ printf("Unknown id %lx:[%lx]\n", manu, id);
+ info->flash_id = FLASH_UNKNOWN;
+ info->chipwidth=1;
+ return (0); /* => no or unknown flash */
+
+ }
+
+ flash_get_offsets(base, info);
+
+#if 0
+ /* set up sector start address table */
+ if (info->flash_id & FLASH_AM040) {
+ /* this chip has uniformly spaced sectors */
+ for (i = 0; i < info->sector_count; i++)
+ info->start[i] = base + (i * 0x00010000);
+
+ } else if (info->flash_id & FLASH_BTYPE) {
+ /* set sector offsets for bottom boot block type */
+ info->start[0] = base + 0x00000000;
+ info->start[1] = base + 0x00008000;
+ info->start[2] = base + 0x0000C000;
+ info->start[3] = base + 0x00010000;
+ for (i = 4; i < info->sector_count; i++) {
+ info->start[i] = base + (i * 0x00020000) - 0x00060000;
+ }
+ } else {
+ /* set sector offsets for top boot block type */
+ i = info->sector_count - 1;
+ info->start[i--] = base + info->size - 0x00008000;
+ info->start[i--] = base + info->size - 0x0000C000;
+ info->start[i--] = base + info->size - 0x00010000;
+ for (; i >= 0; i--) {
+ info->start[i] = base + i * 0x00020000;
+ }
+ }
+#endif
+
+ /* 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 */
+ caddr = (volatile unsigned char *)(info->start[i]);
+ saddr = (volatile unsigned short *)(info->start[i]);
+ laddr = (volatile unsigned long *)(info->start[i]);
+ if(portwidth==1)
+ info->protect[i] = caddr[2] & 1;
+ else if(portwidth==2)
+ info->protect[i] = saddr[2] & 1;
+ else
+ info->protect[i] = laddr[2] & 1;
+ }
+
+ /*
+ * Prevent writes to uninitialized FLASH.
+ */
+ if (info->flash_id != FLASH_UNKNOWN) {
+ caddr = (volatile unsigned char *)info->start[0];
+
+ flash_cmd(portwidth,caddr,0,0xF0); /* reset bank */
+ }
+
+ return (info->size);
+}
+
+/* TODO: 2x16 unsupported */
+int
+flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+ volatile unsigned char *addr = (char *)(info->start[0]);
+ int flag, prot, sect, l_sect;
+ ulong start, now, last;
+
+ /* TODO: 2x16 unsupported */
+ if(info->portwidth==4) return 1;
+
+ if((info->flash_id & FLASH_TYPEMASK) == FLASH_ROM) return 1;
+ if((info->flash_id & FLASH_TYPEMASK) == FLASH_RAM) {
+ for (sect = s_first; sect<=s_last; sect++) {
+ int sector_size=info->size/info->sector_count;
+ addr = (char *)(info->start[sect]);
+ memset((void *)addr, 0, sector_size);
+ }
+ return 0;
+ }
+
+ 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_VENDMASK) == FLASH_MAN_INTEL) {
+ return flash_erase_intel(info,
+ (unsigned short)s_first,
+ (unsigned short)s_last);
+ }
+
+#if 0
+ if ((info->flash_id == FLASH_UNKNOWN) ||
+ (info->flash_id > FLASH_AMD_COMP)) {
+ printf ("Can't erase unknown flash type %08lx - aborted\n",
+ info->flash_id);
+ return 1;
+ }
+#endif
+
+ 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");
+ }
+
+ l_sect = -1;
+
+ /* Disable interrupts which might cause a timeout here */
+ flag = disable_interrupts();
+
+ flash_cmd(info->portwidth,addr,0x555,0xAA);
+ flash_cmd(info->portwidth,addr,0x2AA,0x55);
+ flash_cmd(info->portwidth,addr,0x555,0x80);
+ flash_cmd(info->portwidth,addr,0x555,0xAA);
+ flash_cmd(info->portwidth,addr,0x2AA,0x55);
+
+ /* Start erase on unprotected sectors */
+ for (sect = s_first; sect<=s_last; sect++) {
+ if (info->protect[sect] == 0) { /* not protected */
+ addr = (char *)(info->start[sect]);
+ flash_cmd(info->portwidth,addr,0,0x30);
+ l_sect = sect;
+ }
+ }
+
+ /* re-enable interrupts if necessary */
+ if (flag)
+ enable_interrupts();
+
+ /* wait at least 80us - let's wait 1 ms */
+ udelay (1000);
+
+ /*
+ * We wait for the last triggered sector
+ */
+ if (l_sect < 0)
+ goto DONE;
+
+ start = get_timer (0);
+ last = start;
+ addr = (volatile unsigned char *)(info->start[l_sect]);
+ /* broken for 2x16: TODO */
+ while ((addr[0] & 0x80) != 0x80) {
+ if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
+ printf ("Timeout\n");
+ return 1;
+ }
+ /* show that we're waiting */
+ if ((now - last) > 1000) { /* every second */
+ putc ('.');
+ last = now;
+ }
+ }
+
+DONE:
+ /* reset to read mode */
+ addr = (volatile unsigned char *)info->start[0];
+ flash_cmd(info->portwidth,addr,0,0xf0);
+ flash_cmd(info->portwidth,addr,0,0xf0);
+
+ printf (" done\n");
+ return 0;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+
+/* broken for 2x16: TODO */
+int
+write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+ ulong cp, wp, data;
+ int i, l, rc;
+
+ if(info->portwidth==4) return 1;
+
+ if((info->flash_id & FLASH_TYPEMASK) == FLASH_ROM) return 0;
+ if((info->flash_id & FLASH_TYPEMASK) == FLASH_RAM) {
+ memcpy((void *)addr, src, cnt);
+ return 0;
+ }
+
+ 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
+ */
+/* broken for 2x16: TODO */
+static int
+write_word (flash_info_t *info, ulong dest, ulong data)
+{
+ volatile unsigned char *addr = (char *)(info->start[0]);
+ ulong start;
+ int flag, i;
+
+ if(info->portwidth==4) return 1;
+
+ if((info->flash_id & FLASH_TYPEMASK) == FLASH_ROM) return 1;
+ if((info->flash_id & FLASH_TYPEMASK) == FLASH_RAM) {
+ *(unsigned long *)dest=data;
+ return 0;
+ }
+ if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
+ unsigned short low = data & 0xffff;
+ unsigned short hi = (data >> 16) & 0xffff;
+ int ret = write_word_intel((bank_addr_t)dest, hi);
+
+ if (!ret) ret = write_word_intel((bank_addr_t)(dest+2), low);
+
+ return ret;
+ }
+
+ /* Check if Flash is (sufficiently) erased */
+ if ((*((vu_long *)dest) & data) != data) {
+ return (2);
+ }
+ /* Disable interrupts which might cause a timeout here */
+ flag = disable_interrupts();
+
+ /* first, perform an unlock bypass command to speed up flash writes */
+ addr[0x555] = 0xAA;
+ addr[0x2AA] = 0x55;
+ addr[0x555] = 0x20;
+
+ /* write each byte out */
+ for (i = 0; i < 4; i++) {
+ char *data_ch = (char *)&data;
+ addr[0] = 0xA0;
+ *(((char *)dest)+i) = data_ch[i];
+ udelay(10); /* XXX */
+ }
+
+ /* we're done, now do an unlock bypass reset */
+ addr[0] = 0x90;
+ addr[0] = 0x00;
+
+ /* re-enable interrupts if necessary */
+ if (flag)
+ enable_interrupts();
+
+ /* data polling for D7 */
+ start = get_timer (0);
+ while ((*((vu_long *)dest) & 0x00800080) != (data & 0x00800080)) {
+ if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+ return (1);
+ }
+ }
+ return (0);
+}
diff --git a/board/evb64260/memory.c b/board/evb64260/memory.c
new file mode 100644
index 0000000..9d301f8
--- /dev/null
+++ b/board/evb64260/memory.c
@@ -0,0 +1,457 @@
+/* Memory.c - Memory mappings and remapping functions */
+
+/* Copyright - Galileo technology. */
+
+/* modified by Josh Huber to clean some things up, and
+ * fit it into the U-Boot framework */
+
+#include <galileo/core.h>
+#include <galileo/memory.h>
+
+/********************************************************************
+* memoryGetBankBaseAddress - Gets the base address of a memory bank
+* - If the memory bank size is 0 then this base address has no meaning!!!
+*
+*
+* INPUTS: MEMORY_BANK bank - The bank we ask for its base Address.
+* OUTPUT: N/A
+* RETURNS: Memory bank base address.
+*********************************************************************/
+static unsigned long memoryGetBankRegOffset(MEMORY_BANK bank)
+{
+ switch (bank)
+ {
+ case BANK0:
+ return SCS_0_LOW_DECODE_ADDRESS;
+ case BANK1:
+ return SCS_1_LOW_DECODE_ADDRESS;
+ case BANK2:
+ return SCS_2_LOW_DECODE_ADDRESS;
+ case BANK3:
+ return SCS_3_LOW_DECODE_ADDRESS;
+ }
+ return SCS_0_LOW_DECODE_ADDRESS; /* default value */
+}
+
+unsigned int memoryGetBankBaseAddress(MEMORY_BANK bank)
+{
+ unsigned int base;
+ unsigned int regOffset=memoryGetBankRegOffset(bank);
+
+ GT_REG_READ(regOffset,&base);
+ base = base << 20;
+ return base;
+}
+
+/********************************************************************
+* memoryGetDeviceBaseAddress - Gets the base address of a device.
+* - If the device size is 0 then this base address has no meaning!!!
+*
+*
+* INPUT: DEVICE device - The device we ask for its base address.
+* OUTPUT: N/A
+* RETURNS: Device base address.
+*********************************************************************/
+static unsigned int memoryGetDeviceRegOffset(DEVICE device)
+{
+ switch (device)
+ {
+ case DEVICE0:
+ return CS_0_LOW_DECODE_ADDRESS;
+ case DEVICE1:
+ return CS_1_LOW_DECODE_ADDRESS;
+ case DEVICE2:
+ return CS_2_LOW_DECODE_ADDRESS;
+ case DEVICE3:
+ return CS_3_LOW_DECODE_ADDRESS;
+ case BOOT_DEVICE:
+ return BOOTCS_LOW_DECODE_ADDRESS;
+ }
+ return CS_0_LOW_DECODE_ADDRESS; /* default value */
+}
+
+unsigned int memoryGetDeviceBaseAddress(DEVICE device)
+{
+ unsigned int regBase;
+ unsigned int regEnd;
+ unsigned int regOffset=memoryGetDeviceRegOffset(device);
+
+ GT_REG_READ(regOffset, &regBase);
+ GT_REG_READ(regOffset+8, &regEnd);
+
+ if(regEnd<=regBase) return 0xffffffff; /* ERROR !!! */
+
+ regBase = regBase << 20;
+ return regBase;
+}
+
+/********************************************************************
+* memoryGetBankSize - Returns the size of a memory bank.
+*
+*
+* INPUT: MEMORY_BANK bank - The bank we ask for its size.
+* OUTPUT: N/A
+* RETURNS: Memory bank size.
+*********************************************************************/
+unsigned int memoryGetBankSize(MEMORY_BANK bank)
+{
+ unsigned int size,base;
+ unsigned int highValue;
+ unsigned int highAddress=memoryGetBankRegOffset(bank)+8;
+
+ base = memoryGetBankBaseAddress(bank);
+ GT_REG_READ(highAddress,&highValue);
+ highValue = (highValue + 1) << 20;
+ if(base > highValue)
+ size=0;
+ else
+ size = highValue - base;
+ return size;
+}
+
+/********************************************************************
+* memoryGetDeviceSize - Returns the size of a device memory space
+*
+*
+* INPUT: DEVICE device - The device we ask for its base address.
+* OUTPUT: N/A
+* RETURNS: Size of a device memory space.
+*********************************************************************/
+unsigned int memoryGetDeviceSize(DEVICE device)
+{
+ unsigned int size,base;
+ unsigned int highValue;
+ unsigned int highAddress=memoryGetDeviceRegOffset(device)+8;
+
+ base = memoryGetDeviceBaseAddress(device);
+ GT_REG_READ(highAddress,&highValue);
+ if (highValue == 0xfff)
+ {
+ size = (~base) + 1; /* what the heck is this? */
+ return size;
+ }
+ else
+ highValue = (highValue + 1) << 20;
+
+ if(base > highValue)
+ size=0;
+ else
+ size = highValue - base;
+ return size;
+}
+
+/********************************************************************
+* memoryGetDeviceWidth - A device can be with: 1,2,4 or 8 Bytes data width.
+* The width is determine in registers: 'Device Parameters'
+* registers (0x45c, 0x460, 0x464, 0x468, 0x46c - for each device.
+* at bits: [21:20].
+*
+* INPUT: DEVICE device - Device number
+* OUTPUT: N/A
+* RETURNS: Device width in Bytes (1,2,4 or 8), 0 if error had occurred.
+*********************************************************************/
+unsigned int memoryGetDeviceWidth(DEVICE device)
+{
+ unsigned int width;
+ unsigned int regValue;
+
+ GT_REG_READ(DEVICE_BANK0PARAMETERS + device*4,&regValue);
+ width = (regValue & 0x00300000) >> 20;
+ switch (width)
+ {
+ case 0:
+ return 1;
+ case 1:
+ return 2;
+ case 2:
+ return 4;
+ case 3:
+ return 8;
+ default:
+ return 0;
+ }
+}
+
+bool memoryMapBank(MEMORY_BANK bank, unsigned int bankBase,unsigned int bankLength)
+{
+ unsigned int low=0xfff;
+ unsigned int high=0x0;
+ unsigned int regOffset=memoryGetBankRegOffset(bank);
+
+ if(bankLength!=0) {
+ low = (bankBase >> 20) & 0xffff;
+ high=((bankBase+bankLength)>>20)-1;
+ }
+
+#ifdef DEBUG
+ {
+ unsigned int oldLow, oldHigh;
+ GT_REG_READ(regOffset,&oldLow);
+ GT_REG_READ(regOffset+8,&oldHigh);
+
+ printf("b%d %x-%x->%x-%x\n", bank, oldLow, oldHigh, low, high);
+ }
+#endif
+
+ GT_REG_WRITE(regOffset,low);
+ GT_REG_WRITE(regOffset+8,high);
+
+ return true;
+}
+bool memoryMapDeviceSpace(DEVICE device, unsigned int deviceBase,unsigned int deviceLength)
+{
+ /* TODO: what are appropriate "unmapped" values? */
+ unsigned int low=0xfff;
+ unsigned int high=0x0;
+ unsigned int regOffset=memoryGetDeviceRegOffset(device);
+
+ if(deviceLength != 0) {
+ low=deviceBase>>20;
+ high=((deviceBase+deviceLength)>>20)-1;
+ } else {
+ /* big problems in here... */
+ /* this will HANG */
+ }
+
+ GT_REG_WRITE(regOffset,low);
+ GT_REG_WRITE(regOffset+8,high);
+
+ return true;
+}
+
+
+/********************************************************************
+* memoryMapInternalRegistersSpace - Sets new base address for the internals
+* registers.
+*
+* INPUTS: unsigned int internalRegBase - The new base address.
+* RETURNS: true on success, false on failure
+*********************************************************************/
+bool memoryMapInternalRegistersSpace(unsigned int internalRegBase)
+{
+ unsigned int currentValue;
+ unsigned int internalValue = internalRegBase;
+
+ internalRegBase = (internalRegBase >> 20);
+ GT_REG_READ(INTERNAL_SPACE_DECODE,&currentValue);
+ internalRegBase = (currentValue & 0xffff0000) | internalRegBase;
+ GT_REG_WRITE(INTERNAL_SPACE_DECODE,internalRegBase);
+ INTERNAL_REG_BASE_ADDR = internalValue;
+ return true;
+}
+
+/********************************************************************
+* memoryGetInternalRegistersSpace - Gets internal registers Base Address.
+*
+* INPUTS: unsigned int internalRegBase - The new base address.
+* RETURNS: true on success, false on failure
+*********************************************************************/
+unsigned int memoryGetInternalRegistersSpace(void)
+{
+ return INTERNAL_REG_BASE_ADDR;
+}
+
+/********************************************************************
+* memorySetProtectRegion - This function modifys one of the 8 regions with
+* one of the three protection mode.
+* - Be advised to check the spec before modifying them.
+*
+*
+* Inputs: CPU_PROTECT_REGION - one of the eight regions.
+* CPU_ACCESS - general access.
+* CPU_WRITE - read only access.
+* CPU_CACHE_PROTECT - chache access.
+* we defining CPU because there is another protect from the pci SIDE.
+* Returns: false if one of the parameters is wrong and true else
+*********************************************************************/
+bool memorySetProtectRegion(MEMORY_PROTECT_REGION region,
+ MEMORY_ACCESS memAccess,
+ MEMORY_ACCESS_WRITE memWrite,
+ MEMORY_CACHE_PROTECT cacheProtection,
+ unsigned int baseAddress,
+ unsigned int regionLength)
+{
+ unsigned int protectHigh = baseAddress + regionLength;
+
+ if(regionLength == 0) /* closing the region */
+ {
+ GT_REG_WRITE(CPU_LOW_PROTECT_ADDRESS_0 + 0x10*region,0x0000ffff);
+ GT_REG_WRITE(CPU_HIGH_PROTECT_ADDRESS_0 + 0x10*region,0);
+ return true;
+ }
+ baseAddress = (baseAddress & 0xfff00000) >> 20;
+ baseAddress = baseAddress | memAccess << 16 | memWrite << 17
+ | cacheProtection << 18;
+ GT_REG_WRITE(CPU_LOW_PROTECT_ADDRESS_0 + 0x10*region,baseAddress);
+ protectHigh = (protectHigh & 0xfff00000) >> 20;
+ GT_REG_WRITE(CPU_HIGH_PROTECT_ADDRESS_0 + 0x10*region,protectHigh - 1);
+ return true;
+}
+
+/********************************************************************
+* memorySetRegionSnoopMode - This function modifys one of the 4 regions which
+* supports Cache Coherency.
+*
+*
+* Inputs: SNOOP_REGION region - One of the four regions.
+* SNOOP_TYPE snoopType - There is four optional Types:
+* 1. No Snoop.
+* 2. Snoop to WT region.
+* 3. Snoop to WB region.
+* 4. Snoop & Invalidate to WB region.
+* unsigned int baseAddress - Base Address of this region.
+* unsigned int topAddress - Top Address of this region.
+* Returns: false if one of the parameters is wrong and true else
+*********************************************************************/
+bool memorySetRegionSnoopMode(MEMORY_SNOOP_REGION region,
+ MEMORY_SNOOP_TYPE snoopType,
+ unsigned int baseAddress,
+ unsigned int regionLength)
+{
+ unsigned int snoopXbaseAddress;
+ unsigned int snoopXtopAddress;
+ unsigned int data;
+ unsigned int snoopHigh = baseAddress + regionLength;
+
+ if( (region > MEM_SNOOP_REGION3) || (snoopType > MEM_SNOOP_WB) )
+ return false;
+ snoopXbaseAddress = SNOOP_BASE_ADDRESS_0 + 0x10 * region;
+ snoopXtopAddress = SNOOP_TOP_ADDRESS_0 + 0x10 * region;
+ if(regionLength == 0) /* closing the region */
+ {
+ GT_REG_WRITE(snoopXbaseAddress,0x0000ffff);
+ GT_REG_WRITE(snoopXtopAddress,0);
+ return true;
+ }
+ baseAddress = baseAddress & 0xffff0000;
+ data = (baseAddress >> 16) | snoopType << 16;
+ GT_REG_WRITE(snoopXbaseAddress,data);
+ snoopHigh = (snoopHigh & 0xfff00000) >> 20;
+ GT_REG_WRITE(snoopXtopAddress,snoopHigh - 1);
+ return true;
+}
+
+/********************************************************************
+* memoryRemapAddress - This fubction used for address remapping.
+*
+*
+* Inputs: regOffset: remap register
+* remapValue :
+* Returns: false if one of the parameters is erroneous,true otherwise.
+*********************************************************************/
+bool memoryRemapAddress(unsigned int remapReg, unsigned int remapValue)
+{
+ unsigned int valueForReg;
+ valueForReg = (remapValue & 0xfff00000) >> 20;
+ GT_REG_WRITE(remapReg, valueForReg);
+ return true;
+}
+
+/********************************************************************
+* memoryGetDeviceParam - This function used for getting device parameters from
+* DEVICE BANK PARAMETERS REGISTER
+*
+*
+* Inputs: - deviceParam: STRUCT with paramiters for DEVICE BANK
+* PARAMETERS REGISTER
+* - deviceNum : number of device
+* Returns: false if one of the parameters is erroneous,true otherwise.
+*********************************************************************/
+bool memoryGetDeviceParam(DEVICE_PARAM *deviceParam, DEVICE deviceNum)
+{
+ unsigned int valueOfReg;
+ unsigned int calcData;
+
+ GT_REG_READ(DEVICE_BANK0PARAMETERS + 4 * deviceNum, &valueOfReg);
+ calcData = (0x7 & valueOfReg) + ((0x400000 & valueOfReg) >> 19);
+ deviceParam -> turnOff = calcData; /* Turn Off */
+
+ calcData = ((0x78 & valueOfReg) >> 3) + ((0x800000 & valueOfReg) >> 19);
+ deviceParam -> acc2First = calcData; /* Access To First */
+
+ calcData = ((0x780 & valueOfReg) >> 7) + ((0x1000000 & valueOfReg) >> 20);
+ deviceParam -> acc2Next = calcData; /* Access To Next */
+
+ calcData = ((0x3800 & valueOfReg) >> 11) + ((0x2000000 & valueOfReg) >> 22);
+ deviceParam -> ale2Wr = calcData; /* Ale To Write */
+
+ calcData = ((0x1c000 & valueOfReg) >> 14) + ((0x4000000 & valueOfReg) >> 23);
+ deviceParam -> wrLow = calcData; /* Write Active */
+
+ calcData = ((0xe0000 & valueOfReg) >> 17) + ((0x8000000 & valueOfReg) >> 24);
+ deviceParam -> wrHigh = calcData; /* Write High */
+
+ calcData = ((0x300000 & valueOfReg) >> 20);
+ switch (calcData)
+ {
+ case 0:
+ deviceParam -> deviceWidth = 1; /* one Byte - 8-bit */
+ break;
+ case 1:
+ deviceParam -> deviceWidth = 2; /* two Bytes - 16-bit */
+ break;
+ case 2:
+ deviceParam -> deviceWidth = 4; /* four Bytes - 32-bit */
+ break;
+ case 3:
+ deviceParam -> deviceWidth = 8; /* eight Bytes - 64-bit */
+ break;
+ default:
+ deviceParam -> deviceWidth = 1;
+ break;
+ }
+ return true;
+}
+
+/********************************************************************
+* memorySetDeviceParam - This function used for setting device parameters to
+* DEVICE BANK PARAMETERS REGISTER
+*
+*
+* Inputs: - deviceParam: STRUCT for store paramiters from DEVICE BANK
+* PARAMETERS REGISTER
+* - deviceNum : number of device
+* Returns: false if one of the parameters is erroneous,true otherwise.
+*********************************************************************/
+bool memorySetDeviceParam(DEVICE_PARAM *deviceParam, DEVICE deviceNum)
+{
+ unsigned int valueForReg;
+
+ if((deviceParam -> turnOff >= 0xf) || (deviceParam -> acc2First >= 0x1f) ||
+ (deviceParam -> acc2Next >= 0x1f) || (deviceParam -> ale2Wr >= 0xf) ||
+ (deviceParam -> wrLow >= 0xf) || (deviceParam -> wrHigh >= 0xf))
+ return false;
+ valueForReg = (((deviceParam -> turnOff) & 0x7) |
+ (((deviceParam -> turnOff) & 0x8) << 19) |
+ (((deviceParam -> acc2First) & 0xf) << 3) |
+ (((deviceParam -> acc2First) & 0x10) << 19) |
+ (((deviceParam -> acc2Next) & 0xf) << 7) |
+ (((deviceParam -> acc2Next) & 0x10) << 20) |
+ (((deviceParam -> ale2Wr) & 0x7) << 11) |
+ (((deviceParam -> ale2Wr) & 0xf) << 22) |
+ (((deviceParam -> wrLow) & 0x7) << 14) |
+ (((deviceParam -> wrLow) & 0xf) << 23) |
+ (((deviceParam -> wrHigh) & 0x7) << 17) |
+ (((deviceParam -> wrHigh) & 0xf) << 24));
+ /* insert the device width: */
+ switch(deviceParam->deviceWidth)
+ {
+ case 1:
+ valueForReg = valueForReg | _8BIT;
+ break;
+ case 2:
+ valueForReg = valueForReg | _16BIT;
+ break;
+ case 4:
+ valueForReg = valueForReg | _32BIT;
+ break;
+ case 8:
+ valueForReg = valueForReg | _64BIT;
+ break;
+ default:
+ valueForReg = valueForReg | _8BIT;
+ break;
+ }
+ GT_REG_WRITE(DEVICE_BANK0PARAMETERS + 4 * deviceNum, valueForReg);
+ return true;
+}
diff --git a/board/evb64260/u-boot.lds b/board/evb64260/u-boot.lds
new file mode 100644
index 0000000..7b10c0d
--- /dev/null
+++ b/board/evb64260/u-boot.lds
@@ -0,0 +1,129 @@
+/*
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
+ *
+ * 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
+ */
+
+/*
+ * u-boot.lds - linker script for U-Boot on the Galileo Eval Board.
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+ __DYNAMIC = 0; */
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = + SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) }
+ .plt : { *(.plt) }
+ .text :
+ {
+ cpu/74xx_7xx/start.o (.text)
+
+/* store the environment in a seperate sector in the boot flash */
+/* . = env_offset; */
+/* common/environment.o(.text) */
+
+ *(.text)
+ *(.fixup)
+ *(.got1)
+ }
+ _etext = .;
+ PROVIDE (etext = .);
+ .rodata :
+ {
+ *(.rodata)
+ *(.rodata1)
+ }
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x00FF) & 0xFFFFFF00;
+ _erotext = .;
+ PROVIDE (erotext = .);
+ .reloc :
+ {
+ *(.got)
+ _GOT2_TABLE_ = .;
+ *(.got2)
+ _FIXUP_TABLE_ = .;
+ *(.fixup)
+ }
+ __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+ __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ . = ALIGN(256);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(256);
+ __init_end = .;
+
+ __bss_start = .;
+ .bss :
+ {
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ _end = . ;
+ PROVIDE (end = .);
+}