[coreboot-gerrit] New patch to review for coreboot: mediatek/mt8173: add NOR DMA read

Patrick Georgi (pgeorgi@google.com) gerrit at coreboot.org
Tue Mar 8 22:35:36 CET 2016


Patrick Georgi (pgeorgi at google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/13979

-gerrit

commit 606e596968e28d6f236cf6df6dee91c67cd54048
Author: Bayi Cheng <bayi.cheng at mediatek.com>
Date:   Thu Jan 21 21:48:37 2016 +0800

    mediatek/mt8173: add NOR DMA read
    
    BRANCH=none
    BUG=none
    TEST=boot oak to kernel on rev2
    
    Change-Id: I368fcac1cf5e2261d00a34882a7341733ebd0732
    Signed-off-by: Patrick Georgi <pgeorgi at chromium.org>
    Original-Commit-Id: 6ea0407f7273bc88613bc23a6fc4c41f9cca1adb
    Original-Change-Id: Ic422e7265fdd35c573d8cd44280a1f7dc163a6db
    Original-Signed-off-by: Bayi Cheng <bayi.cheng at mediatek.com>
    Original-Reviewed-on: https://chromium-review.googlesource.com/323932
    Original-Commit-Ready: Yidi Lin <yidi.lin at mediatek.com>
    Original-Tested-by: Yidi Lin <yidi.lin at mediatek.com>
    Original-Reviewed-by: Julius Werner <jwerner at chromium.org>
---
 src/soc/mediatek/mt8173/flash_controller.c         | 60 ++++++++++++++++++++--
 .../mediatek/mt8173/include/soc/flash_controller.h | 15 +++++-
 2 files changed, 70 insertions(+), 5 deletions(-)

diff --git a/src/soc/mediatek/mt8173/flash_controller.c b/src/soc/mediatek/mt8173/flash_controller.c
index 3cd81a2..f662916 100644
--- a/src/soc/mediatek/mt8173/flash_controller.c
+++ b/src/soc/mediatek/mt8173/flash_controller.c
@@ -23,6 +23,7 @@
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
+#include <symbols.h>
 #include <timer.h>
 #include <soc/flash_controller.h>
 
@@ -111,21 +112,74 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len)
 	return min(65535, buf_len);
 }
 
-static int nor_read(struct spi_flash *flash, u32 addr, size_t len, void *buf)
+static int dma_read(u32 addr, u8 *buf, u32 len)
 {
-	u8 *buffer = (u8 *)buf;
+	struct stopwatch sw;
+
+	assert(IS_ALIGNED((uintptr_t)buf, SFLASH_DMA_ALIGN) &&
+	       IS_ALIGNED(len, SFLASH_DMA_ALIGN) &&
+	       len <= _dma_coherent_size);
+
+	/* do dma reset */
+	write32(&mt8173_nor->fdma_ctl, SFLASH_DMA_SW_RESET);
+	write32(&mt8173_nor->fdma_ctl, SFLASH_DMA_WDLE_EN);
+	/* flash source address and dram dest address */
+	write32(&mt8173_nor->fdma_fadr, addr);
+	write32(&mt8173_nor->fdma_dadr, ((uintptr_t)_dma_coherent ));
+	write32(&mt8173_nor->fdma_end_dadr, ((uintptr_t)_dma_coherent + len));
+	/* start dma */
+	write32(&mt8173_nor->fdma_ctl, SFLASH_DMA_TRIGGER | SFLASH_DMA_WDLE_EN);
+
+	stopwatch_init_usecs_expire(&sw, SFLASH_POLLINGREG_US);
+	while ((read32(&mt8173_nor->fdma_ctl) & SFLASH_DMA_TRIGGER) != 0) {
+		if (stopwatch_expired(&sw)) {
+			printk(BIOS_WARNING, "dma read timeout!\n");
+			return -1;
+		}
+	}
+
+	memcpy(buf, _dma_coherent, len);
+	return 0;
+}
 
+static int pio_read(u32 addr, u8 *buf, u32 len)
+{
 	set_sfpaddr(addr);
 	while (len) {
 		if (mt8173_nor_execute_cmd(SFLASH_RD_TRIGGER | SFLASH_AUTOINC))
 			return -1;
 
-		*buffer++ = read8(&mt8173_nor->rdata);
+		*buf++ = read8(&mt8173_nor->rdata);
 		len--;
 	}
 	return 0;
 }
 
+static int nor_read(struct spi_flash *flash, u32 addr, size_t len, void *buf)
+{
+	u32 next;
+
+	size_t done = 0;
+	if (!IS_ALIGNED((uintptr_t)buf, SFLASH_DMA_ALIGN)) {
+		next = MIN(ALIGN_UP((uintptr_t)buf, SFLASH_DMA_ALIGN) -
+			   (uintptr_t)buf, len);
+		if (pio_read(addr, buf, next))
+			return -1;
+		done += next;
+	}
+	while (len - done >= SFLASH_DMA_ALIGN) {
+		next = MIN(_dma_coherent_size, ALIGN_DOWN(len - done,
+			   SFLASH_DMA_ALIGN));
+		if (dma_read(addr + done, buf + done, next))
+			return -1;
+		done += next;
+	}
+	next = len - done;
+	if (next > 0 && pio_read(addr + done, buf + done, next))
+		return -1;
+	return 0;
+}
+
 static int nor_write(struct spi_flash *flash, u32 addr, size_t len,
 		       const void *buf)
 {
diff --git a/src/soc/mediatek/mt8173/include/soc/flash_controller.h b/src/soc/mediatek/mt8173/include/soc/flash_controller.h
index 2527d6b..1d2ac32 100644
--- a/src/soc/mediatek/mt8173/include/soc/flash_controller.h
+++ b/src/soc/mediatek/mt8173/include/soc/flash_controller.h
@@ -27,6 +27,7 @@ enum {
 	SFLASHNAME_LENGTH	  = 16,
 	SFLASH_WRITE_IN_PROGRESS  = 1,
 	SFLASH_COMMAND_ENABLE	  = 0x30,
+	SFLASH_DMA_ALIGN	  = 0x10,
 
 	/* NOR flash controller commands */
 	SFLASH_RD_TRIGGER	  = 1 << 0,
@@ -38,7 +39,11 @@ enum {
 	/* NOR flash commands */
 	SFLASH_OP_WREN		  = 0x6,
 	SECTOR_ERASE_CMD	  = 0x20,
-	SFLASH_UNPROTECTED	  = 0x0
+	SFLASH_UNPROTECTED	  = 0x0,
+	/* DMA commands */
+	SFLASH_DMA_TRIGGER	  = 1 << 0,
+	SFLASH_DMA_SW_RESET	  = 1 << 1,
+	SFLASH_DMA_WDLE_EN	  = 1 << 2
 };
 
 /* register Offset */
@@ -72,8 +77,14 @@ struct mt8173_nor_regs {
 	u32 radr3;
 	u32 read_dual;
 	u32 delsel[3];
+	u32 reserved[397];
+	u32 cfg1_bri[2];
+	u32 fdma_ctl;
+	u32 fdma_fadr;
+	u32 fdma_dadr;
+	u32 fdma_end_dadr;
 };
-check_member(mt8173_nor_regs, delsel[2], 0xD8);
+check_member(mt8173_nor_regs, fdma_end_dadr, 0x724);
 static struct mt8173_nor_regs * const mt8173_nor = (void *)SFLASH_REG_BASE;
 
 struct spi_flash *mt8173_nor_flash_probe(struct spi_slave *spi);



More information about the coreboot-gerrit mailing list