Revision: linuxbios@linuxbios.org--devel/freebios--devel--2.0--patch-30
[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 //      write back
99         dword |= (1<<12);
100         dword |= (1<<14);
101
102 #if 1
103 //      ADMA
104         dword |= (1<<16);
105         dword |= (1<<17);
106 #endif
107
108 #if 1   
109 //DO NOT relay OK and PAGE_FRNDLY_DTXFR_CNT.
110         dword &= ~(0x1f<<24);
111         dword |= (0x15<<24); 
112 #endif
113         pci_write_config32(dev, 0x50, dword);
114
115 #if 1
116 //SLUMBER_DURING_D3.
117         dword = pci_read_config32(dev, 0x7c);
118         dword &=  ~(1<<4);
119         pci_write_config32(dev, 0x7c, dword);
120
121         dword = pci_read_config32(dev, 0xd0);
122         dword &=  ~(0xff<<24);
123         dword |= (0x68<<24);
124         pci_write_config32(dev, 0xd0, dword);
125
126         dword = pci_read_config32(dev, 0xe0);
127         dword &=  ~(0xff<<24);
128         dword |= (0x68<<24);
129         pci_write_config32(dev, 0xe0, dword);
130 #endif
131
132         dword = pci_read_config32(dev, 0xf8);
133         dword |= 2; 
134         pci_write_config32(dev, 0xf8, dword);
135
136 #if 0
137         dword = pci_read_config32(dev, 0xac);
138         dword &= ~((1<<13)|(1<<14));
139         dword |= (1<<13)|(0<<14);
140         pci_write_config32(dev, 0xac, dword);
141
142         sata_com_reset(dev, 1); // for discover some s-atapi device
143 #endif
144
145 }
146
147 static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
148 {
149         pci_write_config32(dev, 0x40,
150                 ((device & 0xffff) << 16) | (vendor & 0xffff));
151 }
152 static struct pci_operations lops_pci = {
153         .set_subsystem = lpci_set_subsystem,
154 };
155
156 static struct device_operations sata_ops  = {
157         .read_resources   = pci_dev_read_resources,
158         .set_resources    = pci_dev_set_resources,
159         .enable_resources = pci_dev_enable_resources,
160 //      .enable           = ck804_enable,
161         .init             = sata_init,
162         .scan_bus         = 0,
163         .ops_pci          = &lops_pci,
164 };
165
166 static struct pci_driver sata0_driver __pci_driver = {
167         .ops    = &sata_ops,
168         .vendor = PCI_VENDOR_ID_NVIDIA,
169         .device = PCI_DEVICE_ID_NVIDIA_CK804_SATA0,
170 };
171
172 static struct pci_driver sata1_driver __pci_driver = {
173         .ops    = &sata_ops,
174         .vendor = PCI_VENDOR_ID_NVIDIA,
175         .device = PCI_DEVICE_ID_NVIDIA_CK804_SATA1,
176 };