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