From 28ecbeab8830c35f4fe9a299a443623d891b6fa6 Mon Sep 17 00:00:00 2001 From: "Ronald G. Minnich" Date: Wed, 17 Sep 2008 16:36:20 +0000 Subject: [PATCH] The K8 is one example, but there are other devices (e.g. I2C) that also have multiple links. The way this was done in v2 was a big confusing; this way is less so. The changes are easy. Getting them right has been hard :-) First, for a k8 north that has three links, you can name each one as follows: pci0@18,0 pci1@18,0 pci2@18,0 We have to have the same pcidevfn on these because that is how the k8 works. But the unit numbers (pci0, pci1, etc.) distinguish them. The dts will properly generate a "v3 device code" compatible static tree that puts the links in the right place in the data structure. The changes to dts are trivial. As before, dts nodes with children are understood to be a bridge. But what if there is a dts entry like this: pci1@18,0 {/config/("northbridge/amd/k8/pci");}; This entry has no children in the dts. How does dt compiler know it is a bridge? It can not know unless we add information to the dts for that northbridge part. To ensure that all bridge devices are detected, we support the following: if a dts node for a device has a bridge property, e.g.: { device_operations = "k8_ops"; bridge; }; The dt compiler will treat it as a bridge whether it has children or not. Why would a device not have children? Because it might be attached to a pci or other socket, and we don't know at build time if the socket is empty, or what might be in the socket. This code has been tested on dbe62 and k8 simnow, and works on each. It is minimal in size and it does what we need. I hope it resolves our discussion for now. We might want to improve or change the device code later but, at this point, forward motion is important -- I'm on a deadline for a very important demo Oct. 22! Also included in this patch are new debug prints in k8 north. Signed-off-by: Ronald G. Minnich Acked-by: Carl-Daniel Hailfinger git-svn-id: svn://coreboot.org/repository/coreboot-v3@865 f3766cd6-281f-0410-b1cd-43a5c92072e9 --- arch/x86/amd/model_fxx/fidvid.c | 1 + device/pci_ops.c | 6 ++ mainboard/Kconfig | 7 ++ mainboard/amd/serengeti/dts | 12 ++- mainboard/amp/Kconfig | 44 ++++++++++ mainboard/amp/tinygx/Makefile | 34 ++++++++ mainboard/amp/tinygx/cmos.layout | 74 +++++++++++++++++ mainboard/amp/tinygx/dts | 60 ++++++++++++++ mainboard/amp/tinygx/initram.c | 118 +++++++++++++++++++++++++++ mainboard/amp/tinygx/irq_tables.h | 81 ++++++++++++++++++ mainboard/amp/tinygx/stage1.c | 57 +++++++++++++ mainboard/artecgroup/dbe62/initram.c | 2 +- northbridge/amd/geodelx/pci | 1 + northbridge/amd/k8/domain.c | 5 +- northbridge/amd/k8/pci | 1 + northbridge/amd/k8/pci.c | 9 +- superio/ite/it8716f/dts | 40 ++++----- util/dtc/dtc.h | 8 ++ util/dtc/flattree.c | 93 ++++++++++++++++++--- 19 files changed, 620 insertions(+), 33 deletions(-) create mode 100644 mainboard/amp/Kconfig create mode 100644 mainboard/amp/tinygx/Makefile create mode 100644 mainboard/amp/tinygx/cmos.layout create mode 100644 mainboard/amp/tinygx/dts create mode 100644 mainboard/amp/tinygx/initram.c create mode 100644 mainboard/amp/tinygx/irq_tables.h create mode 100644 mainboard/amp/tinygx/stage1.c diff --git a/arch/x86/amd/model_fxx/fidvid.c b/arch/x86/amd/model_fxx/fidvid.c index 45a05a8ddc..29f790b33d 100644 --- a/arch/x86/amd/model_fxx/fidvid.c +++ b/arch/x86/amd/model_fxx/fidvid.c @@ -441,6 +441,7 @@ void init_fidvid_bsp(unsigned bsp_apicid) struct msr msr; msr = rdmsr(FIDVID_STATUS); fid_max = ((msr.lo >> 16) & 0x3f); /* max fid */ + printk(BIOS_DEBUG, "init_fidvid_bsp: fid_max is 0x%x\n", fid_max); #if FX_SUPPORT == 1 if (fid_max >= ((25-4) * 2)) { /* FX max fid is 5G */ fid_max = ((msr.lo >> 8) & 0x3f) + 5*2; /* maxFID = minFID + 1G */ diff --git a/device/pci_ops.c b/device/pci_ops.c index 2fee87ab94..3fe9551e3c 100644 --- a/device/pci_ops.c +++ b/device/pci_ops.c @@ -35,6 +35,12 @@ static struct bus *get_pbus(struct device *dev) { struct bus *pbus = dev->bus; while (pbus && pbus->dev && !ops_pci_bus(pbus)) { + if (pbus->dev == dev) { + printk(BIOS_EMERG, "Loop: dev->dtsname dev->bus->dev\n"); + printk(BIOS_EMERG, "To fix this, set ops_pci_bus in dts\n"); + die("loop due to insufficient dts"); + } + pbus = pbus->dev->bus; } if (!pbus || !pbus->dev || !pbus->dev->ops diff --git a/mainboard/Kconfig b/mainboard/Kconfig index 9a63433601..0453841524 100644 --- a/mainboard/Kconfig +++ b/mainboard/Kconfig @@ -37,6 +37,12 @@ config VENDOR_AMD Select this option for various systems from Advanced Micro Devices, Inc. +config VENDOR_AMP + bool "AMP" + help + Select this option for various systems from + Advanced Micro Devices, Inc. + config VENDOR_ARTECGROUP bool "Artec Group" help @@ -61,6 +67,7 @@ endchoice source "mainboard/adl/Kconfig" source "mainboard/amd/Kconfig" +source "mainboard/amp/Kconfig" source "mainboard/artecgroup/Kconfig" source "mainboard/emulation/Kconfig" source "mainboard/gigabyte/Kconfig" diff --git a/mainboard/amd/serengeti/dts b/mainboard/amd/serengeti/dts index 23f1a81936..693804066c 100644 --- a/mainboard/amd/serengeti/dts +++ b/mainboard/amd/serengeti/dts @@ -25,10 +25,11 @@ apic@0 { }; domain@0 { + /config/("northbridge/amd/k8/domain"); pci@1,0{ }; /* guesses; we need a real lspci */ - pci@18,0 { + pci0@18,0 { /config/("northbridge/amd/k8/pci"); pci@0,0 { /config/("southbridge/amd/amd8111/amd8111.dts"); @@ -40,6 +41,15 @@ /config/("southbridge/amd/amd8111/nic.dts"); }; }; + pci1@18,0 { + /config/("northbridge/amd/k8/pci"); + }; + pci2@18,0 { + /config/("northbridge/amd/k8/pci"); + /* just for illustrating link #2 */ + pci@2,0{ + }; + }; ioport@2e { /config/("superio/winbond/w83627hf/dts"); com1enable = "1"; diff --git a/mainboard/amp/Kconfig b/mainboard/amp/Kconfig new file mode 100644 index 0000000000..b749db7398 --- /dev/null +++ b/mainboard/amp/Kconfig @@ -0,0 +1,44 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2007 coresystems GmbH +## (Written by Stefan Reinauer for coresystems GmbH) +## +## 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +## + +choice + prompt "Mainboard model" + depends on VENDOR_AMP + +config BOARD_AMP_TINYGX + bool "TinyGX" + select ARCH_X86 + select CPU_AMD_GEODELX + select OPTION_TABLE + select NORTHBRIDGE_AMD_GEODELX + select SOUTHBRIDGE_AMD_CS5536 + select SUPERIO_ITE_IT8716F + select PIRQ_TABLE + help + SMP TinyGX + +endchoice + +config MAINBOARD_DIR + string + default amp/tinygx + depends BOARD_AMP_TINYGX + diff --git a/mainboard/amp/tinygx/Makefile b/mainboard/amp/tinygx/Makefile new file mode 100644 index 0000000000..a8bd1db04f --- /dev/null +++ b/mainboard/amp/tinygx/Makefile @@ -0,0 +1,34 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2006-2007 coresystems GmbH +## (Written by Stefan Reinauer for coresystems GmbH) +## +## 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +## + +STAGE0_MAINBOARD_SRC := $(src)/mainboard/$(MAINBOARDDIR)/stage1.c + +INITRAM_SRC = $(src)/mainboard/$(MAINBOARDDIR)/initram.c \ + $(src)/northbridge/amd/geodelx/raminit.c \ + $(src)/southbridge/amd/cs5536/smbus_initram.c \ + $(src)/arch/x86/geodelx/geodelx.c + +STAGE2_MAINBOARD_SRC = + +$(obj)/coreboot.vpd: + $(Q)printf " BUILD DUMMY VPD\n" + $(Q)dd if=/dev/zero of=$(obj)/coreboot.vpd bs=256 count=1 $(SILENT) + diff --git a/mainboard/amp/tinygx/cmos.layout b/mainboard/amp/tinygx/cmos.layout new file mode 100644 index 0000000000..5ba4c032c1 --- /dev/null +++ b/mainboard/amp/tinygx/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 + + diff --git a/mainboard/amp/tinygx/dts b/mainboard/amp/tinygx/dts new file mode 100644 index 0000000000..ec2b86a249 --- /dev/null +++ b/mainboard/amp/tinygx/dts @@ -0,0 +1,60 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Ronald G. Minnich + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/{ + mainboard_vendor = "AMP"; + mainboard_name = "TinyGX"; + mainboard_pci_subsystem_vendor = "0x1022"; + mainboard_pci_subsystem_device = "0x2323"; + cpus { }; + apic@0 { + /config/("northbridge/amd/geodelx/apic"); + }; + domain@0 { + /config/("northbridge/amd/geodelx/domain"); + /* Video RAM has to be in 2MB chunks. */ + geode_video_mb = "8"; + pci@1,0 { + /config/("northbridge/amd/geodelx/pci"); + }; + pci@f,0 { + /config/("southbridge/amd/cs5536/dts"); + /* Interrupt enables for LPC bus. + * Each bit is an IRQ 0-15. */ + lpc_serirq_enable = "0x000010da"; + /* LPC IRQ polarity. Each bit is an IRQ 0-15. */ + lpc_serirq_polarity = "0x0000EF25"; + /* 0:continuous 1:quiet */ + lpc_serirq_mode = "1"; + /* GPIO(0-0x20) for INT D:C:B:A, 0xFF=none. + * See virtual PIC spec. */ + enable_gpio_int_route = "0x0D0C0700"; + enable_USBP4_device = "1"; + }; + pci@f,2 { + /config/("southbridge/amd/cs5536/ide"); + enable_ide = "1"; + }; + ioport@2e { + /config/("superio/ite/it8716f/dts"); + com1enable = "1"; + }; + }; +}; diff --git a/mainboard/amp/tinygx/initram.c b/mainboard/amp/tinygx/initram.c new file mode 100644 index 0000000000..34f3308f18 --- /dev/null +++ b/mainboard/amp/tinygx/initram.c @@ -0,0 +1,118 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Advanced Micro Devices, Inc. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define _MAINOBJECT + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* #include + * TODO: figure out how smbus functions should be done. See smbus_ops.c + */ +extern int smbus_read_byte(u16 device, u8 address); + +#define MANUALCONF 0 /* Do automatic strapped PLL config */ +#define PLLMSRHI 0x00001490 /* manual settings for the PLL */ +#define PLLMSRLO 0x02000030 +#define DIMM0 ((u8) 0xA0) +#define DIMM1 ((u8) 0xA2) + +/** + * Read a byte from the SPD. + * + * For this board, that is really just saying 'read a byte from SMBus'. + * So we use smbus_read_byte(). Nota Bene: leave this here as a function + * rather than a #define in an obscure location. This function is called + * only a few dozen times, and it's not performance critical. + * + * @param device The device. + * @param address The address. + * @return The data from the SMBus packet area or an error of 0xff (i.e. -1). + */ +u8 spd_read_byte(u16 device, u8 address) +{ + u8 spdbyte; + + printk(BIOS_DEBUG, "spd_read_byte dev %04x\n", device); + + spdbyte = smbus_read_byte(device, address); + + printk(BIOS_DEBUG, " addr %02x returns %02x\n", address, spdbyte); + + return spdbyte; +} + +/** + * Placeholder in case we ever need it. Since this file is a + * template for other motherboards, we want this here and we want the + * call in the right place. + */ + +static void mb_gpio_init(void) +{ + /* Early mainboard specific GPIO setup */ +} + +/** + * main for initram for the AMD DB800 development platform. + * It might seem that you could somehow do these functions in, e.g., the cpu + * code, but the order of operations and what those operations are is VERY + * strongly mainboard dependent. It's best to leave it in the mainboard code. + */ +int main(void) +{ + printk(BIOS_DEBUG, "Hi there from initram (stage1) main!\n"); + post_code(POST_START_OF_MAIN); + + system_preinit(); + printk(BIOS_DEBUG, "done preinit\n"); + + mb_gpio_init(); + printk(BIOS_DEBUG, "done gpio init\n"); + + pll_reset(MANUALCONF, PLLMSRHI, PLLMSRLO); + printk(BIOS_DEBUG, "done pll reset\n"); + + cpu_reg_init(0, DIMM0, DIMM1, DRAM_UNTERMINATED); + printk(BIOS_DEBUG, "done cpu reg init\n"); + + sdram_set_registers(); + printk(BIOS_DEBUG, "done sdram set registers\n"); + + sdram_set_spd_registers(DIMM0, DIMM1); + printk(BIOS_DEBUG, "done sdram set spd registers\n"); + + sdram_enable(DIMM0, DIMM1); + printk(BIOS_DEBUG, "done sdram enable\n"); + + /* Check low memory */ + /*ram_check(0x00000000, 640*1024); */ + + printk(BIOS_DEBUG, "stage1 returns\n"); + return 0; +} diff --git a/mainboard/amp/tinygx/irq_tables.h b/mainboard/amp/tinygx/irq_tables.h new file mode 100644 index 0000000000..874bf6acac --- /dev/null +++ b/mainboard/amp/tinygx/irq_tables.h @@ -0,0 +1,81 @@ +/* +* This file is part of the coreboot project. +* +* Copyright (C) 2007 Advanced Micro Devices, Inc. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +* +* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +/* Number of slots and devices in the PIR table */ +#define SLOT_COUNT 4 + +/* Platform IRQs */ +#define PIRQA 10 +#define PIRQB 11 +#define PIRQC 10 +#define PIRQD 11 + +/* Map */ +#define M_PIRQA (1 << PIRQA) /* Bitmap of supported IRQs */ +#define M_PIRQB (1 << PIRQB) /* Bitmap of supported IRQs */ +#define M_PIRQC (1 << PIRQC) /* Bitmap of supported IRQs */ +#define M_PIRQD (1 << PIRQD) /* Bitmap of supported IRQs */ + +/* Link */ +#define L_PIRQA 1 /* Means Slot INTx# Connects To Chipset INTA# */ +#define L_PIRQB 2 /* Means Slot INTx# Connects To Chipset INTB# */ +#define L_PIRQC 3 /* Means Slot INTx# Connects To Chipset INTC# */ +#define L_PIRQD 4 /* Means Slot INTx# Connects To Chipset INTD# */ + +/* + * AMD DB800 interrupt wiring. + * + * Devices are: + * + * FIXME + * + */ + +const struct irq_routing_table intel_irq_routing_table = { + PIRQ_SIGNATURE, + PIRQ_VERSION, + 32 + 16 * SLOT_COUNT, /* Max. number of devices on the bus */ + 0x00, /* Where the interrupt router lies (bus) */ + (0x0F << 3) | 0x0, /* Where the interrupt router lies (dev) */ + 0x00, /* IRQs devoted exclusively to PCI usage */ + 0x100B, /* Vendor */ + 0x002B, /* Device */ + 0, /* Crap (miniport) */ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* u8 rfu[11] */ + 0x00, /* Checksum */ + { + /* If you change the number of entries, change IRQ_SLOT_COUNT above! */ + + /* bus, dev|fn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu */ + + /* CPU */ + {0x00, (0x01 << 3) | 0x0, {{L_PIRQA, M_PIRQA}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}}, 0x0, 0x0}, + + /* Chipset slots -- f.3 wires to B, and f.4 and f.5 wires to D. */ + {0x00, (0x0F << 3) | 0x0, {{L_PIRQA, M_PIRQA}, {L_PIRQB, M_PIRQB}, {L_PIRQC, M_PIRQC}, {L_PIRQD, M_PIRQD}}, 0x0, 0x0}, + + /* On-board ethernet */ + {0x00, (0x0D << 3) | 0x0, {{L_PIRQB, M_PIRQB}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}}, 0x0, 0x0}, + + /* PCI (slot 1) */ + {0x00, (0x0E << 3) | 0x0, {{L_PIRQC, M_PIRQC}, {L_PIRQD, M_PIRQD}, {L_PIRQA, M_PIRQA}, {L_PIRQB, M_PIRQB}}, 0x1, 0x0}, + } +}; diff --git a/mainboard/amp/tinygx/stage1.c b/mainboard/amp/tinygx/stage1.c new file mode 100644 index 0000000000..cc6325774e --- /dev/null +++ b/mainboard/amp/tinygx/stage1.c @@ -0,0 +1,57 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Advanced Micro Devices, Inc. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SERIAL_DEV IT8716F_SP1 +#define SERIAL_IOBASE 0x3f8 + +void hardware_stage1(void) +{ + void it8716f_enable_serial(u8 dev, u8 serial, u16 iobase); + post_code(POST_START_OF_MAIN); + geodelx_msr_init(); + + cs5536_stage1(); + + /* NOTE: must do this AFTER the early_setup! + * it is counting on some early MSR setup + * for cs5536. + */ + cs5536_disable_internal_uart(); + it8716f_enable_serial(0x2e, SERIAL_DEV, SERIAL_IOBASE); + +} + +void mainboard_pre_payload(void) +{ + geode_pre_payload(); + banner(BIOS_DEBUG, "mainboard_pre_payload: done"); +} diff --git a/mainboard/artecgroup/dbe62/initram.c b/mainboard/artecgroup/dbe62/initram.c index 186f27821a..7ab26061cf 100644 --- a/mainboard/artecgroup/dbe62/initram.c +++ b/mainboard/artecgroup/dbe62/initram.c @@ -65,7 +65,7 @@ static const struct spd_entry spd_table[] = { {SPD_tRP, 0x58}, {SPD_PRIMARY_SDRAM_WIDTH, 8}, {SPD_NUM_BANKS_PER_SDRAM, 0x4}, - {SPD_NUM_COLUMNS, 0xa}, /* 8kB */ + {SPD_NUM_COLUMNS, 0x8}, /* 8kB */ {SPD_NUM_DIMM_BANKS, 0x1}, {SPD_REFRESH, 0x82}, {SPD_SDRAM_CYCLE_TIME_2ND, 0x0}, diff --git a/northbridge/amd/geodelx/pci b/northbridge/amd/geodelx/pci index 3039ac0cca..e3a8936a64 100644 --- a/northbridge/amd/geodelx/pci +++ b/northbridge/amd/geodelx/pci @@ -20,5 +20,6 @@ { device_operations = "geodelx_north_pci"; + bridge; }; diff --git a/northbridge/amd/k8/domain.c b/northbridge/amd/k8/domain.c index b6b4fdabab..5f71291d73 100644 --- a/northbridge/amd/k8/domain.c +++ b/northbridge/amd/k8/domain.c @@ -104,6 +104,7 @@ static void k8_pci_domain_read_resources(struct device * dev) unsigned reg; /* Find the already assigned resource pairs */ + printk(BIOS_DEBUG, "k8_pci_domain_read_resources\n"); get_fx_devs(); for(reg = 0x80; reg <= 0xd8; reg+= 0x08) { u32 base, limit; @@ -166,6 +167,7 @@ static void k8_pci_domain_read_resources(struct device * dev) static void k8_pci_domain_set_resources(struct device * dev) { + printk(BIOS_DEBUG, "k8_pci_domain_set_resources\n"); #if CONFIG_HW_MEM_HOLE_SIZEK != 0 struct hw_mem_hole_info get_hw_mem_hole_info(void); void disable_hoist_memory(unsigned long hole_startk, int i); @@ -367,6 +369,7 @@ static unsigned int k8_domain_scan_bus(struct device * dev, unsigned int max) { unsigned reg; int i; + printk(BIOS_DEBUG, "k8_domain_scan_bus\n"); /* Unmap all of the HT chains */ for(reg = 0xe0; reg <= 0xec; reg += 4) { f1_write_config32(reg, 0); @@ -397,7 +400,7 @@ static unsigned int k8_domain_scan_bus(struct device * dev, unsigned int max) return max; } -struct device_operations k8apic_ops = { +struct device_operations k8domain_ops = { .id = {.type = DEVICE_ID_APIC_CLUSTER, {.pci_domain = {.vendor = PCI_VENDOR_ID_AMD, .device = 0x1100}}}, diff --git a/northbridge/amd/k8/pci b/northbridge/amd/k8/pci index 330fcf63bd..071621d16b 100644 --- a/northbridge/amd/k8/pci +++ b/northbridge/amd/k8/pci @@ -20,4 +20,5 @@ { device_operations = "k8_ops"; + bridge; }; diff --git a/northbridge/amd/k8/pci.c b/northbridge/amd/k8/pci.c index 37dfebaae5..387eae811d 100644 --- a/northbridge/amd/k8/pci.c +++ b/northbridge/amd/k8/pci.c @@ -74,6 +74,7 @@ static unsigned int amdk8_scan_chain(struct device * dev, unsigned nodeid, unsig if (!(link_type & LinkConnected)) { return max; } + printk(BIOS_DEBUG, "amdk8_scan_chain: link %d is connected\n", link); do { link_type = pci_read_config32(dev, dev->link[link].cap + 0x18); } while(!(link_type & InitComplete)); @@ -211,6 +212,8 @@ static unsigned int amdk8_scan_chains(struct device * dev, unsigned int max) unsigned offset_unitid = 0; nodeid = amdk8_nodeid(dev); + printk(BIOS_DEBUG, "amdk8_scan_chains\n"); + if(nodeid==0) { sblink = (pci_read_config32(dev, 0x64)>>8) & 3; #if SB_HT_CHAIN_ON_BUS0 > 0 @@ -371,6 +374,7 @@ static void amdk8_link_read_bases(struct device * dev, unsigned nodeid, unsigned static void amdk8_read_resources(struct device * dev) { + printk(BIOS_DEBUG, "amdk8_read_resources\n"); unsigned nodeid, link; nodeid = amdk8_nodeid(dev); for(link = 0; link < dev->links; link++) { @@ -385,7 +389,7 @@ static void amdk8_set_resource(struct device * dev, struct resource *resource, u resource_t rbase, rend; unsigned reg, link; char buf[50]; - + printk(BIOS_DEBUG, "amdk8_set_resource\n"); /* Make certain the resource has actually been set */ if (!(resource->flags & IORESOURCE_ASSIGNED)) { return; @@ -536,6 +540,7 @@ static void amdk8_set_resources(struct device * dev) /* Find the nodeid */ nodeid = amdk8_nodeid(dev); + printk(BIOS_DEBUG, "amdk8_set_resources: nodeid %d\n", nodeid); amdk8_create_vga_resource(dev, nodeid); /* Set each resource we have found */ @@ -554,6 +559,7 @@ static void amdk8_set_resources(struct device * dev) static void amdk8_enable_resources(struct device * dev) { + printk(BIOS_DEBUG, "amdk8_enable_resources\n"); pci_dev_enable_resources(dev); enable_childrens_resources(dev); } @@ -581,4 +587,5 @@ struct device_operations k8_ops = { .phase5_enable_resources = amdk8_enable_resources, .phase6_init = mcf0_control_init, .ops_pci = &pci_dev_ops_pci, + .ops_pci_bus = &pci_cf8_conf1, }; diff --git a/superio/ite/it8716f/dts b/superio/ite/it8716f/dts index 3f9a93afa1..171e964004 100644 --- a/superio/ite/it8716f/dts +++ b/superio/ite/it8716f/dts @@ -1,22 +1,24 @@ -## -## This file is part of the coreboot project. -## -## Copyright (C) 2008 Peter Stuge -## -## 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -## +/* + * + * This file is part of the coreboot project. + * + * Copyright (C) 2008 Peter Stuge + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ { /* Floppy */ floppydev = "0x0"; diff --git a/util/dtc/dtc.h b/util/dtc/dtc.h index a1a09e3838..c06b4dcbc3 100644 --- a/util/dtc/dtc.h +++ b/util/dtc/dtc.h @@ -166,6 +166,10 @@ struct node { int addr_cells, size_cells; char *label; + /* coreboot-specific */ + int linked; /* has this node been added to the links for a bridge? */ + struct node *linknode; /* If I am linked, which node is it? */ + int whichlink; /* which link of the node am I on? */ }; #define for_each_property(n, p) \ @@ -174,6 +178,10 @@ struct node { #define for_each_child(n, c) \ for ((c) = (n)->children; (c); (c) = (c)->next_sibling) +/* N.B.: includes ourselves */ +#define for_all_siblings(n, s) \ + for ((s) = (n->next_sibling); (s); (s) = (s)->next_sibling) + #define for_each_config(n, p) \ for ((p) = (n)->config; (p); (p) = (p)->next) diff --git a/util/dtc/flattree.c b/util/dtc/flattree.c index 6fb34b92c1..e0383e1a53 100644 --- a/util/dtc/flattree.c +++ b/util/dtc/flattree.c @@ -529,6 +529,31 @@ static void coreboot_emit_property(void *e, char *label) fprintf(f, "\tu32 p%d = \tOF_DT_PROP;\n", unique++); } +/* Is the node a bridge? + * If it has children, yes. + * OR if it has a config, if the config has + * the 'bridge' property, yes. + */ +static int is_bridge(struct node *tree) +{ + int bridge = 0; + struct property *prop; + /* simple test: does it have children? If so, it's a bridge */ + if (tree->children) + return 1; + if (tree->config){ + for_each_config(tree, prop) { + if (streq(prop->name, "bridge")){ + bridge = 1; + } + } + } + + return bridge; + +} + + static void coreboot_emit_special(FILE *e, struct node *tree) { FILE *f = e; @@ -538,6 +563,7 @@ static void coreboot_emit_special(FILE *e, struct node *tree) char *configname; char *path; int enabled = 1; + int linkcount = 0; fprintf(f, "struct device dev_%s = {\n", tree->label); /* special case -- the root has a distinguished path */ @@ -609,6 +635,10 @@ static void coreboot_emit_special(FILE *e, struct node *tree) if (streq(prop->name, "device_operations")){ fprintf(f, "\t.ops = &%s,\n", prop->val.val); } + if (streq(prop->name, "ops_pci_bus")){ + fprintf(f, "\t.ops_pci_bus = &%s,\n", clean((char *)prop->val.val, 0)); + ops_set = 1; + } } } /* Process the properties specified in the mainboard dts. @@ -661,23 +691,50 @@ static void coreboot_emit_special(FILE *e, struct node *tree) } if (tree->next_sibling) fprintf(f, "\t.sibling = &dev_%s,\n", tree->next_sibling->label); - /* now do we do next? */ - /* this will need to do a bus for every child. And, below, we're going to need to find which bus we're on*/ - /* for now, let's keep it to the minimum that will work, while we see if we like this. */ - if (tree->children){ - fprintf(f,"\t.links = 1,\n"); + + /* If we are a bridge, and we have not been linked, then set up our links. + * There is a good chance we could expand the for loop to contain this first bit of code. + * OTOH, the compiler can do it for us, and the initial conditions are clearer this way. + */ + if ((! tree->linked) && is_bridge(tree)){ + struct node *siblings; fprintf(f,"\t.link = {\n"); - fprintf(f,"\t\t[0] = {\n"); + fprintf(f,"\t\t[%d] = {\n", linkcount); fprintf(f,"\t\t\t.dev = &dev_%s,\n", tree->label); - fprintf(f,"\t\t\t.link = 0,\n"); - fprintf(f,"\t\t\t.children = &dev_%s\n", tree->children->label); + fprintf(f,"\t\t\t.link = %d,\n", linkcount); + if (tree->children) + fprintf(f,"\t\t\t.children = &dev_%s\n", tree->children->label); fprintf(f,"\t\t},\n"); + /* now we need to handle our siblings. */ + linkcount++; + for_all_siblings(tree, siblings) { + if (is_bridge(siblings) && (!siblings->linked)){ + fprintf(f,"\t\t[%d] = {\n", linkcount); + fprintf(f,"\t\t\t.dev = &dev_%s,\n", siblings->label); + fprintf(f,"\t\t\t.link = %d,\n", linkcount); + if (siblings->children) { + fprintf(f,"\t\t\t.children = &dev_%s\n", siblings->children->label); + siblings->children->linked = 1; + siblings->children->linknode = tree; + siblings->children->whichlink = linkcount; + } + fprintf(f,"\t\t},\n"); + siblings->linked = 1; + siblings->whichlink = linkcount; + siblings->linknode = tree; + linkcount++; + } + } fprintf(f,"\t},\n"); } + fprintf(f,"\t.links = %d,\n", linkcount); /* fill in the 'bus I am on' entry */ - if (tree->parent) + /* being 'linked' on a bus overrides the parent link */ + if (tree->linked) + fprintf(f, "\t.bus = &dev_%s.link[%d],\n", tree->linknode->label, tree->whichlink); + else if (tree->parent) fprintf(f, "\t.bus = &dev_%s.link[0],\n", tree->parent->label); - else + else /* this is a very unusual case: the root */ fprintf(f, "\t.bus = &dev_%s.link[0],\n", tree->label); if (tree->next) @@ -784,6 +841,8 @@ fprintf(stderr, "LEFT OVER CONSTRUCTOR -- FIX ME\n"); } +char *emitted_names[256]; +int emitted_names_count = 0; static void flatten_tree_emit_structdecls(struct node *tree, struct emitter *emit, void *etarget, struct data *strbuf, struct version_info *vi) @@ -794,10 +853,24 @@ static void flatten_tree_emit_structdecls(struct node *tree, struct emitter *emi struct node *child; int seen_name_prop = 0; FILE *f = etarget; + int doconfig = 0; + int already_done = 0; if (tree->config){ + int i; // treename = clean(tree->label, 0); treename = toname(tree->config->label, "_config"); + for(i = 0; i < emitted_names_count; i++) + if (!strcmp(treename, emitted_names[i])) + already_done++; + if (! already_done) { + emitted_names[emitted_names_count++] = treename; + doconfig = 1; + } + } + + if (doconfig) { + emit->beginnode(etarget, treename);