diff mbox

spi: s3c64xx: add support for exynos7 SPI controller

Message ID 1415267509-16653-1-git-send-email-padma.v@samsung.com (mailing list archive)
State New, archived
Headers show

Commit Message

padma venkat Nov. 6, 2014, 9:51 a.m. UTC
Exynos7 SPI controller supports only the auto Selection of
CS toggle mode and Exynos7 SoC includes six SPI controllers.
Add support for these changes in Exynos7 SPI controller driver.

Signed-off-by: Padmavathi Venna <padma.v@samsung.com>
---
 .../devicetree/bindings/spi/spi-samsung.txt        |    2 +-
 drivers/spi/Kconfig                                |    2 +-
 drivers/spi/spi-s3c64xx.c                          |   32 ++++++++++++++++---
 3 files changed, 29 insertions(+), 7 deletions(-)

Comments

Mark Brown Nov. 6, 2014, 10:26 a.m. UTC | #1
On Thu, Nov 06, 2014 at 03:21:49PM +0530, Padmavathi Venna wrote:
> Exynos7 SPI controller supports only the auto Selection of
> CS toggle mode and Exynos7 SoC includes six SPI controllers.
> Add support for these changes in Exynos7 SPI controller driver.

Could you give a bit more detail on what the "auto selection of CS
toggle mode" is - in the diff it looks like it's not an existing mode.
I'm a bit worried that it's not going to function well with devices that
send more than one transfer per message.

> Signed-off-by: Padmavathi Venna <padma.v@samsung.com>

It's better if your signoff is using the same e-maill address as
padma venkat Nov. 7, 2014, 8:31 a.m. UTC | #2
Hi Mark,

CCing Kukjin Kim.

On 11/6/14, Mark Brown <broonie@kernel.org> wrote:
> On Thu, Nov 06, 2014 at 03:21:49PM +0530, Padmavathi Venna wrote:
>> Exynos7 SPI controller supports only the auto Selection of
>> CS toggle mode and Exynos7 SoC includes six SPI controllers.
>> Add support for these changes in Exynos7 SPI controller driver.
>
> Could you give a bit more detail on what the "auto selection of CS
> toggle mode" is - in the diff it looks like it's not an existing mode.
> I'm a bit worried that it's not going to function well with devices that
> send more than one transfer per message.

There is a bit AUTO_N_MANUAL(as per manual) in the spi CS_CFG
register(as per manual, in the driver it is S3C64XX_SPI_SLAVE_SEL) to
control the CS toggle mode either manually or automatically. If CS has
to be controlled manually the AUTO_N_MANUAL should be set to 0 which
the driver is doing in the s3c64xx_spi_transfer_one function by
writing 0 in the S3C64XX_SPI_SLAVE_SEL. When it is handled manually
NSSOUT as per the manual(in the driver it is
S3C64XX_SPI_SLAVE_SIG_INACT) controls the level of CS which when set
deactivates the signal and reset activates.

CS can also be controlled automatically by setting AUTO_N_MANUAL to 1
in CS_CFG. When it is auto CS automatically toggles between packet to
packet. NCS_TIME_COUNT in CS_CFG controls the inactive period. The
driver by default uses manual mode. But on exynos7 the manual mode is
removed.

I tested the driver with wm5110 codec.

>
>> Signed-off-by: Padmavathi Venna <padma.v@samsung.com>
>
> It's better if your signoff is using the same e-maill address as

ok.  I will take care of this.

>

Thanks
Padma
Mark Brown Nov. 7, 2014, 10:13 a.m. UTC | #3
On Fri, Nov 07, 2014 at 02:01:57PM +0530, Padma Venkat wrote:

> CS can also be controlled automatically by setting AUTO_N_MANUAL to 1
> in CS_CFG. When it is auto CS automatically toggles between packet to
> packet. NCS_TIME_COUNT in CS_CFG controls the inactive period. The
> driver by default uses manual mode. But on exynos7 the manual mode is
> removed.

OK, but what's a packet here?

> I tested the driver with wm5110 codec.

Did you try firmware downloads or something else that generates multiple
transfers in a message?  Normal register writes will use a single
transfer so I'd expect them to just work.
padma venkat Nov. 10, 2014, 4:50 a.m. UTC | #4
Hi Mark,

On 11/7/14, Mark Brown <broonie@kernel.org> wrote:
> On Fri, Nov 07, 2014 at 02:01:57PM +0530, Padma Venkat wrote:
>
>> CS can also be controlled automatically by setting AUTO_N_MANUAL to 1
>> in CS_CFG. When it is auto CS automatically toggles between packet to
>> packet. NCS_TIME_COUNT in CS_CFG controls the inactive period. The
>> driver by default uses manual mode. But on exynos7 the manual mode is
>> removed.
>
> OK, but what's a packet here?

Packet is either 1 byte or 4 bytes size depends on width of the SPI channel.

