On Tuesday 09 January 2018 11:31 AM, Goldschmidt Simon wrote: > On Mon, 08/01/2018 12:18, Vignesh R wrote: >> Make flash writes 32 bit aligned by using bounce buffers to deal with non 32 >> bit >> aligned buffers. Allocate a 512 byte bounce buffer (max known page size >> currently) for this case. > > Looking at drivers/mtd/spi/sf_dataflash.c, I see at least one chip > with 1024 byte page size (at45db642d). > This should probably be a constant somewhere, or at least be checked > at runtime, see below. >
Oh, I missed the dataflash devices. Since, we don't get the page size info from framework it would be difficult to do allocate bounce buffer only once in probe. I think better way would be to allocate and free bounce buffer as and when required in cadence_qspi_apb_indirect_write_execute() just like bounce_buffer_start/stop. Will make changes and post v2 shortly Regards Vignesh >> This is required because as per TI K2G TRM[1], the external master is only >> permitted to issue 32-bit data interface writes until the last word of an >> indirect >> transfer. Otherwise indirect writes is known to fail sometimes. >> >> [1] http://www.ti.com/lit/ug/spruhy8g/spruhy8g.pdf >> >> Signed-off-by: Vignesh R <vigne...@ti.com> >> --- >> drivers/spi/cadence_qspi.c | 13 ++++++++++++- >> drivers/spi/cadence_qspi.h | 1 + >> drivers/spi/cadence_qspi_apb.c | 10 +++++----- >> 3 files changed, 18 insertions(+), 6 deletions(-) >> >> diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c index >> 991a7160bdb8..49c9b477e678 100644 >> --- a/drivers/spi/cadence_qspi.c >> +++ b/drivers/spi/cadence_qspi.c >> @@ -158,6 +158,10 @@ static int cadence_spi_probe(struct udevice *bus) >> >> priv->regbase = plat->regbase; >> priv->ahbbase = plat->ahbbase; >> + /* Bounce buf to handle unaligned writes. 512B is max pagesize */ >> + priv->bounce_buf = malloc(512); > > This should probably be a named constant. > >> + if (!priv->bounce_buf) >> + return -ENOMEM; >> >> if (!priv->qspi_is_init) { >> cadence_qspi_apb_controller_init(plat); >> @@ -259,8 +263,15 @@ static int cadence_spi_xfer(struct udevice *dev, >> unsigned >> int bitlen, >> err = cadence_qspi_apb_indirect_write_setup >> (plat, priv->cmd_len, cmd_buf); >> if (!err) { >> + const u8 *txbuf = dout; >> + >> + if ((uintptr_t)txbuf % 4) { >> + memcpy(priv->bounce_buf, dout, >> + data_bytes); > > Without checking the size of the buffer allocated for bounce_buf here, > you risk a buffer overflow for chips with larger page size. > >> + txbuf = priv->bounce_buf; >> + } >> err = cadence_qspi_apb_indirect_write_execute >> - (plat, data_bytes, dout); >> + (plat, data_bytes, txbuf); >> } >> break; >> default: >> diff --git a/drivers/spi/cadence_qspi.h b/drivers/spi/cadence_qspi.h index >> 83154210bd95..c97419af3de3 100644 >> --- a/drivers/spi/cadence_qspi.h >> +++ b/drivers/spi/cadence_qspi.h >> @@ -43,6 +43,7 @@ struct cadence_spi_priv { >> unsigned int qspi_calibrated_hz; >> unsigned int qspi_calibrated_cs; >> unsigned int previous_hz; >> + void *bounce_buf; >> }; >> >> /* Functions call declaration */ >> diff --git a/drivers/spi/cadence_qspi_apb.c b/drivers/spi/cadence_qspi_apb.c >> index fa8af33ae19b..fd3ece4cb129 100644 >> --- a/drivers/spi/cadence_qspi_apb.c >> +++ b/drivers/spi/cadence_qspi_apb.c >> @@ -727,11 +727,11 @@ int cadence_qspi_apb_indirect_write_execute(struct >> cadence_spi_platdata *plat, >> >> while (remaining > 0) { >> write_bytes = remaining > page_size ? page_size : remaining; >> - /* Handle non-4-byte aligned access to avoid data abort. */ >> - if (((uintptr_t)txbuf % 4) || (write_bytes % 4)) >> - writesb(plat->ahbbase, txbuf, write_bytes); >> - else >> - writesl(plat->ahbbase, txbuf, write_bytes >> 2); >> + writesl(plat->ahbbase, txbuf, write_bytes >> 2); >> + if (write_bytes % 4) >> + writesb(plat->ahbbase, >> + txbuf + rounddown(write_bytes, 4), >> + write_bytes % 4); >> >> ret = wait_for_bit("QSPI", plat->regbase + >> CQSPI_REG_SDRAMLEVEL, >> CQSPI_REG_SDRAMLEVEL_WR_MASK << >> -- >> 2.15.1 > > Regards, > Simon > _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot