Hi Benjamin On 11/14/18 10:01 AM, Benjamin Gaignard wrote: > Implement hardware spinlock support for STM32MP1. > > Signed-off-by: Benjamin Gaignard <benjamin.gaign...@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.chot...@st.com> Thanks _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot