* Patch by David Mller, 13 Sep 2003:

various changes to VCMA9 board specific files

* Add I2C support for MGT5100 / MPC5200
This commit is contained in:
wdenk 2003-09-13 19:01:12 +00:00
parent b70e7a00c8
commit 531716e171
13 changed files with 616 additions and 78 deletions

View File

@ -2,6 +2,11 @@
Changes for U-Boot 1.0.0: Changes for U-Boot 1.0.0:
====================================================================== ======================================================================
* Patch by David Müller, 13 Sep 2003:
various changes to VCMA9 board specific files
* Add I2C support for MGT5100 / MPC5200
* Patch by Rune Torgersen, 11 Sep 2003: * Patch by Rune Torgersen, 11 Sep 2003:
Changed default memory option on MPC8266ADS to NOT be Page Based Changed default memory option on MPC8266ADS to NOT be Page Based
Interleave, since this doesn't work very well with the standard Interleave, since this doesn't work very well with the standard

3
README
View File

@ -203,6 +203,7 @@ Directory Hierarchy:
- board/mpl/common Common files for MPL boards - board/mpl/common Common files for MPL boards
- board/mpl/pip405 Files specific to PIP405 boards - board/mpl/pip405 Files specific to PIP405 boards
- board/mpl/mip405 Files specific to MIP405 boards - board/mpl/mip405 Files specific to MIP405 boards
- board/mpl/vcma9 Files specific to VCMA9 boards
- board/musenki Files specific to MUSEKNI boards - board/musenki Files specific to MUSEKNI boards
- board/mvs1 Files specific to MVS1 boards - board/mvs1 Files specific to MVS1 boards
- board/nx823 Files specific to NX823 boards - board/nx823 Files specific to NX823 boards
@ -363,7 +364,7 @@ The following options need to be configured:
CONFIG_IMPA7, CONFIG_LART, CONFIG_LUBBOCK, CONFIG_IMPA7, CONFIG_LART, CONFIG_LUBBOCK,
CONFIG_INNOVATOROMAP1510, CONFIG_INNOVATOROMAP1610 CONFIG_INNOVATOROMAP1510, CONFIG_INNOVATOROMAP1610
CONFIG_SHANNON, CONFIG_SMDK2400, CONFIG_SMDK2410, CONFIG_SHANNON, CONFIG_SMDK2400, CONFIG_SMDK2410,
CONFIG_TRAB, CONFIG_AT91RM9200DK CONFIG_TRAB, CONFIG_VCMA9, CONFIG_AT91RM9200DK
- CPU Module Type: (if CONFIG_COGENT is defined) - CPU Module Type: (if CONFIG_COGENT is defined)

View File

@ -41,9 +41,12 @@ static uchar cs8900_chksum(ushort data)
#endif #endif
extern void print_vcma9_info(void); extern void print_vcma9_info(void);
extern int vcma9_cantest(void); extern int vcma9_cantest(int);
extern int vcma9_nandtest(void); extern int vcma9_nandtest(void);
extern int vcma9_dactest(void); extern int vcma9_nanderase(void);
extern int vcma9_nandread(ulong);
extern int vcma9_nandwrite(ulong);
extern int vcma9_dactest(int);
extern int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); extern int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
@ -126,18 +129,53 @@ int do_vcma9(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
#endif #endif
#if 0 #if 0
if (strcmp(argv[1], "cantest") == 0) { if (strcmp(argv[1], "cantest") == 0) {
vcma9_cantest(); if (argc >= 3)
vcma9_cantest(strcmp(argv[2], "s") ? 0 : 1);
else
vcma9_cantest(0);
return 0; return 0;
} }
if (strcmp(argv[1], "nandtest") == 0) { if (strcmp(argv[1], "nandtest") == 0) {
vcma9_nandtest(); vcma9_nandtest();
return 0; return 0;
} }
if (strcmp(argv[1], "nanderase") == 0) {
vcma9_nanderase();
return 0;
}
if (strcmp(argv[1], "nandread") == 0) {
ulong offset = 0;
if (argc >= 3)
offset = simple_strtoul(argv[2], NULL, 16);
vcma9_nandread(offset);
return 0;
}
if (strcmp(argv[1], "nandwrite") == 0) {
ulong offset = 0;
if (argc >= 3)
offset = simple_strtoul(argv[2], NULL, 16);
vcma9_nandwrite(offset);
return 0;
}
if (strcmp(argv[1], "dactest") == 0) { if (strcmp(argv[1], "dactest") == 0) {
vcma9_dactest(); if (argc >= 3)
vcma9_dactest(strcmp(argv[2], "s") ? 0 : 1);
else
vcma9_dactest(0);
return 0; return 0;
} }
#endif #endif
return (do_mplcommon(cmdtp, flag, argc, argv)); return (do_mplcommon(cmdtp, flag, argc, argv));
} }
U_BOOT_CMD(
vcma9, 6, 1, do_vcma9,
"vcma9 - VCMA9 specific commands\n",
"flash mem [SrcAddr]\n - updates U-Boot with image in memory\n"
);

View File

@ -1,5 +1,5 @@
# #
# (C) Copyright 2002 # (C) Copyright 2002, 2003
# David Mueller, ELSOFT AG, <d.mueller@elsoft.ch> # David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
# #
# MPL VCMA9 board with S3C2410X (ARM920T) cpu # MPL VCMA9 board with S3C2410X (ARM920T) cpu
@ -8,17 +8,17 @@
# #
# #
# MPL VCMA9 has 1 bank of 64 MB DRAM # MPL VCMA9 has 1 bank of minimal 16 MB DRAM
# # from 0x30000000
# 3000'0000 to 3400'0000
# #
# Linux-Kernel is expected to be at 3000'8000, entry 3000'8000 # Linux-Kernel is expected to be at 3000'8000, entry 3000'8000
# optionally with a ramdisk at 3080'0000 # optionally with a ramdisk at 3040'0000
# #
# we load ourself to 33F8'0000 # we load ourself to 30F8'0000
# #
# download area is 3300'0000 # download area is 3080'0000
# #
#TEXT_BASE = 0x30F80000
TEXT_BASE = 0x33F80000 TEXT_BASE = 0x33F80000

View File

@ -34,7 +34,9 @@
/* some parameters for the board */ /* some parameters for the board */
#define BWSCON 0x48000000 #define BWSCON 0x48000000
#define PLD_BASE 0x2C000000
#define SDRAM_REG 0x2C000106
/* BWSCON */ /* BWSCON */
#define DW8 (0x0) #define DW8 (0x0)
@ -43,6 +45,9 @@
#define WAIT (0x1<<2) #define WAIT (0x1<<2)
#define UBLB (0x1<<3) #define UBLB (0x1<<3)
/* BANKSIZE */
#define BURST_EN (0x1<<7)
#define B1_BWSCON (DW16) #define B1_BWSCON (DW16)
#define B2_BWSCON (DW32) #define B2_BWSCON (DW32)
#define B3_BWSCON (DW32) #define B3_BWSCON (DW32)
@ -130,11 +135,26 @@ memsetup:
/* memory control configuration */ /* memory control configuration */
/* make r0 relative the current location so that it */ /* make r0 relative the current location so that it */
/* reads SMRDATA out of FLASH rather than memory ! */ /* reads SMRDATA out of FLASH rather than memory ! */
ldr r0, =SMRDATA ldr r0, =CSDATA
ldr r1, _TEXT_BASE ldr r1, _TEXT_BASE
sub r0, r0, r1 sub r0, r0, r1
ldr r1, =BWSCON /* Bus Width Status Controller */ ldr r1, =BWSCON /* Bus Width Status Controller */
add r2, r0, #13*4 add r2, r0, #CSDATA_END-CSDATA
0:
ldr r3, [r0], #4
str r3, [r1], #4
cmp r2, r0
bne 0b
/* PLD access is now possible */
/* r0 == SDRAMDATA */
/* r1 == SDRAM controller regs */
ldr r2, =PLD_BASE
ldrb r3, [r2, #SDRAM_REG-PLD_BASE]
mov r4, #SDRAMDATA1_END-SDRAMDATA
/* calculate start and end point */
mla r0, r3, r4, r0
add r2, r0, r4
0: 0:
ldr r3, [r0], #4 ldr r3, [r0], #4
str r3, [r1], #4 str r3, [r1], #4
@ -147,7 +167,7 @@ memsetup:
.ltorg .ltorg
/* the literal pools origin */ /* the literal pools origin */
SMRDATA: CSDATA:
.word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28)) .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
.word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC)) .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
.word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC)) .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
@ -155,9 +175,38 @@ SMRDATA:
.word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC)) .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
.word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC)) .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
.word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC)) .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
CSDATA_END:
SDRAMDATA:
/* 4Mx8x4 */
.word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN)) .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
.word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)) .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
.word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT) .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
.word 0x32 .word 0x32 + BURST_EN
.word 0x30
.word 0x30
SDRAMDATA1_END:
/* 8Mx8x4 (not implemented yet) */
.word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
.word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
.word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
.word 0x32 + BURST_EN
.word 0x30
.word 0x30
/* 2Mx8x4 (not implemented yet) */
.word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
.word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
.word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
.word 0x32 + BURST_EN
.word 0x30
.word 0x30
/* 4Mx8x2 (not implemented yet) */
.word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
.word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
.word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
.word 0x32 + BURST_EN
.word 0x30 .word 0x30
.word 0x30 .word 0x30

