Rudolf Marek wrote:
What about a weak function? I think about this:
Make a non-weak dummy function which will read the original devicetree data. Create a weak function in your mainboard.c which will override it.
[coreboot] [PATCH] [RFC] sata PHY settings callback on SB700
Something like this.
Move cable detect logic to a weak function in vt8237r_ide.c and add an override function in m2v/mainboard.c
Signed-off-by: Tobias Diedrich ranma+coreboot@tdiedrich.de
---
Index: src/mainboard/asus/m2v/mainboard.c =================================================================== --- src/mainboard/asus/m2v/mainboard.c.orig 2010-11-13 20:25:20.000000000 +0100 +++ src/mainboard/asus/m2v/mainboard.c 2010-11-14 13:32:33.000000000 +0100 @@ -17,9 +17,45 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+#include <arch/io.h> #include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <console/console.h> +#include "southbridge/via/vt8237r/vt8237r.h" #include "chip.h"
+u32 vt8237_ide_80pin_detect(struct device *dev) +{ + device_t lpc_dev; + u16 acpi_io_base; + u32 gpio_in; + u32 res; + + lpc_dev = dev_find_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_VT8237A_LPC, 0); + if (!lpc_dev) + return; + + acpi_io_base = pci_read_config16(lpc_dev, 0x88); + if (!acpi_io_base || (acpi_io_base & ~1) == 0) + return; + acpi_io_base &= ~1; + + gpio_in = inl(acpi_io_base + 0x48); + /* bit 9 for primary port, clear if unconnected or 80-pin cable */ + res = gpio_in & (1<<9) ? 0 : VT8237R_IDE0_80PIN_CABLE; + /* bit 4 for secondary port, clear if unconnected or 80-pin cable */ + res |= gpio_in & (1<<4) ? 0 : VT8237R_IDE1_80PIN_CABLE; + + printk(BIOS_INFO, "Cable on %s PATA port: %d pin\n", "primary", + gpio_in & (1<<9) ? 40 : 80); + printk(BIOS_INFO, "Cable on %s PATA port: %d pin\n", "secondary", + gpio_in & (1<<4) ? 40 : 80); + + return res; +} + struct chip_operations mainboard_ops = { CHIP_NAME("ASUS M2V") }; Index: src/southbridge/via/vt8237r/vt8237r.h =================================================================== --- src/southbridge/via/vt8237r/vt8237r.h.orig 2010-11-13 20:25:20.000000000 +0100 +++ src/southbridge/via/vt8237r/vt8237r.h 2010-11-14 13:30:22.000000000 +0100 @@ -45,6 +45,10 @@ #define IDE_MISC_II 0x45 #define IDE_UDMA 0x50
+#define VT8237R_IDE0_80PIN_CABLE ((1UL<<28)|(1UL<<20)) +#define VT8237R_IDE1_80PIN_CABLE ((1UL<<12)|(1UL<< 4)) +#define VT8237R_IDE_CABLESEL_MASK (VT8237R_IDE0_80PIN_CABLE|VT8237R_IDE1_80PIN_CABLE) + /* SMBus */ #define VT8237R_PSON 0x82 #define VT8237R_POWER_WELL 0x94 @@ -118,6 +122,7 @@ #include <device/device.h> void writeback(struct device *dev, u16 where, u8 what); void dump_south(device_t dev); +u32 vt8237_ide_80pin_detect(struct device *dev); #endif
#endif Index: src/southbridge/via/vt8237r/vt8237r_ide.c =================================================================== --- src/southbridge/via/vt8237r/vt8237r_ide.c.orig 2010-11-13 20:25:20.000000000 +0100 +++ src/southbridge/via/vt8237r/vt8237r_ide.c 2010-11-14 13:31:51.000000000 +0100 @@ -27,6 +27,19 @@ #include "chip.h"
/** + * Cable type detect function, weak so it can be overloaded in mainboard.c + */ +u32 __attribute__((weak)) vt8237_ide_80pin_detect(struct device *dev) +{ + struct southbridge_via_vt8237r_config *sb = + (struct southbridge_via_vt8237r_config *)dev->chip_info; + u32 res; + res = sb->ide0_80pin_cable ? VT8237R_IDE0_80PIN_CABLE : 0; + res |= sb->ide1_80pin_cable ? VT8237R_IDE1_80PIN_CABLE : 0; + return res; +} + +/** * No native mode. Interrupts from unconnected HDDs might occur if * IRQ14/15 is used for PCI. Therefore no native mode support. */ @@ -88,11 +101,8 @@
/* Cable guy... */ cablesel = pci_read_config32(dev, IDE_UDMA); - cablesel &= ~((1 << 28) | (1 << 20) | (1 << 12) | (1 << 4)); - cablesel |= (sb->ide0_80pin_cable << 28) | - (sb->ide0_80pin_cable << 20) | - (sb->ide1_80pin_cable << 12) | - (sb->ide1_80pin_cable << 4); + cablesel &= ~VT8237R_IDE_CABLESEL_MASK; + cablesel |= vt8237_ide_80pin_detect(dev); pci_write_config32(dev, IDE_UDMA, cablesel);
#if CONFIG_EPIA_VT8237R_INIT