RE: [PATCH v2 2/5] spi: imx: mx51-ecspi: Move some initialisation to prepare_message hook.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




> -----Original Message-----
> From: Uwe Kleine-König <u.kleine-koenig@xxxxxxxxxxxxxx>
> Sent: 2018年11月23日 16:52
> To: Mark Brown <broonie@xxxxxxxxxx>; Robin Gong <yibin.gong@xxxxxxx>
> Cc: Marek Vasut <marex@xxxxxxx>; dl-linux-imx <linux-imx@xxxxxxx>;
> kernel@xxxxxxxxxxxxxx; linux-spi@xxxxxxxxxxxxxxx
> Subject: [PATCH v2 2/5] spi: imx: mx51-ecspi: Move some initialisation to
> prepare_message hook.
> 
> The relevant difference between prepare_message and config is that the
> former is run before the CS signal is asserted. So the polarity of the CLK line
> must be configured in prepare_message as an edge generated by config might
> already result in a latch of the MOSI line.
Is this a real problem fix patch or just refine in theory? I have quick test and 
saw a big performance downgrade below on i.mx6sl-evk board(1.6MB/s->706KB/s)

root@imx6qpdlsolox:~# dd if=/dev/mtd0 of=/dev/null bs=1M count=1
1+0 records in
1+0 records out
1048576 bytes (1.0 MB, 1.0 MiB) copied, 1.48557 s, 706 kB/s
> 
> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@xxxxxxxxxxxxxx>
> ---
>  drivers/spi/spi-imx.c | 55 ++++++++++++++++++++++++++-----------------
>  1 file changed, 33 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index
> c7db42d6b3bc..88a7a53441f5 100644
> --- a/drivers/spi/spi-imx.c
> +++ b/drivers/spi/spi-imx.c
> @@ -490,14 +490,9 @@ static void mx51_ecspi_disable(struct spi_imx_data
> *spi_imx)  static int mx51_ecspi_prepare_message(struct spi_imx_data
> *spi_imx,
>  				      struct spi_message *msg)
>  {
> -	return 0;
> -}
> -
> -static int mx51_ecspi_config(struct spi_device *spi) -{
> -	struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master);
> +	struct spi_device *spi = msg->spi;
>  	u32 ctrl = MX51_ECSPI_CTRL_ENABLE;
> -	u32 clk = spi_imx->speed_hz, delay, reg;
> +	u32 testreg;
>  	u32 cfg = readl(spi_imx->base + MX51_ECSPI_CONFIG);
> 
>  	/* set Master or Slave mode */
> @@ -512,10 +507,6 @@ static int mx51_ecspi_config(struct spi_device *spi)
>  	if (spi->mode & SPI_READY)
>  		ctrl |= MX51_ECSPI_CTRL_DRCTL(spi_imx->spi_drctl);
> 
> -	/* set clock speed */
> -	ctrl |= mx51_ecspi_clkdiv(spi_imx, spi_imx->speed_hz, &clk);
> -	spi_imx->spi_bus_clk = clk;
> -
>  	/* set chip select to use */
>  	ctrl |= MX51_ECSPI_CTRL_CS(spi->chip_select);
> 
> @@ -526,6 +517,19 @@ static int mx51_ecspi_config(struct spi_device *spi)
>  		ctrl |= (spi_imx->bits_per_word - 1)
>  			<< MX51_ECSPI_CTRL_BL_OFFSET;
> 
> +	/*
> +	 * The ctrl register must be written first, with the EN bit set other
> +	 * registers must not be written to.
> +	 */
> +	writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL);
> +
> +	testreg = readl(spi_imx->base + MX51_ECSPI_TESTREG);
> +	if (spi->mode & SPI_LOOP)
> +		testreg |= MX51_ECSPI_TESTREG_LBC;
> +	else
> +		testreg &= ~MX51_ECSPI_TESTREG_LBC;
> +	writel(testreg, spi_imx->base + MX51_ECSPI_TESTREG);
> +
>  	/*
>  	 * eCSPI burst completion by Chip Select signal in Slave mode
>  	 * is not functional for imx53 Soc, config SPI burst completed when @@
> -548,26 +552,34 @@ static int mx51_ecspi_config(struct spi_device *spi)
>  		cfg &= ~MX51_ECSPI_CONFIG_SCLKPOL(spi->chip_select);
>  		cfg &= ~MX51_ECSPI_CONFIG_SCLKCTL(spi->chip_select);
>  	}
> +
>  	if (spi->mode & SPI_CS_HIGH)
>  		cfg |= MX51_ECSPI_CONFIG_SSBPOL(spi->chip_select);
>  	else
>  		cfg &= ~MX51_ECSPI_CONFIG_SSBPOL(spi->chip_select);
> 
> +	writel(cfg, spi_imx->base + MX51_ECSPI_CONFIG);
> +
> +	return 0;
> +}
> +
> +static int mx51_ecspi_config(struct spi_device *spi) {
> +	struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master);
> +	u32 ctrl = readl(spi_imx->base + MX51_ECSPI_CTRL);
> +	u32 clk = spi_imx->speed_hz, delay;
> +
> +	/* set clock speed */
> +	ctrl &= ~(0xf << MX51_ECSPI_CTRL_POSTDIV_OFFSET |
> +		  0xf << MX51_ECSPI_CTRL_PREDIV_OFFSET);
> +	ctrl |= mx51_ecspi_clkdiv(spi_imx, spi_imx->speed_hz, &clk);
> +	spi_imx->spi_bus_clk = clk;
> +
>  	if (spi_imx->usedma)
>  		ctrl |= MX51_ECSPI_CTRL_SMC;
> 
> -	/* CTRL register always go first to bring out controller from reset */
>  	writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL);
> 
> -	reg = readl(spi_imx->base + MX51_ECSPI_TESTREG);
> -	if (spi->mode & SPI_LOOP)
> -		reg |= MX51_ECSPI_TESTREG_LBC;
> -	else
> -		reg &= ~MX51_ECSPI_TESTREG_LBC;
> -	writel(reg, spi_imx->base + MX51_ECSPI_TESTREG);
> -
> -	writel(cfg, spi_imx->base + MX51_ECSPI_CONFIG);
> -
>  	/*
>  	 * Wait until the changes in the configuration register CONFIGREG
>  	 * propagate into the hardware. It takes exactly one tick of the @@
> -594,7 +606,6 @@ static void mx51_setup_wml(struct spi_imx_data *spi_imx)
>  	 * Configure the DMA register: setup the watermark
>  	 * and enable DMA request.
>  	 */
> -
>  	writel(MX51_ECSPI_DMA_RX_WML(spi_imx->wml - 1) |
>  		MX51_ECSPI_DMA_TX_WML(spi_imx->wml) |
>  		MX51_ECSPI_DMA_RXT_WML(spi_imx->wml) |
> --
> 2.19.1





[Index of Archives]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux