Ever wondered where those "setting incorrect section attributes for
[coreboot.git] / src / southbridge / via / vt8231 / vt8231_ide.c
1 #include <console/console.h>
2 #include <device/device.h>
3 #include <device/pci.h>
4 #include <device/pci_ops.h>
5 #include <device/pci_ids.h>
6 #include "vt8231.h"
7 #include "chip.h"
8
9 static void ide_init(struct device *dev)
10 {
11         struct southbridge_via_vt8231_config *conf = (struct southbridge_via_vt8231_config *)dev->chip_info;
12         unsigned char enables;
13
14         if (!conf->enable_native_ide) {
15                 // Run the IDE controller in 'compatiblity mode - i.e. don't use PCI
16                 // interrupts.  Using PCI ints confuses linux for some reason.
17                 /* Setting reg 0x42 here does not work. It is set in mainboard/auto.c
18                 * It probably can only be changed while the IDE is disabled
19                 * or it is possibly a timing issue. Ben Hewson 29 Apr 2007.
20                 */
21
22                 /*              
23                 printk_info("%s: enabling compatibility IDE addresses\n", __FUNCTION__);
24                 enables = pci_read_config8(dev, 0x42);
25                 printk_debug("enables in reg 0x42 0x%x\n", enables);
26                 enables &= ~0xc0;               // compatability mode
27                 pci_write_config8(dev, 0x42, enables);
28                 enables = pci_read_config8(dev, 0x42);
29                 printk_debug("enables in reg 0x42 read back as 0x%x\n", enables);
30                 */
31         }
32         
33         enables = pci_read_config8(dev, 0x40);
34         printk_debug("enables in reg 0x40 0x%x\n", enables);
35         enables |= 3;
36         pci_write_config8(dev, 0x40, enables);
37         enables = pci_read_config8(dev, 0x40);
38         printk_debug("enables in reg 0x40 read back as 0x%x\n", enables);
39         
40         // Enable prefetch buffers
41         enables = pci_read_config8(dev, 0x41);
42         enables |= 0xf0;
43         pci_write_config8(dev, 0x41, enables);
44         
45         // Lower thresholds (cause award does it)
46         enables = pci_read_config8(dev, 0x43);
47         enables &= ~0x0f;
48         enables |=  0x05;
49         pci_write_config8(dev, 0x43, enables);
50         
51         // PIO read prefetch counter (cause award does it)
52         pci_write_config8(dev, 0x44, 0x18);
53         
54         // Use memory read multiple
55         pci_write_config8(dev, 0x45, 0x1c);
56         
57         // address decoding. 
58         // we want "flexible", i.e. 1f0-1f7 etc. or native PCI
59         // kevinh@ispiri.com - the standard linux drivers seem ass slow when 
60         // used in native mode - I've changed back to classic
61         enables = pci_read_config8(dev, 0x9);
62         printk_debug("enables in reg 0x9 0x%x\n", enables);
63         // by the book, set the low-order nibble to 0xa. 
64         if (conf->enable_native_ide) {
65                 enables &= ~0xf;
66                 // cf/cg silicon needs an 'f' here. 
67                 enables |= 0xf;
68         } else {
69                 enables &= ~0x5;
70         }
71         
72         pci_write_config8(dev, 0x9, enables);
73         enables = pci_read_config8(dev, 0x9);
74         printk_debug("enables in reg 0x9 read back as 0x%x\n", enables);
75         
76         // standard bios sets master bit. 
77         enables = pci_read_config8(dev, 0x4);
78         printk_debug("command in reg 0x4 0x%x\n", enables);
79         enables |= 7;
80         
81         // No need for stepping - kevinh@ispiri.com
82         enables &= ~0x80;
83         
84         pci_write_config8(dev, 0x4, enables);
85         enables = pci_read_config8(dev, 0x4);
86         printk_debug("command in reg 0x4 reads back as 0x%x\n", enables);
87         
88         if (!conf->enable_native_ide) {
89                 // Use compatability mode - per award bios
90                 pci_write_config32(dev, 0x10, 0x0);
91                 pci_write_config32(dev, 0x14, 0x0);
92                 pci_write_config32(dev, 0x18, 0x0);
93                 pci_write_config32(dev, 0x1c, 0x0);
94                 
95                 // Force interrupts to use compat mode - just like Award bios
96                 pci_write_config8(dev, 0x3d, 00);
97                 pci_write_config8(dev, 0x3c, 0xff);
98         }       
99 }
100
101 static struct device_operations ide_ops = {
102         .read_resources   = pci_dev_read_resources,
103         .set_resources    = pci_dev_set_resources,
104         .enable_resources = pci_dev_enable_resources,
105         .init             = ide_init,
106         .enable           = 0,
107         .ops_pci          = 0,
108 };
109
110 static const struct pci_driver northbridge_driver __pci_driver = {
111         .ops    = &ide_ops,
112         .vendor = PCI_VENDOR_ID_VIA,
113         .device = PCI_DEVICE_ID_VIA_82C586_1,
114 };