📄 tffsarch.c
字号:
volatile u32 clnk; /* Channel Link Control */ volatile u32 cicr; /* Channel Interrupt Control Register */ volatile u32 csr; /* Channel Status Register */ volatile u32 csdp; /* Channel Source / Destination Parameters */ volatile u32 cen; /* Channel Element Number */ volatile u32 cfn; /* Channel Frame Number */ volatile u32 cssa; /* Channel Source Start Address */ volatile u32 cdsa; /* Channel Destination Start Address */ volatile u32 csei; /* Channel Source Element Index */ volatile u32 csfi; /* Channel Source Frame Index */ volatile u32 cdei; /* Channel Destination Element Index */ volatile u32 cdfi; /* Channel Destination Frame Index */ volatile u32 csac; /* Channel Source Address Counter */ volatile u32 cdac; /* Channel Destination Address Counter */ volatile u32 ccen; /* Channel Current Element Number */ volatile u32 ccfn; /* Channel Current Frame Number */} __dma_reg_t;/* * static routines for OMAP2420 */static void tffs_dma_init (int resume);static void tffs_dma_release (void);/* * static vars */static __dma_reg_t * dma_regs_vptr = NULL;void omap24xx_enable_gpio_irq (int gpio_irq, int enable){ register u32 gpio_line = gpio_irq - IH_GPIO_BASE; register u32 bit = OMAP_GPIO_BIT(gpio_line); register u32 base_reg = OMAP_GPIO_BASE_REG(gpio_line); unsigned int val = 0; if (enable == TRUE) { writel (bit, (base_reg + OMAP2420_GPIO_SET_IRQENABLE1)); __asm__ __volatile__("mcr p15, 0, %0, c7, c10, 4"::"r"(val)); /* memory barrier */ omap_set_gpio_edge_ctrl (gpio_line, OMAP_GPIO_LEVEL_LOW); } else { omap_set_gpio_edge_ctrl (gpio_line, 0); writel (bit, (base_reg + OMAP2420_GPIO_CLEAR_IRQENABLE1)); __asm__ __volatile__("mcr p15, 0, %0, c7, c10, 4"::"r"(val)); /* memory barrier */ writel (bit, (base_reg + OMAP2420_GPIO_IRQSTATUS1)); __asm__ __volatile__("mcr p15, 0, %0, c7, c10, 4"::"r"(val)); /* memory barrier */ }}/*-----------------------------------------------------------------------* * * * 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. For OMAP2420 (H4) board. * * * * Parameters: * * suspend FALSE (module initialization) or TRUE (power resume) * * * * Returns: * * always '1' (success) * * * *-----------------------------------------------------------------------*/unsigned char tffsarch_init (int resume){ register int tmp; char * vp; if ((vp = (char *)ioremap_nocache(OMAP2420_GPMC_BASE, PAGE_SIZE)) == NULL) { PrintkError ("ioremap_nocache failed"); } else { /* Configure Chip Select that DiskOnChip is connected to. * * NOTE. Code below configures Chip Select to set duration of * DiskOnChip access cycle to 65 nanosecond, which is * appropriate for the case when DiskOnChip is connected to * OMAP2420 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. */ tmp = (0 << 31) | /* synchronous wrapping burst not supported */ (0 << 30) | /* single access */ (0 << 29) | /* asynchronous read */ (0 << 28) | /* single access */ (0 << 27) | /* write asynchronous */ (0 << 25) | /* start access time at first rising edge of GPMC.CLK */ (0 << 23) | /* burst length 4 words */ (0 << 22) | /* wait pin not monitored for read access */ (0 << 21) | /* wait pin not monitored for write access */ (0 << 18) | /* wait pin is monitored with valid data */ (0 << 16) | /* wait input pin is WAIT0 */ (1 << 12) | /* 16-bit device */ (0 << 10) | /* NOR flash, pSRAM, or asynchronous device */ (1 << 9) | /* address/data multiplexed attached device */ (0 << 4) | /* x1 latencies */ (3 << 0); /* GPMC.CLK = GPMC_FCLK/4 */ writel (tmp /* 0x00001203 */, vp + GPMC_CONFIG1_CS2); tmp = (6 << 16) | /* nCS assertion time for write access */ (6 << 8) | /* nCS assertion time for read access */ (0 << 7) | /* nCS timing sygnal is not delayed */ (0 << 0); /* nCS assertion time */ writel (tmp /* 0x00060600 */, vp + GPMC_CONFIG2_CS2); tmp = (1 << 16) | /* nADV deassertion time for write access */ (1 << 8) | /* nADV deassertion time for read access */ (0 << 7) | /* nADV timing control sygnal is not delayed */ (0 << 0); /* nADV assertion time */ writel (tmp /* 0x00010100 */, vp + GPMC_CONFIG3_CS2); tmp = (5 << 24) | /* nWE deassertion time */ (0 << 23) | /* nWE timing control sygnal is not delayed */ (2 << 16) | /* nWE assertion time */ (6 << 8) | /* nOE deassertion time */ (0 << 7) | /* nOE timing control sygnal is not delayed */ (2 << 0); /* nOE assertion time */ writel (tmp /* 0x05020602 */, vp + GPMC_CONFIG4_CS2); tmp = (1 << 24) | /* delay between successive words in multiple access */ (5 << 16) | /* delay between start-cycle and first data valid */ (7 << 8) | /* total write cycle time in GPMC_FCLK cycles */ (7 << 0); /* total read cycle time in GPMC_FCLK cycles */ writel (tmp /* 0x01050707 */, vp + GPMC_CONFIG5_CS2); /* Map Chips Select CS2 at physical address 0x10000000 (as * specified by macro TFFS_PHYS_ADDR). */ tmp = 0x00000F50; writel (tmp, vp + GPMC_CONFIG7_CS2); iounmap (vp); } if (tffs_irq >= 0) { register int gpio_line = (tffs_irq - IH_GPIO_BASE); if( omap_request_gpio(gpio_line) == 0 ) { register u8 x = readb (OMAP24XX_VA_SYSTEM_CONTROL_BASE + 0x10c); /* set GPIO function (mux mode 3), disable pullup/pulldown */ x &= ~(MUXMODE_MASK); x |= 3; x &= ~(PULL_UD_ENABLE_MASK); writeb (x, OMAP24XX_VA_SYSTEM_CONTROL_BASE + 0x10c); /* configure this GPIO line as input */ omap_set_gpio_direction (gpio_line, TRUE); /* configure GPIO interrupt as level-low for this GPIO line */#if 0 omap_set_gpio_edge_ctrl (gpio_line, /* OMAP_GPIO_LEVEL_LOW */ OMAP_GPIO_FALLING_EDGE);#endif } else { PrintkWarning ("failed to get IRQ %d", tffs_irq); tffs_irq = -1; } } /* 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 (); } /* if IRQ was actually used, release respective GPIO resources */ if (tffs_irq >= 0) { register int gpio_line = (tffs_irq - IH_GPIO_BASE); omap_free_gpio (gpio_line); }}/*-----------------------------------------------------------------------* * * * 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. For OMAP2420 (H4) board. * * * * Parameters: * * suspend FALSE (module initialization) or TRUE (power resume) * * * *-----------------------------------------------------------------------*/static void tffs_dma_init (int resume){ register u32 tmp; int rc; 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. */ rc = omap_request_dma (0, TFFS_DEVICE_NAME, NULL, /* no callback when DMA completes */ NULL, /* data to pass to DMA callback */ &tffsInfo.channel); if ((rc != 0) || (tffsInfo.channel < 0) || (tffsInfo.channel >= OMAP24XX_LOGICAL_DMA_CH_COUNT)) { /* failed to allocate DMA channel, won't use DMA */ tffs_dma_mode = 0; PrintkError ("can't get DMA chan"); return; } else { PrintkInfo ("use DMA channel %d", tffsInfo.channel); /* virt. address of DMA channel's register set */ dma_regs_vptr = (__dma_reg_t *) (OMAP_DMA4_BASE + (0x60 * tffsInfo.channel) + 0x80); } } /* Channel Control Register */ tmp = (0 << 25) | /* buffering enabled */ (0 << 24) | /* destination triggers DMA request */ (1 << 23) | /* prefetch enabled */ (0 << 21) | /* secure mode disabled */ (0 << 19) | /* no synchronization */ (1 << 18) | /* block synchronization */ (0 << 17) | /* transaparent copy disabled */ (0 << 16) | /* constant fill disabled */ (1 << 14) | /* post-increment destination address */ (0 << 12) | /* constant source address */ (0 << 8) | /* ignore MSUSPEND */ (0 << 7) | /* channel disabled (stopped) */ (1 << 6) | /* high priority channel */ (0 << 5) | /* no frame synchronization */ (0 << 0); /* no synchronization (i.e. s/w DMA) */ writel (tmp, &dma_regs_vptr->ccr); /* Channel Frame Number Register. * We assume that frame consists of single element. */ writel (1, &dma_regs_vptr->cfn); /* Channel Interrupt Control Register. * Disable all interrupts - we will be polling DMA controller. */ tmp = /* OMAP_DMA_DROP_IRQ | */ /* synchronization drop */ /* OMAP_DMA_BLOCK_IRQ | */ /* end-of-block interrupt */ /* (1 << 11) | */ /* misaligned address error */ /* (1 << 8) | */ /* transaction error */ 0; writel (tmp, &dma_regs_vptr->cicr); /* Channel Status Register. * Write all-ones to clear any pending interrupts. */ writel (~0, &dma_regs_vptr->csr); if (resume == FALSE) { tffsInfo.dma_buf_vptr = NULL; tffsInfo.dma_buf_size = 0; if ((tffs_dma_mode >= 1)#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) || !defined(OMAP2420_DCACHE_BUG_WORKAROUND) && (tffs_dma_mode <= 3)#endif ) { /* allocate intermediate DMA buffer (we assume one MMU page
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -