Merge with git+ssh://sr@pollux.denx.org/home/sr/git/u-boot/denx-merge-sr

This commit is contained in:
Stefan Roese 2007-01-13 08:01:31 +01:00
commit 44cd6de2e1
15 changed files with 1206 additions and 51 deletions

212
CHANGELOG
View File

@ -1,3 +1,211 @@
commit 787fa15860a57833e50bd30555079a9cd4e519b8
Author: Wolfgang Denk <wd@pollux.denx.de>
Date: Wed Jan 10 01:28:39 2007 +0100
Fix auto_update for MCC200 board.
The invocation of do_auto_update() is moved to the end of the
misc_init_r() function, after the flash mappings have been
initialized. Please find attached a patch that implements that
change.
Also correct the decoding of the keypad status. With this update, the
key that will trigger the update is Column 2, Row 2.
commit 67fea022fa957f59653b5238c7496f80a6b70432
Author: Markus Klotzbuecher <mk@denx.de>
Date: Tue Jan 9 16:02:48 2007 +0100
SPC1920: cleanup memory contoller setup
commit 8fc2102faa23593c80381437c09f7745a14deb40
Author: Markus Klotzbuecher <mk@denx.de>
Date: Tue Jan 9 14:57:14 2007 +0100
Fix the cpu speed setup to work with all boards.
commit 9295acb77481cf099ef9b40e1fa2d145b3c7490c
Author: Markus Klotzbuecher <mk@denx.de>
Date: Tue Jan 9 14:57:13 2007 +0100
SPC1920: add support for the FM18L08 Ramtron FRAM
commit 38ccd2fdf3364a53fe80e9b365303ecdafc9e223
Author: Markus Klotzbuecher <mk@denx.de>
Date: Tue Jan 9 14:57:13 2007 +0100
SPC1920: update the HPI register addresses to work with the second
generation of hardware
commit 5921e5313fc3eadd42770c2b99badd7fae5ecf1e
Author: Markus Klotzbuecher <mk@creamnet.de>
Date: Tue Jan 9 14:57:13 2007 +0100
Miscellanious spc1920 related cleanups
commit e4c2d37adc8bb1bf69dcf600cbc6c75f916a6120
Author: Markus Klotzbuecher <mk@denx.de>
Date: Tue Jan 9 14:57:12 2007 +0100
SPC1920 GO/NOGO led should be set to color red in U-Boot
commit 0be62728aac459ba268d6d752ed49ec0e2bc7348
Author: Markus Klotzbuecher <mk@creamnet.de>
Date: Tue Jan 9 14:57:12 2007 +0100
Add support for the DS3231 RTC
commit 8139567b60d678584b05f0718a681f2047c5e14f
Author: Markus Klotzbuecher <mk@creamnet.de>
Date: Tue Jan 9 14:57:11 2007 +0100
SMC1 uses external CLK4 instead of BRG on spc1920
commit d8d9de1a02fbd880b613d607143d1f57342affc7
Author: Markus Klotzbuecher <mk@creamnet.de>
Date: Tue Jan 9 14:57:10 2007 +0100
Update the SPC1920 CMB PLD driver
commit 3f34f869162750e5e999fd140f884f5de952bcfe
Author: Markus Klotzbuecher <mk@creamnet.de>
Date: Tue Jan 9 14:57:10 2007 +0100
Add / enable I2C support on the spc1920 board
commit d28707dbce1e9ac2017ad051da4133bf22b4204f
Author: Markus Klotzbuecher <mk@creamnet.de>
Date: Tue Jan 9 14:57:10 2007 +0100
Add support for the tms320671x host port interface (HPI)
commit f4eb54529bb3664c3a562e488b460fe075f79d67
Author: Wolfgang Denk <wd@pollux.denx.de>
Date: Sun Jan 7 00:13:11 2007 +0100
Prepare for release 1.2.0
commit f07ae7a9daef27a3d0213a4f3fe39d5342173c02
Author: Stefan Roese <sr@denx.de>
Date: Sat Jan 6 15:58:09 2007 +0100
[PATCH] 44x: Fix problem with DDR controller setup (refresh rate)
This patch fixes a problem with an incorrect setup for the refresh
timer of the 44x DDR controller in the file cpu/ppc4xx/sdram.c
Signed-off-by: Stefan Roese <sr@denx.de>
commit f16c1da9577f06c5fc08651a4065537407de4635
Author: Stefan Roese <sr@denx.de>
Date: Sat Jan 6 15:56:13 2007 +0100
[PATCH] Update ALPR board files
This update brings the ALPR board support to the newest version.
It also fixes a problem with the NAND driver.
Signed-off-by: Stefan Roese <sr@denx.de>
commit cd1d937f90250a32988c37b2b4af8364d25de8ed
Author: Stefan Roese <sr@denx.de>
Date: Fri Jan 5 11:46:05 2007 +0100
[PATCH] nand: Fix problem with oobsize calculation
Here the description from Brian Brelsford <Brian_Brelsford@dell.com>:
The Hynix part returns a 0x1d in the 4th ID byte. The Samsung part
returns a 0x15. In the code fragment below bits [1:0] determine the
page size, it is ANDed via "(extid & 0x3)" then shifted out. The
next field is also ANDed with 0x3. However this is a one bit field
as defined in the Hynix and Samsung parts in the 4th ID byte that
determins the oobsize, not a two bit field. It works on Samsung as
bits[3:2] are 01. However for the Hynix there is a 11 in these two
bits, so the oob size gets messed up.
I checked the correct linux code and the suggested fix from Brian is
also available in the linux nand mtd driver.
Signed-off-by: Stefan Roese <sr@denx.de>
commit a78bc443ae5a4a8ba87590587d5e35bf5a787b2e
Author: Stefan Roese <sr@denx.de>
Date: Fri Jan 5 10:40:36 2007 +0100
[PATCH] Clear PLB4A0_ACR[WRP] on Sequoia (440EPx)
This fix will make the MAL burst disabling patch for the Linux
EMAC driver obsolete.
Signed-off-by: Stefan Roese <sr@denx.de>
commit 023889838282b6237b401664f22dd22dfba2c066
Author: Stefan Roese <sr@denx.de>
Date: Fri Jan 5 10:38:05 2007 +0100
[PATCH] Add DDR2 optimization code for Sequoia (440EPx) board
This code will optimize the DDR2 controller setup on a board specific
basis.
Note: This code doesn't work right now on the NAND booting image for the
Sequoia board, since it doesn't fit into the 4kBytes for the SPL image.
Signed-off-by: Stefan Roese <sr@denx.de>
commit cce4acbb68398634b8d011ed7bb0d12269c84230
Author: Bartlomiej Sieka <tur@semihalf.com>
Date: Thu Dec 28 19:08:21 2006 +0100
Few V38B changes:
- fix a typo in V38B config file
- move watchdog initialisation earlier in the boot process
- add "wdt=off" to default kernel command line (disables kernel watchdog)
commit 92eb729bad876725aeea908d2addba0800620840
Author: Wolfgang Denk <wd@pollux.denx.de>
Date: Wed Dec 27 01:26:13 2006 +0100
Fix bug in adaption of Stefano Babic's CFI driver patch.
commit 9c0f42ecfe25f7ffce8ec7a815f03864d723ffe3
Author: Wolfgang Denk <wd@pollux.denx.de>
Date: Sun Dec 24 01:42:57 2006 +0100
Minor code cleanup.
commit d784fdb05900ada3686d5778783e1fb328e9fb66
Author: Stefano Babic <sbabic@denx.de>
Date: Tue Dec 12 00:22:42 2006 +0100
Fix cfi failure with Spansion Flash (Spansion Flash Devices have a different offset to go into CFI mode)
commit 1b3c360c235dc684ec06c2d5f183f0a282ce45e2
Author: Stefan Roese <sr@denx.de>
Date: Fri Dec 22 14:29:40 2006 +0100
[PATCH] Fix sequoia flash autodetection (finally correct)
Now 32MByte and 64MByte FLASH is know to work and other
configurations should work too.
Signed-off-by: Stefan Roese <sr@denx.de>
commit 82e5236a8b719543643fd26d5827938ab2b94818
Author: Wolfgang Denk <wd@pollux.denx.de>
Date: Fri Dec 22 10:30:26 2006 +0100
Minor code cleanup; update CHANGELOG.
commit fa23044564091f05d9695beb7b5b9a931e7f41a4
Author: Heiko Schocher <hs@pollux.denx.de>
Date: Thu Dec 21 17:17:02 2006 +0100
Added support for the TQM8272 board from TQ
Signed-off-by: Heiko Schocher <hs@denx.de>
commit c84bad0ef60e7055ab0bd49b93069509cecc382a
Author: Bartlomiej Sieka <tur@semihalf.com>
Date: Wed Dec 20 00:29:43 2006 +0100
@ -210,7 +418,7 @@ Date: Mon Nov 27 17:04:06 2006 +0100
[PATCH] Allow CONFIG_OF_FLAT_TREE to boot a non-arch/powerpc kernel
This patch allows an arch/ppc kernel to be booted by just passing 1 or 2
arguments to bootm. It removes the getenv("disable_of") test that used
arguments to bootm. It removes the getenv("disable_of") test that used
to be used for this purpose.
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
@ -908,7 +1116,7 @@ Date: Tue Oct 24 23:47:37 2006 -0500
If a Multi-Image file contains a third image we try to use it as a
device tree. The device tree image is assumed to be uncompressed in the
image file. We automatically allocate space for the device tree in memory
image file. We automatically allocate space for the device tree in memory
and provide an 8k pad to allow more than a reasonable amount of growth.
Additionally, a device tree that was contained in flash will now automatically

View File

@ -22,8 +22,8 @@
#
VERSION = 1
PATCHLEVEL = 1
SUBLEVEL = 6
PATCHLEVEL = 2
SUBLEVEL = 0
EXTRAVERSION =
U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
VERSION_FILE = $(obj)include/version_autogenerated.h
@ -557,6 +557,7 @@ Total5200_Rev2_lowboot_config: unconfig
@$(MKCONFIG) -a Total5200 ppc mpc5xxx total5200
cam5200_config \
cam5200_niosflash_config \
fo300_config \
MiniFAP_config \
TQM5200S_config \
@ -574,6 +575,10 @@ TQM5200_STK100_config: unconfig
echo "#define CONFIG_TQM5200_B" >>$(obj)include/config.h ; \
echo "... TQM5200S on Cam5200" ; \
}
@[ -z "$(findstring niosflash,$@)" ] || \
{ echo "#define CONFIG_CAM5200_NIOSFLASH" >>$(obj)include/config.h ; \
echo "... with NIOS flash driver" ; \
}
@[ -z "$(findstring fo300,$@)" ] || \
{ echo "#define CONFIG_FO300" >>$(obj)include/config.h ; \
echo "... TQM5200 on FO300" ; \

View File

@ -121,10 +121,10 @@ struct flash_layout aufl_layout[AU_MAXFILES] = { \
#define I2C_PSOC_KEYPAD_ADDR 0x53
/* keypad mask */
#define KEYPAD_ROW 3
#define KEYPAD_COL 3
#define KEYPAD_MASK_LO ((1<<(KEYPAD_COL-1+(KEYPAD_ROW*4-4)))&0xFF)
#define KEYPAD_MASK_HI ((1<<(KEYPAD_COL-1+(KEYPAD_ROW*4-4)))>>8)
#define KEYPAD_ROW 2
#define KEYPAD_COL 2
#define KEYPAD_MASK_LO ((1<<(KEYPAD_COL-1+(KEYPAD_ROW*3-3)))&0xFF)
#define KEYPAD_MASK_HI ((1<<(KEYPAD_COL-1+(KEYPAD_ROW*3-3)))>>8)
/* externals */
extern int fat_register_device(block_dev_desc_t *, int);

View File

@ -228,10 +228,6 @@ int misc_init_r (void)
{
ulong flash_sup_end, snum;
#ifdef CONFIG_AUTO_UPDATE
/* this has priority over all else */
do_auto_update();
#endif
/*
* Adjust flash start and offset to detected values
*/
@ -294,6 +290,9 @@ int misc_init_r (void)
flash_info[0].sector_count = snum;
}
#ifdef CONFIG_AUTO_UPDATE
do_auto_update();
#endif
return (0);
}

View File

@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(BOARD).a
COBJS = $(BOARD).o
COBJS = $(BOARD).o hpi.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))

603
board/spc1920/hpi.c Normal file
View File

