extensions.
* Moved EEPROM code to common directory (cmd_eeprom.c); eliminnated
board specific EEPROM code from a couple of board configurations.
* Moved code for software-I2C from board specific to CPU specific
directory as general alternative for hardware supported code.
Sorry, we have several different interfaces to I2C code right now;
ideally, the hardware supported code should be simplified /
rewritten so that the software and hardware versions become drop-in
replacements for each other.
Modifications for 0.9.0:
======================================================================
+* Added generic interface for board dependend spacial command
+ extensions.
+
+* Moved EEPROM code to common directory (cmd_eeprom.c); eliminnated
+ board specific EEPROM code from a couple of board configurations.
+
+* Moved code for software-I2C from board specific to CPU specific
+ directory as general alternative for hardware supported code.
+ Sorry, we have several different interfaces to I2C code right now;
+ ideally, the hardware supported code should be simplified /
+ rewritten so that the software and hardware versions become drop-in
+ replacements for each other.
+
* Cleanup of 8xx specific #includes, Makefiles, ...
* Fix console on SCC3 for MPC850 systems
FADS823 FADS850SAR FADS860T ADS860 \
cogent_mpc8xx \
GENIETV \
- MBX \
+ MBX MBX860T \
RPXlite \
GTH \
"
-# MBX860T disabled for now, file `include/config_MBX860T.h' is missing
-
#########################################################################
## PPC4xx Systems
#########################################################################
# load other configuration
include $(TOPDIR)/config.mk
-SUBDIRS = tools $(ARCH) cpu/$(CPU) board/$(BOARD) common net disk examples
+SUBDIRS = tools \
+ $(ARCH) \
+ cpu/$(CPU) \
+ board/$(BOARD) \
+ common \
+ net \
+ disk \
+ rtc \
+ examples
#########################################################################
# ppcboot objects....order is important (i.e. start must be first)
OBJS = cpu/$(CPU)/start.o \
common/libcommon.a
-OBJS += net/libnet.a disk/libdisk.a
+OBJS += net/libnet.a disk/libdisk.a rtc/librtc.a
OBJS += board/$(BOARD)/lib$(BOARD).a \
cpu/$(CPU)/lib$(CPU).a \
echo "CPU = mpc8xx" >>config.mk ; \
echo "#include <config_$(@:_config=).h>" >config.h
-MBX_config: unconfig
- @echo "Configuring for $(@:_config=) Board..." ; \
- cd include ; \
- echo "ARCH = ppc" > config.mk ; \
- echo "BOARD = mbx8xx" >>config.mk ; \
- echo "CPU = mpc8xx" >>config.mk ; \
- echo "#include <config_$(@:_config=).h>" >config.h
-
+MBX_config \
MBX860T_config: unconfig
@echo "Configuring for $(@:_config=) Board..." ; \
cd include ; \
echo "ARCH = ppc" > config.mk ; \
- echo "BOARD = mbx" >>config.mk ; \
+ echo "BOARD = mbx8xx" >>config.mk ; \
echo "CPU = mpc8xx" >>config.mk ; \
echo "#include <config_$(@:_config=).h>" >config.h
LIB = lib$(BOARD).a
-OBJS = $(BOARD).o flash.o eeprom.o
+OBJS = $(BOARD).o flash.o
SOBJS = init.o
$(LIB): $(OBJS) $(SOBJS)
+++ /dev/null
-/*
- * (C) Copyright 2000
- * 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 <ppcboot.h>
-#include "canbt.h"
-#include <asm/processor.h>
-#include <405gp_i2c.h>
-
-/* i2c eeprom access */
-#ifdef CFG_ENV_IS_IN_EEPROM
-/*-----------------------------------------------------------------------
- */
-void eeprom_init (void)
-{
- /* nothing to be done here ! */
-}
-
-/*-----------------------------------------------------------------------
- *
- * for CONFIG_I2C_X defined (16-bit EEPROM address) offset is
- * 0x000nxxxx for EEPROM address selectors at n, offset xxxx in EEPROM.
- * --> this is not supported on the CPCI405 board <--
- *
- * for CONFIG_I2C_X not defined (8-bit EEPROM page address) offset is
- * 0x00000nxx for EEPROM address selectors and page number at n.
- */
-void eeprom_read (unsigned offset, uchar *buffer, unsigned cnt)
-{
- unsigned i, blk_off, blk_num;
- unsigned char dataout[1];
-
-#ifdef CONFIG_I2C_X
-#error "CONFIG_I2C_X not supported by this target"
-#else
-
- for (i=0;i<cnt;i++)
- {
- blk_num = (offset+i) >> 8;
- blk_off = (offset+i) & 0xFF;
- dataout[0] = blk_off;
-
- i2c_send(EEPROM_WRITE_ADDRESS | (blk_num << 1),1,dataout);
- i2c_receive(EEPROM_READ_ADDRESS | (blk_num << 1),1,&buffer[i]);
- }
-
-#endif /* CONFIG_I2C_X */
-}
-
-/*-----------------------------------------------------------------------
- *
- * for CONFIG_I2C_X defined (16-bit EEPROM address) offset is
- * 0x000nxxxx for EEPROM address selectors at n, offset xxxx in EEPROM.
- *
- * for CONFIG_I2C_X not defined (8-bit EEPROM page address) offset is
- * 0x00000nxx for EEPROM address selectors and page number at n.
- */
-void eeprom_write (unsigned offset, uchar *buffer, unsigned cnt)
-{
- unsigned i,blk_off, blk_num;
- unsigned char dataout[2];
-#ifdef CONFIG_I2C_X
-#error "CONFIG_I2C_X not supported by this target"
-#else
- blk_num = (offset + i) >> 8;
- blk_off = (offset + i) & 0xFF;
-
- for (i=0;i<cnt;i++)
- {
- blk_num = (offset+i) >> 8;
- blk_off = (offset+i) & 0xFF;
-
- dataout[0]=blk_off;
- dataout[1]=buffer[i];
-
- /* write with ack polling */
- while (i2c_send(EEPROM_WRITE_ADDRESS | (blk_num << 1),2,dataout) != 0)
- udelay(500);
- }
-
-#endif /* CONFIG_I2C_X */
-}
-#endif /* CFG_ENV_IS_IN_EEPROM */
LIB = lib$(BOARD).a
-OBJS = $(BOARD).o flash.o eeprom.o
+OBJS = $(BOARD).o flash.o
SOBJS = init.o
$(LIB): $(OBJS) $(SOBJS)
+++ /dev/null
-/*
- * (C) Copyright 2000
- * 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 <ppcboot.h>
-#include "cpci405.h"
-#include <asm/processor.h>
-#include <405gp_i2c.h>
-
-/* i2c eeprom access */
-#ifdef CFG_ENV_IS_IN_EEPROM
-/*-----------------------------------------------------------------------
- */
-void eeprom_init (void)
-{
- /* nothing to be done here ! */
-}
-
-/*-----------------------------------------------------------------------
- *
- * for CONFIG_I2C_X defined (16-bit EEPROM address) offset is
- * 0x000nxxxx for EEPROM address selectors at n, offset xxxx in EEPROM.
- * --> this is not supported on the CPCI405 board <--
- *
- * for CONFIG_I2C_X not defined (8-bit EEPROM page address) offset is
- * 0x00000nxx for EEPROM address selectors and page number at n.
- */
-void eeprom_read (unsigned offset, uchar *buffer, unsigned cnt)
-{
- unsigned i, blk_off, blk_num;
- unsigned char dataout[1];
-
-#ifdef CONFIG_I2C_X
-#error "CONFIG_I2C_X not supported by this target"
-#else
-
- for (i=0;i<cnt;i++)
- {
- blk_num = (offset+i) >> 8;
- blk_off = (offset+i) & 0xFF;
- dataout[0] = blk_off;
-
- i2c_send(EEPROM_WRITE_ADDRESS | (blk_num << 1),1,dataout);
- i2c_receive(EEPROM_READ_ADDRESS | (blk_num << 1),1,&buffer[i]);
- }
-
-#endif /* CONFIG_I2C_X */
-}
-
-/*-----------------------------------------------------------------------
- *
- * for CONFIG_I2C_X defined (16-bit EEPROM address) offset is
- * 0x000nxxxx for EEPROM address selectors at n, offset xxxx in EEPROM.
- *
- * for CONFIG_I2C_X not defined (8-bit EEPROM page address) offset is
- * 0x00000nxx for EEPROM address selectors and page number at n.
- */
-void eeprom_write (unsigned offset, uchar *buffer, unsigned cnt)
-{
- unsigned i,blk_off, blk_num;
- unsigned char dataout[2];
-#ifdef CONFIG_I2C_X
-#error "CONFIG_I2C_X not supported by this target"
-#else
- blk_num = (offset + i) >> 8;
- blk_off = (offset + i) & 0xFF;
-
- for (i=0;i<cnt;i++)
- {
- blk_num = (offset+i) >> 8;
- blk_off = (offset+i) & 0xFF;
-
- dataout[0]=blk_off;
- dataout[1]=buffer[i];
-
- /* write with ack polling */
- while (i2c_send(EEPROM_WRITE_ADDRESS | (blk_num << 1),2,dataout) != 0)
- udelay(500);
- }
-
-#endif /* CONFIG_I2C_X */
-}
-#endif /* CFG_ENV_IS_IN_EEPROM */
-/*-----------------------------------------------------------------------
- */
LIB = lib$(BOARD).a
-OBJS = $(BOARD).o flash.o eeprom.o
+OBJS = $(BOARD).o flash.o
SOBJS = init.o
$(LIB): $(OBJS) $(SOBJS)
+++ /dev/null
-/*
- * (C) Copyright 2000
- * 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 <ppcboot.h>
-#include "cpciiser4.h"
-#include <asm/processor.h>
-#include <405gp_i2c.h>
-
-/* i2c eeprom access */
-#ifdef CFG_ENV_IS_IN_EEPROM
-/*-----------------------------------------------------------------------
- */
-void eeprom_init (void)
-{
- /* nothing to be done here ! */
-}
-
-/*-----------------------------------------------------------------------
- *
- * for CONFIG_I2C_X defined (16-bit EEPROM address) offset is
- * 0x000nxxxx for EEPROM address selectors at n, offset xxxx in EEPROM.
- * --> this is not supported on the CPCI405 board <--
- *
- * for CONFIG_I2C_X not defined (8-bit EEPROM page address) offset is
- * 0x00000nxx for EEPROM address selectors and page number at n.
- */
-void eeprom_read (unsigned offset, uchar *buffer, unsigned cnt)
-{
- unsigned i, blk_off, blk_num;
- unsigned char dataout[1];
-
-#ifdef CONFIG_I2C_X
-#error "CONFIG_I2C_X not supported by this target"
-#else
-
- for (i=0;i<cnt;i++)
- {
- blk_num = (offset+i) >> 8;
- blk_off = (offset+i) & 0xFF;
- dataout[0] = blk_off;
-
- i2c_send(EEPROM_WRITE_ADDRESS | (blk_num << 1),1,dataout);
- i2c_receive(EEPROM_READ_ADDRESS | (blk_num << 1),1,&buffer[i]);
- }
-
-#endif /* CONFIG_I2C_X */
-}
-
-/*-----------------------------------------------------------------------
- *
- * for CONFIG_I2C_X defined (16-bit EEPROM address) offset is
- * 0x000nxxxx for EEPROM address selectors at n, offset xxxx in EEPROM.
- *
- * for CONFIG_I2C_X not defined (8-bit EEPROM page address) offset is
- * 0x00000nxx for EEPROM address selectors and page number at n.
- */
-void eeprom_write (unsigned offset, uchar *buffer, unsigned cnt)
-{
- unsigned i,blk_off, blk_num;
- unsigned char dataout[2];
-#ifdef CONFIG_I2C_X
-#error "CONFIG_I2C_X not supported by this target"
-#else
- blk_num = (offset + i) >> 8;
- blk_off = (offset + i) & 0xFF;
-
- for (i=0;i<cnt;i++)
- {
- blk_num = (offset+i) >> 8;
- blk_off = (offset+i) & 0xFF;
-
- dataout[0]=blk_off;
- dataout[1]=buffer[i];
-
- /* write with ack polling */
- while (i2c_send(EEPROM_WRITE_ADDRESS | (blk_num << 1),2,dataout) != 0)
- udelay(500);
- }
-
-#endif /* CONFIG_I2C_X */
-}
-#endif /* CFG_ENV_IS_IN_EEPROM */
-/*-----------------------------------------------------------------------
- */
LIB = lib$(BOARD).a
-OBJS = $(BOARD).o flash.o eeprom.o
+OBJS = $(BOARD).o flash.o
$(LIB): .depend $(OBJS)
$(AR) crv $@ $^
LIB = lib$(BOARD).a
-OBJS = $(BOARD).o flash.o eeprom.o
+OBJS = $(BOARD).o flash.o
$(LIB): .depend $(OBJS)
$(AR) crv $@ $^
+++ /dev/null
-/*
- * (C) Copyright 2000
- * 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 <ppcboot.h>
-#include <mpc8xx.h>
-
-/*-----------------------------------------------------------------------
- * Definitions
- */
-
-#define PB_SCL 0x00000020 /* PB 26 */
-#define PB_SDA 0x00000010 /* PB 27 */
-#define I2C_ACK 0 /* PB_SDA level to ack a byte */
-#define I2C_NOACK 1 /* PB_SDA level to noack a byte */
-
-#define SET_PB_BIT(bit) do { \
- immr->im_cpm.cp_pbdir |= bit; /* output */ \
- immr->im_cpm.cp_pbdat |= bit; /* set 1 */ \
- udelay (5); \
- } while (0)
-
-#define RESET_PB_BIT(bit) do { \
- immr->im_cpm.cp_pbdir |= bit; /* output */ \
- immr->im_cpm.cp_pbdat &= ~bit; /* set 0 */ \
- udelay (5); \
- } while (0)
-
-#define RESET_PB_BIT1(bit) do { \
- immr->im_cpm.cp_pbdir |= bit; /* output */ \
- immr->im_cpm.cp_pbdat &= ~bit; /* set 0 */ \
- udelay (1); \
- } while (0)
-
-/*-----------------------------------------------------------------------
- * Functions
- */
-static void send_start (void);
-static void send_stop (void);
-static void send_ack (int);
-static void rcv_ack (void);
-static void send_data_1 (void);
-static void send_data_0 (void);
-static void read_addr (uchar dev_id, uchar addr);
-static void write_addr (uchar dev_id, uchar addr);
-static int read_bit (void);
-static uchar read_byte (int);
-static void write_byte (uchar byte);
-
-/*-----------------------------------------------------------------------
- * START: High -> Low on SDA while SCL is High
- */
-static void send_start (void)
-{
- volatile immap_t *immr = (immap_t *)CFG_IMMR;
-
- SET_PB_BIT (PB_SCL);
- RESET_PB_BIT (PB_SDA);
-}
-
-/*-----------------------------------------------------------------------
- * STOP: Low -> High on SDA while SCL is High
- */
-static void send_stop (void)
-{
- volatile immap_t *immr = (immap_t *)CFG_IMMR;
-
- RESET_PB_BIT (PB_SDA);
- SET_PB_BIT (PB_SCL);
- SET_PB_BIT (PB_SDA);
- udelay (5);
-}
-
-/*-----------------------------------------------------------------------
- * ack should be I2C_ACK or I2C_NOACK
- */
-static void send_ack (int ack)
-{
- volatile immap_t *immr = (immap_t *)CFG_IMMR;
-
- RESET_PB_BIT (PB_SCL);
- if (ack == I2C_ACK)
- RESET_PB_BIT (PB_SDA);
- else
- SET_PB_BIT (PB_SDA);
- SET_PB_BIT (PB_SCL);
- udelay (5);
- RESET_PB_BIT (PB_SCL);
-}
-
-/*-----------------------------------------------------------------------
- */
-static void rcv_ack (void)
-{
- volatile immap_t *immr = (immap_t *)CFG_IMMR;
-
- RESET_PB_BIT (PB_SCL);
-
- immr->im_cpm.cp_pbdir &= ~PB_SDA; /* input */
- udelay (10);
- while (immr->im_cpm.cp_pbdat & PB_SDA)
- ;
- udelay (5);
- SET_PB_BIT (PB_SCL);
- RESET_PB_BIT (PB_SCL);
- SET_PB_BIT (PB_SDA);
-}
-
-/*-----------------------------------------------------------------------
- */
-static void send_data_1 (void)
-{
- volatile immap_t *immr = (immap_t *)CFG_IMMR;
-
- RESET_PB_BIT1(PB_SCL);
- SET_PB_BIT (PB_SDA);
- SET_PB_BIT (PB_SCL);
-}
-
-/*-----------------------------------------------------------------------
- */
-static void send_data_0 (void)
-{
- volatile immap_t *immr = (immap_t *)CFG_IMMR;
-
- RESET_PB_BIT1(PB_SCL);
- RESET_PB_BIT (PB_SDA);
- SET_PB_BIT (PB_SCL);
-}
-
-
-/*-----------------------------------------------------------------------
- */
-static void read_addr (uchar dev_id, uchar addr)
-{
- int i;
-
- addr = ((dev_id | addr) << 1) | 0x01;
- for (i=0; i<8; ++i) {
- if (addr & 0x80) {
- send_data_1 ();
- } else {
- send_data_0 ();
- }
- addr <<= 1;
- }
-
- rcv_ack ();
-}
-
-/*-----------------------------------------------------------------------
- * addr & 0xF0 -> Device Identifier
- * addr & 0x0E -> bank_num or device address << 1
- * addr & 0x01 -> 1 = read, 0 = write
- */
-static void write_addr (uchar dev_id, uchar addr)
-{
- volatile immap_t *immr = (immap_t *)CFG_IMMR;
-
- addr = (dev_id | addr) << 1;
-
- for (;;) {
- uchar a = addr;
- uint i;
-
- send_start ();
-
- for (i=0; i<8; ++i) {
- if (a & 0x80) {
- send_data_1 ();
- } else {
- send_data_0 ();
- }
- a <<= 1;
- }
-
- RESET_PB_BIT (PB_SCL);
-
- immr->im_cpm.cp_pbdir &= ~PB_SDA; /* input */
- udelay (10);
-
- i = immr->im_cpm.cp_pbdat;
- udelay (5);
- SET_PB_BIT (PB_SCL);
- RESET_PB_BIT (PB_SCL);
- SET_PB_BIT (PB_SDA);
-
- if ((i & PB_SDA) == 0)
- break;
-
- send_stop();
- }
-}
-
-/*-----------------------------------------------------------------------
- */
-static int read_bit (void)
-{
- volatile immap_t *immr = (immap_t *)CFG_IMMR;
- int bit;
-
- RESET_PB_BIT (PB_SCL);
- SET_PB_BIT (PB_SCL);
- bit = (immr->im_cpm.cp_pbdat & PB_SDA) ? 1 : 0;
- return (bit);
-}
-
-/*-----------------------------------------------------------------------
- * if last == 0, ACK the byte so can continue reading
- * else NO ACK to end the read
- */
-static uchar read_byte (int last)
-{
- volatile immap_t *immr = (immap_t *)CFG_IMMR;
- uchar byte = 0;
- int i;
-
- immr->im_cpm.cp_pbdir &= ~PB_SDA; /* input */
- udelay (5);
-
- for (i=0; i<8; ++i) {
- byte = (byte << 1) | read_bit();
- }
- if (!last)
- send_ack (I2C_ACK);
- else
- send_ack (I2C_NOACK);
-
- return byte;
-}
-
-/*-----------------------------------------------------------------------
- */
-static void write_byte (uchar byte)
-{
- int i;
- for (i=0; i<8; ++i) {
- if (byte & 0x80) {
- send_data_1 ();
- } else {
- send_data_0 ();
- }
- byte <<= 1;
- }
- rcv_ack();
-}
-
-/*-----------------------------------------------------------------------
- */
-void eeprom_init (void)
-{
- volatile immap_t *immr = (immap_t *)CFG_IMMR;
-
- immr->im_cpm.cp_pbpar &= ~(PB_SCL | PB_SDA); /* GPIO */
- immr->im_cpm.cp_pbodr |= (PB_SCL | PB_SDA); /* Open Drain Output */
-
- RESET_PB_BIT (PB_SCL);
- RESET_PB_BIT (PB_SDA);
- SET_PB_BIT (PB_SCL);
- SET_PB_BIT (PB_SDA); /* stop condition */
- udelay (25);
-}
-
-/*-----------------------------------------------------------------------
- *
- * for CONFIG_I2C_X defined (16-bit EEPROM address) offset is
- * 0x000nxxxx for EEPROM address selectors at n, offset xxxx in EEPROM.
- *
- * for CONFIG_I2C_X not defined (8-bit EEPROM page address) offset is
- * 0x00000nxx for EEPROM address selectors and page number at n.
- */
-void eeprom_read (unsigned offset, uchar *buffer, unsigned cnt)
-{
- unsigned i, blk_off, blk_num;
- int last;
-
- i = 0;
- while (i<cnt) {
-#ifndef CONFIG_I2C_X
- blk_num = (offset + i) >> 8;
- blk_off = (offset + i) & 0xFF;
- write_addr (CFG_I2C_EEPROM_ADDR, blk_num);
- write_byte (blk_off);
-#else
- blk_num = (offset + i) >> 16; /* addr selectors */
- blk_off = (offset + i) & 0xFFFF;/* 16-bit address in EEPROM */
-
- write_addr (CFG_I2C_EEPROM_ADDR, blk_num);
- write_byte (blk_off >> 8); /* upper address octet */
- write_byte (blk_off & 0xff); /* lower address octet */
-#endif /* CONFIG_I2C_X */
-
- send_start ();
- read_addr (CFG_I2C_EEPROM_ADDR, blk_num);
-
- /* Read data until done or would cross a page boundary.
- * We must write the address again when changing pages
- * because the next page may be in a different device.
- */
- do {
- ++i;
- last = (i == cnt || ((offset + i) & 0xFF) == 0);
- *buffer++ = read_byte(last);
- } while (!last);
- send_stop ();
- }
-}
-
-/*-----------------------------------------------------------------------
- *
- * for CONFIG_I2C_X defined (16-bit EEPROM address) offset is
- * 0x000nxxxx for EEPROM address selectors at n, offset xxxx in EEPROM.
- *
- * for CONFIG_I2C_X not defined (8-bit EEPROM page address) offset is
- * 0x00000nxx for EEPROM address selectors and page number at n.
- */
-void eeprom_write (unsigned offset, uchar *buffer, unsigned cnt)
-{
- unsigned i, blk_off, blk_num;
-
- i = 0;
- while (i < cnt) {
-#ifndef CONFIG_I2C_X
- blk_num = (offset + i) >> 8;
- blk_off = (offset + i) & 0xFF;
-
- write_addr (CFG_I2C_EEPROM_ADDR, blk_num);
- write_byte (blk_off);
-#else
- blk_num = (offset + i) >> 16; /* addr selectors */
- blk_off = (offset + i) & 0xFFFF;/* 16-bit address in EEPROM */
-
- write_addr (CFG_I2C_EEPROM_ADDR, blk_num);
- write_byte (blk_off >> 8); /* upper address octet */
- write_byte (blk_off & 0xff); /* lower address octet */
-#endif /* CONFIG_I2C_X */
-
-#if defined(CFG_EEPROM_PAGE_WRITE_BITS)
-#define PAGE_OFFSET(x) ((x) & ((1 << CFG_EEPROM_PAGE_WRITE_BITS) - 1))
- /* Write data until done or would cross a write page boundary.
- * We must write the address again when changing pages
- * because the address counter only increments within a page.
- */
- do {
- write_byte (*buffer++);
- ++i;
- } while (i < cnt && PAGE_OFFSET(offset + i) != 0);
-#else
- write_byte (*buffer++);
- ++i;
-#endif
- send_stop ();
- }
-}
-
-/*-----------------------------------------------------------------------
- * Test: Enable Ethernet
- */
-uchar pic_read (uchar reg)
-{
- uchar c;
-
- eeprom_init ();
-
- write_addr (CFG_I2C_PICIO_ADDR, 0);
- write_byte (reg);
- send_start ();
- read_addr (CFG_I2C_PICIO_ADDR, 0);
- c = read_byte(1);
- send_stop ();
- return (c);
-}
-void pic_write (uchar reg, uchar val)
-{
- write_addr (CFG_I2C_PICIO_ADDR, 0);
- write_byte (reg);
- write_byte (val);
- send_stop ();
-}
-
-/*-----------------------------------------------------------------------
- * Test:
- */
-uchar x_i2c_read (uchar addr)
-{
- uchar c;
-
- eeprom_init ();
-
- send_start ();
- read_addr (addr, 0);
- c = read_byte(1);
- send_stop ();
- return (c);
-}
-
-void x_i2c_write (uchar addr, uchar val)
-{
- write_addr (addr, 0);
- write_byte (val);
- send_stop ();
-}
-
-/*-----------------------------------------------------------------------
- */
#include <ppcboot.h>
#include <mpc8xx.h>
-flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
-
#if defined(CFG_ENV_IS_IN_FLASH)
# ifndef CFG_ENV_ADDR
# define CFG_ENV_ADDR (CFG_FLASH_BASE + CFG_ENV_OFFSET)
#endif
/*---------------------------------------------------------------------*/
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
+
/*-----------------------------------------------------------------------
* Functions
*/
#include <ppcboot.h>
#include <mpc8xx.h>
#include <commproc.h>
+#include <i2c.h>
+#include <command.h>
/* ------------------------------------------------------------------------- */
memctl->memc_mamr = CFG_MAMR | MAMR_PTBE;
+ /*
+ * Final mapping:
+ */
+
+ memctl->memc_or3 = ((-size_b0) & 0xFFFF0000) | \
+ OR_CSNT_SAM | OR_G5LS | SDRAM_TIMING;
+ memctl->memc_br3 = (CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V;
+ udelay(1000);
+
return (size_b0);
}
/* ------------------------------------------------------------------------- */
-void board_postclk_init(void)
-{
-#ifdef CFG_I2C_CLOCK
- //i2c_init (CFG_I2C_CLOCK, 0xFE);
-#else
- //i2c_init (10000, 0xFE); /* play it slow but safe */
+#ifndef PB_ENET_TENA
+# define PB_ENET_TENA ((uint)0x00002000) /* PB 18 */
#endif
+
+int board_pre_init (void)
+{
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+
+ /* Disable Ethernet TENA on Port B
+ * Necessary because of pull up in COM3 port.
+ *
+ * This is just a preliminary fix, intended to turn off TENA
+ * as soon as possible to avoid noise on the network. Once
+ * I²C is running we will make sure the interface is
+ * correctly initialized.
+ */
+ immr->im_cpm.cp_pbpar &= ~PB_ENET_TENA;
+ immr->im_cpm.cp_pbodr &= ~PB_ENET_TENA;
+ immr->im_cpm.cp_pbdat &= ~PB_ENET_TENA; /* set to 0 = disabled */
+ immr->im_cpm.cp_pbdir |= PB_ENET_TENA;
+ return (0);
}
/* ------------------------------------------------------------------------- */
printf ("New PIC read: reg_61 = 0x%02x\n", c);
udelay(1000);
}
+
+/*-----------------------------------------------------------------------
+ * Board Special Commands: PIC read/write
+ */
+
+void do_pic (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+{
+ uchar reg, val;
+
+ switch (argc) {
+ case 3: /* PIC read reg */
+ if (strcmp(argv[1],"read") != 0)
+ break;
+
+ reg = simple_strtoul(argv[2], NULL, 16);
+
+ printf ("PIC read: reg %02x: %02x\n\n", reg, pic_read (reg));
+
+ return;
+ case 4: /* PIC write reg val */
+ if (strcmp(argv[1],"write") != 0)
+ break;
+
+ reg = simple_strtoul(argv[2], NULL, 16);
+ val = simple_strtoul(argv[3], NULL, 16);
+
+ printf ("PIC write: reg %02x val 0x%02x: %02x => ",
+ reg, val, pic_read (reg));
+ pic_write (reg, val);
+ printf ("%02x\n\n", pic_read (reg));
+
+ return;
+ default:
+ break;
+ }
+ printf ("Usage:\n%s\n", cmdtp->usage);
+}
+
+
+/*-----------------------------------------------------------------------
+ * Test: Enable Ethernet
+ */
+
+uchar pic_read (uchar reg)
+{
+ return (i2c_reg_read(CFG_I2C_PICIO_ADDR, reg));
+}
+
+void pic_write (uchar reg, uchar val)
+{
+ i2c_reg_write(CFG_I2C_PICIO_ADDR, reg, val);
+}
LIB = lib$(BOARD).a
-OBJS = $(BOARD).o flash.o ../ip860/eeprom.o
+OBJS = $(BOARD).o flash.o
$(LIB): .depend $(OBJS)
$(AR) crv $@ $^
endif
COBJS = board.o main.o command.o \
cmd_boot.o cmd_bootm.o cmd_cache.o \
- cmd_console.o cmd_eeprom.o cmd_flash.o \
- cmd_ide.o cmd_mem.o cmd_net.o \
+ cmd_console.o cmd_date.o cmd_eeprom.o \
+ cmd_flash.o cmd_ide.o cmd_mem.o cmd_net.o \
cmd_nvedit.o cmd_pcmcia.o cmd_reginfo.o \
s_record.o dlmalloc.o \
kgdb.o console.o lists.o devices.o flash.o cmd_i2c.o cmd_immap.o
defined(CONFIG_CANBT) || \
defined(CONFIG_WALNUT405) || \
defined(CONFIG_CPCIISER4) || \
- defined(CONFIG_ADCIOP)
+ defined(CONFIG_ADCIOP) || \
+ defined(CONFIG_LWMON)
board_pre_init(); /* very early board init code (fpga boot, etc.) */
#endif
printf (" New Stack Pointer is: %08lx\n", addr_sp);
#endif
-#if defined(CONFIG_LWMON) /* XXX move to same place as for HYMOD XXX */
- board_postclk_init(); /* XXX once debugging is no longer needed XXX */
-#endif
relocate_code (addr_sp, bd, addr_moni);
/* NOTREACHED - relocate_code() does not return */
hermes_start_lxt980((int)bd->bi_ethspeed);
#endif
-#if defined(CONFIG_SPD823TS) || \
+#if (CONFIG_COMMANDS & CFG_CMD_NET) && ( \
+ defined(CONFIG_SPD823TS) || \
defined(CONFIG_IVMS8) || \
defined(CONFIG_IVML24) || \
defined(CONFIG_IP860) || \
- defined(CONFIG_LWMON)
+ defined(CONFIG_LWMON) )
# ifdef DEBUG
puts (" Reset Ethernet PHY\n");
# endif
static void *zalloc(void *, unsigned, unsigned);
static void zfree(void *, void *, unsigned);
+#if (CONFIG_COMMANDS & CFG_CMD_IMI)
static void image_info (unsigned long addr);
+#endif
static void print_type (image_header_t *hdr);
image_header_t header;
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * 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
+ */
+
+/*
+ * RTC, Date & Time support: get and set date & time
+ */
+#include <ppcboot.h>
+#include <command.h>
+#include <rtc.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_DATE)
+
+const char *weekdays[] = {
+ "Sun", "Mon", "Tues", "Wednes", "Thurs", "Fri", "Satur",
+};
+
+int mk_date (char *, struct rtc_time *);
+
+void do_date (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+{
+ struct rtc_time tm;
+
+ switch (argc) {
+ case 2: /* set date & time */
+ if (strcmp(argv[1],"reset") == 0) {
+ printf ("Reset RTC...\n");
+ rtc_reset ();
+ } else {
+ /* initialize tm with current time */
+ rtc_get (&tm);
+ /* insert new date & time */
+ if (mk_date (argv[1], &tm) != 0) {
+ printf ("## Bad date format\n");
+ return;
+ }
+ /* and write to RTC */
+ rtc_set (&tm);
+ }
+ /* FALL TROUGH */
+ case 1: /* get date & time */
+ rtc_get (&tm);
+
+ printf ("Date: %4d-%02d-%02d (%sday) Time: %2d:%02d:%02d\n",
+ tm.tm_year, tm.tm_mon, tm.tm_mday,
+ (tm.tm_wday<0 || tm.tm_wday>6) ?
+ "unknown " : weekdays[tm.tm_wday],
+ tm.tm_hour, tm.tm_min, tm.tm_sec);
+ return;
+ default:
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ }
+}
+
+/*
+ * simple conversion of two-digit string with error checking
+ */
+static int cnvrt2 (char *str, int *valp)
+{
+ int val;
+
+ if ((*str < '0') || (*str > '9'))
+ return (-1);
+
+ val = *str - '0';
+
+ ++str;
+
+ if ((*str < '0') || (*str > '9'))
+ return (-1);
+
+ *valp = 10 * val + (*str - '0');
+
+ return (0);
+}
+
+/*
+ * Convert date string: MMDDhhmm[[CC]YY][.ss]
+ *
+ * Some basic checking for valid values is done, but this will not catch
+ * all possible error conditions.
+ */
+int mk_date (char *datestr, struct rtc_time *tmp)
+{
+ int len, val;
+ char *ptr;
+
+ ptr = strchr (datestr,'.');
+ len = strlen (datestr);
+
+ /* Set seconds */
+ if (ptr) {
+ int sec;
+
+ *ptr++ = '\0';
+ if ((len - (ptr - datestr)) != 2)
+ return (-1);
+
+ len = strlen (datestr);
+
+ if (cnvrt2 (ptr, &sec))
+ return (-1);
+
+ tmp->tm_sec = sec;
+ } else {
+ tmp->tm_sec = 0;
+ }
+
+ if (len == 12) { /* MMDDhhmmCCYY */
+ int year, century;
+
+ if (cnvrt2 (datestr+ 8, ¢ury) ||
+ cnvrt2 (datestr+10, &year) ) {
+ return (-1);
+ }
+ tmp->tm_year = 100 * century + year;
+ } else if (len == 10) { /* MMDDhhmmYY */
+ int year, century;
+
+ century = tmp->tm_year / 100;
+ if (cnvrt2 (datestr+ 8, &year))
+ return (-1);
+ tmp->tm_year = 100 * century + year;
+ }
+
+ switch (len) {
+ case 8: /* MMDDhhmm */
+ /* fall thru */
+ case 10: /* MMDDhhmmYY */
+ /* fall thru */
+ case 12: /* MMDDhhmmCCYY */
+ if (cnvrt2 (datestr+0, &val) ||
+ val > 12) {
+ break;
+ }
+ tmp->tm_mon = val;
+ if (cnvrt2 (datestr+2, &val) ||
+ val > ((tmp->tm_mon==2) ? 29 : 31)) {
+ break;
+ }
+ tmp->tm_mday = val;
+
+ if (cnvrt2 (datestr+4, &val) ||
+ val > 23) {
+ break;
+ }
+ tmp->tm_hour = val;
+
+ if (cnvrt2 (datestr+6, &val) ||
+ val > 59) {
+ break;
+ }
+ tmp->tm_min = val;
+
+ /* calculate day of week */
+ GregorianDay (tmp);
+
+ return (0);
+ default:
+ break;
+ }
+
+ return (-1);
+}
+
+#endif /* CFG_CMD_DATE */
/*
- * (C) Copyright 2000
+ * (C) Copyright 2000, 2001
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
#include <ppcboot.h>
#include <config.h>
#include <command.h>
+#include <i2c.h>
-#if (CONFIG_COMMANDS & CFG_CMD_EEPROM)
+#if (CONFIG_COMMANDS & CFG_CMD_EEPROM) || defined(CFG_ENV_IS_IN_EEPROM)
extern void eeprom_init (void);
extern void eeprom_read (unsigned offset, uchar *buffer, unsigned cnt);
extern void eeprom_write (unsigned offset, uchar *buffer, unsigned cnt);
+#endif
+
/* ------------------------------------------------------------------------- */
+#if (CONFIG_COMMANDS & CFG_CMD_EEPROM)
+
void do_eeprom (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
{
switch (argc) {
}
return;
+ }
+}
+#endif /* CFG_CMD_EEPROM */
-#ifdef CONFIG_LWMON
- case 3:
- if (strcmp(argv[1],"prd") != 0) {
- printf ("Usage:\n%s\n", cmdtp->usage);
- return;
- }
- /* fall through */
- case 4:
- if (strcmp(argv[1],"prd") == 0) {
- uchar reg = simple_strtoul(argv[2], NULL, 16);
- uchar cnt = (argc == 4) ? simple_strtoul(argv[3], NULL, 16) : 1;
-
- printf ("\nPIC read: reg %02x cnt %d:", reg, cnt);
- while (cnt) {
- printf (" %02x", pic_read (reg));
- ++reg;
- --cnt;
- }
-
- printf (" - done\n");
- return;
- } else if (strcmp(argv[1],"pwr") == 0) {
- uchar reg = simple_strtoul(argv[2], NULL, 16);
- uchar val = simple_strtoul(argv[3], NULL, 16);
+/*-----------------------------------------------------------------------
+ *
+ * for CONFIG_I2C_X defined (16-bit EEPROM address) offset is
+ * 0x000nxxxx for EEPROM address selectors at n, offset xxxx in EEPROM.
+ *
+ * for CONFIG_I2C_X not defined (8-bit EEPROM page address) offset is
+ * 0x00000nxx for EEPROM address selectors and page number at n.
+ */
- printf ("\nPIC write: reg %02x val 0x%02x: %02x => ",
- reg, val, pic_read (reg));
- pic_write (reg, val);
- printf ("%02x - done\n", pic_read (reg));
+#if (CONFIG_COMMANDS & CFG_CMD_EEPROM) || defined(CFG_ENV_IS_IN_EEPROM)
- return;
- } else {
- printf ("Usage:\n%s\n", cmdtp->usage);
+void eeprom_read (unsigned offset, uchar *buffer, unsigned cnt)
+{
+ unsigned end = offset + cnt;
+ unsigned blk_off;
+
+ /* Read data until done or would cross a page boundary.
+ * We must write the address again when changing pages
+ * because the next page may be in a different device.
+ */
+ while (offset < end) {
+ unsigned alen, len, maxlen;
+#ifndef CONFIG_I2C_X
+ uchar addr[2];
+
+ blk_off = offset & 0xFF; /* block offset */
+
+ addr[0] = offset >> 8; /* block number */
+ addr[1] = blk_off; /* block offset */
+ alen = 2;
+#else
+ uchar addr[3];
+
+ blk_off = offset & 0xFF; /* block offset */
+
+ addr[0] = offset >> 16; /* block number */
+ addr[1] = offset >> 8; /* upper address octet */
+ addr[2] = blk_off; /* lower address octet */
+ alen = 3;
+#endif /* CONFIG_I2C_X */
+
+ addr[0] |= CFG_I2C_EEPROM_ADDR; /* insert device address */
+
+ maxlen = 0x100 - blk_off;
+ len = end - offset;
+ if (len > maxlen)
+ len = maxlen;
+
+ i2c_read (addr, alen, buffer, len);
+ buffer += len;
+ offset += len;
}
+}
+
+/*-----------------------------------------------------------------------
+ *
+ * for CONFIG_I2C_X defined (16-bit EEPROM address) offset is
+ * 0x000nxxxx for EEPROM address selectors at n, offset xxxx in EEPROM.
+ *
+ * for CONFIG_I2C_X not defined (8-bit EEPROM page address) offset is
+ * 0x00000nxx for EEPROM address selectors and page number at n.
+ */
+
+void eeprom_write (unsigned offset, uchar *buffer, unsigned cnt)
+{
+ unsigned end = offset + cnt;
+ unsigned blk_off;
+
+ /* Write data until done or would cross a write page boundary.
+ * We must write the address again when changing pages
+ * because the address counter only increments within a page.
+ */
+
+ while (offset < end) {
+ unsigned alen, len, maxlen;
+#ifndef CONFIG_I2C_X
+ uchar addr[2];
+
+ blk_off = offset & 0xFF; /* block offset */
+
+ addr[0] = offset >> 8; /* block number */
+ addr[1] = blk_off; /* block offset */
+ alen = 2;
+#else
+ uchar addr[3];
+
+ blk_off = offset & 0xFF; /* block offset */
+
+ addr[0] = offset >> 16; /* block number */
+ addr[1] = offset >> 8; /* upper address octet */
+ addr[2] = blk_off; /* lower address octet */
+ alen = 3;
+#endif /* CONFIG_I2C_X */
+
+ addr[0] |= CFG_I2C_EEPROM_ADDR; /* insert device address */
+
+#if defined(CFG_EEPROM_PAGE_WRITE_BITS)
+#define PAGE_OFFSET(x) ((x) & ((1 << CFG_EEPROM_PAGE_WRITE_BITS) - 1))
+ maxlen = (1 << CFG_EEPROM_PAGE_WRITE_BITS) - \
+ (blk_off & ((1 << CFG_EEPROM_PAGE_WRITE_BITS)-1));
+#else
+ maxlen = 0x100 - blk_off;
#endif
- }
+ len = end - offset;
+ if (len > maxlen)
+ len = maxlen;
+
+ i2c_write (addr, alen, buffer, len);
+ buffer += len;
+ offset += len;
+ }
}
+/*-----------------------------------------------------------------------
+ * Set default values
+ */
+#ifndef CFG_I2C_SPEED
+#define CFG_I2C_SPEED 50000
+#endif
+
+#ifndef CFG_I2C_SLAVE
+#define CFG_I2C_SLAVE 0xFE
+#endif
+
+void eeprom_init (void)
+{
+#if defined(CONFIG_8xx)
+ i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
+#endif
+}
+/*-----------------------------------------------------------------------
+ */
#endif /* CFG_CMD_EEPROM */
#include <i2c.h>
#include <cmd_i2c.h>
-#undef I2C_DEBUG
+#define I2C_DEBUG
#ifdef I2C_DEBUG
#define PRINTF(fmt,args...) printf (fmt ,##args)
/* ------------------------------------------------------------------------- */
void
-do_i2c(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
{
unsigned char i2c_addr, sec_addr, *data_addr;
unsigned short size;
break;
case 2:
- if (strncmp(argv[1], "res", 3) == 0) {
- printf("\nI2C reset 50kHz ... ");
- i2c_init(50000, 0xfe); /* use all one's as slave address */
- printf("DONE\n");
+ if (strncmp (argv[1], "res", 3) == 0) {
+ printf ("I2C reset 50kHz ... ");
+ i2c_init (50000, 0xfe); /* use all one's as slave address */
+ printf ("DONE\n");
return;
}
break;
if (strncmp(argv[1], "res", 3) == 0) {
speed = (int)simple_strtoul(argv[2], NULL, 10);
if (speed % 1000)
- printf("\nI2C reset %d.%03dkHz ... ", speed/1000, speed%1000);
+ printf ("I2C reset %d.%03dkHz ... ", speed/1000, speed%1000);
else
- printf("\nI2C reset %dkHz ... ", speed/1000);
- i2c_init(speed, 0xfe); /* use all one's as slave address */
- printf("DONE\n");
+ printf ("I2C reset %dkHz ... ", speed/1000);
+ i2c_init (speed, 0xfe); /* use all one's as slave address */
+ printf ("DONE\n");
return;
}
break;
data_addr = (unsigned char *)simple_strtoul(argv[3], NULL, 16);
size = (unsigned short)simple_strtoul(argv[4], NULL, 16);
- printf("\nI2C recv: i2c_addr 0x%02x, data_addr 0x%08lx, "
- "size %u ... ", i2c_addr, (ulong)data_addr, size);
+ printf ("I2C recv: i2c_addr 0x%02x, data_addr 0x%08lx, "
+ "size %u ... "
+#ifdef I2C_DEBUG
+ "\n"
+#endif
+ , i2c_addr, (ulong)data_addr, size);
- i2c_newio(&state);
+ i2c_newio (&state);
- rc = i2c_receive(&state, i2c_addr, 0,
- I2CF_START_COND|I2CF_STOP_COND, size, data_addr);
+ rc = i2c_receive (&state, i2c_addr, 0,
+ I2CF_START_COND|I2CF_STOP_COND,
+ size, data_addr);
if (rc) {
- printf("FAILED (i2c_receive return code = %d)\n", rc);
+ printf ("i2c_receive FAILED rc=%d\n", rc);
return;
}
- rc = i2c_doio(&state);
+ rc = i2c_doio (&state);
if (rc) {
- printf("FAILED (i2c_doio return code = %d)\n", rc);
+ printf ("i2c_doio FAILED rc=%d\n", rc);
return;
}
- printf("DONE\n");
+ printf ("DONE\n");
return;
- }
- else if (strcmp(argv[1], "send") == 0) {
+ } else if (strcmp(argv[1], "send") == 0) {
i2c_addr = (unsigned char)simple_strtoul(argv[2], NULL, 16);
data_addr = (unsigned char *)simple_strtoul(argv[3], NULL, 16);
size = (unsigned short)simple_strtoul(argv[4], NULL, 16);
- printf("\nI2C send: i2c_addr 0x%02x, data_addr 0x%08lx, "
+ printf ("I2C send: i2c_addr 0x%02x, data_addr 0x%08lx, "
"size %u ... ", i2c_addr, (ulong)data_addr, size);
- i2c_newio(&state);
+ i2c_newio (&state);
- rc = i2c_send(&state, i2c_addr, 0,
+ rc = i2c_send (&state, i2c_addr, 0,
I2CF_START_COND|I2CF_STOP_COND, size, data_addr);
if (rc) {
- printf("FAILED (i2c_receive return code = %d)\n", rc);
+ printf ("i2c_receive FAILED rc=%d\n", rc);
return;
}
- rc = i2c_doio(&state);
+ rc = i2c_doio (&state);
if (rc) {
- printf("FAILED (i2c_doio return code = %d)\n", rc);
+ printf ("i2c_doio FAILED rc=%d\n", rc);
return;
}
- printf("DONE\n");
+ printf ("DONE\n");
return;
}
break;
data_addr = (unsigned char *)simple_strtoul(argv[4], NULL, 16);
size = (unsigned short)simple_strtoul(argv[5], NULL, 16);
- printf("\nI2C recv: i2c_addr 0x%02x, sec_addr 0x%02x, "
+ printf ("I2C recv: i2c_addr 0x%02x, sec_addr 0x%02x, "
"data_addr 0x%08lx, size %u ... ",
i2c_addr, sec_addr, (ulong)data_addr, size);
- i2c_newio(&state);
+ i2c_newio (&state);
- rc = i2c_receive(&state, i2c_addr, sec_addr,
+ rc = i2c_receive (&state, i2c_addr, sec_addr,
I2CF_ENABLE_SECONDARY|I2CF_START_COND|I2CF_STOP_COND,
size, data_addr);
if (rc) {
- printf("FAILED (i2c_receive return code = %d)\n", rc);
+ printf ("i2c_receive FAILED rc=%d\n", rc);
return;
}
- rc = i2c_doio(&state);
+ rc = i2c_doio (&state);
if (rc) {
- printf("FAILED (i2c_doio return code = %d)\n", rc);
+ printf ("i2c_doio FAILED rc=%d\n", rc);
return;
}
- printf("DONE\n");
+ printf ("DONE\n");
return;
}
else if (strcmp(argv[1], "snds") == 0) {
data_addr = (unsigned char *)simple_strtoul(argv[4], NULL, 16);
size = (unsigned short)simple_strtoul(argv[5], NULL, 16);
- printf("\nI2C send: i2c_addr 0x%02x, sec_addr 0x%02x, "
+ printf ("I2C send: i2c_addr 0x%02x, sec_addr 0x%02x, "
"data_addr 0x%08lx, size %u ... ",
i2c_addr, sec_addr, (ulong)data_addr, size);
- i2c_newio(&state);
+ i2c_newio (&state);
- rc = i2c_receive(&state, i2c_addr, sec_addr,
+ rc = i2c_receive (&state, i2c_addr, sec_addr,
I2CF_ENABLE_SECONDARY|I2CF_START_COND|I2CF_STOP_COND,
size, data_addr);
if (rc) {
- printf("FAILED (i2c_receive return code = %d)\n", rc);
+ printf ("i2c_receive FAILED rc=%d\n", rc);
return;
}
- rc = i2c_doio(&state);
+ rc = i2c_doio (&state);
if (rc) {
- printf("FAILED (i2c_doio return code = %d)\n", rc);
+ printf ("i2c_doio FAILED rc=%d\n", rc);
return;
}
- printf("DONE\n");
+ printf ("DONE\n");
return;
}
break;
break;
}
- printf("Usage:\n%s\n", cmdtp->usage);
+ printf ("Usage:\n%s\n", cmdtp->usage);
return;
}
#if defined(CONFIG_IDE_PCCARD) && defined(CONFIG_8xx)
#include <mpc8xx.h>
#endif
+#if defined(CONFIG_LWMON)
+#include <i2c.h>
+#endif
#if (CONFIG_COMMANDS & CFG_CMD_PCMCIA) || \
((CONFIG_COMMANDS & CFG_CMD_IDE) && defined(CONFIG_IDE_PCCARD))
#define MAX1604_VPPBHIZ 0x02
/* reserved 0x01 */
-extern void x_i2c_write (uchar, uchar);
-
static int hardware_enable(int slot)
{
volatile immap_t *immap;
volatile pcmconf8xx_t *pcmp;
volatile sysconf8xx_t *sysp;
uint reg, mask;
- uchar val;
+ uchar addr, val;
PCMCIA_DEBUG ("hardware_enable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
}
/* switch VCC on */
+ addr = CFG_I2C_POWER_A_ADDR;
val |= MAX1604_OP_SUS | MAX1604_VCCBON;
- x_i2c_write (CFG_I2C_POWER_A_ADDR, val);
+ i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
+ i2c_write (&addr, 1, &val, 1);
udelay(500000);
volatile immap_t *immap;
volatile pcmconf8xx_t *pcmp;
u_long reg;
+ uchar addr, val;
PCMCIA_DEBUG ("hardware_disable: " PCMCIA_BOARD_MSG " Slot %c\n", 'A'+slot);
pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
/* remove all power, put output in high impedance state */
- x_i2c_write (CFG_I2C_POWER_A_ADDR, MAX1604_VCCBHIZ | MAX1604_VPPBHIZ);
+ addr = CFG_I2C_POWER_A_ADDR;
+ val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
+ i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
+ i2c_write (&addr, 1, &val, 1);
/* Configure PCMCIA General Control Register */
PCMCIA_PGCRX(_slot_) = 0;
volatile immap_t *immap;
volatile pcmconf8xx_t *pcmp;
u_long reg;
- uchar val;
+ uchar addr, val;
PCMCIA_DEBUG ("voltage_set: " \
PCMCIA_BOARD_MSG \
* Turn off all power (switch to high impedance)
*/
PCMCIA_DEBUG ("PCMCIA power OFF\n");
- x_i2c_write (CFG_I2C_POWER_A_ADDR, MAX1604_VCCBHIZ | MAX1604_VPPBHIZ);
+ addr = CFG_I2C_POWER_A_ADDR;
+ val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
+ i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
+ i2c_write (&addr, 1, &val, 1);
val = 0;
switch(vcc) {
pcmp->pcmc_pipr,
(pcmp->pcmc_pipr & 0x00008000) ? "only 5 V" : "can do 3.3V");
- x_i2c_write (CFG_I2C_POWER_A_ADDR, val);
+ i2c_write (&addr, 1, &val, 1);
if (val) {
PCMCIA_DEBUG ("PCMCIA powered at %sV\n",
(val & MAX1604_VCC_35) ? "3.3" : "5.0");
#include <cmd_eeprom.h>
#include <cmd_i2c.h>
#include <cmd_immap.h>
+#include <cmd_rtc.h>
+
+#include <cmd_bsp.h> /* board special functions */
+
#ifdef CONFIG_HYMOD
#include <board/hymod/cmd_fpga.h>
#endif
CMD_TBL_CONINFO
CMD_TBL_IDE
CMD_TBL_PINIT
+ CMD_TBL_I2C
+ CMD_TBL_EEPROM
+ CMD_TBL_DATE
CMD_TBL_LOOP
CMD_TBL_MTEST
CMD_TBL_ICACHE
CMD_TBL_DCACHE
CMD_TBL_RESET
CMD_TBL_KGDB
- CMD_TBL_I2C
#ifdef CONFIG_HYMOD
CMD_TBL_FPGA
#endif
CMD_TBL_MUXINFO
CMD_TBL_SIINFO
CMD_TBL_MCCINFO
+#ifdef CMD_TBL_BSP /* Board Specific extensions ? */
+ CMD_TBL_BSP
+#endif
CMD_TBL_VERS
CMD_TBL_HELP
CMD_TBL_QUES
- CMD_TBL_EEPROM
-
/* the following entry terminates this table */
MK_CMD_TBL_ENTRY( NULL, 0, 0, 0, NULL, NULL, NULL )
};
PRINTD(("[I2C] txbd = %08x\n", (int)txbd));
+ if (flags & I2CF_START_COND)
+ {
PRINTD(("[I2C] Formatting addresses...\n"));
if (flags & I2CF_ENABLE_SECONDARY)
{
txbd->addr[0] = address << 1; /* Write destination address to BD */
i = 1;
}
+ }
+ else
+ i = 0;
/* set up txbd */
txbd->status = BD_SC_READY;
rxbd->length = size_to_expect;
rxbd->addr = datain;
- if (flags & I2CF_START_COND)
- txbd->status |= BD_I2C_TX_START;
+ txbd->status |= BD_I2C_TX_START;
if (flags & I2CF_STOP_COND)
{
txbd->status |= BD_SC_LAST | BD_SC_WRAP;
START = start.o kgdb.o
OBJS = traps.o serial.o cpu.o cpu_init.o speed.o \
commproc.o interrupts.o fec.o scc.o \
- i2c.o video.o wlkbd.o status_led.o
+ i2c.o soft_i2c.o video.o wlkbd.o status_led.o
all: .depend $(START) $(LIB)
volatile cbd_t *tbdf, *rbdf;
volatile cpm8xx_t *cp = &(im->im_cpm);
uint dpaddr;
+#if (SCC_INDEX != 2) || !defined(CONFIG_MPC850)
volatile iop8xx_t *ip = (iop8xx_t *)&(im->im_ioport);
+#endif
/* initialize pointers to SCC */
sp = (scc_t *) &(cp->cp_scc[SCC_INDEX]);
up = (scc_uart_t *) &cp->cp_dparam[PROFF_SCC];
+#if defined(CONFIG_LWMON) && defined(CONFIG_8xx_CONS_SCC2)
+ { /* Disable Ethernet, enable Serial */
+ uchar c;
+
+ c = pic_read (0x61);
+ c &= ~0x40; /* enable COM3 */
+ c |= 0x80; /* disable Ethernet */
+ pic_write (0x61, c);
+
+ /* enable RTS2 */
+ cp->cp_pbpar |= 0x2000;
+ cp->cp_pbdat |= 0x2000;
+ cp->cp_pbdir |= 0x2000;
+ }
+#endif /* CONFIG_LWMON */
+
/* Disable transmitter/receiver.
*/
sp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
- /* Enable SDMA.
- */
- im->im_siu_conf.sc_sdcr = 1;
-
#if (SCC_INDEX == 2) && defined(CONFIG_MPC850)
/*
* The MPC850 has SCC3 on Port B
dpaddr = CPM_SERIAL_BASE ;
#endif
+ /* Enable SDMA.
+ */
+ im->im_siu_conf.sc_sdcr = 0x0001;
+
/* Set the physical address of the host memory buffers in
* the buffer descriptors.
*/
tbdf->cbd_bufaddr = ((uint) (rbdf+2)) + 1;
tbdf->cbd_sc = 0;
+ /* Set up the baud rate generator.
+ */
+ serial_setbrg (cpu_clock, baudrate);
+
/* Set up the uart parameters in the parameter ram.
*/
up->scc_genscc.scc_rbase = dpaddr;
up->scc_genscc.scc_tbase = dpaddr+sizeof(cbd_t);
- up->scc_genscc.scc_rfcr = SCC_EB;
- up->scc_genscc.scc_tfcr = SCC_EB;
+
+ /* Initialize Tx/Rx parameters.
+ */
+ while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */
+ ;
+ cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SCC, CPM_CR_INIT_TRX) | CPM_CR_FLG;
+
+ while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */
+ ;
+
+ up->scc_genscc.scc_rfcr = SCC_EB | 0x05;
+ up->scc_genscc.scc_tfcr = SCC_EB | 0x05;
+
+ up->scc_genscc.scc_mrblr = 1; /* Single character receive */
+ up->scc_maxidl = 0; /* disable max idle */
+ up->scc_brkcr = 1; /* send one break character on stop TX */
+ up->scc_parec = 0;
+ up->scc_frmec = 0;
+ up->scc_nosec = 0;
+ up->scc_brkec = 0;
+ up->scc_uaddr1 = 0;
+ up->scc_uaddr2 = 0;
+ up->scc_toseq = 0;
+ up->scc_char1 = 0x8000;
+ up->scc_char2 = 0x8000;
+ up->scc_char3 = 0x8000;
+ up->scc_char4 = 0x8000;
+ up->scc_char5 = 0x8000;
+ up->scc_char6 = 0x8000;
+ up->scc_char7 = 0x8000;
+ up->scc_char8 = 0x8000;
+ up->scc_rccm = 0xc0ff;
+
+ /* Set low latency / small fifo.
+ */
+ sp->scc_gsmrh = SCC_GSMRH_RFW;
/* Set SCC(x) clock mode to 16x
- * Set up the baud rate generator.
* See 8xx_io/commproc.c for details.
*
* Wire BRG1 to SCCn
*/
- /* Set up the baud rate generator.
- */
-
- sp->scc_gsmrl |= (SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16);
-
- serial_setbrg (cpu_clock, baudrate);
-
- /* Set UART mode, 8 bit, no parity, one stop.
- * Enable receive and transmit.
+ /* Set UART mode, clock divider 16 on Tx and Rx
*/
- sp->scc_gsmrl |= SCC_GSMRL_MODE_UART;
+ sp->scc_gsmrl |=
+ (SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16);
+
sp->scc_psmr |= SCU_PMSR_CL;
/* Mask all interrupts and remove anything pending.
*/
sp->scc_sccm = 0;
sp->scc_scce = 0xffff;
+ sp->scc_dsr = 0x7e7e;
+ sp->scc_psmr = 0x3000;
/* Make the first buffer the only buffer.
*/
tbdf->cbd_sc |= BD_SC_WRAP;
rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
- /* Single character receive.
- */
- up->scc_genscc.scc_mrblr = 1;
- up->scc_maxidl = 0;
-
- /* Initialize Tx/Rx parameters.
- */
-
- while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */
- ;
-
- cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SCC, CPM_CR_INIT_TRX) | CPM_CR_FLG;
-
- while (cp->cp_cpcr & CPM_CR_FLG) /* wait if cp is busy */
- ;
-
/* Enable transmitter/receiver.
*/
sp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
/*
- * (C) Copyright 2000
+ * (C) Copyright 2001
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
#include <ppcboot.h>
#include <mpc8xx.h>
+#include <i2c.h>
+
+#if defined(CONFIG_SOFT_I2C)
+
+/*-----------------------------------------------------------------------
+ * Set default values
+ */
+#ifndef CFG_I2C_SPEED
+#define CFG_I2C_SPEED 50000
+#endif
+
+#ifndef CFG_I2C_SLAVE
+#define CFG_I2C_SLAVE 0xFE
+#endif
/*-----------------------------------------------------------------------
* Definitions
{
int i;
- addr = (addr << 1) | 0xA1;
+ addr = (addr << 1) | 0x01;
+
for (i=0; i<8; ++i) {
if (addr & 0x80) {
send_data_1 ();
}
/*-----------------------------------------------------------------------
- * addr & 0xF0 -> 0xA0 = Device Type Identifier
+ * addr & 0xF0 -> Device Identifier
* addr & 0x0E -> bank_num or device address << 1
* addr & 0x01 -> 1 = read, 0 = write
*/
{
volatile immap_t *immr = (immap_t *)CFG_IMMR;
- addr = (addr << 1) | 0xA0;
+ addr <<= 1;
for (;;) {
uchar a = addr;
for (i=0; i<8; ++i) {
byte = (byte << 1) | read_bit();
}
- if (!last)
- send_ack (I2C_ACK);
- else
- send_ack (I2C_NOACK);
+ send_ack (last ? I2C_NOACK : I2C_ACK);
return byte;
}
rcv_ack();
}
+/*=====================================================================*/
+/*=====================================================================*/
+
/*-----------------------------------------------------------------------
+ * `speed' and `slaveaddr' not implemented
*/
-void eeprom_init (void)
+void i2c_init (int speed, int slaveaddr)
{
volatile immap_t *immr = (immap_t *)CFG_IMMR;
/*-----------------------------------------------------------------------
*
- * for CONFIG_I2C_X defined (16-bit EEPROM address) offset is
- * 0x000nxxxx for EEPROM address selectors at n, offset xxxx in EEPROM.
- *
- * for CONFIG_I2C_X not defined (8-bit EEPROM page address) offset is
- * 0x00000nxx for EEPROM address selectors and page number at n.
+ * addr: Array of address bytes; for instance, to read from
+ * EEPROM with 8 bit page addresses you have to write 2
+ * address bytes: the block number, and the block
+ * offset.
+ * alen: Number of address bytes in "addr"
+ * buffer: where to store the read data in
+ * len: number of bytes to read
+ * Warning: it is expected that the device is really
+ * capable of reading `len' sequential bytes; no
+ * checking is doen here
*/
-void eeprom_read (unsigned offset, uchar *buffer, unsigned cnt)
+void i2c_read (uchar *addr, int alen, uchar *buffer, int len)
{
- unsigned i, blk_off, blk_num;
- int last;
-
- i = 0;
- while (i<cnt) {
-#ifndef CONFIG_I2C_X
- blk_num = (offset + i) >> 8;
- blk_off = (offset + i) & 0xFF;
- write_addr (blk_num);
- write_byte (blk_off);
-#else
- blk_num = (offset + i) >> 16; /* addr selectors */
- blk_off = (offset + i) & 0xFFFF;/* 16-bit address in EEPROM */
-
- write_addr (blk_num);
- write_byte (blk_off >> 8); /* upper address octet */
- write_byte (blk_off & 0xff); /* lower address octet */
-#endif /* CONFIG_I2C_X */
+ uchar *ap = addr;
- send_start ();
- read_addr (blk_num);
-
- /* Read data until done or would cross a page boundary.
- * We must write the address again when changing pages
- * because the next page may be in a different device.
- */
- do {
- ++i;
- last = (i == cnt || ((offset + i) & 0xFF) == 0);
- *buffer++ = read_byte(last);
- } while (!last);
- send_stop ();
+ write_addr (*ap);
+ while (--alen > 0) {
+ write_byte (*++ap);
+ }
+ send_start ();
+
+ read_addr (*addr);
+ while (len-- > 0) {
+ *buffer++ = read_byte (len==0);
}
+ send_stop ();
}
-/*-----------------------------------------------------------------------
- *
- * for CONFIG_I2C_X defined (16-bit EEPROM address) offset is
- * 0x000nxxxx for EEPROM address selectors at n, offset xxxx in EEPROM.
- *
- * for CONFIG_I2C_X not defined (8-bit EEPROM page address) offset is
- * 0x00000nxx for EEPROM address selectors and page number at n.
- */
-void eeprom_write (unsigned offset, uchar *buffer, unsigned cnt)
+void i2c_write (uchar *addr, int alen, uchar *buffer, int len)
{
- unsigned i, blk_off, blk_num;
-
- i = 0;
- while (i < cnt) {
-#ifndef CONFIG_I2C_X
- blk_num = (offset + i) >> 8;
- blk_off = (offset + i) & 0xFF;
-
- write_addr (blk_num);
- write_byte (blk_off);
-#else
- blk_num = (offset + i) >> 16; /* addr selectors */
- blk_off = (offset + i) & 0xFFFF;/* 16-bit address in EEPROM */
-
- write_addr (blk_num);
- write_byte (blk_off >> 8); /* upper address octet */
- write_byte (blk_off & 0xff); /* lower address octet */
-#endif /* CONFIG_I2C_X */
-
-#if defined(CFG_EEPROM_PAGE_WRITE_BITS)
-#define PAGE_OFFSET(x) ((x) & ((1 << CFG_EEPROM_PAGE_WRITE_BITS) - 1))
- /* Write data until done or would cross a write page boundary.
- * We must write the address again when changing pages
- * because the address counter only increments within a page.
- */
- do {
- write_byte (*buffer++);
- ++i;
- } while (i < cnt && PAGE_OFFSET(offset + i) != 0);
-#else
+ uchar *ap = addr;
+
+ write_addr (*ap);
+ while (--alen > 0) {
+ write_byte (*++ap);
+ }
+
+ while (len-- > 0) {
write_byte (*buffer++);
- ++i;
-#endif
- send_stop ();
}
+ send_stop ();
+}
+
+uchar i2c_reg_read (uchar i2c_addr, uchar reg)
+{
+ char addr[2];
+ char buf [1];
+
+ i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
+
+ addr[0] = i2c_addr;
+ addr[1] = reg;
+
+ i2c_read (addr, 2, buf, 1);
+
+ return (buf[0]);
+}
+
+void i2c_reg_write (uchar i2c_addr, uchar reg, uchar val)
+{
+ char addr[2];
+
+ i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
+
+ addr[0] = i2c_addr;
+ addr[1] = reg;
+
+ i2c_write (addr, 2, &val, 1);
}
+#endif /* CONFIG_SOFT_I2C */
/*-----------------------------------------------------------------------
*/
/* write 1 in SCMP IRQA to clear these fields */
/* !!! ASH QpenBios says 0x08 */
/* out8(IIC_STS, 0x0C); */
- out8(IIC_STS, 0x08);
+ out8(IIC_STS, 0x08);
__asm__ volatile("eieio");
/* write 1 in IRQP IRQD LA ICT XFRA to clear these fields */
out8(IIC_EXTSTS, 0x8F);
divisor = 0x5;
out8(IIC_CLKDIV,divisor);
__asm__ volatile("eieio");
-
+
/* no interrupts */
out8(IIC_INTRMSK,0);
__asm__ volatile("eieio");
/* clear transfer count */
- out8(IIC_XFRCNT,0);
- __asm__ volatile("eieio");
+ out8(IIC_XFRCNT,0);
+ __asm__ volatile("eieio");
/* clear extended control & stat */
/* write 1 in SRC SRS SWC SWS to clear these fields */
out8(IIC_XTCNTLSS,0xF0);
- __asm__ volatile("eieio");
-
- /* Mode Control Register
+ __asm__ volatile("eieio");
+
+ /* Mode Control Register
Flush Slave/Master data buffer */
out8(IIC_MDCNTL, IIC_MDCNTL_FSDB | IIC_MDCNTL_FMDB);
__asm__ volatile("eieio");
-
- /* Ignore General Call, 100kHz, slave transfers are ignored,
+
+ /* Ignore General Call, 100kHz, slave transfers are ignored,
disable interrupts, exit unknown bus state, enable hold
SCL
*/
__asm__ volatile("eieio");
/* clear control reg */
- out8(IIC_CNTL,0x00);
- __asm__ volatile("eieio");
-
-}
+ out8(IIC_CNTL,0x00);
+ __asm__ volatile("eieio");
+
+}
int i2c_transfer(unsigned char command_is_reading, unsigned char address,
int status;
int i, TimeReady, TimeOut;
ulong freqOPB,freqProc;
-
+
result = IIC_OK;
bytes_transfered = 0;
-
+
i2c_init();
-
+
/* Check init */
i=10;
do{
result = IIC_NOK_TOUT;
return(result);
}
-
+
/* 7-bit adressing */
out8(IIC_HMADR,0);
__asm__ volatile("eieio");
out8(IIC_LMADR, address);
__asm__ volatile("eieio");
-
+
/* In worst case, you need to wait 4 OPB clocks */
/* for data being ready on IIC bus */
/* (because FIFO is 4 bytes depth) */
freqOPB = get_OPB_freq();
freqProc = get_gclk_freq();
TimeReady = (4/(freqProc/freqOPB)) + 1;
-
+
/* IIC time out => wait for TimeOut cycles */
/* TimeOut /= 2; because waiting-loop is 2-instruction loop */
TimeOut = freqProc*IIC_TIMEOUT*10;
while ((bytes_transfered < size_to_transfer) && (result == IIC_OK))
{
- /* Control register =
+ /* Control register =
Normal transfer, 7-bits adressing, Transfer 1 byte, Normal start,
Transfer is a sequence of transfers
Write/Read, Start transfer */
/* issue read command */
if (bytes_transfered == size_to_transfer-1)
{
- out8(IIC_CNTL, IIC_CNTL_READ | IIC_CNTL_PT);
+ out8(IIC_CNTL, IIC_CNTL_READ | IIC_CNTL_PT);
__asm__ volatile("eieio");
}
else
{
- out8(IIC_CNTL, IIC_CNTL_READ | IIC_CNTL_CHT | IIC_CNTL_PT);
+ out8(IIC_CNTL, IIC_CNTL_READ | IIC_CNTL_CHT | IIC_CNTL_PT);
__asm__ volatile("eieio");
}
}
/* issue write command */
if (bytes_transfered == size_to_transfer-1)
{
- out8(IIC_CNTL, IIC_CNTL_PT);
+ out8(IIC_CNTL, IIC_CNTL_PT);
__asm__ volatile("eieio");
}
else
{
- out8(IIC_CNTL, IIC_CNTL_CHT | IIC_CNTL_PT);
+ out8(IIC_CNTL, IIC_CNTL_CHT | IIC_CNTL_PT);
__asm__ volatile("eieio");
}
}
-
+
/* Transfer is in progress */
i=TimeOut;
{
result = IIC_NOK_TOUT;
}
- else if (status & IIC_STS_ERR)
+ else if (status & IIC_STS_ERR)
{
result = IIC_NOK;
status = in8(IIC_EXTSTS);
}
return(result);
}
-
+
int i2c_receive(unsigned char address,
unsigned short size_to_expect, unsigned char datain[] )
}
-
+
int i2c_send(unsigned char address,
if (status != 0) printf("\nI2C error => status = %d\n", status);
#endif
return status;
-}
+}
+void i2c_read (uchar *addr, int alen, uchar *buffer, int len)
+{
+ if (alen != 2) {
+ printf ("I2C read: addr len %d not supported\n", alen);
+ return;
+ }
+ i2c_send (addr[0] << 1, 1, addr+1);
+ i2c_receive ((addr[0] << 1) | 0x01, len, buffer);
+}
+
+void i2c_write (uchar *addr, int alen, uchar *buffer, int len)
+{
+ uchar xbuf[2];
+ if (alen != 2) {
+ printf ("I2C write: addr len %d not supported\n", alen);
+ return;
+ }
+
+ /* write with ack polling */
+ /* XXX this should be improved to allow page write mode XXX - wd */
+ while (len-- > 0) {
+ xbuf[0] = addr[1];
+ xbuf[1] = *buffer++;
+ i2c_send (addr[0] << 1, 2, xbuf);
+ }
+}
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * 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
+ */
+
+#ifndef _CMD_BSP_H_
+#define _CMD_BSP_H_
+
+#include <ppcboot.h>
+#include <command.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_BSP)
+
+/* ----- LWMON -----------------------------------------------------------------
+ */
+#if defined(CONFIG_LWMON)
+
+#define CMD_TBL_BSP MK_CMD_TBL_ENTRY( \
+ "pic", 3, 4, 1, do_pic, \
+ "pic - read and write PIC registers\n", \
+ "read reg - read PIC register `reg'\n" \
+ "pic write reg val - write value `val' to PIC register `reg'\n" \
+),
+
+void do_pic (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]);
+
+#endif /* CONFIG_LWMON */
+/* ----------------------------------------------------------------------------*/
+
+#else
+
+#define CMD_TBL_BSP
+
+#endif /* CFG_CMD_BSP */
+
+
+#endif /* _CMD_BSP_H_ */
#define CFG_CMD_I2C 0x00100000 /* I2C serial bus support */
#define CFG_CMD_REGINFO 0x00200000 /* Register dump */
#define CFG_CMD_IMMAP 0x00400000 /* IMMR dump support */
+#define CFG_CMD_DATE 0x00800000 /* support for RTC, date/time...*/
+#define CFG_CMD_BSP 0x01000000 /* Board SPecific functions */
#define CFG_CMD_ALL 0xFFFFFFFF /* ALL commands */
CFG_CMD_ECHO | \
CFG_CMD_I2C | \
CFG_CMD_REGINFO | \
- CFG_CMD_IMMAP )
+ CFG_CMD_IMMAP | \
+ CFG_CMD_DATE | \
+ CFG_CMD_BSP )
/* Default configuration
*/
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * 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
+ */
+
+#ifndef _CMD_RTC_H_
+#define _CMD_RTC_H_
+
+#include <ppcboot.h>
+#include <command.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_DATE)
+
+#define CMD_TBL_DATE MK_CMD_TBL_ENTRY( \
+ "date", 3, 2, 1, do_date, \
+ "date - get/set date & time\n", \
+ "[MMDDhhmm[[CC]YY][.ss]]\n" \
+ " - without arguments: print date & time\n" \
+ " - with argument: set the system date & time\n" \
+),
+
+void do_date (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]);
+
+#else
+
+#define CMD_TBL_DATE
+
+#endif /* CFG_CMD_DATE */
+
+
+#endif /* _CMD_RTC_H_ */
/*** LWMON **********************************************************/
-#if defined(CONFIG_LWMON)
+#if defined(CONFIG_LWMON) && !defined(CONFIG_8xx_CONS_SCC2)
/* Bits in parallel I/O port registers that have to be set/cleared
* to configure the pins for SCC2 use.
*/
#define CFG_ENV_IS_IN_EEPROM 1 /* use EEPROM for environment vars */
#define CFG_ENV_OFFSET 0x000 /* environment starts at the beginning of the EEPROM */
#define CFG_ENV_SIZE 0x200 /* 512 bytes may be used for env vars */
- /* total size of a cat24wc08 is 1024 bytes */
-#define EEPROM_WRITE_ADDRESS 0xA0
-#define EEPROM_READ_ADDRESS 0xA1
+ /* total size of a CAT24WC08 is 1024 bytes */
+#define CFG_I2C_EEPROM_ADDR 0x50 /* EEPROM CAT28WC08 */
+#define CFG_EEPROM_PAGE_WRITE_BITS 4 /* The Catalyst CAT24WC08 has */
+ /* 16 byte page write mode using*/
+ /* last 4 bits of the address */
#endif
/*-----------------------------------------------------------------------
* Cache Configuration
#define CFG_ENV_IS_IN_EEPROM 1 /* use EEPROM for environment vars */
#define CFG_ENV_OFFSET 0x000 /* environment starts at the beginning of the EEPROM */
#define CFG_ENV_SIZE 0x200 /* 512 bytes may be used for env vars */
- /* total size of a cat24wc08 is 1024 bytes */
-#define EEPROM_WRITE_ADDRESS 0xA0
-#define EEPROM_READ_ADDRESS 0xA1
+ /* total size of a CAT24WC08 is 1024 bytes */
+
+#define CFG_I2C_EEPROM_ADDR 0x50 /* EEPROM CAT28WC08 */
+#define CFG_EEPROM_PAGE_WRITE_BITS 4 /* The Catalyst CAT24WC08 has */
+ /* 16 byte page write mode using*/
+ /* last 4 bits of the address */
#endif
/*-----------------------------------------------------------------------
* Cache Configuration
#define CFG_ENV_IS_IN_EEPROM 1 /* use EEPROM for environment vars */
#define CFG_ENV_OFFSET 0x000 /* environment starts at the beginning of the EEPROM */
#define CFG_ENV_SIZE 0x200 /* 512 bytes may be used for env vars */
- /* total size of a cat24wc08 is 1024 bytes */
-#define EEPROM_WRITE_ADDRESS 0xA0
-#define EEPROM_READ_ADDRESS 0xA1
+ /* total size of a CAT24WC08 is 1024 bytes */
+
+#define CFG_I2C_EEPROM_ADDR 0x50 /* EEPROM CAT28WC08 */
+#define CFG_EEPROM_PAGE_WRITE_BITS 4 /* The Catalyst CAT24WC08 has */
+ /* 16 byte page write mode using*/
+ /* last 4 bits of the address */
#endif
/*-----------------------------------------------------------------------
* Cache Configuration
#undef CONFIG_WATCHDOG /* watchdog disabled */
+#define CONFIG_SOFT_I2C /* Software I2C support enabled */
+# define CFG_I2C_SPEED 50000
+# define CFG_I2C_SLAVE 0xFE
+# define CFG_I2C_EEPROM_ADDR 0x50 /* EEPROM X24C16 */
+# define CFG_EEPROM_PAGE_WRITE_BITS 4 /* The Xicor X24C16 has 16 byte */
+ /* page write mode using last */
+ /* 4 bits of the address */
+
#define CONFIG_COMMANDS (CONFIG_CMD_DFL | CFG_CMD_EEPROM)
#define CONFIG_BOOTP_MASK CONFIG_BOOTP_DEFAULT
--- /dev/null
+ /*
+ * A collection of structures, addresses, and values associated with
+ * the Motorola 860T MBX board.
+ * Copied from the FADS stuff, which was originally copied from the MBX stuff!
+ * Magnus Damm added defines for 8xxrom and extended bd_info.
+ * Helmut Buchsbaum added bitvalues for BCSRx
+ * Rob Taylor coverted it back to MBX
+ *
+ * Copyright (c) 1998 Dan Malek (dmalek@jlc.net)
+ */
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+#include <mpc8xx_irq.h>
+
+#define CONFIG_MPC860 1
+#define CONFIG_MPC860T 1
+#define CONFIG_MBX 1
+
+#define CONFIG_8xx_CPUCLOCK 40
+#define CONFIG_8xx_BUSCLOCK (CONFIG_8xx_CPUCLOCK)
+#define TARGET_SYSTEM_FREQUENCY 40
+
+#define CONFIG_8xx_CONS_SMC1 1 /* Console is on SMC1 */
+#undef CONFIG_8xx_CONS_SMC2
+#define CONFIG_BAUDRATE 9600
+
+#define MPC8XX_FACT 10 /* Multiply by 10 */
+#define MPC8XX_XIN 40000000 /* 50 MHz in */
+#define MPC8XX_HZ ((MPC8XX_XIN) * (MPC8XX_FACT))
+
+#if 1
+#define CONFIG_8xx_BOOTDELAY -1 /* autoboot disabled */
+#define CONFIG_8xx_TFTP_MODE
+#else
+#define CONFIG_8xx_BOOTDELAY 5 /* autoboot after 5 seconds */
+#undef CONFIG_8xx_TFTP_MODE
+#endif
+
+#define CONFIG_DRAM_SPEED (CONFIG_8xx_BUSCLOCK) /* MHz */
+#define CONFIG_BOOTCOMMAND "bootm FE020000" /* autoboot command */
+#define CONFIG_BOOTARGS " "
+/*
+ * Miscellaneous configurable options
+ */
+#undef CFG_LONGHELP /* undef to save memory */
+#define CFG_PROMPT ":>" /* Monitor Command Prompt */
+#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
+#define CFG_MAXARGS 16 /* max number of command args */
+#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
+
+#define CFG_MEMTEST_START 0x0400000 /* memtest works on */
+#define CFG_MEMTEST_END 0x0800000 /* 4 ... 8 MB in DRAM */
+
+#define CFG_LOAD_ADDR 0x100000 /* default load address */
+
+#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */
+
+#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
+
+/*
+ * Low Level Configuration Settings
+ * (address mappings, register initial values, etc.)
+ * You should know what you are doing if you make changes here.
+ */
+/*-----------------------------------------------------------------------
+ * Internal Memory Mapped Register
+ */
+#define CFG_IMMR 0xFFA00000
+#define CFG_IMMR_SIZE ((uint)(64 * 1024))
+#define CFG_NVRAM_BASE 0xFA000000 /* NVRAM */
+#define CFG_NVRAM_OR 0xffe00000 /* w/o speed dependent flags!! */
+#define CFG_CSR_BASE 0xFA100000 /* Control/Status Registers */
+#define CFG_PCIMEM_BASE 0x80000000 /* PCI I/O and Memory Spaces */
+#define CFG_PCIMEM_OR 0xA0000108
+#define CFG_PCIBRIDGE_BASE 0xFA210000 /* PCI-Bus Bridge Registers */
+#define CFG_PCIBRIDGE_OR 0xFFFF0108
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area (in DPRAM)
+ */
+#define CFG_INIT_RAM_ADDR CFG_IMMR
+#define CFG_INIT_RAM_END 0x2f00 /* End of used area in DPRAM */
+#define CFG_INIT_DATA_SIZE 64 /* size in bytes reserved for initial data */
+#define CFG_INIT_DATA_OFFSET (CFG_INIT_RAM_END - CFG_INIT_DATA_SIZE)
+#define CFG_INIT_VPD_SIZE 256 /* size in bytes reserved for vpd buffer */
+#define CFG_INIT_VPD_OFFSET (CFG_INIT_DATA_OFFSET - CFG_INIT_VPD_SIZE)
+#define CFG_INIT_SP_OFFSET (CFG_INIT_VPD_OFFSET-8)
+
+/*-----------------------------------------------------------------------
+ * Offset in DPMEM where we keep the VPD data
+ */
+#define CFG_DPRAMVPD (CFG_INIT_VPD_OFFSET - 0x2000)
+
+/*-----------------------------------------------------------------------
+ * Start addresses for the final memory configuration
+ * (Set up by the startup code)
+ * Please note that CFG_SDRAM_BASE _must_ start at 0
+ */
+#define CFG_SDRAM_BASE 0x00000000
+#define CFG_FLASH_BASE 0x00000000
+/*0xFE000000*/
+#define CFG_FLASH_SIZE ((uint)(8 * 1024 * 1024)) /* max 8Mbyte */
+#define CFG_MONITOR_BASE CFG_FLASH_BASE
+#define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */
+#define CFG_HWINFO_LEN 0x0040 /* Length of HW Info Data */
+#define CFG_HWINFO_ADDR (CFG_FLASH_BASE + CFG_MONITOR_LEN - CFG_HWINFO_LEN)
+#define CFG_MALLOC_LEN (256 << 10) /* Reserve 256 kB for malloc() */
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
+
+/*-----------------------------------------------------------------------
+ * FLASH organization
+ */
+#define CFG_MAX_FLASH_BANKS 4 /* max number of memory banks */
+#define CFG_MAX_FLASH_SECT 16 /* max number of sectors on one chip */
+
+#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */
+#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */
+
+/*-----------------------------------------------------------------------
+ * NVRAM Configuration
+ *
+ * Note: the MBX is special because there is already a firmware on this
+ * board: EPPC-Bug from Motorola. To avoid collisions in NVRAM Usage, we
+ * access the NVRAM at the offset 0x1000.
+ */
+#define CFG_ENV_IS_IN_NVRAM 1 /* turn on NVRAM env feature */
+#define CFG_ENV_ADDR (CFG_NVRAM_BASE + 0x1000)
+#define CFG_ENV_SIZE 0x1000
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_CACHELINE_SIZE 16 /* For all MPC8xx CPUs */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CACHELINE_SHIFT 4 /* log base 2 of the above value */
+#endif
+
+/*-----------------------------------------------------------------------
+ * SYPCR - System Protection Control 11-9
+ * SYPCR can only be written once after reset!
+ *-----------------------------------------------------------------------
+ * Software & Bus Monitor Timer max, Bus Monitor enable, SW Watchdog freeze
+ */
+#if defined(CONFIG_WATCHDOG)
+#define CFG_SYPCR (SYPCR_SWTC | SYPCR_BMT | SYPCR_BME | SYPCR_SWF | \
+ SYPCR_SWE | SYPCR_SWP)
+#else
+#define CFG_SYPCR (SYPCR_SWTC | SYPCR_BMT | SYPCR_BME | SYPCR_SWF)
+#endif
+
+/*-----------------------------------------------------------------------
+ * SIUMCR - SIU Module Configuration 11-6
+ *-----------------------------------------------------------------------
+ * PCMCIA config., multi-function pin tri-state
+ */
+#define CFG_SIUMCR (SIUMCR_DBGC11 | SIUMCR_DPC | SIUMCR_MLRC10 | SIUMCR_SEME)
+
+/*-----------------------------------------------------------------------
+ * TBSCR - Time Base Status and Control 11-26
+ *-----------------------------------------------------------------------
+ * Clear Reference Interrupt Status, Timebase freezing enabled
+ */
+#define CFG_TBSCR (TBSCR_REFA | TBSCR_REFB | TBSCR_TBF)
+
+/*-----------------------------------------------------------------------
+ * PISCR - Periodic Interrupt Status and Control 11-31
+ *-----------------------------------------------------------------------
+ * Clear Periodic Interrupt Status, Interrupt Timer freezing enabled
+ */
+#define CFG_PISCR (PISCR_PS | PISCR_PITF | PISCR_PTE)
+
+/*-----------------------------------------------------------------------
+ * PLPRCR - PLL, Low-Power, and Reset Control Register 15-30
+ *-----------------------------------------------------------------------
+ * Reset PLL lock status sticky bit, timer expired status bit and timer
+ * interrupt status bit - leave PLL multiplication factor unchanged !
+ */
+#define CFG_PLPRCR (PLPRCR_SPLSS | PLPRCR_TEXPS | PLPRCR_TMIST)
+
+/*-----------------------------------------------------------------------
+ * SCCR - System Clock and reset Control Register 15-27
+ *-----------------------------------------------------------------------
+ * Set clock output, timebase and RTC source and divider,
+ * power management and some other internal clocks
+ */
+#define SCCR_MASK (SCCR_RTDIV | SCCR_RTSEL)
+#define CFG_SCCR SCCR_TBS
+
+ /*-----------------------------------------------------------------------
+ *
+ *-----------------------------------------------------------------------
+ *
+ */
+#define CFG_DER 0
+
+/* Because of the way the 860 starts up and assigns CS0 the
+* entire address space, we have to set the memory controller
+* differently. Normally, you write the option register
+* first, and then enable the chip select by writing the
+* base register. For CS0, you must write the base register
+* first, followed by the option register.
+*/
+
+/*
+ * Init Memory Controller:
+ *
+ * BR0/1 and OR0/1 (FLASH)
+ */
+/* the other CS:s are determined by looking at parameters in BCSRx */
+
+
+#define BCSR_ADDR ((uint) 0xFF010000)
+#define BCSR_SIZE ((uint)(64 * 1024))
+
+#define FLASH_BASE0_PRELIM 0xFE000000 /* FLASH bank #0 */
+#define FLASH_BASE1_PRELIM 0xFF010000 /* FLASH bank #0 */
+
+#define CFG_REMAP_OR_AM 0x80000000 /* OR addr mask */
+#define CFG_PRELIM_OR_AM 0xFFF00000 /* OR addr mask */
+
+/* FLASH timing: ACS = 10, TRLX = 1, CSNT = 1, SCY = 3, EHTR = 0 */
+#define CFG_OR_TIMING_FLASH (OR_CSNT_SAM | OR_ACS_DIV4 | OR_BI | OR_SCY_3_CLK | OR_TRLX)
+
+#define CFG_OR0_REMAP (CFG_REMAP_OR_AM | CFG_OR_TIMING_FLASH)
+#define CFG_OR0_PRELIM (0xFF800000 | OR_CSNT_SAM | OR_BI | OR_SCY_3_CLK) /* 1 Mbyte until detected and only 1 Mbyte is needed*/
+#define CFG_BR0_PRELIM (0xFE000000 | BR_V )
+
+/* BCSRx - Board Control and Status Registers */
+#define CFG_OR1_REMAP CFG_OR0_REMAP
+#define CFG_OR1_PRELIM 0xFFC00000 | OR_ACS_DIV4
+#define CFG_BR1_PRELIM (0x00000000 | BR_MS_UPMA | BR_V )
+
+
+/*
+ * Memory Periodic Timer Prescaler
+ */
+
+/* periodic timer for refresh */
+#define CFG_MAMR_PTA 97 /* start with divider for 100 MHz */
+
+/* refresh rate 15.6 us (= 64 ms / 4K = 62.4 / quad bursts) for <= 128 MBit */
+#define CFG_MPTPR_2BK_4K MPTPR_PTP_DIV16 /* setting for 2 banks */
+#define CFG_MPTPR_1BK_4K MPTPR_PTP_DIV32 /* setting for 1 bank */
+
+/* refresh rate 7.8 us (= 64 ms / 8K = 31.2 / quad bursts) for 256 MBit */
+#define CFG_MPTPR_2BK_8K MPTPR_PTP_DIV8 /* setting for 2 banks */
+#define CFG_MPTPR_1BK_8K MPTPR_PTP_DIV16 /* setting for 1 bank */
+
+/*
+ * MAMR settings for SDRAM
+ */
+
+/* 8 column SDRAM */
+#define CFG_MAMR_8COL ((CFG_MAMR_PTA << MAMR_PTA_SHIFT) | MAMR_PTAE | \
+ MAMR_AMA_TYPE_0 | MAMR_DSA_1_CYCL | MAMR_G0CLA_A11 | \
+ MAMR_RLFA_1X | MAMR_WLFA_1X | MAMR_TLFA_4X)
+/* 9 column SDRAM */
+#define CFG_MAMR_9COL ((CFG_MAMR_PTA << MAMR_PTA_SHIFT) | MAMR_PTAE | \
+ MAMR_AMA_TYPE_1 | MAMR_DSA_1_CYCL | MAMR_G0CLA_A10 | \
+ MAMR_RLFA_1X | MAMR_WLFA_1X | MAMR_TLFA_4X)
+
+#define CFG_MAMR 0x13821000
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
+#define BOOTFLAG_WARM 0x02 /* Software reboot */
+
+
+/* values according to the manual */
+
+
+#define PCMCIA_MEM_ADDR ((uint)0xff020000)
+#define PCMCIA_MEM_SIZE ((uint)(64 * 1024))
+
+#define BCSR0 ((uint) (BCSR_ADDR + 00))
+#define BCSR1 ((uint) (BCSR_ADDR + 0x04))
+#define BCSR2 ((uint) (BCSR_ADDR + 0x08))
+#define BCSR3 ((uint) (BCSR_ADDR + 0x0c))
+#define BCSR4 ((uint) (BCSR_ADDR + 0x10))
+
+/* FADS bitvalues by Helmut Buchsbaum
+ * see MPC8xxADS User's Manual for a proper description
+ * of the following structures
+ */
+
+#define BCSR0_ERB ((uint)0x80000000)
+#define BCSR0_IP ((uint)0x40000000)
+#define BCSR0_BDIS ((uint)0x10000000)
+#define BCSR0_BPS_MASK ((uint)0x0C000000)
+#define BCSR0_ISB_MASK ((uint)0x01800000)
+#define BCSR0_DBGC_MASK ((uint)0x00600000)
+#define BCSR0_DBPC_MASK ((uint)0x00180000)
+#define BCSR0_EBDF_MASK ((uint)0x00060000)
+
+#define BCSR1_FLASH_EN ((uint)0x80000000)
+#define BCSR1_DRAM_EN ((uint)0x40000000)
+#define BCSR1_ETHEN ((uint)0x20000000)
+#define BCSR1_IRDEN ((uint)0x10000000)
+#define BCSR1_FLASH_CFG_EN ((uint)0x08000000)
+#define BCSR1_CNT_REG_EN_PROTECT ((uint)0x04000000)
+#define BCSR1_BCSR_EN ((uint)0x02000000)
+#define BCSR1_RS232EN_1 ((uint)0x01000000)
+#define BCSR1_PCCEN ((uint)0x00800000)
+#define BCSR1_PCCVCC0 ((uint)0x00400000)
+#define BCSR1_PCCVPP_MASK ((uint)0x00300000)
+#define BCSR1_DRAM_HALF_WORD ((uint)0x00080000)
+#define BCSR1_RS232EN_2 ((uint)0x00040000)
+#define BCSR1_SDRAM_EN ((uint)0x00020000)
+#define BCSR1_PCCVCC1 ((uint)0x00010000)
+
+#define BCSR2_FLASH_PD_MASK ((uint)0xF0000000)
+#define BCSR2_DRAM_PD_MASK ((uint)0x07800000)
+#define BCSR2_DRAM_PD_SHIFT (23)
+#define BCSR2_EXTTOLI_MASK ((uint)0x00780000)
+#define BCSR2_DBREVNR_MASK ((uint)0x00030000)
+
+#define BCSR3_DBID_MASK ((ushort)0x3800)
+#define BCSR3_CNT_REG_EN_PROTECT ((ushort)0x0400)
+#define BCSR3_BREVNR0 ((ushort)0x0080)
+#define BCSR3_FLASH_PD_MASK ((ushort)0x0070)
+#define BCSR3_BREVN1 ((ushort)0x0008)
+#define BCSR3_BREVN2_MASK ((ushort)0x0003)
+
+#define BCSR4_ETHLOOP ((uint)0x80000000)
+#define BCSR4_TFPLDL ((uint)0x40000000)
+#define BCSR4_TPSQEL ((uint)0x20000000)
+#define BCSR4_SIGNAL_LAMP ((uint)0x10000000)
+#ifdef CONFIG_MPC823
+#define BCSR4_USB_EN ((uint)0x08000000)
+#endif /* CONFIG_MPC823 */
+#ifdef CONFIG_MPC860SAR
+#define BCSR4_UTOPIA_EN ((uint)0x08000000)
+#endif /* CONFIG_MPC860SAR */
+#ifdef CONFIG_MPC860T
+#define BCSR4_FETH_EN ((uint)0x08000000)
+#endif /* CONFIG_MPC860T */
+#define BCSR4_USB_SPEED ((uint)0x04000000)
+#define BCSR4_VCCO ((uint)0x02000000)
+#define BCSR4_VIDEO_ON ((uint)0x00800000)
+#define BCSR4_VDO_EKT_CLK_EN ((uint)0x00400000)
+#define BCSR4_VIDEO_RST ((uint)0x00200000)
+#define BCSR4_MODEM_EN ((uint)0x00100000)
+#define BCSR4_DATA_VOICE ((uint)0x00080000)
+
+#define CONFIG_DRAM_40MHZ 1
+
+#ifdef CONFIG_MPC860T
+
+/* Interrupt level assignments.
+*/
+#define FEC_INTERRUPT SIU_LEVEL1 /* FEC interrupt */
+
+#endif /* CONFIG_MPC860T */
+
+/* We don't use the 8259.
+*/
+#define NR_8259_INTS 0
+
+/* Machine type
+*/
+#define _MACH_8xx (_MACH_fads)
+
+/*
+ * MPC8xx CPM Options
+ */
+#define CONFIG_SCC_ENET 1
+#define CONFIG_SCC1_ENET 1
+#define CONFIG_FEC_ENET 1
+#undef CONFIG_CPM_IIC
+#undef CONFIG_UCODE_PATCH
+
+
+#define CONFIG_DISK_SPINUP_TIME 1000000
+
+
+/* PCMCIA configuration */
+
+#define PCMCIA_MAX_SLOTS 2
+
+#ifdef CONFIG_MPC860
+#define PCMCIA_SLOT_A 1
+#endif
+
+#endif /* __CONFIG_H */
#undef CONFIG_WATCHDOG /* watchdog disabled */
+#define CONFIG_SOFT_I2C /* Software I2C support enabled */
+# define CFG_I2C_SPEED 50000
+# define CFG_I2C_SLAVE 0xFE
+# define CFG_I2C_EEPROM_ADDR 0x50 /* Atmel 24C64 */
+# define CFG_EEPROM_PAGE_WRITE_BITS 5 /* The Atmel 24C64 has 32 byte */
+ /* page write mode using last */
+ /* 5 bits of the address */
+
#define CONFIG_FEC_ENET 1 /* use FEC ethernet */
#undef CONFIG_SCC1_ENET /* disable SCC1 ethernet */
#if defined(CONFIG_SCC1_ENET) && defined(CONFIG_FEC_ENET)
#define CFG_ENV_SIZE 512 /* Use only a part of it*/
#define CONFIG_I2C_X 1 /* EEPROM uses 16-bit address */
-/* Atmel 24C64 has 32-byte page write mode using last 5 bits of the address */
-#define CFG_EEPROM_PAGE_WRITE_BITS 5
-
#if 1
#define CONFIG_BOOT_RETRY_TIME 60 /* boot if no command in 60 seconds */
#endif
CFG_CMD_IDE | \
CFG_CMD_PCMCIA | \
CFG_CMD_PCI | \
+ CFG_CMD_DATE | \
CFG_CMD_EEPROM ))
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
#define CONFIG_LWMON 1 /* ...on a LWMON board */
#define CONFIG_8xx_CONS_SMC2 1 /* Console is on SMC2 */
+//#define CONFIG_8xx_CONS_SCC2
#define CONFIG_BAUDRATE 19200
#if 0
#undef CONFIG_STATUS_LED /* Status LED disabled */
-// #define CONFIG_I2C /* I2C support enabled */
-
-#define CONFIG_COMMANDS (CONFIG_CMD_DFL | CFG_CMD_EEPROM | CFG_CMD_IDE /*|CFG_CMD_I2C*/)
+#define CONFIG_SOFT_I2C /* Software I2C support enabled */
+# define CFG_I2C_SPEED 50000
+# define CFG_I2C_SLAVE 0xFE
+# define CFG_EEPROM_PAGE_WRITE_BITS 4 /* The Atmel 24C164 has 16 byte */
+ /* page write mode using last */
+ /* 4 bits of the address */
+
+#ifdef CONFIG_8xx_CONS_SCC2 /* Can't use ethernet, then */
+#define CONFIG_COMMANDS ((CONFIG_CMD_DFL & ~CFG_CMD_NET) | \
+ CFG_CMD_EEPROM | \
+ CFG_CMD_DATE | \
+ CFG_CMD_IDE | \
+ CFG_CMD_BSP )
+#else
+#define CONFIG_COMMANDS (CONFIG_CMD_DFL | \
+ CFG_CMD_EEPROM | \
+ CFG_CMD_DATE | \
+ CFG_CMD_IDE | \
+ CFG_CMD_BSP )
+#endif
#define CONFIG_MAC_PARTITION
#define CONFIG_DOS_PARTITION
#define CFG_MAX_FLASH_BANKS 2 /* max number of memory banks */
#define CFG_MAX_FLASH_SECT 128 /* max number of sectors on one chip */
-#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */
-#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */
+#define CFG_FLASH_ERASE_TOUT 180000 /* Timeout for Flash Erase (in ms) */
+#define CFG_FLASH_WRITE_TOUT 600 /* Timeout for Flash Write (in ms) */
-/* XXX Start port with environment in flash; switch to EEPROM later */
+#if 0
+/* Start port with environment in flash; switch to EEPROM later */
#define CFG_ENV_IS_IN_FLASH 1
#define CFG_ENV_ADDR 0x407E0000 /* Address of Environment Sector */
#define CFG_ENV_SIZE 0x1000 /* Total Size of Environment */
#define CFG_ENV_SECT_SIZE 0x20000 /* we have BIG sectors only :-( */
+#else
+/* Final version: environment in EEPROM */
+#define CFG_ENV_IS_IN_EEPROM 1
+#define CFG_ENV_OFFSET 0
+#define CFG_ENV_SIZE 1024
+#endif
/*-----------------------------------------------------------------------
* I2C/EEPROM Configuration
*/
#define CFG_SCCR (SCCR_COM00 | /*SCCR_TBS|*/ \
SCCR_RTDIV | SCCR_RTSEL | \
/*SCCR_CRQEN|*/ /*SCCR_PRQEN|*/ \
-SCCR_EBDF01 /**** SCCR_EBDF00 ****/ | SCCR_DFSYNC00 | \
+ SCCR_EBDF00 | SCCR_DFSYNC00 | \
SCCR_DFBRG00 | SCCR_DFNL000 | \
SCCR_DFNH000 | SCCR_DFLCD100 | \
SCCR_DFALCD01)
#ifndef _I2C_H_
#define _I2C_H_
+#if defined(CONFIG_SOFT_I2C)
+void i2c_init (int speed, int slaveaddr);
+uchar i2c_reg_read (uchar i2c_addr, uchar reg);
+void i2c_reg_write (uchar i2c_addr, uchar reg, uchar val);
+#endif /* CONFIG_SOFT_I2C */
+
+#if defined(CONFIG_SOFT_I2C) || defined(CONFIG_PPC405)
+void i2c_read (uchar *addr, int alen, uchar *buffer, int len);
+void i2c_write (uchar *addr, int alen, uchar *buffer, int len);
+#endif
+
+
#if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || defined (CONFIG_WALNUT405)
void i2c_receive(unsigned char address,
void i2c_send(unsigned char address,
unsigned short size_to_send, unsigned char dataout[] );
-#else
+#else /* !CPCI405, !AR405, !WALNUT405 */
#define I2C_RXTX_LEN 128 /* maximum tx/rx buffer length */
/* This structure keeps track of the bd and buffer space usage. */
typedef struct i2c_state {
- int rx_idx, tx_idx; /* index to next free rx/tx bd */
- void *rxbd, *txbd; /* pointer to next free rx/tx bd */
- int tx_space; /* number of tx bytes left */
- unsigned char *tx_buf; /* pointer to free tx area */
+ int rx_idx; /* index to next free Rx BD */
+ int tx_idx; /* index to next free Tx BD */
+ void *rxbd; /* pointer to next free Rx BD */
+ void *txbd; /* pointer to next free Tx BD */
+ int tx_space; /* number of Tx bytes left */
+ unsigned char *tx_buf; /* pointer to free Tx area */
} i2c_state_t;
/* initialize i2c usage */
/* schedule a send operation (uses 1 tx bd) */
int i2c_send(i2c_state_t *state,
- unsigned char address,
- unsigned char secondary_address,
- unsigned int flags,
- unsigned short size,
- unsigned char *dataout);
+ unsigned char address,
+ unsigned char secondary_address,
+ unsigned int flags,
+ unsigned short size,
+ unsigned char *dataout);
/* schedule a receive operation (uses 1 tx bd, 1 rx bd) */
int i2c_receive(i2c_state_t *state,
- unsigned char address,
- unsigned char secondary_address,
- unsigned int flags,
- unsigned short size_to_expect,
- unsigned char *datain);
+ unsigned char address,
+ unsigned char secondary_address,
+ unsigned int flags,
+ unsigned short size_to_expect,
+ unsigned char *datain);
/* execute all scheduled operations */
int i2c_doio(i2c_state_t *state);
/* flags for i2c_send() and i2c_receive() */
-#define I2CF_ENABLE_SECONDARY 0x01 /* secondary_address is valid */
-#define I2CF_START_COND 0x02 /* tx: generate start condition */
-#define I2CF_STOP_COND 0x04 /* tx: generate stop condition */
+#define I2CF_ENABLE_SECONDARY 0x01 /* secondary_address is valid */
+#define I2CF_START_COND 0x02 /* tx: generate start condition */
+#define I2CF_STOP_COND 0x04 /* tx: generate stop condition */
/* return codes */
-#define I2CERR_NO_BUFFERS 0x01 /* no more bds or buffer space */
-#define I2CERR_MSG_TOO_LONG 0x02 /* tried to send/receive to much data */
-#define I2CERR_TIMEOUT 0x03 /* timeout in i2c_doio() */
+#define I2CERR_NO_BUFFERS 0x01 /* no more BDs or buffer space */
+#define I2CERR_MSG_TOO_LONG 0x02 /* tried to send/receive to much data */
+#define I2CERR_TIMEOUT 0x03 /* timeout in i2c_doio() */
#define I2CERR_QUEUE_EMPTY 0x04 /* i2c_doio called without send/receive */
-#endif
+#endif /* CPCI405, AR405, WALNUT405 */
#define ERROR_I2C_NONE 0
#define ERROR_I2C_LENGTH 1
-#endif
+#define I2C_WRITE_BIT 0x00
+#define I2C_READ_BIT 0x01
+
+#endif /* _I2C_H_ */
int getenv_r (uchar *name, uchar *buf, unsigned len);
void inline setenv (char *, char *);
-#if defined(CONFIG_CPCI405) || \
- defined(CONFIG_AR405) || \
- defined (CONFIG_WALNUT405) || \
+#if defined(CONFIG_CPCI405) || \
+ defined(CONFIG_AR405) || \
+ defined (CONFIG_WALNUT405) || \
defined (CONFIG_CPCIISER4)
/* $(CPU)/405gp_pci.c */
void pci_init (void);
defined(CONFIG_SXNI855T) || \
defined(CONFIG_CPCI405) || \
defined(CONFIG_CANBT) || \
- defined(CONFIG_WALNUT405) || \
+ defined(CONFIG_WALNUT405) || \
defined(CONFIG_CPCIISER4) || \
defined(CONFIG_LWMON)
/* $(BOARD)/eeprom.c */
void hermes_start_lxt980 (int speed);
#endif
-#if defined(CONFIG_CPCI405) || \
- defined(CONFIG_AR405) || \
- defined(CONFIG_CANBT) || \
- defined(CONFIG_WALNUT405) || \
- defined(CONFIG_CPCIISER4) || \
- defined(CONFIG_ADCIOP)
+#if defined(CONFIG_CPCI405) || \
+ defined(CONFIG_AR405) || \
+ defined(CONFIG_CANBT) || \
+ defined(CONFIG_WALNUT405) || \
+ defined(CONFIG_CPCIISER4) || \
+ defined(CONFIG_ADCIOP) || \
+ defined(CONFIG_LWMON)
/* $(BOARD)/$(BOARD).c */
int board_pre_init (void);
#endif
-#if defined(CONFIG_HYMOD) || defined(CONFIG_LWMON)
+#if defined(CONFIG_HYMOD)
void board_postclk_init(void); /* after clocks/timebase, before env/serial */
#endif
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * 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
+ */
+
+/*
+ * Generic RTC interface.
+ */
+#ifndef _RTC_H_
+#define _RTC_H_
+
+/*
+ * The struct used to pass data from the generic interface code to
+ * the hardware dependend low-level code ande vice versa. Identical
+ * to struct rtc_time used by the Linux kernel.
+ *
+ * Note that there are small but significant differences to the
+ * common "struct time":
+ *
+ * struct time: struct rtc_time:
+ * tm_mon 0 ... 11 1 ... 12
+ * tm_year years since 1900 years since 0
+ */
+
+struct rtc_time {
+ int tm_sec;
+ int tm_min;
+ int tm_hour;
+ int tm_mday;
+ int tm_mon;
+ int tm_year;
+ int tm_wday;
+ int tm_yday;
+ int tm_isdst;
+};
+
+void rtc_get (struct rtc_time *);
+void rtc_set (struct rtc_time *);
+void rtc_reset (void);
+
+void GregorianDay (struct rtc_time *);
+void to_tm (int, struct rtc_time *);
+unsigned long mktime (unsigned int, unsigned int, unsigned int,
+ unsigned int, unsigned int, unsigned int);
+
+#endif /* _RTC_H_ */
#ifndef __VERSION_H__
#define __VERSION_H__
-#define PPCBOOT_VERSION "ppcboot 0.9.0-pre4"
+#define PPCBOOT_VERSION "ppcboot 0.9.0"
#endif /* __VERSION_H__ */
--- /dev/null
+#
+# (C) Copyright 2001
+# 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 $(TOPDIR)/config.mk
+
+#CFLAGS += -DDEBUG
+
+LIB = librtc.a
+
+OBJS = date.o pcf8563.o
+
+all: $(LIB)
+
+$(LIB): $(START) $(OBJS)
+ $(AR) crv $@ $(OBJS)
+
+#########################################################################
+
+.depend: Makefile $(OBJS:.o=.c)
+ $(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * 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
+ */
+
+/*
+ * Date & Time support for Philips PCF8563 RTC
+ */
+
+#define DEBUG
+
+#include <ppcboot.h>
+#include <command.h>
+#include <rtc.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_DATE)
+
+#define FEBRUARY 2
+#define STARTOFTIME 1970
+#define SECDAY 86400L
+#define SECYR (SECDAY * 365)
+#define leapyear(year) ((year) % 4 == 0)
+#define days_in_year(a) (leapyear(a) ? 366 : 365)
+#define days_in_month(a) (month_days[(a) - 1])
+
+static int month_days[12] = {
+ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+};
+
+/*
+ * This only works for the Gregorian calendar - i.e. after 1752 (in the UK)
+ */
+void GregorianDay(struct rtc_time * tm)
+{
+ int leapsToDate;
+ int lastYear;
+ int day;
+ int MonthOffset[] = { 0,31,59,90,120,151,181,212,243,273,304,334 };
+
+ lastYear=tm->tm_year-1;
+
+ /*
+ * Number of leap corrections to apply up to end of last year
+ */
+ leapsToDate = lastYear/4 - lastYear/100 + lastYear/400;
+
+ /*
+ * This year is a leap year if it is divisible by 4 except when it is
+ * divisible by 100 unless it is divisible by 400
+ *
+ * e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 will be
+ */
+ if((tm->tm_year%4==0) &&
+ ((tm->tm_year%100!=0) || (tm->tm_year%400==0)) &&
+ (tm->tm_mon>2)) {
+ /*
+ * We are past Feb. 29 in a leap year
+ */
+ day=1;
+ } else {
+ day=0;
+ }
+
+ day += lastYear*365 + leapsToDate + MonthOffset[tm->tm_mon-1] + tm->tm_mday;
+
+ tm->tm_wday=day%7;
+}
+
+void to_tm(int tim, struct rtc_time * tm)
+{
+ register int i;
+ register long hms, day;
+
+ day = tim / SECDAY;
+ hms = tim % SECDAY;
+
+ /* Hours, minutes, seconds are easy */
+ tm->tm_hour = hms / 3600;
+ tm->tm_min = (hms % 3600) / 60;
+ tm->tm_sec = (hms % 3600) % 60;
+
+ /* Number of years in days */
+ for (i = STARTOFTIME; day >= days_in_year(i); i++) {
+ day -= days_in_year(i);
+ }
+ tm->tm_year = i;
+
+ /* Number of months in days left */
+ if (leapyear(tm->tm_year)) {
+ days_in_month(FEBRUARY) = 29;
+ }
+ for (i = 1; day >= days_in_month(i); i++) {
+ day -= days_in_month(i);
+ }
+ days_in_month(FEBRUARY) = 28;
+ tm->tm_mon = i;
+
+ /* Days are what is left over (+1) from all that. */
+ tm->tm_mday = day + 1;
+
+ /*
+ * Determine the day of week
+ */
+ GregorianDay(tm);
+}
+
+/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
+ * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
+ * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
+ *
+ * [For the Julian calendar (which was used in Russia before 1917,
+ * Britain & colonies before 1752, anywhere else before 1582,
+ * and is still in use by some communities) leave out the
+ * -year/100+year/400 terms, and add 10.]
+ *
+ * This algorithm was first published by Gauss (I think).
+ *
+ * WARNING: this function will overflow on 2106-02-07 06:28:16 on
+ * machines were long is 32-bit! (However, as time_t is signed, we
+ * will already get problems at other places on 2038-01-19 03:14:08)
+ */
+unsigned long
+mktime (unsigned int year, unsigned int mon,
+ unsigned int day, unsigned int hour,
+ unsigned int min, unsigned int sec)
+{
+ if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */
+ mon += 12; /* Puts Feb last since it has leap day */
+ year -= 1;
+ }
+
+ return (((
+ (unsigned long) (year/4 - year/100 + year/400 + 367*mon/12 + day) +
+ year*365 - 719499
+ )*24 + hour /* now have hours */
+ )*60 + min /* now have minutes */
+ )*60 + sec; /* finally seconds */
+}
+
+#endif /* CFG_CMD_DATE */
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * 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
+ */
+
+/*
+ * Date & Time support for Philips PCF8563 RTC
+ */
+
+/*#define DEBUG*/
+
+#include <ppcboot.h>
+#include <command.h>
+#include <rtc.h>
+#include <i2c.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_DATE)
+
+static uchar rtc_read (uchar reg);
+static void rtc_write (uchar reg, uchar val);
+static uchar bin2bcd (unsigned int n);
+static unsigned bcd2bin(uchar c);
+
+/* ------------------------------------------------------------------------- */
+
+void rtc_get (struct rtc_time *tmp)
+{
+ uchar sec, min, hour, mday, wday, mon_cent, year;
+
+ sec = rtc_read (0x02);
+ min = rtc_read (0x03);
+ hour = rtc_read (0x04);
+ mday = rtc_read (0x05);
+ wday = rtc_read (0x06);
+ mon_cent= rtc_read (0x07);
+ year = rtc_read (0x08);
+
+ debug ( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
+ "hr: %02x min: %02x sec: %02x\n",
+ year, mon_cent, mday, wday,
+ hour, min, sec );
+ debug ( "Alarms: wday: %02x day: %02x hour: %02x min: %02x\n",
+ rtc_read (0x0C),
+ rtc_read (0x0B),
+ rtc_read (0x0A),
+ rtc_read (0x09) );
+
+ if (sec & 0x80) {
+ printf ("### Warning: RTC Low Voltage - date/time not reliable\n");
+ }
+
+ tmp->tm_sec = bcd2bin (sec & 0x7F);
+ tmp->tm_min = bcd2bin (min & 0x7F);
+ tmp->tm_hour = bcd2bin (hour & 0x3F);
+ tmp->tm_mday = bcd2bin (mday & 0x3F);
+ tmp->tm_mon = bcd2bin (mon_cent & 0x1F);
+ tmp->tm_year = bcd2bin (year) + ((mon_cent & 0x80) ? 2000 : 1900);
+ tmp->tm_wday = bcd2bin (wday & 0x07);
+ tmp->tm_yday = 0;
+ tmp->tm_isdst= 0;
+
+ debug ( "Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
+ tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+ tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+}
+
+void rtc_set (struct rtc_time *tmp)
+{
+ uchar century;
+
+ debug ( "Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
+ tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+ tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+ rtc_write (0x08, bin2bcd(tmp->tm_year % 100));
+
+ century = (tmp->tm_year >= 2000) ? 0x80 : 0;
+ rtc_write (0x07, bin2bcd(tmp->tm_mon) | century);
+
+ rtc_write (0x06, bin2bcd(tmp->tm_wday));
+ rtc_write (0x05, bin2bcd(tmp->tm_mday));
+ rtc_write (0x04, bin2bcd(tmp->tm_hour));
+ rtc_write (0x03, bin2bcd(tmp->tm_min ));
+ rtc_write (0x02, bin2bcd(tmp->tm_sec ));
+}
+
+void rtc_reset (void)
+{
+ /* clear all control & status registers */
+ rtc_write (0x00, 0x00);
+ rtc_write (0x01, 0x00);
+ rtc_write (0x0D, 0x00);
+
+ /* clear Voltage Low bit */
+ rtc_write (0x02, rtc_read (0x02) & 0x7F);
+
+ /* reset all alarms */
+ rtc_write (0x09, 0x00);
+ rtc_write (0x0A, 0x00);
+ rtc_write (0x0B, 0x00);
+ rtc_write (0x0C, 0x00);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static uchar rtc_read (uchar reg)
+{
+ return (i2c_reg_read (CFG_I2C_RTC_ADDR, reg));
+}
+
+static void rtc_write (uchar reg, uchar val)
+{
+ i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val);
+}
+
+static unsigned bcd2bin (uchar n)
+{
+ return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+static unsigned char bin2bcd (unsigned int n)
+{
+ return (((n / 10) << 4) | (n % 10));
+}
+
+#endif /* CFG_CMD_DATE */