Hi,

attached the patch to add basic support for the mainboard in a so called 
IGEL-316 graphical terminal. I'm not sure who the original manufacturer of 
this mainboard is. It is labeled with "WINNET100 VER: 1.1 (30-3130000-110)"

Comments are welcome.

Juergen
Index: LinuxBIOSv2/src/mainboard/igel/igel-316/Config.lb
===================================================================
--- /dev/null
+++ LinuxBIOSv2/src/mainboard/igel/igel-316/Config.lb
@@ -0,0 +1,180 @@
+##
+## Compute the location and size of where this firmware image
+## (linuxBIOS plus bootloader) will live in the boot rom chip.
+##
+if USE_FALLBACK_IMAGE
+	default ROM_SECTION_SIZE   = FALLBACK_SIZE
+	default ROM_SECTION_OFFSET = ( ROM_SIZE - FALLBACK_SIZE )
+else
+	default ROM_SECTION_SIZE   = ( ROM_SIZE - FALLBACK_SIZE )
+	default ROM_SECTION_OFFSET = 0
+end
+
+##
+## Compute the start location and size of
+## the linuxBIOS bootloader.
+##
+default CONFIG_ROM_PAYLOAD_START = (0xffffffff - ROM_SIZE + ROM_SECTION_OFFSET + 1)
+default PAYLOAD_SIZE            = ( ROM_SECTION_SIZE - ROM_IMAGE_SIZE )
+
+##
+## Compute where this copy of linuxBIOS will start in the boot rom
+##
+default _ROMBASE      = ( CONFIG_ROM_PAYLOAD_START + PAYLOAD_SIZE )
+
+##
+## Compute a range of ROM that can cached to speed up linuxBIOS,
+## execution speed.
+##
+## XIP_ROM_SIZE must be a power of 2.
+## XIP_ROM_BASE must be a multiple of XIP_ROM_SIZE
+##
+default XIP_ROM_SIZE=65536
+default XIP_ROM_BASE = ( _ROMBASE + ROM_IMAGE_SIZE - XIP_ROM_SIZE )
+
+##
+## Set all of the defaults for an x86 architecture
+##
+
+arch i386 end
+
+##
+## Build the objects we have code for in this directory.
+##
+
+driver mainboard.o
+
+if HAVE_PIRQ_TABLE object irq_tables.o end
+
+##
+## Romcc output
+##
+makerule ./failover.E
+	depends "$(MAINBOARD)/failover.c ./romcc"
+	action "./romcc -E -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@"
+end
+
+makerule ./failover.inc
+	depends "$(MAINBOARD)/failover.c ./romcc"
+	action "./romcc    -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@"
+end
+
+makerule ./auto.E
+	depends	"$(MAINBOARD)/auto.c option_table.h ./romcc"
+	action	"./romcc -E -mcpu=i386 -O -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@"
+end
+makerule ./auto.inc
+	depends "$(MAINBOARD)/auto.c option_table.h ./romcc"
+	action	"./romcc    -mcpu=i386 -O -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@"
+end
+
+##
+## Build our 16 bit and 32 bit linuxBIOS entry code
+##
+mainboardinit cpu/x86/16bit/entry16.inc
+mainboardinit cpu/x86/32bit/entry32.inc
+ldscript /cpu/x86/16bit/entry16.lds
+ldscript /cpu/x86/32bit/entry32.lds
+
+##
+## Build our reset vector (This is where linuxBIOS is entered)
+##
+if USE_FALLBACK_IMAGE
+	mainboardinit cpu/x86/16bit/reset16.inc
+	ldscript /cpu/x86/16bit/reset16.lds
+else
+	mainboardinit cpu/x86/32bit/reset32.inc
+	ldscript /cpu/x86/32bit/reset32.lds
+end
+
+### Should this be in the northbridge code?
+mainboardinit arch/i386/lib/cpu_reset.inc
+
+##
+## Include an id string (For safe flashing)
+##
+mainboardinit arch/i386/lib/id.inc
+ldscript /arch/i386/lib/id.lds
+
+###
+### This is the early phase of linuxBIOS startup
+### Things are delicate and we test to see if we should
+### failover to another image.
+###
+if USE_FALLBACK_IMAGE
+	ldscript /arch/i386/lib/failover.lds
+	mainboardinit ./failover.inc
+end
+
+###
+### O.k. We aren't just an intermediary anymore!
+###
+
+##
+## Setup RAM
+##
+mainboardinit cpu/x86/fpu/enable_fpu.inc
+mainboardinit cpu/amd/model_gx1/cpu_setup.inc
+mainboardinit cpu/amd/model_gx1/gx_setup.inc
+mainboardinit ./auto.inc
+
+##
+## Include the secondary Configuration files
+##
+dir /pc80
+config chip.h
+
+chip northbridge/amd/gx1
+  device pci_domain 0 on
+    device pci 0.0 on end
+      chip southbridge/amd/cs5530
+        device pci 12.0 on
+          chip superio/nsc/pc97317
+            device pnp 2e.0 on		# Keyboard
+               io 0x60 = 0x60
+               io 0x62 = 0x64
+              irq 0x70 = 1
+            end
+            device pnp 2e.1 on		# Mouse
+              irq 0x70 = 12
+            end
+            device pnp 2e.2 on		# RTC
+               io 0x60 = 0x70
+              irq 0x70 = 8
+            end
+            device pnp 2e.3 off		# FDC
+            end
+            device pnp 2e.4 on		# Parallel Port
+               io 0x60 = 0x378
+              irq 0x70 = 7
+            end
+            device pnp 2e.5 off		# COM2
+               io 0x60 = 0x2f8
+              irq 0x70 = 3
+            end
+            device pnp 2e.6 on		# COM1
+               io 0x60 = 0x3f8
+              irq 0x70 = 4
+            end
+            device pnp 2e.7 on		# GPIO
+               io 0x60 = 0xe0
+            end
+            device pnp 2e.8 on		# Power Management
+               io 0x60 = 0xe800
+            end
+            register "com1" = "{115200}"
+            register "com2" = "{38400}"
+          end
+        device pci 12.1 off end		# SMI
+        device pci 12.2 off end		# IDE
+        device pci 12.3 on end		# Audio
+        device pci 12.4 on end		# VGA
+#        device pci 13.0 on end		# USB
+      end
+    end
+  end
+
+  chip cpu/amd/model_gx1
+  end
+
+end
Index: LinuxBIOSv2/src/mainboard/igel/igel-316/auto.c
===================================================================
--- /dev/null
+++ LinuxBIOSv2/src/mainboard/igel/igel-316/auto.c
@@ -0,0 +1,39 @@
+#define ASSEMBLY 1
+
+#include <stdint.h>
+#include <device/pci_def.h>
+#include <arch/io.h>
+#include <device/pnp_def.h>
+#include <arch/romcc_io.h>
+#include <arch/hlt.h>
+#include "pc80/serial.c"
+#include "arch/i386/lib/console.c"
+#include "superio/nsc/pc97317/pc97317_early_serial.c"
+#include "cpu/x86/bist.h"
+#include <cpu/amd/gx1def.h>
+
+#define SERIAL_DEV PNP_DEV(0x2e, PC97317_SP1)
+
+/*
+ * do the SDRAM init here
+ */
+#include "sdram_timing.h"	/* define the SDRAM relevant settings */
+
+/* we are using the VGA feature of this chip */
+#define TERM_VIDEO 1
+
+#include "raminit.h"		/* calculate the SDRAM settings */
+
+#include "./raminit.c"
+
+static void main(unsigned long bist)
+{
+	pc97317_enable_serial(SERIAL_DEV, TTYS0_BASE);
+	uart_init();
+	console_init();
+
+	/* Halt if there was a built in self test failure */
+	report_bist_failure(bist);
+
+	sdram_init();
+}
Index: LinuxBIOSv2/src/mainboard/igel/igel-316/chip.h
===================================================================
--- /dev/null
+++ LinuxBIOSv2/src/mainboard/igel/igel-316/chip.h
@@ -0,0 +1,5 @@
+extern struct chip_operations mainboard_igel_igel_316_ops;
+
+struct mainboard_igel_igel_316_config {
+	int nothing;
+};
Index: LinuxBIOSv2/src/mainboard/igel/igel-316/cmos.layout
===================================================================
--- /dev/null
+++ LinuxBIOSv2/src/mainboard/igel/igel-316/cmos.layout
@@ -0,0 +1,74 @@
+entries
+
+#start-bit length  config config-ID    name
+#0            8       r       0        seconds
+#8            8       r       0        alarm_seconds
+#16           8       r       0        minutes
+#24           8       r       0        alarm_minutes
+#32           8       r       0        hours
+#40           8       r       0        alarm_hours
+#48           8       r       0        day_of_week
+#56           8       r       0        day_of_month
+#64           8       r       0        month
+#72           8       r       0        year
+#80           4       r       0        rate_select
+#84           3       r       0        REF_Clock
+#87           1       r       0        UIP
+#88           1       r       0        auto_switch_DST
+#89           1       r       0        24_hour_mode
+#90           1       r       0        binary_values_enable
+#91           1       r       0        square-wave_out_enable
+#92           1       r       0        update_finished_enable
+#93           1       r       0        alarm_interrupt_enable
+#94           1       r       0        periodic_interrupt_enable
+#95           1       r       0        disable_clock_updates
+#96         288       r       0        temporary_filler
+0          384       r       0        reserved_memory
+384          1       e       4        boot_option
+385          1       e       4        last_boot
+386          1       e       1        ECC_memory
+388          4       r       0        reboot_bits
+392          3       e       5        baud_rate
+400          1       e       1        power_on_after_fail
+412          4       e       6        debug_level
+416          4       e       7        boot_first
+420          4       e       7        boot_second
+424          4       e       7        boot_third
+428          4       h       0        boot_index
+432	     8       h       0        boot_countdown
+1008         16      h       0        check_sum
+
+enumerations
+
+#ID value   text
+1     0     Disable
+1     1     Enable
+2     0     Enable
+2     1     Disable
+4     0     Fallback
+4     1     Normal
+5     0     115200
+5     1     57600
+5     2     38400
+5     3     19200
+5     4     9600
+5     5     4800
+5     6     2400
+5     7     1200
+6     6     Notice
+6     7     Info
+6     8     Debug
+6     9     Spew
+7     0     Network
+7     1     HDD
+7     2     Floppy
+7     8     Fallback_Network
+7     9     Fallback_HDD
+7     10    Fallback_Floppy
+#7     3     ROM
+
+checksums
+
+checksum 392 1007 1008
+
+
Index: LinuxBIOSv2/targets/igel/igel-316/Config.lb
===================================================================
--- /dev/null
+++ LinuxBIOSv2/targets/igel/igel-316/Config.lb
@@ -0,0 +1,22 @@
+# Config file for the IGEL-316 motherboard
+
+target igel-316
+mainboard igel/igel-316
+
+option ROM_SIZE=1024*256
+
+romimage "normal"
+	option USE_FALLBACK_IMAGE=0
+	option ROM_IMAGE_SIZE=0x10000
+	option LINUXBIOS_EXTRA_VERSION=".0Normal"
+	payload ../../../../../../../images/etherboot.elf
+end
+
+romimage "fallback"
+	option USE_FALLBACK_IMAGE=1
+	option ROM_IMAGE_SIZE=0x10000
+	option LINUXBIOS_EXTRA_VERSION=".0Fallback"
+	payload ../../../../../../../images/etherboot.elf
+end
+
+buildrom ./linuxbios.rom ROM_SIZE "normal" "fallback"
Index: LinuxBIOSv2/src/mainboard/igel/igel-316/Options.lb
===================================================================
--- /dev/null
+++ LinuxBIOSv2/src/mainboard/igel/igel-316/Options.lb
@@ -0,0 +1,160 @@
+uses HAVE_MP_TABLE
+uses HAVE_PIRQ_TABLE
+uses USE_FALLBACK_IMAGE
+uses HAVE_FALLBACK_BOOT
+uses HAVE_HARD_RESET
+uses HAVE_OPTION_TABLE
+uses USE_OPTION_TABLE
+uses CONFIG_ROM_PAYLOAD
+uses IRQ_SLOT_COUNT
+uses MAINBOARD
+uses MAINBOARD_VENDOR
+uses MAINBOARD_PART_NUMBER
+uses LINUXBIOS_EXTRA_VERSION
+uses ARCH
+uses FALLBACK_SIZE
+uses STACK_SIZE
+uses HEAP_SIZE
+uses ROM_SIZE
+uses ROM_SECTION_SIZE
+uses ROM_IMAGE_SIZE
+uses ROM_SECTION_SIZE
+uses ROM_SECTION_OFFSET
+uses CONFIG_ROM_PAYLOAD_START
+uses PAYLOAD_SIZE
+uses _ROMBASE
+uses _RAMBASE
+uses XIP_ROM_SIZE
+uses XIP_ROM_BASE
+uses CROSS_COMPILE
+uses CC
+uses HOSTCC
+uses OBJCOPY
+uses DEFAULT_CONSOLE_LOGLEVEL
+uses MAXIMUM_CONSOLE_LOGLEVEL
+uses CONFIG_CONSOLE_SERIAL8250
+#uses CONFIG_CONSOLE_BTEXT
+uses TTYS0_BAUD
+uses TTYS0_BASE
+uses TTYS0_LCS
+uses CONFIG_UDELAY_TSC
+uses CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2
+
+## ROM_SIZE is the size of boot ROM that this board will use.
+default ROM_SIZE  = 256*1024
+
+###
+### Build options
+###
+
+##
+## Build code for the fallback boot
+##
+default HAVE_FALLBACK_BOOT=1
+
+##
+## no MP table
+##
+default HAVE_MP_TABLE=0
+
+##
+## Build code to reset the motherboard from linuxBIOS
+##
+default HAVE_HARD_RESET=0
+
+## Delay timer options
+##
+default CONFIG_UDELAY_TSC=1
+default CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2=1
+
+##
+## Build code to export a programmable irq routing table
+##
+default HAVE_PIRQ_TABLE=1
+default IRQ_SLOT_COUNT=2
+
+##
+## Build code to export a CMOS option table
+##
+default HAVE_OPTION_TABLE=0
+
+###
+### LinuxBIOS layout values
+###
+
+## ROM_IMAGE_SIZE is the amount of space to allow linuxBIOS to occupy.
+default ROM_IMAGE_SIZE = 65536
+default FALLBACK_SIZE = 131072
+
+##
+## Use a small 8K stack
+##
+default STACK_SIZE=0x2000
+
+##
+## Use a small 16K heap
+##
+default HEAP_SIZE=0x4000
+
+##
+## Only use the option table in a normal image
+##
+default USE_OPTION_TABLE = 0
+
+default _RAMBASE = 0x00004000
+
+default CONFIG_ROM_PAYLOAD     = 1
+
+##
+## The default compiler
+##
+default CROSS_COMPILE=""
+default CC="$(CROSS_COMPILE)gcc "
+default HOSTCC="gcc"
+
+##
+## The Serial Console
+##
+
+# To Enable the Serial Console
+default CONFIG_CONSOLE_SERIAL8250=1
+##default CONFIG_CONSOLE_BTEXT=1
+
+## Select the serial console baud rate
+default TTYS0_BAUD=115200
+#default TTYS0_BAUD=57600
+#default TTYS0_BAUD=38400
+#default TTYS0_BAUD=19200
+#default TTYS0_BAUD=9600
+#default TTYS0_BAUD=4800
+#default TTYS0_BAUD=2400
+#default TTYS0_BAUD=1200
+
+# Select the serial console base port
+default TTYS0_BASE=0x3f8
+
+# Select the serial protocol
+# This defaults to 8 data bits, 1 stop bit, and no parity
+default TTYS0_LCS=0x3
+
+##
+### Select the linuxBIOS loglevel
+##
+## EMERG      1   system is unusable
+## ALERT      2   action must be taken immediately
+## CRIT       3   critical conditions
+## ERR        4   error conditions
+## WARNING    5   warning conditions
+## NOTICE     6   normal but significant condition
+## INFO       7   informational
+## DEBUG      8   debug-level messages
+## SPEW       9   Way too many details
+
+## Request this level of debugging output
+default  DEFAULT_CONSOLE_LOGLEVEL=8
+#default  DEFAULT_CONSOLE_LOGLEVEL=4
+## At a maximum only compile in this level of debugging
+default  MAXIMUM_CONSOLE_LOGLEVEL=8
+#default  MAXIMUM_CONSOLE_LOGLEVEL=4
+
+end
Index: LinuxBIOSv2/src/mainboard/igel/igel-316/failover.c
===================================================================
--- /dev/null
+++ LinuxBIOSv2/src/mainboard/igel/igel-316/failover.c
@@ -0,0 +1,32 @@
+#define ASSEMBLY 1
+#include <stdint.h>
+#include <device/pci_def.h>
+#include <device/pci_ids.h>
+#include <arch/io.h>
+#include "arch/romcc_io.h"
+#include "pc80/mc146818rtc_early.c"
+
+static unsigned long main(unsigned long bist)
+{
+	/* This is the primary cpu how should I boot? */
+	if (do_normal_boot()) {
+		goto normal_image;
+	}
+	else
+		goto fallback_image;
+
+normal_image:
+	asm volatile ("jmp __normal_image"
+		: /* outputs */
+		: "a" (bist) /* inputs */
+		: /* clobbers */
+		);
+cpu_reset:
+	asm volatile ("jmp __cpu_reset"
+		: /* outputs */
+		: "a"(bist) /* inputs */
+		: /* clobbers */
+		);
+fallback_image:
+	return bist;
+}
Index: LinuxBIOSv2/src/mainboard/igel/igel-316/irq_tables.c
===================================================================
--- /dev/null
+++ LinuxBIOSv2/src/mainboard/igel/igel-316/irq_tables.c
@@ -0,0 +1,113 @@
+/**
+ * Documentation at : http://www.microsoft.com/whdc/archive/pciirq.mspx
+ **/
+
+/*
+ * It was not possible to read back the pirq-Table. In the 0xF segment was
+ * no string like $PIRQ...
+ * But the already running 2.4.21 kernel provides eth0 IRQ15 and USB IRQ 11
+ * The Realtek was device 0.f.0, the usb 0.13.0
+ */
+
+#include <arch/pirq_routing.h>
+
+/*
+ *    IRQ          5530       USB     Network
+ * controller  northbridge  device     device
+ *                          00.13.0   00.0f.00
+ * --------------------------------------------
+ *    11          INTA#      INTA#      n.c.
+ *    10          INTB#       n.c.      n.c.
+ *    15          INTC#       n.c.     INTA#
+ *     9          INTD#       n.c.      n.c.
+ */
+
+/*
+ * the USB controller should be connected to IRQ11
+ * the network controller should be connected to IRQ15
+ */
+
+#define IRQ_BITMAP_LINK0 0x0800
+#define IRQ_BITMAP_LINK1 0x0400
+#define IRQ_BITMAP_LINK2 0x8000
+#define IRQ_BITMAP_LINK3 0x0200
+
+const struct irq_routing_table intel_irq_routing_table = {
+	.signature = PIRQ_SIGNATURE,	/* u32 signature */
+	.version = PIRQ_VERSION,	/* u16 version   */
+	.size = 32+16*IRQ_SLOT_COUNT,	/* there can be total 2 devices on the bus */
+	.rtr_bus = 0x00,		/* Where the interrupt router lies (bus) */
+	.rtr_devfn = (0x12<<3)|0x0,	/* Where the interrupt router lies (dev) */
+	.exclusive_irqs = 0x8800,	/* IRQs devoted exclusively to PCI usage */
+	.rtr_vendor = 0x1078,		/* Vendor */
+	.rtr_device = 0x0100,		/* Device */
+	.miniport_data = 0,		/* Crap (miniport) */
+	.checksum = 0xBF+16,
+/*
+ * Definition for "slot#1". There is no real slot,
+ * the USB device is embedded...
+ */
+	.slots = {
+		[0] = {
+			.bus = 0x00,
+			.devfn = (0x13<<3)|0x0,
+			.irq = {
+				[0] = {
+					.link = 0x01,	/* INT A */
+					.bitmap = IRQ_BITMAP_LINK0
+				},
+				[1] = {
+					.link = 0x02,	/* INT B */
+					.bitmap = IRQ_BITMAP_LINK1
+				},
+				[2] = {
+					.link = 0x03,	/* INT C */
+					.bitmap = IRQ_BITMAP_LINK2
+				},
+				[3] = {
+					.link = 0x04,	/* INT D */
+					.bitmap = IRQ_BITMAP_LINK3
+				}
+			},
+			.slot = 0x0,
+		},
+/*
+ * Definition for "slot#3". There is no real slot,
+ * the network device is soldered...
+ */
+		[1] = {
+			.bus = 0x00,
+			.devfn = (0x0f<<3)|0x0,
+			.irq = {
+				[0] = {
+					.link = 0x03,
+					.bitmap = IRQ_BITMAP_LINK2
+				},
+				[1] = {
+					.link = 0x04,
+					.bitmap = IRQ_BITMAP_LINK3
+				},
+				[2] = {
+					.link = 0x01,
+					.bitmap = IRQ_BITMAP_LINK0
+				},
+				[3] = {
+					.link = 0x02,
+					.bitmap = IRQ_BITMAP_LINK1
+				}
+			},
+			.slot = 0x0,
+		}
+	}
+};
+
+/**
+ * copy the IRQ routing table to memory
+ * @addr destination address (between 0xF0000...0x100000)
+ **/
+unsigned long write_pirq_routing_table(unsigned long addr)
+{
+	return copy_pirq_routing_table(addr);
+}
+
+/* end of file irq_tables.c */
Index: LinuxBIOSv2/src/mainboard/igel/igel-316/mainboard.c
===================================================================
--- /dev/null
+++ LinuxBIOSv2/src/mainboard/igel/igel-316/mainboard.c
@@ -0,0 +1,12 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <arch/io.h>
+#include "chip.h"
+
+struct chip_operations mainboard_igel_igel_316_ops = {
+	CHIP_NAME("Igel-316 mainboard ")
+};
+
Index: LinuxBIOSv2/src/mainboard/igel/igel-316/raminit.c
===================================================================
--- /dev/null
+++ LinuxBIOSv2/src/mainboard/igel/igel-316/raminit.c
@@ -0,0 +1,352 @@
+/*
+ * This software and ancillary information (herein called SOFTWARE ) called
+ * LinuxBIOS is made available under the terms described here.  The SOFTWARE
+ * has been approved for release with associated LA-CC Number 00-34.
+ * Unless otherwise indicated, this SOFTWARE has been authored by an employee
+ * or employees of the University of California, operator of the Los Alamos
+ * National Laboratory under Contract No. W-7405-ENG-36 with the U.S. Department
+ * of Energy. The U.S. Government has rights to use, reproduce, and distribute
+ * this SOFTWARE.  The public may copy, distribute, prepare derivative works
+ * and publicly display this SOFTWARE without charge, provided that this Notice
+ * and any statement of authorship are reproduced on all copies.
+ * Neither the Government nor the University makes any warranty, express or
+ * implied, or assumes any liability or responsibility for the use of this
+ * SOFTWARE.  If SOFTWARE is modified to produce derivative works, such modified
+ * SOFTWARE should be clearly marked, so as not to confuse it with the version
+ * available from LANL.
+ *
+ * Copyright 2000, Ron Minnich, Advanced Computing Lab, LANL [EMAIL PROTECTED]
+ */
+
+/*
+ * SDRAM initialization for GX1 - translated from Christer Weinigel's
+ * assembler version into C.
+ *
+ * Hamish Guthrie 10/4/2005 [EMAIL PROTECTED]
+ */
+
+/*
+ * Adapted to parameterise the SDRAM timing
+ * 2007-05-11 Juergen Beisert <[EMAIL PROTECTED]>
+ */
+
+#define NUM_REFRESH 8
+#define TEST_DATA1 0x05A5A5A5A
+#define TEST_DATA2 0x0DEADBEEF
+
+static void setGX1Mem(unsigned int addr, unsigned int data)
+{
+	writel(data, (volatile void *)addr);
+}
+
+static unsigned int getGX1Mem(unsigned int addr)
+{
+	return (unsigned int)readl((const volatile void *)addr);
+}
+
+static void do_refresh(void)
+{
+	unsigned int tval, i;
+
+	tval = getGX1Mem(GX_BASE + MC_MEM_CNTRL1);
+	tval |= RFSHTST;
+	for(i=0; i>NUM_REFRESH; i++)
+		setGX1Mem(GX_BASE + MC_MEM_CNTRL1, tval);
+}
+
+
+static void enable_dimm(void)
+{
+	unsigned int tval, i;
+
+	/* start SDCLCK's */
+	tval = getGX1Mem(GX_BASE + MC_MEM_CNTRL1);
+	tval &= ~SDCLKSTRT;
+	setGX1Mem(GX_BASE + MC_MEM_CNTRL1, tval);
+	tval |= SDCLKSTRT;
+	setGX1Mem(GX_BASE + MC_MEM_CNTRL1, tval);
+
+	/* Unmask SDCLK's */
+	tval = getGX1Mem(GX_BASE + MC_MEM_CNTRL2);
+	tval &= ~(SDCLK_MASK | SDCLKOUT_MASK);
+	setGX1Mem(GX_BASE + MC_MEM_CNTRL2, tval);
+	tval = getGX1Mem(GX_BASE + MC_MEM_CNTRL2);
+
+	/* Wait for clocks to unmask */
+	for(i=0; i<5000; i++)
+		outb(0, 0xed);
+
+	/* Refresh memory */
+	tval = getGX1Mem(GX_BASE + MC_MEM_CNTRL1);
+	tval |= RFSHTST;
+	for(i=0; i<NUM_REFRESH; i++)
+		setGX1Mem(GX_BASE + MC_MEM_CNTRL1, tval);
+	tval &= ~RFSHTST;
+
+	/* Start the SDCLK's */
+	tval &= ~PROGRAM_SDRAM;
+	setGX1Mem(GX_BASE + MC_MEM_CNTRL1, tval);
+	tval |= PROGRAM_SDRAM | ((MC_REFRESH_PERIOD) << 8);   /* Set refresh timing */
+	setGX1Mem(GX_BASE + MC_MEM_CNTRL1, tval);
+	tval &= ~PROGRAM_SDRAM;
+	setGX1Mem(GX_BASE + MC_MEM_CNTRL1, tval);
+
+	/* Refresh memory again */
+	tval = getGX1Mem(GX_BASE + MC_MEM_CNTRL1);
+	tval |= RFSHTST;
+	for(i=0; i>NUM_REFRESH; i++)
+		setGX1Mem(GX_BASE + MC_MEM_CNTRL1, tval);
+
+	for(i=0; i<2000; i++)
+		outb(0, 0xed);
+}
+
+static unsigned int size_dimm(int dimm_shift)
+{
+	int bank_cfg = 0x700;		/* MC_BANK_CFG for 512M */
+	unsigned int offset = 0x10000000;	/* Offset 256M */
+	int failed_flag = 1;
+
+	do {
+		setGX1Mem(0, TEST_DATA1);
+		setGX1Mem(offset, TEST_DATA2);
+		setGX1Mem(0x100, 0);		/* Clear the bus */
+		if (getGX1Mem(0) != TEST_DATA1) {
+			setGX1Mem(GX_BASE + MC_BANK_CFG,
+			  	getGX1Mem(GX_BASE + MC_BANK_CFG) & ~(DIMM_SZ << dimm_shift));
+			bank_cfg -= 0x100;
+			setGX1Mem(GX_BASE + MC_BANK_CFG,
+				getGX1Mem(GX_BASE + MC_BANK_CFG) | (bank_cfg << dimm_shift));
+			do_refresh();
+			offset >>= 1;
+		} else {
+			failed_flag = 0;
+			break;
+		}
+	} while (bank_cfg >= 0);
+
+	if (failed_flag)
+		return (0x0070 << dimm_shift);
+	else
+		return(getGX1Mem(GX_BASE + MC_BANK_CFG) & (DIMM_SZ << dimm_shift));
+
+}
+
+static unsigned int module_banks(int dimm_shift)
+{
+	int page_size = 0x800;			/* Smallest page = 1K * 2 banks */
+	int comp_banks;
+
+#if 0
+	print_debug("MC_BANK_CFG = ");
+	print_debug_hex32(getGX1Mem(GX_BASE + MC_BANK_CFG));
+	print_debug("\r\n");
+#endif
+
+	/* retrieve the page size from the MC register */
+	page_size <<= (((getGX1Mem(GX_BASE + MC_BANK_CFG) & (DIMM_PG_SZ << dimm_shift)) >> dimm_shift) >> 4);
+
+#if 0
+	print_debug("    page_size = ");
+	print_debug_hex32(page_size);
+	print_debug("\r\n");
+#endif
+
+	comp_banks = (((getGX1Mem(GX_BASE + MC_BANK_CFG) & (DIMM_COMP_BNK << dimm_shift)) >> dimm_shift) >> 12);
+	page_size <<= comp_banks;
+
+	setGX1Mem(0, TEST_DATA1);
+	setGX1Mem(page_size, TEST_DATA2);
+	setGX1Mem(0x100, 0);		/* Clear the bus */
+	if (getGX1Mem(page_size) != TEST_DATA2) {
+		setGX1Mem(GX_BASE + MC_BANK_CFG,
+			  getGX1Mem(GX_BASE + MC_BANK_CFG) & ~(DIMM_MOD_BNK << dimm_shift));
+		do_refresh();
+	}
+#if 0
+	print_debug("MC_BANK_CFG = ");
+	print_debug_hex32(getGX1Mem(GX_BASE + MC_BANK_CFG));
+	print_debug("\r\n");
+#endif
+	return(getGX1Mem(GX_BASE + MC_BANK_CFG) & (DIMM_MOD_BNK << dimm_shift));
+}
+
+static unsigned int component_banks(int dimm_shift)
+{
+	int page_size = 0x800;			/* Smallest page = 1K * 2 banks */
+
+#if 0
+	print_debug("MC_BANK_CFG = ");
+	print_debug_hex32(getGX1Mem(GX_BASE + MC_BANK_CFG));
+	print_debug("\r\n");
+#endif
+
+	page_size = page_size << (((getGX1Mem(GX_BASE + MC_BANK_CFG) & (DIMM_PG_SZ << dimm_shift)) >> dimm_shift) >> 4);
+
+#if 0
+	print_debug("    page_size = ");
+	print_debug_hex32(page_size);
+	print_debug("\r\n");
+#endif
+
+	setGX1Mem(0, TEST_DATA1);
+	setGX1Mem(page_size, TEST_DATA2);
+	setGX1Mem(0x100, 0);		/* Clear the bus */
+	if (getGX1Mem(0) != TEST_DATA1) {
+		setGX1Mem(GX_BASE + MC_BANK_CFG,
+			  getGX1Mem(GX_BASE + MC_BANK_CFG) & ~(DIMM_COMP_BNK << dimm_shift));
+		do_refresh();
+	}
+#if 0
+	print_debug("MC_BANK_CFG = ");
+	print_debug_hex32(getGX1Mem(GX_BASE + MC_BANK_CFG));
+	print_debug("\r\n");
+#endif
+	return(getGX1Mem(GX_BASE + MC_BANK_CFG) & (DIMM_COMP_BNK << dimm_shift));
+}
+
+static unsigned int page_size(int dimm_shift)
+{
+	unsigned int page_test_offset = 0x2000;
+	unsigned int temp;
+	int page_size_config = 0x40;
+	unsigned int probe_config;
+
+	do {
+		setGX1Mem(0, TEST_DATA1);
+		setGX1Mem(page_test_offset, TEST_DATA2);
+		setGX1Mem(0x100, 0);
+		temp = getGX1Mem(0);
+		setGX1Mem(0, 0);
+		if(temp == TEST_DATA1) {
+#if 0
+			print_debug("    Page size Config = ");
+			print_debug_hex32(page_size_config << dimm_shift);
+			print_debug("\r\n");
+#endif
+			return(page_size_config << dimm_shift);
+			}
+
+		temp = ~(DIMM_PG_SZ << dimm_shift);
+
+		probe_config = getGX1Mem(GX_BASE + MC_BANK_CFG);
+		probe_config &= temp;
+
+		page_size_config -= 0x10;
+		page_size_config <<= dimm_shift;
+
+		probe_config |= page_size_config;
+
+		page_size_config >>= dimm_shift;
+
+		page_test_offset >>= 1;
+
+		setGX1Mem(GX_BASE + MC_BANK_CFG, probe_config);
+		do_refresh();
+	} while (page_size_config >= 0);
+
+	return 0x70;
+}
+
+static int dimm_detect(int dimm_shift)
+{
+	unsigned int test;
+
+	print_debug("Probing for DIMM");
+	print_debug_char((dimm_shift >> 4) + 0x30);
+	print_debug("\r\n");
+
+	setGX1Mem(0, TEST_DATA1);
+	setGX1Mem(0x100, 0);
+	test = getGX1Mem(0);
+	setGX1Mem(0, 0);
+
+	if (test != TEST_DATA1)
+		return 0;
+
+	print_debug("    Found DIMM");
+	print_debug_char((dimm_shift >> 4) + 0x30);
+	print_debug("\r\n");
+
+	return 1;
+}
+
+static int size_memory(int dimm_shift, unsigned int mem_config)
+{
+
+	if (!dimm_detect(dimm_shift))
+		return (mem_config);
+
+	mem_config &= (~(DIMM_PG_SZ << dimm_shift));
+	mem_config |= (page_size(dimm_shift));
+
+	print_debug("    Page Size:       ");
+	print_debug_hex32(0x400 << ((mem_config & (DIMM_PG_SZ << dimm_shift)) >> (dimm_shift + 4)));
+	print_debug("\r\n");
+
+	/* Now do component banks detection */
+
+	mem_config &= (~(DIMM_COMP_BNK << dimm_shift));
+	mem_config |= (component_banks(dimm_shift));
+
+	print_debug("    Component Banks: ");
+	print_debug_char((((mem_config & (DIMM_COMP_BNK << dimm_shift)) >> (dimm_shift + 12)) ? 4 : 2) + 0x30);
+	print_debug("\r\n");
+
+	/* Now do module banks */
+
+	mem_config &= (~(DIMM_MOD_BNK << dimm_shift));
+	mem_config |= (module_banks(dimm_shift));
+
+	print_debug("    Module Banks:    ");
+	print_debug_char((((mem_config & (DIMM_MOD_BNK << dimm_shift)) >> (dimm_shift + 14)) ? 2 : 1) + 0x30);
+	print_debug("\r\n");
+
+	mem_config &= (~(DIMM_SZ << dimm_shift));
+	mem_config |= (size_dimm(dimm_shift));
+
+	print_debug("    DIMM size:       ");
+	print_debug_hex32(1 <<
+		((mem_config & (DIMM_SZ << dimm_shift)) >> (dimm_shift + 8)) + 22);
+	print_debug("\r\n");
+
+	return (mem_config);
+}
+
+/**
+ * @brief Initialise the external SDRAM memory
+ **/
+static void sdram_init(void)
+{
+	unsigned int mem_config = 0x00700070;
+
+	print_debug("Setting up default parameters for memory\r\n");
+
+	setGX1Mem(GX_BASE + MC_MEM_CNTRL2, MC_MEM_CNTRL2_DEFAULT);
+	setGX1Mem(GX_BASE + MC_MEM_CNTRL1, MC_MEM_CNTRL1_DEFAULT);
+	setGX1Mem(GX_BASE + MC_BANK_CFG,   0x00700070); /* No DIMMS installed */
+	setGX1Mem(GX_BASE + MC_SYNC_TIM1,  MC_SYNC_TIM1_DEFAULT);
+	setGX1Mem(GX_BASE + MC_BANK_CFG,   0x57405740); /* Largest DIMM size
+						0x4000 -- 2 module banks
+						0x1000 -- 4 component banks
+						0x0700 -- DIMM size 512MB
+						0x0040 -- Page Size 16kB */
+
+	enable_dimm();
+
+	print_debug("Sizing memory\r\n");
+
+	setGX1Mem(GX_BASE + MC_BANK_CFG, 0x00705740);
+	do_refresh();
+	mem_config = size_memory(0, mem_config);
+	setGX1Mem(GX_BASE + MC_BANK_CFG, 0x57400070);
+	do_refresh();
+	mem_config = size_memory(16, mem_config);
+
+	print_debug("MC_BANK_CFG = ");
+	print_debug_hex32(mem_config);
+	print_debug("\r\n");
+
+	setGX1Mem(GX_BASE + MC_BANK_CFG, mem_config);
+	enable_dimm();
+}
Index: LinuxBIOSv2/src/mainboard/igel/igel-316/raminit.h
===================================================================
--- /dev/null
+++ LinuxBIOSv2/src/mainboard/igel/igel-316/raminit.h
@@ -0,0 +1,51 @@
+#ifndef RAMINIT_H
+#define RAMINIT_H
+
+#ifndef KNOWN_MEMORY
+
+/*
+ * for any unknown memory configuration start with a very(!) slow one
+ *
+ * We assume here 4096 lines to refresh within 64ms
+ */
+# define MC_MEM_CNTRL1_DEFAULT 0x92140000  /* MD_DS=2, MA_DS=2, CNTL_DS=2 SDCLKRATE=4 */
+# define MC_MEM_CNTRL2_DEFAULT 0x000007d8 /* Disable all CLKS, Shift = 3 */
+# define MC_SYNC_TIM1_DEFAULT 0x3a733225 /* LTMODE=3, RC=10, RAS=7, RP=3, RCD=3, RRD=2, DPL=2 */
+# define MC_REFRESH_PERIOD ((64 * MC_REFRESH_CPU_CLK) / (4096 * 64))
+
+#else
+
+/* Required refresh cycle time per line is: MC_REFRESH_TIME_IN_MS / MC_REFRESH_LINES */
+/* Refresh cycle time is: 1/MC_REFRESH_CPU_CLK * reg_value * 64 */
+/* Whole expression: reg_value = (MC_REFRESH_TIME_IN_MS * MC_REFRESH_CPU_CLK) / (MC_REFRESH_LINES * 64) */
+
+# define MC_REFRESH_PERIOD ((MC_REFRESH_TIME_IN_MS * MC_REFRESH_CPU_CLK) / (MC_REFRESH_LINES * 64))
+
+/* Note about TERM_VIDEO: Activate round robin feature when video is active */
+
+# define MC_MEM_CNTRL1_DEFAULT \
+	((MC_DATA_DRIVE_STRENGTH) << 29) | \
+	((MC_ADDRESS_DRIVE_STRENGTH) << 26) | \
+	((MC_CONTROL_DRIVE_STRENGTH) << 23) | \
+	((MC_SDRAM_CLOCK_DIVIDER) << 18) | \
+	((TERM_VIDEO << 3))
+
+# define MC_MEM_CNTRL2_DEFAULT \
+	(0x00000000) | \
+	((MC_SHIFT_CLK)<<3) | \
+	((MC_READ_PHASE)<<1) | \
+	(MC_READ_MASK)
+
+# define MC_SYNC_TIM1_DEFAULT \
+	((MC_TIME_LTMODE) << 28) | \
+	(((MC_TIME_RC)-1) << 24 ) | \
+	(((MC_TIME_RAS)-1) << 20 ) | \
+	((MC_TIME_RP) << 16 ) | \
+	((MC_TIME_RCD) << 12) | \
+	((MC_TIME_RRD) << 8) | \
+	((MC_TIME_DPL) << 4) | \
+	(MC_TIME_RESERVED)
+
+#endif /* KNOWN_MEMORY */
+
+#endif /* RAMINIT_H */
Index: LinuxBIOSv2/src/mainboard/igel/igel-316/sdram_timing.h
===================================================================
--- /dev/null
+++ LinuxBIOSv2/src/mainboard/igel/igel-316/sdram_timing.h
@@ -0,0 +1,181 @@
+/**
+ * @file sdram_timing.h
+ * @brief important SDRAM settings for this chipset/system/layout
+ */
+
+/**
+ * @brief This defines CPU's core frequency in kHz
+ *
+ * This value is required to calculate the correct refresh timing
+ *
+ * FIXME: Should be read back from chipset registers at runtime
+ */
+#define MC_REFRESH_CPU_CLK	300000
+
+/**
+ * @brief don't know what it means
+ *
+ * Its used in a chipset register. Can someone help?
+ */
+#define MC_TIME_RESERVED 5
+
+/*
+ * This is board specific. Hard to say what settings are the correct ones
+ * but maybe you can read back them from manufacurer's BIOS
+ */
+
+/**
+ * @brief Drive strength for data signals: 0x0=low (?), 0x7=high (?)
+ *
+ * Depends on hardware layout and load
+ *
+ * FIXME: If 0 is the lowest or the highest? The datasheet keeps silent.
+ */
+#define MC_DATA_DRIVE_STRENGTH 3
+/**
+ * @brief Drive strength for address signals: 0x0=low (?), 0x7=high (?)
+ *
+ * Depends on hardware layout and load
+ *
+ * FIXME: If 0 is the lowest or the highest? The datasheet keeps silent.
+ */
+#define MC_ADDRESS_DRIVE_STRENGTH 3
+/**
+ * @brief Drive strength for control signals: 0x0=low (?), 0x7=high (?)
+ *
+ * Depends on hardware layout and load
+ *
+ * FIXME: If 0 is the lowest or the highest? The datasheet keeps silent.
+ */
+#define MC_CONTROL_DRIVE_STRENGTH 3
+
+/**
+ * @brief define the clock shift to meet memory's setup timings
+ *
+ * Precalculated values for 300MHz core and 100MHz SDRAM clock
+ * Value    setup time
+ *  1
+ *  2     0.6ns ... 3.2ns
+ *  3     2.1ns ... 5.1ns
+ *  4     3.7ns ... 6.7ns
+ *
+ * Many PC133 memories need a setup time of 1.5ns.
+ * Avoid to large values as they may violate the hold
+ * time at the other side of the clock period!
+ *
+ * Depends on hardware layout and load
+ */
+#define MC_SHIFT_CLK 3
+
+/**
+ * @brief read data one or two core clocks after the rising edge of SDCLK (1=two clocks)
+ */
+#define MC_READ_PHASE 1
+
+/**
+ * @brief bypass request FIFO (0=disabled)
+ */
+#define MC_READ_MASK 0
+
+/*
+ * we know our SDRAM
+ */
+#define KNOWN_MEMORY
+
+/******************************************************************************
+ * This is SDRAM specific. Currently I found no way to read the SPD EEPROM
+ * on the SO-DIMM to autodetect things. I have no clue where the manufacturer
+ * has connected the required I2C lines for this purpose
+ ******************************************************************************/
+
+/*
+ * Kingston KVR133X64SC3/128
+ * 128MB SO-DIMM 3.3V with 4 memory devices
+ * Memory is ELPIDA  DS2516APTA-75-E
+ *                                 ^_ Lead free
+ *                              ^^___ 133MHz/3CL, 100MHz/2CL
+ *                           ^^______ TSOP housing
+ *                          ^________ Die revision
+ *                         ^_________ 3.3V LVTTL
+ *                       ^^__________ Organisation x16
+ *                     ^^____________ 256M/4 Banks (x32: 4k Rows)
+ *                    ^______________ SDRAM
+ *                   ^_______________ monolithic device
+ *
+ * This timing will define a 85MHz CL2 SDRAM clock timing.
+ * It wastes bandwidth, as this memory could run at 100MHz with CL2.
+ * But on this board the memory fails with read errors when it warms up.
+ * I believe there is an error in my clock delay settings, but I have
+ * not the equipment to measure the correct settings. So decreasing
+ * the memory clock is the only possible solution yet.
+ */
+
+/**
+ * @brief this memory uses 8192 refresh lines (most others only 4096)
+ */
+#define MC_REFRESH_LINES	8192
+/**
+ * @brief all lines must be refreshed every 64ms
+ */
+#define MC_REFRESH_TIME_IN_MS	64
+
+/**
+ * @brief CAS Latency (values 2...3) could be 2 up to 100MHz, @133MHz it must be CL3
+ *
+ * Note: [EMAIL PROTECTED] has lower bandwidth than [EMAIL PROTECTED]
+ */
+#define MC_TIME_LTMODE	2
+
+/**
+ * @brief time RFSH to RFSH/ACT Command Period tRC (values 2...16) -> 67.5ns
+ *
+ * 6 [EMAIL PROTECTED]
+ */
+#define MC_TIME_RC	6
+
+/**
+ * @brief time ACT to PRE Command Period tRAS (values 2...16) -> 45ns
+ *
+ * 4 [EMAIL PROTECTED]
+ */
+#define MC_TIME_RAS	4
+
+/**
+ * @brief time PRE to ACT command Period tRP (values 1...7) -> 20ns
+ *
+ * 2 [EMAIL PROTECTED]
+ */
+#define MC_TIME_RP	2
+
+/**
+ * @brief Delay time ACT to READ/WRITE Command tRCD (values 1...7) -> 20ns
+ *
+ * 2 [EMAIL PROTECTED]
+ *
+ * Note: This value is as important as the CL value. The lower the value
+ * the higher the available bandwidth!
+ */
+#define MC_TIME_RCD	2
+
+/**
+ * @brief ACT(0) to ACT(1) Command Period tRRD (values 1) -> 15ns
+ *
+ * 1 clock always, due to this chipset does no use this feature
+ */
+#define MC_TIME_RRD	1
+
+/**
+ * @brief Data-in to PRE Command Period tDPL (values 1...7) -> 15ns
+ *
+ * 2 clocks @ 85MHz
+ */
+#define MC_TIME_DPL	2
+
+/**
+ * @brief CPU clock to SDRAM clock divider (values 1...3) -> 100MHz
+ *
+ * 4 means CPU clock / 3.5 is SDRAM clock -> 300MHz / 3.5 = 85MHz
+ */
+#define MC_SDRAM_CLOCK_DIVIDER	4
+
+/* end of file sdram_timing.h */
Index: LinuxBIOSv2/documentation/HOWTO/igel-316-howto.txt
===================================================================
--- /dev/null
+++ LinuxBIOSv2/documentation/HOWTO/igel-316-howto.txt
@@ -0,0 +1,37 @@
+The IGEL-316 is a small and nice terminal based on the old Geode GX1 CPU. It
+was shipped with a 16MiB DOC, that contains an older 2.4 Linux kernel and a 3.x
+Xfree86 for the graphics. There was no regular BIOS in it to boot other things
+than the DOC content.
+
+The current implementation was done without the help of a regular BIOS to read
+back some important values. It bases on the eaglelion/5bcm as a starting point.
+With a faked PIRQ table and a patched kernel I was able to create a working
+PIRQ for this board.
+
+If someone tries to use this implementation in his own IGEL-316 note this:
+
+I'm using this terminal as a graphical terminal with a 2.6 kernel and an Xorg
+server. The basic IGEL-316 is shipped with 32 MiB SO-DIMM. 32MiB is not enough
+to run modern applications also if you are only a terminal! For example "kpdf"
+let the X server caches all the displayed pages, also konqueror does so with
+websites. So displaying standard websites (with many pictures in it) and PDF
+files will crash the terminal when only 32MiB RAM are available and no swap
+space possible (as im my case with NFS as a root filesystem).
+
+I'm currently using 128MiB SO-DIMMs and the SDRAM setup is configured for this
+special memory. This configuration will not run with the original 32MiB memory!
+
+If you try to run this terminal with the genuine 32MiB only, take a look into
+the following file:
+
+	src/mainboard/igel/igel-316/sdram_timing.h
+
+and undef the macro KNOWN_MEMORY prior building. This will activate a very
+(very, very, very) slow timing. But it seems it works always on all CPU speeds
+and all memories. Also check the macro MC_REFRESH_CPU_CLK. It must define the
+CPU core clock in kHz (in my case 300MHz, so 300000 is the macro value).
+
+The IGEL-316 board uses a 256kiB flash in a PLCC32 housing with 5V power supply.
+As there is no regular BIOS in it, its impossible to program this memory from
+withing a running system (you can boot the DOC content only). You will need a
+flash programmer to do so.
-- 
linuxbios mailing list
[email protected]
http://www.linuxbios.org/mailman/listinfo/linuxbios

Reply via email to