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@chromium.org> Original-Commit-Id: 6ea0407f7273bc88613bc23a6fc4c41f9cca1adb Original-Change-Id: Ic422e7265fdd35c573d8cd44280a1f7dc163a6db Original-Signed-off-by: Bayi Cheng <bayi.cheng@mediatek.com> Original-Reviewed-on: https://chromium-review.googlesource.com/323932 Original-Commit-Ready: Yidi Lin <yidi.lin@mediatek.com> Original-Tested-by: Yidi Lin <yidi.lin@mediatek.com> Original-Reviewed-by: Julius Werner <jwerner@chromium.org> Reviewed-on: https://review.coreboot.org/13979 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
parent
5ffb6887c2
commit
d8bb51eb4e
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue