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

📄 glamo-mmc.patch

📁 Uboot常用的移植patches, 方便定制移植到s3c2440
💻 PATCH
📖 第 1 页 / 共 3 页
字号:
+		goto done;++	/* enforce timeout */+	glamo_reg_write(0xfff, GLAMO_REGOFS_MMC + GLAMO_REG_MMC_TIMEOUT);+	/*+	 * spin+	 */+	while (!(glamo_reg_read(GLAMO_REG_IRQ_STATUS) & GLAMO_IRQ_MMC))+		;+	/* ack this interrupt source */+	glamo_reg_write(GLAMO_IRQ_MMC, GLAMO_REG_IRQ_CLEAR);++	if (status & GLAMO_STAT1_MMC_DTOUT)+		error = -1;+	if (status & (GLAMO_STAT1_MMC_BWERR | GLAMO_STAT1_MMC_BRERR))+		error = -2;+	if (status & GLAMO_STAT1_MMC_RTOUT)+		error = -5;+	if (error) {+		printf("cmd 0x%x, arg 0x%x flags 0x%x\n", opcode, arg, flags);+		printf("Error after resp: 0x%x\n", status);+		goto done;+	}+#if 0+	if (flags & MMC_DATA_READ) {+		volatile u8 * pu8 = (volatile u8 *)GLAMO_START_OF_MMC_INTMEM;+		for (n = 0; n < 512; n += 16) {+			int n1;+			for (n1 = 0; n1 < 16; n1++) {+				printf("%02X ", pu8[n + n1]);+			}+			printf("\n");+		}+	}+#endif+	return 0;++done:+	return error;+}++static void glamo_mci_reset(void)+{+	/* reset MMC controller */+	glamo_reg_write(GLAMO_CLOCK_MMC_RESET | GLAMO_CLOCK_MMC_DG_TCLK |+		   GLAMO_CLOCK_MMC_EN_TCLK | GLAMO_CLOCK_MMC_DG_M9CLK |+		   GLAMO_CLOCK_MMC_EN_M9CLK,+		  GLAMO_REG_CLOCK_MMC);+	udelay(100000);+	/* and disable reset */+	glamo_reg_write(GLAMO_CLOCK_MMC_DG_TCLK |+		   GLAMO_CLOCK_MMC_EN_TCLK | GLAMO_CLOCK_MMC_DG_M9CLK |+		   GLAMO_CLOCK_MMC_EN_M9CLK,+		   GLAMO_REG_CLOCK_MMC);+}+++static u_int8_t ldo_voltage(unsigned int millivolts)+{+	if (millivolts < 900)+		return 0;+	else if (millivolts > 3600)+		return 0x1f;++	millivolts -= 900;+	return millivolts / 100;+}++int mmc_read(ulong src, uchar *dst, int size)+{+	int resp;+	u8 response[16];+	int size_original = size;++	if ((!size) || (size & (MMC_BLOCK_SIZE - 1))) {+		printf("Bad size %d\n", size);+		return 0;+	}++	if (((int)dst) & 1) {+		printf("Bad align on dst\n");+		return 0;+	}++	resp = mmc_cmd(MMC_SET_BLOCKLEN, MMC_BLOCK_SIZE,+		       MMC_CMD_AC | MMC_RSP_R1, 0, 0, 0,+		       (u16 *)&response[0]);++	while (size) {+		switch (card_type) {+		case CARDTYPE_SDHC: /* block addressing */+			resp = mmc_cmd(MMC_READ_SINGLE_BLOCK,+				       src >> MMC_BLOCK_SIZE_BITS,+				       MMC_CMD_ADTC | MMC_RSP_R1 |+				       MMC_DATA_READ, MMC_BLOCK_SIZE, 1, 0,+				       (u16 *)&response[0]);+			break;+		default: /* byte addressing */+			resp = mmc_cmd(MMC_READ_SINGLE_BLOCK, src,+				MMC_CMD_ADTC | MMC_RSP_R1 | MMC_DATA_READ,+				MMC_BLOCK_SIZE, 1, 0,+				(u16 *)&response[0]);+			break;+		}+		do_pio_read((u16 *)dst, MMC_BLOCK_SIZE >> 1);++		if (size >= MMC_BLOCK_SIZE)+			size -= MMC_BLOCK_SIZE;+		else+			size = 0;+		dst += MMC_BLOCK_SIZE;+		src += MMC_BLOCK_SIZE;+	}+	return size_original;+}++int mmc_write(uchar *src, ulong dst, int size)+{+	int resp;+	u8 response[16];+	int size_original = size;++	if ((!size) || (size & (MMC_BLOCK_SIZE - 1))) {+		printf("Bad size %d\n", size);+		return 0;+	}++	if (((int)dst) & 1) {+		printf("Bad align on dst\n");+		return 0;+	}++	resp = mmc_cmd(MMC_SET_BLOCKLEN, MMC_BLOCK_SIZE,+		       MMC_CMD_AC | MMC_RSP_R1, 0, 0, 0,+		       (u16 *)&response[0]);++	while (size) {+		do_pio_write((u16 *)src, MMC_BLOCK_SIZE >> 1);+		switch (card_type) {+		case CARDTYPE_SDHC: /* block addressing */+			resp = mmc_cmd(MMC_WRITE_BLOCK,+				       dst >> MMC_BLOCK_SIZE_BITS,+				       MMC_CMD_ADTC | MMC_RSP_R1 |+								MMC_DATA_WRITE,+				       MMC_BLOCK_SIZE, 1, 0,+				       (u16 *)&response[0]);+			break;+		default: /* byte addressing */+			resp = mmc_cmd(MMC_WRITE_BLOCK, dst,+				       MMC_CMD_ADTC | MMC_RSP_R1 |+								MMC_DATA_WRITE,+				       MMC_BLOCK_SIZE, 1, 0,+				       (u16 *)&response[0]);+			break;+		}+		if (size >= MMC_BLOCK_SIZE)+			size -= MMC_BLOCK_SIZE;+		else+			size = 0;+		dst += MMC_BLOCK_SIZE;+		src += MMC_BLOCK_SIZE;+	}+	return size_original;+}++static void print_mmc_cid(mmc_cid_t *cid)+{+	printf("MMC found. Card desciption is:\n");+	printf("Manufacturer ID = %02x%02x%02x\n",+		cid->id[0], cid->id[1], cid->id[2]);+	printf("HW/FW Revision = %x %x\n",cid->hwrev, cid->fwrev);+	cid->hwrev = cid->fwrev = 0;	/* null terminate string */+	printf("Product Name = %s\n",cid->name);+	printf("Serial Number = %02x%02x%02x\n",+		cid->sn[0], cid->sn[1], cid->sn[2]);+	printf("Month = %d\n",cid->month);+	printf("Year = %d\n",1997 + cid->year);+}++static void print_sd_cid(const struct sd_cid *cid)+{+	printf("Card Type:          ");+	switch (card_type) {+	case CARDTYPE_NONE:+		printf("(None)\n");+		break;+	case CARDTYPE_MMC:+		printf("MMC\n");+		break;+	case CARDTYPE_SD:+		printf("SD\n");+		break;+	case CARDTYPE_SD20:+		printf("SD 2.0\n");+		break;+	case CARDTYPE_SDHC:+		printf("SD 2.0 SDHC\n");+		break;+	}+	printf("Manufacturer:       0x%02x, OEM \"%c%c\"\n",+	    cid->mid, cid->oid_0, cid->oid_1);+	printf("Product name:       \"%c%c%c%c%c\", revision %d.%d\n",+	    cid->pnm_0, cid->pnm_1, cid->pnm_2, cid->pnm_3, cid->pnm_4,+	    cid->prv >> 4, cid->prv & 15);+	printf("Serial number:      %u\n",+	    cid->psn_0 << 24 | cid->psn_1 << 16 | cid->psn_2 << 8 |+	    cid->psn_3);+	printf("Manufacturing date: %d/%d\n",+	    cid->mdt_1 & 15,+	    2000+((cid->mdt_0 & 15) << 4)+((cid->mdt_1 & 0xf0) >> 4));+/*	printf("CRC:                0x%02x, b0 = %d\n",+	    cid->crc >> 1, cid->crc & 1); */+}+++int mmc_init(int verbose)+{+ 	int retries = 14, rc = -ENODEV;+	int resp;+	u8 response[16];+	mmc_cid_t *mmc_cid = (mmc_cid_t *)response;+	struct sd_cid *sd_cid = (struct sd_cid *)response;+	u32 hcs = 0;++	card_type = CARDTYPE_NONE;++	/* enable engine */++	glamo_reg_write(GLAMO_CLOCK_MMC_EN_M9CLK |+			GLAMO_CLOCK_MMC_EN_TCLK |+			GLAMO_CLOCK_MMC_DG_M9CLK |+			GLAMO_CLOCK_MMC_DG_TCLK, GLAMO_REG_CLOCK_MMC);+	glamo_reg_write(glamo_reg_read(GLAMO_REG_HOSTBUS(2)) |+			GLAMO_HOSTBUS2_MMIO_EN_MMC, GLAMO_REG_HOSTBUS(2));++	/* controller reset */++	glamo_mci_reset();++	/* power the sdcard slot */++	pcf50633_reg_write(PCF50633_REG_HCLDOOUT, ldo_voltage(3300));+	udelay(10000);+	pcf50633_reg_write(PCF50633_REG_HCLDOOUT + 1,+		pcf50633_reg_read(PCF50633_REG_HCLDOOUT + 1) | 1); /* on */+	udelay(10000);++	/* start the clock -- slowly (50MHz / 250 == 195kHz */++	glamo_reg_write((glamo_reg_read(GLAMO_REG_CLOCK_GEN8) & 0xff00) | 250,+			 GLAMO_REG_CLOCK_GEN8);++	/* enable clock to divider input */++	glamo_reg_write(glamo_reg_read(+		GLAMO_REG_CLOCK_GEN5_1) | GLAMO_CLOCK_GEN51_EN_DIV_TCLK,+		GLAMO_REG_CLOCK_GEN5_1);++	udelay(100000);++	/* set bus width to 1 */++	glamo_reg_write((glamo_reg_read(GLAMO_REGOFS_MMC ++			 GLAMO_REG_MMC_BASIC) &+			 (~GLAMO_BASIC_MMC_EN_4BIT_DATA)),+					GLAMO_REGOFS_MMC + GLAMO_REG_MMC_BASIC);++	/* reset */++	resp = mmc_cmd(MMC_GO_IDLE_STATE, 0, MMC_CMD_BCR, 0, 0, 0,+		       (u16 *)&response[0]);++	udelay(100000);+	udelay(100000);+	udelay(100000);++	/* SDHC card? */++	resp = mmc_cmd(SD_SEND_IF_COND, 0x000001aa,+		MMC_CMD_BCR | MMC_RSP_R7, 0, 0, 0,+		(u16 *)&response[0]);+	if (!resp && (response[0] == 0xaa)) {+		card_type = CARDTYPE_SD20; /* 2.0 SD, may not be SDHC */+		hcs = 0x40000000;+	}++	/* Well, either way let's say hello in SD card protocol */++	while (retries--) {++		udelay(100000);++		resp = mmc_cmd(MMC_APP_CMD, 0x00000000,+			MMC_CMD_AC | MMC_RSP_R1, 0, 0, 0,+			(u16 *)&response[0]);+		if (resp)+			continue;+		resp = mmc_cmd(SD_APP_OP_COND, hcs | 0x00300000,+			MMC_CMD_BCR | MMC_RSP_R3, 0, 0, 0,+			(u16 *)&response[0]);+		if (resp)+			continue;++		if (response[3] & (1 << 6)) /* asserts block addressing */+			card_type = CARDTYPE_SDHC;++		if (response[3] & (1 << 7)) { /* not busy */+			if (card_type == CARDTYPE_NONE)+				card_type = CARDTYPE_SD;+			break;+		}+	}+	if (retries < 0)+		return 1;++	if (card_type == CARDTYPE_NONE) {+		retries = 10;+		printf("failed to detect SD Card, trying MMC\n");+		do {+			resp = mmc_cmd(MMC_SEND_OP_COND, 0x00ffc000,+				       MMC_CMD_BCR | MMC_RSP_R3, 0, 0, 0,+				       (u16 *)&response[0]);+			debug("resp %x %x\n", response[0], response[1]);+			udelay(50);+		} while (retries-- && !(response[3] & 0x80));+		if (retries >= 0)+			card_type = CARDTYPE_MMC;+		else+			return 1;+	}++	/* fill in device description */+	mmc_dev.if_type = IF_TYPE_MMC;+	mmc_dev.part_type = PART_TYPE_DOS;+	mmc_dev.dev = 0;+	mmc_dev.lun = 0;+	mmc_dev.type = 0;+	mmc_dev.removable = 0;+	mmc_dev.block_read = mmc_bread;+	mmc_dev.blksz = 512;+	mmc_dev.lba = 1 << 16; /* 64K x 512 blocks = 32MB default */++	/* try to get card id */+	resp = mmc_cmd(MMC_ALL_SEND_CID, hcs,+			MMC_CMD_BCR | MMC_RSP_R2, 0, 0, 0,+			(u16 *)&response[0]);+	if (resp)+		return 1;++	switch (card_type) {+	case CARDTYPE_MMC:+		/* TODO configure mmc driver depending on card+			attributes */++		if (verbose)+			print_mmc_cid(mmc_cid);+		sprintf((char *) mmc_dev.vendor,+			"Man %02x%02x%02x Snr %02x%02x%02x",

⌨️ 快捷键说明

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