* Patches by Richard Woodruff, 01 Oct 2004:

add support for the TI OMAP2420 processor and its H4 reference
  board

* Patch by Christian Pellegrin, 24 Sep 2004:
  Added support for NE2000 compatible (DP8390, DP83902) NICs.
This commit is contained in:
wdenk 2005-01-09 23:16:25 +00:00
parent ff36fd8591
commit 8ed9604613
41 changed files with 6158 additions and 28 deletions

View file

@ -2,6 +2,13 @@
Changes for U-Boot 1.1.3:
======================================================================
* Patches by Richard Woodruff, 01 Oct 2004:
add support for the TI OMAP2420 processor and its H4 reference
board
* Patch by Christian Pellegrin, 24 Sep 2004:
Added support for NE2000 compatible (DP8390, DP83902) NICs.
* Patch by Leif Lindholm, 23 Sep 2004:
add support for the AMD db1550 board

View file

@ -382,6 +382,10 @@ Rishi Bhattacharya <rishi@ti.com>
omap5912osk ARM926EJS
Richard Woodruff <r-woodruff2@ti.com>
omap2420h4 ARM1136EJS
David Müller <d.mueller@elsoft.ch>
smdk2410 ARM920T

13
MAKEALL
View file

@ -157,6 +157,11 @@ LIST_ARM9=" \
versatile \
"
#########################################################################
## ARM11 Systems
#########################################################################
LIST_ARM11="omap2420h4"
#########################################################################
## Xscale Systems
#########################################################################
@ -170,7 +175,11 @@ LIST_pxa=" \
LIST_ixp="ixdp425"
LIST_arm="${LIST_SA} ${LIST_ARM7} ${LIST_ARM9} ${LIST_pxa} ${LIST_ixp}"
LIST_arm=" \
${LIST_SA} \
${LIST_ARM7} ${LIST_ARM9} ${LIST_ARM11} \
${LIST_pxa} ${LIST_ixp} \
"
#########################################################################
## MIPS Systems
@ -238,7 +247,7 @@ for arg in $@
do
case "$arg" in
ppc|5xx|5xxx|8xx|8220|824x|8260|85xx|4xx|7xx|74xx| \
arm|SA|ARM7|ARM9|pxa|ixp| \
arm|SA|ARM7|ARM9|ARM11|pxa|ixp| \
microblaze| \
mips| \
nios|nios2| \

View file

@ -1403,6 +1403,12 @@ xm250_config : unconfig
xsengine_config : unconfig
@./mkconfig $(@:_config=) arm pxa xsengine
#########################################################################
## ARM1136 Systems
#########################################################################
omap2420h4_config : unconfig
@./mkconfig $(@:_config=) arm arm1136 omap2420h4
#========================================================================
# i386
#========================================================================

17
README
View file

@ -130,6 +130,7 @@ Directory Hierarchy:
- s3c24x0 Files specific to Samsung S3C24X0 CPUs
- arm925t Files specific to ARM 925 CPUs
- arm926ejs Files specific to ARM 926 CPUs
- arm1136 Files specific to ARM 1136 CPUs
- at91rm9200 Files specific to Atmel AT91RM9200 CPUs
- i386 Files specific to i386 CPUs
- ixp Files specific to Intel XScale IXP CPUs
@ -301,13 +302,13 @@ The following options need to be configured:
ARM based boards:
-----------------
CONFIG_AT91RM9200DK, CONFIG_CERF250, CONFIG_DNP1110,
CONFIG_EP7312, CONFIG_H2_OMAP1610, CONFIG_HHP_CRADLE,
CONFIG_IMPA7, CONFIG_INNOVATOROMAP1510, CONFIG_INNOVATOROMAP1610,
CONFIG_LART, CONFIG_LPD7A400 CONFIG_LUBBOCK,
CONFIG_OSK_OMAP5912, CONFIG_SHANNON, CONFIG_P2_OMAP730,
CONFIG_SMDK2400, CONFIG_SMDK2410, CONFIG_TRAB,
CONFIG_VCMA9
CONFIG_AT91RM9200DK, CONFIG_CERF250, CONFIG_DNP1110,
CONFIG_EP7312, CONFIG_H2_OMAP1610, CONFIG_HHP_CRADLE,
CONFIG_IMPA7, CONFIG_INNOVATOROMAP1510, CONFIG_INNOVATOROMAP1610,
CONFIG_LART, CONFIG_LPD7A400 CONFIG_LUBBOCK,
CONFIG_OSK_OMAP5912, CONFIG_OMAP2420H4, CONFIG_SHANNON,
CONFIG_P2_OMAP730, CONFIG_SMDK2400, CONFIG_SMDK2410,
CONFIG_TRAB, CONFIG_VCMA9
MicroBlaze based boards:
------------------------
@ -2177,7 +2178,7 @@ configurations; the following names are supported:
FADS850SAR_config omap1610h2_config TQM850L_config
FADS860T_config omap1610inn_config TQM855L_config
FPS850L_config omap5912osk_config TQM860L_config
WALNUT405_config
omap2420h4_config WALNUT405_config
Yukon8220_config
ZPC1900_config

47
board/omap2420h4/Makefile Normal file
View file

@ -0,0 +1,47 @@
#
# (C) Copyright 2000, 2001, 2002
# 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
LIB = lib$(BOARD).a
OBJS := omap2420h4.o flash.o mem.o sys_info.o
SOBJS := platform.o
$(LIB): $(OBJS) $(SOBJS)
$(AR) crv $@ $^
clean:
rm -f $(SOBJS) $(OBJS)
distclean: clean
rm -f $(LIB) core *.bak .depend
#########################################################################
.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
$(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
-include .depend
#########################################################################

View file

@ -0,0 +1,26 @@
#
# (C) Copyright 2004
# Texas Instruments, <www.ti.com>
#
# TI H4 board with OMAP2420 (ARM1136) cpu
# see http://www.ti.com/ for more information on Texas Instruments
#
# H4 has 1 bank of 32MB or 64MB mDDR-SDRAM on CS0
# H4 has 1 bank of 32MB or 00MB mDDR-SDRAM on CS1
# Physical Address:
# 8000'0000 (bank0)
# A000/0000 (bank1) ES2 will be configurable
# Linux-Kernel is expected to be at 8000'8000, entry 8000'8000
# (mem base + reserved)
# For use with external or internal boots.
# CONFIG_PARTIAL_SRAM must be defined to use this.
TEXT_BASE = 0x80e80000
# Used with full SRAM boot.
# This is either with a GP system or a signed boot image.
# easiest, and safest way to go if you can.
# Comment out //CONFIG_PARTIAL_SRAM for this one.
#
#TEXT_BASE = 0x40280000

536
board/omap2420h4/flash.c Normal file
View file

@ -0,0 +1,536 @@
/*
* (C) Copyright 2001
* Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
*
* (C) Copyright 2001-2004
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* (C) Copyright 2003
* Texas Instruments, <www.ti.com>
* Kshitij Gupta <Kshitij@ti.com>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <asm/arch/sizes.h>
#include <linux/byteorder/swab.h>
#define PHYS_FLASH_SECT_SIZE SZ_128K
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
/* Board support for 1 or 2 flash devices */
#undef FLASH_PORT_WIDTH32
#define FLASH_PORT_WIDTH16
#ifdef FLASH_PORT_WIDTH16
# define FLASH_PORT_WIDTH ushort
# define FLASH_PORT_WIDTHV vu_short
# define SWAP(x) __swab16(x)
#else
# define FLASH_PORT_WIDTH ulong
# define FLASH_PORT_WIDTHV vu_long
# define SWAP(x) __swab32(x)
#endif
#define FPW FLASH_PORT_WIDTH
#define FPWV FLASH_PORT_WIDTHV
#define mb() __asm__ __volatile__ ("" : : : "memory")
/* Flash Organization Structure */
typedef struct OrgDef {
unsigned int sector_number;
unsigned int sector_size;
} OrgDef;
/* Flash Organizations */
OrgDef OrgIntel_28F256L18T[] = {
{4, SZ_32K}, /* 4 * 32kBytes sectors */
{255, SZ_128K}, /* 255 * 128kBytes sectors */
};
/*-----------------------------------------------------------------------
* Functions
*/
unsigned long flash_init (void);
static ulong flash_get_size (FPW * addr, flash_info_t * info);
static int write_data (flash_info_t * info, ulong dest, FPW data);
static void flash_get_offsets (ulong base, flash_info_t * info);
void inline spin_wheel (void);
void flash_print_info (flash_info_t * info);
void flash_unprotect_sectors (FPWV * addr);
int flash_erase (flash_info_t * info, int s_first, int s_last);
int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt);
void flash_unlock(flash_info_t * info, int bank);
int flash_probe(void);
/*-----------------------------------------------------------------------
*/
/* see if flash is ok */
int flash_probe(void)
{
return(flash_get_size ((FPW *) PHYS_FLASH_1, &flash_info[0]));
}
unsigned long flash_init (void)
{
int i;
ulong size = 0;
for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
switch (i) {
case 0:
flash_get_size ((FPW *) PHYS_FLASH_1, &flash_info[i]);
flash_get_offsets (PHYS_FLASH_1, &flash_info[i]);
/* to reset the lock bit */
flash_unlock(&flash_info[i],i);
break;
case 1:
flash_get_size ((FPW *) PHYS_FLASH_2, &flash_info[i]);
flash_get_offsets (PHYS_FLASH_2, &flash_info[i]);
/* to reset the lock bit */
flash_unlock(&flash_info[i],i);
break;
default:
panic ("configured too many flash banks!\n");
break;
}
size += flash_info[i].size;
}
/* Protect monitor and environment sectors
*/
flash_protect (FLAG_PROTECT_SET,
CFG_FLASH_BASE,
CFG_FLASH_BASE + monitor_flash_len - 1, &flash_info[0]);
flash_protect (FLAG_PROTECT_SET,
CFG_ENV_ADDR,
CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
return size;
}
/*-----------------------------------------------------------------------
*/
void flash_unlock(flash_info_t * info, int bank)
{
int j;
if (!bank)
j=2; /* leave 0,1 locked for boot bank */
else
j=0; /* get the whole bank for #2 */
for (;j<CFG_MAX_FLASH_SECT;j++) {
FPWV *addr = (FPWV *) (info->start[j]);
if (addr == NULL) {
printf("Warning Flash probe failed\n");
break;
}
flash_unprotect_sectors (addr);
*addr = (FPW) 0x00500050;/* clear status register */
*addr = (FPW) 0x00FF00FF;/* resest to read mode */
}
}
/*-----------------------------------------------------------------------
*/
static void flash_get_offsets (ulong base, flash_info_t * info)
{
int i;
volatile int r; /* gcc 3.4.0-1 strangeness, need to follow up.*/
if (info->flash_id == FLASH_UNKNOWN) {
return;
}
if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
for (i = 0; i < info->sector_count; i++) {
if (i > 254) { /* 255,256,257,258 */
r=i;
info->start[i] = base + (((r-(int)255) * SZ_32K) + (255*PHYS_FLASH_SECT_SIZE));
info->protect[i] = 0;
} else {
info->start[i] = base + (i * PHYS_FLASH_SECT_SIZE);
info->protect[i] = 0;
}
}
}
}
/*-----------------------------------------------------------------------
*/
void flash_print_info (flash_info_t * info)
{
int i;
if (info->flash_id == FLASH_UNKNOWN) {
printf ("missing or unknown FLASH type\n");
return;
}
switch (info->flash_id & FLASH_VENDMASK) {
case FLASH_MAN_INTEL:
printf ("INTEL ");
break;
default:
printf ("Unknown Vendor ");
break;
}
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_28F256L18T:
printf ("FLASH 28F256L18T\n");
break;
default:
printf ("Unknown Chip Type\n");
break;
}
printf (" Size: %ld MB in %d Sectors\n",
info->size >> 20, info->sector_count);
printf (" Sector Start Addresses:");
for (i = 0; i < info->sector_count; ++i) {
if ((i % 5) == 0)
printf ("\n ");
printf (" %08lX%s",
info->start[i], info->protect[i] ? " (RO)" : " ");
}
printf ("\n");
return;
}
/*
* The following code cannot be run from FLASH!
*/
static ulong flash_get_size (FPW * addr, flash_info_t * info)
{
volatile FPW value;
/* mb(); this one makes ARM11 err go away, but I want it :) as a guide to problems */
/* Write auto select command: read Manufacturer ID */
addr[0x5555] = (FPW) 0x00AA00AA;
addr[0x2AAA] = (FPW) 0x00550055;
addr[0x5555] = (FPW) 0x00900090;
mb ();
value = addr[0] & 0xFF; /* just looking for 89 (8989 is hw pat)*/
switch (value) {
case (FPW) INTEL_MANUFACT:
info->flash_id = FLASH_MAN_INTEL;
break;
default:
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
info->size = 0;
addr[0] = (FPW) 0x00FF00FF; /* restore read mode */
return(0); /* no or unknown flash */
}
mb ();
value = addr[1]; /* device ID */
switch (value) {
case (FPW) (INTEL_ID_28F256L18T): /* 880D */
info->flash_id += FLASH_28F256L18T;
info->sector_count = 259; /*0-258*/
info->size = SZ_32M;
break; /* => 32 MB */
default:
info->flash_id = FLASH_UNKNOWN;
break;
}
if (info->sector_count > CFG_MAX_FLASH_SECT) {
printf ("** ERROR: sector count %d > max (%d) **\n",
info->sector_count, CFG_MAX_FLASH_SECT);
info->sector_count = CFG_MAX_FLASH_SECT;
}
addr[0] = (FPW) 0x00FF00FF; /* restore read mode */
return(info->size);
}
/* unprotects a sector for write and erase
* on some intel parts, this unprotects the entire chip, but it
* wont hurt to call this additional times per sector...
*/
void flash_unprotect_sectors (FPWV * addr)
{
#define PD_FINTEL_WSMS_READY_MASK 0x0080
*addr = (FPW) 0x00500050; /* clear status register */
/* this sends the clear lock bit command */
*addr = (FPW) 0x00600060;
*addr = (FPW) 0x00D000D0;
}
/*-----------------------------------------------------------------------
*/
int flash_erase (flash_info_t * info, int s_first, int s_last)
{
int prot, sect;
ulong type, start, last;
int rcode = 0;
#ifdef CONFIG_USE_IRQ
int iflag;
#endif
if ((s_first < 0) || (s_first > s_last)) {
if (info->flash_id == FLASH_UNKNOWN) {
printf ("- missing\n");
} else {
printf ("- no sectors to erase\n");
}
return 1;
}
type = (info->flash_id & FLASH_VENDMASK);
if ((type != FLASH_MAN_INTEL)) {
printf ("Can't erase unknown flash type %08lx - aborted\n",
info->flash_id);
return 1;
}
prot = 0;
for (sect = s_first; sect <= s_last; ++sect) {
if (info->protect[sect]) {
prot++;
}
}
if (prot) {
printf ("- Warning: %d protected sectors will not be erased!\n",
prot);
} else {
printf ("\n");
}
start = get_timer (0);
last = start;
#ifdef CONFIG_USE_IRQ
/* Disable interrupts which might cause a timeout here */
iflag = disable_interrupts ();
#endif
/* Start erase on unprotected sectors */
for (sect = s_first; sect <= s_last; sect++) {
if (info->protect[sect] == 0) { /* not protected */
FPWV *addr = (FPWV *) (info->start[sect]);
FPW status;
printf ("Erasing sector %2d ... ", sect);
flash_unprotect_sectors (addr);
/* arm simple, non interrupt dependent timer */
reset_timer_masked ();
*addr = (FPW) 0x00500050;/* clear status register */
*addr = (FPW) 0x00200020;/* erase setup */
*addr = (FPW) 0x00D000D0;/* erase confirm */
while (((status =
*addr) & (FPW) 0x00800080) !=
(FPW) 0x00800080) {
if (get_timer_masked () >
CFG_FLASH_ERASE_TOUT) {
printf ("Timeout\n");
/* suspend erase */
*addr = (FPW) 0x00B000B0;
/* reset to read mode */
*addr = (FPW) 0x00FF00FF;
rcode = 1;
break;
}
}
/* clear status register cmd. */
*addr = (FPW) 0x00500050;
*addr = (FPW) 0x00FF00FF;/* resest to read mode */
printf (" done\n");
}
}
#ifdef CONFIG_USE_IRQ
if (iflag)
enable_interrupts();
#endif
return rcode;
}
/*-----------------------------------------------------------------------
* Copy memory to flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
* 4 - Flash not identified
*/
int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
{
ulong cp, wp;
FPW data;
int count, i, l, rc, port_width;
if (info->flash_id == FLASH_UNKNOWN) {
return 4;
}
/* get lower word aligned address */
#ifdef FLASH_PORT_WIDTH16
wp = (addr & ~1);
port_width = 2;
#else
wp = (addr & ~3);
port_width = 4;
#endif
/*
* handle unaligned start bytes
*/
if ((l = addr - wp) != 0) {
data = 0;
for (i = 0, cp = wp; i < l; ++i, ++cp) {
data = (data << 8) | (*(uchar *) cp);
}
for (; i < port_width && cnt > 0; ++i) {
data = (data << 8) | *src++;
--cnt;
++cp;
}
for (; cnt == 0 && i < port_width; ++i, ++cp) {
data = (data << 8) | (*(uchar *) cp);
}
if ((rc = write_data (info, wp, SWAP (data))) != 0) {
return(rc);
}
wp += port_width;
}
/*
* handle word aligned part
*/
count = 0;
while (cnt >= port_width) {
data = 0;
for (i = 0; i < port_width; ++i) {
data = (data << 8) | *src++;
}
if ((rc = write_data (info, wp, SWAP (data))) != 0) {
return(rc);
}
wp += port_width;
cnt -= port_width;
if (count++ > 0x800) {
spin_wheel ();
count = 0;
}
}
if (cnt == 0) {
return(0);
}
/*
* handle unaligned tail bytes
*/
data = 0;
for (i = 0, cp = wp; i < port_width && cnt > 0; ++i, ++cp) {
data = (data << 8) | *src++;
--cnt;
}
for (; i < port_width; ++i, ++cp) {
data = (data << 8) | (*(uchar *) cp);
}
return(write_data (info, wp, SWAP (data)));
}
/*-----------------------------------------------------------------------
* Write a word or halfword to Flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
static int write_data (flash_info_t * info, ulong dest, FPW data)
{
FPWV *addr = (FPWV *) dest;
ulong status;
#ifdef CONFIG_USE_IRQ
int iflag;
#endif
/* Check if Flash is (sufficiently) erased */
if ((*addr & data) != data) {
printf ("not erased at %08lx (%x)\n", (ulong) addr, *addr);
return(2);
}
/* Disable interrupts which might cause a timeout here */
#ifdef CONFIG_USE_IRQ
iflag = disable_interrupts ();
#endif
*addr = (FPW) 0x00400040; /* write setup */
*addr = data;
/* arm simple, non interrupt dependent timer */
reset_timer_masked ();
/* wait while polling the status register */
while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
if (get_timer_masked () > CFG_FLASH_WRITE_TOUT) {
*addr = (FPW) 0x00FF00FF; /* restore read mode */
return(1);
}
}
*addr = (FPW) 0x00FF00FF; /* restore read mode */
#ifdef CONFIG_USE_IRQ
if (iflag)
enable_interrupts();
#endif
return(0);
}
void inline spin_wheel (void)
{
static int p = 0;
static char w[] = "\\/-";
printf ("\010%c", w[p]);
(++p == 3) ? (p = 0) : 0;
}

306
board/omap2420h4/mem.c Normal file
View file

@ -0,0 +1,306 @@
/*
* (C) Copyright 2004
* Texas Instruments, <www.ti.com>
* Richard Woodruff <r-woodruff2@ti.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <asm/arch/omap2420.h>
#include <asm/io.h>
#include <asm/arch/bits.h>
#include <asm/arch/mux.h>
#include <asm/arch/mem.h>
#include <asm/arch/clocks.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/sys_info.h>
/************************************************************
* sdelay() - simple spin loop. Will be constant time as
* its generally used in 12MHz bypass conditions only. This
* is necessary until timers are accessible.
*
* not inline to increase chances its in cache when called
*************************************************************/
void sdelay (unsigned long loops)
{
__asm__ volatile ("1:\n"
"subs %0, %1, #1\n"
"bne 1b":"=r" (loops):"0" (loops));
}
/*********************************************************************************
* prcm_init() - inits clocks for PRCM as defined in clocks.h (config II default).
* -- called from SRAM, or Flash (using temp SRAM stack).
*********************************************************************************/
void prcm_init(void)
{
u32 rev,div;
#ifdef CONFIG_PARTIAL_SRAM
void (*f_lock_pll) (u32, u32, u32, u32);
extern void *_end_vect, *_start;
f_lock_pll = (void *)((u32)&_end_vect - (u32)&_start + SRAM_VECT_CODE);
#endif
__raw_writel(0, CM_FCLKEN1_CORE); /* stop all clocks to reduce ringing */
__raw_writel(0, CM_FCLKEN2_CORE); /* may not be necessary */
__raw_writel(0, CM_ICLKEN1_CORE);
__raw_writel(0, CM_ICLKEN2_CORE);
__raw_writel(DPLL_OUT, CM_CLKSEL2_PLL); /* set DPLL out */
__raw_writel(MPU_DIV, CM_CLKSEL_MPU); /* set MPU divider */
__raw_writel(DSP_DIV, CM_CLKSEL_DSP); /* set dsp and iva dividers */
__raw_writel(GFX_DIV, CM_CLKSEL_GFX); /* set gfx dividers */
rev = get_cpu_rev();
if (rev == CPU_2420_ES1 || rev == CPU_2422_ES1)
div = BUS_DIV_ES1;
else
div = BUS_DIV;
__raw_writel(div, CM_CLKSEL1_CORE);/* set L3/L4/USB/Display/Vlnc/SSi dividers */
sdelay(1000);
#ifndef CONFIG_PARTIAL_SRAM
/* If running fully from SRAM this is OK. The Flash bus drops out for just a little.
* but then comes back. If running from Flash this sequence kills you, thus you need
* to run it using CONFIG_PARTIAL_SRAM.
*/
__raw_writel(MODE_BYPASS_FAST, CM_CLKEN_PLL); /* go to bypass, fast relock */
wait_on_value(BIT0|BIT1, BIT1, CM_IDLEST_CKGEN, LDELAY); /* wait till in bypass */
/* set clock selection and dpll dividers. */
__raw_writel(DPLL_VAL, CM_CLKSEL1_PLL); /* set pll for target rate */
__raw_writel(COMMIT_DIVIDERS, PRCM_CLKCFG_CTRL); /* commit dividers */
sdelay(10000);
__raw_writel(DPLL_LOCK, CM_CLKEN_PLL); /* enable dpll */
sdelay(10000);
wait_on_value(BIT0|BIT1, BIT2, CM_IDLEST_CKGEN, LDELAY); /*wait for dpll lock */
#else
/* if running from flash, need to jump to small relocated code area in SRAM.
* This is the only safe spot to do configurations from.
*/
(*f_lock_pll)(PRCM_CLKCFG_CTRL, CM_CLKEN_PLL, DPLL_LOCK, CM_IDLEST_CKGEN);
#endif
__raw_writel(DPLL_LOCK|APLL_LOCK, CM_CLKEN_PLL); /* enable apll */
wait_on_value(BIT8, BIT8, CM_IDLEST_CKGEN, LDELAY); /* wait for apll lock */
sdelay(1000);
}
/***********************************************
* memif_init() - init the gpmc and sdrc
* - early init routines, called from flash or
* SRAM.
***********************************************/
void memif_init(void)
{
sdrc_init();
#ifndef CONFIG_PARTIAL_SRAM /* don't init if calling from flash */
gpmc_init();
#endif
}
/********************************************************
* mem_ok() - test used to see if timings are correct
* for a part. Helps in gussing which part
* we are currently using.
*******************************************************/
u32 mem_ok(void)
{ u32 val;
__raw_writel(0x0,OMAP2420_SDRC_CS0+0x400); /* clear pos A */
__raw_writel(0x12345678, OMAP2420_SDRC_CS0);/* pattern to pos B */
val = __raw_readl(OMAP2420_SDRC_CS0+0x400); /* get pos A value */
if (val != 0) /* see if pos A value changed*/
return(0);
else
return(1);
}
/********************************************************
* sdrc_init() - init the sdrc chip selects CS0 and CS1
* - early init routines, called from flash or
* SRAM.
*******************************************************/
void sdrc_init(void)
{
#define EARLY_INIT 1
do_sdrc_init(SDRC_CS0_OSET, EARLY_INIT); /* only init up first bank here */
}
/**********************************************************
* do_sdrc_init(): initialize the SDRAM for use.
* -called from low level code with stack only.
* -code sets up SDRAM timing and muxing for 2422 or 2420.
* -optimal settings can be placed here, or redone after i2c
* inspection of board info
*
* !!! When ES1 comes out need to conditionalize RFR value!!!
**********************************************************/
void do_sdrc_init(u32 offset, u32 early)
{
u32 cpu, bug=0, rev, shared=0, cs0=0, pmask=0,first=1;
sdrc_data_t *sdata; /* do not change type */
static const sdrc_data_t sdrc_2422 =
{
H4_2422_SDRC_SHARING, H4_2422_SDRC_MDCFG_0, H4_2422_SDRC_ACTIM_CTRLA_0,
H4_2422_SDRC_ACTIM_CTRLB_0, H4_2422_SDRC_RFR_CTRL_ES1, H4_2422_SDRC_MR_0,
H4_2422_SDRC_DLLA_CTRL, H4_2422_SDRC_DLLB_CTRL
};
static const sdrc_data_t sdrc_2420 =
{
H4_2420_SDRC_SHARING, H4_2420_SDRC_MDCFG_0, H4_2420_SDRC_ACTIM_CTRLA_0,
H4_2420_SDRC_ACTIM_CTRLB_0, H4_2420_SDRC_RFR_CTRL_ES1, H4_2420_SDRC_MR_0,
H4_2420_SDRC_DLLA_CTRL, H4_2420_SDRC_DLLB_CTRL
};
if (offset == SDRC_CS0_OSET)
cs0 = shared = 1; /* int regs shared between both chip select */
cpu = get_cpu_type();
/* warning generated, though code generation is correct. this may bite later, but is ok for now.
* there is only so much C code you can do on stack only operation.
*/
if (cpu == CPU_2422)
sdata = &sdrc_2422;
else
sdata = &sdrc_2420;
__asm__ __volatile__("": : :"memory");
#ifdef CONFIG_PARTIAL_SRAM
/* u-boot is compiled to run in DDR at 8xxxxxxx. If we use data here which is not pc relative
* we need to get the address correct. We need to find the current flash mapping to dress up
* the initial pointer load. As long as this is const data we should be ok.
*/
if(early)
sdata = (sdrc_data_t *)(((u32)sdata & 0x0003FFFF) | get_gpmc0_base());
#endif
men_combo:
if (!early && get_mem_type() == DDR_COMBO) { /* combo part has a shared CKE signal, can't use feature */
pmask = BIT2;
first = 0; /* trigger ddr_combo init */
}
if (shared) {
__raw_writel(__raw_readl(SMS_SYSCONFIG)|SMART_IDLE, SMS_SYSCONFIG);
__raw_writel(SMART_IDLE|SOFTRESET, SDRC_SYSCONFIG); /* reset sdrc */
wait_on_value(BIT0, BIT0, SDRC_STATUS, 12000000); /* wait till reset done set */
__raw_writel(SMART_IDLE, SDRC_SYSCONFIG); /* clear soft reset */
__raw_writel(sdata->sdrc_sharing, SDRC_SHARING);
__raw_writel((__raw_readl(SDRC_POWER)|SMART_IDLE) & ~pmask, SDRC_POWER);
}
if (first)
__raw_writel(sdata->sdrc_mdcfg_0, SDRC_MCFG_0+offset);
else {
__raw_writel((__raw_readl(SDRC_POWER)|SMART_IDLE) & ~pmask, SDRC_POWER);
__raw_writel(H4_2420_COMBO_MDCFG_0,SDRC_MCFG_0+offset);
}
if (cs0) {
__raw_writel(sdata->sdrc_actim_ctrla_0, SDRC_ACTIM_CTRLA_0);
__raw_writel(sdata->sdrc_actim_ctrlb_0, SDRC_ACTIM_CTRLB_0);
} else {
__raw_writel(sdata->sdrc_actim_ctrla_0, SDRC_ACTIM_CTRLA_1);
__raw_writel(sdata->sdrc_actim_ctrlb_0, SDRC_ACTIM_CTRLB_1);
}
__raw_writel(sdata->sdrc_rfr_ctrl, SDRC_RFR_CTRL+offset);
/* init sequence for _mDDR_ using manual commands (DDR is a bit different) */
__raw_writel(CMD_NOP, SDRC_MANUAL_0+offset);
sdelay(5000); /* susposed to be 100us per design spec for mddr*/
__raw_writel(CMD_PRECHARGE, SDRC_MANUAL_0+offset);
__raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_0+offset);
__raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_0+offset);
/*
* CSx SDRC Mode Register
* Burst length = 4 - DDR memory
* Serial mode
* CAS latency = x
*/
__raw_writel(sdata->sdrc_mr_0, SDRC_MR_0+offset);
/* NOTE: ES1 242x _BUG_ DLL */
rev = get_cpu_rev();
if (rev == CPU_2420_ES1 || rev == CPU_2422_ES1)
bug = BIT0;
/* enable & load up DLL with good value for 75MHz, and set phase to 90% */
if (shared) {
__raw_writel(sdata->sdrc_dlla_ctrl, SDRC_DLLA_CTRL);
__raw_writel(sdata->sdrc_dlla_ctrl & ~(BIT2|bug), SDRC_DLLA_CTRL);
__raw_writel(sdata->sdrc_dllb_ctrl, SDRC_DLLB_CTRL);
__raw_writel(sdata->sdrc_dllb_ctrl & ~(BIT2|bug) , SDRC_DLLB_CTRL);
}
sdelay(9000);
if (!first || mem_ok()) /* passed test or 2nd bank init */
return;
else {
first = 0;
goto men_combo;
}
}
/*****************************************************
* gpmc_init(): init gpmc bus
* Init GPMC for x16, MuxMode (SDRAM in x32).
* This code can only be executed from SRAM or SDRAM.
*****************************************************/
void gpmc_init(void)
{
u32 mux=0, mtype, mwidth;
/* global settings */
__raw_writel(0x10, GPMC_SYSCONFIG); /* smart idle */
__raw_writel(0x0, GPMC_IRQENABLE); /* isr's sources masked */
__raw_writel(0x1, GPMC_TIMEOUT_CONTROL);/* timeout disable */
__raw_writel(0x111, GPMC_CONFIG); /* set nWP, disable limited addr */
/* discover bus connection from sysboot */
if (is_gpmc_muxed() == GPMC_MUXED)
mux = BIT9;
mtype = get_gpmc0_type();
mwidth = get_gpmc0_width();
/* setup cs0 */
__raw_writel(0x0, GPMC_CONFIG7_0); /* disable current map */
sdelay(1000);
__raw_writel(H4_24XX_GPMC_CONFIG1_0|mux|mtype|mwidth, GPMC_CONFIG1_0);
//__raw_writel(H4_24XX_GPMC_CONFIG2_0, GPMC_CONFIG2_0);
__raw_writel(H4_24XX_GPMC_CONFIG3_0, GPMC_CONFIG3_0);
__raw_writel(H4_24XX_GPMC_CONFIG4_0, GPMC_CONFIG4_0);
//__raw_writel(H4_24XX_GPMC_CONFIG5_0, GPMC_CONFIG5_0);
__raw_writel(H4_24XX_GPMC_CONFIG7_0, GPMC_CONFIG7_0);/* enable new mapping */
sdelay(2000);
/* setup cs1 */
__raw_writel(0, GPMC_CONFIG7_1); /* disable any mapping */
sdelay(1000);
__raw_writel(H4_24XX_GPMC_CONFIG1_1|mux, GPMC_CONFIG1_1);
__raw_writel(H4_24XX_GPMC_CONFIG2_1, GPMC_CONFIG2_1);
__raw_writel(H4_24XX_GPMC_CONFIG3_1, GPMC_CONFIG3_1);
__raw_writel(H4_24XX_GPMC_CONFIG4_1, GPMC_CONFIG4_1);
__raw_writel(H4_24XX_GPMC_CONFIG5_1, GPMC_CONFIG5_1);
__raw_writel(H4_24XX_GPMC_CONFIG6_1, GPMC_CONFIG6_1);
__raw_writel(H4_24XX_GPMC_CONFIG7_1, GPMC_CONFIG7_1); /* enable mapping */
sdelay(2000);
}

View file

