return is_dual;
}
+
+/**
+ * xqspips_write_quad_bit - Write 1 to QUAD bit on flash
+ *
+ * This function will write a 1 to quad bit in flash
+ * using QSPI controller and supports only spansion flash.
+ *
+ * @regs_base: base address of QSPI controller
+ */
+void xqspips_write_quad_bit(void __iomem *regs_base)
+{
+ u32 config_reg, intr_status;
+
+ /* enable the QSPI controller */
+ xqspips_write(regs_base + XQSPIPSS_ENABLE_OFFSET,
+ XQSPIPSS_ENABLE_ENABLE_MASK);
+
+ /* Write QUAD bit with 3-byte instruction */
+ xqspips_write(regs_base + XQSPIPSS_TXD_00_11_OFFSET, 0x20001);
+
+ /* Enable manual start command */
+ config_reg = xqspips_read(regs_base +
+ XQSPIPSS_CONFIG_OFFSET) | XQSPIPSS_CONFIG_MANSRT_MASK;
+ xqspips_write(regs_base + XQSPIPSS_CONFIG_OFFSET, config_reg);
+
+ /* Wait for the transfer to finish by polling Tx fifo status */
+ do {
+ intr_status = xqspips_read(regs_base +
+ XQSPIPSS_STATUS_OFFSET);
+ } while ((intr_status & 0x04) == 0);
+
+ /* Read data receive register */
+ config_reg = xqspips_read(regs_base + XQSPIPSS_RXD_OFFSET);
+}
extern int xqspips_transfer(struct spi_device *qspi,
struct spi_transfer *transfer);
extern int xqspips_check_is_dual_flash(void *regs_base);
+extern void xqspips_write_quad_bit(void *regs_base);
+/* Few mtd flash functions */
+extern int spi_flash_cmd(struct spi_slave *spi, u8 cmd,
+ void *response, size_t len);
+extern int spi_flash_cmd_read(struct spi_slave *spi, const u8 *cmd,
+ size_t cmd_len, void *data, size_t data_len);
/**************************************************************************/
#endif
debug("spi_init\n");
}
+/**
+ * spi_enable_quad_bit - Enable the QUAD bit for SPI flash
+ *
+ * This function will enable the quad bit in flash using
+ * the QSPI controller. Supports only spansion.
+ *
+ * @spi : SPI slave structure
+ */
+void spi_enable_quad_bit(struct spi_slave *spi)
+{
+ int ret;
+ u8 idcode[5];
+ u8 rdid_cmd = 0x9f; /* RDID */
+ u8 rcr_data = 0;
+ u8 rcr_cmd = 0x35; /* RCR */
+ u8 rdsr_cmd = 0x05; /* RDSR */
+ u8 wren_cmd = 0x06; /* WREN */
+
+ ret = spi_flash_cmd(spi, rdid_cmd, &idcode, sizeof(idcode));
+ if (ret) {
+ debug("SF error: Failed read RDID\n");
+ return;
+ }
+
+ if (idcode[0] == 0x01) {
+ /* Read config register */
+ ret = spi_flash_cmd_read(spi, &rcr_cmd, sizeof(rcr_cmd),
+ &rcr_data, sizeof(rcr_data));
+ if (ret) {
+ debug("SF error: Failed read RCR\n");
+ return;
+ }
+
+ if (rcr_data & 0x2)
+ debug("QUAD bit is already set..\n");
+ else {
+ debug("QUAD bit needs to be set ..\n");
+
+ /* Write enable */
+ ret = spi_flash_cmd(spi, wren_cmd, NULL, 0);
+ if (ret) {
+ debug("SF error: Failed write WREN\n");
+ return;
+ }
+
+ /* Write QUAD bit */
+ xqspips_write_quad_bit((void *)XPSS_QSPI_BASEADDR);
+
+ /* Read RDSR */
+ do {
+ ret = spi_flash_cmd_read(spi, &rdsr_cmd,
+ sizeof(rdsr_cmd), &rcr_data,
+ sizeof(rcr_data));
+ } while ((ret == 0) && (rcr_data != 0));
+
+ /* Read config register */
+ ret = spi_flash_cmd_read(spi, &rcr_cmd, sizeof(rcr_cmd),
+ &rcr_data, sizeof(rcr_data));
+ if (!(rcr_data & 0x2)) {
+ printf("SF error: Fail to set QUAD enable bit"
+ " 0x%x\n", rcr_data);
+ return;
+ } else
+ debug("SF: QUAD enable bit is set 0x%x\n",
+ rcr_data);
+ }
+ } else
+ debug("SF: QUAD bit not enabled for 0x%x SPI flash\n",
+ idcode[0]);
+
+ return;
+}
+
struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
unsigned int max_hz, unsigned int mode)
{
pspi->qspi.bits_per_word = 32;
xqspips_setup_transfer(&pspi->qspi, NULL);
+ spi_enable_quad_bit(&pspi->slave);
+
return &pspi->slave;
}