blob: f84c430e27f694aef8f6cff7eb34a9e42a333697 [file] [log] [blame]
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001/*
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
Patrick Georgib890a122015-03-26 15:17:45 +010017 * Foundation, Inc.
Stefan Reinaueraeba92a2009-04-17 08:37:18 +000018 */
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
45static void sata_init(struct device *dev)
46{
47 u8 reg8;
48
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000049 printk(BIOS_DEBUG, "Configuring VIA SATA & EIDE Controller\n");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +000050
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)
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000060 printk(BIOS_INFO, "Disabling SATA (Primary Channel)\n");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +000061 /* 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);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000135 printk(BIOS_DEBUG, "Reg 0x42 read back as 0x%x\n", reg8);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000136
137 /* Support Staggered Spin-Up */
138 reg8 = pci_read_config8(dev, 0xb9);
139 if ((reg8 & 0x8) == 0) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000140 printk(BIOS_DEBUG, "start OOB sequence on both drives\n");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000141 reg8 |= 0x30;
142 pci_write_config8(dev, 0xb9, reg8);
143 }
144}
145
146static 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 */
156static const struct pci_driver northbridge_driver __pci_driver = {
157 .ops = &sata_ops,
158 .vendor = PCI_VENDOR_ID_VIA,
159 .device = 0x5324,
160};