mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-04 20:19:47 +08:00
soc: driver updates for 6.17
Changes are all over the place, but very little sticks out as noteworthy. There is a new misc driver for the Raspberry Pi 5's RP1 multifunction I/O chip, along with hooking it up to the pinctrl and clk frameworks. The reset controller and memory subsystems have mainly small updates, but there are two new reset drivers for the K230 and VC1800B SoCs, and new memory driver support for Tegra264. The ARM SMCCC and SCMI firmware drivers gain a few more features that should help them be supported across more environments. Similarly, the SoC specific firmware on Tegra and Qualcomm get minor enhancements and chip support. In the drivers/soc/ directory, the ASPEED LPC snoop driver gets an overhaul for code robustness, the Tegra and Qualcomm and NXP drivers grow to support more chips, while the Hisilicon, Mediatek and Renesas drivers see mostly janitorial fixes. -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEo6/YBQwIrVS28WGKmmx57+YAGNkFAmiEmIcACgkQmmx57+YA GNkE4g/6A2OKti+qtIsLt10zS7paGP38ftu9ad27WC54AOGgVk4ZXt8mVGRmqOf+ BICIM+wc4gehdvRJTRnq3gZg3e1puuYdcMuBOh4qsghRMjdYUKfNairtn/iX7d+f e5auzz5/gV7MWNM7jiQNydCqZSeV6u2/cqD5iRCrRgaB5FOG4yY1BkAsah1UzZjk MycudqjkK4IX5zp5oqXB/PoesULAbB2unjvfw194LATYSqmcRLQRWFdv4aM0R6ba TDP5x0d95nhMTNWif3495zc2WxdSYzbD4lNv44RPpKDywqBj+qFBI/EpMFkxQ5Hy cqv60Dm+/tx+DBO/Ma0zJzsV4ChRIEBNkTUh36OxmYxq70x1T4FEynZ6IT8a8dXD ltjHwOcTHp1M0OpNj+PIFBD+ohWFWKOo+T9GRtTInLjUGBlJA6LK9i4Lb0DaIyRt DmmvbZCwh0PI/nZiyQzw7rsXWwqDcqeF8FScw+9ooBk7Z7Jr1gMc52ya0qrRWQ8w Tr3D+lNE0aDfErnx4RrNsjD8lpX4nOfRFvuWSTlWqkBjGhoDP/tnNi2RCWmbXo2Z PDDWLnECo6o1aIxYO/tHjbFKVJB38p4e/LLP89htu8dFxSZKnVzxosnOvEVWS8+Y a0oZb9j1tAOYHmMWDm+zaQ7BlK9CMURNTdUcnqNqIvZpHnHz9M8= =7T40 -----END PGP SIGNATURE----- Merge tag 'soc-drivers-6.17' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc Pull SoC driver updates from Arnd Bergmann: "Changes are all over the place, but very little sticks out as noteworthy. There is a new misc driver for the Raspberry Pi 5's RP1 multifunction I/O chip, along with hooking it up to the pinctrl and clk frameworks. The reset controller and memory subsystems have mainly small updates, but there are two new reset drivers for the K230 and VC1800B SoCs, and new memory driver support for Tegra264. The ARM SMCCC and SCMI firmware drivers gain a few more features that should help them be supported across more environments. Similarly, the SoC specific firmware on Tegra and Qualcomm get minor enhancements and chip support. In the drivers/soc/ directory, the ASPEED LPC snoop driver gets an overhaul for code robustness, the Tegra and Qualcomm and NXP drivers grow to support more chips, while the Hisilicon, Mediatek and Renesas drivers see mostly janitorial fixes" * tag 'soc-drivers-6.17' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc: (100 commits) bus: del unnecessary init var soc: fsl: qe: convert set_multiple() to returning an integer pinctrl: rp1: use new GPIO line value setter callbacks soc: hisilicon: kunpeng_hccs: Fix incorrect log information dt-bindings: soc: qcom: qcom,pmic-glink: document Milos compatible dt-bindings: soc: qcom,aoss-qmp: document the Milos Always-On Subsystem side channel dt-bindings: firmware: qcom,scm: document Milos SCM Firmware Interface soc: qcom: socinfo: Add support to retrieve APPSBL build details soc: qcom: pmic_glink: fix OF node leak soc: qcom: spmi-pmic: add more PMIC SUBTYPE IDs soc: qcom: socinfo: Add PM7550 & PMIV0108 PMICs soc: qcom: socinfo: Add SoC IDs for SM7635 family dt-bindings: arm: qcom,ids: Add SoC IDs for SM7635 family firmware: qcom: scm: request the waitqueue irq *after* initializing SCM firmware: qcom: scm: initialize tzmem before marking SCM as available firmware: qcom: scm: take struct device as argument in SHM bridge enable firmware: qcom: scm: remove unused arguments from SHM bridge routines soc: qcom: rpmh-rsc: Add RSC version 4 support memory: tegra: Add Tegra264 MC and EMC support firmware: tegra: bpmp: Fix build failure for tegra264-only config ...
This commit is contained in:
commit
0f46f50845
@ -200,6 +200,7 @@ properties:
|
|||||||
- qcom,kryo385
|
- qcom,kryo385
|
||||||
- qcom,kryo465
|
- qcom,kryo465
|
||||||
- qcom,kryo468
|
- qcom,kryo468
|
||||||
|
- qcom,kryo470
|
||||||
- qcom,kryo485
|
- qcom,kryo485
|
||||||
- qcom,kryo560
|
- qcom,kryo560
|
||||||
- qcom,kryo570
|
- qcom,kryo570
|
||||||
|
@ -32,6 +32,7 @@ properties:
|
|||||||
- qcom,scm-ipq8074
|
- qcom,scm-ipq8074
|
||||||
- qcom,scm-ipq9574
|
- qcom,scm-ipq9574
|
||||||
- qcom,scm-mdm9607
|
- qcom,scm-mdm9607
|
||||||
|
- qcom,scm-milos
|
||||||
- qcom,scm-msm8226
|
- qcom,scm-msm8226
|
||||||
- qcom,scm-msm8660
|
- qcom,scm-msm8660
|
||||||
- qcom,scm-msm8916
|
- qcom,scm-msm8916
|
||||||
@ -198,6 +199,7 @@ allOf:
|
|||||||
compatible:
|
compatible:
|
||||||
contains:
|
contains:
|
||||||
enum:
|
enum:
|
||||||
|
- qcom,scm-milos
|
||||||
- qcom,scm-sm8450
|
- qcom,scm-sm8450
|
||||||
- qcom,scm-sm8550
|
- qcom,scm-sm8550
|
||||||
- qcom,scm-sm8650
|
- qcom,scm-sm8650
|
||||||
|
@ -1,127 +0,0 @@
|
|||||||
* Device tree bindings for ARM PL172/PL175/PL176 MultiPort Memory Controller
|
|
||||||
|
|
||||||
Required properties:
|
|
||||||
|
|
||||||
- compatible: Must be "arm,primecell" and exactly one from
|
|
||||||
"arm,pl172", "arm,pl175" or "arm,pl176".
|
|
||||||
|
|
||||||
- reg: Must contains offset/length value for controller.
|
|
||||||
|
|
||||||
- #address-cells: Must be 2. The partition number has to be encoded in the
|
|
||||||
first address cell and it may accept values 0..N-1
|
|
||||||
(N - total number of partitions). The second cell is the
|
|
||||||
offset into the partition.
|
|
||||||
|
|
||||||
- #size-cells: Must be set to 1.
|
|
||||||
|
|
||||||
- ranges: Must contain one or more chip select memory regions.
|
|
||||||
|
|
||||||
- clocks: Must contain references to controller clocks.
|
|
||||||
|
|
||||||
- clock-names: Must contain "mpmcclk" and "apb_pclk".
|
|
||||||
|
|
||||||
- clock-ranges: Empty property indicating that child nodes can inherit
|
|
||||||
named clocks. Required only if clock tree data present
|
|
||||||
in device tree.
|
|
||||||
See clock-bindings.txt
|
|
||||||
|
|
||||||
Child chip-select (cs) nodes contain the memory devices nodes connected to
|
|
||||||
such as NOR (e.g. cfi-flash) and NAND.
|
|
||||||
|
|
||||||
Required child cs node properties:
|
|
||||||
|
|
||||||
- #address-cells: Must be 2.
|
|
||||||
|
|
||||||
- #size-cells: Must be 1.
|
|
||||||
|
|
||||||
- ranges: Empty property indicating that child nodes can inherit
|
|
||||||
memory layout.
|
|
||||||
|
|
||||||
- clock-ranges: Empty property indicating that child nodes can inherit
|
|
||||||
named clocks. Required only if clock tree data present
|
|
||||||
in device tree.
|
|
||||||
|
|
||||||
- mpmc,cs: Chip select number. Indicates to the pl0172 driver
|
|
||||||
which chipselect is used for accessing the memory.
|
|
||||||
|
|
||||||
- mpmc,memory-width: Width of the chip select memory. Must be equal to
|
|
||||||
either 8, 16 or 32.
|
|
||||||
|
|
||||||
Optional child cs node config properties:
|
|
||||||
|
|
||||||
- mpmc,async-page-mode: Enable asynchronous page mode.
|
|
||||||
|
|
||||||
- mpmc,cs-active-high: Set chip select polarity to active high.
|
|
||||||
|
|
||||||
- mpmc,byte-lane-low: Set byte lane state to low.
|
|
||||||
|
|
||||||
- mpmc,extended-wait: Enable extended wait.
|
|
||||||
|
|
||||||
- mpmc,buffer-enable: Enable write buffer, option is not supported by
|
|
||||||
PL175 and PL176 controllers.
|
|
||||||
|
|
||||||
- mpmc,write-protect: Enable write protect.
|
|
||||||
|
|
||||||
Optional child cs node timing properties:
|
|
||||||
|
|
||||||
- mpmc,write-enable-delay: Delay from chip select assertion to write
|
|
||||||
enable (WE signal) in nano seconds.
|
|
||||||
|
|
||||||
- mpmc,output-enable-delay: Delay from chip select assertion to output
|
|
||||||
enable (OE signal) in nano seconds.
|
|
||||||
|
|
||||||
- mpmc,write-access-delay: Delay from chip select assertion to write
|
|
||||||
access in nano seconds.
|
|
||||||
|
|
||||||
- mpmc,read-access-delay: Delay from chip select assertion to read
|
|
||||||
access in nano seconds.
|
|
||||||
|
|
||||||
- mpmc,page-mode-read-delay: Delay for asynchronous page mode sequential
|
|
||||||
accesses in nano seconds.
|
|
||||||
|
|
||||||
- mpmc,turn-round-delay: Delay between access to memory banks in nano
|
|
||||||
seconds.
|
|
||||||
|
|
||||||
If any of the above timing parameters are absent, current parameter value will
|
|
||||||
be taken from the corresponding HW reg.
|
|
||||||
|
|
||||||
Example for pl172 with nor flash on chip select 0 shown below.
|
|
||||||
|
|
||||||
emc: memory-controller@40005000 {
|
|
||||||
compatible = "arm,pl172", "arm,primecell";
|
|
||||||
reg = <0x40005000 0x1000>;
|
|
||||||
clocks = <&ccu1 CLK_CPU_EMCDIV>, <&ccu1 CLK_CPU_EMC>;
|
|
||||||
clock-names = "mpmcclk", "apb_pclk";
|
|
||||||
#address-cells = <2>;
|
|
||||||
#size-cells = <1>;
|
|
||||||
ranges = <0 0 0x1c000000 0x1000000
|
|
||||||
1 0 0x1d000000 0x1000000
|
|
||||||
2 0 0x1e000000 0x1000000
|
|
||||||
3 0 0x1f000000 0x1000000>;
|
|
||||||
|
|
||||||
cs0 {
|
|
||||||
#address-cells = <2>;
|
|
||||||
#size-cells = <1>;
|
|
||||||
ranges;
|
|
||||||
|
|
||||||
mpmc,cs = <0>;
|
|
||||||
mpmc,memory-width = <16>;
|
|
||||||
mpmc,byte-lane-low;
|
|
||||||
mpmc,write-enable-delay = <0>;
|
|
||||||
mpmc,output-enable-delay = <0>;
|
|
||||||
mpmc,read-enable-delay = <70>;
|
|
||||||
mpmc,page-mode-read-delay = <70>;
|
|
||||||
|
|
||||||
flash@0,0 {
|
|
||||||
compatible = "sst,sst39vf320", "cfi-flash";
|
|
||||||
reg = <0 0 0x400000>;
|
|
||||||
bank-width = <2>;
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <1>;
|
|
||||||
partition@0 {
|
|
||||||
label = "data";
|
|
||||||
reg = <0 0x400000>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
@ -0,0 +1,222 @@
|
|||||||
|
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/memory-controllers/arm,pl172.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: ARM PL172/PL175/PL176 MultiPort Memory Controller
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Frank Li <Frank.Li@nxp.com>
|
||||||
|
|
||||||
|
# We need a select here so we don't match all nodes with 'arm,primecell'
|
||||||
|
select:
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
contains:
|
||||||
|
enum:
|
||||||
|
- arm,pl172
|
||||||
|
- arm,pl175
|
||||||
|
- arm,pl176
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
items:
|
||||||
|
- enum:
|
||||||
|
- arm,pl172
|
||||||
|
- arm,pl175
|
||||||
|
- arm,pl176
|
||||||
|
- const: arm,primecell
|
||||||
|
|
||||||
|
reg:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
'#address-cells':
|
||||||
|
const: 2
|
||||||
|
|
||||||
|
'#size-cells':
|
||||||
|
const: 1
|
||||||
|
|
||||||
|
ranges: true
|
||||||
|
|
||||||
|
clocks:
|
||||||
|
maxItems: 2
|
||||||
|
|
||||||
|
clock-names:
|
||||||
|
items:
|
||||||
|
- const: mpmcclk
|
||||||
|
- const: apb_pclk
|
||||||
|
|
||||||
|
clock-ranges: true
|
||||||
|
|
||||||
|
resets:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
patternProperties:
|
||||||
|
"^cs[0-9]$":
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
patternProperties:
|
||||||
|
"^flash@[0-9],[0-9a-f]+$":
|
||||||
|
type: object
|
||||||
|
$ref: /schemas/mtd/mtd-physmap.yaml#
|
||||||
|
unevaluatedProperties: false
|
||||||
|
|
||||||
|
"^(gpio|sram)@[0-9],[0-9a-f]+$":
|
||||||
|
type: object
|
||||||
|
additionalProperties: true
|
||||||
|
|
||||||
|
properties:
|
||||||
|
'#address-cells':
|
||||||
|
const: 2
|
||||||
|
|
||||||
|
'#size-cells':
|
||||||
|
const: 1
|
||||||
|
|
||||||
|
ranges: true
|
||||||
|
|
||||||
|
clocks:
|
||||||
|
maxItems: 2
|
||||||
|
|
||||||
|
clock-ranges: true
|
||||||
|
|
||||||
|
mpmc,cs:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/uint32
|
||||||
|
description:
|
||||||
|
Chip select number. Indicates to the pl0172 driver
|
||||||
|
which chipselect is used for accessing the memory.
|
||||||
|
|
||||||
|
mpmc,memory-width:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/uint32
|
||||||
|
enum: [8, 16, 32]
|
||||||
|
description:
|
||||||
|
Width of the chip select memory. Must be equal to either 8, 16 or 32.
|
||||||
|
|
||||||
|
mpmc,async-page-mode:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/flag
|
||||||
|
description:
|
||||||
|
Enable asynchronous page mode.
|
||||||
|
|
||||||
|
mpmc,cs-active-high:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/flag
|
||||||
|
description:
|
||||||
|
Set chip select polarity to active high.
|
||||||
|
|
||||||
|
mpmc,byte-lane-low:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/flag
|
||||||
|
description:
|
||||||
|
Set byte lane state to low.
|
||||||
|
|
||||||
|
mpmc,extended-wait:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/flag
|
||||||
|
description:
|
||||||
|
Enable extended wait.
|
||||||
|
|
||||||
|
mpmc,buffer-enable:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/flag
|
||||||
|
description:
|
||||||
|
Enable write buffer, option is not supported by
|
||||||
|
PL175 and PL176 controllers.
|
||||||
|
|
||||||
|
mpmc,write-protect:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/flag
|
||||||
|
description:
|
||||||
|
Enable write protect.
|
||||||
|
|
||||||
|
mpmc,read-enable-delay:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/uint32
|
||||||
|
description:
|
||||||
|
Delay from chip select assertion to read
|
||||||
|
enable (RE signal) in nano seconds.
|
||||||
|
|
||||||
|
mpmc,write-enable-delay:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/uint32
|
||||||
|
description:
|
||||||
|
Delay from chip select assertion to write
|
||||||
|
enable (WE signal) in nano seconds.
|
||||||
|
|
||||||
|
mpmc,output-enable-delay:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/uint32
|
||||||
|
description:
|
||||||
|
Delay from chip select assertion to output
|
||||||
|
enable (OE signal) in nano seconds.
|
||||||
|
|
||||||
|
mpmc,write-access-delay:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/uint32
|
||||||
|
description:
|
||||||
|
Delay from chip select assertion to write
|
||||||
|
access in nano seconds.
|
||||||
|
|
||||||
|
mpmc,read-access-delay:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/uint32
|
||||||
|
description:
|
||||||
|
Delay from chip select assertion to read
|
||||||
|
access in nano seconds.
|
||||||
|
|
||||||
|
mpmc,page-mode-read-delay:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/uint32
|
||||||
|
description:
|
||||||
|
Delay for asynchronous page mode sequential
|
||||||
|
accesses in nano seconds.
|
||||||
|
|
||||||
|
mpmc,turn-round-delay:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/uint32
|
||||||
|
description:
|
||||||
|
Delay between access to memory banks in nano
|
||||||
|
seconds.
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- reg
|
||||||
|
- '#address-cells'
|
||||||
|
- '#size-cells'
|
||||||
|
- ranges
|
||||||
|
- clocks
|
||||||
|
- clock-names
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
#include <dt-bindings/clock/lpc18xx-ccu.h>
|
||||||
|
|
||||||
|
memory-controller@40005000 {
|
||||||
|
compatible = "arm,pl172", "arm,primecell";
|
||||||
|
reg = <0x40005000 0x1000>;
|
||||||
|
clocks = <&ccu1 CLK_CPU_EMCDIV>, <&ccu1 CLK_CPU_EMC>;
|
||||||
|
clock-names = "mpmcclk", "apb_pclk";
|
||||||
|
#address-cells = <2>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
ranges = <0 0 0x1c000000 0x1000000
|
||||||
|
1 0 0x1d000000 0x1000000
|
||||||
|
2 0 0x1e000000 0x1000000
|
||||||
|
3 0 0x1f000000 0x1000000>;
|
||||||
|
|
||||||
|
cs0 {
|
||||||
|
#address-cells = <2>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
ranges;
|
||||||
|
|
||||||
|
mpmc,cs = <0>;
|
||||||
|
mpmc,memory-width = <16>;
|
||||||
|
mpmc,byte-lane-low;
|
||||||
|
mpmc,write-enable-delay = <0>;
|
||||||
|
mpmc,output-enable-delay = <0>;
|
||||||
|
mpmc,read-enable-delay = <70>;
|
||||||
|
mpmc,page-mode-read-delay = <70>;
|
||||||
|
|
||||||
|
flash@0,0 {
|
||||||
|
compatible = "sst,sst39vf320", "cfi-flash";
|
||||||
|
reg = <0 0 0x400000>;
|
||||||
|
bank-width = <2>;
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
partition@0 {
|
||||||
|
label = "data";
|
||||||
|
reg = <0 0x400000>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
@ -11,25 +11,37 @@ maintainers:
|
|||||||
|
|
||||||
properties:
|
properties:
|
||||||
compatible:
|
compatible:
|
||||||
items:
|
oneOf:
|
||||||
- enum:
|
- description: Revision > 2.1 controllers
|
||||||
- brcm,brcmstb-memc-ddr-rev-b.1.x
|
items:
|
||||||
- brcm,brcmstb-memc-ddr-rev-b.2.0
|
- enum:
|
||||||
- brcm,brcmstb-memc-ddr-rev-b.2.1
|
- brcm,brcmstb-memc-ddr-rev-b.2.2
|
||||||
- brcm,brcmstb-memc-ddr-rev-b.2.2
|
- brcm,brcmstb-memc-ddr-rev-b.2.3
|
||||||
- brcm,brcmstb-memc-ddr-rev-b.2.3
|
- brcm,brcmstb-memc-ddr-rev-b.2.5
|
||||||
- brcm,brcmstb-memc-ddr-rev-b.2.5
|
- brcm,brcmstb-memc-ddr-rev-b.2.6
|
||||||
- brcm,brcmstb-memc-ddr-rev-b.2.6
|
- brcm,brcmstb-memc-ddr-rev-b.2.7
|
||||||
- brcm,brcmstb-memc-ddr-rev-b.2.7
|
- brcm,brcmstb-memc-ddr-rev-b.2.8
|
||||||
- brcm,brcmstb-memc-ddr-rev-b.2.8
|
- brcm,brcmstb-memc-ddr-rev-b.3.0
|
||||||
- brcm,brcmstb-memc-ddr-rev-b.3.0
|
- brcm,brcmstb-memc-ddr-rev-b.3.1
|
||||||
- brcm,brcmstb-memc-ddr-rev-b.3.1
|
- brcm,brcmstb-memc-ddr-rev-c.1.0
|
||||||
- brcm,brcmstb-memc-ddr-rev-c.1.0
|
- brcm,brcmstb-memc-ddr-rev-c.1.1
|
||||||
- brcm,brcmstb-memc-ddr-rev-c.1.1
|
- brcm,brcmstb-memc-ddr-rev-c.1.2
|
||||||
- brcm,brcmstb-memc-ddr-rev-c.1.2
|
- brcm,brcmstb-memc-ddr-rev-c.1.3
|
||||||
- brcm,brcmstb-memc-ddr-rev-c.1.3
|
- brcm,brcmstb-memc-ddr-rev-c.1.4
|
||||||
- brcm,brcmstb-memc-ddr-rev-c.1.4
|
- const: brcm,brcmstb-memc-ddr-rev-b.2.1
|
||||||
- const: brcm,brcmstb-memc-ddr
|
- const: brcm,brcmstb-memc-ddr
|
||||||
|
- description: Revision 2.1 controllers
|
||||||
|
items:
|
||||||
|
- const: brcm,brcmstb-memc-ddr-rev-b.2.1
|
||||||
|
- const: brcm,brcmstb-memc-ddr
|
||||||
|
- description: Revision 2.0 controllers
|
||||||
|
items:
|
||||||
|
- const: brcm,brcmstb-memc-ddr-rev-b.2.0
|
||||||
|
- const: brcm,brcmstb-memc-ddr
|
||||||
|
- description: Revision 1.x controllers
|
||||||
|
items:
|
||||||
|
- const: brcm,brcmstb-memc-ddr-rev-b.1.x
|
||||||
|
- const: brcm,brcmstb-memc-ddr
|
||||||
|
|
||||||
reg:
|
reg:
|
||||||
maxItems: 1
|
maxItems: 1
|
||||||
@ -46,7 +58,9 @@ additionalProperties: false
|
|||||||
examples:
|
examples:
|
||||||
- |
|
- |
|
||||||
memory-controller@9902000 {
|
memory-controller@9902000 {
|
||||||
compatible = "brcm,brcmstb-memc-ddr-rev-c.1.1", "brcm,brcmstb-memc-ddr";
|
compatible = "brcm,brcmstb-memc-ddr-rev-c.1.1",
|
||||||
|
"brcm,brcmstb-memc-ddr-rev-b.2.1",
|
||||||
|
"brcm,brcmstb-memc-ddr";
|
||||||
reg = <0x9902000 0x600>;
|
reg = <0x9902000 0x600>;
|
||||||
clock-frequency = <2133000000>;
|
clock-frequency = <2133000000>;
|
||||||
};
|
};
|
||||||
|
@ -23,7 +23,14 @@ allOf:
|
|||||||
|
|
||||||
properties:
|
properties:
|
||||||
compatible:
|
compatible:
|
||||||
const: renesas,r9a09g047-xspi # RZ/G3E
|
oneOf:
|
||||||
|
- const: renesas,r9a09g047-xspi # RZ/G3E
|
||||||
|
|
||||||
|
- items:
|
||||||
|
- enum:
|
||||||
|
- renesas,r9a09g056-xspi # RZ/V2N
|
||||||
|
- renesas,r9a09g057-xspi # RZ/V2H(P)
|
||||||
|
- const: renesas,r9a09g047-xspi
|
||||||
|
|
||||||
reg:
|
reg:
|
||||||
items:
|
items:
|
||||||
|
39
Documentation/devicetree/bindings/reset/canaan,k230-rst.yaml
Normal file
39
Documentation/devicetree/bindings/reset/canaan,k230-rst.yaml
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/reset/canaan,k230-rst.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: Canaan Kendryte K230 Reset Controller
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Junhui Liu <junhui.liu@pigmoral.tech>
|
||||||
|
|
||||||
|
description:
|
||||||
|
The Canaan Kendryte K230 reset controller is part of the SoC's system
|
||||||
|
controller and controls the reset registers for CPUs and various peripherals.
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
const: canaan,k230-rst
|
||||||
|
|
||||||
|
reg:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
'#reset-cells':
|
||||||
|
const: 1
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- reg
|
||||||
|
- '#reset-cells'
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
reset-controller@91101000 {
|
||||||
|
compatible = "canaan,k230-rst";
|
||||||
|
reg = <0x91101000 0x1000>;
|
||||||
|
#reset-cells = <1>;
|
||||||
|
};
|
@ -1,83 +0,0 @@
|
|||||||
NXP LPC1850 Reset Generation Unit (RGU)
|
|
||||||
========================================
|
|
||||||
|
|
||||||
Please also refer to reset.txt in this directory for common reset
|
|
||||||
controller binding usage.
|
|
||||||
|
|
||||||
Required properties:
|
|
||||||
- compatible: Should be "nxp,lpc1850-rgu"
|
|
||||||
- reg: register base and length
|
|
||||||
- clocks: phandle and clock specifier to RGU clocks
|
|
||||||
- clock-names: should contain "delay" and "reg"
|
|
||||||
- #reset-cells: should be 1
|
|
||||||
|
|
||||||
See table below for valid peripheral reset numbers. Numbers not
|
|
||||||
in the table below are either reserved or not applicable for
|
|
||||||
normal operation.
|
|
||||||
|
|
||||||
Reset Peripheral
|
|
||||||
9 System control unit (SCU)
|
|
||||||
12 ARM Cortex-M0 subsystem core (LPC43xx only)
|
|
||||||
13 CPU core
|
|
||||||
16 LCD controller
|
|
||||||
17 USB0
|
|
||||||
18 USB1
|
|
||||||
19 DMA
|
|
||||||
20 SDIO
|
|
||||||
21 External memory controller (EMC)
|
|
||||||
22 Ethernet
|
|
||||||
25 Flash bank A
|
|
||||||
27 EEPROM
|
|
||||||
28 GPIO
|
|
||||||
29 Flash bank B
|
|
||||||
32 Timer0
|
|
||||||
33 Timer1
|
|
||||||
34 Timer2
|
|
||||||
35 Timer3
|
|
||||||
36 Repetitive Interrupt timer (RIT)
|
|
||||||
37 State Configurable Timer (SCT)
|
|
||||||
38 Motor control PWM (MCPWM)
|
|
||||||
39 QEI
|
|
||||||
40 ADC0
|
|
||||||
41 ADC1
|
|
||||||
42 DAC
|
|
||||||
44 USART0
|
|
||||||
45 UART1
|
|
||||||
46 USART2
|
|
||||||
47 USART3
|
|
||||||
48 I2C0
|
|
||||||
49 I2C1
|
|
||||||
50 SSP0
|
|
||||||
51 SSP1
|
|
||||||
52 I2S0 and I2S1
|
|
||||||
53 Serial Flash Interface (SPIFI)
|
|
||||||
54 C_CAN1
|
|
||||||
55 C_CAN0
|
|
||||||
56 ARM Cortex-M0 application core (LPC4370 only)
|
|
||||||
57 SGPIO (LPC43xx only)
|
|
||||||
58 SPI (LPC43xx only)
|
|
||||||
60 ADCHS (12-bit ADC) (LPC4370 only)
|
|
||||||
|
|
||||||
Refer to NXP LPC18xx or LPC43xx user manual for more details about
|
|
||||||
the reset signals and the connected block/peripheral.
|
|
||||||
|
|
||||||
Reset provider example:
|
|
||||||
rgu: reset-controller@40053000 {
|
|
||||||
compatible = "nxp,lpc1850-rgu";
|
|
||||||
reg = <0x40053000 0x1000>;
|
|
||||||
clocks = <&cgu BASE_SAFE_CLK>, <&ccu1 CLK_CPU_BUS>;
|
|
||||||
clock-names = "delay", "reg";
|
|
||||||
#reset-cells = <1>;
|
|
||||||
};
|
|
||||||
|
|
||||||
Reset consumer example:
|
|
||||||
mac: ethernet@40010000 {
|
|
||||||
compatible = "nxp,lpc1850-dwmac", "snps,dwmac-3.611", "snps,dwmac";
|
|
||||||
reg = <0x40010000 0x2000>;
|
|
||||||
interrupts = <5>;
|
|
||||||
interrupt-names = "macirq";
|
|
||||||
clocks = <&ccu1 CLK_CPU_ETHERNET>;
|
|
||||||
clock-names = "stmmaceth";
|
|
||||||
resets = <&rgu 22>;
|
|
||||||
reset-names = "stmmaceth";
|
|
||||||
};
|
|
101
Documentation/devicetree/bindings/reset/nxp,lpc1850-rgu.yaml
Normal file
101
Documentation/devicetree/bindings/reset/nxp,lpc1850-rgu.yaml
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/reset/nxp,lpc1850-rgu.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: NXP LPC1850 Reset Generation Unit (RGU)
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Frank Li <Frank.Li@nxp.com>
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
const: nxp,lpc1850-rgu
|
||||||
|
|
||||||
|
reg:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
clocks:
|
||||||
|
maxItems: 2
|
||||||
|
|
||||||
|
clock-names:
|
||||||
|
items:
|
||||||
|
- const: delay
|
||||||
|
- const: reg
|
||||||
|
|
||||||
|
'#reset-cells':
|
||||||
|
const: 1
|
||||||
|
description: |
|
||||||
|
See table below for valid peripheral reset numbers. Numbers not
|
||||||
|
in the table below are either reserved or not applicable for
|
||||||
|
normal operation.
|
||||||
|
|
||||||
|
Reset Peripheral
|
||||||
|
9 System control unit (SCU)
|
||||||
|
12 ARM Cortex-M0 subsystem core (LPC43xx only)
|
||||||
|
13 CPU core
|
||||||
|
16 LCD controller
|
||||||
|
17 USB0
|
||||||
|
18 USB1
|
||||||
|
19 DMA
|
||||||
|
20 SDIO
|
||||||
|
21 External memory controller (EMC)
|
||||||
|
22 Ethernet
|
||||||
|
25 Flash bank A
|
||||||
|
27 EEPROM
|
||||||
|
28 GPIO
|
||||||
|
29 Flash bank B
|
||||||
|
32 Timer0
|
||||||
|
33 Timer1
|
||||||
|
34 Timer2
|
||||||
|
35 Timer3
|
||||||
|
36 Repetitive Interrupt timer (RIT)
|
||||||
|
37 State Configurable Timer (SCT)
|
||||||
|
38 Motor control PWM (MCPWM)
|
||||||
|
39 QEI
|
||||||
|
40 ADC0
|
||||||
|
41 ADC1
|
||||||
|
42 DAC
|
||||||
|
44 USART0
|
||||||
|
45 UART1
|
||||||
|
46 USART2
|
||||||
|
47 USART3
|
||||||
|
48 I2C0
|
||||||
|
49 I2C1
|
||||||
|
50 SSP0
|
||||||
|
51 SSP1
|
||||||
|
52 I2S0 and I2S1
|
||||||
|
53 Serial Flash Interface (SPIFI)
|
||||||
|
54 C_CAN1
|
||||||
|
55 C_CAN0
|
||||||
|
56 ARM Cortex-M0 application core (LPC4370 only)
|
||||||
|
57 SGPIO (LPC43xx only)
|
||||||
|
58 SPI (LPC43xx only)
|
||||||
|
60 ADCHS (12-bit ADC) (LPC4370 only)
|
||||||
|
|
||||||
|
Refer to NXP LPC18xx or LPC43xx user manual for more details about
|
||||||
|
the reset signals and the connected block/peripheral.
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- reg
|
||||||
|
- clocks
|
||||||
|
- clock-names
|
||||||
|
- '#reset-cells'
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
#include <dt-bindings/clock/lpc18xx-ccu.h>
|
||||||
|
#include <dt-bindings/clock/lpc18xx-cgu.h>
|
||||||
|
|
||||||
|
reset-controller@40053000 {
|
||||||
|
compatible = "nxp,lpc1850-rgu";
|
||||||
|
reg = <0x40053000 0x1000>;
|
||||||
|
clocks = <&cgu BASE_SAFE_CLK>, <&ccu1 CLK_CPU_BUS>;
|
||||||
|
clock-names = "delay", "reg";
|
||||||
|
#reset-cells = <1>;
|
||||||
|
};
|
||||||
|
|
@ -15,7 +15,12 @@ description:
|
|||||||
|
|
||||||
properties:
|
properties:
|
||||||
compatible:
|
compatible:
|
||||||
const: renesas,r9a09g057-usb2phy-reset # RZ/V2H(P)
|
oneOf:
|
||||||
|
- items:
|
||||||
|
- const: renesas,r9a09g056-usb2phy-reset # RZ/V2N
|
||||||
|
- const: renesas,r9a09g057-usb2phy-reset
|
||||||
|
|
||||||
|
- const: renesas,r9a09g057-usb2phy-reset # RZ/V2H(P)
|
||||||
|
|
||||||
reg:
|
reg:
|
||||||
maxItems: 1
|
maxItems: 1
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
Synopsys DesignWare Reset controller
|
|
||||||
=======================================
|
|
||||||
|
|
||||||
Please also refer to reset.txt in this directory for common reset
|
|
||||||
controller binding usage.
|
|
||||||
|
|
||||||
Required properties:
|
|
||||||
|
|
||||||
- compatible: should be one of the following.
|
|
||||||
"snps,dw-high-reset" - for active high configuration
|
|
||||||
"snps,dw-low-reset" - for active low configuration
|
|
||||||
|
|
||||||
- reg: physical base address of the controller and length of memory mapped
|
|
||||||
region.
|
|
||||||
|
|
||||||
- #reset-cells: must be 1.
|
|
||||||
|
|
||||||
example:
|
|
||||||
|
|
||||||
dw_rst_1: reset-controller@0000 {
|
|
||||||
compatible = "snps,dw-high-reset";
|
|
||||||
reg = <0x0000 0x4>;
|
|
||||||
#reset-cells = <1>;
|
|
||||||
};
|
|
||||||
|
|
||||||
dw_rst_2: reset-controller@1000 {
|
|
||||||
compatible = "snps,dw-low-reset";
|
|
||||||
reg = <0x1000 0x8>;
|
|
||||||
#reset-cells = <1>;
|
|
||||||
};
|
|
39
Documentation/devicetree/bindings/reset/snps,dw-reset.yaml
Normal file
39
Documentation/devicetree/bindings/reset/snps,dw-reset.yaml
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/reset/snps,dw-reset.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: Synopsys DesignWare Reset controller
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Philipp Zabel <p.zabel@pengutronix.de>
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
enum:
|
||||||
|
- snps,dw-high-reset
|
||||||
|
- snps,dw-low-reset
|
||||||
|
|
||||||
|
reg:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
'#reset-cells':
|
||||||
|
const: 1
|
||||||
|
|
||||||
|
reset-controller: true
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- reg
|
||||||
|
- '#reset-cells'
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
reset-controller@0 {
|
||||||
|
compatible = "snps,dw-high-reset";
|
||||||
|
reg = <0x0000 0x4>;
|
||||||
|
#reset-cells = <1>;
|
||||||
|
};
|
@ -16,7 +16,9 @@ properties:
|
|||||||
- enum:
|
- enum:
|
||||||
- sophgo,sg2044-reset
|
- sophgo,sg2044-reset
|
||||||
- const: sophgo,sg2042-reset
|
- const: sophgo,sg2042-reset
|
||||||
- const: sophgo,sg2042-reset
|
- enum:
|
||||||
|
- sophgo,cv1800b-reset
|
||||||
|
- sophgo,sg2042-reset
|
||||||
|
|
||||||
reg:
|
reg:
|
||||||
maxItems: 1
|
maxItems: 1
|
||||||
|
@ -25,6 +25,7 @@ properties:
|
|||||||
compatible:
|
compatible:
|
||||||
items:
|
items:
|
||||||
- enum:
|
- enum:
|
||||||
|
- qcom,milos-aoss-qmp
|
||||||
- qcom,qcs615-aoss-qmp
|
- qcom,qcs615-aoss-qmp
|
||||||
- qcom,qcs8300-aoss-qmp
|
- qcom,qcs8300-aoss-qmp
|
||||||
- qcom,qdu1000-aoss-qmp
|
- qcom,qdu1000-aoss-qmp
|
||||||
@ -38,6 +39,7 @@ properties:
|
|||||||
- qcom,sdx75-aoss-qmp
|
- qcom,sdx75-aoss-qmp
|
||||||
- qcom,sdm845-aoss-qmp
|
- qcom,sdm845-aoss-qmp
|
||||||
- qcom,sm6350-aoss-qmp
|
- qcom,sm6350-aoss-qmp
|
||||||
|
- qcom,sm7150-aoss-qmp
|
||||||
- qcom,sm8150-aoss-qmp
|
- qcom,sm8150-aoss-qmp
|
||||||
- qcom,sm8250-aoss-qmp
|
- qcom,sm8250-aoss-qmp
|
||||||
- qcom,sm8350-aoss-qmp
|
- qcom,sm8350-aoss-qmp
|
||||||
|
@ -18,6 +18,7 @@ properties:
|
|||||||
compatible:
|
compatible:
|
||||||
items:
|
items:
|
||||||
- enum:
|
- enum:
|
||||||
|
- qcom,sm7150-dcc
|
||||||
- qcom,sm8150-dcc
|
- qcom,sm8150-dcc
|
||||||
- qcom,sc7280-dcc
|
- qcom,sc7280-dcc
|
||||||
- qcom,sc7180-dcc
|
- qcom,sc7180-dcc
|
||||||
|
@ -37,6 +37,7 @@ properties:
|
|||||||
- const: qcom,pmic-glink
|
- const: qcom,pmic-glink
|
||||||
- items:
|
- items:
|
||||||
- enum:
|
- enum:
|
||||||
|
- qcom,milos-pmic-glink
|
||||||
- qcom,sm8650-pmic-glink
|
- qcom,sm8650-pmic-glink
|
||||||
- qcom,sm8750-pmic-glink
|
- qcom,sm8750-pmic-glink
|
||||||
- qcom,x1e80100-pmic-glink
|
- qcom,x1e80100-pmic-glink
|
||||||
|
@ -22,17 +22,32 @@ properties:
|
|||||||
- qcom,msm8974-imem
|
- qcom,msm8974-imem
|
||||||
- qcom,msm8976-imem
|
- qcom,msm8976-imem
|
||||||
- qcom,qcs404-imem
|
- qcom,qcs404-imem
|
||||||
|
- qcom,qcs615-imem
|
||||||
- qcom,qcs8300-imem
|
- qcom,qcs8300-imem
|
||||||
- qcom,qdu1000-imem
|
- qcom,qdu1000-imem
|
||||||
- qcom,sa8775p-imem
|
- qcom,sa8775p-imem
|
||||||
|
- qcom,sar2130p-imem
|
||||||
- qcom,sc7180-imem
|
- qcom,sc7180-imem
|
||||||
- qcom,sc7280-imem
|
- qcom,sc7280-imem
|
||||||
|
- qcom,sc8280xp-imem
|
||||||
- qcom,sdm630-imem
|
- qcom,sdm630-imem
|
||||||
- qcom,sdm845-imem
|
- qcom,sdm845-imem
|
||||||
- qcom,sdx55-imem
|
- qcom,sdx55-imem
|
||||||
- qcom,sdx65-imem
|
- qcom,sdx65-imem
|
||||||
|
- qcom,sdx75-imem
|
||||||
|
- qcom,sm6115-imem
|
||||||
|
- qcom,sm6125-imem
|
||||||
|
- qcom,sm6350-imem
|
||||||
- qcom,sm6375-imem
|
- qcom,sm6375-imem
|
||||||
|
- qcom,sm7150-imem
|
||||||
|
- qcom,sm8150-imem
|
||||||
|
- qcom,sm8250-imem
|
||||||
|
- qcom,sm8350-imem
|
||||||
- qcom,sm8450-imem
|
- qcom,sm8450-imem
|
||||||
|
- qcom,sm8550-imem
|
||||||
|
- qcom,sm8650-imem
|
||||||
|
- qcom,sm8750-imem
|
||||||
|
- qcom,x1e80100-imem
|
||||||
- const: syscon
|
- const: syscon
|
||||||
- const: simple-mfd
|
- const: simple-mfd
|
||||||
|
|
||||||
|
12
MAINTAINERS
12
MAINTAINERS
@ -2620,6 +2620,8 @@ L: imx@lists.linux.dev
|
|||||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||||
S: Maintained
|
S: Maintained
|
||||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git
|
T: git git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git
|
||||||
|
F: Documentation/devicetree/bindings/firmware/fsl*
|
||||||
|
F: Documentation/devicetree/bindings/firmware/nxp*
|
||||||
F: arch/arm/boot/dts/nxp/imx/
|
F: arch/arm/boot/dts/nxp/imx/
|
||||||
F: arch/arm/boot/dts/nxp/mxs/
|
F: arch/arm/boot/dts/nxp/mxs/
|
||||||
F: arch/arm64/boot/dts/freescale/
|
F: arch/arm64/boot/dts/freescale/
|
||||||
@ -3035,8 +3037,10 @@ R: Ghennadi Procopciuc <ghennadi.procopciuc@oss.nxp.com>
|
|||||||
R: NXP S32 Linux Team <s32@nxp.com>
|
R: NXP S32 Linux Team <s32@nxp.com>
|
||||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
F: Documentation/devicetree/bindings/rtc/nxp,s32g-rtc.yaml
|
||||||
F: arch/arm64/boot/dts/freescale/s32g*.dts*
|
F: arch/arm64/boot/dts/freescale/s32g*.dts*
|
||||||
F: drivers/pinctrl/nxp/
|
F: drivers/pinctrl/nxp/
|
||||||
|
F: drivers/rtc/rtc-s32g.c
|
||||||
|
|
||||||
ARM/NXP S32G/S32R DWMAC ETHERNET DRIVER
|
ARM/NXP S32G/S32R DWMAC ETHERNET DRIVER
|
||||||
M: Jan Petrous <jan.petrous@oss.nxp.com>
|
M: Jan Petrous <jan.petrous@oss.nxp.com>
|
||||||
@ -20819,6 +20823,14 @@ S: Maintained
|
|||||||
F: Documentation/devicetree/bindings/media/raspberrypi,rp1-cfe.yaml
|
F: Documentation/devicetree/bindings/media/raspberrypi,rp1-cfe.yaml
|
||||||
F: drivers/media/platform/raspberrypi/rp1-cfe/
|
F: drivers/media/platform/raspberrypi/rp1-cfe/
|
||||||
|
|
||||||
|
RASPBERRY PI RP1 PCI DRIVER
|
||||||
|
M: Andrea della Porta <andrea.porta@suse.com>
|
||||||
|
S: Maintained
|
||||||
|
F: arch/arm64/boot/dts/broadcom/rp1*.dts*
|
||||||
|
F: drivers/clk/clk-rp1.c
|
||||||
|
F: drivers/misc/rp1/
|
||||||
|
F: drivers/pinctrl/pinctrl-rp1.c
|
||||||
|
|
||||||
RC-CORE / LIRC FRAMEWORK
|
RC-CORE / LIRC FRAMEWORK
|
||||||
M: Sean Young <sean@mess.org>
|
M: Sean Young <sean@mess.org>
|
||||||
L: linux-media@vger.kernel.org
|
L: linux-media@vger.kernel.org
|
||||||
|
@ -87,6 +87,12 @@ config HISILICON_LPC
|
|||||||
Driver to enable I/O access to devices attached to the Low Pin
|
Driver to enable I/O access to devices attached to the Low Pin
|
||||||
Count bus on the HiSilicon Hip06/7 SoC.
|
Count bus on the HiSilicon Hip06/7 SoC.
|
||||||
|
|
||||||
|
config IMX_AIPSTZ
|
||||||
|
tristate "Support for IMX Secure AHB to IP Slave bus (AIPSTZ) bridge"
|
||||||
|
depends on ARCH_MXC
|
||||||
|
help
|
||||||
|
Enable support for IMX AIPSTZ bridge.
|
||||||
|
|
||||||
config IMX_WEIM
|
config IMX_WEIM
|
||||||
bool "Freescale EIM DRIVER"
|
bool "Freescale EIM DRIVER"
|
||||||
depends on ARCH_MXC || COMPILE_TEST
|
depends on ARCH_MXC || COMPILE_TEST
|
||||||
|
@ -15,6 +15,7 @@ obj-$(CONFIG_FSL_MC_BUS) += fsl-mc/
|
|||||||
|
|
||||||
obj-$(CONFIG_BT1_APB) += bt1-apb.o
|
obj-$(CONFIG_BT1_APB) += bt1-apb.o
|
||||||
obj-$(CONFIG_BT1_AXI) += bt1-axi.o
|
obj-$(CONFIG_BT1_AXI) += bt1-axi.o
|
||||||
|
obj-$(CONFIG_IMX_AIPSTZ) += imx-aipstz.o
|
||||||
obj-$(CONFIG_IMX_WEIM) += imx-weim.o
|
obj-$(CONFIG_IMX_WEIM) += imx-weim.o
|
||||||
obj-$(CONFIG_INTEL_IXP4XX_EB) += intel-ixp4xx-eb.o
|
obj-$(CONFIG_INTEL_IXP4XX_EB) += intel-ixp4xx-eb.o
|
||||||
obj-$(CONFIG_MIPS_CDMM) += mips_cdmm.o
|
obj-$(CONFIG_MIPS_CDMM) += mips_cdmm.o
|
||||||
|
108
drivers/bus/imx-aipstz.c
Normal file
108
drivers/bus/imx-aipstz.c
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
|
/*
|
||||||
|
* Copyright 2025 NXP
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/of_platform.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/pm_runtime.h>
|
||||||
|
#include <linux/regmap.h>
|
||||||
|
|
||||||
|
#define IMX_AIPSTZ_MPR0 0x0
|
||||||
|
|
||||||
|
struct imx_aipstz_config {
|
||||||
|
u32 mpr0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct imx_aipstz_data {
|
||||||
|
void __iomem *base;
|
||||||
|
const struct imx_aipstz_config *default_cfg;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void imx_aipstz_apply_default(struct imx_aipstz_data *data)
|
||||||
|
{
|
||||||
|
writel(data->default_cfg->mpr0, data->base + IMX_AIPSTZ_MPR0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct of_device_id imx_aipstz_match_table[] = {
|
||||||
|
{ .compatible = "simple-bus", },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
static int imx_aipstz_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct imx_aipstz_data *data;
|
||||||
|
|
||||||
|
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
|
||||||
|
if (!data)
|
||||||
|
return dev_err_probe(&pdev->dev, -ENOMEM,
|
||||||
|
"failed to allocate data memory\n");
|
||||||
|
|
||||||
|
data->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
|
||||||
|
if (IS_ERR(data->base))
|
||||||
|
return dev_err_probe(&pdev->dev, -ENOMEM,
|
||||||
|
"failed to get/ioremap AC memory\n");
|
||||||
|
|
||||||
|
data->default_cfg = of_device_get_match_data(&pdev->dev);
|
||||||
|
|
||||||
|
imx_aipstz_apply_default(data);
|
||||||
|
|
||||||
|
dev_set_drvdata(&pdev->dev, data);
|
||||||
|
|
||||||
|
pm_runtime_set_active(&pdev->dev);
|
||||||
|
devm_pm_runtime_enable(&pdev->dev);
|
||||||
|
|
||||||
|
return of_platform_populate(pdev->dev.of_node, imx_aipstz_match_table,
|
||||||
|
NULL, &pdev->dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void imx_aipstz_remove(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
of_platform_depopulate(&pdev->dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int imx_aipstz_runtime_resume(struct device *dev)
|
||||||
|
{
|
||||||
|
struct imx_aipstz_data *data = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
/* restore potentially lost configuration during domain power-off */
|
||||||
|
imx_aipstz_apply_default(data);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct dev_pm_ops imx_aipstz_pm_ops = {
|
||||||
|
RUNTIME_PM_OPS(NULL, imx_aipstz_runtime_resume, NULL)
|
||||||
|
SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* following configuration is equivalent to:
|
||||||
|
* masters 0-7 => trusted for R/W + use AHB's HPROT[1] to det. privilege
|
||||||
|
*/
|
||||||
|
static const struct imx_aipstz_config imx8mp_aipstz_default_cfg = {
|
||||||
|
.mpr0 = 0x77777777,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct of_device_id imx_aipstz_of_ids[] = {
|
||||||
|
{ .compatible = "fsl,imx8mp-aipstz", .data = &imx8mp_aipstz_default_cfg },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, imx_aipstz_of_ids);
|
||||||
|
|
||||||
|
static struct platform_driver imx_aipstz_of_driver = {
|
||||||
|
.probe = imx_aipstz_probe,
|
||||||
|
.remove = imx_aipstz_remove,
|
||||||
|
.driver = {
|
||||||
|
.name = "imx-aipstz",
|
||||||
|
.of_match_table = imx_aipstz_of_ids,
|
||||||
|
.pm = pm_ptr(&imx_aipstz_pm_ops),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
module_platform_driver(imx_aipstz_of_driver);
|
||||||
|
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_DESCRIPTION("IMX secure AHB to IP Slave bus (AIPSTZ) bridge driver");
|
||||||
|
MODULE_AUTHOR("Laurentiu Mihalcea <laurentiu.mihalcea@nxp.com>");
|
@ -2170,9 +2170,8 @@ static int sysc_reset(struct sysc *ddata)
|
|||||||
static int sysc_init_module(struct sysc *ddata)
|
static int sysc_init_module(struct sysc *ddata)
|
||||||
{
|
{
|
||||||
bool rstctrl_deasserted = false;
|
bool rstctrl_deasserted = false;
|
||||||
int error = 0;
|
int error = sysc_clockdomain_init(ddata);
|
||||||
|
|
||||||
error = sysc_clockdomain_init(ddata);
|
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
|
@ -88,6 +88,15 @@ config COMMON_CLK_RK808
|
|||||||
These multi-function devices have two fixed-rate oscillators, clocked at 32KHz each.
|
These multi-function devices have two fixed-rate oscillators, clocked at 32KHz each.
|
||||||
Clkout1 is always on, Clkout2 can off by control register.
|
Clkout1 is always on, Clkout2 can off by control register.
|
||||||
|
|
||||||
|
config COMMON_CLK_RP1
|
||||||
|
tristate "Raspberry Pi RP1-based clock support"
|
||||||
|
depends on MISC_RP1 || COMPILE_TEST
|
||||||
|
default MISC_RP1
|
||||||
|
help
|
||||||
|
Enable common clock framework support for Raspberry Pi RP1.
|
||||||
|
This multi-function device has 3 main PLLs and several clock
|
||||||
|
generators to drive the internal sub-peripherals.
|
||||||
|
|
||||||
config COMMON_CLK_HI655X
|
config COMMON_CLK_HI655X
|
||||||
tristate "Clock driver for Hi655x" if EXPERT
|
tristate "Clock driver for Hi655x" if EXPERT
|
||||||
depends on (MFD_HI655X_PMIC || COMPILE_TEST)
|
depends on (MFD_HI655X_PMIC || COMPILE_TEST)
|
||||||
|
@ -84,6 +84,7 @@ obj-$(CONFIG_CLK_LS1028A_PLLDIG) += clk-plldig.o
|
|||||||
obj-$(CONFIG_COMMON_CLK_PWM) += clk-pwm.o
|
obj-$(CONFIG_COMMON_CLK_PWM) += clk-pwm.o
|
||||||
obj-$(CONFIG_CLK_QORIQ) += clk-qoriq.o
|
obj-$(CONFIG_CLK_QORIQ) += clk-qoriq.o
|
||||||
obj-$(CONFIG_COMMON_CLK_RK808) += clk-rk808.o
|
obj-$(CONFIG_COMMON_CLK_RK808) += clk-rk808.o
|
||||||
|
obj-$(CONFIG_COMMON_CLK_RP1) += clk-rp1.o
|
||||||
obj-$(CONFIG_COMMON_CLK_HI655X) += clk-hi655x.o
|
obj-$(CONFIG_COMMON_CLK_HI655X) += clk-hi655x.o
|
||||||
obj-$(CONFIG_COMMON_CLK_S2MPS11) += clk-s2mps11.o
|
obj-$(CONFIG_COMMON_CLK_S2MPS11) += clk-s2mps11.o
|
||||||
obj-$(CONFIG_COMMON_CLK_SCMI) += clk-scmi.o
|
obj-$(CONFIG_COMMON_CLK_SCMI) += clk-scmi.o
|
||||||
|
1494
drivers/clk/clk-rp1.c
Normal file
1494
drivers/clk/clk-rp1.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -323,6 +323,31 @@ static struct attribute *scmi_device_attributes_attrs[] = {
|
|||||||
};
|
};
|
||||||
ATTRIBUTE_GROUPS(scmi_device_attributes);
|
ATTRIBUTE_GROUPS(scmi_device_attributes);
|
||||||
|
|
||||||
|
static int scmi_pm_suspend(struct device *dev)
|
||||||
|
{
|
||||||
|
const struct device_driver *drv = dev->driver;
|
||||||
|
|
||||||
|
if (drv && drv->pm && drv->pm->suspend)
|
||||||
|
return drv->pm->suspend(dev);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int scmi_pm_resume(struct device *dev)
|
||||||
|
{
|
||||||
|
const struct device_driver *drv = dev->driver;
|
||||||
|
|
||||||
|
if (drv && drv->pm && drv->pm->resume)
|
||||||
|
return drv->pm->resume(dev);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct dev_pm_ops scmi_dev_pm_ops = {
|
||||||
|
.suspend = pm_sleep_ptr(scmi_pm_suspend),
|
||||||
|
.resume = pm_sleep_ptr(scmi_pm_resume),
|
||||||
|
};
|
||||||
|
|
||||||
const struct bus_type scmi_bus_type = {
|
const struct bus_type scmi_bus_type = {
|
||||||
.name = "scmi_protocol",
|
.name = "scmi_protocol",
|
||||||
.match = scmi_dev_match,
|
.match = scmi_dev_match,
|
||||||
@ -330,6 +355,7 @@ const struct bus_type scmi_bus_type = {
|
|||||||
.remove = scmi_dev_remove,
|
.remove = scmi_dev_remove,
|
||||||
.uevent = scmi_device_uevent,
|
.uevent = scmi_device_uevent,
|
||||||
.dev_groups = scmi_device_attributes_groups,
|
.dev_groups = scmi_device_attributes_groups,
|
||||||
|
.pm = &scmi_dev_pm_ops,
|
||||||
};
|
};
|
||||||
EXPORT_SYMBOL_GPL(scmi_bus_type);
|
EXPORT_SYMBOL_GPL(scmi_bus_type);
|
||||||
|
|
||||||
|
@ -305,6 +305,7 @@ enum debug_counters {
|
|||||||
ERR_MSG_INVALID,
|
ERR_MSG_INVALID,
|
||||||
ERR_MSG_NOMEM,
|
ERR_MSG_NOMEM,
|
||||||
ERR_PROTOCOL,
|
ERR_PROTOCOL,
|
||||||
|
XFERS_INFLIGHT,
|
||||||
SCMI_DEBUG_COUNTERS_LAST
|
SCMI_DEBUG_COUNTERS_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -314,6 +315,12 @@ static inline void scmi_inc_count(atomic_t *arr, int stat)
|
|||||||
atomic_inc(&arr[stat]);
|
atomic_inc(&arr[stat]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void scmi_dec_count(atomic_t *arr, int stat)
|
||||||
|
{
|
||||||
|
if (IS_ENABLED(CONFIG_ARM_SCMI_DEBUG_COUNTERS))
|
||||||
|
atomic_dec(&arr[stat]);
|
||||||
|
}
|
||||||
|
|
||||||
enum scmi_bad_msg {
|
enum scmi_bad_msg {
|
||||||
MSG_UNEXPECTED = -1,
|
MSG_UNEXPECTED = -1,
|
||||||
MSG_INVALID = -2,
|
MSG_INVALID = -2,
|
||||||
@ -498,4 +505,5 @@ static struct platform_driver __drv = { \
|
|||||||
void scmi_notification_instance_data_set(const struct scmi_handle *handle,
|
void scmi_notification_instance_data_set(const struct scmi_handle *handle,
|
||||||
void *priv);
|
void *priv);
|
||||||
void *scmi_notification_instance_data_get(const struct scmi_handle *handle);
|
void *scmi_notification_instance_data_get(const struct scmi_handle *handle);
|
||||||
|
int scmi_inflight_count(const struct scmi_handle *handle);
|
||||||
#endif /* _SCMI_COMMON_H */
|
#endif /* _SCMI_COMMON_H */
|
||||||
|
@ -190,6 +190,7 @@ struct scmi_info {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define handle_to_scmi_info(h) container_of(h, struct scmi_info, handle)
|
#define handle_to_scmi_info(h) container_of(h, struct scmi_info, handle)
|
||||||
|
#define tx_minfo_to_scmi_info(h) container_of(h, struct scmi_info, tx_minfo)
|
||||||
#define bus_nb_to_scmi_info(nb) container_of(nb, struct scmi_info, bus_nb)
|
#define bus_nb_to_scmi_info(nb) container_of(nb, struct scmi_info, bus_nb)
|
||||||
#define req_nb_to_scmi_info(nb) container_of(nb, struct scmi_info, dev_req_nb)
|
#define req_nb_to_scmi_info(nb) container_of(nb, struct scmi_info, dev_req_nb)
|
||||||
|
|
||||||
@ -603,9 +604,14 @@ static inline void
|
|||||||
scmi_xfer_inflight_register_unlocked(struct scmi_xfer *xfer,
|
scmi_xfer_inflight_register_unlocked(struct scmi_xfer *xfer,
|
||||||
struct scmi_xfers_info *minfo)
|
struct scmi_xfers_info *minfo)
|
||||||
{
|
{
|
||||||
|
/* In this context minfo will be tx_minfo due to the xfer pending */
|
||||||
|
struct scmi_info *info = tx_minfo_to_scmi_info(minfo);
|
||||||
|
|
||||||
/* Set in-flight */
|
/* Set in-flight */
|
||||||
set_bit(xfer->hdr.seq, minfo->xfer_alloc_table);
|
set_bit(xfer->hdr.seq, minfo->xfer_alloc_table);
|
||||||
hash_add(minfo->pending_xfers, &xfer->node, xfer->hdr.seq);
|
hash_add(minfo->pending_xfers, &xfer->node, xfer->hdr.seq);
|
||||||
|
scmi_inc_count(info->dbg->counters, XFERS_INFLIGHT);
|
||||||
|
|
||||||
xfer->pending = true;
|
xfer->pending = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -807,9 +813,13 @@ __scmi_xfer_put(struct scmi_xfers_info *minfo, struct scmi_xfer *xfer)
|
|||||||
spin_lock_irqsave(&minfo->xfer_lock, flags);
|
spin_lock_irqsave(&minfo->xfer_lock, flags);
|
||||||
if (refcount_dec_and_test(&xfer->users)) {
|
if (refcount_dec_and_test(&xfer->users)) {
|
||||||
if (xfer->pending) {
|
if (xfer->pending) {
|
||||||
|
struct scmi_info *info = tx_minfo_to_scmi_info(minfo);
|
||||||
|
|
||||||
scmi_xfer_token_clear(minfo, xfer);
|
scmi_xfer_token_clear(minfo, xfer);
|
||||||
hash_del(&xfer->node);
|
hash_del(&xfer->node);
|
||||||
xfer->pending = false;
|
xfer->pending = false;
|
||||||
|
|
||||||
|
scmi_dec_count(info->dbg->counters, XFERS_INFLIGHT);
|
||||||
}
|
}
|
||||||
hlist_add_head(&xfer->node, &minfo->free_xfers);
|
hlist_add_head(&xfer->node, &minfo->free_xfers);
|
||||||
}
|
}
|
||||||
@ -1433,7 +1443,8 @@ static int do_xfer(const struct scmi_protocol_handle *ph,
|
|||||||
|
|
||||||
trace_scmi_xfer_begin(xfer->transfer_id, xfer->hdr.id,
|
trace_scmi_xfer_begin(xfer->transfer_id, xfer->hdr.id,
|
||||||
xfer->hdr.protocol_id, xfer->hdr.seq,
|
xfer->hdr.protocol_id, xfer->hdr.seq,
|
||||||
xfer->hdr.poll_completion);
|
xfer->hdr.poll_completion,
|
||||||
|
scmi_inflight_count(&info->handle));
|
||||||
|
|
||||||
/* Clear any stale status */
|
/* Clear any stale status */
|
||||||
xfer->hdr.status = SCMI_SUCCESS;
|
xfer->hdr.status = SCMI_SUCCESS;
|
||||||
@ -1469,7 +1480,8 @@ static int do_xfer(const struct scmi_protocol_handle *ph,
|
|||||||
info->desc->ops->mark_txdone(cinfo, ret, xfer);
|
info->desc->ops->mark_txdone(cinfo, ret, xfer);
|
||||||
|
|
||||||
trace_scmi_xfer_end(xfer->transfer_id, xfer->hdr.id,
|
trace_scmi_xfer_end(xfer->transfer_id, xfer->hdr.id,
|
||||||
xfer->hdr.protocol_id, xfer->hdr.seq, ret);
|
xfer->hdr.protocol_id, xfer->hdr.seq, ret,
|
||||||
|
scmi_inflight_count(&info->handle));
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -2912,6 +2924,7 @@ static const char * const dbg_counter_strs[] = {
|
|||||||
"err_msg_invalid",
|
"err_msg_invalid",
|
||||||
"err_msg_nomem",
|
"err_msg_nomem",
|
||||||
"err_protocol",
|
"err_protocol",
|
||||||
|
"xfers_inflight",
|
||||||
};
|
};
|
||||||
|
|
||||||
static ssize_t reset_all_on_write(struct file *filp, const char __user *buf,
|
static ssize_t reset_all_on_write(struct file *filp, const char __user *buf,
|
||||||
@ -3405,6 +3418,17 @@ static struct dentry *scmi_debugfs_init(void)
|
|||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int scmi_inflight_count(const struct scmi_handle *handle)
|
||||||
|
{
|
||||||
|
if (IS_ENABLED(CONFIG_ARM_SCMI_DEBUG_COUNTERS)) {
|
||||||
|
struct scmi_info *info = handle_to_scmi_info(handle);
|
||||||
|
|
||||||
|
return atomic_read(&info->dbg->counters[XFERS_INFLIGHT]);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int __init scmi_driver_init(void)
|
static int __init scmi_driver_init(void)
|
||||||
{
|
{
|
||||||
scmi_quirks_initialize();
|
scmi_quirks_initialize();
|
||||||
|
@ -318,6 +318,9 @@ struct scmi_registered_events_desc {
|
|||||||
* customized event report
|
* customized event report
|
||||||
* @num_sources: The number of possible sources for this event as stated at
|
* @num_sources: The number of possible sources for this event as stated at
|
||||||
* events' registration time
|
* events' registration time
|
||||||
|
* @not_supported_by_platform: A flag to indicate that not even one source was
|
||||||
|
* found to be supported by the platform for this
|
||||||
|
* event
|
||||||
* @sources: A reference to a dynamically allocated array used to refcount the
|
* @sources: A reference to a dynamically allocated array used to refcount the
|
||||||
* events' enable requests for all the existing sources
|
* events' enable requests for all the existing sources
|
||||||
* @sources_mtx: A mutex to serialize the access to @sources
|
* @sources_mtx: A mutex to serialize the access to @sources
|
||||||
@ -334,6 +337,7 @@ struct scmi_registered_event {
|
|||||||
const struct scmi_event *evt;
|
const struct scmi_event *evt;
|
||||||
void *report;
|
void *report;
|
||||||
u32 num_sources;
|
u32 num_sources;
|
||||||
|
bool not_supported_by_platform;
|
||||||
refcount_t *sources;
|
refcount_t *sources;
|
||||||
/* locking to serialize the access to sources */
|
/* locking to serialize the access to sources */
|
||||||
struct mutex sources_mtx;
|
struct mutex sources_mtx;
|
||||||
@ -811,10 +815,19 @@ int scmi_register_protocol_events(const struct scmi_handle *handle, u8 proto_id,
|
|||||||
if (!r_evt->report)
|
if (!r_evt->report)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
for (id = 0; id < r_evt->num_sources; id++)
|
if (ee->ops->is_notify_supported) {
|
||||||
if (ee->ops->is_notify_supported &&
|
int supported = 0;
|
||||||
!ee->ops->is_notify_supported(ph, r_evt->evt->id, id))
|
|
||||||
refcount_set(&r_evt->sources[id], NOTIF_UNSUPP);
|
for (id = 0; id < r_evt->num_sources; id++) {
|
||||||
|
if (!ee->ops->is_notify_supported(ph, r_evt->evt->id, id))
|
||||||
|
refcount_set(&r_evt->sources[id], NOTIF_UNSUPP);
|
||||||
|
else
|
||||||
|
supported++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Not even one source has been found to be supported */
|
||||||
|
r_evt->not_supported_by_platform = !supported;
|
||||||
|
}
|
||||||
|
|
||||||
pd->registered_events[i] = r_evt;
|
pd->registered_events[i] = r_evt;
|
||||||
/* Ensure events are updated */
|
/* Ensure events are updated */
|
||||||
@ -936,6 +949,11 @@ static inline int scmi_bind_event_handler(struct scmi_notify_instance *ni,
|
|||||||
* of protocol instance.
|
* of protocol instance.
|
||||||
*/
|
*/
|
||||||
hash_del(&hndl->hash);
|
hash_del(&hndl->hash);
|
||||||
|
|
||||||
|
/* Bailout if event is not supported at all */
|
||||||
|
if (r_evt->not_supported_by_platform)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Acquire protocols only for NON pending handlers, so as NOT to trigger
|
* Acquire protocols only for NON pending handlers, so as NOT to trigger
|
||||||
* protocol initialization when a notifier is registered against a still
|
* protocol initialization when a notifier is registered against a still
|
||||||
@ -1060,6 +1078,9 @@ __scmi_event_handler_get_ops(struct scmi_notify_instance *ni,
|
|||||||
r_evt = SCMI_GET_REVT(ni, KEY_XTRACT_PROTO_ID(evt_key),
|
r_evt = SCMI_GET_REVT(ni, KEY_XTRACT_PROTO_ID(evt_key),
|
||||||
KEY_XTRACT_EVT_ID(evt_key));
|
KEY_XTRACT_EVT_ID(evt_key));
|
||||||
|
|
||||||
|
if (r_evt && r_evt->not_supported_by_platform)
|
||||||
|
return ERR_PTR(-EOPNOTSUPP);
|
||||||
|
|
||||||
mutex_lock(&ni->pending_mtx);
|
mutex_lock(&ni->pending_mtx);
|
||||||
/* Search registered events at first ... if possible at all */
|
/* Search registered events at first ... if possible at all */
|
||||||
if (r_evt) {
|
if (r_evt) {
|
||||||
@ -1087,7 +1108,7 @@ __scmi_event_handler_get_ops(struct scmi_notify_instance *ni,
|
|||||||
hndl->key);
|
hndl->key);
|
||||||
/* this hndl can be only a pending one */
|
/* this hndl can be only a pending one */
|
||||||
scmi_put_handler_unlocked(ni, hndl);
|
scmi_put_handler_unlocked(ni, hndl);
|
||||||
hndl = NULL;
|
hndl = ERR_PTR(-EINVAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mutex_unlock(&ni->pending_mtx);
|
mutex_unlock(&ni->pending_mtx);
|
||||||
@ -1370,8 +1391,8 @@ static int scmi_notifier_register(const struct scmi_handle *handle,
|
|||||||
evt_key = MAKE_HASH_KEY(proto_id, evt_id,
|
evt_key = MAKE_HASH_KEY(proto_id, evt_id,
|
||||||
src_id ? *src_id : SRC_ID_MASK);
|
src_id ? *src_id : SRC_ID_MASK);
|
||||||
hndl = scmi_get_or_create_handler(ni, evt_key);
|
hndl = scmi_get_or_create_handler(ni, evt_key);
|
||||||
if (!hndl)
|
if (IS_ERR(hndl))
|
||||||
return -EINVAL;
|
return PTR_ERR(hndl);
|
||||||
|
|
||||||
blocking_notifier_chain_register(&hndl->chain, nb);
|
blocking_notifier_chain_register(&hndl->chain, nb);
|
||||||
|
|
||||||
@ -1416,8 +1437,8 @@ static int scmi_notifier_unregister(const struct scmi_handle *handle,
|
|||||||
evt_key = MAKE_HASH_KEY(proto_id, evt_id,
|
evt_key = MAKE_HASH_KEY(proto_id, evt_id,
|
||||||
src_id ? *src_id : SRC_ID_MASK);
|
src_id ? *src_id : SRC_ID_MASK);
|
||||||
hndl = scmi_get_handler(ni, evt_key);
|
hndl = scmi_get_handler(ni, evt_key);
|
||||||
if (!hndl)
|
if (IS_ERR(hndl))
|
||||||
return -EINVAL;
|
return PTR_ERR(hndl);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note that this chain unregistration call is safe on its own
|
* Note that this chain unregistration call is safe on its own
|
||||||
|
@ -892,7 +892,7 @@ static int scmi_dvfs_device_opps_add(const struct scmi_protocol_handle *ph,
|
|||||||
freq = dom->opp[idx].indicative_freq * dom->mult_factor;
|
freq = dom->opp[idx].indicative_freq * dom->mult_factor;
|
||||||
|
|
||||||
/* All OPPs above the sustained frequency are treated as turbo */
|
/* All OPPs above the sustained frequency are treated as turbo */
|
||||||
data.turbo = freq > dom->sustained_freq_khz * 1000;
|
data.turbo = freq > dom->sustained_freq_khz * 1000UL;
|
||||||
|
|
||||||
data.level = dom->opp[idx].perf;
|
data.level = dom->opp[idx].perf;
|
||||||
data.freq = freq;
|
data.freq = freq;
|
||||||
|
@ -475,7 +475,8 @@ static void scmi_xfer_raw_worker(struct work_struct *work)
|
|||||||
raw->desc->ops->mark_txdone(rw->cinfo, ret, xfer);
|
raw->desc->ops->mark_txdone(rw->cinfo, ret, xfer);
|
||||||
|
|
||||||
trace_scmi_xfer_end(xfer->transfer_id, xfer->hdr.id,
|
trace_scmi_xfer_end(xfer->transfer_id, xfer->hdr.id,
|
||||||
xfer->hdr.protocol_id, xfer->hdr.seq, ret);
|
xfer->hdr.protocol_id, xfer->hdr.seq,
|
||||||
|
ret, scmi_inflight_count(raw->handle));
|
||||||
|
|
||||||
/* Wait also for an async delayed response if needed */
|
/* Wait also for an async delayed response if needed */
|
||||||
if (!ret && xfer->async_done) {
|
if (!ret && xfer->async_done) {
|
||||||
@ -642,7 +643,8 @@ static int scmi_do_xfer_raw_start(struct scmi_raw_mode_info *raw,
|
|||||||
|
|
||||||
trace_scmi_xfer_begin(xfer->transfer_id, xfer->hdr.id,
|
trace_scmi_xfer_begin(xfer->transfer_id, xfer->hdr.id,
|
||||||
xfer->hdr.protocol_id, xfer->hdr.seq,
|
xfer->hdr.protocol_id, xfer->hdr.seq,
|
||||||
xfer->hdr.poll_completion);
|
xfer->hdr.poll_completion,
|
||||||
|
scmi_inflight_count(raw->handle));
|
||||||
|
|
||||||
ret = raw->desc->ops->send_message(rw->cinfo, xfer);
|
ret = raw->desc->ops->send_message(rw->cinfo, xfer);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -46,6 +46,7 @@
|
|||||||
#include <linux/math.h>
|
#include <linux/math.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
|
#include <linux/pm.h>
|
||||||
#include <linux/printk.h>
|
#include <linux/printk.h>
|
||||||
#include <linux/reboot.h>
|
#include <linux/reboot.h>
|
||||||
#include <linux/scmi_protocol.h>
|
#include <linux/scmi_protocol.h>
|
||||||
@ -324,12 +325,7 @@ static int scmi_userspace_notifier(struct notifier_block *nb,
|
|||||||
|
|
||||||
static void scmi_suspend_work_func(struct work_struct *work)
|
static void scmi_suspend_work_func(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct scmi_syspower_conf *sc =
|
|
||||||
container_of(work, struct scmi_syspower_conf, suspend_work);
|
|
||||||
|
|
||||||
pm_suspend(PM_SUSPEND_MEM);
|
pm_suspend(PM_SUSPEND_MEM);
|
||||||
|
|
||||||
sc->state = SCMI_SYSPOWER_IDLE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int scmi_syspower_probe(struct scmi_device *sdev)
|
static int scmi_syspower_probe(struct scmi_device *sdev)
|
||||||
@ -354,6 +350,7 @@ static int scmi_syspower_probe(struct scmi_device *sdev)
|
|||||||
sc->required_transition = SCMI_SYSTEM_MAX;
|
sc->required_transition = SCMI_SYSTEM_MAX;
|
||||||
sc->userspace_nb.notifier_call = &scmi_userspace_notifier;
|
sc->userspace_nb.notifier_call = &scmi_userspace_notifier;
|
||||||
sc->dev = &sdev->dev;
|
sc->dev = &sdev->dev;
|
||||||
|
dev_set_drvdata(&sdev->dev, sc);
|
||||||
|
|
||||||
INIT_WORK(&sc->suspend_work, scmi_suspend_work_func);
|
INIT_WORK(&sc->suspend_work, scmi_suspend_work_func);
|
||||||
|
|
||||||
@ -363,6 +360,18 @@ static int scmi_syspower_probe(struct scmi_device *sdev)
|
|||||||
NULL, &sc->userspace_nb);
|
NULL, &sc->userspace_nb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int scmi_system_power_resume(struct device *dev)
|
||||||
|
{
|
||||||
|
struct scmi_syspower_conf *sc = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
sc->state = SCMI_SYSPOWER_IDLE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct dev_pm_ops scmi_system_power_pmops = {
|
||||||
|
SYSTEM_SLEEP_PM_OPS(NULL, scmi_system_power_resume)
|
||||||
|
};
|
||||||
|
|
||||||
static const struct scmi_device_id scmi_id_table[] = {
|
static const struct scmi_device_id scmi_id_table[] = {
|
||||||
{ SCMI_PROTOCOL_SYSTEM, "syspower" },
|
{ SCMI_PROTOCOL_SYSTEM, "syspower" },
|
||||||
{ },
|
{ },
|
||||||
@ -370,6 +379,9 @@ static const struct scmi_device_id scmi_id_table[] = {
|
|||||||
MODULE_DEVICE_TABLE(scmi, scmi_id_table);
|
MODULE_DEVICE_TABLE(scmi, scmi_id_table);
|
||||||
|
|
||||||
static struct scmi_driver scmi_system_power_driver = {
|
static struct scmi_driver scmi_system_power_driver = {
|
||||||
|
.driver = {
|
||||||
|
.pm = pm_sleep_ptr(&scmi_system_power_pmops),
|
||||||
|
},
|
||||||
.name = "scmi-system-power",
|
.name = "scmi-system-power",
|
||||||
.probe = scmi_syspower_probe,
|
.probe = scmi_syspower_probe,
|
||||||
.id_table = scmi_id_table,
|
.id_table = scmi_id_table,
|
||||||
|
@ -1603,7 +1603,13 @@ bool qcom_scm_lmh_dcvsh_available(void)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(qcom_scm_lmh_dcvsh_available);
|
EXPORT_SYMBOL_GPL(qcom_scm_lmh_dcvsh_available);
|
||||||
|
|
||||||
int qcom_scm_shm_bridge_enable(void)
|
/*
|
||||||
|
* This is only supposed to be called once by the TZMem module. It takes the
|
||||||
|
* SCM struct device as argument and uses it to pass the call as at the time
|
||||||
|
* the SHM Bridge is enabled, the SCM is not yet fully set up and doesn't
|
||||||
|
* accept global user calls. Don't try to use the __scm pointer here.
|
||||||
|
*/
|
||||||
|
int qcom_scm_shm_bridge_enable(struct device *scm_dev)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -1615,11 +1621,11 @@ int qcom_scm_shm_bridge_enable(void)
|
|||||||
|
|
||||||
struct qcom_scm_res res;
|
struct qcom_scm_res res;
|
||||||
|
|
||||||
if (!__qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_MP,
|
if (!__qcom_scm_is_call_available(scm_dev, QCOM_SCM_SVC_MP,
|
||||||
QCOM_SCM_MP_SHM_BRIDGE_ENABLE))
|
QCOM_SCM_MP_SHM_BRIDGE_ENABLE))
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
ret = qcom_scm_call(__scm->dev, &desc, &res);
|
ret = qcom_scm_call(scm_dev, &desc, &res);
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
@ -1631,7 +1637,7 @@ int qcom_scm_shm_bridge_enable(void)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(qcom_scm_shm_bridge_enable);
|
EXPORT_SYMBOL_GPL(qcom_scm_shm_bridge_enable);
|
||||||
|
|
||||||
int qcom_scm_shm_bridge_create(struct device *dev, u64 pfn_and_ns_perm_flags,
|
int qcom_scm_shm_bridge_create(u64 pfn_and_ns_perm_flags,
|
||||||
u64 ipfn_and_s_perm_flags, u64 size_and_flags,
|
u64 ipfn_and_s_perm_flags, u64 size_and_flags,
|
||||||
u64 ns_vmids, u64 *handle)
|
u64 ns_vmids, u64 *handle)
|
||||||
{
|
{
|
||||||
@ -1659,7 +1665,7 @@ int qcom_scm_shm_bridge_create(struct device *dev, u64 pfn_and_ns_perm_flags,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(qcom_scm_shm_bridge_create);
|
EXPORT_SYMBOL_GPL(qcom_scm_shm_bridge_create);
|
||||||
|
|
||||||
int qcom_scm_shm_bridge_delete(struct device *dev, u64 handle)
|
int qcom_scm_shm_bridge_delete(u64 handle)
|
||||||
{
|
{
|
||||||
struct qcom_scm_desc desc = {
|
struct qcom_scm_desc desc = {
|
||||||
.svc = QCOM_SCM_SVC_MP,
|
.svc = QCOM_SCM_SVC_MP,
|
||||||
@ -2250,24 +2256,47 @@ static int qcom_scm_probe(struct platform_device *pdev)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* Paired with smp_load_acquire() in qcom_scm_is_available(). */
|
ret = of_reserved_mem_device_init(scm->dev);
|
||||||
smp_store_release(&__scm, scm);
|
if (ret && ret != -ENODEV)
|
||||||
|
return dev_err_probe(scm->dev, ret,
|
||||||
|
"Failed to setup the reserved memory region for TZ mem\n");
|
||||||
|
|
||||||
|
ret = qcom_tzmem_enable(scm->dev);
|
||||||
|
if (ret)
|
||||||
|
return dev_err_probe(scm->dev, ret,
|
||||||
|
"Failed to enable the TrustZone memory allocator\n");
|
||||||
|
|
||||||
|
memset(&pool_config, 0, sizeof(pool_config));
|
||||||
|
pool_config.initial_size = 0;
|
||||||
|
pool_config.policy = QCOM_TZMEM_POLICY_ON_DEMAND;
|
||||||
|
pool_config.max_size = SZ_256K;
|
||||||
|
|
||||||
|
scm->mempool = devm_qcom_tzmem_pool_new(scm->dev, &pool_config);
|
||||||
|
if (IS_ERR(scm->mempool))
|
||||||
|
return dev_err_probe(scm->dev, PTR_ERR(scm->mempool),
|
||||||
|
"Failed to create the SCM memory pool\n");
|
||||||
|
|
||||||
irq = platform_get_irq_optional(pdev, 0);
|
irq = platform_get_irq_optional(pdev, 0);
|
||||||
if (irq < 0) {
|
if (irq < 0) {
|
||||||
if (irq != -ENXIO) {
|
if (irq != -ENXIO)
|
||||||
ret = irq;
|
return irq;
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
ret = devm_request_threaded_irq(__scm->dev, irq, NULL, qcom_scm_irq_handler,
|
ret = devm_request_threaded_irq(scm->dev, irq, NULL, qcom_scm_irq_handler,
|
||||||
IRQF_ONESHOT, "qcom-scm", __scm);
|
IRQF_ONESHOT, "qcom-scm", scm);
|
||||||
if (ret < 0) {
|
if (ret < 0)
|
||||||
dev_err_probe(scm->dev, ret, "Failed to request qcom-scm irq\n");
|
return dev_err_probe(scm->dev, ret,
|
||||||
goto err;
|
"Failed to request qcom-scm irq\n");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Paired with smp_load_acquire() in qcom_scm_is_available().
|
||||||
|
*
|
||||||
|
* This marks the SCM API as ready to accept user calls and can only
|
||||||
|
* be called after the TrustZone memory pool is initialized and the
|
||||||
|
* waitqueue interrupt requested.
|
||||||
|
*/
|
||||||
|
smp_store_release(&__scm, scm);
|
||||||
|
|
||||||
__get_convention();
|
__get_convention();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2283,32 +2312,6 @@ static int qcom_scm_probe(struct platform_device *pdev)
|
|||||||
if (of_property_read_bool(pdev->dev.of_node, "qcom,sdi-enabled") || !download_mode)
|
if (of_property_read_bool(pdev->dev.of_node, "qcom,sdi-enabled") || !download_mode)
|
||||||
qcom_scm_disable_sdi();
|
qcom_scm_disable_sdi();
|
||||||
|
|
||||||
ret = of_reserved_mem_device_init(__scm->dev);
|
|
||||||
if (ret && ret != -ENODEV) {
|
|
||||||
dev_err_probe(__scm->dev, ret,
|
|
||||||
"Failed to setup the reserved memory region for TZ mem\n");
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = qcom_tzmem_enable(__scm->dev);
|
|
||||||
if (ret) {
|
|
||||||
dev_err_probe(__scm->dev, ret,
|
|
||||||
"Failed to enable the TrustZone memory allocator\n");
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&pool_config, 0, sizeof(pool_config));
|
|
||||||
pool_config.initial_size = 0;
|
|
||||||
pool_config.policy = QCOM_TZMEM_POLICY_ON_DEMAND;
|
|
||||||
pool_config.max_size = SZ_256K;
|
|
||||||
|
|
||||||
__scm->mempool = devm_qcom_tzmem_pool_new(__scm->dev, &pool_config);
|
|
||||||
if (IS_ERR(__scm->mempool)) {
|
|
||||||
ret = dev_err_probe(__scm->dev, PTR_ERR(__scm->mempool),
|
|
||||||
"Failed to create the SCM memory pool\n");
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the QSEECOM interface.
|
* Initialize the QSEECOM interface.
|
||||||
*
|
*
|
||||||
@ -2323,12 +2326,6 @@ static int qcom_scm_probe(struct platform_device *pdev)
|
|||||||
WARN(ret < 0, "failed to initialize qseecom: %d\n", ret);
|
WARN(ret < 0, "failed to initialize qseecom: %d\n", ret);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err:
|
|
||||||
/* Paired with smp_load_acquire() in qcom_scm_is_available(). */
|
|
||||||
smp_store_release(&__scm, NULL);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qcom_scm_shutdown(struct platform_device *pdev)
|
static void qcom_scm_shutdown(struct platform_device *pdev)
|
||||||
|
@ -83,6 +83,7 @@ int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc,
|
|||||||
struct qcom_scm_res *res);
|
struct qcom_scm_res *res);
|
||||||
|
|
||||||
struct qcom_tzmem_pool *qcom_scm_get_tzmem_pool(void);
|
struct qcom_tzmem_pool *qcom_scm_get_tzmem_pool(void);
|
||||||
|
int qcom_scm_shm_bridge_enable(struct device *scm_dev);
|
||||||
|
|
||||||
#define QCOM_SCM_SVC_BOOT 0x01
|
#define QCOM_SCM_SVC_BOOT 0x01
|
||||||
#define QCOM_SCM_BOOT_SET_ADDR 0x01
|
#define QCOM_SCM_BOOT_SET_ADDR 0x01
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
#include "qcom_scm.h"
|
||||||
#include "qcom_tzmem.h"
|
#include "qcom_tzmem.h"
|
||||||
|
|
||||||
struct qcom_tzmem_area {
|
struct qcom_tzmem_area {
|
||||||
@ -94,7 +95,7 @@ static int qcom_tzmem_init(void)
|
|||||||
goto notsupp;
|
goto notsupp;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = qcom_scm_shm_bridge_enable();
|
ret = qcom_scm_shm_bridge_enable(qcom_tzmem_dev);
|
||||||
if (ret == -EOPNOTSUPP)
|
if (ret == -EOPNOTSUPP)
|
||||||
goto notsupp;
|
goto notsupp;
|
||||||
|
|
||||||
@ -124,9 +125,9 @@ static int qcom_tzmem_init_area(struct qcom_tzmem_area *area)
|
|||||||
if (!handle)
|
if (!handle)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
ret = qcom_scm_shm_bridge_create(qcom_tzmem_dev, pfn_and_ns_perm,
|
ret = qcom_scm_shm_bridge_create(pfn_and_ns_perm, ipfn_and_s_perm,
|
||||||
ipfn_and_s_perm, size_and_flags,
|
size_and_flags, QCOM_SCM_VMID_HLOS,
|
||||||
QCOM_SCM_VMID_HLOS, handle);
|
handle);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -142,7 +143,7 @@ static void qcom_tzmem_cleanup_area(struct qcom_tzmem_area *area)
|
|||||||
if (!qcom_tzmem_using_shm_bridge)
|
if (!qcom_tzmem_using_shm_bridge)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
qcom_scm_shm_bridge_delete(qcom_tzmem_dev, *handle);
|
qcom_scm_shm_bridge_delete(*handle);
|
||||||
kfree(handle);
|
kfree(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,10 +72,7 @@ bool arm_smccc_hypervisor_has_uuid(const uuid_t *hyp_uuid)
|
|||||||
struct arm_smccc_res res = {};
|
struct arm_smccc_res res = {};
|
||||||
uuid_t uuid;
|
uuid_t uuid;
|
||||||
|
|
||||||
if (arm_smccc_1_1_get_conduit() != SMCCC_CONDUIT_HVC)
|
arm_smccc_1_1_invoke(ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID, &res);
|
||||||
return false;
|
|
||||||
|
|
||||||
arm_smccc_1_1_hvc(ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID, &res);
|
|
||||||
if (res.a0 == SMCCC_RET_NOT_SUPPORTED)
|
if (res.a0 == SMCCC_RET_NOT_SUPPORTED)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
menu "Tegra firmware driver"
|
menu "Tegra firmware driver"
|
||||||
|
|
||||||
config TEGRA_IVC
|
config TEGRA_IVC
|
||||||
bool "Tegra IVC protocol"
|
bool "Tegra IVC protocol" if COMPILE_TEST
|
||||||
depends on ARCH_TEGRA
|
depends on ARCH_TEGRA
|
||||||
help
|
help
|
||||||
IVC (Inter-VM Communication) protocol is part of the IPC
|
IVC (Inter-VM Communication) protocol is part of the IPC
|
||||||
@ -13,8 +13,9 @@ config TEGRA_IVC
|
|||||||
|
|
||||||
config TEGRA_BPMP
|
config TEGRA_BPMP
|
||||||
bool "Tegra BPMP driver"
|
bool "Tegra BPMP driver"
|
||||||
depends on ARCH_TEGRA && TEGRA_HSP_MBOX && TEGRA_IVC
|
depends on ARCH_TEGRA && TEGRA_HSP_MBOX
|
||||||
depends on !CPU_BIG_ENDIAN
|
depends on !CPU_BIG_ENDIAN
|
||||||
|
select TEGRA_IVC
|
||||||
help
|
help
|
||||||
BPMP (Boot and Power Management Processor) is designed to off-loading
|
BPMP (Boot and Power Management Processor) is designed to off-loading
|
||||||
the PM functions which include clock/DVFS/thermal/power from the CPU.
|
the PM functions which include clock/DVFS/thermal/power from the CPU.
|
||||||
|
@ -4,6 +4,7 @@ tegra-bpmp-$(CONFIG_ARCH_TEGRA_210_SOC) += bpmp-tegra210.o
|
|||||||
tegra-bpmp-$(CONFIG_ARCH_TEGRA_186_SOC) += bpmp-tegra186.o
|
tegra-bpmp-$(CONFIG_ARCH_TEGRA_186_SOC) += bpmp-tegra186.o
|
||||||
tegra-bpmp-$(CONFIG_ARCH_TEGRA_194_SOC) += bpmp-tegra186.o
|
tegra-bpmp-$(CONFIG_ARCH_TEGRA_194_SOC) += bpmp-tegra186.o
|
||||||
tegra-bpmp-$(CONFIG_ARCH_TEGRA_234_SOC) += bpmp-tegra186.o
|
tegra-bpmp-$(CONFIG_ARCH_TEGRA_234_SOC) += bpmp-tegra186.o
|
||||||
|
tegra-bpmp-$(CONFIG_ARCH_TEGRA_264_SOC) += bpmp-tegra186.o
|
||||||
tegra-bpmp-$(CONFIG_DEBUG_FS) += bpmp-debugfs.o
|
tegra-bpmp-$(CONFIG_DEBUG_FS) += bpmp-debugfs.o
|
||||||
obj-$(CONFIG_TEGRA_BPMP) += tegra-bpmp.o
|
obj-$(CONFIG_TEGRA_BPMP) += tegra-bpmp.o
|
||||||
obj-$(CONFIG_TEGRA_IVC) += ivc.o
|
obj-$(CONFIG_TEGRA_IVC) += ivc.o
|
||||||
|
@ -23,13 +23,7 @@ struct tegra_bpmp_ops {
|
|||||||
int (*resume)(struct tegra_bpmp *bpmp);
|
int (*resume)(struct tegra_bpmp *bpmp);
|
||||||
};
|
};
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_ARCH_TEGRA_186_SOC) || \
|
|
||||||
IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC) || \
|
|
||||||
IS_ENABLED(CONFIG_ARCH_TEGRA_234_SOC)
|
|
||||||
extern const struct tegra_bpmp_ops tegra186_bpmp_ops;
|
extern const struct tegra_bpmp_ops tegra186_bpmp_ops;
|
||||||
#endif
|
|
||||||
#if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC)
|
|
||||||
extern const struct tegra_bpmp_ops tegra210_bpmp_ops;
|
extern const struct tegra_bpmp_ops tegra210_bpmp_ops;
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include <linux/genalloc.h>
|
#include <linux/genalloc.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/mailbox_client.h>
|
#include <linux/mailbox_client.h>
|
||||||
#include <linux/of_address.h>
|
#include <linux/of_reserved_mem.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
|
|
||||||
#include <soc/tegra/bpmp.h>
|
#include <soc/tegra/bpmp.h>
|
||||||
@ -192,16 +192,11 @@ static void tegra186_bpmp_teardown_channels(struct tegra_bpmp *bpmp)
|
|||||||
static int tegra186_bpmp_dram_init(struct tegra_bpmp *bpmp)
|
static int tegra186_bpmp_dram_init(struct tegra_bpmp *bpmp)
|
||||||
{
|
{
|
||||||
struct tegra186_bpmp *priv = bpmp->priv;
|
struct tegra186_bpmp *priv = bpmp->priv;
|
||||||
struct device_node *np;
|
|
||||||
struct resource res;
|
struct resource res;
|
||||||
size_t size;
|
size_t size;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
np = of_parse_phandle(bpmp->dev->of_node, "memory-region", 0);
|
err = of_reserved_mem_region_to_resource(bpmp->dev->of_node, 0, &res);
|
||||||
if (!np)
|
|
||||||
return -ENODEV;
|
|
||||||
|
|
||||||
err = of_address_to_resource(np, 0, &res);
|
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
dev_warn(bpmp->dev, "failed to parse memory region: %d\n", err);
|
dev_warn(bpmp->dev, "failed to parse memory region: %d\n", err);
|
||||||
return err;
|
return err;
|
||||||
|
@ -836,7 +836,8 @@ static const struct dev_pm_ops tegra_bpmp_pm_ops = {
|
|||||||
|
|
||||||
#if IS_ENABLED(CONFIG_ARCH_TEGRA_186_SOC) || \
|
#if IS_ENABLED(CONFIG_ARCH_TEGRA_186_SOC) || \
|
||||||
IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC) || \
|
IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC) || \
|
||||||
IS_ENABLED(CONFIG_ARCH_TEGRA_234_SOC)
|
IS_ENABLED(CONFIG_ARCH_TEGRA_234_SOC) || \
|
||||||
|
IS_ENABLED(CONFIG_ARCH_TEGRA_264_SOC)
|
||||||
static const struct tegra_bpmp_soc tegra186_soc = {
|
static const struct tegra_bpmp_soc tegra186_soc = {
|
||||||
.channels = {
|
.channels = {
|
||||||
.cpu_tx = {
|
.cpu_tx = {
|
||||||
@ -884,7 +885,8 @@ static const struct tegra_bpmp_soc tegra210_soc = {
|
|||||||
static const struct of_device_id tegra_bpmp_match[] = {
|
static const struct of_device_id tegra_bpmp_match[] = {
|
||||||
#if IS_ENABLED(CONFIG_ARCH_TEGRA_186_SOC) || \
|
#if IS_ENABLED(CONFIG_ARCH_TEGRA_186_SOC) || \
|
||||||
IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC) || \
|
IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC) || \
|
||||||
IS_ENABLED(CONFIG_ARCH_TEGRA_234_SOC)
|
IS_ENABLED(CONFIG_ARCH_TEGRA_234_SOC) || \
|
||||||
|
IS_ENABLED(CONFIG_ARCH_TEGRA_264_SOC)
|
||||||
{ .compatible = "nvidia,tegra186-bpmp", .data = &tegra186_soc },
|
{ .compatible = "nvidia,tegra186-bpmp", .data = &tegra186_soc },
|
||||||
#endif
|
#endif
|
||||||
#if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC)
|
#if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC)
|
||||||
|
@ -184,62 +184,10 @@ static const struct of_device_id brcmstb_memc_of_match[] = {
|
|||||||
.compatible = "brcm,brcmstb-memc-ddr-rev-b.2.1",
|
.compatible = "brcm,brcmstb-memc-ddr-rev-b.2.1",
|
||||||
.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
|
.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
|
||||||
},
|
},
|
||||||
{
|
/* default to the V21 offset */
|
||||||
.compatible = "brcm,brcmstb-memc-ddr-rev-b.2.2",
|
|
||||||
.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.compatible = "brcm,brcmstb-memc-ddr-rev-b.2.3",
|
|
||||||
.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.compatible = "brcm,brcmstb-memc-ddr-rev-b.2.5",
|
|
||||||
.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.compatible = "brcm,brcmstb-memc-ddr-rev-b.2.6",
|
|
||||||
.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.compatible = "brcm,brcmstb-memc-ddr-rev-b.2.7",
|
|
||||||
.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.compatible = "brcm,brcmstb-memc-ddr-rev-b.2.8",
|
|
||||||
.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.compatible = "brcm,brcmstb-memc-ddr-rev-b.3.0",
|
|
||||||
.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.compatible = "brcm,brcmstb-memc-ddr-rev-b.3.1",
|
|
||||||
.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.compatible = "brcm,brcmstb-memc-ddr-rev-c.1.0",
|
|
||||||
.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.compatible = "brcm,brcmstb-memc-ddr-rev-c.1.1",
|
|
||||||
.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.compatible = "brcm,brcmstb-memc-ddr-rev-c.1.2",
|
|
||||||
.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.compatible = "brcm,brcmstb-memc-ddr-rev-c.1.3",
|
|
||||||
.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.compatible = "brcm,brcmstb-memc-ddr-rev-c.1.4",
|
|
||||||
.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
|
|
||||||
},
|
|
||||||
/* default to the original offset */
|
|
||||||
{
|
{
|
||||||
.compatible = "brcm,brcmstb-memc-ddr",
|
.compatible = "brcm,brcmstb-memc-ddr",
|
||||||
.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V1X]
|
.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
|
||||||
},
|
},
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
* are two devices attached to this EMIF, this
|
* are two devices attached to this EMIF, this
|
||||||
* value is the maximum of the two temperature
|
* value is the maximum of the two temperature
|
||||||
* levels.
|
* levels.
|
||||||
|
* @lpmode: Chosen low power mode
|
||||||
* @node: node in the device list
|
* @node: node in the device list
|
||||||
* @base: base address of memory-mapped IO registers.
|
* @base: base address of memory-mapped IO registers.
|
||||||
* @dev: device pointer.
|
* @dev: device pointer.
|
||||||
|
@ -320,6 +320,38 @@ static const u8 mtk_smi_larb_mt6893_ostd[][SMI_LARB_PORT_NR_MAX] = {
|
|||||||
[20] = {0x9, 0x9, 0x5, 0x5, 0x1, 0x1},
|
[20] = {0x9, 0x9, 0x5, 0x5, 0x1, 0x1},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const u8 mtk_smi_larb_mt8186_ostd[][SMI_LARB_PORT_NR_MAX] = {
|
||||||
|
[0] = {0x2, 0x1, 0x8, 0x1,},
|
||||||
|
[1] = {0x1, 0x3, 0x1, 0x1,},
|
||||||
|
[2] = {0x6, 0x1, 0x4, 0x1,},
|
||||||
|
[3] = {},
|
||||||
|
[4] = {0xf, 0x1, 0x5, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,
|
||||||
|
0x1, 0x1, 0x1,},
|
||||||
|
[5] = {},
|
||||||
|
[6] = {},
|
||||||
|
[7] = {0x1, 0x3, 0x1, 0x1, 0x1, 0x3, 0x2, 0xd, 0x7, 0x5, 0x3,
|
||||||
|
0x1, 0x5,},
|
||||||
|
[8] = {0x1, 0x2, 0x2,},
|
||||||
|
[9] = {0x9, 0x7, 0xf, 0x8, 0x1, 0x8, 0x9, 0x3, 0x3, 0xb, 0x7, 0x4,
|
||||||
|
0x9, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,
|
||||||
|
0x1, 0x1, 0x1, 0x1, 0x1,},
|
||||||
|
[10] = {},
|
||||||
|
[11] = {0x9, 0x7, 0xf, 0x8, 0x1, 0x8, 0x9, 0x3, 0x3, 0xb, 0x7, 0x4,
|
||||||
|
0x9, 0x1, 0x1, 0x1, 0x1, 0x1, 0x8, 0x7, 0x7, 0x1, 0x6, 0x2,
|
||||||
|
0xf, 0x8, 0x1, 0x1, 0x1,},
|
||||||
|
[12] = {},
|
||||||
|
[13] = {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x6, 0x6, 0x6, 0x1, 0x1, 0x1,},
|
||||||
|
[14] = {0x1, 0x1, 0x1, 0x1, 0x1, 0x1,},
|
||||||
|
[15] = {},
|
||||||
|
[16] = {0x28, 0x14, 0x2, 0xc, 0x18, 0x1, 0x14, 0x1, 0x4, 0x4, 0x4,
|
||||||
|
0x2, 0x4, 0x2, 0x8, 0x4, 0x4,},
|
||||||
|
[17] = {0x28, 0x14, 0x2, 0xc, 0x18, 0x1, 0x14, 0x1, 0x4, 0x4, 0x4,
|
||||||
|
0x2, 0x4, 0x2, 0x8, 0x4, 0x4,},
|
||||||
|
[18] = {},
|
||||||
|
[19] = {0x1, 0x1, 0x1, 0x1,},
|
||||||
|
[20] = {0x2, 0x2, 0x2, 0x2, 0x1, 0x1,},
|
||||||
|
};
|
||||||
|
|
||||||
static const u8 mtk_smi_larb_mt8188_ostd[][SMI_LARB_PORT_NR_MAX] = {
|
static const u8 mtk_smi_larb_mt8188_ostd[][SMI_LARB_PORT_NR_MAX] = {
|
||||||
[0] = {0x02, 0x18, 0x22, 0x22, 0x01, 0x02, 0x0a,},
|
[0] = {0x02, 0x18, 0x22, 0x22, 0x01, 0x02, 0x0a,},
|
||||||
[1] = {0x12, 0x02, 0x14, 0x14, 0x01, 0x18, 0x0a,},
|
[1] = {0x12, 0x02, 0x14, 0x14, 0x01, 0x18, 0x0a,},
|
||||||
@ -491,6 +523,7 @@ static const struct mtk_smi_larb_gen mtk_smi_larb_mt8183 = {
|
|||||||
static const struct mtk_smi_larb_gen mtk_smi_larb_mt8186 = {
|
static const struct mtk_smi_larb_gen mtk_smi_larb_mt8186 = {
|
||||||
.config_port = mtk_smi_larb_config_port_gen2_general,
|
.config_port = mtk_smi_larb_config_port_gen2_general,
|
||||||
.flags_general = MTK_SMI_FLAG_SLEEP_CTL,
|
.flags_general = MTK_SMI_FLAG_SLEEP_CTL,
|
||||||
|
.ostd = mtk_smi_larb_mt8186_ostd,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct mtk_smi_larb_gen mtk_smi_larb_mt8188 = {
|
static const struct mtk_smi_larb_gen mtk_smi_larb_mt8188 = {
|
||||||
|
@ -1455,8 +1455,8 @@ static int gpmc_setup_irq(struct gpmc_device *gpmc)
|
|||||||
gpmc->irq_chip.irq_unmask = gpmc_irq_unmask;
|
gpmc->irq_chip.irq_unmask = gpmc_irq_unmask;
|
||||||
gpmc->irq_chip.irq_set_type = gpmc_irq_set_type;
|
gpmc->irq_chip.irq_set_type = gpmc_irq_set_type;
|
||||||
|
|
||||||
gpmc_irq_domain = irq_domain_create_linear(of_fwnode_handle(gpmc->dev->of_node),
|
gpmc_irq_domain = irq_domain_create_linear(dev_fwnode(gpmc->dev), gpmc->nirqs,
|
||||||
gpmc->nirqs, &gpmc_irq_domain_ops, gpmc);
|
&gpmc_irq_domain_ops, gpmc);
|
||||||
if (!gpmc_irq_domain) {
|
if (!gpmc_irq_domain) {
|
||||||
dev_err(gpmc->dev, "IRQ domain add failed\n");
|
dev_err(gpmc->dev, "IRQ domain add failed\n");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
@ -46,7 +46,7 @@ static int stm32_omm_set_amcr(struct device *dev, bool set)
|
|||||||
struct regmap *syscfg_regmap;
|
struct regmap *syscfg_regmap;
|
||||||
struct device_node *node;
|
struct device_node *node;
|
||||||
struct resource res, res1;
|
struct resource res, res1;
|
||||||
u32 amcr_base, amcr_mask;
|
unsigned int syscon_args[2];
|
||||||
int ret, idx;
|
int ret, idx;
|
||||||
unsigned int i, amcr, read_amcr;
|
unsigned int i, amcr, read_amcr;
|
||||||
|
|
||||||
@ -98,29 +98,20 @@ static int stm32_omm_set_amcr(struct device *dev, bool set)
|
|||||||
of_node_put(node);
|
of_node_put(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
syscfg_regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "st,syscfg-amcr");
|
syscfg_regmap = syscon_regmap_lookup_by_phandle_args(dev->of_node, "st,syscfg-amcr",
|
||||||
|
2, syscon_args);
|
||||||
if (IS_ERR(syscfg_regmap))
|
if (IS_ERR(syscfg_regmap))
|
||||||
return dev_err_probe(dev, PTR_ERR(syscfg_regmap),
|
return dev_err_probe(dev, PTR_ERR(syscfg_regmap),
|
||||||
"Failed to get st,syscfg-amcr property\n");
|
"Failed to get st,syscfg-amcr property\n");
|
||||||
|
|
||||||
ret = of_property_read_u32_index(dev->of_node, "st,syscfg-amcr", 1,
|
|
||||||
&amcr_base);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
ret = of_property_read_u32_index(dev->of_node, "st,syscfg-amcr", 2,
|
|
||||||
&amcr_mask);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
amcr = mm_ospi2_size / SZ_64M;
|
amcr = mm_ospi2_size / SZ_64M;
|
||||||
|
|
||||||
if (set)
|
if (set)
|
||||||
regmap_update_bits(syscfg_regmap, amcr_base, amcr_mask, amcr);
|
regmap_update_bits(syscfg_regmap, syscon_args[0], syscon_args[1], amcr);
|
||||||
|
|
||||||
/* read AMCR and check coherency with memory-map areas defined in DT */
|
/* read AMCR and check coherency with memory-map areas defined in DT */
|
||||||
regmap_read(syscfg_regmap, amcr_base, &read_amcr);
|
regmap_read(syscfg_regmap, syscon_args[0], &read_amcr);
|
||||||
read_amcr = read_amcr >> (ffs(amcr_mask) - 1);
|
read_amcr = read_amcr >> (ffs(syscon_args[1]) - 1);
|
||||||
|
|
||||||
if (amcr != read_amcr) {
|
if (amcr != read_amcr) {
|
||||||
dev_err(dev, "AMCR value not coherent with DT memory-map areas\n");
|
dev_err(dev, "AMCR value not coherent with DT memory-map areas\n");
|
||||||
|
@ -10,6 +10,7 @@ tegra-mc-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210.o
|
|||||||
tegra-mc-$(CONFIG_ARCH_TEGRA_186_SOC) += tegra186.o
|
tegra-mc-$(CONFIG_ARCH_TEGRA_186_SOC) += tegra186.o
|
||||||
tegra-mc-$(CONFIG_ARCH_TEGRA_194_SOC) += tegra186.o tegra194.o
|
tegra-mc-$(CONFIG_ARCH_TEGRA_194_SOC) += tegra186.o tegra194.o
|
||||||
tegra-mc-$(CONFIG_ARCH_TEGRA_234_SOC) += tegra186.o tegra234.o
|
tegra-mc-$(CONFIG_ARCH_TEGRA_234_SOC) += tegra186.o tegra234.o
|
||||||
|
tegra-mc-$(CONFIG_ARCH_TEGRA_264_SOC) += tegra186.o tegra264.o
|
||||||
|
|
||||||
obj-$(CONFIG_TEGRA_MC) += tegra-mc.o
|
obj-$(CONFIG_TEGRA_MC) += tegra-mc.o
|
||||||
|
|
||||||
@ -21,5 +22,6 @@ obj-$(CONFIG_TEGRA210_EMC) += tegra210-emc.o
|
|||||||
obj-$(CONFIG_ARCH_TEGRA_186_SOC) += tegra186-emc.o
|
obj-$(CONFIG_ARCH_TEGRA_186_SOC) += tegra186-emc.o
|
||||||
obj-$(CONFIG_ARCH_TEGRA_194_SOC) += tegra186-emc.o
|
obj-$(CONFIG_ARCH_TEGRA_194_SOC) += tegra186-emc.o
|
||||||
obj-$(CONFIG_ARCH_TEGRA_234_SOC) += tegra186-emc.o
|
obj-$(CONFIG_ARCH_TEGRA_234_SOC) += tegra186-emc.o
|
||||||
|
obj-$(CONFIG_ARCH_TEGRA_264_SOC) += tegra186-emc.o
|
||||||
|
|
||||||
tegra210-emc-y := tegra210-emc-core.o tegra210-emc-cc-r21021.o
|
tegra210-emc-y := tegra210-emc-core.o tegra210-emc-cc-r21021.o
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2014 NVIDIA CORPORATION. All rights reserved.
|
* Copyright (C) 2014-2025 NVIDIA CORPORATION. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
@ -48,6 +48,9 @@ static const struct of_device_id tegra_mc_of_match[] = {
|
|||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_ARCH_TEGRA_234_SOC
|
#ifdef CONFIG_ARCH_TEGRA_234_SOC
|
||||||
{ .compatible = "nvidia,tegra234-mc", .data = &tegra234_mc_soc },
|
{ .compatible = "nvidia,tegra234-mc", .data = &tegra234_mc_soc },
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_ARCH_TEGRA_264_SOC
|
||||||
|
{ .compatible = "nvidia,tegra264-mc", .data = &tegra264_mc_soc },
|
||||||
#endif
|
#endif
|
||||||
{ /* sentinel */ }
|
{ /* sentinel */ }
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2014 NVIDIA CORPORATION. All rights reserved.
|
* Copyright (C) 2014-2025 NVIDIA CORPORATION. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MEMORY_TEGRA_MC_H
|
#ifndef MEMORY_TEGRA_MC_H
|
||||||
@ -182,6 +182,10 @@ extern const struct tegra_mc_soc tegra194_mc_soc;
|
|||||||
extern const struct tegra_mc_soc tegra234_mc_soc;
|
extern const struct tegra_mc_soc tegra234_mc_soc;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARCH_TEGRA_264_SOC
|
||||||
|
extern const struct tegra_mc_soc tegra264_mc_soc;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_ARCH_TEGRA_3x_SOC) || \
|
#if defined(CONFIG_ARCH_TEGRA_3x_SOC) || \
|
||||||
defined(CONFIG_ARCH_TEGRA_114_SOC) || \
|
defined(CONFIG_ARCH_TEGRA_114_SOC) || \
|
||||||
defined(CONFIG_ARCH_TEGRA_124_SOC) || \
|
defined(CONFIG_ARCH_TEGRA_124_SOC) || \
|
||||||
@ -193,7 +197,8 @@ extern const struct tegra_mc_ops tegra30_mc_ops;
|
|||||||
|
|
||||||
#if defined(CONFIG_ARCH_TEGRA_186_SOC) || \
|
#if defined(CONFIG_ARCH_TEGRA_186_SOC) || \
|
||||||
defined(CONFIG_ARCH_TEGRA_194_SOC) || \
|
defined(CONFIG_ARCH_TEGRA_194_SOC) || \
|
||||||
defined(CONFIG_ARCH_TEGRA_234_SOC)
|
defined(CONFIG_ARCH_TEGRA_234_SOC) || \
|
||||||
|
defined(CONFIG_ARCH_TEGRA_264_SOC)
|
||||||
extern const struct tegra_mc_ops tegra186_mc_ops;
|
extern const struct tegra_mc_ops tegra186_mc_ops;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019 NVIDIA CORPORATION. All rights reserved.
|
* Copyright (C) 2019-2025 NVIDIA CORPORATION. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
@ -393,6 +393,9 @@ static const struct of_device_id tegra186_emc_of_match[] = {
|
|||||||
#endif
|
#endif
|
||||||
#if defined(CONFIG_ARCH_TEGRA_234_SOC)
|
#if defined(CONFIG_ARCH_TEGRA_234_SOC)
|
||||||
{ .compatible = "nvidia,tegra234-emc" },
|
{ .compatible = "nvidia,tegra234-emc" },
|
||||||
|
#endif
|
||||||
|
#if defined(CONFIG_ARCH_TEGRA_264_SOC)
|
||||||
|
{ .compatible = "nvidia,tegra264-emc" },
|
||||||
#endif
|
#endif
|
||||||
{ /* sentinel */ }
|
{ /* sentinel */ }
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2017-2021 NVIDIA CORPORATION. All rights reserved.
|
* Copyright (C) 2017-2025 NVIDIA CORPORATION. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
@ -26,11 +26,24 @@
|
|||||||
static int tegra186_mc_probe(struct tegra_mc *mc)
|
static int tegra186_mc_probe(struct tegra_mc *mc)
|
||||||
{
|
{
|
||||||
struct platform_device *pdev = to_platform_device(mc->dev);
|
struct platform_device *pdev = to_platform_device(mc->dev);
|
||||||
|
struct resource *res;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
char name[8];
|
char name[8];
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
mc->bcast_ch_regs = devm_platform_ioremap_resource_byname(pdev, "broadcast");
|
/*
|
||||||
|
* From Tegra264, the SID region is not present in MC node and BROADCAST is first.
|
||||||
|
* The common function 'tegra_mc_probe()' already maps first region entry from DT.
|
||||||
|
* Check if the SID region is present in DT then map BROADCAST. Otherwise, consider
|
||||||
|
* the first entry mapped in mc probe as the BROADCAST region. This is done to avoid
|
||||||
|
* mapping the region twice when SID is not present and keep backward compatibility.
|
||||||
|
*/
|
||||||
|
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sid");
|
||||||
|
if (res)
|
||||||
|
mc->bcast_ch_regs = devm_platform_ioremap_resource_byname(pdev, "broadcast");
|
||||||
|
else
|
||||||
|
mc->bcast_ch_regs = mc->regs;
|
||||||
|
|
||||||
if (IS_ERR(mc->bcast_ch_regs)) {
|
if (IS_ERR(mc->bcast_ch_regs)) {
|
||||||
if (PTR_ERR(mc->bcast_ch_regs) == -EINVAL) {
|
if (PTR_ERR(mc->bcast_ch_regs) == -EINVAL) {
|
||||||
dev_warn(&pdev->dev,
|
dev_warn(&pdev->dev,
|
||||||
|
50
drivers/memory/tegra/tegra264-bwmgr.h
Normal file
50
drivers/memory/tegra/tegra264-bwmgr.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
/* Copyright (C) 2025 NVIDIA CORPORATION. All rights reserved. */
|
||||||
|
|
||||||
|
#ifndef MEMORY_TEGRA_TEGRA264_BWMGR_H
|
||||||
|
#define MEMORY_TEGRA_TEGRA264_BWMGR_H
|
||||||
|
|
||||||
|
#define TEGRA264_BWMGR_ICC_PRIMARY 1
|
||||||
|
#define TEGRA264_BWMGR_DEBUG 2
|
||||||
|
#define TEGRA264_BWMGR_CPU_CLUSTER0 3
|
||||||
|
#define TEGRA264_BWMGR_CPU_CLUSTER1 4
|
||||||
|
#define TEGRA264_BWMGR_CPU_CLUSTER2 5
|
||||||
|
#define TEGRA264_BWMGR_CPU_CLUSTER3 6
|
||||||
|
#define TEGRA264_BWMGR_CPU_CLUSTER4 7
|
||||||
|
#define TEGRA264_BWMGR_CPU_CLUSTER5 8
|
||||||
|
#define TEGRA264_BWMGR_CPU_CLUSTER6 9
|
||||||
|
#define TEGRA264_BWMGR_CACTMON 10
|
||||||
|
#define TEGRA264_BWMGR_DISPLAY 11
|
||||||
|
#define TEGRA264_BWMGR_VI 12
|
||||||
|
#define TEGRA264_BWMGR_APE 13
|
||||||
|
#define TEGRA264_BWMGR_VIFAL 14
|
||||||
|
#define TEGRA264_BWMGR_GPU 15
|
||||||
|
#define TEGRA264_BWMGR_EQOS 16
|
||||||
|
#define TEGRA264_BWMGR_PCIE_0 17
|
||||||
|
#define TEGRA264_BWMGR_PCIE_1 18
|
||||||
|
#define TEGRA264_BWMGR_PCIE_2 19
|
||||||
|
#define TEGRA264_BWMGR_PCIE_3 20
|
||||||
|
#define TEGRA264_BWMGR_PCIE_4 21
|
||||||
|
#define TEGRA264_BWMGR_PCIE_5 22
|
||||||
|
#define TEGRA264_BWMGR_SDMMC_1 23
|
||||||
|
#define TEGRA264_BWMGR_SDMMC_2 24
|
||||||
|
#define TEGRA264_BWMGR_NVDEC 25
|
||||||
|
#define TEGRA264_BWMGR_NVENC 26
|
||||||
|
#define TEGRA264_BWMGR_NVJPG_0 27
|
||||||
|
#define TEGRA264_BWMGR_NVJPG_1 28
|
||||||
|
#define TEGRA264_BWMGR_OFAA 29
|
||||||
|
#define TEGRA264_BWMGR_XUSB_HOST 30
|
||||||
|
#define TEGRA264_BWMGR_XUSB_DEV 31
|
||||||
|
#define TEGRA264_BWMGR_TSEC 32
|
||||||
|
#define TEGRA264_BWMGR_VIC 33
|
||||||
|
#define TEGRA264_BWMGR_APEDMA 34
|
||||||
|
#define TEGRA264_BWMGR_SE 35
|
||||||
|
#define TEGRA264_BWMGR_ISP 36
|
||||||
|
#define TEGRA264_BWMGR_HDA 37
|
||||||
|
#define TEGRA264_BWMGR_VI2FAL 38
|
||||||
|
#define TEGRA264_BWMGR_VI2 39
|
||||||
|
#define TEGRA264_BWMGR_RCE 40
|
||||||
|
#define TEGRA264_BWMGR_PVA 41
|
||||||
|
#define TEGRA264_BWMGR_NVPMODEL 42
|
||||||
|
|
||||||
|
#endif
|
313
drivers/memory/tegra/tegra264.c
Normal file
313
drivers/memory/tegra/tegra264.c
Normal file
@ -0,0 +1,313 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2025, NVIDIA CORPORATION. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <dt-bindings/memory/nvidia,tegra264.h>
|
||||||
|
|
||||||
|
#include <linux/interconnect.h>
|
||||||
|
#include <linux/of_device.h>
|
||||||
|
#include <linux/tegra-icc.h>
|
||||||
|
|
||||||
|
#include <soc/tegra/bpmp.h>
|
||||||
|
#include <soc/tegra/mc.h>
|
||||||
|
|
||||||
|
#include "mc.h"
|
||||||
|
#include "tegra264-bwmgr.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MC Client entries are sorted in the increasing order of the
|
||||||
|
* override and security register offsets.
|
||||||
|
*/
|
||||||
|
static const struct tegra_mc_client tegra264_mc_clients[] = {
|
||||||
|
{
|
||||||
|
.id = TEGRA264_MEMORY_CLIENT_HDAR,
|
||||||
|
.name = "hdar",
|
||||||
|
.bpmp_id = TEGRA264_BWMGR_HDA,
|
||||||
|
.type = TEGRA_ICC_ISO_AUDIO,
|
||||||
|
}, {
|
||||||
|
.id = TEGRA264_MEMORY_CLIENT_HDAW,
|
||||||
|
.name = "hdaw",
|
||||||
|
.bpmp_id = TEGRA264_BWMGR_HDA,
|
||||||
|
.type = TEGRA_ICC_ISO_AUDIO,
|
||||||
|
}, {
|
||||||
|
.id = TEGRA264_MEMORY_CLIENT_MGBE0R,
|
||||||
|
.name = "mgbe0r",
|
||||||
|
.bpmp_id = TEGRA264_BWMGR_EQOS,
|
||||||
|
.type = TEGRA_ICC_NISO,
|
||||||
|
}, {
|
||||||
|
.id = TEGRA264_MEMORY_CLIENT_MGBE0W,
|
||||||
|
.name = "mgbe0w",
|
||||||
|
.bpmp_id = TEGRA264_BWMGR_EQOS,
|
||||||
|
.type = TEGRA_ICC_NISO,
|
||||||
|
}, {
|
||||||
|
.id = TEGRA264_MEMORY_CLIENT_MGBE1R,
|
||||||
|
.name = "mgbe1r",
|
||||||
|
.bpmp_id = TEGRA264_BWMGR_EQOS,
|
||||||
|
.type = TEGRA_ICC_NISO,
|
||||||
|
}, {
|
||||||
|
.id = TEGRA264_MEMORY_CLIENT_MGBE1W,
|
||||||
|
.name = "mgbe1w",
|
||||||
|
.bpmp_id = TEGRA264_BWMGR_EQOS,
|
||||||
|
.type = TEGRA_ICC_NISO,
|
||||||
|
}, {
|
||||||
|
.id = TEGRA264_MEMORY_CLIENT_SDMMC0R,
|
||||||
|
.name = "sdmmc0r",
|
||||||
|
.bpmp_id = TEGRA264_BWMGR_SDMMC_1,
|
||||||
|
.type = TEGRA_ICC_NISO,
|
||||||
|
}, {
|
||||||
|
.id = TEGRA264_MEMORY_CLIENT_SDMMC0W,
|
||||||
|
.name = "sdmmc0w",
|
||||||
|
.bpmp_id = TEGRA264_BWMGR_SDMMC_1,
|
||||||
|
.type = TEGRA_ICC_NISO,
|
||||||
|
}, {
|
||||||
|
.id = TEGRA264_MEMORY_CLIENT_VICR,
|
||||||
|
.name = "vicr",
|
||||||
|
.bpmp_id = TEGRA264_BWMGR_VIC,
|
||||||
|
.type = TEGRA_ICC_NISO,
|
||||||
|
}, {
|
||||||
|
.id = TEGRA264_MEMORY_CLIENT_VICW,
|
||||||
|
.name = "vicw",
|
||||||
|
.bpmp_id = TEGRA264_BWMGR_VIC,
|
||||||
|
.type = TEGRA_ICC_NISO,
|
||||||
|
}, {
|
||||||
|
.id = TEGRA264_MEMORY_CLIENT_APER,
|
||||||
|
.name = "aper",
|
||||||
|
.bpmp_id = TEGRA264_BWMGR_APE,
|
||||||
|
.type = TEGRA_ICC_ISO_AUDIO,
|
||||||
|
}, {
|
||||||
|
.id = TEGRA264_MEMORY_CLIENT_APEW,
|
||||||
|
.name = "apew",
|
||||||
|
.bpmp_id = TEGRA264_BWMGR_APE,
|
||||||
|
.type = TEGRA_ICC_ISO_AUDIO,
|
||||||
|
}, {
|
||||||
|
.id = TEGRA264_MEMORY_CLIENT_APEDMAR,
|
||||||
|
.name = "apedmar",
|
||||||
|
.bpmp_id = TEGRA264_BWMGR_APEDMA,
|
||||||
|
.type = TEGRA_ICC_ISO_AUDIO,
|
||||||
|
}, {
|
||||||
|
.id = TEGRA264_MEMORY_CLIENT_APEDMAW,
|
||||||
|
.name = "apedmaw",
|
||||||
|
.bpmp_id = TEGRA264_BWMGR_APEDMA,
|
||||||
|
.type = TEGRA_ICC_ISO_AUDIO,
|
||||||
|
}, {
|
||||||
|
.id = TEGRA264_MEMORY_CLIENT_VIFALCONR,
|
||||||
|
.name = "vifalconr",
|
||||||
|
.bpmp_id = TEGRA264_BWMGR_VIFAL,
|
||||||
|
.type = TEGRA_ICC_ISO_VIFAL,
|
||||||
|
}, {
|
||||||
|
.id = TEGRA264_MEMORY_CLIENT_VIFALCONW,
|
||||||
|
.name = "vifalconw",
|
||||||
|
.bpmp_id = TEGRA264_BWMGR_VIFAL,
|
||||||
|
.type = TEGRA_ICC_ISO_VIFAL,
|
||||||
|
}, {
|
||||||
|
.id = TEGRA264_MEMORY_CLIENT_RCER,
|
||||||
|
.name = "rcer",
|
||||||
|
.bpmp_id = TEGRA264_BWMGR_RCE,
|
||||||
|
.type = TEGRA_ICC_NISO,
|
||||||
|
}, {
|
||||||
|
.id = TEGRA264_MEMORY_CLIENT_RCEW,
|
||||||
|
.name = "rcew",
|
||||||
|
.bpmp_id = TEGRA264_BWMGR_RCE,
|
||||||
|
.type = TEGRA_ICC_NISO,
|
||||||
|
}, {
|
||||||
|
.id = TEGRA264_MEMORY_CLIENT_PCIE0W,
|
||||||
|
.name = "pcie0w",
|
||||||
|
.bpmp_id = TEGRA264_BWMGR_PCIE_0,
|
||||||
|
.type = TEGRA_ICC_NISO,
|
||||||
|
}, {
|
||||||
|
.id = TEGRA264_MEMORY_CLIENT_PCIE1R,
|
||||||
|
.name = "pcie1r",
|
||||||
|
.bpmp_id = TEGRA264_BWMGR_PCIE_1,
|
||||||
|
.type = TEGRA_ICC_NISO,
|
||||||
|
}, {
|
||||||
|
.id = TEGRA264_MEMORY_CLIENT_PCIE1W,
|
||||||
|
.name = "pcie1w",
|
||||||
|
.bpmp_id = TEGRA264_BWMGR_PCIE_1,
|
||||||
|
.type = TEGRA_ICC_NISO,
|
||||||
|
}, {
|
||||||
|
.id = TEGRA264_MEMORY_CLIENT_PCIE2AR,
|
||||||
|
.name = "pcie2ar",
|
||||||
|
.bpmp_id = TEGRA264_BWMGR_PCIE_2,
|
||||||
|
.type = TEGRA_ICC_NISO,
|
||||||
|
}, {
|
||||||
|
.id = TEGRA264_MEMORY_CLIENT_PCIE2AW,
|
||||||
|
.name = "pcie2aw",
|
||||||
|
.bpmp_id = TEGRA264_BWMGR_PCIE_2,
|
||||||
|
.type = TEGRA_ICC_NISO,
|
||||||
|
}, {
|
||||||
|
.id = TEGRA264_MEMORY_CLIENT_PCIE3R,
|
||||||
|
.name = "pcie3r",
|
||||||
|
.bpmp_id = TEGRA264_BWMGR_PCIE_3,
|
||||||
|
.type = TEGRA_ICC_NISO,
|
||||||
|
}, {
|
||||||
|
.id = TEGRA264_MEMORY_CLIENT_PCIE3W,
|
||||||
|
.name = "pcie3w",
|
||||||
|
.bpmp_id = TEGRA264_BWMGR_PCIE_3,
|
||||||
|
.type = TEGRA_ICC_NISO,
|
||||||
|
}, {
|
||||||
|
.id = TEGRA264_MEMORY_CLIENT_PCIE4R,
|
||||||
|
.name = "pcie4r",
|
||||||
|
.bpmp_id = TEGRA264_BWMGR_PCIE_4,
|
||||||
|
.type = TEGRA_ICC_NISO,
|
||||||
|
}, {
|
||||||
|
.id = TEGRA264_MEMORY_CLIENT_PCIE4W,
|
||||||
|
.name = "pcie4w",
|
||||||
|
.bpmp_id = TEGRA264_BWMGR_PCIE_4,
|
||||||
|
.type = TEGRA_ICC_NISO,
|
||||||
|
}, {
|
||||||
|
.id = TEGRA264_MEMORY_CLIENT_PCIE5R,
|
||||||
|
.name = "pcie5r",
|
||||||
|
.bpmp_id = TEGRA264_BWMGR_PCIE_5,
|
||||||
|
.type = TEGRA_ICC_NISO,
|
||||||
|
}, {
|
||||||
|
.id = TEGRA264_MEMORY_CLIENT_PCIE5W,
|
||||||
|
.name = "pcie5w",
|
||||||
|
.bpmp_id = TEGRA264_BWMGR_PCIE_5,
|
||||||
|
.type = TEGRA_ICC_NISO,
|
||||||
|
}, {
|
||||||
|
.id = TEGRA264_MEMORY_CLIENT_GPUR02MC,
|
||||||
|
.name = "gpur02mc",
|
||||||
|
.bpmp_id = TEGRA264_BWMGR_GPU,
|
||||||
|
.type = TEGRA_ICC_NISO,
|
||||||
|
}, {
|
||||||
|
.id = TEGRA264_MEMORY_CLIENT_GPUW02MC,
|
||||||
|
.name = "gpuw02mc",
|
||||||
|
.bpmp_id = TEGRA264_BWMGR_GPU,
|
||||||
|
.type = TEGRA_ICC_NISO,
|
||||||
|
}, {
|
||||||
|
.id = TEGRA264_MEMORY_CLIENT_NVDECSRD2MC,
|
||||||
|
.name = "nvdecsrd2mc",
|
||||||
|
.bpmp_id = TEGRA264_BWMGR_NVDEC,
|
||||||
|
.type = TEGRA_ICC_NISO,
|
||||||
|
}, {
|
||||||
|
.id = TEGRA264_MEMORY_CLIENT_NVDECSWR2MC,
|
||||||
|
.name = "nvdecswr2mc",
|
||||||
|
.bpmp_id = TEGRA264_BWMGR_NVDEC,
|
||||||
|
.type = TEGRA_ICC_NISO,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tegra264_mc_icc_set() - Pass MC client info to the BPMP-FW
|
||||||
|
* @src: ICC node for Memory Controller's (MC) Client
|
||||||
|
* @dst: ICC node for Memory Controller (MC)
|
||||||
|
*
|
||||||
|
* Passing the current request info from the MC to the BPMP-FW where
|
||||||
|
* LA and PTSA registers are accessed and the final EMC freq is set
|
||||||
|
* based on client_id, type, latency and bandwidth.
|
||||||
|
* icc_set_bw() makes set_bw calls for both MC and EMC providers in
|
||||||
|
* sequence. Both the calls are protected by 'mutex_lock(&icc_lock)'.
|
||||||
|
* So, the data passed won't be updated by concurrent set calls from
|
||||||
|
* other clients.
|
||||||
|
*/
|
||||||
|
static int tegra264_mc_icc_set(struct icc_node *src, struct icc_node *dst)
|
||||||
|
{
|
||||||
|
struct tegra_mc *mc = icc_provider_to_tegra_mc(dst->provider);
|
||||||
|
struct mrq_bwmgr_int_request bwmgr_req = { 0 };
|
||||||
|
struct mrq_bwmgr_int_response bwmgr_resp = { 0 };
|
||||||
|
const struct tegra_mc_client *pclient = src->data;
|
||||||
|
struct tegra_bpmp_message msg;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Same Src and Dst node will happen during boot from icc_node_add().
|
||||||
|
* This can be used to pre-initialize and set bandwidth for all clients
|
||||||
|
* before their drivers are loaded. We are skipping this case as for us,
|
||||||
|
* the pre-initialization already happened in Bootloader(MB2) and BPMP-FW.
|
||||||
|
*/
|
||||||
|
if (src->id == dst->id)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!mc->bwmgr_mrq_supported)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!mc->bpmp) {
|
||||||
|
dev_err(mc->dev, "BPMP reference NULL\n");
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pclient->type == TEGRA_ICC_NISO)
|
||||||
|
bwmgr_req.bwmgr_calc_set_req.niso_bw = src->avg_bw;
|
||||||
|
else
|
||||||
|
bwmgr_req.bwmgr_calc_set_req.iso_bw = src->avg_bw;
|
||||||
|
|
||||||
|
bwmgr_req.bwmgr_calc_set_req.client_id = pclient->bpmp_id;
|
||||||
|
|
||||||
|
bwmgr_req.cmd = CMD_BWMGR_INT_CALC_AND_SET;
|
||||||
|
bwmgr_req.bwmgr_calc_set_req.mc_floor = src->peak_bw;
|
||||||
|
bwmgr_req.bwmgr_calc_set_req.floor_unit = BWMGR_INT_UNIT_KBPS;
|
||||||
|
|
||||||
|
memset(&msg, 0, sizeof(msg));
|
||||||
|
msg.mrq = MRQ_BWMGR_INT;
|
||||||
|
msg.tx.data = &bwmgr_req;
|
||||||
|
msg.tx.size = sizeof(bwmgr_req);
|
||||||
|
msg.rx.data = &bwmgr_resp;
|
||||||
|
msg.rx.size = sizeof(bwmgr_resp);
|
||||||
|
|
||||||
|
ret = tegra_bpmp_transfer(mc->bpmp, &msg);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(mc->dev, "BPMP transfer failed: %d\n", ret);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (msg.rx.ret < 0) {
|
||||||
|
pr_err("failed to set bandwidth for %u: %d\n",
|
||||||
|
bwmgr_req.bwmgr_calc_set_req.client_id, msg.rx.ret);
|
||||||
|
ret = -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
error:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tegra264_mc_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
|
||||||
|
u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
|
||||||
|
{
|
||||||
|
struct icc_provider *p = node->provider;
|
||||||
|
struct tegra_mc *mc = icc_provider_to_tegra_mc(p);
|
||||||
|
|
||||||
|
if (!mc->bwmgr_mrq_supported)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
*agg_avg += avg_bw;
|
||||||
|
*agg_peak = max(*agg_peak, peak_bw);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tegra264_mc_icc_get_init_bw(struct icc_node *node, u32 *avg, u32 *peak)
|
||||||
|
{
|
||||||
|
*avg = 0;
|
||||||
|
*peak = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct tegra_mc_icc_ops tegra264_mc_icc_ops = {
|
||||||
|
.xlate = tegra_mc_icc_xlate,
|
||||||
|
.aggregate = tegra264_mc_icc_aggregate,
|
||||||
|
.get_bw = tegra264_mc_icc_get_init_bw,
|
||||||
|
.set = tegra264_mc_icc_set,
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct tegra_mc_soc tegra264_mc_soc = {
|
||||||
|
.num_clients = ARRAY_SIZE(tegra264_mc_clients),
|
||||||
|
.clients = tegra264_mc_clients,
|
||||||
|
.num_address_bits = 40,
|
||||||
|
.num_channels = 16,
|
||||||
|
.client_id_mask = 0x1ff,
|
||||||
|
.intmask = MC_INT_DECERR_ROUTE_SANITY |
|
||||||
|
MC_INT_DECERR_GENERALIZED_CARVEOUT | MC_INT_DECERR_MTS |
|
||||||
|
MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
|
||||||
|
MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM,
|
||||||
|
.has_addr_hi_reg = true,
|
||||||
|
.ops = &tegra186_mc_ops,
|
||||||
|
.icc_ops = &tegra264_mc_icc_ops,
|
||||||
|
.ch_intmask = 0x0000ff00,
|
||||||
|
.global_intstatus_channel_shift = 8,
|
||||||
|
/*
|
||||||
|
* Additionally, there are lite carveouts but those are not currently
|
||||||
|
* supported.
|
||||||
|
*/
|
||||||
|
.num_carveouts = 32,
|
||||||
|
};
|
@ -660,4 +660,5 @@ source "drivers/misc/pvpanic/Kconfig"
|
|||||||
source "drivers/misc/mchp_pci1xxxx/Kconfig"
|
source "drivers/misc/mchp_pci1xxxx/Kconfig"
|
||||||
source "drivers/misc/keba/Kconfig"
|
source "drivers/misc/keba/Kconfig"
|
||||||
source "drivers/misc/amd-sbi/Kconfig"
|
source "drivers/misc/amd-sbi/Kconfig"
|
||||||
|
source "drivers/misc/rp1/Kconfig"
|
||||||
endmenu
|
endmenu
|
||||||
|
@ -75,3 +75,4 @@ lan966x-pci-objs += lan966x_pci.dtbo.o
|
|||||||
obj-$(CONFIG_MCHP_LAN966X_PCI) += lan966x-pci.o
|
obj-$(CONFIG_MCHP_LAN966X_PCI) += lan966x-pci.o
|
||||||
obj-y += keba/
|
obj-y += keba/
|
||||||
obj-y += amd-sbi/
|
obj-y += amd-sbi/
|
||||||
|
obj-$(CONFIG_MISC_RP1) += rp1/
|
||||||
|
20
drivers/misc/rp1/Kconfig
Normal file
20
drivers/misc/rp1/Kconfig
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
#
|
||||||
|
# RaspberryPi RP1 misc device
|
||||||
|
#
|
||||||
|
|
||||||
|
config MISC_RP1
|
||||||
|
tristate "RaspberryPi RP1 misc device"
|
||||||
|
depends on OF_IRQ && OF_OVERLAY && PCI_MSI && PCI_QUIRKS
|
||||||
|
select PCI_DYNAMIC_OF_NODES
|
||||||
|
help
|
||||||
|
Support the RP1 peripheral chip found on Raspberry Pi 5 board.
|
||||||
|
|
||||||
|
This device supports several sub-devices including e.g. Ethernet
|
||||||
|
controller, USB controller, I2C, SPI and UART.
|
||||||
|
|
||||||
|
The driver is responsible for enabling the DT node once the PCIe
|
||||||
|
endpoint has been configured, and handling interrupts.
|
||||||
|
|
||||||
|
This driver uses an overlay to load other drivers to support for
|
||||||
|
RP1 internal sub-devices.
|
3
drivers/misc/rp1/Makefile
Normal file
3
drivers/misc/rp1/Makefile
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
obj-$(CONFIG_MISC_RP1) += rp1-pci.o
|
||||||
|
rp1-pci-objs := rp1_pci.o rp1-pci.dtbo.o
|
25
drivers/misc/rp1/rp1-pci.dtso
Normal file
25
drivers/misc/rp1/rp1-pci.dtso
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The dts overlay is included from the dts directory so
|
||||||
|
* it can be possible to check it with CHECK_DTBS while
|
||||||
|
* also compile it from the driver source directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/dts-v1/;
|
||||||
|
/plugin/;
|
||||||
|
|
||||||
|
/ {
|
||||||
|
fragment@0 {
|
||||||
|
target-path="";
|
||||||
|
__overlay__ {
|
||||||
|
compatible = "pci1de4,1";
|
||||||
|
#address-cells = <3>;
|
||||||
|
#size-cells = <2>;
|
||||||
|
interrupt-controller;
|
||||||
|
#interrupt-cells = <2>;
|
||||||
|
|
||||||
|
#include "arm64/broadcom/rp1-common.dtsi"
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
333
drivers/misc/rp1/rp1_pci.c
Normal file
333
drivers/misc/rp1/rp1_pci.c
Normal file
@ -0,0 +1,333 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2025 Raspberry Pi Ltd.
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
#include <linux/irq.h>
|
||||||
|
#include <linux/irqchip/chained_irq.h>
|
||||||
|
#include <linux/irqdomain.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/msi.h>
|
||||||
|
#include <linux/of_platform.h>
|
||||||
|
#include <linux/pci.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
|
||||||
|
#define RP1_HW_IRQ_MASK GENMASK(5, 0)
|
||||||
|
|
||||||
|
#define REG_SET 0x800
|
||||||
|
#define REG_CLR 0xc00
|
||||||
|
|
||||||
|
/* MSI-X CFG registers start at 0x8 */
|
||||||
|
#define MSIX_CFG(x) (0x8 + (4 * (x)))
|
||||||
|
|
||||||
|
#define MSIX_CFG_IACK_EN BIT(3)
|
||||||
|
#define MSIX_CFG_IACK BIT(2)
|
||||||
|
#define MSIX_CFG_ENABLE BIT(0)
|
||||||
|
|
||||||
|
/* Address map */
|
||||||
|
#define RP1_PCIE_APBS_BASE 0x108000
|
||||||
|
|
||||||
|
/* Interrupts */
|
||||||
|
#define RP1_INT_END 61
|
||||||
|
|
||||||
|
/* Embedded dtbo symbols created by cmd_wrap_S_dtb in scripts/Makefile.lib */
|
||||||
|
extern char __dtbo_rp1_pci_begin[];
|
||||||
|
extern char __dtbo_rp1_pci_end[];
|
||||||
|
|
||||||
|
struct rp1_dev {
|
||||||
|
struct pci_dev *pdev;
|
||||||
|
struct irq_domain *domain;
|
||||||
|
struct irq_data *pcie_irqds[64];
|
||||||
|
void __iomem *bar1;
|
||||||
|
int ovcs_id; /* overlay changeset id */
|
||||||
|
bool level_triggered_irq[RP1_INT_END];
|
||||||
|
};
|
||||||
|
|
||||||
|
static void msix_cfg_set(struct rp1_dev *rp1, unsigned int hwirq, u32 value)
|
||||||
|
{
|
||||||
|
iowrite32(value, rp1->bar1 + RP1_PCIE_APBS_BASE + REG_SET + MSIX_CFG(hwirq));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void msix_cfg_clr(struct rp1_dev *rp1, unsigned int hwirq, u32 value)
|
||||||
|
{
|
||||||
|
iowrite32(value, rp1->bar1 + RP1_PCIE_APBS_BASE + REG_CLR + MSIX_CFG(hwirq));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rp1_mask_irq(struct irq_data *irqd)
|
||||||
|
{
|
||||||
|
struct rp1_dev *rp1 = irqd->domain->host_data;
|
||||||
|
struct irq_data *pcie_irqd = rp1->pcie_irqds[irqd->hwirq];
|
||||||
|
|
||||||
|
pci_msi_mask_irq(pcie_irqd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rp1_unmask_irq(struct irq_data *irqd)
|
||||||
|
{
|
||||||
|
struct rp1_dev *rp1 = irqd->domain->host_data;
|
||||||
|
struct irq_data *pcie_irqd = rp1->pcie_irqds[irqd->hwirq];
|
||||||
|
|
||||||
|
pci_msi_unmask_irq(pcie_irqd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rp1_irq_set_type(struct irq_data *irqd, unsigned int type)
|
||||||
|
{
|
||||||
|
struct rp1_dev *rp1 = irqd->domain->host_data;
|
||||||
|
unsigned int hwirq = (unsigned int)irqd->hwirq;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case IRQ_TYPE_LEVEL_HIGH:
|
||||||
|
dev_dbg(&rp1->pdev->dev, "MSIX IACK EN for IRQ %u\n", hwirq);
|
||||||
|
msix_cfg_set(rp1, hwirq, MSIX_CFG_IACK_EN);
|
||||||
|
rp1->level_triggered_irq[hwirq] = true;
|
||||||
|
break;
|
||||||
|
case IRQ_TYPE_EDGE_RISING:
|
||||||
|
msix_cfg_clr(rp1, hwirq, MSIX_CFG_IACK_EN);
|
||||||
|
rp1->level_triggered_irq[hwirq] = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct irq_chip rp1_irq_chip = {
|
||||||
|
.name = "rp1_irq_chip",
|
||||||
|
.irq_mask = rp1_mask_irq,
|
||||||
|
.irq_unmask = rp1_unmask_irq,
|
||||||
|
.irq_set_type = rp1_irq_set_type,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void rp1_chained_handle_irq(struct irq_desc *desc)
|
||||||
|
{
|
||||||
|
unsigned int hwirq = desc->irq_data.hwirq & RP1_HW_IRQ_MASK;
|
||||||
|
struct rp1_dev *rp1 = irq_desc_get_handler_data(desc);
|
||||||
|
struct irq_chip *chip = irq_desc_get_chip(desc);
|
||||||
|
unsigned int virq;
|
||||||
|
|
||||||
|
chained_irq_enter(chip, desc);
|
||||||
|
|
||||||
|
virq = irq_find_mapping(rp1->domain, hwirq);
|
||||||
|
generic_handle_irq(virq);
|
||||||
|
if (rp1->level_triggered_irq[hwirq])
|
||||||
|
msix_cfg_set(rp1, hwirq, MSIX_CFG_IACK);
|
||||||
|
|
||||||
|
chained_irq_exit(chip, desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rp1_irq_xlate(struct irq_domain *d, struct device_node *node,
|
||||||
|
const u32 *intspec, unsigned int intsize,
|
||||||
|
unsigned long *out_hwirq, unsigned int *out_type)
|
||||||
|
{
|
||||||
|
struct rp1_dev *rp1 = d->host_data;
|
||||||
|
struct irq_data *pcie_irqd;
|
||||||
|
unsigned long hwirq;
|
||||||
|
int pcie_irq;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = irq_domain_xlate_twocell(d, node, intspec, intsize,
|
||||||
|
&hwirq, out_type);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
pcie_irq = pci_irq_vector(rp1->pdev, hwirq);
|
||||||
|
pcie_irqd = irq_get_irq_data(pcie_irq);
|
||||||
|
rp1->pcie_irqds[hwirq] = pcie_irqd;
|
||||||
|
*out_hwirq = hwirq;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rp1_irq_activate(struct irq_domain *d, struct irq_data *irqd,
|
||||||
|
bool reserve)
|
||||||
|
{
|
||||||
|
struct rp1_dev *rp1 = d->host_data;
|
||||||
|
|
||||||
|
msix_cfg_set(rp1, (unsigned int)irqd->hwirq, MSIX_CFG_ENABLE);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rp1_irq_deactivate(struct irq_domain *d, struct irq_data *irqd)
|
||||||
|
{
|
||||||
|
struct rp1_dev *rp1 = d->host_data;
|
||||||
|
|
||||||
|
msix_cfg_clr(rp1, (unsigned int)irqd->hwirq, MSIX_CFG_ENABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct irq_domain_ops rp1_domain_ops = {
|
||||||
|
.xlate = rp1_irq_xlate,
|
||||||
|
.activate = rp1_irq_activate,
|
||||||
|
.deactivate = rp1_irq_deactivate,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void rp1_unregister_interrupts(struct pci_dev *pdev)
|
||||||
|
{
|
||||||
|
struct rp1_dev *rp1 = pci_get_drvdata(pdev);
|
||||||
|
int irq, i;
|
||||||
|
|
||||||
|
if (rp1->domain) {
|
||||||
|
for (i = 0; i < RP1_INT_END; i++) {
|
||||||
|
irq = irq_find_mapping(rp1->domain, i);
|
||||||
|
irq_dispose_mapping(irq);
|
||||||
|
}
|
||||||
|
|
||||||
|
irq_domain_remove(rp1->domain);
|
||||||
|
}
|
||||||
|
|
||||||
|
pci_free_irq_vectors(pdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rp1_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||||
|
{
|
||||||
|
u32 dtbo_size = __dtbo_rp1_pci_end - __dtbo_rp1_pci_begin;
|
||||||
|
void *dtbo_start = __dtbo_rp1_pci_begin;
|
||||||
|
struct device *dev = &pdev->dev;
|
||||||
|
struct device_node *rp1_node;
|
||||||
|
bool skip_ovl = true;
|
||||||
|
struct rp1_dev *rp1;
|
||||||
|
int err = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Either use rp1_nexus node if already present in DT, or
|
||||||
|
* set a flag to load it from overlay at runtime
|
||||||
|
*/
|
||||||
|
rp1_node = of_find_node_by_name(NULL, "rp1_nexus");
|
||||||
|
if (!rp1_node) {
|
||||||
|
rp1_node = dev_of_node(dev);
|
||||||
|
skip_ovl = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rp1_node) {
|
||||||
|
dev_err(dev, "Missing of_node for device\n");
|
||||||
|
err = -EINVAL;
|
||||||
|
goto err_put_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
rp1 = devm_kzalloc(&pdev->dev, sizeof(*rp1), GFP_KERNEL);
|
||||||
|
if (!rp1) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto err_put_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
rp1->pdev = pdev;
|
||||||
|
|
||||||
|
if (pci_resource_len(pdev, 1) <= 0x10000) {
|
||||||
|
dev_err(&pdev->dev,
|
||||||
|
"Not initialized - is the firmware running?\n");
|
||||||
|
err = -EINVAL;
|
||||||
|
goto err_put_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = pcim_enable_device(pdev);
|
||||||
|
if (err < 0) {
|
||||||
|
err = dev_err_probe(&pdev->dev, err,
|
||||||
|
"Enabling PCI device has failed");
|
||||||
|
goto err_put_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
rp1->bar1 = pcim_iomap(pdev, 1, 0);
|
||||||
|
if (!rp1->bar1) {
|
||||||
|
dev_err(&pdev->dev, "Cannot map PCI BAR\n");
|
||||||
|
err = -EIO;
|
||||||
|
goto err_put_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
pci_set_master(pdev);
|
||||||
|
|
||||||
|
err = pci_alloc_irq_vectors(pdev, RP1_INT_END, RP1_INT_END,
|
||||||
|
PCI_IRQ_MSIX);
|
||||||
|
if (err < 0) {
|
||||||
|
err = dev_err_probe(&pdev->dev, err,
|
||||||
|
"Failed to allocate MSI-X vectors\n");
|
||||||
|
goto err_put_node;
|
||||||
|
} else if (err != RP1_INT_END) {
|
||||||
|
dev_err(&pdev->dev, "Cannot allocate enough interrupts\n");
|
||||||
|
err = -EINVAL;
|
||||||
|
goto err_put_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
pci_set_drvdata(pdev, rp1);
|
||||||
|
rp1->domain = irq_domain_add_linear(rp1_node, RP1_INT_END,
|
||||||
|
&rp1_domain_ops, rp1);
|
||||||
|
if (!rp1->domain) {
|
||||||
|
dev_err(&pdev->dev, "Error creating IRQ domain\n");
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto err_unregister_interrupts;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < RP1_INT_END; i++) {
|
||||||
|
unsigned int irq = irq_create_mapping(rp1->domain, i);
|
||||||
|
|
||||||
|
if (!irq) {
|
||||||
|
dev_err(&pdev->dev, "Failed to create IRQ mapping\n");
|
||||||
|
err = -EINVAL;
|
||||||
|
goto err_unregister_interrupts;
|
||||||
|
}
|
||||||
|
|
||||||
|
irq_set_chip_and_handler(irq, &rp1_irq_chip, handle_level_irq);
|
||||||
|
irq_set_probe(irq);
|
||||||
|
irq_set_chained_handler_and_data(pci_irq_vector(pdev, i),
|
||||||
|
rp1_chained_handle_irq, rp1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!skip_ovl) {
|
||||||
|
err = of_overlay_fdt_apply(dtbo_start, dtbo_size, &rp1->ovcs_id,
|
||||||
|
rp1_node);
|
||||||
|
if (err)
|
||||||
|
goto err_unregister_interrupts;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = of_platform_default_populate(rp1_node, NULL, dev);
|
||||||
|
if (err) {
|
||||||
|
dev_err_probe(&pdev->dev, err, "Error populating devicetree\n");
|
||||||
|
goto err_unload_overlay;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err_unload_overlay:
|
||||||
|
of_overlay_remove(&rp1->ovcs_id);
|
||||||
|
err_unregister_interrupts:
|
||||||
|
rp1_unregister_interrupts(pdev);
|
||||||
|
err_put_node:
|
||||||
|
if (skip_ovl)
|
||||||
|
of_node_put(rp1_node);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rp1_remove(struct pci_dev *pdev)
|
||||||
|
{
|
||||||
|
struct rp1_dev *rp1 = pci_get_drvdata(pdev);
|
||||||
|
struct device *dev = &pdev->dev;
|
||||||
|
|
||||||
|
of_platform_depopulate(dev);
|
||||||
|
of_overlay_remove(&rp1->ovcs_id);
|
||||||
|
rp1_unregister_interrupts(pdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct pci_device_id dev_id_table[] = {
|
||||||
|
{ PCI_DEVICE(PCI_VENDOR_ID_RPI, PCI_DEVICE_ID_RPI_RP1_C0), },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(pci, dev_id_table);
|
||||||
|
|
||||||
|
static struct pci_driver rp1_driver = {
|
||||||
|
.name = KBUILD_MODNAME,
|
||||||
|
.id_table = dev_id_table,
|
||||||
|
.probe = rp1_probe,
|
||||||
|
.remove = rp1_remove,
|
||||||
|
};
|
||||||
|
|
||||||
|
module_pci_driver(rp1_driver);
|
||||||
|
|
||||||
|
MODULE_AUTHOR("Phil Elwell <phil@raspberrypi.com>");
|
||||||
|
MODULE_AUTHOR("Andrea della Porta <andrea.porta@suse.com>");
|
||||||
|
MODULE_DESCRIPTION("RaspberryPi RP1 misc device");
|
||||||
|
MODULE_LICENSE("GPL");
|
@ -6303,6 +6303,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_XILINX, 0x5020, of_pci_make_dev_node);
|
|||||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_XILINX, 0x5021, of_pci_make_dev_node);
|
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_XILINX, 0x5021, of_pci_make_dev_node);
|
||||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_REDHAT, 0x0005, of_pci_make_dev_node);
|
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_REDHAT, 0x0005, of_pci_make_dev_node);
|
||||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_EFAR, 0x9660, of_pci_make_dev_node);
|
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_EFAR, 0x9660, of_pci_make_dev_node);
|
||||||
|
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_RPI, PCI_DEVICE_ID_RPI_RP1_C0, of_pci_make_dev_node);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Devices known to require a longer delay before first config space access
|
* Devices known to require a longer delay before first config space access
|
||||||
|
@ -624,6 +624,17 @@ config PINCTRL_MLXBF3
|
|||||||
each pin. This driver can also be built as a module called
|
each pin. This driver can also be built as a module called
|
||||||
pinctrl-mlxbf3.
|
pinctrl-mlxbf3.
|
||||||
|
|
||||||
|
config PINCTRL_RP1
|
||||||
|
tristate "Pinctrl driver for RP1"
|
||||||
|
depends on MISC_RP1
|
||||||
|
default MISC_RP1
|
||||||
|
select PINMUX
|
||||||
|
select PINCONF
|
||||||
|
select GENERIC_PINCONF
|
||||||
|
help
|
||||||
|
Enable the gpio and pinctrl/mux driver for RaspberryPi RP1
|
||||||
|
multi function device.
|
||||||
|
|
||||||
source "drivers/pinctrl/actions/Kconfig"
|
source "drivers/pinctrl/actions/Kconfig"
|
||||||
source "drivers/pinctrl/aspeed/Kconfig"
|
source "drivers/pinctrl/aspeed/Kconfig"
|
||||||
source "drivers/pinctrl/bcm/Kconfig"
|
source "drivers/pinctrl/bcm/Kconfig"
|
||||||
|
@ -49,6 +49,7 @@ obj-$(CONFIG_PINCTRL_PIC32) += pinctrl-pic32.o
|
|||||||
obj-$(CONFIG_PINCTRL_PISTACHIO) += pinctrl-pistachio.o
|
obj-$(CONFIG_PINCTRL_PISTACHIO) += pinctrl-pistachio.o
|
||||||
obj-$(CONFIG_PINCTRL_RK805) += pinctrl-rk805.o
|
obj-$(CONFIG_PINCTRL_RK805) += pinctrl-rk805.o
|
||||||
obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o
|
obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o
|
||||||
|
obj-$(CONFIG_PINCTRL_RP1) += pinctrl-rp1.o
|
||||||
obj-$(CONFIG_PINCTRL_SCMI) += pinctrl-scmi.o
|
obj-$(CONFIG_PINCTRL_SCMI) += pinctrl-scmi.o
|
||||||
obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o
|
obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o
|
||||||
obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o
|
obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o
|
||||||
|
1831
drivers/pinctrl/pinctrl-rp1.c
Normal file
1831
drivers/pinctrl/pinctrl-rp1.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -51,8 +51,8 @@ config RESET_BERLIN
|
|||||||
|
|
||||||
config RESET_BRCMSTB
|
config RESET_BRCMSTB
|
||||||
tristate "Broadcom STB reset controller"
|
tristate "Broadcom STB reset controller"
|
||||||
depends on ARCH_BRCMSTB || COMPILE_TEST
|
depends on ARCH_BRCMSTB || ARCH_BCM2835 || COMPILE_TEST
|
||||||
default ARCH_BRCMSTB
|
default ARCH_BRCMSTB || ARCH_BCM2835
|
||||||
help
|
help
|
||||||
This enables the reset controller driver for Broadcom STB SoCs using
|
This enables the reset controller driver for Broadcom STB SoCs using
|
||||||
a SUN_TOP_CTRL_SW_INIT style controller.
|
a SUN_TOP_CTRL_SW_INIT style controller.
|
||||||
@ -60,11 +60,11 @@ config RESET_BRCMSTB
|
|||||||
config RESET_BRCMSTB_RESCAL
|
config RESET_BRCMSTB_RESCAL
|
||||||
tristate "Broadcom STB RESCAL reset controller"
|
tristate "Broadcom STB RESCAL reset controller"
|
||||||
depends on HAS_IOMEM
|
depends on HAS_IOMEM
|
||||||
depends on ARCH_BRCMSTB || COMPILE_TEST
|
depends on ARCH_BRCMSTB || ARCH_BCM2835 || COMPILE_TEST
|
||||||
default ARCH_BRCMSTB
|
default ARCH_BRCMSTB || ARCH_BCM2835
|
||||||
help
|
help
|
||||||
This enables the RESCAL reset controller for SATA, PCIe0, or PCIe1 on
|
This enables the RESCAL reset controller for SATA, PCIe0, or PCIe1 on
|
||||||
BCM7216.
|
BCM7216 or the BCM2712.
|
||||||
|
|
||||||
config RESET_EYEQ
|
config RESET_EYEQ
|
||||||
bool "Mobileye EyeQ reset controller"
|
bool "Mobileye EyeQ reset controller"
|
||||||
@ -140,6 +140,15 @@ config RESET_K210
|
|||||||
Say Y if you want to control reset signals provided by this
|
Say Y if you want to control reset signals provided by this
|
||||||
controller.
|
controller.
|
||||||
|
|
||||||
|
config RESET_K230
|
||||||
|
tristate "Reset controller driver for Canaan Kendryte K230 SoC"
|
||||||
|
depends on ARCH_CANAAN || COMPILE_TEST
|
||||||
|
depends on OF
|
||||||
|
help
|
||||||
|
Support for the Canaan Kendryte K230 RISC-V SoC reset controller.
|
||||||
|
Say Y if you want to control reset signals provided by this
|
||||||
|
controller.
|
||||||
|
|
||||||
config RESET_LANTIQ
|
config RESET_LANTIQ
|
||||||
bool "Lantiq XWAY Reset Driver" if COMPILE_TEST
|
bool "Lantiq XWAY Reset Driver" if COMPILE_TEST
|
||||||
default SOC_TYPE_XWAY
|
default SOC_TYPE_XWAY
|
||||||
@ -287,7 +296,7 @@ config RESET_SUNXI
|
|||||||
This enables the reset driver for Allwinner SoCs.
|
This enables the reset driver for Allwinner SoCs.
|
||||||
|
|
||||||
config RESET_TH1520
|
config RESET_TH1520
|
||||||
tristate "T-HEAD 1520 reset controller"
|
tristate "T-HEAD TH1520 reset controller"
|
||||||
depends on ARCH_THEAD || COMPILE_TEST
|
depends on ARCH_THEAD || COMPILE_TEST
|
||||||
select REGMAP_MMIO
|
select REGMAP_MMIO
|
||||||
help
|
help
|
||||||
|
@ -20,6 +20,7 @@ obj-$(CONFIG_RESET_IMX7) += reset-imx7.o
|
|||||||
obj-$(CONFIG_RESET_IMX8MP_AUDIOMIX) += reset-imx8mp-audiomix.o
|
obj-$(CONFIG_RESET_IMX8MP_AUDIOMIX) += reset-imx8mp-audiomix.o
|
||||||
obj-$(CONFIG_RESET_INTEL_GW) += reset-intel-gw.o
|
obj-$(CONFIG_RESET_INTEL_GW) += reset-intel-gw.o
|
||||||
obj-$(CONFIG_RESET_K210) += reset-k210.o
|
obj-$(CONFIG_RESET_K210) += reset-k210.o
|
||||||
|
obj-$(CONFIG_RESET_K230) += reset-k230.o
|
||||||
obj-$(CONFIG_RESET_LANTIQ) += reset-lantiq.o
|
obj-$(CONFIG_RESET_LANTIQ) += reset-lantiq.o
|
||||||
obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o
|
obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o
|
||||||
obj-$(CONFIG_RESET_MCHP_SPARX5) += reset-microchip-sparx5.o
|
obj-$(CONFIG_RESET_MCHP_SPARX5) += reset-microchip-sparx5.o
|
||||||
|
371
drivers/reset/reset-k230.c
Normal file
371
drivers/reset/reset-k230.c
Normal file
@ -0,0 +1,371 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2022-2024 Canaan Bright Sight Co., Ltd
|
||||||
|
* Copyright (C) 2024-2025 Junhui Liu <junhui.liu@pigmoral.tech>
|
||||||
|
*
|
||||||
|
* The reset management module in the K230 SoC provides reset time control
|
||||||
|
* registers. For RST_TYPE_CPU0, RST_TYPE_CPU1 and RST_TYPE_SW_DONE, the period
|
||||||
|
* during which reset is applied or removed while the clock is stopped can be
|
||||||
|
* set up to 15 * 0.25 = 3.75 µs. For RST_TYPE_HW_DONE, that period can be set
|
||||||
|
* up to 255 * 0.25 = 63.75 µs. For RST_TYPE_FLUSH, the reset bit is
|
||||||
|
* automatically cleared by hardware when flush completes.
|
||||||
|
*
|
||||||
|
* Although this driver does not configure the reset time registers, delays have
|
||||||
|
* been added to the assert, deassert, and reset operations to cover the maximum
|
||||||
|
* reset time. Some reset types include done bits whose toggle does not
|
||||||
|
* unambiguously signal whether hardware reset removal or clock-stop period
|
||||||
|
* expiration occurred first. Delays are therefore retained for types with done
|
||||||
|
* bits to ensure safe timing.
|
||||||
|
*
|
||||||
|
* Reference: K230 Technical Reference Manual V0.3.1
|
||||||
|
* https://kendryte-download.canaan-creative.com/developer/k230/HDK/K230%E7%A1%AC%E4%BB%B6%E6%96%87%E6%A1%A3/K230_Technical_Reference_Manual_V0.3.1_20241118.pdf
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/cleanup.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
#include <linux/iopoll.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/reset-controller.h>
|
||||||
|
#include <linux/spinlock.h>
|
||||||
|
|
||||||
|
#include <dt-bindings/reset/canaan,k230-rst.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum k230_rst_type - K230 reset types
|
||||||
|
* @RST_TYPE_CPU0: Reset type for CPU0
|
||||||
|
* Automatically clears, has write enable and done bit, active high
|
||||||
|
* @RST_TYPE_CPU1: Reset type for CPU1
|
||||||
|
* Manually clears, has write enable and done bit, active high
|
||||||
|
* @RST_TYPE_FLUSH: Reset type for CPU L2 cache flush
|
||||||
|
* Automatically clears, has write enable, no done bit, active high
|
||||||
|
* @RST_TYPE_HW_DONE: Reset type for hardware auto clear
|
||||||
|
* Automatically clears, no write enable, has done bit, active high
|
||||||
|
* @RST_TYPE_SW_DONE: Reset type for software manual clear
|
||||||
|
* Manually clears, no write enable and done bit,
|
||||||
|
* active high if ID is RST_SPI2AXI, otherwise active low
|
||||||
|
*/
|
||||||
|
enum k230_rst_type {
|
||||||
|
RST_TYPE_CPU0,
|
||||||
|
RST_TYPE_CPU1,
|
||||||
|
RST_TYPE_FLUSH,
|
||||||
|
RST_TYPE_HW_DONE,
|
||||||
|
RST_TYPE_SW_DONE,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct k230_rst_map {
|
||||||
|
u32 offset;
|
||||||
|
enum k230_rst_type type;
|
||||||
|
u32 done;
|
||||||
|
u32 reset;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct k230_rst {
|
||||||
|
struct reset_controller_dev rcdev;
|
||||||
|
void __iomem *base;
|
||||||
|
/* protect register read-modify-write */
|
||||||
|
spinlock_t lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct k230_rst_map k230_resets[] = {
|
||||||
|
[RST_CPU0] = { 0x4, RST_TYPE_CPU0, BIT(12), BIT(0) },
|
||||||
|
[RST_CPU1] = { 0xc, RST_TYPE_CPU1, BIT(12), BIT(0) },
|
||||||
|
[RST_CPU0_FLUSH] = { 0x4, RST_TYPE_FLUSH, 0, BIT(4) },
|
||||||
|
[RST_CPU1_FLUSH] = { 0xc, RST_TYPE_FLUSH, 0, BIT(4) },
|
||||||
|
[RST_AI] = { 0x14, RST_TYPE_HW_DONE, BIT(31), BIT(0) },
|
||||||
|
[RST_VPU] = { 0x1c, RST_TYPE_HW_DONE, BIT(31), BIT(0) },
|
||||||
|
[RST_HISYS] = { 0x2c, RST_TYPE_HW_DONE, BIT(4), BIT(0) },
|
||||||
|
[RST_HISYS_AHB] = { 0x2c, RST_TYPE_HW_DONE, BIT(5), BIT(1) },
|
||||||
|
[RST_SDIO0] = { 0x34, RST_TYPE_HW_DONE, BIT(28), BIT(0) },
|
||||||
|
[RST_SDIO1] = { 0x34, RST_TYPE_HW_DONE, BIT(29), BIT(1) },
|
||||||
|
[RST_SDIO_AXI] = { 0x34, RST_TYPE_HW_DONE, BIT(30), BIT(2) },
|
||||||
|
[RST_USB0] = { 0x3c, RST_TYPE_HW_DONE, BIT(28), BIT(0) },
|
||||||
|
[RST_USB1] = { 0x3c, RST_TYPE_HW_DONE, BIT(29), BIT(1) },
|
||||||
|
[RST_USB0_AHB] = { 0x3c, RST_TYPE_HW_DONE, BIT(30), BIT(0) },
|
||||||
|
[RST_USB1_AHB] = { 0x3c, RST_TYPE_HW_DONE, BIT(31), BIT(1) },
|
||||||
|
[RST_SPI0] = { 0x44, RST_TYPE_HW_DONE, BIT(28), BIT(0) },
|
||||||
|
[RST_SPI1] = { 0x44, RST_TYPE_HW_DONE, BIT(29), BIT(1) },
|
||||||
|
[RST_SPI2] = { 0x44, RST_TYPE_HW_DONE, BIT(30), BIT(2) },
|
||||||
|
[RST_SEC] = { 0x4c, RST_TYPE_HW_DONE, BIT(31), BIT(0) },
|
||||||
|
[RST_PDMA] = { 0x54, RST_TYPE_HW_DONE, BIT(28), BIT(0) },
|
||||||
|
[RST_SDMA] = { 0x54, RST_TYPE_HW_DONE, BIT(29), BIT(1) },
|
||||||
|
[RST_DECOMPRESS] = { 0x5c, RST_TYPE_HW_DONE, BIT(31), BIT(0) },
|
||||||
|
[RST_SRAM] = { 0x64, RST_TYPE_HW_DONE, BIT(28), BIT(0) },
|
||||||
|
[RST_SHRM_AXIM] = { 0x64, RST_TYPE_HW_DONE, BIT(30), BIT(2) },
|
||||||
|
[RST_SHRM_AXIS] = { 0x64, RST_TYPE_HW_DONE, BIT(31), BIT(3) },
|
||||||
|
[RST_NONAI2D] = { 0x6c, RST_TYPE_HW_DONE, BIT(31), BIT(0) },
|
||||||
|
[RST_MCTL] = { 0x74, RST_TYPE_HW_DONE, BIT(31), BIT(0) },
|
||||||
|
[RST_ISP] = { 0x80, RST_TYPE_HW_DONE, BIT(29), BIT(6) },
|
||||||
|
[RST_ISP_DW] = { 0x80, RST_TYPE_HW_DONE, BIT(28), BIT(5) },
|
||||||
|
[RST_DPU] = { 0x88, RST_TYPE_HW_DONE, BIT(31), BIT(0) },
|
||||||
|
[RST_DISP] = { 0x90, RST_TYPE_HW_DONE, BIT(31), BIT(0) },
|
||||||
|
[RST_GPU] = { 0x98, RST_TYPE_HW_DONE, BIT(31), BIT(0) },
|
||||||
|
[RST_AUDIO] = { 0xa4, RST_TYPE_HW_DONE, BIT(31), BIT(0) },
|
||||||
|
[RST_TIMER0] = { 0x20, RST_TYPE_SW_DONE, 0, BIT(0) },
|
||||||
|
[RST_TIMER1] = { 0x20, RST_TYPE_SW_DONE, 0, BIT(1) },
|
||||||
|
[RST_TIMER2] = { 0x20, RST_TYPE_SW_DONE, 0, BIT(2) },
|
||||||
|
[RST_TIMER3] = { 0x20, RST_TYPE_SW_DONE, 0, BIT(3) },
|
||||||
|
[RST_TIMER4] = { 0x20, RST_TYPE_SW_DONE, 0, BIT(4) },
|
||||||
|
[RST_TIMER5] = { 0x20, RST_TYPE_SW_DONE, 0, BIT(5) },
|
||||||
|
[RST_TIMER_APB] = { 0x20, RST_TYPE_SW_DONE, 0, BIT(6) },
|
||||||
|
[RST_HDI] = { 0x20, RST_TYPE_SW_DONE, 0, BIT(7) },
|
||||||
|
[RST_WDT0] = { 0x20, RST_TYPE_SW_DONE, 0, BIT(12) },
|
||||||
|
[RST_WDT1] = { 0x20, RST_TYPE_SW_DONE, 0, BIT(13) },
|
||||||
|
[RST_WDT0_APB] = { 0x20, RST_TYPE_SW_DONE, 0, BIT(14) },
|
||||||
|
[RST_WDT1_APB] = { 0x20, RST_TYPE_SW_DONE, 0, BIT(15) },
|
||||||
|
[RST_TS_APB] = { 0x20, RST_TYPE_SW_DONE, 0, BIT(16) },
|
||||||
|
[RST_MAILBOX] = { 0x20, RST_TYPE_SW_DONE, 0, BIT(17) },
|
||||||
|
[RST_STC] = { 0x20, RST_TYPE_SW_DONE, 0, BIT(18) },
|
||||||
|
[RST_PMU] = { 0x20, RST_TYPE_SW_DONE, 0, BIT(19) },
|
||||||
|
[RST_LOSYS_APB] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(0) },
|
||||||
|
[RST_UART0] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(1) },
|
||||||
|
[RST_UART1] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(2) },
|
||||||
|
[RST_UART2] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(3) },
|
||||||
|
[RST_UART3] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(4) },
|
||||||
|
[RST_UART4] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(5) },
|
||||||
|
[RST_I2C0] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(6) },
|
||||||
|
[RST_I2C1] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(7) },
|
||||||
|
[RST_I2C2] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(8) },
|
||||||
|
[RST_I2C3] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(9) },
|
||||||
|
[RST_I2C4] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(10) },
|
||||||
|
[RST_JAMLINK0_APB] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(11) },
|
||||||
|
[RST_JAMLINK1_APB] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(12) },
|
||||||
|
[RST_JAMLINK2_APB] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(13) },
|
||||||
|
[RST_JAMLINK3_APB] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(14) },
|
||||||
|
[RST_CODEC_APB] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(17) },
|
||||||
|
[RST_GPIO_DB] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(18) },
|
||||||
|
[RST_GPIO_APB] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(19) },
|
||||||
|
[RST_ADC] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(20) },
|
||||||
|
[RST_ADC_APB] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(21) },
|
||||||
|
[RST_PWM_APB] = { 0x24, RST_TYPE_SW_DONE, 0, BIT(22) },
|
||||||
|
[RST_SHRM_APB] = { 0x64, RST_TYPE_SW_DONE, 0, BIT(1) },
|
||||||
|
[RST_CSI0] = { 0x80, RST_TYPE_SW_DONE, 0, BIT(0) },
|
||||||
|
[RST_CSI1] = { 0x80, RST_TYPE_SW_DONE, 0, BIT(1) },
|
||||||
|
[RST_CSI2] = { 0x80, RST_TYPE_SW_DONE, 0, BIT(2) },
|
||||||
|
[RST_CSI_DPHY] = { 0x80, RST_TYPE_SW_DONE, 0, BIT(3) },
|
||||||
|
[RST_ISP_AHB] = { 0x80, RST_TYPE_SW_DONE, 0, BIT(4) },
|
||||||
|
[RST_M0] = { 0x80, RST_TYPE_SW_DONE, 0, BIT(7) },
|
||||||
|
[RST_M1] = { 0x80, RST_TYPE_SW_DONE, 0, BIT(8) },
|
||||||
|
[RST_M2] = { 0x80, RST_TYPE_SW_DONE, 0, BIT(9) },
|
||||||
|
[RST_SPI2AXI] = { 0xa8, RST_TYPE_SW_DONE, 0, BIT(0) }
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline struct k230_rst *to_k230_rst(struct reset_controller_dev *rcdev)
|
||||||
|
{
|
||||||
|
return container_of(rcdev, struct k230_rst, rcdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void k230_rst_clear_done(struct k230_rst *rstc, unsigned long id,
|
||||||
|
bool write_en)
|
||||||
|
{
|
||||||
|
const struct k230_rst_map *rmap = &k230_resets[id];
|
||||||
|
u32 reg;
|
||||||
|
|
||||||
|
guard(spinlock_irqsave)(&rstc->lock);
|
||||||
|
|
||||||
|
reg = readl(rstc->base + rmap->offset);
|
||||||
|
reg |= rmap->done; /* write 1 to clear */
|
||||||
|
if (write_en)
|
||||||
|
reg |= rmap->done << 16;
|
||||||
|
writel(reg, rstc->base + rmap->offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int k230_rst_wait_and_clear_done(struct k230_rst *rstc, unsigned long id,
|
||||||
|
bool write_en)
|
||||||
|
{
|
||||||
|
const struct k230_rst_map *rmap = &k230_resets[id];
|
||||||
|
u32 reg;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = readl_poll_timeout(rstc->base + rmap->offset, reg,
|
||||||
|
reg & rmap->done, 10, 1000);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(rstc->rcdev.dev, "Wait for reset done timeout\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
k230_rst_clear_done(rstc, id, write_en);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void k230_rst_update(struct k230_rst *rstc, unsigned long id,
|
||||||
|
bool assert, bool write_en, bool active_low)
|
||||||
|
{
|
||||||
|
const struct k230_rst_map *rmap = &k230_resets[id];
|
||||||
|
u32 reg;
|
||||||
|
|
||||||
|
guard(spinlock_irqsave)(&rstc->lock);
|
||||||
|
|
||||||
|
reg = readl(rstc->base + rmap->offset);
|
||||||
|
if (assert ^ active_low)
|
||||||
|
reg |= rmap->reset;
|
||||||
|
else
|
||||||
|
reg &= ~rmap->reset;
|
||||||
|
if (write_en)
|
||||||
|
reg |= rmap->reset << 16;
|
||||||
|
writel(reg, rstc->base + rmap->offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int k230_rst_assert(struct reset_controller_dev *rcdev, unsigned long id)
|
||||||
|
{
|
||||||
|
struct k230_rst *rstc = to_k230_rst(rcdev);
|
||||||
|
|
||||||
|
switch (k230_resets[id].type) {
|
||||||
|
case RST_TYPE_CPU1:
|
||||||
|
k230_rst_update(rstc, id, true, true, false);
|
||||||
|
break;
|
||||||
|
case RST_TYPE_SW_DONE:
|
||||||
|
k230_rst_update(rstc, id, true, false,
|
||||||
|
id == RST_SPI2AXI ? false : true);
|
||||||
|
break;
|
||||||
|
case RST_TYPE_CPU0:
|
||||||
|
case RST_TYPE_FLUSH:
|
||||||
|
case RST_TYPE_HW_DONE:
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The time period when reset is applied but the clock is stopped for
|
||||||
|
* RST_TYPE_CPU1 and RST_TYPE_SW_DONE can be set up to 3.75us. Delay
|
||||||
|
* 10us to ensure proper reset timing.
|
||||||
|
*/
|
||||||
|
udelay(10);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int k230_rst_deassert(struct reset_controller_dev *rcdev,
|
||||||
|
unsigned long id)
|
||||||
|
{
|
||||||
|
struct k230_rst *rstc = to_k230_rst(rcdev);
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
switch (k230_resets[id].type) {
|
||||||
|
case RST_TYPE_CPU1:
|
||||||
|
k230_rst_update(rstc, id, false, true, false);
|
||||||
|
ret = k230_rst_wait_and_clear_done(rstc, id, true);
|
||||||
|
break;
|
||||||
|
case RST_TYPE_SW_DONE:
|
||||||
|
k230_rst_update(rstc, id, false, false,
|
||||||
|
id == RST_SPI2AXI ? false : true);
|
||||||
|
break;
|
||||||
|
case RST_TYPE_CPU0:
|
||||||
|
case RST_TYPE_FLUSH:
|
||||||
|
case RST_TYPE_HW_DONE:
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The time period when reset is removed but the clock is stopped for
|
||||||
|
* RST_TYPE_CPU1 and RST_TYPE_SW_DONE can be set up to 3.75us. Delay
|
||||||
|
* 10us to ensure proper reset timing.
|
||||||
|
*/
|
||||||
|
udelay(10);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int k230_rst_reset(struct reset_controller_dev *rcdev, unsigned long id)
|
||||||
|
{
|
||||||
|
struct k230_rst *rstc = to_k230_rst(rcdev);
|
||||||
|
const struct k230_rst_map *rmap = &k230_resets[id];
|
||||||
|
u32 reg;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
switch (rmap->type) {
|
||||||
|
case RST_TYPE_CPU0:
|
||||||
|
k230_rst_clear_done(rstc, id, true);
|
||||||
|
k230_rst_update(rstc, id, true, true, false);
|
||||||
|
ret = k230_rst_wait_and_clear_done(rstc, id, true);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The time period when reset is applied and removed but the
|
||||||
|
* clock is stopped for RST_TYPE_CPU0 can be set up to 7.5us.
|
||||||
|
* Delay 10us to ensure proper reset timing.
|
||||||
|
*/
|
||||||
|
udelay(10);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case RST_TYPE_FLUSH:
|
||||||
|
k230_rst_update(rstc, id, true, true, false);
|
||||||
|
|
||||||
|
/* Wait flush request bit auto cleared by hardware */
|
||||||
|
ret = readl_poll_timeout(rstc->base + rmap->offset, reg,
|
||||||
|
!(reg & rmap->reset), 10, 1000);
|
||||||
|
if (ret)
|
||||||
|
dev_err(rcdev->dev, "Wait for flush done timeout\n");
|
||||||
|
|
||||||
|
break;
|
||||||
|
case RST_TYPE_HW_DONE:
|
||||||
|
k230_rst_clear_done(rstc, id, false);
|
||||||
|
k230_rst_update(rstc, id, true, false, false);
|
||||||
|
ret = k230_rst_wait_and_clear_done(rstc, id, false);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The time period when reset is applied and removed but the
|
||||||
|
* clock is stopped for RST_TYPE_HW_DONE can be set up to
|
||||||
|
* 127.5us. Delay 200us to ensure proper reset timing.
|
||||||
|
*/
|
||||||
|
fsleep(200);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case RST_TYPE_CPU1:
|
||||||
|
case RST_TYPE_SW_DONE:
|
||||||
|
k230_rst_assert(rcdev, id);
|
||||||
|
ret = k230_rst_deassert(rcdev, id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct reset_control_ops k230_rst_ops = {
|
||||||
|
.reset = k230_rst_reset,
|
||||||
|
.assert = k230_rst_assert,
|
||||||
|
.deassert = k230_rst_deassert,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int k230_rst_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct device *dev = &pdev->dev;
|
||||||
|
struct k230_rst *rstc;
|
||||||
|
|
||||||
|
rstc = devm_kzalloc(dev, sizeof(*rstc), GFP_KERNEL);
|
||||||
|
if (!rstc)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
rstc->base = devm_platform_ioremap_resource(pdev, 0);
|
||||||
|
if (IS_ERR(rstc->base))
|
||||||
|
return PTR_ERR(rstc->base);
|
||||||
|
|
||||||
|
spin_lock_init(&rstc->lock);
|
||||||
|
|
||||||
|
rstc->rcdev.dev = dev;
|
||||||
|
rstc->rcdev.owner = THIS_MODULE;
|
||||||
|
rstc->rcdev.ops = &k230_rst_ops;
|
||||||
|
rstc->rcdev.nr_resets = ARRAY_SIZE(k230_resets);
|
||||||
|
rstc->rcdev.of_node = dev->of_node;
|
||||||
|
|
||||||
|
return devm_reset_controller_register(dev, &rstc->rcdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct of_device_id k230_rst_match[] = {
|
||||||
|
{ .compatible = "canaan,k230-rst", },
|
||||||
|
{ /* sentinel */ }
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, k230_rst_match);
|
||||||
|
|
||||||
|
static struct platform_driver k230_rst_driver = {
|
||||||
|
.probe = k230_rst_probe,
|
||||||
|
.driver = {
|
||||||
|
.name = "k230-rst",
|
||||||
|
.of_match_table = k230_rst_match,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
module_platform_driver(k230_rst_driver);
|
||||||
|
|
||||||
|
MODULE_AUTHOR("Junhui Liu <junhui.liu@pigmoral.tech>");
|
||||||
|
MODULE_DESCRIPTION("Canaan K230 reset driver");
|
||||||
|
MODULE_LICENSE("GPL");
|
@ -155,62 +155,16 @@ static int mpfs_reset_probe(struct auxiliary_device *adev,
|
|||||||
return devm_reset_controller_register(dev, rcdev);
|
return devm_reset_controller_register(dev, rcdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mpfs_reset_unregister_adev(void *_adev)
|
|
||||||
{
|
|
||||||
struct auxiliary_device *adev = _adev;
|
|
||||||
|
|
||||||
auxiliary_device_delete(adev);
|
|
||||||
auxiliary_device_uninit(adev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mpfs_reset_adev_release(struct device *dev)
|
|
||||||
{
|
|
||||||
struct auxiliary_device *adev = to_auxiliary_dev(dev);
|
|
||||||
|
|
||||||
kfree(adev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct auxiliary_device *mpfs_reset_adev_alloc(struct device *clk_dev)
|
|
||||||
{
|
|
||||||
struct auxiliary_device *adev;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
adev = kzalloc(sizeof(*adev), GFP_KERNEL);
|
|
||||||
if (!adev)
|
|
||||||
return ERR_PTR(-ENOMEM);
|
|
||||||
|
|
||||||
adev->name = "reset-mpfs";
|
|
||||||
adev->dev.parent = clk_dev;
|
|
||||||
adev->dev.release = mpfs_reset_adev_release;
|
|
||||||
adev->id = 666u;
|
|
||||||
|
|
||||||
ret = auxiliary_device_init(adev);
|
|
||||||
if (ret) {
|
|
||||||
kfree(adev);
|
|
||||||
return ERR_PTR(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
return adev;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mpfs_reset_controller_register(struct device *clk_dev, void __iomem *base)
|
int mpfs_reset_controller_register(struct device *clk_dev, void __iomem *base)
|
||||||
{
|
{
|
||||||
struct auxiliary_device *adev;
|
struct auxiliary_device *adev;
|
||||||
int ret;
|
|
||||||
|
|
||||||
adev = mpfs_reset_adev_alloc(clk_dev);
|
adev = devm_auxiliary_device_create(clk_dev, "reset-mpfs",
|
||||||
if (IS_ERR(adev))
|
(__force void *)base);
|
||||||
return PTR_ERR(adev);
|
if (!adev)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
ret = auxiliary_device_add(adev);
|
return 0;
|
||||||
if (ret) {
|
|
||||||
auxiliary_device_uninit(adev);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
adev->dev.platform_data = (__force void *)base;
|
|
||||||
|
|
||||||
return devm_add_action_or_reset(clk_dev, mpfs_reset_unregister_adev, adev);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_NS_GPL(mpfs_reset_controller_register, "MCHP_CLK_MPFS");
|
EXPORT_SYMBOL_NS_GPL(mpfs_reset_controller_register, "MCHP_CLK_MPFS");
|
||||||
|
|
||||||
|
@ -151,6 +151,8 @@ static const struct of_device_id reset_simple_dt_ids[] = {
|
|||||||
{ .compatible = "snps,dw-high-reset" },
|
{ .compatible = "snps,dw-high-reset" },
|
||||||
{ .compatible = "snps,dw-low-reset",
|
{ .compatible = "snps,dw-low-reset",
|
||||||
.data = &reset_simple_active_low },
|
.data = &reset_simple_active_low },
|
||||||
|
{ .compatible = "sophgo,cv1800b-reset",
|
||||||
|
.data = &reset_simple_active_low },
|
||||||
{ .compatible = "sophgo,sg2042-reset",
|
{ .compatible = "sophgo,sg2042-reset",
|
||||||
.data = &reset_simple_active_low },
|
.data = &reset_simple_active_low },
|
||||||
{ /* sentinel */ },
|
{ /* sentinel */ },
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include <linux/bitops.h>
|
#include <linux/bitops.h>
|
||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
|
#include <linux/dev_printk.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/kfifo.h>
|
#include <linux/kfifo.h>
|
||||||
@ -25,7 +26,6 @@
|
|||||||
|
|
||||||
#define DEVICE_NAME "aspeed-lpc-snoop"
|
#define DEVICE_NAME "aspeed-lpc-snoop"
|
||||||
|
|
||||||
#define NUM_SNOOP_CHANNELS 2
|
|
||||||
#define SNOOP_FIFO_SIZE 2048
|
#define SNOOP_FIFO_SIZE 2048
|
||||||
|
|
||||||
#define HICR5 0x80
|
#define HICR5 0x80
|
||||||
@ -57,7 +57,22 @@ struct aspeed_lpc_snoop_model_data {
|
|||||||
unsigned int has_hicrb_ensnp;
|
unsigned int has_hicrb_ensnp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum aspeed_lpc_snoop_index {
|
||||||
|
ASPEED_LPC_SNOOP_INDEX_0 = 0,
|
||||||
|
ASPEED_LPC_SNOOP_INDEX_1 = 1,
|
||||||
|
ASPEED_LPC_SNOOP_INDEX_MAX = ASPEED_LPC_SNOOP_INDEX_1,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct aspeed_lpc_snoop_channel_cfg {
|
||||||
|
enum aspeed_lpc_snoop_index index;
|
||||||
|
u32 hicr5_en;
|
||||||
|
u32 snpwadr_mask;
|
||||||
|
u32 snpwadr_shift;
|
||||||
|
u32 hicrb_en;
|
||||||
|
};
|
||||||
|
|
||||||
struct aspeed_lpc_snoop_channel {
|
struct aspeed_lpc_snoop_channel {
|
||||||
|
const struct aspeed_lpc_snoop_channel_cfg *cfg;
|
||||||
bool enabled;
|
bool enabled;
|
||||||
struct kfifo fifo;
|
struct kfifo fifo;
|
||||||
wait_queue_head_t wq;
|
wait_queue_head_t wq;
|
||||||
@ -68,7 +83,24 @@ struct aspeed_lpc_snoop {
|
|||||||
struct regmap *regmap;
|
struct regmap *regmap;
|
||||||
int irq;
|
int irq;
|
||||||
struct clk *clk;
|
struct clk *clk;
|
||||||
struct aspeed_lpc_snoop_channel chan[NUM_SNOOP_CHANNELS];
|
struct aspeed_lpc_snoop_channel chan[ASPEED_LPC_SNOOP_INDEX_MAX + 1];
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct aspeed_lpc_snoop_channel_cfg channel_cfgs[ASPEED_LPC_SNOOP_INDEX_MAX + 1] = {
|
||||||
|
{
|
||||||
|
.index = ASPEED_LPC_SNOOP_INDEX_0,
|
||||||
|
.hicr5_en = HICR5_EN_SNP0W | HICR5_ENINT_SNP0W,
|
||||||
|
.snpwadr_mask = SNPWADR_CH0_MASK,
|
||||||
|
.snpwadr_shift = SNPWADR_CH0_SHIFT,
|
||||||
|
.hicrb_en = HICRB_ENSNP0D,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.index = ASPEED_LPC_SNOOP_INDEX_1,
|
||||||
|
.hicr5_en = HICR5_EN_SNP1W | HICR5_ENINT_SNP1W,
|
||||||
|
.snpwadr_mask = SNPWADR_CH1_MASK,
|
||||||
|
.snpwadr_shift = SNPWADR_CH1_SHIFT,
|
||||||
|
.hicrb_en = HICRB_ENSNP1D,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct aspeed_lpc_snoop_channel *snoop_file_to_chan(struct file *file)
|
static struct aspeed_lpc_snoop_channel *snoop_file_to_chan(struct file *file)
|
||||||
@ -182,108 +214,88 @@ static int aspeed_lpc_snoop_config_irq(struct aspeed_lpc_snoop *lpc_snoop,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int aspeed_lpc_enable_snoop(struct aspeed_lpc_snoop *lpc_snoop,
|
__attribute__((nonnull))
|
||||||
struct device *dev,
|
static int aspeed_lpc_enable_snoop(struct device *dev,
|
||||||
int channel, u16 lpc_port)
|
struct aspeed_lpc_snoop *lpc_snoop,
|
||||||
|
struct aspeed_lpc_snoop_channel *channel,
|
||||||
|
const struct aspeed_lpc_snoop_channel_cfg *cfg,
|
||||||
|
u16 lpc_port)
|
||||||
{
|
{
|
||||||
|
const struct aspeed_lpc_snoop_model_data *model_data;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
u32 hicr5_en, snpwadr_mask, snpwadr_shift, hicrb_en;
|
|
||||||
const struct aspeed_lpc_snoop_model_data *model_data =
|
|
||||||
of_device_get_match_data(dev);
|
|
||||||
|
|
||||||
if (WARN_ON(lpc_snoop->chan[channel].enabled))
|
if (WARN_ON(channel->enabled))
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
init_waitqueue_head(&lpc_snoop->chan[channel].wq);
|
init_waitqueue_head(&channel->wq);
|
||||||
/* Create FIFO datastructure */
|
|
||||||
rc = kfifo_alloc(&lpc_snoop->chan[channel].fifo,
|
channel->cfg = cfg;
|
||||||
SNOOP_FIFO_SIZE, GFP_KERNEL);
|
channel->miscdev.minor = MISC_DYNAMIC_MINOR;
|
||||||
|
channel->miscdev.fops = &snoop_fops;
|
||||||
|
channel->miscdev.parent = dev;
|
||||||
|
|
||||||
|
channel->miscdev.name =
|
||||||
|
devm_kasprintf(dev, GFP_KERNEL, "%s%d", DEVICE_NAME, cfg->index);
|
||||||
|
if (!channel->miscdev.name)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
rc = kfifo_alloc(&channel->fifo, SNOOP_FIFO_SIZE, GFP_KERNEL);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
lpc_snoop->chan[channel].miscdev.minor = MISC_DYNAMIC_MINOR;
|
rc = misc_register(&channel->miscdev);
|
||||||
lpc_snoop->chan[channel].miscdev.name =
|
|
||||||
devm_kasprintf(dev, GFP_KERNEL, "%s%d", DEVICE_NAME, channel);
|
|
||||||
if (!lpc_snoop->chan[channel].miscdev.name) {
|
|
||||||
rc = -ENOMEM;
|
|
||||||
goto err_free_fifo;
|
|
||||||
}
|
|
||||||
lpc_snoop->chan[channel].miscdev.fops = &snoop_fops;
|
|
||||||
lpc_snoop->chan[channel].miscdev.parent = dev;
|
|
||||||
rc = misc_register(&lpc_snoop->chan[channel].miscdev);
|
|
||||||
if (rc)
|
if (rc)
|
||||||
goto err_free_fifo;
|
goto err_free_fifo;
|
||||||
|
|
||||||
/* Enable LPC snoop channel at requested port */
|
/* Enable LPC snoop channel at requested port */
|
||||||
switch (channel) {
|
regmap_set_bits(lpc_snoop->regmap, HICR5, cfg->hicr5_en);
|
||||||
case 0:
|
regmap_update_bits(lpc_snoop->regmap, SNPWADR, cfg->snpwadr_mask,
|
||||||
hicr5_en = HICR5_EN_SNP0W | HICR5_ENINT_SNP0W;
|
lpc_port << cfg->snpwadr_shift);
|
||||||
snpwadr_mask = SNPWADR_CH0_MASK;
|
|
||||||
snpwadr_shift = SNPWADR_CH0_SHIFT;
|
|
||||||
hicrb_en = HICRB_ENSNP0D;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
hicr5_en = HICR5_EN_SNP1W | HICR5_ENINT_SNP1W;
|
|
||||||
snpwadr_mask = SNPWADR_CH1_MASK;
|
|
||||||
snpwadr_shift = SNPWADR_CH1_SHIFT;
|
|
||||||
hicrb_en = HICRB_ENSNP1D;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
rc = -EINVAL;
|
|
||||||
goto err_misc_deregister;
|
|
||||||
}
|
|
||||||
|
|
||||||
regmap_update_bits(lpc_snoop->regmap, HICR5, hicr5_en, hicr5_en);
|
model_data = of_device_get_match_data(dev);
|
||||||
regmap_update_bits(lpc_snoop->regmap, SNPWADR, snpwadr_mask,
|
if (model_data && model_data->has_hicrb_ensnp)
|
||||||
lpc_port << snpwadr_shift);
|
regmap_set_bits(lpc_snoop->regmap, HICRB, cfg->hicrb_en);
|
||||||
if (model_data->has_hicrb_ensnp)
|
|
||||||
regmap_update_bits(lpc_snoop->regmap, HICRB,
|
|
||||||
hicrb_en, hicrb_en);
|
|
||||||
|
|
||||||
lpc_snoop->chan[channel].enabled = true;
|
channel->enabled = true;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_misc_deregister:
|
|
||||||
misc_deregister(&lpc_snoop->chan[channel].miscdev);
|
|
||||||
err_free_fifo:
|
err_free_fifo:
|
||||||
kfifo_free(&lpc_snoop->chan[channel].fifo);
|
kfifo_free(&channel->fifo);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__attribute__((nonnull))
|
||||||
static void aspeed_lpc_disable_snoop(struct aspeed_lpc_snoop *lpc_snoop,
|
static void aspeed_lpc_disable_snoop(struct aspeed_lpc_snoop *lpc_snoop,
|
||||||
int channel)
|
struct aspeed_lpc_snoop_channel *channel)
|
||||||
{
|
{
|
||||||
if (!lpc_snoop->chan[channel].enabled)
|
if (!channel->enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (channel) {
|
/* Disable interrupts along with the device */
|
||||||
case 0:
|
regmap_clear_bits(lpc_snoop->regmap, HICR5, channel->cfg->hicr5_en);
|
||||||
regmap_update_bits(lpc_snoop->regmap, HICR5,
|
|
||||||
HICR5_EN_SNP0W | HICR5_ENINT_SNP0W,
|
|
||||||
0);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
regmap_update_bits(lpc_snoop->regmap, HICR5,
|
|
||||||
HICR5_EN_SNP1W | HICR5_ENINT_SNP1W,
|
|
||||||
0);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
lpc_snoop->chan[channel].enabled = false;
|
channel->enabled = false;
|
||||||
/* Consider improving safety wrt concurrent reader(s) */
|
/* Consider improving safety wrt concurrent reader(s) */
|
||||||
misc_deregister(&lpc_snoop->chan[channel].miscdev);
|
misc_deregister(&channel->miscdev);
|
||||||
kfifo_free(&lpc_snoop->chan[channel].fifo);
|
kfifo_free(&channel->fifo);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void aspeed_lpc_snoop_remove(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct aspeed_lpc_snoop *lpc_snoop = dev_get_drvdata(&pdev->dev);
|
||||||
|
|
||||||
|
/* Disable both snoop channels */
|
||||||
|
aspeed_lpc_disable_snoop(lpc_snoop, &lpc_snoop->chan[0]);
|
||||||
|
aspeed_lpc_disable_snoop(lpc_snoop, &lpc_snoop->chan[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int aspeed_lpc_snoop_probe(struct platform_device *pdev)
|
static int aspeed_lpc_snoop_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct aspeed_lpc_snoop *lpc_snoop;
|
struct aspeed_lpc_snoop *lpc_snoop;
|
||||||
struct device *dev;
|
|
||||||
struct device_node *np;
|
struct device_node *np;
|
||||||
u32 port;
|
struct device *dev;
|
||||||
|
int idx;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
dev = &pdev->dev;
|
dev = &pdev->dev;
|
||||||
@ -301,69 +313,42 @@ static int aspeed_lpc_snoop_probe(struct platform_device *pdev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
lpc_snoop->regmap = syscon_node_to_regmap(np);
|
lpc_snoop->regmap = syscon_node_to_regmap(np);
|
||||||
if (IS_ERR(lpc_snoop->regmap)) {
|
if (IS_ERR(lpc_snoop->regmap))
|
||||||
dev_err(dev, "Couldn't get regmap\n");
|
return dev_err_probe(dev, PTR_ERR(lpc_snoop->regmap), "Couldn't get regmap\n");
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
dev_set_drvdata(&pdev->dev, lpc_snoop);
|
dev_set_drvdata(&pdev->dev, lpc_snoop);
|
||||||
|
|
||||||
rc = of_property_read_u32_index(dev->of_node, "snoop-ports", 0, &port);
|
lpc_snoop->clk = devm_clk_get_enabled(dev, NULL);
|
||||||
if (rc) {
|
if (IS_ERR(lpc_snoop->clk))
|
||||||
dev_err(dev, "no snoop ports configured\n");
|
return dev_err_probe(dev, PTR_ERR(lpc_snoop->clk), "couldn't get clock");
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
lpc_snoop->clk = devm_clk_get(dev, NULL);
|
|
||||||
if (IS_ERR(lpc_snoop->clk)) {
|
|
||||||
rc = PTR_ERR(lpc_snoop->clk);
|
|
||||||
if (rc != -EPROBE_DEFER)
|
|
||||||
dev_err(dev, "couldn't get clock\n");
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
rc = clk_prepare_enable(lpc_snoop->clk);
|
|
||||||
if (rc) {
|
|
||||||
dev_err(dev, "couldn't enable clock\n");
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = aspeed_lpc_snoop_config_irq(lpc_snoop, pdev);
|
rc = aspeed_lpc_snoop_config_irq(lpc_snoop, pdev);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto err;
|
return rc;
|
||||||
|
|
||||||
rc = aspeed_lpc_enable_snoop(lpc_snoop, dev, 0, port);
|
static_assert(ARRAY_SIZE(channel_cfgs) == ARRAY_SIZE(lpc_snoop->chan),
|
||||||
if (rc)
|
"Broken implementation assumption regarding cfg count");
|
||||||
goto err;
|
for (idx = ASPEED_LPC_SNOOP_INDEX_0; idx <= ASPEED_LPC_SNOOP_INDEX_MAX; idx++) {
|
||||||
|
u32 port;
|
||||||
|
|
||||||
/* Configuration of 2nd snoop channel port is optional */
|
rc = of_property_read_u32_index(dev->of_node, "snoop-ports", idx, &port);
|
||||||
if (of_property_read_u32_index(dev->of_node, "snoop-ports",
|
if (rc)
|
||||||
1, &port) == 0) {
|
break;
|
||||||
rc = aspeed_lpc_enable_snoop(lpc_snoop, dev, 1, port);
|
|
||||||
if (rc) {
|
rc = aspeed_lpc_enable_snoop(dev, lpc_snoop, &lpc_snoop->chan[idx],
|
||||||
aspeed_lpc_disable_snoop(lpc_snoop, 0);
|
&channel_cfgs[idx], port);
|
||||||
goto err;
|
if (rc)
|
||||||
}
|
goto cleanup_channels;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return idx == ASPEED_LPC_SNOOP_INDEX_0 ? -ENODEV : 0;
|
||||||
|
|
||||||
err:
|
cleanup_channels:
|
||||||
clk_disable_unprepare(lpc_snoop->clk);
|
aspeed_lpc_snoop_remove(pdev);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void aspeed_lpc_snoop_remove(struct platform_device *pdev)
|
|
||||||
{
|
|
||||||
struct aspeed_lpc_snoop *lpc_snoop = dev_get_drvdata(&pdev->dev);
|
|
||||||
|
|
||||||
/* Disable both snoop channels */
|
|
||||||
aspeed_lpc_disable_snoop(lpc_snoop, 0);
|
|
||||||
aspeed_lpc_disable_snoop(lpc_snoop, 1);
|
|
||||||
|
|
||||||
clk_disable_unprepare(lpc_snoop->clk);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct aspeed_lpc_snoop_model_data ast2400_model_data = {
|
static const struct aspeed_lpc_snoop_model_data ast2400_model_data = {
|
||||||
.has_hicrb_ensnp = 0,
|
.has_hicrb_ensnp = 0,
|
||||||
};
|
};
|
||||||
|
@ -57,7 +57,7 @@ static int qe_gpio_get(struct gpio_chip *gc, unsigned int gpio)
|
|||||||
return !!(ioread32be(®s->cpdata) & pin_mask);
|
return !!(ioread32be(®s->cpdata) & pin_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qe_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
|
static int qe_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
|
||||||
{
|
{
|
||||||
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
|
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
|
||||||
struct qe_gpio_chip *qe_gc = gpiochip_get_data(gc);
|
struct qe_gpio_chip *qe_gc = gpiochip_get_data(gc);
|
||||||
@ -75,10 +75,12 @@ static void qe_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
|
|||||||
iowrite32be(qe_gc->cpdata, ®s->cpdata);
|
iowrite32be(qe_gc->cpdata, ®s->cpdata);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&qe_gc->lock, flags);
|
spin_unlock_irqrestore(&qe_gc->lock, flags);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qe_gpio_set_multiple(struct gpio_chip *gc,
|
static int qe_gpio_set_multiple(struct gpio_chip *gc,
|
||||||
unsigned long *mask, unsigned long *bits)
|
unsigned long *mask, unsigned long *bits)
|
||||||
{
|
{
|
||||||
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
|
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
|
||||||
struct qe_gpio_chip *qe_gc = gpiochip_get_data(gc);
|
struct qe_gpio_chip *qe_gc = gpiochip_get_data(gc);
|
||||||
@ -102,6 +104,8 @@ static void qe_gpio_set_multiple(struct gpio_chip *gc,
|
|||||||
iowrite32be(qe_gc->cpdata, ®s->cpdata);
|
iowrite32be(qe_gc->cpdata, ®s->cpdata);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&qe_gc->lock, flags);
|
spin_unlock_irqrestore(&qe_gc->lock, flags);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qe_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
|
static int qe_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
|
||||||
@ -317,8 +321,8 @@ static int __init qe_add_gpiochips(void)
|
|||||||
gc->direction_input = qe_gpio_dir_in;
|
gc->direction_input = qe_gpio_dir_in;
|
||||||
gc->direction_output = qe_gpio_dir_out;
|
gc->direction_output = qe_gpio_dir_out;
|
||||||
gc->get = qe_gpio_get;
|
gc->get = qe_gpio_get;
|
||||||
gc->set = qe_gpio_set;
|
gc->set_rv = qe_gpio_set;
|
||||||
gc->set_multiple = qe_gpio_set_multiple;
|
gc->set_multiple_rv = qe_gpio_set_multiple;
|
||||||
|
|
||||||
ret = of_mm_gpiochip_add_data(np, mm_gc, qe_gc);
|
ret = of_mm_gpiochip_add_data(np, mm_gc, qe_gc);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -407,7 +407,6 @@ static int qe_ic_init(struct platform_device *pdev)
|
|||||||
void (*high_handler)(struct irq_desc *desc);
|
void (*high_handler)(struct irq_desc *desc);
|
||||||
struct qe_ic *qe_ic;
|
struct qe_ic *qe_ic;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
struct device_node *node = pdev->dev.of_node;
|
|
||||||
|
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
if (res == NULL) {
|
if (res == NULL) {
|
||||||
@ -441,7 +440,7 @@ static int qe_ic_init(struct platform_device *pdev)
|
|||||||
high_handler = NULL;
|
high_handler = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
qe_ic->irqhost = irq_domain_create_linear(of_fwnode_handle(node), NR_QE_IC_INTS,
|
qe_ic->irqhost = irq_domain_create_linear(dev_fwnode(&pdev->dev), NR_QE_IC_INTS,
|
||||||
&qe_ic_host_ops, qe_ic);
|
&qe_ic_host_ops, qe_ic);
|
||||||
if (qe_ic->irqhost == NULL) {
|
if (qe_ic->irqhost == NULL) {
|
||||||
dev_err(dev, "failed to add irq domain\n");
|
dev_err(dev, "failed to add irq domain\n");
|
||||||
|
@ -1295,11 +1295,11 @@ static int hccs_get_all_spec_port_idle_sta(struct hccs_dev *hdev, u8 port_type,
|
|||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(hdev->dev,
|
dev_err(hdev->dev,
|
||||||
"hccs%u on chip%u/die%u get idle status failed, ret = %d.\n",
|
"hccs%u on chip%u/die%u get idle status failed, ret = %d.\n",
|
||||||
k, i, j, ret);
|
port->port_id, chip->chip_id, die->die_id, ret);
|
||||||
return ret;
|
return ret;
|
||||||
} else if (idle == 0) {
|
} else if (idle == 0) {
|
||||||
dev_info(hdev->dev, "hccs%u on chip%u/die%u is busy.\n",
|
dev_info(hdev->dev, "hccs%u on chip%u/die%u is busy.\n",
|
||||||
k, i, j);
|
port->port_id, chip->chip_id, die->die_id);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,16 +17,35 @@
|
|||||||
|
|
||||||
#define MT2701_MUTEX0_MOD0 0x2c
|
#define MT2701_MUTEX0_MOD0 0x2c
|
||||||
#define MT2701_MUTEX0_SOF0 0x30
|
#define MT2701_MUTEX0_SOF0 0x30
|
||||||
|
#define MT2701_MUTEX0_MOD1 0x34
|
||||||
|
|
||||||
#define MT8183_MUTEX0_MOD0 0x30
|
#define MT8183_MUTEX0_MOD0 0x30
|
||||||
|
#define MT8183_MUTEX0_MOD1 0x34
|
||||||
#define MT8183_MUTEX0_SOF0 0x2c
|
#define MT8183_MUTEX0_SOF0 0x2c
|
||||||
|
|
||||||
#define DISP_REG_MUTEX_EN(n) (0x20 + 0x20 * (n))
|
#define DISP_REG_MUTEX_EN(n) (0x20 + 0x20 * (n))
|
||||||
#define DISP_REG_MUTEX(n) (0x24 + 0x20 * (n))
|
#define DISP_REG_MUTEX(n) (0x24 + 0x20 * (n))
|
||||||
#define DISP_REG_MUTEX_RST(n) (0x28 + 0x20 * (n))
|
#define DISP_REG_MUTEX_RST(n) (0x28 + 0x20 * (n))
|
||||||
#define DISP_REG_MUTEX_MOD(mutex_mod_reg, n) (mutex_mod_reg + 0x20 * (n))
|
/*
|
||||||
#define DISP_REG_MUTEX_MOD1(mutex_mod_reg, n) ((mutex_mod_reg) + 0x20 * (n) + 0x4)
|
* Some SoCs may have multiple MUTEX_MOD registers as more than 32 mods
|
||||||
|
* are present, hence requiring multiple 32-bits registers.
|
||||||
|
*
|
||||||
|
* The mutex_table_mod fully represents that by defining the number of
|
||||||
|
* the mod sequentially, later used as a bit number, which can be more
|
||||||
|
* than 0..31.
|
||||||
|
*
|
||||||
|
* In order to retain compatibility with older SoCs, we perform R/W on
|
||||||
|
* the single 32 bits registers, but this requires us to translate the
|
||||||
|
* mutex ID bit accordingly.
|
||||||
|
*/
|
||||||
|
#define DISP_REG_MUTEX_MOD(mutex, id, n) ({ \
|
||||||
|
const typeof(mutex) _mutex = (mutex); \
|
||||||
|
u32 _offset = (id) < 32 ? \
|
||||||
|
_mutex->data->mutex_mod_reg : \
|
||||||
|
_mutex->data->mutex_mod1_reg; \
|
||||||
|
_offset + 0x20 * (n); \
|
||||||
|
})
|
||||||
#define DISP_REG_MUTEX_SOF(mutex_sof_reg, n) (mutex_sof_reg + 0x20 * (n))
|
#define DISP_REG_MUTEX_SOF(mutex_sof_reg, n) (mutex_sof_reg + 0x20 * (n))
|
||||||
#define DISP_REG_MUTEX_MOD2(n) (0x34 + 0x20 * (n))
|
|
||||||
|
|
||||||
#define INT_MUTEX BIT(1)
|
#define INT_MUTEX BIT(1)
|
||||||
|
|
||||||
@ -334,6 +353,7 @@ struct mtk_mutex_data {
|
|||||||
const u8 *mutex_table_mod;
|
const u8 *mutex_table_mod;
|
||||||
const u16 *mutex_sof;
|
const u16 *mutex_sof;
|
||||||
const u16 mutex_mod_reg;
|
const u16 mutex_mod_reg;
|
||||||
|
const u16 mutex_mod1_reg;
|
||||||
const u16 mutex_sof_reg;
|
const u16 mutex_sof_reg;
|
||||||
const bool no_clk;
|
const bool no_clk;
|
||||||
};
|
};
|
||||||
@ -714,6 +734,7 @@ static const struct mtk_mutex_data mt2701_mutex_driver_data = {
|
|||||||
.mutex_mod = mt2701_mutex_mod,
|
.mutex_mod = mt2701_mutex_mod,
|
||||||
.mutex_sof = mt2712_mutex_sof,
|
.mutex_sof = mt2712_mutex_sof,
|
||||||
.mutex_mod_reg = MT2701_MUTEX0_MOD0,
|
.mutex_mod_reg = MT2701_MUTEX0_MOD0,
|
||||||
|
.mutex_mod1_reg = MT2701_MUTEX0_MOD1,
|
||||||
.mutex_sof_reg = MT2701_MUTEX0_SOF0,
|
.mutex_sof_reg = MT2701_MUTEX0_SOF0,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -721,6 +742,7 @@ static const struct mtk_mutex_data mt2712_mutex_driver_data = {
|
|||||||
.mutex_mod = mt2712_mutex_mod,
|
.mutex_mod = mt2712_mutex_mod,
|
||||||
.mutex_sof = mt2712_mutex_sof,
|
.mutex_sof = mt2712_mutex_sof,
|
||||||
.mutex_mod_reg = MT2701_MUTEX0_MOD0,
|
.mutex_mod_reg = MT2701_MUTEX0_MOD0,
|
||||||
|
.mutex_mod1_reg = MT2701_MUTEX0_MOD1,
|
||||||
.mutex_sof_reg = MT2701_MUTEX0_SOF0,
|
.mutex_sof_reg = MT2701_MUTEX0_SOF0,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -728,6 +750,7 @@ static const struct mtk_mutex_data mt6795_mutex_driver_data = {
|
|||||||
.mutex_mod = mt8173_mutex_mod,
|
.mutex_mod = mt8173_mutex_mod,
|
||||||
.mutex_sof = mt6795_mutex_sof,
|
.mutex_sof = mt6795_mutex_sof,
|
||||||
.mutex_mod_reg = MT2701_MUTEX0_MOD0,
|
.mutex_mod_reg = MT2701_MUTEX0_MOD0,
|
||||||
|
.mutex_mod1_reg = MT2701_MUTEX0_MOD1,
|
||||||
.mutex_sof_reg = MT2701_MUTEX0_SOF0,
|
.mutex_sof_reg = MT2701_MUTEX0_SOF0,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -735,6 +758,7 @@ static const struct mtk_mutex_data mt8167_mutex_driver_data = {
|
|||||||
.mutex_mod = mt8167_mutex_mod,
|
.mutex_mod = mt8167_mutex_mod,
|
||||||
.mutex_sof = mt8167_mutex_sof,
|
.mutex_sof = mt8167_mutex_sof,
|
||||||
.mutex_mod_reg = MT2701_MUTEX0_MOD0,
|
.mutex_mod_reg = MT2701_MUTEX0_MOD0,
|
||||||
|
.mutex_mod1_reg = MT2701_MUTEX0_MOD1,
|
||||||
.mutex_sof_reg = MT2701_MUTEX0_SOF0,
|
.mutex_sof_reg = MT2701_MUTEX0_SOF0,
|
||||||
.no_clk = true,
|
.no_clk = true,
|
||||||
};
|
};
|
||||||
@ -743,6 +767,7 @@ static const struct mtk_mutex_data mt8173_mutex_driver_data = {
|
|||||||
.mutex_mod = mt8173_mutex_mod,
|
.mutex_mod = mt8173_mutex_mod,
|
||||||
.mutex_sof = mt2712_mutex_sof,
|
.mutex_sof = mt2712_mutex_sof,
|
||||||
.mutex_mod_reg = MT2701_MUTEX0_MOD0,
|
.mutex_mod_reg = MT2701_MUTEX0_MOD0,
|
||||||
|
.mutex_mod1_reg = MT2701_MUTEX0_MOD1,
|
||||||
.mutex_sof_reg = MT2701_MUTEX0_SOF0,
|
.mutex_sof_reg = MT2701_MUTEX0_SOF0,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -750,6 +775,7 @@ static const struct mtk_mutex_data mt8183_mutex_driver_data = {
|
|||||||
.mutex_mod = mt8183_mutex_mod,
|
.mutex_mod = mt8183_mutex_mod,
|
||||||
.mutex_sof = mt8183_mutex_sof,
|
.mutex_sof = mt8183_mutex_sof,
|
||||||
.mutex_mod_reg = MT8183_MUTEX0_MOD0,
|
.mutex_mod_reg = MT8183_MUTEX0_MOD0,
|
||||||
|
.mutex_mod1_reg = MT8183_MUTEX0_MOD1,
|
||||||
.mutex_sof_reg = MT8183_MUTEX0_SOF0,
|
.mutex_sof_reg = MT8183_MUTEX0_SOF0,
|
||||||
.mutex_table_mod = mt8183_mutex_table_mod,
|
.mutex_table_mod = mt8183_mutex_table_mod,
|
||||||
.no_clk = true,
|
.no_clk = true,
|
||||||
@ -757,6 +783,7 @@ static const struct mtk_mutex_data mt8183_mutex_driver_data = {
|
|||||||
|
|
||||||
static const struct mtk_mutex_data mt8186_mdp_mutex_driver_data = {
|
static const struct mtk_mutex_data mt8186_mdp_mutex_driver_data = {
|
||||||
.mutex_mod_reg = MT8183_MUTEX0_MOD0,
|
.mutex_mod_reg = MT8183_MUTEX0_MOD0,
|
||||||
|
.mutex_mod1_reg = MT8183_MUTEX0_MOD1,
|
||||||
.mutex_sof_reg = MT8183_MUTEX0_SOF0,
|
.mutex_sof_reg = MT8183_MUTEX0_SOF0,
|
||||||
.mutex_table_mod = mt8186_mdp_mutex_table_mod,
|
.mutex_table_mod = mt8186_mdp_mutex_table_mod,
|
||||||
};
|
};
|
||||||
@ -765,6 +792,7 @@ static const struct mtk_mutex_data mt8186_mutex_driver_data = {
|
|||||||
.mutex_mod = mt8186_mutex_mod,
|
.mutex_mod = mt8186_mutex_mod,
|
||||||
.mutex_sof = mt8186_mutex_sof,
|
.mutex_sof = mt8186_mutex_sof,
|
||||||
.mutex_mod_reg = MT8183_MUTEX0_MOD0,
|
.mutex_mod_reg = MT8183_MUTEX0_MOD0,
|
||||||
|
.mutex_mod1_reg = MT8183_MUTEX0_MOD1,
|
||||||
.mutex_sof_reg = MT8183_MUTEX0_SOF0,
|
.mutex_sof_reg = MT8183_MUTEX0_SOF0,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -772,12 +800,14 @@ static const struct mtk_mutex_data mt8188_mutex_driver_data = {
|
|||||||
.mutex_mod = mt8188_mutex_mod,
|
.mutex_mod = mt8188_mutex_mod,
|
||||||
.mutex_sof = mt8188_mutex_sof,
|
.mutex_sof = mt8188_mutex_sof,
|
||||||
.mutex_mod_reg = MT8183_MUTEX0_MOD0,
|
.mutex_mod_reg = MT8183_MUTEX0_MOD0,
|
||||||
|
.mutex_mod1_reg = MT8183_MUTEX0_MOD1,
|
||||||
.mutex_sof_reg = MT8183_MUTEX0_SOF0,
|
.mutex_sof_reg = MT8183_MUTEX0_SOF0,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct mtk_mutex_data mt8188_vpp_mutex_driver_data = {
|
static const struct mtk_mutex_data mt8188_vpp_mutex_driver_data = {
|
||||||
.mutex_sof = mt8188_mutex_sof,
|
.mutex_sof = mt8188_mutex_sof,
|
||||||
.mutex_mod_reg = MT8183_MUTEX0_MOD0,
|
.mutex_mod_reg = MT8183_MUTEX0_MOD0,
|
||||||
|
.mutex_mod1_reg = MT8183_MUTEX0_MOD1,
|
||||||
.mutex_sof_reg = MT8183_MUTEX0_SOF0,
|
.mutex_sof_reg = MT8183_MUTEX0_SOF0,
|
||||||
.mutex_table_mod = mt8188_mdp_mutex_table_mod,
|
.mutex_table_mod = mt8188_mdp_mutex_table_mod,
|
||||||
};
|
};
|
||||||
@ -786,6 +816,7 @@ static const struct mtk_mutex_data mt8192_mutex_driver_data = {
|
|||||||
.mutex_mod = mt8192_mutex_mod,
|
.mutex_mod = mt8192_mutex_mod,
|
||||||
.mutex_sof = mt8183_mutex_sof,
|
.mutex_sof = mt8183_mutex_sof,
|
||||||
.mutex_mod_reg = MT8183_MUTEX0_MOD0,
|
.mutex_mod_reg = MT8183_MUTEX0_MOD0,
|
||||||
|
.mutex_mod1_reg = MT8183_MUTEX0_MOD1,
|
||||||
.mutex_sof_reg = MT8183_MUTEX0_SOF0,
|
.mutex_sof_reg = MT8183_MUTEX0_SOF0,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -793,12 +824,14 @@ static const struct mtk_mutex_data mt8195_mutex_driver_data = {
|
|||||||
.mutex_mod = mt8195_mutex_mod,
|
.mutex_mod = mt8195_mutex_mod,
|
||||||
.mutex_sof = mt8195_mutex_sof,
|
.mutex_sof = mt8195_mutex_sof,
|
||||||
.mutex_mod_reg = MT8183_MUTEX0_MOD0,
|
.mutex_mod_reg = MT8183_MUTEX0_MOD0,
|
||||||
|
.mutex_mod1_reg = MT8183_MUTEX0_MOD1,
|
||||||
.mutex_sof_reg = MT8183_MUTEX0_SOF0,
|
.mutex_sof_reg = MT8183_MUTEX0_SOF0,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct mtk_mutex_data mt8195_vpp_mutex_driver_data = {
|
static const struct mtk_mutex_data mt8195_vpp_mutex_driver_data = {
|
||||||
.mutex_sof = mt8195_mutex_sof,
|
.mutex_sof = mt8195_mutex_sof,
|
||||||
.mutex_mod_reg = MT8183_MUTEX0_MOD0,
|
.mutex_mod_reg = MT8183_MUTEX0_MOD0,
|
||||||
|
.mutex_mod1_reg = MT8183_MUTEX0_MOD1,
|
||||||
.mutex_sof_reg = MT8183_MUTEX0_SOF0,
|
.mutex_sof_reg = MT8183_MUTEX0_SOF0,
|
||||||
.mutex_table_mod = mt8195_mutex_table_mod,
|
.mutex_table_mod = mt8195_mutex_table_mod,
|
||||||
};
|
};
|
||||||
@ -807,6 +840,7 @@ static const struct mtk_mutex_data mt8365_mutex_driver_data = {
|
|||||||
.mutex_mod = mt8365_mutex_mod,
|
.mutex_mod = mt8365_mutex_mod,
|
||||||
.mutex_sof = mt8183_mutex_sof,
|
.mutex_sof = mt8183_mutex_sof,
|
||||||
.mutex_mod_reg = MT8183_MUTEX0_MOD0,
|
.mutex_mod_reg = MT8183_MUTEX0_MOD0,
|
||||||
|
.mutex_mod1_reg = MT8183_MUTEX0_MOD1,
|
||||||
.mutex_sof_reg = MT8183_MUTEX0_SOF0,
|
.mutex_sof_reg = MT8183_MUTEX0_SOF0,
|
||||||
.no_clk = true,
|
.no_clk = true,
|
||||||
};
|
};
|
||||||
@ -859,7 +893,7 @@ void mtk_mutex_add_comp(struct mtk_mutex *mutex,
|
|||||||
struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
|
struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
|
||||||
mutex[mutex->id]);
|
mutex[mutex->id]);
|
||||||
unsigned int reg;
|
unsigned int reg;
|
||||||
unsigned int sof_id;
|
unsigned int sof_id, mod_id;
|
||||||
unsigned int offset;
|
unsigned int offset;
|
||||||
|
|
||||||
WARN_ON(&mtx->mutex[mutex->id] != mutex);
|
WARN_ON(&mtx->mutex[mutex->id] != mutex);
|
||||||
@ -890,18 +924,11 @@ void mtk_mutex_add_comp(struct mtk_mutex *mutex,
|
|||||||
sof_id = MUTEX_SOF_DP_INTF1;
|
sof_id = MUTEX_SOF_DP_INTF1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (mtx->data->mutex_mod[id] < 32) {
|
offset = DISP_REG_MUTEX_MOD(mtx, mtx->data->mutex_mod[id], mutex->id);
|
||||||
offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg,
|
mod_id = mtx->data->mutex_mod[id] % 32;
|
||||||
mutex->id);
|
reg = readl_relaxed(mtx->regs + offset);
|
||||||
reg = readl_relaxed(mtx->regs + offset);
|
reg |= BIT(mod_id);
|
||||||
reg |= 1 << mtx->data->mutex_mod[id];
|
writel_relaxed(reg, mtx->regs + offset);
|
||||||
writel_relaxed(reg, mtx->regs + offset);
|
|
||||||
} else {
|
|
||||||
offset = DISP_REG_MUTEX_MOD2(mutex->id);
|
|
||||||
reg = readl_relaxed(mtx->regs + offset);
|
|
||||||
reg |= 1 << (mtx->data->mutex_mod[id] - 32);
|
|
||||||
writel_relaxed(reg, mtx->regs + offset);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -917,6 +944,7 @@ void mtk_mutex_remove_comp(struct mtk_mutex *mutex,
|
|||||||
struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
|
struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
|
||||||
mutex[mutex->id]);
|
mutex[mutex->id]);
|
||||||
unsigned int reg;
|
unsigned int reg;
|
||||||
|
unsigned int mod_id;
|
||||||
unsigned int offset;
|
unsigned int offset;
|
||||||
|
|
||||||
WARN_ON(&mtx->mutex[mutex->id] != mutex);
|
WARN_ON(&mtx->mutex[mutex->id] != mutex);
|
||||||
@ -936,18 +964,11 @@ void mtk_mutex_remove_comp(struct mtk_mutex *mutex,
|
|||||||
mutex->id));
|
mutex->id));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (mtx->data->mutex_mod[id] < 32) {
|
offset = DISP_REG_MUTEX_MOD(mtx, mtx->data->mutex_mod[id], mutex->id);
|
||||||
offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg,
|
mod_id = mtx->data->mutex_mod[id] % 32;
|
||||||
mutex->id);
|
reg = readl_relaxed(mtx->regs + offset);
|
||||||
reg = readl_relaxed(mtx->regs + offset);
|
reg &= ~BIT(mod_id);
|
||||||
reg &= ~(1 << mtx->data->mutex_mod[id]);
|
writel_relaxed(reg, mtx->regs + offset);
|
||||||
writel_relaxed(reg, mtx->regs + offset);
|
|
||||||
} else {
|
|
||||||
offset = DISP_REG_MUTEX_MOD2(mutex->id);
|
|
||||||
reg = readl_relaxed(mtx->regs + offset);
|
|
||||||
reg &= ~(1 << (mtx->data->mutex_mod[id] - 32));
|
|
||||||
writel_relaxed(reg, mtx->regs + offset);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1023,7 +1044,7 @@ int mtk_mutex_write_mod(struct mtk_mutex *mutex,
|
|||||||
struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
|
struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
|
||||||
mutex[mutex->id]);
|
mutex[mutex->id]);
|
||||||
unsigned int reg;
|
unsigned int reg;
|
||||||
u32 reg_offset, id_offset = 0;
|
u32 offset, mod_id;
|
||||||
|
|
||||||
WARN_ON(&mtx->mutex[mutex->id] != mutex);
|
WARN_ON(&mtx->mutex[mutex->id] != mutex);
|
||||||
|
|
||||||
@ -1033,34 +1054,16 @@ int mtk_mutex_write_mod(struct mtk_mutex *mutex,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
offset = DISP_REG_MUTEX_MOD(mtx, mtx->data->mutex_table_mod[idx], mutex->id);
|
||||||
* Some SoCs may have multiple MUTEX_MOD registers as more than 32 mods
|
mod_id = mtx->data->mutex_table_mod[idx] % 32;
|
||||||
* are present, hence requiring multiple 32-bits registers.
|
|
||||||
*
|
|
||||||
* The mutex_table_mod fully represents that by defining the number of
|
|
||||||
* the mod sequentially, later used as a bit number, which can be more
|
|
||||||
* than 0..31.
|
|
||||||
*
|
|
||||||
* In order to retain compatibility with older SoCs, we perform R/W on
|
|
||||||
* the single 32 bits registers, but this requires us to translate the
|
|
||||||
* mutex ID bit accordingly.
|
|
||||||
*/
|
|
||||||
if (mtx->data->mutex_table_mod[idx] < 32) {
|
|
||||||
reg_offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg,
|
|
||||||
mutex->id);
|
|
||||||
} else {
|
|
||||||
reg_offset = DISP_REG_MUTEX_MOD1(mtx->data->mutex_mod_reg,
|
|
||||||
mutex->id);
|
|
||||||
id_offset = 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
reg = readl_relaxed(mtx->regs + reg_offset);
|
reg = readl_relaxed(mtx->regs + offset);
|
||||||
if (clear)
|
if (clear)
|
||||||
reg &= ~BIT(mtx->data->mutex_table_mod[idx] - id_offset);
|
reg &= ~BIT(mod_id);
|
||||||
else
|
else
|
||||||
reg |= BIT(mtx->data->mutex_table_mod[idx] - id_offset);
|
reg |= BIT(mod_id);
|
||||||
|
|
||||||
writel_relaxed(reg, mtx->regs + reg_offset);
|
writel_relaxed(reg, mtx->regs + offset);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,38 @@
|
|||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/soc/qcom/mdt_loader.h>
|
#include <linux/soc/qcom/mdt_loader.h>
|
||||||
|
|
||||||
static bool mdt_phdr_valid(const struct elf32_phdr *phdr)
|
static bool mdt_header_valid(const struct firmware *fw)
|
||||||
|
{
|
||||||
|
const struct elf32_hdr *ehdr;
|
||||||
|
size_t phend;
|
||||||
|
size_t shend;
|
||||||
|
|
||||||
|
if (fw->size < sizeof(*ehdr))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ehdr = (struct elf32_hdr *)fw->data;
|
||||||
|
|
||||||
|
if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (ehdr->e_phentsize != sizeof(struct elf32_phdr))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
phend = size_add(size_mul(sizeof(struct elf32_phdr), ehdr->e_phnum), ehdr->e_phoff);
|
||||||
|
if (phend > fw->size)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (ehdr->e_shentsize != sizeof(struct elf32_shdr))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
shend = size_add(size_mul(sizeof(struct elf32_shdr), ehdr->e_shnum), ehdr->e_shoff);
|
||||||
|
if (shend > fw->size)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool mdt_phdr_loadable(const struct elf32_phdr *phdr)
|
||||||
{
|
{
|
||||||
if (phdr->p_type != PT_LOAD)
|
if (phdr->p_type != PT_LOAD)
|
||||||
return false;
|
return false;
|
||||||
@ -82,13 +113,16 @@ ssize_t qcom_mdt_get_size(const struct firmware *fw)
|
|||||||
phys_addr_t max_addr = 0;
|
phys_addr_t max_addr = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (!mdt_header_valid(fw))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
ehdr = (struct elf32_hdr *)fw->data;
|
ehdr = (struct elf32_hdr *)fw->data;
|
||||||
phdrs = (struct elf32_phdr *)(ehdr + 1);
|
phdrs = (struct elf32_phdr *)(fw->data + ehdr->e_phoff);
|
||||||
|
|
||||||
for (i = 0; i < ehdr->e_phnum; i++) {
|
for (i = 0; i < ehdr->e_phnum; i++) {
|
||||||
phdr = &phdrs[i];
|
phdr = &phdrs[i];
|
||||||
|
|
||||||
if (!mdt_phdr_valid(phdr))
|
if (!mdt_phdr_loadable(phdr))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (phdr->p_paddr < min_addr)
|
if (phdr->p_paddr < min_addr)
|
||||||
@ -134,8 +168,11 @@ void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len,
|
|||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
void *data;
|
void *data;
|
||||||
|
|
||||||
|
if (!mdt_header_valid(fw))
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
ehdr = (struct elf32_hdr *)fw->data;
|
ehdr = (struct elf32_hdr *)fw->data;
|
||||||
phdrs = (struct elf32_phdr *)(ehdr + 1);
|
phdrs = (struct elf32_phdr *)(fw->data + ehdr->e_phoff);
|
||||||
|
|
||||||
if (ehdr->e_phnum < 2)
|
if (ehdr->e_phnum < 2)
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
@ -214,13 +251,16 @@ int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw,
|
|||||||
int ret;
|
int ret;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (!mdt_header_valid(fw))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
ehdr = (struct elf32_hdr *)fw->data;
|
ehdr = (struct elf32_hdr *)fw->data;
|
||||||
phdrs = (struct elf32_phdr *)(ehdr + 1);
|
phdrs = (struct elf32_phdr *)(fw->data + ehdr->e_phoff);
|
||||||
|
|
||||||
for (i = 0; i < ehdr->e_phnum; i++) {
|
for (i = 0; i < ehdr->e_phnum; i++) {
|
||||||
phdr = &phdrs[i];
|
phdr = &phdrs[i];
|
||||||
|
|
||||||
if (!mdt_phdr_valid(phdr))
|
if (!mdt_phdr_loadable(phdr))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (phdr->p_flags & QCOM_MDT_RELOCATABLE)
|
if (phdr->p_flags & QCOM_MDT_RELOCATABLE)
|
||||||
@ -270,7 +310,7 @@ static bool qcom_mdt_bins_are_split(const struct firmware *fw, const char *fw_na
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
ehdr = (struct elf32_hdr *)fw->data;
|
ehdr = (struct elf32_hdr *)fw->data;
|
||||||
phdrs = (struct elf32_phdr *)(ehdr + 1);
|
phdrs = (struct elf32_phdr *)(fw->data + ehdr->e_phoff);
|
||||||
|
|
||||||
for (i = 0; i < ehdr->e_phnum; i++) {
|
for (i = 0; i < ehdr->e_phnum; i++) {
|
||||||
/*
|
/*
|
||||||
@ -310,14 +350,17 @@ static int __qcom_mdt_load(struct device *dev, const struct firmware *fw,
|
|||||||
if (!fw || !mem_region || !mem_phys || !mem_size)
|
if (!fw || !mem_region || !mem_phys || !mem_size)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (!mdt_header_valid(fw))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
is_split = qcom_mdt_bins_are_split(fw, fw_name);
|
is_split = qcom_mdt_bins_are_split(fw, fw_name);
|
||||||
ehdr = (struct elf32_hdr *)fw->data;
|
ehdr = (struct elf32_hdr *)fw->data;
|
||||||
phdrs = (struct elf32_phdr *)(ehdr + 1);
|
phdrs = (struct elf32_phdr *)(fw->data + ehdr->e_phoff);
|
||||||
|
|
||||||
for (i = 0; i < ehdr->e_phnum; i++) {
|
for (i = 0; i < ehdr->e_phnum; i++) {
|
||||||
phdr = &phdrs[i];
|
phdr = &phdrs[i];
|
||||||
|
|
||||||
if (!mdt_phdr_valid(phdr))
|
if (!mdt_phdr_loadable(phdr))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (phdr->p_flags & QCOM_MDT_RELOCATABLE)
|
if (phdr->p_flags & QCOM_MDT_RELOCATABLE)
|
||||||
@ -344,7 +387,7 @@ static int __qcom_mdt_load(struct device *dev, const struct firmware *fw,
|
|||||||
for (i = 0; i < ehdr->e_phnum; i++) {
|
for (i = 0; i < ehdr->e_phnum; i++) {
|
||||||
phdr = &phdrs[i];
|
phdr = &phdrs[i];
|
||||||
|
|
||||||
if (!mdt_phdr_valid(phdr))
|
if (!mdt_phdr_loadable(phdr))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
offset = phdr->p_paddr - mem_reloc;
|
offset = phdr->p_paddr - mem_reloc;
|
||||||
|
@ -167,7 +167,10 @@ static int pmic_glink_rpmsg_callback(struct rpmsg_device *rpdev, void *data,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pmic_glink_aux_release(struct device *dev) {}
|
static void pmic_glink_aux_release(struct device *dev)
|
||||||
|
{
|
||||||
|
of_node_put(dev->of_node);
|
||||||
|
}
|
||||||
|
|
||||||
static int pmic_glink_add_aux_device(struct pmic_glink *pg,
|
static int pmic_glink_add_aux_device(struct pmic_glink *pg,
|
||||||
struct auxiliary_device *aux,
|
struct auxiliary_device *aux,
|
||||||
@ -181,8 +184,10 @@ static int pmic_glink_add_aux_device(struct pmic_glink *pg,
|
|||||||
aux->dev.release = pmic_glink_aux_release;
|
aux->dev.release = pmic_glink_aux_release;
|
||||||
device_set_of_node_from_dev(&aux->dev, parent);
|
device_set_of_node_from_dev(&aux->dev, parent);
|
||||||
ret = auxiliary_device_init(aux);
|
ret = auxiliary_device_init(aux);
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
of_node_put(aux->dev.of_node);
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
ret = auxiliary_device_add(aux);
|
ret = auxiliary_device_add(aux);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011-2021, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2011-2021, The Linux Foundation. All rights reserved.
|
||||||
|
* Copyright (c) 2022-2025, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/bitfield.h>
|
||||||
#include <linux/debugfs.h>
|
#include <linux/debugfs.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
@ -11,6 +13,7 @@
|
|||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
|
|
||||||
|
#include <linux/soc/qcom/qcom_aoss.h>
|
||||||
#include <linux/soc/qcom/smem.h>
|
#include <linux/soc/qcom/smem.h>
|
||||||
#include <clocksource/arm_arch_timer.h>
|
#include <clocksource/arm_arch_timer.h>
|
||||||
|
|
||||||
@ -24,6 +27,19 @@
|
|||||||
#define ACCUMULATED_OFFSET 0x18
|
#define ACCUMULATED_OFFSET 0x18
|
||||||
#define CLIENT_VOTES_OFFSET 0x20
|
#define CLIENT_VOTES_OFFSET 0x20
|
||||||
|
|
||||||
|
#define DDR_STATS_MAGIC_KEY 0xA1157A75
|
||||||
|
#define DDR_STATS_MAX_NUM_MODES 20
|
||||||
|
#define DDR_STATS_MAGIC_KEY_ADDR 0x0
|
||||||
|
#define DDR_STATS_NUM_MODES_ADDR 0x4
|
||||||
|
#define DDR_STATS_ENTRY_START_ADDR 0x8
|
||||||
|
|
||||||
|
#define DDR_STATS_CP_IDX(data) FIELD_GET(GENMASK(4, 0), data)
|
||||||
|
#define DDR_STATS_LPM_NAME(data) FIELD_GET(GENMASK(7, 0), data)
|
||||||
|
#define DDR_STATS_TYPE(data) FIELD_GET(GENMASK(15, 8), data)
|
||||||
|
#define DDR_STATS_FREQ(data) FIELD_GET(GENMASK(31, 16), data)
|
||||||
|
|
||||||
|
static struct qmp *qcom_stats_qmp;
|
||||||
|
|
||||||
struct subsystem_data {
|
struct subsystem_data {
|
||||||
const char *name;
|
const char *name;
|
||||||
u32 smem_item;
|
u32 smem_item;
|
||||||
@ -48,12 +64,19 @@ static const struct subsystem_data subsystems[] = {
|
|||||||
|
|
||||||
struct stats_config {
|
struct stats_config {
|
||||||
size_t stats_offset;
|
size_t stats_offset;
|
||||||
|
size_t ddr_stats_offset;
|
||||||
size_t num_records;
|
size_t num_records;
|
||||||
bool appended_stats_avail;
|
bool appended_stats_avail;
|
||||||
bool dynamic_offset;
|
bool dynamic_offset;
|
||||||
bool subsystem_stats_in_smem;
|
bool subsystem_stats_in_smem;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ddr_stats_entry {
|
||||||
|
u32 name;
|
||||||
|
u32 count;
|
||||||
|
u64 duration;
|
||||||
|
};
|
||||||
|
|
||||||
struct stats_data {
|
struct stats_data {
|
||||||
bool appended_stats_avail;
|
bool appended_stats_avail;
|
||||||
void __iomem *base;
|
void __iomem *base;
|
||||||
@ -122,8 +145,101 @@ static int qcom_soc_sleep_stats_show(struct seq_file *s, void *unused)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void qcom_ddr_stats_print(struct seq_file *s, struct ddr_stats_entry *data)
|
||||||
|
{
|
||||||
|
u32 cp_idx;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DDR statistic have two different types of details encoded.
|
||||||
|
* (1) DDR LPM Stats
|
||||||
|
* (2) DDR Frequency Stats
|
||||||
|
*
|
||||||
|
* The name field have details like which type of DDR stat (bits 8:15)
|
||||||
|
* along with other details as explained below
|
||||||
|
*
|
||||||
|
* In case of DDR LPM stat, name field will be encoded as,
|
||||||
|
* Bits - Meaning
|
||||||
|
* 0:7 - DDR LPM name, can be of 0xd4, 0xd3, 0x11 and 0xd0.
|
||||||
|
* 8:15 - 0x0 (indicates its a LPM stat)
|
||||||
|
* 16:31 - Unused
|
||||||
|
*
|
||||||
|
* In case of DDR FREQ stats, name field will be encoded as,
|
||||||
|
* Bits - Meaning
|
||||||
|
* 0:4 - DDR Clock plan index (CP IDX)
|
||||||
|
* 5:7 - Unused
|
||||||
|
* 8:15 - 0x1 (indicates its Freq stat)
|
||||||
|
* 16:31 - Frequency value in Mhz
|
||||||
|
*/
|
||||||
|
switch (DDR_STATS_TYPE(data->name)) {
|
||||||
|
case 0:
|
||||||
|
seq_printf(s, "DDR LPM Stat Name:0x%lx\tcount:%u\tDuration (ticks):%llu\n",
|
||||||
|
DDR_STATS_LPM_NAME(data->name), data->count, data->duration);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (!data->count || !DDR_STATS_FREQ(data->name))
|
||||||
|
return;
|
||||||
|
|
||||||
|
cp_idx = DDR_STATS_CP_IDX(data->name);
|
||||||
|
seq_printf(s, "DDR Freq %luMhz:\tCP IDX:%u\tcount:%u\tDuration (ticks):%llu\n",
|
||||||
|
DDR_STATS_FREQ(data->name), cp_idx, data->count, data->duration);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int qcom_ddr_stats_show(struct seq_file *s, void *d)
|
||||||
|
{
|
||||||
|
struct ddr_stats_entry data[DDR_STATS_MAX_NUM_MODES];
|
||||||
|
void __iomem *reg = (void __iomem *)s->private;
|
||||||
|
u32 entry_count;
|
||||||
|
int i, ret;
|
||||||
|
|
||||||
|
entry_count = readl_relaxed(reg + DDR_STATS_NUM_MODES_ADDR);
|
||||||
|
if (entry_count > DDR_STATS_MAX_NUM_MODES)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (qcom_stats_qmp) {
|
||||||
|
/*
|
||||||
|
* Recent SoCs (SM8450 onwards) do not have duration field
|
||||||
|
* populated from boot up onwards for both DDR LPM Stats
|
||||||
|
* and DDR Frequency Stats.
|
||||||
|
*
|
||||||
|
* Send QMP message to Always on processor which will
|
||||||
|
* populate duration field into MSG RAM area.
|
||||||
|
*
|
||||||
|
* Sent every time to read latest data.
|
||||||
|
*/
|
||||||
|
ret = qmp_send(qcom_stats_qmp, "{class: ddr, action: freqsync}");
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
reg += DDR_STATS_ENTRY_START_ADDR;
|
||||||
|
memcpy_fromio(data, reg, sizeof(struct ddr_stats_entry) * entry_count);
|
||||||
|
|
||||||
|
for (i = 0; i < entry_count; i++)
|
||||||
|
qcom_ddr_stats_print(s, &data[i]);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
DEFINE_SHOW_ATTRIBUTE(qcom_soc_sleep_stats);
|
DEFINE_SHOW_ATTRIBUTE(qcom_soc_sleep_stats);
|
||||||
DEFINE_SHOW_ATTRIBUTE(qcom_subsystem_sleep_stats);
|
DEFINE_SHOW_ATTRIBUTE(qcom_subsystem_sleep_stats);
|
||||||
|
DEFINE_SHOW_ATTRIBUTE(qcom_ddr_stats);
|
||||||
|
|
||||||
|
static void qcom_create_ddr_stat_files(struct dentry *root, void __iomem *reg,
|
||||||
|
const struct stats_config *config)
|
||||||
|
{
|
||||||
|
u32 key;
|
||||||
|
|
||||||
|
if (!config->ddr_stats_offset)
|
||||||
|
return;
|
||||||
|
|
||||||
|
key = readl_relaxed(reg + config->ddr_stats_offset + DDR_STATS_MAGIC_KEY_ADDR);
|
||||||
|
if (key == DDR_STATS_MAGIC_KEY)
|
||||||
|
debugfs_create_file("ddr_stats", 0400, root,
|
||||||
|
(__force void *)reg + config->ddr_stats_offset,
|
||||||
|
&qcom_ddr_stats_fops);
|
||||||
|
}
|
||||||
|
|
||||||
static void qcom_create_soc_sleep_stat_files(struct dentry *root, void __iomem *reg,
|
static void qcom_create_soc_sleep_stat_files(struct dentry *root, void __iomem *reg,
|
||||||
struct stats_data *d,
|
struct stats_data *d,
|
||||||
@ -207,11 +323,27 @@ static int qcom_stats_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
for (i = 0; i < config->num_records; i++)
|
for (i = 0; i < config->num_records; i++)
|
||||||
d[i].appended_stats_avail = config->appended_stats_avail;
|
d[i].appended_stats_avail = config->appended_stats_avail;
|
||||||
|
/*
|
||||||
|
* QMP is used for DDR stats syncing to MSG RAM for recent SoCs (SM8450 onwards).
|
||||||
|
* The prior SoCs do not need QMP handle as the required stats are already present
|
||||||
|
* in MSG RAM, provided the DDR_STATS_MAGIC_KEY matches.
|
||||||
|
*/
|
||||||
|
qcom_stats_qmp = qmp_get(&pdev->dev);
|
||||||
|
if (IS_ERR(qcom_stats_qmp)) {
|
||||||
|
/* We ignore error if QMP is not defined/needed */
|
||||||
|
if (!of_property_present(pdev->dev.of_node, "qcom,qmp"))
|
||||||
|
qcom_stats_qmp = NULL;
|
||||||
|
else if (PTR_ERR(qcom_stats_qmp) == -EPROBE_DEFER)
|
||||||
|
return -EPROBE_DEFER;
|
||||||
|
else
|
||||||
|
return PTR_ERR(qcom_stats_qmp);
|
||||||
|
}
|
||||||
|
|
||||||
root = debugfs_create_dir("qcom_stats", NULL);
|
root = debugfs_create_dir("qcom_stats", NULL);
|
||||||
|
|
||||||
qcom_create_subsystem_stat_files(root, config);
|
qcom_create_subsystem_stat_files(root, config);
|
||||||
qcom_create_soc_sleep_stat_files(root, reg, d, config);
|
qcom_create_soc_sleep_stat_files(root, reg, d, config);
|
||||||
|
qcom_create_ddr_stat_files(root, reg, config);
|
||||||
|
|
||||||
platform_set_drvdata(pdev, root);
|
platform_set_drvdata(pdev, root);
|
||||||
|
|
||||||
@ -254,6 +386,7 @@ static const struct stats_config rpmh_data_sdm845 = {
|
|||||||
|
|
||||||
static const struct stats_config rpmh_data = {
|
static const struct stats_config rpmh_data = {
|
||||||
.stats_offset = 0x48,
|
.stats_offset = 0x48,
|
||||||
|
.ddr_stats_offset = 0xb8,
|
||||||
.num_records = 3,
|
.num_records = 3,
|
||||||
.appended_stats_avail = false,
|
.appended_stats_avail = false,
|
||||||
.dynamic_offset = false,
|
.dynamic_offset = false,
|
||||||
|
@ -304,6 +304,8 @@ static int qmi_encode(const struct qmi_elem_info *ei_array, void *out_buf,
|
|||||||
const void *buf_src;
|
const void *buf_src;
|
||||||
int encode_tlv = 0;
|
int encode_tlv = 0;
|
||||||
int rc;
|
int rc;
|
||||||
|
u8 val8;
|
||||||
|
u16 val16;
|
||||||
|
|
||||||
if (!ei_array)
|
if (!ei_array)
|
||||||
return 0;
|
return 0;
|
||||||
@ -338,7 +340,6 @@ static int qmi_encode(const struct qmi_elem_info *ei_array, void *out_buf,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case QMI_DATA_LEN:
|
case QMI_DATA_LEN:
|
||||||
memcpy(&data_len_value, buf_src, temp_ei->elem_size);
|
|
||||||
data_len_sz = temp_ei->elem_size == sizeof(u8) ?
|
data_len_sz = temp_ei->elem_size == sizeof(u8) ?
|
||||||
sizeof(u8) : sizeof(u16);
|
sizeof(u8) : sizeof(u16);
|
||||||
/* Check to avoid out of range buffer access */
|
/* Check to avoid out of range buffer access */
|
||||||
@ -348,8 +349,17 @@ static int qmi_encode(const struct qmi_elem_info *ei_array, void *out_buf,
|
|||||||
__func__);
|
__func__);
|
||||||
return -ETOOSMALL;
|
return -ETOOSMALL;
|
||||||
}
|
}
|
||||||
rc = qmi_encode_basic_elem(buf_dst, &data_len_value,
|
if (data_len_sz == sizeof(u8)) {
|
||||||
1, data_len_sz);
|
val8 = *(u8 *)buf_src;
|
||||||
|
data_len_value = (u32)val8;
|
||||||
|
rc = qmi_encode_basic_elem(buf_dst, &val8,
|
||||||
|
1, data_len_sz);
|
||||||
|
} else {
|
||||||
|
val16 = *(u16 *)buf_src;
|
||||||
|
data_len_value = (u32)le16_to_cpu(val16);
|
||||||
|
rc = qmi_encode_basic_elem(buf_dst, &val16,
|
||||||
|
1, data_len_sz);
|
||||||
|
}
|
||||||
UPDATE_ENCODE_VARIABLES(temp_ei, buf_dst,
|
UPDATE_ENCODE_VARIABLES(temp_ei, buf_dst,
|
||||||
encoded_bytes, tlv_len,
|
encoded_bytes, tlv_len,
|
||||||
encode_tlv, rc);
|
encode_tlv, rc);
|
||||||
@ -523,14 +533,23 @@ static int qmi_decode_string_elem(const struct qmi_elem_info *ei_array,
|
|||||||
u32 string_len = 0;
|
u32 string_len = 0;
|
||||||
u32 string_len_sz = 0;
|
u32 string_len_sz = 0;
|
||||||
const struct qmi_elem_info *temp_ei = ei_array;
|
const struct qmi_elem_info *temp_ei = ei_array;
|
||||||
|
u8 val8;
|
||||||
|
u16 val16;
|
||||||
|
|
||||||
if (dec_level == 1) {
|
if (dec_level == 1) {
|
||||||
string_len = tlv_len;
|
string_len = tlv_len;
|
||||||
} else {
|
} else {
|
||||||
string_len_sz = temp_ei->elem_len <= U8_MAX ?
|
string_len_sz = temp_ei->elem_len <= U8_MAX ?
|
||||||
sizeof(u8) : sizeof(u16);
|
sizeof(u8) : sizeof(u16);
|
||||||
rc = qmi_decode_basic_elem(&string_len, buf_src,
|
if (string_len_sz == sizeof(u8)) {
|
||||||
1, string_len_sz);
|
rc = qmi_decode_basic_elem(&val8, buf_src,
|
||||||
|
1, string_len_sz);
|
||||||
|
string_len = (u32)val8;
|
||||||
|
} else {
|
||||||
|
rc = qmi_decode_basic_elem(&val16, buf_src,
|
||||||
|
1, string_len_sz);
|
||||||
|
string_len = (u32)val16;
|
||||||
|
}
|
||||||
decoded_bytes += rc;
|
decoded_bytes += rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -604,6 +623,9 @@ static int qmi_decode(const struct qmi_elem_info *ei_array, void *out_c_struct,
|
|||||||
u32 decoded_bytes = 0;
|
u32 decoded_bytes = 0;
|
||||||
const void *buf_src = in_buf;
|
const void *buf_src = in_buf;
|
||||||
int rc;
|
int rc;
|
||||||
|
u8 val8;
|
||||||
|
u16 val16;
|
||||||
|
u32 val32;
|
||||||
|
|
||||||
while (decoded_bytes < in_buf_len) {
|
while (decoded_bytes < in_buf_len) {
|
||||||
if (dec_level >= 2 && temp_ei->data_type == QMI_EOTI)
|
if (dec_level >= 2 && temp_ei->data_type == QMI_EOTI)
|
||||||
@ -642,9 +664,17 @@ static int qmi_decode(const struct qmi_elem_info *ei_array, void *out_c_struct,
|
|||||||
if (temp_ei->data_type == QMI_DATA_LEN) {
|
if (temp_ei->data_type == QMI_DATA_LEN) {
|
||||||
data_len_sz = temp_ei->elem_size == sizeof(u8) ?
|
data_len_sz = temp_ei->elem_size == sizeof(u8) ?
|
||||||
sizeof(u8) : sizeof(u16);
|
sizeof(u8) : sizeof(u16);
|
||||||
rc = qmi_decode_basic_elem(&data_len_value, buf_src,
|
if (data_len_sz == sizeof(u8)) {
|
||||||
1, data_len_sz);
|
rc = qmi_decode_basic_elem(&val8, buf_src,
|
||||||
memcpy(buf_dst, &data_len_value, sizeof(u32));
|
1, data_len_sz);
|
||||||
|
data_len_value = (u32)val8;
|
||||||
|
} else {
|
||||||
|
rc = qmi_decode_basic_elem(&val16, buf_src,
|
||||||
|
1, data_len_sz);
|
||||||
|
data_len_value = (u32)val16;
|
||||||
|
}
|
||||||
|
val32 = cpu_to_le32(data_len_value);
|
||||||
|
memcpy(buf_dst, &val32, sizeof(u32));
|
||||||
temp_ei = temp_ei + 1;
|
temp_ei = temp_ei + 1;
|
||||||
buf_dst = out_c_struct + temp_ei->offset;
|
buf_dst = out_c_struct + temp_ei->offset;
|
||||||
tlv_len -= data_len_sz;
|
tlv_len -= data_len_sz;
|
||||||
@ -746,9 +776,9 @@ void *qmi_encode_message(int type, unsigned int msg_id, size_t *len,
|
|||||||
|
|
||||||
hdr = msg;
|
hdr = msg;
|
||||||
hdr->type = type;
|
hdr->type = type;
|
||||||
hdr->txn_id = txn_id;
|
hdr->txn_id = cpu_to_le16(txn_id);
|
||||||
hdr->msg_id = msg_id;
|
hdr->msg_id = cpu_to_le16(msg_id);
|
||||||
hdr->msg_len = msglen;
|
hdr->msg_len = cpu_to_le16(msglen);
|
||||||
|
|
||||||
*len = sizeof(*hdr) + msglen;
|
*len = sizeof(*hdr) + msglen;
|
||||||
|
|
||||||
|
@ -400,7 +400,7 @@ static void qmi_invoke_handler(struct qmi_handle *qmi, struct sockaddr_qrtr *sq,
|
|||||||
|
|
||||||
for (handler = qmi->handlers; handler->fn; handler++) {
|
for (handler = qmi->handlers; handler->fn; handler++) {
|
||||||
if (handler->type == hdr->type &&
|
if (handler->type == hdr->type &&
|
||||||
handler->msg_id == hdr->msg_id)
|
handler->msg_id == le16_to_cpu(hdr->msg_id))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -488,7 +488,7 @@ static void qmi_handle_message(struct qmi_handle *qmi,
|
|||||||
/* If this is a response, find the matching transaction handle */
|
/* If this is a response, find the matching transaction handle */
|
||||||
if (hdr->type == QMI_RESPONSE) {
|
if (hdr->type == QMI_RESPONSE) {
|
||||||
mutex_lock(&qmi->txn_lock);
|
mutex_lock(&qmi->txn_lock);
|
||||||
txn = idr_find(&qmi->txns, hdr->txn_id);
|
txn = idr_find(&qmi->txns, le16_to_cpu(hdr->txn_id));
|
||||||
|
|
||||||
/* Ignore unexpected responses */
|
/* Ignore unexpected responses */
|
||||||
if (!txn) {
|
if (!txn) {
|
||||||
@ -514,7 +514,7 @@ static void qmi_handle_message(struct qmi_handle *qmi,
|
|||||||
} else {
|
} else {
|
||||||
/* Create a txn based on the txn_id of the incoming message */
|
/* Create a txn based on the txn_id of the incoming message */
|
||||||
memset(&tmp_txn, 0, sizeof(tmp_txn));
|
memset(&tmp_txn, 0, sizeof(tmp_txn));
|
||||||
tmp_txn.id = hdr->txn_id;
|
tmp_txn.id = le16_to_cpu(hdr->txn_id);
|
||||||
|
|
||||||
qmi_invoke_handler(qmi, sq, &tmp_txn, buf, len);
|
qmi_invoke_handler(qmi, sq, &tmp_txn, buf, len);
|
||||||
}
|
}
|
||||||
|
@ -1072,7 +1072,7 @@ static int rpmh_rsc_probe(struct platform_device *pdev)
|
|||||||
drv->ver.minor = rsc_id & (MINOR_VER_MASK << MINOR_VER_SHIFT);
|
drv->ver.minor = rsc_id & (MINOR_VER_MASK << MINOR_VER_SHIFT);
|
||||||
drv->ver.minor >>= MINOR_VER_SHIFT;
|
drv->ver.minor >>= MINOR_VER_SHIFT;
|
||||||
|
|
||||||
if (drv->ver.major == 3)
|
if (drv->ver.major >= 3)
|
||||||
drv->regs = rpmh_rsc_reg_offset_ver_3_0;
|
drv->regs = rpmh_rsc_reg_offset_ver_3_0;
|
||||||
else
|
else
|
||||||
drv->regs = rpmh_rsc_reg_offset_ver_2_7;
|
drv->regs = rpmh_rsc_reg_offset_ver_2_7;
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
#define SMEM_IMAGE_TABLE_BOOT_INDEX 0
|
#define SMEM_IMAGE_TABLE_BOOT_INDEX 0
|
||||||
#define SMEM_IMAGE_TABLE_TZ_INDEX 1
|
#define SMEM_IMAGE_TABLE_TZ_INDEX 1
|
||||||
#define SMEM_IMAGE_TABLE_RPM_INDEX 3
|
#define SMEM_IMAGE_TABLE_RPM_INDEX 3
|
||||||
|
#define SMEM_IMAGE_TABLE_APPSBL_INDEX 9
|
||||||
#define SMEM_IMAGE_TABLE_APPS_INDEX 10
|
#define SMEM_IMAGE_TABLE_APPS_INDEX 10
|
||||||
#define SMEM_IMAGE_TABLE_MPSS_INDEX 11
|
#define SMEM_IMAGE_TABLE_MPSS_INDEX 11
|
||||||
#define SMEM_IMAGE_TABLE_ADSP_INDEX 12
|
#define SMEM_IMAGE_TABLE_ADSP_INDEX 12
|
||||||
@ -48,6 +49,7 @@
|
|||||||
#define SMEM_IMAGE_TABLE_CDSP1_INDEX 19
|
#define SMEM_IMAGE_TABLE_CDSP1_INDEX 19
|
||||||
#define SMEM_IMAGE_TABLE_GPDSP_INDEX 20
|
#define SMEM_IMAGE_TABLE_GPDSP_INDEX 20
|
||||||
#define SMEM_IMAGE_TABLE_GPDSP1_INDEX 21
|
#define SMEM_IMAGE_TABLE_GPDSP1_INDEX 21
|
||||||
|
#define SMEM_IMAGE_TABLE_TME_INDEX 28
|
||||||
#define SMEM_IMAGE_VERSION_TABLE 469
|
#define SMEM_IMAGE_VERSION_TABLE 469
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -55,6 +57,7 @@
|
|||||||
*/
|
*/
|
||||||
static const char *const socinfo_image_names[] = {
|
static const char *const socinfo_image_names[] = {
|
||||||
[SMEM_IMAGE_TABLE_ADSP_INDEX] = "adsp",
|
[SMEM_IMAGE_TABLE_ADSP_INDEX] = "adsp",
|
||||||
|
[SMEM_IMAGE_TABLE_APPSBL_INDEX] = "appsbl",
|
||||||
[SMEM_IMAGE_TABLE_APPS_INDEX] = "apps",
|
[SMEM_IMAGE_TABLE_APPS_INDEX] = "apps",
|
||||||
[SMEM_IMAGE_TABLE_BOOT_INDEX] = "boot",
|
[SMEM_IMAGE_TABLE_BOOT_INDEX] = "boot",
|
||||||
[SMEM_IMAGE_TABLE_CNSS_INDEX] = "cnss",
|
[SMEM_IMAGE_TABLE_CNSS_INDEX] = "cnss",
|
||||||
@ -67,6 +70,7 @@ static const char *const socinfo_image_names[] = {
|
|||||||
[SMEM_IMAGE_TABLE_CDSP1_INDEX] = "cdsp1",
|
[SMEM_IMAGE_TABLE_CDSP1_INDEX] = "cdsp1",
|
||||||
[SMEM_IMAGE_TABLE_GPDSP_INDEX] = "gpdsp",
|
[SMEM_IMAGE_TABLE_GPDSP_INDEX] = "gpdsp",
|
||||||
[SMEM_IMAGE_TABLE_GPDSP1_INDEX] = "gpdsp1",
|
[SMEM_IMAGE_TABLE_GPDSP1_INDEX] = "gpdsp1",
|
||||||
|
[SMEM_IMAGE_TABLE_TME_INDEX] = "tme",
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *const pmic_models[] = {
|
static const char *const pmic_models[] = {
|
||||||
@ -126,8 +130,12 @@ static const char *const pmic_models[] = {
|
|||||||
[72] = "PMR735D",
|
[72] = "PMR735D",
|
||||||
[73] = "PM8550",
|
[73] = "PM8550",
|
||||||
[74] = "PMK8550",
|
[74] = "PMK8550",
|
||||||
|
[78] = "PMM8650AU",
|
||||||
|
[79] = "PMM8650AU_PSAIL",
|
||||||
|
[80] = "PM7550",
|
||||||
[82] = "PMC8380",
|
[82] = "PMC8380",
|
||||||
[83] = "SMB2360",
|
[83] = "SMB2360",
|
||||||
|
[91] = "PMIV0108",
|
||||||
};
|
};
|
||||||
|
|
||||||
struct socinfo_params {
|
struct socinfo_params {
|
||||||
@ -446,8 +454,13 @@ static const struct soc_id soc_id[] = {
|
|||||||
{ qcom_board_id(QCM8550) },
|
{ qcom_board_id(QCM8550) },
|
||||||
{ qcom_board_id(SM8750) },
|
{ qcom_board_id(SM8750) },
|
||||||
{ qcom_board_id(IPQ5300) },
|
{ qcom_board_id(IPQ5300) },
|
||||||
|
{ qcom_board_id(SM7635) },
|
||||||
|
{ qcom_board_id(SM6650) },
|
||||||
|
{ qcom_board_id(SM6650P) },
|
||||||
{ qcom_board_id(IPQ5321) },
|
{ qcom_board_id(IPQ5321) },
|
||||||
{ qcom_board_id(IPQ5424) },
|
{ qcom_board_id(IPQ5424) },
|
||||||
|
{ qcom_board_id(QCM6690) },
|
||||||
|
{ qcom_board_id(QCS6690) },
|
||||||
{ qcom_board_id(IPQ5404) },
|
{ qcom_board_id(IPQ5404) },
|
||||||
{ qcom_board_id(QCS9100) },
|
{ qcom_board_id(QCS9100) },
|
||||||
{ qcom_board_id(QCS8300) },
|
{ qcom_board_id(QCS8300) },
|
||||||
|
@ -69,79 +69,8 @@ config ARCH_EMEV2
|
|||||||
select HAVE_ARM_SCU if SMP
|
select HAVE_ARM_SCU if SMP
|
||||||
select SYS_SUPPORTS_EM_STI
|
select SYS_SUPPORTS_EM_STI
|
||||||
|
|
||||||
config ARCH_R8A7794
|
|
||||||
bool "ARM32 Platform support for R-Car E2"
|
|
||||||
default ARCH_RENESAS
|
|
||||||
select ARCH_RCAR_GEN2
|
|
||||||
select ARM_ERRATA_814220
|
|
||||||
select SYSC_R8A7794
|
|
||||||
|
|
||||||
config ARCH_R8A7779
|
|
||||||
bool "ARM32 Platform support for R-Car H1"
|
|
||||||
default ARCH_RENESAS
|
|
||||||
select ARCH_RCAR_GEN1
|
|
||||||
select ARM_ERRATA_754322
|
|
||||||
select ARM_GLOBAL_TIMER
|
|
||||||
select HAVE_ARM_SCU if SMP
|
|
||||||
select HAVE_ARM_TWD if SMP
|
|
||||||
select SYSC_R8A7779
|
|
||||||
|
|
||||||
config ARCH_R8A7790
|
|
||||||
bool "ARM32 Platform support for R-Car H2"
|
|
||||||
default ARCH_RENESAS
|
|
||||||
select ARCH_RCAR_GEN2
|
|
||||||
select ARM_ERRATA_798181 if SMP
|
|
||||||
select ARM_ERRATA_814220
|
|
||||||
select I2C
|
|
||||||
select SYSC_R8A7790
|
|
||||||
|
|
||||||
config ARCH_R8A7778
|
|
||||||
bool "ARM32 Platform support for R-Car M1A"
|
|
||||||
default ARCH_RENESAS
|
|
||||||
select ARCH_RCAR_GEN1
|
|
||||||
select ARM_ERRATA_754322
|
|
||||||
|
|
||||||
config ARCH_R8A7793
|
|
||||||
bool "ARM32 Platform support for R-Car M2-N"
|
|
||||||
default ARCH_RENESAS
|
|
||||||
select ARCH_RCAR_GEN2
|
|
||||||
select ARM_ERRATA_798181 if SMP
|
|
||||||
select I2C
|
|
||||||
select SYSC_R8A7791
|
|
||||||
|
|
||||||
config ARCH_R8A7791
|
|
||||||
bool "ARM32 Platform support for R-Car M2-W"
|
|
||||||
default ARCH_RENESAS
|
|
||||||
select ARCH_RCAR_GEN2
|
|
||||||
select ARM_ERRATA_798181 if SMP
|
|
||||||
select I2C
|
|
||||||
select SYSC_R8A7791
|
|
||||||
|
|
||||||
config ARCH_R8A7792
|
|
||||||
bool "ARM32 Platform support for R-Car V2H"
|
|
||||||
default ARCH_RENESAS
|
|
||||||
select ARCH_RCAR_GEN2
|
|
||||||
select ARM_ERRATA_798181 if SMP
|
|
||||||
select SYSC_R8A7792
|
|
||||||
|
|
||||||
config ARCH_R8A7740
|
|
||||||
bool "ARM32 Platform support for R-Mobile A1"
|
|
||||||
default ARCH_RENESAS
|
|
||||||
select ARCH_RMOBILE
|
|
||||||
select ARM_ERRATA_754322
|
|
||||||
select RENESAS_INTC_IRQPIN
|
|
||||||
|
|
||||||
config ARCH_R8A73A4
|
|
||||||
bool "ARM32 Platform support for R-Mobile APE6"
|
|
||||||
default ARCH_RENESAS
|
|
||||||
select ARCH_RMOBILE
|
|
||||||
select ARM_ERRATA_798181 if SMP
|
|
||||||
select ARM_ERRATA_814220
|
|
||||||
select HAVE_ARM_ARCH_TIMER
|
|
||||||
select RENESAS_IRQC
|
|
||||||
|
|
||||||
config ARCH_R7S72100
|
config ARCH_R7S72100
|
||||||
bool "ARM32 Platform support for RZ/A1H"
|
bool "ARM32 Platform support for R7S72100 (RZ/A1H)"
|
||||||
default ARCH_RENESAS
|
default ARCH_RENESAS
|
||||||
select ARM_ERRATA_754322
|
select ARM_ERRATA_754322
|
||||||
select PM
|
select PM
|
||||||
@ -151,29 +80,31 @@ config ARCH_R7S72100
|
|||||||
select SYS_SUPPORTS_SH_MTU2
|
select SYS_SUPPORTS_SH_MTU2
|
||||||
|
|
||||||
config ARCH_R7S9210
|
config ARCH_R7S9210
|
||||||
bool "ARM32 Platform support for RZ/A2"
|
bool "ARM32 Platform support for R7S9210 (RZ/A2)"
|
||||||
default ARCH_RENESAS
|
default ARCH_RENESAS
|
||||||
select PM
|
select PM
|
||||||
select PM_GENERIC_DOMAINS
|
select PM_GENERIC_DOMAINS
|
||||||
select RENESAS_OSTM
|
select RENESAS_OSTM
|
||||||
select RENESAS_RZA1_IRQC
|
select RENESAS_RZA1_IRQC
|
||||||
|
|
||||||
config ARCH_R8A77470
|
config ARCH_R8A73A4
|
||||||
bool "ARM32 Platform support for RZ/G1C"
|
bool "ARM32 Platform support for R8A73A4 (R-Mobile APE6)"
|
||||||
default ARCH_RENESAS
|
default ARCH_RENESAS
|
||||||
select ARCH_RCAR_GEN2
|
select ARCH_RMOBILE
|
||||||
|
select ARM_ERRATA_798181 if SMP
|
||||||
select ARM_ERRATA_814220
|
select ARM_ERRATA_814220
|
||||||
select SYSC_R8A77470
|
select HAVE_ARM_ARCH_TIMER
|
||||||
|
select RENESAS_IRQC
|
||||||
|
|
||||||
config ARCH_R8A7745
|
config ARCH_R8A7740
|
||||||
bool "ARM32 Platform support for RZ/G1E"
|
bool "ARM32 Platform support for R8A7740 (R-Mobile A1)"
|
||||||
default ARCH_RENESAS
|
default ARCH_RENESAS
|
||||||
select ARCH_RCAR_GEN2
|
select ARCH_RMOBILE
|
||||||
select ARM_ERRATA_814220
|
select ARM_ERRATA_754322
|
||||||
select SYSC_R8A7745
|
select RENESAS_INTC_IRQPIN
|
||||||
|
|
||||||
config ARCH_R8A7742
|
config ARCH_R8A7742
|
||||||
bool "ARM32 Platform support for RZ/G1H"
|
bool "ARM32 Platform support for R8A7742 (RZ/G1H)"
|
||||||
default ARCH_RENESAS
|
default ARCH_RENESAS
|
||||||
select ARCH_RCAR_GEN2
|
select ARCH_RCAR_GEN2
|
||||||
select ARM_ERRATA_798181 if SMP
|
select ARM_ERRATA_798181 if SMP
|
||||||
@ -181,27 +112,96 @@ config ARCH_R8A7742
|
|||||||
select SYSC_R8A7742
|
select SYSC_R8A7742
|
||||||
|
|
||||||
config ARCH_R8A7743
|
config ARCH_R8A7743
|
||||||
bool "ARM32 Platform support for RZ/G1M"
|
bool "ARM32 Platform support for R8A7743 (RZ/G1M)"
|
||||||
default ARCH_RENESAS
|
default ARCH_RENESAS
|
||||||
select ARCH_RCAR_GEN2
|
select ARCH_RCAR_GEN2
|
||||||
select ARM_ERRATA_798181 if SMP
|
select ARM_ERRATA_798181 if SMP
|
||||||
select SYSC_R8A7743
|
select SYSC_R8A7743
|
||||||
|
|
||||||
config ARCH_R8A7744
|
config ARCH_R8A7744
|
||||||
bool "ARM32 Platform support for RZ/G1N"
|
bool "ARM32 Platform support for R8A7744 (RZ/G1N)"
|
||||||
default ARCH_RENESAS
|
default ARCH_RENESAS
|
||||||
select ARCH_RCAR_GEN2
|
select ARCH_RCAR_GEN2
|
||||||
select ARM_ERRATA_798181 if SMP
|
select ARM_ERRATA_798181 if SMP
|
||||||
select SYSC_R8A7743
|
select SYSC_R8A7743
|
||||||
|
|
||||||
|
config ARCH_R8A7745
|
||||||
|
bool "ARM32 Platform support for R8A7745 (RZ/G1E)"
|
||||||
|
default ARCH_RENESAS
|
||||||
|
select ARCH_RCAR_GEN2
|
||||||
|
select ARM_ERRATA_814220
|
||||||
|
select SYSC_R8A7745
|
||||||
|
|
||||||
|
config ARCH_R8A77470
|
||||||
|
bool "ARM32 Platform support for R8A77470 (RZ/G1C)"
|
||||||
|
default ARCH_RENESAS
|
||||||
|
select ARCH_RCAR_GEN2
|
||||||
|
select ARM_ERRATA_814220
|
||||||
|
select SYSC_R8A77470
|
||||||
|
|
||||||
|
config ARCH_R8A7778
|
||||||
|
bool "ARM32 Platform support for R8A7778 (R-Car M1A)"
|
||||||
|
default ARCH_RENESAS
|
||||||
|
select ARCH_RCAR_GEN1
|
||||||
|
select ARM_ERRATA_754322
|
||||||
|
|
||||||
|
config ARCH_R8A7779
|
||||||
|
bool "ARM32 Platform support for R8A7779 (R-Car H1)"
|
||||||
|
default ARCH_RENESAS
|
||||||
|
select ARCH_RCAR_GEN1
|
||||||
|
select ARM_ERRATA_754322
|
||||||
|
select ARM_GLOBAL_TIMER
|
||||||
|
select HAVE_ARM_SCU if SMP
|
||||||
|
select HAVE_ARM_TWD if SMP
|
||||||
|
select SYSC_R8A7779
|
||||||
|
|
||||||
|
config ARCH_R8A7790
|
||||||
|
bool "ARM32 Platform support for R8A7790 (R-Car H2)"
|
||||||
|
default ARCH_RENESAS
|
||||||
|
select ARCH_RCAR_GEN2
|
||||||
|
select ARM_ERRATA_798181 if SMP
|
||||||
|
select ARM_ERRATA_814220
|
||||||
|
select I2C
|
||||||
|
select SYSC_R8A7790
|
||||||
|
|
||||||
|
config ARCH_R8A7791
|
||||||
|
bool "ARM32 Platform support for R8A7791 (R-Car M2-W)"
|
||||||
|
default ARCH_RENESAS
|
||||||
|
select ARCH_RCAR_GEN2
|
||||||
|
select ARM_ERRATA_798181 if SMP
|
||||||
|
select I2C
|
||||||
|
select SYSC_R8A7791
|
||||||
|
|
||||||
|
config ARCH_R8A7792
|
||||||
|
bool "ARM32 Platform support for R8A7792 (R-Car V2H)"
|
||||||
|
default ARCH_RENESAS
|
||||||
|
select ARCH_RCAR_GEN2
|
||||||
|
select ARM_ERRATA_798181 if SMP
|
||||||
|
select SYSC_R8A7792
|
||||||
|
|
||||||
|
config ARCH_R8A7793
|
||||||
|
bool "ARM32 Platform support for R8A7793 (R-Car M2-N)"
|
||||||
|
default ARCH_RENESAS
|
||||||
|
select ARCH_RCAR_GEN2
|
||||||
|
select ARM_ERRATA_798181 if SMP
|
||||||
|
select I2C
|
||||||
|
select SYSC_R8A7791
|
||||||
|
|
||||||
|
config ARCH_R8A7794
|
||||||
|
bool "ARM32 Platform support for R8A7794 (R-Car E2)"
|
||||||
|
default ARCH_RENESAS
|
||||||
|
select ARCH_RCAR_GEN2
|
||||||
|
select ARM_ERRATA_814220
|
||||||
|
select SYSC_R8A7794
|
||||||
|
|
||||||
config ARCH_R9A06G032
|
config ARCH_R9A06G032
|
||||||
bool "ARM32 Platform support for RZ/N1D"
|
bool "ARM32 Platform support for R9A06G032 (RZ/N1D)"
|
||||||
default ARCH_RENESAS
|
default ARCH_RENESAS
|
||||||
select ARCH_RZN1
|
select ARCH_RZN1
|
||||||
select ARM_ERRATA_814220
|
select ARM_ERRATA_814220
|
||||||
|
|
||||||
config ARCH_SH73A0
|
config ARCH_SH73A0
|
||||||
bool "ARM32 Platform support for SH-Mobile AG5"
|
bool "ARM32 Platform support for SH73A0 (SH-Mobile AG5)"
|
||||||
default ARCH_RENESAS
|
default ARCH_RENESAS
|
||||||
select ARCH_RMOBILE
|
select ARCH_RMOBILE
|
||||||
select ARM_ERRATA_754322
|
select ARM_ERRATA_754322
|
||||||
@ -214,26 +214,40 @@ endif # ARM
|
|||||||
|
|
||||||
if ARM64
|
if ARM64
|
||||||
|
|
||||||
config ARCH_R8A77995
|
config ARCH_R8A774A1
|
||||||
bool "ARM64 Platform support for R-Car D3"
|
bool "ARM64 Platform support for R8A774A1 (RZ/G2M)"
|
||||||
default y if ARCH_RENESAS
|
default y if ARCH_RENESAS
|
||||||
select ARCH_RCAR_GEN3
|
select ARCH_RCAR_GEN3
|
||||||
select SYSC_R8A77995
|
select SYSC_R8A774A1
|
||||||
help
|
help
|
||||||
This enables support for the Renesas R-Car D3 SoC.
|
This enables support for the Renesas RZ/G2M SoC.
|
||||||
This includes different gradings like R-Car D3e.
|
|
||||||
|
|
||||||
config ARCH_R8A77990
|
config ARCH_R8A774B1
|
||||||
bool "ARM64 Platform support for R-Car E3"
|
bool "ARM64 Platform support for R8A774B1 (RZ/G2N)"
|
||||||
default y if ARCH_RENESAS
|
default y if ARCH_RENESAS
|
||||||
select ARCH_RCAR_GEN3
|
select ARCH_RCAR_GEN3
|
||||||
select SYSC_R8A77990
|
select SYSC_R8A774B1
|
||||||
help
|
help
|
||||||
This enables support for the Renesas R-Car E3 SoC.
|
This enables support for the Renesas RZ/G2N SoC.
|
||||||
This includes different gradings like R-Car E3e.
|
|
||||||
|
config ARCH_R8A774C0
|
||||||
|
bool "ARM64 Platform support for R8A774C0 (RZ/G2E)"
|
||||||
|
default y if ARCH_RENESAS
|
||||||
|
select ARCH_RCAR_GEN3
|
||||||
|
select SYSC_R8A774C0
|
||||||
|
help
|
||||||
|
This enables support for the Renesas RZ/G2E SoC.
|
||||||
|
|
||||||
|
config ARCH_R8A774E1
|
||||||
|
bool "ARM64 Platform support for R8A774E1 (RZ/G2H)"
|
||||||
|
default y if ARCH_RENESAS
|
||||||
|
select ARCH_RCAR_GEN3
|
||||||
|
select SYSC_R8A774E1
|
||||||
|
help
|
||||||
|
This enables support for the Renesas RZ/G2H SoC.
|
||||||
|
|
||||||
config ARCH_R8A77951
|
config ARCH_R8A77951
|
||||||
bool "ARM64 Platform support for R-Car H3 ES2.0+"
|
bool "ARM64 Platform support for R8A77951 (R-Car H3 ES2.0+)"
|
||||||
default y if ARCH_RENESAS
|
default y if ARCH_RENESAS
|
||||||
select ARCH_RCAR_GEN3
|
select ARCH_RCAR_GEN3
|
||||||
select SYSC_R8A7795
|
select SYSC_R8A7795
|
||||||
@ -242,17 +256,8 @@ config ARCH_R8A77951
|
|||||||
later).
|
later).
|
||||||
This includes different gradings like R-Car H3e, H3e-2G, and H3Ne.
|
This includes different gradings like R-Car H3e, H3e-2G, and H3Ne.
|
||||||
|
|
||||||
config ARCH_R8A77965
|
|
||||||
bool "ARM64 Platform support for R-Car M3-N"
|
|
||||||
default y if ARCH_RENESAS
|
|
||||||
select ARCH_RCAR_GEN3
|
|
||||||
select SYSC_R8A77965
|
|
||||||
help
|
|
||||||
This enables support for the Renesas R-Car M3-N SoC.
|
|
||||||
This includes different gradings like R-Car M3Ne and M3Ne-2G.
|
|
||||||
|
|
||||||
config ARCH_R8A77960
|
config ARCH_R8A77960
|
||||||
bool "ARM64 Platform support for R-Car M3-W"
|
bool "ARM64 Platform support for R8A77960 (R-Car M3-W)"
|
||||||
default y if ARCH_RENESAS
|
default y if ARCH_RENESAS
|
||||||
select ARCH_RCAR_GEN3
|
select ARCH_RCAR_GEN3
|
||||||
select SYSC_R8A77960
|
select SYSC_R8A77960
|
||||||
@ -260,7 +265,7 @@ config ARCH_R8A77960
|
|||||||
This enables support for the Renesas R-Car M3-W SoC.
|
This enables support for the Renesas R-Car M3-W SoC.
|
||||||
|
|
||||||
config ARCH_R8A77961
|
config ARCH_R8A77961
|
||||||
bool "ARM64 Platform support for R-Car M3-W+"
|
bool "ARM64 Platform support for R8A77961 (R-Car M3-W+)"
|
||||||
default y if ARCH_RENESAS
|
default y if ARCH_RENESAS
|
||||||
select ARCH_RCAR_GEN3
|
select ARCH_RCAR_GEN3
|
||||||
select SYSC_R8A77961
|
select SYSC_R8A77961
|
||||||
@ -268,40 +273,67 @@ config ARCH_R8A77961
|
|||||||
This enables support for the Renesas R-Car M3-W+ SoC.
|
This enables support for the Renesas R-Car M3-W+ SoC.
|
||||||
This includes different gradings like R-Car M3e and M3e-2G.
|
This includes different gradings like R-Car M3e and M3e-2G.
|
||||||
|
|
||||||
config ARCH_R8A779F0
|
config ARCH_R8A77965
|
||||||
bool "ARM64 Platform support for R-Car S4-8"
|
bool "ARM64 Platform support for R8A77965 (R-Car M3-N)"
|
||||||
default y if ARCH_RENESAS
|
|
||||||
select ARCH_RCAR_GEN4
|
|
||||||
select SYSC_R8A779F0
|
|
||||||
help
|
|
||||||
This enables support for the Renesas R-Car S4-8 SoC.
|
|
||||||
|
|
||||||
config ARCH_R8A77980
|
|
||||||
bool "ARM64 Platform support for R-Car V3H"
|
|
||||||
default y if ARCH_RENESAS
|
default y if ARCH_RENESAS
|
||||||
select ARCH_RCAR_GEN3
|
select ARCH_RCAR_GEN3
|
||||||
select SYSC_R8A77980
|
select SYSC_R8A77965
|
||||||
help
|
help
|
||||||
This enables support for the Renesas R-Car V3H SoC.
|
This enables support for the Renesas R-Car M3-N SoC.
|
||||||
|
This includes different gradings like R-Car M3Ne and M3Ne-2G.
|
||||||
|
|
||||||
config ARCH_R8A77970
|
config ARCH_R8A77970
|
||||||
bool "ARM64 Platform support for R-Car V3M"
|
bool "ARM64 Platform support for R8A77970 (R-Car V3M)"
|
||||||
default y if ARCH_RENESAS
|
default y if ARCH_RENESAS
|
||||||
select ARCH_RCAR_GEN3
|
select ARCH_RCAR_GEN3
|
||||||
select SYSC_R8A77970
|
select SYSC_R8A77970
|
||||||
help
|
help
|
||||||
This enables support for the Renesas R-Car V3M SoC.
|
This enables support for the Renesas R-Car V3M SoC.
|
||||||
|
|
||||||
|
config ARCH_R8A77980
|
||||||
|
bool "ARM64 Platform support for R8A77980 (R-Car V3H)"
|
||||||
|
default y if ARCH_RENESAS
|
||||||
|
select ARCH_RCAR_GEN3
|
||||||
|
select SYSC_R8A77980
|
||||||
|
help
|
||||||
|
This enables support for the Renesas R-Car V3H SoC.
|
||||||
|
|
||||||
|
config ARCH_R8A77990
|
||||||
|
bool "ARM64 Platform support for R8A77990 (R-Car E3)"
|
||||||
|
default y if ARCH_RENESAS
|
||||||
|
select ARCH_RCAR_GEN3
|
||||||
|
select SYSC_R8A77990
|
||||||
|
help
|
||||||
|
This enables support for the Renesas R-Car E3 SoC.
|
||||||
|
This includes different gradings like R-Car E3e.
|
||||||
|
|
||||||
|
config ARCH_R8A77995
|
||||||
|
bool "ARM64 Platform support for R8A77995 (R-Car D3)"
|
||||||
|
default y if ARCH_RENESAS
|
||||||
|
select ARCH_RCAR_GEN3
|
||||||
|
select SYSC_R8A77995
|
||||||
|
help
|
||||||
|
This enables support for the Renesas R-Car D3 SoC.
|
||||||
|
This includes different gradings like R-Car D3e.
|
||||||
|
|
||||||
config ARCH_R8A779A0
|
config ARCH_R8A779A0
|
||||||
bool "ARM64 Platform support for R-Car V3U"
|
bool "ARM64 Platform support for R8A779A0 (R-Car V3U)"
|
||||||
default y if ARCH_RENESAS
|
default y if ARCH_RENESAS
|
||||||
select ARCH_RCAR_GEN4
|
select ARCH_RCAR_GEN4
|
||||||
select SYSC_R8A779A0
|
select SYSC_R8A779A0
|
||||||
help
|
help
|
||||||
This enables support for the Renesas R-Car V3U SoC.
|
This enables support for the Renesas R-Car V3U SoC.
|
||||||
|
|
||||||
|
config ARCH_R8A779F0
|
||||||
|
bool "ARM64 Platform support for R8A779F0 (R-Car S4-8)"
|
||||||
|
default y if ARCH_RENESAS
|
||||||
|
select ARCH_RCAR_GEN4
|
||||||
|
select SYSC_R8A779F0
|
||||||
|
help
|
||||||
|
This enables support for the Renesas R-Car S4-8 SoC.
|
||||||
|
|
||||||
config ARCH_R8A779G0
|
config ARCH_R8A779G0
|
||||||
bool "ARM64 Platform support for R-Car V4H"
|
bool "ARM64 Platform support for R8A779G0 (R-Car V4H)"
|
||||||
default y if ARCH_RENESAS
|
default y if ARCH_RENESAS
|
||||||
select ARCH_RCAR_GEN4
|
select ARCH_RCAR_GEN4
|
||||||
select SYSC_R8A779G0
|
select SYSC_R8A779G0
|
||||||
@ -309,68 +341,36 @@ config ARCH_R8A779G0
|
|||||||
This enables support for the Renesas R-Car V4H SoC.
|
This enables support for the Renesas R-Car V4H SoC.
|
||||||
|
|
||||||
config ARCH_R8A779H0
|
config ARCH_R8A779H0
|
||||||
bool "ARM64 Platform support for R-Car V4M"
|
bool "ARM64 Platform support for R8A779H0 (R-Car V4M)"
|
||||||
default y if ARCH_RENESAS
|
default y if ARCH_RENESAS
|
||||||
select ARCH_RCAR_GEN4
|
select ARCH_RCAR_GEN4
|
||||||
select SYSC_R8A779H0
|
select SYSC_R8A779H0
|
||||||
help
|
help
|
||||||
This enables support for the Renesas R-Car V4M SoC.
|
This enables support for the Renesas R-Car V4M SoC.
|
||||||
|
|
||||||
config ARCH_R8A774C0
|
|
||||||
bool "ARM64 Platform support for RZ/G2E"
|
|
||||||
default y if ARCH_RENESAS
|
|
||||||
select ARCH_RCAR_GEN3
|
|
||||||
select SYSC_R8A774C0
|
|
||||||
help
|
|
||||||
This enables support for the Renesas RZ/G2E SoC.
|
|
||||||
|
|
||||||
config ARCH_R8A774E1
|
|
||||||
bool "ARM64 Platform support for RZ/G2H"
|
|
||||||
default y if ARCH_RENESAS
|
|
||||||
select ARCH_RCAR_GEN3
|
|
||||||
select SYSC_R8A774E1
|
|
||||||
help
|
|
||||||
This enables support for the Renesas RZ/G2H SoC.
|
|
||||||
|
|
||||||
config ARCH_R8A774A1
|
|
||||||
bool "ARM64 Platform support for RZ/G2M"
|
|
||||||
default y if ARCH_RENESAS
|
|
||||||
select ARCH_RCAR_GEN3
|
|
||||||
select SYSC_R8A774A1
|
|
||||||
help
|
|
||||||
This enables support for the Renesas RZ/G2M SoC.
|
|
||||||
|
|
||||||
config ARCH_R8A774B1
|
|
||||||
bool "ARM64 Platform support for RZ/G2N"
|
|
||||||
default y if ARCH_RENESAS
|
|
||||||
select ARCH_RCAR_GEN3
|
|
||||||
select SYSC_R8A774B1
|
|
||||||
help
|
|
||||||
This enables support for the Renesas RZ/G2N SoC.
|
|
||||||
|
|
||||||
config ARCH_R9A07G043
|
config ARCH_R9A07G043
|
||||||
bool "ARM64 Platform support for RZ/G2UL"
|
bool "ARM64 Platform support for R9A07G043U (RZ/G2UL)"
|
||||||
default y if ARCH_RENESAS
|
default y if ARCH_RENESAS
|
||||||
select ARCH_RZG2L
|
select ARCH_RZG2L
|
||||||
help
|
help
|
||||||
This enables support for the Renesas RZ/G2UL SoC variants.
|
This enables support for the Renesas RZ/G2UL SoC variants.
|
||||||
|
|
||||||
config ARCH_R9A07G044
|
config ARCH_R9A07G044
|
||||||
bool "ARM64 Platform support for RZ/G2L"
|
bool "ARM64 Platform support for R9A07G044 (RZ/G2L)"
|
||||||
default y if ARCH_RENESAS
|
default y if ARCH_RENESAS
|
||||||
select ARCH_RZG2L
|
select ARCH_RZG2L
|
||||||
help
|
help
|
||||||
This enables support for the Renesas RZ/G2L SoC variants.
|
This enables support for the Renesas RZ/G2L SoC variants.
|
||||||
|
|
||||||
config ARCH_R9A07G054
|
config ARCH_R9A07G054
|
||||||
bool "ARM64 Platform support for RZ/V2L"
|
bool "ARM64 Platform support for R9A07G054 (RZ/V2L)"
|
||||||
default y if ARCH_RENESAS
|
default y if ARCH_RENESAS
|
||||||
select ARCH_RZG2L
|
select ARCH_RZG2L
|
||||||
help
|
help
|
||||||
This enables support for the Renesas RZ/V2L SoC variants.
|
This enables support for the Renesas RZ/V2L SoC variants.
|
||||||
|
|
||||||
config ARCH_R9A08G045
|
config ARCH_R9A08G045
|
||||||
bool "ARM64 Platform support for RZ/G3S"
|
bool "ARM64 Platform support for R9A08G045 (RZ/G3S)"
|
||||||
default y if ARCH_RENESAS
|
default y if ARCH_RENESAS
|
||||||
select ARCH_RZG2L
|
select ARCH_RZG2L
|
||||||
select SYSC_R9A08G045
|
select SYSC_R9A08G045
|
||||||
@ -378,7 +378,7 @@ config ARCH_R9A08G045
|
|||||||
This enables support for the Renesas RZ/G3S SoC variants.
|
This enables support for the Renesas RZ/G3S SoC variants.
|
||||||
|
|
||||||
config ARCH_R9A09G011
|
config ARCH_R9A09G011
|
||||||
bool "ARM64 Platform support for RZ/V2M"
|
bool "ARM64 Platform support for R9A09G011 (RZ/V2M)"
|
||||||
default y if ARCH_RENESAS
|
default y if ARCH_RENESAS
|
||||||
select PM
|
select PM
|
||||||
select PM_GENERIC_DOMAINS
|
select PM_GENERIC_DOMAINS
|
||||||
@ -387,33 +387,45 @@ config ARCH_R9A09G011
|
|||||||
This enables support for the Renesas RZ/V2M SoC.
|
This enables support for the Renesas RZ/V2M SoC.
|
||||||
|
|
||||||
config ARCH_R9A09G047
|
config ARCH_R9A09G047
|
||||||
bool "ARM64 Platform support for RZ/G3E"
|
bool "ARM64 Platform support for R9A09G047 (RZ/G3E)"
|
||||||
default y if ARCH_RENESAS
|
default y if ARCH_RENESAS
|
||||||
select SYS_R9A09G047
|
select SYS_R9A09G047
|
||||||
help
|
help
|
||||||
This enables support for the Renesas RZ/G3E SoC variants.
|
This enables support for the Renesas RZ/G3E SoC variants.
|
||||||
|
|
||||||
config ARCH_R9A09G056
|
config ARCH_R9A09G056
|
||||||
bool "ARM64 Platform support for RZ/V2N"
|
bool "ARM64 Platform support for R9A09G056 (RZ/V2N)"
|
||||||
default y if ARCH_RENESAS
|
default y if ARCH_RENESAS
|
||||||
select SYS_R9A09G056
|
select SYS_R9A09G056
|
||||||
help
|
help
|
||||||
This enables support for the Renesas RZ/V2N SoC variants.
|
This enables support for the Renesas RZ/V2N SoC variants.
|
||||||
|
|
||||||
config ARCH_R9A09G057
|
config ARCH_R9A09G057
|
||||||
bool "ARM64 Platform support for RZ/V2H(P)"
|
bool "ARM64 Platform support for R9A09G057 (RZ/V2H(P))"
|
||||||
default y if ARCH_RENESAS
|
default y if ARCH_RENESAS
|
||||||
select RENESAS_RZV2H_ICU
|
select RENESAS_RZV2H_ICU
|
||||||
select SYS_R9A09G057
|
select SYS_R9A09G057
|
||||||
help
|
help
|
||||||
This enables support for the Renesas RZ/V2H(P) SoC variants.
|
This enables support for the Renesas RZ/V2H(P) SoC variants.
|
||||||
|
|
||||||
|
config ARCH_R9A09G077
|
||||||
|
bool "ARM64 Platform support for R9A09G077 (RZ/T2H)"
|
||||||
|
default y if ARCH_RENESAS
|
||||||
|
help
|
||||||
|
This enables support for the Renesas RZ/T2H SoC variants.
|
||||||
|
|
||||||
|
config ARCH_R9A09G087
|
||||||
|
bool "ARM64 Platform support for R9A09G087 (RZ/N2H)"
|
||||||
|
default y if ARCH_RENESAS
|
||||||
|
help
|
||||||
|
This enables support for the Renesas RZ/N2H SoC variants.
|
||||||
|
|
||||||
endif # ARM64
|
endif # ARM64
|
||||||
|
|
||||||
if RISCV
|
if RISCV
|
||||||
|
|
||||||
config ARCH_R9A07G043
|
config ARCH_R9A07G043
|
||||||
bool "RISC-V Platform support for RZ/Five"
|
bool "RISC-V Platform support for R9A07G043F (RZ/Five)"
|
||||||
depends on NONPORTABLE
|
depends on NONPORTABLE
|
||||||
depends on !DMA_DIRECT_REMAP
|
depends on !DMA_DIRECT_REMAP
|
||||||
depends on RISCV_ALTERNATIVE
|
depends on RISCV_ALTERNATIVE
|
||||||
@ -439,19 +451,19 @@ config SYSC_RZ
|
|||||||
bool "System controller for RZ SoCs" if COMPILE_TEST
|
bool "System controller for RZ SoCs" if COMPILE_TEST
|
||||||
|
|
||||||
config SYSC_R9A08G045
|
config SYSC_R9A08G045
|
||||||
bool "Renesas RZ/G3S System controller support" if COMPILE_TEST
|
bool "Renesas System controller support for R9A08G045 (RZ/G3S)" if COMPILE_TEST
|
||||||
select SYSC_RZ
|
select SYSC_RZ
|
||||||
|
|
||||||
config SYS_R9A09G047
|
config SYS_R9A09G047
|
||||||
bool "Renesas RZ/G3E System controller support" if COMPILE_TEST
|
bool "Renesas System controller support for R9A09G047 (RZ/G3E)" if COMPILE_TEST
|
||||||
select SYSC_RZ
|
select SYSC_RZ
|
||||||
|
|
||||||
config SYS_R9A09G056
|
config SYS_R9A09G056
|
||||||
bool "Renesas RZ/V2N System controller support" if COMPILE_TEST
|
bool "Renesas System controller support for R9A09G056 (RZ/V2N)" if COMPILE_TEST
|
||||||
select SYSC_RZ
|
select SYSC_RZ
|
||||||
|
|
||||||
config SYS_R9A09G057
|
config SYS_R9A09G057
|
||||||
bool "Renesas RZ/V2H System controller support" if COMPILE_TEST
|
bool "Renesas System controller support for R9A09G057 (RZ/V2H)" if COMPILE_TEST
|
||||||
select SYSC_RZ
|
select SYSC_RZ
|
||||||
|
|
||||||
endif # SOC_RENESAS
|
endif # SOC_RENESAS
|
||||||
|
@ -24,8 +24,8 @@ struct rzv2m_pwc_priv {
|
|||||||
DECLARE_BITMAP(ch_en_bits, 2);
|
DECLARE_BITMAP(ch_en_bits, 2);
|
||||||
};
|
};
|
||||||
|
|
||||||
static void rzv2m_pwc_gpio_set(struct gpio_chip *chip, unsigned int offset,
|
static int rzv2m_pwc_gpio_set(struct gpio_chip *chip, unsigned int offset,
|
||||||
int value)
|
int value)
|
||||||
{
|
{
|
||||||
struct rzv2m_pwc_priv *priv = gpiochip_get_data(chip);
|
struct rzv2m_pwc_priv *priv = gpiochip_get_data(chip);
|
||||||
u32 reg;
|
u32 reg;
|
||||||
@ -38,6 +38,8 @@ static void rzv2m_pwc_gpio_set(struct gpio_chip *chip, unsigned int offset,
|
|||||||
writel(reg, priv->base + PWC_GPIO);
|
writel(reg, priv->base + PWC_GPIO);
|
||||||
|
|
||||||
assign_bit(offset, priv->ch_en_bits, value);
|
assign_bit(offset, priv->ch_en_bits, value);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rzv2m_pwc_gpio_get(struct gpio_chip *chip, unsigned int offset)
|
static int rzv2m_pwc_gpio_get(struct gpio_chip *chip, unsigned int offset)
|
||||||
@ -62,7 +64,7 @@ static const struct gpio_chip rzv2m_pwc_gc = {
|
|||||||
.label = "gpio_rzv2m_pwc",
|
.label = "gpio_rzv2m_pwc",
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.get = rzv2m_pwc_gpio_get,
|
.get = rzv2m_pwc_gpio_get,
|
||||||
.set = rzv2m_pwc_gpio_set,
|
.set_rv = rzv2m_pwc_gpio_set,
|
||||||
.direction_output = rzv2m_pwc_gpio_direction_output,
|
.direction_output = rzv2m_pwc_gpio_direction_output,
|
||||||
.can_sleep = false,
|
.can_sleep = false,
|
||||||
.ngpio = 2,
|
.ngpio = 2,
|
||||||
|
@ -138,6 +138,14 @@ config ARCH_TEGRA_241_SOC
|
|||||||
help
|
help
|
||||||
Enable support for the NVIDIA Tegra241 SoC.
|
Enable support for the NVIDIA Tegra241 SoC.
|
||||||
|
|
||||||
|
config ARCH_TEGRA_264_SOC
|
||||||
|
bool "NVIDIA Tegra264 SoC"
|
||||||
|
depends on !CPU_BIG_ENDIAN
|
||||||
|
select MAILBOX
|
||||||
|
select SOC_TEGRA_PMC
|
||||||
|
help
|
||||||
|
Enable support for the NVIDIA Tegra264 SoC.
|
||||||
|
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021-2022, NVIDIA CORPORATION. All rights reserved
|
* Copyright (c) 2021-2025, NVIDIA CORPORATION. All rights reserved
|
||||||
*
|
*
|
||||||
* The driver handles Error's from Control Backbone(CBB) generated due to
|
* The driver handles Error's from Control Backbone(CBB) generated due to
|
||||||
* illegal accesses. When an error is reported from a NOC within CBB,
|
* illegal accesses. When an error is reported from a NOC within CBB,
|
||||||
@ -138,7 +138,7 @@ struct tegra194_cbb_userbits {
|
|||||||
struct tegra194_cbb_noc_data {
|
struct tegra194_cbb_noc_data {
|
||||||
const char *name;
|
const char *name;
|
||||||
bool erd_mask_inband_err;
|
bool erd_mask_inband_err;
|
||||||
const char * const *master_id;
|
const char * const *initiator_id;
|
||||||
unsigned int max_aperture;
|
unsigned int max_aperture;
|
||||||
const struct tegra194_cbb_aperture *noc_aperture;
|
const struct tegra194_cbb_aperture *noc_aperture;
|
||||||
const char * const *routeid_initflow;
|
const char * const *routeid_initflow;
|
||||||
@ -216,7 +216,7 @@ static const char * const tegra194_axi2apb_error[] = {
|
|||||||
"CH2RFIFOF - Ch2 Request FIFO Full interrupt"
|
"CH2RFIFOF - Ch2 Request FIFO Full interrupt"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char * const tegra194_master_id[] = {
|
static const char * const tegra194_initiator_id[] = {
|
||||||
[0x0] = "CCPLEX",
|
[0x0] = "CCPLEX",
|
||||||
[0x1] = "CCPLEX_DPMU",
|
[0x1] = "CCPLEX_DPMU",
|
||||||
[0x2] = "BPMP",
|
[0x2] = "BPMP",
|
||||||
@ -238,7 +238,7 @@ static const struct tegra_cbb_error tegra194_cbb_errors[] = {
|
|||||||
{
|
{
|
||||||
.code = "SLV",
|
.code = "SLV",
|
||||||
.source = "Target",
|
.source = "Target",
|
||||||
.desc = "Target error detected by CBB slave"
|
.desc = "Target error detected by CBB target"
|
||||||
}, {
|
}, {
|
||||||
.code = "DEC",
|
.code = "DEC",
|
||||||
.source = "Initiator NIU",
|
.source = "Initiator NIU",
|
||||||
@ -1774,8 +1774,8 @@ static void print_errlog5(struct seq_file *file, struct tegra194_cbb *cbb)
|
|||||||
tegra_cbb_print_err(file, "\t AXI ID\t\t: %#x\n", userbits.axi_id);
|
tegra_cbb_print_err(file, "\t AXI ID\t\t: %#x\n", userbits.axi_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
tegra_cbb_print_err(file, "\t Master ID\t\t: %s\n",
|
tegra_cbb_print_err(file, "\t Initiator ID\t\t: %s\n",
|
||||||
cbb->noc->master_id[userbits.mstr_id]);
|
cbb->noc->initiator_id[userbits.mstr_id]);
|
||||||
tegra_cbb_print_err(file, "\t Security Group(GRPSEC): %#x\n", userbits.grpsec);
|
tegra_cbb_print_err(file, "\t Security Group(GRPSEC): %#x\n", userbits.grpsec);
|
||||||
tegra_cbb_print_cache(file, userbits.axcache);
|
tegra_cbb_print_cache(file, userbits.axcache);
|
||||||
tegra_cbb_print_prot(file, userbits.axprot);
|
tegra_cbb_print_prot(file, userbits.axprot);
|
||||||
@ -1837,14 +1837,14 @@ print_errlog1_2(struct seq_file *file, struct tegra194_cbb *cbb,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Print transcation type, error code and description from ErrLog0 for all
|
* Print transcation type, error code and description from ErrLog0 for all
|
||||||
* errors. For NOC slave errors, all relevant error info is printed using
|
* errors. For NOC target errors, all relevant error info is printed using
|
||||||
* ErrLog0 only. But additional information is printed for errors from
|
* ErrLog0 only. But additional information is printed for errors from
|
||||||
* APB slaves because for them:
|
* APB targets because for them:
|
||||||
* - All errors are logged as SLV(slave) errors due to APB having only single
|
* - All errors are logged as SLV(target) errors due to APB having only single
|
||||||
* bit pslverr to report all errors.
|
* bit pslverr to report all errors.
|
||||||
* - Exact cause is printed by reading DMAAPB_X_RAW_INTERRUPT_STATUS register.
|
* - Exact cause is printed by reading DMAAPB_X_RAW_INTERRUPT_STATUS register.
|
||||||
* - The driver prints information showing AXI2APB bridge and exact error
|
* - The driver prints information showing AXI2APB bridge and exact error
|
||||||
* only if there is error in any AXI2APB slave.
|
* only if there is error in any AXI2APB target.
|
||||||
* - There is still no way to disambiguate a DEC error from SLV error type.
|
* - There is still no way to disambiguate a DEC error from SLV error type.
|
||||||
*/
|
*/
|
||||||
static bool print_errlog0(struct seq_file *file, struct tegra194_cbb *cbb)
|
static bool print_errlog0(struct seq_file *file, struct tegra194_cbb *cbb)
|
||||||
@ -1884,8 +1884,8 @@ static bool print_errlog0(struct seq_file *file, struct tegra194_cbb *cbb)
|
|||||||
/* For all SLV errors, read DMAAPB_X_RAW_INTERRUPT_STATUS
|
/* For all SLV errors, read DMAAPB_X_RAW_INTERRUPT_STATUS
|
||||||
* register to get error status for all AXI2APB bridges.
|
* register to get error status for all AXI2APB bridges.
|
||||||
* Print bridge details if a bit is set in a bridge's
|
* Print bridge details if a bit is set in a bridge's
|
||||||
* status register due to error in a APB slave connected
|
* status register due to error in a APB target connected
|
||||||
* to that bridge. For other NOC slaves, none of the status
|
* to that bridge. For other NOC targets, none of the status
|
||||||
* register will be set.
|
* register will be set.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -2118,7 +2118,7 @@ static const struct tegra_cbb_ops tegra194_cbb_ops = {
|
|||||||
static struct tegra194_cbb_noc_data tegra194_cbb_central_noc_data = {
|
static struct tegra194_cbb_noc_data tegra194_cbb_central_noc_data = {
|
||||||
.name = "cbb-noc",
|
.name = "cbb-noc",
|
||||||
.erd_mask_inband_err = true,
|
.erd_mask_inband_err = true,
|
||||||
.master_id = tegra194_master_id,
|
.initiator_id = tegra194_initiator_id,
|
||||||
.noc_aperture = tegra194_cbbcentralnoc_apert_lookup,
|
.noc_aperture = tegra194_cbbcentralnoc_apert_lookup,
|
||||||
.max_aperture = ARRAY_SIZE(tegra194_cbbcentralnoc_apert_lookup),
|
.max_aperture = ARRAY_SIZE(tegra194_cbbcentralnoc_apert_lookup),
|
||||||
.routeid_initflow = tegra194_cbbcentralnoc_routeid_initflow,
|
.routeid_initflow = tegra194_cbbcentralnoc_routeid_initflow,
|
||||||
@ -2130,7 +2130,7 @@ static struct tegra194_cbb_noc_data tegra194_cbb_central_noc_data = {
|
|||||||
static struct tegra194_cbb_noc_data tegra194_aon_noc_data = {
|
static struct tegra194_cbb_noc_data tegra194_aon_noc_data = {
|
||||||
.name = "aon-noc",
|
.name = "aon-noc",
|
||||||
.erd_mask_inband_err = false,
|
.erd_mask_inband_err = false,
|
||||||
.master_id = tegra194_master_id,
|
.initiator_id = tegra194_initiator_id,
|
||||||
.noc_aperture = tegra194_aonnoc_aperture_lookup,
|
.noc_aperture = tegra194_aonnoc_aperture_lookup,
|
||||||
.max_aperture = ARRAY_SIZE(tegra194_aonnoc_aperture_lookup),
|
.max_aperture = ARRAY_SIZE(tegra194_aonnoc_aperture_lookup),
|
||||||
.routeid_initflow = tegra194_aonnoc_routeid_initflow,
|
.routeid_initflow = tegra194_aonnoc_routeid_initflow,
|
||||||
@ -2142,7 +2142,7 @@ static struct tegra194_cbb_noc_data tegra194_aon_noc_data = {
|
|||||||
static struct tegra194_cbb_noc_data tegra194_bpmp_noc_data = {
|
static struct tegra194_cbb_noc_data tegra194_bpmp_noc_data = {
|
||||||
.name = "bpmp-noc",
|
.name = "bpmp-noc",
|
||||||
.erd_mask_inband_err = false,
|
.erd_mask_inband_err = false,
|
||||||
.master_id = tegra194_master_id,
|
.initiator_id = tegra194_initiator_id,
|
||||||
.noc_aperture = tegra194_bpmpnoc_apert_lookup,
|
.noc_aperture = tegra194_bpmpnoc_apert_lookup,
|
||||||
.max_aperture = ARRAY_SIZE(tegra194_bpmpnoc_apert_lookup),
|
.max_aperture = ARRAY_SIZE(tegra194_bpmpnoc_apert_lookup),
|
||||||
.routeid_initflow = tegra194_bpmpnoc_routeid_initflow,
|
.routeid_initflow = tegra194_bpmpnoc_routeid_initflow,
|
||||||
@ -2154,7 +2154,7 @@ static struct tegra194_cbb_noc_data tegra194_bpmp_noc_data = {
|
|||||||
static struct tegra194_cbb_noc_data tegra194_rce_noc_data = {
|
static struct tegra194_cbb_noc_data tegra194_rce_noc_data = {
|
||||||
.name = "rce-noc",
|
.name = "rce-noc",
|
||||||
.erd_mask_inband_err = false,
|
.erd_mask_inband_err = false,
|
||||||
.master_id = tegra194_master_id,
|
.initiator_id = tegra194_initiator_id,
|
||||||
.noc_aperture = tegra194_scenoc_apert_lookup,
|
.noc_aperture = tegra194_scenoc_apert_lookup,
|
||||||
.max_aperture = ARRAY_SIZE(tegra194_scenoc_apert_lookup),
|
.max_aperture = ARRAY_SIZE(tegra194_scenoc_apert_lookup),
|
||||||
.routeid_initflow = tegra194_scenoc_routeid_initflow,
|
.routeid_initflow = tegra194_scenoc_routeid_initflow,
|
||||||
@ -2166,7 +2166,7 @@ static struct tegra194_cbb_noc_data tegra194_rce_noc_data = {
|
|||||||
static struct tegra194_cbb_noc_data tegra194_sce_noc_data = {
|
static struct tegra194_cbb_noc_data tegra194_sce_noc_data = {
|
||||||
.name = "sce-noc",
|
.name = "sce-noc",
|
||||||
.erd_mask_inband_err = false,
|
.erd_mask_inband_err = false,
|
||||||
.master_id = tegra194_master_id,
|
.initiator_id = tegra194_initiator_id,
|
||||||
.noc_aperture = tegra194_scenoc_apert_lookup,
|
.noc_aperture = tegra194_scenoc_apert_lookup,
|
||||||
.max_aperture = ARRAY_SIZE(tegra194_scenoc_apert_lookup),
|
.max_aperture = ARRAY_SIZE(tegra194_scenoc_apert_lookup),
|
||||||
.routeid_initflow = tegra194_scenoc_routeid_initflow,
|
.routeid_initflow = tegra194_scenoc_routeid_initflow,
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -128,6 +128,7 @@ static const struct of_device_id apbmisc_match[] __initconst = {
|
|||||||
{ .compatible = "nvidia,tegra186-misc", },
|
{ .compatible = "nvidia,tegra186-misc", },
|
||||||
{ .compatible = "nvidia,tegra194-misc", },
|
{ .compatible = "nvidia,tegra194-misc", },
|
||||||
{ .compatible = "nvidia,tegra234-misc", },
|
{ .compatible = "nvidia,tegra234-misc", },
|
||||||
|
{ .compatible = "nvidia,tegra264-misc", },
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2500,8 +2500,7 @@ static int tegra_pmc_irq_init(struct tegra_pmc *pmc)
|
|||||||
pmc->irq.irq_set_type = pmc->soc->irq_set_type;
|
pmc->irq.irq_set_type = pmc->soc->irq_set_type;
|
||||||
pmc->irq.irq_set_wake = pmc->soc->irq_set_wake;
|
pmc->irq.irq_set_wake = pmc->soc->irq_set_wake;
|
||||||
|
|
||||||
pmc->domain = irq_domain_create_hierarchy(parent, 0, 96,
|
pmc->domain = irq_domain_create_hierarchy(parent, 0, 96, dev_fwnode(pmc->dev),
|
||||||
of_fwnode_handle(pmc->dev->of_node),
|
|
||||||
&tegra_pmc_irq_domain_ops, pmc);
|
&tegra_pmc_irq_domain_ops, pmc);
|
||||||
if (!pmc->domain) {
|
if (!pmc->domain) {
|
||||||
dev_err(pmc->dev, "failed to allocate domain\n");
|
dev_err(pmc->dev, "failed to allocate domain\n");
|
||||||
@ -4248,7 +4247,128 @@ static const struct tegra_pmc_soc tegra234_pmc_soc = {
|
|||||||
.has_single_mmio_aperture = false,
|
.has_single_mmio_aperture = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct tegra_pmc_regs tegra264_pmc_regs = {
|
||||||
|
.scratch0 = 0x684,
|
||||||
|
.rst_status = 0x4,
|
||||||
|
.rst_source_shift = 0x2,
|
||||||
|
.rst_source_mask = 0x1fc,
|
||||||
|
.rst_level_shift = 0x0,
|
||||||
|
.rst_level_mask = 0x3,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char * const tegra264_reset_sources[] = {
|
||||||
|
"SYS_RESET_N", /* 0x0 */
|
||||||
|
"CSDC_RTC_XTAL",
|
||||||
|
"VREFRO_POWER_BAD",
|
||||||
|
"SCPM_SOC_XTAL",
|
||||||
|
"SCPM_RTC_XTAL",
|
||||||
|
"FMON_32K",
|
||||||
|
"FMON_OSC",
|
||||||
|
"POD_RTC",
|
||||||
|
"POD_IO", /* 0x8 */
|
||||||
|
"POD_PLUS_IO_SPLL",
|
||||||
|
"POD_PLUS_SOC",
|
||||||
|
"VMON_PLUS_UV",
|
||||||
|
"VMON_PLUS_OV",
|
||||||
|
"FUSECRC_FAULT",
|
||||||
|
"OSC_FAULT",
|
||||||
|
"BPMP_BOOT_FAULT",
|
||||||
|
"SCPM_BPMP_CORE_CLK", /* 0x10 */
|
||||||
|
"SCPM_PSC_SE_CLK",
|
||||||
|
"VMON_SOC_MIN",
|
||||||
|
"VMON_SOC_MAX",
|
||||||
|
"VMON_MSS_MIN",
|
||||||
|
"VMON_MSS_MAX",
|
||||||
|
"POD_PLUS_IO_VMON",
|
||||||
|
"NVJTAG_SEL_MONITOR",
|
||||||
|
"NV_THERM_FAULT", /* 0x18 */
|
||||||
|
"FSI_THERM_FAULT",
|
||||||
|
"PSC_SW",
|
||||||
|
"SCPM_OESP_SE_CLK",
|
||||||
|
"SCPM_SB_SE_CLK",
|
||||||
|
"POD_CPU",
|
||||||
|
"POD_GPU",
|
||||||
|
"DCLS_GPU",
|
||||||
|
"POD_MSS", /* 0x20 */
|
||||||
|
"FMON_FSI",
|
||||||
|
"POD_FSI",
|
||||||
|
"VMON_FSI_MIN",
|
||||||
|
"VMON_FSI_MAX",
|
||||||
|
"VMON_CPU0_MIN",
|
||||||
|
"VMON_CPU0_MAX",
|
||||||
|
"BPMP_FMON",
|
||||||
|
"AO_WDT_POR", /* 0x28 */
|
||||||
|
"BPMP_WDT_POR",
|
||||||
|
"AO_TKE_WDT_POR",
|
||||||
|
"RCE0_WDT_POR",
|
||||||
|
"RCE1_WDT_POR",
|
||||||
|
"DCE_WDT_POR",
|
||||||
|
"FSI_R5_WDT_POR",
|
||||||
|
"FSI_R52_0_WDT_POR",
|
||||||
|
"FSI_R52_1_WDT_POR", /* 0x30 */
|
||||||
|
"FSI_R52_2_WDT_POR",
|
||||||
|
"FSI_R52_3_WDT_POR",
|
||||||
|
"TOP_0_WDT_POR",
|
||||||
|
"TOP_1_WDT_POR",
|
||||||
|
"TOP_2_WDT_POR",
|
||||||
|
"APE_C0_WDT_POR",
|
||||||
|
"APE_C1_WDT_POR",
|
||||||
|
"GPU_TKE_WDT_POR", /* 0x38 */
|
||||||
|
"PSC_WDT_POR",
|
||||||
|
"OESP_WDT_POR",
|
||||||
|
"SB_WDT_POR",
|
||||||
|
"SW_MAIN",
|
||||||
|
"L0L1_RST_OUT_N",
|
||||||
|
"FSI_HSM",
|
||||||
|
"CSITE_SW",
|
||||||
|
"AO_WDT_DBG", /* 0x40 */
|
||||||
|
"BPMP_WDT_DBG",
|
||||||
|
"AO_TKE_WDT_DBG",
|
||||||
|
"RCE0_WDT_DBG",
|
||||||
|
"RCE1_WDT_DBG",
|
||||||
|
"DCE_WDT_DBG",
|
||||||
|
"FSI_R5_WDT_DBG",
|
||||||
|
"FSI_R52_0_WDT_DBG",
|
||||||
|
"FSI_R52_1_WDT_DBG", /* 0x48 */
|
||||||
|
"FSI_R52_2_WDT_DBG",
|
||||||
|
"FSI_R52_3_WDT_DBG",
|
||||||
|
"TOP_0_WDT_DBG",
|
||||||
|
"TOP_1_WDT_DBG",
|
||||||
|
"TOP_2_WDT_DBG",
|
||||||
|
"APE_C0_WDT_DBG",
|
||||||
|
"APE_C1_WDT_DBG",
|
||||||
|
"PSC_WDT_DBG", /* 0x50 */
|
||||||
|
"OESP_WDT_DBG",
|
||||||
|
"SB_WDT_DBG",
|
||||||
|
"TSC_0_WDT_DBG",
|
||||||
|
"TSC_1_WDT_DBG",
|
||||||
|
"L2_RST_OUT_N",
|
||||||
|
"SC7"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct tegra_wake_event tegra264_wake_events[] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct tegra_pmc_soc tegra264_pmc_soc = {
|
||||||
|
.has_impl_33v_pwr = true,
|
||||||
|
.regs = &tegra264_pmc_regs,
|
||||||
|
.init = tegra186_pmc_init,
|
||||||
|
.setup_irq_polarity = tegra186_pmc_setup_irq_polarity,
|
||||||
|
.set_wake_filters = tegra186_pmc_set_wake_filters,
|
||||||
|
.irq_set_wake = tegra186_pmc_irq_set_wake,
|
||||||
|
.irq_set_type = tegra186_pmc_irq_set_type,
|
||||||
|
.reset_sources = tegra264_reset_sources,
|
||||||
|
.num_reset_sources = ARRAY_SIZE(tegra264_reset_sources),
|
||||||
|
.reset_levels = tegra186_reset_levels,
|
||||||
|
.num_reset_levels = ARRAY_SIZE(tegra186_reset_levels),
|
||||||
|
.wake_events = tegra264_wake_events,
|
||||||
|
.num_wake_events = ARRAY_SIZE(tegra264_wake_events),
|
||||||
|
.max_wake_events = 128,
|
||||||
|
.max_wake_vectors = 4,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct of_device_id tegra_pmc_match[] = {
|
static const struct of_device_id tegra_pmc_match[] = {
|
||||||
|
{ .compatible = "nvidia,tegra264-pmc", .data = &tegra264_pmc_soc },
|
||||||
{ .compatible = "nvidia,tegra234-pmc", .data = &tegra234_pmc_soc },
|
{ .compatible = "nvidia,tegra234-pmc", .data = &tegra234_pmc_soc },
|
||||||
{ .compatible = "nvidia,tegra194-pmc", .data = &tegra194_pmc_soc },
|
{ .compatible = "nvidia,tegra194-pmc", .data = &tegra194_pmc_soc },
|
||||||
{ .compatible = "nvidia,tegra186-pmc", .data = &tegra186_pmc_soc },
|
{ .compatible = "nvidia,tegra186-pmc", .data = &tegra186_pmc_soc },
|
||||||
|
@ -279,8 +279,13 @@
|
|||||||
#define QCOM_ID_QCM8550 604
|
#define QCOM_ID_QCM8550 604
|
||||||
#define QCOM_ID_SM8750 618
|
#define QCOM_ID_SM8750 618
|
||||||
#define QCOM_ID_IPQ5300 624
|
#define QCOM_ID_IPQ5300 624
|
||||||
|
#define QCOM_ID_SM7635 636
|
||||||
|
#define QCOM_ID_SM6650 640
|
||||||
|
#define QCOM_ID_SM6650P 641
|
||||||
#define QCOM_ID_IPQ5321 650
|
#define QCOM_ID_IPQ5321 650
|
||||||
#define QCOM_ID_IPQ5424 651
|
#define QCOM_ID_IPQ5424 651
|
||||||
|
#define QCOM_ID_QCM6690 657
|
||||||
|
#define QCOM_ID_QCS6690 658
|
||||||
#define QCOM_ID_IPQ5404 671
|
#define QCOM_ID_IPQ5404 671
|
||||||
#define QCOM_ID_QCS9100 667
|
#define QCOM_ID_QCS9100 667
|
||||||
#define QCOM_ID_QCS8300 674
|
#define QCOM_ID_QCS8300 674
|
||||||
|
90
include/dt-bindings/reset/canaan,k230-rst.h
Normal file
90
include/dt-bindings/reset/canaan,k230-rst.h
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023-2024 Canaan Bright Sight Co., Ltd
|
||||||
|
* Copyright (C) 2024-2025 Junhui Liu <junhui.liu@pigmoral.tech>
|
||||||
|
*/
|
||||||
|
#ifndef _DT_BINDINGS_CANAAN_K230_RST_H_
|
||||||
|
#define _DT_BINDINGS_CANAAN_K230_RST_H_
|
||||||
|
|
||||||
|
#define RST_CPU0 0
|
||||||
|
#define RST_CPU1 1
|
||||||
|
#define RST_CPU0_FLUSH 2
|
||||||
|
#define RST_CPU1_FLUSH 3
|
||||||
|
#define RST_AI 4
|
||||||
|
#define RST_VPU 5
|
||||||
|
#define RST_HISYS 6
|
||||||
|
#define RST_HISYS_AHB 7
|
||||||
|
#define RST_SDIO0 8
|
||||||
|
#define RST_SDIO1 9
|
||||||
|
#define RST_SDIO_AXI 10
|
||||||
|
#define RST_USB0 11
|
||||||
|
#define RST_USB1 12
|
||||||
|
#define RST_USB0_AHB 13
|
||||||
|
#define RST_USB1_AHB 14
|
||||||
|
#define RST_SPI0 15
|
||||||
|
#define RST_SPI1 16
|
||||||
|
#define RST_SPI2 17
|
||||||
|
#define RST_SEC 18
|
||||||
|
#define RST_PDMA 19
|
||||||
|
#define RST_SDMA 20
|
||||||
|
#define RST_DECOMPRESS 21
|
||||||
|
#define RST_SRAM 22
|
||||||
|
#define RST_SHRM_AXIM 23
|
||||||
|
#define RST_SHRM_AXIS 24
|
||||||
|
#define RST_NONAI2D 25
|
||||||
|
#define RST_MCTL 26
|
||||||
|
#define RST_ISP 27
|
||||||
|
#define RST_ISP_DW 28
|
||||||
|
#define RST_DPU 29
|
||||||
|
#define RST_DISP 30
|
||||||
|
#define RST_GPU 31
|
||||||
|
#define RST_AUDIO 32
|
||||||
|
#define RST_TIMER0 33
|
||||||
|
#define RST_TIMER1 34
|
||||||
|
#define RST_TIMER2 35
|
||||||
|
#define RST_TIMER3 36
|
||||||
|
#define RST_TIMER4 37
|
||||||
|
#define RST_TIMER5 38
|
||||||
|
#define RST_TIMER_APB 39
|
||||||
|
#define RST_HDI 40
|
||||||
|
#define RST_WDT0 41
|
||||||
|
#define RST_WDT1 42
|
||||||
|
#define RST_WDT0_APB 43
|
||||||
|
#define RST_WDT1_APB 44
|
||||||
|
#define RST_TS_APB 45
|
||||||
|
#define RST_MAILBOX 46
|
||||||
|
#define RST_STC 47
|
||||||
|
#define RST_PMU 48
|
||||||
|
#define RST_LOSYS_APB 49
|
||||||
|
#define RST_UART0 50
|
||||||
|
#define RST_UART1 51
|
||||||
|
#define RST_UART2 52
|
||||||
|
#define RST_UART3 53
|
||||||
|
#define RST_UART4 54
|
||||||
|
#define RST_I2C0 55
|
||||||
|
#define RST_I2C1 56
|
||||||
|
#define RST_I2C2 57
|
||||||
|
#define RST_I2C3 58
|
||||||
|
#define RST_I2C4 59
|
||||||
|
#define RST_JAMLINK0_APB 60
|
||||||
|
#define RST_JAMLINK1_APB 61
|
||||||
|
#define RST_JAMLINK2_APB 62
|
||||||
|
#define RST_JAMLINK3_APB 63
|
||||||
|
#define RST_CODEC_APB 64
|
||||||
|
#define RST_GPIO_DB 65
|
||||||
|
#define RST_GPIO_APB 66
|
||||||
|
#define RST_ADC 67
|
||||||
|
#define RST_ADC_APB 68
|
||||||
|
#define RST_PWM_APB 69
|
||||||
|
#define RST_SHRM_APB 70
|
||||||
|
#define RST_CSI0 71
|
||||||
|
#define RST_CSI1 72
|
||||||
|
#define RST_CSI2 73
|
||||||
|
#define RST_CSI_DPHY 74
|
||||||
|
#define RST_ISP_AHB 75
|
||||||
|
#define RST_M0 76
|
||||||
|
#define RST_M1 77
|
||||||
|
#define RST_M2 78
|
||||||
|
#define RST_SPI2AXI 79
|
||||||
|
|
||||||
|
#endif
|
@ -148,11 +148,10 @@ bool qcom_scm_lmh_dcvsh_available(void);
|
|||||||
|
|
||||||
int qcom_scm_gpu_init_regs(u32 gpu_req);
|
int qcom_scm_gpu_init_regs(u32 gpu_req);
|
||||||
|
|
||||||
int qcom_scm_shm_bridge_enable(void);
|
int qcom_scm_shm_bridge_create(u64 pfn_and_ns_perm_flags,
|
||||||
int qcom_scm_shm_bridge_create(struct device *dev, u64 pfn_and_ns_perm_flags,
|
|
||||||
u64 ipfn_and_s_perm_flags, u64 size_and_flags,
|
u64 ipfn_and_s_perm_flags, u64 size_and_flags,
|
||||||
u64 ns_vmids, u64 *handle);
|
u64 ns_vmids, u64 *handle);
|
||||||
int qcom_scm_shm_bridge_delete(struct device *dev, u64 handle);
|
int qcom_scm_shm_bridge_delete(u64 handle);
|
||||||
|
|
||||||
#ifdef CONFIG_QCOM_QSEECOM
|
#ifdef CONFIG_QCOM_QSEECOM
|
||||||
|
|
||||||
|
@ -2624,6 +2624,9 @@
|
|||||||
#define PCI_VENDOR_ID_TEKRAM 0x1de1
|
#define PCI_VENDOR_ID_TEKRAM 0x1de1
|
||||||
#define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29
|
#define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29
|
||||||
|
|
||||||
|
#define PCI_VENDOR_ID_RPI 0x1de4
|
||||||
|
#define PCI_DEVICE_ID_RPI_RP1_C0 0x0001
|
||||||
|
|
||||||
#define PCI_VENDOR_ID_ALIBABA 0x1ded
|
#define PCI_VENDOR_ID_ALIBABA 0x1ded
|
||||||
|
|
||||||
#define PCI_VENDOR_ID_CXL 0x1e98
|
#define PCI_VENDOR_ID_CXL 0x1e98
|
||||||
|
@ -24,9 +24,9 @@ struct socket;
|
|||||||
*/
|
*/
|
||||||
struct qmi_header {
|
struct qmi_header {
|
||||||
u8 type;
|
u8 type;
|
||||||
u16 txn_id;
|
__le16 txn_id;
|
||||||
u16 msg_id;
|
__le16 msg_id;
|
||||||
u16 msg_len;
|
__le16 msg_len;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
#define QMI_REQUEST 0
|
#define QMI_REQUEST 0
|
||||||
|
@ -50,6 +50,8 @@
|
|||||||
#define PMR735B_SUBTYPE 0x34
|
#define PMR735B_SUBTYPE 0x34
|
||||||
#define PM6350_SUBTYPE 0x36
|
#define PM6350_SUBTYPE 0x36
|
||||||
#define PM4125_SUBTYPE 0x37
|
#define PM4125_SUBTYPE 0x37
|
||||||
|
#define PMM8650AU_SUBTYPE 0x4e
|
||||||
|
#define PMM8650AU_PSAIL_SUBTYPE 0x4f
|
||||||
|
|
||||||
#define PMI8998_FAB_ID_SMIC 0x11
|
#define PMI8998_FAB_ID_SMIC 0x11
|
||||||
#define PMI8998_FAB_ID_GF 0x30
|
#define PMI8998_FAB_ID_GF 0x30
|
||||||
|
@ -36,8 +36,8 @@ TRACE_EVENT(scmi_fc_call,
|
|||||||
|
|
||||||
TRACE_EVENT(scmi_xfer_begin,
|
TRACE_EVENT(scmi_xfer_begin,
|
||||||
TP_PROTO(int transfer_id, u8 msg_id, u8 protocol_id, u16 seq,
|
TP_PROTO(int transfer_id, u8 msg_id, u8 protocol_id, u16 seq,
|
||||||
bool poll),
|
bool poll, int inflight),
|
||||||
TP_ARGS(transfer_id, msg_id, protocol_id, seq, poll),
|
TP_ARGS(transfer_id, msg_id, protocol_id, seq, poll, inflight),
|
||||||
|
|
||||||
TP_STRUCT__entry(
|
TP_STRUCT__entry(
|
||||||
__field(int, transfer_id)
|
__field(int, transfer_id)
|
||||||
@ -45,6 +45,7 @@ TRACE_EVENT(scmi_xfer_begin,
|
|||||||
__field(u8, protocol_id)
|
__field(u8, protocol_id)
|
||||||
__field(u16, seq)
|
__field(u16, seq)
|
||||||
__field(bool, poll)
|
__field(bool, poll)
|
||||||
|
__field(int, inflight)
|
||||||
),
|
),
|
||||||
|
|
||||||
TP_fast_assign(
|
TP_fast_assign(
|
||||||
@ -53,11 +54,12 @@ TRACE_EVENT(scmi_xfer_begin,
|
|||||||
__entry->protocol_id = protocol_id;
|
__entry->protocol_id = protocol_id;
|
||||||
__entry->seq = seq;
|
__entry->seq = seq;
|
||||||
__entry->poll = poll;
|
__entry->poll = poll;
|
||||||
|
__entry->inflight = inflight;
|
||||||
),
|
),
|
||||||
|
|
||||||
TP_printk("pt=%02X msg_id=%02X seq=%04X transfer_id=%X poll=%u",
|
TP_printk("pt=%02X msg_id=%02X seq=%04X transfer_id=%X poll=%u inflight=%d",
|
||||||
__entry->protocol_id, __entry->msg_id, __entry->seq,
|
__entry->protocol_id, __entry->msg_id, __entry->seq,
|
||||||
__entry->transfer_id, __entry->poll)
|
__entry->transfer_id, __entry->poll, __entry->inflight)
|
||||||
);
|
);
|
||||||
|
|
||||||
TRACE_EVENT(scmi_xfer_response_wait,
|
TRACE_EVENT(scmi_xfer_response_wait,
|
||||||
@ -90,8 +92,8 @@ TRACE_EVENT(scmi_xfer_response_wait,
|
|||||||
|
|
||||||
TRACE_EVENT(scmi_xfer_end,
|
TRACE_EVENT(scmi_xfer_end,
|
||||||
TP_PROTO(int transfer_id, u8 msg_id, u8 protocol_id, u16 seq,
|
TP_PROTO(int transfer_id, u8 msg_id, u8 protocol_id, u16 seq,
|
||||||
int status),
|
int status, int inflight),
|
||||||
TP_ARGS(transfer_id, msg_id, protocol_id, seq, status),
|
TP_ARGS(transfer_id, msg_id, protocol_id, seq, status, inflight),
|
||||||
|
|
||||||
TP_STRUCT__entry(
|
TP_STRUCT__entry(
|
||||||
__field(int, transfer_id)
|
__field(int, transfer_id)
|
||||||
@ -99,6 +101,7 @@ TRACE_EVENT(scmi_xfer_end,
|
|||||||
__field(u8, protocol_id)
|
__field(u8, protocol_id)
|
||||||
__field(u16, seq)
|
__field(u16, seq)
|
||||||
__field(int, status)
|
__field(int, status)
|
||||||
|
__field(int, inflight)
|
||||||
),
|
),
|
||||||
|
|
||||||
TP_fast_assign(
|
TP_fast_assign(
|
||||||
@ -107,11 +110,12 @@ TRACE_EVENT(scmi_xfer_end,
|
|||||||
__entry->protocol_id = protocol_id;
|
__entry->protocol_id = protocol_id;
|
||||||
__entry->seq = seq;
|
__entry->seq = seq;
|
||||||
__entry->status = status;
|
__entry->status = status;
|
||||||
|
__entry->inflight = inflight;
|
||||||
),
|
),
|
||||||
|
|
||||||
TP_printk("pt=%02X msg_id=%02X seq=%04X transfer_id=%X s=%d",
|
TP_printk("pt=%02X msg_id=%02X seq=%04X transfer_id=%X s=%d inflight=%d",
|
||||||
__entry->protocol_id, __entry->msg_id, __entry->seq,
|
__entry->protocol_id, __entry->msg_id, __entry->seq,
|
||||||
__entry->transfer_id, __entry->status)
|
__entry->transfer_id, __entry->status, __entry->inflight)
|
||||||
);
|
);
|
||||||
|
|
||||||
TRACE_EVENT(scmi_rx_done,
|
TRACE_EVENT(scmi_rx_done,
|
||||||
|
Loading…
Reference in New Issue
Block a user