Lines Matching +full:host +full:- +full:command
1 // SPDX-License-Identifier: GPL-2.0-only
91 #define SPI_DMA_BLK_COUNT(count) (((count) - 1) & 0xFFFF)
105 struct spi_controller *host; member
142 return readl(tsd->base + reg); in tegra_sflash_readl()
148 writel(val, tsd->base + reg); in tegra_sflash_writel()
161 unsigned remain_len = t->len - tsd->cur_pos; in tegra_sflash_calculate_curr_xfer_param()
164 tsd->bytes_per_word = DIV_ROUND_UP(t->bits_per_word, 8); in tegra_sflash_calculate_curr_xfer_param()
165 max_word = remain_len / tsd->bytes_per_word; in tegra_sflash_calculate_curr_xfer_param()
168 tsd->curr_xfer_words = max_word; in tegra_sflash_calculate_curr_xfer_param()
177 unsigned max_n_32bit = tsd->curr_xfer_words; in tegra_sflash_fill_tx_fifo_from_client_txbuf()
178 u8 *tx_buf = (u8 *)t->tx_buf + tsd->cur_tx_pos; in tegra_sflash_fill_tx_fifo_from_client_txbuf()
182 nbytes = max_n_32bit * tsd->bytes_per_word; in tegra_sflash_fill_tx_fifo_from_client_txbuf()
189 for (i = 0; nbytes && (i < tsd->bytes_per_word); in tegra_sflash_fill_tx_fifo_from_client_txbuf()
190 i++, nbytes--) in tegra_sflash_fill_tx_fifo_from_client_txbuf()
198 tsd->cur_tx_pos += max_n_32bit * tsd->bytes_per_word; in tegra_sflash_fill_tx_fifo_from_client_txbuf()
207 u8 *rx_buf = (u8 *)t->rx_buf + tsd->cur_rx_pos; in tegra_sflash_read_rx_fifo_to_client_rxbuf()
214 for (i = 0; (i < tsd->bytes_per_word); i++) in tegra_sflash_read_rx_fifo_to_client_rxbuf()
219 tsd->cur_rx_pos += read_words * tsd->bytes_per_word; in tegra_sflash_read_rx_fifo_to_client_rxbuf()
229 if (tsd->cur_direction & DATA_DIR_TX) in tegra_sflash_start_cpu_based_transfer()
232 if (tsd->cur_direction & DATA_DIR_RX) in tegra_sflash_start_cpu_based_transfer()
236 tsd->dma_control_reg = val; in tegra_sflash_start_cpu_based_transfer()
238 if (tsd->cur_direction & DATA_DIR_TX) in tegra_sflash_start_cpu_based_transfer()
241 cur_words = tsd->curr_xfer_words; in tegra_sflash_start_cpu_based_transfer()
244 tsd->dma_control_reg = val; in tegra_sflash_start_cpu_based_transfer()
254 struct tegra_sflash_data *tsd = spi_controller_get_devdata(spi->controller); in tegra_sflash_start_transfer_one()
256 u32 command; in tegra_sflash_start_transfer_one() local
258 speed = t->speed_hz; in tegra_sflash_start_transfer_one()
259 if (speed != tsd->cur_speed) { in tegra_sflash_start_transfer_one()
260 clk_set_rate(tsd->clk, speed); in tegra_sflash_start_transfer_one()
261 tsd->cur_speed = speed; in tegra_sflash_start_transfer_one()
264 tsd->cur_spi = spi; in tegra_sflash_start_transfer_one()
265 tsd->cur_pos = 0; in tegra_sflash_start_transfer_one()
266 tsd->cur_rx_pos = 0; in tegra_sflash_start_transfer_one()
267 tsd->cur_tx_pos = 0; in tegra_sflash_start_transfer_one()
268 tsd->curr_xfer = t; in tegra_sflash_start_transfer_one()
271 command = tsd->def_command_reg; in tegra_sflash_start_transfer_one()
272 command |= SPI_BIT_LENGTH(t->bits_per_word - 1); in tegra_sflash_start_transfer_one()
273 command |= SPI_CS_VAL_HIGH; in tegra_sflash_start_transfer_one()
275 command &= ~SPI_MODES; in tegra_sflash_start_transfer_one()
276 if (spi->mode & SPI_CPHA) in tegra_sflash_start_transfer_one()
277 command |= SPI_CK_SDA_FALLING; in tegra_sflash_start_transfer_one()
279 if (spi->mode & SPI_CPOL) in tegra_sflash_start_transfer_one()
280 command |= SPI_ACTIVE_SCLK_DRIVE_HIGH; in tegra_sflash_start_transfer_one()
282 command |= SPI_ACTIVE_SCLK_DRIVE_LOW; in tegra_sflash_start_transfer_one()
283 command |= SPI_CS0_EN << spi_get_chipselect(spi, 0); in tegra_sflash_start_transfer_one()
285 command = tsd->command_reg; in tegra_sflash_start_transfer_one()
286 command &= ~SPI_BIT_LENGTH(~0); in tegra_sflash_start_transfer_one()
287 command |= SPI_BIT_LENGTH(t->bits_per_word - 1); in tegra_sflash_start_transfer_one()
288 command &= ~(SPI_RX_EN | SPI_TX_EN); in tegra_sflash_start_transfer_one()
291 tsd->cur_direction = 0; in tegra_sflash_start_transfer_one()
292 if (t->rx_buf) { in tegra_sflash_start_transfer_one()
293 command |= SPI_RX_EN; in tegra_sflash_start_transfer_one()
294 tsd->cur_direction |= DATA_DIR_RX; in tegra_sflash_start_transfer_one()
296 if (t->tx_buf) { in tegra_sflash_start_transfer_one()
297 command |= SPI_TX_EN; in tegra_sflash_start_transfer_one()
298 tsd->cur_direction |= DATA_DIR_TX; in tegra_sflash_start_transfer_one()
300 tegra_sflash_writel(tsd, command, SPI_COMMAND); in tegra_sflash_start_transfer_one()
301 tsd->command_reg = command; in tegra_sflash_start_transfer_one()
306 static int tegra_sflash_transfer_one_message(struct spi_controller *host, in tegra_sflash_transfer_one_message() argument
311 struct tegra_sflash_data *tsd = spi_controller_get_devdata(host); in tegra_sflash_transfer_one_message()
313 struct spi_device *spi = msg->spi; in tegra_sflash_transfer_one_message()
316 msg->status = 0; in tegra_sflash_transfer_one_message()
317 msg->actual_length = 0; in tegra_sflash_transfer_one_message()
318 single_xfer = list_is_singular(&msg->transfers); in tegra_sflash_transfer_one_message()
319 list_for_each_entry(xfer, &msg->transfers, transfer_list) { in tegra_sflash_transfer_one_message()
320 reinit_completion(&tsd->xfer_completion); in tegra_sflash_transfer_one_message()
324 dev_err(tsd->dev, in tegra_sflash_transfer_one_message()
329 ret = wait_for_completion_timeout(&tsd->xfer_completion, in tegra_sflash_transfer_one_message()
332 dev_err(tsd->dev, in tegra_sflash_transfer_one_message()
334 ret = -EIO; in tegra_sflash_transfer_one_message()
338 if (tsd->tx_status || tsd->rx_status) { in tegra_sflash_transfer_one_message()
339 dev_err(tsd->dev, "Error in Transfer\n"); in tegra_sflash_transfer_one_message()
340 ret = -EIO; in tegra_sflash_transfer_one_message()
343 msg->actual_length += xfer->len; in tegra_sflash_transfer_one_message()
344 if (xfer->cs_change && xfer->delay.value) { in tegra_sflash_transfer_one_message()
345 tegra_sflash_writel(tsd, tsd->def_command_reg, in tegra_sflash_transfer_one_message()
352 tegra_sflash_writel(tsd, tsd->def_command_reg, SPI_COMMAND); in tegra_sflash_transfer_one_message()
353 msg->status = ret; in tegra_sflash_transfer_one_message()
354 spi_finalize_current_message(host); in tegra_sflash_transfer_one_message()
360 struct spi_transfer *t = tsd->curr_xfer; in handle_cpu_based_xfer()
362 spin_lock(&tsd->lock); in handle_cpu_based_xfer()
363 if (tsd->tx_status || tsd->rx_status || (tsd->status_reg & SPI_BSY)) { in handle_cpu_based_xfer()
364 dev_err(tsd->dev, in handle_cpu_based_xfer()
365 "CpuXfer ERROR bit set 0x%x\n", tsd->status_reg); in handle_cpu_based_xfer()
366 dev_err(tsd->dev, in handle_cpu_based_xfer()
367 "CpuXfer 0x%08x:0x%08x\n", tsd->command_reg, in handle_cpu_based_xfer()
368 tsd->dma_control_reg); in handle_cpu_based_xfer()
369 reset_control_assert(tsd->rst); in handle_cpu_based_xfer()
371 reset_control_deassert(tsd->rst); in handle_cpu_based_xfer()
372 complete(&tsd->xfer_completion); in handle_cpu_based_xfer()
376 if (tsd->cur_direction & DATA_DIR_RX) in handle_cpu_based_xfer()
379 if (tsd->cur_direction & DATA_DIR_TX) in handle_cpu_based_xfer()
380 tsd->cur_pos = tsd->cur_tx_pos; in handle_cpu_based_xfer()
382 tsd->cur_pos = tsd->cur_rx_pos; in handle_cpu_based_xfer()
384 if (tsd->cur_pos == t->len) { in handle_cpu_based_xfer()
385 complete(&tsd->xfer_completion); in handle_cpu_based_xfer()
389 tegra_sflash_calculate_curr_xfer_param(tsd->cur_spi, tsd, t); in handle_cpu_based_xfer()
392 spin_unlock(&tsd->lock); in handle_cpu_based_xfer()
400 tsd->status_reg = tegra_sflash_readl(tsd, SPI_STATUS); in tegra_sflash_isr()
401 if (tsd->cur_direction & DATA_DIR_TX) in tegra_sflash_isr()
402 tsd->tx_status = tsd->status_reg & SPI_TX_OVF; in tegra_sflash_isr()
404 if (tsd->cur_direction & DATA_DIR_RX) in tegra_sflash_isr()
405 tsd->rx_status = tsd->status_reg & SPI_RX_UNF; in tegra_sflash_isr()
412 { .compatible = "nvidia,tegra20-sflash", },
419 struct spi_controller *host; in tegra_sflash_probe() local
424 match = of_match_device(tegra_sflash_of_match, &pdev->dev); in tegra_sflash_probe()
426 dev_err(&pdev->dev, "Error: No device match found\n"); in tegra_sflash_probe()
427 return -ENODEV; in tegra_sflash_probe()
430 host = spi_alloc_host(&pdev->dev, sizeof(*tsd)); in tegra_sflash_probe()
431 if (!host) { in tegra_sflash_probe()
432 dev_err(&pdev->dev, "host allocation failed\n"); in tegra_sflash_probe()
433 return -ENOMEM; in tegra_sflash_probe()
436 /* the spi->mode bits understood by this driver: */ in tegra_sflash_probe()
437 host->mode_bits = SPI_CPOL | SPI_CPHA; in tegra_sflash_probe()
438 host->transfer_one_message = tegra_sflash_transfer_one_message; in tegra_sflash_probe()
439 host->auto_runtime_pm = true; in tegra_sflash_probe()
440 host->num_chipselect = MAX_CHIP_SELECT; in tegra_sflash_probe()
442 platform_set_drvdata(pdev, host); in tegra_sflash_probe()
443 tsd = spi_controller_get_devdata(host); in tegra_sflash_probe()
444 tsd->host = host; in tegra_sflash_probe()
445 tsd->dev = &pdev->dev; in tegra_sflash_probe()
446 spin_lock_init(&tsd->lock); in tegra_sflash_probe()
448 if (of_property_read_u32(tsd->dev->of_node, "spi-max-frequency", in tegra_sflash_probe()
449 &host->max_speed_hz)) in tegra_sflash_probe()
450 host->max_speed_hz = 25000000; /* 25MHz */ in tegra_sflash_probe()
452 tsd->base = devm_platform_ioremap_resource(pdev, 0); in tegra_sflash_probe()
453 if (IS_ERR(tsd->base)) { in tegra_sflash_probe()
454 ret = PTR_ERR(tsd->base); in tegra_sflash_probe()
461 tsd->irq = ret; in tegra_sflash_probe()
463 ret = request_irq(tsd->irq, tegra_sflash_isr, 0, in tegra_sflash_probe()
464 dev_name(&pdev->dev), tsd); in tegra_sflash_probe()
466 dev_err(&pdev->dev, "Failed to register ISR for IRQ %d\n", in tegra_sflash_probe()
467 tsd->irq); in tegra_sflash_probe()
471 tsd->clk = devm_clk_get(&pdev->dev, NULL); in tegra_sflash_probe()
472 if (IS_ERR(tsd->clk)) { in tegra_sflash_probe()
473 dev_err(&pdev->dev, "can not get clock\n"); in tegra_sflash_probe()
474 ret = PTR_ERR(tsd->clk); in tegra_sflash_probe()
478 tsd->rst = devm_reset_control_get_exclusive(&pdev->dev, "spi"); in tegra_sflash_probe()
479 if (IS_ERR(tsd->rst)) { in tegra_sflash_probe()
480 dev_err(&pdev->dev, "can not get reset\n"); in tegra_sflash_probe()
481 ret = PTR_ERR(tsd->rst); in tegra_sflash_probe()
485 init_completion(&tsd->xfer_completion); in tegra_sflash_probe()
486 pm_runtime_enable(&pdev->dev); in tegra_sflash_probe()
487 if (!pm_runtime_enabled(&pdev->dev)) { in tegra_sflash_probe()
488 ret = tegra_sflash_runtime_resume(&pdev->dev); in tegra_sflash_probe()
493 ret = pm_runtime_resume_and_get(&pdev->dev); in tegra_sflash_probe()
495 dev_err(&pdev->dev, "pm runtime get failed, e = %d\n", ret); in tegra_sflash_probe()
500 reset_control_assert(tsd->rst); in tegra_sflash_probe()
502 reset_control_deassert(tsd->rst); in tegra_sflash_probe()
504 tsd->def_command_reg = SPI_M_S | SPI_CS_SW; in tegra_sflash_probe()
505 tegra_sflash_writel(tsd, tsd->def_command_reg, SPI_COMMAND); in tegra_sflash_probe()
506 pm_runtime_put(&pdev->dev); in tegra_sflash_probe()
508 host->dev.of_node = pdev->dev.of_node; in tegra_sflash_probe()
509 ret = devm_spi_register_controller(&pdev->dev, host); in tegra_sflash_probe()
511 dev_err(&pdev->dev, "can not register to host err %d\n", ret); in tegra_sflash_probe()
517 pm_runtime_disable(&pdev->dev); in tegra_sflash_probe()
518 if (!pm_runtime_status_suspended(&pdev->dev)) in tegra_sflash_probe()
519 tegra_sflash_runtime_suspend(&pdev->dev); in tegra_sflash_probe()
521 free_irq(tsd->irq, tsd); in tegra_sflash_probe()
523 spi_controller_put(host); in tegra_sflash_probe()
529 struct spi_controller *host = platform_get_drvdata(pdev); in tegra_sflash_remove() local
530 struct tegra_sflash_data *tsd = spi_controller_get_devdata(host); in tegra_sflash_remove()
532 free_irq(tsd->irq, tsd); in tegra_sflash_remove()
534 pm_runtime_disable(&pdev->dev); in tegra_sflash_remove()
535 if (!pm_runtime_status_suspended(&pdev->dev)) in tegra_sflash_remove()
536 tegra_sflash_runtime_suspend(&pdev->dev); in tegra_sflash_remove()
542 struct spi_controller *host = dev_get_drvdata(dev); in tegra_sflash_suspend() local
544 return spi_controller_suspend(host); in tegra_sflash_suspend()
549 struct spi_controller *host = dev_get_drvdata(dev); in tegra_sflash_resume() local
550 struct tegra_sflash_data *tsd = spi_controller_get_devdata(host); in tegra_sflash_resume()
558 tegra_sflash_writel(tsd, tsd->command_reg, SPI_COMMAND); in tegra_sflash_resume()
561 return spi_controller_resume(host); in tegra_sflash_resume()
567 struct spi_controller *host = dev_get_drvdata(dev); in tegra_sflash_runtime_suspend() local
568 struct tegra_sflash_data *tsd = spi_controller_get_devdata(host); in tegra_sflash_runtime_suspend()
573 clk_disable_unprepare(tsd->clk); in tegra_sflash_runtime_suspend()
579 struct spi_controller *host = dev_get_drvdata(dev); in tegra_sflash_runtime_resume() local
580 struct tegra_sflash_data *tsd = spi_controller_get_devdata(host); in tegra_sflash_runtime_resume()
583 ret = clk_prepare_enable(tsd->clk); in tegra_sflash_runtime_resume()
585 dev_err(tsd->dev, "clk_prepare failed: %d\n", ret); in tegra_sflash_runtime_resume()
598 .name = "spi-tegra-sflash",
607 MODULE_ALIAS("platform:spi-tegra-sflash");