Re: [PATCH v6 19/23] drivers/fsi: Add GPIO based FSI master

2017-05-11 Thread Christopher Bostic



On 5/10/17 8:58 PM, Jeremy Kerr wrote:

Hi Chris,


I don't think we'd want this per master.   The lock is for the 'top'
master issuing commands.  Only the top master can initiate any
transactions on the bus to any devices connected downstream. Downstream
masters such as hub masters, etc... cannot initiate a command.

I think what Joel meant there was that we have it per *GPIO* master; if
there are two GPIO masters on a system, there's no need to provide
mutual exclusion to each (separate) set of GPIOs.

To implement this, we'd just move the lock into struct fsi_master_gpio.


Hi Jeremy,

Understand now -will make the change.

Thanks
-Chris


Cheers,


Jeremy





Re: [PATCH v6 19/23] drivers/fsi: Add GPIO based FSI master

2017-05-11 Thread Christopher Bostic



On 5/10/17 8:58 PM, Jeremy Kerr wrote:

Hi Chris,


I don't think we'd want this per master.   The lock is for the 'top'
master issuing commands.  Only the top master can initiate any
transactions on the bus to any devices connected downstream. Downstream
masters such as hub masters, etc... cannot initiate a command.

I think what Joel meant there was that we have it per *GPIO* master; if
there are two GPIO masters on a system, there's no need to provide
mutual exclusion to each (separate) set of GPIOs.

To implement this, we'd just move the lock into struct fsi_master_gpio.


Hi Jeremy,

Understand now -will make the change.

Thanks
-Chris


Cheers,


Jeremy





Re: [PATCH v6 19/23] drivers/fsi: Add GPIO based FSI master

2017-05-10 Thread Jeremy Kerr
Hi Chris,

> I don't think we'd want this per master.   The lock is for the 'top'
> master issuing commands.  Only the top master can initiate any
> transactions on the bus to any devices connected downstream. Downstream
> masters such as hub masters, etc... cannot initiate a command.

I think what Joel meant there was that we have it per *GPIO* master; if
there are two GPIO masters on a system, there's no need to provide
mutual exclusion to each (separate) set of GPIOs.

To implement this, we'd just move the lock into struct fsi_master_gpio.

Cheers,


Jeremy


Re: [PATCH v6 19/23] drivers/fsi: Add GPIO based FSI master

2017-05-10 Thread Jeremy Kerr
Hi Chris,

> I don't think we'd want this per master.   The lock is for the 'top'
> master issuing commands.  Only the top master can initiate any
> transactions on the bus to any devices connected downstream. Downstream
> masters such as hub masters, etc... cannot initiate a command.

I think what Joel meant there was that we have it per *GPIO* master; if
there are two GPIO masters on a system, there's no need to provide
mutual exclusion to each (separate) set of GPIOs.

To implement this, we'd just move the lock into struct fsi_master_gpio.

Cheers,


Jeremy


Re: [PATCH v6 19/23] drivers/fsi: Add GPIO based FSI master

2017-05-10 Thread Christopher Bostic



On 5/10/17 2:30 AM, Joel Stanley wrote:

Hi Chris,

On Tue, Apr 11, 2017 at 5:17 AM, Christopher Bostic
 wrote:


From: Chris Bostic 

Implement a FSI master using GPIO.  Will generate FSI protocol for
read and write commands to particular addresses.  Sends master command
and waits for and decodes a slave response.

Includes changes from Edward A. James  and Jeremy
Kerr .

I think the series is looking good. I've done a bunch of testing on
some machines, and it worked for me.

I've got a few comments and things to be clarified below.


Signed-off-by: Edward A. James 
Signed-off-by: Jeremy Kerr 
Signed-off-by: Chris Bostic 
Signed-off-by: Joel Stanley 
---
  drivers/fsi/Kconfig   |  11 +
  drivers/fsi/Makefile  |   1 +
  drivers/fsi/fsi-master-gpio.c | 610 ++
  3 files changed, 622 insertions(+)
  create mode 100644 drivers/fsi/fsi-master-gpio.c

diff --git a/drivers/fsi/Kconfig b/drivers/fsi/Kconfig
index 04c1a0e..448bc3b 100644
--- a/drivers/fsi/Kconfig
+++ b/drivers/fsi/Kconfig
@@ -9,4 +9,15 @@ config FSI
 ---help---
   FSI - the FRU Support Interface - is a simple bus for low-level
   access to POWER-based hardware.
+
+if FSI
+
+config FSI_MASTER_GPIO
+   tristate "GPIO-based FSI master"
+   depends on GPIOLIB
+   ---help---
+   This option enables a FSI master driver using GPIO lines.
+
+endif
+
  endmenu
diff --git a/drivers/fsi/Makefile b/drivers/fsi/Makefile
index db0e5e7..ed28ac0 100644
--- a/drivers/fsi/Makefile
+++ b/drivers/fsi/Makefile
@@ -1,2 +1,3 @@

  obj-$(CONFIG_FSI) += fsi-core.o
+obj-$(CONFIG_FSI_MASTER_GPIO) += fsi-master-gpio.o
diff --git a/drivers/fsi/fsi-master-gpio.c b/drivers/fsi/fsi-master-gpio.c
new file mode 100644
index 000..9fedfaf
--- /dev/null
+++ b/drivers/fsi/fsi-master-gpio.c
@@ -0,0 +1,610 @@
+/*
+ * A FSI master controller, using a simple GPIO bit-banging interface
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "fsi-master.h"
+
+#defineFSI_GPIO_STD_DLY1   /* Standard pin delay in nS */
+#defineFSI_ECHO_DELAY_CLOCKS   16  /* Number clocks for echo delay 
*/
+#defineFSI_PRE_BREAK_CLOCKS50  /* Number clocks to prep for 
break */
+#defineFSI_BREAK_CLOCKS256 /* Number of clocks to issue 
break */
+#defineFSI_POST_BREAK_CLOCKS   16000   /* Number clocks to set up cfam 
*/
+#defineFSI_INIT_CLOCKS 5000/* Clock out any old data */
+#defineFSI_GPIO_STD_DELAY  10  /* Standard GPIO delay in nS */
+   /* todo: adjust down as low as */
+   /* possible or eliminate */
+#defineFSI_GPIO_CMD_DPOLL  0x2
+#defineFSI_GPIO_CMD_TERM   0x3f
+#define FSI_GPIO_CMD_ABS_AR0x4
+
+#defineFSI_GPIO_DPOLL_CLOCKS   100  /* < 21 will cause slave to 
hang */
+
+/* Bus errors */
+#defineFSI_GPIO_ERR_BUSY   1   /* Slave stuck in busy state */
+#defineFSI_GPIO_RESP_ERRA  2   /* Any (misc) Error */
+#defineFSI_GPIO_RESP_ERRC  3   /* Slave reports master CRC 
error */
+#defineFSI_GPIO_MTOE   4   /* Master time out error */
+#defineFSI_GPIO_CRC_INVAL  5   /* Master reports slave CRC 
error */
+
+/* Normal slave responses */
+#defineFSI_GPIO_RESP_BUSY  1
+#defineFSI_GPIO_RESP_ACK   0
+#defineFSI_GPIO_RESP_ACKD  4
+
+#defineFSI_GPIO_MAX_BUSY   100
+#defineFSI_GPIO_MTOE_COUNT 1000
+#defineFSI_GPIO_DRAIN_BITS 20
+#defineFSI_GPIO_CRC_SIZE   4
+#defineFSI_GPIO_MSG_ID_SIZE2
+#defineFSI_GPIO_MSG_RESPID_SIZE2
+#defineFSI_GPIO_PRIME_SLAVE_CLOCKS 100
+
+static DEFINE_SPINLOCK(fsi_gpio_cmd_lock); /* lock around fsi commands */

Should this be per-master?


Hi Joel,

I don't think we'd want this per master.   The lock is for the 'top' 
master issuing commands.  Only the top master can initiate any 
transactions on the bus to any devices connected downstream. Downstream 
masters such as hub masters, etc... cannot initiate a command.



