1
From: Patrice Chotard <patrice.chotard@foss.st.com>
2
3
This series adds SPI NOR support for STM32MP25 SoCs from STMicroelectronics.
1
This series adds SPI NOR support for STM32MP25 SoCs from STMicroelectronics.
4
2
5
On STM32MP25 SoCs family, an Octo Memory Manager block manages the muxing,
3
On STM32MP25 SoCs family, an Octo Memory Manager block manages the muxing,
6
the memory area split, the chip select override and the time constraint
4
the memory area split, the chip select override and the time constraint
7
between its 2 Octo SPI children.
5
between its 2 Octo SPI children.
8
6
9
Due to these depedencies, this series adds support for:
7
Due to these depedencies, this series adds support for:
10
- Octo Memory Manager driver.
8
- Octo Memory Manager driver.
11
- Octo SPI driver.
9
- Octo SPI driver.
12
- yaml schema for Octo Memory Manager and Octo SPI drivers.
10
- yaml schema for Octo Memory Manager and Octo SPI drivers.
13
11
14
The device tree files adds Octo Memory Manager and its 2 associated Octo
12
The device tree files adds Octo Memory Manager and its 2 associated Octo
15
SPI chidren in stm32mp251.dtsi and adds SPI NOR support in stm32mp257f-ev1
13
SPI chidren in stm32mp251.dtsi and adds SPI NOR support in stm32mp257f-ev1
16
board.
14
board.
15
16
Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com>
17
17
18
Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com>
18
Changes in v7:
19
- update OMM's dt-bindings by updating :
20
- clock-names and reset-names properties.
21
- spi unit-address node.
22
- example.
23
- update stm32mp251.dtsi to match with OMM's bindings update.
24
- update stm32mp257f-ev1.dts to match with OMM's bindings update.
25
- Link to v6: https://lore.kernel.org/r/20250321-upstream_ospi_v6-v6-0-37bbcab43439@foss.st.com
26
27
Changes in v6:
28
- Update MAINTAINERS file.
29
- Remove previous patch 1/8 and 2/8, merged by Mark Brown in spi git tree.
30
- Fix Signed-off-by order for patch 3.
31
- OMM driver:
32
- Add dev_err_probe() in error path.
33
- Rename stm32_omm_enable_child_clock() to stm32_omm_toggle_child_clock().
34
- Reorder initialised/non-initialized variable in stm32_omm_configure()
35
and stm32_omm_probe().
36
- Move pm_runtime_disable() calls from stm32_omm_configure() to
37
stm32_omm_probe().
38
- Update children's clocks and reset management.
39
- Use of_platform_populate() to probe children.
40
- Add missing pm_runtime_disable().
41
- Remove useless stm32_omm_check_access's first parameter.
42
- Update OMM's dt-bindings by adding OSPI's clocks and resets.
43
- Update stm32mp251.dtsi by adding OSPI's clock and reset in OMM's node.
19
44
20
Changes in v5:
45
Changes in v5:
21
- Add Reviewed-by Krzysztof Kozlowski for patch 1 and 3.
46
- Add Reviewed-by Krzysztof Kozlowski for patch 1 and 3.
22
47
23
Changes in v4:
48
Changes in v4:
24
- Add default value requested by Krzysztof for st,omm-req2ack-ns,
49
- Add default value requested by Krzysztof for st,omm-req2ack-ns,
25
st,omm-cssel-ovr and st,omm-mux properties in st,stm32mp25-omm.yaml
50
st,omm-cssel-ovr and st,omm-mux properties in st,stm32mp25-omm.yaml
26
- Remove constraint in free form test for st,omm-mux property.
51
- Remove constraint in free form test for st,omm-mux property.
27
- Fix drivers/memory/Kconfig by replacing TEST_COMPILE_ by COMPILE_TEST.
52
- Fix drivers/memory/Kconfig by replacing TEST_COMPILE_ by COMPILE_TEST.
28
- Fix SPDX-License-Identifier for stm32-omm.c.
53
- Fix SPDX-License-Identifier for stm32-omm.c.
29
- Fix Kernel test robot by fixing dev_err() format in stm32-omm.c.
54
- Fix Kernel test robot by fixing dev_err() format in stm32-omm.c.
30
- Add missing pm_runtime_disable() in the error handling path in
55
- Add missing pm_runtime_disable() in the error handling path in
31
stm32-omm.c.
56
stm32-omm.c.
32
- Replace an int by an unsigned int in stm32-omm.c
57
- Replace an int by an unsigned int in stm32-omm.c
33
- Remove uneeded "," after terminator in stm32-omm.c.
58
- Remove uneeded "," after terminator in stm32-omm.c.
34
- Update cover letter description to explain dependecies between
59
- Update cover letter description to explain dependecies between
35
Octo Memory Manager and its 2 Octo SPI children.
60
Octo Memory Manager and its 2 Octo SPI children.
36
61
37
Changes in v3:
62
Changes in v3:
38
- Squash defconfig patches 8 and 9.
63
- Squash defconfig patches 8 and 9.
39
- Update STM32 Octo Memory Manager controller bindings.
64
- Update STM32 Octo Memory Manager controller bindings.
40
- Rename st,stm32-omm.yaml to st,stm32mp25-omm.yaml.
65
- Rename st,stm32-omm.yaml to st,stm32mp25-omm.yaml.
41
- Update STM32 OSPI controller bindings.
66
- Update STM32 OSPI controller bindings.
42
- Reorder DT properties in .dtsi and .dts files.
67
- Reorder DT properties in .dtsi and .dts files.
43
- Replace devm_reset_control_get_optional() by
68
- Replace devm_reset_control_get_optional() by
44
devm_reset_control_get_optional_exclusive() in stm32_omm.c.
69
devm_reset_control_get_optional_exclusive() in stm32_omm.c.
45
- Reintroduce region-memory-names management in stm32_omm.c.
70
- Reintroduce region-memory-names management in stm32_omm.c.
46
- Rename stm32_ospi_tx_poll() and stm32_ospi_tx() to respectively to
71
- Rename stm32_ospi_tx_poll() and stm32_ospi_tx() to respectively to
47
stm32_ospi_poll() and stm32_ospi_xfer() in spi-stm32-ospi.c.
72
stm32_ospi_poll() and stm32_ospi_xfer() in spi-stm32-ospi.c.
48
- Set SPI_CONTROLLER_HALF_DUPLEX in controller flags in spi-stm32-ospi.c.
73
- Set SPI_CONTROLLER_HALF_DUPLEX in controller flags in spi-stm32-ospi.c.
49
74
50
Changes in v2:
75
Changes in v2:
51
- Move STM32 Octo Memory Manager controller driver and bindings from
76
- Move STM32 Octo Memory Manager controller driver and bindings from
52
misc to memory-controllers.
77
misc to memory-controllers.
53
- Update STM32 OSPI controller bindings.
78
- Update STM32 OSPI controller bindings.
54
- Update STM32 Octo Memory Manager controller bindings.
79
- Update STM32 Octo Memory Manager controller bindings.
55
- Update STM32 Octo Memory Manager driver to match bindings update.
80
- Update STM32 Octo Memory Manager driver to match bindings update.
56
- Update DT to match bindings update.
81
- Update DT to match bindings update.
57
82
83
Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com>
84
---
85
Patrice Chotard (7):
86
MAINTAINERS: add entry for STM32 OCTO MEMORY MANAGER driver
87
dt-bindings: memory-controllers: Add STM32 Octo Memory Manager controller
88
memory: Add STM32 Octo Memory Manager driver
89
arm64: dts: st: Add OMM node on stm32mp251
90
arm64: dts: st: Add ospi port1 pinctrl entries in stm32mp25-pinctrl.dtsi
91
arm64: dts: st: Add SPI NOR flash support on stm32mp257f-ev1 board
92
arm64: defconfig: Enable STM32 Octo Memory Manager and OcstoSPI driver
58
93
59
Patrice Chotard (8):
94
.../memory-controllers/st,stm32mp25-omm.yaml | 227 ++++++++++
60
dt-bindings: spi: Add STM32 OSPI controller
95
MAINTAINERS | 6 +
61
spi: stm32: Add OSPI driver
96
arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi | 51 +++
62
dt-bindings: memory-controllers: Add STM32 Octo Memory Manager
97
arch/arm64/boot/dts/st/stm32mp251.dtsi | 54 +++
63
controller
98
arch/arm64/boot/dts/st/stm32mp257f-ev1.dts | 32 ++
64
memory: Add STM32 Octo Memory Manager driver
99
arch/arm64/configs/defconfig | 2 +
65
arm64: dts: st: Add OMM node on stm32mp251
100
drivers/memory/Kconfig | 17 +
66
arm64: dts: st: Add ospi port1 pinctrl entries in
101
drivers/memory/Makefile | 1 +
67
stm32mp25-pinctrl.dtsi
102
drivers/memory/stm32_omm.c | 474 +++++++++++++++++++++
68
arm64: dts: st: Add SPI NOR flash support on stm32mp257f-ev1 board
103
9 files changed, 864 insertions(+)
69
arm64: defconfig: Enable STM32 Octo Memory Manager and OcstoSPI driver
104
---
105
base-commit: 88424abd55ab36c3565898a656589a0a25ecd92f
106
change-id: 20250320-upstream_ospi_v6-d432a8172105
70
107
71
.../memory-controllers/st,stm32mp25-omm.yaml | 204 ++++
108
Best regards,
72
.../bindings/spi/st,stm32mp25-ospi.yaml | 105 ++
73
arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi | 51 +
74
arch/arm64/boot/dts/st/stm32mp251.dtsi | 48 +
75
arch/arm64/boot/dts/st/stm32mp257f-ev1.dts | 32 +
76
arch/arm64/configs/defconfig | 2 +
77
drivers/memory/Kconfig | 17 +
78
drivers/memory/Makefile | 1 +
79
drivers/memory/stm32_omm.c | 522 ++++++++
80
drivers/spi/Kconfig | 10 +
81
drivers/spi/Makefile | 1 +
82
drivers/spi/spi-stm32-ospi.c | 1065 +++++++++++++++++
83
12 files changed, 2058 insertions(+)
84
create mode 100644 Documentation/devicetree/bindings/memory-controllers/st,stm32mp25-omm.yaml
85
create mode 100644 Documentation/devicetree/bindings/spi/st,stm32mp25-ospi.yaml
86
create mode 100644 drivers/memory/stm32_omm.c
87
create mode 100644 drivers/spi/spi-stm32-ospi.c
88
89
--
109
--
90
2.25.1
110
Patrice Chotard <patrice.chotard@foss.st.com>
diff view generated by jsdifflib
Deleted patch
1
From: Patrice Chotard <patrice.chotard@foss.st.com>
2
1
3
Add device tree bindings for the STM32 OSPI controller.
4
5
Main features of the Octo-SPI controller :
6
- support sNOR / sNAND / HyperRAM™ and HyperFlash™ devices.
7
- Three functional modes: indirect, automatic-status polling,
8
memory-mapped.
9
- Up to 4 Gbytes of external memory can be addressed in indirect
10
mode (per physical port and per CS), and up to 256 Mbytes in
11
memory-mapped mode (combined for both physical ports and per CS).
12
- Single-, dual-, quad-, and octal-SPI communication.
13
- Dual-quad communication.
14
- Single data rate (SDR) and double transfer rate (DTR).
15
- Maximum target frequency is 133 MHz for SDR and 133 MHz for DTR.
16
- Data strobe support.
17
- DMA channel for indirect mode.
18
- Double CS mapping that allows two external flash devices to be
19
addressed with a single OCTOSPI controller mapped on a single
20
OCTOSPI port.
21
22
Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com>
23
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
24
---
25
.../bindings/spi/st,stm32mp25-ospi.yaml | 105 ++++++++++++++++++
26
1 file changed, 105 insertions(+)
27
create mode 100644 Documentation/devicetree/bindings/spi/st,stm32mp25-ospi.yaml
28
29
diff --git a/Documentation/devicetree/bindings/spi/st,stm32mp25-ospi.yaml b/Documentation/devicetree/bindings/spi/st,stm32mp25-ospi.yaml
30
new file mode 100644
31
index XXXXXXX..XXXXXXX
32
--- /dev/null
33
+++ b/Documentation/devicetree/bindings/spi/st,stm32mp25-ospi.yaml
34
@@ -XXX,XX +XXX,XX @@
35
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
36
+%YAML 1.2
37
+---
38
+$id: http://devicetree.org/schemas/spi/st,stm32mp25-ospi.yaml#
39
+$schema: http://devicetree.org/meta-schemas/core.yaml#
40
+
41
+title: STMicroelectronics STM32 Octal Serial Peripheral Interface (OSPI)
42
+
43
+maintainers:
44
+ - Patrice Chotard <patrice.chotard@foss.st.com>
45
+
46
+allOf:
47
+ - $ref: spi-controller.yaml#
48
+
49
+properties:
50
+ compatible:
51
+ const: st,stm32mp25-ospi
52
+
53
+ reg:
54
+ maxItems: 1
55
+
56
+ memory-region:
57
+ description:
58
+ Memory region to be used for memory-map read access.
59
+ In memory-mapped mode, read access are performed from the memory
60
+ device using the direct mapping.
61
+ maxItems: 1
62
+
63
+ clocks:
64
+ maxItems: 1
65
+
66
+ interrupts:
67
+ maxItems: 1
68
+
69
+ resets:
70
+ items:
71
+ - description: phandle to OSPI block reset
72
+ - description: phandle to delay block reset
73
+
74
+ dmas:
75
+ maxItems: 2
76
+
77
+ dma-names:
78
+ items:
79
+ - const: tx
80
+ - const: rx
81
+
82
+ st,syscfg-dlyb:
83
+ description: configure OCTOSPI delay block.
84
+ $ref: /schemas/types.yaml#/definitions/phandle-array
85
+ items:
86
+ - description: phandle to syscfg
87
+ - description: register offset within syscfg
88
+
89
+ access-controllers:
90
+ description: phandle to the rifsc device to check access right
91
+ and in some cases, an additional phandle to the rcc device for
92
+ secure clock control.
93
+ items:
94
+ - description: phandle to bus controller
95
+ - description: phandle to clock controller
96
+ minItems: 1
97
+
98
+ power-domains:
99
+ maxItems: 1
100
+
101
+required:
102
+ - compatible
103
+ - reg
104
+ - clocks
105
+ - interrupts
106
+ - st,syscfg-dlyb
107
+
108
+unevaluatedProperties: false
109
+
110
+examples:
111
+ - |
112
+ #include <dt-bindings/clock/st,stm32mp25-rcc.h>
113
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
114
+ #include <dt-bindings/reset/st,stm32mp25-rcc.h>
115
+
116
+ spi@40430000 {
117
+ compatible = "st,stm32mp25-ospi";
118
+ reg = <0x40430000 0x400>;
119
+ memory-region = <&mm_ospi1>;
120
+ interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>;
121
+ dmas = <&hpdma 2 0x62 0x00003121 0x0>,
122
+ <&hpdma 2 0x42 0x00003112 0x0>;
123
+ dma-names = "tx", "rx";
124
+ clocks = <&scmi_clk CK_SCMI_OSPI1>;
125
+ resets = <&scmi_reset RST_SCMI_OSPI1>, <&scmi_reset RST_SCMI_OSPI1DLL>;
126
+ access-controllers = <&rifsc 74>;
127
+ power-domains = <&CLUSTER_PD>;
128
+ st,syscfg-dlyb = <&syscfg 0x1000>;
129
+
130
+ #address-cells = <1>;
131
+ #size-cells = <0>;
132
+
133
+ flash@0 {
134
+ compatible = "jedec,spi-nor";
135
+ reg = <0>;
136
+ spi-rx-bus-width = <4>;
137
+ spi-max-frequency = <108000000>;
138
+ };
139
+ };
140
--
141
2.25.1
142
diff view generated by jsdifflib
1
From: Patrice Chotard <patrice.chotard@foss.st.com>
1
Add myself as STM32 OCTO MEMORY MANAGER maintainer.
2
3
Add STM32 OSPI driver, it supports :
4
- support sNOR / sNAND devices.
5
- Three functional modes: indirect, automatic-status polling,
6
memory-mapped.
7
- Single-, dual-, quad-, and octal-SPI communication.
8
- Dual-quad communication.
9
- Single data rate (SDR).
10
- DMA channel for indirect mode.
11
2
12
Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com>
3
Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com>
13
---
4
---
14
drivers/spi/Kconfig | 10 +
5
MAINTAINERS | 6 ++++++
15
drivers/spi/Makefile | 1 +
6
1 file changed, 6 insertions(+)
16
drivers/spi/spi-stm32-ospi.c | 1065 ++++++++++++++++++++++++++++++++++
17
3 files changed, 1076 insertions(+)
18
create mode 100644 drivers/spi/spi-stm32-ospi.c
19
7
20
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
8
diff --git a/MAINTAINERS b/MAINTAINERS
21
index XXXXXXX..XXXXXXX 100644
9
index XXXXXXX..XXXXXXX 100644
22
--- a/drivers/spi/Kconfig
10
--- a/MAINTAINERS
23
+++ b/drivers/spi/Kconfig
11
+++ b/MAINTAINERS
24
@@ -XXX,XX +XXX,XX @@ config SPI_STM32
12
@@ -XXX,XX +XXX,XX @@ L:    linux-i2c@vger.kernel.org
25
     is not available, the driver automatically falls back to
13
S:    Maintained
26
     PIO mode.
14
F:    drivers/i2c/busses/i2c-stm32*
27
15
28
+config SPI_STM32_OSPI
16
+ST STM32 OCTO MEMORY MANAGER
29
+    tristate "STMicroelectronics STM32 OCTO SPI controller"
17
+M:    Patrice Chotard <patrice.chotard@foss.st.com>
30
+    depends on ARCH_STM32 || COMPILE_TEST
18
+S:    Maintained
31
+    depends on OF
19
+F:    Documentation/devicetree/bindings/memory-controllers/st,stm32mp25-omm.yaml
32
+    depends on SPI_MEM
20
+F:    drivers/memory/stm32_omm.c
33
+    help
34
+     This enables support for the Octo SPI controller in master mode.
35
+     This driver does not support generic SPI. The implementation only
36
+     supports spi-mem interface.
37
+
21
+
38
config SPI_STM32_QSPI
22
ST STM32 SPI DRIVER
39
    tristate "STMicroelectronics STM32 QUAD SPI controller"
23
M:    Alain Volmat <alain.volmat@foss.st.com>
40
    depends on ARCH_STM32 || COMPILE_TEST
24
L:    linux-spi@vger.kernel.org
41
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
25
42
index XXXXXXX..XXXXXXX 100644
43
--- a/drivers/spi/Makefile
44
+++ b/drivers/spi/Makefile
45
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_SPI_SN_F_OSPI)        += spi-sn-f-ospi.o
46
obj-$(CONFIG_SPI_SPRD)            += spi-sprd.o
47
obj-$(CONFIG_SPI_SPRD_ADI)        += spi-sprd-adi.o
48
obj-$(CONFIG_SPI_STM32)         += spi-stm32.o
49
+obj-$(CONFIG_SPI_STM32_OSPI)         += spi-stm32-ospi.o
50
obj-$(CONFIG_SPI_STM32_QSPI)         += spi-stm32-qspi.o
51
obj-$(CONFIG_SPI_ST_SSC4)        += spi-st-ssc4.o
52
obj-$(CONFIG_SPI_SUN4I)            += spi-sun4i.o
53
diff --git a/drivers/spi/spi-stm32-ospi.c b/drivers/spi/spi-stm32-ospi.c
54
new file mode 100644
55
index XXXXXXX..XXXXXXX
56
--- /dev/null
57
+++ b/drivers/spi/spi-stm32-ospi.c
58
@@ -XXX,XX +XXX,XX @@
59
+// SPDX-License-Identifier: GPL-2.0
60
+/*
61
+ * Copyright (C) STMicroelectronics 2025 - All Rights Reserved
62
+ */
63
+
64
+#include <linux/bitfield.h>
65
+#include <linux/clk.h>
66
+#include <linux/delay.h>
67
+#include <linux/dma-mapping.h>
68
+#include <linux/dmaengine.h>
69
+#include <linux/err.h>
70
+#include <linux/errno.h>
71
+#include <linux/interrupt.h>
72
+#include <linux/io.h>
73
+#include <linux/iopoll.h>
74
+#include <linux/mfd/syscon.h>
75
+#include <linux/module.h>
76
+#include <linux/mutex.h>
77
+#include <linux/of.h>
78
+#include <linux/of_address.h>
79
+#include <linux/of_device.h>
80
+#include <linux/of_gpio.h>
81
+#include <linux/of_reserved_mem.h>
82
+#include <linux/pinctrl/consumer.h>
83
+#include <linux/platform_device.h>
84
+#include <linux/pm_runtime.h>
85
+#include <linux/reset.h>
86
+#include <linux/sizes.h>
87
+#include <linux/spi/spi-mem.h>
88
+#include <linux/types.h>
89
+
90
+#define OSPI_CR            0x00
91
+#define CR_EN            BIT(0)
92
+#define CR_ABORT        BIT(1)
93
+#define CR_DMAEN        BIT(2)
94
+#define CR_FTHRES_SHIFT        8
95
+#define CR_TEIE            BIT(16)
96
+#define CR_TCIE            BIT(17)
97
+#define CR_SMIE            BIT(19)
98
+#define CR_APMS            BIT(22)
99
+#define CR_CSSEL        BIT(24)
100
+#define CR_FMODE_MASK        GENMASK(29, 28)
101
+#define CR_FMODE_INDW        (0U)
102
+#define CR_FMODE_INDR        (1U)
103
+#define CR_FMODE_APM        (2U)
104
+#define CR_FMODE_MM        (3U)
105
+
106
+#define OSPI_DCR1        0x08
107
+#define DCR1_DLYBYP        BIT(3)
108
+#define DCR1_DEVSIZE_MASK    GENMASK(20, 16)
109
+#define DCR1_MTYP_MASK        GENMASK(26, 24)
110
+#define DCR1_MTYP_MX_MODE    1
111
+#define DCR1_MTYP_HP_MEMMODE    4
112
+
113
+#define OSPI_DCR2        0x0c
114
+#define DCR2_PRESC_MASK        GENMASK(7, 0)
115
+
116
+#define OSPI_SR            0x20
117
+#define SR_TEF            BIT(0)
118
+#define SR_TCF            BIT(1)
119
+#define SR_FTF            BIT(2)
120
+#define SR_SMF            BIT(3)
121
+#define SR_BUSY            BIT(5)
122
+
123
+#define OSPI_FCR        0x24
124
+#define FCR_CTEF        BIT(0)
125
+#define FCR_CTCF        BIT(1)
126
+#define FCR_CSMF        BIT(3)
127
+
128
+#define OSPI_DLR        0x40
129
+#define OSPI_AR            0x48
130
+#define OSPI_DR            0x50
131
+#define OSPI_PSMKR        0x80
132
+#define OSPI_PSMAR        0x88
133
+
134
+#define OSPI_CCR        0x100
135
+#define CCR_IMODE_MASK        GENMASK(2, 0)
136
+#define CCR_IDTR        BIT(3)
137
+#define CCR_ISIZE_MASK        GENMASK(5, 4)
138
+#define CCR_ADMODE_MASK        GENMASK(10, 8)
139
+#define CCR_ADMODE_8LINES    4
140
+#define CCR_ADDTR        BIT(11)
141
+#define CCR_ADSIZE_MASK        GENMASK(13, 12)
142
+#define CCR_ADSIZE_32BITS    3
143
+#define CCR_DMODE_MASK        GENMASK(26, 24)
144
+#define CCR_DMODE_8LINES    4
145
+#define CCR_DQSE        BIT(29)
146
+#define CCR_DDTR        BIT(27)
147
+#define CCR_BUSWIDTH_0        0x0
148
+#define CCR_BUSWIDTH_1        0x1
149
+#define CCR_BUSWIDTH_2        0x2
150
+#define CCR_BUSWIDTH_4        0x3
151
+#define CCR_BUSWIDTH_8        0x4
152
+
153
+#define OSPI_TCR        0x108
154
+#define TCR_DCYC_MASK        GENMASK(4, 0)
155
+#define TCR_DHQC        BIT(28)
156
+#define TCR_SSHIFT        BIT(30)
157
+
158
+#define OSPI_IR            0x110
159
+
160
+#define STM32_OSPI_MAX_MMAP_SZ    SZ_256M
161
+#define STM32_OSPI_MAX_NORCHIP    2
162
+
163
+#define STM32_FIFO_TIMEOUT_US        30000
164
+#define STM32_ABT_TIMEOUT_US        100000
165
+#define STM32_COMP_TIMEOUT_MS        5000
166
+#define STM32_BUSY_TIMEOUT_US        100000
167
+
168
+
169
+#define STM32_AUTOSUSPEND_DELAY -1
170
+
171
+struct stm32_ospi {
172
+    struct device *dev;
173
+    struct spi_controller *ctrl;
174
+    struct clk *clk;
175
+    struct reset_control *rstc;
176
+
177
+    struct completion data_completion;
178
+    struct completion match_completion;
179
+
180
+    struct dma_chan *dma_chtx;
181
+    struct dma_chan *dma_chrx;
182
+    struct completion dma_completion;
183
+
184
+    void __iomem *regs_base;
185
+    void __iomem *mm_base;
186
+    phys_addr_t regs_phys_base;
187
+    resource_size_t mm_size;
188
+    u32 clk_rate;
189
+    u32 fmode;
190
+    u32 cr_reg;
191
+    u32 dcr_reg;
192
+    u32 flash_presc[STM32_OSPI_MAX_NORCHIP];
193
+    int irq;
194
+    unsigned long status_timeout;
195
+
196
+    /*
197
+     * To protect device configuration, could be different between
198
+     * 2 flash access
199
+     */
200
+    struct mutex lock;
201
+};
202
+
203
+static void stm32_ospi_read_fifo(u8 *val, void __iomem *addr)
204
+{
205
+    *val = readb_relaxed(addr);
206
+}
207
+
208
+static void stm32_ospi_write_fifo(u8 *val, void __iomem *addr)
209
+{
210
+    writeb_relaxed(*val, addr);
211
+}
212
+
213
+static int stm32_ospi_abort(struct stm32_ospi *ospi)
214
+{
215
+    void __iomem *regs_base = ospi->regs_base;
216
+    u32 cr;
217
+    int timeout;
218
+
219
+    cr = readl_relaxed(regs_base + OSPI_CR) | CR_ABORT;
220
+    writel_relaxed(cr, regs_base + OSPI_CR);
221
+
222
+    /* wait clear of abort bit by hw */
223
+    timeout = readl_relaxed_poll_timeout_atomic(regs_base + OSPI_CR,
224
+                         cr, !(cr & CR_ABORT), 1,
225
+                         STM32_ABT_TIMEOUT_US);
226
+
227
+    if (timeout)
228
+        dev_err(ospi->dev, "%s abort timeout:%d\n", __func__, timeout);
229
+
230
+    return timeout;
231
+}
232
+
233
+static int stm32_ospi_poll(struct stm32_ospi *ospi, u8 *buf, u32 len, bool read)
234
+{
235
+    void __iomem *regs_base = ospi->regs_base;
236
+    void (*fifo)(u8 *val, void __iomem *addr);
237
+    u32 sr;
238
+    int ret;
239
+
240
+    if (read)
241
+        fifo = stm32_ospi_read_fifo;
242
+    else
243
+        fifo = stm32_ospi_write_fifo;
244
+
245
+    while (len--) {
246
+        ret = readl_relaxed_poll_timeout_atomic(regs_base + OSPI_SR,
247
+                            sr, sr & SR_FTF, 1,
248
+                            STM32_FIFO_TIMEOUT_US);
249
+        if (ret) {
250
+            dev_err(ospi->dev, "fifo timeout (len:%d stat:%#x)\n",
251
+                len, sr);
252
+            return ret;
253
+        }
254
+        fifo(buf++, regs_base + OSPI_DR);
255
+    }
256
+
257
+    return 0;
258
+}
259
+
260
+static int stm32_ospi_wait_nobusy(struct stm32_ospi *ospi)
261
+{
262
+    u32 sr;
263
+
264
+    return readl_relaxed_poll_timeout_atomic(ospi->regs_base + OSPI_SR,
265
+                         sr, !(sr & SR_BUSY), 1,
266
+                         STM32_BUSY_TIMEOUT_US);
267
+}
268
+
269
+static int stm32_ospi_wait_cmd(struct stm32_ospi *ospi)
270
+{
271
+    void __iomem *regs_base = ospi->regs_base;
272
+    u32 cr, sr;
273
+    int err = 0;
274
+
275
+    if ((readl_relaxed(regs_base + OSPI_SR) & SR_TCF) ||
276
+     ospi->fmode == CR_FMODE_APM)
277
+        goto out;
278
+
279
+    reinit_completion(&ospi->data_completion);
280
+    cr = readl_relaxed(regs_base + OSPI_CR);
281
+    writel_relaxed(cr | CR_TCIE | CR_TEIE, regs_base + OSPI_CR);
282
+
283
+    if (!wait_for_completion_timeout(&ospi->data_completion,
284
+                msecs_to_jiffies(STM32_COMP_TIMEOUT_MS)))
285
+        err = -ETIMEDOUT;
286
+
287
+    sr = readl_relaxed(regs_base + OSPI_SR);
288
+    if (sr & SR_TCF)
289
+        /* avoid false timeout */
290
+        err = 0;
291
+    if (sr & SR_TEF)
292
+        err = -EIO;
293
+
294
+out:
295
+    /* clear flags */
296
+    writel_relaxed(FCR_CTCF | FCR_CTEF, regs_base + OSPI_FCR);
297
+
298
+    if (!err)
299
+        err = stm32_ospi_wait_nobusy(ospi);
300
+
301
+    return err;
302
+}
303
+
304
+static void stm32_ospi_dma_callback(void *arg)
305
+{
306
+    struct completion *dma_completion = arg;
307
+
308
+    complete(dma_completion);
309
+}
310
+
311
+static irqreturn_t stm32_ospi_irq(int irq, void *dev_id)
312
+{
313
+    struct stm32_ospi *ospi = (struct stm32_ospi *)dev_id;
314
+    void __iomem *regs_base = ospi->regs_base;
315
+    u32 cr, sr;
316
+
317
+    cr = readl_relaxed(regs_base + OSPI_CR);
318
+    sr = readl_relaxed(regs_base + OSPI_SR);
319
+
320
+    if (cr & CR_SMIE && sr & SR_SMF) {
321
+        /* disable irq */
322
+        cr &= ~CR_SMIE;
323
+        writel_relaxed(cr, regs_base + OSPI_CR);
324
+        complete(&ospi->match_completion);
325
+
326
+        return IRQ_HANDLED;
327
+    }
328
+
329
+    if (sr & (SR_TEF | SR_TCF)) {
330
+        /* disable irq */
331
+        cr &= ~CR_TCIE & ~CR_TEIE;
332
+        writel_relaxed(cr, regs_base + OSPI_CR);
333
+        complete(&ospi->data_completion);
334
+    }
335
+
336
+    return IRQ_HANDLED;
337
+}
338
+
339
+static void stm32_ospi_dma_setup(struct stm32_ospi *ospi,
340
+             struct dma_slave_config *dma_cfg)
341
+{
342
+    if (dma_cfg && ospi->dma_chrx) {
343
+        if (dmaengine_slave_config(ospi->dma_chrx, dma_cfg)) {
344
+            dev_err(ospi->dev, "dma rx config failed\n");
345
+            dma_release_channel(ospi->dma_chrx);
346
+            ospi->dma_chrx = NULL;
347
+        }
348
+    }
349
+
350
+    if (dma_cfg && ospi->dma_chtx) {
351
+        if (dmaengine_slave_config(ospi->dma_chtx, dma_cfg)) {
352
+            dev_err(ospi->dev, "dma tx config failed\n");
353
+            dma_release_channel(ospi->dma_chtx);
354
+            ospi->dma_chtx = NULL;
355
+        }
356
+    }
357
+
358
+    init_completion(&ospi->dma_completion);
359
+}
360
+
361
+static int stm32_ospi_tx_mm(struct stm32_ospi *ospi,
362
+             const struct spi_mem_op *op)
363
+{
364
+    memcpy_fromio(op->data.buf.in, ospi->mm_base + op->addr.val,
365
+         op->data.nbytes);
366
+    return 0;
367
+}
368
+
369
+static int stm32_ospi_tx_dma(struct stm32_ospi *ospi,
370
+             const struct spi_mem_op *op)
371
+{
372
+    struct dma_async_tx_descriptor *desc;
373
+    void __iomem *regs_base = ospi->regs_base;
374
+    enum dma_transfer_direction dma_dir;
375
+    struct dma_chan *dma_ch;
376
+    struct sg_table sgt;
377
+    dma_cookie_t cookie;
378
+    u32 cr, t_out;
379
+    int err;
380
+
381
+    if (op->data.dir == SPI_MEM_DATA_IN) {
382
+        dma_dir = DMA_DEV_TO_MEM;
383
+        dma_ch = ospi->dma_chrx;
384
+    } else {
385
+        dma_dir = DMA_MEM_TO_DEV;
386
+        dma_ch = ospi->dma_chtx;
387
+    }
388
+
389
+    /*
390
+     * Spi_map_buf return -EINVAL if the buffer is not DMA-able
391
+     * (DMA-able: in vmalloc | kmap | virt_addr_valid)
392
+     */
393
+    err = spi_controller_dma_map_mem_op_data(ospi->ctrl, op, &sgt);
394
+    if (err)
395
+        return err;
396
+
397
+    desc = dmaengine_prep_slave_sg(dma_ch, sgt.sgl, sgt.nents,
398
+                 dma_dir, DMA_PREP_INTERRUPT);
399
+    if (!desc) {
400
+        err = -ENOMEM;
401
+        goto out_unmap;
402
+    }
403
+
404
+    cr = readl_relaxed(regs_base + OSPI_CR);
405
+
406
+    reinit_completion(&ospi->dma_completion);
407
+    desc->callback = stm32_ospi_dma_callback;
408
+    desc->callback_param = &ospi->dma_completion;
409
+    cookie = dmaengine_submit(desc);
410
+    err = dma_submit_error(cookie);
411
+    if (err)
412
+        goto out;
413
+
414
+    dma_async_issue_pending(dma_ch);
415
+
416
+    writel_relaxed(cr | CR_DMAEN, regs_base + OSPI_CR);
417
+
418
+    t_out = sgt.nents * STM32_COMP_TIMEOUT_MS;
419
+    if (!wait_for_completion_timeout(&ospi->dma_completion,
420
+                     msecs_to_jiffies(t_out)))
421
+        err = -ETIMEDOUT;
422
+
423
+    if (err)
424
+        dmaengine_terminate_all(dma_ch);
425
+
426
+out:
427
+    writel_relaxed(cr & ~CR_DMAEN, regs_base + OSPI_CR);
428
+out_unmap:
429
+    spi_controller_dma_unmap_mem_op_data(ospi->ctrl, op, &sgt);
430
+
431
+    return err;
432
+}
433
+
434
+static int stm32_ospi_xfer(struct stm32_ospi *ospi, const struct spi_mem_op *op)
435
+{
436
+    u8 *buf;
437
+
438
+    if (!op->data.nbytes)
439
+        return 0;
440
+
441
+    if (ospi->fmode == CR_FMODE_MM)
442
+        return stm32_ospi_tx_mm(ospi, op);
443
+    else if (((op->data.dir == SPI_MEM_DATA_IN && ospi->dma_chrx) ||
444
+         (op->data.dir == SPI_MEM_DATA_OUT && ospi->dma_chtx)) &&
445
+         op->data.nbytes > 8)
446
+        if (!stm32_ospi_tx_dma(ospi, op))
447
+            return 0;
448
+
449
+    if (op->data.dir == SPI_MEM_DATA_IN)
450
+        buf = op->data.buf.in;
451
+    else
452
+        buf = (u8 *)op->data.buf.out;
453
+
454
+    return stm32_ospi_poll(ospi, buf, op->data.nbytes,
455
+             op->data.dir == SPI_MEM_DATA_IN);
456
+}
457
+
458
+static int stm32_ospi_wait_poll_status(struct stm32_ospi *ospi,
459
+                 const struct spi_mem_op *op)
460
+{
461
+    void __iomem *regs_base = ospi->regs_base;
462
+    u32 cr;
463
+
464
+    reinit_completion(&ospi->match_completion);
465
+    cr = readl_relaxed(regs_base + OSPI_CR);
466
+    writel_relaxed(cr | CR_SMIE, regs_base + OSPI_CR);
467
+
468
+    if (!wait_for_completion_timeout(&ospi->match_completion,
469
+                     msecs_to_jiffies(ospi->status_timeout))) {
470
+        u32 sr = readl_relaxed(regs_base + OSPI_SR);
471
+
472
+        /* Avoid false timeout */
473
+        if (!(sr & SR_SMF))
474
+            return -ETIMEDOUT;
475
+    }
476
+
477
+    writel_relaxed(FCR_CSMF, regs_base + OSPI_FCR);
478
+
479
+    return 0;
480
+}
481
+
482
+static int stm32_ospi_get_mode(u8 buswidth)
483
+{
484
+    switch (buswidth) {
485
+    case 8:
486
+        return CCR_BUSWIDTH_8;
487
+    case 4:
488
+        return CCR_BUSWIDTH_4;
489
+    default:
490
+        return buswidth;
491
+    }
492
+}
493
+
494
+static int stm32_ospi_send(struct spi_device *spi, const struct spi_mem_op *op)
495
+{
496
+    struct stm32_ospi *ospi = spi_controller_get_devdata(spi->controller);
497
+    void __iomem *regs_base = ospi->regs_base;
498
+    u32 ccr, cr, dcr2, tcr;
499
+    int timeout, err = 0, err_poll_status = 0;
500
+    u8 cs = spi->chip_select[ffs(spi->cs_index_mask) - 1];
501
+
502
+    dev_dbg(ospi->dev, "cmd:%#x mode:%d.%d.%d.%d addr:%#llx len:%#x\n",
503
+        op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth,
504
+        op->dummy.buswidth, op->data.buswidth,
505
+        op->addr.val, op->data.nbytes);
506
+
507
+    cr = readl_relaxed(ospi->regs_base + OSPI_CR);
508
+    cr &= ~CR_CSSEL;
509
+    cr |= FIELD_PREP(CR_CSSEL, cs);
510
+    cr &= ~CR_FMODE_MASK;
511
+    cr |= FIELD_PREP(CR_FMODE_MASK, ospi->fmode);
512
+    writel_relaxed(cr, regs_base + OSPI_CR);
513
+
514
+    if (op->data.nbytes)
515
+        writel_relaxed(op->data.nbytes - 1, regs_base + OSPI_DLR);
516
+
517
+    /* set prescaler */
518
+    dcr2 = readl_relaxed(regs_base + OSPI_DCR2);
519
+    dcr2 |= FIELD_PREP(DCR2_PRESC_MASK, ospi->flash_presc[cs]);
520
+    writel_relaxed(dcr2, regs_base + OSPI_DCR2);
521
+
522
+    ccr = FIELD_PREP(CCR_IMODE_MASK, stm32_ospi_get_mode(op->cmd.buswidth));
523
+
524
+    if (op->addr.nbytes) {
525
+        ccr |= FIELD_PREP(CCR_ADMODE_MASK,
526
+                 stm32_ospi_get_mode(op->addr.buswidth));
527
+        ccr |= FIELD_PREP(CCR_ADSIZE_MASK, op->addr.nbytes - 1);
528
+    }
529
+
530
+    tcr = TCR_SSHIFT;
531
+    if (op->dummy.buswidth && op->dummy.nbytes) {
532
+        tcr |= FIELD_PREP(TCR_DCYC_MASK,
533
+                 op->dummy.nbytes * 8 / op->dummy.buswidth);
534
+    }
535
+    writel_relaxed(tcr, regs_base + OSPI_TCR);
536
+
537
+    if (op->data.nbytes) {
538
+        ccr |= FIELD_PREP(CCR_DMODE_MASK,
539
+                 stm32_ospi_get_mode(op->data.buswidth));
540
+    }
541
+
542
+    writel_relaxed(ccr, regs_base + OSPI_CCR);
543
+
544
+    /* set instruction, must be set after ccr register update */
545
+    writel_relaxed(op->cmd.opcode, regs_base + OSPI_IR);
546
+
547
+    if (op->addr.nbytes && ospi->fmode != CR_FMODE_MM)
548
+        writel_relaxed(op->addr.val, regs_base + OSPI_AR);
549
+
550
+    if (ospi->fmode == CR_FMODE_APM)
551
+        err_poll_status = stm32_ospi_wait_poll_status(ospi, op);
552
+
553
+    err = stm32_ospi_xfer(ospi, op);
554
+
555
+    /*
556
+     * Abort in:
557
+     * -error case
558
+     * -read memory map: prefetching must be stopped if we read the last
559
+     * byte of device (device size - fifo size). like device size is not
560
+     * knows, the prefetching is always stop.
561
+     */
562
+    if (err || err_poll_status || ospi->fmode == CR_FMODE_MM)
563
+        goto abort;
564
+
565
+    /* Wait end of tx in indirect mode */
566
+    err = stm32_ospi_wait_cmd(ospi);
567
+    if (err)
568
+        goto abort;
569
+
570
+    return 0;
571
+
572
+abort:
573
+    timeout = stm32_ospi_abort(ospi);
574
+    writel_relaxed(FCR_CTCF | FCR_CSMF, regs_base + OSPI_FCR);
575
+
576
+    if (err || err_poll_status || timeout)
577
+        dev_err(ospi->dev, "%s err:%d err_poll_status:%d abort timeout:%d\n",
578
+            __func__, err, err_poll_status, timeout);
579
+
580
+    return err;
581
+}
582
+
583
+static int stm32_ospi_poll_status(struct spi_mem *mem,
584
+                 const struct spi_mem_op *op,
585
+                 u16 mask, u16 match,
586
+                 unsigned long initial_delay_us,
587
+                 unsigned long polling_rate_us,
588
+                 unsigned long timeout_ms)
589
+{
590
+    struct stm32_ospi *ospi = spi_controller_get_devdata(mem->spi->controller);
591
+    void __iomem *regs_base = ospi->regs_base;
592
+    int ret;
593
+
594
+    ret = pm_runtime_resume_and_get(ospi->dev);
595
+    if (ret < 0)
596
+        return ret;
597
+
598
+    mutex_lock(&ospi->lock);
599
+
600
+    writel_relaxed(mask, regs_base + OSPI_PSMKR);
601
+    writel_relaxed(match, regs_base + OSPI_PSMAR);
602
+    ospi->fmode = CR_FMODE_APM;
603
+    ospi->status_timeout = timeout_ms;
604
+
605
+    ret = stm32_ospi_send(mem->spi, op);
606
+    mutex_unlock(&ospi->lock);
607
+
608
+    pm_runtime_mark_last_busy(ospi->dev);
609
+    pm_runtime_put_autosuspend(ospi->dev);
610
+
611
+    return ret;
612
+}
613
+
614
+static int stm32_ospi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
615
+{
616
+    struct stm32_ospi *ospi = spi_controller_get_devdata(mem->spi->controller);
617
+    int ret;
618
+
619
+    ret = pm_runtime_resume_and_get(ospi->dev);
620
+    if (ret < 0)
621
+        return ret;
622
+
623
+    mutex_lock(&ospi->lock);
624
+    if (op->data.dir == SPI_MEM_DATA_IN && op->data.nbytes)
625
+        ospi->fmode = CR_FMODE_INDR;
626
+    else
627
+        ospi->fmode = CR_FMODE_INDW;
628
+
629
+    ret = stm32_ospi_send(mem->spi, op);
630
+    mutex_unlock(&ospi->lock);
631
+
632
+    pm_runtime_mark_last_busy(ospi->dev);
633
+    pm_runtime_put_autosuspend(ospi->dev);
634
+
635
+    return ret;
636
+}
637
+
638
+static int stm32_ospi_dirmap_create(struct spi_mem_dirmap_desc *desc)
639
+{
640
+    struct stm32_ospi *ospi = spi_controller_get_devdata(desc->mem->spi->controller);
641
+
642
+    if (desc->info.op_tmpl.data.dir == SPI_MEM_DATA_OUT)
643
+        return -EOPNOTSUPP;
644
+
645
+    /* Should never happen, as mm_base == null is an error probe exit condition */
646
+    if (!ospi->mm_base && desc->info.op_tmpl.data.dir == SPI_MEM_DATA_IN)
647
+        return -EOPNOTSUPP;
648
+
649
+    if (!ospi->mm_size)
650
+        return -EOPNOTSUPP;
651
+
652
+    return 0;
653
+}
654
+
655
+static ssize_t stm32_ospi_dirmap_read(struct spi_mem_dirmap_desc *desc,
656
+                 u64 offs, size_t len, void *buf)
657
+{
658
+    struct stm32_ospi *ospi = spi_controller_get_devdata(desc->mem->spi->controller);
659
+    struct spi_mem_op op;
660
+    u32 addr_max;
661
+    int ret;
662
+
663
+    ret = pm_runtime_resume_and_get(ospi->dev);
664
+    if (ret < 0)
665
+        return ret;
666
+
667
+    mutex_lock(&ospi->lock);
668
+    /*
669
+     * Make a local copy of desc op_tmpl and complete dirmap rdesc
670
+     * spi_mem_op template with offs, len and *buf in order to get
671
+     * all needed transfer information into struct spi_mem_op
672
+     */
673
+    memcpy(&op, &desc->info.op_tmpl, sizeof(struct spi_mem_op));
674
+    dev_dbg(ospi->dev, "%s len = 0x%zx offs = 0x%llx buf = 0x%p\n", __func__, len, offs, buf);
675
+
676
+    op.data.nbytes = len;
677
+    op.addr.val = desc->info.offset + offs;
678
+    op.data.buf.in = buf;
679
+
680
+    addr_max = op.addr.val + op.data.nbytes + 1;
681
+    if (addr_max < ospi->mm_size && op.addr.buswidth)
682
+        ospi->fmode = CR_FMODE_MM;
683
+    else
684
+        ospi->fmode = CR_FMODE_INDR;
685
+
686
+    ret = stm32_ospi_send(desc->mem->spi, &op);
687
+    mutex_unlock(&ospi->lock);
688
+
689
+    pm_runtime_mark_last_busy(ospi->dev);
690
+    pm_runtime_put_autosuspend(ospi->dev);
691
+
692
+    return ret ?: len;
693
+}
694
+
695
+static int stm32_ospi_transfer_one_message(struct spi_controller *ctrl,
696
+                     struct spi_message *msg)
697
+{
698
+    struct stm32_ospi *ospi = spi_controller_get_devdata(ctrl);
699
+    struct spi_transfer *transfer;
700
+    struct spi_device *spi = msg->spi;
701
+    struct spi_mem_op op;
702
+    struct gpio_desc *cs_gpiod = spi->cs_gpiod[ffs(spi->cs_index_mask) - 1];
703
+    int ret = 0;
704
+
705
+    if (!cs_gpiod)
706
+        return -EOPNOTSUPP;
707
+
708
+    ret = pm_runtime_resume_and_get(ospi->dev);
709
+    if (ret < 0)
710
+        return ret;
711
+
712
+    mutex_lock(&ospi->lock);
713
+
714
+    gpiod_set_value_cansleep(cs_gpiod, true);
715
+
716
+    list_for_each_entry(transfer, &msg->transfers, transfer_list) {
717
+        u8 dummy_bytes = 0;
718
+
719
+        memset(&op, 0, sizeof(op));
720
+
721
+        dev_dbg(ospi->dev, "tx_buf:%p tx_nbits:%d rx_buf:%p rx_nbits:%d len:%d dummy_data:%d\n",
722
+            transfer->tx_buf, transfer->tx_nbits,
723
+            transfer->rx_buf, transfer->rx_nbits,
724
+            transfer->len, transfer->dummy_data);
725
+
726
+        /*
727
+         * OSPI hardware supports dummy bytes transfer.
728
+         * If current transfer is dummy byte, merge it with the next
729
+         * transfer in order to take into account OSPI block constraint
730
+         */
731
+        if (transfer->dummy_data) {
732
+            op.dummy.buswidth = transfer->tx_nbits;
733
+            op.dummy.nbytes = transfer->len;
734
+            dummy_bytes = transfer->len;
735
+
736
+            /* If happens, means that message is not correctly built */
737
+            if (list_is_last(&transfer->transfer_list, &msg->transfers)) {
738
+                ret = -EINVAL;
739
+                goto end_of_transfer;
740
+            }
741
+
742
+            transfer = list_next_entry(transfer, transfer_list);
743
+        }
744
+
745
+        op.data.nbytes = transfer->len;
746
+
747
+        if (transfer->rx_buf) {
748
+            ospi->fmode = CR_FMODE_INDR;
749
+            op.data.buswidth = transfer->rx_nbits;
750
+            op.data.dir = SPI_MEM_DATA_IN;
751
+            op.data.buf.in = transfer->rx_buf;
752
+        } else {
753
+            ospi->fmode = CR_FMODE_INDW;
754
+            op.data.buswidth = transfer->tx_nbits;
755
+            op.data.dir = SPI_MEM_DATA_OUT;
756
+            op.data.buf.out = transfer->tx_buf;
757
+        }
758
+
759
+        ret = stm32_ospi_send(spi, &op);
760
+        if (ret)
761
+            goto end_of_transfer;
762
+
763
+        msg->actual_length += transfer->len + dummy_bytes;
764
+    }
765
+
766
+end_of_transfer:
767
+    gpiod_set_value_cansleep(cs_gpiod, false);
768
+
769
+    mutex_unlock(&ospi->lock);
770
+
771
+    msg->status = ret;
772
+    spi_finalize_current_message(ctrl);
773
+
774
+    pm_runtime_mark_last_busy(ospi->dev);
775
+    pm_runtime_put_autosuspend(ospi->dev);
776
+
777
+    return ret;
778
+}
779
+
780
+static int stm32_ospi_setup(struct spi_device *spi)
781
+{
782
+    struct spi_controller *ctrl = spi->controller;
783
+    struct stm32_ospi *ospi = spi_controller_get_devdata(ctrl);
784
+    void __iomem *regs_base = ospi->regs_base;
785
+    int ret;
786
+    u8 cs = spi->chip_select[ffs(spi->cs_index_mask) - 1];
787
+
788
+    if (ctrl->busy)
789
+        return -EBUSY;
790
+
791
+    if (!spi->max_speed_hz)
792
+        return -EINVAL;
793
+
794
+    ret = pm_runtime_resume_and_get(ospi->dev);
795
+    if (ret < 0)
796
+        return ret;
797
+
798
+    ospi->flash_presc[cs] = DIV_ROUND_UP(ospi->clk_rate, spi->max_speed_hz) - 1;
799
+
800
+    mutex_lock(&ospi->lock);
801
+
802
+    ospi->cr_reg = CR_APMS | 3 << CR_FTHRES_SHIFT | CR_EN;
803
+    writel_relaxed(ospi->cr_reg, regs_base + OSPI_CR);
804
+
805
+    /* set dcr fsize to max address */
806
+    ospi->dcr_reg = DCR1_DEVSIZE_MASK | DCR1_DLYBYP;
807
+    writel_relaxed(ospi->dcr_reg, regs_base + OSPI_DCR1);
808
+
809
+    mutex_unlock(&ospi->lock);
810
+
811
+    pm_runtime_mark_last_busy(ospi->dev);
812
+    pm_runtime_put_autosuspend(ospi->dev);
813
+
814
+    return 0;
815
+}
816
+
817
+/*
818
+ * No special host constraint, so use default spi_mem_default_supports_op
819
+ * to check supported mode.
820
+ */
821
+static const struct spi_controller_mem_ops stm32_ospi_mem_ops = {
822
+    .exec_op    = stm32_ospi_exec_op,
823
+    .dirmap_create    = stm32_ospi_dirmap_create,
824
+    .dirmap_read    = stm32_ospi_dirmap_read,
825
+    .poll_status    = stm32_ospi_poll_status,
826
+};
827
+
828
+static int stm32_ospi_get_resources(struct platform_device *pdev)
829
+{
830
+    struct device *dev = &pdev->dev;
831
+    struct stm32_ospi *ospi = platform_get_drvdata(pdev);
832
+    struct resource *res;
833
+    struct reserved_mem *rmem = NULL;
834
+    struct device_node *node;
835
+    int ret;
836
+
837
+    ospi->regs_base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
838
+    if (IS_ERR(ospi->regs_base))
839
+        return PTR_ERR(ospi->regs_base);
840
+
841
+    ospi->regs_phys_base = res->start;
842
+
843
+    ospi->clk = devm_clk_get(dev, NULL);
844
+    if (IS_ERR(ospi->clk))
845
+        return dev_err_probe(dev, PTR_ERR(ospi->clk),
846
+                 "Can't get clock\n");
847
+
848
+    ospi->clk_rate = clk_get_rate(ospi->clk);
849
+    if (!ospi->clk_rate) {
850
+        dev_err(dev, "Invalid clock rate\n");
851
+        return -EINVAL;
852
+    }
853
+
854
+    ospi->irq = platform_get_irq(pdev, 0);
855
+    if (ospi->irq < 0) {
856
+        dev_err(dev, "Can't get irq %d\n", ospi->irq);
857
+        return ospi->irq;
858
+    }
859
+
860
+    ret = devm_request_irq(dev, ospi->irq, stm32_ospi_irq, 0,
861
+             dev_name(dev), ospi);
862
+    if (ret) {
863
+        dev_err(dev, "Failed to request irq\n");
864
+        return ret;
865
+    }
866
+
867
+    ospi->rstc = devm_reset_control_array_get_optional_exclusive(dev);
868
+    if (IS_ERR(ospi->rstc))
869
+        return dev_err_probe(dev, PTR_ERR(ospi->rstc),
870
+                 "Can't get reset\n");
871
+
872
+    ospi->dma_chrx = dma_request_chan(dev, "rx");
873
+    if (IS_ERR(ospi->dma_chrx)) {
874
+        ret = PTR_ERR(ospi->dma_chrx);
875
+        ospi->dma_chrx = NULL;
876
+        if (ret == -EPROBE_DEFER)
877
+            goto err_dma;
878
+    }
879
+
880
+    ospi->dma_chtx = dma_request_chan(dev, "tx");
881
+    if (IS_ERR(ospi->dma_chtx)) {
882
+        ret = PTR_ERR(ospi->dma_chtx);
883
+        ospi->dma_chtx = NULL;
884
+        if (ret == -EPROBE_DEFER)
885
+            goto err_dma;
886
+    }
887
+
888
+    node = of_parse_phandle(dev->of_node, "memory-region", 0);
889
+    if (node)
890
+        rmem = of_reserved_mem_lookup(node);
891
+    of_node_put(node);
892
+
893
+    if (rmem) {
894
+        ospi->mm_size = rmem->size;
895
+        ospi->mm_base = devm_ioremap(dev, rmem->base, rmem->size);
896
+        if (IS_ERR(ospi->mm_base)) {
897
+            dev_err(dev, "unable to map memory region: %pa+%pa\n",
898
+                &rmem->base, &rmem->size);
899
+            ret = PTR_ERR(ospi->mm_base);
900
+            goto err_dma;
901
+        }
902
+
903
+        if (ospi->mm_size > STM32_OSPI_MAX_MMAP_SZ) {
904
+            dev_err(dev, "Memory map size outsize bounds\n");
905
+            ret = -EINVAL;
906
+            goto err_dma;
907
+        }
908
+    } else {
909
+        dev_info(dev, "No memory-map region found\n");
910
+    }
911
+
912
+    init_completion(&ospi->data_completion);
913
+    init_completion(&ospi->match_completion);
914
+
915
+    return 0;
916
+
917
+err_dma:
918
+    dev_info(dev, "Can't get all resources (%d)\n", ret);
919
+
920
+    if (ospi->dma_chtx)
921
+        dma_release_channel(ospi->dma_chtx);
922
+    if (ospi->dma_chrx)
923
+        dma_release_channel(ospi->dma_chrx);
924
+
925
+    return ret;
926
+};
927
+
928
+static int stm32_ospi_probe(struct platform_device *pdev)
929
+{
930
+    struct device *dev = &pdev->dev;
931
+    struct spi_controller *ctrl;
932
+    struct stm32_ospi *ospi;
933
+    struct dma_slave_config dma_cfg;
934
+    struct device_node *child;
935
+    int ret;
936
+    u8 spi_flash_count = 0;
937
+
938
+    /*
939
+     * Flash subnodes sanity check:
940
+     * 1 or 2 spi-nand/spi-nor flashes        => supported
941
+     *     All other flash node configuration        => not supported
942
+     */
943
+    for_each_available_child_of_node(dev->of_node, child) {
944
+        if (of_device_is_compatible(child, "jedec,spi-nor") ||
945
+         of_device_is_compatible(child, "spi-nand"))
946
+            spi_flash_count++;
947
+    }
948
+
949
+    if (spi_flash_count == 0 || spi_flash_count > 2) {
950
+        dev_err(dev, "Incorrect DT flash node\n");
951
+        return -ENODEV;
952
+    }
953
+
954
+    ctrl = devm_spi_alloc_host(dev, sizeof(*ospi));
955
+    if (!ctrl)
956
+        return -ENOMEM;
957
+
958
+    ospi = spi_controller_get_devdata(ctrl);
959
+    ospi->ctrl = ctrl;
960
+
961
+    ospi->dev = &pdev->dev;
962
+    platform_set_drvdata(pdev, ospi);
963
+
964
+    ret = stm32_ospi_get_resources(pdev);
965
+    if (ret)
966
+        return ret;
967
+
968
+    memset(&dma_cfg, 0, sizeof(dma_cfg));
969
+    dma_cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
970
+    dma_cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
971
+    dma_cfg.src_addr = ospi->regs_phys_base + OSPI_DR;
972
+    dma_cfg.dst_addr = ospi->regs_phys_base + OSPI_DR;
973
+    dma_cfg.src_maxburst = 4;
974
+    dma_cfg.dst_maxburst = 4;
975
+    stm32_ospi_dma_setup(ospi, &dma_cfg);
976
+
977
+    mutex_init(&ospi->lock);
978
+
979
+    ctrl->mode_bits = SPI_RX_DUAL | SPI_RX_QUAD |
980
+             SPI_TX_DUAL | SPI_TX_QUAD |
981
+             SPI_TX_OCTAL | SPI_RX_OCTAL;
982
+    ctrl->flags = SPI_CONTROLLER_HALF_DUPLEX;
983
+    ctrl->setup = stm32_ospi_setup;
984
+    ctrl->bus_num = -1;
985
+    ctrl->mem_ops = &stm32_ospi_mem_ops;
986
+    ctrl->use_gpio_descriptors = true;
987
+    ctrl->transfer_one_message = stm32_ospi_transfer_one_message;
988
+    ctrl->num_chipselect = STM32_OSPI_MAX_NORCHIP;
989
+    ctrl->dev.of_node = dev->of_node;
990
+
991
+    pm_runtime_enable(ospi->dev);
992
+    pm_runtime_set_autosuspend_delay(ospi->dev, STM32_AUTOSUSPEND_DELAY);
993
+    pm_runtime_use_autosuspend(ospi->dev);
994
+
995
+    ret = pm_runtime_resume_and_get(ospi->dev);
996
+    if (ret < 0)
997
+        goto err_pm_enable;
998
+
999
+    if (ospi->rstc) {
1000
+        reset_control_assert(ospi->rstc);
1001
+        udelay(2);
1002
+        reset_control_deassert(ospi->rstc);
1003
+    }
1004
+
1005
+    ret = spi_register_controller(ctrl);
1006
+    if (ret) {
1007
+        /* Disable ospi */
1008
+        writel_relaxed(0, ospi->regs_base + OSPI_CR);
1009
+        goto err_pm_resume;
1010
+    }
1011
+
1012
+    pm_runtime_mark_last_busy(ospi->dev);
1013
+    pm_runtime_put_autosuspend(ospi->dev);
1014
+
1015
+    return 0;
1016
+
1017
+err_pm_resume:
1018
+    pm_runtime_put_sync_suspend(ospi->dev);
1019
+
1020
+err_pm_enable:
1021
+    pm_runtime_force_suspend(ospi->dev);
1022
+    mutex_destroy(&ospi->lock);
1023
+
1024
+    return ret;
1025
+}
1026
+
1027
+static void stm32_ospi_remove(struct platform_device *pdev)
1028
+{
1029
+    struct stm32_ospi *ospi = platform_get_drvdata(pdev);
1030
+    int ret;
1031
+
1032
+    ret = pm_runtime_resume_and_get(ospi->dev);
1033
+    if (ret < 0)
1034
+        return;
1035
+
1036
+    spi_unregister_controller(ospi->ctrl);
1037
+    /* Disable ospi */
1038
+    writel_relaxed(0, ospi->regs_base + OSPI_CR);
1039
+    mutex_destroy(&ospi->lock);
1040
+
1041
+    if (ospi->dma_chtx)
1042
+        dma_release_channel(ospi->dma_chtx);
1043
+    if (ospi->dma_chrx)
1044
+        dma_release_channel(ospi->dma_chrx);
1045
+
1046
+    pm_runtime_put_sync_suspend(ospi->dev);
1047
+    pm_runtime_force_suspend(ospi->dev);
1048
+}
1049
+
1050
+static int __maybe_unused stm32_ospi_suspend(struct device *dev)
1051
+{
1052
+    struct stm32_ospi *ospi = dev_get_drvdata(dev);
1053
+
1054
+    pinctrl_pm_select_sleep_state(dev);
1055
+
1056
+    return pm_runtime_force_suspend(ospi->dev);
1057
+}
1058
+
1059
+static int __maybe_unused stm32_ospi_resume(struct device *dev)
1060
+{
1061
+    struct stm32_ospi *ospi = dev_get_drvdata(dev);
1062
+    void __iomem *regs_base = ospi->regs_base;
1063
+    int ret;
1064
+
1065
+    ret = pm_runtime_force_resume(ospi->dev);
1066
+    if (ret < 0)
1067
+        return ret;
1068
+
1069
+    pinctrl_pm_select_default_state(dev);
1070
+
1071
+    ret = pm_runtime_resume_and_get(ospi->dev);
1072
+    if (ret < 0)
1073
+        return ret;
1074
+
1075
+    writel_relaxed(ospi->cr_reg, regs_base + OSPI_CR);
1076
+    writel_relaxed(ospi->dcr_reg, regs_base + OSPI_DCR1);
1077
+    pm_runtime_mark_last_busy(ospi->dev);
1078
+    pm_runtime_put_autosuspend(ospi->dev);
1079
+
1080
+    return 0;
1081
+}
1082
+
1083
+static int __maybe_unused stm32_ospi_runtime_suspend(struct device *dev)
1084
+{
1085
+    struct stm32_ospi *ospi = dev_get_drvdata(dev);
1086
+
1087
+    clk_disable_unprepare(ospi->clk);
1088
+
1089
+    return 0;
1090
+}
1091
+
1092
+static int __maybe_unused stm32_ospi_runtime_resume(struct device *dev)
1093
+{
1094
+    struct stm32_ospi *ospi = dev_get_drvdata(dev);
1095
+
1096
+    return clk_prepare_enable(ospi->clk);
1097
+}
1098
+
1099
+static const struct dev_pm_ops stm32_ospi_pm_ops = {
1100
+    SET_SYSTEM_SLEEP_PM_OPS(stm32_ospi_suspend, stm32_ospi_resume)
1101
+    SET_RUNTIME_PM_OPS(stm32_ospi_runtime_suspend,
1102
+             stm32_ospi_runtime_resume, NULL)
1103
+};
1104
+
1105
+static const struct of_device_id stm32_ospi_of_match[] = {
1106
+    { .compatible = "st,stm32mp25-ospi" },
1107
+    {},
1108
+};
1109
+MODULE_DEVICE_TABLE(of, stm32_ospi_of_match);
1110
+
1111
+static struct platform_driver stm32_ospi_driver = {
1112
+    .probe    = stm32_ospi_probe,
1113
+    .remove    = stm32_ospi_remove,
1114
+    .driver    = {
1115
+        .name = "stm32-ospi",
1116
+        .pm = &stm32_ospi_pm_ops,
1117
+        .of_match_table = stm32_ospi_of_match,
1118
+    },
1119
+};
1120
+module_platform_driver(stm32_ospi_driver);
1121
+
1122
+MODULE_DESCRIPTION("STMicroelectronics STM32 OCTO SPI driver");
1123
+MODULE_LICENSE("GPL");
1124
--
26
--
1125
2.25.1
27
2.25.1
diff view generated by jsdifflib
1
From: Patrice Chotard <patrice.chotard@foss.st.com>
2
3
Add bindings for STM32 Octo Memory Manager (OMM) controller.
1
Add bindings for STM32 Octo Memory Manager (OMM) controller.
4
2
5
OMM manages:
3
OMM manages:
6
- the muxing between 2 OSPI busses and 2 output ports.
4
- the muxing between 2 OSPI busses and 2 output ports.
7
There are 4 possible muxing configurations:
5
There are 4 possible muxing configurations:
...
...
14
- the split of the memory area shared between the 2 OSPI instances.
12
- the split of the memory area shared between the 2 OSPI instances.
15
- chip select selection override.
13
- chip select selection override.
16
- the time between 2 transactions in multiplexed mode.
14
- the time between 2 transactions in multiplexed mode.
17
15
18
Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com>
16
Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com>
19
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
20
---
17
---
21
.../memory-controllers/st,stm32mp25-omm.yaml | 204 ++++++++++++++++++
18
.../memory-controllers/st,stm32mp25-omm.yaml | 227 +++++++++++++++++++++
22
1 file changed, 204 insertions(+)
19
1 file changed, 227 insertions(+)
23
create mode 100644 Documentation/devicetree/bindings/memory-controllers/st,stm32mp25-omm.yaml
24
20
25
diff --git a/Documentation/devicetree/bindings/memory-controllers/st,stm32mp25-omm.yaml b/Documentation/devicetree/bindings/memory-controllers/st,stm32mp25-omm.yaml
21
diff --git a/Documentation/devicetree/bindings/memory-controllers/st,stm32mp25-omm.yaml b/Documentation/devicetree/bindings/memory-controllers/st,stm32mp25-omm.yaml
26
new file mode 100644
22
new file mode 100644
27
index XXXXXXX..XXXXXXX
23
index XXXXXXX..XXXXXXX
28
--- /dev/null
24
--- /dev/null
...
...
57
+ "#size-cells":
53
+ "#size-cells":
58
+ const: 1
54
+ const: 1
59
+
55
+
60
+ ranges:
56
+ ranges:
61
+ description: |
57
+ description: |
62
+ Reflects the memory layout with four integer values per OSPI instance.
58
+ Reflects the memory layout per OSPI instance.
63
+ Format:
59
+ Format:
64
+ <chip-select> 0 <registers base address> <size>
60
+ <chip-select> 0 <registers base address> <size>
65
+ minItems: 2
61
+ minItems: 2
66
+ maxItems: 2
62
+ maxItems: 2
67
+
63
+
...
...
74
+ items:
70
+ items:
75
+ - const: regs
71
+ - const: regs
76
+ - const: memory_map
72
+ - const: memory_map
77
+
73
+
78
+ memory-region:
74
+ memory-region:
79
+ description: |
75
+ description:
80
+ Memory region shared between the 2 OCTOSPI instance.
76
+ Memory region shared between the 2 OCTOSPI instance.
81
+ One or two phandle to a node describing a memory mapped region
77
+ One or two phandle to a node describing a memory mapped region
82
+ depending of child number.
78
+ depending of child number.
83
+ minItems: 1
79
+ minItems: 1
84
+ maxItems: 2
80
+ maxItems: 2
85
+
81
+
86
+ memory-region-names:
82
+ memory-region-names:
87
+ description: |
83
+ description:
88
+ OCTOSPI instance's name to which memory region is associated
84
+ Identify to which OSPI instance the memory region belongs to.
89
+ items:
85
+ items:
90
+ enum: [ospi1, ospi2]
86
+ enum: [ospi1, ospi2]
91
+ minItems: 1
87
+ minItems: 1
92
+ maxItems: 2
88
+ maxItems: 2
93
+
89
+
94
+ clocks:
90
+ clocks:
95
+ maxItems: 1
91
+ minItems: 3
92
+ maxItems: 3
93
+
94
+ clock-names:
95
+ items:
96
+ - const: omm
97
+ - const: ospi1
98
+ - const: ospi2
96
+
99
+
97
+ resets:
100
+ resets:
98
+ maxItems: 1
101
+ minItems: 3
102
+ maxItems: 3
103
+
104
+ reset-names:
105
+ items:
106
+ - const: omm
107
+ - const: ospi1
108
+ - const: ospi2
99
+
109
+
100
+ access-controllers:
110
+ access-controllers:
101
+ maxItems: 1
111
+ maxItems: 1
102
+
112
+
103
+ st,syscfg-amcr:
113
+ st,syscfg-amcr:
...
...
116
+ - description: phandle to syscfg
126
+ - description: phandle to syscfg
117
+ - description: register offset within syscfg
127
+ - description: register offset within syscfg
118
+ - description: register bitmask for memory split
128
+ - description: register bitmask for memory split
119
+
129
+
120
+ st,omm-req2ack-ns:
130
+ st,omm-req2ack-ns:
121
+ description: |
131
+ description:
122
+ In multiplexed mode (MUXEN = 1), this field defines the time in
132
+ In multiplexed mode (MUXEN = 1), this field defines the time in
123
+ nanoseconds between two transactions.
133
+ nanoseconds between two transactions.
124
+ default: 0
134
+ default: 0
125
+
135
+
126
+ st,omm-cssel-ovr:
136
+ st,omm-cssel-ovr:
...
...
149
+
159
+
150
+ power-domains:
160
+ power-domains:
151
+ maxItems: 1
161
+ maxItems: 1
152
+
162
+
153
+patternProperties:
163
+patternProperties:
154
+ ^spi@[a-f0-9]+$:
164
+ ^spi@[0-9]:
155
+ type: object
165
+ type: object
156
+ $ref: /schemas/spi/st,stm32mp25-ospi.yaml#
166
+ $ref: /schemas/spi/st,stm32mp25-ospi.yaml#
157
+ description: Required spi child node
167
+ description: Required spi child node
158
+
168
+
159
+required:
169
+required:
160
+ - compatible
170
+ - compatible
161
+ - reg
171
+ - reg
162
+ - "#address-cells"
172
+ - "#address-cells"
163
+ - "#size-cells"
173
+ - "#size-cells"
164
+ - clocks
174
+ - clocks
175
+ - clock-names
176
+ - resets
177
+ - reset-names
165
+ - st,syscfg-amcr
178
+ - st,syscfg-amcr
166
+ - ranges
179
+ - ranges
167
+
180
+
168
+additionalProperties: false
181
+additionalProperties: false
169
+
182
+
...
...
185
+ &ospi_port1_cs0_pins_a>;
198
+ &ospi_port1_cs0_pins_a>;
186
+ pinctrl-1 = <&ospi_port1_clk_sleep_pins_a
199
+ pinctrl-1 = <&ospi_port1_clk_sleep_pins_a
187
+ &ospi_port1_io03_sleep_pins_a
200
+ &ospi_port1_io03_sleep_pins_a
188
+ &ospi_port1_cs0_sleep_pins_a>;
201
+ &ospi_port1_cs0_sleep_pins_a>;
189
+ pinctrl-names = "default", "sleep";
202
+ pinctrl-names = "default", "sleep";
190
+ clocks = <&rcc CK_BUS_OSPIIOM>;
203
+ clocks = <&rcc CK_BUS_OSPIIOM>,
191
+ resets = <&rcc OSPIIOM_R>;
204
+ <&scmi_clk CK_SCMI_OSPI1>,
205
+ <&scmi_clk CK_SCMI_OSPI2>;
206
+ clock-names = "omm", "ospi1", "ospi2";
207
+ resets = <&rcc OSPIIOM_R>,
208
+ <&scmi_reset RST_SCMI_OSPI1>,
209
+ <&scmi_reset RST_SCMI_OSPI2>;
210
+ reset-names = "omm", "ospi1", "ospi2";
192
+ access-controllers = <&rifsc 111>;
211
+ access-controllers = <&rifsc 111>;
193
+ power-domains = <&CLUSTER_PD>;
212
+ power-domains = <&CLUSTER_PD>;
194
+ #address-cells = <2>;
213
+ #address-cells = <2>;
195
+ #size-cells = <1>;
214
+ #size-cells = <1>;
196
+ st,syscfg-amcr = <&syscfg 0x2c00 0x7>;
215
+ st,syscfg-amcr = <&syscfg 0x2c00 0x7>;
197
+ st,omm-req2ack-ns = <0>;
216
+ st,omm-req2ack-ns = <0>;
198
+ st,omm-mux = <0>;
217
+ st,omm-mux = <0>;
199
+ st,omm-cssel-ovr = <0>;
218
+ st,omm-cssel-ovr = <0>;
200
+
219
+
201
+ spi@40430000 {
220
+ spi@0 {
202
+ compatible = "st,stm32mp25-ospi";
221
+ compatible = "st,stm32mp25-ospi";
203
+ reg = <0 0 0x400>;
222
+ reg = <0 0 0x400>;
204
+ memory-region = <&mm_ospi1>;
223
+ memory-region = <&mm_ospi1>;
205
+ interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>;
224
+ interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>;
206
+ dmas = <&hpdma 2 0x62 0x00003121 0x0>,
225
+ dmas = <&hpdma 2 0x62 0x00003121 0x0>,
...
...
213
+ #address-cells = <1>;
232
+ #address-cells = <1>;
214
+ #size-cells = <0>;
233
+ #size-cells = <0>;
215
+ st,syscfg-dlyb = <&syscfg 0x1000>;
234
+ st,syscfg-dlyb = <&syscfg 0x1000>;
216
+ };
235
+ };
217
+
236
+
218
+ spi@40440000 {
237
+ spi@1 {
219
+ compatible = "st,stm32mp25-ospi";
238
+ compatible = "st,stm32mp25-ospi";
220
+ reg = <1 0 0x400>;
239
+ reg = <1 0 0x400>;
221
+ memory-region = <&mm_ospi1>;
240
+ memory-region = <&mm_ospi1>;
222
+ interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
241
+ interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
223
+ dmas = <&hpdma 3 0x62 0x00003121 0x0>,
242
+ dmas = <&hpdma 3 0x62 0x00003121 0x0>,
...
...
230
+ #address-cells = <1>;
249
+ #address-cells = <1>;
231
+ #size-cells = <0>;
250
+ #size-cells = <0>;
232
+ st,syscfg-dlyb = <&syscfg 0x1000>;
251
+ st,syscfg-dlyb = <&syscfg 0x1000>;
233
+ };
252
+ };
234
+ };
253
+ };
254
235
--
255
--
236
2.25.1
256
2.25.1
diff view generated by jsdifflib
1
From: Patrice Chotard <patrice.chotard@foss.st.com>
2
3
Octo Memory Manager driver (OMM) manages:
1
Octo Memory Manager driver (OMM) manages:
4
- the muxing between 2 OSPI busses and 2 output ports.
2
- the muxing between 2 OSPI busses and 2 output ports.
5
There are 4 possible muxing configurations:
3
There are 4 possible muxing configurations:
6
- direct mode (no multiplexing): OSPI1 output is on port 1 and OSPI2
4
- direct mode (no multiplexing): OSPI1 output is on port 1 and OSPI2
7
output is on port 2
5
output is on port 2
...
...
12
- the split of the memory area shared between the 2 OSPI instances.
10
- the split of the memory area shared between the 2 OSPI instances.
13
- chip select selection override.
11
- chip select selection override.
14
- the time between 2 transactions in multiplexed mode.
12
- the time between 2 transactions in multiplexed mode.
15
- check firewall access.
13
- check firewall access.
16
14
15
Signed-off-by: Christophe Kerello <christophe.kerello@foss.st.com>
17
Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com>
16
Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com>
18
Signed-off-by: Christophe Kerello <christophe.kerello@foss.st.com>
19
---
17
---
20
drivers/memory/Kconfig | 17 ++
18
drivers/memory/Kconfig | 17 ++
21
drivers/memory/Makefile | 1 +
19
drivers/memory/Makefile | 1 +
22
drivers/memory/stm32_omm.c | 522 +++++++++++++++++++++++++++++++++++++
20
drivers/memory/stm32_omm.c | 474 +++++++++++++++++++++++++++++++++++++++++++++
23
3 files changed, 540 insertions(+)
21
3 files changed, 492 insertions(+)
24
create mode 100644 drivers/memory/stm32_omm.c
25
22
26
diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
23
diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
27
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
28
--- a/drivers/memory/Kconfig
25
--- a/drivers/memory/Kconfig
29
+++ b/drivers/memory/Kconfig
26
+++ b/drivers/memory/Kconfig
...
...
95
+#define CR_CSSEL_OVR_EN        BIT(4)
92
+#define CR_CSSEL_OVR_EN        BIT(4)
96
+#define CR_CSSEL_OVR_MASK    GENMASK(6, 5)
93
+#define CR_CSSEL_OVR_MASK    GENMASK(6, 5)
97
+#define CR_REQ2ACK_MASK        GENMASK(23, 16)
94
+#define CR_REQ2ACK_MASK        GENMASK(23, 16)
98
+
95
+
99
+#define OMM_CHILD_NB        2
96
+#define OMM_CHILD_NB        2
100
+
97
+#define OMM_CLK_NB        3
101
+struct ospi_child {
102
+    struct device *dev;
103
+    struct device_node *node;
104
+    struct clk *clk;
105
+};
106
+
98
+
107
+struct stm32_omm {
99
+struct stm32_omm {
108
+    struct ospi_child child[OMM_CHILD_NB];
109
+    struct resource *mm_res;
100
+    struct resource *mm_res;
110
+    struct clk *clk;
101
+    struct clk_bulk_data clk_bulk[OMM_CLK_NB];
111
+    void __iomem *io_base;
102
+    void __iomem *io_base;
112
+    u32 cr;
103
+    u32 cr;
113
+    u8 nb_child;
104
+    u8 nb_child;
114
+    bool restore_omm;
105
+    bool restore_omm;
115
+};
106
+};
116
+
107
+
117
+static int stm32_omm_set_amcr(struct device *dev, bool set)
108
+static int stm32_omm_set_amcr(struct device *dev, bool set)
118
+{
109
+{
119
+    struct stm32_omm *omm = dev_get_drvdata(dev);
110
+    struct stm32_omm *omm = dev_get_drvdata(dev);
111
+    resource_size_t mm_ospi2_size = 0;
112
+    static const char * const mm_name[] = { "ospi1", "ospi2" };
120
+    struct regmap *syscfg_regmap;
113
+    struct regmap *syscfg_regmap;
121
+    struct device_node *node;
114
+    struct device_node *node;
122
+    struct resource res, res1;
115
+    struct resource res, res1;
123
+    resource_size_t mm_ospi2_size = 0;
124
+    static const char * const mm_name[] = { "ospi1", "ospi2" };
125
+    u32 amcr_base, amcr_mask;
116
+    u32 amcr_base, amcr_mask;
126
+    int ret, idx;
117
+    int ret, idx;
127
+    unsigned int i, amcr, read_amcr;
118
+    unsigned int i, amcr, read_amcr;
128
+
119
+
129
+    for (i = 0; i < omm->nb_child; i++) {
120
+    for (i = 0; i < omm->nb_child; i++) {
...
...
169
+            }
160
+            }
170
+        }
161
+        }
171
+    }
162
+    }
172
+
163
+
173
+    syscfg_regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "st,syscfg-amcr");
164
+    syscfg_regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "st,syscfg-amcr");
174
+    if (IS_ERR(syscfg_regmap)) {
165
+    if (IS_ERR(syscfg_regmap))
175
+        dev_err(dev, "Failed to get st,syscfg-amcr property\n");
166
+        return dev_err_probe(dev, PTR_ERR(syscfg_regmap),
176
+        return PTR_ERR(syscfg_regmap);
167
+                 "Failed to get st,syscfg-amcr property\n");
177
+    }
178
+
168
+
179
+    ret = of_property_read_u32_index(dev->of_node, "st,syscfg-amcr", 1,
169
+    ret = of_property_read_u32_index(dev->of_node, "st,syscfg-amcr", 1,
180
+                     &amcr_base);
170
+                     &amcr_base);
181
+    if (ret)
171
+    if (ret)
182
+        return ret;
172
+        return ret;
...
...
201
+    }
191
+    }
202
+
192
+
203
+    return ret;
193
+    return ret;
204
+}
194
+}
205
+
195
+
206
+static int stm32_omm_enable_child_clock(struct device *dev, bool enable)
196
+static int stm32_omm_toggle_child_clock(struct device *dev, bool enable)
207
+{
197
+{
208
+    /* As there is only 2 children, remember first child in case of error */
198
+    /* As there is only 2 children, remember first child in case of error */
209
+    struct clk *first_child_clk = NULL;
199
+    struct clk *first_child_clk = NULL;
210
+    struct stm32_omm *omm = dev_get_drvdata(dev);
200
+    struct stm32_omm *omm = dev_get_drvdata(dev);
211
+    u8 i;
201
+    u8 i;
212
+    int ret;
202
+    int ret;
213
+
203
+
214
+    for (i = 0; i < omm->nb_child; i++) {
204
+    for (i = 0; i < omm->nb_child; i++) {
215
+        if (enable) {
205
+        if (enable) {
216
+            ret = clk_prepare_enable(omm->child[i].clk);
206
+            ret = clk_prepare_enable(omm->clk_bulk[i + 1].clk);
217
+            if (ret) {
207
+            if (ret) {
218
+                if (first_child_clk)
208
+                if (first_child_clk)
219
+                    clk_disable_unprepare(first_child_clk);
209
+                    clk_disable_unprepare(first_child_clk);
220
+
210
+
221
+                dev_err(dev, "Can not enable clock\n");
211
+                dev_err(dev, "Can not enable clock\n");
222
+                return ret;
212
+                return ret;
223
+            }
213
+            }
224
+        } else {
214
+        } else {
225
+            clk_disable_unprepare(omm->child[i].clk);
215
+            clk_disable_unprepare(omm->clk_bulk[i + 1].clk);
226
+        }
216
+        }
227
+
217
+
228
+        first_child_clk = omm->child[i].clk;
218
+        first_child_clk = omm->clk_bulk[i + 1].clk;
229
+    }
219
+    }
230
+
220
+
231
+    return 0;
221
+    return 0;
232
+}
222
+}
233
+
223
+
234
+static int stm32_omm_configure(struct device *dev)
224
+static int stm32_omm_disable_child(struct device *dev)
235
+{
225
+{
236
+    struct stm32_omm *omm = dev_get_drvdata(dev);
226
+    static const char * const resets_name[] = {"ospi1", "ospi2"};
237
+    struct reset_control *rstc;
227
+    struct stm32_omm *omm = dev_get_drvdata(dev);
238
+    unsigned long clk_rate, clk_rate_max = 0;
228
+    struct reset_control *reset;
239
+    int ret;
229
+    int ret;
240
+    u8 i;
230
+    u8 i;
231
+
232
+    ret = stm32_omm_toggle_child_clock(dev, true);
233
+    if (!ret)
234
+        return ret;
235
+
236
+    for (i = 0; i < omm->nb_child; i++) {
237
+        reset = reset_control_get_exclusive(dev, resets_name[i]);
238
+        if (IS_ERR(reset)) {
239
+            dev_err(dev, "Can't get %s reset\n", resets_name[i]);
240
+            return PTR_ERR(reset);
241
+        };
242
+
243
+        /* reset OSPI to ensure CR_EN bit is set to 0 */
244
+        reset_control_assert(reset);
245
+        udelay(2);
246
+        reset_control_deassert(reset);
247
+
248
+        reset_control_put(reset);
249
+    }
250
+
251
+    return stm32_omm_toggle_child_clock(dev, false);
252
+}
253
+
254
+static int stm32_omm_configure(struct device *dev)
255
+{
256
+    static const char * const clocks_name[] = {"omm", "ospi1", "ospi2"};
257
+    struct stm32_omm *omm = dev_get_drvdata(dev);
258
+    unsigned long clk_rate_max = 0;
241
+    u32 mux = 0;
259
+    u32 mux = 0;
242
+    u32 cssel_ovr = 0;
260
+    u32 cssel_ovr = 0;
243
+    u32 req2ack = 0;
261
+    u32 req2ack = 0;
244
+
262
+    struct reset_control *rstc;
245
+    omm->clk = devm_clk_get(dev, NULL);
263
+    unsigned long clk_rate;
246
+    if (IS_ERR(omm->clk)) {
264
+    int ret;
247
+        dev_err(dev, "Failed to get OMM clock (%ld)\n",
265
+    u8 i;
248
+            PTR_ERR(omm->clk));
266
+
249
+
267
+    for (i = 0; i < OMM_CLK_NB; i++)
250
+        return PTR_ERR(omm->clk);
268
+        omm->clk_bulk[i].id = clocks_name[i];
251
+    }
269
+
270
+    /* retrieve OMM, OSPI1 and OSPI2 clocks */
271
+    ret = devm_clk_bulk_get(dev, OMM_CLK_NB, omm->clk_bulk);
272
+    if (ret)
273
+        return dev_err_probe(dev, ret, "Failed to get OMM/OSPI's clocks\n");
274
+
275
+    /* Ensure both OSPI instance are disabled before configuring OMM */
276
+    ret = stm32_omm_disable_child(dev);
277
+    if (ret)
278
+        return ret;
252
+
279
+
253
+    ret = pm_runtime_resume_and_get(dev);
280
+    ret = pm_runtime_resume_and_get(dev);
254
+    if (ret < 0)
281
+    if (ret < 0)
255
+        return ret;
282
+        return ret;
256
+
283
+
257
+    /* parse children's clock */
284
+    /* parse children's clock */
258
+    for (i = 0; i < omm->nb_child; i++) {
285
+    for (i = 1; i <= omm->nb_child; i++) {
259
+        clk_rate = clk_get_rate(omm->child[i].clk);
286
+        clk_rate = clk_get_rate(omm->clk_bulk[i].clk);
260
+        if (!clk_rate) {
287
+        if (!clk_rate) {
261
+            dev_err(dev, "Invalid clock rate\n");
288
+            dev_err(dev, "Invalid clock rate\n");
262
+            pm_runtime_disable(dev);
263
+            goto err_clk_disable;
289
+            goto err_clk_disable;
264
+        }
290
+        }
265
+
291
+
266
+        if (clk_rate > clk_rate_max)
292
+        if (clk_rate > clk_rate_max)
267
+            clk_rate_max = clk_rate;
293
+            clk_rate_max = clk_rate;
268
+    }
294
+    }
269
+
295
+
270
+    rstc = devm_reset_control_get_optional_exclusive(dev, NULL);
296
+    rstc = devm_reset_control_get_exclusive(dev, "omm");
271
+    if (IS_ERR(rstc)) {
297
+    if (IS_ERR(rstc))
272
+        ret = dev_err_probe(dev, PTR_ERR(rstc), "reset get failed\n");
298
+        return dev_err_probe(dev, PTR_ERR(rstc), "reset get failed\n");
273
+        pm_runtime_disable(dev);
274
+        goto err_clk_disable;
275
+    }
276
+
299
+
277
+    reset_control_assert(rstc);
300
+    reset_control_assert(rstc);
278
+    udelay(2);
301
+    udelay(2);
279
+    reset_control_deassert(rstc);
302
+    reset_control_deassert(rstc);
280
+
303
+
...
...
299
+
322
+
300
+            /*
323
+            /*
301
+             * If the mux is enabled, the 2 OSPI clocks have to be
324
+             * If the mux is enabled, the 2 OSPI clocks have to be
302
+             * always enabled
325
+             * always enabled
303
+             */
326
+             */
304
+            ret = stm32_omm_enable_child_clock(dev, true);
327
+            ret = stm32_omm_toggle_child_clock(dev, true);
305
+            if (ret) {
328
+            if (ret)
306
+                pm_runtime_disable(dev);
307
+                goto err_clk_disable;
329
+                goto err_clk_disable;
308
+            }
309
+        }
330
+        }
310
+
331
+
311
+        omm->cr &= ~CR_MUXENMODE_MASK;
332
+        omm->cr &= ~CR_MUXENMODE_MASK;
312
+        omm->cr |= FIELD_PREP(CR_MUXENMODE_MASK, mux);
333
+        omm->cr |= FIELD_PREP(CR_MUXENMODE_MASK, mux);
313
+    }
334
+    }
...
...
329
+    pm_runtime_put_sync_suspend(dev);
350
+    pm_runtime_put_sync_suspend(dev);
330
+
351
+
331
+    return ret;
352
+    return ret;
332
+}
353
+}
333
+
354
+
334
+static int stm32_omm_check_access(struct device *dev, struct device_node *np)
355
+static int stm32_omm_check_access(struct device_node *np)
335
+{
356
+{
336
+    struct stm32_firewall firewall;
357
+    struct stm32_firewall firewall;
337
+    int ret;
358
+    int ret;
338
+
359
+
339
+    ret = stm32_firewall_get_firewall(np, &firewall, 1);
360
+    ret = stm32_firewall_get_firewall(np, &firewall, 1);
340
+    if (ret)
361
+    if (ret)
341
+        return ret;
362
+        return ret;
342
+
363
+
343
+    return stm32_firewall_grant_access(&firewall);
364
+    return stm32_firewall_grant_access(&firewall);
344
+}
365
+}
345
+
366
+
346
+static int stm32_omm_disable_child(struct device *dev)
367
+static int stm32_omm_probe(struct platform_device *pdev)
347
+{
368
+{
348
+    struct stm32_omm *omm = dev_get_drvdata(dev);
369
+    struct device *dev = &pdev->dev;
349
+    struct reset_control *reset;
370
+    u8 child_access_granted = 0;
371
+    struct stm32_omm *omm;
350
+    int ret;
372
+    int ret;
351
+    u8 i;
352
+
353
+    for (i = 0; i < omm->nb_child; i++) {
354
+        ret = clk_prepare_enable(omm->child[i].clk);
355
+        if (ret) {
356
+            dev_err(dev, "Can not enable clock\n");
357
+            return ret;
358
+        }
359
+
360
+        reset = of_reset_control_get_exclusive(omm->child[i].node, 0);
361
+        if (IS_ERR(reset)) {
362
+            dev_err(dev, "Can't get child reset\n");
363
+            return PTR_ERR(reset);
364
+        };
365
+
366
+        /* reset OSPI to ensure CR_EN bit is set to 0 */
367
+        reset_control_assert(reset);
368
+        udelay(2);
369
+        reset_control_deassert(reset);
370
+
371
+        reset_control_put(reset);
372
+        clk_disable_unprepare(omm->child[i].clk);
373
+    }
374
+
375
+    return 0;
376
+}
377
+
378
+static int stm32_omm_probe(struct platform_device *pdev)
379
+{
380
+    struct platform_device *vdev;
381
+    struct device *dev = &pdev->dev;
382
+    struct stm32_omm *omm;
383
+    struct clk *clk;
384
+    int ret;
385
+    u8 child_access_granted = 0;
386
+    u8 i, j;
387
+    bool child_access[OMM_CHILD_NB];
388
+
373
+
389
+    omm = devm_kzalloc(dev, sizeof(*omm), GFP_KERNEL);
374
+    omm = devm_kzalloc(dev, sizeof(*omm), GFP_KERNEL);
390
+    if (!omm)
375
+    if (!omm)
391
+        return -ENOMEM;
376
+        return -ENOMEM;
392
+
377
+
...
...
400
+
385
+
401
+    /* check child's access */
386
+    /* check child's access */
402
+    for_each_child_of_node_scoped(dev->of_node, child) {
387
+    for_each_child_of_node_scoped(dev->of_node, child) {
403
+        if (omm->nb_child >= OMM_CHILD_NB) {
388
+        if (omm->nb_child >= OMM_CHILD_NB) {
404
+            dev_err(dev, "Bad DT, found too much children\n");
389
+            dev_err(dev, "Bad DT, found too much children\n");
405
+            ret = -E2BIG;
390
+            return -E2BIG;
406
+            goto err_clk_release;
391
+        }
407
+        }
392
+
408
+
393
+        if (!of_device_is_compatible(child, "st,stm32mp25-omi"))
409
+        if (!of_device_is_compatible(child, "st,stm32mp25-ospi")) {
394
+            return -EINVAL;
410
+            ret = -EINVAL;
395
+
411
+            goto err_clk_release;
396
+        ret = stm32_omm_check_access(child);
412
+        }
413
+
414
+        ret = stm32_omm_check_access(dev, child);
415
+        if (ret < 0 && ret != -EACCES)
397
+        if (ret < 0 && ret != -EACCES)
416
+            goto err_clk_release;
398
+            return ret;
417
+
399
+
418
+        child_access[omm->nb_child] = false;
400
+        if (!ret)
419
+        if (!ret) {
420
+            child_access_granted++;
401
+            child_access_granted++;
421
+            child_access[omm->nb_child] = true;
402
+
422
+        }
423
+
424
+        omm->child[omm->nb_child].node = child;
425
+
426
+        clk = of_clk_get(child, 0);
427
+        if (IS_ERR(clk)) {
428
+            dev_err(dev, "Can't get child clock\n");
429
+            ret = PTR_ERR(clk);
430
+            goto err_clk_release;
431
+        };
432
+
433
+        omm->child[omm->nb_child].clk = clk;
434
+        omm->nb_child++;
403
+        omm->nb_child++;
435
+    }
404
+    }
436
+
405
+
437
+    if (omm->nb_child != OMM_CHILD_NB) {
406
+    if (omm->nb_child != OMM_CHILD_NB)
438
+        ret = -EINVAL;
407
+        return -EINVAL;
439
+        goto err_clk_release;
440
+    }
441
+
408
+
442
+    platform_set_drvdata(pdev, omm);
409
+    platform_set_drvdata(pdev, omm);
443
+
410
+
444
+    pm_runtime_enable(dev);
411
+    pm_runtime_enable(dev);
445
+
412
+
446
+    /* check if OMM's resource access is granted */
413
+    /* check if OMM's resource access is granted */
447
+    ret = stm32_omm_check_access(dev, dev->of_node);
414
+    ret = stm32_omm_check_access(dev->of_node);
448
+    if (ret < 0 && ret != -EACCES)
415
+    if (ret < 0 && ret != -EACCES)
449
+        goto err_clk_release;
416
+        goto error;
450
+
417
+
451
+    if (!ret && child_access_granted == OMM_CHILD_NB) {
418
+    if (!ret && child_access_granted == OMM_CHILD_NB) {
452
+        /* Ensure both OSPI instance are disabled before configuring OMM */
453
+        ret = stm32_omm_disable_child(dev);
454
+        if (ret)
455
+            goto err_clk_release;
456
+
457
+        ret = stm32_omm_configure(dev);
419
+        ret = stm32_omm_configure(dev);
458
+        if (ret)
420
+        if (ret)
459
+            goto err_clk_release;
421
+            goto error;
460
+    } else {
422
+    } else {
461
+        dev_dbg(dev, "Octo Memory Manager resource's access not granted\n");
423
+        dev_dbg(dev, "Octo Memory Manager resource's access not granted\n");
462
+        /*
424
+        /*
463
+         * AMCR can't be set, so check if current value is coherent
425
+         * AMCR can't be set, so check if current value is coherent
464
+         * with memory-map areas defined in DT
426
+         * with memory-map areas defined in DT
465
+         */
427
+         */
466
+        ret = stm32_omm_set_amcr(dev, false);
428
+        ret = stm32_omm_set_amcr(dev, false);
467
+        if (ret)
429
+        if (ret)
468
+            goto err_clk_release;
430
+            goto error;
469
+    }
431
+    }
470
+
432
+
471
+    /* for each child, if resource access is granted and status "okay", probe it */
433
+    ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
472
+    for (i = 0; i < omm->nb_child; i++) {
434
+    if (ret) {
473
+        if (!child_access[i] || !of_device_is_available(omm->child[i].node))
435
+        dev_err(dev, "Failed to create Octo Memory Manager child\n");
474
+            continue;
436
+        of_platform_depopulate(dev);
475
+
437
+        ret = -EINVAL;
476
+        vdev = of_platform_device_create(omm->child[i].node, NULL, NULL);
438
+        goto error;
477
+        if (!vdev) {
439
+    }
478
+            dev_err(dev, "Failed to create Octo Memory Manager child\n");
479
+            for (j = i; j > 0; --j) {
480
+                if (omm->child[j].dev)
481
+                    of_platform_device_destroy(omm->child[j].dev, NULL);
482
+            }
483
+
484
+            ret = -EINVAL;
485
+            goto err_clk_release;
486
+        }
487
+        omm->child[i].dev = &vdev->dev;
488
+    }
489
+
490
+err_clk_release:
491
+    for (i = 0; i < omm->nb_child; i++)
492
+        clk_put(omm->child[i].clk);
493
+
440
+
494
+    return ret;
441
+    return ret;
442
+
443
+error:
444
+    pm_runtime_disable(dev);
445
+
446
+    return ret;
447
+
495
+}
448
+}
496
+
449
+
497
+static void stm32_omm_remove(struct platform_device *pdev)
450
+static void stm32_omm_remove(struct platform_device *pdev)
498
+{
451
+{
499
+    struct stm32_omm *omm = platform_get_drvdata(pdev);
452
+    struct stm32_omm *omm = platform_get_drvdata(pdev);
500
+    int i;
453
+
501
+
454
+    of_platform_depopulate(&pdev->dev);
502
+    for (i = 0; i < omm->nb_child; i++)
503
+        if (omm->child[i].dev)
504
+            of_platform_device_destroy(omm->child[i].dev, NULL);
505
+
506
+    if (omm->cr & CR_MUXEN)
455
+    if (omm->cr & CR_MUXEN)
507
+        stm32_omm_enable_child_clock(&pdev->dev, false);
456
+        stm32_omm_toggle_child_clock(&pdev->dev, false);
508
+
457
+
509
+    pm_runtime_disable(&pdev->dev);
458
+    pm_runtime_disable(&pdev->dev);
510
+}
459
+}
511
+
460
+
512
+static const struct of_device_id stm32_omm_of_match[] = {
461
+static const struct of_device_id stm32_omm_of_match[] = {
...
...
517
+
466
+
518
+static int __maybe_unused stm32_omm_runtime_suspend(struct device *dev)
467
+static int __maybe_unused stm32_omm_runtime_suspend(struct device *dev)
519
+{
468
+{
520
+    struct stm32_omm *omm = dev_get_drvdata(dev);
469
+    struct stm32_omm *omm = dev_get_drvdata(dev);
521
+
470
+
522
+    clk_disable_unprepare(omm->clk);
471
+    clk_disable_unprepare(omm->clk_bulk[0].clk);
523
+
472
+
524
+    return 0;
473
+    return 0;
525
+}
474
+}
526
+
475
+
527
+static int __maybe_unused stm32_omm_runtime_resume(struct device *dev)
476
+static int __maybe_unused stm32_omm_runtime_resume(struct device *dev)
528
+{
477
+{
529
+    struct stm32_omm *omm = dev_get_drvdata(dev);
478
+    struct stm32_omm *omm = dev_get_drvdata(dev);
530
+
479
+
531
+    return clk_prepare_enable(omm->clk);
480
+    return clk_prepare_enable(omm->clk_bulk[0].clk);
532
+}
481
+}
533
+
482
+
534
+static int __maybe_unused stm32_omm_suspend(struct device *dev)
483
+static int __maybe_unused stm32_omm_suspend(struct device *dev)
535
+{
484
+{
536
+    struct stm32_omm *omm = dev_get_drvdata(dev);
485
+    struct stm32_omm *omm = dev_get_drvdata(dev);
537
+
486
+
538
+    if (omm->restore_omm && omm->cr & CR_MUXEN)
487
+    if (omm->restore_omm && omm->cr & CR_MUXEN)
539
+        stm32_omm_enable_child_clock(dev, false);
488
+        stm32_omm_toggle_child_clock(dev, false);
540
+
489
+
541
+    return pinctrl_pm_select_sleep_state(dev);
490
+    return pinctrl_pm_select_sleep_state(dev);
542
+}
491
+}
543
+
492
+
544
+static int __maybe_unused stm32_omm_resume(struct device *dev)
493
+static int __maybe_unused stm32_omm_resume(struct device *dev)
...
...
565
+    pm_runtime_put_sync_suspend(dev);
514
+    pm_runtime_put_sync_suspend(dev);
566
+    if (ret)
515
+    if (ret)
567
+        return ret;
516
+        return ret;
568
+
517
+
569
+    if (omm->cr & CR_MUXEN)
518
+    if (omm->cr & CR_MUXEN)
570
+        ret = stm32_omm_enable_child_clock(dev, true);
519
+        ret = stm32_omm_toggle_child_clock(dev, true);
571
+
520
+
572
+    return ret;
521
+    return ret;
573
+}
522
+}
574
+
523
+
575
+static const struct dev_pm_ops stm32_omm_pm_ops = {
524
+static const struct dev_pm_ops stm32_omm_pm_ops = {
...
...
589
+};
538
+};
590
+module_platform_driver(stm32_omm_driver);
539
+module_platform_driver(stm32_omm_driver);
591
+
540
+
592
+MODULE_DESCRIPTION("STMicroelectronics Octo Memory Manager driver");
541
+MODULE_DESCRIPTION("STMicroelectronics Octo Memory Manager driver");
593
+MODULE_LICENSE("GPL");
542
+MODULE_LICENSE("GPL");
543
594
--
544
--
595
2.25.1
545
2.25.1
diff view generated by jsdifflib
1
From: Patrice Chotard <patrice.chotard@foss.st.com>
2
3
Add Octo Memory Manager (OMM) entry on stm32mp251 and its two
1
Add Octo Memory Manager (OMM) entry on stm32mp251 and its two
4
OSPI instance.
2
OSPI instance.
5
3
6
Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com>
4
Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com>
7
---
5
---
8
arch/arm64/boot/dts/st/stm32mp251.dtsi | 48 ++++++++++++++++++++++++++
6
arch/arm64/boot/dts/st/stm32mp251.dtsi | 54 ++++++++++++++++++++++++++++++++++
9
1 file changed, 48 insertions(+)
7
1 file changed, 54 insertions(+)
10
8
11
diff --git a/arch/arm64/boot/dts/st/stm32mp251.dtsi b/arch/arm64/boot/dts/st/stm32mp251.dtsi
9
diff --git a/arch/arm64/boot/dts/st/stm32mp251.dtsi b/arch/arm64/boot/dts/st/stm32mp251.dtsi
12
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
13
--- a/arch/arm64/boot/dts/st/stm32mp251.dtsi
11
--- a/arch/arm64/boot/dts/st/stm32mp251.dtsi
14
+++ b/arch/arm64/boot/dts/st/stm32mp251.dtsi
12
+++ b/arch/arm64/boot/dts/st/stm32mp251.dtsi
...
...
20
+                compatible = "st,stm32mp25-omm";
18
+                compatible = "st,stm32mp25-omm";
21
+                reg = <0x40500000 0x400>, <0x60000000 0x10000000>;
19
+                reg = <0x40500000 0x400>, <0x60000000 0x10000000>;
22
+                reg-names = "regs", "memory_map";
20
+                reg-names = "regs", "memory_map";
23
+                ranges = <0 0 0x40430000 0x400>,
21
+                ranges = <0 0 0x40430000 0x400>,
24
+                     <1 0 0x40440000 0x400>;
22
+                     <1 0 0x40440000 0x400>;
25
+                clocks = <&rcc CK_BUS_OSPIIOM>;
23
+                clocks = <&rcc CK_BUS_OSPIIOM>,
26
+                resets = <&rcc OSPIIOM_R>;
24
+                     <&scmi_clk CK_SCMI_OSPI1>,
25
+                     <&scmi_clk CK_SCMI_OSPI2>;
26
+                clock-names = "omm", "ospi1", "ospi2";
27
+                resets = <&rcc OSPIIOM_R>,
28
+                     <&scmi_reset RST_SCMI_OSPI1>,
29
+                     <&scmi_reset RST_SCMI_OSPI2>;
30
+                reset-names = "omm", "ospi1", "ospi2";
27
+                access-controllers = <&rifsc 111>;
31
+                access-controllers = <&rifsc 111>;
28
+                power-domains = <&CLUSTER_PD>;
32
+                power-domains = <&CLUSTER_PD>;
29
+                #address-cells = <2>;
33
+                #address-cells = <2>;
30
+                #size-cells = <1>;
34
+                #size-cells = <1>;
31
+                st,syscfg-amcr = <&syscfg 0x2c00 0x7>;
35
+                st,syscfg-amcr = <&syscfg 0x2c00 0x7>;
32
+                status = "disabled";
36
+                status = "disabled";
33
+
37
+
34
+                ospi1: spi@40430000 {
38
+                ospi1: spi@0 {
35
+                    compatible = "st,stm32mp25-ospi";
39
+                    compatible = "st,stm32mp25-ospi";
36
+                    reg = <0 0 0x400>;
40
+                    reg = <0 0 0x400>;
37
+                    interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>;
41
+                    interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>;
38
+                    dmas = <&hpdma 2 0x62 0x00003121>,
42
+                    dmas = <&hpdma 2 0x62 0x00003121>,
39
+                     <&hpdma 2 0x42 0x00003112>;
43
+                     <&hpdma 2 0x42 0x00003112>;
...
...
45
+                    power-domains = <&CLUSTER_PD>;
49
+                    power-domains = <&CLUSTER_PD>;
46
+                    st,syscfg-dlyb = <&syscfg 0x1000>;
50
+                    st,syscfg-dlyb = <&syscfg 0x1000>;
47
+                    status = "disabled";
51
+                    status = "disabled";
48
+                };
52
+                };
49
+
53
+
50
+                ospi2: spi@40440000 {
54
+                ospi2: spi@1 {
51
+                    compatible = "st,stm32mp25-ospi";
55
+                    compatible = "st,stm32mp25-ospi";
52
+                    reg = <1 0 0x400>;
56
+                    reg = <1 0 0x400>;
53
+                    interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
57
+                    interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
54
+                    dmas = <&hpdma 3 0x62 0x00003121>,
58
+                    dmas = <&hpdma 3 0x62 0x00003121>,
55
+                     <&hpdma 3 0x42 0x00003112>;
59
+                     <&hpdma 3 0x42 0x00003112>;
...
...
65
+            };
69
+            };
66
+
70
+
67
            spi8: spi@46020000 {
71
            spi8: spi@46020000 {
68
                #address-cells = <1>;
72
                #address-cells = <1>;
69
                #size-cells = <0>;
73
                #size-cells = <0>;
74
70
--
75
--
71
2.25.1
76
2.25.1
diff view generated by jsdifflib
1
From: Patrice Chotard <patrice.chotard@foss.st.com>
2
3
Add pinctrl entry related to OSPI's port1 in stm32mp25-pinctrl.dtsi
1
Add pinctrl entry related to OSPI's port1 in stm32mp25-pinctrl.dtsi
4
2
5
Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com>
3
Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com>
6
---
4
---
7
arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi | 51 +++++++++++++++++++
5
arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi | 51 +++++++++++++++++++++++++++
8
1 file changed, 51 insertions(+)
6
1 file changed, 51 insertions(+)
9
7
10
diff --git a/arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi b/arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi
8
diff --git a/arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi b/arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi
11
index XXXXXXX..XXXXXXX 100644
9
index XXXXXXX..XXXXXXX 100644
12
--- a/arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi
10
--- a/arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi
...
...
67
+    };
65
+    };
68
+
66
+
69
    sdmmc1_b4_od_pins_a: sdmmc1-b4-od-0 {
67
    sdmmc1_b4_od_pins_a: sdmmc1-b4-od-0 {
70
        pins1 {
68
        pins1 {
71
            pinmux = <STM32_PINMUX('E', 4, AF10)>, /* SDMMC1_D0 */
69
            pinmux = <STM32_PINMUX('E', 4, AF10)>, /* SDMMC1_D0 */
70
72
--
71
--
73
2.25.1
72
2.25.1
diff view generated by jsdifflib
1
From: Patrice Chotard <patrice.chotard@foss.st.com>
2
3
Add SPI NOR flash nor support on stm32mp257f-ev1 board.
1
Add SPI NOR flash nor support on stm32mp257f-ev1 board.
4
2
5
Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com>
3
Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com>
6
---
4
---
7
arch/arm64/boot/dts/st/stm32mp257f-ev1.dts | 32 ++++++++++++++++++++++
5
arch/arm64/boot/dts/st/stm32mp257f-ev1.dts | 32 ++++++++++++++++++++++++++++++
8
1 file changed, 32 insertions(+)
6
1 file changed, 32 insertions(+)
9
7
10
diff --git a/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts b/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
8
diff --git a/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts b/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
11
index XXXXXXX..XXXXXXX 100644
9
index XXXXXXX..XXXXXXX 100644
12
--- a/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
10
--- a/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
...
...
36
+         &ospi_port1_io03_sleep_pins_a
34
+         &ospi_port1_io03_sleep_pins_a
37
+         &ospi_port1_cs0_sleep_pins_a>;
35
+         &ospi_port1_cs0_sleep_pins_a>;
38
+    pinctrl-names = "default", "sleep";
36
+    pinctrl-names = "default", "sleep";
39
+    status = "okay";
37
+    status = "okay";
40
+
38
+
41
+    spi@40430000 {
39
+    spi@0 {
42
+        #address-cells = <1>;
40
+        #address-cells = <1>;
43
+        #size-cells = <0>;
41
+        #size-cells = <0>;
44
+        memory-region = <&mm_ospi1>;
42
+        memory-region = <&mm_ospi1>;
45
+        status = "okay";
43
+        status = "okay";
46
+
44
+
...
...
55
+};
53
+};
56
+
54
+
57
&rtc {
55
&rtc {
58
    status = "okay";
56
    status = "okay";
59
};
57
};
58
60
--
59
--
61
2.25.1
60
2.25.1
diff view generated by jsdifflib
1
From: Patrice Chotard <patrice.chotard@foss.st.com>
2
3
Enable STM32 OctoSPI driver.
1
Enable STM32 OctoSPI driver.
4
Enable STM32 Octo Memory Manager (OMM) driver which is needed
2
Enable STM32 Octo Memory Manager (OMM) driver which is needed
5
for OSPI usage on STM32MP257F-EV1 board.
3
for OSPI usage on STM32MP257F-EV1 board.
6
4
7
Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com>
5
Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com>
...
...
27
CONFIG_RENESAS_RPCIF=m
25
CONFIG_RENESAS_RPCIF=m
28
+CONFIG_STM32_OMM=m
26
+CONFIG_STM32_OMM=m
29
CONFIG_IIO=y
27
CONFIG_IIO=y
30
CONFIG_EXYNOS_ADC=y
28
CONFIG_EXYNOS_ADC=y
31
CONFIG_IMX8QXP_ADC=m
29
CONFIG_IMX8QXP_ADC=m
30
32
--
31
--
33
2.25.1
32
2.25.1
diff view generated by jsdifflib