... | ... | ||
---|---|---|---|
12 | 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 |
13 | 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 |
14 | board. | 14 | board. |
15 | 15 | ||
16 | Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com> | 16 | Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com> |
17 | |||
18 | Changes in v9: | ||
19 | - split patchset by susbsystem, current one include only OMM related | ||
20 | patches. | ||
21 | - Update SPDX Identifiers to "GPL-2.0-only". | ||
22 | - Add of_node_put)() instm32_omm_set_amcr(). | ||
23 | - Rework error path in stm32_omm_toggle_child_clock(). | ||
24 | - Make usage of reset_control_acquire/release() in stm32_omm_disable_child() | ||
25 | and move reset_control_get in probe(). | ||
26 | - Rename error label in stm32_omm_configure(). | ||
27 | - Remove child compatible check in stm32_omm_probe(). | ||
28 | - Make usage of devm_of_platform_populate(). | ||
29 | - Link to v8: https://lore.kernel.org/r/20250407-upstream_ospi_v6-v8-0-7b7716c1c1f6@foss.st.com | ||
30 | |||
31 | Changes in v8: | ||
32 | - update OMM's dt-bindings: | ||
33 | - Remove minItems for clocks and resets properties. | ||
34 | - Fix st,syscfg-amcr items declaration. | ||
35 | - move power-domains property before vendor specific properties. | ||
36 | - Update compatible check wrongly introduced during internal tests in | ||
37 | stm32_omm.c. | ||
38 | - Move ommanager's node outside bus@42080000's node in stm32mp251.dtsi. | ||
39 | - Link to v7: https://lore.kernel.org/r/20250401-upstream_ospi_v6-v7-0-0ef28513ed81@foss.st.com | ||
17 | 40 | ||
18 | Changes in v7: | 41 | Changes in v7: |
19 | - update OMM's dt-bindings by updating : | 42 | - update OMM's dt-bindings by updating : |
20 | - clock-names and reset-names properties. | 43 | - clock-names and reset-names properties. |
21 | - spi unit-address node. | 44 | - spi unit-address node. |
... | ... | ||
80 | - Update STM32 Octo Memory Manager driver to match bindings update. | 103 | - Update STM32 Octo Memory Manager driver to match bindings update. |
81 | - Update DT to match bindings update. | 104 | - Update DT to match bindings update. |
82 | 105 | ||
83 | Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com> | 106 | Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com> |
84 | --- | 107 | --- |
85 | Patrice Chotard (7): | 108 | Patrice Chotard (3): |
86 | MAINTAINERS: add entry for STM32 OCTO MEMORY MANAGER driver | ||
87 | dt-bindings: memory-controllers: Add STM32 Octo Memory Manager controller | 109 | dt-bindings: memory-controllers: Add STM32 Octo Memory Manager controller |
88 | memory: Add STM32 Octo Memory Manager driver | 110 | memory: Add STM32 Octo Memory Manager driver |
89 | arm64: dts: st: Add OMM node on stm32mp251 | 111 | MAINTAINERS: add entry for STM32 OCTO MEMORY MANAGER driver |
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 | ||
93 | 112 | ||
94 | .../memory-controllers/st,stm32mp25-omm.yaml | 227 ++++++++++ | 113 | .../memory-controllers/st,stm32mp25-omm.yaml | 226 ++++++++++ |
95 | MAINTAINERS | 6 + | 114 | MAINTAINERS | 6 + |
96 | arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi | 51 +++ | ||
97 | arch/arm64/boot/dts/st/stm32mp251.dtsi | 54 +++ | ||
98 | arch/arm64/boot/dts/st/stm32mp257f-ev1.dts | 32 ++ | ||
99 | arch/arm64/configs/defconfig | 2 + | ||
100 | drivers/memory/Kconfig | 17 + | 115 | drivers/memory/Kconfig | 17 + |
101 | drivers/memory/Makefile | 1 + | 116 | drivers/memory/Makefile | 1 + |
102 | drivers/memory/stm32_omm.c | 474 +++++++++++++++++++++ | 117 | drivers/memory/stm32_omm.c | 468 +++++++++++++++++++++ |
103 | 9 files changed, 864 insertions(+) | 118 | 5 files changed, 718 insertions(+) |
104 | --- | 119 | --- |
105 | base-commit: 88424abd55ab36c3565898a656589a0a25ecd92f | 120 | base-commit: 0af2f6be1b4281385b618cb86ad946eded089ac8 |
106 | change-id: 20250320-upstream_ospi_v6-d432a8172105 | 121 | change-id: 20250320-upstream_ospi_v6-d432a8172105 |
107 | 122 | ||
108 | Best regards, | 123 | Best regards, |
109 | -- | 124 | -- |
110 | Patrice Chotard <patrice.chotard@foss.st.com> | 125 | Patrice Chotard <patrice.chotard@foss.st.com> | diff view generated by jsdifflib |
... | ... | ||
---|---|---|---|
13 | - chip select selection override. | 13 | - chip select selection override. |
14 | - the time between 2 transactions in multiplexed mode. | 14 | - the time between 2 transactions in multiplexed mode. |
15 | 15 | ||
16 | Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com> | 16 | Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com> |
17 | --- | 17 | --- |
18 | .../memory-controllers/st,stm32mp25-omm.yaml | 227 +++++++++++++++++++++ | 18 | .../memory-controllers/st,stm32mp25-omm.yaml | 226 +++++++++++++++++++++ |
19 | 1 file changed, 227 insertions(+) | 19 | 1 file changed, 226 insertions(+) |
20 | 20 | ||
21 | 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 |
22 | new file mode 100644 | 22 | new file mode 100644 |
23 | index XXXXXXX..XXXXXXX | 23 | index XXXXXXX..XXXXXXX |
24 | --- /dev/null | 24 | --- /dev/null |
... | ... | ||
86 | + enum: [ospi1, ospi2] | 86 | + enum: [ospi1, ospi2] |
87 | + minItems: 1 | 87 | + minItems: 1 |
88 | + maxItems: 2 | 88 | + maxItems: 2 |
89 | + | 89 | + |
90 | + clocks: | 90 | + clocks: |
91 | + minItems: 3 | ||
92 | + maxItems: 3 | 91 | + maxItems: 3 |
93 | + | 92 | + |
94 | + clock-names: | 93 | + clock-names: |
95 | + items: | 94 | + items: |
96 | + - const: omm | 95 | + - const: omm |
97 | + - const: ospi1 | 96 | + - const: ospi1 |
98 | + - const: ospi2 | 97 | + - const: ospi2 |
99 | + | 98 | + |
100 | + resets: | 99 | + resets: |
101 | + minItems: 3 | ||
102 | + maxItems: 3 | 100 | + maxItems: 3 |
103 | + | 101 | + |
104 | + reset-names: | 102 | + reset-names: |
105 | + items: | 103 | + items: |
106 | + - const: omm | 104 | + - const: omm |
107 | + - const: ospi1 | 105 | + - const: ospi1 |
108 | + - const: ospi2 | 106 | + - const: ospi2 |
109 | + | 107 | + |
110 | + access-controllers: | 108 | + access-controllers: |
109 | + maxItems: 1 | ||
110 | + | ||
111 | + power-domains: | ||
111 | + maxItems: 1 | 112 | + maxItems: 1 |
112 | + | 113 | + |
113 | + st,syscfg-amcr: | 114 | + st,syscfg-amcr: |
114 | + $ref: /schemas/types.yaml#/definitions/phandle-array | 115 | + $ref: /schemas/types.yaml#/definitions/phandle-array |
115 | + description: | | 116 | + description: | |
... | ... | ||
121 | + - 001: OCTOSPI1 (192 Mbytes), OCTOSPI2 (64 Mbytes) | 122 | + - 001: OCTOSPI1 (192 Mbytes), OCTOSPI2 (64 Mbytes) |
122 | + - 010: OCTOSPI1 (128 Mbytes), OCTOSPI2 (128 Mbytes) | 123 | + - 010: OCTOSPI1 (128 Mbytes), OCTOSPI2 (128 Mbytes) |
123 | + - 011: OCTOSPI1 (64 Mbytes), OCTOSPI2 (192 Mbytes) | 124 | + - 011: OCTOSPI1 (64 Mbytes), OCTOSPI2 (192 Mbytes) |
124 | + - 1xx: OCTOSPI1 unmapped, OCTOSPI2 (256 Mbytes) | 125 | + - 1xx: OCTOSPI1 unmapped, OCTOSPI2 (256 Mbytes) |
125 | + items: | 126 | + items: |
126 | + - description: phandle to syscfg | 127 | + - items: |
127 | + - description: register offset within syscfg | 128 | + - description: phandle to syscfg |
128 | + - description: register bitmask for memory split | 129 | + - description: register offset within syscfg |
130 | + - description: register bitmask for memory split | ||
129 | + | 131 | + |
130 | + st,omm-req2ack-ns: | 132 | + st,omm-req2ack-ns: |
131 | + description: | 133 | + description: |
132 | + In multiplexed mode (MUXEN = 1), this field defines the time in | 134 | + In multiplexed mode (MUXEN = 1), this field defines the time in |
133 | + nanoseconds between two transactions. | 135 | + nanoseconds between two transactions. |
... | ... | ||
154 | + - 2: swapped mode | 156 | + - 2: swapped mode |
155 | + - 3: mux OCTOSPI1 and OCTOSPI2 to port 2 | 157 | + - 3: mux OCTOSPI1 and OCTOSPI2 to port 2 |
156 | + minimum: 0 | 158 | + minimum: 0 |
157 | + maximum: 3 | 159 | + maximum: 3 |
158 | + default: 0 | 160 | + default: 0 |
159 | + | ||
160 | + power-domains: | ||
161 | + maxItems: 1 | ||
162 | + | 161 | + |
163 | +patternProperties: | 162 | +patternProperties: |
164 | + ^spi@[0-9]: | 163 | + ^spi@[0-9]: |
165 | + type: object | 164 | + type: object |
166 | + $ref: /schemas/spi/st,stm32mp25-ospi.yaml# | 165 | + $ref: /schemas/spi/st,stm32mp25-ospi.yaml# |
... | ... | diff view generated by jsdifflib |
... | ... | ||
---|---|---|---|
15 | Signed-off-by: Christophe Kerello <christophe.kerello@foss.st.com> | 15 | Signed-off-by: Christophe Kerello <christophe.kerello@foss.st.com> |
16 | Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com> | 16 | Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com> |
17 | --- | 17 | --- |
18 | drivers/memory/Kconfig | 17 ++ | 18 | drivers/memory/Kconfig | 17 ++ |
19 | drivers/memory/Makefile | 1 + | 19 | drivers/memory/Makefile | 1 + |
20 | drivers/memory/stm32_omm.c | 474 +++++++++++++++++++++++++++++++++++++++++++++ | 20 | drivers/memory/stm32_omm.c | 468 +++++++++++++++++++++++++++++++++++++++++++++ |
21 | 3 files changed, 492 insertions(+) | 21 | 3 files changed, 486 insertions(+) |
22 | 22 | ||
23 | diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig | 23 | diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig |
24 | index XXXXXXX..XXXXXXX 100644 | 24 | index XXXXXXX..XXXXXXX 100644 |
25 | --- a/drivers/memory/Kconfig | 25 | --- a/drivers/memory/Kconfig |
26 | +++ b/drivers/memory/Kconfig | 26 | +++ b/drivers/memory/Kconfig |
... | ... | ||
64 | new file mode 100644 | 64 | new file mode 100644 |
65 | index XXXXXXX..XXXXXXX | 65 | index XXXXXXX..XXXXXXX |
66 | --- /dev/null | 66 | --- /dev/null |
67 | +++ b/drivers/memory/stm32_omm.c | 67 | +++ b/drivers/memory/stm32_omm.c |
68 | @@ -XXX,XX +XXX,XX @@ | 68 | @@ -XXX,XX +XXX,XX @@ |
69 | +// SPDX-License-Identifier: GPL-2.0 | 69 | +// SPDX-License-Identifier: GPL-2.0-only |
70 | +/* | 70 | +/* |
71 | + * Copyright (C) STMicroelectronics 2025 - All Rights Reserved | 71 | + * Copyright (C) STMicroelectronics 2025 - All Rights Reserved |
72 | + * Author(s): Patrice Chotard <patrice.chotard@foss.st.com> for STMicroelectronics. | 72 | + * Author(s): Patrice Chotard <patrice.chotard@foss.st.com> for STMicroelectronics. |
73 | + */ | 73 | + */ |
74 | + | 74 | + |
... | ... | ||
97 | +#define OMM_CLK_NB 3 | 97 | +#define OMM_CLK_NB 3 |
98 | + | 98 | + |
99 | +struct stm32_omm { | 99 | +struct stm32_omm { |
100 | + struct resource *mm_res; | 100 | + struct resource *mm_res; |
101 | + struct clk_bulk_data clk_bulk[OMM_CLK_NB]; | 101 | + struct clk_bulk_data clk_bulk[OMM_CLK_NB]; |
102 | + struct reset_control *child_reset[OMM_CHILD_NB]; | ||
102 | + void __iomem *io_base; | 103 | + void __iomem *io_base; |
103 | + u32 cr; | 104 | + u32 cr; |
104 | + u8 nb_child; | 105 | + u8 nb_child; |
105 | + bool restore_omm; | 106 | + bool restore_omm; |
106 | +}; | 107 | +}; |
... | ... | ||
132 | + if (!node) | 133 | + if (!node) |
133 | + continue; | 134 | + continue; |
134 | + | 135 | + |
135 | + ret = of_address_to_resource(node, 0, &res); | 136 | + ret = of_address_to_resource(node, 0, &res); |
136 | + if (ret) { | 137 | + if (ret) { |
138 | + of_node_put(node); | ||
137 | + dev_err(dev, "unable to resolve memory region\n"); | 139 | + dev_err(dev, "unable to resolve memory region\n"); |
138 | + return ret; | 140 | + return ret; |
139 | + } | 141 | + } |
140 | + | 142 | + |
141 | + /* check that memory region fits inside OMM memory map area */ | 143 | + /* check that memory region fits inside OMM memory map area */ |
... | ... | ||
193 | + return ret; | 195 | + return ret; |
194 | +} | 196 | +} |
195 | + | 197 | + |
196 | +static int stm32_omm_toggle_child_clock(struct device *dev, bool enable) | 198 | +static int stm32_omm_toggle_child_clock(struct device *dev, bool enable) |
197 | +{ | 199 | +{ |
198 | + /* As there is only 2 children, remember first child in case of error */ | 200 | + struct stm32_omm *omm = dev_get_drvdata(dev); |
199 | + struct clk *first_child_clk = NULL; | 201 | + int i, ret; |
200 | + struct stm32_omm *omm = dev_get_drvdata(dev); | ||
201 | + u8 i; | ||
202 | + int ret; | ||
203 | + | 202 | + |
204 | + for (i = 0; i < omm->nb_child; i++) { | 203 | + for (i = 0; i < omm->nb_child; i++) { |
205 | + if (enable) { | 204 | + if (enable) { |
206 | + ret = clk_prepare_enable(omm->clk_bulk[i + 1].clk); | 205 | + ret = clk_prepare_enable(omm->clk_bulk[i + 1].clk); |
207 | + if (ret) { | 206 | + if (ret) { |
208 | + if (first_child_clk) | ||
209 | + clk_disable_unprepare(first_child_clk); | ||
210 | + | ||
211 | + dev_err(dev, "Can not enable clock\n"); | 207 | + dev_err(dev, "Can not enable clock\n"); |
212 | + return ret; | 208 | + goto clk_error; |
213 | + } | 209 | + } |
214 | + } else { | 210 | + } else { |
215 | + clk_disable_unprepare(omm->clk_bulk[i + 1].clk); | 211 | + clk_disable_unprepare(omm->clk_bulk[i + 1].clk); |
216 | + } | 212 | + } |
217 | + | ||
218 | + first_child_clk = omm->clk_bulk[i + 1].clk; | ||
219 | + } | 213 | + } |
220 | + | 214 | + |
221 | + return 0; | 215 | + return 0; |
216 | + | ||
217 | +clk_error: | ||
218 | + while (i--) | ||
219 | + clk_disable_unprepare(omm->clk_bulk[i + 1].clk); | ||
220 | + | ||
221 | + return ret; | ||
222 | +} | 222 | +} |
223 | + | 223 | + |
224 | +static int stm32_omm_disable_child(struct device *dev) | 224 | +static int stm32_omm_disable_child(struct device *dev) |
225 | +{ | 225 | +{ |
226 | + static const char * const resets_name[] = {"ospi1", "ospi2"}; | ||
227 | + struct stm32_omm *omm = dev_get_drvdata(dev); | 226 | + struct stm32_omm *omm = dev_get_drvdata(dev); |
228 | + struct reset_control *reset; | 227 | + struct reset_control *reset; |
229 | + int ret; | 228 | + int ret; |
230 | + u8 i; | 229 | + u8 i; |
231 | + | 230 | + |
232 | + ret = stm32_omm_toggle_child_clock(dev, true); | 231 | + ret = stm32_omm_toggle_child_clock(dev, true); |
233 | + if (!ret) | 232 | + if (!ret) |
234 | + return ret; | 233 | + return ret; |
235 | + | 234 | + |
236 | + for (i = 0; i < omm->nb_child; i++) { | 235 | + 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 */ | 236 | + /* reset OSPI to ensure CR_EN bit is set to 0 */ |
237 | + reset = omm->child_reset[i]; | ||
238 | + ret = reset_control_acquire(reset); | ||
239 | + if (ret) { | ||
240 | + dev_err(dev, "Can not acquire resset %d\n", ret); | ||
241 | + return ret; | ||
242 | + } | ||
243 | + | ||
244 | + reset_control_assert(reset); | 244 | + reset_control_assert(reset); |
245 | + udelay(2); | 245 | + udelay(2); |
246 | + reset_control_deassert(reset); | 246 | + reset_control_deassert(reset); |
247 | + | 247 | + |
248 | + reset_control_put(reset); | 248 | + reset_control_release(reset); |
249 | + } | 249 | + } |
250 | + | 250 | + |
251 | + return stm32_omm_toggle_child_clock(dev, false); | 251 | + return stm32_omm_toggle_child_clock(dev, false); |
252 | +} | 252 | +} |
253 | + | 253 | + |
... | ... | ||
284 | + /* parse children's clock */ | 284 | + /* parse children's clock */ |
285 | + for (i = 1; i <= omm->nb_child; i++) { | 285 | + for (i = 1; i <= omm->nb_child; i++) { |
286 | + clk_rate = clk_get_rate(omm->clk_bulk[i].clk); | 286 | + clk_rate = clk_get_rate(omm->clk_bulk[i].clk); |
287 | + if (!clk_rate) { | 287 | + if (!clk_rate) { |
288 | + dev_err(dev, "Invalid clock rate\n"); | 288 | + dev_err(dev, "Invalid clock rate\n"); |
289 | + goto err_clk_disable; | 289 | + goto error; |
290 | + } | 290 | + } |
291 | + | 291 | + |
292 | + if (clk_rate > clk_rate_max) | 292 | + if (clk_rate > clk_rate_max) |
293 | + clk_rate_max = clk_rate; | 293 | + clk_rate_max = clk_rate; |
294 | + } | 294 | + } |
... | ... | ||
324 | + * 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 |
325 | + * always enabled | 325 | + * always enabled |
326 | + */ | 326 | + */ |
327 | + ret = stm32_omm_toggle_child_clock(dev, true); | 327 | + ret = stm32_omm_toggle_child_clock(dev, true); |
328 | + if (ret) | 328 | + if (ret) |
329 | + goto err_clk_disable; | 329 | + goto error; |
330 | + } | 330 | + } |
331 | + | 331 | + |
332 | + omm->cr &= ~CR_MUXENMODE_MASK; | 332 | + omm->cr &= ~CR_MUXENMODE_MASK; |
333 | + omm->cr |= FIELD_PREP(CR_MUXENMODE_MASK, mux); | 333 | + omm->cr |= FIELD_PREP(CR_MUXENMODE_MASK, mux); |
334 | + } | 334 | + } |
... | ... | ||
344 | + omm->restore_omm = true; | 344 | + omm->restore_omm = true; |
345 | + writel_relaxed(omm->cr, omm->io_base + OMM_CR); | 345 | + writel_relaxed(omm->cr, omm->io_base + OMM_CR); |
346 | + | 346 | + |
347 | + ret = stm32_omm_set_amcr(dev, true); | 347 | + ret = stm32_omm_set_amcr(dev, true); |
348 | + | 348 | + |
349 | +err_clk_disable: | 349 | +error: |
350 | + pm_runtime_put_sync_suspend(dev); | 350 | + pm_runtime_put_sync_suspend(dev); |
351 | + | 351 | + |
352 | + return ret; | 352 | + return ret; |
353 | +} | 353 | +} |
354 | + | 354 | + |
... | ... | ||
364 | + return stm32_firewall_grant_access(&firewall); | 364 | + return stm32_firewall_grant_access(&firewall); |
365 | +} | 365 | +} |
366 | + | 366 | + |
367 | +static int stm32_omm_probe(struct platform_device *pdev) | 367 | +static int stm32_omm_probe(struct platform_device *pdev) |
368 | +{ | 368 | +{ |
369 | + static const char * const resets_name[] = {"ospi1", "ospi2"}; | ||
369 | + struct device *dev = &pdev->dev; | 370 | + struct device *dev = &pdev->dev; |
370 | + u8 child_access_granted = 0; | 371 | + u8 child_access_granted = 0; |
371 | + struct stm32_omm *omm; | 372 | + struct stm32_omm *omm; |
372 | + int ret; | 373 | + int i, ret; |
373 | + | 374 | + |
374 | + omm = devm_kzalloc(dev, sizeof(*omm), GFP_KERNEL); | 375 | + omm = devm_kzalloc(dev, sizeof(*omm), GFP_KERNEL); |
375 | + if (!omm) | 376 | + if (!omm) |
376 | + return -ENOMEM; | 377 | + return -ENOMEM; |
377 | + | 378 | + |
... | ... | ||
388 | + if (omm->nb_child >= OMM_CHILD_NB) { | 389 | + if (omm->nb_child >= OMM_CHILD_NB) { |
389 | + dev_err(dev, "Bad DT, found too much children\n"); | 390 | + dev_err(dev, "Bad DT, found too much children\n"); |
390 | + return -E2BIG; | 391 | + return -E2BIG; |
391 | + } | 392 | + } |
392 | + | 393 | + |
393 | + if (!of_device_is_compatible(child, "st,stm32mp25-omi")) | ||
394 | + return -EINVAL; | ||
395 | + | ||
396 | + ret = stm32_omm_check_access(child); | 394 | + ret = stm32_omm_check_access(child); |
397 | + if (ret < 0 && ret != -EACCES) | 395 | + if (ret < 0 && ret != -EACCES) |
398 | + return ret; | 396 | + return ret; |
399 | + | 397 | + |
400 | + if (!ret) | 398 | + if (!ret) |
... | ... | ||
406 | + if (omm->nb_child != OMM_CHILD_NB) | 404 | + if (omm->nb_child != OMM_CHILD_NB) |
407 | + return -EINVAL; | 405 | + return -EINVAL; |
408 | + | 406 | + |
409 | + platform_set_drvdata(pdev, omm); | 407 | + platform_set_drvdata(pdev, omm); |
410 | + | 408 | + |
411 | + pm_runtime_enable(dev); | 409 | + devm_pm_runtime_enable(dev); |
412 | + | 410 | + |
413 | + /* check if OMM's resource access is granted */ | 411 | + /* check if OMM's resource access is granted */ |
414 | + ret = stm32_omm_check_access(dev->of_node); | 412 | + ret = stm32_omm_check_access(dev->of_node); |
415 | + if (ret < 0 && ret != -EACCES) | 413 | + if (ret < 0 && ret != -EACCES) |
416 | + goto error; | 414 | + return ret; |
415 | + | ||
416 | + for (i = 0; i < omm->nb_child; i++) { | ||
417 | + omm->child_reset[i] = devm_reset_control_get_exclusive_released(dev, | ||
418 | + resets_name[i]); | ||
419 | + | ||
420 | + if (IS_ERR(omm->child_reset[i])) | ||
421 | + return dev_err_probe(dev, PTR_ERR(omm->child_reset[i]), | ||
422 | + "Can't get %s reset\n", resets_name[i]); | ||
423 | + } | ||
417 | + | 424 | + |
418 | + if (!ret && child_access_granted == OMM_CHILD_NB) { | 425 | + if (!ret && child_access_granted == OMM_CHILD_NB) { |
419 | + ret = stm32_omm_configure(dev); | 426 | + ret = stm32_omm_configure(dev); |
420 | + if (ret) | 427 | + if (ret) |
421 | + goto error; | 428 | + return ret; |
422 | + } else { | 429 | + } else { |
423 | + dev_dbg(dev, "Octo Memory Manager resource's access not granted\n"); | 430 | + dev_dbg(dev, "Octo Memory Manager resource's access not granted\n"); |
424 | + /* | 431 | + /* |
425 | + * AMCR can't be set, so check if current value is coherent | 432 | + * AMCR can't be set, so check if current value is coherent |
426 | + * with memory-map areas defined in DT | 433 | + * with memory-map areas defined in DT |
427 | + */ | 434 | + */ |
428 | + ret = stm32_omm_set_amcr(dev, false); | 435 | + ret = stm32_omm_set_amcr(dev, false); |
429 | + if (ret) | 436 | + if (ret) |
430 | + goto error; | 437 | + return ret; |
431 | + } | 438 | + } |
432 | + | 439 | + |
433 | + ret = of_platform_populate(dev->of_node, NULL, NULL, dev); | 440 | + ret = devm_of_platform_populate(dev); |
434 | + if (ret) { | 441 | + if (ret) |
435 | + dev_err(dev, "Failed to create Octo Memory Manager child\n"); | 442 | + dev_err(dev, "Failed to create Octo Memory Manager child\n"); |
436 | + of_platform_depopulate(dev); | ||
437 | + ret = -EINVAL; | ||
438 | + goto error; | ||
439 | + } | ||
440 | + | 443 | + |
441 | + return ret; | 444 | + return ret; |
442 | + | ||
443 | +error: | ||
444 | + pm_runtime_disable(dev); | ||
445 | + | ||
446 | + return ret; | ||
447 | + | ||
448 | +} | 445 | +} |
449 | + | 446 | + |
450 | +static void stm32_omm_remove(struct platform_device *pdev) | 447 | +static void stm32_omm_remove(struct platform_device *pdev) |
451 | +{ | 448 | +{ |
452 | + struct stm32_omm *omm = platform_get_drvdata(pdev); | 449 | + struct stm32_omm *omm = platform_get_drvdata(pdev); |
453 | + | 450 | + |
454 | + of_platform_depopulate(&pdev->dev); | ||
455 | + if (omm->cr & CR_MUXEN) | 451 | + if (omm->cr & CR_MUXEN) |
456 | + stm32_omm_toggle_child_clock(&pdev->dev, false); | 452 | + stm32_omm_toggle_child_clock(&pdev->dev, false); |
457 | + | ||
458 | + pm_runtime_disable(&pdev->dev); | ||
459 | +} | 453 | +} |
460 | + | 454 | + |
461 | +static const struct of_device_id stm32_omm_of_match[] = { | 455 | +static const struct of_device_id stm32_omm_of_match[] = { |
462 | + { .compatible = "st,stm32mp25-omm", }, | 456 | + { .compatible = "st,stm32mp25-omm", }, |
463 | + {} | 457 | + {} |
... | ... | diff view generated by jsdifflib |
1 | Add myself as STM32 OCTO MEMORY MANAGER maintainer. | 1 | Add myself as STM32 OCTO MEMORY MANAGER maintainer. |
---|---|---|---|
2 | 2 | ||
3 | Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com> | 3 | Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com> |
4 | --- | 4 | --- |
5 | MAINTAINERS | 6 ++++++ | 5 | MAINTAINERS | 6 ++++++ |
6 | 1 file changed, 6 insertions(+) | 6 | 1 file changed, 6 insertions(+) |
7 | 7 | ||
8 | diff --git a/MAINTAINERS b/MAINTAINERS | 8 | diff --git a/MAINTAINERS b/MAINTAINERS |
9 | index XXXXXXX..XXXXXXX 100644 | 9 | index XXXXXXX..XXXXXXX 100644 |
10 | --- a/MAINTAINERS | 10 | --- a/MAINTAINERS |
11 | +++ b/MAINTAINERS | 11 | +++ b/MAINTAINERS |
12 | @@ -XXX,XX +XXX,XX @@ L: linux-i2c@vger.kernel.org | 12 | @@ -XXX,XX +XXX,XX @@ L: linux-i2c@vger.kernel.org |
13 | S: Maintained | 13 | S: Maintained |
14 | F: drivers/i2c/busses/i2c-stm32* | 14 | F: drivers/i2c/busses/i2c-stm32* |
15 | 15 | ||
16 | +ST STM32 OCTO MEMORY MANAGER | 16 | +ST STM32 OCTO MEMORY MANAGER |
17 | +M: Patrice Chotard <patrice.chotard@foss.st.com> | 17 | +M: Patrice Chotard <patrice.chotard@foss.st.com> |
18 | +S: Maintained | 18 | +S: Maintained |
19 | +F: Documentation/devicetree/bindings/memory-controllers/st,stm32mp25-omm.yaml | 19 | +F: Documentation/devicetree/bindings/memory-controllers/st,stm32mp25-omm.yaml |
20 | +F: drivers/memory/stm32_omm.c | 20 | +F: drivers/memory/stm32_omm.c |
21 | + | 21 | + |
22 | ST STM32 SPI DRIVER | 22 | ST STM32 SPI DRIVER |
23 | M: Alain Volmat <alain.volmat@foss.st.com> | 23 | M: Alain Volmat <alain.volmat@foss.st.com> |
24 | L: linux-spi@vger.kernel.org | 24 | L: linux-spi@vger.kernel.org |
25 | 25 | ||
26 | -- | 26 | -- |
27 | 2.25.1 | 27 | 2.25.1 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | Add Octo Memory Manager (OMM) entry on stm32mp251 and its two | ||
2 | OSPI instance. | ||
3 | 1 | ||
4 | Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com> | ||
5 | --- | ||
6 | arch/arm64/boot/dts/st/stm32mp251.dtsi | 54 ++++++++++++++++++++++++++++++++++ | ||
7 | 1 file changed, 54 insertions(+) | ||
8 | |||
9 | diff --git a/arch/arm64/boot/dts/st/stm32mp251.dtsi b/arch/arm64/boot/dts/st/stm32mp251.dtsi | ||
10 | index XXXXXXX..XXXXXXX 100644 | ||
11 | --- a/arch/arm64/boot/dts/st/stm32mp251.dtsi | ||
12 | +++ b/arch/arm64/boot/dts/st/stm32mp251.dtsi | ||
13 | @@ -XXX,XX +XXX,XX @@ rng: rng@42020000 { | ||
14 | status = "disabled"; | ||
15 | }; | ||
16 | |||
17 | + ommanager: ommanager@40500000 { | ||
18 | + compatible = "st,stm32mp25-omm"; | ||
19 | + reg = <0x40500000 0x400>, <0x60000000 0x10000000>; | ||
20 | + reg-names = "regs", "memory_map"; | ||
21 | + ranges = <0 0 0x40430000 0x400>, | ||
22 | + <1 0 0x40440000 0x400>; | ||
23 | + clocks = <&rcc CK_BUS_OSPIIOM>, | ||
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"; | ||
31 | + access-controllers = <&rifsc 111>; | ||
32 | + power-domains = <&CLUSTER_PD>; | ||
33 | + #address-cells = <2>; | ||
34 | + #size-cells = <1>; | ||
35 | + st,syscfg-amcr = <&syscfg 0x2c00 0x7>; | ||
36 | + status = "disabled"; | ||
37 | + | ||
38 | + ospi1: spi@0 { | ||
39 | + compatible = "st,stm32mp25-ospi"; | ||
40 | + reg = <0 0 0x400>; | ||
41 | + interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>; | ||
42 | + dmas = <&hpdma 2 0x62 0x00003121>, | ||
43 | + <&hpdma 2 0x42 0x00003112>; | ||
44 | + dma-names = "tx", "rx"; | ||
45 | + clocks = <&scmi_clk CK_SCMI_OSPI1>; | ||
46 | + resets = <&scmi_reset RST_SCMI_OSPI1>, | ||
47 | + <&scmi_reset RST_SCMI_OSPI1DLL>; | ||
48 | + access-controllers = <&rifsc 74>; | ||
49 | + power-domains = <&CLUSTER_PD>; | ||
50 | + st,syscfg-dlyb = <&syscfg 0x1000>; | ||
51 | + status = "disabled"; | ||
52 | + }; | ||
53 | + | ||
54 | + ospi2: spi@1 { | ||
55 | + compatible = "st,stm32mp25-ospi"; | ||
56 | + reg = <1 0 0x400>; | ||
57 | + interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>; | ||
58 | + dmas = <&hpdma 3 0x62 0x00003121>, | ||
59 | + <&hpdma 3 0x42 0x00003112>; | ||
60 | + dma-names = "tx", "rx"; | ||
61 | + clocks = <&scmi_clk CK_SCMI_OSPI2>; | ||
62 | + resets = <&scmi_reset RST_SCMI_OSPI2>, | ||
63 | + <&scmi_reset RST_SCMI_OSPI2DLL>; | ||
64 | + access-controllers = <&rifsc 75>; | ||
65 | + power-domains = <&CLUSTER_PD>; | ||
66 | + st,syscfg-dlyb = <&syscfg 0x1400>; | ||
67 | + status = "disabled"; | ||
68 | + }; | ||
69 | + }; | ||
70 | + | ||
71 | spi8: spi@46020000 { | ||
72 | #address-cells = <1>; | ||
73 | #size-cells = <0>; | ||
74 | |||
75 | -- | ||
76 | 2.25.1 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | Add pinctrl entry related to OSPI's port1 in stm32mp25-pinctrl.dtsi | ||
2 | 1 | ||
3 | Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com> | ||
4 | --- | ||
5 | arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi | 51 +++++++++++++++++++++++++++ | ||
6 | 1 file changed, 51 insertions(+) | ||
7 | |||
8 | diff --git a/arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi b/arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi | ||
9 | index XXXXXXX..XXXXXXX 100644 | ||
10 | --- a/arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi | ||
11 | +++ b/arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi | ||
12 | @@ -XXX,XX +XXX,XX @@ pins2 { | ||
13 | }; | ||
14 | }; | ||
15 | |||
16 | + ospi_port1_clk_pins_a: ospi-port1-clk-0 { | ||
17 | + pins { | ||
18 | + pinmux = <STM32_PINMUX('D', 0, AF10)>; /* OSPI1_CLK */ | ||
19 | + bias-disable; | ||
20 | + drive-push-pull; | ||
21 | + slew-rate = <2>; | ||
22 | + }; | ||
23 | + }; | ||
24 | + | ||
25 | + ospi_port1_clk_sleep_pins_a: ospi-port1-clk-sleep-0 { | ||
26 | + pins { | ||
27 | + pinmux = <STM32_PINMUX('D', 0, ANALOG)>; /* OSPI1_CLK */ | ||
28 | + }; | ||
29 | + }; | ||
30 | + | ||
31 | + ospi_port1_cs0_pins_a: ospi-port1-cs0-0 { | ||
32 | + pins { | ||
33 | + pinmux = <STM32_PINMUX('D', 3, AF10)>; /* OSPI_NCS0 */ | ||
34 | + bias-pull-up; | ||
35 | + drive-push-pull; | ||
36 | + slew-rate = <0>; | ||
37 | + }; | ||
38 | + }; | ||
39 | + | ||
40 | + ospi_port1_cs0_sleep_pins_a: ospi-port1-cs0-sleep-0 { | ||
41 | + pins { | ||
42 | + pinmux = <STM32_PINMUX('D', 3, ANALOG)>; /* OSPI_NCS0 */ | ||
43 | + }; | ||
44 | + }; | ||
45 | + | ||
46 | + ospi_port1_io03_pins_a: ospi-port1-io03-0 { | ||
47 | + pins { | ||
48 | + pinmux = <STM32_PINMUX('D', 4, AF10)>, /* OSPI_IO0 */ | ||
49 | + <STM32_PINMUX('D', 5, AF10)>, /* OSPI_IO1 */ | ||
50 | + <STM32_PINMUX('D', 6, AF10)>, /* OSPI_IO2 */ | ||
51 | + <STM32_PINMUX('D', 7, AF10)>; /* OSPI_IO3 */ | ||
52 | + bias-disable; | ||
53 | + drive-push-pull; | ||
54 | + slew-rate = <0>; | ||
55 | + }; | ||
56 | + }; | ||
57 | + | ||
58 | + ospi_port1_io03_sleep_pins_a: ospi-port1-io03-sleep-0 { | ||
59 | + pins { | ||
60 | + pinmux = <STM32_PINMUX('D', 4, ANALOG)>, /* OSPI_IO0 */ | ||
61 | + <STM32_PINMUX('D', 5, ANALOG)>, /* OSPI_IO1 */ | ||
62 | + <STM32_PINMUX('D', 6, ANALOG)>, /* OSPI_IO2 */ | ||
63 | + <STM32_PINMUX('D', 7, ANALOG)>; /* OSPI_IO3 */ | ||
64 | + }; | ||
65 | + }; | ||
66 | + | ||
67 | sdmmc1_b4_od_pins_a: sdmmc1-b4-od-0 { | ||
68 | pins1 { | ||
69 | pinmux = <STM32_PINMUX('E', 4, AF10)>, /* SDMMC1_D0 */ | ||
70 | |||
71 | -- | ||
72 | 2.25.1 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | Add SPI NOR flash nor support on stm32mp257f-ev1 board. | ||
2 | 1 | ||
3 | Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com> | ||
4 | --- | ||
5 | arch/arm64/boot/dts/st/stm32mp257f-ev1.dts | 32 ++++++++++++++++++++++++++++++ | ||
6 | 1 file changed, 32 insertions(+) | ||
7 | |||
8 | diff --git a/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts b/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts | ||
9 | index XXXXXXX..XXXXXXX 100644 | ||
10 | --- a/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts | ||
11 | +++ b/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts | ||
12 | @@ -XXX,XX +XXX,XX @@ fw@80000000 { | ||
13 | reg = <0x0 0x80000000 0x0 0x4000000>; | ||
14 | no-map; | ||
15 | }; | ||
16 | + | ||
17 | + mm_ospi1: mm-ospi@60000000 { | ||
18 | + reg = <0x0 0x60000000 0x0 0x10000000>; | ||
19 | + no-map; | ||
20 | + }; | ||
21 | }; | ||
22 | }; | ||
23 | |||
24 | @@ -XXX,XX +XXX,XX @@ &i2c8 { | ||
25 | status = "disabled"; | ||
26 | }; | ||
27 | |||
28 | +&ommanager { | ||
29 | + memory-region = <&mm_ospi1>; | ||
30 | + pinctrl-0 = <&ospi_port1_clk_pins_a | ||
31 | + &ospi_port1_io03_pins_a | ||
32 | + &ospi_port1_cs0_pins_a>; | ||
33 | + pinctrl-1 = <&ospi_port1_clk_sleep_pins_a | ||
34 | + &ospi_port1_io03_sleep_pins_a | ||
35 | + &ospi_port1_cs0_sleep_pins_a>; | ||
36 | + pinctrl-names = "default", "sleep"; | ||
37 | + status = "okay"; | ||
38 | + | ||
39 | + spi@0 { | ||
40 | + #address-cells = <1>; | ||
41 | + #size-cells = <0>; | ||
42 | + memory-region = <&mm_ospi1>; | ||
43 | + status = "okay"; | ||
44 | + | ||
45 | + flash0: flash@0 { | ||
46 | + compatible = "jedec,spi-nor"; | ||
47 | + reg = <0>; | ||
48 | + spi-rx-bus-width = <4>; | ||
49 | + spi-tx-bus-width = <4>; | ||
50 | + spi-max-frequency = <50000000>; | ||
51 | + }; | ||
52 | + }; | ||
53 | +}; | ||
54 | + | ||
55 | &rtc { | ||
56 | status = "okay"; | ||
57 | }; | ||
58 | |||
59 | -- | ||
60 | 2.25.1 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | Enable STM32 OctoSPI driver. | ||
2 | Enable STM32 Octo Memory Manager (OMM) driver which is needed | ||
3 | for OSPI usage on STM32MP257F-EV1 board. | ||
4 | 1 | ||
5 | Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com> | ||
6 | --- | ||
7 | arch/arm64/configs/defconfig | 2 ++ | ||
8 | 1 file changed, 2 insertions(+) | ||
9 | |||
10 | diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig | ||
11 | index XXXXXXX..XXXXXXX 100644 | ||
12 | --- a/arch/arm64/configs/defconfig | ||
13 | +++ b/arch/arm64/configs/defconfig | ||
14 | @@ -XXX,XX +XXX,XX @@ CONFIG_SPI_QUP=y | ||
15 | CONFIG_SPI_QCOM_GENI=m | ||
16 | CONFIG_SPI_S3C64XX=y | ||
17 | CONFIG_SPI_SH_MSIOF=m | ||
18 | +CONFIG_SPI_STM32_OSPI=m | ||
19 | CONFIG_SPI_SUN6I=y | ||
20 | CONFIG_SPI_TEGRA210_QUAD=m | ||
21 | CONFIG_SPI_TEGRA114=m | ||
22 | @@ -XXX,XX +XXX,XX @@ CONFIG_EXTCON_USB_GPIO=y | ||
23 | CONFIG_EXTCON_USBC_CROS_EC=y | ||
24 | CONFIG_FSL_IFC=y | ||
25 | CONFIG_RENESAS_RPCIF=m | ||
26 | +CONFIG_STM32_OMM=m | ||
27 | CONFIG_IIO=y | ||
28 | CONFIG_EXYNOS_ADC=y | ||
29 | CONFIG_IMX8QXP_ADC=m | ||
30 | |||
31 | -- | ||
32 | 2.25.1 | diff view generated by jsdifflib |