}
-// WARNING
-// KESTREL SPECIFIC
-#define TERCEL_SPI_REG_SYS_PHY_CFG1 0x10
-#define TERCEL_SPI_REG_SYS_FLASH_CFG5 0x24
-#define TERCEL_SPI_PHY_CLOCK_DIVISOR_MASK 0xff
-#define TERCEL_SPI_PHY_CLOCK_DIVISOR_SHIFT 0
-#define TERCEL_SPI_FLASH_EN_MULTCYC_READ_MASK 0x1
-#define TERCEL_SPI_FLASH_EN_MULTCYC_READ_SHIFT 0
-static inline uint32_t read_tercel_register(uint8_t reg)
-{
- return readl((unsigned long)(SPI_FCTRL_BASE+reg));
-}
-
-static inline void write_tercel_register(uint8_t reg, uint32_t value)
-{
- writel(value, (unsigned long)(SPI_FCTRL_BASE+reg));
-}
-
-// TODO: need to use this
-// https://gitlab.raptorengineering.com/kestrel-collaboration/kestrel-firmware/bare-metal-firmware/-/blob/master/main.c#L2328
-
-/* this is a "level 1" speed-up, which gets an initial improvement of 10-50x
- * over the default speed (which is a scant 100 bytes per second).
- */
-static void crank_up_qspi_level1(void)
-{
- // WARNING: KESTREL SPECIFIC
- // Set SPI clock cycle divider to 1
- uint32_t dword;
- dword = read_tercel_register(TERCEL_SPI_REG_SYS_PHY_CFG1);
- dword &= ~(TERCEL_SPI_PHY_CLOCK_DIVISOR_MASK <<
- TERCEL_SPI_PHY_CLOCK_DIVISOR_SHIFT);
- dword |= ((1 & TERCEL_SPI_PHY_CLOCK_DIVISOR_MASK) <<
- TERCEL_SPI_PHY_CLOCK_DIVISOR_SHIFT);
- write_tercel_register(TERCEL_SPI_REG_SYS_PHY_CFG1, dword);
- // Enable read merging
- dword = read_tercel_register(TERCEL_SPI_REG_SYS_FLASH_CFG5);
- dword |= (TERCEL_SPI_FLASH_EN_MULTCYC_READ_MASK <<
- TERCEL_SPI_FLASH_EN_MULTCYC_READ_SHIFT);
- write_tercel_register(TERCEL_SPI_REG_SYS_FLASH_CFG5, dword);
-}
+extern void crank_up_qspi_level1(void);
+extern int host_spi_flash_init(void);
static bool fl_read(void *dst, uint32_t offset, uint32_t size)
{
if (ftr & SYS_REG_INFO_HAS_SPI_FLASH) {
// speed up the QSPI to at least a sane level
crank_up_qspi_level1();
+ // run at saner level
+ host_spi_flash_init();
puts("SPI Offset: ");
spi_offs = readl(SYSCON_BASE + SYS_REG_SPI_INFO);
//volatile uint8_t *qspi_bytes = (uint8_t*)spi_offs;
// let's not, eh? writel(0xDEAF0123, (unsigned long)&(qspi[0]));
// tmp = readl((unsigned long)&(qspi[0]));
- for (int i=0;i<2;i++) {
+ for (int i=0;i<10;i++) {
tmp = readl((unsigned long)&(qspi[i]));
uart_writeuint32(tmp);
puts(" ");
volatile uint32_t *mem = (uint32_t*)0x1000000;
fl_read(mem, // destination in RAM
0x600000, // offset into QSPI
- 0x1000000); // length - shorter (testing) 0x8000);
+ 0x8000); // length - shorter (testing) 0x8000);
+ //0x1000000); // length
puts("dump mem\n");
for (int i=0;i<256;i++) {
tmp = readl((unsigned long)&(mem[i]));
--- /dev/null
+// Copyright (C) 2020 - 2021 Raptor Engineering, LLC
+//
+// Released under the terms of the GPL v3
+// See the LICENSE file for full details
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "console.h"
+#include "microwatt_soc.h"
+#include "io.h"
+
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "micron_n25q_flash.h"
+#include "tercel_spi.h"
+
+#define ALLOW_SPI_QUAD_MODE 1
+
+static inline uint8_t read_tercel_reg8(uint8_t reg)
+{
+ return readb((unsigned long)(SPI_FCTRL_BASE+reg));
+}
+
+static inline void write_tercel_reg8(uint8_t reg, uint8_t value)
+{
+ writeb(value, (unsigned long)(SPI_FCTRL_BASE+reg));
+}
+
+static inline uint32_t read_tercel_register(uint8_t reg)
+{
+ return readl((unsigned long)(SPI_FCTRL_BASE+reg));
+}
+
+static inline void write_tercel_register(uint8_t reg, uint32_t value)
+{
+ writel(value, (unsigned long)(SPI_FCTRL_BASE+reg));
+}
+
+static uint32_t read_host_spi_flash_id(void)
+{
+ uint32_t flash_id = 0;
+
+ // Set user mode
+ write_tercel_register(TERCEL_SPI_REG_SYS_CORE_CTL1,
+ read_tercel_register(TERCEL_SPI_REG_SYS_CORE_CTL1) |
+ (TERCEL_SPI_ENABLE_USER_MODE_MASK << TERCEL_SPI_ENABLE_USER_MODE_SHIFT));
+
+ // Send Flash ID command
+ write_tercel_reg8(0, 0x9e);
+
+ // Read response
+ flash_id = (flash_id << 8) | read_tercel_reg8(0);
+ flash_id = (flash_id << 8) | read_tercel_reg8(0);
+ flash_id = (flash_id << 8) | read_tercel_reg8(0);
+ flash_id = (flash_id << 8) | read_tercel_reg8(0);
+
+ // Clear user mode
+ write_tercel_register(TERCEL_SPI_REG_SYS_CORE_CTL1,
+ read_tercel_register(TERCEL_SPI_REG_SYS_CORE_CTL1) &
+ ~(TERCEL_SPI_ENABLE_USER_MODE_MASK <<
+ TERCEL_SPI_ENABLE_USER_MODE_SHIFT));
+
+ return flash_id;
+}
+
+
+/* this is a "level 1" speed-up, which gets an initial improvement of 10-50x
+ * over the default speed (which is a scant 100 bytes per second).
+ */
+void crank_up_qspi_level1(void)
+{
+ // WARNING: KESTREL SPECIFIC
+ // Set SPI clock cycle divider to 1
+ uint32_t dword;
+ dword = read_tercel_register(TERCEL_SPI_REG_SYS_PHY_CFG1);
+ dword &= ~(TERCEL_SPI_PHY_CLOCK_DIVISOR_MASK <<
+ TERCEL_SPI_PHY_CLOCK_DIVISOR_SHIFT);
+ dword |= ((1 & TERCEL_SPI_PHY_CLOCK_DIVISOR_MASK) <<
+ TERCEL_SPI_PHY_CLOCK_DIVISOR_SHIFT);
+ write_tercel_register(TERCEL_SPI_REG_SYS_PHY_CFG1, dword);
+ // Enable read merging
+ dword = read_tercel_register(TERCEL_SPI_REG_SYS_FLASH_CFG5);
+ dword |= (TERCEL_SPI_FLASH_EN_MULTCYC_READ_MASK <<
+ TERCEL_SPI_FLASH_EN_MULTCYC_READ_SHIFT);
+ write_tercel_register(TERCEL_SPI_REG_SYS_FLASH_CFG5, dword);
+}
+
+extern void uart_writeuint32(uint32_t val);
+
+// level 2 speedup
+int host_spi_flash_init(void)
+{
+ int i;
+ uint32_t dword;
+ uint32_t flash_device_id;
+
+ if ((read_tercel_register(TERCEL_SPI_REG_DEVICE_ID_HIGH) !=
+ TERCEL_SPI_DEVICE_ID_HIGH) ||
+ (read_tercel_register(TERCEL_SPI_REG_DEVICE_ID_LOW) !=
+ TERCEL_SPI_DEVICE_ID_LOW))
+ {
+ return -1;
+ }
+
+ uint32_t tercel_version;
+ tercel_version = read_tercel_register(TERCEL_SPI_REG_DEVICE_VERSION);
+ puts("Raptor Tercel SPI master found, device version ");
+ uart_writeuint32((tercel_version >> TERCEL_SPI_VERSION_MAJOR_SHIFT) &
+ TERCEL_SPI_VERSION_MAJOR_MASK);
+ uart_writeuint32((tercel_version >> TERCEL_SPI_VERSION_MINOR_SHIFT) &
+ TERCEL_SPI_VERSION_MINOR_MASK);
+ uart_writeuint32((tercel_version >> TERCEL_SPI_VERSION_PATCH_SHIFT) &
+ TERCEL_SPI_VERSION_PATCH_MASK);
+ puts("\n");
+
+ flash_device_id = read_host_spi_flash_id();
+ puts("Flash ID ");
+ uart_writeuint32(flash_device_id);
+ puts("\n");
+ for (i = 0; i < (sizeof(micron_n25q_spi_device_ids) /
+ sizeof(micron_n25q_spi_device_ids[0])); i++)
+ {
+ if (flash_device_id == micron_n25q_spi_device_ids[i])
+ {
+ puts(micron_n25q_spi_device_names[i]);
+ puts(" Flash device detected, configuring\n");
+
+ // Set up Flash-specific commands
+ dword = 0;
+ dword |= (MICRON_N25Q_SPI_4BA_QSPI_READ_CMD
+ & TERCEL_SPI_4BA_QSPI_CMD_MASK) <<
+ TERCEL_SPI_4BA_QSPI_CMD_SHIFT;
+ dword |= (MICRON_N25Q_SPI_3BA_QSPI_READ_CMD
+ & TERCEL_SPI_3BA_QSPI_CMD_MASK) <<
+ TERCEL_SPI_3BA_QSPI_CMD_SHIFT;
+ dword |= (MICRON_N25Q_SPI_4BA_SPI_READ_CMD &
+ TERCEL_SPI_4BA_SPI_CMD_MASK) <<
+ TERCEL_SPI_4BA_SPI_CMD_SHIFT;
+ dword |= (MICRON_N25Q_SPI_3BA_SPI_READ_CMD &
+ TERCEL_SPI_3BA_SPI_CMD_MASK) <<
+ TERCEL_SPI_3BA_SPI_CMD_SHIFT;
+ write_tercel_register(TERCEL_SPI_REG_SYS_FLASH_CFG1, dword);
+
+ dword = 0;
+ dword |= (MICRON_N25Q_SPI_4BA_QSPI_FAST_READ_CMD
+ & TERCEL_SPI_4BA_QSPI_CMD_MASK) <<
+ TERCEL_SPI_4BA_QSPI_CMD_SHIFT;
+ dword |= (MICRON_N25Q_SPI_3BA_QSPI_FAST_READ_CMD
+ & TERCEL_SPI_3BA_QSPI_CMD_MASK) <<
+ TERCEL_SPI_3BA_QSPI_CMD_SHIFT;
+ dword |= (MICRON_N25Q_SPI_4BA_SPI_FAST_READ_CMD &
+ TERCEL_SPI_4BA_SPI_CMD_MASK) <<
+ TERCEL_SPI_4BA_SPI_CMD_SHIFT;
+ dword |= (MICRON_N25Q_SPI_3BA_SPI_FAST_READ_CMD &
+ TERCEL_SPI_3BA_SPI_CMD_MASK) <<
+ TERCEL_SPI_3BA_SPI_CMD_SHIFT;
+ write_tercel_register(TERCEL_SPI_REG_SYS_FLASH_CFG2, dword);
+
+ dword = 0;
+ dword |= (MICRON_N25Q_SPI_4BA_QSPI_PAGE_PROGRAM_CMD
+ & TERCEL_SPI_4BA_QSPI_CMD_MASK) <<
+ TERCEL_SPI_4BA_QSPI_CMD_SHIFT;
+ dword |= (MICRON_N25Q_SPI_3BA_QSPI_PAGE_PROGRAM_CMD
+ & TERCEL_SPI_3BA_QSPI_CMD_MASK) <<
+ TERCEL_SPI_3BA_QSPI_CMD_SHIFT;
+ dword |= (MICRON_N25Q_SPI_4BA_SPI_PAGE_PROGRAM_CMD &
+ TERCEL_SPI_4BA_SPI_CMD_MASK) <<
+ TERCEL_SPI_4BA_SPI_CMD_SHIFT;
+ dword |= (MICRON_N25Q_SPI_3BA_SPI_PAGE_PROGRAM_CMD &
+ TERCEL_SPI_3BA_SPI_CMD_MASK) <<
+ TERCEL_SPI_3BA_SPI_CMD_SHIFT;
+ write_tercel_register(TERCEL_SPI_REG_SYS_FLASH_CFG3, dword);
+
+ // Enable extended QSPI read/write operations
+ dword = read_tercel_register(TERCEL_SPI_REG_SYS_PHY_CFG1);
+ dword |= TERCEL_SPI_PHY_QSPI_EXT_READ_EN_MASK <<
+ TERCEL_SPI_PHY_QSPI_EXT_READ_EN_SHIFT;
+ dword |= TERCEL_SPI_PHY_QSPI_EXT_WRITE_EN_MASK <<
+ TERCEL_SPI_PHY_QSPI_EXT_WRITE_EN_SHIFT;
+ write_tercel_register(TERCEL_SPI_REG_SYS_PHY_CFG1, dword);
+
+ break;
+ }
+ }
+
+ // Set SPI core to automatic mode
+ write_tercel_register(TERCEL_SPI_REG_SYS_CORE_CTL1,
+ read_tercel_register(TERCEL_SPI_REG_SYS_CORE_CTL1) &
+ ~(TERCEL_SPI_ENABLE_USER_MODE_MASK <<
+ TERCEL_SPI_ENABLE_USER_MODE_SHIFT));
+
+ // Set extra CS delay cycle count to 0
+ dword = read_tercel_register(TERCEL_SPI_REG_SYS_PHY_CFG1);
+ dword &= ~(TERCEL_SPI_PHY_CS_EXTRA_IDLE_CYC_MASK <<
+ TERCEL_SPI_PHY_CS_EXTRA_IDLE_CYC_SHIFT);
+ dword |= ((0 & TERCEL_SPI_PHY_CS_EXTRA_IDLE_CYC_MASK) <<
+ TERCEL_SPI_PHY_CS_EXTRA_IDLE_CYC_SHIFT);
+ write_tercel_register(TERCEL_SPI_REG_SYS_PHY_CFG1, dword);
+
+ // Set maximum CS assert cycle count to 10000
+ dword = read_tercel_register(TERCEL_SPI_REG_SYS_FLASH_CFG4);
+ dword &= ~(TERCEL_SPI_FLASH_CS_EN_LIMIT_CYC_MASK <<
+ TERCEL_SPI_FLASH_CS_EN_LIMIT_CYC_SHIFT);
+ dword |= ((10000 & TERCEL_SPI_FLASH_CS_EN_LIMIT_CYC_MASK) <<
+ TERCEL_SPI_FLASH_CS_EN_LIMIT_CYC_SHIFT);
+ write_tercel_register(TERCEL_SPI_REG_SYS_FLASH_CFG4, dword);
+
+ // Set SPI fast read dummy cycles to
+ // MICRON_N25Q_SPI_FAST_READ_DUMMY_CLOCK_CYCLES
+ dword = read_tercel_register(TERCEL_SPI_REG_SYS_PHY_CFG1);
+ dword &= ~(TERCEL_SPI_PHY_DUMMY_CYCLES_MASK <<
+ TERCEL_SPI_PHY_DUMMY_CYCLES_SHIFT);
+ dword |= ((MICRON_N25Q_SPI_FAST_READ_DUMMY_CLOCK_CYCLES
+ & TERCEL_SPI_PHY_DUMMY_CYCLES_MASK) <<
+ TERCEL_SPI_PHY_DUMMY_CYCLES_SHIFT);
+ write_tercel_register(TERCEL_SPI_REG_SYS_PHY_CFG1, dword);
+
+ // Enable SPI fast read functionality
+ dword = read_tercel_register(TERCEL_SPI_REG_SYS_PHY_CFG1);
+ dword &= ~(TERCEL_SPI_PHY_FAST_READ_ENABLE_MASK <<
+ TERCEL_SPI_PHY_FAST_READ_ENABLE_SHIFT);
+ dword |= ((1 & TERCEL_SPI_PHY_FAST_READ_ENABLE_MASK) <<
+ TERCEL_SPI_PHY_FAST_READ_ENABLE_SHIFT);
+ write_tercel_register(TERCEL_SPI_REG_SYS_PHY_CFG1, dword);
+
+ // Set SPI controller to 4BA mode
+ dword = read_tercel_register(TERCEL_SPI_REG_SYS_PHY_CFG1);
+ dword &= ~(TERCEL_SPI_PHY_4BA_ENABLE_MASK <<
+ TERCEL_SPI_PHY_4BA_ENABLE_SHIFT);
+ dword |= ((TERCEL_SPI_PHY_4BA_MODE & TERCEL_SPI_PHY_4BA_ENABLE_MASK)
+ << TERCEL_SPI_PHY_4BA_ENABLE_SHIFT);
+ write_tercel_register(TERCEL_SPI_REG_SYS_PHY_CFG1, dword);
+
+#if (ALLOW_SPI_QUAD_MODE)
+ // Set SPI controller to QSPI mode
+ dword = read_tercel_register(TERCEL_SPI_REG_SYS_PHY_CFG1);
+ dword &= ~(TERCEL_SPI_PHY_IO_TYPE_MASK << TERCEL_SPI_PHY_IO_TYPE_SHIFT);
+ dword |= ((TERCEL_SPI_PHY_IO_TYPE_QUAD & TERCEL_SPI_PHY_IO_TYPE_MASK)
+ << TERCEL_SPI_PHY_IO_TYPE_SHIFT);
+ write_tercel_register(TERCEL_SPI_REG_SYS_PHY_CFG1, dword);
+#endif
+
+ // Set SPI clock cycle divider to 5
+ dword = read_tercel_register(TERCEL_SPI_REG_SYS_PHY_CFG1);
+ dword &= ~(TERCEL_SPI_PHY_CLOCK_DIVISOR_MASK <<
+ TERCEL_SPI_PHY_CLOCK_DIVISOR_SHIFT);
+ dword |= ((5 & TERCEL_SPI_PHY_CLOCK_DIVISOR_MASK) <<
+ TERCEL_SPI_PHY_CLOCK_DIVISOR_SHIFT);
+ write_tercel_register(TERCEL_SPI_REG_SYS_PHY_CFG1, dword);
+
+ // Calculate and dump configured SPI clock speed
+ uint8_t spi_divisor =
+ (read_tercel_register(TERCEL_SPI_REG_SYS_PHY_CFG1)
+ >> TERCEL_SPI_PHY_CLOCK_DIVISOR_SHIFT) &
+ TERCEL_SPI_PHY_CLOCK_DIVISOR_MASK;
+ spi_divisor = (spi_divisor + 1) * 2;
+ uint8_t spi_dummy_cycles =
+ (read_tercel_register(TERCEL_SPI_REG_SYS_PHY_CFG1)
+ >> TERCEL_SPI_PHY_DUMMY_CYCLES_SHIFT) &
+ TERCEL_SPI_PHY_DUMMY_CYCLES_MASK;
+ puts("Flash controller frequency ");
+ uart_writeuint32((read_tercel_register(TERCEL_SPI_REG_SYS_CLK_FREQ) /
+ spi_divisor) / 1000000);
+ puts("\nbus frequency ");
+ uart_writeuint32(read_tercel_register(TERCEL_SPI_REG_SYS_CLK_FREQ) /
+ 1000000);
+ puts("\ndummy cycles");
+ uart_writeuint32(spi_dummy_cycles);
+ puts("\n");
+
+ // Enable read merging
+ write_tercel_register(TERCEL_SPI_REG_SYS_FLASH_CFG5,
+ read_tercel_register(TERCEL_SPI_REG_SYS_FLASH_CFG5) |
+ (TERCEL_SPI_FLASH_EN_MULTCYC_READ_MASK <<
+ TERCEL_SPI_FLASH_EN_MULTCYC_READ_SHIFT));
+
+ // Enable write merging
+ write_tercel_register(TERCEL_SPI_REG_SYS_FLASH_CFG5,
+ read_tercel_register(TERCEL_SPI_REG_SYS_FLASH_CFG5)
+ |
+ (TERCEL_SPI_FLASH_EN_MULTCYC_WRITE_MASK <<
+ TERCEL_SPI_FLASH_EN_MULTCYC_WRITE_SHIFT));
+
+ return 0;
+}
+
--- /dev/null
+// © 2020 Raptor Engineering, LLC
+//
+// Released under the terms of the GPL v3
+// See the LICENSE file for full details
+
+#define TERCEL_SPI_REG_DEVICE_ID_HIGH 0x0
+#define TERCEL_SPI_REG_DEVICE_ID_LOW 0x4
+#define TERCEL_SPI_REG_DEVICE_VERSION 0x8
+#define TERCEL_SPI_REG_SYS_CLK_FREQ 0xc
+#define TERCEL_SPI_REG_SYS_PHY_CFG1 0x10
+#define TERCEL_SPI_REG_SYS_FLASH_CFG1 0x14
+#define TERCEL_SPI_REG_SYS_FLASH_CFG2 0x18
+#define TERCEL_SPI_REG_SYS_FLASH_CFG3 0x1c
+#define TERCEL_SPI_REG_SYS_FLASH_CFG4 0x20
+#define TERCEL_SPI_REG_SYS_FLASH_CFG5 0x24
+#define TERCEL_SPI_REG_SYS_CORE_CTL1 0x28
+#define TERCEL_SPI_REG_SYS_CORE_DATA1 0x2c
+
+#define TERCEL_SPI_DEVICE_ID_HIGH 0x7c525054
+#define TERCEL_SPI_DEVICE_ID_LOW 0x5350494d
+
+#define TERCEL_SPI_VERSION_MAJOR_MASK 0xffff
+#define TERCEL_SPI_VERSION_MAJOR_SHIFT 16
+#define TERCEL_SPI_VERSION_MINOR_MASK 0xff
+#define TERCEL_SPI_VERSION_MINOR_SHIFT 8
+#define TERCEL_SPI_VERSION_PATCH_MASK 0xff
+#define TERCEL_SPI_VERSION_PATCH_SHIFT 0
+
+#define TERCEL_SPI_ENABLE_USER_MODE_MASK 0x1
+#define TERCEL_SPI_ENABLE_USER_MODE_SHIFT 0x0
+#define TERCEL_SPI_PHY_DUMMY_CYCLES_MASK 0xff
+#define TERCEL_SPI_PHY_DUMMY_CYCLES_SHIFT 8
+#define TERCEL_SPI_PHY_CLOCK_DIVISOR_MASK 0xff
+#define TERCEL_SPI_PHY_CLOCK_DIVISOR_SHIFT 0
+#define TERCEL_SPI_PHY_IO_TYPE_MASK 0x3
+#define TERCEL_SPI_PHY_IO_TYPE_SHIFT 16
+#define TERCEL_SPI_PHY_4BA_ENABLE_MASK 0x1
+#define TERCEL_SPI_PHY_4BA_ENABLE_SHIFT 18
+#define TERCEL_SPI_PHY_FAST_READ_ENABLE_MASK 0x1
+#define TERCEL_SPI_PHY_FAST_READ_ENABLE_SHIFT 19
+#define TERCEL_SPI_PHY_QSPI_EXT_READ_EN_MASK 0x1
+#define TERCEL_SPI_PHY_QSPI_EXT_READ_EN_SHIFT 20
+#define TERCEL_SPI_PHY_QSPI_EXT_WRITE_EN_MASK 0x1
+#define TERCEL_SPI_PHY_QSPI_EXT_WRITE_EN_SHIFT 21
+#define TERCEL_SPI_PHY_CS_EXTRA_IDLE_CYC_MASK 0xff
+#define TERCEL_SPI_PHY_CS_EXTRA_IDLE_CYC_SHIFT 24
+#define TERCEL_SPI_FLASH_EN_MULTCYC_WRITE_MASK 0x1
+#define TERCEL_SPI_FLASH_EN_MULTCYC_WRITE_SHIFT 1
+#define TERCEL_SPI_FLASH_EN_MULTCYC_READ_MASK 0x1
+#define TERCEL_SPI_FLASH_EN_MULTCYC_READ_SHIFT 0
+#define TERCEL_SPI_FLASH_CS_EN_LIMIT_CYC_MASK 0xffffffff
+#define TERCEL_SPI_FLASH_CS_EN_LIMIT_CYC_SHIFT 0
+
+#define TERCEL_SPI_3BA_SPI_CMD_MASK 0xff
+#define TERCEL_SPI_3BA_SPI_CMD_SHIFT 0
+#define TERCEL_SPI_4BA_SPI_CMD_MASK 0xff
+#define TERCEL_SPI_4BA_SPI_CMD_SHIFT 8
+#define TERCEL_SPI_3BA_QSPI_CMD_MASK 0xff
+#define TERCEL_SPI_3BA_QSPI_CMD_SHIFT 16
+#define TERCEL_SPI_4BA_QSPI_CMD_MASK 0xff
+#define TERCEL_SPI_4BA_QSPI_CMD_SHIFT 24
+
+#define TERCEL_SPI_PHY_IO_TYPE_SINGLE 0x0
+#define TERCEL_SPI_PHY_IO_TYPE_QUAD 0x2
+
+#define TERCEL_SPI_PHY_3BA_MODE 0x0
+#define TERCEL_SPI_PHY_4BA_MODE 0x1
+