Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'memory-controller-drv-6.16' of https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-mem-ctrl into soc/drivers

Memory controller drivers for v6.16

1. Mediatek: Add support for MT6893 MTK SMI.
2. STM32: Add new driver for STM32 Octo Memory Manager (OMM), which
manages muxing between two OSPI busses.
3. Several cleanups and minor improvements (OMAP GPMC, Kconfig entries,
BT1 L2).

* tag 'memory-controller-drv-6.16' of https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-mem-ctrl:
MAINTAINERS: add entry for STM32 OCTO MEMORY MANAGER driver
memory: Add STM32 Octo Memory Manager driver
dt-bindings: memory-controllers: Add STM32 Octo Memory Manager controller
bus: firewall: Fix missing static inline annotations for stubs
memory: bt1-l2-ctl: replace scnprintf() with sysfs_emit()
memory: mtk-smi: Add support for Dimensity 1200 MT6893 SMI
dt-bindings: memory: mtk-smi: Add support for MT6893
memory: tegra: Do not enable by default during compile testing
memory: Simplify 'default' choice in Kconfig
memory: omap-gpmc: remove GPIO set() and direction_output() callbacks
memory: omap-gpmc: use the dedicated define for GPIO direction

Link: https://lore.kernel.org/r/20250508093451.55755-2-krzysztof.kozlowski@linaro.org
Signed-off-by: Arnd Bergmann <arnd@arndb.de>