View File

@ -130,16 +130,6 @@ int board_init(void)
return 0; return 0;
} }
int dram_init(void)
{
DECLARE_GLOBAL_DATA_PTR;
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
return 0;
}
/* /*
* NAND flash initialization. * NAND flash initialization.
*/ */
@ -162,9 +152,16 @@ static inline void NF_Reset(void)
static inline void NF_Init(void) static inline void NF_Init(void)
{ {
#if 0 /* a little bit too optimistic */
#define TACLS 0 #define TACLS 0
#define TWRPH0 3 #define TWRPH0 3
#define TWRPH1 0 #define TWRPH1 0
#else
#define TACLS 0
#define TWRPH0 4
#define TWRPH1 2
#endif
NF_Conf((1<<15)|(0<<14)|(0<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0)); NF_Conf((1<<15)|(0<<14)|(0<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0));
/*nand->NFCONF = (1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0); */ /*nand->NFCONF = (1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0); */
/* 1 1 1 1, 1 xxx, r xxx, r xxx */ /* 1 1 1 1, 1 xxx, r xxx, r xxx */
@ -177,15 +174,12 @@ void
nand_init(void) nand_init(void)
{ {
S3C2410_NAND * const nand = S3C2410_GetBase_NAND(); S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
unsigned totlen;
NF_Init(); NF_Init();
#ifdef DEBUG #ifdef DEBUG
printf("NAND flash probing at 0x%.8lX\n", (ulong)nand); printf("NAND flash probing at 0x%.8lX\n", (ulong)nand);
#endif #endif
totlen = nand_probe((ulong)nand) >> 20; printf ("%4lu MB\n", nand_probe((ulong)nand) >> 20);
printf ("%4lu MB\n", totlen >> 20);
} }
#endif #endif
@ -193,29 +187,40 @@ nand_init(void)
* Get some Board/PLD Info * Get some Board/PLD Info
*/ */
static uchar Get_PLD_ID(void) static u8 Get_PLD_ID(void)
{ {
return(*(volatile uchar *)PLD_ID_REG); VCMA9_PLD * const pld = VCMA9_GetBase_PLD();
return(pld->ID);
} }
static uchar Get_PLD_BOARD(void) static u8 Get_PLD_BOARD(void)
{ {
return(*(volatile uchar *)PLD_BOARD_REG); VCMA9_PLD * const pld = VCMA9_GetBase_PLD();
return(pld->BOARD);
} }
static uchar Get_PLD_Version(void) static u8 Get_PLD_SDRAM(void)
{
VCMA9_PLD * const pld = VCMA9_GetBase_PLD();
return(pld->SDRAM);
}
static u8 Get_PLD_Version(void)
{ {
return((Get_PLD_ID() >> 4) & 0x0F); return((Get_PLD_ID() >> 4) & 0x0F);
} }
static uchar Get_PLD_Revision(void) static u8 Get_PLD_Revision(void)
{ {
return(Get_PLD_ID() & 0x0F); return(Get_PLD_ID() & 0x0F);
} }
static int Get_Board_Config(void) static int Get_Board_Config(void)
{ {
uchar config = Get_PLD_BOARD() & 0x03; u8 config = Get_PLD_BOARD() & 0x03;
if (config == 3) if (config == 3)
return 1; return 1;
@ -228,6 +233,54 @@ static uchar Get_Board_PCB(void)
return(((Get_PLD_BOARD() >> 4) & 0x03) + 'A'); return(((Get_PLD_BOARD() >> 4) & 0x03) + 'A');
} }
static u8 Get_SDRAM_ChipNr(void)
{
switch ((Get_PLD_SDRAM() >> 4) & 0x0F) {
case 0: return 4;
case 1: return 1;
case 2: return 2;
default: return 0;
}
}
static ulong Get_SDRAM_ChipSize(void)
{
switch (Get_PLD_SDRAM() & 0x0F) {
case 0: return 16 * (1024*1024);
case 1: return 32 * (1024*1024);
case 2: return 8 * (1024*1024);
case 3: return 8 * (1024*1024);
default: return 0;
}
}
static const char * Get_SDRAM_ChipGeom(void)
{
switch (Get_PLD_SDRAM() & 0x0F) {
case 0: return "4Mx8x4";
case 1: return "8Mx8x4";
case 2: return "2Mx8x4";
case 3: return "4Mx8x2";
default: return "unknown";
}
}
static void Show_VCMA9_Info(char *board_name, char *serial)
{
printf("Board: %s SN: %s PCB Rev: %c PLD(%d,%d)\n",
board_name, serial, Get_Board_PCB(), Get_PLD_Version(), Get_PLD_Revision());
printf("SDRAM: %d chips %s\n", Get_SDRAM_ChipNr(), Get_SDRAM_ChipGeom());
}
int dram_init(void)
{
DECLARE_GLOBAL_DATA_PTR;
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
gd->bd->bi_dram[0].size = Get_SDRAM_ChipSize() * Get_SDRAM_ChipNr();
return 0;
}
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
/* /*
@ -240,8 +293,6 @@ int checkboard(void)
int i; int i;
backup_t *b = (backup_t *) s; backup_t *b = (backup_t *) s;
puts("Board: ");
i = getenv_r("serial#", s, 32); i = getenv_r("serial#", s, 32);
if ((i < 0) || strncmp (s, "VCMA9", 5)) { if ((i < 0) || strncmp (s, "VCMA9", 5)) {
get_backup_values (b); get_backup_values (b);
@ -249,32 +300,23 @@ int checkboard(void)
puts ("### No HW ID - assuming VCMA9"); puts ("### No HW ID - assuming VCMA9");
} else { } else {
b->serial_name[5] = 0; b->serial_name[5] = 0;
printf ("%s-%d PCB Rev %c SN: %s", b->serial_name, Get_Board_Config(), Show_VCMA9_Info(b->serial_name, &b->serial_name[6]);
Get_Board_PCB(), &b->serial_name[6]);
} }
} else { } else {
s[5] = 0; s[5] = 0;
printf ("%s-%d PCB Rev %c SN: %s", s, Get_Board_Config(), Get_Board_PCB(), Show_VCMA9_Info(s, &s[6]);
&s[6]);
} }
printf("\n"); /*printf("\n");*/
return(0); return(0);
} }
void print_vcma9_rev(void)
{
printf("Board: VCMA9-%d PCB Rev: %c (PLD Ver: %d, Rev: %d)\n",
Get_Board_Config(), Get_Board_PCB(),
Get_PLD_Version(), Get_PLD_Revision());
}
extern void mem_test_reloc(void); extern void mem_test_reloc(void);
int last_stage_init(void) int last_stage_init(void)
{ {
mem_test_reloc(); mem_test_reloc();
print_vcma9_rev(); checkboard();
show_stdio_dev(); show_stdio_dev();
check_env(); check_env();
return 0; return 0;
@ -296,5 +338,14 @@ int overwrite_console(void)
************************************************************************/ ************************************************************************/
void print_vcma9_info(void) void print_vcma9_info(void)
{ {
print_vcma9_rev(); unsigned char s[50];
int i;
if ((i = getenv_r("serial#", s, 32)) < 0) {
puts ("### No HW ID - assuming VCMA9");
printf("i %d", i*24);
} else {
s[5] = 0;
Show_VCMA9_Info(s, &s[6]);
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* (C) Copyright 2002 * (C) Copyright 2002, 2003
* David Mueller, ELSOFT AG, d.mueller@elsoft.ch * David Mueller, ELSOFT AG, d.mueller@elsoft.ch
* *
* See file CREDITS for list of people who contributed to this * See file CREDITS for list of people who contributed to this
@ -116,11 +116,19 @@ static inline u32 NF_Read_ECC(void)
#endif #endif
/* VCMA9 PLD regsiters */
typedef struct {
S3C24X0_REG8 ID;
S3C24X0_REG8 NIC;
S3C24X0_REG8 CAN;
S3C24X0_REG8 MISC;
S3C24X0_REG8 GPCD;
S3C24X0_REG8 BOARD;
S3C24X0_REG8 SDRAM;
} /*__attribute__((__packed__))*/ VCMA9_PLD;
#define PLD_BASE_ADDRESS 0x2C000100 #define VCMA9_PLD_BASE 0x2C000100
#define PLD_ID_REG (PLD_BASE_ADDRESS + 0) static inline VCMA9_PLD * const VCMA9_GetBase_PLD(void)
#define PLD_NIC_REG (PLD_BASE_ADDRESS + 1) {
#define PLD_CAN_REG (PLD_BASE_ADDRESS + 2) return (VCMA9_PLD * const)VCMA9_PLD_BASE;
#define PLD_MISC_REG (PLD_BASE_ADDRESS + 3) }
#define PLD_GPCD_REG (PLD_BASE_ADDRESS + 4)
#define PLD_BOARD_REG (PLD_BASE_ADDRESS + 5)

View File

@ -27,7 +27,7 @@ LIB = lib$(CPU).a
START = start.o START = start.o
ASOBJS = io.o firmware_sc_task_bestcomm.impl.o firmware_sc_task.impl.o ASOBJS = io.o firmware_sc_task_bestcomm.impl.o firmware_sc_task.impl.o
OBJS = traps.o cpu.o cpu_init.o speed.o interrupts.o serial.o \ OBJS = i2c.o traps.o cpu.o cpu_init.o speed.o interrupts.o serial.o \
loadtask.o fec.o pci_mpc5200.o loadtask.o fec.o pci_mpc5200.o
all: .depend $(START) $(ASOBJS) $(LIB) all: .depend $(START) $(ASOBJS) $(LIB)

338
cpu/mpc5xxx/i2c.c Normal file
View File

@ -0,0 +1,338 @@
/*
* (C) Copyright 2003
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#ifdef CONFIG_HARD_I2C
#include <mpc5xxx.h>
#include <i2c.h>
#ifdef CFG_I2C_MODULE
#define I2C_BASE MPC5XXX_I2C2
#else
#define I2C_BASE MPC5XXX_I2C1
#endif
#define I2C_TIMEOUT 100
#define I2C_RETRIES 3
static int mpc_reg_in (volatile u32 *reg);
static void mpc_reg_out (volatile u32 *reg, int val, int mask);
static int wait_for_bb (void);
static int wait_for_pin (int *status);
static int do_address (uchar chip, char rdwr_flag);
static int send_bytes (uchar chip, char *buf, int len);
static int receive_bytes (uchar chip, char *buf, int len);
static int mpc_reg_in(volatile u32 *reg)
{
return *reg >> 24;
__asm__ __volatile__ ("eieio");
}
static void mpc_reg_out(volatile u32 *reg, int val, int mask)
{
int tmp;
if (!mask) {
*reg = val << 24;
} else {
tmp = mpc_reg_in(reg);
*reg = ((tmp & ~mask) | (val & mask)) << 24;
}
__asm__ __volatile__ ("eieio");
return;
}
static int wait_for_bb(void)
{
struct mpc5xxx_i2c *regs = (struct mpc5xxx_i2c *)I2C_BASE;
int timeout = I2C_TIMEOUT;
int status;
status = mpc_reg_in(&regs->msr);
while (timeout-- && (status & I2C_BB)) {
#if 1
volatile int temp;
mpc_reg_out(&regs->mcr, I2C_STA, I2C_STA);
temp = mpc_reg_in(&regs->mdr);
mpc_reg_out(&regs->mcr, 0, I2C_STA);
mpc_reg_out(&regs->mcr, 0, 0);
mpc_reg_out(&regs->mcr, I2C_EN, 0);
#endif
udelay(1000);
status = mpc_reg_in(&regs->msr);
}
return (status & I2C_BB);
}
static int wait_for_pin(int *status)
{
struct mpc5xxx_i2c *regs = (struct mpc5xxx_i2c *)I2C_BASE;
int timeout = I2C_TIMEOUT;
*status = mpc_reg_in(&regs->msr);
while (timeout-- && !(*status & I2C_IF)) {
udelay(1000);
*status = mpc_reg_in(&regs->msr);
}
if (!(*status & I2C_IF)) {
return -1;
}
mpc_reg_out(&regs->msr, 0, I2C_IF);
return 0;
}
static int do_address(uchar chip, char rdwr_flag)
{
struct mpc5xxx_i2c *regs = (struct mpc5xxx_i2c *)I2C_BASE;
int status;
chip <<= 1;
if (rdwr_flag) {
chip |= 1;
}
mpc_reg_out(&regs->mcr, I2C_TX, I2C_TX);
mpc_reg_out(&regs->mdr, chip, 0);
if (wait_for_pin(&status)) {
return -2;
}
if (status & I2C_RXAK) {
return -3;
}
return 0;
}
static int send_bytes(uchar chip, char *buf, int len)
{
struct mpc5xxx_i2c *regs = (struct mpc5xxx_i2c *)I2C_BASE;
int wrcount;
int status;
for (wrcount = 0; wrcount < len; ++wrcount) {
mpc_reg_out(&regs->mdr, buf[wrcount], 0);
if (wait_for_pin(&status)) {
break;
}
if (status & I2C_RXAK) {
break;
}
}
return !(wrcount == len);
}
static int receive_bytes(uchar chip, char *buf, int len)
{
struct mpc5xxx_i2c *regs = (struct mpc5xxx_i2c *)I2C_BASE;
int dummy = 1;
int rdcount = 0;
int status;
int i;
mpc_reg_out(&regs->mcr, 0, I2C_TX);
for (i = 0; i < len; ++i) {
buf[rdcount] = mpc_reg_in(&regs->mdr);
if (dummy) {
dummy = 0;
} else {
rdcount++;
}
if (wait_for_pin(&status)) {
return -4;
}
}
mpc_reg_out(&regs->mcr, I2C_TXAK, I2C_TXAK);
buf[rdcount++] = mpc_reg_in(&regs->mdr);
if (wait_for_pin(&status)) {
return -5;
}
mpc_reg_out(&regs->mcr, 0, I2C_TXAK);
return 0;
}
/**************** I2C API ****************/
void i2c_init(int speed, int saddr)
{
struct mpc5xxx_i2c *regs = (struct mpc5xxx_i2c *)I2C_BASE;
mpc_reg_out(&regs->mcr, 0, 0);
mpc_reg_out(&regs->madr, saddr << 1, 0);
/* Set clock
*/
mpc_reg_out(&regs->mfdr, speed, 0);
/* Enable module
*/
mpc_reg_out(&regs->mcr, I2C_EN, I2C_INIT_MASK);
mpc_reg_out(&regs->msr, 0, I2C_IF);
return;
}
int i2c_probe(uchar chip)
{
struct mpc5xxx_i2c *regs = (struct mpc5xxx_i2c *)I2C_BASE;
int i;
for (i = 0; i < I2C_RETRIES; i++) {
mpc_reg_out(&regs->mcr, I2C_STA, I2C_STA);
if (! do_address(chip, 0)) {
mpc_reg_out(&regs->mcr, 0, I2C_STA);
break;
}
mpc_reg_out(&regs->mcr, 0, I2C_STA);
udelay(500);
}
return (i == I2C_RETRIES);
}
int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
{
uchar xaddr[4];
struct mpc5xxx_i2c * regs = (struct mpc5xxx_i2c *)I2C_BASE;
int ret = -1;
xaddr[0] = (addr >> 24) & 0xFF;
xaddr[1] = (addr >> 16) & 0xFF;
xaddr[2] = (addr >> 8) & 0xFF;
xaddr[3] = addr & 0xFF;
if (wait_for_bb()) {
printf("i2c_read: bus is busy\n");
goto Done;
}
mpc_reg_out(&regs->mcr, I2C_STA, I2C_STA);
if (do_address(chip, 0)) {
printf("i2c_read: failed to address chip\n");
goto Done;
}
if (send_bytes(chip, &xaddr[4-alen], alen)) {
printf("i2c_read: send_bytes failed\n");
goto Done;
}
mpc_reg_out(&regs->mcr, I2C_RSTA, I2C_RSTA);
if (do_address(chip, 1)) {
printf("i2c_read: failed to address chip\n");
goto Done;
}
if (receive_bytes(chip, buf, len)) {
printf("i2c_read: receive_bytes failed\n");
goto Done;
}
ret = 0;
Done:
mpc_reg_out(&regs->mcr, 0, I2C_STA);
return ret;
}
int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)
{
uchar xaddr[4];
struct mpc5xxx_i2c *regs = (struct mpc5xxx_i2c *)I2C_BASE;
int ret = -1;
xaddr[0] = (addr >> 24) & 0xFF;
xaddr[1] = (addr >> 16) & 0xFF;
xaddr[2] = (addr >> 8) & 0xFF;
xaddr[3] = addr & 0xFF;
if (wait_for_bb()) {
printf("i2c_write: bus is busy\n");
goto Done;
}
mpc_reg_out(&regs->mcr, I2C_STA, I2C_STA);
if (do_address(chip, 0)) {
printf("i2c_write: failed to address chip\n");
goto Done;
}
if (send_bytes(chip, &xaddr[4-alen], alen)) {
printf("i2c_write: send_bytes failed\n");
goto Done;
}
if (send_bytes(chip, buf, len)) {
printf("i2c_write: send_bytes failed\n");
goto Done;
}
ret = 0;
Done:
mpc_reg_out(&regs->mcr, 0, I2C_STA);
return ret;
}
uchar i2c_reg_read(uchar chip, uchar reg)
{
char buf;
i2c_read(chip, reg, 1, &buf, 1);
return buf;
}
void i2c_reg_write(uchar chip, uchar reg, uchar val)
{
i2c_write(chip, reg, 1, &val, 1);
return;
}
#endif /* CONFIG_HARD_I2C */

View File

@ -83,7 +83,8 @@
/* /*
* Supported commands * Supported commands
*/ */
#define CONFIG_COMMANDS (CONFIG_CMD_DFL | ADD_PCI_CMD) #define CONFIG_COMMANDS (CONFIG_CMD_DFL | ADD_PCI_CMD | \
CFG_CMD_I2C | CFG_CMD_EEPROM)
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
#include <cmd_confdefs.h> #include <cmd_confdefs.h>
@ -98,6 +99,23 @@
/* /*
* I2C configuration * I2C configuration
*/ */
#define CONFIG_HARD_I2C 1 /* I2C with hardware support */
#define CFG_I2C_MODULE 1 /* If defined then I2C module #2 is used
* otherwise I2C module #1 is used */
#ifdef CONFIG_MPC5200
#define CFG_I2C_SPEED 0x3D /* 86KHz given 133MHz IPBI */
#else
#define CFG_I2C_SPEED 0x35 /* 86KHz given 33MHz IPBI */
#endif
#define CFG_I2C_SLAVE 0x7F
/*
* EEPROM configuration
*/
#define CFG_I2C_EEPROM_ADDR 0x50 /* 1010000x */
#define CFG_I2C_EEPROM_ADDR_LEN 1
#define CFG_EEPROM_PAGE_WRITE_BITS 3
#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 35
/* /*
* Flash configuration * Flash configuration

View File

@ -1,5 +1,5 @@
/* /*
* (C) Copyright 2002 * (C) Copyright 2002, 2003
* Sysgo Real-Time Solutions, GmbH <www.elinos.com> * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de> * Marius Groeger <mgroeger@sysgo.de>
* Gary Jennejohn <gj@denx.de> * Gary Jennejohn <gj@denx.de>
@ -160,9 +160,10 @@
#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ #define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
#define CFG_MEMTEST_START 0x30000000 /* memtest works on */ #define CFG_MEMTEST_START 0x30000000 /* memtest works on */
#define CFG_MEMTEST_END 0x33F80000 /* 63.5 MB in DRAM */ #define CFG_MEMTEST_END 0x30F80000 /* 15.5 MB in DRAM */
#define CFG_ALT_MEMTEST #define CFG_ALT_MEMTEST
#define CFG_LOAD_ADDR 0x33000000 /* default load address */ #define CFG_LOAD_ADDR 0x30800000 /* default load address */
#undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */ #undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */
@ -197,8 +198,6 @@
*/ */
#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */ #define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */
#define PHYS_SDRAM_1 0x30000000 /* SDRAM Bank #1 */ #define PHYS_SDRAM_1 0x30000000 /* SDRAM Bank #1 */
#define PHYS_SDRAM_1_SIZE 0x04000000 /* 64 MB */
#define PHYS_FLASH_1 0x00000000 /* Flash Bank #1 */ #define PHYS_FLASH_1 0x00000000 /* Flash Bank #1 */
#define CFG_FLASH_BASE PHYS_FLASH_1 #define CFG_FLASH_BASE PHYS_FLASH_1

View File

@ -108,6 +108,9 @@
#define MPC5XXX_FEC (CFG_MBAR + 0x3000) #define MPC5XXX_FEC (CFG_MBAR + 0x3000)
#define MPC5XXX_I2C1 (CFG_MBAR + 0x3D00)
#define MPC5XXX_I2C2 (CFG_MBAR + 0x3D40)
#if defined(CONFIG_MGT5100) #if defined(CONFIG_MGT5100)
#define MPC5XXX_SRAM (CFG_MBAR + 0x4000) #define MPC5XXX_SRAM (CFG_MBAR + 0x4000)
#define MPC5XXX_SRAM_SIZE (8*1024) #define MPC5XXX_SRAM_SIZE (8*1024)
@ -197,6 +200,24 @@
#define MPC5XXX_GPT0_ENABLE (MPC5XXX_GPT + 0x0) #define MPC5XXX_GPT0_ENABLE (MPC5XXX_GPT + 0x0)
#define MPC5XXX_GPT0_COUNTER (MPC5XXX_GPT + 0x4) #define MPC5XXX_GPT0_COUNTER (MPC5XXX_GPT + 0x4)
/* I2Cn control register bits */
#define I2C_EN 0x80
#define I2C_IEN 0x40
#define I2C_STA 0x20
#define I2C_TX 0x10
#define I2C_TXAK 0x08
#define I2C_RSTA 0x04
#define I2C_INIT_MASK (I2C_EN | I2C_STA | I2C_TX | I2C_RSTA)
/* I2Cn status register bits */
#define I2C_CF 0x80
#define I2C_AAS 0x40
#define I2C_BB 0x20
#define I2C_AL 0x10
#define I2C_SRW 0x04
#define I2C_IF 0x02
#define I2C_RXAK 0x01
/* Programmable Serial Controller (PSC) status register bits */ /* Programmable Serial Controller (PSC) status register bits */
#define PSC_SR_CDE 0x0080 #define PSC_SR_CDE 0x0080
#define PSC_SR_RXRDY 0x0100 #define PSC_SR_RXRDY 0x0100
@ -505,6 +526,14 @@ struct mpc5xxx_sdma {
volatile u32 EU37; /* SDMA + 0xfc */ volatile u32 EU37; /* SDMA + 0xfc */
}; };
struct mpc5xxx_i2c {
volatile u32 madr; /* I2Cn + 0x00 */
volatile u32 mfdr; /* I2Cn + 0x04 */
volatile u32 mcr; /* I2Cn + 0x08 */
volatile u32 msr; /* I2Cn + 0x0C */
volatile u32 mdr; /* I2Cn + 0x10 */
};
/* function prototypes */ /* function prototypes */
void loadtask(int basetask, int tasks); void loadtask(int basetask, int tasks);

View File

@ -80,13 +80,15 @@ void rtc_get (struct rtc_time *tmp)
SetRTC_Access(RTC_ENABLE); SetRTC_Access(RTC_ENABLE);
/* read RTC registers */ /* read RTC registers */
sec = rtc->BCDSEC; do {
min = rtc->BCDMIN; sec = rtc->BCDSEC;
hour = rtc->BCDHOUR; min = rtc->BCDMIN;
mday = rtc->BCDDATE; hour = rtc->BCDHOUR;
wday = rtc->BCDDAY; mday = rtc->BCDDATE;
mon = rtc->BCDMON; wday = rtc->BCDDAY;
year = rtc->BCDYEAR; mon = rtc->BCDMON;
year = rtc->BCDYEAR;
} while (sec != rtc->BCDSEC);
/* read ALARM registers */ /* read ALARM registers */
a_sec = rtc->ALMSEC; a_sec = rtc->ALMSEC;
@ -170,7 +172,7 @@ void rtc_reset (void)
S3C24X0_RTC * const rtc = S3C24X0_GetBase_RTC(); S3C24X0_RTC * const rtc = S3C24X0_GetBase_RTC();
rtc->RTCCON = (rtc->RTCCON & ~0x06) | 0x08; rtc->RTCCON = (rtc->RTCCON & ~0x06) | 0x08;
rtc->RTCCON &= ~0x08; rtc->RTCCON &= ~(0x08|0x01);
} }
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */