Skip to content
Snippets Groups Projects
Commit 47cd00fa authored by Wolfgang Denk's avatar Wolfgang Denk
Browse files

* Patches by Robert Schwebel, 06 Mar 2003:

  - fix bug in BOOTP code (must use NetCopyIP)
  - update of CSB226 port
  - clear BSS segment on XScale
  - added support for i2c_init_board() function
  - update to the Innokom plattform

* Extend support for redundand environments for configurations where
  environment size < sector size
parent db2f721f
No related branches found
No related tags found
No related merge requests found
Showing
with 644 additions and 251 deletions
...@@ -2,6 +2,16 @@ ...@@ -2,6 +2,16 @@
Changes since U-Boot 0.2.2: Changes since U-Boot 0.2.2:
====================================================================== ======================================================================
* Patches by Robert Schwebel, 06 Mar 2003:
- fix bug in BOOTP code (must use NetCopyIP)
- update of CSB226 port
- clear BSS segment on XScale
- added support for i2c_init_board() function
- update to the Innokom plattform
* Extend support for redundand environments for configurations where
environment size < sector size
* Patch by Rune Torgersen, 13 Feb 2003: * Patch by Rune Torgersen, 13 Feb 2003:
Add support for Motorola MPC8266ADS board Add support for Motorola MPC8266ADS board
......
...@@ -897,6 +897,17 @@ The following options need to be configured: ...@@ -897,6 +897,17 @@ The following options need to be configured:
controls the rate of data transfer. The data rate thus controls the rate of data transfer. The data rate thus
is 1 / (I2C_DELAY * 4). is 1 / (I2C_DELAY * 4).
CFG_I2C_INIT_BOARD
When a board is reset during an i2c bus transfer
chips might think that the current transfer is still
in progress. On some boards it is possible to access
the i2c SCLK line directly, either by using the
processor pin as a GPIO or by having a second pin
connected to the bus. If this option is defined a
custom i2c_init_board() routine in boards/xxx/board.c
is run early in the boot sequence.
- SPI Support: CONFIG_SPI - SPI Support: CONFIG_SPI
Enables SPI driver (so far only tested with Enables SPI driver (so far only tested with
...@@ -1043,7 +1054,7 @@ The following options need to be configured: ...@@ -1043,7 +1054,7 @@ The following options need to be configured:
If CONFIG_ENV_OVERWRITE is #defined in your config If CONFIG_ENV_OVERWRITE is #defined in your config
file, the write protection for vendor parameters is file, the write protection for vendor parameters is
completely disabled. Anybody can change or delte completely disabled. Anybody can change or delete
these parameters. these parameters.
Alternatively, if you #define _both_ CONFIG_ETHADDR Alternatively, if you #define _both_ CONFIG_ETHADDR
......
...@@ -47,7 +47,9 @@ SECTIONS ...@@ -47,7 +47,9 @@ SECTIONS
armboot_end_data = .; armboot_end_data = .;
. = ALIGN(4); . = ALIGN(4);
bss_start = .;
.bss : { *(.bss) } .bss : { *(.bss) }
bss_end = .;
armboot_end = .; armboot_end = .;
} }
...@@ -32,10 +32,30 @@ ...@@ -32,10 +32,30 @@
# define SHOW_BOOT_PROGRESS(arg) # define SHOW_BOOT_PROGRESS(arg)
#endif #endif
/* /**
* Miscelaneous platform dependent initialisations * misc_init_r: - misc initialisation routines
*/ */
int misc_init_r(void)
{
uchar *str;
/* determine if the software update key is pressed during startup */
#if 0
/* not ported yet... */
if (GPLR0 & 0x00000800) {
printf("using bootcmd_normal (sw-update button not pressed)\n");
str = getenv("bootcmd_normal");
} else {
printf("using bootcmd_update (sw-update button pressed)\n");
str = getenv("bootcmd_update");
}
setenv("bootcmd",str);
#endif
return 0;
}
/** /**
* board_init: - setup some data structures * board_init: - setup some data structures
......
...@@ -45,44 +45,44 @@ flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; ...@@ -45,44 +45,44 @@ flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
ulong flash_init(void) ulong flash_init(void)
{ {
int i, j; int i, j;
ulong size = 0; ulong size = 0;
for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) { for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
ulong flashbase = 0; ulong flashbase = 0;
flash_info[i].flash_id = flash_info[i].flash_id =
(INTEL_MANUFACT & FLASH_VENDMASK) | (INTEL_MANUFACT & FLASH_VENDMASK) |
(INTEL_ID_28F128J3 & FLASH_TYPEMASK); (INTEL_ID_28F128J3 & FLASH_TYPEMASK);
flash_info[i].size = FLASH_BANK_SIZE; flash_info[i].size = FLASH_BANK_SIZE;
flash_info[i].sector_count = CFG_MAX_FLASH_SECT; flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
memset(flash_info[i].protect, 0, CFG_MAX_FLASH_SECT); memset(flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
switch (i) { switch (i) {
case 0: case 0:
flashbase = PHYS_FLASH_1; flashbase = PHYS_FLASH_1;
break; break;
default: default:
panic("configured to many flash banks!\n"); panic("configured to many flash banks!\n");
break; break;
} }
for (j = 0; j < flash_info[i].sector_count; j++) { for (j = 0; j < flash_info[i].sector_count; j++) {
flash_info[i].start[j] = flashbase + j*MAIN_SECT_SIZE; flash_info[i].start[j] = flashbase + j*MAIN_SECT_SIZE;
}
size += flash_info[i].size;
} }
size += flash_info[i].size;
}
/* Protect monitor and environment sectors */ /* Protect monitor and environment sectors */
flash_protect(FLAG_PROTECT_SET, flash_protect(FLAG_PROTECT_SET,
CFG_FLASH_BASE, CFG_FLASH_BASE,
CFG_FLASH_BASE + _armboot_end_data - _armboot_start, CFG_FLASH_BASE + _armboot_end_data - _armboot_start,
&flash_info[0]); &flash_info[0]);
flash_protect(FLAG_PROTECT_SET, flash_protect(FLAG_PROTECT_SET,
CFG_ENV_ADDR, CFG_ENV_ADDR,
CFG_ENV_ADDR + CFG_ENV_SIZE - 1, CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
&flash_info[0]); &flash_info[0]);
return size; return size;
} }
...@@ -94,43 +94,43 @@ ulong flash_init(void) ...@@ -94,43 +94,43 @@ ulong flash_init(void)
void flash_print_info (flash_info_t *info) void flash_print_info (flash_info_t *info)
{ {
int i, j; int i, j;
for (j=0; j<CFG_MAX_FLASH_BANKS; j++) { for (j=0; j<CFG_MAX_FLASH_BANKS; j++) {
switch (info->flash_id & FLASH_VENDMASK) { switch (info->flash_id & FLASH_VENDMASK) {
case (INTEL_MANUFACT & FLASH_VENDMASK): case (INTEL_MANUFACT & FLASH_VENDMASK):
printf("Intel: "); printf("Intel: ");
break; break;
default: default:
printf("Unknown Vendor "); printf("Unknown Vendor ");
break; break;
} }
switch (info->flash_id & FLASH_TYPEMASK) { switch (info->flash_id & FLASH_TYPEMASK) {
case (INTEL_ID_28F128J3 & FLASH_TYPEMASK): case (INTEL_ID_28F128J3 & FLASH_TYPEMASK):
printf("28F128J3 (128Mbit)\n"); printf("28F128J3 (128Mbit)\n");
break; break;
default: default:
printf("Unknown Chip Type\n"); printf("Unknown Chip Type\n");
return; return;
} }
printf(" Size: %ld MB in %d Sectors\n", printf(" Size: %ld MB in %d Sectors\n",
info->size >> 20, info->sector_count); info->size >> 20, info->sector_count);
printf(" Sector Start Addresses:"); printf(" Sector Start Addresses:");
for (i = 0; i < info->sector_count; i++) { for (i = 0; i < info->sector_count; i++) {
if ((i % 5) == 0) printf ("\n "); if ((i % 5) == 0) printf ("\n ");
printf (" %08lX%s", info->start[i], printf (" %08lX%s", info->start[i],
info->protect[i] ? " (RO)" : " "); info->protect[i] ? " (RO)" : " ");
} }
printf ("\n"); printf ("\n");
info++; info++;
} }
} }
...@@ -139,46 +139,47 @@ void flash_print_info (flash_info_t *info) ...@@ -139,46 +139,47 @@ void flash_print_info (flash_info_t *info)
* *
*/ */
int flash_erase (flash_info_t *info, int s_first, int s_last) int flash_erase(flash_info_t *info, int s_first, int s_last)
{ {
int flag, prot, sect; int flag, prot, sect;
int rc = ERR_OK; int rc = ERR_OK;
if (info->flash_id == FLASH_UNKNOWN) if (info->flash_id == FLASH_UNKNOWN)
return ERR_UNKNOWN_FLASH_TYPE; return ERR_UNKNOWN_FLASH_TYPE;
if ((s_first < 0) || (s_first > s_last)) { if ((s_first < 0) || (s_first > s_last)) {
return ERR_INVAL; return ERR_INVAL;
} }
if ((info->flash_id & FLASH_VENDMASK) != (INTEL_MANUFACT & FLASH_VENDMASK)) if ((info->flash_id & FLASH_VENDMASK) != (INTEL_MANUFACT & FLASH_VENDMASK))
return ERR_UNKNOWN_FLASH_VENDOR; return ERR_UNKNOWN_FLASH_VENDOR;
prot = 0; prot = 0;
for (sect=s_first; sect<=s_last; ++sect) { for (sect=s_first; sect<=s_last; ++sect) {
if (info->protect[sect]) prot++; if (info->protect[sect]) prot++;
} }
if (prot) return ERR_PROTECTED; if (prot) return ERR_PROTECTED;
/* /*
* Disable interrupts which might cause a timeout * Disable interrupts which might cause a timeout
* here. Remember that our exception vectors are * here. Remember that our exception vectors are
* at address 0 in the flash, and we don't want a * at address 0 in the flash, and we don't want a
* (ticker) exception to happen while the flash * (ticker) exception to happen while the flash
* chip is in programming mode. * chip is in programming mode.
*/ */
flag = disable_interrupts();
/* Start erase on unprotected sectors */ flag = disable_interrupts();
for (sect = s_first; sect<=s_last && !ctrlc(); sect++) {
printf("Erasing sector %2d ... ", sect); /* Start erase on unprotected sectors */
for (sect = s_first; sect<=s_last && !ctrlc(); sect++) {
/* arm simple, non interrupt dependent timer */ printf("Erasing sector %2d ... ", sect);
reset_timer_masked();
if (info->protect[sect] == 0) { /* not protected */ /* arm simple, non interrupt dependent timer */
reset_timer_masked();
if (info->protect[sect] == 0) { /* not protected */
u32 * volatile addr = (u32 * volatile)(info->start[sect]); u32 * volatile addr = (u32 * volatile)(info->start[sect]);
/* erase sector: */ /* erase sector: */
...@@ -190,32 +191,32 @@ int flash_erase (flash_info_t *info, int s_first, int s_last) ...@@ -190,32 +191,32 @@ int flash_erase (flash_info_t *info, int s_first, int s_last)
*addr = 0x00D000D0; /* erase confirm */ *addr = 0x00D000D0; /* erase confirm */
while ((*addr & 0x00800080) != 0x00800080) { while ((*addr & 0x00800080) != 0x00800080) {
if (get_timer_masked() > CFG_FLASH_ERASE_TOUT) { if (get_timer_masked() > CFG_FLASH_ERASE_TOUT) {
*addr = 0x00B000B0; /* suspend erase*/ *addr = 0x00B000B0; /* suspend erase*/
*addr = 0x00FF00FF; /* read mode */ *addr = 0x00FF00FF; /* read mode */
rc = ERR_TIMOUT; rc = ERR_TIMOUT;
goto outahere; goto outahere;
} }
} }
*addr = 0x00500050; /* clear status register cmd. */ *addr = 0x00500050; /* clear status register cmd. */
*addr = 0x00FF00FF; /* resest to read mode */ *addr = 0x00FF00FF; /* resest to read mode */
} }
printf("ok.\n"); printf("ok.\n");
} }
if (ctrlc()) printf("User Interrupt!\n"); if (ctrlc()) printf("User Interrupt!\n");
outahere: outahere:
/* allow flash to settle - wait 10 ms */ /* allow flash to settle - wait 10 ms */
udelay_masked(10000); udelay_masked(10000);
if (flag) enable_interrupts(); if (flag) enable_interrupts();
return rc; return rc;
} }
...@@ -230,71 +231,71 @@ outahere: ...@@ -230,71 +231,71 @@ outahere:
static int write_word (flash_info_t *info, ulong dest, ushort data) static int write_word (flash_info_t *info, ulong dest, ushort data)
{ {
ushort *addr = (ushort *)dest, val; u32 * volatile addr = (u32 * volatile)dest, val;
int rc = ERR_OK; int rc = ERR_OK;
int flag; int flag;
/* Check if Flash is (sufficiently) erased */ /* Check if Flash is (sufficiently) erased */
if ((*addr & data) != data) return ERR_NOT_ERASED; if ((*addr & data) != data) return ERR_NOT_ERASED;
/* /*
* Disable interrupts which might cause a timeout * Disable interrupts which might cause a timeout
* here. Remember that our exception vectors are * here. Remember that our exception vectors are
* at address 0 in the flash, and we don't want a * at address 0 in the flash, and we don't want a
* (ticker) exception to happen while the flash * (ticker) exception to happen while the flash
* chip is in programming mode. * chip is in programming mode.
*/ */
flag = disable_interrupts(); flag = disable_interrupts();
/* clear status register command */ /* clear status register command */
*addr = 0x50; *addr = 0x50;
/* program set-up command */ /* program set-up command */
*addr = 0x40; *addr = 0x40;
/* latch address/data */ /* latch address/data */
*addr = data; *addr = data;
/* arm simple, non interrupt dependent timer */ /* arm simple, non interrupt dependent timer */
reset_timer_masked(); reset_timer_masked();
/* wait while polling the status register */ /* wait while polling the status register */
while(((val = *addr) & 0x80) != 0x80) { while(((val = *addr) & 0x80) != 0x80) {
if (get_timer_masked() > CFG_FLASH_WRITE_TOUT) { if (get_timer_masked() > CFG_FLASH_WRITE_TOUT) {
rc = ERR_TIMOUT; rc = ERR_TIMOUT;
*addr = 0xB0; /* suspend program command */ *addr = 0xB0; /* suspend program command */
goto outahere; goto outahere;
}
} }
}
if(val & 0x1A) { /* check for error */
if(val & 0x1A) { /* check for error */ printf("\nFlash write error %02x at address %08lx\n",
printf("\nFlash write error %02x at address %08lx\n", (int)val, (unsigned long)dest);
(int)val, (unsigned long)dest); if(val & (1<<3)) {
if(val & (1<<3)) { printf("Voltage range error.\n");
printf("Voltage range error.\n"); rc = ERR_PROG_ERROR;
rc = ERR_PROG_ERROR; goto outahere;
goto outahere; }
} if(val & (1<<1)) {
if(val & (1<<1)) { printf("Device protect error.\n");
printf("Device protect error.\n"); rc = ERR_PROTECTED;
rc = ERR_PROTECTED; goto outahere;
goto outahere; }
} if(val & (1<<4)) {
if(val & (1<<4)) { printf("Programming error.\n");
printf("Programming error.\n"); rc = ERR_PROG_ERROR;
rc = ERR_PROG_ERROR; goto outahere;
goto outahere; }
} rc = ERR_PROG_ERROR;
rc = ERR_PROG_ERROR; goto outahere;
goto outahere; }
}
outahere:
outahere:
*addr = 0xFF; /* read array command */ *addr = 0xFF; /* read array command */
if (flag) enable_interrupts(); if (flag) enable_interrupts();
return rc; return rc;
} }
...@@ -311,63 +312,64 @@ outahere: ...@@ -311,63 +312,64 @@ outahere:
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
{ {
ulong cp, wp; ulong cp, wp;
ushort data; ushort data;
int l; int l;
int i, rc; int i, rc;
wp = (addr & ~1); /* get lower word aligned address */ wp = (addr & ~1); /* get lower word aligned address */
/*
* handle unaligned start bytes
*/
if ((l = addr - wp) != 0) {
data = 0;
for (i=0, cp=wp; i<l; ++i, ++cp) {
data = (data >> 8) | (*(uchar *)cp << 8);
}
for (; i<2 && cnt>0; ++i) {
data = (data >> 8) | (*src++ << 8);
--cnt;
++cp;
}
for (; cnt==0 && i<2; ++i, ++cp) {
data = (data >> 8) | (*(uchar *)cp << 8);
}
/* if ((rc = write_word(info, wp, data)) != 0) {
* handle unaligned start bytes return (rc);
*/ }
if ((l = addr - wp) != 0) { wp += 2;
data = 0;
for (i=0, cp=wp; i<l; ++i, ++cp) {
data = (data >> 8) | (*(uchar *)cp << 8);
}
for (; i<2 && cnt>0; ++i) {
data = (data >> 8) | (*src++ << 8);
--cnt;
++cp;
}
for (; cnt==0 && i<2; ++i, ++cp) {
data = (data >> 8) | (*(uchar *)cp << 8);
} }
if ((rc = write_word(info, wp, data)) != 0) { /*
return (rc); * handle word aligned part
} */
wp += 2; while (cnt >= 2) {
} /* data = *((vushort*)src); */
data = *((ushort*)src);
/* if ((rc = write_word(info, wp, data)) != 0) {
* handle word aligned part return (rc);
*/ }
while (cnt >= 2) { src += 2;
/* data = *((vushort*)src); */ wp += 2;
data = *((ushort*)src); cnt -= 2;
if ((rc = write_word(info, wp, data)) != 0) {
return (rc);
} }
src += 2;
wp += 2;
cnt -= 2;
}
if (cnt == 0) return ERR_OK; if (cnt == 0) return ERR_OK;
/* /*
* handle unaligned tail bytes * handle unaligned tail bytes
*/ */
data = 0; data = 0;
for (i=0, cp=wp; i<2 && cnt>0; ++i, ++cp) { for (i=0, cp=wp; i<2 && cnt>0; ++i, ++cp) {
data = (data >> 8) | (*src++ << 8); data = (data >> 8) | (*src++ << 8);
--cnt; --cnt;
} }
for (; i<2; ++i, ++cp) { for (; i<2; ++i, ++cp) {
data = (data >> 8) | (*(uchar *)cp << 8); data = (data >> 8) | (*(uchar *)cp << 8);
} }
return write_word(info, wp, data); return write_word(info, wp, data);
} }
...@@ -313,16 +313,22 @@ mem_init: ...@@ -313,16 +313,22 @@ mem_init:
/* documented in SDRAM data sheets. The address(es) used */ /* documented in SDRAM data sheets. The address(es) used */
/* for this purpose must not be cacheable. */ /* for this purpose must not be cacheable. */
ldr r3, =CFG_DRAM_BASE /* There should 9 writes, since the first write doesn't */
str r2, [r3] /* trigger a refresh cycle on PXA250. See Intel PXA250 and */
str r2, [r3] /* PXA210 Processors Specification Update, */
str r2, [r3] /* Jan 2003, Errata #116, page 30. */
str r2, [r3]
str r2, [r3]
str r2, [r3]
str r2, [r3]
str r2, [r3]
ldr r3, =CFG_DRAM_BASE
str r2, [r3]
str r2, [r3]
str r2, [r3]
str r2, [r3]
str r2, [r3]
str r2, [r3]
str r2, [r3]
str r2, [r3]
str r2, [r3]
/* Step 4g: Write MDCNFG with enable bits asserted */ /* Step 4g: Write MDCNFG with enable bits asserted */
/* (MDCNFG:DEx set to 1). */ /* (MDCNFG:DEx set to 1). */
...@@ -339,7 +345,6 @@ mem_init: ...@@ -339,7 +345,6 @@ mem_init:
/* We are finished with Intel's memory controller initialisation */ /* We are finished with Intel's memory controller initialisation */
/* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */
/* Disable (mask) all interrupts at interrupt controller */ /* Disable (mask) all interrupts at interrupt controller */
/* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */
...@@ -378,10 +383,11 @@ initclks: ...@@ -378,10 +383,11 @@ initclks:
str r2, [r1] str r2, [r1]
/* enable the 32Khz oscillator for RTC and PowerManager */ /* enable the 32Khz oscillator for RTC and PowerManager */
/*
ldr r1, =OSCC ldr r1, =OSCC
mov r2, #OSCC_OON mov r2, #OSCC_OON
str r2, [r1] str r2, [r1]
*/
/* NOTE: spin here until OSCC.OOK get set, meaning the PLL */ /* NOTE: spin here until OSCC.OOK get set, meaning the PLL */
/* has settled. */ /* has settled. */
60: 60:
...@@ -404,8 +410,7 @@ initclks: ...@@ -404,8 +410,7 @@ initclks:
/* FIXME */ /* FIXME */
#define NODEBUG #ifndef DEBUG
#ifdef NODEBUG
/*Disable software and data breakpoints */ /*Disable software and data breakpoints */
mov r0,#0 mov r0,#0
mcr p15,0,r0,c14,c8,0 /* ibcr0 */ mcr p15,0,r0,c14,c8,0 /* ibcr0 */
...@@ -415,7 +420,6 @@ initclks: ...@@ -415,7 +420,6 @@ initclks:
/*Enable all debug functionality */ /*Enable all debug functionality */
mov r0,#0x80000000 mov r0,#0x80000000
mcr p14,0,r0,c10,c0,0 /* dcsr */ mcr p14,0,r0,c10,c0,0 /* dcsr */
#endif #endif
/* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */
......
...@@ -47,7 +47,9 @@ SECTIONS ...@@ -47,7 +47,9 @@ SECTIONS
armboot_end_data = .; armboot_end_data = .;
. = ALIGN(4); . = ALIGN(4);
bss_start = .;
.bss : { *(.bss) } .bss : { *(.bss) }
bss_end = .;
armboot_end = .; armboot_end = .;
} }
...@@ -31,12 +31,228 @@ ...@@ -31,12 +31,228 @@
#include <common.h> #include <common.h>
#include <asm/arch/pxa-regs.h> #include <asm/arch/pxa-regs.h>
#define FLASH_BANK_SIZE 0x02000000 #if defined CFG_JFFS_CUSTOM_PART
#define MAIN_SECT_SIZE 0x40000 /* 2x16 = 256k per sector */ #include <jffs2/jffs2.h>
#endif
/* Debugging macros ------------------------------------------------------ */
#undef FLASH_DEBUG
//#define FLASH_DEBUG 1
/* Some debug macros */
#if (FLASH_DEBUG > 2 )
#define PRINTK3(args...) printf(args)
#else
#define PRINTK3(args...)
#endif
#if FLASH_DEBUG > 1
#define PRINTK2(args...) printf(args)
#else
#define PRINTK2(args...)
#endif
#ifdef FLASH_DEBUG
#define PRINTK(args...) printf(args)
#else
#define PRINTK(args...)
#endif
/* ------------------------------------------------------------------------ */
/* Development system: we have only 16 MB Flash */
#ifdef CONFIG_MTD_INNOKOM_16MB
#define FLASH_BANK_SIZE 0x01000000 /* 16 MB (during development) */
#define MAIN_SECT_SIZE 0x00020000 /* 128k per sector */
#endif
/* Production system: we have 64 MB Flash */
#ifdef CONFIG_MTD_INNOKOM_64MB
#define FLASH_BANK_SIZE 0x04000000 /* 64 MB */
#define MAIN_SECT_SIZE 0x00020000 /* 128k per sector */
#endif
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
#if defined CFG_JFFS_CUSTOM_PART
/**
* jffs2_part_info - get information about a JFFS2 partition
*
* @part_num: number of the partition you want to get info about
* @return: struct part_info* in case of success, 0 if failure
*/
static struct part_info part;
#ifdef CONFIG_MTD_INNOKOM_16MB
#ifdef CONFIG_MTD_INNOKOM_64MB
#error Please define only one CONFIG_MTD_INNOKOM_XXMB option.
#endif
struct part_info* jffs2_part_info(int part_num) {
PRINTK2("jffs2_part_info: part_num=%i\n",part_num);
/* u-boot partition */
if(part_num==0){
if(part.usr_priv==(void*)1) return &part;
memset(&part, 0, sizeof(part));
part.offset=(char*)0x00000000;
part.size=256*1024;
/* Mark the struct as ready */
part.usr_priv=(void*)1;
PRINTK("part.offset = 0x%08x\n",(unsigned int)part.offset);
PRINTK("part.size = 0x%08x\n",(unsigned int)part.size);
return &part;
}
/* primary OS+firmware partition */
if(part_num==1){
if(part.usr_priv==(void*)1) return &part;
memset(&part, 0, sizeof(part));
part.offset=(char*)0x00040000;
part.size=768*1024;
/* Mark the struct as ready */
part.usr_priv=(void*)1;
PRINTK("part.offset = 0x%08x\n",(unsigned int)part.offset);
PRINTK("part.size = 0x%08x\n",(unsigned int)part.size);
return &part;
}
/* secondary OS+firmware partition */
if(part_num==2){
if(part.usr_priv==(void*)1) return &part;
memset(&part, 0, sizeof(part));
part.offset=(char*)0x00100000;
part.size=8*1024*1024;
/* Mark the struct as ready */
part.usr_priv=(void*)1;
PRINTK("part.offset = 0x%08x\n",(unsigned int)part.offset);
PRINTK("part.size = 0x%08x\n",(unsigned int)part.size);
return &part;
}
/* data partition */
if(part_num==3){
if(part.usr_priv==(void*)1) return &part;
memset(&part, 0, sizeof(part));
part.offset=(char*)0x00900000;
part.size=7*1024*1024;
/* Mark the struct as ready */
part.usr_priv=(void*)1;
PRINTK("part.offset = 0x%08x\n",(unsigned int)part.offset);
PRINTK("part.size = 0x%08x\n",(unsigned int)part.size);
return &part;
}
PRINTK("jffs2_part_info: end of partition table\n");
return 0;
}
#endif /* CONFIG_MTD_INNOKOM_16MB */
#ifdef CONFIG_MTD_INNOKOM_64MB
#ifdef CONFIG_MTD_INNOKOM_16MB
#error Please define only one CONFIG_MTD_INNOKOM_XXMB option.
#endif
struct part_info* jffs2_part_info(int part_num) {
PRINTK2("jffs2_part_info: part_num=%i\n",part_num);
/* u-boot partition */
if(part_num==0){
if(part.usr_priv==(void*)1) return &part;
memset(&part, 0, sizeof(part));
part.offset=(char*)0x00000000;
part.size=256*1024;
/* Mark the struct as ready */
part.usr_priv=(void*)1;
PRINTK("part.offset = 0x%08x\n",(unsigned int)part.offset);
PRINTK("part.size = 0x%08x\n",(unsigned int)part.size);
return &part;
}
/* primary OS+firmware partition */
if(part_num==1){
if(part.usr_priv==(void*)1) return &part;
memset(&part, 0, sizeof(part));
part.offset=(char*)0x00040000;
part.size=16*1024*1024-128*1024;
/* Mark the struct as ready */
part.usr_priv=(void*)1;
PRINTK("part.offset = 0x%08x\n",(unsigned int)part.offset);
PRINTK("part.size = 0x%08x\n",(unsigned int)part.size);
return &part;
}
/* secondary OS+firmware partition */
if(part_num==2){
if(part.usr_priv==(void*)1) return &part;
memset(&part, 0, sizeof(part));
part.offset=(char*)0x01020000;
part.size=16*1024*1024-128*1024;
/* Mark the struct as ready */
part.usr_priv=(void*)1;
PRINTK("part.offset = 0x%08x\n",(unsigned int)part.offset);
PRINTK("part.size = 0x%08x\n",(unsigned int)part.size);
return &part;
}
/* data partition */
if(part_num==3){
if(part.usr_priv==(void*)1) return &part;
memset(&part, 0, sizeof(part));
part.offset=(char*)0x02000000;
part.size=32*1024*1024;
/* Mark the struct as ready */
part.usr_priv=(void*)1;
PRINTK("part.offset = 0x%08x\n",(unsigned int)part.offset);
PRINTK("part.size = 0x%08x\n",(unsigned int)part.size);
return &part;
}
PRINTK("jffs2_part_info: end of partition table\n");
return 0;
}
#endif /* CONFIG_MTD_INNOKOM_64MB */
#endif /* defined CFG_JFFS_CUSTOM_PART */
/** /**
* flash_init: - initialize data structures for flash chips * flash_init: - initialize data structures for flash chips
* *
...@@ -71,10 +287,10 @@ ulong flash_init(void) ...@@ -71,10 +287,10 @@ ulong flash_init(void)
size += flash_info[i].size; size += flash_info[i].size;
} }
/* Protect monitor and environment sectors */ /* Protect u-boot sectors */
flash_protect(FLAG_PROTECT_SET, flash_protect(FLAG_PROTECT_SET,
CFG_FLASH_BASE, CFG_FLASH_BASE,
CFG_FLASH_BASE + _armboot_end_data - _armboot_start, CFG_FLASH_BASE + (256*1024) - 1,
&flash_info[0]); &flash_info[0]);
#ifdef CFG_ENV_IS_IN_FLASH #ifdef CFG_ENV_IS_IN_FLASH
...@@ -178,32 +394,38 @@ int flash_erase(flash_info_t *info, int s_first, int s_last) ...@@ -178,32 +394,38 @@ int flash_erase(flash_info_t *info, int s_first, int s_last)
printf("Erasing sector %2d ... ", sect); printf("Erasing sector %2d ... ", sect);
PRINTK("\n");
/* arm simple, non interrupt dependent timer */ /* arm simple, non interrupt dependent timer */
reset_timer_masked(); reset_timer_masked();
if (info->protect[sect] == 0) { /* not protected */ if (info->protect[sect] == 0) { /* not protected */
u32 * volatile addr = (u32 * volatile)(info->start[sect]); u16 * volatile addr = (u16 * volatile)(info->start[sect]);
/* erase sector: */ PRINTK("unlocking sector\n");
/* The strata flashs are aligned side by side on */ *addr = 0x0060;
/* the data bus, so we have to write the commands */ *addr = 0x00d0;
/* to both chips here: */ *addr = 0x00ff;
*addr = 0x00200020; /* erase setup */ PRINTK("erasing sector\n");
*addr = 0x00D000D0; /* erase confirm */ *addr = 0x0020;
PRINTK("confirming erase\n");
*addr = 0x00D0;
while ((*addr & 0x00800080) != 0x00800080) { while ((*addr & 0x0080) != 0x0080) {
PRINTK(".");
if (get_timer_masked() > CFG_FLASH_ERASE_TOUT) { if (get_timer_masked() > CFG_FLASH_ERASE_TOUT) {
*addr = 0x00B000B0; /* suspend erase*/ *addr = 0x00B0; /* suspend erase*/
*addr = 0x00FF00FF; /* read mode */ *addr = 0x00FF; /* read mode */
rc = ERR_TIMOUT; rc = ERR_TIMOUT;
goto outahere; goto outahere;
} }
} }
*addr = 0x00500050; /* clear status register cmd. */ PRINTK("clearing status register\n");
*addr = 0x00FF00FF; /* resest to read mode */ *addr = 0x0050;
PRINTK("resetting to read mode");
*addr = 0x00FF;
} }
printf("ok.\n"); printf("ok.\n");
...@@ -233,7 +455,7 @@ int flash_erase(flash_info_t *info, int s_first, int s_last) ...@@ -233,7 +455,7 @@ int flash_erase(flash_info_t *info, int s_first, int s_last)
static int write_word (flash_info_t *info, ulong dest, ushort data) static int write_word (flash_info_t *info, ulong dest, ushort data)
{ {
ushort *addr = (ushort *)dest, val; volatile u16 *addr = (u16 *)dest, val;
int rc = ERR_OK; int rc = ERR_OK;
int flag; int flag;
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <common.h> #include <common.h>
#include <asm/arch/pxa-regs.h> #include <asm/arch/pxa-regs.h>
#include <asm/mach-types.h>
#ifdef CONFIG_SHOW_BOOT_PROGRESS #ifdef CONFIG_SHOW_BOOT_PROGRESS
# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg) # define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg)
...@@ -32,10 +33,53 @@ ...@@ -32,10 +33,53 @@
# define SHOW_BOOT_PROGRESS(arg) # define SHOW_BOOT_PROGRESS(arg)
#endif #endif
/* /**
* Miscelaneous platform dependent initialisations * i2c_init_board - reset i2c bus. When the board is powercycled during a
* bus transfer it might hang; for details see doc/I2C_Edge_Conditions.
* The Innokom board has GPIO70 connected to SCLK which can be toggled
* until all chips think that their current cycles are finished.
*/
int i2c_init_board(void)
{
int i;
/* set gpio pin to output */
GPDR(70) |= GPIO_bit(70);
for (i = 0; i < 11; i++) {
GPCR(70) = GPIO_bit(70);
udelay(10);
GPSR(70) = GPIO_bit(70);
udelay(10);
}
/* set gpio pin to input */
GPDR(70) &= ~GPIO_bit(70);
return 0;
}
/**
* misc_init_r: - misc initialisation routines
*/ */
int misc_init_r(void)
{
uchar *str;
/* determine if the software update key is pressed during startup */
if (GPLR0 & 0x00000800) {
printf("using bootcmd_normal (sw-update button not pressed)\n");
str = getenv("bootcmd_normal");
} else {
printf("using bootcmd_update (sw-update button pressed)\n");
str = getenv("bootcmd_update");
}
setenv("bootcmd",str);
return 0;
}
/** /**
* board_init: - setup some data structures * board_init: - setup some data structures
...@@ -51,7 +95,7 @@ int board_init (void) ...@@ -51,7 +95,7 @@ int board_init (void)
/* so we do _nothing_ here */ /* so we do _nothing_ here */
/* arch number of Innokom board */ /* arch number of Innokom board */
gd->bd->bi_arch_number = 258; gd->bd->bi_arch_number = MACH_TYPE_INNOKOM;
/* adress of boot parameters */ /* adress of boot parameters */
gd->bd->bi_boot_params = 0xa0000100; gd->bd->bi_boot_params = 0xa0000100;
......
...@@ -38,6 +38,9 @@ DRAM_SIZE: .long CFG_DRAM_SIZE ...@@ -38,6 +38,9 @@ DRAM_SIZE: .long CFG_DRAM_SIZE
sub pc,pc,#4 sub pc,pc,#4
.endm .endm
_TEXT_BASE:
.word TEXT_BASE
/* /*
* Memory setup * Memory setup
...@@ -222,6 +225,12 @@ mem_init: ...@@ -222,6 +225,12 @@ mem_init:
/* Step 2c: Write FLYCNFG FIXME: what's that??? */ /* Step 2c: Write FLYCNFG FIXME: what's that??? */
/* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */
/* test if we run from flash or RAM - RAM/BDI: don't setup RAM */
adr r3, mem_init /* r0 <- current position of code */
ldr r2, =mem_init
cmp r3, r2 /* skip init if in place */
beq initirqs
/* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */
/* Step 2d: Initialize Timing for Sync Memory (SDCLK0) */ /* Step 2d: Initialize Timing for Sync Memory (SDCLK0) */
...@@ -313,17 +322,23 @@ mem_init: ...@@ -313,17 +322,23 @@ mem_init:
/* documented in SDRAM data sheets. The address(es) used */ /* documented in SDRAM data sheets. The address(es) used */
/* for this purpose must not be cacheable. */ /* for this purpose must not be cacheable. */
ldr r3, =CFG_DRAM_BASE /* There should 9 writes, since the first write doesn't */
str r2, [r3] /* trigger a refresh cycle on PXA250. See Intel PXA250 and */
str r2, [r3] /* PXA210 Processors Specification Update, */
str r2, [r3] /* Jan 2003, Errata #116, page 30. */
str r2, [r3]
str r2, [r3]
str r2, [r3]
str r2, [r3]
str r2, [r3]
ldr r3, =CFG_DRAM_BASE
str r2, [r3]
str r2, [r3]
str r2, [r3]
str r2, [r3]
str r2, [r3]
str r2, [r3]
str r2, [r3]
str r2, [r3]
str r2, [r3]
/* Step 4g: Write MDCNFG with enable bits asserted */ /* Step 4g: Write MDCNFG with enable bits asserted */
/* (MDCNFG:DEx set to 1). */ /* (MDCNFG:DEx set to 1). */
...@@ -339,7 +354,6 @@ mem_init: ...@@ -339,7 +354,6 @@ mem_init:
/* We are finished with Intel's memory controller initialisation */ /* We are finished with Intel's memory controller initialisation */
/* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */
/* Disable (mask) all interrupts at interrupt controller */ /* Disable (mask) all interrupts at interrupt controller */
/* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */
...@@ -405,8 +419,7 @@ initclks: ...@@ -405,8 +419,7 @@ initclks:
/* FIXME */ /* FIXME */
#define NODEBUG #ifndef DEBUG
#ifdef NODEBUG
/*Disable software and data breakpoints */ /*Disable software and data breakpoints */
mov r0,#0 mov r0,#0
mcr p15,0,r0,c14,c8,0 /* ibcr0 */ mcr p15,0,r0,c14,c8,0 /* ibcr0 */
...@@ -416,7 +429,6 @@ initclks: ...@@ -416,7 +429,6 @@ initclks:
/*Enable all debug functionality */ /*Enable all debug functionality */
mov r0,#0x80000000 mov r0,#0x80000000
mcr p14,0,r0,c10,c0,0 /* dcsr */ mcr p14,0,r0,c10,c0,0 /* dcsr */
#endif #endif
/* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */
......
...@@ -47,7 +47,9 @@ SECTIONS ...@@ -47,7 +47,9 @@ SECTIONS
armboot_end_data = .; armboot_end_data = .;
. = ALIGN(4); . = ALIGN(4);
bss_start = .;
.bss : { *(.bss) } .bss : { *(.bss) }
bss_end = .;
armboot_end = .; armboot_end = .;
} }
...@@ -47,7 +47,9 @@ SECTIONS ...@@ -47,7 +47,9 @@ SECTIONS
armboot_end_data = .; armboot_end_data = .;
. = ALIGN(4); . = ALIGN(4);
bss_start = .;
.bss : { *(.bss) } .bss : { *(.bss) }
bss_end = .;
armboot_end = .; armboot_end = .;
} }
...@@ -301,7 +301,7 @@ extern char *stdio_names[]; ...@@ -301,7 +301,7 @@ extern char *stdio_names[];
void show_stdio_dev(void) void show_stdio_dev(void)
{ {
/* Print informations */ /* Print information */
printf ("In: "); printf ("In: ");
if (stdio_devices[stdin] == NULL) { if (stdio_devices[stdin] == NULL) {
printf ("No input devices available!\n"); printf ("No input devices available!\n");
......
...@@ -38,7 +38,7 @@ SECTIONS ...@@ -38,7 +38,7 @@ SECTIONS
lib_generic/crc32.o (.text) lib_generic/crc32.o (.text)
lib_generic/string.o (.text) lib_generic/string.o (.text)
. = env_offset; . = DEFINED(env_offset) ? env_offset : .;
common/environment.o (.ppcenv) common/environment.o (.ppcenv)
*(.text) *(.text)
......
...@@ -496,7 +496,7 @@ int console_init_r (void) ...@@ -496,7 +496,7 @@ int console_init_r (void)
} }
#ifndef CFG_CONSOLE_INFO_QUIET #ifndef CFG_CONSOLE_INFO_QUIET
/* Print informations */ /* Print information */
printf ("In: "); printf ("In: ");
if (stdio_devices[stdin] == NULL) { if (stdio_devices[stdin] == NULL) {
printf ("No input devices available!\n"); printf ("No input devices available!\n");
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <environment.h> #include <environment.h>
#include <cmd_nvedit.h> #include <cmd_nvedit.h>
#include <linux/stddef.h> #include <linux/stddef.h>
#include <malloc.h>
#if ((CONFIG_COMMANDS&(CFG_CMD_ENV|CFG_CMD_FLASH)) == (CFG_CMD_ENV|CFG_CMD_FLASH)) #if ((CONFIG_COMMANDS&(CFG_CMD_ENV|CFG_CMD_FLASH)) == (CFG_CMD_ENV|CFG_CMD_FLASH))
#define CMD_SAVEENV #define CMD_SAVEENV
...@@ -41,11 +42,6 @@ ...@@ -41,11 +42,6 @@
#error Cannot use CFG_ENV_ADDR_REDUND without CFG_CMD_ENV & CFG_CMD_FLASH #error Cannot use CFG_ENV_ADDR_REDUND without CFG_CMD_ENV & CFG_CMD_FLASH
#endif #endif
#if defined(CFG_ENV_SECT_SIZE) && (CFG_ENV_SECT_SIZE > CFG_ENV_SIZE) && \
defined(CFG_ENV_ADDR_REDUND)
#error CFG_ENV_ADDR_REDUND should not be used when CFG_ENV_SECT_SIZE > CFG_ENV_SIZE
#endif
#if defined(CFG_ENV_SIZE_REDUND) && (CFG_ENV_SIZE_REDUND < CFG_ENV_SIZE) #if defined(CFG_ENV_SIZE_REDUND) && (CFG_ENV_SIZE_REDUND < CFG_ENV_SIZE)
#error CFG_ENV_SIZE_REDUND should not be less then CFG_ENV_SIZE #error CFG_ENV_SIZE_REDUND should not be less then CFG_ENV_SIZE
#endif #endif
...@@ -80,8 +76,9 @@ static env_t *flash_addr = (env_t *)CFG_ENV_ADDR; ...@@ -80,8 +76,9 @@ static env_t *flash_addr = (env_t *)CFG_ENV_ADDR;
#ifdef CFG_ENV_ADDR_REDUND #ifdef CFG_ENV_ADDR_REDUND
static env_t *flash_addr_new = (env_t *)CFG_ENV_ADDR_REDUND; static env_t *flash_addr_new = (env_t *)CFG_ENV_ADDR_REDUND;
static ulong end_addr = CFG_ENV_ADDR + CFG_ENV_SIZE - 1; /* CFG_ENV_ADDR is supposed to be on sector boundary */
static ulong end_addr_new = CFG_ENV_ADDR_REDUND + CFG_ENV_SIZE_REDUND - 1; static ulong end_addr = CFG_ENV_ADDR + CFG_ENV_SECT_SIZE - 1;
static ulong end_addr_new = CFG_ENV_ADDR_REDUND + CFG_ENV_SECT_SIZE - 1;
static uchar active_flag = 1; static uchar active_flag = 1;
static uchar obsolete_flag = 0; static uchar obsolete_flag = 0;
...@@ -164,6 +161,8 @@ int env_init(void) ...@@ -164,6 +161,8 @@ int env_init(void)
int saveenv(void) int saveenv(void)
{ {
int rc = 1; int rc = 1;
ulong up_data = 0;
char *saved_data = NULL;
debug ("Protect off %08lX ... %08lX\n", debug ("Protect off %08lX ... %08lX\n",
(ulong)flash_addr, end_addr); (ulong)flash_addr, end_addr);
...@@ -179,6 +178,22 @@ int saveenv(void) ...@@ -179,6 +178,22 @@ int saveenv(void)
goto Done; goto Done;
} }
#if CFG_ENV_SECT_SIZE > CFG_ENV_SIZE
up_data = (end_addr_new + 1 - ((long)flash_addr_new + CFG_ENV_SIZE));
debug ("Data to save 0x%x\n", up_data);
if (up_data) {
if ((saved_data = malloc(up_data)) == NULL) {
printf("Unable to save the rest of sector (%ld)\n",
up_data);
goto Done;
}
memcpy(saved_data,
(void *)((long)flash_addr_new + CFG_ENV_SIZE), up_data);
debug ("Data (start 0x%x, len 0x%x) saved at 0x%x\n",
(long)flash_addr_new + CFG_ENV_SIZE,
up_data, saved_data);
}
#endif
puts ("Erasing Flash..."); puts ("Erasing Flash...");
debug (" %08lX ... %08lX ...", debug (" %08lX ... %08lX ...",
(ulong)flash_addr_new, end_addr_new); (ulong)flash_addr_new, end_addr_new);
...@@ -212,6 +227,18 @@ int saveenv(void) ...@@ -212,6 +227,18 @@ int saveenv(void)
} }
puts ("done\n"); puts ("done\n");
#if CFG_ENV_SECT_SIZE > CFG_ENV_SIZE
if (up_data) { /* restore the rest of sector */
debug ("Restoring the rest of data to 0x%x len 0x%x\n",
(long)flash_addr_new + CFG_ENV_SIZE, up_data);
if (flash_write(saved_data,
(long)flash_addr_new + CFG_ENV_SIZE,
up_data)) {
flash_perror(rc);
goto Done;
}
}
#endif
{ {
env_t * etmp = flash_addr; env_t * etmp = flash_addr;
ulong ltmp = end_addr; ulong ltmp = end_addr;
...@@ -226,6 +253,8 @@ int saveenv(void) ...@@ -226,6 +253,8 @@ int saveenv(void)
rc = 0; rc = 0;
Done: Done:
if (saved_data)
free (saved_data);
/* try to re-protect */ /* try to re-protect */
(void) flash_sect_protect (1, (ulong)flash_addr, end_addr); (void) flash_sect_protect (1, (ulong)flash_addr, end_addr);
(void) flash_sect_protect (1, (ulong)flash_addr_new, end_addr_new); (void) flash_sect_protect (1, (ulong)flash_addr_new, end_addr_new);
......
...@@ -1128,6 +1128,15 @@ static void I2C_Set_Stat (unsigned int eumbbar, I2C_STAT stat) ...@@ -1128,6 +1128,15 @@ static void I2C_Set_Stat (unsigned int eumbbar, I2C_STAT stat)
void i2c_init (int speed, int slaveadd) 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 #ifdef DEBUG
I2C_Initialize (0x7f, 0, (void *) printf); I2C_Initialize (0x7f, 0, (void *) printf);
#else #else
......
...@@ -221,6 +221,13 @@ void i2c_init(int speed, int slaveadd) ...@@ -221,6 +221,13 @@ void i2c_init(int speed, int slaveadd)
volatile I2C_BD *rxbd, *txbd; volatile I2C_BD *rxbd, *txbd;
uint dpaddr; uint dpaddr;
#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
dpaddr = *((unsigned short*)(&immap->im_dprambase[PROFF_I2C_BASE])); dpaddr = *((unsigned short*)(&immap->im_dprambase[PROFF_I2C_BASE]));
if (dpaddr == 0) { if (dpaddr == 0) {
/* need to allocate dual port ram */ /* need to allocate dual port ram */
......
...@@ -215,6 +215,13 @@ i2c_init(int speed, int slaveaddr) ...@@ -215,6 +215,13 @@ i2c_init(int speed, int slaveaddr)
volatile I2C_BD *rxbd, *txbd; volatile I2C_BD *rxbd, *txbd;
uint dpaddr; uint dpaddr;
#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 CFG_I2C_UCODE_PATCH #ifdef CFG_I2C_UCODE_PATCH
iip = (iic_t *)&cp->cp_dpmem[iip->iic_rpbase]; iip = (iic_t *)&cp->cp_dpmem[iip->iic_rpbase];
#else #else
......
...@@ -85,7 +85,15 @@ void i2c_init (int speed, int slaveadd) ...@@ -85,7 +85,15 @@ void i2c_init (int speed, int slaveadd)
unsigned long freqOPB; unsigned long freqOPB;
int val, divisor; int val, divisor;
#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
/* Handle possible failed I2C state */ /* Handle possible failed I2C state */
/* FIXME: put this into i2c_init_board()? */
_i2c_bus_reset (); _i2c_bus_reset ();
/* clear lo master address */ /* clear lo master address */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment