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