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()
205 static int spi_engine_compile_message(struct spi_engine *spi_engine, in spi_engine_compile_message() argument
220 new_clk_div = spi_engine_get_clk_div(spi_engine, spi, xfer); in spi_engine_compile_message()
232 spi_engine_gen_sleep(p, dry, spi_engine, clk_div, xfer); in spi_engine_compile_message()
245 static void spi_engine_xfer_next(struct spi_engine *spi_engine, in spi_engine_xfer_next() argument
248 struct spi_message *msg = spi_engine->msg; in spi_engine_xfer_next()
263 static void spi_engine_tx_next(struct spi_engine *spi_engine) in spi_engine_tx_next() argument
265 struct spi_transfer *xfer = spi_engine->tx_xfer; in spi_engine_tx_next()
268 spi_engine_xfer_next(spi_engine, &xfer); in spi_engine_tx_next()
271 spi_engine->tx_xfer = xfer; in spi_engine_tx_next()
273 spi_engine->tx_length = xfer->len; in spi_engine_tx_next()
274 spi_engine->tx_buf = xfer->tx_buf; in spi_engine_tx_next()
276 spi_engine->tx_buf = NULL; in spi_engine_tx_next()
280 static void spi_engine_rx_next(struct spi_engine *spi_engine) in spi_engine_rx_next() argument
282 struct spi_transfer *xfer = spi_engine->rx_xfer; in spi_engine_rx_next()
285 spi_engine_xfer_next(spi_engine, &xfer); in spi_engine_rx_next()
288 spi_engine->rx_xfer = xfer; in spi_engine_rx_next()
290 spi_engine->rx_length = xfer->len; in spi_engine_rx_next()
291 spi_engine->rx_buf = xfer->rx_buf; in spi_engine_rx_next()
293 spi_engine->rx_buf = NULL; in spi_engine_rx_next()
297 static bool spi_engine_write_cmd_fifo(struct spi_engine *spi_engine) in spi_engine_write_cmd_fifo() argument
299 void __iomem *addr = spi_engine->base + SPI_ENGINE_REG_CMD_FIFO; in spi_engine_write_cmd_fifo()
303 n = readl_relaxed(spi_engine->base + SPI_ENGINE_REG_CMD_FIFO_ROOM); in spi_engine_write_cmd_fifo()
304 while (n && spi_engine->cmd_length) { in spi_engine_write_cmd_fifo()
305 m = min(n, spi_engine->cmd_length); in spi_engine_write_cmd_fifo()
306 buf = spi_engine->cmd_buf; in spi_engine_write_cmd_fifo()
309 spi_engine->cmd_buf += m; in spi_engine_write_cmd_fifo()
310 spi_engine->cmd_length -= m; in spi_engine_write_cmd_fifo()
314 return spi_engine->cmd_length != 0; in spi_engine_write_cmd_fifo()
317 static bool spi_engine_write_tx_fifo(struct spi_engine *spi_engine) in spi_engine_write_tx_fifo() argument
319 void __iomem *addr = spi_engine->base + SPI_ENGINE_REG_SDO_DATA_FIFO; in spi_engine_write_tx_fifo()
323 n = readl_relaxed(spi_engine->base + SPI_ENGINE_REG_SDO_FIFO_ROOM); in spi_engine_write_tx_fifo()
324 while (n && spi_engine->tx_length) { in spi_engine_write_tx_fifo()
325 m = min(n, spi_engine->tx_length); in spi_engine_write_tx_fifo()
326 buf = spi_engine->tx_buf; in spi_engine_write_tx_fifo()
329 spi_engine->tx_buf += m; in spi_engine_write_tx_fifo()
330 spi_engine->tx_length -= m; in spi_engine_write_tx_fifo()
332 if (spi_engine->tx_length == 0) in spi_engine_write_tx_fifo()
333 spi_engine_tx_next(spi_engine); in spi_engine_write_tx_fifo()
336 return spi_engine->tx_length != 0; in spi_engine_write_tx_fifo()
339 static bool spi_engine_read_rx_fifo(struct spi_engine *spi_engine) in spi_engine_read_rx_fifo() argument
341 void __iomem *addr = spi_engine->base + SPI_ENGINE_REG_SDI_DATA_FIFO; in spi_engine_read_rx_fifo()
345 n = readl_relaxed(spi_engine->base + SPI_ENGINE_REG_SDI_FIFO_LEVEL); in spi_engine_read_rx_fifo()
346 while (n && spi_engine->rx_length) { in spi_engine_read_rx_fifo()
347 m = min(n, spi_engine->rx_length); in spi_engine_read_rx_fifo()
348 buf = spi_engine->rx_buf; in spi_engine_read_rx_fifo()
351 spi_engine->rx_buf += m; in spi_engine_read_rx_fifo()
352 spi_engine->rx_length -= m; in spi_engine_read_rx_fifo()
354 if (spi_engine->rx_length == 0) in spi_engine_read_rx_fifo()
355 spi_engine_rx_next(spi_engine); in spi_engine_read_rx_fifo()
358 return spi_engine->rx_length != 0; in spi_engine_read_rx_fifo()
364 struct spi_engine *spi_engine = spi_master_get_devdata(master); in spi_engine_irq() local
368 pending = readl_relaxed(spi_engine->base + SPI_ENGINE_REG_INT_PENDING); in spi_engine_irq()
372 spi_engine->base + SPI_ENGINE_REG_INT_PENDING); in spi_engine_irq()
373 spi_engine->completed_id = readl_relaxed( in spi_engine_irq()
374 spi_engine->base + SPI_ENGINE_REG_SYNC_ID); in spi_engine_irq()
377 spin_lock(&spi_engine->lock); in spi_engine_irq()
380 if (!spi_engine_write_cmd_fifo(spi_engine)) in spi_engine_irq()
385 if (!spi_engine_write_tx_fifo(spi_engine)) in spi_engine_irq()
390 if (!spi_engine_read_rx_fifo(spi_engine)) in spi_engine_irq()
395 if (spi_engine->msg && in spi_engine_irq()
396 spi_engine->completed_id == spi_engine->sync_id) { in spi_engine_irq()
397 struct spi_message *msg = spi_engine->msg; in spi_engine_irq()
399 kfree(spi_engine->p); in spi_engine_irq()
402 spi_engine->msg = NULL; in spi_engine_irq()
409 spi_engine->int_enable &= ~disable_int; in spi_engine_irq()
410 writel_relaxed(spi_engine->int_enable, in spi_engine_irq()
411 spi_engine->base + SPI_ENGINE_REG_INT_ENABLE); in spi_engine_irq()
414 spin_unlock(&spi_engine->lock); in spi_engine_irq()
423 struct spi_engine *spi_engine = spi_master_get_devdata(master); in spi_engine_transfer_one_message() local
429 spi_engine_compile_message(spi_engine, msg, true, &p_dry); in spi_engine_transfer_one_message()
435 spi_engine_compile_message(spi_engine, msg, false, p); in spi_engine_transfer_one_message()
437 spin_lock_irqsave(&spi_engine->lock, flags); in spi_engine_transfer_one_message()
438 spi_engine->sync_id = (spi_engine->sync_id + 1) & 0xff; in spi_engine_transfer_one_message()
440 SPI_ENGINE_CMD_SYNC(spi_engine->sync_id)); in spi_engine_transfer_one_message()
442 spi_engine->msg = msg; in spi_engine_transfer_one_message()
443 spi_engine->p = p; in spi_engine_transfer_one_message()
445 spi_engine->cmd_buf = p->instructions; in spi_engine_transfer_one_message()
446 spi_engine->cmd_length = p->length; in spi_engine_transfer_one_message()
447 if (spi_engine_write_cmd_fifo(spi_engine)) in spi_engine_transfer_one_message()
450 spi_engine_tx_next(spi_engine); in spi_engine_transfer_one_message()
451 if (spi_engine_write_tx_fifo(spi_engine)) in spi_engine_transfer_one_message()
454 spi_engine_rx_next(spi_engine); in spi_engine_transfer_one_message()
455 if (spi_engine->rx_length != 0) in spi_engine_transfer_one_message()
461 spi_engine->base + SPI_ENGINE_REG_INT_ENABLE); in spi_engine_transfer_one_message()
462 spi_engine->int_enable = int_enable; in spi_engine_transfer_one_message()
463 spin_unlock_irqrestore(&spi_engine->lock, flags); in spi_engine_transfer_one_message()
470 struct spi_engine *spi_engine; in spi_engine_probe() local
480 spi_engine = devm_kzalloc(&pdev->dev, sizeof(*spi_engine), GFP_KERNEL); in spi_engine_probe()
481 if (!spi_engine) in spi_engine_probe()
488 spi_master_set_devdata(master, spi_engine); in spi_engine_probe()
490 spin_lock_init(&spi_engine->lock); in spi_engine_probe()
492 spi_engine->clk = devm_clk_get(&pdev->dev, "s_axi_aclk"); in spi_engine_probe()
493 if (IS_ERR(spi_engine->clk)) { in spi_engine_probe()
494 ret = PTR_ERR(spi_engine->clk); in spi_engine_probe()
498 spi_engine->ref_clk = devm_clk_get(&pdev->dev, "spi_clk"); in spi_engine_probe()
499 if (IS_ERR(spi_engine->ref_clk)) { in spi_engine_probe()
500 ret = PTR_ERR(spi_engine->ref_clk); in spi_engine_probe()
504 ret = clk_prepare_enable(spi_engine->clk); in spi_engine_probe()
508 ret = clk_prepare_enable(spi_engine->ref_clk); in spi_engine_probe()
512 spi_engine->base = devm_platform_ioremap_resource(pdev, 0); in spi_engine_probe()
513 if (IS_ERR(spi_engine->base)) { in spi_engine_probe()
514 ret = PTR_ERR(spi_engine->base); in spi_engine_probe()
518 version = readl(spi_engine->base + SPI_ENGINE_REG_VERSION); in spi_engine_probe()
528 writel_relaxed(0x00, spi_engine->base + SPI_ENGINE_REG_RESET); in spi_engine_probe()
529 writel_relaxed(0xff, spi_engine->base + SPI_ENGINE_REG_INT_PENDING); in spi_engine_probe()
530 writel_relaxed(0x00, spi_engine->base + SPI_ENGINE_REG_INT_ENABLE); in spi_engine_probe()
539 master->max_speed_hz = clk_get_rate(spi_engine->ref_clk) / 2; in spi_engine_probe()
553 clk_disable_unprepare(spi_engine->ref_clk); in spi_engine_probe()
555 clk_disable_unprepare(spi_engine->clk); in spi_engine_probe()
564 struct spi_engine *spi_engine = spi_master_get_devdata(master); in spi_engine_remove() local
573 writel_relaxed(0xff, spi_engine->base + SPI_ENGINE_REG_INT_PENDING); in spi_engine_remove()
574 writel_relaxed(0x00, spi_engine->base + SPI_ENGINE_REG_INT_ENABLE); in spi_engine_remove()
575 writel_relaxed(0x01, spi_engine->base + SPI_ENGINE_REG_RESET); in spi_engine_remove()
577 clk_disable_unprepare(spi_engine->ref_clk); in spi_engine_remove()
578 clk_disable_unprepare(spi_engine->clk); in spi_engine_remove()