Changes for U-Boot 0.4.8:
======================================================================
+* Patches by Denis Peter, 9 Sep 2003:
+ add FAT support for IDE, SCSI and USB
+
+* Patches by Gleb Natapov, 2 Sep 2003:
+ - cleanup of POST code for unsupported architectures
+ - MPC824x locks way0 of data cache for use as initial RAM;
+ this patch unlocks it after relocation to RAM and invalidates
+ the locked entries.
+
+* Patch by Gleb Natapov, 30 Aug 2003:
+ new I2C driver for mpc107 bridge. Now works from flash.
+
+* Patch by Dave Ellis, 11 Aug 2003:
+ - JFFS2: fix typo in common/cmd_jffs2.c
+ - JFFS2: fix CFG_JFFS2_SORT_FRAGMENTS option
+ - JFFS2: remove node version 0 warning
+ - JFFS2: accept JFFS2 PADDING nodes
+ - SXNI855T: add AM29LV800 support
+ - SXNI855T: move environment from EEPROM to flash
+ - SXNI855T: boot from JFFS2 in NOR or NAND flash
+
+* Patch by Bill Hargen, 11 Aug 2003:
+ fixes for I2C on MPC8240
+ - fix i2c_write routine
+ - fix iprobe command
+ - eliminates use of global variables, plus dead code, cleanup.
+
* Add support for USB Mass Storage Devices (BBB)
(tested with USB memory sticks only)
N: Pantelis Antoniou
E: panto@intracom.gr
D: NETVIA board support, ARTOS support.
+
+N: Raghu Krishnaprasad
+E: Raghu.Krishnaprasad@fci.com
+D: Support for Adder-II MPC852T evaluation board
+W: http://www.forcecomputers.com
+
SXNI855T MPC8xx
+Raghu Krishnaprasad <raghu.krishnaprasad@fci.com>
+
+ ADDERII MPC852T
+
Thomas Frieden <ThomasF@hyperion-entertainment.com>
AmigaOneG3SE MPC7xx
}
}
-/* ------------------------------------------------------------------------- */
-
- /* switches the cs0 and the cs1 to the locations.
- When boot is TRUE, the the mapping is switched
- to the boot configuration, If it is FALSE, the
- flash will be switched in the boot area */
-
-#undef SW_CS_DBG
-#ifdef SW_CS_DBG
-#define SW_CS_PRINTF(fmt,args...) printf (fmt ,##args)
-#else
-#define SW_CS_PRINTF(fmt,args...)
-#endif
-
-#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
-int switch_cs(unsigned char boot)
-{
- unsigned long pbcr;
- int mode;
-
- mode=get_boot_mode();
- mtdcr(ebccfga, pb0cr);
- pbcr = mfdcr (ebccfgd);
- if (mode & BOOT_MPS) {
- /* Boot width = 8 bit MPS Boot, set up MPS on CS0 */
- /* we need only to switch if boot from MPS */
- /* printf(" MPS boot mode detected. ");*/
- /* printf("cs0 cfg: %lx\n",pbcr); */
- if(boot) {
- /* switch to boot configuration */
- /* this is a 8bit boot, switch cs0 to flash location */
- SW_CS_PRINTF("switch to boot mode (MPS on High address\n");
- pbcr&=0x000FFFFF; /*mask base address of the cs0 */
- pbcr|=(FLASH_BASE0_PRELIM & 0xFFF00000);
- mtdcr(ebccfga, pb0cr);
- mtdcr(ebccfgd, pbcr);
- SW_CS_PRINTF(" new cs0 cfg: %lx\n",pbcr);
- mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */
- pbcr = mfdcr(ebccfgd);
- SW_CS_PRINTF(" old cs1 cfg: %lx\n",pbcr);
- pbcr&=0x000FFFFF; /*mask base address of the cs1 */
- pbcr|=(MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000);
- mtdcr(ebccfga, pb1cr);
- mtdcr(ebccfgd, pbcr);
- SW_CS_PRINTF(" new cs1 cfg: %lx, MPS is on High Address\n",pbcr);
- }
- else {
- /* map flash to boot area, */
- SW_CS_PRINTF("map Flash to boot area\n");
- pbcr&=0x000FFFFF; /*mask base address of the cs0 */
- pbcr|=(MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000);
- mtdcr(ebccfga, pb0cr);
- mtdcr(ebccfgd, pbcr);
- SW_CS_PRINTF(" new cs0 cfg: %lx\n",pbcr);
- mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */
- pbcr = mfdcr(ebccfgd);
- SW_CS_PRINTF(" cs1 cfg: %lx\n",pbcr);
- pbcr&=0x000FFFFF; /*mask base address of the cs1 */
- pbcr|=(FLASH_BASE0_PRELIM & 0xFFF00000);
- mtdcr(ebccfga, pb1cr);
- mtdcr(ebccfgd, pbcr);
- SW_CS_PRINTF(" new cs1 cfg: %lx Flash is on High Address\n",pbcr);
- }
- return 1;
- }
- else {
- SW_CS_PRINTF("Normal boot, no switching necessary\n");
- return 0;
- }
-
-}
-
-int get_boot_mode(void)
-{
- unsigned long pbcr;
- int res = 0;
- pbcr = mfdcr (strap);
- if ((pbcr & PSR_ROM_WIDTH_MASK) == 0)
- /* boot via MPS or MPS mapping */
- res = BOOT_MPS;
- if(pbcr & PSR_ROM_LOC)
- /* boot via PCI.. */
- res |= BOOT_PCI;
- return res;
-}
-
-/* Setup cs0 parameter finally.
- Map the flash high (in boot area)
- This code can only be executed from SDRAM (after relocation).
-*/
-void setup_cs_reloc(void)
-{
- unsigned long pbcr;
- /* Since we are relocated, we can set-up the CS finaly
- * but first of all, switch off PCI mapping (in case it was a PCI boot) */
- out32r(PMM0MA,0L);
- icache_enable (); /* we are relocated */
- /* for PCI Boot, we have to set-up the remaining CS correctly */
- pbcr = mfdcr (strap);
- if(pbcr & PSR_ROM_LOC) {
- /* boot via PCI.. */
- if ((pbcr & PSR_ROM_WIDTH_MASK) == 0) {
- /* Boot width = 8 bit MPS Boot, set up MPS on CS0 */
- #ifdef DEBUG
- printf("Mapping MPS to CS0 @ 0x%lx\n",(MPS_CR_B & 0xfff00000));
- #endif
- mtdcr (ebccfga, pb0ap);
- mtdcr (ebccfgd, MPS_AP);
- mtdcr (ebccfga, pb0cr);
- mtdcr (ebccfgd, MPS_CR_B);
- }
- else {
- /* Flash boot, set up the Flash on CS0 */
- #ifdef DEBUG
- printf("Mapping Flash to CS0 @ 0x%lx\n",(FLASH_CR_B & 0xfff00000));
- #endif
- mtdcr (ebccfga, pb0ap);
- mtdcr (ebccfgd, FLASH_AP);
- mtdcr (ebccfga, pb0cr);
- mtdcr (ebccfgd, FLASH_CR_B);
- }
- }
- switch_cs(0); /* map Flash High */
-}
-
-
-#elif defined(CONFIG_VCMA9)
-int switch_cs(unsigned char boot)
-{
- return 0;
-}
-#endif /* CONFIG_VCMA9 */
int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
#ifdef CONFIG_CONSOLE_EXTRA_INFO
extern GraphicDevice ctfb;
+extern int get_boot_mode(void);
void video_get_info_str (int line_number, char *info)
{
} backup_t;
void get_backup_values(backup_t *buf);
-int switch_cs(unsigned char boot);
+
#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
-int get_boot_mode(void);
-void setup_cs_reloc(void);
#define BOOT_MPS 0x01
#define BOOT_PCI 0x02
#endif
#include <ppc4xx.h>
#include <asm/processor.h>
#include "common_util.h"
+#if defined(CONFIG_MIP405)
+#include "../mip405/mip405.h"
+#endif
+#if defined(CONFIG_PIP405)
+#include "../pip405/pip405.h"
+#endif
+#include <405gp_pci.h>
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
/*-----------------------------------------------------------------------
#define TRUE 1
/*-----------------------------------------------------------------------
+ * Some CS switching routines:
+ *
+ * On PIP/MIP405 we have 3 (4) possible boot mode
+ *
+ * - Boot from Flash (Flash CS = CS0, MPS CS = CS1)
+ * - Boot from MPS (Flash CS = CS1, MPS CS = CS0)
+ * - Boot from PCI with Flash map (Flash CS = CS0, MPS CS = CS1)
+ * - Boot from PCI with MPS map (Flash CS = CS1, MPS CS = CS0)
+ * The flash init is the first board specific routine which is called
+ * after code relocation (running from SDRAM)
+ * The first thing we do is to map the Flash CS to the Flash area and
+ * the MPS CS to the MPS area. Since the flash size is unknown at this
+ * point, we use the max flash size and the lowest flash address as base.
+ *
+ * After flash detection we adjust the size of the CS area accordingly.
+ * The board_init_r will fill in wrong values in the board init structure,
+ * but this will be fixed in the misc_init_r routine:
+ * bd->bi_flashstart=0-flash_info[0].size
+ * bd->bi_flashsize=flash_info[0].size-CFG_MONITOR_LEN
+ * bd->bi_flashoffset=0
+ *
*/
+int get_boot_mode(void)
+{
+ unsigned long pbcr;
+ int res = 0;
+ pbcr = mfdcr (strap);
+ if ((pbcr & PSR_ROM_WIDTH_MASK) == 0)
+ /* boot via MPS or MPS mapping */
+ res = BOOT_MPS;
+ if(pbcr & PSR_ROM_LOC)
+ /* boot via PCI.. */
+ res |= BOOT_PCI;
+ return res;
+}
+
+/* Map the flash high (in boot area)
+ This code can only be executed from SDRAM (after relocation).
+*/
+void setup_cs_reloc(void)
+{
+ int mode;
+ /* Since we are relocated, we can set-up the CS finaly
+ * but first of all, switch off PCI mapping (in case it was a PCI boot) */
+ out32r(PMM0MA,0L);
+ icache_enable (); /* we are relocated */
+ /* get boot mode */
+ mode=get_boot_mode();
+ /* we map the flash high in every case */
+ /* first findout on which cs the flash is */
+ if(mode & BOOT_MPS) {
+ /* map flash high on CS1 and MPS on CS0 */
+ mtdcr (ebccfga, pb0ap);
+ mtdcr (ebccfgd, MPS_AP);
+ mtdcr (ebccfga, pb0cr);
+ mtdcr (ebccfgd, MPS_CR);
+ /* we use the default values (max values) for the flash
+ * because its real size is not yet known */
+ mtdcr (ebccfga, pb1ap);
+ mtdcr (ebccfgd, FLASH_AP);
+ mtdcr (ebccfga, pb1cr);
+ mtdcr (ebccfgd, FLASH_CR_B);
+ }
+ else {
+ /* map flash high on CS0 and MPS on CS1 */
+ mtdcr (ebccfga, pb1ap);
+ mtdcr (ebccfgd, MPS_AP);
+ mtdcr (ebccfga, pb1cr);
+ mtdcr (ebccfgd, MPS_CR);
+ /* we use the default values (max values) for the flash
+ * because its real size is not yet known */
+ mtdcr (ebccfga, pb0ap);
+ mtdcr (ebccfgd, FLASH_AP);
+ mtdcr (ebccfga, pb0cr);
+ mtdcr (ebccfgd, FLASH_CR_B);
+ }
+}
+
unsigned long flash_init (void)
{
- unsigned long size_b0, size_b1;
- int i;
+ unsigned long size_b0, size_b1,flashcr;
+ int mode, i;
+ extern char version_string;
+ char *p=&version_string;
/* Since we are relocated, we can set-up the CS finally */
setup_cs_reloc();
/* get and display boot mode */
- i=get_boot_mode();
- if(i & BOOT_PCI)
- printf("(PCI Boot %s Map) ",(i & BOOT_MPS) ?
+ mode=get_boot_mode();
+ if(mode & BOOT_PCI)
+ printf("(PCI Boot %s Map) ",(mode & BOOT_MPS) ?
"MPS" : "Flash");
else
- printf("(%s Boot) ",(i & BOOT_MPS) ?
+ printf("(%s Boot) ",(mode & BOOT_MPS) ?
"MPS" : "Flash");
/* Init: no FLASHes known */
for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
/* Static FLASH Bank configuration here - FIXME XXX */
- size_b0 = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]);
+ size_b0 = flash_get_size((vu_long *)CFG_MONITOR_BASE, &flash_info[0]);
if (flash_info[0].flash_id == FLASH_UNKNOWN) {
printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
flash_info[0].protect[flash_info[0].sector_count-1] = 1;
size_b1 = 0 ;
flash_info[0].size = size_b0;
+ /* set up flash cs according to the size */
+ if(mode & BOOT_MPS) {
+ /* flash is on CS1 */
+ mtdcr(ebccfga, pb1cr);
+ flashcr = mfdcr (ebccfgd);
+ /* we map the flash high in every case */
+ flashcr&=0x0001FFFF; /* mask out address bits */
+ flashcr|= ((0-flash_info[0].size) & 0xFFF00000); /* start addr */
+ flashcr|= (((flash_info[0].size >>21) & 0x07) << 17); /* size addr */
+ mtdcr(ebccfga, pb1cr);
+ mtdcr(ebccfgd, flashcr);
+ }
+ else {
+ /* flash is on CS0 */
+ mtdcr(ebccfga, pb0cr);
+ flashcr = mfdcr (ebccfgd);
+ /* we map the flash high in every case */
+ flashcr&=0x0001FFFF; /* mask out address bits */
+ flashcr|= ((0-flash_info[0].size) & 0xFFF00000); /* start addr */
+ flashcr|= (((flash_info[0].size >>21) & 0x07) << 17); /* size addr */
+ mtdcr(ebccfga, pb0cr);
+ mtdcr(ebccfgd, flashcr);
+ }
#if 0
- /* include this if you want to test if
+ /* enable this if you want to test if
the relocation has be done ok.
This will disable both Chipselects */
mtdcr (ebccfga, pb0cr);
mtdcr (ebccfgd, 0L);
printf("CS0 & CS1 switched off for test\n");
#endif
+ /* patch version_string */
+ for(i=0;i<0x100;i++) {
+ if(*p=='\n') {
+ *p=0;
+ break;
+ }
+ p++;
+ }
return (size_b0);
}
break;
case FLASH_INTEL320T: printf ("TE28F320C3 (32 Mbit, top sector size)\n");
break;
+ case FLASH_AM640U: printf ("AM29LV640U (64 Mbit, uniform sector size)\n");
+ break;
default: printf ("Unknown Chip Type\n");
break;
}
/*-----------------------------------------------------------------------
- */
+
+*/
/*
* The following code cannot be run from FLASH!
{
short i;
FLASH_WORD_SIZE value;
- ulong base = (ulong)addr;
+ ulong base;
volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)addr;
/* Write auto select command: read Manufacturer ID */
return (0); /* no or unknown flash */
}
value = addr2[1]; /* device ID */
- /* printf("Device value %x\n",value); */
+ /* printf("Device value %x\n",value); */
switch (value) {
case (FLASH_WORD_SIZE)AMD_ID_F040B:
info->flash_id += FLASH_AM040;
info->sector_count = 35;
info->size = 0x00200000;
break; /* => 2 MB */
-#if 0 /* enable when device IDs are available */
case (FLASH_WORD_SIZE)AMD_ID_LV320T:
info->flash_id += FLASH_AM320T;
info->sector_count = 67;
info->size = 0x00400000;
break; /* => 4 MB */
+ case (FLASH_WORD_SIZE)AMD_ID_LV640U:
+ info->flash_id += FLASH_AM640U;
+ info->sector_count = 128;
+ info->size = 0x00800000;
+ break; /* => 8 MB */
+#if 0 /* enable when device IDs are available */
case (FLASH_WORD_SIZE)AMD_ID_LV320B:
info->flash_id += FLASH_AM320B;
return (0); /* => no or unknown flash */
}
-
+ /* base address calculation */
+ base=0-info->size;
/* set up sector start address table */
if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
- (info->flash_id == FLASH_AM040)){
+ (info->flash_id == FLASH_AM040) ||
+ (info->flash_id == FLASH_AM640U)){
for (i = 0; i < info->sector_count; i++)
info->start[i] = base + (i * 0x00010000);
}
#include "kbd.h"
#include "video.h"
-extern int drv_isa_kbd_init (void);
#undef ISA_DEBUG
#define FALSE 0
#endif
+#if defined(CONFIG_PIP405)
+
+extern int drv_isa_kbd_init (void);
/* fdc (logical device 0) */
const SIO_LOGDEV_TABLE sio_fdc[] = {
close_cfg_super_IO(0x3F0);
}
}
-
+#endif
/******************************************************************************
* IRQ Controller
/*
* This contains the irq mask for both 8259A irq controllers,
*/
-static unsigned int cached_irq_mask = 0xffff;
+static unsigned int cached_irq_mask = 0xfff9;
#define cached_imr1 (unsigned char)cached_irq_mask
#define cached_imr2 (unsigned char)(cached_irq_mask>>8)
isr2=in8(ISR_2);
isr1=in8(ISR_1);
irq=(unsigned char)irqack;
- if((irq==7)&&((isr1&0x80)==0)) {
+ irq-=32;
+/* if((irq==7)&&((isr1&0x80)==0)) {
PRINTF("IRQ7 detected but not in ISR\n");
}
else {
- /* we should handle cascaded interrupts here also */
- /* printf("ISA Irq %d\n",irq); */
- isa_irqs[irq].count++;
- if (isa_irqs[irq].handler != NULL)
- (*isa_irqs[irq].handler)(isa_irqs[irq].arg); /* call isr */
- else
+*/ /* we should handle cascaded interrupts here also */
{
- PRINTF ("bogus interrupt vector 0x%x\n", irq);
- }
+/* printf("ISA Irq %d\n",irq); */
+ isa_irqs[irq].count++;
+ if(irq!=2) { /* just swallow the cascade irq 2 */
+ if (isa_irqs[irq].handler != NULL)
+ (*isa_irqs[irq].handler)(isa_irqs[irq].arg); /* call isr */
+ else {
+ PRINTF ("bogus interrupt vector 0x%x\n", irq);
+ }
+ }
}
/* issue EOI instruction to clear the IRQ */
mask_and_ack_8259A(irq);
void isa_irq_install_handler(int vec, interrupt_handler_t *handler, void *arg)
{
- if (isa_irqs[vec].handler != NULL) {
- printf ("ISA Interrupt vector %d: handler 0x%x replacing 0x%x\n",
- vec, (uint)handler, (uint)isa_irqs[vec].handler);
- }
- isa_irqs[vec].handler = handler;
- isa_irqs[vec].arg = arg;
- enable_8259A_irq(vec);
+ if (isa_irqs[vec].handler != NULL) {
+ printf ("ISA Interrupt vector %d: handler 0x%x replacing 0x%x\n",
+ vec, (uint)handler, (uint)isa_irqs[vec].handler);
+ }
+ isa_irqs[vec].handler = handler;
+ isa_irqs[vec].arg = arg;
+ enable_8259A_irq(vec);
PRINTF ("Install ISA IRQ %d ==> %p, @ %p mask=%04x\n", vec, handler, &isa_irqs[vec].handler,cached_irq_mask);
}
void isa_irq_free_handler(int vec)
{
disable_8259A_irq(vec);
- isa_irqs[vec].handler = NULL;
- isa_irqs[vec].arg = NULL;
- printf ("Free ISA IRQ %d mask=%04x\n", vec, cached_irq_mask);
+ isa_irqs[vec].handler = NULL;
+ isa_irqs[vec].arg = NULL;
+ PRINTF ("Free ISA IRQ %d mask=%04x\n", vec, cached_irq_mask);
}
init_8259A();
out8(IMR_2,0xFF);
}
+/*************************************************************************/
+void isa_show_irq(void)
+{
+ int vec;
+
+ printf ("\nISA Interrupt-Information:\n");
+ printf ("Nr Routine Arg Count\n");
+
+ for (vec=0; vec<16; vec++) {
+ if (isa_irqs[vec].handler != NULL) {
+ printf ("%02d %08lx %08lx %d\n",
+ vec,
+ (ulong)isa_irqs[vec].handler,
+ (ulong)isa_irqs[vec].arg,
+ isa_irqs[vec].count);
+ }
+ }
+}
+
+int isa_irq_get_count(int vec)
+{
+ return(isa_irqs[vec].count);
+}
/******************************************************************
* Init the ISA bus and devices.
*/
+#if defined(CONFIG_PIP405)
int isa_init(void)
{
isa_sio_setup();
+ isa_init_irq_contr();
drv_isa_kbd_init();
return 0;
}
+#endif
* MA 02111-1307 USA
*/
-#ifndef _PIP405_ISA_H_
-#define _PIP405_ISA_H_
+#ifndef _ISA_H_
+#define _ISA_H_
/* Super IO */
#define SIO_CFG_PORT 0x3F0 /* Config Port Address */
-
+#if defined(CONFIG_PIP405)
/* table fore SIO initialization */
typedef struct {
const uchar index;
void write_cfg_super_IO(int address, unsigned char function, unsigned char regaddr, unsigned char data);
void close_cfg_super_IO(int address);
void isa_sio_setup(void);
-void isa_sio_setup(void);
+#endif
+
void isa_irq_install_handler(int vec, interrupt_handler_t *handler, void *arg);
void isa_irq_free_handler(int vec);
int handle_isa_int(void);
+void isa_init_irq_contr(void);
+void isa_show_irq(void);
+int isa_irq_get_count(int vec);
#endif
/* PIIX4 ISA Bridge Function 0 */
static struct pci_pip405_config_entry piix4_isa_bridge_f0[] = {
{PCI_CFG_PIIX4_SERIRQ, 0xD0, 1}, /* enable Continous SERIRQ Pin */
- {PCI_CFG_PIIX4_GENCFG, 0x00010041, 4}, /* enable SERIRQs, ISA, PNP */
+ {PCI_CFG_PIIX4_GENCFG, 0x00018041, 4}, /* enable SERIRQs, ISA, PNP, GPI11 */
{PCI_CFG_PIIX4_TOM, 0xFE, 1}, /* Top of Memory */
{PCI_CFG_PIIX4_XBCS, 0x02C4, 2}, /* disable all peri CS */
{PCI_CFG_PIIX4_RTCCFG, 0x21, 1}, /* enable RTC */
/* PIIX4 IDE Controller Function 1 */
static struct pci_pip405_config_entry piix4_ide_cntrl_f1[] = {
+ {PCI_CFG_PIIX4_BMIBA, 0x0001000, 4}, /* set BMI to a valid address */
{PCI_COMMAND, 0x0001, 2}, /* enable IO access */
#if !defined(CONFIG_MIP405T)
{PCI_CFG_PIIX4_IDETIM, 0x80008000, 4}, /* enable Both IDE channels */
/* PIIX4 Power Management Function 3 */
static struct pci_pip405_config_entry piix4_pmm_cntrl_f3[] = {
- {PCI_COMMAND, 0x0001, 2}, /* enable IO access */
- {PCI_CFG_PIIX4_PMAB, 0x00004000, 4}, /* set PMBA to "valid" value */
- {PCI_CFG_PIIX4_PMMISC, 0x01, 1}, /* enable PMBA IO access */
+ {PCI_CFG_PIIX4_PMBA, 0x00004000, 4}, /* set PMBA to "valid" value */
{PCI_CFG_PIIX4_SMBBA, 0x00005000, 4}, /* set SMBBA to "valid" value */
+ {PCI_CFG_PIIX4_PMMISC, 0x01, 1}, /* enable PMBA IO access */
+ {PCI_COMMAND, 0x0001, 2}, /* enable IO access */
{ } /* end of device table */
};
/* PPC405 Dummy only used to prevent autosetup on this host bridge */
#define PCI_CFG_PIIX4_LEGSUP 0xC0
/* Function 3 Power Management */
-#define PCI_CFG_PIIX4_PMAB 0x40
+#define PCI_CFG_PIIX4_PMBA 0x40
#define PCI_CFG_PIIX4_CNTA 0x44
#define PCI_CFG_PIIX4_CNTB 0x48
#define PCI_CFG_PIIX4_GPICTL 0x4C
return (do_mplcommon(cmdtp, flag, argc, argv));
}
U_BOOT_CMD(
- mip405, 6, 1, do_mip405,
+ mip405, 8, 1, do_mip405,
"mip405 - MIP405 specific Cmds\n",
"flash mem [SrcAddr] - updates U-Boot with image in memory\n"
"mip405 flash mps - updates U-Boot with image from MPS\n"
+ "mip405 info - displays board information\n"
+ "mip405 led <on> - switches LED on (on=1) or off (on=0)\n"
+ "mip405 mem [cnt] - Memory Test <cnt>-times, <cnt> = -1 loop forever\n"
);
/* ------------------------------------------------------------------------- */
mfdcr r4,ebccfgd
andi. r0, r4, 0x2000 /* mask out irrelevant bits */
- beq 0f /* jump if 8 bit bus width */
+ beq 0f /* jump if 8 bit bus width */
- /* setup 16 bit things (Flash Boot)
+ /* setup 16 bit things
*-----------------------------------------------------------------------
* Memory Bank 0 (16 Bit Flash) initialization
*---------------------------------------------------------------------- */
addi r4,0,pb0ap
mtdcr ebccfga,r4
-/* addis r4,0,0xFF8F */
-/* ori r4,r4,0xFE80 */
-/* addis r4,0,0x9B01 */
-/* ori r4,r4,0x5480 */
addis r4,0,(FLASH_AP_B)@h
ori r4,r4,(FLASH_AP_B)@l
mtdcr ebccfgd,r4
addi r4,0,pb0cr
mtdcr ebccfga,r4
/* BS=0x010(4MB),BU=0x3(R/W), */
-/* addis r4,0,((FLASH_BASE0_PRELIM & 0xFFF00000) | 0x00050000)@h */
-/* ori r4,r4,0xA000 / * BW=0x01(16 bits) */
addis r4,0,(FLASH_CR_B)@h
ori r4,r4,(FLASH_CR_B)@l
mtdcr ebccfgd,r4
/* 0x7F8FFE80 slowest boot */
addi r4,0,pb0ap
mtdcr ebccfga,r4
-#if 0
- addis r4,0,0x9B01
- ori r4,r4,0x5480
-#else
addis r4,0,(MPS_AP_B)@h
ori r4,r4,(MPS_AP_B)@l
-#endif
mtdcr ebccfgd,r4
addi r4,0,pb0cr
mtdcr ebccfga,r4
/* BS=0x010(4MB),BU=0x3(R/W), */
-/* addis r4,0,((FLASH_BASE0_PRELIM & 0xFFF00000) | 0x00050000)@h */
-/* ori r4,r4,0x8000 / * BW=0x0( 8 bits) */
-
addis r4,0,(MPS_CR_B)@h
ori r4,r4,(MPS_CR_B)@l
ori r4,r4,0x0000
mtdcr ebccfgd,r4
- addi r4,0,pb6cr
+ addi r4,0,pb6cr
mtdcr ebccfga,r4
addis r4,0,0x0000
ori r4,r4,0x0000
mtdcr ebccfgd,r4
- addi r4,0,pb7cr
+ addi r4,0,pb7cr
mtdcr ebccfga,r4
addis r4,0,0x0000
ori r4,r4,0x0000
mtdcr ebccfgd,r4
- nop /* pass2 DCR errata #8 */
+ nop /* pass2 DCR errata #8 */
blr
/*-----------------------------------------------------------------------------
/* used to check if the time in RTC is valid */
static unsigned long start;
static struct rtc_time tm;
+extern flash_info_t flash_info[]; /* info for FLASH chips */
int misc_init_r (void)
{
+ DECLARE_GLOBAL_DATA_PTR;
+ /* adjust flash start and size as well as the offset */
+ gd->bd->bi_flashstart=0-flash_info[0].size;
+ gd->bd->bi_flashsize=flash_info[0].size-CFG_MONITOR_LEN;
+ gd->bd->bi_flashoffset=0;
+
/* check, if RTC is running */
rtc_get (&tm);
start=get_timer(0);
(FLASH_WBF << 12) + (FLASH_TH << 9) + (FLASH_RE << 8) + (FLASH_SOR << 7) + (FLASH_BEM << 6) + (FLASH_PEN << 5))
/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
-#define FLASH_BS 2 /* 4 MByte */
+#define FLASH_BS FLASH_SIZE_PRELIM /* 4 MByte */
/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
#define FLASH_BU 3 /* R/W */
/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
#define FLASH_BW 1 /* 16Bit */
/* CR register for Boot */
-#define FLASH_CR_B ((FLASH_BASE0_PRELIM & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13))
+#define FLASH_CR_B ((FLASH_BASE_PRELIM & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13))
/* CR register for non Boot */
#define FLASH_CR ((MULTI_PURPOSE_SOCKET_ADDR & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13))
/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
#define MPS_BS 2 /* 4 MByte */
+#define MPS_BS_B FLASH_SIZE_PRELIM /* 1 MByte */
/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
#define MPS_BU 3 /* R/W */
/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
#define MPS_BW 0 /* 8Bit */
/* CR register for Boot */
-#define MPS_CR_B ((FLASH_BASE0_PRELIM & 0xfff00000) + (MPS_BS << 17) + (MPS_BU << 15) + (MPS_BW << 13))
+#define MPS_CR_B ((FLASH_BASE_PRELIM & 0xfff00000) + (MPS_BS_B << 17) + (MPS_BU << 15) + (MPS_BW << 13))
/* CR register for non Boot */
#define MPS_CR ((MULTI_PURPOSE_SOCKET_ADDR & 0xfff00000) + (MPS_BS << 17) + (MPS_BU << 15) + (MPS_BW << 13))
#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
-#include "configs/PIP405.h"
+#include <configs/PIP405.h>
#include <ppc_asm.tmpl>
#include <ppc_defs.h>
#include <asm/cache.h>
#include <asm/mmu.h>
+#include "pip405.h"
+ .globl ext_bus_cntlr_init
+ ext_bus_cntlr_init:
+ mflr r4 /* save link register */
+ mfdcr r3,strap /* get strapping reg */
+ andi. r0, r3, PSR_ROM_LOC /* mask out irrelevant bits */
+ bnelr /* jump back if PCI boot */
- .globl ext_bus_cntlr_init
-ext_bus_cntlr_init:
- mflr r4 /* save link register */
bl ..getAddr
..getAddr:
mflr r3 /* get address of ..getAddr */
mfdcr r4,ebccfgd
andi. r0, r4, 0x2000 /* mask out irrelevant bits */
- beq 0f /* jump if 8 bit bus width */
+ beq 0f /* jump if 8 bit bus width */
/* setup 16 bit things
*-----------------------------------------------------------------------
*---------------------------------------------------------------------- */
addi r4,0,pb0ap
- mtdcr ebccfga,r4
- addis r4,0,0x9B01
- ori r4,r4,0x5480
- mtdcr ebccfgd,r4
-
- addi r4,0,pb0cr
- mtdcr ebccfga,r4
- /* BS=0x011(8MB),BU=0x3(R/W), */
- addis r4,0,((FLASH_BASE0_PRELIM & 0xFFF00000) | 0x00050000)@h
- ori r4,r4,0xA000 /* BW=0x01(16 bits) */
- mtdcr ebccfgd,r4
-
- /*-----------------------------------------------------------------------
- * Memory Bank 1 (Multi Purpose Socket) initialization
- *----------------------------------------------------------------------*/
- addi r4,0,pb1ap
- mtdcr ebccfga,r4
- addis r4,0,0x0281
- ori r4,r4,0x5480
- mtdcr ebccfgd,r4
-
- addi r4,0,pb1cr
- mtdcr ebccfga,r4
- /* BS=0x011(8MB),BU=0x3(R/W), */
- addis r4,0,((MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000) | 0x00050000)@h
- ori r4,r4,0x8000 /* BW=0x0( 8 bits) */
- mtdcr ebccfgd,r4
+ mtdcr ebccfga,r4
+ addis r4,0,(FLASH_AP_B)@h
+ ori r4,r4,(FLASH_AP_B)@l
+ mtdcr ebccfgd,r4
+
+ addi r4,0,pb0cr
+ mtdcr ebccfga,r4
+ /* BS=0x010(4MB),BU=0x3(R/W), */
+ addis r4,0,(FLASH_CR_B)@h
+ ori r4,r4,(FLASH_CR_B)@l
+ mtdcr ebccfgd,r4
b 1f
0:
- /* 8Bit boot mode: */
+ /* 8Bit boot mode: */
/*-----------------------------------------------------------------------
- * Memory Bank 0 Multi Purpose Socket initialization
- *----------------------------------------------------------------------- */
-
+ * Memory Bank 0 Multi Purpose Socket initialization
+ *----------------------------------------------------------------------- */
+ /* 0x7F8FFE80 slowest boot */
addi r4,0,pb0ap
- mtdcr ebccfga,r4
- addis r4,0,0x9B01
- ori r4,r4,0x5480
- mtdcr ebccfgd,r4
+ mtdcr ebccfga,r4
+ addis r4,0,(MPS_AP_B)@h
+ ori r4,r4,(MPS_AP_B)@l
+ mtdcr ebccfgd,r4
+
+ addi r4,0,pb0cr
+ mtdcr ebccfga,r4
+ /* BS=0x010(4MB),BU=0x3(R/W), */
+ addis r4,0,(MPS_CR_B)@h
+ ori r4,r4,(MPS_CR_B)@l
+ mtdcr ebccfgd,r4
- addi r4,0,pb0cr
- mtdcr ebccfga,r4
- /* BS=0x011(4MB),BU=0x3(R/W), */
- addis r4,0,((FLASH_BASE0_PRELIM & 0xFFF00000) | 0x00050000)@h
- ori r4,r4,0x8000 /* BW=0x0( 8 bits) */
- mtdcr ebccfgd,r4
+1:
/*-----------------------------------------------------------------------
- * Memory Bank 1 (Flash) initialization
+ * Memory Bank 2-3-4-5-6 (not used) initialization
*-----------------------------------------------------------------------*/
- addi r4,0,pb1ap
- mtdcr ebccfga,r4
- addis r4,0,0x0281
- ori r4,r4,0x5480
- mtdcr ebccfgd,r4
-
addi r4,0,pb1cr
mtdcr ebccfga,r4
- /* BS=0x011(8MB),BU=0x3(R/W), */
- addis r4,0,((MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000) | 0x00050000)@h
- ori r4,r4,0xA000 /* BW=0x0( 8 bits) */
+ addis r4,0,0x0000
+ ori r4,r4,0x0000
mtdcr ebccfgd,r4
-1:
- /*-----------------------------------------------------------------------
- * Memory Bank 2-3-4-5-6 (not used) initialization
- *-----------------------------------------------------------------------*/
addi r4,0,pb2cr
mtdcr ebccfga,r4
addis r4,0,0x0000
ori r4,r4,0x0000
mtdcr ebccfgd,r4
- addi r4,0,pb6cr
+ addi r4,0,pb6cr
mtdcr ebccfga,r4
addis r4,0,0x0000
ori r4,r4,0x0000
- mtdcr ebccfgd,r4
-
- /*-----------------------------------------------------------------------
- * Memory Bank 7 (Config Register) initialization
- *----------------------------------------------------------------------- */
- addi r4,0,pb7ap
- mtdcr ebccfga,r4
- addis r4,0,0x0181 /* Doc says TWT=3 and Openios TWT=3!! */
- ori r4,r4,0x5280 /* disable Ready, BEM=0 */
mtdcr ebccfgd,r4
addi r4,0,pb7cr
mtdcr ebccfga,r4
- /* BS=0x0(1MB),BU=0x3(R/W), */
- addis r4,0,((CONFIG_PORT_ADDR & 0xFFF00000) | 0x00010000)@h
- ori r4,r4,0x8000 /* BW=0x0(8 bits) */
+ addis r4,0,0x0000
+ ori r4,r4,0x0000
mtdcr ebccfgd,r4
- nop /* pass2 DCR errata #8 */
+ nop /* pass2 DCR errata #8 */
blr
/*-----------------------------------------------------------------------------
blr
+
+
+#if defined(CONFIG_BOOT_PCI)
+ .section .bootpg,"ax"
+ .globl _start_pci
+/*******************************************
+ */
+
+_start_pci:
+ /* first handle errata #68 / PCI_18 */
+ iccci r0, r0 /* invalidate I-cache */
+ lis r31, 0
+ mticcr r31 /* ICCR = 0 (all uncachable) */
+ isync
+
+ mfccr0 r28 /* set CCR0[24] = 1 */
+ ori r28, r28, 0x0080
+ mtccr0 r28
+
+ /* setup PMM0MA (0xEF400004) and PMM0PCIHA (0xEF40000C) */
+ lis r28, 0xEF40
+ addi r28, r28, 0x0004
+ stw r31, 0x0C(r28) /* clear PMM0PCIHA */
+ lis r29, 0xFFF8 /* open 512 kByte */
+ addi r29, r29, 0x0001/* and enable this region */
+ stwbrx r29, r0, r28 /* write PMM0MA */
+
+ lis r28, 0xEEC0 /* address of PCIC0_CFGADDR */
+ addi r29, r28, 4 /* add 4 to r29 -> PCIC0_CFGDATA */
+
+ lis r31, 0x8000 /* set en bit bus 0 */
+ ori r31, r31, 0x304C/* device 6 func 0 reg 4C (XBCS register) */
+ stwbrx r31, r0, r28 /* write it */
+
+ lwbrx r31, r0, r29 /* load XBCS register */
+ oris r31, r31, 0x02C4/* clear BIOSCS WPE, set lower, extended and 1M extended BIOS enable */
+ stwbrx r31, r0, r29 /* write back XBCS register */
+
+ nop
+ nop
+ b _start /* normal start */
+#endif
#ifdef SDRAM_DEBUG
DECLARE_GLOBAL_DATA_PTR;
#endif
+ /* set up the config port */
+ mtdcr (ebccfga, pb7ap);
+ mtdcr (ebccfgd, CONFIG_PORT_AP);
+ mtdcr (ebccfga, pb7cr);
+ mtdcr (ebccfgd, CONFIG_PORT_CR);
memclk = get_bus_freq (tmemclk);
tmemclk = 1000000000 / (memclk / 100); /* in 10 ps units */
}
+extern flash_info_t flash_info[]; /* info for FLASH chips */
+
int misc_init_r (void)
{
+ DECLARE_GLOBAL_DATA_PTR;
+ /* adjust flash start and size as well as the offset */
+ gd->bd->bi_flashstart=0-flash_info[0].size;
+ gd->bd->bi_flashsize=flash_info[0].size-CFG_MONITOR_LEN;
+ gd->bd->bi_flashoffset=0;
+
+ /* if PIP405 has booted from PCI, reset CCR0[24] as described in errata PCI_18 */
+ if (mfdcr(strap) & PSR_ROM_LOC)
+ mtspr(ccr0, (mfspr(ccr0) & ~0x80));
+
return (0);
}
* Global routines used for PIP405
*****************************************************************************/
+#ifndef __ASSEMBLY__
extern int mem_test(unsigned long start, unsigned long ramsize,int mode);
#define PLD_BASE_ADDRESS CFG_ISA_IO_BASE_ADDRESS + 0x800
-#define PLD_PART_REG PLD_BASE_ADDRESS + 0
-#define PLD_VERS_REG PLD_BASE_ADDRESS + 1
+#define PLD_PART_REG PLD_BASE_ADDRESS + 0
+#define PLD_VERS_REG PLD_BASE_ADDRESS + 1
#define PLD_BOARD_CFG_REG PLD_BASE_ADDRESS + 2
#define PLD_LED_USER_REG PLD_BASE_ADDRESS + 3
#define PLD_SYS_MAN_REG PLD_BASE_ADDRESS + 4
#define PLD_FLASH_COM_REG PLD_BASE_ADDRESS + 5
-#define PLD_CAN_REG PLD_BASE_ADDRESS + 6
+#define PLD_CAN_REG PLD_BASE_ADDRESS + 6
#define PLD_SER_PWR_REG PLD_BASE_ADDRESS + 7
#define PLD_COM_PWR_REG PLD_BASE_ADDRESS + 8
#define PLD_NIC_VGA_REG PLD_BASE_ADDRESS + 9
#define PIIX4_VENDOR_ID 0x8086
#define PIIX4_IDE_DEV_ID 0x7111
+#endif
/* timings */
-/* PLD (CS7) */
-#define PLD_BME 0 /* Burst disable */
-#define PLD_TWE 5 /* 5 * 30ns 120ns Waitstates (access=TWT+1+TH) */
-#define PLD_CSN 1 /* Chipselect is driven inactive for 1 Cycle BTW transfers */
-#define PLD_OEN 1 /* Cycles from CS low to OE low */
-#define PLD_WBN 1 /* Cycles from CS low to WE low */
-#define PLD_WBF 1 /* Cycles from WE high to CS high */
-#define PLD_TH 2 /* Number of hold cycles after transfer */
-#define PLD_RE 0 /* Ready disabled */
-#define PLD_SOR 1 /* Sample on Ready disabled */
-#define PLD_BEM 0 /* Byte Write only active on Write cycles */
-#define PLD_PEN 0 /* Parity disable */
-#define PLD_AP ((PLD_BME << 31) + (PLD_TWE << 23) + (PLD_CSN << 18) + (PLD_OEN << 16) + (PLD_WBN << 14) + \
- (PLD_WBF << 12) + (PLD_TH << 9) + (PLD_RE << 8) + (PLD_SOR << 7) + (PLD_BEM << 6) + (PLD_PEN << 5))
-
-/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
-#define PLD_BS 0 /* 1 MByte */
-/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
-#define PLD_BU 3 /* R/W */
-/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
-#define PLD_BW 0 /* 16Bit */
-#define PLD_CR ((PER_PLD_ADDR & 0xfff00000) + (PLD_BS << 17) + (PLD_BU << 15) + (PLD_BW << 13))
-
-/* timings */
-
-#define PER_BOARD_ADDR (PER_UART1_ADDR+(1024*1024))
-/* Dummy CS to get the board revision */
-#define BOARD_BME 0 /* Burst disable */
-#define BOARD_TWE 255 /* 255 * 30ns 120ns Waitstates (access=TWT+1+TH) */
-#define BOARD_CSN 1 /* Chipselect is driven inactive for 1 Cycle BTW transfers */
-#define BOARD_OEN 1 /* Cycles from CS low to OE low */
-#define BOARD_WBN 1 /* Cycles from CS low to WE low */
-#define BOARD_WBF 1 /* Cycles from WE high to CS high */
-#define BOARD_TH 2 /* Number of hold cycles after transfer */
-#define BOARD_RE 0 /* Ready disabled */
-#define BOARD_SOR 1 /* Sample on Ready disabled */
-#define BOARD_BEM 0 /* Byte Write only active on Write cycles */
-#define BOARD_PEN 0 /* Parity disable */
-#define BOARD_AP ((BOARD_BME << 31) + (BOARD_TWE << 23) + (BOARD_CSN << 18) + (BOARD_OEN << 16) + (BOARD_WBN << 14) + \
- (BOARD_WBF << 12) + (BOARD_TH << 9) + (BOARD_RE << 8) + (BOARD_SOR << 7) + (BOARD_BEM << 6) + (BOARD_PEN << 5))
+/* CS Config register (CS7) */
+#define CONFIG_PORT_BME 0 /* Burst disable */
+#define CONFIG_PORT_TWE 255 /* 255 * 30ns 120ns Waitstates (access=TWT+1+TH) */
+#define CONFIG_PORT_CSN 1 /* Chipselect is driven inactive for 1 Cycle BTW transfers */
+#define CONFIG_PORT_OEN 1 /* Cycles from CS low to OE low */
+#define CONFIG_PORT_WBN 1 /* Cycles from CS low to WE low */
+#define CONFIG_PORT_WBF 1 /* Cycles from WE high to CS high */
+#define CONFIG_PORT_TH 2 /* Number of hold cycles after transfer */
+#define CONFIG_PORT_RE 0 /* Ready disabled */
+#define CONFIG_PORT_SOR 1 /* Sample on Ready disabled */
+#define CONFIG_PORT_BEM 0 /* Byte Write only active on Write cycles */
+#define CONFIG_PORT_PEN 0 /* Parity disable */
+#define CONFIG_PORT_AP ((CONFIG_PORT_BME << 31) + (CONFIG_PORT_TWE << 23) + (CONFIG_PORT_CSN << 18) + (CONFIG_PORT_OEN << 16) + (CONFIG_PORT_WBN << 14) + \
+ (CONFIG_PORT_WBF << 12) + (CONFIG_PORT_TH << 9) + (CONFIG_PORT_RE << 8) + (CONFIG_PORT_SOR << 7) + (CONFIG_PORT_BEM << 6) + (CONFIG_PORT_PEN << 5))
/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
-#define BOARD_BS 0 /* 1 MByte */
+#define CONFIG_PORT_BS 0 /* 1 MByte */
/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
-#define BOARD_BU 3 /* R/W */
+#define CONFIG_PORT_BU 3 /* R/W */
/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
-#define BOARD_BW 0 /* 16Bit */
-#define BOARD_CR ((PER_BOARD_ADDR & 0xfff00000) + (BOARD_BS << 17) + (BOARD_BU << 15) + (BOARD_BW << 13))
-
-
-/* UART0 CS2 */
-#define UART0_BME 0 /* Burst disable */
-#define UART0_TWE 7 /* 7 * 30ns 210ns Waitstates (access=TWT+1+TH) */
-#define UART0_CSN 1 /* Chipselect is driven inactive for 1 Cycle BTW transfers */
-#define UART0_OEN 1 /* Cycles from CS low to OE low */
-#define UART0_WBN 1 /* Cycles from CS low to WE low */
-#define UART0_WBF 1 /* Cycles from WE high to CS high */
-#define UART0_TH 2 /* Number of hold cycles after transfer */
-#define UART0_RE 0 /* Ready disabled */
-#define UART0_SOR 1 /* Sample on Ready disabled */
-#define UART0_BEM 0 /* Byte Write only active on Write cycles */
-#define UART0_PEN 0 /* Parity disable */
-#define UART0_AP ((UART0_BME << 31) + (UART0_TWE << 23) + (UART0_CSN << 18) + (UART0_OEN << 16) + (UART0_WBN << 14) + \
- (UART0_WBF << 12) + (UART0_TH << 9) + (UART0_RE << 8) + (UART0_SOR << 7) + (UART0_BEM << 6) + (UART0_PEN << 5))
-
-/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
-#define UART0_BS 0 /* 1 MByte */
-/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
-#define UART0_BU 3 /* R/W */
-/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
-#define UART0_BW 0 /* 8Bit */
-#define UART0_CR ((PER_UART0_ADDR & 0xfff00000) + (UART0_BS << 17) + (UART0_BU << 15) + (UART0_BW << 13))
-
-/* UART1 CS3 */
-#define UART1_AP UART0_AP /* same timing as UART0 */
-#define UART1_CR ((PER_UART1_ADDR & 0xfff00000) + (UART0_BS << 17) + (UART0_BU << 15) + (UART0_BW << 13))
-
+#define CONFIG_PORT_BW 0 /* 16Bit */
+#define CONFIG_PORT_CR ((CONFIG_PORT_ADDR & 0xfff00000) + (CONFIG_PORT_BS << 17) + (CONFIG_PORT_BU << 15) + (CONFIG_PORT_BW << 13))
/* Flash CS0 or CS 1 */
/* 0x7F8FFE80 slowest timing at all... */
#define FLASH_PEN 0 /* Parity disable */
/* Access Parameter Register for non Boot */
#define FLASH_AP ((FLASH_BME << 31) + (FLASH_TWE << 23) + (FLASH_CSN << 18) + (FLASH_OEN << 16) + (FLASH_WBN << 14) + \
- (FLASH_WBF << 12) + (FLASH_TH << 9) + (FLASH_RE << 8) + (FLASH_SOR << 7) + (FLASH_BEM << 6) + (FLASH_PEN << 5))
+ (FLASH_WBF << 12) + (FLASH_TH << 9) + (FLASH_RE << 8) + (FLASH_SOR << 7) + (FLASH_BEM << 6) + (FLASH_PEN << 5))
/* Access Parameter Register for Boot */
#define FLASH_AP_B ((FLASH_BME_B << 31) + (FLASH_FWT_B << 26) + (FLASH_BWT_B << 23) + (FLASH_CSN << 18) + (FLASH_OEN << 16) + (FLASH_WBN << 14) + \
- (FLASH_WBF << 12) + (FLASH_TH << 9) + (FLASH_RE << 8) + (FLASH_SOR << 7) + (FLASH_BEM << 6) + (FLASH_PEN << 5))
+ (FLASH_WBF << 12) + (FLASH_TH << 9) + (FLASH_RE << 8) + (FLASH_SOR << 7) + (FLASH_BEM << 6) + (FLASH_PEN << 5))
/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
-#define FLASH_BS 2 /* 4 MByte */
+#define FLASH_BS FLASH_SIZE_PRELIM /* 4 MByte */
/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
#define FLASH_BU 3 /* R/W */
/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
#define FLASH_BW 1 /* 16Bit */
/* CR register for Boot */
-#define FLASH_CR_B ((FLASH_BASE0_PRELIM & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13))
+#define FLASH_CR_B ((FLASH_BASE_PRELIM & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13))
/* CR register for non Boot */
#define FLASH_CR ((MULTI_PURPOSE_SOCKET_ADDR & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13))
#define MPS_PEN 0 /* Parity disable */
/* Access Parameter Register for non Boot */
#define MPS_AP ((MPS_BME << 31) + (MPS_TWE << 23) + (MPS_CSN << 18) + (MPS_OEN << 16) + (MPS_WBN << 14) + \
- (MPS_WBF << 12) + (MPS_TH << 9) + (MPS_RE << 8) + (MPS_SOR << 7) + (MPS_BEM << 6) + (MPS_PEN << 5))
+ (MPS_WBF << 12) + (MPS_TH << 9) + (MPS_RE << 8) + (MPS_SOR << 7) + (MPS_BEM << 6) + (MPS_PEN << 5))
/* Access Parameter Register for Boot */
-#define MPS_AP_B ((MPS_BME_B << 31) + (MPS_FWT_B << 26) + (MPS_BWT_B << 23) + (MPS_CSN << 18) + (MPS_OEN << 16) + (MPS_WBN << 14) + \
- (MPS_WBF << 12) + (MPS_TH << 9) + (MPS_RE << 8) + (MPS_SOR << 7) + (MPS_BEM << 6) + (MPS_PEN << 5))
+#define MPS_AP_B ((MPS_BME_B << 31) + (MPS_FWT_B << 26) + (MPS_BWT_B << 23) + (MPS_CSN << 18) + (MPS_OEN << 16) + (MPS_WBN << 14) + \
+ (MPS_WBF << 12) + (MPS_TH << 9) + (MPS_RE << 8) + (MPS_SOR << 7) + (MPS_BEM << 6) + (MPS_PEN << 5))
/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
#define MPS_BS 2 /* 4 MByte */
+#define MPS_BS_B FLASH_SIZE_PRELIM /* 1 MByte */
/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
#define MPS_BU 3 /* R/W */
/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
#define MPS_BW 0 /* 8Bit */
/* CR register for Boot */
-#define MPS_CR_B ((FLASH_BASE0_PRELIM & 0xfff00000) + (MPS_BS << 17) + (MPS_BU << 15) + (MPS_BW << 13))
+#define MPS_CR_B ((FLASH_BASE_PRELIM & 0xfff00000) + (MPS_BS << 17) + (MPS_BU << 15) + (MPS_BW << 13))
/* CR register for non Boot */
#define MPS_CR ((MULTI_PURPOSE_SOCKET_ADDR & 0xfff00000) + (MPS_BS << 17) + (MPS_BU << 15) + (MPS_BW << 13))
#include <common.h>
#include <mpc8xx.h>
+/* environment.h defines the various CFG_ENV_... values in terms
+ * of whichever ones are given in the configuration file.
+ */
+#include <environment.h>
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
&flash_info[0]);
#endif
+#ifdef CFG_ENV_ADDR
+ flash_protect ( FLAG_PROTECT_SET,
+ CFG_ENV_ADDR,
+ CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
+#endif
+
+#ifdef CFG_ENV_ADDR_REDUND
+ flash_protect ( FLAG_PROTECT_SET,
+ CFG_ENV_ADDR_REDUND,
+ CFG_ENV_ADDR_REDUND + CFG_ENV_SIZE_REDUND - 1,
+ &flash_info[0]);
+#endif
+
return (size_b);
}
for( i = 0; i < info->sector_count; i++ )
info->start[i] = base + (i * sect_size);
}
+ else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD
+ && (info->flash_id & FLASH_TYPEMASK) == FLASH_AM800T) {
+
+ int sect_size; /* number of bytes/sector */
+
+ sect_size = 0x00010000 * (sizeof(FPW)/2);
+
+ /* set up sector start address table (top boot sector type) */
+ for (i = 0; i < info->sector_count - 3; i++)
+ info->start[i] = base + (i * sect_size);
+ i = info->sector_count - 1;
+ info->start[i--] = base + (info->size - 0x00004000) * (sizeof(FPW)/2);
+ info->start[i--] = base + (info->size - 0x00006000) * (sizeof(FPW)/2);
+ info->start[i--] = base + (info->size - 0x00008000) * (sizeof(FPW)/2);
+ }
}
/*-----------------------------------------------------------------------
}
switch (info->flash_id & FLASH_TYPEMASK) {
+ case FLASH_AM800T:
+ fmt = "29LV800B%s (8 Mbit, %s)\n";
+ break;
case FLASH_AM640U:
fmt = "29LV641D (64 Mbit, uniform sectors)\n";
break;
/* Check 16 bits or 32 bits of ID so work on 32 or 16 bit bus. */
if (info->flash_id != FLASH_UNKNOWN) switch (addr[1]) {
+ case (FPW)AMD_ID_LV800T:
+ info->flash_id += FLASH_AM800T;
+ info->sector_count = 19;
+ info->size = 0x00100000 * (sizeof(FPW)/2);
+ break; /* => 1 or 2 MiB */
+
case (FPW)AMD_ID_LV640U: /* 29LV640 and 29LV641 have same ID */
info->flash_id += FLASH_AM640U;
info->sector_count = 128;
break;
case FLASH_AM640U:
+ case FLASH_AM800T:
default:
/* no hardware protect that we support */
break;
case FLASH_28F320C3B:
case FLASH_28F640C3B:
case FLASH_AM640U:
+ case FLASH_AM800T:
break;
case FLASH_UNKNOWN:
default:
break;
case FLASH_AM640U:
+ case FLASH_AM800T:
default:
/* no hardware protect that we support */
info->protect[sector] = prot;
#include <common.h>
#include <config.h>
+#include <jffs2/jffs2.h>
#include <mpc8xx.h>
#include <net.h> /* for eth_init() */
#include <rtc.h>
return (size_sdram);
}
+
+#ifdef CFG_JFFS_CUSTOM_PART
+
+static struct part_info part;
+
+#define jffs2_block(i) \
+ ((struct jffs2_unknown_node*)(CFG_JFFS2_BASE + (i) * 65536))
+
+struct part_info* jffs2_part_info(int part_num)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ bd_t *bd = gd->bd;
+ char* s;
+ int i;
+ int bootnor = 0; /* assume booting from NAND flash */
+
+ if (part_num != 0)
+ return 0; /* only support one partition */
+
+ if (part.usr_priv == (void*)1)
+ return ∂ /* already have part info */
+
+ memset(&part, 0, sizeof(part));
+
+ if (nand_dev_desc[0].ChipID == NAND_ChipID_UNKNOWN)
+ bootnor = 1;
+ else if (bd->bi_flashsize < 0x800000)
+ bootnor = 0;
+ else for (i = 0; !bootnor && i < 4; ++i) {
+ /* boot from NOR if JFFS2 info in any of
+ * first 4 erase blocks
+ */
+
+ if (jffs2_block(i)->magic == JFFS2_MAGIC_BITMASK)
+ bootnor = 1;
+ }
+
+ if (bootnor) {
+ /* no NAND flash or boot in NOR, use NOR flash */
+ part.offset = (unsigned char *)CFG_JFFS2_BASE;
+ part.size = CFG_JFFS2_SIZE;
+ }
+ else {
+ char readcmd[60];
+
+ /* boot info in NAND flash, get and use copy in RAM */
+
+ /* override info from environment if present */
+ s = getenv("fsaddr");
+ part.offset = s ? (void *)simple_strtoul(s, NULL, 16)
+ : (void *)CFG_JFFS2_RAMBASE;
+ s = getenv("fssize");
+ part.size = s ? simple_strtoul(s, NULL, 16)
+ : CFG_JFFS2_RAMSIZE;
+
+ /* read from nand flash */
+ sprintf(readcmd, "nand read.jffs2 %x 0 %x",
+ (uint32_t)part.offset, part.size);
+ run_command(readcmd, 0);
+ }
+
+ part.erasesize = 0; /* unused */
+ part.usr_priv=(void*)1; /* ready */
+
+ return ∂
+}
+#endif /* ifdef CFG_JFFS_CUSTOM_PART */
memcpy(mh, buf, sizeof(struct NFTLMediaHeader));
/* Do some sanity checks on it */
- if (mh->UnitSizeFactor != 0xff) {
- puts ("Sorry, we don't support UnitSizeFactor "
+ if (mh->UnitSizeFactor == 0) {
+#ifdef NFTL_DEBUG
+ puts ("UnitSizeFactor 0x00 detected.\n"
+ "This violates the spec but we think we know what it means...\n");
+#endif
+ } else if (mh->UnitSizeFactor != 0xff) {
+ printf ("Sorry, we don't support UnitSizeFactor "
"of != 1 yet.\n");
return -1;
}
/* Ident all the chips present. */
DoC_ScanChips(this);
+ if ((!this->numchips) || (!this->chips))
+ return;
nftl = &this->nftl;
#include <fat.h>
-extern block_dev_desc_t *ide_get_dev (int dev);
+
+
+
+block_dev_desc_t *get_dev (char* ifname, int dev)
+{
+#if (CONFIG_COMMANDS & CFG_CMD_IDE)
+ if (strncmp(ifname,"ide",3)==0) {
+ extern block_dev_desc_t * ide_get_dev(int dev);
+ return(ide_get_dev(dev));
+ }
+#endif
+#if (CONFIG_COMMANDS & CFG_CMD_SCSI)
+ if (strncmp(ifname,"scsi",4)==0) {
+ extern block_dev_desc_t * scsi_get_dev(int dev);
+ return(scsi_get_dev(dev));
+ }
+#endif
+#if ((CONFIG_COMMANDS & CFG_CMD_USB) && defined(CONFIG_USB_STORAGE))
+ if (strncmp(ifname,"usb",3)==0) {
+ extern block_dev_desc_t * usb_stor_get_dev(int dev);
+ return(usb_stor_get_dev(dev));
+ }
+#endif
+#if defined(CONFIG_MMC)
+ if (strncmp(ifname,"mmc",3)==0) {
+ extern block_dev_desc_t * mmc_get_dev(int dev);
+ return(mmc_get_dev(dev));
+ }
+#endif
+ return NULL;
+}
+
int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
long size;
unsigned long offset;
unsigned long count;
+ block_dev_desc_t *dev_desc=NULL;
+ int dev=0;
+ int part=1;
+ char *ep;
- if (argc < 3) {
- printf ("usage:fatload <filename> <addr> [bytes]\n");
+ if (argc < 5) {
+ printf ("usage: fatload <interface> <dev[:part]> <addr> <filename> [bytes]\n");
return (0);
}
-
- offset = simple_strtoul (argv[2], NULL, 16);
- if (argc == 4)
- count = simple_strtoul (argv[3], NULL, 16);
+ dev = (int)simple_strtoul (argv[2], &ep, 16);
+ dev_desc=get_dev(argv[1],dev);
+ if (dev_desc==NULL) {
+ puts ("\n** Invalid boot device **\n");
+ return 1;
+ }
+ if (*ep) {
+ if (*ep != ':') {
+ puts ("\n** Invalid boot device, use `dev[:part]' **\n");
+ return 1;
+ }
+ part = (int)simple_strtoul(++ep, NULL, 16);
+ }
+ if (fat_register_device(dev_desc,part)!=0) {
+ printf ("\n** Unable to use %s %d:%d for fatload **\n",argv[1],dev,part);
+ return 1;
+ }
+ offset = simple_strtoul (argv[3], NULL, 16);
+ if (argc == 6)
+ count = simple_strtoul (argv[5], NULL, 16);
else
count = 0;
+ size = file_fat_read (argv[4], (unsigned char *) offset, count);
- size = file_fat_read (argv[1], (unsigned char *) offset, count);
-
- printf ("%ld bytes read\n", size);
+ if(size==-1)
+ printf("\n** Unable to read \"%s\" from %s %d:%d **\n",argv[4],argv[1],dev,part);
+ else
+ printf ("\n%ld bytes read\n", size);
return size;
}
+
+
+
U_BOOT_CMD(
- fatload, 4, 0, do_fat_fsload,
+ fatload, 6, 0, do_fat_fsload,
"fatload - load binary file from a dos filesystem\n",
- "[ off ] [ filename ]\n"
- " - load binary file from dos filesystem\n"
- " with offset 'off'\n"
+ "<interface> <dev[:part]> <addr> <filename> [bytes]\n"
+ " - load binary file 'filename' from 'dev' on 'interface'\n"
+ " to address 'addr' from dos filesystem\n"
);
int do_fat_ls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
char *filename = "/";
int ret;
+ int dev=0;
+ int part=1;
+ char *ep;
+ block_dev_desc_t *dev_desc=NULL;
- if (argc == 2)
- ret = file_fat_ls (argv[1]);
+ if (argc < 3) {
+ printf ("usage: fatls <interface> <dev[:part]> [directory]\n");
+ return (0);
+ }
+ dev = (int)simple_strtoul (argv[2], &ep, 16);
+ dev_desc=get_dev(argv[1],dev);
+ if (dev_desc==NULL) {
+ puts ("\n** Invalid boot device **\n");
+ return 1;
+ }
+ if (*ep) {
+ if (*ep != ':') {
+ puts ("\n** Invalid boot device, use `dev[:part]' **\n");
+ return 1;
+ }
+ part = (int)simple_strtoul(++ep, NULL, 16);
+ }
+ if (fat_register_device(dev_desc,part)!=0) {
+ printf ("\n** Unable to use %s %d:%d for fatls **\n",argv[1],dev,part);
+ return 1;
+ }
+ if (argc == 4)
+ ret = file_fat_ls (argv[3]);
else
ret = file_fat_ls (filename);
+ if(ret!=0)
+ printf("No Fat FS detected\n");
return (ret);
}
U_BOOT_CMD(
- fatls, 2, 1, do_fat_ls,
+ fatls, 4, 1, do_fat_ls,
"fatls - list files in a directory (default /)\n",
- "[ directory ]\n"
- " - list files in a directory\n"
+ "<interface> <dev[:part]> [directory]\n"
+ " - list files from 'dev' on 'interface' in a 'directory'\n"
);
int do_fat_fsinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
- int ret;
+ int dev=0;
+ int part=1;
+ char *ep;
+ block_dev_desc_t *dev_desc=NULL;
- ret = 0;
-
- printf ("FAT info: %d\n", file_fat_detectfs ());
-
- return (ret);
+ if (argc < 2) {
+ printf ("usage: fatinfo <interface> <dev[:part]>\n");
+ return (0);
+ }
+ dev = (int)simple_strtoul (argv[2], &ep, 16);
+ dev_desc=get_dev(argv[1],dev);
+ if (dev_desc==NULL) {
+ puts ("\n** Invalid boot device **\n");
+ return 1;
+ }
+ if (*ep) {
+ if (*ep != ':') {
+ puts ("\n** Invalid boot device, use `dev[:part]' **\n");
+ return 1;
+ }
+ part = (int)simple_strtoul(++ep, NULL, 16);
+ }
+ if (fat_register_device(dev_desc,part)!=0) {
+ printf ("\n** Unable to use %s %d:%d for fatinfo **\n",argv[1],dev,part);
+ return 1;
+ }
+ return (file_fat_detectfs ());
}
U_BOOT_CMD(
- fatinfo, 1, 1, do_fat_fsinfo,
+ fatinfo, 3, 1, do_fat_fsinfo,
"fatinfo - print information about filesystem\n",
- "\n"
- " - print information about filesystem\n"
+ "<interface> <dev[:part]>\n"
+ " - print information about filesystem from 'dev' on 'interface'\n"
);
#ifdef NOT_IMPLEMENTED_YET
}
if (jffs2_part_info(tmp_part)){
- printf("Partiton changed to %d\n",tmp_part);
+ printf("Partition changed to %d\n",tmp_part);
part_num=tmp_part;
return 0;
}
LIB = lib$(CPU).a
-START = start.S drivers/i2c/i2c2.o
+START = start.S
OBJS = traps.o cpu.o cpu_init.o interrupts.o speed.o \
- drivers/epic/epic1.o drivers/i2c/i2c1.o pci.o bedbug_603e.o
+ drivers/epic/epic1.o drivers/i2c/i2c.o pci.o bedbug_603e.o
all: .depend $(START) $(LIB)
$(LIB): $(OBJS)
- $(AR) crv $@ $(OBJS) drivers/i2c/i2c2.o
+ $(AR) crv $@ $(OBJS)
bedbug_603e.c:
ln -s ../mpc8260/bedbug_603e.c bedbug_603e.c
+++ /dev/null
-##########################################################################
-#
-# Copyright Motorola, Inc. 1997
-# ALL RIGHTS RESERVED
-#
-# You are hereby granted a copyright license to use, modify, and
-# distribute the SOFTWARE so long as this entire notice is retained
-# without alteration in any modified and/or redistributed versions,
-# and that such modified versions are clearly identified as such.
-# No licenses are granted by implication, estoppel or otherwise under
-# any patents or trademarks of Motorola, Inc.
-#
-# The SOFTWARE is provided on an "AS IS" basis and without warranty.
-# To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS
-# ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED
-# WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
-# PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
-# REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS
-# THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS.
-#
-# To the maximum extent permitted by applicable law, IN NO EVENT SHALL
-# MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
-# (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF
-# BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
-# INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR
-# INABILITY TO USE THE SOFTWARE.
-#
-############################################################################
-TARGET = libi2c.a
-
-#DEBUG = -g
-DEBUG = -DI2CDBG
-LST = -Hanno -S
-OPTIM =
-CC = /risc/tools/pkgs/metaware/bin/hcppc
-CFLAGS = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc
-CCobj = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM)
-PREP = $(CC) $(CFLAGS) -P
-
-# Assembler used to build the .s files (for the board version)
-
-ASOPT = -big_si -c
-ASDEBUG = -l -fm
-AS = /risc/tools/pkgs/metaware/bin/asppc
-
-# Linker to bring .o files together into an executable.
-
-LKOPT = -Bbase=0 -q -Qn -r
-LKCMD =
-LINK = /risc/tools/pkgs/metaware/bin/ldppc $(LKCMD) $(LKOPT)
-
-# DOS Utilities
-
-DEL = rm
-COPY = cp
-LIST = ls
-
-OBJECTS = i2c1.o i2c2.o
-
-all: $(TARGET)
-
-objects: $(OBJECTS)
-
-$(TARGET): $(OBJECTS)
- $(LINK) $(OBJECTS) -o $@
-
-clean:
- $(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS)
-
-.s.o:
- $(DEL) -f $*.i
- $(PREP) -Hasmcpp $<
- $(AS) $(ASOPT) $*.i
-# $(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst
-
-.c.o:
- $(CCobj) $<
-
-.c.s:
- $(CCobj) $(LST) $<
-
-i2c1.o: i2c_export.h i2c.h i2c1.c
-
-i2c2.o: i2c.h i2c2.s
+++ /dev/null
-##########################################################################
-#
-# makefile_pc for use with PC mksnt tools dink32/drivers/i2c
-#
-# Copyright Motorola, Inc. 1997
-# ALL RIGHTS RESERVED
-#
-# You are hereby granted a copyright license to use, modify, and
-# distribute the SOFTWARE so long as this entire notice is retained
-# without alteration in any modified and/or redistributed versions,
-# and that such modified versions are clearly identified as such.
-# No licenses are granted by implication, estoppel or otherwise under
-# any patents or trademarks of Motorola, Inc.
-#
-# The SOFTWARE is provided on an "AS IS" basis and without warranty.
-# To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS
-# ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED
-# WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
-# PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
-# REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS
-# THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS.
-#
-# To the maximum extent permitted by applicable law, IN NO EVENT SHALL
-# MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
-# (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF
-# BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
-# INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR
-# INABILITY TO USE THE SOFTWARE.
-#
-############################################################################
-TARGET = libi2c.a
-
-#DEBUG = -g
-DEBUG = -DI2CDBG
-LST = -Hanno -S
-OPTIM =
-CC = m:/old_tools/tools/hcppc/bin/hcppc
-CFLAGS = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc
-CCobj = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM)
-PREP = $(CC) $(CFLAGS) -P
-
-# Assembler used to build the .s files (for the board version)
-
-ASOPT = -big_si -c
-ASDEBUG = -l -fm
-AS = m:/old_tools/tools/hcppc/bin/asppc
-
-# Linker to bring .o files together into an executable.
-
-LKOPT = -Bbase=0 -q -Qn -r
-LKCMD =
-LINK = m:/old_tools/tools/hcppc/bin/ldppc $(LKCMD) $(LKOPT)
-
-# DOS Utilities
-
-DEL = rm
-COPY = cp
-LIST = ls
-
-OBJECTS = i2c1.o i2c2.o
-
-all: $(TARGET)
-
-objects: $(OBJECTS)
-
-$(TARGET): $(OBJECTS)
- $(LINK) $(OBJECTS) -o $@
-
-clean:
- $(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS)
-
-.s.o:
- $(DEL) -f $*.i
- $(PREP) -Hasmcpp $<
- $(AS) $(ASOPT) $*.i
-# $(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst
-
-.c.o:
- $(CCobj) $<
-
-.c.s:
- $(CCobj) $(LST) $<
-
-i2c1.o: i2c_export.h i2c.h i2c1.c
- $(CCobj) $<
-
-
-i2c2.o: i2c.h i2c2.s
- $(DEL) -f $*.i
- $(PREP) -Hasmcpp $<
- $(AS) $(ASOPT) $*.i
+++ /dev/null
-CONTENT:
-
- i2c.h
- i2c1.c
- i2c2.s
-
-WHAT ARE THESE FILES:
-
-These files contain MPC8240 (Kahlua) I2C
-driver routines. The driver routines are not
-written for any specific operating system.
-They serves the purpose of code sample, and
-jump-start for using the MPC8240 I2C unit.
-
-For the reason of correctness of C language
-syntax, these files are compiled by Metaware
-C compiler and assembler.
-
-ENDIAN NOTATION:
-
-The algorithm is designed for big-endian mode,
-software is responsible for byte swapping.
-
-USAGE:
-
-1. The host system that is running on MPC8240
- shall link the files listed here. The memory
- location of driver routines shall take into
- account of that driver routines need to run
- in supervisor mode and they process I2C
- interrupt.
-
-2. The host system is responsible for configuring
- the MPC8240 including Embedded Utilities Memory
- Block. All I2C driver functions require the
- content of Embedded Utilities Memory Block
- Base Address Register, EUMBBAR, as the first
- parameter.
-
-3. Before I2C unit of MPC8240 can be used,
- initialize I2C unit by calling I2C_Init
- with the corresponding parameters.
-
- Note that the I2CFDR register shall be written
- once during the initialization. If it is written
- in the midst of transers, or after I2C STOPs or
- REPEAT STATRs, depending on the data written,
- a long reset time may be encountered.
-
-4. After I2C unit has been successfully initialized,
- use the Application level API to send data or
- receive data upon the desired mode, Master or
- Slave.
-
-5. If the host system is also using the EPIC unit
- on MPC8240, the system can register the
- I2C_ISR with the EPIC including other
- desired resources.
-
- If the host system does not using the EPIC unit
- on MPC8240, I2C_Timer_Event function can
- be called for each desired time interval.
-
- In both cases, the host system is free to provide
- its own timer event handler and interrupt service
- routine.
-
-6. The I2C driver routines contains a set
- of utilities, Set and Get, for host system
- to query and modify the desired I2C registers.
-
-7. It is the host system's responsibility of
- queueing the I2C I/O request. The host
- system shall check the I2C_ISR return code
- for I2C I/O status. If I2C_ISR returns
- I2CBUFFEMPTY or I2CBUFFFULL, it means
- I2C unit has completed a I/O request
- stated by the Application API.
-
-8. If the host system has more than one master
- mode I2C unit I/O requests but doesn't want
- to be intervented by being addressed as slave,
- the host system can use the master mode
- Application API with stop_flag set to 0 in
- conjunction with is_cnt flag set to 1.
- The first API call sets both stop_flag and
- is_cnt to 0, indicating a START condition
- shall be generated but when the end of
- transaction is reached, do not generate a
- STOP condition. Once the host system is
- informed that the transaction has been
- completed, the next Application API call
- shall set is_cnt flag to 1, indicating a
- repeated START condition shall be generated.
- The last Application API call shall set
- stop_flag
- to 1.
-
-9. The I2C_Timer_Event function containes
- a user defined function pointer. It
- serves the purpose of providing the
- host system a way to use its own event
- handler instead of the I2C_ISR provided
- here.
--- /dev/null
+/*
+ * (C) Copyright 2003
+ * Gleb Natapov <gnatapov@mrv.com>
+ * Some bits are taken from linux driver writen by adrian@humboldt.co.uk
+ *
+ * Hardware I2C driver for MPC107 PCI bridge.
+ *
+ * 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>
+
+#undef I2CDBG
+
+#ifdef CONFIG_HARD_I2C
+#include <i2c.h>
+
+#define TIMEOUT (CFG_HZ/4)
+
+#define I2C_Addr ((unsigned *)(CFG_EUMB_ADDR + 0x3000))
+
+#define I2CADR &I2C_Addr[0]
+#define I2CFDR &I2C_Addr[1]
+#define I2CCCR &I2C_Addr[2]
+#define I2CCSR &I2C_Addr[3]
+#define I2CCDR &I2C_Addr[4]
+
+#define MPC107_CCR_MEN 0x80
+#define MPC107_CCR_MIEN 0x40
+#define MPC107_CCR_MSTA 0x20
+#define MPC107_CCR_MTX 0x10
+#define MPC107_CCR_TXAK 0x08
+#define MPC107_CCR_RSTA 0x04
+
+#define MPC107_CSR_MCF 0x80
+#define MPC107_CSR_MAAS 0x40
+#define MPC107_CSR_MBB 0x20
+#define MPC107_CSR_MAL 0x10
+#define MPC107_CSR_SRW 0x04
+#define MPC107_CSR_MIF 0x02
+#define MPC107_CSR_RXAK 0x01
+
+#define I2C_READ 1
+#define I2C_WRITE 0
+
+/* taken from linux include/asm-ppc/io.h */
+inline unsigned in_le32 (volatile unsigned *addr)
+{
+ unsigned ret;
+
+ __asm__ __volatile__ ("lwbrx %0,0,%1;\n"
+ "twi 0,%0,0;\n"
+ "isync":"=r" (ret): "r" (addr), "m" (*addr));
+ return ret;
+}
+
+inline void out_le32 (volatile unsigned *addr, int val)
+{
+ __asm__ __volatile__ ("stwbrx %1,0,%2; eieio":"=m" (*addr):"r" (val),
+ "r" (addr));
+}
+
+#define writel(val, addr) out_le32(addr, val)
+#define readl(addr) in_le32(addr)
+
+void i2c_init (int speed, int slaveadd)
+{
+ /* stop I2C controller */
+ writel (0x0, I2CCCR);
+ /* set clock */
+ writel (0x1020, I2CFDR);
+ /* write slave address */
+ writel (slaveadd, I2CADR);
+ /* clear status register */
+ writel (0x0, I2CCSR);
+ /* start I2C controller */
+ writel (MPC107_CCR_MEN, I2CCCR);
+
+ return;
+}
+
+static __inline__ int i2c_wait4bus (void)
+{
+ ulong timeval = get_timer (0);
+
+ while (readl (I2CCSR) & MPC107_CSR_MBB)
+ if (get_timer (timeval) > TIMEOUT)
+ return -1;
+
+ return 0;
+}
+
+static __inline__ int i2c_wait (int write)
+{
+ u32 csr;
+ ulong timeval = get_timer (0);
+
+ do {
+ csr = readl (I2CCSR);
+
+ if (!(csr & MPC107_CSR_MIF))
+ continue;
+
+ writel (0x0, I2CCSR);
+
+ if (csr & MPC107_CSR_MAL) {
+#ifdef I2CDBG
+ printf ("i2c_wait: MAL\n");
+#endif
+ return -1;
+ }
+
+ if (!(csr & MPC107_CSR_MCF)) {
+#ifdef I2CDBG
+ printf ("i2c_wait: unfinished\n");
+#endif
+ return -1;
+ }
+
+ if (write == I2C_WRITE && (csr & MPC107_CSR_RXAK)) {
+#ifdef I2CDBG
+ printf ("i2c_wait: No RXACK\n");
+#endif
+ return -1;
+ }
+
+ return 0;
+ } while (get_timer (timeval) < TIMEOUT);
+
+#ifdef I2CDBG
+ printf ("i2c_wait: timed out\n");
+#endif
+ return -1;
+}
+
+static __inline__ int i2c_write_addr (u8 dev, u8 dir, int rsta)
+{
+ writel (MPC107_CCR_MEN | MPC107_CCR_MSTA | MPC107_CCR_MTX |
+ (rsta ? MPC107_CCR_RSTA : 0), I2CCCR);
+
+ writel ((dev << 1) | dir, I2CCDR);
+
+ if (i2c_wait (I2C_WRITE) < 0)
+ return 0;
+
+ return 1;
+}
+
+static __inline__ int __i2c_write (u8 * data, int length)
+{
+ int i;
+
+ writel (MPC107_CCR_MEN | MPC107_CCR_MSTA | MPC107_CCR_MTX, I2CCCR);
+
+ for (i = 0; i < length; i++) {
+ writel (data[i], I2CCDR);
+
+ if (i2c_wait (I2C_WRITE) < 0)
+ break;
+ }
+
+ return i;
+}
+
+static __inline__ int __i2c_read (u8 * data, int length)
+{
+ int i;
+
+ writel (MPC107_CCR_MEN | MPC107_CCR_MSTA |
+ ((length == 1) ? MPC107_CCR_TXAK : 0), I2CCCR);
+
+ /* dummy read */
+ readl (I2CCDR);
+
+ for (i = 0; i < length; i++) {
+ if (i2c_wait (I2C_READ) < 0)
+ break;
+
+ /* Generate ack on last next to last byte */
+ if (i == length - 2)
+ writel (MPC107_CCR_MEN | MPC107_CCR_MSTA |
+ MPC107_CCR_TXAK, I2CCCR);
+
+ /* Generate stop on last byte */
+ if (i == length - 1)
+ writel (MPC107_CCR_MEN | MPC107_CCR_TXAK, I2CCCR);
+
+ data[i] = readl (I2CCDR);
+ }
+
+ return i;
+}
+
+int i2c_read (u8 dev, uint addr, int alen, u8 * data, int length)
+{
+ int i = 0;
+ u8 *a = (u8 *) & addr;
+
+ if (i2c_wait4bus () < 0)
+ goto exit;
+
+ if (i2c_write_addr (dev, I2C_WRITE, 0) == 0)
+ goto exit;
+
+ if (__i2c_write (&a[4 - alen], alen) != alen)
+ goto exit;
+
+ if (i2c_write_addr (dev, I2C_READ, 1) == 0)
+ goto exit;
+
+ i = __i2c_read (data, length);
+
+exit:
+ writel (MPC107_CCR_MEN, I2CCCR);
+
+ return !(i == length);
+}
+
+int i2c_write (u8 dev, uint addr, int alen, u8 * data, int length)
+{
+ int i = 0;
+ u8 *a = (u8 *) & addr;
+
+ if (i2c_wait4bus () < 0)
+ goto exit;
+
+ if (i2c_write_addr (dev, I2C_WRITE, 0) == 0)
+ goto exit;
+
+ if (__i2c_write (&a[4 - alen], alen) != alen)
+ goto exit;
+
+ i = __i2c_write (data, length);
+
+exit:
+ writel (MPC107_CCR_MEN, I2CCCR);
+
+ return !(i == length);
+}
+
+int i2c_probe (uchar chip)
+{
+ int tmp;
+
+ /*
+ * Try to read the first location of the chip. The underlying
+ * driver doesn't appear to support sending just the chip address
+ * and looking for an <ACK> back.
+ */
+ udelay (10000);
+ return i2c_read (chip, 0, 1, (char *) &tmp, 1);
+}
+
+uchar i2c_reg_read (uchar i2c_addr, uchar reg)
+{
+ char buf[1];
+
+ i2c_read (i2c_addr, reg, 1, buf, 1);
+
+ return (buf[0]);
+}
+
+void i2c_reg_write (uchar i2c_addr, uchar reg, uchar val)
+{
+ i2c_write (i2c_addr, reg, 1, &val, 1);
+}
+
+#endif /* CONFIG_HARD_I2C */
+++ /dev/null
-#ifndef I2C_H
-#define I2C_H
-
-/****************************************************
- *
- * Copyright Motrola 1999
- *
- ****************************************************/
-#define get_eumbbar() CFG_EUMB_ADDR
-
-#define I2CADR 0x00003000
-#define I2CFDR 0x00003004
-#define I2CCR 0x00003008
-#define I2CSR 0x0000300C
-#define I2CDR 0x00003010
-
-typedef enum _i2cstatus
-{
- I2CSUCCESS = 0x3000,
- I2CADDRESS,
- I2CERROR,
- I2CBUFFFULL,
- I2CBUFFEMPTY,
- I2CXMITERROR,
- I2CRCVERROR,
- I2CBUSBUSY,
- I2CALOSS,
- I2CNOEVENT,
-} I2CStatus;
-
-typedef enum i2c_control
-{
- MEN = 0x00000080,
- MIEN = 0x00000040,
- MSTA = 0x00000020,
- MTX = 0x00000010,
- TXAK = 0x00000008,
- RSTA = 0x00000004,
-} I2C_CONTROL;
-
-typedef enum i2c_status
-{
- MCF = 0x00000080,
- MAAS = 0x00000040,
- MBB = 0x00000020,
- MAL = 0x00000010,
- SRW = 0x00000004,
- MIF = 0x00000002,
- RXAK = 0x00000001,
-} I2C_STATUS;
-
-typedef struct _i2c_ctrl
-{
- unsigned int reserved0 : 24;
- unsigned int men : 1;
- unsigned int mien : 1;
- unsigned int msta : 1;
- unsigned int mtx : 1;
- unsigned int txak : 1;
- unsigned int rsta : 1;
- unsigned int reserved1 : 2;
-} I2C_CTRL;
-
-typedef struct _i2c_stat
-{
- unsigned int rsrv0 : 24;
- unsigned int mcf : 1;
- unsigned int maas : 1;
- unsigned int mbb : 1;
- unsigned int mal : 1;
- unsigned int rsrv1 : 1;
- unsigned int srw : 1;
- unsigned int mif : 1;
- unsigned int rxak : 1;
-} I2C_STAT;
-
-typedef enum _i2c_mode
-{
- RCV = 0,
- XMIT = 1,
-} I2C_MODE;
-
-/******************** App. API ********************
- * The application API is for user level application
- * to use the funcitonality provided by I2C driver
- *
- * Note: Its App.s responsibility to swap the data
- * byte. In our API, we just transfer whatever
- * we are given
- **************************************************/
-/**
- * Note:
- *
- * In all following functions,
- * the caller shall pass the configured embedded utility memory
- * block base, EUMBBAR.
- **/
-
-/* Send a buffer of data to the intended rcv_addr.
- * If stop_flag is set, after the whole buffer
- * is sent, generate a STOP signal provided that the
- * receiver doesn't signal the STOP in the middle.
- * I2C is the master performing transmitting. If
- * no STOP signal is generated at the end of current
- * transaction, the master can generate a START signal
- * to another slave addr.
- *
- * return I2CSUCCESS if no error.
- */
-static I2CStatus I2C_put( unsigned int eumbbar,
- unsigned char rcv_addr, /* receiver's address */
- unsigned char *buffer_ptr, /* pointer of data to be sent */
- unsigned int length, /* number of byte of in the buffer */
- unsigned int stop_flag, /* 1 - signal STOP when buffer is empty
- * 0 - no STOP signal when buffer is empty
- */
- unsigned int is_cnt ); /* 1 - this is a restart, don't check MBB
- * 0 - this is a new start, check MBB
- */
-
-/* Receive a buffer of data from the desired sender_addr
- * If stop_flag is set, when the buffer is full and the
- * sender does not signal STOP, generate a STOP signal.
- * I2C is the master performing receiving. If no STOP signal
- * is generated, the master can generate a START signal
- * to another slave addr.
- *
- * return I2CSUCCESS if no error.
- */
-static I2CStatus I2C_get( unsigned int eumbbar,
- unsigned char sender_addr, /* sender's address */
- unsigned char *buffer_ptr, /* pointer of receiving buffer */
- unsigned int length, /* length of the receiving buffer */
- unsigned int stop_flag, /* 1 - signal STOP when buffer is full
- * 0 - no STOP signal when buffer is full
- */
- unsigned int is_cnt ); /* 1 - this is a restart, don't check MBB
- * 0 - this is a new start, check MBB
- */
-
-#if 0 /* the I2C_write and I2C_read functions are not active */
-/* Send a buffer of data to the requiring master.
- * If stop_flag is set, after the whole buffer is sent,
- * generate a STOP signal provided that the requiring
- * receiver doesn't signal the STOP in the middle.
- * I2C is the slave performing transmitting.
- *
- * return I2CSUCCESS if no error.
- *
- * Note: due to the Kahlua design, slave transmitter
- * shall not signal STOP since there is no way
- * for master to detect it, causing I2C bus hung.
- *
- * For the above reason, the stop_flag is always
- * set, i.e., 1.
- *
- * programmer shall use the timer on Kahlua to
- * control the interval of data byte at the
- * master side.
- */
-static I2CStatus I2C_write( unsigned int eumbbar,
- unsigned char *buffer_ptr, /* pointer of data to be sent */
- unsigned int length, /* number of byte of in the buffer */
- unsigned int stop_flag ); /* 1 - signal STOP when buffer is empty
- * 0 - no STOP signal when buffer is empty
- */
-
- /* Receive a buffer of data from the sending master.
- * If stop_flag is set, when the buffer is full and the
- * sender does not signal STOP, generate a STOP signal.
- * I2C is the slave performing receiving.
- *
- * return I2CSUCCESS if no error.
- */
-static I2CStatus I2C_read(unsigned int eumbbar,
- unsigned char *buffer_ptr, /* pointer of receiving buffer */
- unsigned int length, /* length of the receiving buffer */
- unsigned int stop_flag ); /* 1 - signal STOP when buffer is full
- * 0 - no STOP signal when buffer is full
- */
-#endif /* of if0 for turning off I2C_read & I2C_write */
-
-/* if interrupt is not used, this is the timer event handler.
- * After each fixed time interval, this function can be called
- * to check the I2C status and call appropriate function to
- * handle the status event.
- */
-static I2CStatus I2C_Timer_Event( unsigned int eumbbar, I2CStatus (*handler)( unsigned int ) );
-
-/********************* Kernel API ************************
- * Kernel APIs are functions I2C driver provides to the
- * O.S.
- *********************************************************/
-
-/******************* device I/O function ***************/
-
-/* Generate a START signal in the desired mode.
- * I2C is the master.
- *
- * return I2CSUCCESS if no error.
- * I2CERROR if i2c unit is not enabled.
- * I2CBUSBUSY if bus cannot be granted
- */
-static I2CStatus I2C_Start( unsigned int eumbbar,
- unsigned char slave_addr, /* address of the receiver */
- I2C_MODE mode, /* XMIT(1) - put (write)
- * RCV(0) - get (read)
- */
- unsigned int is_cnt ); /* 1 - this is a restart, don't check MBB
- * 0 - this is a new start, check MBB
- */
-
-/* Generate a STOP signal to terminate the transaction. */
-static I2CStatus I2C_Stop( unsigned int eumbbar );
-
-/* Do a one-byte master transmit.
- *
- * return I2CBUFFEMPTY if this is the last byte.
- * Otherwise return I2CSUCCESS
- */
-static I2CStatus I2C_Master_Xmit( unsigned int eumbbar );
-
-/* Do a one-byte master receive.
- *
- * return I2CBUFFFULL if this is the last byte.
- * Otherwise return I2CSUCCESS
- */
-static I2CStatus I2C_Master_Rcv( unsigned int eumbbar );
-
-/* Do a one-byte slave transmit.
- *
- * return I2CBUFFEMPTY if this is the last byte.
- * Otherwise return I2CSUCCESS
- *
- */
-static I2CStatus I2C_Slave_Xmit( unsigned int eumbbar );
-
-/* Do a one-byte slave receive.
- *
- * return I2CBUFFFULL if this is the last byte.
- * Otherwise return I2CSUCCESS
- */
-static I2CStatus I2C_Slave_Rcv( unsigned int eumbbar );
-
-/* Process slave address phase.
- *
- * return I2CADDRESS if this is slave receiver's address phase
- * Otherwise return the result of slave xmit one byte.
- */
-static I2CStatus I2C_Slave_Addr( unsigned int eumbbar );
-
-/******************* Device Control Fucntion ****************/
-/* Initialize I2C unit with desired frequency divider,
- * driver's slave address w/o interrupt enabled.
- *
- * This function must be called before I2C unit can
- * be used.
- */
-static I2CStatus I2C_Init( unsigned int eumbbar,
- unsigned char fdr, /* frequency divider */
- unsigned char addr, /* driver's address used for receiving */
- unsigned int en_int); /* 1 - enable I2C interrupt
- * 0 - disable I2C interrup
- */
-
-/* I2C interrupt service routine.
- *
- * return I2CADDRESS if it is receiver's (either master or slave) address phase.
- * return the result of xmit or receive one byte
- */
-static I2CStatus I2C_ISR(unsigned int eumbbar );
-
-/* Set I2C Status, i.e., write to I2CSR */
-static void I2C_Set_Stat( unsigned int eumbbar, I2C_STAT stat );
-
-/* Query I2C Status, i.e., read I2CSR */
-static I2C_STAT I2C_Get_Stat( unsigned int eumbbar );
-
-/* Change I2C Control bits, i.e., write to I2CCR */
-static void I2C_Set_Ctrl( unsigned int eumbbar, I2C_CTRL ); /* new control value */
-
-/* Query I2C Control bits, i.e., read I2CCR */
-static I2C_CTRL I2C_Get_Ctrl( unsigned int eumbbar );
-
-/* This function performs the work for I2C_do_transaction. The work is
- * split into this function to enable I2C_do_transaction to first transmit
- * the data address to the I2C slave device without putting the data address
- * into the first byte of the buffer.
- *
- * en_int controls interrupt/polling mode
- * act is the type of transaction
- * i2c_addr is the I2C address of the slave device
- * len is the length of data to send or receive
- * buffer is the address of the data buffer
- * stop = I2C_NO_STOP, don't signal STOP at end of transaction
- * I2C_STOP, signal STOP at end of transaction
- * retry is the timeout retry value, currently ignored
- * rsta = I2C_NO_RESTART, this is not continuation of existing transaction
- * I2C_RESTART, this is a continuation of existing transaction
- */
-static I2C_Status I2C_do_buffer( I2C_INTERRUPT_MODE en_int,
- I2C_TRANSACTION_MODE act,
- unsigned char i2c_addr,
- int len,
- unsigned char *buffer,
- I2C_STOP_MODE stop,
- int retry,
- I2C_RESTART_MODE rsta);
-#endif
+++ /dev/null
-/*************************************************************
- *
- * Copyright @ Motorola, 1999
- *
- ************************************************************/
-#include <common.h>
-
-#ifdef CONFIG_HARD_I2C
-#include <i2c.h>
-#include "i2c_export.h"
-#include "i2c.h"
-
-#undef I2CDBG0
-#undef DEBUG
-
-/* Define a macro to use an optional application-layer print function, if
- * one was passed to the I2C library during initialization. If there was
- * no function pointer passed, this protects against calling it. Also define
- * the global variable that holds the passed pointer.
- */
-#define TIMEOUT (CFG_HZ/4)
-#define PRINT if ( app_print ) app_print
-static int (*app_print) (char *, ...);
-
-/******************* Internal to I2C Driver *****************/
-static unsigned int ByteToXmit = 0;
-static unsigned int XmitByte = 0;
-static unsigned char *XmitBuf = 0;
-static unsigned int XmitBufEmptyStop = 0;
-static unsigned int ByteToRcv = 0;
-static unsigned int RcvByte = 0;
-static unsigned char *RcvBuf = 0;
-static unsigned int RcvBufFulStop = 0;
-static unsigned int MasterRcvAddress = 0;
-
-/* Set by call to get_eumbbar during I2C_Initialize.
- * This could be globally available to the I2C library, but there is
- * an advantage to passing it as a parameter: it is already in a register
- * and doesn't have to be loaded from memory. Also, that is the way the
- * I2C library was already implemented and I don't want to change it without
- * a more detailed analysis.
- * It is being set as a global variable in I2C_Initialize to hide it from
- * the DINK application layer, because it is Kahlua-specific. I think that
- * get_eumbbar, load_runtime_reg, and store_runtime_reg should be defined in
- * a Kahlua-specific library dealing with the embedded utilities memory block.
- * Right now, get_eumbbar is defined in dink32/kahlua.s. The other two are
- * defined in dink32/drivers/i2c/i2c2.s.
- */
-static unsigned int Global_eumbbar = 0;
-
-extern unsigned int load_runtime_reg (unsigned int eumbbar,
- unsigned int reg);
-
-extern unsigned int store_runtime_reg (unsigned int eumbbar,
- unsigned int reg, unsigned int val);
-
-/************************** API *****************/
-
-/* Application Program Interface (API) are the calls provided by the I2C
- * library to upper layer applications (i.e., DINK) to access the Kahlua
- * I2C bus interface. The functions and values that are part of this API
- * are declared in i2c_export.h.
- */
-
-/* Initialize I2C unit with the following:
- * driver's slave address
- * interrupt enabled
- * optional pointer to application layer print function
- *
- * These parameters may be added:
- * desired clock rate
- * digital filter frequency sampling rate
- *
- * This function must be called before I2C unit can be used.
- */
-I2C_Status I2C_Initialize (unsigned char addr,
- I2C_INTERRUPT_MODE en_int,
- int (*p) (char *, ...))
-{
- I2CStatus status;
-
- /* establish the pointer, if there is one, to the application's "printf" */
- app_print = p;
-
- /* If this is the first call, get the embedded utilities memory block
- * base address. I'm not sure what to do about error handling here:
- * if a non-zero value is returned, accept it.
- */
- if (Global_eumbbar == 0)
- Global_eumbbar = get_eumbbar ();
- if (Global_eumbbar == 0) {
- PRINT ("I2C_Initialize: can't find EUMBBAR\n");
- return I2C_ERROR;
- }
-
- /* validate the I2C address */
- if (addr & 0x80) {
- PRINT ("I2C_Initialize, I2C address invalid: %d 0x%x\n",
- (unsigned int) addr, (unsigned int) addr);
- return I2C_ERROR;
- }
-
- /* Call the internal I2C library function to perform work.
- * Accept the default frequency sampling rate (no way to set it currently,
- * via I2C_Init) and set the clock frequency to something reasonable.
- */
- status = I2C_Init (Global_eumbbar, (unsigned char) 0x31, addr, en_int);
- if (status != I2CSUCCESS) {
- PRINT ("I2C_Initialize: error in initiation\n");
- return I2C_ERROR;
- }
-
- /* all is well */
- return I2C_SUCCESS;
-}
-
-
-/* Perform the given I2C transaction, only MASTER_XMIT and MASTER_RCV
- * are implemented. Both are only in polling mode.
- *
- * en_int controls interrupt/polling mode
- * act is the type of transaction
- * i2c_addr is the I2C address of the slave device
- * data_addr is the address of the data on the slave device
- * len is the length of data to send or receive
- * buffer is the address of the data buffer
- * stop = I2C_NO_STOP, don't signal STOP at end of transaction
- * I2C_STOP, signal STOP at end of transaction
- * retry is the timeout retry value, currently ignored
- * rsta = I2C_NO_RESTART, this is not continuation of existing transaction
- * I2C_RESTART, this is a continuation of existing transaction
- */
-I2C_Status I2C_do_transaction ( I2C_INTERRUPT_MODE en_int,
- I2C_TRANSACTION_MODE act,
- unsigned char i2c_addr,
- unsigned char data_addr,
- int len,
- char *buffer,
- I2C_STOP_MODE stop,
- int retry, I2C_RESTART_MODE rsta)
-{
- I2C_Status status;
- unsigned char data_addr_buffer[1];
-
-#if 1
-/* This is a temporary work-around. The I2C library breaks the protocol
- * if it attempts to handle a data transmission in more than one
- * transaction, so the data address and the actual data bytes are put
- * into a single buffer before sending it to the library internal functions.
- * The problem is related to being able to restart a transaction without
- * sending the I2C device address or repeating the data address. It may take
- * a day or two to sort it all out, so I'll have to get back to it later.
- * Look at I2C_Start to see about using some status flags (I'm not sure that
- * "stop" and "rsta" are enough to reflect the states, maybe so; but the logic
- * in the library is insufficient) to control correct handling of the protocol.
- */
- unsigned char dummy_buffer[257];
-
- if (act == I2C_MASTER_XMIT) {
- int i;
-
- if (len > 256)
- return I2C_ERROR;
- for (i = 1; i <= len; i++)
- dummy_buffer[i] = buffer[i - 1];
- dummy_buffer[0] = data_addr;
- status = I2C_do_buffer (en_int, act, i2c_addr, 1 + len,
- dummy_buffer, stop, retry, rsta);
- if (status != I2C_SUCCESS) {
- PRINT ("I2C_do_transaction: can't perform data transfer\n");
- return I2C_ERROR;
- }
- return I2C_SUCCESS;
- }
-#endif /* end of temp work-around */
-
- /* validate requested transaction type */
- if ((act != I2C_MASTER_XMIT) && (act != I2C_MASTER_RCV)) {
- PRINT ("I2C_do_transaction, invalid transaction request: %d\n",
- act);
- return I2C_ERROR;
- }
-
- /* range check the I2C address */
- if (i2c_addr & 0x80) {
- PRINT ("I2C_do_transaction, I2C address out of range: %d 0x%x\n",
- (unsigned int) i2c_addr, (unsigned int) i2c_addr);
- return I2C_ERROR;
- } else {
- data_addr_buffer[0] = data_addr;
- }
-
- /*
- * We first have to contact the slave device and transmit the
- * data address. Be careful about the STOP and restart stuff.
- * We don't want to signal STOP after sending the data
- * address, but this could be a continuation if the
- * application didn't release the bus after the previous
- * transaction, by not sending a STOP after it.
- */
- status = I2C_do_buffer (en_int, I2C_MASTER_XMIT, i2c_addr, 1,
- data_addr_buffer, I2C_NO_STOP, retry, rsta);
- if (status != I2C_SUCCESS) {
- PRINT ("I2C_do_transaction: can't send data address for read\n");
- return I2C_ERROR;
- }
-
- /* The data transfer will be a continuation. */
- rsta = I2C_RESTART;
-
- /* now handle the user data */
- status = I2C_do_buffer (en_int, act, i2c_addr, len,
- buffer, stop, retry, rsta);
- if (status != I2C_SUCCESS) {
- PRINT ("I2C_do_transaction: can't perform data transfer\n");
- return I2C_ERROR;
- }
-
- /* all is well */
- return I2C_SUCCESS;
-}
-
-/* This function performs the work for I2C_do_transaction. The work is
- * split into this function to enable I2C_do_transaction to first transmit
- * the data address to the I2C slave device without putting the data address
- * into the first byte of the buffer.
- *
- * en_int controls interrupt/polling mode
- * act is the type of transaction
- * i2c_addr is the I2C address of the slave device
- * len is the length of data to send or receive
- * buffer is the address of the data buffer
- * stop = I2C_NO_STOP, don't signal STOP at end of transaction
- * I2C_STOP, signal STOP at end of transaction
- * retry is the timeout retry value, currently ignored
- * rsta = I2C_NO_RESTART, this is not continuation of existing transaction
- * I2C_RESTART, this is a continuation of existing transaction
- */
-static I2C_Status I2C_do_buffer (I2C_INTERRUPT_MODE en_int,
- I2C_TRANSACTION_MODE act,
- unsigned char i2c_addr,
- int len,
- unsigned char *buffer,
- I2C_STOP_MODE stop,
- int retry, I2C_RESTART_MODE rsta)
-{
- I2CStatus rval;
- unsigned int dev_stat;
-
- if (act == I2C_MASTER_RCV) {
- /* set up for master-receive transaction */
- rval = I2C_get (Global_eumbbar, i2c_addr, buffer, len, stop, rsta);
- } else {
- /* set up for master-transmit transaction */
- rval = I2C_put (Global_eumbbar, i2c_addr, buffer, len, stop, rsta);
- }
-
- /* validate the setup */
- if (rval != I2CSUCCESS) {
- dev_stat = load_runtime_reg (Global_eumbbar, I2CSR);
- PRINT ("Error(I2C_do_buffer): control phase, code(0x%08x), status(0x%08x)\n", rval, dev_stat);
- I2C_Stop (Global_eumbbar);
- return I2C_ERROR;
- }
-
- if (en_int == 1) {
- /* this should not happen, no interrupt handling yet */
- return I2C_SUCCESS;
- }
-
- /* this performs the polling action, when the transfer is completed,
- * the status returned from I2C_Timer_Event will be I2CBUFFFULL or
- * I2CBUFFEMPTY (rcv or xmit), I2CSUCCESS or I2CADDRESS indicates the
- * transaction is not yet complete, anything else is an error.
- */
- while (rval == I2CSUCCESS || rval == I2CADDRESS) {
- int timeval = get_timer (0);
-
- /* poll the device until something happens */
- do {
- rval = I2C_Timer_Event (Global_eumbbar, 0);
- }
- while (rval == I2CNOEVENT && get_timer (timeval) < TIMEOUT);
-
- /* check for error condition */
- if (rval == I2CSUCCESS ||
- rval == I2CBUFFFULL ||
- rval == I2CBUFFEMPTY ||
- rval == I2CADDRESS) {
- ; /* do nothing */
- } else {
- /* report the error condition */
- dev_stat = load_runtime_reg (Global_eumbbar, I2CSR);
- PRINT ("Error(I2C_do_buffer): code(0x%08x), status(0x%08x)\n",
- rval, dev_stat);
- return I2C_ERROR;
- }
- }
-
- /* all is well */
- return I2C_SUCCESS;
-}
-
-/**
- * Note:
- *
- * In all following functions,
- * the caller shall pass the configured embedded utility memory
- * block base, EUMBBAR.
- **/
-
-/***********************************************************
- * function: I2C_put
- *
- * description:
- Send a buffer of data to the intended rcv_addr.
- * If stop_flag is set, after the whole buffer
- * is sent, generate a STOP signal provided that the
- * receiver doesn't signal the STOP in the middle.
- * I2C is the master performing transmitting. If
- * no STOP signal is generated at the end of current
- * transaction, the master can generate a START signal
- * to another slave addr.
- *
- * note: this is master xmit API
- *********************************************************/
-static I2CStatus I2C_put (unsigned int eumbbar, unsigned char rcv_addr, /* receiver's address */
- unsigned char *buffer_ptr, /* pointer of data to be sent */
- unsigned int length, /* number of byte of in the buffer */
- unsigned int stop_flag, /* 1 - signal STOP when buffer is empty
- * 0 - no STOP signal when buffer is empty
- */
- unsigned int is_cnt)
-{ /* 1 - this is a restart, don't check MBB
- * 0 - this is a new start, check MBB
- */
- if (buffer_ptr == 0 || length == 0) {
- return I2CERROR;
- }
-#ifdef I2CDBG0
- PRINT ("%s(%d): I2C_put\n", __FILE__, __LINE__);
-#endif
-
- XmitByte = 0;
- ByteToXmit = length;
- XmitBuf = buffer_ptr;
- XmitBufEmptyStop = stop_flag;
-
- RcvByte = 0;
- ByteToRcv = 0;
- RcvBuf = 0;
-
- /* we are the master, start transaction */
- return I2C_Start (eumbbar, rcv_addr, XMIT, is_cnt);
-}
-
-/***********************************************************
- * function: I2C_get
- *
- * description:
- * Receive a buffer of data from the desired sender_addr
- * If stop_flag is set, when the buffer is full and the
- * sender does not signal STOP, generate a STOP signal.
- * I2C is the master performing receiving. If no STOP signal
- * is generated, the master can generate a START signal
- * to another slave addr.
- *
- * note: this is master receive API
- **********************************************************/
-static I2CStatus I2C_get (unsigned int eumbbar, unsigned char rcv_from, /* sender's address */
- unsigned char *buffer_ptr, /* pointer of receiving buffer */
- unsigned int length, /* length of the receiving buffer */
- unsigned int stop_flag, /* 1 - signal STOP when buffer is full
- * 0 - no STOP signal when buffer is full
- */
- unsigned int is_cnt)
-{ /* 1 - this is a restart, don't check MBB
- * 0 - this is a new start, check MBB
- */
- if (buffer_ptr == 0 || length == 0) {
- return I2CERROR;
- }
-#ifdef I2CDBG0
- PRINT ("%s(%d): I2C_get\n", __FILE__, __LINE__);
-#endif
-
- RcvByte = 0;
- ByteToRcv = length;
- RcvBuf = buffer_ptr;
- RcvBufFulStop = stop_flag;
-
- XmitByte = 0;
- ByteToXmit = 0;
- XmitBuf = 0;
-
- /* we are the master, start the transaction */
- return I2C_Start (eumbbar, rcv_from, RCV, is_cnt);
-
-}
-
-#if 0 /* turn off dead code */
-/*********************************************************
- * function: I2C_write
- *
- * description:
- * Send a buffer of data to the requiring master.
- * If stop_flag is set, after the whole buffer is sent,
- * generate a STOP signal provided that the requiring
- * receiver doesn't signal the STOP in the middle.
- * I2C is the slave performing transmitting.
- *
- * Note: this is slave xmit API.
- *
- * due to the current Kahlua design, slave transmitter
- * shall not signal STOP since there is no way
- * for master to detect it, causing I2C bus hung.
- *
- * For the above reason, the stop_flag is always
- * set, i.e., 0.
- *
- * programmer shall use the timer on Kahlua to
- * control the interval of data byte at the
- * master side.
- *******************************************************/
-static I2CStatus I2C_write (unsigned int eumbbar, unsigned char *buffer_ptr, /* pointer of data to be sent */
- unsigned int length, /* number of byte of in the buffer */
- unsigned int stop_flag)
-{ /* 1 - signal STOP when buffer is empty
- * 0 - no STOP signal when buffer is empty
- */
- if (buffer_ptr == 0 || length == 0) {
- return I2CERROR;
- }
-
- XmitByte = 0;
- ByteToXmit = length;
- XmitBuf = buffer_ptr;
- XmitBufEmptyStop = 0; /* in order to avoid bus hung, ignored the user's stop_flag */
-
- RcvByte = 0;
- ByteToRcv = 0;
- RcvBuf = 0;
-
- /* we are the slave, just wait for being called, or pull */
- /* I2C_Timer_Event( eumbbar ); */
-}
-
-/******************************************************
- * function: I2C_read
- *
- * description:
- * Receive a buffer of data from the sending master.
- * If stop_flag is set, when the buffer is full and the
- * sender does not signal STOP, generate a STOP signal.
- * I2C is the slave performing receiving.
- *
- * note: this is slave receive API
- ****************************************************/
-static I2CStatus I2C_read (unsigned int eumbbar, unsigned char *buffer_ptr, /* pointer of receiving buffer */
- unsigned int length, /* length of the receiving buffer */
- unsigned int stop_flag)
-{ /* 1 - signal STOP when buffer is full
- * 0 - no STOP signal when buffer is full
- */
- if (buffer_ptr == 0 || length == 0) {
- return I2CERROR;
- }
-
- RcvByte = 0;
- ByteToRcv = length;
- RcvBuf = buffer_ptr;
- RcvBufFulStop = stop_flag;
-
- XmitByte = 0;
- ByteToXmit = 0;
- XmitBuf = 0;
-
- /* wait for master to call us, or poll */
- /* I2C_Timer_Event( eumbbar ); */
-}
-#endif /* turn off dead code */
-
-/*********************************************************
- * function: I2c_Timer_Event
- *
- * description:
- * if interrupt is not used, this is the timer event handler.
- * After each fixed time interval, this function can be called
- * to check the I2C status and call appropriate function to
- * handle the status event.
- ********************************************************/
-static I2CStatus I2C_Timer_Event (unsigned int eumbbar,
- I2CStatus (*handler) (unsigned int))
-{
- I2C_STAT stat;
-
-#ifdef I2CDBG0
- PRINT ("%s(%d): I2C_Timer_Event\n", __FILE__, __LINE__);
-#endif
-
- stat = I2C_Get_Stat (eumbbar);
-
- if (stat.mif == 1) {
- if (handler == 0) {
- return I2C_ISR (eumbbar);
- } else {
- return (*handler) (eumbbar);
- }
- }
-
- return I2CNOEVENT;
-}
-
-
-/****************** Device I/O function *****************/
-
-/******************************************************
- * function: I2C_Start
- *
- * description: Generate a START signal in the desired mode.
- * I2C is the master.
- *
- * Return I2CSUCCESS if no error.
- *
- * note:
- ****************************************************/
-static I2CStatus I2C_Start (unsigned int eumbbar, unsigned char slave_addr, /* address of the receiver */
- I2C_MODE mode, /* XMIT(1) - put (write)
- * RCV(0) - get (read)
- */
- unsigned int is_cnt)
-{ /* 1 - this is a restart, don't check MBB
- * 0 - this is a new start
- */
- unsigned int tmp = 0;
- I2C_STAT stat;
- I2C_CTRL ctrl;
-
-#ifdef I2CDBG0
- PRINT ("%s(%d): I2C_Start addr 0x%x mode %d cnt %d\n", __FILE__,
- __LINE__, slave_addr, mode, is_cnt);
-#endif
-
- ctrl = I2C_Get_Ctrl (eumbbar);
-
- /* first make sure I2C has been initialized */
- if (ctrl.men == 0) {
- return I2CERROR;
- }
-
- /* next make sure bus is idle */
- stat = I2C_Get_Stat (eumbbar);
-
- if (is_cnt == 0 && stat.mbb == 1) {
- /* sorry, we lost */
- return I2CBUSBUSY;
- } else if (is_cnt == 1 && stat.mif == 1 && stat.mal == 0) {
- /* sorry, we lost the bus */
- return I2CALOSS;
- }
-
-
- /* OK, I2C is enabled and we have the bus */
-
- /* prepare to write the slave address */
- ctrl.msta = 1;
- ctrl.mtx = 1;
- ctrl.txak = 0;
- ctrl.rsta = is_cnt; /* set the repeat start bit */
- I2C_Set_Ctrl (eumbbar, ctrl);
-
- /* write the slave address and xmit/rcv mode bit */
- tmp = load_runtime_reg (eumbbar, I2CDR);
- tmp = (tmp & 0xffffff00) |
- ((slave_addr & 0x007f) << 1) |
- (mode == XMIT ? 0x0 : 0x1);
- store_runtime_reg (eumbbar, I2CDR, tmp);
-
- if (mode == RCV) {
- MasterRcvAddress = 1;
- } else {
- MasterRcvAddress = 0;
- }
-
-#ifdef I2CDBG0
- PRINT ("%s(%d): I2C_Start exit\n", __FILE__, __LINE__);
-#endif
-
- /* wait for the interrupt or poll */
- return I2CSUCCESS;
-}
-
-/***********************************************************
- * function: I2c_Stop
- *
- * description: Generate a STOP signal to terminate the master
- * transaction.
- * return I2CSUCCESS
- *
- **********************************************************/
-static I2CStatus I2C_Stop (unsigned int eumbbar)
-{
- I2C_CTRL ctrl;
-
-#ifdef I2CDBG0
- PRINT ("%s(%d): I2C_Stop enter\n", __FILE__, __LINE__);
-#endif
-
- ctrl = I2C_Get_Ctrl (eumbbar);
- ctrl.msta = 0;
- I2C_Set_Ctrl (eumbbar, ctrl);
-
-#ifdef I2CDBG0
- PRINT ("%s(%d): I2C_Stop exit\n", __FILE__, __LINE__);
-#endif
-
- return I2CSUCCESS;
-}
-
-/****************************************************
- * function: I2C_Master_Xmit
- *
- * description: Master sends one byte of data to
- * slave target
- *
- * return I2CSUCCESS if the byte transmitted.
- * Otherwise no-zero
- *
- * Note: condition must meet when this function is called:
- * I2CSR(MIF) == 1 && I2CSR(MCF) == 1 && I2CSR(RXAK) == 0
- * I2CCR(MSTA) == 1 && I2CCR(MTX) == 1
- *
- ***************************************************/
-static I2CStatus I2C_Master_Xmit (unsigned int eumbbar)
-{
- unsigned int val;
-
- if (ByteToXmit > 0) {
-
- if (ByteToXmit == XmitByte) {
- /* all xmitted */
- ByteToXmit = 0;
-
- if (XmitBufEmptyStop == 1) {
- I2C_Stop (eumbbar);
- }
-
- return I2CBUFFEMPTY;
-
- }
-#ifdef I2CDBG0
- PRINT ("%s(%d): xmit 0x%02x\n", __FILE__, __LINE__,
- *(XmitBuf + XmitByte));
-#endif
-
- val = *(XmitBuf + XmitByte);
- val &= 0x000000ff;
- store_runtime_reg (eumbbar, I2CDR, val);
- XmitByte++;
-
- return I2CSUCCESS;
-
- }
-
- return I2CBUFFEMPTY;
-}
-
-/***********************************************
- * function: I2C_Master_Rcv
- *
- * description: master reads one byte data
- * from slave source
- *
- * return I2CSUCCESS if no error
- *
- * Note: condition must meet when this function is called:
- * I2CSR(MIF) == 1 && I2CSR(MCF) == 1 &&
- * I2CCR(MSTA) == 1 && I2CCR(MTX) == 0
- *
- ***********************************************/
-static I2CStatus I2C_Master_Rcv (unsigned int eumbbar)
-{
- I2C_CTRL ctrl;
- unsigned int val;
-
- if (ByteToRcv > 0) {
-
- if (ByteToRcv - RcvByte == 2 && RcvBufFulStop == 1) {
- /* master requests more than or equal to 2 bytes
- * we are reading 2nd to last byte
- */
-
- /* we need to set I2CCR(TXAK) to generate a STOP */
- ctrl = I2C_Get_Ctrl (eumbbar);
- ctrl.txak = 1;
- I2C_Set_Ctrl (eumbbar, ctrl);
-
- /* Kahlua will automatically generate a STOP
- * next time a transaction happens
- */
-
- /* note: the case of master requesting one byte is
- * handled in I2C_ISR
- */
- }
-
- /* generat a STOP before reading the last byte */
- if (RcvByte + 1 == ByteToRcv && RcvBufFulStop == 1) {
- I2C_Stop (eumbbar);
- }
-
- val = load_runtime_reg (eumbbar, I2CDR);
- *(RcvBuf + RcvByte) = val & 0xFF;
-
-#ifdef I2CDBG0
- PRINT ("%s(%d): rcv 0x%02x\n", __FILE__, __LINE__,
- *(RcvBuf + RcvByte));
-#endif
-
- RcvByte++;
-
- if (ByteToRcv == RcvByte) {
- ByteToRcv = 0;
-
- return I2CBUFFFULL;
- }
-
- return I2CSUCCESS;
- }
-
- return I2CBUFFFULL;
-
-}
-
-/****************************************************
- * function: I2C_Slave_Xmit
- *
- * description: Slave sends one byte of data to
- * requesting destination
- *
- * return SUCCESS if the byte transmitted. Otherwise
- * No-zero
- *
- * Note: condition must meet when this function is called:
- * I2CSR(MIF) == 1 && I2CSR(MCF) == 1 && I2CSR(RXAK) = 0
- * I2CCR(MSTA) == 0 && I2CCR(MTX) == 1
- *
- ***************************************************/
-static I2CStatus I2C_Slave_Xmit (unsigned int eumbbar)
-{
- unsigned int val;
-
- if (ByteToXmit > 0) {
-
- if (ByteToXmit == XmitByte) {
- /* no more data to send */
- ByteToXmit = 0;
-
- /*
- * do not toggle I2CCR(MTX). Doing so will
- * cause bus-hung since current Kahlua design
- * does not give master a way to detect slave
- * stop. It is always a good idea for master
- * to use timer to prevent the long long
- * delays
- */
-
- return I2CBUFFEMPTY;
- }
-#ifdef I2CDBG
- PRINT ("%s(%d): xmit 0x%02x\n", __FILE__, __LINE__,
- *(XmitBuf + XmitByte));
-#endif
-
- val = *(XmitBuf + XmitByte);
- val &= 0x000000ff;
- store_runtime_reg (eumbbar, I2CDR, val);
- XmitByte++;
-
- return I2CSUCCESS;
- }
-
- return I2CBUFFEMPTY;
-}
-
-/***********************************************
- * function: I2C_Slave_Rcv
- *
- * description: slave reads one byte data
- * from master source
- *
- * return I2CSUCCESS if no error otherwise non-zero
- *
- * Note: condition must meet when this function is called:
- * I2CSR(MIF) == 1 && I2CSR(MCF) == 1 &&
- * I2CCR(MSTA) == 0 && I2CCR(MTX) = 0
- *
- ***********************************************/
-static I2CStatus I2C_Slave_Rcv (unsigned int eumbbar)
-{
- unsigned int val;
- I2C_CTRL ctrl;
-
- if (ByteToRcv > 0) {
- val = load_runtime_reg (eumbbar, I2CDR);
- *(RcvBuf + RcvByte) = val & 0xff;
-#ifdef I2CDBG
- PRINT ("%s(%d): rcv 0x%02x\n", __FILE__, __LINE__,
- *(RcvBuf + RcvByte));
-#endif
- RcvByte++;
-
- if (ByteToRcv == RcvByte) {
- if (RcvBufFulStop == 1) {
- /* all done */
- ctrl = I2C_Get_Ctrl (eumbbar);
- ctrl.txak = 1;
- I2C_Set_Ctrl (eumbbar, ctrl);
- }
-
- ByteToRcv = 0;
- return I2CBUFFFULL;
- }
-
- return I2CSUCCESS;
- }
-
- return I2CBUFFFULL;
-}
-
-/****************** Device Control Function *************/
-
-/*********************************************************
- * function: I2C_Init
- *
- * description: Initialize I2C unit with desired frequency divider,
- * master's listening address, with interrupt enabled
- * or disabled.
- *
- * note:
- ********************************************************/
-static I2CStatus I2C_Init (unsigned int eumbbar, unsigned char fdr, /* frequency divider */
- unsigned char slave_addr, /* driver's address used for receiving */
- unsigned int en_int)
-{ /* 1 - enable I2C interrupt
- * 0 - disable I2C interrup
- */
- I2C_CTRL ctrl;
- unsigned int tmp;
-
-#ifdef I2CDBG0
- PRINT ("%s(%d): I2C_Init enter\n", __FILE__, __LINE__);
-#endif
-
- ctrl = I2C_Get_Ctrl (eumbbar);
- /* disable the I2C module before we change everything */
- ctrl.men = 0;
- I2C_Set_Ctrl (eumbbar, ctrl);
-
- /* set the frequency diver */
- tmp = load_runtime_reg (eumbbar, I2CFDR);
- tmp = (tmp & 0xffffffc0) | (fdr & 0x3f);
- store_runtime_reg (eumbbar, I2CFDR, tmp);
-
- /* Set our listening (slave) address */
- tmp = load_runtime_reg (eumbbar, I2CADR);
- tmp = (tmp & 0xffffff01) | ((slave_addr & 0x7f) << 1);
- store_runtime_reg (eumbbar, I2CADR, tmp);
-
- /* enable I2C with desired interrupt setting */
- ctrl.men = 1;
- ctrl.mien = en_int & 0x1;
- I2C_Set_Ctrl (eumbbar, ctrl);
-#ifdef I2CDBG0
- PRINT ("%s(%d): I2C_Init exit\n", __FILE__, __LINE__);
-#endif
-
- return I2CSUCCESS;
-
-}
-
-/*****************************************
- * function I2c_Get_Stat
- *
- * description: Query I2C Status, i.e., read I2CSR
- *
- ****************************************/
-static I2C_STAT I2C_Get_Stat (unsigned int eumbbar)
-{
- unsigned int temp;
- I2C_STAT stat;
-
- temp = load_runtime_reg (eumbbar, I2CSR);
-
-#ifdef I2CDBG0
- PRINT ("%s(%d): get stat = 0x%08x\n", __FILE__, __LINE__, temp);
-#endif
-
- stat.rsrv0 = (temp & 0xffffff00) >> 8;
- stat.mcf = (temp & 0x00000080) >> 7;
- stat.maas = (temp & 0x00000040) >> 6;
- stat.mbb = (temp & 0x00000020) >> 5;
- stat.mal = (temp & 0x00000010) >> 4;
- stat.rsrv1 = (temp & 0x00000008) >> 3;
- stat.srw = (temp & 0x00000004) >> 2;
- stat.mif = (temp & 0x00000002) >> 1;
- stat.rxak = (temp & 0x00000001);
- return stat;
-}
-
-/*********************************************
- * function: I2c_Set_Ctrl
- *
- * description: Change I2C Control bits,
- * i.e., write to I2CCR
- *
- ********************************************/
-static void I2C_Set_Ctrl (unsigned int eumbbar, I2C_CTRL ctrl)
-{ /* new control value */
- unsigned int temp = load_runtime_reg (eumbbar, I2CCR);
-
- temp &= 0xffffff03;
- temp |= ((ctrl.men & 0x1) << 7);
- temp |= ((ctrl.mien & 0x1) << 6);
- temp |= ((ctrl.msta & 0x1) << 5);
- temp |= ((ctrl.mtx & 0x1) << 4);
- temp |= ((ctrl.txak & 0x1) << 3);
- temp |= ((ctrl.rsta & 0x1) << 2);
-#ifdef I2CDBG0
- PRINT ("%s(%d): set ctrl = 0x%08x\n", __FILE__, __LINE__, temp);
-#endif
- store_runtime_reg (eumbbar, I2CCR, temp);
-
-}
-
-/*****************************************
- * function: I2C_Get_Ctrl
- *
- * description: Query I2C Control bits,
- * i.e., read I2CCR
- *****************************************/
-static I2C_CTRL I2C_Get_Ctrl (unsigned int eumbbar)
-{
- union {
- I2C_CTRL ctrl;
- unsigned int temp;
- } s;
-
- s.temp = load_runtime_reg (eumbbar, I2CCR);
-#ifdef I2CDBG0
- PRINT ("%s(%d): get ctrl = 0x%08x\n", __FILE__, __LINE__, s.temp);
-#endif
-
- return s.ctrl;
-}
-
-
-/****************************************
- * function: I2C_Slave_Addr
- *
- * description: Process slave address phase.
- * return I2CSUCCESS if no error
- *
- * note: Precondition for calling this function:
- * I2CSR(MIF) == 1 &&
- * I2CSR(MAAS) == 1
- ****************************************/
-static I2CStatus I2C_Slave_Addr (unsigned int eumbbar)
-{
- I2C_STAT stat = I2C_Get_Stat (eumbbar);
- I2C_CTRL ctrl = I2C_Get_Ctrl (eumbbar);
-
- if (stat.srw == 1) {
- /* we are asked to xmit */
- ctrl.mtx = 1;
- I2C_Set_Ctrl (eumbbar, ctrl); /* set MTX */
- return I2C_Slave_Xmit (eumbbar);
- }
-
- /* we are asked to receive data */
- ctrl.mtx = 0;
- I2C_Set_Ctrl (eumbbar, ctrl);
- (void) load_runtime_reg (eumbbar, I2CDR); /* do a fake read to start */
-
- return I2CADDRESS;
-}
-
-/***********************************************
- * function: I2C_ISR
- *
- * description: I2C Interrupt service routine
- *
- * note: Precondition:
- * I2CSR(MIF) == 1
- **********************************************/
-static I2CStatus I2C_ISR (unsigned int eumbbar)
-{
- I2C_STAT stat;
- I2C_CTRL ctrl;
-
-#ifdef I2CDBG0
- PRINT ("%s(%d): I2C_ISR\n", __FILE__, __LINE__);
-#endif
-
- stat = I2C_Get_Stat (eumbbar);
- ctrl = I2C_Get_Ctrl (eumbbar);
-
- /* clear MIF */
- stat.mif = 0;
-
- /* Now let see what kind of event this is */
- if (stat.mcf == 1) {
- /* transfer compete */
-
- /* clear the MIF bit */
- I2C_Set_Stat (eumbbar, stat);
-
- if (ctrl.msta == 1) {
- /* master */
- if (ctrl.mtx == 1) {
- /* check if this is the address phase for master receive */
- if (MasterRcvAddress == 1) {
- /* Yes, it is the address phase of master receive */
- ctrl.mtx = 0;
- /* now check how much we want to receive */
- if (ByteToRcv == 1 && RcvBufFulStop == 1) {
- ctrl.txak = 1;
- }
-
- I2C_Set_Ctrl (eumbbar, ctrl);
- (void) load_runtime_reg (eumbbar, I2CDR); /* fake read first */
-
- MasterRcvAddress = 0;
- return I2CADDRESS;
-
- }
-
- /* master xmit */
- if (stat.rxak == 0) {
- /* slave has acknowledged */
- return I2C_Master_Xmit (eumbbar);
- }
-
- /* slave has not acknowledged yet, generate a STOP */
- if (XmitBufEmptyStop == 1) {
- ctrl.msta = 0;
- I2C_Set_Ctrl (eumbbar, ctrl);
- }
-
- return I2CSUCCESS;
- }
-
- /* master receive */
- return I2C_Master_Rcv (eumbbar);
- }
-
- /* slave */
- if (ctrl.mtx == 1) {
- /* slave xmit */
- if (stat.rxak == 0) {
- /* master has acknowledged */
- return I2C_Slave_Xmit (eumbbar);
- }
-
- /* master has not acknowledged, wait for STOP */
- /* do nothing for preventing bus from hung */
- return I2CSUCCESS;
- }
-
- /* slave rcv */
- return I2C_Slave_Rcv (eumbbar);
-
- } else if (stat.maas == 1) {
- /* received a call from master */
-
- /* clear the MIF bit */
- I2C_Set_Stat (eumbbar, stat);
-
- /* master is calling us, process the address phase */
- return I2C_Slave_Addr (eumbbar);
- } else {
- /* has to be arbitration lost */
- stat.mal = 0;
- I2C_Set_Stat (eumbbar, stat);
-
- ctrl.msta = 0; /* return to receive mode */
- I2C_Set_Ctrl (eumbbar, ctrl);
- }
-
- return I2CSUCCESS;
-
-}
-
-/******************************************************
- * function: I2C_Set_Stat
- *
- * description: modify the I2CSR
- *
- *****************************************************/
-static void I2C_Set_Stat (unsigned int eumbbar, I2C_STAT stat)
-{
- union {
- unsigned int val;
- I2C_STAT stat;
- } s_tmp;
- union {
- unsigned int val;
- I2C_STAT stat;
- } s;
-
- s.val = load_runtime_reg (eumbbar, I2CSR);
- s.val &= 0xffffff08;
- s_tmp.stat = stat;
- s.val |= (s_tmp.val & 0xf7);
-
-#ifdef I2CDBG0
- PRINT ("%s(%d): set stat = 0x%08x\n", __FILE__, __LINE__, s.val);
-#endif
-
- store_runtime_reg (eumbbar, I2CSR, s.val);
-
-}
-
-/******************************************************
- * The following are routines to glue the rest of
- * U-Boot to the Sandpoint I2C driver.
- *****************************************************/
-
-void i2c_init (int speed, int slaveadd)
-{
-#ifdef CFG_I2C_INIT_BOARD
- /*
- * call board specific i2c bus reset routine before accessing the
- * environment, which might be in a chip on that bus. For details
- * about this problem see doc/I2C_Edge_Conditions.
- */
- i2c_init_board();
-#endif
-
-#ifdef DEBUG
- I2C_Initialize (0x7f, 0, (void *) printf);
-#else
- I2C_Initialize (0x7f, 0, 0);
-#endif
-}
-
-int i2c_probe (uchar chip)
-{
- int tmp;
-
- /*
- * Try to read the first location of the chip. The underlying
- * driver doesn't appear to support sending just the chip address
- * and looking for an <ACK> back.
- */
- udelay(10000);
- return i2c_read (chip, 0, 1, (char *)&tmp, 1);
-}
-
-int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len)
-{
- I2CStatus status;
- uchar xaddr[4];
-
- if (alen > 0) {
- xaddr[0] = (addr >> 24) & 0xFF;
- xaddr[1] = (addr >> 16) & 0xFF;
- xaddr[2] = (addr >> 8) & 0xFF;
- xaddr[3] = addr & 0xFF;
-
- status = I2C_do_buffer (0, I2C_MASTER_XMIT, chip, alen,
- &xaddr[4 - alen], I2C_NO_STOP, 1,
- I2C_NO_RESTART);
- if (status != I2C_SUCCESS) {
- PRINT ("i2c_read: can't send data address for read\n");
- return 1;
- }
- }
-
- /* The data transfer will be a continuation. */
- status = I2C_do_buffer (0, I2C_MASTER_RCV, chip, len,
- buffer, I2C_STOP, 1, (alen > 0 ? I2C_RESTART :
- I2C_NO_RESTART));
-
- if (status != I2C_SUCCESS) {
- PRINT ("i2c_read: can't perform data transfer\n");
- return 1;
- }
-
- return 0;
-}
-
-int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len)
-{
- I2CStatus status;
- uchar dummy_buffer[I2C_RXTX_LEN + 2];
- uchar *p;
- int i;
-
- /* fill in address in big endian order */
- for (i=alen-1; i>=0; --i) {
- buffer[i] = addr & 0xFF;
- addr >>= 8;
- }
- /* fill in data */
- p = dummy_buffer + alen;
-
- for (i=0; i<len; ++i)
- *p++ = *buffer++;
-
- status = I2C_do_buffer (0, I2C_MASTER_XMIT, chip, alen + len,
- dummy_buffer, I2C_STOP, 1, I2C_NO_RESTART);
-
-#ifdef CFG_EEPROM_PAGE_WRITE_DELAY_MS
- udelay(CFG_EEPROM_PAGE_WRITE_DELAY_MS * 1000);
-#endif
- if (status != I2C_SUCCESS) {
- PRINT ("i2c_write: can't perform data transfer\n");
- return 1;
- }
-
- return 0;
-}
-
-uchar i2c_reg_read (uchar i2c_addr, uchar reg)
-{
- char buf[1];
-
- i2c_init (0, 0);
-
- i2c_read (i2c_addr, reg, 1, buf, 1);
-
- return (buf[0]);
-}
-
-void i2c_reg_write (uchar i2c_addr, uchar reg, uchar val)
-{
- i2c_init (0, 0);
-
- i2c_write (i2c_addr, reg, 1, &val, 1);
-}
-
-#endif /* CONFIG_HARD_I2C */
+++ /dev/null
-/**************************************
- *
- * copyright @ Motorola, 1999
- *
- **************************************/
-
-#include <config.h>
-#ifdef CONFIG_HARD_I2C
-#include <ppc_asm.tmpl>
-#include <asm/mmu.h>
-/**********************************************************
- * function: load_runtime_reg
- *
- * input: r3 - value of eumbbar
- * r4 - register offset in embedded utility space
- *
- * output: r3 - register content
- **********************************************************/
- .text
- .align 2
- .global load_runtime_reg
-load_runtime_reg:
-
-/* xor r5,r5,r5
- * or r5,r5,r3
- *
- * lwbrx r3,r4,r5
- */
- lwbrx r3,r4,r3
- sync
-
- bclr 20, 0
-
-/****************************************************************
- * function: store_runtime_reg
- *
- * input: r3 - value of eumbbar
- * r4 - register offset in embedded utility space
- * r5 - new value to be stored
- *
- ****************************************************************/
- .text
- .align 2
- .global store_runtime_reg
-store_runtime_reg:
-
- stwbrx r5, r4, r3
- sync
-
- bclr 20,0
-
-#endif /* CONFIG_HARD_I2C */
+++ /dev/null
-#ifndef I2C_EXPORT_H
-#define I2C_EXPORT_H
-
-/****************************************************
- *
- * Copyright Motrola 1999
- *
- ****************************************************/
-
-/* These are the defined return values for the I2C_do_transaction function.
- * Any non-zero value indicates failure. Failure modes can be added for
- * more detailed error reporting.
- */
-typedef enum _i2c_status
-{
- I2C_SUCCESS = 0,
- I2C_ERROR,
-} I2C_Status;
-
-/* These are the defined tasks for I2C_do_transaction.
- * Modes for SLAVE_RCV and SLAVE_XMIT will be added.
- */
-typedef enum _i2c_transaction_mode
-{
- I2C_MASTER_RCV = 0,
- I2C_MASTER_XMIT = 1,
-} I2C_TRANSACTION_MODE;
-
-typedef enum _i2c_interrupt_mode
-{
- I2C_INT_DISABLE = 0,
- I2C_INT_ENABLE = 1,
-} I2C_INTERRUPT_MODE;
-
-typedef enum _i2c_stop
-{
- I2C_NO_STOP = 0,
- I2C_STOP = 1,
-} I2C_STOP_MODE;
-
-typedef enum _i2c_restart
-{
- I2C_NO_RESTART = 0,
- I2C_RESTART = 1,
-} I2C_RESTART_MODE;
-
-/******************** App. API ********************
- * The application API is for user level application
- * to use the functionality provided by I2C driver.
- * This is a "generic" I2C interface, it should contain
- * nothing specific to the Kahlua implementation.
- * Only the generic functions are exported by the library.
- *
- * Note: Its App.s responsibility to swap the data
- * byte. In our API, we just transfer whatever
- * we are given
- **************************************************/
-
-
-/* Initialize I2C unit with the following:
- * driver's slave address
- * interrupt enabled
- * optional pointer to application layer print function
- *
- * These parameters may be added:
- * desired clock rate
- * digital filter frequency sampling rate
- *
- * This function must be called before I2C unit can be used.
- */
-extern I2C_Status I2C_Initialize(
- unsigned char addr, /* driver's I2C slave address */
- I2C_INTERRUPT_MODE en_int, /* 1 - enable I2C interrupt
- * 0 - disable I2C interrupt
- */
- int (*app_print_function)(char *,...)); /* pointer to optional "printf"
- * provided by application
- */
-
-/* Perform the given I2C transaction, only MASTER_XMIT and MASTER_RCV
- * are implemented. Both are only in polling mode.
- *
- * en_int controls interrupt/polling mode
- * act is the type of transaction
- * addr is the I2C address of the slave device
- * len is the length of data to send or receive
- * buffer is the address of the data buffer
- * stop = I2C_NO_STOP, don't signal STOP at end of transaction
- * I2C_STOP, signal STOP at end of transaction
- * retry is the timeout retry value, currently ignored
- * rsta = I2C_NO_RESTART, this is not continuation of existing transaction
- * I2C_RESTART, this is a continuation of existing transaction
- */
-extern I2C_Status I2C_do_transaction( I2C_INTERRUPT_MODE en_int,
- I2C_TRANSACTION_MODE act,
- unsigned char i2c_addr,
- unsigned char data_addr,
- int len,
- char *buffer,
- I2C_STOP_MODE stop,
- int retry,
- I2C_RESTART_MODE rsta);
-#endif
stwu r0,-4(r7)
bdnz 3b
+4:
+#if !defined(CONFIG_BMW)
+/* Unlock the data cache and invalidate locked area */
+ xor r0, r0, r0
+ mtspr 1011, r0
+ lis r4, CFG_INIT_RAM_ADDR@h
+ ori r4, r4, CFG_INIT_RAM_ADDR@l
+ li r0, 128
+ mtctr r0
+41:
+ dcbi r0, r4
+ addi r4, r4, 32
+ bdnz 41b
+#endif
+
/*
* Now flush the cache: note that we must start from a cache aligned
* address. Otherwise we might miss one cache line.
*/
-4: cmpwi r6,0
+ cmpwi r6,0
add r5,r3,r5
beq 7f /* Always flush prefetch queue in any case */
subi r0,r6,1
#include <mmc.h>
#include <asm/errno.h>
#include <asm/arch/hardware.h>
+#include <part.h>
#ifdef CONFIG_MMC
extern int
-fat_register_read(int(*block_read)(int device, ulong blknr, ulong blkcnt, uchar *buffer));
+fat_register_device(block_dev_desc_t *dev_desc, int part_no);
+
+static block_dev_desc_t mmc_dev;
+
+block_dev_desc_t * mmc_get_dev(int dev)
+{
+ return ((block_dev_desc_t *)&mmc_dev);
+}
/*
* FIXME needs to read cid and csd info to determine block size
return 0;
}
-int
+ulong
/****************************************************/
-mmc_bread(int dev_num, ulong blknr, ulong blkcnt, uchar *dst)
+mmc_bread(int dev_num, ulong blknr, ulong blkcnt, ulong *dst)
/****************************************************/
{
int mmc_block_size = MMC_BLOCK_SIZE;
printf("Month = %d\n",cid->month);
printf("Year = %d\n",1997 + cid->year);
}
+ /* fill in device description */
+ mmc_dev.if_type = IF_TYPE_MMC;
+ mmc_dev.dev = 0;
+ mmc_dev.lun = 0;
+ mmc_dev.type = 0;
+ /* FIXME fill in the correct size (is set to 32MByte) */
+ mmc_dev.blksz = 512;
+ mmc_dev.lba = 0x10000;
+ sprintf(mmc_dev.vendor,"Man %02x%02x%02x Snr %02x%02x%02x",
+ cid->id[0], cid->id[1], cid->id[2],
+ cid->sn[0], cid->sn[1], cid->sn[2]);
+ sprintf(mmc_dev.product,"%s",cid->name);
+ sprintf(mmc_dev.revision,"%x %x",cid->hwrev, cid->fwrev);
+ mmc_dev.removable = 0;
+ mmc_dev.block_read = mmc_bread;
/* MMC exists, get CSD too */
resp = mmc_cmd(MMC_CMD_SET_RCA, MMC_DEFAULT_RCA, 0, MMC_CMDAT_R1);
MMC_CLKRT = 0; /* 20 MHz */
resp = mmc_cmd(7, MMC_DEFAULT_RCA, 0, MMC_CMDAT_R1);
- fat_register_read(mmc_bread);
+ fat_register_device(&mmc_dev,1); /* partitions start counting with 1 */
return rc;
}
(is_extended (p->sys_ind) ? " Extd" : ""));
}
+static int test_block_type(unsigned char *buffer)
+{
+ if((buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) ||
+ (buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) ) {
+ return (-1);
+ } /* no DOS Signature at all */
+ if(strncmp(&buffer[DOS_PBR_FSTYPE_OFFSET],"FAT",3)==0)
+ return DOS_PBR; /* is PBR */
+ return DOS_MBR; /* Is MBR */
+}
+
int test_part_dos (block_dev_desc_t *dev_desc)
{
dev_desc->dev, ext_part_sector);
return;
}
- if (buffer[DOS_PART_MAGIC_OFFSET] != 0x55 ||
- buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) {
+ i=test_block_type(buffer);
+ if(i==-1) {
printf ("bad MBR sector signature 0x%02x%02x\n",
buffer[DOS_PART_MAGIC_OFFSET],
buffer[DOS_PART_MAGIC_OFFSET + 1]);
return;
}
-
+ if(i==DOS_PBR) {
+ printf (" 1\t\t 0\t%10ld\t%2x\n",
+ dev_desc->lba, buffer[DOS_PBR_MEDIA_TYPE_OFFSET]);
+ return;
+ }
/* Print all primary/logical partitions */
pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
for (i = 0; i < 4; i++, pt++) {
#endif
#define DOS_PART_TBL_OFFSET 0x1be
#define DOS_PART_MAGIC_OFFSET 0x1fe
+#define DOS_PBR_FSTYPE_OFFSET 0x36
+#define DOS_PBR_MEDIA_TYPE_OFFSET 0x15
+#define DOS_MBR 0
+#define DOS_PBR 1
typedef struct dos_partition {
unsigned char boot_ind; /* 0x80 - active */
#include <config.h>
#include <fat.h>
#include <asm/byteorder.h>
+#include <part.h>
#if (CONFIG_COMMANDS & CFG_CMD_FAT)
}
}
-int (*dev_block_read)(int device, __u32 blknr, __u32 blkcnt, __u8 *buffer) = 0;
+static block_dev_desc_t *cur_dev = NULL;
+static unsigned long part_offset = 0;
+static int cur_part = 1;
+
+#define DOS_PART_TBL_OFFSET 0x1be
+#define DOS_PART_MAGIC_OFFSET 0x1fe
+#define DOS_FS_TYPE_OFFSET 0x36
int disk_read (__u32 startblock, __u32 getsize, __u8 * bufptr)
{
- /* FIXME we need to determine the start block of the
- * partition where the DOS FS resides
- */
- startblock += 32;
-
- if (dev_block_read) {
- return dev_block_read (0, startblock, getsize, bufptr);
+ startblock += part_offset;
+ if (cur_dev == NULL)
+ return -1;
+ if (cur_dev->block_read) {
+ return cur_dev->block_read (cur_dev->dev, startblock, getsize, (unsigned long *)bufptr);
}
return -1;
}
int
-fat_register_read (int (*block_read)(int, __u32, __u32, __u8 *))
+fat_register_device(block_dev_desc_t *dev_desc, int part_no)
{
- dev_block_read = block_read;
+ unsigned char buffer[SECTOR_SIZE];
+
+ if (!dev_desc->block_read)
+ return -1;
+ cur_dev=dev_desc;
+ /* check if we have a MBR (on floppies we have only a PBR) */
+ if (dev_desc->block_read (dev_desc->dev, 0, 1, (ulong *) buffer) != 1) {
+ printf ("** Can't read from device %d **\n", dev_desc->dev);
+ return -1;
+ }
+ if (buffer[DOS_PART_MAGIC_OFFSET] != 0x55 ||
+ buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) {
+ /* no signature found */
+ return -1;
+ }
+ if(!strncmp(&buffer[DOS_FS_TYPE_OFFSET],"FAT",3)) {
+ /* ok, we assume we are on a PBR only */
+ cur_part = 1;
+ part_offset=0;
+ }
+ else {
+#if (CONFIG_COMMANDS & CFG_CMD_IDE) || (CONFIG_COMMANDS & CFG_CMD_SCSI)
+ disk_partition_t info;
+ if(!get_partition_info(dev_desc, part_no, &info)) {
+ part_offset = info.start;
+ cur_part = part_no;
+ }
+ else {
+ printf ("** Partition %d not valid on device %d **\n",part_no,dev_desc->dev);
+ return -1;
+ }
+#else
+ /* FIXME we need to determine the start block of the
+ * partition where the DOS FS resides. This can be done
+ * by using the get_partition_info routine. For this
+ * purpose the libpart must be included.
+ */
+ part_offset=32;
+ cur_part = 1;
+#endif
+ }
return 0;
}
}
FAT_DPRINT("gc - clustnum: %d, startsect: %d\n", clustnum, startsect);
- while (size > 0) {
- if (size >= FS_BLOCK_SIZE) {
- if (disk_read(startsect + idx, 1, buffer) < 0) {
- FAT_DPRINT("Error reading data\n");
- return -1;
- }
- } else {
- __u8 tmpbuf[FS_BLOCK_SIZE];
- if (disk_read(startsect + idx, 1, tmpbuf) < 0) {
- FAT_DPRINT("Error reading data\n");
- return -1;
- }
- memcpy(buffer, tmpbuf, size);
-
- return 0;
+ if (disk_read(startsect, size/FS_BLOCK_SIZE , buffer) < 0) {
+ FAT_DPRINT("Error reading data\n");
+ return -1;
+ }
+ if(size % FS_BLOCK_SIZE) {
+ __u8 tmpbuf[FS_BLOCK_SIZE];
+ idx= size/FS_BLOCK_SIZE;
+ if (disk_read(startsect + idx, 1, tmpbuf) < 0) {
+ FAT_DPRINT("Error reading data\n");
+ return -1;
}
- buffer += FS_BLOCK_SIZE;
- size -= FS_BLOCK_SIZE;
- idx++;
+ buffer += idx*FS_BLOCK_SIZE;
+
+ memcpy(buffer, tmpbuf, size % FS_BLOCK_SIZE);
+ return 0;
}
return 0;
unsigned long filesize = FAT2CPU32(dentptr->size), gotsize = 0;
unsigned int bytesperclust = mydata->clust_size * SECTOR_SIZE;
__u32 curclust = START(dentptr);
+ __u32 endclust, newclust;
+ unsigned long actsize;
FAT_DPRINT("Filesize: %ld bytes\n", filesize);
FAT_DPRINT("Reading: %ld bytes\n", filesize);
+ actsize=bytesperclust;
+ endclust=curclust;
do {
- int getsize = (filesize > bytesperclust) ? bytesperclust :
- filesize;
-
- if (get_cluster(mydata, curclust, buffer, getsize) != 0) {
+ /* search for consecutive clusters */
+ while(actsize < filesize) {
+ newclust = get_fatent(mydata, endclust);
+ if((newclust -1)!=endclust)
+ goto getit;
+ if (newclust <= 0x0001 || newclust >= 0xfff0) {
+ FAT_DPRINT("curclust: 0x%x\n", newclust);
+ FAT_DPRINT("Invalid FAT entry\n");
+ return gotsize;
+ }
+ endclust=newclust;
+ actsize+= bytesperclust;
+ }
+ /* actsize >= file size */
+ actsize -= bytesperclust;
+ /* get remaining clusters */
+ if (get_cluster(mydata, curclust, buffer, (int)actsize) != 0) {
FAT_ERROR("Error reading cluster\n");
return -1;
}
- gotsize += getsize;
- filesize -= getsize;
- if (filesize <= 0) return gotsize;
- buffer += getsize;
-
- curclust = get_fatent(mydata, curclust);
+ /* get remaining bytes */
+ gotsize += (int)actsize;
+ filesize -= actsize;
+ buffer += actsize;
+ actsize= filesize;
+ if (get_cluster(mydata, endclust, buffer, (int)actsize) != 0) {
+ FAT_ERROR("Error reading cluster\n");
+ return -1;
+ }
+ gotsize+=actsize;
+ return gotsize;
+getit:
+ if (get_cluster(mydata, curclust, buffer, (int)actsize) != 0) {
+ FAT_ERROR("Error reading cluster\n");
+ return -1;
+ }
+ gotsize += (int)actsize;
+ filesize -= actsize;
+ buffer += actsize;
+ curclust = get_fatent(mydata, endclust);
if (curclust <= 0x0001 || curclust >= 0xfff0) {
FAT_DPRINT("curclust: 0x%x\n", curclust);
FAT_ERROR("Invalid FAT entry\n");
return gotsize;
}
+ actsize=bytesperclust;
+ endclust=curclust;
} while (1);
}
do_fat_read (const char *filename, void *buffer, unsigned long maxsize,
int dols)
{
- __u8 block[FS_BLOCK_SIZE]; /* Block buffer */
+ __u8 block[MAX_CLUSTSIZE]; /* Block buffer */
char fnamecopy[2048];
boot_sector bs;
volume_info volinfo;
while (1) {
int i;
- if (disk_read (cursect, 1, block) < 0) {
+ if (disk_read (cursect, mydata->clust_size, block) < 0) {
FAT_DPRINT ("Error: reading rootdir block\n");
return -1;
}
boot_sector bs;
volume_info volinfo;
int fatsize;
+ char vol_label[12];
- return read_bootsectandvi(&bs, &volinfo, &fatsize);
+ if(cur_dev==NULL) {
+ printf("No current device\n");
+ return 1;
+ }
+#if (CONFIG_COMMANDS & CFG_CMD_IDE) || (CONFIG_COMMANDS & CFG_CMD_SCSI)
+ printf("Interface: ");
+ switch(cur_dev->if_type) {
+ case IF_TYPE_IDE : printf("IDE"); break;
+ case IF_TYPE_SCSI : printf("SCSI"); break;
+ case IF_TYPE_ATAPI : printf("ATAPI"); break;
+ case IF_TYPE_USB : printf("USB"); break;
+ case IF_TYPE_DOC : printf("DOC"); break;
+ case IF_TYPE_MMC : printf("MMC"); break;
+ default : printf("Unknown");
+ }
+ printf("\n Device %d: ",cur_dev->dev);
+ dev_print(cur_dev);
+#endif
+ if(read_bootsectandvi(&bs, &volinfo, &fatsize)) {
+ printf("\nNo valid FAT fs found\n");
+ return 1;
+ }
+ memcpy (vol_label, volinfo.volume_label, 11);
+ vol_label[11] = '\0';
+ volinfo.fs_type[5]='\0';
+ printf("Partition %d: Filesystem: %s \"%s\"\n",cur_part,volinfo.fs_type,vol_label);
+ return 0;
}
long
file_fat_read(const char *filename, void *buffer, unsigned long maxsize)
{
+ printf("reading %s\n",filename);
return do_fat_read(filename, buffer, maxsize, LS_NO);
}
-/* vi: set sw=4 ts=4: */
/*
-------------------------------------------------------------------------
* Filename: jffs2.c
}
#ifdef CFG_JFFS2_SORT_FRAGMENTS
+/* Sort data entries with the latest version last, so that if there
+ * is overlapping data the latest version will be used.
+ */
static int compare_inodes(struct b_node *new, struct b_node *old)
{
struct jffs2_raw_inode *jNew = (struct jffs2_raw_inode *)new->offset;
struct jffs2_raw_inode *jOld = (struct jffs2_raw_inode *)old->offset;
- return jNew->version < jOld->version;
+ return jNew->version > jOld->version;
}
+/* Sort directory entries so all entries in the same directory
+ * with the same name are grouped together, with the latest version
+ * last. This makes it easy to eliminate all but the latest version
+ * by marking the previous version dead by setting the inode to 0.
+ */
static int compare_dirents(struct b_node *new, struct b_node *old)
{
struct jffs2_raw_dirent *jNew = (struct jffs2_raw_dirent *)new->offset;
struct jffs2_raw_dirent *jOld = (struct jffs2_raw_dirent *)old->offset;
-
- return jNew->version > jOld->version;
+ int cmp;
+
+ /* ascending sort by pino */
+ if (jNew->pino != jOld->pino)
+ return jNew->pino > jOld->pino;
+
+ /* pino is the same, so use ascending sort by nsize, so
+ * we don't do strncmp unless we really must.
+ */
+ if (jNew->nsize != jOld->nsize)
+ return jNew->nsize > jOld->nsize;
+
+ /* length is also the same, so use ascending sort by name
+ */
+ cmp = strncmp(jNew->name, jOld->name, jNew->nsize);
+ if (cmp != 0)
+ return cmp > 0;
+
+ /* we have duplicate names in this directory, so use ascending
+ * sort by version
+ */
+ if (jNew->version > jOld->version) {
+ /* since jNew is newer, we know jOld is not valid, so
+ * mark it with inode 0 and it will not be used
+ */
+ jOld->ino = 0;
+ return 1;
+ }
+
+ return 0;
}
#endif
struct b_node *b;
struct jffs2_raw_inode *jNode;
u32 totalSize = 0;
- u16 latestVersion = 0;
+ u32 latestVersion = 0;
char *lDest;
char *src;
long ret;
int i;
u32 counter = 0;
+#ifdef CFG_JFFS2_SORT_FRAGMENTS
+ /* Find file size before loading any data, so fragments that
+ * start past the end of file can be ignored. A fragment
+ * that is partially in the file is loaded, so extra data may
+ * be loaded up to the next 4K boundary above the file size.
+ * This shouldn't cause trouble when loading kernel images, so
+ * we will live with it.
+ */
+ for (b = pL->frag.listHead; b != NULL; b = b->next) {
+ jNode = (struct jffs2_raw_inode *) (b->offset);
+ if ((inode == jNode->ino)) {
+ /* get actual file length from the newest node */
+ if (jNode->version >= latestVersion) {
+ totalSize = jNode->isize;
+ latestVersion = jNode->version;
+ }
+ }
+ }
+#endif
for (b = pL->frag.listHead; b != NULL; b = b->next) {
jNode = (struct jffs2_raw_inode *) (b->offset);
putLabeledWord("read_inode: usercompr = ", jNode->usercompr);
putLabeledWord("read_inode: flags = ", jNode->flags);
#endif
+
+#ifndef CFG_JFFS2_SORT_FRAGMENTS
/* get actual file length from the newest node */
if (jNode->version >= latestVersion) {
totalSize = jNode->isize;
latestVersion = jNode->version;
}
+#endif
if(dest) {
src = ((char *) jNode) + sizeof(struct jffs2_raw_inode);
if ((pino == jDir->pino) && (len == jDir->nsize) &&
(jDir->ino) && /* 0 for unlink */
(!strncmp(jDir->name, name, len))) { /* a match */
- if (jDir->version < version) continue;
+ if (jDir->version < version)
+ continue;
- if(jDir->version == 0) {
- /* Is this legal? */
- putstr(" ** WARNING ** ");
- putnstr(jDir->name, jDir->nsize);
- putstr(" is version 0 (in find, ignoring)\r\n");
- } else if(jDir->version == version) {
- /* Im pretty sure this isn't ... */
+ if (jDir->version == version && inode != 0) {
+ /* I'm pretty sure this isn't legal */
putstr(" ** ERROR ** ");
putnstr(jDir->name, jDir->nsize);
putLabeledWord(" has dup version =", version);
for(b = pL->dir.listHead; b; b = b->next) {
jDir = (struct jffs2_raw_dirent *) (b->offset);
if (ino == jDir->ino) {
- if(jDir->version < version) continue;
+ if (jDir->version < version)
+ continue;
- if(jDir->version == 0) {
- /* Is this legal? */
- putstr(" ** WARNING ** ");
- putnstr(jDir->name, jDir->nsize);
- putstr(" is version 0 (in resolve, ignoring)\r\n");
- } else if(jDir->version == version) {
- /* Im pretty sure this isn't ... */
+ if (jDir->version == version && jDirFound) {
+ /* I'm pretty sure this isn't legal */
putstr(" ** ERROR ** ");
putnstr(jDir->name, jDir->nsize);
putLabeledWord(" has dup version (resolve) = ",
printf("OOPS Cleanmarker has bad size "
"%d != %d\n", node->totlen,
sizeof(struct jffs2_unknown_node));
+ } else if (node->nodetype == JFFS2_NODETYPE_PADDING) {
+ if (node->totlen < sizeof(struct jffs2_unknown_node))
+ printf("OOPS Padding has bad size "
+ "%d < %d\n", node->totlen,
+ sizeof(struct jffs2_unknown_node));
} else {
printf("Unknown node type: %x len %d "
"offset 0x%x\n", node->nodetype,
#define CONFIG_CLOCKS_IN_MHZ 1
/* Monitor Functions */
-#define CONFIG_COMMANDS ( CFG_CMD_FLASH | \
+#define CONFIG_COMMANDS ( CFG_CMD_ENV | \
+ CFG_CMD_FLASH | \
CFG_CMD_MEMORY| \
CFG_CMD_NET | \
- CFG_CMD_ENV | \
CFG_CMD_PING | \
CFG_CMD_SDRAM )
CFG_CMD_DATE | \
CFG_CMD_ELF | \
CFG_CMD_MII | \
+ CFG_CMD_FAT | \
CFG_CMD_PING | \
CFG_CMD_SAVES | \
CFG_CMD_BSP )
/*
* Init Memory Controller:
*/
-
-#define FLASH_BASE0_PRELIM 0xFFC00000 /* FLASH bank #0 */
-#define FLASH_BASE1_PRELIM 0 /* FLASH bank #1 */
+#define FLASH_MAX_SIZE 0x00800000 /* 8MByte max */
+#define FLASH_BASE_PRELIM 0xFF800000 /* open the flash CS */
+/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
+#define FLASH_SIZE_PRELIM 3 /* maximal flash FLASH size bank #0 */
#define CONFIG_BOARD_PRE_INIT
#undef CONFIG_IDE_LED /* no led for ide supported */
#define CONFIG_IDE_RESET /* reset for ide supported... */
#define CONFIG_IDE_RESET_ROUTINE /* with a special reset function */
-
+#define CONFIG_SUPPORT_VFAT
/************************************************************
* ATAPI support (experimental)
************************************************************/
CFG_CMD_PCI | \
CFG_CMD_CACHE | \
CFG_CMD_IRQ | \
+ CFG_CMD_ECHO | \
CFG_CMD_EEPROM | \
CFG_CMD_I2C | \
CFG_CMD_REGINFO | \
CFG_CMD_FDC | \
CFG_CMD_SCSI | \
+ CFG_CMD_FAT | \
CFG_CMD_DATE | \
CFG_CMD_ELF | \
CFG_CMD_USB | \
#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */
#define CFG_LOADS_BAUD_CHANGE 1 /* allow baudrate change */
-
+#define CONFIG_MISC_INIT_R
/***********************************************************
* Miscellaneous configurable options
**********************************************************/
/*
* Init Memory Controller:
*/
+#define FLASH_MAX_SIZE 0x00800000 /* 8MByte max */
+#define FLASH_BASE_PRELIM 0xFF800000 /* open the flash CS */
+/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
+#define FLASH_SIZE_PRELIM 3 /* maximal flash FLASH size bank #0 */
-#define FLASH_BASE0_PRELIM 0xFFC00000 /* FLASH bank #0 */
-#define FLASH_BASE1_PRELIM 0 /* FLASH bank #1 */
+#define CONFIG_BOARD_PRE_INIT
/* Configuration Port location */
#define CONFIG_PORT_ADDR 0xF4000000
#undef CONFIG_IDE_LED /* no led for ide supported */
#define CONFIG_IDE_RESET /* reset for ide supported... */
#define CONFIG_IDE_RESET_ROUTINE /* with a special reset function */
+#define CONFIG_SUPPORT_VFAT
/************************************************************
* ATAPI support (experimental)
#define CONFIG_COMMANDS (CONFIG_CMD_DFL | \
CFG_CMD_EEPROM | \
+ CFG_CMD_JFFS2 | \
CFG_CMD_NAND | \
CFG_CMD_DATE)
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
#include <cmd_confdefs.h>
+#define CFG_JFFS_CUSTOM_PART
+#define CFG_JFFS2_SORT_FRAGMENTS
+/* JFFS2 location when using NOR flash */
+#define CFG_JFFS2_BASE (CFG_FLASH_BASE + 0x80000)
+#define CFG_JFFS2_SIZE (0x780000)
+/* JFFS2 location (in RAM) when using NAND flash */
+#define CFG_JFFS2_RAMBASE 0x400000
+#define CFG_JFFS2_RAMSIZE 0x200000 /* NAND boot partition is 2MiB */
+
/* NAND flash support */
#define CONFIG_MTD_NAND_ECC_JFFS2
#define CFG_MAX_NAND_DEVICE 1 /* Max number of NAND devices */
#define CONFIG_RESET_ON_PANIC /* reset if system panic() */
-/* to put environment in EEROM */
-#define CFG_ENV_IS_IN_EEPROM 1
-#define CFG_ENV_OFFSET 0 /* Start right at beginning of NVRAM */
-#define CFG_ENV_SIZE 1024 /* Use only a part of it*/
-
-#if 1
-#define CONFIG_BOOT_RETRY_TIME 60 /* boot if no command in 60 seconds */
+#define CFG_ENV_IS_IN_FLASH
+#ifdef CFG_ENV_IS_IN_FLASH
+ /* environment is in FLASH */
+ #define CFG_ENV_ADDR 0xF8040000 /* AM29LV641 or AM29LV800BT */
+ #define CFG_ENV_ADDR_REDUND 0xF8050000 /* AM29LV641 or AM29LV800BT */
+ #define CFG_ENV_SECT_SIZE 0x00010000
+ #define CFG_ENV_SIZE 0x00002000
+#else
+ /* environment is in EEPROM */
+ #define CFG_ENV_IS_IN_EEPROM 1
+ #define CFG_ENV_OFFSET 0 /* at beginning of EEPROM */
+ #define CFG_ENV_SIZE 1024 /* Use only a part of it*/
#endif
#if 1
int file_fat_ls(const char *dir);
long file_fat_read(const char *filename, void *buffer, unsigned long maxsize);
const char *file_getfsname(int idx);
+int fat_register_device(block_dev_desc_t *dev_desc, int part_no);
#endif /* _FAT_H_ */
#define JFFS2_NODETYPE_DIRENT (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 1)
#define JFFS2_NODETYPE_INODE (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 2)
#define JFFS2_NODETYPE_CLEANMARKER (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3)
+#define JFFS2_NODETYPE_PADDING (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 4)
/* Maybe later... */
/*#define JFFS2_NODETYPE_CHECKPOINT (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3) */
#define IF_TYPE_ATAPI 3
#define IF_TYPE_USB 4
#define IF_TYPE_DOC 5
+#define IF_TYPE_MMC 6
/* Part types */
#define PART_TYPE_UNKNOWN 0x00
defined(CONFIG_MPC850) || \
defined(CONFIG_MPC855) || \
defined(CONFIG_MPC860) || \
- defined(CONFIG_MPC862) || \
- defined(CONFIG_MPC824X)
+ defined(CONFIG_MPC862)
#include <post.h>
#include <ppc_asm.tmpl>
mtlr r0
blr
-#endif /* CONFIG_MPC823 || MPC850 || MPC855 || MPC860 || MPC824X */
+#endif /* CONFIG_MPC823 || MPC850 || MPC855 || MPC860 */
#endif /* CONFIG_POST & CFG_POST_CACHE */
#endif /* CONFIG_POST */
#ifdef CONFIG_POST
#include <post.h>
-
+#if CONFIG_POST & CFG_POST_ETHER
#if defined(CONFIG_8xx)
#include <commproc.h>
#elif defined(CONFIG_MPC8260)
#include <command.h>
#include <net.h>
-#if CONFIG_POST & CFG_POST_ETHER
-
#define MIN_PACKET_LENGTH 64
#define MAX_PACKET_LENGTH 256
#define TEST_NUM 1
#ifdef CONFIG_POST
#include <post.h>
+#if CONFIG_POST & CFG_POST_UART
#if defined(CONFIG_8xx)
#include <commproc.h>
#elif defined(CONFIG_MPC8260)
#include <command.h>
#include <net.h>
-#if CONFIG_POST & CFG_POST_UART
-
#define CTLR_SMC 0
#define CTLR_SCC 1