⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 atapiromi.cpp

📁 SMDK2450的BSP 有很多新的特性,记得升级PB啊.
💻 CPP
📖 第 1 页 / 共 3 页
字号:

// ----------------------------------------------------------------------------
// Function: BeginDMA
//     Begin DMA transfer
//
// Parameters:
//     fRead -
// ----------------------------------------------------------------------------

BOOL
CRomiDisk::BeginDMA(
    BOOL fRead
    )
{
    BYTE bStatus, bCommand;

    CacheSync(CACHE_SYNC_DISCARD);

    WriteBMCommand(0);
    WriteBMTable(m_pPRDPhys);

    bStatus = ReadBMStatus();
    bStatus |= 0x06;
    // bStatus |= 0x66;

    WriteBMStatus(bStatus);

    if (fRead) {
        bCommand = 0x08 | 0x01;
    }
    else {
        bCommand = 0x00 | 0x01;
    }

    WriteBMCommand(bCommand);

    bStatus = ReadBMStatus();

    return TRUE;
}

// ----------------------------------------------------------------------------
// Function: EndDMA
//     End DMA transfer
//
// Parameters:
//     None
// ----------------------------------------------------------------------------

BOOL
CRomiDisk::EndDMA(
    )
{
    BYTE bStatus = ReadBMStatus();

    if ((bStatus & BM_STATUS_INTR) && (bStatus & BM_STATUS_ACTIVE)) {
        DEBUGMSG(ZONE_DMA, (_T(
            "Atapi!CRomiDisk::EndDMA> Status: active; status(0x%x)\r\n"
            ), bStatus));
    }
    else if ((bStatus & BM_STATUS_INTR) && !(bStatus & BM_STATUS_ACTIVE)) {
        DEBUGMSG(ZONE_DMA, (_T(
            "Atapi!CRomiDisk::EndDMA> Status: inactive; status(0x%x)\r\n"
            ), bStatus));
    }
    else if (!(bStatus & BM_STATUS_INTR)&& (bStatus & BM_STATUS_ACTIVE)) {

        DEBUGMSG(ZONE_ERROR|ZONE_DMA, (_T(
            "Atapi!CRomiDisk::EndDMA> Interrupt delayed; status(0x%x)\r\n"
            ), bStatus));

        BOOL bCount = 0;

        while (TRUE) {

            StallExecution(100);

            bCount++;
            bStatus = ReadBMStatus();

            if ((bStatus & BM_STATUS_INTR) && !(bStatus & BM_STATUS_ACTIVE)) {
                DEBUGMSG(ZONE_DMA, (_T(
                    "Atapi!CRomiDisk::EndDMA> DMA complete after delay; status(0x%x)\r\n"
                    ), bStatus));
                break;
            }
            else {
                DEBUGMSG(ZONE_ERROR|ZONE_DMA, (_T(
                    "Atapi!CRomiDisk::EndDMA> Interrupt still delayed; status(0x%x)\r\n"
                    ), bStatus));
                if (bCount > 10) {
                    WriteBMCommand(0);
                    return FALSE;
                }
            }
        }
    }
    else {
        if (bStatus & BM_STATUS_ERROR) {
            DEBUGMSG(ZONE_ERROR|ZONE_DMA, (_T(
                "Atapi!CRomiDisk::EndDMA> Error; (0x%x)\r\n"
                ), bStatus));
            DEBUGCHK(0);
            return FALSE;
        }
    }

    WriteBMCommand(0);

    return TRUE;
}

// ----------------------------------------------------------------------------
// Function: AbortDMA
//     Abort DMA transfer
//
// Parameters:
//     None
// ----------------------------------------------------------------------------

BOOL
CRomiDisk::AbortDMA(
    )
{
    DWORD i;

    WriteBMCommand(0);

    for (i = 0; i < m_dwSGCount; i++) {
        if (!m_pSGCopy[i].pDstAddress) {
            UnlockPages(m_pSGCopy[i].pSrcAddress, m_pSGCopy[i].dwSize);
        }
    }

    // free all but the first @MIN_PHYS_PAGES pages; these are fixed
    for (i = MIN_PHYS_PAGES; i < m_dwPhysCount; i++) {
        FreePhysMem(m_pPhysList[i].pVirtualAddress);
    }

    return FALSE;
}

