^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2012 Thomas Langer <thomas.langer@lantiq.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/spi/spi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/of_platform.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <lantiq_soc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define DRV_NAME "sflash-falcon"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define FALCON_SPI_XFER_BEGIN (1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define FALCON_SPI_XFER_END (1 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /* Bus Read Configuration Register0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define BUSRCON0 0x00000010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /* Bus Write Configuration Register0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define BUSWCON0 0x00000018
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /* Serial Flash Configuration Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define SFCON 0x00000080
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /* Serial Flash Time Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define SFTIME 0x00000084
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /* Serial Flash Status Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define SFSTAT 0x00000088
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /* Serial Flash Command Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define SFCMD 0x0000008C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) /* Serial Flash Address Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define SFADDR 0x00000090
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /* Serial Flash Data Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define SFDATA 0x00000094
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) /* Serial Flash I/O Control Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define SFIO 0x00000098
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /* EBU Clock Control Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define EBUCC 0x000000C4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /* Dummy Phase Length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define SFCMD_DUMLEN_OFFSET 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define SFCMD_DUMLEN_MASK 0x000F0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /* Chip Select */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define SFCMD_CS_OFFSET 24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define SFCMD_CS_MASK 0x07000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /* field offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define SFCMD_ALEN_OFFSET 20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define SFCMD_ALEN_MASK 0x00700000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /* SCK Rise-edge Position */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define SFTIME_SCKR_POS_OFFSET 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define SFTIME_SCKR_POS_MASK 0x00000F00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /* SCK Period */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define SFTIME_SCK_PER_OFFSET 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define SFTIME_SCK_PER_MASK 0x0000000F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /* SCK Fall-edge Position */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define SFTIME_SCKF_POS_OFFSET 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define SFTIME_SCKF_POS_MASK 0x0000F000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /* Device Size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define SFCON_DEV_SIZE_A23_0 0x03000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define SFCON_DEV_SIZE_MASK 0x0F000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /* Read Data Position */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define SFTIME_RD_POS_MASK 0x000F0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /* Data Output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define SFIO_UNUSED_WD_MASK 0x0000000F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) /* Command Opcode mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define SFCMD_OPC_MASK 0x000000FF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /* dlen bytes of data to write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define SFCMD_DIR_WRITE 0x00000100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /* Data Length offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define SFCMD_DLEN_OFFSET 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /* Command Error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define SFSTAT_CMD_ERR 0x20000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /* Access Command Pending */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define SFSTAT_CMD_PEND 0x00400000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /* Frequency set to 100MHz. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define EBUCC_EBUDIV_SELF100 0x00000001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /* Serial Flash */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define BUSRCON0_AGEN_SERIAL_FLASH 0xF0000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /* 8-bit multiplexed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define BUSRCON0_PORTW_8_BIT_MUX 0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /* Serial Flash */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define BUSWCON0_AGEN_SERIAL_FLASH 0xF0000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) /* Chip Select after opcode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define SFCMD_KEEP_CS_KEEP_SELECTED 0x00008000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define CLOCK_100M 100000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define CLOCK_50M 50000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct falcon_sflash {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) u32 sfcmd; /* for caching of opcode, direction, ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) struct spi_master *master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) int falcon_sflash_xfer(struct spi_device *spi, struct spi_transfer *t,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) unsigned long flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct device *dev = &spi->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct falcon_sflash *priv = spi_master_get_devdata(spi->master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) const u8 *txp = t->tx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) u8 *rxp = t->rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) unsigned int bytelen = ((8 * t->len + 7) / 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) unsigned int len, alen, dumlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) state_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) state_command_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) state_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) state_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) state_disable_cs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) state_end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) } state = state_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) switch (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) case state_init: /* detect phase of upper layer sequence */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /* initial write ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (flags & FALCON_SPI_XFER_BEGIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if (!txp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) dev_err(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) "BEGIN without tx data!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * Prepare the parts of the sfcmd register,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * which should not change during a sequence!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * Only exception are the length fields,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * especially alen and dumlen.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) priv->sfcmd = ((spi->chip_select
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) << SFCMD_CS_OFFSET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) & SFCMD_CS_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) priv->sfcmd |= SFCMD_KEEP_CS_KEEP_SELECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) priv->sfcmd |= *txp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) txp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) bytelen--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (bytelen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * more data:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * maybe address and/or dummy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) state = state_command_prepare;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) dev_dbg(dev, "write cmd %02X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) priv->sfcmd & SFCMD_OPC_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /* continued write ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (txp && bytelen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) state = state_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) /* read data? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (rxp && bytelen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) state = state_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /* end of sequence? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (flags & FALCON_SPI_XFER_END)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) state = state_disable_cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) state = state_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) /* collect tx data for address and dummy phase */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) case state_command_prepare:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /* txp is valid, already checked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) alen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) dumlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) while (bytelen > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (alen < 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) val = (val << 8) | (*txp++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) alen++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) } else if ((dumlen < 15) && (*txp == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * assume dummy bytes are set to 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * from upper layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) dumlen++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) txp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) bytelen--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) priv->sfcmd &= ~(SFCMD_ALEN_MASK | SFCMD_DUMLEN_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) priv->sfcmd |= (alen << SFCMD_ALEN_OFFSET) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) (dumlen << SFCMD_DUMLEN_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (alen > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) ltq_ebu_w32(val, SFADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) dev_dbg(dev, "wr %02X, alen=%d (addr=%06X) dlen=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) priv->sfcmd & SFCMD_OPC_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) alen, val, dumlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (bytelen > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /* continue with write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) state = state_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) } else if (flags & FALCON_SPI_XFER_END) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) /* end of sequence? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) state = state_disable_cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * go to end and expect another
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * call (read or write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) state = state_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) case state_write:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) /* txp still valid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) priv->sfcmd |= SFCMD_DIR_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (bytelen--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) val |= (*txp++) << (8 * len++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if ((flags & FALCON_SPI_XFER_END)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) && (bytelen == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) priv->sfcmd &=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) ~SFCMD_KEEP_CS_KEEP_SELECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if ((len == 4) || (bytelen == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) ltq_ebu_w32(val, SFDATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) ltq_ebu_w32(priv->sfcmd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) | (len<<SFCMD_DLEN_OFFSET),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) SFCMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) priv->sfcmd &= ~(SFCMD_ALEN_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) | SFCMD_DUMLEN_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) } while (bytelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) state = state_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) case state_read:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) /* read data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) priv->sfcmd &= ~SFCMD_DIR_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if ((flags & FALCON_SPI_XFER_END)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) && (bytelen <= 4)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) priv->sfcmd &=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) ~SFCMD_KEEP_CS_KEEP_SELECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) len = (bytelen > 4) ? 4 : bytelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) bytelen -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) ltq_ebu_w32(priv->sfcmd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) | (len << SFCMD_DLEN_OFFSET), SFCMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) priv->sfcmd &= ~(SFCMD_ALEN_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) | SFCMD_DUMLEN_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) val = ltq_ebu_r32(SFSTAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (val & SFSTAT_CMD_ERR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) /* reset error status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) dev_err(dev, "SFSTAT: CMD_ERR");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) dev_err(dev, " (%x)\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) ltq_ebu_w32(SFSTAT_CMD_ERR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) SFSTAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) return -EBADE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) } while (val & SFSTAT_CMD_PEND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) val = ltq_ebu_r32(SFDATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) *rxp = (val & 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) rxp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) val >>= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) len--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) } while (len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) } while (bytelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) state = state_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) case state_disable_cs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) priv->sfcmd &= ~SFCMD_KEEP_CS_KEEP_SELECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) ltq_ebu_w32(priv->sfcmd | (0 << SFCMD_DLEN_OFFSET),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) SFCMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) val = ltq_ebu_r32(SFSTAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if (val & SFSTAT_CMD_ERR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) /* reset error status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) dev_err(dev, "SFSTAT: CMD_ERR (%x)\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) ltq_ebu_w32(SFSTAT_CMD_ERR, SFSTAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return -EBADE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) state = state_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) case state_end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) } while (state != state_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) static int falcon_sflash_setup(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) spin_lock_irqsave(&ebu_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (spi->max_speed_hz >= CLOCK_100M) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) /* set EBU clock to 100 MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) ltq_sys1_w32_mask(0, EBUCC_EBUDIV_SELF100, EBUCC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) i = 1; /* divider */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) /* set EBU clock to 50 MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) ltq_sys1_w32_mask(EBUCC_EBUDIV_SELF100, 0, EBUCC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) /* search for suitable divider */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) for (i = 1; i < 7; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (CLOCK_50M / i <= spi->max_speed_hz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) /* setup period of serial clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) ltq_ebu_w32_mask(SFTIME_SCKF_POS_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) | SFTIME_SCKR_POS_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) | SFTIME_SCK_PER_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) (i << SFTIME_SCKR_POS_OFFSET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) | (i << (SFTIME_SCK_PER_OFFSET + 1)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) SFTIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) * set some bits of unused_wd, to not trigger HOLD/WP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) * signals on non QUAD flashes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) ltq_ebu_w32((SFIO_UNUSED_WD_MASK & (0x8 | 0x4)), SFIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) ltq_ebu_w32(BUSRCON0_AGEN_SERIAL_FLASH | BUSRCON0_PORTW_8_BIT_MUX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) BUSRCON0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) ltq_ebu_w32(BUSWCON0_AGEN_SERIAL_FLASH, BUSWCON0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) /* set address wrap around to maximum for 24-bit addresses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) ltq_ebu_w32_mask(SFCON_DEV_SIZE_MASK, SFCON_DEV_SIZE_A23_0, SFCON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) spin_unlock_irqrestore(&ebu_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) static int falcon_sflash_xfer_one(struct spi_master *master,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) struct spi_message *m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) struct falcon_sflash *priv = spi_master_get_devdata(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) struct spi_transfer *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) unsigned long spi_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) priv->sfcmd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) m->actual_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) spi_flags = FALCON_SPI_XFER_BEGIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) list_for_each_entry(t, &m->transfers, transfer_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (list_is_last(&t->transfer_list, &m->transfers))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) spi_flags |= FALCON_SPI_XFER_END;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) spin_lock_irqsave(&ebu_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) ret = falcon_sflash_xfer(m->spi, t, spi_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) spin_unlock_irqrestore(&ebu_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) m->actual_length += t->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) WARN_ON(t->delay_usecs || t->delay.value || t->cs_change);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) spi_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) m->status = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) spi_finalize_current_message(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) static int falcon_sflash_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) struct falcon_sflash *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) struct spi_master *master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) master = spi_alloc_master(&pdev->dev, sizeof(*priv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (!master)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) priv = spi_master_get_devdata(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) priv->master = master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) master->mode_bits = SPI_MODE_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) master->flags = SPI_MASTER_HALF_DUPLEX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) master->setup = falcon_sflash_setup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) master->transfer_one_message = falcon_sflash_xfer_one;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) master->dev.of_node = pdev->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) ret = devm_spi_register_master(&pdev->dev, master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) spi_master_put(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) static const struct of_device_id falcon_sflash_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) { .compatible = "lantiq,sflash-falcon" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) MODULE_DEVICE_TABLE(of, falcon_sflash_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) static struct platform_driver falcon_sflash_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) .probe = falcon_sflash_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) .name = DRV_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) .of_match_table = falcon_sflash_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) module_platform_driver(falcon_sflash_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) MODULE_DESCRIPTION("Lantiq Falcon SPI/SFLASH controller driver");