From 0bdfec85789f56167757a17a8dd18ca7418a51b3 Mon Sep 17 00:00:00 2001 From: Yidi Lin Date: Tue, 16 Feb 2016 20:42:10 +0800 Subject: mediatek/mt8173: memlayout: Create DRAM DMA region for NOR flash DMA read. NOR flash has a hardware limitation that it can't access SRAM region after 4GB mode is enabled. We add a DRAM DMA region after 0x40000000 for NOR flash driver. So that the NOR flash driver can use this region after 4GB mode is enabled. BRANCH=none BUG=chormoe-os-partner:49229 TEST=Boot to kernel on rev4 w/ 2GB ram and rev3 w/ 4GB ram. And check /proc/meminfo. Change-Id: I4a86f0028b26509589ec8d09e2d077920446ece1 Signed-off-by: Patrick Georgi Original-Commit-Id: dc61ec55187959101a9e891fe5e93928e9b8176e Original-Change-Id: Ifedc9e2dfba5d294297b3a28134997ac1dd38f94 Original-Signed-off-by: Yidi Lin Original-Reviewed-on: https://chromium-review.googlesource.com/327962 Original-Reviewed-by: Julius Werner Original-Reviewed-on: https://chromium-review.googlesource.com/331177 Original-Commit-Ready: Patrick Georgi Original-Tested-by: Patrick Georgi Reviewed-on: https://review.coreboot.org/13989 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer --- src/soc/mediatek/mt8173/flash_controller.c | 29 ++++++++++++++++------ src/soc/mediatek/mt8173/include/soc/memlayout.ld | 6 +++++ .../mediatek/mt8173/include/soc/mmu_operations.h | 4 +++ src/soc/mediatek/mt8173/mmu_operations.c | 2 ++ 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/soc/mediatek/mt8173/flash_controller.c b/src/soc/mediatek/mt8173/flash_controller.c index f66291661e..5d73f3aba2 100644 --- a/src/soc/mediatek/mt8173/flash_controller.c +++ b/src/soc/mediatek/mt8173/flash_controller.c @@ -26,6 +26,7 @@ #include #include #include +#include #define get_nth_byte(d, n) ((d >> (8 * n)) & 0xff) @@ -112,21 +113,22 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) return min(65535, buf_len); } -static int dma_read(u32 addr, u8 *buf, u32 len) +static int dma_read(u32 addr, u8 *buf, u32 len, uintptr_t dma_buf, + size_t dma_buf_len) { struct stopwatch sw; assert(IS_ALIGNED((uintptr_t)buf, SFLASH_DMA_ALIGN) && IS_ALIGNED(len, SFLASH_DMA_ALIGN) && - len <= _dma_coherent_size); + len <= dma_buf_len); /* 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)); + write32(&mt8173_nor->fdma_dadr, dma_buf); + write32(&mt8173_nor->fdma_end_dadr, (dma_buf + len)); /* start dma */ write32(&mt8173_nor->fdma_ctl, SFLASH_DMA_TRIGGER | SFLASH_DMA_WDLE_EN); @@ -138,7 +140,7 @@ static int dma_read(u32 addr, u8 *buf, u32 len) } } - memcpy(buf, _dma_coherent, len); + memcpy(buf, (const void *)dma_buf, len); return 0; } @@ -160,6 +162,9 @@ static int nor_read(struct spi_flash *flash, u32 addr, size_t len, void *buf) u32 next; size_t done = 0; + uintptr_t dma_buf; + size_t dma_buf_len; + if (!IS_ALIGNED((uintptr_t)buf, SFLASH_DMA_ALIGN)) { next = MIN(ALIGN_UP((uintptr_t)buf, SFLASH_DMA_ALIGN) - (uintptr_t)buf, len); @@ -167,10 +172,20 @@ static int nor_read(struct spi_flash *flash, u32 addr, size_t len, void *buf) return -1; done += next; } + + if (ENV_BOOTBLOCK || ENV_VERSTAGE) { + dma_buf = (uintptr_t)_dma_coherent; + dma_buf_len = _dma_coherent_size; + } else { + dma_buf = (uintptr_t)_dram_dma; + dma_buf_len = _dram_dma_size; + } + while (len - done >= SFLASH_DMA_ALIGN) { - next = MIN(_dma_coherent_size, ALIGN_DOWN(len - done, + next = MIN(dma_buf_len, ALIGN_DOWN(len - done, SFLASH_DMA_ALIGN)); - if (dma_read(addr + done, buf + done, next)) + if (dma_read(addr + done, buf + done, next, dma_buf, + dma_buf_len)) return -1; done += next; } diff --git a/src/soc/mediatek/mt8173/include/soc/memlayout.ld b/src/soc/mediatek/mt8173/include/soc/memlayout.ld index 7d0c766297..771f32652e 100644 --- a/src/soc/mediatek/mt8173/include/soc/memlayout.ld +++ b/src/soc/mediatek/mt8173/include/soc/memlayout.ld @@ -25,6 +25,11 @@ #define SRAM_L2C_START(addr) SYMBOL(sram_l2c, addr) #define SRAM_L2C_END(addr) SYMBOL(esram_l2c, addr) +#define DRAM_DMA(addr, size) \ + REGION(dram_dma, addr, size, 4K) \ + _ = ASSERT(size % 4K == 0, \ + "DRAM DMA buffer should be multiple of smallest page size (4K)!"); + SECTIONS { SRAM_L2C_START(0x000C0000) @@ -44,6 +49,7 @@ SECTIONS SRAM_END(0x00130000) DRAM_START(0x40000000) + DRAM_DMA(0x40000000, 1M) POSTRAM_CBFS_CACHE(0x40100000, 1M) RAMSTAGE(0x40200000, 256K) } diff --git a/src/soc/mediatek/mt8173/include/soc/mmu_operations.h b/src/soc/mediatek/mt8173/include/soc/mmu_operations.h index 98fffa2758..2428c4280c 100644 --- a/src/soc/mediatek/mt8173/include/soc/mmu_operations.h +++ b/src/soc/mediatek/mt8173/include/soc/mmu_operations.h @@ -29,6 +29,10 @@ extern unsigned char _sram_l2c[]; extern unsigned char _esram_l2c[]; #define _sram_l2c_size (_esram_l2c - _sram_l2c) +extern unsigned char _dram_dma[]; +extern unsigned char _edram_dma[]; +#define _dram_dma_size (_edram_dma - _dram_dma) + void mt8173_mmu_init(void); void mt8173_mmu_after_dram(void); diff --git a/src/soc/mediatek/mt8173/mmu_operations.c b/src/soc/mediatek/mt8173/mmu_operations.c index 53152dd631..c744d65b8e 100644 --- a/src/soc/mediatek/mt8173/mmu_operations.c +++ b/src/soc/mediatek/mt8173/mmu_operations.c @@ -53,6 +53,8 @@ void mt8173_mmu_after_dram(void) /* TODO: Implement true unmapping, and also use it for the zero-page! */ mmu_config_range(_sram_l2c, _sram_l2c_size, DEV_MEM); + mmu_config_range(_dram_dma, _dram_dma_size, UNCACHED_MEM); + /* Careful: changing cache geometry while it's active is a bad idea! */ mmu_disable(); -- cgit v1.2.3