All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v5 0/4] Add Hardware Spinlock class
@ 2018-11-27 12:49 Benjamin Gaignard
  2018-11-27 12:49 ` [U-Boot] [PATCH v5 1/4] dm: " Benjamin Gaignard
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Benjamin Gaignard @ 2018-11-27 12:49 UTC (permalink / raw)
  To: u-boot

version 5:
- rebased on top of master branch (patches 1 and 4)
  
version 4:
- make timeout loop more robust

version 3:
- use dev_get_parent
- add Review-by
  
version 2:
- use -ETIMEDOUT and -ENOSYS for errors cases
- do not test if ops is valid
- remove useless include
- add a private structure to store base address
- be more verbose in configuration flag description and commit message
- log the error after hwspinlock_get_by_index()

This series add a news class to support hardware spinlock.
Hardware spinlock could be used to protect critical sections of code
between multi-processors.

The proposed API remain simple with only 3 functions to be called client:
- hwspinlock_get_by_index: get a hardware spinlock by integer index from
  device-tree node
- hwspinlock_lock_timeout: lock the hardware spinlock
- hwspinlock_unlock: unlock the hardware spinlock

Driver API offert 4 operations:
- of_xlate: translate a client's device-tree (OF) hardware specifier
- lock: lock the hardware spinlock
- unlock: unlock the hardware spinlock
- relax: wait time between two calls to lock operations


Benjamin Gaignard (4):
  dm: Add Hardware Spinlock class
  clk: stm32: add hardware spinlock clock
  hwspinlock: add stm32 hardware spinlock support
  pinctrl: stm32: make pinctrl use hwspinlock

 arch/arm/dts/stm32mp157c-ed1.dts        |   8 ++
 arch/arm/dts/stm32mp157c.dtsi           |   9 ++
 arch/sandbox/dts/test.dts               |   4 +
 arch/sandbox/include/asm/state.h        |   1 +
 configs/sandbox_defconfig               |   2 +
 configs/stm32mp15_basic_defconfig       |   2 +
 drivers/Kconfig                         |   2 +
 drivers/Makefile                        |   1 +
 drivers/clk/clk_stm32mp1.c              |   3 +
 drivers/hwspinlock/Kconfig              |  24 ++++++
 drivers/hwspinlock/Makefile             |   7 ++
 drivers/hwspinlock/hwspinlock-uclass.c  | 144 ++++++++++++++++++++++++++++++++
 drivers/hwspinlock/sandbox_hwspinlock.c |  56 +++++++++++++
 drivers/hwspinlock/stm32_hwspinlock.c   |  92 ++++++++++++++++++++
 drivers/pinctrl/pinctrl_stm32.c         |  27 +++++-
 include/dm/uclass-id.h                  |   1 +
 include/hwspinlock.h                    | 140 +++++++++++++++++++++++++++++++
 test/dm/Makefile                        |   1 +
 test/dm/hwspinlock.c                    |  40 +++++++++
 19 files changed, 560 insertions(+), 4 deletions(-)
 create mode 100644 drivers/hwspinlock/Kconfig
 create mode 100644 drivers/hwspinlock/Makefile
 create mode 100644 drivers/hwspinlock/hwspinlock-uclass.c
 create mode 100644 drivers/hwspinlock/sandbox_hwspinlock.c
 create mode 100644 drivers/hwspinlock/stm32_hwspinlock.c
 create mode 100644 include/hwspinlock.h
 create mode 100644 test/dm/hwspinlock.c

-- 
2.15.0

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

* [U-Boot] [PATCH v5 1/4] dm: Add Hardware Spinlock class
  2018-11-27 12:49 [U-Boot] [PATCH v5 0/4] Add Hardware Spinlock class Benjamin Gaignard
@ 2018-11-27 12:49 ` Benjamin Gaignard
  2018-12-07 20:33   ` [U-Boot] [U-Boot,v5,1/4] " Tom Rini
  2018-11-27 12:49 ` [U-Boot] [PATCH v5 2/4] clk: stm32: add hardware spinlock clock Benjamin Gaignard
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 9+ messages in thread
From: Benjamin Gaignard @ 2018-11-27 12:49 UTC (permalink / raw)
  To: u-boot

This is uclass for Hardware Spinlocks.
It implements two mandatory operations: lock and unlock
and one optional relax operation.

Signed-off-by: Benjamin Gaignard <benjamin.gaignard@linaro.org>
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Patrice Chotard <patrice.chotard@st.com>
---
version 5
- rebased on top of master branch
  
version 4:
- make timeout loop more robust

 arch/sandbox/dts/test.dts               |   4 +
 arch/sandbox/include/asm/state.h        |   1 +
 configs/sandbox_defconfig               |   2 +
 drivers/Kconfig                         |   2 +
 drivers/Makefile                        |   1 +
 drivers/hwspinlock/Kconfig              |  16 ++++
 drivers/hwspinlock/Makefile             |   6 ++
 drivers/hwspinlock/hwspinlock-uclass.c  | 144 ++++++++++++++++++++++++++++++++
 drivers/hwspinlock/sandbox_hwspinlock.c |  56 +++++++++++++
 include/dm/uclass-id.h                  |   1 +
 include/hwspinlock.h                    | 140 +++++++++++++++++++++++++++++++
 test/dm/Makefile                        |   1 +
 test/dm/hwspinlock.c                    |  40 +++++++++
 13 files changed, 414 insertions(+)
 create mode 100644 drivers/hwspinlock/Kconfig
 create mode 100644 drivers/hwspinlock/Makefile
 create mode 100644 drivers/hwspinlock/hwspinlock-uclass.c
 create mode 100644 drivers/hwspinlock/sandbox_hwspinlock.c
 create mode 100644 include/hwspinlock.h
 create mode 100644 test/dm/hwspinlock.c

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 2c6b422312..c438fa500c 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -731,6 +731,10 @@
 	pinctrl {
 		compatible = "sandbox,pinctrl";
 	};
