brcm63xx: ensure dummy byte is set for mapped spi flash with fast read
[openwrt/staging/noltari.git] / target / linux / brcm63xx / patches-4.1 / 345-MIPS-BCM63XX-fixup-mapped-SPI-flash-access-on-boot.patch
index 2b19600776d6270717a1160dd385fc9910c8770b..c8bef13625845cfeb95ba07f7d5d5a4cffd650ad 100644 (file)
@@ -9,12 +9,20 @@ reads.
 
 Signed-off-by: Jonas Gorski <jogo@openwrt.org>
 ---
- arch/mips/bcm63xx/dev-flash.c | 36 ++++++++++++++++++++++++++++++++++++
- 1 file changed, 36 insertions(+)
+ arch/mips/bcm63xx/dev-flash.c | 51 ++++++++++++++++++++++++++++++++++++
+ 1 file changed, 51 insertions(+)
 
 --- a/arch/mips/bcm63xx/dev-flash.c
 +++ b/arch/mips/bcm63xx/dev-flash.c
-@@ -110,9 +110,46 @@ static int __init bcm63xx_detect_flash_t
+@@ -16,6 +16,7 @@
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/partitions.h>
+ #include <linux/mtd/physmap.h>
++#include <linux/mtd/spi-nor.h>
+ #include <bcm63xx_cpu.h>
+ #include <bcm63xx_dev_flash.h>
+@@ -110,9 +111,59 @@ static int __init bcm63xx_detect_flash_t
        }
  }
  
@@ -24,36 +32,49 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
 +#define FLASH_CTRL_ADDR_BYTES_2               (0 << 8)
 +#define FLASH_CTRL_ADDR_BYTES_3               (1 << 8)
 +#define FLASH_CTRL_ADDR_BYTES_4               (2 << 8)
++#define FLASH_CTRL_DUMMY_BYTES_SHIFT  10
++#define FLASH_CTRL_DUMMY_BYTES_MASK   (0x3 << FLASH_CTRL_DUMMY_BYTES_SHIFT)
 +#define FLASH_CTRL_MB_EN              (1 << 23)
 +
  void __init bcm63xx_flash_detect(void)
  {
        flash_type = bcm63xx_detect_flash_type();
 +
-+      /* reduce flash mapping to single i/o reads for safety */
++      /* ensure flash mapping has sane values */
 +      if (flash_type == BCM63XX_FLASH_TYPE_SERIAL &&
 +          (BCMCPU_IS_6318() || BCMCPU_IS_6328() || BCMCPU_IS_6362() ||
 +           BCMCPU_IS_63268())) {
 +              u32 val = bcm_rset_readl(RSET_HSSPI, HSSPI_FLASH_CTRL_REG);
 +
-+              if (!(val & FLASH_CTRL_MB_EN))
-+                      return;
++              if (val & FLASH_CTRL_MB_EN) {
++                      /* cfe might configure non working dual-io mode */
++                      val &= ~FLASH_CTRL_MB_EN;
++                      val &= ~FLASH_CTRL_READ_OPCODE_MASK;
++                      val &= ~FLASH_CTRL_DUMMY_BYTES_MASK;
++                      val |= 1 << FLASH_CTRL_DUMMY_BYTES_SHIFT;
++
++                      switch (val & FLASH_CTRL_ADDR_BYTES_MASK) {
++                      case FLASH_CTRL_ADDR_BYTES_3:
++                              val |= SPINOR_OP_READ_FAST;
++                              break;
++                      case FLASH_CTRL_ADDR_BYTES_4:
++                              val |= SPINOR_OP_READ4_FAST;
++                              break;
++                      case FLASH_CTRL_ADDR_BYTES_2:
++                      default:
++                              pr_warn("unsupported address byte mode (%x), not fixing up\n",
++                                      val & FLASH_CTRL_ADDR_BYTES_MASK);
++                              return;
++                      }
++              } else {
++                      /* ensure dummy bytes is set to 1 for _FAST reads */
++                      u8 cmd = val & FLASH_CTRL_READ_OPCODE_MASK;
 +
-+              val &= ~FLASH_CTRL_MB_EN;
-+              val &= ~FLASH_CTRL_READ_OPCODE_MASK;
++                      if (cmd != SPINOR_OP_READ_FAST && cmd != SPINOR_OP_READ4_FAST)
++                              return;
 +
-+              switch (val & FLASH_CTRL_ADDR_BYTES_MASK) {
-+              case FLASH_CTRL_ADDR_BYTES_3:
-+                      val |= 0x0b; /* OPCODE_FAST_READ */
-+                      break;
-+              case FLASH_CTRL_ADDR_BYTES_4:
-+                      val |= 0x0c; /* OPCODE_FAST_READ_4B */
-+                      break;
-+              case FLASH_CTRL_ADDR_BYTES_2:
-+              default:
-+                      pr_warn("unsupported address byte mode (%x), not fixing up\n",
-+                              val & FLASH_CTRL_ADDR_BYTES_MASK);
-+                      return;
++                      val &= ~FLASH_CTRL_DUMMY_BYTES_MASK;
++                      val |= 1 << FLASH_CTRL_DUMMY_BYTES_SHIFT;
 +              }
 +
 +              bcm_rset_writel(RSET_HSSPI, val, HSSPI_FLASH_CTRL_REG);