893126606e37ae8c8116588a421f0722a0b24c90
[coreboot.git] / src / northbridge / via / cx700 / cx700_sata.c
1 /*
2  * This file is part of the coreboot project.
3  *
4  * Copyright (C) 2007-2009 coresystems GmbH
5  *
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.
9  *
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.
14  *
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
18  */
19
20 #include <console/console.h>
21 #include <device/device.h>
22 #include <device/pci.h>
23 #include <device/pci_ids.h>
24
25 /* IDE specific bits */
26 #define IDE_MODE_REG            0x09
27 #define IDE0_NATIVE_MODE        (1 << 0)
28 #define IDE1_NATIVE_MODE        (1 << 2)
29
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
35
36 #define BUS_MASTER_ADDR         0xfc00
37
38 #define CHANNEL_ENABLE_REG      0x40
39 #define ENABLE_IDE0             (1 << 0)
40 #define ENABLE_IDE1             (1 << 1)
41
42 /* TODO: better user configuration */
43 #define DISABLE_SATA 0
44
45 static void sata_init(struct device *dev)
46 {
47         u8 reg8;
48
49         printk_debug("Configuring VIA SATA & EIDE Controller\n");
50
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);
58
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);
63 #else
64         pci_write_config8(dev, 0x40, 0x43);
65 #endif
66
67         reg8 = pci_read_config8(dev, 0x6a);
68         reg8 |= 0x8;            /* Mode Select set to Manual Mode */
69         reg8 &= ~7;
70         reg8 |= 0x2;            /* Manual setting to 50 ohm */
71
72         pci_write_config8(dev, 0x6a, reg8);
73
74         reg8 = pci_read_config8(dev, 0x6b);
75         reg8 &= ~7;
76         reg8 |= 0x01;           /* Autocomp of Termination */
77         pci_write_config8(dev, 0x6b, reg8);
78
79         /* Enable EIDE (secondary channel) even if SATA disabled */
80         reg8 = pci_read_config8(dev, 0xc0);
81         reg8 |= 0x1;
82         pci_write_config8(dev, 0xc0, reg8);
83
84         // Enable bus mastering, memory space acces, io space access
85         pci_write_config16(dev, 0x04, 0x0007);
86
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);
93
94         /* SATA/EIDE Bus Master mode base address */
95         pci_write_config32(dev, 0x20, BUS_MASTER_ADDR | 1);
96
97         /* Enable read/write prefetch buffers */
98         reg8 = pci_read_config8(dev, 0xc1);
99         reg8 |= 0x30;
100         pci_write_config8(dev, 0xc1, reg8);
101
102         /* Set FIFO thresholds like */
103         pci_write_config8(dev, 0xc3, 0x1);      /* FIFO flushed when 1/2 full */
104
105         /* EIDE Sector Size */
106         pci_write_config16(dev, 0xe8, 0x200);
107
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);
112
113         /* EIDE Configuration */
114         reg8 = pci_read_config8(dev, 0xc4);
115         reg8 |= 0x10;
116         pci_write_config8(dev, 0xc4, reg8);
117
118         pci_write_config8(dev, 0xc5, 0xc);
119
120         /* Interrupt Line */
121         reg8 = pci_read_config8(dev, 0x45);
122         reg8 &= ~(1 << 4);      /* Interrupt Line Write Protect off */
123         pci_write_config8(dev, 0x45, reg8);
124
125         pci_write_config8(dev, 0x3c, 0x0e);     /* Interrupt */
126
127         /* Set the drive timing control */
128         pci_write_config16(dev, 0x48, 0x5d5d);
129
130         /* Enable only compatibility mode. */
131         reg8 = pci_read_config8(dev, 0x42);
132         reg8 &= ~0xa0;
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);
136
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");
141                 reg8 |= 0x30;
142                 pci_write_config8(dev, 0xb9, reg8);
143         }
144 }
145
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,
150         .init             = sata_init,
151         .enable           = 0,
152         .ops_pci          = 0,
153 };
154
155 /* When the SATA controller is in IDE mode, the Device ID is 0x5324 */
156 static const struct pci_driver northbridge_driver __pci_driver = {
157         .ops = &sata_ops,
158         .vendor = PCI_VENDOR_ID_VIA,
159         .device = 0x5324,
160 };