+
+	hwspinlock at 0 {
+		compatible = "sandbox,hwspinlock";
+	};
 };
 
 #include "sandbox_pmic.dtsi"
diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h
index 8fabe70a86..92c8ab508e 100644
--- a/arch/sandbox/include/asm/state.h
+++ b/arch/sandbox/include/asm/state.h
@@ -100,6 +100,7 @@ struct sandbox_state {
 
 	ulong next_tag;			/* Next address tag to allocate */
 	struct list_head mapmem_head;	/* struct sandbox_mapmem_entry */
+	bool hwspinlock;		/* Hardware Spinlock status */
 };
 
 /* Minimum space we guarantee in the state FDT when calling read/write*/
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 5a744f4791..f4a50d5df3 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -95,6 +95,8 @@ CONFIG_BOARD=y
 CONFIG_BOARD_SANDBOX=y
 CONFIG_PM8916_GPIO=y
 CONFIG_SANDBOX_GPIO=y
+CONFIG_DM_HWSPINLOCK=y
+CONFIG_HWSPINLOCK_SANDBOX=y
 CONFIG_DM_I2C_COMPAT=y
 CONFIG_I2C_CROS_EC_TUNNEL=y
 CONFIG_I2C_CROS_EC_LDO=y
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 4ac823d962..e9fbadd13d 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -40,6 +40,8 @@ source "drivers/fpga/Kconfig"
 
 source "drivers/gpio/Kconfig"
 
+source "drivers/hwspinlock/Kconfig"
+
 source "drivers/i2c/Kconfig"
 
 source "drivers/input/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 55de10926e..c425831b58 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -113,4 +113,5 @@ obj-$(CONFIG_W1) += w1/
 obj-$(CONFIG_W1_EEPROM) += w1-eeprom/
 
 obj-$(CONFIG_MACH_PIC32) += ddr/microchip/
+obj-$(CONFIG_DM_HWSPINLOCK) += hwspinlock/
 endif
