shithub: tpi

Download patch

ref: 65bf18d655db88faed69fdbc13a342500cef328a
parent: b9efa5bad11f7ada9416bab6f63ca4dd69b520c5
author: glenda <glenda@9front.local>
date: Sat Jun 25 19:44:54 EDT 2022

emmc diff file

--- a/v1/9/emmc.diff
+++ b/v1/9/emmc.diff
@@ -1,0 +1,235 @@
+diff 10afa189d5ee84e1935ead905b3bbe38060a92e8 uncommitted
+--- a//sys/src/9/bcm/emmc.c
++++ b//sys/src/9/bcm/emmc.c
+@@ -33,6 +33,7 @@
+ 
+ 	GoIdle		= 0,		/* mmc/sdio go idle state */
+ 	MMCSelect	= 7,		/* mmc/sd card select command */
++	Sendextcsd  = 8,		/* mmc ext_csd, sd send_if_cond */
+ 	Setbuswidth	= 6,		/* mmc/sd set bus width command */
+ 
+ 	Switchfunc	= 6,		/* mmc/sd switch function command */
+@@ -141,6 +142,7 @@
+ 
+ static int cmdinfo[64] = {
+ [0]  Ixchken,
++[1]  Resp48,
+ [2]  Resp136,
+ [3]  Resp48 | Ixchken | Crcchken,
+ [5]  Resp48,
+@@ -166,6 +168,7 @@
+ 
+ struct Ctlr {
+ 	Rendez	r;
++	Rendez	cardr;
+ 	int	fastclock;
+ 	ulong	extclk;
+ 	int	appcmd;
+@@ -303,6 +306,11 @@
+ 	 */
+ 	if(cmd == Switchfunc && !emmc.appcmd)
+ 		c |= Isdata|Card2host;
++	/*
++	 * CMD8 can be SD_SEND_IF_COND or SEND_EXT_CSD depending on arg
++	 */
++	if(cmd == Sendextcsd && arg == 0)
++		c |= Isdata|Card2host;
+ 	if(cmd == IORWextended){
+ 		if(arg & (1<<31))
+ 			c |= Host2card;
+@@ -318,8 +326,7 @@
+ 		WR(Control0, r[Control0] & ~(Dwidth4|Hispeed));
+ 		emmcclk(Initfreq);
+ 	}
+-	if((r[Status] & Datinhibit) &&
+-	   ((c & Isdata) || (c & Respmask) == Resp48busy)){
++	if(r[Status] & Cmdinhibit){
+ 		print("emmccmd: need to reset Cmdinhibit intr %ux stat %ux\n",
+ 			r[Interrupt], r[Status]);
+ 		WR(Control1, r[Control1] | Srstcmd);
+@@ -494,6 +501,8 @@
+ 	i = r[Interrupt];
+ 	if(i&(Datadone|Err))
+ 		wakeup(&emmc.r);
++	if(i&Cardintr)
++		wakeup(&emmc.cardr);
+ 	WR(Irpten, r[Irpten] & ~i);
+ }
+ 
+--- a//sys/src/9/port/sdmmc.c
++++ b//sys/src/9/port/sdmmc.c
+@@ -23,6 +23,8 @@
+ enum {
+ 	Inittimeout	= 15,
+ 	Multiblock	= 1,
++	MMC_TYPE_SD = 1,
++	MMC_TYPE_MMC = 2,
+ 
+ 	/* Commands */
+ 	GO_IDLE_STATE	= 0,
+@@ -31,6 +33,7 @@
+ 	SWITCH_FUNC	= 6,
+ 	SELECT_CARD	= 7,
+ 	SD_SEND_IF_COND	= 8,
++	SEND_EXT_CSD = 8,
+ 	SEND_CSD	= 9,
+ 	STOP_TRANSMISSION= 12,
+ 	SEND_STATUS	= 13,
+@@ -42,6 +45,7 @@
+ 	APP_CMD		= 55,	/* prefix for following app-specific commands */
+ 	SET_BUS_WIDTH	= 6,
+ 	SD_SEND_OP_COND	= 41,
++	MMC_SEND_OP_COND = 1,
+ 
+ 	/* Command arguments */
+ 	/* SD_SEND_IF_COND */
+@@ -81,8 +85,12 @@
+ 	u32int	csd[4];
+ 
+ 	int	retry;
++
++	uchar type;
+ };
+ 
++SDio *sdcardlink;
++
+ extern SDifc sdmmcifc;
+ extern SDio sdio;
+ 
+@@ -104,9 +112,14 @@
+ }
+ 
+ static void
+-identify(SDunit *unit, u32int *csd)
++identify(SDunit *unit)
+ {
+ 	uint csize, mult;
++	Ctlr *ctl = unit->dev->ctlr;
++	u32int *csd = ctl->csd;
++	SDio *io = ctl->io;                                                     
++	uchar ext_csd[512];
++	u32int r[4];
+ 
+ 	unit->secsize = 1 << CSD(83, 80);
+ 	switch(CSD(127, 126)){
+@@ -119,6 +132,22 @@
+ 		csize = CSD(69, 48);
+ 		unit->sectors = (csize+1) * 0x80000LL / unit->secsize;
+ 		break;
++	case 3:
++		if(CSD(125, 122) < 4) { /* no EXT_CSD */
++			print("sdmmc: no ext_csd\n");                           
++			break;
++		}
++		if(waserror()){
++			print("sdmmc: send_ext_csd error\n");
++			nexterror();
++		}
++		io->iosetup(0, ext_csd, 512, 1);
++		io->cmd(SEND_EXT_CSD, 0, r);
++		io->io(0, ext_csd, 512);
++		unit->sectors = ext_csd[212] | (ext_csd[213]<<8) |
++					(ext_csd[214]<<16) | (ext_csd[215]<<24);
++		poperror();
++		break;
+ 	}
+ 	if(unit->secsize == 1024){
+ 		unit->sectors <<= 1;
+@@ -132,7 +161,9 @@
+ 	SDev *sdev;
+ 	Ctlr *ctl;
+ 
+-	if(sdio.init() < 0)
++	if(sdcardlink == nil)
++		sdcardlink = &sdio;
++	if(sdcardlink->init() < 0)
+ 		return nil;
+ 	sdev = malloc(sizeof(SDev));
+ 	if(sdev == nil)
+@@ -147,7 +178,7 @@
+ 	sdev->nunit = 1;
+ 	sdev->ctlr = ctl;
+ 	ctl->dev = sdev;
+-	ctl->io = &sdio;
++	ctl->io = sdcardlink;
+ 	return sdev;
+ }
+ 
+@@ -213,20 +244,44 @@
+ 			hcs = Hcs;
+ 		poperror();
+ 	}
+-	for(i = 0; i < Inittimeout; i++){
+-		tsleep(&up->sleep, return0, nil, 100);
+-		io->cmd(APP_CMD, 0, r);
+-		io->cmd(SD_SEND_OP_COND, hcs|V3_3, r);
+-		if(r[0] & Powerup)
+-			break;
++	if(!waserror()){
++		for(i = 0; i < Inittimeout; i++){
++			tsleep(&up->sleep, return0, nil, 100);
++			io->cmd(APP_CMD, 0, r);
++			io->cmd(SD_SEND_OP_COND, hcs|V3_3, r);
++			if(r[0] & Powerup){
++				ctl->type = MMC_TYPE_SD;
++				break;
++			}
++		}
++		poperror();
++	}else{
++		io->cmd(GO_IDLE_STATE, 0, r);
++		ctl->ocr = (1 << 30);
++		for(i = 0; i < Inittimeout; i++){
++			tsleep(&up->sleep, return0, nil, 100);
++			io->cmd(MMC_SEND_OP_COND, ctl->ocr, r);
++			if(r[0] & Powerup){
++				ctl->type = MMC_TYPE_MMC;
++				break;
++			}
++			ctl->ocr = r[0] | (1 << 30);
++		}
+ 	}
++	if(ctl->type == 0)
++		return 3;
+ 	if(i == Inittimeout)
+ 		return 2;
+ 	ctl->ocr = r[0];
+ 	io->cmd(ALL_SEND_CID, 0, r);
+ 	memmove(ctl->cid, r, sizeof ctl->cid);
+-	io->cmd(SEND_RELATIVE_ADDR, 0, r);
+-	ctl->rca = r[0]>>16;
++	if(ctl->type == MMC_TYPE_SD){
++		io->cmd(SEND_RELATIVE_ADDR, 0, r);
++		ctl->rca = r[0]>>16;
++	}else if(ctl->type == MMC_TYPE_MMC){
++		ctl->rca = 1;
++		io->cmd(SEND_RELATIVE_ADDR, ctl->rca<<Rcashift, r);
++	}
+ 	io->cmd(SEND_CSD, ctl->rca<<Rcashift, r);
+ 	memmove(ctl->csd, r, sizeof ctl->csd);
+ 	return 1;
+@@ -275,15 +330,17 @@
+ 		poperror();
+ 		return 2;
+ 	}
+-	identify(unit, ctl->csd);
+ 	io->cmd(SELECT_CARD, ctl->rca<<Rcashift, r);
++	identify(unit);
+ 	io->cmd(SET_BLOCKLEN, unit->secsize, r);
+-	io->cmd(APP_CMD, ctl->rca<<Rcashift, r);
+-	io->cmd(SET_BUS_WIDTH, Width4, r);
+-	if(io->highspeed){
+-		if(!waserror()){
+-			mmcswitchfunc(io, Hispeed|Setfunc);
+-			poperror();
++	if(ctl->type == MMC_TYPE_SD){
++		io->cmd(APP_CMD, ctl->rca<<Rcashift, r);
++		io->cmd(SET_BUS_WIDTH, Width4, r);
++		if(io->highspeed){
++			if(!waserror()){
++				mmcswitchfunc(io, Hispeed|Setfunc);
++				poperror();
++			}
+ 		}
+ 	}
+ 	poperror();