mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2025-08-06 23:36:59 +02:00
reset: stm32mp25: add stm32mp25 reset driver
Implement STM32MP25 reset drivers using stm32-core-reset API. This reset stm32-reset-core API and will be able to use DT binding index started from 0. This patch also moves legacy reset into stm32 directory reset. Signed-off-by: Gabriel Fernandez <gabriel.fernandez@foss.st.com> Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com> Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>
This commit is contained in:
parent
901e0d95df
commit
0994a627c2
@ -718,7 +718,7 @@ F: drivers/power/regulator/stm32-vrefbuf.c
|
||||
F: drivers/power/regulator/stpmic1.c
|
||||
F: drivers/ram/stm32mp1/
|
||||
F: drivers/remoteproc/stm32_copro.c
|
||||
F: drivers/reset/stm32-reset.c
|
||||
F: drivers/reset/stm32/
|
||||
F: drivers/rng/optee_rng.c
|
||||
F: drivers/rng/stm32_rng.c
|
||||
F: drivers/rtc/stm32_rtc.c
|
||||
@ -731,6 +731,7 @@ F: include/dt-bindings/clock/stm32fx-clock.h
|
||||
F: include/dt-bindings/clock/stm32mp*
|
||||
F: include/dt-bindings/pinctrl/stm32-pinfunc.h
|
||||
F: include/dt-bindings/reset/stm32mp*
|
||||
F: include/stm32-reset-core.h
|
||||
F: include/stm32_rcc.h
|
||||
F: tools/logos/st.bmp
|
||||
F: tools/stm32image.c
|
||||
|
@ -14,47 +14,56 @@
|
||||
#include <dm/device_compat.h>
|
||||
#include <dm/lists.h>
|
||||
|
||||
struct stm32_rcc_clk stm32_rcc_clk_f42x = {
|
||||
.drv_name = "stm32fx_rcc_clock",
|
||||
static const struct stm32_rcc stm32_rcc_f42x = {
|
||||
.drv_name_clk = "stm32fx_rcc_clock",
|
||||
.drv_name_rst = "stm32_rcc_reset",
|
||||
.soc = STM32F42X,
|
||||
};
|
||||
|
||||
struct stm32_rcc_clk stm32_rcc_clk_f469 = {
|
||||
.drv_name = "stm32fx_rcc_clock",
|
||||
static const struct stm32_rcc stm32_rcc_f469 = {
|
||||
.drv_name_clk = "stm32fx_rcc_clock",
|
||||
.drv_name_rst = "stm32_rcc_reset",
|
||||
.soc = STM32F469,
|
||||
};
|
||||
|
||||
struct stm32_rcc_clk stm32_rcc_clk_f7 = {
|
||||
.drv_name = "stm32fx_rcc_clock",
|
||||
static const struct stm32_rcc stm32_rcc_f7 = {
|
||||
.drv_name_clk = "stm32fx_rcc_clock",
|
||||
.drv_name_rst = "stm32_rcc_reset",
|
||||
.soc = STM32F7,
|
||||
};
|
||||
|
||||
struct stm32_rcc_clk stm32_rcc_clk_h7 = {
|
||||
.drv_name = "stm32h7_rcc_clock",
|
||||
static const struct stm32_rcc stm32_rcc_h7 = {
|
||||
.drv_name_clk = "stm32h7_rcc_clock",
|
||||
.drv_name_rst = "stm32_rcc_reset",
|
||||
};
|
||||
|
||||
struct stm32_rcc_clk stm32_rcc_clk_mp1 = {
|
||||
.drv_name = "stm32mp1_clk",
|
||||
.soc = STM32MP1,
|
||||
static const struct stm32_rcc stm32_rcc_mp15 = {
|
||||
.drv_name_clk = "stm32mp1_clk",
|
||||
.drv_name_rst = "stm32mp1_reset",
|
||||
};
|
||||
|
||||
struct stm32_rcc_clk stm32_rcc_clk_mp13 = {
|
||||
.drv_name = "stm32mp13_clk",
|
||||
.soc = STM32MP1,
|
||||
static const struct stm32_rcc stm32_rcc_mp13 = {
|
||||
.drv_name_clk = "stm32mp13_clk",
|
||||
.drv_name_rst = "stm32mp1_reset",
|
||||
};
|
||||
|
||||
static const struct stm32_rcc stm32_rcc_mp25 = {
|
||||
.drv_name_clk = "stm32mp25_clk",
|
||||
.drv_name_rst = "stm32mp25_reset",
|
||||
};
|
||||
|
||||
static int stm32_rcc_bind(struct udevice *dev)
|
||||
{
|
||||
struct udevice *child;
|
||||
struct driver *drv;
|
||||
struct stm32_rcc_clk *rcc_clk =
|
||||
(struct stm32_rcc_clk *)dev_get_driver_data(dev);
|
||||
struct stm32_rcc *rcc_clk =
|
||||
(struct stm32_rcc *)dev_get_driver_data(dev);
|
||||
int ret;
|
||||
|
||||
dev_dbg(dev, "RCC bind\n");
|
||||
drv = lists_driver_lookup_name(rcc_clk->drv_name);
|
||||
drv = lists_driver_lookup_name(rcc_clk->drv_name_clk);
|
||||
if (!drv) {
|
||||
dev_err(dev, "Cannot find driver '%s'\n", rcc_clk->drv_name);
|
||||
dev_err(dev, "Cannot find driver '%s'\n", rcc_clk->drv_name_clk);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
@ -65,25 +74,24 @@ static int stm32_rcc_bind(struct udevice *dev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
drv = lists_driver_lookup_name("stm32_rcc_reset");
|
||||
drv = lists_driver_lookup_name(rcc_clk->drv_name_rst);
|
||||
if (!drv) {
|
||||
dev_err(dev, "Cannot find driver stm32_rcc_reset'\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
return device_bind_with_driver_data(dev, drv, dev->name,
|
||||
rcc_clk->soc,
|
||||
dev_ofnode(dev), &child);
|
||||
return device_bind(dev, drv, dev->name, NULL, dev_ofnode(dev), &child);
|
||||
}
|
||||
|
||||
static const struct udevice_id stm32_rcc_ids[] = {
|
||||
{.compatible = "st,stm32f42xx-rcc", .data = (ulong)&stm32_rcc_clk_f42x },
|
||||
{.compatible = "st,stm32f469-rcc", .data = (ulong)&stm32_rcc_clk_f469 },
|
||||
{.compatible = "st,stm32f746-rcc", .data = (ulong)&stm32_rcc_clk_f7 },
|
||||
{.compatible = "st,stm32h743-rcc", .data = (ulong)&stm32_rcc_clk_h7 },
|
||||
{.compatible = "st,stm32mp1-rcc", .data = (ulong)&stm32_rcc_clk_mp1 },
|
||||
{.compatible = "st,stm32mp1-rcc-secure", .data = (ulong)&stm32_rcc_clk_mp1 },
|
||||
{.compatible = "st,stm32mp13-rcc", .data = (ulong)&stm32_rcc_clk_mp13 },
|
||||
{.compatible = "st,stm32f42xx-rcc", .data = (ulong)&stm32_rcc_f42x },
|
||||
{.compatible = "st,stm32f469-rcc", .data = (ulong)&stm32_rcc_f469 },
|
||||
{.compatible = "st,stm32f746-rcc", .data = (ulong)&stm32_rcc_f7 },
|
||||
{.compatible = "st,stm32h743-rcc", .data = (ulong)&stm32_rcc_h7 },
|
||||
{.compatible = "st,stm32mp1-rcc", .data = (ulong)&stm32_rcc_mp15 },
|
||||
{.compatible = "st,stm32mp1-rcc-secure", .data = (ulong)&stm32_rcc_mp15 },
|
||||
{.compatible = "st,stm32mp13-rcc", .data = (ulong)&stm32_rcc_mp13 },
|
||||
{.compatible = "st,stm32mp25-rcc", .data = (ulong)&stm32_rcc_mp25 },
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -28,13 +28,6 @@ config STI_RESET
|
||||
Say Y if you want to control reset signals provided by system config
|
||||
block.
|
||||
|
||||
config STM32_RESET
|
||||
bool "Enable the STM32 reset"
|
||||
depends on ARCH_STM32 || ARCH_STM32MP
|
||||
help
|
||||
Support for reset controllers on STMicroelectronics STM32 family SoCs.
|
||||
This reset driver is compatible with STM32 F4/F7 and H7 SoCs.
|
||||
|
||||
config TEGRA_CAR_RESET
|
||||
bool "Enable Tegra CAR-based reset driver"
|
||||
depends on TEGRA_CAR
|
||||
@ -258,4 +251,6 @@ config RESET_SPACEMIT_K1
|
||||
help
|
||||
Support for SPACEMIT's K1 Reset system. Basic Assert/Deassert
|
||||
is supported.
|
||||
|
||||
source "drivers/reset/stm32/Kconfig"
|
||||
endmenu
|
||||
|
@ -7,7 +7,6 @@ obj-$(CONFIG_DM_RESET) += reset-uclass.o
|
||||
obj-$(CONFIG_SANDBOX_MBOX) += sandbox-reset.o
|
||||
obj-$(CONFIG_SANDBOX_MBOX) += sandbox-reset-test.o
|
||||
obj-$(CONFIG_STI_RESET) += sti-reset.o
|
||||
obj-$(CONFIG_STM32_RESET) += stm32-reset.o
|
||||
obj-$(CONFIG_TEGRA_CAR_RESET) += tegra-car-reset.o
|
||||
obj-$(CONFIG_TEGRA186_RESET) += tegra186-reset.o
|
||||
obj-$(CONFIG_RESET_AIROHA) += reset-airoha.o
|
||||
@ -36,3 +35,6 @@ obj-$(CONFIG_RESET_AT91) += reset-at91.o
|
||||
obj-$(CONFIG_$(PHASE_)RESET_JH7110) += reset-jh7110.o
|
||||
obj-$(CONFIG_RESET_RZG2L_USBPHY_CTRL) += reset-rzg2l-usbphy-ctrl.o
|
||||
obj-$(CONFIG_RESET_SPACEMIT_K1) += reset-spacemit-k1.o
|
||||
|
||||
obj-$(CONFIG_ARCH_STM32) += stm32/
|
||||
obj-$(CONFIG_ARCH_STM32MP) += stm32/
|
||||
|
@ -1,97 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2017, STMicroelectronics - All Rights Reserved
|
||||
* Author(s): Patrice Chotard, <patrice.chotard@foss.st.com> for STMicroelectronics.
|
||||
*/
|
||||
|
||||
#define LOG_CATEGORY UCLASS_RESET
|
||||
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <log.h>
|
||||
#include <malloc.h>
|
||||
#include <reset-uclass.h>
|
||||
#include <stm32_rcc.h>
|
||||
#include <asm/io.h>
|
||||
#include <dm/device_compat.h>
|
||||
#include <linux/bitops.h>
|
||||
|
||||
/* offset of register without set/clear management */
|
||||
#define RCC_MP_GCR_OFFSET 0x10C
|
||||
|
||||
/* reset clear offset for STM32MP RCC */
|
||||
#define RCC_CL 0x4
|
||||
|
||||
struct stm32_reset_priv {
|
||||
fdt_addr_t base;
|
||||
};
|
||||
|
||||
static int stm32_reset_assert(struct reset_ctl *reset_ctl)
|
||||
{
|
||||
struct stm32_reset_priv *priv = dev_get_priv(reset_ctl->dev);
|
||||
int bank = (reset_ctl->id / (sizeof(u32) * BITS_PER_BYTE)) * 4;
|
||||
int offset = reset_ctl->id % (sizeof(u32) * BITS_PER_BYTE);
|
||||
|
||||
dev_dbg(reset_ctl->dev, "reset id = %ld bank = %d offset = %d)\n",
|
||||
reset_ctl->id, bank, offset);
|
||||
|
||||
if (dev_get_driver_data(reset_ctl->dev) == STM32MP1)
|
||||
if (bank != RCC_MP_GCR_OFFSET)
|
||||
/* reset assert is done in rcc set register */
|
||||
writel(BIT(offset), priv->base + bank);
|
||||
else
|
||||
clrbits_le32(priv->base + bank, BIT(offset));
|
||||
else
|
||||
setbits_le32(priv->base + bank, BIT(offset));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stm32_reset_deassert(struct reset_ctl *reset_ctl)
|
||||
{
|
||||
struct stm32_reset_priv *priv = dev_get_priv(reset_ctl->dev);
|
||||
int bank = (reset_ctl->id / (sizeof(u32) * BITS_PER_BYTE)) * 4;
|
||||
int offset = reset_ctl->id % (sizeof(u32) * BITS_PER_BYTE);
|
||||
|
||||
dev_dbg(reset_ctl->dev, "reset id = %ld bank = %d offset = %d)\n",
|
||||
reset_ctl->id, bank, offset);
|
||||
|
||||
if (dev_get_driver_data(reset_ctl->dev) == STM32MP1)
|
||||
if (bank != RCC_MP_GCR_OFFSET)
|
||||
/* reset deassert is done in rcc clr register */
|
||||
writel(BIT(offset), priv->base + bank + RCC_CL);
|
||||
else
|
||||
setbits_le32(priv->base + bank, BIT(offset));
|
||||
else
|
||||
clrbits_le32(priv->base + bank, BIT(offset));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct reset_ops stm32_reset_ops = {
|
||||
.rst_assert = stm32_reset_assert,
|
||||
.rst_deassert = stm32_reset_deassert,
|
||||
};
|
||||
|
||||
static int stm32_reset_probe(struct udevice *dev)
|
||||
{
|
||||
struct stm32_reset_priv *priv = dev_get_priv(dev);
|
||||
|
||||
priv->base = dev_read_addr(dev);
|
||||
if (priv->base == FDT_ADDR_T_NONE) {
|
||||
/* for MFD, get address of parent */
|
||||
priv->base = dev_read_addr(dev->parent);
|
||||
if (priv->base == FDT_ADDR_T_NONE)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_DRIVER(stm32_rcc_reset) = {
|
||||
.name = "stm32_rcc_reset",
|
||||
.id = UCLASS_RESET,
|
||||
.probe = stm32_reset_probe,
|
||||
.priv_auto = sizeof(struct stm32_reset_priv),
|
||||
.ops = &stm32_reset_ops,
|
||||
};
|
23
drivers/reset/stm32/Kconfig
Normal file
23
drivers/reset/stm32/Kconfig
Normal file
@ -0,0 +1,23 @@
|
||||
config RESET_STM32
|
||||
bool "Enable the STM32 reset"
|
||||
depends on ARCH_STM32
|
||||
default y
|
||||
help
|
||||
Support for reset controllers on STMicroelectronics STM32 family SoCs.
|
||||
This reset driver is compatible with STM32 F4/F7 and H7 SoCs.
|
||||
|
||||
config RESET_STM32MP1
|
||||
bool "Enable the STM32MP1 reset"
|
||||
depends on STM32MP13X || STM32MP15X
|
||||
default y
|
||||
help
|
||||
Support for reset controllers on STMicroelectronics STM32MP1 family SoCs.
|
||||
This reset driver is compatible with STM32MP13 and STM32MP15 SoCs.
|
||||
|
||||
config RESET_STM32MP25
|
||||
bool "Enable the STM32MP25 reset"
|
||||
depends on STM32MP25X
|
||||
default y
|
||||
help
|
||||
Support for reset controllers on STMicroelectronics STM32MP2 family SoCs.
|
||||
This reset driver is compatible with STM32MP25 SoCs.
|
9
drivers/reset/stm32/Makefile
Normal file
9
drivers/reset/stm32/Makefile
Normal file
@ -0,0 +1,9 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#
|
||||
# Copyright (C) 2024, STMicroelectronics - All Rights Reserved
|
||||
|
||||
obj-y += stm32-reset-core.o
|
||||
|
||||
obj-$(CONFIG_RESET_STM32) += stm32-reset.o
|
||||
obj-$(CONFIG_RESET_STM32MP1) += stm32-reset-mp1.o
|
||||
obj-$(CONFIG_RESET_STM32MP25) += stm32-reset-mp25.o
|
92
drivers/reset/stm32/stm32-reset-core.c
Normal file
92
drivers/reset/stm32/stm32-reset-core.c
Normal file
@ -0,0 +1,92 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2024, STMicroelectronics - All Rights Reserved
|
||||
* Author(s): Gabriel Fernandez, <gabriel.fernandez@foss.st.com> for STMicroelectronics.
|
||||
*/
|
||||
|
||||
#include <dm.h>
|
||||
#include <reset-uclass.h>
|
||||
#include <stm32-reset-core.h>
|
||||
#include <stm32_rcc.h>
|
||||
#include <dm/device_compat.h>
|
||||
#include <linux/iopoll.h>
|
||||
|
||||
static int stm32_reset_update(struct reset_ctl *reset_ctl, bool status)
|
||||
{
|
||||
struct stm32_reset_priv *priv = dev_get_priv(reset_ctl->dev);
|
||||
const struct stm32_reset_data *data = priv->data;
|
||||
const struct stm32_reset_cfg *ptr_line;
|
||||
fdt_addr_t addr;
|
||||
|
||||
assert(priv->data->get_reset_line);
|
||||
|
||||
ptr_line = priv->data->get_reset_line(reset_ctl);
|
||||
if (!ptr_line)
|
||||
return -EPERM;
|
||||
|
||||
addr = priv->base + ptr_line->offset;
|
||||
|
||||
dev_dbg(reset_ctl->dev, "reset id=%ld offset=0x%x bit=%d status=%d\n",
|
||||
reset_ctl->id, ptr_line->offset, ptr_line->bit_idx, status);
|
||||
|
||||
status = ptr_line->inverted ^ status;
|
||||
|
||||
if (ptr_line->set_clr) {
|
||||
if (!status)
|
||||
addr += data->clear_offset;
|
||||
|
||||
writel(BIT(ptr_line->bit_idx), addr);
|
||||
|
||||
} else {
|
||||
if (status)
|
||||
setbits_le32(addr, BIT(ptr_line->bit_idx));
|
||||
else
|
||||
clrbits_le32(addr, BIT(ptr_line->bit_idx));
|
||||
}
|
||||
|
||||
/* Check deassert */
|
||||
if (!status) {
|
||||
u32 reg;
|
||||
|
||||
return readl_poll_timeout(addr, reg,
|
||||
!(reg & BIT(ptr_line->bit_idx)),
|
||||
data->reset_us);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stm32_reset_assert(struct reset_ctl *reset_ctl)
|
||||
{
|
||||
return stm32_reset_update(reset_ctl, true);
|
||||
}
|
||||
|
||||
static int stm32_reset_deassert(struct reset_ctl *reset_ctl)
|
||||
{
|
||||
return stm32_reset_update(reset_ctl, false);
|
||||
}
|
||||
|
||||
const struct reset_ops stm32_reset_ops = {
|
||||
.rst_assert = stm32_reset_assert,
|
||||
.rst_deassert = stm32_reset_deassert,
|
||||
};
|
||||
|
||||
int stm32_reset_core_probe(struct udevice *dev,
|
||||
const struct stm32_reset_data *data)
|
||||
{
|
||||
struct stm32_reset_priv *priv = dev_get_priv(dev);
|
||||
|
||||
priv->base = dev_read_addr(dev);
|
||||
if (priv->base == FDT_ADDR_T_NONE) {
|
||||
/* for MFD, get address of parent */
|
||||
priv->base = dev_read_addr(dev->parent);
|
||||
if (priv->base == FDT_ADDR_T_NONE)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
priv->data = data;
|
||||
|
||||
assert(priv->data);
|
||||
|
||||
return 0;
|
||||
}
|
31
drivers/reset/stm32/stm32-reset-core.h
Normal file
31
drivers/reset/stm32/stm32-reset-core.h
Normal file
@ -0,0 +1,31 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (C) 2025, STMicroelectronics - All Rights Reserved
|
||||
* Author(s): Gabriel Fernandez, <gabriel.fernandez@foss.st.com> for STMicroelectronics.
|
||||
*/
|
||||
|
||||
#include <reset-uclass.h>
|
||||
|
||||
struct stm32_reset_cfg {
|
||||
u16 offset;
|
||||
u8 bit_idx;
|
||||
bool set_clr;
|
||||
bool inverted;
|
||||
};
|
||||
|
||||
struct stm32_reset_data {
|
||||
const struct stm32_reset_cfg * (*get_reset_line)(struct reset_ctl *reset_ctl);
|
||||
u32 clear_offset;
|
||||
u32 reset_us;
|
||||
};
|
||||
|
||||
struct stm32_reset_priv {
|
||||
fdt_addr_t base;
|
||||
struct stm32_reset_cfg reset_line;
|
||||
const struct stm32_reset_data *data;
|
||||
};
|
||||
|
||||
extern const struct reset_ops stm32_reset_ops;
|
||||
|
||||
int stm32_reset_core_probe(struct udevice *dev,
|
||||
const struct stm32_reset_data *data);
|
55
drivers/reset/stm32/stm32-reset-mp1.c
Normal file
55
drivers/reset/stm32/stm32-reset-mp1.c
Normal file
@ -0,0 +1,55 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2017, STMicroelectronics - All Rights Reserved
|
||||
* Author(s): Patrice Chotard, <patrice.chotard@foss.st.com> for STMicroelectronics.
|
||||
*/
|
||||
|
||||
#include <dm.h>
|
||||
#include <stm32-reset-core.h>
|
||||
|
||||
/* Reset clear offset for STM32MP RCC */
|
||||
#define RCC_CLR_OFFSET 0x4
|
||||
|
||||
/* Offset of register without set/clear management */
|
||||
#define RCC_MP_GCR_OFFSET 0x10C
|
||||
|
||||
/* Timeout for deassert */
|
||||
#define STM32_DEASSERT_TIMEOUT_US 10000
|
||||
|
||||
static const struct stm32_reset_cfg *stm32_get_reset_line(struct reset_ctl *reset_ctl)
|
||||
{
|
||||
struct stm32_reset_priv *priv = dev_get_priv(reset_ctl->dev);
|
||||
struct stm32_reset_cfg *ptr_line = &priv->reset_line;
|
||||
int bank = (reset_ctl->id / (sizeof(u32) * BITS_PER_BYTE)) * 4;
|
||||
int offset = reset_ctl->id % (sizeof(u32) * BITS_PER_BYTE);
|
||||
|
||||
ptr_line->offset = bank;
|
||||
ptr_line->bit_idx = offset;
|
||||
ptr_line->set_clr = true;
|
||||
|
||||
if (ptr_line->offset == RCC_MP_GCR_OFFSET) {
|
||||
ptr_line->set_clr = false;
|
||||
ptr_line->inverted = true;
|
||||
}
|
||||
|
||||
return ptr_line;
|
||||
}
|
||||
|
||||
static const struct stm32_reset_data stm32mp1_reset_data = {
|
||||
.get_reset_line = stm32_get_reset_line,
|
||||
.clear_offset = RCC_CLR_OFFSET,
|
||||
.reset_us = STM32_DEASSERT_TIMEOUT_US,
|
||||
};
|
||||
|
||||
static int stm32_reset_probe(struct udevice *dev)
|
||||
{
|
||||
return stm32_reset_core_probe(dev, &stm32mp1_reset_data);
|
||||
}
|
||||
|
||||
U_BOOT_DRIVER(stm32mp25_rcc_reset) = {
|
||||
.name = "stm32mp1_reset",
|
||||
.id = UCLASS_RESET,
|
||||
.probe = stm32_reset_probe,
|
||||
.priv_auto = sizeof(struct stm32_reset_priv),
|
||||
.ops = &stm32_reset_ops,
|
||||
};
|
159
drivers/reset/stm32/stm32-reset-mp25.c
Normal file
159
drivers/reset/stm32/stm32-reset-mp25.c
Normal file
@ -0,0 +1,159 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2024, STMicroelectronics - All Rights Reserved
|
||||
* Author(s): Gabriel Fernandez, <gabriel.fernandez@foss.st.com> for STMicroelectronics.
|
||||
*/
|
||||
|
||||
#include <dm.h>
|
||||
#include <stm32-reset-core.h>
|
||||
#include <stm32mp25_rcc.h>
|
||||
#include <dt-bindings/reset/st,stm32mp25-rcc.h>
|
||||
|
||||
/* Reset clear offset for STM32MP RCC */
|
||||
#define RCC_CLR_OFFSET 0x4
|
||||
|
||||
/* Timeout for deassert */
|
||||
#define STM32_DEASSERT_TIMEOUT_US 10000
|
||||
|
||||
#define RESET(id, _offset, _bit_idx, _set_clr) \
|
||||
[id] = &(struct stm32_reset_cfg){ \
|
||||
.offset = (_offset), \
|
||||
.bit_idx = (_bit_idx), \
|
||||
.set_clr = (_set_clr), \
|
||||
}
|
||||
|
||||
static const struct stm32_reset_cfg *stm32mp25_reset[STM32MP25_LAST_RESET] = {
|
||||
RESET(TIM1_R, RCC_TIM1CFGR, 0, 0),
|
||||
RESET(TIM2_R, RCC_TIM2CFGR, 0, 0),
|
||||
RESET(TIM3_R, RCC_TIM3CFGR, 0, 0),
|
||||
RESET(TIM4_R, RCC_TIM4CFGR, 0, 0),
|
||||
RESET(TIM5_R, RCC_TIM5CFGR, 0, 0),
|
||||
RESET(TIM6_R, RCC_TIM6CFGR, 0, 0),
|
||||
RESET(TIM7_R, RCC_TIM7CFGR, 0, 0),
|
||||
RESET(TIM8_R, RCC_TIM8CFGR, 0, 0),
|
||||
RESET(TIM10_R, RCC_TIM10CFGR, 0, 0),
|
||||
RESET(TIM11_R, RCC_TIM11CFGR, 0, 0),
|
||||
RESET(TIM12_R, RCC_TIM12CFGR, 0, 0),
|
||||
RESET(TIM13_R, RCC_TIM13CFGR, 0, 0),
|
||||
RESET(TIM14_R, RCC_TIM14CFGR, 0, 0),
|
||||
RESET(TIM15_R, RCC_TIM15CFGR, 0, 0),
|
||||
RESET(TIM16_R, RCC_TIM16CFGR, 0, 0),
|
||||
RESET(TIM17_R, RCC_TIM17CFGR, 0, 0),
|
||||
RESET(TIM20_R, RCC_TIM20CFGR, 0, 0),
|
||||
RESET(LPTIM1_R, RCC_LPTIM1CFGR, 0, 0),
|
||||
RESET(LPTIM2_R, RCC_LPTIM2CFGR, 0, 0),
|
||||
RESET(LPTIM3_R, RCC_LPTIM3CFGR, 0, 0),
|
||||
RESET(LPTIM4_R, RCC_LPTIM4CFGR, 0, 0),
|
||||
RESET(LPTIM5_R, RCC_LPTIM5CFGR, 0, 0),
|
||||
RESET(SPI1_R, RCC_SPI1CFGR, 0, 0),
|
||||
RESET(SPI2_R, RCC_SPI2CFGR, 0, 0),
|
||||
RESET(SPI3_R, RCC_SPI3CFGR, 0, 0),
|
||||
RESET(SPI4_R, RCC_SPI4CFGR, 0, 0),
|
||||
RESET(SPI5_R, RCC_SPI5CFGR, 0, 0),
|
||||
RESET(SPI6_R, RCC_SPI6CFGR, 0, 0),
|
||||
RESET(SPI7_R, RCC_SPI7CFGR, 0, 0),
|
||||
RESET(SPI8_R, RCC_SPI8CFGR, 0, 0),
|
||||
RESET(SPDIFRX_R, RCC_SPDIFRXCFGR, 0, 0),
|
||||
RESET(USART1_R, RCC_USART1CFGR, 0, 0),
|
||||
RESET(USART2_R, RCC_USART2CFGR, 0, 0),
|
||||
RESET(USART3_R, RCC_USART3CFGR, 0, 0),
|
||||
RESET(UART4_R, RCC_UART4CFGR, 0, 0),
|
||||
RESET(UART5_R, RCC_UART5CFGR, 0, 0),
|
||||
RESET(USART6_R, RCC_USART6CFGR, 0, 0),
|
||||
RESET(UART7_R, RCC_UART7CFGR, 0, 0),
|
||||
RESET(UART8_R, RCC_UART8CFGR, 0, 0),
|
||||
RESET(UART9_R, RCC_UART9CFGR, 0, 0),
|
||||
RESET(LPUART1_R, RCC_LPUART1CFGR, 0, 0),
|
||||
RESET(IS2M_R, RCC_IS2MCFGR, 0, 0),
|
||||
RESET(I2C1_R, RCC_I2C1CFGR, 0, 0),
|
||||
RESET(I2C2_R, RCC_I2C2CFGR, 0, 0),
|
||||
RESET(I2C3_R, RCC_I2C3CFGR, 0, 0),
|
||||
RESET(I2C4_R, RCC_I2C4CFGR, 0, 0),
|
||||
RESET(I2C5_R, RCC_I2C5CFGR, 0, 0),
|
||||
RESET(I2C6_R, RCC_I2C6CFGR, 0, 0),
|
||||
RESET(I2C7_R, RCC_I2C7CFGR, 0, 0),
|
||||
RESET(I2C8_R, RCC_I2C8CFGR, 0, 0),
|
||||
RESET(SAI1_R, RCC_SAI1CFGR, 0, 0),
|
||||
RESET(SAI2_R, RCC_SAI2CFGR, 0, 0),
|
||||
RESET(SAI3_R, RCC_SAI3CFGR, 0, 0),
|
||||
RESET(SAI4_R, RCC_SAI4CFGR, 0, 0),
|
||||
RESET(MDF1_R, RCC_MDF1CFGR, 0, 0),
|
||||
RESET(MDF2_R, RCC_ADF1CFGR, 0, 0),
|
||||
RESET(FDCAN_R, RCC_FDCANCFGR, 0, 0),
|
||||
RESET(HDP_R, RCC_HDPCFGR, 0, 0),
|
||||
RESET(ADC12_R, RCC_ADC12CFGR, 0, 0),
|
||||
RESET(ADC3_R, RCC_ADC3CFGR, 0, 0),
|
||||
RESET(ETH1_R, RCC_ETH1CFGR, 0, 0),
|
||||
RESET(ETH2_R, RCC_ETH2CFGR, 0, 0),
|
||||
RESET(USBH_R, RCC_USBHCFGR, 0, 0),
|
||||
RESET(USB2PHY1_R, RCC_USB2PHY1CFGR, 0, 0),
|
||||
RESET(USB2PHY2_R, RCC_USB2PHY2CFGR, 0, 0),
|
||||
RESET(USB3DR_R, RCC_USB3DRCFGR, 0, 0),
|
||||
RESET(USB3PCIEPHY_R, RCC_USB3PCIEPHYCFGR, 0, 0),
|
||||
RESET(USBTC_R, RCC_UCPDCFGR, 0, 0),
|
||||
RESET(ETHSW_R, RCC_ETHSWCFGR, 0, 0),
|
||||
RESET(SDMMC1_R, RCC_SDMMC1CFGR, 0, 0),
|
||||
RESET(SDMMC1DLL_R, RCC_SDMMC1CFGR, 16, 0),
|
||||
RESET(SDMMC2_R, RCC_SDMMC2CFGR, 0, 0),
|
||||
RESET(SDMMC2DLL_R, RCC_SDMMC2CFGR, 16, 0),
|
||||
RESET(SDMMC3_R, RCC_SDMMC3CFGR, 0, 0),
|
||||
RESET(SDMMC3DLL_R, RCC_SDMMC3CFGR, 16, 0),
|
||||
RESET(GPU_R, RCC_GPUCFGR, 0, 0),
|
||||
RESET(LTDC_R, RCC_LTDCCFGR, 0, 0),
|
||||
RESET(DSI_R, RCC_DSICFGR, 0, 0),
|
||||
RESET(LVDS_R, RCC_LVDSCFGR, 0, 0),
|
||||
RESET(CSI_R, RCC_CSICFGR, 0, 0),
|
||||
RESET(DCMIPP_R, RCC_DCMIPPCFGR, 0, 0),
|
||||
RESET(CCI_R, RCC_CCICFGR, 0, 0),
|
||||
RESET(VDEC_R, RCC_VDECCFGR, 0, 0),
|
||||
RESET(VENC_R, RCC_VENCCFGR, 0, 0),
|
||||
RESET(WWDG1_R, RCC_WWDG1CFGR, 0, 0),
|
||||
RESET(WWDG2_R, RCC_WWDG2CFGR, 0, 0),
|
||||
RESET(VREF_R, RCC_VREFCFGR, 0, 0),
|
||||
RESET(DTS_R, RCC_DTSCFGR, 0, 0),
|
||||
RESET(CRC_R, RCC_CRCCFGR, 0, 0),
|
||||
RESET(SERC_R, RCC_SERCCFGR, 0, 0),
|
||||
RESET(OSPIIOM_R, RCC_OSPIIOMCFGR, 0, 0),
|
||||
RESET(I3C1_R, RCC_I3C1CFGR, 0, 0),
|
||||
RESET(I3C2_R, RCC_I3C2CFGR, 0, 0),
|
||||
RESET(I3C3_R, RCC_I3C3CFGR, 0, 0),
|
||||
RESET(I3C4_R, RCC_I3C4CFGR, 0, 0),
|
||||
RESET(IWDG2_KER_R, RCC_IWDGC1CFGSETR, 18, 1),
|
||||
RESET(IWDG4_KER_R, RCC_IWDGC2CFGSETR, 18, 1),
|
||||
RESET(RNG_R, RCC_RNGCFGR, 0, 0),
|
||||
RESET(PKA_R, RCC_PKACFGR, 0, 0),
|
||||
RESET(SAES_R, RCC_SAESCFGR, 0, 0),
|
||||
RESET(HASH_R, RCC_HASHCFGR, 0, 0),
|
||||
RESET(CRYP1_R, RCC_CRYP1CFGR, 0, 0),
|
||||
RESET(CRYP2_R, RCC_CRYP2CFGR, 0, 0),
|
||||
RESET(PCIE_R, RCC_PCIECFGR, 0, 0),
|
||||
};
|
||||
|
||||
static const struct stm32_reset_cfg *stm32_get_reset_line(struct reset_ctl *reset_ctl)
|
||||
{
|
||||
unsigned long id = reset_ctl->id;
|
||||
|
||||
if (id < STM32MP25_LAST_RESET)
|
||||
return stm32mp25_reset[id];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const struct stm32_reset_data stm32mp25_reset_data = {
|
||||
.get_reset_line = stm32_get_reset_line,
|
||||
.clear_offset = RCC_CLR_OFFSET,
|
||||
.reset_us = STM32_DEASSERT_TIMEOUT_US,
|
||||
};
|
||||
|
||||
static int stm32_reset_probe(struct udevice *dev)
|
||||
{
|
||||
return stm32_reset_core_probe(dev, &stm32mp25_reset_data);
|
||||
}
|
||||
|
||||
U_BOOT_DRIVER(stm32mp25_rcc_reset) = {
|
||||
.name = "stm32mp25_reset",
|
||||
.id = UCLASS_RESET,
|
||||
.probe = stm32_reset_probe,
|
||||
.priv_auto = sizeof(struct stm32_reset_priv),
|
||||
.ops = &stm32_reset_ops,
|
||||
};
|
43
drivers/reset/stm32/stm32-reset.c
Normal file
43
drivers/reset/stm32/stm32-reset.c
Normal file
@ -0,0 +1,43 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2017, STMicroelectronics - All Rights Reserved
|
||||
* Author(s): Patrice Chotard, <patrice.chotard@foss.st.com> for STMicroelectronics.
|
||||
*/
|
||||
|
||||
#include <dm.h>
|
||||
#include <stm32-reset-core.h>
|
||||
|
||||
/* Timeout for deassert */
|
||||
#define STM32_DEASSERT_TIMEOUT_US 10000
|
||||
|
||||
static const struct stm32_reset_cfg *stm32_get_reset_line(struct reset_ctl *reset_ctl)
|
||||
{
|
||||
struct stm32_reset_priv *priv = dev_get_priv(reset_ctl->dev);
|
||||
struct stm32_reset_cfg *ptr_line = &priv->reset_line;
|
||||
int bank = (reset_ctl->id / (sizeof(u32) * BITS_PER_BYTE)) * 4;
|
||||
int offset = reset_ctl->id % (sizeof(u32) * BITS_PER_BYTE);
|
||||
|
||||
ptr_line->offset = bank;
|
||||
ptr_line->bit_idx = offset;
|
||||
ptr_line->set_clr = true;
|
||||
|
||||
return ptr_line;
|
||||
}
|
||||
|
||||
static const struct stm32_reset_data stm32_reset_data = {
|
||||
.get_reset_line = stm32_get_reset_line,
|
||||
.reset_us = STM32_DEASSERT_TIMEOUT_US,
|
||||
};
|
||||
|
||||
static int stm32_reset_probe(struct udevice *dev)
|
||||
{
|
||||
return stm32_reset_core_probe(dev, &stm32_reset_data);
|
||||
}
|
||||
|
||||
U_BOOT_DRIVER(stm32_rcc_reset) = {
|
||||
.name = "stm32_rcc_reset",
|
||||
.id = UCLASS_RESET,
|
||||
.probe = stm32_reset_probe,
|
||||
.priv_auto = sizeof(struct stm32_reset_priv),
|
||||
.ops = &stm32_reset_ops,
|
||||
};
|
@ -39,11 +39,11 @@ struct stm32_clk_info {
|
||||
bool v2;
|
||||
};
|
||||
|
||||
/* platdata used for clk-stm32f.c driver */
|
||||
enum soc_family {
|
||||
STM32F42X,
|
||||
STM32F469,
|
||||
STM32F7,
|
||||
STM32MP1,
|
||||
};
|
||||
|
||||
enum apb {
|
||||
@ -51,8 +51,9 @@ enum apb {
|
||||
APB2,
|
||||
};
|
||||
|
||||
struct stm32_rcc_clk {
|
||||
char *drv_name;
|
||||
struct stm32_rcc {
|
||||
char *drv_name_clk;
|
||||
char *drv_name_rst;
|
||||
enum soc_family soc;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user