Lines Matching +full:spi +full:- +full:mode
1 // SPDX-License-Identifier: GPL-2.0
5 // SiFive SPI controller driver (master mode only)
15 #include <linux/spi/spi.h>
27 #define SIFIVE_SPI_REG_SCKMODE 0x04 /* Serial clock mode */
30 #define SIFIVE_SPI_REG_CSMODE 0x18 /* Chip select mode */
38 #define SIFIVE_SPI_REG_FCTRL 0x60 /* SPI flash interface control */
39 #define SIFIVE_SPI_REG_FFMT 0x64 /* SPI flash instruction format */
96 struct completion done; /* wake-up from interrupt */
99 static void sifive_spi_write(struct sifive_spi *spi, int offset, u32 value) in sifive_spi_write() argument
101 iowrite32(value, spi->regs + offset); in sifive_spi_write()
104 static u32 sifive_spi_read(struct sifive_spi *spi, int offset) in sifive_spi_read() argument
106 return ioread32(spi->regs + offset); in sifive_spi_read()
109 static void sifive_spi_init(struct sifive_spi *spi) in sifive_spi_init() argument
112 sifive_spi_write(spi, SIFIVE_SPI_REG_IE, 0); in sifive_spi_init()
115 sifive_spi_write(spi, SIFIVE_SPI_REG_TXMARK, 1); in sifive_spi_init()
116 sifive_spi_write(spi, SIFIVE_SPI_REG_RXMARK, 0); in sifive_spi_init()
119 sifive_spi_write(spi, SIFIVE_SPI_REG_DELAY0, in sifive_spi_init()
122 sifive_spi_write(spi, SIFIVE_SPI_REG_DELAY1, in sifive_spi_init()
126 /* Exit specialized memory-mapped SPI flash mode */ in sifive_spi_init()
127 sifive_spi_write(spi, SIFIVE_SPI_REG_FCTRL, 0); in sifive_spi_init()
133 struct sifive_spi *spi = spi_controller_get_devdata(host); in sifive_spi_prepare_message() local
134 struct spi_device *device = msg->spi; in sifive_spi_prepare_message()
137 if (device->mode & SPI_CS_HIGH) in sifive_spi_prepare_message()
138 spi->cs_inactive &= ~BIT(spi_get_chipselect(device, 0)); in sifive_spi_prepare_message()
140 spi->cs_inactive |= BIT(spi_get_chipselect(device, 0)); in sifive_spi_prepare_message()
141 sifive_spi_write(spi, SIFIVE_SPI_REG_CSDEF, spi->cs_inactive); in sifive_spi_prepare_message()
144 sifive_spi_write(spi, SIFIVE_SPI_REG_CSID, spi_get_chipselect(device, 0)); in sifive_spi_prepare_message()
146 /* Set clock mode */ in sifive_spi_prepare_message()
147 sifive_spi_write(spi, SIFIVE_SPI_REG_SCKMODE, in sifive_spi_prepare_message()
148 device->mode & SIFIVE_SPI_SCKMODE_MODE_MASK); in sifive_spi_prepare_message()
155 struct sifive_spi *spi = spi_controller_get_devdata(device->controller); in sifive_spi_set_cs() local
158 if (device->mode & SPI_CS_HIGH) in sifive_spi_set_cs()
161 sifive_spi_write(spi, SIFIVE_SPI_REG_CSMODE, is_high ? in sifive_spi_set_cs()
167 sifive_spi_prep_transfer(struct sifive_spi *spi, struct spi_device *device, in sifive_spi_prep_transfer() argument
171 unsigned int mode; in sifive_spi_prep_transfer() local
174 cr = DIV_ROUND_UP(clk_get_rate(spi->clk) >> 1, t->speed_hz) - 1; in sifive_spi_prep_transfer()
176 sifive_spi_write(spi, SIFIVE_SPI_REG_SCKDIV, cr); in sifive_spi_prep_transfer()
178 mode = max_t(unsigned int, t->rx_nbits, t->tx_nbits); in sifive_spi_prep_transfer()
181 cr = SIFIVE_SPI_FMT_LEN(t->bits_per_word); in sifive_spi_prep_transfer()
182 switch (mode) { in sifive_spi_prep_transfer()
193 if (device->mode & SPI_LSB_FIRST) in sifive_spi_prep_transfer()
195 if (!t->rx_buf) in sifive_spi_prep_transfer()
197 sifive_spi_write(spi, SIFIVE_SPI_REG_FMT, cr); in sifive_spi_prep_transfer()
202 * (8/mode) * fifo_depth / hz <= 5 * 10^-6 in sifive_spi_prep_transfer()
203 * 1600000 * fifo_depth <= hz * mode in sifive_spi_prep_transfer()
205 return 1600000 * spi->fifo_depth <= t->speed_hz * mode; in sifive_spi_prep_transfer()
210 struct sifive_spi *spi = dev_id; in sifive_spi_irq() local
211 u32 ip = sifive_spi_read(spi, SIFIVE_SPI_REG_IP); in sifive_spi_irq()
215 sifive_spi_write(spi, SIFIVE_SPI_REG_IE, 0); in sifive_spi_irq()
216 complete(&spi->done); in sifive_spi_irq()
223 static void sifive_spi_wait(struct sifive_spi *spi, u32 bit, int poll) in sifive_spi_wait() argument
229 cr = sifive_spi_read(spi, SIFIVE_SPI_REG_IP); in sifive_spi_wait()
232 reinit_completion(&spi->done); in sifive_spi_wait()
233 sifive_spi_write(spi, SIFIVE_SPI_REG_IE, bit); in sifive_spi_wait()
234 wait_for_completion(&spi->done); in sifive_spi_wait()
238 static void sifive_spi_tx(struct sifive_spi *spi, const u8 *tx_ptr) in sifive_spi_tx() argument
240 WARN_ON_ONCE((sifive_spi_read(spi, SIFIVE_SPI_REG_TXDATA) in sifive_spi_tx()
242 sifive_spi_write(spi, SIFIVE_SPI_REG_TXDATA, in sifive_spi_tx()
246 static void sifive_spi_rx(struct sifive_spi *spi, u8 *rx_ptr) in sifive_spi_rx() argument
248 u32 data = sifive_spi_read(spi, SIFIVE_SPI_REG_RXDATA); in sifive_spi_rx()
258 struct sifive_spi *spi = spi_controller_get_devdata(host); in sifive_spi_transfer_one() local
259 int poll = sifive_spi_prep_transfer(spi, device, t); in sifive_spi_transfer_one()
260 const u8 *tx_ptr = t->tx_buf; in sifive_spi_transfer_one()
261 u8 *rx_ptr = t->rx_buf; in sifive_spi_transfer_one()
262 unsigned int remaining_words = t->len; in sifive_spi_transfer_one()
265 unsigned int n_words = min(remaining_words, spi->fifo_depth); in sifive_spi_transfer_one()
270 sifive_spi_tx(spi, tx_ptr++); in sifive_spi_transfer_one()
274 sifive_spi_write(spi, SIFIVE_SPI_REG_RXMARK, in sifive_spi_transfer_one()
275 n_words - 1); in sifive_spi_transfer_one()
276 sifive_spi_wait(spi, SIFIVE_SPI_IP_RXWM, poll); in sifive_spi_transfer_one()
280 sifive_spi_rx(spi, rx_ptr++); in sifive_spi_transfer_one()
283 sifive_spi_wait(spi, SIFIVE_SPI_IP_TXWM, poll); in sifive_spi_transfer_one()
286 remaining_words -= n_words; in sifive_spi_transfer_one()
294 struct sifive_spi *spi; in sifive_spi_probe() local
299 host = spi_alloc_host(&pdev->dev, sizeof(struct sifive_spi)); in sifive_spi_probe()
301 dev_err(&pdev->dev, "out of memory\n"); in sifive_spi_probe()
302 return -ENOMEM; in sifive_spi_probe()
305 spi = spi_controller_get_devdata(host); in sifive_spi_probe()
306 init_completion(&spi->done); in sifive_spi_probe()
309 spi->regs = devm_platform_ioremap_resource(pdev, 0); in sifive_spi_probe()
310 if (IS_ERR(spi->regs)) { in sifive_spi_probe()
311 ret = PTR_ERR(spi->regs); in sifive_spi_probe()
315 spi->clk = devm_clk_get(&pdev->dev, NULL); in sifive_spi_probe()
316 if (IS_ERR(spi->clk)) { in sifive_spi_probe()
317 dev_err(&pdev->dev, "Unable to find bus clock\n"); in sifive_spi_probe()
318 ret = PTR_ERR(spi->clk); in sifive_spi_probe()
330 of_property_read_u32(pdev->dev.of_node, "sifive,fifo-depth", in sifive_spi_probe()
331 &spi->fifo_depth); in sifive_spi_probe()
333 spi->fifo_depth = SIFIVE_SPI_DEFAULT_DEPTH; in sifive_spi_probe()
336 of_property_read_u32(pdev->dev.of_node, "sifive,max-bits-per-word", in sifive_spi_probe()
340 dev_err(&pdev->dev, "Only 8bit SPI words supported by the driver\n"); in sifive_spi_probe()
341 ret = -EINVAL; in sifive_spi_probe()
346 ret = clk_prepare_enable(spi->clk); in sifive_spi_probe()
348 dev_err(&pdev->dev, "Unable to enable bus clock\n"); in sifive_spi_probe()
353 spi->cs_inactive = sifive_spi_read(spi, SIFIVE_SPI_REG_CSDEF); in sifive_spi_probe()
354 sifive_spi_write(spi, SIFIVE_SPI_REG_CSDEF, 0xffffffffU); in sifive_spi_probe()
355 cs_bits = sifive_spi_read(spi, SIFIVE_SPI_REG_CSDEF); in sifive_spi_probe()
356 sifive_spi_write(spi, SIFIVE_SPI_REG_CSDEF, spi->cs_inactive); in sifive_spi_probe()
358 dev_err(&pdev->dev, "Could not auto probe CS lines\n"); in sifive_spi_probe()
359 ret = -EINVAL; in sifive_spi_probe()
365 dev_err(&pdev->dev, "Invalid number of spi targets\n"); in sifive_spi_probe()
366 ret = -EINVAL; in sifive_spi_probe()
371 host->dev.of_node = pdev->dev.of_node; in sifive_spi_probe()
372 host->bus_num = pdev->id; in sifive_spi_probe()
373 host->num_chipselect = num_cs; in sifive_spi_probe()
374 host->mode_bits = SPI_CPHA | SPI_CPOL in sifive_spi_probe()
379 * we need to "left-align" the bits (unless SPI_LSB_FIRST) in sifive_spi_probe()
381 host->bits_per_word_mask = SPI_BPW_MASK(8); in sifive_spi_probe()
382 host->flags = SPI_CONTROLLER_MUST_TX | SPI_CONTROLLER_GPIO_SS; in sifive_spi_probe()
383 host->prepare_message = sifive_spi_prepare_message; in sifive_spi_probe()
384 host->set_cs = sifive_spi_set_cs; in sifive_spi_probe()
385 host->transfer_one = sifive_spi_transfer_one; in sifive_spi_probe()
387 pdev->dev.dma_mask = NULL; in sifive_spi_probe()
388 /* Configure the SPI host hardware */ in sifive_spi_probe()
389 sifive_spi_init(spi); in sifive_spi_probe()
391 /* Register for SPI Interrupt */ in sifive_spi_probe()
392 ret = devm_request_irq(&pdev->dev, irq, sifive_spi_irq, 0, in sifive_spi_probe()
393 dev_name(&pdev->dev), spi); in sifive_spi_probe()
395 dev_err(&pdev->dev, "Unable to bind to interrupt\n"); in sifive_spi_probe()
399 dev_info(&pdev->dev, "mapped; irq=%d, cs=%d\n", in sifive_spi_probe()
400 irq, host->num_chipselect); in sifive_spi_probe()
402 ret = devm_spi_register_controller(&pdev->dev, host); in sifive_spi_probe()
404 dev_err(&pdev->dev, "spi_register_host failed\n"); in sifive_spi_probe()
411 clk_disable_unprepare(spi->clk); in sifive_spi_probe()
421 struct sifive_spi *spi = spi_controller_get_devdata(host); in sifive_spi_remove() local
424 sifive_spi_write(spi, SIFIVE_SPI_REG_IE, 0); in sifive_spi_remove()
425 clk_disable_unprepare(spi->clk); in sifive_spi_remove()
431 struct sifive_spi *spi = spi_controller_get_devdata(host); in sifive_spi_suspend() local
439 sifive_spi_write(spi, SIFIVE_SPI_REG_IE, 0); in sifive_spi_suspend()
441 clk_disable_unprepare(spi->clk); in sifive_spi_suspend()
449 struct sifive_spi *spi = spi_controller_get_devdata(host); in sifive_spi_resume() local
452 ret = clk_prepare_enable(spi->clk); in sifive_spi_resume()
457 clk_disable_unprepare(spi->clk); in sifive_spi_resume()
484 MODULE_DESCRIPTION("SiFive SPI driver");