[PATCH v3] platform/mellanox: mlxbf-pmc: Add Mellanox BlueField PMC driver

2020-10-08 Thread Shravan Kumar Ramani
The performance modules in BlueField are present in several hardware
blocks and each block provides access to these stats either through
counters that can be programmed to monitor supported events or
through memory-mapped registers that hold the relevant information.
The hardware blocks that include a performance module are:
 * Tile (block containing 2 cores and a shared L2 cache)
 * TRIO (PCIe root complex)
 * MSS (Memory Sub-system containing the Memory Controller and L3 cache)
 * GIC (Interrupt controller)
 * SMMU (System Memory Management Unit)
The mlx_pmc driver provides access to all of these performance modules
through a hwmon sysfs interface.

v2 --> v3
Update copyright info.

v1 --> v2
Remove unused headers.
Add comma to arrays where last line is not a termination.
Use kstrtoint in place of sscanf.
UUID manipulation follows drivers/platform/mellanox/mlxbf-bootctl.c

Signed-off-by: Shravan Kumar Ramani 
Reviewed-by: Vadim Pasternak 
Reviewed-by: Jiri Pirko 
---
 drivers/platform/mellanox/Kconfig |   10 +
 drivers/platform/mellanox/Makefile|1 +
 drivers/platform/mellanox/mlxbf-pmc.c | 1478 +
 3 files changed, 1489 insertions(+)
 create mode 100644 drivers/platform/mellanox/mlxbf-pmc.c

diff --git a/drivers/platform/mellanox/Kconfig 
b/drivers/platform/mellanox/Kconfig
index 916b39d..edd17e1 100644
--- a/drivers/platform/mellanox/Kconfig
+++ b/drivers/platform/mellanox/Kconfig
@@ -56,4 +56,14 @@ config MLXBF_BOOTCTL
  to the userspace tools, to be used in conjunction with the eMMC
  device driver to do necessary initial swap of the boot partition.
 
+config MLXBF_PMC
+   tristate "Mellanox BlueField Performance Monitoring Counters driver"
+   depends on ARM64
+   depends on HWMON
+   depends on ACPI
+   help
+ Say y here to enable PMC support. The PMC driver provides access
+ to performance monitoring counters within various blocks in the
+ Mellanox BlueField SoC via a sysfs interface.
+
 endif # MELLANOX_PLATFORM
diff --git a/drivers/platform/mellanox/Makefile 
b/drivers/platform/mellanox/Makefile
index 499623c..000ddaa 100644
--- a/drivers/platform/mellanox/Makefile
+++ b/drivers/platform/mellanox/Makefile
@@ -4,6 +4,7 @@
 # Mellanox Platform-Specific Drivers
 #
 obj-$(CONFIG_MLXBF_BOOTCTL)+= mlxbf-bootctl.o
+obj-$(CONFIG_MLXBF_PMC)+= mlxbf-pmc.o
 obj-$(CONFIG_MLXBF_TMFIFO) += mlxbf-tmfifo.o
 obj-$(CONFIG_MLXREG_HOTPLUG)   += mlxreg-hotplug.o
 obj-$(CONFIG_MLXREG_IO) += mlxreg-io.o
