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