>
>> I tested the driver with wm5110 codec.
>
> Did you try firmware downloads or something else that generates multiple
> transfers in a message?  Normal register writes will use a single
> transfer so I'd expect them to just work.
>

OK. I don't have provision to test on this board. I will try to test
on older boards by disabling manual mode.

Thanks
padma
padma venkat Nov. 14, 2014, 11:16 a.m. UTC | #5
Hi Mark,

On 11/10/14, Padma Venkat <padma.kvr@gmail.com> wrote:
> Hi Mark,
>
> On 11/7/14, Mark Brown <broonie@kernel.org> wrote:
>> On Fri, Nov 07, 2014 at 02:01:57PM +0530, Padma Venkat wrote:
>>
>>> CS can also be controlled automatically by setting AUTO_N_MANUAL to 1
>>> in CS_CFG. When it is auto CS automatically toggles between packet to
>>> packet. NCS_TIME_COUNT in CS_CFG controls the inactive period. The
>>> driver by default uses manual mode. But on exynos7 the manual mode is
>>> removed.
>>
>> OK, but what's a packet here?
>
> Packet is either 1 byte or 4 bytes size depends on width of the SPI
> channel.
>
>>
>>> I tested the driver with wm5110 codec.
>>
>> Did you try firmware downloads or something else that generates multiple
>> transfers in a message?  Normal register writes will use a single
>> transfer so I'd expect them to just work.
>>
>
> OK. I don't have provision to test on this board. I will try to test
> on older boards by disabling manual mode.
>

I tested on exynos5420 peach-pit by enabling auto mode. I used dd
command to read 1MB data from spi flash and I compared the result with
manual mode. Both are same.

> Thanks
> padma
>
padma venkat Nov. 21, 2014, 7:08 a.m. UTC | #6
Hi Mark,

>>>> CS can also be controlled automatically by setting AUTO_N_MANUAL to 1
>>>> in CS_CFG. When it is auto CS automatically toggles between packet to
>>>> packet. NCS_TIME_COUNT in CS_CFG controls the inactive period. The
>>>> driver by default uses manual mode. But on exynos7 the manual mode is
>>>> removed.
>>>
>>> OK, but what's a packet here?
>>
>> Packet is either 1 byte or 4 bytes size depends on width of the SPI
>> channel.
>>
>>>
>>>> I tested the driver with wm5110 codec.
>>>
>>> Did you try firmware downloads or something else that generates multiple
>>> transfers in a message?  Normal register writes will use a single
>>> transfer so I'd expect them to just work.
>>>
>>
>> OK. I don't have provision to test on this board. I will try to test
>> on older boards by disabling manual mode.
>>
>
> I tested on exynos5420 peach-pit by enabling auto mode. I used dd
> command to read 1MB data from spi flash and I compared the result with
> manual mode. Both are same.

I also tested this patch with Javier Martinez Canillas patches for
enabling spidev nodes from
http://www.spinics.net/lists/linux-samsung-soc/msg39057.html.

I read 4MB flashdata from spi by enabling auto mode and compared the
result. They look same.

>
>> Thanks
>> padma
>>
>
padma venkat Nov. 25, 2014, 3:07 a.m. UTC | #7
Hi Mark,

>>> OK. I don't have provision to test on this board. I will try to test
>>> on older boards by disabling manual mode.
>>>
>>
>> I tested on exynos5420 peach-pit by enabling auto mode. I used dd
>> command to read 1MB data from spi flash and I compared the result with
>> manual mode. Both are same.
>
> I also tested this patch with Javier Martinez Canillas patches for
> enabling spidev nodes from
> http://www.spinics.net/lists/linux-samsung-soc/msg39057.html.
>
> I read 4MB flashdata from spi by enabling auto mode and compared the
> result. They look same.

Do want some extra tests need to be done for this patch or is it okey?

>
>>
>>> Thanks
>>> padma
>>>
>>
>
Mark Brown Nov. 26, 2014, 7:01 p.m. UTC | #8
On Thu, Nov 06, 2014 at 03:21:49PM +0530, Padmavathi Venna wrote:
> Exynos7 SPI controller supports only the auto Selection of
> CS toggle mode and Exynos7 SoC includes six SPI controllers.
> Add support for these changes in Exynos7 SPI controller driver.

Applied, thanks.  It does seem like these controllers are getting more
restricted in functionality which seems a bit of a shame.
diff mbox

Patch

diff --git a/Documentation/devicetree/bindings/spi/spi-samsung.txt b/Documentation/devicetree/bindings/spi/spi-samsung.txt
index 1e8a857..6dbdeb3 100644
--- a/Documentation/devicetree/bindings/spi/spi-samsung.txt
+++ b/Documentation/devicetree/bindings/spi/spi-samsung.txt
@@ -9,7 +9,7 @@  Required SoC Specific Properties:
     - samsung,s3c2443-spi: for s3c2443, s3c2416 and s3c2450 platforms
     - samsung,s3c6410-spi: for s3c6410 platforms
     - samsung,s5pv210-spi: for s5pv210 and s5pc110 platforms
