diff mbox series

[2/3] spi: spi-imx: add support for SPI_MOSI_IDLE_LOW mode bit

Message ID 20230517103007.26287-2-boerge.struempfel@gmail.com (mailing list archive)
State Superseded
Headers show
Series [1/3] spi: add SPI_MOSI_IDLE_LOW mode bit | expand

Commit Message

Boerge Struempfel May 17, 2023, 10:30 a.m. UTC
By default, the spi-imx controller pulls the mosi line high, whenever it
is idle. This behaviour can be inverted per CS by setting the
corresponding DATA_CTL bit in the config register of the controller.

Also, since the controller mode-bits have to be touched anyways, the
SPI_CPOL and SPI_CPHA are replaced by the combined SPI_MODE_X_MASK flag.

Signed-off-by: Boerge Struempfel <boerge.struempfel@gmail.com>
---
 drivers/spi/spi-imx.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

Comments

kernel test robot May 17, 2023, 5:22 p.m. UTC | #1
Hi Boerge,

kernel test robot noticed the following build errors:

[auto build test ERROR on broonie-spi/for-next]
[also build test ERROR on shawnguo/for-next linus/master v6.4-rc2 next-20230517]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Boerge-Struempfel/spi-spi-imx-add-support-for-SPI_MOSI_IDLE_LOW-mode-bit/20230517-183245
base:   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next
patch link:    https://lore.kernel.org/r/20230517103007.26287-2-boerge.struempfel%40gmail.com
patch subject: [PATCH 2/3] spi: spi-imx: add support for SPI_MOSI_IDLE_LOW mode bit
config: riscv-randconfig-r001-20230517
compiler: clang version 17.0.0 (https://github.com/llvm/llvm-project b0fb98227c90adf2536c9ad644a74d5e92961111)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install riscv cross compiling tool for clang build
        # apt-get install binutils-riscv64-linux-gnu
        # https://github.com/intel-lab-lkp/linux/commit/62dc97266153cfe514c983e9baeb51766f16daa2
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Boerge-Struempfel/spi-spi-imx-add-support-for-SPI_MOSI_IDLE_LOW-mode-bit/20230517-183245
        git checkout 62dc97266153cfe514c983e9baeb51766f16daa2
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=riscv olddefconfig
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=riscv SHELL=/bin/bash drivers/spi/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202305180035.jUAVfUNY-lkp@intel.com/

All errors (new ones prefixed by >>):

>> drivers/spi/spi-imx.c:580:11: error: unterminated function-like macro invocation
                   cfg &= ~MX51_ECSPI_CONFIG_DATACTL(spi_get_chipselect(spi, 0);
                           ^
   drivers/spi/spi-imx.c:284:9: note: macro 'MX51_ECSPI_CONFIG_DATACTL' defined here
   #define MX51_ECSPI_CONFIG_DATACTL(cs)   (1 << ((cs & 3) + 16))
           ^
>> drivers/spi/spi-imx.c:1956:39: error: expected expression
   MODULE_ALIAS("platform:" DRIVER_NAME);
                                         ^
>> drivers/spi/spi-imx.c:1956:39: error: expected '}'
   drivers/spi/spi-imx.c:522:1: note: to match this '{'
   {
   ^
   3 errors generated.


vim +580 drivers/spi/spi-imx.c

   519	
   520	static int mx51_ecspi_prepare_message(struct spi_imx_data *spi_imx,
   521					      struct spi_message *msg)
   522	{
   523		struct spi_device *spi = msg->spi;
   524		struct spi_transfer *xfer;
   525		u32 ctrl = MX51_ECSPI_CTRL_ENABLE;
   526		u32 min_speed_hz = ~0U;
   527		u32 testreg, delay;
   528		u32 cfg = readl(spi_imx->base + MX51_ECSPI_CONFIG);
   529		u32 current_cfg = cfg;
   530	
   531		/* set Master or Slave mode */
   532		if (spi_imx->slave_mode)
   533			ctrl &= ~MX51_ECSPI_CTRL_MODE_MASK;
   534		else
   535			ctrl |= MX51_ECSPI_CTRL_MODE_MASK;
   536	
   537		/*
   538		 * Enable SPI_RDY handling (falling edge/level triggered).
   539		 */
   540		if (spi->mode & SPI_READY)
   541			ctrl |= MX51_ECSPI_CTRL_DRCTL(spi_imx->spi_drctl);
   542	
   543		/* set chip select to use */
   544		ctrl |= MX51_ECSPI_CTRL_CS(spi_get_chipselect(spi, 0));
   545	
   546		/*
   547		 * The ctrl register must be written first, with the EN bit set other
   548		 * registers must not be written to.
   549		 */
   550		writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL);
   551	
   552		testreg = readl(spi_imx->base + MX51_ECSPI_TESTREG);
   553		if (spi->mode & SPI_LOOP)
   554			testreg |= MX51_ECSPI_TESTREG_LBC;
   555		else
   556			testreg &= ~MX51_ECSPI_TESTREG_LBC;
   557		writel(testreg, spi_imx->base + MX51_ECSPI_TESTREG);
   558	
   559		/*
   560		 * eCSPI burst completion by Chip Select signal in Slave mode
   561		 * is not functional for imx53 Soc, config SPI burst completed when
   562		 * BURST_LENGTH + 1 bits are received
   563		 */
   564		if (spi_imx->slave_mode && is_imx53_ecspi(spi_imx))
   565			cfg &= ~MX51_ECSPI_CONFIG_SBBCTRL(spi_get_chipselect(spi, 0));
   566		else
   567			cfg |= MX51_ECSPI_CONFIG_SBBCTRL(spi_get_chipselect(spi, 0));
   568	
   569		if (spi->mode & SPI_CPOL) {
   570			cfg |= MX51_ECSPI_CONFIG_SCLKPOL(spi_get_chipselect(spi, 0));
   571			cfg |= MX51_ECSPI_CONFIG_SCLKCTL(spi_get_chipselect(spi, 0));
   572		} else {
   573			cfg &= ~MX51_ECSPI_CONFIG_SCLKPOL(spi_get_chipselect(spi, 0));
   574			cfg &= ~MX51_ECSPI_CONFIG_SCLKCTL(spi_get_chipselect(spi, 0));
   575		}
   576	
   577		if (spi->mode & SPI_MOSI_IDLE_LOW)
   578			cfg |= MX51_ECSPI_CONFIG_DATACTL(spi_get_chipselect(spi, 0));
   579		else
 > 580			cfg &= ~MX51_ECSPI_CONFIG_DATACTL(spi_get_chipselect(spi, 0);
   581	
   582		if (spi->mode & SPI_CS_HIGH)
   583			cfg |= MX51_ECSPI_CONFIG_SSBPOL(spi_get_chipselect(spi, 0));
   584		else
   585			cfg &= ~MX51_ECSPI_CONFIG_SSBPOL(spi_get_chipselect(spi, 0));
   586	
   587		if (cfg == current_cfg)
   588			return 0;
   589	
   590		writel(cfg, spi_imx->base + MX51_ECSPI_CONFIG);
   591	
   592		/*
   593		 * Wait until the changes in the configuration register CONFIGREG
   594		 * propagate into the hardware. It takes exactly one tick of the
   595		 * SCLK clock, but we will wait two SCLK clock just to be sure. The
   596		 * effect of the delay it takes for the hardware to apply changes
   597		 * is noticable if the SCLK clock run very slow. In such a case, if
   598		 * the polarity of SCLK should be inverted, the GPIO ChipSelect might
   599		 * be asserted before the SCLK polarity changes, which would disrupt
   600		 * the SPI communication as the device on the other end would consider
   601		 * the change of SCLK polarity as a clock tick already.
   602		 *
   603		 * Because spi_imx->spi_bus_clk is only set in prepare_message
   604		 * callback, iterate over all the transfers in spi_message, find the
   605		 * one with lowest bus frequency, and use that bus frequency for the
   606		 * delay calculation. In case all transfers have speed_hz == 0, then
   607		 * min_speed_hz is ~0 and the resulting delay is zero.
   608		 */
   609		list_for_each_entry(xfer, &msg->transfers, transfer_list) {
   610			if (!xfer->speed_hz)
   611				continue;
   612			min_speed_hz = min(xfer->speed_hz, min_speed_hz);
   613		}
   614	
   615		delay = (2 * 1000000) / min_speed_hz;
   616		if (likely(delay < 10))	/* SCLK is faster than 200 kHz */
   617			udelay(delay);
   618		else			/* SCLK is _very_ slow */
   619			usleep_range(delay, delay + 10);
   620	
   621		return 0;
   622	}
   623
kernel test robot May 17, 2023, 5:46 p.m. UTC | #2
Hi Boerge,

kernel test robot noticed the following build errors:

[auto build test ERROR on broonie-spi/for-next]
[also build test ERROR on shawnguo/for-next linus/master v6.4-rc2 next-20230517]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Boerge-Struempfel/spi-spi-imx-add-support-for-SPI_MOSI_IDLE_LOW-mode-bit/20230517-183245
base:   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next
patch link:    https://lore.kernel.org/r/20230517103007.26287-2-boerge.struempfel%40gmail.com
patch subject: [PATCH 2/3] spi: spi-imx: add support for SPI_MOSI_IDLE_LOW mode bit
config: m68k-allyesconfig
compiler: m68k-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/62dc97266153cfe514c983e9baeb51766f16daa2
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Boerge-Struempfel/spi-spi-imx-add-support-for-SPI_MOSI_IDLE_LOW-mode-bit/20230517-183245
        git checkout 62dc97266153cfe514c983e9baeb51766f16daa2
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=m68k olddefconfig
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=m68k SHELL=/bin/bash drivers/spi/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202305180132.mcBZduH0-lkp@intel.com/

All errors (new ones prefixed by >>):

   drivers/spi/spi-imx.c: In function 'mx51_ecspi_prepare_message':
>> drivers/spi/spi-imx.c:1956:39: error: unterminated argument list invoking macro "MX51_ECSPI_CONFIG_DATACTL"
    1956 | MODULE_ALIAS("platform:" DRIVER_NAME);
         |                                       ^
>> drivers/spi/spi-imx.c:580:25: error: 'MX51_ECSPI_CONFIG_DATACTL' undeclared (first use in this function)
     580 |                 cfg &= ~MX51_ECSPI_CONFIG_DATACTL(spi_get_chipselect(spi, 0);
         |                         ^~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/spi/spi-imx.c:580:25: note: each undeclared identifier is reported only once for each function it appears in
>> drivers/spi/spi-imx.c:580:50: error: expected ';' at end of input
     580 |                 cfg &= ~MX51_ECSPI_CONFIG_DATACTL(spi_get_chipselect(spi, 0);
         |                                                  ^
         |                                                  ;
   ......
   drivers/spi/spi-imx.c:579:9: note: '-Wmisleading-indentation' is disabled from this point onwards, since column-tracking was disabled due to the size of the code/headers
     579 |         else
         |         ^~~~
   drivers/spi/spi-imx.c:579:9: note: adding '-flarge-source-files' will allow for more column-tracking support, at the expense of compilation time and memory
>> drivers/spi/spi-imx.c:580:17: error: expected declaration or statement at end of input
     580 |                 cfg &= ~MX51_ECSPI_CONFIG_DATACTL(spi_get_chipselect(spi, 0);
         |                 ^~~
   drivers/spi/spi-imx.c:529:13: warning: unused variable 'current_cfg' [-Wunused-variable]
     529 |         u32 current_cfg = cfg;
         |             ^~~~~~~~~~~
   drivers/spi/spi-imx.c:527:22: warning: unused variable 'delay' [-Wunused-variable]
     527 |         u32 testreg, delay;
         |                      ^~~~~
   drivers/spi/spi-imx.c:526:13: warning: unused variable 'min_speed_hz' [-Wunused-variable]
     526 |         u32 min_speed_hz = ~0U;
         |             ^~~~~~~~~~~~
   drivers/spi/spi-imx.c:524:30: warning: unused variable 'xfer' [-Wunused-variable]
     524 |         struct spi_transfer *xfer;
         |                              ^~~~
   drivers/spi/spi-imx.c:580:17: error: no return statement in function returning non-void [-Werror=return-type]
     580 |                 cfg &= ~MX51_ECSPI_CONFIG_DATACTL(spi_get_chipselect(spi, 0);
         |                 ^~~
   drivers/spi/spi-imx.c: At top level:
   drivers/spi/spi-imx.c:520:12: warning: 'mx51_ecspi_prepare_message' defined but not used [-Wunused-function]
     520 | static int mx51_ecspi_prepare_message(struct spi_imx_data *spi_imx,
         |            ^~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/spi/spi-imx.c:511:13: warning: 'mx51_ecspi_disable' defined but not used [-Wunused-function]
     511 | static void mx51_ecspi_disable(struct spi_imx_data *spi_imx)
         |             ^~~~~~~~~~~~~~~~~~
   drivers/spi/spi-imx.c:502:13: warning: 'mx51_ecspi_trigger' defined but not used [-Wunused-function]
     502 | static void mx51_ecspi_trigger(struct spi_imx_data *spi_imx)
         |             ^~~~~~~~~~~~~~~~~~
   drivers/spi/spi-imx.c:486:13: warning: 'mx51_ecspi_intctrl' defined but not used [-Wunused-function]
     486 | static void mx51_ecspi_intctrl(struct spi_imx_data *spi_imx, int enable)
         |             ^~~~~~~~~~~~~~~~~~
   drivers/spi/spi-imx.c:449:21: warning: 'mx51_ecspi_clkdiv' defined but not used [-Wunused-function]
     449 | static unsigned int mx51_ecspi_clkdiv(struct spi_imx_data *spi_imx,
         |                     ^~~~~~~~~~~~~~~~~
   drivers/spi/spi-imx.c:428:13: warning: 'mx53_ecspi_tx_slave' defined but not used [-Wunused-function]
     428 | static void mx53_ecspi_tx_slave(struct spi_imx_data *spi_imx)
         |             ^~~~~~~~~~~~~~~~~~~
   drivers/spi/spi-imx.c:408:13: warning: 'mx53_ecspi_rx_slave' defined but not used [-Wunused-function]
     408 | static void mx53_ecspi_rx_slave(struct spi_imx_data *spi_imx)
         |             ^~~~~~~~~~~~~~~~~~~
   drivers/spi/spi-imx.c:380:13: warning: 'spi_imx_buf_tx_swap' defined but not used [-Wunused-function]
     380 | static void spi_imx_buf_tx_swap(struct spi_imx_data *spi_imx)
         |             ^~~~~~~~~~~~~~~~~~~
   drivers/spi/spi-imx.c:328:13: warning: 'spi_imx_buf_rx_swap' defined but not used [-Wunused-function]
     328 | static void spi_imx_buf_rx_swap(struct spi_imx_data *spi_imx)
         |             ^~~~~~~~~~~~~~~~~~~
   drivers/spi/spi-imx.c:233:13: warning: 'spi_imx_can_dma' defined but not used [-Wunused-function]
     233 | static bool spi_imx_can_dma(struct spi_controller *controller, struct spi_device *spi,
         |             ^~~~~~~~~~~~~~~
   drivers/spi/spi-imx.c:207:21: warning: 'spi_imx_clkdiv_2' defined but not used [-Wunused-function]
     207 | static unsigned int spi_imx_clkdiv_2(unsigned int fin,
         |                     ^~~~~~~~~~~~~~~~
   drivers/spi/spi-imx.c:193:21: warning: 'spi_imx_clkdiv_1' defined but not used [-Wunused-function]
     193 | static unsigned int spi_imx_clkdiv_1(unsigned int fin,
         |                     ^~~~~~~~~~~~~~~~
   drivers/spi/spi-imx.c:165:13: warning: 'spi_imx_buf_tx_u32' defined but not used [-Wunused-function]
     165 | static void spi_imx_buf_tx_##type(struct spi_imx_data *spi_imx)         \
         |             ^~~~~~~~~~~~~~~
   drivers/spi/spi-imx.c:184:1: note: in expansion of macro 'MXC_SPI_BUF_TX'
     184 | MXC_SPI_BUF_TX(u32)
         | ^~~~~~~~~~~~~~
   drivers/spi/spi-imx.c:152:13: warning: 'spi_imx_buf_rx_u32' defined but not used [-Wunused-function]
     152 | static void spi_imx_buf_rx_##type(struct spi_imx_data *spi_imx)         \
         |             ^~~~~~~~~~~~~~~
   drivers/spi/spi-imx.c:183:1: note: in expansion of macro 'MXC_SPI_BUF_RX'
     183 | MXC_SPI_BUF_RX(u32)
         | ^~~~~~~~~~~~~~
   drivers/spi/spi-imx.c:165:13: warning: 'spi_imx_buf_tx_u8' defined but not used [-Wunused-function]
     165 | static void spi_imx_buf_tx_##type(struct spi_imx_data *spi_imx)         \
         |             ^~~~~~~~~~~~~~~
   drivers/spi/spi-imx.c:180:1: note: in expansion of macro 'MXC_SPI_BUF_TX'
     180 | MXC_SPI_BUF_TX(u8)
         | ^~~~~~~~~~~~~~
   drivers/spi/spi-imx.c:152:13: warning: 'spi_imx_buf_rx_u8' defined but not used [-Wunused-function]
     152 | static void spi_imx_buf_rx_##type(struct spi_imx_data *spi_imx)         \
         |             ^~~~~~~~~~~~~~~
   drivers/spi/spi-imx.c:179:1: note: in expansion of macro 'MXC_SPI_BUF_RX'
     179 | MXC_SPI_BUF_RX(u8)
         | ^~~~~~~~~~~~~~
   cc1: some warnings being treated as errors


vim +/MX51_ECSPI_CONFIG_DATACTL +1956 drivers/spi/spi-imx.c

b5f3294f0be549 drivers/spi/mxc_spi.c Sascha Hauer  2009-09-22  1952  
92bad4a4c755cd drivers/spi/spi-imx.c Fabio Estevam 2021-03-16  1953  MODULE_DESCRIPTION("i.MX SPI Controller driver");
b5f3294f0be549 drivers/spi/mxc_spi.c Sascha Hauer  2009-09-22  1954  MODULE_AUTHOR("Sascha Hauer, Pengutronix");
b5f3294f0be549 drivers/spi/mxc_spi.c Sascha Hauer  2009-09-22  1955  MODULE_LICENSE("GPL");
3133fba3bb3a37 drivers/spi/spi-imx.c Fabio Estevam 2013-01-07 @1956  MODULE_ALIAS("platform:" DRIVER_NAME);
diff mbox series

Patch

diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
index 34e5f81ec431..e5e55d66fecc 100644
--- a/drivers/spi/spi-imx.c
+++ b/drivers/spi/spi-imx.c
@@ -281,6 +281,7 @@  static bool spi_imx_can_dma(struct spi_controller *controller, struct spi_device
 #define MX51_ECSPI_CONFIG_SCLKPOL(cs)	(1 << ((cs & 3) +  4))
 #define MX51_ECSPI_CONFIG_SBBCTRL(cs)	(1 << ((cs & 3) +  8))
 #define MX51_ECSPI_CONFIG_SSBPOL(cs)	(1 << ((cs & 3) + 12))
+#define MX51_ECSPI_CONFIG_DATACTL(cs)	(1 << ((cs & 3) + 16))
 #define MX51_ECSPI_CONFIG_SCLKCTL(cs)	(1 << ((cs & 3) + 20))
 
 #define MX51_ECSPI_INT		0x10
@@ -573,6 +574,11 @@  static int mx51_ecspi_prepare_message(struct spi_imx_data *spi_imx,
 		cfg &= ~MX51_ECSPI_CONFIG_SCLKCTL(spi_get_chipselect(spi, 0));
 	}
 
+	if (spi->mode & SPI_MOSI_IDLE_LOW)
+		cfg |= MX51_ECSPI_CONFIG_DATACTL(spi_get_chipselect(spi, 0));
+	else
+		cfg &= ~MX51_ECSPI_CONFIG_DATACTL(spi_get_chipselect(spi, 0);
+
 	if (spi->mode & SPI_CS_HIGH)
 		cfg |= MX51_ECSPI_CONFIG_SSBPOL(spi_get_chipselect(spi, 0));
 	else
@@ -1743,7 +1749,8 @@  static int spi_imx_probe(struct platform_device *pdev)
 	spi_imx->controller->prepare_message = spi_imx_prepare_message;
 	spi_imx->controller->unprepare_message = spi_imx_unprepare_message;
 	spi_imx->controller->slave_abort = spi_imx_slave_abort;
-	spi_imx->controller->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_NO_CS;
+	spi_imx->controller->mode_bits = SPI_MODE_X_MASK | SPI_CS_HIGH | SPI_NO_CS |
+					 SPI_MOSI_IDLE_LOW;
 
 	if (is_imx35_cspi(spi_imx) || is_imx51_ecspi(spi_imx) ||
 	    is_imx53_ecspi(spi_imx))