KERNEL: 5.15-stm32mp1-r1
Signed-off-by: Christophe Priouzeau <christophe.priouzeau@foss.st.com> Change-Id: I0b997edf47d41b8633c5a58861ff2cf04caad2f0
This commit is contained in:
1 parent
48b49d3e27
commit
9825958fd6
44 files changed
+40991
-22512
No files matched your search
@@ -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.
|
||||||
#
|
#
|
||||||
|
|||||||
-39
@@ -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
|
|
||||||
|
|
||||||
-1799
File diff suppressed because it is too large.
Load diff
-1596
File diff suppressed because it is too large.
Load diff
-1468
File diff suppressed because it is too large.
Load diff
-2145
File diff suppressed because it is too large.
Load diff
-3099
File diff suppressed because it is too large.
Load diff
-1441
File diff suppressed because it is too large.
Load diff
-40
@@ -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
|
|
||||||
|
|
||||||
-1527
File diff suppressed because it is too large.
Load diff
-2218
File diff suppressed because it is too large.
Load diff
-652
@@ -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
|
|
||||||
|
|
||||||
-131
@@ -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
|
|
||||||
|
|
||||||
-717
@@ -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
|
|
||||||
|
|
||||||
-31
@@ -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
|
|
||||||
|
|
||||||
-701
@@ -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
|
|
||||||
|
|
||||||
+124
@@ -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
|
||||||
|
|
||||||
+5180
File diff suppressed because it is too large.
Load diff
+24
-23
@@ -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
|
||||||
|
|
||||||
+1539
File diff suppressed because it is too large.
Load diff
+587
-602
File diff suppressed because it is too large.
Load diff
+2538
File diff suppressed because it is too large.
Load diff
+96
-17
@@ -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>
|
||||||
---
|
---
|
||||||
|
.../devicetree/bindings/hwlock/hwlock.txt | 27 +++++--
|
||||||
|
.../bindings/hwlock/st,stm32-hwspinlock.yaml | 4 +-
|
||||||
Documentation/locking/hwspinlock.rst | 10 ++-
|
Documentation/locking/hwspinlock.rst | 10 ++-
|
||||||
drivers/hwspinlock/hwspinlock_core.c | 80 +++++++++++++++++++-----
|
drivers/hwspinlock/hwspinlock_core.c | 80 +++++++++++++++----
|
||||||
drivers/hwspinlock/hwspinlock_internal.h | 2 +
|
drivers/hwspinlock/hwspinlock_internal.h | 2 +
|
||||||
drivers/hwspinlock/stm32_hwspinlock.c | 60 +++++++++++-------
|
drivers/hwspinlock/stm32_hwspinlock.c | 58 +++++++++-----
|
||||||
4 files changed, 110 insertions(+), 42 deletions(-)
|
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
|
||||||
|
|
||||||
+2996
File diff suppressed because it is too large.
Load diff
+5789
File diff suppressed because it is too large.
Load diff
+9043
File diff suppressed because it is too large.
Load diff
+129
-27
@@ -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>
|
||||||
---
|
---
|
||||||
|
.../bindings/mfd/st,stm32-lptimer.yaml | 3 +
|
||||||
|
.../bindings/mfd/st,stm32mp1-pwr.txt | 57 +++
|
||||||
drivers/mfd/Kconfig | 10 +
|
drivers/mfd/Kconfig | 10 +
|
||||||
drivers/mfd/Makefile | 1 +
|
drivers/mfd/Makefile | 1 +
|
||||||
drivers/mfd/stm32-pwr.c | 402 +++++++++++++++++++++++++++++++
|
drivers/mfd/stm32-pwr.c | 423 ++++++++++++++++++
|
||||||
drivers/mfd/stmfx.c | 2 -
|
drivers/mfd/stmfx.c | 2 -
|
||||||
drivers/mfd/stpmic1.c | 6 +
|
drivers/mfd/stpmic1.c | 6 +
|
||||||
drivers/mfd/wm8994-core.c | 6 +
|
drivers/mfd/wm8994-core.c | 6 +
|
||||||
include/linux/mfd/stm32-timers.h | 1 +
|
include/linux/mfd/stm32-timers.h | 1 +
|
||||||
7 files changed, 426 insertions(+), 2 deletions(-)
|
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
|
||||||
|
|
||||||
+114
@@ -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
|
||||||
|
|
||||||
+625
-876
File diff suppressed because it is too large.
Load diff
+82
-19
@@ -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
|
||||||
|
|
||||||
+2640
File diff suppressed because it is too large.
Load diff
+1703
File diff suppressed because it is too large.
Load diff
+878
@@ -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
|
||||||
|
|
||||||
+1045
File diff suppressed because it is too large.
Load diff
+299
@@ -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
|
||||||
|
|
||||||
+411
@@ -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
|
||||||
|
|
||||||
+4909
-3174
File diff suppressed because it is too large.
Load diff
+133
-96
@@ -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
|
||||||
|
|
||||||
File renamed without changes.
+3
@@ -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
|
||||||
File renamed without changes.
@@ -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)
|
||||||
|
|||||||
+32
-28
@@ -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
|
||||||
Reference in new issue
Block a user