summaryrefslogtreecommitdiff
path: root/drivers/spi/spi-dw-core.c
AgeCommit message (Collapse)Author
2021-12-23spi: dw: Propagate firmware nodeAndy Shevchenko
Propagate firmware node by using a specific API call, i.e. device_set_node(). Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Tested-by: Serge Semin <fancer.lancer@gmail.com> Acked-by: Serge Semin <fancer.lancer@gmail.com> Link: https://lore.kernel.org/r/20211222155739.7699-2-andriy.shevchenko@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
2021-11-16spi: dw: Replace DWC_HSSI capability with IP-core version checkerSerge Semin
Since there is a common IP-core and component versions interface available we can use it to differentiate the DW HSSI device features in the code. Let's remove the corresponding DWC_HSSI capability flag then and use the dw_spi_ip_is() macro instead. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20211115181917.7521-7-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown <broonie@kernel.org>
2021-11-16spi: dw: Introduce Synopsys IP-core versions interfaceSerge Semin
The driver currently supports two IP-core versions. It's DW APB SSI which is older version of the controller with APB system bus interface, and DW SSI controller with AHB bus interface. The later one is supposed to be a new generation high-speed SSI. Even though both of these IP-cores have got an almost identical registers space there are some differences. The driver differentiates these distinctions by the DW_SPI_CAP_DWC_HSSI capability flag. In addition to that each DW SSI IP-core is equipped with a Synopsys Component version register, which encodes the IP-core release ID the has been synthesized from. Seeing we are going to need the later one to differentiate some controller peculiarities it would be better to have a unified interface for both IP-core line and release versions instead of using each of them separately. Introduced here IP-core versioning interface consists of two parts: 1) IDs of the IP-core (virtual) and component versions. 2) a set of macro helpers to identify current IP-core and component versions. So the platform code is supposed to assign a proper IP-core version based on it's platform -knowledge. The main driver initialization method reads the IP-core release ID from the SSI component version register. That data is used by the helpers to distinguish one IP-core release from another. Thus the rest of the driver can use these macros to implement the conditional code execution based on the specified IP-core and version IDs. Collect the IP-core versions interface and the defined capabilities at the top of the header file since they represent a common device description data and so to immediately available for the driver hackers. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Suggested-by: Andy Shevchenko <andy.shevchenko@gmail.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20211115181917.7521-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown <broonie@kernel.org>
2021-11-16spi: dw: Convert to using the Bitfield access macrosSerge Semin
The driver has been using the offset/bitwise-shift-based approach for the CSR fields R/W operations since it was merged into the kernel. It can be simplified by using the macros defined in the linux/bitfield.h and linux/bit.h header files like BIT(), GENMASK(), FIELD_PREP(), FIELD_GET(), etc where it is required, for instance in the cached cr0 preparation method. Thus in order to have the FIELD_*()-macros utilized we just need to convert the macros with the CSR-fields offsets to the masks with the corresponding registers fields definition. That's where the GENMASK() and BIT() macros come in handy. After that the masks can be used in the FIELD_*()-macros where it's appropriate. We also need to convert the macros with the CRS-bit flags using the manual bitwise shift operations (x << y) to using the BIT() macro. Thus we'll have a more coherent set of the CSR-related macros. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20211115181917.7521-5-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown <broonie@kernel.org>
2021-11-16spi: dw: Put the driver entities naming in orderSerge Semin
Mostly due to a long driver history it's methods and macro names look a bit messy. In particularly that concerns the code their prefixes. A biggest part of the driver functions and macros have got the dw_spi/DW_SPI prefixes. But there are some entities which have been just "spi_/SPI_"-prefixed. Especially that concerns the CSR and their fields macro definitions. It makes the code harder to comprehend since such methods and macros can be easily confused with the global SPI-subsystem exports. In this case the only possible way to more or less quickly distinguish one naming space from another is either by context or by the argument type, which most of the times isn't that easy anyway. In addition to that a new DW SSI IP-core support has been added in the framework of commit e539f435cb9c ("spi: dw: Add support for DesignWare DWC_ssi"), which introduced a new set or macro-prefixes to describe CTRLR0-specific fields and worsen the situation. Finally there are methods with no DW SPI driver-reference prefix at all, that make the code reading even harder. So in order to ease the driver hacking let's bring the code naming to a common base: 1) Each method is supposed to have "dw_spi_" prefix so to be easily distinguished from the kernel API, e.g. SPI-subsystem methods and macros. (Exception is the local implementation of the readl/writel methods since being just the regspace accessors.) 2) Each generically used macro should have DW_SPI_-prefix thus being easily comprehended as the local driver definition. 3) DW APB SSI and DW SSI specific macros should have prefixes as DW_PSSI_ and DW_HSSI_ respectively so referring to the system buses they support (APB and AHB similarly to the DT clocks naming like pclk, hclk). Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20211115181917.7521-4-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown <broonie@kernel.org>
2021-11-16spi: dw: Discard redundant DW SSI Frame Formats enumerationSerge Semin
The dw_ssi_type enumeration describes the SPI frame formats the controller supports, like Motorola SPI, Texas Instruments SSP and National Semiconductors Microwire, that is the serial protocol utilized for the SPI-transfers. Depending on the DW SSI IP-core configuration the protocol could be either fixed or selectable. If it is changebale the protocol can be selected by means of the CTRL0.FRF field, which possible values encoded by the dw_ssi_type enumeration. Aside with the denoted enum the field values are also described by a set of SPI_FRF_{SPI,SSP,MICROWIRE} macros. Thus currently the DW SPI driver has got two entities describing the same data. Let's get rid of the enumeration one then, since first it hasn't been used as enumeration-type but merely as a parametrized values set and second that would unify the macro-based CSR read/write interface of the driver. While at it convert the macro names to be more descriptive about the protocols they represent. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20211115181917.7521-3-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown <broonie@kernel.org>
2021-11-16spi: dw: Add a symbols namespace for the core moduleSerge Semin
The exported from the DW SPI driver core/DMA symbols are only used by the spi-dw-{mmio,pci,bt1}.o objects. Add these symbols to a separate namespace then and make sure the depended modules have it imported. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Suggested-by: Andy Shevchenko <andy.shevchenko@gmail.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20211115181917.7521-2-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown <broonie@kernel.org>
2020-12-09spi: dw: Add support for 32-bits max xfer sizeDamien Le Moal
The Synopsis DesignWare DW_apb_ssi specifications version 3.23 onward define a 32-bits maximum transfer size synthesis parameter (SSI_MAX_XFER_SIZE=32) in addition to the legacy 16-bits configuration (SSI_MAX_XFER_SIZE=16) for SPI controllers. When SSI_MAX_XFER_SIZE=32, the layout of the ctrlr0 register changes, moving the data frame format field from bits [3..0] to bits [16..20], and the RX/TX FIFO word size can be up to 32-bits. To support this new format, introduce the DW SPI capability flag DW_SPI_CAP_DFS32 to indicate that a controller is configured with SSI_MAX_XFER_SIZE=32. Since SSI_MAX_XFER_SIZE is a controller synthesis parameter not accessible through a register, the detection of this parameter value is done in spi_hw_init() by writing and reading the ctrlr0 register and testing the value of bits [3..0]. These bits are ignored (unchanged) for SSI_MAX_XFER_SIZE=16, allowing the detection. If a DFS32 capable SPI controller is detected, the new field dfs_offset in struct dw_spi is set to SPI_DFS32_OFFSET (16). dw_spi_update_config() is modified to set the data frame size field at the correct position is the CTRLR0 register, as indicated by the dfs_offset field of the dw_spi structure. The DW_SPI_CAP_DFS32 flag is also unconditionally set for SPI slave controllers, e.g. controllers that have the DW_SPI_CAP_DWC_SSI capability flag set. However, for these ssi controllers, the dfs_offset field is set to 0 as before (as per specifications). Finally, for any controller with the DW_SPI_CAP_DFS32 capability flag set, dw_spi_add_host() extends the value of bits_per_word_mask from 16-bits to 32-bits. dw_reader() and dw_writer() are also modified to handle 32-bits iTX/RX FIFO words. Suggested-by: Sean Anderson <seanga2@gmail.com> Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com> Acked-by: Serge Semin <fancer.lancer@gmail.com> Link: https://lore.kernel.org/r/20201206011817.11700-3-damien.lemoal@wdc.com Signed-off-by: Mark Brown <broonie@kernel.org>
2020-11-25spi: dw: Fix spi registration for controllers overriding CSLars Povlsen
When SPI DW memory ops support was introduced, there was a check for excluding controllers which supplied their own CS function. Even so, the mem_ops pointer is *always* presented to the SPI core. This causes the SPI core sanity check in spi_controller_check_ops() to refuse registration, since a mem_ops pointer is being supplied without an exec_op member function. The end result is failure of the SPI DW driver on sparx5 and similar platforms. The fix in the core SPI DW driver is to avoid presenting the mem_ops pointer if the exec_op function is not set. Fixes: 6423207e57ea (spi: dw: Add memory operations support) Signed-off-by: Lars Povlsen <lars.povlsen@microchip.com> Acked-by: Serge Semin <fancer.lancer@gmail.com> Link: https://lore.kernel.org/r/20201120213414.339701-1-lars.povlsen@microchip.com Signed-off-by: Mark Brown <broonie@kernel.org>
2020-11-17spi: dw: Set transfer handler before unmasking the IRQsSerge Semin
It turns out the IRQs most like can be unmasked before the controller is enabled with no problematic consequences. The manual doesn't explicitly state that, but the examples perform the controller initialization procedure in that order. So the commit da8f58909e7e ("spi: dw: Unmask IRQs after enabling the chip") hasn't been that required as I thought. But anyway setting the IRQs up after the chip enabling still worth adding since it has simplified the code a bit. The problem is that it has introduced a potential bug. The transfer handler pointer is now initialized after the IRQs are enabled. That may and eventually will cause an invalid or uninitialized callback invocation. Fix that just by performing the callback initialization before the IRQ unmask procedure. Fixes: da8f58909e7e ("spi: dw: Unmask IRQs after enabling the chip") Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20201117094054.4696-1-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown <broonie@kernel.org>
2020-10-08spi: dw: Add poll-based SPI transfers supportSerge Semin
A functionality of the poll-based transfer has been removed by commit 1ceb09717e98 ("spi: dw: remove cs_control and poll_mode members from chip_data") with a justification that "there is no user of one anymore". It turns out one of our DW APB SSI core is synthesized with no IRQ line attached and the only possible way of using it is to implement a poll-based SPI transfer procedure. So we have to get the removed functionality back, but with some alterations described below. First of all the poll-based transfer is activated only if the DW SPI controller doesn't have an IRQ line attached and the Linux IRQ number is initialized with the IRQ_NOTCONNECTED value. Secondly the transfer procedure is now executed with a delay performed between writer and reader methods. The delay value is calculated based on the number of data words expected to be received on the current iteration. Finally the errors status is checked on each iteration. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20201007235511.4935-20-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown <broonie@kernel.org>
2020-10-08spi: dw: Introduce max mem-ops SPI bus frequency settingSerge Semin
In some circumstances the current implementation of the SPI memory operations may occasionally fail even though they are executed in the atomic context. This may happen if the system bus is relatively slow in comparison to the SPI bus frequency, or there is a concurrent access to it, which makes the MMIO-operations occasionally stalling before push-pulling data from the DW APB SPI FIFOs. These two problems we've discovered on the Baikal-T1 SoC. In order to fix them we have no choice but to set an artificial limitation on the SPI bus speed. Note currently this limitation will be only applicable for the memory operations, since the standard SPI core interface is implemented with an assumption that there is no problem with the automatic CS toggling. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20201007235511.4935-19-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown <broonie@kernel.org>
2020-10-08spi: dw: Add memory operations supportSerge Semin
Aside from the synchronous Tx-Rx mode, which has been utilized to create the normal SPI transfers in the framework of the DW SSI driver, DW SPI controller supports Tx-only and EEPROM-read modes. The former one just enables the controller to transmit all the data from the Tx FIFO ignoring anything retrieved from the MISO lane. The later mode is so called write-then-read operation: DW SPI controller first pushes out all the data from the Tx FIFO, after that it'll automatically receive as much data as has been specified by means of the CTRLR1 register. Both of those modes can be used to implement the memory operations supported by the SPI-memory subsystem. The memory operation implementation is pretty much straightforward, except a few peculiarities we have had to take into account to make things working. Since DW SPI controller doesn't provide a way to directly set and clear the native CS lane level, but instead automatically de-asserts it when a transfer going on, we have to make sure the Tx FIFO isn't empty during entire Tx procedure. In addition we also need to read data from the Rx FIFO as fast as possible to prevent it' overflow with automatically fetched incoming traffic. The denoted peculiarities get to cause even more problems if DW SSI controller is equipped with relatively small FIFO and is connected to a relatively slow system bus (APB) (with respect to the SPI bus speed). In order to workaround the problems for as much as it's possible, the memory operation execution procedure collects all the Tx data into a single buffer and disables the local IRQs to speed the write-then-optionally-read method up. Note the provided memory operations are utilized by default only if a glue driver hasn't provided a custom version of ones and this is not a DW APB SSI controller with fixed automatic CS toggle functionality. Co-developed-by: Ramil Zaripov <Ramil.Zaripov@baikalelectronics.ru> Signed-off-by: Ramil Zaripov <Ramil.Zaripov@baikalelectronics.ru> Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20201007235511.4935-18-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown <broonie@kernel.org>
2020-10-08spi: dw: Add generic DW SSI status-check methodSerge Semin
The DW SSI errors handling method can be generically implemented for all types of the transfers: IRQ, DMA and poll-based ones. It will be a function which checks the overflow/underflow error flags and resets the controller if any of them is set. In the framework of this commit we make use of the new method to detect the errors in the IRQ- and DMA-based SPI transfer execution procedures. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20201007235511.4935-17-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown <broonie@kernel.org>
2020-10-08spi: dw: Explicitly de-assert CS on SPI transfer completionSerge Semin
By design of the currently available native set_cs callback, the CS de-assertion will be done only if it's required by the corresponding controller capability. But in order to pre-fill the Tx FIFO buffer with data during the SPI memory ops execution the SER register needs to be left cleared before that. We'll also need a way to explicitly set and clear the corresponding CS bit at a certain moment of the operation. Let's alter the set_cs function then to also de-activate the CS, when it's required. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20201007235511.4935-15-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown <broonie@kernel.org>
2020-10-08spi: dw: Discard chip enabling on DMA setup errorSerge Semin
It's pointless to enable the chip back if the DMA setup procedure fails, since we'll disable it on the next transfer anyway. For the same reason We don't do that in case of a failure detected in any other methods called from the transfer_one() method. While at it consider any non-zero value returned from the dma_setup callback to be erroneous as it's supposed to be in the kernel. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20201007235511.4935-13-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown <broonie@kernel.org>
2020-10-08spi: dw: Unmask IRQs after enabling the chipSerge Semin
It's theoretically erroneous to enable IRQ before the chip is turned on. If IRQ handler gets executed before the chip is enabled, then any data written to the Tx FIFO will be just ignored. I say "theoretically" because we haven't noticed any problem with that, but let's fix it anyway just in case... Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20201007235511.4935-12-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown <broonie@kernel.org>
2020-10-08spi: dw: Perform IRQ setup in a dedicated functionSerge Semin
In order to make the transfer_one() callback method more readable and for unification with the DMA-based transfer, let's detach the IRQ setup procedure into a dedicated function. While at it rename the IRQ-based transfer handler function to be dw_spi-prefixe and looking more like the DMA-related one. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20201007235511.4935-11-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown <broonie@kernel.org>
2020-10-08spi: dw: Refactor IRQ-based SPI transfer procedureSerge Semin
Current IRQ-based SPI transfer execution procedure doesn't work well at the final stage of the execution. If all the Tx data is sent out (written to the Tx FIFO) but there is some data left to receive, the Tx FIFO Empty IRQ will constantly happen until all of the requested inbound data is received. Though for a short period of time, but it will make the system less responsive. In order to fix that let's refactor the SPI transfer execution procedure by taking the Rx FIFO Full IRQ into account. We'll read and write SPI transfer data each time the IRQ happens as before. If all the outbound data is sent out, we'll disable the Tx FIFO Empty IRQ. If there is still some data to receive, we'll adjust the Rx FIFO Threshold level, so the next IRQ would be raised at the moment of all incoming data being available in the Rx FIFO. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20201007235511.4935-10-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown <broonie@kernel.org>
2020-10-08spi: dw: Refactor data IO procedureSerge Semin
The Tx and Rx data write/read procedure can be significantly simplified by using Tx/Rx transfer lengths instead of the end pointers. By having the Tx/Rx data leftover lengths (in the number of transfer words) we can get rid of all subtraction and division operations utilized here and there in the tx_max(), rx_max(), dw_writer() and dw_reader() methods. Such modification will not only give us the more optimized IO procedures, but will make the data IO methods much more readable than before. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20201007235511.4935-9-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown <broonie@kernel.org>
2020-10-08spi: dw: Add DW SPI controller config structureSerge Semin
DW APB SSI controller can be used by the two SPI core interfaces: traditional SPI transfers and SPI memory operations. The controller needs to be accordingly configured at runtime when the corresponding operations are executed. In order to do that for the both interfaces from a single function we introduce a new data wrapper for the transfer mode, data width, number of data frames (for the automatic data transfer) and the bus frequency. It will be used by the update_config() method to tune the DW APB SSI up. The update_config() method is made exported to be used not only by the DW SPI core driver, but by the glue layer drivers too. This will be required in a coming further commit. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20201007235511.4935-8-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown <broonie@kernel.org>
2020-10-08spi: dw: Update Rx sample delay in the config functionSerge Semin
Rx sample delay can be SPI device specific, and should be synchronously initialized with the rest of the communication and peripheral device related controller setups. So let's move the Rx-sample delay setup into the DW APB SSI configuration update method. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20201007235511.4935-7-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown <broonie@kernel.org>
2020-10-08spi: dw: Simplify the SPI bus speed config procedureSerge Semin
The code currently responsible for the SPI communication speed setting up is a bit messy. Most likely for some historical reason the bus frequency is saved in the peripheral chip private data. It's pointless now since the custom communication speed is a SPI-transfer-specific thing and only if there is no SPI transfer data specified (like during the SPI memory operations) it can be taken from the SPI device structure. But even in the later case there is no point in having the clock divider and the SPI bus frequency saved in the chip data, because the controller can be used for both SPI-transfer-based and SPI-transfer-less communications. From software point of view keeping the current clock divider in an SPI-device specific storage may give a small performance gain (to avoid sometimes a round-up division), but in comparison to the total SPI transfer time it just doesn't worth saving a few CPU cycles in comparison to the total SPI transfer time while having the harder to read code. The only optimization, which could worth preserving in the code is to avoid unnecessary DW SPI controller registers update if it's possible. So to speak let's simplify the SPI communication speed update procedure by removing the clock-related fields from the peripheral chip data and update the DW SPI clock divider only if it's really changed. The later change is reached by keeping the effective SPI bus speed in the internal DW SPI private data. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20201007235511.4935-6-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown <broonie@kernel.org>
2020-10-08spi: dw: Update SPI bus speed in a config functionSerge Semin
The SPI bus speed update functionality will be useful in another parts of the driver too (like to implement the SPI memory operations and from the DW SPI glue layers). Let's move it to the update_cr0() method then and since the later is now updating not only the CTRLR0 register alter its prototype to have a generic function name not related to CR0. Leave the too long line with the chip->clk_div setting as is for now, since it's going to be changed later anyway. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20201007235511.4935-5-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown <broonie@kernel.org>
2020-10-08spi: dw: Detach SPI device specific CR0 config methodSerge Semin
Indeed there is no point in detecting the SPI peripheral device parameters and initializing the CR0 register fields each time an SPI transfer is executed. Instead let's define a dedicated CR0 chip-data member, which will be initialized in accordance with the SPI device settings at the moment of setting it up. By doing so we'll finally make the SPI device chip_data serving as it's supposed to - to preserve the SPI device specific DW SPI configuration. See spi-fsl-dspi.c, spi-pl022.c, spi-pxa2xx.c drivers for example of the way the chip data is utilized. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20201007235511.4935-4-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown <broonie@kernel.org>
2020-10-08spi: dw: Add DWC SSI capabilitySerge Semin
Currently DWC SSI core is supported by means of setting up the core-specific update_cr0() callback. It isn't suitable for multiple reasons. First of all having exported several methods doing the same thing but for different chips makes the code harder to maintain. Secondly the spi-dw-core driver exports the methods, then the spi-dw-mmio driver sets the private data callback with one of them so to be called by the core driver again. That makes the code logic too complicated. Thirdly using callbacks for just updating the CR0 register is problematic, since in case if the register needed to be updated from different parts of the code, we'd have to create another callback (for instance the SPI device-specific parameters don't need to be calculated each time the SPI transfer is submitted, so it's better to pre-calculate the CR0 data at the SPI-device setup stage). So keeping all the above in mind let's discard the update_cr0() callbacks, define a generic and static dw_spi_update_cr0() method and create the DW_SPI_CAP_DWC_SSI capability, which when enabled would activate the alternative CR0 register layout. While at it add the comments to the code path of the normal DW APB SSI controller setup to make the dw_spi_update_cr0() method looking coherent. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20201007235511.4935-3-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown <broonie@kernel.org>
2020-10-08spi: dw: Use an explicit set_cs assignmentSerge Semin
Simplify the dw_spi_add_host() method a bit by replacing the currently implemented default set_cs callback setting up and later having it overwritten by a custom function with direct if-else-based callback assignment. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20201007235511.4935-2-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown <broonie@kernel.org>
2020-09-29spi: spi-dw: Remove extraneous lockingSerge Semin
There is no point in having the commit 19b61392c5a8 ("spi: spi-dw: Add lock protect dw_spi rx/tx to prevent concurrent calls") applied. The commit author made an assumption that the problem with the rx data mismatch was due to the lack of the data protection. While most likely it was caused by the lack of the memory barrier. So having the commit bfda044533b2 ("spi: dw: use "smp_mb()" to avoid sending spi data error") applied would be enough to fix the problem. Indeed the spin unlock operation makes sure each memory operation issued before the release will be completed before it's completed. In other words it works as an implicit one way memory barrier. So having both smp_mb() and the spin_unlock_irqrestore() here is just redundant. One of them would be enough. It's better to leave the smp_mb() since the Tx/Rx buffers consistency is provided by the data transfer algorithm implementation: first we initialize the buffers pointers, then make sure the assignments are visible by the other CPUs by calling the smp_mb(), only after that enable the interrupt, which handler uses the buffers. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20200920112914.26501-5-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown <broonie@kernel.org>
2020-09-29spi: dw: Add KeemBay Master capabilitySerge Semin
In a further commit we'll have to get rid of the update_cr0() callback and define a DW SSI capability instead. Since Keem Bay master/slave functionality is controller by the CTRL0 register bitfield, we need to first move the master mode selection into the internal corresponding update_cr0 method, which would be activated by means of the dedicated DW_SPI_CAP_KEEMBAY_MST capability setup. Note this will be also useful if the driver will be ever altered to support the DW SPI slave interface. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20200920112914.26501-11-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown <broonie@kernel.org>
2020-09-29spi: dw: Convert CS-override to DW SPI capabilitiesSerge Semin
There are several vendor-specific versions of the DW SPI controllers, each of which may have some peculiarities with respect to the original IP-core. Seeing it has already caused adding flags and a callback into the DW SPI private data, let's introduce a generic capabilities interface to tune the generic DW SPI controller driver up in accordance with the particular controller specifics. It's done by converting a simple Alpine-specific CS-override capability into the DW SPI controller capability activated by setting the DW_SPI_CAP_CS_OVERRIDE flag. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20200920112914.26501-10-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown <broonie@kernel.org>
2020-09-29spi: dw: Discard DW SSI chip type storagesSerge Semin
Keeping SPI peripheral devices type is pointless since first it hasn't been functionally utilized by any of the client drivers/code and second it won't work for Microwire type at the very least. Moreover there is no point in setting up the type by means of the chip-data in the modern kernel. The peripheral devices with specific interface type need to be detected in order to activate the corresponding frame format. It most likely will require some peripheral device specific DT property or whatever to find out the interface protocol. So let's remove the serial interface type fields from the DW APB SSI controller and the SPI peripheral device private data. Note we'll preserve the explicit SSI_MOTO_SPI interface type setting up to signify the only currently supported interface protocol. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20200920112914.26501-9-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown <broonie@kernel.org>
2020-09-29spi: dw: Disable all IRQs when controller is unusedSerge Semin
It's a good practice to disable all IRQs if a device is fully unused. In our case it is supposed to be done before requesting the IRQ and after the last byte of an SPI transfer is received. In the former case it's required to prevent the IRQ handler invocation before the driver data is fully initialized (which may happen if the IRQs status has been left uncleared before the device is probed). So we just moved the spi_hw_init() method invocation to the earlier stage before requesting the IRQ. In the later case there is just no point in having any of the IRQs enabled between SPI transfers and when there is no SPI message currently being processed. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20200920112914.26501-7-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown <broonie@kernel.org>
2020-09-29spi: dw: Initialize n_bytes before the memory barrierSerge Semin
Since n_bytes field of the DW SPI private data is also utilized by the IRQ handler, we need to make sure it' initialization is done before the memory barrier. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Link: https://lore.kernel.org/r/20200920112914.26501-4-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown <broonie@kernel.org>
2020-09-08spi: dw: Add support for RX sample delay registerLars Povlsen
This add support for the RX_SAMPLE_DLY register. If enabled in the Designware IP, it allows tuning of the rx data signal by means of an internal rx sample fifo. The register is controlled by the rx-sample-delay-ns DT property, which is defined per SPI slave as well on controller level. The controller level rx-sample-delay-ns will apply to all slaves without the property explicitly defined. The register is located at offset 0xf0, and if the option is not enabled in the IP, changing the register will have no effect. The register will only be written if any slave defines a nonzero value (after scaling by the clock period). Signed-off-by: Lars Povlsen <lars.povlsen@microchip.com> Link: https://lore.kernel.org/r/20200824203010.2033-2-lars.povlsen@microchip.com Signed-off-by: Mark Brown <broonie@kernel.org>
2020-05-30Merge remote-tracking branch 'spi/for-5.8' into spi-nextMark Brown
2020-05-29spi: dw: Use regset32 DebugFS method to create regdump fileSerge Semin
DebugFS kernel interface provides a dedicated method to create the registers dump file. Use it instead of creating a generic DebugFS file with manually written read callback function. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Cc: Georgy Vlasov <Georgy.Vlasov@baikalelectronics.ru> Cc: Ramil Zaripov <Ramil.Zaripov@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Feng Tang <feng.tang@intel.com> Cc: Rob Herring <robh+dt@kernel.org> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200529131205.31838-16-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown <broonie@kernel.org>
2020-05-29spi: dw: Add core suffix to the DW APB SSI core source fileSerge Semin
Generic DMA support is going to be part of the DW APB SSI core object. In order to preserve the kernel loadable module name as spi-dw.ko, let's add the "-core" suffix to the object with generic DW APB SSI code and build it into the target spi-dw.ko driver. Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Cc: Georgy Vlasov <Georgy.Vlasov@baikalelectronics.ru> Cc: Ramil Zaripov <Ramil.Zaripov@baikalelectronics.ru> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru> Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de> Cc: Feng Tang <feng.tang@intel.com> Cc: Rob Herring <robh+dt@kernel.org> Cc: Arnd Bergmann <arnd@arndb.de> Cc: linux-mips@vger.kernel.org Cc: devicetree@vger.kernel.org Link: https://lore.kernel.org/r/20200529131205.31838-10-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown <broonie@kernel.org>