+798 -28
+1
Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml
··· 33 33 - mediatek,mt2712-smi-common 34 34 - mediatek,mt6779-smi-common 35 35 - mediatek,mt6795-smi-common 36 + - mediatek,mt6893-smi-common 36 37 - mediatek,mt8167-smi-common 37 38 - mediatek,mt8173-smi-common 38 39 - mediatek,mt8183-smi-common
+1
Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
··· 21 21 - mediatek,mt2712-smi-larb 22 22 - mediatek,mt6779-smi-larb 23 23 - mediatek,mt6795-smi-larb 24 + - mediatek,mt6893-smi-larb 24 25 - mediatek,mt8167-smi-larb 25 26 - mediatek,mt8173-smi-larb 26 27 - mediatek,mt8183-smi-larb
+226
Documentation/devicetree/bindings/memory-controllers/st,stm32mp25-omm.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/memory-controllers/st,stm32mp25-omm.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: STM32 Octo Memory Manager (OMM) 8 + 9 + maintainers: 10 + - Patrice Chotard <patrice.chotard@foss.st.com> 11 + 12 + description: | 13 + The STM32 Octo Memory Manager is a low-level interface that enables an 14 + efficient OCTOSPI pin assignment with a full I/O matrix (before alternate 15 + function map) and multiplex of single/dual/quad/octal SPI interfaces over 16 + the same bus. It Supports up to: 17 + - Two single/dual/quad/octal SPI interfaces 18 + - Two ports for pin assignment 19 + 20 + properties: 21 + compatible: 22 + const: st,stm32mp25-omm 23 + 24 + "#address-cells": 25 + const: 2 26 + 27 + "#size-cells": 28 + const: 1 29 + 30 + ranges: 31 + description: | 32 + Reflects the memory layout per OSPI instance. 33 + Format: 34 + <chip-select> 0 <registers base address> <size> 35 + minItems: 2 36 + maxItems: 2 37 + 38 + reg: 39 + items: 40 + - description: OMM registers 41 + - description: OMM memory map area 42 + 43 + reg-names: 44 + items: 45 + - const: regs 46 + - const: memory_map 47 + 48 + memory-region: 49 + description: 50 + Memory region shared between the 2 OCTOSPI instance. 51 + One or two phandle to a node describing a memory mapped region 52 + depending of child number. 53 + minItems: 1 54 + maxItems: 2 55 + 56 + memory-region-names: 57 + description: 58 + Identify to which OSPI instance the memory region belongs to. 59 + items: 60 + enum: [ospi1, ospi2] 61 + minItems: 1 62 + maxItems: 2 63 + 64 + clocks: 65 + maxItems: 3 66 + 67 + clock-names: 68 + items: 69 + - const: omm 70 + - const: ospi1 71 + - const: ospi2 72 + 73 + resets: 74 + maxItems: 3 75 + 76 + reset-names: 77 + items: 78 + - const: omm 79 + - const: ospi1 80 + - const: ospi2 81 + 82 + access-controllers: 83 + maxItems: 1 84 + 85 + power-domains: 86 + maxItems: 1 87 + 88 + st,syscfg-amcr: 89 + $ref: /schemas/types.yaml#/definitions/phandle-array 90 + description: | 91 + The Address Mapping Control Register (AMCR) is used to split the 256MB 92 + memory map area shared between the 2 OSPI instance. The Octo Memory 93 + Manager sets the AMCR depending of the memory-region configuration. 94 + The memory split bitmask description is: 95 + - 000: OCTOSPI1 (256 Mbytes), OCTOSPI2 unmapped 96 + - 001: OCTOSPI1 (192 Mbytes), OCTOSPI2 (64 Mbytes) 97 + - 010: OCTOSPI1 (128 Mbytes), OCTOSPI2 (128 Mbytes) 98 + - 011: OCTOSPI1 (64 Mbytes), OCTOSPI2 (192 Mbytes) 99 + - 1xx: OCTOSPI1 unmapped, OCTOSPI2 (256 Mbytes) 100 + items: 101 + - items: 102 + - description: phandle to syscfg 103 + - description: register offset within syscfg 104 + - description: register bitmask for memory split 105 + 106 + st,omm-req2ack-ns: 107 + description: 108 + In multiplexed mode (MUXEN = 1), this field defines the time in 109 + nanoseconds between two transactions. 110 + default: 0 111 + 112 + st,omm-cssel-ovr: 113 + $ref: /schemas/types.yaml#/definitions/uint32 114 + description: | 115 + Configure the chip select selector override for the 2 OCTOSPIs. 116 + - 0: OCTOSPI1 chip select send to NCS1 OCTOSPI2 chip select send to NCS1 117 + - 1: OCTOSPI1 chip select send to NCS2 OCTOSPI2 chip select send to NCS1 118 + - 2: OCTOSPI1 chip select send to NCS1 OCTOSPI2 chip select send to NCS2 119 + - 3: OCTOSPI1 chip select send to NCS2 OCTOSPI2 chip select send to NCS2 120 + minimum: 0 121 + maximum: 3 122 + default: 0 123 + 124 + st,omm-mux: 125 + $ref: /schemas/types.yaml#/definitions/uint32 126 + description: | 127 + Configure the muxing between the 2 OCTOSPIs busses and the 2 output ports. 128 + - 0: direct mode 129 + - 1: mux OCTOSPI1 and OCTOSPI2 to port 1 130 + - 2: swapped mode 131 + - 3: mux OCTOSPI1 and OCTOSPI2 to port 2 132 + minimum: 0 133 + maximum: 3 134 + default: 0 135 + 136 + patternProperties: 137 + ^spi@[0-9]: 138 + type: object 139 + $ref: /schemas/spi/st,stm32mp25-ospi.yaml# 140 + description: Required spi child node 141 + 142 + required: 143 + - compatible 144 + - reg 145 + - "#address-cells" 146 + - "#size-cells" 147 + - clocks 148 + - clock-names 149 + - resets 150 + - reset-names 151 + - st,syscfg-amcr 152 + - ranges 153 + 154 + additionalProperties: false 155 + 156 + examples: 157 + - | 158 + #include <dt-bindings/clock/st,stm32mp25-rcc.h> 159 + #include <dt-bindings/interrupt-controller/arm-gic.h> 160 + #include <dt-bindings/reset/st,stm32mp25-rcc.h> 161 + ommanager@40500000 { 162 + compatible = "st,stm32mp25-omm"; 163 + reg = <0x40500000 0x400>, <0x60000000 0x10000000>; 164 + reg-names = "regs", "memory_map"; 165 + ranges = <0 0 0x40430000 0x400>, 166 + <1 0 0x40440000 0x400>; 167 + memory-region = <&mm_ospi1>, <&mm_ospi2>; 168 + memory-region-names = "ospi1", "ospi2"; 169 + pinctrl-0 = <&ospi_port1_clk_pins_a 170 + &ospi_port1_io03_pins_a 171 + &ospi_port1_cs0_pins_a>; 172 + pinctrl-1 = <&ospi_port1_clk_sleep_pins_a 173 + &ospi_port1_io03_sleep_pins_a 174 + &ospi_port1_cs0_sleep_pins_a>; 175 + pinctrl-names = "default", "sleep"; 176 + clocks = <&rcc CK_BUS_OSPIIOM>, 177 + <&scmi_clk CK_SCMI_OSPI1>, 178 + <&scmi_clk CK_SCMI_OSPI2>; 179 + clock-names = "omm", "ospi1", "ospi2"; 180 + resets = <&rcc OSPIIOM_R>, 181 + <&scmi_reset RST_SCMI_OSPI1>, 182 + <&scmi_reset RST_SCMI_OSPI2>; 183 + reset-names = "omm", "ospi1", "ospi2"; 184 + access-controllers = <&rifsc 111>; 185 + power-domains = <&CLUSTER_PD>; 186 + #address-cells = <2>; 187 + #size-cells = <1>; 188 + st,syscfg-amcr = <&syscfg 0x2c00 0x7>; 189 + st,omm-req2ack-ns = <0>; 190 + st,omm-mux = <0>; 191 + st,omm-cssel-ovr = <0>; 192 + 193 + spi@0 { 194 + compatible = "st,stm32mp25-ospi"; 195 + reg = <0 0 0x400>; 196 + memory-region = <&mm_ospi1>; 197 + interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>; 198 + dmas = <&hpdma 2 0x62 0x00003121 0x0>, 199 + <&hpdma 2 0x42 0x00003112 0x0>; 200 + dma-names = "tx", "rx"; 201 + clocks = <&scmi_clk CK_SCMI_OSPI1>; 202 + resets = <&scmi_reset RST_SCMI_OSPI1>, <&scmi_reset RST_SCMI_OSPI1DLL>; 203 + access-controllers = <&rifsc 74>; 204 + power-domains = <&CLUSTER_PD>; 205 + #address-cells = <1>; 206 + #size-cells = <0>; 207 + st,syscfg-dlyb = <&syscfg 0x1000>; 208 + }; 209 + 210 + spi@1 { 211 + compatible = "st,stm32mp25-ospi"; 212 + reg = <1 0 0x400>; 213 + memory-region = <&mm_ospi1>; 214 + interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>; 215 + dmas = <&hpdma 3 0x62 0x00003121 0x0>, 216 + <&hpdma 3 0x42 0x00003112 0x0>; 217 + dma-names = "tx", "rx"; 218 + clocks = <&scmi_clk CK_KER_OSPI2>; 219 + resets = <&scmi_reset RST_SCMI_OSPI2>, <&scmi_reset RST_SCMI_OSPI1DLL>; 220 + access-controllers = <&rifsc 75>; 221 + power-domains = <&CLUSTER_PD>; 222 + #address-cells = <1>; 223 + #size-cells = <0>; 224 + st,syscfg-dlyb = <&syscfg 0x1000>; 225 + }; 226 + };
+6
MAINTAINERS
··· 22939 22939 S: Maintained 22940 22940 F: drivers/i2c/busses/i2c-stm32* 22941 22941 22942 + ST STM32 OCTO MEMORY MANAGER 22943 + M: Patrice Chotard <patrice.chotard@foss.st.com> 22944 + S: Maintained 22945 + F: Documentation/devicetree/bindings/memory-controllers/st,stm32mp25-omm.yaml 22946 + F: drivers/memory/stm32_omm.c 22947 + 22942 22948 ST STM32 SPI DRIVER 22943 22949 M: Alain Volmat <alain.volmat@foss.st.com> 22944 22950 L: linux-spi@vger.kernel.org
+20 -3
drivers/memory/Kconfig
··· 32 32 33 33 config ATMEL_EBI 34 34 bool "Atmel EBI driver" 35 - default y if ARCH_AT91 35 + default ARCH_AT91 36 36 depends on ARCH_AT91 || COMPILE_TEST 37 37 depends on OF 38 38 select MFD_SYSCON ··· 147 147 148 148 config MVEBU_DEVBUS 149 149 bool "Marvell EBU Device Bus Controller" 150 - default y if PLAT_ORION 150 + default PLAT_ORION 151 151 depends on PLAT_ORION || COMPILE_TEST 152 152 depends on OF 153 153 help ··· 198 198 199 199 config PL353_SMC 200 200 tristate "ARM PL35X Static Memory Controller(SMC) driver" 201 - default y if ARM 201 + default ARM 202 202 depends on ARM || COMPILE_TEST 203 203 depends on ARM_AMBA 204 204 help ··· 224 224 controller. This driver configures the transactions with external 225 225 devices (like SRAM, ethernet adapters, FPGAs, LCD displays, ...) on 226 226 SOCs containing the FMC2 External Bus Interface. 227 + 228 + config STM32_OMM 229 + tristate "STM32 Octo Memory Manager" 230 + depends on SPI_STM32_OSPI || COMPILE_TEST 231 + help 232 + This driver manages the muxing between the 2 OSPI busses and 233 + the 2 output ports. There are 4 possible muxing configurations: 234 + - direct mode (no multiplexing): OSPI1 output is on port 1 and OSPI2 235 + output is on port 2 236 + - OSPI1 and OSPI2 are multiplexed over the same output port 1 237 + - swapped mode (no multiplexing), OSPI1 output is on port 2, 238 + OSPI2 output is on port 1 239 + - OSPI1 and OSPI2 are multiplexed over the same output port 2 240 + It also manages : 241 + - the split of the memory area shared between the 2 OSPI instances. 242 + - chip select selection override. 243 + - the time between 2 transactions in multiplexed mode. 227 244 228 245 source "drivers/memory/samsung/Kconfig" 229 246 source "drivers/memory/tegra/Kconfig"
+1
drivers/memory/Makefile
··· 24 24 obj-$(CONFIG_PL353_SMC) += pl353-smc.o 25 25 obj-$(CONFIG_RENESAS_RPCIF) += renesas-rpc-if.o 26 26 obj-$(CONFIG_STM32_FMC2_EBI) += stm32-fmc2-ebi.o 27 + obj-$(CONFIG_STM32_OMM) += stm32_omm.o 27 28 28 29 obj-$(CONFIG_SAMSUNG_MC) += samsung/ 29 30 obj-$(CONFIG_TEGRA_MC) += tegra/
+1 -1
drivers/memory/bt1-l2-ctl.c
··· 222 222 if (ret) 223 223 return ret; 224 224 225 - return scnprintf(buf, PAGE_SIZE, "%u\n", data); 225 + return sysfs_emit(buf, "%u\n", data); 226 226 } 227 227 228 228 static ssize_t l2_ctl_latency_store(struct device *dev,
+52
drivers/memory/mtk-smi.c
··· 283 283 return 0; 284 284 } 285 285 286 + static const u8 mtk_smi_larb_mt6893_ostd[][SMI_LARB_PORT_NR_MAX] = { 287 + [0] = {0x2, 0x6, 0x2, 0x2, 0x2, 0x28, 0x18, 0x18, 0x1, 0x1, 0x1, 0x8, 288 + 0x8, 0x1, 0x3f}, 289 + [1] = {0x2, 0x6, 0x2, 0x2, 0x2, 0x28, 0x18, 0x18, 0x1, 0x1, 0x1, 0x8, 290 + 0x8, 0x1, 0x3f}, 291 + [2] = {0x5, 0x5, 0x5, 0x5, 0x1, 0x3f}, 292 + [3] = {0x5, 0x5, 0x5, 0x5, 0x1, 0x3f}, 293 + [4] = {0x28, 0x19, 0xb, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x4, 0x1}, 294 + [5] = {0x1, 0x1, 0x4, 0x1, 0x1, 0x1, 0x1, 0x16}, 295 + [6] = {}, 296 + [7] = {0x1, 0x4, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x4, 0x4, 0x1, 297 + 0x4, 0x1, 0xa, 0x6, 0x1, 0xa, 0x6, 0x1, 0x1, 0x1, 0x1, 0x5, 298 + 0x3, 0x3, 0x4}, 299 + [8] = {0x1, 0x4, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x4, 0x4, 0x1, 300 + 0x4, 0x1, 0xa, 0x6, 0x1, 0xa, 0x6, 0x1, 0x1, 0x1, 0x1, 0x5, 301 + 0x3, 0x3, 0x4}, 302 + [9] = {0x9, 0x7, 0xf, 0x8, 0x1, 0x8, 0x9, 0x3, 0x3, 0x6, 0x7, 0x4, 303 + 0x9, 0x3, 0x4, 0xe, 0x1, 0x7, 0x8, 0x7, 0x7, 0x1, 0x6, 0x2, 304 + 0xf, 0x8, 0x1, 0x1, 0x1}, 305 + [10] = {}, 306 + [11] = {0x9, 0x7, 0xf, 0x8, 0x1, 0x8, 0x9, 0x3, 0x3, 0x6, 0x7, 0x4, 307 + 0x9, 0x3, 0x4, 0xe, 0x1, 0x7, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 308 + 0x1, 0x1, 0x1, 0x1, 0x1}, 309 + [12] = {}, 310 + [13] = {0x2, 0xc, 0xc, 0xe, 0x6, 0x6, 0x6, 0x6, 0x6, 0x12, 0x6, 0x1}, 311 + [14] = {0x2, 0xc, 0xc, 0x28, 0x12, 0x6}, 312 + [15] = {0x28, 0x1, 0x2, 0x28, 0x1}, 313 + [16] = {0x28, 0x14, 0x2, 0xc, 0x18, 0x2, 0x14, 0x14, 0x4, 0x4, 0x4, 0x2, 314 + 0x4, 0x2, 0x8, 0x4, 0x4}, 315 + [17] = {0x28, 0x14, 0x2, 0xc, 0x18, 0x2, 0x14, 0x14, 0x4, 0x4, 0x4, 0x2, 316 + 0x4, 0x2, 0x8, 0x4, 0x4}, 317 + [18] = {0x28, 0x14, 0x2, 0xc, 0x18, 0x2, 0x14, 0x14, 0x4, 0x4, 0x4, 0x2, 318 + 0x4, 0x2, 0x8, 0x4, 0x4}, 319 + [19] = {0x2, 0x2, 0x4, 0x2}, 320 + [20] = {0x9, 0x9, 0x5, 0x5, 0x1, 0x1}, 321 + }; 322 + 286 323 static const u8 mtk_smi_larb_mt8188_ostd[][SMI_LARB_PORT_NR_MAX] = { 287 324 [0] = {0x02, 0x18, 0x22, 0x22, 0x01, 0x02, 0x0a,}, 288 325 [1] = {0x12, 0x02, 0x14, 0x14, 0x01, 0x18, 0x0a,}, ··· 466 429 /* DUMMY | IPU0 | IPU1 | CCU | MDLA */ 467 430 }; 468 431 432 + static const struct mtk_smi_larb_gen mtk_smi_larb_mt6893 = { 433 + .config_port = mtk_smi_larb_config_port_gen2_general, 434 + .flags_general = MTK_SMI_FLAG_THRT_UPDATE | MTK_SMI_FLAG_SW_FLAG, 435 + .ostd = mtk_smi_larb_mt6893_ostd, 436 + }; 437 + 469 438 static const struct mtk_smi_larb_gen mtk_smi_larb_mt8167 = { 470 439 /* mt8167 do not need the port in larb */ 471 440 .config_port = mtk_smi_larb_config_port_mt8167, ··· 517 474 {.compatible = "mediatek,mt2712-smi-larb", .data = &mtk_smi_larb_mt2712}, 518 475 {.compatible = "mediatek,mt6779-smi-larb", .data = &mtk_smi_larb_mt6779}, 519 476 {.compatible = "mediatek,mt6795-smi-larb", .data = &mtk_smi_larb_mt8173}, 477 + {.compatible = "mediatek,mt6893-smi-larb", .data = &mtk_smi_larb_mt6893}, 520 478 {.compatible = "mediatek,mt8167-smi-larb", .data = &mtk_smi_larb_mt8167}, 521 479 {.compatible = "mediatek,mt8173-smi-larb", .data = &mtk_smi_larb_mt8173}, 522 480 {.compatible = "mediatek,mt8183-smi-larb", .data = &mtk_smi_larb_mt8183}, ··· 738 694 .init = mtk_smi_common_mt6795_init, 739 695 }; 740 696 697 + static const struct mtk_smi_common_plat mtk_smi_common_mt6893 = { 698 + .type = MTK_SMI_GEN2, 699 + .has_gals = true, 700 + .bus_sel = F_MMU1_LARB(1) | F_MMU1_LARB(2) | F_MMU1_LARB(4) | 701 + F_MMU1_LARB(5) | F_MMU1_LARB(7), 702 + }; 703 + 741 704 static const struct mtk_smi_common_plat mtk_smi_common_mt8183 = { 742 705 .type = MTK_SMI_GEN2, 743 706 .has_gals = true, ··· 807 756 {.compatible = "mediatek,mt2712-smi-common", .data = &mtk_smi_common_gen2}, 808 757 {.compatible = "mediatek,mt6779-smi-common", .data = &mtk_smi_common_mt6779}, 809 758 {.compatible = "mediatek,mt6795-smi-common", .data = &mtk_smi_common_mt6795}, 759 + {.compatible = "mediatek,mt6893-smi-common", .data = &mtk_smi_common_mt6893}, 810 760 {.compatible = "mediatek,mt8167-smi-common", .data = &mtk_smi_common_gen2}, 811 761 {.compatible = "mediatek,mt8173-smi-common", .data = &mtk_smi_common_gen2}, 812 762 {.compatible = "mediatek,mt8183-smi-common", .data = &mtk_smi_common_mt8183},
+1 -14
drivers/memory/omap-gpmc.c
··· 2376 2376 2377 2377 static int gpmc_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) 2378 2378 { 2379 - return 1; /* we're input only */ 2379 + return GPIO_LINE_DIRECTION_IN; /* we're input only */ 2380 2380 } 2381 2381 2382 2382 static int gpmc_gpio_direction_input(struct gpio_chip *chip, 2383 2383 unsigned int offset) 2384 2384 { 2385 2385 return 0; /* we're input only */ 2386 - } 2387 - 2388 - static int gpmc_gpio_direction_output(struct gpio_chip *chip, 2389 - unsigned int offset, int value) 2390 - { 2391 - return -EINVAL; /* we're input only */ 2392 - } 2393 - 2394 - static void gpmc_gpio_set(struct gpio_chip *chip, unsigned int offset, 2395 - int value) 2396 - { 2397 2386 } 2398 2387 2399 2388 static int gpmc_gpio_get(struct gpio_chip *chip, unsigned int offset) ··· 2406 2417 gpmc->gpio_chip.ngpio = gpmc_nr_waitpins; 2407 2418 gpmc->gpio_chip.get_direction = gpmc_gpio_get_direction; 2408 2419 gpmc->gpio_chip.direction_input = gpmc_gpio_direction_input; 2409 - gpmc->gpio_chip.direction_output = gpmc_gpio_direction_output; 2410 - gpmc->gpio_chip.set = gpmc_gpio_set; 2411 2420 gpmc->gpio_chip.get = gpmc_gpio_get; 2412 2421 gpmc->gpio_chip.base = -1; 2413 2422
+476
drivers/memory/stm32_omm.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (C) STMicroelectronics 2025 - All Rights Reserved 4 + * Author(s): Patrice Chotard <patrice.chotard@foss.st.com> for STMicroelectronics. 5 + */ 6 + 7 + #include <linux/bitfield.h> 8 + #include <linux/bus/stm32_firewall_device.h> 9 + #include <linux/clk.h> 10 + #include <linux/err.h> 11 + #include <linux/mfd/syscon.h> 12 + #include <linux/mod_devicetable.h> 13 + #include <linux/module.h> 14 + #include <linux/of_address.h> 15 + #include <linux/of_platform.h> 16 + #include <linux/pinctrl/consumer.h> 17 + #include <linux/pm_runtime.h> 18 + #include <linux/regmap.h> 19 + #include <linux/reset.h> 20 + 21 + #define OMM_CR 0 22 + #define CR_MUXEN BIT(0) 23 + #define CR_MUXENMODE_MASK GENMASK(1, 0) 24 + #define CR_CSSEL_OVR_EN BIT(4) 25 + #define CR_CSSEL_OVR_MASK GENMASK(6, 5) 26 + #define CR_REQ2ACK_MASK GENMASK(23, 16) 27 + 28 + #define OMM_CHILD_NB 2 29 + #define OMM_CLK_NB 3 30 + 31 + struct stm32_omm { 32 + struct resource *mm_res; 33 + struct clk_bulk_data clk_bulk[OMM_CLK_NB]; 34 + struct reset_control *child_reset[OMM_CHILD_NB]; 35 + void __iomem *io_base; 36 + u32 cr; 37 + u8 nb_child; 38 + bool restore_omm; 39 + }; 40 + 41 + static int stm32_omm_set_amcr(struct device *dev, bool set) 42 + { 43 + struct stm32_omm *omm = dev_get_drvdata(dev); 44 + resource_size_t mm_ospi2_size = 0; 45 + static const char * const mm_name[] = { "ospi1", "ospi2" }; 46 + struct regmap *syscfg_regmap; 47 + struct device_node *node; 48 + struct resource res, res1; 49 + u32 amcr_base, amcr_mask; 50 + int ret, idx; 51 + unsigned int i, amcr, read_amcr; 52 + 53 + for (i = 0; i < omm->nb_child; i++) { 54 + idx = of_property_match_string(dev->of_node, 55 + "memory-region-names", 56 + mm_name[i]); 57 + if (idx < 0) 58 + continue; 59 + 60 + /* res1 only used on second loop iteration */ 61 + res1.start = res.start; 62 + res1.end = res.end; 63 + 64 + node = of_parse_phandle(dev->of_node, "memory-region", idx); 65 + if (!node) 66 + continue; 67 + 68 + ret = of_address_to_resource(node, 0, &res); 69 + if (ret) { 70 + of_node_put(node); 71 + dev_err(dev, "unable to resolve memory region\n"); 72 + return ret; 73 + } 74 + 75 + /* check that memory region fits inside OMM memory map area */ 76 + if (!resource_contains(omm->mm_res, &res)) { 77 + dev_err(dev, "%s doesn't fit inside OMM memory map area\n", 78 + mm_name[i]); 79 + dev_err(dev, "%pR doesn't fit inside %pR\n", &res, omm->mm_res); 80 + of_node_put(node); 81 + 82 + return -EFAULT; 83 + } 84 + 85 + if (i == 1) { 86 + mm_ospi2_size = resource_size(&res); 87 + 88 + /* check that OMM memory region 1 doesn't overlap memory region 2 */ 89 + if (resource_overlaps(&res, &res1)) { 90 + dev_err(dev, "OMM memory-region %s overlaps memory region %s\n", 91 + mm_name[0], mm_name[1]); 92 + dev_err(dev, "%pR overlaps %pR\n", &res1, &res); 93 + of_node_put(node); 94 + 95 + return -EFAULT; 96 + } 97 + } 98 + of_node_put(node); 99 + } 100 + 101 + syscfg_regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "st,syscfg-amcr"); 102 + if (IS_ERR(syscfg_regmap)) 103 + return dev_err_probe(dev, PTR_ERR(syscfg_regmap), 104 + "Failed to get st,syscfg-amcr property\n"); 105 + 106 + ret = of_property_read_u32_index(dev->of_node, "st,syscfg-amcr", 1, 107 + &amcr_base); 108 + if (ret) 109 + return ret; 110 + 111 + ret = of_property_read_u32_index(dev->of_node, "st,syscfg-amcr", 2, 112 + &amcr_mask); 113 + if (ret) 114 + return ret; 115 + 116 + amcr = mm_ospi2_size / SZ_64M; 117 + 118 + if (set) 119 + regmap_update_bits(syscfg_regmap, amcr_base, amcr_mask, amcr); 120 + 121 + /* read AMCR and check coherency with memory-map areas defined in DT */ 122 + regmap_read(syscfg_regmap, amcr_base, &read_amcr); 123 + read_amcr = read_amcr >> (ffs(amcr_mask) - 1); 124 + 125 + if (amcr != read_amcr) { 126 + dev_err(dev, "AMCR value not coherent with DT memory-map areas\n"); 127 + ret = -EINVAL; 128 + } 129 + 130 + return ret; 131 + } 132 + 133 + static int stm32_omm_toggle_child_clock(struct device *dev, bool enable) 134 + { 135 + struct stm32_omm *omm = dev_get_drvdata(dev); 136 + int i, ret; 137 + 138 + for (i = 0; i < omm->nb_child; i++) { 139 + if (enable) { 140 + ret = clk_prepare_enable(omm->clk_bulk[i + 1].clk); 141 + if (ret) { 142 + dev_err(dev, "Can not enable clock\n"); 143 + goto clk_error; 144 + } 145 + } else { 146 + clk_disable_unprepare(omm->clk_bulk[i + 1].clk); 147 + } 148 + } 149 + 150 + return 0; 151 + 152 + clk_error: 153 + while (i--) 154 + clk_disable_unprepare(omm->clk_bulk[i + 1].clk); 155 + 156 + return ret; 157 + } 158 + 159 + static int stm32_omm_disable_child(struct device *dev) 160 + { 161 + struct stm32_omm *omm = dev_get_drvdata(dev); 162 + struct reset_control *reset; 163 + int ret; 164 + u8 i; 165 + 166 + ret = stm32_omm_toggle_child_clock(dev, true); 167 + if (!ret) 168 + return ret; 169 + 170 + for (i = 0; i < omm->nb_child; i++) { 171 + /* reset OSPI to ensure CR_EN bit is set to 0 */ 172 + reset = omm->child_reset[i]; 173 + ret = reset_control_acquire(reset); 174 + if (ret) { 175 + stm32_omm_toggle_child_clock(dev, false); 176 + dev_err(dev, "Can not acquire resset %d\n", ret); 177 + return ret; 178 + } 179 + 180 + reset_control_assert(reset); 181 + udelay(2); 182 + reset_control_deassert(reset); 183 + 184 + reset_control_release(reset); 185 + } 186 + 187 + return stm32_omm_toggle_child_clock(dev, false); 188 + } 189 + 190 + static int stm32_omm_configure(struct device *dev) 191 + { 192 + static const char * const clocks_name[] = {"omm", "ospi1", "ospi2"}; 193 + struct stm32_omm *omm = dev_get_drvdata(dev); 194 + unsigned long clk_rate_max = 0; 195 + u32 mux = 0; 196 + u32 cssel_ovr = 0; 197 + u32 req2ack = 0; 198 + struct reset_control *rstc; 199 + unsigned long clk_rate; 200 + int ret; 201 + u8 i; 202 + 203 + for (i = 0; i < OMM_CLK_NB; i++) 204 + omm->clk_bulk[i].id = clocks_name[i]; 205 + 206 + /* retrieve OMM, OSPI1 and OSPI2 clocks */ 207 + ret = devm_clk_bulk_get(dev, OMM_CLK_NB, omm->clk_bulk); 208 + if (ret) 209 + return dev_err_probe(dev, ret, "Failed to get OMM/OSPI's clocks\n"); 210 + 211 + /* Ensure both OSPI instance are disabled before configuring OMM */ 212 + ret = stm32_omm_disable_child(dev); 213 + if (ret) 214 + return ret; 215 + 216 + ret = pm_runtime_resume_and_get(dev); 217 + if (ret < 0) 218 + return ret; 219 + 220 + /* parse children's clock */ 221 + for (i = 1; i <= omm->nb_child; i++) { 222 + clk_rate = clk_get_rate(omm->clk_bulk[i].clk); 223 + if (!clk_rate) { 224 + dev_err(dev, "Invalid clock rate\n"); 225 + goto error; 226 + } 227 + 228 + if (clk_rate > clk_rate_max) 229 + clk_rate_max = clk_rate; 230 + } 231 + 232 + rstc = devm_reset_control_get_exclusive(dev, "omm"); 233 + if (IS_ERR(rstc)) 234 + return dev_err_probe(dev, PTR_ERR(rstc), "reset get failed\n"); 235 + 236 + reset_control_assert(rstc); 237 + udelay(2); 238 + reset_control_deassert(rstc); 239 + 240 + omm->cr = readl_relaxed(omm->io_base + OMM_CR); 241 + /* optional */ 242 + ret = of_property_read_u32(dev->of_node, "st,omm-mux", &mux); 243 + if (!ret) { 244 + if (mux & CR_MUXEN) { 245 + ret = of_property_read_u32(dev->of_node, "st,omm-req2ack-ns", 246 + &req2ack); 247 + if (!ret && !req2ack) { 248 + req2ack = DIV_ROUND_UP(req2ack, NSEC_PER_SEC / clk_rate_max) - 1; 249 + 250 + if (req2ack > 256) 251 + req2ack = 256; 252 + } 253 + 254 + req2ack = FIELD_PREP(CR_REQ2ACK_MASK, req2ack); 255 + 256 + omm->cr &= ~CR_REQ2ACK_MASK; 257 + omm->cr |= FIELD_PREP(CR_REQ2ACK_MASK, req2ack); 258 + 259 + /* 260 + * If the mux is enabled, the 2 OSPI clocks have to be 261 + * always enabled 262 + */ 263 + ret = stm32_omm_toggle_child_clock(dev, true); 264 + if (ret) 265 + goto error; 266 + } 267 + 268 + omm->cr &= ~CR_MUXENMODE_MASK; 269 + omm->cr |= FIELD_PREP(CR_MUXENMODE_MASK, mux); 270 + } 271 + 272 + /* optional */ 273 + ret = of_property_read_u32(dev->of_node, "st,omm-cssel-ovr", &cssel_ovr); 274 + if (!ret) { 275 + omm->cr &= ~CR_CSSEL_OVR_MASK; 276 + omm->cr |= FIELD_PREP(CR_CSSEL_OVR_MASK, cssel_ovr); 277 + omm->cr |= CR_CSSEL_OVR_EN; 278 + } 279 + 280 + omm->restore_omm = true; 281 + writel_relaxed(omm->cr, omm->io_base + OMM_CR); 282 + 283 + ret = stm32_omm_set_amcr(dev, true); 284 + 285 + error: 286 + pm_runtime_put_sync_suspend(dev); 287 + 288 + return ret; 289 + } 290 + 291 + static int stm32_omm_check_access(struct device_node *np) 292 + { 293 + struct stm32_firewall firewall; 294 + int ret; 295 + 296 + ret = stm32_firewall_get_firewall(np, &firewall, 1); 297 + if (ret) 298 + return ret; 299 + 300 + return stm32_firewall_grant_access(&firewall); 301 + } 302 + 303 + static int stm32_omm_probe(struct platform_device *pdev) 304 + { 305 + static const char * const resets_name[] = {"ospi1", "ospi2"}; 306 + struct device *dev = &pdev->dev; 307 + u8 child_access_granted = 0; 308 + struct stm32_omm *omm; 309 + int i, ret; 310 + 311 + omm = devm_kzalloc(dev, sizeof(*omm), GFP_KERNEL); 312 + if (!omm) 313 + return -ENOMEM; 314 + 315 + omm->io_base = devm_platform_ioremap_resource_byname(pdev, "regs"); 316 + if (IS_ERR(omm->io_base)) 317 + return PTR_ERR(omm->io_base); 318 + 319 + omm->mm_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "memory_map"); 320 + if (IS_ERR(omm->mm_res)) 321 + return PTR_ERR(omm->mm_res); 322 + 323 + /* check child's access */ 324 + for_each_child_of_node_scoped(dev->of_node, child) { 325 + if (omm->nb_child >= OMM_CHILD_NB) { 326 + dev_err(dev, "Bad DT, found too much children\n"); 327 + return -E2BIG; 328 + } 329 + 330 + ret = stm32_omm_check_access(child); 331 + if (ret < 0 && ret != -EACCES) 332 + return ret; 333 + 334 + if (!ret) 335 + child_access_granted++; 336 + 337 + omm->nb_child++; 338 + } 339 + 340 + if (omm->nb_child != OMM_CHILD_NB) 341 + return -EINVAL; 342 + 343 + platform_set_drvdata(pdev, omm); 344 + 345 + devm_pm_runtime_enable(dev); 346 + 347 + /* check if OMM's resource access is granted */ 348 + ret = stm32_omm_check_access(dev->of_node); 349 + if (ret < 0 && ret != -EACCES) 350 + return ret; 351 + 352 + for (i = 0; i < omm->nb_child; i++) { 353 + omm->child_reset[i] = devm_reset_control_get_exclusive_released(dev, 354 + resets_name[i]); 355 + 356 + if (IS_ERR(omm->child_reset[i])) 357 + return dev_err_probe(dev, PTR_ERR(omm->child_reset[i]), 358 + "Can't get %s reset\n", resets_name[i]); 359 + } 360 + 361 + if (!ret && child_access_granted == OMM_CHILD_NB) { 362 + ret = stm32_omm_configure(dev); 363 + if (ret) 364 + return ret; 365 + } else { 366 + dev_dbg(dev, "Octo Memory Manager resource's access not granted\n"); 367 + /* 368 + * AMCR can't be set, so check if current value is coherent 369 + * with memory-map areas defined in DT 370 + */ 371 + ret = stm32_omm_set_amcr(dev, false); 372 + if (ret) 373 + return ret; 374 + } 375 + 376 + ret = devm_of_platform_populate(dev); 377 + if (ret) { 378 + if (omm->cr & CR_MUXEN) 379 + stm32_omm_toggle_child_clock(&pdev->dev, false); 380 + 381 + return dev_err_probe(dev, ret, "Failed to create Octo Memory Manager child\n"); 382 + } 383 + 384 + return 0; 385 + } 386 + 387 + static void stm32_omm_remove(struct platform_device *pdev) 388 + { 389 + struct stm32_omm *omm = platform_get_drvdata(pdev); 390 + 391 + if (omm->cr & CR_MUXEN) 392 + stm32_omm_toggle_child_clock(&pdev->dev, false); 393 + } 394 + 395 + static const struct of_device_id stm32_omm_of_match[] = { 396 + { .compatible = "st,stm32mp25-omm", }, 397 + {} 398 + }; 399 + MODULE_DEVICE_TABLE(of, stm32_omm_of_match); 400 + 401 + static int __maybe_unused stm32_omm_runtime_suspend(struct device *dev) 402 + { 403 + struct stm32_omm *omm = dev_get_drvdata(dev); 404 + 405 + clk_disable_unprepare(omm->clk_bulk[0].clk); 406 + 407 + return 0; 408 + } 409 + 410 + static int __maybe_unused stm32_omm_runtime_resume(struct device *dev) 411 + { 412 + struct stm32_omm *omm = dev_get_drvdata(dev); 413 + 414 + return clk_prepare_enable(omm->clk_bulk[0].clk); 415 + } 416 + 417 + static int __maybe_unused stm32_omm_suspend(struct device *dev) 418 + { 419 + struct stm32_omm *omm = dev_get_drvdata(dev); 420 + 421 + if (omm->restore_omm && omm->cr & CR_MUXEN) 422 + stm32_omm_toggle_child_clock(dev, false); 423 + 424 + return pinctrl_pm_select_sleep_state(dev); 425 + } 426 + 427 + static int __maybe_unused stm32_omm_resume(struct device *dev) 428 + { 429 + struct stm32_omm *omm = dev_get_drvdata(dev); 430 + int ret; 431 + 432 + pinctrl_pm_select_default_state(dev); 433 + 434 + if (!omm->restore_omm) 435 + return 0; 436 + 437 + /* Ensure both OSPI instance are disabled before configuring OMM */ 438 + ret = stm32_omm_disable_child(dev); 439 + if (ret) 440 + return ret; 441 + 442 + ret = pm_runtime_resume_and_get(dev); 443 + if (ret < 0) 444 + return ret; 445 + 446 + writel_relaxed(omm->cr, omm->io_base + OMM_CR); 447 + ret = stm32_omm_set_amcr(dev, true); 448 + pm_runtime_put_sync_suspend(dev); 449 + if (ret) 450 + return ret; 451 + 452 + if (omm->cr & CR_MUXEN) 453 + ret = stm32_omm_toggle_child_clock(dev, true); 454 + 455 + return ret; 456 + } 457 + 458 + static const struct dev_pm_ops stm32_omm_pm_ops = { 459 + SET_RUNTIME_PM_OPS(stm32_omm_runtime_suspend, 460 + stm32_omm_runtime_resume, NULL) 461 + SET_SYSTEM_SLEEP_PM_OPS(stm32_omm_suspend, stm32_omm_resume) 462 + }; 463 + 464 + static struct platform_driver stm32_omm_driver = { 465 + .probe = stm32_omm_probe, 466 + .remove = stm32_omm_remove, 467 + .driver = { 468 + .name = "stm32-omm", 469 + .of_match_table = stm32_omm_of_match, 470 + .pm = &stm32_omm_pm_ops, 471 + }, 472 + }; 473 + module_platform_driver(stm32_omm_driver); 474 + 475 + MODULE_DESCRIPTION("STMicroelectronics Octo Memory Manager driver"); 476 + MODULE_LICENSE("GPL");
+4 -4
drivers/memory/tegra/Kconfig
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 2 config TEGRA_MC 3 3 bool "NVIDIA Tegra Memory Controller support" 4 - default y 4 + default ARCH_TEGRA 5 5 depends on ARCH_TEGRA || (COMPILE_TEST && COMMON_CLK) 6 6 select INTERCONNECT 7 7 help ··· 12 12 13 13 config TEGRA20_EMC 14 14 tristate "NVIDIA Tegra20 External Memory Controller driver" 15 - default y 15 + default ARCH_TEGRA_2x_SOC 16 16 depends on ARCH_TEGRA_2x_SOC || COMPILE_TEST 17 17 select DEVFREQ_GOV_SIMPLE_ONDEMAND 18 18 select PM_DEVFREQ ··· 25 25 26 26 config TEGRA30_EMC 27 27 tristate "NVIDIA Tegra30 External Memory Controller driver" 28 - default y 28 + default ARCH_TEGRA_3x_SOC 29 29 depends on ARCH_TEGRA_3x_SOC || COMPILE_TEST 30 30 select PM_OPP 31 31 select DDR ··· 37 37 38 38 config TEGRA124_EMC 39 39 tristate "NVIDIA Tegra124 External Memory Controller driver" 40 - default y 40 + default ARCH_TEGRA_124_SOC 41 41 depends on ARCH_TEGRA_124_SOC || COMPILE_TEST 42 42 select TEGRA124_CLK_EMC if ARCH_TEGRA 43 43 select PM_OPP
+9 -6
include/linux/bus/stm32_firewall_device.h
··· 114 114 115 115 #else /* CONFIG_STM32_FIREWALL */ 116 116 117 - int stm32_firewall_get_firewall(struct device_node *np, struct stm32_firewall *firewall, 118 - unsigned int nb_firewall) 117 + static inline int stm32_firewall_get_firewall(struct device_node *np, 118 + struct stm32_firewall *firewall, 119 + unsigned int nb_firewall) 119 120 { 120 121 return -ENODEV; 121 122 } 122 123 123 - int stm32_firewall_grant_access(struct stm32_firewall *firewall) 124 + static inline int stm32_firewall_grant_access(struct stm32_firewall *firewall) 124 125 { 125 126 return -ENODEV; 126 127 } 127 128 128 - void stm32_firewall_release_access(struct stm32_firewall *firewall) 129 + static inline void stm32_firewall_release_access(struct stm32_firewall *firewall) 129 130 { 130 131 } 131 132 132 - int stm32_firewall_grant_access_by_id(struct stm32_firewall *firewall, u32 subsystem_id) 133 + static inline int stm32_firewall_grant_access_by_id(struct stm32_firewall *firewall, 134 + u32 subsystem_id) 133 135 { 134 136 return -ENODEV; 135 137 } 136 138 137 - void stm32_firewall_release_access_by_id(struct stm32_firewall *firewall, u32 subsystem_id) 139 + static inline void stm32_firewall_release_access_by_id(struct stm32_firewall *firewall, 140 + u32 subsystem_id) 138 141 { 139 142 } 140 143