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

📄 x

📁 omap3 linux 2.6 用nocc去除了冗余代码
💻
📖 第 1 页 / 共 3 页
字号:
+	//host->params.ie =+	host->params.read_prio = DMA_CH_PRIO_HIGH;+	host->params.src_ei = 0;+	host->params.src_fi = 0;+	host->params.src_port = 0;+	host->params.sync_mode = OMAP_DMA_SYNC_FRAME;+	host->params.write_prio = DMA_CH_PRIO_HIGH;+  	if (!(data->flags & MMC_DATA_WRITE)) { 		host->dma_dir = DMA_FROM_DEVICE;@@ -1233,42 +1843,102 @@ mmc_omap_start_dma_transfer(struct mmc_o 			sync_dev = OMAP24XX_DMA_MMC1_RX; 		else 			sync_dev = OMAP24XX_DMA_MMC2_RX;++		host->params.dst_amode = OMAP_DMA_AMODE_POST_INC;+		host->params.dst_start = sg_dma_address(&data->sg[host->sg_idx]);++		host->params.frame_count = count;++		host->params.src_amode = OMAP_DMA_AMODE_CONSTANT;+		host->params.src_or_dst_synch = OMAP_DMA_SRC_SYNC;+		host->params.src_start = (dma_addr_t) (host->mapbase +OMAP_HSMMC_DATA);++		host->params.trigger = sync_dev; 	} else { 		host->dma_dir = DMA_TO_DEVICE; 		if (host->id == OMAP_MMC1_DEVID) 			sync_dev = OMAP24XX_DMA_MMC1_TX; 		else 			sync_dev = OMAP24XX_DMA_MMC2_TX;++		host->params.dst_amode = OMAP_DMA_AMODE_CONSTANT;+		host->params.dst_start = (dma_addr_t) (host->mapbase + OMAP_HSMMC_DATA);++		host->params.frame_count = count;++		host->params.src_amode = OMAP_DMA_AMODE_POST_INC;+		host->params.src_or_dst_synch = OMAP_DMA_DST_SYNC;+		host->params.src_start = sg_dma_address(&data->sg[host->sg_idx]);++		host->params.trigger = sync_dev; 	} -	ret = omap_request_dma(sync_dev, "MMC/SD", mmc_omap_dma_cb, host,-						&dma_ch);+	/* Request a DMA chain for transfer+	 * A chain is requested before each transfer to avoid+	 * locking of DMA resources+	 */+	ret = omap_request_dma_chain(sync_dev, "MMC/SD", mmc_omap_dma_cb,+							&dma_chid, host->chains_requested,+							OMAP_DMA_DYNAMIC_CHAIN, host->params); 	if (ret != 0) { 		dev_dbg(mmc_dev(host->mmc),-			"%s: omap_request_dma() failed with %d\n",+			"%s: omap_request_dma_chain() failed with %d\n", 			mmc_hostname(host->mmc), ret); 		return ret; 	}+	else+	{+		if(host->chains_requested > 1)+		omap_dma_set_interrupt_ch(dma_chid, OMAP_DMA_DROP_IRQ |+						 OMAP2_DMA_MISALIGNED_ERR_IRQ |+						 OMAP2_DMA_TRANS_ERR_IRQ,+						 OMAP_DMA_DROP_IRQ |+						 OMAP_DMA_BLOCK_IRQ |+						 OMAP2_DMA_MISALIGNED_ERR_IRQ |+						 OMAP2_DMA_TRANS_ERR_IRQ);+	}+	host->chain_id = dma_chid;+	return 0;+} -	host->dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len,-								host->dma_dir);-	host->dma_ch = dma_ch; -	if (!(data->flags & MMC_DATA_WRITE)) {-		sync_dir = OMAP_DMA_SRC_SYNC;-		mmc_omap_config_dma_param(sync_dir, host, data);-	} else {-		sync_dir = OMAP_DMA_DST_SYNC;-		mmc_omap_config_dma_param(sync_dir, host, data);+static void mmc_chain_dma(struct mmc_omap_host *host, struct mmc_data *data)+{+	u16 frame;+	u32 count,i,dma_chain_status, sg_idx = host->sg_idx;+	struct scatterlist *sg;++	frame = data->blksz;+	for(i = host->sg_idx ;i < (host->chains_requested + sg_idx); i++)+	{+		sg = &data->sg[i];+		count = sg_dma_len(sg)/frame;+		host->sg_dma_len += (frame * count);+		if(!(data->flags & MMC_DATA_WRITE))+		{+			dma_chain_status = omap_dma_chain_a_transfer(host->chain_id,+			(dma_addr_t) (host->mapbase +OMAP_HSMMC_DATA),+			sg_dma_address(&data->sg[i]), (data->blksz / 4),+			count, host);+			if(dma_chain_status != 0)+				dev_dbg(mmc_dev(host->mmc),+					"%s: omap_dma_chain_a_transfer() failed during read with %d\n",+					mmc_hostname(host->mmc), dma_chain_status);+		}+		else+		{+			dma_chain_status = omap_dma_chain_a_transfer(host->chain_id,+			sg_dma_address(&data->sg[i]),+			(dma_addr_t) (host->mapbase + OMAP_HSMMC_DATA),+			(data->blksz / 4) ,count ,host);+			if(dma_chain_status != 0)+				dev_dbg(mmc_dev(host->mmc),+					"%s: omap_dma_chain_a_transfer() failed during write with %d\n",+					mmc_hostname(host->mmc), dma_chain_status);+		}+		host->sg_idx++; 	} -	omap_set_dma_transfer_params(dma_ch, OMAP_DMA_DATA_TYPE_S32,-					(data->blksz / 4), data->blocks,-					OMAP_DMA_SYNC_FRAME, sync_dev,-					sync_dir);--	omap_start_dma(dma_ch);-	return 0; }  /*@@ -1278,11 +1948,23 @@ mmc_omap_start_dma_transfer(struct mmc_o static int mmc_omap_prepare_data(struct mmc_omap_host *host, struct mmc_request *req) {-	int ret = 0;+	int use_dma;+	int i, block_size;+	unsigned sg_len;+	struct mmc_data *data = req->data;+	unsigned long flags;+ #ifdef CONFIG_OMAP_SDIO 	int byte_count = 0, func = 0;+	int ret = 0; #endif +	if(unlikely(host == NULL))+	{+		return -1;+	}++	/* Store the pointer for request */ 	host->data = req->data;  #ifdef CONFIG_OMAP_SDIO@@ -1313,7 +1995,7 @@ mmc_omap_prepare_data(struct mmc_omap_ho 					| (1 << 16)); 		} -#ifdef  CONFIG_OMAP_SDIO_NON_DMA_MODE+#ifdef	CONFIG_OMAP_SDIO_NON_DMA_MODE 		host->buffer = (u32 *) req->data->sdio_buffer_virt; #else 		if (polling_mode == 0) {@@ -1333,9 +2015,13 @@ mmc_omap_prepare_data(struct mmc_omap_ho 		return 0; 	} #endif	/* ifdef CONFIG_OMAP_SDIO */+	/* Enable DMA */+	host->use_dma = 1; 	if (req->data == NULL) { 		host->datadir = OMAP_MMC_DATADIR_NONE; 		OMAP_HSMMC_WRITE(host->base, BLK, BLK_CLEAR);+		/* Since there is nothing to DMA, clear the flag */+		host->use_dma = 0; 		return 0; 	} @@ -1343,17 +2029,69 @@ mmc_omap_prepare_data(struct mmc_omap_ho 	OMAP_HSMMC_WRITE(host->base, BLK, 					OMAP_HSMMC_READ(host->base, 					BLK) | (req->data->blocks << 16));+++	/* Copy the Block Size information */+	block_size = data->blksz;++	/* Cope with calling layer confusion; it issues "single+	 * block" writes using multi-block scatterlists.+	 */+	sg_len = (data->blocks == 1) ? 1 : data->sg_len;++	spin_lock_irqsave(&host->dma_lock, flags);+	if(sg_len > NO_OF_DMA_CHAINS_USED)+	{+		host->extra_chain_reqd = sg_len % NO_OF_DMA_CHAINS_USED;+		host->no_of_chain_reqd = sg_len / NO_OF_DMA_CHAINS_USED;+		host->chains_requested = NO_OF_DMA_CHAINS_USED;+		host->current_cb_cnt = 1;+	}+	else+	{+		host->extra_chain_reqd = 0;+		host->no_of_chain_reqd = 0;+		host->chains_requested = data->sg_len;+		host->current_cb_cnt = 0;+	}+	spin_unlock_irqrestore(&host->dma_lock, flags);++	/* Only do DMA for entire blocks */+	use_dma = host->use_dma;+	if (use_dma) {+		for (i = 0; i < sg_len; i++) {+			if ((data->sg[i].length % block_size) != 0) {+				use_dma = 0;+				break;+			}+		}+	} 	host->datadir = (req->data-> flags & MMC_DATA_WRITE) ? 			OMAP_MMC_DATADIR_WRITE : OMAP_MMC_DATADIR_READ;+	/* Initialize the internal scatter list count */+	host->sg_idx = 0;+	if (use_dma) {+		if (mmc_omap_get_dma_channel(host, data) == 0) {+			enum dma_data_direction dma_data_dir; -	if (host->use_dma) {-		ret = mmc_omap_start_dma_transfer(host, req);-		if (ret != 0) {-			dev_dbg(mmc_dev(host->mmc), "MMC start dma failure\n");-			return ret;-		} else {-			host->buffer = NULL;-			host->bytesleft = 0;+			if (data->flags & MMC_DATA_WRITE)+				dma_data_dir = DMA_TO_DEVICE;+			else+				dma_data_dir = DMA_FROM_DEVICE;++			host->sg_len = dma_map_sg(mmc_dev(host->mmc), data->sg,+						sg_len, dma_data_dir);+			host->total_bytes_left = 0;+			mmc_chain_dma(host, req->data);+			host->brs_received = 0;+			host->dma_done = 0;++			/* Enable DMA */+			host->use_dma = 1;+		}+		else+		{+			host->use_dma = 0; 		} 	} else { 		/* Revert to CPU copy */@@ -1362,6 +2100,7 @@ mmc_omap_prepare_data(struct mmc_omap_ho 				req->data->sg->offset); 		host->bytesleft = req->data->blocks * (req->data->blksz); 		host->dma_ch = -1;+		host->use_dma = 0; 	}  	return 0;@@ -1395,6 +2134,36 @@ static void omap_mmc_request(struct mmc_ 			"MMC host %s failed to initiate data transfer\n", 			mmc_hostname(host->mmc)); +	/* Start the DMA if DMA is needed */+	if (host->use_dma && (host->mmc->mode == MMC_MODE_MMC+			|| host->mmc->mode == MMC_MODE_SD))+	{+		omap_start_dma_chain_transfers(host->chain_id);+	}+	if(host->card_detected == 1)+	{+		if (host->mmc->mode == MMC_MODE_MMC ||+			host->mmc->mode == MMC_MODE_SD)+		{+			host->mmc->max_hw_segs = 128;+			host->mmc->max_phys_segs = 128;+			host->mmc->max_blk_size = 512;+			host->mmc->max_blk_count = 0xFFFF;+			host->mmc->max_req_size = host->mmc->max_blk_size * host->mmc->max_blk_count;+			host->mmc->max_seg_size = host->mmc->max_req_size;+			host->card_detected = 0;+		}+		else if(host->mmc->mode == MMC_MODE_SDIO)+		{+			host->mmc->max_hw_segs = 1;+			host->mmc->max_phys_segs = 1;+			host->mmc->max_seg_size = 1<<12;+			host->mmc->max_req_size = 1<<12;+			host->mmc->max_blk_size = 512;+			host->mmc->max_blk_count = 1<<12 / 512;+			host->card_detected = 0;+		}+	} 	mmc_clk_disable_aggressive(host);  	mmc_omap_start_command(host, req->cmd);@@ -1451,19 +2220,16 @@ static void omap_mmc_set_ios(struct mmc_  	switch (mmc->ios.bus_width) { 	case MMC_BUS_WIDTH_8:-		printk("MMC: Operating in 8 bit mode\n");-               	OMAP_HSMMC_WRITE(host->base, CON,+				OMAP_HSMMC_WRITE(host->base, CON, 			OMAP_HSMMC_READ(host->base,CON) 			| EIGHT_BIT); 		break; 	case MMC_BUS_WIDTH_4:-		printk("MMC: Operating in 4 bit mode\n"); 		OMAP_HSMMC_WRITE(host->base, HCTL, 			OMAP_HSMMC_READ(host->base,HCTL) 			| FOUR_BIT); 		break; 	case MMC_BUS_WIDTH_1:-		printk("MMC: Operating in 1 bit mode\n"); 		OMAP_HSMMC_WRITE(host->base, CON, 			OMAP_HSMMC_READ(host->base,CON) & ~EIGHT_BIT); 		OMAP_HSMMC_WRITE(host->base, HCTL,@@ -1475,10 +2241,10 @@ static void omap_mmc_set_ios(struct mmc_ 		if ((cpu_is_omap34xx() && is_sil_rev_less_than(OMAP3430_REV_ES2_0)) 			|| (cpu_is_omap2430() && omap2_cpu_rev() == 2)) { 			if ((OMAP_HSMMC_READ(host->base, HCTL) & SDVSDET) &&-		    		((ios->vdd == 7) || (ios->vdd == 8))) {+					((ios->vdd == 7) || (ios->vdd == 8))) { 				if (omap_mmc_switch_opcond(host, 0) != 0) 					dev_dbg(mmc_dev(host->mmc),-				       		"omap_mmc_set_ios:"+							"omap_mmc_set_ios:" 						"switch operation failed\n"); 				host->initstream = 0; 			}@@ -1529,7 +2295,7 @@ static struct mmc_host_ops mmc_omap_ops   */ static ssize_t sdio_polling_switch(struct device *dev, 				struct device_attribute *attr,-			   	const char *buf, size_t count)+				const char *buf, size_t count) { 	char cmd[25]; 	int i = 0;@@ -1611,9 +2377,20 @@ static int __init omap_mmc_probe(struct  	mmc->ops = &mmc_omap_ops; 	mmc->f_min = 400000; 	mmc->f_max = 52000000;+	mmc->mode = MMC_CARD_NONE;+	host->card_detected = 1;+	host->is_high_capacity = 0;+	host->flag_err = 0;+	host->cmd_12 = 0;+	host->cmd_13 = 0;+	host->crc_retry = 0;+ #ifdef CONFIG_OMAP_SDIO 	host->sdio_card_intr = 0; #endif+	spin_lock_init(&host->dma_lock);+	host->chain_id = -1;+	host->sg_dma_len = 0;  	if (cpu_is_omap2430()) { 		if (host->id == OMAP_MMC1_DEVID) {@@ -1660,7 +2437,7 @@ static int __init omap_mmc_probe(struct  			 */ 			if (IS_ERR(host->dbclk)) 				dev_dbg(mmc_dev(host->mmc),-			       		"Failed to get"+						"Failed to get" 					"debounce clock for MMC2\n"); 		} 	}@@ -1703,9 +2480,6 @@ static int __init omap_mmc_probe(struct  			dev_dbg(mmc_dev(host->mmc), 				"Failed to enable debounce clock for MMC%d\n", 				host->id);-	}--	if (cpu_is_omap2430()) { 		omap_writel(omap_readl(OMAP2_CONTROL_DEVCONF1) | MMC1_ACTIVE_OVERWRITE, 							OMAP2_CONTROL_DEVCONF1); 		if (minfo->wire4)@@ -1728,10 +2502,8 @@ static int __init omap_mmc_probe(struct  				if (cpu_is_omap3410()) { 					mmc->caps = MMC_CAP_4_BIT_DATA; 				}-				else {+				else 					mmc->caps = MMC_CAP_8_BIT_DATA;-					printk("\n Configuring for 8 BIT DATA -------------- \n");-				} 			}  			OMAP_HSMMC_WRITE(host->base, HCTL,@@ -1765,6 +2537,23 @@ static int __init omap_mmc_probe(struct  						HCTL) | SDVS18); 	} +	/* Use scatterlist DMA to reduce per-transfer costs.+	 * NOTE max_seg_size assumption that small blocks aren't+	 * normally used (except e.g. for reading SD registers).+	 */+	mmc->max_phys_segs = 128;		 /* Largest sized scatter list+									 * the driver could handle. Since this is+									 * managed by us in software, we can tune+									 * this value */+	mmc->max_hw_segs = 128; 		 /* Largest number of address/length+									 * pairs the host adapter can actually+									 * give at once to the device. This value+									 * should be kept same as scatter list	*/+	mmc->max_blk_size = 512;	   /* Block Length at max can be 1024 */+	mmc->max_blk_count = 0xFFFF;	/* No. of Blocks is 16 bits 			*/+	mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;+	mmc->max_seg_size = mmc->max_req_size;+ 	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;  	OMAP_HSMMC_WRITE(host->base, CAPA,OMAP_HSMMC_READ(host->base,@@ -1780,8 +2569,10 @@ static int __init omap_mmc_probe(struct  	OMAP_HSMMC_WRITE(host->base, HCTL, 			OMAP_HSMMC_READ(host->base, HCTL) | SDBP); -	if (machine_is_omap_2430sdp() || machine_is_omap_3430sdp()-	    || machine_is_omap_3430labrador() || machine_is_omap3_beagle() ) {+	if (machine_is_omap_2430sdp() ||+			machine_is_omap_3430sdp() ||+			machine_is_omap_3430labrador() ||+			machine_is_omap3evm()) { 		/* 		 * Create sysfs entries for enabling/disabling hotplug 		 * support for MMC cards@@ -1789,7 +2580,7 @@ static int __init omap_mmc_probe(struct  		if (device_create_file(&pdev->dev, 				&dev_attr_mmc_cover_switch) < 0) { 			dev_dbg(mmc_dev(host->mmc),-		       		"Unable to create sysfs"+					"Unable to create sysfs" 				"attribute for MMC1 cover switch\n"); 		} 		if (device_create_file(&pdev->dev,@@ -1818,8 +2609,10 @@ static int __init omap_mmc_probe(struct   	host->card_detect_irq = minfo->switch_pin; 	if (minfo->switch_pin >= 0) {-		if (machine_is_omap_2430sdp() || machine_is_omap_3430sdp()-		    || machine_is_omap_3430labrador() || machine_is_omap3_beagle()) {+		if (machine_is_omap_2430sdp() ||+					machine_is_omap_3430sdp() ||+					machine_is_omap_3430labrador() ||+					machine_is_omap3evm()) { 			host->card_detect_irq = 				TWL4030_GPIO_IRQ_NO(minfo->switch_pin); 			INIT_WORK(&host->mmc_carddetect_work, mmc_omap_detect);@@ -1943,8 +2736,10 @@ static int omap_mmc_suspend(struct platf 		/* Temporarily enabling the clocks for configuration */ 		mmc_clk_enable_aggressive(host); -		if (machine_is_omap_2430sdp() || machine_is_omap_3430sdp()-		    || machine_is_omap_3430labrador() || machine_is_omap3_beagle() ) {+		if (machine_is_omap_2430sdp() ||+					machine_is_omap_3430sdp() ||+					machine_is_omap_3430labrador() ||+					machine_is_omap3evm()) { 			disable_irq(host->card_detect_irq); 			ret = mask_carddetect_int(host->id); 			if (ret)@@ -1974,7 +2769,7 @@ static int omap_mmc_suspend(struct platf  		/* Clearing the STAT register*/ 		status = OMAP_HSMMC_READ(host->base, STAT);-	        OMAP_HSMMC_WRITE(host->base, STAT, status);+			OMAP_HSMMC_WRITE(host->base, STAT, status); 		/* disable clks for MMC1 */ 		mmc_clk_disable(host); @@ -2024,7 +2819,7 @@ static int omap_mmc_resume(struct platfo 		ret = mmc_omap_power(host,1); 		if (ret != 0) { 			dev_dbg(mmc_dev(host->mmc),-			       "Unable to enable power to MMC1\n");+				   "Unable to enable power to MMC1\n"); 			return ret; 		} @@ -2035,12 +2830,14 @@ static int omap_mmc_resume(struct platfo 		if (cpu_is_omap2430()) { 			if (clk_enable(host->dbclk) != 0) 				dev_dbg(mmc_dev(host->mmc),-		       			"Unable to enable debounce"+						"Unable to enable debounce" 					"clock for MMC1\n"); 		} -		if (machine_is_omap_2430sdp() || machine_is_omap_3430sdp()-		    || machine_is_omap_3430labrador() || machine_is_omap3_beagle() ) {+		if (machine_is_omap_2430sdp() ||+					machine_is_omap_3430sdp() ||+					machine_is_omap_3430labrador() ||+					machine_is_omap3evm()) { 			enable_irq(host->card_detect_irq); 			ret = unmask_carddetect_int(host->id); 			if (ret)@@ -2101,7 +2898,7 @@ omap_mmc_pre_scale(int slot, struct noti  static int omap_mmc_post_scale(int slot, struct notifier_block *op, unsigned long level,-		    void *ptr)+			void *ptr) { 	struct mmc_omap_host *host = (slot == MMC1) ? saved_host1 : saved_host2; 

⌨️ 快捷键说明

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