@ -0,0 +1,834 @@
/*
* (C) Copyright 2004
* Texas Instruments, <www.ti.com>
* Richard Woodruff <r-woodruff2@ti.com>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <asm/arch/omap2420.h>
#include <asm/io.h>
#include <asm/arch/bits.h>
#include <asm/arch/mux.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/sys_info.h>
#include <asm/arch/mem.h>
#include <i2c.h>
#include <asm/mach-types.h>
static void wait_for_command_complete(unsigned int wd_base);
/*******************************************************
* Routine: delay
* Description: spinning delay to use before udelay works
******************************************************/
static inline void delay (unsigned long loops)
{
__asm__ volatile ("1:\n"
"subs %0, %1, #1\n"
"bne 1b":"=r" (loops):"0" (loops));
}
/*****************************************
* Routine: board_init
* Description: Early hardware init.
*****************************************/
int board_init (void)
{
DECLARE_GLOBAL_DATA_PTR;
#ifndef CONFIG_PARTIAL_SRAM
s_init(0x0); /* full sram build, never skip clock and sdrc, no point */
#else
gpmc_init();
#endif
gd->bd->bi_arch_number = MACH_TYPE_OMAP_H4; /* board id for linux */
gd->bd->bi_boot_params = (OMAP2420_SDRC_CS0+0x100); /* adress of boot parameters */
return 0;
}
/**********************************************************
* Routine: s_init
* Description: Does early system init of muxing and clocks.
* - Called at time when only stack is available.
**********************************************************/
void s_init(int skip)
{
watchdog_init();
set_muxconf_regs();
delay(100);
if (!skip)
prcm_init();
peripheral_enable();
icache_enable();
#ifndef CONFIG_APTIX
if (!skip)
memif_init();
#endif
}
/*******************************************************
* Routine: misc_init_r
* Description: Init ethernet (done here so udelay works)
********************************************************/
int misc_init_r (void)
{
ether_init(); /* better done here so timers are init'ed */
return(0);
}
/****************************************
* Routine: watchdog_init
* Description: Shut down watch dogs
*****************************************/
void watchdog_init(void)
{
int mode;
#define GP (BIT8|BIT9)
/* There are 4 watch dogs. 1 secure, and 3 general purpose.
* I would expect that the ROM takes care of the secure one,
* but we will try also. Of the 3 GP ones, 1 can reset us
* directly, the other 2 only generate MPU interrupts.
*/
mode = (__raw_readl(CONTROL_STATUS) & (BIT8|BIT9));
if (mode == GP) {
__raw_writel(WD_UNLOCK1 ,WD1_BASE+WSPR);
wait_for_command_complete(WD1_BASE);
__raw_writel(WD_UNLOCK2 ,WD1_BASE+WSPR);
}
__raw_writel(WD_UNLOCK1 ,WD2_BASE+WSPR);
wait_for_command_complete(WD2_BASE);
__raw_writel(WD_UNLOCK2 ,WD2_BASE+WSPR);
#if MPU_WD_CLOCKED /* value 0x10 stick on aptix, BIT4 polarity seems oppsite*/
__raw_writel(WD_UNLOCK1 ,WD3_BASE+WSPR);
wait_for_command_complete(WD3_BASE);
__raw_writel(WD_UNLOCK2 ,WD3_BASE+WSPR);
__raw_writel(WD_UNLOCK1 ,WD4_BASE+WSPR);
wait_for_command_complete(WD4_BASE);
__raw_writel(WD_UNLOCK2 ,WD4_BASE+WSPR);
#endif
}
/******************************************************
* Routine: wait_for_command_complete
* Description: Wait for posting to finish on watchdog
******************************************************/
static void wait_for_command_complete(unsigned int wd_base)
{
int pending = 1;
do {
pending = __raw_readl(wd_base+WWPS);
} while (pending);
}
/*******************************************************************
* Routine:ether_init
* Description: take the Ethernet controller out of reset and wait
* for the EEPROM load to complete.
******************************************************************/
void ether_init (void)
{
#ifdef CONFIG_DRIVER_LAN91C96
int cnt = 20;
__raw_writew(0x0, LAN_RESET_REGISTER);
do {
__raw_writew(0x1, LAN_RESET_REGISTER);
udelay (100);
if (cnt == 0)
goto h4reset_err_out;
--cnt;
} while (__raw_readw(LAN_RESET_REGISTER) != 0x1);
cnt = 20;
do {
__raw_writew(0x0, LAN_RESET_REGISTER);
udelay (100);
if (cnt == 0)
goto h4reset_err_out;
--cnt;
} while (__raw_readw(LAN_RESET_REGISTER) != 0x0000);
udelay (1000);
*((volatile unsigned char *) ETH_CONTROL_REG) &= ~0x01;
udelay (1000);
h4reset_err_out:
return;
#endif
}
/**********************************************
* Routine: dram_init
* Description: sets uboots idea of sdram size
**********************************************/
int dram_init (void)
{
DECLARE_GLOBAL_DATA_PTR;
unsigned int size0=0,size1=0;
u32 mtype, btype;
#define NOT_EARLY 0
i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE); /* need this a bit early */
btype = get_board_type();
mtype = get_mem_type();
display_board_info(btype);
if (btype == BOARD_H4_MENELAUS)
update_mux(btype,mtype);
if ((mtype == DDR_COMBO) || (mtype == DDR_STACKED)) {
do_sdrc_init(SDRC_CS1_OSET, NOT_EARLY); /* init other chip select */
size0 = size1 = SZ_32M;
} else
size0 = SZ_64M;
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
gd->bd->bi_dram[0].size = size0;
gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
gd->bd->bi_dram[1].size = size1;
return 0;
}
/**********************************************************
* Routine: set_muxconf_regs
* Description: Setting up the configuration Mux registers
* specific to the hardware
*********************************************************/
void set_muxconf_regs (void)
{
muxSetupSDRC();
muxSetupGPMC();
muxSetupUsb0();
muxSetupUart3();
muxSetupI2C1();
muxSetupUART1();
muxSetupLCD();
muxSetupCamera();
muxSetupMMCSD();
muxSetupTouchScreen();
muxSetupHDQ();
}
/*****************************************************************
* Routine: peripheral_enable
* Description: Enable the clks & power for perifs (GPT2, UART1,...)
******************************************************************/
void peripheral_enable(void)
{
unsigned int v, if_clks=0, func_clks=0;
/* Enable GP2 timer.*/
if_clks |= BIT4;
func_clks |= BIT4;
v = __raw_readl(CM_CLKSEL2_CORE) | 0x4; /* Sys_clk input OMAP2420_GPT2 */
__raw_writel(v, CM_CLKSEL2_CORE);
__raw_writel(0x1, CM_CLKSEL_WKUP);
#ifdef CFG_NS16550
/* Enable UART1 clock */
func_clks |= BIT21;
if_clks |= BIT21;
#endif
v = __raw_readl(CM_ICLKEN1_CORE) | if_clks; /* Interface clocks on */
__raw_writel(v,CM_ICLKEN1_CORE );
v = __raw_readl(CM_FCLKEN1_CORE) | func_clks; /* Functional Clocks on */
__raw_writel(v, CM_FCLKEN1_CORE);
delay(1000);
#ifndef KERNEL_UPDATED
{
#define V1 0xffffffff
#define V2 0x00000007
__raw_writel(V1, CM_FCLKEN1_CORE);
__raw_writel(V2, CM_FCLKEN2_CORE);
__raw_writel(V1, CM_ICLKEN1_CORE);
__raw_writel(V1, CM_ICLKEN2_CORE);
}
#endif
}
/****************************************
* Routine: muxSetupUsb0 (ostboot)
* Description: Setup usb muxing
*****************************************/
void muxSetupUsb0(void)
{
volatile uint8 *MuxConfigReg;
volatile uint32 *otgCtrlReg;
MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_USB0_PUEN;
*MuxConfigReg &= (uint8)(~0x1F);
MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_USB0_VP;
*MuxConfigReg &= (uint8)(~0x1F);
MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_USB0_VM;
*MuxConfigReg &= (uint8)(~0x1F);
MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_USB0_RCV;
*MuxConfigReg &= (uint8)(~0x1F);
MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_USB0_TXEN;
*MuxConfigReg &= (uint8)(~0x1F);
MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_USB0_SE0;
*MuxConfigReg &= (uint8)(~0x1F);
MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_USB0_DAT;
*MuxConfigReg &= (uint8)(~0x1F);
/* setup for USB VBus detection */
otgCtrlReg = (volatile uint32 *)USB_OTG_CTRL;
*otgCtrlReg |= 0x00040000; /* bit 18 */
}
/****************************************
* Routine: muxSetupUart3 (ostboot)
* Description: Setup uart3 muxing
*****************************************/
void muxSetupUart3(void)
{
volatile uint8 *MuxConfigReg;
MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_UART3_TX_IRTX;
*MuxConfigReg &= (uint8)(~0x1F);
MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_UART3_RX_IRRX;
*MuxConfigReg &= (uint8)(~0x1F);
}
/****************************************
* Routine: muxSetupI2C1 (ostboot)
* Description: Setup i2c muxing
*****************************************/
void muxSetupI2C1(void)
{
volatile unsigned char *MuxConfigReg;
/* I2C1 Clock pin configuration, PIN = M19 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_I2C1_SCL;
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* I2C1 Data pin configuration, PIN = L15 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_I2C1_SDA;
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* Pull-up required on data line */
/* external pull-up already present. */
/* *MuxConfigReg |= 0x18 ;*/ /* Mode = 0, PullTypeSel=PU, PullUDEnable=Enabled */
}
/****************************************
* Routine: muxSetupUART1 (ostboot)
* Description: Set up uart1 muxing
*****************************************/
void muxSetupUART1(void)
{
volatile unsigned char *MuxConfigReg;
/* UART1_CTS pin configuration, PIN = D21 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_UART1_CTS;
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* UART1_RTS pin configuration, PIN = H21 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_UART1_RTS;
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* UART1_TX pin configuration, PIN = L20 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_UART1_TX;
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
/* UART1_RX pin configuration, PIN = T21 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_UART1_RX;
*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */
}
/****************************************
* Routine: muxSetupLCD (ostboot)
* Description: Setup lcd muxing
*****************************************/
void muxSetupLCD(void)
{
volatile unsigned char *MuxConfigReg;
/* LCD_D0 pin configuration, PIN = Y7 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D0;
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* LCD_D1 pin configuration, PIN = P10 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D1;
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* LCD_D2 pin configuration, PIN = V8 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D2;
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* LCD_D3 pin configuration, PIN = Y8 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D3;
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* LCD_D4 pin configuration, PIN = W8 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D4;
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* LCD_D5 pin configuration, PIN = R10 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D5;
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* LCD_D6 pin configuration, PIN = Y9 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D6;
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* LCD_D7 pin configuration, PIN = V9 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D7;
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* LCD_D8 pin configuration, PIN = W9 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D8;
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* LCD_D9 pin configuration, PIN = P11 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D9;
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* LCD_D10 pin configuration, PIN = V10 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D10;
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* LCD_D11 pin configuration, PIN = Y10 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D11;
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* LCD_D12 pin configuration, PIN = W10 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D12;
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* LCD_D13 pin configuration, PIN = R11 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D13;
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* LCD_D14 pin configuration, PIN = V11 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D14;
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* LCD_D15 pin configuration, PIN = W11 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D15;
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* LCD_D16 pin configuration, PIN = P12 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D16;
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* LCD_D17 pin configuration, PIN = R12 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D17;
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* LCD_PCLK pin configuration, PIN = W6 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_PCLK;
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* LCD_VSYNC pin configuration, PIN = V7 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_VSYNC;
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* LCD_HSYNC pin configuration, PIN = Y6 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_HSYNC;
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* LCD_ACBIAS pin configuration, PIN = W7 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_ACBIAS;
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
}
/****************************************
* Routine: muxSetupCamera (ostboot)
* Description: Setup camera muxing
*****************************************/
void muxSetupCamera(void)
{
volatile unsigned char *MuxConfigReg;
/* CAMERA_RSTZ pin configuration, PIN = Y16 */
/* CAM_RST is connected through the I2C IO expander.*/
/* MuxConfigReg = (volatile unsigned char *), CONTROL_PADCONF_SYS_NRESWARM*/
/* *MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled */
/* CAMERA_XCLK pin configuration, PIN = U3 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_XCLK;
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* CAMERA_LCLK pin configuration, PIN = V5 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_LCLK;
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* CAMERA_VSYNC pin configuration, PIN = U2 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_VS,
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* CAMERA_HSYNC pin configuration, PIN = T3 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_HS,
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* CAMERA_DAT0 pin configuration, PIN = T4 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D0,
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* CAMERA_DAT1 pin configuration, PIN = V2 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D1,
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* CAMERA_DAT2 pin configuration, PIN = V3 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D2,
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* CAMERA_DAT3 pin configuration, PIN = U4 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D3,
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* CAMERA_DAT4 pin configuration, PIN = W2 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D4,
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* CAMERA_DAT5 pin configuration, PIN = V4 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D5,
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* CAMERA_DAT6 pin configuration, PIN = W3 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D6,
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* CAMERA_DAT7 pin configuration, PIN = Y2 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D7,
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* CAMERA_DAT8 pin configuration, PIN = Y4 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D8,
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* CAMERA_DAT9 pin configuration, PIN = V6 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D9,
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
}
/****************************************
* Routine: muxSetupMMCSD (ostboot)
* Description: set up MMC muxing
*****************************************/
void muxSetupMMCSD(void)
{
volatile unsigned char *MuxConfigReg;
/* SDMMC_CLKI pin configuration, PIN = H15 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_CLKI,
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* SDMMC_CLKO pin configuration, PIN = G19 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_CLKO,
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* SDMMC_CMD pin configuration, PIN = H18 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_CMD,
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
// External pull-ups are present.
// *MuxConfigReg |= 0x18 ; // PullUDEnable=Enabled, PullTypeSel=PU
/* SDMMC_DAT0 pin configuration, PIN = F20 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_DAT0,
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
// External pull-ups are present.
// *MuxConfigReg |= 0x18 ; // PullUDEnable=Enabled, PullTypeSel=PU
/* SDMMC_DAT1 pin configuration, PIN = H14 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_DAT1,
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
// External pull-ups are present.
// *MuxConfigReg |= 0x18 ; // PullUDEnable=Enabled, PullTypeSel=PU
/* SDMMC_DAT2 pin configuration, PIN = E19 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_DAT2,
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
// External pull-ups are present.
// *MuxConfigReg |= 0x18 ; // PullUDEnable=Enabled, PullTypeSel=PU
/* SDMMC_DAT3 pin configuration, PIN = D19 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_DAT3,
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
// External pull-ups are present.
// *MuxConfigReg |= 0x18 ; // PullUDEnable=Enabled, PullTypeSel=PU
/* SDMMC_DDIR0 pin configuration, PIN = F19 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_DAT_DIR0,
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* SDMMC_DDIR1 pin configuration, PIN = E20 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_DAT_DIR1,
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* SDMMC_DDIR2 pin configuration, PIN = F18 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_DAT_DIR2,
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* SDMMC_DDIR3 pin configuration, PIN = E18 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_DAT_DIR3,
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* SDMMC_CDIR pin configuration, PIN = G18 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_CMD_DIR,
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* MMC_CD pin configuration, PIN = B3 ---2420IP ONLY---*/
/* MMC_CD for 2422IP=K1 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_SDRC_A14,
*MuxConfigReg = 0x03 ; // Mode = 3, PUPD=Disabled
/* MMC_WP pin configuration, PIN = B4 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_SDRC_A13,
*MuxConfigReg = 0x03 ; // Mode = 3, PUPD=Disabled
}
/******************************************
* Routine: muxSetupTouchScreen (ostboot)
* Description: Set up touch screen muxing
*******************************************/
void muxSetupTouchScreen(void)
{
volatile unsigned char *MuxConfigReg;
/* SPI1_CLK pin configuration, PIN = U18 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_SPI1_CLK,
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* SPI1_MOSI pin configuration, PIN = V20 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_SPI1_SIMO,
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* SPI1_MISO pin configuration, PIN = T18 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_SPI1_SOMI,
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* SPI1_nCS0 pin configuration, PIN = U19 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_SPI1_NCS0,
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
/* PEN_IRQ pin configuration, PIN = P20 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MCBSP1_FSR,
*MuxConfigReg = 0x03 ; // Mode = 3, PUPD=Disabled
}
/****************************************
* Routine: muxSetupHDQ (ostboot)
* Description: setup 1wire mux
*****************************************/
void muxSetupHDQ(void)
{
volatile unsigned char *MuxConfigReg;
/* HDQ_SIO pin configuration, PIN = N18 */
MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_HDQ_SIO,
*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled
}
/***************************************************************
* Routine: muxSetupGPMC (ostboot)
* Description: Configures balls which cam up in protected mode
***************************************************************/
void muxSetupGPMC(void)
{
volatile uint8 *MuxConfigReg;
volatile unsigned int *MCR = 0x4800008C;
/* gpmc_io_dir */
*MCR = 0x19000000;
/* NOR FLASH CS0 */
/* signal - Gpmc_clk; pin - J4; offset - 0x0088; mode - 0; Byte-3 Pull/up - N/A */
MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_GPMC_D2_BYTE3,
*MuxConfigReg = 0x00 ;
/* signal - Gpmc_iodir; pin - n2; offset - 0x008C; mode - 1; Byte-3 Pull/up - N/A */
MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_GPMC_NCS0_BYTE3,
*MuxConfigReg = 0x01 ;
/* MPDB(Multi Port Debug Port) CS1 */
/* signal - gpmc_ncs1; pin - N8; offset - 0x008C; mode - 0; Byte-1 Pull/up - N/A */
MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_GPMC_NCS0_BYTE1,
*MuxConfigReg = 0x00 ;
/* signal - Gpmc_ncs2; pin - E2; offset - 0x008C; mode - 0; Byte-2 Pull/up - N/A */
MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_GPMC_NCS0_BYTE2,
*MuxConfigReg = 0x00 ;
}
/****************************************************************
* Routine: muxSetupSDRC (ostboot)
* Description: Configures balls which come up in protected mode
****************************************************************/
void muxSetupSDRC(void)
{
volatile uint8 *MuxConfigReg;
/* signal - sdrc_ncs1; pin - C12; offset - 0x00A0; mode - 0; Byte-1 Pull/up - N/A */
MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_SDRC_NCS0_BYTE1,
*MuxConfigReg = 0x00 ;
/* signal - sdrc_a12; pin - D11; offset - 0x0030; mode - 0; Byte-2 Pull/up - N/A */
MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_SDRC_A14_BYTE2,
*MuxConfigReg = 0x00 ;
/* signal - sdrc_cke1; pin - B13; offset - 0x00A0; mode - 0; Byte-3 Pull/up - N/A */
MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_SDRC_NCS0_BYTE3,
*MuxConfigReg = 0x00;
if (get_cpu_type() == CPU_2422) {
MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_SDRC_A14_BYTE0,
*MuxConfigReg = 0x1b;
}
}
/*****************************************************************************
* Routine: update_mux()
* Description: Update balls which are different beween boards. All should be
* updated to match functionaly. However, I'm only updating ones
* which I'll be using for now. When power comes into play they
* all need updating.
*****************************************************************************/
void update_mux(u32 btype,u32 mtype)
{
u32 cpu, base = OMAP2420_CTRL_BASE;
cpu = get_cpu_type();
if (btype == BOARD_H4_MENELAUS) {
if (cpu == CPU_2420) {
/* PIN = B3, GPIO.0->KBR5, mode 3, (pun?),-DO-*/
__raw_writeb(0x3, base+0x30);
/* PIN = B13, GPIO.38->KBC6, mode 3, (pun?)-DO-*/
__raw_writeb(0x3, base+0xa3);
/* PIN = F1, GPIO.25->HSUSBxx mode 3, (for external HS USB)*/
/* PIN = H1, GPIO.26->HSUSBxx mode 3, (for external HS USB)*/
/* PIN = K1, GPMC_ncs6 mode 0, (on board nand access)*/
/* PIN = L2, GPMC_ncs67 mode 0, (for external HS USB)*/
/* PIN = M1 (HSUSBOTG) */
/* PIN = P1, GPIO.35->MEN_POK mode 3, (menelaus powerok)-DO-*/
__raw_writeb(0x3, base+0x9d);
/* PIN = U32, (WLAN_CLKREQ) */
/* PIN = Y11, WLAN */
/* PIN = AA4, GPIO.15->KBC2, mode 3, -DO- */
__raw_writeb(0x3, base+0xe7);
/* PIN = AA8, mDOC */
/* PIN = AA10, BT */
/* PIN = AA13, WLAN */
/* PIN = M18 GPIO.96->MMC2_WP mode 3 -DO- */
__raw_writeb(0x3, base+0x10e);
/* PIN = N19 GPIO.98->WLAN_INT mode 3 -DO- */
__raw_writeb(0x3, base+0x110);
/* PIN = J15 HHUSB */
/* PIN = H19 HSUSB */
/* PIN = W13, P13, R13, W16 ... */
/* PIN = V12 GPIO.25->I2C_CAMEN mode 3 -DO- */
__raw_writeb(0x3, base+0xde);
/* PIN = W19 sys_nirq->MENELAUS_INT mode 0 -DO- */
__raw_writeb(0x0, base+0x12c);
/* PIN = AA17->sys_clkreq mode 0 -DO- */
__raw_writeb(0x0, base+0x136);
} else if (cpu == CPU_2422) {
/* PIN = B3, GPIO.0->nc, mode 3, set above (pun?)*/
/* PIN = B13, GPIO.cke1->nc, mode 0, set above, (pun?)*/
/* PIN = F1, GPIO.25->HSUSBxx mode 3, (for external HS USB)*/
/* PIN = H1, GPIO.26->HSUSBxx mode 3, (for external HS USB)*/
/* PIN = K1, GPMC_ncs6 mode 0, (on board nand access)*/
__raw_writeb(0x0, base+0x92);
/* PIN = L2, GPMC_ncs67 mode 0, (for external HS USB)*/
/* PIN = M1 (HSUSBOTG) */
/* PIN = P1, GPIO.35->MEN_POK mode 3, (menelaus powerok)-DO-*/
__raw_writeb(0x3, base+0x10c);
/* PIN = U32, (WLAN_CLKREQ) */
/* PIN = AA4, GPIO.15->KBC2, mode 3, -DO- */
__raw_writeb(0x3, base+0x30);
/* PIN = AA8, mDOC */
/* PIN = AA10, BT */
/* PIN = AA12, WLAN */
/* PIN = M18 GPIO.96->MMC2_WP mode 3 -DO- */
__raw_writeb(0x3, base+0x10e);
/* PIN = N19 GPIO.98->WLAN_INT mode 3 -DO- */
__raw_writeb(0x3, base+0x110);
/* PIN = J15 HHUSB */
/* PIN = H19 HSUSB */
/* PIN = W13, P13, R13, W16 ... */
/* PIN = V12 GPIO.25->I2C_CAMEN mode 3 -DO- */
__raw_writeb(0x3, base+0xde);
/* PIN = W19 sys_nirq->MENELAUS_INT mode 0 -DO- */
__raw_writeb(0x0, base+0x12c);
/* PIN = AA17->sys_clkreq mode 0 -DO- */
__raw_writeb(0x0, base+0x136);
}
} else if (btype == BOARD_H4_SDP) {
if (cpu == CPU_2420) {
/* PIN = B3, GPIO.0->nc mode 3, set above (pun?)*/
/* PIN = B13, GPIO.cke1->nc, mode 0, set above, (pun?)*/
/* Pin = Y11 VLNQ */
/* Pin = AA4 VLNQ */
/* Pin = AA6 VLNQ */
/* Pin = AA8 VLNQ */
/* Pin = AA10 VLNQ */
/* Pin = AA12 VLNQ */
/* PIN = M18 GPIO.96->KBR5 mode 3 -DO- */
__raw_writeb(0x3, base+0x10e);
/* PIN = N19 GPIO.98->KBC6 mode 3 -DO- */
__raw_writeb(0x3, base+0x110);
/* PIN = J15 MDOC_nDMAREQ */
/* PIN = H19 GPIO.100->KBC2 mode 3 -DO- */
__raw_writeb(0x3, base+0x114);
/* PIN = W13, V12, P13, R13, W19, W16 ... */
/* PIN = AA17 sys_clkreq->bt_clk_req mode 0 */
} else if (cpu == CPU_2422) {
/* PIN = B3, GPIO.0->MMC_CD, mode 3, set above */
/* PIN = B13, GPIO.38->wlan_int, mode 3, (pun?)*/
/* Pin = Y11 VLNQ */
/* Pin = AA4 VLNQ */
/* Pin = AA6 VLNQ */
/* Pin = AA8 VLNQ */
/* Pin = AA10 VLNQ */
/* Pin = AA12 VLNQ */
/* PIN = M18 GPIO.96->KBR5 mode 3 -DO- */
__raw_writeb(0x3, base+0x10e);
/* PIN = N19 GPIO.98->KBC6 mode 3 -DO- */
__raw_writeb(0x3, base+0x110);
/* PIN = J15 MDOC_nDMAREQ */
/* PIN = H19 GPIO.100->KBC2 mode 3 -DO- */
__raw_writeb(0x3, base+0x114);
/* PIN = W13, V12, P13, R13, W19, W16 ... */
/* PIN = AA17 sys_clkreq->bt_clk_req mode 0 */
}
}
}

237
board/omap2420h4/platform.S Normal file
View file

@ -0,0 +1,237 @@
/*
* Board specific setup info
*
* (C) Copyright 2004
* Texas Instruments, <www.ti.com>
* Richard Woodruff <r-woodruff2@ti.com>
*
* 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 <config.h>
#include <version.h>
#include <asm/arch/omap2420.h>
#include <asm/arch/mem.h>
#include <asm/arch/clocks.h>
_TEXT_BASE:
.word TEXT_BASE /* sdram load addr from config.mk */
#ifdef CONFIG_PARTIAL_SRAM
/**************************************************************************
* cpy_clk_code: relocates clock code into SRAM where its safer to execute
* R1 = SRAM destination address.
*************************************************************************/
.global cpy_clk_code
cpy_clk_code:
/* Copy DPLL code into SRAM */
adr r0, go_to_speed /* get addr of clock setting code */
mov r2, #384 /* r2 size to copy (div by 32 bytes) */
mov r1, r1 /* r1 <- dest address (passed in) */
add r2, r2, r0 /* r2 <- source end address */
next2:
ldmia r0!, {r3-r10} /* copy from source address [r0] */
stmia r1!, {r3-r10} /* copy to target address [r1] */
cmp r0, r2 /* until source end address [r2] */
bne next2
mov pc, lr /* back to caller */
/* ****************************************************************************
* go_to_speed: -Moves to bypass, -Commits clock dividers, -puts dpll at speed
* -executed from SRAM.
* R0 = PRCM_CLKCFG_CTRL - addr of valid reg
* R1 = CM_CLKEN_PLL - addr dpll ctlr reg
* R2 = dpll value
* R3 = CM_IDLEST_CKGEN - addr dpll lock wait
******************************************************************************/
.global go_to_speed
go_to_speed:
sub sp, sp, #0x4 /* get some stack space */
str r4, [sp] /* save r4's value */
/* move into fast relock bypass */
ldr r8, pll_ctl_add
mov r4, #0x2
str r4, [r8]
ldr r4, pll_stat
block:
ldr r8, [r4] /* wait for bypass to take effect */
and r8, r8, #0x3
cmp r8, #0x1
bne block
/* set new dpll dividers _after_ in bypass */
ldr r4, pll_div_add
ldr r8, pll_div_val
str r8, [r4]
/* now prepare GPMC (flash) for new dpll speed */
/* flash needs to be stable when we jump back to it */
ldr r4, cfg3_0_addr
ldr r8, cfg3_0_val
str r8, [r4]
ldr r4, cfg4_0_addr
ldr r8, cfg4_0_val
str r8, [r4]
ldr r4, cfg1_0_addr
ldr r8, [r4]
orr r8, r8, #0x3 /* up gpmc divider */
str r8, [r4]
/* setup to 2x loop though code. The first loop pre-loads the
* icache, the 2nd commits the prcm config, and locks the dpll
*/
mov r4, #0x1000 /* spin spin spin */
mov r8, #0x4 /* first pass condition & set registers */
cmp r8, #0x4
2:
ldrne r8, [r3] /* DPLL lock check */
and r8, r8, #0x7
cmp r8, #0x2
beq 4f
3:
subeq r8, r8, #0x1
streq r8, [r0] /* commit dividers (2nd time) */
nop
lloop1:
sub r4, r4, #0x1 /* Loop currently necessary else bad jumps */
nop
cmp r4, #0x0
bne lloop1
mov r4, #0x40000
cmp r8, #0x1
nop
streq r2, [r1] /* lock dpll (2nd time) */
nop
lloop2:
sub r4, r4, #0x1 /* loop currently necessary else bad jumps */
nop
cmp r4, #0x0
bne lloop2
mov r4, #0x40000
cmp r8, #0x1
nop
ldreq r8, [r3] /* get lock condition for dpll */
cmp r8, #0x4 /* first time though? */
bne 2b
moveq r8, #0x2 /* set to dpll check condition. */
beq 3b /* if condition not true branch */
4:
ldr r4, [sp]
add sp, sp, #0x4 /* return stack space */
mov pc, lr /* back to caller, locked */
_go_to_speed: .word go_to_speed
/* these constants need to be close for PIC code */
cfg3_0_addr:
.word GPMC_CONFIG3_0
cfg3_0_val:
.word H4_24XX_GPMC_CONFIG3_0
cfg4_0_addr:
.word GPMC_CONFIG4_0
cfg4_0_val:
.word H4_24XX_GPMC_CONFIG4_0
cfg1_0_addr:
.word GPMC_CONFIG1_0
pll_ctl_add:
.word CM_CLKEN_PLL
pll_stat:
.word CM_IDLEST_CKGEN
pll_div_add:
.word CM_CLKSEL1_PLL
pll_div_val:
.word DPLL_VAL /* DPLL setting (300MHz default) */
#endif
.globl platformsetup
platformsetup:
mov r3, r0 /* save skip information */
#ifdef CONFIG_APTIX
ldr r0, REG_SDRC_MCFG_0
ldr r1, VAL_SDRC_MCFG_0
str r1, [r0]
ldr r0, REG_SDRC_MR_0
ldr r1, VAL_SDRC_MR_0
str r1, [r0]
/* a ddr needs emr1 set here */
ldr r0, REG_SDRC_SHARING
ldr r1, VAL_SDRC_SHARING
str r1, [r0]
ldr r0, REG_SDRC_RFR_CTRL_0
ldr r1, VAL_SDRC_RFR_CTRL_0
str r1, [r0]
/* little delay after init */
mov r2, #0x1800
1:
subs r2, r2, #0x1
bne 1b
#endif
#ifdef CONFIG_PARTIAL_SRAM
ldr sp, SRAM_STACK
str ip, [sp] /* stash old link register */
mov ip, lr /* save link reg across call */
mov r0, r3 /* pass skip info to s_init */
bl s_init /* go setup pll,mux,memory */
ldr ip, [sp] /* restore save ip */
mov lr, ip /* restore link reg */
#endif
/* map interrupt controller */
ldr r0, VAL_INTH_SETUP
mcr p15, 0, r0, c15, c2, 4
/* back to arch calling code */
mov pc, lr
/* the literal pools origin */
.ltorg
REG_CONTROL_STATUS:
.word CONTROL_STATUS
VAL_INTH_SETUP:
.word PERIFERAL_PORT_BASE
SRAM_STACK:
.word LOW_LEVEL_SRAM_STACK
#ifdef CONFIG_APTIX
REG_SDRC_SHARING:
.word SDRC_SHARING
REG_SDRC_MCFG_0:
.word SDRC_MCFG_0
REG_SDRC_MR_0:
.word SDRC_MR_0
REG_SDRC_RFR_CTRL_0:
.word SDRC_RFR_CTRL
VAL_SDRC_SHARING:
.word VAL_H4_SDRC_SHARING
VAL_SDRC_MCFG_0:
.word VAL_H4_SDRC_MCFG_0
VAL_SDRC_MR_0:
.word VAL_H4_SDRC_MR_0
VAL_SDRC_RFR_CTRL_0:
.word VAL_H4_SDRC_RFR_CTRL_0
#endif

202
board/omap2420h4/sys_info.c Normal file
View file

@ -0,0 +1,202 @@
/*
* (C) Copyright 2004
* Texas Instruments, <www.ti.com>
* Richard Woodruff <r-woodruff2@ti.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <asm/arch/omap2420.h>
#include <asm/io.h>
#include <asm/arch/bits.h>
#include <asm/arch/mem.h> /* get mem tables */
#include <asm/arch/sys_proto.h>
#include <asm/arch/sys_info.h>
#include <i2c.h>
/**************************************************************************
* get_cpu_type() - low level get cpu type
* - no C globals yet.
* - just looking to say if this is a 2422 or 2420 or ...
* - to start with we will look at switch settings..
* - 2422 id's same as 2420 for ES1 will rely on H4 board characteristics
* (mux for 2420, non-mux for 2422).
***************************************************************************/
u32 get_cpu_type(void)
{
u32 v;
v = __raw_readl(TAP_IDCODE_REG);
v &= CPU_24XX_ID_MASK;
if (v == CPU_2420_CHIPID) { /* currently 2420 and 2422 have same id */
if (is_gpmc_muxed() == GPMC_MUXED) /* if mux'ed */
return(CPU_2420);
else
return(CPU_2422);
} else
return(CPU_2420); /* don't know, say 2420 */
}
/******************************************
* get_cpu_rev(void) - extract version info
******************************************/
u32 get_cpu_rev(void)
{
u32 v;
v = __raw_readl(TAP_IDCODE_REG);
v = v >> 28;
return(v+1); /* currently 2422 and 2420 match up */
}
/***********************************************************
* get_mem_type() - identify type of mDDR part used.
* 2422 uses stacked DDR, 2 parts CS0/CS1.
* 2420 may have 1 or 2, no good way to know...only init 1...
* when eeprom data is up we can select 1 more.
*************************************************************/
u32 get_mem_type(void)
{
if (get_cpu_type() == CPU_2422)
return(DDR_STACKED);
if (get_board_type() == BOARD_H4_MENELAUS)
return(DDR_COMBO);
else
return(DDR_DISCRETE);
}
/***********************************************************************
* get_board_type() - get board type based on current production stats.
* --- NOTE: 2 I2C EEPROMs will someday be populated with proper info.
* when they are available we can get info from there. This should
* be correct of all known boards up until today.
************************************************************************/
u32 get_board_type(void)
{
if (i2c_probe(I2C_MENELAUS) == 0)
return(BOARD_H4_MENELAUS);
else
return(BOARD_H4_SDP);
}
/******************************************************************
* get_sysboot_value() - get init word settings (dip switch on h4)
******************************************************************/
u32 get_sysboot_value(void)
{
return(0x00000FFF & __raw_readl(CONTROL_STATUS));
}
/***************************************************************************
* get_gpmc0_base() - Return current address hardware will be
* fetching from. The below effectively gives what is correct, its a bit
* mis-leading compared to the TRM. For the most general case the mask
* needs to be also taken into account this does work in practice.
* - for u-boot we currently map:
* -- 0 to nothing,
* -- 4 to flash
* -- 8 to enent
* -- c to wifi
****************************************************************************/
u32 get_gpmc0_base(void)
{
u32 b;
b = __raw_readl(GPMC_CONFIG7_0);
b &= 0x1F; /* keep base [5:0] */
b = b << 24; /* ret 0x0b000000 */
return(b);
}
/*****************************************************************
* is_gpmc_muxed() - tells if address/data lines are multiplexed
*****************************************************************/
u32 is_gpmc_muxed(void)
{
u32 mux;
mux = get_sysboot_value();
if (mux & BIT1) /* if mux'ed */
return(GPMC_MUXED);
else
return(GPMC_NONMUXED);
}
/************************************************************************
* get_gpmc0_type() - read sysboot lines to see type of memory attached
************************************************************************/
u32 get_gpmc0_type(void)
{
u32 type;
type = get_sysboot_value();
if ((type & (BIT3|BIT2)) == (BIT3|BIT2))
return(TYPE_NAND);
else
return(TYPE_NOR);
}
/*******************************************************************
* get_gpmc0_width() - See if bus is in x8 or x16 (mainly for nand)
*******************************************************************/
u32 get_gpmc0_width(void)
{
u32 width;
width = get_sysboot_value();
if ((width & 0xF) == (BIT3|BIT2))
return(WIDTH_8BIT);
else
return(WIDTH_16BIT);
}
/*********************************************************************
* wait_on_value() - common routine to allow waiting for changes in
* volatile regs.
*********************************************************************/
u32 wait_on_value(u32 read_bit_mask, u32 match_value, u32 read_addr, u32 bound)
{
u32 i = 0, val;
do {
++i;
val = __raw_readl(read_addr) & read_bit_mask;
if (val == match_value)
return(1);
if (i==bound)
return(0);
} while (1);
}
/*********************************************************************
* display_board_info() - print banner with board info.
*********************************************************************/
void display_board_info(u32 btype)
{
char cpu_2420[] = "2420";
char cpu_2422[] = "2422";
char db_men[] = "Menelaus";
char db_ip[]= "IP";
char *cpu_s, *db_s;
u32 cpu = get_cpu_type();
if(cpu == CPU_2420)
cpu_s = cpu_2420;
else
cpu_s = cpu_2422;
if(btype == BOARD_H4_MENELAUS)
db_s = db_men;
else
db_s = db_ip;
printf("TI H4 SDP Base Board with OMAP%s %s Daughter Board\n",cpu_s, db_s);
}

View file

@ -0,0 +1,58 @@
/*
* January 2004 - Changed to support H4 device
* Copyright (c) 2004 Texas Instruments
*
* (C) Copyright 2002
* Gary Jennejohn, DENX Software Engineering, <gj@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
*/
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.text :
{
cpu/arm1136/start.o (.text)
*(.text)
}
. = ALIGN(4);
.rodata : { *(.rodata) }
. = ALIGN(4);
.data : { *(.data) }
. = ALIGN(4);
.got : { *(.got) }
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;
. = ALIGN(4);
__bss_start = .;
.bss : { *(.bss) }
_end = .;
}

View file

@ -99,11 +99,7 @@ uchar env_get_char_spec (int index)
int env_init(void)
{
DECLARE_GLOBAL_DATA_PTR;
int crc1_ok =
(crc32(0, flash_addr->data, ENV_SIZE) == flash_addr->crc);
int crc2_ok =
(crc32(0, flash_addr_new->data, ENV_SIZE) == flash_addr_new->crc);
int crc1_ok = 0, crc2_ok = 0;
uchar flag1 = flash_addr->flags;
uchar flag2 = flash_addr_new->flags;
@ -112,6 +108,16 @@ int env_init(void)
ulong addr1 = (ulong)&(flash_addr->data);
ulong addr2 = (ulong)&(flash_addr_new->data);
#ifdef CONFIG_OMAP2420H4
int flash_probe(void);
if(flash_probe() == 0)
goto bad_flash;
#endif
crc1_ok = (crc32(0, flash_addr->data, ENV_SIZE) == flash_addr->crc);
crc2_ok = (crc32(0, flash_addr_new->data, ENV_SIZE) == flash_addr_new->crc);
if (crc1_ok && ! crc2_ok) {
gd->env_addr = addr1;
gd->env_valid = 1;
@ -138,6 +144,9 @@ int env_init(void)
gd->env_valid = 2;
}
#ifdef CONFIG_OMAP2420H4
bad_flash:
#endif
return (0);
}
@ -252,15 +261,22 @@ Done:
int env_init(void)
{
DECLARE_GLOBAL_DATA_PTR;
#ifdef CONFIG_OMAP2420H4
int flash_probe(void);
if(flash_probe() == 0)
goto bad_flash;
#endif
if (crc32(0, env_ptr->data, ENV_SIZE) == env_ptr->crc) {
gd->env_addr = (ulong)&(env_ptr->data);
gd->env_valid = 1;
} else {
gd->env_addr = (ulong)&default_environment[0];
gd->env_valid = 0;
return(0);
}
#ifdef CONFIG_OMAP2420H4
bad_flash:
#endif
gd->env_addr = (ulong)&default_environment[0];
gd->env_valid = 0;
return (0);
}

43
cpu/arm1136/Makefile Normal file
View file

@ -0,0 +1,43 @@
#
# (C) Copyright 2000-2003
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# See file CREDITS for list of people who contributed to this
# project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
include $(TOPDIR)/config.mk
LIB = lib$(CPU).a
START = start.o
OBJS = interrupts.o cpu.o
all: .depend $(START) $(LIB)
$(LIB): $(OBJS)
$(AR) crv $@ $(OBJS)
#########################################################################
.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c)
$(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
sinclude .depend
#########################################################################

25
cpu/arm1136/config.mk Normal file
View file

@ -0,0 +1,25 @@
#
# (C) Copyright 2002
# Gary Jennejohn, DENX Software Engineering, <gj@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
#
PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8 \
PLATFORM_CPPFLAGS += -mapcs-32 -march=armv6

163
cpu/arm1136/cpu.c Normal file
View file

@ -0,0 +1,163 @@
/*
* (C) Copyright 2004 Texas Insturments
*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
*
* (C) Copyright 2002
* Gary Jennejohn, DENX Software Engineering, <gj@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
*/
/*
* CPU specific code
*/
#include <common.h>
#include <command.h>
#include <asm/arch/omap2420.h>
/* read co-processor 15, register #1 (control register) */
static unsigned long read_p15_c1 (void)
{
unsigned long value;
__asm__ __volatile__(
"mrc p15, 0, %0, c1, c0, 0 @ read control reg\n"
: "=r" (value)
:
: "memory");
return value;
}
/* write to co-processor 15, register #1 (control register) */
static void write_p15_c1 (unsigned long value)
{
__asm__ __volatile__(
"mcr p15, 0, %0, c1, c0, 0 @ write it back\n"
:
: "r" (value)
: "memory");
read_p15_c1 ();
}
static void cp_delay (void)
{
volatile int i;
/* Many OMAP regs need at least 2 nops */
for (i = 0; i < 100; i++);
}
/* See also ARM Ref. Man. */
#define C1_MMU (1<<0) /* mmu off/on */
#define C1_ALIGN (1<<1) /* alignment faults off/on */
#define C1_DC (1<<2) /* dcache off/on */
#define C1_WB (1<<3) /* merging write buffer on/off */
#define C1_BIG_ENDIAN (1<<7) /* big endian off/on */
#define C1_SYS_PROT (1<<8) /* system protection */
#define C1_ROM_PROT (1<<9) /* ROM protection */
#define C1_IC (1<<12) /* icache off/on */
#define C1_HIGH_VECTORS (1<<13) /* location of vectors: low/high addresses */
#define RESERVED_1 (0xf << 3) /* must be 111b for R/W */
int cpu_init (void)
{
/*
* setup up stacks if necessary
*/
#ifdef CONFIG_USE_IRQ
DECLARE_GLOBAL_DATA_PTR;
IRQ_STACK_START = _armboot_start - CFG_MALLOC_LEN - CFG_GBL_DATA_SIZE - 4;
FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ;
#endif
return 0;
}
int cleanup_before_linux (void)
{
/*
* this function is called just before we call linux
* it prepares the processor for linux
*
* we turn off caches etc ...
*/
unsigned long i;
disable_interrupts ();
#ifdef CONFIG_LCD
{
extern void lcd_disable(void);
extern void lcd_panel_disable(void);
lcd_disable(); /* proper disable of lcd & panel */
lcd_panel_disable();
}
#endif
/* turn off I/D-cache */
asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
i &= ~(C1_DC | C1_IC);
asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
/* flush I/D-cache */
i = 0;
asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i)); // invalidate both caches and flush btb
asm ("mcr p15, 0, %0, c7, c10, 4": :"r" (i)); // mem barrier to sync things
return(0);
}
int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
extern void reset_cpu (ulong addr);
disable_interrupts ();
reset_cpu (0);
/*NOTREACHED*/
return(0);
}
void icache_enable (void)
{
ulong reg;
reg = read_p15_c1 (); /* get control reg. */
cp_delay ();
write_p15_c1 (reg | C1_IC);
}
void icache_disable (void)
{
ulong reg;
reg = read_p15_c1 ();
cp_delay ();
write_p15_c1 (reg & ~C1_IC);
}
int icache_status (void)
{
return(read_p15_c1 () & C1_IC) != 0;
}

293
cpu/arm1136/interrupts.c Normal file
View file

