All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/6] dt-bindings: Add Baikal-T1 AXI-bus EHB dts bindings file
       [not found] <20200306130721.10347-1-Sergey.Semin@baikalelectronics.ru>
@ 2020-03-06 13:07 ` Sergey.Semin
  2020-03-06 13:07 ` [PATCH 2/6] dt-bindings: Add Baikal-T1 APB-bus " Sergey.Semin
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Sergey.Semin @ 2020-03-06 13:07 UTC (permalink / raw)
  To: Rob Herring, Mark Rutland
  Cc: Serge Semin, Serge Semin, Alexey Malahov, Thomas Bogendoerfer,
	Paul Burton, Ralf Baechle, Arnd Bergmann, Olof Johansson, soc,
	devicetree, linux-kernel

From: Serge Semin <Sergey.Semin@baikalelectronics.ru>

This is a specific block embedded into the Baikal-T1 SoC, which is
dedicated to detect AXI-bus protocol errors. So the dts node just
needs to have the "be,bt1-axi-ehb" compatible string, MMIO registers
and interrupts properties declared.

Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
Signed-off-by: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>
Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: Paul Burton <paulburton@kernel.org>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Olof Johansson <olof@lixom.net>
Cc: soc@kernel.org
---
 .../soc/baikal-t1/be,bt1-axi-ehb.yaml         | 52 +++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/baikal-t1/be,bt1-axi-ehb.yaml

diff --git a/Documentation/devicetree/bindings/soc/baikal-t1/be,bt1-axi-ehb.yaml b/Documentation/devicetree/bindings/soc/baikal-t1/be,bt1-axi-ehb.yaml
new file mode 100644
index 000000000000..f0deeb8f261c
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/baikal-t1/be,bt1-axi-ehb.yaml
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (C) 2019 - 2020 BAIKAL ELECTRONICS, JSC
+#
+# Baikal-T1 AXI-bus Errors Handler Block Device Tree Bindings.
+#
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/baikal-t1/be,bt1-axi-ehb.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Baikal-T1 AXI-bus Errors Handler Block
+
+maintainers:
+  - Serge Semin <fancer.lancer@gmail.com>
+
+description: |
+  AXI3-bus is the main communication bus connecting all high-speed peripheral
+  IP-cores with RAM controller and with MIPS P5600 cores. Traffic arbitration
+  is done by means of Main Interconnect routing IO request from one block to
+  another. In case of any protocol error, device not responding an IRQ is
+  raised and a faulty situation is reported to the AXI EHB described by this
+  bindings.
+
+properties:
+  compatible:
+    const: be,bt1-axi-ehb
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - interrupts
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/mips-gic.h>
+
+    axi_ehb: ehb@1F04D110 {
+      compatible = "be,bt1-axi-ehb";
+      reg = <0x1F04D110 0x008>;
+
+      interrupts = <GIC_SHARED 127 IRQ_TYPE_LEVEL_HIGH>;
+    };
+...
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/6] dt-bindings: Add Baikal-T1 APB-bus EHB dts bindings file
       [not found] <20200306130721.10347-1-Sergey.Semin@baikalelectronics.ru>
  2020-03-06 13:07 ` [PATCH 1/6] dt-bindings: Add Baikal-T1 AXI-bus EHB dts bindings file Sergey.Semin
@ 2020-03-06 13:07 ` Sergey.Semin
  2020-03-09 18:07   ` Rob Herring
  2020-03-06 13:07 ` [PATCH 3/6] dt-bindings: Add Baikal-T1 L2-cache Control Block " Sergey.Semin
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 10+ messages in thread
From: Sergey.Semin @ 2020-03-06 13:07 UTC (permalink / raw)
  To: Rob Herring, Mark Rutland
  Cc: Serge Semin, Serge Semin, Alexey Malahov, Thomas Bogendoerfer,
	Paul Burton, Ralf Baechle, Arnd Bergmann, Olof Johansson, soc,
	devicetree, linux-kernel

From: Serge Semin <Sergey.Semin@baikalelectronics.ru>

This is a specific block embedded into the Baikal-T1 SoC, which is
dedicated to detect APB-bus protocol errors and tune the peripheral
access timeout. So the dts bindings implies that corresponding dts
node would be equipped with "be,bt1-apb-ehb" compatible string, MMIO
region of registers space and of space with no device mapped,
interrupts property and with an APB-reference clock handler.

Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
Signed-off-by: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>
Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: Paul Burton <paulburton@kernel.org>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Olof Johansson <olof@lixom.net>
Cc: soc@kernel.org
---
 .../soc/baikal-t1/be,bt1-apb-ehb.yaml         | 66 +++++++++++++++++++
 1 file changed, 66 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/baikal-t1/be,bt1-apb-ehb.yaml

diff --git a/Documentation/devicetree/bindings/soc/baikal-t1/be,bt1-apb-ehb.yaml b/Documentation/devicetree/bindings/soc/baikal-t1/be,bt1-apb-ehb.yaml
new file mode 100644
index 000000000000..e262aead2fb5
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/baikal-t1/be,bt1-apb-ehb.yaml
@@ -0,0 +1,66 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (C) 2019 - 2020 BAIKAL ELECTRONICS, JSC
+#
+# Baikal-T1 APB-bus Errors Handler Block Device Tree Bindings.
+#
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/baikal-t1/be,bt1-apb-ehb.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Baikal-T1 APB-bus Errors Handler Block
+
+maintainers:
+  - Serge Semin <fancer.lancer@gmail.com>
+
+description: |
+  Configuration registers of Baikal-T1 SoC peripheral interfaces are accessed
+  by means of the APB-bus. In case of any APB protocol collisions, slave device
+  not responding on timeout an IRQ is raised with an erroneous address reported
+  to the APB terminator (EHB) sub-block described by this bindings file.
+
+properties:
+  compatible:
+    const: be,bt1-apb-ehb
+
+  reg:
+    items:
+      - description: APB EHB MMIO registers.
+      - description: APB MMIO region with no any device mapped.
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    description: APB reference clock.
+    maxItems: 1
+
+  clock-names:
+    const: ref
+
+additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/mips-gic.h>
+    #include <dt-bindings/clock/bt1-ccu.h>
+
+    apb_ehb: ehb@1F059000 {
+      compatible = "be,bt1-apb-ehb";
+      reg = <0x1F059000 0x1000>,
+            <0x1D000000 0x2040000>;
+
+      interrupts = <GIC_SHARED 16 IRQ_TYPE_LEVEL_HIGH>;
+
+      clocks = <&ccu_sys CCU_SYS_APB_CLK>;
+      clock-names = "ref";
+    };
+...
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/6] dt-bindings: Add Baikal-T1 L2-cache Control Block dts bindings file
       [not found] <20200306130721.10347-1-Sergey.Semin@baikalelectronics.ru>
  2020-03-06 13:07 ` [PATCH 1/6] dt-bindings: Add Baikal-T1 AXI-bus EHB dts bindings file Sergey.Semin
  2020-03-06 13:07 ` [PATCH 2/6] dt-bindings: Add Baikal-T1 APB-bus " Sergey.Semin