@ -0,0 +1,603 @@
/*
* (C) Copyright 2006
* Markus Klotzbuecher, DENX Software Engineering, mk@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
*/
/*
* Host Port Interface (HPI)
*/
/* debug levels:
* 0 : errors
* 1 : usefull info
* 2 : lots of info
* 3 : noisy
*/
#define DEBUG 0
#include <config.h>
#include <common.h>
#include <mpc8xx.h>
#include "pld.h"
#include "hpi.h"
#define _NOT_USED_ 0xFFFFFFFF
/* original table:
* - inserted loops to achieve long CS low and high Periods (~217ns)
* - move cs high 2/4 to the right
*/
const uint dsp_table_slow[] =
{
/* single read (offset 0x00 in upm ram) */
0x8fffdc04, 0x0fffdc84, 0x0fffdc84, 0x0fffdc00,
0x3fffdc04, 0xffffdc84, 0xffffdc84, 0xffffdc05,
/* burst read (offset 0x08 in upm ram) */
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
/* single write (offset 0x18 in upm ram) */
0x8fffd004, 0x0fffd084, 0x0fffd084, 0x3fffd000,
0xffffd084, 0xffffd084, 0xffffd005, _NOT_USED_,
/* burst write (offset 0x20 in upm ram) */
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
/* refresh (offset 0x30 in upm ram) */
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
/* exception (offset 0x3C in upm ram) */
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
};
/* dsp hpi upm ram table
* works fine for noninc access, failes on incremental.
* - removed first word
*/
const uint dsp_table_fast[] =
{
/* single read (offset 0x00 in upm ram) */
0x8fffdc04, 0x0fffdc04, 0x0fffdc00, 0x3fffdc04,
0xffffdc05, _NOT_USED_, _NOT_USED_, _NOT_USED_,
/* burst read (offset 0x08 in upm ram) */
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
/* single write (offset 0x18 in upm ram) */
0x8fffd004, 0x0fffd004, 0x3fffd000, 0xffffd005,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
/* burst write (offset 0x20 in upm ram) */
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
/* refresh (offset 0x30 in upm ram) */
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
/* exception (offset 0x3C in upm ram) */
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
};
#ifdef CONFIG_SPC1920_HPI_TEST
#undef HPI_TEST_OSZI
#define HPI_TEST_CHUNKSIZE 0x1000
#define HPI_TEST_PATTERN 0x00000000
#define HPI_TEST_START 0x0
#define HPI_TEST_END 0x30000
#define TINY_AUTOINC_DATA_SIZE 16 /* 32bit words */
#define TINY_AUTOINC_BASE_ADDR 0x0
static int hpi_activate(void);
static void hpi_inactivate(void);
static void dsp_reset(void);
static int hpi_write_inc(u32 addr, u32 *data, u32 count);
static int hpi_read_inc(u32 addr, u32 *buf, u32 count);
static int hpi_write_noinc(u32 addr, u32 data);
static u32 hpi_read_noinc(u32 addr);
int hpi_test(void);
static int hpi_write_addr_test(u32 addr);
static int hpi_read_write_test(u32 addr, u32 data);
static int hpi_tiny_autoinc_test(void);
#endif /* CONFIG_SPC1920_HPI_TEST */
/* init the host port interface on UPMA */
int hpi_init(void)
{
volatile immap_t *immr = (immap_t *) CFG_IMMR;
volatile memctl8xx_t *memctl = &immr->im_memctl;
volatile spc1920_pld_t *pld = (spc1920_pld_t *) CFG_SPC1920_PLD_BASE;
upmconfig(UPMA, (uint *)dsp_table_slow, sizeof(dsp_table_slow)/sizeof(uint));
udelay(100);
memctl->memc_mamr = CFG_MAMR;
memctl->memc_or3 = CFG_OR3;
memctl->memc_br3 = CFG_BR3;
/* reset dsp */
dsp_reset();
/* activate hpi switch*/
pld->dsp_hpi_on = 0x1;
udelay(100);
return 0;
}
#ifdef CONFIG_SPC1920_HPI_TEST
/* activate the Host Port interface */
static int hpi_activate(void)
{
volatile spc1920_pld_t *pld = (spc1920_pld_t *) CFG_SPC1920_PLD_BASE;
/* turn on hpi */
pld->dsp_hpi_on = 0x1;
udelay(5);
/* turn on the power EN_DSP_POWER high*/
/* currently always on TBD */
/* setup hpi control register */
HPI_HPIC_1 = (u16) 0x0008;
HPI_HPIC_2 = (u16) 0x0008;
udelay(100);
return 0;
}
/* turn off the host port interface */
static void hpi_inactivate(void)
{
volatile spc1920_pld_t *pld = (spc1920_pld_t *) CFG_SPC1920_PLD_BASE;
/* deactivate hpi */
pld->dsp_hpi_on = 0x0;
/* reset the dsp */
/* pld->dsp_reset = 0x0; */
/* turn off the power EN_DSP_POWER# high*/
/* currently always on TBD */
}
/* reset the DSP */
static void dsp_reset(void)
{
volatile spc1920_pld_t *pld = (spc1920_pld_t *) CFG_SPC1920_PLD_BASE;
pld->dsp_reset = 0x1;
pld->dsp_hpi_on = 0x0;
udelay(300000);
pld->dsp_reset = 0x0;
pld->dsp_hpi_on = 0x1;
}
/* write using autoinc (count is number of 32bit words) */
static int hpi_write_inc(u32 addr, u32 *data, u32 count)
{
int i;
u16 addr1, addr2;
addr1 = (u16) ((addr >> 16) & 0xffff); /* First HW is most significant */
addr2 = (u16) (addr & 0xffff);
/* write address */
HPI_HPIA_1 = addr1;
HPI_HPIA_2 = addr2;
debugX(4, "writing from data=0x%x to 0x%x\n", data, (data+count));
for(i=0; i<count; i++) {
HPI_HPID_INC_1 = (u16) ((data[i] >> 16) & 0xffff);
HPI_HPID_INC_2 = (u16) (data[i] & 0xffff);
debugX(4, "hpi_write_inc: data1=0x%x, data2=0x%x\n",
(u16) ((data[i] >> 16) & 0xffff),
(u16) (data[i] & 0xffff));
}
#if 0
while(data_ptr < (u16*) (data + count)) {
HPI_HPID_INC_1 = *(data_ptr++);
HPI_HPID_INC_2 = *(data_ptr++);
}
#endif
/* return number of bytes written */
return count;
}
/*
* read using autoinc (count is number of 32bit words)
*/
static int hpi_read_inc(u32 addr, u32 *buf, u32 count)
{
int i;
u16 addr1, addr2, data1, data2;
addr1 = (u16) ((addr >> 16) & 0xffff); /* First HW is most significant */
addr2 = (u16) (addr & 0xffff);
/* write address */
HPI_HPIA_1 = addr1;
HPI_HPIA_2 = addr2;
for(i=0; i<count; i++) {
data1 = HPI_HPID_INC_1;
data2 = HPI_HPID_INC_2;
debugX(4, "hpi_read_inc: data1=0x%x, data2=0x%x\n", data1, data2);
buf[i] = (((u32) data1) << 16) | (data2 & 0xffff);
}
#if 0
while(buf_ptr < (u16*) (buf + count)) {
*(buf_ptr++) = HPI_HPID_INC_1;
*(buf_ptr++) = HPI_HPID_INC_2;
}
#endif
/* return number of bytes read */
return count;
}
/* write to non- auto inc regs */
static int hpi_write_noinc(u32 addr, u32 data)
{
u16 addr1, addr2, data1, data2;
addr1 = (u16) ((addr >> 16) & 0xffff); /* First HW is most significant */
addr2 = (u16) (addr & 0xffff);
/* printf("hpi_write_noinc: addr1=0x%x, addr2=0x%x\n", addr1, addr2); */
HPI_HPIA_1 = addr1;
HPI_HPIA_2 = addr2;
data1 = (u16) ((data >> 16) & 0xffff);
data2 = (u16) (data & 0xffff);
/* printf("hpi_write_noinc: data1=0x%x, data2=0x%x\n", data1, data2); */
HPI_HPID_NOINC_1 = data1;
HPI_HPID_NOINC_2 = data2;
return 0;
}
/* read from non- auto inc regs */
static u32 hpi_read_noinc(u32 addr)
{
u16 addr1, addr2, data1, data2;
u32 ret;
addr1 = (u16) ((addr >> 16) & 0xffff); /* First HW is most significant */
addr2 = (u16) (addr & 0xffff);
HPI_HPIA_1 = addr1;
HPI_HPIA_2 = addr2;
/* printf("hpi_read_noinc: addr1=0x%x, addr2=0x%x\n", addr1, addr2); */
data1 = HPI_HPID_NOINC_1;
data2 = HPI_HPID_NOINC_2;
/* printf("hpi_read_noinc: data1=0x%x, data2=0x%x\n", data1, data2); */
ret = (((u32) data1) << 16) | (data2 & 0xffff);
return ret;
}
/*
* Host Port Interface Tests
*/
#ifndef HPI_TEST_OSZI
/* main test function */
int hpi_test(void)
{
int err = 0;
u32 i, ii, pattern, tmp;
pattern = HPI_TEST_PATTERN;
u32 test_data[HPI_TEST_CHUNKSIZE];
u32 read_data[HPI_TEST_CHUNKSIZE];
debugX(2, "hpi_test: activating hpi...");
hpi_activate();
debugX(2, "OK.\n");
#if 0
/* Dump the first 1024 bytes
*
*/
for(i=0; i<1024; i+=4) {
if(i%16==0)
printf("\n0x%08x: ", i);
printf("0x%08x ", hpi_read_noinc(i));
}
#endif
/* HPIA read-write test
*
*/
debugX(1, "hpi_test: starting HPIA read-write tests...\n");
err |= hpi_write_addr_test(0xdeadc0de);
err |= hpi_write_addr_test(0xbeefd00d);
err |= hpi_write_addr_test(0xabcd1234);
err |= hpi_write_addr_test(0xaaaaaaaa);
if(err) {
debugX(1, "hpi_test: HPIA read-write tests: *** FAILED ***\n");
return -1;
}
debugX(1, "hpi_test: HPIA read-write tests: OK\n");
/* read write test using nonincremental data regs
*
*/
debugX(1, "hpi_test: starting nonincremental tests...\n");
for(i=HPI_TEST_START; i<HPI_TEST_END; i+=4) {
err |= hpi_read_write_test(i, pattern);
/* stolen from cmd_mem.c */
if(pattern & 0x80000000) {
pattern = -pattern; /* complement & increment */
} else {
pattern = ~pattern;
}
err |= hpi_read_write_test(i, pattern);
if(err) {
debugX(1, "hpi_test: nonincremental tests *** FAILED ***\n");
return -1;
}
}
debugX(1, "hpi_test: nonincremental test OK\n");
/* read write a chunk of data using nonincremental data regs
*
*/
debugX(1, "hpi_test: starting nonincremental chunk tests...\n");
pattern = HPI_TEST_PATTERN;
for(i=HPI_TEST_START; i<HPI_TEST_END; i+=4) {
hpi_write_noinc(i, pattern);
/* stolen from cmd_mem.c */
if(pattern & 0x80000000) {
pattern = -pattern; /* complement & increment */
} else {
pattern = ~pattern;
}
}
pattern = HPI_TEST_PATTERN;
for(i=HPI_TEST_START; i<HPI_TEST_END; i+=4) {
tmp = hpi_read_noinc(i);
if(tmp != pattern) {
debugX(1, "hpi_test: noninc chunk test *** FAILED *** @ 0x%x, written=0x%x, read=0x%x\n", i, pattern, tmp);
err = -1;
}
/* stolen from cmd_mem.c */
if(pattern & 0x80000000) {
pattern = -pattern; /* complement & increment */
} else {
pattern = ~pattern;
}
}
if(err)
return -1;
debugX(1, "hpi_test: nonincremental chunk test OK\n");
#ifdef DO_TINY_TEST
/* small verbose test using autoinc and nonautoinc to compare
*
*/
debugX(1, "hpi_test: tiny_autoinc_test...\n");
hpi_tiny_autoinc_test();
debugX(1, "hpi_test: tiny_autoinc_test done\n");
#endif /* DO_TINY_TEST */
/* $%& write a chunk of data using the autoincremental regs
*
*/
debugX(1, "hpi_test: starting autoinc test %d chunks with 0x%x bytes...\n",
((HPI_TEST_END - HPI_TEST_START) / HPI_TEST_CHUNKSIZE),
HPI_TEST_CHUNKSIZE);
for(i=HPI_TEST_START;
i < ((HPI_TEST_END - HPI_TEST_START) / HPI_TEST_CHUNKSIZE);
i++) {
/* generate the pattern data */
debugX(3, "generating pattern data: ");
for(ii = 0; ii < HPI_TEST_CHUNKSIZE; ii++) {
debugX(3, "0x%x ", pattern);
test_data[ii] = pattern;
read_data[ii] = 0x0; /* zero to be sure */
/* stolen from cmd_mem.c */
if(pattern & 0x80000000) {
pattern = -pattern; /* complement & increment */
} else {
pattern = ~pattern;
}
}
debugX(3, "done\n");
debugX(2, "Writing autoinc data @ 0x%x\n", i);
hpi_write_inc(i, test_data, HPI_TEST_CHUNKSIZE);
debugX(2, "Reading autoinc data @ 0x%x\n", i);
hpi_read_inc(i, read_data, HPI_TEST_CHUNKSIZE);
/* compare */
for(ii = 0; ii < HPI_TEST_CHUNKSIZE; ii++) {
debugX(3, "hpi_test_autoinc: @ 0x%x, written=0x%x, read=0x%x", i+ii, test_data[ii], read_data[ii]);
if(read_data[ii] != test_data[ii]) {
debugX(0, "hpi_test: autoinc test @ 0x%x, written=0x%x, read=0x%x *** FAILED ***\n", i+ii, test_data[ii], read_data[ii]);
return -1;
}
}
}
debugX(1, "hpi_test: autoinc test OK\n");
return 0;
}
#else /* HPI_TEST_OSZI */
int hpi_test(void)
{
int i;
u32 read_data[TINY_AUTOINC_DATA_SIZE];
unsigned int dummy_data[TINY_AUTOINC_DATA_SIZE] = {
0x11112222, 0x33334444, 0x55556666, 0x77778888,
0x9999aaaa, 0xbbbbcccc, 0xddddeeee, 0xffff1111,
0x00010002, 0x00030004, 0x00050006, 0x00070008,
0x0009000a, 0x000b000c, 0x000d000e, 0x000f0001
};
debugX(0, "hpi_test: activating hpi...");
hpi_activate();
debugX(0, "OK.\n");
while(1) {
led9(1);
debugX(0, " writing to autoinc...\n");
hpi_write_inc(TINY_AUTOINC_BASE_ADDR,
dummy_data, TINY_AUTOINC_DATA_SIZE);
debugX(0, " reading from autoinc...\n");
hpi_read_inc(TINY_AUTOINC_BASE_ADDR,
read_data, TINY_AUTOINC_DATA_SIZE);
for(i=0; i < (TINY_AUTOINC_DATA_SIZE); i++) {
debugX(0, " written=0x%x, read(inc)=0x%x\n",
dummy_data[i], read_data[i]);
}
led9(0);
udelay(2000000);
}
return 0;
}
#endif
/* test if Host Port Address Register can be written correctly */
static int hpi_write_addr_test(u32 addr)
{
u32 read_back;
/* write address */
HPI_HPIA_1 = ((u16) (addr >> 16)); /* First HW is most significant */
HPI_HPIA_2 = ((u16) addr);
read_back = (((u32) HPI_HPIA_1)<<16) | ((u32) HPI_HPIA_2);
if(read_back == addr) {
debugX(2, " hpi_write_addr_test OK: written=0x%x, read=0x%x\n",
addr, read_back);
return 0;
} else {
debugX(0, " hpi_write_addr_test *** FAILED ***: written=0x%x, read=0x%x\n",
addr, read_back);
return -1;
}
return 0;
}
/* test if a simple read/write sequence succeeds */
static int hpi_read_write_test(u32 addr, u32 data)
{
u32 read_back;
hpi_write_noinc(addr, data);
read_back = hpi_read_noinc(addr);
if(read_back == data) {
debugX(2, " hpi_read_write_test: OK, addr=0x%x written=0x%x, read=0x%x\n", addr, data, read_back);
return 0;
} else {
debugX(0, " hpi_read_write_test: *** FAILED ***, addr=0x%x written=0x%x, read=0x%x\n", addr, data, read_back);
return -1;
}
return 0;
}
static int hpi_tiny_autoinc_test(void)
{
int i;
u32 read_data[TINY_AUTOINC_DATA_SIZE];
u32 read_data_noinc[TINY_AUTOINC_DATA_SIZE];
unsigned int dummy_data[TINY_AUTOINC_DATA_SIZE] = {
0x11112222, 0x33334444, 0x55556666, 0x77778888,
0x9999aaaa, 0xbbbbcccc, 0xddddeeee, 0xffff1111,
0x00010002, 0x00030004, 0x00050006, 0x00070008,
0x0009000a, 0x000b000c, 0x000d000e, 0x000f0001
};
printf(" writing to autoinc...\n");
hpi_write_inc(TINY_AUTOINC_BASE_ADDR, dummy_data, TINY_AUTOINC_DATA_SIZE);
printf(" reading from autoinc...\n");
hpi_read_inc(TINY_AUTOINC_BASE_ADDR, read_data, TINY_AUTOINC_DATA_SIZE);
printf(" reading from noinc for comparison...\n");
for(i=0; i < (TINY_AUTOINC_DATA_SIZE); i++)
read_data_noinc[i] = hpi_read_noinc(TINY_AUTOINC_BASE_ADDR+i*4);
for(i=0; i < (TINY_AUTOINC_DATA_SIZE); i++) {
printf(" written=0x%x, read(inc)=0x%x, read(noinc)=0x%x\n",
dummy_data[i], read_data[i], read_data_noinc[i]);
}
return 0;
}
#endif /* CONFIG_SPC1920_HPI_TEST */