@ -0,0 +1,293 @@
/*
* (C) Copyright 2004
* Texas Instruments
* Richard Woodruff <r-woodruff2@ti.com>
*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Alex Zuepke <azu@sysgo.de>
*
* (C) Copyright 2002
* Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <asm/arch/bits.h>
#include <asm/arch/omap2420.h>
#include <asm/proc-armv/ptrace.h>
extern void reset_cpu(ulong addr);
#define TIMER_LOAD_VAL 0
/* macro to read the 32 bit timer */
#define READ_TIMER (*(volatile ulong *)(CFG_TIMERBASE+TCRR))
#ifdef CONFIG_USE_IRQ
/* enable IRQ interrupts */
void enable_interrupts (void)
{
unsigned long temp;
__asm__ __volatile__("mrs %0, cpsr\n"
"bic %0, %0, #0x80\n"
"msr cpsr_c, %0"
: "=r" (temp)
:
: "memory");
}
/*
* disable IRQ/FIQ interrupts
* returns true if interrupts had been enabled before we disabled them
*/
int disable_interrupts (void)
{
unsigned long old,temp;
__asm__ __volatile__("mrs %0, cpsr\n"
"orr %1, %0, #0xc0\n"
"msr cpsr_c, %1"
: "=r" (old), "=r" (temp)
:
: "memory");
return(old & 0x80) == 0;
}
#else
void enable_interrupts (void)
{
return;
}
int disable_interrupts (void)
{
return 0;
}
#endif
void bad_mode (void)
{
panic ("Resetting CPU ...\n");
reset_cpu (0);
}
void show_regs (struct pt_regs *regs)
{
unsigned long flags;
const char *processor_modes[] = {
"USER_26", "FIQ_26", "IRQ_26", "SVC_26",
"UK4_26", "UK5_26", "UK6_26", "UK7_26",
"UK8_26", "UK9_26", "UK10_26", "UK11_26",
"UK12_26", "UK13_26", "UK14_26", "UK15_26",
"USER_32", "FIQ_32", "IRQ_32", "SVC_32",
"UK4_32", "UK5_32", "UK6_32", "ABT_32",
"UK8_32", "UK9_32", "UK10_32", "UND_32",
"UK12_32", "UK13_32", "UK14_32", "SYS_32",
};
flags = condition_codes (regs);
printf ("pc : [<%08lx>] lr : [<%08lx>]\n"
"sp : %08lx ip : %08lx fp : %08lx\n",
instruction_pointer (regs),
regs->ARM_lr, regs->ARM_sp, regs->ARM_ip, regs->ARM_fp);
printf ("r10: %08lx r9 : %08lx r8 : %08lx\n",
regs->ARM_r10, regs->ARM_r9, regs->ARM_r8);
printf ("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n",
regs->ARM_r7, regs->ARM_r6, regs->ARM_r5, regs->ARM_r4);
printf ("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n",
regs->ARM_r3, regs->ARM_r2, regs->ARM_r1, regs->ARM_r0);
printf ("Flags: %c%c%c%c",
flags & CC_N_BIT ? 'N' : 'n',
flags & CC_Z_BIT ? 'Z' : 'z',
flags & CC_C_BIT ? 'C' : 'c', flags & CC_V_BIT ? 'V' : 'v');
printf (" IRQs %s FIQs %s Mode %s%s\n",
interrupts_enabled (regs) ? "on" : "off",
fast_interrupts_enabled (regs) ? "on" : "off",
processor_modes[processor_mode (regs)],
thumb_mode (regs) ? " (T)" : "");
}
void do_undefined_instruction (struct pt_regs *pt_regs)
{
printf ("undefined instruction\n");
show_regs (pt_regs);
bad_mode ();
}
void do_software_interrupt (struct pt_regs *pt_regs)
{
printf ("software interrupt\n");
show_regs (pt_regs);
bad_mode ();
}
void do_prefetch_abort (struct pt_regs *pt_regs)
{
printf ("prefetch abort\n");
show_regs (pt_regs);
bad_mode ();
}
void do_data_abort (struct pt_regs *pt_regs)
{
printf ("data abort\n");
show_regs (pt_regs);
bad_mode ();
}
void do_not_used (struct pt_regs *pt_regs)
{
printf ("not used\n");
show_regs (pt_regs);
bad_mode ();
}
void do_fiq (struct pt_regs *pt_regs)
{
printf ("fast interrupt request\n");
show_regs (pt_regs);
bad_mode ();
}
void do_irq (struct pt_regs *pt_regs)
{
printf ("interrupt request\n");
show_regs (pt_regs);
bad_mode ();
}
static ulong timestamp;
static ulong lastinc;
/* nothing really to do with interrupts, just starts up a counter. */
int interrupt_init (void)
{
int32_t val;
/* Start the counter ticking up */
*((int32_t *) (CFG_TIMERBASE + TLDR)) = TIMER_LOAD_VAL; /* reload value on overflow*/
val = (CFG_PVT << 2) | BIT5 | BIT1 | BIT0; /* mask to enable timer*/
*((int32_t *) (CFG_TIMERBASE + TCLR)) = val; /* start timer */
reset_timer_masked(); /* init the timestamp and lastinc value */
return(0);
}
/*
* timer without interrupts
*/
void reset_timer (void)
{
reset_timer_masked ();
}
ulong get_timer (ulong base)
{
return get_timer_masked () - base;
}
void set_timer (ulong t)
{
timestamp = t;
}
/* delay x useconds AND perserve advance timstamp value */
void udelay (unsigned long usec)
{
ulong tmo, tmp;
if (usec >= 1000) { /* if "big" number, spread normalization to seconds */
tmo = usec / 1000; /* start to normalize for usec to ticks per sec */
tmo *= CFG_HZ; /* find number of "ticks" to wait to achieve target */
tmo /= 1000; /* finish normalize. */
} else { /* else small number, don't kill it prior to HZ multiply */
tmo = usec * CFG_HZ;
tmo /= (1000*1000);
}
tmp = get_timer (0); /* get current timestamp */
if ( (tmo + tmp + 1) < tmp )/* if setting this forward will roll time stamp */
reset_timer_masked (); /* reset "advancing" timestamp to 0, set lastinc value */
else
tmo += tmp; /* else, set advancing stamp wake up time */
while (get_timer_masked () < tmo)/* loop till event */
/*NOP*/;
}
void reset_timer_masked (void)
{
/* reset time */
lastinc = READ_TIMER; /* capture current incrementer value time */
timestamp = 0; /* start "advancing" time stamp from 0 */
}
ulong get_timer_masked (void)
{
ulong now = READ_TIMER; /* current tick value */
if (now >= lastinc) /* normal mode (non roll) */
timestamp += (now - lastinc); /* move stamp fordward with absoulte diff ticks */
else /* we have rollover of incrementer */
timestamp += (0xFFFFFFFF - lastinc) + now;
lastinc = now;
return timestamp;
}
/* waits specified delay value and resets timestamp */
void udelay_masked (unsigned long usec)
{
ulong tmo;
if (usec >= 1000) { /* if "big" number, spread normalization to seconds */
tmo = usec / 1000; /* start to normalize for usec to ticks per sec */
tmo *= CFG_HZ; /* find number of "ticks" to wait to achieve target */
tmo /= 1000; /* finish normalize. */
} else { /* else small number, don't kill it prior to HZ multiply */
tmo = usec * CFG_HZ;
tmo /= (1000*1000);
}
reset_timer_masked (); /* set "advancing" timestamp to 0, set lastinc vaule */
while (get_timer_masked () < tmo) /* wait for time stamp to overtake tick number.*/
/* NOP */;
}
/*
* This function is derived from PowerPC code (read timebase as long long).
* On ARM it just returns the timer value.
*/
unsigned long long get_ticks(void)
{
return get_timer(0);
}
/*
* This function is derived from PowerPC code (timebase clock frequency).
* On ARM it returns the number of timer ticks per second.
*/
ulong get_tbclk (void)
{
ulong tbclk;
tbclk = CFG_HZ;
return tbclk;
}

414
cpu/arm1136/start.S Normal file
View file

@ -0,0 +1,414 @@
/*
* armboot - Startup Code for OMP2420/ARM1136 CPU-core
*
* Copyright (c) 2004 Texas Instruments <r-woodruff2@ti.com>
*
* Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
* Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
* Copyright (c) 2002 Gary Jennejohn <gj@denx.de>
* Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com>
* Copyright (c) 2003 Kshitij <kshitij@ti.com>
*
* 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 <config.h>
#include <version.h>
#include <asm/arch/omap2420.h>
.globl _start
_start: b reset
ldr pc, _undefined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
ldr pc, _not_used
ldr pc, _irq
ldr pc, _fiq
_undefined_instruction: .word undefined_instruction
_software_interrupt: .word software_interrupt
_prefetch_abort: .word prefetch_abort
_data_abort: .word data_abort
_not_used: .word not_used
_irq: .word irq
_fiq: .word fiq
_pad: .word 0x12345678 /* now 16*4=64 */
.global _end_vect
_end_vect:
.balignl 16,0xdeadbeef
/*
*************************************************************************
*
* Startup Code (reset vector)
*
* do important init only if we don't start from memory!
* setup Memory and board specific bits prior to relocation.
* relocate armboot to ram
* setup stack
*
*************************************************************************
*/
_TEXT_BASE:
.word TEXT_BASE
.globl _armboot_start
_armboot_start:
.word _start
/*
* These are defined in the board-specific linker script.
*/
.globl _bss_start
_bss_start:
.word __bss_start
.globl _bss_end
_bss_end:
.word _end
#ifdef CONFIG_USE_IRQ
/* IRQ stack memory (calculated at run-time) */
.globl IRQ_STACK_START
IRQ_STACK_START:
.word 0x0badc0de
/* IRQ stack memory (calculated at run-time) */
.globl FIQ_STACK_START
FIQ_STACK_START:
.word 0x0badc0de
#endif
/*
* the actual reset code
*/
reset:
/*
* set the cpu to SVC32 mode
*/
mrs r0,cpsr
bic r0,r0,#0x1f
orr r0,r0,#0xd3
msr cpsr,r0
#ifdef CONFIG_OMAP2420H4
/* Copy vectors to mask ROM indirect addr */
adr r0, _start /* r0 <- current position of code */
mov r2, #64 /* r2 <- size to copy */
add r2, r0, r2 /* r2 <- source end address */
mov r1, #SRAM_OFFSET0 /* build vect addr */
mov r3, #SRAM_OFFSET1
add r1, r1, r3
mov r3, #SRAM_OFFSET2
add r1, r1, r3
next:
ldmia r0!, {r3-r10} /* copy from source address [r0] */
stmia r1!, {r3-r10} /* copy to target address [r1] */
cmp r0, r2 /* until source end address [r2] */
bne next /* loop until equal */
#ifdef CONFIG_PARTIAL_SRAM
bl cpy_clk_code /* put dpll adjust code behind vectors */
#endif
#endif
/* the mask ROM code should have PLL and others stable */
bl cpu_init_crit
relocate: /* relocate U-Boot to RAM */
adr r0, _start /* r0 <- current position of code */
ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
cmp r0, r1 /* don't reloc during debug */
beq stack_setup
ldr r2, _armboot_start
ldr r3, _bss_start
sub r2, r3, r2 /* r2 <- size of armboot */
add r2, r0, r2 /* r2 <- source end address */
copy_loop:
ldmia r0!, {r3-r10} /* copy from source address [r0] */
stmia r1!, {r3-r10} /* copy to target address [r1] */
cmp r0, r2 /* until source end addreee [r2] */
ble copy_loop
/* Set up the stack */
stack_setup:
ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
#ifdef CONFIG_USE_IRQ
sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
sub sp, r0, #12 /* leave 3 words for abort-stack */
clear_bss:
ldr r0, _bss_start /* find start of bss segment */
ldr r1, _bss_end /* stop here */
mov r2, #0x00000000 /* clear */
clbss_l:str r2, [r0] /* clear loop... */
add r0, r0, #4
cmp r0, r1
bne clbss_l
ldr pc, _start_armboot
_start_armboot: .word start_armboot
/*
*************************************************************************
*
* CPU_init_critical registers
*
* setup important registers
* setup memory timing
*
*************************************************************************
*/
cpu_init_crit:
/*
* flush v4 I/D caches
*/
mov r0, #0
mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
/*
* disable MMU stuff and caches
*/
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
orr r0, r0, #0x00000002 @ set bit 2 (A) Align
#ifndef CONFIG_ICACHE_OFF
orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
#endif
mcr p15, 0, r0, c1, c0, 0
/*
* Jump to board specific initialization... The Mask ROM will have already initialized
* basic memory. Go here to bump up clock rate and handle wake up conditions.
*/
adr r0, _start /* r0 <- current position of code */
ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
cmp r0, r1 /* pass on info about skipping some init portions */
moveq r0,#0x1 /* flag to skip prcm and sdrc setup */
movne r0,#0x0
mov ip, lr /* persevere link reg across call */
bl platformsetup /* go setup pll,mux,memory */
mov lr, ip /* restore link */
mov pc, lr /* back to my caller */
/*
*************************************************************************
*
* Interrupt handling
*
*************************************************************************
*/
@
@ IRQ stack frame.
@
#define S_FRAME_SIZE 72
#define S_OLD_R0 68
#define S_PSR 64
#define S_PC 60
#define S_LR 56
#define S_SP 52
#define S_IP 48
#define S_FP 44
#define S_R10 40
#define S_R9 36
#define S_R8 32
#define S_R7 28
#define S_R6 24
#define S_R5 20
#define S_R4 16
#define S_R3 12
#define S_R2 8
#define S_R1 4
#define S_R0 0
#define MODE_SVC 0x13
#define I_BIT 0x80
/*
* use bad_save_user_regs for abort/prefetch/undef/swi ...
* use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
*/
.macro bad_save_user_regs
sub sp, sp, #S_FRAME_SIZE @ carve out a frame on current user stack
stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12
ldr r2, _armboot_start
sub r2, r2, #(CFG_MALLOC_LEN)
sub r2, r2, #(CFG_GBL_DATA_SIZE+8) @ set base 2 words into abort stack
ldmia r2, {r2 - r3} @ get values for "aborted" pc and cpsr (into parm regs)
add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack
add r5, sp, #S_SP
mov r1, lr
stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
mov r0, sp @ save current stack into r0 (param register)
.endm
.macro irq_save_user_regs
sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} @ Calling r0-r12
add r8, sp, #S_PC @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
stmdb r8, {sp, lr}^ @ Calling SP, LR
str lr, [r8, #0] @ Save calling PC
mrs r6, spsr
str r6, [r8, #4] @ Save CPSR
str r0, [r8, #8] @ Save OLD_R0
mov r0, sp
.endm
.macro irq_restore_user_regs
ldmia sp, {r0 - lr}^ @ Calling r0 - lr
mov r0, r0
ldr lr, [sp, #S_PC] @ Get PC
add sp, sp, #S_FRAME_SIZE
subs pc, lr, #4 @ return & move spsr_svc into cpsr
.endm
.macro get_bad_stack
ldr r13, _armboot_start @ setup our mode stack (enter in banked mode)
sub r13, r13, #(CFG_MALLOC_LEN) @ move past malloc pool
sub r13, r13, #(CFG_GBL_DATA_SIZE+8) @ move to reserved a couple spots for abort stack
str lr, [r13] @ save caller lr in position 0 of saved stack
mrs lr, spsr @ get the spsr
str lr, [r13, #4] @ save spsr in position 1 of saved stack
mov r13, #MODE_SVC @ prepare SVC-Mode
@ msr spsr_c, r13
msr spsr, r13 @ switch modes, make sure moves will execute
mov lr, pc @ capture return pc
movs pc, lr @ jump to next instruction & switch modes.
.endm
.macro get_bad_stack_swi
sub r13, r13, #4 @ space on current stack for scratch reg.
str r0, [r13] @ save R0's value.
ldr r0, _armboot_start @ get data regions start
sub r0, r0, #(CFG_MALLOC_LEN) @ move past malloc pool
sub r0, r0, #(CFG_GBL_DATA_SIZE+8) @ move past gbl and a couple spots for abort stack
str lr, [r0] @ save caller lr in position 0 of saved stack
mrs r0, spsr @ get the spsr
str lr, [r0, #4] @ save spsr in position 1 of saved stack
ldr r0, [r13] @ restore r0
add r13, r13, #4 @ pop stack entry
.endm
.macro get_irq_stack @ setup IRQ stack
ldr sp, IRQ_STACK_START
.endm
.macro get_fiq_stack @ setup FIQ stack
ldr sp, FIQ_STACK_START
.endm
/*
* exception handlers
*/
.align 5
undefined_instruction:
get_bad_stack
bad_save_user_regs
bl do_undefined_instruction
.align 5
software_interrupt:
get_bad_stack_swi
bad_save_user_regs
bl do_software_interrupt
.align 5
prefetch_abort:
get_bad_stack
bad_save_user_regs
bl do_prefetch_abort
.align 5
data_abort:
get_bad_stack
bad_save_user_regs
bl do_data_abort
.align 5
not_used:
get_bad_stack
bad_save_user_regs
bl do_not_used
#ifdef CONFIG_USE_IRQ
.align 5
irq:
get_irq_stack
irq_save_user_regs
bl do_irq
irq_restore_user_regs
.align 5
fiq:
get_fiq_stack
/* someone ought to write a more effiction fiq_save_user_regs */
irq_save_user_regs
bl do_fiq
irq_restore_user_regs
#else
.align 5
irq:
get_bad_stack
bad_save_user_regs
bl do_irq
.align 5
fiq:
get_bad_stack
bad_save_user_regs
bl do_fiq
#endif
.align 5
.global arm1136_cache_flush
arm1136_cache_flush:
mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache
mov pc, lr @ back to caller
.align 5
.globl reset_cpu
reset_cpu:
ldr r1, rstctl /* get addr for global reset reg */
mov r3, #0x3 /* full reset pll+mpu */
str r3, [r1] /* force reset */
mov r0, r0
_loop_forever:
b _loop_forever
rstctl:
.word PM_RSTCTRL_WKUP

38
doc/README.ne2000 Normal file
View file

@ -0,0 +1,38 @@
This driver supports NE2000 compatible cards (those based on DP8390,
DP83902 and similar). It can be used with PCMCIA/CF cards provided
that the CCR is correctly initialized.
The code is based on sources from the Linux kernel (pcnet_cs.c,
8390.h) and eCOS(if_dp83902a.c, if_dp83902a.h). Both of these 2
wonderful world are GPL, so this is, of course, GPL.
I developed and tested this driver on a custom PXA255 based system and
with a billionton CF network card connected to the PCMCIA interface of
the micro (have a look at README.PXA_CF for the support of this port).
The options you have to specify in the config file are (with the
value for my board as an example):
#define CONFIG_DRIVER_NE2000
- Enables the driver
#define CONFIG_DRIVER_NE2000_BASE (0x20000000+0x300)
- Address where the board is mapped
#define CONFIG_DRIVER_NE2000_CCR (0x28000000+0x3f8)
- Address of the CCR (card configuration register). It could be found
by enabling DEBUG in cmd_pcmcia.c. If this is not defined nothing is
done as far as PCMCIA support is concerned.
#define CONFIG_DRIVER_NE2000_VAL (0x20)
- The value to be written in the CCR. It selects among different I/O
spaces that could be used by the card.
Enjoy!
Christian Pellegrin <chri@ascensit.com>

126
drivers/8390.h Normal file
View file

@ -0,0 +1,126 @@
/*
Ported to U-Boot by Christian Pellegrin <chri@ascensit.com>
Based on sources from the Linux kernel (pcnet_cs.c, 8390.h) and
eCOS(if_dp83902a.c, if_dp83902a.h). Both of these 2 wonderful world
are GPL, so this is, of course, GPL.
*/
/* Generic NS8390 register definitions. */
/* This file is part of Donald Becker's 8390 drivers, and is distributed
under the same license. Auto-loading of 8390.o only in v2.2 - Paul G.
Some of these names and comments originated from the Crynwr
packet drivers, which are distributed under the GPL. */
#ifndef _8390_h
#define _8390_h
/* Some generic ethernet register configurations. */
#define E8390_TX_IRQ_MASK 0xa /* For register EN0_ISR */
#define E8390_RX_IRQ_MASK 0x5
#define E8390_RXCONFIG 0x4 /* EN0_RXCR: broadcasts, no multicast,errors */
#define E8390_RXOFF 0x20 /* EN0_RXCR: Accept no packets */
#define E8390_TXCONFIG 0x00 /* EN0_TXCR: Normal transmit mode */
#define E8390_TXOFF 0x02 /* EN0_TXCR: Transmitter off */
/* Register accessed at EN_CMD, the 8390 base addr. */
#define E8390_STOP 0x01 /* Stop and reset the chip */
#define E8390_START 0x02 /* Start the chip, clear reset */
#define E8390_TRANS 0x04 /* Transmit a frame */
#define E8390_RREAD 0x08 /* Remote read */
#define E8390_RWRITE 0x10 /* Remote write */
#define E8390_NODMA 0x20 /* Remote DMA */
#define E8390_PAGE0 0x00 /* Select page chip registers */
#define E8390_PAGE1 0x40 /* using the two high-order bits */
#define E8390_PAGE2 0x80 /* Page 3 is invalid. */
/*
* Only generate indirect loads given a machine that needs them.
* - removed AMIGA_PCMCIA from this list, handled as ISA io now
*/
#define n2k_inb(port) (*((volatile unsigned char *)(port+CONFIG_DRIVER_NE2000_BASE)))
#define n2k_outb(val,port) (*((volatile unsigned char *)(port+CONFIG_DRIVER_NE2000_BASE)) = val)
#define EI_SHIFT(x) (x)
#define E8390_CMD EI_SHIFT(0x00) /* The command register (for all pages) */
/* Page 0 register offsets. */
#define EN0_CLDALO EI_SHIFT(0x01) /* Low byte of current local dma addr RD */
#define EN0_STARTPG EI_SHIFT(0x01) /* Starting page of ring bfr WR */
#define EN0_CLDAHI EI_SHIFT(0x02) /* High byte of current local dma addr RD */
#define EN0_STOPPG EI_SHIFT(0x02) /* Ending page +1 of ring bfr WR */
#define EN0_BOUNDARY EI_SHIFT(0x03) /* Boundary page of ring bfr RD WR */
#define EN0_TSR EI_SHIFT(0x04) /* Transmit status reg RD */
#define EN0_TPSR EI_SHIFT(0x04) /* Transmit starting page WR */
#define EN0_NCR EI_SHIFT(0x05) /* Number of collision reg RD */
#define EN0_TCNTLO EI_SHIFT(0x05) /* Low byte of tx byte count WR */
#define EN0_FIFO EI_SHIFT(0x06) /* FIFO RD */
#define EN0_TCNTHI EI_SHIFT(0x06) /* High byte of tx byte count WR */
#define EN0_ISR EI_SHIFT(0x07) /* Interrupt status reg RD WR */
#define EN0_CRDALO EI_SHIFT(0x08) /* low byte of current remote dma address RD */
#define EN0_RSARLO EI_SHIFT(0x08) /* Remote start address reg 0 */
#define EN0_CRDAHI EI_SHIFT(0x09) /* high byte, current remote dma address RD */
#define EN0_RSARHI EI_SHIFT(0x09) /* Remote start address reg 1 */
#define EN0_RCNTLO EI_SHIFT(0x0a) /* Remote byte count reg WR */
#define EN0_RCNTHI EI_SHIFT(0x0b) /* Remote byte count reg WR */
#define EN0_RSR EI_SHIFT(0x0c) /* rx status reg RD */
#define EN0_RXCR EI_SHIFT(0x0c) /* RX configuration reg WR */
#define EN0_TXCR EI_SHIFT(0x0d) /* TX configuration reg WR */
#define EN0_COUNTER0 EI_SHIFT(0x0d) /* Rcv alignment error counter RD */
#define EN0_DCFG EI_SHIFT(0x0e) /* Data configuration reg WR */
#define EN0_COUNTER1 EI_SHIFT(0x0e) /* Rcv CRC error counter RD */
#define EN0_IMR EI_SHIFT(0x0f) /* Interrupt mask reg WR */
#define EN0_COUNTER2 EI_SHIFT(0x0f) /* Rcv missed frame error counter RD */
/* Bits in EN0_ISR - Interrupt status register */
#define ENISR_RX 0x01 /* Receiver, no error */
#define ENISR_TX 0x02 /* Transmitter, no error */
#define ENISR_RX_ERR 0x04 /* Receiver, with error */
#define ENISR_TX_ERR 0x08 /* Transmitter, with error */
#define ENISR_OVER 0x10 /* Receiver overwrote the ring */
#define ENISR_COUNTERS 0x20 /* Counters need emptying */
#define ENISR_RDC 0x40 /* remote dma complete */
#define ENISR_RESET 0x80 /* Reset completed */
#define ENISR_ALL 0x3f /* Interrupts we will enable */
/* Bits in EN0_DCFG - Data config register */
#define ENDCFG_WTS 0x01 /* word transfer mode selection */
#define ENDCFG_BOS 0x02 /* byte order selection */
#define ENDCFG_AUTO_INIT 0x10 /* Auto-init to remove packets from ring */
#define ENDCFG_FIFO 0x40 /* 8 bytes */
/* Page 1 register offsets. */
#define EN1_PHYS EI_SHIFT(0x01) /* This board's physical enet addr RD WR */
#define EN1_PHYS_SHIFT(i) EI_SHIFT(i+1) /* Get and set mac address */
#define EN1_CURPAG EI_SHIFT(0x07) /* Current memory page RD WR */
#define EN1_MULT EI_SHIFT(0x08) /* Multicast filter mask array (8 bytes) RD WR */
#define EN1_MULT_SHIFT(i) EI_SHIFT(8+i) /* Get and set multicast filter */
/* Bits in received packet status byte and EN0_RSR*/
#define ENRSR_RXOK 0x01 /* Received a good packet */
#define ENRSR_CRC 0x02 /* CRC error */
#define ENRSR_FAE 0x04 /* frame alignment error */
#define ENRSR_FO 0x08 /* FIFO overrun */
#define ENRSR_MPA 0x10 /* missed pkt */
#define ENRSR_PHY 0x20 /* physical/multicast address */
#define ENRSR_DIS 0x40 /* receiver disable. set in monitor mode */
#define ENRSR_DEF 0x80 /* deferring */
/* Transmitted packet status, EN0_TSR. */
#define ENTSR_PTX 0x01 /* Packet transmitted without error */
#define ENTSR_ND 0x02 /* The transmit wasn't deferred. */
#define ENTSR_COL 0x04 /* The transmit collided at least once. */
#define ENTSR_ABT 0x08 /* The transmit collided 16 times, and was deferred. */
#define ENTSR_CRS 0x10 /* The carrier sense was lost. */
#define ENTSR_FU 0x20 /* A "FIFO underrun" occurred during transmit. */
#define ENTSR_CDH 0x40 /* The collision detect "heartbeat" signal was lost. */
#define ENTSR_OWC 0x80 /* There was an out-of-window collision. */
#define NIC_RECEIVE_MONITOR_MODE 0x20
#endif /* _8390_h */

View file

@ -32,9 +32,10 @@ OBJS = 3c589.o 5701rls.o ali512x.o \
cs8900.o ct69000.o dataflash.o dc2114x.o dm9000x.o \
e1000.o eepro100.o \
i8042.o i82365.o inca-ip_sw.o keyboard.o \
lan91c96.o natsemi.o netarm_eth.o netconsole.o \
lan91c96.o \
natsemi.o ne2000.o netarm_eth.o netconsole.o \
ns16550.o ns8382x.o ns87308.o omap1510_i2c.o \
pci.o pci_auto.o pci_indirect.o \
omap24xx_i2c.o pci.o pci_auto.o pci_indirect.o \
pcnet.o plb2800_eth.o \
ps2ser.o ps2mult.o pc_keyb.o \
rtl8019.o rtl8139.o rtl8169.o \

963
drivers/ne2000.c Normal file
View file

@ -0,0 +1,963 @@
/*
Ported to U-Boot by Christian Pellegrin <chri@ascensit.com>
Based on sources from the Linux kernel (pcnet_cs.c, 8390.h) and
eCOS(if_dp83902a.c, if_dp83902a.h). Both of these 2 wonderful world
are GPL, so this is, of course, GPL.
==========================================================================
dev/if_dp83902a.c
Ethernet device driver for NS DP83902a ethernet controller
==========================================================================
####ECOSGPLCOPYRIGHTBEGIN####
-------------------------------------------
This file is part of eCos, the Embedded Configurable Operating System.
Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
eCos 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 or (at your option) any later version.
eCos 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 eCos; if not, write to the Free Software Foundation, Inc.,
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
As a special exception, if other files instantiate templates or use macros
or inline functions from this file, or you compile this file and link it
with other works to produce a work based on this file, this file does not
by itself cause the resulting work to be covered by the GNU General Public
License. However the source code for this file must still be made available
in accordance with section (3) of the GNU General Public License.
This exception does not invalidate any other reasons why a work based on
this file might be covered by the GNU General Public License.
Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
at http://sources.redhat.com/ecos/ecos-license/
-------------------------------------------
####ECOSGPLCOPYRIGHTEND####
####BSDCOPYRIGHTBEGIN####
-------------------------------------------
Portions of this software may have been derived from OpenBSD or other sources,
and are covered by the appropriate copyright disclaimers included herein.
-------------------------------------------
####BSDCOPYRIGHTEND####
==========================================================================
#####DESCRIPTIONBEGIN####
Author(s): gthomas
Contributors: gthomas, jskov, rsandifo
Date: 2001-06-13
Purpose:
Description:
FIXME: Will fail if pinged with large packets (1520 bytes)
Add promisc config
Add SNMP
####DESCRIPTIONEND####
==========================================================================
*/
#include <common.h>
#include <command.h>
#include <net.h>
#include <malloc.h>
#ifdef CONFIG_DRIVER_NE2000
/* wor around udelay resetting OCR */
static void my_udelay(long us) {
long tmo;
tmo = get_timer (0) + us * CFG_HZ / 1000000; /* will this be much greater than 0 ? */
while (get_timer (0) < tmo);
}
#define mdelay(n) my_udelay((n)*1000)
/* forward definition of function used for the uboot interface */
void uboot_push_packet_len(int len);
void uboot_push_tx_done(int key, int val);
/* timeout for tx/rx in s */
#define TOUT 5
#define ETHER_ADDR_LEN 6
/*
------------------------------------------------------------------------
Debugging details
Set to perms of:
0 disables all debug output
1 for process debug output
2 for added data IO output: get_reg, put_reg
4 for packet allocation/free output
8 for only startup status, so we can tell we're installed OK
*/
/*#define DEBUG 0xf*/
#define DEBUG 0
#if DEBUG & 1
#define DEBUG_FUNCTION() do { printf("%s\n", __FUNCTION__); } while (0)
#define DEBUG_LINE() do { printf("%d\n", __LINE__); } while (0)
#else
#define DEBUG_FUNCTION() do {} while(0)
#define DEBUG_LINE() do {} while(0)
#endif
#include "ne2000.h"
#if DEBUG & 1
#define PRINTK(args...) printf(args)
#else
#define PRINTK(args...)
#endif
static dp83902a_priv_data_t nic; /* just one instance of the card supported */
static bool
dp83902a_init(void)
{
dp83902a_priv_data_t *dp = &nic;
cyg_uint8* base;
int i;
DEBUG_FUNCTION();
base = dp->base;
if (!base) return false; /* No device found */
DEBUG_LINE();
/* Prepare ESA */
DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1); /* Select page 1 */
/* Use the address from the serial EEPROM */
for (i = 0; i < 6; i++)
DP_IN(base, DP_P1_PAR0+i, dp->esa[i]);
DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0); /* Select page 0 */
printf("NE2000 - %s ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
"eeprom",
dp->esa[0],
dp->esa[1],
dp->esa[2],
dp->esa[3],
dp->esa[4],
dp->esa[5] );
return true;
}
static void
dp83902a_stop(void)
{
dp83902a_priv_data_t *dp = &nic;
cyg_uint8 *base = dp->base;
DEBUG_FUNCTION();
DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_STOP); /* Brutal */
DP_OUT(base, DP_ISR, 0xFF); /* Clear any pending interrupts */
DP_OUT(base, DP_IMR, 0x00); /* Disable all interrupts */
dp->running = false;
}
/*
This function is called to "start up" the interface. It may be called
multiple times, even when the hardware is already running. It will be
called whenever something "hardware oriented" changes and should leave
the hardware ready to send/receive packets.
*/
static void
dp83902a_start(unsigned char * enaddr)
{
dp83902a_priv_data_t *dp = &nic;
cyg_uint8 *base = dp->base;
int i;
DEBUG_FUNCTION();
DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_STOP); /* Brutal */
DP_OUT(base, DP_DCR, DP_DCR_INIT);
DP_OUT(base, DP_RBCH, 0); /* Remote byte count */
DP_OUT(base, DP_RBCL, 0);
DP_OUT(base, DP_RCR, DP_RCR_MON); /* Accept no packets */
DP_OUT(base, DP_TCR, DP_TCR_LOCAL); /* Transmitter [virtually] off */
DP_OUT(base, DP_TPSR, dp->tx_buf1); /* Transmitter start page */
dp->tx1 = dp->tx2 = 0;
dp->tx_next = dp->tx_buf1;
dp->tx_started = false;
DP_OUT(base, DP_PSTART, dp->rx_buf_start); /* Receive ring start page */
DP_OUT(base, DP_BNDRY, dp->rx_buf_end-1); /* Receive ring boundary */
DP_OUT(base, DP_PSTOP, dp->rx_buf_end); /* Receive ring end page */
dp->rx_next = dp->rx_buf_start-1;
DP_OUT(base, DP_ISR, 0xFF); /* Clear any pending interrupts */
DP_OUT(base, DP_IMR, DP_IMR_All); /* Enable all interrupts */
DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1 | DP_CR_STOP); /* Select page 1 */
DP_OUT(base, DP_P1_CURP, dp->rx_buf_start); /* Current page - next free page for Rx */
for (i = 0; i < ETHER_ADDR_LEN; i++) {
DP_OUT(base, DP_P1_PAR0+i, enaddr[i]);
}
/* Enable and start device */
DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
DP_OUT(base, DP_TCR, DP_TCR_NORMAL); /* Normal transmit operations */
DP_OUT(base, DP_RCR, DP_RCR_AB); /* Accept broadcast, no errors, no multicast */
dp->running = true;
}
/*
This routine is called to start the transmitter. It is split out from the
data handling routine so it may be called either when data becomes first
available or when an Tx interrupt occurs
*/
static void
dp83902a_start_xmit(int start_page, int len)
{
dp83902a_priv_data_t *dp = (dp83902a_priv_data_t *) &nic;
cyg_uint8 *base = dp->base;
DEBUG_FUNCTION();
#if DEBUG & 1
printf("Tx pkt %d len %d\n", start_page, len);
if (dp->tx_started)
printf("TX already started?!?\n");
#endif
DP_OUT(base, DP_ISR, (DP_ISR_TxP | DP_ISR_TxE));
DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
DP_OUT(base, DP_TBCL, len & 0xFF);
DP_OUT(base, DP_TBCH, len >> 8);
DP_OUT(base, DP_TPSR, start_page);
DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_TXPKT | DP_CR_START);
dp->tx_started = true;
}
/*
This routine is called to send data to the hardware. It is known a-priori
that there is free buffer space (dp->tx_next).
*/
static void
dp83902a_send(unsigned char *data, int total_len, unsigned long key)
{
struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
cyg_uint8 *base = dp->base;
int len, start_page, pkt_len, i, isr;
#if DEBUG & 4
int dx;
#endif
DEBUG_FUNCTION();
len = pkt_len = total_len;
if (pkt_len < IEEE_8023_MIN_FRAME) pkt_len = IEEE_8023_MIN_FRAME;
start_page = dp->tx_next;
if (dp->tx_next == dp->tx_buf1) {
dp->tx1 = start_page;
dp->tx1_len = pkt_len;
dp->tx1_key = key;
dp->tx_next = dp->tx_buf2;
} else {
dp->tx2 = start_page;
dp->tx2_len = pkt_len;
dp->tx2_key = key;
dp->tx_next = dp->tx_buf1;
}
#if DEBUG & 5
printf("TX prep page %d len %d\n", start_page, pkt_len);
#endif
DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */
{
/* Dummy read. The manual sez something slightly different, */
/* but the code is extended a bit to do what Hitachi's monitor */
/* does (i.e., also read data). */
cyg_uint16 tmp;
int len = 1;
DP_OUT(base, DP_RSAL, 0x100-len);
DP_OUT(base, DP_RSAH, (start_page-1) & 0xff);
DP_OUT(base, DP_RBCL, len);
DP_OUT(base, DP_RBCH, 0);
DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_RDMA | DP_CR_START);
DP_IN_DATA(dp->data, tmp);
}
#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA
/* Stall for a bit before continuing to work around random data */
/* corruption problems on some platforms. */
CYGACC_CALL_IF_DELAY_US(1);
#endif
/* Send data to device buffer(s) */
DP_OUT(base, DP_RSAL, 0);
DP_OUT(base, DP_RSAH, start_page);
DP_OUT(base, DP_RBCL, pkt_len & 0xFF);
DP_OUT(base, DP_RBCH, pkt_len >> 8);
DP_OUT(base, DP_CR, DP_CR_WDMA | DP_CR_START);
/* Put data into buffer */
#if DEBUG & 4
printf(" sg buf %08lx len %08x\n ", (unsigned long) data, len);
dx = 0;
#endif
while (len > 0) {
#if DEBUG & 4
printf(" %02x", *data);
if (0 == (++dx % 16)) printf("\n ");
#endif
DP_OUT_DATA(dp->data, *data++);
len--;
}
#if DEBUG & 4
printf("\n");
#endif
if (total_len < pkt_len) {
#if DEBUG & 4
printf(" + %d bytes of padding\n", pkt_len - total_len);
#endif
/* Padding to 802.3 length was required */
for (i = total_len; i < pkt_len;) {
i++;
DP_OUT_DATA(dp->data, 0);
}
}
#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA
/* After last data write, delay for a bit before accessing the */
/* device again, or we may get random data corruption in the last */
/* datum (on some platforms). */
CYGACC_CALL_IF_DELAY_US(1);
#endif
/* Wait for DMA to complete */
do {
DP_IN(base, DP_ISR, isr);
} while ((isr & DP_ISR_RDC) == 0);
/* Then disable DMA */
DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
/* Start transmit if not already going */
if (!dp->tx_started) {
if (start_page == dp->tx1) {
dp->tx_int = 1; /* Expecting interrupt from BUF1 */
} else {
dp->tx_int = 2; /* Expecting interrupt from BUF2 */
}
dp83902a_start_xmit(start_page, pkt_len);
}
}
/*
This function is called when a packet has been received. It's job is
to prepare to unload the packet from the hardware. Once the length of
the packet is known, the upper layer of the driver can be told. When
the upper layer is ready to unload the packet, the internal function
'dp83902a_recv' will be called to actually fetch it from the hardware.
*/
static void
dp83902a_RxEvent(void)
{
struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
cyg_uint8 *base = dp->base;
unsigned char rsr;
unsigned char rcv_hdr[4];
int i, len, pkt, cur;
DEBUG_FUNCTION();
DP_IN(base, DP_RSR, rsr);
while (true) {
/* Read incoming packet header */
DP_OUT(base, DP_CR, DP_CR_PAGE1 | DP_CR_NODMA | DP_CR_START);
DP_IN(base, DP_P1_CURP, cur);
DP_OUT(base, DP_P1_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
DP_IN(base, DP_BNDRY, pkt);
pkt += 1;
if (pkt == dp->rx_buf_end)
pkt = dp->rx_buf_start;
if (pkt == cur) {
break;
}
DP_OUT(base, DP_RBCL, sizeof(rcv_hdr));
DP_OUT(base, DP_RBCH, 0);
DP_OUT(base, DP_RSAL, 0);
DP_OUT(base, DP_RSAH, pkt);
if (dp->rx_next == pkt) {
if (cur == dp->rx_buf_start)
DP_OUT(base, DP_BNDRY, dp->rx_buf_end-1);
else
DP_OUT(base, DP_BNDRY, cur-1); /* Update pointer */
return;
}
dp->rx_next = pkt;
DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */
DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START);
#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA
CYGACC_CALL_IF_DELAY_US(10);
#endif
for (i = 0; i < sizeof(rcv_hdr);) {
DP_IN_DATA(dp->data, rcv_hdr[i++]);
}
#if DEBUG & 5
printf("rx hdr %02x %02x %02x %02x\n",
rcv_hdr[0], rcv_hdr[1], rcv_hdr[2], rcv_hdr[3]);
#endif
len = ((rcv_hdr[3] << 8) | rcv_hdr[2]) - sizeof(rcv_hdr);
uboot_push_packet_len(len);
if (rcv_hdr[1] == dp->rx_buf_start)
DP_OUT(base, DP_BNDRY, dp->rx_buf_end-1);
else
DP_OUT(base, DP_BNDRY, rcv_hdr[1]-1); /* Update pointer */
}
}
/*
This function is called as a result of the "eth_drv_recv()" call above.
It's job is to actually fetch data for a packet from the hardware once
memory buffers have been allocated for the packet. Note that the buffers
may come in pieces, using a scatter-gather list. This allows for more
efficient processing in the upper layers of the stack.
*/
static void
dp83902a_recv(unsigned char *data, int len)
{
struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
cyg_uint8 *base = dp->base;
int i, mlen;
cyg_uint8 saved_char = 0;
bool saved;
#if DEBUG & 4
int dx;
#endif
DEBUG_FUNCTION();
#if DEBUG & 5
printf("Rx packet %d length %d\n", dp->rx_next, len);
#endif
/* Read incoming packet data */
DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
DP_OUT(base, DP_RBCL, len & 0xFF);
DP_OUT(base, DP_RBCH, len >> 8);
DP_OUT(base, DP_RSAL, 4); /* Past header */
DP_OUT(base, DP_RSAH, dp->rx_next);
DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */
DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START);
#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA
CYGACC_CALL_IF_DELAY_US(10);
#endif
saved = false;
for (i = 0; i < 1; i++) {
if (data) {
mlen = len;
#if DEBUG & 4
printf(" sg buf %08lx len %08x \n", (unsigned long) data, mlen);
dx = 0;
#endif
while (0 < mlen) {
/* Saved byte from previous loop? */
if (saved) {
*data++ = saved_char;
mlen--;
saved = false;
continue;
}
{
cyg_uint8 tmp;
DP_IN_DATA(dp->data, tmp);
#if DEBUG & 4
printf(" %02x", tmp);
if (0 == (++dx % 16)) printf("\n ");
#endif
*data++ = tmp;;
mlen--;
}
}
#if DEBUG & 4
printf("\n");
#endif
}
}
}
static void
dp83902a_TxEvent(void)
{
struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
cyg_uint8 *base = dp->base;
unsigned char tsr;
unsigned long key;
DEBUG_FUNCTION();
DP_IN(base, DP_TSR, tsr);
if (dp->tx_int == 1) {
key = dp->tx1_key;
dp->tx1 = 0;
} else {
key = dp->tx2_key;
dp->tx2 = 0;
}
/* Start next packet if one is ready */
dp->tx_started = false;
if (dp->tx1) {
dp83902a_start_xmit(dp->tx1, dp->tx1_len);
dp->tx_int = 1;
} else if (dp->tx2) {
dp83902a_start_xmit(dp->tx2, dp->tx2_len);
dp->tx_int = 2;
} else {
dp->tx_int = 0;
}
/* Tell higher level we sent this packet */
uboot_push_tx_done(key, 0);
}
/* Read the tally counters to clear them. Called in response to a CNT */
/* interrupt. */
static void
dp83902a_ClearCounters(void)
{
struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
cyg_uint8 *base = dp->base;
cyg_uint8 cnt1, cnt2, cnt3;
DP_IN(base, DP_FER, cnt1);
DP_IN(base, DP_CER, cnt2);
DP_IN(base, DP_MISSED, cnt3);
DP_OUT(base, DP_ISR, DP_ISR_CNT);
}
/* Deal with an overflow condition. This code follows the procedure set */
/* out in section 7.0 of the datasheet. */
static void
dp83902a_Overflow(void)
{
struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *)&nic;
cyg_uint8 *base = dp->base;
cyg_uint8 isr;
/* Issue a stop command and wait 1.6ms for it to complete. */
DP_OUT(base, DP_CR, DP_CR_STOP | DP_CR_NODMA);
CYGACC_CALL_IF_DELAY_US(1600);
/* Clear the remote byte counter registers. */
DP_OUT(base, DP_RBCL, 0);
DP_OUT(base, DP_RBCH, 0);
/* Enter loopback mode while we clear the buffer. */
DP_OUT(base, DP_TCR, DP_TCR_LOCAL);
DP_OUT(base, DP_CR, DP_CR_START | DP_CR_NODMA);
/* Read in as many packets as we can and acknowledge any and receive */
/* interrupts. Since the buffer has overflowed, a receive event of */
/* some kind will have occured. */
dp83902a_RxEvent();
DP_OUT(base, DP_ISR, DP_ISR_RxP|DP_ISR_RxE);
/* Clear the overflow condition and leave loopback mode. */
DP_OUT(base, DP_ISR, DP_ISR_OFLW);
DP_OUT(base, DP_TCR, DP_TCR_NORMAL);
/* If a transmit command was issued, but no transmit event has occured, */
/* restart it here. */
DP_IN(base, DP_ISR, isr);
if (dp->tx_started && !(isr & (DP_ISR_TxP|DP_ISR_TxE))) {
DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_TXPKT | DP_CR_START);
}
}
static void
dp83902a_poll(void)
{
struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
cyg_uint8 *base = dp->base;
unsigned char isr;
DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0 | DP_CR_START);
DP_IN(base, DP_ISR, isr);
while (0 != isr) {
/* The CNT interrupt triggers when the MSB of one of the error */
/* counters is set. We don't much care about these counters, but */
/* we should read their values to reset them. */
if (isr & DP_ISR_CNT) {
dp83902a_ClearCounters();
}
/* Check for overflow. It's a special case, since there's a */
/* particular procedure that must be followed to get back into */
/* a running state.a */
if (isr & DP_ISR_OFLW) {
dp83902a_Overflow();
} else {
/* Other kinds of interrupts can be acknowledged simply by */
/* clearing the relevant bits of the ISR. Do that now, then */
/* handle the interrupts we care about. */
DP_OUT(base, DP_ISR, isr); /* Clear set bits */
if (!dp->running) break; /* Is this necessary? */
/* Check for tx_started on TX event since these may happen */
/* spuriously it seems. */
if (isr & (DP_ISR_TxP|DP_ISR_TxE) && dp->tx_started) {
dp83902a_TxEvent();
}
if (isr & (DP_ISR_RxP|DP_ISR_RxE)) {
dp83902a_RxEvent();
}
}
DP_IN(base, DP_ISR, isr);
}
}
/* find prom (taken from pc_net_cs.c from Linux) */
#include "8390.h"
typedef struct hw_info_t {
u_int offset;
u_char a0, a1, a2;
u_int flags;
} hw_info_t;
#define DELAY_OUTPUT 0x01
#define HAS_MISC_REG 0x02
#define USE_BIG_BUF 0x04
#define HAS_IBM_MISC 0x08
#define IS_DL10019 0x10
#define IS_DL10022 0x20
#define HAS_MII 0x40
#define USE_SHMEM 0x80 /* autodetected */
#define AM79C9XX_HOME_PHY 0x00006B90 /* HomePNA PHY */
#define AM79C9XX_ETH_PHY 0x00006B70 /* 10baseT PHY */
#define MII_PHYID_REV_MASK 0xfffffff0
#define MII_PHYID_REG1 0x02
#define MII_PHYID_REG2 0x03
static hw_info_t hw_info[] = {
{ /* Accton EN2212 */ 0x0ff0, 0x00, 0x00, 0xe8, DELAY_OUTPUT },
{ /* Allied Telesis LA-PCM */ 0x0ff0, 0x00, 0x00, 0xf4, 0 },
{ /* APEX MultiCard */ 0x03f4, 0x00, 0x20, 0xe5, 0 },
{ /* ASANTE FriendlyNet */ 0x4910, 0x00, 0x00, 0x94,
DELAY_OUTPUT | HAS_IBM_MISC },
{ /* Danpex EN-6200P2 */ 0x0110, 0x00, 0x40, 0xc7, 0 },
{ /* DataTrek NetCard */ 0x0ff0, 0x00, 0x20, 0xe8, 0 },
{ /* Dayna CommuniCard E */ 0x0110, 0x00, 0x80, 0x19, 0 },
{ /* D-Link DE-650 */ 0x0040, 0x00, 0x80, 0xc8, 0 },
{ /* EP-210 Ethernet */ 0x0110, 0x00, 0x40, 0x33, 0 },
{ /* EP4000 Ethernet */ 0x01c0, 0x00, 0x00, 0xb4, 0 },
{ /* Epson EEN10B */ 0x0ff0, 0x00, 0x00, 0x48,
HAS_MISC_REG | HAS_IBM_MISC },
{ /* ELECOM Laneed LD-CDWA */ 0xb8, 0x08, 0x00, 0x42, 0 },
{ /* Hypertec Ethernet */ 0x01c0, 0x00, 0x40, 0x4c, 0 },
{ /* IBM CCAE */ 0x0ff0, 0x08, 0x00, 0x5a,
HAS_MISC_REG | HAS_IBM_MISC },
{ /* IBM CCAE */ 0x0ff0, 0x00, 0x04, 0xac,
HAS_MISC_REG | HAS_IBM_MISC },
{ /* IBM CCAE */ 0x0ff0, 0x00, 0x06, 0x29,
HAS_MISC_REG | HAS_IBM_MISC },
{ /* IBM FME */ 0x0374, 0x08, 0x00, 0x5a,
HAS_MISC_REG | HAS_IBM_MISC },
{ /* IBM FME */ 0x0374, 0x00, 0x04, 0xac,
HAS_MISC_REG | HAS_IBM_MISC },
{ /* Kansai KLA-PCM/T */ 0x0ff0, 0x00, 0x60, 0x87,
HAS_MISC_REG | HAS_IBM_MISC },
{ /* NSC DP83903 */ 0x0374, 0x08, 0x00, 0x17,
HAS_MISC_REG | HAS_IBM_MISC },
{ /* NSC DP83903 */ 0x0374, 0x00, 0xc0, 0xa8,
HAS_MISC_REG | HAS_IBM_MISC },
{ /* NSC DP83903 */ 0x0374, 0x00, 0xa0, 0xb0,
HAS_MISC_REG | HAS_IBM_MISC },
{ /* NSC DP83903 */ 0x0198, 0x00, 0x20, 0xe0,
HAS_MISC_REG | HAS_IBM_MISC },
{ /* I-O DATA PCLA/T */ 0x0ff0, 0x00, 0xa0, 0xb0, 0 },
{ /* Katron PE-520 */ 0x0110, 0x00, 0x40, 0xf6, 0 },
{ /* Kingston KNE-PCM/x */ 0x0ff0, 0x00, 0xc0, 0xf0,
HAS_MISC_REG | HAS_IBM_MISC },
{ /* Kingston KNE-PCM/x */ 0x0ff0, 0xe2, 0x0c, 0x0f,
HAS_MISC_REG | HAS_IBM_MISC },
{ /* Kingston KNE-PC2 */ 0x0180, 0x00, 0xc0, 0xf0, 0 },
{ /* Maxtech PCN2000 */ 0x5000, 0x00, 0x00, 0xe8, 0 },
{ /* NDC Instant-Link */ 0x003a, 0x00, 0x80, 0xc6, 0 },
{ /* NE2000 Compatible */ 0x0ff0, 0x00, 0xa0, 0x0c, 0 },
{ /* Network General Sniffer */ 0x0ff0, 0x00, 0x00, 0x65,
HAS_MISC_REG | HAS_IBM_MISC },
{ /* Panasonic VEL211 */ 0x0ff0, 0x00, 0x80, 0x45,
HAS_MISC_REG | HAS_IBM_MISC },
{ /* PreMax PE-200 */ 0x07f0, 0x00, 0x20, 0xe0, 0 },
{ /* RPTI EP400 */ 0x0110, 0x00, 0x40, 0x95, 0 },
{ /* SCM Ethernet */ 0x0ff0, 0x00, 0x20, 0xcb, 0 },
{ /* Socket EA */ 0x4000, 0x00, 0xc0, 0x1b,
DELAY_OUTPUT | HAS_MISC_REG | USE_BIG_BUF },
{ /* Socket LP-E CF+ */ 0x01c0, 0x00, 0xc0, 0x1b, 0 },
{ /* SuperSocket RE450T */ 0x0110, 0x00, 0xe0, 0x98, 0 },
{ /* Volktek NPL-402CT */ 0x0060, 0x00, 0x40, 0x05, 0 },
{ /* NEC PC-9801N-J12 */ 0x0ff0, 0x00, 0x00, 0x4c, 0 },
{ /* PCMCIA Technology OEM */ 0x01c8, 0x00, 0xa0, 0x0c, 0 }
};
#define NR_INFO (sizeof(hw_info)/sizeof(hw_info_t))
static hw_info_t default_info = { 0, 0, 0, 0, 0 };
unsigned char dev_addr[6];
#define PCNET_CMD 0x00
#define PCNET_DATAPORT 0x10 /* NatSemi-defined port window offset. */
#define PCNET_RESET 0x1f /* Issue a read to reset, a write to clear. */
#define PCNET_MISC 0x18 /* For IBM CCAE and Socket EA cards */
unsigned long nic_base;
static void pcnet_reset_8390(void)
{
int i, r;
PRINTK("nic base is %lx\n", nic_base);
#if 1
n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD);
PRINTK("cmd (at %lx) is %x\n", nic_base+ E8390_CMD, n2k_inb(E8390_CMD));
n2k_outb(E8390_NODMA+E8390_PAGE1+E8390_STOP, E8390_CMD);
PRINTK("cmd (at %lx) is %x\n", nic_base+ E8390_CMD, n2k_inb(E8390_CMD));
n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD);
PRINTK("cmd (at %lx) is %x\n", nic_base+ E8390_CMD, n2k_inb(E8390_CMD));
#endif
n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD);
n2k_outb(n2k_inb(nic_base + PCNET_RESET), PCNET_RESET);
for (i = 0; i < 100; i++) {
if ((r = (n2k_inb(EN0_ISR) & ENISR_RESET)) != 0)
break;
PRINTK("got %x in reset\n", r);
my_udelay(100);
}
n2k_outb(ENISR_RESET, EN0_ISR); /* Ack intr. */
if (i == 100)
printf("pcnet_reset_8390() did not complete.\n");
} /* pcnet_reset_8390 */
static hw_info_t * get_prom(void ) {
unsigned char prom[32];
int i, j;
struct {
u_char value, offset;
} program_seq[] = {
{E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/
{0x48, EN0_DCFG}, /* Set byte-wide (0x48) access. */
{0x00, EN0_RCNTLO}, /* Clear the count regs. */
{0x00, EN0_RCNTHI},
{0x00, EN0_IMR}, /* Mask completion irq. */
{0xFF, EN0_ISR},
{E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */
{E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */
{32, EN0_RCNTLO},
{0x00, EN0_RCNTHI},
{0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */
{0x00, EN0_RSARHI},
{E8390_RREAD+E8390_START, E8390_CMD},
};
PRINTK("trying to get MAC via prom reading\n");
pcnet_reset_8390();
mdelay(10);
for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++)
n2k_outb(program_seq[i].value, program_seq[i].offset);
PRINTK("PROM:");
for (i = 0; i < 32; i++) {
prom[i] = n2k_inb(PCNET_DATAPORT);
PRINTK(" %02x", prom[i]);
}
PRINTK("\n");
for (i = 0; i < NR_INFO; i++) {
if ((prom[0] == hw_info[i].a0) &&
(prom[2] == hw_info[i].a1) &&
(prom[4] == hw_info[i].a2)) {
PRINTK("matched board %d\n", i);
break;
}
}
if ((i < NR_INFO) || ((prom[28] == 0x57) && (prom[30] == 0x57))) {
for (j = 0; j < 6; j++)
dev_addr[j] = prom[j<<1];
PRINTK("on exit i is %d/%ld\n", i, NR_INFO);
PRINTK("MAC address is %02x:%02x:%02x:%02x:%02x:%02x\n",
dev_addr[0],dev_addr[1],dev_addr[2],dev_addr[3],dev_addr[4],dev_addr[5]);
return (i < NR_INFO) ? hw_info+i : &default_info;
}
return NULL;
}
/* U-boot specific routines */
#define NB 5
static unsigned char *pbuf = NULL;
static int plen[NB];
static int nrx = 0;
static int pkey = -1;
void uboot_push_packet_len(int len) {
PRINTK("pushed len = %d, nrx = %d\n", len, nrx);
if (len>=2000) {
printf("NE2000: packet too big\n");
return;
}
if (nrx >= NB) {
printf("losing packets in rx\n");
return;
}
plen[nrx] = len;
dp83902a_recv(&pbuf[nrx*2000], len);
nrx++;
}
void uboot_push_tx_done(int key, int val) {
PRINTK("pushed key = %d\n", key);
pkey = key;
}
int eth_init(bd_t *bd) {
static hw_info_t * r;
char ethaddr[20];
PRINTK("### eth_init\n");
if (!pbuf) {
pbuf = malloc(NB*2000);
if (!pbuf) {
printf("Cannot allocate rx buffers\n");
return -1;
}
}
#ifdef CONFIG_DRIVER_NE2000_CCR
{
volatile unsigned char *p = (volatile unsigned char *) CONFIG_DRIVER_NE2000_CCR;
PRINTK("CCR before is %x\n", *p);
*p = CONFIG_DRIVER_NE2000_VAL;
PRINTK("CCR after is %x\n", *p);
}
#endif
nic_base = CONFIG_DRIVER_NE2000_BASE;
nic.base = (cyg_uint8 *) CONFIG_DRIVER_NE2000_BASE;
r = get_prom();
if (!r)
return -1;
sprintf (ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X",
dev_addr[0], dev_addr[1],
dev_addr[2], dev_addr[3],
dev_addr[4], dev_addr[5]) ;
PRINTK("Set environment from HW MAC addr = \"%s\"\n", ethaddr);
setenv ("ethaddr", ethaddr);
#define DP_DATA 0x10
nic.data = nic.base + DP_DATA;
nic.tx_buf1 = 0x40;
nic.tx_buf2 = 0x48;
nic.rx_buf_start = 0x50;
nic.rx_buf_end = 0x80;
if (dp83902a_init() == false)
return -1;
dp83902a_start(dev_addr);
return 0;
}
void eth_halt() {
PRINTK("### eth_halt\n");
dp83902a_stop();
}
int eth_rx() {
int j, tmo;
PRINTK("### eth_rx\n");
tmo = get_timer (0) + TOUT * CFG_HZ;
while(1) {
dp83902a_poll();
if (nrx > 0) {
for(j=0; j<nrx; j++) {
NetReceive(&pbuf[j*2000], plen[j]);
}
nrx = 0;
return 1;
}
if (get_timer (0) >= tmo) {
printf("timeout during rx\n");
return 0;
}
}
return 0;
}
int eth_send(volatile void *packet, int length) {
int tmo;
PRINTK("### eth_send\n");
pkey = -1;
dp83902a_send((unsigned char *) packet, length, 666);
tmo = get_timer (0) + TOUT * CFG_HZ;
while(1) {
dp83902a_poll();
if (pkey != -1) {
PRINTK("Packet sucesfully sent\n");
return 0;
}
if (get_timer (0) >= tmo) {
printf("transmission error (timoeut)\n");
return 0;
}
}
return 0;
}
#endif

279
drivers/ne2000.h Normal file
View file

@ -0,0 +1,279 @@
/*
Ported to U-Boot by Christian Pellegrin <chri@ascensit.com>
Based on sources from the Linux kernel (pcnet_cs.c, 8390.h) and
eCOS(if_dp83902a.c, if_dp83902a.h). Both of these 2 wonderful world
are GPL, so this is, of course, GPL.
==========================================================================
dev/dp83902a.h
National Semiconductor DP83902a ethernet chip
==========================================================================
####ECOSGPLCOPYRIGHTBEGIN####
-------------------------------------------
This file is part of eCos, the Embedded Configurable Operating System.
Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
eCos 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 or (at your option) any later version.
eCos 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 eCos; if not, write to the Free Software Foundation, Inc.,
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
As a special exception, if other files instantiate templates or use macros
or inline functions from this file, or you compile this file and link it
with other works to produce a work based on this file, this file does not
by itself cause the resulting work to be covered by the GNU General Public
License. However the source code for this file must still be made available
in accordance with section (3) of the GNU General Public License.
This exception does not invalidate any other reasons why a work based on
this file might be covered by the GNU General Public License.
Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
at http://sources.redhat.com/ecos/ecos-license/ */
-------------------------------------------
####ECOSGPLCOPYRIGHTEND####
####BSDCOPYRIGHTBEGIN####
-------------------------------------------
Portions of this software may have been derived from OpenBSD or other sources,
and are covered by the appropriate copyright disclaimers included herein.
-------------------------------------------
####BSDCOPYRIGHTEND####
==========================================================================
#####DESCRIPTIONBEGIN####
Author(s): gthomas
Contributors: gthomas, jskov
Date: 2001-06-13
Purpose:
Description:
####DESCRIPTIONEND####
==========================================================================
*/
/*
------------------------------------------------------------------------
Macros for accessing DP registers
These can be overridden by the platform header
*/
#define DP_IN(_b_, _o_, _d_) (_d_) = *( (volatile unsigned char *) ((_b_)+(_o_)))
#define DP_OUT(_b_, _o_, _d_) *( (volatile unsigned char *) ((_b_)+(_o_))) = (_d_)
#define DP_IN_DATA(_b_, _d_) (_d_) = *( (volatile unsigned char *) ((_b_)))
#define DP_OUT_DATA(_b_, _d_) *( (volatile unsigned char *) ((_b_))) = (_d_)
/* here is all the data */
#define cyg_uint8 unsigned char
#define cyg_uint16 unsigned short
#define bool int
#define false 0
#define true 1
#define CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA 1
#define CYGACC_CALL_IF_DELAY_US(X) my_udelay(X)
typedef struct dp83902a_priv_data {
cyg_uint8* base;
cyg_uint8* data;
cyg_uint8* reset;
int tx_next; /* First free Tx page */
int tx_int; /* Expecting interrupt from this buffer */
int rx_next; /* First free Rx page */
int tx1, tx2; /* Page numbers for Tx buffers */
unsigned long tx1_key, tx2_key; /* Used to ack when packet sent */
int tx1_len, tx2_len;
bool tx_started, running, hardwired_esa;
cyg_uint8 esa[6];
void* plf_priv;
/* Buffer allocation */
int tx_buf1, tx_buf2;
int rx_buf_start, rx_buf_end;
} dp83902a_priv_data_t;
/*
------------------------------------------------------------------------
Some forward declarations
*/
static void dp83902a_poll(void);
/* ------------------------------------------------------------------------ */
/* Register offsets */
#define DP_CR 0x00
#define DP_CLDA0 0x01
#define DP_PSTART 0x01 /* write */
#define DP_CLDA1 0x02
#define DP_PSTOP 0x02 /* write */
#define DP_BNDRY 0x03
#define DP_TSR 0x04
#define DP_TPSR 0x04 /* write */
#define DP_NCR 0x05
#define DP_TBCL 0x05 /* write */
#define DP_FIFO 0x06
#define DP_TBCH 0x06 /* write */
#define DP_ISR 0x07
#define DP_CRDA0 0x08
#define DP_RSAL 0x08 /* write */
#define DP_CRDA1 0x09
#define DP_RSAH 0x09 /* write */
#define DP_RBCL 0x0a /* write */
#define DP_RBCH 0x0b /* write */
#define DP_RSR 0x0c
#define DP_RCR 0x0c /* write */
#define DP_FER 0x0d
#define DP_TCR 0x0d /* write */
#define DP_CER 0x0e
#define DP_DCR 0x0e /* write */
#define DP_MISSED 0x0f
#define DP_IMR 0x0f /* write */
#define DP_DATAPORT 0x10 /* "eprom" data port */
#define DP_P1_CR 0x00
#define DP_P1_PAR0 0x01
#define DP_P1_PAR1 0x02
#define DP_P1_PAR2 0x03
#define DP_P1_PAR3 0x04
#define DP_P1_PAR4 0x05
#define DP_P1_PAR5 0x06
#define DP_P1_CURP 0x07
#define DP_P1_MAR0 0x08
#define DP_P1_MAR1 0x09
#define DP_P1_MAR2 0x0a
#define DP_P1_MAR3 0x0b
#define DP_P1_MAR4 0x0c
#define DP_P1_MAR5 0x0d
#define DP_P1_MAR6 0x0e
#define DP_P1_MAR7 0x0f
#define DP_P2_CR 0x00
#define DP_P2_PSTART 0x01
#define DP_P2_CLDA0 0x01 /* write */
#define DP_P2_PSTOP 0x02
#define DP_P2_CLDA1 0x02 /* write */
#define DP_P2_RNPP 0x03
#define DP_P2_TPSR 0x04
#define DP_P2_LNPP 0x05
#define DP_P2_ACH 0x06
#define DP_P2_ACL 0x07
#define DP_P2_RCR 0x0c
#define DP_P2_TCR 0x0d
#define DP_P2_DCR 0x0e
#define DP_P2_IMR 0x0f
/* Command register - common to all pages */
#define DP_CR_STOP 0x01 /* Stop: software reset */
#define DP_CR_START 0x02 /* Start: initialize device */
#define DP_CR_TXPKT 0x04 /* Transmit packet */
#define DP_CR_RDMA 0x08 /* Read DMA (recv data from device) */
#define DP_CR_WDMA 0x10 /* Write DMA (send data to device) */
#define DP_CR_SEND 0x18 /* Send packet */
#define DP_CR_NODMA 0x20 /* Remote (or no) DMA */
#define DP_CR_PAGE0 0x00 /* Page select */
#define DP_CR_PAGE1 0x40
#define DP_CR_PAGE2 0x80
#define DP_CR_PAGEMSK 0x3F /* Used to mask out page bits */
/* Data configuration register */
#define DP_DCR_WTS 0x01 /* 1=16 bit word transfers */
#define DP_DCR_BOS 0x02 /* 1=Little Endian */
#define DP_DCR_LAS 0x04 /* 1=Single 32 bit DMA mode */
#define DP_DCR_LS 0x08 /* 1=normal mode, 0=loopback */
#define DP_DCR_ARM 0x10 /* 0=no send command (program I/O) */
#define DP_DCR_FIFO_1 0x00 /* FIFO threshold */
#define DP_DCR_FIFO_2 0x20
#define DP_DCR_FIFO_4 0x40
#define DP_DCR_FIFO_6 0x60
#define DP_DCR_INIT (DP_DCR_LS|DP_DCR_FIFO_4)
/* Interrupt status register */
#define DP_ISR_RxP 0x01 /* Packet received */
#define DP_ISR_TxP 0x02 /* Packet transmitted */
#define DP_ISR_RxE 0x04 /* Receive error */
#define DP_ISR_TxE 0x08 /* Transmit error */
#define DP_ISR_OFLW 0x10 /* Receive overflow */
#define DP_ISR_CNT 0x20 /* Tally counters need emptying */
#define DP_ISR_RDC 0x40 /* Remote DMA complete */
#define DP_ISR_RESET 0x80 /* Device has reset (shutdown, error) */
/* Interrupt mask register */
#define DP_IMR_RxP 0x01 /* Packet received */
#define DP_IMR_TxP 0x02 /* Packet transmitted */
#define DP_IMR_RxE 0x04 /* Receive error */
#define DP_IMR_TxE 0x08 /* Transmit error */
#define DP_IMR_OFLW 0x10 /* Receive overflow */
#define DP_IMR_CNT 0x20 /* Tall counters need emptying */
#define DP_IMR_RDC 0x40 /* Remote DMA complete */
#define DP_IMR_All 0x3F /* Everything but remote DMA */
/* Receiver control register */
#define DP_RCR_SEP 0x01 /* Save bad(error) packets */
#define DP_RCR_AR 0x02 /* Accept runt packets */
#define DP_RCR_AB 0x04 /* Accept broadcast packets */
#define DP_RCR_AM 0x08 /* Accept multicast packets */
#define DP_RCR_PROM 0x10 /* Promiscuous mode */
#define DP_RCR_MON 0x20 /* Monitor mode - 1=accept no packets */
/* Receiver status register */
#define DP_RSR_RxP 0x01 /* Packet received */
#define DP_RSR_CRC 0x02 /* CRC error */
#define DP_RSR_FRAME 0x04 /* Framing error */
#define DP_RSR_FO 0x08 /* FIFO overrun */
#define DP_RSR_MISS 0x10 /* Missed packet */
#define DP_RSR_PHY 0x20 /* 0=pad match, 1=mad match */
#define DP_RSR_DIS 0x40 /* Receiver disabled */
#define DP_RSR_DFR 0x80 /* Receiver processing deferred */
/* Transmitter control register */
#define DP_TCR_NOCRC 0x01 /* 1=inhibit CRC */
#define DP_TCR_NORMAL 0x00 /* Normal transmitter operation */
#define DP_TCR_LOCAL 0x02 /* Internal NIC loopback */
#define DP_TCR_INLOOP 0x04 /* Full internal loopback */
#define DP_TCR_OUTLOOP 0x08 /* External loopback */
#define DP_TCR_ATD 0x10 /* Auto transmit disable */
#define DP_TCR_OFFSET 0x20 /* Collision offset adjust */
/* Transmit status register */
#define DP_TSR_TxP 0x01 /* Packet transmitted */
#define DP_TSR_COL 0x04 /* Collision (at least one) */
#define DP_TSR_ABT 0x08 /* Aborted because of too many collisions */
#define DP_TSR_CRS 0x10 /* Lost carrier */
#define DP_TSR_FU 0x20 /* FIFO underrun */
#define DP_TSR_CDH 0x40 /* Collision Detect Heartbeat */
#define DP_TSR_OWC 0x80 /* Collision outside normal window */
#define IEEE_8023_MAX_FRAME 1518 /* Largest possible ethernet frame */
#define IEEE_8023_MIN_FRAME 64 /* Smallest possible ethernet frame */

View file

@ -17,7 +17,7 @@
void NS16550_init (NS16550_t com_port, int baud_divisor)
{
com_port->ier = 0x00;
#ifdef CONFIG_OMAP1510
#ifdef CONFIG_OMAP
com_port->mdr1 = 0x7; /* mode select reset TL16C750*/
#endif
com_port->lcr = LCR_BKSE | LCRVAL;
@ -26,8 +26,12 @@ void NS16550_init (NS16550_t com_port, int baud_divisor)
com_port->lcr = LCRVAL;
com_port->mcr = MCRVAL;
com_port->fcr = FCRVAL;
#if defined(CONFIG_OMAP1510) || defined(CONFIG_OMAP1610) || defined(CONFIG_OMAP730)
com_port->mdr1 = 0; /* select uart mode */
#if defined(CONFIG_OMAP)
#if defined(CONFIG_APTIX)
com_port->mdr1 = 3; /* /13 mode so Aptix 6MHz can hit 115200 */
#else
com_port->mdr1 = 0; /* /16 is proper to hit 115200 with 48MHz */
#endif
#endif
}

317
drivers/omap24xx_i2c.c Normal file
View file

@ -0,0 +1,317 @@
/*
* Basic I2C functions
*
* Copyright (c) 2004 Texas Instruments
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the license found in the file
* named COPYING that should have accompanied this file.
*
* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* Author: Jian Zhang jzhang@ti.com, Texas Instruments
*
* Copyright (c) 2003 Wolfgang Denk, wd@denx.de
* Rewritten to fit into the current U-Boot framework
*
* Adapted for OMAP2420 I2C, r-woodruff2@ti.com
*
*/
#include <common.h>
#include <asm/arch/i2c.h>
#include <asm/io.h>
#define inw(a) __raw_readw(a)
#define outw(a,v) __raw_writew(a,v)
#ifdef CONFIG_DRIVER_OMAP24XX_I2C
static void wait_for_bb (void);
static u16 wait_for_pin (void);
void flush_fifo(void);
void i2c_init (int speed, int slaveadd)
{
u16 scl;
if (inw (I2C_CON) & I2C_CON_EN) {
outw (0, I2C_CON);
udelay (50000);
}
/* 12Mhz I2C module clock */
outw (0, I2C_PSC);
speed = speed/1000; /* 100 or 400 */
scl = ((12000/(speed*2)) - 7); /* use 7 when PSC = 0 */
outw (scl, I2C_SCLL);
outw (scl, I2C_SCLH);
/* own address */
outw (slaveadd, I2C_OA);
outw (I2C_CON_EN, I2C_CON);
outw (0, I2C_CNT);
/* have to enable intrrupts or OMAP i2c module doesn't work */
outw (I2C_IE_XRDY_IE | I2C_IE_RRDY_IE | I2C_IE_ARDY_IE |
I2C_IE_NACK_IE | I2C_IE_AL_IE, I2C_IE);
udelay (1000);
}
static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value)
{
int i2c_error = 0;
u16 status;
/* wait until bus not busy */
wait_for_bb ();
/* one byte only */
outw (1, I2C_CNT);
/* set slave address */
outw (devaddr, I2C_SA);
/* no stop bit needed here */
outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX, I2C_CON);
status = wait_for_pin ();
if (status & I2C_STAT_XRDY) {
/* Important: have to use byte access */
*(volatile u8 *) (I2C_DATA) = regoffset;
udelay (20000);
if (inw (I2C_STAT) & I2C_STAT_NACK) {
i2c_error = 1;
}
} else {
i2c_error = 1;
}
if (!i2c_error) {
/* free bus, otherwise we can't use a combined transction */
outw (0, I2C_CON);
while (inw (I2C_STAT) || (inw (I2C_CON) & I2C_CON_MST)) {
udelay (10000);
/* Have to clear pending interrupt to clear I2C_STAT */
outw (0xFFFF, I2C_STAT);
}
wait_for_bb ();
/* set slave address */
outw (devaddr, I2C_SA);
/* read one byte from slave */
outw (1, I2C_CNT);
/* need stop bit here */
outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP,
I2C_CON);
status = wait_for_pin ();
if (status & I2C_STAT_RRDY) {
*value = inw (I2C_DATA);
udelay (20000);
} else {
i2c_error = 1;
}
if (!i2c_error) {
outw (I2C_CON_EN, I2C_CON);
while (inw (I2C_STAT)
|| (inw (I2C_CON) & I2C_CON_MST)) {
udelay (10000);
outw (0xFFFF, I2C_STAT);
}
}
}
flush_fifo();
outw (0xFFFF, I2C_STAT);
outw (0, I2C_CNT);
return i2c_error;
}
static int i2c_write_byte (u8 devaddr, u8 regoffset, u8 value)
{
int i2c_error = 0;
u16 status, stat;
/* wait until bus not busy */
wait_for_bb ();
/* two bytes */
outw (2, I2C_CNT);
/* set slave address */
outw (devaddr, I2C_SA);
/* stop bit needed here */
outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX |
I2C_CON_STP, I2C_CON);
/* wait until state change */
status = wait_for_pin ();
if (status & I2C_STAT_XRDY) {
/* send out two bytes */
outw ((value << 8) + regoffset, I2C_DATA);
/* must have enough delay to allow BB bit to go low */
udelay (50000);
if (inw (I2C_STAT) & I2C_STAT_NACK) {
i2c_error = 1;
}
} else {
i2c_error = 1;
}
if (!i2c_error) {
outw (I2C_CON_EN, I2C_CON);
while ((stat = inw (I2C_STAT)) || (inw (I2C_CON) & I2C_CON_MST)) {
udelay (1000);
/* have to read to clear intrrupt */
outw (0xFFFF, I2C_STAT);
}
}
flush_fifo();
outw (0xFFFF, I2C_STAT);
outw (0, I2C_CNT);
return i2c_error;
}
void flush_fifo(void)
{ u16 stat;
/* note: if you try and read data when its not there or ready
* you get a bus error
*/
while(1){
stat = inw(I2C_STAT);
if(stat == I2C_STAT_RRDY){
inw(I2C_DATA);
outw(I2C_STAT_RRDY,I2C_STAT);
udelay(1000);
}else
break;
}
}
int i2c_probe (uchar chip)
{
int res = 1; /* default = fail */
if (chip == inw (I2C_OA)) {
return res;
}
/* wait until bus not busy */
wait_for_bb ();
/* try to read one byte */
outw (1, I2C_CNT);
/* set slave address */
outw (chip, I2C_SA);
/* stop bit needed here */
outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP, I2C_CON);
/* enough delay for the NACK bit set */
udelay (50000);
if (!(inw (I2C_STAT) & I2C_STAT_NACK)) {
res = 0; /* success case */
flush_fifo();
outw(0xFFFF, I2C_STAT);
} else {
outw(0xFFFF, I2C_STAT); /* failue, clear sources*/
outw (inw (I2C_CON) | I2C_CON_STP, I2C_CON); /* finish up xfer */
udelay(20000);
wait_for_bb ();
}
flush_fifo();
outw (0, I2C_CNT); /* don't allow any more data in...we don't want it.*/
outw(0xFFFF, I2C_STAT);
return res;
}
int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len)
{
int i;
if (alen > 1) {
printf ("I2C read: addr len %d not supported\n", alen);
return 1;
}
if (addr + len > 256) {
printf ("I2C read: address out of range\n");
return 1;
}
for (i = 0; i < len; i++) {
if (i2c_read_byte (chip, addr + i, &buffer[i])) {
printf ("I2C read: I/O error\n");
i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
return 1;
}
}
return 0;
}
int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len)
{
int i;
if (alen > 1) {
printf ("I2C read: addr len %d not supported\n", alen);
return 1;
}
if (addr + len > 256) {
printf ("I2C read: address out of range\n");
return 1;
}
for (i = 0; i < len; i++) {
if (i2c_write_byte (chip, addr + i, buffer[i])) {
printf ("I2C read: I/O error\n");
i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
return 1;
}
}
return 0;
}
static void wait_for_bb (void)
{
int timeout = 10;
u16 stat;
outw(0xFFFF, I2C_STAT); /* clear current interruts...*/
while ((stat = inw (I2C_STAT) & I2C_STAT_BB) && timeout--) {
outw (stat, I2C_STAT);
udelay (50000);
}
if (timeout <= 0) {
printf ("timed out in wait_for_bb: I2C_STAT=%x\n",
inw (I2C_STAT));
}
outw(0xFFFF, I2C_STAT); /* clear delayed stuff*/
}
static u16 wait_for_pin (void)
{
u16 status;
int timeout = 10;
do {
udelay (1000);
status = inw (I2C_STAT);
} while ( !(status &
(I2C_STAT_ROVR | I2C_STAT_XUDF | I2C_STAT_XRDY |
I2C_STAT_RRDY | I2C_STAT_ARDY | I2C_STAT_NACK |
I2C_STAT_AL)) && timeout--);
if (timeout <= 0) {
printf ("timed out in wait_for_pin: I2C_STAT=%x\n",
inw (I2C_STAT));
outw(0xFFFF, I2C_STAT);
}
return status;
}
#endif /* CONFIG_DRIVER_OMAP24XX_I2C */

