Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
250 changes: 250 additions & 0 deletions Documentation/devicetree/bindings/soc/adi/adi,sc59x-smpu.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/soc/adi/adi,sc59x-smpu.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Analog Devices SC59x System Memory Protection Unit

maintainers:
- Ozan Durgut <ozan.durgut@analog.com>
- Analog Devices <linux@analog.com>

description: |
The System Memory Protection Unit (SMPU) provides hardware-based memory
protection for ADSP-SC59x processors. Each SMPU instance can configure up
to 8 protection regions with transaction ID-based access control.

There are 9 SMPU instances in SC59x processors protecting different memory
domains:
- SMPU0 (0x31007000): L2 SRAM Banks 0-3, Boot ROM0
- SMPU2 (0x31083000): L2 SRAM Banks 4-7, Boot ROM1-2
- SMPU3 (0x31084000): L2 SRAM Banks 0-7 (Instruction Port)
- SMPU4 (0x31085000): L2 DMA Port 0
- SMPU5 (0x31086000): L2 DMA Port 1
- SMPU6 (0x31087000): Reserved
- SMPU9 (0x310A0000): DDR3 Memory Controller
- SMPU11 (0x310A1000): SPI2/OSPI Flash
- SMPU12 (0x31012000): OTP Memory

Each region can be configured with:
- Base address and size (power-of-2, 4KB to 4GB)
- Read/write protection independently
- Transaction ID filtering with dual match units and masks
- Inversion logic for blocking specific IDs

Silicon Anomaly 20000003: Non-secure accesses to SMPU registers in range
0x800-0xFFF cause erroneous bus errors. The driver handles this by avoiding
these registers unless the adi,secure-access property indicates secure mode.

properties:
compatible:
const: adi,sc59x-smpu

reg:
description: Register regions for each SMPU instance
minItems: 1
maxItems: 9

reg-names:
description: Names for each SMPU instance (sparse numbering)
minItems: 1
maxItems: 9
items:
enum:
- smpu0
- smpu2
- smpu3
- smpu4
- smpu5
- smpu6
- smpu9
- smpu11
- smpu12

interrupts:
description: Protection violation interrupt (SEC ID 217)
maxItems: 1

adi,secure-access:
type: boolean
description: |
Driver has secure-mode access and can program registers at offset
0x800-0xFFF (SMPU_SECURECTL and SMPU_SECURERCTL).

If absent, driver avoids these registers to work around Anomaly 20000003
(non-secure access causes bus errors). Basic protection still works via
registers at 0x00-0x7FF.

static-regions:
type: object
description: |
Optional static protection regions to be configured at boot time.
Each child node defines a region with base address, size, permissions,
and allowed transaction IDs. These regions are automatically configured
and enabled during driver probe.
patternProperties:
"^region-[0-9]+$":
type: object
properties:
instance:
$ref: /schemas/types.yaml#/definitions/uint32
description: SMPU instance ID (0, 2-6, 9, 11-12)

memory-region:
$ref: /schemas/types.yaml#/definitions/phandle
description: |
Reference to reserved-memory node. Preferred method for defining
base and size.

base:
$ref: /schemas/types.yaml#/definitions/uint64
description: |
Physical base address (alternative to memory-region). Must be
aligned to region size.

size:
$ref: /schemas/types.yaml#/definitions/uint64
description: |
Region size (alternative to memory-region). Must be power of 2,
minimum 4KB, maximum 4GB.

permissions:
$ref: /schemas/types.yaml#/definitions/uint32
description: |
Access permissions bitmap:
bit 0: Read enable
bit 1: Write enable
bit 2: Execute enable
Default is 0x3 (read/write).

allowed-ids:
$ref: /schemas/types.yaml#/definitions/uint32-array
minItems: 1
maxItems: 2
description: |
Transaction IDs allowed to access this region (up to 2).
13-bit IDs identifying bus masters (CPU cores, DMA, etc).

id-masks:
$ref: /schemas/types.yaml#/definitions/uint32-array
minItems: 1
maxItems: 2
description: |
Masks for transaction ID matching (0x0000 = match all,
0x1FFF = exact match). Default is 0x1FFF for exact matching.

id-invert-a:
type: boolean
description: Invert ID match logic for first ID (block instead of allow)

id-invert-b:
type: boolean
description: Invert ID match logic for second ID (block instead of allow)

secure-only:
type: boolean
description: |
Allow only secure transactions. Blocks all non-secure accesses.
Only effective if adi,secure-access property is set.
Cannot be combined with non-secure-only.

non-secure-only:
type: boolean
description: |
Allow only non-secure transactions. Blocks all secure accesses.
Useful for non-secure peripherals in TrustZone systems.
Cannot be combined with secure-only.

required:
- instance

oneOf:
- required:
- memory-region
- required:
- base
- size

required:
- compatible
- reg
- reg-names

additionalProperties: false

examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interrupt-controller/irq.h>