+
+struct fsi_master_gpio {
+   struct fsi_master   master;
+   struct device   *dev;
+   struct gpio_desc*gpio_clk;
+   struct gpio_desc*gpio_data;
+   struct gpio_desc*gpio_trans;/* Voltage translator */
+   struct gpio_desc*gpio_enable;   /* FSI enable */
+   struct gpio_desc*gpio_mux;  /* Mux control */
+};
+
+#define to_fsi_master_gpio(m) container_of(m, struct fsi_master_gpio, master)
+
+struct fsi_gpio_msg {
+   

Re: [PATCH v6 19/23] drivers/fsi: Add GPIO based FSI master

2017-05-10 Thread Christopher Bostic



On 5/10/17 2:30 AM, Joel Stanley wrote:

Hi Chris,

On Tue, Apr 11, 2017 at 5:17 AM, Christopher Bostic
 wrote:


From: Chris Bostic 

Implement a FSI master using GPIO.  Will generate FSI protocol for
read and write commands to particular addresses.  Sends master command
and waits for and decodes a slave response.

Includes changes from Edward A. James  and Jeremy
Kerr .

I think the series is looking good. I've done a bunch of testing on
some machines, and it worked for me.

I've got a few comments and things to be clarified below.


Signed-off-by: Edward A. James 
Signed-off-by: Jeremy Kerr 
Signed-off-by: Chris Bostic 
Signed-off-by: Joel Stanley 
---
  drivers/fsi/Kconfig   |  11 +
  drivers/fsi/Makefile  |   1 +
  drivers/fsi/fsi-master-gpio.c | 610 ++
  3 files changed, 622 insertions(+)
  create mode 100644 drivers/fsi/fsi-master-gpio.c

diff --git a/drivers/fsi/Kconfig b/drivers/fsi/Kconfig
index 04c1a0e..448bc3b 100644
--- a/drivers/fsi/Kconfig
+++ b/drivers/fsi/Kconfig
@@ -9,4 +9,15 @@ config FSI
 ---help---
   FSI - the FRU Support Interface - is a simple bus for low-level
   access to POWER-based hardware.
+
+if FSI
+
+config FSI_MASTER_GPIO
+   tristate "GPIO-based FSI master"
+   depends on GPIOLIB
+   ---help---
+   This option enables a FSI master driver using GPIO lines.
+
+endif
+
  endmenu
diff --git a/drivers/fsi/Makefile b/drivers/fsi/Makefile
index db0e5e7..ed28ac0 100644
--- a/drivers/fsi/Makefile
+++ b/drivers/fsi/Makefile
@@ -1,2 +1,3 @@

  obj-$(CONFIG_FSI) += fsi-core.o
+obj-$(CONFIG_FSI_MASTER_GPIO) += fsi-master-gpio.o
diff --git a/drivers/fsi/fsi-master-gpio.c b/drivers/fsi/fsi-master-gpio.c
new file mode 100644
index 000..9fedfaf
--- /dev/null
+++ b/drivers/fsi/fsi-master-gpio.c
@@ -0,0 +1,610 @@
+/*
+ * A FSI master controller, using a simple GPIO bit-banging interface
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "fsi-master.h"
+
+#defineFSI_GPIO_STD_DLY1   /* Standard pin delay in nS */
+#defineFSI_ECHO_DELAY_CLOCKS   16  /* Number clocks for echo delay 
*/
+#defineFSI_PRE_BREAK_CLOCKS50  /* Number clocks to prep for 
break */
+#defineFSI_BREAK_CLOCKS256 /* Number of clocks to issue 
break */
+#defineFSI_POST_BREAK_CLOCKS   16000   /* Number clocks to set up cfam 
*/
+#defineFSI_INIT_CLOCKS 5000/* Clock out any old data */
+#defineFSI_GPIO_STD_DELAY  10  /* Standard GPIO delay in nS */
+   /* todo: adjust down as low as */
+   /* possible or eliminate */
+#defineFSI_GPIO_CMD_DPOLL  0x2
+#defineFSI_GPIO_CMD_TERM   0x3f
+#define FSI_GPIO_CMD_ABS_AR0x4
+
+#defineFSI_GPIO_DPOLL_CLOCKS   100  /* < 21 will cause slave to 
hang */
+
+/* Bus errors */
+#defineFSI_GPIO_ERR_BUSY   1   /* Slave stuck in busy state */
+#defineFSI_GPIO_RESP_ERRA  2   /* Any (misc) Error */
+#defineFSI_GPIO_RESP_ERRC  3   /* Slave reports master CRC 
error */
+#defineFSI_GPIO_MTOE   4   /* Master time out error */
+#defineFSI_GPIO_CRC_INVAL  5   /* Master reports slave CRC 
error */
+
+/* Normal slave responses */
+#defineFSI_GPIO_RESP_BUSY  1
+#defineFSI_GPIO_RESP_ACK   0
+#defineFSI_GPIO_RESP_ACKD  4
+
+#defineFSI_GPIO_MAX_BUSY   100
+#defineFSI_GPIO_MTOE_COUNT 1000
+#defineFSI_GPIO_DRAIN_BITS 20
+#defineFSI_GPIO_CRC_SIZE   4
+#defineFSI_GPIO_MSG_ID_SIZE2
+#defineFSI_GPIO_MSG_RESPID_SIZE2
+#defineFSI_GPIO_PRIME_SLAVE_CLOCKS 100
+
+static DEFINE_SPINLOCK(fsi_gpio_cmd_lock); /* lock around fsi commands */

Should this be per-master?


Hi Joel,

I don't think we'd want this per master.   The lock is for the 'top' 
master issuing commands.  Only the top master can initiate any 
transactions on the bus to any devices connected downstream. Downstream 
masters such as hub masters, etc... cannot initiate a command.



+
+struct fsi_master_gpio {
+   struct fsi_master   master;
+   struct device   *dev;
+   struct gpio_desc*gpio_clk;
+   struct gpio_desc*gpio_data;
+   struct gpio_desc*gpio_trans;/* Voltage translator */
+   struct gpio_desc*gpio_enable;   /* FSI enable */
+   struct gpio_desc*gpio_mux;  /* Mux control */
+};
+
+#define to_fsi_master_gpio(m) container_of(m, struct fsi_master_gpio, master)
+
+struct fsi_gpio_msg {
+   uint64_tmsg;
+   uint8_t bits;
+};
+
+static void clock_toggle(struct fsi_master_gpio *master, int count)
+{
+   int i;
+
+   for (i = 0; i < count; 

Re: [PATCH v6 19/23] drivers/fsi: Add GPIO based FSI master

2017-05-10 Thread Joel Stanley
Hi Chris,

On Tue, Apr 11, 2017 at 5:17 AM, Christopher Bostic
 wrote:

> From: Chris Bostic 
>
> Implement a FSI master using GPIO.  Will generate FSI protocol for
> read and write commands to particular addresses.  Sends master command
> and waits for and decodes a slave response.
>
> Includes changes from Edward A. James  and Jeremy
> Kerr .

I think the series is looking good. I've done a bunch of testing on
some machines, and it worked for me.

I've got a few comments and things to be clarified below.

>
> Signed-off-by: Edward A. James 
> Signed-off-by: Jeremy Kerr 
> Signed-off-by: Chris Bostic 
> Signed-off-by: Joel Stanley 
> ---
>  drivers/fsi/Kconfig   |  11 +
>  drivers/fsi/Makefile  |   1 +
>  drivers/fsi/fsi-master-gpio.c | 610 
> ++
>  3 files changed, 622 insertions(+)
>  create mode 100644 drivers/fsi/fsi-master-gpio.c
>
> diff --git a/drivers/fsi/Kconfig b/drivers/fsi/Kconfig
> index 04c1a0e..448bc3b 100644
> --- a/drivers/fsi/Kconfig
> +++ b/drivers/fsi/Kconfig
> @@ -9,4 +9,15 @@ config FSI
> ---help---
>   FSI - the FRU Support Interface - is a simple bus for low-level
>   access to POWER-based hardware.
> +
> +if FSI
> +
> +config FSI_MASTER_GPIO
> +   tristate "GPIO-based FSI master"
> +   depends on GPIOLIB
> +   ---help---
> +   This option enables a FSI master driver using GPIO lines.
> +
> +endif
> +
>  endmenu
> diff --git a/drivers/fsi/Makefile b/drivers/fsi/Makefile
> index db0e5e7..ed28ac0 100644
> --- a/drivers/fsi/Makefile
> +++ b/drivers/fsi/Makefile
> @@ -1,2 +1,3 @@
>
>  obj-$(CONFIG_FSI) += fsi-core.o
> +obj-$(CONFIG_FSI_MASTER_GPIO) += fsi-master-gpio.o
> diff --git a/drivers/fsi/fsi-master-gpio.c b/drivers/fsi/fsi-master-gpio.c
> new file mode 100644
> index 000..9fedfaf
> --- /dev/null
> +++ b/drivers/fsi/fsi-master-gpio.c
> @@ -0,0 +1,610 @@
> +/*
> + * A FSI master controller, using a simple GPIO bit-banging interface
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "fsi-master.h"
> +
> +#defineFSI_GPIO_STD_DLY1   /* Standard pin delay in nS */
> +#defineFSI_ECHO_DELAY_CLOCKS   16  /* Number clocks for echo 
> delay */
> +#defineFSI_PRE_BREAK_CLOCKS50  /* Number clocks to prep for 
> break */
> +#defineFSI_BREAK_CLOCKS256 /* Number of clocks to issue 
> break */
> +#defineFSI_POST_BREAK_CLOCKS   16000   /* Number clocks to set up 
> cfam */
> +#defineFSI_INIT_CLOCKS 5000/* Clock out any old data */
> +#defineFSI_GPIO_STD_DELAY  10  /* Standard GPIO delay in nS 
> */
> +   /* todo: adjust down as low as */
> +   /* possible or eliminate */
> +#defineFSI_GPIO_CMD_DPOLL  0x2
> +#defineFSI_GPIO_CMD_TERM   0x3f
> +#define FSI_GPIO_CMD_ABS_AR0x4
> +
> +#defineFSI_GPIO_DPOLL_CLOCKS   100  /* < 21 will cause slave to 
> hang */
> +
> +/* Bus errors */
> +#defineFSI_GPIO_ERR_BUSY   1   /* Slave stuck in busy state 
> */
> +#defineFSI_GPIO_RESP_ERRA  2   /* Any (misc) Error */
> +#defineFSI_GPIO_RESP_ERRC  3   /* Slave reports master CRC 
> error */
> +#defineFSI_GPIO_MTOE   4   /* Master time out error */
> +#defineFSI_GPIO_CRC_INVAL  5   /* Master reports slave CRC 
> error */
> +
> +/* Normal slave responses */
> +#defineFSI_GPIO_RESP_BUSY  1
> +#defineFSI_GPIO_RESP_ACK   0
> +#defineFSI_GPIO_RESP_ACKD  4
> +
> +#defineFSI_GPIO_MAX_BUSY   100
> +#defineFSI_GPIO_MTOE_COUNT 1000
> +#defineFSI_GPIO_DRAIN_BITS 20
> +#defineFSI_GPIO_CRC_SIZE   4
> +#defineFSI_GPIO_MSG_ID_SIZE2
> +#defineFSI_GPIO_MSG_RESPID_SIZE2
> +#defineFSI_GPIO_PRIME_SLAVE_CLOCKS 100
> +
> +static DEFINE_SPINLOCK(fsi_gpio_cmd_lock); /* lock around fsi commands */

Should this be per-master?

> +
> +struct fsi_master_gpio {
> +   struct fsi_master   master;
> +   struct device   *dev;
> +   struct gpio_desc*gpio_clk;
> +   struct gpio_desc*gpio_data;
> +   struct gpio_desc*gpio_trans;/* Voltage translator */
> +   struct gpio_desc*gpio_enable;   /* FSI enable */
> +   struct gpio_desc*gpio_mux;  /* Mux control */
> +};
> +
> +#define to_fsi_master_gpio(m) container_of(m, struct fsi_master_gpio, master)
> +
> +struct fsi_gpio_msg {
> +   uint64_tmsg;
> +   uint8_t bits;
> +};
> +
> +static void 

Re: [PATCH v6 19/23] drivers/fsi: Add GPIO based FSI master

2017-05-10 Thread Joel Stanley
Hi Chris,

On Tue, Apr 11, 2017 at 5:17 AM, Christopher Bostic
 wrote:

> From: Chris Bostic 
>
> Implement a FSI master using GPIO.  Will generate FSI protocol for
> read and write commands to particular addresses.  Sends master command
> and waits for and decodes a slave response.
>
> Includes changes from Edward A. James  and Jeremy
> Kerr .

I think the series is looking good. I've done a bunch of testing on
some machines, and it worked for me.

I've got a few comments and things to be clarified below.

>
> Signed-off-by: Edward A. James 
> Signed-off-by: Jeremy Kerr 
> Signed-off-by: Chris Bostic 
> Signed-off-by: Joel Stanley 
> ---
>  drivers/fsi/Kconfig   |  11 +
>  drivers/fsi/Makefile  |   1 +
>  drivers/fsi/fsi-master-gpio.c | 610 
> ++
>  3 files changed, 622 insertions(+)
>  create mode 100644 drivers/fsi/fsi-master-gpio.c
>
> diff --git a/drivers/fsi/Kconfig b/drivers/fsi/Kconfig
> index 04c1a0e..448bc3b 100644
> --- a/drivers/fsi/Kconfig
> +++ b/drivers/fsi/Kconfig
> @@ -9,4 +9,15 @@ config FSI
> ---help---
>   FSI - the FRU Support Interface - is a simple bus for low-level
>   access to POWER-based hardware.
> +
> +if FSI
> +
> +config FSI_MASTER_GPIO
> +   tristate "GPIO-based FSI master"
> +   depends on GPIOLIB
> +   ---help---
> +   This option enables a FSI master driver using GPIO lines.
> +
> +endif
> +
>  endmenu
> diff --git a/drivers/fsi/Makefile b/drivers/fsi/Makefile
> index db0e5e7..ed28ac0 100644
> --- a/drivers/fsi/Makefile
> +++ b/drivers/fsi/Makefile
> @@ -1,2 +1,3 @@
>
>  obj-$(CONFIG_FSI) += fsi-core.o
> +obj-$(CONFIG_FSI_MASTER_GPIO) += fsi-master-gpio.o
> diff --git a/drivers/fsi/fsi-master-gpio.c b/drivers/fsi/fsi-master-gpio.c
> new file mode 100644
> index 000..9fedfaf
> --- /dev/null
> +++ b/drivers/fsi/fsi-master-gpio.c
> @@ -0,0 +1,610 @@
> +/*
> + * A FSI master controller, using a simple GPIO bit-banging interface
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "fsi-master.h"
> +
> +#defineFSI_GPIO_STD_DLY1   /* Standard pin delay in nS */
> +#defineFSI_ECHO_DELAY_CLOCKS   16  /* Number clocks for echo 
> delay */
> +#defineFSI_PRE_BREAK_CLOCKS50  /* Number clocks to prep for 
> break */
> +#defineFSI_BREAK_CLOCKS256 /* Number of clocks to issue 
> break */
> +#defineFSI_POST_BREAK_CLOCKS   16000   /* Number clocks to set up 
> cfam */
> +#defineFSI_INIT_CLOCKS 5000/* Clock out any old data */
> +#defineFSI_GPIO_STD_DELAY  10  /* Standard GPIO delay in nS 
> */
> +   /* todo: adjust down as low as */
> +   /* possible or eliminate */
> +#defineFSI_GPIO_CMD_DPOLL  0x2
> +#defineFSI_GPIO_CMD_TERM   0x3f
> +#define FSI_GPIO_CMD_ABS_AR0x4
> +
> +#defineFSI_GPIO_DPOLL_CLOCKS   100  /* < 21 will cause slave to 
> hang */
> +
> +/* Bus errors */
> +#defineFSI_GPIO_ERR_BUSY   1   /* Slave stuck in busy state 
> */
> +#defineFSI_GPIO_RESP_ERRA  2   /* Any (misc) Error */
> +#defineFSI_GPIO_RESP_ERRC  3   /* Slave reports master CRC 
> error */
> +#defineFSI_GPIO_MTOE   4   /* Master time out error */
> +#defineFSI_GPIO_CRC_INVAL  5   /* Master reports slave CRC 
> error */
> +
> +/* Normal slave responses */
> +#defineFSI_GPIO_RESP_BUSY  1
> +#defineFSI_GPIO_RESP_ACK   0
> +#defineFSI_GPIO_RESP_ACKD  4
> +
> +#defineFSI_GPIO_MAX_BUSY   100
> +#defineFSI_GPIO_MTOE_COUNT 1000
> +#defineFSI_GPIO_DRAIN_BITS 20
> +#defineFSI_GPIO_CRC_SIZE   4
> +#defineFSI_GPIO_MSG_ID_SIZE2
> +#defineFSI_GPIO_MSG_RESPID_SIZE2
> +#defineFSI_GPIO_PRIME_SLAVE_CLOCKS 100
> +
> +static DEFINE_SPINLOCK(fsi_gpio_cmd_lock); /* lock around fsi commands */

Should this be per-master?

> +
> +struct fsi_master_gpio {
> +   struct fsi_master   master;
> +   struct device   *dev;
> +   struct gpio_desc*gpio_clk;
> +   struct gpio_desc*gpio_data;
> +   struct gpio_desc*gpio_trans;/* Voltage translator */
> +   struct gpio_desc*gpio_enable;   /* FSI enable */
> +   struct gpio_desc*gpio_mux;  /* Mux control */
> +};
> +
> +#define to_fsi_master_gpio(m) container_of(m, struct fsi_master_gpio, master)
> +
> +struct fsi_gpio_msg {
> +   uint64_tmsg;
> +   uint8_t bits;
> +};
> +
> +static void clock_toggle(struct fsi_master_gpio *master, int count)
> +{
> +   int i;
> +
> +   for (i = 0; i < count; i++) {
> +   ndelay(FSI_GPIO_STD_DLY);
> + 

[PATCH v6 19/23] drivers/fsi: Add GPIO based FSI master

2017-04-10 Thread Christopher Bostic
From: Chris Bostic 

Implement a FSI master using GPIO.  Will generate FSI protocol for
read and write commands to particular addresses.  Sends master command
and waits for and decodes a slave response.

Includes changes from Edward A. James  and Jeremy
Kerr .

Signed-off-by: Edward A. James 
Signed-off-by: Jeremy Kerr 
Signed-off-by: Chris Bostic 
Signed-off-by: Joel Stanley 
---
 drivers/fsi/Kconfig   |  11 +
 drivers/fsi/Makefile  |   1 +
 drivers/fsi/fsi-master-gpio.c | 610 ++
 3 files changed, 622 insertions(+)
 create mode 100644 drivers/fsi/fsi-master-gpio.c

diff --git a/drivers/fsi/Kconfig b/drivers/fsi/Kconfig
index 04c1a0e..448bc3b 100644
--- a/drivers/fsi/Kconfig
+++ b/drivers/fsi/Kconfig
@@ -9,4 +9,15 @@ config FSI
---help---
  FSI - the FRU Support Interface - is a simple bus for low-level
  access to POWER-based hardware.
+
+if FSI
+
+config FSI_MASTER_GPIO
+   tristate "GPIO-based FSI master"
+   depends on GPIOLIB
+   ---help---
+   This option enables a FSI master driver using GPIO lines.
+
+endif
+
 endmenu
diff --git a/drivers/fsi/Makefile b/drivers/fsi/Makefile
index db0e5e7..ed28ac0 100644
--- a/drivers/fsi/Makefile
+++ b/drivers/fsi/Makefile
@@ -1,2 +1,3 @@
 
 obj-$(CONFIG_FSI) += fsi-core.o
+obj-$(CONFIG_FSI_MASTER_GPIO) += fsi-master-gpio.o
diff --git a/drivers/fsi/fsi-master-gpio.c b/drivers/fsi/fsi-master-gpio.c
new file mode 100644
index 000..9fedfaf
--- /dev/null
+++ b/drivers/fsi/fsi-master-gpio.c
@@ -0,0 +1,610 @@
+/*
+ * A FSI master controller, using a simple GPIO bit-banging interface
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "fsi-master.h"
+
+#defineFSI_GPIO_STD_DLY1   /* Standard pin delay in nS */
+#defineFSI_ECHO_DELAY_CLOCKS   16  /* Number clocks for echo delay 
*/
+#defineFSI_PRE_BREAK_CLOCKS50  /* Number clocks to prep for 
break */
+#defineFSI_BREAK_CLOCKS256 /* Number of clocks to issue 
break */
+#defineFSI_POST_BREAK_CLOCKS   16000   /* Number clocks to set up cfam 
*/
+#defineFSI_INIT_CLOCKS 5000/* Clock out any old data */
+#defineFSI_GPIO_STD_DELAY  10  /* Standard GPIO delay in nS */
+   /* todo: adjust down as low as */
+   /* possible or eliminate */
+#defineFSI_GPIO_CMD_DPOLL  0x2
+#defineFSI_GPIO_CMD_TERM   0x3f
+#define FSI_GPIO_CMD_ABS_AR0x4
+
+#defineFSI_GPIO_DPOLL_CLOCKS   100  /* < 21 will cause slave to 
hang */
+
+/* Bus errors */
+#defineFSI_GPIO_ERR_BUSY   1   /* Slave stuck in busy state */
+#defineFSI_GPIO_RESP_ERRA  2   /* Any (misc) Error */
+#defineFSI_GPIO_RESP_ERRC  3   /* Slave reports master CRC 
error */
+#defineFSI_GPIO_MTOE   4   /* Master time out error */
+#defineFSI_GPIO_CRC_INVAL  5   /* Master reports slave CRC 
error */
+
+/* Normal slave responses */
+#defineFSI_GPIO_RESP_BUSY  1
+#defineFSI_GPIO_RESP_ACK   0
+#defineFSI_GPIO_RESP_ACKD  4
+
+#defineFSI_GPIO_MAX_BUSY   100
+#defineFSI_GPIO_MTOE_COUNT 1000
+#defineFSI_GPIO_DRAIN_BITS 20
+#defineFSI_GPIO_CRC_SIZE   4
+#defineFSI_GPIO_MSG_ID_SIZE2
+#defineFSI_GPIO_MSG_RESPID_SIZE2
+#defineFSI_GPIO_PRIME_SLAVE_CLOCKS 100
+
+static DEFINE_SPINLOCK(fsi_gpio_cmd_lock); /* lock around fsi commands */
+
+struct fsi_master_gpio {
+   struct fsi_master   master;
+   struct device   *dev;
+   struct gpio_desc*gpio_clk;
+   struct gpio_desc*gpio_data;
+   struct gpio_desc*gpio_trans;/* Voltage translator */
+   struct gpio_desc*gpio_enable;   /* FSI enable */
+   struct gpio_desc*gpio_mux;  /* Mux control */
+};
+
+#define to_fsi_master_gpio(m) container_of(m, struct fsi_master_gpio, master)
+
+struct fsi_gpio_msg {
+   uint64_tmsg;
+   uint8_t bits;
+};
+
+static void clock_toggle(struct fsi_master_gpio *master, int count)
+{
+   int i;
+
+   for (i = 0; i < count; i++) {
+   ndelay(FSI_GPIO_STD_DLY);
+   gpiod_set_value(master->gpio_clk, 0);
+   ndelay(FSI_GPIO_STD_DLY);
+   gpiod_set_value(master->gpio_clk, 1);
+   }
+}
+
+static int sda_in(struct fsi_master_gpio *master)
+{
+   int in;
+
+   ndelay(FSI_GPIO_STD_DLY);
+   in = gpiod_get_value(master->gpio_data);
+   return in ? 1 : 0;
+}
+
+static void sda_out(struct fsi_master_gpio *master, int 

[PATCH v6 19/23] drivers/fsi: Add GPIO based FSI master

2017-04-10 Thread Christopher Bostic
From: Chris Bostic 

Implement a FSI master using GPIO.  Will generate FSI protocol for
read and write commands to particular addresses.  Sends master command
and waits for and decodes a slave response.

Includes changes from Edward A. James  and Jeremy
Kerr .

Signed-off-by: Edward A. James 
Signed-off-by: Jeremy Kerr 
Signed-off-by: Chris Bostic 
Signed-off-by: Joel Stanley 
---
 drivers/fsi/Kconfig   |  11 +
 drivers/fsi/Makefile  |   1 +
 drivers/fsi/fsi-master-gpio.c | 610 ++
 3 files changed, 622 insertions(+)
 create mode 100644 drivers/fsi/fsi-master-gpio.c

diff --git a/drivers/fsi/Kconfig b/drivers/fsi/Kconfig
index 04c1a0e..448bc3b 100644
--- a/drivers/fsi/Kconfig
+++ b/drivers/fsi/Kconfig
@@ -9,4 +9,15 @@ config FSI
---help---
  FSI - the FRU Support Interface - is a simple bus for low-level
  access to POWER-based hardware.
+
+if FSI
+
+config FSI_MASTER_GPIO
+   tristate "GPIO-based FSI master"
+   depends on GPIOLIB
+   ---help---
+   This option enables a FSI master driver using GPIO lines.
+
+endif
+
 endmenu
diff --git a/drivers/fsi/Makefile b/drivers/fsi/Makefile
index db0e5e7..ed28ac0 100644
--- a/drivers/fsi/Makefile
+++ b/drivers/fsi/Makefile
@@ -1,2 +1,3 @@
 
 obj-$(CONFIG_FSI) += fsi-core.o
+obj-$(CONFIG_FSI_MASTER_GPIO) += fsi-master-gpio.o
diff --git a/drivers/fsi/fsi-master-gpio.c b/drivers/fsi/fsi-master-gpio.c
new file mode 100644
index 000..9fedfaf
--- /dev/null
+++ b/drivers/fsi/fsi-master-gpio.c
@@ -0,0 +1,610 @@
+/*
+ * A FSI master controller, using a simple GPIO bit-banging interface
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "fsi-master.h"
+
+#defineFSI_GPIO_STD_DLY1   /* Standard pin delay in nS */
+#defineFSI_ECHO_DELAY_CLOCKS   16  /* Number clocks for echo delay 
*/
+#defineFSI_PRE_BREAK_CLOCKS50  /* Number clocks to prep for 
break */
+#defineFSI_BREAK_CLOCKS256 /* Number of clocks to issue 
break */
+#defineFSI_POST_BREAK_CLOCKS   16000   /* Number clocks to set up cfam 
*/
+#defineFSI_INIT_CLOCKS 5000/* Clock out any old data */
+#defineFSI_GPIO_STD_DELAY  10  /* Standard GPIO delay in nS */
+   /* todo: adjust down as low as */
+   /* possible or eliminate */
+#defineFSI_GPIO_CMD_DPOLL  0x2
+#defineFSI_GPIO_CMD_TERM   0x3f
+#define FSI_GPIO_CMD_ABS_AR0x4
+
+#defineFSI_GPIO_DPOLL_CLOCKS   100  /* < 21 will cause slave to 
hang */
+
+/* Bus errors */
+#defineFSI_GPIO_ERR_BUSY   1   /* Slave stuck in busy state */
+#defineFSI_GPIO_RESP_ERRA  2   /* Any (misc) Error */
+#defineFSI_GPIO_RESP_ERRC  3   /* Slave reports master CRC 
error */
+#defineFSI_GPIO_MTOE   4   /* Master time out error */
+#defineFSI_GPIO_CRC_INVAL  5   /* Master reports slave CRC 
error */
+
+/* Normal slave responses */
+#defineFSI_GPIO_RESP_BUSY  1
+#defineFSI_GPIO_RESP_ACK   0
+#defineFSI_GPIO_RESP_ACKD  4
+
+#defineFSI_GPIO_MAX_BUSY   100
+#defineFSI_GPIO_MTOE_COUNT 1000
+#defineFSI_GPIO_DRAIN_BITS 20
+#defineFSI_GPIO_CRC_SIZE   4
+#defineFSI_GPIO_MSG_ID_SIZE2
+#defineFSI_GPIO_MSG_RESPID_SIZE2
+#defineFSI_GPIO_PRIME_SLAVE_CLOCKS 100
+
+static DEFINE_SPINLOCK(fsi_gpio_cmd_lock); /* lock around fsi commands */
+
+struct fsi_master_gpio {
+   struct fsi_master   master;
+   struct device   *dev;
+   struct gpio_desc*gpio_clk;
+   struct gpio_desc*gpio_data;
+   struct gpio_desc*gpio_trans;/* Voltage translator */
+   struct gpio_desc*gpio_enable;   /* FSI enable */
+   struct gpio_desc*gpio_mux;  /* Mux control */
+};
+
+#define to_fsi_master_gpio(m) container_of(m, struct fsi_master_gpio, master)
+
+struct fsi_gpio_msg {
+   uint64_tmsg;
+   uint8_t bits;
+};
+
+static void clock_toggle(struct fsi_master_gpio *master, int count)
+{
+   int i;
+
+   for (i = 0; i < count; i++) {
+   ndelay(FSI_GPIO_STD_DLY);
+   gpiod_set_value(master->gpio_clk, 0);
+   ndelay(FSI_GPIO_STD_DLY);
+   gpiod_set_value(master->gpio_clk, 1);
+   }
+}
+
+static int sda_in(struct fsi_master_gpio *master)
+{
+   int in;
+
+   ndelay(FSI_GPIO_STD_DLY);
+   in = gpiod_get_value(master->gpio_data);
+   return in ? 1 : 0;
+}
+
+static void sda_out(struct fsi_master_gpio *master, int value)
+{
+   gpiod_set_value(master->gpio_data, value);
+}
+
+static void set_sda_input(struct fsi_master_gpio *master)
+{
+