亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? dma-sa1111.c

?? MIZI Research, Inc.發布的嵌入式Linux內核源碼
?? C
字號:
/* *  linux/arch/arm/mach-sa1100/dma-sa1111.c * *  Copyright (C) 2000 John Dorsey * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License version 2 as *  published by the Free Software Foundation. * *  4 September 2000 - created. */#include <linux/module.h>#include <linux/init.h>#include <linux/sched.h>#include <linux/delay.h>#include <linux/spinlock.h>#include <linux/errno.h>#include <asm/system.h>#include <asm/irq.h>#include <asm/hardware.h>#include <asm/io.h>#include <asm/dma.h>#include <asm/hardware/sa1111.h>// #define DEBUG#ifdef DEBUG#define DPRINTK( s, arg... )  printk( "dma<%s>: " s, dma->device_id , ##arg )#else#define DPRINTK( x... )#endif/* * Control register structure for the SA1111 SAC DMA */typedef struct {	volatile u_long SAD_CS;	volatile dma_addr_t SAD_SA;	volatile u_long SAD_CA;	volatile dma_addr_t SAD_SB;	volatile u_long SAD_CB;} dma_regs_t;#include "dma.h"void sa1111_reset_sac_dma(dmach_t channel){	sa1100_dma_t *dma = &dma_chan[channel];	dma->regs->SAD_CS = 0;	mdelay(1);	dma->dma_a = dma->dma_b = 0;}int start_sa1111_sac_dma(sa1100_dma_t *dma, dma_addr_t dma_ptr, size_t size){  	dma_regs_t *sac_regs = dma->regs;	DPRINTK(" SAC DMA %cCS %02x at %08x (%d)\n",		(sac_regs==&SADTCS)?'T':'R', sac_regs->SAD_CS, dma_ptr, size);	/* The minimum transfer length requirement has not yet been	 * verified:	 */	if( size < SA1111_SAC_DMA_MIN_XFER )	  printk(KERN_WARNING "Warning: SAC xfers below %u bytes may be buggy!"		 " (%u bytes)\n", SA1111_SAC_DMA_MIN_XFER, size);	if( dma->dma_a && dma->dma_b ){	  	DPRINTK("  neither engine available! (A %d, B %d)\n",			dma->dma_a, dma->dma_b);	  	return -1;	}	if( sa1111_check_dma_bug(dma_ptr) )	  	printk(KERN_WARNING "Warning: DMA address %08x is buggy!\n",		       dma_ptr);	if( (dma->last_dma || dma->dma_b) && dma->dma_a == 0 ){	  	if( sac_regs->SAD_CS & SAD_CS_DBDB ){		  	DPRINTK("  awaiting \"done B\" interrupt, not starting\n");			return -1;		}		sac_regs->SAD_SA = SA1111_DMA_ADDR((u_int)dma_ptr);		sac_regs->SAD_CA = size;		sac_regs->SAD_CS = SAD_CS_DSTA | SAD_CS_DEN;		++dma->dma_a;		DPRINTK("  with A [%02lx %08lx %04lx]\n", sac_regs->SAD_CS,			sac_regs->SAD_SA, sac_regs->SAD_CA);	} else {	  	if( sac_regs->SAD_CS & SAD_CS_DBDA ){		  	DPRINTK("  awaiting \"done A\" interrupt, not starting\n");			return -1;		}		sac_regs->SAD_SB = SA1111_DMA_ADDR((u_int)dma_ptr);		sac_regs->SAD_CB = size;		sac_regs->SAD_CS = SAD_CS_DSTB | SAD_CS_DEN;		++dma->dma_b;		DPRINTK("  with B [%02lx %08lx %04lx]\n", sac_regs->SAD_CS,			sac_regs->SAD_SB, sac_regs->SAD_CB);	}	/* Additional delay to avoid DMA engine lockup during record: */	if( sac_regs == (dma_regs_t*)&SADRCS )	  	mdelay(1);	/* NP : wouuuh! ugly... */	return 0;}static void sa1111_sac_dma_irq(int irq, void *dev_id, struct pt_regs *regs){  	sa1100_dma_t *dma = (sa1100_dma_t *) dev_id;	DPRINTK("irq %d, last DMA serviced was %c, CS %02x\n", irq,		dma->last_dma?'B':'A', dma->regs->SAD_CS);	/* Occasionally, one of the DMA engines (A or B) will	 * lock up. We try to deal with this by quietly kicking	 * the control register for the afflicted transfer	 * direction.	 *	 * Note for the debugging-inclined: we currently aren't	 * properly flushing the DMA engines during channel	 * shutdown. A slight hiccup at the beginning of playback	 * after a channel has been stopped can be heard as	 * evidence of this. Programmatically, this shows up	 * as either a locked engine, or a spurious interrupt. -jd	 */	if(irq==AUDXMTDMADONEA || irq==AUDRCVDMADONEA){	  	if(dma->last_dma == 0){		  	DPRINTK("DMA B has locked up!\n");			dma->regs->SAD_CS = 0;			mdelay(1);			dma->dma_a = dma->dma_b = 0;		} else {		  	if(dma->dma_a == 0)			  	DPRINTK("spurious SAC IRQ %d\n", irq);			else {			  	--dma->dma_a;				/* Servicing the SAC DMA engines too quickly				 * after they issue a DONE interrupt causes				 * them to lock up.				 */				if(irq==AUDRCVDMADONEA || irq==AUDRCVDMADONEB)				  	mdelay(1);			}		}		dma->regs->SAD_CS = SAD_CS_DBDA | SAD_CS_DEN; /* w1c */		dma->last_dma = 0;	} else {	  	if(dma->last_dma == 1){		  	DPRINTK("DMA A has locked up!\n");			dma->regs->SAD_CS = 0;			mdelay(1);			dma->dma_a = dma->dma_b = 0;		} else {		  	if(dma->dma_b == 0)			  	DPRINTK("spurious SAC IRQ %d\n", irq);			else {			  	--dma->dma_b;				/* See lock-up note above. */				if(irq==AUDRCVDMADONEA || irq==AUDRCVDMADONEB)				  	mdelay(1);			}		}		dma->regs->SAD_CS = SAD_CS_DBDB | SAD_CS_DEN; /* w1c */		dma->last_dma = 1;	}	/* NP: maybe this shouldn't be called in all cases? */	sa1100_dma_done (dma);}int sa1111_sac_request_dma(dmach_t *channel, const char *device_id,			   unsigned int direction){	sa1100_dma_t *dma = NULL;	int ch, irq, err;	*channel = -1;		/* to be sure we catch the freeing of a misregistered channel */	ch = SA1111_SAC_DMA_BASE + direction;	if (!channel_is_sa1111_sac(ch)) {	  	printk(KERN_ERR "%s: invalid SA-1111 SAC DMA channel (%d)\n",		       device_id, ch);		return -1;	}	dma = &dma_chan[ch];	if (xchg(&dma->in_use, 1) == 1) {	  	printk(KERN_ERR "%s: SA-1111 SAC DMA channel %d in use\n",		       device_id, ch);		return -EBUSY;	}	irq = AUDXMTDMADONEA + direction;	err = request_irq(irq, sa1111_sac_dma_irq, SA_INTERRUPT,			  device_id, (void *) dma);	if (err) {		printk(KERN_ERR		       "%s: unable to request IRQ %d for DMA channel %d (A)\n",		       device_id, irq, ch);		dma->in_use = 0;		return err;	}	irq = AUDXMTDMADONEB + direction;	err = request_irq(irq, sa1111_sac_dma_irq, SA_INTERRUPT,			  device_id, (void *) dma);	if (err) {		printk(KERN_ERR		       "%s: unable to request IRQ %d for DMA channel %d (B)\n",		       device_id, irq, ch);		dma->in_use = 0;		return err;	}	*channel = ch;	dma->device_id = device_id;	dma->callback = NULL;	dma->spin_size = 0;	return 0;}/* FIXME:  need to complete the three following functions */int sa1111_dma_get_current(dmach_t channel, void **buf_id, dma_addr_t *addr){	sa1100_dma_t *dma = &dma_chan[channel];	int flags, ret;	local_irq_save(flags);	if (dma->curr && dma->spin_ref <= 0) {		dma_buf_t *buf = dma->curr;		if (buf_id)			*buf_id = buf->id;		/* not fully accurate but still... */		*addr = buf->dma_ptr;		ret = 0;	} else {		if (buf_id)			*buf_id = NULL;		*addr = 0;		ret = -ENXIO;	}	local_irq_restore(flags);	return ret;}int sa1111_dma_stop(dmach_t channel){	return 0;}int sa1111_dma_resume(dmach_t channel){	return 0;}void sa1111_cleanup_sac_dma(dmach_t channel){	sa1100_dma_t *dma = &dma_chan[channel];	free_irq(AUDXMTDMADONEA + (channel - SA1111_SAC_DMA_BASE), (void*) dma);	free_irq(AUDXMTDMADONEB + (channel - SA1111_SAC_DMA_BASE), (void*) dma);}/* According to the "Intel StrongARM SA-1111 Microprocessor Companion * Chip Specification Update" (June 2000), erratum #7, there is a * significant bug in Serial Audio Controller DMA. If the SAC is * accessing a region of memory above 1MB relative to the bank base, * it is important that address bit 10 _NOT_ be asserted. Depending * on the configuration of the RAM, bit 10 may correspond to one * of several different (processor-relative) address bits. * * This routine only identifies whether or not a given DMA address * is susceptible to the bug. */int sa1111_check_dma_bug(dma_addr_t addr){	unsigned int physaddr=SA1111_DMA_ADDR((unsigned int)addr);	/* Section 4.6 of the "Intel StrongARM SA-1111 Development Module	 * User's Guide" mentions that jumpers R51 and R52 control the	 * target of SA-1111 DMA (either SDRAM bank 0 on Assabet, or	 * SDRAM bank 1 on Neponset). The default configuration selects	 * Assabet, so any address in bank 1 is necessarily invalid.	 */	if((machine_is_assabet() || machine_is_pfs168()) && addr >= 0xc8000000)	  	return -1;	/* The bug only applies to buffers located more than one megabyte	 * above the start of the target bank:	 */	if(physaddr<(1<<20))	  	return 0;	switch(FExtr(SBI_SMCR, SMCR_DRAC)){	case 01: /* 10 row + bank address bits, A<20> must not be set */	  	if(physaddr & (1<<20))		  	return -1;		break;	case 02: /* 11 row + bank address bits, A<23> must not be set */	  	if(physaddr & (1<<23))		  	return -1;		break;	case 03: /* 12 row + bank address bits, A<24> must not be set */	  	if(physaddr & (1<<24))		  	return -1;		break;	case 04: /* 13 row + bank address bits, A<25> must not be set */	  	if(physaddr & (1<<25))		  	return -1;		break;	case 05: /* 14 row + bank address bits, A<20> must not be set */	  	if(physaddr & (1<<20))		  	return -1;		break;	case 06: /* 15 row + bank address bits, A<20> must not be set */	  	if(physaddr & (1<<20))		  	return -1;		break;	default:	  	printk(KERN_ERR "%s(): invalid SMCR DRAC value 0%lo\n",		       __FUNCTION__, FExtr(SBI_SMCR, SMCR_DRAC));		return -1;	}	return 0;}EXPORT_SYMBOL(sa1111_sac_request_dma);EXPORT_SYMBOL(sa1111_check_dma_bug);static int __init sa1111_init_sac_dma(void){	int channel = SA1111_SAC_DMA_BASE;	dma_chan[channel++].regs = (dma_regs_t *) &SADTCS;	dma_chan[channel++].regs = (dma_regs_t *) &SADRCS;	return 0;}__initcall(sa1111_init_sac_dma);

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产成人高清在线| 欧美色男人天堂| 欧美精品免费视频| 国产亚洲福利社区一区| 日韩黄色片在线观看| 99久久精品免费| 久久精品男人的天堂| 日本亚洲视频在线| 91国偷自产一区二区使用方法| 中文字幕精品综合| 国内不卡的二区三区中文字幕| 欧美乱妇15p| 亚洲精品日韩综合观看成人91| 国产福利一区二区三区视频| 欧美成人性福生活免费看| 亚洲国产欧美在线人成| 在线免费一区三区| 亚洲最大成人综合| 91在线国产福利| 中文幕一区二区三区久久蜜桃| 精品一区二区三区在线视频| 欧美一级片免费看| 日本成人在线网站| 欧美高清精品3d| 香蕉影视欧美成人| 欧美这里有精品| 亚洲超碰97人人做人人爱| 91国偷自产一区二区开放时间| 中文字幕欧美一| 91免费观看视频| 一区二区三区中文免费| 色婷婷久久久亚洲一区二区三区 | 日韩经典一区二区| 欧美性猛交一区二区三区精品| 亚洲综合免费观看高清完整版| 欧洲生活片亚洲生活在线观看| 一区二区三区国产精品| 欧美日韩1区2区| 激情久久五月天| 国产日韩视频一区二区三区| aaa欧美大片| 亚洲第一福利一区| 日韩免费观看高清完整版| 国产一区二区三区在线观看免费| 久久这里只有精品视频网| 国产九色sp调教91| 亚洲女厕所小便bbb| 欧美性高清videossexo| 婷婷国产在线综合| 精品91自产拍在线观看一区| 成人免费av在线| 亚洲一区国产视频| 精品捆绑美女sm三区| 成人综合日日夜夜| 亚洲精品成人天堂一二三| 欧美群妇大交群的观看方式| 国产一区二区三区久久久| 日韩久久一区二区| 制服丝袜亚洲网站| 国产精品主播直播| 亚洲午夜私人影院| 久久综合狠狠综合久久综合88| 99久久国产综合精品女不卡| 日韩高清不卡一区二区| 中文字幕免费观看一区| 777午夜精品免费视频| 国产91在线|亚洲| 青青草一区二区三区| 中国色在线观看另类| 欧美日韩国产一级| 国产99久久久国产精品免费看| 亚洲成人免费视频| 国产精品久久久久影院亚瑟| 日韩午夜在线观看| 99re6这里只有精品视频在线观看 99re8在线精品视频免费播放 | 性做久久久久久| 国产精品系列在线| 91精品国产综合久久福利| 99视频一区二区| 奇米亚洲午夜久久精品| 国产精品国产自产拍高清av王其| 91精品国产丝袜白色高跟鞋| 91蜜桃网址入口| 国产成人亚洲精品狼色在线| 日韩二区三区四区| 一区二区三区四区亚洲| 日本一区二区在线不卡| 欧美男女性生活在线直播观看| 99精品热视频| 国产成人精品在线看| 日本不卡的三区四区五区| 亚洲精品国产高清久久伦理二区| 久久久91精品国产一区二区精品| 91精品黄色片免费大全| 欧洲人成人精品| 97精品国产露脸对白| 国产成人精品亚洲午夜麻豆| 日韩av中文在线观看| 午夜久久久久久久久| 亚洲精品精品亚洲| 亚洲欧洲综合另类| 亚洲四区在线观看| 亚洲视频资源在线| 日韩伦理免费电影| 亚洲欧美国产77777| 亚洲日穴在线视频| 国产精品区一区二区三| 国产婷婷一区二区| 欧美国产精品久久| 久久久久久久久99精品| 欧美成人性战久久| 久久午夜老司机| 国产欧美一区二区精品婷婷| 久久男人中文字幕资源站| 久久综合色婷婷| 欧美激情在线看| 国产精品久久久久影院| 国产精品久久网站| 亚洲三级小视频| 亚洲成人黄色影院| 日韩精品成人一区二区在线| 青娱乐精品视频在线| 韩国理伦片一区二区三区在线播放 | 国产制服丝袜一区| 国内精品视频一区二区三区八戒| 韩国欧美国产1区| 成人免费毛片app| 色一情一伦一子一伦一区| 在线观看国产一区二区| 欧美剧情片在线观看| 欧美成人欧美edvon| 国产亚洲美州欧州综合国| 国产精品不卡视频| 香蕉久久一区二区不卡无毒影院 | 三级在线观看一区二区| 久久精品国产在热久久| 国产精品888| 91女厕偷拍女厕偷拍高清| 69堂国产成人免费视频| 久久精品一区二区三区不卡 | 一区二区在线看| 欧美aa在线视频| 成人黄色小视频| 欧美人体做爰大胆视频| 精品av综合导航| 亚洲激情中文1区| 狠狠色丁香九九婷婷综合五月| 成a人片亚洲日本久久| 欧美三区免费完整视频在线观看| 日韩女优毛片在线| 亚洲毛片av在线| 国产一区二区三区香蕉| 欧美午夜宅男影院| 久久亚洲精华国产精华液| 亚洲午夜久久久久久久久久久 | 欧美一区三区四区| 国产精品萝li| 久久国产欧美日韩精品| 欧美在线色视频| 26uuu精品一区二区 | 亚洲欧洲性图库| 精品亚洲免费视频| 在线免费观看视频一区| 国产人伦精品一区二区| 天天综合色天天综合| 北条麻妃国产九九精品视频| 日韩三级在线观看| 一区二区激情视频| gogo大胆日本视频一区| 久久综合给合久久狠狠狠97色69| 亚洲一卡二卡三卡四卡 | 国产精品亚洲一区二区三区在线| 日本久久一区二区| 中文字幕不卡一区| 精品亚洲欧美一区| 欧美一区二区黄色| 亚洲午夜久久久久久久久电影网| 精品在线观看免费| 日韩欧美一区中文| 午夜伊人狠狠久久| 欧洲视频一区二区| 亚洲欧美韩国综合色| 国产成人av电影在线播放| 欧美一区2区视频在线观看| 香港成人在线视频| 欧美视频在线一区| 中文字幕综合网| 91免费视频大全| 玉米视频成人免费看| 国产成人8x视频一区二区| 久久久久久久久久久黄色| 老色鬼精品视频在线观看播放| 欧美高清激情brazzers| 手机精品视频在线观看| 欧美日韩国产免费| 丝袜亚洲另类欧美| 91精品国产综合久久久蜜臀粉嫩| 亚洲一二三四区不卡| 欧美日韩一区二区三区免费看| 亚洲一区二区成人在线观看|