misc: stm32: Add STM32MP1 support

Following next kernel rcc bindings, we must use a MFD
RCC driver which is able to bind both clock and reset
drivers.

We can reuse and adapt RCC MFD driver already available
for MCU SoCs (F4/F7/H7).

Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
lime2-spi
Patrick Delaunay 6 years ago committed by Tom Rini
parent a674313c2c
commit d090cbab64
  1. 1
      arch/arm/mach-stm32mp/Kconfig
  2. 6
      drivers/clk/clk_stm32mp1.c
  3. 2
      drivers/misc/Kconfig
  4. 19
      drivers/misc/stm32_rcc.c
  5. 16
      drivers/reset/stm32-reset.c
  6. 1
      include/stm32_rcc.h

@ -29,6 +29,7 @@ config TARGET_STM32MP1
select CPU_V7_HAS_NONSEC select CPU_V7_HAS_NONSEC
select CPU_V7_HAS_VIRT select CPU_V7_HAS_VIRT
select PINCTRL_STM32 select PINCTRL_STM32
select STM32_RCC
select STM32_RESET select STM32_RESET
select SYS_ARCH_TIMER select SYS_ARCH_TIMER
select SYSRESET_SYSCON select SYSRESET_SYSCON

@ -1764,15 +1764,9 @@ static const struct clk_ops stm32mp1_clk_ops = {
.get_rate = stm32mp1_clk_get_rate, .get_rate = stm32mp1_clk_get_rate,
}; };
static const struct udevice_id stm32mp1_clk_ids[] = {
{ .compatible = "st,stm32mp1-rcc-clk" },
{ }
};
U_BOOT_DRIVER(stm32mp1_clock) = { U_BOOT_DRIVER(stm32mp1_clock) = {
.name = "stm32mp1_clk", .name = "stm32mp1_clk",
.id = UCLASS_CLK, .id = UCLASS_CLK,
.of_match = stm32mp1_clk_ids,
.ops = &stm32mp1_clk_ops, .ops = &stm32mp1_clk_ops,
.priv_auto_alloc_size = sizeof(struct stm32mp1_clk_priv), .priv_auto_alloc_size = sizeof(struct stm32mp1_clk_priv),
.probe = stm32mp1_clk_probe, .probe = stm32mp1_clk_probe,

@ -169,7 +169,7 @@ config STM32MP_FUSE
config STM32_RCC config STM32_RCC
bool "Enable RCC driver for the STM32 SoC's family" bool "Enable RCC driver for the STM32 SoC's family"
depends on STM32 && MISC depends on (STM32 || ARCH_STM32MP) && MISC
help help
Enable the STM32 RCC driver. The RCC block (Reset and Clock Control Enable the STM32 RCC driver. The RCC block (Reset and Clock Control
block) is responsible of the management of the clock and reset block) is responsible of the management of the clock and reset

@ -30,6 +30,11 @@ struct stm32_rcc_clk stm32_rcc_clk_h7 = {
.drv_name = "stm32h7_rcc_clock", .drv_name = "stm32h7_rcc_clock",
}; };
struct stm32_rcc_clk stm32_rcc_clk_mp1 = {
.drv_name = "stm32mp1_clk",
.soc = STM32MP1,
};
static int stm32_rcc_bind(struct udevice *dev) static int stm32_rcc_bind(struct udevice *dev)
{ {
struct udevice *child; struct udevice *child;
@ -39,7 +44,6 @@ static int stm32_rcc_bind(struct udevice *dev)
int ret; int ret;
debug("%s(dev=%p)\n", __func__, dev); debug("%s(dev=%p)\n", __func__, dev);
drv = lists_driver_lookup_name(rcc_clk->drv_name); drv = lists_driver_lookup_name(rcc_clk->drv_name);
if (!drv) { if (!drv) {
debug("Cannot find driver '%s'\n", rcc_clk->drv_name); debug("Cannot find driver '%s'\n", rcc_clk->drv_name);
@ -53,9 +57,15 @@ static int stm32_rcc_bind(struct udevice *dev)
if (ret) if (ret)
return ret; return ret;
return device_bind_driver_to_node(dev, "stm32_rcc_reset", drv = lists_driver_lookup_name("stm32_rcc_reset");
"stm32_rcc_reset", if (!drv) {
dev_ofnode(dev), &child); dev_err(dev, "Cannot find driver stm32_rcc_reset'\n");
return -ENOENT;
}
return device_bind_with_driver_data(dev, drv, "stm32_rcc_reset",
rcc_clk->soc,
dev_ofnode(dev), &child);
} }
static const struct misc_ops stm32_rcc_ops = { static const struct misc_ops stm32_rcc_ops = {
@ -66,6 +76,7 @@ static const struct udevice_id stm32_rcc_ids[] = {
{.compatible = "st,stm32f469-rcc", .data = (ulong)&stm32_rcc_clk_f469 }, {.compatible = "st,stm32f469-rcc", .data = (ulong)&stm32_rcc_clk_f469 },
{.compatible = "st,stm32f746-rcc", .data = (ulong)&stm32_rcc_clk_f7 }, {.compatible = "st,stm32f746-rcc", .data = (ulong)&stm32_rcc_clk_f7 },
{.compatible = "st,stm32h743-rcc", .data = (ulong)&stm32_rcc_clk_h7 }, {.compatible = "st,stm32h743-rcc", .data = (ulong)&stm32_rcc_clk_h7 },
{.compatible = "st,stm32mp1-rcc", .data = (ulong)&stm32_rcc_clk_mp1 },
{ } { }
}; };

@ -8,16 +8,12 @@
#include <dm.h> #include <dm.h>
#include <errno.h> #include <errno.h>
#include <reset-uclass.h> #include <reset-uclass.h>
#include <stm32_rcc.h>
#include <asm/io.h> #include <asm/io.h>
/* reset clear offset for STM32MP RCC */ /* reset clear offset for STM32MP RCC */
#define RCC_CL 0x4 #define RCC_CL 0x4
enum rcc_type {
RCC_STM32 = 0,
RCC_STM32MP,
};
struct stm32_reset_priv { struct stm32_reset_priv {
fdt_addr_t base; fdt_addr_t base;
}; };
@ -40,7 +36,7 @@ static int stm32_reset_assert(struct reset_ctl *reset_ctl)
debug("%s: reset id = %ld bank = %d offset = %d)\n", __func__, debug("%s: reset id = %ld bank = %d offset = %d)\n", __func__,
reset_ctl->id, bank, offset); reset_ctl->id, bank, offset);
if (dev_get_driver_data(reset_ctl->dev) == RCC_STM32MP) if (dev_get_driver_data(reset_ctl->dev) == STM32MP1)
/* reset assert is done in rcc set register */ /* reset assert is done in rcc set register */
writel(BIT(offset), priv->base + bank); writel(BIT(offset), priv->base + bank);
else else
@ -57,7 +53,7 @@ static int stm32_reset_deassert(struct reset_ctl *reset_ctl)
debug("%s: reset id = %ld bank = %d offset = %d)\n", __func__, debug("%s: reset id = %ld bank = %d offset = %d)\n", __func__,
reset_ctl->id, bank, offset); reset_ctl->id, bank, offset);
if (dev_get_driver_data(reset_ctl->dev) == RCC_STM32MP) if (dev_get_driver_data(reset_ctl->dev) == STM32MP1)
/* reset deassert is done in rcc clr register */ /* reset deassert is done in rcc clr register */
writel(BIT(offset), priv->base + bank + RCC_CL); writel(BIT(offset), priv->base + bank + RCC_CL);
else else
@ -88,15 +84,9 @@ static int stm32_reset_probe(struct udevice *dev)
return 0; return 0;
} }
static const struct udevice_id stm32_reset_ids[] = {
{ .compatible = "st,stm32mp1-rcc-rst", .data = RCC_STM32MP },
{ }
};
U_BOOT_DRIVER(stm32_rcc_reset) = { U_BOOT_DRIVER(stm32_rcc_reset) = {
.name = "stm32_rcc_reset", .name = "stm32_rcc_reset",
.id = UCLASS_RESET, .id = UCLASS_RESET,
.of_match = stm32_reset_ids,
.probe = stm32_reset_probe, .probe = stm32_reset_probe,
.priv_auto_alloc_size = sizeof(struct stm32_reset_priv), .priv_auto_alloc_size = sizeof(struct stm32_reset_priv),
.ops = &stm32_reset_ops, .ops = &stm32_reset_ops,

@ -43,6 +43,7 @@ enum soc_family {
STM32F42X, STM32F42X,
STM32F469, STM32F469,
STM32F7, STM32F7,
STM32MP1,
}; };
enum apb { enum apb {

Loading…
Cancel
Save