| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Marvell Orion SPI controller driver |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Author: Shadi Ammouri <shadi@marvell.com> |
|---|
| 5 | 6 | * Copyright (C) 2007-2008 Marvell Ltd. |
|---|
| 6 | | - * |
|---|
| 7 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 8 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 9 | | - * published by the Free Software Foundation. |
|---|
| 10 | 7 | */ |
|---|
| 11 | 8 | |
|---|
| 12 | 9 | #include <linux/interrupt.h> |
|---|
| .. | .. |
|---|
| 20 | 17 | #include <linux/of.h> |
|---|
| 21 | 18 | #include <linux/of_address.h> |
|---|
| 22 | 19 | #include <linux/of_device.h> |
|---|
| 23 | | -#include <linux/of_gpio.h> |
|---|
| 24 | 20 | #include <linux/clk.h> |
|---|
| 25 | 21 | #include <linux/sizes.h> |
|---|
| 26 | | -#include <linux/gpio.h> |
|---|
| 27 | 22 | #include <asm/unaligned.h> |
|---|
| 28 | 23 | |
|---|
| 29 | 24 | #define DRIVER_NAME "orion_spi" |
|---|
| .. | .. |
|---|
| 101 | 96 | struct clk *clk; |
|---|
| 102 | 97 | struct clk *axi_clk; |
|---|
| 103 | 98 | const struct orion_spi_dev *devdata; |
|---|
| 104 | | - int unused_hw_gpio; |
|---|
| 105 | 99 | |
|---|
| 106 | 100 | struct orion_child_options child[ORION_NUM_CHIPSELECTS]; |
|---|
| 107 | 101 | }; |
|---|
| .. | .. |
|---|
| 328 | 322 | static void orion_spi_set_cs(struct spi_device *spi, bool enable) |
|---|
| 329 | 323 | { |
|---|
| 330 | 324 | struct orion_spi *orion_spi; |
|---|
| 331 | | - int cs; |
|---|
| 332 | 325 | |
|---|
| 333 | 326 | orion_spi = spi_master_get_devdata(spi->master); |
|---|
| 334 | 327 | |
|---|
| 335 | | - if (gpio_is_valid(spi->cs_gpio)) |
|---|
| 336 | | - cs = orion_spi->unused_hw_gpio; |
|---|
| 337 | | - else |
|---|
| 338 | | - cs = spi->chip_select; |
|---|
| 339 | | - |
|---|
| 328 | + /* |
|---|
| 329 | + * If this line is using a GPIO to control chip select, this internal |
|---|
| 330 | + * .set_cs() function will still be called, so we clear any previous |
|---|
| 331 | + * chip select. The CS we activate will not have any elecrical effect, |
|---|
| 332 | + * as it is handled by a GPIO, but that doesn't matter. What we need |
|---|
| 333 | + * is to deassert the old chip select and assert some other chip select. |
|---|
| 334 | + */ |
|---|
| 340 | 335 | orion_spi_clrbits(orion_spi, ORION_SPI_IF_CTRL_REG, ORION_SPI_CS_MASK); |
|---|
| 341 | 336 | orion_spi_setbits(orion_spi, ORION_SPI_IF_CTRL_REG, |
|---|
| 342 | | - ORION_SPI_CS(cs)); |
|---|
| 337 | + ORION_SPI_CS(spi->chip_select)); |
|---|
| 343 | 338 | |
|---|
| 344 | | - /* Chip select logic is inverted from spi_set_cs */ |
|---|
| 339 | + /* |
|---|
| 340 | + * Chip select logic is inverted from spi_set_cs(). For lines using a |
|---|
| 341 | + * GPIO to do chip select SPI_CS_HIGH is enforced and inversion happens |
|---|
| 342 | + * in the GPIO library, but we don't care about that, because in those |
|---|
| 343 | + * cases we are dealing with an unused native CS anyways so the polarity |
|---|
| 344 | + * doesn't matter. |
|---|
| 345 | + */ |
|---|
| 345 | 346 | if (!enable) |
|---|
| 346 | 347 | orion_spi_setbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1); |
|---|
| 347 | 348 | else |
|---|
| .. | .. |
|---|
| 431 | 432 | int word_len; |
|---|
| 432 | 433 | struct orion_spi *orion_spi; |
|---|
| 433 | 434 | int cs = spi->chip_select; |
|---|
| 435 | + void __iomem *vaddr; |
|---|
| 434 | 436 | |
|---|
| 435 | 437 | word_len = spi->bits_per_word; |
|---|
| 436 | 438 | count = xfer->len; |
|---|
| .. | .. |
|---|
| 441 | 443 | * Use SPI direct write mode if base address is available. Otherwise |
|---|
| 442 | 444 | * fall back to PIO mode for this transfer. |
|---|
| 443 | 445 | */ |
|---|
| 444 | | - if ((orion_spi->child[cs].direct_access.vaddr) && (xfer->tx_buf) && |
|---|
| 445 | | - (word_len == 8)) { |
|---|
| 446 | + vaddr = orion_spi->child[cs].direct_access.vaddr; |
|---|
| 447 | + |
|---|
| 448 | + if (vaddr && xfer->tx_buf && word_len == 8) { |
|---|
| 446 | 449 | unsigned int cnt = count / 4; |
|---|
| 447 | 450 | unsigned int rem = count % 4; |
|---|
| 448 | 451 | |
|---|
| .. | .. |
|---|
| 450 | 453 | * Send the TX-data to the SPI device via the direct |
|---|
| 451 | 454 | * mapped address window |
|---|
| 452 | 455 | */ |
|---|
| 453 | | - iowrite32_rep(orion_spi->child[cs].direct_access.vaddr, |
|---|
| 454 | | - xfer->tx_buf, cnt); |
|---|
| 456 | + iowrite32_rep(vaddr, xfer->tx_buf, cnt); |
|---|
| 455 | 457 | if (rem) { |
|---|
| 456 | 458 | u32 *buf = (u32 *)xfer->tx_buf; |
|---|
| 457 | 459 | |
|---|
| 458 | | - iowrite8_rep(orion_spi->child[cs].direct_access.vaddr, |
|---|
| 459 | | - &buf[cnt], rem); |
|---|
| 460 | + iowrite8_rep(vaddr, &buf[cnt], rem); |
|---|
| 460 | 461 | } |
|---|
| 461 | 462 | |
|---|
| 462 | 463 | return count; |
|---|
| .. | .. |
|---|
| 470 | 471 | if (orion_spi_write_read_8bit(spi, &tx, &rx) < 0) |
|---|
| 471 | 472 | goto out; |
|---|
| 472 | 473 | count--; |
|---|
| 474 | + spi_delay_exec(&xfer->word_delay, xfer); |
|---|
| 473 | 475 | } while (count); |
|---|
| 474 | 476 | } else if (word_len == 16) { |
|---|
| 475 | 477 | const u16 *tx = xfer->tx_buf; |
|---|
| .. | .. |
|---|
| 479 | 481 | if (orion_spi_write_read_16bit(spi, &tx, &rx) < 0) |
|---|
| 480 | 482 | goto out; |
|---|
| 481 | 483 | count -= 2; |
|---|
| 484 | + spi_delay_exec(&xfer->word_delay, xfer); |
|---|
| 482 | 485 | } while (count); |
|---|
| 483 | 486 | } |
|---|
| 484 | 487 | |
|---|
| .. | .. |
|---|
| 504 | 507 | |
|---|
| 505 | 508 | static int orion_spi_setup(struct spi_device *spi) |
|---|
| 506 | 509 | { |
|---|
| 507 | | - if (gpio_is_valid(spi->cs_gpio)) { |
|---|
| 508 | | - gpio_direction_output(spi->cs_gpio, !(spi->mode & SPI_CS_HIGH)); |
|---|
| 509 | | - } |
|---|
| 510 | 510 | return orion_spi_setup_transfer(spi, NULL); |
|---|
| 511 | 511 | } |
|---|
| 512 | 512 | |
|---|
| .. | .. |
|---|
| 623 | 623 | master->setup = orion_spi_setup; |
|---|
| 624 | 624 | master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16); |
|---|
| 625 | 625 | master->auto_runtime_pm = true; |
|---|
| 626 | + master->use_gpio_descriptors = true; |
|---|
| 626 | 627 | master->flags = SPI_MASTER_GPIO_SS; |
|---|
| 627 | 628 | |
|---|
| 628 | 629 | platform_set_drvdata(pdev, master); |
|---|
| 629 | 630 | |
|---|
| 630 | 631 | spi = spi_master_get_devdata(master); |
|---|
| 631 | 632 | spi->master = master; |
|---|
| 632 | | - spi->unused_hw_gpio = -1; |
|---|
| 633 | 633 | |
|---|
| 634 | 634 | of_id = of_match_device(orion_spi_of_match_table, &pdev->dev); |
|---|
| 635 | 635 | devdata = (of_id) ? of_id->data : &orion_spi_dev_data; |
|---|
| .. | .. |
|---|
| 647 | 647 | |
|---|
| 648 | 648 | /* The following clock is only used by some SoCs */ |
|---|
| 649 | 649 | spi->axi_clk = devm_clk_get(&pdev->dev, "axi"); |
|---|
| 650 | | - if (IS_ERR(spi->axi_clk) && |
|---|
| 651 | | - PTR_ERR(spi->axi_clk) == -EPROBE_DEFER) { |
|---|
| 650 | + if (PTR_ERR(spi->axi_clk) == -EPROBE_DEFER) { |
|---|
| 652 | 651 | status = -EPROBE_DEFER; |
|---|
| 653 | 652 | goto out_rel_clk; |
|---|
| 654 | 653 | } |
|---|
| .. | .. |
|---|
| 683 | 682 | } |
|---|
| 684 | 683 | |
|---|
| 685 | 684 | for_each_available_child_of_node(pdev->dev.of_node, np) { |
|---|
| 685 | + struct orion_direct_acc *dir_acc; |
|---|
| 686 | 686 | u32 cs; |
|---|
| 687 | | - int cs_gpio; |
|---|
| 688 | 687 | |
|---|
| 689 | 688 | /* Get chip-select number from the "reg" property */ |
|---|
| 690 | 689 | status = of_property_read_u32(np, "reg", &cs); |
|---|
| .. | .. |
|---|
| 693 | 692 | "%pOF has no valid 'reg' property (%d)\n", |
|---|
| 694 | 693 | np, status); |
|---|
| 695 | 694 | continue; |
|---|
| 696 | | - } |
|---|
| 697 | | - |
|---|
| 698 | | - /* |
|---|
| 699 | | - * Initialize the CS GPIO: |
|---|
| 700 | | - * - properly request the actual GPIO signal |
|---|
| 701 | | - * - de-assert the logical signal so that all GPIO CS lines |
|---|
| 702 | | - * are inactive when probing for slaves |
|---|
| 703 | | - * - find an unused physical CS which will be driven for any |
|---|
| 704 | | - * slave which uses a CS GPIO |
|---|
| 705 | | - */ |
|---|
| 706 | | - cs_gpio = of_get_named_gpio(pdev->dev.of_node, "cs-gpios", cs); |
|---|
| 707 | | - if (cs_gpio > 0) { |
|---|
| 708 | | - char *gpio_name; |
|---|
| 709 | | - int cs_flags; |
|---|
| 710 | | - |
|---|
| 711 | | - if (spi->unused_hw_gpio == -1) { |
|---|
| 712 | | - dev_info(&pdev->dev, |
|---|
| 713 | | - "Selected unused HW CS#%d for any GPIO CSes\n", |
|---|
| 714 | | - cs); |
|---|
| 715 | | - spi->unused_hw_gpio = cs; |
|---|
| 716 | | - } |
|---|
| 717 | | - |
|---|
| 718 | | - gpio_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, |
|---|
| 719 | | - "%s-CS%d", dev_name(&pdev->dev), cs); |
|---|
| 720 | | - if (!gpio_name) { |
|---|
| 721 | | - status = -ENOMEM; |
|---|
| 722 | | - goto out_rel_axi_clk; |
|---|
| 723 | | - } |
|---|
| 724 | | - |
|---|
| 725 | | - cs_flags = of_property_read_bool(np, "spi-cs-high") ? |
|---|
| 726 | | - GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH; |
|---|
| 727 | | - status = devm_gpio_request_one(&pdev->dev, cs_gpio, |
|---|
| 728 | | - cs_flags, gpio_name); |
|---|
| 729 | | - if (status) { |
|---|
| 730 | | - dev_err(&pdev->dev, |
|---|
| 731 | | - "Can't request GPIO for CS %d\n", cs); |
|---|
| 732 | | - goto out_rel_axi_clk; |
|---|
| 733 | | - } |
|---|
| 734 | 695 | } |
|---|
| 735 | 696 | |
|---|
| 736 | 697 | /* |
|---|
| .. | .. |
|---|
| 747 | 708 | /* |
|---|
| 748 | 709 | * Only map one page for direct access. This is enough for the |
|---|
| 749 | 710 | * simple TX transfer which only writes to the first word. |
|---|
| 750 | | - * This needs to get extended for the direct SPI-NOR / SPI-NAND |
|---|
| 711 | + * This needs to get extended for the direct SPI NOR / SPI NAND |
|---|
| 751 | 712 | * support, once this gets implemented. |
|---|
| 752 | 713 | */ |
|---|
| 753 | | - spi->child[cs].direct_access.vaddr = devm_ioremap(&pdev->dev, |
|---|
| 754 | | - r->start, |
|---|
| 755 | | - PAGE_SIZE); |
|---|
| 756 | | - if (!spi->child[cs].direct_access.vaddr) { |
|---|
| 714 | + dir_acc = &spi->child[cs].direct_access; |
|---|
| 715 | + dir_acc->vaddr = devm_ioremap(&pdev->dev, r->start, PAGE_SIZE); |
|---|
| 716 | + if (!dir_acc->vaddr) { |
|---|
| 757 | 717 | status = -ENOMEM; |
|---|
| 758 | 718 | goto out_rel_axi_clk; |
|---|
| 759 | 719 | } |
|---|
| 760 | | - spi->child[cs].direct_access.size = PAGE_SIZE; |
|---|
| 720 | + dir_acc->size = PAGE_SIZE; |
|---|
| 761 | 721 | |
|---|
| 762 | 722 | dev_info(&pdev->dev, "CS%d configured for direct access\n", cs); |
|---|
| 763 | 723 | } |
|---|
| .. | .. |
|---|
| 770 | 730 | status = orion_spi_reset(spi); |
|---|
| 771 | 731 | if (status < 0) |
|---|
| 772 | 732 | goto out_rel_pm; |
|---|
| 773 | | - |
|---|
| 774 | | - pm_runtime_mark_last_busy(&pdev->dev); |
|---|
| 775 | | - pm_runtime_put_autosuspend(&pdev->dev); |
|---|
| 776 | 733 | |
|---|
| 777 | 734 | master->dev.of_node = pdev->dev.of_node; |
|---|
| 778 | 735 | status = spi_register_master(master); |
|---|