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

📄 mmci.c

📁 dm320平台的LINUX mmc和sd卡驱动代码
💻 C
📖 第 1 页 / 共 3 页
字号:
                mrq->data->error = 0;                mrq->data->mrq = mrq;                if (mrq->stop) {                        mrq->data->stop = mrq->stop;                        mrq->stop->error = 0;                        mrq->stop->mrq = mrq;                }        }	host->data = mrq->data;        host->size = mrq->data->blocks << mrq->data->blksz_bits;        host->data_xfered = 0;	mmci_init_sg(host, mrq->data);		/*************WORKING******************/	/*	* Map the current scatter buffer.	20*/	it_mmcsd_get_status(&cmd);	it_mmcsd_clear_response_reg(&cmd);	current_add = mrq->cmd->arg;        no_of_blks = mrq->data->blocks;	do{	 unsigned long flags;         unsigned int remain, len = 0;         char *buffer = NULL;	short *buffer_short = NULL;	short stop_status = 0;	short store_DMASEL;	buffer = mmci_kmap_atomic(host, &flags) + host->sg_off;	if (buffer == NULL)                mmc_debug_msg ("NULL data Pointer\n");	remain = host->sg_ptr->length - host->sg_off;	mmc_debug_msg ("WRITE_REMAIN : %d\n",remain);	        outw((remain/512),IO_MMC_NR_BLOCKS);		buffer_short = (short*)buffer;#ifdef DMA_TRANSFER	 /* bring the sd/mmc controller to idle state */        reg = inw(IO_MMC_CONTROL);        outw(reg | 0x03,IO_MMC_CONTROL);        reg = inw(IO_MMC_CONTROL);        outw(((inw(IO_MMC_CONTROL) | 0x10)&0xFBFF),IO_MMC_CONTROL);        /* release idle state */        reg = inw(IO_MMC_CONTROL);        outw(reg & 0xFFFC,IO_MMC_CONTROL);        reg = inw(IO_MMC_CONTROL);        outw(((0xDFFF) & inw (IO_MMC_SD_DMA_MODE)),IO_MMC_SD_DMA_MODE);//Enabling DMA        wmb();        outw((0x0002),IO_MMC_SD_DMA_TRIGGER);//DMA break        wmb();        outw ((0x0003),IO_SDRAM_SDDMASEL);        //printk("Started writing %x blocks from the address %x\n",no_of_blks,current_add);        //outw(no_of_blks,IO_MMC_NR_BLOCKS);        wmb();        store_DMASEL = inw (IO_SDRAM_SDDMASEL);        rmb();        reg = store_DMASEL;        //printk ("Value in IO_SDRAM_SDDMASEL : %x\n",reg);        outw(((1 << 12) | inw (IO_MMC_SD_DMA_MODE)),IO_MMC_SD_DMA_MODE);//DIRECTION        //outw((0x0400 | inw (IO_MMC_SD_DMA_MODE)),IO_MMC_SD_DMA_MODE);//Enable word swap for Reading        outw((0xF000),IO_MMC_SD_DMA_TIMEOUT); //2.4576ms //TIMEOUT        wmb();        //outw((no_of_blks * 512),0x04B0);        outw(remain,0x04B0);//DMA SIZE        outw(((unsigned long)buffer_short & 0xFFFF),IO_MMC_SD_DMA_ADDR_LOW);        wmb();        outw((((unsigned long)buffer_short >> 16) & 0xFFFF),IO_MMC_SD_DMA_ADDR_HI);        wmb();        outw(((0x2000) | inw (IO_MMC_SD_DMA_MODE)),IO_MMC_SD_DMA_MODE);	wmb();#endif		marg = current_add;	cmd1 = 25 |0x4000| 0x2000 |0x0800 | 0x0200 | 0x00;        outw(marg & 0xFFFF,IO_MMC_ARG_LOW);        outw((marg >> 16),IO_MMC_ARG_HI);        outw(cmd1,IO_MMC_COMMAND);	wmb();        write_count = 0;#ifndef DMA_TRANSFER		temp = 0;        it_mmcsd_get_status(&cmd);        reg = cmd.status0;	if ((cmd.status1 & 0x4))        {	write_data = *buffer_short;	buffer_short += 1;	mmc_debug_msg_rw ("%x,",(write_data)& 0xFF);	mmc_debug_msg_rw ("%x\t",((write_data >> 8) & 0xFF));	temp = (write_data & 0xFF00) >> 8;	write_data = ((write_data & 0xFF) << 8) | temp;	mmc_debug_msg ("***********in first condition**************\n");	        outw(write_data,IO_MMC_TX_DATA);        write_count += 1;        }        do 	          {			temp = 0;                        it_mmcsd_get_status(&cmd);                        reg = cmd.status0;                        if (reg & 0x0020)                                {                                        mmc_debug_msg ("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<Write CRC error\n");					mmc_debug_msg ("STATUS0 :%x\tSTATUS1 :%x\n",cmd.status0,cmd.status1);					host->data->error = MMC_ERR_BADCRC;						goto end_write;                                }                        if ((cmd.status1 & 0x4))                                {					write_data = *buffer_short;					mmc_debug_msg_rw ("%x,",(write_data)& 0xFF);					mmc_debug_msg_rw ("%x\t",((write_data >> 8) & 0xFF));     					temp = (write_data & 0xFF00) >> 8;				        write_data = ((write_data & 0xFF) << 8) | temp;					buffer_short += 1;	                                        outw(write_data,IO_MMC_TX_DATA);					wmb();                                        write_count += 1;                                }                            else{					if (cmd.status0 & 0x10){						mmc_debug_msg("Command Time OUT");						mmc_debug_msg ("S0 : %x\tS1 : %x\n",cmd.status0,cmd.status1);		                		break;					}			    }  		} while (!(reg &0x0001));        do{		it_mmcsd_get_status(&cmd);	}while((!(cmd.status0 & 0x2)) && (cmd.status1 & 0x1));#else	do         {                it_mmcsd_get_status(&cmd);		if (cmd.status0 & MMC_INT_RSP_TIMEOUT){                        host->data->error = 1;                        goto complete;                }         }while(!((cmd.status0 & 0x200)==0x200));//checking for respone of the command                //it_mmcsd_print_status(&cmd);                //printk ("Device Revision Number : %x\n",inw (IO_BUSC_REVR));                outw((0x0001),IO_MMC_SD_DMA_TRIGGER);                wmb();		reg = 0;                reg1 = 0;                do                {                        if (inw (IO_MMC_SD_DMA_STATUS1) & 0x1000){                                reg = 0x1000;                        }                        it_mmcsd_get_status(&cmd);                        if ((cmd.status0 & MMC_INT_RSP_TIMEOUT) |(cmd.status0 & MMC_INT_WRITE_CRC_ERROR)){                                host->data->error = 1;				outw((0x0002),IO_MMC_SD_DMA_TRIGGER);		                wmb();                                goto complete;                        }                }while((reg & 0x1000) && (!((cmd.status0 & 0x0100)==0x0100)));//Checking for DMA complete.                write_count = 0;                outw((0x0002),IO_MMC_SD_DMA_TRIGGER);                wmb();                //printk("bytes read : %d\n",(read_count*2));#if 0                for(i=0;i< (512*no_of_blks);i++){                        printk("%4c",*(buffer_short));                        buffer_short += 1;                }#endif#endif#ifndef DMA_TRANSFER	len = (write_count*2);#else	len = remain;#endif	mmc_debug_msg ("len : %d\n",len);	host->data_xfered += len;	/*        *Unmap the buffer.        */	mmci_kunmap_atomic(host, &flags);	host->sg_off += len;	host->size -= len;	remain -= len;	/*************WORKING******************/	/*Stop command*/	it_mmcsd_get_status(&cmd);		it_mmcsd_clear_response_reg(&cmd);	marg = 0;	cmd1 = 12 | 0x0200 | 0x0100 | 0x0080;	outw(marg & 0xFFFF,IO_MMC_ARG_LOW);	outw((marg >> 16),IO_MMC_ARG_HI);	outw(cmd1,IO_MMC_COMMAND);	stop_status = 0;	do	{		it_mmcsd_get_status(&cmd);		if (cmd.status0 & 0x4)				stop_status |= cmd.status0;			if (cmd.status0 & 0x2)			stop_status |= cmd.status0;		if (cmd.status0 & MMC_INT_RSP_TIMEOUT){                        host->data->error = 1;                        goto complete;                }	}while( !((stop_status& 0x6)==6));//checking for busy state and response of the command	if (remain){		break;	}	if (!mmci_next_sg(host)){		it_mmcsd_get_status(&cmd);			break;	}	current_add += len;		}while(1);		mrq->data->bytes_xfered = host->data_xfered;	mmc_debug_msg ("mrq->data->bytes_xfered : %d\n",mrq->data->bytes_xfered);complete:		/* enable clock */        reg = mmc_inw(IO_MMC_MEM_CLK_CONTROL);        mmc_outw(reg | 0x0100, IO_MMC_MEM_CLK_CONTROL);	local_irq_enable();	enable_interrupt();        spin_unlock(&host->lock);	host->data = NULL;	return 0;}int read_from_card(struct mmc_host *mmc,struct mmc_request *mrq){	u32 current_add;	u16 no_of_blks;	u32 marg;        u16 cmd1,reg;	int read_count;	struct mmc_command cmd;	struct mmci_host *host = mmc_priv(mmc);		spin_lock(&host->lock);	disable_interrupt();	local_irq_disable();		/* disable clock */        reg = inw(IO_MMC_MEM_CLK_CONTROL);	        outw(reg & 0xFEFF, IO_MMC_MEM_CLK_CONTROL);	rmb();		mrq->cmd->error = 0;        mrq->cmd->mrq = mrq;	host->cmd = mrq->cmd;        if (mrq->data) {                mrq->cmd->data = mrq->data;                mrq->data->error = 0;                mrq->data->mrq = mrq;                if (mrq->stop) {                        mrq->data->stop = mrq->stop;                        mrq->stop->error = 0;                        mrq->stop->mrq = mrq;                }        }	host->data = mrq->data;        host->size = mrq->data->blocks << mrq->data->blksz_bits;        host->data_xfered = 0;	mmci_init_sg(host, mrq->data);		/*************WORKING******************/	/*	* Map the current scatter buffer.	20*/	it_mmcsd_get_status(&cmd);	it_mmcsd_clear_response_reg(&cmd);	current_add = mrq->cmd->arg;        no_of_blks = mrq->data->blocks;// * host->sg_len; //To read more than segment	do{	 unsigned long flags;         unsigned int remain, len = 0;         char *buffer;	char *buffer_short = NULL;	short store_DMASEL = 0;	buffer = mmci_kmap_atomic(host, &flags) + host->sg_off;	if (buffer == NULL)                mmc_debug_msg ("NULL data Pointer\n");	remain = host->sg_ptr->length - host->sg_off;		mmc_debug_msg (">>>>>>>>>>>>REMAIN : %d\n",remain);        outw((remain/512),IO_MMC_NR_BLOCKS);	buffer_short = buffer;#ifdef DMA_TRANSFER	 /* bring the sd/mmc controller to idle state */        reg = inw(IO_MMC_CONTROL);        outw(reg | 0x03,IO_MMC_CONTROL);        reg = inw(IO_MMC_CONTROL);        outw(((inw(IO_MMC_CONTROL) | 0x10)&0xFDFF),IO_MMC_CONTROL);        /* release idle state */        reg = inw(IO_MMC_CONTROL);        outw(reg & 0xFFFC,IO_MMC_CONTROL);        reg = inw(IO_MMC_CONTROL);	outw(((0xDFFF) & inw (IO_MMC_SD_DMA_MODE)),IO_MMC_SD_DMA_MODE);        wmb();	outw((0x0002),IO_MMC_SD_DMA_TRIGGER);        wmb();	outw ((0x0003),IO_SDRAM_SDDMASEL);        //printk("Started Reading %x blocks from the address %x\n",no_of_blks,current_add);        //outw(no_of_blks,IO_MMC_NR_BLOCKS);        wmb();        store_DMASEL = inw (IO_SDRAM_SDDMASEL);        rmb();        reg = store_DMASEL;        //printk ("Value in IO_SDRAM_SDDMASEL : %x\n",reg);	outw(((0xEFFF) & inw (IO_MMC_SD_DMA_MODE)),IO_MMC_SD_DMA_MODE);			//outw((0x0400 | inw (IO_MMC_SD_DMA_MODE)),IO_MMC_SD_DMA_MODE);//Enable word swap for Reading		outw((0xF000),IO_MMC_SD_DMA_TIMEOUT); //2.4576ms	wmb();	//outw((no_of_blks * 512),0x04B0);	outw(remain,0x04B0);//DMA SIZE	outw(((unsigned long)buffer_short & 0xFFFF),IO_MMC_SD_DMA_ADDR_LOW);	wmb();	outw((((unsigned long)buffer_short >> 16) & 0xFFFF),IO_MMC_SD_DMA_ADDR_HI);	wmb();	outw(((0x2000) | inw (IO_MMC_SD_DMA_MODE)),IO_MMC_SD_DMA_MODE);	wmb();#endif        marg = current_add;        cmd1 = 18 | 0x0200 | 0x4000 | 0x2000 | 0x0080 | 0x0000;        outw(marg & 0xFFFF,IO_MMC_ARG_LOW);        outw((marg >> 16),IO_MMC_ARG_HI);        outw(cmd1,IO_MMC_COMMAND);	do        {		it_mmcsd_get_status(&cmd);		if ((cmd.status0 & MMC_INT_RSP_TIMEOUT) | (cmd.status0 & MMC_INT_RSP_CRC_ERROR)){                        host->data->error = 1;			goto complete_read;                }        }while( !((cmd.status0 & 0x4)==4));//checking for busy state and respone of the read command         read_count = 0;#ifndef DMA_TRANSFER        do{		it_mmcsd_get_status(&cmd);                reg = cmd.status0;                if (reg & 0x0040)                {                        mmc_debug_msg ("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<Read CRC error\n");			mmc_debug_msg ("STATUS0 :%x\tSTATUS1 :%x\n",cmd.status0,cmd.status1);                        break;                }                if ((cmd.status1 & 0x8))                {			temp_data = inw (IO_MMC_RX_DATA);			mmc_debug_msg_rw ("%x\t",temp_data);			*buffer_short = (temp_data >> 8) & 0xFF;			buffer_short = buffer_short + 1;			*buffer_short = temp_data & 0xFF;				buffer_short = buffer_short + 1;			read_count++;                }		else	                        if (cmd.status0 & 0x10){                        	mmc_debug_msg("Command Time OUT");                                break;		}	} while (!(reg &0x0001));	temp_data = inw (IO_MMC_RX_DATA);        mmc_debug_msg_rw ("%x\t",temp_data);        *buffer_short = (temp_data >> 8) & 0xFF;        buffer_short = buffer_short + 1;        *buffer_short = temp_data & 0xFF;        buffer_short = buffer_short + 1;        read_count++;        do{		it_mmcsd_get_status(&cmd);	}while((cmd.status1 & 0x1));	if(reg &1)	{		int temp = inw(IO_MMC_NR_BLOCKS_COUNT);		mmc_debug_msg ("No of blocks remaining to be transferd :%d\n",temp);	}#else         do         {		it_mmcsd_get_status(&cmd);		if (cmd.status0 & MMC_INT_RSP_TIMEOUT){                        host->data->error = 1;			goto complete_read;                }         }while(!((cmd.status0 & 0x400)==0x400));//checking for respone of the command                //it_mmcsd_print_status(&cmd);                //printk ("Device Revision Number : %x\n",inw (IO_BUSC_REVR));                outw((0x0001),IO_MMC_SD_DMA_TRIGGER);                wmb();#if 0                do                {                        reg = inw (IO_MMC_SD_DMA_STATUS1);                        rmb();                }while( (reg & 0x1000));//Checking for DMA complete.                read_count = 0;                do                {                        it_mmcsd_get_status(&cmd);                }while( !((cmd.status0 & 0x0100)==0x0100));//Checking for DMA Done#else		reg = 0;                do                {                        if (inw (IO_MMC_SD_DMA_STATUS1) & 0x1000){                                reg = 0x1000;                        }                        it_mmcsd_get_status(&cmd);                        if ((cmd.status0 & MMC_INT_READ_TIMEOUT) |(cmd.status0 & MMC_INT_READ_CRC_ERROR)){                                host->data->error = 1;				outw((0x0002),IO_MMC_SD_DMA_TRIGGER);                		wmb();				goto complete_read;                        }                }while((reg & 0x1000) && (!((cmd.status0 & 0x0100)==0x0100)));//Checking for DMA complete.#endif                outw((0x0002),IO_MMC_SD_DMA_TRIGGER);                wmb();                //printk("bytes read : %d\n",(read_count*2));#if 0                for(i=0;i< (512*no_of_blks);i++){                        printk("%4c",*(buffer_short));                        buffer_short += 1;                }#endif#endif#ifndef DMA_TRANSFER	len = buffer_short - buffer;#else	len = remain;#endif	mmc_debug_msg ("len : %d\n",len);	host->data_xfered += len;	/*        * Unmap the buffer.        */	mmci_kunmap_atomic(host, &flags);	buffer = NULL;	buffer_short = NULL ;	host->sg_off += len;	host->size -= len;	remain -= len;	/*************WORKING******************/	/*Stop command*/	it_mmcsd_get_status(&cmd);		it_mmcsd_clear_response_reg(&cmd);	marg = 0;	cmd1 = 12 | 0x0200 | 0x0100 | 0x0080;	outw(marg & 0xFFFF,IO_MMC_ARG_LOW);	outw((marg >> 16),IO_MMC_ARG_HI);	outw(cmd1,IO_MMC_COMMAND);	do	{		it_mmcsd_get_status(&cmd);			mmc_debug_msg("S0 : %x\t S1 : %x\n",cmd.status0,cmd.status1);		if ((cmd.status0 & MMC_INT_RSP_TIMEOUT) | (cmd.status0 & MMC_INT_RSP_CRC_ERROR)){                        host->data->error = 1;			goto complete_read;                }	}while( !((cmd.status0 & 0x4)==4));//checking for busy state and respone of the command	if (remain){				mmc_debug_msg ("REMAIN AFTER READ : %d\n",remain);	}	if (!mmci_next_sg(host)){		it_mmcsd_get_status(&cmd);			break;	}	current_add += len;		}while(1);		mrq->data->bytes_xfered = host->data_xfered;	mmc_debug_msg ("mrq->data->bytes_xfered : %d\n",mrq->data->bytes_xfered);complete_read:

⌨️ 快捷键说明

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