Message ID | 1439668968-3882-3-git-send-email-hdegoede@redhat.com |
---|---|
State | Accepted |
Delegated to: | Hans de Goede |
Headers | show |
On Sun, Aug 16, 2015 at 4:02 AM, Hans de Goede <hdegoede@redhat.com> wrote: > nand_spl_load_image() always gets called with either CONFIG_SYS_TEXT_BASE > or spl_image.load_addr as destination, both of which are properly aligened, > and have plenty of space for "overshooting" up to > CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE bytes, as we read in > CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE bytes chunks. > > This saves CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE (typically 1k) in > SPL size, which is a lot on the total 24k we have. > > Signed-off-by: Hans de Goede <hdegoede@redhat.com> > --- > drivers/mtd/nand/sunxi_nand_spl.c | 35 ++++++++--------------------------- > 1 file changed, 8 insertions(+), 27 deletions(-) > > diff --git a/drivers/mtd/nand/sunxi_nand_spl.c b/drivers/mtd/nand/sunxi_nand_spl.c > index ac5f56d..46654e4 100644 > --- a/drivers/mtd/nand/sunxi_nand_spl.c > +++ b/drivers/mtd/nand/sunxi_nand_spl.c > @@ -85,6 +85,7 @@ > > #define SUNXI_DMA_DDMA_CFG_REG_LOADING (1 << 31) > #define SUNXI_DMA_DDMA_CFG_REG_DMA_DEST_DATA_WIDTH_32 (2 << 25) > +#define SUNXI_DMA_DDMA_CFG_REG_DDMA_DST_DRQ_TYPE_DRAM (1 << 16) Might want to mention this change (correct DMA type?) in the commit log. > #define SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_DATA_WIDTH_32 (2 << 9) > #define SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_ADDR_MODE_IO (1 << 5) > #define SUNXI_DMA_DDMA_CFG_REG_DDMA_SRC_DRQ_TYPE_NFC (3 << 0) > @@ -94,10 +95,6 @@ > > /* minimal "boot0" style NAND support for Allwinner A20 */ > > -/* temporary buffer in internal ram */ > -unsigned char temp_buf[CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE] > - __aligned(0x10) __section(".text#"); > - > /* random seed used by linux */ > const uint16_t random_seed[128] = { > 0x2b75, 0x0bd0, 0x5ca3, 0x62d1, 0x1c93, 0x07e9, 0x2162, 0x3a72, > @@ -167,8 +164,8 @@ void nand_init(void) > } > } > > -static void nand_read_page(unsigned int real_addr, int syndrome, > - uint32_t *ecc_errors) > +static void nand_read_page(unsigned int real_addr, dma_addr_t dst, > + int syndrome, uint32_t *ecc_errors) > { > uint32_t val; > int ecc_off = 0; > @@ -226,9 +223,6 @@ static void nand_read_page(unsigned int real_addr, int syndrome, > return; > } > > - /* clear temp_buf */ > - memset(temp_buf, 0, CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE); > - > /* set CMD */ > writel(NFC_SEND_CMD1 | NFC_WAIT_FLAG | NAND_CMD_RESET, > SUNXI_NFC_BASE + NFC_CMD); > @@ -278,8 +272,7 @@ static void nand_read_page(unsigned int real_addr, int syndrome, > writel(SUNXI_NFC_BASE + NFC_IO_DATA, > SUNXI_DMA_BASE + SUNXI_DMA_SRC_START_ADDR_REG0); > /* read to RAM */ > - writel((uint32_t)temp_buf, > - SUNXI_DMA_BASE + SUNXI_DMA_DEST_START_ADDRR_REG0); > + writel(dst, SUNXI_DMA_BASE + SUNXI_DMA_DEST_START_ADDRR_REG0); > writel(SUNXI_DMA_DDMA_PARA_REG_SRC_WAIT_CYC > | SUNXI_DMA_DDMA_PARA_REG_SRC_BLK_SIZE, > SUNXI_DMA_BASE + SUNXI_DMA_DDMA_PARA_REG0); > @@ -287,6 +280,7 @@ static void nand_read_page(unsigned int real_addr, int syndrome, > SUNXI_DMA_BASE + SUNXI_DMA_DDMA_BC_REG0); /* 1kB */ > writel(SUNXI_DMA_DDMA_CFG_REG_LOADING > | SUNXI_DMA_DDMA_CFG_REG_DMA_DEST_DATA_WIDTH_32 > + | SUNXI_DMA_DDMA_CFG_REG_DDMA_DST_DRQ_TYPE_DRAM > | SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_DATA_WIDTH_32 > | SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_ADDR_MODE_IO > | SUNXI_DMA_DDMA_CFG_REG_DDMA_SRC_DRQ_TYPE_NFC, > @@ -324,27 +318,14 @@ static void nand_read_page(unsigned int real_addr, int syndrome, > int nand_spl_load_image(uint32_t offs, unsigned int size, void *dest) > { > void *current_dest; > - uint32_t count; > - uint32_t current_count; > uint32_t ecc_errors = 0; > > - memset(dest, 0x0, size); /* clean destination memory */ > for (current_dest = dest; > current_dest < (dest + size); > current_dest += CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE) { > - nand_read_page(offs, offs > - < CONFIG_NAND_SUNXI_SPL_SYNDROME_PARTITIONS_END, > - &ecc_errors); > - count = current_dest - dest; > - > - if (size - count > CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE) > - current_count = CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE; > - else > - current_count = size - count; > - > - memcpy(current_dest, > - temp_buf, > - current_count); > + nand_read_page(offs, (dma_addr_t)current_dest, > + offs < CONFIG_NAND_SUNXI_SPL_SYNDROME_PARTITIONS_END, > + &ecc_errors); > offs += CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE; > } > return ecc_errors ? -1 : 0; > -- > 2.4.3 > > _______________________________________________ > U-Boot mailing list > U-Boot@lists.denx.de > http://lists.denx.de/mailman/listinfo/u-boot
On Mon, 2015-08-17 at 15:22 +0800, Chen-Yu Tsai wrote: > > > +#define SUNXI_DMA_DDMA_CFG_REG_DDMA_DST_DRQ_TYPE_DRAM (1 << 16) > > Might want to mention this change (correct DMA type?) in the commit > log. Yes, would be good. With that: Acked-by: Ian Campbell <ijc@hellion.org.uk>
diff --git a/drivers/mtd/nand/sunxi_nand_spl.c b/drivers/mtd/nand/sunxi_nand_spl.c index ac5f56d..46654e4 100644 --- a/drivers/mtd/nand/sunxi_nand_spl.c +++ b/drivers/mtd/nand/sunxi_nand_spl.c @@ -85,6 +85,7 @@ #define SUNXI_DMA_DDMA_CFG_REG_LOADING (1 << 31) #define SUNXI_DMA_DDMA_CFG_REG_DMA_DEST_DATA_WIDTH_32 (2 << 25) +#define SUNXI_DMA_DDMA_CFG_REG_DDMA_DST_DRQ_TYPE_DRAM (1 << 16) #define SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_DATA_WIDTH_32 (2 << 9) #define SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_ADDR_MODE_IO (1 << 5) #define SUNXI_DMA_DDMA_CFG_REG_DDMA_SRC_DRQ_TYPE_NFC (3 << 0) @@ -94,10 +95,6 @@ /* minimal "boot0" style NAND support for Allwinner A20 */ -/* temporary buffer in internal ram */ -unsigned char temp_buf[CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE] - __aligned(0x10) __section(".text#"); - /* random seed used by linux */ const uint16_t random_seed[128] = { 0x2b75, 0x0bd0, 0x5ca3, 0x62d1, 0x1c93, 0x07e9, 0x2162, 0x3a72, @@ -167,8 +164,8 @@ void nand_init(void) } } -static void nand_read_page(unsigned int real_addr, int syndrome, - uint32_t *ecc_errors) +static void nand_read_page(unsigned int real_addr, dma_addr_t dst, + int syndrome, uint32_t *ecc_errors) { uint32_t val; int ecc_off = 0; @@ -226,9 +223,6 @@ static void nand_read_page(unsigned int real_addr, int syndrome, return; } - /* clear temp_buf */ - memset(temp_buf, 0, CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE); - /* set CMD */ writel(NFC_SEND_CMD1 | NFC_WAIT_FLAG | NAND_CMD_RESET, SUNXI_NFC_BASE + NFC_CMD); @@ -278,8 +272,7 @@ static void nand_read_page(unsigned int real_addr, int syndrome, writel(SUNXI_NFC_BASE + NFC_IO_DATA, SUNXI_DMA_BASE + SUNXI_DMA_SRC_START_ADDR_REG0); /* read to RAM */ - writel((uint32_t)temp_buf, - SUNXI_DMA_BASE + SUNXI_DMA_DEST_START_ADDRR_REG0); + writel(dst, SUNXI_DMA_BASE + SUNXI_DMA_DEST_START_ADDRR_REG0); writel(SUNXI_DMA_DDMA_PARA_REG_SRC_WAIT_CYC | SUNXI_DMA_DDMA_PARA_REG_SRC_BLK_SIZE, SUNXI_DMA_BASE + SUNXI_DMA_DDMA_PARA_REG0); @@ -287,6 +280,7 @@ static void nand_read_page(unsigned int real_addr, int syndrome, SUNXI_DMA_BASE + SUNXI_DMA_DDMA_BC_REG0); /* 1kB */ writel(SUNXI_DMA_DDMA_CFG_REG_LOADING | SUNXI_DMA_DDMA_CFG_REG_DMA_DEST_DATA_WIDTH_32 + | SUNXI_DMA_DDMA_CFG_REG_DDMA_DST_DRQ_TYPE_DRAM | SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_DATA_WIDTH_32 | SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_ADDR_MODE_IO | SUNXI_DMA_DDMA_CFG_REG_DDMA_SRC_DRQ_TYPE_NFC, @@ -324,27 +318,14 @@ static void nand_read_page(unsigned int real_addr, int syndrome, int nand_spl_load_image(uint32_t offs, unsigned int size, void *dest) { void *current_dest; - uint32_t count; - uint32_t current_count; uint32_t ecc_errors = 0; - memset(dest, 0x0, size); /* clean destination memory */ for (current_dest = dest; current_dest < (dest + size); current_dest += CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE) { - nand_read_page(offs, offs - < CONFIG_NAND_SUNXI_SPL_SYNDROME_PARTITIONS_END, - &ecc_errors); - count = current_dest - dest; - - if (size - count > CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE) - current_count = CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE; - else - current_count = size - count; - - memcpy(current_dest, - temp_buf, - current_count); + nand_read_page(offs, (dma_addr_t)current_dest, + offs < CONFIG_NAND_SUNXI_SPL_SYNDROME_PARTITIONS_END, + &ecc_errors); offs += CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE; } return ecc_errors ? -1 : 0;
nand_spl_load_image() always gets called with either CONFIG_SYS_TEXT_BASE or spl_image.load_addr as destination, both of which are properly aligened, and have plenty of space for "overshooting" up to CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE bytes, as we read in CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE bytes chunks. This saves CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE (typically 1k) in SPL size, which is a lot on the total 24k we have. Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- drivers/mtd/nand/sunxi_nand_spl.c | 35 ++++++++--------------------------- 1 file changed, 8 insertions(+), 27 deletions(-)