spi: Fix invalid D channel response when flash interface is disabled
authorAlbert Ou <albert@sifive.com>
Wed, 2 Aug 2017 20:50:00 +0000 (13:50 -0700)
committerAlbert Ou <albert@sifive.com>
Wed, 2 Aug 2017 20:50:00 +0000 (13:50 -0700)
Issue: When the memory-mapped flash region is accessed while the flash
read mode is disabled (fctrl.en flag is clear), the SPI flash controller
generates an invalid response on the D channel.
This may cause the TileLink bus to deadlock.

Workaround: Software should avoid accessing the memory-mapped flash
region when the SPI controller is not in the flash read mode.

src/main/scala/devices/spi/SPIFlash.scala

index b038482fbf7d2c3e727976386d27771306063e14..17144b86eb0d8425453d94698879505261818502 100644 (file)
@@ -86,7 +86,7 @@ class SPIFlashMap(c: SPIFlashParamsBase) extends Module {
     }
   }
 
-  val (s_idle :: s_cmd :: s_addr :: s_pad :: s_data_pre :: s_data_post :: Nil) = Enum(UInt(), 6)
+  val (s_idle :: s_cmd :: s_addr :: s_pad :: s_data_pre :: s_data_post :: s_off :: Nil) = Enum(UInt(), 7)
   val state = Reg(init = s_idle)
 
   switch (state) {
@@ -105,10 +105,11 @@ class SPIFlashMap(c: SPIFlashParamsBase) extends Module {
           io.link.lock := Bool(false)
         }
       } .otherwise {
-        io.data.valid := io.addr.valid
-        io.addr.ready := io.data.ready
-        io.data.bits := UInt(0)
+        io.addr.ready := Bool(true)
         io.link.lock := Bool(false)
+        when (io.addr.valid) {
+          state := s_off
+        }
       }
     }
 
@@ -158,5 +159,13 @@ class SPIFlashMap(c: SPIFlashParamsBase) extends Module {
         state := s_idle
       }
     }
+
+    is (s_off) {
+      io.data.valid := Bool(true)
+      io.data.bits := UInt(0)
+      when (io.data.ready) {
+        state := s_idle
+      }
+    }
   }
 }