2010-12-06 02:11:12 +01:00
|
|
|
/*
|
|
|
|
* This file is part of the coreboot project.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2010 Advanced Micro Devices, Inc.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; version 2 of the License.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
2013-02-23 18:37:27 +01:00
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
2010-12-06 02:11:12 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
Scope (_SB) {
|
|
|
|
Device(PCI0) {
|
|
|
|
Device(IDEC) {
|
|
|
|
Name(_ADR, 0x00140001)
|
|
|
|
#include "ide.asl"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Some timing tables */
|
|
|
|
Name(UDTT, Package(){ /* Udma timing table */
|
|
|
|
120, 90, 60, 45, 30, 20, 15, 0 /* UDMA modes 0 -> 6 */
|
|
|
|
})
|
|
|
|
|
|
|
|
Name(MDTT, Package(){ /* MWDma timing table */
|
|
|
|
480, 150, 120, 0 /* Legacy DMA modes 0 -> 2 */
|
|
|
|
})
|
|
|
|
|
|
|
|
Name(POTT, Package(){ /* Pio timing table */
|
|
|
|
600, 390, 270, 180, 120, 0 /* PIO modes 0 -> 4 */
|
|
|
|
})
|
|
|
|
|
|
|
|
/* Some timing register value tables */
|
|
|
|
Name(MDRT, Package(){ /* MWDma timing register table */
|
|
|
|
0x77, 0x21, 0x20, 0xFF /* Legacy DMA modes 0 -> 2 */
|
|
|
|
})
|
|
|
|
|
|
|
|
Name(PORT, Package(){
|
|
|
|
0x99, 0x47, 0x34, 0x22, 0x20, 0x99 /* PIO modes 0 -> 4 */
|
|
|
|
})
|
|
|
|
|
|
|
|
OperationRegion(ICRG, PCI_Config, 0x40, 0x20) /* ide control registers */
|
|
|
|
Field(ICRG, AnyAcc, NoLock, Preserve)
|
|
|
|
{
|
|
|
|
PPTS, 8, /* Primary PIO Slave Timing */
|
|
|
|
PPTM, 8, /* Primary PIO Master Timing */
|
|
|
|
OFFSET(0x04), PMTS, 8, /* Primary MWDMA Slave Timing */
|
|
|
|
PMTM, 8, /* Primary MWDMA Master Timing */
|
|
|
|
OFFSET(0x08), PPCR, 8, /* Primary PIO Control */
|
|
|
|
OFFSET(0x0A), PPMM, 4, /* Primary PIO master Mode */
|
|
|
|
PPSM, 4, /* Primary PIO slave Mode */
|
|
|
|
OFFSET(0x14), PDCR, 2, /* Primary UDMA Control */
|
|
|
|
OFFSET(0x16), PDMM, 4, /* Primary UltraDMA Mode */
|
|
|
|
PDSM, 4, /* Primary UltraDMA Mode */
|
|
|
|
}
|
|
|
|
|
|
|
|
Method(GTTM, 1) /* get total time*/
|
|
|
|
{
|
|
|
|
Store(And(Arg0, 0x0F), Local0) /* Recovery Width */
|
|
|
|
Increment(Local0)
|
|
|
|
Store(ShiftRight(Arg0, 4), Local1) /* Command Width */
|
|
|
|
Increment(Local1)
|
|
|
|
Return(Multiply(30, Add(Local0, Local1)))
|
|
|
|
}
|
|
|
|
|
|
|
|
Device(PRID)
|
|
|
|
{
|
|
|
|
Name (_ADR, Zero)
|
|
|
|
Method(_GTM, 0)
|
|
|
|
{
|
|
|
|
NAME(OTBF, Buffer(20) { /* out buffer */
|
|
|
|
0xFF, 0xFF, 0xFF, 0xFF,
|
|
|
|
0xFF, 0xFF, 0xFF, 0xFF,
|
|
|
|
0xFF, 0xFF, 0xFF, 0xFF,
|
|
|
|
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00
|
|
|
|
})
|
|
|
|
|
|
|
|
CreateDwordField(OTBF, 0, PSD0) /* PIO spd0 */
|
|
|
|
CreateDwordField(OTBF, 4, DSD0) /* DMA spd0 */
|
|
|
|
CreateDwordField(OTBF, 8, PSD1) /* PIO spd1 */
|
|
|
|
CreateDwordField(OTBF, 12, DSD1) /* DMA spd1 */
|
|
|
|
CreateDwordField(OTBF, 16, BFFG) /* buffer flags */
|
|
|
|
|
|
|
|
/* Just return if the channel is disabled */
|
|
|
|
If(And(PPCR, 0x01)) { /* primary PIO control */
|
|
|
|
Return(OTBF)
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Always tell them independent timing available and IOChannelReady used on both drives */
|
|
|
|
Or(BFFG, 0x1A, BFFG)
|
|
|
|
|
|
|
|
Store(GTTM(PPTM), PSD0) /* save total time of primary PIO master timming to PIO spd0 */
|
|
|
|
Store(GTTM(PPTS), PSD1) /* save total time of primary PIO slave Timing to PIO spd1 */
|
|
|
|
|
|
|
|
If(And(PDCR, 0x01)) { /* It's under UDMA mode */
|
|
|
|
Or(BFFG, 0x01, BFFG)
|
|
|
|
Store(DerefOf(Index(UDTT, PDMM)), DSD0)
|
|
|
|
}
|
|
|
|
Else {
|
|
|
|
Store(GTTM(PMTM), DSD0) /* Primary MWDMA Master Timing, DmaSpd0 */
|
|
|
|
}
|
|
|
|
|
|
|
|
If(And(PDCR, 0x02)) { /* It's under UDMA mode */
|
|
|
|
Or(BFFG, 0x04, BFFG)
|
|
|
|
Store(DerefOf(Index(UDTT, PDSM)), DSD1)
|
|
|
|
}
|
|
|
|
Else {
|
|
|
|
Store(GTTM(PMTS), DSD1) /* Primary MWDMA Slave Timing, DmaSpd0 */
|
|
|
|
}
|
|
|
|
|
|
|
|
Return(OTBF) /* out buffer */
|
|
|
|
} /* End Method(_GTM) */
|
|
|
|
|
|
|
|
Method(_STM, 3, NotSerialized)
|
|
|
|
{
|
|
|
|
NAME(INBF, Buffer(20) { /* in buffer */
|
|
|
|
0xFF, 0xFF, 0xFF, 0xFF,
|
|
|
|
0xFF, 0xFF, 0xFF, 0xFF,
|
|
|
|
0xFF, 0xFF, 0xFF, 0xFF,
|
|
|
|
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00
|
|
|
|
})
|
|
|
|
|
|
|
|
CreateDwordField(INBF, 0, PSD0) /* PIO spd0 */
|
|
|
|
CreateDwordField(INBF, 4, DSD0) /* PIO spd0 */
|
|
|
|
CreateDwordField(INBF, 8, PSD1) /* PIO spd1 */
|
|
|
|
CreateDwordField(INBF, 12, DSD1) /* DMA spd1 */
|
|
|
|
CreateDwordField(INBF, 16, BFFG) /*buffer flag */
|
|
|
|
|
|
|
|
Store(Match(POTT, MLE, PSD0, MTR, 0, 0), Local0)
|
|
|
|
Divide(Local0, 5, PPMM,) /* Primary PIO master Mode */
|
|
|
|
Store(Match(POTT, MLE, PSD1, MTR, 0, 0), Local1)
|
|
|
|
Divide(Local1, 5, PPSM,) /* Primary PIO slave Mode */
|
|
|
|
|
|
|
|
Store(DerefOf(Index(PORT, Local0)), PPTM) /* Primary PIO Master Timing */
|
|
|
|
Store(DerefOf(Index(PORT, Local1)), PPTS) /* Primary PIO Slave Timing */
|
|
|
|
|
|
|
|
If(And(BFFG, 0x01)) { /* Drive 0 is under UDMA mode */
|
|
|
|
Store(Match(UDTT, MLE, DSD0, MTR, 0, 0), Local0)
|
|
|
|
Divide(Local0, 7, PDMM,)
|
|
|
|
Or(PDCR, 0x01, PDCR)
|
|
|
|
}
|
|
|
|
Else {
|
|
|
|
If(LNotEqual(DSD0, 0xFFFFFFFF)) {
|
|
|
|
Store(Match(MDTT, MLE, DSD0, MTR, 0, 0), Local0)
|
|
|
|
Store(DerefOf(Index(MDRT, Local0)), PMTM)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
If(And(BFFG, 0x04)) { /* Drive 1 is under UDMA mode */
|
|
|
|
Store(Match(UDTT, MLE, DSD1, MTR, 0, 0), Local0)
|
|
|
|
Divide(Local0, 7, PDSM,)
|
|
|
|
Or(PDCR, 0x02, PDCR)
|
|
|
|
}
|
|
|
|
Else {
|
|
|
|
If(LNotEqual(DSD1, 0xFFFFFFFF)) {
|
|
|
|
Store(Match(MDTT, MLE, DSD1, MTR, 0, 0), Local0)
|
|
|
|
Store(DerefOf(Index(MDRT, Local0)), PMTS)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* Return(INBF) */
|
|
|
|
} /*End Method(_STM) */
|
|
|
|
Device(MST)
|
|
|
|
{
|
|
|
|
Name(_ADR, 0)
|
|
|
|
Method(_GTF) {
|
|
|
|
Name(CMBF, Buffer(21) {
|
|
|
|
0x03, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF,
|
|
|
|
0x03, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF,
|
|
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF5
|
|
|
|
})
|
|
|
|
CreateByteField(CMBF, 1, POMD)
|
|
|
|
CreateByteField(CMBF, 8, DMMD)
|
|
|
|
CreateByteField(CMBF, 5, CMDA)
|
|
|
|
CreateByteField(CMBF, 12, CMDB)
|
|
|
|
CreateByteField(CMBF, 19, CMDC)
|
|
|
|
|
|
|
|
Store(0xA0, CMDA)
|
|
|
|
Store(0xA0, CMDB)
|
|
|
|
Store(0xA0, CMDC)
|
|
|
|
|
|
|
|
Or(PPMM, 0x08, POMD)
|
|
|
|
|
|
|
|
If(And(PDCR, 0x01)) {
|
|
|
|
Or(PDMM, 0x40, DMMD)
|
|
|
|
}
|
|
|
|
Else {
|
|
|
|
Store(Match
|
|
|
|
(MDTT, MLE, GTTM(PMTM),
|
|
|
|
MTR, 0, 0), Local0)
|
|
|
|
If(LLess(Local0, 3)) {
|
|
|
|
Or(0x20, Local0, DMMD)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Return(CMBF)
|
|
|
|
}
|
|
|
|
} /* End Device(MST) */
|
|
|
|
|
|
|
|
Device(SLAV)
|
|
|
|
{
|
|
|
|
Name(_ADR, 1)
|
|
|
|
Method(_GTF) {
|
|
|
|
Name(CMBF, Buffer(21) {
|
|
|
|
0x03, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF,
|
|
|
|
0x03, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF,
|
|
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF5
|
|
|
|
})
|
|
|
|
CreateByteField(CMBF, 1, POMD)
|
|
|
|
CreateByteField(CMBF, 8, DMMD)
|
|
|
|
CreateByteField(CMBF, 5, CMDA)
|
|
|
|
CreateByteField(CMBF, 12, CMDB)
|
|
|
|
CreateByteField(CMBF, 19, CMDC)
|
|
|
|
|
|
|
|
Store(0xB0, CMDA)
|
|
|
|
Store(0xB0, CMDB)
|
|
|
|
Store(0xB0, CMDC)
|
|
|
|
|
|
|
|
Or(PPSM, 0x08, POMD)
|
|
|
|
|
|
|
|
If(And(PDCR, 0x02)) {
|
|
|
|
Or(PDSM, 0x40, DMMD)
|
|
|
|
}
|
|
|
|
Else {
|
|
|
|
Store(Match
|
|
|
|
(MDTT, MLE, GTTM(PMTS),
|
|
|
|
MTR, 0, 0), Local0)
|
|
|
|
If(LLess(Local0, 3)) {
|
|
|
|
Or(0x20, Local0, DMMD)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Return(CMBF)
|
|
|
|
}
|
|
|
|
} /* End Device(SLAV) */
|
|
|
|
}
|