summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsatya priya <skakit@codeaurora.org>2020-03-17 15:09:44 +0530
committerJulius Werner <jwerner@chromium.org>2020-05-11 23:58:47 +0000
commit60108fd89d101b6c87aef0e045cf0767d425d98c (patch)
treee7e94138fea867cfab5acd8eebf8cb1b41867b46
parent1e279a5cb2d0e2388023885f6d073ef6eb56dde9 (diff)
downloadcoreboot-60108fd89d101b6c87aef0e045cf0767d425d98c.tar.xz
sc7180: Fix for hang during DMA transfer in SPI-NOR flash driver
Transfer sequence used by SPI-Flash application present in CB/DC. 1. Assert CS through GPIO 2. Data transfer through QSPI (involves construction of command descriptor for multiple read/write transfers) 3. De-assert CS through GPIO. With above sequence, in DMA mode we dont have the support for read transfers that are not preceded by write transfer in QSPI controller. Ex: "write read read read" sequence results in hang during DMA transfer, where as "write read write read" sequence has no issue. As we have application controlling CS through GPIO, we are making fragment bit "set" for all transfers, which keeps CS in asserted state although the ideal way to operate CS is through QSPI controller. Change-Id: Ia45ab793ad05861b88e99a320b1ee9f10707def7 Signed-off-by: satya priya <skakit@codeaurora.org> Reviewed-on: https://review.coreboot.org/c/coreboot/+/39807 Reviewed-by: Julius Werner <jwerner@chromium.org> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
-rw-r--r--src/soc/qualcomm/sc7180/qspi.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/src/soc/qualcomm/sc7180/qspi.c b/src/soc/qualcomm/sc7180/qspi.c
index 10038e412a..675641bc4c 100644
--- a/src/soc/qualcomm/sc7180/qspi.c
+++ b/src/soc/qualcomm/sc7180/qspi.c
@@ -118,17 +118,20 @@ static struct cmd_desc *allocate_descriptor(void)
next->direction = MASTER_READ;
next->multi_io_mode = 0;
next->reserved1 = 0;
- next->fragment = 0;
+ /*
+ * QSPI controller doesn't support transfer starts with read segment.
+ * So to support read transfers that are not preceded by write, set
+ * transfer fragment bit = 1
+ */
+ next->fragment = 1;
next->reserved2 = 0;
next->length = 0;
next->bounce_src = 0;
next->bounce_dst = 0;
next->bounce_length = 0;
- if (current) {
+ if (current)
current->next_descriptor = (uint32_t)(uintptr_t) next;
- current->fragment = 1;
- }
return next;
}