Skip to content

Commit

Permalink
hwspinlock: add stm32 hardware spinlock support
Browse files Browse the repository at this point in the history
Implement hardware spinlock support for STM32MP1.

Signed-off-by: Benjamin Gaignard <[email protected]>
Reviewed-by: Simon Glass <[email protected]>
Reviewed-by: Patrice Chotard <[email protected]>
  • Loading branch information
Benjamin-Gaignard authored and trini committed Dec 7, 2018
1 parent 283bcd9 commit 9119f54
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 0 deletions.
4 changes: 4 additions & 0 deletions arch/arm/dts/stm32mp157c-ed1.dts
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,10 @@
usb33d-supply = <&usb33>;
};

&hwspinlock {
status = "okay";
};

&usbphyc_port0 {
phy-supply = <&vdd_usb>;
vdda1v1-supply = <&reg11>;
Expand Down
9 changes: 9 additions & 0 deletions arch/arm/dts/stm32mp157c.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -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>;
Expand Down
2 changes: 2 additions & 0 deletions configs/stm32mp15_basic_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions drivers/hwspinlock/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
1 change: 1 addition & 0 deletions drivers/hwspinlock/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
92 changes: 92 additions & 0 deletions drivers/hwspinlock/stm32_hwspinlock.c
Original file line number Diff line number Diff line change
@@ -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),
};

0 comments on commit 9119f54

Please sign in to comment.