diff options
Diffstat (limited to 'qemu/roms/u-boot/board/esd/pf5200')
-rw-r--r-- | qemu/roms/u-boot/board/esd/pf5200/Makefile | 14 | ||||
-rw-r--r-- | qemu/roms/u-boot/board/esd/pf5200/flash.c | 445 | ||||
-rw-r--r-- | qemu/roms/u-boot/board/esd/pf5200/mt46v16m16-75.h | 16 | ||||
-rw-r--r-- | qemu/roms/u-boot/board/esd/pf5200/pf5200.c | 357 |
4 files changed, 832 insertions, 0 deletions
diff --git a/qemu/roms/u-boot/board/esd/pf5200/Makefile b/qemu/roms/u-boot/board/esd/pf5200/Makefile new file mode 100644 index 000000000..a54289c07 --- /dev/null +++ b/qemu/roms/u-boot/board/esd/pf5200/Makefile @@ -0,0 +1,14 @@ +# +# (C) Copyright 2003-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +# Objects for Xilinx JTAG programming (CPLD) +# CPLD = ../common/xilinx_jtag/lenval.o \ +# ../common/xilinx_jtag/micro.o \ +# ../common/xilinx_jtag/ports.o + +# obj-y = pf5200.o flash.o $(CPLD) +obj-y = pf5200.o flash.o diff --git a/qemu/roms/u-boot/board/esd/pf5200/flash.c b/qemu/roms/u-boot/board/esd/pf5200/flash.c new file mode 100644 index 000000000..e1b13bfc4 --- /dev/null +++ b/qemu/roms/u-boot/board/esd/pf5200/flash.c @@ -0,0 +1,445 @@ +/* + * (C) Copyright 2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> + +flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */ + +typedef unsigned short FLASH_PORT_WIDTH; +typedef volatile unsigned short FLASH_PORT_WIDTHV; + +#define FLASH_ID_MASK 0x00FF + +#define FPW FLASH_PORT_WIDTH +#define FPWV FLASH_PORT_WIDTHV + +#define FLASH_CYCLE1 0x0555 +#define FLASH_CYCLE2 0x0aaa +#define FLASH_ID1 0x00 +#define FLASH_ID2 0x01 +#define FLASH_ID3 0x0E +#define FLASH_ID4 0x0F + +/*----------------------------------------------------------------------- + * Functions + */ +static ulong flash_get_size(FPWV * addr, flash_info_t * info); +static void flash_reset(flash_info_t * info); +static int write_word_amd(flash_info_t * info, FPWV * dest, FPW data); +static flash_info_t *flash_get_info(ulong base); + +/*----------------------------------------------------------------------- + * flash_init() + * + * sets up flash_info and returns size of FLASH (bytes) + */ +unsigned long flash_init(void) +{ + unsigned long size = 0; + int i = 0; + extern void flash_preinit(void); + extern void flash_afterinit(uint, ulong, ulong); + + ulong flashbase = CONFIG_SYS_FLASH_BASE; + + flash_preinit(); + + /* There is only ONE FLASH device */ + memset(&flash_info[i], 0, sizeof(flash_info_t)); + flash_info[i].size = flash_get_size((FPW *) flashbase, &flash_info[i]); + size += flash_info[i].size; + +#if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE + /* monitor protection ON by default */ + flash_protect(FLAG_PROTECT_SET, CONFIG_SYS_MONITOR_BASE, + CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1, + flash_get_info(CONFIG_SYS_MONITOR_BASE)); +#endif + +#ifdef CONFIG_ENV_IS_IN_FLASH + /* ENV protection ON by default */ + flash_protect(FLAG_PROTECT_SET, CONFIG_ENV_ADDR, + CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, + flash_get_info(CONFIG_ENV_ADDR)); +#endif + + flash_afterinit(i, flash_info[i].start[0], flash_info[i].size); + return size ? size : 1; +} + +/*----------------------------------------------------------------------- + */ +static void flash_reset(flash_info_t * info) { + FPWV *base = (FPWV *) (info->start[0]); + + /* Put FLASH back in read mode */ + if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) { + *base = (FPW) 0x00FF00FF; /* Intel Read Mode */ + } else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD) { + *base = (FPW) 0x00F000F0; /* AMD Read Mode */ + } +} + +/*----------------------------------------------------------------------- + */ + +static flash_info_t *flash_get_info(ulong base) { + int i; + flash_info_t *info; + + for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) { + info = &flash_info[i]; + if ((info->size) && (info->start[0] <= base) + && (base <= info->start[0] + info->size - 1)) { + break; + } + } + return (i == CONFIG_SYS_MAX_FLASH_BANKS ? 0 : info); +} + +/*----------------------------------------------------------------------- + */ + +void flash_print_info(flash_info_t * info) { + int i; + char *fmt; + + 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; + default: + printf("Unknown Vendor "); + break; + } + + switch (info->flash_id & FLASH_TYPEMASK) { + case FLASH_AMLV256U: + fmt = "29LV256M (256 Mbit)\n"; + break; + default: + fmt = "Unknown Chip Type\n"; + break; + } + + printf(fmt); + 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) { + ulong size; + int erased; + ulong *flash = (unsigned long *)info->start[i]; + + if ((i % 5) == 0) { + printf("\n "); + } + + /* + * Check if whole sector is erased + */ + size = + (i != + (info->sector_count - 1)) ? (info->start[i + 1] - + info->start[i]) >> 2 : (info-> + start + [0] + + info-> + size - + info-> + start + [i]) + >> 2; + + for (flash = (unsigned long *)info->start[i], erased = 1; + (flash != (unsigned long *)info->start[i] + size) + && erased; flash++) { + erased = *flash == ~0x0UL; + } + printf(" %08lX %s %s", info->start[i], erased ? "E" : " ", + info->protect[i] ? "(RO)" : " "); + } + + printf("\n"); +} + +/*----------------------------------------------------------------------- + */ + +/* + * The following code cannot be run from FLASH! + */ + +ulong flash_get_size(FPWV * addr, flash_info_t * info) { + int i; + + /* Write auto select command: read Manufacturer ID */ + /* Write auto select command sequence and test FLASH answer */ + addr[FLASH_CYCLE1] = (FPW) 0x00AA00AA; /* for AMD, Intel ignores this */ + addr[FLASH_CYCLE2] = (FPW) 0x00550055; /* for AMD, Intel ignores this */ + addr[FLASH_CYCLE1] = (FPW) 0x00900090; /* selects Intel or AMD */ + + /* The manufacturer codes are only 1 byte, so just use 1 byte. */ + /* This works for any bus width and any FLASH device width. */ + udelay(100); + switch (addr[FLASH_ID1] & 0x00ff) { + case (uchar) AMD_MANUFACT: + info->flash_id = FLASH_MAN_AMD; + break; + default: + printf("unknown vendor=%x ", addr[FLASH_ID1] & 0xff); + info->flash_id = FLASH_UNKNOWN; + info->sector_count = 0; + info->size = 0; + break; + } + + /* Check 16 bits or 32 bits of ID so work on 32 or 16 bit bus. */ + if (info->flash_id != FLASH_UNKNOWN) { + switch ((FPW) addr[FLASH_ID2]) { + case (FPW) AMD_ID_MIRROR: + /* MIRROR BIT FLASH, read more ID bytes */ + if ((FPW) addr[FLASH_ID3] == (FPW) AMD_ID_LV256U_2 + && (FPW) addr[FLASH_ID4] == (FPW) AMD_ID_LV256U_3) { + /* attention: only the first 16 MB will be used in u-boot */ + info->flash_id += FLASH_AMLV256U; + info->sector_count = 512; + info->size = 0x02000000; + for (i = 0; i < info->sector_count; i++) { + info->start[i] = + (ulong) addr + 0x10000 * i; + } + break; + } + /* fall thru to here ! */ + default: + printf("unknown AMD device=%x %x %x", + (FPW) addr[FLASH_ID2], (FPW) addr[FLASH_ID3], + (FPW) addr[FLASH_ID4]); + info->flash_id = FLASH_UNKNOWN; + info->sector_count = 0; + info->size = 0x800000; + break; + } + + /* Put FLASH back in read mode */ + flash_reset(info); + } + return (info->size); +} + +/*----------------------------------------------------------------------- + */ + +int flash_erase(flash_info_t * info, int s_first, int s_last) { + FPWV *addr; + int flag, prot, sect; + int intel = (info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL; + ulong start, now, last; + int rcode = 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; + } + + switch (info->flash_id & FLASH_TYPEMASK) { + case FLASH_AMLV256U: + break; + case FLASH_UNKNOWN: + default: + printf("Can't erase unknown flash type %08lx - aborted\n", + info->flash_id); + 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"); + } + + last = get_timer(0); + + /* Start erase on unprotected sectors */ + for (sect = s_first; sect <= s_last && rcode == 0; sect++) { + if (info->protect[sect] != 0) { /* protected, skip it */ + continue; + } + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + addr = (FPWV *) (info->start[sect]); + if (intel) { + *addr = (FPW) 0x00500050; /* clear status register */ + *addr = (FPW) 0x00200020; /* erase setup */ + *addr = (FPW) 0x00D000D0; /* erase confirm */ + } else { + /* must be AMD style if not Intel */ + FPWV *base; /* first address in bank */ + + base = (FPWV *) (info->start[0]); + base[FLASH_CYCLE1] = (FPW) 0x00AA00AA; /* unlock */ + base[FLASH_CYCLE2] = (FPW) 0x00550055; /* unlock */ + base[FLASH_CYCLE1] = (FPW) 0x00800080; /* erase mode */ + base[FLASH_CYCLE1] = (FPW) 0x00AA00AA; /* unlock */ + base[FLASH_CYCLE2] = (FPW) 0x00550055; /* unlock */ + *addr = (FPW) 0x00300030; /* erase sector */ + } + + /* re-enable interrupts if necessary */ + if (flag) { + enable_interrupts(); + } + start = get_timer(0); + + /* wait at least 50us for AMD, 80us for Intel. */ + /* Let's wait 1 ms. */ + udelay(1000); + + while ((*addr & (FPW) 0x00800080) != (FPW) 0x00800080) { + if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) { + printf("Timeout\n"); + if (intel) { + /* suspend erase */ + *addr = (FPW) 0x00B000B0; + } + flash_reset(info); /* reset to read mode */ + rcode = 1; /* failed */ + break; + } + /* show that we're waiting */ + if ((get_timer(last)) > CONFIG_SYS_HZ) { + /* every second */ + putc('.'); + last = get_timer(0); + } + } + /* show that we're waiting */ + if ((get_timer(last)) > CONFIG_SYS_HZ) { + /* every second */ + putc('.'); + last = get_timer(0); + } + flash_reset(info); /* reset to read mode */ + } + printf(" done\n"); + return (rcode); +} + +/*----------------------------------------------------------------------- + * 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) +{ + FPW data = 0; /* 16 or 32 bit word, matches flash bus width on MPC8XX */ + int bytes; /* number of bytes to program in current word */ + int left; /* number of bytes left to program */ + int i, res; + + for (left = cnt, res = 0; + left > 0 && res == 0; + addr += sizeof(data), left -= sizeof(data) - bytes) { + + bytes = addr & (sizeof(data) - 1); + addr &= ~(sizeof(data) - 1); + + /* combine source and destination data so can program + * an entire word of 16 or 32 bits + */ + for (i = 0; i < sizeof(data); i++) { + data <<= 8; + if (i < bytes || i - bytes >= left) + data += *((uchar *) addr + i); + else + data += *src++; + } + + /* write one word to the flash */ + switch (info->flash_id & FLASH_VENDMASK) { + case FLASH_MAN_AMD: + res = write_word_amd(info, (FPWV *) addr, data); + break; + default: + /* unknown flash type, error! */ + printf("missing or unknown FLASH type\n"); + res = 1; /* not really a timeout, but gives error */ + break; + } + } + return (res); +} + +/*----------------------------------------------------------------------- + * Write a word to Flash for AMD FLASH + * A word is 16 or 32 bits, whichever the bus width of the flash bank + * (not an individual chip) is. + * + * returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ +static int write_word_amd(flash_info_t * info, FPWV * dest, FPW data) { + ulong start; + int flag; + int res = 0; /* result, assume success */ + FPWV *base; /* first address in flash bank */ + + /* Check if Flash is (sufficiently) erased */ + if ((*dest & data) != data) { + return (2); + } + + base = (FPWV *) (info->start[0]); + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + base[FLASH_CYCLE1] = (FPW) 0x00AA00AA; /* unlock */ + base[FLASH_CYCLE2] = (FPW) 0x00550055; /* unlock */ + base[FLASH_CYCLE1] = (FPW) 0x00A000A0; /* selects program mode */ + + *dest = data; /* start programming the data */ + + /* re-enable interrupts if necessary */ + if (flag) { + enable_interrupts(); + } + start = get_timer(0); + + /* data polling for D7 */ + while (res == 0 + && (*dest & (FPW) 0x00800080) != (data & (FPW) 0x00800080)) { + if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) { + *dest = (FPW) 0x00F000F0; /* reset bank */ + res = 1; + } + } + return (res); +} diff --git a/qemu/roms/u-boot/board/esd/pf5200/mt46v16m16-75.h b/qemu/roms/u-boot/board/esd/pf5200/mt46v16m16-75.h new file mode 100644 index 000000000..63a403231 --- /dev/null +++ b/qemu/roms/u-boot/board/esd/pf5200/mt46v16m16-75.h @@ -0,0 +1,16 @@ +/* + * (C) Copyright 2004 + * Mark Jonas, Freescale Semiconductor, mark.jonas@motorola.com. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#define SDRAM_DDR 1 /* is DDR */ + +/* Settings for XLB = 132 MHz */ +#define SDRAM_MODE 0x018D0000 +#define SDRAM_EMODE 0x40090000 +#define SDRAM_CONTROL 0x705f0f00 +#define SDRAM_CONFIG1 0x73722930 +#define SDRAM_CONFIG2 0x47770000 +#define SDRAM_TAPDELAY 0x10000000 diff --git a/qemu/roms/u-boot/board/esd/pf5200/pf5200.c b/qemu/roms/u-boot/board/esd/pf5200/pf5200.c new file mode 100644 index 000000000..7a9ed229e --- /dev/null +++ b/qemu/roms/u-boot/board/esd/pf5200/pf5200.c @@ -0,0 +1,357 @@ +/* + * (C) Copyright 2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2004 + * Mark Jonas, Freescale Semiconductor, mark.jonas@motorola.com. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * pf5200.c - main board support/init for the esd pf5200. + */ + +#include <common.h> +#include <mpc5xxx.h> +#include <pci.h> +#include <command.h> +#include <netdev.h> + +#include "mt46v16m16-75.h" + +void init_power_switch(void); + +static void sdram_start(int hi_addr) +{ + long hi_addr_bit = hi_addr ? 0x01000000 : 0; + + /* unlock mode register */ + *(vu_long *) MPC5XXX_SDRAM_CTRL = + SDRAM_CONTROL | 0x80000000 | hi_addr_bit; + __asm__ volatile ("sync"); + + /* precharge all banks */ + *(vu_long *) MPC5XXX_SDRAM_CTRL = + SDRAM_CONTROL | 0x80000002 | hi_addr_bit; + __asm__ volatile ("sync"); + + /* set mode register: extended mode */ + *(vu_long *) MPC5XXX_SDRAM_MODE = SDRAM_EMODE; + __asm__ volatile ("sync"); + + /* set mode register: reset DLL */ + *(vu_long *) MPC5XXX_SDRAM_MODE = SDRAM_MODE | 0x04000000; + __asm__ volatile ("sync"); + + /* precharge all banks */ + *(vu_long *) MPC5XXX_SDRAM_CTRL = + SDRAM_CONTROL | 0x80000002 | hi_addr_bit; + __asm__ volatile ("sync"); + + /* auto refresh */ + *(vu_long *) MPC5XXX_SDRAM_CTRL = + SDRAM_CONTROL | 0x80000004 | hi_addr_bit; + __asm__ volatile ("sync"); + + /* set mode register */ + *(vu_long *) MPC5XXX_SDRAM_MODE = SDRAM_MODE; + __asm__ volatile ("sync"); + + /* normal operation */ + *(vu_long *) MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | hi_addr_bit; + __asm__ volatile ("sync"); +} + +/* + * ATTENTION: Although partially referenced initdram does NOT make real use + * use of CONFIG_SYS_SDRAM_BASE. The code does not work if CONFIG_SYS_SDRAM_BASE + * is something else than 0x00000000. + */ + +phys_size_t initdram(int board_type) +{ + ulong dramsize = 0; + ulong test1, test2; + + /* setup SDRAM chip selects */ + *(vu_long *) MPC5XXX_SDRAM_CS0CFG = 0x0000001e; /* 2G at 0x0 */ + *(vu_long *) MPC5XXX_SDRAM_CS1CFG = 0x80000000; /* disabled */ + __asm__ volatile ("sync"); + + /* setup config registers */ + *(vu_long *) MPC5XXX_SDRAM_CONFIG1 = SDRAM_CONFIG1; + *(vu_long *) MPC5XXX_SDRAM_CONFIG2 = SDRAM_CONFIG2; + __asm__ volatile ("sync"); + + /* set tap delay */ + *(vu_long *) MPC5XXX_CDM_PORCFG = SDRAM_TAPDELAY; + __asm__ volatile ("sync"); + + /* find RAM size using SDRAM CS0 only */ + sdram_start(0); + test1 = get_ram_size((long *) CONFIG_SYS_SDRAM_BASE, 0x80000000); + sdram_start(1); + test2 = get_ram_size((long *) CONFIG_SYS_SDRAM_BASE, 0x80000000); + + if (test1 > test2) { + sdram_start(0); + dramsize = test1; + } else { + dramsize = test2; + } + + /* memory smaller than 1MB is impossible */ + if (dramsize < (1 << 20)) { + dramsize = 0; + } + + /* set SDRAM CS0 size according to the amount of RAM found */ + if (dramsize > 0) { + *(vu_long *) MPC5XXX_SDRAM_CS0CFG = + 0x13 + __builtin_ffs(dramsize >> 20) - 1; + /* let SDRAM CS1 start right after CS0 */ + *(vu_long *) MPC5XXX_SDRAM_CS1CFG = dramsize + 0x0000001e; /* 2G */ + } else { +#if 0 + *(vu_long *) MPC5XXX_SDRAM_CS0CFG = 0; /* disabled */ + /* let SDRAM CS1 start right after CS0 */ + *(vu_long *) MPC5XXX_SDRAM_CS1CFG = dramsize + 0x0000001e; /* 2G */ +#else + *(vu_long *) MPC5XXX_SDRAM_CS0CFG = + 0x13 + __builtin_ffs(0x08000000 >> 20) - 1; + /* let SDRAM CS1 start right after CS0 */ + *(vu_long *) MPC5XXX_SDRAM_CS1CFG = 0x08000000 + 0x0000001e; /* 2G */ +#endif + } + +#if 0 + /* find RAM size using SDRAM CS1 only */ + sdram_start(0); + get_ram_size((ulong *) (CONFIG_SYS_SDRAM_BASE + dramsize), 0x80000000); + sdram_start(1); + get_ram_size((ulong *) (CONFIG_SYS_SDRAM_BASE + dramsize), 0x80000000); + sdram_start(0); +#endif + /* set SDRAM CS1 size according to the amount of RAM found */ + + *(vu_long *) MPC5XXX_SDRAM_CS1CFG = dramsize; /* disabled */ + + init_power_switch(); + return (dramsize); +} + +int checkboard(void) +{ + puts("Board: esd ParaFinder (pf5200)\n"); + return 0; +} + +void flash_preinit(void) +{ + /* + * Now, when we are in RAM, enable flash write + * access for detection process. + * Note that CS_BOOT cannot be cleared when + * executing in flash. + */ + *(vu_long *) MPC5XXX_BOOTCS_CFG &= ~0x1; /* clear RO */ +} + +void flash_afterinit(ulong size) +{ + if (size == 0x02000000) { + /* adjust mapping */ + *(vu_long *) MPC5XXX_BOOTCS_START = + *(vu_long *) MPC5XXX_CS0_START = + START_REG(CONFIG_SYS_BOOTCS_START | size); + *(vu_long *) MPC5XXX_BOOTCS_STOP = + *(vu_long *) MPC5XXX_CS0_STOP = + STOP_REG(CONFIG_SYS_BOOTCS_START | size, size); + } +} + +#ifdef CONFIG_PCI +static struct pci_controller hose; + +extern void pci_mpc5xxx_init(struct pci_controller *); + +void pci_init_board(void) { + pci_mpc5xxx_init(&hose); +} +#endif + +#if defined(CONFIG_CMD_IDE) && defined(CONFIG_IDE_RESET) + +void init_ide_reset(void) +{ + debug("init_ide_reset\n"); + + /* Configure PSC1_4 as GPIO output for ATA reset */ + *(vu_long *) MPC5XXX_WU_GPIO_ENABLE |= GPIO_PSC1_4; + *(vu_long *) MPC5XXX_WU_GPIO_DIR |= GPIO_PSC1_4; +} + +void ide_set_reset(int idereset) +{ + debug("ide_reset(%d)\n", idereset); + + if (idereset) { + *(vu_long *) MPC5XXX_WU_GPIO_DATA_O &= ~GPIO_PSC1_4; + } else { + *(vu_long *) MPC5XXX_WU_GPIO_DATA_O |= GPIO_PSC1_4; + } +} +#endif + +#define MPC5XXX_SIMPLEIO_GPIO_ENABLE (MPC5XXX_GPIO + 0x0004) +#define MPC5XXX_SIMPLEIO_GPIO_DIR (MPC5XXX_GPIO + 0x000C) +#define MPC5XXX_SIMPLEIO_GPIO_DATA_OUTPUT (MPC5XXX_GPIO + 0x0010) +#define MPC5XXX_SIMPLEIO_GPIO_DATA_INPUT (MPC5XXX_GPIO + 0x0014) + +#define MPC5XXX_INTERRUPT_GPIO_ENABLE (MPC5XXX_GPIO + 0x0020) +#define MPC5XXX_INTERRUPT_GPIO_DIR (MPC5XXX_GPIO + 0x0028) +#define MPC5XXX_INTERRUPT_GPIO_DATA_OUTPUT (MPC5XXX_GPIO + 0x002C) +#define MPC5XXX_INTERRUPT_GPIO_STATUS (MPC5XXX_GPIO + 0x003C) + +#define GPIO_WU6 0x40000000UL +#define GPIO_USB0 0x00010000UL +#define GPIO_USB9 0x08000000UL +#define GPIO_USB9S 0x00080000UL + +void init_power_switch(void) +{ + debug("init_power_switch\n"); + + /* Configure GPIO_WU6 as GPIO output for ATA reset */ + *(vu_long *) MPC5XXX_WU_GPIO_DATA_O |= GPIO_WU6; + *(vu_long *) MPC5XXX_WU_GPIO_ENABLE |= GPIO_WU6; + *(vu_long *) MPC5XXX_WU_GPIO_DIR |= GPIO_WU6; + __asm__ volatile ("sync"); + + *(vu_long *) MPC5XXX_SIMPLEIO_GPIO_DATA_OUTPUT &= ~GPIO_USB0; + *(vu_long *) MPC5XXX_SIMPLEIO_GPIO_ENABLE |= GPIO_USB0; + *(vu_long *) MPC5XXX_SIMPLEIO_GPIO_DIR |= GPIO_USB0; + __asm__ volatile ("sync"); + + *(vu_long *) MPC5XXX_INTERRUPT_GPIO_DATA_OUTPUT &= ~GPIO_USB9; + *(vu_long *) MPC5XXX_INTERRUPT_GPIO_ENABLE &= ~GPIO_USB9; + __asm__ volatile ("sync"); + + if ((*(vu_long *) MPC5XXX_INTERRUPT_GPIO_STATUS & GPIO_USB9S) == 0) { + *(vu_long *) MPC5XXX_SIMPLEIO_GPIO_DATA_OUTPUT |= GPIO_USB0; + __asm__ volatile ("sync"); + } + *(vu_char *) CONFIG_SYS_CS1_START = 0x02; /* Red Power LED on */ + __asm__ volatile ("sync"); + + *(vu_char *) (CONFIG_SYS_CS1_START + 1) = 0x02; /* Disable driver for KB11 */ + __asm__ volatile ("sync"); +} + +int board_eth_init(bd_t *bis) +{ + return pci_eth_init(bis); +} + +void power_set_reset(int power) +{ + debug("ide_set_reset(%d)\n", power); + + if (power) { + *(vu_long *) MPC5XXX_WU_GPIO_DATA_O &= ~GPIO_WU6; + *(vu_long *) MPC5XXX_INTERRUPT_GPIO_DATA_OUTPUT &= ~GPIO_USB9; + } else { + *(vu_long *) MPC5XXX_WU_GPIO_DATA_O |= GPIO_WU6; + if ((*(vu_long *) MPC5XXX_INTERRUPT_GPIO_STATUS & GPIO_USB9S) == + 0) { + *(vu_long *) MPC5XXX_SIMPLEIO_GPIO_DATA_OUTPUT |= + GPIO_USB0; + } + + } +} + +int do_poweroff(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) +{ + power_set_reset(1); + return (0); +} + +U_BOOT_CMD(poweroff, 1, 1, do_poweroff, "Switch off power", ""); + +int phypower(int flag) +{ + u32 addr; + vu_long *reg; + int status; + pci_dev_t dev; + + dev = PCI_BDF(0, 0x18, 0); + status = pci_read_config_dword(dev, PCI_BASE_ADDRESS_1, &addr); + if (status == 0) { + reg = (vu_long *) (addr + 0x00000040); + *reg |= 0x40000000; + __asm__ volatile ("sync"); + + reg = (vu_long *) (addr + 0x001000c); + *reg |= 0x20000000; + __asm__ volatile ("sync"); + + reg = (vu_long *) (addr + 0x0010004); + if (flag != 0) { + *reg &= ~0x20000000; + } else { + *reg |= 0x20000000; + } + __asm__ volatile ("sync"); + } + return (status); +} + +int do_phypower(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) +{ + if (argv[1][0] == '0') + (void)phypower(0); + else + (void)phypower(1); + + return (0); +} + +U_BOOT_CMD(phypower, 2, 2, do_phypower, + "Switch power of ethernet phy", ""); + +int do_writepci(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) +{ + unsigned int addr; + unsigned int size; + int i; + volatile unsigned long *ptr; + + addr = simple_strtol(argv[1], NULL, 16); + size = simple_strtol(argv[2], NULL, 16); + + printf("\nWriting at addr %08x, size %08x.\n", addr, size); + + while (1) { + ptr = (volatile unsigned long *)addr; + for (i = 0; i < (size >> 2); i++) { + *ptr++ = i; + } + + /* Abort if ctrl-c was pressed */ + if (ctrlc()) { + puts("\nAbort\n"); + return 0; + } + putc('.'); + } + return 0; +} + +U_BOOT_CMD(writepci, 3, 1, do_writepci, + "Write some data to pcibus", + "<addr> <size>\n" + "" +); |