2 * This file is part of the coreboot project.
4 * Copyright (C) 2009 One Laptop per Child, Association, Inc.
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 <device/device.h>
21 #include <device/pci.h>
22 #include <device/pci_ops.h>
23 #include <device/pci_ids.h>
24 #include <console/console.h>
29 static const u8 idedevicepcitable[16 * 12] = {
31 0x02, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00,
32 0x00, 0x00, 0xA8, 0xA8, 0xF0, 0x00, 0x00, 0xB6,
33 0x00, 0x00, 0x01, 0x21, 0x00, 0x00, 0x00, 0x00,
34 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
35 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
36 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
37 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
38 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
40 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
41 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
42 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
43 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
44 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
45 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
46 0x00, 0x01, 0x09, 0xC4, 0x06, 0x11, 0x09, 0xC4,
47 0x00, 0xC2, 0xF9, 0x01, 0x10, 0x00, 0x00, 0x00,
48 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
49 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
50 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
52 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53 0x02, 0x01, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,
54 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57 0x02, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00,
58 0x00, 0x00, 0x99, 0x20, 0xf0, 0x00, 0x00, 0x20,
59 0x00, 0x00, 0x17, 0xF1, 0x00, 0x00, 0x00, 0x00,
60 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
61 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
65 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
71 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
72 0x00, 0x01, 0x09, 0xC4, 0x06, 0x11, 0x09, 0xC4,
73 0x00, 0xc2, 0x09, 0x01, 0x10, 0x00, 0x00, 0x00,
74 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
75 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
76 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
77 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
78 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
79 0x02, 0x01, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,
80 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82 /* Legacy BIOS XP PCI value */
84 0x02, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00,
85 0x00, 0x00, 0xa8, 0x20, 0x00, 0x00, 0x00, 0xb6,
86 0x00, 0x00, 0x16, 0xF1, 0x00, 0x00, 0x00, 0x00,
87 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
88 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
89 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
90 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
91 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
92 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
93 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
94 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
95 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
96 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
97 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
98 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
99 0x00, 0x01, 0x09, 0xC4, 0x06, 0x11, 0x09, 0xC4,
100 0x00, 0x02, 0x09, 0x00, 0x18, 0x00, 0x00, 0x00,
101 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
102 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
103 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
104 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
105 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
106 0x02, 0x01, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,
107 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
110 /* ROM legacy BIOS on cn_8562b */
112 0x03, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00,
113 0x00, 0x00, 0x99, 0x20, 0x60, 0x00, 0x00, 0x20,
114 0x00, 0x00, 0x1E, 0xF1, 0x00, 0x00, 0x00, 0x00,
115 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
116 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
117 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
118 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
119 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
120 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
121 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
122 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
123 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
124 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
125 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
126 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
127 0x00, 0x01, 0x09, 0xC4, 0x06, 0x11, 0x09, 0xC4,
128 0x00, 0x02, 0x09, 0x01, 0x18, 0x0C, 0x00, 0x00,
129 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
130 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
131 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
132 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
133 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
134 0x02, 0x01, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,
135 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
138 /* From legacy BIOS on c7_8562b */
140 0x03, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00,
141 0x00, 0x00, 0x5E, 0x20, 0x60, 0x00, 0x00, 0xB6,
142 0x00, 0x00, 0x1E, 0xF1, 0x00, 0x00, 0x00, 0x00,
143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
144 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
147 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
148 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
149 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
150 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
154 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
155 0x00, 0x01, 0x09, 0xC4, 0x06, 0x11, 0x09, 0xC4,
156 0x00, 0x02, 0x09, 0x01, 0x18, 0x0C, 0x00, 0x00,
157 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
158 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
159 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
160 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
161 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
162 0x02, 0x01, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,
163 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
167 static void ide_init(struct device *dev)
170 printk(BIOS_INFO, "ide_init\n");
172 /* these 3 lines help to keep interl back door for DID VID SUBID untouched */
173 u16 data16_1, data16_2;
174 data16_1 = pci_read_config16(dev, 0xba);
175 data16_2 = pci_read_config16(dev, 0xbe);
177 for (i = 0; i < (16 * 12); i++) {
178 pci_write_config8(dev, 0x40 + i, idedevicepcitable[i]);
180 //pci_write_config8(dev, 0x0d, 0x20);
181 data = pci_read_config8(dev, 0x0d);
184 pci_write_config8(dev, 0x0d, data);
186 //these 2 lines help to keep interl back door for DID VID SUBID untouched
187 pci_write_config16(dev, 0xba, data16_1);
188 pci_write_config16(dev, 0xbe, data16_2);
190 /* Force interrupts to use compat mode. */
191 pci_write_config8(dev, PCI_INTERRUPT_PIN, 0x0);
192 pci_write_config8(dev, PCI_INTERRUPT_LINE, 0xff);
195 struct southbridge_via_vt8237r_config *sb =
196 (struct southbridge_via_vt8237r_config *)dev->chip_info;
201 pci_write_config16(dev, 0x04, 0x0007);
203 enables = pci_read_config8(dev, IDE_CS) & ~0x3;
205 pci_write_config8(dev, IDE_CS, enables);
206 enables = pci_read_config8(dev, IDE_CS);
207 printk(BIOS_DEBUG, "Enables in reg 0x40 read back as 0x%x\n", enables);
209 /* Enable only compatibility mode. */
210 enables = pci_read_config8(dev, IDE_CONF_II);
212 pci_write_config8(dev, IDE_CONF_II, enables);
213 enables = pci_read_config8(dev, IDE_CONF_II);
214 printk(BIOS_DEBUG, "Enables in reg 0x42 read back as 0x%x\n", enables);
216 /* Enable prefetch buffers. */
217 enables = pci_read_config8(dev, IDE_CONF_I);
219 pci_write_config8(dev, IDE_CONF_I, enables);
221 /* Flush FIFOs at half. */
222 enables = pci_read_config8(dev, IDE_CONF_FIFO);
224 enables |= (1 << 2) | (1 << 0);
225 pci_write_config8(dev, IDE_CONF_FIFO, enables);
227 /* PIO read prefetch counter, Bus Master IDE Status Reg. Read Retry. */
228 enables = pci_read_config8(dev, IDE_MISC_I);
230 enables |= (1 << 4) | (1 << 3);
231 pci_write_config8(dev, IDE_MISC_I, enables);
233 /* Use memory read multiple, Memory-Write-and-Invalidate. */
234 enables = pci_read_config8(dev, IDE_MISC_II);
235 enables |= (1 << 2) | (1 << 3);
236 pci_write_config8(dev, IDE_MISC_II, enables);
238 /* Force interrupts to use compat mode. */
239 pci_write_config8(dev, PCI_INTERRUPT_PIN, 0x0);
240 pci_write_config8(dev, PCI_INTERRUPT_LINE, 0xff);
243 cablesel = pci_read_config32(dev, IDE_UDMA);
244 cablesel &= ~((1 << 28) | (1 << 20) | (1 << 12) | (1 << 4));
245 cablesel |= (sb->ide0_80pin_cable << 28) |
246 (sb->ide0_80pin_cable << 20) |
247 (sb->ide1_80pin_cable << 12) | (sb->ide1_80pin_cable << 4);
248 pci_write_config32(dev, IDE_UDMA, cablesel);
252 static struct device_operations ide_ops = {
253 .read_resources = pci_dev_read_resources,
254 .set_resources = pci_dev_set_resources,
255 .enable_resources = pci_dev_enable_resources,
261 static const struct pci_driver via_ide_driver __pci_driver = {
263 .vendor = PCI_VENDOR_ID_VIA,
264 .device = PCI_DEVICE_ID_VIA_VX855_IDE,