* emmc support
@ 2020-10-18 4:52 Eli Cohen
0 siblings, 0 replies; only message in thread
From: Eli Cohen @ 2020-10-18 4:52 UTC (permalink / raw)
To: 9front
[-- Attachment #1: Type: text/plain, Size: 245 bytes --]
this patch adds support for the onboard MMC flash on the rpi compute
module 3+ instead of just SD cards on the CM3+ Lite
I modified pmmc.c in pc and emmc.c in zynq so they at least hopefully
don't break, they might support similar hardware now
[-- Attachment #2: emmc.diff --]
[-- Type: application/octet-stream, Size: 7159 bytes --]
diff -r 36b38b32b8b1 sys/src/9/bcm/emmc.c
--- a/sys/src/9/bcm/emmc.c Sat Oct 17 19:27:21 2020 -0700
+++ b/sys/src/9/bcm/emmc.c Sat Oct 17 21:44:11 2020 -0700
@@ -141,6 +141,7 @@
static int cmdinfo[64] = {
[0] Ixchken,
+[1] Resp48,
[2] Resp136,
[3] Resp48 | Ixchken | Crcchken,
[5] Resp48,
@@ -299,11 +300,17 @@
r = (u32int*)EMMCREGS;
assert(cmd < nelem(cmdinfo) && cmdinfo[cmd] != 0);
c = (cmd << Indexshift) | cmdinfo[cmd];
+ if(0)print("emmc: cmd%d %8.8ux arg %8.8ux\n", cmd, c, arg);
/*
* CMD6 may be Setbuswidth or Switchfunc depending on Appcmd prefix
*/
if(cmd == Switchfunc && !emmc.appcmd)
c |= Isdata|Card2host;
+ /*
+ * CMD8 can be SD_SEND_IF_COND or SEND_EXT_CSD depending on arg
+ */
+ if(cmd == 8 && arg == 0)
+ c |= Isdata|Card2host;
if(cmd == IORWextended){
if(arg & (1<<31))
c |= Host2card;
@@ -319,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);
@@ -352,7 +358,7 @@
break;
if((i&(Cmddone|Err)) != Cmddone){
if((i&~(Err|Cardintr)) != Ctoerr)
- print("emmc: cmd %ux arg %ux error intr %ux stat %ux\n", c, arg, i, r[Status]);
+ print("emmc: cmd%d %ux arg %ux error intr %ux stat %ux\n", cmd, c, arg, i, r[Status]);
WR(Interrupt, i);
if(r[Status]&Cmdinhibit){
WR(Control1, r[Control1]|Srstcmd);
diff -r 36b38b32b8b1 sys/src/9/bcm64/sdhc.c
--- a/sys/src/9/bcm64/sdhc.c Sat Oct 17 19:27:21 2020 -0700
+++ b/sys/src/9/bcm64/sdhc.c Sat Oct 17 21:44:11 2020 -0700
@@ -150,6 +150,7 @@
static int cmdinfo[64] = {
[0] Ixchken,
+[1] Resp48,
[2] Resp136,
[3] Resp48 | Ixchken | Crcchken,
[5] Resp48,
@@ -358,6 +359,8 @@
*/
if(cmd == Switchfunc && !emmc.appcmd)
c |= Isdata|Card2host;
+ if(cmd == 8 && arg == 0)
+ c |= Isdata|Card2host;
if(c & Isdata)
c |= Dmaen;
if(cmd == IORWextended){
diff -r 36b38b32b8b1 sys/src/9/pc/pmmc.c
--- a/sys/src/9/pc/pmmc.c Sat Oct 17 19:27:21 2020 -0700
+++ b/sys/src/9/pc/pmmc.c Sat Oct 17 21:44:11 2020 -0700
@@ -145,6 +145,7 @@
static int cmdinfo[64] = {
[0] Ixchken,
+[1] Resp48,
[2] Resp136,
[3] Resp48 | Ixchken | Crcchken,
[6] Resp48 | Ixchken | Crcchken,
@@ -424,6 +425,8 @@
error(Egreg);
mode = cmdinfo[cmd] >> 8;
cmd = (cmd << 8) | (cmdinfo[cmd] & 0xFF);
+ if((cmd >> 8) == 8 && arg == 0)
+ cmd |= Isdata|Card2host;
c = pmmc;
diff -r 36b38b32b8b1 sys/src/9/port/sdmmc.c
--- a/sys/src/9/port/sdmmc.c Sat Oct 17 19:27:21 2020 -0700
+++ b/sys/src/9/port/sdmmc.c Sat Oct 17 21:44:11 2020 -0700
@@ -23,6 +23,8 @@
enum {
Inittimeout = 15,
Multiblock = 1,
+ MMC_TYPE_MMC = 0,
+ MMC_TYPE_SD = 1,
/* 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 */
@@ -79,8 +83,12 @@
u32int ocr;
u32int cid[4];
u32int csd[4];
+ /* SD or MMC */
+ uchar type;
};
+SDio *sdcardlink;
+
extern SDifc sdmmcifc;
extern SDio sdio;
@@ -102,9 +110,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 *buf;
+ u32int r[4];
unit->secsize = 1 << CSD(83, 80);
switch(CSD(127, 126)){
@@ -117,11 +130,30 @@
csize = CSD(69, 48);
unit->sectors = (csize+1) * 0x80000LL / unit->secsize;
break;
+ case 3:
+ if(CSD(125, 122) < 4) { /* no EXT_CSD */
+ print("no ext_csd\n");
+ return;
+ }
+ buf = sdmalloc(512);
+ if(waserror()){
+ print("SEND_EXT_CSD error\n");
+ sdfree(buf);
+ nexterror();
+ }
+ io->iosetup(0, buf, 512, 1);
+ io->cmd(SEND_EXT_CSD, 0, r);
+ io->io(0, buf, 512);
+ unit->sectors = buf[212] | (buf[213]<<8) | (buf[214]<<16) | (buf[215]<<24);
+ sdfree(buf);
+ poperror();
+ break;
}
if(unit->secsize == 1024){
unit->sectors <<= 1;
unit->secsize = 512;
}
+ if(0)print("CSD version: %d, sectors: %llud, secsize: %lud\n", CSD(127, 126), unit->sectors, unit->secsize);
}
static SDev*
@@ -130,7 +162,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)
@@ -145,7 +179,7 @@
sdev->nunit = 1;
sdev->ctlr = ctl;
ctl->dev = sdev;
- ctl->io = &sdio;
+ ctl->io = sdcardlink;
return sdev;
}
@@ -225,12 +259,29 @@
hcs = Hcs;
poperror();
}
- for(i = 0; i < Inittimeout; i++){
- delay(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++){
+ delay(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++){
+ delay(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(i == Inittimeout){
print("sdmmc: card won't power up\n");
@@ -240,19 +291,26 @@
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{
+ 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);
- 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();
diff -r 36b38b32b8b1 sys/src/9/zynq/emmc.c
--- a/sys/src/9/zynq/emmc.c Sat Oct 17 19:27:21 2020 -0700
+++ b/sys/src/9/zynq/emmc.c Sat Oct 17 21:44:11 2020 -0700
@@ -118,6 +118,7 @@
static int cmdinfo[64] = {
[0] Ixchken,
+[1] Resp48,
[2] Resp136,
[3] Resp48 | Ixchken | Crcchken,
[6] Resp48 | Ixchken | Crcchken,
@@ -236,6 +237,8 @@
assert(cmd < nelem(cmdinfo) && cmdinfo[cmd] != 0);
c = (cmd << Indexshift) | cmdinfo[cmd];
+ if(cmd == 8 && arg == 0)
+ c |= Isdata|Card2host|Dmaen;
r = emmc.regs;
if(r[Status] & Cmdinhibit){
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2020-10-18 4:52 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-18 4:52 emmc support Eli Cohen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).