
Hi Benjamin,
On 13 November 2018 at 01:51, Benjamin Gaignard benjamin.gaignard@linaro.org wrote:
Implement hardware spinlock support for STM32MP1.
Signed-off-by: Benjamin Gaignard benjamin.gaignard@st.com
arch/arm/dts/stm32mp157c-ed1.dts | 4 ++ arch/arm/dts/stm32mp157c.dtsi | 9 ++++ configs/stm32mp15_basic_defconfig | 2 + drivers/hwspinlock/Kconfig | 6 +++ drivers/hwspinlock/Makefile | 1 + drivers/hwspinlock/stm32_hwspinlock.c | 90 +++++++++++++++++++++++++++++++++++ 6 files changed, 112 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..f28d582bb2 100644 --- a/drivers/hwspinlock/Kconfig +++ b/drivers/hwspinlock/Kconfig @@ -13,4 +13,10 @@ 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.
Please add more detail here - what is it used for and how does it work?
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..b8f3b1632f --- /dev/null +++ b/drivers/hwspinlock/stm32_hwspinlock.c @@ -0,0 +1,90 @@ +// 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 <fdtdec.h>
Do you need this?
+#include <linux/libfdt.h>
Or this?
+#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
+static int stm32mp1_lock(struct udevice *dev, int index) +{
fdt_addr_t *base = dev_get_priv(dev);
u32 status;
if (index >= STM32_MUTEX_NUM_LOCKS)
return -EINVAL;
status = readl(*base + index * sizeof(u32));
if (status == (STM32_MUTEX_LOCK_BIT | STM32_MUTEX_COREID))
return -EBUSY;
writel(STM32_MUTEX_LOCK_BIT | STM32_MUTEX_COREID,
*base + index * sizeof(u32));
status = readl(*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) +{
fdt_addr_t *base = dev_get_priv(dev);
if (index >= STM32_MUTEX_NUM_LOCKS)
return -EINVAL;
writel(STM32_MUTEX_COREID, *base + index * sizeof(u32));
return 0;
+}
+static int stm32mp1_hwspinlock_probe(struct udevice *dev) +{
fdt_addr_t *base = dev_get_priv(dev);
struct clk clk;
int ret;
*base = dev_read_addr(dev);
if (*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(fdt_addr_t),
Please use a struct with one member, instead of this
+};
2.15.0
Regards, Simon