diff --git a/drivers/hwspinlock/Kconfig b/drivers/hwspinlock/Kconfig
new file mode 100644
index 0000000000..de367fd2a9
--- /dev/null
+++ b/drivers/hwspinlock/Kconfig
@@ -0,0 +1,16 @@
+menu "Hardware Spinlock Support"
+
+config DM_HWSPINLOCK
+	bool "Enable U-Boot hardware spinlock support"
+	help
+	  This option enables U-Boot hardware spinlock support
+
+config HWSPINLOCK_SANDBOX
+	bool "Enable Hardware Spinlock support for Sandbox"
+	depends on SANDBOX && DM_HWSPINLOCK
+	help
+	  Enable hardware spinlock support in Sandbox. This is a dummy device that
+	  can be probed and support all the methods of HWSPINLOCK, but does not
+	  really do anything.
+
+endmenu
diff --git a/drivers/hwspinlock/Makefile b/drivers/hwspinlock/Makefile
new file mode 100644
index 0000000000..2704d6814f
--- /dev/null
+++ b/drivers/hwspinlock/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+#
+# Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+
+obj-$(CONFIG_DM_HWSPINLOCK) += hwspinlock-uclass.o
+obj-$(CONFIG_HWSPINLOCK_SANDBOX) += sandbox_hwspinlock.o
diff --git a/drivers/hwspinlock/hwspinlock-uclass.c b/drivers/hwspinlock/hwspinlock-uclass.c
new file mode 100644
index 0000000000..195f079707
--- /dev/null
+++ b/drivers/hwspinlock/hwspinlock-uclass.c
@@ -0,0 +1,144 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <hwspinlock.h>
+#include <dm/device-internal.h>
+
+static inline const struct hwspinlock_ops *
+hwspinlock_dev_ops(struct udevice *dev)
+{
+	return (const struct hwspinlock_ops *)dev->driver->ops;
+}
+
+static int hwspinlock_of_xlate_default(struct hwspinlock *hws,
+				       struct ofnode_phandle_args *args)
+{
+	if (args->args_count > 1) {
+		debug("Invaild args_count: %d\n", args->args_count);
+		return -EINVAL;
+	}
+
+	if (args->args_count)
+		hws->id = args->args[0];
+	else
+		hws->id = 0;
+
+	return 0;
+}
+
+int hwspinlock_get_by_index(struct udevice *dev, int index,
+			    struct hwspinlock *hws)
+{
+	int ret;
+	struct ofnode_phandle_args args;
+	struct udevice *dev_hws;
+	const struct hwspinlock_ops *ops;
+
+	assert(hws);
+	hws->dev = NULL;
+
+	ret = dev_read_phandle_with_args(dev, "hwlocks", "#hwlock-cells", 1,
+					 index, &args);
+	if (ret) {
+		dev_dbg(dev, "%s: dev_read_phandle_with_args: err=%d\n",
+			__func__, ret);
+		return ret;
+	}
+
+	ret = uclass_get_device_by_ofnode(UCLASS_HWSPINLOCK,
+					  args.node, &dev_hws);
+	if (ret) {
+		dev_dbg(dev,
+			"%s: uclass_get_device_by_of_offset failed: err=%d\n",
+			__func__, ret);
+		return ret;
+	}
+
+	hws->dev = dev_hws;
+
+	ops = hwspinlock_dev_ops(dev_hws);
+
+	if (ops->of_xlate)
+		ret = ops->of_xlate(hws, &args);
+	else
+		ret = hwspinlock_of_xlate_default(hws, &args);
+	if (ret)
+		dev_dbg(dev, "of_xlate() failed: %d\n", ret);
+
+	return ret;
+}
+
+int hwspinlock_lock_timeout(struct hwspinlock *hws, unsigned int timeout)
+{
+	const struct hwspinlock_ops *ops;
+	ulong start;
+	int ret;
+
+	assert(hws);
+
+	if (!hws->dev)
+		return -EINVAL;
+
+	ops = hwspinlock_dev_ops(hws->dev);
+	if (!ops->lock)
+		return -ENOSYS;
+
+	start = get_timer(0);
+	do {
+		ret = ops->lock(hws->dev, hws->id);
+		if (!ret)
+			return ret;
+
+		if (ops->relax)
+			ops->relax(hws->dev);
+	} while (get_timer(start) < timeout);
+
+	return -ETIMEDOUT;
+}
+
+int hwspinlock_unlock(struct hwspinlock *hws)
+{
+	const struct hwspinlock_ops *ops;
+
+	assert(hws);
+
+	if (!hws->dev)
+		return -EINVAL;
+
+	ops = hwspinlock_dev_ops(hws->dev);
+	if (!ops->unlock)
+		return -ENOSYS;
+
+	return ops->unlock(hws->dev, hws->id);
+}
+
+static int hwspinlock_post_bind(struct udevice *dev)
+{
+#if defined(CONFIG_NEEDS_MANUAL_RELOC)
+	struct hwspinlock_ops *ops = device_get_ops(dev);
+	static int reloc_done;
+
+	if (!reloc_done) {
+		if (ops->lock)
+			ops->lock += gd->reloc_off;
+		if (ops->unlock)
+			ops->unlock += gd->reloc_off;
+		if (ops->relax)
+			ops->relax += gd->reloc_off;
+
+		reloc_done++;
+	}
+#endif
+	return 0;
+}
+
+UCLASS_DRIVER(hwspinlock) = {
+	.id		= UCLASS_HWSPINLOCK,
+	.name		= "hwspinlock",
+	.post_bind	= hwspinlock_post_bind,
+};
diff --git a/drivers/hwspinlock/sandbox_hwspinlock.c b/drivers/hwspinlock/sandbox_hwspinlock.c
new file mode 100644
index 0000000000..be920f5f99
--- /dev/null
+++ b/drivers/hwspinlock/sandbox_hwspinlock.c
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <hwspinlock.h>
+#include <asm/state.h>
+
+static int sandbox_lock(struct udevice *dev, int index)
+{
+	struct sandbox_state *state = state_get_current();
+
+	if (index != 0)
+		return -1;
+
+	if (state->hwspinlock)
+		return -1;
+
+	state->hwspinlock = true;
+
+	return 0;
+}
+
+static int sandbox_unlock(struct udevice *dev, int index)
+{
+	struct sandbox_state *state = state_get_current();
+
+	if (index != 0)
+		return -1;
+
+	if (!state->hwspinlock)
+		return -1;
+
+	state->hwspinlock = false;
+
+	return 0;
+}
+
+static const struct hwspinlock_ops sandbox_hwspinlock_ops = {
+	.lock = sandbox_lock,
+	.unlock = sandbox_unlock,
+};
+
+static const struct udevice_id sandbox_hwspinlock_ids[] = {
+	{ .compatible = "sandbox,hwspinlock" },
+	{}
+};
+
+U_BOOT_DRIVER(hwspinlock_sandbox) = {
+	.name = "hwspinlock_sandbox",
+	.id = UCLASS_HWSPINLOCK,
+	.of_match = sandbox_hwspinlock_ids,
+	.ops = &sandbox_hwspinlock_ops,
+};
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index c91dca1f82..d0df2b505a 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -40,6 +40,7 @@ enum uclass_id {
 	UCLASS_ETH,		/* Ethernet device */
 	UCLASS_FS_FIRMWARE_LOADER,		/* Generic loader */
 	UCLASS_GPIO,		/* Bank of general-purpose I/O pins */
+	UCLASS_HWSPINLOCK,	/* Hardware semaphores */
 	UCLASS_FIRMWARE,	/* Firmware */
 	UCLASS_I2C,		/* I2C bus */
 	UCLASS_I2C_EEPROM,	/* I2C EEPROM device */
diff --git a/include/hwspinlock.h b/include/hwspinlock.h
new file mode 100644
index 0000000000..99389c13c2
--- /dev/null
+++ b/include/hwspinlock.h
@@ -0,0 +1,140 @@
+/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
+/*
+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ */
+
+#ifndef _HWSPINLOCK_H_
+#define _HWSPINLOCK_H_
+
+/**
+ * Implement a hwspinlock uclass.
+ * Hardware spinlocks are used to perform hardware protection of
+ * critical sections and synchronisation between multiprocessors.
+ */
+
+struct udevice;
+
+/**
+ * struct hwspinlock - A handle to (allowing control of) a single hardware
+ * spinlock.
+ *
+ * @dev: The device which implements the hardware spinlock.
+ * @id: The hardware spinlock ID within the provider.
+ */
+struct hwspinlock {
+	struct udevice *dev;
+	unsigned long id;
+};
+
+#if CONFIG_IS_ENABLED(DM_HWSPINLOCK)
+
+/**
+ * hwspinlock_get_by_index - Get a hardware spinlock by integer index
+ *
+ * This looks up and request a hardware spinlock. The index is relative to the
+ * client device; each device is assumed to have n hardware spinlock associated
+ * with it somehow, and this function finds and requests one of them.
+ *
+ * @dev:	The client device.
+ * @index:	The index of the hardware spinlock to request, within the
+ *		client's list of hardware spinlock.
+ * @hws:	A pointer to a hardware spinlock struct to initialize.
+ * @return 0 if OK, or a negative error code.
+ */
+int hwspinlock_get_by_index(struct udevice *dev,
+			    int index, struct hwspinlock *hws);
+
+/**
+ * Lock the hardware spinlock
+ *
+ * @hws:	A hardware spinlock struct that previously requested by
+ *		hwspinlock_get_by_index
+ * @timeout:	Timeout value in msecs
+ * @return: 0 if OK, -ETIMEDOUT if timeout, -ve on other errors
+ */
+int hwspinlock_lock_timeout(struct hwspinlock *hws, unsigned int timeout);
+
+/**
+ * Unlock the hardware spinlock
+ *
+ * @hws:	A hardware spinlock struct that previously requested by
+ *		hwspinlock_get_by_index
+ * @return: 0 if OK, -ve on error
+ */
+int hwspinlock_unlock(struct hwspinlock *hws);
+
+#else
+
+static inline int hwspinlock_get_by_index(struct udevice *dev,
+					  int index,
+					  struct hwspinlock *hws)
+{
+	return -ENOSYS;
+}
+
+static inline int hwspinlock_lock_timeout(struct hwspinlock *hws,
+					  int timeout)
+{
+	return -ENOSYS;
+}
+
+static inline int hwspinlock_unlock(struct hwspinlock *hws)
+{
+	return -ENOSYS;
+}
+
+#endif /* CONFIG_DM_HWSPINLOCK */
+
+struct ofnode_phandle_args;
+
+/**
+ * struct hwspinlock_ops - Driver model hwspinlock operations
+ *
+ * The uclass interface is implemented by all hwspinlock devices which use
+ * driver model.
+ */
+struct hwspinlock_ops {
+	/**
+	 * of_xlate - Translate a client's device-tree (OF) hardware specifier.
+	 *
+	 * The hardware core calls this function as the first step in
+	 * implementing a client's hwspinlock_get_by_*() call.
+	 *
+	 * @hws:	The hardware spinlock struct to hold the translation
+	 *			result.
+	 * @args:	The hardware spinlock specifier values from device tree.
+	 * @return 0 if OK, or a negative error code.
+	 */
+	int (*of_xlate)(struct hwspinlock *hws,
+			struct ofnode_phandle_args *args);
+
+	/**
+	 * Lock the hardware spinlock
+	 *
+	 * @dev:	hwspinlock Device
+	 * @index:	index of the lock to be used
+	 * @return 0 if OK, -ve on error
+	 */
+	int (*lock)(struct udevice *dev, int index);
+
+	/**
+	 * Unlock the hardware spinlock
+	 *
+	 * @dev:	hwspinlock Device
+	 * @index:	index of the lock to be unlocked
+	 * @return 0 if OK, -ve on error
+	 */
+	int (*unlock)(struct udevice *dev, int index);
+
+	/**
+	 * Relax - optional
+	 *       Platform-specific relax method, called by hwspinlock core
+	 *       while spinning on a lock, between two successive call to
+	 *       lock
+	 *
+	 * @dev:	hwspinlock Device
+	 */
+	void (*relax)(struct udevice *dev);
+};
+
+#endif /* _HWSPINLOCK_H_ */
diff --git a/test/dm/Makefile b/test/dm/Makefile
index 213e0fda94..7355fe18e2 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_CLK) += clk.o
 obj-$(CONFIG_DM_ETH) += eth.o
 obj-$(CONFIG_FIRMWARE) += firmware.o
 obj-$(CONFIG_DM_GPIO) += gpio.o
+obj-$(CONFIG_DM_HWSPINLOCK) += hwspinlock.o
 obj-$(CONFIG_DM_I2C) += i2c.o
 obj-$(CONFIG_LED) += led.o
 obj-$(CONFIG_DM_MAILBOX) += mailbox.o
diff --git a/test/dm/hwspinlock.c b/test/dm/hwspinlock.c
new file mode 100644
index 0000000000..09ec38b4f3
--- /dev/null
+++ b/test/dm/hwspinlock.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <hwspinlock.h>
+#include <asm/state.h>
+#include <asm/test.h>
+#include <dm/test.h>
+#include <test/ut.h>
+
+/* Test that hwspinlock driver functions are called */
+static int dm_test_hwspinlock_base(struct unit_test_state *uts)
+{
+	struct sandbox_state *state = state_get_current();
+	struct hwspinlock hws;
+
+	ut_assertok(uclass_get_device(UCLASS_HWSPINLOCK, 0, &hws.dev));
+	ut_assertnonnull(hws.dev);
+	ut_asserteq(false, state->hwspinlock);
+
+	hws.id = 0;
+	ut_assertok(hwspinlock_lock_timeout(&hws, 1));
+	ut_asserteq(true, state->hwspinlock);
+
+	ut_assertok(hwspinlock_unlock(&hws));
+	ut_asserteq(false, state->hwspinlock);
+
+	ut_assertok(hwspinlock_lock_timeout(&hws, 1));
+	ut_assertok(!hwspinlock_lock_timeout(&hws, 1));
+
+	ut_assertok(hwspinlock_unlock(&hws));
+	ut_assertok(!hwspinlock_unlock(&hws));
+
+	return 0;
+}
+
+DM_TEST(dm_test_hwspinlock_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
-- 
2.15.0

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

* [U-Boot] [PATCH v5 2/4] clk: stm32: add hardware spinlock clock
  2018-11-27 12:49 [U-Boot] [PATCH v5 0/4] Add Hardware Spinlock class Benjamin Gaignard
  2018-11-27 12:49 ` [U-Boot] [PATCH v5 1/4] dm: " Benjamin Gaignard
@ 2018-11-27 12:49 ` Benjamin Gaignard
  2018-12-07 20:33   ` [U-Boot] [U-Boot, v5, " Tom Rini
  2018-11-27 12:49 ` [U-Boot] [PATCH v5 3/4] hwspinlock: add stm32 hardware spinlock support Benjamin Gaignard
  2018-11-27 12:49 ` [U-Boot] [PATCH v5 4/4] pinctrl: stm32: make pinctrl use hwspinlock Benjamin Gaignard
  3 siblings, 1 reply; 9+ messages in thread
From: Benjamin Gaignard @ 2018-11-27 12:49 UTC (permalink / raw)
  To: u-boot

From: Benjamin Gaignard <benjamin.gaignard@linaro.org>

Add hardware spinlock in the list of the clocks.

Signed-off-by: Benjamin Gaignard <benjamin.gaignard@linaro.org>
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Patrice Chotard <patrice.chotard@st.com>
---
 drivers/clk/clk_stm32mp1.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/clk/clk_stm32mp1.c b/drivers/clk/clk_stm32mp1.c
index 6a8c7b754f..b7c5d34fe0 100644
--- a/drivers/clk/clk_stm32mp1.c
+++ b/drivers/clk/clk_stm32mp1.c
@@ -104,6 +104,7 @@
 #define RCC_MP_APB2ENSETR	0XA08
 #define RCC_MP_APB3ENSETR	0xA10
 #define RCC_MP_AHB2ENSETR	0xA18
+#define RCC_MP_AHB3ENSETR	0xA20
 #define RCC_MP_AHB4ENSETR	0xA28
 
 /* used for most of SELR register */
@@ -534,6 +535,8 @@ static const struct stm32mp1_clk_gate stm32mp1_clk_gate[] = {
 	STM32MP1_CLK_SET_CLR(RCC_MP_AHB2ENSETR, 8, USBO_K, _USBO_SEL),
 	STM32MP1_CLK_SET_CLR(RCC_MP_AHB2ENSETR, 16, SDMMC3_K, _SDMMC3_SEL),
 
+	STM32MP1_CLK_SET_CLR(RCC_MP_AHB3ENSETR, 11, HSEM, _UNKNOWN_SEL),
+
 	STM32MP1_CLK_SET_CLR(RCC_MP_AHB4ENSETR, 0, GPIOA, _UNKNOWN_SEL),
 	STM32MP1_CLK_SET_CLR(RCC_MP_AHB4ENSETR, 1, GPIOB, _UNKNOWN_SEL),
 	STM32MP1_CLK_SET_CLR(RCC_MP_AHB4ENSETR, 2, GPIOC, _UNKNOWN_SEL),
-- 
2.15.0

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

* [U-Boot] [PATCH v5 3/4] hwspinlock: add stm32 hardware spinlock support
  2018-11-27 12:49 [U-Boot] [PATCH v5 0/4] Add Hardware Spinlock class Benjamin Gaignard
  2018-11-27 12:49 ` [U-Boot] [PATCH v5 1/4] dm: " Benjamin Gaignard
  2018-11-27 12:49 ` [U-Boot] [PATCH v5 2/4] clk: stm32: add hardware spinlock clock Benjamin Gaignard
@ 2018-11-27 12:49 ` Benjamin Gaignard
  2018-12-07 20:33   ` [U-Boot] [U-Boot, v5, " Tom Rini
  2018-11-27 12:49 ` [U-Boot] [PATCH v5 4/4] pinctrl: stm32: make pinctrl use hwspinlock Benjamin Gaignard
  3 siblings, 1 reply; 9+ messages in thread
From: Benjamin Gaignard @ 2018-11-27 12:49 UTC (permalink / raw)
  To: u-boot

Implement hardware spinlock support for STM32MP1.

Signed-off-by: Benjamin Gaignard <benjamin.gaignard@st.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Patrice Chotard <patrice.chotard@st.com>
---
 arch/arm/dts/stm32mp157c-ed1.dts      |  4 ++
 arch/arm/dts/stm32mp157c.dtsi         |  9 ++++
 configs/stm32mp15_basic_defconfig     |  2 +
 drivers/hwspinlock/Kconfig            |  8 +++
 drivers/hwspinlock/Makefile           |  1 +
 drivers/hwspinlock/stm32_hwspinlock.c | 92 +++++++++++++++++++++++++++++++++++
 6 files changed, 116 insertions(+)
 create mode 100644 drivers/hwspinlock/stm32_hwspinlock.c

diff --git a/arch/arm/dts/stm32mp157c-ed1.dts b/arch/arm/dts/stm32mp157c-ed1.dts
index f8b7701167..fc277dd7d2 100644
--- a/arch/arm/dts/stm32mp157c-ed1.dts
+++ b/arch/arm/dts/stm32mp157c-ed1.dts
@@ -365,6 +365,10 @@
 	usb33d-supply = <&usb33>;
 };
 
