diff options
Diffstat (limited to 'u-boot/board/kup/common')
-rw-r--r-- | u-boot/board/kup/common/flash.c | 515 | ||||
-rw-r--r-- | u-boot/board/kup/common/kup.c | 84 | ||||
-rw-r--r-- | u-boot/board/kup/common/kup.h | 56 | ||||
-rw-r--r-- | u-boot/board/kup/common/load_sernum_ethaddr.c | 94 | ||||
-rw-r--r-- | u-boot/board/kup/common/pcmcia.c | 225 |
5 files changed, 974 insertions, 0 deletions
diff --git a/u-boot/board/kup/common/flash.c b/u-boot/board/kup/common/flash.c new file mode 100644 index 0000000..134a9d5 --- /dev/null +++ b/u-boot/board/kup/common/flash.c @@ -0,0 +1,515 @@ +/* + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <mpc8xx.h> + +#ifndef CONFIG_ENV_ADDR +#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + CONFIG_ENV_OFFSET) +#endif + +#define CONFIG_FLASH_16BIT + +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); + +/*----------------------------------------------------------------------- + */ + +unsigned long flash_init (void) +{ + volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR; + volatile memctl8xx_t *memctl = &immap->im_memctl; + unsigned long size_b0; + int i; + + /* Init: no FLASHes known */ + for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; ++i) { + flash_info[i].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); + } + + + /* Remap FLASH according to real size */ + memctl->memc_or0 = CONFIG_SYS_OR_TIMING_FLASH | (-size_b0 & OR_AM_MSK); + memctl->memc_br0 = (CONFIG_SYS_FLASH_BASE & BR_BA_MSK) | BR_MS_GPCM | BR_V | BR_PS_16; + + /* Re-do sizing to get full correct info */ + size_b0 = flash_get_size((vu_long *)CONFIG_SYS_FLASH_BASE, &flash_info[0]); + +#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_info[0]); +#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_info[0]); +#endif + + flash_info[0].size = size_b0; + + return (size_b0); +} + +/*----------------------------------------------------------------------- + */ +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; + default: printf ("Unknown Vendor "); break; + } + + switch (info->flash_id & FLASH_TYPEMASK) { + 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; + default: printf ("Unknown Chip Type\n"); + break; + } + + printf (" Size: %ld MB in %d Sectors\n", + info->size >> 20, info->sector_count); + + printf (" Sector Start Addresses:"); + for (i=0; i<info->sector_count; ++i) { + if ((i % 5) == 0) + printf ("\n "); + printf (" %08lX%s", + info->start[i], + info->protect[i] ? " (RO)" : " " + ); + } + printf ("\n"); + return; +} + +/*----------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------- + */ + +/* + * The following code cannot be run from FLASH! + */ + +static ulong flash_get_size (vu_long *addr, flash_info_t *info) +{ + short i; + ulong value; + ulong base = (ulong)addr; + + /* Write auto select command: read Manufacturer ID */ + vu_short *s_addr=(vu_short*)addr; + s_addr[0x5555] = 0x00AA; + s_addr[0x2AAA] = 0x0055; + s_addr[0x5555] = 0x0090; + + value = s_addr[0]; + value = value|(value<<16); + + switch (value) { + case AMD_MANUFACT: + info->flash_id = FLASH_MAN_AMD; + break; + case FUJ_MANUFACT: + info->flash_id = FLASH_MAN_FUJ; + break; + default: + info->flash_id = FLASH_UNKNOWN; + info->sector_count = 0; + info->size = 0; + return (0); /* no or unknown flash */ + } + + value = s_addr[1]; + value = value|(value<<16); + + switch (value) { + case FUJI_ID_29F800BA: + info->flash_id += FLASH_AM400T; + info->sector_count = 19; + info->size = 0x00100000; + break; /* => 1 MB */ + case AMD_ID_LV800T: + info->flash_id += FLASH_AM800T; + info->sector_count = 19; + info->size = 0x00100000; + break; /* => 1 MB */ + case AMD_ID_LV800B: + info->flash_id += FLASH_AM800B; + info->sector_count = 19; + info->size = 0x00100000; + break; /* => 1 MB */ + default: + info->flash_id = FLASH_UNKNOWN; + return (0); /* => no or unknown flash */ + } + + /* set up sector start address table */ + /* set sector offsets for bottom boot block type */ + info->start[0] = base + 0x00000000; + info->start[1] = base + 0x00004000; + info->start[2] = base + 0x00006000; + info->start[3] = base + 0x00008000; + for (i = 4; i < info->sector_count; i++) { + info->start[i] = base + (i * 0x00010000) - 0x00030000; + } + + + /* 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 */ + s_addr = (volatile unsigned short *)(info->start[i]); + info->protect[i] = s_addr[2] & 1; + } + + /* + * Prevent writes to uninitialized FLASH. + */ + if (info->flash_id != FLASH_UNKNOWN) { + s_addr = (volatile unsigned short *)info->start[0]; + *s_addr = 0x00F0; /* reset bank */ + } + return (info->size); +} + + +/*----------------------------------------------------------------------- + */ + + +int flash_erase (flash_info_t *info, int s_first, int s_last) +{ + vu_long *addr = (vu_long*)(info->start[0]); + int flag, prot, sect; + ulong start, now, last; +#ifdef CONFIG_FLASH_16BIT + vu_short *s_addr = (vu_short*)addr; +#endif + + 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; + } +/*#ifndef CONFIG_FLASH_16BIT + ulong type; + type = (info->flash_id & FLASH_VENDMASK); + if ((type != FLASH_MAN_SST) && (type != FLASH_MAN_STM)) { + printf ("Can't erase unknown flash type %08lx - aborted\n", + info->flash_id); + return; + } +#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"); + } + + start = get_timer (0); + last = start; + /* Start erase on unprotected sectors */ + for (sect = s_first; sect<=s_last; sect++) { + if (info->protect[sect] == 0) { /* not protected */ +#ifdef CONFIG_FLASH_16BIT + vu_short *s_sect_addr = (vu_short*)(info->start[sect]); +#else + vu_long *sect_addr = (vu_long*)(info->start[sect]); +#endif + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + +#ifdef CONFIG_FLASH_16BIT + + /*printf("\ns_sect_addr=%x",s_sect_addr);*/ + s_addr[0x5555] = 0x00AA; + s_addr[0x2AAA] = 0x0055; + s_addr[0x5555] = 0x0080; + s_addr[0x5555] = 0x00AA; + s_addr[0x2AAA] = 0x0055; + s_sect_addr[0] = 0x0030; +#else + addr[0x5555] = 0x00AA00AA; + addr[0x2AAA] = 0x00550055; + addr[0x5555] = 0x00800080; + addr[0x5555] = 0x00AA00AA; + addr[0x2AAA] = 0x00550055; + sect_addr[0] = 0x00300030; +#endif + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + /* wait at least 80us - let's wait 1 ms */ + udelay (1000); + +#ifdef CONFIG_FLASH_16BIT + while ((s_sect_addr[0] & 0x0080) != 0x0080) { +#else + while ((sect_addr[0] & 0x00800080) != 0x00800080) { +#endif + 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; + } + } + } + } + + /* reset to read mode */ + addr = (volatile unsigned long *)info->start[0]; +#ifdef CONFIG_FLASH_16BIT + s_addr[0] = 0x00F0; /* reset bank */ +#else + addr[0] = 0x00F000F0; /* reset bank */ +#endif + + 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) +{ + vu_long *addr = (vu_long*)(info->start[0]); + +#ifdef CONFIG_FLASH_16BIT + vu_short high_data; + vu_short low_data; + vu_short *s_addr = (vu_short*)addr; +#endif + ulong start; + int flag; + + /* Check if Flash is (sufficiently) erased */ + if ((*((vu_long *)dest) & data) != data) { + return (2); + } + +#ifdef CONFIG_FLASH_16BIT + /* Write the 16 higher-bits */ + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + high_data = ((data>>16) & 0x0000ffff); + + s_addr[0x5555] = 0x00AA; + s_addr[0x2AAA] = 0x0055; + s_addr[0x5555] = 0x00A0; + + *((vu_short *)dest) = high_data; + + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + /* data polling for D7 */ + start = get_timer (0); + while ((*((vu_short *)dest) & 0x0080) != (high_data & 0x0080)) { + if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) { + return (1); + } + } + + + /* Write the 16 lower-bits */ +#endif + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); +#ifdef CONFIG_FLASH_16BIT + dest += 0x2; + low_data = (data & 0x0000ffff); + + s_addr[0x5555] = 0x00AA; + s_addr[0x2AAA] = 0x0055; + s_addr[0x5555] = 0x00A0; + *((vu_short *)dest) = low_data; + +#else + addr[0x5555] = 0x00AA00AA; + addr[0x2AAA] = 0x00550055; + addr[0x5555] = 0x00A000A0; + *((vu_long *)dest) = data; +#endif + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + /* data polling for D7 */ + start = get_timer (0); + +#ifdef CONFIG_FLASH_16BIT + while ((*((vu_short *)dest) & 0x0080) != (low_data & 0x0080)) { +#else + while ((*((vu_long *)dest) & 0x00800080) != (data & 0x00800080)) { +#endif + + if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) { + return (1); + } + } + return (0); +} diff --git a/u-boot/board/kup/common/kup.c b/u-boot/board/kup/common/kup.c new file mode 100644 index 0000000..38259a5 --- /dev/null +++ b/u-boot/board/kup/common/kup.c @@ -0,0 +1,84 @@ +/* + * (C) Copyright 2004 + * Klaus Heydeck, Kieback & Peter GmbH & Co KG, heydeck@kieback-peter.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <mpc8xx.h> +#include "kup.h" +#include <asm/io.h> + + +int misc_init_f(void) +{ + volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; + volatile sysconf8xx_t *siu = &immap->im_siu_conf; + + while (in_be32(&siu->sc_sipend) & 0x20000000) { + debug("waiting for 5V VCC\n"); + } + + /* RS232 / RS485 default is RS232 */ + clrbits_be16(&immap->im_ioport.iop_padat, PA_RS485); + clrbits_be16(&immap->im_ioport.iop_papar, PA_RS485); + clrbits_be16(&immap->im_ioport.iop_paodr, PA_RS485); + setbits_be16(&immap->im_ioport.iop_padir, PA_RS485); + + /* IO Reset min 1 msec */ + setbits_be16(&immap->im_ioport.iop_padat, + (PA_RESET_IO_01 | PA_RESET_IO_02)); + clrbits_be16(&immap->im_ioport.iop_papar, + (PA_RESET_IO_01 | PA_RESET_IO_02)); + clrbits_be16(&immap->im_ioport.iop_paodr, + (PA_RESET_IO_01 | PA_RESET_IO_02)); + setbits_be16(&immap->im_ioport.iop_padir, + (PA_RESET_IO_01 | PA_RESET_IO_02)); + udelay(1000); + clrbits_be16(&immap->im_ioport.iop_padat, + (PA_RESET_IO_01 | PA_RESET_IO_02)); + return (0); +} + +#ifdef CONFIG_IDE_LED +void ide_led(uchar led, uchar status) +{ + volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; + + /* We have one led for both pcmcia slots */ + if (status) + clrbits_be16(&immap->im_ioport.iop_padat, PA_LED_YELLOW); + else + setbits_be16(&immap->im_ioport.iop_padat, PA_LED_YELLOW); +} +#endif + +void poweron_key(void) +{ + volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; + + clrbits_be16(&immap->im_ioport.iop_pcpar, PC_SWITCH1); + clrbits_be16(&immap->im_ioport.iop_pcdir, PC_SWITCH1); + + if (in_be16(&immap->im_ioport.iop_pcdat) & (PC_SWITCH1)) + setenv("key1", "off"); + else + setenv("key1", "on"); +} diff --git a/u-boot/board/kup/common/kup.h b/u-boot/board/kup/common/kup.h new file mode 100644 index 0000000..455848c --- /dev/null +++ b/u-boot/board/kup/common/kup.h @@ -0,0 +1,56 @@ +/* + * (C) Copyright 2004 + * Klaus Heydeck, Kieback & Peter GmbH & Co KG, heydeck@kieback-peter.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __KUP_H +#define __KUP_H + +#define PA_8 0x0080 +#define PA_9 0x0040 +#define PA_10 0x0020 +#define PA_11 0x0010 +#define PA_12 0x0008 + +#define PB_14 0x00020000 +#define PB_15 0x00010000 +#define PB_16 0x00008000 +#define PB_17 0x00004000 + +#define PC_4 0x0800 +#define PC_5 0x0400 +#define PC_9 0x0040 + +#define PA_RS485 PA_11 /* SCC1: 0=RS232 1=RS485 */ +#define PA_LED_YELLOW PA_8 +#define PA_RESET_IO_01 PA_9 /* Reset left IO */ +#define PA_RESET_IO_02 PA_10 /* Reset right IO */ +#define PB_PROG_IO_01 PB_15 /* Program left IO */ +#define PB_PROG_IO_02 PB_16 /* Program right IO */ +#define BP_USB_VCC PB_14 /* VCC for USB devices 0=vcc on, 1=vcc off */ +#define PB_LCD_PWM PB_17 /* PB 17 */ +#define PC_SWITCH1 PC_9 /* Reboot switch */ + + +extern void poweron_key(void); +extern void load_sernum_ethaddr(void); + +#endif /* __KUP_H */ diff --git a/u-boot/board/kup/common/load_sernum_ethaddr.c b/u-boot/board/kup/common/load_sernum_ethaddr.c new file mode 100644 index 0000000..741e9a5 --- /dev/null +++ b/u-boot/board/kup/common/load_sernum_ethaddr.c @@ -0,0 +1,94 @@ +/* + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <mpc8xx.h> + +/*----------------------------------------------------------------------- + * Process Hardware Information Block: + * + * If we boot on a system fresh from factory, check if the Hardware + * Information Block exists and save the information it contains. + * + * The KUP Hardware Information Block is defined as + * follows: + * - located in first flash bank + * - starts at offset CONFIG_SYS_HWINFO_OFFSET + * - size CONFIG_SYS_HWINFO_SIZE + * + * Internal structure: + * - sequence of ASCII character lines + * - fields separated by <CR><LF> + * - last field terminated by NUL character (0x00) + * + * Fields in Hardware Information Block: + * 1) Module Type + * 2) MAC Address + * 3) .... + */ + + +#define ETHADDR_TOKEN "ethaddr=" +#define LCD_TOKEN "lcd=" + +void load_sernum_ethaddr (void) +{ + unsigned char *hwi; + char *var; + unsigned char hwi_stack[CONFIG_SYS_HWINFO_SIZE]; + char *p; + + hwi = (unsigned char *) (CONFIG_SYS_FLASH_BASE + CONFIG_SYS_HWINFO_OFFSET); + if (*((unsigned long *) hwi) != (unsigned long) CONFIG_SYS_HWINFO_MAGIC) { + printf ("HardwareInfo not found!\n"); + return; + } + memcpy (hwi_stack, hwi, CONFIG_SYS_HWINFO_SIZE); + + /* + ** ethaddr + */ + var = strstr ((char *)hwi_stack, ETHADDR_TOKEN); + if (var) { + var += sizeof (ETHADDR_TOKEN) - 1; + p = strchr (var, '\r'); + if ((unsigned char *)p < hwi + CONFIG_SYS_HWINFO_SIZE) { + *p = '\0'; + setenv ("ethaddr", var); + *p = '\r'; + } + } + /* + ** lcd + */ + var = strstr ((char *)hwi_stack, LCD_TOKEN); + if (var) { + var += sizeof (LCD_TOKEN) - 1; + p = strchr (var, '\r'); + if ((unsigned char *)p < hwi + CONFIG_SYS_HWINFO_SIZE) { + *p = '\0'; + setenv ("lcd", var); + *p = '\r'; + } + } +} diff --git a/u-boot/board/kup/common/pcmcia.c b/u-boot/board/kup/common/pcmcia.c new file mode 100644 index 0000000..ce6b186 --- /dev/null +++ b/u-boot/board/kup/common/pcmcia.c @@ -0,0 +1,225 @@ +#include <common.h> +#include <mpc8xx.h> +#include <pcmcia.h> + +#undef CONFIG_PCMCIA + +#if defined(CONFIG_CMD_PCMCIA) +#define CONFIG_PCMCIA +#endif + +#if defined(CONFIG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD) +#define CONFIG_PCMCIA +#endif + +#ifdef CONFIG_PCMCIA + +#define PCMCIA_BOARD_MSG "KUP" + +#define KUP4K_PCMCIA_B_3V3 (0x00020000) + +int pcmcia_hardware_enable(int slot) +{ + volatile immap_t *immap; + volatile cpm8xx_t *cp; + volatile pcmconf8xx_t *pcmp; + volatile sysconf8xx_t *sysp; + uint reg, mask; + + debug ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot); + + udelay(10000); + + immap = (immap_t *)CONFIG_SYS_IMMR; + sysp = (sysconf8xx_t *)(&(((immap_t *)CONFIG_SYS_IMMR)->im_siu_conf)); + pcmp = (pcmconf8xx_t *)(&(((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia)); + cp = (cpm8xx_t *)(&(((immap_t *)CONFIG_SYS_IMMR)->im_cpm)); + + /* + * Configure SIUMCR to enable PCMCIA port B + * (VFLS[0:1] are not used for debugging, we connect FRZ# instead) + */ + sysp->sc_siumcr &= ~SIUMCR_DBGC11; /* set DBGC to 00 */ + + /* clear interrupt state, and disable interrupts */ + pcmp->pcmc_pscr = PCMCIA_MASK(slot); + pcmp->pcmc_per &= ~PCMCIA_MASK(slot); + + /* + * Disable interrupts, DMA, and PCMCIA buffers + * (isolate the interface) and assert RESET signal + */ + debug ("Disable PCMCIA buffers and assert RESET\n"); + reg = 0; + reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */ + reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */ + PCMCIA_PGCRX(slot) = reg; + udelay(2500); + + /* + * Configure Port B pins for + * 3 Volts enable + */ + if (slot) { /* Slot A is built-in */ + cp->cp_pbdir |= KUP4K_PCMCIA_B_3V3; + cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3; + /* remove all power */ + cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; /* active low */ + } + /* + * Make sure there is a card in the slot, then configure the interface. + */ + udelay(10000); + debug ("[%d] %s: PIPR(%p)=0x%x\n", + __LINE__,__FUNCTION__, + &(pcmp->pcmc_pipr),pcmp->pcmc_pipr); + if (pcmp->pcmc_pipr & (0x18000000 >> (slot << 4))) { + printf (" No Card found\n"); + return (1); + } + + /* + * Power On. + */ + printf("%s Slot %c:", slot ? "" : "\n", 'A' + slot); + mask = PCMCIA_VS1(slot) | PCMCIA_VS2(slot); + reg = pcmp->pcmc_pipr; + debug ("PIPR: 0x%x ==> VS1=o%s, VS2=o%s\n", + reg, + (reg&PCMCIA_VS1(slot))?"n":"ff", + (reg&PCMCIA_VS2(slot))?"n":"ff"); + if ((reg & mask) == mask) { + puts (" 5.0V card found: NOT SUPPORTED !!!\n"); + } else { + if(slot) + cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3; + puts (" 3.3V card found: "); + } +#if 0 + /* VCC switch error flag, PCMCIA slot INPACK_ pin */ + cp->cp_pbdir &= ~(0x0020 | 0x0010); + cp->cp_pbpar &= ~(0x0020 | 0x0010); + udelay(500000); +#endif + debug ("Enable PCMCIA buffers and stop RESET\n"); + reg = PCMCIA_PGCRX(slot); + reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */ + reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */ + PCMCIA_PGCRX(slot) = reg; + + udelay(250000); /* some cards need >150 ms to come up :-( */ + + debug ("# hardware_enable done\n"); + + return (0); +} + + +#if defined(CONFIG_CMD_PCMCIA) +int pcmcia_hardware_disable(int slot) +{ + volatile immap_t *immap; + volatile cpm8xx_t *cp; + volatile pcmconf8xx_t *pcmp; + u_long reg; + + debug ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot); + + immap = (immap_t *)CONFIG_SYS_IMMR; + pcmp = (pcmconf8xx_t *)(&(((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia)); + cp = (cpm8xx_t *)(&(((immap_t *)CONFIG_SYS_IMMR)->im_cpm)); + + /* remove all power */ + if (slot) + cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; + + /* Configure PCMCIA General Control Register */ + debug ("Disable PCMCIA buffers and assert RESET\n"); + reg = 0; + reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */ + reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */ + PCMCIA_PGCRX(slot) = reg; + + udelay(10000); + + return (0); +} +#endif + + +int pcmcia_voltage_set(int slot, int vcc, int vpp) +{ + volatile immap_t *immap; + volatile cpm8xx_t *cp; + volatile pcmconf8xx_t *pcmp; + u_long reg; + + debug ("voltage_set: " \ + PCMCIA_BOARD_MSG \ + " Slot %c, Vcc=%d.%d, Vpp=%d.%d\n", + 'A'+slot, vcc/10, vcc%10, vpp/10, vcc%10); + + if (!slot) /* Slot A is not configurable */ + return 0; + + immap = (immap_t *)CONFIG_SYS_IMMR; + pcmp = (pcmconf8xx_t *)(&(((immap_t *)CONFIG_SYS_IMMR)->im_pcmcia)); + cp = (cpm8xx_t *)(&(((immap_t *)CONFIG_SYS_IMMR)->im_cpm)); + + /* + * Disable PCMCIA buffers (isolate the interface) + * and assert RESET signal + */ + debug ("Disable PCMCIA buffers and assert RESET\n"); + reg = PCMCIA_PGCRX(slot); + reg |= __MY_PCMCIA_GCRX_CXRESET; /* active high */ + reg |= __MY_PCMCIA_GCRX_CXOE; /* active low */ + PCMCIA_PGCRX(slot) = reg; + udelay(500); + + debug ("PCMCIA power OFF\n"); + /* + * Configure Port B pins for + * 3 Volts enable + */ + cp->cp_pbdir |= KUP4K_PCMCIA_B_3V3; + cp->cp_pbpar &= ~KUP4K_PCMCIA_B_3V3; + /* remove all power */ + cp->cp_pbdat |= KUP4K_PCMCIA_B_3V3; /* active low */ + + switch(vcc) { + case 0: break; + case 33: + cp->cp_pbdat &= ~KUP4K_PCMCIA_B_3V3; + debug ("PCMCIA powered at 3.3V\n"); + break; + case 50: + debug ("PCMCIA: 5Volt vcc not supported\n"); + break; + default: + puts("PCMCIA: vcc not supported"); + break; + } + udelay(10000); + /* Checking supported voltages */ + + debug ("PIPR: 0x%x --> %s\n", + pcmp->pcmc_pipr, + (pcmp->pcmc_pipr & (0x80000000 >> (slot << 4))) + ? "only 5 V --> NOT SUPPORTED" + : "can do 3.3V"); + + + debug ("Enable PCMCIA buffers and stop RESET\n"); + reg = PCMCIA_PGCRX(slot); + reg &= ~__MY_PCMCIA_GCRX_CXRESET; /* active high */ + reg &= ~__MY_PCMCIA_GCRX_CXOE; /* active low */ + PCMCIA_PGCRX(slot) = reg; + udelay(500); + + debug ("voltage_set: " PCMCIA_BOARD_MSG " Slot %c, DONE\n", + slot+'A'); + return (0); +} + +#endif /* CONFIG_PCMCIA */ |