2 * This file is part of the coreboot project.
4 * Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me@gmail.com>
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, either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
17 #include <console/console.h>
18 #include <device/pci.h>
19 #include <device/pci_ids.h>
27 * The only issue is the SATA EPHY configuration. We do not know if it is board
28 * specific or not. Otherwise, the SATA controller works without issues.
31 static void vx900_print_sata_errors(u32 flags
)
34 printk(BIOS_DEBUG
, "\tPhyRdy %s\n",
35 (flags
& (1 << 16)) ? "changed" : "not changed");
36 printk(BIOS_DEBUG
, "\tCOMWAKE %s\n",
37 (flags
& (1 << 16)) ? "detected" : "not detected");
38 printk(BIOS_DEBUG
, "\tExchange as determined by COMINIT %s\n",
39 (flags
& (1 << 26)) ? "occurred" : "not occurred");
40 printk(BIOS_DEBUG
, "\tPort selector presence %s\n",
41 (flags
& (1 << 27)) ? "detected" : "not detected");
44 printk(BIOS_DEBUG
, "\tRecovered data integrity ERROR\n");
46 printk(BIOS_DEBUG
, "\tRecovered data communication ERROR\n");
48 printk(BIOS_DEBUG
, "\tNon-recovered Transient Data Integrity ERROR\n");
50 printk(BIOS_DEBUG
, "\tNon-recovered Persistent Communication or"
51 "\tData Integrity ERROR\n");
52 if (flags
& (1 << 10))
53 printk(BIOS_DEBUG
, "\tProtocol ERROR\n");
54 if (flags
& (1 << 11))
55 printk(BIOS_DEBUG
, "\tInternal ERROR\n");
56 if (flags
& (1 << 17))
57 printk(BIOS_DEBUG
, "\tPHY Internal ERROR\n");
58 if (flags
& (1 << 19))
59 printk(BIOS_DEBUG
, "\t10B to 8B Decode ERROR\n");
60 if (flags
& (1 << 20))
61 printk(BIOS_DEBUG
, "\tDisparity ERROR\n");
62 if (flags
& (1 << 21))
63 printk(BIOS_DEBUG
, "\tCRC ERROR\n");
64 if (flags
& (1 << 22))
65 printk(BIOS_DEBUG
, "\tHandshake ERROR\n");
66 if (flags
& (1 << 23))
67 printk(BIOS_DEBUG
, "\tLink Sequence ERROR\n");
68 if (flags
& (1 << 24))
69 printk(BIOS_DEBUG
, "\tTransport State Transition ERROR\n");
70 if (flags
& (1 << 25))
71 printk(BIOS_DEBUG
, "\tUNRECOGNIZED FIS type\n");
74 static void vx900_dbg_sata_errors(struct device
*dev
)
77 if (pci_read_config8(dev
, 0xa0) & (1 << 0)) {
78 printk(BIOS_DEBUG
, "Device detected in SATA port 0.\n");
79 u32 flags
= pci_read_config32(dev
, 0xa8);
80 vx900_print_sata_errors(flags
);
83 if (pci_read_config8(dev
, 0xa1) & (1 << 0)) {
84 printk(BIOS_DEBUG
, "Device detected in SATA port 1.\n");
85 u32 flags
= pci_read_config32(dev
, 0xac);
86 vx900_print_sata_errors(flags
);
90 typedef u8 sata_phy_config
[64];
92 static sata_phy_config reference_ephy
= {
93 0x80, 0xb8, 0xf0, 0xfe, 0x40, 0x7e, 0xf6, 0xdd,
94 0x1a, 0x22, 0xa0, 0x10, 0x02, 0xa9, 0x7c, 0x7e,
95 0x00, 0x00, 0x00, 0x00, 0x40, 0x30, 0x84, 0x8c,
96 0x75, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
97 0x20, 0x40, 0xd0, 0x41, 0x40, 0x00, 0x00, 0x08,
98 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
99 0x20, 0x40, 0x50, 0x41, 0x40, 0x00, 0x00, 0x00,
100 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
103 static u32
sata_phy_read32(struct device
*dev
, u8 index
)
105 /* The SATA PHY control registers are accessed by a funny index/value
106 * scheme. Each byte (0,1,2,3) has its own 4-bit index */
107 index
= (index
>> 2) & 0xf;
108 u16 i16
= index
| (index
<< 4) | (index
<< 8) | (index
<< 12);
110 pci_write_config16(dev
, 0x68, i16
);
112 return pci_read_config32(dev
, 0x64);
115 static void sata_phy_write32(struct device
*dev
, u8 index
, u32 val
)
117 /* The SATA PHY control registers are accessed by a funny index/value
118 * scheme. Each byte (0,1,2,3) has its own 4-bit index */
119 index
= (index
>> 2) & 0xf;
120 u16 i16
= index
| (index
<< 4) | (index
<< 8) | (index
<< 12);
122 pci_write_config16(dev
, 0x68, i16
);
124 pci_write_config32(dev
, 0x64, val
);
127 static void vx900_sata_read_phy_config(struct device
*dev
, sata_phy_config cfg
)
130 u32
*data
= (u32
*) cfg
;
131 for (i
= 0; i
< (sizeof(sata_phy_config
)) >> 2; i
++) {
132 data
[i
] = sata_phy_read32(dev
, i
<< 2);
136 static void vx900_sata_write_phy_config(struct device
*dev
, sata_phy_config cfg
)
139 u32
*data
= (u32
*) cfg
;
140 for (i
= 0; i
< (sizeof(sata_phy_config
)) >> 2; i
++) {
141 sata_phy_write32(dev
, i
<< 2, data
[i
]);
145 static void vx900_sata_dump_phy_config(sata_phy_config cfg
)
147 printk(BIOS_DEBUG
, "SATA PHY config:\n");
149 for (i
= 0; i
< sizeof(sata_phy_config
); i
++) {
152 printk(BIOS_DEBUG
, "%02x:", i
);
155 printk(BIOS_DEBUG
, " |");
156 printk(BIOS_DEBUG
, " %02x", val
);
157 if ((i
& 0x0f) == 0x0f) {
158 printk(BIOS_DEBUG
, "\n");
164 * \brief VX900: Place the onboard SATA controller in Native IDE mode
166 * AHCI mode requires a sub-class of 0x06, and Interface of 0x0
167 * SATA mode requires a sub-class of 0x06, and Interface of 0x00
168 * Unfortunately, setting the class to SATA, will prevent us from modyfing the
169 * interface register to an AHCI/SATA compliant value. Thus, payloads or OS may
170 * not properly identify this as a SATA controller.
171 * We could set the class code to 0x04, which would cause the interface register
172 * to become 0x00, which represents a RAID controller. Unfortunately, when we do
173 * this, SeaBIOS will skip this as a storage device, and we will not be able to
175 * Our only option is to operate in IDE mode. We choose native IDE so that we
176 * can freely assign an IRQ, and are not forced to use IRQ14
178 static void vx900_native_ide_mode(struct device
*dev
)
180 /* Disable subclass write protect */
181 pci_mod_config8(dev
, 0x45, 1 << 7, 0);
182 /* Change the device class to IDE */
183 pci_write_config16(dev
, PCI_CLASS_DEVICE
, PCI_CLASS_STORAGE_IDE
);
184 /* Re-enable subclass write protect */
185 pci_mod_config8(dev
, 0x45, 0, 1 << 7);
186 /* Put it in native IDE mode */
187 pci_write_config8(dev
, PCI_CLASS_PROG
, 0x8f);
190 static void vx900_sata_init(struct device
*dev
)
192 /* Enable SATA primary channel IO access */
193 pci_mod_config8(dev
, 0x40, 0, 1 << 1);
194 /* Just SATA, so it makes sense to be in native SATA mode */
195 vx900_native_ide_mode(dev
);
197 /* TP Layer Idle at least 20us before the Following Command */
198 pci_mod_config8(dev
, 0x53, 0, 1 << 7);
199 /* Resend COMRESET When Recovering SATA Gen2 Device Error */
200 pci_mod_config8(dev
, 0x62, 1 << 1, 1 << 7);
202 /* Fix "PMP Device Can't Detect HDD Normally" (VIA Porting Guide)
203 * SATA device detection will not work unless we clear these bits.
204 * Without doing this, SeaBIOS (and potentially other payloads) will
205 * timeout when detecting SATA devices */
206 pci_mod_config8(dev
, 0x89, (1 << 3) | (1 << 6), 0);
208 /* 12.7 Two Software Resets May Affect the System
209 * When the software does the second reset before the first reset
210 * finishes, it may cause the system hang. It would do one software
211 * reset and check the BSY bit of one port only, and the BSY bit of
212 * other port would be 1, then it does another software reset
213 * immediately and causes the system hang.
214 * This is because the first software reset doesn't finish, and the
215 * state machine of the host controller conflicts, it can't finish the
216 * second one anymore. The BSY bit of slave port would be always 1 after
217 * the second software reset issues. BIOS should set the following
218 * bit to avoid this issue. */
219 pci_mod_config8(dev
, 0x80, 0, 1 << 6);
221 /* We need to set the EPHY values before doing anything with the link */
222 sata_phy_config ephy
;
223 vx900_sata_read_phy_config(dev
, ephy
);
225 vx900_sata_dump_phy_config(ephy
);
226 vx900_sata_write_phy_config(dev
, reference_ephy
);
228 /* Enable TX and RX driving resistance */
230 ephy
[1] &= ~(0x1f << 3);
231 ephy
[1] |= (1 << 7) | (8 << 3);
233 ephy
[2] &= ~(0x1f << 3);
234 ephy
[2] |= (1 << 7) | (8 << 3);
235 vx900_sata_write_phy_config(dev
, ephy
);
238 vx900_sata_read_phy_config(dev
, ephy
);
239 vx900_sata_dump_phy_config(ephy
);
241 /* Clear error flags */
242 pci_write_config32(dev
, 0xa8, 0xffffffff);
243 pci_write_config32(dev
, 0xac, 0xffffffff);
245 /* Start OOB link negotiation sequence */
246 pci_mod_config8(dev
, 0xb9, 0, 3 << 4);
248 /* FIXME: From now on, we are just doing DEBUG stuff
249 * Wait until PHY communication is enabled */
251 while (!(pci_read_config8(dev
, 0xa0) & (1 << 1)))
253 printk(BIOS_SPEW
, "SATA wait loops: %u\n", wloops
);
255 vx900_dbg_sata_errors(dev
);
258 static void vx900_sata_read_resources(struct device
*dev
)
260 pci_dev_read_resources(dev
);
263 static struct device_operations vga_operations
= {
264 .read_resources
= vx900_sata_read_resources
,
265 .set_resources
= pci_dev_set_resources
,
266 .enable_resources
= pci_dev_enable_resources
,
267 .init
= vx900_sata_init
,
270 static const struct pci_driver chrome9hd_driver __pci_driver
= {
271 .ops
= &vga_operations
,
272 .vendor
= PCI_VENDOR_ID_VIA
,
273 .device
= PCI_DEVICE_ID_VIA_VX900_SATA
,