atmel_mci: Use 512 byte blocksize if possible

Instead of always using the largest blocksize the card supports, check
if it can support smaller block sizes and use 512 bytes if possible.
Most cards do support this, and other parts of u-boot seem to have
trouble with block sizes different from 512 bytes.

Also enable underrun/overrun protection.

Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
Acked-by: Hans-Christian Egtvedt <hcegtvedt@atmel.com>
diff --git a/cpu/at32ap/atmel_mci.c b/cpu/at32ap/atmel_mci.c
index 9f62c0f..bdca1c1 100644
--- a/cpu/at32ap/atmel_mci.c
+++ b/cpu/at32ap/atmel_mci.c
@@ -82,7 +82,9 @@
 
 	blklen &= 0xfffc;
 	mmci_writel(MR, (MMCI_BF(CLKDIV, clkdiv)
-			 | MMCI_BF(BLKLEN, blklen)));
+			 | MMCI_BF(BLKLEN, blklen)
+			 | MMCI_BIT(RDPROOF)
+			 | MMCI_BIT(WRPROOF)));
 }
 
 #define RESP_NO_CRC	1
@@ -225,7 +227,7 @@
 				*buffer++ = data;
 				wordcount++;
 			}
-		} while(wordcount < (512 / 4));
+		} while(wordcount < (mmc_blkdev.blksz / 4));
 
 		pr_debug("mmc: read %u words, waiting for BLKE\n", wordcount);
 
@@ -243,7 +245,7 @@
 
 fail:
 	mmc_cmd(MMC_CMD_SEND_STATUS, mmc_rca << 16, &card_status, R1 | NCR);
-	printf("mmc: bread failed, card status = ", card_status);
+	printf("mmc: bread failed, card status = %08x\n", card_status);
 	goto out;
 }
 
@@ -409,6 +411,7 @@
 {
 	struct mmc_cid cid;
 	struct mmc_csd csd;
+	unsigned int max_blksz;
 	int ret;
 
 	/* Initialize controller */
@@ -444,7 +447,17 @@
 		sizeof(mmc_blkdev.product));
 	sprintf((char *)mmc_blkdev.revision, "%x %x",
 		cid.prv >> 4, cid.prv & 0x0f);
-	mmc_blkdev.blksz = 1 << csd.read_bl_len;
+
+	/*
+	 * If we can't use 512 byte blocks, refuse to deal with the
+	 * card. Tons of code elsewhere seems to depend on this.
+	 */
+	max_blksz = 1 << csd.read_bl_len;
+	if (max_blksz < 512 || (max_blksz > 512 && !csd.read_bl_partial)) {
+		printf("Card does not support 512 byte reads, aborting.\n");
+		return -ENODEV;
+	}
+	mmc_blkdev.blksz = 512;
 	mmc_blkdev.lba = (csd.c_size + 1) * (1 << (csd.c_size_mult + 2));
 
 	mci_set_mode(CFG_MMC_CLK_PP, mmc_blkdev.blksz);
diff --git a/cpu/at32ap/atmel_mci.h b/cpu/at32ap/atmel_mci.h
index 0ffbc4f..5b4f5c9 100644
--- a/cpu/at32ap/atmel_mci.h
+++ b/cpu/at32ap/atmel_mci.h
@@ -57,6 +57,10 @@
 #define MMCI_CLKDIV_SIZE			8
 #define MMCI_PWSDIV_OFFSET			8
 #define MMCI_PWSDIV_SIZE			3
+#define MMCI_RDPROOF_OFFSET			11
+#define MMCI_RDPROOF_SIZE			1
+#define MMCI_WRPROOF_OFFSET			12
+#define MMCI_WRPROOF_SIZE			1
 #define MMCI_PDCPADV_OFFSET			14
 #define MMCI_PDCPADV_SIZE			1
 #define MMCI_PDCMODE_OFFSET			15