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

📄 atapiromi.cpp

📁 Samsung公司S3C6400芯片的BSP源码包
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    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(
    )
{
       // 2007.04.11 D.Baek
       // Notes :
       // Chip Selection signal in S3C6400 is controlled using "MEM_SYS_CFG" register in SYSCON.
       // MEM_SYS_CFG[5:4] = 2'b11 -> CFCON CS0, CFCON CS1
	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)
	{
		m_vpIOPORTRegs->GPKCON0 &= ~(0xFFFFFFFF);
		m_vpIOPORTRegs->GPKCON0 |= (0x55555555);

		m_vpIOPORTRegs->GPKCON1 &= ~(0xFFFFFFFF);
		m_vpIOPORTRegs->GPKCON1 |= (0x55555555);

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

		m_vpIOPORTRegs->GPLCON0 &= ~(0xFFF);
		m_vpIOPORTRegs->GPLCON0 |= (0x666);

		m_vpIOPORTRegs->GPMCON &= ~(0xFFFFF);
		m_vpIOPORTRegs->GPMCON |= (0x66666);
	}


	{
		m_vpIOPORTRegs->GPMCON &= ~(0xFFFFFF);
		m_vpIOPORTRegs->GPMCON |=  (0x166666);
		m_vpIOPORTRegs->GPMDAT &= ~(0x3<<5);
		m_vpIOPORTRegs->GPMDAT |=  (0x1<<5); // Set the GPMDAT[5] as HIGH
	}


//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/S3C6400_HCLK);
*/


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

	UINT32 uCycleTime = (UINT32)(1000000000/S3C6400_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/S3C6400_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 + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -