
Hi Benjamin
On 11/14/18 10:01 AM, Benjamin Gaignard wrote:
Implement hardware spinlock support for STM32MP1.
Signed-off-by: Benjamin Gaignard benjamin.gaignard@st.com
version 2:
- remove useless include
- add a private structure to store base address
- be more verbose in configuration flag description
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 = <®11>; 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@4c000000 {
compatible = "st,stm32-hwspinlock";
#hwlock-cells = <1>;
reg = <0x4c000000 0x400>;
clocks = <&rcc HSEM>;
clock-names = "hwspinlock";
status = "disabled";
};
- rcc: rcc@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),
+};
Reviewed-by: Patrice Chotard patrice.chotard@st.com
Thanks