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