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

📄 glamo-mmc.patch

📁 Uboot常用的移植patches, 方便定制移植到s3c2440
💻 PATCH
📖 第 1 页 / 共 3 页
字号:
Index: u-boot/board/neo1973/gta02/Makefile===================================================================--- u-boot.orig/board/neo1973/gta02/Makefile+++ u-boot/board/neo1973/gta02/Makefile@@ -25,7 +25,7 @@  LIB	= lib$(BOARD).a -OBJS	:= gta02.o pcf50633.o nand.o nor.o ../common/cmd_neo1973.o \+OBJS	:= gta02.o pcf50633.o nand.o nor.o glamo-mmc.o ../common/cmd_neo1973.o \ 	   ../common/gsmver.o \ 	   ../common/jbt6k74.o ../common/udc.o ../common/bootmenu.o SOBJS	:= ../common/lowlevel_init.oIndex: u-boot/board/neo1973/gta02/glamo-mmc.c===================================================================--- /dev/null+++ u-boot/board/neo1973/gta02/glamo-mmc.c@@ -0,0 +1,828 @@+/*+ *  linux/drivers/mmc/host/glamo-mmc.c - Glamo MMC driver+ *+ *  Copyright (C) 2007 OpenMoko, Inc,  Andy Green <andy@openmoko.com>+ *  Based on the Glamo MCI driver that was -->+ *+ *  Copyright (C) 2007 OpenMoko, Inc,  Andy Green <andy@openmoko.com>+ *  Based on S3C MMC driver that was:+ *  Copyright (C) 2004-2006 maintech GmbH, Thomas Kleffel <tk@maintech.de>+ *+ *  and+ *+ *  Based on S3C MMC driver that was (original copyright notice ---->)+ *+ * (C) Copyright 2006 by OpenMoko, Inc.+ * Author: Harald Welte <laforge@openmoko.org>+ *+ * based on u-boot pxa MMC driver and linux/drivers/mmc/s3c2410mci.c+ * (C) 2005-2005 Thomas Kleffel+ *+ *  Copyright (C) 2004-2006 maintech GmbH, Thomas Kleffel <tk@maintech.de>+ *+ * 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.+ */++#include <config.h>+#include <common.h>+#include <mmc.h>+#include <asm/errno.h>+#include <asm/io.h>+#include <part.h>+#include <fat.h>+#include <pcf50633.h>++#include "glamo-regs.h"+#include "glamo-mmc.h"++#if defined(CONFIG_MMC) && defined(CONFIG_MMC_GLAMO)++#define MMC_BLOCK_SIZE_BITS 9+#define MMC_BLOCK_SIZE (1 << MMC_BLOCK_SIZE_BITS)++#define GLAMO_REG(x) (*(volatile u16 *)(CONFIG_GLAMO_BASE + x))+#define GLAMO_INTRAM_OFFSET (8 * 1024 * 1024)+#define GLAMO_FB_SIZE ((8 * 1024 * 1024) - 0x10000)+#define GLAMO_START_OF_MMC_INTMEM ((volatile u16 *)(CONFIG_GLAMO_BASE + \+				  GLAMO_INTRAM_OFFSET + GLAMO_FB_SIZE))++static int ccnt;+static block_dev_desc_t mmc_dev;+static mmc_csd_t mmc_csd;+static int mmc_ready = 0;+static int wide = 0;+static enum card_type card_type = CARDTYPE_NONE;++block_dev_desc_t * mmc_get_dev(int dev)+{+	return (block_dev_desc_t *)&mmc_dev;+}++static void+glamo_reg_write(u_int16_t val, u_int16_t reg)+{+	GLAMO_REG(reg) = val;+}++static u_int16_t+glamo_reg_read(u_int16_t reg)+{+	return GLAMO_REG(reg);+}++unsigned char CRC7(u8 * pu8, int cnt)+{+	u8 crc = 0;++	while (cnt--) {+		int n;+		u8 d = *pu8++;+		for (n = 0; n < 8; n++) {+			crc <<= 1;+			if ((d & 0x80) ^ (crc & 0x80))+				crc ^= 0x09;+			d <<= 1;+		}+	}+	return (crc << 1) | 1;+}++ulong mmc_bread(int dev_num, ulong blknr, ulong blkcnt, void *dst)+{+	ulong src = blknr * MMC_BLOCK_SIZE;++	if (!blkcnt)+		return 0;++/*	printf("mmc_bread(%d, %ld, %ld, %p)\n", dev_num, blknr, blkcnt, dst); */+	mmc_read(src, dst, blkcnt * MMC_BLOCK_SIZE);+	return blkcnt;+}++/* MMC_DEFAULT_RCA should probably be just 1, but this may break other code+   that expects it to be shifted. */+static u_int16_t rca = MMC_DEFAULT_RCA >> 16;++static void do_pio_read(u16 *buf, int count_words)+{+	volatile u16 *from_ptr = GLAMO_START_OF_MMC_INTMEM;++	while (count_words--)+		*buf++ = *from_ptr++;+}++static void do_pio_write(u16 *buf, int count_words)+{+	volatile u16 *to_ptr = GLAMO_START_OF_MMC_INTMEM;++	while (count_words--)+		*to_ptr++ = *buf++;+}+++static int mmc_cmd(int opcode, int arg, int flags,+		   int data_size, int data_blocks,+		   int will_stop, u16 *resp)+{+	u16 * pu16 = (u16 *)&resp[0];+	u16 * reg_resp = (u16 *)(CONFIG_GLAMO_BASE + GLAMO_REGOFS_MMC ++				 GLAMO_REG_MMC_CMD_RSP1);+	u16 status;+	int n;+	u8 u8a[6];+	u16 fire = 0;+	int cmd_is_stop = 0;+	int error = 0;++#if 0+	printf("mmc_cmd(opcode=%d, arg=0x%08X, flags=0x%x, "+	       "data_size=%d, data_blocks=%d, will_stop=%d, resp=%p)\n",+	       opcode, arg, flags, data_size, data_blocks, will_stop, resp);+#endif+	switch (opcode) {+	case MMC_STOP_TRANSMISSION:+		cmd_is_stop = 1;+		break;+	default:+		break;+	}++	ccnt++;++	 /* this guy has data to read/write? */+	if ((!cmd_is_stop) && (flags & (MMC_DATA_WRITE | MMC_DATA_READ))) {+		/*+		* the S-Media-internal RAM offset for our MMC buffer+		*/+		glamo_reg_write((u16)GLAMO_FB_SIZE,+			GLAMO_REGOFS_MMC + GLAMO_REG_MMC_WDATADS1);+		glamo_reg_write((u16)(GLAMO_FB_SIZE >> 16),+			GLAMO_REGOFS_MMC + GLAMO_REG_MMC_WDATADS2);+		glamo_reg_write((u16)GLAMO_FB_SIZE,+			GLAMO_REGOFS_MMC + GLAMO_REG_MMC_RDATADS1);+		glamo_reg_write((u16)(GLAMO_FB_SIZE >> 16),+			GLAMO_REGOFS_MMC + GLAMO_REG_MMC_RDATADS2);++		/* set up the block info */+		glamo_reg_write(data_size, GLAMO_REGOFS_MMC ++					   GLAMO_REG_MMC_DATBLKLEN);+		glamo_reg_write(data_blocks, GLAMO_REGOFS_MMC ++					     GLAMO_REG_MMC_DATBLKCNT);+	}++	/* if we can't do it, reject as busy */+	if (!glamo_reg_read(GLAMO_REGOFS_MMC + GLAMO_REG_MMC_RB_STAT1) &+	     GLAMO_STAT1_MMC_IDLE)+		return -1;++	/* create an array in wire order for CRC computation */+	u8a[0] = 0x40 | (opcode & 0x3f);+	u8a[1] = (arg >> 24);+	u8a[2] = (arg >> 16);+	u8a[3] = (arg >> 8);+	u8a[4] = arg;+	u8a[5] = CRC7(&u8a[0], 5); /* CRC7 on first 5 bytes of packet */++	/* issue the wire-order array including CRC in register order */+	glamo_reg_write((u8a[4] << 8) | u8a[5],+			GLAMO_REGOFS_MMC + GLAMO_REG_MMC_CMD_REG1);+	glamo_reg_write((u8a[2] << 8) | u8a[3],+			GLAMO_REGOFS_MMC + GLAMO_REG_MMC_CMD_REG2);+	glamo_reg_write((u8a[0] << 8) | u8a[1],+			GLAMO_REGOFS_MMC + GLAMO_REG_MMC_CMD_REG3);++	/* command index toggle */+	fire |= (ccnt & 1) << 12;++	/* set type of command */+	switch (mmc_cmd_type(flags)) {+	case MMC_CMD_BC:+		fire |= GLAMO_FIRE_MMC_CMDT_BNR;+		break;+	case MMC_CMD_BCR:+		fire |= GLAMO_FIRE_MMC_CMDT_BR;+		break;+	case MMC_CMD_AC:+		fire |= GLAMO_FIRE_MMC_CMDT_AND;+		break;+	case MMC_CMD_ADTC:+		fire |= GLAMO_FIRE_MMC_CMDT_AD;+		break;+	}+	/*+	 * if it expects a response, set the type expected+	 *+	 * R1, Length  : 48bit, Normal response+	 * R1b, Length : 48bit, same R1, but added card busy status+	 * R2, Length  : 136bit (really 128 bits with CRC snipped)+	 * R3, Length  : 48bit (OCR register value)+	 * R4, Length  : 48bit, SDIO_OP_CONDITION, Reverse SDIO Card+	 * R5, Length  : 48bit, IO_RW_DIRECTION, Reverse SDIO Card+	 * R6, Length  : 48bit (RCA register)+	 * R7, Length  : 48bit (interface condition, VHS(voltage supplied),+	 *                     check pattern, CRC7)+	 */+	switch (mmc_resp_type(flags)) {+	case MMC_RSP_R6: /* same index as R7 and R1 */+		fire |= GLAMO_FIRE_MMC_RSPT_R1;+		break;+	case MMC_RSP_R1B:+		fire |= GLAMO_FIRE_MMC_RSPT_R1b;+		break;+	case MMC_RSP_R2:+		fire |= GLAMO_FIRE_MMC_RSPT_R2;+		break;+	case MMC_RSP_R3:+		fire |= GLAMO_FIRE_MMC_RSPT_R3;+		break;+	/* R4 and R5 supported by chip not defined in linux/mmc/core.h (sdio) */+	}+	/*+	 * From the command index, set up the command class in the host ctrllr+	 *+	 * missing guys present on chip but couldn't figure out how to use yet:+	 *     0x0 "stream read"+	 *     0x9 "cancel running command"+	 */+	switch (opcode) {+	case MMC_READ_SINGLE_BLOCK:+		fire |= GLAMO_FIRE_MMC_CC_SBR; /* single block read */+		break;+	case MMC_SWITCH: /* 64 byte payload */+	case 0x33: /* observed issued by MCI */+	case MMC_READ_MULTIPLE_BLOCK:+		/* we will get an interrupt off this */+		if (!will_stop)+			/* multiblock no stop */+			fire |= GLAMO_FIRE_MMC_CC_MBRNS;+		else+			 /* multiblock with stop */+			fire |= GLAMO_FIRE_MMC_CC_MBRS;+		break;+	case MMC_WRITE_BLOCK:+		fire |= GLAMO_FIRE_MMC_CC_SBW; /* single block write */+		break;+	case MMC_WRITE_MULTIPLE_BLOCK:+		if (will_stop)+			 /* multiblock with stop */+			fire |= GLAMO_FIRE_MMC_CC_MBWS;+		else+			 /* multiblock NO stop-- 'RESERVED'? */+			fire |= GLAMO_FIRE_MMC_CC_MBWNS;+		break;+	case MMC_STOP_TRANSMISSION:+		fire |= GLAMO_FIRE_MMC_CC_STOP; /* STOP */+		break;+	default:+		fire |= GLAMO_FIRE_MMC_CC_BASIC; /* "basic command" */+		break;+	}+	/* enforce timeout */+	glamo_reg_write(0xfff, GLAMO_REGOFS_MMC + GLAMO_REG_MMC_TIMEOUT);++	/* Generate interrupt on txfer; drive strength max */+	glamo_reg_write((glamo_reg_read(GLAMO_REGOFS_MMC ++					GLAMO_REG_MMC_BASIC) & 0xfe) |+			 0x0800 | GLAMO_BASIC_MMC_NO_CLK_RD_WAIT |+			 GLAMO_BASIC_MMC_EN_COMPL_INT |+			 GLAMO_BASIC_MMC_EN_DR_STR0 |+			 GLAMO_BASIC_MMC_EN_DR_STR1,+			GLAMO_REGOFS_MMC + GLAMO_REG_MMC_BASIC);++	/* send the command out on the wire */+	/* dev_info(&host->pdev->dev, "Using FIRE %04X\n", fire); */+	glamo_reg_write(fire, GLAMO_REGOFS_MMC + GLAMO_REG_MMC_CMD_FIRE);++	/*+	 * we must spin until response is ready or timed out+	 * -- we don't get interrupts unless there is a bulk rx+	 */+	do+		status = glamo_reg_read(GLAMO_REGOFS_MMC ++					GLAMO_REG_MMC_RB_STAT1);+	while ((((status >> 15) & 1) != (ccnt & 1)) ||+		(!(status & (GLAMO_STAT1_MMC_RB_RRDY |+			     GLAMO_STAT1_MMC_RTOUT |+			     GLAMO_STAT1_MMC_DTOUT |+			     GLAMO_STAT1_MMC_BWERR |+			     GLAMO_STAT1_MMC_BRERR))));++	if (status & (GLAMO_STAT1_MMC_RTOUT | GLAMO_STAT1_MMC_DTOUT))+		error = -4;+	if (status & (GLAMO_STAT1_MMC_BWERR | GLAMO_STAT1_MMC_BRERR))+		error = -5;++	if (cmd_is_stop)+		return 0;++	if (error) {+		printf("cmd 0x%x, arg 0x%x flags 0x%x\n", opcode, arg, flags);+		printf("Error after cmd: 0x%x\n", error);+		goto done;+	}+	/*+	 * mangle the response registers in two different exciting+	 * undocumented ways discovered by trial and error+	 */+	if (mmc_resp_type(flags) == MMC_RSP_R2)+		/* grab the response */+		for (n = 0; n < 8; n++) /* super mangle power 1 */+			pu16[n ^ 6] = reg_resp[n];+	else+		for (n = 0; n < 3; n++) /* super mangle power 2 */+			pu16[n] = (reg_resp[n] >> 8) |+				  (reg_resp[n + 1] << 8);+	/*+	 * if we don't have bulk data to take care of, we're done+	 */+	if (!(flags & (MMC_DATA_READ | MMC_DATA_WRITE)))

⌨️ 快捷键说明

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