@ 2020-03-06 13:07 ` Sergey.Semin
  2020-03-12 21:23   ` Rob Herring
  2020-03-06 13:07 ` [PATCH 4/6] soc: bt1: Add Baikal-T1 AXI-bus EHB driver Sergey.Semin
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 10+ messages in thread
From: Sergey.Semin @ 2020-03-06 13:07 UTC (permalink / raw)
  To: Rob Herring, Mark Rutland
  Cc: Serge Semin, Serge Semin, Alexey Malahov, Thomas Bogendoerfer,
	Paul Burton, Ralf Baechle, Arnd Bergmann, Olof Johansson, soc,
	devicetree, linux-kernel

From: Serge Semin <Sergey.Semin@baikalelectronics.ru>

There is a single register provided by the SoC system controller,
which can be used to tune the L2-cache up. It only provides a way
to change the L2-RAM access latencies. So aside from the MMIO region
with that setting and "be,bt1-l2-ctl" compatible string the device
node can be optionally equipped with the properties of Tag/Data/WS
latencies.

Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
Signed-off-by: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>
Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: Paul Burton <paulburton@kernel.org>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Olof Johansson <olof@lixom.net>
Cc: soc@kernel.org
---
 .../bindings/soc/baikal-t1/be,bt1-l2-ctl.yaml | 108 ++++++++++++++++++
 1 file changed, 108 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/baikal-t1/be,bt1-l2-ctl.yaml

diff --git a/Documentation/devicetree/bindings/soc/baikal-t1/be,bt1-l2-ctl.yaml b/Documentation/devicetree/bindings/soc/baikal-t1/be,bt1-l2-ctl.yaml
new file mode 100644
index 000000000000..8769b3fa517c
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/baikal-t1/be,bt1-l2-ctl.yaml
@@ -0,0 +1,108 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
+#
+# Baikal-T1 L2-cache Control Block Device Tree Bindings.
+#
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/baikal-t1/be,bt1-l2-ctl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Baikal-T1 L2-cache Control Block
+
+maintainers:
+  - Serge Semin <fancer.lancer@gmail.com>
+
+description: |
+  Baikal-T1 exposes a few settings to tune the MIPS P5600 CM2 L2-cache
+  performance up. In particular it's possible to change the Tag, Data and
+  Way-select RAM access latencies. This bindings file describes the system
+  controller block, which provides an interface to set the tuning up.
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: syscon
+    then:
+      $ref: ../../mfd/syscon.yaml#
+    else:
+      properties:
+        reg-io-width: false
+
+        little-endian: false
+
+properties:
+  compatible:
+    oneOf:
+      - description: P5600 CM2 L2-cache RAM external configuration block.
+        const: be,bt1-l2-ctl
+      - description: P5600 CM2 L2-cache RAM system controller block.
+        items:
+          - const: be,bt1-l2-ctl
+          - const: syscon
+
+  reg:
+    description: MMIO register with MIPS P5600 CM2 L2-cache RAM settings.
+    maxItems: 1
+
+  be,l2-ws-latency:
+    description: Cycles of latency for Way-select RAM accesses.
+    default: 0
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/uint32
+      - minimum: 0
+        maximum: 3
+
+  be,l2-tag-latency:
+    description: Cycles of latency for Tag RAM accesses.
+    default: 0
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/uint32
+      - minimum: 0
+        maximum: 3
+
+  be,l2-data-latency:
+    description: Cycles of latency for Data RAM accesses.
+    default: 1
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/uint32
+      - minimum: 0
+        maximum: 3
+
+  reg-io-width:
+    const: 4
+
+  little-endian: true
+
+additionalProperties: false
+
+required:
+  - compatible
+  - reg
+
+examples:
+  - |
+    l2_ctl1: l2@1F04D028 {
+      compatible = "be,bt1-l2-ctl";
+      reg = <0x1F04D028 0x004>;
+
+      be,l2-ws-latency = <0>;
+      be,l2-tag-latency = <0>;
+      be,l2-data-latency = <1>;
+    };
+  - |
+    l2_ctl2: l2@1F04D028 {
+      compatible = "be,bt1-l2-ctl", "syscon";
+      reg = <0x1F04D028 0x004>;
+
+      be,l2-ws-latency = <0>;
+      be,l2-tag-latency = <0>;
+      be,l2-data-latency = <1>;
+
+      little-endian;
+      reg-io-width = <4>;
+    };
+...
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/6] soc: bt1: Add Baikal-T1 AXI-bus EHB driver
       [not found] <20200306130721.10347-1-Sergey.Semin@baikalelectronics.ru>
                   ` (2 preceding siblings ...)
  2020-03-06 13:07 ` [PATCH 3/6] dt-bindings: Add Baikal-T1 L2-cache Control Block " Sergey.Semin
@ 2020-03-06 13:07 ` Sergey.Semin
  2020-03-30  3:14   ` Randy Dunlap
  2020-03-06 13:07 ` [PATCH 5/6] soc: bt1: Add Baikal-T1 APB-bus " Sergey.Semin
  2020-03-06 13:07 ` [PATCH 6/6] soc: bt1: Add Baikal-T1 L2-cache Control Block driver Sergey.Semin
  5 siblings, 1 reply; 10+ messages in thread
From: Sergey.Semin @ 2020-03-06 13:07 UTC (permalink / raw)
  Cc: Serge Semin, Serge Semin, Alexey Malahov, Thomas Bogendoerfer,
	Paul Burton, Ralf Baechle, Arnd Bergmann, Olof Johansson, soc,
	linux-kernel

From: Serge Semin <Sergey.Semin@baikalelectronics.ru>

AXI3-bus is the main communication bus connecting all high-speed peripheral
IP-cores with RAM controller and MIPS P5600 cores. Baikal-T1 SoC provides a
way to detect the bus protocol errors and report a short info about it by
means of the AXI-bus Errors Handler Block (AXI EHB). The block rises an
interrupt indicating an AXI protocol error at an attempt either to reach
a non-existent slave device or to perform an invalid operation with a
slave IP-block. This driver provides the interrupt handler, which prints
an error message with a faulty address and updates an errors counter,
and exposes a sysfs-node to inject the described types of errors.

Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
Signed-off-by: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>
Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: Paul Burton <paulburton@kernel.org>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Olof Johansson <olof@lixom.net>
Cc: soc@kernel.org
---
 drivers/soc/Kconfig             |   1 +
 drivers/soc/Makefile            |   1 +
 drivers/soc/baikal-t1/Kconfig   |  22 +++
 drivers/soc/baikal-t1/Makefile  |   2 +
 drivers/soc/baikal-t1/axi-ehb.c | 250 ++++++++++++++++++++++++++++++++
 drivers/soc/baikal-t1/common.h  |  37 +++++
 6 files changed, 313 insertions(+)
 create mode 100644 drivers/soc/baikal-t1/Kconfig
 create mode 100644 drivers/soc/baikal-t1/Makefile
 create mode 100644 drivers/soc/baikal-t1/axi-ehb.c
 create mode 100644 drivers/soc/baikal-t1/common.h

diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index 1778f8c62861..af2c2ca5d643 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -5,6 +5,7 @@ source "drivers/soc/actions/Kconfig"
 source "drivers/soc/amlogic/Kconfig"
 source "drivers/soc/aspeed/Kconfig"
 source "drivers/soc/atmel/Kconfig"
+source "drivers/soc/baikal-t1/Kconfig"
 source "drivers/soc/bcm/Kconfig"
 source "drivers/soc/fsl/Kconfig"
 source "drivers/soc/imx/Kconfig"
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 8b49d782a1ab..0cf4d91f3d09 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -6,6 +6,7 @@
 obj-$(CONFIG_ARCH_ACTIONS)	+= actions/
 obj-$(CONFIG_SOC_ASPEED)	+= aspeed/
 obj-$(CONFIG_ARCH_AT91)		+= atmel/
+obj-$(CONFIG_SOC_BAIKAL_T1)	+= baikal-t1/
 obj-y				+= bcm/
 obj-$(CONFIG_ARCH_DOVE)		+= dove/
 obj-$(CONFIG_MACH_DOVE)		+= dove/
diff --git a/drivers/soc/baikal-t1/Kconfig b/drivers/soc/baikal-t1/Kconfig
new file mode 100644
index 000000000000..aca155350612
--- /dev/null
+++ b/drivers/soc/baikal-t1/Kconfig
@@ -0,0 +1,22 @@
+# SPDX-License-Identifier: GPL-2.0
+menu "Baikal-T1 SoC drivers"
+
+config SOC_BAIKAL_T1
+	def_bool y
+	depends on MIPS_BAIKAL_T1 || COMPILE_TEST
+
+config BT1_AXI_EHB
+	bool "Baikal-T1 AXI-bus Errors Handler Block"
+	depends on SOC_BAIKAL_T1 && OF
+	help
+	  Baikal-T1 CCU registers space as being MFD provides an access to the
+	  AXI-bus Errors Handler Block (AXI EHB). It rises an interrupt
+	  indicating an AXI protocol error at an attempt either to reach a
+	  non-existent slave device or to perform an invalid operation with a
+	  slave IP-block. This driver provides the interrupt handler, which
+	  prints an error message with a faulty address and updates an errors
+	  counter.
+
+	  If unsure, say N.
+
+endmenu
diff --git a/drivers/soc/baikal-t1/Makefile b/drivers/soc/baikal-t1/Makefile
new file mode 100644
index 000000000000..c069791058b9
--- /dev/null
+++ b/drivers/soc/baikal-t1/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_BT1_AXI_EHB) += axi-ehb.o
diff --git a/drivers/soc/baikal-t1/axi-ehb.c b/drivers/soc/baikal-t1/axi-ehb.c
new file mode 100644
index 000000000000..36929958cb4f
--- /dev/null
+++ b/drivers/soc/baikal-t1/axi-ehb.c
@@ -0,0 +1,250 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2014 - 2020 BAIKAL ELECTRONICS, JSC
+ *
+ * Authors:
+ *   Serge Semin <Sergey.Semin@baikalelectronics.ru>
+ *
+ * Baikal-T1 AXI-bus Errors Handler Block driver.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/atomic.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/nmi.h>
+#include <linux/sysfs.h>
+
+
+#include "common.h"
+
+#define AXI_EHB_WERRL			0x00
+#define AXI_EHB_WERRH			0x04
+#define AXI_EHB_WERRH_TYPE		BIT(23)
+#define AXI_EHB_WERRH_ADDR_FLD		24
+#define AXI_EHB_WERRH_ADDR_MASK		GENMASK(31, AXI_EHB_WERRH_ADDR_FLD)
+
+/*
+ * struct axi_ehb - Baikal-T1 AXI EHB private data.
+ * @dev: Pointer to the device structure.
+ * @regs: Memory mapped block registers.
+ * @irq: Errors IRQ number.
+ * @count: Number of errors detected.
+ */
+struct axi_ehb {
+	struct device *dev;
+
+	void __iomem *regs;
+	int irq;
+
+	atomic_t count;
+};
+
+static irqreturn_t axi_ehb_isr(int irq, void *data)
+{
+	struct axi_ehb *ehb = data;
+	u64 addr, val;
+
+	addr = bt1_read(ehb->regs + AXI_EHB_WERRL);
+	val = bt1_read(ehb->regs + AXI_EHB_WERRH);
+
+	addr |= (u64)(BT1_GET_FLD(AXI_EHB_WERRH_ADDR, val)) << 32;
+
+	dev_crit_ratelimited(ehb->dev,
+		"AXI-bus fault %d: %s at %08llx\n",
+		atomic_inc_return(&ehb->count),
+		val & AXI_EHB_WERRH_TYPE ? "no slave" : "slave protocol error",
+		addr);
+
+	/*
+	 * Print backtrace on each CPU. This might be pointless if the fault
+	 * has happened on the same CPU as the IRQ handler is executed or
+	 * the other core proceeded further execution despite the error.
+	 * But if it's not, by looking at the trace we would get straight to
+	 * the cause of the problem.
+	 */
+	trigger_all_cpu_backtrace();
+
+	return IRQ_HANDLED;
+}
+
+static void axi_ehb_clear_data(void *data)
+{
+	struct axi_ehb *ehb = data;
+	struct platform_device *pdev = to_platform_device(ehb->dev);
+
+	platform_set_drvdata(pdev, NULL);
+}
+
+static struct axi_ehb *axi_ehb_create_data(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct axi_ehb *ehb;
+	int ret;
+
+	ehb = devm_kzalloc(dev, sizeof(*ehb), GFP_KERNEL);
+	if (!ehb)
+		return ERR_PTR(-ENOMEM);
+
+	ret = devm_add_action(dev, axi_ehb_clear_data, ehb);
+	if (ret) {
+		dev_err(dev, "Can't add AXI EHB data clear action\n");
+		return ERR_PTR(ret);
+	}
+
+	ehb->dev = dev;
+	atomic_set(&ehb->count, 0);
+	platform_set_drvdata(pdev, ehb);
+
+	return ehb;
+}
+
+static int axi_ehb_request_regs(struct axi_ehb *ehb)
+{
+	struct platform_device *pdev = to_platform_device(ehb->dev);
+
+	ehb->regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(ehb->regs)) {
+		dev_err(ehb->dev, "Couldn't map AXI EHB registers\n");
+		return PTR_ERR(ehb->regs);
+	}
+
+	return 0;
+}
+
+static int axi_ehb_request_irq(struct axi_ehb *ehb)
+{
+	struct platform_device *pdev = to_platform_device(ehb->dev);
+	int ret;
+
+	ehb->irq = platform_get_irq(pdev, 0);
+	if (ehb->irq < 0) {
+		dev_err(ehb->dev, "Couldn't find AXI EHB IRQ number\n");
+		return ehb->irq;
+	}
+
+	ret = devm_request_irq(ehb->dev, ehb->irq, axi_ehb_isr, IRQF_SHARED,
+			       "axi_ehb", ehb);
+	if (ret) {
+		dev_err(ehb->dev, "Couldn't request AXI EHB IRQ\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static ssize_t count_show(struct device *dev,
+			  struct device_attribute *attr, char *buf)
+{
+	struct axi_ehb *ehb = dev_get_drvdata(dev);
+
+	return scnprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&ehb->count));
+}
+static DEVICE_ATTR_RO(count);
+
+static int inject_error_show(struct device *dev, struct device_attribute *attr,
+			     char *buf)
+{
+	return scnprintf(buf, PAGE_SIZE, "Error injection: bus unaligned\n");
+}
+
+static int inject_error_store(struct device *dev,
+			      struct device_attribute *attr,
+			      const char *data, size_t count)
+{
+	struct axi_ehb *ehb = dev_get_drvdata(dev);
+
+	/*
+	 * Performing unaligned read from the memory will cause the CM bus
+	 * error while unaligned writing - the AXI bus write error handled
+	 * by this driver.
+	 */
+	if (!strncmp(data, "bus", 3))
+		readb(ehb->regs + AXI_EHB_WERRL);
+	else if (!strncmp(data, "unaligned", 9))
+		writeb(0, ehb->regs + AXI_EHB_WERRL);
+	else
+		return -EINVAL;
+
+	return count;
+}
+static DEVICE_ATTR_RW(inject_error);
+
+static struct attribute *axi_ehb_sysfs_attrs[] = {
+	&dev_attr_count.attr,
+	&dev_attr_inject_error.attr,
+	NULL
+};
+ATTRIBUTE_GROUPS(axi_ehb_sysfs);
+
+static void axi_ehb_remove_sysfs(void *data)
+{
+	struct axi_ehb *ehb = data;
+
+	device_remove_groups(ehb->dev, axi_ehb_sysfs_groups);
+}
+
+static int axi_ehb_init_sysfs(struct axi_ehb *ehb)
+{
+	int ret;
+
+	ret = device_add_groups(ehb->dev, axi_ehb_sysfs_groups);
+	if (ret) {
+		dev_err(ehb->dev, "Failed to add sysfs files group\n");
+		return ret;
+	}
+
+	ret = devm_add_action_or_reset(ehb->dev, axi_ehb_remove_sysfs, ehb);
+	if (ret)
+		dev_err(ehb->dev, "Can't add AXI EHB sysfs remove action\n");
+
+	return ret;
+}
+
+static int axi_ehb_probe(struct platform_device *pdev)
+{
+	struct axi_ehb *ehb;
+	int ret;
+
+	ehb = axi_ehb_create_data(pdev);
+	if (IS_ERR(ehb))
+		return PTR_ERR(ehb);
+
+	ret = axi_ehb_request_regs(ehb);
+	if (ret)
+		return ret;
+
+	ret = axi_ehb_request_irq(ehb);
+	if (ret)
+		return ret;
+
+	ret = axi_ehb_init_sysfs(ehb);
+	if (ret)
+		return ret;
+
+	dev_info(ehb->dev, "AXI-bus errors handler installed\n");
+
+	return 0;
+}
+
+static const struct of_device_id axi_ehb_of_match[] = {
+	{ .compatible = "be,bt1-axi-ehb" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, axi_ehb_of_match);
+
+static struct platform_driver axi_ehb_driver = {
+	.probe = axi_ehb_probe,
+	.driver = {
+		.name = "bt1-axi-ehb",
+		.of_match_table = of_match_ptr(axi_ehb_of_match)
+	}
+};
+module_platform_driver(axi_ehb_driver);
+
+MODULE_AUTHOR("Serge Semin <Sergey.Semin@baikalelectronics.ru>");
+MODULE_DESCRIPTION("Baikal-T1 AXI EHB driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/soc/baikal-t1/common.h b/drivers/soc/baikal-t1/common.h
new file mode 100644
index 000000000000..d1d7c4e11bd4
--- /dev/null
+++ b/drivers/soc/baikal-t1/common.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2019 - 2020 BAIKAL ELECTRONICS, JSC
+ *
+ * Baikal-T1 SoC common methods.
+ */
+#ifndef __SOC_BT1_COMMON_H__
+#define __SOC_BT1_COMMON_H__
+
+#include <linux/io.h>
+
+#define BT1_GET_FLD(_name, _data) \
+	(((u32)(_data) & _name ## _MASK) >> _name ## _FLD)
+
+#define BT1_SET_FLD(_name, _data, _val) \
+	(((u32)(_data) & ~_name ## _MASK) | \
+	(((u32)(_val) << _name ## _FLD) & _name ## _MASK))
+
+static inline u32 bt1_read(void __iomem *reg)
+{
+	return readl(reg);
+}
+
+static inline void bt1_write(void __iomem *reg, u32 data)
+{
+	writel(data, reg);
+}
+
+static inline void bt1_update(void __iomem *reg, u32 mask, u32 data)
+{
+	u32 old;
+
+	old = readl_relaxed(reg);
+	writel((old & ~mask) | (data & mask), reg);
+}
+
+#endif /* __SOC_BT1_COMMON_H__ */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 5/6] soc: bt1: Add Baikal-T1 APB-bus EHB driver
       [not found] <20200306130721.10347-1-Sergey.Semin@baikalelectronics.ru>
                   ` (3 preceding siblings ...)
  2020-03-06 13:07 ` [PATCH 4/6] soc: bt1: Add Baikal-T1 AXI-bus EHB driver Sergey.Semin
@ 2020-03-06 13:07 ` Sergey.Semin
  2020-03-06 13:07 ` [PATCH 6/6] soc: bt1: Add Baikal-T1 L2-cache Control Block driver Sergey.Semin
  5 siblings, 0 replies; 10+ messages in thread
From: Sergey.Semin @ 2020-03-06 13:07 UTC (permalink / raw)
  Cc: Serge Semin, Serge Semin, Alexey Malahov, Thomas Bogendoerfer,
	Paul Burton, Ralf Baechle, Arnd Bergmann, Olof Johansson, soc,
	linux-kernel

From: Serge Semin <Sergey.Semin@baikalelectronics.ru>

APB-bus is the system configuration bus utilized to access the peripheral
IP-cores configuration registers space. Baikal-T1 SoC provides a way to
detect the bus protocol errors and report a short info about it by means of
the APB-bus Errors Handler Block (APB EHB). In case if an attempted APB
transaction stays with no response for a pre-defined time an interrupt
occurs and the bus gets freed for a next operation. This driver provides
the interrupt handler to detect the erroneous address, prints an error
message about the faulty address, updates an errors counter. The counter
and the APB-bus operations timeout can be accessed via corresponding sysfs
nodes. A dedicated sysfs-node can be also used to artificially cause the
bus errors described above.

Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
Signed-off-by: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>
Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: Paul Burton <paulburton@kernel.org>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Olof Johansson <olof@lixom.net>
Cc: soc@kernel.org
---
 drivers/soc/baikal-t1/Kconfig   |  15 ++
 drivers/soc/baikal-t1/Makefile  |   1 +
 drivers/soc/baikal-t1/apb-ehb.c | 381 ++++++++++++++++++++++++++++++++
 3 files changed, 397 insertions(+)
 create mode 100644 drivers/soc/baikal-t1/apb-ehb.c

diff --git a/drivers/soc/baikal-t1/Kconfig b/drivers/soc/baikal-t1/Kconfig
index aca155350612..a021abea102f 100644
--- a/drivers/soc/baikal-t1/Kconfig
+++ b/drivers/soc/baikal-t1/Kconfig
@@ -19,4 +19,19 @@ config BT1_AXI_EHB
 
 	  If unsure, say N.
 
+config BT1_APB_EHB
+	bool "Baikal-T1 APB-bus Errors Handler Block"
+	depends on SOC_BAIKAL_T1 && OF
+	help
+	  Baikal-T1 APB-bus is used to access the IP-core blocks CSRs. In case
+	  if an attempted APB transaction stays with no response for a pre-
+	  defined time an interrupt occurs and the bus gets freed for a next
+	  operation. It is done by the APB-bus Errors Handler Block (APB EHB).
+	  This driver provides the interrupt handler to detect the erroneous
+	  address, prints an error message about the address fault, updates an
+	  errors counter. The counter and the APB-bus operations timeout can be
+	  accessed via corresponding sysfs nodes.
+
+	  If unsure, say N.
+
 endmenu
diff --git a/drivers/soc/baikal-t1/Makefile b/drivers/soc/baikal-t1/Makefile
index c069791058b9..ffb035600e01 100644
--- a/drivers/soc/baikal-t1/Makefile
+++ b/drivers/soc/baikal-t1/Makefile
@@ -1,2 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_BT1_AXI_EHB) += axi-ehb.o
+obj-$(CONFIG_BT1_APB_EHB) += apb-ehb.o
diff --git a/drivers/soc/baikal-t1/apb-ehb.c b/drivers/soc/baikal-t1/apb-ehb.c
new file mode 100644
index 000000000000..726cb75d29cb
--- /dev/null
+++ b/drivers/soc/baikal-t1/apb-ehb.c
@@ -0,0 +1,381 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2014 - 2020 BAIKAL ELECTRONICS, JSC
+ *
+ * Authors:
+ *   Serge Semin <Sergey.Semin@baikalelectronics.ru>
+ *
+ * Baikal-T1 APB-bus Errors Handler Block driver.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/atomic.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/nmi.h>
+#include <linux/time64.h>
+#include <linux/clk.h>
+#include <linux/sysfs.h>
+
+#include "common.h"
+
+#define APB_EHB_ISR			0x00
+#define APB_EHB_ISR_PENDING		BIT(0)
+#define APB_EHB_ISR_MASK		BIT(1)
+#define APB_EHB_ADDR			0x04
+#define APB_EHB_TIMEOUT			0x08
+
+#define APB_EHB_TIMEOUT_MIN		0x000003FFU
+#define APB_EHB_TIMEOUT_MAX		0xFFFFFFFFU
+
+#define APB_EHB_N_TO_TOUT_US(_rate, _n) ({		\
+	uint64_t _tmp = USEC_PER_SEC * (uint64_t)(_n);	\
+	do_div(_tmp, _rate);				\
+	_tmp;						\
+})
+#define APB_EHB_TOUT_TO_N_US(_rate, _tout) ({		\
+	uint64_t _tmp = (_tout) * (uint64_t)(_rate);	\
+	do_div(_tmp, USEC_PER_SEC);			\
+	_tmp;						\
+})
+
+/*
+ * struct apb_ehb - Baikal-T1 APB EHB private data.
+ * @dev: Pointer to the device structure.
+ * @regs: Memory mapped block registers.
+ * @reg_isr_lock: Registers memory lock.
+ * @res: No-device error injection memory region.
+ * @irq: Errors IRQ number.
+ * @count: Number of errors detected.
+ * @ref: APB-reference clock.
+ */
+struct apb_ehb {
+	struct device *dev;
+
+	void __iomem *regs;
+	spinlock_t reg_isr_lock;
+	void __iomem *res;
+	int irq;
+
+	atomic_t count;
+
+	struct clk *ref;
+};
+
+static irqreturn_t apb_ehb_isr(int irq, void *data)
+{
+	struct apb_ehb *ehb = data;
+	unsigned long flags;
+	u32 addr;
+
+	addr = bt1_read(ehb->regs + APB_EHB_ADDR);
+
+	dev_crit_ratelimited(ehb->dev,
+		"APB-bus fault %d: Slave access timeout at 0x%08x\n",
+		atomic_inc_return(&ehb->count),
+		addr);
+
+	/*
+	 * Print backtrace on each CPU. This might be pointless if the fault
+	 * has happened on the same CPU as the IRQ handler is executed or
+	 * the other core proceeded further execution despite the error.
+	 * But if it's not, by looking at the trace we would get straight to
+	 * the cause of the problem.
+	 */
+	trigger_all_cpu_backtrace();
+
+	spin_lock_irqsave(&ehb->reg_isr_lock, flags);
+	bt1_update(ehb->regs + APB_EHB_ISR, APB_EHB_ISR_PENDING, 0);
+	spin_unlock_irqrestore(&ehb->reg_isr_lock, flags);
+
+	return IRQ_HANDLED;
+}
+
+static void apb_ehb_clear_data(void *data)
+{
+	struct apb_ehb *ehb = data;
+	struct platform_device *pdev = to_platform_device(ehb->dev);
+
+	platform_set_drvdata(pdev, NULL);
+}
+
+static struct apb_ehb *apb_ehb_create_data(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct apb_ehb *ehb;
+	int ret;
+
+	ehb = devm_kzalloc(dev, sizeof(*ehb), GFP_KERNEL);
+	if (!ehb)
+		return ERR_PTR(-ENOMEM);
+
+	ret = devm_add_action(dev, apb_ehb_clear_data, ehb);
+	if (ret) {
+		dev_err(dev, "Can't add APB EHB data clear action\n");
+		return ERR_PTR(ret);
+	}
+
+	ehb->dev = dev;
+	atomic_set(&ehb->count, 0);
+	platform_set_drvdata(pdev, ehb);
+
+	return ehb;
+}
+
+static int apb_ehb_request_regs(struct apb_ehb *ehb)
+{
+	struct platform_device *pdev = to_platform_device(ehb->dev);
+
+	ehb->regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(ehb->regs)) {
+		dev_err(ehb->dev, "Couldn't map APB EHB registers\n");
+		return PTR_ERR(ehb->regs);
+	}
+
+	ehb->res = devm_platform_ioremap_resource(pdev, 1);
+	if (IS_ERR(ehb->regs)) {
+		dev_err(ehb->dev, "Couldn't map reserved region\n");
+		return PTR_ERR(ehb->res);
+	}
+
+	return 0;
+}
+
+static void apb_ehb_disable_clk(void *data)
+{
+	struct apb_ehb *ehb = data;
+
+	clk_disable_unprepare(ehb->ref);
+}
+
+static int apb_ehb_request_clk(struct apb_ehb *ehb)
+{
+	int ret;
+
+	ehb->ref = devm_clk_get(ehb->dev, "ref");
+	if (IS_ERR(ehb->ref)) {
+		dev_err(ehb->dev, "Couldn't get APB clock descriptor\n");
+		return PTR_ERR(ehb->ref);
+	}
+
+	ret = clk_prepare_enable(ehb->ref);
+	if (ret) {
+		dev_err(ehb->dev, "Couldn't enable the APB clock\n");
+		return ret;
+	}
+
+	ret = devm_add_action_or_reset(ehb->dev, apb_ehb_disable_clk, ehb);
+	if (ret)
+		dev_err(ehb->dev, "Can't add APB EHB clocks disable action\n");
+
+	return ret;
+}
+
+static void apb_ehb_clear_irq(void *data)
+{
+	struct apb_ehb *ehb = data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ehb->reg_isr_lock, flags);
+	bt1_update(ehb->regs + APB_EHB_ISR, APB_EHB_ISR_MASK, 0);
+	spin_unlock_irqrestore(&ehb->reg_isr_lock, flags);
+}
+
+static int apb_ehb_request_irq(struct apb_ehb *ehb)
+{
+	struct platform_device *pdev = to_platform_device(ehb->dev);
+	int ret;
+
+	spin_lock_init(&ehb->reg_isr_lock);
+
+	ehb->irq = platform_get_irq(pdev, 0);
+	if (ehb->irq < 0) {
+		dev_err(ehb->dev, "Couldn't find APB EHB IRQ number\n");
+		return ehb->irq;
+	}
+
+	ret = devm_request_irq(ehb->dev, ehb->irq, apb_ehb_isr, IRQF_SHARED,
+			       "apb_ehb", ehb);
+	if (ret) {
+		dev_err(ehb->dev, "Couldn't request APB EHB IRQ\n");
+		return ret;
+	}
+
+	ret = devm_add_action(ehb->dev, apb_ehb_clear_irq, ehb);
+	if (ret) {
+		dev_err(ehb->dev, "Can't add APB EHB IRQs clear action\n");
+		return ret;
+	}
+
+	/* Unmask IRQ and clear it' pending flag. */
+	bt1_update(ehb->regs + APB_EHB_ISR,
+		   APB_EHB_ISR_PENDING | APB_EHB_ISR_MASK, APB_EHB_ISR_MASK);
+
+	return 0;
+}
+
+static ssize_t count_show(struct device *dev, struct device_attribute *attr,
+			  char *buf)
+{
+	struct apb_ehb *ehb = dev_get_drvdata(dev);
+
+	return scnprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&ehb->count));
+}
+static DEVICE_ATTR_RO(count);
+
+static ssize_t timeout_show(struct device *dev, struct device_attribute *attr,
+			    char *buf)
+{
+	struct apb_ehb *ehb = dev_get_drvdata(dev);
+	unsigned long timeout, rate;
+	u32 n;
+
+	rate = clk_get_rate(ehb->ref);
+	if (!rate)
+		return -ENODEV;
+
+	n = bt1_read(ehb->regs + APB_EHB_TIMEOUT);
+	timeout = APB_EHB_N_TO_TOUT_US(rate, n);
+
+	return scnprintf(buf, PAGE_SIZE, "%lu\n", timeout);
+}
+
+static ssize_t timeout_store(struct device *dev,
+			     struct device_attribute *attr,
+			     const char *buf, size_t count)
+{
+	struct apb_ehb *ehb = dev_get_drvdata(dev);
+	unsigned long timeout, rate;
+	u32 n;
+
+	if (kstrtoul(buf, 0, &timeout) < 0)
+		return -EINVAL;
+
+	rate = clk_get_rate(ehb->ref);
+	if (!rate)
+		return -ENODEV;
+
+	n = APB_EHB_TOUT_TO_N_US(rate, timeout);
+	n = clamp(n, APB_EHB_TIMEOUT_MIN, APB_EHB_TIMEOUT_MAX);
+
+	bt1_write(ehb->regs + APB_EHB_TIMEOUT, n);
+
+	return count;
+}
+static DEVICE_ATTR_RW(timeout);
+
+static int inject_error_show(struct device *dev, struct device_attribute *attr,
+			     char *buf)
+{
+	return scnprintf(buf, PAGE_SIZE, "Error injection: nodev irq\n");
+}
+
+static int inject_error_store(struct device *dev,
+			      struct device_attribute *attr,
+			      const char *data, size_t count)
+{
+	struct apb_ehb *ehb = dev_get_drvdata(dev);
+	unsigned long flags;
+
+	/*
+	 * Either dummy read from the unmapped address in the APB IO area
+	 * or manually set the IRQ status.
+	 */
+	if (!strncmp(data, "nodev", 5)) {
+		readl(ehb->res);
+	} else if (!strncmp(data, "irq", 3)) {
+		spin_lock_irqsave(&ehb->reg_isr_lock, flags);
+		bt1_write(ehb->regs + APB_EHB_ISR,
+			  APB_EHB_ISR_PENDING | APB_EHB_ISR_MASK);
+		spin_unlock_irqrestore(&ehb->reg_isr_lock, flags);
+	} else
+		return -EINVAL;
+
+	return count;
+}
+static DEVICE_ATTR_RW(inject_error);
+
+static struct attribute *apb_ehb_sysfs_attrs[] = {
+	&dev_attr_count.attr,
+	&dev_attr_timeout.attr,
+	&dev_attr_inject_error.attr,
+	NULL
+};
+ATTRIBUTE_GROUPS(apb_ehb_sysfs);
+
+static void apb_ehb_remove_sysfs(void *data)
+{
+	struct apb_ehb *ehb = data;
+
+	device_remove_groups(ehb->dev, apb_ehb_sysfs_groups);
+}
+
+static int apb_ehb_init_sysfs(struct apb_ehb *ehb)
+{
+	int ret;
+
+	ret = device_add_groups(ehb->dev, apb_ehb_sysfs_groups);
+	if (ret) {
+		dev_err(ehb->dev, "Failed to create EHB APB sysfs nodes\n");
+		return ret;
+	}
+
+	ret = devm_add_action_or_reset(ehb->dev, apb_ehb_remove_sysfs, ehb);
+	if (ret)
+		dev_err(ehb->dev, "Can't add APB EHB sysfs remove action\n");
+
+	return ret;
+}
+
+static int apb_ehb_probe(struct platform_device *pdev)
+{
+	struct apb_ehb *ehb;
+	int ret;
+
+	ehb = apb_ehb_create_data(pdev);
+	if (IS_ERR(ehb))
+		return PTR_ERR(ehb);
+
+	ret = apb_ehb_request_regs(ehb);
+	if (ret)
+		return ret;
+
+	ret = apb_ehb_request_clk(ehb);
+	if (ret)
+		return ret;
+
+	ret = apb_ehb_request_irq(ehb);
+	if (ret)
+		return ret;
+
+	ret = apb_ehb_init_sysfs(ehb);
+	if (ret)
+		return ret;
+
+	dev_info(ehb->dev, "APB-bus errors handler installed\n");
+
+	return 0;
+}
+
+static const struct of_device_id apb_ehb_of_match[] = {
+	{ .compatible = "be,bt1-apb-ehb" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, apb_ehb_of_match);
+
+static struct platform_driver apb_ehb_driver = {
+	.probe = apb_ehb_probe,
+	.driver = {
+		.name = "bt1-apb-ehb",
+		.of_match_table = of_match_ptr(apb_ehb_of_match)
+	}
+};
+module_platform_driver(apb_ehb_driver);
+
+MODULE_AUTHOR("Serge Semin <Sergey.Semin@baikalelectronics.ru>");
+MODULE_DESCRIPTION("Baikal-T1 APB EHB driver");
+MODULE_LICENSE("GPL v2");
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 6/6] soc: bt1: Add Baikal-T1 L2-cache Control Block driver
       [not found] <20200306130721.10347-1-Sergey.Semin@baikalelectronics.ru>
                   ` (4 preceding siblings ...)
  2020-03-06 13:07 ` [PATCH 5/6] soc: bt1: Add Baikal-T1 APB-bus " Sergey.Semin
@ 2020-03-06 13:07 ` Sergey.Semin
  5 siblings, 0 replies; 10+ messages in thread
From: Sergey.Semin @ 2020-03-06 13:07 UTC (permalink / raw)
  Cc: Serge Semin, Serge Semin, Alexey Malahov, Thomas Bogendoerfer,
	Paul Burton, Ralf Baechle, Arnd Bergmann, Olof Johansson, soc,
	linux-kernel

From: Serge Semin <Sergey.Semin@baikalelectronics.ru>

Baikal-T1 SoC provides a way to tune the MIPS P5600 CM2 L2-cache
performance up. It can be done by changing the L2-RAM Data/Tag/WS
latencies in a dedicated register exposed by the system controller.
The driver added by this commit provides a dts properties-based and
sysfs-based interface for it.

Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
Signed-off-by: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>
Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: Paul Burton <paulburton@kernel.org>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Olof Johansson <olof@lixom.net>
Cc: soc@kernel.org
---
 drivers/soc/baikal-t1/Kconfig  |  12 ++
 drivers/soc/baikal-t1/Makefile |   1 +
 drivers/soc/baikal-t1/l2-ctl.c | 325 +++++++++++++++++++++++++++++++++
 3 files changed, 338 insertions(+)
 create mode 100644 drivers/soc/baikal-t1/l2-ctl.c

diff --git a/drivers/soc/baikal-t1/Kconfig b/drivers/soc/baikal-t1/Kconfig
index a021abea102f..b23675d4a097 100644
--- a/drivers/soc/baikal-t1/Kconfig
+++ b/drivers/soc/baikal-t1/Kconfig
@@ -34,4 +34,16 @@ config BT1_APB_EHB
 
 	  If unsure, say N.
 
+config BT1_L2_CTL
+	bool "Baikal-T1 CM2 L2 Cache Control Block"
+	depends on SOC_BAIKAL_T1 && OF
+	help
+	  Baikal-T1 CPU is based on the MIPS P5600 Warrior IP-core. The CPU
+	  resides Coherency Manager V2 with embedded 1MB L2-cache. It's
+	  possible to tune the L2 cache performance up by setting the data,
+	  tags and way-select latencies. This driver provides a dts
+	  properties-based and sysfs interface for it.
+
+	  If unsure, say N.
+
 endmenu
diff --git a/drivers/soc/baikal-t1/Makefile b/drivers/soc/baikal-t1/Makefile
index ffb035600e01..70918b79e17f 100644
--- a/drivers/soc/baikal-t1/Makefile
+++ b/drivers/soc/baikal-t1/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_BT1_AXI_EHB) += axi-ehb.o
 obj-$(CONFIG_BT1_APB_EHB) += apb-ehb.o
+obj-$(CONFIG_BT1_L2_CTL) += l2-ctl.o
diff --git a/drivers/soc/baikal-t1/l2-ctl.c b/drivers/soc/baikal-t1/l2-ctl.c
new file mode 100644
index 000000000000..2136b9b8bad5
--- /dev/null
+++ b/drivers/soc/baikal-t1/l2-ctl.c
@@ -0,0 +1,325 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
+ *
+ * Authors:
+ *   Serge Semin <Sergey.Semin@baikalelectronics.ru>
+ *
+ * Baikal-T1 CM2 L2-cache Control Block driver.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+#include <linux/sysfs.h>
+#include <linux/of.h>
+
+#include "common.h"
+
+#define L2_CTL_REG			0x0
+#define L2_CTL_DATA_STALL_FLD		0
+#define L2_CTL_DATA_STALL_MASK		GENMASK(1, L2_CTL_DATA_STALL_FLD)
+#define L2_CTL_TAG_STALL_FLD		2
+#define L2_CTL_TAG_STALL_MASK		GENMASK(3, L2_CTL_TAG_STALL_FLD)
+#define L2_CTL_WS_STALL_FLD		4
+#define L2_CTL_WS_STALL_MASK		GENMASK(5, L2_CTL_WS_STALL_FLD)
+#define L2_CTL_SET_CLKRATIO		BIT(13)
+#define L2_CTL_CLKRATIO_LOCK		BIT(31)
+
+#define L2_CTL_STALL_MIN		0
+#define L2_CTL_STALL_MAX		3
+#define L2_CTL_STALL_SET_DELAY_US	1
+#define L2_CTL_STALL_SET_TOUT_US	1000
+
+/*
+ * struct l2_ctl - Baikal-T1 L2 Control block private data.
+ * @dev: Pointer to the device structure.
+ * @reg: Regmap of the control register.
+ */
+struct l2_ctl {
+	struct device *dev;
+
+	struct regmap *reg;
+};
+
+/*
+ * enum l2_ctl_stall - Baikal-T1 L2-cache-RAM stall identifier.
+ * @L2_WSSTALL: Way-select latency.
+ * @L2_TAGSTALL: Tag latency.
+ * @L2_DATASTALL: Data latency.
+ */
+enum l2_ctl_stall {
+	L2_WS_STALL,
+	L2_TAG_STALL,
+	L2_DATA_STALL
+};
+
+/*
+ * struct l2_ctl_device_attribute - Baikal-T1 L2-cache device attribute.
+ * @dev_attr: Actual sysfs device attribute.
+ * @id: L2-cache stall field identifier.
+ */
+struct l2_ctl_device_attribute {
+	struct device_attribute dev_attr;
+	enum l2_ctl_stall id;
+};
+#define to_l2_ctl_dev_attr(_dev_attr) \
+	container_of(_dev_attr, struct l2_ctl_device_attribute, dev_attr)
+
+#define L2_CTL_ATTR_RW(_name, _prefix, _id) \
+	struct l2_ctl_device_attribute l2_ctl_attr_##_name = \
+		{ __ATTR(_name, 0644, _prefix##_show, _prefix##_store),	_id }
+
+static int l2_ctl_get_latency(struct l2_ctl *l2, enum l2_ctl_stall id, u32 *val)
+{
+	u32 data = 0;
+	int ret;
+
+	ret = regmap_read(l2->reg, L2_CTL_REG, &data);
+	if (ret)
+		return ret;
+
+	switch (id) {
+	case L2_WS_STALL:
+		*val = BT1_GET_FLD(L2_CTL_WS_STALL, data);
+		break;
+	case L2_TAG_STALL:
+		*val = BT1_GET_FLD(L2_CTL_TAG_STALL, data);
+		break;
+	case L2_DATA_STALL:
+		*val = BT1_GET_FLD(L2_CTL_DATA_STALL, data);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int l2_ctl_set_latency(struct l2_ctl *l2, enum l2_ctl_stall id, u32 val)
+{
+	u32 mask = 0, data = 0;
+	int ret;
+
+	val = clamp_val(val, L2_CTL_STALL_MIN, L2_CTL_STALL_MAX);
+
+	switch (id) {
+	case L2_WS_STALL:
+		data = BT1_SET_FLD(L2_CTL_WS_STALL, 0, val);
+		mask = L2_CTL_WS_STALL_MASK;
+		break;
+	case L2_TAG_STALL:
+		data = BT1_SET_FLD(L2_CTL_TAG_STALL, 0, val);
+		mask = L2_CTL_TAG_STALL_MASK;
+		break;
+	case L2_DATA_STALL:
+		data = BT1_SET_FLD(L2_CTL_DATA_STALL, 0, val);
+		mask = L2_CTL_DATA_STALL_MASK;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	data |= L2_CTL_SET_CLKRATIO;
+	mask |= L2_CTL_SET_CLKRATIO;
+
+	ret = regmap_update_bits(l2->reg, L2_CTL_REG, mask, data);
+	if (ret)
+		return ret;
+
+	return regmap_read_poll_timeout(l2->reg, L2_CTL_REG, data,
+					data & L2_CTL_CLKRATIO_LOCK,
+					L2_CTL_STALL_SET_DELAY_US,
+					L2_CTL_STALL_SET_TOUT_US);
+}
+
+static void l2_ctl_clear_data(void *data)
+{
+	struct l2_ctl *l2 = data;
+	struct platform_device *pdev = to_platform_device(l2->dev);
+
+	platform_set_drvdata(pdev, NULL);
+}
+
+static struct l2_ctl *l2_ctl_create_data(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct l2_ctl *l2;
+	int ret;
+
+	l2 = devm_kzalloc(dev, sizeof(*l2), GFP_KERNEL);
+	if (!l2)
+		return ERR_PTR(-ENOMEM);
+
+	ret = devm_add_action(dev, l2_ctl_clear_data, l2);
+	if (ret) {
+		dev_err(dev, "Can't add L2 CTL data clear action\n");
+		return ERR_PTR(ret);
+	}
+
+	l2->dev = dev;
+	platform_set_drvdata(pdev, l2);
+
+	return l2;
+}
+
+static int l2_ctl_request_reg(struct l2_ctl *l2)
+{
+	l2->reg = device_node_to_regmap(l2->dev->of_node);
+	if (IS_ERR(l2->reg)) {
+		dev_err(l2->dev, "Couldn't get L2 CTL register map\n");
+		return PTR_ERR(l2->reg);
+	}
+
+	return 0;
+}
+
+static int l2_ctl_of_parse_property(struct l2_ctl *l2, enum l2_ctl_stall id,
+				    const char *propname)
+{
+	int ret = 0;
+	u32 data;
+
+	if (of_property_read_u32(l2->dev->of_node, propname, &data)) {
+		ret = l2_ctl_set_latency(l2, id, data);
+		if (ret)
+			dev_err(l2->dev, "Invalid value of '%s'\n", propname);
+	}
+
+	return ret;
+}
+
+static int l2_ctl_of_parse(struct l2_ctl *l2)
+{
+	int ret;
+
+	ret = l2_ctl_of_parse_property(l2, L2_WS_STALL, "be,l2-ws-latency");
+	if (ret)
+		return ret;
+
+	ret = l2_ctl_of_parse_property(l2, L2_TAG_STALL, "be,l2-tag-latency");
+	if (ret)
+		return ret;
+
+	return l2_ctl_of_parse_property(l2, L2_DATA_STALL,
+					"be,l2-data-latency");
+}
+
+static ssize_t l2_ctl_latency_show(struct device *dev,
+				   struct device_attribute *attr,
+				   char *buf)
+{
+	struct l2_ctl_device_attribute *devattr = to_l2_ctl_dev_attr(attr);
+	struct l2_ctl *l2 = dev_get_drvdata(dev);
+	u32 data;
+	int ret;
+
+	ret = l2_ctl_get_latency(l2, devattr->id, &data);
+	if (ret)
+		return ret;
+
+	return scnprintf(buf, PAGE_SIZE, "%u\n", data);
+}
+
+static ssize_t l2_ctl_latency_store(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf, size_t count)
+{
+	struct l2_ctl_device_attribute *devattr = to_l2_ctl_dev_attr(attr);
+	struct l2_ctl *l2 = dev_get_drvdata(dev);
+	u32 data;
+	int ret;
+
+	if (kstrtouint(buf, 0, &data) < 0)
+		return -EINVAL;
+
+	ret = l2_ctl_set_latency(l2, devattr->id, data);
+	if (ret)
+		return ret;
+
+	return count;
+}
+static L2_CTL_ATTR_RW(l2_ws_latency, l2_ctl_latency, L2_WS_STALL);
+static L2_CTL_ATTR_RW(l2_tag_latency, l2_ctl_latency, L2_TAG_STALL);
+static L2_CTL_ATTR_RW(l2_data_latency, l2_ctl_latency, L2_DATA_STALL);
+
+static struct attribute *l2_ctl_sysfs_attrs[] = {
+	&l2_ctl_attr_l2_ws_latency.dev_attr.attr,
+	&l2_ctl_attr_l2_tag_latency.dev_attr.attr,
+	&l2_ctl_attr_l2_data_latency.dev_attr.attr,
+	NULL
+};
+ATTRIBUTE_GROUPS(l2_ctl_sysfs);
+
+static void l2_ctl_remove_sysfs(void *data)
+{
+	struct l2_ctl *l2 = data;
+
+	device_remove_groups(l2->dev, l2_ctl_sysfs_groups);
+}
+
+static int l2_ctl_init_sysfs(struct l2_ctl *l2)
+{
+	int ret;
+
+	ret = device_add_groups(l2->dev, l2_ctl_sysfs_groups);
+	if (ret) {
+		dev_err(l2->dev, "Failed to create L2 CTL sysfs nodes\n");
+		return ret;
+	}
+
+	ret = devm_add_action_or_reset(l2->dev, l2_ctl_remove_sysfs, l2);
+	if (ret)
+		dev_err(l2->dev, "Can't add L2 CTL sysfs remove action\n");
+
+	return ret;
+}
+
+static int l2_ctl_probe(struct platform_device *pdev)
+{
+	struct l2_ctl *l2;
+	int ret;
+
+	l2 = l2_ctl_create_data(pdev);
+	if (IS_ERR(l2))
+		return PTR_ERR(l2);
+
+	ret = l2_ctl_request_reg(l2);
+	if (ret)
+		return ret;
+
+	ret = l2_ctl_of_parse(l2);
+	if (ret)
+		return ret;
+
+	ret = l2_ctl_init_sysfs(l2);
+	if (ret)
+		return ret;
+
+	dev_info(l2->dev, "L2-cache control driver installed\n");
+
+	return 0;
+}
+
+static const struct of_device_id l2_ctl_of_match[] = {
+	{ .compatible = "be,bt1-l2-ctl" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, l2_ctl_of_match);
+
+static struct platform_driver l2_ctl_driver = {
+	.probe = l2_ctl_probe,
+	.driver = {
+		.name = "bt1-l2-ctl",
+		.of_match_table = of_match_ptr(l2_ctl_of_match)
+	}
+};
+module_platform_driver(l2_ctl_driver);
+
+MODULE_AUTHOR("Serge Semin <Sergey.Semin@baikalelectronics.ru>");
+MODULE_DESCRIPTION("Baikal-T1 L2-cache driver");
+MODULE_LICENSE("GPL v2");
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/6] dt-bindings: Add Baikal-T1 APB-bus EHB dts bindings file
  2020-03-06 13:07 ` [PATCH 2/6] dt-bindings: Add Baikal-T1 APB-bus " Sergey.Semin
@ 2020-03-09 18:07   ` Rob Herring
  0 siblings, 0 replies; 10+ messages in thread
From: Rob Herring @ 2020-03-09 18:07 UTC (permalink / raw)
  To: Sergey.Semin
  Cc: Mark Rutland, Serge Semin, Serge Semin, Alexey Malahov,
	Thomas Bogendoerfer, Paul Burton, Ralf Baechle, Arnd Bergmann,
	Olof Johansson, soc, devicetree, linux-kernel

On Fri, 6 Mar 2020 16:07:17 +0300, <Sergey.Semin@baikalelectronics.ru> wrote:
> From: Serge Semin <Sergey.Semin@baikalelectronics.ru>
> 
> This is a specific block embedded into the Baikal-T1 SoC, which is
> dedicated to detect APB-bus protocol errors and tune the peripheral
> access timeout. So the dts bindings implies that corresponding dts
> node would be equipped with "be,bt1-apb-ehb" compatible string, MMIO
> region of registers space and of space with no device mapped,
> interrupts property and with an APB-reference clock handler.
> 
> Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
> Signed-off-by: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>
> Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> Cc: Paul Burton <paulburton@kernel.org>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Olof Johansson <olof@lixom.net>
> Cc: soc@kernel.org
> ---
>  .../soc/baikal-t1/be,bt1-apb-ehb.yaml         | 66 +++++++++++++++++++
>  1 file changed, 66 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/soc/baikal-t1/be,bt1-apb-ehb.yaml
> 

My bot found errors running 'make dt_binding_check' on your patch:

Documentation/devicetree/bindings/soc/baikal-t1/be,bt1-apb-ehb.example.dts:18:18: fatal error: dt-bindings/clock/bt1-ccu.h: No such file or directory
         #include <dt-bindings/clock/bt1-ccu.h>
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
scripts/Makefile.lib:311: recipe for target 'Documentation/devicetree/bindings/soc/baikal-t1/be,bt1-apb-ehb.example.dt.yaml' failed
make[1]: *** [Documentation/devicetree/bindings/soc/baikal-t1/be,bt1-apb-ehb.example.dt.yaml] Error 1
Makefile:1262: recipe for target 'dt_binding_check' failed
make: *** [dt_binding_check] Error 2

See https://patchwork.ozlabs.org/patch/1250282
Please check and re-submit.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 3/6] dt-bindings: Add Baikal-T1 L2-cache Control Block dts bindings file
  2020-03-06 13:07 ` [PATCH 3/6] dt-bindings: Add Baikal-T1 L2-cache Control Block " Sergey.Semin
@ 2020-03-12 21:23   ` Rob Herring
  2020-04-03 11:52     ` Sergey Semin
  0 siblings, 1 reply; 10+ messages in thread
From: Rob Herring @ 2020-03-12 21:23 UTC (permalink / raw)
  To: Sergey.Semin
  Cc: Mark Rutland, Serge Semin, Alexey Malahov, Thomas Bogendoerfer,
	Paul Burton, Ralf Baechle, Arnd Bergmann, Olof Johansson, soc,
	devicetree, linux-kernel

On Fri, Mar 06, 2020 at 04:07:18PM +0300, Sergey.Semin@baikalelectronics.ru wrote:
> From: Serge Semin <Sergey.Semin@baikalelectronics.ru>
> 
> There is a single register provided by the SoC system controller,
> which can be used to tune the L2-cache up. It only provides a way
> to change the L2-RAM access latencies. So aside from the MMIO region
> with that setting and "be,bt1-l2-ctl" compatible string the device
> node can be optionally equipped with the properties of Tag/Data/WS
> latencies.
> 
> Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
> Signed-off-by: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>
> Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> Cc: Paul Burton <paulburton@kernel.org>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Olof Johansson <olof@lixom.net>
> Cc: soc@kernel.org
> ---
>  .../bindings/soc/baikal-t1/be,bt1-l2-ctl.yaml | 108 ++++++++++++++++++
>  1 file changed, 108 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/soc/baikal-t1/be,bt1-l2-ctl.yaml
> 
> diff --git a/Documentation/devicetree/bindings/soc/baikal-t1/be,bt1-l2-ctl.yaml b/Documentation/devicetree/bindings/soc/baikal-t1/be,bt1-l2-ctl.yaml
> new file mode 100644
> index 000000000000..8769b3fa517c
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/soc/baikal-t1/be,bt1-l2-ctl.yaml
> @@ -0,0 +1,108 @@
> +# SPDX-License-Identifier: GPL-2.0

Dual license

> +#
> +# Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
> +#
> +# Baikal-T1 L2-cache Control Block Device Tree Bindings.
> +#
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/soc/baikal-t1/be,bt1-l2-ctl.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Baikal-T1 L2-cache Control Block
> +
> +maintainers:
> +  - Serge Semin <fancer.lancer@gmail.com>
> +
> +description: |
> +  Baikal-T1 exposes a few settings to tune the MIPS P5600 CM2 L2-cache
> +  performance up. In particular it's possible to change the Tag, Data and
> +  Way-select RAM access latencies. This bindings file describes the system
> +  controller block, which provides an interface to set the tuning up.
> +
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: syscon
> +    then:
> +      $ref: ../../mfd/syscon.yaml#
> +    else:
> +      properties:
> +        reg-io-width: false
> +
> +        little-endian: false
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - description: P5600 CM2 L2-cache RAM external configuration block.
> +        const: be,bt1-l2-ctl
> +      - description: P5600 CM2 L2-cache RAM system controller block.
> +        items:
> +          - const: be,bt1-l2-ctl
> +          - const: syscon

Why is this conditional? Different h/w?

> +
> +  reg:
> +    description: MMIO register with MIPS P5600 CM2 L2-cache RAM settings.

You can drop this.

> +    maxItems: 1
> +
> +  be,l2-ws-latency:
> +    description: Cycles of latency for Way-select RAM accesses.
> +    default: 0
> +    allOf:
> +      - $ref: /schemas/types.yaml#/definitions/uint32
> +      - minimum: 0
> +        maximum: 3

These should be at the same level as 'default' or default moved here (I 
prefer the former). IOW, only $ref has to be under 'allOf'.

> +
> +  be,l2-tag-latency:
> +    description: Cycles of latency for Tag RAM accesses.
> +    default: 0
> +    allOf:
> +      - $ref: /schemas/types.yaml#/definitions/uint32
> +      - minimum: 0
> +        maximum: 3
> +
> +  be,l2-data-latency:
> +    description: Cycles of latency for Data RAM accesses.
> +    default: 1
> +    allOf:
> +      - $ref: /schemas/types.yaml#/definitions/uint32
> +      - minimum: 0
> +        maximum: 3
> +
> +  reg-io-width:
> +    const: 4
> +
> +  little-endian: true
> +
> +additionalProperties: false
> +
> +required:
> +  - compatible
> +  - reg
> +
> +examples:
> +  - |
> +    l2_ctl1: l2@1F04D028 {

lowercase hex.

> +      compatible = "be,bt1-l2-ctl";
> +      reg = <0x1F04D028 0x004>;
> +
> +      be,l2-ws-latency = <0>;
> +      be,l2-tag-latency = <0>;
> +      be,l2-data-latency = <1>;
> +    };
> +  - |
> +    l2_ctl2: l2@1F04D028 {
> +      compatible = "be,bt1-l2-ctl", "syscon";
> +      reg = <0x1F04D028 0x004>;
> +
> +      be,l2-ws-latency = <0>;
> +      be,l2-tag-latency = <0>;
> +      be,l2-data-latency = <1>;
> +
> +      little-endian;
> +      reg-io-width = <4>;
> +    };
> +...
> -- 
> 2.25.1
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 4/6] soc: bt1: Add Baikal-T1 AXI-bus EHB driver
  2020-03-06 13:07 ` [PATCH 4/6] soc: bt1: Add Baikal-T1 AXI-bus EHB driver Sergey.Semin
@ 2020-03-30  3:14   ` Randy Dunlap
  0 siblings, 0 replies; 10+ messages in thread
From: Randy Dunlap @ 2020-03-30  3:14 UTC (permalink / raw)
  To: Sergey.Semin
  Cc: Serge Semin, Alexey Malahov, Thomas Bogendoerfer, Paul Burton,
	Ralf Baechle, Arnd Bergmann, Olof Johansson, soc, linux-kernel

Hi--

On 3/6/20 5:07 AM, Sergey.Semin@baikalelectronics.ru wrote:
> From: Serge Semin <Sergey.Semin@baikalelectronics.ru>
> 
> AXI3-bus is the main communication bus connecting all high-speed peripheral
> IP-cores with RAM controller and MIPS P5600 cores. Baikal-T1 SoC provides a
> way to detect the bus protocol errors and report a short info about it by
> means of the AXI-bus Errors Handler Block (AXI EHB). The block rises an

                                                                 raises an

> interrupt indicating an AXI protocol error at an attempt either to reach
> a non-existent slave device or to perform an invalid operation with a
> slave IP-block. This driver provides the interrupt handler, which prints
> an error message with a faulty address and updates an errors counter,
> and exposes a sysfs-node to inject the described types of errors.
> 
> Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
> Signed-off-by: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>
> Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> Cc: Paul Burton <paulburton@kernel.org>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Olof Johansson <olof@lixom.net>
> Cc: soc@kernel.org
> ---

> diff --git a/drivers/soc/baikal-t1/Kconfig b/drivers/soc/baikal-t1/Kconfig
> new file mode 100644
> index 000000000000..aca155350612
> --- /dev/null
> +++ b/drivers/soc/baikal-t1/Kconfig
> @@ -0,0 +1,22 @@
> +# SPDX-License-Identifier: GPL-2.0
> +menu "Baikal-T1 SoC drivers"
> +
> +config SOC_BAIKAL_T1
> +	def_bool y
> +	depends on MIPS_BAIKAL_T1 || COMPILE_TEST
> +
> +config BT1_AXI_EHB
> +	bool "Baikal-T1 AXI-bus Errors Handler Block"
> +	depends on SOC_BAIKAL_T1 && OF
> +	help
> +	  Baikal-T1 CCU registers space as being MFD provides an access to the

	                                             and provides access to the

> +	  AXI-bus Errors Handler Block (AXI EHB). It rises an interrupt

	                                             raises

> +	  indicating an AXI protocol error at an attempt either to reach a
> +	  non-existent slave device or to perform an invalid operation with a
> +	  slave IP-block. This driver provides the interrupt handler, which
> +	  prints an error message with a faulty address and updates an errors
> +	  counter.
> +
> +	  If unsure, say N.
> +
> +endmenu

-- 
~Randy


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 3/6] dt-bindings: Add Baikal-T1 L2-cache Control Block dts bindings file
  2020-03-12 21:23   ` Rob Herring
@ 2020-04-03 11:52     ` Sergey Semin
  0 siblings, 0 replies; 10+ messages in thread
From: Sergey Semin @ 2020-04-03 11:52 UTC (permalink / raw)
  To: Rob Herring
  Cc: Mark Rutland, Alexey Malahov, Thomas Bogendoerfer, Paul Burton,
	Ralf Baechle, Arnd Bergmann, Olof Johansson, soc, devicetree,
	linux-kernel

On Thu, Mar 12, 2020 at 04:23:35PM -0500, Rob Herring wrote:
> On Fri, Mar 06, 2020 at 04:07:18PM +0300, Sergey.Semin@baikalelectronics.ru wrote:
> > From: Serge Semin <Sergey.Semin@baikalelectronics.ru>
> > 
> > There is a single register provided by the SoC system controller,
> > which can be used to tune the L2-cache up. It only provides a way
> > to change the L2-RAM access latencies. So aside from the MMIO region
> > with that setting and "be,bt1-l2-ctl" compatible string the device
> > node can be optionally equipped with the properties of Tag/Data/WS
> > latencies.
> > 
> > Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
> > Signed-off-by: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>
> > Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> > Cc: Paul Burton <paulburton@kernel.org>
> > Cc: Ralf Baechle <ralf@linux-mips.org>
> > Cc: Arnd Bergmann <arnd@arndb.de>
> > Cc: Olof Johansson <olof@lixom.net>
> > Cc: soc@kernel.org
> > ---
> >  .../bindings/soc/baikal-t1/be,bt1-l2-ctl.yaml | 108 ++++++++++++++++++
> >  1 file changed, 108 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/soc/baikal-t1/be,bt1-l2-ctl.yaml
> > 
> > diff --git a/Documentation/devicetree/bindings/soc/baikal-t1/be,bt1-l2-ctl.yaml b/Documentation/devicetree/bindings/soc/baikal-t1/be,bt1-l2-ctl.yaml
> > new file mode 100644
> > index 000000000000..8769b3fa517c
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/soc/baikal-t1/be,bt1-l2-ctl.yaml
> > @@ -0,0 +1,108 @@
> > +# SPDX-License-Identifier: GPL-2.0
> 
> Dual license

Ok.

> 
> > +#
> > +# Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
> > +#
> > +# Baikal-T1 L2-cache Control Block Device Tree Bindings.
> > +#
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/soc/baikal-t1/be,bt1-l2-ctl.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Baikal-T1 L2-cache Control Block
> > +
> > +maintainers:
> > +  - Serge Semin <fancer.lancer@gmail.com>
> > +
> > +description: |
> > +  Baikal-T1 exposes a few settings to tune the MIPS P5600 CM2 L2-cache
> > +  performance up. In particular it's possible to change the Tag, Data and
> > +  Way-select RAM access latencies. This bindings file describes the system
> > +  controller block, which provides an interface to set the tuning up.
> > +
> > +allOf:
> > +  - if:
> > +      properties:
> > +        compatible:
> > +          contains:
> > +            const: syscon
> > +    then:
> > +      $ref: ../../mfd/syscon.yaml#
> > +    else:
> > +      properties:
> > +        reg-io-width: false
> > +
> > +        little-endian: false
> > +
> > +properties:
> > +  compatible:
> > +    oneOf:
> > +      - description: P5600 CM2 L2-cache RAM external configuration block.
> > +        const: be,bt1-l2-ctl
> > +      - description: P5600 CM2 L2-cache RAM system controller block.
> > +        items:
> > +          - const: be,bt1-l2-ctl
> > +          - const: syscon
> 
> Why is this conditional? Different h/w?
> 

Seeing the config register has got a few other CPU parameters to tune
I meant to have both syscon and syscon-less compatible nodes supported
For the same reason there is "allOf" with "syscon.yaml" reference above.

This P5600 CM2 L2-Cach RAM setting is a part of the Baikal-T1 System
Control Module, in particular the register lives someplace amongst Clock
Control Unit and System-specific settings. Seeing the clock and
system-specific parameters are almost always redistributed to a
dedicated registers set, in my first System Control Module DT node design
I was going to split the functionality up into the dedicated sub-nodes.
If there are some mixed parameters declared in the corresponding
registers set, I marked these nodes with additional "syscon". I
thoroughly described that design in RFC: https://lkml.org/lkml/2020/3/22/393
sent To: you.

Seeing there are others indirectly related to the System Controller DT node
design issues I've been addressed in the framework of other patchsets, I
also suggested an alternative design in that RFC text. So should you have
any comments, please send your response right there. I am currently in a bit
of frustration, since noone has sent any comments to the RFC, which stops me
from moving on with fixing the patchsets issues. Though I am pretty sure,
that the alternative design would be better accepted by you and community,
so if no comments pop up in the RFC soon, I'll start implementing it.
The alternative solution "/* System Controller DT Nodes II */" in the
RFC includes having a common "syscon"-compatible node representing the
Baikal-T1 System Controller, while sub-nodes like Clocks Control Units and this
L2-cache RAM control block would import a regmap from that "syscon"
(using a standard syscon_node_to_regmap()-like method). This will solve a
multiple issues raised in others patchsets and the problem you noted here.

Please also note, that following Arnd Bergmann suggestion, I'll move
this driver to the drivers/memory subsystem. So the binding file will be
also moved to Documentation/devicetree/bindings/memory-controllers.
Similarly the ehb-drivers and bindings will be moved to the drivers/bus
and Documentation/devicetree/bindings/bus/ directories respectively.

> > +
> > +  reg:
> > +    description: MMIO register with MIPS P5600 CM2 L2-cache RAM settings.
> 
> You can drop this.

Ok.

> 
> > +    maxItems: 1
> > +
> > +  be,l2-ws-latency:
> > +    description: Cycles of latency for Way-select RAM accesses.
> > +    default: 0
> > +    allOf:
> > +      - $ref: /schemas/types.yaml#/definitions/uint32
> > +      - minimum: 0
> > +        maximum: 3
> 
> These should be at the same level as 'default' or default moved here (I 
> prefer the former). IOW, only $ref has to be under 'allOf'.

Ok.

> 
> > +
> > +  be,l2-tag-latency:
> > +    description: Cycles of latency for Tag RAM accesses.
> > +    default: 0
> > +    allOf:
> > +      - $ref: /schemas/types.yaml#/definitions/uint32
> > +      - minimum: 0
> > +        maximum: 3
> > +
> > +  be,l2-data-latency:
> > +    description: Cycles of latency for Data RAM accesses.
> > +    default: 1
> > +    allOf:
> > +      - $ref: /schemas/types.yaml#/definitions/uint32
> > +      - minimum: 0
> > +        maximum: 3
> > +
> > +  reg-io-width:
> > +    const: 4
> > +
> > +  little-endian: true
> > +
> > +additionalProperties: false
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +
> > +examples:
> > +  - |
> > +    l2_ctl1: l2@1F04D028 {
> 
> lowercase hex.

Ok. I'll do this to the next example case as well.

Regards,
-Sergey

> 
> > +      compatible = "be,bt1-l2-ctl";
> > +      reg = <0x1F04D028 0x004>;
> > +
> > +      be,l2-ws-latency = <0>;
> > +      be,l2-tag-latency = <0>;
> > +      be,l2-data-latency = <1>;
> > +    };
> > +  - |
> > +    l2_ctl2: l2@1F04D028 {
> > +      compatible = "be,bt1-l2-ctl", "syscon";
> > +      reg = <0x1F04D028 0x004>;
> > +
> > +      be,l2-ws-latency = <0>;
> > +      be,l2-tag-latency = <0>;
> > +      be,l2-data-latency = <1>;
> > +
> > +      little-endian;
> > +      reg-io-width = <4>;
> > +    };
> > +...
> > -- 
> > 2.25.1
> > 

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2020-04-03 11:52 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20200306130721.10347-1-Sergey.Semin@baikalelectronics.ru>
2020-03-06 13:07 ` [PATCH 1/6] dt-bindings: Add Baikal-T1 AXI-bus EHB dts bindings file Sergey.Semin
2020-03-06 13:07 ` [PATCH 2/6] dt-bindings: Add Baikal-T1 APB-bus " Sergey.Semin
2020-03-09 18:07   ` Rob Herring
2020-03-06 13:07 ` [PATCH 3/6] dt-bindings: Add Baikal-T1 L2-cache Control Block " Sergey.Semin
2020-03-12 21:23   ` Rob Herring
2020-04-03 11:52     ` Sergey Semin
2020-03-06 13:07 ` [PATCH 4/6] soc: bt1: Add Baikal-T1 AXI-bus EHB driver Sergey.Semin
2020-03-30  3:14   ` Randy Dunlap
2020-03-06 13:07 ` [PATCH 5/6] soc: bt1: Add Baikal-T1 APB-bus " Sergey.Semin
2020-03-06 13:07 ` [PATCH 6/6] soc: bt1: Add Baikal-T1 L2-cache Control Block driver Sergey.Semin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.