Commit 9bff9dfc authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'spi-v5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi

Pull spi updates from Mark Brown:
 "One small feature was added this release but the bulk of the diffstat
  and the changelog comes from the fact that several older drivers got
  some fairly hefty reworks and a couple of new drivers were added:

   - Support for detailed control of timing around chip selects from
     Sowjanya Komatineni.

   - A big set of fixes and imrovements for the Tegra114 driver from
     Sowjanya Komatineni.

   - A big simplification of the GPIO driver from Andrey Smirnov.

   - DMA support and fixes for the Freescale LPSPI driver from Clark
     Wang.

   - Fixes and optimizations for the bcm2835aux from Martin Sparl.

   - New drivers for Mediatek MT7621 (graduated from staging) and Zynq
     QSPI"

[ This is a so-called "evil merge" that additionally removes a warning
  due to an unused variable 'i' introduced by commit 1dfbf334 ("spi:
  ep93xx: Convert to use CS GPIO descriptors")     - Linus ]

* tag 'spi-v5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: (127 commits)
  spi: rspi: Fix handling of QSPI code when transmit and receive
  spi: atmel-quadspi: fix crash while suspending
  spi: stm32: return the get_irq error
  spi: tegra114: fix PIO transfer
  spi: pxa2xx: fix SCR (divisor) calculation
  spi: Clear SPI_CS_HIGH flag from bad_bits for GPIO chip-select
  spi: ep93xx: Convert to use CS GPIO descriptors
  spi: AD ASoC: declare missing of table
  spi: spi-mem: zynq-qspi: Fix build error on architectures missing readsl/writesl
  spi: stm32-qspi: manage the get_irq error case
  spi/spi-bcm2835: Split transfers that exceed DLEN
  spi: expand mode support
  dt-bindings: spi: spi-mt65xx: add support for MT8516
  spi: pxa2xx: Add support for Intel Comet Lake
  spi/trace: Cap buffer contents at 64 bytes
  spi: Release spi_res after finalizing message
  spi: Remove warning in spi_split_transfers_maxsize()
  spi: Remove one needless transfer speed fall back case
  spi: sh-msiof: Document r8a77470 bindings
  spi: pxa2xx: use a module softdep for dw_dmac
  ...
parents 61be53f9 2e5f0810
...@@ -18,6 +18,10 @@ Optional properties: ...@@ -18,6 +18,10 @@ Optional properties:
- gpios : specifies the gpio pins to be used for chipselects. - gpios : specifies the gpio pins to be used for chipselects.
The gpios will be referred to as reg = <index> in the SPI child nodes. The gpios will be referred to as reg = <index> in the SPI child nodes.
If unspecified, a single SPI device without a chip select can be used. If unspecified, a single SPI device without a chip select can be used.
- fsl,spisel_boot : for the MPC8306 and MPC8309, specifies that the
SPISEL_BOOT signal is used as chip select for a slave device. Use
reg = <number of gpios> in the corresponding child node, i.e. 0 if
the gpios property is not present.
Example: Example:
spi@4c0 { spi@4c0 {
......
...@@ -23,6 +23,18 @@ Required properties: ...@@ -23,6 +23,18 @@ Required properties:
Recommended properties: Recommended properties:
- spi-max-frequency: Definition as per - spi-max-frequency: Definition as per
Documentation/devicetree/bindings/spi/spi-bus.txt Documentation/devicetree/bindings/spi/spi-bus.txt
Optional properties:
- nvidia,tx-clk-tap-delay: Delays the clock going out to the external device
with this tap value. This property is used to tune the outgoing data from
Tegra SPI master with respect to outgoing Tegra SPI master clock.
Tap values vary based on the platform design trace lengths from Tegra SPI
to corresponding slave devices. Valid tap values are from 0 thru 63.
- nvidia,rx-clk-tap-delay: Delays the clock coming in from the external device
with this tap value. This property is used to adjust the Tegra SPI master
clock with respect to the data from the SPI slave device.
Tap values vary based on the platform design trace lengths from Tegra SPI
to corresponding slave devices. Valid tap values are from 0 thru 63.
Example: Example:
spi@7000d600 { spi@7000d600 {
...@@ -38,4 +50,12 @@ spi@7000d600 { ...@@ -38,4 +50,12 @@ spi@7000d600 {
reset-names = "spi"; reset-names = "spi";
dmas = <&apbdma 16>, <&apbdma 16>; dmas = <&apbdma 16>, <&apbdma 16>;
dma-names = "rx", "tx"; dma-names = "rx", "tx";
<spi-client>@<bus_num> {
...
...
nvidia,rx-clk-tap-delay = <0>;
nvidia,tx-clk-tap-delay = <16>;
...
};
}; };
...@@ -4,6 +4,7 @@ Required properties: ...@@ -4,6 +4,7 @@ Required properties:
- compatible : "renesas,msiof-r8a7743" (RZ/G1M) - compatible : "renesas,msiof-r8a7743" (RZ/G1M)
"renesas,msiof-r8a7744" (RZ/G1N) "renesas,msiof-r8a7744" (RZ/G1N)
"renesas,msiof-r8a7745" (RZ/G1E) "renesas,msiof-r8a7745" (RZ/G1E)
"renesas,msiof-r8a77470" (RZ/G1C)
"renesas,msiof-r8a774a1" (RZ/G2M) "renesas,msiof-r8a774a1" (RZ/G2M)
"renesas,msiof-r8a774c0" (RZ/G2E) "renesas,msiof-r8a774c0" (RZ/G2E)
"renesas,msiof-r8a7790" (R-Car H2) "renesas,msiof-r8a7790" (R-Car H2)
......
...@@ -8,9 +8,16 @@ Required properties: ...@@ -8,9 +8,16 @@ Required properties:
- interrupts : One interrupt, used by the controller. - interrupts : One interrupt, used by the controller.
- #address-cells : <1>, as required by generic SPI binding. - #address-cells : <1>, as required by generic SPI binding.
- #size-cells : <0>, also as required by generic SPI binding. - #size-cells : <0>, also as required by generic SPI binding.
- clocks : phandles for the clocks, see the description of clock-names below.
The phandle for the "ssi_clk" is required. The phandle for the "pclk" clock
is optional. If a single clock is specified but no clock-name, it is the
"ssi_clk" clock. If both clocks are listed, the "ssi_clk" must be first.
Optional properties: Optional properties:
- cs-gpios : Specifies the gpio pis to be used for chipselects. - clock-names : Contains the names of the clocks:
"ssi_clk", for the core clock used to generate the external SPI clock.
"pclk", the interface clock, required for register access.
- cs-gpios : Specifies the gpio pins to be used for chipselects.
- num-cs : The number of chipselects. If omitted, this will default to 4. - num-cs : The number of chipselects. If omitted, this will default to 4.
- reg-io-width : The I/O register width (in bytes) implemented by this - reg-io-width : The I/O register width (in bytes) implemented by this
device. Supported values are 2 or 4 (the default). device. Supported values are 2 or 4 (the default).
...@@ -25,6 +32,7 @@ Example: ...@@ -25,6 +32,7 @@ Example:
interrupts = <0 154 4>; interrupts = <0 154 4>;
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
clocks = <&spi_m_clk>;
num-cs = <2>; num-cs = <2>;
cs-gpios = <&gpio0 13 0>, cs-gpios = <&gpio0 13 0>,
<&gpio0 14 0>; <&gpio0 14 0>;
......
...@@ -7,7 +7,11 @@ Required properties: ...@@ -7,7 +7,11 @@ Required properties:
- reg : address and length of the lpspi master registers - reg : address and length of the lpspi master registers
- interrupt-parent : core interrupt controller - interrupt-parent : core interrupt controller
- interrupts : lpspi interrupt - interrupts : lpspi interrupt
- clocks : lpspi clock specifier - clocks : lpspi clock specifier. Its number and order need to correspond to the
value in clock-names.
- clock-names : Corresponding to per clock and ipg clock in "clocks"
respectively. In i.MX7ULP, it only has per clk, so use CLK_DUMMY
to fill the "ipg" blank.
- spi-slave : spi slave mode support. In slave mode, add this attribute without - spi-slave : spi slave mode support. In slave mode, add this attribute without
value. In master mode, remove it. value. In master mode, remove it.
...@@ -18,6 +22,8 @@ lpspi2: lpspi@40290000 { ...@@ -18,6 +22,8 @@ lpspi2: lpspi@40290000 {
reg = <0x40290000 0x10000>; reg = <0x40290000 0x10000>;
interrupt-parent = <&intc>; interrupt-parent = <&intc>;
interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX7ULP_CLK_LPSPI2>; clocks = <&clks IMX7ULP_CLK_LPSPI2>,
<&clks IMX7ULP_CLK_DUMMY>;
clock-names = "per", "ipg";
spi-slave; spi-slave;
}; };
...@@ -10,6 +10,7 @@ Required properties: ...@@ -10,6 +10,7 @@ Required properties:
- mediatek,mt8135-spi: for mt8135 platforms - mediatek,mt8135-spi: for mt8135 platforms
- mediatek,mt8173-spi: for mt8173 platforms - mediatek,mt8173-spi: for mt8173 platforms
- mediatek,mt8183-spi: for mt8183 platforms - mediatek,mt8183-spi: for mt8183 platforms
- "mediatek,mt8516-spi", "mediatek,mt2712-spi": for mt8516 platforms
- #address-cells: should be 1. - #address-cells: should be 1.
......
Binding for MTK SPI controller (MT7621 MIPS)
Required properties:
- compatible: Should be one of the following:
- "ralink,mt7621-spi": for mt7621/mt7628/mt7688 platforms
- #address-cells: should be 1.
- #size-cells: should be 0.
- reg: Address and length of the register set for the device
- resets: phandle to the reset controller asserting this device in
reset
See ../reset/reset.txt for details.
Optional properties:
- cs-gpios: see spi-bus.txt.
Example:
- SoC Specific Portion:
spi0: spi@b00 {
compatible = "ralink,mt7621-spi";
reg = <0xb00 0x100>;
#address-cells = <1>;
#size-cells = <0>;
resets = <&rstctrl 18>;
reset-names = "spi";
};
Xilinx Zynq QSPI controller Device Tree Bindings
-------------------------------------------------------------------
Required properties:
- compatible : Should be "xlnx,zynq-qspi-1.0".
- reg : Physical base address and size of QSPI registers map.
- interrupts : Property with a value describing the interrupt
number.
- clock-names : List of input clock names - "ref_clk", "pclk"
(See clock bindings for details).
- clocks : Clock phandles (see clock bindings for details).
Optional properties:
- num-cs : Number of chip selects used.
Example:
qspi: spi@e000d000 {
compatible = "xlnx,zynq-qspi-1.0";
reg = <0xe000d000 0x1000>;
interrupt-parent = <&intc>;
interrupts = <0 19 4>;
clock-names = "ref_clk", "pclk";
clocks = <&clkc 10>, <&clkc 43>;
num-cs = <1>;
};
...@@ -572,6 +572,12 @@ SPI MASTER METHODS ...@@ -572,6 +572,12 @@ SPI MASTER METHODS
0: transfer is finished 0: transfer is finished
1: transfer is still in progress 1: transfer is still in progress
master->set_cs_timing(struct spi_device *spi, u8 setup_clk_cycles,
u8 hold_clk_cycles, u8 inactive_clk_cycles)
This method allows SPI client drivers to request SPI master controller
for configuring device specific CS setup, hold and inactive timing
requirements.
DEPRECATED METHODS DEPRECATED METHODS
master->transfer(struct spi_device *spi, struct spi_message *message) master->transfer(struct spi_device *spi, struct spi_message *message)
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/gpio/machine.h>
#include <sound/cs4271.h> #include <sound/cs4271.h>
...@@ -105,13 +106,16 @@ static struct spi_board_info edb93xx_spi_board_info[] __initdata = { ...@@ -105,13 +106,16 @@ static struct spi_board_info edb93xx_spi_board_info[] __initdata = {
}, },
}; };
static int edb93xx_spi_chipselects[] __initdata = { static struct gpiod_lookup_table edb93xx_spi_cs_gpio_table = {
EP93XX_GPIO_LINE_EGPIO6, .dev_id = "ep93xx-spi.0",
.table = {
GPIO_LOOKUP("A", 6, "cs", GPIO_ACTIVE_LOW),
{ },
},
}; };
static struct ep93xx_spi_info edb93xx_spi_info __initdata = { static struct ep93xx_spi_info edb93xx_spi_info __initdata = {
.chipselect = edb93xx_spi_chipselects, /* Intentionally left blank */
.num_chipselect = ARRAY_SIZE(edb93xx_spi_chipselects),
}; };
static void __init edb93xx_register_spi(void) static void __init edb93xx_register_spi(void)
...@@ -123,6 +127,7 @@ static void __init edb93xx_register_spi(void) ...@@ -123,6 +127,7 @@ static void __init edb93xx_register_spi(void)
else if (machine_is_edb9315a()) else if (machine_is_edb9315a())
edb93xx_cs4271_data.gpio_nreset = EP93XX_GPIO_LINE_EGPIO14; edb93xx_cs4271_data.gpio_nreset = EP93XX_GPIO_LINE_EGPIO14;
gpiod_add_lookup_table(&edb93xx_spi_cs_gpio_table);
ep93xx_register_spi(&edb93xx_spi_info, edb93xx_spi_board_info, ep93xx_register_spi(&edb93xx_spi_info, edb93xx_spi_board_info,
ARRAY_SIZE(edb93xx_spi_board_info)); ARRAY_SIZE(edb93xx_spi_board_info));
} }
......
...@@ -77,13 +77,15 @@ static struct spi_board_info simone_spi_devices[] __initdata = { ...@@ -77,13 +77,15 @@ static struct spi_board_info simone_spi_devices[] __initdata = {
* low between multi-message command blocks. From v1.4, it uses a GPIO instead. * low between multi-message command blocks. From v1.4, it uses a GPIO instead.
* v1.3 parts will still work, since the signal on SFRMOUT is automatic. * v1.3 parts will still work, since the signal on SFRMOUT is automatic.
*/ */
static int simone_spi_chipselects[] __initdata = { static struct gpiod_lookup_table simone_spi_cs_gpio_table = {
EP93XX_GPIO_LINE_EGPIO1, .dev_id = "ep93xx-spi.0",
.table = {
GPIO_LOOKUP("A", 1, "cs", GPIO_ACTIVE_LOW),
{ },
},
}; };
static struct ep93xx_spi_info simone_spi_info __initdata = { static struct ep93xx_spi_info simone_spi_info __initdata = {
.chipselect = simone_spi_chipselects,
.num_chipselect = ARRAY_SIZE(simone_spi_chipselects),
.use_dma = 1, .use_dma = 1,
}; };
...@@ -113,6 +115,7 @@ static void __init simone_init_machine(void) ...@@ -113,6 +115,7 @@ static void __init simone_init_machine(void)
ep93xx_register_i2c(simone_i2c_board_info, ep93xx_register_i2c(simone_i2c_board_info,
ARRAY_SIZE(simone_i2c_board_info)); ARRAY_SIZE(simone_i2c_board_info));
gpiod_add_lookup_table(&simone_mmc_spi_gpio_table); gpiod_add_lookup_table(&simone_mmc_spi_gpio_table);
gpiod_add_lookup_table(&simone_spi_cs_gpio_table);
ep93xx_register_spi(&simone_spi_info, simone_spi_devices, ep93xx_register_spi(&simone_spi_info, simone_spi_devices,
ARRAY_SIZE(simone_spi_devices)); ARRAY_SIZE(simone_spi_devices));
simone_register_audio(); simone_register_audio();
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <linux/spi/mmc_spi.h> #include <linux/spi/mmc_spi.h>
#include <linux/mmc/host.h> #include <linux/mmc/host.h>
#include <linux/platform_data/spi-ep93xx.h> #include <linux/platform_data/spi-ep93xx.h>
#include <linux/gpio/machine.h>
#include <mach/gpio-ep93xx.h> #include <mach/gpio-ep93xx.h>
#include <mach/hardware.h> #include <mach/hardware.h>
...@@ -269,13 +270,15 @@ static struct spi_board_info bk3_spi_board_info[] __initdata = { ...@@ -269,13 +270,15 @@ static struct spi_board_info bk3_spi_board_info[] __initdata = {
* The all work is performed automatically by !SPI_FRAME (SFRM1) and * The all work is performed automatically by !SPI_FRAME (SFRM1) and
* goes through CPLD * goes through CPLD
*/ */
static int bk3_spi_chipselects[] __initdata = { static struct gpiod_lookup_table bk3_spi_cs_gpio_table = {
EP93XX_GPIO_LINE_F(3), .dev_id = "ep93xx-spi.0",
.table = {
GPIO_LOOKUP("F", 3, "cs", GPIO_ACTIVE_LOW),
{ },
},
}; };
static struct ep93xx_spi_info bk3_spi_master __initdata = { static struct ep93xx_spi_info bk3_spi_master __initdata = {
.chipselect = bk3_spi_chipselects,
.num_chipselect = ARRAY_SIZE(bk3_spi_chipselects),
.use_dma = 1, .use_dma = 1,
}; };
...@@ -316,13 +319,17 @@ static struct spi_board_info ts72xx_spi_devices[] __initdata = { ...@@ -316,13 +319,17 @@ static struct spi_board_info ts72xx_spi_devices[] __initdata = {
}, },
}; };
static int ts72xx_spi_chipselects[] __initdata = { static struct gpiod_lookup_table ts72xx_spi_cs_gpio_table = {
EP93XX_GPIO_LINE_F(2), /* DIO_17 */ .dev_id = "ep93xx-spi.0",
.table = {
/* DIO_17 */
GPIO_LOOKUP("F", 2, "cs", GPIO_ACTIVE_LOW),
{ },
},
}; };
static struct ep93xx_spi_info ts72xx_spi_info __initdata = { static struct ep93xx_spi_info ts72xx_spi_info __initdata = {
.chipselect = ts72xx_spi_chipselects, /* Intentionally left blank */
.num_chipselect = ARRAY_SIZE(ts72xx_spi_chipselects),
}; };
static void __init ts72xx_init_machine(void) static void __init ts72xx_init_machine(void)
...@@ -339,6 +346,7 @@ static void __init ts72xx_init_machine(void) ...@@ -339,6 +346,7 @@ static void __init ts72xx_init_machine(void)
if (board_is_ts7300()) if (board_is_ts7300())
platform_device_register(&ts73xx_fpga_device); platform_device_register(&ts73xx_fpga_device);
#endif #endif
gpiod_add_lookup_table(&ts72xx_spi_cs_gpio_table);
ep93xx_register_spi(&ts72xx_spi_info, ts72xx_spi_devices, ep93xx_register_spi(&ts72xx_spi_info, ts72xx_spi_devices,
ARRAY_SIZE(ts72xx_spi_devices)); ARRAY_SIZE(ts72xx_spi_devices));
} }
...@@ -398,6 +406,7 @@ static void __init bk3_init_machine(void) ...@@ -398,6 +406,7 @@ static void __init bk3_init_machine(void)
ep93xx_register_eth(&ts72xx_eth_data, 1); ep93xx_register_eth(&ts72xx_eth_data, 1);
gpiod_add_lookup_table(&bk3_spi_cs_gpio_table);
ep93xx_register_spi(&bk3_spi_master, bk3_spi_board_info, ep93xx_register_spi(&bk3_spi_master, bk3_spi_board_info,
ARRAY_SIZE(bk3_spi_board_info)); ARRAY_SIZE(bk3_spi_board_info));
......
...@@ -245,15 +245,17 @@ static struct spi_board_info vision_spi_board_info[] __initdata = { ...@@ -245,15 +245,17 @@ static struct spi_board_info vision_spi_board_info[] __initdata = {
}, },
}; };
static int vision_spi_chipselects[] __initdata = { static struct gpiod_lookup_table vision_spi_cs_gpio_table = {
EP93XX_GPIO_LINE_EGPIO6, .dev_id = "ep93xx-spi.0",
EP93XX_GPIO_LINE_EGPIO7, .table = {
EP93XX_GPIO_LINE_G(2), GPIO_LOOKUP_IDX("A", 6, "cs", 0, GPIO_ACTIVE_LOW),
GPIO_LOOKUP_IDX("A", 7, "cs", 1, GPIO_ACTIVE_LOW),
GPIO_LOOKUP_IDX("G", 2, "cs", 2, GPIO_ACTIVE_LOW),
{ },
},
}; };
static struct ep93xx_spi_info vision_spi_master __initdata = { static struct ep93xx_spi_info vision_spi_master __initdata = {
.chipselect = vision_spi_chipselects,
.num_chipselect = ARRAY_SIZE(vision_spi_chipselects),
.use_dma = 1, .use_dma = 1,
}; };
...@@ -295,6 +297,7 @@ static void __init vision_init_machine(void) ...@@ -295,6 +297,7 @@ static void __init vision_init_machine(void)
ep93xx_register_i2c(vision_i2c_info, ep93xx_register_i2c(vision_i2c_info,
ARRAY_SIZE(vision_i2c_info)); ARRAY_SIZE(vision_i2c_info));
gpiod_add_lookup_table(&vision_spi_mmc_gpio_table); gpiod_add_lookup_table(&vision_spi_mmc_gpio_table);
gpiod_add_lookup_table(&vision_spi_cs_gpio_table);
ep93xx_register_spi(&vision_spi_master, vision_spi_board_info, ep93xx_register_spi(&vision_spi_master, vision_spi_board_info,
ARRAY_SIZE(vision_spi_board_info)); ARRAY_SIZE(vision_spi_board_info));
vision_register_i2s(); vision_register_i2s();
......
...@@ -806,7 +806,6 @@ static struct spi_board_info spi_bus[] = { ...@@ -806,7 +806,6 @@ static struct spi_board_info spi_bus[] = {
.platform_data = &mmc_spi_info, .platform_data = &mmc_spi_info,
.max_speed_hz = 5000000, .max_speed_hz = 5000000,
.mode = SPI_MODE_0, .mode = SPI_MODE_0,
.controller_data = (void *) GPIO_PTM4,
}, },
}; };
...@@ -838,6 +837,14 @@ static struct platform_device msiof0_device = { ...@@ -838,6 +837,14 @@ static struct platform_device msiof0_device = {
.resource = msiof0_resources, .resource = msiof0_resources,
}; };
static struct gpiod_lookup_table msiof_gpio_table = {
.dev_id = "spi_sh_msiof.0",
.table = {
GPIO_LOOKUP("sh7724_pfc", GPIO_PTM4, "cs", GPIO_ACTIVE_HIGH),
{ },
},
};
#endif #endif
/* FSI */ /* FSI */
...@@ -1296,12 +1303,11 @@ static int __init arch_setup(void) ...@@ -1296,12 +1303,11 @@ static int __init arch_setup(void)
gpio_request(GPIO_FN_MSIOF0_TXD, NULL); gpio_request(GPIO_FN_MSIOF0_TXD, NULL);
gpio_request(GPIO_FN_MSIOF0_RXD, NULL); gpio_request(GPIO_FN_MSIOF0_RXD, NULL);
gpio_request(GPIO_FN_MSIOF0_TSCK, NULL); gpio_request(GPIO_FN_MSIOF0_TSCK, NULL);
gpio_request(GPIO_PTM4, NULL); /* software CS control of TSYNC pin */
gpio_direction_output(GPIO_PTM4, 1); /* active low CS */
gpio_request(GPIO_PTB6, NULL); /* 3.3V power control */ gpio_request(GPIO_PTB6, NULL); /* 3.3V power control */
gpio_direction_output(GPIO_PTB6, 0); /* disable power by default */ gpio_direction_output(GPIO_PTB6, 0); /* disable power by default */
gpiod_add_lookup_table(&mmc_spi_gpio_table); gpiod_add_lookup_table(&mmc_spi_gpio_table);
gpiod_add_lookup_table(&msiof_gpio_table);
spi_register_board_info(spi_bus, ARRAY_SIZE(spi_bus)); spi_register_board_info(spi_bus, ARRAY_SIZE(spi_bus));
#endif #endif
......
...@@ -426,6 +426,12 @@ config SPI_MT65XX ...@@ -426,6 +426,12 @@ config SPI_MT65XX
say Y or M here.If you are not sure, say N. say Y or M here.If you are not sure, say N.
SPI drivers for Mediatek MT65XX and MT81XX series ARM SoCs. SPI drivers for Mediatek MT65XX and MT81XX series ARM SoCs.
config SPI_MT7621
tristate "MediaTek MT7621 SPI Controller"
depends on RALINK || COMPILE_TEST
help
This selects a driver for the MediaTek MT7621 SPI Controller.
config SPI_NPCM_PSPI config SPI_NPCM_PSPI
tristate "Nuvoton NPCM PSPI Controller" tristate "Nuvoton NPCM PSPI Controller"
depends on ARCH_NPCM || COMPILE_TEST depends on ARCH_NPCM || COMPILE_TEST
...@@ -842,9 +848,17 @@ config SPI_XTENSA_XTFPGA ...@@ -842,9 +848,17 @@ config SPI_XTENSA_XTFPGA
16 bit words in SPI mode 0, automatically asserting CS on transfer 16 bit words in SPI mode 0, automatically asserting CS on transfer
start and deasserting on end. start and deasserting on end.
config SPI_ZYNQ_QSPI
tristate "Xilinx Zynq QSPI controller"
depends on ARCH_ZYNQ || COMPILE_TEST
help
This enables support for the Zynq Quad SPI controller
in master mode.
This controller only supports SPI memory interface.
config SPI_ZYNQMP_GQSPI config SPI_ZYNQMP_GQSPI
tristate "Xilinx ZynqMP GQSPI controller" tristate "Xilinx ZynqMP GQSPI controller"
depends on SPI_MASTER && HAS_DMA depends on (SPI_MASTER && HAS_DMA) || COMPILE_TEST
help help
Enables Xilinx GQSPI controller driver for Zynq UltraScale+ MPSoC. Enables Xilinx GQSPI controller driver for Zynq UltraScale+ MPSoC.
......
...@@ -60,6 +60,7 @@ obj-$(CONFIG_SPI_MPC512x_PSC) += spi-mpc512x-psc.o ...@@ -60,6 +60,7 @@ obj-$(CONFIG_SPI_MPC512x_PSC) += spi-mpc512x-psc.o
obj-$(CONFIG_SPI_MPC52xx_PSC) += spi-mpc52xx-psc.o obj-$(CONFIG_SPI_MPC52xx_PSC) += spi-mpc52xx-psc.o
obj-$(CONFIG_SPI_MPC52xx) += spi-mpc52xx.o obj-$(CONFIG_SPI_MPC52xx) += spi-mpc52xx.o
obj-$(CONFIG_SPI_MT65XX) += spi-mt65xx.o obj-$(CONFIG_SPI_MT65XX) += spi-mt65xx.o
obj-$(CONFIG_SPI_MT7621) += spi-mt7621.o
obj-$(CONFIG_SPI_MXIC) += spi-mxic.o obj-$(CONFIG_SPI_MXIC) += spi-mxic.o
obj-$(CONFIG_SPI_MXS) += spi-mxs.o obj-$(CONFIG_SPI_MXS) += spi-mxs.o
obj-$(CONFIG_SPI_NPCM_PSPI) += spi-npcm-pspi.o obj-$(CONFIG_SPI_NPCM_PSPI) += spi-npcm-pspi.o
...@@ -118,6 +119,7 @@ obj-$(CONFIG_SPI_XCOMM) += spi-xcomm.o ...@@ -118,6 +119,7 @@ obj-$(CONFIG_SPI_XCOMM) += spi-xcomm.o
obj-$(CONFIG_SPI_XILINX) += spi-xilinx.o obj-$(CONFIG_SPI_XILINX) += spi-xilinx.o
obj-$(CONFIG_SPI_XLP) += spi-xlp.o obj-$(CONFIG_SPI_XLP) += spi-xlp.o
obj-$(CONFIG_SPI_XTENSA_XTFPGA) += spi-xtensa-xtfpga.o obj-$(CONFIG_SPI_XTENSA_XTFPGA) += spi-xtensa-xtfpga.o
obj-$(CONFIG_SPI_ZYNQ_QSPI) += spi-zynq-qspi.o
obj-$(CONFIG_SPI_ZYNQMP_GQSPI) += spi-zynqmp-gqspi.o obj-$(CONFIG_SPI_ZYNQMP_GQSPI) += spi-zynqmp-gqspi.o
# SPI slave protocol handlers # SPI slave protocol handlers
......
...@@ -366,7 +366,7 @@ static int atmel_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) ...@@ -366,7 +366,7 @@ static int atmel_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
return err; return err;
} }
const char *atmel_qspi_get_name(struct spi_mem *spimem) static const char *atmel_qspi_get_name(struct spi_mem *spimem)
{ {
return dev_name(spimem->spi->dev.parent); return dev_name(spimem->spi->dev.parent);
} }
...@@ -570,7 +570,8 @@ static int atmel_qspi_remove(struct platform_device *pdev) ...@@ -570,7 +570,8 @@ static int atmel_qspi_remove(struct platform_device *pdev)
static int __maybe_unused atmel_qspi_suspend(struct device *dev) static int __maybe_unused atmel_qspi_suspend(struct device *dev)
{ {
struct atmel_qspi *aq = dev_get_drvdata(dev); struct spi_controller *ctrl = dev_get_drvdata(dev);
struct atmel_qspi *aq = spi_controller_get_devdata(ctrl);
clk_disable_unprepare(aq->qspick); clk_disable_unprepare(aq->qspick);
clk_disable_unprepare(aq->pclk); clk_disable_unprepare(aq->pclk);
...@@ -580,7 +581,8 @@ static int __maybe_unused atmel_qspi_suspend(struct device *dev) ...@@ -580,7 +581,8 @@ static int __maybe_unused atmel_qspi_suspend(struct device *dev)
static int __maybe_unused atmel_qspi_resume(struct device *dev) static int __maybe_unused atmel_qspi_resume(struct device *dev)
{ {
struct atmel_qspi *aq = dev_get_drvdata(dev); struct spi_controller *ctrl = dev_get_drvdata(dev);
struct atmel_qspi *aq = spi_controller_get_devdata(ctrl);
clk_prepare_enable(aq->pclk); clk_prepare_enable(aq->pclk);
clk_prepare_enable(aq->qspick); clk_prepare_enable(aq->qspick);
......
...@@ -178,12 +178,6 @@ static int at91_usart_spi_setup(struct spi_device *spi) ...@@ -178,12 +178,6 @@ static int at91_usart_spi_setup(struct spi_device *spi)
struct at91_usart_spi *aus = spi_master_get_devdata(spi->controller); struct at91_usart_spi *aus = spi_master_get_devdata(spi->controller);
u32 *ausd = spi->controller_state; u32 *ausd = spi->controller_state;
unsigned int mr = at91_usart_spi_readl(aus, MR); unsigned int mr = at91_usart_spi_readl(aus, MR);
u8 bits = spi->bits_per_word;
if (bits != 8) {
dev_dbg(&spi->dev, "Only 8 bits per word are supported\n");
return -EINVAL;
}
if (spi->mode & SPI_CPOL) if (spi->mode & SPI_CPOL)
mr |= US_MR_CPOL; mr |= US_MR_CPOL;
...@@ -212,7 +206,7 @@ static int at91_usart_spi_setup(struct spi_device *spi) ...@@ -212,7 +206,7 @@ static int at91_usart_spi_setup(struct spi_device *spi)
dev_dbg(&spi->dev, dev_dbg(&spi->dev,
"setup: bpw %u mode 0x%x -> mr %d %08x\n", "setup: bpw %u mode 0x%x -> mr %d %08x\n",
bits, spi->mode, spi->chip_select, mr); spi->bits_per_word, spi->mode, spi->chip_select, mr);
return 0; return 0;
} }
......
...@@ -335,20 +335,6 @@ static int bcm2835_spi_transfer_one_irq(struct spi_master *master, ...@@ -335,20 +335,6 @@ static int bcm2835_spi_transfer_one_irq(struct spi_master *master,
return 1; return 1;
} }
/*
* DMA support
*
* this implementation has currently a few issues in so far as it does
* not work arrount limitations of the HW.
*
* the main one being that DMA transfers are limited to 16 bit
* (so 0 to 65535 bytes) by the SPI HW due to BCM2835_SPI_DLEN
*
* there may be a few more border-cases we may need to address as well
* but unfortunately this would mean splitting up the scatter-gather
* list making it slightly unpractical...
*/
/** /**
* bcm2835_spi_transfer_prologue() - transfer first few bytes without DMA * bcm2835_spi_transfer_prologue() - transfer first few bytes without DMA
* @master: SPI master * @master: SPI master
...@@ -630,19 +616,6 @@ static bool bcm2835_spi_can_dma(struct spi_master *master, ...@@ -630,19 +616,6 @@ static bool bcm2835_spi_can_dma(struct spi_master *master,
if (tfr->len < BCM2835_SPI_DMA_MIN_LENGTH) if (tfr->len < BCM2835_SPI_DMA_MIN_LENGTH)
return false; return false;
/* BCM2835_SPI_DLEN has defined a max transfer size as
* 16 bit, so max is 65535
* we can revisit this by using an alternative transfer
* method - ideally this would get done without any more
* interaction...
*/
if (tfr->len > 65535) {
dev_warn_once(&spi->dev,
"transfer size of %d too big for dma-transfer\n",
tfr->len);
return false;
}
/* return OK */ /* return OK */
return true; return true;
} }
...@@ -707,7 +680,6 @@ static void bcm2835_dma_init(struct spi_master *master, struct device *dev) ...@@ -707,7 +680,6 @@ static void bcm2835_dma_init(struct spi_master *master, struct device *dev)
/* all went well, so set can_dma */ /* all went well, so set can_dma */
master->can_dma = bcm2835_spi_can_dma; master->can_dma = bcm2835_spi_can_dma;
master->max_dma_len = 65535; /* limitation by BCM2835_SPI_DLEN */
/* need to do TX AND RX DMA, so we need dummy buffers */ /* need to do TX AND RX DMA, so we need dummy buffers */
master->flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX; master->flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX;
...@@ -844,6 +816,17 @@ static int bcm2835_spi_prepare_message(struct spi_master *master, ...@@ -844,6 +816,17 @@ static int bcm2835_spi_prepare_message(struct spi_master *master,
struct spi_device *spi = msg->spi; struct spi_device *spi = msg->spi;
struct bcm2835_spi *bs = spi_master_get_devdata(master); struct bcm2835_spi *bs = spi_master_get_devdata(master);
u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS);
int ret;
/*
* DMA transfers are limited to 16 bit (0 to 65535 bytes) by the SPI HW
* due to DLEN. Split up transfers (32-bit FIFO aligned) if the limit is
* exceeded.
*/
ret = spi_split_transfers_maxsize(master, msg, 65532,
GFP_KERNEL | GFP_DMA);
if (ret)
return ret;
cs &= ~(BCM2835_SPI_CS_CPOL | BCM2835_SPI_CS_CPHA); cs &= ~(BCM2835_SPI_CS_CPOL | BCM2835_SPI_CS_CPHA);
......
This diff is collapsed.
...@@ -335,6 +335,42 @@ static void spi_bitbang_set_cs(struct spi_device *spi, bool enable) ...@@ -335,6 +335,42 @@ static void spi_bitbang_set_cs(struct spi_device *spi, bool enable)
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
int spi_bitbang_init(struct spi_bitbang *bitbang)
{
struct spi_master *master = bitbang->master;
if (!master || !bitbang->chipselect)
return -EINVAL;
mutex_init(&bitbang->lock);
if (!master->mode_bits)
master->mode_bits = SPI_CPOL | SPI_CPHA | bitbang->flags;
if (master->transfer || master->transfer_one_message)
return -EINVAL;
master->prepare_transfer_hardware = spi_bitbang_prepare_hardware;
master->unprepare_transfer_hardware = spi_bitbang_unprepare_hardware;
master->transfer_one = spi_bitbang_transfer_one;
master->set_cs = spi_bitbang_set_cs;
if (!bitbang->txrx_bufs) {
bitbang->use_dma = 0;
bitbang->txrx_bufs = spi_bitbang_bufs;
if (!master->setup) {
if (!bitbang->setup_transfer)
bitbang->setup_transfer =
spi_bitbang_setup_transfer;
master->setup = spi_bitbang_setup;
master->cleanup = spi_bitbang_cleanup;
}
}
return 0;
}
EXPORT_SYMBOL_GPL(spi_bitbang_init);
/** /**
* spi_bitbang_start - start up a polled/bitbanging SPI master driver * spi_bitbang_start - start up a polled/bitbanging SPI master driver
* @bitbang: driver handle * @bitbang: driver handle
...@@ -368,33 +404,9 @@ int spi_bitbang_start(struct spi_bitbang *bitbang) ...@@ -368,33 +404,9 @@ int spi_bitbang_start(struct spi_bitbang *bitbang)
struct spi_master *master = bitbang->master; struct spi_master *master = bitbang->master;
int ret; int ret;
if (!master || !bitbang->chipselect) ret = spi_bitbang_init(bitbang);
return -EINVAL; if (ret)
return ret;
mutex_init(&bitbang->lock);
if (!master->mode_bits)
master->mode_bits = SPI_CPOL | SPI_CPHA | bitbang->flags;
if (master->transfer || master->transfer_one_message)
return -EINVAL;
master->prepare_transfer_hardware = spi_bitbang_prepare_hardware;
master->unprepare_transfer_hardware = spi_bitbang_unprepare_hardware;
master->transfer_one = spi_bitbang_transfer_one;
master->set_cs = spi_bitbang_set_cs;
if (!bitbang->txrx_bufs) {
bitbang->use_dma = 0;
bitbang->txrx_bufs = spi_bitbang_bufs;
if (!master->setup) {
if (!bitbang->setup_transfer)
bitbang->setup_transfer =
spi_bitbang_setup_transfer;
master->setup = spi_bitbang_setup;
master->cleanup = spi_bitbang_cleanup;
}
}
/* driver may get busy before register() returns, especially /* driver may get busy before register() returns, especially
* if someone registered boardinfo for devices * if someone registered boardinfo for devices
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
struct dw_spi_mmio { struct dw_spi_mmio {
struct dw_spi dws; struct dw_spi dws;
struct clk *clk; struct clk *clk;
struct clk *pclk;
void *priv; void *priv;
}; };
...@@ -172,6 +173,14 @@ static int dw_spi_mmio_probe(struct platform_device *pdev) ...@@ -172,6 +173,14 @@ static int dw_spi_mmio_probe(struct platform_device *pdev)
if (ret) if (ret)
return ret; return ret;
/* Optional clock needed to access the registers */
dwsmmio->pclk = devm_clk_get_optional(&pdev->dev, "pclk");
if (IS_ERR(dwsmmio->pclk))
return PTR_ERR(dwsmmio->pclk);
ret = clk_prepare_enable(dwsmmio->pclk);
if (ret)
goto out_clk;
dws->bus_num = pdev->id; dws->bus_num = pdev->id;
dws->max_freq = clk_get_rate(dwsmmio->clk); dws->max_freq = clk_get_rate(dwsmmio->clk);
...@@ -199,6 +208,8 @@ static int dw_spi_mmio_probe(struct platform_device *pdev) ...@@ -199,6 +208,8 @@ static int dw_spi_mmio_probe(struct platform_device *pdev)
return 0; return 0;
out: out:
clk_disable_unprepare(dwsmmio->pclk);
out_clk:
clk_disable_unprepare(dwsmmio->clk); clk_disable_unprepare(dwsmmio->clk);
return ret; return ret;
} }
...@@ -208,6 +219,7 @@ static int dw_spi_mmio_remove(struct platform_device *pdev) ...@@ -208,6 +219,7 @@ static int dw_spi_mmio_remove(struct platform_device *pdev)
struct dw_spi_mmio *dwsmmio = platform_get_drvdata(pdev); struct dw_spi_mmio *dwsmmio = platform_get_drvdata(pdev);
dw_spi_remove_host(&dwsmmio->dws); dw_spi_remove_host(&dwsmmio->dws);
clk_disable_unprepare(dwsmmio->pclk);
clk_disable_unprepare(dwsmmio->clk); clk_disable_unprepare(dwsmmio->clk);
return 0; return 0;
......
...@@ -28,7 +28,6 @@ ...@@ -28,7 +28,6 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include <linux/gpio.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/platform_data/dma-ep93xx.h> #include <linux/platform_data/dma-ep93xx.h>
...@@ -652,7 +651,6 @@ static int ep93xx_spi_probe(struct platform_device *pdev) ...@@ -652,7 +651,6 @@ static int ep93xx_spi_probe(struct platform_device *pdev)
struct resource *res; struct resource *res;
int irq; int irq;
int error; int error;
int i;
info = dev_get_platdata(&pdev->dev); info = dev_get_platdata(&pdev->dev);
if (!info) { if (!info) {
...@@ -676,6 +674,7 @@ static int ep93xx_spi_probe(struct platform_device *pdev) ...@@ -676,6 +674,7 @@ static int ep93xx_spi_probe(struct platform_device *pdev)
if (!master) if (!master)
return -ENOMEM; return -ENOMEM;
master->use_gpio_descriptors = true;
master->prepare_transfer_hardware = ep93xx_spi_prepare_hardware; master->prepare_transfer_hardware = ep93xx_spi_prepare_hardware;
master->unprepare_transfer_hardware = ep93xx_spi_unprepare_hardware; master->unprepare_transfer_hardware = ep93xx_spi_unprepare_hardware;
master->prepare_message = ep93xx_spi_prepare_message; master->prepare_message = ep93xx_spi_prepare_message;
...@@ -683,31 +682,11 @@ static int ep93xx_spi_probe(struct platform_device *pdev) ...@@ -683,31 +682,11 @@ static int ep93xx_spi_probe(struct platform_device *pdev)
master->bus_num = pdev->id; master->bus_num = pdev->id;
master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16); master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16);
/*
master->num_chipselect = info->num_chipselect; * The SPI core will count the number of GPIO descriptors to figure
master->cs_gpios = devm_kcalloc(&master->dev, * out the number of chip selects available on the platform.
master->num_chipselect, sizeof(int), */
GFP_KERNEL); master->num_chipselect = 0;
if (!master->cs_gpios) {
error = -ENOMEM;
goto fail_release_master;
}
for (i = 0; i < master->num_chipselect; i++) {
master->cs_gpios[i] = info->chipselect[i];
if (!gpio_is_valid(master->cs_gpios[i]))
continue;
error = devm_gpio_request_one(&pdev->dev, master->cs_gpios[i],
GPIOF_OUT_INIT_HIGH,
"ep93xx-spi");
if (error) {
dev_err(&pdev->dev, "could not request cs gpio %d\n",
master->cs_gpios[i]);
goto fail_release_master;
}
}
platform_set_drvdata(pdev, master); platform_set_drvdata(pdev, master);
......
...@@ -95,8 +95,10 @@ static inline u32 mpc8xxx_spi_read_reg(__be32 __iomem *reg) ...@@ -95,8 +95,10 @@ static inline u32 mpc8xxx_spi_read_reg(__be32 __iomem *reg)
struct mpc8xxx_spi_probe_info { struct mpc8xxx_spi_probe_info {
struct fsl_spi_platform_data pdata; struct fsl_spi_platform_data pdata;
int ngpios;
int *gpios; int *gpios;
bool *alow_flags; bool *alow_flags;
__be32 __iomem *immr_spi_cs;
}; };
extern u32 mpc8xxx_spi_tx_buf_u8(struct mpc8xxx_spi *mpc8xxx_spi); extern u32 mpc8xxx_spi_tx_buf_u8(struct mpc8xxx_spi *mpc8xxx_spi);
......
This diff is collapsed.
...@@ -882,7 +882,7 @@ static int fsl_qspi_probe(struct platform_device *pdev) ...@@ -882,7 +882,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
ctlr->dev.of_node = np; ctlr->dev.of_node = np;
ret = spi_register_controller(ctlr); ret = devm_spi_register_controller(dev, ctlr);
if (ret) if (ret)
goto err_destroy_mutex; goto err_destroy_mutex;
......
...@@ -39,6 +39,14 @@ ...@@ -39,6 +39,14 @@
#include <linux/spi/spi_bitbang.h> #include <linux/spi/spi_bitbang.h>
#include <linux/types.h> #include <linux/types.h>
#ifdef CONFIG_FSL_SOC
#include <sysdev/fsl_soc.h>
#endif
/* Specific to the MPC8306/MPC8309 */
#define IMMR_SPI_CS_OFFSET 0x14c
#define SPI_BOOT_SEL_BIT 0x80000000
#include "spi-fsl-lib.h" #include "spi-fsl-lib.h"
#include "spi-fsl-cpm.h" #include "spi-fsl-cpm.h"
#include "spi-fsl-spi.h" #include "spi-fsl-spi.h"
...@@ -355,33 +363,50 @@ static int fsl_spi_bufs(struct spi_device *spi, struct spi_transfer *t, ...@@ -355,33 +363,50 @@ static int fsl_spi_bufs(struct spi_device *spi, struct spi_transfer *t,
static int fsl_spi_do_one_msg(struct spi_master *master, static int fsl_spi_do_one_msg(struct spi_master *master,
struct spi_message *m) struct spi_message *m)
{ {
struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(master);
struct spi_device *spi = m->spi; struct spi_device *spi = m->spi;
struct spi_transfer *t, *first; struct spi_transfer *t, *first;
unsigned int cs_change; unsigned int cs_change;
const int nsecs = 50; const int nsecs = 50;
int status; int status, last_bpw;
/*
* In CPU mode, optimize large byte transfers to use larger
* bits_per_word values to reduce number of interrupts taken.
*/
if (!(mpc8xxx_spi->flags & SPI_CPM_MODE)) {
list_for_each_entry(t, &m->transfers, transfer_list) {
if (t->len < 256 || t->bits_per_word != 8)
continue;
if ((t->len & 3) == 0)
t->bits_per_word = 32;
else if ((t->len & 1) == 0)
t->bits_per_word = 16;
}
}
/* Don't allow changes if CS is active */ /* Don't allow changes if CS is active */
first = list_first_entry(&m->transfers, struct spi_transfer, cs_change = 1;
transfer_list);
list_for_each_entry(t, &m->transfers, transfer_list) { list_for_each_entry(t, &m->transfers, transfer_list) {
if ((first->bits_per_word != t->bits_per_word) || if (cs_change)
(first->speed_hz != t->speed_hz)) { first = t;
cs_change = t->cs_change;
if (first->speed_hz != t->speed_hz) {
dev_err(&spi->dev, dev_err(&spi->dev,
"bits_per_word/speed_hz should be same for the same SPI transfer\n"); "speed_hz cannot change while CS is active\n");
return -EINVAL; return -EINVAL;
} }
} }
last_bpw = -1;
cs_change = 1; cs_change = 1;
status = -EINVAL; status = -EINVAL;
list_for_each_entry(t, &m->transfers, transfer_list) { list_for_each_entry(t, &m->transfers, transfer_list) {
if (t->bits_per_word || t->speed_hz) { if (cs_change || last_bpw != t->bits_per_word)
if (cs_change) status = fsl_spi_setup_transfer(spi, t);
status = fsl_spi_setup_transfer(spi, t); if (status < 0)
if (status < 0) break;
break; last_bpw = t->bits_per_word;
}
if (cs_change) { if (cs_change) {
fsl_spi_chipselect(spi, BITBANG_CS_ACTIVE); fsl_spi_chipselect(spi, BITBANG_CS_ACTIVE);
...@@ -701,10 +726,17 @@ static void fsl_spi_cs_control(struct spi_device *spi, bool on) ...@@ -701,10 +726,17 @@ static void fsl_spi_cs_control(struct spi_device *spi, bool on)
struct fsl_spi_platform_data *pdata = dev_get_platdata(dev); struct fsl_spi_platform_data *pdata = dev_get_platdata(dev);
struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(pdata); struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(pdata);
u16 cs = spi->chip_select; u16 cs = spi->chip_select;
int gpio = pinfo->gpios[cs];
bool alow = pinfo->alow_flags[cs];
gpio_set_value(gpio, on ^ alow); if (cs < pinfo->ngpios) {
int gpio = pinfo->gpios[cs];
bool alow = pinfo->alow_flags[cs];
gpio_set_value(gpio, on ^ alow);
} else {
if (WARN_ON_ONCE(cs > pinfo->ngpios || !pinfo->immr_spi_cs))
return;
iowrite32be(on ? SPI_BOOT_SEL_BIT : 0, pinfo->immr_spi_cs);
}
} }
static int of_fsl_spi_get_chipselects(struct device *dev) static int of_fsl_spi_get_chipselects(struct device *dev)
...@@ -712,12 +744,15 @@ static int of_fsl_spi_get_chipselects(struct device *dev) ...@@ -712,12 +744,15 @@ static int of_fsl_spi_get_chipselects(struct device *dev)
struct device_node *np = dev->of_node; struct device_node *np = dev->of_node;
struct fsl_spi_platform_data *pdata = dev_get_platdata(dev); struct fsl_spi_platform_data *pdata = dev_get_platdata(dev);
struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(pdata); struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(pdata);
bool spisel_boot = IS_ENABLED(CONFIG_FSL_SOC) &&
of_property_read_bool(np, "fsl,spisel_boot");
int ngpios; int ngpios;
int i = 0; int i = 0;
int ret; int ret;
ngpios = of_gpio_count(np); ngpios = of_gpio_count(np);
if (ngpios <= 0) { ngpios = max(ngpios, 0);
if (ngpios == 0 && !spisel_boot) {
/* /*
* SPI w/o chip-select line. One SPI device is still permitted * SPI w/o chip-select line. One SPI device is still permitted
* though. * though.
...@@ -726,6 +761,7 @@ static int of_fsl_spi_get_chipselects(struct device *dev) ...@@ -726,6 +761,7 @@ static int of_fsl_spi_get_chipselects(struct device *dev)
return 0; return 0;
} }
pinfo->ngpios = ngpios;
pinfo->gpios = kmalloc_array(ngpios, sizeof(*pinfo->gpios), pinfo->gpios = kmalloc_array(ngpios, sizeof(*pinfo->gpios),
GFP_KERNEL); GFP_KERNEL);
if (!pinfo->gpios) if (!pinfo->gpios)
...@@ -769,7 +805,18 @@ static int of_fsl_spi_get_chipselects(struct device *dev) ...@@ -769,7 +805,18 @@ static int of_fsl_spi_get_chipselects(struct device *dev)
} }
} }
pdata->max_chipselect = ngpios; #if IS_ENABLED(CONFIG_FSL_SOC)
if (spisel_boot) {
pinfo->immr_spi_cs = ioremap(get_immrbase() + IMMR_SPI_CS_OFFSET, 4);
if (!pinfo->immr_spi_cs) {
ret = -ENOMEM;
i = ngpios - 1;
goto err_loop;
}
}
#endif
pdata->max_chipselect = ngpios + spisel_boot;
pdata->cs_control = fsl_spi_cs_control; pdata->cs_control = fsl_spi_cs_control;
return 0; return 0;
......
This diff is collapsed.
...@@ -28,6 +28,10 @@ ...@@ -28,6 +28,10 @@
#define DRIVER_NAME "spi_imx" #define DRIVER_NAME "spi_imx"
static bool use_dma = true;
module_param(use_dma, bool, 0644);
MODULE_PARM_DESC(use_dma, "Enable usage of DMA when available (default)");
#define MXC_CSPIRXDATA 0x00 #define MXC_CSPIRXDATA 0x00
#define MXC_CSPITXDATA 0x04 #define MXC_CSPITXDATA 0x04
#define MXC_CSPICTRL 0x08 #define MXC_CSPICTRL 0x08
...@@ -219,6 +223,9 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, ...@@ -219,6 +223,9 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi,
{ {
struct spi_imx_data *spi_imx = spi_master_get_devdata(master); struct spi_imx_data *spi_imx = spi_master_get_devdata(master);
if (!use_dma)
return false;
if (!master->dma_rx) if (!master->dma_rx)
return false; return false;
...@@ -1494,7 +1501,7 @@ static int spi_imx_transfer(struct spi_device *spi, ...@@ -1494,7 +1501,7 @@ static int spi_imx_transfer(struct spi_device *spi,
/* flush rxfifo before transfer */ /* flush rxfifo before transfer */
while (spi_imx->devtype_data->rx_available(spi_imx)) while (spi_imx->devtype_data->rx_available(spi_imx))
spi_imx->rx(spi_imx); readl(spi_imx->base + MXC_CSPIRXDATA);
if (spi_imx->slave_mode) if (spi_imx->slave_mode)
return spi_imx_pio_transfer_slave(spi, transfer); return spi_imx_pio_transfer_slave(spi, transfer);
......
...@@ -135,8 +135,8 @@ static int spi_check_buswidth_req(struct spi_mem *mem, u8 buswidth, bool tx) ...@@ -135,8 +135,8 @@ static int spi_check_buswidth_req(struct spi_mem *mem, u8 buswidth, bool tx)
return -ENOTSUPP; return -ENOTSUPP;
} }
static bool spi_mem_default_supports_op(struct spi_mem *mem, bool spi_mem_default_supports_op(struct spi_mem *mem,
const struct spi_mem_op *op) const struct spi_mem_op *op)
{ {
if (spi_check_buswidth_req(mem, op->cmd.buswidth, true)) if (spi_check_buswidth_req(mem, op->cmd.buswidth, true))
return false; return false;
...@@ -622,7 +622,7 @@ void devm_spi_mem_dirmap_destroy(struct device *dev, ...@@ -622,7 +622,7 @@ void devm_spi_mem_dirmap_destroy(struct device *dev,
EXPORT_SYMBOL_GPL(devm_spi_mem_dirmap_destroy); EXPORT_SYMBOL_GPL(devm_spi_mem_dirmap_destroy);
/** /**
* spi_mem_dirmap_dirmap_read() - Read data through a direct mapping * spi_mem_dirmap_read() - Read data through a direct mapping
* @desc: direct mapping descriptor * @desc: direct mapping descriptor
* @offs: offset to start reading from. Note that this is not an absolute * @offs: offset to start reading from. Note that this is not an absolute
* offset, but the offset within the direct mapping which already has * offset, but the offset within the direct mapping which already has
...@@ -668,7 +668,7 @@ ssize_t spi_mem_dirmap_read(struct spi_mem_dirmap_desc *desc, ...@@ -668,7 +668,7 @@ ssize_t spi_mem_dirmap_read(struct spi_mem_dirmap_desc *desc,
EXPORT_SYMBOL_GPL(spi_mem_dirmap_read); EXPORT_SYMBOL_GPL(spi_mem_dirmap_read);
/** /**
* spi_mem_dirmap_dirmap_write() - Write data through a direct mapping * spi_mem_dirmap_write() - Write data through a direct mapping
* @desc: direct mapping descriptor * @desc: direct mapping descriptor
* @offs: offset to start writing from. Note that this is not an absolute * @offs: offset to start writing from. Note that this is not an absolute
* offset, but the offset within the direct mapping which already has * offset, but the offset within the direct mapping which already has
......
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
/* //
* spi-mt7621.c -- MediaTek MT7621 SPI controller driver // spi-mt7621.c -- MediaTek MT7621 SPI controller driver
* //
* Copyright (C) 2011 Sergiy <piratfm@gmail.com> // Copyright (C) 2011 Sergiy <piratfm@gmail.com>
* Copyright (C) 2011-2013 Gabor Juhos <juhosg@openwrt.org> // Copyright (C) 2011-2013 Gabor Juhos <juhosg@openwrt.org>
* Copyright (C) 2014-2015 Felix Fietkau <nbd@nbd.name> // Copyright (C) 2014-2015 Felix Fietkau <nbd@nbd.name>
* //
* Some parts are based on spi-orion.c: // Some parts are based on spi-orion.c:
* Author: Shadi Ammouri <shadi@marvell.com> // Author: Shadi Ammouri <shadi@marvell.com>
* Copyright (C) 2007-2008 Marvell Ltd. // Copyright (C) 2007-2008 Marvell Ltd.
*/
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/delay.h> #include <linux/delay.h>
...@@ -52,7 +51,7 @@ ...@@ -52,7 +51,7 @@
#define MT7621_LSB_FIRST BIT(3) #define MT7621_LSB_FIRST BIT(3)
struct mt7621_spi { struct mt7621_spi {
struct spi_master *master; struct spi_controller *master;
void __iomem *base; void __iomem *base;
unsigned int sys_freq; unsigned int sys_freq;
unsigned int speed; unsigned int speed;
...@@ -64,7 +63,7 @@ struct mt7621_spi { ...@@ -64,7 +63,7 @@ struct mt7621_spi {
static inline struct mt7621_spi *spidev_to_mt7621_spi(struct spi_device *spi) static inline struct mt7621_spi *spidev_to_mt7621_spi(struct spi_device *spi)
{ {
return spi_master_get_devdata(spi->master); return spi_controller_get_devdata(spi->master);
} }
static inline u32 mt7621_spi_read(struct mt7621_spi *rs, u32 reg) static inline u32 mt7621_spi_read(struct mt7621_spi *rs, u32 reg)
...@@ -77,29 +76,25 @@ static inline void mt7621_spi_write(struct mt7621_spi *rs, u32 reg, u32 val) ...@@ -77,29 +76,25 @@ static inline void mt7621_spi_write(struct mt7621_spi *rs, u32 reg, u32 val)
iowrite32(val, rs->base + reg); iowrite32(val, rs->base + reg);
} }
static void mt7621_spi_reset(struct mt7621_spi *rs) static void mt7621_spi_set_cs(struct spi_device *spi, int enable)
{ {
u32 master = mt7621_spi_read(rs, MT7621_SPI_MASTER); struct mt7621_spi *rs = spidev_to_mt7621_spi(spi);
int cs = spi->chip_select;
u32 polar = 0;
u32 master;
/* /*
* Select SPI device 7, enable "more buffer mode" and disable * Select SPI device 7, enable "more buffer mode" and disable
* full-duplex (only half-duplex really works on this chip * full-duplex (only half-duplex really works on this chip
* reliably) * reliably)
*/ */
master = mt7621_spi_read(rs, MT7621_SPI_MASTER);
master |= MASTER_RS_SLAVE_SEL | MASTER_MORE_BUFMODE; master |= MASTER_RS_SLAVE_SEL | MASTER_MORE_BUFMODE;
master &= ~MASTER_FULL_DUPLEX; master &= ~MASTER_FULL_DUPLEX;
mt7621_spi_write(rs, MT7621_SPI_MASTER, master); mt7621_spi_write(rs, MT7621_SPI_MASTER, master);
rs->pending_write = 0;
}
static void mt7621_spi_set_cs(struct spi_device *spi, int enable) rs->pending_write = 0;
{
struct mt7621_spi *rs = spidev_to_mt7621_spi(spi);
int cs = spi->chip_select;
u32 polar = 0;
mt7621_spi_reset(rs);
if (enable) if (enable)
polar = BIT(cs); polar = BIT(cs);
mt7621_spi_write(rs, MT7621_SPI_POLAR, polar); mt7621_spi_write(rs, MT7621_SPI_POLAR, polar);
...@@ -163,13 +158,14 @@ static inline int mt7621_spi_wait_till_ready(struct mt7621_spi *rs) ...@@ -163,13 +158,14 @@ static inline int mt7621_spi_wait_till_ready(struct mt7621_spi *rs)
static void mt7621_spi_read_half_duplex(struct mt7621_spi *rs, static void mt7621_spi_read_half_duplex(struct mt7621_spi *rs,
int rx_len, u8 *buf) int rx_len, u8 *buf)
{ {
int tx_len;
/* /*
* Combine with any pending write, and perform one or more half-duplex * Combine with any pending write, and perform one or more half-duplex
* transactions reading 'len' bytes. Data to be written is already in * transactions reading 'len' bytes. Data to be written is already in
* MT7621_SPI_DATA. * MT7621_SPI_DATA.
*/ */
int tx_len = rs->pending_write; tx_len = rs->pending_write;
rs->pending_write = 0; rs->pending_write = 0;
while (rx_len || tx_len) { while (rx_len || tx_len) {
...@@ -209,8 +205,8 @@ static inline void mt7621_spi_flush(struct mt7621_spi *rs) ...@@ -209,8 +205,8 @@ static inline void mt7621_spi_flush(struct mt7621_spi *rs)
static void mt7621_spi_write_half_duplex(struct mt7621_spi *rs, static void mt7621_spi_write_half_duplex(struct mt7621_spi *rs,
int tx_len, const u8 *buf) int tx_len, const u8 *buf)
{ {
int val = 0;
int len = rs->pending_write; int len = rs->pending_write;
int val = 0;
if (len & 3) { if (len & 3) {
val = mt7621_spi_read(rs, MT7621_SPI_OPCODE + (len & ~3)); val = mt7621_spi_read(rs, MT7621_SPI_OPCODE + (len & ~3));
...@@ -238,6 +234,7 @@ static void mt7621_spi_write_half_duplex(struct mt7621_spi *rs, ...@@ -238,6 +234,7 @@ static void mt7621_spi_write_half_duplex(struct mt7621_spi *rs,
} }
tx_len -= 1; tx_len -= 1;
} }
if (len & 3) { if (len & 3) {
if (len < 4) { if (len < 4) {
val = swab32(val); val = swab32(val);
...@@ -245,13 +242,14 @@ static void mt7621_spi_write_half_duplex(struct mt7621_spi *rs, ...@@ -245,13 +242,14 @@ static void mt7621_spi_write_half_duplex(struct mt7621_spi *rs,
} }
mt7621_spi_write(rs, MT7621_SPI_OPCODE + (len & ~3), val); mt7621_spi_write(rs, MT7621_SPI_OPCODE + (len & ~3), val);
} }
rs->pending_write = len; rs->pending_write = len;
} }
static int mt7621_spi_transfer_one_message(struct spi_master *master, static int mt7621_spi_transfer_one_message(struct spi_controller *master,
struct spi_message *m) struct spi_message *m)
{ {
struct mt7621_spi *rs = spi_master_get_devdata(master); struct mt7621_spi *rs = spi_controller_get_devdata(master);
struct spi_device *spi = m->spi; struct spi_device *spi = m->spi;
unsigned int speed = spi->max_speed_hz; unsigned int speed = spi->max_speed_hz;
struct spi_transfer *t = NULL; struct spi_transfer *t = NULL;
...@@ -268,11 +266,14 @@ static int mt7621_spi_transfer_one_message(struct spi_master *master, ...@@ -268,11 +266,14 @@ static int mt7621_spi_transfer_one_message(struct spi_master *master,
goto msg_done; goto msg_done;
} }
/* Assert CS */
mt7621_spi_set_cs(spi, 1); mt7621_spi_set_cs(spi, 1);
m->actual_length = 0; m->actual_length = 0;
list_for_each_entry(t, &m->transfers, transfer_list) { list_for_each_entry(t, &m->transfers, transfer_list) {
if ((t->rx_buf) && (t->tx_buf)) { if ((t->rx_buf) && (t->tx_buf)) {
/* This controller will shift some extra data out /*
* This controller will shift some extra data out
* of spi_opcode if (mosi_bit_cnt > 0) && * of spi_opcode if (mosi_bit_cnt > 0) &&
* (cmd_bit_cnt == 0). So the claimed full-duplex * (cmd_bit_cnt == 0). So the claimed full-duplex
* support is broken since we have no way to read * support is broken since we have no way to read
...@@ -287,8 +288,9 @@ static int mt7621_spi_transfer_one_message(struct spi_master *master, ...@@ -287,8 +288,9 @@ static int mt7621_spi_transfer_one_message(struct spi_master *master,
} }
m->actual_length += t->len; m->actual_length += t->len;
} }
mt7621_spi_flush(rs);
/* Flush data and deassert CS */
mt7621_spi_flush(rs);
mt7621_spi_set_cs(spi, 0); mt7621_spi_set_cs(spi, 0);
msg_done: msg_done:
...@@ -303,7 +305,7 @@ static int mt7621_spi_setup(struct spi_device *spi) ...@@ -303,7 +305,7 @@ static int mt7621_spi_setup(struct spi_device *spi)
struct mt7621_spi *rs = spidev_to_mt7621_spi(spi); struct mt7621_spi *rs = spidev_to_mt7621_spi(spi);
if ((spi->max_speed_hz == 0) || if ((spi->max_speed_hz == 0) ||
(spi->max_speed_hz > (rs->sys_freq / 2))) (spi->max_speed_hz > (rs->sys_freq / 2)))
spi->max_speed_hz = (rs->sys_freq / 2); spi->max_speed_hz = (rs->sys_freq / 2);
if (spi->max_speed_hz < (rs->sys_freq / 4097)) { if (spi->max_speed_hz < (rs->sys_freq / 4097)) {
...@@ -324,7 +326,7 @@ MODULE_DEVICE_TABLE(of, mt7621_spi_match); ...@@ -324,7 +326,7 @@ MODULE_DEVICE_TABLE(of, mt7621_spi_match);
static int mt7621_spi_probe(struct platform_device *pdev) static int mt7621_spi_probe(struct platform_device *pdev)
{ {
const struct of_device_id *match; const struct of_device_id *match;
struct spi_master *master; struct spi_controller *master;
struct mt7621_spi *rs; struct mt7621_spi *rs;
void __iomem *base; void __iomem *base;
struct resource *r; struct resource *r;
...@@ -361,7 +363,7 @@ static int mt7621_spi_probe(struct platform_device *pdev) ...@@ -361,7 +363,7 @@ static int mt7621_spi_probe(struct platform_device *pdev)
} }
master->mode_bits = SPI_LSB_FIRST; master->mode_bits = SPI_LSB_FIRST;
master->flags = SPI_CONTROLLER_HALF_DUPLEX;
master->setup = mt7621_spi_setup; master->setup = mt7621_spi_setup;
master->transfer_one_message = mt7621_spi_transfer_one_message; master->transfer_one_message = mt7621_spi_transfer_one_message;
master->bits_per_word_mask = SPI_BPW_MASK(8); master->bits_per_word_mask = SPI_BPW_MASK(8);
...@@ -370,7 +372,7 @@ static int mt7621_spi_probe(struct platform_device *pdev) ...@@ -370,7 +372,7 @@ static int mt7621_spi_probe(struct platform_device *pdev)
dev_set_drvdata(&pdev->dev, master); dev_set_drvdata(&pdev->dev, master);
rs = spi_master_get_devdata(master); rs = spi_controller_get_devdata(master);
rs->base = base; rs->base = base;
rs->clk = clk; rs->clk = clk;
rs->master = master; rs->master = master;
...@@ -385,21 +387,18 @@ static int mt7621_spi_probe(struct platform_device *pdev) ...@@ -385,21 +387,18 @@ static int mt7621_spi_probe(struct platform_device *pdev)
return ret; return ret;
} }
mt7621_spi_reset(rs); return devm_spi_register_controller(&pdev->dev, master);
return spi_register_master(master);
} }
static int mt7621_spi_remove(struct platform_device *pdev) static int mt7621_spi_remove(struct platform_device *pdev)
{ {
struct spi_master *master; struct spi_controller *master;
struct mt7621_spi *rs; struct mt7621_spi *rs;
master = dev_get_drvdata(&pdev->dev); master = dev_get_drvdata(&pdev->dev);
rs = spi_master_get_devdata(master); rs = spi_controller_get_devdata(master);
clk_disable(rs->clk); clk_disable_unprepare(rs->clk);
spi_unregister_master(master);
return 0; return 0;
} }
......
...@@ -492,8 +492,7 @@ static int mxic_spi_transfer_one(struct spi_master *master, ...@@ -492,8 +492,7 @@ static int mxic_spi_transfer_one(struct spi_master *master,
static int __maybe_unused mxic_spi_runtime_suspend(struct device *dev) static int __maybe_unused mxic_spi_runtime_suspend(struct device *dev)
{ {
struct platform_device *pdev = to_platform_device(dev); struct spi_master *master = dev_get_drvdata(dev);
struct spi_master *master = platform_get_drvdata(pdev);
struct mxic_spi *mxic = spi_master_get_devdata(master); struct mxic_spi *mxic = spi_master_get_devdata(master);
mxic_spi_clk_disable(mxic); mxic_spi_clk_disable(mxic);
...@@ -504,8 +503,7 @@ static int __maybe_unused mxic_spi_runtime_suspend(struct device *dev) ...@@ -504,8 +503,7 @@ static int __maybe_unused mxic_spi_runtime_suspend(struct device *dev)
static int __maybe_unused mxic_spi_runtime_resume(struct device *dev) static int __maybe_unused mxic_spi_runtime_resume(struct device *dev)
{ {
struct platform_device *pdev = to_platform_device(dev); struct spi_master *master = dev_get_drvdata(dev);
struct spi_master *master = platform_get_drvdata(pdev);
struct mxic_spi *mxic = spi_master_get_devdata(master); struct mxic_spi *mxic = spi_master_get_devdata(master);
int ret; int ret;
......
...@@ -470,6 +470,8 @@ orion_spi_write_read(struct spi_device *spi, struct spi_transfer *xfer) ...@@ -470,6 +470,8 @@ orion_spi_write_read(struct spi_device *spi, struct spi_transfer *xfer)
if (orion_spi_write_read_8bit(spi, &tx, &rx) < 0) if (orion_spi_write_read_8bit(spi, &tx, &rx) < 0)
goto out; goto out;
count--; count--;
if (xfer->word_delay_usecs)
udelay(xfer->word_delay_usecs);
} while (count); } while (count);
} else if (word_len == 16) { } else if (word_len == 16) {
const u16 *tx = xfer->tx_buf; const u16 *tx = xfer->tx_buf;
...@@ -479,6 +481,8 @@ orion_spi_write_read(struct spi_device *spi, struct spi_transfer *xfer) ...@@ -479,6 +481,8 @@ orion_spi_write_read(struct spi_device *spi, struct spi_transfer *xfer)
if (orion_spi_write_read_16bit(spi, &tx, &rx) < 0) if (orion_spi_write_read_16bit(spi, &tx, &rx) < 0)
goto out; goto out;
count -= 2; count -= 2;
if (xfer->word_delay_usecs)
udelay(xfer->word_delay_usecs);
} while (count); } while (count);
} }
......
...@@ -559,7 +559,7 @@ static int pic32_spi_one_transfer(struct spi_master *master, ...@@ -559,7 +559,7 @@ static int pic32_spi_one_transfer(struct spi_master *master,
dev_err(&spi->dev, "wait error/timedout\n"); dev_err(&spi->dev, "wait error/timedout\n");
if (dma_issued) { if (dma_issued) {
dmaengine_terminate_all(master->dma_rx); dmaengine_terminate_all(master->dma_rx);
dmaengine_terminate_all(master->dma_rx); dmaengine_terminate_all(master->dma_tx);
} }
ret = -ETIMEDOUT; ret = -ETIMEDOUT;
} else { } else {
......
...@@ -239,13 +239,15 @@ int pxa2xx_spi_set_dma_burst_and_threshold(struct chip_data *chip, ...@@ -239,13 +239,15 @@ int pxa2xx_spi_set_dma_burst_and_threshold(struct chip_data *chip,
u32 *threshold) u32 *threshold)
{ {
struct pxa2xx_spi_chip *chip_info = spi->controller_data; struct pxa2xx_spi_chip *chip_info = spi->controller_data;
struct driver_data *drv_data = spi_controller_get_devdata(spi->controller);
u32 dma_burst_size = drv_data->controller_info->dma_burst_size;
/* /*
* If the DMA burst size is given in chip_info we use that, * If the DMA burst size is given in chip_info we use that,
* otherwise we use the default. Also we use the default FIFO * otherwise we use the default. Also we use the default FIFO
* thresholds for now. * thresholds for now.
*/ */
*burst_code = chip_info ? chip_info->dma_burst_size : 1; *burst_code = chip_info ? chip_info->dma_burst_size : dma_burst_size;
*threshold = SSCR1_RxTresh(RX_THRESH_DFLT) *threshold = SSCR1_RxTresh(RX_THRESH_DFLT)
| SSCR1_TxTresh(TX_THRESH_DFLT); | SSCR1_TxTresh(TX_THRESH_DFLT);
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
*/ */
#include <linux/clk-provider.h> #include <linux/clk-provider.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of_device.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/spi/pxa2xx_spi.h> #include <linux/spi/pxa2xx_spi.h>
...@@ -35,6 +34,8 @@ struct pxa_spi_info { ...@@ -35,6 +34,8 @@ struct pxa_spi_info {
void *tx_param; void *tx_param;
void *rx_param; void *rx_param;
int dma_burst_size;
int (*setup)(struct pci_dev *pdev, struct pxa_spi_info *c); int (*setup)(struct pci_dev *pdev, struct pxa_spi_info *c);
}; };
...@@ -133,6 +134,7 @@ static int mrfld_spi_setup(struct pci_dev *dev, struct pxa_spi_info *c) ...@@ -133,6 +134,7 @@ static int mrfld_spi_setup(struct pci_dev *dev, struct pxa_spi_info *c)
rx->dma_dev = &dma_dev->dev; rx->dma_dev = &dma_dev->dev;
c->dma_filter = lpss_dma_filter; c->dma_filter = lpss_dma_filter;
c->dma_burst_size = 8;
return 0; return 0;
} }
...@@ -223,6 +225,7 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev, ...@@ -223,6 +225,7 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev,
spi_pdata.tx_param = c->tx_param; spi_pdata.tx_param = c->tx_param;
spi_pdata.rx_param = c->rx_param; spi_pdata.rx_param = c->rx_param;
spi_pdata.enable_dma = c->rx_param && c->tx_param; spi_pdata.enable_dma = c->rx_param && c->tx_param;
spi_pdata.dma_burst_size = c->dma_burst_size ? c->dma_burst_size : 1;
ssp = &spi_pdata.ssp; ssp = &spi_pdata.ssp;
ssp->phys_base = pci_resource_start(dev, 0); ssp->phys_base = pci_resource_start(dev, 0);
......
...@@ -884,10 +884,14 @@ static unsigned int ssp_get_clk_div(struct driver_data *drv_data, int rate) ...@@ -884,10 +884,14 @@ static unsigned int ssp_get_clk_div(struct driver_data *drv_data, int rate)
rate = min_t(int, ssp_clk, rate); rate = min_t(int, ssp_clk, rate);
/*
* Calculate the divisor for the SCR (Serial Clock Rate), avoiding
* that the SSP transmission rate can be greater than the device rate
*/
if (ssp->type == PXA25x_SSP || ssp->type == CE4100_SSP) if (ssp->type == PXA25x_SSP || ssp->type == CE4100_SSP)
return (ssp_clk / (2 * rate) - 1) & 0xff; return (DIV_ROUND_UP(ssp_clk, 2 * rate) - 1) & 0xff;
else else
return (ssp_clk / rate - 1) & 0xfff; return (DIV_ROUND_UP(ssp_clk, rate) - 1) & 0xfff;
} }
static unsigned int pxa2xx_ssp_get_clk_div(struct driver_data *drv_data, static unsigned int pxa2xx_ssp_get_clk_div(struct driver_data *drv_data,
...@@ -925,7 +929,7 @@ static int pxa2xx_spi_transfer_one(struct spi_controller *controller, ...@@ -925,7 +929,7 @@ static int pxa2xx_spi_transfer_one(struct spi_controller *controller,
{ {
struct driver_data *drv_data = spi_controller_get_devdata(controller); struct driver_data *drv_data = spi_controller_get_devdata(controller);
struct spi_message *message = controller->cur_msg; struct spi_message *message = controller->cur_msg;
struct chip_data *chip = spi_get_ctldata(message->spi); struct chip_data *chip = spi_get_ctldata(spi);
u32 dma_thresh = chip->dma_threshold; u32 dma_thresh = chip->dma_threshold;
u32 dma_burst = chip->dma_burst_size; u32 dma_burst = chip->dma_burst_size;
u32 change_mask = pxa2xx_spi_get_ssrc1_change_mask(drv_data); u32 change_mask = pxa2xx_spi_get_ssrc1_change_mask(drv_data);
...@@ -943,21 +947,21 @@ static int pxa2xx_spi_transfer_one(struct spi_controller *controller, ...@@ -943,21 +947,21 @@ static int pxa2xx_spi_transfer_one(struct spi_controller *controller,
/* reject already-mapped transfers; PIO won't always work */ /* reject already-mapped transfers; PIO won't always work */
if (message->is_dma_mapped if (message->is_dma_mapped
|| transfer->rx_dma || transfer->tx_dma) { || transfer->rx_dma || transfer->tx_dma) {
dev_err(&drv_data->pdev->dev, dev_err(&spi->dev,
"Mapped transfer length of %u is greater than %d\n", "Mapped transfer length of %u is greater than %d\n",
transfer->len, MAX_DMA_LEN); transfer->len, MAX_DMA_LEN);
return -EINVAL; return -EINVAL;
} }
/* warn ... we force this to PIO mode */ /* warn ... we force this to PIO mode */
dev_warn_ratelimited(&message->spi->dev, dev_warn_ratelimited(&spi->dev,
"DMA disabled for transfer length %ld greater than %d\n", "DMA disabled for transfer length %ld greater than %d\n",
(long)transfer->len, MAX_DMA_LEN); (long)transfer->len, MAX_DMA_LEN);
} }
/* Setup the transfer state based on the type of transfer */ /* Setup the transfer state based on the type of transfer */
if (pxa2xx_spi_flush(drv_data) == 0) { if (pxa2xx_spi_flush(drv_data) == 0) {
dev_err(&drv_data->pdev->dev, "Flush failed\n"); dev_err(&spi->dev, "Flush failed\n");
return -EIO; return -EIO;
} }
drv_data->n_bytes = chip->n_bytes; drv_data->n_bytes = chip->n_bytes;
...@@ -999,15 +1003,15 @@ static int pxa2xx_spi_transfer_one(struct spi_controller *controller, ...@@ -999,15 +1003,15 @@ static int pxa2xx_spi_transfer_one(struct spi_controller *controller,
*/ */
if (chip->enable_dma) { if (chip->enable_dma) {
if (pxa2xx_spi_set_dma_burst_and_threshold(chip, if (pxa2xx_spi_set_dma_burst_and_threshold(chip,
message->spi, spi,
bits, &dma_burst, bits, &dma_burst,
&dma_thresh)) &dma_thresh))
dev_warn_ratelimited(&message->spi->dev, dev_warn_ratelimited(&spi->dev,
"DMA burst size reduced to match bits_per_word\n"); "DMA burst size reduced to match bits_per_word\n");
} }
dma_mapped = controller->can_dma && dma_mapped = controller->can_dma &&
controller->can_dma(controller, message->spi, transfer) && controller->can_dma(controller, spi, transfer) &&
controller->cur_msg_mapped; controller->cur_msg_mapped;
if (dma_mapped) { if (dma_mapped) {
...@@ -1035,12 +1039,12 @@ static int pxa2xx_spi_transfer_one(struct spi_controller *controller, ...@@ -1035,12 +1039,12 @@ static int pxa2xx_spi_transfer_one(struct spi_controller *controller,
/* NOTE: PXA25x_SSP _could_ use external clocking ... */ /* NOTE: PXA25x_SSP _could_ use external clocking ... */
cr0 = pxa2xx_configure_sscr0(drv_data, clk_div, bits); cr0 = pxa2xx_configure_sscr0(drv_data, clk_div, bits);
if (!pxa25x_ssp_comp(drv_data)) if (!pxa25x_ssp_comp(drv_data))
dev_dbg(&message->spi->dev, "%u Hz actual, %s\n", dev_dbg(&spi->dev, "%u Hz actual, %s\n",
controller->max_speed_hz controller->max_speed_hz
/ (1 + ((cr0 & SSCR0_SCR(0xfff)) >> 8)), / (1 + ((cr0 & SSCR0_SCR(0xfff)) >> 8)),
dma_mapped ? "DMA" : "PIO"); dma_mapped ? "DMA" : "PIO");
else else
dev_dbg(&message->spi->dev, "%u Hz actual, %s\n", dev_dbg(&spi->dev, "%u Hz actual, %s\n",
controller->max_speed_hz / 2 controller->max_speed_hz / 2
/ (1 + ((cr0 & SSCR0_SCR(0x0ff)) >> 8)), / (1 + ((cr0 & SSCR0_SCR(0x0ff)) >> 8)),
dma_mapped ? "DMA" : "PIO"); dma_mapped ? "DMA" : "PIO");
...@@ -1333,6 +1337,9 @@ static int setup(struct spi_device *spi) ...@@ -1333,6 +1337,9 @@ static int setup(struct spi_device *spi)
dev_warn(&spi->dev, dev_warn(&spi->dev,
"in setup: DMA burst size reduced to match bits_per_word\n"); "in setup: DMA burst size reduced to match bits_per_word\n");
} }
dev_dbg(&spi->dev,
"in setup: DMA burst size set to %u\n",
chip->dma_burst_size);
} }
switch (drv_data->ssp_type) { switch (drv_data->ssp_type) {
...@@ -1451,6 +1458,10 @@ static const struct pci_device_id pxa2xx_spi_pci_compound_match[] = { ...@@ -1451,6 +1458,10 @@ static const struct pci_device_id pxa2xx_spi_pci_compound_match[] = {
{ PCI_VDEVICE(INTEL, 0xa32a), LPSS_CNL_SSP }, { PCI_VDEVICE(INTEL, 0xa32a), LPSS_CNL_SSP },
{ PCI_VDEVICE(INTEL, 0xa32b), LPSS_CNL_SSP }, { PCI_VDEVICE(INTEL, 0xa32b), LPSS_CNL_SSP },
{ PCI_VDEVICE(INTEL, 0xa37b), LPSS_CNL_SSP }, { PCI_VDEVICE(INTEL, 0xa37b), LPSS_CNL_SSP },
/* CML-LP */
{ PCI_VDEVICE(INTEL, 0x02aa), LPSS_CNL_SSP },
{ PCI_VDEVICE(INTEL, 0x02ab), LPSS_CNL_SSP },
{ PCI_VDEVICE(INTEL, 0x02fb), LPSS_CNL_SSP },
{ }, { },
}; };
...@@ -1564,6 +1575,7 @@ pxa2xx_spi_init_pdata(struct platform_device *pdev) ...@@ -1564,6 +1575,7 @@ pxa2xx_spi_init_pdata(struct platform_device *pdev)
pdata->is_slave = of_property_read_bool(pdev->dev.of_node, "spi-slave"); pdata->is_slave = of_property_read_bool(pdev->dev.of_node, "spi-slave");
pdata->num_chipselect = 1; pdata->num_chipselect = 1;
pdata->enable_dma = true; pdata->enable_dma = true;
pdata->dma_burst_size = 1;
return pdata; return pdata;
} }
...@@ -1692,7 +1704,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev) ...@@ -1692,7 +1704,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
if (platform_info->enable_dma) { if (platform_info->enable_dma) {
status = pxa2xx_spi_dma_setup(drv_data); status = pxa2xx_spi_dma_setup(drv_data);
if (status) { if (status) {
dev_dbg(dev, "no DMA channels available, using PIO\n"); dev_warn(dev, "no DMA channels available, using PIO\n");
platform_info->enable_dma = false; platform_info->enable_dma = false;
} else { } else {
controller->can_dma = pxa2xx_spi_can_dma; controller->can_dma = pxa2xx_spi_can_dma;
...@@ -1953,3 +1965,5 @@ static void __exit pxa2xx_spi_exit(void) ...@@ -1953,3 +1965,5 @@ static void __exit pxa2xx_spi_exit(void)
platform_driver_unregister(&driver); platform_driver_unregister(&driver);
} }
module_exit(pxa2xx_spi_exit); module_exit(pxa2xx_spi_exit);
MODULE_SOFTDEP("pre: dw_dmac");
...@@ -271,7 +271,8 @@ static int rspi_set_config_register(struct rspi_data *rspi, int access_size) ...@@ -271,7 +271,8 @@ static int rspi_set_config_register(struct rspi_data *rspi, int access_size)
/* Sets parity, interrupt mask */ /* Sets parity, interrupt mask */
rspi_write8(rspi, 0x00, RSPI_SPCR2); rspi_write8(rspi, 0x00, RSPI_SPCR2);
/* Sets SPCMD */ /* Resets sequencer */
rspi_write8(rspi, 0, RSPI_SPSCR);
rspi->spcmd |= SPCMD_SPB_8_TO_16(access_size); rspi->spcmd |= SPCMD_SPB_8_TO_16(access_size);
rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0); rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0);
...@@ -315,7 +316,8 @@ static int rspi_rz_set_config_register(struct rspi_data *rspi, int access_size) ...@@ -315,7 +316,8 @@ static int rspi_rz_set_config_register(struct rspi_data *rspi, int access_size)
rspi_write8(rspi, 0x00, RSPI_SSLND); rspi_write8(rspi, 0x00, RSPI_SSLND);
rspi_write8(rspi, 0x00, RSPI_SPND); rspi_write8(rspi, 0x00, RSPI_SPND);
/* Sets SPCMD */ /* Resets sequencer */
rspi_write8(rspi, 0, RSPI_SPSCR);
rspi->spcmd |= SPCMD_SPB_8_TO_16(access_size); rspi->spcmd |= SPCMD_SPB_8_TO_16(access_size);
rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0); rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0);
...@@ -366,7 +368,8 @@ static int qspi_set_config_register(struct rspi_data *rspi, int access_size) ...@@ -366,7 +368,8 @@ static int qspi_set_config_register(struct rspi_data *rspi, int access_size)
/* Sets buffer to allow normal operation */ /* Sets buffer to allow normal operation */
rspi_write8(rspi, 0x00, QSPI_SPBFCR); rspi_write8(rspi, 0x00, QSPI_SPBFCR);
/* Sets SPCMD */ /* Resets sequencer */
rspi_write8(rspi, 0, RSPI_SPSCR);
rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0); rspi_write16(rspi, rspi->spcmd, RSPI_SPCMD0);
/* Sets RSPI mode */ /* Sets RSPI mode */
...@@ -736,27 +739,22 @@ static int qspi_trigger_transfer_out_in(struct rspi_data *rspi, const u8 *tx, ...@@ -736,27 +739,22 @@ static int qspi_trigger_transfer_out_in(struct rspi_data *rspi, const u8 *tx,
while (len > 0) { while (len > 0) {
n = qspi_set_send_trigger(rspi, len); n = qspi_set_send_trigger(rspi, len);
qspi_set_receive_trigger(rspi, len); qspi_set_receive_trigger(rspi, len);
if (n == QSPI_BUFFER_SIZE) { ret = rspi_wait_for_tx_empty(rspi);
ret = rspi_wait_for_tx_empty(rspi); if (ret < 0) {
if (ret < 0) { dev_err(&rspi->ctlr->dev, "transmit timeout\n");
dev_err(&rspi->ctlr->dev, "transmit timeout\n"); return ret;
return ret; }
} for (i = 0; i < n; i++)
for (i = 0; i < n; i++) rspi_write_data(rspi, *tx++);
rspi_write_data(rspi, *tx++);
ret = rspi_wait_for_rx_full(rspi); ret = rspi_wait_for_rx_full(rspi);
if (ret < 0) { if (ret < 0) {
dev_err(&rspi->ctlr->dev, "receive timeout\n"); dev_err(&rspi->ctlr->dev, "receive timeout\n");
return ret; return ret;
}
for (i = 0; i < n; i++)
*rx++ = rspi_read_data(rspi);
} else {
ret = rspi_pio_transfer(rspi, tx, rx, n);
if (ret < 0)
return ret;
} }
for (i = 0; i < n; i++)
*rx++ = rspi_read_data(rspi);
len -= n; len -= n;
} }
...@@ -793,19 +791,14 @@ static int qspi_transfer_out(struct rspi_data *rspi, struct spi_transfer *xfer) ...@@ -793,19 +791,14 @@ static int qspi_transfer_out(struct rspi_data *rspi, struct spi_transfer *xfer)
while (n > 0) { while (n > 0) {
len = qspi_set_send_trigger(rspi, n); len = qspi_set_send_trigger(rspi, n);
if (len == QSPI_BUFFER_SIZE) { ret = rspi_wait_for_tx_empty(rspi);
ret = rspi_wait_for_tx_empty(rspi); if (ret < 0) {
if (ret < 0) { dev_err(&rspi->ctlr->dev, "transmit timeout\n");
dev_err(&rspi->ctlr->dev, "transmit timeout\n"); return ret;
return ret;
}
for (i = 0; i < len; i++)
rspi_write_data(rspi, *tx++);
} else {
ret = rspi_pio_transfer(rspi, tx, NULL, len);
if (ret < 0)
return ret;
} }
for (i = 0; i < len; i++)
rspi_write_data(rspi, *tx++);
n -= len; n -= len;
} }
...@@ -830,19 +823,14 @@ static int qspi_transfer_in(struct rspi_data *rspi, struct spi_transfer *xfer) ...@@ -830,19 +823,14 @@ static int qspi_transfer_in(struct rspi_data *rspi, struct spi_transfer *xfer)
while (n > 0) { while (n > 0) {
len = qspi_set_receive_trigger(rspi, n); len = qspi_set_receive_trigger(rspi, n);
if (len == QSPI_BUFFER_SIZE) { ret = rspi_wait_for_rx_full(rspi);
ret = rspi_wait_for_rx_full(rspi); if (ret < 0) {
if (ret < 0) { dev_err(&rspi->ctlr->dev, "receive timeout\n");
dev_err(&rspi->ctlr->dev, "receive timeout\n"); return ret;
return ret;
}
for (i = 0; i < len; i++)
*rx++ = rspi_read_data(rspi);
} else {
ret = rspi_pio_transfer(rspi, NULL, rx, len);
if (ret < 0)
return ret;
} }
for (i = 0; i < len; i++)
*rx++ = rspi_read_data(rspi);
n -= len; n -= len;
} }
...@@ -868,28 +856,6 @@ static int qspi_transfer_one(struct spi_controller *ctlr, ...@@ -868,28 +856,6 @@ static int qspi_transfer_one(struct spi_controller *ctlr,
} }
} }
static int rspi_setup(struct spi_device *spi)
{
struct rspi_data *rspi = spi_controller_get_devdata(spi->controller);
rspi->max_speed_hz = spi->max_speed_hz;
rspi->spcmd = SPCMD_SSLKP;
if (spi->mode & SPI_CPOL)
rspi->spcmd |= SPCMD_CPOL;
if (spi->mode & SPI_CPHA)
rspi->spcmd |= SPCMD_CPHA;
/* CMOS output mode and MOSI signal from previous transfer */
rspi->sppcr = 0;
if (spi->mode & SPI_LOOP)
rspi->sppcr |= SPPCR_SPLP;
set_config_register(rspi, 8);
return 0;
}
static u16 qspi_transfer_mode(const struct spi_transfer *xfer) static u16 qspi_transfer_mode(const struct spi_transfer *xfer)
{ {
if (xfer->tx_buf) if (xfer->tx_buf)
...@@ -959,8 +925,24 @@ static int rspi_prepare_message(struct spi_controller *ctlr, ...@@ -959,8 +925,24 @@ static int rspi_prepare_message(struct spi_controller *ctlr,
struct spi_message *msg) struct spi_message *msg)
{ {
struct rspi_data *rspi = spi_controller_get_devdata(ctlr); struct rspi_data *rspi = spi_controller_get_devdata(ctlr);
struct spi_device *spi = msg->spi;
int ret; int ret;
rspi->max_speed_hz = spi->max_speed_hz;
rspi->spcmd = SPCMD_SSLKP;
if (spi->mode & SPI_CPOL)
rspi->spcmd |= SPCMD_CPOL;
if (spi->mode & SPI_CPHA)
rspi->spcmd |= SPCMD_CPHA;
/* CMOS output mode and MOSI signal from previous transfer */
rspi->sppcr = 0;
if (spi->mode & SPI_LOOP)
rspi->sppcr |= SPPCR_SPLP;
set_config_register(rspi, 8);
if (msg->spi->mode & if (msg->spi->mode &
(SPI_TX_DUAL | SPI_TX_QUAD | SPI_RX_DUAL | SPI_RX_QUAD)) { (SPI_TX_DUAL | SPI_TX_QUAD | SPI_RX_DUAL | SPI_RX_QUAD)) {
/* Setup sequencer for messages with multiple transfer modes */ /* Setup sequencer for messages with multiple transfer modes */
...@@ -1267,7 +1249,6 @@ static int rspi_probe(struct platform_device *pdev) ...@@ -1267,7 +1249,6 @@ static int rspi_probe(struct platform_device *pdev)
init_waitqueue_head(&rspi->wait); init_waitqueue_head(&rspi->wait);
ctlr->bus_num = pdev->id; ctlr->bus_num = pdev->id;
ctlr->setup = rspi_setup;
ctlr->auto_runtime_pm = true; ctlr->auto_runtime_pm = true;
ctlr->transfer_one = ops->transfer_one; ctlr->transfer_one = ops->transfer_one;
ctlr->prepare_message = rspi_prepare_message; ctlr->prepare_message = rspi_prepare_message;
......
This diff is collapsed.
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
*/ */
#include <linux/bitfield.h> #include <linux/bitfield.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/iopoll.h> #include <linux/iopoll.h>
...@@ -13,6 +15,7 @@ ...@@ -13,6 +15,7 @@
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/reset.h> #include <linux/reset.h>
#include <linux/sizes.h> #include <linux/sizes.h>
...@@ -76,7 +79,6 @@ ...@@ -76,7 +79,6 @@
#define QSPI_PSMAR 0x28 #define QSPI_PSMAR 0x28
#define QSPI_PIR 0x2c #define QSPI_PIR 0x2c
#define QSPI_LPTR 0x30 #define QSPI_LPTR 0x30
#define LPTR_DFT_TIMEOUT 0x10
#define STM32_QSPI_MAX_MMAP_SZ SZ_256M #define STM32_QSPI_MAX_MMAP_SZ SZ_256M
#define STM32_QSPI_MAX_NORCHIP 2 #define STM32_QSPI_MAX_NORCHIP 2
...@@ -84,6 +86,7 @@ ...@@ -84,6 +86,7 @@
#define STM32_FIFO_TIMEOUT_US 30000 #define STM32_FIFO_TIMEOUT_US 30000
#define STM32_BUSY_TIMEOUT_US 100000 #define STM32_BUSY_TIMEOUT_US 100000
#define STM32_ABT_TIMEOUT_US 100000 #define STM32_ABT_TIMEOUT_US 100000
#define STM32_COMP_TIMEOUT_MS 1000
struct stm32_qspi_flash { struct stm32_qspi_flash {
struct stm32_qspi *qspi; struct stm32_qspi *qspi;
...@@ -93,6 +96,8 @@ struct stm32_qspi_flash { ...@@ -93,6 +96,8 @@ struct stm32_qspi_flash {
struct stm32_qspi { struct stm32_qspi {
struct device *dev; struct device *dev;
struct spi_controller *ctrl;
phys_addr_t phys_base;
void __iomem *io_base; void __iomem *io_base;
void __iomem *mm_base; void __iomem *mm_base;
resource_size_t mm_size; resource_size_t mm_size;
...@@ -102,6 +107,13 @@ struct stm32_qspi { ...@@ -102,6 +107,13 @@ struct stm32_qspi {
struct completion data_completion; struct completion data_completion;
u32 fmode; u32 fmode;
struct dma_chan *dma_chtx;
struct dma_chan *dma_chrx;
struct completion dma_completion;
u32 cr_reg;
u32 dcr_reg;
/* /*
* to protect device configuration, could be different between * to protect device configuration, could be different between
* 2 flash access (bk1, bk2) * 2 flash access (bk1, bk2)
...@@ -177,6 +189,81 @@ static int stm32_qspi_tx_mm(struct stm32_qspi *qspi, ...@@ -177,6 +189,81 @@ static int stm32_qspi_tx_mm(struct stm32_qspi *qspi,
return 0; return 0;
} }
static void stm32_qspi_dma_callback(void *arg)
{
struct completion *dma_completion = arg;
complete(dma_completion);
}
static int stm32_qspi_tx_dma(struct stm32_qspi *qspi,
const struct spi_mem_op *op)
{
struct dma_async_tx_descriptor *desc;
enum dma_transfer_direction dma_dir;
struct dma_chan *dma_ch;
struct sg_table sgt;
dma_cookie_t cookie;
u32 cr, t_out;
int err;
if (op->data.dir == SPI_MEM_DATA_IN) {
dma_dir = DMA_DEV_TO_MEM;
dma_ch = qspi->dma_chrx;
} else {
dma_dir = DMA_MEM_TO_DEV;
dma_ch = qspi->dma_chtx;
}
/*
* spi_map_buf return -EINVAL if the buffer is not DMA-able
* (DMA-able: in vmalloc | kmap | virt_addr_valid)
*/
err = spi_controller_dma_map_mem_op_data(qspi->ctrl, op, &sgt);
if (err)
return err;
desc = dmaengine_prep_slave_sg(dma_ch, sgt.sgl, sgt.nents,
dma_dir, DMA_PREP_INTERRUPT);
if (!desc) {
err = -ENOMEM;
goto out_unmap;
}
cr = readl_relaxed(qspi->io_base + QSPI_CR);
reinit_completion(&qspi->dma_completion);
desc->callback = stm32_qspi_dma_callback;
desc->callback_param = &qspi->dma_completion;
cookie = dmaengine_submit(desc);
err = dma_submit_error(cookie);
if (err)
goto out;
dma_async_issue_pending(dma_ch);
writel_relaxed(cr | CR_DMAEN, qspi->io_base + QSPI_CR);
t_out = sgt.nents * STM32_COMP_TIMEOUT_MS;
if (!wait_for_completion_interruptible_timeout(&qspi->dma_completion,
msecs_to_jiffies(t_out)))
err = -ETIMEDOUT;
if (dma_async_is_tx_complete(dma_ch, cookie,
NULL, NULL) != DMA_COMPLETE)
err = -ETIMEDOUT;
if (err)
dmaengine_terminate_all(dma_ch);
out:
writel_relaxed(cr & ~CR_DMAEN, qspi->io_base + QSPI_CR);
out_unmap:
spi_controller_dma_unmap_mem_op_data(qspi->ctrl, op, &sgt);
return err;
}
static int stm32_qspi_tx(struct stm32_qspi *qspi, const struct spi_mem_op *op) static int stm32_qspi_tx(struct stm32_qspi *qspi, const struct spi_mem_op *op)
{ {
if (!op->data.nbytes) if (!op->data.nbytes)
...@@ -184,6 +271,10 @@ static int stm32_qspi_tx(struct stm32_qspi *qspi, const struct spi_mem_op *op) ...@@ -184,6 +271,10 @@ static int stm32_qspi_tx(struct stm32_qspi *qspi, const struct spi_mem_op *op)
if (qspi->fmode == CCR_FMODE_MM) if (qspi->fmode == CCR_FMODE_MM)
return stm32_qspi_tx_mm(qspi, op); return stm32_qspi_tx_mm(qspi, op);
else if ((op->data.dir == SPI_MEM_DATA_IN && qspi->dma_chrx) ||
(op->data.dir == SPI_MEM_DATA_OUT && qspi->dma_chtx))
if (!stm32_qspi_tx_dma(qspi, op))
return 0;
return stm32_qspi_tx_poll(qspi, op); return stm32_qspi_tx_poll(qspi, op);
} }
...@@ -214,7 +305,7 @@ static int stm32_qspi_wait_cmd(struct stm32_qspi *qspi, ...@@ -214,7 +305,7 @@ static int stm32_qspi_wait_cmd(struct stm32_qspi *qspi,
writel_relaxed(cr | CR_TCIE | CR_TEIE, qspi->io_base + QSPI_CR); writel_relaxed(cr | CR_TCIE | CR_TEIE, qspi->io_base + QSPI_CR);
if (!wait_for_completion_interruptible_timeout(&qspi->data_completion, if (!wait_for_completion_interruptible_timeout(&qspi->data_completion,
msecs_to_jiffies(1000))) { msecs_to_jiffies(STM32_COMP_TIMEOUT_MS))) {
err = -ETIMEDOUT; err = -ETIMEDOUT;
} else { } else {
sr = readl_relaxed(qspi->io_base + QSPI_SR); sr = readl_relaxed(qspi->io_base + QSPI_SR);
...@@ -356,7 +447,7 @@ static int stm32_qspi_setup(struct spi_device *spi) ...@@ -356,7 +447,7 @@ static int stm32_qspi_setup(struct spi_device *spi)
struct spi_controller *ctrl = spi->master; struct spi_controller *ctrl = spi->master;
struct stm32_qspi *qspi = spi_controller_get_devdata(ctrl); struct stm32_qspi *qspi = spi_controller_get_devdata(ctrl);
struct stm32_qspi_flash *flash; struct stm32_qspi_flash *flash;
u32 cr, presc; u32 presc;
if (ctrl->busy) if (ctrl->busy)
return -EBUSY; return -EBUSY;
...@@ -372,17 +463,60 @@ static int stm32_qspi_setup(struct spi_device *spi) ...@@ -372,17 +463,60 @@ static int stm32_qspi_setup(struct spi_device *spi)
flash->presc = presc; flash->presc = presc;
mutex_lock(&qspi->lock); mutex_lock(&qspi->lock);
writel_relaxed(LPTR_DFT_TIMEOUT, qspi->io_base + QSPI_LPTR); qspi->cr_reg = FIELD_PREP(CR_FTHRES_MASK, 3) | CR_SSHIFT | CR_EN;
cr = FIELD_PREP(CR_FTHRES_MASK, 3) | CR_TCEN | CR_SSHIFT | CR_EN; writel_relaxed(qspi->cr_reg, qspi->io_base + QSPI_CR);
writel_relaxed(cr, qspi->io_base + QSPI_CR);
/* set dcr fsize to max address */ /* set dcr fsize to max address */
writel_relaxed(DCR_FSIZE_MASK, qspi->io_base + QSPI_DCR); qspi->dcr_reg = DCR_FSIZE_MASK;
writel_relaxed(qspi->dcr_reg, qspi->io_base + QSPI_DCR);
mutex_unlock(&qspi->lock); mutex_unlock(&qspi->lock);
return 0; return 0;
} }
static void stm32_qspi_dma_setup(struct stm32_qspi *qspi)
{
struct dma_slave_config dma_cfg;
struct device *dev = qspi->dev;
memset(&dma_cfg, 0, sizeof(dma_cfg));
dma_cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
dma_cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
dma_cfg.src_addr = qspi->phys_base + QSPI_DR;
dma_cfg.dst_addr = qspi->phys_base + QSPI_DR;
dma_cfg.src_maxburst = 4;
dma_cfg.dst_maxburst = 4;
qspi->dma_chrx = dma_request_slave_channel(dev, "rx");
if (qspi->dma_chrx) {
if (dmaengine_slave_config(qspi->dma_chrx, &dma_cfg)) {
dev_err(dev, "dma rx config failed\n");
dma_release_channel(qspi->dma_chrx);
qspi->dma_chrx = NULL;
}
}
qspi->dma_chtx = dma_request_slave_channel(dev, "tx");
if (qspi->dma_chtx) {
if (dmaengine_slave_config(qspi->dma_chtx, &dma_cfg)) {
dev_err(dev, "dma tx config failed\n");
dma_release_channel(qspi->dma_chtx);
qspi->dma_chtx = NULL;
}
}
init_completion(&qspi->dma_completion);
}
static void stm32_qspi_dma_free(struct stm32_qspi *qspi)
{
if (qspi->dma_chtx)
dma_release_channel(qspi->dma_chtx);
if (qspi->dma_chrx)
dma_release_channel(qspi->dma_chrx);
}
/* /*
* no special host constraint, so use default spi_mem_default_supports_op * no special host constraint, so use default spi_mem_default_supports_op
* to check supported mode. * to check supported mode.
...@@ -395,8 +529,10 @@ static void stm32_qspi_release(struct stm32_qspi *qspi) ...@@ -395,8 +529,10 @@ static void stm32_qspi_release(struct stm32_qspi *qspi)
{ {
/* disable qspi */ /* disable qspi */
writel_relaxed(0, qspi->io_base + QSPI_CR); writel_relaxed(0, qspi->io_base + QSPI_CR);
stm32_qspi_dma_free(qspi);
mutex_destroy(&qspi->lock); mutex_destroy(&qspi->lock);
clk_disable_unprepare(qspi->clk); clk_disable_unprepare(qspi->clk);
spi_master_put(qspi->ctrl);
} }
static int stm32_qspi_probe(struct platform_device *pdev) static int stm32_qspi_probe(struct platform_device *pdev)
...@@ -413,43 +549,62 @@ static int stm32_qspi_probe(struct platform_device *pdev) ...@@ -413,43 +549,62 @@ static int stm32_qspi_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
qspi = spi_controller_get_devdata(ctrl); qspi = spi_controller_get_devdata(ctrl);
qspi->ctrl = ctrl;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qspi"); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qspi");
qspi->io_base = devm_ioremap_resource(dev, res); qspi->io_base = devm_ioremap_resource(dev, res);
if (IS_ERR(qspi->io_base)) if (IS_ERR(qspi->io_base)) {
return PTR_ERR(qspi->io_base); ret = PTR_ERR(qspi->io_base);
goto err;
}
qspi->phys_base = res->start;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qspi_mm"); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qspi_mm");
qspi->mm_base = devm_ioremap_resource(dev, res); qspi->mm_base = devm_ioremap_resource(dev, res);
if (IS_ERR(qspi->mm_base)) if (IS_ERR(qspi->mm_base)) {
return PTR_ERR(qspi->mm_base); ret = PTR_ERR(qspi->mm_base);
goto err;
}
qspi->mm_size = resource_size(res); qspi->mm_size = resource_size(res);
if (qspi->mm_size > STM32_QSPI_MAX_MMAP_SZ) if (qspi->mm_size > STM32_QSPI_MAX_MMAP_SZ) {
return -EINVAL; ret = -EINVAL;
goto err;
}
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (irq < 0) {
if (irq != -EPROBE_DEFER)
dev_err(dev, "IRQ error missing or invalid\n");
return irq;
}
ret = devm_request_irq(dev, irq, stm32_qspi_irq, 0, ret = devm_request_irq(dev, irq, stm32_qspi_irq, 0,
dev_name(dev), qspi); dev_name(dev), qspi);
if (ret) { if (ret) {
dev_err(dev, "failed to request irq\n"); dev_err(dev, "failed to request irq\n");
return ret; goto err;
} }
init_completion(&qspi->data_completion); init_completion(&qspi->data_completion);
qspi->clk = devm_clk_get(dev, NULL); qspi->clk = devm_clk_get(dev, NULL);
if (IS_ERR(qspi->clk)) if (IS_ERR(qspi->clk)) {
return PTR_ERR(qspi->clk); ret = PTR_ERR(qspi->clk);
goto err;
}
qspi->clk_rate = clk_get_rate(qspi->clk); qspi->clk_rate = clk_get_rate(qspi->clk);
if (!qspi->clk_rate) if (!qspi->clk_rate) {
return -EINVAL; ret = -EINVAL;
goto err;
}
ret = clk_prepare_enable(qspi->clk); ret = clk_prepare_enable(qspi->clk);
if (ret) { if (ret) {
dev_err(dev, "can not enable the clock\n"); dev_err(dev, "can not enable the clock\n");
return ret; goto err;
} }
rstc = devm_reset_control_get_exclusive(dev, NULL); rstc = devm_reset_control_get_exclusive(dev, NULL);
...@@ -461,6 +616,7 @@ static int stm32_qspi_probe(struct platform_device *pdev) ...@@ -461,6 +616,7 @@ static int stm32_qspi_probe(struct platform_device *pdev)
qspi->dev = dev; qspi->dev = dev;
platform_set_drvdata(pdev, qspi); platform_set_drvdata(pdev, qspi);
stm32_qspi_dma_setup(qspi);
mutex_init(&qspi->lock); mutex_init(&qspi->lock);
ctrl->mode_bits = SPI_RX_DUAL | SPI_RX_QUAD ctrl->mode_bits = SPI_RX_DUAL | SPI_RX_QUAD
...@@ -472,14 +628,11 @@ static int stm32_qspi_probe(struct platform_device *pdev) ...@@ -472,14 +628,11 @@ static int stm32_qspi_probe(struct platform_device *pdev)
ctrl->dev.of_node = dev->of_node; ctrl->dev.of_node = dev->of_node;
ret = devm_spi_register_master(dev, ctrl); ret = devm_spi_register_master(dev, ctrl);
if (ret) if (!ret)
goto err_spi_register; return 0;
return 0;
err_spi_register: err:
stm32_qspi_release(qspi); stm32_qspi_release(qspi);
return ret; return ret;
} }
...@@ -491,6 +644,31 @@ static int stm32_qspi_remove(struct platform_device *pdev) ...@@ -491,6 +644,31 @@ static int stm32_qspi_remove(struct platform_device *pdev)
return 0; return 0;
} }
static int __maybe_unused stm32_qspi_suspend(struct device *dev)
{
struct stm32_qspi *qspi = dev_get_drvdata(dev);
clk_disable_unprepare(qspi->clk);
pinctrl_pm_select_sleep_state(dev);
return 0;
}
static int __maybe_unused stm32_qspi_resume(struct device *dev)
{
struct stm32_qspi *qspi = dev_get_drvdata(dev);
pinctrl_pm_select_default_state(dev);
clk_prepare_enable(qspi->clk);
writel_relaxed(qspi->cr_reg, qspi->io_base + QSPI_CR);
writel_relaxed(qspi->dcr_reg, qspi->io_base + QSPI_DCR);
return 0;
}
static SIMPLE_DEV_PM_OPS(stm32_qspi_pm_ops, stm32_qspi_suspend, stm32_qspi_resume);
static const struct of_device_id stm32_qspi_match[] = { static const struct of_device_id stm32_qspi_match[] = {
{.compatible = "st,stm32f469-qspi"}, {.compatible = "st,stm32f469-qspi"},
{} {}
...@@ -503,6 +681,7 @@ static struct platform_driver stm32_qspi_driver = { ...@@ -503,6 +681,7 @@ static struct platform_driver stm32_qspi_driver = {
.driver = { .driver = {
.name = "stm32-qspi", .name = "stm32-qspi",
.of_match_table = stm32_qspi_match, .of_match_table = stm32_qspi_match,
.pm = &stm32_qspi_pm_ops,
}, },
}; };
module_platform_driver(stm32_qspi_driver); module_platform_driver(stm32_qspi_driver);
......
...@@ -1839,8 +1839,9 @@ static int stm32_spi_probe(struct platform_device *pdev) ...@@ -1839,8 +1839,9 @@ static int stm32_spi_probe(struct platform_device *pdev)
spi->irq = platform_get_irq(pdev, 0); spi->irq = platform_get_irq(pdev, 0);
if (spi->irq <= 0) { if (spi->irq <= 0) {
dev_err(&pdev->dev, "no irq: %d\n", spi->irq); ret = spi->irq;
ret = -ENOENT; if (ret != -EPROBE_DEFER)
dev_err(&pdev->dev, "failed to get irq: %d\n", ret);
goto err_master_put; goto err_master_put;
} }
ret = devm_request_threaded_irq(&pdev->dev, spi->irq, ret = devm_request_threaded_irq(&pdev->dev, spi->irq,
......
This diff is collapsed.
...@@ -717,9 +717,6 @@ static int tegra_slink_start_transfer_one(struct spi_device *spi, ...@@ -717,9 +717,6 @@ static int tegra_slink_start_transfer_one(struct spi_device *spi,
command2 = tspi->command2_reg; command2 = tspi->command2_reg;
command2 &= ~(SLINK_RXEN | SLINK_TXEN); command2 &= ~(SLINK_RXEN | SLINK_TXEN);
tegra_slink_writel(tspi, command, SLINK_COMMAND);
tspi->command_reg = command;
tspi->cur_direction = 0; tspi->cur_direction = 0;
if (t->rx_buf) { if (t->rx_buf) {
command2 |= SLINK_RXEN; command2 |= SLINK_RXEN;
...@@ -729,9 +726,18 @@ static int tegra_slink_start_transfer_one(struct spi_device *spi, ...@@ -729,9 +726,18 @@ static int tegra_slink_start_transfer_one(struct spi_device *spi,
command2 |= SLINK_TXEN; command2 |= SLINK_TXEN;
tspi->cur_direction |= DATA_DIR_TX; tspi->cur_direction |= DATA_DIR_TX;
} }
/*
* Writing to the command2 register bevore the command register prevents
* a spike in chip_select line 0. This selects the chip_select line
* before changing the chip_select value.
*/
tegra_slink_writel(tspi, command2, SLINK_COMMAND2); tegra_slink_writel(tspi, command2, SLINK_COMMAND2);
tspi->command2_reg = command2; tspi->command2_reg = command2;
tegra_slink_writel(tspi, command, SLINK_COMMAND);
tspi->command_reg = command;
if (total_fifo_words > SLINK_FIFO_DEPTH) if (total_fifo_words > SLINK_FIFO_DEPTH)
ret = tegra_slink_start_dma_based_transfer(tspi, t); ret = tegra_slink_start_dma_based_transfer(tspi, t);
else else
......
...@@ -1299,18 +1299,27 @@ static void pch_free_dma_buf(struct pch_spi_board_data *board_dat, ...@@ -1299,18 +1299,27 @@ static void pch_free_dma_buf(struct pch_spi_board_data *board_dat,
dma->rx_buf_virt, dma->rx_buf_dma); dma->rx_buf_virt, dma->rx_buf_dma);
} }
static void pch_alloc_dma_buf(struct pch_spi_board_data *board_dat, static int pch_alloc_dma_buf(struct pch_spi_board_data *board_dat,
struct pch_spi_data *data) struct pch_spi_data *data)
{ {
struct pch_spi_dma_ctrl *dma; struct pch_spi_dma_ctrl *dma;
int ret;
dma = &data->dma; dma = &data->dma;
ret = 0;
/* Get Consistent memory for Tx DMA */ /* Get Consistent memory for Tx DMA */
dma->tx_buf_virt = dma_alloc_coherent(&board_dat->pdev->dev, dma->tx_buf_virt = dma_alloc_coherent(&board_dat->pdev->dev,
PCH_BUF_SIZE, &dma->tx_buf_dma, GFP_KERNEL); PCH_BUF_SIZE, &dma->tx_buf_dma, GFP_KERNEL);
if (!dma->tx_buf_virt)
ret = -ENOMEM;
/* Get Consistent memory for Rx DMA */ /* Get Consistent memory for Rx DMA */
dma->rx_buf_virt = dma_alloc_coherent(&board_dat->pdev->dev, dma->rx_buf_virt = dma_alloc_coherent(&board_dat->pdev->dev,
PCH_BUF_SIZE, &dma->rx_buf_dma, GFP_KERNEL); PCH_BUF_SIZE, &dma->rx_buf_dma, GFP_KERNEL);
if (!dma->rx_buf_virt)
ret = -ENOMEM;
return ret;
} }
static int pch_spi_pd_probe(struct platform_device *plat_dev) static int pch_spi_pd_probe(struct platform_device *plat_dev)
...@@ -1387,7 +1396,9 @@ static int pch_spi_pd_probe(struct platform_device *plat_dev) ...@@ -1387,7 +1396,9 @@ static int pch_spi_pd_probe(struct platform_device *plat_dev)
if (use_dma) { if (use_dma) {
dev_info(&plat_dev->dev, "Use DMA for data transfers\n"); dev_info(&plat_dev->dev, "Use DMA for data transfers\n");
pch_alloc_dma_buf(board_dat, data); ret = pch_alloc_dma_buf(board_dat, data);
if (ret)
goto err_spi_register_master;
} }
ret = spi_register_master(master); ret = spi_register_master(master);
......
This diff is collapsed.
...@@ -36,6 +36,8 @@ ...@@ -36,6 +36,8 @@
#define CREATE_TRACE_POINTS #define CREATE_TRACE_POINTS
#include <trace/events/spi.h> #include <trace/events/spi.h>
EXPORT_TRACEPOINT_SYMBOL(spi_transfer_start);
EXPORT_TRACEPOINT_SYMBOL(spi_transfer_stop);
#include "internals.h" #include "internals.h"
...@@ -1039,6 +1041,8 @@ static int spi_map_msg(struct spi_controller *ctlr, struct spi_message *msg) ...@@ -1039,6 +1041,8 @@ static int spi_map_msg(struct spi_controller *ctlr, struct spi_message *msg)
if (max_tx || max_rx) { if (max_tx || max_rx) {
list_for_each_entry(xfer, &msg->transfers, list_for_each_entry(xfer, &msg->transfers,
transfer_list) { transfer_list) {
if (!xfer->len)
continue;
if (!xfer->tx_buf) if (!xfer->tx_buf)
xfer->tx_buf = ctlr->dummy_tx; xfer->tx_buf = ctlr->dummy_tx;
if (!xfer->rx_buf) if (!xfer->rx_buf)
...@@ -1177,10 +1181,10 @@ static int spi_transfer_one_message(struct spi_controller *ctlr, ...@@ -1177,10 +1181,10 @@ static int spi_transfer_one_message(struct spi_controller *ctlr,
if (msg->status && ctlr->handle_err) if (msg->status && ctlr->handle_err)
ctlr->handle_err(ctlr, msg); ctlr->handle_err(ctlr, msg);
spi_res_release(ctlr, msg);
spi_finalize_current_message(ctlr); spi_finalize_current_message(ctlr);
spi_res_release(ctlr, msg);
return ret; return ret;
} }
...@@ -2195,6 +2199,8 @@ static int spi_get_gpio_descs(struct spi_controller *ctlr) ...@@ -2195,6 +2199,8 @@ static int spi_get_gpio_descs(struct spi_controller *ctlr)
*/ */
cs[i] = devm_gpiod_get_index_optional(dev, "cs", i, cs[i] = devm_gpiod_get_index_optional(dev, "cs", i,
GPIOD_OUT_LOW); GPIOD_OUT_LOW);
if (IS_ERR(cs[i]))
return PTR_ERR(cs[i]);
if (cs[i]) { if (cs[i]) {
/* /*
...@@ -2261,7 +2267,7 @@ int spi_register_controller(struct spi_controller *ctlr) ...@@ -2261,7 +2267,7 @@ int spi_register_controller(struct spi_controller *ctlr)
{ {
struct device *dev = ctlr->dev.parent; struct device *dev = ctlr->dev.parent;
struct boardinfo *bi; struct boardinfo *bi;
int status = -ENODEV; int status;
int id, first_dynamic; int id, first_dynamic;
if (!dev) if (!dev)
...@@ -2275,24 +2281,6 @@ int spi_register_controller(struct spi_controller *ctlr) ...@@ -2275,24 +2281,6 @@ int spi_register_controller(struct spi_controller *ctlr)
if (status) if (status)
return status; return status;
if (!spi_controller_is_slave(ctlr)) {
if (ctlr->use_gpio_descriptors) {
status = spi_get_gpio_descs(ctlr);
if (status)
return status;
/*
* A controller using GPIO descriptors always
* supports SPI_CS_HIGH if need be.
*/
ctlr->mode_bits |= SPI_CS_HIGH;
} else {
/* Legacy code path for GPIOs from DT */
status = of_spi_register_master(ctlr);
if (status)
return status;
}
}
/* even if it's just one always-selected device, there must /* even if it's just one always-selected device, there must
* be at least one chipselect * be at least one chipselect
*/ */
...@@ -2349,6 +2337,25 @@ int spi_register_controller(struct spi_controller *ctlr) ...@@ -2349,6 +2337,25 @@ int spi_register_controller(struct spi_controller *ctlr)
* registration fails if the bus ID is in use. * registration fails if the bus ID is in use.
*/ */
dev_set_name(&ctlr->dev, "spi%u", ctlr->bus_num); dev_set_name(&ctlr->dev, "spi%u", ctlr->bus_num);
if (!spi_controller_is_slave(ctlr)) {
if (ctlr->use_gpio_descriptors) {
status = spi_get_gpio_descs(ctlr);
if (status)
return status;
/*
* A controller using GPIO descriptors always
* supports SPI_CS_HIGH if need be.
*/
ctlr->mode_bits |= SPI_CS_HIGH;
} else {
/* Legacy code path for GPIOs from DT */
status = of_spi_register_master(ctlr);
if (status)
return status;
}
}
status = device_add(&ctlr->dev); status = device_add(&ctlr->dev);
if (status < 0) { if (status < 0) {
/* free bus id */ /* free bus id */
...@@ -2781,11 +2788,6 @@ static int __spi_split_transfer_maxsize(struct spi_controller *ctlr, ...@@ -2781,11 +2788,6 @@ static int __spi_split_transfer_maxsize(struct spi_controller *ctlr,
size_t offset; size_t offset;
size_t count, i; size_t count, i;
/* warn once about this fact that we are splitting a transfer */
dev_warn_once(&msg->spi->dev,
"spi_transfer of length %i exceed max length of %zu - needed to split transfers\n",
xfer->len, maxsize);
/* calculate how many we have to replace */ /* calculate how many we have to replace */
count = DIV_ROUND_UP(xfer->len, maxsize); count = DIV_ROUND_UP(xfer->len, maxsize);
...@@ -2943,6 +2945,11 @@ int spi_setup(struct spi_device *spi) ...@@ -2943,6 +2945,11 @@ int spi_setup(struct spi_device *spi)
* so it is ignored here. * so it is ignored here.
*/ */
bad_bits = spi->mode & ~(spi->controller->mode_bits | SPI_CS_WORD); bad_bits = spi->mode & ~(spi->controller->mode_bits | SPI_CS_WORD);
/* nothing prevents from working with active-high CS in case if it
* is driven by GPIO.
*/
if (gpio_is_valid(spi->cs_gpio))
bad_bits &= ~SPI_CS_HIGH;
ugly_bits = bad_bits & ugly_bits = bad_bits &
(SPI_TX_DUAL | SPI_TX_QUAD | SPI_TX_OCTAL | (SPI_TX_DUAL | SPI_TX_QUAD | SPI_TX_OCTAL |
SPI_RX_DUAL | SPI_RX_QUAD | SPI_RX_OCTAL); SPI_RX_DUAL | SPI_RX_QUAD | SPI_RX_OCTAL);
...@@ -2988,6 +2995,21 @@ int spi_setup(struct spi_device *spi) ...@@ -2988,6 +2995,21 @@ int spi_setup(struct spi_device *spi)
} }
EXPORT_SYMBOL_GPL(spi_setup); EXPORT_SYMBOL_GPL(spi_setup);
/**
* spi_set_cs_timing - configure CS setup, hold, and inactive delays
* @spi: the device that requires specific CS timing configuration
* @setup: CS setup time in terms of clock count
* @hold: CS hold time in terms of clock count
* @inactive_dly: CS inactive delay between transfers in terms of clock count
*/
void spi_set_cs_timing(struct spi_device *spi, u8 setup, u8 hold,
u8 inactive_dly)
{
if (spi->controller->set_cs_timing)
spi->controller->set_cs_timing(spi, setup, hold, inactive_dly);
}
EXPORT_SYMBOL_GPL(spi_set_cs_timing);
static int __spi_validate(struct spi_device *spi, struct spi_message *message) static int __spi_validate(struct spi_device *spi, struct spi_message *message)
{ {
struct spi_controller *ctlr = spi->controller; struct spi_controller *ctlr = spi->controller;
...@@ -3062,8 +3084,6 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) ...@@ -3062,8 +3084,6 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message)
if (!xfer->speed_hz) if (!xfer->speed_hz)
xfer->speed_hz = spi->max_speed_hz; xfer->speed_hz = spi->max_speed_hz;
if (!xfer->speed_hz)
xfer->speed_hz = ctlr->max_speed_hz;
if (ctlr->max_speed_hz && xfer->speed_hz > ctlr->max_speed_hz) if (ctlr->max_speed_hz && xfer->speed_hz > ctlr->max_speed_hz)
xfer->speed_hz = ctlr->max_speed_hz; xfer->speed_hz = ctlr->max_speed_hz;
......
...@@ -276,17 +276,19 @@ static int spidev_message(struct spidev_data *spidev, ...@@ -276,17 +276,19 @@ static int spidev_message(struct spidev_data *spidev,
k_tmp->bits_per_word = u_tmp->bits_per_word; k_tmp->bits_per_word = u_tmp->bits_per_word;
k_tmp->delay_usecs = u_tmp->delay_usecs; k_tmp->delay_usecs = u_tmp->delay_usecs;
k_tmp->speed_hz = u_tmp->speed_hz; k_tmp->speed_hz = u_tmp->speed_hz;
k_tmp->word_delay_usecs = u_tmp->word_delay_usecs;
if (!k_tmp->speed_hz) if (!k_tmp->speed_hz)
k_tmp->speed_hz = spidev->speed_hz; k_tmp->speed_hz = spidev->speed_hz;
#ifdef VERBOSE #ifdef VERBOSE
dev_dbg(&spidev->spi->dev, dev_dbg(&spidev->spi->dev,
" xfer len %u %s%s%s%dbits %u usec %uHz\n", " xfer len %u %s%s%s%dbits %u usec %u usec %uHz\n",
u_tmp->len, u_tmp->len,
u_tmp->rx_buf ? "rx " : "", u_tmp->rx_buf ? "rx " : "",
u_tmp->tx_buf ? "tx " : "", u_tmp->tx_buf ? "tx " : "",
u_tmp->cs_change ? "cs " : "", u_tmp->cs_change ? "cs " : "",
u_tmp->bits_per_word ? : spidev->spi->bits_per_word, u_tmp->bits_per_word ? : spidev->spi->bits_per_word,
u_tmp->delay_usecs, u_tmp->delay_usecs,
u_tmp->word_delay_usecs,
u_tmp->speed_hz ? : spidev->spi->max_speed_hz); u_tmp->speed_hz ? : spidev->spi->max_speed_hz);
#endif #endif
spi_message_add_tail(k_tmp, &msg); spi_message_add_tail(k_tmp, &msg);
......
...@@ -106,8 +106,6 @@ source "drivers/staging/mt7621-pci-phy/Kconfig" ...@@ -106,8 +106,6 @@ source "drivers/staging/mt7621-pci-phy/Kconfig"
source "drivers/staging/mt7621-pinctrl/Kconfig" source "drivers/staging/mt7621-pinctrl/Kconfig"
source "drivers/staging/mt7621-spi/Kconfig"
source "drivers/staging/mt7621-dma/Kconfig" source "drivers/staging/mt7621-dma/Kconfig"
source "drivers/staging/ralink-gdma/Kconfig" source "drivers/staging/ralink-gdma/Kconfig"
......
...@@ -43,7 +43,6 @@ obj-$(CONFIG_PI433) += pi433/ ...@@ -43,7 +43,6 @@ obj-$(CONFIG_PI433) += pi433/
obj-$(CONFIG_PCI_MT7621) += mt7621-pci/ obj-$(CONFIG_PCI_MT7621) += mt7621-pci/
obj-$(CONFIG_PCI_MT7621_PHY) += mt7621-pci-phy/ obj-$(CONFIG_PCI_MT7621_PHY) += mt7621-pci-phy/
obj-$(CONFIG_PINCTRL_RT2880) += mt7621-pinctrl/ obj-$(CONFIG_PINCTRL_RT2880) += mt7621-pinctrl/
obj-$(CONFIG_SPI_MT7621) += mt7621-spi/
obj-$(CONFIG_SOC_MT7621) += mt7621-dma/ obj-$(CONFIG_SOC_MT7621) += mt7621-dma/
obj-$(CONFIG_DMA_RALINK) += ralink-gdma/ obj-$(CONFIG_DMA_RALINK) += ralink-gdma/
obj-$(CONFIG_MTK_MMC) += mt7621-mmc/ obj-$(CONFIG_MTK_MMC) += mt7621-mmc/
......
config SPI_MT7621
tristate "MediaTek MT7621 SPI Controller"
depends on RALINK
help
This selects a driver for the MediaTek MT7621 SPI Controller.
obj-$(CONFIG_SPI_MT7621) += spi-mt7621.o
- general code review and clean up
- ensure device-tree requirements are documented
Cc: NeilBrown <neil@brown.name>
...@@ -6,13 +6,9 @@ struct spi_device; ...@@ -6,13 +6,9 @@ struct spi_device;
/** /**
* struct ep93xx_spi_info - EP93xx specific SPI descriptor * struct ep93xx_spi_info - EP93xx specific SPI descriptor
* @chipselect: array of gpio numbers to use as chip selects
* @num_chipselect: ARRAY_SIZE(chipselect)
* @use_dma: use DMA for the transfers * @use_dma: use DMA for the transfers
*/ */
struct ep93xx_spi_info { struct ep93xx_spi_info {
int *chipselect;
int num_chipselect;
bool use_dma; bool use_dma;
}; };
......
...@@ -25,6 +25,7 @@ struct dma_chan; ...@@ -25,6 +25,7 @@ struct dma_chan;
struct pxa2xx_spi_controller { struct pxa2xx_spi_controller {
u16 num_chipselect; u16 num_chipselect;
u8 enable_dma; u8 enable_dma;
u8 dma_burst_size;
bool is_slave; bool is_slave;
/* DMA engine specific config */ /* DMA engine specific config */
......
...@@ -295,6 +295,10 @@ int spi_controller_dma_map_mem_op_data(struct spi_controller *ctlr, ...@@ -295,6 +295,10 @@ int spi_controller_dma_map_mem_op_data(struct spi_controller *ctlr,
void spi_controller_dma_unmap_mem_op_data(struct spi_controller *ctlr, void spi_controller_dma_unmap_mem_op_data(struct spi_controller *ctlr,
const struct spi_mem_op *op, const struct spi_mem_op *op,
struct sg_table *sg); struct sg_table *sg);
bool spi_mem_default_supports_op(struct spi_mem *mem,
const struct spi_mem_op *op);
#else #else
static inline int static inline int
spi_controller_dma_map_mem_op_data(struct spi_controller *ctlr, spi_controller_dma_map_mem_op_data(struct spi_controller *ctlr,
...@@ -310,6 +314,14 @@ spi_controller_dma_unmap_mem_op_data(struct spi_controller *ctlr, ...@@ -310,6 +314,14 @@ spi_controller_dma_unmap_mem_op_data(struct spi_controller *ctlr,
struct sg_table *sg) struct sg_table *sg)
{ {
} }
static inline
bool spi_mem_default_supports_op(struct spi_mem *mem,
const struct spi_mem_op *op)
{
return false;
}
#endif /* CONFIG_SPI_MEM */ #endif /* CONFIG_SPI_MEM */
int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op); int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op);
......
...@@ -143,7 +143,7 @@ struct spi_device { ...@@ -143,7 +143,7 @@ struct spi_device {
u32 max_speed_hz; u32 max_speed_hz;
u8 chip_select; u8 chip_select;
u8 bits_per_word; u8 bits_per_word;
u16 mode; u32 mode;
#define SPI_CPHA 0x01 /* clock phase */ #define SPI_CPHA 0x01 /* clock phase */
#define SPI_CPOL 0x02 /* clock polarity */ #define SPI_CPOL 0x02 /* clock polarity */
#define SPI_MODE_0 (0|0) /* (original MicroWire) */ #define SPI_MODE_0 (0|0) /* (original MicroWire) */
...@@ -330,6 +330,9 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) ...@@ -330,6 +330,9 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
* must fail if an unrecognized or unsupported mode is requested. * must fail if an unrecognized or unsupported mode is requested.
* It's always safe to call this unless transfers are pending on * It's always safe to call this unless transfers are pending on
* the device whose settings are being modified. * the device whose settings are being modified.
* @set_cs_timing: optional hook for SPI devices to request SPI master
* controller for configuring specific CS setup time, hold time and inactive
* delay interms of clock counts
* @transfer: adds a message to the controller's transfer queue. * @transfer: adds a message to the controller's transfer queue.
* @cleanup: frees controller-specific state * @cleanup: frees controller-specific state
* @can_dma: determine whether this controller supports DMA * @can_dma: determine whether this controller supports DMA
...@@ -363,6 +366,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) ...@@ -363,6 +366,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
* @unprepare_transfer_hardware: there are currently no more messages on the * @unprepare_transfer_hardware: there are currently no more messages on the
* queue so the subsystem notifies the driver that it may relax the * queue so the subsystem notifies the driver that it may relax the
* hardware by issuing this call * hardware by issuing this call
*
* @set_cs: set the logic level of the chip select line. May be called * @set_cs: set the logic level of the chip select line. May be called
* from interrupt context. * from interrupt context.
* @prepare_message: set up the controller to transfer a single message, * @prepare_message: set up the controller to transfer a single message,
...@@ -439,13 +443,12 @@ struct spi_controller { ...@@ -439,13 +443,12 @@ struct spi_controller {
u16 dma_alignment; u16 dma_alignment;
/* spi_device.mode flags understood by this controller driver */ /* spi_device.mode flags understood by this controller driver */
u16 mode_bits; u32 mode_bits;
/* bitmask of supported bits_per_word for transfers */ /* bitmask of supported bits_per_word for transfers */
u32 bits_per_word_mask; u32 bits_per_word_mask;
#define SPI_BPW_MASK(bits) BIT((bits) - 1) #define SPI_BPW_MASK(bits) BIT((bits) - 1)
#define SPI_BIT_MASK(bits) (((bits) == 32) ? ~0U : (BIT(bits) - 1)) #define SPI_BPW_RANGE_MASK(min, max) GENMASK((max) - 1, (min) - 1)
#define SPI_BPW_RANGE_MASK(min, max) (SPI_BIT_MASK(max) - SPI_BIT_MASK(min - 1))
/* limits on transfer speed */ /* limits on transfer speed */
u32 min_speed_hz; u32 min_speed_hz;
...@@ -489,6 +492,17 @@ struct spi_controller { ...@@ -489,6 +492,17 @@ struct spi_controller {
*/ */
int (*setup)(struct spi_device *spi); int (*setup)(struct spi_device *spi);
/*
* set_cs_timing() method is for SPI controllers that supports
* configuring CS timing.
*
* This hook allows SPI client drivers to request SPI controllers
* to configure specific CS timing through spi_set_cs_timing() after
* spi_setup().
*/
void (*set_cs_timing)(struct spi_device *spi, u8 setup_clk_cycles,
u8 hold_clk_cycles, u8 inactive_clk_cycles);
/* bidirectional bulk transfers /* bidirectional bulk transfers
* *
* + The transfer() method may not sleep; its main role is * + The transfer() method may not sleep; its main role is
...@@ -1277,7 +1291,7 @@ struct spi_board_info { ...@@ -1277,7 +1291,7 @@ struct spi_board_info {
/* mode becomes spi_device.mode, and is essential for chips /* mode becomes spi_device.mode, and is essential for chips
* where the default of SPI_CS_HIGH = 0 is wrong. * where the default of SPI_CS_HIGH = 0 is wrong.
*/ */
u16 mode; u32 mode;
/* ... may need additional spi_device chip config data here. /* ... may need additional spi_device chip config data here.
* avoid stuff protocol drivers can set; but include stuff * avoid stuff protocol drivers can set; but include stuff
......
...@@ -44,6 +44,7 @@ extern int spi_bitbang_setup_transfer(struct spi_device *spi, ...@@ -44,6 +44,7 @@ extern int spi_bitbang_setup_transfer(struct spi_device *spi,
/* start or stop queue processing */ /* start or stop queue processing */
extern int spi_bitbang_start(struct spi_bitbang *spi); extern int spi_bitbang_start(struct spi_bitbang *spi);
extern int spi_bitbang_init(struct spi_bitbang *spi);
extern void spi_bitbang_stop(struct spi_bitbang *spi); extern void spi_bitbang_stop(struct spi_bitbang *spi);
#endif /* __SPI_BITBANG_H */ #endif /* __SPI_BITBANG_H */
...@@ -131,9 +131,11 @@ DECLARE_EVENT_CLASS(spi_transfer, ...@@ -131,9 +131,11 @@ DECLARE_EVENT_CLASS(spi_transfer,
__field( struct spi_transfer *, xfer ) __field( struct spi_transfer *, xfer )
__field( int, len ) __field( int, len )
__dynamic_array(u8, rx_buf, __dynamic_array(u8, rx_buf,
spi_valid_rxbuf(msg, xfer) ? xfer->len : 0) spi_valid_rxbuf(msg, xfer) ?
(xfer->len < 64 ? xfer->len : 64) : 0)
__dynamic_array(u8, tx_buf, __dynamic_array(u8, tx_buf,
spi_valid_txbuf(msg, xfer) ? xfer->len : 0) spi_valid_txbuf(msg, xfer) ?
(xfer->len < 64 ? xfer->len : 64) : 0)
), ),
TP_fast_assign( TP_fast_assign(
...@@ -144,11 +146,11 @@ DECLARE_EVENT_CLASS(spi_transfer, ...@@ -144,11 +146,11 @@ DECLARE_EVENT_CLASS(spi_transfer,
if (spi_valid_txbuf(msg, xfer)) if (spi_valid_txbuf(msg, xfer))
memcpy(__get_dynamic_array(tx_buf), memcpy(__get_dynamic_array(tx_buf),
xfer->tx_buf, xfer->len); xfer->tx_buf, __get_dynamic_array_len(tx_buf));
if (spi_valid_rxbuf(msg, xfer)) if (spi_valid_rxbuf(msg, xfer))
memcpy(__get_dynamic_array(rx_buf), memcpy(__get_dynamic_array(rx_buf),
xfer->rx_buf, xfer->len); xfer->rx_buf, __get_dynamic_array_len(rx_buf));
), ),
TP_printk("spi%d.%d %p len=%d tx=[%*phD] rx=[%*phD]", TP_printk("spi%d.%d %p len=%d tx=[%*phD] rx=[%*phD]",
......
...@@ -66,6 +66,9 @@ ...@@ -66,6 +66,9 @@
* @delay_usecs: If nonzero, how long to delay after the last bit transfer * @delay_usecs: If nonzero, how long to delay after the last bit transfer
* before optionally deselecting the device before the next transfer. * before optionally deselecting the device before the next transfer.
* @cs_change: True to deselect device before starting the next transfer. * @cs_change: True to deselect device before starting the next transfer.
* @word_delay_usecs: If nonzero, how long to wait between words within one
* transfer. This property needs explicit support in the SPI controller,
* otherwise it is silently ignored.
* *
* This structure is mapped directly to the kernel spi_transfer structure; * This structure is mapped directly to the kernel spi_transfer structure;
* the fields have the same meanings, except of course that the pointers * the fields have the same meanings, except of course that the pointers
...@@ -100,7 +103,8 @@ struct spi_ioc_transfer { ...@@ -100,7 +103,8 @@ struct spi_ioc_transfer {
__u8 cs_change; __u8 cs_change;
__u8 tx_nbits; __u8 tx_nbits;
__u8 rx_nbits; __u8 rx_nbits;
__u16 pad; __u8 word_delay_usecs;
__u8 pad;
/* If the contents of 'struct spi_ioc_transfer' ever change /* If the contents of 'struct spi_ioc_transfer' ever change
* incompatibly, then the ioctl number (currently 0) must change; * incompatibly, then the ioctl number (currently 0) must change;
......
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
#include <linux/mod_devicetable.h> #include <linux/mod_devicetable.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <sound/soc.h> #include <sound/soc.h>
...@@ -54,9 +56,18 @@ static const struct spi_device_id adau1977_spi_ids[] = { ...@@ -54,9 +56,18 @@ static const struct spi_device_id adau1977_spi_ids[] = {
}; };
MODULE_DEVICE_TABLE(spi, adau1977_spi_ids); MODULE_DEVICE_TABLE(spi, adau1977_spi_ids);
static const struct of_device_id adau1977_spi_of_match[] = {
{ .compatible = "adi,adau1977" },
{ .compatible = "adi,adau1978" },
{ .compatible = "adi,adau1979" },
{ },
};
MODULE_DEVICE_TABLE(of, adau1977_spi_of_match);
static struct spi_driver adau1977_spi_driver = { static struct spi_driver adau1977_spi_driver = {
.driver = { .driver = {
.name = "adau1977", .name = "adau1977",
.of_match_table = of_match_ptr(adau1977_spi_of_match),
}, },
.probe = adau1977_spi_probe, .probe = adau1977_spi_probe,
.id_table = adau1977_spi_ids, .id_table = adau1977_spi_ids,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment