1068 lines
31 KiB
Diff
1068 lines
31 KiB
Diff
From 64b878ba46af224fa2c1d0bf7c784927e1890f3a Mon Sep 17 00:00:00 2001
|
|
From: Romuald JEANNE <romuald.jeanne@st.com>
|
|
Date: Mon, 10 Dec 2018 15:53:08 +0100
|
|
Subject: [PATCH 43/52] ARM: stm32mp1-r0-rc3: MISC
|
|
|
|
---
|
|
.../devicetree/bindings/soc/stm32/stm32_hdp.txt | 39 ++++
|
|
arch/arm/Kconfig.debug | 30 ++-
|
|
arch/arm/boot/dts/Makefile | 2 +
|
|
arch/arm/include/debug/stm32.S | 19 +-
|
|
drivers/hwspinlock/hwspinlock_core.c | 15 +-
|
|
drivers/hwspinlock/stm32_hwspinlock.c | 7 +
|
|
drivers/hwtracing/coresight/coresight-stm.c | 58 ++++-
|
|
drivers/soc/st/Kconfig | 8 +
|
|
drivers/soc/st/Makefile | 1 +
|
|
drivers/soc/st/stm32_hdp.c | 242 +++++++++++++++++++++
|
|
drivers/spi/spi-stm32-qspi.c | 192 +++++++++++++++-
|
|
include/dt-bindings/soc/stm32-hdp.h | 108 +++++++++
|
|
12 files changed, 694 insertions(+), 27 deletions(-)
|
|
create mode 100644 Documentation/devicetree/bindings/soc/stm32/stm32_hdp.txt
|
|
create mode 100644 drivers/soc/st/stm32_hdp.c
|
|
create mode 100644 include/dt-bindings/soc/stm32-hdp.h
|
|
|
|
diff --git a/Documentation/devicetree/bindings/soc/stm32/stm32_hdp.txt b/Documentation/devicetree/bindings/soc/stm32/stm32_hdp.txt
|
|
new file mode 100644
|
|
index 0000000..e2bd82f
|
|
--- /dev/null
|
|
+++ b/Documentation/devicetree/bindings/soc/stm32/stm32_hdp.txt
|
|
@@ -0,0 +1,39 @@
|
|
+STM32 - STM32MP1- HDP Pin configuration for STM32MP1
|
|
+=======================================================
|
|
+
|
|
+The Hardware Debug Port (HDP) allows the observation of internal signals. By using multiplexers,
|
|
+up to 16 signals for each of 8-bit output can be observed.
|
|
+
|
|
+Required Properties:
|
|
+
|
|
+ - compatible: Must be "st,stm32mp1-hdp"
|
|
+ - muxing-hdp: Indicates for each HDP pins selected which HDP output among the 16 available signals you want
|
|
+
|
|
+For each HDP pins you can select one of 16 signals which will be described in file : include/dt-bindings/soc/stm32-hdp.h
|
|
+
|
|
+Example
|
|
+-------
|
|
+
|
|
+In common dtsi file:
|
|
+
|
|
+hdp: hdp@5002a000 {
|
|
+ compatible = "st,stm32mp1-hdp";
|
|
+ reg = <0x5002a000 0x400>;
|
|
+ clocks = <&rcc HDP>;
|
|
+ clock-names = "hdp";
|
|
+};
|
|
+
|
|
+In board-specific file:
|
|
+
|
|
+In this example I've selected HDP0, HDP6 and HDP7, and for HDP0 the output signal is HDP0_GPOVAL_0,
|
|
+for HDP6 is HDP6_GPOVAL_6, and for HDP7 is HDP7_GPOVAL_7.
|
|
+
|
|
+&hdp {
|
|
+ pinctrl-names = "default", "sleep";
|
|
+ pinctrl-0 = <&hdp0_pins_a &hdp6_pins_a &hdp7_pins_a>;
|
|
+ pinctrl-1 = <&hdp0_pins_sleep_a &hdp6_pins_sleep_a &hdp7_pins_sleep_a>;
|
|
+
|
|
+ muxing-hdp = <(STM32_HDP(0, HDP0_GPOVAL_0) |
|
|
+ STM32_HDP(6, HDP6_GPOVAL_6) |
|
|
+ STM32_HDP(7, HDP7_GPOVAL_7))>;
|
|
+};
|
|
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
|
|
index d5ec6c3..88849c1 100644
|
|
--- a/arch/arm/Kconfig.debug
|
|
+++ b/arch/arm/Kconfig.debug
|
|
@@ -1186,23 +1186,37 @@ choice
|
|
|
|
config STM32F4_DEBUG_UART
|
|
bool "Use STM32F4 UART for low-level debug"
|
|
- depends on ARCH_STM32
|
|
+ depends on ARCH_STM32 && ARM_SINGLE_ARMV7M
|
|
select DEBUG_STM32_UART
|
|
help
|
|
Say Y here if you want kernel low-level debugging support
|
|
on STM32F4 based platforms, which default UART is wired on
|
|
- USART1.
|
|
+ USART1, but another UART instance can be selected by modifying
|
|
+ CONFIG_DEBUG_UART_PHYS.
|
|
|
|
If unsure, say N.
|
|
|
|
config STM32F7_DEBUG_UART
|
|
bool "Use STM32F7 UART for low-level debug"
|
|
- depends on ARCH_STM32
|
|
+ depends on ARCH_STM32 && ARM_SINGLE_ARMV7M
|
|
select DEBUG_STM32_UART
|
|
help
|
|
Say Y here if you want kernel low-level debugging support
|
|
on STM32F7 based platforms, which default UART is wired on
|
|
- USART1.
|
|
+ USART1, but another UART instance can be selected by modifying
|
|
+ CONFIG_DEBUG_UART_PHYS.
|
|
+
|
|
+ If unsure, say N.
|
|
+
|
|
+ config STM32MP1_DEBUG_UART
|
|
+ bool "Use STM32MP1 UART for low-level debug"
|
|
+ depends on ARCH_STM32 && ARCH_MULTI_V7
|
|
+ select DEBUG_STM32_UART
|
|
+ help
|
|
+ Say Y here if you want kernel low-level debugging support
|
|
+ on STM32MP1 based platforms, wich default UART is wired on
|
|
+ UART4, but another UART instance can be selected by modifying
|
|
+ CONFIG_DEBUG_UART_PHYS and CONFIG_DEBUG_UART_VIRT.
|
|
|
|
If unsure, say N.
|
|
|
|
@@ -1607,6 +1621,8 @@ config DEBUG_UART_PHYS
|
|
default 0x3e000000 if DEBUG_BCM_KONA_UART
|
|
default 0x3f201000 if DEBUG_BCM2836
|
|
default 0x4000e400 if DEBUG_LL_UART_EFM32
|
|
+ default 0x40010000 if STM32MP1_DEBUG_UART
|
|
+ default 0x40011000 if STM32F4_DEBUG_UART || STM32F7_DEBUG_UART
|
|
default 0x40028000 if DEBUG_AT91_SAMV7_USART1
|
|
default 0x40081000 if DEBUG_LPC18XX_UART0
|
|
default 0x40090000 if DEBUG_LPC32XX
|
|
@@ -1700,10 +1716,12 @@ config DEBUG_UART_PHYS
|
|
DEBUG_S3C64XX_UART || \
|
|
DEBUG_BCM63XX_UART || DEBUG_ASM9260_UART || \
|
|
DEBUG_SIRFSOC_UART || DEBUG_DIGICOLOR_UA0 || \
|
|
- DEBUG_AT91_UART
|
|
+ DEBUG_AT91_UART || STM32F4_DEBUG_UART || \
|
|
+ STM32F7_DEBUG_UART || STM32MP1_DEBUG_UART
|
|
|
|
config DEBUG_UART_VIRT
|
|
hex "Virtual base address of debug UART"
|
|
+ default 0xfe010000 if STM32MP1_DEBUG_UART
|
|
default 0xc881f000 if DEBUG_RV1108_UART2
|
|
default 0xc8821000 if DEBUG_RV1108_UART1
|
|
default 0xc8912000 if DEBUG_RV1108_UART0
|
|
@@ -1815,7 +1833,7 @@ config DEBUG_UART_VIRT
|
|
DEBUG_S3C64XX_UART || \
|
|
DEBUG_BCM63XX_UART || DEBUG_ASM9260_UART || \
|
|
DEBUG_SIRFSOC_UART || DEBUG_DIGICOLOR_UA0 || \
|
|
- DEBUG_AT91_UART
|
|
+ DEBUG_AT91_UART || STM32MP1_DEBUG_UART
|
|
|
|
config DEBUG_UART_8250_SHIFT
|
|
int "Register offset shift for the 8250 debug UART"
|
|
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
|
|
index fdf53f5..5665290 100644
|
|
--- a/arch/arm/boot/dts/Makefile
|
|
+++ b/arch/arm/boot/dts/Makefile
|
|
@@ -924,9 +924,11 @@ dtb-$(CONFIG_ARCH_STM32) += \
|
|
stm32h743i-disco.dtb \
|
|
stm32mp157a-dk1.dtb \
|
|
stm32mp157c-dk2.dtb \
|
|
+ stm32mp157c-dk2-a7-examples.dtb \
|
|
stm32mp157c-dk2-m4-examples.dtb \
|
|
stm32mp157c-ed1.dtb \
|
|
stm32mp157c-ev1.dtb \
|
|
+ stm32mp157c-ev1-a7-examples.dtb \
|
|
stm32mp157c-ev1-m4-examples.dtb
|
|
dtb-$(CONFIG_MACH_SUN4I) += \
|
|
sun4i-a10-a1000.dtb \
|
|
diff --git a/arch/arm/include/debug/stm32.S b/arch/arm/include/debug/stm32.S
|
|
index 427561e..3353a81 100644
|
|
--- a/arch/arm/include/debug/stm32.S
|
|
+++ b/arch/arm/include/debug/stm32.S
|
|
@@ -4,21 +4,12 @@
|
|
* Author: Gerald Baeza <gerald.baeza@st.com> for STMicroelectronics.
|
|
*/
|
|
|
|
-#ifdef CONFIG_ARM_SINGLE_ARMV7M
|
|
-#define STM32_UART_BASE_PHYS 0x40011000 /* USART1 */
|
|
-#define STM32_UART_BASE_VIRT STM32_UART_BASE_PHYS /* no MMU */
|
|
-#else
|
|
-#define STM32_UART_BASE_PHYS 0x40010000 /* UART4 */
|
|
-#define STM32_UART_BASE_VIRT 0xfe010000 /* UART4 */
|
|
-#endif
|
|
-
|
|
-
|
|
#ifdef CONFIG_STM32F4_DEBUG_UART
|
|
#define STM32_USART_SR_OFF 0x00
|
|
#define STM32_USART_TDR_OFF 0x04
|
|
#endif
|
|
|
|
-#ifdef CONFIG_STM32F7_DEBUG_UART
|
|
+#if defined(CONFIG_STM32F7_DEBUG_UART) || defined(CONFIG_STM32MP1_DEBUG_UART)
|
|
#define STM32_USART_SR_OFF 0x1C
|
|
#define STM32_USART_TDR_OFF 0x28
|
|
#endif
|
|
@@ -27,8 +18,12 @@
|
|
#define STM32_USART_TXE (1 << 7) /* Tx data reg empty */
|
|
|
|
.macro addruart, rp, rv, tmp
|
|
- ldr \rp, =STM32_UART_BASE_PHYS @ physical base
|
|
- ldr \rv, =STM32_UART_BASE_VIRT @ virt base
|
|
+ ldr \rp, =CONFIG_DEBUG_UART_PHYS @ physical base
|
|
+#if defined(CONFIG_MMU)
|
|
+ ldr \rv, =CONFIG_DEBUG_UART_VIRT @ virt base
|
|
+#else
|
|
+ ldr \rv, =CONFIG_DEBUG_UART_PHYS @ same as physical base
|
|
+#endif
|
|
.endm
|
|
|
|
.macro senduart,rd,rx
|
|
diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c
|
|
index 2bad40d..287e1b3 100644
|
|
--- a/drivers/hwspinlock/hwspinlock_core.c
|
|
+++ b/drivers/hwspinlock/hwspinlock_core.c
|
|
@@ -333,6 +333,9 @@ int of_hwspin_lock_get_id(struct device_node *np, int index)
|
|
if (ret)
|
|
return ret;
|
|
|
|
+ if (!of_device_is_available(args.np))
|
|
+ return -ENOENT;
|
|
+
|
|
/* Find the hwspinlock device: we need its base_id */
|
|
ret = -EPROBE_DEFER;
|
|
rcu_read_lock();
|
|
@@ -742,13 +745,11 @@ struct hwspinlock *hwspin_lock_request_specific(unsigned int id)
|
|
/* sanity check (this shouldn't happen) */
|
|
WARN_ON(hwlock_to_id(hwlock) != id);
|
|
|
|
- /* make sure this hwspinlock is unused */
|
|
- ret = radix_tree_tag_get(&hwspinlock_tree, id, HWSPINLOCK_UNUSED);
|
|
- if (ret == 0) {
|
|
- pr_warn("hwspinlock %u is already in use\n", id);
|
|
- hwlock = NULL;
|
|
- goto out;
|
|
- }
|
|
+ /*
|
|
+ * We intentionally do not check for the HWSPINLOCK_UNUSED tag as
|
|
+ * we want to share HWSPINLOCK between several devices. This is safe
|
|
+ * since the lock/unlock requests are called under &hwlock->lock control
|
|
+ */
|
|
|
|
/* mark as used and power up */
|
|
ret = __hwspin_lock_request(hwlock);
|
|
diff --git a/drivers/hwspinlock/stm32_hwspinlock.c b/drivers/hwspinlock/stm32_hwspinlock.c
|
|
index 3242b72..b9b9b99 100644
|
|
--- a/drivers/hwspinlock/stm32_hwspinlock.c
|
|
+++ b/drivers/hwspinlock/stm32_hwspinlock.c
|
|
@@ -5,6 +5,7 @@
|
|
*/
|
|
|
|
#include <linux/clk.h>
|
|
+#include <linux/delay.h>
|
|
#include <linux/hwspinlock.h>
|
|
#include <linux/io.h>
|
|
#include <linux/kernel.h>
|
|
@@ -42,9 +43,15 @@ static void stm32_hwspinlock_unlock(struct hwspinlock *lock)
|
|
writel(STM32_MUTEX_COREID, lock_addr);
|
|
}
|
|
|
|
+static void stm32_hwspinlock_relax(struct hwspinlock *lock)
|
|
+{
|
|
+ ndelay(50);
|
|
+}
|
|
+
|
|
static const struct hwspinlock_ops stm32_hwspinlock_ops = {
|
|
.trylock = stm32_hwspinlock_trylock,
|
|
.unlock = stm32_hwspinlock_unlock,
|
|
+ .relax = stm32_hwspinlock_relax,
|
|
};
|
|
|
|
static int stm32_hwspinlock_probe(struct platform_device *pdev)
|
|
diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
|
|
index c46c70a..65687c0 100644
|
|
--- a/drivers/hwtracing/coresight/coresight-stm.c
|
|
+++ b/drivers/hwtracing/coresight/coresight-stm.c
|
|
@@ -40,6 +40,7 @@
|
|
#define STMHETER 0xd20
|
|
#define STMHEBSR 0xd60
|
|
#define STMHEMCR 0xd64
|
|
+#define STMHEEXTMUXR 0xd68
|
|
#define STMHEMASTR 0xdf4
|
|
#define STMHEFEAT1R 0xdf8
|
|
#define STMHEIDR 0xdfc
|
|
@@ -125,9 +126,11 @@ struct channel_space {
|
|
* @stmheer: settings for register STMHEER.
|
|
* @stmheter: settings for register STMHETER.
|
|
* @stmhebsr: settings for register STMHEBSR.
|
|
+ * @stmheextmuxr: settings for register STMHEEXTMUXR.
|
|
*/
|
|
struct stm_drvdata {
|
|
void __iomem *base;
|
|
+ void __iomem *base_cti;
|
|
struct device *dev;
|
|
struct clk *atclk;
|
|
struct coresight_device *csdev;
|
|
@@ -143,6 +146,7 @@ struct stm_drvdata {
|
|
u32 stmheer;
|
|
u32 stmheter;
|
|
u32 stmhebsr;
|
|
+ u32 stmheextmuxr;
|
|
};
|
|
|
|
static void stm_hwevent_enable_hw(struct stm_drvdata *drvdata)
|
|
@@ -152,6 +156,7 @@ static void stm_hwevent_enable_hw(struct stm_drvdata *drvdata)
|
|
writel_relaxed(drvdata->stmhebsr, drvdata->base + STMHEBSR);
|
|
writel_relaxed(drvdata->stmheter, drvdata->base + STMHETER);
|
|
writel_relaxed(drvdata->stmheer, drvdata->base + STMHEER);
|
|
+ writel_relaxed(drvdata->stmheextmuxr, drvdata->base + STMHEEXTMUXR);
|
|
writel_relaxed(0x01 | /* Enable HW event tracing */
|
|
0x04, /* Error detection on event tracing */
|
|
drvdata->base + STMHEMCR);
|
|
@@ -222,6 +227,7 @@ static void stm_hwevent_disable_hw(struct stm_drvdata *drvdata)
|
|
writel_relaxed(0x0, drvdata->base + STMHEMCR);
|
|
writel_relaxed(0x0, drvdata->base + STMHEER);
|
|
writel_relaxed(0x0, drvdata->base + STMHETER);
|
|
+ writel_relaxed(0x0, drvdata->base + STMHEEXTMUXR);
|
|
|
|
CS_LOCK(drvdata->base);
|
|
}
|
|
@@ -455,6 +461,34 @@ static ssize_t notrace stm_generic_packet(struct stm_data *stm_data,
|
|
return size;
|
|
}
|
|
|
|
+static ssize_t hwevent_extmux_select_show(struct device *dev,
|
|
+ struct device_attribute *attr,
|
|
+ char *buf)
|
|
+{
|
|
+ struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
|
|
+ unsigned long val = drvdata->stmheextmuxr;
|
|
+
|
|
+ return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
|
|
+}
|
|
+
|
|
+static ssize_t hwevent_extmux_select_store(struct device *dev,
|
|
+ struct device_attribute *attr,
|
|
+ const char *buf, size_t size)
|
|
+{
|
|
+ struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
|
|
+ unsigned long val;
|
|
+ int ret = 0;
|
|
+
|
|
+ ret = kstrtoul(buf, 16, &val);
|
|
+ if (ret)
|
|
+ return -EINVAL;
|
|
+
|
|
+ drvdata->stmheextmuxr = val;
|
|
+
|
|
+ return size;
|
|
+}
|
|
+static DEVICE_ATTR_RW(hwevent_extmux_select);
|
|
+
|
|
static ssize_t hwevent_enable_show(struct device *dev,
|
|
struct device_attribute *attr, char *buf)
|
|
{
|
|
@@ -644,10 +678,16 @@ coresight_stm_reg(spfeat1r, STMSPFEAT1R);
|
|
coresight_stm_reg(spfeat2r, STMSPFEAT2R);
|
|
coresight_stm_reg(spfeat3r, STMSPFEAT3R);
|
|
coresight_stm_reg(devid, CORESIGHT_DEVID);
|
|
+coresight_stm_reg(stmheer, STMHEER);
|
|
+coresight_stm_reg(stmheter, STMHETER);
|
|
+coresight_stm_reg(stmhebsr, STMHEBSR);
|
|
+coresight_stm_reg(stmheextmux, STMHEEXTMUXR);
|
|
+coresight_stm_reg(stmhemcr, STMHEMCR);
|
|
|
|
static struct attribute *coresight_stm_attrs[] = {
|
|
&dev_attr_hwevent_enable.attr,
|
|
&dev_attr_hwevent_select.attr,
|
|
+ &dev_attr_hwevent_extmux_select.attr,
|
|
&dev_attr_port_enable.attr,
|
|
&dev_attr_port_select.attr,
|
|
&dev_attr_traceid.attr,
|
|
@@ -667,6 +707,11 @@ static struct attribute *coresight_stm_mgmt_attrs[] = {
|
|
&dev_attr_spfeat2r.attr,
|
|
&dev_attr_spfeat3r.attr,
|
|
&dev_attr_devid.attr,
|
|
+ &dev_attr_stmheer.attr,
|
|
+ &dev_attr_stmheter.attr,
|
|
+ &dev_attr_stmhebsr.attr,
|
|
+ &dev_attr_stmheextmux.attr,
|
|
+ &dev_attr_stmhemcr.attr,
|
|
NULL,
|
|
};
|
|
|
|
@@ -792,7 +837,7 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id)
|
|
struct coresight_platform_data *pdata = NULL;
|
|
struct stm_drvdata *drvdata;
|
|
struct resource *res = &adev->res;
|
|
- struct resource ch_res;
|
|
+ struct resource ch_res, cti_res;
|
|
size_t res_size, bitmap_size;
|
|
struct coresight_desc desc = { 0 };
|
|
struct device_node *np = adev->dev.of_node;
|
|
@@ -821,6 +866,17 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id)
|
|
return PTR_ERR(base);
|
|
drvdata->base = base;
|
|
|
|
+ ret = stm_get_resource_byname(np, "cti-base", &cti_res);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ base = devm_ioremap_resource(dev, &cti_res);
|
|
+
|
|
+ if (IS_ERR(base))
|
|
+ return PTR_ERR(base);
|
|
+
|
|
+ drvdata->base_cti = base;
|
|
+
|
|
ret = stm_get_resource_byname(np, "stm-stimulus-base", &ch_res);
|
|
if (ret)
|
|
return ret;
|
|
diff --git a/drivers/soc/st/Kconfig b/drivers/soc/st/Kconfig
|
|
index 82ee423..8ab6049 100644
|
|
--- a/drivers/soc/st/Kconfig
|
|
+++ b/drivers/soc/st/Kconfig
|
|
@@ -6,4 +6,12 @@ config STM32_PM_DOMAINS
|
|
select PM_GENERIC_DOMAINS
|
|
default y if MACH_STM32MP157
|
|
|
|
+config STM32_HDP
|
|
+ bool "STMicroelectronics STM32MP157 Hardware Debug Port (HDP) pin control"
|
|
+ depends on MACH_STM32MP157
|
|
+ default n if MACH_STM32MP157
|
|
+ help
|
|
+ The Hardware Debug Port allows the observation of internal signals. By using multiplexers,
|
|
+ up to 16 signals for each of 8-bit output can be observed.
|
|
+
|
|
endif # ARCH_STM32
|
|
diff --git a/drivers/soc/st/Makefile b/drivers/soc/st/Makefile
|
|
index 8d7f291..85905b7 100644
|
|
--- a/drivers/soc/st/Makefile
|
|
+++ b/drivers/soc/st/Makefile
|
|
@@ -1 +1,2 @@
|
|
obj-$(CONFIG_STM32_PM_DOMAINS) += stm32_pm_domain.o
|
|
+obj-$(CONFIG_STM32_HDP) += stm32_hdp.o
|
|
diff --git a/drivers/soc/st/stm32_hdp.c b/drivers/soc/st/stm32_hdp.c
|
|
new file mode 100644
|
|
index 0000000..6408ac6
|
|
--- /dev/null
|
|
+++ b/drivers/soc/st/stm32_hdp.c
|
|
@@ -0,0 +1,242 @@
|
|
+// SPDX-License-Identifier: GPL-2.0
|
|
+/*
|
|
+ * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
|
|
+ * Author: Christophe Roullier <christophe.roullier@st.com>
|
|
+ * for STMicroelectronics.
|
|
+ */
|
|
+
|
|
+#include <linux/clk.h>
|
|
+#include <linux/debugfs.h>
|
|
+#include <linux/init.h>
|
|
+#include <linux/of.h>
|
|
+#include <linux/module.h>
|
|
+#include <linux/pinctrl/pinconf.h>
|
|
+#include <linux/pinctrl/pinconf-generic.h>
|
|
+#include <linux/pinctrl/pinctrl.h>
|
|
+#include <linux/platform_device.h>
|
|
+#include <linux/io.h>
|
|
+#include <linux/suspend.h>
|
|
+
|
|
+#define HDP_CTRL_ENABLE 1
|
|
+#define HDP_CTRL_DISABLE 0
|
|
+
|
|
+enum {
|
|
+ HDP_CTRL = 0,
|
|
+ HDP_MUX = 0x4,
|
|
+ HDP_VAL = 0x10,
|
|
+ HDP_GPOSET = 0x14,
|
|
+ HDP_GPOCLR = 0x18,
|
|
+ HDP_GPOVAL = 0x1c,
|
|
+ HDP_VERR = 0x3f4,
|
|
+ HDP_IPIDR = 0x3f8,
|
|
+ HDP_SIDR = 0x3fc
|
|
+} HDP_register_offsets;
|
|
+
|
|
+struct data_priv {
|
|
+ struct clk *clk;
|
|
+ int clk_is_enabled;
|
|
+ struct dentry *pwr_dentry;
|
|
+ unsigned char __iomem *hdp_membase;
|
|
+ unsigned int hdp_ctrl;
|
|
+ unsigned int hdp_mux;
|
|
+};
|
|
+
|
|
+/* enable/disable */
|
|
+static int stm32_hdp_enable_set(void *data, int val)
|
|
+{
|
|
+ struct data_priv *e = (struct data_priv *)data;
|
|
+
|
|
+ if (!e->clk)
|
|
+ return -EPERM;
|
|
+
|
|
+ if (val == 1) {
|
|
+ if (clk_prepare_enable(e->clk) < 0) {
|
|
+ pr_err("Failed to enable HDP clock\n");
|
|
+ return -EPERM;
|
|
+ }
|
|
+ e->clk_is_enabled = 1;
|
|
+ } else {
|
|
+ clk_disable_unprepare(e->clk);
|
|
+ e->clk_is_enabled = 0;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int stm32_hdp_fops_set(void *data, u64 val)
|
|
+{
|
|
+ unsigned char __iomem *addr = (unsigned char __iomem *)data;
|
|
+
|
|
+ writel_relaxed(val, addr);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int stm32_hdp_fops_get(void *data, u64 *val)
|
|
+{
|
|
+ unsigned char __iomem *addr = (unsigned char __iomem *)data;
|
|
+
|
|
+ *val = readl_relaxed(addr);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+DEFINE_SIMPLE_ATTRIBUTE(stm32_hdp_fops, stm32_hdp_fops_get,
|
|
+ stm32_hdp_fops_set, "0x%llx\n");
|
|
+
|
|
+int stm32_hdp_probe(struct platform_device *pdev)
|
|
+{
|
|
+ struct device_node *np = pdev->dev.of_node;
|
|
+ struct device *dev = &pdev->dev;
|
|
+ struct resource *res;
|
|
+
|
|
+ struct data_priv *data;
|
|
+ struct dentry *r;
|
|
+
|
|
+ int ret;
|
|
+ const __be32 *getmuxing;
|
|
+ u32 muxing, version;
|
|
+
|
|
+ if (!np)
|
|
+ return -ENODEV;
|
|
+
|
|
+ data = devm_kzalloc(&pdev->dev, sizeof(struct data_priv), GFP_KERNEL);
|
|
+ if (!data)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
+ data->hdp_membase = devm_ioremap_resource(&pdev->dev, res);
|
|
+ if (IS_ERR(data->hdp_membase))
|
|
+ return PTR_ERR(data->hdp_membase);
|
|
+
|
|
+ /* Get HDP clocks */
|
|
+ data->clk = devm_clk_get(dev, "hdp");
|
|
+ if (IS_ERR(data->clk)) {
|
|
+ dev_err(dev, "No HDP CK clock provided...\n");
|
|
+ return PTR_ERR(data->clk);
|
|
+ }
|
|
+
|
|
+ /* Enable clock */
|
|
+ ret = stm32_hdp_enable_set(data, 1);
|
|
+ if (ret != 0)
|
|
+ return ret;
|
|
+
|
|
+ getmuxing = of_get_property(np, "muxing-hdp", NULL);
|
|
+ if (!getmuxing) {
|
|
+ dev_err(dev,
|
|
+ "no muxing-hdp property in node\n");
|
|
+ /* Disable clock */
|
|
+ ret = stm32_hdp_enable_set(data, 0);
|
|
+ if (ret != 0)
|
|
+ return ret;
|
|
+
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ /* add hdp directory */
|
|
+ r = debugfs_create_dir("hdp", NULL);
|
|
+ if (!r) {
|
|
+ dev_err(dev, "Unable to create HDP debugFS\n");
|
|
+ /* Disable clock */
|
|
+ ret = stm32_hdp_enable_set(data, 0);
|
|
+ if (ret != 0)
|
|
+ return ret;
|
|
+
|
|
+ return -ENODEV;
|
|
+ }
|
|
+
|
|
+ debugfs_create_file("ctrl", 0644, r,
|
|
+ data->hdp_membase + HDP_CTRL, &stm32_hdp_fops);
|
|
+ debugfs_create_file("mux", 0644, r,
|
|
+ data->hdp_membase + HDP_MUX, &stm32_hdp_fops);
|
|
+ debugfs_create_file("val", 0644, r,
|
|
+ data->hdp_membase + HDP_VAL, &stm32_hdp_fops);
|
|
+ debugfs_create_file("gposet", 0644, r,
|
|
+ data->hdp_membase + HDP_GPOSET, &stm32_hdp_fops);
|
|
+ debugfs_create_file("gpoclr", 0644, r,
|
|
+ data->hdp_membase + HDP_GPOCLR, &stm32_hdp_fops);
|
|
+ debugfs_create_file("gpoval", 0644, r,
|
|
+ data->hdp_membase + HDP_GPOVAL, &stm32_hdp_fops);
|
|
+
|
|
+ /* Enable HDP */
|
|
+ writel(HDP_CTRL_ENABLE, data->hdp_membase + HDP_CTRL);
|
|
+
|
|
+ /* HDP Multiplexing */
|
|
+ muxing = of_read_number(getmuxing,
|
|
+ of_n_addr_cells(np));
|
|
+
|
|
+ writel(muxing, data->hdp_membase + HDP_MUX);
|
|
+
|
|
+ platform_set_drvdata(pdev, data);
|
|
+
|
|
+ /* Get Majeur, Minor version */
|
|
+ version = readl(data->hdp_membase + HDP_VERR);
|
|
+
|
|
+ dev_info(dev, "STM32 HDP version %d.%d initialized\n",
|
|
+ version >> 4, version & 0x0F);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int stm32_hdp_remove(struct platform_device *pdev)
|
|
+{
|
|
+ struct data_priv *data = platform_get_drvdata(pdev);
|
|
+
|
|
+ /* Disable HDP */
|
|
+ writel(HDP_CTRL_DISABLE, data->hdp_membase + HDP_CTRL);
|
|
+
|
|
+ if (data->clk) {
|
|
+ if (data->clk_is_enabled)
|
|
+ clk_disable_unprepare(data->clk);
|
|
+ }
|
|
+
|
|
+ pr_info("driver STM32 HDP removed\n");
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+#ifdef CONFIG_PM_SLEEP
|
|
+static int stm32_hdp_suspend(struct device *dev)
|
|
+{
|
|
+ struct data_priv *data = dev_get_drvdata(dev);
|
|
+
|
|
+ data->hdp_ctrl = readl_relaxed(data->hdp_membase + HDP_CTRL);
|
|
+ data->hdp_mux = readl_relaxed(data->hdp_membase + HDP_MUX);
|
|
+
|
|
+ pinctrl_pm_select_sleep_state(dev);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int stm32_hdp_resume(struct device *dev)
|
|
+{
|
|
+ struct data_priv *data = dev_get_drvdata(dev);
|
|
+
|
|
+ writel_relaxed(data->hdp_ctrl, data->hdp_membase + HDP_CTRL);
|
|
+ writel_relaxed(data->hdp_mux, data->hdp_membase + HDP_MUX);
|
|
+
|
|
+ pinctrl_pm_select_default_state(dev);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+#endif /* CONFIG_PM_SLEEP */
|
|
+
|
|
+static SIMPLE_DEV_PM_OPS(stm32_hdp_pm_ops,
|
|
+ stm32_hdp_suspend,
|
|
+ stm32_hdp_resume);
|
|
+
|
|
+static const struct of_device_id hdp_match[] = {
|
|
+ { .compatible = "st,stm32mp1-hdp",},
|
|
+ { }
|
|
+};
|
|
+MODULE_DEVICE_TABLE(of, hdp_match);
|
|
+
|
|
+static struct platform_driver hdp_driver = {
|
|
+ .probe = stm32_hdp_probe,
|
|
+ .remove = stm32_hdp_remove,
|
|
+ .driver = {
|
|
+ .name = "hdp",
|
|
+ .of_match_table = hdp_match,
|
|
+ .pm = &stm32_hdp_pm_ops,
|
|
+ },
|
|
+};
|
|
+
|
|
+module_platform_driver(hdp_driver);
|
|
diff --git a/drivers/spi/spi-stm32-qspi.c b/drivers/spi/spi-stm32-qspi.c
|
|
index 3e8ca10..9c67718 100644
|
|
--- a/drivers/spi/spi-stm32-qspi.c
|
|
+++ b/drivers/spi/spi-stm32-qspi.c
|
|
@@ -5,7 +5,10 @@
|
|
*/
|
|
#include <linux/bitfield.h>
|
|
#include <linux/clk.h>
|
|
+#include <linux/dmaengine.h>
|
|
+#include <linux/dma-mapping.h>
|
|
#include <linux/errno.h>
|
|
+#include <linux/highmem.h>
|
|
#include <linux/io.h>
|
|
#include <linux/iopoll.h>
|
|
#include <linux/interrupt.h>
|
|
@@ -84,6 +87,7 @@
|
|
#define STM32_FIFO_TIMEOUT_US 30000
|
|
#define STM32_BUSY_TIMEOUT_US 100000
|
|
#define STM32_ABT_TIMEOUT_US 100000
|
|
+#define STM32_COMP_TIMEOUT_MS 1000
|
|
|
|
struct stm32_qspi_flash {
|
|
struct stm32_qspi *qspi;
|
|
@@ -93,6 +97,7 @@ struct stm32_qspi_flash {
|
|
|
|
struct stm32_qspi {
|
|
struct device *dev;
|
|
+ phys_addr_t phys_base;
|
|
void __iomem *io_base;
|
|
void __iomem *mm_base;
|
|
resource_size_t mm_size;
|
|
@@ -102,6 +107,11 @@ struct stm32_qspi {
|
|
struct completion data_completion;
|
|
u32 fmode;
|
|
|
|
+ struct dma_chan *dma_chtx;
|
|
+ struct dma_chan *dma_chrx;
|
|
+ struct completion dma_completion;
|
|
+ struct sg_table dma_sgt;
|
|
+
|
|
u32 cr_reg;
|
|
u32 dcr_reg;
|
|
|
|
@@ -180,6 +190,131 @@ static int stm32_qspi_tx_mm(struct stm32_qspi *qspi,
|
|
return 0;
|
|
}
|
|
|
|
+static void stm32_qspi_dma_callback(void *arg)
|
|
+{
|
|
+ struct completion *dma_completion = arg;
|
|
+
|
|
+ complete(dma_completion);
|
|
+}
|
|
+
|
|
+static int stm32_qspi_tx_dma(struct stm32_qspi *qspi,
|
|
+ const struct spi_mem_op *op)
|
|
+{
|
|
+ struct dma_async_tx_descriptor *desc;
|
|
+ enum dma_transfer_direction dma_dir;
|
|
+ enum dma_data_direction map_dir;
|
|
+ bool addr_valid, vmalloced_buf;
|
|
+ unsigned int dma_max_seg_size;
|
|
+ struct scatterlist *sg;
|
|
+ struct dma_chan *dma_ch;
|
|
+ struct page *vm_page;
|
|
+ dma_cookie_t cookie;
|
|
+ u32 cr, len, t_out;
|
|
+ int i, err, nents, desc_len;
|
|
+ u8 *buf;
|
|
+
|
|
+ cr = readl_relaxed(qspi->io_base + QSPI_CR);
|
|
+
|
|
+ if (op->data.dir == SPI_MEM_DATA_IN) {
|
|
+ map_dir = DMA_FROM_DEVICE;
|
|
+ dma_dir = DMA_DEV_TO_MEM;
|
|
+ dma_ch = qspi->dma_chrx;
|
|
+ buf = op->data.buf.in;
|
|
+ } else {
|
|
+ map_dir = DMA_TO_DEVICE;
|
|
+ dma_dir = DMA_MEM_TO_DEV;
|
|
+ dma_ch = qspi->dma_chtx;
|
|
+ buf = (u8 *)op->data.buf.out;
|
|
+ }
|
|
+
|
|
+ /* the stm32 dma could tx MAX_DMA_BLOCK_LEN */
|
|
+ dma_max_seg_size = dma_get_max_seg_size(dma_ch->device->dev);
|
|
+ len = op->data.nbytes;
|
|
+
|
|
+ vmalloced_buf = is_vmalloc_addr(buf);
|
|
+ addr_valid = virt_addr_valid(buf);
|
|
+ if (addr_valid) {
|
|
+ desc_len = dma_max_seg_size;
|
|
+ nents = DIV_ROUND_UP(len, desc_len);
|
|
+ } else {
|
|
+ desc_len = min_t(int, dma_max_seg_size, PAGE_SIZE);
|
|
+ nents = DIV_ROUND_UP(len + offset_in_page(buf), desc_len);
|
|
+ }
|
|
+
|
|
+ if (nents != qspi->dma_sgt.nents) {
|
|
+ sg_free_table(&qspi->dma_sgt);
|
|
+
|
|
+ err = sg_alloc_table(&qspi->dma_sgt, nents, GFP_KERNEL);
|
|
+ if (err)
|
|
+ return err;
|
|
+ }
|
|
+
|
|
+ for_each_sg(qspi->dma_sgt.sgl, sg, nents, i) {
|
|
+ size_t bytes;
|
|
+
|
|
+ if (addr_valid) {
|
|
+ bytes = min_t(size_t, len, desc_len);
|
|
+ sg_set_buf(sg, buf, bytes);
|
|
+ } else {
|
|
+ bytes = min_t(size_t, len,
|
|
+ desc_len - offset_in_page(buf));
|
|
+ if (vmalloced_buf)
|
|
+ vm_page = vmalloc_to_page(buf);
|
|
+ else
|
|
+ vm_page = kmap_to_page(buf);
|
|
+ if (!vm_page) {
|
|
+ sg_free_table(&qspi->dma_sgt);
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+ sg_set_page(sg, vm_page, bytes,
|
|
+ offset_in_page(buf));
|
|
+ }
|
|
+
|
|
+ buf += bytes;
|
|
+ len -= bytes;
|
|
+ }
|
|
+
|
|
+ if (dma_map_sg(qspi->dev, qspi->dma_sgt.sgl, nents, map_dir) != nents)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ desc = dmaengine_prep_slave_sg(dma_ch, qspi->dma_sgt.sgl, nents,
|
|
+ dma_dir, DMA_PREP_INTERRUPT);
|
|
+ if (!desc) {
|
|
+ err = -ENOMEM;
|
|
+ goto out_unmap;
|
|
+ }
|
|
+
|
|
+ reinit_completion(&qspi->dma_completion);
|
|
+ desc->callback = stm32_qspi_dma_callback;
|
|
+ desc->callback_param = &qspi->dma_completion;
|
|
+ cookie = dmaengine_submit(desc);
|
|
+ err = dma_submit_error(cookie);
|
|
+ if (err)
|
|
+ goto out_unmap;
|
|
+
|
|
+ dma_async_issue_pending(dma_ch);
|
|
+
|
|
+ writel_relaxed(cr | CR_DMAEN, qspi->io_base + QSPI_CR);
|
|
+
|
|
+ t_out = nents * STM32_COMP_TIMEOUT_MS;
|
|
+ if (!wait_for_completion_interruptible_timeout(&qspi->dma_completion,
|
|
+ msecs_to_jiffies(t_out)))
|
|
+ err = -ETIMEDOUT;
|
|
+
|
|
+ if (dma_async_is_tx_complete(dma_ch, cookie,
|
|
+ NULL, NULL) != DMA_COMPLETE)
|
|
+ err = -ETIMEDOUT;
|
|
+
|
|
+ if (err)
|
|
+ dmaengine_terminate_all(dma_ch);
|
|
+
|
|
+out_unmap:
|
|
+ writel_relaxed(cr & ~CR_DMAEN, qspi->io_base + QSPI_CR);
|
|
+ dma_unmap_sg(qspi->dev, qspi->dma_sgt.sgl, nents, map_dir);
|
|
+
|
|
+ return err;
|
|
+}
|
|
+
|
|
static int stm32_qspi_tx(struct stm32_qspi *qspi, const struct spi_mem_op *op)
|
|
{
|
|
if (!op->data.nbytes)
|
|
@@ -187,6 +322,10 @@ static int stm32_qspi_tx(struct stm32_qspi *qspi, const struct spi_mem_op *op)
|
|
|
|
if (qspi->fmode == CCR_FMODE_MM)
|
|
return stm32_qspi_tx_mm(qspi, op);
|
|
+ else if (op->data.dir == SPI_MEM_DATA_IN && qspi->dma_chrx)
|
|
+ return stm32_qspi_tx_dma(qspi, op);
|
|
+ else if (op->data.dir == SPI_MEM_DATA_OUT && qspi->dma_chtx)
|
|
+ return stm32_qspi_tx_dma(qspi, op);
|
|
|
|
return stm32_qspi_tx_poll(qspi, op);
|
|
}
|
|
@@ -217,7 +356,7 @@ static int stm32_qspi_wait_cmd(struct stm32_qspi *qspi,
|
|
writel_relaxed(cr | CR_TCIE | CR_TEIE, qspi->io_base + QSPI_CR);
|
|
|
|
if (!wait_for_completion_interruptible_timeout(&qspi->data_completion,
|
|
- msecs_to_jiffies(1000))) {
|
|
+ msecs_to_jiffies(STM32_COMP_TIMEOUT_MS))) {
|
|
err = -ETIMEDOUT;
|
|
} else {
|
|
sr = readl_relaxed(qspi->io_base + QSPI_SR);
|
|
@@ -386,6 +525,52 @@ static int stm32_qspi_setup(struct spi_device *spi)
|
|
return 0;
|
|
}
|
|
|
|
+static void stm32_qspi_dma_setup(struct stm32_qspi *qspi)
|
|
+{
|
|
+ struct dma_slave_config dma_cfg;
|
|
+ struct device *dev = qspi->dev;
|
|
+ int ret;
|
|
+
|
|
+ memset(&dma_cfg, 0, sizeof(dma_cfg));
|
|
+
|
|
+ dma_cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
|
|
+ dma_cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
|
|
+ dma_cfg.src_addr = qspi->phys_base + QSPI_DR;
|
|
+ dma_cfg.dst_addr = qspi->phys_base + QSPI_DR;
|
|
+ dma_cfg.src_maxburst = 4;
|
|
+ dma_cfg.dst_maxburst = 4;
|
|
+
|
|
+ qspi->dma_chrx = dma_request_slave_channel(dev, "rx");
|
|
+ if (qspi->dma_chrx) {
|
|
+ ret = dmaengine_slave_config(qspi->dma_chrx, &dma_cfg);
|
|
+ if (ret) {
|
|
+ dev_err(dev, "dma rx config failed\n");
|
|
+ dma_release_channel(qspi->dma_chrx);
|
|
+ qspi->dma_chrx = NULL;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ qspi->dma_chtx = dma_request_slave_channel(dev, "tx");
|
|
+ if (qspi->dma_chtx) {
|
|
+ ret = dmaengine_slave_config(qspi->dma_chtx, &dma_cfg);
|
|
+ if (ret) {
|
|
+ dev_err(dev, "dma tx config failed\n");
|
|
+ dma_release_channel(qspi->dma_chtx);
|
|
+ qspi->dma_chtx = NULL;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ init_completion(&qspi->dma_completion);
|
|
+}
|
|
+
|
|
+static void stm32_qspi_dma_free(struct stm32_qspi *qspi)
|
|
+{
|
|
+ if (qspi->dma_chtx)
|
|
+ dma_release_channel(qspi->dma_chtx);
|
|
+ if (qspi->dma_chrx)
|
|
+ dma_release_channel(qspi->dma_chrx);
|
|
+}
|
|
+
|
|
/*
|
|
* no special host constraint, so use default spi_mem_default_supports_op
|
|
* to check supported mode.
|
|
@@ -398,6 +583,8 @@ static void stm32_qspi_release(struct stm32_qspi *qspi)
|
|
{
|
|
/* disable qspi */
|
|
writel_relaxed(0, qspi->io_base + QSPI_CR);
|
|
+ stm32_qspi_dma_free(qspi);
|
|
+ sg_free_table(&qspi->dma_sgt);
|
|
mutex_destroy(&qspi->lock);
|
|
clk_disable_unprepare(qspi->clk);
|
|
}
|
|
@@ -422,6 +609,8 @@ static int stm32_qspi_probe(struct platform_device *pdev)
|
|
if (IS_ERR(qspi->io_base))
|
|
return PTR_ERR(qspi->io_base);
|
|
|
|
+ qspi->phys_base = res->start;
|
|
+
|
|
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qspi_mm");
|
|
qspi->mm_base = devm_ioremap_resource(dev, res);
|
|
if (IS_ERR(qspi->mm_base))
|
|
@@ -464,6 +653,7 @@ static int stm32_qspi_probe(struct platform_device *pdev)
|
|
|
|
qspi->dev = dev;
|
|
platform_set_drvdata(pdev, qspi);
|
|
+ stm32_qspi_dma_setup(qspi);
|
|
mutex_init(&qspi->lock);
|
|
|
|
ctrl->mode_bits = SPI_RX_DUAL | SPI_RX_QUAD
|
|
diff --git a/include/dt-bindings/soc/stm32-hdp.h b/include/dt-bindings/soc/stm32-hdp.h
|
|
new file mode 100644
|
|
index 0000000..d986653
|
|
--- /dev/null
|
|
+++ b/include/dt-bindings/soc/stm32-hdp.h
|
|
@@ -0,0 +1,108 @@
|
|
+/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
|
|
+/*
|
|
+ * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
|
|
+ * Author: Roullier Christophe <christophe.roullier@st.com>
|
|
+ * for STMicroelectronics.
|
|
+ */
|
|
+
|
|
+#ifndef _DT_BINDINGS_STM32_HDP_H
|
|
+#define _DT_BINDINGS_STM32_HDP_H
|
|
+
|
|
+#define STM32_HDP(port, value) ((value) << ((port) * 4))
|
|
+
|
|
+/* define HDP Pins number*/
|
|
+#define HDP0_PWR_PWRWAKE_SYS 0
|
|
+#define HDP0_CM4_SLEEPDEEP 1
|
|
+#define HDP0_PWR_STDBY_WKUP 2
|
|
+#define HDP0_PWR_ENCOMP_VDDCORE 3
|
|
+#define HDP0_BSEC_OUT_SEC_NIDEN 4
|
|
+#define HDP0_RCC_CM4_SLEEPDEEP 6
|
|
+#define HDP0_GPU_DBG7 7
|
|
+#define HDP0_DDRCTRL_LP_REQ 8
|
|
+#define HDP0_PWR_DDR_RET_ENABLE_N 9
|
|
+#define HDP0_GPOVAL_0 15
|
|
+
|
|
+#define HDP1_PWR_PWRWAKE_MCU 0
|
|
+#define HDP1_CM4_HALTED 1
|
|
+#define HDP1_CA7_NAXIERRIRQ 2
|
|
+#define HDP1_PWR_OKIN_MR 3
|
|
+#define HDP1_BSEC_OUT_SEC_DBGEN 4
|
|
+#define HDP1_EXTI_SYS_WAKEUP 5
|
|
+#define HDP1_RCC_PWRDS_MPU 6
|
|
+#define HDP1_GPU_DBG6 7
|
|
+#define HDP1_DDRCTRL_DFI_CTRLUPD_REQ 8
|
|
+#define HDP1_DDRCTRL_CACTIVE_DDRC_ASR 9
|
|
+#define HDP1_GPOVAL_1 15
|
|
+
|
|
+#define HDP2_PWR_PWRWAKE_MPU 0
|
|
+#define HDP2_CM4_RXEV 1
|
|
+#define HDP2_CA7_NPMUIRQ1 2
|
|
+#define HDP2_CA7_NFIQOUT1 3
|
|
+#define HDP2_BSEC_IN_RSTCORE_N 4
|
|
+#define HDP2_EXTI_C2_WAKEUP 5
|
|
+#define HDP2_RCC_PWRDS_MCU 6
|
|
+#define HDP2_GPU_DBG5 7
|
|
+#define HDP2_DDRCTRL_DFI_INIT_COMPLETE 8
|
|
+#define HDP2_DDRCTRL_PERF_OP_IS_REFRESH 9
|
|
+#define HDP2_DDRCTRL_GSKP_DFI_LP_REQ 10
|
|
+#define HDP2_GPOVAL_2 15
|
|
+
|
|
+#define HDP3_PWR_SEL_VTH_VDD_CORE 0
|
|
+#define HDP3_CM4_TXEV 1
|
|
+#define HDP3_CA7_NPMUIRQ0 2
|
|
+#define HDP3_CA7_NFIQOUT0 3
|
|
+#define HDP3_BSEC_OUT_SEC_DFTLOCK 4
|
|
+#define HDP3_EXTI_C1_WAKEUP 5
|
|
+#define HDP3_RCC_PWRDS_SYS 6
|
|
+#define HDP3_GPU_DBG4 7
|
|
+#define HDP3_DDRCTRL_STAT_DDRC_REG_SELREF_TYPE0 8
|
|
+#define HDP3_DDRCTRL_CACTIVE_1 9
|
|
+#define HDP3_GPOVAL_3 15
|
|
+
|
|
+#define HDP4_PWR_PDDS 0
|
|
+#define HDP4_CM4_SLEEPING 1
|
|
+#define HDP4_CA7_NRESET1 2
|
|
+#define HDP4_CA7_NIRQOUT1 3
|
|
+#define HDP4_BSEC_OUT_SEC_DFTEN 4
|
|
+#define HDP4_BSEC_OUT_SEC_DBGSWENABLE 5
|
|
+#define HDP4_ETH_OUT_PMT_INTR_O 6
|
|
+#define HDP4_GPU_DBG3 7
|
|
+#define HDP4_DDRCTRL_STAT_DDRC_REG_SELREF_TYPE1 8
|
|
+#define HDP4_DDRCTRL_CACTIVE_0 9
|
|
+#define HDP4_GPOVAL_4 15
|
|
+
|
|
+#define HDP5_CA7_STANDBYWFIL2 0
|
|
+#define HDP5_PWR_VTH_VDDCORE_ACK 1
|
|
+#define HDP5_CA7_NRESET0 2
|
|
+#define HDP5_CA7_NIRQOUT0 3
|
|
+#define HDP5_BSEC_IN_PWROK 4
|
|
+#define HDP5_BSEC_OUT_SEC_DEVICEEN 5
|
|
+#define HDP5_ETH_OUT_LPI_INTR_O 6
|
|
+#define HDP5_GPU_DBG2 7
|
|
+#define HDP5_DDRCTRL_CACTIVE_DDRC 8
|
|
+#define HDP5_DDRCTRL_WR_CREDIT_CNT 9
|
|
+#define HDP5_GPOVAL_5 15
|
|
+
|
|
+#define HDP6_CA7_STANDBYWFI1 0
|
|
+#define HDP6_CA7_STANDBYWFE1 1
|
|
+#define HDP6_CA7_EVENT0 2
|
|
+#define HDP6_CA7_DBGACK1 3
|
|
+#define HDP6_BSEC_OUT_SEC_SPNIDEN 5
|
|
+#define HDP6_ETH_OUT_MAC_SPEED_O1 6
|
|
+#define HDP6_GPU_DBG1 7
|
|
+#define HDP6_DDRCTRL_CSYSACK_DDRC 8
|
|
+#define HDP6_DDRCTRL_LPR_CREDIT_CNT 9
|
|
+#define HDP6_GPOVAL_6 15
|
|
+
|
|
+#define HDP7_CA7_STANDBYWFI0 0
|
|
+#define HDP7_CA7_STANDBYWFE0 1
|
|
+#define HDP7_CA7_DBGACK0 3
|
|
+#define HDP7_BSEC_OUT_FUSE_OK 4
|
|
+#define HDP7_BSEC_OUT_SEC_SPIDEN 5
|
|
+#define HDP7_ETH_OUT_MAC_SPEED_O0 6
|
|
+#define HDP7_GPU_DBG0 7
|
|
+#define HDP7_DDRCTRL_CSYSREQ_DDRC 8
|
|
+#define HDP7_DDRCTRL_HPR_CREDIT_CNT 9
|
|
+#define HDP7_GPOVAL_7 15
|
|
+
|
|
+#endif /* _DT_BINDINGS_STM32_HDP_H */
|
|
--
|
|
2.7.4
|
|
|