-    - samsung,exynos4210-spi: for exynos4 and exynos5 platforms
+    - samsung,exynos7-spi: for exynos7 platforms
 
 - reg: physical base address of the controller and length of memory mapped
   region.
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 84e7c9e..de2d33d 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -444,7 +444,7 @@  config SPI_S3C24XX_FIQ
 
 config SPI_S3C64XX
 	tristate "Samsung S3C64XX series type SPI"
-	depends on PLAT_SAMSUNG
+	depends on (PLAT_SAMSUNG || ARCH_EXYNOS)
 	select S3C64XX_PL080 if ARCH_S3C64XX
 	help
 	  SPI driver for Samsung S3C64XX and newer SoCs.
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 480133e..59e07cf 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -33,8 +33,9 @@ 
 
 #include <linux/platform_data/spi-s3c64xx.h>
 
-#define MAX_SPI_PORTS		3
+#define MAX_SPI_PORTS		6
 #define S3C64XX_SPI_QUIRK_POLL		(1 << 0)
+#define S3C64XX_SPI_QUIRK_CS_AUTO	(1 << 1)
 
 /* Registers and bit-fields */
 
@@ -78,6 +79,7 @@ 
 
 #define S3C64XX_SPI_SLAVE_AUTO			(1<<1)
 #define S3C64XX_SPI_SLAVE_SIG_INACT		(1<<0)
+#define S3C64XX_SPI_SLAVE_NSC_CNT_2		(2<<4)
 
 #define S3C64XX_SPI_INT_TRAILING_EN		(1<<6)
 #define S3C64XX_SPI_INT_RX_OVERRUN_EN		(1<<5)
@@ -717,7 +719,12 @@  static int s3c64xx_spi_transfer_one(struct spi_master *master,
 	enable_datapath(sdd, spi, xfer, use_dma);
 
 	/* Start the signals */
-	writel(0, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
+	if (!(sdd->port_conf->quirks & S3C64XX_SPI_QUIRK_CS_AUTO))
+		writel(0, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
+	else
+		writel(readl(sdd->regs + S3C64XX_SPI_SLAVE_SEL)
+			| S3C64XX_SPI_SLAVE_AUTO | S3C64XX_SPI_SLAVE_NSC_CNT_2,
+			sdd->regs + S3C64XX_SPI_SLAVE_SEL);
 
 	spin_unlock_irqrestore(&sdd->lock, flags);
 
@@ -866,13 +873,15 @@  static int s3c64xx_spi_setup(struct spi_device *spi)
 	}
 
 	pm_runtime_put(&sdd->pdev->dev);
-	writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
+	if (!(sdd->port_conf->quirks & S3C64XX_SPI_QUIRK_CS_AUTO))
+		writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
 	return 0;
 
 setup_exit:
 	pm_runtime_put(&sdd->pdev->dev);
 	/* setup() returns with device de-selected */
-	writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
+	if (!(sdd->port_conf->quirks & S3C64XX_SPI_QUIRK_CS_AUTO))
+		writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
 
 	if (gpio_is_valid(spi->cs_gpio))
 		gpio_free(spi->cs_gpio);
@@ -946,7 +955,8 @@  static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd, int channel)
 
 	sdd->cur_speed = 0;
 
-	writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
+	if (!(sdd->port_conf->quirks & S3C64XX_SPI_QUIRK_CS_AUTO))
+		writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
 
 	/* Disable Interrupts - we use Polling if not DMA mode */
 	writel(0, regs + S3C64XX_SPI_INT_EN);
@@ -1341,6 +1351,15 @@  static struct s3c64xx_spi_port_config exynos5440_spi_port_config = {
 	.quirks		= S3C64XX_SPI_QUIRK_POLL,
 };
 
+static struct s3c64xx_spi_port_config exynos7_spi_port_config = {
+	.fifo_lvl_mask	= { 0x1ff, 0x7F, 0x7F, 0x7F, 0x7F, 0x1ff},
+	.rx_lvl_offset	= 15,
+	.tx_st_done	= 25,
+	.high_speed	= true,
+	.clk_from_cmu	= true,
+	.quirks		= S3C64XX_SPI_QUIRK_CS_AUTO,
+};
+
 static struct platform_device_id s3c64xx_spi_driver_ids[] = {
 	{
 		.name		= "s3c2443-spi",
@@ -1374,6 +1393,9 @@  static const struct of_device_id s3c64xx_spi_dt_match[] = {
 	{ .compatible = "samsung,exynos5440-spi",
 			.data = (void *)&exynos5440_spi_port_config,
 	},
+	{ .compatible = "samsung,exynos7-spi",
+			.data = (void *)&exynos7_spi_port_config,
+	},
 	{ },
 };
 MODULE_DEVICE_TABLE(of, s3c64xx_spi_dt_match);