2 * This file is part of the coreboot project.
4 * Copyright (C) 2007-2009 coresystems GmbH
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 #include <console/console.h>
21 #include <device/device.h>
22 #include <device/pci.h>
23 #include <device/pci_ids.h>
25 /* IDE specific bits */
26 #define IDE_MODE_REG 0x09
27 #define IDE0_NATIVE_MODE (1 << 0)
28 #define IDE1_NATIVE_MODE (1 << 2)
30 /* These are default addresses */
31 #define IDE0_DATA_ADDR 0x1f0
32 #define IDE0_CONTROL_ADDR 0x3f4
33 #define IDE1_DATA_ADDR 0x170
34 #define IDE1_CONTROL_ADDR 0x370
36 #define BUS_MASTER_ADDR 0xfc00
38 #define CHANNEL_ENABLE_REG 0x40
39 #define ENABLE_IDE0 (1 << 0)
40 #define ENABLE_IDE1 (1 << 1)
42 /* TODO: better user configuration */
43 #define DISABLE_SATA 0
45 static void sata_init(struct device *dev)
49 printk_debug("Configuring VIA SATA & EIDE Controller\n");
51 /* Class IDE Disk, instead of RAID controller */
52 reg8 = pci_read_config8(dev, 0x45);
53 reg8 &= 0x7f; /* Sub Class Write Protect off */
54 pci_write_config8(dev, 0x45, reg8);
55 pci_write_config8(dev, 0x0a, 0x01);
56 reg8 |= 0x80; /* Sub Class Write Protect on */
57 pci_write_config8(dev, 0x45, reg8);
59 #if defined(DISABLE_SATA) && (DISABLE_SATA == 1)
60 printk_info("Disabling SATA (Primary Channel)\n");
61 /* Disable SATA channels */
62 pci_write_config8(dev, 0x40, 0x00);
64 pci_write_config8(dev, 0x40, 0x43);
67 reg8 = pci_read_config8(dev, 0x6a);
68 reg8 |= 0x8; /* Mode Select set to Manual Mode */
70 reg8 |= 0x2; /* Manual setting to 50 ohm */
72 pci_write_config8(dev, 0x6a, reg8);
74 reg8 = pci_read_config8(dev, 0x6b);
76 reg8 |= 0x01; /* Autocomp of Termination */
77 pci_write_config8(dev, 0x6b, reg8);
79 /* Enable EIDE (secondary channel) even if SATA disabled */
80 reg8 = pci_read_config8(dev, 0xc0);
82 pci_write_config8(dev, 0xc0, reg8);
84 // Enable bus mastering, memory space acces, io space access
85 pci_write_config16(dev, 0x04, 0x0007);
87 /* Set SATA base ports. */
88 pci_write_config32(dev, 0x10, 0x01f1);
89 pci_write_config32(dev, 0x14, 0x03f5);
90 /* Set EIDE base ports. */
91 pci_write_config32(dev, 0x18, 0x0171);
92 pci_write_config32(dev, 0x1c, 0x0375);
94 /* SATA/EIDE Bus Master mode base address */
95 pci_write_config32(dev, 0x20, BUS_MASTER_ADDR | 1);
97 /* Enable read/write prefetch buffers */
98 reg8 = pci_read_config8(dev, 0xc1);
100 pci_write_config8(dev, 0xc1, reg8);
102 /* Set FIFO thresholds like */
103 pci_write_config8(dev, 0xc3, 0x1); /* FIFO flushed when 1/2 full */
105 /* EIDE Sector Size */
106 pci_write_config16(dev, 0xe8, 0x200);
108 /* Some Miscellaneous Control */
109 pci_write_config8(dev, 0x44, 0x7);
110 pci_write_config8(dev, 0x45, 0xaf);
111 pci_write_config8(dev, 0x46, 0x8);
113 /* EIDE Configuration */
114 reg8 = pci_read_config8(dev, 0xc4);
116 pci_write_config8(dev, 0xc4, reg8);
118 pci_write_config8(dev, 0xc5, 0xc);
121 reg8 = pci_read_config8(dev, 0x45);
122 reg8 &= ~(1 << 4); /* Interrupt Line Write Protect off */
123 pci_write_config8(dev, 0x45, reg8);
125 pci_write_config8(dev, 0x3c, 0x0e); /* Interrupt */
127 /* Set the drive timing control */
128 pci_write_config16(dev, 0x48, 0x5d5d);
130 /* Enable only compatibility mode. */
131 reg8 = pci_read_config8(dev, 0x42);
133 pci_write_config8(dev, 0x42, reg8);
134 reg8 = pci_read_config8(dev, 0x42);
135 printk_debug("Reg 0x42 read back as 0x%x\n", reg8);
137 /* Support Staggered Spin-Up */
138 reg8 = pci_read_config8(dev, 0xb9);
139 if ((reg8 & 0x8) == 0) {
140 printk_debug("start OOB sequence on both drives\n");
142 pci_write_config8(dev, 0xb9, reg8);
146 static struct device_operations sata_ops = {
147 .read_resources = pci_dev_read_resources,
148 .set_resources = pci_dev_set_resources,
149 .enable_resources = pci_dev_enable_resources,
155 /* When the SATA controller is in IDE mode, the Device ID is 0x5324 */
156 static const struct pci_driver northbridge_driver __pci_driver = {
158 .vendor = PCI_VENDOR_ID_VIA,