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

📄 tffsarch.c

📁 H3 M-system NAND flash driver in Linux OS, M-DOC driver
💻 C
📖 第 1 页 / 共 5 页
字号:
 *                     t f f s _ d m a _ i n t r                         * *                                                                       * * Handle DMA interrupt on Intel PXA27x (Mainstone) board.               * *                                                                       * * Parameters:                                                           * *      dma           interrupting DMA channel                           * *      dummy         not used                                           * *      regs          not used                                           * *                                                                       * *-----------------------------------------------------------------------*/static void tffs_dma_intr ( int              dma,                      void           * dummy,    /* not used */                     struct pt_regs * regs )    /* not used */{    register u_int tmp;    profiling[4]++;    /* check if interrupt came from our DMA channel */    if (dma == tffsInfo.channel)    {        /* check if DMA transfer was successful */        if ((tmp = DCSR(dma)) & DCSR_BUSERR)        {             /* andrayk Mar 24 2006: DMA transfer failed, find way to let MTD know this */            PrintkError ("Bus error, DMA transfer failed");        }        /* clear DMA interrupt from this channel */        DCSR(dma) = (tmp | (DCSR_BUSERR | DCSR_ENDINTR));    }    else        { PrintkError ("received DMA interrupt on wrong channel"); }}#elif defined(CONFIG_OMAP_H2) || defined(CONFIG_MACH_OMAP_H2)/*_____________________________________________________________________________ |                                                                            | |                                                                            | |                Texas Instruments OMAP-1610 (H2) board                      | |                                                                            | |____________________________________________________________________________| */# include <asm/arch/hardware.h># include <asm/arch/dma.h>    /*        EMIFS: Extended Memory Interface Slow. This 16-bit wide bus can interface    with and handle all transactions to flash memory, ROM, asynchronous    memories, and synchronous burst flash.    The EMIFS can support 16-bit interface width only.    TC: traffic controller    The EMIFS supports 8-,16-, or 32-bit asynchronous and synchronous    read, 4- x 32-bit synchronous burst read and 8-, 16-, or 32-bit    asynchronous write.        EMIFS_PRIOR		EMIFS LRU priority register				FFFECC04    EMIFS_CONFIG	EMIFS configuration register			FFFECC0C    EMIFS_CCS2		EMIFS chip-select configuration CS2		FFFECC18    	7:4		RDWST			Controls the wait states cycle number for asynchronous read operation and the initial idle time for asynchronous read page mode and synchronous read mode.    	15:12	PGWST/WELEN		Controls the wait states cycle number between accesses in a page for asynchronous page mode. Controls the WE pulse length during a write access. When PGWSTEN is 0, this bit specifies both PGWST/WELEN. When PGWSTEN is 1, this bit specifies only WELEN    EMIFS_PTOR1		EMIFS dynamic priority time-out 1		FFFECC28    EMIFS_PTOR2		EMIFS dynamic priority time-out 2		FFFECC2C    EMIFS_PTOR3		EMIFS dynamic priority time-out 3		FFFECC30    EMIFS_DWS		EMIFS dynamic wait states				FFFECC40    EMIFS_AADDR		EMIFS abort address						FFFECC44    EMIFS_ATYPER	EMIFS abort type						FFFECC48    EMIFS_ATOR		EMIFS abort time-out					FFFECC4C    EMIFS_ACS2		Advanced EMIFS chip-select configuration nCS2	FFFECC58            EMIFS_CS2_CONFIG 0xFFFECC18     	BSP sets the reg val 0xf800f22a, but the val after kernel starts is 0xff80fff3        *//* * static routines for OMAP1610 */static void tffs_dma_init (int resume);static void tffs_dma_release (void);/* * static vars */static dma_regs_t * dma_regs = NULL;/*-----------------------------------------------------------------------* *                                                                       * *                    t f f s a r c h _ i n i t                          * *                                                                       * * This routine is called during module initialization time with 'resume'* * argument set to FALSE, and from Power Manager's 'resume' routine with * * 'resume' argument set to TRUE. If 'resume' is FALSE, this routine     * * allocates and initializes all required board resources; if 'resume'   * * is TRUE, this routine does minimal required re-initialization of      * * these resources after power suspend.                                  * *                                                                       * * Parameters:                                                           * *      suspend     FALSE (module initialization) or TRUE (power resume) * *                                                                       * * Returns:                                                              * *      always '1' (success)                                             * *                                                                       * *-----------------------------------------------------------------------*/unsigned char tffsarch_init (int resume){    register unsigned short tmp16;    register unsigned long  tmp32;    /* Configure Chip Select that DiskOnChip is connected to.     *      * NOTE. Code below configures Chip Select to set duration of     *       DiskOnChip access cycle to 70 nanosecond, which is     *       appropriate for the case when DiskOnChip is connected to     *       OMAP1610 board via M-Systems' adapters. If you solder     *       DiskOnChip into your board, consider changing Chip Select     *       settings to significantly shorten DiskOnChip acecss cycle.     *       This should have significant positive efefct on     *       DiskOnChip's 'read' performance.     */    tmp32 = (1 << 27) | /* wait states between accesses in a page for async. page mode */            (1 << 23) | /* idle cycles for bus turn around */            (0 << 16) | /* asynchronous read */              (1 << 12) | /* WE length */            (0 <<  8) | /* wait states in write operation */            (0 <<  4) | /* wait states in read operation */                   2;   /* REF_CLK = TC_CK / 2 */    #define OMAP1610_H2_CS  2 /* chip select that DiskOnChip is connected to */    outl (tmp32, (EMIFS_CS0_CONFIG + (OMAP1610_H2_CS * sizeof(unsigned long))));    if (tffs_irq >= 0)    {        /* Configure GPIO-9 as input. This is actually a default state         * after reset, but just to be sure ...         */        tmp16 = inw (GPIO_DIRECTION_REG);        outw ((tmp16 | (1 << (tffs_irq - IH_GPIO_BASE))), GPIO_DIRECTION_REG);              /* configure DiskOnChip IRQ as GPIO-9, disable PullDown */        outl( (inl(PULL_DWN_CTRL_2) | (1 << 23)), PULL_DWN_CTRL_2);        /* select function W8 pin as GPIO-9 */        outl( (inl(FUNC_MUX_CTRL_B) & 0xFF1FFFFF), FUNC_MUX_CTRL_B);    }# if 0	volatile unsigned long*reg;	unsigned long ulTemp;	/* configure DMAREQ# as MPUIO4, disable PullDown */	ulTemp  = *(volatile unsigned long*) 0xFFFE1044;	ulTemp  |= 0x00002000; /* 0x1<<13; */	*(volatile unsigned long *)0xFFFE1044 = (unsigned long)ulTemp;	/* select function DMA_REQ tffsInfo.channel 6 */	ulTemp  = *(volatile unsigned long*) 0xFFFE1020;	ulTemp  |= 0x8000; /* 0x1<<15; */	*(volatile unsigned long *)0xFFFE1020 = (unsigned long)ulTemp;		/* configure mDoc IRQ# as GPIO-9, disable PullDown */	/* TH: For H2 Platform */	ulTemp  = *(volatile unsigned long*) 0xFFFE1048;	ulTemp  |= 0x800000; /* 0x1<<23; */	*(volatile unsigned long *)0xFFFE1048 = (unsigned long)ulTemp;	/* select function W8 pin as GPIO-9 */	ulTemp  = *(volatile unsigned long*) (0xFFFE1030);	ulTemp  &= 0xFF1FFFFF;	*(volatile unsigned long *)(0xFFFE1030) = (unsigned long)ulTemp;	reg=(unsigned long*)EMIFS_CONFIG_REG;	PrintkInfo("EMIFS_CONFIG_REG=0x%lx",*reg);	*reg=0x0c;	reg=(unsigned long*)EMIFS_CONFIG_REG;	PrintkInfo("EMIFS_CONFIG_REG=0x%lx",*reg);	reg=(unsigned long*)EMIFS_CS2_CONFIG2;	PrintkInfo("EMIFS_CS2_CONFIG2=0x%lx",*reg);	reg=(unsigned long*)EMIFS_CS2_CONFIG;	PrintkInfo("EMIFS_CS2_CONFIG=0x%lx",*reg);	*reg=0x8070;	reg=(unsigned long*)EMIFS_CS2_CONFIG;	PrintkInfo("EMIFS_CS2_CONFIG=0x%lx",*reg);# endif    /* if DMA is requested, configure it */    if (tffs_dma_mode > 0)    {        tffs_dma_init (resume);    }    return 1;}void TffsHWRelease(void){    /* if DMA was actually used, release all DMA resources */    if (tffs_dma_mode > 0)    {        tffs_dma_release ();    }}/*-----------------------------------------------------------------------* *                                                                       * *                    t f f s _ d m a _ i n i t                          * *                                                                       * * This routine is called during module initialization time with 'resume'* * argument set to FALSE, and from Power Manager's 'resume' routine with * * 'resume' argument set to TRUE. If 'resume' is FALSE, this routine     * * allocates and initializes all required DMA resources; if 'resume' is  * * TRUE, this routine does minimal required re-initialization of DMA     * * channel after power suspend.                                          * *                                                                       * * Parameters:                                                           * *      resume     FALSE (module initialization) or TRUE (power resume)  * *                                                                       * *-----------------------------------------------------------------------*/static void tffs_dma_init (int resume){    u32 tmp;    if (resume == FALSE)     {        /* We use single DMA channel for both 'read' and 'write' operations,         * so we allocate it here. We don't use DMA interrupts, so we won't         * need DMA callback.         */        tffsInfo.channel =             omap_request_dma (eDMANotSync, /* not connected to any DMA line  */                              TFFS_DEVICE_NAME,                              NULL,        /* no callback when DMA completes */                              NULL,        /* data to pass to DMA callback   */                              &dma_regs);        if ((tffsInfo.channel != 0) || (dma_regs == NULL))        {            /* failed to allocate DMA channel, won't use DMA */            tffs_dma_mode = 0;            PrintkError ("can't get DMA chan");            return;        }    }    /* Logical Channel Control Register.     * Specify peripheral DMA transfer.     */    dma_regs->lch_ctrl = LCH_TYPE_P;    /* Channel Element Number Register.     * Specify single element (16-bit word) per DMA frame.     */    dma_regs->cen = 1;    /* Channel Control Register 2.     * Specify block synchronization.     */    dma_regs->ccr2 = (1 << 2);    /* Channel Interrupt Control Register.     * Enable time-out interrupt, disable all others.     */    dma_regs->cicr = /* (1 << 5) | */   /* end-of-block interrupt */                     1;                 /* timeout interrupt */    /* read Channel Status register to clear it */    tmp = dma_regs->csr;    if (resume == FALSE)    {        tffsInfo.dma_buf_vptr = NULL;        tffsInfo.dma_buf_size = 0;        if ((tffs_dma_mode >= 1) && (tffs_dma_mode <= 3))        {            /* allocate intermediate DMA buffer (we assume one MMU page will be enough) */            tffsInfo.dma_buf_size = PAGE_SIZE;            tffsInfo.dma_buf_vptr = #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)                consistent_alloc ((GFP_KERNEL | GFP_DMA), tffsInfo.dma_buf_size,                                         &tffsInfo.dma_buf_paddr);#else                dma_alloc_coherent (NULL, tffsInfo.dma_buf_size,                                          &tffsInfo.dma_buf_paddr, (GFP_KERNEL | GFP_DMA));#endif            if (tffsInfo.dma_buf_vptr == NULL)            {                /* failed to allocate intermediate DMA buffer, won't use DMA */                tffs_dma_mode = 0;                omap_free_dma (dma_regs);                dma_regs = NULL;                tffsInfo.dma_buf_size = 0;                PrintkError ("can't alloc DMA buffer");            }

⌨️ 快捷键说明

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