/**
* xqspips_init_hw - Initialize the hardware
* @regs_base: Base address of QSPI controller
+ * @is_dual: Indicates whether dual memories are used
*
* The default settings of the QSPI controller's configurable parameters on
* reset are
* - Set the little endian mode of TX FIFO and
* - Enable the QSPI controller
**/
-void xqspips_init_hw(void __iomem *regs_base)
+void xqspips_init_hw(void __iomem *regs_base, unsigned int is_dual)
{
u32 config_reg;
config_reg |= 0x8000FCC1;
xqspips_write(regs_base + XQSPIPSS_CONFIG_OFFSET, config_reg);
-#ifdef CONFIG_XILINX_PSS_QSPI_USE_DUAL_FLASH
- xqspips_write(regs_base + XQSPIPSS_LINEAR_CFG_OFFSET, 0x6400016B);
-#endif
+ if (is_dual == 1)
+ /* Enable two memories on seperate buses */
+ xqspips_write(regs_base + XQSPIPSS_LINEAR_CFG_OFFSET,
+ 0x6400016B);
xqspips_write(regs_base + XQSPIPSS_ENABLE_OFFSET,
XQSPIPSS_ENABLE_ENABLE_MASK);
xqspi->curr_inst = &flash_inst[index];
xqspi->inst_response = 1;
-#ifdef CONFIG_XILINX_PSS_QSPI_USE_DUAL_FLASH
/* In case of dual memories, convert 25 bit address to 24 bit
* address before transmitting to the 2 memories
*/
- if ((instruction == XQSPIPSS_FLASH_OPCODE_PP) ||
+ if ((xqspi->is_dual == 1) &&
+ ((instruction == XQSPIPSS_FLASH_OPCODE_PP) ||
(instruction == XQSPIPSS_FLASH_OPCODE_SE) ||
(instruction == XQSPIPSS_FLASH_OPCODE_BE_32K) ||
(instruction == XQSPIPSS_FLASH_OPCODE_BE_4K) ||
(instruction == XQSPIPSS_FLASH_OPCODE_NORM_READ) ||
(instruction == XQSPIPSS_FLASH_OPCODE_FAST_READ) ||
(instruction == XQSPIPSS_FLASH_OPCODE_DUAL_READ) ||
- (instruction == XQSPIPSS_FLASH_OPCODE_QUAD_READ)) {
+ (instruction == XQSPIPSS_FLASH_OPCODE_QUAD_READ))) {
u8 *ptr = (u8*) (xqspi->txbuf);
data = ((u32) ptr[1] << 24) | ((u32) ptr[2] << 16) |
xqspi->bytes_to_transfer -= 1;
xqspi->bytes_to_receive -= 1;
}
-#endif
/* Get the instruction */
data = 0;
MODULE_LICENSE("GPL");
#endif
+
+/**
+ * xqspips_check_is_dual_flash - checking for dual or single qspi
+ *
+ * This function will check the type of the flash whether it supports
+ * single or dual qspi based on the MIO configuration done by FSBL.
+ *
+ * User needs to correctly configure the MIO's based on the
+ * number of qspi flashes present on the board.
+ *
+ * function will return -1, if there is no MIO configuration for
+ * qspi flash.
+ *
+ * @regs_base: base address of SLCR
+ */
+
+int xqspips_check_is_dual_flash(void __iomem *regs_base)
+{
+ int is_dual = -1, lower_mio = 0, upper_mio = 0, val;
+ u16 mask = 3, type = 2;
+ u32 mio_base, mio_pin_index;
+
+#ifdef CONFIG_EP107
+#ifdef CONFIG_XILINX_PSS_QSPI_USE_DUAL_FLASH
+ is_dual = 1;
+#else
+ is_dual = 0;
+#endif
+ return is_dual;
+#endif
+
+ mio_base = regs_base + 0x700;
+
+ /* checking single QSPI MIO's */
+ for (mio_pin_index = 2; mio_pin_index < 7; mio_pin_index++) {
+ val = xqspips_read(mio_base + 4 * mio_pin_index);
+ if ((val & mask) == type)
+ lower_mio++;
+ }
+
+ /* checking dual QSPI MIO's */
+ for (mio_pin_index = 8; mio_pin_index < 14; mio_pin_index++) {
+ val = xqspips_read(mio_base + 4 * mio_pin_index);
+ if ((val & mask) == type)
+ upper_mio++;
+ }
+
+ if ((lower_mio == 5) && (upper_mio == 6))
+ is_dual = 1;
+ else if (lower_mio == 5)
+ is_dual = 0;
+
+ return is_dual;
+}
struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
unsigned int max_hz, unsigned int mode)
{
+ int is_dual;
struct zynq_spi_slave *pspi;
#ifdef DEBUG
bus, cs, max_hz, mode);
#endif
- xqspips_init_hw((void *)XPSS_QSPI_BASEADDR);
+ is_dual = xqspips_check_is_dual_flash((void *)XPSS_SYS_CTRL_BASEADDR);
+
+ if (is_dual == -1) {
+ printf("SPI error: No QSPI device detected based"
+ " on MIO settings\n");
+ return NULL;
+ }
+
+ xqspips_init_hw((void *)XPSS_QSPI_BASEADDR, is_dual);
pspi = malloc(sizeof(struct zynq_spi_slave));
if (!pspi) {
}
pspi->slave.bus = bus;
pspi->slave.cs = cs;
+ pspi->slave.is_dual = is_dual;
pspi->qspi.master.input_clk_hz = 100000000;
pspi->qspi.master.speed_hz = pspi->qspi.master.input_clk_hz / 2;
pspi->qspi.max_speed_hz = pspi->qspi.master.speed_hz;
pspi->qspi.master.dev_busy = 0;
pspi->qspi.master.regs = (void*)XPSS_QSPI_BASEADDR;
+ pspi->qspi.master.is_dual = is_dual;
pspi->qspi.mode = mode;
pspi->qspi.chip_select = 0;
pspi->qspi.bits_per_word = 32;