View file

@ -59,7 +59,14 @@ static int calc_divisor (void)
return (26); /* return 26 for base divisor */
}
#endif
return (CFG_NS16550_CLK / 16 / gd->baudrate);
#ifdef CONFIG_APTIX
#define MODE_X_DIV 13
#else
#define MODE_X_DIV 16
#endif
return (CFG_NS16550_CLK / MODE_X_DIV / gd->baudrate);
}
int serial_init (void)

View file

@ -0,0 +1,49 @@
/* bits.h
* Copyright (c) 2004 Texas Instruments
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the license found in the file
* named COPYING that should have accompanied this file.
*
* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef __bits_h
#define __bits_h 1
#define BIT0 (1<<0)
#define BIT1 (1<<1)
#define BIT2 (1<<2)
#define BIT3 (1<<3)
#define BIT4 (1<<4)
#define BIT5 (1<<5)
#define BIT6 (1<<6)
#define BIT7 (1<<7)
#define BIT8 (1<<8)
#define BIT9 (1<<9)
#define BIT10 (1<<10)
#define BIT11 (1<<11)
#define BIT12 (1<<12)
#define BIT13 (1<<13)
#define BIT14 (1<<14)
#define BIT15 (1<<15)
#define BIT16 (1<<16)
#define BIT17 (1<<17)
#define BIT18 (1<<18)
#define BIT19 (1<<19)
#define BIT20 (1<<20)
#define BIT21 (1<<21)
#define BIT22 (1<<22)
#define BIT23 (1<<23)
#define BIT24 (1<<24)
#define BIT25 (1<<25)
#define BIT26 (1<<26)
#define BIT27 (1<<27)
#define BIT28 (1<<28)
#define BIT29 (1<<29)
#define BIT30 (1<<30)
#define BIT31 (1<<31)
#endif

View file

@ -0,0 +1,79 @@
/*
* (C) Copyright 2004
* Texas Instruments, <www.ti.com>
* Richard Woodruff <r-woodruff2@ti.com>
*
* 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 _OMAP24XX_CLOCKS_H_
#define _OMAP24XX_CLOCKS_H_
#define COMMIT_DIVIDERS 0x1
#define MODE_BYPASS_FAST 0x2
#define APLL_LOCK 0xc
#ifdef CONFIG_APTIX
#define DPLL_LOCK 0x1 /* stay in bypass mode */
#else
#define DPLL_LOCK 0x3 /* DPLL lock */
#endif
/****************************************************************************;
; PRCM Scheme II
;
; Enable clocks and DPLL for:
; DPLL=300, DPLLout=600 M=1,N=50 CM_CLKSEL1_PLL[21:8] 12/2*50
; Core=600 (core domain) DPLLx2 CM_CLKSEL2_PLL[1:0]
; MPUF=300 (mpu domain) 2 CM_CLKSEL_MPU[4:0]
; DSPF=200 (dsp domain) 3 CM_CLKSEL_DSP[4:0]
; DSPI=100 6 CM_CLKSEL_DSP[6:5]
; DSP_S bypass CM_CLKSEL_DSP[7]
; IVAF=200 (dsp domain) 3 CM_CLKSEL_DSP[12:8]
; IVAF=100 auto
; IVAI auto
; IVA_MPU auto
; IVA_S bypass CM_CLKSEL_DSP[13]
; GFXF=50 (gfx domain) 12 CM_CLKSEL_FGX[2:0]
; SSI_SSRF=200 3 CM_CLKSEL1_CORE[24:20]
; SSI_SSTF=100 auto
; L3=100Mhz (sdram) 6 CM_CLKSEL1_CORE[4:0]
; L4=100Mhz 6
; C_L4_USB=50 12 CM_CLKSEL1_CORE[6:5]
***************************************************************************/
#define II_DPLL_OUT_X2 0x2 /* x2 core out */
#define II_MPU_DIV 0x2 /* mpu = core/2 */
#define II_DSP_DIV 0x343 /* dsp & iva divider */
#define II_GFX_DIV 0x2
#define II_BUS_DIV 0x04600C26
#define II_BUS_DIV_ES1 0x04601026
#define II_DPLL_300 0x01832100
/* set defaults for boot up */
#ifdef PRCM_CONFIG_II
#define DPLL_OUT II_DPLL_OUT_X2
#define MPU_DIV II_MPU_DIV
#define DSP_DIV II_DSP_DIV
#define GFX_DIV II_GFX_DIV
#define BUS_DIV II_BUS_DIV
#define BUS_DIV_ES1 II_BUS_DIV_ES1
#define DPLL_VAL II_DPLL_300
#endif
/* lock delay time out */
#define LDELAY 12000000
#endif

