The AmigaOneG3SE board has been orphaned or a very long time, and broken for more than 12 releases resp. more than 3 years. As nobody seems to be interested any more in this stuff we may as well ged rid of it, especially as it clutters many areas of the code so it is a continuous pain for all kinds of ongoing work. Signed-off-by: Wolfgang Denk <wd@denx.de>master
parent
ee80fa7b6e
commit
953b7e6291
@ -1,122 +0,0 @@ |
||||
/*
|
||||
* (C) Copyright 2002 |
||||
* Hyperion Entertainment, ThomasF@hyperion-entertainment.com |
||||
* (C) Copyright 2006 |
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de. |
||||
* |
||||
* See file CREDITS for list of people who contributed to this |
||||
* project. |
||||
* |
||||
* This program is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU General Public License as |
||||
* published by the Free Software Foundation; either version 2 of |
||||
* the License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program; if not, write to the Free Software |
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
||||
* MA 02111-1307 USA |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <command.h> |
||||
#include <pci.h> |
||||
#include <netdev.h> |
||||
#include "articiaS.h" |
||||
#include "memio.h" |
||||
#include "via686.h" |
||||
|
||||
__asm__(" .globl send_kb \n " |
||||
"send_kb: \n " |
||||
" lis r9, 0xfe00 \n " |
||||
" \n " |
||||
" li r4, 0x10 # retries \n " |
||||
" mtctr r4 \n " |
||||
" \n " |
||||
"idle: \n " |
||||
" lbz r4, 0x64(r9) \n " |
||||
" andi. r4, r4, 0x02 \n " |
||||
" bne idle \n " |
||||
|
||||
"ready: \n " |
||||
" stb r3, 0x60(r9) \n " |
||||
" \n " |
||||
"check: \n " |
||||
" lbz r4, 0x64(r9) \n " |
||||
" andi. r4, r4, 0x01 \n " |
||||
" beq check \n " |
||||
" \n " |
||||
" lbz r4, 0x60(r9) \n " |
||||
" cmpwi r4, 0xfa \n " |
||||
" beq done \n " |
||||
|
||||
" bdnz idle \n " |
||||
|
||||
" li r3, 0 \n " |
||||
" blr \n " |
||||
|
||||
"done: \n " |
||||
" li r3, 1 \n " |
||||
" blr \n " |
||||
|
||||
".globl test_kb \n " |
||||
"test_kb: \n " |
||||
" mflr r10 \n " |
||||
" li r3, 0xed \n " |
||||
" bl send_kb \n " |
||||
" li r3, 0x01 \n " |
||||
" bl send_kb \n " |
||||
" mtlr r10 \n " |
||||
" blr \n " |
||||
); |
||||
|
||||
|
||||
int checkboard (void) |
||||
{ |
||||
printf ("Board: AmigaOneG3SE\n"); |
||||
return 0; |
||||
} |
||||
|
||||
phys_size_t initdram (int board_type) |
||||
{ |
||||
return articiaS_ram_init (); |
||||
} |
||||
|
||||
|
||||
void after_reloc (ulong dest_addr, gd_t *gd) |
||||
{ |
||||
board_init_r (gd, dest_addr); |
||||
} |
||||
|
||||
|
||||
int misc_init_r (void) |
||||
{ |
||||
extern pci_dev_t video_dev; |
||||
extern void drv_video_init (void); |
||||
|
||||
if (video_dev != ~0) |
||||
drv_video_init (); |
||||
|
||||
return (0); |
||||
} |
||||
|
||||
|
||||
void pci_init_board (void) |
||||
{ |
||||
#ifndef CONFIG_RAMBOOT |
||||
articiaS_pci_init (); |
||||
#endif |
||||
} |
||||
|
||||
int board_eth_init(bd_t *bis) |
||||
{ |
||||
#if defined(CONFIG_3COM) |
||||
eth_3com_initialize(bis); |
||||
#endif |
||||
return 0; |
||||
} |
@ -1,63 +0,0 @@ |
||||
#
|
||||
# (C) Copyright 2002-2006
|
||||
# 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 |
||||
ifneq ($(OBJTREE),$(SRCTREE)) |
||||
$(shell mkdir -p $(obj)../menu) |
||||
$(shell mkdir -p $(obj)../bios_emulator) |
||||
endif |
||||
|
||||
LIB = $(obj)lib$(BOARD).a
|
||||
|
||||
COBJS = $(BOARD).o articiaS.o flash.o serial.o smbus.o articiaS_pci.o \
|
||||
via686.o i8259.o ../bios_emulator/x86interface.o \
|
||||
../bios_emulator/bios.o ../bios_emulator/glue.o \
|
||||
interrupts.o ps2kbd.o video.o usb_uhci.o enet.o \
|
||||
../menu/cmd_menu.o cmd_boota.o nvram.o
|
||||
|
||||
SOBJS = board_asm_init.o memio.o
|
||||
|
||||
EMUDIR = ../bios_emulator/scitech/src/x86emu/
|
||||
EMUOBJ = $(EMUDIR)decode.o $(EMUDIR)ops2.o $(EMUDIR)fpu.o $(EMUDIR)prim_ops.o \
|
||||
$(EMUDIR)ops.o $(EMUDIR)sys.o
|
||||
EMUSRC = $(EMUOBJ:.o=.c)
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS))
|
||||
SOBJS := $(addprefix $(obj),$(SOBJS))
|
||||
EMUOBJ := $(addprefix $(obj),$(EMUOBJ))
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS) $(SOBJS) $(EMUSRC) |
||||
make $(obj)libx86emu.a -C ../bios_emulator/scitech/src/x86emu -f makefile.uboot CROSS_COMPILE=$(CROSS_COMPILE)
|
||||
-rm $(LIB)
|
||||
$(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS) $(EMUOBJ)
|
||||
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk |
||||
|
||||
sinclude $(obj).depend |
||||
|
||||
#########################################################################
|
@ -1,704 +0,0 @@ |
||||
/*
|
||||
* (C) Copyright 2002 |
||||
* Hyperion Entertainment, ThomasF@hyperion-entertainment.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 <pci.h> |
||||
#include <asm/processor.h> |
||||
#include "memio.h" |
||||
#include "articiaS.h" |
||||
#include "smbus.h" |
||||
#include "via686.h" |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
#undef DEBUG |
||||
|
||||
struct dimm_bank { |
||||
uint8 used; /* Bank is populated */ |
||||
uint32 rows; /* Number of row addresses */ |
||||
uint32 columns; /* Number of column addresses */ |
||||
uint8 registered; /* SIMM is registered */ |
||||
uint8 ecc; /* SIMM has ecc */ |
||||
uint8 burst_len; /* Supported burst lengths */ |
||||
uint32 cas_lat; /* Supported CAS latencies */ |
||||
uint32 cas_used; /* CAS to use (not set by user) */ |
||||
uint32 trcd; /* RAS to CAS latency */ |
||||
uint32 trp; /* Precharge latency */ |
||||
uint32 tclk_hi; /* SDRAM cycle time (highest CAS latency) */ |
||||
uint32 tclk_2hi; /* SDRAM second highest CAS latency */ |
||||
uint32 size; /* Size of bank in bytes */ |
||||
uint8 auto_refresh; /* Module supports auto refresh */ |
||||
uint32 refresh_time; /* Refresh time (in ns) */ |
||||
}; |
||||
|
||||
|
||||
/*
|
||||
** Based in part on the evb64260 code |
||||
*/ |
||||
|
||||
/*
|
||||
* translate ns.ns/10 coding of SPD timing values |
||||
* into 10 ps unit values |
||||
*/ |
||||
static inline unsigned short NS10to10PS (unsigned char spd_byte) |
||||
{ |
||||
unsigned short ns, ns10; |
||||
|
||||
/* isolate upper nibble */ |
||||
ns = (spd_byte >> 4) & 0x0F; |
||||
/* isolate lower nibble */ |
||||
ns10 = (spd_byte & 0x0F); |
||||
|
||||
return (ns * 100 + ns10 * 10); |
||||
} |
||||
|
||||
/*
|
||||
* translate ns coding of SPD timing values |
||||
* into 10 ps unit values |
||||
*/ |
||||
static inline unsigned short NSto10PS (unsigned char spd_byte) |
||||
{ |
||||
return (spd_byte * 100); |
||||
} |
||||
|
||||
|
||||
long detect_sdram (uint8 * rom, int dimmNum, struct dimm_bank *banks) |
||||
{ |
||||
int dimm_address = (dimmNum == 0) ? SM_DIMM0_ADDR : SM_DIMM1_ADDR; |
||||
uint32 busclock = gd->bus_clk; |
||||
uint32 memclock = busclock; |
||||
uint32 tmemclock = 1000000000 / (memclock / 100); |
||||
uint32 datawidth; |
||||
|
||||
if (sm_get_data (rom, dimm_address) == 0) { |
||||
/* Nothing in slot, make both banks empty */ |
||||
debug ("Slot %d: vacant\n", dimmNum); |
||||
banks[0].used = 0; |
||||
banks[1].used = 0; |
||||
return 0; |
||||
} |
||||
|
||||
if (rom[2] != 0x04) { |
||||
debug ("Slot %d: No SDRAM\n", dimmNum); |
||||
banks[0].used = 0; |
||||
banks[1].used = 0; |
||||
return 0; |
||||
} |
||||
|
||||
/* Determine number of banks/rows */ |
||||
if (rom[5] == 1) { |
||||
banks[0].used = 1; |
||||
banks[1].used = 0; |
||||
} else { |
||||
banks[0].used = 1; |
||||
banks[1].used = 1; |
||||
} |
||||
|
||||
/* Determine number of row addresses */ |
||||
if (rom[3] & 0xf0) { |
||||
/* Different banks sizes */ |
||||
banks[0].rows = rom[3] & 0x0f; |
||||
banks[1].rows = (rom[3] & 0xf0) >> 4; |
||||
} else { |
||||
/* Equal sized banks */ |
||||
banks[0].rows = rom[3] & 0x0f; |
||||
banks[1].rows = banks[0].rows; |
||||
} |
||||
|
||||
/* Determine number of column addresses */ |
||||
if (rom[4] & 0xf0) { |
||||
/* Different bank sizes */ |
||||
banks[0].columns = rom[4] & 0x0f; |
||||
banks[1].columns = (rom[4] & 0xf0) >> 4; |
||||
} else { |
||||
banks[0].columns = rom[4] & 0x0f; |
||||
banks[1].columns = banks[0].columns; |
||||
} |
||||
|
||||
/* Check Jedec revision, and modify row/column accordingly */ |
||||
if (rom[62] > 0x10) { |
||||
if (banks[0].rows <= 3) |
||||
banks[0].rows += 15; |
||||
if (banks[1].rows <= 3) |
||||
banks[1].rows += 15; |
||||
if (banks[0].columns <= 3) |
||||
banks[0].columns += 15; |
||||
if (banks[0].columns <= 3) |
||||
banks[0].columns += 15; |
||||
} |
||||
|
||||
/* Check registered/unregisterd */ |
||||
if (rom[21] & 0x12) { |
||||
banks[0].registered = 1; |
||||
banks[1].registered = 1; |
||||
} else { |
||||
banks[0].registered = 0; |
||||
banks[1].registered = 0; |
||||
} |
||||
|
||||
#ifdef CONFIG_ECC |
||||
/* Check parity/ECC */ |
||||
banks[0].ecc = (rom[11] == 0x02); |
||||
banks[1].ecc = (rom[11] == 0x02); |
||||
#endif |
||||
|
||||
/* Find burst lengths supported */ |
||||
banks[0].burst_len = rom[16] & 0x8f; |
||||
banks[1].burst_len = rom[16] & 0x8f; |
||||
|
||||
/* Find possible cas latencies */ |
||||
banks[0].cas_lat = rom[18] & 0x7F; |
||||
banks[1].cas_lat = rom[18] & 0x7F; |
||||
|
||||
/* RAS/CAS latency */ |
||||
banks[0].trcd = (NSto10PS (rom[29]) + (tmemclock - 1)) / tmemclock; |
||||
banks[1].trcd = (NSto10PS (rom[29]) + (tmemclock - 1)) / tmemclock; |
||||
|
||||
/* Precharge latency */ |
||||
banks[0].trp = (NSto10PS (rom[27]) + (tmemclock - 1)) / tmemclock; |
||||
banks[1].trp = (NSto10PS (rom[27]) + (tmemclock - 1)) / tmemclock; |
||||
|
||||
/* highest CAS latency */ |
||||
banks[0].tclk_hi = NS10to10PS (rom[9]); |
||||
banks[1].tclk_hi = NS10to10PS (rom[9]); |
||||
|
||||
/* second highest CAS latency */ |
||||
banks[0].tclk_2hi = NS10to10PS (rom[23]); |
||||
banks[1].tclk_2hi = NS10to10PS (rom[23]); |
||||
|
||||
/* bank sizes */ |
||||
datawidth = rom[13] & 0x7f; |
||||
banks[0].size = |
||||
(1L << (banks[0].rows + banks[0].columns)) * |
||||
/* FIXME datawidth */ 8 * rom[17]; |
||||
if (rom[13] & 0x80) |
||||
banks[1].size = 2 * banks[0].size; |
||||
else |
||||
banks[1].size = (1L << (banks[1].rows + banks[1].columns)) * |
||||
/* FIXME datawidth */ 8 * rom[17]; |
||||
|
||||
/* Refresh */ |
||||
if (rom[12] & 0x80) { |
||||
banks[0].auto_refresh = 1; |
||||
banks[1].auto_refresh = 1; |
||||
} else { |
||||
banks[0].auto_refresh = 0; |
||||
banks[1].auto_refresh = 0; |
||||
} |
||||
|
||||
switch (rom[12] & 0x7f) { |
||||
case 0: |
||||
banks[0].refresh_time = (1562500 + (tmemclock - 1)) / tmemclock; |
||||
banks[1].refresh_time = (1562500 + (tmemclock - 1)) / tmemclock; |
||||
break; |
||||
case 1: |
||||
banks[0].refresh_time = (390600 + (tmemclock - 1)) / tmemclock; |
||||
banks[1].refresh_time = (390600 + (tmemclock - 1)) / tmemclock; |
||||
break; |
||||
case 2: |
||||
banks[0].refresh_time = (781200 + (tmemclock - 1)) / tmemclock; |
||||
banks[1].refresh_time = (781200 + (tmemclock - 1)) / tmemclock; |
||||
break; |
||||
case 3: |
||||
banks[0].refresh_time = (3125000 + (tmemclock - 1)) / tmemclock; |
||||
banks[1].refresh_time = (3125000 + (tmemclock - 1)) / tmemclock; |
||||
break; |
||||
case 4: |
||||
banks[0].refresh_time = (6250000 + (tmemclock - 1)) / tmemclock; |
||||
banks[1].refresh_time = (6250000 + (tmemclock - 1)) / tmemclock; |
||||
break; |
||||
case 5: |
||||
banks[0].refresh_time = (12500000 + (tmemclock - 1)) / tmemclock; |
||||
banks[1].refresh_time = (12500000 + (tmemclock - 1)) / tmemclock; |
||||
break; |
||||
default: |
||||
banks[0].refresh_time = 0x100; /* Default of Articia S */ |
||||
banks[1].refresh_time = 0x100; |
||||
break; |
||||
} |
||||
|
||||
#ifdef DEBUG |
||||
printf ("\nInformation for SIMM bank %ld:\n", dimmNum); |
||||
printf ("Number of banks: %ld\n", banks[0].used + banks[1].used); |
||||
printf ("Number of row addresses: %ld\n", banks[0].rows); |
||||
printf ("Number of coumns addresses: %ld\n", banks[0].columns); |
||||
printf ("SIMM is %sregistered\n", |
||||
banks[0].registered == 0 ? "not " : ""); |
||||
#ifdef CONFIG_ECC |
||||
printf ("SIMM %s ECC\n", |
||||
banks[0].ecc == 1 ? "supports" : "doesn't support"); |
||||
#endif |
||||
printf ("Supported burst lenghts: %s %s %s %s %s\n", |
||||
banks[0].burst_len & 0x08 ? "8" : " ", |
||||
banks[0].burst_len & 0x04 ? "4" : " ", |
||||
banks[0].burst_len & 0x02 ? "2" : " ", |
||||
banks[0].burst_len & 0x01 ? "1" : " ", |
||||
banks[0].burst_len & 0x80 ? "PAGE" : " "); |
||||
printf ("Supported CAS latencies: %s %s %s\n", |
||||
banks[0].cas_lat & 0x04 ? "CAS 3" : " ", |
||||
banks[0].cas_lat & 0x02 ? "CAS 2" : " ", |
||||
banks[0].cas_lat & 0x01 ? "CAS 1" : " "); |
||||
printf ("RAS to CAS latency: %ld\n", banks[0].trcd); |
||||
printf ("Precharge latency: %ld\n", banks[0].trp); |
||||
printf ("SDRAM highest CAS latency: %ld\n", banks[0].tclk_hi); |
||||
printf ("SDRAM 2nd highest CAS latency: %ld\n", banks[0].tclk_2hi); |
||||
printf ("SDRAM data width: %ld\n", datawidth); |
||||
printf ("Auto Refresh %ssupported\n", |
||||
banks[0].auto_refresh ? "" : "not "); |
||||
printf ("Refresh time: %ld clocks\n", banks[0].refresh_time); |
||||
if (banks[0].used) |
||||
printf ("Bank 0 size: %ld MB\n", banks[0].size / 1024 / 1024); |
||||
if (banks[1].used) |
||||
printf ("Bank 1 size: %ld MB\n", banks[1].size / 1024 / 1024); |
||||
|
||||
printf ("\n"); |
||||
#endif |
||||
|
||||
sm_term (); |
||||
return 1; |
||||
} |
||||
|
||||
void select_cas (struct dimm_bank *banks, uint8 fast) |
||||
{ |
||||
if (!banks[0].used) { |
||||
banks[0].cas_used = 0; |
||||
banks[0].cas_used = 0; |
||||
return; |
||||
} |
||||
|
||||
if (fast) { |
||||
/* Search for fast CAS */ |
||||
uint32 i; |
||||
uint32 c = 0x01; |
||||
|
||||
for (i = 1; i < 5; i++) { |
||||
if (banks[0].cas_lat & c) { |
||||
banks[0].cas_used = i; |
||||
banks[1].cas_used = i; |
||||
debug ("Using CAS %d (fast)\n", i); |
||||
return; |
||||
} |
||||
c <<= 1; |
||||
} |
||||
|
||||
/* Default to CAS 3 */ |
||||
banks[0].cas_used = 3; |
||||
banks[1].cas_used = 3; |
||||
debug ("Using CAS 3 (fast)\n"); |
||||
|
||||
return; |
||||
} else { |
||||
/* Search for slow cas */ |
||||
uint32 i; |
||||
uint32 c = 0x08; |
||||
|
||||
for (i = 4; i > 1; i--) { |
||||
if (banks[0].cas_lat & c) { |
||||
banks[0].cas_used = i; |
||||
banks[1].cas_used = i; |
||||
debug ("Using CAS %d (slow)\n", i); |
||||
return; |
||||
} |
||||
c >>= 1; |
||||
} |
||||
|
||||
/* Default to CAS 3 */ |
||||
banks[0].cas_used = 3; |
||||
banks[1].cas_used = 3; |
||||
debug ("Using CAS 3 (slow)\n"); |
||||
|
||||
return; |
||||
} |
||||
|
||||
banks[0].cas_used = 3; |
||||
banks[1].cas_used = 3; |
||||
debug ("Using CAS 3\n"); |
||||
|
||||
return; |
||||
} |
||||
|
||||
uint32 get_reg_setting (uint32 banks, uint32 rows, uint32 columns, uint32 size) |
||||
{ |
||||
uint32 i; |
||||
|
||||
struct RowColumnSize { |
||||
uint32 banks; |
||||
uint32 rows; |
||||
uint32 columns; |
||||
uint32 size; |
||||
uint32 register_value; |
||||
}; |
||||
|
||||
struct RowColumnSize rcs_map[] = { |
||||
/* Sbk Radr Cadr MB Value */ |
||||
{1, 11, 8, 8, 0x00840f00}, |
||||
{1, 11, 9, 16, 0x00925f00}, |
||||
{1, 11, 10, 32, 0x00a64f00}, |
||||
{2, 12, 8, 32, 0x00c55f00}, |
||||
{2, 12, 9, 64, 0x00d66f00}, |
||||
{2, 12, 10, 128, 0x00e77f00}, |
||||
{2, 12, 11, 256, 0x00ff8f00}, |
||||
{2, 13, 11, 512, 0x00ff9f00}, |
||||
{0, 0, 0, 0, 0x00000000} |
||||
}; |
||||
|
||||
|
||||
i = 0; |
||||
|
||||
while (rcs_map[i].banks != 0) { |
||||
if (rows == rcs_map[i].rows |
||||
&& columns == rcs_map[i].columns |
||||
&& (size / 1024 / 1024) == rcs_map[i].size) |
||||
return rcs_map[i].register_value; |
||||
|
||||
i++; |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
uint32 burst_to_len (uint32 support) |
||||
{ |
||||
if (support & 0x80) |
||||
return 0x7; |
||||
else if (support & 0x8) |
||||
return 0x3; |
||||
else if (support & 0x4) |
||||
return 0x2; |
||||
else if (support & 0x2) |
||||
return 0x1; |
||||
else if (support & 0x1) |
||||
return 0x0; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
long articiaS_ram_init (void) |
||||
{ |
||||
register uint32 i; |
||||
register uint32 value1; |
||||
register uint32 value2; |
||||
uint8 rom[128]; |
||||
uint32 burst_len; |
||||
uint32 burst_support; |
||||
uint32 total_ram = 0; |
||||
|
||||
struct dimm_bank banks[4]; /* FIXME: Move to initram */ |
||||
uint32 busclock = gd->bus_clk; |
||||
uint32 memclock = busclock; |
||||
uint32 reg32; |
||||
uint32 refresh_clocks; |
||||
uint8 auto_refresh; |
||||
|
||||
memset (banks, 0, sizeof (struct dimm_bank) * 4); |
||||
|
||||
detect_sdram (rom, 0, &banks[0]); |
||||
detect_sdram (rom, 1, &banks[2]); |
||||
|
||||
for (i = 0; i < 4; i++) { |
||||
total_ram = total_ram + (banks[i].used * banks[i].size); |
||||
} |
||||
|
||||
pci_write_cfg_long (0, 0, GLOBALINFO0, 0x117430c0); |
||||
pci_write_cfg_long (0, 0, HBUSACR0, 0x1f0100b0); |
||||
pci_write_cfg_long (0, 0, SRAM_CR, 0x00f12000); /* Note: Might also try 0x00f10000 (original: 0x00f12000) */ |
||||
pci_write_cfg_byte (0, 0, DRAM_RAS_CTL0, 0x3f); |
||||
pci_write_cfg_byte (0, 0, DRAM_RAS_CTL1, 0x00); /* was: 0x04); */ |
||||
pci_write_cfg_word (0, 0, DRAM_ECC0, 0x2020); /* was: 0x2400); No ECC yet */ |
||||
|
||||
/* FIXME: Move this stuff to seperate function, like setup_dimm_bank */ |
||||
if (banks[0].used) { |
||||
value1 = get_reg_setting (banks[0].used + banks[1].used, |
||||
banks[0].rows, banks[0].columns, |
||||
banks[0].size); |
||||
} else { |
||||
value1 = 0; |
||||
} |
||||
|
||||
if (banks[1].used) { |
||||
value2 = get_reg_setting (banks[0].used + banks[1].used, |
||||
banks[1].rows, banks[1].columns, |
||||
banks[1].size); |
||||
} else { |
||||
value2 = 0; |
||||
} |
||||
|
||||
pci_write_cfg_long (0, 0, DIMM0_B0_SCR0, value1); |
||||
pci_write_cfg_long (0, 0, DIMM0_B1_SCR0, value2); |
||||
|
||||
debug ("DIMM0_B0_SCR0 = 0x%08x\n", value1); |
||||
debug ("DIMM0_B1_SCR0 = 0x%08x\n", value2); |
||||
|
||||
if (banks[2].used) { |
||||
value1 = get_reg_setting (banks[2].used + banks[3].used, |
||||
banks[2].rows, banks[2].columns, |
||||
banks[2].size); |
||||
} else { |
||||
value1 = 0; |
||||
} |
||||
|
||||
if (banks[3].used) { |
||||
value2 = get_reg_setting (banks[2].used + banks[3].used, |
||||
banks[3].rows, banks[3].columns, |
||||
banks[3].size); |
||||
} else { |
||||
value2 = 0; |
||||
} |
||||
|
||||
pci_write_cfg_long (0, 0, DIMM1_B2_SCR0, value1); |
||||
pci_write_cfg_long (0, 0, DIMM1_B3_SCR0, value2); |
||||
|
||||
debug ("DIMM0_B2_SCR0 = 0x%08x\n", value1); |
||||
debug ("DIMM0_B3_SCR0 = 0x%08x\n", value2); |
||||
|
||||
pci_write_cfg_long (0, 0, DIMM2_B4_SCR0, 0); |
||||
pci_write_cfg_long (0, 0, DIMM2_B5_SCR0, 0); |
||||
pci_write_cfg_long (0, 0, DIMM3_B6_SCR0, 0); |
||||
pci_write_cfg_long (0, 0, DIMM3_B7_SCR0, 0); |
||||
|
||||
/* Determine timing */ |
||||
select_cas (&banks[0], 0); |
||||
select_cas (&banks[2], 0); |
||||
|
||||
/* FIXME: What about write recovery */ |
||||
/* Auto refresh Precharge */ |
||||
#if 0 |
||||
reg32 = (0x3 << 13) | (0x7 << 10) | ((banks[0].trp - 2) << 8) | |
||||
/* Write recovery CAS Latency */ |
||||
(0x1 << 6) | (banks[0].cas_used << 4) | |
||||
/* RAS/CAS latency */ |
||||
((banks[0].trcd - 1) << 0); |
||||
|
||||
reg32 |= ((0x3 << 13) | (0x7 << 10) | ((banks[2].trp - 2) << 8) | |
||||
(0x1 << 6) | (banks[2].cas_used << 4) | |
||||
((banks[2].trcd - 1) << 0)) << 16; |
||||
#else |
||||
if (100000000 == gd->bus_clk) |
||||
reg32 = 0x71737173; |
||||
else |
||||
reg32 = 0x69736973; |
||||
#endif |
||||
pci_write_cfg_long (0, 0, DIMM0_TCR0, reg32); |
||||
debug ("DIMM0_TCR0 = 0x%08x\n", reg32); |
||||
|
||||
/* Write default in DIMM2/3 (not used on A1) */ |
||||
pci_write_cfg_long (0, 0, DIMM2_TCR0, 0x7d737d73); |
||||
|
||||
|
||||
/* Determine buffered/unbuffered mode for each SIMM. Uses first bank as reference (second, if present, uses the same) */ |
||||
reg32 = pci_read_cfg_long (0, 0, DRAM_GCR0); |
||||
reg32 &= 0xFF00FFFF; |
||||
|
||||
#if 0 |
||||
if (banks[0].used && banks[0].registered) |
||||
reg32 |= 0x1 << 16; |
||||
|
||||
if (banks[2].used && banks[2].registered) |
||||
reg32 |= 0x1 << 18; |
||||
#else |
||||
if (banks[0].registered || banks[2].registered) |
||||
reg32 |= 0x55 << 16; |
||||
#endif |
||||
pci_write_cfg_long (0, 0, DRAM_GCR0, reg32); |
||||
debug ("DRAM_GCR0 = 0x%08x\n", reg32); |
||||
|
||||
/* Determine refresh */ |
||||
refresh_clocks = 0xffffffff; |
||||
auto_refresh = 1; |
||||
|
||||
for (i = 0; i < 4; i++) { |
||||
if (banks[i].used) { |
||||
if (banks[i].auto_refresh == 0) |
||||
auto_refresh = 0; |
||||
if (banks[i].refresh_time < refresh_clocks) |
||||
refresh_clocks = banks[i].refresh_time; |
||||
} |
||||
} |
||||
|
||||
|
||||
#if 1 |
||||
/* It seems this is suggested by the ArticiaS data book */ |
||||
if (100000000 == gd->bus_clk) |
||||
refresh_clocks = 1561; |
||||
else |
||||
refresh_clocks = 2083; |
||||
#endif |
||||
|
||||
|
||||
debug ("Refresh set to %ld clocks, auto refresh %s\n", |
||||
refresh_clocks, auto_refresh ? "on" : "off"); |
||||
|
||||
pci_write_cfg_long (0, 0, DRAM_REFRESH0, |
||||
(1 << 16) | (1 << 15) | (auto_refresh << 12) | |
||||
(refresh_clocks)); |
||||
debug ("DRAM_REFRESH0 = 0x%08x\n", |
||||
(1 << 16) | (1 << 15) | (auto_refresh << 12) | |
||||
(refresh_clocks)); |
||||
|
||||
/* pci_write_cfg_long(0, 0, DRAM_REFRESH0, 0x00019400); */ |
||||
|
||||
/* Set mode registers */ |
||||
/* FIXME: For now, set same burst len for all modules. Dunno if that's necessary */ |
||||
/* Find a common burst len */ |
||||
burst_support = 0xff; |
||||
|
||||
if (banks[0].used) |
||||
burst_support = banks[0].burst_len; |
||||
if (banks[1].used) |
||||
burst_support = banks[1].burst_len; |
||||
if (banks[2].used) |
||||
burst_support = banks[2].burst_len; |
||||
if (banks[3].used) |
||||
burst_support = banks[3].burst_len; |
||||
|
||||
/*
|
||||
** Mode register: |
||||
** Bits Use |
||||
** 0-2 Burst len |
||||
** 3 Burst type (0 = sequential, 1 = interleave) |
||||
** 4-6 CAS latency |
||||
** 7-8 Operation mode (0 = default, all others invalid) |
||||
** 9 Write burst |
||||
** 10-11 Reserved |
||||
** |
||||
** Mode register burst table: |
||||
** A2 A1 A0 lenght |
||||
** 0 0 0 1 |
||||
** 0 0 1 2 |
||||
** 0 1 0 4 |
||||
** 0 1 1 8 |
||||
** 1 0 0 invalid |
||||
** 1 0 1 invalid |
||||
** 1 1 0 invalid |
||||
** 1 1 1 page (only valid for non-interleaved) |
||||
*/ |
||||
|
||||
burst_len = burst_to_len (burst_support); |
||||
burst_len = 2; /* FIXME */ |
||||
|
||||
if (banks[0].used) { |
||||
pci_write_cfg_word (0, 0, DRAM_PCR0, |
||||
0x8000 | burst_len | (banks[0].cas_used << 4)); |
||||
debug ("Mode bank 0: 0x%08x\n", |
||||
0x8000 | burst_len | (banks[0].cas_used << 4)); |
||||
} else { |
||||
/* Seems to be needed to disable the bank */ |
||||
pci_write_cfg_word (0, 0, DRAM_PCR0, 0x0000 | 0x032); |
||||
} |
||||
|
||||
if (banks[1].used) { |
||||
pci_write_cfg_word (0, 0, DRAM_PCR0, |
||||
0x9000 | burst_len | (banks[1].cas_used << 4)); |
||||
debug ("Mode bank 1: 0x%08x\n", |
||||
0x8000 | burst_len | (banks[1].cas_used << 4)); |
||||
} else { |
||||
/* Seems to be needed to disable the bank */ |
||||
pci_write_cfg_word (0, 0, DRAM_PCR0, 0x1000 | 0x032); |
||||
} |
||||
|
||||
|
||||
if (banks[2].used) { |
||||
pci_write_cfg_word (0, 0, DRAM_PCR0, |
||||
0xa000 | burst_len | (banks[2].cas_used << 4)); |
||||
debug ("Mode bank 2: 0x%08x\n", |
||||
0x8000 | burst_len | (banks[2].cas_used << 4)); |
||||
} else { |
||||
/* Seems to be needed to disable the bank */ |
||||
pci_write_cfg_word (0, 0, DRAM_PCR0, 0x2000 | 0x032); |
||||
} |
||||
|
||||
|
||||
if (banks[3].used) { |
||||
pci_write_cfg_word (0, 0, DRAM_PCR0, |
||||
0xb000 | burst_len | (banks[3].cas_used << 4)); |
||||
debug ("Mode bank 3: 0x%08x\n", |
||||
0x8000 | burst_len | (banks[3].cas_used << 4)); |
||||
} else { |
||||
/* Seems to be needed to disable the bank */ |
||||
pci_write_cfg_word (0, 0, DRAM_PCR0, 0x3000 | 0x032); |
||||
} |
||||
|
||||
|
||||
pci_write_cfg_word (0, 0, 0xba, 0x00); |
||||
|
||||
return total_ram; |
||||
} |
||||
|
||||
extern int drv_isa_kbd_init (void); |
||||
|
||||
int last_stage_init (void) |
||||
{ |
||||
drv_isa_kbd_init (); |
||||
return 0; |
||||
} |
||||
|
||||
int overwrite_console (void) |
||||
{ |
||||
return (0); |
||||
} |
||||
|
||||
#define in_8 read_byte |
||||
#define out_8 write_byte |
||||
|
||||
static __inline__ unsigned long get_msr (void) |
||||
{ |
||||
unsigned long msr; |
||||
|
||||
asm volatile ("mfmsr %0":"=r" (msr):); |
||||
|
||||
return msr; |
||||
} |
||||
|
||||
static __inline__ void set_msr (unsigned long msr) |
||||
{ |
||||
asm volatile ("mtmsr %0"::"r" (msr)); |
||||
} |
||||
|
||||
int board_early_init_f (void) |
||||
{ |
||||
unsigned char c_value = 0; |
||||
unsigned long msr; |
||||
|
||||
/* Basic init of PS/2 keyboard (needed for some reason)... */ |
||||
/* Ripped from John's code */ |
||||
while ((in_8 ((unsigned char *) 0xfe000064) & 0x02) != 0); |
||||
out_8 ((unsigned char *) 0xfe000064, 0xaa); |
||||
while ((in_8 ((unsigned char *) 0xfe000064) & 0x01) == 0); |
||||
c_value = in_8 ((unsigned char *) 0xfe000060); |
||||
while ((in_8 ((unsigned char *) 0xfe000064) & 0x02) != 0); |
||||
out_8 ((unsigned char *) 0xfe000064, 0xab); |
||||
while ((in_8 ((unsigned char *) 0xfe000064) & 0x01) == 0); |
||||
c_value = in_8 ((unsigned char *) 0xfe000060); |
||||
while ((in_8 ((unsigned char *) 0xfe000064) & 0x02) != 0); |
||||
out_8 ((unsigned char *) 0xfe000064, 0xae); |
||||
/* while ((in_8((unsigned char *)0xfe000064) & 0x01) == 0); */ |
||||
/* c_value = in_8((unsigned char *)0xfe000060); */ |
||||
|
||||
/* Enable FPU */ |
||||
msr = get_msr (); |
||||
set_msr (msr | MSR_FP); |
||||
|
||||
via_calibrate_bus_freq (); |
||||
|
||||
return 0; |
||||
} |
@ -1,142 +0,0 @@ |
||||
#ifndef ARTICIAS_H |
||||
#define ARTICIAS_H |
||||
|
||||
#include "short_types.h" |
||||
#include <common.h> |
||||
|
||||
#define REG_GROUP 0xF0 |
||||
|
||||
/* ArticiaS registers */ |
||||
#define GLOBALINFO0 0x50 |
||||
#define GLOBALINFO1 0x51 |
||||
#define GLOBALINFO2 0x52 |
||||
#define GLOBALINFO3 0x53 |
||||
#define GLOBALCTL0 0x54 |
||||
#define GLOBALCTL1 0x55 |
||||
#define NVRAMCTL 0x56 |
||||
#define PCI1ACR0 0x58 |
||||
#define PCI1ACR1 0x59 |
||||
#define PCI1ACR2 0x5a |
||||
#define PCI1ACR3 0x5b |
||||
#define HBUSACR0 0x5c |
||||
#define HBUSACR1 0x5d |
||||
#define HBUSACR2 0x5e |
||||
#define HBUSACR3 0x5f |
||||
#define HOSTINT0 0x68 |
||||
#define HOSTINT1 0x69 |
||||
#define HOSTINT2 0x6a |
||||
#define HOSTINT3 0x6b |
||||
#define HOSTRBCR 0x70 |
||||
#define XDBCR 0x74 |
||||
|
||||
#define LBSBCR2 0xd2 |
||||
|
||||
|
||||
/* Memory controller */ |
||||
|
||||
#define DIMM0_B0_SCR0 0x90 |
||||
#define DIMM0_B1_SCR0 0x94 |
||||
#define DIMM1_B2_SCR0 0x98 |
||||
#define DIMM1_B3_SCR0 0x9c |
||||
#define DIMM2_B4_SCR0 0xa0 |
||||
#define DIMM2_B5_SCR0 0xa4 |
||||
#define DIMM3_B6_SCR0 0xa8 |
||||
#define DIMM3_B7_SCR0 0xac |
||||
|
||||
#define DIMM0_TCR0 0xb0 |
||||
#define DIMM1_TCR0 0xb2 |
||||
#define DIMM2_TCR0 0xb4 |
||||
#define DIMM3_TCR0 0xb6 |
||||
|
||||
#define DRAM_REFRESH0 0xb8 |
||||
#define DRAM_GCR0 0xc0 |
||||
#define DRAM_PCR0 0xc6 |
||||
#define DRAM_ECC0 0xc4 |
||||
#define SRAM_CR 0xc8 |
||||
#define DRAM_RAS_CTL0 0xcc |
||||
#define DRAM_RAS_CTL1 0xcd |
||||
|
||||
/* Bits for REG_GROUP */ |
||||
#define REG_GROUP_MULTI (1<<1) |
||||
#define REG_GROUP_SPECIAL (1<<3) |
||||
#define REG_GROUP_DIAG (0x1<<4) |
||||
#define REG_GROUP_POWER (0x2<<4) |
||||
|
||||
|
||||
#define GLOBALINFO0_BO (1<<7) |
||||
|
||||
|
||||
#define GLOBALINFO2_B1ARBITER (1<<6) |
||||
|
||||
|
||||
#define HBUSACR0_CPUAPC (1<<0) |
||||
#define HBUSACR0_NUMREQ_2 (0<<1) |
||||
#define HBUSACR0_NUMREQ_3 (1<<1) |
||||
#define HBUSACR0_NUMREQ_4 (2<<1) |
||||
#define HBUSACR0_NUMREQ_MASK (7<<1) |
||||
#define HBUSACR0_RAW (1<<6) |
||||
#define HBUSACR0_WAIT (1<<7) |
||||
#define HBUSACR0_RESERVED (0x30) |
||||
|
||||
|
||||
#define HBUSACR2_BURST (1<<0) |
||||
#define HBUSACR2_LAT (1<<1) |
||||
|
||||
|
||||
#define HBUSACR3_LMWC_SM (1<<0) |
||||
#define HBUSACR3_LMWC_PCI1 (1<<1) |
||||
#define HBUSACR3_LMWC_PCI0 (1<<2) |
||||
#define HBUSACR3_PMWC_PCI1 (1<<3) |
||||
#define HBUSACR3_PMWC_PCI0 (1<<4) |
||||
#define HBUSACR3_FKH (1<<5) |
||||
#define HBUSACR3_92H_EN (1<<6) |
||||
#define HBUSACR3_60H_64H_EN (1<<7) |
||||
|
||||
|
||||
#define HOSTRBCR_PREFETCH (1<<4) |
||||
|
||||
|
||||
#define XDBCR_HWTOXD (1<<0) |
||||
#define XDBCR_KBTOXD (1<<1) |
||||
#define XDBCR_RTCTOXD (1<<2) |
||||
#define XDBCR_SCALE_1_1 (0x0<<3) |
||||
#define XDBCR_SCALE_2_2 (0x1<<3) |
||||
#define XDBCR_SCALE_3_2 (0x2<<3) |
||||
#define XDBCR_SCALE_4_4 (0x3<<3) |
||||
#define XDBCR_SCALE_5_8 (0x4<<3) |
||||
#define XDBCR_SCALE_6_8 (0x5<<3) |
||||
#define XDBCR_SCALE_8_8 (0x6<<3) |
||||
#define XDBCR_SCALE_0_16 (0x7<<3) |
||||
#define XDBCR_XDPROM (1<<7) |
||||
|
||||
|
||||
#define LBSBCR2_1_RWAC (1<<2) |
||||
|
||||
|
||||
/* PCI controller */ |
||||
#define ARTICIAS_PCI_CFGADDR 0xfec00cf8 |
||||
#define ARTICIAS_PCI_CFGDATA 0xfee00cfc |
||||
|
||||
#define ARTICIAS_PCI_BUS 0x80000000 |
||||
#define ARTICIAS_PCI_MAXSIZE 0x7cffffff |
||||
#define ARTICIAS_PCI_PHYS 0x80000000 |
||||
|
||||
#define ARTICIAS_SYS_BUS 0x00000000 |
||||
#define ARTICIAS_SYS_MAXSIZE 0x7fffffff |
||||
#define ARTICIAS_SYS_PHYS 0x00000000 |
||||
|
||||
#define ARTICIAS_PCIIO_BUS 0x00800000 |
||||
#define ARTICIAS_PCIIO_MAXSIZE 0x003fffff |
||||
#define ARTICIAS_PCIIO_PHYS 0xfe800000 |
||||
|
||||
#define ARTICIAS_ISAIO_BUS 0x00002000 |
||||
#define ARTICIAS_ISAIO_MAXSIZE 0x0000d000 |
||||
#define ARTICIAS_ISAIO_PHYS 0xfe002000 |
||||
|
||||
|
||||
/* Prototypes */ |
||||
long articiaS_ram_init(void); |
||||
void articiaS_pci_init(void); |
||||
|
||||
|
||||
#endif |
@ -1,576 +0,0 @@ |
||||
/*
|
||||
* (C) Copyright 2002 |
||||
* Hyperion Entertainment, Hans-JoergF@hyperion-entertainment.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 <pci.h> |
||||
#include "memio.h" |
||||
#include "articiaS.h" |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
#undef ARTICIA_PCI_DEBUG |
||||
|
||||
#ifdef ARTICIA_PCI_DEBUG |
||||
#define PRINTF(fmt,args...) printf (fmt ,##args) |
||||
#else |
||||
#define PRINTF(fmt,args...) |
||||
#endif |
||||
|
||||
struct pci_controller articiaS_hose; |
||||
|
||||
long irq_alloc(long wanted); |
||||
|
||||
static pci_dev_t pci_hose_find_class(struct pci_controller *hose, int bus, short find_class, int index); |
||||
static int articiaS_init_vga(void); |
||||
static void pci_cfgfunc_dummy(struct pci_controller *host, pci_dev_t dev, struct pci_config_table *table); |
||||
unsigned char pci_irq_alloc(void); |
||||
|
||||
extern void via_cfgfunc_via686(struct pci_controller * host, pci_dev_t dev, struct pci_config_table *table); |
||||
extern void via_cfgfunc_ide_init(struct pci_controller *host, pci_dev_t dev, struct pci_config_table *table); |
||||
extern void via_init_irq_routing(uint8 []); |
||||
extern void via_init_afterscan(void); |
||||
|
||||
#define cfgfunc_via686 1 |
||||
#define cfgfunc_dummy 2 |
||||
#define cfgfunc_ide_init 3 |
||||
|
||||
static struct pci_config_table config_table[] = |
||||
{ |
||||
{ |
||||
0x1106, PCI_ANY_ID, PCI_CLASS_BRIDGE_ISA, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
||||
(void *)cfgfunc_via686, {0, 0, 0} |
||||
}, |
||||
{ |
||||
0x1106, PCI_ANY_ID, PCI_ANY_ID, 0,7,4, |
||||
(void *)cfgfunc_dummy, {0,0,0} |
||||
}, |
||||
{ |
||||
0x1106, 0x3068, PCI_ANY_ID, 0, 7, PCI_ANY_ID, |
||||
(void *)cfgfunc_dummy, {0,0,0} |
||||
}, |
||||
{ |
||||
0x1106, PCI_ANY_ID, PCI_ANY_ID, 0,7,1, |
||||
(void *)cfgfunc_ide_init, {0,0,0} |
||||
}, |
||||
{ |
||||
0, |
||||
} |
||||
}; |
||||
|
||||
|
||||
void pci_cfgfunc_dummy(struct pci_controller *host, pci_dev_t dev, struct pci_config_table *table) |
||||
{ |
||||
|
||||
|
||||
} |
||||
|
||||
unsigned long irq_penalties[16] = |
||||
{ |
||||
1000, /* 0:timer */ |
||||
1000, /* 1:keyboard */ |
||||
1000, /* 2:cascade */ |
||||
50, /* 3:serial (COM2) */ |
||||
50, /* 4:serial (COM1) */ |
||||
4, /* 5:USB2 */ |
||||
100, /* 6:floppy */ |
||||
3, /* 7:parallel */ |
||||
50, /* 8:AC97/MC97 */ |
||||
0, /* 9: */ |
||||
3, /* 10:: */ |
||||
0, /* 11: */ |
||||
3, /* 12: USB1 */ |
||||
0, /* 13: */ |
||||
100, /* 14: ide0 */ |
||||
100, /* 15: ide1 */ |
||||
}; |
||||
|
||||
|
||||
/*
|
||||
* The following defines a hard-coded interrupt mapping for the |
||||
* know devices on the board. |
||||
* If a device isn't found here, assumed to be a device that's |
||||
* plugged into a PCI or AGP slot |
||||
* NOTE: This table is machine dependant. |
||||
*/ |
||||
|
||||
struct pci_irq_fixup_table |
||||
{ |
||||
uint8 bus; /* Bus number */ |
||||
uint8 device; /* Device number */ |
||||
uint8 func; /* Function number */ |
||||
uint8 interrupt; /* Interrupt to use (0xff to disable) */ |
||||
}; |
||||
|
||||
struct pci_irq_fixup_table fixuptab [] = |
||||
{ |
||||
{ 0, 0, 0, 0xff}, /* Articia S host bridge */ |
||||
{ 0, 1, 0, 0xff}, /* Articia S AGP bridge */ |
||||
/* { 0, 6, 0, 0x05}, /###* 3COM ethernet */ |
||||
{ 0, 7, 0, 0xff}, /* VIA southbridge */ |
||||
{ 0, 7, 1, 0x0e}, /* IDE controller in legacy mode */ |
||||
/* { 0, 7, 2, 0x05}, /###* First USB controller */ |
||||
/* { 0, 7, 3, 0x0c}, /###* Second USB controller (shares interrupt with ethernet) */ |
||||
{ 0, 7, 4, 0xff}, /* ACPI Power Management */ |
||||
/* { 0, 7, 5, 0x08}, /###* AC97 */ |
||||
/* { 0, 7, 6, 0x08}, /###* MC97 */ |
||||
{ 0xff, 0xff, 0xff, 0xff} |
||||
}; |
||||
|
||||
|
||||
/*
|
||||
* This table maps IRQ's to PCI interrupts |
||||
*/ |
||||
|
||||
uint8 pci_intmap[4] = {0, 0, 0, 0}; |
||||
|
||||
/*
|
||||
* Map PCI slots to interrupt routings |
||||
* This table lists the device number assigned to a card inserted |
||||
* into the slot, along with a permutation for the slot's IRQ routing. |
||||
* NOTE: This table is machine dependant. |
||||
*/ |
||||
|
||||
struct pci_slot_irq_routing |
||||
{ |
||||
uint8 bus; |
||||
uint8 device; |
||||
|
||||
uint8 ints[4]; |
||||
}; |
||||
|
||||
struct pci_slot_irq_routing amigaone_pci_routing[] = |
||||
{ |
||||
{0, 8, {0, 1, 2, 3}}, /* Slot 1 (left of riser slot) */ |
||||
{0, 9, {1, 2, 3, 0}}, /* Slot 2 (middle slot) */ |
||||
{0, 10, {2, 3, 0, 1}}, /* Slot 3 (leftmost slot) */ |
||||
{1, 0, {1, 0, 2, 3}}, /* AGP slot (only IRQA and IRQB) */ |
||||
{1, 1, {1, 2, 3, 0}}, /* PCI slot on AGP bus */ |
||||
{0, 6, {3, 3, 3, 3}}, /* On board ethernet */ |
||||
{0, 7, {0, 1, 2, 3}}, /* Southbridge */ |
||||
{0xff, 0, {0, 0, 0, 0}} |
||||
}; |
||||
|
||||
void articiaS_pci_irq_init(void) |
||||
{ |
||||
char *s; |
||||
|
||||
s = getenv("pci_irqa"); |
||||
if (s) |
||||
pci_intmap[0] = simple_strtoul (s, NULL, 10); |
||||
else |
||||
pci_intmap[0] = pci_irq_alloc(); |
||||
|
||||
s = getenv("pci_irqb"); |
||||
if (s) |
||||
pci_intmap[1] = simple_strtoul (s, NULL, 10); |
||||
else |
||||
pci_intmap[1] = pci_irq_alloc(); |
||||
|
||||
s = getenv("pci_irqc"); |
||||
if (s) |
||||
pci_intmap[2] = simple_strtoul (s, NULL, 10); |
||||
else |
||||
pci_intmap[2] = pci_irq_alloc(); |
||||
|
||||
s = getenv("pci_irqd"); |
||||
if (s) |
||||
pci_intmap[3] = simple_strtoul (s, NULL, 10); |
||||
else |
||||
pci_intmap[3] = pci_irq_alloc(); |
||||
} |
||||
|
||||
|
||||
unsigned char pci_irq_alloc(void) |
||||
{ |
||||
int i; |
||||
int interrupt = 10; |
||||
unsigned long min_penalty = 1000; |
||||
|
||||
/* Search for the minimal penalty, favoring interrupts at the end */ |
||||
for (i = 0; i < 16; i++) |
||||
{ |
||||
if (irq_penalties[i] <= min_penalty) |
||||
{ |
||||
interrupt = i; |
||||
min_penalty = irq_penalties[i]; |
||||
} |
||||
} |
||||
|
||||
PRINTF("pci_irq_alloc: Minimal penalty is %ld for %d\n", min_penalty, interrupt); |
||||
|
||||
irq_penalties[interrupt]++; |
||||
|
||||
return interrupt; |
||||
} |
||||
|
||||
|
||||
void articiaS_pci_fixup_irq(struct pci_controller *hose, pci_dev_t dev) |
||||
{ |
||||
int8 bus, device, func, pin, line; |
||||
int i; |
||||
|
||||
bus = PCI_BUS(dev); |
||||
device = PCI_DEV(dev); |
||||
func = PCI_FUNC(dev); |
||||
|
||||
PRINTF("Fixup irq of %d:%d.%d\n", bus, device, func); |
||||
|
||||
/* Search for the device in the table */ |
||||
for (i = 0; fixuptab[i].bus != 0xff; i++) |
||||
{ |
||||
if (bus == fixuptab[i].bus && device == fixuptab[i].device && func == fixuptab[i].func) |
||||
{ |
||||
/* If the device needs an interrupt, write it */ |
||||
if (fixuptab[i].interrupt != 0xff) |
||||
{ |
||||
PRINTF("Assigning IRQ %d (fixed)\n", fixuptab[i].interrupt); |
||||
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, fixuptab[i].interrupt); |
||||
} |
||||
else |
||||
{ |
||||
/* Otherwise, see if it wants an interrupt, and disable it if needed */ |
||||
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); |
||||
if (pin) |
||||
{ |
||||
PRINTF("Disabling IRQ\n"); |
||||
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 0xff); |
||||
} |
||||
} |
||||
|
||||
return; |
||||
} |
||||
} |
||||
|
||||
/* If we get here, we have another PCI device in a slot... find the appropriate IRQ */ |
||||
|
||||
/* Find matching pin */ |
||||
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); |
||||
pin--; |
||||
|
||||
/* Search for it's map */ |
||||
for (i = 0; amigaone_pci_routing[i].bus != 0xff; i++) |
||||
{ |
||||
if (bus == amigaone_pci_routing[i].bus && device == amigaone_pci_routing[i].device) |
||||
{ |
||||
line = pci_intmap[amigaone_pci_routing[i].ints[pin]]; |
||||
PRINTF("Assigning IRQ %d (pin %d)\n", line, pin); |
||||
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, line); |
||||
return; |
||||
} |
||||
} |
||||
|
||||
PRINTF("Unkonwn PCI device found\n"); |
||||
} |
||||
|
||||
void articiaS_pci_init (void) |
||||
{ |
||||
int i; |
||||
char *s; |
||||
|
||||
PRINTF("atriciaS_pci_init\n"); |
||||
|
||||
/* Why aren't these relocated?? */ |
||||
for (i=0; config_table[i].config_device; i++) |
||||
{ |
||||
switch((int)config_table[i].config_device) |
||||
{ |
||||
case cfgfunc_via686: config_table[i].config_device = via_cfgfunc_via686; break; |
||||
case cfgfunc_dummy: config_table[i].config_device = pci_cfgfunc_dummy; break; |
||||
case cfgfunc_ide_init: config_table[i].config_device = via_cfgfunc_ide_init; break; |
||||
default: PRINTF("Error: Unknown constant\n"); |
||||
} |
||||
} |
||||
|
||||
articiaS_hose.first_busno = 0; |
||||
articiaS_hose.last_busno = 0xff; |
||||
articiaS_hose.config_table = config_table; |
||||
articiaS_hose.fixup_irq = articiaS_pci_fixup_irq; |
||||
|
||||
articiaS_pci_irq_init(); |
||||
|
||||
/* System memory */ |
||||
pci_set_region(articiaS_hose.regions + 0, |
||||
ARTICIAS_SYS_BUS, |
||||
ARTICIAS_SYS_PHYS, |
||||
ARTICIAS_SYS_MAXSIZE, |
||||
PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); |
||||
|
||||
/* PCI memory space */ |
||||
pci_set_region(articiaS_hose.regions + 1, |
||||
ARTICIAS_PCI_BUS, |
||||
ARTICIAS_PCI_PHYS, |
||||
ARTICIAS_PCI_MAXSIZE, |
||||
PCI_REGION_MEM); |
||||
|
||||
/* PCI io space */ |
||||
pci_set_region(articiaS_hose.regions + 2, |
||||
ARTICIAS_PCIIO_BUS, |
||||
ARTICIAS_PCIIO_PHYS, |
||||
ARTICIAS_PCIIO_MAXSIZE, |
||||
PCI_REGION_IO); |
||||
|
||||
/* PCI/ISA io space */ |
||||
pci_set_region(articiaS_hose.regions + 3, |
||||
ARTICIAS_ISAIO_BUS, |
||||
ARTICIAS_ISAIO_PHYS, |
||||
ARTICIAS_ISAIO_MAXSIZE, |
||||
PCI_REGION_IO); |
||||
|
||||
|
||||
articiaS_hose.region_count = 4; |
||||
|
||||
pci_setup_indirect(&articiaS_hose, ARTICIAS_PCI_CFGADDR, ARTICIAS_PCI_CFGDATA); |
||||
PRINTF("Registering articia hose...\n"); |
||||
pci_register_hose(&articiaS_hose); |
||||
PRINTF("Enabling AGP...\n"); |
||||
pci_write_config_byte(PCI_BDF(0,0,0), 0x58, 0x01); |
||||
PRINTF("Scanning bus...\n"); |
||||
articiaS_hose.last_busno = pci_hose_scan(&articiaS_hose); |
||||
|
||||
via_init_irq_routing(pci_intmap); |
||||
|
||||
PRINTF("After-Scan results:\n"); |
||||
PRINTF("Bus range: %d - %d\n", articiaS_hose.first_busno , articiaS_hose.last_busno); |
||||
|
||||
via_init_afterscan(); |
||||
|
||||
pci_write_config_byte(PCI_BDF(0,1,0), PCI_INTERRUPT_LINE, 0xFF); |
||||
|
||||
s = getenv("as_irq"); |
||||
if (s) |
||||
{ |
||||
pci_write_config_byte(PCI_BDF(0,0,0), PCI_INTERRUPT_LINE, simple_strtoul (s, NULL, 10)); |
||||
} |
||||
|
||||
s = getenv("x86_run_bios"); |
||||
if (!s || (s && strcmp(s, "on")==0)) |
||||
{ |
||||
if (articiaS_init_vga() == -1) |
||||
{ |
||||
/* If the VGA didn't init and we have stdout set to VGA, reset to serial */ |
||||
/* s = getenv("stdout"); */ |
||||
/* if (s && strcmp(s, "vga") == 0) */ |
||||
/* { */ |
||||
/* setenv("stdout", "serial"); */ |
||||
/* } */ |
||||
} |
||||
} |
||||
pci_write_config_byte(PCI_BDF(0,1,0), PCI_INTERRUPT_LINE, 0xFF); |
||||
|
||||
} |
||||
|
||||
pci_dev_t pci_hose_find_class(struct pci_controller *hose, int bus, short find_class, int index) |
||||
{ |
||||
unsigned int sub_bus, found_multi=0; |
||||
unsigned short vendor, class; |
||||
unsigned char header_type; |
||||
pci_dev_t dev; |
||||
u8 c1, c2; |
||||
|
||||
sub_bus = bus; |
||||
|
||||
for (dev = PCI_BDF(bus,0,0); |
||||
dev < PCI_BDF(bus,PCI_MAX_PCI_DEVICES-1,PCI_MAX_PCI_FUNCTIONS-1); |
||||
dev += PCI_BDF(0,0,1)) |
||||
{ |
||||
if ( dev == PCI_BDF(hose->first_busno,0,0) ) |
||||
continue; |
||||
|
||||
if (PCI_FUNC(dev) && !found_multi) |
||||
continue; |
||||
|
||||
pci_hose_read_config_byte(hose, dev, PCI_HEADER_TYPE, &header_type); |
||||
|
||||
pci_hose_read_config_word(hose, dev, PCI_VENDOR_ID, &vendor); |
||||
|
||||
if (vendor != 0xffff && vendor != 0x0000) |
||||
{ |
||||
|
||||
if (!PCI_FUNC(dev)) |
||||
found_multi = header_type & 0x80; |
||||
pci_hose_read_config_byte(hose, dev, 0x0B, &c1); |
||||
pci_hose_read_config_byte(hose, dev, 0x0A, &c2); |
||||
class = c1<<8 | c2; |
||||
/*printf("At %02x:%02x:%02x: class %x\n", */ |
||||
/* PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev), class); */ |
||||
if (class == find_class) |
||||
{ |
||||
if (index == 0) |
||||
return dev; |
||||
else index--; |
||||
} |
||||
} |
||||
} |
||||
|
||||
return ~0; |
||||
} |
||||
|
||||
|
||||
/*
|
||||
* For a given bus number, find the bridge on this hose that provides this |
||||
* bus number. The function scans for bridges and peeks config space offset |
||||
* 0x19 (PCI_SECONDARY_BUS). |
||||
*/ |
||||
pci_dev_t pci_find_bridge_for_bus(struct pci_controller *hose, int busnr) |
||||
{ |
||||
pci_dev_t dev; |
||||
int bus; |
||||
unsigned int found_multi=0; |
||||
unsigned char header_type; |
||||
unsigned short vendor; |
||||
unsigned char secondary_bus; |
||||
|
||||
if (hose == NULL) hose = &articiaS_hose; |
||||
|
||||
if (busnr < hose->first_busno || busnr > hose->last_busno) return PCI_ANY_ID; /* Not in range */ |
||||
|
||||
/*
|
||||
* The bridge must be on a lower bus number |
||||
*/ |
||||
for (bus = hose->first_busno; bus < busnr; bus++) |
||||
{ |
||||
for (dev = PCI_BDF(bus,0,0); |
||||
dev < PCI_BDF(bus,PCI_MAX_PCI_DEVICES-1,PCI_MAX_PCI_FUNCTIONS-1); |
||||
dev += PCI_BDF(0,0,1)) |
||||
{ |
||||
if ( dev == PCI_BDF(hose->first_busno,0,0) ) |
||||
continue; |
||||
|
||||
if (PCI_FUNC(dev) && !found_multi) |
||||
continue; |
||||
|
||||
pci_hose_read_config_byte(hose, dev, PCI_HEADER_TYPE, &header_type); |
||||
|
||||
pci_hose_read_config_word(hose, dev, PCI_VENDOR_ID, &vendor); |
||||
|
||||
if (vendor != 0xffff && vendor != 0x0000) |
||||
{ |
||||
|
||||
if (!PCI_FUNC(dev)) |
||||
found_multi = header_type & 0x80; |
||||
if (header_type == 1) /* Bridge device header */ |
||||
{ |
||||
pci_hose_read_config_byte(hose, dev, PCI_SECONDARY_BUS, &secondary_bus); |
||||
if ((int)secondary_bus == busnr) return dev; |
||||
} |
||||
|
||||
} |
||||
} |
||||
} |
||||
return PCI_ANY_ID; |
||||
} |
||||
|
||||
static short classes[] = |
||||
{ |
||||
PCI_CLASS_DISPLAY_VGA, |
||||
PCI_CLASS_DISPLAY_XGA, |
||||
PCI_CLASS_DISPLAY_3D, |
||||
PCI_CLASS_DISPLAY_OTHER, |
||||
~0 |
||||
}; |
||||
|
||||
extern int execute_bios(pci_dev_t gr_dev, void *); |
||||
|
||||
pci_dev_t video_dev; |
||||
|
||||
int articiaS_init_vga (void) |
||||
{ |
||||
extern void shutdown_bios(void); |
||||
pci_dev_t dev = ~0; |
||||
int busnr = 0; |
||||
int classnr = 0; |
||||
|
||||
video_dev = PCI_ANY_ID; |
||||
|
||||
printf("VGA: "); |
||||
|
||||
PRINTF("Trying to initialize x86 VGA Card(s)\n"); |
||||
|
||||
while (dev == ~0) |
||||
{ |
||||
PRINTF("Searching for class 0x%x on bus %d\n", classes[classnr], busnr); |
||||
/* Find the first of this class on this bus */ |
||||
dev = pci_hose_find_class(&articiaS_hose, busnr, classes[classnr], 0); |
||||
if (dev != ~0) |
||||
{ |
||||
PRINTF("Found VGA Card at %02x:%02x:%02x\n", PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev)); |
||||
break; |
||||
} |
||||
busnr++; |
||||
if (busnr > articiaS_hose.last_busno) |
||||
{ |
||||
busnr = 0; |
||||
classnr ++; |
||||
if (classes[classnr] == ~0) |
||||
{ |
||||
printf("NOT PRESENT\n"); |
||||
return -1; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/*
|
||||
* If we get here we have found the first graphics card. |
||||
* If the bus number is not 0, then it is probably behind a bridge, and the |
||||
* bridge needs to be told to forward VGA access. |
||||
*/ |
||||
|
||||
if (PCI_BUS(dev) != 0) |
||||
{ |
||||
pci_dev_t bridge; |
||||
PRINTF("Behind bridge, looking for bridge\n"); |
||||
bridge = pci_find_bridge_for_bus(&articiaS_hose, PCI_BUS(dev)); |
||||
if (dev != PCI_ANY_ID) |
||||
{ |
||||
unsigned char agp_control_0; |
||||
PRINTF("Got the bridge at %02x:%02x:%02x\n", |
||||
PCI_BUS(bridge), PCI_DEV(bridge), PCI_FUNC(bridge)); |
||||
pci_hose_read_config_byte(&articiaS_hose, bridge, 0x3E, &agp_control_0); |
||||
agp_control_0 |= 0x18; |
||||
pci_hose_write_config_byte(&articiaS_hose, bridge, 0x3E, agp_control_0); |
||||
PRINTF("Configured for VGA forwarding\n"); |
||||
} |
||||
} |
||||
|
||||
/*
|
||||
* Now try to run the bios |
||||
*/ |
||||
PRINTF("Trying to run bios now\n"); |
||||
if (execute_bios(dev, gd->relocaddr)) |
||||
{ |
||||
printf("OK\n"); |
||||
video_dev = dev; |
||||
} |
||||
else |
||||
{ |
||||
printf("ERROR\n"); |
||||
} |
||||
|
||||
PRINTF("Done scanning.\n"); |
||||
|
||||
shutdown_bios(); |
||||
|
||||
if (dev == PCI_ANY_ID) return -1; |
||||
else return 0; |
||||
|
||||
} |
@ -1,156 +0,0 @@ |
||||
#include "macros.h" |
||||
|
||||
|
||||
#define GLOBALINFO0 0x50 |
||||
#define GLOBALINFO0_BO (1<<7) |
||||
#define GLOBALINFO2_B1ARBITER (1<<6) |
||||
#define HBUSACR0 0x5c |
||||
#define HBUSACR2_BURST (1<<0) |
||||
#define HBUSACR2_LAT (1<<1) |
||||
|
||||
#define RECEIVER_HOLDING 0 |
||||
#define TRANSMITTER_HOLDING 0 |
||||
#define INTERRUPT_ENABLE 1 |
||||
#define INTERRUPT_STATUS 2 |
||||
#define FIFO_CONTROL 2 |
||||
#define LINE_CONTROL 3 |
||||
#define MODEM_CONTROL 4 |
||||
#define LINE_STATUS 5 |
||||
#define MODEM_STATUS 6 |
||||
#define SCRATCH_PAD 7 |
||||
|
||||
#define DIVISOR_LATCH_LSB 0 |
||||
#define DIVISOR_LATCH_MSB 1 |
||||
#define PRESCALER_DIVISION 5 |
||||
|
||||
#define UART(x) (0x3f8+(x)) |
||||
|
||||
#define GLOBALINFO0 0x50 |
||||
#define GLOBALINFO0_BO (1<<7) |
||||
#define GLOBALINFO2_B1ARBITER (1<<6) |
||||
#define HBUSACR0 0x5c |
||||
#define HBUSACR2_BURST (1<<0) |
||||
#define HBUSACR2_LAT (1<<1) |
||||
|
||||
#define SUPERIO_1 ((7 << 3) | (0)) |
||||
#define SUPERIO_2 ((7 << 3) | (1)) |
||||
|
||||
.globl board_asm_init
|
||||
|
||||
board_asm_init: |
||||
mflr r29 |
||||
/* Set 'Must-set' register */ |
||||
li r3, 0 |
||||
li r4, 0 |
||||
li r5, 0x5e |
||||
bl pci_read_cfg_byte |
||||
ori r3, r3, (1<<1) |
||||
xori r6, r3, (1<<1) |
||||
li r3, 0 |
||||
bl pci_write_cfg_byte |
||||
|
||||
li r3, 0 |
||||
li r5, 0x52 |
||||
bl pci_read_cfg_byte |
||||
ori r6, r3, (1<<6) |
||||
li r3, 0 |
||||
bl pci_write_cfg_byte |
||||
|
||||
li r3, 0 |
||||
li r4, 0x08 |
||||
li r5, 0xd2 |
||||
bl pci_read_cfg_byte |
||||
ori r6, r3, (1<<2) |
||||
li r3, 0 |
||||
bl pci_write_cfg_byte |
||||
|
||||
|
||||
/* Do PCI reset */ |
||||
/* li r3, 0 |
||||
li r4, 0x38 |
||||
li r5, 0x47 |
||||
bl pci_read_cfg_byte |
||||
ori r6, r3, 0x01 |
||||
li r3, 0 |
||||
li r4, 0x38 |
||||
li r5, 0x47 |
||||
bl pci_write_cfg_byte*/ |
||||
|
||||
|
||||
/* Enable NVRAM for environment */ |
||||
li r3, 0 |
||||
li r4, 0 |
||||
li r5, 0x56 |
||||
li r6, 0x0B |
||||
bl pci_write_cfg_byte |
||||
|
||||
|
||||
/* Init Super-I/O chips */ |
||||
|
||||
siowb 0x40, 0x08 |
||||
siowb 0x41, 0x01 |
||||
siowb 0x45, 0x80 |
||||
siowb 0x46, 0x60 |
||||
siowb 0x47, 0x20 |
||||
siowb 0x48, 0x01 |
||||
siowb 0x4a, 0xc4 |
||||
siowb 0x50, 0x0e |
||||
siowb 0x51, 0x76 |
||||
siowb 0x52, 0x34 |
||||
siowb 0x54, 0x00 |
||||
siowb 0x55, 0x90 |
||||
siowb 0x56, 0x99 |
||||
siowb 0x57, 0x90 |
||||
siowb 0x85, 0x01 |
||||
|
||||
/* Enable configuration mode for SuperIO */ |
||||
li r3, 0 |
||||
li r4, (7<<3) |
||||
li r5, 0x85 |
||||
bl pci_read_cfg_byte |
||||
ori r6, r3, 0x02 |
||||
mr r31, r6 |
||||
li r3,0 |
||||
bl pci_write_cfg_byte |
||||
|
||||
/* COM1 as 3f8 */ |
||||
outb 0x3f0, 0xe7 |
||||
outb 0x3f1, 0xfe |
||||
|
||||
/* COM2 as 2f8 */ |
||||
outb 0x3f0, 0xe8 |
||||
outb 0x3f1, 0xeb |
||||
|
||||
/* Enable */ |
||||
outb 0x3f0, 0xe2 |
||||
inb r3, 0x3f1 |
||||
ori r3, r3, 0x0c |
||||
outb 0x3f0, 0xe2 |
||||
outbr 0x3f1, r3 |
||||
|
||||
/* Disable configuration mode */ |
||||
li r3, 0 |
||||
li r4, (7<<3) |
||||
li r5, 0x85 |
||||
mr r6, r31 |
||||
bl pci_write_cfg_byte |
||||
|
||||
/* Set line control */ |
||||
outb UART(LINE_CONTROL), 0x83 |
||||
outb UART(DIVISOR_LATCH_LSB), 0x0c |
||||
outb UART(DIVISOR_LATCH_MSB), 0x00 |
||||
outb UART(LINE_CONTROL), 0x3 |
||||
|
||||
mtlr r29 |
||||
blr |
||||
|
||||
|
||||
.globl new_reset
|
||||
.globl new_reset_end
|
||||
new_reset: |
||||
li r0, 0x100 |
||||
oris r0, r0, 0xFFF0 |
||||
mtlr r0 |
||||
blr |
||||
|
||||
new_reset_end: |
@ -1,128 +0,0 @@ |
||||
#include <common.h> |
||||
#include <command.h> |
||||
#include "../disk/part_amiga.h" |
||||
#include <asm/cache.h> |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
#undef BOOTA_DEBUG |
||||
|
||||
#ifdef BOOTA_DEBUG |
||||
#define PRINTF(fmt,args...) printf (fmt ,##args) |
||||
#else |
||||
#define PRINTF(fmt,args...) |
||||
#endif |
||||
|
||||
struct block_header { |
||||
u32 id; |
||||
u32 summed_longs; |
||||
s32 chk_sum; |
||||
}; |
||||
|
||||
extern block_dev_desc_t *ide_get_dev (int dev); |
||||
extern struct bootcode_block *get_bootcode (block_dev_desc_t * dev_desc); |
||||
extern int sum_block (struct block_header *header); |
||||
|
||||
struct bootcode_block bblk; |
||||
|
||||
int do_boota (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) |
||||
{ |
||||
unsigned char *load_address = (unsigned char *) CONFIG_SYS_LOAD_ADDR; |
||||
unsigned char *base_address; |
||||
unsigned long offset; |
||||
|
||||
unsigned long part_number = 0; |
||||
block_dev_desc_t *boot_disk; |
||||
char *s; |
||||
struct bootcode_block *boot_code; |
||||
|
||||
/* Get parameters */ |
||||
|
||||
switch (argc) { |
||||
case 2: |
||||
load_address = (unsigned char *) simple_strtol (argv[1], NULL, 16); |
||||
part_number = 0; |
||||
break; |
||||
case 3: |
||||
load_address = (unsigned char *) simple_strtol (argv[1], NULL, 16); |
||||
part_number = simple_strtol (argv[2], NULL, 16); |
||||
break; |
||||
} |
||||
|
||||
base_address = load_address; |
||||
|
||||
PRINTF ("Loading boot code from disk %d to %p\n", part_number, |
||||
load_address); |
||||
|
||||
/* Find the appropriate disk device */ |
||||
boot_disk = ide_get_dev (part_number); |
||||
if (!boot_disk) { |
||||
PRINTF ("Unknown disk %d\n", part_number); |
||||
return 1; |
||||
} |
||||
|
||||
/* Find the bootcode block */ |
||||
boot_code = get_bootcode (boot_disk); |
||||
if (!boot_code) { |
||||
PRINTF ("Not a bootable disk %d\n", part_number); |
||||
return 1; |
||||
} |
||||
|
||||
/* Only use the offset from the first block */ |
||||
offset = boot_code->load_data[0]; |
||||
memcpy (load_address, &boot_code->load_data[1], 122 * 4); |
||||
load_address += 122 * 4; |
||||
|
||||
/* Setup for the loop */ |
||||
bblk.next = boot_code->next; |
||||
boot_code = &bblk; |
||||
|
||||
/* Scan the chain, and copy the loader succesively into the destination area */ |
||||
while (0xffffffff != boot_code->next) { |
||||
PRINTF ("Loading block %d\n", boot_code->next); |
||||
|
||||
/* Load block */ |
||||
if (1 != |
||||
boot_disk->block_read (boot_disk->dev, boot_code->next, 1, |
||||
(ulong *) & bblk)) { |
||||
PRINTF ("Read error\n"); |
||||
return 1; |
||||
} |
||||
|
||||
/* check sum */ |
||||
if (sum_block ((struct block_header *) (ulong *) & bblk) != 0) { |
||||
PRINTF ("Checksum error\n"); |
||||
return 1; |
||||
} |
||||
|
||||
/* Ok, concatenate it to the already loaded code */ |
||||
memcpy (load_address, boot_code->load_data, 123 * 4); |
||||
load_address += 123 * 4; |
||||
} |
||||
|
||||
printf ("Bootcode loaded to %p (size %d)\n", base_address, |
||||
load_address - base_address); |
||||
printf ("Entry point at %p\n", base_address + offset); |
||||
|
||||
flush_cache (base_address, load_address - base_address); |
||||
|
||||
|
||||
s = getenv ("autostart"); |
||||
if (s && strcmp (s, "yes") == 0) { |
||||
void (*boot) (bd_t *, char *, block_dev_desc_t *); |
||||
char *args; |
||||
|
||||
boot = (void (*)(bd_t *, char *, block_dev_desc_t *)) (base_address + offset); |
||||
boot (gd->bd, getenv ("amiga_bootargs"), boot_disk); |
||||
} |
||||
|
||||
|
||||
return 0; |
||||
} |
||||
#if defined(CONFIG_AMIGAONEG3SE) && defined(CONFIG_CMD_BSP) |
||||
U_BOOT_CMD( |
||||
boota, 3, 1, do_boota, |
||||
"boot an Amiga kernel", |
||||
"address disk" |
||||
); |
||||
#endif /* _CMD_BOOTA_H */ |
@ -1,32 +0,0 @@ |
||||
#
|
||||
# (C) Copyright 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
|
||||
#
|
||||
|
||||
#
|
||||
# AmigaOneG3SE boards
|
||||
#
|
||||
|
||||
X86EMU = -I../bios_emulator/scitech/include -I../bios_emulator/scitech/src/x86emu
|
||||
|
||||
TEXT_BASE = 0xfff00000
|
||||
|
||||
PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -Wa,-mregnames -DEASTEREGG $(X86EMU) -Dprintk=printf #-DDEBUG
|
@ -1,840 +0,0 @@ |
||||
/*
|
||||
* (C) Copyright 2002 |
||||
* Adam Kowalczyk, ACK Software Controls Inc. akowalczyk@cogeco.ca |
||||
* |
||||
* Some portions taken from 3c59x.c Written 1996-1999 by Donald Becker. |
||||
* |
||||
* Outline of the program based on eepro100.c which is |
||||
* |
||||
* (C) Copyright 2002 |
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de. |
||||
* |
||||
* 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 <malloc.h> |
||||
#include <net.h> |
||||
#include <netdev.h> |
||||
#include <asm/io.h> |
||||
#include <pci.h> |
||||
|
||||
#include "articiaS.h" |
||||
#include "memio.h" |
||||
|
||||
/* 3Com Ethernet PCI definitions*/ |
||||
|
||||
/* #define PCI_VENDOR_ID_3COM 0x10B7 */ |
||||
#define PCI_DEVICE_ID_3COM_3C905C 0x9200 |
||||
|
||||
/* 3Com Commands, top 5 bits are command and bottom 11 bits are parameters */ |
||||
|
||||
#define TotalReset (0<<11) |
||||
#define SelectWindow (1<<11) |
||||
#define StartCoax (2<<11) |
||||
#define RxDisable (3<<11) |
||||
#define RxEnable (4<<11) |
||||
#define RxReset (5<<11) |
||||
#define UpStall (6<<11) |
||||
#define UpUnstall (6<<11)+1 |
||||
#define DownStall (6<<11)+2 |
||||
#define DownUnstall (6<<11)+3 |
||||
#define RxDiscard (8<<11) |
||||
#define TxEnable (9<<11) |
||||
#define TxDisable (10<<11) |
||||
#define TxReset (11<<11) |
||||
#define FakeIntr (12<<11) |
||||
#define AckIntr (13<<11) |
||||
#define SetIntrEnb (14<<11) |
||||
#define SetStatusEnb (15<<11) |
||||
#define SetRxFilter (16<<11) |
||||
#define SetRxThreshold (17<<11) |
||||
#define SetTxThreshold (18<<11) |
||||
#define SetTxStart (19<<11) |
||||
#define StartDMAUp (20<<11) |
||||
#define StartDMADown (20<<11)+1 |
||||
#define StatsEnable (21<<11) |
||||
#define StatsDisable (22<<11) |
||||
#define StopCoax (23<<11) |
||||
#define SetFilterBit (25<<11) |
||||
|
||||
/* The SetRxFilter command accepts the following classes */ |
||||
|
||||
#define RxStation 1 |
||||
#define RxMulticast 2 |
||||
#define RxBroadcast 4 |
||||
#define RxProm 8 |
||||
|
||||
/* 3Com status word defnitions */ |
||||
|
||||
#define IntLatch 0x0001 |
||||
#define HostError 0x0002 |
||||
#define TxComplete 0x0004 |
||||
#define TxAvailable 0x0008 |
||||
#define RxComplete 0x0010 |
||||
#define RxEarly 0x0020 |
||||
#define IntReq 0x0040 |
||||
#define StatsFull 0x0080 |
||||
#define DMADone (1<<8) |
||||
#define DownComplete (1<<9) |
||||
#define UpComplete (1<<10) |
||||
#define DMAInProgress (1<<11) /* DMA controller is still busy.*/ |
||||
#define CmdInProgress (1<<12) /* EL3_CMD is still busy.*/ |
||||
|
||||
/* Polling Registers */ |
||||
|
||||
#define DnPoll 0x2d |
||||
#define UpPoll 0x3d |
||||
|
||||
/* Register window 0 offets */ |
||||
|
||||
#define Wn0EepromCmd 10 /* Window 0: EEPROM command register. */ |
||||
#define Wn0EepromData 12 /* Window 0: EEPROM results register. */ |
||||
#define IntrStatus 0x0E /* Valid in all windows. */ |
||||
|
||||
/* Register window 0 EEPROM bits */ |
||||
|
||||
#define EEPROM_Read 0x80 |
||||
#define EEPROM_WRITE 0x40 |
||||
#define EEPROM_ERASE 0xC0 |
||||
#define EEPROM_EWENB 0x30 /* Enable erasing/writing for 10 msec. */ |
||||
#define EEPROM_EWDIS 0x00 /* Disable EWENB before 10 msec timeout. */ |
||||
|
||||
/* EEPROM locations. */ |
||||
|
||||
#define PhysAddr01 0 |
||||
#define PhysAddr23 1 |
||||
#define PhysAddr45 2 |
||||
#define ModelID 3 |
||||
#define EtherLink3ID 7 |
||||
#define IFXcvrIO 8 |
||||
#define IRQLine 9 |
||||
#define NodeAddr01 10 |
||||
#define NodeAddr23 11 |
||||
#define NodeAddr45 12 |
||||
#define DriverTune 13 |
||||
#define Checksum 15 |
||||
|
||||
/* Register window 1 offsets, the window used in normal operation */ |
||||
|
||||
#define TX_FIFO 0x10 |
||||
#define RX_FIFOa 0x10 |
||||
#define RxErrors 0x14 |
||||
#define RxStatus 0x18 |
||||
#define Timer 0x1A |
||||
#define TxStatus 0x1B |
||||
#define TxFree 0x1C /* Remaining free bytes in Tx buffer. */ |
||||
|
||||
/* Register Window 2 */ |
||||
|
||||
#define Wn2_ResetOptions 12 |
||||
|
||||
/* Register Window 3: MAC/config bits */ |
||||
|
||||
#define Wn3_Config 0 /* Internal Configuration */ |
||||
#define Wn3_MAC_Ctrl 6 |
||||
#define Wn3_Options 8 |
||||
|
||||
#define BFEXT(value, offset, bitcount) \ |
||||
((((unsigned long)(value)) >> (offset)) & ((1 << (bitcount)) - 1)) |
||||
|
||||
#define BFINS(lhs, rhs, offset, bitcount) \ |
||||
(((lhs) & ~((((1 << (bitcount)) - 1)) << (offset))) | \
|
||||
(((rhs) & ((1 << (bitcount)) - 1)) << (offset))) |
||||
|
||||
#define RAM_SIZE(v) BFEXT(v, 0, 3) |
||||
#define RAM_WIDTH(v) BFEXT(v, 3, 1) |
||||
#define RAM_SPEED(v) BFEXT(v, 4, 2) |
||||
#define ROM_SIZE(v) BFEXT(v, 6, 2) |
||||
#define RAM_SPLIT(v) BFEXT(v, 16, 2) |
||||
#define XCVR(v) BFEXT(v, 20, 4) |
||||
#define AUTOSELECT(v) BFEXT(v, 24, 1) |
||||
|
||||
/* Register Window 4: Xcvr/media bits */ |
||||
|
||||
#define Wn4_FIFODiag 4 |
||||
#define Wn4_NetDiag 6 |
||||
#define Wn4_PhysicalMgmt 8 |
||||
#define Wn4_Media 10 |
||||
|
||||
#define Media_SQE 0x0008 /* Enable SQE error counting for AUI. */ |
||||
#define Media_10TP 0x00C0 /* Enable link beat and jabber for 10baseT. */ |
||||
#define Media_Lnk 0x0080 /* Enable just link beat for 100TX/100FX. */ |
||||
#define Media_LnkBeat 0x0800 |
||||
|
||||
/* Register Window 7: Bus Master control */ |
||||
|
||||
#define Wn7_MasterAddr 0 |
||||
#define Wn7_MasterLen 6 |
||||
#define Wn7_MasterStatus 12 |
||||
|
||||
/* Boomerang bus master control registers. */ |
||||
|
||||
#define PktStatus 0x20 |
||||
#define DownListPtr 0x24 |
||||
#define FragAddr 0x28 |
||||
#define FragLen 0x2c |
||||
#define TxFreeThreshold 0x2f |
||||
#define UpPktStatus 0x30 |
||||
#define UpListPtr 0x38 |
||||
|
||||
/* The Rx and Tx descriptor lists. */ |
||||
|
||||
#define LAST_FRAG 0x80000000 /* Last Addr/Len pair in descriptor. */ |
||||
#define DN_COMPLETE 0x00010000 /* This packet has been downloaded */ |
||||
|
||||
struct rx_desc_3com { |
||||
u32 next; /* Last entry points to 0 */ |
||||
u32 status; /* FSH -> Frame Start Header */ |
||||
u32 addr; /* Up to 63 addr/len pairs possible */ |
||||
u32 length; /* Set LAST_FRAG to indicate last pair */ |
||||
}; |
||||
|
||||
/* Values for the Rx status entry. */ |
||||
|
||||
#define RxDComplete 0x00008000 |
||||
#define RxDError 0x4000 |
||||
#define IPChksumErr (1<<25) |
||||
#define TCPChksumErr (1<<26) |
||||
#define UDPChksumErr (1<<27) |
||||
#define IPChksumValid (1<<29) |
||||
#define TCPChksumValid (1<<30) |
||||
#define UDPChksumValid (1<<31) |
||||
|
||||
struct tx_desc_3com { |
||||
u32 next; /* Last entry points to 0 */ |
||||
u32 status; /* bits 0:12 length, others see below */ |
||||
u32 addr; |
||||
u32 length; |
||||
}; |
||||
|
||||
/* Values for the Tx status entry. */ |
||||
|
||||
#define CRCDisable 0x2000 |
||||
#define TxDComplete 0x8000 |
||||
#define AddIPChksum 0x02000000 |
||||
#define AddTCPChksum 0x04000000 |
||||
#define AddUDPChksum 0x08000000 |
||||
#define TxIntrUploaded 0x80000000 /* IRQ when in FIFO, but maybe not sent. */ |
||||
|
||||
/* XCVR Types */ |
||||
|
||||
#define XCVR_10baseT 0 |
||||
#define XCVR_AUI 1 |
||||
#define XCVR_10baseTOnly 2 |
||||
#define XCVR_10base2 3 |
||||
#define XCVR_100baseTx 4 |
||||
#define XCVR_100baseFx 5 |
||||
#define XCVR_MII 6 |
||||
#define XCVR_NWAY 8 |
||||
#define XCVR_ExtMII 9 |
||||
#define XCVR_Default 10 /* I don't think this is correct -> should have been 0x10 if Auto Negotiate */ |
||||
|
||||
struct descriptor { /* A generic descriptor. */ |
||||
u32 next; /* Last entry points to 0 */ |
||||
u32 status; /* FSH -> Frame Start Header */ |
||||
u32 addr; /* Up to 63 addr/len pairs possible */ |
||||
u32 length; /* Set LAST_FRAG to indicate last pair */ |
||||
}; |
||||
|
||||
/* Misc. definitions */ |
||||
|
||||
#define NUM_RX_DESC PKTBUFSRX * 10 |
||||
#define NUM_TX_DESC 1 /* Number of TX descriptors */ |
||||
|
||||
#define TOUT_LOOP 1000000 |
||||
|
||||
#define ETH_ALEN 6 |
||||
|
||||
#define EL3WINDOW(dev, win_num) ETH_OUTW(dev, SelectWindow + (win_num), EL3_CMD) |
||||
#define EL3_CMD 0x0e |
||||
#define EL3_STATUS 0x0e |
||||
|
||||
|
||||
#undef ETH_DEBUG |
||||
|
||||
#ifdef ETH_DEBUG |
||||
#define PRINTF(fmt,args...) printf (fmt ,##args) |
||||
#else |
||||
#define PRINTF(fmt,args...) |
||||
#endif |
||||
|
||||
|
||||
static struct rx_desc_3com *rx_ring; /* RX descriptor ring */ |
||||
static struct tx_desc_3com *tx_ring; /* TX descriptor ring */ |
||||
static u8 rx_buffer[NUM_RX_DESC][PKTSIZE_ALIGN];/* storage for the incoming messages */ |
||||
static int rx_next = 0; /* RX descriptor ring pointer */ |
||||
static int tx_next = 0; /* TX descriptor ring pointer */ |
||||
static int tx_threshold; |
||||
|
||||
static void init_rx_ring(struct eth_device* dev); |
||||
static void purge_tx_ring(struct eth_device* dev); |
||||
|
||||
static void read_hw_addr(struct eth_device* dev, bd_t * bis); |
||||
|
||||
static int eth_3com_init(struct eth_device* dev, bd_t *bis); |
||||
static int eth_3com_send(struct eth_device* dev, volatile void *packet, int length); |
||||
static int eth_3com_recv(struct eth_device* dev); |
||||
static void eth_3com_halt(struct eth_device* dev); |
||||
|
||||
#define io_to_phys(a) pci_io_to_phys((pci_dev_t)dev->priv, a) |
||||
#define phys_to_io(a) pci_phys_to_io((pci_dev_t)dev->priv, a) |
||||
#define mem_to_phys(a) pci_mem_to_phys((pci_dev_t)dev->priv, a) |
||||
#define phys_to_mem(a) pci_phys_to_mem((pci_dev_t)dev->priv, a) |
||||
|
||||
static inline int ETH_INL(struct eth_device* dev, u_long addr) |
||||
{ |
||||
__asm__ volatile ("eieio"); |
||||
return le32_to_cpu(*(volatile u32 *)io_to_phys(addr + dev->iobase)); |
||||
} |
||||
|
||||
static inline int ETH_INW(struct eth_device* dev, u_long addr) |
||||
{ |
||||
__asm__ volatile ("eieio"); |
||||
return le16_to_cpu(*(volatile u16 *)io_to_phys(addr + dev->iobase)); |
||||
} |
||||
|
||||
static inline int ETH_INB(struct eth_device* dev, u_long addr) |
||||
{ |
||||
__asm__ volatile ("eieio"); |
||||
return *(volatile u8 *)io_to_phys(addr + dev->iobase); |
||||
} |
||||
|
||||
static inline void ETH_OUTB(struct eth_device* dev, int command, u_long addr) |
||||
{ |
||||
*(volatile u8 *)io_to_phys(addr + dev->iobase) = command; |
||||
__asm__ volatile ("eieio"); |
||||
} |
||||
|
||||
static inline void ETH_OUTW(struct eth_device* dev, int command, u_long addr) |
||||
{ |
||||
*(volatile u16 *)io_to_phys(addr + dev->iobase) = cpu_to_le16(command); |
||||
__asm__ volatile ("eieio"); |
||||
} |
||||
|
||||
static inline void ETH_OUTL(struct eth_device* dev, int command, u_long addr) |
||||
{ |
||||
*(volatile u32 *)io_to_phys(addr + dev->iobase) = cpu_to_le32(command); |
||||
__asm__ volatile ("eieio"); |
||||
} |
||||
|
||||
static inline int ETH_STATUS(struct eth_device* dev) |
||||
{ |
||||
__asm__ volatile ("eieio"); |
||||
return le16_to_cpu(*(volatile u16 *)io_to_phys(EL3_STATUS + dev->iobase)); |
||||
} |
||||
|
||||
static inline void ETH_CMD(struct eth_device* dev, int command) |
||||
{ |
||||
*(volatile u16 *)io_to_phys(EL3_CMD + dev->iobase) = cpu_to_le16(command); |
||||
__asm__ volatile ("eieio"); |
||||
} |
||||
|
||||
/* Command register is always in the same spot in all the register windows */ |
||||
/* This function issues a command and waits for it so complete by checking the CmdInProgress bit */ |
||||
|
||||
static int issue_and_wait(struct eth_device* dev, int command) |
||||
{ |
||||
|
||||
int i, status; |
||||
|
||||
ETH_CMD(dev, command); |
||||
for (i = 0; i < 2000; i++) { |
||||
status = ETH_STATUS(dev); |
||||
/*printf ("Issue: status 0x%4x.\n", status); */ |
||||
if (!(status & CmdInProgress)) |
||||
return 1; |
||||
} |
||||
|
||||
/* OK, that didn't work. Do it the slow way. One second */ |
||||
for (i = 0; i < 100000; i++) { |
||||
status = ETH_STATUS(dev); |
||||
/*printf ("Issue: status 0x%4x.\n", status); */ |
||||
return 1; |
||||
udelay(10); |
||||
} |
||||
PRINTF("Ethernet command: 0x%4x did not complete! Status: 0x%4x\n", command, ETH_STATUS(dev) ); |
||||
return 0; |
||||
} |
||||
|
||||
/* Determine network media type and set up 3com accordingly */ |
||||
/* I think I'm going to start with something known first like 10baseT */ |
||||
|
||||
static int auto_negotiate (struct eth_device *dev) |
||||
{ |
||||
int i; |
||||
|
||||
EL3WINDOW (dev, 1); |
||||
|
||||
/* Wait for Auto negotiation to complete */ |
||||
for (i = 0; i <= 1000; i++) { |
||||
if (ETH_INW (dev, 2) & 0x04) |
||||
break; |
||||
udelay (100); |
||||
|
||||
if (i == 1000) { |
||||
PRINTF ("Error: Auto negotiation failed\n"); |
||||
return 0; |
||||
} |
||||
} |
||||
|
||||
|
||||
return 1; |
||||
} |
||||
|
||||
void eth_interrupt (struct eth_device *dev) |
||||
{ |
||||
u16 status = ETH_STATUS (dev); |
||||
|
||||
printf ("eth0: status = 0x%04x\n", status); |
||||
|
||||
if (!(status & IntLatch)) |
||||
return; |
||||
|
||||
if (status & (1 << 6)) { |
||||
ETH_CMD (dev, AckIntr | (1 << 6)); |
||||
printf ("Acknowledged Interrupt command\n"); |
||||
} |
||||
|
||||
if (status & DownComplete) { |
||||
ETH_CMD (dev, AckIntr | DownComplete); |
||||
printf ("Acknowledged DownComplete\n"); |
||||
} |
||||
|
||||
if (status & UpComplete) { |
||||
ETH_CMD (dev, AckIntr | UpComplete); |
||||
printf ("Acknowledged UpComplete\n"); |
||||
} |
||||
|
||||
ETH_CMD (dev, AckIntr | IntLatch); |
||||
printf ("Acknowledged IntLatch\n"); |
||||
} |
||||
|
||||
int eth_3com_initialize (bd_t * bis) |
||||
{ |
||||
u32 eth_iobase = 0, status; |
||||
int card_number = 0, ret; |
||||
struct eth_device *dev; |
||||
pci_dev_t devno; |
||||
char *s; |
||||
|
||||
s = getenv ("3com_base"); |
||||
|
||||
/* Find ethernet controller on the PCI bus */ |
||||
|
||||
if ((devno = |
||||
pci_find_device (PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905C, |
||||
0)) < 0) { |
||||
PRINTF ("Error: Cannot find the ethernet device on the PCI bus\n"); |
||||
goto Done; |
||||
} |
||||
|
||||
if (s) { |
||||
unsigned long base = atoi (s); |
||||
|
||||
pci_write_config_dword (devno, PCI_BASE_ADDRESS_0, |
||||
base | 0x01); |
||||
} |
||||
|
||||
ret = pci_read_config_dword (devno, PCI_BASE_ADDRESS_0, ð_iobase); |
||||
eth_iobase &= ~0xf; |
||||
|
||||
PRINTF ("eth: 3Com Found at Address: 0x%x\n", eth_iobase); |
||||
|
||||
pci_write_config_dword (devno, PCI_COMMAND, |
||||
PCI_COMMAND_IO | PCI_COMMAND_MEMORY | |
||||
PCI_COMMAND_MASTER); |
||||
|
||||
/* Check if I/O accesses and Bus Mastering are enabled */ |
||||
|
||||
ret = pci_read_config_dword (devno, PCI_COMMAND, &status); |
||||
|
||||
if (!(status & PCI_COMMAND_IO)) { |
||||
printf ("Error: Cannot enable IO access.\n"); |
||||
goto Done; |
||||
} |
||||
|
||||
if (!(status & PCI_COMMAND_MEMORY)) { |
||||
printf ("Error: Cannot enable MEMORY access.\n"); |
||||
goto Done; |
||||
} |
||||
|
||||
if (!(status & PCI_COMMAND_MASTER)) { |
||||
printf ("Error: Cannot enable Bus Mastering.\n"); |
||||
goto Done; |
||||
} |
||||
|
||||
dev = (struct eth_device *) malloc (sizeof (*dev)); /*struct eth_device)); */ |
||||
|
||||
sprintf (dev->name, "3Com 3c920c#%d", card_number); |
||||
dev->iobase = eth_iobase; |
||||
dev->priv = (void *) devno; |
||||
dev->init = eth_3com_init; |
||||
dev->halt = eth_3com_halt; |
||||
dev->send = eth_3com_send; |
||||
dev->recv = eth_3com_recv; |
||||
|
||||
eth_register (dev); |
||||
|
||||
/* { */ |
||||
/* char interrupt; */ |
||||
/* devno = pci_find_device(PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905C, 0); */ |
||||
/* pci_read_config_byte(devno, PCI_INTERRUPT_LINE, &interrupt); */ |
||||
|
||||
/* printf("Installing eth0 interrupt handler to %d\n", interrupt); */ |
||||
/* irq_install_handler(interrupt, eth_interrupt, dev); */ |
||||
/* } */ |
||||
|
||||
card_number++; |
||||
|
||||
/* Set the latency timer for value */ |
||||
s = getenv ("3com_latency"); |
||||
if (s) { |
||||
ret = pci_write_config_byte (devno, PCI_LATENCY_TIMER, |
||||
(unsigned char) atoi (s)); |
||||
} else |
||||
ret = pci_write_config_byte (devno, PCI_LATENCY_TIMER, 0x0a); |
||||
|
||||
read_hw_addr (dev, bis); /* get the MAC address from Window 2 */ |
||||
|
||||
/* Reset the ethernet controller */ |
||||
|
||||
PRINTF ("Issuing reset command....\n"); |
||||
if (!issue_and_wait (dev, TotalReset)) { |
||||
printf ("Error: Cannot reset ethernet controller.\n"); |
||||
goto Done; |
||||
} else |
||||
PRINTF ("Ethernet controller reset.\n"); |
||||
|
||||
/* allocate memory for rx and tx rings */ |
||||
|
||||
if (!(rx_ring = memalign (sizeof (struct rx_desc_3com) * NUM_RX_DESC, 16))) { |
||||
PRINTF ("Cannot allocate memory for RX_RING.....\n"); |
||||
goto Done; |
||||
} |
||||
|
||||
if (!(tx_ring = memalign (sizeof (struct tx_desc_3com) * NUM_TX_DESC, 16))) { |
||||
PRINTF ("Cannot allocate memory for TX_RING.....\n"); |
||||
goto Done; |
||||
} |
||||
|
||||
Done: |
||||
return status; |
||||
} |
||||
|
||||
|
||||
static int eth_3com_init (struct eth_device *dev, bd_t * bis) |
||||
{ |
||||
int i, status = 0; |
||||
int tx_cur, loop; |
||||
u16 status_enable, intr_enable; |
||||
struct descriptor *ias_cmd; |
||||
|
||||
/* Determine what type of network the machine is connected to */ |
||||
/* presently drops the connect to 10Mbps */ |
||||
|
||||
if (!auto_negotiate (dev)) { |
||||
printf ("Error: Cannot determine network media.\n"); |
||||
goto Done; |
||||
} |
||||
|
||||
issue_and_wait (dev, TxReset); |
||||
issue_and_wait (dev, RxReset | 0x04); |
||||
|
||||
/* Switch to register set 7 for normal use. */ |
||||
EL3WINDOW (dev, 7); |
||||
|
||||
/* Initialize Rx and Tx rings */ |
||||
|
||||
init_rx_ring (dev); |
||||
purge_tx_ring (dev); |
||||
|
||||
ETH_CMD (dev, SetRxFilter | RxStation | RxBroadcast | RxProm); |
||||
|
||||
issue_and_wait (dev, SetTxStart | 0x07ff); |
||||
|
||||
/* Below sets which indication bits to be seen. */ |
||||
|
||||
status_enable = |
||||
SetStatusEnb | HostError | DownComplete | UpComplete | (1 << |
||||
6); |
||||
ETH_CMD (dev, status_enable); |
||||
|
||||
/* Below sets no bits are to cause an interrupt since this is just polling */ |
||||
|
||||
intr_enable = SetIntrEnb; |
||||
/* intr_enable = SetIntrEnb | (1<<9) | (1<<10) | (1<<6); */ |
||||
ETH_CMD (dev, intr_enable); |
||||
ETH_OUTB (dev, 127, UpPoll); |
||||
|
||||
/* Ack all pending events, and set active indicator mask */ |
||||
|
||||
ETH_CMD (dev, AckIntr | IntLatch | TxAvailable | RxEarly | IntReq); |
||||
ETH_CMD (dev, intr_enable); |
||||
|
||||
/* Tell the adapter where the RX ring is located */ |
||||
|
||||
issue_and_wait (dev, UpStall); /* Stall and set the UplistPtr */ |
||||
ETH_OUTL (dev, (u32) & rx_ring[rx_next], UpListPtr); |
||||
ETH_CMD (dev, RxEnable); /* Enable the receiver. */ |
||||
issue_and_wait (dev, UpUnstall); |
||||
|
||||
/* Send the Individual Address Setup frame */ |
||||
|
||||
tx_cur = tx_next; |
||||
tx_next = ((tx_next + 1) % NUM_TX_DESC); |
||||
|
||||
ias_cmd = (struct descriptor *) &tx_ring[tx_cur]; |
||||
ias_cmd->status = cpu_to_le32 (1 << 31); /* set DnIndicate bit. */ |
||||
ias_cmd->next = 0; |
||||
ias_cmd->addr = cpu_to_le32 ((u32) dev->enetaddr); |
||||
ias_cmd->length = cpu_to_le32 (6 | LAST_FRAG); |
||||
|
||||
/* Tell the adapter where the TX ring is located */ |
||||
|
||||
ETH_CMD (dev, TxEnable); /* Enable transmitter. */ |
||||
issue_and_wait (dev, DownStall); /* Stall and set the DownListPtr. */ |
||||
ETH_OUTL (dev, (u32) & tx_ring[tx_cur], DownListPtr); |
||||
issue_and_wait (dev, DownUnstall); |
||||
for (i = 0; !(ETH_STATUS (dev) & DownComplete); i++) { |
||||
if (i >= TOUT_LOOP) { |
||||
PRINTF ("TX Ring status (Init): 0x%4x\n", |
||||
le32_to_cpu (tx_ring[tx_cur].status)); |
||||
PRINTF ("ETH_STATUS: 0x%x\n", ETH_STATUS (dev)); |
||||
goto Done; |
||||
} |
||||
} |
||||
if (ETH_STATUS (dev) & DownComplete) { /* If DownLoad Complete ACK the bit */ |
||||
ETH_CMD (dev, AckIntr | DownComplete); /* acknowledge the indication bit */ |
||||
issue_and_wait (dev, DownStall); /* stall and clear DownListPtr */ |
||||
ETH_OUTL (dev, 0, DownListPtr); |
||||
issue_and_wait (dev, DownUnstall); |
||||
} |
||||
status = 1; |
||||
Done: |
||||
return status; |
||||
} |
||||
|
||||
int eth_3com_send (struct eth_device *dev, volatile void *packet, int length) |
||||
{ |
||||
int i, status = 0; |
||||
int tx_cur; |
||||
|
||||
if (length <= 0) { |
||||
PRINTF ("eth: bad packet size: %d\n", length); |
||||
goto Done; |
||||
} |
||||
|
||||
tx_cur = tx_next; |
||||
tx_next = (tx_next + 1) % NUM_TX_DESC; |
||||
|
||||
tx_ring[tx_cur].status = cpu_to_le32 (1 << 31); /* set DnIndicate bit */ |
||||
tx_ring[tx_cur].next = 0; |
||||
tx_ring[tx_cur].addr = cpu_to_le32 (((u32) packet)); |
||||
tx_ring[tx_cur].length = cpu_to_le32 (length | LAST_FRAG); |
||||
|
||||
/* Send the packet */ |
||||
|
||||
issue_and_wait (dev, DownStall); /* stall and set the DownListPtr */ |
||||
ETH_OUTL (dev, (u32) & tx_ring[tx_cur], DownListPtr); |
||||
issue_and_wait (dev, DownUnstall); |
||||
|
||||
for (i = 0; !(ETH_STATUS (dev) & DownComplete); i++) { |
||||
if (i >= TOUT_LOOP) { |
||||
PRINTF ("TX Ring status (send): 0x%4x\n", |
||||
le32_to_cpu (tx_ring[tx_cur].status)); |
||||
goto Done; |
||||
} |
||||
} |
||||
if (ETH_STATUS (dev) & DownComplete) { /* If DownLoad Complete ACK the bit */ |
||||
ETH_CMD (dev, AckIntr | DownComplete); /* acknowledge the indication bit */ |
||||
issue_and_wait (dev, DownStall); /* stall and clear DownListPtr */ |
||||
ETH_OUTL (dev, 0, DownListPtr); |
||||
issue_and_wait (dev, DownUnstall); |
||||
} |
||||
status = 1; |
||||
Done: |
||||
return status; |
||||
} |
||||
|
||||
void PrintPacket (uchar * packet, int length) |
||||
{ |
||||
int loop; |
||||
uchar *ptr; |
||||
|
||||
printf ("Printing packet of length %x.\n\n", length); |
||||
ptr = packet; |
||||
for (loop = 1; loop <= length; loop++) { |
||||
printf ("%2x ", *ptr++); |
||||
if ((loop % 40) == 0) |
||||
printf ("\n"); |
||||
} |
||||
} |
||||
|
||||
int eth_3com_recv (struct eth_device *dev) |
||||
{ |
||||
u16 stat = 0; |
||||
u32 status; |
||||
int rx_prev, length = 0; |
||||
|
||||
while (!(ETH_STATUS (dev) & UpComplete)) /* wait on receipt of packet */ |
||||
; |
||||
|
||||
status = le32_to_cpu (rx_ring[rx_next].status); /* packet status */ |
||||
|
||||
while (status & (1 << 15)) { |
||||
/* A packet has been received */ |
||||
|
||||
if (status & (1 << 15)) { |
||||
/* A valid frame received */ |
||||
|
||||
length = le32_to_cpu (rx_ring[rx_next].status) & 0x1fff; /* length is in bits 0 - 12 */ |
||||
|
||||
/* Pass the packet up to the protocol layers */ |
||||
|
||||
NetReceive ((uchar *) |
||||
le32_to_cpu (rx_ring[rx_next].addr), |
||||
length); |
||||
rx_ring[rx_next].status = 0; /* clear the status word */ |
||||
ETH_CMD (dev, AckIntr | UpComplete); |
||||
issue_and_wait (dev, UpUnstall); |
||||
} else if (stat & HostError) { |
||||
/* There was an error */ |
||||
|
||||
printf ("Rx error status: 0x%4x\n", stat); |
||||
init_rx_ring (dev); |
||||
goto Done; |
||||
} |
||||
|
||||
rx_prev = rx_next; |
||||
rx_next = (rx_next + 1) % NUM_RX_DESC; |
||||
stat = ETH_STATUS (dev); /* register status */ |
||||
status = le32_to_cpu (rx_ring[rx_next].status); /* packet status */ |
||||
} |
||||
Done: |
||||
return length; |
||||
} |
||||
|
||||
void eth_3com_halt (struct eth_device *dev) |
||||
{ |
||||
if (!(dev->iobase)) { |
||||
goto Done; |
||||
} |
||||
|
||||
issue_and_wait (dev, DownStall); /* shut down transmit and receive */ |
||||
issue_and_wait (dev, UpStall); |
||||
issue_and_wait (dev, RxDisable); |
||||
issue_and_wait (dev, TxDisable); |
||||
|
||||
/* free(tx_ring); /###* release memory allocated to the DPD and UPD rings */ |
||||
/* free(rx_ring); */ |
||||
|
||||
Done: |
||||
return; |
||||
} |
||||
|
||||
static void init_rx_ring (struct eth_device *dev) |
||||
{ |
||||
int i; |
||||
|
||||
PRINTF ("Initializing rx_ring. rx_buffer = %p\n", rx_buffer); |
||||
issue_and_wait (dev, UpStall); |
||||
|
||||
for (i = 0; i < NUM_RX_DESC; i++) { |
||||
rx_ring[i].next = |
||||
cpu_to_le32 (((u32) & |
||||
rx_ring[(i + 1) % NUM_RX_DESC])); |
||||
rx_ring[i].status = 0; |
||||
rx_ring[i].addr = cpu_to_le32 (((u32) & rx_buffer[i][0])); |
||||
rx_ring[i].length = cpu_to_le32 (PKTSIZE_ALIGN | LAST_FRAG); |
||||
} |
||||
rx_next = 0; |
||||
} |
||||
|
||||
static void purge_tx_ring (struct eth_device *dev) |
||||
{ |
||||
int i; |
||||
|
||||
PRINTF ("Purging tx_ring.\n"); |
||||
|
||||
tx_next = 0; |
||||
|
||||
for (i = 0; i < NUM_TX_DESC; i++) { |
||||
tx_ring[i].next = 0; |
||||
tx_ring[i].status = 0; |
||||
tx_ring[i].addr = 0; |
||||
tx_ring[i].length = 0; |
||||
} |
||||
} |
||||
|
||||
static void read_hw_addr (struct eth_device *dev, bd_t * bis) |
||||
{ |
||||
u8 hw_addr[ETH_ALEN]; |
||||
unsigned int eeprom[0x40]; |
||||
unsigned int checksum = 0; |
||||
int i, j, timer; |
||||
|
||||
/* First, try the env ... if that works, we're all done! */ |
||||
if (eth_getenv_enetaddr("ethaddr", hw_addr)) |
||||
goto Done; |
||||
|
||||
/* Read the station address from the EEPROM. */ |
||||
|
||||
EL3WINDOW (dev, 0); |
||||
for (i = 0; i < 0x40; i++) { |
||||
ETH_OUTW (dev, EEPROM_Read + i, Wn0EepromCmd); |
||||
/* Pause for at least 162 us. for the read to take place. */ |
||||
for (timer = 10; timer >= 0; timer--) { |
||||
udelay (162); |
||||
if ((ETH_INW (dev, Wn0EepromCmd) & 0x8000) == 0) |
||||
break; |
||||
} |
||||
eeprom[i] = ETH_INW (dev, Wn0EepromData); |
||||
} |
||||
|
||||
/* Checksum calculation. I'm not sure about this part and there seems to be a bug on the 3com side of things */ |
||||
|
||||
for (i = 0; i < 0x21; i++) |
||||
checksum ^= eeprom[i]; |
||||
checksum = (checksum ^ (checksum >> 8)) & 0xff; |
||||
|
||||
if (checksum != 0xbb) |
||||
printf (" *** INVALID EEPROM CHECKSUM %4.4x *** \n", |
||||
checksum); |
||||
|
||||
for (i = 0, j = 0; i < 3; i++) { |
||||
hw_addr[j++] = (u8) ((eeprom[i + 10] >> 8) & 0xff); |
||||
hw_addr[j++] = (u8) (eeprom[i + 10] & 0xff); |
||||
} |
||||
|
||||
/* MAC Address is in window 2, write value from EEPROM to window 2 */ |
||||
|
||||
EL3WINDOW (dev, 2); |
||||
for (i = 0; i < 6; i++) |
||||
ETH_OUTB (dev, hw_addr[i], i); |
||||
|
||||
for (j = 0; j < ETH_ALEN; j += 2) { |
||||
hw_addr[j] = (u8) (ETH_INW (dev, j) & 0xff); |
||||
hw_addr[j + 1] = (u8) ((ETH_INW (dev, j) >> 8) & 0xff); |
||||
} |
||||
|
||||
/* Save the result in the environment */ |
||||
eth_setenv_enetaddr("ethaddr", hw_addr); |
||||
|
||||
Done: |
||||
memcpy(dev->enetaddr, hw_addr, 6); |
||||
return; |
||||
} |
@ -1,35 +0,0 @@ |
||||
#include <common.h> |
||||
#include <flash.h> |
||||
|
||||
flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; |
||||
|
||||
|
||||
unsigned long flash_init(void) |
||||
{ |
||||
int i; |
||||
|
||||
for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) |
||||
{ |
||||
flash_info[i].flash_id = FLASH_UNKNOWN; |
||||
flash_info[i].sector_count = 0; |
||||
flash_info[i].size = 0; |
||||
} |
||||
|
||||
|
||||
return 1; |
||||
} |
||||
|
||||
int flash_erase(flash_info_t *info, int s_first, int s_last) |
||||
{ |
||||
return 1; |
||||
} |
||||
|
||||
void flash_print_info(flash_info_t *info) |
||||
{ |
||||
printf("No flashrom installed\n"); |
||||
} |
||||
|
||||
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) |
||||
{ |
||||
return 0; |
||||
} |
@ -1,651 +0,0 @@ |
||||
/*
|
||||
* (C) Copyright 2001 |
||||
* Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc. |
||||
* |
||||
* (C) Copyright 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 <common.h> |
||||
#include <flash.h> |
||||
#include <asm/io.h> |
||||
#include "memio.h" |
||||
|
||||
/*---------------------------------------------------------------------*/ |
||||
#undef DEBUG_FLASH |
||||
|
||||
#ifdef DEBUG_FLASH |
||||
#define DEBUGF(fmt,args...) printf(fmt ,##args) |
||||
#else |
||||
#define DEBUGF(fmt,args...) |
||||
#endif |
||||
/*---------------------------------------------------------------------*/ |
||||
|
||||
flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; |
||||
|
||||
static ulong flash_get_size (ulong addr, flash_info_t *info); |
||||
static int flash_get_offsets (ulong base, flash_info_t *info); |
||||
static int write_word (flash_info_t *info, ulong dest, ulong data); |
||||
static void flash_reset (ulong addr); |
||||
|
||||
int flash_xd_nest; |
||||
|
||||
static void flash_to_xd(void) |
||||
{ |
||||
unsigned char x; |
||||
|
||||
flash_xd_nest ++; |
||||
|
||||
if (flash_xd_nest == 1) |
||||
{ |
||||
DEBUGF("Flash on XD\n"); |
||||
x = pci_read_cfg_byte(0, 0, 0x74); |
||||
pci_write_cfg_byte(0, 0, 0x74, x|1); |
||||
} |
||||
} |
||||
|
||||
static void flash_to_mem(void) |
||||
{ |
||||
unsigned char x; |
||||
|
||||
flash_xd_nest --; |
||||
|
||||
if (flash_xd_nest == 0) |
||||
{ |
||||
DEBUGF("Flash on memory bus\n"); |
||||
x = pci_read_cfg_byte(0, 0, 0x74); |
||||
pci_write_cfg_byte(0, 0, 0x74, x&0xFE); |
||||
} |
||||
} |
||||
|
||||
unsigned long flash_init_old(void) |
||||
{ |
||||
int i; |
||||
|
||||
for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) |
||||
{ |
||||
flash_info[i].flash_id = FLASH_UNKNOWN; |
||||
flash_info[i].sector_count = 0; |
||||
flash_info[i].size = 0; |
||||
} |
||||
|
||||
|
||||
return 1; |
||||
} |
||||
|
||||
unsigned long flash_init (void) |
||||
{ |
||||
unsigned int i; |
||||
unsigned long flash_size = 0; |
||||
|
||||
flash_xd_nest = 0; |
||||
|
||||
flash_to_xd(); |
||||
|
||||
/* Init: no FLASHes known */ |
||||
for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; ++i) { |
||||
flash_info[i].flash_id = FLASH_UNKNOWN; |
||||
flash_info[i].sector_count = 0; |
||||
flash_info[i].size = 0; |
||||
} |
||||
|
||||
DEBUGF("\n## Get flash size @ 0x%08x\n", CONFIG_SYS_FLASH_BASE); |
||||
|
||||
flash_size = flash_get_size (CONFIG_SYS_FLASH_BASE, flash_info); |
||||
|
||||
DEBUGF("## Flash bank size: %08lx\n", flash_size); |
||||
|
||||
if (flash_size) { |
||||
#if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE && \ |
||||
CONFIG_SYS_MONITOR_BASE < CONFIG_SYS_FLASH_BASE + CONFIG_SYS_FLASH_MAX_SIZE |
||||
/* monitor protection ON by default */ |
||||
flash_protect(FLAG_PROTECT_SET, |
||||
CONFIG_SYS_MONITOR_BASE, |
||||
CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1, |
||||
&flash_info[0]); |
||||
#endif |
||||
|
||||
#ifdef CONFIG_ENV_IS_IN_FLASH |
||||
/* ENV protection ON by default */ |
||||
flash_protect(FLAG_PROTECT_SET, |
||||
CONFIG_ENV_ADDR, |
||||
CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE - 1, |
||||
&flash_info[0]); |
||||
#endif |
||||
|
||||
} else { |
||||
puts ("Warning: the BOOT Flash is not initialised !"); |
||||
} |
||||
|
||||
flash_to_mem(); |
||||
|
||||
return flash_size; |
||||
} |
||||
|
||||
/*
|
||||
* The following code cannot be run from FLASH! |
||||
*/ |
||||
static ulong flash_get_size (ulong addr, flash_info_t *info) |
||||
{ |
||||
short i; |
||||
uchar value; |
||||
uchar *x = (uchar *)addr; |
||||
|
||||
flash_to_xd(); |
||||
|
||||
/* Write auto select command: read Manufacturer ID */ |
||||
x[0x0555] = 0xAA; |
||||
__asm__ volatile ("sync\n eieio"); |
||||
x[0x02AA] = 0x55; |
||||
__asm__ volatile ("sync\n eieio"); |
||||
x[0x0555] = 0x90; |
||||
__asm__ volatile ("sync\n eieio"); |
||||
|
||||
value = x[0]; |
||||
__asm__ volatile ("sync\n eieio"); |
||||
|
||||
DEBUGF("Manuf. ID @ 0x%08lx: 0x%08x\n", (ulong)addr, value); |
||||
|
||||
switch (value | (value << 16)) { |
||||
case AMD_MANUFACT: |
||||
info->flash_id = FLASH_MAN_AMD; |
||||
break; |
||||
|
||||
case FUJ_MANUFACT: |
||||
info->flash_id = FLASH_MAN_FUJ; |
||||
break; |
||||
|
||||
case STM_MANUFACT: |
||||
info->flash_id = FLASH_MAN_STM; |
||||
break; |
||||
|
||||
default: |
||||
info->flash_id = FLASH_UNKNOWN; |
||||
info->sector_count = 0; |
||||
info->size = 0; |
||||
flash_reset (addr); |
||||
return 0; |
||||
} |
||||
|
||||
value = x[1]; |
||||
__asm__ volatile ("sync\n eieio"); |
||||
|
||||
DEBUGF("Device ID @ 0x%08lx: 0x%08x\n", addr+1, value); |
||||
|
||||
switch (value) { |
||||
case AMD_ID_F040B: |
||||
DEBUGF("Am29F040B\n"); |
||||
info->flash_id += FLASH_AM040; |
||||
info->sector_count = 8; |
||||
info->size = 0x00080000; |
||||
break; /* => 512 kB */ |
||||
|
||||
case AMD_ID_LV040B: |
||||
DEBUGF("Am29LV040B\n"); |
||||
info->flash_id += FLASH_AM040; |
||||
info->sector_count = 8; |
||||
info->size = 0x00080000; |
||||
break; /* => 512 kB */ |
||||
|
||||
case AMD_ID_LV400T: |
||||
DEBUGF("Am29LV400T\n"); |
||||
info->flash_id += FLASH_AM400T; |
||||
info->sector_count = 11; |
||||
info->size = 0x00100000; |
||||
break; /* => 1 MB */ |
||||
|
||||
case AMD_ID_LV400B: |
||||
DEBUGF("Am29LV400B\n"); |
||||
info->flash_id += FLASH_AM400B; |
||||
info->sector_count = 11; |
||||
info->size = 0x00100000; |
||||
break; /* => 1 MB */ |
||||
|
||||
case AMD_ID_LV800T: |
||||
DEBUGF("Am29LV800T\n"); |
||||
info->flash_id += FLASH_AM800T; |
||||
info->sector_count = 19; |
||||
info->size = 0x00200000; |
||||
break; /* => 2 MB */ |
||||
|
||||
case AMD_ID_LV800B: |
||||
DEBUGF("Am29LV400B\n"); |
||||
info->flash_id += FLASH_AM800B; |
||||
info->sector_count = 19; |
||||
info->size = 0x00200000; |
||||
break; /* => 2 MB */ |
||||
|
||||
case AMD_ID_LV160T: |
||||
DEBUGF("Am29LV160T\n"); |
||||
info->flash_id += FLASH_AM160T; |
||||
info->sector_count = 35; |
||||
info->size = 0x00400000; |
||||
break; /* => 4 MB */ |
||||
|
||||
case AMD_ID_LV160B: |
||||
DEBUGF("Am29LV160B\n"); |
||||
info->flash_id += FLASH_AM160B; |
||||
info->sector_count = 35; |
||||
info->size = 0x00400000; |
||||
break; /* => 4 MB */ |
||||
|
||||
case AMD_ID_LV320T: |
||||
DEBUGF("Am29LV320T\n"); |
||||
info->flash_id += FLASH_AM320T; |
||||
info->sector_count = 67; |
||||
info->size = 0x00800000; |
||||
break; /* => 8 MB */ |
||||
|
||||
#if 0 |
||||
/* Has the same ID as AMD_ID_LV320T, to be fixed */ |
||||
case AMD_ID_LV320B: |
||||
DEBUGF("Am29LV320B\n"); |
||||
info->flash_id += FLASH_AM320B; |
||||
info->sector_count = 67; |
||||
info->size = 0x00800000; |
||||
break; /* => 8 MB */ |
||||
#endif |
||||
|
||||
case AMD_ID_LV033C: |
||||
DEBUGF("Am29LV033C\n"); |
||||
info->flash_id += FLASH_AM033C; |
||||
info->sector_count = 64; |
||||
info->size = 0x01000000; |
||||
break; /* => 16Mb */ |
||||
|
||||
case STM_ID_F040B: |
||||
DEBUGF("M29F040B\n"); |
||||
info->flash_id += FLASH_AM040; |
||||
info->sector_count = 8; |
||||
info->size = 0x00080000; |
||||
break; /* => 512 kB */ |
||||
|
||||
default: |
||||
info->flash_id = FLASH_UNKNOWN; |
||||
flash_reset (addr); |
||||
flash_to_mem(); |
||||
return (0); /* => no or unknown flash */ |
||||
|
||||
} |
||||
|
||||
if (info->sector_count > CONFIG_SYS_MAX_FLASH_SECT) { |
||||
printf ("** ERROR: sector count %d > max (%d) **\n", |
||||
info->sector_count, CONFIG_SYS_MAX_FLASH_SECT); |
||||
info->sector_count = CONFIG_SYS_MAX_FLASH_SECT; |
||||
} |
||||
|
||||
if (! flash_get_offsets (addr, info)) { |
||||
flash_reset (addr); |
||||
flash_to_mem(); |
||||
return 0; |
||||
} |
||||
|
||||
/* check for protected sectors */ |
||||
for (i = 0; i < info->sector_count; i++) { |
||||
/* read sector protection at sector address, (A7 .. A0) = 0x02 */ |
||||
/* D0 = 1 if protected */ |
||||
value = in8(info->start[i] + 2); |
||||
iobarrier_rw(); |
||||
info->protect[i] = (value & 1) != 0; |
||||
} |
||||
|
||||
/*
|
||||
* Reset bank to read mode |
||||
*/ |
||||
flash_reset (addr); |
||||
|
||||
flash_to_mem(); |
||||
|
||||
return (info->size); |
||||
} |
||||
|
||||
static int flash_get_offsets (ulong base, flash_info_t *info) |
||||
{ |
||||
unsigned int i; |
||||
|
||||
switch (info->flash_id & FLASH_TYPEMASK) { |
||||
case FLASH_AM040: |
||||
/* set sector offsets for uniform sector type */ |
||||
for (i = 0; i < info->sector_count; i++) { |
||||
info->start[i] = base + i * info->size / |
||||
info->sector_count; |
||||
} |
||||
break; |
||||
default: |
||||
return 0; |
||||
} |
||||
|
||||
return 1; |
||||
} |
||||
|
||||
int flash_erase (flash_info_t *info, int s_first, int s_last) |
||||
{ |
||||
volatile ulong addr = info->start[0]; |
||||
int flag, prot, sect, l_sect; |
||||
ulong start, now, last; |
||||
|
||||
flash_to_xd(); |
||||
|
||||
if (s_first < 0 || s_first > s_last) { |
||||
if (info->flash_id == FLASH_UNKNOWN) { |
||||
printf ("- missing\n"); |
||||
} else { |
||||
printf ("- no sectors to erase\n"); |
||||
} |
||||
flash_to_mem(); |
||||
return 1; |
||||
} |
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN) { |
||||
printf ("Can't erase unknown flash type %08lx - aborted\n", |
||||
info->flash_id); |
||||
flash_to_mem(); |
||||
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"); |
||||
} |
||||
|
||||
l_sect = -1; |
||||
|
||||
/* Disable interrupts which might cause a timeout here */ |
||||
flag = disable_interrupts(); |
||||
|
||||
out8(addr + 0x555, 0xAA); |
||||
iobarrier_rw(); |
||||
out8(addr + 0x2AA, 0x55); |
||||
iobarrier_rw(); |
||||
out8(addr + 0x555, 0x80); |
||||
iobarrier_rw(); |
||||
out8(addr + 0x555, 0xAA); |
||||
iobarrier_rw(); |
||||
out8(addr + 0x2AA, 0x55); |
||||
iobarrier_rw(); |
||||
|
||||
/* Start erase on unprotected sectors */ |
||||
for (sect = s_first; sect<=s_last; sect++) { |
||||
if (info->protect[sect] == 0) { /* not protected */ |
||||
addr = info->start[sect]; |
||||
out8(addr, 0x30); |
||||
iobarrier_rw(); |
||||
l_sect = sect; |
||||
} |
||||
} |
||||
|
||||
/* re-enable interrupts if necessary */ |
||||
if (flag) |
||||
enable_interrupts(); |
||||
|
||||
/* wait at least 80us - let's wait 1 ms */ |
||||
udelay (1000); |
||||
|
||||
/*
|
||||
* We wait for the last triggered sector |
||||
*/ |
||||
if (l_sect < 0) |
||||
goto DONE; |
||||
|
||||
start = get_timer (0); |
||||
last = start; |
||||
addr = info->start[l_sect]; |
||||
|
||||
DEBUGF ("Start erase timeout: %d\n", CONFIG_SYS_FLASH_ERASE_TOUT); |
||||
|
||||
while ((in8(addr) & 0x80) != 0x80) { |
||||
if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) { |
||||
printf ("Timeout\n"); |
||||
flash_reset (info->start[0]); |
||||
flash_to_mem(); |
||||
return 1; |
||||
} |
||||
/* show that we're waiting */ |
||||
if ((now - last) > 1000) { /* every second */ |
||||
putc ('.'); |
||||
last = now; |
||||
} |
||||
iobarrier_rw(); |
||||
} |
||||
|
||||
DONE: |
||||
/* reset to read mode */ |
||||
flash_reset (info->start[0]); |
||||
flash_to_mem(); |
||||
|
||||
printf (" done\n"); |
||||
return 0; |
||||
} |
||||
|
||||
/*
|
||||
* Copy memory to flash, returns: |
||||
* 0 - OK |
||||
* 1 - write timeout |
||||
* 2 - Flash not erased |
||||
*/ |
||||
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) |
||||
{ |
||||
ulong cp, wp, data; |
||||
int i, l, rc; |
||||
|
||||
flash_to_xd(); |
||||
|
||||
wp = (addr & ~3); /* get lower word aligned address */ |
||||
|
||||
/*
|
||||
* 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<4 && cnt>0; ++i) { |
||||
data = (data << 8) | *src++; |
||||
--cnt; |
||||
++cp; |
||||
} |
||||
for (; cnt==0 && i<4; ++i, ++cp) { |
||||
data = (data << 8) | (*(uchar *)cp); |
||||
} |
||||
|
||||
if ((rc = write_word(info, wp, data)) != 0) { |
||||
flash_to_mem(); |
||||
return (rc); |
||||
} |
||||
wp += 4; |
||||
} |
||||
|
||||
/*
|
||||
* handle word aligned part |
||||
*/ |
||||
while (cnt >= 4) { |
||||
data = 0; |
||||
for (i=0; i<4; ++i) { |
||||
data = (data << 8) | *src++; |
||||
} |
||||
if ((rc = write_word(info, wp, data)) != 0) { |
||||
flash_to_mem(); |
||||
return (rc); |
||||
} |
||||
wp += 4; |
||||
cnt -= 4; |
||||
} |
||||
|
||||
if (cnt == 0) { |
||||
flash_to_mem(); |
||||
return (0); |
||||
} |
||||
|
||||
/*
|
||||
* handle unaligned tail bytes |
||||
*/ |
||||
data = 0; |
||||
for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) { |
||||
data = (data << 8) | *src++; |
||||
--cnt; |
||||
} |
||||
for (; i<4; ++i, ++cp) { |
||||
data = (data << 8) | (*(uchar *)cp); |
||||
} |
||||
|
||||
|
||||
flash_to_mem(); |
||||
return (write_word(info, wp, data)); |
||||
} |
||||
|
||||
/*
|
||||
* Write a word to Flash, returns: |
||||
* 0 - OK |
||||
* 1 - write timeout |
||||
* 2 - Flash not erased |
||||
*/ |
||||
static int write_word (flash_info_t *info, ulong dest, ulong data) |
||||
{ |
||||
volatile ulong addr = info->start[0]; |
||||
ulong start; |
||||
int i; |
||||
|
||||
flash_to_xd(); |
||||
|
||||
/* Check if Flash is (sufficiently) erased */ |
||||
if ((in32(dest) & data) != data) { |
||||
flash_to_mem(); |
||||
return (2); |
||||
} |
||||
|
||||
/* write each byte out */ |
||||
for (i = 0; i < 4; i++) { |
||||
char *data_ch = (char *)&data; |
||||
int flag = disable_interrupts(); |
||||
|
||||
out8(addr + 0x555, 0xAA); |
||||
iobarrier_rw(); |
||||
out8(addr + 0x2AA, 0x55); |
||||
iobarrier_rw(); |
||||
out8(addr + 0x555, 0xA0); |
||||
iobarrier_rw(); |
||||
out8(dest+i, data_ch[i]); |
||||
iobarrier_rw(); |
||||
|
||||
/* re-enable interrupts if necessary */ |
||||
if (flag) |
||||
enable_interrupts(); |
||||
|
||||
/* data polling for D7 */ |
||||
start = get_timer (0); |
||||
while ((in8(dest+i) & 0x80) != (data_ch[i] & 0x80)) { |
||||
if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) { |
||||
flash_reset (addr); |
||||
flash_to_mem(); |
||||
return (1); |
||||
} |
||||
iobarrier_rw(); |
||||
} |
||||
} |
||||
|
||||
flash_reset (addr); |
||||
flash_to_mem(); |
||||
return (0); |
||||
} |
||||
|
||||
/*
|
||||
* Reset bank to read mode |
||||
*/ |
||||
static void flash_reset (ulong addr) |
||||
{ |
||||
flash_to_xd(); |
||||
out8(addr, 0xF0); /* reset bank */ |
||||
iobarrier_rw(); |
||||
flash_to_mem(); |
||||
} |
||||
|
||||
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_AMD: printf ("AMD "); break; |
||||
case FLASH_MAN_FUJ: printf ("FUJITSU "); break; |
||||
case FLASH_MAN_BM: printf ("BRIGHT MICRO "); break; |
||||
case FLASH_MAN_STM: printf ("SGS THOMSON "); break; |
||||
default: printf ("Unknown Vendor "); break; |
||||
} |
||||
|
||||
switch (info->flash_id & FLASH_TYPEMASK) { |
||||
case FLASH_AM040: printf ("29F040 or 29LV040 (4 Mbit, uniform sectors)\n"); |
||||
break; |
||||
case FLASH_AM400B: printf ("AM29LV400B (4 Mbit, bottom boot sect)\n"); |
||||
break; |
||||
case FLASH_AM400T: printf ("AM29LV400T (4 Mbit, top boot sector)\n"); |
||||
break; |
||||
case FLASH_AM800B: printf ("AM29LV800B (8 Mbit, bottom boot sect)\n"); |
||||
break; |
||||
case FLASH_AM800T: printf ("AM29LV800T (8 Mbit, top boot sector)\n"); |
||||
break; |
||||
case FLASH_AM160B: printf ("AM29LV160B (16 Mbit, bottom boot sect)\n"); |
||||
break; |
||||
case FLASH_AM160T: printf ("AM29LV160T (16 Mbit, top boot sector)\n"); |
||||
break; |
||||
case FLASH_AM320B: printf ("AM29LV320B (32 Mbit, bottom boot sect)\n"); |
||||
break; |
||||
case FLASH_AM320T: printf ("AM29LV320T (32 Mbit, top boot sector)\n"); |
||||
break; |
||||
default: printf ("Unknown Chip Type\n"); |
||||
break; |
||||
} |
||||
|
||||
if (info->size % 0x100000 == 0) { |
||||
printf (" Size: %ld MB in %d Sectors\n", |
||||
info->size / 0x100000, info->sector_count); |
||||
} else if (info->size % 0x400 == 0) { |
||||
printf (" Size: %ld KB in %d Sectors\n", |
||||
info->size / 0x400, info->sector_count); |
||||
} else { |
||||
printf (" Size: %ld B in %d Sectors\n", |
||||
info->size, 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"); |
||||
} |
@ -1,230 +0,0 @@ |
||||
/*
|
||||
* (C) Copyright 2002 |
||||
* John W. Linville, linville@tuxdriver.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 "i8259.h" |
||||
|
||||
#undef IRQ_DEBUG |
||||
|
||||
#ifdef IRQ_DEBUG |
||||
#define PRINTF(fmt,args...) printf (fmt ,##args) |
||||
#else |
||||
#define PRINTF(fmt,args...) |
||||
#endif |
||||
|
||||
static inline unsigned char read_byte(volatile unsigned char* from) |
||||
{ |
||||
int x; |
||||
asm volatile ("lbz %0,%1\n eieio" : "=r" (x) : "m" (*from)); |
||||
return (unsigned char)x; |
||||
} |
||||
|
||||
static inline void write_byte(volatile unsigned char *to, int x) |
||||
{ |
||||
asm volatile ("stb %1,%0\n eieio" : "=m" (*to) : "r" (x)); |
||||
} |
||||
|
||||
static inline unsigned long read_long_little(volatile unsigned long *from) |
||||
{ |
||||
unsigned long x; |
||||
asm volatile ("lwbrx %0,0,%1\n eieio\n sync" : "=r" (x) : "r" (from), "m"(*from)); |
||||
return (unsigned long)x; |
||||
} |
||||
|
||||
#ifdef out8 |
||||
#undef out8 |
||||
#endif |
||||
|
||||
#ifdef in8 |
||||
#undef in8 |
||||
#endif |
||||
|
||||
#define out8(addr, byte) write_byte(0xFE000000 | addr, byte) |
||||
#define in8(addr) read_byte(0xFE000000 | addr) |
||||
|
||||
/*
|
||||
* This contains the irq mask for both 8259A irq controllers, |
||||
*/ |
||||
static char cached_imr[2] = {0xff, 0xff}; |
||||
|
||||
#define cached_imr1 (cached_imr[0]) |
||||
#define cached_imr2 (cached_imr[1]) |
||||
|
||||
void i8259_init(void) |
||||
{ |
||||
char dummy; |
||||
PRINTF("Initializing Interrupt controller\n"); |
||||
/* init master interrupt controller */ |
||||
out8(0x20, 0x11); /* 0x19); /###* Start init sequence */ |
||||
out8(0x21, 0x00); /* Vector base */ |
||||
out8(0x21, 0x04); /* edge tiggered, Cascade (slave) on IRQ2 */ |
||||
out8(0x21, 0x11); /* was: 0x01); /###* Select 8086 mode */ |
||||
|
||||
/* init slave interrupt controller */ |
||||
out8(0xA0, 0x11); /* 0x19); /###* Start init sequence */ |
||||
out8(0xA1, 0x08); /* Vector base */ |
||||
out8(0xA1, 0x02); /* edge triggered, Cascade (slave) on IRQ2 */ |
||||
out8(0xA1, 0x11); /* was: 0x01); /###* Select 8086 mode */ |
||||
|
||||
/* always read ISR */ |
||||
out8(0x20, 0x0B); |
||||
dummy = in8(ISR_1); |
||||
out8(0xA0, 0x0B); |
||||
dummy = in8(ISR_2); |
||||
|
||||
/* out8(0x43, 0x30); */ |
||||
/* out8(0x40, 0); */ |
||||
/* out8(0x40, 0); */ |
||||
/* out8(0x43, 0x70); */ |
||||
/* out8(0x41, 0); */ |
||||
/* out8(0x41, 0); */ |
||||
/* out8(0x43, 0xb0); */ |
||||
/* out8(0x42, 0); */ |
||||
/* out8(0x42, 0); */ |
||||
|
||||
/* Mask all interrupts */ |
||||
out8(IMR_2, cached_imr2); |
||||
out8(IMR_1, cached_imr1); |
||||
|
||||
i8259_unmask_irq(2); |
||||
#if 0 |
||||
{ |
||||
int i; |
||||
for (i=0; i<16; i++) |
||||
{ |
||||
i8259_unmask_irq(i); |
||||
} |
||||
} |
||||
#endif |
||||
} |
||||
|
||||
static volatile char *pci_intack = (void *)0xFEF00000; |
||||
|
||||
int i8259_irq(void) |
||||
{ |
||||
int irq; |
||||
|
||||
irq = read_long_little(pci_intack) & 0xff; |
||||
if (irq==7) { |
||||
/*
|
||||
* This may be a spurious interrupt. |
||||
* |
||||
* Read the interrupt status register (ISR). If the most |
||||
* significant bit is not set then there is no valid |
||||
* interrupt. |
||||
*/ |
||||
if(~in8(0x20)&0x80) { |
||||
irq = -1; |
||||
} |
||||
} |
||||
|
||||
return irq; |
||||
} |
||||
int i8259_get_irq(struct pt_regs *regs) |
||||
{ |
||||
unsigned char irq; |
||||
|
||||
/*
|
||||
* Perform an interrupt acknowledge cycle on controller 1 |
||||
*/ |
||||
out8(OCW3_1, 0x0C); /* prepare for poll */ |
||||
irq = in8(IPL_1) & 7; |
||||
if (irq == 2) { |
||||
/*
|
||||
* Interrupt is cascaded so perform interrupt |
||||
* acknowledge on controller 2 |
||||
*/ |
||||
out8(OCW3_2, 0x0C); /* prepare for poll */ |
||||
irq = (in8(IPL_2) & 7) + 8; |
||||
if (irq == 15) { |
||||
/*
|
||||
* This may be a spurious interrupt |
||||
* |
||||
* Read the interrupt status register. If the most |
||||
* significant bit is not set then there is no valid |
||||
* interrupt |
||||
*/ |
||||
out8(OCW3_2, 0x0b); |
||||
if (~(in8(ISR_2) & 0x80)) { |
||||
return -1; |
||||
} |
||||
} |
||||
} else if (irq == 7) { |
||||
/*
|
||||
* This may be a spurious interrupt |
||||
* |
||||
* Read the interrupt status register. If the most |
||||
* significant bit is not set then there is no valid |
||||
* interrupt |
||||
*/ |
||||
out8(OCW3_1, 0x0b); |
||||
if (~(in8(ISR_1) & 0x80)) { |
||||
return -1; |
||||
} |
||||
} |
||||
return irq; |
||||
} |
||||
|
||||
/*
|
||||
* Careful! The 8259A is a fragile beast, it pretty |
||||
* much _has_ to be done exactly like this (mask it |
||||
* first, _then_ send the EOI, and the order of EOI |
||||
* to the two 8259s is important! |
||||
*/ |
||||
void i8259_mask_and_ack(int irq) |
||||
{ |
||||
if (irq > 7) { |
||||
cached_imr2 |= (1 << (irq - 8)); |
||||
in8(IMR_2); /* DUMMY */ |
||||
out8(IMR_2, cached_imr2); |
||||
out8(OCW2_2, 0x20); /* Non-specific EOI */ |
||||
out8(OCW2_1, 0x20); /* Non-specific EOI to cascade */ |
||||
} else { |
||||
cached_imr1 |= (1 << irq); |
||||
in8(IMR_1); /* DUMMY */ |
||||
out8(IMR_1, cached_imr1); |
||||
out8(OCW2_1, 0x20); /* Non-specific EOI */ |
||||
} |
||||
} |
||||
|
||||
void i8259_mask_irq(int irq) |
||||
{ |
||||
if (irq & 8) { |
||||
cached_imr2 |= (1 << (irq & 7)); |
||||
out8(IMR_2, cached_imr2); |
||||
} else { |
||||
cached_imr1 |= (1 << irq); |
||||
out8(IMR_1, cached_imr1); |
||||
} |
||||
} |
||||
|
||||
void i8259_unmask_irq(int irq) |
||||
{ |
||||
if (irq & 8) { |
||||
cached_imr2 &= ~(1 << (irq & 7)); |
||||
out8(IMR_2, cached_imr2); |
||||
} else { |
||||
cached_imr1 &= ~(1 << irq); |
||||
out8(IMR_1, cached_imr1); |
||||
} |
||||
} |
@ -1,56 +0,0 @@ |
||||
/*
|
||||
* (C) Copyright 2002 |
||||
* John W. Linville, linville@tuxdriver.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 |
||||
*/ |
||||
|
||||
#define ICW1_1 CONFIG_SYS_ISA_IO_BASE_ADDRESS + ISA_INT1_ICW1 |
||||
#define ICW1_2 CONFIG_SYS_ISA_IO_BASE_ADDRESS + ISA_INT2_ICW1 |
||||
#define ICW2_1 CONFIG_SYS_ISA_IO_BASE_ADDRESS + ISA_INT1_ICW2 |
||||
#define ICW2_2 CONFIG_SYS_ISA_IO_BASE_ADDRESS + ISA_INT2_ICW2 |
||||
#define ICW3_1 CONFIG_SYS_ISA_IO_BASE_ADDRESS + ISA_INT1_ICW3 |
||||
#define ICW3_2 CONFIG_SYS_ISA_IO_BASE_ADDRESS + ISA_INT2_ICW3 |
||||
#define ICW4_1 CONFIG_SYS_ISA_IO_BASE_ADDRESS + ISA_INT1_ICW4 |
||||
#define ICW4_2 CONFIG_SYS_ISA_IO_BASE_ADDRESS + ISA_INT2_ICW4 |
||||
#define OCW1_1 CONFIG_SYS_ISA_IO_BASE_ADDRESS + ISA_INT1_OCW1 |
||||
#define OCW1_2 CONFIG_SYS_ISA_IO_BASE_ADDRESS + ISA_INT2_OCW1 |
||||
#define OCW2_1 CONFIG_SYS_ISA_IO_BASE_ADDRESS + ISA_INT1_OCW2 |
||||
#define OCW2_2 CONFIG_SYS_ISA_IO_BASE_ADDRESS + ISA_INT2_OCW2 |
||||
#define OCW3_1 CONFIG_SYS_ISA_IO_BASE_ADDRESS + ISA_INT1_OCW3 |
||||
#define OCW3_2 CONFIG_SYS_ISA_IO_BASE_ADDRESS + ISA_INT2_OCW3 |
||||
|
||||
#define IMR_1 OCW1_1 |
||||
#define IMR_2 OCW1_2 |
||||
|
||||
#define ISR_1 ICW1_1 |
||||
#define ISR_2 ICW1_2 |
||||
|
||||
#define IPL_1 ICW1_1 |
||||
#define IPL_2 ICW1_2 |
||||
|
||||
extern void i8259_init(void); |
||||
|
||||
extern int i8259_get_irq(struct pt_regs *regs); |
||||
|
||||
extern void i8259_mask_and_ack(int irq); |
||||
|
||||
extern void i8259_mask_irq(int irq); |
||||
|
||||
extern void i8259_unmask_irq(int irq); |
@ -1,266 +0,0 @@ |
||||
/*
|
||||
* (C) Copyright 2002 |
||||
* John W. Linville <linville@tuxdriver.com> |
||||
* |
||||
* Copied and modified from original code by Josh Huber. Original |
||||
* copyright notice preserved below. |
||||
* |
||||
* (C) Copyright 2001 |
||||
* Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc. |
||||
* |
||||
* 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 |
||||
*/ |
||||
|
||||
/*
|
||||
* interrupts.c - just enough support for the decrementer/timer |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <asm/processor.h> |
||||
#include <command.h> |
||||
#include "i8259.h" |
||||
|
||||
#undef DEBUG |
||||
#ifdef DEBUG |
||||
#define PRINTF(fmt,args...) printf (fmt ,##args) |
||||
#else |
||||
#define PRINTF(fmt,args...) |
||||
#endif |
||||
#define NR_IRQS 16 |
||||
|
||||
void irq_alloc_init(void); |
||||
long irq_alloc(long wanted); |
||||
|
||||
/****************************************************************************/ |
||||
|
||||
unsigned decrementer_count; /* count value for 1e6/HZ microseconds */ |
||||
|
||||
struct irq_action { |
||||
interrupt_handler_t *handler; |
||||
void *arg; |
||||
ulong count; |
||||
}; |
||||
|
||||
static struct irq_action irq_handlers[NR_IRQS]; |
||||
|
||||
/****************************************************************************/ |
||||
|
||||
static __inline__ unsigned long |
||||
get_msr(void) |
||||
{ |
||||
unsigned long msr; |
||||
|
||||
asm volatile("mfmsr %0" : "=r" (msr) :); |
||||
return msr; |
||||
} |
||||
|
||||
static __inline__ void |
||||
set_msr(unsigned long msr) |
||||
{ |
||||
asm volatile("mtmsr %0" : : "r" (msr)); |
||||
} |
||||
|
||||
static __inline__ unsigned long |
||||
get_dec(void) |
||||
{ |
||||
unsigned long val; |
||||
|
||||
asm volatile("mfdec %0" : "=r" (val) :); |
||||
return val; |
||||
} |
||||
|
||||
|
||||
static __inline__ void |
||||
set_dec(unsigned long val) |
||||
{ |
||||
asm volatile("mtdec %0" : : "r" (val)); |
||||
} |
||||
|
||||
|
||||
void |
||||
enable_interrupts(void) |
||||
{ |
||||
set_msr (get_msr() | MSR_EE); |
||||
} |
||||
|
||||
/* returns flag if MSR_EE was set before */ |
||||
int |
||||
disable_interrupts(void) |
||||
{ |
||||
ulong msr; |
||||
|
||||
msr = get_msr(); |
||||
set_msr (msr & ~MSR_EE); |
||||
return ((msr & MSR_EE) != 0); |
||||
} |
||||
|
||||
/****************************************************************************/ |
||||
|
||||
int interrupt_init (void) |
||||
{ |
||||
extern void new_reset(void); |
||||
extern void new_reset_end(void); |
||||
#ifdef DEBUG |
||||
puts("interrupt_init: setting decrementer_count\n"); |
||||
#endif |
||||
decrementer_count = get_tbclk() / CONFIG_SYS_HZ; |
||||
|
||||
#ifdef DEBUG |
||||
puts("interrupt_init: setting actual decremter\n"); |
||||
#endif |
||||
set_dec (get_tbclk() / CONFIG_SYS_HZ); |
||||
|
||||
#ifdef DEBUG |
||||
puts("interrupt_init: clearing external interrupt table\n"); |
||||
#endif |
||||
/* clear external interrupt table here */ |
||||
memset(irq_handlers, 0, sizeof(irq_handlers)); |
||||
|
||||
#ifdef DEBUG |
||||
puts("interrupt_init: initializing interrupt controller\n"); |
||||
#endif |
||||
i8259_init(); |
||||
|
||||
#ifdef DEBUG |
||||
puts("Copying reset trampoline\n"); |
||||
#endif |
||||
/* WARNING: Assmues that the first megabyte is CACHEINHIBIT! */ |
||||
memcpy((void *)0x100, new_reset, new_reset_end - new_reset); |
||||
|
||||
#ifdef DEBUG |
||||
PRINTF("interrupt_init: enabling interrupts (msr = %08x)\n", |
||||
get_msr()); |
||||
#endif |
||||
set_msr (get_msr() | MSR_EE); |
||||
|
||||
#ifdef DEBUG |
||||
PRINTF("interrupt_init: done. (msr = %08x)\n", get_msr()); |
||||
#endif |
||||
|
||||
} |
||||
|
||||
/****************************************************************************/ |
||||
|
||||
/*
|
||||
* Handle external interrupts |
||||
*/ |
||||
void |
||||
external_interrupt(struct pt_regs *regs) |
||||
{ |
||||
extern int i8259_irq(void); |
||||
|
||||
int irq, unmask = 1; |
||||
|
||||
irq = i8259_irq(); /*i8259_get_irq(regs); */ |
||||
/* printf("irq = %d, handler at %p ack=%d\n", irq, irq_handlers[irq].handler, *(volatile unsigned char *)0xFEF00000); */ |
||||
i8259_mask_and_ack(irq); |
||||
|
||||
if (irq_handlers[irq].handler != NULL) |
||||
(*irq_handlers[irq].handler)(irq_handlers[irq].arg); |
||||
else { |
||||
PRINTF ("\nBogus External Interrupt IRQ %d\n", irq); |
||||
/*
|
||||
* turn off the bogus interrupt, otherwise it |
||||
* might repeat forever |
||||
*/ |
||||
unmask = 0; |
||||
} |
||||
|
||||
if (unmask) i8259_unmask_irq(irq); |
||||
} |
||||
|
||||
volatile ulong timestamp = 0; |
||||
|
||||
/*
|
||||
* timer_interrupt - gets called when the decrementer overflows, |
||||
* with interrupts disabled. |
||||
* Trivial implementation - no need to be really accurate. |
||||
*/ |
||||
void |
||||
timer_interrupt(struct pt_regs *regs) |
||||
{ |
||||
set_dec(decrementer_count); |
||||
timestamp++; |
||||
} |
||||
|
||||
/****************************************************************************/ |
||||
|
||||
void |
||||
reset_timer(void) |
||||
{ |
||||
timestamp = 0; |
||||
} |
||||
|
||||
ulong |
||||
get_timer(ulong base) |
||||
{ |
||||
return (timestamp - base); |
||||
} |
||||
|
||||
void |
||||
set_timer(ulong t) |
||||
{ |
||||
timestamp = t; |
||||
} |
||||
|
||||
/****************************************************************************/ |
||||
|
||||
/*
|
||||
* Install and free a interrupt handler. |
||||
*/ |
||||
|
||||
void |
||||
irq_install_handler(int irq, interrupt_handler_t *handler, void *arg) |
||||
{ |
||||
if (irq < 0 || irq >= NR_IRQS) { |
||||
PRINTF("irq_install_handler: bad irq number %d\n", irq); |
||||
return; |
||||
} |
||||
|
||||
if (irq_handlers[irq].handler != NULL) |
||||
PRINTF("irq_install_handler: 0x%08lx replacing 0x%08lx\n", |
||||
(ulong)handler, (ulong)irq_handlers[irq].handler); |
||||
|
||||
irq_handlers[irq].handler = handler; |
||||
irq_handlers[irq].arg = arg; |
||||
|
||||
i8259_unmask_irq(irq); |
||||
} |
||||
|
||||
void |
||||
irq_free_handler(int irq) |
||||
{ |
||||
if (irq < 0 || irq >= NR_IRQS) { |
||||
PRINTF("irq_free_handler: bad irq number %d\n", irq); |
||||
return; |
||||
} |
||||
|
||||
i8259_mask_irq(irq); |
||||
|
||||
irq_handlers[irq].handler = NULL; |
||||
irq_handlers[irq].arg = NULL; |
||||
} |
||||
|
||||
/****************************************************************************/ |
||||
|
||||
void |
||||
do_irqinfo(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) |
||||
{ |
||||
puts("IRQ related functions are unimplemented currently.\n"); |
||||
} |
@ -1,84 +0,0 @@ |
||||
|
||||
#ifndef _MACROS_H |
||||
#define _MACROS_H |
||||
|
||||
/*
|
||||
** Load a long integer into a register |
||||
*/ |
||||
.macro liw reg, value |
||||
lis \reg, \value@h |
||||
ori \reg, \reg, \value@l |
||||
.endm |
||||
|
||||
|
||||
/*
|
||||
** Generate config_addr request |
||||
** This macro expects the values in registers: |
||||
** r3 - bus |
||||
** r4 - devfn |
||||
** r5 - offset |
||||
*/ |
||||
.macro config_addr |
||||
rlwinm r9, r5, 24, 0, 6 |
||||
rlwinm r8, r4, 16, 0, 31 |
||||
rlwinm r7, r3, 8, 0, 31 |
||||
or r9, r8, r9 |
||||
or r9, r7, r9 |
||||
ori r9, r9, 0x80 |
||||
liw r10, 0xfec00cf8 |
||||
stw r9, 0(r10) |
||||
eieio |
||||
sync |
||||
.endm |
||||
|
||||
|
||||
/*
|
||||
** Generate config_data address |
||||
*/ |
||||
.macro config_data mask |
||||
andi. r9, r5, \mask |
||||
addi r9, r9, 0xcfc |
||||
oris r9, r9, 0xfee0 |
||||
.endm |
||||
|
||||
|
||||
/*
|
||||
** Write a byte value to an output port |
||||
*/ |
||||
.macro outb port, value |
||||
lis r2, 0xfe00 |
||||
li r0, \value |
||||
stb r0, \port(r2) |
||||
.endm |
||||
|
||||
|
||||
/*
|
||||
** Write a register byte value to an output port |
||||
*/ |
||||
.macro outbr port, value |
||||
lis r2, 0xfe00 |
||||
stb \value, \port(r2) |
||||
.endm |
||||
|
||||
|
||||
/*
|
||||
** Read a byte value from a port into a specified register |
||||
*/ |
||||
.macro inb reg, port |
||||
lis r2, 0xfe00 |
||||
lbz \reg, \port(r2) |
||||
.endm |
||||
|
||||
|
||||
/*
|
||||
** Write a byte to the SuperIO config area |
||||
*/ |
||||
.macro siowb offset, value |
||||
li r3, 0 |
||||
li r4, (7<<3) |
||||
li r5, \offset |
||||
li r6, \value |
||||
bl pci_write_cfg_byte |
||||
.endm |
||||
|
||||
#endif |
@ -1,67 +0,0 @@ |
||||
#include "macros.h" |
||||
|
||||
|
||||
.globl pci_read_cfg_byte
|
||||
|
||||
pci_read_cfg_byte: |
||||
config_addr |
||||
config_data 3 |
||||
eieio |
||||
sync |
||||
lbz r3, 0(r9) |
||||
blr |
||||
|
||||
|
||||
.globl pci_write_cfg_byte
|
||||
|
||||
pci_write_cfg_byte: |
||||
config_addr |
||||
config_data 3 |
||||
stb r6, 0(r9) |
||||
eieio |
||||
sync |
||||
blr |
||||
|
||||
|
||||
.globl pci_read_cfg_word
|
||||
|
||||
pci_read_cfg_word: |
||||
config_addr |
||||
config_data 2 |
||||
lhbrx r3, 0, r9 |
||||
eieio |
||||
sync |
||||
blr |
||||
|
||||
|
||||
.globl pci_write_cfg_word
|
||||
|
||||
pci_write_cfg_word: |
||||
config_addr |
||||
config_data 2 |
||||
sthbrx r6, 0, r9 |
||||
eieio |
||||
sync |
||||
blr |
||||
|
||||
|
||||
.globl pci_read_cfg_long
|
||||
|
||||
pci_read_cfg_long: |
||||
config_addr |
||||
config_data 0 |
||||
lwbrx r3, 0, r9 |
||||
eieio |
||||
sync |
||||
blr |
||||
|
||||
|
||||
.globl pci_write_cfg_long
|
||||
|
||||
pci_write_cfg_long: |
||||
config_addr |
||||
config_data 0 |
||||
stwbrx r6, 0, r9 |
||||
eieio |
||||
sync |
||||
blr |
@ -1,113 +0,0 @@ |
||||
/*
|
||||
* Memory mapped IO |
||||
* |
||||
* (C) Copyright 2002 |
||||
* Hyperion Entertainment, ThomasF@hyperion-entertainment.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. |
||||
* You may also use this under a BSD license. |
||||
* |
||||
* 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. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef _MEMIO_H |
||||
#define _MEMIO_H |
||||
|
||||
#include "short_types.h" |
||||
|
||||
#define IOBASE 0xFE000000 |
||||
|
||||
#define in_byte(from) read_byte( (uint8 *)(IOBASE | (from))) |
||||
#define in_word(from) read_word_little((uint16 *)(IOBASE | (from))) |
||||
#define in_long(from) read_long_little((uint32 *)(IOBASE | (from))) |
||||
#define out_byte(to, val) write_byte((uint8 *)(IOBASE | (to)), val) |
||||
#define out_word(to, val) write_word_little((uint16 *)(IOBASE | (to)), val) |
||||
#define out_long(to, val) write_long_little((uint32 *)(IOBASE | (to)), val) |
||||
|
||||
|
||||
static inline uint8 read_byte(volatile uint8 *from) |
||||
{ |
||||
int x; |
||||
asm volatile ("lbz %0,%1\n eieio\n sync" : "=r" (x) : "m" (*from)); |
||||
return (uint8)x; |
||||
} |
||||
|
||||
|
||||
static inline void write_byte(volatile uint8 *to, uint8 x) |
||||
{ |
||||
asm volatile ("stb %1,%0\n eieio\n sync" : "=m" (*to) : "r" (x)); |
||||
} |
||||
|
||||
static inline uint16 read_word_little(volatile uint16 *from) |
||||
{ |
||||
int x; |
||||
asm volatile ("lhbrx %0,0,%1\n eieio\n sync" : "=r" (x) : "r" (from), "m" (*from)); |
||||
return (uint16)x; |
||||
} |
||||
|
||||
static inline uint16 read_word_big(volatile uint16 *from) |
||||
{ |
||||
int x; |
||||
asm volatile ("lhz %0,%1\n eieio\n sync" : "=r" (x) : "m" (*from)); |
||||
return (uint16)x; |
||||
} |
||||
|
||||
static inline void write_word_little(volatile uint16 *to, int x) |
||||
{ |
||||
asm volatile ("sthbrx %1,0,%2\n eieio\n sync" : "=m" (*to) : "r" (x), "r" (to)); |
||||
} |
||||
|
||||
static inline void write_word_big(volatile uint16 *to, int x) |
||||
{ |
||||
asm volatile ("sth %1,%0\n eieio\n sync" : "=m" (*to) : "r" (x)); |
||||
} |
||||
|
||||
static inline uint32 read_long_little(volatile uint32 *from) |
||||
{ |
||||
unsigned long x; |
||||
asm volatile ("lwbrx %0,0,%1\n eieio\n sync" : "=r" (x) : "r" (from), "m"(*from)); |
||||
return (uint32)x; |
||||
} |
||||
|
||||
static inline uint32 read_long_big(volatile uint32 *from) |
||||
{ |
||||
unsigned long x; |
||||
asm volatile ("lwz %0,%1\n eieio\n sync" : "=r" (x) : "m" (*from)); |
||||
return (uint32)x; |
||||
} |
||||
|
||||
static inline void write_long_little(volatile uint32 *to, uint32 x) |
||||
{ |
||||
asm volatile ("stwbrx %1,0,%2\n eieio\n sync" : "=m" (*to) : "r" (x), "r" (to)); |
||||
} |
||||
|
||||
static inline void write_long_big(volatile uint32 *to, uint32 x) |
||||
{ |
||||
asm volatile ("stw %1,%0\n eieio\n sync" : "=m" (*to) : "r" (x)); |
||||
} |
||||
|
||||
#define CONFIG_ADDR(bus, devfn, offset) \ |
||||
write_long_big((uint32 *)0xFEC00CF8, \
|
||||
((offset & 0xFC)<<24) | (devfn << 16) \
|
||||
| (bus<<8) | 0x80); |
||||
#define CONFIG_DATA(offset,mask) ((void *)(0xFEE00CFC+(offset & mask))) |
||||
|
||||
|
||||
uint8 pci_read_cfg_byte(int32 bus, int32 devfn, int32 offset); |
||||
void pci_write_cfg_byte(int32 bus, int32 devfn, int32 offset, uint8 x); |
||||
uint16 pci_read_cfg_word(int32 bus, int32 devfn, int32 offset); |
||||
void pci_write_cfg_word(int32 bus, int32 devfn, int32 offset, uint16 x); |
||||
uint32 pci_read_cfg_long(int32 bus, int32 devfn, int32 offset); |
||||
void pci_write_cfg_long(int32 bus, int32 devfn, int32 offset, uint32 x); |
||||
|
||||
|
||||
#endif |
@ -1,30 +0,0 @@ |
||||
64 MB: |
||||
0x00: 80 08 04 0c 09 01 40 00 01 a0 60 00 80 08 00 01 |
||||
0x10: 8f 04 04 01 01 00 06 a0 60 00 00 14 10 14 2d 10 |
||||
0x20: 20 10 20 10 00 00 00 00 00 00 00 00 00 00 00 00 |
||||
0x30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 12 f2 |
||||
0x40: 7f 61 00 00 00 00 00 00 46 04 00 ff ff ff ff ff |
||||
0x50: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |
||||
0x60: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |
||||
0x70: ff ff ff ff ff ff ff ff ff ff ff ff ff ff 64 f4 |
||||
|
||||
512 MB: |
||||
0x00: 80 08 04 0d 0a 02 40 00 01 75 54 00 82 08 00 01 |
||||
0x10: 8f 04 04 01 01 00 0f 00 00 00 00 14 0f 14 2d 40 |
||||
0x20: 15 08 15 08 00 00 00 00 00 00 00 00 00 00 00 00 |
||||
0x30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 12 d2 |
||||
0x40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
||||
0x50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
||||
0x60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
||||
0x70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 64 fd |
||||
|
||||
256 MB: |
||||
0x00: 80 08 04 0c 0a 02 40 00 01 75 54 00 80 08 00 01 |
||||
0x10: 8f 04 06 01 01 00 0e a0 60 00 00 14 0f 14 2d 20 |
||||
0x20: 15 08 15 08 00 00 00 00 00 00 00 00 00 00 00 00 |
||||
0x30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 12 b0 |
||||
0x40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
||||
0x50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
||||
0x60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
||||
0x70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 64 f6 |
||||
|
@ -1,36 +0,0 @@ |
||||
/*
|
||||
* (C) Copyright 2002 |
||||
* Thomas Frieden, Hyperion Entertainment |
||||
* ThomasF@hyperion-entertainment.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 "memio.h" |
||||
|
||||
void enable_nvram(void) |
||||
{ |
||||
pci_write_cfg_byte(0, 0, 0x56, 0x0b); |
||||
} |
||||
|
||||
void disable_nvram(void) |
||||
{ |
||||
pci_write_cfg_byte(0, 0, 0x56, 0x0); |
||||
} |
@ -1,685 +0,0 @@ |
||||
/*
|
||||
* (C) Copyright 2002 |
||||
* John W. Linville, linville@tuxdriver.com |
||||
* |
||||
* Modified from code for support of MIP405 and PIP405 boards. Previous |
||||
* copyright follows. |
||||
* |
||||
* (C) Copyright 2001 |
||||
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch |
||||
* |
||||
* 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 |
||||
* |
||||
* |
||||
* Source partly derived from: |
||||
* linux/drivers/char/pc_keyb.c |
||||
* |
||||
* |
||||
*/ |
||||
#include <common.h> |
||||
#include <asm/processor.h> |
||||
#include <stdio_dev.h> |
||||
#include "ps2kbd.h" |
||||
|
||||
|
||||
unsigned char kbd_read_status(void); |
||||
unsigned char kbd_read_input(void); |
||||
void kbd_send_data(unsigned char data); |
||||
void i8259_mask_irq(unsigned int irq); |
||||
void i8259_unmask_irq(unsigned int irq); |
||||
|
||||
/* used only by send_data - set by keyboard_interrupt */ |
||||
|
||||
|
||||
#undef KBG_DEBUG |
||||
|
||||
#ifdef KBG_DEBUG |
||||
#define PRINTF(fmt,args...) printf (fmt ,##args) |
||||
#else |
||||
#define PRINTF(fmt,args...) |
||||
#endif |
||||
|
||||
#define KBD_STAT_KOBF 0x01 |
||||
#define KBD_STAT_IBF 0x02 |
||||
#define KBD_STAT_SYS 0x04 |
||||
#define KBD_STAT_CD 0x08 |
||||
#define KBD_STAT_LOCK 0x10 |
||||
#define KBD_STAT_MOBF 0x20 |
||||
#define KBD_STAT_TI_OUT 0x40 |
||||
#define KBD_STAT_PARERR 0x80 |
||||
|
||||
#define KBD_INIT_TIMEOUT 2000 /* Timeout in ms for initializing the keyboard */ |
||||
#define KBC_TIMEOUT 250 /* Timeout in ms for sending to keyboard controller */ |
||||
#define KBD_TIMEOUT 2000 /* Timeout in ms for keyboard command acknowledge */ |
||||
/*
|
||||
* Keyboard Controller Commands |
||||
*/ |
||||
|
||||
#define KBD_CCMD_READ_MODE 0x20 /* Read mode bits */ |
||||
#define KBD_CCMD_WRITE_MODE 0x60 /* Write mode bits */ |
||||
#define KBD_CCMD_GET_VERSION 0xA1 /* Get controller version */ |
||||
#define KBD_CCMD_MOUSE_DISABLE 0xA7 /* Disable mouse interface */ |
||||
#define KBD_CCMD_MOUSE_ENABLE 0xA8 /* Enable mouse interface */ |
||||
#define KBD_CCMD_TEST_MOUSE 0xA9 /* Mouse interface test */ |
||||
#define KBD_CCMD_SELF_TEST 0xAA /* Controller self test */ |
||||
#define KBD_CCMD_KBD_TEST 0xAB /* Keyboard interface test */ |
||||
#define KBD_CCMD_KBD_DISABLE 0xAD /* Keyboard interface disable */ |
||||
#define KBD_CCMD_KBD_ENABLE 0xAE /* Keyboard interface enable */ |
||||
#define KBD_CCMD_WRITE_AUX_OBUF 0xD3 /* Write to output buffer as if |
||||
initiated by the auxiliary device */ |
||||
#define KBD_CCMD_WRITE_MOUSE 0xD4 /* Write the following byte to the mouse */ |
||||
|
||||
/*
|
||||
* Keyboard Commands |
||||
*/ |
||||
|
||||
#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */ |
||||
#define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */ |
||||
#define KBD_CMD_ENABLE 0xF4 /* Enable scanning */ |
||||
#define KBD_CMD_DISABLE 0xF5 /* Disable scanning */ |
||||
#define KBD_CMD_RESET 0xFF /* Reset */ |
||||
|
||||
/*
|
||||
* Keyboard Replies |
||||
*/ |
||||
|
||||
#define KBD_REPLY_POR 0xAA /* Power on reset */ |
||||
#define KBD_REPLY_ACK 0xFA /* Command ACK */ |
||||
#define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */ |
||||
|
||||
/*
|
||||
* Status Register Bits |
||||
*/ |
||||
|
||||
#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */ |
||||
#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */ |
||||
#define KBD_STAT_SELFTEST 0x04 /* Self test successful */ |
||||
#define KBD_STAT_CMD 0x08 /* Last write was a command write (0=data) */ |
||||
#define KBD_STAT_UNLOCKED 0x10 /* Zero if keyboard locked */ |
||||
#define KBD_STAT_MOUSE_OBF 0x20 /* Mouse output buffer full */ |
||||
#define KBD_STAT_GTO 0x40 /* General receive/xmit timeout */ |
||||
#define KBD_STAT_PERR 0x80 /* Parity error */ |
||||
|
||||
#define AUX_STAT_OBF (KBD_STAT_OBF | KBD_STAT_MOUSE_OBF) |
||||
|
||||
/*
|
||||
* Controller Mode Register Bits |
||||
*/ |
||||
|
||||
#define KBD_MODE_KBD_INT 0x01 /* Keyboard data generate IRQ1 */ |
||||
#define KBD_MODE_MOUSE_INT 0x02 /* Mouse data generate IRQ12 */ |
||||
#define KBD_MODE_SYS 0x04 /* The system flag (?) */ |
||||
#define KBD_MODE_NO_KEYLOCK 0x08 /* The keylock doesn't affect the keyboard if set */ |
||||
#define KBD_MODE_DISABLE_KBD 0x10 /* Disable keyboard interface */ |
||||
#define KBD_MODE_DISABLE_MOUSE 0x20 /* Disable mouse interface */ |
||||
#define KBD_MODE_KCC 0x40 /* Scan code conversion to PC format */ |
||||
#define KBD_MODE_RFU 0x80 |
||||
|
||||
|
||||
#define KDB_DATA_PORT 0x60 |
||||
#define KDB_COMMAND_PORT 0x64 |
||||
|
||||
#define LED_SCR 0x01 /* scroll lock led */ |
||||
#define LED_CAP 0x04 /* caps lock led */ |
||||
#define LED_NUM 0x02 /* num lock led */ |
||||
|
||||
#define KBD_BUFFER_LEN 0x20 /* size of the keyboardbuffer */ |
||||
|
||||
|
||||
static volatile char kbd_buffer[KBD_BUFFER_LEN]; |
||||
static volatile int in_pointer = 0; |
||||
static volatile int out_pointer = 0; |
||||
|
||||
|
||||
static unsigned char num_lock = 0; |
||||
static unsigned char caps_lock = 0; |
||||
static unsigned char scroll_lock = 0; |
||||
static unsigned char shift = 0; |
||||
static unsigned char ctrl = 0; |
||||
static unsigned char alt = 0; |
||||
static unsigned char e0 = 0; |
||||
static unsigned char leds = 0; |
||||
|
||||
#define DEVNAME "ps2kbd" |
||||
|
||||
/* Simple translation table for the keys */ |
||||
|
||||
static unsigned char kbd_plain_xlate[] = { |
||||
0xff,0x1b, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=','\b','\t', /* 0x00 - 0x0f */ |
||||
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']','\r',0xff, 'a', 's', /* 0x10 - 0x1f */ |
||||
'd', 'f', 'g', 'h', 'j', 'k', 'l', ';','\'', '`',0xff,'\\', 'z', 'x', 'c', 'v', /* 0x20 - 0x2f */ |
||||
'b', 'n', 'm', ',', '.', '/',0xff,0xff,0xff, ' ',0xff,0xff,0xff,0xff,0xff,0xff, /* 0x30 - 0x3f */ |
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff, '7', '8', '9', '-', '4', '5', '6', '+', '1', /* 0x40 - 0x4f */ |
||||
'2', '3', '0', '.',0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 0x50 - 0x5F */ |
||||
'\r',0xff,0xff |
||||
}; |
||||
|
||||
static unsigned char kbd_shift_xlate[] = { |
||||
0xff,0x1b, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+','\b','\t', /* 0x00 - 0x0f */ |
||||
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}','\r',0xff, 'A', 'S', /* 0x10 - 0x1f */ |
||||
'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~',0xff, '|', 'Z', 'X', 'C', 'V', /* 0x20 - 0x2f */ |
||||
'B', 'N', 'M', '<', '>', '?',0xff,0xff,0xff, ' ',0xff,0xff,0xff,0xff,0xff,0xff, /* 0x30 - 0x3f */ |
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff, '7', '8', '9', '-', '4', '5', '6', '+', '1', /* 0x40 - 0x4f */ |
||||
'2', '3', '0', '.',0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 0x50 - 0x5F */ |
||||
'\r',0xff,0xff |
||||
}; |
||||
|
||||
static unsigned char kbd_ctrl_xlate[] = { |
||||
0xff,0x1b, '1',0x00, '3', '4', '5',0x1E, '7', '8', '9', '0',0x1F, '=','\b','\t', /* 0x00 - 0x0f */ |
||||
0x11,0x17,0x05,0x12,0x14,0x18,0x15,0x09,0x0f,0x10,0x1b,0x1d,'\n',0xff,0x01,0x13, /* 0x10 - 0x1f */ |
||||
0x04,0x06,0x08,0x09,0x0a,0x0b,0x0c, ';','\'', '~',0x00,0x1c,0x1a,0x18,0x03,0x16, /* 0x20 - 0x2f */ |
||||
0x02,0x0e,0x0d, '<', '>', '?',0xff,0xff,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xff, /* 0x30 - 0x3f */ |
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff, '7', '8', '9', '-', '4', '5', '6', '+', '1', /* 0x40 - 0x4f */ |
||||
'2', '3', '0', '.',0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 0x50 - 0x5F */ |
||||
'\r',0xff,0xff |
||||
}; |
||||
|
||||
/******************************************************************
|
||||
* Init |
||||
******************************************************************/ |
||||
|
||||
int isa_kbd_init (void) |
||||
{ |
||||
char *result; |
||||
|
||||
result = kbd_initialize (); |
||||
if (result != NULL) { |
||||
result = kbd_initialize (); |
||||
} |
||||
if (result == NULL) { |
||||
printf ("AT Keyboard initialized\n"); |
||||
irq_install_handler (KBD_INTERRUPT, |
||||
(interrupt_handler_t *) kbd_interrupt, |
||||
NULL); |
||||
return (1); |
||||
} else { |
||||
printf ("%s\n", result); |
||||
return (-1); |
||||
} |
||||
} |
||||
|
||||
#ifdef CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE |
||||
extern int overwrite_console (void); |
||||
#else |
||||
int overwrite_console (void) |
||||
{ |
||||
return (0); |
||||
} |
||||
#endif |
||||
|
||||
int drv_isa_kbd_init (void) |
||||
{ |
||||
int error; |
||||
struct stdio_dev kbddev ; |
||||
char *stdinname = getenv ("stdin"); |
||||
|
||||
if(isa_kbd_init() == -1) |
||||
return -1; |
||||
memset (&kbddev, 0, sizeof(kbddev)); |
||||
strcpy(kbddev.name, DEVNAME); |
||||
kbddev.flags = DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM; |
||||
kbddev.putc = NULL ; |
||||
kbddev.puts = NULL ; |
||||
kbddev.getc = kbd_getc ; |
||||
kbddev.tstc = kbd_testc ; |
||||
|
||||
error = stdio_register (&kbddev); |
||||
if(error==0) { |
||||
/* check if this is the standard input device */ |
||||
if(strcmp(stdinname,DEVNAME)==0) { |
||||
/* reassign the console */ |
||||
if(overwrite_console()) { |
||||
return 1; |
||||
} |
||||
error=console_assign(stdin,DEVNAME); |
||||
if(error==0) |
||||
return 1; |
||||
else |
||||
return error; |
||||
} |
||||
return 1; |
||||
} |
||||
return error; |
||||
} |
||||
|
||||
/******************************************************************
|
||||
* Queue handling |
||||
******************************************************************/ |
||||
/* puts character in the queue and sets up the in and out pointer */ |
||||
void kbd_put_queue(char data) |
||||
{ |
||||
if((in_pointer+1)==KBD_BUFFER_LEN) { |
||||
if(out_pointer==0) { |
||||
return; /* buffer full */ |
||||
} else{ |
||||
in_pointer=0; |
||||
} |
||||
} else { |
||||
if((in_pointer+1)==out_pointer) |
||||
return; /* buffer full */ |
||||
in_pointer++; |
||||
} |
||||
kbd_buffer[in_pointer]=data; |
||||
return; |
||||
} |
||||
|
||||
/* test if a character is in the queue */ |
||||
int kbd_testc(void) |
||||
{ |
||||
if(in_pointer==out_pointer) |
||||
return(0); /* no data */ |
||||
else |
||||
return(1); |
||||
} |
||||
/* gets the character from the queue */ |
||||
int kbd_getc(void) |
||||
{ |
||||
char c; |
||||
|
||||
while(in_pointer==out_pointer); |
||||
if((out_pointer+1)==KBD_BUFFER_LEN) |
||||
out_pointer=0; |
||||
else |
||||
out_pointer++; |
||||
c=kbd_buffer[out_pointer]; |
||||
return (int)c; |
||||
|
||||
} |
||||
|
||||
/* set LEDs */ |
||||
|
||||
void kbd_set_leds(void) |
||||
{ |
||||
if(caps_lock==0) |
||||
leds&=~LED_CAP; /* switch caps_lock off */ |
||||
else |
||||
leds|=LED_CAP; /* switch on LED */ |
||||
if(num_lock==0) |
||||
leds&=~LED_NUM; /* switch LED off */ |
||||
else |
||||
leds|=LED_NUM; /* switch on LED */ |
||||
if(scroll_lock==0) |
||||
leds&=~LED_SCR; /* switch LED off */ |
||||
else |
||||
leds|=LED_SCR; /* switch on LED */ |
||||
kbd_send_data(KBD_CMD_SET_LEDS); |
||||
kbd_send_data(leds); |
||||
} |
||||
|
||||
void handle_keyboard_event (unsigned char scancode) |
||||
{ |
||||
unsigned char keycode; |
||||
|
||||
/* Convert scancode to keycode */ |
||||
PRINTF ("scancode %x\n", scancode); |
||||
if (scancode == 0xe0) { |
||||
e0 = 1; /* special charakters */ |
||||
return; |
||||
} |
||||
if (e0 == 1) { |
||||
e0 = 0; /* delete flag */ |
||||
if (!(((scancode & 0x7F) == 0x38) || /* the right ctrl key */ |
||||
((scancode & 0x7F) == 0x1D) || /* the right alt key */ |
||||
((scancode & 0x7F) == 0x35) || /* the right '/' key */ |
||||
((scancode & 0x7F) == 0x1C) || /* the right enter key */ |
||||
((scancode) == 0x48) || /* arrow up */ |
||||
((scancode) == 0x50) || /* arrow down */ |
||||
((scancode) == 0x4b) || /* arrow left */ |
||||
((scancode) == 0x4d))) |
||||
/* arrow right */ |
||||
/* we swallow unknown e0 codes */ |
||||
return; |
||||
} |
||||
/* special cntrl keys */ |
||||
switch (scancode) { |
||||
case 0x48: |
||||
kbd_put_queue (27); |
||||
kbd_put_queue (91); |
||||
kbd_put_queue ('A'); |
||||
return; |
||||
case 0x50: |
||||
kbd_put_queue (27); |
||||
kbd_put_queue (91); |
||||
kbd_put_queue ('B'); |
||||
return; |
||||
case 0x4b: |
||||
kbd_put_queue (27); |
||||
kbd_put_queue (91); |
||||
kbd_put_queue ('D'); |
||||
return; |
||||
case 0x4D: |
||||
kbd_put_queue (27); |
||||
kbd_put_queue (91); |
||||
kbd_put_queue ('C'); |
||||
return; |
||||
case 0x58: /* F12 key */ |
||||
if (ctrl == 1) { |
||||
extern int console_changed; |
||||
|
||||
setenv ("stdin", DEVNAME); |
||||
setenv ("stdout", "vga"); |
||||
console_changed = 1; |
||||
} |
||||
return; |
||||
case 0x2A: |
||||
case 0x36: /* shift pressed */ |
||||
shift = 1; |
||||
return; /* do nothing else */ |
||||
case 0xAA: |
||||
case 0xB6: /* shift released */ |
||||
shift = 0; |
||||
return; /* do nothing else */ |
||||
case 0x38: /* alt pressed */ |
||||
alt = 1; |
||||
return; /* do nothing else */ |
||||
case 0xB8: /* alt released */ |
||||
alt = 0; |
||||
return; /* do nothing else */ |
||||
case 0x1d: /* ctrl pressed */ |
||||
ctrl = 1; |
||||
return; /* do nothing else */ |
||||
case 0x9d: /* ctrl released */ |
||||
ctrl = 0; |
||||
return; /* do nothing else */ |
||||
case 0x46: /* scrollock pressed */ |
||||
scroll_lock = ~scroll_lock; |
||||
kbd_set_leds (); |
||||
return; /* do nothing else */ |
||||
case 0x3A: /* capslock pressed */ |
||||
caps_lock = ~caps_lock; |
||||
kbd_set_leds (); |
||||
return; |
||||
case 0x45: /* numlock pressed */ |
||||
num_lock = ~num_lock; |
||||
kbd_set_leds (); |
||||
return; |
||||
case 0xC6: /* scroll lock released */ |
||||
case 0xC5: /* num lock released */ |
||||
case 0xBA: /* caps lock released */ |
||||
return; /* just swallow */ |
||||
} |
||||
if ((scancode & 0x80) == 0x80) /* key released */ |
||||
return; |
||||
/* now, decide which table we need */ |
||||
if (scancode > (sizeof (kbd_plain_xlate) / sizeof (kbd_plain_xlate[0]))) { /* scancode not in list */ |
||||
PRINTF ("unkown scancode %X\n", scancode); |
||||
return; /* swallow it */ |
||||
} |
||||
/* setup plain code first */ |
||||
keycode = kbd_plain_xlate[scancode]; |
||||
if (caps_lock == 1) { /* caps_lock is pressed, overwrite plain code */ |
||||
if (scancode > (sizeof (kbd_shift_xlate) / sizeof (kbd_shift_xlate[0]))) { /* scancode not in list */ |
||||
PRINTF ("unkown caps-locked scancode %X\n", scancode); |
||||
return; /* swallow it */ |
||||
} |
||||
keycode = kbd_shift_xlate[scancode]; |
||||
if (keycode < 'A') { /* we only want the alphas capital */ |
||||
keycode = kbd_plain_xlate[scancode]; |
||||
} |
||||
} |
||||
if (shift == 1) { /* shift overwrites caps_lock */ |
||||
if (scancode > (sizeof (kbd_shift_xlate) / sizeof (kbd_shift_xlate[0]))) { /* scancode not in list */ |
||||
PRINTF ("unkown shifted scancode %X\n", scancode); |
||||
return; /* swallow it */ |
||||
} |
||||
keycode = kbd_shift_xlate[scancode]; |
||||
} |
||||
if (ctrl == 1) { /* ctrl overwrites caps_lock and shift */ |
||||
if (scancode > (sizeof (kbd_ctrl_xlate) / sizeof (kbd_ctrl_xlate[0]))) { /* scancode not in list */ |
||||
PRINTF ("unkown ctrl scancode %X\n", scancode); |
||||
return; /* swallow it */ |
||||
} |
||||
keycode = kbd_ctrl_xlate[scancode]; |
||||
} |
||||
/* check if valid keycode */ |
||||
if (keycode == 0xff) { |
||||
PRINTF ("unkown scancode %X\n", scancode); |
||||
return; /* swallow unknown codes */ |
||||
} |
||||
|
||||
kbd_put_queue (keycode); |
||||
PRINTF ("%x\n", keycode); |
||||
} |
||||
|
||||
/*
|
||||
* This reads the keyboard status port, and does the |
||||
* appropriate action. |
||||
* |
||||
*/ |
||||
unsigned char handle_kbd_event (void) |
||||
{ |
||||
unsigned char status = kbd_read_status (); |
||||
unsigned int work = 10000; |
||||
|
||||
while ((--work > 0) && (status & KBD_STAT_OBF)) { |
||||
unsigned char scancode; |
||||
|
||||
scancode = kbd_read_input (); |
||||
|
||||
/* Error bytes must be ignored to make the
|
||||
Synaptics touchpads compaq use work */ |
||||
/* Ignore error bytes */ |
||||
if (!(status & (KBD_STAT_GTO | KBD_STAT_PERR))) { |
||||
if (status & KBD_STAT_MOUSE_OBF); /* not supported: handle_mouse_event(scancode); */ |
||||
else |
||||
handle_keyboard_event (scancode); |
||||
} |
||||
status = kbd_read_status (); |
||||
} |
||||
if (!work) |
||||
PRINTF ("pc_keyb: controller jammed (0x%02X).\n", status); |
||||
return status; |
||||
} |
||||
|
||||
/******************************************************************************
|
||||
* Lowlevel Part of keyboard section |
||||
*/ |
||||
unsigned char kbd_read_status(void) |
||||
{ |
||||
return(in8(CONFIG_SYS_ISA_IO_BASE_ADDRESS + KDB_COMMAND_PORT)); |
||||
} |
||||
|
||||
unsigned char kbd_read_input(void) |
||||
{ |
||||
return(in8(CONFIG_SYS_ISA_IO_BASE_ADDRESS + KDB_DATA_PORT)); |
||||
} |
||||
|
||||
void kbd_write_command(unsigned char cmd) |
||||
{ |
||||
out8(CONFIG_SYS_ISA_IO_BASE_ADDRESS + KDB_COMMAND_PORT,cmd); |
||||
} |
||||
|
||||
void kbd_write_output(unsigned char data) |
||||
{ |
||||
out8(CONFIG_SYS_ISA_IO_BASE_ADDRESS + KDB_DATA_PORT, data); |
||||
} |
||||
|
||||
int kbd_read_data(void) |
||||
{ |
||||
int val; |
||||
unsigned char status; |
||||
|
||||
val = -1; |
||||
status = kbd_read_status(); |
||||
if (status & KBD_STAT_OBF) { |
||||
val = kbd_read_input(); |
||||
if (status & (KBD_STAT_GTO | KBD_STAT_PERR)) |
||||
val = -2; |
||||
} |
||||
return val; |
||||
} |
||||
|
||||
int kbd_wait_for_input (void) |
||||
{ |
||||
unsigned long timeout; |
||||
int val; |
||||
|
||||
timeout = KBD_TIMEOUT; |
||||
val = kbd_read_data (); |
||||
while (val < 0) { |
||||
if (timeout-- == 0) |
||||
return -1; |
||||
udelay (1000); |
||||
val = kbd_read_data (); |
||||
} |
||||
return val; |
||||
} |
||||
|
||||
|
||||
int kb_wait (void) |
||||
{ |
||||
unsigned long timeout = KBC_TIMEOUT * 10; |
||||
|
||||
do { |
||||
unsigned char status = handle_kbd_event (); |
||||
|
||||
if (!(status & KBD_STAT_IBF)) |
||||
return 0; /* ok */ |
||||
udelay (1000); |
||||
timeout--; |
||||
} while (timeout); |
||||
return 1; |
||||
} |
||||
|
||||
void kbd_write_command_w (int data) |
||||
{ |
||||
if (kb_wait ()) |
||||
PRINTF ("timeout in kbd_write_command_w\n"); |
||||
kbd_write_command (data); |
||||
} |
||||
|
||||
void kbd_write_output_w (int data) |
||||
{ |
||||
if (kb_wait ()) |
||||
PRINTF ("timeout in kbd_write_output_w\n"); |
||||
kbd_write_output (data); |
||||
} |
||||
|
||||
void kbd_send_data (unsigned char data) |
||||
{ |
||||
unsigned char status; |
||||
|
||||
i8259_mask_irq (KBD_INTERRUPT); /* disable interrupt */ |
||||
kbd_write_output_w (data); |
||||
status = kbd_wait_for_input (); |
||||
if (status == KBD_REPLY_ACK) |
||||
i8259_unmask_irq (KBD_INTERRUPT); /* enable interrupt */ |
||||
} |
||||
|
||||
|
||||
char *kbd_initialize (void) |
||||
{ |
||||
int status; |
||||
|
||||
in_pointer = 0; /* delete in Buffer */ |
||||
out_pointer = 0; |
||||
/*
|
||||
* Test the keyboard interface. |
||||
* This seems to be the only way to get it going. |
||||
* If the test is successful a x55 is placed in the input buffer. |
||||
*/ |
||||
kbd_write_command_w (KBD_CCMD_SELF_TEST); |
||||
if (kbd_wait_for_input () != 0x55) |
||||
return "Kbd: failed self test"; |
||||
/*
|
||||
* Perform a keyboard interface test. This causes the controller |
||||
* to test the keyboard clock and data lines. The results of the |
||||
* test are placed in the input buffer. |
||||
*/ |
||||
kbd_write_command_w (KBD_CCMD_KBD_TEST); |
||||
if (kbd_wait_for_input () != 0x00) |
||||
return "Kbd: interface failed self test"; |
||||
/*
|
||||
* Enable the keyboard by allowing the keyboard clock to run. |
||||
*/ |
||||
kbd_write_command_w (KBD_CCMD_KBD_ENABLE); |
||||
status = kbd_wait_for_input (); |
||||
/*
|
||||
* Reset keyboard. If the read times out |
||||
* then the assumption is that no keyboard is |
||||
* plugged into the machine. |
||||
* This defaults the keyboard to scan-code set 2. |
||||
* |
||||
* Set up to try again if the keyboard asks for RESEND. |
||||
*/ |
||||
do { |
||||
kbd_write_output_w (KBD_CMD_RESET); |
||||
status = kbd_wait_for_input (); |
||||
if (status == KBD_REPLY_ACK) |
||||
break; |
||||
if (status != KBD_REPLY_RESEND) { |
||||
PRINTF ("status: %X\n", status); |
||||
return "Kbd: reset failed, no ACK"; |
||||
} |
||||
} while (1); |
||||
if (kbd_wait_for_input () != KBD_REPLY_POR) |
||||
return "Kbd: reset failed, no POR"; |
||||
|
||||
/*
|
||||
* Set keyboard controller mode. During this, the keyboard should be |
||||
* in the disabled state. |
||||
* |
||||
* Set up to try again if the keyboard asks for RESEND. |
||||
*/ |
||||
do { |
||||
kbd_write_output_w (KBD_CMD_DISABLE); |
||||
status = kbd_wait_for_input (); |
||||
if (status == KBD_REPLY_ACK) |
||||
break; |
||||
if (status != KBD_REPLY_RESEND) |
||||
return "Kbd: disable keyboard: no ACK"; |
||||
} while (1); |
||||
|
||||
kbd_write_command_w (KBD_CCMD_WRITE_MODE); |
||||
kbd_write_output_w (KBD_MODE_KBD_INT |
||||
| KBD_MODE_SYS |
||||
| KBD_MODE_DISABLE_MOUSE | KBD_MODE_KCC); |
||||
|
||||
/* AMCC powerpc portables need this to use scan-code set 1 -- Cort */ |
||||
kbd_write_command_w (KBD_CCMD_READ_MODE); |
||||
if (!(kbd_wait_for_input () & KBD_MODE_KCC)) { |
||||
/*
|
||||
* If the controller does not support conversion, |
||||
* Set the keyboard to scan-code set 1. |
||||
*/ |
||||
kbd_write_output_w (0xF0); |
||||
kbd_wait_for_input (); |
||||
kbd_write_output_w (0x01); |
||||
kbd_wait_for_input (); |
||||
} |
||||
kbd_write_output_w (KBD_CMD_ENABLE); |
||||
if (kbd_wait_for_input () != KBD_REPLY_ACK) |
||||
return "Kbd: enable keyboard: no ACK"; |
||||
|
||||
/*
|
||||
* Finally, set the typematic rate to maximum. |
||||
*/ |
||||
kbd_write_output_w (KBD_CMD_SET_RATE); |
||||
if (kbd_wait_for_input () != KBD_REPLY_ACK) |
||||
return "Kbd: Set rate: no ACK"; |
||||
kbd_write_output_w (0x00); |
||||
if (kbd_wait_for_input () != KBD_REPLY_ACK) |
||||
return "Kbd: Set rate: no ACK"; |
||||
return NULL; |
||||
} |
||||
|
||||
void kbd_interrupt(void) |
||||
{ |
||||
handle_kbd_event(); |
||||
} |
@ -1,41 +0,0 @@ |
||||
/*
|
||||
* (C) Copyright 2002 |
||||
* John W. Linville, linville@tuxdriver.com |
||||
* |
||||
* Modified from code for support of MIP405 and PIP405 boards. Previous |
||||
* copyright follows. |
||||
* |
||||
* (C) Copyright 2001 |
||||
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch |
||||
* |
||||
* 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 _KBD_H_ |
||||
#define _KBD_H_ |
||||
|
||||
extern int kbd_testc(void); |
||||
extern int kbd_getc(void); |
||||
extern void kbd_interrupt(void); |
||||
extern char *kbd_initialize(void); |
||||
|
||||
unsigned char kbd_is_init(void); |
||||
#define KBD_INTERRUPT 1 |
||||
#endif |
@ -1,245 +0,0 @@ |
||||
#include <common.h> |
||||
#include <ns16550.h> |
||||
#include "short_types.h" |
||||
#include "memio.h" |
||||
#include "articiaS.h" |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
#ifndef CONFIG_SYS_NS16550 |
||||
static uint32 ComPort1; |
||||
|
||||
uint16 SerialEcho = 1; |
||||
|
||||
|
||||
#define RECEIVER_HOLDING 0 |
||||
#define TRANSMITTER_HOLDING 0 |
||||
#define INTERRUPT_ENABLE 1 |
||||
#define INTERRUPT_STATUS 2 |
||||
#define FIFO_CONTROL 2 |
||||
#define LINE_CONTROL 3 |
||||
#define MODEM_CONTROL 4 |
||||
#define LINE_STATUS 5 |
||||
#define MODEM_STATUS 6 |
||||
#define SCRATCH_PAD 7 |
||||
|
||||
#define DIVISOR_LATCH_LSB 0 |
||||
#define DIVISOR_LATCH_MSB 1 |
||||
#define PRESCALER_DIVISION 5 |
||||
|
||||
#define COM_WRITE_BYTE(reg, byte) out_byte((ComPort1+reg), byte) |
||||
#define COM_READ_BYTE(reg) in_byte((ComPort1+reg)) |
||||
|
||||
static int serial_init_done = 0; |
||||
|
||||
void serial_init (void) |
||||
{ |
||||
#if 0 |
||||
uint32 clock_divisor = 115200 / baudrate; |
||||
uint8 cfg; |
||||
uint8 a; |
||||
uint16 devfn = 7 << 3; |
||||
|
||||
if (serial_init_done) |
||||
return; |
||||
|
||||
/* Enter configuration mode */ |
||||
cfg = pci_read_cfg_byte (0, devfn, 0x85); |
||||
pci_write_cfg_byte (0, devfn, 0x85, cfg | 0x02); |
||||
|
||||
/* Set serial port COM1 as 3F8 */ |
||||
out_byte (0x3F0, 0xE7); |
||||
out_byte (0x3f1, 0xfe); |
||||
|
||||
/* Set serial port COM2 as 2F8 */ |
||||
out_byte (0x3f0, 0xe8); |
||||
out_byte (0x3f1, 0xeb); |
||||
|
||||
/* Enable */ |
||||
out_byte (0x3f0, 0xe2); |
||||
a = in_byte (0x3f1); |
||||
a |= 0xc; |
||||
out_byte (0x3f0, 0xe2); |
||||
out_byte (0x3f1, a); |
||||
|
||||
/* Reset the configuration mode */ |
||||
pci_write_cfg_byte (0, devfn, 0x85, cfg); |
||||
#endif |
||||
|
||||
ComPort1 = 0x3F8; |
||||
|
||||
/* Disable interrupts */ |
||||
COM_WRITE_BYTE (INTERRUPT_ENABLE, 0x00); |
||||
|
||||
/* Set baud rate */ |
||||
/* COM_WRITE_BYTE(LINE_CONTROL, 0x83); */ |
||||
/* COM_WRITE_BYTE(DIVISOR_LATCH_LSB, (uint8)(clock_divisor & 0xFF)); */ |
||||
/* COM_WRITE_BYTE(DIVISOR_LATCH_MSB, (uint8)(clock_divisor >> 8)); */ |
||||
/* __asm__("eieio"); */ |
||||
|
||||
/* Set 8-N-1 */ |
||||
COM_WRITE_BYTE (LINE_CONTROL, 0x03); |
||||
__asm__ ("eieio"); |
||||
|
||||
/* Disable FIFO */ |
||||
COM_WRITE_BYTE (MODEM_CONTROL, 0x03); |
||||
COM_WRITE_BYTE (FIFO_CONTROL, 0x07); |
||||
|
||||
__asm__ ("eieio"); |
||||
serial_init_done = 1; |
||||
} |
||||
|
||||
extern int console_changed; |
||||
|
||||
void serial_putc (const char sendme) |
||||
{ |
||||
if (sendme == '\n') { |
||||
while ((in_byte (0x3FD) & 0x40) == 0); |
||||
out_byte (0x3f8, 0x0D); |
||||
} |
||||
|
||||
while ((in_byte (0x3FD) & 0x40) == 0); |
||||
out_byte (0x3f8, sendme); |
||||
} |
||||
|
||||
int serial_getc (void) |
||||
{ |
||||
#if 0 |
||||
uint8 c; |
||||
|
||||
for (;;) { |
||||
uint8 x = in_byte (0x3FD); |
||||
|
||||
if (x & 0x01) |
||||
break; |
||||
|
||||
if (x & 0x0C) |
||||
out_byte (0x3fd, 0x0c); |
||||
} |
||||
|
||||
c = in_byte (0x3F8); |
||||
|
||||
return c; |
||||
#else |
||||
while ((in_byte (0x3FD) & 0x01) == 0) { |
||||
if (console_changed != 0) { |
||||
printf ("Console changed\n"); |
||||
console_changed = 0; |
||||
return 0; |
||||
} |
||||
} |
||||
return in_byte (0x3F8); |
||||
#endif |
||||
} |
||||
|
||||
int serial_tstc (void) |
||||
{ |
||||
return (in_byte (0x03FD) & 0x01) != 0; |
||||
} |
||||
|
||||
void serial_debug_putc (int c) |
||||
{ |
||||
serial_puts ("DBG"); |
||||
serial_putc (c); |
||||
serial_putc (0x0d); |
||||
serial_putc (0x0A); |
||||
} |
||||
|
||||
#else |
||||
|
||||
const NS16550_t Com0 = (NS16550_t) CONFIG_SYS_NS16550_COM1; |
||||
const NS16550_t Com1 = (NS16550_t) CONFIG_SYS_NS16550_COM2; |
||||
|
||||
int serial_init (void) |
||||
{ |
||||
uint32 clock_divisor = 115200 / gd->baudrate; |
||||
|
||||
NS16550_init (Com0, clock_divisor); |
||||
/* NS16550_reinit(Com1, clock_divisor); */ |
||||
/* serial_puts("COM1: 3F8h initalized"); */ |
||||
|
||||
return (0); |
||||
} |
||||
|
||||
#if 0 |
||||
void serial_putc (const char c) |
||||
{ |
||||
NS16550_putc (Com0, c); |
||||
if (c == '\n') |
||||
NS16550_putc (Com0, 0x0D); |
||||
} |
||||
|
||||
int serial_getc (void) |
||||
{ |
||||
return (int) NS16550_getc (Com0); |
||||
} |
||||
|
||||
int serial_tstc (void) |
||||
{ |
||||
return NS16550_tstc (Com0); |
||||
} |
||||
#else |
||||
void serial_putc (const char sendme) |
||||
{ |
||||
if (sendme == '\n') { |
||||
while ((in_byte (0x3FD) & 0x40) == 0); |
||||
out_byte (0x3f8, 0x0D); |
||||
} |
||||
|
||||
while ((in_byte (0x3FD) & 0x40) == 0); |
||||
out_byte (0x3f8, sendme); |
||||
} |
||||
|
||||
|
||||
extern int console_changed; |
||||
|
||||
int serial_getc (void) |
||||
{ |
||||
#if 0 |
||||
uint8 c; |
||||
|
||||
for (;;) { |
||||
uint8 x = in_byte (0x3FD); |
||||
|
||||
if (x & 0x01) |
||||
break; |
||||
|
||||
if (x & 0x0C) |
||||
out_byte (0x3fd, 0x0c); |
||||
} |
||||
|
||||
c = in_byte (0x3F8); |
||||
|
||||
return c; |
||||
#else |
||||
while ((in_byte (0x3FD) & 0x01) == 0) { |
||||
if (console_changed != 0) { |
||||
console_changed = 0; |
||||
return 0; |
||||
} |
||||
} |
||||
|
||||
return in_byte (0x3F8); |
||||
#endif |
||||
} |
||||
|
||||
int serial_tstc (void) |
||||
{ |
||||
return (in_byte (0x03FD) & 0x01) != 0; |
||||
} |
||||
#endif |
||||
|
||||
#endif |
||||
|
||||
void serial_puts (const char *string) |
||||
{ |
||||
while (*string) |
||||
serial_putc (*string++); |
||||
} |
||||
|
||||
void serial_setbrg (void) |
||||
{ |
||||
uint32 clock_divisor = 115200 / gd->baudrate; |
||||
|
||||
NS16550_init (Com0, clock_divisor); |
||||
} |
@ -1,36 +0,0 @@ |
||||
/*
|
||||
* short type names |
||||
* |
||||
* (C) Copyright 2002 |
||||
* Hyperion Entertainment, ThomasF@hyperion-entertainment.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 _SHORT_TYPES_H |
||||
#define _SHORT_TYPES_H |
||||
|
||||
typedef unsigned long uint32; |
||||
typedef long int32; |
||||
typedef unsigned short uint16; |
||||
typedef short int16; |
||||
typedef unsigned char uint8; |
||||
typedef signed char int8; |
||||
|
||||
#endif |
@ -1,206 +0,0 @@ |
||||
#include "memio.h" |
||||
#include "articiaS.h" |
||||
|
||||
#ifndef FALSE |
||||
#define FALSE 0 |
||||
#endif |
||||
|
||||
#ifndef TRUE |
||||
#define TRUE 1 |
||||
#endif |
||||
|
||||
|
||||
void sm_write_mode(void) |
||||
{ |
||||
out_byte(0xA539, 0x00); |
||||
out_byte(0xA53A, 0x03); |
||||
} |
||||
|
||||
void sm_read_mode(void) |
||||
{ |
||||
out_byte(0xA53A, 0x02); |
||||
out_byte(0xA539, 0x02); |
||||
} |
||||
|
||||
void sm_write_byte(uint8 writeme) |
||||
{ |
||||
int i; |
||||
int level; |
||||
|
||||
out_byte(0xA539, 0x00); |
||||
|
||||
level = 0; |
||||
|
||||
for (i=0; i<8; i++) |
||||
{ |
||||
if ((writeme & 0x80) == (level<<7)) |
||||
{ |
||||
/* Bit did not change, rewrite strobe */ |
||||
out_byte(0xA539, level | 0x02); |
||||
out_byte(0xA539, level); |
||||
} |
||||
else |
||||
{ |
||||
/* Bit changed, set bit, then strobe */ |
||||
level = (writeme & 0x80) >> 7; |
||||
out_byte(0xA539, level); |
||||
out_byte(0xA539, level | 0x02); |
||||
out_byte(0xA539, level); |
||||
} |
||||
writeme <<= 1; |
||||
} |
||||
out_byte(0xA539, 0x00); |
||||
} |
||||
|
||||
uint8 sm_read_byte(void) |
||||
{ |
||||
uint8 retme, r; |
||||
int i; |
||||
|
||||
retme = 0; |
||||
for (i=0; i<8; i++) |
||||
{ |
||||
retme <<= 1; |
||||
out_byte(0xA539, 0x00); |
||||
out_byte(0xA539, 0x02); |
||||
r = in_byte(0xA538) & 0x01; |
||||
retme |= r; |
||||
} |
||||
|
||||
return retme; |
||||
} |
||||
|
||||
int sm_get_ack(void) |
||||
{ |
||||
uint8 r; |
||||
r = in_byte(0xA538); |
||||
if ((r&0x01) == 0) return TRUE; |
||||
else return FALSE; |
||||
} |
||||
|
||||
void sm_write_ack(void) |
||||
{ |
||||
out_byte(0xA539, 0x00); |
||||
out_byte(0xA539, 0x02); |
||||
out_byte(0xA539, 0x00); |
||||
} |
||||
|
||||
void sm_write_nack(void) |
||||
{ |
||||
out_byte(0xA539, 0x01); |
||||
out_byte(0xA539, 0x03); |
||||
out_byte(0xA539, 0x01); |
||||
} |
||||
|
||||
void sm_send_start(void) |
||||
{ |
||||
out_byte(0xA539, 0x03); |
||||
out_byte(0xA539, 0x02); |
||||
} |
||||
|
||||
void sm_send_stop(void) |
||||
{ |
||||
out_byte(0xA539, 0x02); |
||||
out_byte(0xA539, 0x03); |
||||
} |
||||
|
||||
int sm_read_byte_from_device(uint8 addr, uint8 reg, uint8 *storage) |
||||
{ |
||||
/* S Addr Wr */ |
||||
sm_write_mode(); |
||||
sm_send_start(); |
||||
sm_write_byte((addr<<1)); |
||||
|
||||
/* [A] */ |
||||
sm_read_mode(); |
||||
if (sm_get_ack() == FALSE) return FALSE; |
||||
|
||||
/* Comm */ |
||||
sm_write_mode(); |
||||
sm_write_byte(reg); |
||||
|
||||
/* [A] */ |
||||
sm_read_mode(); |
||||
if (sm_get_ack() == FALSE) return FALSE; |
||||
|
||||
/* S Addr Rd */ |
||||
sm_write_mode(); |
||||
sm_send_start(); |
||||
sm_write_byte((addr<<1)|1); |
||||
|
||||
/* [A] */ |
||||
sm_read_mode(); |
||||
if (sm_get_ack() == FALSE) return FALSE; |
||||
|
||||
/* [Data] */ |
||||
*storage = sm_read_byte(); |
||||
|
||||
/* NA */ |
||||
sm_write_mode(); |
||||
sm_write_nack(); |
||||
sm_send_stop(); |
||||
|
||||
return TRUE; |
||||
} |
||||
|
||||
void sm_init(void) |
||||
{ |
||||
/* Switch to PMC mode */ |
||||
pci_write_cfg_byte(0, 0, REG_GROUP, (uint8)(REG_GROUP_SPECIAL|REG_GROUP_POWER)); |
||||
|
||||
/* Set GPIO Base */ |
||||
pci_write_cfg_long(0, 0, 0x40, 0xa500); |
||||
|
||||
/* Enable GPIO */ |
||||
pci_write_cfg_byte(0, 0, 0x44, 0x11); |
||||
|
||||
/* Set both GPIO 0 and 1 as output */ |
||||
out_byte(0xA53A, 0x03); |
||||
} |
||||
|
||||
|
||||
void sm_term(void) |
||||
{ |
||||
/* Switch to normal mode */ |
||||
pci_write_cfg_byte(0, 0, REG_GROUP, 0); |
||||
} |
||||
|
||||
|
||||
int sm_get_data(uint8 *DataArray, int dimm_socket) |
||||
{ |
||||
int j; |
||||
|
||||
#if 0 |
||||
/* Switch to PMC mode */ |
||||
pci_write_cfg_byte(0, 0, REG_GROUP, (uint8)(REG_GROUP_SPECIAL|REG_GROUP_POWER)); |
||||
|
||||
/* Set GPIO Base */ |
||||
pci_write_cfg_long(0, 0, 0x40, 0xa500); |
||||
|
||||
/* Enable GPIO */ |
||||
pci_write_cfg_byte(0, 0, 0x44, 0x11); |
||||
|
||||
/* Set both GPIO 0 and 1 as output */ |
||||
out_byte(0xA53A, 0x03); |
||||
#endif |
||||
|
||||
sm_init(); |
||||
/* Start reading the rom */ |
||||
|
||||
j = 0; |
||||
|
||||
do |
||||
{ |
||||
if (sm_read_byte_from_device(dimm_socket, (uint8)j, DataArray) == FALSE) |
||||
{ |
||||
sm_term(); |
||||
return FALSE; |
||||
} |
||||
|
||||
DataArray++; |
||||
j++; |
||||
} while (j < 128); |
||||
|
||||
sm_term(); |
||||
return TRUE; |
||||
} |
@ -1,22 +0,0 @@ |
||||
#ifndef _SMBUS_H_ |
||||
#define _SMBUS_H_ |
||||
|
||||
#include "short_types.h" |
||||
|
||||
#define SM_DIMM0_ADDR 0x51 |
||||
#define SM_DIMM1_ADDR 0x52 |
||||
|
||||
void sm_write_mode(void); |
||||
void sm_read_mode(void); |
||||
void sm_write_byte(uint8 writeme); |
||||
uint8 sm_read_byte(void); |
||||
int sm_get_ack(void); |
||||
void sm_write_ack(void); |
||||
void sm_write_nack(void); |
||||
void sm_send_start(void); |
||||
void sm_send_stop(void); |
||||
int sm_read_byte_from_device(uint8 addr, uint8 reg, uint8 *storage); |
||||
int sm_get_data(uint8 *DataArray, int dimm_socket); |
||||
void sm_init(void); |
||||
void sm_term(void); |
||||
#endif |
@ -1,198 +0,0 @@ |
||||
|
||||
/*------------------------------------------------------*/ |
||||
/* TERON Articia / SDRAM Init */ |
||||
/*------------------------------------------------------*/ |
||||
|
||||
* XD_CTL = 0x81000000 (0x74) |
||||
|
||||
* HBUS_ACC_CTL_0 &= 0xFFFFFDFF (0x5c) |
||||
/* host bus access ctl reg 2(5e) */ |
||||
/* set - CPU read from memory data one clock after data is latched */ |
||||
|
||||
* GLOBL_INFO_0 |= 0x00004000 (0x50) |
||||
/* global info register 2 (52), AGP/PCI bus 1 arbiter is addressed in Articia S */ |
||||
|
||||
PCI_1_SB_CONFIG_0 |= 0x00000400 (0x80d0) |
||||
/* PCI1 side band config reg 2 (d2), enable read acces while write buffer not empty */ |
||||
|
||||
MEM_RAS_CTL_0 |= 0x3f000000 (0xcc) |
||||
&= 0x3fffffff |
||||
/* RAS park control reg 0(cc), park access enable is set */ |
||||
|
||||
HOST_RDBUF_CTL |= 0x10000000 (0x70) |
||||
&= 0x10ffffff |
||||
/* host read buffer control reg, enable prefetch for CPU read from DRAM control */ |
||||
|
||||
HBUS_ACC_CTL_0 |= 0x0100001f (0x5c) |
||||
&= 0xf1ffffff |
||||
/* host bus access control register, enable CPU address bus pipe control */ |
||||
/* two outstanding requests, *** changed to 2 from 3 */ |
||||
/* enable line merge write control for CPU write to system memory, PCI 1 */ |
||||
/* and PCI 0 bus memory; enable page merge write control for write to */ |
||||
/* PCI bus 0 & bus 1 memory */ |
||||
|
||||
SRAM_CTL |= 0x00004000 (0xc8) |
||||
&= 0xffbff7ff |
||||
/* DRAM detail timing control register 1 (ca), bit 3 set to 0 */ |
||||
/* DRAM start access latency control - wait for one clock */ |
||||
/* ff9f changed to ffbf */ |
||||
|
||||
DIM0_TIM_CTL_0 = 0x737d737d (0xc9) |
||||
/* DRAM timing control for dimm0 & dimm1; set wait one clock */ |
||||
/* cycle for next data access */ |
||||
|
||||
DIM2_TIM_CTL_0 = 0x737d737d (0xca) |
||||
/* DRAM timing control for dimm2 & dimm3; set wait one clock */ |
||||
/* cycle for next data access */ |
||||
|
||||
DIM0_BNK0_CTL_0 = BNK0_RAM_SIZ_128MB (0x90) |
||||
/* set dimm0 bank0 for 128 MB */ |
||||
|
||||
DIM0_BNK1_CTL_0 = BNK1_RAM_SIZ_128MB (0x94) |
||||
/* set dimm0 for bank1 */ |
||||
|
||||
DIM0_TIM_CTL_0 = 0xf3bf0000 (0xc9) |
||||
/* dimm0 timing control register; RAS - CAS latency - 4 clock */ |
||||
/* CAS access latency - 3 wait; pre-charge latency - 3 wait */ |
||||
/* pre-charge command period control - 5 clock; wait one clock */ |
||||
/* cycle for next data access; read to write access latency control */ |
||||
/* - 2 clock cycles */ |
||||
|
||||
DRAM_GBL_CTL_0 |= 0x00000100 (0xc0) |
||||
&= 0xffff01ff |
||||
/* memory global control register - support buffer sdram on bank 0 */ |
||||
|
||||
DRAM_ECC_CTL_0 |= 0x00260000 (0xc4) |
||||
&= 0xff26ffff |
||||
/* enable ECC; enable read, modify, write control */ |
||||
|
||||
DRAM_REF_CTL_0 = DRAM_REF_DATA (0xb8) |
||||
/* set DRAM refresh parameters *** changed to 00940100 */ |
||||
|
||||
nop |
||||
nop |
||||
nop |
||||
nop |
||||
nop |
||||
|
||||
DRAM_ECC_CTL_0 |= 0x20243280 (0xc4) |
||||
/* turn off ecc */ |
||||
/* for SDRAM bank 0 */ |
||||
|
||||
DRAM_ECC_CTL_0 |= 0x20243290 (0xc4) ? |
||||
/* for SDRAM bank 1 */ |
||||
|
||||
|
||||
/* Additional Stuff...*/ |
||||
|
||||
GLOBL_CTRL |= 0x20000b00 (0x54) |
||||
|
||||
PCI_0_SB_CONFIG |= 0x04100007 (0xd0) |
||||
/* PCI 0 Side band config reg*/ |
||||
|
||||
0x8000083c |= 0x00080000 |
||||
/* Disable VGA decode on PCI Bus 1 */ |
||||
|
||||
|
||||
/*End Additional Stuff..*/ |
||||
|
||||
/*--------------------------------------------------------------*/ |
||||
/* TERON serial port initialization code */ |
||||
/*--------------------------------------------------------------*/ |
||||
|
||||
0x84380080 |= 0x00030000 |
||||
/* enable super IO configuration VIA chip Register 85 */ |
||||
/* Enable super I/O config mode */ |
||||
|
||||
0xfe0003f0 = 0xe2 |
||||
bl delay1 |
||||
|
||||
0xfe0003f1 = 0x0f |
||||
bl delay1 |
||||
/* enable com1 & com2, parallel port disabled */ |
||||
|
||||
0xfe0003f0 = 0xe7 |
||||
bl delay1 |
||||
/* let's make com1 base as 0x3f8 */ |
||||
|
||||
0xfe0003f1 = 0xfe |
||||
bl delay1 |
||||
|
||||
0xfe0003f0 = 0xe8 |
||||
bl delay1 |
||||
/* let's make com2 base as 0x2f8 */ |
||||
|
||||
0xfe0003f1 = 0xbe |
||||
|
||||
0x84380080 &= 0xfffdffff |
||||
/* closing super IO configuration VIA chip Register 85 */ |
||||
|
||||
|
||||
/* -------------------------------*/ |
||||
|
||||
0xfe0003fb = 0x83 |
||||
bl delay1 |
||||
/*latch enable word length -8 bit */ /* set mslab bit */ |
||||
0xfe0003f8 = 0x0c |
||||
bl delay1 |
||||
/* set baud rate lsb for 9600 baud */ |
||||
0xfe0003f9 = 0x0 |
||||
bl delay1 |
||||
/* set baud rate msb for 9600 baud */ |
||||
0xfe0003fb = 0x03 |
||||
bl delay1 |
||||
/* reset mslab */ |
||||
|
||||
/*--------------------------------------------------------------*/ |
||||
/* END TERON Serial Port Initialization Code */ |
||||
/*--------------------------------------------------------------*/ |
||||
|
||||
|
||||
/*--------------------------------------------------------------*/ |
||||
/* END TERON Articia / SDRAM Initialization code */ |
||||
/*--------------------------------------------------------------*/ |
||||
|
||||
Proposed from Documentation: |
||||
|
||||
write dmem 0xfec00cf8 0x50000080 |
||||
write dmem 0xfee00cfc 0xc0305411 |
||||
|
||||
Writes to index 0x50-0x53. |
||||
0x50: Global Information Register 0 |
||||
0xC0 = Little Endian CPU, Sequential order Burst |
||||
0x51: Global Information Register 1 |
||||
Read only, 0x30 = Provides PowerPC and X86 support |
||||
0x52: Global Information Register 2 |
||||
0x05 = 64/128 bit CPU bus support |
||||
0x53: Global Information Register 3 |
||||
0x80 = PCI Bus 0 grant active time is 1 clock after REQ# deasserted |
||||
|
||||
write dmem 0xfec00cf8 0x5c000080 |
||||
write dmem 0xfee00cfc 0xb300011F |
||||
|
||||
write dmem 0xfec00cf8 0xc8000080 |
||||
write dmem 0xfee00cfc 0x0020f100 |
||||
|
||||
write dmem 0xfec00cf8 0x90000080 |
||||
write dmem 0xfee00cfc 0x007fe700 |
||||
|
||||
write dmem 0xfec00cf8 0x9400080 |
||||
write dmem 0xfee00cfc 0x007fe700 |
||||
|
||||
write dmem 0xfec00cf8 0xb0000080 |
||||
write dmem 0xfee00cfc 0x737d737d |
||||
|
||||
write dmem 0xfec00cf8 0xb4000080 |
||||
write dmem 0xfee00cfc 0x737d737d |
||||
|
||||
write dmem 0xfec00cf8 0xc0000080 |
||||
write dmem 0xfee00cfc 0x40005500 |
||||
|
||||
write dmem 0xfec00cf8 0xb8000080 |
||||
write dmem 0xfee00cfc 0x00940100 |
||||
|
||||
write dmem 0xfec00cf8 0xc4000080 |
||||
write dmem 0xfee00cfc 0x00003280 |
||||
|
||||
write dmem 0xfec00cf8 0xc4000080 |
||||
write dmem 0xfee00cfc 0x00003290 |
@ -1,3 +0,0 @@ |
||||
- Init interrupt controller |
||||
- init sdram |
||||
- init ide controller |
@ -1,136 +0,0 @@ |
||||
/* |
||||
* (C) Copyright 2001 |
||||
* Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc. |
||||
* |
||||
* (C) Copyright 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 |
||||
*/ |
||||
|
||||
/* |
||||
* u-boot.lds - linker script for U-Boot on the AmigaOneG3SE Board. |
||||
*/ |
||||
|
||||
OUTPUT_ARCH(powerpc) |
||||
/* Do we need any of these for elf? |
||||
__DYNAMIC = 0; */ |
||||
SECTIONS |
||||
{ |
||||
/* Read-only sections, merged into text segment: */ |
||||
. = + SIZEOF_HEADERS; |
||||
.interp : { *(.interp) } |
||||
.hash : { *(.hash) } |
||||
.dynsym : { *(.dynsym) } |
||||
.dynstr : { *(.dynstr) } |
||||
.rel.text : { *(.rel.text) } |
||||
.rela.text : { *(.rela.text) } |
||||
.rel.data : { *(.rel.data) } |
||||
.rela.data : { *(.rela.data) } |
||||
.rel.rodata : { *(.rel.rodata) } |
||||
.rela.rodata : { *(.rela.rodata) } |
||||
.rel.got : { *(.rel.got) } |
||||
.rela.got : { *(.rela.got) } |
||||
.rel.ctors : { *(.rel.ctors) } |
||||
.rela.ctors : { *(.rela.ctors) } |
||||
.rel.dtors : { *(.rel.dtors) } |
||||
.rela.dtors : { *(.rela.dtors) } |
||||
.rel.bss : { *(.rel.bss) } |
||||
.rela.bss : { *(.rela.bss) } |
||||
.rel.plt : { *(.rel.plt) } |
||||
.rela.plt : { *(.rela.plt) } |
||||
.init : { *(.init) } |
||||
.plt : { *(.plt) } |
||||
.text : |
||||
{ |
||||
arch/powerpc/cpu/74xx_7xx/start.o (.text) |
||||
/* store the environment in a seperate sector in the boot flash */ |
||||
/* . = env_offset; */ |
||||
common/env_embedded.o(.text) |
||||
|
||||
*(.text) |
||||
*(.got1) |
||||
} |
||||
_etext = .; |
||||
PROVIDE (etext = .); |
||||
.rodata : |
||||
{ |
||||
*(.eh_frame) |
||||
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) |
||||
} |
||||
.fini : { *(.fini) } =0 |
||||
.ctors : { *(.ctors) } |
||||
.dtors : { *(.dtors) } |
||||
|
||||
/* Read-write section, merged into data segment: */ |
||||
. = (. + 0x00FF) & 0xFFFFFF00; |
||||
_erotext = .; |
||||
PROVIDE (erotext = .); |
||||
.reloc : |
||||
{ |
||||
*(.got) |
||||
_GOT2_TABLE_ = .; |
||||
*(.got2) |
||||
_FIXUP_TABLE_ = .; |
||||
*(.fixup) |
||||
} |
||||
__got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; |
||||
__fixup_entries = (. - _FIXUP_TABLE_)>>2; |
||||
|
||||
.data : |
||||
{ |
||||
*(.data) |
||||
*(.data1) |
||||
*(.sdata) |
||||
*(.sdata2) |
||||
*(.dynamic) |
||||
CONSTRUCTORS |
||||
} |
||||
_edata = .; |
||||
PROVIDE (edata = .); |
||||
|
||||
. = .; |
||||
__u_boot_cmd_start = .; |
||||
.u_boot_cmd : { *(.u_boot_cmd) } |
||||
__u_boot_cmd_end = .; |
||||
|
||||
|
||||
. = .; |
||||
__start___ex_table = .; |
||||
__ex_table : { *(__ex_table) } |
||||
__stop___ex_table = .; |
||||
|
||||
. = ALIGN(256); |
||||
__init_begin = .; |
||||
.text.init : { *(.text.init) } |
||||
.data.init : { *(.data.init) } |
||||
. = ALIGN(256); |
||||
__init_end = .; |
||||
|
||||
__bss_start = .; |
||||
.bss (NOLOAD) : |
||||
{ |
||||
*(.sbss) *(.scommon) |
||||
*(.dynbss) |
||||
*(.bss) |
||||
*(COMMON) |
||||
} |
||||
_end = ALIGN(4) /*.*/ ; |
||||
PROVIDE (end = ALIGN(4) /*.*/); |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -1,192 +0,0 @@ |
||||
/*
|
||||
* (C) Copyright 2001 |
||||
* Denis Peter, MPL AG Switzerland |
||||
* |
||||
* 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 |
||||
* |
||||
* Note: Part of this code has been derived from linux |
||||
* |
||||
*/ |
||||
#ifndef _USB_UHCI_H_ |
||||
#define _USB_UHCI_H_ |
||||
|
||||
#undef USB_UHCI_VEND_ID |
||||
#define USB_UHCI_VEND_ID PCI_VENDOR_ID_VIA |
||||
#undef USB_UHCI_DEV_ID |
||||
#define USB_UHCI_DEV_ID 0x3038 |
||||
|
||||
/* Command register */ |
||||
#define USBCMD 0 |
||||
#define USBCMD_RS 0x0001 /* Run/Stop */ |
||||
#define USBCMD_HCRESET 0x0002 /* Host reset */ |
||||
#define USBCMD_GRESET 0x0004 /* Global reset */ |
||||
#define USBCMD_EGSM 0x0008 /* Global Suspend Mode */ |
||||
#define USBCMD_FGR 0x0010 /* Force Global Resume */ |
||||
#define USBCMD_SWDBG 0x0020 /* SW Debug mode */ |
||||
#define USBCMD_CF 0x0040 /* Config Flag (sw only) */ |
||||
#define USBCMD_MAXP 0x0080 /* Max Packet (0 = 32, 1 = 64) */ |
||||
|
||||
/* Status register */ |
||||
#define USBSTS 2 |
||||
#define USBSTS_USBINT 0x0001 /* Interrupt due to IOC */ |
||||
#define USBSTS_ERROR 0x0002 /* Interrupt due to error */ |
||||
#define USBSTS_RD 0x0004 /* Resume Detect */ |
||||
#define USBSTS_HSE 0x0008 /* Host System Error - basically PCI problems */ |
||||
#define USBSTS_HCPE 0x0010 /* Host Controller Process Error - the scripts were buggy */ |
||||
#define USBSTS_HCH 0x0020 /* HC Halted */ |
||||
|
||||
/* Interrupt enable register */ |
||||
#define USBINTR 4 |
||||
#define USBINTR_TIMEOUT 0x0001 /* Timeout/CRC error enable */ |
||||
#define USBINTR_RESUME 0x0002 /* Resume interrupt enable */ |
||||
#define USBINTR_IOC 0x0004 /* Interrupt On Complete enable */ |
||||
#define USBINTR_SP 0x0008 /* Short packet interrupt enable */ |
||||
|
||||
#define USBFRNUM 6 |
||||
#define USBFLBASEADD 8 |
||||
#define USBSOF 12 |
||||
|
||||
/* USB port status and control registers */ |
||||
#define USBPORTSC1 16 |
||||
#define USBPORTSC2 18 |
||||
#define USBPORTSC_CCS 0x0001 /* Current Connect Status ("device present") */ |
||||
#define USBPORTSC_CSC 0x0002 /* Connect Status Change */ |
||||
#define USBPORTSC_PE 0x0004 /* Port Enable */ |
||||
#define USBPORTSC_PEC 0x0008 /* Port Enable Change */ |
||||
#define USBPORTSC_LS 0x0030 /* Line Status */ |
||||
#define USBPORTSC_RD 0x0040 /* Resume Detect */ |
||||
#define USBPORTSC_LSDA 0x0100 /* Low Speed Device Attached */ |
||||
#define USBPORTSC_PR 0x0200 /* Port Reset */ |
||||
#define USBPORTSC_SUSP 0x1000 /* Suspend */ |
||||
|
||||
/* Legacy support register */ |
||||
#define USBLEGSUP 0xc0 |
||||
#define USBLEGSUP_DEFAULT 0x2000 /* only PIRQ enable set */ |
||||
|
||||
#define UHCI_NULL_DATA_SIZE 0x7ff /* for UHCI controller TD */ |
||||
#define UHCI_PID 0xff /* PID MASK */ |
||||
|
||||
#define UHCI_PTR_BITS 0x000F |
||||
#define UHCI_PTR_TERM 0x0001 |
||||
#define UHCI_PTR_QH 0x0002 |
||||
#define UHCI_PTR_DEPTH 0x0004 |
||||
|
||||
/* for TD <status>: */ |
||||
#define TD_CTRL_SPD (1 << 29) /* Short Packet Detect */ |
||||
#define TD_CTRL_C_ERR_MASK (3 << 27) /* Error Counter bits */ |
||||
#define TD_CTRL_LS (1 << 26) /* Low Speed Device */ |
||||
#define TD_CTRL_IOS (1 << 25) /* Isochronous Select */ |
||||
#define TD_CTRL_IOC (1 << 24) /* Interrupt on Complete */ |
||||
#define TD_CTRL_ACTIVE (1 << 23) /* TD Active */ |
||||
#define TD_CTRL_STALLED (1 << 22) /* TD Stalled */ |
||||
#define TD_CTRL_DBUFERR (1 << 21) /* Data Buffer Error */ |
||||
#define TD_CTRL_BABBLE (1 << 20) /* Babble Detected */ |
||||
#define TD_CTRL_NAK (1 << 19) /* NAK Received */ |
||||
#define TD_CTRL_CRCTIMEO (1 << 18) /* CRC/Time Out Error */ |
||||
#define TD_CTRL_BITSTUFF (1 << 17) /* Bit Stuff Error */ |
||||
#define TD_CTRL_ACTLEN_MASK 0x7ff /* actual length, encoded as n - 1 */ |
||||
|
||||
#define TD_CTRL_ANY_ERROR (TD_CTRL_STALLED | TD_CTRL_DBUFERR | \ |
||||
TD_CTRL_BABBLE | TD_CTRL_CRCTIME | TD_CTRL_BITSTUFF) |
||||
|
||||
#define TD_TOKEN_TOGGLE 19 |
||||
|
||||
/* ------------------------------------------------------------------------------------
|
||||
Virtual Root HUB |
||||
------------------------------------------------------------------------------------ */ |
||||
/* destination of request */ |
||||
#define RH_INTERFACE 0x01 |
||||
#define RH_ENDPOINT 0x02 |
||||
#define RH_OTHER 0x03 |
||||
|
||||
#define RH_CLASS 0x20 |
||||
#define RH_VENDOR 0x40 |
||||
|
||||
/* Requests: bRequest << 8 | bmRequestType */ |
||||
#define RH_GET_STATUS 0x0080 |
||||
#define RH_CLEAR_FEATURE 0x0100 |
||||
#define RH_SET_FEATURE 0x0300 |
||||
#define RH_SET_ADDRESS 0x0500 |
||||
#define RH_GET_DESCRIPTOR 0x0680 |
||||
#define RH_SET_DESCRIPTOR 0x0700 |
||||
#define RH_GET_CONFIGURATION 0x0880 |
||||
#define RH_SET_CONFIGURATION 0x0900 |
||||
#define RH_GET_STATE 0x0280 |
||||
#define RH_GET_INTERFACE 0x0A80 |
||||
#define RH_SET_INTERFACE 0x0B00 |
||||
#define RH_SYNC_FRAME 0x0C80 |
||||
/* Our Vendor Specific Request */ |
||||
#define RH_SET_EP 0x2000 |
||||
|
||||
/* Hub port features */ |
||||
#define RH_PORT_CONNECTION 0x00 |
||||
#define RH_PORT_ENABLE 0x01 |
||||
#define RH_PORT_SUSPEND 0x02 |
||||
#define RH_PORT_OVER_CURRENT 0x03 |
||||
#define RH_PORT_RESET 0x04 |
||||
#define RH_PORT_POWER 0x08 |
||||
#define RH_PORT_LOW_SPEED 0x09 |
||||
#define RH_C_PORT_CONNECTION 0x10 |
||||
#define RH_C_PORT_ENABLE 0x11 |
||||
#define RH_C_PORT_SUSPEND 0x12 |
||||
#define RH_C_PORT_OVER_CURRENT 0x13 |
||||
#define RH_C_PORT_RESET 0x14 |
||||
|
||||
/* Hub features */ |
||||
#define RH_C_HUB_LOCAL_POWER 0x00 |
||||
#define RH_C_HUB_OVER_CURRENT 0x01 |
||||
|
||||
#define RH_DEVICE_REMOTE_WAKEUP 0x00 |
||||
#define RH_ENDPOINT_STALL 0x01 |
||||
|
||||
/* Our Vendor Specific feature */ |
||||
#define RH_REMOVE_EP 0x00 |
||||
|
||||
|
||||
#define RH_ACK 0x01 |
||||
#define RH_REQ_ERR -1 |
||||
#define RH_NACK 0x00 |
||||
|
||||
|
||||
/* Transfer descriptor structure */ |
||||
typedef struct { |
||||
unsigned long link; /* next td/qh (LE)*/ |
||||
unsigned long status; /* status of the td */ |
||||
unsigned long info; /* Max Lenght / Endpoint / device address and PID */ |
||||
unsigned long buffer; /* pointer to data buffer (LE) */ |
||||
unsigned long dev_ptr; /* pointer to the assigned device (BE) */ |
||||
unsigned long res[3]; /* reserved (TDs must be 8Byte aligned) */ |
||||
} uhci_td_t, *puhci_td_t; |
||||
|
||||
/* Queue Header structure */ |
||||
typedef struct { |
||||
unsigned long head; /* Next QH (LE)*/ |
||||
unsigned long element; /* Queue element pointer (LE) */ |
||||
unsigned long res[5]; /* reserved */ |
||||
unsigned long dev_ptr; /* if 0 no tds have been assigned to this qh */ |
||||
} uhci_qh_t, *puhci_qh_t; |
||||
|
||||
struct virt_root_hub { |
||||
int devnum; /* Address of Root Hub endpoint */ |
||||
int numports; /* number of ports */ |
||||
int c_p_r[8]; /* C_PORT_RESET */ |
||||
}; |
||||
|
||||
|
||||
#endif /* _USB_UHCI_H_ */ |
@ -1,299 +0,0 @@ |
||||
/*
|
||||
* (C) Copyright 2002 |
||||
* Hyperion Entertainment, Hans-JoergF@hyperion-entertainment.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 <pci.h> |
||||
#include <ata.h> |
||||
#include "memio.h" |
||||
#include "articiaS.h" |
||||
#include "via686.h" |
||||
#include "i8259.h" |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
#undef VIA_DEBUG |
||||
|
||||
#ifdef VIA_DEBUG |
||||
#define PRINTF(fmt,args...) printf (fmt ,##args) |
||||
#else |
||||
#define PRINTF(fmt,args...) |
||||
#endif |
||||
|
||||
|
||||
/* Setup the ISA-to-PCI host bridge */ |
||||
void via_isa_init(pci_dev_t dev, struct pci_config_table *table) |
||||
{ |
||||
char regval; |
||||
if (PCI_FUNC(dev) == 0) |
||||
{ |
||||
PRINTF("... PCI-to-ISA bridge, dev=0x%X\n", dev); |
||||
|
||||
/* Enable I/O Recovery time */ |
||||
pci_write_config_byte(dev, 0x40, 0x08); |
||||
|
||||
/* Enable ISA refresh */ |
||||
pci_write_config_byte(dev, 0x41, 0x41); /* was 01 */ |
||||
|
||||
/* Enable ISA line buffer */ |
||||
pci_write_config_byte(dev, 0x45, 0x80); |
||||
|
||||
/* Gate INTR, and flush line buffer */ |
||||
pci_write_config_byte(dev, 0x46, 0x60); |
||||
|
||||
/* Enable EISA ports 4D0/4D1. Do we need this ? */ |
||||
pci_write_config_byte(dev, 0x47, 0xe6); /* was 20 */ |
||||
|
||||
/* 512 K PCI Decode */ |
||||
pci_write_config_byte(dev, 0x48, 0x01); |
||||
|
||||
/* Wait for PGNT before grant to ISA Master/DMA */ |
||||
/* ports 0-FF to SDBus */ |
||||
/* IRQ 14 and 15 for ide 0/1 */ |
||||
pci_write_config_byte(dev, 0x4a, 0x04); /* Was c4 */ |
||||
|
||||
/* Plug'n'Play */ |
||||
/* Parallel DRQ 3, Floppy DRQ 2 (default) */ |
||||
pci_write_config_byte(dev, 0x50, 0x0e); |
||||
|
||||
/* IRQ Routing for Floppy and Parallel port */ |
||||
/* IRQ 6 for floppy, IRQ 7 for parallel port */ |
||||
pci_write_config_byte(dev, 0x51, 0x76); |
||||
|
||||
/* IRQ Routing for serial ports (take IRQ 3 and 4) */ |
||||
pci_write_config_byte(dev, 0x52, 0x34); |
||||
|
||||
/* All IRQ's level triggered. */ |
||||
pci_write_config_byte(dev, 0x54, 0x00); |
||||
|
||||
/* PCI IRQ's all at IRQ 9 */ |
||||
pci_write_config_byte(dev, 0x55, 0x90); |
||||
pci_write_config_byte(dev, 0x56, 0x99); |
||||
pci_write_config_byte(dev, 0x57, 0x90); |
||||
|
||||
/* Enable Keyboard */ |
||||
pci_read_config_byte(dev, 0x5A, ®val); |
||||
regval |= 0x01; |
||||
pci_write_config_byte(dev, 0x5A, regval); |
||||
|
||||
pci_write_config_byte(dev, 0x80, 0); |
||||
pci_write_config_byte(dev, 0x85, 0x01); |
||||
|
||||
/* pci_write_config_byte(dev, 0x77, 0x00); */ |
||||
} |
||||
} |
||||
|
||||
/*
|
||||
* Initialize PNP irq routing |
||||
*/ |
||||
|
||||
void via_init_irq_routing(uint8 irq_map[]) |
||||
{ |
||||
char *s; |
||||
uint8 level_edge_bits = 0xf; |
||||
|
||||
/* Set irq routings */ |
||||
pci_write_cfg_byte(0, 7<<3, 0x55, irq_map[0]<<4); |
||||
pci_write_cfg_byte(0, 7<<3, 0x56, irq_map[1] | irq_map[2]<<4); |
||||
pci_write_cfg_byte(0, 7<<3, 0x57, irq_map[3]<<4); |
||||
|
||||
/*
|
||||
* Gather level/edge bits |
||||
* Default is to assume level triggered |
||||
*/ |
||||
|
||||
s = getenv("pci_irqa_select"); |
||||
if (s && strcmp(s, "level") == 0) |
||||
level_edge_bits &= ~0x01; |
||||
|
||||
s = getenv("pci_irqb_select"); |
||||
if (s && strcmp(s, "level") == 0) |
||||
level_edge_bits &= ~0x02; |
||||
|
||||
s = getenv("pci_irqc_select"); |
||||
if (s && strcmp(s, "level") == 0) |
||||
level_edge_bits &= ~0x04; |
||||
|
||||
s = getenv("pci_irqd_select"); |
||||
if (s && strcmp(s, "level") == 0) |
||||
level_edge_bits &= ~0x08; |
||||
|
||||
PRINTF("IRQ map\n"); |
||||
PRINTF("%d: %s\n", irq_map[0], level_edge_bits&0x1 ? "edge" : "level"); |
||||
PRINTF("%d: %s\n", irq_map[1], level_edge_bits&0x2 ? "edge" : "level"); |
||||
PRINTF("%d: %s\n", irq_map[2], level_edge_bits&0x4 ? "edge" : "level"); |
||||
PRINTF("%d: %s\n", irq_map[3], level_edge_bits&0x8 ? "edge" : "level"); |
||||
pci_write_cfg_byte(0, 7<<3, 0x54, level_edge_bits); |
||||
|
||||
PRINTF("%02x %02x %02x %02x\n", pci_read_cfg_byte(0, 7<<3, 0x54), |
||||
pci_read_cfg_byte(0, 7<<3, 0x55), pci_read_cfg_byte(0, 7<<3, 0x56), |
||||
pci_read_cfg_byte(0, 7<<3, 0x57)); |
||||
} |
||||
|
||||
|
||||
/* Setup the IDE controller. This doesn't seem to work yet. I/O to an IDE controller port */ |
||||
/* always return the last character output on the serial port (!) */ |
||||
/* This function is called by the pnp-library when it encounters 0:7:1 */ |
||||
void via_cfgfunc_ide_init(struct pci_controller *host, pci_dev_t dev, struct pci_config_table *table) |
||||
{ |
||||
PRINTF("... IDE controller, dev=0x%X\n", dev); |
||||
|
||||
/* Enable both IDE channels. */ |
||||
pci_write_config_byte(dev, 0x40, 0x03); |
||||
/* udelay(10000); */ |
||||
/* udelay(10000); */ |
||||
|
||||
/* Enable IO Space */ |
||||
pci_write_config_word(dev, 0x04, 0x03); |
||||
|
||||
/* Set to compatibility mode */ |
||||
pci_write_config_byte(dev, 0x09, 0x8A); /* WAS: 0x8f); */ |
||||
|
||||
/* Set to legacy interrupt mode */ |
||||
pci_write_config_byte(dev, 0x3d, 0x00); /* WAS: 0x01); */ |
||||
|
||||
} |
||||
|
||||
|
||||
/* Set the base address of the floppy controller to 0x3F0 */ |
||||
void via_fdc_init(pci_dev_t dev) |
||||
{ |
||||
unsigned char c; |
||||
/* Enable Configuration mode */ |
||||
pci_read_config_byte(dev, 0x85, &c); |
||||
c |= 0x02; |
||||
pci_write_config_byte(dev, 0x85, c); |
||||
|
||||
/* Set floppy controller port to 0x3F0. */ |
||||
SIO_WRITE_CONFIG(0xE3, (0x3F<<2)); |
||||
|
||||
/* Enable floppy controller */ |
||||
SIO_READ_CONFIG(0xE2, c); |
||||
c |= 0x10; |
||||
SIO_WRITE_CONFIG(0xE2, c); |
||||
|
||||
/* Switch of configuration mode */ |
||||
pci_read_config_byte(dev, 0x85, &c); |
||||
c &= ~0x02; |
||||
pci_write_config_byte(dev, 0x85, c); |
||||
} |
||||
|
||||
/* Init function 0 of the via southbridge. Called by the pnp-library */ |
||||
void via_cfgfunc_via686(struct pci_controller *host, pci_dev_t dev, struct pci_config_table *table) |
||||
{ |
||||
if (PCI_FUNC(dev) == 0) |
||||
{ |
||||
/* FIXME: Try to generate a PCI reset */ |
||||
/* unsigned char c; */ |
||||
/* pci_read_config_byte(dev, 0x47, &c); */ |
||||
/* pci_write_config_byte(dev, 0x47, c | 0x01); */ |
||||
|
||||
via_isa_init(dev, table); |
||||
via_fdc_init(dev); |
||||
} |
||||
} |
||||
|
||||
__asm__ (" .globl via_calibrate_time_base \n" |
||||
"via_calibrate_time_base: \n" |
||||
" lis 9, 0xfe00 \n" |
||||
" li 0, 0x00 \n" |
||||
" mttbu 0 \n" |
||||
" mttbl 0 \n" |
||||
"ctb_loop: \n" |
||||
" lbz 0, 0x61(9) \n" |
||||
" eieio \n" |
||||
" andi. 0, 0, 0x20 \n" |
||||
" beq ctb_loop \n" |
||||
"ctb_done: \n" |
||||
" mftb 3 \n" |
||||
" blr"); |
||||
|
||||
extern unsigned long via_calibrate_time_base(void); |
||||
|
||||
void via_calibrate_bus_freq (void) |
||||
{ |
||||
unsigned long tb; |
||||
|
||||
/* This is 20 microseconds */ |
||||
#define CALIBRATE_TIME 28636 |
||||
|
||||
/* Enable the timer (and disable speaker) */ |
||||
unsigned char c; |
||||
|
||||
c = in_byte (0x61); |
||||
out_byte (0x61, ((c & ~0x02) | 0x01)); |
||||
|
||||
/* Set timer 2 to low/high writing */ |
||||
out_byte (0x43, 0xb0); |
||||
out_byte (0x42, CALIBRATE_TIME & 0xff); |
||||
out_byte (0x42, CALIBRATE_TIME >> 8); |
||||
|
||||
/* Read the time base */ |
||||
tb = via_calibrate_time_base (); |
||||
|
||||
if (tb >= 700000) |
||||
gd->bus_clk = 133333333; |
||||
else |
||||
gd->bus_clk = 100000000; |
||||
|
||||
} |
||||
|
||||
|
||||
void ide_led(uchar led, uchar status) |
||||
{ |
||||
/* unsigned char c = in_byte(0x92); */ |
||||
|
||||
/* if (!status) */ |
||||
/* out_byte(0x92, c | 0xC0); */ |
||||
/* else */ |
||||
/* out_byte(0x92, c & ~0xC0); */ |
||||
} |
||||
|
||||
|
||||
void via_init_afterscan(void) |
||||
{ |
||||
/* Modify IDE controller setup */ |
||||
pci_write_cfg_byte(0, 7<<3|1, PCI_LATENCY_TIMER, 0x20); |
||||
pci_write_cfg_byte(0, 7<<3|1, PCI_COMMAND, PCI_COMMAND_IO|PCI_COMMAND_MEMORY|PCI_COMMAND_MASTER); |
||||
pci_write_cfg_byte(0, 7<<3|1, PCI_INTERRUPT_LINE, 0xff); |
||||
pci_write_cfg_byte(0, 7<<3|1, 0x40, 0x0b); /* FIXME: Might depend on drives connected */ |
||||
pci_write_cfg_byte(0, 7<<3|1, 0x41, 0x42); /* FIXME: Might depend on drives connected */ |
||||
pci_write_cfg_byte(0, 7<<3|1, 0x43, 0x05); |
||||
pci_write_cfg_byte(0, 7<<3|1, 0x44, 0x18); |
||||
pci_write_cfg_byte(0, 7<<3|1, 0x45, 0x10); |
||||
pci_write_cfg_byte(0, 7<<3|1, 0x4e, 0x22); /* FIXME: Not documented, but set in PC bios */ |
||||
pci_write_cfg_byte(0, 7<<3|1, 0x4f, 0x20); /* FIXME: Not documented */ |
||||
|
||||
/* Modify some values in the USB controller */ |
||||
pci_write_cfg_byte(0, 7<<3|2, 0x05, 0x17); |
||||
pci_write_cfg_byte(0, 7<<3|2, 0x06, 0x01); |
||||
pci_write_cfg_byte(0, 7<<3|2, 0x41, 0x12); |
||||
pci_write_cfg_byte(0, 7<<3|2, 0x42, 0x03); |
||||
pci_write_cfg_byte(0, 7<<3|2, PCI_LATENCY_TIMER, 0x40); |
||||
|
||||
pci_write_cfg_byte(0, 7<<3|3, 0x05, 0x17); |
||||
pci_write_cfg_byte(0, 7<<3|3, 0x06, 0x01); |
||||
pci_write_cfg_byte(0, 7<<3|3, 0x41, 0x12); |
||||
pci_write_cfg_byte(0, 7<<3|3, 0x42, 0x03); |
||||
pci_write_cfg_byte(0, 7<<3|3, PCI_LATENCY_TIMER, 0x40); |
||||
|
||||
|
||||
} |
@ -1,29 +0,0 @@ |
||||
#ifndef VIA686_H_ |
||||
#define VIA686_H_ |
||||
|
||||
|
||||
#define CMOS_ADDR 0x70 |
||||
#define CMOS_DATA 0x71 |
||||
|
||||
#define I8259_MASTER_CONTROL 0x20 |
||||
#define I8259_MASTER_MASK 0x21 |
||||
|
||||
#define I8259_SLAVE_CONTROL 0xA0 |
||||
#define I8259_SLAVE_MASK 0xA1 |
||||
|
||||
#define SIO_CONFIG_ADDR 0x3F0 |
||||
#define SIO_CONFIG_DATA 0x3F1 |
||||
|
||||
#define SIO_WRITE_CONFIG(addr, byte) \ |
||||
out_byte(SIO_CONFIG_ADDR, addr); \
|
||||
out_byte(SIO_CONFIG_DATA, byte); |
||||
|
||||
#define SIO_READ_CONFIG(addr, byte) \ |
||||
out_byte(SIO_CONFIG_ADDR, addr); \
|
||||
byte = in_byte(SIO_CONFIG_DATA); |
||||
|
||||
void via_init(void); |
||||
|
||||
void via_calibrate_bus_freq(void); |
||||
|
||||
#endif |
@ -1,541 +0,0 @@ |
||||
/*
|
||||
* (C) Copyright 2002 |
||||
* Hyperion Entertainment, Hans-JoergF@hyperion-entertainment.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 <stdio_dev.h> |
||||
#include "memio.h" |
||||
#include <part.h> |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
unsigned char *cursor_position; |
||||
unsigned int cursor_row; |
||||
unsigned int cursor_col; |
||||
|
||||
unsigned char current_attr; |
||||
|
||||
unsigned int video_numrows = 25; |
||||
unsigned int video_numcols = 80; |
||||
unsigned int video_scrolls = 0; |
||||
|
||||
#define VIDEO_BASE (unsigned char *)0xFD0B8000 |
||||
#define VIDEO_ROWS video_numrows |
||||
#define VIDEO_COLS video_numcols |
||||
#define VIDEO_PITCH (2 * video_numcols) |
||||
#define VIDEO_SIZE (video_numrows * video_numcols * 2) |
||||
#define VIDEO_NAME "vga" |
||||
|
||||
void video_test(void); |
||||
void video_putc(char ch); |
||||
void video_puts(char *string); |
||||
void video_scroll(int rows); |
||||
void video_banner(void); |
||||
int video_init(void); |
||||
int video_start(void); |
||||
int video_rows(void); |
||||
int video_cols(void); |
||||
|
||||
char *prompt_string = "=>"; |
||||
unsigned char video_get_attr(void); |
||||
|
||||
void video_set_color(unsigned char attr) |
||||
{ |
||||
unsigned char *fb = (unsigned char *)VIDEO_BASE; |
||||
int i; |
||||
|
||||
current_attr = video_get_attr(); |
||||
|
||||
for (i=0; i<VIDEO_SIZE; i+=2) |
||||
{ |
||||
*(fb+i+1) = current_attr; |
||||
} |
||||
} |
||||
|
||||
unsigned char video_get_attr(void) |
||||
{ |
||||
char *s; |
||||
unsigned char attr; |
||||
|
||||
attr = 0x0f; |
||||
|
||||
s = getenv("vga_fg_color"); |
||||
if (s) |
||||
{ |
||||
attr = atoi(s); |
||||
} |
||||
|
||||
s = getenv("vga_bg_color"); |
||||
if (s) |
||||
{ |
||||
attr |= atoi(s)<<4; |
||||
} |
||||
|
||||
return attr; |
||||
} |
||||
|
||||
int video_inited = 0; |
||||
|
||||
int drv_video_init(void) |
||||
{ |
||||
int error, devices = 1 ; |
||||
struct stdio_dev vgadev ; |
||||
if (video_inited) return 1; |
||||
video_inited = 1; |
||||
video_init(); |
||||
memset (&vgadev, 0, sizeof(vgadev)); |
||||
|
||||
strcpy(vgadev.name, VIDEO_NAME); |
||||
vgadev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_SYSTEM; |
||||
vgadev.putc = video_putc; |
||||
vgadev.puts = video_puts; |
||||
vgadev.getc = NULL; |
||||
vgadev.tstc = NULL; |
||||
vgadev.start = video_start; |
||||
|
||||
error = stdio_register (&vgadev); |
||||
|
||||
if (error == 0) |
||||
{ |
||||
char *s = getenv("stdout"); |
||||
if (s && strcmp(s, VIDEO_NAME)==0) |
||||
{ |
||||
if (overwrite_console()) return 1; |
||||
error = console_assign(stdout, VIDEO_NAME); |
||||
if (error == 0) return 1; |
||||
else return error; |
||||
} |
||||
return 1; |
||||
} |
||||
|
||||
return error; |
||||
} |
||||
|
||||
int video_init(void) |
||||
{ |
||||
cursor_position = VIDEO_BASE; /* Color text display base */ |
||||
cursor_row = 0; |
||||
cursor_col = 0; |
||||
current_attr = video_get_attr(); /* Currently selected value for attribute. */ |
||||
/* video_test(); */ |
||||
video_set_color(current_attr); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
void video_set_cursor(int line, int column) |
||||
{ |
||||
unsigned short offset = line*video_numcols + column; |
||||
cursor_position = VIDEO_BASE + line*VIDEO_PITCH + column*2; |
||||
out_byte(0x3D4, 0x0E); |
||||
out_byte(0x3D5, offset/256); |
||||
out_byte(0x3D4, 0x0F); |
||||
out_byte(0x3D5, offset%256); |
||||
} |
||||
|
||||
void video_write_char(int character) |
||||
{ |
||||
*cursor_position = character; |
||||
*(cursor_position+1) = current_attr; |
||||
} |
||||
|
||||
void video_test(void) |
||||
{ |
||||
|
||||
} |
||||
|
||||
void video_putc(char ch) |
||||
{ |
||||
switch(ch) |
||||
{ |
||||
case '\n': |
||||
cursor_col = 0; |
||||
cursor_row += 1; |
||||
break; |
||||
case '\r': |
||||
cursor_col = 0; |
||||
break; |
||||
case '\b': |
||||
if (cursor_col) cursor_col--; |
||||
else return; |
||||
break; |
||||
case '\t': |
||||
cursor_col = (cursor_col/8+1)*8; |
||||
break; |
||||
default: |
||||
video_write_char(ch); |
||||
cursor_col++; |
||||
if (cursor_col > VIDEO_COLS-1) |
||||
{ |
||||
cursor_row++; |
||||
cursor_col=0; |
||||
} |
||||
} |
||||
|
||||
if (cursor_row > VIDEO_ROWS-1) |
||||
video_scroll(1); |
||||
video_set_cursor(cursor_row, cursor_col); |
||||
} |
||||
|
||||
void video_scroll(int rows) |
||||
{ |
||||
unsigned short clear = ((unsigned short)current_attr) | (' '<<8); |
||||
unsigned short* addr16 = &((unsigned short *)VIDEO_BASE)[(VIDEO_ROWS-rows)*VIDEO_COLS]; |
||||
int i; |
||||
char *s; |
||||
|
||||
s = getenv("vga_askscroll"); |
||||
video_scrolls += rows; |
||||
|
||||
if (video_scrolls >= video_numrows) |
||||
{ |
||||
if (s && strcmp(s, "yes")) |
||||
{ |
||||
while (-1 == tstc()); |
||||
} |
||||
|
||||
video_scrolls = 0; |
||||
} |
||||
|
||||
|
||||
memcpy(VIDEO_BASE, VIDEO_BASE+rows*(VIDEO_COLS*2), (VIDEO_ROWS-rows)*(VIDEO_COLS*2)); |
||||
for (i = 0 ; i < rows * VIDEO_COLS ; i++) |
||||
addr16[i] = clear; |
||||
cursor_row-=rows; |
||||
cursor_col=0; |
||||
} |
||||
|
||||
void video_puts(char *string) |
||||
{ |
||||
while (*string) |
||||
{ |
||||
video_putc(*string); |
||||
string++; |
||||
} |
||||
} |
||||
|
||||
int video_start(void) |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
unsigned char video_single_box[] = |
||||
{ |
||||
218, 196, 191, |
||||
179, 179, |
||||
192, 196, 217 |
||||
}; |
||||
|
||||
unsigned char video_double_box[] = |
||||
{ |
||||
201, 205, 187, |
||||
186, 186, |
||||
200, 205, 188 |
||||
}; |
||||
|
||||
unsigned char video_single_title[] = |
||||
{ |
||||
195, 196, 180, 180, 195 |
||||
}; |
||||
|
||||
unsigned char video_double_title[] = |
||||
{ |
||||
204, 205, 185, 181, 198 |
||||
}; |
||||
|
||||
#define SINGLE_BOX 0 |
||||
#define DOUBLE_BOX 1 |
||||
|
||||
unsigned char *video_addr(int x, int y) |
||||
{ |
||||
return VIDEO_BASE + 2*(VIDEO_COLS*y) + 2*x; |
||||
} |
||||
|
||||
void video_bios_print_string(char *s, int x, int y, int attr, int count) |
||||
{ |
||||
int cattr = current_attr; |
||||
if (attr != -1) current_attr = attr; |
||||
video_set_cursor(x,y); |
||||
while (count) |
||||
{ |
||||
char c = *s++; |
||||
if (attr == -1) current_attr = *s++; |
||||
video_putc(c); |
||||
count--; |
||||
} |
||||
} |
||||
|
||||
void video_draw_box(int style, int attr, char *title, int separate, int x, int y, int w, int h) |
||||
{ |
||||
unsigned char *fb, *fb2; |
||||
unsigned char *st = (style == SINGLE_BOX)?video_single_box : video_double_box; |
||||
unsigned char *ti = (style == SINGLE_BOX)?video_single_title : video_double_title; |
||||
int i; |
||||
|
||||
fb = video_addr(x,y); |
||||
*(fb) = st[0]; |
||||
*(fb+1) = attr; |
||||
fb += 2; |
||||
|
||||
fb2 = video_addr(x,y+h-1); |
||||
*(fb2) = st[5]; |
||||
*(fb2+1) = attr; |
||||
fb2 += 2; |
||||
|
||||
for (i=0; i<w-2;i++) |
||||
{ |
||||
*fb = st[1]; |
||||
fb++; |
||||
*fb = attr; |
||||
fb++; |
||||
|
||||
*fb2 = st[6]; |
||||
fb2++; |
||||
*fb2 = attr; |
||||
fb2++; |
||||
|
||||
} |
||||
*fb = st[2]; |
||||
*(fb+1) = attr; |
||||
|
||||
*fb2 = st[7]; |
||||
*(fb2+1) = attr; |
||||
|
||||
fb = video_addr(x, y+1); |
||||
fb2 = video_addr(x+w-1, y+1); |
||||
for (i=0; i<h-2; i++) |
||||
{ |
||||
*fb = st[3]; |
||||
*(fb+1) = attr; fb += 2*VIDEO_COLS; |
||||
|
||||
*fb2 = st[4]; |
||||
*(fb2+1) = attr; fb2 += 2*VIDEO_COLS; |
||||
} |
||||
|
||||
/* Draw title */ |
||||
if (title) |
||||
{ |
||||
if (separate == 0) |
||||
{ |
||||
fb = video_addr(x+1, y); |
||||
*fb = ti[3]; |
||||
fb += 2; |
||||
*fb = ' '; |
||||
fb += 2; |
||||
while (*title) |
||||
{ |
||||
*fb = *title; |
||||
fb ++; |
||||
*fb = attr; |
||||
fb++; title++; |
||||
} |
||||
*fb = ' '; |
||||
fb += 2; |
||||
*fb = ti[4]; |
||||
} |
||||
else |
||||
{ |
||||
fb = video_addr(x, y+2); |
||||
*fb = ti[0]; |
||||
fb += 2; |
||||
for (i=0; i<w-2; i++) |
||||
{ |
||||
*fb = ti[1]; |
||||
*(fb+1) = attr; |
||||
fb += 2; |
||||
} |
||||
*fb = ti[2]; |
||||
*(fb+1) = attr; |
||||
fb = video_addr(x+1, y+1); |
||||
for (i=0; i<w-2; i++) |
||||
{ |
||||
*fb = ' '; |
||||
*(fb+1) = attr; |
||||
fb += 2; |
||||
} |
||||
fb = video_addr(x+2, y+1); |
||||
|
||||
while (*title) |
||||
{ |
||||
*fb = *title; |
||||
*(fb+1) = attr; |
||||
fb += 2; |
||||
title++; |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
void video_draw_text(int x, int y, int attr, char *text) |
||||
{ |
||||
unsigned char *fb = video_addr(x,y); |
||||
while (*text) |
||||
{ |
||||
*fb++ = *text++; |
||||
*fb++ = attr; |
||||
} |
||||
} |
||||
|
||||
void video_save_rect(int x, int y, int w, int h, void *save_area, int clearchar, int clearattr) |
||||
{ |
||||
unsigned char *save = (unsigned char *)save_area; |
||||
unsigned char *fb = video_addr(x,y); |
||||
int i,j; |
||||
for (i=0; i<h; i++) |
||||
{ |
||||
unsigned char *fbb = fb; |
||||
for (j=0; j<w; j++) |
||||
{ |
||||
*save ++ = *fb; |
||||
if (clearchar > 0) *fb = clearchar; |
||||
fb ++; |
||||
*save ++ = *fb; |
||||
if (clearattr > 0) *fb = clearattr; |
||||
} |
||||
fb = fbb + 2*VIDEO_COLS; |
||||
} |
||||
} |
||||
|
||||
void video_restore_rect(int x, int y, int w, int h, void *save_area) |
||||
{ |
||||
unsigned char *save = (unsigned char *)save_area; |
||||
unsigned char *fb = video_addr(x,y); |
||||
int i,j; |
||||
for (i=0; i<h; i++) |
||||
{ |
||||
unsigned char *fbb = fb; |
||||
for (j=0; j<w; j++) |
||||
{ |
||||
*fb ++ = *save ++; |
||||
*fb ++ = *save ++; |
||||
} |
||||
fb = fbb + 2*VIDEO_COLS; |
||||
} |
||||
|
||||
} |
||||
|
||||
int video_rows(void) |
||||
{ |
||||
return VIDEO_ROWS; |
||||
} |
||||
|
||||
int video_cols(void) |
||||
{ |
||||
return VIDEO_COLS; |
||||
} |
||||
|
||||
void video_size(int cols, int rows) |
||||
{ |
||||
video_numrows = rows; |
||||
video_numcols = cols; |
||||
} |
||||
|
||||
void video_clear(void) |
||||
{ |
||||
unsigned short *fbb = (unsigned short *)0xFD0B8000; |
||||
int i,j; |
||||
unsigned short val = 0x2000 | current_attr; |
||||
|
||||
for (i=0; i<video_rows(); i++) |
||||
{ |
||||
for (j=0; j<video_cols(); j++) |
||||
{ |
||||
*fbb++ = val; |
||||
} |
||||
} |
||||
video_set_cursor(0,0); |
||||
cursor_row = 0; |
||||
cursor_col = 0; |
||||
} |
||||
|
||||
#ifdef EASTEREGG |
||||
int video_easteregg_active = 0; |
||||
|
||||
void video_easteregg(void) |
||||
{ |
||||
video_easteregg_active = 1; |
||||
} |
||||
#endif |
||||
|
||||
extern block_dev_desc_t * ide_get_dev(int dev); |
||||
extern char version_string[]; |
||||
|
||||
void video_banner(void) |
||||
{ |
||||
block_dev_desc_t *ide; |
||||
int i; |
||||
char *s; |
||||
int maxdev; |
||||
|
||||
|
||||
if (video_inited == 0) return; |
||||
#ifdef EASTEREGG |
||||
if (video_easteregg_active) |
||||
{ |
||||
prompt_string=""; |
||||
video_clear(); |
||||
printf("\n"); |
||||
printf(" **** COMMODORE 64 BASIC X2 ****\n\n"); |
||||
printf(" 64K RAM SYSTEM 38911 BASIC BYTES FREE\n\n"); |
||||
printf("READY\n"); |
||||
} |
||||
else |
||||
{ |
||||
#endif |
||||
s = getenv("ide_maxbus"); |
||||
if (s) |
||||
maxdev = atoi(s) * 2; |
||||
else |
||||
maxdev = 4; |
||||
|
||||
s = getenv("stdout"); |
||||
if (s && strcmp(s, "serial") == 0) |
||||
return; |
||||
|
||||
video_clear(); |
||||
printf("%s\n\nCPU: ", version_string); |
||||
checkcpu(); |
||||
printf("DRAM: %ld MB\n", gd->bd->bi_memsize/(1024*1024)); |
||||
printf("FSB: %ld MHz\n", gd->bd->bi_busfreq/1000000); |
||||
|
||||
printf("\n---- Disk summary ----\n"); |
||||
for (i = 0; i < maxdev; i++) |
||||
{ |
||||
ide = ide_get_dev(i); |
||||
printf("Device %d: ", i); |
||||
dev_print(ide); |
||||
} |
||||
|
||||
/*
|
||||
video_draw_box(SINGLE_BOX, 0x0F, "Test 1", 0, 0,18, 72, 4); |
||||
video_draw_box(DOUBLE_BOX, 0x0F, "Test 2", 1, 4,10, 50, 6); |
||||
video_draw_box(DOUBLE_BOX, 0x0F, "Test 3", 0, 40, 3, 20, 5); |
||||
|
||||
video_draw_text(1, 4, 0x2F, "Highlighted options"); |
||||
video_draw_text(1, 5, 0x0F, "Non-selected option"); |
||||
video_draw_text(1, 6, 0x07, "disabled option"); |
||||
*/ |
||||
#ifdef EASTEREGG |
||||
} |
||||
#endif |
||||
} |
@ -1,16 +0,0 @@ |
||||
#include <common.h> |
||||
#include <command.h> |
||||
|
||||
int do_menu( cmd_tbl_t *cmdtp, /*bd_t *bd,*/ int flag, int argc, char *argv[] ) |
||||
{ |
||||
/* printf("<NOT YET IMPLEMENTED>\n"); */ |
||||
return 0; |
||||
} |
||||
|
||||
#if defined(CONFIG_AMIGAONEG3SE) && defined(CONFIG_CMD_BSP) |
||||
U_BOOT_CMD( |
||||
menu, 1, 1, do_menu, |
||||
"display BIOS setup menu", |
||||
"" |
||||
); |
||||
#endif |
@ -1,404 +0,0 @@ |
||||
/*
|
||||
* (C) Copyright 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 |
||||
*/ |
||||
|
||||
/*
|
||||
* |
||||
* Configuration settings for the AmigaOneG3SE board. |
||||
* |
||||
*/ |
||||
|
||||
/* ------------------------------------------------------------------------- */ |
||||
|
||||
/*
|
||||
* board/config.h - configuration options, board specific |
||||
*/ |
||||
|
||||
#ifndef __CONFIG_H |
||||
#define __CONFIG_H |
||||
|
||||
/*
|
||||
* High Level Configuration Options |
||||
* (easy to change) |
||||
*/ |
||||
|
||||
#define CONFIG_AMIGAONEG3SE 1 |
||||
|
||||
#define CONFIG_BOARD_EARLY_INIT_F 1 |
||||
#define CONFIG_MISC_INIT_R 1 |
||||
|
||||
#define CONFIG_VERY_BIG_RAM 1 |
||||
|
||||
#define CONFIG_CONS_INDEX 1 |
||||
#define CONFIG_BAUDRATE 9600 |
||||
#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } |
||||
|
||||
#undef CONFIG_CLOCKS_IN_MHZ /* clocks passed to Linux in Hz */ |
||||
|
||||
#define CONFIG_BOOTARGS "root=/dev/ram rw ramdisk_size=4096" |
||||
|
||||
/*
|
||||
* BOOTP options |
||||
*/ |
||||
#define CONFIG_BOOTP_SUBNETMASK |
||||
#define CONFIG_BOOTP_GATEWAY |
||||
#define CONFIG_BOOTP_HOSTNAME |
||||
#define CONFIG_BOOTP_BOOTPATH |
||||
#define CONFIG_BOOTP_BOOTFILESIZE |
||||
|
||||
|
||||
#define CONFIG_MAC_PARTITION |
||||
#define CONFIG_DOS_PARTITION |
||||
#define CONFIG_AMIGA_PARTITION |
||||
|
||||
|
||||
/*
|
||||
* Command line configuration. |
||||
*/ |
||||
#include <config_cmd_default.h> |
||||
|
||||
#define CONFIG_CMD_ASKENV |
||||
#define CONFIG_CMD_BSP |
||||
#define CONFIG_CMD_DATE |
||||
#define CONFIG_CMD_DHCP |
||||
#define CONFIG_CMD_ELF |
||||
#define CONFIG_CMD_NET |
||||
#define CONFIG_CMD_IDE |
||||
#define CONFIG_CMD_FDC |
||||
#define CONFIG_CMD_CACHE |
||||
#define CONFIG_CMD_CONSOLE |
||||
#define CONFIG_CMD_USB |
||||
#define CONFIG_CMD_BSP |
||||
#define CONFIG_CMD_PCI |
||||
|
||||
|
||||
#define CONFIG_PCI 1 |
||||
/* #define CONFIG_PCI_SCAN_SHOW 1 */ |
||||
#define CONFIG_PCI_PNP 1 /* PCI plug-and-play */ |
||||
|
||||
#define atoi(x) simple_strtoul(x,NULL,10) |
||||
|
||||
/*
|
||||
* Miscellaneous configurable options |
||||
*/ |
||||
#define CONFIG_SYS_LONGHELP /* undef to save memory */ |
||||
#define CONFIG_SYS_PROMPT "] " /* Monitor Command Prompt */ |
||||
|
||||
#define CONFIG_SYS_HUSH_PARSER 1 /* use "hush" command parser */ |
||||
/* #undef CONFIG_SYS_HUSH_PARSER */ |
||||
#ifdef CONFIG_SYS_HUSH_PARSER |
||||
#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " |
||||
#endif |
||||
#define CONFIG_SYS_CBSIZE 1024 /* Console I/O Buffer Size */ |
||||
|
||||
/* Print Buffer Size
|
||||
*/ |
||||
#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16) |
||||
|
||||
#define CONFIG_SYS_MAXARGS 64 /* max number of command args */ |
||||
#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Argument Buffer Size */ |
||||
#define CONFIG_SYS_LOAD_ADDR 0x00500000 /* Default load address */ |
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Start addresses for the final memory configuration |
||||
* (Set up by the startup code) |
||||
* Please note that CONFIG_SYS_SDRAM_BASE _must_ start at 0 |
||||
*/ |
||||
#define CONFIG_SYS_SDRAM_BASE 0x00000000 |
||||
#define CONFIG_SYS_FLASH_BASE 0xFFF00000 |
||||
#define CONFIG_SYS_FLASH_MAX_SIZE 0x00080000 |
||||
/* Maximum amount of RAM.
|
||||
*/ |
||||
#define CONFIG_SYS_MAX_RAM_SIZE 0x80000000 /* 2G */ |
||||
|
||||
#define CONFIG_SYS_RESET_ADDRESS 0xFFF00100 |
||||
|
||||
#define CONFIG_SYS_MONITOR_BASE TEXT_BASE |
||||
|
||||
#define CONFIG_SYS_MONITOR_LEN (768 << 10) /* Reserve 512 kB for Monitor */ |
||||
#define CONFIG_SYS_MALLOC_LEN (2500 << 10) /* Reserve 128 kB for malloc() */ |
||||
|
||||
#if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_SDRAM_BASE && \ |
||||
CONFIG_SYS_MONITOR_BASE < CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_MAX_RAM_SIZE |
||||
#define CONFIG_SYS_RAMBOOT |
||||
#else |
||||
#undef CONFIG_SYS_RAMBOOT |
||||
#endif |
||||
|
||||
#define CONFIG_SYS_MEMTEST_START 0x00004000 /* memtest works on */ |
||||
#define CONFIG_SYS_MEMTEST_END 0x02000000 /* 0 ... 32 MB in DRAM */ |
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Definitions for initial stack pointer and data area |
||||
*/ |
||||
|
||||
/* Size in bytes reserved for initial data
|
||||
*/ |
||||
/* HJF: used to be 0x400000 */ |
||||
#define CONFIG_SYS_INIT_RAM_ADDR 0x40000000 |
||||
#define CONFIG_SYS_INIT_RAM_END 0x8000 |
||||
#define CONFIG_SYS_GBL_DATA_SIZE 128 |
||||
#define CONFIG_SYS_GBL_DATA_OFFSET (CONFIG_SYS_INIT_RAM_END - CONFIG_SYS_GBL_DATA_SIZE) |
||||
#define CONFIG_SYS_INIT_SP_OFFSET CONFIG_SYS_GBL_DATA_OFFSET |
||||
|
||||
#define CONFIG_SYS_INIT_RAM_LOCK |
||||
|
||||
/*
|
||||
* Temporary buffer for serial data until the real serial driver |
||||
* is initialised (memtest will destroy this buffer) |
||||
*/ |
||||
#define CONFIG_SYS_SCONSOLE_ADDR CONFIG_SYS_INIT_RAM_ADDR |
||||
#define CONFIG_SYS_SCONSOLE_SIZE 0x0002000 |
||||
|
||||
/* SDRAM 0 - 256MB
|
||||
*/ |
||||
|
||||
/*HJF: #define CONFIG_SYS_IBAT0L (CONFIG_SYS_SDRAM_BASE | BATL_PP_RW | BATL_CACHEINHIBIT)
|
||||
#define CONFIG_SYS_IBAT0U (CONFIG_SYS_SDRAM_BASE | BATU_BL_4M | BATU_VS | BATU_VP) |
||||
#define CONFIG_SYS_DBAT0L (CONFIG_SYS_SDRAM_BASE | BATL_PP_RW | BATL_CACHEINHIBIT) |
||||
#define CONFIG_SYS_DBAT0U CONFIG_SYS_IBAT0U*/ |
||||
|
||||
#define CONFIG_SYS_DBAT0L (CONFIG_SYS_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE) |
||||
#define CONFIG_SYS_DBAT0U (CONFIG_SYS_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP) |
||||
#define CONFIG_SYS_IBAT0L (CONFIG_SYS_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE) |
||||
#define CONFIG_SYS_IBAT0U (CONFIG_SYS_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP) |
||||
/* PCI Range
|
||||
*/ |
||||
#define CONFIG_SYS_DBAT1L (0x80000000 | BATL_PP_RW | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) |
||||
#define CONFIG_SYS_DBAT1U (0x80000000 | BATU_BL_256M | BATU_VS | BATU_VP) |
||||
#define CONFIG_SYS_IBAT1L (0x80000000 | BATL_PP_RW | BATL_CACHEINHIBIT) |
||||
#define CONFIG_SYS_IBAT1U (0x80000000 | BATU_BL_256M | BATU_VS | BATU_VP) |
||||
/* HJF:
|
||||
#define CONFIG_SYS_IBAT1L ((CONFIG_SYS_SDRAM_BASE+CONFIG_SYS_INIT_RAM_ADDR) | BATL_PP_RW) |
||||
#define CONFIG_SYS_IBAT1U ((CONFIG_SYS_SDRAM_BASE+CONFIG_SYS_INIT_RAM_ADDR) | BATU_BL_256M | BATU_VS | BATU_VP) |
||||
#define CONFIG_SYS_DBAT1L ((CONFIG_SYS_SDRAM_BASE+CONFIG_SYS_INIT_RAM_ADDR + 0x20000) | BATL_PP_RW ) |
||||
#define CONFIG_SYS_DBAT1U ((CONFIG_SYS_SDRAM_BASE+CONFIG_SYS_INIT_RAM_ADDR + 0x20000) | BATU_BL_256M | BATU_VS | BATU_VP) |
||||
*/ |
||||
|
||||
/* Init RAM in the CPU DCache (no backing memory)
|
||||
*/ |
||||
#define CONFIG_SYS_DBAT2L (CONFIG_SYS_INIT_RAM_ADDR | BATL_PP_RW | BATL_MEMCOHERENCE) |
||||
#define CONFIG_SYS_DBAT2U (CONFIG_SYS_INIT_RAM_ADDR | BATU_BL_128K | BATU_VS | BATU_VP) |
||||
/* This used to be commented out */ |
||||
#define CONFIG_SYS_IBAT2L CONFIG_SYS_DBAT2L |
||||
/* This here too */ |
||||
#define CONFIG_SYS_IBAT2U CONFIG_SYS_DBAT2U |
||||
|
||||
|
||||
/* I/O and PCI memory at 0xf0000000
|
||||
*/ |
||||
#define CONFIG_SYS_DBAT3L (0xf0000000 | BATL_PP_RW | BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE) |
||||
#define CONFIG_SYS_DBAT3U (0xf0000000 | BATU_BL_256M | BATU_VS | BATU_VP) |
||||
|
||||
#define CONFIG_SYS_IBAT3L (0xf0000000 | BATL_PP_RW | BATL_CACHEINHIBIT) |
||||
#define CONFIG_SYS_IBAT3U (0xf0000000 | BATU_BL_256M | BATU_VS | BATU_VP) |
||||
|
||||
/*
|
||||
* Low Level Configuration Settings |
||||
* (address mappings, register initial values, etc.) |
||||
*/ |
||||
#define CONFIG_SYS_HZ 1000 |
||||
#define CONFIG_SYS_BUS_HZ 133000000 /* bus speed - 100 mhz */ |
||||
#define CONFIG_SYS_CPU_CLK 133000000 |
||||
#define CONFIG_SYS_BUS_CLK 133000000 |
||||
|
||||
/*
|
||||
* For booting Linux, the board info and command line data |
||||
* have to be in the first 8 MB of memory, since this is |
||||
* the maximum mapped by the Linux kernel during initialization. |
||||
*/ |
||||
#define CONFIG_SYS_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */ |
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* FLASH organization |
||||
*/ |
||||
#define CONFIG_SYS_MAX_FLASH_BANKS 1 /* Max number of flash banks */ |
||||
#define CONFIG_SYS_MAX_FLASH_SECT 8 /* Max number of sectors in one bank */ |
||||
|
||||
#define CONFIG_SYS_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */ |
||||
#define CONFIG_SYS_FLASH_WRITE_TOUT 1000 /* Timeout for Flash Write (in ms) */ |
||||
|
||||
/*
|
||||
* Environment is stored in NVRAM. |
||||
*/ |
||||
#define CONFIG_ENV_IS_IN_NVRAM 1 |
||||
#define CONFIG_ENV_ADDR 0xFD0E0000 /* This should be 0xFD0E0000, but we skip bytes to |
||||
* protect softex's settings for now. |
||||
* Original 768 bytes where not enough. |
||||
*/ |
||||
#define CONFIG_ENV_SIZE 0x8000 /* Size of the Environment. See comment above */ |
||||
|
||||
#define CONFIG_SYS_CONSOLE_IS_IN_ENV 1 /* stdin/stdout/stderr are in environment */ |
||||
#define CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE 1 |
||||
#define CONFIG_ENV_OVERWRITE 1 |
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Cache Configuration |
||||
*/ |
||||
#define CONFIG_SYS_CACHELINE_SIZE 32 |
||||
#if defined(CONFIG_CMD_KGDB) |
||||
# define CONFIG_SYS_CACHELINE_SHIFT 5 /* log base 2 of the above value */ |
||||
#endif |
||||
|
||||
/*
|
||||
* L2 cache |
||||
*/ |
||||
#define CONFIG_SYS_L2 |
||||
#define L2_INIT (L2CR_L2SIZ_2M | L2CR_L2CLK_3 | L2CR_L2RAM_BURST | \ |
||||
L2CR_L2OH_5 | L2CR_L2CTL | L2CR_L2WT) |
||||
#define L2_ENABLE (L2_INIT | L2CR_L2E) |
||||
|
||||
/*
|
||||
* Internal Definitions |
||||
* |
||||
* Boot Flags |
||||
*/ |
||||
#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ |
||||
#define BOOTFLAG_WARM 0x02 /* Software reboot */ |
||||
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* IDE ATAPI Configuration |
||||
*/ |
||||
|
||||
#define CONFIG_ATAPI 1 |
||||
#define CONFIG_SYS_IDE_MAXBUS 2 |
||||
#define CONFIG_SYS_IDE_MAXDEVICE 4 |
||||
#define CONFIG_ISO_PARTITION 1 |
||||
|
||||
#define CONFIG_SYS_ATA_BASE_ADDR 0xFE000000 /* was: via_get_base_addr() */ |
||||
#define CONFIG_SYS_ATA_IDE0_OFFSET 0x1F0 |
||||
#define CONFIG_SYS_ATA_IDE1_OFFSET 0x170 |
||||
|
||||
#define CONFIG_SYS_ATA_REG_OFFSET 0 |
||||
#define CONFIG_SYS_ATA_DATA_OFFSET 0 |
||||
#define CONFIG_SYS_ATA_ALT_OFFSET 0x0200 |
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Disk-On-Chip configuration |
||||
*/ |
||||
|
||||
#define CONFIG_SYS_MAX_DOC_DEVICE 1 /* Max number of DOC devices */ |
||||
|
||||
#define CONFIG_SYS_DOC_SUPPORT_2000 |
||||
#undef CONFIG_SYS_DOC_SUPPORT_MILLENNIUM |
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
RTC |
||||
*/ |
||||
#define CONFIG_RTC_MC146818 |
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* NS16550 Configuration |
||||
*/ |
||||
|
||||
#define CONFIG_SYS_NS16550 |
||||
|
||||
#define CONFIG_SYS_NS16550_COM1 0xFE0003F8 |
||||
#define CONFIG_SYS_NS16550_COM2 0xFE0002F8 |
||||
|
||||
#define CONFIG_SYS_NS16550_REG_SIZE 1 |
||||
|
||||
/* base address for ISA I/O
|
||||
*/ |
||||
#define CONFIG_SYS_ISA_IO_BASE_ADDRESS 0xFE000000 |
||||
|
||||
/* ISA Interrupt stuff (taken from JWL) */ |
||||
|
||||
#define ISA_INT1_OCW1 0x21 |
||||
#define ISA_INT2_OCW1 0xA1 |
||||
#define ISA_INT1_OCW2 0x20 |
||||
#define ISA_INT2_OCW2 0xA0 |
||||
#define ISA_INT1_OCW3 0x20 |
||||
#define ISA_INT2_OCW3 0xA0 |
||||
|
||||
#define ISA_INT1_ICW1 0x20 |
||||
#define ISA_INT2_ICW1 0xA0 |
||||
#define ISA_INT1_ICW2 0x21 |
||||
#define ISA_INT2_ICW2 0xA1 |
||||
#define ISA_INT1_ICW3 0x21 |
||||
#define ISA_INT2_ICW3 0xA1 |
||||
#define ISA_INT1_ICW4 0x21 |
||||
#define ISA_INT2_ICW4 0xA1 |
||||
|
||||
|
||||
/*
|
||||
* misc |
||||
*/ |
||||
|
||||
#define CONFIG_NET_MULTI |
||||
#define CONFIG_SYS_BOARD_ASM_INIT |
||||
#define CONFIG_LAST_STAGE_INIT |
||||
|
||||
/* #define CONFIG_ETHADDR 00:09:D2:10:00:76 */ |
||||
/* #define CONFIG_IPADDR 192.168.0.2 */ |
||||
/* #define CONFIG_NETMASK 255.255.255.240 */ |
||||
/* #define CONFIG_GATEWAYIP 192.168.0.3 */ |
||||
|
||||
#define CONFIG_3COM |
||||
/* #define CONFIG_BOOTP_RANDOM_DELAY */ |
||||
|
||||
/*
|
||||
* USB configuration |
||||
*/ |
||||
#define CONFIG_USB_UHCI 1 |
||||
#define CONFIG_USB_STORAGE 1 |
||||
#define CONFIG_USB_KEYBOARD 1 |
||||
#define CONFIG_SYS_STDIO_DEREGISTER 1 /* needed by CONFIG_USB_KEYBOARD */ |
||||
|
||||
/*
|
||||
* Autoboot stuff |
||||
*/ |
||||
#define CONFIG_BOOTDELAY 5 /* Boot automatically after five seconds */ |
||||
#define CONFIG_PREBOOT "" |
||||
#define CONFIG_BOOTCOMMAND "fdcboot; diskboot" |
||||
#define CONFIG_MENUPROMPT \ |
||||
"Press any key to interrupt autoboot: %2d ", bootdelay |
||||
#define CONFIG_MENUKEY ' ' |
||||
#define CONFIG_MENUCOMMAND "menu" |
||||
/* #define CONFIG_AUTOBOOT_KEYED */ |
||||
|
||||
/*
|
||||
* Extra ENV stuff |
||||
*/ |
||||
#define CONFIG_EXTRA_ENV_SETTINGS \ |
||||
"stdout=vga\0" \
|
||||
"stdin=ps2kbd\0" \
|
||||
"ide_doreset=on\0" \
|
||||
"ide_maxbus=2\0" \
|
||||
"ide_cd_timeout=30\0" \
|
||||
"menucmd=menu\0" \
|
||||
"pci_irqa=9\0" \
|
||||
"pci_irqa_select=edge\0" \
|
||||
"pci_irqb=10\0" \
|
||||
"pci_irqb_select=edge\0" \
|
||||
"pci_irqc=11\0" \
|
||||
"pci_irqc_select=edge\0" \
|
||||
"pci_irqd=7\0" \
|
||||
"pci_irqd_select=edge\0" |
||||
|
||||
|
||||
/* #define CONFIG_MII 1 */ |
||||
/* #define CONFIG_BITBANGMII 1 */ |
||||
|
||||
|
||||
#endif /* __CONFIG_H */ |
Loading…
Reference in new issue