[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC 1/3] hw: m25p80: add prereading ability in transfer8
From: |
Iris Chen |
Subject: |
[RFC 1/3] hw: m25p80: add prereading ability in transfer8 |
Date: |
Thu, 28 Jul 2022 16:23:20 -0700 |
With SPI-GPIO we don't have the input bits until
all 8 bits of the output have been shifted out,
so we have to prime the MISO with bogus values (0xFF).
Signed-off-by: Iris Chen <irischenlj@fb.com>
---
hw/block/m25p80.c | 29 ++++++++++++++++++++++++++++-
hw/ssi/ssi.c | 4 ----
include/hw/ssi/ssi.h | 5 +++++
3 files changed, 33 insertions(+), 5 deletions(-)
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index a8d2519141..9b26bb96e5 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -1462,7 +1462,7 @@ static int m25p80_cs(SSIPeripheral *ss, bool select)
return 0;
}
-static uint32_t m25p80_transfer8(SSIPeripheral *ss, uint32_t tx)
+static uint32_t m25p80_transfer8_ex(SSIPeripheral *ss, uint32_t tx)
{
Flash *s = M25P80(ss);
uint32_t r = 0;
@@ -1548,6 +1548,33 @@ static uint32_t m25p80_transfer8(SSIPeripheral *ss,
uint32_t tx)
return r;
}
+/*
+ * Pre-reading logic for m25p80_transfer8:
+ * The existing SPI model assumes the output byte is fully formed,
+ * can be passed to the SPI device, and the input byte can be returned,
+ * all in one operation. With SPI-GPIO, we don't have the input byte
+ * until all 8 bits of the output have been shifted out, so we have
+ * to prime the MISO with bogus values (0xFF).
+ */
+static uint32_t m25p80_transfer8(SSIPeripheral *ss, uint32_t tx)
+{
+ Flash *s = M25P80(ss);
+ SSIBus *ssibus = (SSIBus *)qdev_get_parent_bus(DEVICE(s));
+
+ uint8_t prev_state = s->state;
+ uint32_t r = m25p80_transfer8_ex(ss, tx);
+ uint8_t curr_state = s->state;
+
+ if (ssibus->preread &&
+ /* cmd state has changed into DATA reading state */
+ (!(prev_state == STATE_READ || prev_state == STATE_READING_DATA) &&
+ (curr_state == STATE_READ || curr_state == STATE_READING_DATA))) {
+ r = m25p80_transfer8_ex(ss, 0xFF);
+ }
+
+ return r;
+}
+
static void m25p80_write_protect_pin_irq_handler(void *opaque, int n, int
level)
{
Flash *s = M25P80(opaque);
diff --git a/hw/ssi/ssi.c b/hw/ssi/ssi.c
index 003931fb50..21570fe25f 100644
--- a/hw/ssi/ssi.c
+++ b/hw/ssi/ssi.c
@@ -19,10 +19,6 @@
#include "qapi/error.h"
#include "qom/object.h"
-struct SSIBus {
- BusState parent_obj;
-};
-
#define TYPE_SSI_BUS "SSI"
OBJECT_DECLARE_SIMPLE_TYPE(SSIBus, SSI_BUS)
diff --git a/include/hw/ssi/ssi.h b/include/hw/ssi/ssi.h
index f411858ab0..e54073d822 100644
--- a/include/hw/ssi/ssi.h
+++ b/include/hw/ssi/ssi.h
@@ -30,6 +30,11 @@ enum SSICSMode {
SSI_CS_HIGH,
};
+struct SSIBus {
+ BusState parent_obj;
+ bool preread;
+};
+
/* Peripherals. */
struct SSIPeripheralClass {
DeviceClass parent_class;
--
2.30.2