View file

@ -0,0 +1,106 @@
/*
* (C) Copyright 2004
* Texas Instruments, <www.ti.com>
*
* 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 _OMAP24XX_I2C_H_
#define _OMAP24XX_I2C_H_
#define I2C_BASE 0x48070000
#define I2C_BASE2 0x48072000 /* nothing hooked up on h4 */
#define I2C_REV (I2C_BASE + 0x00)
#define I2C_IE (I2C_BASE + 0x04)
#define I2C_STAT (I2C_BASE + 0x08)
#define I2C_IV (I2C_BASE + 0x0c)
#define I2C_BUF (I2C_BASE + 0x14)
#define I2C_CNT (I2C_BASE + 0x18)
#define I2C_DATA (I2C_BASE + 0x1c)
#define I2C_CON (I2C_BASE + 0x24)
#define I2C_OA (I2C_BASE + 0x28)
#define I2C_SA (I2C_BASE + 0x2c)
#define I2C_PSC (I2C_BASE + 0x30)
#define I2C_SCLL (I2C_BASE + 0x34)
#define I2C_SCLH (I2C_BASE + 0x38)
#define I2C_SYSTEST (I2C_BASE + 0x3c)
/* I2C masks */
/* I2C Interrupt Enable Register (I2C_IE): */
#define I2C_IE_GC_IE (1 << 5)
#define I2C_IE_XRDY_IE (1 << 4) /* Transmit data ready interrupt enable */
#define I2C_IE_RRDY_IE (1 << 3) /* Receive data ready interrupt enable */
#define I2C_IE_ARDY_IE (1 << 2) /* Register access ready interrupt enable */
#define I2C_IE_NACK_IE (1 << 1) /* No acknowledgment interrupt enable */
#define I2C_IE_AL_IE (1 << 0) /* Arbitration lost interrupt enable */
/* I2C Status Register (I2C_STAT): */
#define I2C_STAT_SBD (1 << 15) /* Single byte data */
#define I2C_STAT_BB (1 << 12) /* Bus busy */
#define I2C_STAT_ROVR (1 << 11) /* Receive overrun */
#define I2C_STAT_XUDF (1 << 10) /* Transmit underflow */
#define I2C_STAT_AAS (1 << 9) /* Address as slave */
#define I2C_STAT_GC (1 << 5)
#define I2C_STAT_XRDY (1 << 4) /* Transmit data ready */
#define I2C_STAT_RRDY (1 << 3) /* Receive data ready */
#define I2C_STAT_ARDY (1 << 2) /* Register access ready */
#define I2C_STAT_NACK (1 << 1) /* No acknowledgment interrupt enable */
#define I2C_STAT_AL (1 << 0) /* Arbitration lost interrupt enable */
/* I2C Interrupt Code Register (I2C_INTCODE): */
#define I2C_INTCODE_MASK 7
#define I2C_INTCODE_NONE 0
#define I2C_INTCODE_AL 1 /* Arbitration lost */
#define I2C_INTCODE_NAK 2 /* No acknowledgement/general call */
#define I2C_INTCODE_ARDY 3 /* Register access ready */
#define I2C_INTCODE_RRDY 4 /* Rcv data ready */
#define I2C_INTCODE_XRDY 5 /* Xmit data ready */
/* I2C Buffer Configuration Register (I2C_BUF): */
#define I2C_BUF_RDMA_EN (1 << 15) /* Receive DMA channel enable */
#define I2C_BUF_XDMA_EN (1 << 7) /* Transmit DMA channel enable */
/* I2C Configuration Register (I2C_CON): */
#define I2C_CON_EN (1 << 15) /* I2C module enable */
#define I2C_CON_BE (1 << 14) /* Big endian mode */
#define I2C_CON_STB (1 << 11) /* Start byte mode (master mode only) */
#define I2C_CON_MST (1 << 10) /* Master/slave mode */
#define I2C_CON_TRX (1 << 9) /* Transmitter/receiver mode (master mode only) */
#define I2C_CON_XA (1 << 8) /* Expand address */
#define I2C_CON_STP (1 << 1) /* Stop condition (master mode only) */
#define I2C_CON_STT (1 << 0) /* Start condition (master mode only) */
/* I2C System Test Register (I2C_SYSTEST): */
#define I2C_SYSTEST_ST_EN (1 << 15) /* System test enable */
#define I2C_SYSTEST_FREE (1 << 14) /* Free running mode (on breakpoint) */
#define I2C_SYSTEST_TMODE_MASK (3 << 12) /* Test mode select */
#define I2C_SYSTEST_TMODE_SHIFT (12) /* Test mode select */
#define I2C_SYSTEST_SCL_I (1 << 3) /* SCL line sense input value */
#define I2C_SYSTEST_SCL_O (1 << 2) /* SCL line drive output value */
#define I2C_SYSTEST_SDA_I (1 << 1) /* SDA line sense input value */
#define I2C_SYSTEST_SDA_O (1 << 0) /* SDA line drive output value */
#endif

View file

@ -0,0 +1,119 @@
/*
* (C) Copyright 2004
* Texas Instruments, <www.ti.com>
* Richard Woodruff <r-woodruff2@ti.com>
*
* 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 _OMAP24XX_MEM_H_
#define _OMAP24XX_MEM_H_
#define SDRC_CS0_OSET 0x0
#define SDRC_CS1_OSET 0x30 /* mirror CS1 regs appear offset 0x30 from CS0 */
#ifndef __ASSEMBLY__
/* struct's for holding data tables for current boards, they are getting used
early in init when NO global access are there */
struct sdrc_data_s {
u32 sdrc_sharing;
u32 sdrc_mdcfg_0;
u32 sdrc_actim_ctrla_0;
u32 sdrc_actim_ctrlb_0;
u32 sdrc_rfr_ctrl;
u32 sdrc_mr_0;
u32 sdrc_dlla_ctrl;
u32 sdrc_dllb_ctrl;
} /*__attribute__ ((packed))*/;
typedef struct sdrc_data_s sdrc_data_t;
#endif
/* Slower full frequency range default timings for x32 operation*/
#define H4_2420_SDRC_SHARING 0x00000100
#define H4_2420_SDRC_MDCFG_0 0x01702011
#define H4_2420_SDRC_ACTIM_CTRLA_0 0x9bead909
#define H4_2420_SDRC_ACTIM_CTRLB_0 0x00000014
#define H4_2420_SDRC_RFR_CTRL_ES1 0x00002401
#define H4_2420_SDRC_RFR_CTRL 0x0002da01
#define H4_2420_SDRC_MR_0 0x00000032
#define H4_2420_SDRC_DLLA_CTRL 0x00007307
#define H4_2420_SDRC_DLLB_CTRL 0x00007307
#define H4_2422_SDRC_SHARING 0x00004b00
#define H4_2422_SDRC_MDCFG_0 0x00801011
#define H4_2422_SDRC_ACTIM_CTRLA_0 0x9BEAD909
#define H4_2422_SDRC_ACTIM_CTRLB_0 0x00000020
#define H4_2422_SDRC_RFR_CTRL_ES1 0x00002401
#define H4_2422_SDRC_RFR_CTRL 0x0002da03
#define H4_2422_SDRC_MR_0 0x00000032
#define H4_2422_SDRC_DLLA_CTRL 0x00007307
#define H4_2422_SDRC_DLLB_CTRL 0x00007307
#define H4_2420_COMBO_MDCFG_0 0x00801011
/* optimized timings */
#define H4_2420_SDRC_ACTIM_CTRLA_0_100MHz 0x5A59B485
#define H4_2420_SDRC_ACTIM_CTRLB_0_100MHz 0x0000000e
#ifdef PRCM_CONFIG_II /* L3 at 100MHz */
#define H4_24XX_GPMC_CONFIG1_0 0x3
#define H4_24XX_GPMC_CONFIG2_0 0x001f1f01
#define H4_24XX_GPMC_CONFIG3_0 0x00030301
#define H4_24XX_GPMC_CONFIG4_0 0x0C030C03
#define H4_24XX_GPMC_CONFIG5_0 0x01131F1F
#define H4_24XX_GPMC_CONFIG7_0 (0x00000C40|(H4_CS0_BASE >> 24))
#define H4_24XX_GPMC_CONFIG1_1 0x00011000
#define H4_24XX_GPMC_CONFIG2_1 0x001F1F00
#define H4_24XX_GPMC_CONFIG3_1 0x00080802
#define H4_24XX_GPMC_CONFIG4_1 0x1C091C09
#define H4_24XX_GPMC_CONFIG5_1 0x031A1F1F
#define H4_24XX_GPMC_CONFIG6_1 0x000003C2
#define H4_24XX_GPMC_CONFIG7_1 (0x00000F40|(H4_CS1_BASE >> 24))
#endif
#ifdef PRCM_CONFIG_III /* L3 at 133MHz */
#define H4_24XX_GPMC_CONFIG1_0 0x3
#define H4_24XX_GPMC_CONFIG2_0 0x001f1f01
#define H4_24XX_GPMC_CONFIG3_0 0x001F1F00
#define H4_24XX_GPMC_CONFIG4_0 0x16061606
#define H4_24XX_GPMC_CONFIG5_0 0x01131F1F
#define H4_24XX_GPMC_CONFIG7_0 (0x00000C40|(H4_CS0_BASE >> 24))
#define H4_24XX_GPMC_CONFIG1_1 0x00011000
#define H4_24XX_GPMC_CONFIG2_1 0x001f1f01
#define H4_24XX_GPMC_CONFIG3_1 0x001F1F00
#define H4_24XX_GPMC_CONFIG4_1 0x1A061A06
#define H4_24XX_GPMC_CONFIG5_1 0x041F1F1F
#define H4_24XX_GPMC_CONFIG6_1 0x000004C4
#define H4_24XX_GPMC_CONFIG7_1 (0x00000F40|(H4_CS1_BASE >> 24))
#endif
#ifdef CONFIG_APTIX /* SDRC-SDR for Aptix x16 */
#define VAL_H4_SDRC_SHARING_16 0x00002400 /* No-Tristate, 16bit on D31-D16, CS1=dont care */
#define VAL_H4_SDRC_SHARING 0x00000100
#define VAL_H4_SDRC_MCFG_0_16 0x00901000 /* SDR-SDRAM,External,x16 bit */
#define VAL_H4_SDRC_MCFG_0 0x01702011
#define VAL_H4_SDRC_MR_0 0x00000029 /* Burst=2, Serial Mode, CAS 3*/
#define VAL_H4_SDRC_RFR_CTRL_0 0x00001703 /* refresh time */
#define VAL_H4_SDRC_DCDL2_CTRL 0x5A59B485
#endif
#endif

View file

@ -0,0 +1,158 @@
/*
* (C) Copyright 2004
* Texas Instruments, <www.ti.com>
* Richard Woodruff <r-woodruff2@ti.com>
*
* 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 _OMAP2420_MUX_H_
#define _OMAP2420_MUX_H_
#ifndef __ASSEMBLY__
typedef unsigned char uint8;
typedef unsigned int uint32;
void muxSetupSDRC(void);
void muxSetupGPMC(void);
void muxSetupUsb0(void);
void muxSetupUart3(void);
void muxSetupI2C1(void);
void muxSetupUART1(void);
void muxSetupLCD(void);
void muxSetupCamera(void);
void muxSetupMMCSD(void) ;
void muxSetupTouchScreen(void) ;
void muxSetupHDQ(void);
#endif
#define USB_OTG_CTRL ((volatile uint32 *)0x4805E30C)
/* Pin Muxing registers used for HDQ (Smart battery) */
#define CONTROL_PADCONF_HDQ_SIO ((volatile unsigned char *)0x48000115)
/* Pin Muxing registers used for GPMC */
#define CONTROL_PADCONF_GPMC_D2_BYTE0 ((volatile unsigned char *)0x48000088)
#define CONTROL_PADCONF_GPMC_D2_BYTE1 ((volatile unsigned char *)0x48000089)
#define CONTROL_PADCONF_GPMC_D2_BYTE2 ((volatile unsigned char *)0x4800008A)
#define CONTROL_PADCONF_GPMC_D2_BYTE3 ((volatile unsigned char *)0x4800008B)
#define CONTROL_PADCONF_GPMC_NCS0_BYTE0 ((volatile unsigned char *)0x4800008C)
#define CONTROL_PADCONF_GPMC_NCS0_BYTE1 ((volatile unsigned char *)0x4800008D)
#define CONTROL_PADCONF_GPMC_NCS0_BYTE2 ((volatile unsigned char *)0x4800008E)
#define CONTROL_PADCONF_GPMC_NCS0_BYTE3 ((volatile unsigned char *)0x4800008F)
/* Pin Muxing registers used for SDRC */
#define CONTROL_PADCONF_SDRC_NCS0_BYTE0 ((volatile unsigned char *)0x480000A0)
#define CONTROL_PADCONF_SDRC_NCS0_BYTE1 ((volatile unsigned char *)0x480000A1)
#define CONTROL_PADCONF_SDRC_NCS0_BYTE2 ((volatile unsigned char *)0x480000A2)
#define CONTROL_PADCONF_SDRC_NCS0_BYTE3 ((volatile unsigned char *)0x480000A3)
#define CONTROL_PADCONF_SDRC_A14_BYTE0 ((volatile unsigned char *)0x48000030)
#define CONTROL_PADCONF_SDRC_A14_BYTE1 ((volatile unsigned char *)0x48000031)
#define CONTROL_PADCONF_SDRC_A14_BYTE2 ((volatile unsigned char *)0x48000032)
#define CONTROL_PADCONF_SDRC_A14_BYTE3 ((volatile unsigned char *)0x48000033)
/* Pin Muxing registers used for Touch Screen (SPI) */
#define CONTROL_PADCONF_SPI1_CLK ((volatile unsigned char *)0x480000FF)
#define CONTROL_PADCONF_SPI1_SIMO ((volatile unsigned char *)0x48000100)
#define CONTROL_PADCONF_SPI1_SOMI ((volatile unsigned char *)0x48000101)
#define CONTROL_PADCONF_SPI1_NCS0 ((volatile unsigned char *)0x48000102)
#define CONTROL_PADCONF_MCBSP1_FSR ((volatile unsigned char *)0x4800010B)
/* Pin Muxing registers used for MMCSD */
#define CONTROL_PADCONF_MMC_CLKI ((volatile unsigned char *)0x480000FE)
#define CONTROL_PADCONF_MMC_CLKO ((volatile unsigned char *)0x480000F3)
#define CONTROL_PADCONF_MMC_CMD ((volatile unsigned char *)0x480000F4)
#define CONTROL_PADCONF_MMC_DAT0 ((volatile unsigned char *)0x480000F5)
#define CONTROL_PADCONF_MMC_DAT1 ((volatile unsigned char *)0x480000F6)
#define CONTROL_PADCONF_MMC_DAT2 ((volatile unsigned char *)0x480000F7)
#define CONTROL_PADCONF_MMC_DAT3 ((volatile unsigned char *)0x480000F8)
#define CONTROL_PADCONF_MMC_DAT_DIR0 ((volatile unsigned char *)0x480000F9)
#define CONTROL_PADCONF_MMC_DAT_DIR1 ((volatile unsigned char *)0x480000FA)
#define CONTROL_PADCONF_MMC_DAT_DIR2 ((volatile unsigned char *)0x480000FB)
#define CONTROL_PADCONF_MMC_DAT_DIR3 ((volatile unsigned char *)0x480000FC)
#define CONTROL_PADCONF_MMC_CMD_DIR ((volatile unsigned char *)0x480000FD)
#define CONTROL_PADCONF_SDRC_A14 ((volatile unsigned char *)0x48000030)
#define CONTROL_PADCONF_SDRC_A13 ((volatile unsigned char *)0x48000031)
/* Pin Muxing registers used for CAMERA */
#define CONTROL_PADCONF_SYS_NRESWARM ((volatile unsigned char *)0x4800012B)
#define CONTROL_PADCONF_CAM_XCLK ((volatile unsigned char *)0x480000DC)
#define CONTROL_PADCONF_CAM_LCLK ((volatile unsigned char *)0x480000DB)
#define CONTROL_PADCONF_CAM_VS ((volatile unsigned char *)0x480000DA)
#define CONTROL_PADCONF_CAM_HS ((volatile unsigned char *)0x480000D9)
#define CONTROL_PADCONF_CAM_D0 ((volatile unsigned char *)0x480000D8)
#define CONTROL_PADCONF_CAM_D1 ((volatile unsigned char *)0x480000D7)
#define CONTROL_PADCONF_CAM_D2 ((volatile unsigned char *)0x480000D6)
#define CONTROL_PADCONF_CAM_D3 ((volatile unsigned char *)0x480000D5)
#define CONTROL_PADCONF_CAM_D4 ((volatile unsigned char *)0x480000D4)
#define CONTROL_PADCONF_CAM_D5 ((volatile unsigned char *)0x480000D3)
#define CONTROL_PADCONF_CAM_D6 ((volatile unsigned char *)0x480000D2)
#define CONTROL_PADCONF_CAM_D7 ((volatile unsigned char *)0x480000D1)
#define CONTROL_PADCONF_CAM_D8 ((volatile unsigned char *)0x480000D0)
#define CONTROL_PADCONF_CAM_D9 ((volatile unsigned char *)0x480000CF)
/* Pin Muxing registers used for LCD */
#define CONTROL_PADCONF_DSS_D0 ((volatile unsigned char *)0x480000B3)
#define CONTROL_PADCONF_DSS_D1 ((volatile unsigned char *)0x480000B4)
#define CONTROL_PADCONF_DSS_D2 ((volatile unsigned char *)0x480000B5)
#define CONTROL_PADCONF_DSS_D3 ((volatile unsigned char *)0x480000B6)
#define CONTROL_PADCONF_DSS_D4 ((volatile unsigned char *)0x480000B7)
#define CONTROL_PADCONF_DSS_D5 ((volatile unsigned char *)0x480000B8)
#define CONTROL_PADCONF_DSS_D6 ((volatile unsigned char *)0x480000B9)
#define CONTROL_PADCONF_DSS_D7 ((volatile unsigned char *)0x480000BA)
#define CONTROL_PADCONF_DSS_D8 ((volatile unsigned char *)0x480000BB)
#define CONTROL_PADCONF_DSS_D9 ((volatile unsigned char *)0x480000BC)
#define CONTROL_PADCONF_DSS_D10 ((volatile unsigned char *)0x480000BD)
#define CONTROL_PADCONF_DSS_D11 ((volatile unsigned char *)0x480000BE)
#define CONTROL_PADCONF_DSS_D12 ((volatile unsigned char *)0x480000BF)
#define CONTROL_PADCONF_DSS_D13 ((volatile unsigned char *)0x480000C0)
#define CONTROL_PADCONF_DSS_D14 ((volatile unsigned char *)0x480000C1)
#define CONTROL_PADCONF_DSS_D15 ((volatile unsigned char *)0x480000C2)
#define CONTROL_PADCONF_DSS_D16 ((volatile unsigned char *)0x480000C3)
#define CONTROL_PADCONF_DSS_D17 ((volatile unsigned char *)0x480000C4)
#define CONTROL_PADCONF_DSS_PCLK ((volatile unsigned char *)0x480000CB)
#define CONTROL_PADCONF_DSS_VSYNC ((volatile unsigned char *)0x480000CC)
#define CONTROL_PADCONF_DSS_HSYNC ((volatile unsigned char *)0x480000CD)
#define CONTROL_PADCONF_DSS_ACBIAS ((volatile unsigned char *)0x480000CE)
/* Pin Muxing registers used for UART1 */
#define CONTROL_PADCONF_UART1_CTS ((volatile unsigned char *)0x480000C5)
#define CONTROL_PADCONF_UART1_RTS ((volatile unsigned char *)0x480000C6)
#define CONTROL_PADCONF_UART1_TX ((volatile unsigned char *)0x480000C7)
#define CONTROL_PADCONF_UART1_RX ((volatile unsigned char *)0x480000C8)
/* Pin Muxing registers used for I2C1 */
#define CONTROL_PADCONF_I2C1_SCL ((volatile unsigned char *)0x48000111)
#define CONTROL_PADCONF_I2C1_SDA ((volatile unsigned char *)0x48000112)
/* Pin Muxing registres used for USB0. */
#define CONTROL_PADCONF_USB0_PUEN ((volatile uint8 *)0x4800011D)
#define CONTROL_PADCONF_USB0_VP ((volatile uint8 *)0x4800011E)
#define CONTROL_PADCONF_USB0_VM ((volatile uint8 *)0x4800011F)
#define CONTROL_PADCONF_USB0_RCV ((volatile uint8 *)0x48000120)
#define CONTROL_PADCONF_USB0_TXEN ((volatile uint8 *)0x48000121)
#define CONTROL_PADCONF_USB0_SE0 ((volatile uint8 *)0x48000122)
#define CONTROL_PADCONF_USB0_DAT ((volatile uint8 *)0x48000123)
/* Pin Muxing registers used for UART3/IRDA */
#define CONTROL_PADCONF_UART3_TX_IRTX ((volatile uint8 *)0x48000118)
#define CONTROL_PADCONF_UART3_RX_IRRX ((volatile uint8 *)0x48000119)
#endif

View file

@ -0,0 +1,200 @@
/*
* (C) Copyright 2004
* Texas Instruments, <www.ti.com>
* Richard Woodruff <r-woodruff2@ti.com>
*
* 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 _OMAP2420_SYS_H_
#define _OMAP2420_SYS_H_
#include <asm/arch/sizes.h>
/*
* 2420 specific Section
*/
/* CONTROL */
#define OMAP2420_CTRL_BASE (0x48000000)
#define CONTROL_STATUS (OMAP2420_CTRL_BASE + 0x2F8)
/* TAP information */
#define OMAP2420_TAP_BASE (0x48014000)
#define TAP_IDCODE_REG (OMAP2420_TAP_BASE+0x204)
/* GPMC */
#define OMAP2420_GPMC_BASE (0x6800A000)
#define GPMC_SYSCONFIG (OMAP2420_GPMC_BASE+0x10)
#define GPMC_IRQENABLE (OMAP2420_GPMC_BASE+0x1C)
#define GPMC_TIMEOUT_CONTROL (OMAP2420_GPMC_BASE+0x40)
#define GPMC_CONFIG (OMAP2420_GPMC_BASE+0x50)
#define GPMC_CONFIG1_0 (OMAP2420_GPMC_BASE+0x60)
#define GPMC_CONFIG2_0 (OMAP2420_GPMC_BASE+0x64)
#define GPMC_CONFIG3_0 (OMAP2420_GPMC_BASE+0x68)
#define GPMC_CONFIG4_0 (OMAP2420_GPMC_BASE+0x6C)
#define GPMC_CONFIG5_0 (OMAP2420_GPMC_BASE+0x70)
#define GPMC_CONFIG7_0 (OMAP2420_GPMC_BASE+0x78)
#define GPMC_CONFIG1_1 (OMAP2420_GPMC_BASE+0x90)
#define GPMC_CONFIG2_1 (OMAP2420_GPMC_BASE+0x94)
#define GPMC_CONFIG3_1 (OMAP2420_GPMC_BASE+0x98)
#define GPMC_CONFIG4_1 (OMAP2420_GPMC_BASE+0x9C)
#define GPMC_CONFIG5_1 (OMAP2420_GPMC_BASE+0xA0)
#define GPMC_CONFIG6_1 (OMAP2420_GPMC_BASE+0xA4)
#define GPMC_CONFIG7_1 (OMAP2420_GPMC_BASE+0xA8)
/* SMS */
#define OMAP2420_SMS_BASE 0x68008000
#define SMS_SYSCONFIG (OMAP2420_SMS_BASE+0x10)
/* SDRC */
#define OMAP2420_SDRC_BASE 0x68009000
#define SDRC_SYSCONFIG (OMAP2420_SDRC_BASE+0x10)
#define SDRC_STATUS (OMAP2420_SDRC_BASE+0x14)
#define SDRC_SHARING (OMAP2420_SDRC_BASE+0x44)
#define SDRC_DLLA_CTRL (OMAP2420_SDRC_BASE+0x60)
#define SDRC_DLLB_CTRL (OMAP2420_SDRC_BASE+0x68)
#define SDRC_POWER (OMAP2420_SDRC_BASE+0x70)
#define SDRC_MCFG_0 (OMAP2420_SDRC_BASE+0x80)
#define SDRC_MR_0 (OMAP2420_SDRC_BASE+0x84)
#define SDRC_ACTIM_CTRLA_0 (OMAP2420_SDRC_BASE+0x9C)
#define SDRC_ACTIM_CTRLB_0 (OMAP2420_SDRC_BASE+0xA0)
#define SDRC_ACTIM_CTRLA_1 (OMAP2420_SDRC_BASE+0xC4)
#define SDRC_ACTIM_CTRLB_1 (OMAP2420_SDRC_BASE+0xC8)
#define SDRC_RFR_CTRL (OMAP2420_SDRC_BASE+0xA4)
#define SDRC_MANUAL_0 (OMAP2420_SDRC_BASE+0xA8)
#define OMAP2420_SDRC_CS0 0x80000000
#define OMAP2420_SDRC_CS1 0xA0000000
#define CMD_NOP 0x0
#define CMD_PRECHARGE 0x1
#define CMD_AUTOREFRESH 0x2
#define CMD_ENTR_PWRDOWN 0x3
#define CMD_EXIT_PWRDOWN 0x4
#define CMD_ENTR_SRFRSH 0x5
#define CMD_CKE_HIGH 0x6
#define CMD_CKE_LOW 0x7
#define SOFTRESET BIT1
#define SMART_IDLE (0x2 << 3)
#define REF_ON_IDLE (0x1 << 6)
/* UART */
#define OMAP2420_UART1 0x4806A000
#define OMAP2420_UART2 0x4806C000
#define OMAP2420_UART3 0x4806E000
/* General Purpose Timers */
#define OMAP2420_GPT1 0x48028000
#define OMAP2420_GPT2 0x4802A000
#define OMAP2420_GPT3 0x48078000
#define OMAP2420_GPT4 0x4807A000
#define OMAP2420_GPT5 0x4807C000
#define OMAP2420_GPT6 0x4807E000
#define OMAP2420_GPT7 0x48080000
#define OMAP2420_GPT8 0x48082000
#define OMAP2420_GPT9 0x48084000
#define OMAP2420_GPT10 0x48086000
#define OMAP2420_GPT11 0x48088000
#define OMAP2420_GPT12 0x4808A000
/* timer regs offsets (32 bit regs) */
#define TIDR 0x0 /* r */
#define TIOCP_CFG 0x10 /* rw */
#define TISTAT 0x14 /* r */
#define TISR 0x18 /* rw */
#define TIER 0x1C /* rw */
#define TWER 0x20 /* rw */
#define TCLR 0x24 /* rw */
#define TCRR 0x28 /* rw */
#define TLDR 0x2C /* rw */
#define TTGR 0x30 /* rw */
#define TWPS 0x34 /* r */
#define TMAR 0x38 /* rw */
#define TCAR1 0x3c /* r */
#define TSICR 0x40 /* rw */
#define TCAR2 0x44 /* r */
/* WatchDog Timers (1 secure, 3 GP) */
#define WD1_BASE 0x48020000
#define WD2_BASE 0x48022000
#define WD3_BASE 0x48024000
#define WD4_BASE 0x48026000
#define WWPS 0x34 /* r */
#define WSPR 0x48 /* rw */
#define WD_UNLOCK1 0xAAAA
#define WD_UNLOCK2 0x5555
/* PRCM */
#define OMAP2420_CM_BASE 0x48008000
#define PRCM_CLKCFG_CTRL (OMAP2420_CM_BASE+0x080)
#define CM_CLKSEL_MPU (OMAP2420_CM_BASE+0x140)
#define CM_FCLKEN1_CORE (OMAP2420_CM_BASE+0x200)
#define CM_FCLKEN2_CORE (OMAP2420_CM_BASE+0x204)
#define CM_ICLKEN1_CORE (OMAP2420_CM_BASE+0x210)
#define CM_ICLKEN2_CORE (OMAP2420_CM_BASE+0x214)
#define CM_CLKSEL1_CORE (OMAP2420_CM_BASE+0x240)
#define CM_CLKSEL_WKUP (OMAP2420_CM_BASE+0x440)
#define CM_CLKSEL2_CORE (OMAP2420_CM_BASE+0x244)
#define CM_CLKSEL_GFX (OMAP2420_CM_BASE+0x340)
#define PM_RSTCTRL_WKUP (OMAP2420_CM_BASE+0x450)
#define CM_CLKEN_PLL (OMAP2420_CM_BASE+0x500)
#define CM_IDLEST_CKGEN (OMAP2420_CM_BASE+0x520)
#define CM_CLKSEL1_PLL (OMAP2420_CM_BASE+0x540)
#define CM_CLKSEL2_PLL (OMAP2420_CM_BASE+0x544)
#define CM_CLKSEL_DSP (OMAP2420_CM_BASE+0x840)
/*
* H4 specific Section
*/
/*
* The 2420's chip selects are programmable. The mask ROM
* does configure CS0 to 0x08000000 before dispatch. So, if
* you want your code to live below that address, you have to
* be prepared to jump though hoops, to reset the base address.
*/
#if defined(CONFIG_OMAP2420H4)
/* GPMC */
#ifdef CONFIG_VIRTIO_A /* Pre version B */
# define H4_CS0_BASE 0x08000000 /* flash (64 Meg aligned) */
# define H4_CS1_BASE 0x04000000 /* debug board */
# define H4_CS2_BASE 0x0A000000 /* wifi board */
#else
# define H4_CS0_BASE 0x04000000 /* flash (64 Meg aligned) */
# define H4_CS1_BASE 0x08000000 /* debug board */
# define H4_CS2_BASE 0x0A000000 /* wifi board */
#endif
/* base address for indirect vectors (internal boot mode) */
#define SRAM_OFFSET0 0x40000000
#define SRAM_OFFSET1 0x00200000
#define SRAM_OFFSET2 0x0000F800
#define SRAM_VECT_CODE (SRAM_OFFSET0|SRAM_OFFSET1|SRAM_OFFSET2)
#define LOW_LEVEL_SRAM_STACK 0x4020FFFC
#define PERIFERAL_PORT_BASE 0x480FE003
/* FPGA on Debug board.*/
#define ETH_CONTROL_REG (H4_CS1_BASE+0x30b)
#define LAN_RESET_REGISTER (H4_CS1_BASE+0x1c)
#endif /* endif CONFIG_2420H4 */
#endif

View file

@ -0,0 +1,59 @@
/*
* (C) Copyright 2004
* Texas Instruments, <www.ti.com>
* Richard Woodruff <r-woodruff2@ti.com>
*
* 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 _OMAP24XX_REV_H_
#define _OMAP24XX_REV_H_
typedef struct h4_system_data {
/* base board info */
u32 base_b_rev; /* rev from base board i2c */
/* cpu board info */
u32 cpu_b_rev; /* rev from cpu board i2c */
u32 cpu_b_mux; /* mux type on daughter board */
u32 cpu_b_ddr_type; /* mem type */
u32 cpu_b_ddr_speed; /* ddr speed rating */
u32 cpu_b_switches; /* boot ctrl switch settings */
/* cpu info */
u32 cpu_type; /* type of cpu; 2420, 2422, 2430,...*/
u32 cpu_rev; /* rev of given cpu; ES1, ES2,...*/
} h4_sys_data;
#define CDB_DDR_COMBO /* combo part on cpu daughter card */
#define CDB_DDR_IPDB /* 2x16 parts on daughter card */
#define DDR_100 100 /* type found on most mem d-boards */
#define DDR_111 111 /* some combo parts */
#define DDR_133 133 /* most combo, some mem d-boards */
#define DDR_165 165 /* future parts */
#define CPU_2420 0x2420
#define CPU_2422 0x2422
#define CPU_2422_ES1 1
#define CPU_2422_ES2 2
#define CPU_2420_ES1 1
#define CPU_2420_ES2 2
#endif

View file

@ -0,0 +1,50 @@
/*
* 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
*/
/* Size defintions
* Copyright (C) ARM Limited 1998. All rights reserved.
*/
#ifndef __sizes_h
#define __sizes_h 1
/* handy sizes */
#define SZ_1K 0x00000400
#define SZ_4K 0x00001000
#define SZ_8K 0x00002000
#define SZ_16K 0x00004000
#define SZ_32K 0x00008000
#define SZ_64K 0x00010000
#define SZ_128K 0x00020000
#define SZ_256K 0x00040000
#define SZ_512K 0x00080000
#define SZ_1M 0x00100000
#define SZ_2M 0x00200000
#define SZ_4M 0x00400000
#define SZ_8M 0x00800000
#define SZ_16M 0x01000000
#define SZ_31M 0x01F00000
#define SZ_32M 0x02000000
#define SZ_64M 0x04000000
#define SZ_128M 0x08000000
#define SZ_256M 0x10000000
#define SZ_512M 0x20000000
#define SZ_1G 0x40000000
#define SZ_2G 0x80000000
#endif /* __sizes_h */

View file

@ -0,0 +1,78 @@
/*
* (C) Copyright 2004
* Texas Instruments, <www.ti.com>
* Richard Woodruff <r-woodruff2@ti.com>
*
* 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 _OMAP24XX_SYS_INFO_H_
#define _OMAP24XX_SYS_INFO_H_
typedef struct h4_system_data {
/* base board info */
u32 base_b_rev; /* rev from base board i2c */
/* cpu board info */
u32 cpu_b_rev; /* rev from cpu board i2c */
u32 cpu_b_mux; /* mux type on daughter board */
u32 cpu_b_ddr_type; /* mem type */
u32 cpu_b_ddr_speed; /* ddr speed rating */
u32 cpu_b_switches; /* boot ctrl switch settings */
/* cpu info */
u32 cpu_type; /* type of cpu; 2420, 2422, 2430,...*/
u32 cpu_rev; /* rev of given cpu; ES1, ES2,...*/
} h4_sys_data;
#define DDR_STACKED 3 /* stacked part on 2422 */
#define DDR_COMBO 2 /* combo part on cpu daughter card (menalaeus) */
#define DDR_DISCRETE 1 /* 2x16 parts on daughter card */
#define DDR_100 100 /* type found on most mem d-boards */
#define DDR_111 111 /* some combo parts */
#define DDR_133 133 /* most combo, some mem d-boards */
#define DDR_165 165 /* future parts */
#define CPU_2420 0x2420
#define CPU_2422 0x2422
#define CPU_2422_ES1 1
#define CPU_2422_ES2 2
#define CPU_2420_ES1 1
#define CPU_2420_ES2 2
#define CPU_2420_CHIPID 0x0B5D9000
#define CPU_24XX_ID_MASK 0x0FFFF000
#define CPU_242X_REV_MASK 0xF0000000
#define BOARD_H4_MENELAUS 1
#define BOARD_H4_SDP 2
#define GPMC_MUXED 1
#define GPMC_NONMUXED 0
#define TYPE_NAND 0x800 /* bit pos for nand in gpmc reg */
#define TYPE_NOR 0x000
#define WIDTH_8BIT 0x0000
#define WIDTH_16BIT 0x1000 /* bit pos for 16 bit in gpmc */
#define I2C_MENELAUS 0x72 /* i2c id for companion chip */
#endif

View file

@ -0,0 +1,48 @@
/*
* (C) Copyright 2004
* Texas Instruments, <www.ti.com>
* Richard Woodruff <r-woodruff2@ti.com>
*
* 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 _OMAP24XX_SYS_PROTO_H_
#define _OMAP24XX_SYS_PROTO_H_
void prcm_init(void);
void memif_init(void);
void sdrc_init(void);
void do_sdrc_init(u32,u32);
void gpmc_init(void);
void ether_init(void);
void watchdog_init(void);
void set_muxconf_regs(void);
void peripheral_enable(void);
u32 get_cpu_type(void);
u32 get_cpu_rev(void);
u32 get_mem_type(void);
u32 get_sysboot_value(void);
u32 get_gpmc0_base(void);
u32 is_gpmc_muxed(void);
u32 get_gpmc0_type(void);
u32 get_gpmc0_width(void);
u32 wait_on_value(u32 read_bit_mask, u32 match_value, u32 read_addr, u32 bound);
u32 get_board_type(void);
void display_board_info(u32);
void update_mux(u32,u32);
#endif

View file

@ -35,10 +35,12 @@
* to the architecture specific code.
*/
#define __arch_getb(a) (*(volatile unsigned char *)(a))
#define __arch_getl(a) (*(volatile unsigned int *)(a))
#define __arch_getw(a) (*(volatile unsigned short *)(a))
#define __arch_getl(a) (*(volatile unsigned int *)(a))
#define __arch_putb(v,a) (*(volatile unsigned char *)(a) = (v))
#define __arch_putl(v,a) (*(volatile unsigned int *)(a) = (v))
#define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v))
#define __arch_putl(v,a) (*(volatile unsigned int *)(a) = (v))
extern void __raw_writesb(unsigned int addr, const void *data, int bytelen);
extern void __raw_writesw(unsigned int addr, const void *data, int wordlen);

View file

@ -0,0 +1,213 @@
/*
* (C) Copyright 2004
* Texas Instruments.
* Richard Woodruff <r-woodruff2@ti.com>
* Kshitij Gupta <kshitij@ti.com>
*
* Configuration settings for the 242x TI H4 board.
*
* 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 __CONFIG_H
#define __CONFIG_H
/*
* High Level Configuration Options
*/
#define CONFIG_ARM1136 1 /* This is an arm1136 CPU core */
#define CONFIG_OMAP 1 /* in a TI OMAP core */
#define CONFIG_OMAP2420 1 /* which is in a 2420 */
#define CONFIG_OMAP2420H4 1 /* and on a H4 board */
//#define CONFIG_APTIX 1 /* define if on APTIX test chip */
//#define CONFIG_VIRTIO 1 /* Using Virtio simulator */
#define PRCM_CONFIG_II 1
#define CONFIG_PARTIAL_SRAM 1
#include <asm/arch/omap2420.h> /* get chip and board defs */
#ifdef CONFIG_APTIX
#define V_SCLK 1500000
#else
#define V_SCLK 12000000
#endif
/* input clock of PLL */
/* the OMAP2420 H4 has 12MHz, 13MHz, or 19.2Mhz crystal input */
#define CONFIG_SYS_CLK_FREQ V_SCLK
#undef CONFIG_USE_IRQ /* no support for IRQs */
#define CONFIG_MISC_INIT_R
#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
#define CONFIG_SETUP_MEMORY_TAGS 1
#define CONFIG_INITRD_TAG 1
/*
* Size of malloc() pool
*/
#define CFG_ENV_SIZE SZ_128K /* Total Size of Environment Sector */
#define CFG_MALLOC_LEN (CFG_ENV_SIZE + SZ_128K)
#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
/*
* Hardware drivers
*/
/*
* SMC91c96 Etherent
*/
#define CONFIG_DRIVER_LAN91C96
#define CONFIG_LAN91C96_BASE (H4_CS1_BASE+0x300)
#define CONFIG_LAN91C96_EXT_PHY
/*
* NS16550 Configuration
*/
#ifdef CONFIG_APTIX
#define V_NS16550_CLK (6000000) /* 6MHz in current MaxSet */
#else
#define V_NS16550_CLK (48000000) /* 48MHz (APLL96/2) */
#endif
#define CFG_NS16550
#define CFG_NS16550_SERIAL
#define CFG_NS16550_REG_SIZE (-4)
#define CFG_NS16550_CLK V_NS16550_CLK /* 3MHz (1.5MHz*2) */
#define CFG_NS16550_COM1 OMAP2420_UART1
/*
* select serial console configuration
*/
#define CONFIG_SERIAL1 1 /* UART1 on H4 */
/*
* I2C configuration
*/
#define CONFIG_HARD_I2C
#define CFG_I2C_SPEED 100000
#define CFG_I2C_SLAVE 1
#define CONFIG_DRIVER_OMAP24XX_I2C
/* allow to overwrite serial and ethaddr */
#define CONFIG_ENV_OVERWRITE
#define CONFIG_CONS_INDEX 1
#define CONFIG_BAUDRATE 115200
#define CFG_BAUDRATE_TABLE {9600, 19200, 38400, 57600, 115200}
#define CONFIG_COMMANDS (CONFIG_CMD_DFL | CFG_CMD_DHCP | CFG_CMD_I2C)
// I'd like to get to these. Snap kernel loads if we make MMC go //
// #define CONFIG_COMMANDS (CONFIG_CMD_DFL | CFG_CMD_NAND | CFG_CMD_JFFS2 | CFG_CMD_DHCP | CFG_CMD_MMC | CFG_CMD_FAT | CFG_CMD_I2C)
#define CONFIG_BOOTP_MASK CONFIG_BOOTP_DEFAULT
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
#include <cmd_confdefs.h>
#define CONFIG_BOOTDELAY 3
#ifdef NFS_BOOT_DEFAULTS
#define CONFIG_BOOTARGS "mem=32M console=ttyS0,115200n8 noinitrd root=/dev/nfs rw nfsroot=128.247.77.158:/home/a0384864/wtbu/rootfs ip=dhcp"
#else
#define CONFIG_BOOTARGS "root=/dev/ram0 rw mem=32M console=ttyS0,115200n8 initrd=0x80600000,8M ramdisk_size=8192"
#endif
#define CONFIG_NETMASK 255.255.254.0
#define CONFIG_IPADDR 128.247.77.90
#define CONFIG_SERVERIP 128.247.77.158
#define CONFIG_BOOTFILE "uImage"
/*
* Miscellaneous configurable options
*/
#ifdef CONFIG_APTIX
#define V_PROMPT "OMAP2420 Aptix # "
#else
#define V_PROMPT "OMAP242x H4 # "
#endif
#define CFG_LONGHELP /* undef to save memory */
#define CFG_PROMPT V_PROMPT
#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
/* Print Buffer Size */
#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16)
#define CFG_MAXARGS 16 /* max number of command args */
#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
#define CFG_MEMTEST_START (OMAP2420_SDRC_CS0) /* memtest works on */
#define CFG_MEMTEST_END (OMAP2420_SDRC_CS0+SZ_31M)
#undef CFG_CLKS_IN_HZ /* everything, incl board info, in Hz */
#define CFG_LOAD_ADDR (OMAP2420_SDRC_CS0) /* default load address */
/* The 2420 has 12 GP timers, they can be driven by the SysClk (12/13/19.2) or by
* 32KHz clk, or from external sig. This rate is divided by a local divisor.
*/
#ifdef CONFIG_APTIX
#define V_PVT 3
#else
#define V_PVT 7 /* use with 12MHz/128 */
#endif
#define CFG_TIMERBASE OMAP2420_GPT2
#define CFG_PVT V_PVT /* 2^(pvt+1) */
#define CFG_HZ ((CONFIG_SYS_CLK_FREQ)/(2 << CFG_PVT))
/*-----------------------------------------------------------------------
* Stack sizes
*
* The stack sizes are set up in start.S using the settings below
*/
#define CONFIG_STACKSIZE SZ_128K /* regular stack */
#ifdef CONFIG_USE_IRQ
#define CONFIG_STACKSIZE_IRQ SZ_4K /* IRQ stack */
#define CONFIG_STACKSIZE_FIQ SZ_4K /* FIQ stack */
#endif
/*-----------------------------------------------------------------------
* Physical Memory Map
*/
#define CONFIG_NR_DRAM_BANKS 2 /* CS1 may or may not be populated */
#define PHYS_SDRAM_1 OMAP2420_SDRC_CS0
#define PHYS_SDRAM_1_SIZE SZ_32M /* at least 32 meg */
#define PHYS_SDRAM_2 OMAP2420_SDRC_CS1
#define PHYS_FLASH_1 H4_CS0_BASE /* Flash Bank #1 */
#define PHYS_FLASH_SIZE_1 SZ_32M
#define PHYS_FLASH_2 (H4_CS0_BASE+SZ_32M) /* same cs, 2 chips in series */
#define PHYS_FLASH_SIZE_2 SZ_32M
#define CFG_FLASH_BASE PHYS_FLASH_1
/*-----------------------------------------------------------------------
* FLASH and environment organization
*/
#define CFG_MAX_FLASH_BANKS 2 /* max number of memory banks */
#define CFG_MAX_FLASH_SECT (259) /* max number of sectors on one chip */
#define CFG_ENV_ADDR (CFG_FLASH_BASE + SZ_128K)
#define CFG_ENV_IS_IN_FLASH 1
/* timeout values are in ticks */
#define CFG_FLASH_ERASE_TOUT (10*75*CFG_HZ) /* Timeout for Flash Erase */
#define CFG_FLASH_WRITE_TOUT (10*75*CFG_HZ) /* Timeout for Flash Write */
#endif /* __CONFIG_H */

View file

@ -72,7 +72,7 @@ struct NS16550 {
int pad7:24;
unsigned char scr; /* 7 */
int pad8:24;
#if defined(CONFIG_OMAP1510) || defined(CONFIG_OMAP1610)
#if defined(CONFIG_OMAP)
unsigned char mdr1; /* mode select reset TL16C750*/
#endif
#ifdef CONFIG_OMAP1510

View file

@ -23,7 +23,14 @@
/* for now: just dummy functions to satisfy the linker */
#include <common.h>
void flush_cache (unsigned long dummy1, unsigned long dummy2)
{
#ifdef CONFIG_OMAP2420
void arm1136_cache_flush(void);
arm1136_cache_flush();
#endif
return;
}