[U-Boot-Users] [PATCH] extended hardware support for MCF5282

CHANGELOG patch_m5282_watchdog.diff
* add Watchdog support for MCF 5282
CHANGELOG patch_m5282_fec.diff
* fix MII_Speed calculation for MCF 528x * mii_send returns -1, if timeout reached * starts discover phy with address 0
CHANGELOG patch_m5282_i2c.diff
* add polling hardware i2c driver for M528x
CHANGELOG patch_m5282_interrupt.diff
* extended interupt support for Freescale MCF 5282 interupt controllers
CHANGELOG patch_m5282_h.diff
* add definitions for I2C controller modul * add definitions for interrupt controller modul * add vector number for UART and PIT
CHANGELOG patch_m5282_time.diff
* interupt driven timer MCF 5282, if CFG_HZ = 1000, to realize tick counter * udelay considers CFG_CLK
diff --git a/cpu/mcf52x2/fec.c b/cpu/mcf52x2/fec.c index b6540b5..a41db4f 100644 --- a/cpu/mcf52x2/fec.c +++ b/cpu/mcf52x2/fec.c @@ -71,7 +71,6 @@ static void mii_discover_phy (void); #define PKT_MINBUF_SIZE 64 #define PKT_MAXBLR_SIZE 1520
- static char txbuf[DBUF_LENGTH];
static uint rxIdx; /* index of the current RX buffer */ @@ -257,17 +256,15 @@ int eth_init (bd_t * bd) */ fecp->fec_ihash_table_high = 0; fecp->fec_ihash_table_low = 0; -#else - /* Clear multicast address hash table - */ -#ifdef CONFIG_M5282 +#elif defined(CONFIG_M5282) + fecp->fec_ghash_table_high = 0; + fecp->fec_ghash_table_low = 0; fecp->fec_ihash_table_high = 0; fecp->fec_ihash_table_low = 0; #else fecp->fec_hash_table_high = 0; fecp->fec_hash_table_low = 0; #endif -#endif
/* Set maximum receive buffer size. */ @@ -333,8 +330,16 @@ int eth_init (bd_t * bd) fecp->fec_x_cntrl = 0; #endif /* Set MII speed */ +#ifdef CONFIG_M5282 + fecp->fec_mii_speed = (CFG_CLK / (2 * 2500000)); + fecp->fec_mii_speed *= 2; +#ifdef ET_DEBUG + printf ("fecp->fec_mii_speed: 0x%x\n",fecp->fec_mii_speed); +#endif +#else fecp->fec_mii_speed = (((CFG_CLK / 2) / (2500000 / 10)) + 5) / 10; fecp->fec_mii_speed *= 2; +#endif
/* Configure port B for MII. */ @@ -404,19 +409,28 @@ static uint phytype; /* send command to phy using mii, wait for result */ static uint mii_send (uint mii_cmd) { + uint timeout; uint mii_reply; volatile fec_t *ep = (fec_t *) (FEC_ADDR);
ep->fec_mii_data = mii_cmd; /* command to phy */
/* wait for mii complete */ - while (!(ep->fec_ievent & FEC_ENET_MII)); /* spin until done */ + timeout=50; + while (!(ep->fec_ievent & FEC_ENET_MII) && (timeout>0)) + { + udelay(2); +#ifdef ET_DEBUG + printf ("w"); +#endif + }; /* spin until done */ mii_reply = ep->fec_mii_data; /* result from phy */ ep->fec_ievent = FEC_ENET_MII; /* clear MII complete */ #ifdef ET_DEBUG printf ("%s[%d] %s: sent=0x%8.8x, reply=0x%8.8x\n", __FILE__, __LINE__, __FUNCTION__, mii_cmd, mii_reply); #endif + if (timeout ==0) return -1; return (mii_reply & 0xffff); /* data read from phy */ } #endif /* CFG_DISCOVER_PHY || (CONFIG_COMMANDS & CFG_CMD_MII) */ @@ -438,10 +452,10 @@ static void mii_discover_phy (void) */ udelay (10000); /* wait 10ms */ } - for (phyno = 1; phyno < 32 && phyaddr < 0; ++phyno) { + for (phyno = 0; phyno < 32 && phyaddr < 0; ++phyno) { phytype = mii_send (mk_mii_read (phyno, PHY_PHYIDR1)); #ifdef ET_DEBUG - printf ("PHY type 0x%x pass %d type ", phytype, pass); + printf ("PHY type 0x%x pass %d type \n", phytype, pass); #endif if (phytype != 0xffff) { phyaddr = phyno;
diff --git a/include/asm-m68k/m5282.h b/include/asm-m68k/m5282.h index e5058a4..2b4b318 100644 --- a/include/asm-m68k/m5282.h +++ b/include/asm-m68k/m5282.h @@ -347,6 +347,11 @@ #define MCFSDRAMC_DMR_V (0x00000001)
#define MCFWTM_WCR (*(vu_short *)(CFG_MBAR+0x00140000)) +#define MCFWTM_WCR_EN (0x0001) +#define MCFWTM_WCR_HALTED (0x0002) +#define MCFWTM_WCR_DOZE (0x0004) +#define MCFWTM_WCR_WAIT (0x0008) + #define MCFWTM_WMR (*(vu_short *)(CFG_MBAR+0x00140002)) #define MCFWTM_WCNTR (*(vu_short *)(CFG_MBAR+0x00140004)) #define MCFWTM_WSR (*(vu_short *)(CFG_MBAR+0x00140006)) @@ -376,6 +381,39 @@
/********************************************************************* * +* Inter-IC (I2C) Module +* +*********************************************************************/ + +/* Read/Write access macros for general use */ +#define MCFI2C_I2ADR (*(vu_char *)(CFG_MBAR+0x00000300)) +#define MCFI2C_I2FDR (*(vu_char *)(CFG_MBAR+0x00000304)) +#define MCFI2C_I2CR (*(vu_char *)(CFG_MBAR+0x00000308)) +#define MCFI2C_I2SR (*(vu_char *)(CFG_MBAR+0x0000030C)) +#define MCFI2C_I2DR (*(vu_char *)(CFG_MBAR+0x00000310)) + +/* Bit level definitions and macros */ +#define MCFI2C_I2ADR_ADDR(x) (((x)&0x7F)<<0x01) + +#define MCFI2C_I2FDR_IC(x) (((x)&0x3F)) + +#define MCFI2C_I2CR_IEN (0x80) +#define MCFI2C_I2CR_IIEN (0x40) +#define MCFI2C_I2CR_MSTA (0x20) +#define MCFI2C_I2CR_MTX (0x10) +#define MCFI2C_I2CR_TXAK (0x08) +#define MCFI2C_I2CR_RSTA (0x04) + +#define MCFI2C_I2SR_ICF (0x80) +#define MCFI2C_I2SR_IAAS (0x40) +#define MCFI2C_I2SR_IBB (0x20) +#define MCFI2C_I2SR_IAL (0x10) +#define MCFI2C_I2SR_SRW (0x04) +#define MCFI2C_I2SR_IIF (0x02) +#define MCFI2C_I2SR_RXAK (0x01) + +/********************************************************************* +* * General Purpose Timer (GPT) Module * *********************************************************************/ @@ -541,5 +579,75 @@ #define MCFCFM_CMD_PGERS 0x40 #define MCFCFM_CMD_MASERS 0x41
+/********************************************************************* +* +* Interupt Controller (ICM) Module +* +*********************************************************************/ + +#define MCFICM_IMRH0 (*(vu_long*) (CFG_MBAR+0x00000C08)) +#define MCFICM_IMRH0_FEC_GRA 0x00000001 +#define MCFICM_IMRH0_FEC_EBERR 0x00000002 +#define MCFICM_IMRH0_FEC_BABT 0x00000004 +#define MCFICM_IMRH0_FEC_BABR 0x00000008 +#define MCFICM_IMRH0_PMM 0x00000010 +#define MCFICM_IMRH0_QADC_CF1 0x00000020 +#define MCFICM_IMRH0_QADC_CF2 0x00000040 +#define MCFICM_IMRH0_QADC_PF1 0x00000080 + +#define MCFICM_IMRH0_QADC_PF2 0x00000100 +#define MCFICM_IMRH0_GPTA_TOF 0x00000200 +#define MCFICM_IMRH0_GPTA_PAIF 0x00000400 +#define MCFICM_IMRH0_GPTA_PAOVF 0x00000800 +#define MCFICM_IMRH0_GPTA_C0F 0x00001000 +#define MCFICM_IMRH0_GPTA_C1F 0x00002000 +#define MCFICM_IMRH0_GPTA_C2F 0x00004000 +#define MCFICM_IMRH0_GPTA_C3F 0x00008000 + +#define MCFICM_IMRH0_GPTB_TOF 0x00010000 +#define MCFICM_IMRH0_GPTB_PAIF 0x00020000 +#define MCFICM_IMRH0_GPTB_PAOVF 0x00040000 +#define MCFICM_IMRH0_GPTB_C0F 0x00080000 +#define MCFICM_IMRH0_GPTB_C1F 0x00100000 +#define MCFICM_IMRH0_GPTB_C2F 0x00200000 +#define MCFICM_IMRH0_GPTB_C3F 0x00400000 +#define MCFICM_IMRH0_PIT0 0x00800000 + +#define MCFICM_IMRH0_PIT1 0x01000000 +#define MCFICM_IMRH0_PIT2 0x02000000 +#define MCFICM_IMRH0_PIT3 0x04000000 +#define MCFICM_IMRH0_CFM_CBEIF 0x08000000 +#define MCFICM_IMRH0_CFM_CCIF 0x10000000 +#define MCFICM_IMRH0_CFM_PVIF 0x20000000 +#define MCFICM_IMRH0_CFM_AEIF 0x40000000 +#define MCFICM_IMRH0_63 0x80000000 + +#define MCFICM_ICR_IL 3 +#define MCFICM_ICR_IP 0 + +#define MCFICM_ICR_PIT0 (*(vu_char*) (CFG_MBAR+0x00000C77)) +#define MCFICM_ICR_PIT1 (*(vu_char*) (CFG_MBAR+0x00000C78)) +#define MCFICM_ICR_PIT2 (*(vu_char*) (CFG_MBAR+0x00000C79)) +#define MCFICM_ICR_PIT3 (*(vu_char*) (CFG_MBAR+0x00000C7A)) + +/********************************************************************* +* +* Vectors +* +*********************************************************************/ + +#define MCFVECTOR_INTC0_OFFSET 64 + +#define MCFVECTOR_UART0 MCFVECTOR_INTC0_OFFSET+13 +#define MCFVECTOR_UART1 MCFVECTOR_INTC0_OFFSET+14 +#define MCFVECTOR_UART2 MCFVECTOR_INTC0_OFFSET+15 + +#define MCFVECTOR_I2C MCFVECTOR_INTC0_OFFSET+17 + +#define MCFVECTOR_PIT0 MCFVECTOR_INTC0_OFFSET+55 +#define MCFVECTOR_PIT1 MCFVECTOR_INTC0_OFFSET+56 +#define MCFVECTOR_PIT2 MCFVECTOR_INTC0_OFFSET+57 +#define MCFVECTOR_PIT3 MCFVECTOR_INTC0_OFFSET+58 + /****************************************************************************/ #endif /* m5282_h */
diff --git a/cpu/mcf52x2/Makefile b/cpu/mcf52x2/Makefile index 70d57cf..071fc60 100644 --- a/cpu/mcf52x2/Makefile +++ b/cpu/mcf52x2/Makefile @@ -28,7 +28,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(CPU).a
START = -COBJS = serial.o interrupts.o cpu.o speed.o cpu_init.o fec.o +COBJS = serial.o interrupts.o cpu.o speed.o cpu_init.o fec.o i2c.o
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/cpu/mcf52x2/i2c.c b/cpu/mcf52x2/i2c.c new file mode 100644 index 0000000..3f4daa2 --- /dev/null +++ b/cpu/mcf52x2/i2c.c @@ -0,0 +1,596 @@ +/* + * (C) Copyright 2006 + * Jens Scharsig @ BuS Elektronik GmbH & Co. KG esw@bus-elektronik.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 + */ + +#undef CFG_I2C_DEBUG +#include <common.h> + +DECLARE_GLOBAL_DATA_PTR; + +#ifdef CONFIG_HARD_I2C + +#include <i2c.h> + +#if defined(CONFIG_M5280) || defined(CONFIG_M5281) || defined(CONFIG_M5282) + +#include <asm/m5282.h> + + +unsigned short MCFI2C_Divider[0x40] = { 28, 30, 34, 30, 44, 48, 56, 68, + 80, 88, 104, 128, 144, 160, 192, 240, + 288, 320, 384, 480, 576, 640, 768, 960, + 1152,1280,1536,1920,2304,2560,3072,3840, + 20, 22, 24, 26, 28, 32, 36, 40, + 48, 56, 64, 72, 80, 96, 112, 128, + 160, 192, 224, 256, 320, 384, 448, 512, + 640, 768, 896,1024,1280,1536,1792,2048}; + +#define I2C_TIMEOUT 1000 /* Milliseconds */ + +/***************************************************************************** +****f* i2c/i2c_init +*** +******************************************************************************/ + +void i2c_init(int speed, int slaveaddr) +{ + int fdr; + int cnt; + int actspeed; + int calcspeed; + + /* Search Clock Divider for real speed near speed */ + + fdr=0x1F; + actspeed=CFG_CLK / MCFI2C_Divider[fdr]; + + for (cnt=0;cnt<=0x3F;cnt++) + { + calcspeed = CFG_CLK / MCFI2C_Divider[cnt]; + if ((actspeed < calcspeed) && (calcspeed <= speed)) + { + fdr = cnt; + actspeed=calcspeed; + } + } + if (gd->flags & GD_FLG_RELOC) { + } + else + { + printf("Speed %d Hz ",actspeed,speed); + } + + MCFI2C_I2ADR = CFG_I2C_SLAVE; + + MCFI2C_I2FDR = MCFI2C_I2FDR_IC(fdr); + + MCFI2C_I2CR = MCFI2C_I2CR_IEN; + + MCFGPIO_PASPAR |= 0x0F; /* PAS0 and PAS1 as I2C Port */ + + + if (MCFI2C_I2SR & MCFI2C_I2SR_IBB) + { + MCFI2C_I2CR = 0; + MCFI2C_I2CR = 0xA0; + cnt = MCFI2C_I2DR; + MCFI2C_I2SR = 0; + MCFI2C_I2CR = 0; + MCFGPIO_PASPAR &= ~0x0F; + + MCFGPIO_CLRAS = ~0x01; + MCFGPIO_DDRAS |= 0x01; + for (cnt=0;cnt<=9;cnt++) + { + MCFGPIO_CLRAS = 0xFE; + udelay(10); + MCFGPIO_SETAS = 0x01; + udelay(10); + } + MCFGPIO_PASPAR |= 0x0F; /* PAS0 and PAS1 as I2C Port */ + MCFI2C_I2CR = MCFI2C_I2CR_IEN; + }; + +} + +/***************************************************************************** + ****f* i2c/i2c_waitidle + * FUNCTION + * Waits while I2C-Bus is busy + * RESULT + * >1, if I2C-Bus is idle , 0 Timeout + *** +******************************************************************************/ + +int i2c_waitidle(void) +{ + int timeout; + timeout = I2C_TIMEOUT*100; + while ((MCFI2C_I2SR & MCFI2C_I2SR_IBB) && (timeout>0)) + { + #ifdef CFG_I2C_DEBUG + printf("i",MCFI2C_I2SR); + #endif + timeout--; + udelay(10); + } + if (timeout==0) + { + printf("I2C Error: Bus idle timeout\n"); + } + return timeout; +} + +/***************************************************************************** + ****f* i2c/i2c_waitbusy + * FUNCTION + * Waits until I2C-Bus is busy + * RESULT + * >1, if I2C-Bus is busy , 0 Timeout + *** +******************************************************************************/ + +int i2c_waitbusy(void) +{ + int timeout; + timeout = I2C_TIMEOUT * 100; + while ((!(MCFI2C_I2SR & MCFI2C_I2SR_IBB)) && (timeout>0)) + { + #ifdef CFG_I2C_DEBUG + printf("b",MCFI2C_I2SR); + #endif + timeout--; + udelay(10); + } + if (timeout==0) + { + printf("I2C Error: Bus busy timeout\n"); + } + return timeout; +} + +/***************************************************************************** + ****f* i2c/i2c_start + * FUNCTION + * generates a stop condition + * RESULT + * 0 = sucess, >1 = error + *** +******************************************************************************/ + +int i2c_stop(void) +{ + MCFI2C_I2CR &= ~MCFI2C_I2CR_MSTA; + #ifdef CFG_I2C_DEBUG + printf(" Stop \n"); + #endif + return 0; +} + +/***************************************************************************** + ****f* i2c/i2c_datacomplete + * FUNCTION + * Waits until data transfer is complete + * RESULT + * >1, if data transfer is complete , 0 Timeout + *** +******************************************************************************/ + +int i2c_datacomplete(void) +{ + int timeout; + timeout = I2C_TIMEOUT*100; + while ((!(MCFI2C_I2SR & MCFI2C_I2SR_IIF)) && (timeout>0)) + { + #ifdef CFG_I2C_DEBUG + printf("d",MCFI2C_I2SR); + #endif + timeout--; + udelay(10); + } + MCFI2C_I2SR &= ~MCFI2C_I2SR_IIF; + + if (timeout==0) + { + printf("I2C Error: data transfer complete timeout\n"); + } + if (((MCFI2C_I2SR & MCFI2C_I2SR_RXAK)) && (MCFI2C_I2CR & MCFI2C_I2CR_MTX)) + { + #ifdef CFG_I2C_DEBUG + printf("RX_NACK",MCFI2C_I2SR); + #endif + timeout=0; + i2c_stop(); + } + return timeout; +} + +/***************************************************************************** + ****f* i2c/i2c_start + * FUNCTION + * generates a start condition and send the chip address + * PARAMETERS + * uchar chip - chip address + * uchar readdata - set to start a read opperation + * RESULT + * 0 = sucess, >1 = error + *** +******************************************************************************/ + +int i2c_start(uchar chip, uchar readdata) +{ + int error; + #ifdef CFG_I2C_DEBUG + printf("Start 0x%2.2x ",chip); + #endif + MCFI2C_I2CR |= MCFI2C_I2CR_MSTA | MCFI2C_I2CR_MTX; + if (readdata) + { + MCFI2C_I2DR = MCFI2C_I2ADR_ADDR(chip) | 0x01; + } + else + { + MCFI2C_I2DR = MCFI2C_I2ADR_ADDR(chip); + } + error = 1; + if (i2c_waitbusy()) + { + if (i2c_datacomplete()) + { + #ifdef CFG_I2C_DEBUG + printf("Address send\n"); + #endif + error=0; + } + } + return error; +} + +/***************************************************************************** + ****f* i2c/i2c_restart + * FUNCTION + * generates a restart condition and send the chip address + * PARAMETERS + * uchar chip - chip address + * uchar readdata - set to start a read opperation + * RESULT + * 0 = sucess, >1 = error + *** +******************************************************************************/ + +int i2c_restart(uchar chip, uchar readdata) +{ + int error; + MCFI2C_I2CR |= MCFI2C_I2CR_MSTA | MCFI2C_I2CR_RSTA; + if (readdata) + { + MCFI2C_I2DR = MCFI2C_I2ADR_ADDR(chip) | 0x01; + } + else + { + MCFI2C_I2DR = MCFI2C_I2ADR_ADDR(chip); + } + error = 1; + if (i2c_waitbusy()) + { + if (i2c_datacomplete()) + { + #ifdef CFG_I2C_DEBUG + printf("Address send\n"); + #endif + error=0; + } + } + return error; +} + +/***************************************************************************** + ****f* i2c/i2c_receive + * FUNCTION + * receives n Bytes from I2C Device + * PARAMETERS + * char *Buffer - receive buffer + * int len - receive buffer size + * RESULT + * 0 = sucess, >1 = error + *** +******************************************************************************/ + +int i2c_receive(uchar *buffer, int len) +{ + int error; + int ptr; + error = 0; + ptr = 0; + + MCFI2C_I2CR &= ~(MCFI2C_I2CR_MTX | MCFI2C_I2CR_TXAK); + if (len==1) + { + #ifdef CFG_I2C_DEBUG + printf(" TXAK"); + #endif + MCFI2C_I2CR |= MCFI2C_I2CR_TXAK; + } + buffer[0] = MCFI2C_I2DR; + #ifdef CFG_I2C_DEBUG + printf(" dummy"); + #endif + + while ((len>0) && (error == 0)) + { + if (i2c_datacomplete()) + { + if (len==2) + { + #ifdef CFG_I2C_DEBUG + printf(" TXAK"); + #endif + MCFI2C_I2CR |= MCFI2C_I2CR_TXAK; + } + if (len==1) + { + i2c_stop(); + } + buffer[ptr] = MCFI2C_I2DR; + #ifdef CFG_I2C_DEBUG + printf(" %2.2x",(uchar) buffer[ptr]); + #endif + ptr++; + len--; + } + else + { + error = 1; + } + } + return error; +} + +/***************************************************************************** + ****f* i2c/i2c_send + * FUNCTION + * sends n Bytes to I2C Device + * PARAMETERS + * char *Buffer - send buffer + * int len - send buffer size + * RESULT + * 0 = sucess, >1 = error + *** +******************************************************************************/ + +int i2c_send(uchar *buffer, int len) +{ + int error; + int ptr; + error = 0; + ptr = 0; + while ((len>0) && (error == 0)) + { + #ifdef CFG_I2C_DEBUG + printf(" 0x%2.2x ",buffer[ptr]); + #endif + MCFI2C_I2DR = buffer[ptr]; + ptr++; + len--; + if (!(i2c_datacomplete())) error = 1; + } + return error; +} + +/* + * Probe the given I2C chip address. Returns 0 if a chip responded, + * not 0 on failure. + */ +int i2c_probe(uchar chip) +{ + int result; + uchar buffer[2]; + result=1; + if (chip != CFG_I2C_SLAVE) + { + if (i2c_waitidle()) + { + if (!i2c_start(chip,1)) + { + if (!i2c_receive(&buffer[0],1)) + { + result=0; + } + } + } + } + return result; +} + +/* + * Read interface: + * chip: I2C chip address, range 0..127 + * addr: Memory (register) address within the chip + * alen: Number of bytes to use for addr (typically 1, 2 for larger + * memories, 0 for register type devices with only one + * register) + * buffer: Where to read/write the data + * len: How many bytes to read/write + * + * Returns: 0 on success, not 0 on failure + */ + +int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) +{ + uchar bufaddr[2]; + int error; + + error=0; + #ifdef CFG_I2C_DEBUG + printf("I2C_Read"); + printf(" 0x%2.2x ",addr); + #endif + if (i2c_waitidle()) + { + while (MCFI2C_I2SR & MCFI2C_I2SR_IBB); + + bufaddr[0] = (addr >>8) & 0xFF; + bufaddr[1] = addr & 0xFF; + + error |= i2c_start(chip,0); + #ifdef CFG_I2C_DEBUG + printf("\nI2C_Read"); + #endif + switch (alen) + { + case 0: + #ifdef CFG_I2C_DEBUG + printf(" no address"); + #endif + break; + case 1: + #ifdef CFG_I2C_DEBUG + printf(" byte address"); + #endif + error |= i2c_send(&bufaddr[1],1); + break; + case 2: + #ifdef CFG_I2C_DEBUG + printf(" word address"); + #endif + error |= i2c_send(&bufaddr[0],2); + break; + default: + printf("Address length %d not supported\n",alen); + error=1; + } + #ifdef CFG_I2C_DEBUG + printf("\nI2C_Read Restart"); + #endif + error |= i2c_restart(chip,1); + #ifdef CFG_I2C_DEBUG + printf("\nI2C_Read Receive"); + #endif + error |= i2c_receive(buffer,len); + } + else + { + error=1; + } + return error; +} + +/* + * Write interface: + * chip: I2C chip address, range 0..127 + * addr: Memory (register) address within the chip + * alen: Number of bytes to use for addr (typically 1, 2 for larger + * memories, 0 for register type devices with only one + * register) + * buffer: Where to read/write the data + * len: How many bytes to read/write + * + * Returns: 0 on success, not 0 on failure + */ + +int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) +{ + uchar bufaddr[2]; + int error; + + error=0; + #ifdef CFG_I2C_DEBUG + printf("I2C_Write 0x%2.2x@0x%2.2x ",addr,chip); + #endif + if (i2c_waitidle()) + { + bufaddr[0] = (addr >>8) & 0xFF; + bufaddr[1] = addr & 0xFF; + + error |= i2c_start(chip,0); + #ifdef CFG_I2C_DEBUG + printf("\nI2C_Write"); + #endif + switch (alen) + { + case 0: + #ifdef CFG_I2C_DEBUG + printf(" no address"); + #endif + break; + case 1: + #ifdef CFG_I2C_DEBUG + printf(" byte address"); + #endif + error |= i2c_send(&bufaddr[1],1); + break; + case 2: + #ifdef CFG_I2C_DEBUG + printf(" word address"); + #endif + error |= i2c_send(&bufaddr[0],2); + break; + default: + printf("Address length %d not supported\n",alen); + error=1; + } + #ifdef CFG_I2C_DEBUG + printf("\nI2C_Read Receive"); + #endif + error |= i2c_send(buffer,len); + error |= i2c_stop(); + } + else + { + error = 1; + } + return error; +} + +/* + * Utility routines to read/write registers. + */ + +#else + #error Hard I2C not implementetd for this CPU +#endif + +uchar i2c_reg_read(uchar chip, uchar reg) +{ + uchar buf; + + #ifdef CFG_I2C_DEBUG + printf("Reg_Read: 0x%2.2x ",reg); + #endif + i2c_read(chip, reg, 1, &buf, 1); + + return buf; +} + +void i2c_reg_write(uchar chip, uchar reg, uchar val) +{ + #ifdef CFG_I2C_DEBUG + printf("Reg_Write: 0x%2.2x ",reg); + #endif + i2c_write(chip, reg, 1, &val, 1); + + return; +} + +#endif + +/* EOF */
diff --git a/cpu/mcf52x2/interrupts.c b/cpu/mcf52x2/interrupts.c index 116747a..7d0aaad 100644 --- a/cpu/mcf52x2/interrupts.c +++ b/cpu/mcf52x2/interrupts.c @@ -46,9 +46,11 @@ #include <asm/m5249.h> #endif
- +#ifdef CONFIG_M5282 +#define NR_IRQS 256 +#else #define NR_IRQS 31 - +#endif /* * Interrupt vector functions. */ @@ -179,6 +181,7 @@ int interrupt_init (void) #if defined(CONFIG_M5282) || defined(CONFIG_M5271) int interrupt_init (void) { + enable_interrupts (); return 0; } #endif
diff --git a/lib_m68k/time.c b/lib_m68k/time.c index d45e470..3029949 100644 --- a/lib_m68k/time.c +++ b/lib_m68k/time.c @@ -141,6 +141,17 @@ void udelay(unsigned long usec)
timerp = (volatile unsigned short *) (CFG_MBAR + MCFTIMER_BASE3);
+#if CFG_CLK>=20000000 + usec = (usec * (CFG_CLK / 1000000)) >> 1; +#else + usec = usec * (2000000 / CFG_CLK); +#endif + /* Set up TIMER 3 as timebase clock */ + timerp[MCFTIMER_PCSR] = MCFTIMER_PCSR_OVW; + timerp[MCFTIMER_PMR] = 0; + /* set period to 2/Clock */ + timerp[MCFTIMER_PCSR] = (0<<8) | MCFTIMER_PCSR_EN | MCFTIMER_PCSR_OVW | + MCFTIMER_PCSR_PIF; while (usec > 0) { if (usec > 65000) tmp = 65000; @@ -148,18 +159,62 @@ void udelay(unsigned long usec) tmp = usec; usec = usec - tmp;
- /* Set up TIMER 3 as timebase clock */ - timerp[MCFTIMER_PCSR] = MCFTIMER_PCSR_OVW; - timerp[MCFTIMER_PMR] = 0; - /* set period to 1 us */ - timerp[MCFTIMER_PCSR] = - (5 << 8) | MCFTIMER_PCSR_EN | MCFTIMER_PCSR_OVW;
timerp[MCFTIMER_PMR] = tmp; - while (timerp[MCFTIMER_PCNTR] > 0); + while ((timerp[MCFTIMER_PCSR] & MCFTIMER_PCSR_PIF) == 0); + timerp[MCFTIMER_PCSR] |= MCFTIMER_PCSR_PIF; } }
+#if CFG_HZ == 1000 + +void timer_isr (void * not_used) +{ + volatile unsigned short *timerp; + timerp = (volatile unsigned short *) (CFG_MBAR + MCFTIMER_BASE4); + timerp[MCFTIMER_PCSR] |= MCFTIMER_PCSR_PIF; + timestamp++; +} + +void timer_init (void) +{ + volatile unsigned short *timerp; +#if (CFG_CLK/2000) <65000 + #define TI_PMR CFG_CLK/2000 + #define TI_PRE 0 +#else + #define TI_PMR CFG_CLK/4000 + #define TI_PRE 1 +#endif + + timerp = (volatile unsigned short *) (CFG_MBAR + MCFTIMER_BASE4); + timestamp = 0; + + irq_install_handler (MCFVECTOR_PIT3,timer_isr,0); + + /* Set up TIMER 4 as 1ms interupt event */ + timerp[MCFTIMER_PCSR] = MCFTIMER_PCSR_OVW; + timerp[MCFTIMER_PMR] = TI_PMR; + timerp[MCFTIMER_PCSR] = (TI_PRE << 8) | MCFTIMER_PCSR_RLD | + MCFTIMER_PCSR_EN | MCFTIMER_PCSR_OVW | + MCFTIMER_PCSR_PIF | MCFTIMER_PCSR_PIE; + + MCFICM_ICR_PIT3 = (3<<MCFICM_ICR_IL) | (3<<MCFICM_ICR_IP); + + MCFICM_IMRH0 &= ~MCFICM_IMRH0_PIT3; +} + +void set_timer (ulong t) +{ + timestamp = t; +} + +ulong get_timer (ulong base) +{ + return timestamp - base; +} + +#else void timer_init (void) { volatile unsigned short *timerp; @@ -202,8 +257,9 @@ void wait_ticks (unsigned long ticks) set_timer (0); while (get_timer (0) < ticks); } -#endif +#endif /* CFG_HZ=1000 */
+#endif /* defined(CONFIG_M5282) || defined(CONFIG_M5271) */
#if defined(CONFIG_M5249) /*
diff --git a/cpu/mcf52x2/cpu.c b/cpu/mcf52x2/cpu.c index aa6b2bd..486ebfa 100644 --- a/cpu/mcf52x2/cpu.c +++ b/cpu/mcf52x2/cpu.c @@ -159,7 +159,7 @@ int watchdog_init (void) #endif /* #ifdef CONFIG_M5272 */
-#ifdef CONFIG_M5282 +#ifdef CONFIG_M5282 int checkcpu (void) { unsigned char resetsource = MCFRESET_RSR; @@ -183,7 +183,41 @@ int do_reset (cmd_tbl_t *cmdtp, bd_t *bd MCFRESET_RCR = MCFRESET_RCR_SOFTRST; return 0; }; -#endif + +#if defined(CONFIG_WATCHDOG) +void watchdog_reset (void) +{ + MCFWTM_WSR=0x5555; + MCFWTM_WSR=0xAAAA; +} + +int watchdog_disable (void) +{ + /* MCF5282 doen't allow reconfigure WDT */ + return (0); +} + +int watchdog_init (void) +{ + int enable; + char *s; + enable=MCFWTM_WCR_EN; + /* prevent enable if environment is set watchdog=off + MCF5282 doen't allow reconfigure WDT + */ + if ((s = getenv ("watchdog")) != NULL) + { + if ((strncmp (s, "off", 3) == 0) || (strncmp (s, "0", 1) == 0)) + { + enable=0; + } + } + MCFWTM_WCR=enable; + return (0); +} +#endif /* #ifdef CONFIG_WATCHDOG */ + +#endif /* endif CONFIG_M5282 */
#ifdef CONFIG_M5249 /* test-only: todo... */ int checkcpu (void)
participants (1)
-
Jens Scharsig