28
board/spc1920/hpi.h Normal file
View File

@ -0,0 +1,28 @@
/*
* (C) Copyright 2006
* Markus Klotzbuecher, DENX Software Engineering, mk@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
*/
int hpi_init(void);
#ifdef CONFIG_SPC1920_HPI_TEST
int hpi_test(void);
#endif

View File

@ -5,8 +5,8 @@ typedef struct spc1920_pld {
uchar com1_en;
uchar dsp_reset;
uchar dsp_hpi_on;
uchar superv_mode;
uchar codec_dsp_power_en;
uchar clk2_en;
uchar clk3_select;
uchar clk4_select;
} spc1920_pld_t;

View File

@ -27,9 +27,9 @@
#include <common.h>
#include <mpc8xx.h>
#include "pld.h"
#include "hpi.h"
#define _NOT_USED_ 0xFFFFFFFF
/* #define debug(fmt,args...) printf (fmt ,##args) */
static long int dram_size (long int, long int *, long int);
@ -172,10 +172,12 @@ long int initdram (int board_type)
memctl->memc_br1 = (CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMB | BR_V;
udelay (1000);
/* initalize the DSP Host Port Interface */
hpi_init();
/* PLD Setup */
memctl->memc_or5 = CFG_OR5_PRELIM;
memctl->memc_br5 = CFG_BR5_PRELIM;
/* FRAM Setup */
memctl->memc_or4 = CFG_OR4;
memctl->memc_br4 = CFG_BR4;
udelay(1000);
return (size_b0);
@ -207,13 +209,31 @@ int board_early_init_f(void)
{
volatile immap_t *immap = (immap_t *) CFG_IMMR;
/* Set Go/NoGo led (PA15) to color red */
immap->im_ioport.iop_papar &= ~0x1;
immap->im_ioport.iop_paodr &= ~0x1;
immap->im_ioport.iop_padir |= 0x1;
immap->im_ioport.iop_padat |= 0x1;
#if 0
/* Turn on LED PD9 */
immap->im_ioport.iop_pdpar &= ~(0x0040);
immap->im_ioport.iop_pddir |= 0x0040;
immap->im_ioport.iop_pddat |= 0x0040;
#endif
/* Enable PD10 (COM2_EN) */
/*
* Enable console on SMC1. This requires turning on
* the com2_en signal and SMC1_DISABLE
*/
/* SMC1_DISABLE: PB17 */
immap->im_cpm.cp_pbodr &= ~0x4000;
immap->im_cpm.cp_pbpar &= ~0x4000;
immap->im_cpm.cp_pbdir |= 0x4000;
immap->im_cpm.cp_pbdat &= ~0x4000;
/* COM2_EN: PD10 */
immap->im_ioport.iop_pdpar &= ~0x0020;
immap->im_ioport.iop_pddir &= ~0x4000;
immap->im_ioport.iop_pddir |= 0x0020;
@ -228,6 +248,14 @@ int board_early_init_f(void)
return 0;
}
int last_stage_init(void)
{
#ifdef CONFIG_SPC1920_HPI_TEST
printf("CMB1920 Host Port Interface Test: %s\n",
hpi_test() ? "Failed!" : "OK");
#endif
return 0;
}
int checkboard (void)
{

View File

@ -25,7 +25,7 @@
#include <mpc5xxx.h>
#include <asm/processor.h>
#ifdef CONFIG_CAM5200
#if defined(CONFIG_CAM5200) && defined(CONFIG_CAM5200_NIOSFLASH)
#if 0
#define DEBUGF(x...) printf(x)
@ -783,4 +783,4 @@ unsigned long flash_init(void)
return total_b;
}
#endif /* ifdef CONFIG_CAM5200 */
#endif /* if defined(CONFIG_CAM5200) && defined(CONFIG_CAM5200_NIOSFLASH) */

View File

@ -227,8 +227,17 @@ static int smc_init (void)
sp->smc_smcm = 0;
sp->smc_smce = 0xff;
#ifdef CFG_SPC1920_SMC1_CLK4 /* clock source is PLD */
*((volatile uchar *) CFG_SPC1920_PLD_BASE+6) = 0xff;
#ifdef CFG_SPC1920_SMC1_CLK4
/* clock source is PLD */
/* set freq to 19200 Baud */
*((volatile uchar *) CFG_SPC1920_PLD_BASE+6) = 0x3;
/* configure clk4 as input */
im->im_ioport.iop_pdpar |= 0x800;
im->im_ioport.iop_pddir &= ~0x800;
cp->cp_simode = 0x0000;
cp->cp_simode |= 0x7000;
#else
/* Set up the baud rate generator */
smc_setbrg ();

View File

@ -231,6 +231,17 @@
"protect on FC000000 +${filesize}\0"
#endif
#ifndef CONFIG_CAM5200
#define CUSTOM_ENV_SETTINGS \
"bootfile=/tftpboot/tqm5200/uImage\0" \
"u-boot=/tftpboot/tqm5200/u-boot.bin\0"
#else
#define CUSTOM_ENV_SETTINGS \
"bootfile=cam5200/uImage\0" \
"u-boot=cam5200/u-boot.bin\0" \
"setup=tftp 200000 cam5200/setup.img; autoscr 200000\0"
#endif
#define CONFIG_EXTRA_ENV_SETTINGS \
"netdev=eth0\0" \
"rootpath=/opt/eldk/ppc_6xx\0" \
@ -248,8 +259,7 @@
"bootm ${kernel_addr}\0" \
"net_nfs=tftp 200000 ${bootfile};run nfsargs addip addcons;" \
"bootm\0" \
"bootfile=/tftpboot/tqm5200/uImage\0" \
"u-boot=/tftpboot/tqm5200/u-boot.bin\0" \
CUSTOM_ENV_SETTINGS \
"load=tftp 200000 ${u-boot}\0" \
ENV_UPDT \
""
@ -325,15 +335,7 @@
*/
#define CFG_FLASH_BASE 0xFC000000
#ifndef CONFIG_CAM5200
/* use CFI flash driver */
#define CFG_FLASH_CFI 1 /* Flash is CFI conformant */
#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */
#define CFG_FLASH_BANKS_LIST { CFG_BOOTCS_START }
#define CFG_MAX_FLASH_BANKS 1 /* max num of flash banks
(= chip selects) */
#define CFG_MAX_FLASH_SECT 512 /* max num of sects on one chip */
#else /* CONFIG_CAM5200 */
#if defined(CONFIG_CAM5200) && defined(CONFIG_CAM5200_NIOSFLASH)
#define CFG_MAX_FLASH_BANKS 2 /* max num of flash banks
(= chip selects) */
#define CFG_FLASH_WORD_SIZE unsigned int /* main flash device with */
@ -344,7 +346,15 @@
#define CFG_FLASH_ADDR1 0x2AA
#define CFG_FLASH_2ND_16BIT_DEV 1 /* NIOS flash is a 16bit device */
#define CFG_MAX_FLASH_SECT 128
#endif /* ifndef CONFIG_CAM5200 */
#else
/* use CFI flash driver */
#define CFG_FLASH_CFI 1 /* Flash is CFI conformant */
#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */
#define CFG_FLASH_BANKS_LIST { CFG_BOOTCS_START }
#define CFG_MAX_FLASH_BANKS 1 /* max num of flash banks
(= chip selects) */
#define CFG_MAX_FLASH_SECT 512 /* max num of sects on one chip */
#endif
#define CFG_FLASH_EMPTY_INFO
#define CFG_FLASH_SIZE 0x04000000 /* 64 MByte */

View File

@ -44,19 +44,19 @@
#define CONFIG_BAUDRATE 19200
/* use PLD CLK4 instead of brg */
#undef CFG_SPC1920_SMC1_CLK4
#define CFG_SPC1920_SMC1_CLK4
#define CONFIG_8xx_OSCLK 10000000 /* 10 MHz oscillator on EXTCLK */
#define CONFIG_8xx_CPUCLK_DEFAULT 50000000
#define CFG_8xx_CPUCLK_MIN 40000000
#define CFG_8xx_CPUCLK_MAX 133000000
#define CFG_RESET_ADDRESS 0xf8000000
#define CFG_RESET_ADDRESS 0xC0000000
#define CONFIG_BOARD_EARLY_INIT_F
#define CONFIG_LAST_STAGE_INIT
#if 1
#if 0
#define CONFIG_BOOTDELAY -1 /* autoboot disabled */
#else
#define CONFIG_BOOTDELAY 5 /* autoboot after 5 seconds */
@ -83,12 +83,13 @@
#ifndef CONFIG_COMMANDS
#define CONFIG_COMMANDS (CONFIG_CMD_DFL \
| CFG_CMD_ASKENV \
| CFG_CMD_DATE \
| CFG_CMD_ECHO \
| CFG_CMD_IMMAP \
| CFG_CMD_JFFS2 \
| CFG_CMD_PING \
| CFG_CMD_DHCP \
| CFG_CMD_IMMAP \
| CFG_CMD_I2C \
| CFG_CMD_MII)
/* & ~( CFG_CMD_NET)) */
@ -193,13 +194,39 @@
#define CFG_CACHELINE_SIZE 16 /* For all MPC8xx CPUs */
#define CFG_CACHELINE_SHIFT 4 /* log base 2 of the above value */
#ifdef CFG_CMD_DATE
# define CONFIG_RTC_DS3231
# define CFG_I2C_RTC_ADDR 0x68
#endif
/*-----------------------------------------------------------------------
* I2C configuration
*/
#if (CONFIG_COMMANDS & CFG_CMD_I2C)
#define CONFIG_HARD_I2C 1 /* I2C with hardware support */
#define CFG_I2C_SPEED 400000 /* I2C speed and slave address defaults */
#define CFG_I2C_SLAVE 0x7F
/* enable I2C and select the hardware/software driver */
#undef CONFIG_HARD_I2C /* I2C with hardware support */
#define CONFIG_SOFT_I2C 1 /* I2C bit-banged */
#define CFG_I2C_SPEED 93000 /* 93 kHz is supposed to work */
#define CFG_I2C_SLAVE 0xFE
#ifdef CONFIG_SOFT_I2C
/*
* Software (bit-bang) I2C driver configuration
*/
#define PB_SCL 0x00000020 /* PB 26 */
#define PB_SDA 0x00000010 /* PB 27 */
#define I2C_INIT (immr->im_cpm.cp_pbdir |= PB_SCL)
#define I2C_ACTIVE (immr->im_cpm.cp_pbdir |= PB_SDA)
#define I2C_TRISTATE (immr->im_cpm.cp_pbdir &= ~PB_SDA)
#define I2C_READ ((immr->im_cpm.cp_pbdat & PB_SDA) != 0)
#define I2C_SDA(bit) if(bit) immr->im_cpm.cp_pbdat |= PB_SDA; \
else immr->im_cpm.cp_pbdat &= ~PB_SDA
#define I2C_SCL(bit) if(bit) immr->im_cpm.cp_pbdat |= PB_SCL; \
else immr->im_cpm.cp_pbdat &= ~PB_SCL
#define I2C_DELAY udelay(2) /* 1/4 I2C clock duration */
#endif /* CONFIG_SOFT_I2C */
#endif
/*-----------------------------------------------------------------------
@ -220,7 +247,7 @@
*-----------------------------------------------------------------------
* PCMCIA config., multi-function pin tri-state
*/
#define CFG_SIUMCR (SIUMCR_DBGC00 | SIUMCR_DBPC00 | SIUMCR_MLRC01)
#define CFG_SIUMCR (SIUMCR_FRC)
/*-----------------------------------------------------------------------
* TBSCR - Time Base Status and Control 11-26
@ -283,7 +310,7 @@
* FLASH timing:
*/
#define CFG_OR_TIMING_FLASH (OR_ACS_DIV1 | OR_TRLX | OR_CSNT_SAM | \
OR_SCY_3_CLK | OR_EHTR | OR_BI)
OR_SCY_6_CLK | OR_EHTR | OR_BI)
#define CFG_OR0_REMAP (CFG_REMAP_OR_AM | CFG_OR_TIMING_FLASH)
#define CFG_OR0_PRELIM (CFG_PRELIM_OR_AM | CFG_OR_TIMING_FLASH)
@ -330,7 +357,56 @@
MBMR_TLFB_4X) /* 0x04804114 */ /* 0x10802114 */
/* PLD CS5 */
/*
* DSP Host Port Interface CS3
*/
#define CFG_SPC1920_HPI_BASE 0x90000000
#define CFG_PRELIM_OR3_AM 0xF8000000
#define CFG_OR3 (CFG_PRELIM_OR3_AM | \
OR_G5LS | \
OR_SCY_0_CLK | \
OR_BI)
#define CFG_BR3 ((CFG_SPC1920_HPI_BASE & BR_BA_MSK) | \
BR_MS_UPMA | \
BR_PS_16 | \
BR_V);
#define CFG_MAMR (MAMR_GPL_A4DIS | \
MAMR_RLFA_5X | \
MAMR_WLFA_5X)
#define CONFIG_SPC1920_HPI_TEST
#ifdef CONFIG_SPC1920_HPI_TEST
#define HPI_REG(x) (*((volatile u16 *) (CFG_SPC1920_HPI_BASE + x)))
#define HPI_HPIC_1 HPI_REG(0)
#define HPI_HPIC_2 HPI_REG(2)
#define HPI_HPIA_1 HPI_REG(0x2000008)
#define HPI_HPIA_2 HPI_REG(0x2000008 + 2)
#define HPI_HPID_INC_1 HPI_REG(0x1000004)
#define HPI_HPID_INC_2 HPI_REG(0x1000004 + 2)
#define HPI_HPID_NOINC_1 HPI_REG(0x300000c)
#define HPI_HPID_NOINC_2 HPI_REG(0x300000c + 2)
#endif /* CONFIG_SPC1920_HPI_TEST */
/*
* Ramtron FM18L08 FRAM 32KB on CS4
*/
#define CFG_SPC1920_FRAM_BASE 0x80100000
#define CFG_PRELIM_OR4_AM 0xffff8000
#define CFG_OR4 (CFG_PRELIM_OR4_AM | \
OR_ACS_DIV2 | \
OR_BI | \
OR_SCY_4_CLK | \
OR_TRLX)
#define CFG_BR4 ((CFG_SPC1920_FRAM_BASE & BR_BA_MSK) | BR_PS_8 | BR_V);
/*
* PLD CS5
*/
#define CFG_SPC1920_PLD_BASE 0x80000000
#define CFG_PRELIM_OR5_AM 0xffff8000
@ -343,10 +419,6 @@
#define CFG_BR5_PRELIM ((CFG_SPC1920_PLD_BASE & BR_BA_MSK) | BR_PS_8 | BR_V);
/* #define CFG_PLD_BASE 0x30000000 */
/* #define CFG_OR5_PRELIM 0xffff1110 */
/* #define CFG_BR5_PRELIM 0x30000401 */
/*
* Internal Definitions
*

View File

@ -29,7 +29,7 @@ LIB = $(obj)librtc.a
COBJS = date.o \
bf533_rtc.o ds12887.o ds1302.o ds1306.o ds1307.o \
ds1337.o ds1374.o ds1556.o ds164x.o ds174x.o \
ds1337.o ds1374.o ds1556.o ds164x.o ds174x.o ds3231.o \
m41t11.o max6900.o m48t35ax.o mc146818.o mk48t59.o \
mpc5xxx.o mpc8xx.o pcf8563.o s3c24x0_rtc.o rs5c372.o

193
rtc/ds3231.c Normal file
View File

@ -0,0 +1,193 @@
/*
* (C) Copyright 2006
* Markus Klotzbuecher, mk@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 (no alarms) for Dallas Semiconductor (now Maxim)
* Extremly Accurate DS3231 Real Time Clock (RTC).
*
* copied from ds1337.c
*/
#include <common.h>
#include <command.h>
#include <rtc.h>
#include <i2c.h>
#if defined(CONFIG_RTC_DS3231) && (CONFIG_COMMANDS & CFG_CMD_DATE)
/*---------------------------------------------------------------------*/
#undef DEBUG_RTC
#ifdef DEBUG_RTC
#define DEBUGR(fmt,args...) printf(fmt ,##args)
#else
#define DEBUGR(fmt,args...)
#endif
/*---------------------------------------------------------------------*/
/*
* RTC register addresses
*/
#define RTC_SEC_REG_ADDR 0x0
#define RTC_MIN_REG_ADDR 0x1
#define RTC_HR_REG_ADDR 0x2
#define RTC_DAY_REG_ADDR 0x3
#define RTC_DATE_REG_ADDR 0x4
#define RTC_MON_REG_ADDR 0x5
#define RTC_YR_REG_ADDR 0x6
#define RTC_CTL_REG_ADDR 0x0e
#define RTC_STAT_REG_ADDR 0x0f
/*
* RTC control register bits
*/
#define RTC_CTL_BIT_A1IE 0x1 /* Alarm 1 interrupt enable */
#define RTC_CTL_BIT_A2IE 0x2 /* Alarm 2 interrupt enable */
#define RTC_CTL_BIT_INTCN 0x4 /* Interrupt control */
#define RTC_CTL_BIT_RS1 0x8 /* Rate select 1 */
#define RTC_CTL_BIT_RS2 0x10 /* Rate select 2 */
#define RTC_CTL_BIT_DOSC 0x80 /* Disable Oscillator */
/*
* RTC status register bits
*/
#define RTC_STAT_BIT_A1F 0x1 /* Alarm 1 flag */
#define RTC_STAT_BIT_A2F 0x2 /* Alarm 2 flag */
#define RTC_STAT_BIT_OSF 0x80 /* Oscillator stop flag */
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);
/*
* Get the current time from the RTC
*/
void rtc_get (struct rtc_time *tmp)
{
uchar sec, min, hour, mday, wday, mon_cent, year, control, status;
control = rtc_read (RTC_CTL_REG_ADDR);
status = rtc_read (RTC_STAT_REG_ADDR);
sec = rtc_read (RTC_SEC_REG_ADDR);
min = rtc_read (RTC_MIN_REG_ADDR);
hour = rtc_read (RTC_HR_REG_ADDR);
wday = rtc_read (RTC_DAY_REG_ADDR);
mday = rtc_read (RTC_DATE_REG_ADDR);
mon_cent = rtc_read (RTC_MON_REG_ADDR);
year = rtc_read (RTC_YR_REG_ADDR);
DEBUGR ("Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
"hr: %02x min: %02x sec: %02x control: %02x status: %02x\n",
year, mon_cent, mday, wday, hour, min, sec, control, status);
if (status & RTC_STAT_BIT_OSF) {
printf ("### Warning: RTC oscillator has stopped\n");
/* clear the OSF flag */
rtc_write (RTC_STAT_REG_ADDR,
rtc_read (RTC_STAT_REG_ADDR) & ~RTC_STAT_BIT_OSF);
}
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 - 1) & 0x07);
tmp->tm_yday = 0;
tmp->tm_isdst= 0;
DEBUGR ("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);
}
/*
* Set the RTC
*/
void rtc_set (struct rtc_time *tmp)
{
uchar century;
DEBUGR ("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 (RTC_YR_REG_ADDR, bin2bcd (tmp->tm_year % 100));
century = (tmp->tm_year >= 2000) ? 0x80 : 0;
rtc_write (RTC_MON_REG_ADDR, bin2bcd (tmp->tm_mon) | century);
rtc_write (RTC_DAY_REG_ADDR, bin2bcd (tmp->tm_wday + 1));
rtc_write (RTC_DATE_REG_ADDR, bin2bcd (tmp->tm_mday));
rtc_write (RTC_HR_REG_ADDR, bin2bcd (tmp->tm_hour));
rtc_write (RTC_MIN_REG_ADDR, bin2bcd (tmp->tm_min));
rtc_write (RTC_SEC_REG_ADDR, bin2bcd (tmp->tm_sec));
}
/*
* Reset the RTC. We also enable the oscillator output on the
* SQW/INTB* pin and program it for 32,768 Hz output. Note that
* according to the datasheet, turning on the square wave output
* increases the current drain on the backup battery from about
* 600 nA to 2uA.
*/
void rtc_reset (void)
{
rtc_write (RTC_CTL_REG_ADDR, RTC_CTL_BIT_RS1 | RTC_CTL_BIT_RS2);
}
/*
* Helper functions
*/
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 /* (CONFIG_RTC_DS3231) && (CONFIG_COMMANDS & CFG_CMD_DATE) */