atapiromi.cpp

来自「SAMSUNG S3C6410 CPU BSP for winmobile6」· C++ 代码 · 共 1,306 行 · 第 1/3 页

CPP
1,306
字号
    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(
    )
{
	m_vpSYSCONRegs->MEM_SYS_CFG |= ((m_vpSYSCONRegs->MEM_SYS_CFG & (~(0x3F<<0)))|(0x1<<5)|(0x1<<4));
	m_vpIOPORTRegs->GPBCON &= ~(0xF<<16);
	m_vpIOPORTRegs->GPBCON |= (4<<16);

	if ( m_dwIndirectMode == 1 )
	{
		m_vpSYSCONRegs->MEM_SYS_CFG &= ~(0x1<<14); // InDirectMode
		m_dwOPMode = IndirectMode;
		RETAILMSG(1,(TEXT("[CF-ATA] Mode : InDirect Mode\n")));
	}
	else 
	{
		m_vpSYSCONRegs->MEM_SYS_CFG |= (0x1<<14); // Use independent CF interface (DirectMode)
		m_dwOPMode = DirectMode;
		RETAILMSG(1,(TEXT("[CF-ATA] Mode : Direct Mode\n")));
	}

	// 2007.04.11 D.Baek
	// Set the GPIO for CF_Data, CF_Addr, IORDY, IOWR, IORD, CE[0], and CE[1]
	// Details.
	// 1. GPKCON0[31:0]  - DATA_CF[7:0] -> 4'b0101
	// 2. GPKCON1[31:0]  - DATA_CF[15:8] -> 4'b0101
	// 3. GPLCON0[11:0]  - ADDR_CF[2:0] -> 4'b0110
	// 4. GPMCON[19:16] - IORDY_CF -> 4'b0110
	// 5. GPMCON[15:12] - IOWR_CF -> 4'b0110
	// 6. GPMCON[11:8]   - IORD_CF -> 4'b0110
	// 7. GPMCON[74]      - CE_CF[1] -> 4'b0110
	// 8. GPMCON[3:0]     - CE_CF[0] -> 4'b0110
	
	if(m_dwOPMode == DirectMode)
	{
#if	(CPU_REVISION == EVT0)
		dwBackup_GPACON = m_vpIOPORTRegs->GPACON;
#endif
		m_vpIOPORTRegs->GPKCON0 &= ~(0xFFFFFFFF);
		m_vpIOPORTRegs->GPKCON0 |= (0x55555555);
#if	(CPU_REVISION == EVT0)
		m_vpIOPORTRegs->GPACON = dwBackup_GPACON;
#endif

#if	(CPU_REVISION == EVT0)
		dwBackup_GPACON = m_vpIOPORTRegs->GPADAT;
#endif
		m_vpIOPORTRegs->GPKCON1 &= ~(0xFFFFFFFF);
		m_vpIOPORTRegs->GPKCON1 |= (0x55555555);
#if	(CPU_REVISION == EVT0)
		m_vpIOPORTRegs->GPADAT = dwBackup_GPACON;
#endif

	//RETAILMSG(1,(TEXT("GPKCON0,1  : OK\r\n")));

#if	(CPU_REVISION == EVT0)
		dwBackup_GPACON = m_vpIOPORTRegs->GPAPUDSLP;
#endif
		m_vpIOPORTRegs->GPLCON0 &= ~(0xFFF);
		m_vpIOPORTRegs->GPLCON0 |= (0x666);
#if	(CPU_REVISION == EVT0)
		m_vpIOPORTRegs->GPAPUDSLP=dwBackup_GPACON;
#endif

#if	(CPU_REVISION == EVT0)
		dwBackup_GPACON = m_vpIOPORTRegs->GPBCON;
#endif
		m_vpIOPORTRegs->GPMCON &= ~(0xFFFFF);
		m_vpIOPORTRegs->GPMCON |= (0x66666);
#if	(CPU_REVISION == EVT0)
		m_vpIOPORTRegs->GPBCON = dwBackup_GPACON;
#endif
	}

//2007.04.28 D.Baek
//The "output enable" and "Card Power Enable" signal is NOT connected. Namely, it is uncontrollable.
#if 1
	*((UINT32 *)(m_pATAReg + MUX_REG)) = 0x07;
	*((UINT32 *)(m_pATAReg + MUX_REG)) = 0x03;
#endif
	*((UINT32 *)(m_pATAReg + MUX_REG)) = 0x01;
	Sleep(100);


	*((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_CFG)) &= ~(0x40);

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

	Sleep(100);
	m_vpIOPORTRegs->GPNCON &= ~(0x3<<16);
	m_vpIOPORTRegs->GPNCON |= (0x1<<16); // Set GPN8 to output
	m_vpIOPORTRegs->GPNDAT |= (0x1<<8);
	Sleep(100);
	m_vpIOPORTRegs->GPNDAT &= ~ (0x1<<8);

    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] = {70,50,30,30,30};    // min = {70,50,30,30,25};
	UINT32 m_uPioT2[5] = {290,290,290,80,70}; // min = {290,290,290,80,70};
	UINT32 m_uPioTeoc[5] = {20,20,10,10,10};  // min = {20,15,10,10,10};
	UINT32 uCycleTime = (UINT32)(1000000000/S3C6410_HCLK);
*/	


	UINT32 uPioTime[5];
	UINT32 m_uPioT1[5] = {70,50,30,30,35};
	UINT32 m_uPioT2[5] = {290,290,290,80,80};
	UINT32 m_uPioTeoc[5] = {20,15,20,20,20};

	UINT32 uCycleTime = (UINT32)(1000000000/S3C6410_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_vpATAPIRegs->ATA_IRQ=0xff;
//	g_vpATAPIRegs->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,10,10,10}; //{7,7,7,7,7};
	UINT32 uUdmaTdvs[5] = {100,60,50,35,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 uUdmaTackenvMax[5] = {70,70,70,55,55};	
	UINT32 uCycleTime = (UINT32)(1000000000/S3C6410_HCLK);
	//UINT32 uCycleTime = 7;

	
	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;
		uTackenv= (uUdmaTackenvMax[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_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) 
	{
		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 + =
减小字号Ctrl + -
显示快捷键?