mtd: spi-nor: atmel-quadspi: Remove unused code from atmel-quadspi driver
Code used for previous interface is no longer needed. This change just removes obsolete code. Suggested-by: Boris Brezillon <boris.brezillon@bootlin.com> Signed-off-by: Piotr Bugalski <bugalski.piotr@gmail.com> Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
2d30ac5ed6
commit
6ca622c871
|
@ -29,14 +29,9 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/mtd/spi-nor.h>
|
||||
#include <linux/platform_data/atmel.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/spi/spi-mem.h>
|
||||
|
||||
/* QSPI register offsets */
|
||||
|
@ -160,35 +155,9 @@ struct atmel_qspi {
|
|||
struct clk *clk;
|
||||
struct platform_device *pdev;
|
||||
u32 pending;
|
||||
|
||||
struct spi_nor nor;
|
||||
u32 clk_rate;
|
||||
struct completion cmd_completion;
|
||||
};
|
||||
|
||||
struct atmel_qspi_command {
|
||||
union {
|
||||
struct {
|
||||
u32 instruction:1;
|
||||
u32 address:3;
|
||||
u32 mode:1;
|
||||
u32 dummy:1;
|
||||
u32 data:1;
|
||||
u32 reserved:25;
|
||||
} bits;
|
||||
u32 word;
|
||||
} enable;
|
||||
u8 instruction;
|
||||
u8 mode;
|
||||
u8 num_mode_cycles;
|
||||
u8 num_dummy_cycles;
|
||||
u32 address;
|
||||
|
||||
size_t buf_len;
|
||||
const void *tx_buf;
|
||||
void *rx_buf;
|
||||
};
|
||||
|
||||
struct qspi_mode {
|
||||
u8 cmd_buswidth;
|
||||
u8 addr_buswidth;
|
||||
|
@ -407,363 +376,6 @@ static int atmel_qspi_setup(struct spi_device *spi)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int atmel_qspi_run_transfer(struct atmel_qspi *aq,
|
||||
const struct atmel_qspi_command *cmd)
|
||||
{
|
||||
void __iomem *ahb_mem;
|
||||
|
||||
/* Then fallback to a PIO transfer (memcpy() DOES NOT work!) */
|
||||
ahb_mem = aq->mem;
|
||||
if (cmd->enable.bits.address)
|
||||
ahb_mem += cmd->address;
|
||||
if (cmd->tx_buf)
|
||||
_memcpy_toio(ahb_mem, cmd->tx_buf, cmd->buf_len);
|
||||
else
|
||||
_memcpy_fromio(cmd->rx_buf, ahb_mem, cmd->buf_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static void atmel_qspi_debug_command(struct atmel_qspi *aq,
|
||||
const struct atmel_qspi_command *cmd,
|
||||
u32 ifr)
|
||||
{
|
||||
u8 cmd_buf[SPI_NOR_MAX_CMD_SIZE];
|
||||
size_t len = 0;
|
||||
int i;
|
||||
|
||||
if (cmd->enable.bits.instruction)
|
||||
cmd_buf[len++] = cmd->instruction;
|
||||
|
||||
for (i = cmd->enable.bits.address-1; i >= 0; --i)
|
||||
cmd_buf[len++] = (cmd->address >> (i << 3)) & 0xff;
|
||||
|
||||
if (cmd->enable.bits.mode)
|
||||
cmd_buf[len++] = cmd->mode;
|
||||
|
||||
if (cmd->enable.bits.dummy) {
|
||||
int num = cmd->num_dummy_cycles;
|
||||
|
||||
switch (ifr & QSPI_IFR_WIDTH_MASK) {
|
||||
case QSPI_IFR_WIDTH_SINGLE_BIT_SPI:
|
||||
case QSPI_IFR_WIDTH_DUAL_OUTPUT:
|
||||
case QSPI_IFR_WIDTH_QUAD_OUTPUT:
|
||||
num >>= 3;
|
||||
break;
|
||||
case QSPI_IFR_WIDTH_DUAL_IO:
|
||||
case QSPI_IFR_WIDTH_DUAL_CMD:
|
||||
num >>= 2;
|
||||
break;
|
||||
case QSPI_IFR_WIDTH_QUAD_IO:
|
||||
case QSPI_IFR_WIDTH_QUAD_CMD:
|
||||
num >>= 1;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < num; ++i)
|
||||
cmd_buf[len++] = 0;
|
||||
}
|
||||
|
||||
/* Dump the SPI command */
|
||||
print_hex_dump(KERN_DEBUG, "qspi cmd: ", DUMP_PREFIX_NONE,
|
||||
32, 1, cmd_buf, len, false);
|
||||
|
||||
#ifdef VERBOSE_DEBUG
|
||||
/* If verbose debug is enabled, also dump the TX data */
|
||||
if (cmd->enable.bits.data && cmd->tx_buf)
|
||||
print_hex_dump(KERN_DEBUG, "qspi tx : ", DUMP_PREFIX_NONE,
|
||||
32, 1, cmd->tx_buf, cmd->buf_len, false);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
#define atmel_qspi_debug_command(aq, cmd, ifr)
|
||||
#endif
|
||||
|
||||
static int atmel_qspi_run_command(struct atmel_qspi *aq,
|
||||
const struct atmel_qspi_command *cmd,
|
||||
u32 ifr_tfrtyp, enum spi_nor_protocol proto)
|
||||
{
|
||||
u32 iar, icr, ifr, sr;
|
||||
int err = 0;
|
||||
|
||||
iar = 0;
|
||||
icr = 0;
|
||||
ifr = ifr_tfrtyp;
|
||||
|
||||
/* Set the SPI protocol */
|
||||
switch (proto) {
|
||||
case SNOR_PROTO_1_1_1:
|
||||
ifr |= QSPI_IFR_WIDTH_SINGLE_BIT_SPI;
|
||||
break;
|
||||
|
||||
case SNOR_PROTO_1_1_2:
|
||||
ifr |= QSPI_IFR_WIDTH_DUAL_OUTPUT;
|
||||
break;
|
||||
|
||||
case SNOR_PROTO_1_1_4:
|
||||
ifr |= QSPI_IFR_WIDTH_QUAD_OUTPUT;
|
||||
break;
|
||||
|
||||
case SNOR_PROTO_1_2_2:
|
||||
ifr |= QSPI_IFR_WIDTH_DUAL_IO;
|
||||
break;
|
||||
|
||||
case SNOR_PROTO_1_4_4:
|
||||
ifr |= QSPI_IFR_WIDTH_QUAD_IO;
|
||||
break;
|
||||
|
||||
case SNOR_PROTO_2_2_2:
|
||||
ifr |= QSPI_IFR_WIDTH_DUAL_CMD;
|
||||
break;
|
||||
|
||||
case SNOR_PROTO_4_4_4:
|
||||
ifr |= QSPI_IFR_WIDTH_QUAD_CMD;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Compute instruction parameters */
|
||||
if (cmd->enable.bits.instruction) {
|
||||
icr |= QSPI_ICR_INST(cmd->instruction);
|
||||
ifr |= QSPI_IFR_INSTEN;
|
||||
}
|
||||
|
||||
/* Compute address parameters */
|
||||
switch (cmd->enable.bits.address) {
|
||||
case 4:
|
||||
ifr |= QSPI_IFR_ADDRL;
|
||||
/* fall through to the 24bit (3 byte) address case. */
|
||||
case 3:
|
||||
iar = (cmd->enable.bits.data) ? 0 : cmd->address;
|
||||
ifr |= QSPI_IFR_ADDREN;
|
||||
break;
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Compute option parameters */
|
||||
if (cmd->enable.bits.mode && cmd->num_mode_cycles) {
|
||||
u32 mode_cycle_bits, mode_bits;
|
||||
|
||||
icr |= QSPI_ICR_OPT(cmd->mode);
|
||||
ifr |= QSPI_IFR_OPTEN;
|
||||
|
||||
switch (ifr & QSPI_IFR_WIDTH_MASK) {
|
||||
case QSPI_IFR_WIDTH_SINGLE_BIT_SPI:
|
||||
case QSPI_IFR_WIDTH_DUAL_OUTPUT:
|
||||
case QSPI_IFR_WIDTH_QUAD_OUTPUT:
|
||||
mode_cycle_bits = 1;
|
||||
break;
|
||||
case QSPI_IFR_WIDTH_DUAL_IO:
|
||||
case QSPI_IFR_WIDTH_DUAL_CMD:
|
||||
mode_cycle_bits = 2;
|
||||
break;
|
||||
case QSPI_IFR_WIDTH_QUAD_IO:
|
||||
case QSPI_IFR_WIDTH_QUAD_CMD:
|
||||
mode_cycle_bits = 4;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mode_bits = cmd->num_mode_cycles * mode_cycle_bits;
|
||||
switch (mode_bits) {
|
||||
case 1:
|
||||
ifr |= QSPI_IFR_OPTL_1BIT;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
ifr |= QSPI_IFR_OPTL_2BIT;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
ifr |= QSPI_IFR_OPTL_4BIT;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
ifr |= QSPI_IFR_OPTL_8BIT;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set number of dummy cycles */
|
||||
if (cmd->enable.bits.dummy)
|
||||
ifr |= QSPI_IFR_NBDUM(cmd->num_dummy_cycles);
|
||||
|
||||
/* Set data enable */
|
||||
if (cmd->enable.bits.data) {
|
||||
ifr |= QSPI_IFR_DATAEN;
|
||||
|
||||
/* Special case for Continuous Read Mode */
|
||||
if (!cmd->tx_buf && !cmd->rx_buf)
|
||||
ifr |= QSPI_IFR_CRM;
|
||||
}
|
||||
|
||||
/* Clear pending interrupts */
|
||||
(void)qspi_readl(aq, QSPI_SR);
|
||||
|
||||
/* Set QSPI Instruction Frame registers */
|
||||
atmel_qspi_debug_command(aq, cmd, ifr);
|
||||
qspi_writel(aq, QSPI_IAR, iar);
|
||||
qspi_writel(aq, QSPI_ICR, icr);
|
||||
qspi_writel(aq, QSPI_IFR, ifr);
|
||||
|
||||
/* Skip to the final steps if there is no data */
|
||||
if (!cmd->enable.bits.data)
|
||||
goto no_data;
|
||||
|
||||
/* Dummy read of QSPI_IFR to synchronize APB and AHB accesses */
|
||||
(void)qspi_readl(aq, QSPI_IFR);
|
||||
|
||||
/* Stop here for continuous read */
|
||||
if (!cmd->tx_buf && !cmd->rx_buf)
|
||||
return 0;
|
||||
/* Send/Receive data */
|
||||
err = atmel_qspi_run_transfer(aq, cmd);
|
||||
|
||||
/* Release the chip-select */
|
||||
qspi_writel(aq, QSPI_CR, QSPI_CR_LASTXFER);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
#if defined(DEBUG) && defined(VERBOSE_DEBUG)
|
||||
/*
|
||||
* If verbose debug is enabled, also dump the RX data in addition to
|
||||
* the SPI command previously dumped by atmel_qspi_debug_command()
|
||||
*/
|
||||
if (cmd->rx_buf)
|
||||
print_hex_dump(KERN_DEBUG, "qspi rx : ", DUMP_PREFIX_NONE,
|
||||
32, 1, cmd->rx_buf, cmd->buf_len, false);
|
||||
#endif
|
||||
no_data:
|
||||
/* Poll INSTRuction End status */
|
||||
sr = qspi_readl(aq, QSPI_SR);
|
||||
if ((sr & QSPI_SR_CMD_COMPLETED) == QSPI_SR_CMD_COMPLETED)
|
||||
return err;
|
||||
|
||||
/* Wait for INSTRuction End interrupt */
|
||||
reinit_completion(&aq->cmd_completion);
|
||||
aq->pending = sr & QSPI_SR_CMD_COMPLETED;
|
||||
qspi_writel(aq, QSPI_IER, QSPI_SR_CMD_COMPLETED);
|
||||
if (!wait_for_completion_timeout(&aq->cmd_completion,
|
||||
msecs_to_jiffies(1000)))
|
||||
err = -ETIMEDOUT;
|
||||
qspi_writel(aq, QSPI_IDR, QSPI_SR_CMD_COMPLETED);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int atmel_qspi_read_reg(struct spi_nor *nor, u8 opcode,
|
||||
u8 *buf, int len)
|
||||
{
|
||||
struct atmel_qspi *aq = nor->priv;
|
||||
struct atmel_qspi_command cmd;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.enable.bits.instruction = 1;
|
||||
cmd.enable.bits.data = 1;
|
||||
cmd.instruction = opcode;
|
||||
cmd.rx_buf = buf;
|
||||
cmd.buf_len = len;
|
||||
return atmel_qspi_run_command(aq, &cmd, QSPI_IFR_TFRTYP_TRSFR_READ,
|
||||
nor->reg_proto);
|
||||
}
|
||||
|
||||
static int atmel_qspi_write_reg(struct spi_nor *nor, u8 opcode,
|
||||
u8 *buf, int len)
|
||||
{
|
||||
struct atmel_qspi *aq = nor->priv;
|
||||
struct atmel_qspi_command cmd;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.enable.bits.instruction = 1;
|
||||
cmd.enable.bits.data = (buf != NULL && len > 0);
|
||||
cmd.instruction = opcode;
|
||||
cmd.tx_buf = buf;
|
||||
cmd.buf_len = len;
|
||||
return atmel_qspi_run_command(aq, &cmd, QSPI_IFR_TFRTYP_TRSFR_WRITE,
|
||||
nor->reg_proto);
|
||||
}
|
||||
|
||||
static ssize_t atmel_qspi_write(struct spi_nor *nor, loff_t to, size_t len,
|
||||
const u_char *write_buf)
|
||||
{
|
||||
struct atmel_qspi *aq = nor->priv;
|
||||
struct atmel_qspi_command cmd;
|
||||
ssize_t ret;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.enable.bits.instruction = 1;
|
||||
cmd.enable.bits.address = nor->addr_width;
|
||||
cmd.enable.bits.data = 1;
|
||||
cmd.instruction = nor->program_opcode;
|
||||
cmd.address = (u32)to;
|
||||
cmd.tx_buf = write_buf;
|
||||
cmd.buf_len = len;
|
||||
ret = atmel_qspi_run_command(aq, &cmd, QSPI_IFR_TFRTYP_TRSFR_WRITE_MEM,
|
||||
nor->write_proto);
|
||||
return (ret < 0) ? ret : len;
|
||||
}
|
||||
|
||||
static int atmel_qspi_erase(struct spi_nor *nor, loff_t offs)
|
||||
{
|
||||
struct atmel_qspi *aq = nor->priv;
|
||||
struct atmel_qspi_command cmd;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.enable.bits.instruction = 1;
|
||||
cmd.enable.bits.address = nor->addr_width;
|
||||
cmd.instruction = nor->erase_opcode;
|
||||
cmd.address = (u32)offs;
|
||||
return atmel_qspi_run_command(aq, &cmd, QSPI_IFR_TFRTYP_TRSFR_WRITE,
|
||||
nor->reg_proto);
|
||||
}
|
||||
|
||||
static ssize_t atmel_qspi_read(struct spi_nor *nor, loff_t from, size_t len,
|
||||
u_char *read_buf)
|
||||
{
|
||||
struct atmel_qspi *aq = nor->priv;
|
||||
struct atmel_qspi_command cmd;
|
||||
u8 num_mode_cycles, num_dummy_cycles;
|
||||
ssize_t ret;
|
||||
|
||||
if (nor->read_dummy >= 2) {
|
||||
num_mode_cycles = 2;
|
||||
num_dummy_cycles = nor->read_dummy - 2;
|
||||
} else {
|
||||
num_mode_cycles = nor->read_dummy;
|
||||
num_dummy_cycles = 0;
|
||||
}
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.enable.bits.instruction = 1;
|
||||
cmd.enable.bits.address = nor->addr_width;
|
||||
cmd.enable.bits.mode = (num_mode_cycles > 0);
|
||||
cmd.enable.bits.dummy = (num_dummy_cycles > 0);
|
||||
cmd.enable.bits.data = 1;
|
||||
cmd.instruction = nor->read_opcode;
|
||||
cmd.address = (u32)from;
|
||||
cmd.mode = 0xff; /* This value prevents from entering the 0-4-4 mode */
|
||||
cmd.num_mode_cycles = num_mode_cycles;
|
||||
cmd.num_dummy_cycles = num_dummy_cycles;
|
||||
cmd.rx_buf = read_buf;
|
||||
cmd.buf_len = len;
|
||||
ret = atmel_qspi_run_command(aq, &cmd, QSPI_IFR_TFRTYP_TRSFR_READ_MEM,
|
||||
nor->read_proto);
|
||||
return (ret < 0) ? ret : len;
|
||||
}
|
||||
|
||||
static int atmel_qspi_init(struct atmel_qspi *aq)
|
||||
{
|
||||
/* Reset the QSPI controller */
|
||||
|
|
Loading…
Reference in New Issue