/* Basic configuration without static regions */
smpu: smpu@31007000 {
compatible = "adi,sc59x-smpu";
reg = <0x31007000 0x1000>, /* SMPU0 */
<0x31083000 0x1000>, /* SMPU2 */
<0x31084000 0x1000>, /* SMPU3 */
<0x31085000 0x1000>, /* SMPU4 */
<0x31086000 0x1000>, /* SMPU5 */
<0x31087000 0x1000>, /* SMPU6 */
<0x310A0000 0x1000>, /* SMPU9 */
<0x310A1000 0x1000>, /* SMPU11 */
<0x31012000 0x1000>; /* SMPU12 */
reg-names = "smpu0", "smpu2", "smpu3", "smpu4", "smpu5",
"smpu6", "smpu9", "smpu11", "smpu12";
interrupts = <GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH>;
};

- |
#include <dt-bindings/interrupt-controller/arm-gic.h>

/* Example with static protection regions */
reserved-memory {
#address-cells = <1>;
#size-cells = <1>;
ranges;

dsp_memory: dsp@20000000 {
reg = <0x20000000 0x100000>; /* 1MB for DSP */
no-map;
};

sharc_memory: sharc@20100000 {
reg = <0x20100000 0x200000>; /* 2MB for SHARC+ */
no-map;
};
};

smpu: smpu@31007000 {
compatible = "adi,sc59x-smpu";
reg = <0x31007000 0x1000>, /* SMPU0 */
<0x310A0000 0x1000>; /* SMPU9 (DDR) */
reg-names = "smpu0", "smpu9";
interrupts = <GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH>;

/* Static protection regions configured at boot */
static-regions {
region-0 {
instance = <0>; /* SMPU0: L2 SRAM */
memory-region = <&dsp_memory>;
permissions = <0x3>; /* Read/Write */
allowed-ids = <0x100>; /* DSP core transaction ID */
};

region-1 {
instance = <0>; /* SMPU0: L2 SRAM */
memory-region = <&sharc_memory>;
permissions = <0x3>; /* Read/Write */
allowed-ids = <0x200 0x201>; /* SHARC+ cores */
};

region-2 {
instance = <9>; /* SMPU9: DDR protection */
base = <0x80000000>;
size = <0x40000000>; /* 1GB DDR */
permissions = <0x7>; /* Read/Write/Execute */
allowed-ids = <0x100 0x200>; /* DSP and SHARC */
id-masks = <0x1FFF 0x1FF0>; /* Exact and range match */
};
};
};
29 changes: 29 additions & 0 deletions arch/arm64/boot/dts/adi/sc59x-64.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@
reg = <0x20005000 0x20000>; /*128KiB*/
no-map;
};

};

scb {
Expand Down Expand Up @@ -248,6 +249,34 @@
status = "okay";
};

smpu: smpu@31083000 {
compatible = "adi,sc59x-smpu";
reg = <0x31083000 0x1000>, /* SMPU2 - L2 SRAM Port 1 */
<0x31084000 0x1000>, /* SMPU3 - L2 SRAM Port 2 */
<0x31085000 0x1000>, /* SMPU4 - L2 DMA Port 0 */
<0x31086000 0x1000>, /* SMPU5 - L2 DMA Port 1 */
/* <0x31087000 0x1000>, SMPU6 - Reserved */
<0x310A0000 0x1000>, /* SMPU9 - DDR Memory Controller */
<0x310A1000 0x1000>, /* SMPU11 - SPI2/OSPI Flash */
/* <0x31012000 0x1000>; SMPU12 - OTP Memory */
reg-names = "smpu2", "smpu3", "smpu4", "smpu5",
"smpu9", "smpu11";
interrupts = <GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH>;
status = "okay";

static-regions {
/* Test region on SMPU2 */
region-test-l2 {
instance = <2>; /* SMPU2: L2 SRAM Port 1 */
base = <0x20040000>; /* L2 SRAM bank 1 */
size = <0x40000>; /* 256KB */
permissions = <0x1>; /* Read-only */
allowed-ids = <0x0289 0>; /* ARM A55 TID */
id-masks = <0x1FFF 0>; /* Exact match */
};
};
};

tru: tru@3108a000 {
compatible = "adi,trigger-routing-unit";
reg = <0x3108a000 0x1000>;
Expand Down
8 changes: 8 additions & 0 deletions drivers/soc/adi/Kconfig
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# SPDX-License-Identifier: GPL-2.0-only

config ADI_SYSTEM_CONFIG
Expand All @@ -16,3 +16,11 @@
help
This enables support for the ADI PADS System Config driver,
which manages pin configuration and other system settings.

config ADI_SC59X_SMPU

Check warning on line 20 in drivers/soc/adi/Kconfig

View workflow job for this annotation

GitHub Actions / checks / checks

checkpatch: please write a help paragraph that fully describes the config symbol with at least 4 lines +config ADI_SC59X_SMPU + tristate "ADI SC59x System Memory Protection Unit" + depends on ARCH_SC59X_64 || COMPILE_TEST + default ARCH_SC59X_64 + help + This enables support for the SMPU (System Memory Protection Unit) + on Analog Devices SC59x processors (SC595/SC596/SC598).
tristate "ADI SC59x System Memory Protection Unit"
depends on ARCH_SC59X_64 || COMPILE_TEST
default ARCH_SC59X_64
help
This enables support for the SMPU (System Memory Protection Unit)
on Analog Devices SC59x processors (SC595/SC596/SC598).
1 change: 1 addition & 0 deletions drivers/soc/adi/mach-sc59x/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
# todo modularize with kconfigs

obj-y := core.o
obj-$(CONFIG_ADI_SC59X_SMPU) += smpu.o
Loading
Loading