+&hwspinlock {
+	status = "okay";
+};
+
 &usbphyc_port0 {
 	phy-supply = <&vdd_usb>;
 	vdda1v1-supply = <&reg11>;
diff --git a/arch/arm/dts/stm32mp157c.dtsi b/arch/arm/dts/stm32mp157c.dtsi
index 33c5981869..37cadfa30c 100644
--- a/arch/arm/dts/stm32mp157c.dtsi
+++ b/arch/arm/dts/stm32mp157c.dtsi
@@ -690,6 +690,15 @@
 			status = "disabled";
 		};
 
+		hwspinlock: hwspinlock at 4c000000 {
+			compatible = "st,stm32-hwspinlock";
+			#hwlock-cells = <1>;
+			reg = <0x4c000000 0x400>;
+			clocks = <&rcc HSEM>;
+			clock-names = "hwspinlock";
+			status = "disabled";
+		};
+
 		rcc: rcc at 50000000 {
 			compatible = "st,stm32mp1-rcc", "syscon";
 			reg = <0x50000000 0x1000>;
diff --git a/configs/stm32mp15_basic_defconfig b/configs/stm32mp15_basic_defconfig
index 3bf7538089..c8409fd04e 100644
--- a/configs/stm32mp15_basic_defconfig
+++ b/configs/stm32mp15_basic_defconfig
@@ -32,6 +32,8 @@ CONFIG_CMD_EXT4_WRITE=y
 # CONFIG_SPL_DOS_PARTITION is not set
 CONFIG_DEFAULT_DEVICE_TREE="stm32mp157c-ev1"
 CONFIG_STM32_ADC=y
+CONFIG_DM_HWSPINLOCK=y
+CONFIG_HWSPINLOCK_STM32=y
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_STM32F7=y
 CONFIG_LED=y
diff --git a/drivers/hwspinlock/Kconfig b/drivers/hwspinlock/Kconfig
index de367fd2a9..96d4f5d6ca 100644
--- a/drivers/hwspinlock/Kconfig
+++ b/drivers/hwspinlock/Kconfig
@@ -13,4 +13,12 @@ config HWSPINLOCK_SANDBOX
 	  can be probed and support all the methods of HWSPINLOCK, but does not
 	  really do anything.
 
+config HWSPINLOCK_STM32
+	bool "Enable Hardware Spinlock support for STM32"
+	depends on ARCH_STM32MP && DM_HWSPINLOCK
+	help
+	  Enable hardware spinlock support in STM32MP. Hardware spinlocks are
+	  hardware mutex which provide a synchronisation mechanism for the
+	  various processors on the SoC.
+
 endmenu
diff --git a/drivers/hwspinlock/Makefile b/drivers/hwspinlock/Makefile
index 2704d6814f..289b12a256 100644
--- a/drivers/hwspinlock/Makefile
+++ b/drivers/hwspinlock/Makefile
@@ -4,3 +4,4 @@
 
 obj-$(CONFIG_DM_HWSPINLOCK) += hwspinlock-uclass.o
 obj-$(CONFIG_HWSPINLOCK_SANDBOX) += sandbox_hwspinlock.o
+obj-$(CONFIG_HWSPINLOCK_STM32) += stm32_hwspinlock.o
diff --git a/drivers/hwspinlock/stm32_hwspinlock.c b/drivers/hwspinlock/stm32_hwspinlock.c
new file mode 100644
index 0000000000..a32bde4906
--- /dev/null
+++ b/drivers/hwspinlock/stm32_hwspinlock.c
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <hwspinlock.h>
+#include <asm/io.h>
+
+#define STM32_MUTEX_COREID	BIT(8)
+#define STM32_MUTEX_LOCK_BIT	BIT(31)
+#define STM32_MUTEX_NUM_LOCKS	32
+
+struct stm32mp1_hws_priv {
+	fdt_addr_t base;
+};
+
+static int stm32mp1_lock(struct udevice *dev, int index)
+{
+	struct stm32mp1_hws_priv *priv = dev_get_priv(dev);
+	u32 status;
+
+	if (index >= STM32_MUTEX_NUM_LOCKS)
+		return -EINVAL;
+
+	status = readl(priv->base + index * sizeof(u32));
+	if (status == (STM32_MUTEX_LOCK_BIT | STM32_MUTEX_COREID))
+		return -EBUSY;
+
+	writel(STM32_MUTEX_LOCK_BIT | STM32_MUTEX_COREID,
+	       priv->base + index * sizeof(u32));
+
+	status = readl(priv->base + index * sizeof(u32));
+	if (status != (STM32_MUTEX_LOCK_BIT | STM32_MUTEX_COREID))
+		return -EINVAL;
+
+	return 0;
+}
+
+static int stm32mp1_unlock(struct udevice *dev, int index)
+{
+	struct stm32mp1_hws_priv *priv = dev_get_priv(dev);
+
+	if (index >= STM32_MUTEX_NUM_LOCKS)
+		return -EINVAL;
+
+	writel(STM32_MUTEX_COREID, priv->base + index * sizeof(u32));
+
+	return 0;
+}
+
+static int stm32mp1_hwspinlock_probe(struct udevice *dev)
+{
+	struct stm32mp1_hws_priv *priv = dev_get_priv(dev);
+	struct clk clk;
+	int ret;
+
+	priv->base = dev_read_addr(dev);
+	if (priv->base == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	ret = clk_get_by_index(dev, 0, &clk);
+	if (ret)
+		return ret;
+
+	ret = clk_enable(&clk);
+	if (ret)
+		clk_free(&clk);
+
+	return ret;
+}
+
+static const struct hwspinlock_ops stm32mp1_hwspinlock_ops = {
+	.lock = stm32mp1_lock,
+	.unlock = stm32mp1_unlock,
+};
+
+static const struct udevice_id stm32mp1_hwspinlock_ids[] = {
+	{ .compatible = "st,stm32-hwspinlock" },
+	{}
+};
+
+U_BOOT_DRIVER(hwspinlock_stm32mp1) = {
+	.name = "hwspinlock_stm32mp1",
+	.id = UCLASS_HWSPINLOCK,
+	.of_match = stm32mp1_hwspinlock_ids,
+	.ops = &stm32mp1_hwspinlock_ops,
+	.probe = stm32mp1_hwspinlock_probe,
+	.priv_auto_alloc_size = sizeof(struct stm32mp1_hws_priv),
+};
-- 
2.15.0

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

* [U-Boot] [PATCH v5 4/4] pinctrl: stm32: make pinctrl use hwspinlock
  2018-11-27 12:49 [U-Boot] [PATCH v5 0/4] Add Hardware Spinlock class Benjamin Gaignard
                   ` (2 preceding siblings ...)
  2018-11-27 12:49 ` [U-Boot] [PATCH v5 3/4] hwspinlock: add stm32 hardware spinlock support Benjamin Gaignard
@ 2018-11-27 12:49 ` Benjamin Gaignard
  2018-12-07 20:33   ` [U-Boot] [U-Boot, v5, " Tom Rini
  3 siblings, 1 reply; 9+ messages in thread
From: Benjamin Gaignard @ 2018-11-27 12:49 UTC (permalink / raw)
  To: u-boot

Protect configuration registers with a hardware spinlock.

If a hwspinlock is defined in the device-tree node used it
to be sure that none of the others processors on the SoC could
change the configuration at the same time.

Signed-off-by: Benjamin Gaignard <benjamin.gaignard@linaro.org>
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Patrice Chotard <patrice.chotard@st.com>
---
version 5:
²- rebased on top of master branch
 arch/arm/dts/stm32mp157c-ed1.dts |  4 ++++
 drivers/pinctrl/pinctrl_stm32.c  | 27 +++++++++++++++++++++++----
 2 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/arch/arm/dts/stm32mp157c-ed1.dts b/arch/arm/dts/stm32mp157c-ed1.dts
index fc277dd7d2..7a9b742d36 100644
--- a/arch/arm/dts/stm32mp157c-ed1.dts
+++ b/arch/arm/dts/stm32mp157c-ed1.dts
@@ -369,6 +369,10 @@
 	status = "okay";
 };
 
+&pinctrl {
+	hwlocks = <&hwspinlock 0>;
+};
+
 &usbphyc_port0 {
 	phy-supply = <&vdd_usb>;
 	vdda1v1-supply = <&reg11>;
diff --git a/drivers/pinctrl/pinctrl_stm32.c b/drivers/pinctrl/pinctrl_stm32.c
index 6d4117d941..bb63da3739 100644
--- a/drivers/pinctrl/pinctrl_stm32.c
+++ b/drivers/pinctrl/pinctrl_stm32.c
@@ -1,6 +1,7 @@
 #include <common.h>
 #include <dm.h>
 #include <dm/pinctrl.h>
+#include <hwspinlock.h>
 #include <asm/arch/gpio.h>
 #include <asm/gpio.h>
 #include <asm/io.h>
@@ -14,8 +15,8 @@ DECLARE_GLOBAL_DATA_PTR;
 #define OTYPE_MSK			1
 #define AFR_MASK			0xF
 
-#ifndef CONFIG_SPL_BUILD
 struct stm32_pinctrl_priv {
+	struct hwspinlock hws;
 	int pinctrl_ngpios;
 	struct list_head gpio_dev;
 };
@@ -25,6 +26,8 @@ struct stm32_gpio_bank {
 	struct list_head list;
 };
 
+#ifndef CONFIG_SPL_BUILD
+
 #define MAX_PIN_PER_BANK		16
 
 static char pin_name[PINNAME_SIZE];
@@ -166,6 +169,8 @@ static int stm32_pinctrl_get_pin_muxing(struct udevice *dev,
 	return 0;
 }
 
+#endif
+
 int stm32_pinctrl_probe(struct udevice *dev)
 {
 	struct stm32_pinctrl_priv *priv = dev_get_priv(dev);
@@ -198,21 +203,35 @@ int stm32_pinctrl_probe(struct udevice *dev)
 		list_add_tail(&gpio_bank->list, &priv->gpio_dev);
 	}
 
+	/* hwspinlock property is optional, just log the error */
+	ret = hwspinlock_get_by_index(dev, 0, &priv->hws);
+	if (ret)
+		debug("%s: hwspinlock_get_by_index may have failed (%d)\n",
+		      __func__, ret);
+
 	return 0;
 }
-#endif
 
 static int stm32_gpio_config(struct gpio_desc *desc,
 			     const struct stm32_gpio_ctl *ctl)
 {
 	struct stm32_gpio_priv *priv = dev_get_priv(desc->dev);
 	struct stm32_gpio_regs *regs = priv->regs;
+	struct stm32_pinctrl_priv *ctrl_priv;
+	int ret;
 	u32 index;
 
 	if (!ctl || ctl->af > 15 || ctl->mode > 3 || ctl->otype > 1 ||
 	    ctl->pupd > 2 || ctl->speed > 3)
 		return -EINVAL;
 
+	ctrl_priv = dev_get_priv(dev_get_parent(desc->dev));
+	ret = hwspinlock_lock_timeout(&ctrl_priv->hws, 10);
+	if (ret == -ETIME) {
+		dev_err(desc->dev, "HWSpinlock timeout\n");
+		return ret;
+	}
+
 	index = (desc->offset & 0x07) * 4;
 	clrsetbits_le32(&regs->afr[desc->offset >> 3], AFR_MASK << index,
 			ctl->af << index);
@@ -227,6 +246,8 @@ static int stm32_gpio_config(struct gpio_desc *desc,
 	index = desc->offset;
 	clrsetbits_le32(&regs->otyper, OTYPE_MSK << index, ctl->otype << index);
 
+	hwspinlock_unlock(&ctrl_priv->hws);
+
 	return 0;
 }
 
@@ -393,8 +414,6 @@ U_BOOT_DRIVER(pinctrl_stm32) = {
 	.of_match		= stm32_pinctrl_ids,
 	.ops			= &stm32_pinctrl_ops,
 	.bind			= dm_scan_fdt_dev,
-#ifndef CONFIG_SPL_BUILD
 	.probe			= stm32_pinctrl_probe,
 	.priv_auto_alloc_size	= sizeof(struct stm32_pinctrl_priv),
-#endif
 };
-- 
2.15.0

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

* [U-Boot] [U-Boot,v5,1/4] dm: Add Hardware Spinlock class
  2018-11-27 12:49 ` [U-Boot] [PATCH v5 1/4] dm: " Benjamin Gaignard
@ 2018-12-07 20:33   ` Tom Rini
  0 siblings, 0 replies; 9+ messages in thread
From: Tom Rini @ 2018-12-07 20:33 UTC (permalink / raw)
  To: u-boot

On Tue, Nov 27, 2018 at 01:49:50PM +0100, Benjamin Gaignard wrote:

> This is uclass for Hardware Spinlocks.
> It implements two mandatory operations: lock and unlock
> and one optional relax operation.
> 
> Signed-off-by: Benjamin Gaignard <benjamin.gaignard@linaro.org>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Patrice Chotard <patrice.chotard@st.com>

Applied to u-boot/master, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20181207/7e2cab2d/attachment.sig>

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

* [U-Boot] [U-Boot, v5, 2/4] clk: stm32: add hardware spinlock clock
  2018-11-27 12:49 ` [U-Boot] [PATCH v5 2/4] clk: stm32: add hardware spinlock clock Benjamin Gaignard
@ 2018-12-07 20:33   ` Tom Rini
  0 siblings, 0 replies; 9+ messages in thread
From: Tom Rini @ 2018-12-07 20:33 UTC (permalink / raw)
  To: u-boot

On Tue, Nov 27, 2018 at 01:49:51PM +0100, Benjamin Gaignard wrote:

> From: Benjamin Gaignard <benjamin.gaignard@linaro.org>
> 
> Add hardware spinlock in the list of the clocks.
> 
> Signed-off-by: Benjamin Gaignard <benjamin.gaignard@linaro.org>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Patrice Chotard <patrice.chotard@st.com>

Applied to u-boot/master, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20181207/7ad9d2f2/attachment.sig>

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

* [U-Boot] [U-Boot, v5, 3/4] hwspinlock: add stm32 hardware spinlock support
  2018-11-27 12:49 ` [U-Boot] [PATCH v5 3/4] hwspinlock: add stm32 hardware spinlock support Benjamin Gaignard
@ 2018-12-07 20:33   ` Tom Rini
  0 siblings, 0 replies; 9+ messages in thread
From: Tom Rini @ 2018-12-07 20:33 UTC (permalink / raw)
  To: u-boot

On Tue, Nov 27, 2018 at 01:49:52PM +0100, Benjamin Gaignard wrote:

> Implement hardware spinlock support for STM32MP1.
> 
> Signed-off-by: Benjamin Gaignard <benjamin.gaignard@st.com>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Patrice Chotard <patrice.chotard@st.com>

Applied to u-boot/master, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20181207/47483ba0/attachment.sig>

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

* [U-Boot] [U-Boot, v5, 4/4] pinctrl: stm32: make pinctrl use hwspinlock
  2018-11-27 12:49 ` [U-Boot] [PATCH v5 4/4] pinctrl: stm32: make pinctrl use hwspinlock Benjamin Gaignard
@ 2018-12-07 20:33   ` Tom Rini
  0 siblings, 0 replies; 9+ messages in thread
From: Tom Rini @ 2018-12-07 20:33 UTC (permalink / raw)
  To: u-boot

On Tue, Nov 27, 2018 at 01:49:53PM +0100, Benjamin Gaignard wrote:

> Protect configuration registers with a hardware spinlock.
> 
> If a hwspinlock is defined in the device-tree node used it
> to be sure that none of the others processors on the SoC could
> change the configuration at the same time.
> 
> Signed-off-by: Benjamin Gaignard <benjamin.gaignard@linaro.org>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Patrice Chotard <patrice.chotard@st.com>

Applied to u-boot/master, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20181207/29fc2201/attachment.sig>

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

end of thread, other threads:[~2018-12-07 20:33 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-27 12:49 [U-Boot] [PATCH v5 0/4] Add Hardware Spinlock class Benjamin Gaignard
2018-11-27 12:49 ` [U-Boot] [PATCH v5 1/4] dm: " Benjamin Gaignard
2018-12-07 20:33   ` [U-Boot] [U-Boot,v5,1/4] " Tom Rini
2018-11-27 12:49 ` [U-Boot] [PATCH v5 2/4] clk: stm32: add hardware spinlock clock Benjamin Gaignard
2018-12-07 20:33   ` [U-Boot] [U-Boot, v5, " Tom Rini
2018-11-27 12:49 ` [U-Boot] [PATCH v5 3/4] hwspinlock: add stm32 hardware spinlock support Benjamin Gaignard
2018-12-07 20:33   ` [U-Boot] [U-Boot, v5, " Tom Rini
2018-11-27 12:49 ` [U-Boot] [PATCH v5 4/4] pinctrl: stm32: make pinctrl use hwspinlock Benjamin Gaignard
2018-12-07 20:33   ` [U-Boot] [U-Boot, v5, " Tom Rini

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.