diff --git a/drivers/platform/mellanox/mlxbf-pmc.c 
b/drivers/platform/mellanox/mlxbf-pmc.c
new file mode 100644
index 000..3588398
--- /dev/null
+++ b/drivers/platform/mellanox/mlxbf-pmc.c
@@ -0,0 +1,1478 @@
+// SPDX-License-Identifier: GPL-2.0-only OR Linux-OpenIB
+/*
+ * Mellanox BlueField Performance Monitoring Counters driver
+ *
+ * This driver provides a sysfs interface for monitoring
+ * performance statistics in BlueField SoC.
+ *
+ * Copyright (c) 2020, NVIDIA CORPORATION.  All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MLXBF_PMC_WRITE_REG_32 0x8209
+#define MLXBF_PMC_READ_REG_32 0x820A
+#define MLXBF_PMC_WRITE_REG_64 0x820B
+#define MLXBF_PMC_READ_REG_64 0x820C
+#define MLXBF_PMC_SIP_SVC_UID 0x8200ff01
+#define MLXBF_PMC_SIP_SVC_VERSION 0x8200ff03
+#define MLXBF_PMC_SVC_REQ_MAJOR 0
+#define MLXBF_PMC_SVC_MIN_MINOR 3
+
+#define MLXBF_PMC_SMCCC_ACCESS_VIOLATION -4
+
+#define MLXBF_PMC_EVENT_SET_BF1 0
+#define MLXBF_PMC_EVENT_SET_BF2 1
+#define MLXBF_PMC_EVENT_INFO_LEN 100
+
+#define MLXBF_PMC_MAX_BLOCKS 30
+#define MLXBF_PMC_MAX_ATTRS 30
+#define MLXBF_PMC_INFO_SZ 4
+#define MLXBF_PMC_REG_SIZE 8
+#define MLXBF_PMC_L3C_REG_SIZE 4
+
+#define MLXBF_PMC_TYPE_COUNTER 1
+#define MLXBF_PMC_TYPE_REGISTER 0
+
+#define MLXBF_PMC_PERFCTL 0
+#define MLXBF_PMC_PERFEVT 1
+#define MLXBF_PMC_PERFACC0 4
+
+#define MLXBF_PMC_PERFMON_CONFIG_WR_R_B BIT(0)
+#define MLXBF_PMC_PERFMON_CONFIG_STROBE BIT(1)
+#define MLXBF_PMC_PERFMON_CONFIG_ADDR GENMASK_ULL(4, 2)
+#define MLXBF_PMC_PERFMON_CONFIG_WDATA GENMASK_ULL(60, 5)
+
+#define MLXBF_PMC_PERFCTL_FM0 GENMASK_ULL(18, 16)
+#define MLXBF_PMC_PERFCTL_MS0 GENMASK_ULL(21, 20)
+#define MLXBF_PMC_PERFCTL_ACCM0 GENMASK_ULL(26, 24)
+#define MLXBF_PMC_PERFCTL_AD0 BIT(27)
+#define MLXBF_PMC_PERFCTL_ETRIG0 GENMASK_ULL(29, 28)
+#define MLXBF_PMC_PERFCTL_EB0 BIT(30)
+#define MLXBF_PMC_PERFCTL_EN0 BIT(31)
+
+#define MLXBF_PMC_PERFEVT_EVTSEL GENMASK_ULL(31, 24)
+
+#define MLXBF_PMC_L3C_PERF_CNT_CFG 0x0
+#define MLXBF_PMC_L3C_PERF_CNT_SEL 0x10
+#define MLXBF_PMC_L3C_PERF_CNT_SEL_1 0x14
+#define MLXBF_PMC_L3C_PERF_CNT_LOW 0x40
+#define MLXBF_PMC_L3C_PERF_CNT_HIGH 0x60
+
+#define MLXBF_PMC_L3C_PERF_CNT_CFG_EN BIT(0)
+#define MLXBF_PMC_L3C_PERF_CNT_CFG_RST BIT(1)
+#define MLXBF_PMC_L3C_PERF_CNT_SEL_CNT_0 GENMASK(5, 0)
+#define MLXBF_PMC_L3C_PERF_CNT_SEL_CNT

[PATCH v2] platform/mellanox: mlxbf-pmc: Add Mellanox BlueField PMC driver

2020-08-03 Thread Shravan Kumar Ramani
The performance modules in BlueField are present in several hardware
blocks and each block provides access to these stats either through
counters that can be programmed to monitor supported events or
through memory-mapped registers that hold the relevant information.
The hardware blocks that include a performance module are:
 * Tile (block containing 2 cores and a shared L2 cache)
 * TRIO (PCIe root complex)
 * MSS (Memory Sub-system containing the Memory Controller and L3 cache)
 * GIC (Interrupt controller)
 * SMMU (System Memory Management Unit)
The mlx_pmc driver provides access to all of these performance modules
through a hwmon sysfs interface.

v1 --> v2
Remove unused headers.
Add comma to arrays where last line is not a termination.
Use kstrtoint in place of sscanf.
UUID manipulation follows drivers/platform/mellanox/mlxbf-bootctl.c

Signed-off-by: Shravan Kumar Ramani 
Reviewed-by: Vadim Pasternak 
Reviewed-by: Jiri Pirko 
---
 drivers/platform/mellanox/Kconfig |   10 +
 drivers/platform/mellanox/Makefile|1 +
 drivers/platform/mellanox/mlxbf-pmc.c | 1478 +
 3 files changed, 1489 insertions(+)
 create mode 100644 drivers/platform/mellanox/mlxbf-pmc.c

diff --git a/drivers/platform/mellanox/Kconfig 
b/drivers/platform/mellanox/Kconfig
index 916b39d..edd17e1 100644
--- a/drivers/platform/mellanox/Kconfig
+++ b/drivers/platform/mellanox/Kconfig
@@ -56,4 +56,14 @@ config MLXBF_BOOTCTL
  to the userspace tools, to be used in conjunction with the eMMC
  device driver to do necessary initial swap of the boot partition.
 
+config MLXBF_PMC
+   tristate "Mellanox BlueField Performance Monitoring Counters driver"
+   depends on ARM64
+   depends on HWMON
+   depends on ACPI
+   help
+ Say y here to enable PMC support. The PMC driver provides access
+ to performance monitoring counters within various blocks in the
+ Mellanox BlueField SoC via a sysfs interface.
+
 endif # MELLANOX_PLATFORM
diff --git a/drivers/platform/mellanox/Makefile 
b/drivers/platform/mellanox/Makefile
index 499623c..000ddaa 100644
--- a/drivers/platform/mellanox/Makefile
+++ b/drivers/platform/mellanox/Makefile
@@ -4,6 +4,7 @@
 # Mellanox Platform-Specific Drivers
 #
 obj-$(CONFIG_MLXBF_BOOTCTL)+= mlxbf-bootctl.o
+obj-$(CONFIG_MLXBF_PMC)+= mlxbf-pmc.o
 obj-$(CONFIG_MLXBF_TMFIFO) += mlxbf-tmfifo.o
 obj-$(CONFIG_MLXREG_HOTPLUG)   += mlxreg-hotplug.o
 obj-$(CONFIG_MLXREG_IO) += mlxreg-io.o
diff --git a/drivers/platform/mellanox/mlxbf-pmc.c 
b/drivers/platform/mellanox/mlxbf-pmc.c
new file mode 100644
index 000..24e558c
--- /dev/null
+++ b/drivers/platform/mellanox/mlxbf-pmc.c
@@ -0,0 +1,1478 @@
+// SPDX-License-Identifier: GPL-2.0-only OR Linux-OpenIB
+/*
+ * Mellanox BlueField Performance Monitoring Counters driver
+ *
+ * This driver provides a sysfs interface for monitoring
+ * performance statistics in BlueField SoC.
+ *
+ * Copyright (C) 2020 Mellanox Technologies Ltd.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MLXBF_PMC_WRITE_REG_32 0x8209
+#define MLXBF_PMC_READ_REG_32 0x820A
+#define MLXBF_PMC_WRITE_REG_64 0x820B
+#define MLXBF_PMC_READ_REG_64 0x820C
+#define MLXBF_PMC_SIP_SVC_UID 0x8200ff01
+#define MLXBF_PMC_SIP_SVC_VERSION 0x8200ff03
+#define MLXBF_PMC_SVC_REQ_MAJOR 0
+#define MLXBF_PMC_SVC_MIN_MINOR 3
+
+#define MLXBF_PMC_SMCCC_ACCESS_VIOLATION -4
+
+#define MLXBF_PMC_EVENT_SET_BF1 0
+#define MLXBF_PMC_EVENT_SET_BF2 1
+#define MLXBF_PMC_EVENT_INFO_LEN 100
+
+#define MLXBF_PMC_MAX_BLOCKS 30
+#define MLXBF_PMC_MAX_ATTRS 30
+#define MLXBF_PMC_INFO_SZ 4
+#define MLXBF_PMC_REG_SIZE 8
+#define MLXBF_PMC_L3C_REG_SIZE 4
+
+#define MLXBF_PMC_TYPE_COUNTER 1
+#define MLXBF_PMC_TYPE_REGISTER 0
+
+#define MLXBF_PMC_PERFCTL 0
+#define MLXBF_PMC_PERFEVT 1
+#define MLXBF_PMC_PERFACC0 4
+
+#define MLXBF_PMC_PERFMON_CONFIG_WR_R_B BIT(0)
+#define MLXBF_PMC_PERFMON_CONFIG_STROBE BIT(1)
+#define MLXBF_PMC_PERFMON_CONFIG_ADDR GENMASK_ULL(4, 2)
+#define MLXBF_PMC_PERFMON_CONFIG_WDATA GENMASK_ULL(60, 5)
+
+#define MLXBF_PMC_PERFCTL_FM0 GENMASK_ULL(18, 16)
+#define MLXBF_PMC_PERFCTL_MS0 GENMASK_ULL(21, 20)
+#define MLXBF_PMC_PERFCTL_ACCM0 GENMASK_ULL(26, 24)
+#define MLXBF_PMC_PERFCTL_AD0 BIT(27)
+#define MLXBF_PMC_PERFCTL_ETRIG0 GENMASK_ULL(29, 28)
+#define MLXBF_PMC_PERFCTL_EB0 BIT(30)
+#define MLXBF_PMC_PERFCTL_EN0 BIT(31)
+
+#define MLXBF_PMC_PERFEVT_EVTSEL GENMASK_ULL(31, 24)
+
+#define MLXBF_PMC_L3C_PERF_CNT_CFG 0x0
+#define MLXBF_PMC_L3C_PERF_CNT_SEL 0x10
+#define MLXBF_PMC_L3C_PERF_CNT_SEL_1 0x14
+#define MLXBF_PMC_L3C_PERF_CNT_LOW 0x40
+#define MLXBF_PMC_L3C_PERF_CNT_HIGH 0x60
+
+#define MLXBF_PMC_L3C_PERF_CNT_CFG_EN BIT(0)
+#define MLXBF_PMC_L3C_PERF_CNT_CFG_RST BIT(1)
+#define MLXBF_PMC_L3C_PERF_CNT_SEL_CNT_0 GENMASK(5, 0)
+#define MLXBF_PMC_L3C_PERF_CNT_SEL_CNT_1 GENMASK(13, 8)
+#define MLXBF_PMC_L3C_PERF_CNT_SEL_CNT

RE: [PATCH v1] platform/mellanox: mlxbf-pmc: Add Mellanox BlueField PMC driver

2020-07-27 Thread Shravan Ramani


> -Original Message-
> From: Andy Shevchenko 
> Sent: Monday, July 27, 2020 4:24 PM
> To: Shravan Ramani 
> Cc: Andy Shevchenko ; Darren Hart
> ; Vadim Pasternak ; Jiri Pirko
> ; Platform Driver ;
> Linux Kernel Mailing List 
> Subject: Re: [PATCH v1] platform/mellanox: mlxbf-pmc: Add Mellanox BlueField
> PMC driver
> 
> On Mon, Jul 27, 2020 at 12:02 PM Shravan Kumar Ramani
>  wrote:
> >
> > The performance modules in BlueField are present in several hardware
> > blocks and each block provides access to these stats either through
> > counters that can be programmed to monitor supported events or through
> > memory-mapped registers that hold the relevant information.
> > The hardware blocks that include a performance module are:
> >  * Tile (block containing 2 cores and a shared L2 cache)
> >  * TRIO (PCIe root complex)
> >  * MSS (Memory Sub-system containing the Memory Controller and L3
> > cache)
> >  * GIC (Interrupt controller)
> >  * SMMU (System Memory Management Unit) The mlx_pmc driver provides
> > access to all of these performance modules through a hwmon sysfs
> > interface.
> 
> Just brief comments:
> - consider to revisit header block to see what is really necessary and what 
> can
> be dropped
> - add comma to the arrays where last line is not a termination
> - look at match_string() / sysfs_match_string() API, I think they can be 
> utilised
> here
> - UUID manipulations (esp. with that GUID_INIT() against non-constant) seems
> too much, consider refactoring and cleaning up these pieces

Could you please elaborate on what approach you'd like me to take with the UUID 
manipulation?
I used the same approach as in drivers/platform/mellanox/mlxbf-bootctl.c which 
seemed like an appropriate example.
Any other pointers would be helpful.

Thanks for the feedback. Will address all the other comments in v2.

Regards,
Shravan

> - use kstroto*() API instead of sscanf. It has a range check
> 
> 
> --
> With Best Regards,
> Andy Shevchenko


[PATCH v1] platform/mellanox: mlxbf-pmc: Add Mellanox BlueField PMC driver

2020-07-27 Thread Shravan Kumar Ramani
The performance modules in BlueField are present in several hardware
blocks and each block provides access to these stats either through
counters that can be programmed to monitor supported events or
through memory-mapped registers that hold the relevant information.
The hardware blocks that include a performance module are:
 * Tile (block containing 2 cores and a shared L2 cache)
 * TRIO (PCIe root complex)
 * MSS (Memory Sub-system containing the Memory Controller and L3 cache)
 * GIC (Interrupt controller)
 * SMMU (System Memory Management Unit)
The mlx_pmc driver provides access to all of these performance modules
through a hwmon sysfs interface.

Signed-off-by: Shravan Kumar Ramani 
Reviewed-by: Jiri Pirko 
---
 drivers/platform/mellanox/Kconfig |   10 +
 drivers/platform/mellanox/Makefile|1 +
 drivers/platform/mellanox/mlxbf-pmc.c | 1486 +
 3 files changed, 1497 insertions(+)
 create mode 100644 drivers/platform/mellanox/mlxbf-pmc.c

diff --git a/drivers/platform/mellanox/Kconfig 
b/drivers/platform/mellanox/Kconfig
index 916b39d..edd17e1 100644
--- a/drivers/platform/mellanox/Kconfig
+++ b/drivers/platform/mellanox/Kconfig
@@ -56,4 +56,14 @@ config MLXBF_BOOTCTL
  to the userspace tools, to be used in conjunction with the eMMC
  device driver to do necessary initial swap of the boot partition.
 
+config MLXBF_PMC
+   tristate "Mellanox BlueField Performance Monitoring Counters driver"
+   depends on ARM64
+   depends on HWMON
+   depends on ACPI
+   help
+ Say y here to enable PMC support. The PMC driver provides access
+ to performance monitoring counters within various blocks in the
+ Mellanox BlueField SoC via a sysfs interface.
+
 endif # MELLANOX_PLATFORM
diff --git a/drivers/platform/mellanox/Makefile 
b/drivers/platform/mellanox/Makefile
index 499623c..000ddaa 100644
--- a/drivers/platform/mellanox/Makefile
+++ b/drivers/platform/mellanox/Makefile
@@ -4,6 +4,7 @@
 # Mellanox Platform-Specific Drivers
 #
 obj-$(CONFIG_MLXBF_BOOTCTL)+= mlxbf-bootctl.o
+obj-$(CONFIG_MLXBF_PMC)+= mlxbf-pmc.o
 obj-$(CONFIG_MLXBF_TMFIFO) += mlxbf-tmfifo.o
 obj-$(CONFIG_MLXREG_HOTPLUG)   += mlxreg-hotplug.o
 obj-$(CONFIG_MLXREG_IO) += mlxreg-io.o
diff --git a/drivers/platform/mellanox/mlxbf-pmc.c 
b/drivers/platform/mellanox/mlxbf-pmc.c
new file mode 100644
index 000..07d6790
--- /dev/null
+++ b/drivers/platform/mellanox/mlxbf-pmc.c
@@ -0,0 +1,1486 @@
+// SPDX-License-Identifier: GPL-2.0-only OR Linux-OpenIB
+/*
+ * Mellanox BlueField Performance Monitoring Counters driver
+ *
+ * This driver provides a sysfs interface for monitoring
+ * performance statistics in BlueField SoC.
+ *
+ * Copyright (C) 2020 Mellanox Technologies Ltd.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MLXBF_PMC_WRITE_REG_32 0x8209
+#define MLXBF_PMC_READ_REG_32 0x820A
+#define MLXBF_PMC_WRITE_REG_64 0x820B
+#define MLXBF_PMC_READ_REG_64 0x820C
+#define MLXBF_PMC_SIP_SVC_UID 0x8200ff01
+#define MLXBF_PMC_SIP_SVC_VERSION 0x8200ff03
+#define MLXBF_PMC_SVC_REQ_MAJOR 0
+#define MLXBF_PMC_SVC_MIN_MINOR 3
+
+#define MLXBF_PMC_SMCCC_ACCESS_VIOLATION -4
+
+#define MLXBF_PMC_EVENT_SET_BF1 0
+#define MLXBF_PMC_EVENT_SET_BF2 1
+#define MLXBF_PMC_EVENT_INFO_LEN 100
+
+#define MLXBF_PMC_MAX_BLOCKS 30
+#define MLXBF_PMC_MAX_ATTRS 30
+#define MLXBF_PMC_INFO_SZ 4
+#define MLXBF_PMC_REG_SIZE 8
+#define MLXBF_PMC_L3C_REG_SIZE 4
+
+#define MLXBF_PMC_TYPE_COUNTER 1
+#define MLXBF_PMC_TYPE_REGISTER 0
+
+#define MLXBF_PMC_PERFCTL 0
+#define MLXBF_PMC_PERFEVT 1
+#define MLXBF_PMC_PERFACC0 4
+
+#define MLXBF_PMC_PERFMON_CONFIG_WR_R_B BIT(0)
+#define MLXBF_PMC_PERFMON_CONFIG_STROBE BIT(1)
+#define MLXBF_PMC_PERFMON_CONFIG_ADDR GENMASK_ULL(4, 2)
+#define MLXBF_PMC_PERFMON_CONFIG_WDATA GENMASK_ULL(60, 5)
+
+#define MLXBF_PMC_PERFCTL_FM0 GENMASK_ULL(18, 16)
+#define MLXBF_PMC_PERFCTL_MS0 GENMASK_ULL(21, 20)
+#define MLXBF_PMC_PERFCTL_ACCM0 GENMASK_ULL(26, 24)
+#define MLXBF_PMC_PERFCTL_AD0 BIT(27)
+#define MLXBF_PMC_PERFCTL_ETRIG0 GENMASK_ULL(29, 28)
+#define MLXBF_PMC_PERFCTL_EB0 BIT(30)
+#define MLXBF_PMC_PERFCTL_EN0 BIT(31)
+
+#define MLXBF_PMC_PERFEVT_EVTSEL GENMASK_ULL(31, 24)
+
+#define MLXBF_PMC_L3C_PERF_CNT_CFG 0x0
+#define MLXBF_PMC_L3C_PERF_CNT_SEL 0x10
+#define MLXBF_PMC_L3C_PERF_CNT_SEL_1 0x14
+#define MLXBF_PMC_L3C_PERF_CNT_LOW 0x40
+#define MLXBF_PMC_L3C_PERF_CNT_HIGH 0x60
+
+#define MLXBF_PMC_L3C_PERF_CNT_CFG_EN BIT(0)
+#define MLXBF_PMC_L3C_PERF_CNT_CFG_RST BIT(1)
+#define MLXBF_PMC_L3C_PERF_CNT_SEL_CNT_0 GENMASK(5, 0)
+#define MLXBF_PMC_L3C_PERF_CNT_SEL_CNT_1 GENMASK(13, 8)
+#define MLXBF_PMC_L3C_PERF_CNT_SEL_CNT_2 GENMASK(21, 16)
+#define MLXBF_PMC_L3C_PERF_CNT_SEL_CNT_3 GENMASK(29, 24)
+
+#define MLXBF_PMC_L3C_PERF_CNT_SEL_1_CNT_4 GENMASK(5, 0)

[PATCH v7 0/1] EDAC, mellanox: Add ECC support for BlueField DDR4

2019-06-25 Thread Shravan Kumar Ramani
Changes since v6:
Use FIELD_GET and GENMASK instead of shifting/masking using separate macros

Shravan Kumar Ramani (1):
  EDAC, mellanox: Add ECC support for BlueField DDR4

 MAINTAINERS   |   5 +
 drivers/edac/Kconfig  |   7 +
 drivers/edac/Makefile |   1 +
 drivers/edac/bluefield_edac.c | 356 ++
 4 files changed, 369 insertions(+)
 create mode 100644 drivers/edac/bluefield_edac.c

-- 
2.1.2



[PATCH v7 1/1] EDAC, mellanox: Add ECC support for BlueField DDR4

2019-06-25 Thread Shravan Kumar Ramani
Add ECC support for Mellanox BlueField SoC DDR controller.
This requires SMC to the running Arm Trusted Firmware to report
what is the current memory configuration.

Reviewed-by: James Morse 
Signed-off-by: Shravan Kumar Ramani 
---
 MAINTAINERS   |   5 +
 drivers/edac/Kconfig  |   7 +
 drivers/edac/Makefile |   1 +
 drivers/edac/bluefield_edac.c | 356 ++
 4 files changed, 369 insertions(+)
 create mode 100644 drivers/edac/bluefield_edac.c

diff --git a/MAINTAINERS b/MAINTAINERS
index d0ed735..a821587 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5669,6 +5669,11 @@ S:   Supported
 F: drivers/edac/aspeed_edac.c
 F: Documentation/devicetree/bindings/edac/aspeed-sdram-edac.txt
 
+EDAC-BLUEFIELD
+M: Shravan Kumar Ramani 
+S: Supported
+F: drivers/edac/bluefield_edac.c
+
 EDAC-CALXEDA
 M: Robert Richter 
 L: linux-e...@vger.kernel.org
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index 5e2e034..43df551 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -504,4 +504,11 @@ config EDAC_ASPEED
  First, ECC must be configured in the bootloader. Then, this driver
  will expose error counters via the EDAC kernel framework.
 
+config EDAC_BLUEFIELD
+   tristate "Mellanox BlueField Memory ECC"
+   depends on ARM64 && ((MELLANOX_PLATFORM && ACPI) || COMPILE_TEST)
+   help
+ Support for error detection and correction on the
+ Mellanox BlueField SoCs.
+
 endif # EDAC
diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile
index 89ad4a84..0294a67 100644
--- a/drivers/edac/Makefile
+++ b/drivers/edac/Makefile
@@ -84,3 +84,4 @@ obj-$(CONFIG_EDAC_XGENE)  += xgene_edac.o
 obj-$(CONFIG_EDAC_TI)  += ti_edac.o
 obj-$(CONFIG_EDAC_QCOM)+= qcom_edac.o
 obj-$(CONFIG_EDAC_ASPEED)  += aspeed_edac.o
+obj-$(CONFIG_EDAC_BLUEFIELD)   += bluefield_edac.o
diff --git a/drivers/edac/bluefield_edac.c b/drivers/edac/bluefield_edac.c
new file mode 100644
index 000..e4736eb
--- /dev/null
+++ b/drivers/edac/bluefield_edac.c
@@ -0,0 +1,356 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Bluefield-specific EDAC driver.
+ *
+ * Copyright (c) 2019 Mellanox Technologies.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "edac_module.h"
+
+#define DRIVER_NAME"bluefield-edac"
+
+/*
+ * Mellanox BlueField EMI (External Memory Interface) register definitions.
+ */
+
+#define MLXBF_ECC_CNT 0x340
+#define MLXBF_ECC_CNT__SERR_CNT GENMASK(15, 0)
+#define MLXBF_ECC_CNT__DERR_CNT GENMASK(31, 16)
+
+#define MLXBF_ECC_ERR 0x348
+#define MLXBF_ECC_ERR__SECC BIT(0)
+#define MLXBF_ECC_ERR__DECC BIT(16)
+
+#define MLXBF_ECC_LATCH_SEL 0x354
+#define MLXBF_ECC_LATCH_SEL__START BIT(24)
+
+#define MLXBF_ERR_ADDR_0 0x358
+
+#define MLXBF_ERR_ADDR_1 0x37c
+
+#define MLXBF_SYNDROM 0x35c
+#define MLXBF_SYNDROM__DERR BIT(0)
+#define MLXBF_SYNDROM__SERR BIT(1)
+#define MLXBF_SYNDROM__SYN GENMASK(25, 16)
+
+#define MLXBF_ADD_INFO 0x364
+#define MLXBF_ADD_INFO__ERR_PRANK GENMASK(9, 8)
+
+#define MLXBF_EDAC_MAX_DIMM_PER_MC 2
+#define MLXBF_EDAC_ERROR_GRAIN 8
+
+/*
+ * Request MLNX_SIP_GET_DIMM_INFO
+ *
+ * Retrieve information about DIMM on a certain slot.
+ *
+ * Call register usage:
+ * a0: MLNX_SIP_GET_DIMM_INFO
+ * a1: (Memory controller index) << 16 | (Dimm index in memory controller)
+ * a2-7: not used.
+ *
+ * Return status:
+ * a0: MLXBF_DIMM_INFO defined below describing the DIMM.
+ * a1-3: not used.
+ */
+#define MLNX_SIP_GET_DIMM_INFO 0x8208
+
+/* Format for the SMC response about the memory information */
+#define MLXBF_DIMM_INFO__SIZE_GB GENMASK_ULL(15, 0)
+#define MLXBF_DIMM_INFO__IS_RDIMM BIT(16)
+#define MLXBF_DIMM_INFO__IS_LRDIMM BIT(17)
+#define MLXBF_DIMM_INFO__IS_NVDIMM BIT(18)
+#define MLXBF_DIMM_INFO__RANKS GENMASK_ULL(23, 21)
+#define MLXBF_DIMM_INFO__PACKAGE_X GENMASK_ULL(31, 24)
+
+struct bluefield_edac_priv {
+   int dimm_ranks[MLXBF_EDAC_MAX_DIMM_PER_MC];
+   void __iomem *emi_base;
+   int dimm_per_mc;
+};
+
+static u64 smc_call1(u64 smc_op, u64 smc_arg)
+{
+   struct arm_smccc_res res;
+
+   arm_smccc_smc(smc_op, smc_arg, 0, 0, 0, 0, 0, 0, );
+
+   return res.a0;
+}
+
+/*
+ * Gather the ECC information from the External Memory Interface registers
+ * and report it to the edac handler.
+ */
+static void bluefield_gather_report_ecc(struct mem_ctl_info *mci,
+   int error_cnt,
+   int is_single_ecc)
+{
+   struct bluefield_edac_priv *priv = mci->pvt_info;
+   u32 dram_additional_info, err_prank, edea0, edea1;
+   u32 ecc_latch_select, dram_syndrom, serr, derr, syndrom;
+   enum hw_event_mc_err_type ecc_type;
+   u64 ecc_dimm_addr;
+   int ecc_dimm;
+
+ 

[PATCH v6 1/1] EDAC, mellanox: Add ECC support for BlueField DDR4

2019-06-24 Thread Shravan Kumar Ramani
Add ECC support for Mellanox BlueField SoC DDR controller.
This requires SMC to the running Arm Trusted Firmware to report
what is the current memory configuration.

Reviewed-by: James Morse 
Signed-off-by: Shravan Kumar Ramani 
---
 MAINTAINERS   |   5 +
 drivers/edac/Kconfig  |   7 +
 drivers/edac/Makefile |   1 +
 drivers/edac/bluefield_edac.c | 381 ++
 4 files changed, 394 insertions(+)
 create mode 100644 drivers/edac/bluefield_edac.c

diff --git a/MAINTAINERS b/MAINTAINERS
index d0ed735..a821587 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5669,6 +5669,11 @@ S:   Supported
 F: drivers/edac/aspeed_edac.c
 F: Documentation/devicetree/bindings/edac/aspeed-sdram-edac.txt
 
+EDAC-BLUEFIELD
+M: Shravan Kumar Ramani 
+S: Supported
+F: drivers/edac/bluefield_edac.c
+
 EDAC-CALXEDA
 M: Robert Richter 
 L: linux-e...@vger.kernel.org
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index 5e2e034..43df551 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -504,4 +504,11 @@ config EDAC_ASPEED
  First, ECC must be configured in the bootloader. Then, this driver
  will expose error counters via the EDAC kernel framework.
 
+config EDAC_BLUEFIELD
+   tristate "Mellanox BlueField Memory ECC"
+   depends on ARM64 && ((MELLANOX_PLATFORM && ACPI) || COMPILE_TEST)
+   help
+ Support for error detection and correction on the
+ Mellanox BlueField SoCs.
+
 endif # EDAC
diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile
index 89ad4a84..0294a67 100644
--- a/drivers/edac/Makefile
+++ b/drivers/edac/Makefile
@@ -84,3 +84,4 @@ obj-$(CONFIG_EDAC_XGENE)  += xgene_edac.o
 obj-$(CONFIG_EDAC_TI)  += ti_edac.o
 obj-$(CONFIG_EDAC_QCOM)+= qcom_edac.o
 obj-$(CONFIG_EDAC_ASPEED)  += aspeed_edac.o
+obj-$(CONFIG_EDAC_BLUEFIELD)   += bluefield_edac.o
diff --git a/drivers/edac/bluefield_edac.c b/drivers/edac/bluefield_edac.c
new file mode 100644
index 000..a0300a4
--- /dev/null
+++ b/drivers/edac/bluefield_edac.c
@@ -0,0 +1,381 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Bluefield-specific EDAC driver.
+ *
+ * Copyright (c) 2019 Mellanox Technologies.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "edac_module.h"
+
+#define DRIVER_NAME"bluefield-edac"
+
+/*
+ * Mellanox BlueField EMI (External Memory Interface) register definitions.
+ */
+
+#define MLXBF_ECC_CNT 0x340
+#define MLXBF_ECC_CNT__SERR_CNT_SHIFT 0
+#define MLXBF_ECC_CNT__SERR_CNT_MASK 0x
+#define MLXBF_ECC_CNT__DERR_CNT_SHIFT 16
+#define MLXBF_ECC_CNT__DERR_CNT_MASK 0x
+
+#define MLXBF_ECC_ERR 0x348
+#define MLXBF_ECC_ERR__SECC_SHIFT 0
+#define MLXBF_ECC_ERR__DECC_SHIFT 16
+
+#define MLXBF_ECC_LATCH_SEL 0x354
+#define MLXBF_ECC_LATCH_SEL__START_SHIFT 24
+
+#define MLXBF_ERR_ADDR_0 0x358
+
+#define MLXBF_ERR_ADDR_1 0x37c
+
+#define MLXBF_SYNDROM 0x35c
+#define MLXBF_SYNDROM__DERR_SHIFT 0
+#define MLXBF_SYNDROM__DERR_MASK 0x1
+#define MLXBF_SYNDROM__SERR_SHIFT 1
+#define MLXBF_SYNDROM__SERR_MASK 0x1
+#define MLXBF_SYNDROM__SYN_SHIFT 16
+#define MLXBF_SYNDROM__SYN_MASK 0x3ff
+
+#define MLXBF_ADD_INFO 0x364
+#define MLXBF_ADD_INFO__ERR_PRANK_SHIFT 8
+#define MLXBF_ADD_INFO__ERR_PRANK_MASK 0x3
+
+#define MLXBF_EDAC_MAX_DIMM_PER_MC 2
+#define MLXBF_EDAC_ERROR_GRAIN 8
+
+/*
+ * Request MLNX_SIP_GET_DIMM_INFO
+ *
+ * Retrieve information about DIMM on a certain slot.
+ *
+ * Call register usage:
+ * a0: MLNX_SIP_GET_DIMM_INFO
+ * a1: (Memory controller index) << 16 | (Dimm index in memory controller)
+ * a2-7: not used.
+ *
+ * Return status:
+ * a0: MLXBF_DIMM_INFO defined below describing the DIMM.
+ * a1-3: not used.
+ */
+#define MLNX_SIP_GET_DIMM_INFO 0x8208
+
+/* Format for the SMC response about the memory information */
+#define MLXBF_DIMM_INFO__SIZE_GB_SHIFT 0
+#define MLXBF_DIMM_INFO__SIZE_GB_MASK 0x
+#define MLXBF_DIMM_INFO__IS_RDIMM_SHIFT 16
+#define MLXBF_DIMM_INFO__IS_RDIMM_MASK 0x1
+#define MLXBF_DIMM_INFO__IS_LRDIMM_SHIFT 17
+#define MLXBF_DIMM_INFO__IS_LRDIMM_MASK 0x1
+#define MLXBF_DIMM_INFO__IS_NVDIMM_SHIFT 18
+#define MLXBF_DIMM_INFO__IS_NVDIMM_MASK 0x1
+#define MLXBF_DIMM_INFO__RANKS_SHIFT 21
+#define MLXBF_DIMM_INFO__RANKS_MASK 0x7
+#define MLXBF_DIMM_INFO__PACKAGE_X_SHIFT 24
+#define MLXBF_DIMM_INFO__PACKAGE_X_MASK 0xff
+
+struct bluefield_edac_priv {
+   int dimm_ranks[MLXBF_EDAC_MAX_DIMM_PER_MC];
+   void __iomem *emi_base;
+   int dimm_per_mc;
+};
+
+static unsigned long smc_call1(unsigned long smc_op, unsigned long smc_arg)
+{
+   struct arm_smccc_res res;
+
+   arm_smccc_smc(smc_op, smc_arg, 0, 0, 0, 0, 0, 0, );
+
+   return res.a0;
+}
+
+/*
+ * Gather the ECC information from the External Memory Interface registers
+ * and report it to the edac ha

[PATCH v6 0/1] EDAC, mellanox: Add ECC support for BlueField DDR4

2019-06-24 Thread Shravan Kumar Ramani
Chnages since v5:
Use shifts/masks for SMC response fields.
Add limit check for dimm_per_mc read from firmware.
Make use of offset_in_page() call.

Shravan Kumar Ramani (1):
  EDAC, mellanox: Add ECC support for BlueField DDR4

 MAINTAINERS   |   5 +
 drivers/edac/Kconfig  |   7 +
 drivers/edac/Makefile |   1 +
 drivers/edac/bluefield_edac.c | 381 ++
 4 files changed, 394 insertions(+)
 create mode 100644 drivers/edac/bluefield_edac.c

-- 
2.1.2



[PATCH v5 1/1] EDAC, mellanox: Add ECC support for BlueField DDR4

2019-06-17 Thread Shravan Kumar Ramani
Add ECC support for Mellanox BlueField SoC DDR controller.
This requires SMC to the running Arm Trusted Firmware to report
what is the current memory configuration.

Signed-off-by: Shravan Kumar Ramani 
---
 MAINTAINERS   |   5 +
 drivers/edac/Kconfig  |   7 +
 drivers/edac/Makefile |   1 +
 drivers/edac/bluefield_edac.c | 366 ++
 4 files changed, 379 insertions(+)
 create mode 100644 drivers/edac/bluefield_edac.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 57f496c..9d04cc4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5669,6 +5669,11 @@ S:   Supported
 F: drivers/edac/aspeed_edac.c
 F: Documentation/devicetree/bindings/edac/aspeed-sdram-edac.txt
 
+EDAC-BLUEFIELD
+M: Shravan Kumar Ramani 
+S: Supported
+F: drivers/edac/bluefield_edac.c
+
 EDAC-CALXEDA
 M: Robert Richter 
 L: linux-e...@vger.kernel.org
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index 5e2e034..43df551 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -504,4 +504,11 @@ config EDAC_ASPEED
  First, ECC must be configured in the bootloader. Then, this driver
  will expose error counters via the EDAC kernel framework.
 
+config EDAC_BLUEFIELD
+   tristate "Mellanox BlueField Memory ECC"
+   depends on ARM64 && ((MELLANOX_PLATFORM && ACPI) || COMPILE_TEST)
+   help
+ Support for error detection and correction on the
+ Mellanox BlueField SoCs.
+
 endif # EDAC
diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile
index 89ad4a84..0294a67 100644
--- a/drivers/edac/Makefile
+++ b/drivers/edac/Makefile
@@ -84,3 +84,4 @@ obj-$(CONFIG_EDAC_XGENE)  += xgene_edac.o
 obj-$(CONFIG_EDAC_TI)  += ti_edac.o
 obj-$(CONFIG_EDAC_QCOM)+= qcom_edac.o
 obj-$(CONFIG_EDAC_ASPEED)  += aspeed_edac.o
+obj-$(CONFIG_EDAC_BLUEFIELD)   += bluefield_edac.o
diff --git a/drivers/edac/bluefield_edac.c b/drivers/edac/bluefield_edac.c
new file mode 100644
index 000..d4a29ba
--- /dev/null
+++ b/drivers/edac/bluefield_edac.c
@@ -0,0 +1,366 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Bluefield-specific EDAC driver.
+ *
+ * Copyright (c) 2019 Mellanox Technologies.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "edac_module.h"
+
+#define DRIVER_NAME"bluefield-edac"
+
+/*
+ * Mellanox BlueField EMI (External Memory Interface) register definitions.
+ */
+
+#define MLXBF_ECC_CNT 0x340
+#define MLXBF_ECC_CNT__SERR_CNT_SHIFT 0
+#define MLXBF_ECC_CNT__SERR_CNT_MASK 0x
+#define MLXBF_ECC_CNT__DERR_CNT_SHIFT 16
+#define MLXBF_ECC_CNT__DERR_CNT_MASK 0x
+
+#define MLXBF_ECC_ERR 0x348
+#define MLXBF_ECC_ERR__SECC_SHIFT 0
+#define MLXBF_ECC_ERR__DECC_SHIFT 16
+
+#define MLXBF_ECC_LATCH_SEL 0x354
+#define MLXBF_ECC_LATCH_SEL__START_SHIFT 24
+
+#define MLXBF_ERR_ADDR_0 0x358
+
+#define MLXBF_ERR_ADDR_1 0x37c
+
+#define MLXBF_SYNDROM 0x35c
+#define MLXBF_SYNDROM__DERR_SHIFT 0
+#define MLXBF_SYNDROM__DERR_MASK 0x1
+#define MLXBF_SYNDROM__SERR_SHIFT 1
+#define MLXBF_SYNDROM__SERR_MASK 0x1
+#define MLXBF_SYNDROM__SYN_SHIFT 16
+#define MLXBF_SYNDROM__SYN_MASK 0x3ff
+
+#define MLXBF_ADD_INFO 0x364
+#define MLXBF_ADD_INFO__ERR_PRANK_SHIFT 8
+#define MLXBF_ADD_INFO__ERR_PRANK_MASK 0x3
+
+#define MLXBF_EDAC_MAX_DIMM_PER_MC 2
+#define MLXBF_EDAC_ERROR_GRAIN 8
+
+/*
+ * Request MLNX_SIP_GET_DIMM_INFO
+ *
+ * Retrieve information about DIMM on a certain slot.
+ *
+ * Call register usage:
+ * a0: MLNX_SIP_GET_DIMM_INFO
+ * a1: (Memory controller index) << 16 | (Dimm index in memory controller)
+ * a2-7: not used.
+ *
+ * Return status:
+ * a0: dimm_info_smc union defined below describing the DIMM.
+ * a1-3: not used.
+ */
+#define MLNX_SIP_GET_DIMM_INFO 0x8208
+
+/* Format for the SMC response about the memory information */
+union dimm_info_smc {
+   struct {
+   unsigned long size_GB : 16;
+   unsigned long is_rdimm : 1;
+   unsigned long is_lrdimm : 1;
+   unsigned long is_nvdimm : 1;
+   unsigned long __reserved0 : 2;
+   unsigned long ranks : 3;
+   unsigned long package_X : 8;/* Bits per memory package */
+   unsigned long __reserved1 : 32;
+   };
+   unsigned long val;
+};
+
+struct bluefield_edac_priv {
+   int dimm_ranks[MLXBF_EDAC_MAX_DIMM_PER_MC];
+   void __iomem *emi_base;
+   int dimm_per_mc;
+};
+
+static unsigned long smc_call1(unsigned long smc_op, unsigned long smc_arg)
+{
+   struct arm_smccc_res res;
+
+   arm_smccc_smc(smc_op, smc_arg, 0, 0, 0, 0, 0, 0, );
+
+   return res.a0;
+}
+
+/*
+ * Gather the ECC information from the External Memory Interface registers
+ * and report it to the edac handler.
+ */
+static void bluefield_gather_report_ecc(struct mem_ctl_in

[PATCH v5 0/1] EDAC, mellanox: Add ECC support for BlueField DDR4

2019-06-17 Thread Shravan Kumar Ramani
Changes since v4:
Shorten long macro names.

Changes since v3:
Replace bitfields with shifts and masks.
Make use of SZ_ and PAGE_ macros.
Read DIMM count from the ACPI table instead of hard-coding the info in
the driver.

Shravan Kumar Ramani (1):
  EDAC, mellanox: Add ECC support for BlueField DDR4

 MAINTAINERS   |   5 +
 drivers/edac/Kconfig  |   7 +
 drivers/edac/Makefile |   1 +
 drivers/edac/bluefield_edac.c | 366 ++
 4 files changed, 379 insertions(+)
 create mode 100644 drivers/edac/bluefield_edac.c

-- 
2.1.2



[PATCH v4 1/1] EDAC, mellanox: Add ECC support for BlueField DDR4

2019-06-14 Thread Shravan Kumar Ramani
Add ECC support for Mellanox BlueField SoC DDR controller.
This requires SMC to the running Arm Trusted Firmware to report
what is the current memory configuration.

Signed-off-by: Shravan Kumar Ramani 
---
 MAINTAINERS   |   5 +
 drivers/edac/Kconfig  |   7 +
 drivers/edac/Makefile |   1 +
 drivers/edac/bluefield_edac.c | 404 ++
 4 files changed, 417 insertions(+)
 create mode 100644 drivers/edac/bluefield_edac.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 57f496c..9d04cc4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5669,6 +5669,11 @@ S:   Supported
 F: drivers/edac/aspeed_edac.c
 F: Documentation/devicetree/bindings/edac/aspeed-sdram-edac.txt
 
+EDAC-BLUEFIELD
+M: Shravan Kumar Ramani 
+S: Supported
+F: drivers/edac/bluefield_edac.c
+
 EDAC-CALXEDA
 M: Robert Richter 
 L: linux-e...@vger.kernel.org
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index 5e2e034..43df551 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -504,4 +504,11 @@ config EDAC_ASPEED
  First, ECC must be configured in the bootloader. Then, this driver
  will expose error counters via the EDAC kernel framework.
 
+config EDAC_BLUEFIELD
+   tristate "Mellanox BlueField Memory ECC"
+   depends on ARM64 && ((MELLANOX_PLATFORM && ACPI) || COMPILE_TEST)
+   help
+ Support for error detection and correction on the
+ Mellanox BlueField SoCs.
+
 endif # EDAC
diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile
index 89ad4a84..0294a67 100644
--- a/drivers/edac/Makefile
+++ b/drivers/edac/Makefile
@@ -84,3 +84,4 @@ obj-$(CONFIG_EDAC_XGENE)  += xgene_edac.o
 obj-$(CONFIG_EDAC_TI)  += ti_edac.o
 obj-$(CONFIG_EDAC_QCOM)+= qcom_edac.o
 obj-$(CONFIG_EDAC_ASPEED)  += aspeed_edac.o
+obj-$(CONFIG_EDAC_BLUEFIELD)   += bluefield_edac.o
diff --git a/drivers/edac/bluefield_edac.c b/drivers/edac/bluefield_edac.c
new file mode 100644
index 000..9c69033
--- /dev/null
+++ b/drivers/edac/bluefield_edac.c
@@ -0,0 +1,404 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Bluefield-specific EDAC driver.
+ *
+ * Copyright (c) 2019 Mellanox Technologies.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "edac_module.h"
+
+#define DRIVER_NAME"bluefield-edac"
+
+/*
+ * Mellanox BlueField EMI (External Memory Interface) register definitions.
+ */
+
+#define MLXBF_EMI_DRAM_ECC_COUNT 0x340
+#define MLXBF_EMI_DRAM_ECC_COUNT__LENGTH 0x0001
+
+#define MLXBF_EMI_DRAM_ECC_COUNT__SINGLE_ERROR_COUNT_SHIFT 0
+#define MLXBF_EMI_DRAM_ECC_COUNT__SINGLE_ERROR_COUNT_RMASK 0x
+
+#define MLXBF_EMI_DRAM_ECC_COUNT__DOUBLE_ERROR_COUNT_SHIFT 16
+#define MLXBF_EMI_DRAM_ECC_COUNT__DOUBLE_ERROR_COUNT_RMASK 0x
+
+#define MLXBF_EMI_DRAM_ECC_ERROR 0x348
+
+#define MLXBF_EMI_DRAM_ECC_ERROR__DRAM_ECC_SINGLE_SHIFT 0
+#define MLXBF_EMI_DRAM_ECC_ERROR__DRAM_ECC_SINGLE_RMASK 0x1
+
+#define MLXBF_EMI_DRAM_ECC_ERROR__DRAM_ECC_DOUBLE_SHIFT 16
+#define MLXBF_EMI_DRAM_ECC_ERROR__DRAM_ECC_DOUBLE_RMASK 0x1
+
+#define MLXBF_EMI_DRAM_ECC_LATCH_SELECT 0x354
+
+#define MLXBF_EMI_DRAM_ECC_LATCH_SELECT__DRAM_ECC_FIRST_SHIFT 0
+#define MLXBF_EMI_DRAM_ECC_LATCH_SELECT__DRAM_ECC_FIRST_RMASK 0x1
+
+#define MLXBF_EMI_DRAM_ECC_LATCH_SELECT__EDGE_SEL_SHIFT 16
+#define MLXBF_EMI_DRAM_ECC_LATCH_SELECT__EDGE_SEL_RMASK 0xf
+
+#define MLXBF_EMI_DRAM_ECC_LATCH_SELECT__START_SHIFT 24
+#define MLXBF_EMI_DRAM_ECC_LATCH_SELECT__START_RMASK 0x1
+
+#define MLXBF_EMI_DRAM_ERR_ADDR_0 0x358
+
+#define MLXBF_EMI_DRAM_ERR_ADDR_1 0x37c
+
+#define MLXBF_EMI_DRAM_SYNDROM 0x35c
+#define MLXBF_EMI_DRAM_SYNDROM__LENGTH 0x0001
+
+#define MLXBF_EMI_DRAM_SYNDROM__DERR_SHIFT 0
+#define MLXBF_EMI_DRAM_SYNDROM__DERR_RMASK 0x1
+
+#define MLXBF_EMI_DRAM_SYNDROM__SERR_SHIFT 1
+#define MLXBF_EMI_DRAM_SYNDROM__SERR_RMASK 0x1
+
+#define MLXBF_EMI_DRAM_SYNDROM__SYNDROM_SHIFT 16
+#define MLXBF_EMI_DRAM_SYNDROM__SYNDROM_RMASK 0x3ff
+
+#define MLXBF_EMI_DRAM_ADDITIONAL_INFO_0 0x364
+
+#define MLXBF_EMI_DRAM_ADDITIONAL_INFO_0__ERR_BANK_SHIFT 0
+#define MLXBF_EMI_DRAM_ADDITIONAL_INFO_0__ERR_BANK_RMASK 0xf
+
+#define MLXBF_EMI_DRAM_ADDITIONAL_INFO_0__ERR_LRANK_SHIFT 4
+#define MLXBF_EMI_DRAM_ADDITIONAL_INFO_0__ERR_LRANK_RMASK 0x3
+
+#define MLXBF_EMI_DRAM_ADDITIONAL_INFO_0__ERR_PRANK_SHIFT 8
+#define MLXBF_EMI_DRAM_ADDITIONAL_INFO_0__ERR_PRANK_RMASK 0x3
+
+#define MLXBF_EMI_DRAM_ADDITIONAL_INFO_0__ERR_EDGE_SHIFT 16
+#define MLXBF_EMI_DRAM_ADDITIONAL_INFO_0__ERR_EDGE_RMASK 0xff
+
+#define MLXBF_EDAC_MAX_DIMM_PER_MC 2
+#define MLXBF_EDAC_ERROR_GRAIN 8
+
+/*
+ * Request MLNX_SIP_GET_DIMM_INFO
+ *
+ * Retrieve information about DIMM on a certain slot.
+ *
+ * Call register usage:
+ * a0: MLNX_SIP_GET_DIMM_INFO
+ * a1: (Memory controller index) << 16 | (Dimm index in memory controller)
+ * a2-7: no

[PATCH v4 0/1] EDAC, mellanox: Add ECC support for BlueField DDR4

2019-06-14 Thread Shravan Kumar Ramani
Changes since v3:
Replace bitfields with shifts and masks.
Make use of SZ_ and PAGE_ macros.
Read DIMM count from the ACPI table instead of hard-coding the info in
the driver.

Shravan Kumar Ramani (1):
  EDAC, mellanox: Add ECC support for BlueField DDR4

 MAINTAINERS   |   5 +
 drivers/edac/Kconfig  |   7 +
 drivers/edac/Makefile |   1 +
 drivers/edac/bluefield_edac.c | 404 ++
 4 files changed, 417 insertions(+)
 create mode 100644 drivers/edac/bluefield_edac.c

-- 
2.1.2



[PATCH v1] gpio: gpio-mlxbf: Add dependency on 64BIT to Kconfig entry

2019-03-27 Thread Shravan Kumar Ramani
Fixes a compile test failure

Signed-off-by: Shravan Kumar Ramani 
---
 drivers/gpio/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 0d9ddff..530ee34 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1318,7 +1318,7 @@ config GPIO_MERRIFIELD
 
 config GPIO_MLXBF
tristate "Mellanox BlueField SoC GPIO"
-   depends on (MELLANOX_PLATFORM && ARM64 && ACPI) || COMPILE_TEST
+   depends on (MELLANOX_PLATFORM && ARM64 && ACPI) || (64BIT && 
COMPILE_TEST)
select GPIO_GENERIC
help
  Say Y here if you want GPIO support on Mellanox BlueField SoC.
-- 
2.1.2



[PATCH v6 1/1] gpio: add driver for Mellanox BlueField GPIO controller

2019-03-26 Thread Shravan Kumar Ramani
This patch adds support for the GPIO controller used by Mellanox
BlueField SOCs.

Reviewed-by: David Woods 
Signed-off-by: Shravan Kumar Ramani 
---
 drivers/gpio/Kconfig  |   7 +++
 drivers/gpio/Makefile |   1 +
 drivers/gpio/gpio-mlxbf.c | 153 ++
 3 files changed, 161 insertions(+)
 create mode 100644 drivers/gpio/gpio-mlxbf.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 3f50526..0d9ddff 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1316,6 +1316,13 @@ config GPIO_MERRIFIELD
help
  Say Y here to support Intel Merrifield GPIO.
 
+config GPIO_MLXBF
+   tristate "Mellanox BlueField SoC GPIO"
+   depends on (MELLANOX_PLATFORM && ARM64 && ACPI) || COMPILE_TEST
+   select GPIO_GENERIC
+   help
+ Say Y here if you want GPIO support on Mellanox BlueField SoC.
+
 config GPIO_ML_IOH
tristate "OKI SEMICONDUCTOR ML7213 IOH GPIO support"
depends on X86 || COMPILE_TEST
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 54d5527..db8d854 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -85,6 +85,7 @@ obj-$(CONFIG_GPIO_MENZ127)+= gpio-menz127.o
 obj-$(CONFIG_GPIO_MERRIFIELD)  += gpio-merrifield.o
 obj-$(CONFIG_GPIO_MC33880) += gpio-mc33880.o
 obj-$(CONFIG_GPIO_MC9S08DZ60)  += gpio-mc9s08dz60.o
+obj-$(CONFIG_GPIO_MLXBF)   += gpio-mlxbf.o
 obj-$(CONFIG_GPIO_ML_IOH)  += gpio-ml-ioh.o
 obj-$(CONFIG_GPIO_MM_LANTIQ)   += gpio-mm-lantiq.o
 obj-$(CONFIG_GPIO_MOCKUP)  += gpio-mockup.o
diff --git a/drivers/gpio/gpio-mlxbf.c b/drivers/gpio/gpio-mlxbf.c
new file mode 100644
index 000..d428f42
--- /dev/null
+++ b/drivers/gpio/gpio-mlxbf.c
@@ -0,0 +1,153 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Number of pins on BlueField */
+#define MLXBF_GPIO_NR 54
+
+/* Pad Electrical Controls. */
+#define MLXBF_GPIO_PAD_CONTROL_FIRST_WORD 0x0700
+#define MLXBF_GPIO_PAD_CONTROL_1_FIRST_WORD 0x0708
+#define MLXBF_GPIO_PAD_CONTROL_2_FIRST_WORD 0x0710
+#define MLXBF_GPIO_PAD_CONTROL_3_FIRST_WORD 0x0718
+
+#define MLXBF_GPIO_PIN_DIR_I 0x1040
+#define MLXBF_GPIO_PIN_DIR_O 0x1048
+#define MLXBF_GPIO_PIN_STATE 0x1000
+#define MLXBF_GPIO_SCRATCHPAD 0x20
+
+#ifdef CONFIG_PM
+struct mlxbf_gpio_context_save_regs {
+   u64 scratchpad;
+   u64 pad_control[MLXBF_GPIO_NR];
+   u64 pin_dir_i;
+   u64 pin_dir_o;
+};
+#endif
+
+/* Device state structure. */
+struct mlxbf_gpio_state {
+   struct gpio_chip gc;
+
+   /* Memory Address */
+   void __iomem *base;
+
+#ifdef CONFIG_PM
+   struct mlxbf_gpio_context_save_regs csave_regs;
+#endif
+};
+
+static int mlxbf_gpio_probe(struct platform_device *pdev)
+{
+   struct mlxbf_gpio_state *gs;
+   struct device *dev = >dev;
+   struct gpio_chip *gc;
+   int ret;
+
+   gs = devm_kzalloc(>dev, sizeof(*gs), GFP_KERNEL);
+   if (!gs)
+   return -ENOMEM;
+
+   gs->base = devm_platform_ioremap_resource(pdev, 0);
+   if (IS_ERR(gs->base))
+   return PTR_ERR(gs->base);
+
+   gc = >gc;
+   ret = bgpio_init(gc, dev, 8,
+gs->base + MLXBF_GPIO_PIN_STATE,
+NULL,
+NULL,
+gs->base + MLXBF_GPIO_PIN_DIR_O,
+gs->base + MLXBF_GPIO_PIN_DIR_I,
+0);
+   if (ret)
+   return -ENODEV;
+
+   gc->owner = THIS_MODULE;
+   gc->ngpio = MLXBF_GPIO_NR;
+
+   ret = devm_gpiochip_add_data(dev, >gc, gs);
+   if (ret) {
+   dev_err(>dev, "Failed adding memory mapped gpiochip\n");
+   return ret;
+   }
+
+   platform_set_drvdata(pdev, gs);
+   dev_info(>dev, "registered Mellanox BlueField GPIO");
+   return 0;
+}
+
+#ifdef CONFIG_PM
+static int mlxbf_gpio_suspend(struct platform_device *pdev, pm_message_t state)
+{
+   struct mlxbf_gpio_state *gs = platform_get_drvdata(pdev);
+
+   gs->csave_regs.scratchpad = readq(gs->base + MLXBF_GPIO_SCRATCHPAD);
+   gs->csave_regs.pad_control[0] =
+   readq(gs->base + MLXBF_GPIO_PAD_CONTROL_FIRST_WORD);
+   gs->csave_regs.pad_control[1] =
+   readq(gs->base + MLXBF_GPIO_PAD_CONTROL_1_FIRST_WORD);
+   gs->csave_regs.pad_control[2] =
+   readq(gs->base + MLXBF_GPIO_PAD_CONTROL_2_FIRST_WORD);
+   gs->csave_regs.pad_control[3] =
+   readq(gs->base + MLXBF_GPIO_PAD_CONTROL_3_FIRST_WORD);
+   gs->csave_regs.pin_dir_i = readq(gs->base + MLXBF_GPIO_PIN_DIR_I);
+   gs->csave_regs.pin_dir_o = readq(gs->base + MLXBF_GPIO_PIN_DIR_O);
+
+   return 0;
+}
+
+static 

[PATCH v6 0/1] gpio: add driver for Mellanox BlueField GPIO

2019-03-26 Thread Shravan Kumar Ramani
Changes since v5:
Use devm_platform_ioremap_resource().

Shravan Kumar Ramani (1):
  gpio: add driver for Mellanox BlueField GPIO controller

 drivers/gpio/Kconfig  |   7 +++
 drivers/gpio/Makefile |   1 +
 drivers/gpio/gpio-mlxbf.c | 153 ++
 3 files changed, 161 insertions(+)
 create mode 100644 drivers/gpio/gpio-mlxbf.c

-- 
2.1.2



[PATCH v5 0/1] gpio: add driver for Mellanox BlueField GPIO

2019-03-25 Thread Shravan Kumar Ramani
Changes since v4:
Use bgpio_init to make use of the generic MMIO library.
Remove routines made unnecessary by the above change.

Shravan Kumar Ramani (1):
  gpio: add driver for Mellanox BlueField GPIO controller

 drivers/gpio/Kconfig  |   7 +++
 drivers/gpio/Makefile |   1 +
 drivers/gpio/gpio-mlxbf.c | 154 ++
 3 files changed, 162 insertions(+)
 create mode 100644 drivers/gpio/gpio-mlxbf.c

-- 
2.1.2



[PATCH v5 1/1] gpio: add driver for Mellanox BlueField GPIO controller

2019-03-25 Thread Shravan Kumar Ramani
This patch adds support for the GPIO controller used by Mellanox
BlueField SOCs.

Reviewed-by: David Woods 
Signed-off-by: Shravan Kumar Ramani 
---
 drivers/gpio/Kconfig  |   7 +++
 drivers/gpio/Makefile |   1 +
 drivers/gpio/gpio-mlxbf.c | 154 ++
 3 files changed, 162 insertions(+)
 create mode 100644 drivers/gpio/gpio-mlxbf.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 3f50526..0d9ddff 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1316,6 +1316,13 @@ config GPIO_MERRIFIELD
help
  Say Y here to support Intel Merrifield GPIO.
 
+config GPIO_MLXBF
+   tristate "Mellanox BlueField SoC GPIO"
+   depends on (MELLANOX_PLATFORM && ARM64 && ACPI) || COMPILE_TEST
+   select GPIO_GENERIC
+   help
+ Say Y here if you want GPIO support on Mellanox BlueField SoC.
+
 config GPIO_ML_IOH
tristate "OKI SEMICONDUCTOR ML7213 IOH GPIO support"
depends on X86 || COMPILE_TEST
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 54d5527..db8d854 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -85,6 +85,7 @@ obj-$(CONFIG_GPIO_MENZ127)+= gpio-menz127.o
 obj-$(CONFIG_GPIO_MERRIFIELD)  += gpio-merrifield.o
 obj-$(CONFIG_GPIO_MC33880) += gpio-mc33880.o
 obj-$(CONFIG_GPIO_MC9S08DZ60)  += gpio-mc9s08dz60.o
+obj-$(CONFIG_GPIO_MLXBF)   += gpio-mlxbf.o
 obj-$(CONFIG_GPIO_ML_IOH)  += gpio-ml-ioh.o
 obj-$(CONFIG_GPIO_MM_LANTIQ)   += gpio-mm-lantiq.o
 obj-$(CONFIG_GPIO_MOCKUP)  += gpio-mockup.o
diff --git a/drivers/gpio/gpio-mlxbf.c b/drivers/gpio/gpio-mlxbf.c
new file mode 100644
index 000..42087c6
--- /dev/null
+++ b/drivers/gpio/gpio-mlxbf.c
@@ -0,0 +1,154 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Number of pins on BlueField */
+#define MLXBF_GPIO_NR 54
+
+/* Pad Electrical Controls. */
+#define MLXBF_GPIO_PAD_CONTROL_FIRST_WORD 0x0700
+#define MLXBF_GPIO_PAD_CONTROL_1_FIRST_WORD 0x0708
+#define MLXBF_GPIO_PAD_CONTROL_2_FIRST_WORD 0x0710
+#define MLXBF_GPIO_PAD_CONTROL_3_FIRST_WORD 0x0718
+
+#define MLXBF_GPIO_PIN_DIR_I 0x1040
+#define MLXBF_GPIO_PIN_DIR_O 0x1048
+#define MLXBF_GPIO_PIN_STATE 0x1000
+#define MLXBF_GPIO_SCRATCHPAD 0x20
+
+#ifdef CONFIG_PM
+struct mlxbf_gpio_context_save_regs {
+   u64 scratchpad;
+   u64 pad_control[MLXBF_GPIO_NR];
+   u64 pin_dir_i;
+   u64 pin_dir_o;
+};
+#endif
+
+/* Device state structure. */
+struct mlxbf_gpio_state {
+   struct gpio_chip gc;
+
+   /* Memory Address */
+   void __iomem *base;
+
+#ifdef CONFIG_PM
+   struct mlxbf_gpio_context_save_regs csave_regs;
+#endif
+};
+
+static int mlxbf_gpio_probe(struct platform_device *pdev)
+{
+   struct mlxbf_gpio_state *gs;
+   struct device *dev = >dev;
+   struct gpio_chip *gc;
+   struct resource *res;
+   int ret;
+
+   gs = devm_kzalloc(>dev, sizeof(*gs), GFP_KERNEL);
+   if (!gs)
+   return -ENOMEM;
+
+   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+   gs->base = devm_ioremap_resource(>dev, res);
+   if (IS_ERR(gs->base))
+   return PTR_ERR(gs->base);
+
+   gc = >gc;
+   ret = bgpio_init(gc, dev, 8,
+gs->base + MLXBF_GPIO_PIN_STATE,
+NULL,
+NULL,
+gs->base + MLXBF_GPIO_PIN_DIR_O,
+gs->base + MLXBF_GPIO_PIN_DIR_I,
+0);
+   if (ret)
+   return -ENODEV;
+   gc->owner = THIS_MODULE;
+   gc->ngpio = MLXBF_GPIO_NR;
+
+   ret = devm_gpiochip_add_data(dev, >gc, gs);
+   if (ret) {
+   dev_err(>dev, "Failed adding memory mapped gpiochip\n");
+   return ret;
+   }
+
+   platform_set_drvdata(pdev, gs);
+   dev_info(>dev, "registered Mellanox BlueField GPIO");
+   return 0;
+}
+
+#ifdef CONFIG_PM
+static int mlxbf_gpio_suspend(struct platform_device *pdev, pm_message_t state)
+{
+   struct mlxbf_gpio_state *gs = platform_get_drvdata(pdev);
+
+   gs->csave_regs.scratchpad = readq(gs->base + MLXBF_GPIO_SCRATCHPAD);
+   gs->csave_regs.pad_control[0] =
+   readq(gs->base + MLXBF_GPIO_PAD_CONTROL_FIRST_WORD);
+   gs->csave_regs.pad_control[1] =
+   readq(gs->base + MLXBF_GPIO_PAD_CONTROL_1_FIRST_WORD);
+   gs->csave_regs.pad_control[2] =
+   readq(gs->base + MLXBF_GPIO_PAD_CONTROL_2_FIRST_WORD);
+   gs->csave_regs.pad_control[3] =
+   readq(gs->base + MLXBF_GPIO_PAD_CONTROL_3_FIRST_WORD);
+   gs->csave_regs.pin_dir_i = readq(gs->base + MLXBF_GPIO_PIN_DIR_I);
+   gs->csave_regs.pin_dir_o = re

[PATCH v1 1/1] hwmon: (emc1403) Add support for EMC1444

2019-02-26 Thread Shravan Kumar Ramani
EMC1444 is compatible with EMC1404. Add it to device ID table.

Reviewed-by: David Thompson 
Signed-off-by: Shravan Kumar Ramani 
---
 drivers/hwmon/emc1403.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/hwmon/emc1403.c b/drivers/hwmon/emc1403.c
index bdab47a..88f6a40 100644
--- a/drivers/hwmon/emc1403.c
+++ b/drivers/hwmon/emc1403.c
@@ -453,6 +453,7 @@ static const struct i2c_device_id emc1403_idtable[] = {
{ "emc1422", emc1402 },
{ "emc1423", emc1403 },
{ "emc1424", emc1404 },
+   { "emc1444", emc1404 },
{ }
 };
 MODULE_DEVICE_TABLE(i2c, emc1403_idtable);
-- 
2.1.2



[PATCH v4 1/1] gpio: add driver for Mellanox BlueField GPIO controller

2019-02-21 Thread Shravan Kumar Ramani
This patch adds support for the GPIO controller used by Mellanox
BlueField SOCs.

Reviewed-by: David Woods 
Signed-off-by: Shravan Kumar Ramani 
---
 drivers/gpio/Kconfig  |   6 ++
 drivers/gpio/Makefile |   1 +
 drivers/gpio/gpio-mlxbf.c | 222 ++
 3 files changed, 229 insertions(+)
 create mode 100644 drivers/gpio/gpio-mlxbf.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index b5a2845..c950fe8 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1292,6 +1292,12 @@ config GPIO_MERRIFIELD
help
  Say Y here to support Intel Merrifield GPIO.
 
+config GPIO_MLXBF
+   tristate "Mellanox BlueField SoC GPIO"
+   depends on (MELLANOX_PLATFORM && ARM64 && ACPI) || COMPILE_TEST
+   help
+ Say Y here if you want GPIO support on Mellanox BlueField SoC.
+
 config GPIO_ML_IOH
tristate "OKI SEMICONDUCTOR ML7213 IOH GPIO support"
depends on X86 || COMPILE_TEST
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 37628f8..8d54279 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -83,6 +83,7 @@ obj-$(CONFIG_GPIO_MENZ127)+= gpio-menz127.o
 obj-$(CONFIG_GPIO_MERRIFIELD)  += gpio-merrifield.o
 obj-$(CONFIG_GPIO_MC33880) += gpio-mc33880.o
 obj-$(CONFIG_GPIO_MC9S08DZ60)  += gpio-mc9s08dz60.o
+obj-$(CONFIG_GPIO_MLXBF)   += gpio-mlxbf.o
 obj-$(CONFIG_GPIO_ML_IOH)  += gpio-ml-ioh.o
 obj-$(CONFIG_GPIO_MM_LANTIQ)   += gpio-mm-lantiq.o
 obj-$(CONFIG_GPIO_MOCKUP)  += gpio-mockup.o
diff --git a/drivers/gpio/gpio-mlxbf.c b/drivers/gpio/gpio-mlxbf.c
new file mode 100644
index 000..e2d23c2
--- /dev/null
+++ b/drivers/gpio/gpio-mlxbf.c
@@ -0,0 +1,222 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Number of pins on BlueField */
+#define MLXBF_GPIO_NR 54
+
+/* Pad Electrical Controls. */
+#define MLXBF_GPIO_PAD_CONTROL_FIRST_WORD 0x0700
+#define MLXBF_GPIO_PAD_CONTROL_1_FIRST_WORD 0x0708
+#define MLXBF_GPIO_PAD_CONTROL_2_FIRST_WORD 0x0710
+#define MLXBF_GPIO_PAD_CONTROL_3_FIRST_WORD 0x0718
+
+#define MLXBF_GPIO_PIN_DIR_I 0x1040
+#define MLXBF_GPIO_PIN_DIR_O 0x1048
+#define MLXBF_GPIO_PIN_STATE 0x1000
+#define MLXBF_GPIO_SCRATCHPAD 0x20
+
+#ifdef CONFIG_PM
+struct mlxbf_gpio_context_save_regs {
+   u64 scratchpad;
+   u64 pad_control[MLXBF_GPIO_NR];
+   u64 pin_dir_i;
+   u64 pin_dir_o;
+};
+#endif
+
+/* Device state structure. */
+struct mlxbf_gpio_state {
+   struct gpio_chip gc;
+
+   /* Must hold this lock to modify shared data. */
+   spinlock_t lock;
+
+   /* Memory Address */
+   void __iomem *base;
+
+#ifdef CONFIG_PM
+   struct mlxbf_gpio_context_save_regs csave_regs;
+#endif
+};
+
+static int mlxbf_gpio_set_input(struct gpio_chip *chip, unsigned int offset)
+{
+   struct mlxbf_gpio_state *gs = gpiochip_get_data(chip);
+   u64 in;
+   u64 out;
+
+   spin_lock(>lock);
+   out = readq(gs->base + MLXBF_GPIO_PIN_DIR_O);
+   in = readq(gs->base + MLXBF_GPIO_PIN_DIR_I);
+
+   writeq(out & ~BIT(offset), gs->base + MLXBF_GPIO_PIN_DIR_O);
+   writeq(in | BIT(offset), gs->base + MLXBF_GPIO_PIN_DIR_I);
+   spin_unlock(>lock);
+
+   return 0;
+}
+
+static int mlxbf_gpio_set_output(struct gpio_chip *chip, unsigned int offset,
+int value)
+{
+   struct mlxbf_gpio_state *gs = gpiochip_get_data(chip);
+   u64 in;
+   u64 out;
+
+   spin_lock(>lock);
+   out = readq(gs->base + MLXBF_GPIO_PIN_DIR_O);
+   in = readq(gs->base + MLXBF_GPIO_PIN_DIR_I);
+
+   writeq(out | BIT(offset), gs->base + MLXBF_GPIO_PIN_DIR_O);
+   writeq(in & ~BIT(offset), gs->base + MLXBF_GPIO_PIN_DIR_I);
+   spin_unlock(>lock);
+
+   return 0;
+}
+
+static int mlxbf_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+   u64 value;
+   struct mlxbf_gpio_state *gs = gpiochip_get_data(chip);
+
+   spin_lock(>lock);
+   value = readq(gs->base + MLXBF_GPIO_PIN_STATE);
+   spin_unlock(>lock);
+
+   return (value >> offset) & 1;
+}
+
+static void mlxbf_gpio_set(struct gpio_chip *chip, unsigned int offset,
+  int value)
+{
+   u64 data;
+   struct mlxbf_gpio_state *gs = gpiochip_get_data(chip);
+
+   spin_lock(>lock);
+   data = readq(gs->base + MLXBF_GPIO_PIN_STATE);
+
+   if (value)
+   data |= BIT(offset);
+   else
+   data &= ~BIT(offset);
+   writeq(data, gs->base + MLXBF_GPIO_PIN_STATE);
+   spin_unlock(>lock);
+}
+
+static int mlxbf_gpio_probe(struct platform_device *pdev)
+{
+   struct mlxbf_gpio_state *gs;
+   struct device *dev = >dev;
+   struct g

[PATCH v4 0/1] gpio: add driver for Mellanox BlueField GPIO controller

2019-02-21 Thread Shravan Kumar Ramani
Changes since v3
 - the naming scheme has been fixed to remove double underscores and use
standard variable names
 - the locking has been updated to protect the entire read/modify
operations.

Regarding the suggested use of the generic MMIO library, I noticed that
bgpio_init only allows for either dirin or dirout to be set, never both.
But since our controller has 2 separate registers, using bgpio_init
might not be possible here.

Shravan Kumar Ramani (1):
  gpio: add driver for Mellanox BlueField GPIO controller

 drivers/gpio/Kconfig  |   6 ++
 drivers/gpio/Makefile |   1 +
 drivers/gpio/gpio-mlxbf.c | 222 ++
 3 files changed, 229 insertions(+)
 create mode 100644 drivers/gpio/gpio-mlxbf.c

-- 
2.1.2



[PATCH v3 1/1] gpio: add driver for Mellanox BlueField GPIO controller

2019-02-20 Thread Shravan Kumar Ramani
This patch adds support for the GPIO controller used by Mellanox
BlueField SOCs.

Reviewed-by: David Woods 
Signed-off-by: Shravan Kumar Ramani 
---
 drivers/gpio/Kconfig  |   6 ++
 drivers/gpio/Makefile |   1 +
 drivers/gpio/gpio-mlxbf.c | 222 ++
 3 files changed, 229 insertions(+)
 create mode 100644 drivers/gpio/gpio-mlxbf.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index b5a2845..c950fe8 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1292,6 +1292,12 @@ config GPIO_MERRIFIELD
help
  Say Y here to support Intel Merrifield GPIO.
 
+config GPIO_MLXBF
+   tristate "Mellanox BlueField SoC GPIO"
+   depends on (MELLANOX_PLATFORM && ARM64 && ACPI) || COMPILE_TEST
+   help
+ Say Y here if you want GPIO support on Mellanox BlueField SoC.
+
 config GPIO_ML_IOH
tristate "OKI SEMICONDUCTOR ML7213 IOH GPIO support"
depends on X86 || COMPILE_TEST
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 37628f8..8d54279 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -83,6 +83,7 @@ obj-$(CONFIG_GPIO_MENZ127)+= gpio-menz127.o
 obj-$(CONFIG_GPIO_MERRIFIELD)  += gpio-merrifield.o
 obj-$(CONFIG_GPIO_MC33880) += gpio-mc33880.o
 obj-$(CONFIG_GPIO_MC9S08DZ60)  += gpio-mc9s08dz60.o
+obj-$(CONFIG_GPIO_MLXBF)   += gpio-mlxbf.o
 obj-$(CONFIG_GPIO_ML_IOH)  += gpio-ml-ioh.o
 obj-$(CONFIG_GPIO_MM_LANTIQ)   += gpio-mm-lantiq.o
 obj-$(CONFIG_GPIO_MOCKUP)  += gpio-mockup.o
diff --git a/drivers/gpio/gpio-mlxbf.c b/drivers/gpio/gpio-mlxbf.c
new file mode 100644
index 000..c0f21f4
--- /dev/null
+++ b/drivers/gpio/gpio-mlxbf.c
@@ -0,0 +1,222 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Number of pins on BlueField */
+#define MLXBF_GPIO_NR 54
+
+/* Pad Electrical Controls. */
+#define MLXBF_GPIO_PAD_CONTROL__FIRST_WORD 0x0700
+#define MLXBF_GPIO_PAD_CONTROL_1__FIRST_WORD 0x0708
+#define MLXBF_GPIO_PAD_CONTROL_2__FIRST_WORD 0x0710
+#define MLXBF_GPIO_PAD_CONTROL_3__FIRST_WORD 0x0718
+
+#define MLXBF_GPIO_PIN_DIR_I 0x1040
+#define MLXBF_GPIO_PIN_DIR_O 0x1048
+#define MLXBF_GPIO_PIN_STATE 0x1000
+#define MLXBF_GPIO_SCRATCHPAD 0x20
+
+#ifdef CONFIG_PM
+struct mlxbf_gpio_context_save_regs {
+   u64 scratchpad;
+   u64 pad_control[MLXBF_GPIO_NR];
+   u64 pin_dir_i;
+   u64 pin_dir_o;
+};
+#endif
+
+/* Device state structure. */
+struct mlxbf_gpio_state {
+   struct gpio_chip gc;
+
+   /* Must hold this lock to modify shared data. */
+   spinlock_t lock;
+
+   /* Memory Address */
+   void __iomem *dc_base;
+
+#ifdef CONFIG_PM
+   struct mlxbf_gpio_context_save_regs csave_regs;
+#endif
+};
+
+static int mlxbf_gpio_set_input(struct gpio_chip *chip, unsigned int offset)
+{
+   struct mlxbf_gpio_state *gs = gpiochip_get_data(chip);
+   u64 in;
+   u64 out;
+
+   out = readq(gs->dc_base + MLXBF_GPIO_PIN_DIR_O);
+   in = readq(gs->dc_base + MLXBF_GPIO_PIN_DIR_I);
+
+   spin_lock(>lock);
+   writeq(out & ~BIT(offset), gs->dc_base + MLXBF_GPIO_PIN_DIR_O);
+   writeq(in | BIT(offset), gs->dc_base + MLXBF_GPIO_PIN_DIR_I);
+   spin_unlock(>lock);
+
+   return 0;
+}
+
+static int mlxbf_gpio_set_output(struct gpio_chip *chip, unsigned int offset,
+int value)
+{
+   struct mlxbf_gpio_state *gs = gpiochip_get_data(chip);
+   u64 in;
+   u64 out;
+
+   out = readq(gs->dc_base + MLXBF_GPIO_PIN_DIR_O);
+   in = readq(gs->dc_base + MLXBF_GPIO_PIN_DIR_I);
+
+   spin_lock(>lock);
+   writeq(out | BIT(offset), gs->dc_base + MLXBF_GPIO_PIN_DIR_O);
+   writeq(in & ~BIT(offset), gs->dc_base + MLXBF_GPIO_PIN_DIR_I);
+   spin_unlock(>lock);
+
+   return 0;
+}
+
+static int mlxbf_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+   u64 value;
+   struct mlxbf_gpio_state *gs = gpiochip_get_data(chip);
+
+   spin_lock(>lock);
+   value = readq(gs->dc_base + MLXBF_GPIO_PIN_STATE);
+   spin_unlock(>lock);
+
+   return (value >> offset) & 1;
+}
+
+static void mlxbf_gpio_set(struct gpio_chip *chip, unsigned int offset,
+  int value)
+{
+   u64 data;
+   struct mlxbf_gpio_state *gs = gpiochip_get_data(chip);
+
+   spin_lock(>lock);
+   data = readq(gs->dc_base + MLXBF_GPIO_PIN_STATE);
+
+   if (value)
+   data |= BIT(offset);
+   else
+   data &= ~BIT(offset);
+   writeq(data, gs->dc_base + MLXBF_GPIO_PIN_STATE);
+   spin_unlock(>lock);
+}
+
+static int mlxbf_gpio_probe(struct platform_device *pdev)
+{
+   struct mlxbf_gpio_state *gs;
+   struct device *dev 

[PATCH v2 1/1] gpio: add driver for Mellanox BlueField GPIO controller

2019-02-19 Thread Shravan Kumar Ramani
This patch adds support for the GPIO controller used by Mellanox
BlueField SOCs.

Reviewed-by: David Woods 
Signed-off-by: Shravan Kumar Ramani 
---
 drivers/gpio/Kconfig  |   6 ++
 drivers/gpio/Makefile |   1 +
 drivers/gpio/gpio-mlxbf.c | 246 ++
 3 files changed, 253 insertions(+)
 create mode 100644 drivers/gpio/gpio-mlxbf.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index b5a2845..c950fe8 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1292,6 +1292,12 @@ config GPIO_MERRIFIELD
help
  Say Y here to support Intel Merrifield GPIO.
 
+config GPIO_MLXBF
+   tristate "Mellanox BlueField SoC GPIO"
+   depends on (MELLANOX_PLATFORM && ARM64 && ACPI) || COMPILE_TEST
+   help
+ Say Y here if you want GPIO support on Mellanox BlueField SoC.
+
 config GPIO_ML_IOH
tristate "OKI SEMICONDUCTOR ML7213 IOH GPIO support"
depends on X86 || COMPILE_TEST
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 37628f8..8d54279 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -83,6 +83,7 @@ obj-$(CONFIG_GPIO_MENZ127)+= gpio-menz127.o
 obj-$(CONFIG_GPIO_MERRIFIELD)  += gpio-merrifield.o
 obj-$(CONFIG_GPIO_MC33880) += gpio-mc33880.o
 obj-$(CONFIG_GPIO_MC9S08DZ60)  += gpio-mc9s08dz60.o
+obj-$(CONFIG_GPIO_MLXBF)   += gpio-mlxbf.o
 obj-$(CONFIG_GPIO_ML_IOH)  += gpio-ml-ioh.o
 obj-$(CONFIG_GPIO_MM_LANTIQ)   += gpio-mm-lantiq.o
 obj-$(CONFIG_GPIO_MOCKUP)  += gpio-mockup.o
diff --git a/drivers/gpio/gpio-mlxbf.c b/drivers/gpio/gpio-mlxbf.c
new file mode 100644
index 000..bf197aa
--- /dev/null
+++ b/drivers/gpio/gpio-mlxbf.c
@@ -0,0 +1,246 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Number of pins on BlueField */
+#define MLXBF_GPIO_NR 54
+
+/* Pad Electrical Controls. */
+#define GPIO_PAD_CONTROL__FIRST_WORD 0x0700
+#define GPIO_PAD_CONTROL_1__FIRST_WORD 0x0708
+#define GPIO_PAD_CONTROL_2__FIRST_WORD 0x0710
+#define GPIO_PAD_CONTROL_3__FIRST_WORD 0x0718
+
+#define GPIO_PIN_DIR_I 0x1040
+#define GPIO_PIN_DIR_O 0x1048
+#define GPIO_PIN_STATE 0x1000
+#define GPIO_SCRATCHPAD 0x20
+
+#ifdef CONFIG_PM
+struct bluefield_context_save_regs {
+   u64 gpio_scratchpad;
+   u64 gpio_pad_control[MLXBF_GPIO_NR];
+   u64 gpio_pin_dir_i;
+   u64 gpio_pin_dir_o;
+};
+#endif
+
+/* Device state structure. */
+struct gpio_state {
+   struct gpio_chip gc;
+
+   /* Must hold this lock to modify shared data. */
+   spinlock_t lock;
+
+   /* Memory Address */
+   void __iomem *dc_base;
+
+#ifdef CONFIG_PM
+   struct bluefield_context_save_regs csave_regs;
+#endif
+};
+
+static int gpio_bf_set_input(struct gpio_chip *chip, unsigned int offset)
+{
+   struct gpio_state *gs = gpiochip_get_data(chip);
+   u64 in;
+   u64 out;
+
+   out = readq(gs->dc_base + GPIO_PIN_DIR_O);
+   in = readq(gs->dc_base + GPIO_PIN_DIR_I);
+
+   writeq(out & ~BIT(offset), gs->dc_base + GPIO_PIN_DIR_O);
+   writeq(in | BIT(offset), gs->dc_base + GPIO_PIN_DIR_I);
+
+   return 0;
+}
+
+static int gpio_bf_set_output(struct gpio_chip *chip, unsigned int offset)
+{
+   struct gpio_state *gs = gpiochip_get_data(chip);
+   u64 in;
+   u64 out;
+
+   out = readq(gs->dc_base + GPIO_PIN_DIR_O);
+   in = readq(gs->dc_base + GPIO_PIN_DIR_I);
+
+   writeq(out | BIT(offset), gs->dc_base + GPIO_PIN_DIR_O);
+   writeq(in & ~BIT(offset), gs->dc_base + GPIO_PIN_DIR_I);
+
+   return 0;
+}
+
+static int gpio_bf_set_output_lock(struct gpio_chip *chip,
+  unsigned int offset, int value)
+{
+   struct gpio_state *gs = gpiochip_get_data(chip);
+
+   spin_lock(>lock);
+   gpio_bf_set_output(chip, offset);
+   spin_unlock(>lock);
+
+   return 0;
+}
+
+static int gpio_bf_set_input_lock(struct gpio_chip *chip, unsigned int offset)
+{
+   struct gpio_state *gs = gpiochip_get_data(chip);
+
+   spin_lock(>lock);
+   gpio_bf_set_input(chip, offset);
+   spin_unlock(>lock);
+
+   return 0;
+}
+
+static int gpio_bf_get(struct gpio_chip *chip, unsigned int offset)
+{
+   u64 value;
+   struct gpio_state *gs = gpiochip_get_data(chip);
+
+   value = readq(gs->dc_base + GPIO_PIN_STATE);
+
+   return (value >> offset) & 1;
+}
+
+static void gpio_bf_set(struct gpio_chip *chip, unsigned int offset, int value)
+{
+   u64 data;
+   struct gpio_state *gs = gpiochip_get_data(chip);
+
+   spin_lock(>lock);
+   data = readq(gs->dc_base + GPIO_PIN_STATE);
+
+   if (value)
+   data |= BIT(offset);
+   else
+   data &= ~BIT(of

RE: [PATCH v1 1/1] gpio: add driver for Mellanox BlueField GPIO controller

2019-02-19 Thread Shravan Ramani
Thank you for the feedback. Regarding the suggested use of regmap mmio, all of 
the registers being accessed here are 64-bit and the 
regmap_update_bits/regmap_read/regmap_write calls aren't very convenient to use 
in this case. All other comments have been addressed in v2.

Regards,
Shravan Kumar Ramani

-Original Message-
From: Bartosz Golaszewski  
Sent: Friday, February 15, 2019 3:48 AM
To: Shravan Ramani 
Cc: Linus Walleij ; linux-gpio 
; LKML 
Subject: Re: [PATCH v1 1/1] gpio: add driver for Mellanox BlueField GPIO 
controller

czw., 14 lut 2019 o 22:30 Shravan Kumar Ramani 
napisaƂ(a):
>
> This patch adds support for the GPIO controller used by Mellanox 
> BlueField SOCs.
>
> Reviewed-by: David Woods 
> Signed-off-by: Shravan Kumar Ramani 
> ---
>  drivers/gpio/Kconfig  |   7 ++
>  drivers/gpio/Makefile |   1 +
>  drivers/gpio/gpio-mlxbf.c | 287 
> ++
>  3 files changed, 295 insertions(+)
>  create mode 100644 drivers/gpio/gpio-mlxbf.c
>
> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 
> b5a2845..2bebe92 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -1292,6 +1292,13 @@ config GPIO_MERRIFIELD
> help
>   Say Y here to support Intel Merrifield GPIO.
>
> +config GPIO_MLXBF
> +   tristate "Mellanox BlueField SoC GPIO"
> +   depends on (MELLANOX_PLATFORM && ARM64 && ACPI) || COMPILE_TEST
> +   select GPIO_GENERIC

You're not really depending on it.

> +   help
> + Say Y here if you want GPIO support on Mellanox BlueField SoC.
> +
>  config GPIO_ML_IOH
> tristate "OKI SEMICONDUCTOR ML7213 IOH GPIO support"
> depends on X86 || COMPILE_TEST diff --git 
> a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 37628f8..8d54279 
> 100644
> --- a/drivers/gpio/Makefile
> +++ b/drivers/gpio/Makefile
> @@ -83,6 +83,7 @@ obj-$(CONFIG_GPIO_MENZ127)+= gpio-menz127.o
>  obj-$(CONFIG_GPIO_MERRIFIELD)  += gpio-merrifield.o
>  obj-$(CONFIG_GPIO_MC33880) += gpio-mc33880.o
>  obj-$(CONFIG_GPIO_MC9S08DZ60)  += gpio-mc9s08dz60.o
> +obj-$(CONFIG_GPIO_MLXBF)   += gpio-mlxbf.o
>  obj-$(CONFIG_GPIO_ML_IOH)  += gpio-ml-ioh.o
>  obj-$(CONFIG_GPIO_MM_LANTIQ)   += gpio-mm-lantiq.o
>  obj-$(CONFIG_GPIO_MOCKUP)  += gpio-mockup.o
> diff --git a/drivers/gpio/gpio-mlxbf.c b/drivers/gpio/gpio-mlxbf.c new 
> file mode 100644 index 000..e5c50db
> --- /dev/null
> +++ b/drivers/gpio/gpio-mlxbf.c
> @@ -0,0 +1,287 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +/* Number of pins on BlueField */
> +#define MLXBF_GPIO_NR 54
> +
> +/* Pad Electrical Controls. */
> +#define GPIO_PAD_CONTROL__FIRST_WORD 0x0700 #define 
> +GPIO_PAD_CONTROL_1__FIRST_WORD 0x0708 #define 
> +GPIO_PAD_CONTROL_2__FIRST_WORD 0x0710 #define 
> +GPIO_PAD_CONTROL_3__FIRST_WORD 0x0718
> +
> +#define GPIO_PIN_DIR_I 0x1040
> +#define GPIO_PIN_DIR_O 0x1048
> +#define GPIO_PIN_STATE 0x1000
> +#define GPIO_SCRATCHPAD 0x20
> +
> +#ifdef CONFIG_PM
> +struct bluefield_context_save_regs {
> +   u64 gpio_scratchpad;
> +   u64 gpio_pad_control[MLXBF_GPIO_NR];
> +   u64 gpio_pin_dir_i;
> +   u64 gpio_pin_dir_o;
> +};
> +#endif
> +
> +/* Device state structure. */
> +struct gpio_state {
> +   struct list_head node;

Why do you need that? You're not using it anywhere AFAICT.

> +   struct platform_device *pdev;

You're not using this either.

> +
> +   struct gpio_chip gc;
> +
> +   /* Must hold this lock to modify shared data. */
> +   spinlock_t lock;
> +
> +   /* Memory Address */
> +   void __iomem *dc_base;
> +
> +#ifdef CONFIG_PM
> +   struct bluefield_context_save_regs csave_regs; #endif };
> +
> +/* GPIO driver set input pins */
> +static int gpio_bf_set_input(struct gpio_chip *chip, unsigned int 
> +offset) {
> +   struct gpio_state *gs = gpiochip_get_data(chip);
> +   u64 in;
> +   u64 out;
> +
> +   if (offset > MLXBF_GPIO_NR - 1) {
> +   dev_err(chip->parent, "gpio input pins: Invalid offset %d\n",
> +   offset);
> +   return -EINVAL;
> +   }

You don't need that, the subsystem makes sure this doesn't happen.
Same elsewhere.

> +
> +   out = readq(gs->dc_base + GPIO_PIN_DIR_O);
> +   in = readq(gs->dc_base + GPIO_PIN_DIR_I);
> +
> +  

[PATCH v1 1/1] gpio: add driver for Mellanox BlueField GPIO controller

2019-02-14 Thread Shravan Kumar Ramani
This patch adds support for the GPIO controller used by Mellanox
BlueField SOCs.

Reviewed-by: David Woods 
Signed-off-by: Shravan Kumar Ramani 
---
 drivers/gpio/Kconfig  |   7 ++
 drivers/gpio/Makefile |   1 +
 drivers/gpio/gpio-mlxbf.c | 287 ++
 3 files changed, 295 insertions(+)
 create mode 100644 drivers/gpio/gpio-mlxbf.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index b5a2845..2bebe92 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1292,6 +1292,13 @@ config GPIO_MERRIFIELD
help
  Say Y here to support Intel Merrifield GPIO.
 
+config GPIO_MLXBF
+   tristate "Mellanox BlueField SoC GPIO"
+   depends on (MELLANOX_PLATFORM && ARM64 && ACPI) || COMPILE_TEST
+   select GPIO_GENERIC
+   help
+ Say Y here if you want GPIO support on Mellanox BlueField SoC.
+
 config GPIO_ML_IOH
tristate "OKI SEMICONDUCTOR ML7213 IOH GPIO support"
depends on X86 || COMPILE_TEST
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 37628f8..8d54279 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -83,6 +83,7 @@ obj-$(CONFIG_GPIO_MENZ127)+= gpio-menz127.o
 obj-$(CONFIG_GPIO_MERRIFIELD)  += gpio-merrifield.o
 obj-$(CONFIG_GPIO_MC33880) += gpio-mc33880.o
 obj-$(CONFIG_GPIO_MC9S08DZ60)  += gpio-mc9s08dz60.o
+obj-$(CONFIG_GPIO_MLXBF)   += gpio-mlxbf.o
 obj-$(CONFIG_GPIO_ML_IOH)  += gpio-ml-ioh.o
 obj-$(CONFIG_GPIO_MM_LANTIQ)   += gpio-mm-lantiq.o
 obj-$(CONFIG_GPIO_MOCKUP)  += gpio-mockup.o
diff --git a/drivers/gpio/gpio-mlxbf.c b/drivers/gpio/gpio-mlxbf.c
new file mode 100644
index 000..e5c50db
--- /dev/null
+++ b/drivers/gpio/gpio-mlxbf.c
@@ -0,0 +1,287 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Number of pins on BlueField */
+#define MLXBF_GPIO_NR 54
+
+/* Pad Electrical Controls. */
+#define GPIO_PAD_CONTROL__FIRST_WORD 0x0700
+#define GPIO_PAD_CONTROL_1__FIRST_WORD 0x0708
+#define GPIO_PAD_CONTROL_2__FIRST_WORD 0x0710
+#define GPIO_PAD_CONTROL_3__FIRST_WORD 0x0718
+
+#define GPIO_PIN_DIR_I 0x1040
+#define GPIO_PIN_DIR_O 0x1048
+#define GPIO_PIN_STATE 0x1000
+#define GPIO_SCRATCHPAD 0x20
+
+#ifdef CONFIG_PM
+struct bluefield_context_save_regs {
+   u64 gpio_scratchpad;
+   u64 gpio_pad_control[MLXBF_GPIO_NR];
+   u64 gpio_pin_dir_i;
+   u64 gpio_pin_dir_o;
+};
+#endif
+
+/* Device state structure. */
+struct gpio_state {
+   struct list_head node;
+   struct platform_device *pdev;
+
+   struct gpio_chip gc;
+
+   /* Must hold this lock to modify shared data. */
+   spinlock_t lock;
+
+   /* Memory Address */
+   void __iomem *dc_base;
+
+#ifdef CONFIG_PM
+   struct bluefield_context_save_regs csave_regs;
+#endif
+};
+
+/* GPIO driver set input pins */
+static int gpio_bf_set_input(struct gpio_chip *chip, unsigned int offset)
+{
+   struct gpio_state *gs = gpiochip_get_data(chip);
+   u64 in;
+   u64 out;
+
+   if (offset > MLXBF_GPIO_NR - 1) {
+   dev_err(chip->parent, "gpio input pins: Invalid offset %d\n",
+   offset);
+   return -EINVAL;
+   }
+
+   out = readq(gs->dc_base + GPIO_PIN_DIR_O);
+   in = readq(gs->dc_base + GPIO_PIN_DIR_I);
+
+   writeq(out & ~BIT(offset), gs->dc_base + GPIO_PIN_DIR_O);
+   writeq(in | BIT(offset), gs->dc_base + GPIO_PIN_DIR_I);
+
+   return 0;
+}
+
+/* GPIO driver set output pins */
+static int gpio_bf_set_output(struct gpio_chip *chip, unsigned int offset)
+{
+   struct gpio_state *gs = gpiochip_get_data(chip);
+   u64 in;
+   u64 out;
+
+   if (offset > MLXBF_GPIO_NR - 1) {
+   dev_err(chip->parent, "gpio output pins: Invalid offset %d\n",
+   offset);
+   return -EINVAL;
+   }
+
+   out = readq(gs->dc_base + GPIO_PIN_DIR_O);
+   in = readq(gs->dc_base + GPIO_PIN_DIR_I);
+
+   writeq(out | BIT(offset), gs->dc_base + GPIO_PIN_DIR_O);
+   writeq(in & ~BIT(offset), gs->dc_base + GPIO_PIN_DIR_I);
+
+   return 0;
+}
+
+/* GPIO driver output direction */
+static int gpio_bf_set_output_lock(struct gpio_chip *chip,
+  unsigned int offset, int value)
+{
+   struct gpio_state *gs = gpiochip_get_data(chip);
+
+   spin_lock(>lock);
+   gpio_bf_set_output(chip, offset);
+   spin_unlock(>lock);
+
+   return 0;
+}
+
+/* GPIO driver input direction */
+static int gpio_bf_set_input_lock(struct gpio_chip *chip, unsigned int offset)
+{
+   struct gpio_state *gs = gpiochip_get_data(chip);
+
+   spin_lock(>lock);
+   gpio_bf_set_input(chip, offset);
+  

ADC continous mode

2014-01-22 Thread shravan
Hi experts,
i am new to this area,
I am using amstrong 3.8.13 kernel in BBB
at first i loaded the device tree as below,

 echo cape-bone-iio > /sys/devices/bone_capemgr.*/slots

then i used analog pins however i am getting the fixed values that is values 
are not varying continously as i vary input analog voltage

if i go to this path
/sys/devices/ocp.2/44e0d000.tscadc/tiadc/iio:device0

and then ls -al gives me

total 0
drwxr-xr-x 3 root root0 Jan  1 03:24 .
drwxr-xr-x 4 root root0 Jan  1 03:24 ..
-r--r--r-- 1 root root 4096 Jan  1 03:27 dev
-rw-r--r-- 1 root root 4096 Jan  1 03:27 in_voltage0_raw
-rw-r--r-- 1 root root 4096 Jan  1 03:27 in_voltage1_raw
-rw-r--r-- 1 root root 4096 Jan  1 03:27 in_voltage2_raw
-rw-r--r-- 1 root root 4096 Jan  1 03:27 in_voltage3_raw
-rw-r--r-- 1 root root 4096 Jan  1 03:27 in_voltage4_raw
-rw-r--r-- 1 root root 4096 Jan  1 03:27 in_voltage5_raw
-rw-r--r-- 1 root root 4096 Jan  1 03:27 in_voltage6_raw
-rw-r--r-- 1 root root 4096 Jan  1 03:27 in_voltage7_raw
-r--r--r-- 1 root root 4096 Jan  1 03:25 name
drwxr-xr-x 2 root root0 Jan  1 03:27 power
lrwxrwxrwx 1 root root0 Jan  1 03:27 subsystem -> ../../../../../bus/iio
-rw-r--r-- 1 root root 4096 Jan  1 03:24 uevent

there is no mode directory and buffer directory in list . please help to 
configure ADC In continous mode. 

Thanks 
shravankumar

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


ADC continous mode

2014-01-22 Thread shravan
Hi experts,
i am new to this area,
I am using amstrong 3.8.13 kernel in BBB
at first i loaded the device tree as below,

 echo cape-bone-iio  /sys/devices/bone_capemgr.*/slots

then i used analog pins however i am getting the fixed values that is values 
are not varying continously as i vary input analog voltage

if i go to this path
/sys/devices/ocp.2/44e0d000.tscadc/tiadc/iio:device0

and then ls -al gives me

total 0
drwxr-xr-x 3 root root0 Jan  1 03:24 .
drwxr-xr-x 4 root root0 Jan  1 03:24 ..
-r--r--r-- 1 root root 4096 Jan  1 03:27 dev
-rw-r--r-- 1 root root 4096 Jan  1 03:27 in_voltage0_raw
-rw-r--r-- 1 root root 4096 Jan  1 03:27 in_voltage1_raw
-rw-r--r-- 1 root root 4096 Jan  1 03:27 in_voltage2_raw
-rw-r--r-- 1 root root 4096 Jan  1 03:27 in_voltage3_raw
-rw-r--r-- 1 root root 4096 Jan  1 03:27 in_voltage4_raw
-rw-r--r-- 1 root root 4096 Jan  1 03:27 in_voltage5_raw
-rw-r--r-- 1 root root 4096 Jan  1 03:27 in_voltage6_raw
-rw-r--r-- 1 root root 4096 Jan  1 03:27 in_voltage7_raw
-r--r--r-- 1 root root 4096 Jan  1 03:25 name
drwxr-xr-x 2 root root0 Jan  1 03:27 power
lrwxrwxrwx 1 root root0 Jan  1 03:27 subsystem - ../../../../../bus/iio
-rw-r--r-- 1 root root 4096 Jan  1 03:24 uevent

there is no mode directory and buffer directory in list . please help to 
configure ADC In continous mode. 

Thanks 
shravankumar

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/