KERNEL: 5.15-stm32mp1-r1
Signed-off-by: Christophe Priouzeau <christophe.priouzeau@foss.st.com> Change-Id: I0b997edf47d41b8633c5a58861ff2cf04caad2f0
This commit is contained in:
parent
48b49d3e27
commit
9825958fd6
|
|
@ -1,7 +1,6 @@
|
||||||
COMPATIBLE_MACHINE = "(stm32mpcommon)"
|
COMPATIBLE_MACHINE = "(stm32mpcommon)"
|
||||||
|
|
||||||
inherit kernel
|
inherit kernel
|
||||||
inherit kernel-fitimage
|
|
||||||
|
|
||||||
DEPENDS += "openssl-native util-linux-native libyaml-native"
|
DEPENDS += "openssl-native util-linux-native libyaml-native"
|
||||||
|
|
||||||
|
|
@ -114,6 +113,18 @@ do_deploy:append() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
do_deploy[depends] += " virtual/kernel:do_package "
|
do_deploy[depends] += " virtual/kernel:do_package "
|
||||||
|
|
||||||
|
python() {
|
||||||
|
fitimage_signed = d.getVar('UBOOT_SIGN_ENABLE')
|
||||||
|
devicetree = d.getVar('KERNEL_DEVICETREE').split()
|
||||||
|
machine_features = d.getVar('MACHINE_FEATURES')
|
||||||
|
if 'fit' in machine_features:
|
||||||
|
if fitimage_signed is not None and fitimage_signed == "1":
|
||||||
|
if len(devicetree) > 1:
|
||||||
|
bb.fatal("The signature of FIT image work only when there is only "
|
||||||
|
"one DEVICE-TREE specified")
|
||||||
|
}
|
||||||
|
|
||||||
# ---------------------------------------------------------------------
|
# ---------------------------------------------------------------------
|
||||||
# Support checking the kernel load address parameter: expecting proper value for ST kernel.
|
# Support checking the kernel load address parameter: expecting proper value for ST kernel.
|
||||||
#
|
#
|
||||||
|
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
From 291e33f627836085d320628794cbc836a3241965 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lionel Vitte <lionel.vitte@st.com>
|
|
||||||
Date: Thu, 14 Oct 2021 16:51:41 +0200
|
|
||||||
Subject: [PATCH 01/23] ARM 5.10.61-stm32mp1-r2 MACHINE
|
|
||||||
|
|
||||||
---
|
|
||||||
arch/arm/mach-stm32/Kconfig | 2 ++
|
|
||||||
arch/arm/mach-stm32/board-dt.c | 2 ++
|
|
||||||
2 files changed, 4 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/arch/arm/mach-stm32/Kconfig b/arch/arm/mach-stm32/Kconfig
|
|
||||||
index 57699bd8f..d1f79bc2c 100644
|
|
||||||
--- a/arch/arm/mach-stm32/Kconfig
|
|
||||||
+++ b/arch/arm/mach-stm32/Kconfig
|
|
||||||
@@ -46,6 +46,8 @@ if ARCH_MULTI_V7
|
|
||||||
config MACH_STM32MP157
|
|
||||||
bool "STMicroelectronics STM32MP157"
|
|
||||||
select ARM_ERRATA_814220
|
|
||||||
+ select REGULATOR
|
|
||||||
+ select ARCH_SUPPORTS_RT
|
|
||||||
default y
|
|
||||||
|
|
||||||
endif # ARMv7-A
|
|
||||||
diff --git a/arch/arm/mach-stm32/board-dt.c b/arch/arm/mach-stm32/board-dt.c
|
|
||||||
index 011d57b48..8e06a9442 100644
|
|
||||||
--- a/arch/arm/mach-stm32/board-dt.c
|
|
||||||
+++ b/arch/arm/mach-stm32/board-dt.c
|
|
||||||
@@ -17,6 +17,8 @@ static const char *const stm32_compat[] __initconst = {
|
|
||||||
"st,stm32f746",
|
|
||||||
"st,stm32f769",
|
|
||||||
"st,stm32h743",
|
|
||||||
+ "st,stm32mp151",
|
|
||||||
+ "st,stm32mp153",
|
|
||||||
"st,stm32mp157",
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
--
|
|
||||||
2.17.1
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -1,40 +0,0 @@
|
||||||
From b1ce5fb5a80db8945c9496f8ad9a74280d31ecf8 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lionel Vitte <lionel.vitte@st.com>
|
|
||||||
Date: Thu, 14 Oct 2021 16:51:47 +0200
|
|
||||||
Subject: [PATCH 12/23] ARM 5.10.61-stm32mp1-r2 MMC
|
|
||||||
|
|
||||||
---
|
|
||||||
drivers/mmc/core/mmc_test.c | 2 +-
|
|
||||||
drivers/mmc/host/mmci.c | 3 ---
|
|
||||||
2 files changed, 1 insertion(+), 4 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/mmc/core/mmc_test.c b/drivers/mmc/core/mmc_test.c
|
|
||||||
index 152e7525e..b1f0d04f9 100644
|
|
||||||
--- a/drivers/mmc/core/mmc_test.c
|
|
||||||
+++ b/drivers/mmc/core/mmc_test.c
|
|
||||||
@@ -2124,7 +2124,7 @@ static int mmc_test_rw_multiple(struct mmc_test_card *test,
|
|
||||||
if (mmc_can_erase(test->card) &&
|
|
||||||
tdata->prepare & MMC_TEST_PREP_ERASE) {
|
|
||||||
ret = mmc_erase(test->card, dev_addr,
|
|
||||||
- size / 512, MMC_SECURE_ERASE_ARG);
|
|
||||||
+ size / 512, test->card->erase_arg);
|
|
||||||
if (ret)
|
|
||||||
ret = mmc_erase(test->card, dev_addr,
|
|
||||||
size / 512, MMC_ERASE_ARG);
|
|
||||||
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
|
|
||||||
index 9bde0def1..fa6d85190 100644
|
|
||||||
--- a/drivers/mmc/host/mmci.c
|
|
||||||
+++ b/drivers/mmc/host/mmci.c
|
|
||||||
@@ -2104,9 +2104,6 @@ static int mmci_probe(struct amba_device *dev,
|
|
||||||
host->stop_abort.arg = 0;
|
|
||||||
host->stop_abort.flags = MMC_RSP_R1B | MMC_CMD_AC;
|
|
||||||
|
|
||||||
- /* We support these PM capabilities. */
|
|
||||||
- mmc->pm_caps |= MMC_PM_KEEP_POWER;
|
|
||||||
-
|
|
||||||
/*
|
|
||||||
* We can do SGIO
|
|
||||||
*/
|
|
||||||
--
|
|
||||||
2.17.1
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -1,652 +0,0 @@
|
||||||
From 32651dddd362b90d443aa3e6f15b699d0e1ad26c Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lionel Vitte <lionel.vitte@st.com>
|
|
||||||
Date: Thu, 14 Oct 2021 16:51:50 +0200
|
|
||||||
Subject: [PATCH 17/23] ARM 5.10.61-stm32mp1-r2 RESET-RTC-WATCHDOG
|
|
||||||
|
|
||||||
---
|
|
||||||
drivers/reset/Kconfig | 6 -
|
|
||||||
drivers/reset/Makefile | 1 -
|
|
||||||
drivers/reset/reset-stm32mp1.c | 115 -----------
|
|
||||||
drivers/rtc/Kconfig | 1 +
|
|
||||||
drivers/rtc/rtc-stm32.c | 214 +++++++++++++++-----
|
|
||||||
drivers/watchdog/stm32_iwdg.c | 13 +-
|
|
||||||
include/dt-bindings/reset/stm32mp1-resets.h | 15 ++
|
|
||||||
include/dt-bindings/rtc/rtc-stm32.h | 13 ++
|
|
||||||
8 files changed, 202 insertions(+), 176 deletions(-)
|
|
||||||
delete mode 100644 drivers/reset/reset-stm32mp1.c
|
|
||||||
create mode 100644 include/dt-bindings/rtc/rtc-stm32.h
|
|
||||||
|
|
||||||
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
|
|
||||||
index 147543ad3..6c1409b38 100644
|
|
||||||
--- a/drivers/reset/Kconfig
|
|
||||||
+++ b/drivers/reset/Kconfig
|
|
||||||
@@ -182,12 +182,6 @@ config RESET_SIMPLE
|
|
||||||
- Allwinner SoCs
|
|
||||||
- ZTE's zx2967 family
|
|
||||||
|
|
||||||
-config RESET_STM32MP157
|
|
||||||
- bool "STM32MP157 Reset Driver" if COMPILE_TEST
|
|
||||||
- default MACH_STM32MP157
|
|
||||||
- help
|
|
||||||
- This enables the RCC reset controller driver for STM32 MPUs.
|
|
||||||
-
|
|
||||||
config RESET_SOCFPGA
|
|
||||||
bool "SoCFPGA Reset Driver" if COMPILE_TEST && !ARCH_SOCFPGA
|
|
||||||
default ARCH_SOCFPGA
|
|
||||||
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
|
|
||||||
index 16947610c..b2c9eff41 100644
|
|
||||||
--- a/drivers/reset/Makefile
|
|
||||||
+++ b/drivers/reset/Makefile
|
|
||||||
@@ -24,7 +24,6 @@ obj-$(CONFIG_RESET_QCOM_PDC) += reset-qcom-pdc.o
|
|
||||||
obj-$(CONFIG_RESET_RASPBERRYPI) += reset-raspberrypi.o
|
|
||||||
obj-$(CONFIG_RESET_SCMI) += reset-scmi.o
|
|
||||||
obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o
|
|
||||||
-obj-$(CONFIG_RESET_STM32MP157) += reset-stm32mp1.o
|
|
||||||
obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
|
|
||||||
obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
|
|
||||||
obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o
|
|
||||||
diff --git a/drivers/reset/reset-stm32mp1.c b/drivers/reset/reset-stm32mp1.c
|
|
||||||
deleted file mode 100644
|
|
||||||
index b221a2804..000000000
|
|
||||||
--- a/drivers/reset/reset-stm32mp1.c
|
|
||||||
+++ /dev/null
|
|
||||||
@@ -1,115 +0,0 @@
|
|
||||||
-// SPDX-License-Identifier: GPL-2.0
|
|
||||||
-/*
|
|
||||||
- * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
|
|
||||||
- * Author: Gabriel Fernandez <gabriel.fernandez@st.com> for STMicroelectronics.
|
|
||||||
- */
|
|
||||||
-
|
|
||||||
-#include <linux/device.h>
|
|
||||||
-#include <linux/err.h>
|
|
||||||
-#include <linux/io.h>
|
|
||||||
-#include <linux/of.h>
|
|
||||||
-#include <linux/platform_device.h>
|
|
||||||
-#include <linux/reset-controller.h>
|
|
||||||
-
|
|
||||||
-#define CLR_OFFSET 0x4
|
|
||||||
-
|
|
||||||
-struct stm32_reset_data {
|
|
||||||
- struct reset_controller_dev rcdev;
|
|
||||||
- void __iomem *membase;
|
|
||||||
-};
|
|
||||||
-
|
|
||||||
-static inline struct stm32_reset_data *
|
|
||||||
-to_stm32_reset_data(struct reset_controller_dev *rcdev)
|
|
||||||
-{
|
|
||||||
- return container_of(rcdev, struct stm32_reset_data, rcdev);
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static int stm32_reset_update(struct reset_controller_dev *rcdev,
|
|
||||||
- unsigned long id, bool assert)
|
|
||||||
-{
|
|
||||||
- struct stm32_reset_data *data = to_stm32_reset_data(rcdev);
|
|
||||||
- int reg_width = sizeof(u32);
|
|
||||||
- int bank = id / (reg_width * BITS_PER_BYTE);
|
|
||||||
- int offset = id % (reg_width * BITS_PER_BYTE);
|
|
||||||
- void __iomem *addr;
|
|
||||||
-
|
|
||||||
- addr = data->membase + (bank * reg_width);
|
|
||||||
- if (!assert)
|
|
||||||
- addr += CLR_OFFSET;
|
|
||||||
-
|
|
||||||
- writel(BIT(offset), addr);
|
|
||||||
-
|
|
||||||
- return 0;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static int stm32_reset_assert(struct reset_controller_dev *rcdev,
|
|
||||||
- unsigned long id)
|
|
||||||
-{
|
|
||||||
- return stm32_reset_update(rcdev, id, true);
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static int stm32_reset_deassert(struct reset_controller_dev *rcdev,
|
|
||||||
- unsigned long id)
|
|
||||||
-{
|
|
||||||
- return stm32_reset_update(rcdev, id, false);
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static int stm32_reset_status(struct reset_controller_dev *rcdev,
|
|
||||||
- unsigned long id)
|
|
||||||
-{
|
|
||||||
- struct stm32_reset_data *data = to_stm32_reset_data(rcdev);
|
|
||||||
- int reg_width = sizeof(u32);
|
|
||||||
- int bank = id / (reg_width * BITS_PER_BYTE);
|
|
||||||
- int offset = id % (reg_width * BITS_PER_BYTE);
|
|
||||||
- u32 reg;
|
|
||||||
-
|
|
||||||
- reg = readl(data->membase + (bank * reg_width));
|
|
||||||
-
|
|
||||||
- return !!(reg & BIT(offset));
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static const struct reset_control_ops stm32_reset_ops = {
|
|
||||||
- .assert = stm32_reset_assert,
|
|
||||||
- .deassert = stm32_reset_deassert,
|
|
||||||
- .status = stm32_reset_status,
|
|
||||||
-};
|
|
||||||
-
|
|
||||||
-static const struct of_device_id stm32_reset_dt_ids[] = {
|
|
||||||
- { .compatible = "st,stm32mp1-rcc"},
|
|
||||||
- { /* sentinel */ },
|
|
||||||
-};
|
|
||||||
-
|
|
||||||
-static int stm32_reset_probe(struct platform_device *pdev)
|
|
||||||
-{
|
|
||||||
- struct device *dev = &pdev->dev;
|
|
||||||
- struct stm32_reset_data *data;
|
|
||||||
- void __iomem *membase;
|
|
||||||
- struct resource *res;
|
|
||||||
-
|
|
||||||
- data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
|
|
||||||
- if (!data)
|
|
||||||
- return -ENOMEM;
|
|
||||||
-
|
|
||||||
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
||||||
- membase = devm_ioremap_resource(dev, res);
|
|
||||||
- if (IS_ERR(membase))
|
|
||||||
- return PTR_ERR(membase);
|
|
||||||
-
|
|
||||||
- data->membase = membase;
|
|
||||||
- data->rcdev.owner = THIS_MODULE;
|
|
||||||
- data->rcdev.nr_resets = resource_size(res) * BITS_PER_BYTE;
|
|
||||||
- data->rcdev.ops = &stm32_reset_ops;
|
|
||||||
- data->rcdev.of_node = dev->of_node;
|
|
||||||
-
|
|
||||||
- return devm_reset_controller_register(dev, &data->rcdev);
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static struct platform_driver stm32_reset_driver = {
|
|
||||||
- .probe = stm32_reset_probe,
|
|
||||||
- .driver = {
|
|
||||||
- .name = "stm32mp1-reset",
|
|
||||||
- .of_match_table = stm32_reset_dt_ids,
|
|
||||||
- },
|
|
||||||
-};
|
|
||||||
-
|
|
||||||
-builtin_platform_driver(stm32_reset_driver);
|
|
||||||
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
|
|
||||||
index 33e4ecd6c..65619e077 100644
|
|
||||||
--- a/drivers/rtc/Kconfig
|
|
||||||
+++ b/drivers/rtc/Kconfig
|
|
||||||
@@ -1885,6 +1885,7 @@ config RTC_DRV_R7301
|
|
||||||
config RTC_DRV_STM32
|
|
||||||
tristate "STM32 RTC"
|
|
||||||
select REGMAP_MMIO
|
|
||||||
+ depends on COMMON_CLK
|
|
||||||
depends on ARCH_STM32 || COMPILE_TEST
|
|
||||||
help
|
|
||||||
If you say yes here you get support for the STM32 On-Chip
|
|
||||||
diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c
|
|
||||||
index d096b58cd..ffab177ed 100644
|
|
||||||
--- a/drivers/rtc/rtc-stm32.c
|
|
||||||
+++ b/drivers/rtc/rtc-stm32.c
|
|
||||||
@@ -6,6 +6,8 @@
|
|
||||||
|
|
||||||
#include <linux/bcd.h>
|
|
||||||
#include <linux/clk.h>
|
|
||||||
+#include <linux/clk-provider.h>
|
|
||||||
+#include <linux/errno.h>
|
|
||||||
#include <linux/iopoll.h>
|
|
||||||
#include <linux/ioport.h>
|
|
||||||
#include <linux/mfd/syscon.h>
|
|
||||||
@@ -15,6 +17,8 @@
|
|
||||||
#include <linux/regmap.h>
|
|
||||||
#include <linux/rtc.h>
|
|
||||||
|
|
||||||
+#include <dt-bindings/rtc/rtc-stm32.h>
|
|
||||||
+
|
|
||||||
#define DRIVER_NAME "stm32_rtc"
|
|
||||||
|
|
||||||
/* STM32_RTC_TR bit fields */
|
|
||||||
@@ -39,6 +43,12 @@
|
|
||||||
#define STM32_RTC_CR_FMT BIT(6)
|
|
||||||
#define STM32_RTC_CR_ALRAE BIT(8)
|
|
||||||
#define STM32_RTC_CR_ALRAIE BIT(12)
|
|
||||||
+#define STM32_RTC_CR_COSEL BIT(19)
|
|
||||||
+#define STM32_RTC_CR_OSEL_SHIFT 21
|
|
||||||
+#define STM32_RTC_CR_OSEL GENMASK(22, 21)
|
|
||||||
+#define STM32_RTC_CR_COE BIT(23)
|
|
||||||
+#define STM32_RTC_CR_TAMPOE BIT(26)
|
|
||||||
+#define STM32_RTC_CR_OUT2EN BIT(31)
|
|
||||||
|
|
||||||
/* STM32_RTC_ISR/STM32_RTC_ICSR bit fields */
|
|
||||||
#define STM32_RTC_ISR_ALRAWF BIT(0)
|
|
||||||
@@ -75,6 +85,11 @@
|
|
||||||
/* STM32_RTC_SR/_SCR bit fields */
|
|
||||||
#define STM32_RTC_SR_ALRA BIT(0)
|
|
||||||
|
|
||||||
+/* STM32_RTC_CFGR bit fields */
|
|
||||||
+#define STM32_RTC_CFGR_OUT2_RMP BIT(0)
|
|
||||||
+#define STM32_RTC_CFGR_LSCOEN_OUT1 1
|
|
||||||
+#define STM32_RTC_CFGR_LSCOEN_OUT2_RMP 2
|
|
||||||
+
|
|
||||||
/* STM32_RTC_VERR bit fields */
|
|
||||||
#define STM32_RTC_VERR_MINREV_SHIFT 0
|
|
||||||
#define STM32_RTC_VERR_MINREV GENMASK(3, 0)
|
|
||||||
@@ -101,6 +116,7 @@ struct stm32_rtc_registers {
|
|
||||||
u16 wpr;
|
|
||||||
u16 sr;
|
|
||||||
u16 scr;
|
|
||||||
+ u16 cfgr;
|
|
||||||
u16 verr;
|
|
||||||
};
|
|
||||||
|
|
||||||
@@ -114,7 +130,8 @@ struct stm32_rtc_data {
|
|
||||||
void (*clear_events)(struct stm32_rtc *rtc, unsigned int flags);
|
|
||||||
bool has_pclk;
|
|
||||||
bool need_dbp;
|
|
||||||
- bool has_wakeirq;
|
|
||||||
+ bool has_lsco;
|
|
||||||
+ bool need_accuracy;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct stm32_rtc {
|
|
||||||
@@ -127,9 +144,87 @@ struct stm32_rtc {
|
|
||||||
struct clk *rtc_ck;
|
|
||||||
const struct stm32_rtc_data *data;
|
|
||||||
int irq_alarm;
|
|
||||||
- int wakeirq_alarm;
|
|
||||||
+ int lsco;
|
|
||||||
+ struct clk *clk_lsco;
|
|
||||||
};
|
|
||||||
|
|
||||||
+/*
|
|
||||||
+ * -------------------------------------------------------------------------
|
|
||||||
+ * | TAMPOE | OSEL[1:0] | COE | OUT2EN | RTC_OUT1 | RTC_OUT2 |
|
|
||||||
+ * | | | | | | or RTC_OUT2_RMP |
|
|
||||||
+ * |-------------------------------------------------------------------------|
|
|
||||||
+ * | 0 | 00 | 0 | 0 or 1 | - | - |
|
|
||||||
+ * |--------|-----------|-----|--------|------------------|------------------|
|
|
||||||
+ * | 0 | 00 | 1 | 0 | CALIB | - |
|
|
||||||
+ * |--------|-----------|-----|--------|------------------|------------------|
|
|
||||||
+ * | 0 or 1 | !=00 | 0 | 0 | TAMPALRM | - |
|
|
||||||
+ * |--------|-----------|-----|--------|------------------|------------------|
|
|
||||||
+ * | 0 | 00 | 1 | 1 | - | CALIB |
|
|
||||||
+ * |--------|-----------|-----|--------|------------------|------------------|
|
|
||||||
+ * | 0 or 1 | !=00 | 0 | 1 | - | TAMPALRM |
|
|
||||||
+ * |--------|-----------|-----|--------|------------------|------------------|
|
|
||||||
+ * | 0 or 1 | !=00 | 1 | 1 | TAMPALRM | CALIB |
|
|
||||||
+ * -------------------------------------------------------------------------
|
|
||||||
+ */
|
|
||||||
+static int stm32_rtc_clk_lsco_check_availability(struct stm32_rtc *rtc)
|
|
||||||
+{
|
|
||||||
+ struct stm32_rtc_registers regs = rtc->data->regs;
|
|
||||||
+ unsigned int cr = readl_relaxed(rtc->base + regs.cr);
|
|
||||||
+ unsigned int cfgr = readl_relaxed(rtc->base + regs.cfgr);
|
|
||||||
+ unsigned int calib = STM32_RTC_CR_COE;
|
|
||||||
+ unsigned int tampalrm = STM32_RTC_CR_TAMPOE | STM32_RTC_CR_OSEL;
|
|
||||||
+
|
|
||||||
+ switch (rtc->lsco) {
|
|
||||||
+ case RTC_OUT1:
|
|
||||||
+ if ((!(cr & STM32_RTC_CR_OUT2EN) &&
|
|
||||||
+ ((cr & calib) || cr & tampalrm)) ||
|
|
||||||
+ ((cr & calib) && (cr & tampalrm)))
|
|
||||||
+ return -EBUSY;
|
|
||||||
+ break;
|
|
||||||
+ case RTC_OUT2_RMP:
|
|
||||||
+ if ((cr & STM32_RTC_CR_OUT2EN) &&
|
|
||||||
+ (cfgr & STM32_RTC_CFGR_OUT2_RMP) &&
|
|
||||||
+ ((cr & calib) || (cr & tampalrm)))
|
|
||||||
+ return -EBUSY;
|
|
||||||
+ break;
|
|
||||||
+ default:
|
|
||||||
+ return -EINVAL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (clk_get_rate(rtc->rtc_ck) != 32768)
|
|
||||||
+ return -ERANGE;
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int stm32_rtc_clk_lsco_register(struct platform_device *pdev)
|
|
||||||
+{
|
|
||||||
+ struct stm32_rtc *rtc = platform_get_drvdata(pdev);
|
|
||||||
+ struct stm32_rtc_registers regs = rtc->data->regs;
|
|
||||||
+ u8 lscoen;
|
|
||||||
+ int ret;
|
|
||||||
+
|
|
||||||
+ ret = stm32_rtc_clk_lsco_check_availability(rtc);
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
+ lscoen = (rtc->lsco == RTC_OUT1) ? STM32_RTC_CFGR_LSCOEN_OUT1 :
|
|
||||||
+ STM32_RTC_CFGR_LSCOEN_OUT2_RMP;
|
|
||||||
+
|
|
||||||
+ rtc->clk_lsco = clk_register_gate(&pdev->dev, "rtc_lsco",
|
|
||||||
+ __clk_get_name(rtc->rtc_ck),
|
|
||||||
+ CLK_IGNORE_UNUSED | CLK_IS_CRITICAL,
|
|
||||||
+ rtc->base + regs.cfgr, lscoen,
|
|
||||||
+ 0, NULL);
|
|
||||||
+ if (IS_ERR(rtc->clk_lsco))
|
|
||||||
+ return PTR_ERR(rtc->clk_lsco);
|
|
||||||
+
|
|
||||||
+ of_clk_add_provider(pdev->dev.of_node,
|
|
||||||
+ of_clk_src_simple_get, rtc->clk_lsco);
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static void stm32_rtc_wpr_unlock(struct stm32_rtc *rtc)
|
|
||||||
{
|
|
||||||
const struct stm32_rtc_registers *regs = &rtc->data->regs;
|
|
||||||
@@ -160,10 +255,9 @@ static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)
|
|
||||||
* slowest rtc_ck frequency may be 32kHz and highest should be
|
|
||||||
* 1MHz, we poll every 10 us with a timeout of 100ms.
|
|
||||||
*/
|
|
||||||
- return readl_relaxed_poll_timeout_atomic(
|
|
||||||
- rtc->base + regs->isr,
|
|
||||||
- isr, (isr & STM32_RTC_ISR_INITF),
|
|
||||||
- 10, 100000);
|
|
||||||
+ return readl_relaxed_poll_timeout_atomic(rtc->base + regs->isr, isr,
|
|
||||||
+ (isr & STM32_RTC_ISR_INITF),
|
|
||||||
+ 10, 100000);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
@@ -448,16 +542,16 @@ static int stm32_rtc_valid_alrm(struct stm32_rtc *rtc, struct rtc_time *tm)
|
|
||||||
* M-D-Y H:M:S < alarm <= (M+1)-D-Y H:M:S
|
|
||||||
* with a specific case for December...
|
|
||||||
*/
|
|
||||||
- if ((((tm->tm_year > cur_year) &&
|
|
||||||
- (tm->tm_mon == 0x1) && (cur_mon == 0x12)) ||
|
|
||||||
- ((tm->tm_year == cur_year) &&
|
|
||||||
- (tm->tm_mon <= cur_mon + 1))) &&
|
|
||||||
- ((tm->tm_mday > cur_day) ||
|
|
||||||
- ((tm->tm_mday == cur_day) &&
|
|
||||||
- ((tm->tm_hour > cur_hour) ||
|
|
||||||
- ((tm->tm_hour == cur_hour) && (tm->tm_min > cur_min)) ||
|
|
||||||
- ((tm->tm_hour == cur_hour) && (tm->tm_min == cur_min) &&
|
|
||||||
- (tm->tm_sec >= cur_sec))))))
|
|
||||||
+ if (((tm->tm_year > cur_year &&
|
|
||||||
+ tm->tm_mon == 0x1 && cur_mon == 0x12) ||
|
|
||||||
+ (tm->tm_year == cur_year &&
|
|
||||||
+ tm->tm_mon <= cur_mon + 1)) &&
|
|
||||||
+ (tm->tm_mday > cur_day ||
|
|
||||||
+ (tm->tm_mday == cur_day &&
|
|
||||||
+ (tm->tm_hour > cur_hour ||
|
|
||||||
+ (tm->tm_hour == cur_hour && tm->tm_min > cur_min) ||
|
|
||||||
+ (tm->tm_hour == cur_hour && tm->tm_min == cur_min &&
|
|
||||||
+ tm->tm_sec >= cur_sec)))))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return -EINVAL;
|
|
||||||
@@ -547,7 +641,8 @@ static void stm32_rtc_clear_events(struct stm32_rtc *rtc,
|
|
||||||
static const struct stm32_rtc_data stm32_rtc_data = {
|
|
||||||
.has_pclk = false,
|
|
||||||
.need_dbp = true,
|
|
||||||
- .has_wakeirq = false,
|
|
||||||
+ .has_lsco = false,
|
|
||||||
+ .need_accuracy = false,
|
|
||||||
.regs = {
|
|
||||||
.tr = 0x00,
|
|
||||||
.dr = 0x04,
|
|
||||||
@@ -558,6 +653,7 @@ static const struct stm32_rtc_data stm32_rtc_data = {
|
|
||||||
.wpr = 0x24,
|
|
||||||
.sr = 0x0C, /* set to ISR offset to ease alarm management */
|
|
||||||
.scr = UNDEF_REG,
|
|
||||||
+ .cfgr = UNDEF_REG,
|
|
||||||
.verr = UNDEF_REG,
|
|
||||||
},
|
|
||||||
.events = {
|
|
||||||
@@ -569,7 +665,8 @@ static const struct stm32_rtc_data stm32_rtc_data = {
|
|
||||||
static const struct stm32_rtc_data stm32h7_rtc_data = {
|
|
||||||
.has_pclk = true,
|
|
||||||
.need_dbp = true,
|
|
||||||
- .has_wakeirq = false,
|
|
||||||
+ .has_lsco = false,
|
|
||||||
+ .need_accuracy = false,
|
|
||||||
.regs = {
|
|
||||||
.tr = 0x00,
|
|
||||||
.dr = 0x04,
|
|
||||||
@@ -580,6 +677,7 @@ static const struct stm32_rtc_data stm32h7_rtc_data = {
|
|
||||||
.wpr = 0x24,
|
|
||||||
.sr = 0x0C, /* set to ISR offset to ease alarm management */
|
|
||||||
.scr = UNDEF_REG,
|
|
||||||
+ .cfgr = UNDEF_REG,
|
|
||||||
.verr = UNDEF_REG,
|
|
||||||
},
|
|
||||||
.events = {
|
|
||||||
@@ -600,7 +698,8 @@ static void stm32mp1_rtc_clear_events(struct stm32_rtc *rtc,
|
|
||||||
static const struct stm32_rtc_data stm32mp1_data = {
|
|
||||||
.has_pclk = true,
|
|
||||||
.need_dbp = false,
|
|
||||||
- .has_wakeirq = true,
|
|
||||||
+ .has_lsco = true,
|
|
||||||
+ .need_accuracy = true,
|
|
||||||
.regs = {
|
|
||||||
.tr = 0x00,
|
|
||||||
.dr = 0x04,
|
|
||||||
@@ -611,6 +710,7 @@ static const struct stm32_rtc_data stm32mp1_data = {
|
|
||||||
.wpr = 0x24,
|
|
||||||
.sr = 0x50,
|
|
||||||
.scr = 0x5C,
|
|
||||||
+ .cfgr = 0x60,
|
|
||||||
.verr = 0x3F4,
|
|
||||||
},
|
|
||||||
.events = {
|
|
||||||
@@ -641,18 +741,32 @@ static int stm32_rtc_init(struct platform_device *pdev,
|
|
||||||
pred_a_max = STM32_RTC_PRER_PRED_A >> STM32_RTC_PRER_PRED_A_SHIFT;
|
|
||||||
pred_s_max = STM32_RTC_PRER_PRED_S >> STM32_RTC_PRER_PRED_S_SHIFT;
|
|
||||||
|
|
||||||
- for (pred_a = pred_a_max; pred_a + 1 > 0; pred_a--) {
|
|
||||||
- pred_s = (rate / (pred_a + 1)) - 1;
|
|
||||||
+ if (rate > (pred_a_max + 1) * (pred_s_max + 1)) {
|
|
||||||
+ dev_err(&pdev->dev, "rtc_ck rate is too high: %dHz\n", rate);
|
|
||||||
+ return -EINVAL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (rtc->data->need_accuracy) {
|
|
||||||
+ for (pred_a = 0; pred_a <= pred_a_max; pred_a++) {
|
|
||||||
+ pred_s = (rate / (pred_a + 1)) - 1;
|
|
||||||
|
|
||||||
- if (((pred_s + 1) * (pred_a + 1)) == rate)
|
|
||||||
- break;
|
|
||||||
+ if (pred_s <= pred_s_max && ((pred_s + 1) * (pred_a + 1)) == rate)
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ } else {
|
|
||||||
+ for (pred_a = pred_a_max; pred_a + 1 > 0; pred_a--) {
|
|
||||||
+ pred_s = (rate / (pred_a + 1)) - 1;
|
|
||||||
+
|
|
||||||
+ if (((pred_s + 1) * (pred_a + 1)) == rate)
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Can't find a 1Hz, so give priority to RTC power consumption
|
|
||||||
* by choosing the higher possible value for prediv_a
|
|
||||||
*/
|
|
||||||
- if ((pred_s > pred_s_max) || (pred_a > pred_a_max)) {
|
|
||||||
+ if (pred_s > pred_s_max || pred_a > pred_a_max) {
|
|
||||||
pred_a = pred_a_max;
|
|
||||||
pred_s = (rate / (pred_a + 1)) - 1;
|
|
||||||
|
|
||||||
@@ -736,13 +850,15 @@ static int stm32_rtc_probe(struct platform_device *pdev)
|
|
||||||
} else {
|
|
||||||
rtc->pclk = devm_clk_get(&pdev->dev, "pclk");
|
|
||||||
if (IS_ERR(rtc->pclk)) {
|
|
||||||
- dev_err(&pdev->dev, "no pclk clock");
|
|
||||||
+ if (PTR_ERR(rtc->pclk) != -EPROBE_DEFER)
|
|
||||||
+ dev_err(&pdev->dev, "no pclk clock");
|
|
||||||
return PTR_ERR(rtc->pclk);
|
|
||||||
}
|
|
||||||
rtc->rtc_ck = devm_clk_get(&pdev->dev, "rtc_ck");
|
|
||||||
}
|
|
||||||
if (IS_ERR(rtc->rtc_ck)) {
|
|
||||||
- dev_err(&pdev->dev, "no rtc_ck clock");
|
|
||||||
+ if (PTR_ERR(rtc->rtc_ck) != -EPROBE_DEFER)
|
|
||||||
+ dev_err(&pdev->dev, "no rtc_ck clock");
|
|
||||||
return PTR_ERR(rtc->rtc_ck);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -779,19 +895,12 @@ static int stm32_rtc_probe(struct platform_device *pdev)
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = device_init_wakeup(&pdev->dev, true);
|
|
||||||
- if (rtc->data->has_wakeirq) {
|
|
||||||
- rtc->wakeirq_alarm = platform_get_irq(pdev, 1);
|
|
||||||
- if (rtc->wakeirq_alarm > 0) {
|
|
||||||
- ret = dev_pm_set_dedicated_wake_irq(&pdev->dev,
|
|
||||||
- rtc->wakeirq_alarm);
|
|
||||||
- } else {
|
|
||||||
- ret = rtc->wakeirq_alarm;
|
|
||||||
- if (rtc->wakeirq_alarm == -EPROBE_DEFER)
|
|
||||||
- goto err;
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
if (ret)
|
|
||||||
- dev_warn(&pdev->dev, "alarm can't wake up the system: %d", ret);
|
|
||||||
+ goto err;
|
|
||||||
+
|
|
||||||
+ ret = dev_pm_set_wake_irq(&pdev->dev, rtc->irq_alarm);
|
|
||||||
+ if (ret)
|
|
||||||
+ goto err;
|
|
||||||
|
|
||||||
platform_set_drvdata(pdev, rtc);
|
|
||||||
|
|
||||||
@@ -814,6 +923,21 @@ static int stm32_rtc_probe(struct platform_device *pdev)
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ if (rtc->data->has_lsco) {
|
|
||||||
+ ret = of_property_read_s32(pdev->dev.of_node,
|
|
||||||
+ "st,lsco", &rtc->lsco);
|
|
||||||
+ if (!ret) {
|
|
||||||
+ ret = stm32_rtc_clk_lsco_register(pdev);
|
|
||||||
+ if (ret)
|
|
||||||
+ dev_warn(&pdev->dev,
|
|
||||||
+ "LSCO clock registration failed: %d\n",
|
|
||||||
+ ret);
|
|
||||||
+ } else {
|
|
||||||
+ rtc->lsco = ret;
|
|
||||||
+ dev_dbg(&pdev->dev, "No LSCO clock: %d\n", ret);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* If INITS flag is reset (calendar year field set to 0x00), calendar
|
|
||||||
* must be initialized
|
|
||||||
@@ -852,6 +976,9 @@ static int stm32_rtc_remove(struct platform_device *pdev)
|
|
||||||
const struct stm32_rtc_registers *regs = &rtc->data->regs;
|
|
||||||
unsigned int cr;
|
|
||||||
|
|
||||||
+ if (!IS_ERR_OR_NULL(rtc->clk_lsco))
|
|
||||||
+ clk_unregister_gate(rtc->clk_lsco);
|
|
||||||
+
|
|
||||||
/* Disable interrupts */
|
|
||||||
stm32_rtc_wpr_unlock(rtc);
|
|
||||||
cr = readl_relaxed(rtc->base + regs->cr);
|
|
||||||
@@ -881,9 +1008,6 @@ static int stm32_rtc_suspend(struct device *dev)
|
|
||||||
if (rtc->data->has_pclk)
|
|
||||||
clk_disable_unprepare(rtc->pclk);
|
|
||||||
|
|
||||||
- if (device_may_wakeup(dev))
|
|
||||||
- return enable_irq_wake(rtc->irq_alarm);
|
|
||||||
-
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -905,15 +1029,13 @@ static int stm32_rtc_resume(struct device *dev)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (device_may_wakeup(dev))
|
|
||||||
- return disable_irq_wake(rtc->irq_alarm);
|
|
||||||
-
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
-static SIMPLE_DEV_PM_OPS(stm32_rtc_pm_ops,
|
|
||||||
- stm32_rtc_suspend, stm32_rtc_resume);
|
|
||||||
+static const struct dev_pm_ops stm32_rtc_pm_ops = {
|
|
||||||
+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(stm32_rtc_suspend, stm32_rtc_resume)
|
|
||||||
+};
|
|
||||||
|
|
||||||
static struct platform_driver stm32_rtc_driver = {
|
|
||||||
.probe = stm32_rtc_probe,
|
|
||||||
diff --git a/drivers/watchdog/stm32_iwdg.c b/drivers/watchdog/stm32_iwdg.c
|
|
||||||
index 25188d6bb..a3436c296 100644
|
|
||||||
--- a/drivers/watchdog/stm32_iwdg.c
|
|
||||||
+++ b/drivers/watchdog/stm32_iwdg.c
|
|
||||||
@@ -162,18 +162,15 @@ static int stm32_iwdg_clk_init(struct platform_device *pdev,
|
|
||||||
u32 ret;
|
|
||||||
|
|
||||||
wdt->clk_lsi = devm_clk_get(dev, "lsi");
|
|
||||||
- if (IS_ERR(wdt->clk_lsi)) {
|
|
||||||
- dev_err(dev, "Unable to get lsi clock\n");
|
|
||||||
- return PTR_ERR(wdt->clk_lsi);
|
|
||||||
- }
|
|
||||||
+ if (IS_ERR(wdt->clk_lsi))
|
|
||||||
+ return dev_err_probe(dev, PTR_ERR(wdt->clk_lsi), "Unable to get lsi clock\n");
|
|
||||||
|
|
||||||
/* optional peripheral clock */
|
|
||||||
if (wdt->data->has_pclk) {
|
|
||||||
wdt->clk_pclk = devm_clk_get(dev, "pclk");
|
|
||||||
- if (IS_ERR(wdt->clk_pclk)) {
|
|
||||||
- dev_err(dev, "Unable to get pclk clock\n");
|
|
||||||
- return PTR_ERR(wdt->clk_pclk);
|
|
||||||
- }
|
|
||||||
+ if (IS_ERR(wdt->clk_pclk))
|
|
||||||
+ return dev_err_probe(dev, PTR_ERR(wdt->clk_pclk),
|
|
||||||
+ "Unable to get pclk clock\n");
|
|
||||||
|
|
||||||
ret = clk_prepare_enable(wdt->clk_pclk);
|
|
||||||
if (ret) {
|
|
||||||
diff --git a/include/dt-bindings/reset/stm32mp1-resets.h b/include/dt-bindings/reset/stm32mp1-resets.h
|
|
||||||
index f0c3aaef6..f3a0ed317 100644
|
|
||||||
--- a/include/dt-bindings/reset/stm32mp1-resets.h
|
|
||||||
+++ b/include/dt-bindings/reset/stm32mp1-resets.h
|
|
||||||
@@ -7,6 +7,7 @@
|
|
||||||
#ifndef _DT_BINDINGS_STM32MP1_RESET_H_
|
|
||||||
#define _DT_BINDINGS_STM32MP1_RESET_H_
|
|
||||||
|
|
||||||
+#define MCU_HOLD_BOOT_R 2144
|
|
||||||
#define LTDC_R 3072
|
|
||||||
#define DSI_R 3076
|
|
||||||
#define DDRPERFM_R 3080
|
|
||||||
@@ -105,4 +106,18 @@
|
|
||||||
#define GPIOJ_R 19785
|
|
||||||
#define GPIOK_R 19786
|
|
||||||
|
|
||||||
+/* SCMI reset domain identifiers */
|
|
||||||
+#define RST_SCMI0_SPI6 0
|
|
||||||
+#define RST_SCMI0_I2C4 1
|
|
||||||
+#define RST_SCMI0_I2C6 2
|
|
||||||
+#define RST_SCMI0_USART1 3
|
|
||||||
+#define RST_SCMI0_STGEN 4
|
|
||||||
+#define RST_SCMI0_GPIOZ 5
|
|
||||||
+#define RST_SCMI0_CRYP1 6
|
|
||||||
+#define RST_SCMI0_HASH1 7
|
|
||||||
+#define RST_SCMI0_RNG1 8
|
|
||||||
+#define RST_SCMI0_MDMA 9
|
|
||||||
+#define RST_SCMI0_MCU 10
|
|
||||||
+#define RST_SCMI0_MCU_HOLD_BOOT 11
|
|
||||||
+
|
|
||||||
#endif /* _DT_BINDINGS_STM32MP1_RESET_H_ */
|
|
||||||
diff --git a/include/dt-bindings/rtc/rtc-stm32.h b/include/dt-bindings/rtc/rtc-stm32.h
|
|
||||||
new file mode 100644
|
|
||||||
index 000000000..4373c4dea
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/include/dt-bindings/rtc/rtc-stm32.h
|
|
||||||
@@ -0,0 +1,13 @@
|
|
||||||
+/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
+/*
|
|
||||||
+ * This header provides constants for STM32_RTC bindings.
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+#ifndef _DT_BINDINGS_RTC_RTC_STM32_H
|
|
||||||
+#define _DT_BINDINGS_RTC_RTC_STM32_H
|
|
||||||
+
|
|
||||||
+#define RTC_OUT1 0
|
|
||||||
+#define RTC_OUT2 1
|
|
||||||
+#define RTC_OUT2_RMP 2
|
|
||||||
+
|
|
||||||
+#endif
|
|
||||||
--
|
|
||||||
2.17.1
|
|
||||||
|
|
||||||
|
|
@ -1,131 +0,0 @@
|
||||||
From 03fe6061e18768eee7b247999cecaad2280098cf Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lionel Vitte <lionel.vitte@st.com>
|
|
||||||
Date: Thu, 14 Oct 2021 16:51:51 +0200
|
|
||||||
Subject: [PATCH 18/23] ARM 5.10.61-stm32mp1-r2 SCMI
|
|
||||||
|
|
||||||
---
|
|
||||||
drivers/firmware/arm_scmi/base.c | 2 +-
|
|
||||||
drivers/firmware/arm_scmi/bus.c | 9 ---------
|
|
||||||
drivers/firmware/arm_scmi/clock.c | 2 +-
|
|
||||||
drivers/firmware/arm_scmi/common.h | 2 ++
|
|
||||||
drivers/firmware/arm_scmi/driver.c | 10 ++++++++++
|
|
||||||
drivers/firmware/arm_scmi/perf.c | 2 +-
|
|
||||||
drivers/firmware/arm_scmi/sensors.c | 2 +-
|
|
||||||
7 files changed, 16 insertions(+), 13 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/firmware/arm_scmi/base.c b/drivers/firmware/arm_scmi/base.c
|
|
||||||
index 017e5d8bd..a70b10eba 100644
|
|
||||||
--- a/drivers/firmware/arm_scmi/base.c
|
|
||||||
+++ b/drivers/firmware/arm_scmi/base.c
|
|
||||||
@@ -183,7 +183,7 @@ static int scmi_base_implementation_list_get(const struct scmi_handle *handle,
|
|
||||||
/* Set the number of protocols to be skipped/already read */
|
|
||||||
*num_skip = cpu_to_le32(tot_num_ret);
|
|
||||||
|
|
||||||
- ret = scmi_do_xfer(handle, t);
|
|
||||||
+ ret = scmi_do_xfer_again(handle, t);
|
|
||||||
if (ret)
|
|
||||||
break;
|
|
||||||
|
|
||||||
diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c
|
|
||||||
index def8a84d1..33d1a6c79 100644
|
|
||||||
--- a/drivers/firmware/arm_scmi/bus.c
|
|
||||||
+++ b/drivers/firmware/arm_scmi/bus.c
|
|
||||||
@@ -60,11 +60,6 @@ static int scmi_protocol_init(int protocol_id, struct scmi_handle *handle)
|
|
||||||
return fn(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int scmi_protocol_dummy_init(struct scmi_handle *handle)
|
|
||||||
-{
|
|
||||||
- return 0;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
static int scmi_dev_probe(struct device *dev)
|
|
||||||
{
|
|
||||||
struct scmi_driver *scmi_drv = to_scmi_driver(dev->driver);
|
|
||||||
@@ -83,10 +78,6 @@ static int scmi_dev_probe(struct device *dev)
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
- /* Skip protocol initialisation for additional devices */
|
|
||||||
- idr_replace(&scmi_protocols, &scmi_protocol_dummy_init,
|
|
||||||
- scmi_dev->protocol_id);
|
|
||||||
-
|
|
||||||
return scmi_drv->probe(scmi_dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/clock.c
|
|
||||||
index 4645677d8..c348a6f2e 100644
|
|
||||||
--- a/drivers/firmware/arm_scmi/clock.c
|
|
||||||
+++ b/drivers/firmware/arm_scmi/clock.c
|
|
||||||
@@ -161,7 +161,7 @@ scmi_clock_describe_rates_get(const struct scmi_handle *handle, u32 clk_id,
|
|
||||||
/* Set the number of rates to be skipped/already read */
|
|
||||||
clk_desc->rate_index = cpu_to_le32(tot_rate_cnt);
|
|
||||||
|
|
||||||
- ret = scmi_do_xfer(handle, t);
|
|
||||||
+ ret = scmi_do_xfer_again(handle, t);
|
|
||||||
if (ret)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
|
|
||||||
index 34b7ae798..9fa5c0022 100644
|
|
||||||
--- a/drivers/firmware/arm_scmi/common.h
|
|
||||||
+++ b/drivers/firmware/arm_scmi/common.h
|
|
||||||
@@ -143,6 +143,8 @@ struct scmi_xfer {
|
|
||||||
|
|
||||||
void scmi_xfer_put(const struct scmi_handle *h, struct scmi_xfer *xfer);
|
|
||||||
int scmi_do_xfer(const struct scmi_handle *h, struct scmi_xfer *xfer);
|
|
||||||
+int scmi_do_xfer_again(const struct scmi_handle *handle,
|
|
||||||
+ struct scmi_xfer *xfer);
|
|
||||||
int scmi_do_xfer_with_response(const struct scmi_handle *h,
|
|
||||||
struct scmi_xfer *xfer);
|
|
||||||
int scmi_xfer_get_init(const struct scmi_handle *h, u8 msg_id, u8 prot_id,
|
|
||||||
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
|
|
||||||
index 763223248..2b3ce604f 100644
|
|
||||||
--- a/drivers/firmware/arm_scmi/driver.c
|
|
||||||
+++ b/drivers/firmware/arm_scmi/driver.c
|
|
||||||
@@ -415,6 +415,16 @@ void scmi_reset_rx_to_maxsz(const struct scmi_handle *handle,
|
|
||||||
xfer->rx.len = info->desc->max_msg_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
+int scmi_do_xfer_again(const struct scmi_handle *handle, struct scmi_xfer *xfer)
|
|
||||||
+{
|
|
||||||
+ struct scmi_info *info = handle_to_scmi_info(handle);
|
|
||||||
+
|
|
||||||
+ xfer->rx.len = info->desc->max_msg_size;
|
|
||||||
+ xfer->hdr.poll_completion = false;
|
|
||||||
+
|
|
||||||
+ return scmi_do_xfer(handle, xfer);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
#define SCMI_MAX_RESPONSE_TIMEOUT (2 * MSEC_PER_SEC)
|
|
||||||
|
|
||||||
/**
|
|
||||||
diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c
|
|
||||||
index 82fb3babf..7bea0f646 100644
|
|
||||||
--- a/drivers/firmware/arm_scmi/perf.c
|
|
||||||
+++ b/drivers/firmware/arm_scmi/perf.c
|
|
||||||
@@ -281,7 +281,7 @@ scmi_perf_describe_levels_get(const struct scmi_handle *handle, u32 domain,
|
|
||||||
/* Set the number of OPPs to be skipped/already read */
|
|
||||||
dom_info->level_index = cpu_to_le32(tot_opp_cnt);
|
|
||||||
|
|
||||||
- ret = scmi_do_xfer(handle, t);
|
|
||||||
+ ret = scmi_do_xfer_again(handle, t);
|
|
||||||
if (ret)
|
|
||||||
break;
|
|
||||||
|
|
||||||
diff --git a/drivers/firmware/arm_scmi/sensors.c b/drivers/firmware/arm_scmi/sensors.c
|
|
||||||
index b4232d611..6dae881be 100644
|
|
||||||
--- a/drivers/firmware/arm_scmi/sensors.c
|
|
||||||
+++ b/drivers/firmware/arm_scmi/sensors.c
|
|
||||||
@@ -134,7 +134,7 @@ static int scmi_sensor_description_get(const struct scmi_handle *handle,
|
|
||||||
/* Set the number of sensors to be skipped/already read */
|
|
||||||
put_unaligned_le32(desc_index, t->tx.buf);
|
|
||||||
|
|
||||||
- ret = scmi_do_xfer(handle, t);
|
|
||||||
+ ret = scmi_do_xfer_again(handle, t);
|
|
||||||
if (ret)
|
|
||||||
break;
|
|
||||||
|
|
||||||
--
|
|
||||||
2.17.1
|
|
||||||
|
|
||||||
|
|
@ -1,717 +0,0 @@
|
||||||
From e8a701ceba6fdf12989b38212c510bfdfea5c830 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lionel Vitte <lionel.vitte@st.com>
|
|
||||||
Date: Thu, 14 Oct 2021 16:51:51 +0200
|
|
||||||
Subject: [PATCH 19/23] ARM 5.10.61-stm32mp1-r2 SOUND
|
|
||||||
|
|
||||||
---
|
|
||||||
sound/soc/codecs/Kconfig | 2 +-
|
|
||||||
sound/soc/codecs/wm8994.c | 81 ++++++++-
|
|
||||||
sound/soc/stm/stm32_adfsdm.c | 11 +-
|
|
||||||
sound/soc/stm/stm32_i2s.c | 316 +++++++++++++++++++++++++++++-----
|
|
||||||
sound/soc/stm/stm32_sai_sub.c | 4 +-
|
|
||||||
sound/soc/stm/stm32_spdifrx.c | 4 +
|
|
||||||
6 files changed, 361 insertions(+), 57 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
|
|
||||||
index 34c6dd04b..3afc5d1f0 100644
|
|
||||||
--- a/sound/soc/codecs/Kconfig
|
|
||||||
+++ b/sound/soc/codecs/Kconfig
|
|
||||||
@@ -1642,7 +1642,7 @@ config SND_SOC_WM8993
|
|
||||||
depends on I2C
|
|
||||||
|
|
||||||
config SND_SOC_WM8994
|
|
||||||
- tristate
|
|
||||||
+ tristate "Wolfson Microelectronics WM8994 codec"
|
|
||||||
|
|
||||||
config SND_SOC_WM8995
|
|
||||||
tristate
|
|
||||||
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
|
|
||||||
index f57884113..6d30b438b 100644
|
|
||||||
--- a/sound/soc/codecs/wm8994.c
|
|
||||||
+++ b/sound/soc/codecs/wm8994.c
|
|
||||||
@@ -7,6 +7,7 @@
|
|
||||||
* Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
+#include <linux/clk.h>
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/moduleparam.h>
|
|
||||||
#include <linux/init.h>
|
|
||||||
@@ -838,6 +839,37 @@ static int clk_sys_event(struct snd_soc_dapm_widget *w,
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static int mclk_event(struct snd_soc_dapm_widget *w,
|
|
||||||
+ struct snd_kcontrol *kcontrol, int event)
|
|
||||||
+{
|
|
||||||
+ struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
|
|
||||||
+ struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(comp);
|
|
||||||
+ int ret, mclk_id = 0;
|
|
||||||
+
|
|
||||||
+ if (!strncmp(w->name, "MCLK2", 5))
|
|
||||||
+ mclk_id = 1;
|
|
||||||
+
|
|
||||||
+ switch (event) {
|
|
||||||
+ case SND_SOC_DAPM_PRE_PMU:
|
|
||||||
+ dev_dbg(comp->dev, "Enable master clock %s\n",
|
|
||||||
+ mclk_id ? "MCLK2" : "MCLK1");
|
|
||||||
+
|
|
||||||
+ ret = clk_prepare_enable(wm8994->mclk[mclk_id].clk);
|
|
||||||
+ if (ret < 0) {
|
|
||||||
+ dev_err(comp->dev, "Failed to enable clock: %d\n", ret);
|
|
||||||
+ return ret;
|
|
||||||
+ }
|
|
||||||
+ break;
|
|
||||||
+ case SND_SOC_DAPM_POST_PMD:
|
|
||||||
+ dev_dbg(comp->dev, "Disable master clock %s\n",
|
|
||||||
+ mclk_id ? "MCLK2" : "MCLK1");
|
|
||||||
+ clk_disable_unprepare(wm8994->mclk[mclk_id].clk);
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static void vmid_reference(struct snd_soc_component *component)
|
|
||||||
{
|
|
||||||
struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
|
|
||||||
@@ -1225,7 +1257,6 @@ static int aif2clk_ev(struct snd_soc_dapm_widget *w,
|
|
||||||
else
|
|
||||||
adc = WM8994_AIF2ADCL_ENA | WM8994_AIF2ADCR_ENA;
|
|
||||||
|
|
||||||
-
|
|
||||||
val = snd_soc_component_read(component, WM8994_AIF2_CONTROL_2);
|
|
||||||
if ((val & WM8994_AIF2DACL_SRC) &&
|
|
||||||
(val & WM8994_AIF2DACR_SRC))
|
|
||||||
@@ -1847,6 +1878,16 @@ static const struct snd_soc_dapm_widget wm8994_specific_dapm_widgets[] = {
|
|
||||||
SND_SOC_DAPM_MUX("AIF3ADC Mux", SND_SOC_NOPM, 0, 0, &wm8994_aif3adc_mux),
|
|
||||||
};
|
|
||||||
|
|
||||||
+static const struct snd_soc_dapm_widget wm8994_mclk1_dapm_widgets[] = {
|
|
||||||
+SND_SOC_DAPM_SUPPLY("MCLK1", SND_SOC_NOPM, 0, 0, mclk_event,
|
|
||||||
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static const struct snd_soc_dapm_widget wm8994_mclk2_dapm_widgets[] = {
|
|
||||||
+SND_SOC_DAPM_SUPPLY("MCLK2", SND_SOC_NOPM, 0, 0, mclk_event,
|
|
||||||
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static const struct snd_soc_dapm_widget wm8958_dapm_widgets[] = {
|
|
||||||
SND_SOC_DAPM_SUPPLY("AIF3", WM8994_POWER_MANAGEMENT_6, 5, 1, NULL, 0),
|
|
||||||
SND_SOC_DAPM_MUX("Mono PCM Out Mux", SND_SOC_NOPM, 0, 0, &mono_pcm_out_mux),
|
|
||||||
@@ -2071,10 +2112,10 @@ static const struct snd_soc_dapm_route wm8994_lateclk_intercon[] = {
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct snd_soc_dapm_route wm8994_revd_intercon[] = {
|
|
||||||
- { "AIF1DACDAT", NULL, "AIF2DACDAT" },
|
|
||||||
- { "AIF2DACDAT", NULL, "AIF1DACDAT" },
|
|
||||||
- { "AIF1ADCDAT", NULL, "AIF2ADCDAT" },
|
|
||||||
- { "AIF2ADCDAT", NULL, "AIF1ADCDAT" },
|
|
||||||
+// { "AIF1DACDAT", NULL, "AIF2DACDAT" },
|
|
||||||
+// { "AIF2DACDAT", NULL, "AIF1DACDAT" },
|
|
||||||
+// { "AIF1ADCDAT", NULL, "AIF2ADCDAT" },
|
|
||||||
+// { "AIF2ADCDAT", NULL, "AIF1ADCDAT" },
|
|
||||||
{ "MICBIAS1", NULL, "CLK_SYS" },
|
|
||||||
{ "MICBIAS1", NULL, "MICBIAS Supply" },
|
|
||||||
{ "MICBIAS2", NULL, "CLK_SYS" },
|
|
||||||
@@ -2506,11 +2547,24 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
|
|
||||||
{
|
|
||||||
struct snd_soc_component *component = dai->component;
|
|
||||||
struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
|
|
||||||
- int ret, i;
|
|
||||||
+ int i, ret;
|
|
||||||
|
|
||||||
+ /*
|
|
||||||
+ * Simple card provides unconditionnaly clock_id = 0.
|
|
||||||
+ * Workaround to select master clock for aif1/2
|
|
||||||
+ */
|
|
||||||
switch (dai->id) {
|
|
||||||
case 1:
|
|
||||||
+ if (wm8994->mclk[0].clk)
|
|
||||||
+ clk_id = WM8994_SYSCLK_MCLK1;
|
|
||||||
+ else if (wm8994->mclk[1].clk)
|
|
||||||
+ clk_id = WM8994_SYSCLK_MCLK2;
|
|
||||||
+ break;
|
|
||||||
case 2:
|
|
||||||
+ if (wm8994->mclk[1].clk)
|
|
||||||
+ clk_id = WM8994_SYSCLK_MCLK2;
|
|
||||||
+ else if (wm8994->mclk[0].clk)
|
|
||||||
+ clk_id = WM8994_SYSCLK_MCLK1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
@@ -2522,6 +2576,10 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
|
|
||||||
case WM8994_SYSCLK_MCLK1:
|
|
||||||
wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_MCLK1;
|
|
||||||
|
|
||||||
+ /* Avoid busy error on exclusive rate change request */
|
|
||||||
+ if (!freq)
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
ret = wm8994_set_mclk_rate(wm8994, dai->id - 1, &freq);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
@@ -2535,6 +2593,9 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
|
|
||||||
/* TODO: Set GPIO AF */
|
|
||||||
wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_MCLK2;
|
|
||||||
|
|
||||||
+ if (!freq)
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
ret = wm8994_set_mclk_rate(wm8994, dai->id - 1, &freq);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
@@ -4438,6 +4499,14 @@ static int wm8994_component_probe(struct snd_soc_component *component)
|
|
||||||
ARRAY_SIZE(wm8994_snd_controls));
|
|
||||||
snd_soc_dapm_new_controls(dapm, wm8994_specific_dapm_widgets,
|
|
||||||
ARRAY_SIZE(wm8994_specific_dapm_widgets));
|
|
||||||
+ if (wm8994->mclk[0].clk)
|
|
||||||
+ snd_soc_dapm_new_controls(dapm, wm8994_mclk1_dapm_widgets,
|
|
||||||
+ ARRAY_SIZE(wm8994_mclk1_dapm_widgets));
|
|
||||||
+
|
|
||||||
+ if (wm8994->mclk[1].clk)
|
|
||||||
+ snd_soc_dapm_new_controls(dapm, wm8994_mclk2_dapm_widgets,
|
|
||||||
+ ARRAY_SIZE(wm8994_mclk2_dapm_widgets));
|
|
||||||
+
|
|
||||||
if (control->revision < 4) {
|
|
||||||
snd_soc_dapm_new_controls(dapm, wm8994_lateclk_revd_widgets,
|
|
||||||
ARRAY_SIZE(wm8994_lateclk_revd_widgets));
|
|
||||||
diff --git a/sound/soc/stm/stm32_adfsdm.c b/sound/soc/stm/stm32_adfsdm.c
|
|
||||||
index c4031988f..a67cadc03 100644
|
|
||||||
--- a/sound/soc/stm/stm32_adfsdm.c
|
|
||||||
+++ b/sound/soc/stm/stm32_adfsdm.c
|
|
||||||
@@ -12,7 +12,7 @@
|
|
||||||
#include <linux/mutex.h>
|
|
||||||
#include <linux/platform_device.h>
|
|
||||||
#include <linux/slab.h>
|
|
||||||
-
|
|
||||||
+#include <linux/pm_runtime.h>
|
|
||||||
#include <linux/iio/iio.h>
|
|
||||||
#include <linux/iio/consumer.h>
|
|
||||||
#include <linux/iio/adc/stm32-dfsdm-adc.h>
|
|
||||||
@@ -353,15 +353,20 @@ static int stm32_adfsdm_probe(struct platform_device *pdev)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ret = snd_soc_add_component(component, NULL, 0);
|
|
||||||
- if (ret < 0)
|
|
||||||
+ if (ret < 0) {
|
|
||||||
dev_err(&pdev->dev, "%s: Failed to register PCM platform\n",
|
|
||||||
__func__);
|
|
||||||
+ return ret;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- return ret;
|
|
||||||
+ pm_runtime_enable(&pdev->dev);
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int stm32_adfsdm_remove(struct platform_device *pdev)
|
|
||||||
{
|
|
||||||
+ pm_runtime_disable(&pdev->dev);
|
|
||||||
snd_soc_unregister_component(&pdev->dev);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
diff --git a/sound/soc/stm/stm32_i2s.c b/sound/soc/stm/stm32_i2s.c
|
|
||||||
index 7c4d63c33..f324ce974 100644
|
|
||||||
--- a/sound/soc/stm/stm32_i2s.c
|
|
||||||
+++ b/sound/soc/stm/stm32_i2s.c
|
|
||||||
@@ -8,10 +8,12 @@
|
|
||||||
|
|
||||||
#include <linux/bitfield.h>
|
|
||||||
#include <linux/clk.h>
|
|
||||||
+#include <linux/clk-provider.h>
|
|
||||||
#include <linux/delay.h>
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/of_irq.h>
|
|
||||||
#include <linux/of_platform.h>
|
|
||||||
+#include <linux/pm_runtime.h>
|
|
||||||
#include <linux/regmap.h>
|
|
||||||
#include <linux/reset.h>
|
|
||||||
#include <linux/spinlock.h>
|
|
||||||
@@ -196,6 +198,9 @@ enum i2s_datlen {
|
|
||||||
#define STM32_I2S_IS_MASTER(x) ((x)->ms_flg == I2S_MS_MASTER)
|
|
||||||
#define STM32_I2S_IS_SLAVE(x) ((x)->ms_flg == I2S_MS_SLAVE)
|
|
||||||
|
|
||||||
+#define STM32_I2S_NAME_LEN 32
|
|
||||||
+#define STM32_I2S_RATE_11K 11025
|
|
||||||
+
|
|
||||||
/**
|
|
||||||
* struct stm32_i2s_data - private data of I2S
|
|
||||||
* @regmap_conf: I2S register map configuration pointer
|
|
||||||
@@ -206,6 +211,7 @@ enum i2s_datlen {
|
|
||||||
* @dma_data_rx: dma configuration data for tx channel
|
|
||||||
* @substream: PCM substream data pointer
|
|
||||||
* @i2sclk: kernel clock feeding the I2S clock generator
|
|
||||||
+ * @i2smclk: master clock from I2S mclk provider
|
|
||||||
* @pclk: peripheral clock driving bus interface
|
|
||||||
* @x8kclk: I2S parent clock for sampling frequencies multiple of 8kHz
|
|
||||||
* @x11kclk: I2S parent clock for sampling frequencies multiple of 11kHz
|
|
||||||
@@ -215,6 +221,9 @@ enum i2s_datlen {
|
|
||||||
* @irq_lock: prevent race condition with IRQ
|
|
||||||
* @mclk_rate: master clock frequency (Hz)
|
|
||||||
* @fmt: DAI protocol
|
|
||||||
+ * @divider: prescaler division ratio
|
|
||||||
+ * @div: prescaler div field
|
|
||||||
+ * @odd: prescaler odd field
|
|
||||||
* @refcount: keep count of opened streams on I2S
|
|
||||||
* @ms_flg: master mode flag.
|
|
||||||
*/
|
|
||||||
@@ -227,6 +236,7 @@ struct stm32_i2s_data {
|
|
||||||
struct snd_dmaengine_dai_dma_data dma_data_rx;
|
|
||||||
struct snd_pcm_substream *substream;
|
|
||||||
struct clk *i2sclk;
|
|
||||||
+ struct clk *i2smclk;
|
|
||||||
struct clk *pclk;
|
|
||||||
struct clk *x8kclk;
|
|
||||||
struct clk *x11kclk;
|
|
||||||
@@ -236,10 +246,210 @@ struct stm32_i2s_data {
|
|
||||||
spinlock_t irq_lock; /* used to prevent race condition with IRQ */
|
|
||||||
unsigned int mclk_rate;
|
|
||||||
unsigned int fmt;
|
|
||||||
+ unsigned int divider;
|
|
||||||
+ unsigned int div;
|
|
||||||
+ bool odd;
|
|
||||||
int refcount;
|
|
||||||
int ms_flg;
|
|
||||||
};
|
|
||||||
|
|
||||||
+struct stm32_i2smclk_data {
|
|
||||||
+ struct clk_hw hw;
|
|
||||||
+ unsigned long freq;
|
|
||||||
+ struct stm32_i2s_data *i2s_data;
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+#define to_mclk_data(_hw) container_of(_hw, struct stm32_i2smclk_data, hw)
|
|
||||||
+
|
|
||||||
+static int stm32_i2s_calc_clk_div(struct stm32_i2s_data *i2s,
|
|
||||||
+ unsigned long input_rate,
|
|
||||||
+ unsigned long output_rate)
|
|
||||||
+{
|
|
||||||
+ unsigned int ratio, div, divider = 1;
|
|
||||||
+ bool odd;
|
|
||||||
+
|
|
||||||
+ ratio = DIV_ROUND_CLOSEST(input_rate, output_rate);
|
|
||||||
+
|
|
||||||
+ /* Check the parity of the divider */
|
|
||||||
+ odd = ratio & 0x1;
|
|
||||||
+
|
|
||||||
+ /* Compute the div prescaler */
|
|
||||||
+ div = ratio >> 1;
|
|
||||||
+
|
|
||||||
+ /* If div is 0 actual divider is 1 */
|
|
||||||
+ if (div) {
|
|
||||||
+ divider = ((2 * div) + odd);
|
|
||||||
+ dev_dbg(&i2s->pdev->dev, "Divider: 2*%d(div)+%d(odd) = %d\n",
|
|
||||||
+ div, odd, divider);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* Division by three is not allowed by I2S prescaler */
|
|
||||||
+ if ((div == 1 && odd) || div > I2S_CGFR_I2SDIV_MAX) {
|
|
||||||
+ dev_err(&i2s->pdev->dev, "Wrong divider setting\n");
|
|
||||||
+ return -EINVAL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (input_rate % divider)
|
|
||||||
+ dev_dbg(&i2s->pdev->dev,
|
|
||||||
+ "Rate not accurate. requested (%ld), actual (%ld)\n",
|
|
||||||
+ output_rate, input_rate / divider);
|
|
||||||
+
|
|
||||||
+ i2s->div = div;
|
|
||||||
+ i2s->odd = odd;
|
|
||||||
+ i2s->divider = divider;
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int stm32_i2s_set_clk_div(struct stm32_i2s_data *i2s)
|
|
||||||
+{
|
|
||||||
+ u32 cgfr, cgfr_mask;
|
|
||||||
+
|
|
||||||
+ cgfr = I2S_CGFR_I2SDIV_SET(i2s->div) | (i2s->odd << I2S_CGFR_ODD_SHIFT);
|
|
||||||
+ cgfr_mask = I2S_CGFR_I2SDIV_MASK | I2S_CGFR_ODD;
|
|
||||||
+
|
|
||||||
+ return regmap_update_bits(i2s->regmap, STM32_I2S_CGFR_REG,
|
|
||||||
+ cgfr_mask, cgfr);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int stm32_i2s_set_parent_clock(struct stm32_i2s_data *i2s,
|
|
||||||
+ unsigned int rate)
|
|
||||||
+{
|
|
||||||
+ struct platform_device *pdev = i2s->pdev;
|
|
||||||
+ struct clk *parent_clk;
|
|
||||||
+ int ret;
|
|
||||||
+
|
|
||||||
+ if (!(rate % STM32_I2S_RATE_11K))
|
|
||||||
+ parent_clk = i2s->x11kclk;
|
|
||||||
+ else
|
|
||||||
+ parent_clk = i2s->x8kclk;
|
|
||||||
+
|
|
||||||
+ ret = clk_set_parent(i2s->i2sclk, parent_clk);
|
|
||||||
+ if (ret)
|
|
||||||
+ dev_err(&pdev->dev,
|
|
||||||
+ "Error %d setting i2sclk parent clock\n", ret);
|
|
||||||
+
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static long stm32_i2smclk_round_rate(struct clk_hw *hw, unsigned long rate,
|
|
||||||
+ unsigned long *prate)
|
|
||||||
+{
|
|
||||||
+ struct stm32_i2smclk_data *mclk = to_mclk_data(hw);
|
|
||||||
+ struct stm32_i2s_data *i2s = mclk->i2s_data;
|
|
||||||
+ int ret;
|
|
||||||
+
|
|
||||||
+ ret = stm32_i2s_calc_clk_div(i2s, *prate, rate);
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
+ mclk->freq = *prate / i2s->divider;
|
|
||||||
+
|
|
||||||
+ return mclk->freq;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static unsigned long stm32_i2smclk_recalc_rate(struct clk_hw *hw,
|
|
||||||
+ unsigned long parent_rate)
|
|
||||||
+{
|
|
||||||
+ struct stm32_i2smclk_data *mclk = to_mclk_data(hw);
|
|
||||||
+
|
|
||||||
+ return mclk->freq;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int stm32_i2smclk_set_rate(struct clk_hw *hw, unsigned long rate,
|
|
||||||
+ unsigned long parent_rate)
|
|
||||||
+{
|
|
||||||
+ struct stm32_i2smclk_data *mclk = to_mclk_data(hw);
|
|
||||||
+ struct stm32_i2s_data *i2s = mclk->i2s_data;
|
|
||||||
+ int ret;
|
|
||||||
+
|
|
||||||
+ ret = stm32_i2s_calc_clk_div(i2s, parent_rate, rate);
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
+ ret = stm32_i2s_set_clk_div(i2s);
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
+ mclk->freq = rate;
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int stm32_i2smclk_enable(struct clk_hw *hw)
|
|
||||||
+{
|
|
||||||
+ struct stm32_i2smclk_data *mclk = to_mclk_data(hw);
|
|
||||||
+ struct stm32_i2s_data *i2s = mclk->i2s_data;
|
|
||||||
+
|
|
||||||
+ dev_dbg(&i2s->pdev->dev, "Enable master clock\n");
|
|
||||||
+
|
|
||||||
+ return regmap_update_bits(i2s->regmap, STM32_I2S_CGFR_REG,
|
|
||||||
+ I2S_CGFR_MCKOE, I2S_CGFR_MCKOE);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void stm32_i2smclk_disable(struct clk_hw *hw)
|
|
||||||
+{
|
|
||||||
+ struct stm32_i2smclk_data *mclk = to_mclk_data(hw);
|
|
||||||
+ struct stm32_i2s_data *i2s = mclk->i2s_data;
|
|
||||||
+
|
|
||||||
+ dev_dbg(&i2s->pdev->dev, "Disable master clock\n");
|
|
||||||
+
|
|
||||||
+ regmap_update_bits(i2s->regmap, STM32_I2S_CGFR_REG, I2S_CGFR_MCKOE, 0);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static const struct clk_ops mclk_ops = {
|
|
||||||
+ .enable = stm32_i2smclk_enable,
|
|
||||||
+ .disable = stm32_i2smclk_disable,
|
|
||||||
+ .recalc_rate = stm32_i2smclk_recalc_rate,
|
|
||||||
+ .round_rate = stm32_i2smclk_round_rate,
|
|
||||||
+ .set_rate = stm32_i2smclk_set_rate,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static int stm32_i2s_add_mclk_provider(struct stm32_i2s_data *i2s)
|
|
||||||
+{
|
|
||||||
+ struct clk_hw *hw;
|
|
||||||
+ struct stm32_i2smclk_data *mclk;
|
|
||||||
+ struct device *dev = &i2s->pdev->dev;
|
|
||||||
+ const char *pname = __clk_get_name(i2s->i2sclk);
|
|
||||||
+ char *mclk_name, *p, *s = (char *)pname;
|
|
||||||
+ int ret, i = 0;
|
|
||||||
+
|
|
||||||
+ mclk = devm_kzalloc(dev, sizeof(*mclk), GFP_KERNEL);
|
|
||||||
+ if (!mclk)
|
|
||||||
+ return -ENOMEM;
|
|
||||||
+
|
|
||||||
+ mclk_name = devm_kcalloc(dev, sizeof(char),
|
|
||||||
+ STM32_I2S_NAME_LEN, GFP_KERNEL);
|
|
||||||
+ if (!mclk_name)
|
|
||||||
+ return -ENOMEM;
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * Forge mclk clock name from parent clock name and suffix.
|
|
||||||
+ * String after "_" char is stripped in parent name.
|
|
||||||
+ */
|
|
||||||
+ p = mclk_name;
|
|
||||||
+ while (*s && *s != '_' && (i < (STM32_I2S_NAME_LEN - 7))) {
|
|
||||||
+ *p++ = *s++;
|
|
||||||
+ i++;
|
|
||||||
+ }
|
|
||||||
+ strcat(p, "_mclk");
|
|
||||||
+
|
|
||||||
+ mclk->hw.init = CLK_HW_INIT(mclk_name, pname, &mclk_ops, 0);
|
|
||||||
+ mclk->i2s_data = i2s;
|
|
||||||
+ hw = &mclk->hw;
|
|
||||||
+
|
|
||||||
+ dev_dbg(dev, "Register master clock %s\n", mclk_name);
|
|
||||||
+ ret = devm_clk_hw_register(&i2s->pdev->dev, hw);
|
|
||||||
+ if (ret) {
|
|
||||||
+ dev_err(dev, "mclk register fails with error %d\n", ret);
|
|
||||||
+ return ret;
|
|
||||||
+ }
|
|
||||||
+ i2s->i2smclk = hw->clk;
|
|
||||||
+
|
|
||||||
+ /* register mclk provider */
|
|
||||||
+ return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, hw);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static irqreturn_t stm32_i2s_isr(int irq, void *devid)
|
|
||||||
{
|
|
||||||
struct stm32_i2s_data *i2s = (struct stm32_i2s_data *)devid;
|
|
||||||
@@ -405,18 +615,46 @@ static int stm32_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
|
|
||||||
int clk_id, unsigned int freq, int dir)
|
|
||||||
{
|
|
||||||
struct stm32_i2s_data *i2s = snd_soc_dai_get_drvdata(cpu_dai);
|
|
||||||
+ int ret = 0;
|
|
||||||
|
|
||||||
- dev_dbg(cpu_dai->dev, "I2S MCLK frequency is %uHz\n", freq);
|
|
||||||
+ dev_dbg(cpu_dai->dev, "I2S MCLK frequency is %uHz. mode: %s, dir: %s\n",
|
|
||||||
+ freq, STM32_I2S_IS_MASTER(i2s) ? "master" : "slave",
|
|
||||||
+ dir ? "output" : "input");
|
|
||||||
|
|
||||||
- if ((dir == SND_SOC_CLOCK_OUT) && STM32_I2S_IS_MASTER(i2s)) {
|
|
||||||
- i2s->mclk_rate = freq;
|
|
||||||
+ /* MCLK generation is available only in master mode */
|
|
||||||
+ if (dir == SND_SOC_CLOCK_OUT && STM32_I2S_IS_MASTER(i2s)) {
|
|
||||||
+ if (!i2s->i2smclk) {
|
|
||||||
+ dev_dbg(cpu_dai->dev, "No MCLK registered\n");
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- /* Enable master clock if master mode and mclk-fs are set */
|
|
||||||
- return regmap_update_bits(i2s->regmap, STM32_I2S_CGFR_REG,
|
|
||||||
- I2S_CGFR_MCKOE, I2S_CGFR_MCKOE);
|
|
||||||
+ /* Assume shutdown if requested frequency is 0Hz */
|
|
||||||
+ if (!freq) {
|
|
||||||
+ /* Release mclk rate only if rate was actually set */
|
|
||||||
+ if (i2s->mclk_rate) {
|
|
||||||
+ clk_rate_exclusive_put(i2s->i2smclk);
|
|
||||||
+ i2s->mclk_rate = 0;
|
|
||||||
+ }
|
|
||||||
+ return regmap_update_bits(i2s->regmap,
|
|
||||||
+ STM32_I2S_CGFR_REG,
|
|
||||||
+ I2S_CGFR_MCKOE, 0);
|
|
||||||
+ }
|
|
||||||
+ /* If master clock is used, set parent clock now */
|
|
||||||
+ ret = stm32_i2s_set_parent_clock(i2s, freq);
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+ ret = clk_set_rate_exclusive(i2s->i2smclk, freq);
|
|
||||||
+ if (ret) {
|
|
||||||
+ dev_err(cpu_dai->dev, "Could not set mclk rate\n");
|
|
||||||
+ return ret;
|
|
||||||
+ }
|
|
||||||
+ ret = regmap_update_bits(i2s->regmap, STM32_I2S_CGFR_REG,
|
|
||||||
+ I2S_CGFR_MCKOE, I2S_CGFR_MCKOE);
|
|
||||||
+ if (!ret)
|
|
||||||
+ i2s->mclk_rate = freq;
|
|
||||||
}
|
|
||||||
|
|
||||||
- return 0;
|
|
||||||
+ return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int stm32_i2s_configure_clock(struct snd_soc_dai *cpu_dai,
|
|
||||||
@@ -424,11 +662,10 @@ static int stm32_i2s_configure_clock(struct snd_soc_dai *cpu_dai,
|
|
||||||
{
|
|
||||||
struct stm32_i2s_data *i2s = snd_soc_dai_get_drvdata(cpu_dai);
|
|
||||||
unsigned long i2s_clock_rate;
|
|
||||||
- unsigned int tmp, div, real_div, nb_bits, frame_len;
|
|
||||||
+ unsigned int nb_bits, frame_len;
|
|
||||||
unsigned int rate = params_rate(params);
|
|
||||||
+ u32 cgfr;
|
|
||||||
int ret;
|
|
||||||
- u32 cgfr, cgfr_mask;
|
|
||||||
- bool odd;
|
|
||||||
|
|
||||||
if (!(rate % 11025))
|
|
||||||
clk_set_parent(i2s->i2sclk, i2s->x11kclk);
|
|
||||||
@@ -449,7 +686,10 @@ static int stm32_i2s_configure_clock(struct snd_soc_dai *cpu_dai,
|
|
||||||
* dsp mode : div = i2s_clk / (nb_bits x ws)
|
|
||||||
*/
|
|
||||||
if (i2s->mclk_rate) {
|
|
||||||
- tmp = DIV_ROUND_CLOSEST(i2s_clock_rate, i2s->mclk_rate);
|
|
||||||
+ ret = stm32_i2s_calc_clk_div(i2s, i2s_clock_rate,
|
|
||||||
+ i2s->mclk_rate);
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
} else {
|
|
||||||
frame_len = 32;
|
|
||||||
if ((i2s->fmt & SND_SOC_DAIFMT_FORMAT_MASK) ==
|
|
||||||
@@ -461,35 +701,14 @@ static int stm32_i2s_configure_clock(struct snd_soc_dai *cpu_dai,
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
- nb_bits = frame_len * ((cgfr & I2S_CGFR_CHLEN) + 1);
|
|
||||||
- tmp = DIV_ROUND_CLOSEST(i2s_clock_rate, (nb_bits * rate));
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- /* Check the parity of the divider */
|
|
||||||
- odd = tmp & 0x1;
|
|
||||||
-
|
|
||||||
- /* Compute the div prescaler */
|
|
||||||
- div = tmp >> 1;
|
|
||||||
-
|
|
||||||
- cgfr = I2S_CGFR_I2SDIV_SET(div) | (odd << I2S_CGFR_ODD_SHIFT);
|
|
||||||
- cgfr_mask = I2S_CGFR_I2SDIV_MASK | I2S_CGFR_ODD;
|
|
||||||
-
|
|
||||||
- real_div = ((2 * div) + odd);
|
|
||||||
- dev_dbg(cpu_dai->dev, "I2S clk: %ld, SCLK: %d\n",
|
|
||||||
- i2s_clock_rate, rate);
|
|
||||||
- dev_dbg(cpu_dai->dev, "Divider: 2*%d(div)+%d(odd) = %d\n",
|
|
||||||
- div, odd, real_div);
|
|
||||||
-
|
|
||||||
- if (((div == 1) && odd) || (div > I2S_CGFR_I2SDIV_MAX)) {
|
|
||||||
- dev_err(cpu_dai->dev, "Wrong divider setting\n");
|
|
||||||
- return -EINVAL;
|
|
||||||
+ nb_bits = frame_len * (FIELD_GET(I2S_CGFR_CHLEN, cgfr) + 1);
|
|
||||||
+ ret = stm32_i2s_calc_clk_div(i2s, i2s_clock_rate,
|
|
||||||
+ (nb_bits * rate));
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (!div && !odd)
|
|
||||||
- dev_warn(cpu_dai->dev, "real divider forced to 1\n");
|
|
||||||
-
|
|
||||||
- ret = regmap_update_bits(i2s->regmap, STM32_I2S_CGFR_REG,
|
|
||||||
- cgfr_mask, cgfr);
|
|
||||||
+ ret = stm32_i2s_set_clk_div(i2s);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
@@ -694,9 +913,6 @@ static void stm32_i2s_shutdown(struct snd_pcm_substream *substream,
|
|
||||||
struct stm32_i2s_data *i2s = snd_soc_dai_get_drvdata(cpu_dai);
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
- regmap_update_bits(i2s->regmap, STM32_I2S_CGFR_REG,
|
|
||||||
- I2S_CGFR_MCKOE, (unsigned int)~I2S_CGFR_MCKOE);
|
|
||||||
-
|
|
||||||
clk_disable_unprepare(i2s->i2sclk);
|
|
||||||
|
|
||||||
spin_lock_irqsave(&i2s->irq_lock, flags);
|
|
||||||
@@ -861,6 +1077,13 @@ static int stm32_i2s_parse_dt(struct platform_device *pdev,
|
|
||||||
return PTR_ERR(i2s->x11kclk);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ /* Register mclk provider if requested */
|
|
||||||
+ if (of_find_property(np, "#clock-cells", NULL)) {
|
|
||||||
+ ret = stm32_i2s_add_mclk_provider(i2s);
|
|
||||||
+ if (ret < 0)
|
|
||||||
+ return ret;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
/* Get irqs */
|
|
||||||
irq = platform_get_irq(pdev, 0);
|
|
||||||
if (irq < 0)
|
|
||||||
@@ -892,6 +1115,7 @@ static int stm32_i2s_remove(struct platform_device *pdev)
|
|
||||||
{
|
|
||||||
snd_dmaengine_pcm_unregister(&pdev->dev);
|
|
||||||
snd_soc_unregister_component(&pdev->dev);
|
|
||||||
+ pm_runtime_disable(&pdev->dev);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -906,16 +1130,16 @@ static int stm32_i2s_probe(struct platform_device *pdev)
|
|
||||||
if (!i2s)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
- ret = stm32_i2s_parse_dt(pdev, i2s);
|
|
||||||
- if (ret)
|
|
||||||
- return ret;
|
|
||||||
-
|
|
||||||
i2s->pdev = pdev;
|
|
||||||
i2s->ms_flg = I2S_MS_NOT_SET;
|
|
||||||
spin_lock_init(&i2s->lock_fd);
|
|
||||||
spin_lock_init(&i2s->irq_lock);
|
|
||||||
platform_set_drvdata(pdev, i2s);
|
|
||||||
|
|
||||||
+ ret = stm32_i2s_parse_dt(pdev, i2s);
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
ret = stm32_i2s_dais_init(pdev, i2s);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
@@ -974,6 +1198,8 @@ static int stm32_i2s_probe(struct platform_device *pdev)
|
|
||||||
FIELD_GET(I2S_VERR_MIN_MASK, val));
|
|
||||||
}
|
|
||||||
|
|
||||||
+ pm_runtime_enable(&pdev->dev);
|
|
||||||
+
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
error:
|
|
||||||
diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c
|
|
||||||
index 3aa1cf262..780f48138 100644
|
|
||||||
--- a/sound/soc/stm/stm32_sai_sub.c
|
|
||||||
+++ b/sound/soc/stm/stm32_sai_sub.c
|
|
||||||
@@ -1294,7 +1294,7 @@ static struct snd_soc_dai_driver stm32_sai_playback_dai = {
|
|
||||||
.id = 1, /* avoid call to fmt_single_name() */
|
|
||||||
.playback = {
|
|
||||||
.channels_min = 1,
|
|
||||||
- .channels_max = 2,
|
|
||||||
+ .channels_max = 16,
|
|
||||||
.rate_min = 8000,
|
|
||||||
.rate_max = 192000,
|
|
||||||
.rates = SNDRV_PCM_RATE_CONTINUOUS,
|
|
||||||
@@ -1312,7 +1312,7 @@ static struct snd_soc_dai_driver stm32_sai_capture_dai = {
|
|
||||||
.id = 1, /* avoid call to fmt_single_name() */
|
|
||||||
.capture = {
|
|
||||||
.channels_min = 1,
|
|
||||||
- .channels_max = 2,
|
|
||||||
+ .channels_max = 16,
|
|
||||||
.rate_min = 8000,
|
|
||||||
.rate_max = 192000,
|
|
||||||
.rates = SNDRV_PCM_RATE_CONTINUOUS,
|
|
||||||
diff --git a/sound/soc/stm/stm32_spdifrx.c b/sound/soc/stm/stm32_spdifrx.c
|
|
||||||
index 1bfa3b2ba..aa38f9df9 100644
|
|
||||||
--- a/sound/soc/stm/stm32_spdifrx.c
|
|
||||||
+++ b/sound/soc/stm/stm32_spdifrx.c
|
|
||||||
@@ -12,6 +12,7 @@
|
|
||||||
#include <linux/delay.h>
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/of_platform.h>
|
|
||||||
+#include <linux/pm_runtime.h>
|
|
||||||
#include <linux/regmap.h>
|
|
||||||
#include <linux/reset.h>
|
|
||||||
|
|
||||||
@@ -956,6 +957,7 @@ static int stm32_spdifrx_remove(struct platform_device *pdev)
|
|
||||||
|
|
||||||
snd_dmaengine_pcm_unregister(&pdev->dev);
|
|
||||||
snd_soc_unregister_component(&pdev->dev);
|
|
||||||
+ pm_runtime_disable(&pdev->dev);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1046,6 +1048,8 @@ static int stm32_spdifrx_probe(struct platform_device *pdev)
|
|
||||||
FIELD_GET(SPDIFRX_VERR_MIN_MASK, ver));
|
|
||||||
}
|
|
||||||
|
|
||||||
+ pm_runtime_enable(&pdev->dev);
|
|
||||||
+
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
error:
|
|
||||||
--
|
|
||||||
2.17.1
|
|
||||||
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
From 49a7d9003e2c89aa252d3ccccb16d4ab22a90ef6 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lionel Vitte <lionel.vitte@st.com>
|
|
||||||
Date: Thu, 14 Oct 2021 16:51:52 +0200
|
|
||||||
Subject: [PATCH 20/23] ARM 5.10.61-stm32mp1-r2 MISC
|
|
||||||
|
|
||||||
---
|
|
||||||
drivers/opp/core.c | 6 +++++-
|
|
||||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/opp/core.c b/drivers/opp/core.c
|
|
||||||
index 903b465c8..dbcce5de9 100644
|
|
||||||
--- a/drivers/opp/core.c
|
|
||||||
+++ b/drivers/opp/core.c
|
|
||||||
@@ -1608,9 +1608,13 @@ struct opp_table *dev_pm_opp_set_supported_hw(struct device *dev,
|
|
||||||
struct opp_table *opp_table;
|
|
||||||
|
|
||||||
opp_table = dev_pm_opp_get_opp_table(dev);
|
|
||||||
- if (IS_ERR(opp_table))
|
|
||||||
+
|
|
||||||
+ if (PTR_ERR(opp_table) == -EPROBE_DEFER)
|
|
||||||
return opp_table;
|
|
||||||
|
|
||||||
+ if (!opp_table)
|
|
||||||
+ return ERR_PTR(-ENOMEM);
|
|
||||||
+
|
|
||||||
/* Make sure there are no concurrent readers while updating opp_table */
|
|
||||||
WARN_ON(!list_empty(&opp_table->opp_list));
|
|
||||||
|
|
||||||
--
|
|
||||||
2.17.1
|
|
||||||
|
|
||||||
|
|
@ -1,701 +0,0 @@
|
||||||
From 5707d44444b4bd31e2690d5d7e72f83c6e28b48b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lionel Vitte <lionel.vitte@st.com>
|
|
||||||
Date: Fri, 15 Oct 2021 08:44:32 +0200
|
|
||||||
Subject: [PATCH 21/23] ARM 5.10.61-stm32mp1-r2 CPUIDLE-POWER
|
|
||||||
|
|
||||||
---
|
|
||||||
drivers/base/power/domain.c | 4 +-
|
|
||||||
drivers/base/power/main.c | 4 +-
|
|
||||||
drivers/cpuidle/Kconfig.arm | 8 +
|
|
||||||
drivers/cpuidle/Makefile | 1 +
|
|
||||||
drivers/cpuidle/cpuidle-stm32.c | 276 ++++++++++++++++++++++++++++++++
|
|
||||||
drivers/nvmem/stm32-romem.c | 165 +++++++++++++++++--
|
|
||||||
include/linux/pm_wakeup.h | 10 ++
|
|
||||||
kernel/power/suspend.c | 1 -
|
|
||||||
8 files changed, 453 insertions(+), 16 deletions(-)
|
|
||||||
create mode 100644 drivers/cpuidle/cpuidle-stm32.c
|
|
||||||
|
|
||||||
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
|
|
||||||
index 743268996..e0894ef84 100644
|
|
||||||
--- a/drivers/base/power/domain.c
|
|
||||||
+++ b/drivers/base/power/domain.c
|
|
||||||
@@ -1142,7 +1142,7 @@ static int genpd_finish_suspend(struct device *dev, bool poweroff)
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
- if (dev->power.wakeup_path && genpd_is_active_wakeup(genpd))
|
|
||||||
+ if (device_wakeup_path(dev) && genpd_is_active_wakeup(genpd))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (genpd->dev_ops.stop && genpd->dev_ops.start &&
|
|
||||||
@@ -1196,7 +1196,7 @@ static int genpd_resume_noirq(struct device *dev)
|
|
||||||
if (IS_ERR(genpd))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
- if (dev->power.wakeup_path && genpd_is_active_wakeup(genpd))
|
|
||||||
+ if (device_wakeup_path(dev) && genpd_is_active_wakeup(genpd))
|
|
||||||
return pm_generic_resume_noirq(dev);
|
|
||||||
|
|
||||||
genpd_lock(genpd);
|
|
||||||
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
|
|
||||||
index c7ac49042..921c5b2ec 100644
|
|
||||||
--- a/drivers/base/power/main.c
|
|
||||||
+++ b/drivers/base/power/main.c
|
|
||||||
@@ -1359,7 +1359,7 @@ static void dpm_propagate_wakeup_to_parent(struct device *dev)
|
|
||||||
|
|
||||||
spin_lock_irq(&parent->power.lock);
|
|
||||||
|
|
||||||
- if (dev->power.wakeup_path && !parent->power.ignore_children)
|
|
||||||
+ if (device_wakeup_path(dev) && !parent->power.ignore_children)
|
|
||||||
parent->power.wakeup_path = true;
|
|
||||||
|
|
||||||
spin_unlock_irq(&parent->power.lock);
|
|
||||||
@@ -1627,7 +1627,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
|
|
||||||
goto Complete;
|
|
||||||
|
|
||||||
/* Avoid direct_complete to let wakeup_path propagate. */
|
|
||||||
- if (device_may_wakeup(dev) || dev->power.wakeup_path)
|
|
||||||
+ if (device_may_wakeup(dev) || device_wakeup_path(dev))
|
|
||||||
dev->power.direct_complete = false;
|
|
||||||
|
|
||||||
if (dev->power.direct_complete) {
|
|
||||||
diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
|
|
||||||
index 334f83e56..4de5db493 100644
|
|
||||||
--- a/drivers/cpuidle/Kconfig.arm
|
|
||||||
+++ b/drivers/cpuidle/Kconfig.arm
|
|
||||||
@@ -91,6 +91,14 @@ config ARM_EXYNOS_CPUIDLE
|
|
||||||
help
|
|
||||||
Select this to enable cpuidle for Exynos processors.
|
|
||||||
|
|
||||||
+config ARM_STM32_CPUIDLE
|
|
||||||
+ bool "Cpu Idle Driver for the STM32 processors"
|
|
||||||
+ depends on MACH_STM32MP157
|
|
||||||
+ select DT_IDLE_STATES
|
|
||||||
+ select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP
|
|
||||||
+ help
|
|
||||||
+ Select this to enable cpuidle for STM32 processors.
|
|
||||||
+
|
|
||||||
config ARM_MVEBU_V7_CPUIDLE
|
|
||||||
bool "CPU Idle Driver for mvebu v7 family processors"
|
|
||||||
depends on (ARCH_MVEBU || COMPILE_TEST) && !ARM64
|
|
||||||
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
|
|
||||||
index 26bbc5e74..cc1eccc73 100644
|
|
||||||
--- a/drivers/cpuidle/Makefile
|
|
||||||
+++ b/drivers/cpuidle/Makefile
|
|
||||||
@@ -25,6 +25,7 @@ obj-$(CONFIG_ARM_PSCI_CPUIDLE) += cpuidle-psci.o
|
|
||||||
obj-$(CONFIG_ARM_PSCI_CPUIDLE_DOMAIN) += cpuidle-psci-domain.o
|
|
||||||
obj-$(CONFIG_ARM_TEGRA_CPUIDLE) += cpuidle-tegra.o
|
|
||||||
obj-$(CONFIG_ARM_QCOM_SPM_CPUIDLE) += cpuidle-qcom-spm.o
|
|
||||||
+obj-$(CONFIG_ARM_STM32_CPUIDLE) += cpuidle-stm32.o
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# MIPS drivers
|
|
||||||
diff --git a/drivers/cpuidle/cpuidle-stm32.c b/drivers/cpuidle/cpuidle-stm32.c
|
|
||||||
new file mode 100644
|
|
||||||
index 000000000..d3413386c
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/drivers/cpuidle/cpuidle-stm32.c
|
|
||||||
@@ -0,0 +1,276 @@
|
|
||||||
+// SPDX-License-Identifier: GPL-2.0
|
|
||||||
+// Copyright (C) STMicroelectronics 2019
|
|
||||||
+// Author:
|
|
||||||
+
|
|
||||||
+#include <linux/arm-smccc.h>
|
|
||||||
+#include <linux/cpu_pm.h>
|
|
||||||
+#include <linux/cpuidle.h>
|
|
||||||
+#include <linux/module.h>
|
|
||||||
+#include <linux/platform_device.h>
|
|
||||||
+#include <linux/pm_domain.h>
|
|
||||||
+#include <linux/pm_runtime.h>
|
|
||||||
+#include <linux/of.h>
|
|
||||||
+#include <linux/slab.h>
|
|
||||||
+#include <linux/tick.h>
|
|
||||||
+
|
|
||||||
+#include <asm/cpuidle.h>
|
|
||||||
+
|
|
||||||
+#include "dt_idle_states.h"
|
|
||||||
+
|
|
||||||
+#define SMC_AUTOSTOP() \
|
|
||||||
+{ \
|
|
||||||
+ struct arm_smccc_res res; \
|
|
||||||
+ arm_smccc_smc(0x8200100a, 0, 0, 0, \
|
|
||||||
+ 0, 0, 0, 0, &res); \
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+struct stm32_pm_domain {
|
|
||||||
+ struct device *dev;
|
|
||||||
+ struct generic_pm_domain genpd;
|
|
||||||
+ int id;
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static atomic_t stm_idle_barrier;
|
|
||||||
+
|
|
||||||
+static int stm32_enter_idle(struct cpuidle_device *dev,
|
|
||||||
+ struct cpuidle_driver *drv, int index)
|
|
||||||
+{
|
|
||||||
+ /*
|
|
||||||
+ * Call idle CPU PM enter notifier chain so that
|
|
||||||
+ * VFP and per CPU interrupt context is saved.
|
|
||||||
+ */
|
|
||||||
+ cpu_pm_enter();
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * be sure that both cpu enter at the same time
|
|
||||||
+ * normally not needed is the state is declared as coupled
|
|
||||||
+ */
|
|
||||||
+ cpuidle_coupled_parallel_barrier(dev, &stm_idle_barrier);
|
|
||||||
+
|
|
||||||
+ /* Enter broadcast mode for periodic timers */
|
|
||||||
+ tick_broadcast_enable();
|
|
||||||
+
|
|
||||||
+ /* Enter broadcast mode for one-shot timers */
|
|
||||||
+ tick_broadcast_enter();
|
|
||||||
+
|
|
||||||
+ if (dev->cpu == 0)
|
|
||||||
+ cpu_cluster_pm_enter();
|
|
||||||
+
|
|
||||||
+ SMC_AUTOSTOP();
|
|
||||||
+
|
|
||||||
+ if (dev->cpu == 0)
|
|
||||||
+ cpu_cluster_pm_exit();
|
|
||||||
+
|
|
||||||
+ tick_broadcast_exit();
|
|
||||||
+
|
|
||||||
+ cpuidle_coupled_parallel_barrier(dev, &stm_idle_barrier);
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * Call idle CPU PM exit notifier chain to restore
|
|
||||||
+ * VFP and per CPU IRQ context.
|
|
||||||
+ */
|
|
||||||
+ cpu_pm_exit();
|
|
||||||
+
|
|
||||||
+ return index;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static const struct of_device_id stm32_idle_state_match[] __initconst = {
|
|
||||||
+ { .compatible = "arm,idle-state",
|
|
||||||
+ .data = stm32_enter_idle },
|
|
||||||
+ { },
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static struct cpuidle_driver stm32_idle_driver = {
|
|
||||||
+ .name = "stm32_idle",
|
|
||||||
+ .states = {
|
|
||||||
+ ARM_CPUIDLE_WFI_STATE,
|
|
||||||
+ {
|
|
||||||
+ .enter = stm32_enter_idle,
|
|
||||||
+ .exit_latency = 620,
|
|
||||||
+ .target_residency = 700,
|
|
||||||
+ .flags = /*CPUIDLE_FLAG_TIMER_STOP | */
|
|
||||||
+ CPUIDLE_FLAG_COUPLED,
|
|
||||||
+ .name = "CStop",
|
|
||||||
+ .desc = "Clocks off",
|
|
||||||
+ },
|
|
||||||
+ },
|
|
||||||
+ .safe_state_index = 0,
|
|
||||||
+ .state_count = 2,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static int stm32_pd_cpuidle_off(struct generic_pm_domain *domain)
|
|
||||||
+{
|
|
||||||
+ struct stm32_pm_domain *priv = container_of(domain,
|
|
||||||
+ struct stm32_pm_domain,
|
|
||||||
+ genpd);
|
|
||||||
+ int cpu;
|
|
||||||
+
|
|
||||||
+ for_each_possible_cpu(cpu) {
|
|
||||||
+ struct cpuidle_device *cpuidle_dev = per_cpu(cpuidle_devices,
|
|
||||||
+ cpu);
|
|
||||||
+
|
|
||||||
+ cpuidle_dev->states_usage[1].disable = false;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ dev_dbg(priv->dev, "%s OFF\n", domain->name);
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int stm32_pd_cpuidle_on(struct generic_pm_domain *domain)
|
|
||||||
+{
|
|
||||||
+ struct stm32_pm_domain *priv = container_of(domain,
|
|
||||||
+ struct stm32_pm_domain,
|
|
||||||
+ genpd);
|
|
||||||
+ int cpu;
|
|
||||||
+
|
|
||||||
+ for_each_possible_cpu(cpu) {
|
|
||||||
+ struct cpuidle_device *cpuidle_dev = per_cpu(cpuidle_devices,
|
|
||||||
+ cpu);
|
|
||||||
+
|
|
||||||
+ cpuidle_dev->states_usage[1].disable = true;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ dev_dbg(priv->dev, "%s ON\n", domain->name);
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void stm32_cpuidle_domain_remove(struct stm32_pm_domain *domain)
|
|
||||||
+{
|
|
||||||
+ int ret;
|
|
||||||
+
|
|
||||||
+ ret = pm_genpd_remove(&domain->genpd);
|
|
||||||
+ if (ret)
|
|
||||||
+ dev_err(domain->dev, "failed to remove PM domain %s: %d\n",
|
|
||||||
+ domain->genpd.name, ret);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int stm32_cpuidle_domain_add(struct stm32_pm_domain *domain,
|
|
||||||
+ struct device *dev,
|
|
||||||
+ struct device_node *np)
|
|
||||||
+{
|
|
||||||
+ int ret;
|
|
||||||
+
|
|
||||||
+ domain->dev = dev;
|
|
||||||
+ domain->genpd.name = np->name;
|
|
||||||
+ domain->genpd.power_off = stm32_pd_cpuidle_off;
|
|
||||||
+ domain->genpd.power_on = stm32_pd_cpuidle_on;
|
|
||||||
+
|
|
||||||
+ ret = pm_genpd_init(&domain->genpd, NULL, 0);
|
|
||||||
+ if (ret < 0) {
|
|
||||||
+ dev_err(domain->dev, "failed to initialise PM domain %s: %d\n",
|
|
||||||
+ np->name, ret);
|
|
||||||
+ return ret;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ ret = of_genpd_add_provider_simple(np, &domain->genpd);
|
|
||||||
+ if (ret < 0) {
|
|
||||||
+ dev_err(domain->dev, "failed to register PM domain %s: %d\n",
|
|
||||||
+ np->name, ret);
|
|
||||||
+ stm32_cpuidle_domain_remove(domain);
|
|
||||||
+ return ret;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ dev_info(domain->dev, "domain %s registered\n", np->name);
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int stm32_cpuidle_probe(struct platform_device *pdev)
|
|
||||||
+{
|
|
||||||
+ struct cpuidle_driver *drv;
|
|
||||||
+ struct stm32_pm_domain *domain;
|
|
||||||
+ struct device *dev = &pdev->dev;
|
|
||||||
+ struct device_node *np = dev->of_node;
|
|
||||||
+ struct of_phandle_args child, parent;
|
|
||||||
+ struct device_node *np_child;
|
|
||||||
+ int cpu, ret;
|
|
||||||
+
|
|
||||||
+ drv = devm_kmemdup(dev, &stm32_idle_driver, sizeof(*drv), GFP_KERNEL);
|
|
||||||
+ if (!drv)
|
|
||||||
+ return -ENOMEM;
|
|
||||||
+
|
|
||||||
+ /* Start at index 1, index 0 standard WFI */
|
|
||||||
+ ret = dt_init_idle_driver(drv, stm32_idle_state_match, 1);
|
|
||||||
+ if (ret < 0)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
+ /* all the cpus of the system are coupled */
|
|
||||||
+ ret = cpuidle_register(drv, cpu_possible_mask);
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
+ /* Declare cpuidle domain */
|
|
||||||
+ domain = devm_kzalloc(dev, sizeof(*domain), GFP_KERNEL);
|
|
||||||
+ if (!domain)
|
|
||||||
+ return -ENOMEM;
|
|
||||||
+
|
|
||||||
+ ret = stm32_cpuidle_domain_add(domain, dev, np);
|
|
||||||
+ if (ret) {
|
|
||||||
+ devm_kfree(dev, domain);
|
|
||||||
+ return ret;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* disable cpu idle */
|
|
||||||
+ for_each_possible_cpu(cpu) {
|
|
||||||
+ struct cpuidle_device *cpuidle_dev = per_cpu(cpuidle_devices,
|
|
||||||
+ cpu);
|
|
||||||
+
|
|
||||||
+ cpuidle_dev->states_usage[1].disable = true;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* link main cpuidle domain to consumer domain */
|
|
||||||
+ for_each_child_of_node(np, np_child) {
|
|
||||||
+ if (!of_parse_phandle_with_args(np_child, "power-domains",
|
|
||||||
+ "#power-domain-cells",
|
|
||||||
+ 0, &child)) {
|
|
||||||
+ struct device_node *np_test = child.np;
|
|
||||||
+
|
|
||||||
+ parent.np = np;
|
|
||||||
+ parent.args_count = 0;
|
|
||||||
+
|
|
||||||
+ ret = of_genpd_add_subdomain(&parent, &child);
|
|
||||||
+ if (ret < 0)
|
|
||||||
+ dev_err(dev, "failed to add Sub PM domain %d\n",
|
|
||||||
+ ret);
|
|
||||||
+
|
|
||||||
+ dev_dbg(dev, "%s, add sub cpuidle of %s, with child %s\n",
|
|
||||||
+ __func__, np->name, np_test->name);
|
|
||||||
+
|
|
||||||
+ pm_runtime_put(dev);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ dev_info(dev, "cpuidle domain probed\n");
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+int stm32_cpuidle_remove(struct platform_device *pdev)
|
|
||||||
+{
|
|
||||||
+ cpuidle_unregister(&stm32_idle_driver);
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static const struct of_device_id stm32_cpuidle_of_match[] = {
|
|
||||||
+ {
|
|
||||||
+ .compatible = "stm32,cpuidle",
|
|
||||||
+ },
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static struct platform_driver stm32_cpuidle_driver = {
|
|
||||||
+ .probe = stm32_cpuidle_probe,
|
|
||||||
+ .remove = stm32_cpuidle_remove,
|
|
||||||
+ .driver = {
|
|
||||||
+ .name = "stm32_cpuidle",
|
|
||||||
+ .owner = THIS_MODULE,
|
|
||||||
+ .of_match_table = stm32_cpuidle_of_match,
|
|
||||||
+ },
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+module_platform_driver(stm32_cpuidle_driver);
|
|
||||||
+
|
|
||||||
+MODULE_AUTHOR("<>");
|
|
||||||
+MODULE_DESCRIPTION("STM32 cpu idle driver");
|
|
||||||
+MODULE_LICENSE("GPL v2");
|
|
||||||
diff --git a/drivers/nvmem/stm32-romem.c b/drivers/nvmem/stm32-romem.c
|
|
||||||
index 354be5268..14013fa66 100644
|
|
||||||
--- a/drivers/nvmem/stm32-romem.c
|
|
||||||
+++ b/drivers/nvmem/stm32-romem.c
|
|
||||||
@@ -2,15 +2,17 @@
|
|
||||||
/*
|
|
||||||
* STM32 Factory-programmed memory read access driver
|
|
||||||
*
|
|
||||||
- * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
|
|
||||||
+ * Copyright (C) 2017-2021, STMicroelectronics - All Rights Reserved
|
|
||||||
* Author: Fabrice Gasnier <fabrice.gasnier@st.com> for STMicroelectronics.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/arm-smccc.h>
|
|
||||||
+#include <linux/clk.h>
|
|
||||||
#include <linux/io.h>
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/nvmem-provider.h>
|
|
||||||
#include <linux/of_device.h>
|
|
||||||
+#include <linux/pm_runtime.h>
|
|
||||||
|
|
||||||
/* BSEC secure service access from non-secure */
|
|
||||||
#define STM32_SMC_BSEC 0x82001003
|
|
||||||
@@ -25,6 +27,8 @@
|
|
||||||
/* 32 (x 32-bits) lower shadow registers */
|
|
||||||
#define STM32MP15_BSEC_NUM_LOWER 32
|
|
||||||
|
|
||||||
+#define STM32_ROMEM_AUTOSUSPEND_DELAY_MS 50
|
|
||||||
+
|
|
||||||
struct stm32_romem_cfg {
|
|
||||||
int size;
|
|
||||||
};
|
|
||||||
@@ -32,6 +36,7 @@ struct stm32_romem_cfg {
|
|
||||||
struct stm32_romem_priv {
|
|
||||||
void __iomem *base;
|
|
||||||
struct nvmem_config cfg;
|
|
||||||
+ struct clk *clk;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int stm32_romem_read(void *context, unsigned int offset, void *buf,
|
|
||||||
@@ -39,11 +44,18 @@ static int stm32_romem_read(void *context, unsigned int offset, void *buf,
|
|
||||||
{
|
|
||||||
struct stm32_romem_priv *priv = context;
|
|
||||||
u8 *buf8 = buf;
|
|
||||||
- int i;
|
|
||||||
+ int i, ret;
|
|
||||||
+
|
|
||||||
+ ret = pm_runtime_resume_and_get(priv->cfg.dev);
|
|
||||||
+ if (ret < 0)
|
|
||||||
+ return ret;
|
|
||||||
|
|
||||||
for (i = offset; i < offset + bytes; i++)
|
|
||||||
*buf8++ = readb_relaxed(priv->base + i);
|
|
||||||
|
|
||||||
+ pm_runtime_mark_last_busy(priv->cfg.dev);
|
|
||||||
+ pm_runtime_put_autosuspend(priv->cfg.dev);
|
|
||||||
+
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -74,13 +86,19 @@ static int stm32_bsec_read(void *context, unsigned int offset, void *buf,
|
|
||||||
u8 *buf8 = buf, *val8 = (u8 *)&val;
|
|
||||||
int i, j = 0, ret, skip_bytes, size;
|
|
||||||
|
|
||||||
+ ret = pm_runtime_resume_and_get(priv->cfg.dev);
|
|
||||||
+ if (ret < 0)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
/* Round unaligned access to 32-bits */
|
|
||||||
roffset = rounddown(offset, 4);
|
|
||||||
skip_bytes = offset & 0x3;
|
|
||||||
rbytes = roundup(bytes + skip_bytes, 4);
|
|
||||||
|
|
||||||
- if (roffset + rbytes > priv->cfg.size)
|
|
||||||
- return -EINVAL;
|
|
||||||
+ if (roffset + rbytes > priv->cfg.size) {
|
|
||||||
+ ret = -EINVAL;
|
|
||||||
+ goto end_read;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
for (i = roffset; (i < roffset + rbytes); i += 4) {
|
|
||||||
u32 otp = i >> 2;
|
|
||||||
@@ -95,7 +113,7 @@ static int stm32_bsec_read(void *context, unsigned int offset, void *buf,
|
|
||||||
if (ret) {
|
|
||||||
dev_err(dev, "Can't read data%d (%d)\n", otp,
|
|
||||||
ret);
|
|
||||||
- return ret;
|
|
||||||
+ goto end_read;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* skip first bytes in case of unaligned read */
|
|
||||||
@@ -109,7 +127,11 @@ static int stm32_bsec_read(void *context, unsigned int offset, void *buf,
|
|
||||||
skip_bytes = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
- return 0;
|
|
||||||
+end_read:
|
|
||||||
+ pm_runtime_mark_last_busy(priv->cfg.dev);
|
|
||||||
+ pm_runtime_put_autosuspend(priv->cfg.dev);
|
|
||||||
+
|
|
||||||
+ return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int stm32_bsec_write(void *context, unsigned int offset, void *buf,
|
|
||||||
@@ -120,20 +142,30 @@ static int stm32_bsec_write(void *context, unsigned int offset, void *buf,
|
|
||||||
u32 *buf32 = buf;
|
|
||||||
int ret, i;
|
|
||||||
|
|
||||||
+ ret = pm_runtime_resume_and_get(priv->cfg.dev);
|
|
||||||
+ if (ret < 0)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
/* Allow only writing complete 32-bits aligned words */
|
|
||||||
- if ((bytes % 4) || (offset % 4))
|
|
||||||
- return -EINVAL;
|
|
||||||
+ if ((bytes % 4) || (offset % 4)) {
|
|
||||||
+ ret = -EINVAL;
|
|
||||||
+ goto end_write;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
for (i = offset; i < offset + bytes; i += 4) {
|
|
||||||
ret = stm32_bsec_smc(STM32_SMC_PROG_OTP, i >> 2, *buf32++,
|
|
||||||
NULL);
|
|
||||||
if (ret) {
|
|
||||||
dev_err(dev, "Can't write data%d (%d)\n", i >> 2, ret);
|
|
||||||
- return ret;
|
|
||||||
+ goto end_write;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- return 0;
|
|
||||||
+end_write:
|
|
||||||
+ pm_runtime_mark_last_busy(priv->cfg.dev);
|
|
||||||
+ pm_runtime_put_autosuspend(priv->cfg.dev);
|
|
||||||
+
|
|
||||||
+ return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int stm32_romem_probe(struct platform_device *pdev)
|
|
||||||
@@ -142,6 +174,8 @@ static int stm32_romem_probe(struct platform_device *pdev)
|
|
||||||
struct device *dev = &pdev->dev;
|
|
||||||
struct stm32_romem_priv *priv;
|
|
||||||
struct resource *res;
|
|
||||||
+ struct nvmem_device *nvmem;
|
|
||||||
+ int ret;
|
|
||||||
|
|
||||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
|
||||||
if (!priv)
|
|
||||||
@@ -159,6 +193,27 @@ static int stm32_romem_probe(struct platform_device *pdev)
|
|
||||||
priv->cfg.priv = priv;
|
|
||||||
priv->cfg.owner = THIS_MODULE;
|
|
||||||
|
|
||||||
+ priv->clk = devm_clk_get_optional(&pdev->dev, NULL);
|
|
||||||
+ if (IS_ERR(priv->clk))
|
|
||||||
+ return dev_err_probe(dev, PTR_ERR(priv->clk),
|
|
||||||
+ "failed to get clock\n");
|
|
||||||
+
|
|
||||||
+ if (priv->clk) {
|
|
||||||
+ ret = clk_prepare_enable(priv->clk);
|
|
||||||
+ if (ret) {
|
|
||||||
+ dev_err(dev, "failed to enable clock (%d)\n", ret);
|
|
||||||
+ return ret;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ pm_runtime_set_autosuspend_delay(dev,
|
|
||||||
+ STM32_ROMEM_AUTOSUSPEND_DELAY_MS);
|
|
||||||
+ pm_runtime_use_autosuspend(dev);
|
|
||||||
+
|
|
||||||
+ pm_runtime_get_noresume(dev);
|
|
||||||
+ pm_runtime_set_active(dev);
|
|
||||||
+ pm_runtime_enable(dev);
|
|
||||||
+
|
|
||||||
cfg = (const struct stm32_romem_cfg *)
|
|
||||||
of_match_device(dev->driver->of_match_table, dev)->data;
|
|
||||||
if (!cfg) {
|
|
||||||
@@ -171,9 +226,95 @@ static int stm32_romem_probe(struct platform_device *pdev)
|
|
||||||
priv->cfg.reg_write = stm32_bsec_write;
|
|
||||||
}
|
|
||||||
|
|
||||||
- return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &priv->cfg));
|
|
||||||
+ platform_set_drvdata(pdev, priv);
|
|
||||||
+
|
|
||||||
+ nvmem = nvmem_register(&priv->cfg);
|
|
||||||
+ if (IS_ERR(nvmem))
|
|
||||||
+ goto err_pm_stop;
|
|
||||||
+
|
|
||||||
+ pm_runtime_mark_last_busy(dev);
|
|
||||||
+ pm_runtime_put_autosuspend(dev);
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
+err_pm_stop:
|
|
||||||
+ pm_runtime_disable(dev);
|
|
||||||
+ pm_runtime_set_suspended(dev);
|
|
||||||
+ pm_runtime_put_noidle(dev);
|
|
||||||
+
|
|
||||||
+ if (priv->clk)
|
|
||||||
+ clk_disable_unprepare(priv->clk);
|
|
||||||
+
|
|
||||||
+ return PTR_ERR(nvmem);
|
|
||||||
}
|
|
||||||
|
|
||||||
+static int stm32_romem_remove(struct platform_device *pdev)
|
|
||||||
+{
|
|
||||||
+ struct stm32_romem_priv *priv;
|
|
||||||
+ int ret;
|
|
||||||
+
|
|
||||||
+ priv = dev_get_drvdata(&pdev->dev);
|
|
||||||
+ if (!priv)
|
|
||||||
+ return -ENODEV;
|
|
||||||
+
|
|
||||||
+ ret = pm_runtime_get_sync(&pdev->dev);
|
|
||||||
+ if (ret < 0)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
+ nvmem_unregister((struct nvmem_device *)&priv->cfg);
|
|
||||||
+
|
|
||||||
+ pm_runtime_disable(&pdev->dev);
|
|
||||||
+ pm_runtime_set_suspended(&pdev->dev);
|
|
||||||
+ pm_runtime_put_noidle(&pdev->dev);
|
|
||||||
+
|
|
||||||
+ if (priv->clk)
|
|
||||||
+ clk_disable_unprepare(priv->clk);
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int __maybe_unused stm32_romem_runtime_suspend(struct device *dev)
|
|
||||||
+{
|
|
||||||
+ struct stm32_romem_priv *priv;
|
|
||||||
+
|
|
||||||
+ priv = dev_get_drvdata(dev);
|
|
||||||
+ if (!priv)
|
|
||||||
+ return -ENODEV;
|
|
||||||
+
|
|
||||||
+ if (priv->clk)
|
|
||||||
+ clk_disable_unprepare(priv->clk);
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int __maybe_unused stm32_romem_runtime_resume(struct device *dev)
|
|
||||||
+{
|
|
||||||
+ struct stm32_romem_priv *priv;
|
|
||||||
+ int ret;
|
|
||||||
+
|
|
||||||
+ priv = dev_get_drvdata(dev);
|
|
||||||
+ if (!priv)
|
|
||||||
+ return -ENODEV;
|
|
||||||
+
|
|
||||||
+ if (priv->clk) {
|
|
||||||
+ ret = clk_prepare_enable(priv->clk);
|
|
||||||
+ if (ret) {
|
|
||||||
+ dev_err(priv->cfg.dev,
|
|
||||||
+ "Failed to prepare_enable clock (%d)\n", ret);
|
|
||||||
+ return ret;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static const struct dev_pm_ops stm32_romem_pm_ops = {
|
|
||||||
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
|
|
||||||
+ pm_runtime_force_resume)
|
|
||||||
+ SET_RUNTIME_PM_OPS(stm32_romem_runtime_suspend,
|
|
||||||
+ stm32_romem_runtime_resume, NULL)
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static const struct stm32_romem_cfg stm32mp15_bsec_cfg = {
|
|
||||||
.size = 384, /* 96 x 32-bits data words */
|
|
||||||
};
|
|
||||||
@@ -189,8 +330,10 @@ MODULE_DEVICE_TABLE(of, stm32_romem_of_match);
|
|
||||||
|
|
||||||
static struct platform_driver stm32_romem_driver = {
|
|
||||||
.probe = stm32_romem_probe,
|
|
||||||
+ .remove = stm32_romem_remove,
|
|
||||||
.driver = {
|
|
||||||
.name = "stm32-romem",
|
|
||||||
+ .pm = &stm32_romem_pm_ops,
|
|
||||||
.of_match_table = of_match_ptr(stm32_romem_of_match),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
diff --git a/include/linux/pm_wakeup.h b/include/linux/pm_wakeup.h
|
|
||||||
index aa3da6611..196a15745 100644
|
|
||||||
--- a/include/linux/pm_wakeup.h
|
|
||||||
+++ b/include/linux/pm_wakeup.h
|
|
||||||
@@ -84,6 +84,11 @@ static inline bool device_may_wakeup(struct device *dev)
|
|
||||||
return dev->power.can_wakeup && !!dev->power.wakeup;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static inline bool device_wakeup_path(struct device *dev)
|
|
||||||
+{
|
|
||||||
+ return dev->power.wakeup_path;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static inline void device_set_wakeup_path(struct device *dev)
|
|
||||||
{
|
|
||||||
dev->power.wakeup_path = true;
|
|
||||||
@@ -174,6 +179,11 @@ static inline bool device_may_wakeup(struct device *dev)
|
|
||||||
return dev->power.can_wakeup && dev->power.should_wakeup;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static inline bool device_wakeup_path(struct device *dev)
|
|
||||||
+{
|
|
||||||
+ return false;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static inline void device_set_wakeup_path(struct device *dev) {}
|
|
||||||
|
|
||||||
static inline void __pm_stay_awake(struct wakeup_source *ws) {}
|
|
||||||
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
|
|
||||||
index 32391acc8..dc800d4f5 100644
|
|
||||||
--- a/kernel/power/suspend.c
|
|
||||||
+++ b/kernel/power/suspend.c
|
|
||||||
@@ -34,7 +34,6 @@
|
|
||||||
#include "power.h"
|
|
||||||
|
|
||||||
const char * const pm_labels[] = {
|
|
||||||
- [PM_SUSPEND_TO_IDLE] = "freeze",
|
|
||||||
[PM_SUSPEND_STANDBY] = "standby",
|
|
||||||
[PM_SUSPEND_MEM] = "mem",
|
|
||||||
};
|
|
||||||
--
|
|
||||||
2.17.1
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,124 @@
|
||||||
|
From 4868d40c41f2fb7dea18d7b5fe14da02fc82e2f1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Christophe Priouzeau <christophe.priouzeau@foss.st.com>
|
||||||
|
Date: Tue, 31 May 2022 11:50:09 +0200
|
||||||
|
Subject: [PATCH 01/22] ARM-5.15.24-stm32mp1-r1-MACHINE
|
||||||
|
|
||||||
|
Signed-off-by: Christophe Priouzeau <christophe.priouzeau@foss.st.com>
|
||||||
|
---
|
||||||
|
Documentation/arm/index.rst | 1 +
|
||||||
|
.../arm/stm32/stm32mp13-overview.rst | 37 +++++++++++++++++++
|
||||||
|
arch/arm/Kconfig.debug | 2 +-
|
||||||
|
arch/arm/mach-stm32/Kconfig | 9 +++++
|
||||||
|
arch/arm/mach-stm32/board-dt.c | 5 +++
|
||||||
|
5 files changed, 53 insertions(+), 1 deletion(-)
|
||||||
|
create mode 100644 Documentation/arm/stm32/stm32mp13-overview.rst
|
||||||
|
|
||||||
|
diff --git a/Documentation/arm/index.rst b/Documentation/arm/index.rst
|
||||||
|
index d4f34ae9e..2bda5461a 100644
|
||||||
|
--- a/Documentation/arm/index.rst
|
||||||
|
+++ b/Documentation/arm/index.rst
|
||||||
|
@@ -55,6 +55,7 @@ SoC-specific documents
|
||||||
|
stm32/stm32h750-overview
|
||||||
|
stm32/stm32f769-overview
|
||||||
|
stm32/stm32f429-overview
|
||||||
|
+ stm32/stm32mp13-overview
|
||||||
|
stm32/stm32mp157-overview
|
||||||
|
|
||||||
|
sunxi
|
||||||
|
diff --git a/Documentation/arm/stm32/stm32mp13-overview.rst b/Documentation/arm/stm32/stm32mp13-overview.rst
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..3bb9492da
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/Documentation/arm/stm32/stm32mp13-overview.rst
|
||||||
|
@@ -0,0 +1,37 @@
|
||||||
|
+===================
|
||||||
|
+STM32MP13 Overview
|
||||||
|
+===================
|
||||||
|
+
|
||||||
|
+Introduction
|
||||||
|
+------------
|
||||||
|
+
|
||||||
|
+The STM32MP131/STM32MP133/STM32MP135 are Cortex-A MPU aimed at various applications.
|
||||||
|
+They feature:
|
||||||
|
+
|
||||||
|
+- One Cortex-A7 application core
|
||||||
|
+- Standard memories interface support
|
||||||
|
+- Standard connectivity, widely inherited from the STM32 MCU family
|
||||||
|
+- Comprehensive security support
|
||||||
|
+
|
||||||
|
+More details:
|
||||||
|
+
|
||||||
|
+- Cortex-A7 core running up to @900MHz
|
||||||
|
+- FMC controller to connect SDRAM, NOR and NAND memories
|
||||||
|
+- QSPI
|
||||||
|
+- SD/MMC/SDIO support
|
||||||
|
+- 2*Ethernet controller
|
||||||
|
+- CAN
|
||||||
|
+- ADC/DAC
|
||||||
|
+- USB EHCI/OHCI controllers
|
||||||
|
+- USB OTG
|
||||||
|
+- I2C, SPI, CAN busses support
|
||||||
|
+- Several general purpose timers
|
||||||
|
+- Serial Audio interface
|
||||||
|
+- LCD controller
|
||||||
|
+- DCMIPP
|
||||||
|
+- SPDIFRX
|
||||||
|
+- DFSDM
|
||||||
|
+
|
||||||
|
+:Authors:
|
||||||
|
+
|
||||||
|
+- Alexandre Torgue <alexandre.torgue@foss.st.com>
|
||||||
|
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
|
||||||
|
index 644875d73..37b833761 100644
|
||||||
|
--- a/arch/arm/Kconfig.debug
|
||||||
|
+++ b/arch/arm/Kconfig.debug
|
||||||
|
@@ -1244,7 +1244,7 @@ choice
|
||||||
|
|
||||||
|
config STM32MP1_DEBUG_UART
|
||||||
|
bool "Use STM32MP1 UART for low-level debug"
|
||||||
|
- depends on MACH_STM32MP157
|
||||||
|
+ depends on MACH_STM32MP157 || MACH_STM32MP13
|
||||||
|
select DEBUG_STM32_UART
|
||||||
|
help
|
||||||
|
Say Y here if you want kernel low-level debugging support
|
||||||
|
diff --git a/arch/arm/mach-stm32/Kconfig b/arch/arm/mach-stm32/Kconfig
|
||||||
|
index 57699bd8f..ab6978451 100644
|
||||||
|
--- a/arch/arm/mach-stm32/Kconfig
|
||||||
|
+++ b/arch/arm/mach-stm32/Kconfig
|
||||||
|
@@ -46,8 +46,17 @@ if ARCH_MULTI_V7
|
||||||
|
config MACH_STM32MP157
|
||||||
|
bool "STMicroelectronics STM32MP157"
|
||||||
|
select ARM_ERRATA_814220
|
||||||
|
+ select REGULATOR
|
||||||
|
default y
|
||||||
|
|
||||||
|
+config MACH_STM32MP13
|
||||||
|
+ bool "STMicroelectronics STM32MP13x"
|
||||||
|
+ select ARM_ERRATA_814220
|
||||||
|
+ default y
|
||||||
|
+ help
|
||||||
|
+ Support for STM32MP13 SoCs:
|
||||||
|
+ STM32MP131, STM32MP133, STM32MP135
|
||||||
|
+
|
||||||
|
endif # ARMv7-A
|
||||||
|
|
||||||
|
endif
|
||||||
|
diff --git a/arch/arm/mach-stm32/board-dt.c b/arch/arm/mach-stm32/board-dt.c
|
||||||
|
index a766310d8..9ff06f2fc 100644
|
||||||
|
--- a/arch/arm/mach-stm32/board-dt.c
|
||||||
|
+++ b/arch/arm/mach-stm32/board-dt.c
|
||||||
|
@@ -18,6 +18,11 @@ static const char *const stm32_compat[] __initconst = {
|
||||||
|
"st,stm32f769",
|
||||||
|
"st,stm32h743",
|
||||||
|
"st,stm32h750",
|
||||||
|
+ "st,stm32mp131",
|
||||||
|
+ "st,stm32mp133",
|
||||||
|
+ "st,stm32mp135",
|
||||||
|
+ "st,stm32mp151",
|
||||||
|
+ "st,stm32mp153",
|
||||||
|
"st,stm32mp157",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,21 +1,22 @@
|
||||||
From f425522a8000b8fe201de2db79367a1a7e7b7fdb Mon Sep 17 00:00:00 2001
|
From 1aacc70479e14dd5ca0e60a969478957a390dbda Mon Sep 17 00:00:00 2001
|
||||||
From: Lionel Vitte <lionel.vitte@st.com>
|
From: Christophe Priouzeau <christophe.priouzeau@foss.st.com>
|
||||||
Date: Thu, 14 Oct 2021 16:51:41 +0200
|
Date: Tue, 31 May 2022 11:51:10 +0200
|
||||||
Subject: [PATCH 03/23] ARM 5.10.61-stm32mp1-r2 CPUFREQ
|
Subject: [PATCH 03/22] ARM-5.15.24-stm32mp1-r1-CPUFREQ
|
||||||
|
|
||||||
|
Signed-off-by: Christophe Priouzeau <christophe.priouzeau@foss.st.com>
|
||||||
---
|
---
|
||||||
drivers/cpufreq/Kconfig.arm | 7 ++
|
drivers/cpufreq/Kconfig.arm | 7 ++
|
||||||
drivers/cpufreq/Makefile | 1 +
|
drivers/cpufreq/Makefile | 1 +
|
||||||
drivers/cpufreq/cpufreq-dt-platdev.c | 3 +
|
drivers/cpufreq/cpufreq-dt-platdev.c | 1 +
|
||||||
drivers/cpufreq/stm32-cpufreq.c | 101 +++++++++++++++++++++++++++
|
drivers/cpufreq/stm32-cpufreq.c | 103 +++++++++++++++++++++++++++
|
||||||
4 files changed, 112 insertions(+)
|
4 files changed, 112 insertions(+)
|
||||||
create mode 100644 drivers/cpufreq/stm32-cpufreq.c
|
create mode 100644 drivers/cpufreq/stm32-cpufreq.c
|
||||||
|
|
||||||
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
|
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
|
||||||
index 1f73fa75b..56b210670 100644
|
index 954749afb..eac08e907 100644
|
||||||
--- a/drivers/cpufreq/Kconfig.arm
|
--- a/drivers/cpufreq/Kconfig.arm
|
||||||
+++ b/drivers/cpufreq/Kconfig.arm
|
+++ b/drivers/cpufreq/Kconfig.arm
|
||||||
@@ -289,6 +289,13 @@ config ARM_STI_CPUFREQ
|
@@ -311,6 +311,13 @@ config ARM_STI_CPUFREQ
|
||||||
this config option if you wish to add CPUFreq support for STi based
|
this config option if you wish to add CPUFreq support for STi based
|
||||||
SoCs.
|
SoCs.
|
||||||
|
|
||||||
|
|
@ -26,11 +27,11 @@ index 1f73fa75b..56b210670 100644
|
||||||
+ help
|
+ help
|
||||||
+ This adds the CPUFreq driver support for STM32 MPU SOCs.
|
+ This adds the CPUFreq driver support for STM32 MPU SOCs.
|
||||||
+
|
+
|
||||||
config ARM_TANGO_CPUFREQ
|
config ARM_TEGRA20_CPUFREQ
|
||||||
bool
|
tristate "Tegra20/30 CPUFreq support"
|
||||||
depends on CPUFREQ_DT && ARCH_TANGO
|
depends on ARCH_TEGRA && CPUFREQ_DT
|
||||||
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
|
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
|
||||||
index f1b7e3dd6..b373f97f2 100644
|
index 48ee58590..d34de1b92 100644
|
||||||
--- a/drivers/cpufreq/Makefile
|
--- a/drivers/cpufreq/Makefile
|
||||||
+++ b/drivers/cpufreq/Makefile
|
+++ b/drivers/cpufreq/Makefile
|
||||||
@@ -78,6 +78,7 @@ obj-$(CONFIG_ARM_SCMI_CPUFREQ) += scmi-cpufreq.o
|
@@ -78,6 +78,7 @@ obj-$(CONFIG_ARM_SCMI_CPUFREQ) += scmi-cpufreq.o
|
||||||
|
|
@ -39,28 +40,26 @@ index f1b7e3dd6..b373f97f2 100644
|
||||||
obj-$(CONFIG_ARM_STI_CPUFREQ) += sti-cpufreq.o
|
obj-$(CONFIG_ARM_STI_CPUFREQ) += sti-cpufreq.o
|
||||||
+obj-$(CONFIG_ARM_STM32_CPUFREQ) += stm32-cpufreq.o
|
+obj-$(CONFIG_ARM_STM32_CPUFREQ) += stm32-cpufreq.o
|
||||||
obj-$(CONFIG_ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM) += sun50i-cpufreq-nvmem.o
|
obj-$(CONFIG_ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM) += sun50i-cpufreq-nvmem.o
|
||||||
obj-$(CONFIG_ARM_TANGO_CPUFREQ) += tango-cpufreq.o
|
|
||||||
obj-$(CONFIG_ARM_TEGRA20_CPUFREQ) += tegra20-cpufreq.o
|
obj-$(CONFIG_ARM_TEGRA20_CPUFREQ) += tegra20-cpufreq.o
|
||||||
|
obj-$(CONFIG_ARM_TEGRA124_CPUFREQ) += tegra124-cpufreq.o
|
||||||
diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
|
diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
|
||||||
index 1c192a42f..4d72dbb3a 100644
|
index ca1d103ec..f205e6e97 100644
|
||||||
--- a/drivers/cpufreq/cpufreq-dt-platdev.c
|
--- a/drivers/cpufreq/cpufreq-dt-platdev.c
|
||||||
+++ b/drivers/cpufreq/cpufreq-dt-platdev.c
|
+++ b/drivers/cpufreq/cpufreq-dt-platdev.c
|
||||||
@@ -140,6 +140,9 @@ static const struct of_device_id blacklist[] __initconst = {
|
@@ -150,6 +150,7 @@ static const struct of_device_id blocklist[] __initconst = {
|
||||||
{ .compatible = "st,stih407", },
|
{ .compatible = "st,stih407", },
|
||||||
{ .compatible = "st,stih410", },
|
{ .compatible = "st,stih410", },
|
||||||
{ .compatible = "st,stih418", },
|
{ .compatible = "st,stih418", },
|
||||||
+ { .compatible = "st,stm32mp151", },
|
|
||||||
+ { .compatible = "st,stm32mp153", },
|
|
||||||
+ { .compatible = "st,stm32mp157", },
|
+ { .compatible = "st,stm32mp157", },
|
||||||
|
|
||||||
{ .compatible = "sigma,tango4", },
|
{ .compatible = "ti,am33xx", },
|
||||||
|
{ .compatible = "ti,am43", },
|
||||||
diff --git a/drivers/cpufreq/stm32-cpufreq.c b/drivers/cpufreq/stm32-cpufreq.c
|
diff --git a/drivers/cpufreq/stm32-cpufreq.c b/drivers/cpufreq/stm32-cpufreq.c
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 000000000..35fb3520d
|
index 000000000..d7b1b16ea
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/drivers/cpufreq/stm32-cpufreq.c
|
+++ b/drivers/cpufreq/stm32-cpufreq.c
|
||||||
@@ -0,0 +1,101 @@
|
@@ -0,0 +1,103 @@
|
||||||
+// SPDX-License-Identifier: GPL-2.0-only
|
+// SPDX-License-Identifier: GPL-2.0-only
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
|
+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
|
||||||
|
|
@ -104,7 +103,9 @@ index 000000000..35fb3520d
|
||||||
+ /* Get chip info */
|
+ /* Get chip info */
|
||||||
+ ret = nvmem_cell_read_u8(cpu_dev, "part_number", &part_number);
|
+ ret = nvmem_cell_read_u8(cpu_dev, "part_number", &part_number);
|
||||||
+ if (ret) {
|
+ if (ret) {
|
||||||
+ dev_err(&pdev->dev, "Failed to get chip info: %d\n", ret);
|
+ if (ret != -EPROBE_DEFER)
|
||||||
|
+ dev_err(&pdev->dev, "Failed to get chip info: %d\n",
|
||||||
|
+ ret);
|
||||||
+ return ret;
|
+ return ret;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
|
|
@ -163,5 +164,5 @@ index 000000000..35fb3520d
|
||||||
+MODULE_AUTHOR("Alexandre Torgue <alexandre.torgue@st.com>");
|
+MODULE_AUTHOR("Alexandre Torgue <alexandre.torgue@st.com>");
|
||||||
+MODULE_LICENSE("GPL v2");
|
+MODULE_LICENSE("GPL v2");
|
||||||
--
|
--
|
||||||
2.17.1
|
2.25.1
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -1,15 +1,95 @@
|
||||||
From e6689ed5bee01020d4f2411e92c3741a06232c92 Mon Sep 17 00:00:00 2001
|
From 924efc211ec362bf6b42a5f18327ad6b8b0652a2 Mon Sep 17 00:00:00 2001
|
||||||
From: Lionel Vitte <lionel.vitte@st.com>
|
From: Christophe Priouzeau <christophe.priouzeau@foss.st.com>
|
||||||
Date: Thu, 14 Oct 2021 16:51:43 +0200
|
Date: Tue, 31 May 2022 11:53:54 +0200
|
||||||
Subject: [PATCH 07/23] ARM 5.10.61-stm32mp1-r2 HWSPINLOCK
|
Subject: [PATCH 07/22] ARM-5.15.24-stm32mp1-r1-HWSPINLOCK
|
||||||
|
|
||||||
|
Signed-off-by: Christophe Priouzeau <christophe.priouzeau@foss.st.com>
|
||||||
---
|
---
|
||||||
Documentation/locking/hwspinlock.rst | 10 ++-
|
.../devicetree/bindings/hwlock/hwlock.txt | 27 +++++--
|
||||||
drivers/hwspinlock/hwspinlock_core.c | 80 +++++++++++++++++++-----
|
.../bindings/hwlock/st,stm32-hwspinlock.yaml | 4 +-
|
||||||
drivers/hwspinlock/hwspinlock_internal.h | 2 +
|
Documentation/locking/hwspinlock.rst | 10 ++-
|
||||||
drivers/hwspinlock/stm32_hwspinlock.c | 60 +++++++++++-------
|
drivers/hwspinlock/hwspinlock_core.c | 80 +++++++++++++++----
|
||||||
4 files changed, 110 insertions(+), 42 deletions(-)
|
drivers/hwspinlock/hwspinlock_internal.h | 2 +
|
||||||
|
drivers/hwspinlock/stm32_hwspinlock.c | 58 +++++++++-----
|
||||||
|
6 files changed, 131 insertions(+), 50 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Documentation/devicetree/bindings/hwlock/hwlock.txt b/Documentation/devicetree/bindings/hwlock/hwlock.txt
|
||||||
|
index 085d1f5c9..e98088a40 100644
|
||||||
|
--- a/Documentation/devicetree/bindings/hwlock/hwlock.txt
|
||||||
|
+++ b/Documentation/devicetree/bindings/hwlock/hwlock.txt
|
||||||
|
@@ -13,7 +13,7 @@ hwlock providers:
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- #hwlock-cells: Specifies the number of cells needed to represent a
|
||||||
|
- specific lock.
|
||||||
|
+ specific lock. Shall be 1 or 2 (see hwlocks below).
|
||||||
|
|
||||||
|
hwlock users:
|
||||||
|
=============
|
||||||
|
@@ -27,6 +27,11 @@ Required properties:
|
||||||
|
#hwlock-cells. The list can have just a single hwlock
|
||||||
|
or multiple hwlocks, with each hwlock represented by
|
||||||
|
a phandle and a corresponding args specifier.
|
||||||
|
+ If #hwlock-cells is 1, all of the locks are exclusive
|
||||||
|
+ (cannot be used by several users).
|
||||||
|
+ If #hwlock-cells is 2, the value of the second cell
|
||||||
|
+ defines whether the lock is for exclusive usage (0) or
|
||||||
|
+ shared (1) i.e. can be used by several users.
|
||||||
|
|
||||||
|
Optional properties:
|
||||||
|
- hwlock-names: List of hwlock name strings defined in the same order
|
||||||
|
@@ -46,14 +51,22 @@ of length 1.
|
||||||
|
...
|
||||||
|
};
|
||||||
|
|
||||||
|
-2. Example of a node using multiple specific hwlocks:
|
||||||
|
+2. Example of nodes using multiple and shared specific hwlocks:
|
||||||
|
|
||||||
|
-The following example has a node requesting two hwlocks, a hwlock within
|
||||||
|
-the hwlock device node 'hwlock1' with #hwlock-cells value of 1, and another
|
||||||
|
-hwlock within the hwlock device node 'hwlock2' with #hwlock-cells value of 2.
|
||||||
|
+The following example has a nodeA requesting two hwlocks:
|
||||||
|
+- an exclusive one (#hwlock-cells = 1) within the hwlock device node 'hwlock1'
|
||||||
|
+- a shared one (#hwlock-cells = 2, second cell = 1) within the hwlock device
|
||||||
|
+ node 'hwlock2'.
|
||||||
|
+The shared lock is also be used by nodeB.
|
||||||
|
|
||||||
|
- node {
|
||||||
|
+ nodeA {
|
||||||
|
...
|
||||||
|
- hwlocks = <&hwlock1 2>, <&hwlock2 0 3>;
|
||||||
|
+ hwlocks = <&hwlock1 2>, <&hwlock2 0 1>;
|
||||||
|
...
|
||||||
|
};
|
||||||
|
+
|
||||||
|
+ nodeB {
|
||||||
|
+ ...
|
||||||
|
+ hwlocks = <&hwlock2 0 1>;
|
||||||
|
+ ...
|
||||||
|
+ };
|
||||||
|
\ No newline at end of file
|
||||||
|
diff --git a/Documentation/devicetree/bindings/hwlock/st,stm32-hwspinlock.yaml b/Documentation/devicetree/bindings/hwlock/st,stm32-hwspinlock.yaml
|
||||||
|
index 47cf9c8d9..539a1dc05 100644
|
||||||
|
--- a/Documentation/devicetree/bindings/hwlock/st,stm32-hwspinlock.yaml
|
||||||
|
+++ b/Documentation/devicetree/bindings/hwlock/st,stm32-hwspinlock.yaml
|
||||||
|
@@ -12,7 +12,7 @@ maintainers:
|
||||||
|
|
||||||
|
properties:
|
||||||
|
"#hwlock-cells":
|
||||||
|
- const: 1
|
||||||
|
+ const: 2
|
||||||
|
|
||||||
|
compatible:
|
||||||
|
const: st,stm32-hwspinlock
|
||||||
|
@@ -41,7 +41,7 @@ examples:
|
||||||
|
#include <dt-bindings/clock/stm32mp1-clks.h>
|
||||||
|
hwspinlock@4c000000 {
|
||||||
|
compatible = "st,stm32-hwspinlock";
|
||||||
|
- #hwlock-cells = <1>;
|
||||||
|
+ #hwlock-cells = <2>;
|
||||||
|
reg = <0x4c000000 0x400>;
|
||||||
|
clocks = <&rcc HSEM>;
|
||||||
|
clock-names = "hsem";
|
||||||
diff --git a/Documentation/locking/hwspinlock.rst b/Documentation/locking/hwspinlock.rst
|
diff --git a/Documentation/locking/hwspinlock.rst b/Documentation/locking/hwspinlock.rst
|
||||||
index 6f03713b7..605bd2dc8 100644
|
index 6f03713b7..605bd2dc8 100644
|
||||||
--- a/Documentation/locking/hwspinlock.rst
|
--- a/Documentation/locking/hwspinlock.rst
|
||||||
|
|
@ -247,7 +327,7 @@ index 29892767b..e1f9c9600 100644
|
||||||
};
|
};
|
||||||
|
|
||||||
diff --git a/drivers/hwspinlock/stm32_hwspinlock.c b/drivers/hwspinlock/stm32_hwspinlock.c
|
diff --git a/drivers/hwspinlock/stm32_hwspinlock.c b/drivers/hwspinlock/stm32_hwspinlock.c
|
||||||
index 3ad0ce0da..6c3be33f3 100644
|
index 3ad0ce0da..5bd11a7fa 100644
|
||||||
--- a/drivers/hwspinlock/stm32_hwspinlock.c
|
--- a/drivers/hwspinlock/stm32_hwspinlock.c
|
||||||
+++ b/drivers/hwspinlock/stm32_hwspinlock.c
|
+++ b/drivers/hwspinlock/stm32_hwspinlock.c
|
||||||
@@ -54,8 +54,23 @@ static const struct hwspinlock_ops stm32_hwspinlock_ops = {
|
@@ -54,8 +54,23 @@ static const struct hwspinlock_ops stm32_hwspinlock_ops = {
|
||||||
|
|
@ -295,26 +375,25 @@ index 3ad0ce0da..6c3be33f3 100644
|
||||||
+ dev_err(dev, "Failed to prepare_enable clock\n");
|
+ dev_err(dev, "Failed to prepare_enable clock\n");
|
||||||
+ return ret;
|
+ return ret;
|
||||||
+ }
|
+ }
|
||||||
+
|
|
||||||
+ pm_runtime_get_noresume(dev);
|
|
||||||
+ pm_runtime_set_active(dev);
|
|
||||||
+ pm_runtime_enable(dev);
|
|
||||||
+ pm_runtime_put(dev);
|
|
||||||
|
|
||||||
platform_set_drvdata(pdev, hw);
|
platform_set_drvdata(pdev, hw);
|
||||||
- pm_runtime_enable(&pdev->dev);
|
- pm_runtime_enable(&pdev->dev);
|
||||||
|
|
||||||
- ret = hwspin_lock_register(&hw->bank, &pdev->dev, &stm32_hwspinlock_ops,
|
- ret = hwspin_lock_register(&hw->bank, &pdev->dev, &stm32_hwspinlock_ops,
|
||||||
- 0, STM32_MUTEX_NUM_LOCKS);
|
- 0, STM32_MUTEX_NUM_LOCKS);
|
||||||
|
+ pm_runtime_get_noresume(dev);
|
||||||
|
+ pm_runtime_set_active(dev);
|
||||||
|
+ pm_runtime_enable(dev);
|
||||||
|
+ pm_runtime_put(dev);
|
||||||
|
|
||||||
|
- if (ret)
|
||||||
|
- pm_runtime_disable(&pdev->dev);
|
||||||
+ ret = devm_add_action_or_reset(dev, stm32_hwspinlock_disable_clk, pdev);
|
+ ret = devm_add_action_or_reset(dev, stm32_hwspinlock_disable_clk, pdev);
|
||||||
+ if (ret) {
|
+ if (ret) {
|
||||||
+ dev_err(dev, "Failed to register action\n");
|
+ dev_err(dev, "Failed to register action\n");
|
||||||
+ return ret;
|
+ return ret;
|
||||||
+ }
|
+ }
|
||||||
|
|
||||||
- if (ret)
|
|
||||||
- pm_runtime_disable(&pdev->dev);
|
|
||||||
-
|
|
||||||
- return ret;
|
- return ret;
|
||||||
-}
|
-}
|
||||||
+ for (i = 0; i < STM32_MUTEX_NUM_LOCKS; i++)
|
+ for (i = 0; i < STM32_MUTEX_NUM_LOCKS; i++)
|
||||||
|
|
@ -348,5 +427,5 @@ index 3ad0ce0da..6c3be33f3 100644
|
||||||
.name = "stm32_hwspinlock",
|
.name = "stm32_hwspinlock",
|
||||||
.of_match_table = stm32_hwpinlock_ids,
|
.of_match_table = stm32_hwpinlock_ids,
|
||||||
--
|
--
|
||||||
2.17.1
|
2.25.1
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -1,24 +1,105 @@
|
||||||
From a8b88220ea06e256ca6268be9856a8bbe522b0b5 Mon Sep 17 00:00:00 2001
|
From d88b31f16b525087c38623bda52699ff7859dcf6 Mon Sep 17 00:00:00 2001
|
||||||
From: Lionel Vitte <lionel.vitte@st.com>
|
From: Christophe Priouzeau <christophe.priouzeau@foss.st.com>
|
||||||
Date: Thu, 14 Oct 2021 16:51:47 +0200
|
Date: Tue, 31 May 2022 11:59:44 +0200
|
||||||
Subject: [PATCH 11/23] ARM 5.10.61-stm32mp1-r2 MFD
|
Subject: [PATCH 11/22] ARM-5.15.24-stm32mp1-r1-MFD
|
||||||
|
|
||||||
|
Signed-off-by: Christophe Priouzeau <christophe.priouzeau@foss.st.com>
|
||||||
---
|
---
|
||||||
drivers/mfd/Kconfig | 10 +
|
.../bindings/mfd/st,stm32-lptimer.yaml | 3 +
|
||||||
drivers/mfd/Makefile | 1 +
|
.../bindings/mfd/st,stm32mp1-pwr.txt | 57 +++
|
||||||
drivers/mfd/stm32-pwr.c | 402 +++++++++++++++++++++++++++++++
|
drivers/mfd/Kconfig | 10 +
|
||||||
drivers/mfd/stmfx.c | 2 -
|
drivers/mfd/Makefile | 1 +
|
||||||
drivers/mfd/stpmic1.c | 6 +
|
drivers/mfd/stm32-pwr.c | 423 ++++++++++++++++++
|
||||||
drivers/mfd/wm8994-core.c | 6 +
|
drivers/mfd/stmfx.c | 2 -
|
||||||
include/linux/mfd/stm32-timers.h | 1 +
|
drivers/mfd/stpmic1.c | 6 +
|
||||||
7 files changed, 426 insertions(+), 2 deletions(-)
|
drivers/mfd/wm8994-core.c | 6 +
|
||||||
|
include/linux/mfd/stm32-timers.h | 1 +
|
||||||
|
9 files changed, 507 insertions(+), 2 deletions(-)
|
||||||
|
create mode 100644 Documentation/devicetree/bindings/mfd/st,stm32mp1-pwr.txt
|
||||||
create mode 100644 drivers/mfd/stm32-pwr.c
|
create mode 100644 drivers/mfd/stm32-pwr.c
|
||||||
|
|
||||||
|
diff --git a/Documentation/devicetree/bindings/mfd/st,stm32-lptimer.yaml b/Documentation/devicetree/bindings/mfd/st,stm32-lptimer.yaml
|
||||||
|
index 8bcea8dd7..6e518ae12 100644
|
||||||
|
--- a/Documentation/devicetree/bindings/mfd/st,stm32-lptimer.yaml
|
||||||
|
+++ b/Documentation/devicetree/bindings/mfd/st,stm32-lptimer.yaml
|
||||||
|
@@ -44,6 +44,9 @@ properties:
|
||||||
|
|
||||||
|
wakeup-source: true
|
||||||
|
|
||||||
|
+ power-domains:
|
||||||
|
+ maxItems: 1
|
||||||
|
+
|
||||||
|
pwm:
|
||||||
|
type: object
|
||||||
|
|
||||||
|
diff --git a/Documentation/devicetree/bindings/mfd/st,stm32mp1-pwr.txt b/Documentation/devicetree/bindings/mfd/st,stm32mp1-pwr.txt
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..b5f414a19
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/Documentation/devicetree/bindings/mfd/st,stm32mp1-pwr.txt
|
||||||
|
@@ -0,0 +1,57 @@
|
||||||
|
+STMicroelectronics STM32MP1 Power Management Controller
|
||||||
|
+=======================================================
|
||||||
|
+
|
||||||
|
+The PWR IP is responsible for handling the power related resources such as
|
||||||
|
+clocks, power supplies and resets. It provides 6 wake-up pins that are handled
|
||||||
|
+by an interrupt-controller. Wake-up pin can be used to wake-up from STANDBY SoC state.
|
||||||
|
+
|
||||||
|
+Required properties:
|
||||||
|
+- compatible should be: "st,stm32mp1-pwr"
|
||||||
|
+- reg: should be register base and length as documented in the
|
||||||
|
+ datasheet
|
||||||
|
+- interrupts: contains the reference to the gic wake-up pin interrupt
|
||||||
|
+- interrupt-controller; Enable interrupt controller for wake-up pins.
|
||||||
|
+- #interrupt-cells = <3>
|
||||||
|
+- st,wakeup-pins: contains a list of GPIO spec describing each wake-up pin.
|
||||||
|
+
|
||||||
|
+Optional Properties:
|
||||||
|
+- pwr-supply: main soc power supply
|
||||||
|
+
|
||||||
|
+Interrupt consumers have to specify 3 cells:
|
||||||
|
+ - cell 1: wake-up pin id from 0 to 5
|
||||||
|
+ - cell 2: IRQ_TYPE_EDGE_FALLING or IRQ_TYPE_EDGE_RISING
|
||||||
|
+ - cell 3: Pull config: 0 = No Pull, 1=Pull Up, 2=Pull Down
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+Example:
|
||||||
|
+
|
||||||
|
+ pwr: pwr@50001000 {
|
||||||
|
+ compatible = "st,stm32mp1-pwr", "simple-mfd";
|
||||||
|
+ reg = <0x50001000 0x400>;
|
||||||
|
+ interrupts = <GIC_SPI 149 IRQ_TYPE_NONE>;
|
||||||
|
+ interrupt-controller;
|
||||||
|
+ #interrupt-cells = <3>;
|
||||||
|
+
|
||||||
|
+ st,wakeup-pins = <&gpioa 0 0>, <&gpioa 2 0>,
|
||||||
|
+ <&gpioc 13 0>, <&gpioi 8 0>,
|
||||||
|
+ <&gpioi 11 0>, <&gpioc 1 0>;
|
||||||
|
+
|
||||||
|
+ pwr-supply = <&vdd>;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+Example of interrupt user:
|
||||||
|
+gpio_keys {
|
||||||
|
+ compatible = "gpio-keys";
|
||||||
|
+ #address-cells = <1>;
|
||||||
|
+ #size-cells = <0>;
|
||||||
|
+
|
||||||
|
+ button@4 {
|
||||||
|
+ label = "WakeUp4";
|
||||||
|
+ linux,code = <BTN_4>;
|
||||||
|
+ interrupt-parent = <&pwr>;
|
||||||
|
+ interrupts = <3 IRQ_TYPE_EDGE_FALLING 1>;
|
||||||
|
+ wakeup-source;
|
||||||
|
+ };
|
||||||
|
+};
|
||||||
|
+
|
||||||
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
|
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
|
||||||
index b8847ae04..16449cfc8 100644
|
index d2f345245..181730a69 100644
|
||||||
--- a/drivers/mfd/Kconfig
|
--- a/drivers/mfd/Kconfig
|
||||||
+++ b/drivers/mfd/Kconfig
|
+++ b/drivers/mfd/Kconfig
|
||||||
@@ -2053,6 +2053,16 @@ config MFD_STPMIC1
|
@@ -2042,6 +2042,16 @@ config MFD_STPMIC1
|
||||||
To compile this driver as a module, choose M here: the
|
To compile this driver as a module, choose M here: the
|
||||||
module will be called stpmic1.
|
module will be called stpmic1.
|
||||||
|
|
||||||
|
|
@ -36,7 +117,7 @@ index b8847ae04..16449cfc8 100644
|
||||||
tristate "Support for STMicroelectronics Multi-Function eXpander (STMFX)"
|
tristate "Support for STMicroelectronics Multi-Function eXpander (STMFX)"
|
||||||
depends on I2C
|
depends on I2C
|
||||||
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
|
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
|
||||||
index 1780019d2..90ffa501a 100644
|
index 2ba6646e8..68201ea8e 100644
|
||||||
--- a/drivers/mfd/Makefile
|
--- a/drivers/mfd/Makefile
|
||||||
+++ b/drivers/mfd/Makefile
|
+++ b/drivers/mfd/Makefile
|
||||||
@@ -255,6 +255,7 @@ obj-$(CONFIG_MFD_SUN4I_GPADC) += sun4i-gpadc.o
|
@@ -255,6 +255,7 @@ obj-$(CONFIG_MFD_SUN4I_GPADC) += sun4i-gpadc.o
|
||||||
|
|
@ -49,10 +130,10 @@ index 1780019d2..90ffa501a 100644
|
||||||
obj-$(CONFIG_RAVE_SP_CORE) += rave-sp.o
|
obj-$(CONFIG_RAVE_SP_CORE) += rave-sp.o
|
||||||
diff --git a/drivers/mfd/stm32-pwr.c b/drivers/mfd/stm32-pwr.c
|
diff --git a/drivers/mfd/stm32-pwr.c b/drivers/mfd/stm32-pwr.c
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 000000000..5c130603d
|
index 000000000..c06e2fb6c
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/drivers/mfd/stm32-pwr.c
|
+++ b/drivers/mfd/stm32-pwr.c
|
||||||
@@ -0,0 +1,402 @@
|
@@ -0,0 +1,423 @@
|
||||||
+// SPDX-License-Identifier: GPL-2.0
|
+// SPDX-License-Identifier: GPL-2.0
|
||||||
+/*
|
+/*
|
||||||
+ * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
|
+ * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
|
||||||
|
|
@ -61,10 +142,12 @@ index 000000000..5c130603d
|
||||||
+
|
+
|
||||||
+#include <linux/arm-smccc.h>
|
+#include <linux/arm-smccc.h>
|
||||||
+#include <linux/gpio.h>
|
+#include <linux/gpio.h>
|
||||||
|
+#include <linux/gpio/consumer.h>
|
||||||
+#include <linux/irqchip.h>
|
+#include <linux/irqchip.h>
|
||||||
+#include <linux/irqchip/chained_irq.h>
|
+#include <linux/irqchip/chained_irq.h>
|
||||||
+#include <linux/module.h>
|
+#include <linux/module.h>
|
||||||
+#include <linux/of_address.h>
|
+#include <linux/of_address.h>
|
||||||
|
+#include <linux/of_gpio.h>
|
||||||
+#include <linux/of_irq.h>
|
+#include <linux/of_irq.h>
|
||||||
+#include <linux/platform_device.h>
|
+#include <linux/platform_device.h>
|
||||||
+#include <asm/exception.h>
|
+#include <asm/exception.h>
|
||||||
|
|
@ -110,7 +193,7 @@ index 000000000..5c130603d
|
||||||
+ u32 masked; /* IRQ is masked */
|
+ u32 masked; /* IRQ is masked */
|
||||||
+ u32 wake; /* IRQ is wake on */
|
+ u32 wake; /* IRQ is wake on */
|
||||||
+ u32 pending; /* IRQ has been received while wake on*/
|
+ u32 pending; /* IRQ has been received while wake on*/
|
||||||
+ struct gpio_desc *gpio[NB_WAKEUPPINS];
|
+ int gpio[NB_WAKEUPPINS];
|
||||||
+};
|
+};
|
||||||
+
|
+
|
||||||
+static void stm32_pwr_irq_ack(struct irq_data *d)
|
+static void stm32_pwr_irq_ack(struct irq_data *d)
|
||||||
|
|
@ -121,11 +204,13 @@ index 000000000..5c130603d
|
||||||
+ SMC(STM32_SVC_PWR, STM32_SET_BITS, WKUPCR, BIT(d->hwirq));
|
+ SMC(STM32_SVC_PWR, STM32_SET_BITS, WKUPCR, BIT(d->hwirq));
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static void stm32_pwr_irq_set_enable(struct irq_data *d)
|
+static void stm32_pwr_irq_set_state(struct irq_data *d)
|
||||||
+{
|
+{
|
||||||
+ struct stm32_pwr_data *priv = d->domain->host_data;
|
+ struct stm32_pwr_data *priv = d->domain->host_data;
|
||||||
+
|
+
|
||||||
+ dev_dbg(priv->dev, "irq:%lu\n", d->hwirq);
|
+ dev_dbg(priv->dev, "irq:%lu\n", d->hwirq);
|
||||||
|
+
|
||||||
|
+ /* enable is not masker or wake enabled */
|
||||||
+ if (!(priv->masked & BIT(d->hwirq)) || (priv->wake & BIT(d->hwirq)))
|
+ if (!(priv->masked & BIT(d->hwirq)) || (priv->wake & BIT(d->hwirq)))
|
||||||
+ SMC(STM32_SVC_PWR, STM32_SET_BITS, MPUWKUPENR, BIT(d->hwirq));
|
+ SMC(STM32_SVC_PWR, STM32_SET_BITS, MPUWKUPENR, BIT(d->hwirq));
|
||||||
+ else
|
+ else
|
||||||
|
|
@ -138,7 +223,7 @@ index 000000000..5c130603d
|
||||||
+
|
+
|
||||||
+ dev_dbg(priv->dev, "irq:%lu\n", d->hwirq);
|
+ dev_dbg(priv->dev, "irq:%lu\n", d->hwirq);
|
||||||
+ priv->masked |= BIT(d->hwirq);
|
+ priv->masked |= BIT(d->hwirq);
|
||||||
+ stm32_pwr_irq_set_enable(d);
|
+ stm32_pwr_irq_set_state(d);
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static void stm32_pwr_irq_unmask(struct irq_data *d)
|
+static void stm32_pwr_irq_unmask(struct irq_data *d)
|
||||||
|
|
@ -147,7 +232,7 @@ index 000000000..5c130603d
|
||||||
+
|
+
|
||||||
+ dev_dbg(priv->dev, "irq:%lu\n", d->hwirq);
|
+ dev_dbg(priv->dev, "irq:%lu\n", d->hwirq);
|
||||||
+ priv->masked &= ~BIT(d->hwirq);
|
+ priv->masked &= ~BIT(d->hwirq);
|
||||||
+ stm32_pwr_irq_set_enable(d);
|
+ stm32_pwr_irq_set_state(d);
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static int stm32_pwr_irq_set_wake(struct irq_data *d, unsigned int on)
|
+static int stm32_pwr_irq_set_wake(struct irq_data *d, unsigned int on)
|
||||||
|
|
@ -162,7 +247,7 @@ index 000000000..5c130603d
|
||||||
+ priv->wake &= ~BIT(d->hwirq);
|
+ priv->wake &= ~BIT(d->hwirq);
|
||||||
+ priv->pending &= ~BIT(d->hwirq);
|
+ priv->pending &= ~BIT(d->hwirq);
|
||||||
+ }
|
+ }
|
||||||
+ stm32_pwr_irq_set_enable(d);
|
+ stm32_pwr_irq_set_state(d);
|
||||||
+
|
+
|
||||||
+ if (parent->chip && parent->chip->irq_set_wake)
|
+ if (parent->chip && parent->chip->irq_set_wake)
|
||||||
+ return parent->chip->irq_set_wake(parent, on);
|
+ return parent->chip->irq_set_wake(parent, on);
|
||||||
|
|
@ -225,17 +310,34 @@ index 000000000..5c130603d
|
||||||
+static int stm32_pwr_irq_request_resources(struct irq_data *d)
|
+static int stm32_pwr_irq_request_resources(struct irq_data *d)
|
||||||
+{
|
+{
|
||||||
+ struct stm32_pwr_data *priv = d->domain->host_data;
|
+ struct stm32_pwr_data *priv = d->domain->host_data;
|
||||||
+ struct gpio_desc *gpio;
|
+ struct device_node *dn = priv->dev->of_node;
|
||||||
|
+ int gpio;
|
||||||
+ int ret;
|
+ int ret;
|
||||||
+
|
+
|
||||||
+ dev_dbg(priv->dev, "irq:%lu\n", d->hwirq);
|
+ if (!dn) {
|
||||||
+ gpio = gpiod_get_index(priv->dev, "wakeup", d->hwirq, GPIOD_IN);
|
+ dev_err(priv->dev, "No platform data\n");
|
||||||
+ if (IS_ERR(gpio)) {
|
+ return -ENODEV;
|
||||||
+ ret = PTR_ERR(gpio);
|
|
||||||
+ dev_err(priv->dev, "Failed to get wakeup gpio: %d", ret);
|
|
||||||
+ return ret;
|
|
||||||
+ }
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Get GPIO from device tree */
|
||||||
|
+ dev_dbg(priv->dev, "irq:%lu\n", d->hwirq);
|
||||||
|
+ gpio = of_get_named_gpio(dn, "st,wakeup-pins", d->hwirq);
|
||||||
|
+
|
||||||
|
+ if (gpio < 0) {
|
||||||
|
+ dev_err(priv->dev, "Failed to get wakeup gpio: %d", gpio);
|
||||||
|
+ return gpio;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* GPIO request and configuration */
|
||||||
|
+ ret = devm_gpio_request_one(priv->dev, gpio, GPIOF_DIR_IN,
|
||||||
|
+ "wake-up pin");
|
||||||
|
+ if (ret) {
|
||||||
|
+ dev_err(priv->dev, "Failed to request wake-up pin\n");
|
||||||
|
+ return -ENODEV;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
+ priv->gpio[d->hwirq] = gpio;
|
+ priv->gpio[d->hwirq] = gpio;
|
||||||
|
+
|
||||||
+ return 0;
|
+ return 0;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
|
|
@ -244,7 +346,7 @@ index 000000000..5c130603d
|
||||||
+ struct stm32_pwr_data *priv = d->domain->host_data;
|
+ struct stm32_pwr_data *priv = d->domain->host_data;
|
||||||
+
|
+
|
||||||
+ dev_dbg(priv->dev, "irq:%lu\n", d->hwirq);
|
+ dev_dbg(priv->dev, "irq:%lu\n", d->hwirq);
|
||||||
+ gpiod_put(priv->gpio[d->hwirq]);
|
+ devm_gpio_free(priv->dev, priv->gpio[d->hwirq]);
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static struct irq_chip stm32_pwr_irq_chip = {
|
+static struct irq_chip stm32_pwr_irq_chip = {
|
||||||
|
|
@ -456,7 +558,7 @@ index 000000000..5c130603d
|
||||||
+arch_initcall(stm32_pwr_init);
|
+arch_initcall(stm32_pwr_init);
|
||||||
+module_exit(stm32_pwr_exit);
|
+module_exit(stm32_pwr_exit);
|
||||||
diff --git a/drivers/mfd/stmfx.c b/drivers/mfd/stmfx.c
|
diff --git a/drivers/mfd/stmfx.c b/drivers/mfd/stmfx.c
|
||||||
index 988e2ba6d..39b2fc952 100644
|
index e095a3930..b411d2958 100644
|
||||||
--- a/drivers/mfd/stmfx.c
|
--- a/drivers/mfd/stmfx.c
|
||||||
+++ b/drivers/mfd/stmfx.c
|
+++ b/drivers/mfd/stmfx.c
|
||||||
@@ -81,13 +81,11 @@ static struct mfd_cell stmfx_cells[] = {
|
@@ -81,13 +81,11 @@ static struct mfd_cell stmfx_cells[] = {
|
||||||
|
|
@ -498,7 +600,7 @@ index eb3da558c..40eef5d18 100644
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c
|
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c
|
||||||
index 3b2b93c5b..507572b09 100644
|
index 7b1d27072..e2c98c66b 100644
|
||||||
--- a/drivers/mfd/wm8994-core.c
|
--- a/drivers/mfd/wm8994-core.c
|
||||||
+++ b/drivers/mfd/wm8994-core.c
|
+++ b/drivers/mfd/wm8994-core.c
|
||||||
@@ -185,6 +185,12 @@ static int wm8994_resume(struct device *dev)
|
@@ -185,6 +185,12 @@ static int wm8994_resume(struct device *dev)
|
||||||
|
|
@ -527,5 +629,5 @@ index f8db83aed..f48f04dc4 100644
|
||||||
#define TIM_CR1_CEN BIT(0) /* Counter Enable */
|
#define TIM_CR1_CEN BIT(0) /* Counter Enable */
|
||||||
#define TIM_CR1_DIR BIT(4) /* Counter Direction */
|
#define TIM_CR1_DIR BIT(4) /* Counter Direction */
|
||||||
--
|
--
|
||||||
2.17.1
|
2.25.1
|
||||||
|
|
||||||
|
|
@ -0,0 +1,114 @@
|
||||||
|
From 4ad9ff21f9950e378e159d614a4f3edb5cd187b6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Christophe Priouzeau <christophe.priouzeau@foss.st.com>
|
||||||
|
Date: Tue, 31 May 2022 12:00:10 +0200
|
||||||
|
Subject: [PATCH 12/22] ARM-5.15.24-stm32mp1-r1-MMC
|
||||||
|
|
||||||
|
Signed-off-by: Christophe Priouzeau <christophe.priouzeau@foss.st.com>
|
||||||
|
---
|
||||||
|
Documentation/devicetree/bindings/mmc/arm,pl18x.yaml | 6 ++++++
|
||||||
|
drivers/mmc/host/mmci.c | 12 ++++++++++--
|
||||||
|
drivers/mmc/host/mmci.h | 1 +
|
||||||
|
drivers/mmc/host/mmci_stm32_sdmmc.c | 5 +++--
|
||||||
|
4 files changed, 20 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Documentation/devicetree/bindings/mmc/arm,pl18x.yaml b/Documentation/devicetree/bindings/mmc/arm,pl18x.yaml
|
||||||
|
index 47595cb48..eed54bee7 100644
|
||||||
|
--- a/Documentation/devicetree/bindings/mmc/arm,pl18x.yaml
|
||||||
|
+++ b/Documentation/devicetree/bindings/mmc/arm,pl18x.yaml
|
||||||
|
@@ -53,6 +53,12 @@ properties:
|
||||||
|
items:
|
||||||
|
- const: arm,pl18x
|
||||||
|
- const: arm,primecell
|
||||||
|
+ - description: Entry for STMicroelectronics variant of PL18x.
|
||||||
|
+ This dedicated compatible is used by bootloaders.
|
||||||
|
+ items:
|
||||||
|
+ - const: st,stm32-sdmmc2
|
||||||
|
+ - const: arm,pl18x
|
||||||
|
+ - const: arm,primecell
|
||||||
|
|
||||||
|
clocks:
|
||||||
|
description: One or two clocks, the "apb_pclk" and the "MCLK"
|
||||||
|
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
|
||||||
|
index 3765e2f4a..c15b9a2cd 100644
|
||||||
|
--- a/drivers/mmc/host/mmci.c
|
||||||
|
+++ b/drivers/mmc/host/mmci.c
|
||||||
|
@@ -274,13 +274,14 @@ static struct variant_data variant_stm32_sdmmc = {
|
||||||
|
.busy_detect = true,
|
||||||
|
.busy_detect_flag = MCI_STM32_BUSYD0,
|
||||||
|
.busy_detect_mask = MCI_STM32_BUSYD0ENDMASK,
|
||||||
|
+ .disable_keep_power = true,
|
||||||
|
.init = sdmmc_variant_init,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct variant_data variant_stm32_sdmmcv2 = {
|
||||||
|
.fifosize = 16 * 4,
|
||||||
|
.fifohalfsize = 8 * 4,
|
||||||
|
- .f_max = 208000000,
|
||||||
|
+ .f_max = 267000000,
|
||||||
|
.stm32_clkdiv = true,
|
||||||
|
.cmdreg_cpsm_enable = MCI_CPSM_STM32_ENABLE,
|
||||||
|
.cmdreg_lrsp_crc = MCI_CPSM_STM32_LRSP_CRC,
|
||||||
|
@@ -301,6 +302,7 @@ static struct variant_data variant_stm32_sdmmcv2 = {
|
||||||
|
.busy_detect = true,
|
||||||
|
.busy_detect_flag = MCI_STM32_BUSYD0,
|
||||||
|
.busy_detect_mask = MCI_STM32_BUSYD0ENDMASK,
|
||||||
|
+ .disable_keep_power = true,
|
||||||
|
.init = sdmmc_variant_init,
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -2168,7 +2170,8 @@ static int mmci_probe(struct amba_device *dev,
|
||||||
|
host->stop_abort.flags = MMC_RSP_R1B | MMC_CMD_AC;
|
||||||
|
|
||||||
|
/* We support these PM capabilities. */
|
||||||
|
- mmc->pm_caps |= MMC_PM_KEEP_POWER;
|
||||||
|
+ if (!variant->disable_keep_power)
|
||||||
|
+ mmc->pm_caps |= MMC_PM_KEEP_POWER;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We can do SGIO
|
||||||
|
@@ -2431,6 +2434,11 @@ static const struct amba_id mmci_ids[] = {
|
||||||
|
.mask = 0xf0ffffff,
|
||||||
|
.data = &variant_stm32_sdmmcv2,
|
||||||
|
},
|
||||||
|
+ {
|
||||||
|
+ .id = 0x20253180,
|
||||||
|
+ .mask = 0xf0ffffff,
|
||||||
|
+ .data = &variant_stm32_sdmmcv2,
|
||||||
|
+ },
|
||||||
|
/* Qualcomm variants */
|
||||||
|
{
|
||||||
|
.id = 0x00051180,
|
||||||
|
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
|
||||||
|
index e1a9b96a3..2cad1ef97 100644
|
||||||
|
--- a/drivers/mmc/host/mmci.h
|
||||||
|
+++ b/drivers/mmc/host/mmci.h
|
||||||
|
@@ -361,6 +361,7 @@ struct variant_data {
|
||||||
|
u32 opendrain;
|
||||||
|
u8 dma_lli:1;
|
||||||
|
u32 stm32_idmabsize_mask;
|
||||||
|
+ u8 disable_keep_power:1;
|
||||||
|
void (*init)(struct mmci_host *host);
|
||||||
|
};
|
||||||
|
|
||||||
|
diff --git a/drivers/mmc/host/mmci_stm32_sdmmc.c b/drivers/mmc/host/mmci_stm32_sdmmc.c
|
||||||
|
index a75d3dd34..9c13f2c31 100644
|
||||||
|
--- a/drivers/mmc/host/mmci_stm32_sdmmc.c
|
||||||
|
+++ b/drivers/mmc/host/mmci_stm32_sdmmc.c
|
||||||
|
@@ -241,11 +241,12 @@ static void mmci_sdmmc_set_clkreg(struct mmci_host *host, unsigned int desired)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SDMMC_FBCK is selected when an external Delay Block is needed
|
||||||
|
- * with SDR104.
|
||||||
|
+ * with SDR104 or HS200.
|
||||||
|
*/
|
||||||
|
if (host->mmc->ios.timing >= MMC_TIMING_UHS_SDR50) {
|
||||||
|
clk |= MCI_STM32_CLK_BUSSPEED;
|
||||||
|
- if (host->mmc->ios.timing == MMC_TIMING_UHS_SDR104) {
|
||||||
|
+ if (host->mmc->ios.timing == MMC_TIMING_UHS_SDR104 ||
|
||||||
|
+ host->mmc->ios.timing == MMC_TIMING_MMC_HS200) {
|
||||||
|
clk &= ~MCI_STM32_CLK_SEL_MSK;
|
||||||
|
clk |= MCI_STM32_CLK_SELFBCK;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,16 +1,19 @@
|
||||||
From 000853359feed98e3d2f08d2fc1cc94e8e51fa2d Mon Sep 17 00:00:00 2001
|
From 004f2714f71a2ebf3f233b3fae5a3e0e14b5e68e Mon Sep 17 00:00:00 2001
|
||||||
From: Lionel Vitte <lionel.vitte@st.com>
|
From: Christophe Priouzeau <christophe.priouzeau@foss.st.com>
|
||||||
Date: Thu, 14 Oct 2021 16:51:48 +0200
|
Date: Tue, 31 May 2022 12:01:13 +0200
|
||||||
Subject: [PATCH 14/23] ARM 5.10.61-stm32mp1-r2 PERF
|
Subject: [PATCH 14/22] ARM-5.15.24-stm32mp1-r1-PERF
|
||||||
|
|
||||||
|
Signed-off-by: Christophe Priouzeau <christophe.priouzeau@foss.st.com>
|
||||||
---
|
---
|
||||||
Documentation/admin-guide/perf/index.rst | 1 +
|
Documentation/admin-guide/perf/index.rst | 1 +
|
||||||
.../admin-guide/perf/stm32-ddr-pmu.rst | 44 ++
|
.../admin-guide/perf/stm32-ddr-pmu.rst | 44 ++
|
||||||
|
.../bindings/perf/stm32-ddr-pmu.yaml | 44 ++
|
||||||
drivers/perf/Kconfig | 7 +
|
drivers/perf/Kconfig | 7 +
|
||||||
drivers/perf/Makefile | 1 +
|
drivers/perf/Makefile | 1 +
|
||||||
drivers/perf/stm32_ddr_pmu.c | 429 ++++++++++++++++++
|
drivers/perf/stm32_ddr_pmu.c | 439 ++++++++++++++++++
|
||||||
5 files changed, 482 insertions(+)
|
6 files changed, 536 insertions(+)
|
||||||
create mode 100644 Documentation/admin-guide/perf/stm32-ddr-pmu.rst
|
create mode 100644 Documentation/admin-guide/perf/stm32-ddr-pmu.rst
|
||||||
|
create mode 100644 Documentation/devicetree/bindings/perf/stm32-ddr-pmu.yaml
|
||||||
create mode 100644 drivers/perf/stm32_ddr_pmu.c
|
create mode 100644 drivers/perf/stm32_ddr_pmu.c
|
||||||
|
|
||||||
diff --git a/Documentation/admin-guide/perf/index.rst b/Documentation/admin-guide/perf/index.rst
|
diff --git a/Documentation/admin-guide/perf/index.rst b/Documentation/admin-guide/perf/index.rst
|
||||||
|
|
@ -75,8 +78,58 @@ index 000000000..db647fc1a
|
||||||
+
|
+
|
||||||
+ 20.021068551 seconds time elapsed
|
+ 20.021068551 seconds time elapsed
|
||||||
+
|
+
|
||||||
|
diff --git a/Documentation/devicetree/bindings/perf/stm32-ddr-pmu.yaml b/Documentation/devicetree/bindings/perf/stm32-ddr-pmu.yaml
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..085f2886e
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/Documentation/devicetree/bindings/perf/stm32-ddr-pmu.yaml
|
||||||
|
@@ -0,0 +1,44 @@
|
||||||
|
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||||
|
+%YAML 1.2
|
||||||
|
+---
|
||||||
|
+$id: http://devicetree.org/schemas/perf/stm32-ddr-pmu.yaml#
|
||||||
|
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
+
|
||||||
|
+maintainers:
|
||||||
|
+ - Gerald Baeza <gerald.baeza@st.com>
|
||||||
|
+
|
||||||
|
+title: STMicroelectronics STM32 DDR Performance Monitor (DDRPERFM) bindings
|
||||||
|
+
|
||||||
|
+properties:
|
||||||
|
+ compatible:
|
||||||
|
+ const: st,stm32-ddr-pmu
|
||||||
|
+
|
||||||
|
+ reg:
|
||||||
|
+ maxItems: 1
|
||||||
|
+
|
||||||
|
+ clocks:
|
||||||
|
+ maxItems: 1
|
||||||
|
+
|
||||||
|
+ resets:
|
||||||
|
+ maxItems: 1
|
||||||
|
+
|
||||||
|
+required:
|
||||||
|
+ - compatible
|
||||||
|
+ - reg
|
||||||
|
+ - clocks
|
||||||
|
+ - resets
|
||||||
|
+
|
||||||
|
+additionalProperties: false
|
||||||
|
+
|
||||||
|
+examples:
|
||||||
|
+ - |
|
||||||
|
+ #include <dt-bindings/clock/stm32mp1-clks.h>
|
||||||
|
+ #include <dt-bindings/reset/stm32mp1-resets.h>
|
||||||
|
+
|
||||||
|
+ ddrperfm: perf@5a007000 {
|
||||||
|
+ compatible = "st,stm32-ddr-pmu";
|
||||||
|
+ reg = <0x5a007000 0x400>;
|
||||||
|
+ clocks = <&rcc DDRPERFM>;
|
||||||
|
+ resets = <&rcc DDRPERFM_R>;
|
||||||
|
+ };
|
||||||
|
+...
|
||||||
diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
|
diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
|
||||||
index 130327ff0..a62a26fc5 100644
|
index 77522e5ef..fb55e0bbf 100644
|
||||||
--- a/drivers/perf/Kconfig
|
--- a/drivers/perf/Kconfig
|
||||||
+++ b/drivers/perf/Kconfig
|
+++ b/drivers/perf/Kconfig
|
||||||
@@ -106,6 +106,13 @@ config QCOM_L3_PMU
|
@@ -106,6 +106,13 @@ config QCOM_L3_PMU
|
||||||
|
|
@ -85,7 +138,7 @@ index 130327ff0..a62a26fc5 100644
|
||||||
|
|
||||||
+config STM32_DDR_PMU
|
+config STM32_DDR_PMU
|
||||||
+ tristate "STM32 DDR PMU"
|
+ tristate "STM32 DDR PMU"
|
||||||
+ depends on MACH_STM32MP157
|
+ depends on ARCH_STM32
|
||||||
+ default m
|
+ default m
|
||||||
+ help
|
+ help
|
||||||
+ Support for STM32 DDR performance monitor (DDRPERFM).
|
+ Support for STM32 DDR performance monitor (DDRPERFM).
|
||||||
|
|
@ -94,7 +147,7 @@ index 130327ff0..a62a26fc5 100644
|
||||||
tristate "Cavium ThunderX2 SoC PMU UNCORE"
|
tristate "Cavium ThunderX2 SoC PMU UNCORE"
|
||||||
depends on ARCH_THUNDER2 && ARM64 && ACPI && NUMA
|
depends on ARCH_THUNDER2 && ARM64 && ACPI && NUMA
|
||||||
diff --git a/drivers/perf/Makefile b/drivers/perf/Makefile
|
diff --git a/drivers/perf/Makefile b/drivers/perf/Makefile
|
||||||
index 5365fd56f..7f2b7c5f9 100644
|
index 5260b116c..f1d363307 100644
|
||||||
--- a/drivers/perf/Makefile
|
--- a/drivers/perf/Makefile
|
||||||
+++ b/drivers/perf/Makefile
|
+++ b/drivers/perf/Makefile
|
||||||
@@ -10,6 +10,7 @@ obj-$(CONFIG_FSL_IMX8_DDR_PMU) += fsl_imx8_ddr_perf.o
|
@@ -10,6 +10,7 @@ obj-$(CONFIG_FSL_IMX8_DDR_PMU) += fsl_imx8_ddr_perf.o
|
||||||
|
|
@ -107,10 +160,10 @@ index 5365fd56f..7f2b7c5f9 100644
|
||||||
obj-$(CONFIG_ARM_SPE_PMU) += arm_spe_pmu.o
|
obj-$(CONFIG_ARM_SPE_PMU) += arm_spe_pmu.o
|
||||||
diff --git a/drivers/perf/stm32_ddr_pmu.c b/drivers/perf/stm32_ddr_pmu.c
|
diff --git a/drivers/perf/stm32_ddr_pmu.c b/drivers/perf/stm32_ddr_pmu.c
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 000000000..a6a2c5479
|
index 000000000..c0082109a
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/drivers/perf/stm32_ddr_pmu.c
|
+++ b/drivers/perf/stm32_ddr_pmu.c
|
||||||
@@ -0,0 +1,429 @@
|
@@ -0,0 +1,439 @@
|
||||||
+// SPDX-License-Identifier: GPL-2.0
|
+// SPDX-License-Identifier: GPL-2.0
|
||||||
+/*
|
+/*
|
||||||
+ * This file is the STM32 DDR performance monitor (DDRPERFM) driver
|
+ * This file is the STM32 DDR performance monitor (DDRPERFM) driver
|
||||||
|
|
@ -200,7 +253,7 @@ index 000000000..a6a2c5479
|
||||||
+ }
|
+ }
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static void stm32_ddr_pmu_event_read(struct perf_event *event)
|
+static void stm32_ddr_pmu_event_update(struct perf_event *event)
|
||||||
+{
|
+{
|
||||||
+ struct stm32_ddr_pmu *stm32_ddr_pmu = pmu_to_stm32_ddr_pmu(event->pmu);
|
+ struct stm32_ddr_pmu *stm32_ddr_pmu = pmu_to_stm32_ddr_pmu(event->pmu);
|
||||||
+ unsigned long config_base = event->hw.config_base;
|
+ unsigned long config_base = event->hw.config_base;
|
||||||
|
|
@ -233,6 +286,16 @@ index 000000000..a6a2c5479
|
||||||
+ local64_add(val & mask, &event->count);
|
+ local64_add(val & mask, &event->count);
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
|
+static void stm32_ddr_pmu_event_read(struct perf_event *event)
|
||||||
|
+{
|
||||||
|
+ struct stm32_ddr_pmu *stm32_ddr_pmu = pmu_to_stm32_ddr_pmu(event->pmu);
|
||||||
|
+
|
||||||
|
+ hrtimer_start(&stm32_ddr_pmu->hrtimer, stm32_ddr_pmu->poll_period,
|
||||||
|
+ HRTIMER_MODE_REL_PINNED);
|
||||||
|
+
|
||||||
|
+ stm32_ddr_pmu_event_update(event);
|
||||||
|
+}
|
||||||
|
+
|
||||||
+static void stm32_ddr_pmu_event_start(struct perf_event *event, int flags)
|
+static void stm32_ddr_pmu_event_start(struct perf_event *event, int flags)
|
||||||
+{
|
+{
|
||||||
+ struct stm32_ddr_pmu *stm32_ddr_pmu = pmu_to_stm32_ddr_pmu(event->pmu);
|
+ struct stm32_ddr_pmu *stm32_ddr_pmu = pmu_to_stm32_ddr_pmu(event->pmu);
|
||||||
|
|
@ -278,7 +341,7 @@ index 000000000..a6a2c5479
|
||||||
+ hw->state |= PERF_HES_STOPPED;
|
+ hw->state |= PERF_HES_STOPPED;
|
||||||
+
|
+
|
||||||
+ if (flags & PERF_EF_UPDATE) {
|
+ if (flags & PERF_EF_UPDATE) {
|
||||||
+ stm32_ddr_pmu_event_read(event);
|
+ stm32_ddr_pmu_event_update(event);
|
||||||
+ hw->state |= PERF_HES_UPTODATE;
|
+ hw->state |= PERF_HES_UPTODATE;
|
||||||
+ }
|
+ }
|
||||||
+}
|
+}
|
||||||
|
|
@ -373,7 +436,7 @@ index 000000000..a6a2c5479
|
||||||
+
|
+
|
||||||
+ for (i = 0; i < PMU_NR_COUNTERS; i++)
|
+ for (i = 0; i < PMU_NR_COUNTERS; i++)
|
||||||
+ if (stm32_ddr_pmu->events[i])
|
+ if (stm32_ddr_pmu->events[i])
|
||||||
+ stm32_ddr_pmu_event_read(stm32_ddr_pmu->events[i]);
|
+ stm32_ddr_pmu_event_update(stm32_ddr_pmu->events[i]);
|
||||||
+
|
+
|
||||||
+ hrtimer_forward_now(hrtimer, stm32_ddr_pmu->poll_period);
|
+ hrtimer_forward_now(hrtimer, stm32_ddr_pmu->poll_period);
|
||||||
+
|
+
|
||||||
|
|
@ -384,11 +447,10 @@ index 000000000..a6a2c5479
|
||||||
+ struct device_attribute *attr,
|
+ struct device_attribute *attr,
|
||||||
+ char *buf)
|
+ char *buf)
|
||||||
+{
|
+{
|
||||||
+ struct dev_ext_attribute *eattr;
|
+ struct dev_ext_attribute *eattr = container_of(attr, struct dev_ext_attribute, attr);
|
||||||
|
+ unsigned long cnt_id = (unsigned long)eattr->var;
|
||||||
+
|
+
|
||||||
+ eattr = container_of(attr, struct dev_ext_attribute, attr);
|
+ return sprintf(buf, "config=%ld\n", cnt_id);
|
||||||
+
|
|
||||||
+ return sprintf(buf, "config=0x%lx\n", (unsigned long)eattr->var);
|
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+#define STM32_DDR_PMU_ATTR(_name, _func, _config) \
|
+#define STM32_DDR_PMU_ATTR(_name, _func, _config) \
|
||||||
|
|
@ -475,6 +537,7 @@ index 000000000..a6a2c5479
|
||||||
+ .stop = stm32_ddr_pmu_event_stop,
|
+ .stop = stm32_ddr_pmu_event_stop,
|
||||||
+ .add = stm32_ddr_pmu_event_add,
|
+ .add = stm32_ddr_pmu_event_add,
|
||||||
+ .del = stm32_ddr_pmu_event_del,
|
+ .del = stm32_ddr_pmu_event_del,
|
||||||
|
+ .read = stm32_ddr_pmu_event_read,
|
||||||
+ .event_init = stm32_ddr_pmu_event_init,
|
+ .event_init = stm32_ddr_pmu_event_init,
|
||||||
+ .attr_groups = stm32_ddr_pmu_attr_groups,
|
+ .attr_groups = stm32_ddr_pmu_attr_groups,
|
||||||
+ };
|
+ };
|
||||||
|
|
@ -541,5 +604,5 @@ index 000000000..a6a2c5479
|
||||||
+MODULE_AUTHOR("Gerald Baeza <gerald.baeza@st.com>");
|
+MODULE_AUTHOR("Gerald Baeza <gerald.baeza@st.com>");
|
||||||
+MODULE_LICENSE("GPL v2");
|
+MODULE_LICENSE("GPL v2");
|
||||||
--
|
--
|
||||||
2.17.1
|
2.25.1
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,878 @@
|
||||||
|
From 4f71b18aeac456fac466593f3baa12e5e3f698f3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Christophe Priouzeau <christophe.priouzeau@foss.st.com>
|
||||||
|
Date: Tue, 31 May 2022 12:06:36 +0200
|
||||||
|
Subject: [PATCH 17/22] ARM-5.15.24-stm32mp1-r1-RESET-RTC
|
||||||
|
|
||||||
|
Signed-off-by: Christophe Priouzeau <christophe.priouzeau@foss.st.com>
|
||||||
|
---
|
||||||
|
.../devicetree/bindings/rtc/st,stm32-rtc.yaml | 37 ++
|
||||||
|
drivers/rtc/Kconfig | 1 +
|
||||||
|
drivers/rtc/rtc-stm32.c | 365 ++++++++++++++----
|
||||||
|
include/dt-bindings/reset/stm32mp1-resets.h | 24 +-
|
||||||
|
include/dt-bindings/reset/stm32mp13-resets.h | 100 +++++
|
||||||
|
include/dt-bindings/rtc/rtc-stm32.h | 14 +
|
||||||
|
6 files changed, 459 insertions(+), 82 deletions(-)
|
||||||
|
create mode 100644 include/dt-bindings/reset/stm32mp13-resets.h
|
||||||
|
create mode 100644 include/dt-bindings/rtc/rtc-stm32.h
|
||||||
|
|
||||||
|
diff --git a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.yaml b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.yaml
|
||||||
|
index 5456604b1..d94e1d13d 100644
|
||||||
|
--- a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.yaml
|
||||||
|
+++ b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.yaml
|
||||||
|
@@ -52,6 +52,20 @@ properties:
|
||||||
|
override default rtc_ck parent clock phandle of the new parent clock of rtc_ck
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
+ st,lsco:
|
||||||
|
+ $ref: "/schemas/types.yaml#/definitions/uint32"
|
||||||
|
+ description: |
|
||||||
|
+ To select and enable RTC Low Speed Clock Output.
|
||||||
|
+ Refer to <include/dt-bindings/rtc/rtc-stm32.h> for the supported values.
|
||||||
|
+ Pinctrl state named "default" may be defined to reserve pin for RTC output.
|
||||||
|
+
|
||||||
|
+ st,alarm:
|
||||||
|
+ $ref: "/schemas/types.yaml#/definitions/uint32"
|
||||||
|
+ description: |
|
||||||
|
+ To select and enable RTC Alarm A output.
|
||||||
|
+ Refer to <include/dt-bindings/rtc/rtc-stm32.h> for the supported values.
|
||||||
|
+ Pinctrl state named "default" may be defined to reserve pin for RTC output.
|
||||||
|
+
|
||||||
|
allOf:
|
||||||
|
- if:
|
||||||
|
properties:
|
||||||
|
@@ -65,6 +79,12 @@ allOf:
|
||||||
|
minItems: 1
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
+ st,lsco:
|
||||||
|
+ maxItems: 0
|
||||||
|
+
|
||||||
|
+ st,alarm:
|
||||||
|
+ maxItems: 0
|
||||||
|
+
|
||||||
|
clock-names: false
|
||||||
|
|
||||||
|
required:
|
||||||
|
@@ -82,6 +102,12 @@ allOf:
|
||||||
|
minItems: 2
|
||||||
|
maxItems: 2
|
||||||
|
|
||||||
|
+ st,lsco:
|
||||||
|
+ maxItems: 0
|
||||||
|
+
|
||||||
|
+ st,alarm:
|
||||||
|
+ maxItems: 0
|
||||||
|
+
|
||||||
|
required:
|
||||||
|
- clock-names
|
||||||
|
- st,syscfg
|
||||||
|
@@ -101,6 +127,12 @@ allOf:
|
||||||
|
assigned-clocks: false
|
||||||
|
assigned-clock-parents: false
|
||||||
|
|
||||||
|
+ st,lsco:
|
||||||
|
+ maxItems: 1
|
||||||
|
+
|
||||||
|
+ st,alarm:
|
||||||
|
+ maxItems: 1
|
||||||
|
+
|
||||||
|
required:
|
||||||
|
- clock-names
|
||||||
|
|
||||||
|
@@ -129,12 +161,17 @@ examples:
|
||||||
|
|
||||||
|
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||||
|
#include <dt-bindings/clock/stm32mp1-clks.h>
|
||||||
|
+ #include <dt-bindings/rtc/rtc-stm32.h>
|
||||||
|
rtc@5c004000 {
|
||||||
|
compatible = "st,stm32mp1-rtc";
|
||||||
|
reg = <0x5c004000 0x400>;
|
||||||
|
clocks = <&rcc RTCAPB>, <&rcc RTC>;
|
||||||
|
clock-names = "pclk", "rtc_ck";
|
||||||
|
interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
+ st,alarm = <RTC_OUT1>;
|
||||||
|
+ st,lsco = <RTC_OUT2_RMP>;
|
||||||
|
+ pinctrl-0 = <&rtc_out1_pins_a &rtc_out2_rmp_pins_a>;
|
||||||
|
+ pinctrl-names = "default";
|
||||||
|
};
|
||||||
|
|
||||||
|
...
|
||||||
|
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
|
||||||
|
index e1bc52144..57ef1efdf 100644
|
||||||
|
--- a/drivers/rtc/Kconfig
|
||||||
|
+++ b/drivers/rtc/Kconfig
|
||||||
|
@@ -1867,6 +1867,7 @@ config RTC_DRV_R7301
|
||||||
|
config RTC_DRV_STM32
|
||||||
|
tristate "STM32 RTC"
|
||||||
|
select REGMAP_MMIO
|
||||||
|
+ depends on COMMON_CLK
|
||||||
|
depends on ARCH_STM32 || COMPILE_TEST
|
||||||
|
help
|
||||||
|
If you say yes here you get support for the STM32 On-Chip
|
||||||
|
diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c
|
||||||
|
index ac9e228b5..20896b4b4 100644
|
||||||
|
--- a/drivers/rtc/rtc-stm32.c
|
||||||
|
+++ b/drivers/rtc/rtc-stm32.c
|
||||||
|
@@ -5,7 +5,10 @@
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/bcd.h>
|
||||||
|
+#include <linux/bitfield.h>
|
||||||
|
#include <linux/clk.h>
|
||||||
|
+#include <linux/clk-provider.h>
|
||||||
|
+#include <linux/errno.h>
|
||||||
|
#include <linux/iopoll.h>
|
||||||
|
#include <linux/ioport.h>
|
||||||
|
#include <linux/mfd/syscon.h>
|
||||||
|
@@ -15,6 +18,8 @@
|
||||||
|
#include <linux/regmap.h>
|
||||||
|
#include <linux/rtc.h>
|
||||||
|
|
||||||
|
+#include <dt-bindings/rtc/rtc-stm32.h>
|
||||||
|
+
|
||||||
|
#define DRIVER_NAME "stm32_rtc"
|
||||||
|
|
||||||
|
/* STM32_RTC_TR bit fields */
|
||||||
|
@@ -39,6 +44,13 @@
|
||||||
|
#define STM32_RTC_CR_FMT BIT(6)
|
||||||
|
#define STM32_RTC_CR_ALRAE BIT(8)
|
||||||
|
#define STM32_RTC_CR_ALRAIE BIT(12)
|
||||||
|
+#define STM32_RTC_CR_COSEL BIT(19)
|
||||||
|
+#define STM32_RTC_CR_OSEL GENMASK(22, 21)
|
||||||
|
+#define STM32_RTC_CR_OSEL_ALARM_A FIELD_PREP(STM32_RTC_CR_OSEL, 0x01)
|
||||||
|
+#define STM32_RTC_CR_COE BIT(23)
|
||||||
|
+#define STM32_RTC_CR_TAMPOE BIT(26)
|
||||||
|
+#define STM32_RTC_CR_TAMPALRM_TYPE BIT(30)
|
||||||
|
+#define STM32_RTC_CR_OUT2EN BIT(31)
|
||||||
|
|
||||||
|
/* STM32_RTC_ISR/STM32_RTC_ICSR bit fields */
|
||||||
|
#define STM32_RTC_ISR_ALRAWF BIT(0)
|
||||||
|
@@ -75,6 +87,12 @@
|
||||||
|
/* STM32_RTC_SR/_SCR bit fields */
|
||||||
|
#define STM32_RTC_SR_ALRA BIT(0)
|
||||||
|
|
||||||
|
+/* STM32_RTC_CFGR bit fields */
|
||||||
|
+#define STM32_RTC_CFGR_OUT2_RMP BIT(0)
|
||||||
|
+#define STM32_RTC_CFGR_LSCOEN GENMASK(2, 1)
|
||||||
|
+#define STM32_RTC_CFGR_LSCOEN_OUT1 1
|
||||||
|
+#define STM32_RTC_CFGR_LSCOEN_OUT2_RMP 2
|
||||||
|
+
|
||||||
|
/* STM32_RTC_VERR bit fields */
|
||||||
|
#define STM32_RTC_VERR_MINREV_SHIFT 0
|
||||||
|
#define STM32_RTC_VERR_MINREV GENMASK(3, 0)
|
||||||
|
@@ -89,6 +107,9 @@
|
||||||
|
/* Max STM32 RTC register offset is 0x3FC */
|
||||||
|
#define UNDEF_REG 0xFFFF
|
||||||
|
|
||||||
|
+/* STM32 RTC driver time helpers */
|
||||||
|
+#define SEC_PER_DAY (24 * 60 * 60)
|
||||||
|
+
|
||||||
|
struct stm32_rtc;
|
||||||
|
|
||||||
|
struct stm32_rtc_registers {
|
||||||
|
@@ -101,6 +122,7 @@ struct stm32_rtc_registers {
|
||||||
|
u16 wpr;
|
||||||
|
u16 sr;
|
||||||
|
u16 scr;
|
||||||
|
+ u16 cfgr;
|
||||||
|
u16 verr;
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -114,7 +136,9 @@ struct stm32_rtc_data {
|
||||||
|
void (*clear_events)(struct stm32_rtc *rtc, unsigned int flags);
|
||||||
|
bool has_pclk;
|
||||||
|
bool need_dbp;
|
||||||
|
- bool has_wakeirq;
|
||||||
|
+ bool has_lsco;
|
||||||
|
+ bool has_alarm_out;
|
||||||
|
+ bool need_accuracy;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct stm32_rtc {
|
||||||
|
@@ -127,9 +151,88 @@ struct stm32_rtc {
|
||||||
|
struct clk *rtc_ck;
|
||||||
|
const struct stm32_rtc_data *data;
|
||||||
|
int irq_alarm;
|
||||||
|
- int wakeirq_alarm;
|
||||||
|
+ int lsco;
|
||||||
|
+ struct clk *clk_lsco;
|
||||||
|
+ int out_alarm;
|
||||||
|
};
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * -------------------------------------------------------------------------
|
||||||
|
+ * | TAMPOE | OSEL[1:0] | COE | OUT2EN | RTC_OUT1 | RTC_OUT2 |
|
||||||
|
+ * | | | | | | or RTC_OUT2_RMP |
|
||||||
|
+ * |-------------------------------------------------------------------------|
|
||||||
|
+ * | 0 | 00 | 0 | 0 or 1 | - | - |
|
||||||
|
+ * |--------|-----------|-----|--------|------------------|------------------|
|
||||||
|
+ * | 0 | 00 | 1 | 0 | CALIB | - |
|
||||||
|
+ * |--------|-----------|-----|--------|------------------|------------------|
|
||||||
|
+ * | 0 or 1 | !=00 | 0 | 0 | TAMPALRM | - |
|
||||||
|
+ * |--------|-----------|-----|--------|------------------|------------------|
|
||||||
|
+ * | 0 | 00 | 1 | 1 | - | CALIB |
|
||||||
|
+ * |--------|-----------|-----|--------|------------------|------------------|
|
||||||
|
+ * | 0 or 1 | !=00 | 0 | 1 | - | TAMPALRM |
|
||||||
|
+ * |--------|-----------|-----|--------|------------------|------------------|
|
||||||
|
+ * | 0 or 1 | !=00 | 1 | 1 | TAMPALRM | CALIB |
|
||||||
|
+ * -------------------------------------------------------------------------
|
||||||
|
+ */
|
||||||
|
+static int stm32_rtc_clk_lsco_check_availability(struct stm32_rtc *rtc)
|
||||||
|
+{
|
||||||
|
+ struct stm32_rtc_registers regs = rtc->data->regs;
|
||||||
|
+ unsigned int cr = readl_relaxed(rtc->base + regs.cr);
|
||||||
|
+ unsigned int cfgr = readl_relaxed(rtc->base + regs.cfgr);
|
||||||
|
+ unsigned int calib = STM32_RTC_CR_COE;
|
||||||
|
+ unsigned int tampalrm = STM32_RTC_CR_TAMPOE | STM32_RTC_CR_OSEL;
|
||||||
|
+
|
||||||
|
+ switch (rtc->lsco) {
|
||||||
|
+ case RTC_OUT1:
|
||||||
|
+ if ((!(cr & STM32_RTC_CR_OUT2EN) &&
|
||||||
|
+ ((cr & calib) || cr & tampalrm)) ||
|
||||||
|
+ ((cr & calib) && (cr & tampalrm)))
|
||||||
|
+ return -EBUSY;
|
||||||
|
+ break;
|
||||||
|
+ case RTC_OUT2_RMP:
|
||||||
|
+ if ((cr & STM32_RTC_CR_OUT2EN) &&
|
||||||
|
+ (cfgr & STM32_RTC_CFGR_OUT2_RMP) &&
|
||||||
|
+ ((cr & calib) || (cr & tampalrm)))
|
||||||
|
+ return -EBUSY;
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (clk_get_rate(rtc->rtc_ck) != 32768)
|
||||||
|
+ return -ERANGE;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int stm32_rtc_clk_lsco_register(struct platform_device *pdev)
|
||||||
|
+{
|
||||||
|
+ struct stm32_rtc *rtc = platform_get_drvdata(pdev);
|
||||||
|
+ struct stm32_rtc_registers regs = rtc->data->regs;
|
||||||
|
+ u8 lscoen;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ ret = stm32_rtc_clk_lsco_check_availability(rtc);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ lscoen = (rtc->lsco == RTC_OUT1) ? STM32_RTC_CFGR_LSCOEN_OUT1 :
|
||||||
|
+ STM32_RTC_CFGR_LSCOEN_OUT2_RMP;
|
||||||
|
+
|
||||||
|
+ rtc->clk_lsco = clk_register_gate(&pdev->dev, "rtc_lsco",
|
||||||
|
+ __clk_get_name(rtc->rtc_ck),
|
||||||
|
+ CLK_IGNORE_UNUSED | CLK_IS_CRITICAL,
|
||||||
|
+ rtc->base + regs.cfgr, lscoen,
|
||||||
|
+ 0, NULL);
|
||||||
|
+ if (IS_ERR(rtc->clk_lsco))
|
||||||
|
+ return PTR_ERR(rtc->clk_lsco);
|
||||||
|
+
|
||||||
|
+ of_clk_add_provider(pdev->dev.of_node,
|
||||||
|
+ of_clk_src_simple_get, rtc->clk_lsco);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void stm32_rtc_wpr_unlock(struct stm32_rtc *rtc)
|
||||||
|
{
|
||||||
|
const struct stm32_rtc_registers *regs = &rtc->data->regs;
|
||||||
|
@@ -145,6 +248,73 @@ static void stm32_rtc_wpr_lock(struct stm32_rtc *rtc)
|
||||||
|
writel_relaxed(RTC_WPR_WRONG_KEY, rtc->base + regs->wpr);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void stm32_rtc_clk_lsco_disable(struct platform_device *pdev)
|
||||||
|
+{
|
||||||
|
+ struct stm32_rtc *rtc = platform_get_drvdata(pdev);
|
||||||
|
+ struct stm32_rtc_registers regs = rtc->data->regs;
|
||||||
|
+ unsigned int cfgr = readl_relaxed(rtc->base + regs.cfgr);
|
||||||
|
+
|
||||||
|
+ writel_relaxed(cfgr &= ~STM32_RTC_CFGR_LSCOEN, rtc->base + regs.cfgr);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int stm32_rtc_out_alarm_config(struct platform_device *pdev)
|
||||||
|
+{
|
||||||
|
+ struct stm32_rtc *rtc = platform_get_drvdata(pdev);
|
||||||
|
+ struct stm32_rtc_registers regs = rtc->data->regs;
|
||||||
|
+ unsigned int cr = readl_relaxed(rtc->base + regs.cr);
|
||||||
|
+ unsigned int cfgr = readl_relaxed(rtc->base + regs.cfgr);
|
||||||
|
+
|
||||||
|
+ cr &= ~STM32_RTC_CR_OSEL;
|
||||||
|
+ cr |= STM32_RTC_CR_OSEL_ALARM_A;
|
||||||
|
+ cr &= ~STM32_RTC_CR_TAMPOE;
|
||||||
|
+ cr &= ~STM32_RTC_CR_COE;
|
||||||
|
+ cr &= ~STM32_RTC_CR_TAMPALRM_TYPE;
|
||||||
|
+
|
||||||
|
+ switch (rtc->out_alarm) {
|
||||||
|
+ case RTC_OUT1:
|
||||||
|
+ cr &= ~STM32_RTC_CR_OUT2EN;
|
||||||
|
+ cfgr &= ~STM32_RTC_CFGR_OUT2_RMP;
|
||||||
|
+ break;
|
||||||
|
+ case RTC_OUT2:
|
||||||
|
+ cr |= STM32_RTC_CR_OUT2EN;
|
||||||
|
+ cfgr &= ~STM32_RTC_CFGR_OUT2_RMP;
|
||||||
|
+ break;
|
||||||
|
+ case RTC_OUT2_RMP:
|
||||||
|
+ cr |= STM32_RTC_CR_OUT2EN;
|
||||||
|
+ cfgr |= STM32_RTC_CFGR_OUT2_RMP;
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ stm32_rtc_wpr_unlock(rtc);
|
||||||
|
+ writel_relaxed(cr, rtc->base + regs.cr);
|
||||||
|
+ writel_relaxed(cfgr, rtc->base + regs.cfgr);
|
||||||
|
+ stm32_rtc_wpr_lock(rtc);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void stm32_rtc_out_alarm_disable(struct platform_device *pdev)
|
||||||
|
+{
|
||||||
|
+ struct stm32_rtc *rtc = platform_get_drvdata(pdev);
|
||||||
|
+ struct stm32_rtc_registers regs = rtc->data->regs;
|
||||||
|
+ unsigned int cr = readl_relaxed(rtc->base + regs.cr);
|
||||||
|
+ unsigned int cfgr = readl_relaxed(rtc->base + regs.cfgr);
|
||||||
|
+
|
||||||
|
+ cr &= ~STM32_RTC_CR_OSEL;
|
||||||
|
+ cr &= ~STM32_RTC_CR_TAMPOE;
|
||||||
|
+ cr &= ~STM32_RTC_CR_COE;
|
||||||
|
+ cr &= ~STM32_RTC_CR_TAMPALRM_TYPE;
|
||||||
|
+ cr &= ~STM32_RTC_CR_OUT2EN;
|
||||||
|
+ cfgr &= ~STM32_RTC_CFGR_OUT2_RMP;
|
||||||
|
+
|
||||||
|
+ stm32_rtc_wpr_unlock(rtc);
|
||||||
|
+ writel_relaxed(cr, rtc->base + regs.cr);
|
||||||
|
+ writel_relaxed(cfgr, rtc->base + regs.cfgr);
|
||||||
|
+ stm32_rtc_wpr_lock(rtc);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)
|
||||||
|
{
|
||||||
|
const struct stm32_rtc_registers *regs = &rtc->data->regs;
|
||||||
|
@@ -160,10 +330,9 @@ static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)
|
||||||
|
* slowest rtc_ck frequency may be 32kHz and highest should be
|
||||||
|
* 1MHz, we poll every 10 us with a timeout of 100ms.
|
||||||
|
*/
|
||||||
|
- return readl_relaxed_poll_timeout_atomic(
|
||||||
|
- rtc->base + regs->isr,
|
||||||
|
- isr, (isr & STM32_RTC_ISR_INITF),
|
||||||
|
- 10, 100000);
|
||||||
|
+ return readl_relaxed_poll_timeout_atomic(rtc->base + regs->isr, isr,
|
||||||
|
+ (isr & STM32_RTC_ISR_INITF),
|
||||||
|
+ 10, 100000);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
@@ -427,40 +596,42 @@ static int stm32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int stm32_rtc_valid_alrm(struct stm32_rtc *rtc, struct rtc_time *tm)
|
||||||
|
+static int stm32_rtc_valid_alrm(struct device *dev, struct rtc_time *tm)
|
||||||
|
{
|
||||||
|
- const struct stm32_rtc_registers *regs = &rtc->data->regs;
|
||||||
|
- int cur_day, cur_mon, cur_year, cur_hour, cur_min, cur_sec;
|
||||||
|
- unsigned int dr = readl_relaxed(rtc->base + regs->dr);
|
||||||
|
- unsigned int tr = readl_relaxed(rtc->base + regs->tr);
|
||||||
|
-
|
||||||
|
- cur_day = (dr & STM32_RTC_DR_DATE) >> STM32_RTC_DR_DATE_SHIFT;
|
||||||
|
- cur_mon = (dr & STM32_RTC_DR_MONTH) >> STM32_RTC_DR_MONTH_SHIFT;
|
||||||
|
- cur_year = (dr & STM32_RTC_DR_YEAR) >> STM32_RTC_DR_YEAR_SHIFT;
|
||||||
|
- cur_sec = (tr & STM32_RTC_TR_SEC) >> STM32_RTC_TR_SEC_SHIFT;
|
||||||
|
- cur_min = (tr & STM32_RTC_TR_MIN) >> STM32_RTC_TR_MIN_SHIFT;
|
||||||
|
- cur_hour = (tr & STM32_RTC_TR_HOUR) >> STM32_RTC_TR_HOUR_SHIFT;
|
||||||
|
+ static struct rtc_time now;
|
||||||
|
+ time64_t max_alarm_time64;
|
||||||
|
+ int max_day_forward;
|
||||||
|
+ int next_month;
|
||||||
|
+ int next_year;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Assuming current date is M-D-Y H:M:S.
|
||||||
|
* RTC alarm can't be set on a specific month and year.
|
||||||
|
* So the valid alarm range is:
|
||||||
|
* M-D-Y H:M:S < alarm <= (M+1)-D-Y H:M:S
|
||||||
|
- * with a specific case for December...
|
||||||
|
*/
|
||||||
|
- if ((((tm->tm_year > cur_year) &&
|
||||||
|
- (tm->tm_mon == 0x1) && (cur_mon == 0x12)) ||
|
||||||
|
- ((tm->tm_year == cur_year) &&
|
||||||
|
- (tm->tm_mon <= cur_mon + 1))) &&
|
||||||
|
- ((tm->tm_mday > cur_day) ||
|
||||||
|
- ((tm->tm_mday == cur_day) &&
|
||||||
|
- ((tm->tm_hour > cur_hour) ||
|
||||||
|
- ((tm->tm_hour == cur_hour) && (tm->tm_min > cur_min)) ||
|
||||||
|
- ((tm->tm_hour == cur_hour) && (tm->tm_min == cur_min) &&
|
||||||
|
- (tm->tm_sec >= cur_sec))))))
|
||||||
|
- return 0;
|
||||||
|
+ stm32_rtc_read_time(dev, &now);
|
||||||
|
|
||||||
|
- return -EINVAL;
|
||||||
|
+ /*
|
||||||
|
+ * Find the next month and the year of the next month.
|
||||||
|
+ * Note: tm_mon and next_month are from 0 to 11
|
||||||
|
+ */
|
||||||
|
+ next_month = now.tm_mon + 1;
|
||||||
|
+ if (next_month == 12) {
|
||||||
|
+ next_month = 0;
|
||||||
|
+ next_year = now.tm_year + 1;
|
||||||
|
+ } else {
|
||||||
|
+ next_year = now.tm_year;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Find the maximum limit of alarm in days. */
|
||||||
|
+ max_day_forward = rtc_month_days(now.tm_mon, now.tm_year)
|
||||||
|
+ - now.tm_mday
|
||||||
|
+ + min(rtc_month_days(next_month, next_year), now.tm_mday);
|
||||||
|
+
|
||||||
|
+ /* Convert to timestamp and compare the alarm time and its upper limit */
|
||||||
|
+ max_alarm_time64 = rtc_tm_to_time64(&now) + max_day_forward * SEC_PER_DAY;
|
||||||
|
+ return rtc_tm_to_time64(tm) <= max_alarm_time64 ? 0 : -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
|
||||||
|
@@ -471,17 +642,17 @@ static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
|
||||||
|
unsigned int cr, isr, alrmar;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
- tm2bcd(tm);
|
||||||
|
-
|
||||||
|
/*
|
||||||
|
* RTC alarm can't be set on a specific date, unless this date is
|
||||||
|
* up to the same day of month next month.
|
||||||
|
*/
|
||||||
|
- if (stm32_rtc_valid_alrm(rtc, tm) < 0) {
|
||||||
|
+ if (stm32_rtc_valid_alrm(dev, tm) < 0) {
|
||||||
|
dev_err(dev, "Alarm can be set only on upcoming month.\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ tm2bcd(tm);
|
||||||
|
+
|
||||||
|
alrmar = 0;
|
||||||
|
/* tm_year and tm_mon are not used because not supported by RTC */
|
||||||
|
alrmar |= (tm->tm_mday << STM32_RTC_ALRMXR_DATE_SHIFT) &
|
||||||
|
@@ -547,7 +718,9 @@ static void stm32_rtc_clear_events(struct stm32_rtc *rtc,
|
||||||
|
static const struct stm32_rtc_data stm32_rtc_data = {
|
||||||
|
.has_pclk = false,
|
||||||
|
.need_dbp = true,
|
||||||
|
- .has_wakeirq = false,
|
||||||
|
+ .has_lsco = false,
|
||||||
|
+ .has_alarm_out = false,
|
||||||
|
+ .need_accuracy = false,
|
||||||
|
.regs = {
|
||||||
|
.tr = 0x00,
|
||||||
|
.dr = 0x04,
|
||||||
|
@@ -558,6 +731,7 @@ static const struct stm32_rtc_data stm32_rtc_data = {
|
||||||
|
.wpr = 0x24,
|
||||||
|
.sr = 0x0C, /* set to ISR offset to ease alarm management */
|
||||||
|
.scr = UNDEF_REG,
|
||||||
|
+ .cfgr = UNDEF_REG,
|
||||||
|
.verr = UNDEF_REG,
|
||||||
|
},
|
||||||
|
.events = {
|
||||||
|
@@ -569,7 +743,9 @@ static const struct stm32_rtc_data stm32_rtc_data = {
|
||||||
|
static const struct stm32_rtc_data stm32h7_rtc_data = {
|
||||||
|
.has_pclk = true,
|
||||||
|
.need_dbp = true,
|
||||||
|
- .has_wakeirq = false,
|
||||||
|
+ .has_lsco = false,
|
||||||
|
+ .has_alarm_out = false,
|
||||||
|
+ .need_accuracy = false,
|
||||||
|
.regs = {
|
||||||
|
.tr = 0x00,
|
||||||
|
.dr = 0x04,
|
||||||
|
@@ -580,6 +756,7 @@ static const struct stm32_rtc_data stm32h7_rtc_data = {
|
||||||
|
.wpr = 0x24,
|
||||||
|
.sr = 0x0C, /* set to ISR offset to ease alarm management */
|
||||||
|
.scr = UNDEF_REG,
|
||||||
|
+ .cfgr = UNDEF_REG,
|
||||||
|
.verr = UNDEF_REG,
|
||||||
|
},
|
||||||
|
.events = {
|
||||||
|
@@ -600,7 +777,9 @@ static void stm32mp1_rtc_clear_events(struct stm32_rtc *rtc,
|
||||||
|
static const struct stm32_rtc_data stm32mp1_data = {
|
||||||
|
.has_pclk = true,
|
||||||
|
.need_dbp = false,
|
||||||
|
- .has_wakeirq = true,
|
||||||
|
+ .has_lsco = true,
|
||||||
|
+ .has_alarm_out = true,
|
||||||
|
+ .need_accuracy = true,
|
||||||
|
.regs = {
|
||||||
|
.tr = 0x00,
|
||||||
|
.dr = 0x04,
|
||||||
|
@@ -611,6 +790,7 @@ static const struct stm32_rtc_data stm32mp1_data = {
|
||||||
|
.wpr = 0x24,
|
||||||
|
.sr = 0x50,
|
||||||
|
.scr = 0x5C,
|
||||||
|
+ .cfgr = 0x60,
|
||||||
|
.verr = 0x3F4,
|
||||||
|
},
|
||||||
|
.events = {
|
||||||
|
@@ -633,7 +813,7 @@ static int stm32_rtc_init(struct platform_device *pdev,
|
||||||
|
const struct stm32_rtc_registers *regs = &rtc->data->regs;
|
||||||
|
unsigned int prer, pred_a, pred_s, pred_a_max, pred_s_max, cr;
|
||||||
|
unsigned int rate;
|
||||||
|
- int ret = 0;
|
||||||
|
+ int ret;
|
||||||
|
|
||||||
|
rate = clk_get_rate(rtc->rtc_ck);
|
||||||
|
|
||||||
|
@@ -641,18 +821,32 @@ static int stm32_rtc_init(struct platform_device *pdev,
|
||||||
|
pred_a_max = STM32_RTC_PRER_PRED_A >> STM32_RTC_PRER_PRED_A_SHIFT;
|
||||||
|
pred_s_max = STM32_RTC_PRER_PRED_S >> STM32_RTC_PRER_PRED_S_SHIFT;
|
||||||
|
|
||||||
|
- for (pred_a = pred_a_max; pred_a + 1 > 0; pred_a--) {
|
||||||
|
- pred_s = (rate / (pred_a + 1)) - 1;
|
||||||
|
+ if (rate > (pred_a_max + 1) * (pred_s_max + 1)) {
|
||||||
|
+ dev_err(&pdev->dev, "rtc_ck rate is too high: %dHz\n", rate);
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (rtc->data->need_accuracy) {
|
||||||
|
+ for (pred_a = 0; pred_a <= pred_a_max; pred_a++) {
|
||||||
|
+ pred_s = (rate / (pred_a + 1)) - 1;
|
||||||
|
+
|
||||||
|
+ if (pred_s <= pred_s_max && ((pred_s + 1) * (pred_a + 1)) == rate)
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ for (pred_a = pred_a_max; pred_a + 1 > 0; pred_a--) {
|
||||||
|
+ pred_s = (rate / (pred_a + 1)) - 1;
|
||||||
|
|
||||||
|
- if (((pred_s + 1) * (pred_a + 1)) == rate)
|
||||||
|
- break;
|
||||||
|
+ if (((pred_s + 1) * (pred_a + 1)) == rate)
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Can't find a 1Hz, so give priority to RTC power consumption
|
||||||
|
* by choosing the higher possible value for prediv_a
|
||||||
|
*/
|
||||||
|
- if ((pred_s > pred_s_max) || (pred_a > pred_a_max)) {
|
||||||
|
+ if (pred_s > pred_s_max || pred_a > pred_a_max) {
|
||||||
|
pred_a = pred_a_max;
|
||||||
|
pred_s = (rate / (pred_a + 1)) - 1;
|
||||||
|
|
||||||
|
@@ -661,6 +855,20 @@ static int stm32_rtc_init(struct platform_device *pdev,
|
||||||
|
"fast" : "slow");
|
||||||
|
}
|
||||||
|
|
||||||
|
+ cr = readl_relaxed(rtc->base + regs->cr);
|
||||||
|
+
|
||||||
|
+ prer = readl_relaxed(rtc->base + regs->prer);
|
||||||
|
+ prer &= STM32_RTC_PRER_PRED_S | STM32_RTC_PRER_PRED_A;
|
||||||
|
+
|
||||||
|
+ pred_s = (pred_s << STM32_RTC_PRER_PRED_S_SHIFT) &
|
||||||
|
+ STM32_RTC_PRER_PRED_S;
|
||||||
|
+ pred_a = (pred_a << STM32_RTC_PRER_PRED_A_SHIFT) &
|
||||||
|
+ STM32_RTC_PRER_PRED_A;
|
||||||
|
+
|
||||||
|
+ /* quit if there is nothing to initialize */
|
||||||
|
+ if ((cr & STM32_RTC_CR_FMT) == 0 && prer == (pred_s | pred_a))
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
stm32_rtc_wpr_unlock(rtc);
|
||||||
|
|
||||||
|
ret = stm32_rtc_enter_init_mode(rtc);
|
||||||
|
@@ -670,13 +878,10 @@ static int stm32_rtc_init(struct platform_device *pdev,
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
- prer = (pred_s << STM32_RTC_PRER_PRED_S_SHIFT) & STM32_RTC_PRER_PRED_S;
|
||||||
|
- writel_relaxed(prer, rtc->base + regs->prer);
|
||||||
|
- prer |= (pred_a << STM32_RTC_PRER_PRED_A_SHIFT) & STM32_RTC_PRER_PRED_A;
|
||||||
|
- writel_relaxed(prer, rtc->base + regs->prer);
|
||||||
|
+ writel_relaxed(pred_s, rtc->base + regs->prer);
|
||||||
|
+ writel_relaxed(pred_a | pred_s, rtc->base + regs->prer);
|
||||||
|
|
||||||
|
/* Force 24h time format */
|
||||||
|
- cr = readl_relaxed(rtc->base + regs->cr);
|
||||||
|
cr &= ~STM32_RTC_CR_FMT;
|
||||||
|
writel_relaxed(cr, rtc->base + regs->cr);
|
||||||
|
|
||||||
|
@@ -736,13 +941,15 @@ static int stm32_rtc_probe(struct platform_device *pdev)
|
||||||
|
} else {
|
||||||
|
rtc->pclk = devm_clk_get(&pdev->dev, "pclk");
|
||||||
|
if (IS_ERR(rtc->pclk)) {
|
||||||
|
- dev_err(&pdev->dev, "no pclk clock");
|
||||||
|
+ if (PTR_ERR(rtc->pclk) != -EPROBE_DEFER)
|
||||||
|
+ dev_err(&pdev->dev, "no pclk clock");
|
||||||
|
return PTR_ERR(rtc->pclk);
|
||||||
|
}
|
||||||
|
rtc->rtc_ck = devm_clk_get(&pdev->dev, "rtc_ck");
|
||||||
|
}
|
||||||
|
if (IS_ERR(rtc->rtc_ck)) {
|
||||||
|
- dev_err(&pdev->dev, "no rtc_ck clock");
|
||||||
|
+ if (PTR_ERR(rtc->rtc_ck) != -EPROBE_DEFER)
|
||||||
|
+ dev_err(&pdev->dev, "no rtc_ck clock");
|
||||||
|
return PTR_ERR(rtc->rtc_ck);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -779,19 +986,12 @@ static int stm32_rtc_probe(struct platform_device *pdev)
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = device_init_wakeup(&pdev->dev, true);
|
||||||
|
- if (rtc->data->has_wakeirq) {
|
||||||
|
- rtc->wakeirq_alarm = platform_get_irq(pdev, 1);
|
||||||
|
- if (rtc->wakeirq_alarm > 0) {
|
||||||
|
- ret = dev_pm_set_dedicated_wake_irq(&pdev->dev,
|
||||||
|
- rtc->wakeirq_alarm);
|
||||||
|
- } else {
|
||||||
|
- ret = rtc->wakeirq_alarm;
|
||||||
|
- if (rtc->wakeirq_alarm == -EPROBE_DEFER)
|
||||||
|
- goto err;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
if (ret)
|
||||||
|
- dev_warn(&pdev->dev, "alarm can't wake up the system: %d", ret);
|
||||||
|
+ goto err;
|
||||||
|
+
|
||||||
|
+ ret = dev_pm_set_wake_irq(&pdev->dev, rtc->irq_alarm);
|
||||||
|
+ if (ret)
|
||||||
|
+ goto err;
|
||||||
|
|
||||||
|
platform_set_drvdata(pdev, rtc);
|
||||||
|
|
||||||
|
@@ -814,6 +1014,33 @@ static int stm32_rtc_probe(struct platform_device *pdev)
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (rtc->data->has_alarm_out) {
|
||||||
|
+ ret = of_property_read_s32(pdev->dev.of_node, "st,alarm", &rtc->out_alarm);
|
||||||
|
+ if (!ret) {
|
||||||
|
+ ret = stm32_rtc_out_alarm_config(pdev);
|
||||||
|
+ } else {
|
||||||
|
+ stm32_rtc_out_alarm_disable(pdev);
|
||||||
|
+ rtc->out_alarm = ret;
|
||||||
|
+ dev_dbg(&pdev->dev, "No alarm out: %d\n", ret);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (rtc->data->has_lsco) {
|
||||||
|
+ ret = of_property_read_s32(pdev->dev.of_node,
|
||||||
|
+ "st,lsco", &rtc->lsco);
|
||||||
|
+ if (!ret) {
|
||||||
|
+ ret = stm32_rtc_clk_lsco_register(pdev);
|
||||||
|
+ if (ret)
|
||||||
|
+ dev_warn(&pdev->dev,
|
||||||
|
+ "LSCO clock registration failed: %d\n",
|
||||||
|
+ ret);
|
||||||
|
+ } else {
|
||||||
|
+ stm32_rtc_clk_lsco_disable(pdev);
|
||||||
|
+ rtc->lsco = ret;
|
||||||
|
+ dev_dbg(&pdev->dev, "No LSCO clock: %d\n", ret);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* If INITS flag is reset (calendar year field set to 0x00), calendar
|
||||||
|
* must be initialized
|
||||||
|
@@ -852,6 +1079,9 @@ static int stm32_rtc_remove(struct platform_device *pdev)
|
||||||
|
const struct stm32_rtc_registers *regs = &rtc->data->regs;
|
||||||
|
unsigned int cr;
|
||||||
|
|
||||||
|
+ if (!IS_ERR_OR_NULL(rtc->clk_lsco))
|
||||||
|
+ clk_unregister_gate(rtc->clk_lsco);
|
||||||
|
+
|
||||||
|
/* Disable interrupts */
|
||||||
|
stm32_rtc_wpr_unlock(rtc);
|
||||||
|
cr = readl_relaxed(rtc->base + regs->cr);
|
||||||
|
@@ -881,9 +1111,6 @@ static int stm32_rtc_suspend(struct device *dev)
|
||||||
|
if (rtc->data->has_pclk)
|
||||||
|
clk_disable_unprepare(rtc->pclk);
|
||||||
|
|
||||||
|
- if (device_may_wakeup(dev))
|
||||||
|
- return enable_irq_wake(rtc->irq_alarm);
|
||||||
|
-
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -905,15 +1132,13 @@ static int stm32_rtc_resume(struct device *dev)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (device_may_wakeup(dev))
|
||||||
|
- return disable_irq_wake(rtc->irq_alarm);
|
||||||
|
-
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
-static SIMPLE_DEV_PM_OPS(stm32_rtc_pm_ops,
|
||||||
|
- stm32_rtc_suspend, stm32_rtc_resume);
|
||||||
|
+static const struct dev_pm_ops stm32_rtc_pm_ops = {
|
||||||
|
+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(stm32_rtc_suspend, stm32_rtc_resume)
|
||||||
|
+};
|
||||||
|
|
||||||
|
static struct platform_driver stm32_rtc_driver = {
|
||||||
|
.probe = stm32_rtc_probe,
|
||||||
|
diff --git a/include/dt-bindings/reset/stm32mp1-resets.h b/include/dt-bindings/reset/stm32mp1-resets.h
|
||||||
|
index f3a0ed317..bdbf9e253 100644
|
||||||
|
--- a/include/dt-bindings/reset/stm32mp1-resets.h
|
||||||
|
+++ b/include/dt-bindings/reset/stm32mp1-resets.h
|
||||||
|
@@ -107,17 +107,17 @@
|
||||||
|
#define GPIOK_R 19786
|
||||||
|
|
||||||
|
/* SCMI reset domain identifiers */
|
||||||
|
-#define RST_SCMI0_SPI6 0
|
||||||
|
-#define RST_SCMI0_I2C4 1
|
||||||
|
-#define RST_SCMI0_I2C6 2
|
||||||
|
-#define RST_SCMI0_USART1 3
|
||||||
|
-#define RST_SCMI0_STGEN 4
|
||||||
|
-#define RST_SCMI0_GPIOZ 5
|
||||||
|
-#define RST_SCMI0_CRYP1 6
|
||||||
|
-#define RST_SCMI0_HASH1 7
|
||||||
|
-#define RST_SCMI0_RNG1 8
|
||||||
|
-#define RST_SCMI0_MDMA 9
|
||||||
|
-#define RST_SCMI0_MCU 10
|
||||||
|
-#define RST_SCMI0_MCU_HOLD_BOOT 11
|
||||||
|
+#define RST_SCMI_SPI6 0
|
||||||
|
+#define RST_SCMI_I2C4 1
|
||||||
|
+#define RST_SCMI_I2C6 2
|
||||||
|
+#define RST_SCMI_USART1 3
|
||||||
|
+#define RST_SCMI_STGEN 4
|
||||||
|
+#define RST_SCMI_GPIOZ 5
|
||||||
|
+#define RST_SCMI_CRYP1 6
|
||||||
|
+#define RST_SCMI_HASH1 7
|
||||||
|
+#define RST_SCMI_RNG1 8
|
||||||
|
+#define RST_SCMI_MDMA 9
|
||||||
|
+#define RST_SCMI_MCU 10
|
||||||
|
+#define RST_SCMI_MCU_HOLD_BOOT 11
|
||||||
|
|
||||||
|
#endif /* _DT_BINDINGS_STM32MP1_RESET_H_ */
|
||||||
|
diff --git a/include/dt-bindings/reset/stm32mp13-resets.h b/include/dt-bindings/reset/stm32mp13-resets.h
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..934864e90
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/include/dt-bindings/reset/stm32mp13-resets.h
|
||||||
|
@@ -0,0 +1,100 @@
|
||||||
|
+/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */
|
||||||
|
+/*
|
||||||
|
+ * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
|
||||||
|
+ * Author: Gabriel Fernandez <gabriel.fernandez@st.com> for STMicroelectronics.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#ifndef _DT_BINDINGS_STM32MP13_RESET_H_
|
||||||
|
+#define _DT_BINDINGS_STM32MP13_RESET_H_
|
||||||
|
+
|
||||||
|
+#define TIM2_R 13568
|
||||||
|
+#define TIM3_R 13569
|
||||||
|
+#define TIM4_R 13570
|
||||||
|
+#define TIM5_R 13571
|
||||||
|
+#define TIM6_R 13572
|
||||||
|
+#define TIM7_R 13573
|
||||||
|
+#define LPTIM1_R 13577
|
||||||
|
+#define SPI2_R 13579
|
||||||
|
+#define SPI3_R 13580
|
||||||
|
+#define USART3_R 13583
|
||||||
|
+#define UART4_R 13584
|
||||||
|
+#define UART5_R 13585
|
||||||
|
+#define UART7_R 13586
|
||||||
|
+#define UART8_R 13587
|
||||||
|
+#define I2C1_R 13589
|
||||||
|
+#define I2C2_R 13590
|
||||||
|
+#define SPDIF_R 13594
|
||||||
|
+#define TIM1_R 13632
|
||||||
|
+#define TIM8_R 13633
|
||||||
|
+#define SPI1_R 13640
|
||||||
|
+#define USART6_R 13645
|
||||||
|
+#define SAI1_R 13648
|
||||||
|
+#define SAI2_R 13649
|
||||||
|
+#define DFSDM_R 13652
|
||||||
|
+#define FDCAN_R 13656
|
||||||
|
+#define LPTIM2_R 13696
|
||||||
|
+#define LPTIM3_R 13697
|
||||||
|
+#define LPTIM4_R 13698
|
||||||
|
+#define LPTIM5_R 13699
|
||||||
|
+#define SYSCFG_R 13707
|
||||||
|
+#define VREF_R 13709
|
||||||
|
+#define DTS_R 13712
|
||||||
|
+#define PMBCTRL_R 13713
|
||||||
|
+#define LTDC_R 13760
|
||||||
|
+#define DCMIPP_R 13761
|
||||||
|
+#define DDRPERFM_R 13768
|
||||||
|
+#define USBPHY_R 13776
|
||||||
|
+#define STGEN_R 13844
|
||||||
|
+#define USART1_R 13888
|
||||||
|
+#define USART2_R 13889
|
||||||
|
+#define SPI4_R 13890
|
||||||
|
+#define SPI5_R 13891
|
||||||
|
+#define I2C3_R 13892
|
||||||
|
+#define I2C4_R 13893
|
||||||
|
+#define I2C5_R 13894
|
||||||
|
+#define TIM12_R 13895
|
||||||
|
+#define TIM13_R 13896
|
||||||
|
+#define TIM14_R 13897
|
||||||
|
+#define TIM15_R 13898
|
||||||
|
+#define TIM16_R 13899
|
||||||
|
+#define TIM17_R 13900
|
||||||
|
+#define DMA1_R 13952
|
||||||
|
+#define DMA2_R 13953
|
||||||
|
+#define DMAMUX1_R 13954
|
||||||
|
+#define DMA3_R 13955
|
||||||
|
+#define DMAMUX2_R 13956
|
||||||
|
+#define ADC1_R 13957
|
||||||
|
+#define ADC2_R 13958
|
||||||
|
+#define USBO_R 13960
|
||||||
|
+#define GPIOA_R 14080
|
||||||
|
+#define GPIOB_R 14081
|
||||||
|
+#define GPIOC_R 14082
|
||||||
|
+#define GPIOD_R 14083
|
||||||
|
+#define GPIOE_R 14084
|
||||||
|
+#define GPIOF_R 14085
|
||||||
|
+#define GPIOG_R 14086
|
||||||
|
+#define GPIOH_R 14087
|
||||||
|
+#define GPIOI_R 14088
|
||||||
|
+#define TSC_R 14095
|
||||||
|
+#define PKA_R 14146
|
||||||
|
+#define SAES_R 14147
|
||||||
|
+#define CRYP1_R 14148
|
||||||
|
+#define HASH1_R 14149
|
||||||
|
+#define RNG1_R 14150
|
||||||
|
+#define AXIMC_R 14160
|
||||||
|
+#define MDMA_R 14208
|
||||||
|
+#define MCE_R 14209
|
||||||
|
+#define ETH1MAC_R 14218
|
||||||
|
+#define FMC_R 14220
|
||||||
|
+#define QSPI_R 14222
|
||||||
|
+#define SDMMC1_R 14224
|
||||||
|
+#define SDMMC2_R 14225
|
||||||
|
+#define CRC1_R 14228
|
||||||
|
+#define USBH_R 14232
|
||||||
|
+#define ETH2MAC_R 14238
|
||||||
|
+
|
||||||
|
+/* SCMI reset domain identifiers */
|
||||||
|
+#define RST_SCMI_LTDC 0
|
||||||
|
+#define RST_SCMI_MDMA 1
|
||||||
|
+
|
||||||
|
+#endif /* _DT_BINDINGS_STM32MP13_RESET_H_ */
|
||||||
|
diff --git a/include/dt-bindings/rtc/rtc-stm32.h b/include/dt-bindings/rtc/rtc-stm32.h
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..2fd78c2e6
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/include/dt-bindings/rtc/rtc-stm32.h
|
||||||
|
@@ -0,0 +1,14 @@
|
||||||
|
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
|
+/*
|
||||||
|
+ * This header provides constants for STM32_RTC bindings.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#ifndef _DT_BINDINGS_RTC_RTC_STM32_H
|
||||||
|
+#define _DT_BINDINGS_RTC_RTC_STM32_H
|
||||||
|
+
|
||||||
|
+#define RTC_NO_OUT 0
|
||||||
|
+#define RTC_OUT1 1
|
||||||
|
+#define RTC_OUT2 2
|
||||||
|
+#define RTC_OUT2_RMP 3
|
||||||
|
+
|
||||||
|
+#endif
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,299 @@
|
||||||
|
From a0c67a64074c33685451fff84871a846bc29d523 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Christophe Priouzeau <christophe.priouzeau@foss.st.com>
|
||||||
|
Date: Tue, 31 May 2022 12:07:28 +0200
|
||||||
|
Subject: [PATCH 19/22] ARM-5.15.24-stm32mp1-r1-SOUND
|
||||||
|
|
||||||
|
Signed-off-by: Christophe Priouzeau <christophe.priouzeau@foss.st.com>
|
||||||
|
---
|
||||||
|
sound/soc/codecs/Kconfig | 2 +-
|
||||||
|
sound/soc/codecs/wm8994.c | 81 ++++++++++++++++++++++++++++++++---
|
||||||
|
sound/soc/stm/stm32_adfsdm.c | 11 +++--
|
||||||
|
sound/soc/stm/stm32_i2s.c | 4 ++
|
||||||
|
sound/soc/stm/stm32_sai_sub.c | 4 +-
|
||||||
|
sound/soc/stm/stm32_spdifrx.c | 4 ++
|
||||||
|
6 files changed, 94 insertions(+), 12 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
|
||||||
|
index f12c9b942..4cc91bcfe 100644
|
||||||
|
--- a/sound/soc/codecs/Kconfig
|
||||||
|
+++ b/sound/soc/codecs/Kconfig
|
||||||
|
@@ -1771,7 +1771,7 @@ config SND_SOC_WM8993
|
||||||
|
depends on I2C
|
||||||
|
|
||||||
|
config SND_SOC_WM8994
|
||||||
|
- tristate
|
||||||
|
+ tristate "Wolfson Microelectronics WM8994 codec"
|
||||||
|
|
||||||
|
config SND_SOC_WM8995
|
||||||
|
tristate
|
||||||
|
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
|
||||||
|
index f117ec0c4..98e803516 100644
|
||||||
|
--- a/sound/soc/codecs/wm8994.c
|
||||||
|
+++ b/sound/soc/codecs/wm8994.c
|
||||||
|
@@ -7,6 +7,7 @@
|
||||||
|
* Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
+#include <linux/clk.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/moduleparam.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
@@ -838,6 +839,37 @@ static int clk_sys_event(struct snd_soc_dapm_widget *w,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int mclk_event(struct snd_soc_dapm_widget *w,
|
||||||
|
+ struct snd_kcontrol *kcontrol, int event)
|
||||||
|
+{
|
||||||
|
+ struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
|
||||||
|
+ struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(comp);
|
||||||
|
+ int ret, mclk_id = 0;
|
||||||
|
+
|
||||||
|
+ if (!strncmp(w->name, "MCLK2", 5))
|
||||||
|
+ mclk_id = 1;
|
||||||
|
+
|
||||||
|
+ switch (event) {
|
||||||
|
+ case SND_SOC_DAPM_PRE_PMU:
|
||||||
|
+ dev_dbg(comp->dev, "Enable master clock %s\n",
|
||||||
|
+ mclk_id ? "MCLK2" : "MCLK1");
|
||||||
|
+
|
||||||
|
+ ret = clk_prepare_enable(wm8994->mclk[mclk_id].clk);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ dev_err(comp->dev, "Failed to enable clock: %d\n", ret);
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ case SND_SOC_DAPM_POST_PMD:
|
||||||
|
+ dev_dbg(comp->dev, "Disable master clock %s\n",
|
||||||
|
+ mclk_id ? "MCLK2" : "MCLK1");
|
||||||
|
+ clk_disable_unprepare(wm8994->mclk[mclk_id].clk);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void vmid_reference(struct snd_soc_component *component)
|
||||||
|
{
|
||||||
|
struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
|
||||||
|
@@ -1225,7 +1257,6 @@ static int aif2clk_ev(struct snd_soc_dapm_widget *w,
|
||||||
|
else
|
||||||
|
adc = WM8994_AIF2ADCL_ENA | WM8994_AIF2ADCR_ENA;
|
||||||
|
|
||||||
|
-
|
||||||
|
val = snd_soc_component_read(component, WM8994_AIF2_CONTROL_2);
|
||||||
|
if ((val & WM8994_AIF2DACL_SRC) &&
|
||||||
|
(val & WM8994_AIF2DACR_SRC))
|
||||||
|
@@ -1847,6 +1878,16 @@ static const struct snd_soc_dapm_widget wm8994_specific_dapm_widgets[] = {
|
||||||
|
SND_SOC_DAPM_MUX("AIF3ADC Mux", SND_SOC_NOPM, 0, 0, &wm8994_aif3adc_mux),
|
||||||
|
};
|
||||||
|
|
||||||
|
+static const struct snd_soc_dapm_widget wm8994_mclk1_dapm_widgets[] = {
|
||||||
|
+SND_SOC_DAPM_SUPPLY("MCLK1", SND_SOC_NOPM, 0, 0, mclk_event,
|
||||||
|
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static const struct snd_soc_dapm_widget wm8994_mclk2_dapm_widgets[] = {
|
||||||
|
+SND_SOC_DAPM_SUPPLY("MCLK2", SND_SOC_NOPM, 0, 0, mclk_event,
|
||||||
|
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
static const struct snd_soc_dapm_widget wm8958_dapm_widgets[] = {
|
||||||
|
SND_SOC_DAPM_SUPPLY("AIF3", WM8994_POWER_MANAGEMENT_6, 5, 1, NULL, 0),
|
||||||
|
SND_SOC_DAPM_MUX("Mono PCM Out Mux", SND_SOC_NOPM, 0, 0, &mono_pcm_out_mux),
|
||||||
|
@@ -2071,10 +2112,10 @@ static const struct snd_soc_dapm_route wm8994_lateclk_intercon[] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct snd_soc_dapm_route wm8994_revd_intercon[] = {
|
||||||
|
- { "AIF1DACDAT", NULL, "AIF2DACDAT" },
|
||||||
|
- { "AIF2DACDAT", NULL, "AIF1DACDAT" },
|
||||||
|
- { "AIF1ADCDAT", NULL, "AIF2ADCDAT" },
|
||||||
|
- { "AIF2ADCDAT", NULL, "AIF1ADCDAT" },
|
||||||
|
+// { "AIF1DACDAT", NULL, "AIF2DACDAT" },
|
||||||
|
+// { "AIF2DACDAT", NULL, "AIF1DACDAT" },
|
||||||
|
+// { "AIF1ADCDAT", NULL, "AIF2ADCDAT" },
|
||||||
|
+// { "AIF2ADCDAT", NULL, "AIF1ADCDAT" },
|
||||||
|
{ "MICBIAS1", NULL, "CLK_SYS" },
|
||||||
|
{ "MICBIAS1", NULL, "MICBIAS Supply" },
|
||||||
|
{ "MICBIAS2", NULL, "CLK_SYS" },
|
||||||
|
@@ -2506,11 +2547,24 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
|
||||||
|
{
|
||||||
|
struct snd_soc_component *component = dai->component;
|
||||||
|
struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component);
|
||||||
|
- int ret, i;
|
||||||
|
+ int i, ret;
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * Simple card provides unconditionnaly clock_id = 0.
|
||||||
|
+ * Workaround to select master clock for aif1/2
|
||||||
|
+ */
|
||||||
|
switch (dai->id) {
|
||||||
|
case 1:
|
||||||
|
+ if (wm8994->mclk[0].clk)
|
||||||
|
+ clk_id = WM8994_SYSCLK_MCLK1;
|
||||||
|
+ else if (wm8994->mclk[1].clk)
|
||||||
|
+ clk_id = WM8994_SYSCLK_MCLK2;
|
||||||
|
+ break;
|
||||||
|
case 2:
|
||||||
|
+ if (wm8994->mclk[1].clk)
|
||||||
|
+ clk_id = WM8994_SYSCLK_MCLK2;
|
||||||
|
+ else if (wm8994->mclk[0].clk)
|
||||||
|
+ clk_id = WM8994_SYSCLK_MCLK1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
@@ -2522,6 +2576,10 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
|
||||||
|
case WM8994_SYSCLK_MCLK1:
|
||||||
|
wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_MCLK1;
|
||||||
|
|
||||||
|
+ /* Avoid busy error on exclusive rate change request */
|
||||||
|
+ if (!freq)
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
ret = wm8994_set_mclk_rate(wm8994, dai->id - 1, &freq);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
@@ -2535,6 +2593,9 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
|
||||||
|
/* TODO: Set GPIO AF */
|
||||||
|
wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_MCLK2;
|
||||||
|
|
||||||
|
+ if (!freq)
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
ret = wm8994_set_mclk_rate(wm8994, dai->id - 1, &freq);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
@@ -4438,6 +4499,14 @@ static int wm8994_component_probe(struct snd_soc_component *component)
|
||||||
|
ARRAY_SIZE(wm8994_snd_controls));
|
||||||
|
snd_soc_dapm_new_controls(dapm, wm8994_specific_dapm_widgets,
|
||||||
|
ARRAY_SIZE(wm8994_specific_dapm_widgets));
|
||||||
|
+ if (wm8994->mclk[0].clk)
|
||||||
|
+ snd_soc_dapm_new_controls(dapm, wm8994_mclk1_dapm_widgets,
|
||||||
|
+ ARRAY_SIZE(wm8994_mclk1_dapm_widgets));
|
||||||
|
+
|
||||||
|
+ if (wm8994->mclk[1].clk)
|
||||||
|
+ snd_soc_dapm_new_controls(dapm, wm8994_mclk2_dapm_widgets,
|
||||||
|
+ ARRAY_SIZE(wm8994_mclk2_dapm_widgets));
|
||||||
|
+
|
||||||
|
if (control->revision < 4) {
|
||||||
|
snd_soc_dapm_new_controls(dapm, wm8994_lateclk_revd_widgets,
|
||||||
|
ARRAY_SIZE(wm8994_lateclk_revd_widgets));
|
||||||
|
diff --git a/sound/soc/stm/stm32_adfsdm.c b/sound/soc/stm/stm32_adfsdm.c
|
||||||
|
index e6078f50e..534f96af9 100644
|
||||||
|
--- a/sound/soc/stm/stm32_adfsdm.c
|
||||||
|
+++ b/sound/soc/stm/stm32_adfsdm.c
|
||||||
|
@@ -12,7 +12,7 @@
|
||||||
|
#include <linux/mutex.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
-
|
||||||
|
+#include <linux/pm_runtime.h>
|
||||||
|
#include <linux/iio/iio.h>
|
||||||
|
#include <linux/iio/consumer.h>
|
||||||
|
#include <linux/iio/adc/stm32-dfsdm-adc.h>
|
||||||
|
@@ -363,15 +363,20 @@ static int stm32_adfsdm_probe(struct platform_device *pdev)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ret = snd_soc_add_component(component, NULL, 0);
|
||||||
|
- if (ret < 0)
|
||||||
|
+ if (ret < 0) {
|
||||||
|
dev_err(&pdev->dev, "%s: Failed to register PCM platform\n",
|
||||||
|
__func__);
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- return ret;
|
||||||
|
+ pm_runtime_enable(&pdev->dev);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int stm32_adfsdm_remove(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
+ pm_runtime_disable(&pdev->dev);
|
||||||
|
snd_soc_unregister_component(&pdev->dev);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
diff --git a/sound/soc/stm/stm32_i2s.c b/sound/soc/stm/stm32_i2s.c
|
||||||
|
index 717f45a83..61e2c5d51 100644
|
||||||
|
--- a/sound/soc/stm/stm32_i2s.c
|
||||||
|
+++ b/sound/soc/stm/stm32_i2s.c
|
||||||
|
@@ -13,6 +13,7 @@
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/of_irq.h>
|
||||||
|
#include <linux/of_platform.h>
|
||||||
|
+#include <linux/pm_runtime.h>
|
||||||
|
#include <linux/regmap.h>
|
||||||
|
#include <linux/reset.h>
|
||||||
|
#include <linux/spinlock.h>
|
||||||
|
@@ -1113,6 +1114,7 @@ static int stm32_i2s_remove(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
snd_dmaengine_pcm_unregister(&pdev->dev);
|
||||||
|
snd_soc_unregister_component(&pdev->dev);
|
||||||
|
+ pm_runtime_disable(&pdev->dev);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -1195,6 +1197,8 @@ static int stm32_i2s_probe(struct platform_device *pdev)
|
||||||
|
FIELD_GET(I2S_VERR_MIN_MASK, val));
|
||||||
|
}
|
||||||
|
|
||||||
|
+ pm_runtime_enable(&pdev->dev);
|
||||||
|
+
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
error:
|
||||||
|
diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c
|
||||||
|
index 9c3b8e209..95cd38a50 100644
|
||||||
|
--- a/sound/soc/stm/stm32_sai_sub.c
|
||||||
|
+++ b/sound/soc/stm/stm32_sai_sub.c
|
||||||
|
@@ -1294,7 +1294,7 @@ static struct snd_soc_dai_driver stm32_sai_playback_dai = {
|
||||||
|
.id = 1, /* avoid call to fmt_single_name() */
|
||||||
|
.playback = {
|
||||||
|
.channels_min = 1,
|
||||||
|
- .channels_max = 2,
|
||||||
|
+ .channels_max = 16,
|
||||||
|
.rate_min = 8000,
|
||||||
|
.rate_max = 192000,
|
||||||
|
.rates = SNDRV_PCM_RATE_CONTINUOUS,
|
||||||
|
@@ -1312,7 +1312,7 @@ static struct snd_soc_dai_driver stm32_sai_capture_dai = {
|
||||||
|
.id = 1, /* avoid call to fmt_single_name() */
|
||||||
|
.capture = {
|
||||||
|
.channels_min = 1,
|
||||||
|
- .channels_max = 2,
|
||||||
|
+ .channels_max = 16,
|
||||||
|
.rate_min = 8000,
|
||||||
|
.rate_max = 192000,
|
||||||
|
.rates = SNDRV_PCM_RATE_CONTINUOUS,
|
||||||
|
diff --git a/sound/soc/stm/stm32_spdifrx.c b/sound/soc/stm/stm32_spdifrx.c
|
||||||
|
index 48145f553..e885796ca 100644
|
||||||
|
--- a/sound/soc/stm/stm32_spdifrx.c
|
||||||
|
+++ b/sound/soc/stm/stm32_spdifrx.c
|
||||||
|
@@ -12,6 +12,7 @@
|
||||||
|
#include <linux/delay.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/of_platform.h>
|
||||||
|
+#include <linux/pm_runtime.h>
|
||||||
|
#include <linux/regmap.h>
|
||||||
|
#include <linux/reset.h>
|
||||||
|
|
||||||
|
@@ -955,6 +956,7 @@ static int stm32_spdifrx_remove(struct platform_device *pdev)
|
||||||
|
|
||||||
|
snd_dmaengine_pcm_unregister(&pdev->dev);
|
||||||
|
snd_soc_unregister_component(&pdev->dev);
|
||||||
|
+ pm_runtime_disable(&pdev->dev);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -1045,6 +1047,8 @@ static int stm32_spdifrx_probe(struct platform_device *pdev)
|
||||||
|
FIELD_GET(SPDIFRX_VERR_MIN_MASK, ver));
|
||||||
|
}
|
||||||
|
|
||||||
|
+ pm_runtime_enable(&pdev->dev);
|
||||||
|
+
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
error:
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
|
|
@ -0,0 +1,411 @@
|
||||||
|
From 4627c869d60932edc00dd979d9b1bd374518c5c8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Christophe Priouzeau <christophe.priouzeau@foss.st.com>
|
||||||
|
Date: Tue, 31 May 2022 12:08:46 +0200
|
||||||
|
Subject: [PATCH 20/22] ARM-5.15.24-stm32mp1-r1-CPUIDLE-POWER
|
||||||
|
|
||||||
|
Signed-off-by: Christophe Priouzeau <christophe.priouzeau@foss.st.com>
|
||||||
|
---
|
||||||
|
.../bindings/cpufreq/stm32-cpufreq.txt | 61 ++++
|
||||||
|
drivers/cpuidle/Kconfig.arm | 8 +
|
||||||
|
drivers/cpuidle/Makefile | 1 +
|
||||||
|
drivers/cpuidle/cpuidle-stm32.c | 276 ++++++++++++++++++
|
||||||
|
kernel/power/suspend.c | 1 -
|
||||||
|
5 files changed, 346 insertions(+), 1 deletion(-)
|
||||||
|
create mode 100644 Documentation/devicetree/bindings/cpufreq/stm32-cpufreq.txt
|
||||||
|
create mode 100644 drivers/cpuidle/cpuidle-stm32.c
|
||||||
|
|
||||||
|
diff --git a/Documentation/devicetree/bindings/cpufreq/stm32-cpufreq.txt b/Documentation/devicetree/bindings/cpufreq/stm32-cpufreq.txt
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..1292eb261
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/Documentation/devicetree/bindings/cpufreq/stm32-cpufreq.txt
|
||||||
|
@@ -0,0 +1,61 @@
|
||||||
|
+STM32 CPUFreq and OPP bindings
|
||||||
|
+==============================
|
||||||
|
+
|
||||||
|
+STM32 CPUFreq driver needs to read chip information from the SoC to list
|
||||||
|
+available OPPs. Then it depends on cpufreq-dt bindings.
|
||||||
|
+
|
||||||
|
+Required properties:
|
||||||
|
+--------------------
|
||||||
|
+- clocks: Phandle to the cpu clock "cpu".
|
||||||
|
+- clocks-name: Should contain "cpu".
|
||||||
|
+- nvmem-cells: Phandle to nvmem cell that contains "part_number".
|
||||||
|
+- nvmem-cell-names: Must be "part_number".
|
||||||
|
+- operating-points-v2: Phandle to operating points table. See ../power/opp.txt
|
||||||
|
+ for more details.
|
||||||
|
+
|
||||||
|
+Optional properties:
|
||||||
|
+--------------------
|
||||||
|
+See cpufreq-dt.txt for optional properties.
|
||||||
|
+
|
||||||
|
+Examples:
|
||||||
|
+---------
|
||||||
|
+ cpus {
|
||||||
|
+ #address-cells = <1>;
|
||||||
|
+ #size-cells = <0>;
|
||||||
|
+
|
||||||
|
+ cpu0: cpu@0 {
|
||||||
|
+ compatible = "arm,cortex-a7";
|
||||||
|
+ device_type = "cpu";
|
||||||
|
+ reg = <0>;
|
||||||
|
+ clocks = <&rcc CK_MPU>;
|
||||||
|
+ clock-names = "cpu";
|
||||||
|
+ operating-points-v2 = <&cpu0_opp_table>;
|
||||||
|
+ nvmem-cells = <&part_number_otp>;
|
||||||
|
+ nvmem-cell-names = "part_number";
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ cpu1: cpu@1 {
|
||||||
|
+ compatible = "arm,cortex-a7";
|
||||||
|
+ device_type = "cpu";
|
||||||
|
+ reg = <1>;
|
||||||
|
+ clocks = <&rcc CK_MPU>;
|
||||||
|
+ clock-names = "cpu";
|
||||||
|
+ operating-points-v2 = <&cpu0_opp_table>;
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ cpu0_opp_table: cpu0-opp-table {
|
||||||
|
+ compatible = "operating-points-v2";
|
||||||
|
+ opp-shared;
|
||||||
|
+
|
||||||
|
+ opp-650000000 {
|
||||||
|
+ opp-hz = /bits/ 64 <650000000>;
|
||||||
|
+ opp-microvolt = <1200000>;
|
||||||
|
+ opp-supported-hw = <0x1>;
|
||||||
|
+ };
|
||||||
|
+ opp-800000000 {
|
||||||
|
+ opp-hz = /bits/ 64 <800000000>;
|
||||||
|
+ opp-microvolt = <1350000>;
|
||||||
|
+ opp-supported-hw = <0x2>;
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
|
||||||
|
index 334f83e56..4de5db493 100644
|
||||||
|
--- a/drivers/cpuidle/Kconfig.arm
|
||||||
|
+++ b/drivers/cpuidle/Kconfig.arm
|
||||||
|
@@ -91,6 +91,14 @@ config ARM_EXYNOS_CPUIDLE
|
||||||
|
help
|
||||||
|
Select this to enable cpuidle for Exynos processors.
|
||||||
|
|
||||||
|
+config ARM_STM32_CPUIDLE
|
||||||
|
+ bool "Cpu Idle Driver for the STM32 processors"
|
||||||
|
+ depends on MACH_STM32MP157
|
||||||
|
+ select DT_IDLE_STATES
|
||||||
|
+ select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP
|
||||||
|
+ help
|
||||||
|
+ Select this to enable cpuidle for STM32 processors.
|
||||||
|
+
|
||||||
|
config ARM_MVEBU_V7_CPUIDLE
|
||||||
|
bool "CPU Idle Driver for mvebu v7 family processors"
|
||||||
|
depends on (ARCH_MVEBU || COMPILE_TEST) && !ARM64
|
||||||
|
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
|
||||||
|
index 26bbc5e74..cc1eccc73 100644
|
||||||
|
--- a/drivers/cpuidle/Makefile
|
||||||
|
+++ b/drivers/cpuidle/Makefile
|
||||||
|
@@ -25,6 +25,7 @@ obj-$(CONFIG_ARM_PSCI_CPUIDLE) += cpuidle-psci.o
|
||||||
|
obj-$(CONFIG_ARM_PSCI_CPUIDLE_DOMAIN) += cpuidle-psci-domain.o
|
||||||
|
obj-$(CONFIG_ARM_TEGRA_CPUIDLE) += cpuidle-tegra.o
|
||||||
|
obj-$(CONFIG_ARM_QCOM_SPM_CPUIDLE) += cpuidle-qcom-spm.o
|
||||||
|
+obj-$(CONFIG_ARM_STM32_CPUIDLE) += cpuidle-stm32.o
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# MIPS drivers
|
||||||
|
diff --git a/drivers/cpuidle/cpuidle-stm32.c b/drivers/cpuidle/cpuidle-stm32.c
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..2fef170d6
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/drivers/cpuidle/cpuidle-stm32.c
|
||||||
|
@@ -0,0 +1,276 @@
|
||||||
|
+// SPDX-License-Identifier: GPL-2.0
|
||||||
|
+// Copyright (C) STMicroelectronics 2019
|
||||||
|
+// Author:
|
||||||
|
+
|
||||||
|
+#include <linux/arm-smccc.h>
|
||||||
|
+#include <linux/cpu_pm.h>
|
||||||
|
+#include <linux/cpuidle.h>
|
||||||
|
+#include <linux/module.h>
|
||||||
|
+#include <linux/platform_device.h>
|
||||||
|
+#include <linux/pm_domain.h>
|
||||||
|
+#include <linux/pm_runtime.h>
|
||||||
|
+#include <linux/of.h>
|
||||||
|
+#include <linux/slab.h>
|
||||||
|
+#include <linux/tick.h>
|
||||||
|
+
|
||||||
|
+#include <asm/cpuidle.h>
|
||||||
|
+
|
||||||
|
+#include "dt_idle_states.h"
|
||||||
|
+
|
||||||
|
+#define SMC_AUTOSTOP() \
|
||||||
|
+{ \
|
||||||
|
+ struct arm_smccc_res res; \
|
||||||
|
+ arm_smccc_smc(0x8200100a, 0, 0, 0, \
|
||||||
|
+ 0, 0, 0, 0, &res); \
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+struct stm32_pm_domain {
|
||||||
|
+ struct device *dev;
|
||||||
|
+ struct generic_pm_domain genpd;
|
||||||
|
+ int id;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static atomic_t stm_idle_barrier;
|
||||||
|
+
|
||||||
|
+static int stm32_enter_idle(struct cpuidle_device *dev,
|
||||||
|
+ struct cpuidle_driver *drv, int index)
|
||||||
|
+{
|
||||||
|
+ /*
|
||||||
|
+ * Call idle CPU PM enter notifier chain so that
|
||||||
|
+ * VFP and per CPU interrupt context is saved.
|
||||||
|
+ */
|
||||||
|
+ cpu_pm_enter();
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * be sure that both cpu enter at the same time
|
||||||
|
+ * normally not needed is the state is declared as coupled
|
||||||
|
+ */
|
||||||
|
+ cpuidle_coupled_parallel_barrier(dev, &stm_idle_barrier);
|
||||||
|
+
|
||||||
|
+ /* Enter broadcast mode for periodic timers */
|
||||||
|
+ tick_broadcast_enable();
|
||||||
|
+
|
||||||
|
+ /* Enter broadcast mode for one-shot timers */
|
||||||
|
+ tick_broadcast_enter();
|
||||||
|
+
|
||||||
|
+ if (dev->cpu == 0)
|
||||||
|
+ cpu_cluster_pm_enter();
|
||||||
|
+
|
||||||
|
+ SMC_AUTOSTOP();
|
||||||
|
+
|
||||||
|
+ if (dev->cpu == 0)
|
||||||
|
+ cpu_cluster_pm_exit();
|
||||||
|
+
|
||||||
|
+ tick_broadcast_exit();
|
||||||
|
+
|
||||||
|
+ cpuidle_coupled_parallel_barrier(dev, &stm_idle_barrier);
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Call idle CPU PM exit notifier chain to restore
|
||||||
|
+ * VFP and per CPU IRQ context.
|
||||||
|
+ */
|
||||||
|
+ cpu_pm_exit();
|
||||||
|
+
|
||||||
|
+ return index;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static const struct of_device_id stm32_idle_state_match[] __initconst = {
|
||||||
|
+ { .compatible = "arm,idle-state",
|
||||||
|
+ .data = stm32_enter_idle },
|
||||||
|
+ { },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct cpuidle_driver stm32_idle_driver = {
|
||||||
|
+ .name = "stm32_idle",
|
||||||
|
+ .states = {
|
||||||
|
+ ARM_CPUIDLE_WFI_STATE,
|
||||||
|
+ {
|
||||||
|
+ .enter = stm32_enter_idle,
|
||||||
|
+ .exit_latency = 620,
|
||||||
|
+ .target_residency = 700,
|
||||||
|
+ .flags = /*CPUIDLE_FLAG_TIMER_STOP | */
|
||||||
|
+ CPUIDLE_FLAG_COUPLED,
|
||||||
|
+ .name = "CStop",
|
||||||
|
+ .desc = "Clocks off",
|
||||||
|
+ },
|
||||||
|
+ },
|
||||||
|
+ .safe_state_index = 0,
|
||||||
|
+ .state_count = 2,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int stm32_pd_cpuidle_off(struct generic_pm_domain *domain)
|
||||||
|
+{
|
||||||
|
+ struct stm32_pm_domain *priv = container_of(domain,
|
||||||
|
+ struct stm32_pm_domain,
|
||||||
|
+ genpd);
|
||||||
|
+ int cpu;
|
||||||
|
+
|
||||||
|
+ for_each_possible_cpu(cpu) {
|
||||||
|
+ struct cpuidle_device *cpuidle_dev = per_cpu(cpuidle_devices,
|
||||||
|
+ cpu);
|
||||||
|
+
|
||||||
|
+ cpuidle_dev->states_usage[1].disable = false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ dev_dbg(priv->dev, "%s OFF\n", domain->name);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int stm32_pd_cpuidle_on(struct generic_pm_domain *domain)
|
||||||
|
+{
|
||||||
|
+ struct stm32_pm_domain *priv = container_of(domain,
|
||||||
|
+ struct stm32_pm_domain,
|
||||||
|
+ genpd);
|
||||||
|
+ int cpu;
|
||||||
|
+
|
||||||
|
+ for_each_possible_cpu(cpu) {
|
||||||
|
+ struct cpuidle_device *cpuidle_dev = per_cpu(cpuidle_devices,
|
||||||
|
+ cpu);
|
||||||
|
+
|
||||||
|
+ cpuidle_dev->states_usage[1].disable = true;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ dev_dbg(priv->dev, "%s ON\n", domain->name);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void stm32_cpuidle_domain_remove(struct stm32_pm_domain *domain)
|
||||||
|
+{
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ ret = pm_genpd_remove(&domain->genpd);
|
||||||
|
+ if (ret)
|
||||||
|
+ dev_err(domain->dev, "failed to remove PM domain %s: %d\n",
|
||||||
|
+ domain->genpd.name, ret);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int stm32_cpuidle_domain_add(struct stm32_pm_domain *domain,
|
||||||
|
+ struct device *dev,
|
||||||
|
+ struct device_node *np)
|
||||||
|
+{
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ domain->dev = dev;
|
||||||
|
+ domain->genpd.name = np->name;
|
||||||
|
+ domain->genpd.power_off = stm32_pd_cpuidle_off;
|
||||||
|
+ domain->genpd.power_on = stm32_pd_cpuidle_on;
|
||||||
|
+
|
||||||
|
+ ret = pm_genpd_init(&domain->genpd, NULL, 0);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ dev_err(domain->dev, "failed to initialise PM domain %s: %d\n",
|
||||||
|
+ np->name, ret);
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = of_genpd_add_provider_simple(np, &domain->genpd);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ dev_err(domain->dev, "failed to register PM domain %s: %d\n",
|
||||||
|
+ np->name, ret);
|
||||||
|
+ stm32_cpuidle_domain_remove(domain);
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ dev_info(domain->dev, "domain %s registered\n", np->name);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int stm32_cpuidle_probe(struct platform_device *pdev)
|
||||||
|
+{
|
||||||
|
+ struct cpuidle_driver *drv;
|
||||||
|
+ struct stm32_pm_domain *domain;
|
||||||
|
+ struct device *dev = &pdev->dev;
|
||||||
|
+ struct device_node *np = dev->of_node;
|
||||||
|
+ struct of_phandle_args child, parent;
|
||||||
|
+ struct device_node *np_child;
|
||||||
|
+ int cpu, ret;
|
||||||
|
+
|
||||||
|
+ drv = devm_kmemdup(dev, &stm32_idle_driver, sizeof(*drv), GFP_KERNEL);
|
||||||
|
+ if (!drv)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+
|
||||||
|
+ /* Start at index 1, index 0 standard WFI */
|
||||||
|
+ ret = dt_init_idle_driver(drv, stm32_idle_state_match, 1);
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ /* all the cpus of the system are coupled */
|
||||||
|
+ ret = cpuidle_register(drv, cpu_possible_mask);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ /* Declare cpuidle domain */
|
||||||
|
+ domain = devm_kzalloc(dev, sizeof(*domain), GFP_KERNEL);
|
||||||
|
+ if (!domain)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+
|
||||||
|
+ ret = stm32_cpuidle_domain_add(domain, dev, np);
|
||||||
|
+ if (ret) {
|
||||||
|
+ devm_kfree(dev, domain);
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* disable cpu idle */
|
||||||
|
+ for_each_possible_cpu(cpu) {
|
||||||
|
+ struct cpuidle_device *cpuidle_dev = per_cpu(cpuidle_devices,
|
||||||
|
+ cpu);
|
||||||
|
+
|
||||||
|
+ cpuidle_dev->states_usage[1].disable = true;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* link main cpuidle domain to consumer domain */
|
||||||
|
+ for_each_child_of_node(np, np_child) {
|
||||||
|
+ if (!of_parse_phandle_with_args(np_child, "power-domains",
|
||||||
|
+ "#power-domain-cells",
|
||||||
|
+ 0, &child)) {
|
||||||
|
+ struct device_node *np_test = child.np;
|
||||||
|
+
|
||||||
|
+ parent.np = np;
|
||||||
|
+ parent.args_count = 0;
|
||||||
|
+
|
||||||
|
+ ret = of_genpd_add_subdomain(&parent, &child);
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ dev_err(dev, "failed to add Sub PM domain %d\n",
|
||||||
|
+ ret);
|
||||||
|
+
|
||||||
|
+ dev_dbg(dev, "%s, add sub cpuidle of %s, with child %s\n",
|
||||||
|
+ __func__, np->name, np_test->name);
|
||||||
|
+
|
||||||
|
+ pm_runtime_put(dev);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ dev_info(dev, "cpuidle domain probed\n");
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int stm32_cpuidle_remove(struct platform_device *pdev)
|
||||||
|
+{
|
||||||
|
+ cpuidle_unregister(&stm32_idle_driver);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static const struct of_device_id stm32_cpuidle_of_match[] = {
|
||||||
|
+ {
|
||||||
|
+ .compatible = "stm32,cpuidle",
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct platform_driver stm32_cpuidle_driver = {
|
||||||
|
+ .probe = stm32_cpuidle_probe,
|
||||||
|
+ .remove = stm32_cpuidle_remove,
|
||||||
|
+ .driver = {
|
||||||
|
+ .name = "stm32_cpuidle",
|
||||||
|
+ .owner = THIS_MODULE,
|
||||||
|
+ .of_match_table = stm32_cpuidle_of_match,
|
||||||
|
+ },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+module_platform_driver(stm32_cpuidle_driver);
|
||||||
|
+
|
||||||
|
+MODULE_AUTHOR("<>");
|
||||||
|
+MODULE_DESCRIPTION("STM32 cpu idle driver");
|
||||||
|
+MODULE_LICENSE("GPL v2");
|
||||||
|
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
|
||||||
|
index 13d905dd3..371f2765d 100644
|
||||||
|
--- a/kernel/power/suspend.c
|
||||||
|
+++ b/kernel/power/suspend.c
|
||||||
|
@@ -34,7 +34,6 @@
|
||||||
|
#include "power.h"
|
||||||
|
|
||||||
|
const char * const pm_labels[] = {
|
||||||
|
- [PM_SUSPEND_TO_IDLE] = "freeze",
|
||||||
|
[PM_SUSPEND_STANDBY] = "standby",
|
||||||
|
[PM_SUSPEND_MEM] = "mem",
|
||||||
|
};
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,22 +1,23 @@
|
||||||
From 3bf729d5673783f6e5d2414bb526be34c0a6dbd7 Mon Sep 17 00:00:00 2001
|
From 334f4603a6c9a1bb69ca6b65edf385156dac578b Mon Sep 17 00:00:00 2001
|
||||||
From: Lionel Vitte <lionel.vitte@st.com>
|
From: Christophe Priouzeau <christophe.priouzeau@foss.st.com>
|
||||||
Date: Thu, 14 Oct 2021 16:51:57 +0200
|
Date: Tue, 31 May 2022 12:10:24 +0200
|
||||||
Subject: [PATCH 23/23] ARM 5.10.61-stm32mp1-r2 CONFIG
|
Subject: [PATCH 22/22] ARM-5.15.24-stm32mp1-r1-CONFIG
|
||||||
|
|
||||||
|
Signed-off-by: Christophe Priouzeau <christophe.priouzeau@foss.st.com>
|
||||||
---
|
---
|
||||||
.../fragment-01-multiv7_cleanup.config | 382 +++++++++++++++++
|
.../fragment-01-multiv7_cleanup.config | 408 +++++++++++++++++
|
||||||
.../configs/fragment-02-multiv7_addons.config | 398 ++++++++++++++++++
|
.../configs/fragment-02-multiv7_addons.config | 419 ++++++++++++++++++
|
||||||
arch/arm/configs/multi_v7_defconfig | 5 +
|
arch/arm/configs/multi_v7_defconfig | 1 +
|
||||||
3 files changed, 785 insertions(+)
|
3 files changed, 828 insertions(+)
|
||||||
create mode 100644 arch/arm/configs/fragment-01-multiv7_cleanup.config
|
create mode 100644 arch/arm/configs/fragment-01-multiv7_cleanup.config
|
||||||
create mode 100644 arch/arm/configs/fragment-02-multiv7_addons.config
|
create mode 100644 arch/arm/configs/fragment-02-multiv7_addons.config
|
||||||
|
|
||||||
diff --git a/arch/arm/configs/fragment-01-multiv7_cleanup.config b/arch/arm/configs/fragment-01-multiv7_cleanup.config
|
diff --git a/arch/arm/configs/fragment-01-multiv7_cleanup.config b/arch/arm/configs/fragment-01-multiv7_cleanup.config
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 000000000..4ea7ae3bc
|
index 000000000..52f28a765
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/arch/arm/configs/fragment-01-multiv7_cleanup.config
|
+++ b/arch/arm/configs/fragment-01-multiv7_cleanup.config
|
||||||
@@ -0,0 +1,382 @@
|
@@ -0,0 +1,408 @@
|
||||||
+#
|
+#
|
||||||
+# CPU Core family selection
|
+# CPU Core family selection
|
||||||
+#
|
+#
|
||||||
|
|
@ -34,7 +35,19 @@ index 000000000..4ea7ae3bc
|
||||||
+# CONFIG_ARCH_MESON is not set
|
+# CONFIG_ARCH_MESON is not set
|
||||||
+# CONFIG_ARCH_MXC is not set
|
+# CONFIG_ARCH_MXC is not set
|
||||||
+# CONFIG_ARCH_MEDIATEK is not set
|
+# CONFIG_ARCH_MEDIATEK is not set
|
||||||
|
+# CONFIG_ARCH_ACTIONS is not set
|
||||||
|
+# CONFIG_ARCH_ASPEED is not set
|
||||||
|
+# CONFIG_ARCH_ARCH_MILBEAU is not set
|
||||||
|
+# CONFIG_ARCH_INTEL_SOCFPGA is not set
|
||||||
+
|
+
|
||||||
|
+# Generic Pulse-Width Modulation (PWM) support
|
||||||
|
+# CONFIG_PWM_ATMEL_TCB is not set
|
||||||
|
+
|
||||||
|
+# network driver
|
||||||
|
+# CONFIG_NET_VENDOR_ACTIONS is not set
|
||||||
|
+
|
||||||
|
+# clock driver
|
||||||
|
+# CONFIG_CLK_ACTIONS is not set
|
||||||
+
|
+
|
||||||
+#
|
+#
|
||||||
+# TI OMAP/AM/DM/DRA Family
|
+# TI OMAP/AM/DM/DRA Family
|
||||||
|
|
@ -106,6 +119,11 @@ index 000000000..4ea7ae3bc
|
||||||
+# CONFIG_EFI is not set
|
+# CONFIG_EFI is not set
|
||||||
+
|
+
|
||||||
+#
|
+#
|
||||||
|
+# MII PHY device drivers
|
||||||
|
+#
|
||||||
|
+# CONFIG_MICROCHIP_PHY is not set
|
||||||
|
+# CONFIG_USB_LAN78XX is not set
|
||||||
|
+#
|
||||||
+# CAN SPI interfaces
|
+# CAN SPI interfaces
|
||||||
+#
|
+#
|
||||||
+# CONFIG_CAN_MCP251X is not set
|
+# CONFIG_CAN_MCP251X is not set
|
||||||
|
|
@ -149,6 +167,10 @@ index 000000000..4ea7ae3bc
|
||||||
+# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
|
+# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
|
||||||
+
|
+
|
||||||
+#
|
+#
|
||||||
|
+# MII PHY device drivers
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+#
|
||||||
+# USB Imaging devices
|
+# USB Imaging devices
|
||||||
+#
|
+#
|
||||||
+# CONFIG_USB_MUSB_HDRC is not set
|
+# CONFIG_USB_MUSB_HDRC is not set
|
||||||
|
|
@ -168,6 +190,9 @@ index 000000000..4ea7ae3bc
|
||||||
+# SPI NOR device support
|
+# SPI NOR device support
|
||||||
+# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set
|
+# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set
|
||||||
+
|
+
|
||||||
|
+# parallel NAND support
|
||||||
|
+# CONFIG_MTD_NAND_PL35X is not set
|
||||||
|
+
|
||||||
+#
|
+#
|
||||||
+# Media core support
|
+# Media core support
|
||||||
+#
|
+#
|
||||||
|
|
@ -341,6 +366,7 @@ index 000000000..4ea7ae3bc
|
||||||
+# CONFIG_DVB_AU8522_DTV is not set
|
+# CONFIG_DVB_AU8522_DTV is not set
|
||||||
+# CONFIG_DVB_AU8522_V4L is not set
|
+# CONFIG_DVB_AU8522_V4L is not set
|
||||||
+# CONFIG_DVB_S5H1411 is not set
|
+# CONFIG_DVB_S5H1411 is not set
|
||||||
|
+# CONFIG_DVB_MXL692 is not set
|
||||||
+
|
+
|
||||||
+#
|
+#
|
||||||
+# ISDB-T (terrestrial) frontends
|
+# ISDB-T (terrestrial) frontends
|
||||||
|
|
@ -392,19 +418,20 @@ index 000000000..4ea7ae3bc
|
||||||
+# CONFIG_DVB_SP2 is not set
|
+# CONFIG_DVB_SP2 is not set
|
||||||
+# end of Customise DVB Frontends
|
+# end of Customise DVB Frontends
|
||||||
+
|
+
|
||||||
+# Remove Console display driver support
|
|
||||||
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
|
|
||||||
+
|
+
|
||||||
+# Remove GCC plugins as not supported by GCC9.x
|
+# Remove GCC plugins as not supported by GCC9.x
|
||||||
+# To enable on GCC10
|
+# To enable on GCC10
|
||||||
+#
|
+#
|
||||||
+# CONFIG_GCC_PLUGINS is not set
|
+# CONFIG_GCC_PLUGINS is not set
|
||||||
|
+
|
||||||
|
+# Remove Console display driver support
|
||||||
|
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
|
||||||
diff --git a/arch/arm/configs/fragment-02-multiv7_addons.config b/arch/arm/configs/fragment-02-multiv7_addons.config
|
diff --git a/arch/arm/configs/fragment-02-multiv7_addons.config b/arch/arm/configs/fragment-02-multiv7_addons.config
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 000000000..d6c1a48d5
|
index 000000000..5ce8ee7aa
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/arch/arm/configs/fragment-02-multiv7_addons.config
|
+++ b/arch/arm/configs/fragment-02-multiv7_addons.config
|
||||||
@@ -0,0 +1,398 @@
|
@@ -0,0 +1,419 @@
|
||||||
+#
|
+#
|
||||||
+# General setup
|
+# General setup
|
||||||
+#
|
+#
|
||||||
|
|
@ -412,6 +439,9 @@ index 000000000..d6c1a48d5
|
||||||
+CONFIG_USELIB=y
|
+CONFIG_USELIB=y
|
||||||
+CONFIG_FUTEX=y
|
+CONFIG_FUTEX=y
|
||||||
+
|
+
|
||||||
|
+CONFIG_PREEMPT=y
|
||||||
|
+CONFIG_PREEMPT_COUNT=y
|
||||||
|
+
|
||||||
+#
|
+#
|
||||||
+# RCU Subsystem
|
+# RCU Subsystem
|
||||||
+#
|
+#
|
||||||
|
|
@ -433,8 +463,6 @@ index 000000000..d6c1a48d5
|
||||||
+CONFIG_SCHED_MC=y
|
+CONFIG_SCHED_MC=y
|
||||||
+CONFIG_MCPM=y
|
+CONFIG_MCPM=y
|
||||||
+CONFIG_NR_CPUS=2
|
+CONFIG_NR_CPUS=2
|
||||||
+CONFIG_PREEMPT=y
|
|
||||||
+CONFIG_PREEMPT_COUNT=y
|
|
||||||
+CONFIG_AEABI=y
|
+CONFIG_AEABI=y
|
||||||
+CONFIG_HIGHMEM=y
|
+CONFIG_HIGHMEM=y
|
||||||
+CONFIG_FORCE_MAX_ZONEORDER=12
|
+CONFIG_FORCE_MAX_ZONEORDER=12
|
||||||
|
|
@ -448,9 +476,6 @@ index 000000000..d6c1a48d5
|
||||||
+#
|
+#
|
||||||
+# CPU Power Management
|
+# CPU Power Management
|
||||||
+#
|
+#
|
||||||
+#
|
|
||||||
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
|
|
||||||
+
|
|
||||||
+
|
+
|
||||||
+#
|
+#
|
||||||
+# Floating point emulation
|
+# Floating point emulation
|
||||||
|
|
@ -486,11 +511,6 @@ index 000000000..d6c1a48d5
|
||||||
+CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
|
+CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
|
||||||
+
|
+
|
||||||
+#
|
+#
|
||||||
+# Default contiguous memory area size:
|
|
||||||
+#
|
|
||||||
+CONFIG_CMA_SIZE_MBYTES=128
|
|
||||||
+
|
|
||||||
+#
|
|
||||||
+# Disk-On-Chip Device Drivers
|
+# Disk-On-Chip Device Drivers
|
||||||
+#
|
+#
|
||||||
+
|
+
|
||||||
|
|
@ -525,6 +545,11 @@ index 000000000..d6c1a48d5
|
||||||
+#
|
+#
|
||||||
+# Character devices
|
+# Character devices
|
||||||
+#
|
+#
|
||||||
|
+CONFIG_LEGACY_PTY_COUNT=8
|
||||||
|
+
|
||||||
|
+#
|
||||||
|
+# Non-8250 serial port support
|
||||||
|
+#
|
||||||
+CONFIG_SERIAL_NONSTANDARD=y
|
+CONFIG_SERIAL_NONSTANDARD=y
|
||||||
+
|
+
|
||||||
+#
|
+#
|
||||||
|
|
@ -534,6 +559,7 @@ index 000000000..d6c1a48d5
|
||||||
+#
|
+#
|
||||||
+# Pin controllers
|
+# Pin controllers
|
||||||
+#
|
+#
|
||||||
|
+CONFIG_PINCTRL_MCP23S08=y
|
||||||
+
|
+
|
||||||
+#
|
+#
|
||||||
+# Memory mapped GPIO drivers
|
+# Memory mapped GPIO drivers
|
||||||
|
|
@ -547,6 +573,17 @@ index 000000000..d6c1a48d5
|
||||||
+CONFIG_MTD_MCHP23K256=m
|
+CONFIG_MTD_MCHP23K256=m
|
||||||
+
|
+
|
||||||
+#
|
+#
|
||||||
|
+# Multiple devices driver support
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+CONFIG_MD=y
|
||||||
|
+#
|
||||||
|
+#Device mapper support
|
||||||
|
+#
|
||||||
|
+CONFIG_BLK_DEV_DM=y
|
||||||
|
+CONFIG_DM_CRYPT=y
|
||||||
|
+
|
||||||
|
+#
|
||||||
+# USB GPIO expanders
|
+# USB GPIO expanders
|
||||||
+#
|
+#
|
||||||
+CONFIG_POWER_RESET=y
|
+CONFIG_POWER_RESET=y
|
||||||
|
|
@ -589,6 +626,7 @@ index 000000000..d6c1a48d5
|
||||||
+#
|
+#
|
||||||
+# Camera sensor devices
|
+# Camera sensor devices
|
||||||
+#
|
+#
|
||||||
|
+CONFIG_VIDEO_GC2145=m
|
||||||
+CONFIG_VIDEO_OV5640=m
|
+CONFIG_VIDEO_OV5640=m
|
||||||
+CONFIG_VIDEO_ST_MIPID02=m
|
+CONFIG_VIDEO_ST_MIPID02=m
|
||||||
+
|
+
|
||||||
|
|
@ -608,6 +646,7 @@ index 000000000..d6c1a48d5
|
||||||
+#
|
+#
|
||||||
+CONFIG_DRM_PANEL_ORISETECH_OTM8009A=y
|
+CONFIG_DRM_PANEL_ORISETECH_OTM8009A=y
|
||||||
+CONFIG_DRM_PANEL_RAYDIUM_RM68200=y
|
+CONFIG_DRM_PANEL_RAYDIUM_RM68200=y
|
||||||
|
+CONFIG_DRM_PANEL_ROCKTECH_HX8394=y
|
||||||
+
|
+
|
||||||
+#
|
+#
|
||||||
+# Display Interface Bridges
|
+# Display Interface Bridges
|
||||||
|
|
@ -618,6 +657,7 @@ index 000000000..d6c1a48d5
|
||||||
+#
|
+#
|
||||||
+# Frame buffer hardware drivers
|
+# Frame buffer hardware drivers
|
||||||
+#
|
+#
|
||||||
|
+CONFIG_DRM_SIMPLEDRM=y
|
||||||
+
|
+
|
||||||
+#
|
+#
|
||||||
+# Console display driver support
|
+# Console display driver support
|
||||||
|
|
@ -631,8 +671,13 @@ index 000000000..d6c1a48d5
|
||||||
+CONFIG_BACKLIGHT_GPIO=y
|
+CONFIG_BACKLIGHT_GPIO=y
|
||||||
+
|
+
|
||||||
+#
|
+#
|
||||||
|
+# HD-Audio
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+#
|
||||||
+# STMicroelectronics STM32 SOC audio support
|
+# STMicroelectronics STM32 SOC audio support
|
||||||
+#
|
+#
|
||||||
|
+
|
||||||
+CONFIG_SND_SOC_STM32_SPDIFRX=m
|
+CONFIG_SND_SOC_STM32_SPDIFRX=m
|
||||||
+CONFIG_SND_SOC_STM32_DFSDM=m
|
+CONFIG_SND_SOC_STM32_DFSDM=m
|
||||||
+
|
+
|
||||||
|
|
@ -658,6 +703,12 @@ index 000000000..d6c1a48d5
|
||||||
+#
|
+#
|
||||||
+
|
+
|
||||||
+#
|
+#
|
||||||
|
+# USB UCSI with STM32G07 over I2C
|
||||||
|
+#
|
||||||
|
+CONFIG_TYPEC_UCSI=m
|
||||||
|
+CONFIG_UCSI_STM32G0=m
|
||||||
|
+
|
||||||
|
+#
|
||||||
+# Platform Support
|
+# Platform Support
|
||||||
+#
|
+#
|
||||||
+
|
+
|
||||||
|
|
@ -666,8 +717,15 @@ index 000000000..d6c1a48d5
|
||||||
+#
|
+#
|
||||||
+
|
+
|
||||||
+#
|
+#
|
||||||
|
+# STM32 HSEM
|
||||||
|
+#
|
||||||
|
+CONFIG_HWSPINLOCK=y
|
||||||
|
+CONFIG_HWSPINLOCK_STM32=y
|
||||||
|
+
|
||||||
|
+#
|
||||||
+# Clock Source drivers
|
+# Clock Source drivers
|
||||||
+#
|
+#
|
||||||
|
+CONFIG_CLKSRC_STM32_LP=y
|
||||||
+
|
+
|
||||||
+#
|
+#
|
||||||
+# Regulators
|
+# Regulators
|
||||||
|
|
@ -689,6 +747,20 @@ index 000000000..d6c1a48d5
|
||||||
+CONFIG_RPMSG_TTY=m
|
+CONFIG_RPMSG_TTY=m
|
||||||
+
|
+
|
||||||
+#
|
+#
|
||||||
|
+# NVMEM drivers
|
||||||
|
+#
|
||||||
|
+CONFIG_NVMEM_STM32_ROMEM=y
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+CONFIG_TEE=y
|
||||||
|
+
|
||||||
|
+#
|
||||||
|
+# TEE drivers
|
||||||
|
+#
|
||||||
|
+CONFIG_OPTEE=y
|
||||||
|
+# end of TEE drivers
|
||||||
|
+
|
||||||
|
+#
|
||||||
+# File systems
|
+# File systems
|
||||||
+#
|
+#
|
||||||
+CONFIG_OVERLAY_FS=y
|
+CONFIG_OVERLAY_FS=y
|
||||||
|
|
@ -699,6 +771,20 @@ index 000000000..d6c1a48d5
|
||||||
+#
|
+#
|
||||||
+CONFIG_TMPFS=y
|
+CONFIG_TMPFS=y
|
||||||
+
|
+
|
||||||
|
+# Security options
|
||||||
|
+#
|
||||||
|
+CONFIG_KEYS=y
|
||||||
|
+
|
||||||
|
+#
|
||||||
|
+# Library routines
|
||||||
|
+#
|
||||||
|
+CONFIG_CRC_ITU_T=m
|
||||||
|
+
|
||||||
|
+#
|
||||||
|
+# Default contiguous memory area size:
|
||||||
|
+#
|
||||||
|
+CONFIG_CMA_SIZE_MBYTES=128
|
||||||
|
+
|
||||||
+#
|
+#
|
||||||
+# Kernel hacking
|
+# Kernel hacking
|
||||||
+#
|
+#
|
||||||
|
|
@ -716,7 +802,11 @@ index 000000000..d6c1a48d5
|
||||||
+CONFIG_DEBUG_SECTION_MISMATCH=y
|
+CONFIG_DEBUG_SECTION_MISMATCH=y
|
||||||
+
|
+
|
||||||
+#
|
+#
|
||||||
+# Debug Lockups and Hangs
|
+# Debug Oops, Lockups and Hangs
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+#
|
||||||
|
+# Scheduler Debugging
|
||||||
+#
|
+#
|
||||||
+CONFIG_DEBUG_PREEMPT=y
|
+CONFIG_DEBUG_PREEMPT=y
|
||||||
+
|
+
|
||||||
|
|
@ -724,27 +814,12 @@ index 000000000..d6c1a48d5
|
||||||
+# Runtime Testing
|
+# Runtime Testing
|
||||||
+#
|
+#
|
||||||
+
|
+
|
||||||
+# Security options
|
|
||||||
+#
|
|
||||||
+CONFIG_KEYS=y
|
|
||||||
+
|
|
||||||
+#
|
|
||||||
+# Library routines
|
|
||||||
+#
|
|
||||||
+CONFIG_CRC_ITU_T=m
|
|
||||||
+
|
|
||||||
+#
|
+#
|
||||||
+# STM32 DFSDM
|
+# STM32 DFSDM
|
||||||
+#
|
+#
|
||||||
+CONFIG_SD_ADC_MODULATOR=y
|
+CONFIG_SD_ADC_MODULATOR=y
|
||||||
+
|
+
|
||||||
+#
|
+#
|
||||||
+# STM32 HSEM
|
|
||||||
+#
|
|
||||||
+CONFIG_HWSPINLOCK=y
|
|
||||||
+CONFIG_HWSPINLOCK_STM32=y
|
|
||||||
+
|
|
||||||
+#
|
|
||||||
+# STM32 IPCC
|
+# STM32 IPCC
|
||||||
+#
|
+#
|
||||||
+CONFIG_STM32_IPCC=y
|
+CONFIG_STM32_IPCC=y
|
||||||
|
|
@ -755,28 +830,8 @@ index 000000000..d6c1a48d5
|
||||||
+CONFIG_ARM_SCMI_PROTOCOL=y
|
+CONFIG_ARM_SCMI_PROTOCOL=y
|
||||||
+CONFIG_COMMON_CLK_SCMI=y
|
+CONFIG_COMMON_CLK_SCMI=y
|
||||||
+CONFIG_ARM_SMC_MBOX=y
|
+CONFIG_ARM_SMC_MBOX=y
|
||||||
+
|
+CONFIG_REGULATOR_ARM_SCMI=y
|
||||||
+#
|
+CONFIG_ARM_SCMI_CPUFREQ=y
|
||||||
+# TTY
|
|
||||||
+#
|
|
||||||
+CONFIG_LEGACY_PTY_COUNT=8
|
|
||||||
+
|
|
||||||
+#
|
|
||||||
+# STM32 BSEC NVMEM
|
|
||||||
+#
|
|
||||||
+CONFIG_NVMEM_STM32_ROMEM=y
|
|
||||||
+
|
|
||||||
+#
|
|
||||||
+# RPMSG client sample
|
|
||||||
+#
|
|
||||||
+CONFIG_SAMPLES=y
|
|
||||||
+CONFIG_SAMPLE_RPMSG_CLIENT=m
|
|
||||||
+
|
|
||||||
+#
|
|
||||||
+# REBOOT
|
|
||||||
+#
|
|
||||||
+CONFIG_REBOOT_MODE=y
|
|
||||||
+CONFIG_SYSCON_REBOOT_MODE=y
|
|
||||||
+
|
+
|
||||||
+#
|
+#
|
||||||
+# STM32 CPUIDLE
|
+# STM32 CPUIDLE
|
||||||
|
|
@ -786,46 +841,28 @@ index 000000000..d6c1a48d5
|
||||||
+CONFIG_ARM_CPUIDLE=n
|
+CONFIG_ARM_CPUIDLE=n
|
||||||
+
|
+
|
||||||
+#
|
+#
|
||||||
+# STM32 TIMER
|
+# REBOOT
|
||||||
+#
|
+#
|
||||||
+CONFIG_COUNTER=m
|
+CONFIG_REBOOT_MODE=y
|
||||||
+CONFIG_STM32_TIMER_CNT=m
|
+CONFIG_SYSCON_REBOOT_MODE=y
|
||||||
+
|
+
|
||||||
+#
|
+#
|
||||||
+# STM32 LPTIMER
|
+# RPMSG client sample
|
||||||
+#
|
+#
|
||||||
+CONFIG_MFD_STM32_LPTIMER=y
|
+CONFIG_SAMPLES=y
|
||||||
+CONFIG_STM32_LPTIMER_CNT=m
|
+CONFIG_SAMPLE_RPMSG_CLIENT=m
|
||||||
+CONFIG_CLKSRC_STM32_LP=y
|
|
||||||
+
|
|
||||||
+#
|
|
||||||
+# TEE drivers
|
|
||||||
+#
|
|
||||||
+CONFIG_TEE=y
|
|
||||||
+CONFIG_OPTEE=y
|
|
||||||
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
|
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
|
||||||
index a611b0c1e..abf1b17cb 100644
|
index 33572998d..afb97c505 100644
|
||||||
--- a/arch/arm/configs/multi_v7_defconfig
|
--- a/arch/arm/configs/multi_v7_defconfig
|
||||||
+++ b/arch/arm/configs/multi_v7_defconfig
|
+++ b/arch/arm/configs/multi_v7_defconfig
|
||||||
@@ -829,6 +829,8 @@ CONFIG_USB_CONFIGFS_F_HID=y
|
@@ -646,6 +646,7 @@ CONFIG_V4L_PLATFORM_DRIVERS=y
|
||||||
CONFIG_USB_CONFIGFS_F_UVC=y
|
CONFIG_VIDEO_MMP_CAMERA=m
|
||||||
CONFIG_USB_CONFIGFS_F_PRINTER=y
|
CONFIG_VIDEO_ASPEED=m
|
||||||
CONFIG_USB_ETH=m
|
CONFIG_VIDEO_STM32_DCMI=m
|
||||||
+CONFIG_TYPEC=m
|
+CONFIG_VIDEO_STM32_DCMIPP=m
|
||||||
+CONFIG_TYPEC_STUSB160X=m
|
CONFIG_VIDEO_RENESAS_CEU=m
|
||||||
CONFIG_MMC=y
|
CONFIG_VIDEO_SAMSUNG_EXYNOS4_IS=m
|
||||||
CONFIG_MMC_BLOCK_MINORS=16
|
CONFIG_VIDEO_S5P_FIMC=m
|
||||||
CONFIG_MMC_ARMMMCI=y
|
|
||||||
@@ -1133,6 +1135,9 @@ CONFIG_CRYPTO_DEV_ATMEL_AES=m
|
|
||||||
CONFIG_CRYPTO_DEV_ATMEL_TDES=m
|
|
||||||
CONFIG_CRYPTO_DEV_ATMEL_SHA=m
|
|
||||||
CONFIG_CRYPTO_DEV_ROCKCHIP=m
|
|
||||||
+CONFIG_CRYPTO_DEV_STM32_CRC=m
|
|
||||||
+CONFIG_CRYPTO_DEV_STM32_HASH=m
|
|
||||||
+CONFIG_CRYPTO_DEV_STM32_CRYP=m
|
|
||||||
CONFIG_CMA_SIZE_MBYTES=64
|
|
||||||
CONFIG_PRINTK_TIME=y
|
|
||||||
CONFIG_MAGIC_SYSRQ=y
|
|
||||||
--
|
--
|
||||||
2.17.1
|
2.25.1
|
||||||
|
|
||||||
|
|
@ -20,3 +20,6 @@ CONFIG_INPUT_UINPUT=m
|
||||||
CONFIG_USBIP_CORE=m
|
CONFIG_USBIP_CORE=m
|
||||||
CONFIG_USBIP_HOST=m
|
CONFIG_USBIP_HOST=m
|
||||||
# CONFIG_USBIP_DEBUG is not set
|
# CONFIG_USBIP_DEBUG is not set
|
||||||
|
|
||||||
|
# needed for lttng-modules
|
||||||
|
CONFIG_KPROBES=y
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
# CONFIG_SMP is not set
|
||||||
|
|
@ -1,14 +1,15 @@
|
||||||
Compilation of kernel:
|
Compilation of kernel:
|
||||||
1. Pre-requisite
|
1. Pre-requisite
|
||||||
2. Initialise cross-compilation via SDK
|
2. Initialize cross-compilation via SDK
|
||||||
3. Prepare kernel source code
|
3. Prepare kernel source code
|
||||||
4. Manage the kernel source code
|
4. Manage kernel source code
|
||||||
5. Configure kernel source code
|
5. Configure kernel source code
|
||||||
6. Compile kernel source code
|
6. Compile kernel source code
|
||||||
7. Update software on board
|
7. Update software on board
|
||||||
|
|
||||||
1. Pre-requisite:
|
----------------
|
||||||
-----------------
|
1. Pre-requisite
|
||||||
|
----------------
|
||||||
OpenSTLinux SDK must be installed.
|
OpenSTLinux SDK must be installed.
|
||||||
|
|
||||||
For kernel build, you need to install:
|
For kernel build, you need to install:
|
||||||
|
|
@ -32,8 +33,9 @@ If you have never configured your git configuration, run the following commands:
|
||||||
$ git config --global user.name "your_name"
|
$ git config --global user.name "your_name"
|
||||||
$ git config --global user.email "your_email@example.com"
|
$ git config --global user.email "your_email@example.com"
|
||||||
|
|
||||||
2. Initialise cross-compilation via SDK:
|
---------------------------------------
|
||||||
----------------------------------------
|
2. Initialize cross-compilation via SDK
|
||||||
|
---------------------------------------
|
||||||
Source SDK environment:
|
Source SDK environment:
|
||||||
$ source <path to SDK>/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi
|
$ source <path to SDK>/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi
|
||||||
|
|
||||||
|
|
@ -45,27 +47,38 @@ run the following command:
|
||||||
Warning: the environment is valid only on the shell session where you have
|
Warning: the environment is valid only on the shell session where you have
|
||||||
sourced the SDK environment.
|
sourced the SDK environment.
|
||||||
|
|
||||||
3. Prepare kernel source:
|
------------------------
|
||||||
-------------------------
|
3. Prepare kernel source
|
||||||
If you have the tarball and the list of patches, then you must extract the
|
------------------------
|
||||||
tarball and apply the patches.
|
If not already done, extract the sources from Developer Package tarball, for example:
|
||||||
$> tar xfJ ##LINUX_TARNAME##.tar.xz
|
$ tar xfJ en.SOURCES-stm32mp1-*.tar.xz
|
||||||
A new directory containing kernel standard source code will be created, go into it:
|
|
||||||
$> cd ##LINUX_TARNAME##
|
|
||||||
|
|
||||||
NB: if you like to have a git management of the code, see section 4 [Manage the
|
In the kernel source directory (sources/*/##BP##-##PR##),
|
||||||
kernel source code]
|
you have one kernel source tarball, the patches and one Makefile:
|
||||||
if there is some patch, please apply it on source code
|
- ##LINUX_TARNAME##.tar.xz
|
||||||
|
- 00*.patch
|
||||||
|
- Makefile.sdk
|
||||||
|
|
||||||
|
If you would like to have a git management for the source code move to
|
||||||
|
to section 4 [Management of kernel source code with GIT].
|
||||||
|
|
||||||
|
Otherwise, to manage kernel source code without git, you must extract the
|
||||||
|
tarball now and apply the patch:
|
||||||
|
|
||||||
|
$> tar xfJ ##LINUX_TARNAME##.tar.xz
|
||||||
|
$> cd ##LINUX_TARNAME##
|
||||||
$> for p in `ls -1 ../*.patch`; do patch -p1 < $p; done
|
$> for p in `ls -1 ../*.patch`; do patch -p1 < $p; done
|
||||||
|
|
||||||
4. Manage the kernel source code:
|
You can now move to section 5 [Configure kernel source code].
|
||||||
---------------------------------
|
|
||||||
|
-------------------------------------
|
||||||
|
4. Manage kernel source code with GIT
|
||||||
|
-------------------------------------
|
||||||
If you like to have a better management of change made on kernel source, you
|
If you like to have a better management of change made on kernel source, you
|
||||||
have 3 solutions to use git.
|
have 3 solutions to use git.
|
||||||
|
|
||||||
4.1 Get STMicroelectronics kernel source code from GitHub
|
4.1 Get STMicroelectronics kernel source code from GitHub
|
||||||
|
---------------------------------------------------------
|
||||||
|
|
||||||
URL: https://github.com/STMicroelectronics/linux.git
|
URL: https://github.com/STMicroelectronics/linux.git
|
||||||
Branch: ##ARCHIVER_ST_BRANCH##
|
Branch: ##ARCHIVER_ST_BRANCH##
|
||||||
Revision: ##ARCHIVER_ST_REVISION##
|
Revision: ##ARCHIVER_ST_REVISION##
|
||||||
|
|
@ -74,31 +87,29 @@ have 3 solutions to use git.
|
||||||
$ git checkout -b WORKING ##ARCHIVER_ST_REVISION##
|
$ git checkout -b WORKING ##ARCHIVER_ST_REVISION##
|
||||||
|
|
||||||
4.2 Create Git from tarball
|
4.2 Create Git from tarball
|
||||||
|
---------------------------
|
||||||
* With the kernel source code extracted in the section 3 [Prepare kernel source]
|
|
||||||
$ cd <directory to kernel source code>
|
$ cd <directory to kernel source code>
|
||||||
$ test -d .git || git init . && git add . && git commit -m "new kernel" && git gc
|
$ test -d .git || git init . && git add . && git commit -m "new kernel" && git gc
|
||||||
$ git checkout -b WORKING
|
$ git checkout -b WORKING
|
||||||
Apply patches:
|
Apply patches:
|
||||||
$ for p in `ls -1 <path to patch>/*.patch`; do git am $p; done
|
$ for p in `ls -1 ../*.patch`; do git am $p; done
|
||||||
NB: this is the fastest way to get your kernel source code ready for development
|
NB: this is the fastest way to get your kernel source code ready for development
|
||||||
|
|
||||||
4.3 Get Git from community and apply STMicroelectronics patches
|
4.3 Get Git from Linux kernel community and apply STMicroelectronics patches
|
||||||
|
---------------------------------------------------------------
|
||||||
* With the kernel source code from the Linux kernel git repositories:
|
|
||||||
URL: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git
|
URL: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git
|
||||||
Branch: ##ARCHIVER_COMMUNITY_BRANCH##
|
Branch: ##ARCHIVER_COMMUNITY_BRANCH##
|
||||||
Revision: ##ARCHIVER_COMMUNITY_REVISION##
|
Revision: ##ARCHIVER_COMMUNITY_REVISION##
|
||||||
|
|
||||||
$ git clone https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git
|
$ git clone https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git
|
||||||
$ cd <kernel source>
|
$ cd linux-stable
|
||||||
$ git checkout -b WORKING ##ARCHIVER_COMMUNITY_REVISION##
|
$ git checkout -b WORKING ##ARCHIVER_COMMUNITY_REVISION##
|
||||||
$ for p in `ls -1 <path to patch>/*.patch`; do git am $p; done
|
$ for p in `ls -1 <path to patch>/*.patch`; do git am $p; done
|
||||||
NB: this way is slightly slower than the tarball extraction but you get
|
NB: this way is slightly slower than the tarball extraction but you get
|
||||||
advantage of all git history.
|
advantage of all git history.
|
||||||
|
|
||||||
4.2 Predefined kernel version vs auto-generated kernel version:
|
4.4 Predefined kernel version vs auto-generated kernel version
|
||||||
---------------------------------------------------------------
|
--------------------------------------------------------------
|
||||||
If you are using git for managing your source code, kernel makefile get the SHA1
|
If you are using git for managing your source code, kernel makefile get the SHA1
|
||||||
of current git and add it to kernel version number generated.
|
of current git and add it to kernel version number generated.
|
||||||
ex.: 4.9.23-g3e866b0 (kernel version + SHA1 of current git commit)
|
ex.: 4.9.23-g3e866b0 (kernel version + SHA1 of current git commit)
|
||||||
|
|
@ -112,8 +123,9 @@ This configuration allows to build new kernel from modified source code without
|
||||||
any issue when using the new kernel binary on target regarding any external
|
any issue when using the new kernel binary on target regarding any external
|
||||||
kernel module already available on target rootfs (as built without scmversion).
|
kernel module already available on target rootfs (as built without scmversion).
|
||||||
|
|
||||||
5. Configure kernel source code:
|
-------------------------------
|
||||||
--------------------------------
|
5. Configure kernel source code
|
||||||
|
-------------------------------
|
||||||
There are two methods to configure and compile kernel source code:
|
There are two methods to configure and compile kernel source code:
|
||||||
- Inside kernel source tree directory
|
- Inside kernel source tree directory
|
||||||
- Outside kernel source tree in a build directory
|
- Outside kernel source tree in a build directory
|
||||||
|
|
@ -167,8 +179,9 @@ NB: Two types of fragments are provided:
|
||||||
Please pay special attention to the naming of your optional fragments to
|
Please pay special attention to the naming of your optional fragments to
|
||||||
ensure you select the right features.
|
ensure you select the right features.
|
||||||
|
|
||||||
6. Compile kernel source code:
|
-----------------------------
|
||||||
------------------------------
|
6. Compile kernel source code
|
||||||
|
-----------------------------
|
||||||
You MUST compile from the directory on which the configuration has been done (i.e.
|
You MUST compile from the directory on which the configuration has been done (i.e.
|
||||||
the directory which contains the '.config' file).
|
the directory which contains the '.config' file).
|
||||||
|
|
||||||
|
|
@ -217,20 +230,20 @@ Generated files are :
|
||||||
#> $PWD/install_artifact/boot/uImage
|
#> $PWD/install_artifact/boot/uImage
|
||||||
#> $PWD/install_artifact/boot/<stm32-boards>.dtb
|
#> $PWD/install_artifact/boot/<stm32-boards>.dtb
|
||||||
|
|
||||||
|
---------------------------
|
||||||
|
7. Update software on board
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
7.1 Partitioning of binaries
|
||||||
7. Update software on board:
|
|
||||||
----------------------------
|
----------------------------
|
||||||
7.1. Partitioning of binaries:
|
|
||||||
------------------------------
|
|
||||||
* Bootfs:
|
* Bootfs:
|
||||||
Bootfs contains the kernel and the devicetree.
|
Bootfs contains the kernel and the devicetree.
|
||||||
* Rootfs:
|
* Rootfs:
|
||||||
Rootfs contains the external kernel modules.
|
Rootfs contains the external kernel modules.
|
||||||
Please refer to User guide for more details.
|
Please refer to User guide for more details.
|
||||||
|
|
||||||
7.2. Update via network:
|
7.2 Update via network
|
||||||
------------------------
|
----------------------
|
||||||
* kernel + devicetree
|
* kernel + devicetree
|
||||||
$ cd <path to install_artifact dir>/install_artifact
|
$ cd <path to install_artifact dir>/install_artifact
|
||||||
if bootfs are not monted on target, mount it
|
if bootfs are not monted on target, mount it
|
||||||
|
|
@ -258,8 +271,8 @@ Please refer to User guide for more details.
|
||||||
Reboot the board in order to take update into account
|
Reboot the board in order to take update into account
|
||||||
$ ssh root@<ip of board> reboot
|
$ ssh root@<ip of board> reboot
|
||||||
|
|
||||||
7.3. Update via SDCARD on your Linux PC:
|
7.3 Update via SDCARD on your Linux PC
|
||||||
----------------------------------------
|
--------------------------------------
|
||||||
* kernel + devicetree
|
* kernel + devicetree
|
||||||
$ cd <path to install_artifact dir>/install_artifact
|
$ cd <path to install_artifact dir>/install_artifact
|
||||||
Verify sdcard are mounted on your Linux PC: /media/$USER/bootfs
|
Verify sdcard are mounted on your Linux PC: /media/$USER/bootfs
|
||||||
|
|
@ -290,8 +303,8 @@ Please refer to User guide for more details.
|
||||||
Reboot the board in order to take update into account
|
Reboot the board in order to take update into account
|
||||||
$ ssh root@<ip of board> reboot
|
$ ssh root@<ip of board> reboot
|
||||||
|
|
||||||
7.4. Update via SDCARD on your BOARD (via U-Boot):
|
7.4 Update via SDCARD on your BOARD (via U-Boot)
|
||||||
--------------------------------------------------
|
------------------------------------------------
|
||||||
You MUST configure first, via U-Boot, the board into usb mass storage:
|
You MUST configure first, via U-Boot, the board into usb mass storage:
|
||||||
* Plug the SDCARD on Board.
|
* Plug the SDCARD on Board.
|
||||||
* Start the board and stop on U-boot shell:
|
* Start the board and stop on U-boot shell:
|
||||||
|
|
@ -342,8 +355,9 @@ For USB Disk: ums 0 usb 0
|
||||||
Reboot the board in order to take update into account
|
Reboot the board in order to take update into account
|
||||||
$on board> reboot
|
$on board> reboot
|
||||||
|
|
||||||
8. Useful information:
|
---------------------
|
||||||
----------------------
|
8. Useful information
|
||||||
|
---------------------
|
||||||
* How to re-generate kernel database on board:
|
* How to re-generate kernel database on board:
|
||||||
$on board> depmod -a
|
$on board> depmod -a
|
||||||
(don't forget to synchronize the filesystem before to reboot)
|
(don't forget to synchronize the filesystem before to reboot)
|
||||||
|
|
|
||||||
|
|
@ -6,42 +6,42 @@ LIC_FILES_CHKSUM = "file://COPYING;md5=6bc538ed5bd9a7fc9398086aedcd7e46"
|
||||||
|
|
||||||
include linux-stm32mp.inc
|
include linux-stm32mp.inc
|
||||||
|
|
||||||
LINUX_VERSION = "5.10"
|
LINUX_VERSION = "5.15"
|
||||||
LINUX_SUBVERSION = "61"
|
LINUX_SUBVERSION = "24"
|
||||||
LINUX_TARNAME = "linux-${LINUX_VERSION}.${LINUX_SUBVERSION}"
|
LINUX_TARNAME = "linux-${LINUX_VERSION}.${LINUX_SUBVERSION}"
|
||||||
SRC_URI = "https://cdn.kernel.org/pub/linux/kernel/v5.x/${LINUX_TARNAME}.tar.xz;name=kernel"
|
SRC_URI = "https://cdn.kernel.org/pub/linux/kernel/v5.x/${LINUX_TARNAME}.tar.xz;name=kernel"
|
||||||
#SRC_URI = "https://git.kernel.org/torvalds/t/linux-${LINUX_VERSION}-${LINUX_SUBVERSION}.tar.gz;name=kernel"
|
#SRC_URI = "https://git.kernel.org/torvalds/t/linux-${LINUX_VERSION}-${LINUX_SUBVERSION}.tar.gz;name=kernel"
|
||||||
|
|
||||||
SRC_URI[kernel.sha256sum] = "82eae38cc5cd11dd6aaac91c02ff0d006c7bafd6d4cf5c6a791930820a3a91d1"
|
|
||||||
|
SRC_URI[kernel.sha256sum] = "f496eb03c88731540d483837f919c083148875a7b400468237f0217b5e5ca97f"
|
||||||
|
|
||||||
SRC_URI += " \
|
SRC_URI += " \
|
||||||
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0001-ARM-5.10.61-stm32mp1-r2-MACHINE.patch \
|
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0001-ARM-5.15.24-stm32mp1-r1-MACHINE.patch \
|
||||||
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0002-ARM-5.10.61-stm32mp1-r2-CLOCK.patch \
|
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0002-ARM-5.15.24-stm32mp1-r1-CLOCK.patch \
|
||||||
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0003-ARM-5.10.61-stm32mp1-r2-CPUFREQ.patch \
|
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0003-ARM-5.15.24-stm32mp1-r1-CPUFREQ.patch \
|
||||||
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0004-ARM-5.10.61-stm32mp1-r2-CRYPTO.patch \
|
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0004-ARM-5.15.24-stm32mp1-r1-CRYPTO.patch \
|
||||||
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0005-ARM-5.10.61-stm32mp1-r2-DMA.patch \
|
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0005-ARM-5.15.24-stm32mp1-r1-DMA.patch \
|
||||||
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0006-ARM-5.10.61-stm32mp1-r2-DRM.patch \
|
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0006-ARM-5.15.24-stm32mp1-r1-DRM.patch \
|
||||||
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0007-ARM-5.10.61-stm32mp1-r2-HWSPINLOCK.patch \
|
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0007-ARM-5.15.24-stm32mp1-r1-HWSPINLOCK.patch \
|
||||||
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0008-ARM-5.10.61-stm32mp1-r2-I2C-IIO-IRQCHIP.patch \
|
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0008-ARM-5.15.24-stm32mp1-r1-I2C-IIO-IRQCHIP.patch \
|
||||||
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0009-ARM-5.10.61-stm32mp1-r2-MAILBOX-REMOTEPROC-RPMSG.patch \
|
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0009-ARM-5.15.24-stm32mp1-r1-REMOTEPROC-RPMSG.patch \
|
||||||
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0010-ARM-5.10.61-stm32mp1-r2-MEDIA-SOC-THERMAL.patch \
|
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0010-ARM-5.15.24-stm32mp1-r1-MISC-MEDIA-SOC-THERMAL.patch \
|
||||||
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0011-ARM-5.10.61-stm32mp1-r2-MFD.patch \
|
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0011-ARM-5.15.24-stm32mp1-r1-MFD.patch \
|
||||||
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0012-ARM-5.10.61-stm32mp1-r2-MMC.patch \
|
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0012-ARM-5.15.24-stm32mp1-r1-MMC.patch \
|
||||||
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0013-ARM-5.10.61-stm32mp1-r2-NET-TTY.patch \
|
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0013-ARM-5.15.24-stm32mp1-r1-NET-TTY.patch \
|
||||||
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0014-ARM-5.10.61-stm32mp1-r2-PERF.patch \
|
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0014-ARM-5.15.24-stm32mp1-r1-PERF.patch \
|
||||||
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0015-ARM-5.10.61-stm32mp1-r2-PHY-USB.patch \
|
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0015-ARM-5.15.24-stm32mp1-r1-PHY-USB.patch \
|
||||||
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0016-ARM-5.10.61-stm32mp1-r2-PINCTRL-REGULATOR-SPI.patch \
|
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0016-ARM-5.15.24-stm32mp1-r1-PINCTRL-REGULATOR-SPI.patch \
|
||||||
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0017-ARM-5.10.61-stm32mp1-r2-RESET-RTC-WATCHDOG.patch \
|
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0017-ARM-5.15.24-stm32mp1-r1-RESET-RTC.patch \
|
||||||
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0018-ARM-5.10.61-stm32mp1-r2-SCMI.patch \
|
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0018-ARM-5.15.24-stm32mp1-r1-SCMI.patch \
|
||||||
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0019-ARM-5.10.61-stm32mp1-r2-SOUND.patch \
|
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0019-ARM-5.15.24-stm32mp1-r1-SOUND.patch \
|
||||||
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0020-ARM-5.10.61-stm32mp1-r2-MISC.patch \
|
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0020-ARM-5.15.24-stm32mp1-r1-CPUIDLE-POWER.patch \
|
||||||
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0021-ARM-5.10.61-stm32mp1-r2-CPUIDLE-POWER.patch \
|
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0021-ARM-5.15.24-stm32mp1-r1-DEVICETREE.patch \
|
||||||
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0022-ARM-5.10.61-stm32mp1-r2-DEVICETREE.patch \
|
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0022-ARM-5.15.24-stm32mp1-r1-CONFIG.patch \
|
||||||
file://${LINUX_VERSION}/${LINUX_VERSION}.${LINUX_SUBVERSION}/0023-ARM-5.10.61-stm32mp1-r2-CONFIG.patch \
|
|
||||||
"
|
"
|
||||||
|
|
||||||
LINUX_TARGET = "stm32mp"
|
LINUX_TARGET = "stm32mp1"
|
||||||
LINUX_RELEASE = "r2"
|
LINUX_RELEASE = "r1"
|
||||||
|
|
||||||
PV = "${LINUX_VERSION}.${LINUX_SUBVERSION}-${LINUX_TARGET}-${LINUX_RELEASE}"
|
PV = "${LINUX_VERSION}.${LINUX_SUBVERSION}-${LINUX_TARGET}-${LINUX_RELEASE}"
|
||||||
|
|
||||||
|
|
@ -52,6 +52,7 @@ ARCHIVER_COMMUNITY_REVISION = "v${LINUX_VERSION}.${LINUX_SUBVERSION}"
|
||||||
|
|
||||||
S = "${WORKDIR}/linux-${LINUX_VERSION}.${LINUX_SUBVERSION}"
|
S = "${WORKDIR}/linux-${LINUX_VERSION}.${LINUX_SUBVERSION}"
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------
|
# ---------------------------------
|
||||||
# Configure devupstream class usage
|
# Configure devupstream class usage
|
||||||
# ---------------------------------
|
# ---------------------------------
|
||||||
|
|
@ -81,15 +82,18 @@ KERNEL_CONFIG_FRAGMENTS += "${@bb.utils.contains('KERNEL_DEFCONFIG', 'defconfig'
|
||||||
KERNEL_CONFIG_FRAGMENTS += "${@bb.utils.contains('DISTRO_FEATURES', 'systemd', '${WORKDIR}/fragments/${LINUX_VERSION}/fragment-03-systemd.config', '', d)} "
|
KERNEL_CONFIG_FRAGMENTS += "${@bb.utils.contains('DISTRO_FEATURES', 'systemd', '${WORKDIR}/fragments/${LINUX_VERSION}/fragment-03-systemd.config', '', d)} "
|
||||||
KERNEL_CONFIG_FRAGMENTS += "${WORKDIR}/fragments/${LINUX_VERSION}/fragment-04-modules.config"
|
KERNEL_CONFIG_FRAGMENTS += "${WORKDIR}/fragments/${LINUX_VERSION}/fragment-04-modules.config"
|
||||||
KERNEL_CONFIG_FRAGMENTS += "${@oe.utils.ifelse(d.getVar('KERNEL_SIGN_ENABLE') == '1', '${WORKDIR}/fragments/${LINUX_VERSION}/fragment-05-signature.config','')} "
|
KERNEL_CONFIG_FRAGMENTS += "${@oe.utils.ifelse(d.getVar('KERNEL_SIGN_ENABLE') == '1', '${WORKDIR}/fragments/${LINUX_VERSION}/fragment-05-signature.config','')} "
|
||||||
|
KERNEL_CONFIG_FRAGMENTS += "${@bb.utils.contains('MACHINE_FEATURES', 'nosmp', '${WORKDIR}/fragments/${LINUX_VERSION}/fragment-06-smp.config', '', d)} "
|
||||||
|
|
||||||
SRC_URI += "file://${LINUX_VERSION}/fragment-03-systemd.config;subdir=fragments"
|
SRC_URI += "file://${LINUX_VERSION}/fragment-03-systemd.config;subdir=fragments"
|
||||||
SRC_URI += "file://${LINUX_VERSION}/fragment-04-modules.config;subdir=fragments"
|
SRC_URI += "file://${LINUX_VERSION}/fragment-04-modules.config;subdir=fragments"
|
||||||
SRC_URI += "file://${LINUX_VERSION}/fragment-05-signature.config;subdir=fragments"
|
SRC_URI += "file://${LINUX_VERSION}/fragment-05-signature.config;subdir=fragments"
|
||||||
|
SRC_URI += "file://${LINUX_VERSION}/fragment-06-smp.config;subdir=fragments"
|
||||||
|
|
||||||
# Don't forget to add/del for devupstream
|
# Don't forget to add/del for devupstream
|
||||||
SRC_URI:class-devupstream += "file://${LINUX_VERSION}/fragment-03-systemd.config;subdir=fragments"
|
SRC_URI:class-devupstream += "file://${LINUX_VERSION}/fragment-03-systemd.config;subdir=fragments"
|
||||||
SRC_URI:class-devupstream += "file://${LINUX_VERSION}/fragment-04-modules.config;subdir=fragments"
|
SRC_URI:class-devupstream += "file://${LINUX_VERSION}/fragment-04-modules.config;subdir=fragments"
|
||||||
SRC_URI:class-devupstream += "file://${LINUX_VERSION}/fragment-05-signature.config;subdir=fragments"
|
SRC_URI:class-devupstream += "file://${LINUX_VERSION}/fragment-05-signature.config;subdir=fragments"
|
||||||
|
SRC_URI:class-devupstream += "file://${LINUX_VERSION}/fragment-06-smp.config;subdir=fragments"
|
||||||
|
|
||||||
# -------------------------------------------------------------
|
# -------------------------------------------------------------
|
||||||
# Kernel Args
|
# Kernel Args
|
||||||
Loading…
Reference in New Issue