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

📄 tmbtnanddrv.c

📁 pnx8950 nand flash 驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
    +++ Additional Notes
    After this call the following global variables are valid:
        gtmbtNandDrvNumOfBlocks
        gtmbtNandDrvNumOfPages
        gtmbtNandDrvNumOfBytesMain
        gtmbtNandDrvNumOfBytesSpare
        gtmbtNandDrvNumOfBytesBlock
        gtmbtNandDrvNumOfBytesDevice
        gtmbtNandDrv16bit

*/
/******************************************************************************/
tmErrorCode_t tmbtNandDrvInit(UInt32 *pMmioBasePhys)
{
    register tmErrorCode_t err = TM_OK;
    register UInt32 devMfrMask;
    register UInt32 i;

    /*Setup Selection Profile specified by selprofile*/
    gptmbtNandDrvXioBase = (UInt32*)(((UInt32)pMmioBasePhys + MMIO_PCI_XIO_REGS_OFFSET) | K1BASE);
    i = XIO_REG(MMIO_XIO_SEL0_PROF);
    if ((i & EN_SELX_M) == 0)
    {
        err = TM_BT_ERR_NAND_DRV_INVALID_PARAMETER_XIO_PROFILE;
        goto functionreturn;
    }
    if ((i & SELX_TYPE_M) != SELX_TYPE_NAND)
    {
        err = TM_BT_ERR_NAND_DRV_INVALID_PARAMETER_XIO_PROFILE;
        goto functionreturn;
    }

    gptmbtNandDrvNandBase = (UInt32*)PHYS_TO_UNCACHED(XIO_REG(MMIO_BASE18) + (((i & SELX_OFFSET_M) >> SELX_OFFSET) * 8 * MBYTE));

    /*Read Manufacturer ID and Device ID*/
    NAND_CMD_WITH_DATA(1, 1, gtmbtNandDrv64MegDevice, NAND_CMD_READ_ID, 0);
#ifdef NAND16BIT
    i = *gptmbtNandDrvNandBase;

    devMfrMask = ((i >> 8) &0xFF00) | (i & 0xff);
#else
    devMfrMask = (UInt32) *((UInt16*)gptmbtNandDrvNandBase);
#endif

    for (i = 0; gDeviceList[i] != 0; i ++ )
    {
        if ((gDeviceList[i] & (NAND_MFR_ID_M | NAND_DEV_ID_M)) == devMfrMask)
        {
            gtmbtNandDrvCapabilities    = gDeviceList[i];
            gtmbtNandDrvNumOfBlocks     = 1 << NAND_NROF_BLOCKS_GET(gtmbtNandDrvCapabilities);
            gtmbtNandDrvNumOfPages      = 1 << NAND_NROF_PAGES_GET(gtmbtNandDrvCapabilities);
            gtmbtNandDrvNumOfBytesMain  = 1 << NAND_NROF_BYTES_MAIN_GET(gtmbtNandDrvCapabilities);
            gtmbtNandDrvNumOfBytesSpare = 1 << NAND_NROF_BYTES_SPARE_GET(gtmbtNandDrvCapabilities);
            gtmbtNandDrvNumOfBytesBlock = gtmbtNandDrvNumOfPages * gtmbtNandDrvNumOfBytesMain;
            gtmbtNandDrvNumOfBytesDevice= gtmbtNandDrvNumOfBytesBlock * gtmbtNandDrvNumOfBlocks;
            gtmbtNandDrv16bit           = NAND_16BIT_GET(gtmbtNandDrvCapabilities);

            if (gtmbtNandDrvNumOfBytesDevice > NAND_SIZE_256_MBIT)
            {
                /* Special handling required for devices > 32 megs */
                /* See Viper 2 UM 13-34 */
                gtmbtNandDrvAddressCyclesRW = 3; /* NB. This actually means 4 cycles. */
                gtmbtNandDrvAddressCyclesBE = 2; /* NB. This actually means 3 cycles. */
                gtmbtNandDrv64MegDevice = 1;
            }
            else
            {
                gtmbtNandDrvAddressCyclesRW = 3;
                gtmbtNandDrvAddressCyclesBE = 2;
                gtmbtNandDrv64MegDevice = 0;
            }

            err = TM_OK;
            goto functionreturn;
        }
    }
    err = TM_BT_ERR_NAND_DRV_DETECTED_DEVICE_NOT_SUPPORTED;


functionreturn:
    return err;
}
/******************************************************************************/
/** +++ tmbtNandDrvReadMainArea

    Read the main page area of flash at the specified flash address into memory

    +++ Parameter         Flow    Description
        nandaddr          IN      Address in flash to read.
        dramaddr          IN/OUT  Address to read flash data into.
                                  MUST be 32bit aligned.
        length            IN      Amount of page to read in.

    +++ Return value

    +++ Additional Notes

*/
/******************************************************************************/
tmErrorCode_t tmbtNandDrvReadMainArea(UInt32 nandaddr, void * dramaddr, UInt32 length)
{
    register tmErrorCode_t err = TM_OK;
    register UInt32 nandPhys;
    register UInt32 dramPhys;

    if (length == 0)
    {
        goto functionreturn;
    }
    if ((nandaddr & 3) != 0)
    {
        err = TM_BT_ERR_NAND_DRV_INVALID_PARAMETER_UNALIGNED_NAND_ADDRESS;
        goto functionreturn;
    }
    if (((UInt32)dramaddr & 3) != 0)
    {
        err = TM_BT_ERR_NAND_DRV_INVALID_PARAMETER_UNALIGNED_RAM_ADDRESS;
        goto functionreturn;
    }
    if (nandaddr >= gtmbtNandDrvNumOfBytesDevice)
    {
        err = TM_BT_ERR_NAND_DRV_INVALID_PARAMETER_NAND_ADDRESS_TOO_HIGH;
        goto functionreturn;
    }

    length = (length + 3) & 0xFFFFFFFC; /* Round Up Length */
    if ((nandaddr + length) > gtmbtNandDrvNumOfBytesDevice)
    {
        err = TM_BT_ERR_NAND_DRV_INVALID_PARAMETER_LENGTH_TO_BIG;
        goto functionreturn;
    }

    nandPhys = VIRT_TO_PHYS(gptmbtNandDrvNandBase) + nandaddr;
    dramPhys = VIRT_TO_PHYS(dramaddr);

    NAND_CMD_WITH_DATA(1, gtmbtNandDrvAddressCyclesRW, gtmbtNandDrv64MegDevice, NAND_CMD_READ_MAIN, 0);
    err = tmbtNandDrvDMA(dramPhys, nandPhys, length, 6);
    /* Invalidate Data cache */
    cachePr4450DCInvalidate(dramaddr,  length);
functionreturn:
    return err;
}
/******************************************************************************/
/** +++ tmbtNandDrvReadSpareArea

    Read the spare/OOB page area of flash at the specified flash address into memory

    +++ Parameter         Flow    Description
        nandaddr          IN      Address in flash to read.
        dramaddr          IN/OUT  Address to read flash data into.
                                  MUST be 32bit aligned.

    +++ Return value

    +++ Additional Notes

*/
/******************************************************************************/
tmErrorCode_t tmbtNandDrvReadSpareArea(unsigned long nandaddr, void * dramaddr)
{
        register tmErrorCode_t err = TM_OK;
        register UInt32 nandPhys;
        register UInt32 dramPhys;
        if (((UInt32)dramaddr & 3) != 0)
        {
            err = TM_BT_ERR_NAND_DRV_INVALID_PARAMETER_UNALIGNED_RAM_ADDRESS;
            goto functionreturn;
        }
        if (nandaddr >= gtmbtNandDrvNumOfBytesDevice)
        {
            err = TM_BT_ERR_NAND_DRV_INVALID_PARAMETER_NAND_ADDRESS_TOO_HIGH;
            goto functionreturn;
        }
        nandaddr = nandaddr & (~(gtmbtNandDrvNumOfBytesMain - 1)); /* align NAND offset to page start*/

        nandPhys = VIRT_TO_PHYS(gptmbtNandDrvNandBase) + nandaddr;
        dramPhys = VIRT_TO_PHYS(dramaddr);
        NAND_CMD_WITH_DATA(1, gtmbtNandDrvAddressCyclesRW, gtmbtNandDrv64MegDevice, NAND_CMD_READ_SPARE, 0);
        err = tmbtNandDrvDMA(dramPhys, nandPhys, gtmbtNandDrvNumOfBytesSpare, 6);

        /* Invalidate Data cache */
        cachePr4450DCInvalidate(dramaddr,  gtmbtNandDrvNumOfBytesSpare);
functionreturn:
        return err;
}
/******************************************************************************/
/** +++ tmbtNandDrvDMA

    Function to transfer data to/from NAND Flash using the DMA engine.

    +++ Parameter         Flow    Description
        internal          IN      Internal Memory Address (RAM)
        external          IN      External Memory Address (Flash)
        length            IN      Length of data to transfer
        cmd               IN      DMA engine command, (read/write)

    +++ Return value
    TM_OK on success
    OR
    TM_BT_ERR_NAND_DRV_DMA_TIMEOUT if the DMA took too long

    +++ Additional Notes

*/
/******************************************************************************/
tmErrorCode_t tmbtNandDrvDMA(UInt32 internal, UInt32 external, UInt32 length, UInt cmd)
{
    register UInt32 i;

    XIO_REG(MMIO_DMA_LENGTH) = length >> 2; /* Length in words */
    XIO_REG(MMIO_DMA_EADDR)  = external;
    XIO_REG(MMIO_DMA_IADDR)  = internal;
    XIO_REG(MMIO_DMA_INT_CLR)= DMA_DONE_M;
    XIO_REG(MMIO_DMA_CTRL)   = SND2XIO_M | (MAX_BURST_SIZE_128 << MAX_BURST_SIZE) | INIT_DMA_M | (cmd << CMD_TYPE);

    for (i = 0; i < DMA_TIMEOUT; i ++)
    {
        register UInt32 status;
        status =XIO_REG(MMIO_DMA_INT_STATUS);
        if (status & DMA_DONE_M)
        {
            return TM_OK;
        }
    }
    return TM_BT_ERR_NAND_DRV_DMA_TIMEOUT;
}

⌨️ 快捷键说明

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