// ----------------------------------------------------------------------------
// Function: CompleteDMA
//     Complete DMA transfer
//
// Parameters:
//     pSgBuf -
//     dwSgCount -
//     fRead -
// ----------------------------------------------------------------------------

BOOL
CRomiDisk::CompleteDMA(
    PSG_BUF pSgBuf,
    DWORD dwSgCount,
    BOOL fRead
    )
{
    DWORD i;

    for (i = 0; i < m_dwSGCount; i++) {
        if (m_pSGCopy[i].pDstAddress) {
            // this corresponds to an unaligned region; copy it back to the
            // scatter/gather buffer
            memcpy(m_pSGCopy[i].pDstAddress, m_pSGCopy[i].pSrcAddress, m_pSGCopy[i].dwSize);
        }
        else {
            // this memory region needs to be unlocked
            UnlockPages(m_pSGCopy[i].pSrcAddress, m_pSGCopy[i].dwSize);
        }
    }

    // free all but the first @MIN_PHYS_PAGES pages; the first @MIN_PHYS_PAGES
    // pages are fixed

    for (i = MIN_PHYS_PAGES; i < m_dwPhysCount; i++) {
        FreePhysMem(m_pPhysList[i].pVirtualAddress);
    }

    return TRUE;
}

BOOL
CRomiDisk::WakeUp(
    )
{
//    BOOL retVal;
    //jungpil

    //memory controller settings are not recovered from Wakeup
	m_vpEBIRegs->EBICON |=  (1<<10)|(1<<9); 
	m_vpIOPORTRegs->GPGCON |= (3<<30)|(3<<28)|(3<<26)|(3<<24)|(3<<22);

#if (BSP_TYPE == BSP_SMDK2443)
	m_vpIOPORTRegs->GPADAT = 0x1aa8a; // GPA10 RDATA_OEN setting
#elif (BSP_TYPE == BSP_SMDK2450)
	m_vpIOPORTRegs->GPACON |= (1<<27)|(1<<11)|(1<<14)|(1<<13);// nWE_CF,nOE_CF,nRCS3,nRCS2 enable //S3C2450X01
//	m_vpIOPORTRegs->GPACON &= ~(0x1<<10);	// GPA10 RDATA_OEN setting
#endif	// (BSP_TYPE == BSP_SMDK2443)
	m_vpIOPORTRegs->MISCCR &=(~(1<<30)); // card detect when card is detected ,the bit should be '0'.
	m_vpIOPORTRegs->GPADAT &=~(0x1<<13);
	Sleep(2);
	
	*((UINT32 *)(m_pATAReg + MUX_REG)) = 0x07;
	Sleep(2);
	*((UINT32 *)(m_pATAReg + MUX_REG)) = 0x03;
	Sleep(2);
	*((UINT32 *)(m_pATAReg + MUX_REG)) = 0x01;
	Sleep(500);

	*((UINT32 *)(m_pATAReg + ATA_PIO_TIME)) = 0x1c238;
	*((UINT32 *)(m_pATAReg + ATA_UDMA_TIME)) = 0x20B1362 ; 

	*((UINT32 *)(m_pATAReg + ATA_IRQ)) |= 0x1f; 	
	*((UINT32 *)(m_pATAReg + ATA_IRQ_MASK)) |= 0x1f;	
	
	*((UINT32 *)(m_pATAReg + ATA_CONTROL)) |= 0x1; 	

    //power on
    return CDisk::Init(NULL); // It is the simplest way and best way.
}

CDiskPower *
CRomiDisk::GetDiskPowerInterface(
    void
    )
{
    CDiskPower *pDiskPower = new CRomiDiskPower;
    return pDiskPower;
}

void 
CRomiDisk::SetPioMode(UCHAR  pmode) 
{
	UINT8 nMode;
	UINT32 uT1;
	UINT32 uT2;
	UINT32 uTeoc;
	UINT32 i;
	
	UINT32 uPioTime[5];
	UINT32 m_uPioT1[5] = {100,60,40,40,40};     // min = {70,50,30,30,25};
	UINT32 m_uPioT2[5] = {400,300,290,130,70}; // min = {290,290,290,80,70};
	UINT32 m_uPioTeoc[5] = {100,25,10,10,10};  // min = {20,15,10,10,10};
	
	UINT32 uCycleTime = (UINT32)(1000000000/S3C2450_HCLK);
	UINT32 uTemp = *((UINT32 *)(m_pATAReg + ATA_CFG));

	if ((pmode & (UCHAR)0x3) == 1) 
		nMode = PIO3;
	else if ((pmode & (UCHAR)0x3) == 3) 
		nMode = PIO4;
	else 
		nMode = PIO2 ;


	for (i=0; i<5; i++)
	{
		uT1   = (m_uPioT1[i]  /uCycleTime + 1)&0xff;
		uT2   = (m_uPioT2[i]  /uCycleTime + 1)&0xff;
		uTeoc = (m_uPioTeoc[i]/uCycleTime + 1)&0x0f;
		uPioTime[i] = (uTeoc<<12)|(uT2<<4)|uT1;
	}
	
//	g_vATAPIRegs->ATA_IRQ=0xff;
//	g_vATAPIRegs->ATA_IRQ_MASK = ATAPI_MASK;

	ATA_WRITE_BYTE(m_pATAReg + ATA_PIO_DAD, 0x0);
	ATA_WRITE_BYTE(m_pATAReg + ATA_PIO_FED, 0x3);
	ATA_WRITE_BYTE(m_pATAReg + ATA_PIO_SCR, (0x8 |(nMode&0x7)));
	ATA_WRITE_BYTE(m_pATAReg + ATA_PIO_LLR, 0x0);
	ATA_WRITE_BYTE(m_pATAReg + ATA_PIO_LMR, 0x0);
	ATA_WRITE_BYTE(m_pATAReg + ATA_PIO_LHR, 0x0);
	ATA_WRITE_BYTE(m_pATAReg + ATA_PIO_DVR, 0x40);
	ATA_WRITE_BYTE(m_pATAReg + ATA_PIO_CSD, ATAPI_CMD_SET_FEATURES);	
	WaitForNoBusyStatus();
	switch(pmode) { // modified by Bryan W. Lee (Oct. 19th, 2005)
		case PIO1:
			uTemp &= (~0x2); //IORDY disable
			*(UINT32 *)(m_pATAReg + ATA_PIO_TIME) = uPioTime[1];
			break;
		case PIO2:
			uTemp &= (~0x2); //IORDY disable
			*(UINT32 *)(m_pATAReg + ATA_PIO_TIME) = uPioTime[2];

			break;
		case PIO3:
			uTemp |= 0x2; //IORDY enable
			*(UINT32 *)(m_pATAReg + ATA_PIO_TIME) = uPioTime[3];			
			break;
		case PIO4:
			uTemp |= 0x2; //IORDY enable
			*(UINT32 *)(m_pATAReg + ATA_PIO_TIME) = uPioTime[4];
			break;
		default:
			uTemp &= (~0x2); //IORDY disable
			*(UINT32 *)(m_pATAReg + ATA_PIO_TIME) = uPioTime[0];
			break;
		}
		
	*(UINT32 *)(m_pATAReg + ATA_CFG) = uTemp;
}


void 
CRomiDisk::SetUdmaMode() 
{

	UINT32 uTdvh1;
	UINT32 uTdvs;
	UINT32 uTrp;
	UINT32 uTss;
	UINT32 uTackenv;
	UINT32 i;

	UINT32 uUdmaTime[5];
	UINT32 uUdmaTdvh[5] = {20,20,20,20,10}; //{7,7,7,7,7};
	UINT32 uUdmaTdvs[5] = {100,60,40,25,20}; //{70,48,31,20,7};
	UINT32 uUdmaTrp[5] = {160,125,100,100,100};
	UINT32 uUdmaTss[5] = {50,50,50,50,50};
	UINT32 uUdmaTackenvMin[5] = {20,20,20,20,20};
//	UINT32 uUdmaTackenvMin[5] = {70,70,70,55,55};	
	UINT32 uCycleTime = (UINT32)(1000000000/S3C2450_HCLK);

#if 1
	m_vpIOPORTRegs->GPADAT &= ~(1<<5); // GPA10 RDATA_fOEN setting
//	rGPACDH = 0xaa8a; // GPA10 RDATA_OEN setting
//	rGPBCON = rGPBCON & ~(3<<12) | (1<<12); // GPB6 output setting (nXBREQ)
//	rGPBDAT &= ~(1<<6); // GPB6 -> L, buffer Output enable 
#else
	g_vIOPORTRegs->GPBCON = (g_vIOPORTRegs->GPBCON & ~(0xf<<10)) | (5<<10); // GPB5,6 output mode
	g_vIOPORTRegs->GPBCON = (g_vIOPORTRegs->GPBCON &  ~(0x3<<8)) |( 1<<8); // GPB4 output mode		
	g_vIOPORTRegs->GPBCON = (g_vIOPORTRegs->GPBCON &  ~(0x3<<0)) |( 1<<0); // GPB4 output mode			
	g_vIOPORTRegs->GPBDAT |= (3<<5); // GPB5,6 -> H	
#endif	
	
//	ChangeBufferControl(PIO_CPU);    
	
	for (i=0; i<5; i++)
	{
		uTdvh1	= (uUdmaTdvh[i] / uCycleTime + 1)&0x0f;
		uTdvs	= (uUdmaTdvs[i] / uCycleTime + 1)&0xff;
		uTrp	= (uUdmaTrp[i]  / uCycleTime + 1)&0xff;
		uTss	= (uUdmaTss[i]  / uCycleTime + 1)&0x0f;
		uTackenv= (uUdmaTackenvMin[i]/uCycleTime + 1)&0x0f;
		uUdmaTime[i] = (uTdvh1<<24)|(uTdvs<<16)|(uTrp<<8)|(uTss<<4)|uTackenv;
	}	

	ATA_WRITE_BYTE(m_pATAReg + ATA_PIO_DAD, 0x0);
	ATA_WRITE_BYTE(m_pATAReg + ATA_PIO_FED, 0x3);
	ATA_WRITE_BYTE(m_pATAReg + ATA_PIO_SCR, (0x40 |((BYTE)m_dwCurrentUDMAMode&0x7)));
//	ATA_WRITE_BYTE(m_pATAReg + ATA_PIO_SCR, (0x40 |(3&0x7)));
	ATA_WRITE_BYTE(m_pATAReg + ATA_PIO_LLR, 0x0);
	ATA_WRITE_BYTE(m_pATAReg + ATA_PIO_LMR, 0x0);
	ATA_WRITE_BYTE(m_pATAReg + ATA_PIO_LHR, 0x0);
	ATA_WRITE_BYTE(m_pATAReg + ATA_PIO_DVR, 0x40);
	ATA_WRITE_BYTE(m_pATAReg + ATA_PIO_CSD, ATAPI_CMD_SET_FEATURES);

	WaitForNoBusyStatus();

	
	switch(m_dwCurrentUDMAMode) 
//	switch(3) 
	{
		case UDMA0:
			*(UINT32 *)(m_pATAReg + ATA_UDMA_TIME) = uUdmaTime[0];
			break;		
		case UDMA1:
			*(UINT32 *)(m_pATAReg + ATA_UDMA_TIME) = uUdmaTime[1];
			break;
		case UDMA2:
			*(UINT32 *)(m_pATAReg + ATA_UDMA_TIME) = uUdmaTime[2];
			break;
		case UDMA3:
			*(UINT32 *)(m_pATAReg + ATA_UDMA_TIME) = uUdmaTime[3];
			break;
		case UDMA4:
			*(UINT32 *)(m_pATAReg + ATA_UDMA_TIME) = uUdmaTime[4];
			break;
		default:
			RETAILMSG(1,(TEXT("UDMA mode is supported between 0 to 4 !!!! . %d\r\n"),m_dwCurrentUDMAMode));
			break;
	}
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -