CK804: Cosmetic fixes, switch to u8 et al.
[coreboot.git] / src / southbridge / nvidia / ck804 / sata.c
1 /*
2  * This file is part of the coreboot project.
3  *
4  * Copyright (C) 2004 Tyan Computer
5  * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; version 2 of the License.
10  *
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.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
19  */
20
21 #include <console/console.h>
22 #include <device/device.h>
23 #include <delay.h>
24 #include <device/pci.h>
25 #include <device/pci_ids.h>
26 #include <device/pci_ops.h>
27 #include "ck804.h"
28
29 #ifndef CK804_SATA_RESET_FOR_ATAPI
30 #define CK804_SATA_RESET_FOR_ATAPI 0
31 #endif
32
33 #if CK804_SATA_RESET_FOR_ATAPI
34 static void sata_com_reset(struct device *dev, unsigned reset)
35 // reset = 1 : reset
36 // reset = 0 : clear
37 {
38         u32 *base;
39         u32 dword;
40         int loop;
41
42         base = (u32 *) pci_read_config32(dev, 0x24);
43
44         printk(BIOS_DEBUG, "base = %08lx\n", base);
45
46         if (reset) {
47                 *(base + 4) = 0xffffffff;
48                 *(base + 0x44) = 0xffffffff;
49         }
50
51         dword = *(base + 8);
52         dword &= ~(0xf);
53         dword |= reset;
54
55         *(base + 8) = dword;
56         *(base + 0x48) = dword;
57
58 #if 0
59         udelay(1000);
60         dword &= ~(0xf);
61         *(base + 8) = dword;
62         *(base + 0x48) = dword;
63 #endif
64
65         if (reset)
66                 return;
67
68         dword = *(base + 0);
69         printk(BIOS_DEBUG, "*(base+0)=%08x\n", dword);
70         if (dword == 0x113) {
71                 loop = 200000;  // 2
72                 do {
73                         dword = *(base + 4);
74                         if ((dword & 0x10000) != 0)
75                                 break;
76                         udelay(10);
77                 } while (--loop > 0);
78                 printk(BIOS_DEBUG, "loop=%d, *(base+4)=%08x\n", loop, dword);
79         }
80
81         dword = *(base + 0x40);
82         printk(BIOS_DEBUG, "*(base+0x40)=%08x\n", dword);
83         if (dword == 0x113) {
84                 loop = 200000;  //2
85                 do {
86                         dword = *(base + 0x44);
87                         if ((dword & 0x10000) != 0)
88                                 break;
89                         udelay(10);
90                 } while (--loop > 0);
91                 printk(BIOS_DEBUG, "loop=%d, *(base+0x44)=%08x\n", loop, dword);
92         }
93 }
94 #endif
95
96 static void sata_init(struct device *dev)
97 {
98         u32 dword;
99         struct southbridge_nvidia_ck804_config *conf;
100
101         conf = dev->chip_info;
102
103         dword = pci_read_config32(dev, 0x50);
104         /* Ensure prefetch is disabled. */
105         dword &= ~((1 << 15) | (1 << 13));
106         if (conf->sata1_enable) {
107                 /* Enable secondary SATA interface. */
108                 dword |= (1 << 0);
109                 printk(BIOS_DEBUG, "SATA S \t");
110         }
111         if (conf->sata0_enable) {
112                 /* Enable primary SATA interface. */
113                 dword |= (1 << 1);
114                 printk(BIOS_DEBUG, "SATA P \n");
115         }
116 #if 0
117         /* Write back */
118         dword |= (1 << 12);
119         dword |= (1 << 14);
120 #endif
121
122 #if 0
123         /* ADMA */
124         dword |= (1 << 16);
125         dword |= (1 << 17);
126 #endif
127
128 #if 1
129         /* DO NOT relay OK and PAGE_FRNDLY_DTXFR_CNT. */
130         dword &= ~(0x1f << 24);
131         dword |= (0x15 << 24);
132 #endif
133         pci_write_config32(dev, 0x50, dword);
134
135 #if 0
136         /* SLUMBER_DURING_D3 */
137         dword = pci_read_config32(dev, 0x7c);
138         dword &= ~(1 << 4);
139         pci_write_config32(dev, 0x7c, dword);
140
141         dword = pci_read_config32(dev, 0xd0);
142         dword &= ~(0xff << 24);
143         dword |= (0x68 << 24);
144         pci_write_config32(dev, 0xd0, dword);
145
146         dword = pci_read_config32(dev, 0xe0);
147         dword &= ~(0xff << 24);
148         dword |= (0x68 << 24);
149         pci_write_config32(dev, 0xe0, dword);
150 #endif
151
152         dword = pci_read_config32(dev, 0xf8);
153         dword |= 2;
154         pci_write_config32(dev, 0xf8, dword);
155
156 #if CK804_SATA_RESET_FOR_ATAPI
157         dword = pci_read_config32(dev, 0xac);
158         dword &= ~((1 << 13) | (1 << 14));
159         dword |= (1 << 13) | (0 << 14);
160         pci_write_config32(dev, 0xac, dword);
161
162         sata_com_reset(dev, 1); /* For discover some s-atapi device. */
163 #endif
164 }
165
166 static struct device_operations sata_ops = {
167         .read_resources   = pci_dev_read_resources,
168         .set_resources    = pci_dev_set_resources,
169         .enable_resources = pci_dev_enable_resources,
170         // .enable        = ck804_enable,
171         .init             = sata_init,
172         .scan_bus         = 0,
173         .ops_pci          = &ck804_pci_ops,
174 };
175
176 static const struct pci_driver sata0_driver __pci_driver = {
177         .ops    = &sata_ops,
178         .vendor = PCI_VENDOR_ID_NVIDIA,
179         .device = PCI_DEVICE_ID_NVIDIA_CK804_SATA0,
180 };
181
182 static const struct pci_driver sata1_driver __pci_driver = {
183         .ops    = &sata_ops,
184         .vendor = PCI_VENDOR_ID_NVIDIA,
185         .device = PCI_DEVICE_ID_NVIDIA_CK804_SATA1,
186 };