blob: 42e3e850e5d0753d5ddc21dbab3e684b907e83df [file] [log] [blame]
Rudolf Marek418bc912007-10-30 03:09:39 +00001/*
Stefan Reinauer7e61e452008-01-18 10:35:56 +00002 * This file is part of the coreboot project.
Rudolf Marek418bc912007-10-30 03:09:39 +00003 *
Rudolf Marekd9f29c82008-09-05 18:20:57 +00004 * Copyright (C) 2007, 2008 Rudolf Marek <r.marek@assembler.cz>
Rudolf Marek418bc912007-10-30 03:09:39 +00005 *
6 * This program is free software; you can redistribute it and/or modify
Uwe Hermannc70e9fc2010-02-15 23:10:19 +00007 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
Rudolf Marek418bc912007-10-30 03:09:39 +00009 *
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.
Rudolf Marek418bc912007-10-30 03:09:39 +000014 */
15
16#include <console/console.h>
17#include <device/device.h>
18#include <device/pci.h>
Rudolf Marek418bc912007-10-30 03:09:39 +000019#include <device/pci_ids.h>
20
21#define SATA_MISC_CTRL 0x45
22
Rudolf Marekd9f29c82008-09-05 18:20:57 +000023static void sata_i_init(struct device *dev)
Rudolf Marek418bc912007-10-30 03:09:39 +000024{
25 u8 reg;
26
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000027 printk(BIOS_DEBUG, "Configuring VIA SATA controller\n");
Rudolf Marek418bc912007-10-30 03:09:39 +000028
29 /* Class IDE Disk */
30 reg = pci_read_config8(dev, SATA_MISC_CTRL);
31 reg &= 0x7f; /* Sub Class Write Protect off */
32 pci_write_config8(dev, SATA_MISC_CTRL, reg);
33
34 /* Change the device class to SATA from RAID. */
35 pci_write_config8(dev, PCI_CLASS_DEVICE, 0x1);
36 reg |= 0x80; /* Sub Class Write Protect on */
37 pci_write_config8(dev, SATA_MISC_CTRL, reg);
Uwe Hermann0a20c412008-10-12 14:40:23 +000038
Rudolf Marekd9f29c82008-09-05 18:20:57 +000039 return;
Rudolf Marek418bc912007-10-30 03:09:39 +000040}
41
Uwe Hermann0a20c412008-10-12 14:40:23 +000042static void sata_ii_init(struct device *dev)
43{
Rudolf Marekd9f29c82008-09-05 18:20:57 +000044 u8 reg;
45
46 sata_i_init(dev);
Uwe Hermann0a20c412008-10-12 14:40:23 +000047
48 /*
49 * Analog black magic, you may or may not need to adjust 0x60-0x6f,
50 * depends on PCB.
51 */
52
53 /*
54 * Analog PHY - gen1
Rudolf Marekd9f29c82008-09-05 18:20:57 +000055 * CDR bandwidth [6:5] = 3
56 * Squelch Window Select [4:3] = 1
57 * CDR Charge Pump [2:0] = 1
58 */
Uwe Hermann0a20c412008-10-12 14:40:23 +000059
Rudolf Marekd9f29c82008-09-05 18:20:57 +000060 pci_write_config8(dev, 0x64, 0x49);
Uwe Hermann0a20c412008-10-12 14:40:23 +000061
62 /* Adjust driver current source value to 9. */
Rudolf Marekd9f29c82008-09-05 18:20:57 +000063 reg = pci_read_config8(dev, 0x65);
64 reg &= 0xf0;
65 reg |= 0x9;
66 pci_write_config8(dev, 0x65, reg);
Uwe Hermann0a20c412008-10-12 14:40:23 +000067
68 /* Set all manual termination 50ohm bits [2:0] and enable [4]. */
Rudolf Marekd9f29c82008-09-05 18:20:57 +000069 reg = pci_read_config8(dev, 0x6a);
70 reg |= 0xf;
71 pci_write_config8(dev, 0x6a, reg);
72
Uwe Hermann0a20c412008-10-12 14:40:23 +000073 /*
74 * Analog PHY - gen2
Rudolf Marekd9f29c82008-09-05 18:20:57 +000075 * CDR bandwidth [5:4] = 2
76 * Pre / De-emphasis Level [7:6] controls bits [3:2], rest in 0x6e
77 * CDR Charge Pump [2:0] = 1
78 */
79
80 reg = pci_read_config8(dev, 0x6f);
81 reg &= 0x08;
82 reg |= 0x61;
83 pci_write_config8(dev, 0x6f, reg);
84
Uwe Hermann0a20c412008-10-12 14:40:23 +000085 /* Check if staggered spinup is supported. */
Rudolf Marekd9f29c82008-09-05 18:20:57 +000086 reg = pci_read_config8(dev, 0x83);
87 if ((reg & 0x8) == 0) {
Uwe Hermann0a20c412008-10-12 14:40:23 +000088 /* Start OOB sequence on both drives. */
Rudolf Marekd9f29c82008-09-05 18:20:57 +000089 reg |= 0x30;
90 pci_write_config8(dev, 0x83, reg);
91 }
92}
93
Rudolf Marek0f1dc4e2011-04-22 20:48:21 +020094
95static void vt8237_set_subsystem(device_t dev, unsigned vendor, unsigned device)
96{
97 pci_write_config16(dev, 0xd4, vendor);
98 pci_write_config16(dev, 0xd6, device);
99}
100
101static struct pci_operations lops_pci = {
102 .set_subsystem = vt8237_set_subsystem,
103};
104
Rudolf Marekd9f29c82008-09-05 18:20:57 +0000105static const struct device_operations sata_i_ops = {
Uwe Hermannf7daa0b2007-11-04 04:04:01 +0000106 .read_resources = pci_dev_read_resources,
107 .set_resources = pci_dev_set_resources,
108 .enable_resources = pci_dev_enable_resources,
Rudolf Marekd9f29c82008-09-05 18:20:57 +0000109 .init = sata_i_init,
Uwe Hermannf7daa0b2007-11-04 04:04:01 +0000110 .enable = 0,
Rudolf Marek0f1dc4e2011-04-22 20:48:21 +0200111 .ops_pci = &lops_pci,
Rudolf Marek418bc912007-10-30 03:09:39 +0000112};
113
Rudolf Marekd9f29c82008-09-05 18:20:57 +0000114static const struct device_operations sata_ii_ops = {
115 .read_resources = pci_dev_read_resources,
116 .set_resources = pci_dev_set_resources,
117 .enable_resources = pci_dev_enable_resources,
118 .init = sata_ii_init,
119 .enable = 0,
Rudolf Marek0f1dc4e2011-04-22 20:48:21 +0200120 .ops_pci = &lops_pci,
Rudolf Marekd9f29c82008-09-05 18:20:57 +0000121};
122
123static const struct pci_driver northbridge_driver_ii __pci_driver = {
124 .ops = &sata_ii_ops,
125 .vendor = PCI_VENDOR_ID_VIA,
126 .device = PCI_DEVICE_ID_VIA_VT8237_SATA,
127};
128
Tobias Diedriche080bca2010-11-11 05:08:33 +0000129static const struct pci_driver northbridge_driver_i_a __pci_driver = {
130 .ops = &sata_i_ops,
131 .vendor = PCI_VENDOR_ID_VIA,
132 .device = PCI_DEVICE_ID_VIA_VT8237A_SATA,
133};
134
Rudolf Marekd9f29c82008-09-05 18:20:57 +0000135static const struct pci_driver northbridge_driver_i __pci_driver = {
136 .ops = &sata_i_ops,
Uwe Hermannf7daa0b2007-11-04 04:04:01 +0000137 .vendor = PCI_VENDOR_ID_VIA,
138 .device = PCI_DEVICE_ID_VIA_VT6420_SATA,
Rudolf Marek418bc912007-10-30 03:09:39 +0000139};