blob: 3283f6f5265e0a77663cc9eb41a77828bf4bf2d4 [file] [log] [blame]
Zheng Bao910f4ca2011-03-28 04:38:14 +00001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2010 Advanced Micro Devices, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
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.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
Paul Menzela46a7122013-02-23 18:37:27 +010017 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Zheng Bao910f4ca2011-03-28 04:38:14 +000018 */
19
20/*
21Scope (_SB) {
22 Device(PCI0) {
23 Device(IDEC) {
24 Name(_ADR, 0x00140001)
25 #include "ide.asl"
26 }
27 }
28}
29*/
30
31/* Some timing tables */
32Name(UDTT, Package(){ /* Udma timing table */
33 120, 90, 60, 45, 30, 20, 15, 0 /* UDMA modes 0 -> 6 */
34})
35
36Name(MDTT, Package(){ /* MWDma timing table */
37 480, 150, 120, 0 /* Legacy DMA modes 0 -> 2 */
38})
39
40Name(POTT, Package(){ /* Pio timing table */
41 600, 390, 270, 180, 120, 0 /* PIO modes 0 -> 4 */
42})
43
44/* Some timing register value tables */
45Name(MDRT, Package(){ /* MWDma timing register table */
46 0x77, 0x21, 0x20, 0xFF /* Legacy DMA modes 0 -> 2 */
47})
48
49Name(PORT, Package(){
50 0x99, 0x47, 0x34, 0x22, 0x20, 0x99 /* PIO modes 0 -> 4 */
51})
52
53OperationRegion(ICRG, PCI_Config, 0x40, 0x20) /* ide control registers */
54 Field(ICRG, AnyAcc, NoLock, Preserve)
55{
56 PPTS, 8, /* Primary PIO Slave Timing */
57 PPTM, 8, /* Primary PIO Master Timing */
58 OFFSET(0x04), PMTS, 8, /* Primary MWDMA Slave Timing */
59 PMTM, 8, /* Primary MWDMA Master Timing */
60 OFFSET(0x08), PPCR, 8, /* Primary PIO Control */
61 OFFSET(0x0A), PPMM, 4, /* Primary PIO master Mode */
62 PPSM, 4, /* Primary PIO slave Mode */
63 OFFSET(0x14), PDCR, 2, /* Primary UDMA Control */
64 OFFSET(0x16), PDMM, 4, /* Primary UltraDMA Mode */
65 PDSM, 4, /* Primary UltraDMA Mode */
66}
67
68Method(GTTM, 1) /* get total time*/
69{
70 Store(And(Arg0, 0x0F), Local0) /* Recovery Width */
71 Increment(Local0)
72 Store(ShiftRight(Arg0, 4), Local1) /* Command Width */
73 Increment(Local1)
74 Return(Multiply(30, Add(Local0, Local1)))
75}
76
77Device(PRID)
78{
79 Name (_ADR, Zero)
80 Method(_GTM, 0)
81 {
82 NAME(OTBF, Buffer(20) { /* out buffer */
83 0xFF, 0xFF, 0xFF, 0xFF,
84 0xFF, 0xFF, 0xFF, 0xFF,
85 0xFF, 0xFF, 0xFF, 0xFF,
86 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00
87 })
88
89 CreateDwordField(OTBF, 0, PSD0) /* PIO spd0 */
90 CreateDwordField(OTBF, 4, DSD0) /* DMA spd0 */
91 CreateDwordField(OTBF, 8, PSD1) /* PIO spd1 */
92 CreateDwordField(OTBF, 12, DSD1) /* DMA spd1 */
93 CreateDwordField(OTBF, 16, BFFG) /* buffer flags */
94
95 /* Just return if the channel is disabled */
96 If(And(PPCR, 0x01)) { /* primary PIO control */
97 Return(OTBF)
98 }
99
100 /* Always tell them independent timing available and IOChannelReady used on both drives */
101 Or(BFFG, 0x1A, BFFG)
102
103 Store(GTTM(PPTM), PSD0) /* save total time of primary PIO master timming to PIO spd0 */
104 Store(GTTM(PPTS), PSD1) /* save total time of primary PIO slave Timing to PIO spd1 */
105
106 If(And(PDCR, 0x01)) { /* It's under UDMA mode */
107 Or(BFFG, 0x01, BFFG)
108 Store(DerefOf(Index(UDTT, PDMM)), DSD0)
109 }
110 Else {
111 Store(GTTM(PMTM), DSD0) /* Primary MWDMA Master Timing, DmaSpd0 */
112 }
113
114 If(And(PDCR, 0x02)) { /* It's under UDMA mode */
115 Or(BFFG, 0x04, BFFG)
116 Store(DerefOf(Index(UDTT, PDSM)), DSD1)
117 }
118 Else {
119 Store(GTTM(PMTS), DSD1) /* Primary MWDMA Slave Timing, DmaSpd0 */
120 }
121
122 Return(OTBF) /* out buffer */
123 } /* End Method(_GTM) */
124
125 Method(_STM, 3, NotSerialized)
126 {
127 NAME(INBF, Buffer(20) { /* in buffer */
128 0xFF, 0xFF, 0xFF, 0xFF,
129 0xFF, 0xFF, 0xFF, 0xFF,
130 0xFF, 0xFF, 0xFF, 0xFF,
131 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00
132 })
133
134 CreateDwordField(INBF, 0, PSD0) /* PIO spd0 */
135 CreateDwordField(INBF, 4, DSD0) /* PIO spd0 */
136 CreateDwordField(INBF, 8, PSD1) /* PIO spd1 */
137 CreateDwordField(INBF, 12, DSD1) /* DMA spd1 */
138 CreateDwordField(INBF, 16, BFFG) /*buffer flag */
139
140 Store(Match(POTT, MLE, PSD0, MTR, 0, 0), Local0)
141 Divide(Local0, 5, PPMM,) /* Primary PIO master Mode */
142 Store(Match(POTT, MLE, PSD1, MTR, 0, 0), Local1)
143 Divide(Local1, 5, PPSM,) /* Primary PIO slave Mode */
144
145 Store(DerefOf(Index(PORT, Local0)), PPTM) /* Primary PIO Master Timing */
146 Store(DerefOf(Index(PORT, Local1)), PPTS) /* Primary PIO Slave Timing */
147
148 If(And(BFFG, 0x01)) { /* Drive 0 is under UDMA mode */
149 Store(Match(UDTT, MLE, DSD0, MTR, 0, 0), Local0)
150 Divide(Local0, 7, PDMM,)
151 Or(PDCR, 0x01, PDCR)
152 }
153 Else {
154 If(LNotEqual(DSD0, 0xFFFFFFFF)) {
155 Store(Match(MDTT, MLE, DSD0, MTR, 0, 0), Local0)
156 Store(DerefOf(Index(MDRT, Local0)), PMTM)
157 }
158 }
159
160 If(And(BFFG, 0x04)) { /* Drive 1 is under UDMA mode */
161 Store(Match(UDTT, MLE, DSD1, MTR, 0, 0), Local0)
162 Divide(Local0, 7, PDSM,)
163 Or(PDCR, 0x02, PDCR)
164 }
165 Else {
166 If(LNotEqual(DSD1, 0xFFFFFFFF)) {
167 Store(Match(MDTT, MLE, DSD1, MTR, 0, 0), Local0)
168 Store(DerefOf(Index(MDRT, Local0)), PMTS)
169 }
170 }
171 /* Return(INBF) */
172 } /*End Method(_STM) */
173 Device(MST)
174 {
175 Name(_ADR, 0)
176 Method(_GTF) {
177 Name(CMBF, Buffer(21) {
178 0x03, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF,
179 0x03, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF,
180 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF5
181 })
182 CreateByteField(CMBF, 1, POMD)
183 CreateByteField(CMBF, 8, DMMD)
184 CreateByteField(CMBF, 5, CMDA)
185 CreateByteField(CMBF, 12, CMDB)
186 CreateByteField(CMBF, 19, CMDC)
187
188 Store(0xA0, CMDA)
189 Store(0xA0, CMDB)
190 Store(0xA0, CMDC)
191
192 Or(PPMM, 0x08, POMD)
193
194 If(And(PDCR, 0x01)) {
195 Or(PDMM, 0x40, DMMD)
196 }
197 Else {
198 Store(Match
199 (MDTT, MLE, GTTM(PMTM),
200 MTR, 0, 0), Local0)
201 If(LLess(Local0, 3)) {
202 Or(0x20, Local0, DMMD)
203 }
204 }
205 Return(CMBF)
206 }
207 } /* End Device(MST) */
208
209 Device(SLAV)
210 {
211 Name(_ADR, 1)
212 Method(_GTF) {
213 Name(CMBF, Buffer(21) {
214 0x03, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF,
215 0x03, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF,
216 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF5
217 })
218 CreateByteField(CMBF, 1, POMD)
219 CreateByteField(CMBF, 8, DMMD)
220 CreateByteField(CMBF, 5, CMDA)
221 CreateByteField(CMBF, 12, CMDB)
222 CreateByteField(CMBF, 19, CMDC)
223
224 Store(0xB0, CMDA)
225 Store(0xB0, CMDB)
226 Store(0xB0, CMDC)
227
228 Or(PPSM, 0x08, POMD)
229
230 If(And(PDCR, 0x02)) {
231 Or(PDSM, 0x40, DMMD)
232 }
233 Else {
234 Store(Match
235 (MDTT, MLE, GTTM(PMTS),
236 MTR, 0, 0), Local0)
237 If(LLess(Local0, 3)) {
238 Or(0x20, Local0, DMMD)
239 }
240 }
241 Return(CMBF)
242 }
243 } /* End Device(SLAV) */
244}