exynos: Support a delay after deactivate for SPI
Subsystems (2)
v3 cover exynos: Support a delay after deactivate for SPI
This patch set exports the function timer_get_us and adds a delay for devices that need some time to react after spi transation finishes
This patch set is based on
"EXYNOS: SPI: Support SPI_PREAMBLE mode"
link: "http://comments.gmane.org/gmane.comp.boot-loaders.u-boot/162269"
Changes in V2:
- Removed #ifdefine for exported function.
Changes in V3:
- Rebased on "[PATCH 0/2 V5] spi: Enable SPI_PREAMBLE Mode"
Rajeshwari Shinde (2):
exynos: Export timer_get_us() to get microsecond timer
spi: exynos: Support a delay after deactivate
drivers/spi/exynos_spi.c | 19 +++++++++++++++++++ include/common.h | 6 ++++++ 2 files changed, 25 insertions(+), 0 deletions(-)
Signature · 1 line
1.7.4.4
PATCH v3 1/2 exynos: Export timer_get_us() to get microsecond timer
This function, if implemented by the board, provides a microsecond timer. The granularity may be larger than 1us if hardware does not support this.
---
Changes in V2:
- Removed #ifdefine for exported function.
Changes in V3:
- None
include/common.h | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-)
include/common.h +6 -0
@@ -590,6 +590,12 @@ void ddr_enable_ecc(unsigned int dram_size);#endif #endif +/* +* Return the current value of a monotonically increasing microsecond timer. +* Granularity may be larger than 1us if hardware does not support this. +*/ +ulong timer_get_us (void ); +/* $(CPU)/cpu.c */ static inline int cpumask_next (int cpu,unsigned int mask) {
Signature · 1 line
1.7.4.4
PATCH v3 2/2 spi: exynos: Support a delay after deactivate
In reply to Rajeshwari ShindeFor devices that need some time to react after a spi transaction finishes, add the ability to set a delay.
Implement this as a delay on the first/next transaction to avoid any delay in the fairly common case where a SPI transaction is followed by other processing.
Based on:
"[U-Boot] [PATCH 0/2 V5] spi: Enable SPI_PREAMBLE Mode"
---
Changes in V2:
- None.
Changes in V3:
- Rebased on "[PATCH 0/2 V5] spi: Enable SPI_PREAMBLE Mode"
drivers/spi/exynos_spi.c | 19 +++++++++++++++++++ 1 files changed, 19 insertions(+), 0 deletions(-)
drivers/spi/exynos_spi.c +19 -0
@@ -38,6 +38,7 @@ struct spi_bus {struct exynos_spi *regs;int inited;/* 1 if this bus is ready for use */ int node; +uint deactivate_delay_us;/* Delay to wait after deactivate */ };/* A list of spi buses that we know about */
@@ -52,6 +53,8 @@ struct exynos_spi_slave {enum periph_id periph_id;/* Peripheral ID for this device */ unsigned int fifo_size;int skip_preamble; +struct spi_bus *bus;/* Pointer to our SPI bus info */ +ulong last_transaction_us;/* Time of last transaction end */ };static struct spi_bus *spi_get_bus (unsigned dev_index)
@@ -97,6 +100,7 @@ struct spi_slave *spi_setup_slave(unsigned int busnum, unsigned int cs, } bus = &spi_bus[busnum]; + spi_slave->bus = bus; spi_slave->regs = bus->regs; spi_slave->mode = mode; spi_slave->periph_id = bus->periph_id;
@@ -107,6 +111,7 @@ struct spi_slave *spi_setup_slave(unsigned int busnum, unsigned int cs, spi_slave->fifo_size =256 ; spi_slave->skip_preamble =0 ; + spi_slave->last_transaction_us =timer_get_us (); spi_slave->freq = bus->frequency;if (max_hz)
@@ -371,9 +376,21 @@ void spi_cs_activate(struct spi_slave *slave) {struct exynos_spi_slave *spi_slave =to_exynos_spi (slave); +/* If it's too soon to do another transaction, wait */ +if (spi_slave->bus->deactivate_delay_us && + spi_slave->last_transaction_us) { +ulong delay_us;/* The delay completed so far */ + delay_us =timer_get_us () - spi_slave->last_transaction_us; +if (delay_us < spi_slave->bus->deactivate_delay_us) +udelay (spi_slave->bus->deactivate_delay_us - delay_us); + }clrbits_le32 (&spi_slave->regs->cs_reg,SPI_SLAVE_SIG_INACT );debug ("Activate CS, bus %d\n" , spi_slave->slave.bus); spi_slave->skip_preamble = spi_slave->mode &SPI_PREAMBLE ; + +/* Remember time of this transaction so we can honour the bus delay */ +if (spi_slave->bus->deactivate_delay_us) + spi_slave->last_transaction_us =timer_get_us (); }/**
@@ -423,6 +440,8 @@ static int spi_get_config(const void *blob, int node, struct spi_bus *bus)/* Use 500KHz as a suitable default */ bus->frequency =fdtdec_get_int (blob, node,"spi-max-frequency" ,500000 ); + bus->deactivate_delay_us =fdtdec_get_int (blob, node, +"spi-deactivate-delay" ,0 );return 0 ; }
Signature · 1 line
1.7.4.4
PATCH v3 2/2 spi: exynos: Support a delay after deactivate
Hi,
Quoted 9 lines · Rajeshwari Shinde
For devices that need some time to react after a spi transaction finishes, add the ability to set a delay.
Implement this as a delay on the first/next transaction to avoid any delay in the fairly common case where a SPI transaction is followed by other processing.
Based on:
"[U-Boot] [PATCH 0/2 V5] spi: EnableSPI_PREAMBLEMode"
Please use the below format for referring previous commits ex:
"<PREVIOUS_COMMIT_HEAD>"
(sha1: PREVIOUS_COMMIT_ID)
in this case
"spi: exynos: Support SPI_PREAMBLE mode"
(sha1: e4eaef8910df805d511b1cb9b2caafa7d2827fdc)
Quoted 50 lines
Signed-off-by Simon Glass <[email protected]>Signed-off-by Rajeshwari Shinde <[email protected]>---
Changes in V2:
- None.
Changes in V3:
- Rebased on "[PATCH 0/2 V5] spi: EnableSPI_PREAMBLEMode"drivers/spi/exynos_spi.c | 19 +++++++++++++++++++ 1 files changed, 19 insertions(+), 0 deletions(-)drivers/spi/exynos_spi.c +5
-0@@ -38,6 +38,7 @@ struct spi_bus {struct exynos_spi *regs;int inited;/* 1 if this bus is ready for use */ int node; +uint deactivate_delay_us;/* Delay to wait after deactivate */ };/* A list of spi buses that we know about */ @@ -52,6 +53,8 @@ struct exynos_spi_slave {enum periph_id periph_id;/* Peripheral ID for this device */ unsigned int fifo_size;int skip_preamble; +struct spi_bus *bus;/* Pointer to our SPI bus info */ +ulong last_transaction_us;/* Time of last transaction end */ };static struct spi_bus *spi_get_bus (unsigned dev_index)@@ -97,6 +100,7 @@ struct spi_slave *spi_setup_slave(unsigned int busnum, unsigned int cs, } bus = &spi_bus[busnum]; + spi_slave->bus = bus; spi_slave->regs = bus->regs; spi_slave->mode = mode; spi_slave->periph_id = bus->periph_id;@@ -107,6 +111,7 @@ struct spi_slave *spi_setup_slave(unsigned int busnum, unsigned int cs, spi_slave->fifo_size =256 ; spi_slave->skip_preamble =0 ; + spi_slave->last_transaction_us =timer_get_us (); spi_slave->freq = bus->frequency;if (max_hz)@@ -371,9 +376,21 @@ void spi_cs_activate(struct spi_slave *slave) {
drivers/spi/exynos_spi.c void spi_cs_activate(struct spi_slave *slave) · line 386
Quoted 10 lines
drivers/spi/exynos_spi.c +8
-0struct exynos_spi_slave *spi_slave =to_exynos_spi (slave); +/* If it's too soon to do another transaction, wait */ +if (spi_slave->bus->deactivate_delay_us && + spi_slave->last_transaction_us) { +ulong delay_us;/* The delay completed so far */ + delay_us =timer_get_us () - spi_slave->last_transaction_us; +if (delay_us < spi_slave->bus->deactivate_delay_us) +udelay (spi_slave->bus->deactivate_delay_us - delay_us); + }
Add one space
Quoted 12 lines
drivers/spi/exynos_spi.c +4
-0clrbits_le32 (&spi_slave->regs->cs_reg,SPI_SLAVE_SIG_INACT );debug ("Activate CS, bus %d\n" , spi_slave->slave.bus); spi_slave->skip_preamble = spi_slave->mode &SPI_PREAMBLE ; + +/* Remember time of this transaction so we can honour the bus delay */ +if (spi_slave->bus->deactivate_delay_us) + spi_slave->last_transaction_us =timer_get_us (); }/**
drivers/spi/exynos_spi.c static int spi_get_config(const void *blob, int node, struct spi_bus *bus) · line 447
Quoted 8 lines
drivers/spi/exynos_spi.c +2
-0@@ -423,6 +440,8 @@ static int spi_get_config(const void *blob, int node, struct spi_bus *bus)/* Use 500KHz as a suitable default */ bus->frequency =fdtdec_get_int (blob, node,"spi-max-frequency" ,500000 ); + bus->deactivate_delay_us =fdtdec_get_int (blob, node, +"spi-deactivate-delay" ,0 );return 0 ; }
Was this tested, usually what is the max deactivate delay? In this case your are passing through dts is it?
Thanks,
Jagan.
PATCH v3 2/2 spi: exynos: Support a delay after deactivate
Hi Jagan,
Quoted 16 lines · Jagan Teki
Hi,
Quoted 10 lines · Rajeshwari Shinde
For devices that need some time to react after a spi transaction finishes, add the ability to set a delay.
Implement this as a delay on the first/next transaction to avoid any delay in the fairly common case where a SPI transaction is followed by other processing.
Based on:
"[U-Boot] [PATCH 0/2 V5] spi: EnableSPI_PREAMBLEMode"
Quoted 8 lines
Please use the below format for referring previous commits ex:
"<PREVIOUS_COMMIT_HEAD>"
(sha1:PREVIOUS_COMMIT_ID)in this case
"spi: exynos: SupportSPI_PREAMBLEmode" (sha1: e4eaef8910df805d511b1cb9b2caaf**a7d2827fdc)
I hope you don't mind me answering part of this...
Quoted 91 lines
Quoted 59 lines
Signed-off-by Simon Glass <[email protected]>Signed-off-by Rajeshwari Shinde <[email protected]>---
Changes in V2:
- None.
Changes in V3:
- Rebased on "[PATCH 0/2 V5] spi: EnableSPI_PREAMBLEMode"drivers/spi/exynos_spi.c | 19 +++++++++++++++++++ 1 files changed, 19 insertions(+), 0 deletions(-)drivers/spi/exynos_spi.c +1
-0@@ -38,6 +38,7 @@ struct spi_bus {struct exynos_spi *regs;int inited;/* 1 if this bus is ready for use */ int node; +uint deactivate_delay_us;/* Delay to wait after deactivate */ };/* A list of spi buses that we know about */
drivers/spi/exynos_spi.c +2
-0@@ -52,6 +53,8 @@ struct exynos_spi_slave {enum periph_id periph_id;/* Peripheral ID for this device */ unsigned int fifo_size;int skip_preamble; +struct spi_bus *bus;/* Pointer to our SPI bus info */ +ulong last_transaction_us;/* Time of last transaction end */ };static struct
spi_bus*spi_get_bus(unsigneddev_index)drivers/spi/exynos_spi.c +1
-0@@ -97,6 +100,7 @@ struct spi_slave *spi_setup_slave(unsigned int busnum,unsigned int cs, } bus = &spi_bus[busnum]; + spi_slave->bus = bus; spi_slave->regs = bus->regs; spi_slave->mode = mode;spi_slave->periph_id = bus->periph_id;drivers/spi/exynos_spi.c +1
-0@@ -107,6 +111,7 @@ struct spi_slave *spi_setup_slave(unsigned int busnum, unsigned int cs, spi_slave->fifo_size =256 ; spi_slave->skip_preamble =0 ; + spi_slave->last_transaction_us =timer_get_us (); spi_slave->freq = bus->frequency;if (max_hz)drivers/spi/exynos_spi.c +1
-0@@ -371,9 +376,21 @@ void spi_cs_activate(struct spi_slave *slave) {struct exynos_spi_slave *spi_slave =to_exynos_spi (slave); +/* If it's too soon to do another transaction, wait */ drivers/spi/exynos_spi.c void spi_cs_activate(struct spi_slave *slave) · line 389
Quoted 10 lines
drivers/spi/exynos_spi.c +7
-0+if (spi_slave->bus->deactivate_**delay_us && + spi_slave->last_transaction_**us) { +ulong delay_us;/* The delay completed so far */ + delay_us =timer_get_us () - spi_slave->last_transaction_* *us; +if (delay_us < spi_slave->bus->deactivate_**delay_us) + udelay(spi_slave->bus->**deactivate_delay_us - delay_us); + }Add one space
clrbits_le32(&spi_slave->regs-**>cs_reg, SPI_SLAVE_SIG_INACT);Quoted 18 lines
drivers/spi/exynos_spi.c +2
-0debug ("Activate CS, bus %d\n" , spi_slave->slave.bus); spi_slave->skip_preamble = spi_slave->mode &SPI_PREAMBLE ; + +/* Remember time of this transaction so we can honour the bus delay */
drivers/spi/exynos_spi.c +4
-0+if (spi_slave->bus->deactivate_**delay_us) + spi_slave->last_transaction_us =timer_get_us (); }/** @@ -423,6 +440,8 @@ static int spi_get_config(const void *blob, int node, struct spi_bus *bus)/* Use 500KHz as a suitable default */ bus->frequency = fdtdec_get_int(blob, node, "spi-max-frequency",500000 ); + bus->deactivate_delay_us =fdtdec_get_int (blob, node, +"spi-deactivate-delay" ,0 );
Quoted 6 lines
Quoted 4 lines
drivers/spi/exynos_spi.c +0
-0return 0 ;}Was this tested, usually what is the max deactivate delay?
This was tested with 50us.
Quoted 2 lines
In this case your are passing through dts is it?
Yes that's right.
Regards,
Simon
Quoted 6 lines
Thanks,
Jagan.
PATCH v3 2/2 spi: exynos: Support a delay after deactivate
Quoted 136 lines · Simon Glass
Hi Jagan,
Quoted 17 lines · Jagan Teki
Hi,
Quoted 10 lines · Rajeshwari Shinde
For devices that need some time to react after a spi transaction finishes, add the ability to set a delay.
Implement this as a delay on the first/next transaction to avoid any delay in the fairly common case where a SPI transaction is followed by other processing.
Based on:
"[U-Boot] [PATCH 0/2 V5] spi: EnableSPI_PREAMBLEMode"Quoted 8 lines
Please use the below format for referring previous commits ex:
"<PREVIOUS_COMMIT_HEAD>"
(sha1:PREVIOUS_COMMIT_ID)in this case
"spi: exynos: SupportSPI_PREAMBLEmode"
(sha1:e4eaef8910df805d511b1cb9b2caafa7d2827fdc)I hope you don't mind me answering part of this...
Quoted 93 lines
Quoted 60 lines
Signed-off-by Simon Glass <[email protected]>Signed-off-by Rajeshwari Shinde <[email protected]>---
Changes in V2:
- None.
Changes in V3:
- Rebased on "[PATCH 0/2 V5] spi: EnableSPI_PREAMBLEMode"drivers/spi/exynos_spi.c | 19 +++++++++++++++++++ 1 files changed, 19 insertions(+), 0 deletions(-)drivers/spi/exynos_spi.c +1
-0@@ -38,6 +38,7 @@ struct spi_bus {struct exynos_spi *regs;int inited;/* 1 if this bus is ready for use */ int node; +uint deactivate_delay_us;/* Delay to wait after deactivate */ };/* A list of spi buses that we know about */
drivers/spi/exynos_spi.c +2
-0@@ -52,6 +53,8 @@ struct exynos_spi_slave {enum periph_id periph_id;/* Peripheral ID for this device */ unsigned int fifo_size;int skip_preamble; +struct spi_bus *bus;/* Pointer to our SPI bus info */ +ulong last_transaction_us;/* Time of last transaction end */ };static struct
spi_bus*spi_get_bus(unsigneddev_index)drivers/spi/exynos_spi.c +1
-0@@ -97,6 +100,7 @@ struct spi_slave *spi_setup_slave(unsigned int busnum,unsigned int cs, } bus = &spi_bus[busnum]; + spi_slave->bus = bus; spi_slave->regs = bus->regs; spi_slave->mode = mode;spi_slave->periph_id = bus->periph_id;drivers/spi/exynos_spi.c +1
-0@@ -107,6 +111,7 @@ struct spi_slave *spi_setup_slave(unsigned int busnum, unsigned int cs, spi_slave->fifo_size =256 ; spi_slave->skip_preamble =0 ; + spi_slave->last_transaction_us =timer_get_us (); spi_slave->freq = bus->frequency;if (max_hz)drivers/spi/exynos_spi.c +0
-0@@ -371,9 +376,21 @@ void spi_cs_activate(struct spi_slave *slave) {struct exynos_spi_slave *spi_slave =to_exynos_spi (slave);drivers/spi/exynos_spi.c void spi_cs_activate(struct spi_slave *slave) · line 388
Quoted 10 lines
drivers/spi/exynos_spi.c +8
-0+/* If it's too soon to do another transaction, wait */ +if (spi_slave->bus->deactivate_delay_us && + spi_slave->last_transaction_us) { +ulong delay_us;/* The delay completed so far */ + delay_us =timer_get_us () - spi_slave->last_transaction_us; +if (delay_us < spi_slave->bus->deactivate_delay_us) +udelay (spi_slave->bus->deactivate_delay_us - delay_us); + }Add one space
Quoted 19 lines
drivers/spi/exynos_spi.c +2
-0clrbits_le32 (&spi_slave->regs->cs_reg,SPI_SLAVE_SIG_INACT );debug ("Activate CS, bus %d\n" , spi_slave->slave.bus); spi_slave->skip_preamble = spi_slave->mode &SPI_PREAMBLE ; + +/* Remember time of this transaction so we can honour the bus delay */
drivers/spi/exynos_spi.c +4
-0+if (spi_slave->bus->deactivate_delay_us) + spi_slave->last_transaction_us =timer_get_us (); }/** @@ -423,6 +440,8 @@ static int spi_get_config(const void *blob, int node, struct spi_bus *bus)/* Use 500KHz as a suitable default */ bus->frequency = fdtdec_get_int(blob, node, "spi-max-frequency",500000 ); + bus->deactivate_delay_us =fdtdec_get_int (blob, node, +"spi-deactivate-delay" ,0 );Quoted 5 lines
Quoted 3 lines
drivers/spi/exynos_spi.c +0
-0return 0 ;}Was this tested, usually what is the max deactivate delay?
This was tested with 50us.
Quoted 1 line
Quoted 15 lines
Quoted 1 line
In this case your are passing through dts is it?
Yes that's right.
Regards,
SimonQuoted 6 lines
Thanks,
Jagan.
Can you please send the next version patches.
--
Thanks,
Jagan.
PATCH v3 2/2 spi: exynos: Support a delay after deactivate
HI Rajeshwari,
Can you please send the next version patch w.r.t to current tree. and also fix the comments on last version.
Planning to apply on tree, feel free to ask if you have any concerns.
--
Thanks,
Jagan.
Quoted 158 lines · Jagan Teki
Quoted 136 lines · Simon Glass
Hi Jagan,
Quoted 17 lines · Jagan Teki
Hi,
Quoted 10 lines · Rajeshwari Shinde
For devices that need some time to react after a spi transaction finishes, add the ability to set a delay.
Implement this as a delay on the first/next transaction to avoid any delay in the fairly common case where a SPI transaction is followed by other processing.
Based on:
"[U-Boot] [PATCH 0/2 V5] spi: EnableSPI_PREAMBLEMode"Quoted 8 lines
Please use the below format for referring previous commits ex:
"<PREVIOUS_COMMIT_HEAD>"
(sha1:PREVIOUS_COMMIT_ID)in this case
"spi: exynos: SupportSPI_PREAMBLEmode"
(sha1:e4eaef8910df805d511b1cb9b2caafa7d2827fdc)I hope you don't mind me answering part of this...
Quoted 93 lines
Quoted 60 lines
Signed-off-by Simon Glass <[email protected]>Signed-off-by Rajeshwari Shinde <[email protected]>---
Changes in V2:
- None.
Changes in V3:
- Rebased on "[PATCH 0/2 V5] spi: EnableSPI_PREAMBLEMode"drivers/spi/exynos_spi.c | 19 +++++++++++++++++++ 1 files changed, 19 insertions(+), 0 deletions(-)drivers/spi/exynos_spi.c +1
-0@@ -38,6 +38,7 @@ struct spi_bus {struct exynos_spi *regs;int inited;/* 1 if this bus is ready for use */ int node; +uint deactivate_delay_us;/* Delay to wait after deactivate */ };/* A list of spi buses that we know about */
drivers/spi/exynos_spi.c +2
-0@@ -52,6 +53,8 @@ struct exynos_spi_slave {enum periph_id periph_id;/* Peripheral ID for this device */ unsigned int fifo_size;int skip_preamble; +struct spi_bus *bus;/* Pointer to our SPI bus info */ +ulong last_transaction_us;/* Time of last transaction end */ };static struct
spi_bus*spi_get_bus(unsigneddev_index)drivers/spi/exynos_spi.c +1
-0@@ -97,6 +100,7 @@ struct spi_slave *spi_setup_slave(unsigned int busnum,unsigned int cs, } bus = &spi_bus[busnum]; + spi_slave->bus = bus; spi_slave->regs = bus->regs; spi_slave->mode = mode;spi_slave->periph_id = bus->periph_id;drivers/spi/exynos_spi.c +1
-0@@ -107,6 +111,7 @@ struct spi_slave *spi_setup_slave(unsigned int busnum, unsigned int cs, spi_slave->fifo_size =256 ; spi_slave->skip_preamble =0 ; + spi_slave->last_transaction_us =timer_get_us (); spi_slave->freq = bus->frequency;if (max_hz)drivers/spi/exynos_spi.c +0
-0@@ -371,9 +376,21 @@ void spi_cs_activate(struct spi_slave *slave) {struct exynos_spi_slave *spi_slave =to_exynos_spi (slave);drivers/spi/exynos_spi.c void spi_cs_activate(struct spi_slave *slave) · line 388
Quoted 10 lines
drivers/spi/exynos_spi.c +8
-0+/* If it's too soon to do another transaction, wait */ +if (spi_slave->bus->deactivate_delay_us && + spi_slave->last_transaction_us) { +ulong delay_us;/* The delay completed so far */ + delay_us =timer_get_us () - spi_slave->last_transaction_us; +if (delay_us < spi_slave->bus->deactivate_delay_us) +udelay (spi_slave->bus->deactivate_delay_us - delay_us); + }Add one space
Quoted 19 lines
drivers/spi/exynos_spi.c +2
-0clrbits_le32 (&spi_slave->regs->cs_reg,SPI_SLAVE_SIG_INACT );debug ("Activate CS, bus %d\n" , spi_slave->slave.bus); spi_slave->skip_preamble = spi_slave->mode &SPI_PREAMBLE ; + +/* Remember time of this transaction so we can honour the bus delay */
drivers/spi/exynos_spi.c +4
-0+if (spi_slave->bus->deactivate_delay_us) + spi_slave->last_transaction_us =timer_get_us (); }/** @@ -423,6 +440,8 @@ static int spi_get_config(const void *blob, int node, struct spi_bus *bus)/* Use 500KHz as a suitable default */ bus->frequency = fdtdec_get_int(blob, node, "spi-max-frequency",500000 ); + bus->deactivate_delay_us =fdtdec_get_int (blob, node, +"spi-deactivate-delay" ,0 );Quoted 5 lines
Quoted 3 lines
drivers/spi/exynos_spi.c +0
-0return 0 ;}Was this tested, usually what is the max deactivate delay?
This was tested with 50us.
Quoted 1 line
Quoted 15 lines
Quoted 1 line
In this case your are passing through dts is it?
Yes that's right.
Regards,
SimonQuoted 6 lines
Thanks,
Jagan.Can you please send the next version patches.
--
Thanks,
Jagan.
PATCH v3 2/2 spi: exynos: Support a delay after deactivate
Any update on this!