Lines Matching refs:spi_engine

81 struct spi_engine {  struct
130 static unsigned int spi_engine_get_clk_div(struct spi_engine *spi_engine, in spi_engine_get_clk_div() argument
135 clk_div = DIV_ROUND_UP(clk_get_rate(spi_engine->ref_clk), in spi_engine_get_clk_div()
166 struct spi_engine *spi_engine, unsigned int clk_div, in spi_engine_gen_sleep() argument
169 unsigned int spi_clk = clk_get_rate(spi_engine->ref_clk); in spi_engine_gen_sleep()
201 static int spi_engine_compile_message(struct spi_engine *spi_engine, in spi_engine_compile_message() argument
216 new_clk_div = spi_engine_get_clk_div(spi_engine, spi, xfer); in spi_engine_compile_message()
228 spi_engine_gen_sleep(p, dry, spi_engine, clk_div, xfer); in spi_engine_compile_message()
241 static void spi_engine_xfer_next(struct spi_engine *spi_engine, in spi_engine_xfer_next() argument
244 struct spi_message *msg = spi_engine->msg; in spi_engine_xfer_next()
259 static void spi_engine_tx_next(struct spi_engine *spi_engine) in spi_engine_tx_next() argument
261 struct spi_transfer *xfer = spi_engine->tx_xfer; in spi_engine_tx_next()
264 spi_engine_xfer_next(spi_engine, &xfer); in spi_engine_tx_next()
267 spi_engine->tx_xfer = xfer; in spi_engine_tx_next()
269 spi_engine->tx_length = xfer->len; in spi_engine_tx_next()
270 spi_engine->tx_buf = xfer->tx_buf; in spi_engine_tx_next()
272 spi_engine->tx_buf = NULL; in spi_engine_tx_next()
276 static void spi_engine_rx_next(struct spi_engine *spi_engine) in spi_engine_rx_next() argument
278 struct spi_transfer *xfer = spi_engine->rx_xfer; in spi_engine_rx_next()
281 spi_engine_xfer_next(spi_engine, &xfer); in spi_engine_rx_next()
284 spi_engine->rx_xfer = xfer; in spi_engine_rx_next()
286 spi_engine->rx_length = xfer->len; in spi_engine_rx_next()
287 spi_engine->rx_buf = xfer->rx_buf; in spi_engine_rx_next()
289 spi_engine->rx_buf = NULL; in spi_engine_rx_next()
293 static bool spi_engine_write_cmd_fifo(struct spi_engine *spi_engine) in spi_engine_write_cmd_fifo() argument
295 void __iomem *addr = spi_engine->base + SPI_ENGINE_REG_CMD_FIFO; in spi_engine_write_cmd_fifo()
299 n = readl_relaxed(spi_engine->base + SPI_ENGINE_REG_CMD_FIFO_ROOM); in spi_engine_write_cmd_fifo()
300 while (n && spi_engine->cmd_length) { in spi_engine_write_cmd_fifo()
301 m = min(n, spi_engine->cmd_length); in spi_engine_write_cmd_fifo()
302 buf = spi_engine->cmd_buf; in spi_engine_write_cmd_fifo()
305 spi_engine->cmd_buf += m; in spi_engine_write_cmd_fifo()
306 spi_engine->cmd_length -= m; in spi_engine_write_cmd_fifo()
310 return spi_engine->cmd_length != 0; in spi_engine_write_cmd_fifo()
313 static bool spi_engine_write_tx_fifo(struct spi_engine *spi_engine) in spi_engine_write_tx_fifo() argument
315 void __iomem *addr = spi_engine->base + SPI_ENGINE_REG_SDO_DATA_FIFO; in spi_engine_write_tx_fifo()
319 n = readl_relaxed(spi_engine->base + SPI_ENGINE_REG_SDO_FIFO_ROOM); in spi_engine_write_tx_fifo()
320 while (n && spi_engine->tx_length) { in spi_engine_write_tx_fifo()
321 m = min(n, spi_engine->tx_length); in spi_engine_write_tx_fifo()
322 buf = spi_engine->tx_buf; in spi_engine_write_tx_fifo()
325 spi_engine->tx_buf += m; in spi_engine_write_tx_fifo()
326 spi_engine->tx_length -= m; in spi_engine_write_tx_fifo()
328 if (spi_engine->tx_length == 0) in spi_engine_write_tx_fifo()
329 spi_engine_tx_next(spi_engine); in spi_engine_write_tx_fifo()
332 return spi_engine->tx_length != 0; in spi_engine_write_tx_fifo()
335 static bool spi_engine_read_rx_fifo(struct spi_engine *spi_engine) in spi_engine_read_rx_fifo() argument
337 void __iomem *addr = spi_engine->base + SPI_ENGINE_REG_SDI_DATA_FIFO; in spi_engine_read_rx_fifo()
341 n = readl_relaxed(spi_engine->base + SPI_ENGINE_REG_SDI_FIFO_LEVEL); in spi_engine_read_rx_fifo()
342 while (n && spi_engine->rx_length) { in spi_engine_read_rx_fifo()
343 m = min(n, spi_engine->rx_length); in spi_engine_read_rx_fifo()
344 buf = spi_engine->rx_buf; in spi_engine_read_rx_fifo()
347 spi_engine->rx_buf += m; in spi_engine_read_rx_fifo()
348 spi_engine->rx_length -= m; in spi_engine_read_rx_fifo()
350 if (spi_engine->rx_length == 0) in spi_engine_read_rx_fifo()
351 spi_engine_rx_next(spi_engine); in spi_engine_read_rx_fifo()
354 return spi_engine->rx_length != 0; in spi_engine_read_rx_fifo()
360 struct spi_engine *spi_engine = spi_controller_get_devdata(host); in spi_engine_irq() local
364 pending = readl_relaxed(spi_engine->base + SPI_ENGINE_REG_INT_PENDING); in spi_engine_irq()
368 spi_engine->base + SPI_ENGINE_REG_INT_PENDING); in spi_engine_irq()
369 spi_engine->completed_id = readl_relaxed( in spi_engine_irq()
370 spi_engine->base + SPI_ENGINE_REG_SYNC_ID); in spi_engine_irq()
373 spin_lock(&spi_engine->lock); in spi_engine_irq()
376 if (!spi_engine_write_cmd_fifo(spi_engine)) in spi_engine_irq()
381 if (!spi_engine_write_tx_fifo(spi_engine)) in spi_engine_irq()
386 if (!spi_engine_read_rx_fifo(spi_engine)) in spi_engine_irq()
391 if (spi_engine->msg && in spi_engine_irq()
392 spi_engine->completed_id == spi_engine->sync_id) { in spi_engine_irq()
393 struct spi_message *msg = spi_engine->msg; in spi_engine_irq()
395 kfree(spi_engine->p); in spi_engine_irq()
398 spi_engine->msg = NULL; in spi_engine_irq()
405 spi_engine->int_enable &= ~disable_int; in spi_engine_irq()
406 writel_relaxed(spi_engine->int_enable, in spi_engine_irq()
407 spi_engine->base + SPI_ENGINE_REG_INT_ENABLE); in spi_engine_irq()
410 spin_unlock(&spi_engine->lock); in spi_engine_irq()
419 struct spi_engine *spi_engine = spi_controller_get_devdata(host); in spi_engine_transfer_one_message() local
425 spi_engine_compile_message(spi_engine, msg, true, &p_dry); in spi_engine_transfer_one_message()
431 spi_engine_compile_message(spi_engine, msg, false, p); in spi_engine_transfer_one_message()
433 spin_lock_irqsave(&spi_engine->lock, flags); in spi_engine_transfer_one_message()
434 spi_engine->sync_id = (spi_engine->sync_id + 1) & 0xff; in spi_engine_transfer_one_message()
436 SPI_ENGINE_CMD_SYNC(spi_engine->sync_id)); in spi_engine_transfer_one_message()
438 spi_engine->msg = msg; in spi_engine_transfer_one_message()
439 spi_engine->p = p; in spi_engine_transfer_one_message()
441 spi_engine->cmd_buf = p->instructions; in spi_engine_transfer_one_message()
442 spi_engine->cmd_length = p->length; in spi_engine_transfer_one_message()
443 if (spi_engine_write_cmd_fifo(spi_engine)) in spi_engine_transfer_one_message()
446 spi_engine_tx_next(spi_engine); in spi_engine_transfer_one_message()
447 if (spi_engine_write_tx_fifo(spi_engine)) in spi_engine_transfer_one_message()
450 spi_engine_rx_next(spi_engine); in spi_engine_transfer_one_message()
451 if (spi_engine->rx_length != 0) in spi_engine_transfer_one_message()
457 spi_engine->base + SPI_ENGINE_REG_INT_ENABLE); in spi_engine_transfer_one_message()
458 spi_engine->int_enable = int_enable; in spi_engine_transfer_one_message()
459 spin_unlock_irqrestore(&spi_engine->lock, flags); in spi_engine_transfer_one_message()
466 struct spi_engine *spi_engine; in spi_engine_probe() local
476 spi_engine = devm_kzalloc(&pdev->dev, sizeof(*spi_engine), GFP_KERNEL); in spi_engine_probe()
477 if (!spi_engine) in spi_engine_probe()
484 spi_controller_set_devdata(host, spi_engine); in spi_engine_probe()
486 spin_lock_init(&spi_engine->lock); in spi_engine_probe()
488 spi_engine->clk = devm_clk_get(&pdev->dev, "s_axi_aclk"); in spi_engine_probe()
489 if (IS_ERR(spi_engine->clk)) { in spi_engine_probe()
490 ret = PTR_ERR(spi_engine->clk); in spi_engine_probe()
494 spi_engine->ref_clk = devm_clk_get(&pdev->dev, "spi_clk"); in spi_engine_probe()
495 if (IS_ERR(spi_engine->ref_clk)) { in spi_engine_probe()
496 ret = PTR_ERR(spi_engine->ref_clk); in spi_engine_probe()
500 ret = clk_prepare_enable(spi_engine->clk); in spi_engine_probe()
504 ret = clk_prepare_enable(spi_engine->ref_clk); in spi_engine_probe()
508 spi_engine->base = devm_platform_ioremap_resource(pdev, 0); in spi_engine_probe()
509 if (IS_ERR(spi_engine->base)) { in spi_engine_probe()
510 ret = PTR_ERR(spi_engine->base); in spi_engine_probe()
514 version = readl(spi_engine->base + SPI_ENGINE_REG_VERSION); in spi_engine_probe()
524 writel_relaxed(0x00, spi_engine->base + SPI_ENGINE_REG_RESET); in spi_engine_probe()
525 writel_relaxed(0xff, spi_engine->base + SPI_ENGINE_REG_INT_PENDING); in spi_engine_probe()
526 writel_relaxed(0x00, spi_engine->base + SPI_ENGINE_REG_INT_ENABLE); in spi_engine_probe()
535 host->max_speed_hz = clk_get_rate(spi_engine->ref_clk) / 2; in spi_engine_probe()
549 clk_disable_unprepare(spi_engine->ref_clk); in spi_engine_probe()
551 clk_disable_unprepare(spi_engine->clk); in spi_engine_probe()
560 struct spi_engine *spi_engine = spi_controller_get_devdata(host); in spi_engine_remove() local
569 writel_relaxed(0xff, spi_engine->base + SPI_ENGINE_REG_INT_PENDING); in spi_engine_remove()
570 writel_relaxed(0x00, spi_engine->base + SPI_ENGINE_REG_INT_ENABLE); in spi_engine_remove()
571 writel_relaxed(0x01, spi_engine->base + SPI_ENGINE_REG_RESET); in spi_engine_remove()
573 clk_disable_unprepare(spi_engine->ref_clk); in spi_engine_remove()
574 clk_disable_unprepare(spi_engine->clk); in spi_engine_remove()