soc: driver updates for 6.18
Lots of platform specific updates for Qualcomm SoCs, including a new TEE subsystem driver for the Qualcomm QTEE firmware interface. Added support for the Apple A11 SoC in drivers that are shared with the M1/M2 series, among more updates for those. Smaller platform specific driver updates for Renesas, ASpeed, Broadcom, Nvidia, Mediatek, Amlogic, TI, Allwinner, and Freescale SoCs. Driver updates in the cache controller, memory controller and reset controller subsystems. SCMI firmware updates to add more features and improve robustness. This includes support for having multiple SCMI providers in a single system. TEE subsystem support for protected DMA-bufs, allowing hardware to access memory areas that managed by the kernel but remain inaccessible from the CPU in EL1/EL0. -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEo6/YBQwIrVS28WGKmmx57+YAGNkFAmjdpaoACgkQmmx57+YA GNnBXA//QgmFXYGG7QfB825mt0orKZxpfpLcwvqO7hkWgbXtl7Gokw2lGYN6bwLu zvY4MQ/bVoZ8R5uTVmuaSHBRsttSen8mBf+V0vzsBM/DRRVxvIN/7TESrY3J7Dtx J5syHKIBiUtdkDebWWC6jIElczIBItsd03Ln4Xjjt8Vas5YOO4n44zFrPo+FwlN/ I6D2K86AiNZTtUCDMtB6VfJ6YtjYBWcWnJm7FXw/vE8FAXdZUnNWnZ8hbdQ5GaME JZGepUhONaOMUoGNZNaDGw511RdPhYzPjj9rCsIx2qdsRO9/4tJ8ccpW2aUMYh8c nA6w8Hj8jCwco6aYYrDUDV9uRtURDrmyJgTJBNLU05e/L+MuJ3IZNlzHFWlsxIAE vhyTdmg/P04ClQyixCl67IH/66F/0smX9C+1761LrD7GTdfR92KPl5W6q+DPBg/x yf+s2p3+f7ItV5XobKOrbf3w0xazeDb5o/EK8BufMx9vSe9bpzJ0gOf0CmNXEpyZ owAhbh6wXX1YwPcyA9LHv6gthyJwc/3fLu49ggMZP2rU01ccKOYn9H0cr7C8NVmy wEpJR0lp5aSw2oRkPkxB6sFmUohcpr8/OXGGJuvCXkYsUY1BEup4lewvbIWK4WoE c84kbbaHsjgFhe3IRlQw3G4KLYQT3jRtF7fH+gPx556BcI6K+lg= =mcZR -----END PGP SIGNATURE----- Merge tag 'soc-drivers-6.18' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc Pull SoC driver updates from Arnd Bergmann: "Lots of platform specific updates for Qualcomm SoCs, including a new TEE subsystem driver for the Qualcomm QTEE firmware interface. Added support for the Apple A11 SoC in drivers that are shared with the M1/M2 series, among more updates for those. Smaller platform specific driver updates for Renesas, ASpeed, Broadcom, Nvidia, Mediatek, Amlogic, TI, Allwinner, and Freescale SoCs. Driver updates in the cache controller, memory controller and reset controller subsystems. SCMI firmware updates to add more features and improve robustness. This includes support for having multiple SCMI providers in a single system. TEE subsystem support for protected DMA-bufs, allowing hardware to access memory areas that managed by the kernel but remain inaccessible from the CPU in EL1/EL0" * tag 'soc-drivers-6.18' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc: (139 commits) soc/fsl/qbman: Use for_each_online_cpu() instead of for_each_cpu() soc: fsl: qe: Drop legacy-of-mm-gpiochip.h header from GPIO driver soc: fsl: qe: Change GPIO driver to a proper platform driver tee: fix register_shm_helper() pmdomain: apple: Add "apple,t8103-pmgr-pwrstate" dt-bindings: spmi: Add Apple A11 and T2 compatible serial: qcom-geni: Load UART qup Firmware from linux side spi: geni-qcom: Load spi qup Firmware from linux side i2c: qcom-geni: Load i2c qup Firmware from linux side soc: qcom: geni-se: Add support to load QUP SE Firmware via Linux subsystem soc: qcom: geni-se: Cleanup register defines and update copyright dt-bindings: qcom: se-common: Add QUP Peripheral-specific properties for I2C, SPI, and SERIAL bus Documentation: tee: Add Qualcomm TEE driver tee: qcom: enable TEE_IOC_SHM_ALLOC ioctl tee: qcom: add primordial object tee: add Qualcomm TEE driver tee: increase TEE_MAX_ARG_SIZE to 4096 tee: add TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF tee: add TEE_IOCTL_PARAM_ATTR_TYPE_UBUF tee: add close_context to TEE driver operation ...pull/1354/merge
commit
38057e3236
|
|
@ -20,19 +20,26 @@ properties:
|
|||
pattern: "^power-management@[0-9a-f]+$"
|
||||
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- apple,s5l8960x-pmgr
|
||||
- apple,t7000-pmgr
|
||||
- apple,s8000-pmgr
|
||||
- apple,t8010-pmgr
|
||||
- apple,t8015-pmgr
|
||||
- apple,t8103-pmgr
|
||||
- apple,t8112-pmgr
|
||||
- apple,t6000-pmgr
|
||||
- const: apple,pmgr
|
||||
- const: syscon
|
||||
- const: simple-mfd
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
# Do not add additional SoC to this list.
|
||||
- apple,s5l8960x-pmgr
|
||||
- apple,t7000-pmgr
|
||||
- apple,s8000-pmgr
|
||||
- apple,t8010-pmgr
|
||||
- apple,t8015-pmgr
|
||||
- apple,t8103-pmgr
|
||||
- apple,t8112-pmgr
|
||||
- apple,t6000-pmgr
|
||||
- const: apple,pmgr
|
||||
- const: syscon
|
||||
- const: simple-mfd
|
||||
- items:
|
||||
- const: apple,t6020-pmgr
|
||||
- const: apple,t8103-pmgr
|
||||
- const: syscon
|
||||
- const: simple-mfd
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ properties:
|
|||
const: 2
|
||||
|
||||
cache-sets:
|
||||
const: 1024
|
||||
enum: [1024, 2048]
|
||||
|
||||
cache-size:
|
||||
enum: [131072, 262144, 524288, 1048576, 2097152]
|
||||
|
|
@ -81,6 +81,10 @@ allOf:
|
|||
const: 2048
|
||||
cache-size:
|
||||
const: 2097152
|
||||
else:
|
||||
properties:
|
||||
cache-sets:
|
||||
const: 1024
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
|
|
|||
|
|
@ -19,12 +19,17 @@ description: |
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- apple,t6000-nco
|
||||
- apple,t8103-nco
|
||||
- apple,t8112-nco
|
||||
- const: apple,nco
|
||||
oneOf:
|
||||
- items:
|
||||
- const: apple,t6020-nco
|
||||
- const: apple,t8103-nco
|
||||
- items:
|
||||
- enum:
|
||||
# Do not add additional SoC to this list.
|
||||
- apple,t6000-nco
|
||||
- apple,t8103-nco
|
||||
- apple,t8112-nco
|
||||
- const: apple,nco
|
||||
|
||||
clocks:
|
||||
description:
|
||||
|
|
|
|||
|
|
@ -35,6 +35,9 @@ properties:
|
|||
- const: apple,t7000-cluster-cpufreq
|
||||
- const: apple,s5l8960x-cluster-cpufreq
|
||||
- const: apple,s5l8960x-cluster-cpufreq
|
||||
- items:
|
||||
- const: apple,t6020-cluster-cpufreq
|
||||
- const: apple,t8112-cluster-cpufreq
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
|
|
|||
|
|
@ -22,12 +22,17 @@ allOf:
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- apple,t6000-admac
|
||||
- apple,t8103-admac
|
||||
- apple,t8112-admac
|
||||
- const: apple,admac
|
||||
oneOf:
|
||||
- items:
|
||||
- const: apple,t6020-admac
|
||||
- const: apple,t8103-admac
|
||||
- items:
|
||||
- enum:
|
||||
# Do not add additional SoC to this list.
|
||||
- apple,t6000-admac
|
||||
- apple,t8103-admac
|
||||
- apple,t8112-admac
|
||||
- const: apple,admac
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ anyOf:
|
|||
|
||||
properties:
|
||||
$nodename:
|
||||
const: scmi
|
||||
pattern: '^scmi(-[0-9]+)?$'
|
||||
|
||||
compatible:
|
||||
oneOf:
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ properties:
|
|||
- qcom,scm-msm8226
|
||||
- qcom,scm-msm8660
|
||||
- qcom,scm-msm8916
|
||||
- qcom,scm-msm8937
|
||||
- qcom,scm-msm8953
|
||||
- qcom,scm-msm8960
|
||||
- qcom,scm-msm8974
|
||||
|
|
@ -134,6 +135,7 @@ allOf:
|
|||
- qcom,scm-msm8226
|
||||
- qcom,scm-msm8660
|
||||
- qcom,scm-msm8916
|
||||
- qcom,scm-msm8937
|
||||
- qcom,scm-msm8953
|
||||
- qcom,scm-msm8960
|
||||
- qcom,scm-msm8974
|
||||
|
|
@ -177,6 +179,7 @@ allOf:
|
|||
- qcom,scm-mdm9607
|
||||
- qcom,scm-msm8226
|
||||
- qcom,scm-msm8916
|
||||
- qcom,scm-msm8937
|
||||
- qcom,scm-msm8953
|
||||
- qcom,scm-msm8974
|
||||
- qcom,scm-msm8976
|
||||
|
|
|
|||
|
|
@ -16,11 +16,17 @@ properties:
|
|||
- apple,agx-g13g
|
||||
- apple,agx-g13s
|
||||
- apple,agx-g14g
|
||||
- apple,agx-g14s
|
||||
- items:
|
||||
- enum:
|
||||
- apple,agx-g13c
|
||||
- apple,agx-g13d
|
||||
- const: apple,agx-g13s
|
||||
- items:
|
||||
- enum:
|
||||
- apple,agx-g14c
|
||||
- apple,agx-g14d
|
||||
- const: apple,agx-g14s
|
||||
|
||||
reg:
|
||||
items:
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ required:
|
|||
|
||||
allOf:
|
||||
- $ref: /schemas/i2c/i2c-controller.yaml#
|
||||
- $ref: /schemas/soc/qcom/qcom,se-common-props.yaml#
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ properties:
|
|||
- enum:
|
||||
- apple,t8112-aic
|
||||
- apple,t6000-aic
|
||||
- apple,t6020-aic
|
||||
- const: apple,aic2
|
||||
|
||||
interrupt-controller: true
|
||||
|
|
|
|||
|
|
@ -22,11 +22,15 @@ description: |+
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- apple,t8103-dart
|
||||
- apple,t8103-usb4-dart
|
||||
- apple,t8110-dart
|
||||
- apple,t6000-dart
|
||||
oneOf:
|
||||
- enum:
|
||||
- apple,t8103-dart
|
||||
- apple,t8103-usb4-dart
|
||||
- apple,t8110-dart
|
||||
- apple,t6000-dart
|
||||
- items:
|
||||
- const: apple,t6020-dart
|
||||
- const: apple,t8110-dart
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
|
|
|||
|
|
@ -30,10 +30,13 @@ properties:
|
|||
compatible:
|
||||
oneOf:
|
||||
- items:
|
||||
- const: apple,t8112-sart
|
||||
- enum:
|
||||
- apple,t6020-sart
|
||||
- apple,t8112-sart
|
||||
- const: apple,t6000-sart
|
||||
- enum:
|
||||
- apple,t6000-sart
|
||||
- apple,t8015-sart
|
||||
- apple,t8103-sart
|
||||
|
||||
reg:
|
||||
|
|
|
|||
|
|
@ -31,8 +31,16 @@ properties:
|
|||
- apple,t8103-asc-mailbox
|
||||
- apple,t8112-asc-mailbox
|
||||
- apple,t6000-asc-mailbox
|
||||
- apple,t6020-asc-mailbox
|
||||
- const: apple,asc-mailbox-v4
|
||||
|
||||
- description:
|
||||
An older ASC mailbox interface found on T2 and A11 that is also
|
||||
used for the NVMe coprocessor and the system management
|
||||
controller.
|
||||
items:
|
||||
- const: apple,t8015-asc-mailbox
|
||||
|
||||
- description:
|
||||
M3 mailboxes are an older variant with a slightly different MMIO
|
||||
interface still found on the M1. It is used for the Thunderbolt
|
||||
|
|
|
|||
|
|
@ -42,6 +42,10 @@ properties:
|
|||
items:
|
||||
- const: brcm,brcmstb-memc-ddr-rev-b.1.x
|
||||
- const: brcm,brcmstb-memc-ddr
|
||||
- description: Revision 0.x controllers
|
||||
items:
|
||||
- const: brcm,brcmstb-memc-ddr-rev-a.0.0
|
||||
- const: brcm,brcmstb-memc-ddr
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
|
|
|||
|
|
@ -33,6 +33,9 @@ properties:
|
|||
items:
|
||||
- description: EMC general interrupt
|
||||
|
||||
"#interconnect-cells":
|
||||
const: 0
|
||||
|
||||
memory-region:
|
||||
maxItems: 1
|
||||
description:
|
||||
|
|
@ -44,6 +47,11 @@ properties:
|
|||
description:
|
||||
phandle of the memory controller node
|
||||
|
||||
operating-points-v2:
|
||||
description:
|
||||
Should contain freqs and voltages and opp-supported-hw property, which
|
||||
is a bitfield indicating SoC speedo ID mask.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
|
@ -79,4 +87,7 @@ examples:
|
|||
interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
|
||||
memory-region = <&emc_table>;
|
||||
nvidia,memory-controller = <&mc>;
|
||||
operating-points-v2 = <&dvfs_opp_table>;
|
||||
|
||||
#interconnect-cells = <0>;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -15,12 +15,17 @@ description:
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- apple,t6000-smc
|
||||
- apple,t8103-smc
|
||||
- apple,t8112-smc
|
||||
- const: apple,smc
|
||||
oneOf:
|
||||
- items:
|
||||
- const: apple,t6020-smc
|
||||
- const: apple,t8103-smc
|
||||
- items:
|
||||
- enum:
|
||||
# Do not add additional SoC to this list.
|
||||
- apple,t6000-smc
|
||||
- apple,t8103-smc
|
||||
- apple,t8112-smc
|
||||
- const: apple,smc
|
||||
|
||||
reg:
|
||||
items:
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ properties:
|
|||
- pci14e4,5fa0 # BCM4377
|
||||
- pci14e4,5f69 # BCM4378
|
||||
- pci14e4,5f71 # BCM4387
|
||||
- pci14e4,5f72 # BCM4388
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ properties:
|
|||
- pci14e4,4488 # BCM4377
|
||||
- pci14e4,4425 # BCM4378
|
||||
- pci14e4,4433 # BCM4387
|
||||
- pci14e4,4434 # BCM4388
|
||||
- pci14e4,449d # BCM43752
|
||||
|
||||
reg:
|
||||
|
|
|
|||
|
|
@ -11,12 +11,18 @@ maintainers:
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- apple,t8103-nvme-ans2
|
||||
- apple,t8112-nvme-ans2
|
||||
- apple,t6000-nvme-ans2
|
||||
- const: apple,nvme-ans2
|
||||
oneOf:
|
||||
- const: apple,t8015-nvme-ans2
|
||||
- items:
|
||||
- const: apple,t6020-nvme-ans2
|
||||
- const: apple,t8103-nvme-ans2
|
||||
- items:
|
||||
- enum:
|
||||
# Do not add additional SoC to this list.
|
||||
- apple,t8103-nvme-ans2
|
||||
- apple,t8112-nvme-ans2
|
||||
- apple,t6000-nvme-ans2
|
||||
- const: apple,nvme-ans2
|
||||
|
||||
reg:
|
||||
items:
|
||||
|
|
@ -67,20 +73,20 @@ if:
|
|||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- apple,t8103-nvme-ans2
|
||||
- apple,t8112-nvme-ans2
|
||||
- apple,t6000-nvme-ans2
|
||||
- apple,t6020-nvme-ans2
|
||||
then:
|
||||
properties:
|
||||
power-domains:
|
||||
maxItems: 2
|
||||
minItems: 3
|
||||
power-domain-names:
|
||||
maxItems: 2
|
||||
minItems: 3
|
||||
else:
|
||||
properties:
|
||||
power-domains:
|
||||
minItems: 3
|
||||
maxItems: 2
|
||||
power-domain-names:
|
||||
minItems: 3
|
||||
maxItems: 2
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
|
|
|||
|
|
@ -16,17 +16,22 @@ description: |
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- apple,s5l8960x-pinctrl
|
||||
- apple,t7000-pinctrl
|
||||
- apple,s8000-pinctrl
|
||||
- apple,t8010-pinctrl
|
||||
- apple,t8015-pinctrl
|
||||
- apple,t8103-pinctrl
|
||||
- apple,t8112-pinctrl
|
||||
- apple,t6000-pinctrl
|
||||
- const: apple,pinctrl
|
||||
oneOf:
|
||||
- items:
|
||||
- const: apple,t6020-pinctrl
|
||||
- const: apple,t8103-pinctrl
|
||||
- items:
|
||||
# Do not add additional SoC to this list.
|
||||
- enum:
|
||||
- apple,s5l8960x-pinctrl
|
||||
- apple,t7000-pinctrl
|
||||
- apple,s8000-pinctrl
|
||||
- apple,t8010-pinctrl
|
||||
- apple,t8015-pinctrl
|
||||
- apple,t8103-pinctrl
|
||||
- apple,t8112-pinctrl
|
||||
- apple,t6000-pinctrl
|
||||
- const: apple,pinctrl
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
|
|
|||
|
|
@ -29,17 +29,22 @@ description: |
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- apple,s5l8960x-pmgr-pwrstate
|
||||
- apple,t7000-pmgr-pwrstate
|
||||
- apple,s8000-pmgr-pwrstate
|
||||
- apple,t8010-pmgr-pwrstate
|
||||
- apple,t8015-pmgr-pwrstate
|
||||
- apple,t8103-pmgr-pwrstate
|
||||
- apple,t8112-pmgr-pwrstate
|
||||
- apple,t6000-pmgr-pwrstate
|
||||
- const: apple,pmgr-pwrstate
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
# Do not add additional SoC to this list.
|
||||
- apple,s5l8960x-pmgr-pwrstate
|
||||
- apple,t7000-pmgr-pwrstate
|
||||
- apple,s8000-pmgr-pwrstate
|
||||
- apple,t8010-pmgr-pwrstate
|
||||
- apple,t8015-pmgr-pwrstate
|
||||
- apple,t8103-pmgr-pwrstate
|
||||
- apple,t8112-pmgr-pwrstate
|
||||
- apple,t6000-pmgr-pwrstate
|
||||
- const: apple,pmgr-pwrstate
|
||||
- items:
|
||||
- const: apple,t6020-pmgr-pwrstate
|
||||
- const: apple,t8103-pmgr-pwrstate
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
|
|
|||
|
|
@ -13,7 +13,9 @@ maintainers:
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
const: brcm,bcm6345-reset
|
||||
enum:
|
||||
- brcm,bcm6345-reset
|
||||
- brcm,bcm63xx-ephy-ctrl
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ maintainers:
|
|||
|
||||
allOf:
|
||||
- $ref: /schemas/serial/serial.yaml#
|
||||
- $ref: /schemas/soc/qcom/qcom,se-common-props.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ description: |
|
|||
SLEEP - Triggered by F/W
|
||||
WAKE - Triggered by F/W
|
||||
CONTROL - Triggered by F/W
|
||||
See also:: <dt-bindings/soc/qcom,rpmh-rsc.h>
|
||||
See also: <dt-bindings/soc/qcom,rpmh-rsc.h>
|
||||
|
||||
The order in which they are described in the DT, should match the hardware
|
||||
configuration.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/soc/qcom/qcom,se-common-props.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: QUP Peripheral-specific properties for I2C, SPI and SERIAL bus
|
||||
|
||||
description:
|
||||
The Generic Interface (GENI) based Qualcomm Universal Peripheral (QUP) is
|
||||
a programmable module that supports a wide range of serial interfaces
|
||||
such as UART, SPI, I2C, I3C, etc. This defines the common properties used
|
||||
across QUP-supported peripherals.
|
||||
|
||||
maintainers:
|
||||
- Mukesh Kumar Savaliya <mukesh.savaliya@oss.qualcomm.com>
|
||||
- Viken Dadhaniya <viken.dadhaniya@oss.qualcomm.com>
|
||||
|
||||
properties:
|
||||
qcom,enable-gsi-dma:
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
description:
|
||||
Configure the Serial Engine (SE) to transfer data in QCOM GPI DMA mode.
|
||||
By default, FIFO mode (PIO/CPU DMA) will be selected.
|
||||
|
||||
additionalProperties: true
|
||||
|
|
@ -36,6 +36,7 @@ properties:
|
|||
- items:
|
||||
- enum:
|
||||
- google,gs101-usi
|
||||
- samsung,exynos2200-usi
|
||||
- samsung,exynosautov9-usi
|
||||
- samsung,exynosautov920-usi
|
||||
- const: samsung,exynos850-usi
|
||||
|
|
|
|||
|
|
@ -19,12 +19,17 @@ allOf:
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- apple,t6000-mca
|
||||
- apple,t8103-mca
|
||||
- apple,t8112-mca
|
||||
- const: apple,mca
|
||||
oneOf:
|
||||
- items:
|
||||
- const: apple,t6020-mca
|
||||
- const: apple,t8103-mca
|
||||
- items:
|
||||
- enum:
|
||||
# Do not add additional SoC to this list.
|
||||
- apple,t6000-mca
|
||||
- apple,t8103-mca
|
||||
- apple,t8112-mca
|
||||
- const: apple,mca
|
||||
|
||||
reg:
|
||||
items:
|
||||
|
|
|
|||
|
|
@ -14,12 +14,16 @@ maintainers:
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- apple,t8103-spi
|
||||
- apple,t8112-spi
|
||||
- apple,t6000-spi
|
||||
- const: apple,spi
|
||||
oneOf:
|
||||
- items:
|
||||
- const: apple,t6020-spi
|
||||
- const: apple,t8103-spi
|
||||
- items:
|
||||
- enum:
|
||||
- apple,t8103-spi
|
||||
- apple,t8112-spi
|
||||
- apple,t6000-spi
|
||||
- const: apple,spi
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ description:
|
|||
|
||||
allOf:
|
||||
- $ref: /schemas/spi/spi-controller.yaml#
|
||||
- $ref: /schemas/soc/qcom/qcom,se-common-props.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
|
|
|
|||
|
|
@ -16,12 +16,20 @@ allOf:
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- apple,t8103-spmi
|
||||
- apple,t6000-spmi
|
||||
- apple,t8112-spmi
|
||||
- const: apple,spmi
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- apple,t6020-spmi
|
||||
- apple,t8012-spmi
|
||||
- apple,t8015-spmi
|
||||
- const: apple,t8103-spmi
|
||||
- items:
|
||||
- enum:
|
||||
# Do not add additional SoC to this list.
|
||||
- apple,t8103-spmi
|
||||
- apple,t6000-spmi
|
||||
- apple,t8112-spmi
|
||||
- const: apple,spmi
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ properties:
|
|||
items:
|
||||
- enum:
|
||||
- qcom,apq8064-imem
|
||||
- qcom,ipq5424-imem
|
||||
- qcom,msm8226-imem
|
||||
- qcom,msm8974-imem
|
||||
- qcom,msm8976-imem
|
||||
|
|
|
|||
|
|
@ -14,17 +14,22 @@ allOf:
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- apple,s5l8960x-wdt
|
||||
- apple,t7000-wdt
|
||||
- apple,s8000-wdt
|
||||
- apple,t8010-wdt
|
||||
- apple,t8015-wdt
|
||||
- apple,t8103-wdt
|
||||
- apple,t8112-wdt
|
||||
- apple,t6000-wdt
|
||||
- const: apple,wdt
|
||||
oneOf:
|
||||
- items:
|
||||
- const: apple,t6020-wdt
|
||||
- const: apple,t8103-wdt
|
||||
- items:
|
||||
- enum:
|
||||
# Do not add additional SoC to this list.
|
||||
- apple,s5l8960x-wdt
|
||||
- apple,t7000-wdt
|
||||
- apple,s8000-wdt
|
||||
- apple,t8010-wdt
|
||||
- apple,t8015-wdt
|
||||
- apple,t8103-wdt
|
||||
- apple,t8112-wdt
|
||||
- apple,t6000-wdt
|
||||
- const: apple,wdt
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ TEE Subsystem
|
|||
op-tee
|
||||
amd-tee
|
||||
ts-tee
|
||||
qtee
|
||||
|
||||
.. only:: subproject and html
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,96 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
=============================================
|
||||
QTEE (Qualcomm Trusted Execution Environment)
|
||||
=============================================
|
||||
|
||||
The QTEE driver handles communication with Qualcomm TEE [1].
|
||||
|
||||
The lowest level of communication with QTEE builds on the ARM SMC Calling
|
||||
Convention (SMCCC) [2], which is the foundation for QTEE's Secure Channel
|
||||
Manager (SCM) [3] used internally by the driver.
|
||||
|
||||
In a QTEE-based system, services are represented as objects with a series of
|
||||
operations that can be called to produce results, including other objects.
|
||||
|
||||
When an object is hosted within QTEE, executing its operations is referred
|
||||
to as "direct invocation". QTEE can also invoke objects hosted in the non-secure
|
||||
world using a method known as "callback request".
|
||||
|
||||
The SCM provides two functions to support direct invocation and callback requests:
|
||||
|
||||
- QCOM_SCM_SMCINVOKE_INVOKE: Used for direct invocation. It can return either
|
||||
a result or initiate a callback request.
|
||||
- QCOM_SCM_SMCINVOKE_CB_RSP: Used to submit a response to a callback request
|
||||
triggered by a previous direct invocation.
|
||||
|
||||
The QTEE Transport Message [4] is stacked on top of the SCM driver functions.
|
||||
|
||||
A message consists of two buffers shared with QTEE: inbound and outbound
|
||||
buffers. The inbound buffer is used for direct invocation, and the outbound
|
||||
buffer is used to make callback requests. This picture shows the contents of
|
||||
a QTEE transport message::
|
||||
|
||||
+---------------------+
|
||||
| v
|
||||
+-----------------+-------+-------+------+--------------------------+
|
||||
| qcomtee_msg_ |object | buffer | |
|
||||
| object_invoke | id | offset, size | | (inbound buffer)
|
||||
+-----------------+-------+--------------+--------------------------+
|
||||
<---- header -----><---- arguments ------><- in/out buffer payload ->
|
||||
|
||||
+-----------+
|
||||
| v
|
||||
+-----------------+-------+-------+------+----------------------+
|
||||
| qcomtee_msg_ |object | buffer | |
|
||||
| callback | id | offset, size | | (outbound buffer)
|
||||
+-----------------+-------+--------------+----------------------+
|
||||
|
||||
Each buffer is started with a header and array of arguments.
|
||||
|
||||
QTEE Transport Message supports four types of arguments:
|
||||
|
||||
- Input Object (IO) is an object parameter to the current invocation
|
||||
or callback request.
|
||||
- Output Object (OO) is an object parameter from the current invocation
|
||||
or callback request.
|
||||
- Input Buffer (IB) is (offset, size) pair to the inbound or outbound region
|
||||
to store parameter to the current invocation or callback request.
|
||||
- Output Buffer (OB) is (offset, size) pair to the inbound or outbound region
|
||||
to store parameter from the current invocation or callback request.
|
||||
|
||||
Picture of the relationship between the different components in the QTEE
|
||||
architecture::
|
||||
|
||||
User space Kernel Secure world
|
||||
~~~~~~~~~~ ~~~~~~ ~~~~~~~~~~~~
|
||||
+--------+ +----------+ +--------------+
|
||||
| Client | |callback | | Trusted |
|
||||
+--------+ |server | | Application |
|
||||
/\ +----------+ +--------------+
|
||||
|| +----------+ /\ /\
|
||||
|| |callback | || ||
|
||||
|| |server | || \/
|
||||
|| +----------+ || +--------------+
|
||||
|| /\ || | TEE Internal |
|
||||
|| || || | API |
|
||||
\/ \/ \/ +--------+--------+ +--------------+
|
||||
+---------------------+ | TEE | QTEE | | QTEE |
|
||||
| libqcomtee [5] | | subsys | driver | | Trusted OS |
|
||||
+-------+-------------+--+----+-------+----+-------------+--------------+
|
||||
| Generic TEE API | | QTEE MSG |
|
||||
| IOCTL (TEE_IOC_*) | | SMCCC (QCOM_SCM_SMCINVOKE_*) |
|
||||
+-----------------------------+ +---------------------------------+
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
[1] https://docs.qualcomm.com/bundle/publicresource/topics/80-70015-11/qualcomm-trusted-execution-environment.html
|
||||
|
||||
[2] http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
|
||||
|
||||
[3] drivers/firmware/qcom/qcom_scm.c
|
||||
|
||||
[4] drivers/tee/qcomtee/qcomtee_msg.h
|
||||
|
||||
[5] https://github.com/quic/quic-teec
|
||||
|
|
@ -21038,6 +21038,13 @@ F: Documentation/networking/device_drivers/cellular/qualcomm/rmnet.rst
|
|||
F: drivers/net/ethernet/qualcomm/rmnet/
|
||||
F: include/linux/if_rmnet.h
|
||||
|
||||
QUALCOMM TEE (QCOMTEE) DRIVER
|
||||
M: Amirreza Zarrabi <amirreza.zarrabi@oss.qualcomm.com>
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/tee/qtee.rst
|
||||
F: drivers/tee/qcomtee/
|
||||
|
||||
QUALCOMM TRUST ZONE MEMORY ALLOCATOR
|
||||
M: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
|
|
@ -21739,7 +21746,7 @@ F: drivers/thermal/renesas/rzg3e_thermal.c
|
|||
RESET CONTROLLER FRAMEWORK
|
||||
M: Philipp Zabel <p.zabel@pengutronix.de>
|
||||
S: Maintained
|
||||
T: git git://git.pengutronix.de/git/pza/linux
|
||||
T: git https://git.pengutronix.de/git/pza/linux.git
|
||||
F: Documentation/devicetree/bindings/reset/
|
||||
F: Documentation/driver-api/reset.rst
|
||||
F: drivers/reset/
|
||||
|
|
|
|||
|
|
@ -138,20 +138,6 @@ config ARCH_EXYNOS
|
|||
help
|
||||
This enables support for ARMv8 based Samsung Exynos SoC family.
|
||||
|
||||
config ARCH_SPARX5
|
||||
bool "Microchip Sparx5 SoC family"
|
||||
select PINCTRL
|
||||
select DW_APB_TIMER_OF
|
||||
help
|
||||
This enables support for the Microchip Sparx5 ARMv8-based
|
||||
SoC family of TSN-capable gigabit switches.
|
||||
|
||||
The SparX-5 Ethernet switch family provides a rich set of
|
||||
switching features such as advanced TCAM-based VLAN and QoS
|
||||
processing enabling delivery of differentiated services, and
|
||||
security through TCAM-based frame processing using versatile
|
||||
content aware processor (VCAP).
|
||||
|
||||
config ARCH_K3
|
||||
bool "Texas Instruments Inc. K3 multicore SoC architecture"
|
||||
select SOC_TI
|
||||
|
|
@ -193,6 +179,43 @@ config ARCH_MESON
|
|||
This enables support for the arm64 based Amlogic SoCs
|
||||
such as the s905, S905X/D, S912, A113X/D or S905X/D2
|
||||
|
||||
menu "Microchip SoC support"
|
||||
|
||||
config ARCH_MICROCHIP
|
||||
bool
|
||||
|
||||
config ARCH_LAN969X
|
||||
bool "Microchip LAN969X SoC family"
|
||||
select PINCTRL
|
||||
select DW_APB_TIMER_OF
|
||||
select ARCH_MICROCHIP
|
||||
help
|
||||
This enables support for the Microchip LAN969X ARMv8-based
|
||||
SoC family of TSN-capable gigabit switches.
|
||||
|
||||
The LAN969X Ethernet switch family provides a rich set of
|
||||
switching features such as advanced TCAM-based VLAN and QoS
|
||||
processing enabling delivery of differentiated services, and
|
||||
security through TCAM-based frame processing using versatile
|
||||
content aware processor (VCAP).
|
||||
|
||||
config ARCH_SPARX5
|
||||
bool "Microchip Sparx5 SoC family"
|
||||
select PINCTRL
|
||||
select DW_APB_TIMER_OF
|
||||
select ARCH_MICROCHIP
|
||||
help
|
||||
This enables support for the Microchip Sparx5 ARMv8-based
|
||||
SoC family of TSN-capable gigabit switches.
|
||||
|
||||
The SparX-5 Ethernet switch family provides a rich set of
|
||||
switching features such as advanced TCAM-based VLAN and QoS
|
||||
processing enabling delivery of differentiated services, and
|
||||
security through TCAM-based frame processing using versatile
|
||||
content aware processor (VCAP).
|
||||
|
||||
endmenu
|
||||
|
||||
config ARCH_MMP
|
||||
bool "Marvell MMP SoC Family"
|
||||
select PINCTRL
|
||||
|
|
|
|||
|
|
@ -232,7 +232,6 @@ config QE_GPIO
|
|||
bool "QE GPIO support"
|
||||
depends on QUICC_ENGINE
|
||||
select GPIOLIB
|
||||
select OF_GPIO_MM_GPIOCHIP
|
||||
help
|
||||
Say Y here if you're going to use hardware that connects to the
|
||||
QE GPIOs.
|
||||
|
|
|
|||
|
|
@ -176,8 +176,8 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
|
|||
{
|
||||
struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
|
||||
|
||||
return sprintf(buf, "fsl-mc:v%08Xd%s\n", mc_dev->obj_desc.vendor,
|
||||
mc_dev->obj_desc.type);
|
||||
return sysfs_emit(buf, "fsl-mc:v%08Xd%s\n", mc_dev->obj_desc.vendor,
|
||||
mc_dev->obj_desc.type);
|
||||
}
|
||||
static DEVICE_ATTR_RO(modalias);
|
||||
|
||||
|
|
@ -203,7 +203,7 @@ static ssize_t driver_override_show(struct device *dev,
|
|||
{
|
||||
struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%s\n", mc_dev->driver_override);
|
||||
return sysfs_emit(buf, "%s\n", mc_dev->driver_override);
|
||||
}
|
||||
static DEVICE_ATTR_RW(driver_override);
|
||||
|
||||
|
|
@ -1104,6 +1104,9 @@ static int fsl_mc_bus_probe(struct platform_device *pdev)
|
|||
* Get physical address of MC portal for the root DPRC:
|
||||
*/
|
||||
plat_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!plat_res)
|
||||
return -EINVAL;
|
||||
|
||||
mc_portal_phys_addr = plat_res->start;
|
||||
mc_portal_size = resource_size(plat_res);
|
||||
mc_portal_base_phys_addr = mc_portal_phys_addr & ~0x3ffffff;
|
||||
|
|
|
|||
|
|
@ -151,16 +151,16 @@ static void ccache_flush_range(phys_addr_t start, size_t len)
|
|||
if (!len)
|
||||
return;
|
||||
|
||||
mb();
|
||||
mb(); /* complete earlier memory accesses before the cache flush */
|
||||
for (line = ALIGN_DOWN(start, SIFIVE_CCACHE_LINE_SIZE); line < end;
|
||||
line += SIFIVE_CCACHE_LINE_SIZE) {
|
||||
#ifdef CONFIG_32BIT
|
||||
writel(line >> 4, ccache_base + SIFIVE_CCACHE_FLUSH32);
|
||||
writel_relaxed(line >> 4, ccache_base + SIFIVE_CCACHE_FLUSH32);
|
||||
#else
|
||||
writeq(line, ccache_base + SIFIVE_CCACHE_FLUSH64);
|
||||
writeq_relaxed(line, ccache_base + SIFIVE_CCACHE_FLUSH64);
|
||||
#endif
|
||||
mb();
|
||||
}
|
||||
mb(); /* issue later memory accesses after the cache flush */
|
||||
}
|
||||
|
||||
static const struct riscv_nonstd_cache_ops ccache_mgmt_ops __initconst = {
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ config HW_RANDOM_AIROHA
|
|||
|
||||
config HW_RANDOM_ATMEL
|
||||
tristate "Atmel Random Number Generator support"
|
||||
depends on (ARCH_AT91 || COMPILE_TEST)
|
||||
depends on (ARCH_MICROCHIP || COMPILE_TEST)
|
||||
default HW_RANDOM
|
||||
help
|
||||
This driver provides kernel-side support for the Random Number
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -439,7 +439,7 @@ config CRYPTO_DEV_ATMEL_AUTHENC
|
|||
|
||||
config CRYPTO_DEV_ATMEL_AES
|
||||
tristate "Support for Atmel AES hw accelerator"
|
||||
depends on ARCH_AT91 || COMPILE_TEST
|
||||
depends on ARCH_MICROCHIP || COMPILE_TEST
|
||||
select CRYPTO_AES
|
||||
select CRYPTO_AEAD
|
||||
select CRYPTO_SKCIPHER
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include <linux/dma-buf.h>
|
||||
#include <linux/dma-heap.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/nospec.h>
|
||||
#include <linux/syscalls.h>
|
||||
|
|
@ -202,6 +203,7 @@ void *dma_heap_get_drvdata(struct dma_heap *heap)
|
|||
{
|
||||
return heap->priv;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(dma_heap_get_drvdata, "DMA_BUF_HEAP");
|
||||
|
||||
/**
|
||||
* dma_heap_get_name - get heap name
|
||||
|
|
@ -214,6 +216,7 @@ const char *dma_heap_get_name(struct dma_heap *heap)
|
|||
{
|
||||
return heap->name;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(dma_heap_get_name, "DMA_BUF_HEAP");
|
||||
|
||||
/**
|
||||
* dma_heap_add - adds a heap to dmabuf heaps
|
||||
|
|
@ -303,6 +306,7 @@ err0:
|
|||
kfree(heap);
|
||||
return err_ret;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(dma_heap_add, "DMA_BUF_HEAP");
|
||||
|
||||
static char *dma_heap_devnode(const struct device *dev, umode_t *mode)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -401,8 +401,8 @@ static void scmi_device_release(struct device *dev)
|
|||
|
||||
static void __scmi_device_destroy(struct scmi_device *scmi_dev)
|
||||
{
|
||||
pr_debug("(%s) Destroying SCMI device '%s' for protocol 0x%x (%s)\n",
|
||||
of_node_full_name(scmi_dev->dev.parent->of_node),
|
||||
pr_debug("(%pOF) Destroying SCMI device '%s' for protocol 0x%x (%s)\n",
|
||||
scmi_dev->dev.parent->of_node,
|
||||
dev_name(&scmi_dev->dev), scmi_dev->protocol_id,
|
||||
scmi_dev->name);
|
||||
|
||||
|
|
@ -474,9 +474,8 @@ __scmi_device_create(struct device_node *np, struct device *parent,
|
|||
if (retval)
|
||||
goto put_dev;
|
||||
|
||||
pr_debug("(%s) Created SCMI device '%s' for protocol 0x%x (%s)\n",
|
||||
of_node_full_name(parent->of_node),
|
||||
dev_name(&scmi_dev->dev), protocol, name);
|
||||
pr_debug("(%pOF) Created SCMI device '%s' for protocol 0x%x (%s)\n",
|
||||
parent->of_node, dev_name(&scmi_dev->dev), protocol, name);
|
||||
|
||||
return scmi_dev;
|
||||
put_dev:
|
||||
|
|
@ -493,8 +492,8 @@ _scmi_device_create(struct device_node *np, struct device *parent,
|
|||
|
||||
sdev = __scmi_device_create(np, parent, protocol, name);
|
||||
if (!sdev)
|
||||
pr_err("(%s) Failed to create device for protocol 0x%x (%s)\n",
|
||||
of_node_full_name(parent->of_node), protocol, name);
|
||||
pr_err("(%pOF) Failed to create device for protocol 0x%x (%s)\n",
|
||||
parent->of_node, protocol, name);
|
||||
|
||||
return sdev;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/cleanup.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/hashtable.h>
|
||||
|
|
@ -89,9 +90,9 @@
|
|||
struct scmi_quirk {
|
||||
bool enabled;
|
||||
const char *name;
|
||||
char *vendor;
|
||||
char *sub_vendor_id;
|
||||
char *impl_ver_range;
|
||||
const char *vendor;
|
||||
const char *sub_vendor_id;
|
||||
const char *impl_ver_range;
|
||||
u32 start_range;
|
||||
u32 end_range;
|
||||
struct static_key_false *key;
|
||||
|
|
@ -217,7 +218,7 @@ static unsigned int scmi_quirk_signature(const char *vend, const char *sub_vend)
|
|||
|
||||
static int scmi_quirk_range_parse(struct scmi_quirk *quirk)
|
||||
{
|
||||
const char *last, *first = quirk->impl_ver_range;
|
||||
const char *last, *first __free(kfree) = NULL;
|
||||
size_t len;
|
||||
char *sep;
|
||||
int ret;
|
||||
|
|
@ -228,8 +229,12 @@ static int scmi_quirk_range_parse(struct scmi_quirk *quirk)
|
|||
if (!len)
|
||||
return 0;
|
||||
|
||||
first = kmemdup(quirk->impl_ver_range, len + 1, GFP_KERNEL);
|
||||
if (!first)
|
||||
return -ENOMEM;
|
||||
|
||||
last = first + len - 1;
|
||||
sep = strchr(quirk->impl_ver_range, '-');
|
||||
sep = strchr(first, '-');
|
||||
if (sep)
|
||||
*sep = '\0';
|
||||
|
||||
|
|
|
|||
|
|
@ -127,8 +127,8 @@ static int mailbox_chan_validate(struct device *cdev, int *a2p_rx_chan,
|
|||
(num_mb == 1 && num_sh != 1) || (num_mb == 3 && num_sh != 2) ||
|
||||
(num_mb == 4 && num_sh != 2)) {
|
||||
dev_warn(cdev,
|
||||
"Invalid channel descriptor for '%s' - mbs:%d shm:%d\n",
|
||||
of_node_full_name(np), num_mb, num_sh);
|
||||
"Invalid channel descriptor for '%pOF' - mbs:%d shm:%d\n",
|
||||
np, num_mb, num_sh);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -140,8 +140,7 @@ static int mailbox_chan_validate(struct device *cdev, int *a2p_rx_chan,
|
|||
of_parse_phandle(np, "shmem", 1);
|
||||
|
||||
if (!np_tx || !np_rx || np_tx == np_rx) {
|
||||
dev_warn(cdev, "Invalid shmem descriptor for '%s'\n",
|
||||
of_node_full_name(np));
|
||||
dev_warn(cdev, "Invalid shmem descriptor for '%pOF'\n", np);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -498,7 +498,7 @@ static void scmi_optee_mark_txdone(struct scmi_chan_info *cinfo, int ret,
|
|||
mutex_unlock(&channel->mu);
|
||||
}
|
||||
|
||||
static struct scmi_transport_ops scmi_optee_ops = {
|
||||
static const struct scmi_transport_ops scmi_optee_ops = {
|
||||
.chan_available = scmi_optee_chan_available,
|
||||
.chan_setup = scmi_optee_chan_setup,
|
||||
.chan_free = scmi_optee_chan_free,
|
||||
|
|
|
|||
|
|
@ -871,6 +871,9 @@ static int scmi_vio_probe(struct virtio_device *vdev)
|
|||
/* Ensure initialized scmi_vdev is visible */
|
||||
smp_store_mb(scmi_vdev, vdev);
|
||||
|
||||
/* Set device ready */
|
||||
virtio_device_ready(vdev);
|
||||
|
||||
ret = platform_driver_register(&scmi_virtio_driver);
|
||||
if (ret) {
|
||||
vdev->priv = NULL;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,10 @@
|
|||
enum scmi_imx_misc_protocol_cmd {
|
||||
SCMI_IMX_MISC_CTRL_SET = 0x3,
|
||||
SCMI_IMX_MISC_CTRL_GET = 0x4,
|
||||
SCMI_IMX_MISC_DISCOVER_BUILD_INFO = 0x6,
|
||||
SCMI_IMX_MISC_CTRL_NOTIFY = 0x8,
|
||||
SCMI_IMX_MISC_CFG_INFO_GET = 0xC,
|
||||
SCMI_IMX_MISC_BOARD_INFO = 0xE,
|
||||
};
|
||||
|
||||
struct scmi_imx_misc_info {
|
||||
|
|
@ -65,6 +68,27 @@ struct scmi_imx_misc_ctrl_get_out {
|
|||
__le32 val[];
|
||||
};
|
||||
|
||||
struct scmi_imx_misc_buildinfo_out {
|
||||
__le32 buildnum;
|
||||
__le32 buildcommit;
|
||||
#define MISC_MAX_BUILDDATE 16
|
||||
u8 builddate[MISC_MAX_BUILDDATE];
|
||||
#define MISC_MAX_BUILDTIME 16
|
||||
u8 buildtime[MISC_MAX_BUILDTIME];
|
||||
};
|
||||
|
||||
struct scmi_imx_misc_board_info_out {
|
||||
__le32 attributes;
|
||||
#define MISC_MAX_BRDNAME 16
|
||||
u8 brdname[MISC_MAX_BRDNAME];
|
||||
};
|
||||
|
||||
struct scmi_imx_misc_cfg_info_out {
|
||||
__le32 msel;
|
||||
#define MISC_MAX_CFGNAME 16
|
||||
u8 cfgname[MISC_MAX_CFGNAME];
|
||||
};
|
||||
|
||||
static int scmi_imx_misc_attributes_get(const struct scmi_protocol_handle *ph,
|
||||
struct scmi_imx_misc_info *mi)
|
||||
{
|
||||
|
|
@ -272,6 +296,81 @@ static int scmi_imx_misc_ctrl_set(const struct scmi_protocol_handle *ph,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int scmi_imx_misc_build_info_discover(const struct scmi_protocol_handle *ph)
|
||||
{
|
||||
char date[MISC_MAX_BUILDDATE], time[MISC_MAX_BUILDTIME];
|
||||
struct scmi_imx_misc_buildinfo_out *out;
|
||||
struct scmi_xfer *t;
|
||||
int ret;
|
||||
|
||||
ret = ph->xops->xfer_get_init(ph, SCMI_IMX_MISC_DISCOVER_BUILD_INFO, 0,
|
||||
sizeof(*out), &t);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ph->xops->do_xfer(ph, t);
|
||||
if (!ret) {
|
||||
out = t->rx.buf;
|
||||
strscpy(date, out->builddate, MISC_MAX_BUILDDATE);
|
||||
strscpy(time, out->buildtime, MISC_MAX_BUILDTIME);
|
||||
dev_info(ph->dev, "SM Version\t= Build %u, Commit %08x %s %s\n",
|
||||
le32_to_cpu(out->buildnum), le32_to_cpu(out->buildcommit),
|
||||
date, time);
|
||||
}
|
||||
|
||||
ph->xops->xfer_put(ph, t);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int scmi_imx_misc_board_info(const struct scmi_protocol_handle *ph)
|
||||
{
|
||||
struct scmi_imx_misc_board_info_out *out;
|
||||
char name[MISC_MAX_BRDNAME];
|
||||
struct scmi_xfer *t;
|
||||
int ret;
|
||||
|
||||
ret = ph->xops->xfer_get_init(ph, SCMI_IMX_MISC_BOARD_INFO, 0, sizeof(*out), &t);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ph->xops->do_xfer(ph, t);
|
||||
if (!ret) {
|
||||
out = t->rx.buf;
|
||||
strscpy(name, out->brdname, MISC_MAX_BRDNAME);
|
||||
dev_info(ph->dev, "Board\t\t= %s, attr=0x%08x\n",
|
||||
name, le32_to_cpu(out->attributes));
|
||||
}
|
||||
|
||||
ph->xops->xfer_put(ph, t);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int scmi_imx_misc_cfg_info_get(const struct scmi_protocol_handle *ph)
|
||||
{
|
||||
struct scmi_imx_misc_cfg_info_out *out;
|
||||
char name[MISC_MAX_CFGNAME];
|
||||
struct scmi_xfer *t;
|
||||
int ret;
|
||||
|
||||
ret = ph->xops->xfer_get_init(ph, SCMI_IMX_MISC_CFG_INFO_GET, 0, sizeof(*out), &t);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ph->xops->do_xfer(ph, t);
|
||||
if (!ret) {
|
||||
out = t->rx.buf;
|
||||
strscpy(name, out->cfgname, MISC_MAX_CFGNAME);
|
||||
dev_info(ph->dev, "SM Config\t= %s, mSel = %u\n",
|
||||
name, le32_to_cpu(out->msel));
|
||||
}
|
||||
|
||||
ph->xops->xfer_put(ph, t);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct scmi_imx_misc_proto_ops scmi_imx_misc_proto_ops = {
|
||||
.misc_ctrl_set = scmi_imx_misc_ctrl_set,
|
||||
.misc_ctrl_get = scmi_imx_misc_ctrl_get,
|
||||
|
|
@ -299,6 +398,18 @@ static int scmi_imx_misc_protocol_init(const struct scmi_protocol_handle *ph)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = scmi_imx_misc_build_info_discover(ph);
|
||||
if (ret && ret != -EOPNOTSUPP)
|
||||
return ret;
|
||||
|
||||
ret = scmi_imx_misc_board_info(ph);
|
||||
if (ret && ret != -EOPNOTSUPP)
|
||||
return ret;
|
||||
|
||||
ret = scmi_imx_misc_cfg_info_get(ph);
|
||||
if (ret && ret != -EOPNOTSUPP)
|
||||
return ret;
|
||||
|
||||
return ph->set_priv(ph, minfo, version);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1660,6 +1660,7 @@ protocol_id: 0x84
|
|||
|Name |Description |
|
||||
+--------------------+---------------------------------------------------------+
|
||||
|int32 status |SUCCESS: system log return |
|
||||
| |NOT_SUPPORTED: system log not available |
|
||||
+--------------------+---------------------------------------------------------+
|
||||
|uint32 numLogflags |Descriptor for the log data returned by this call. |
|
||||
| |Bits[31:20] Number of remaining log words. |
|
||||
|
|
@ -1670,6 +1671,30 @@ protocol_id: 0x84
|
|||
|uint32 syslog[N] |Log data array, N is defined in bits[11:0] of numLogflags|
|
||||
+--------------------+---------------------------------------------------------+
|
||||
|
||||
MISC_BOARD_INFO
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
message_id: 0xE
|
||||
protocol_id: 0x84
|
||||
|
||||
+--------------------+---------------------------------------------------------+
|
||||
|Return values |
|
||||
+--------------------+---------------------------------------------------------+
|
||||
|Name |Description |
|
||||
+--------------------+---------------------------------------------------------+
|
||||
|int32 status |SUCCESS: config name return |
|
||||
| |NOT_SUPPORTED: name not available |
|
||||
+--------------------+---------------------------------------------------------+
|
||||
|uint32 attributes |Board-specific attributes reserved for future expansion |
|
||||
| |without breaking backwards compatibility. The firmware |
|
||||
| |sets the value to 0 |
|
||||
+--------------------+---------------------------------------------------------+
|
||||
|uint8 boardname[16] |Board name. NULL terminated ASCII string, up to 16 bytes |
|
||||
| |in length. This is System Manager(SM) firmware-exported |
|
||||
| |board-name and may not align with the board name in the |
|
||||
| |device tree. |
|
||||
+--------------------+---------------------------------------------------------+
|
||||
|
||||
NEGOTIATE_PROTOCOL_VERSION
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
|||
|
|
@ -393,7 +393,7 @@ static int scmi_voltage_domains_num_get(const struct scmi_protocol_handle *ph)
|
|||
return vinfo->num_domains;
|
||||
}
|
||||
|
||||
static struct scmi_voltage_proto_ops voltage_proto_ops = {
|
||||
static const struct scmi_voltage_proto_ops voltage_proto_ops = {
|
||||
.num_domains_get = scmi_voltage_domains_num_get,
|
||||
.info_get = scmi_voltage_info_get,
|
||||
.config_set = scmi_voltage_config_set,
|
||||
|
|
|
|||
|
|
@ -404,7 +404,7 @@ static void bcm47xx_sprom_fill_auto(struct ssb_sprom *sprom,
|
|||
ENTRY(0x00000700, u8, pre, "noiselvl5gua1", noiselvl5gua[1], 0, fb);
|
||||
ENTRY(0x00000700, u8, pre, "noiselvl5gua2", noiselvl5gua[2], 0, fb);
|
||||
}
|
||||
#undef ENTRY /* It's specififc, uses local variable, don't use it (again). */
|
||||
#undef ENTRY /* It's specific, uses local variable, don't use it (again). */
|
||||
|
||||
static void bcm47xx_fill_sprom_path_r4589(struct ssb_sprom *sprom,
|
||||
const char *prefix, bool fallback)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
config MESON_SM
|
||||
tristate "Amlogic Secure Monitor driver"
|
||||
depends on ARCH_MESON || COMPILE_TEST
|
||||
default y
|
||||
default ARCH_MESON
|
||||
depends on ARM64_4K_PAGES
|
||||
help
|
||||
Say y here to enable the Amlogic secure monitor driver
|
||||
|
|
|
|||
|
|
@ -232,11 +232,16 @@ EXPORT_SYMBOL(meson_sm_call_write);
|
|||
struct meson_sm_firmware *meson_sm_get(struct device_node *sm_node)
|
||||
{
|
||||
struct platform_device *pdev = of_find_device_by_node(sm_node);
|
||||
struct meson_sm_firmware *fw;
|
||||
|
||||
if (!pdev)
|
||||
return NULL;
|
||||
|
||||
return platform_get_drvdata(pdev);
|
||||
fw = platform_get_drvdata(pdev);
|
||||
|
||||
put_device(&pdev->dev);
|
||||
|
||||
return fw;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(meson_sm_get);
|
||||
|
||||
|
|
|
|||
|
|
@ -1119,7 +1119,7 @@ int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
|
|||
if (ret) {
|
||||
dev_err(__scm->dev,
|
||||
"Assign memory protection call failed %d\n", ret);
|
||||
return -EINVAL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
*srcvm = next_vm;
|
||||
|
|
@ -1994,11 +1994,14 @@ static const struct of_device_id qcom_scm_qseecom_allowlist[] __maybe_unused = {
|
|||
{ .compatible = "asus,vivobook-s15" },
|
||||
{ .compatible = "asus,zenbook-a14-ux3407qa" },
|
||||
{ .compatible = "asus,zenbook-a14-ux3407ra" },
|
||||
{ .compatible = "dell,inspiron-14-plus-7441" },
|
||||
{ .compatible = "dell,latitude-7455" },
|
||||
{ .compatible = "dell,xps13-9345" },
|
||||
{ .compatible = "hp,elitebook-ultra-g1q" },
|
||||
{ .compatible = "hp,omnibook-x14" },
|
||||
{ .compatible = "huawei,gaokun3" },
|
||||
{ .compatible = "lenovo,flex-5g" },
|
||||
{ .compatible = "lenovo,thinkbook-16" },
|
||||
{ .compatible = "lenovo,thinkpad-t14s" },
|
||||
{ .compatible = "lenovo,thinkpad-x13s", },
|
||||
{ .compatible = "lenovo,yoga-slim7x" },
|
||||
|
|
@ -2006,6 +2009,7 @@ static const struct of_device_id qcom_scm_qseecom_allowlist[] __maybe_unused = {
|
|||
{ .compatible = "microsoft,blackrock" },
|
||||
{ .compatible = "microsoft,romulus13", },
|
||||
{ .compatible = "microsoft,romulus15", },
|
||||
{ .compatible = "qcom,hamoa-iot-evk" },
|
||||
{ .compatible = "qcom,sc8180x-primus" },
|
||||
{ .compatible = "qcom,x1e001de-devkit" },
|
||||
{ .compatible = "qcom,x1e80100-crd" },
|
||||
|
|
@ -2093,6 +2097,122 @@ static int qcom_scm_qseecom_init(struct qcom_scm *scm)
|
|||
|
||||
#endif /* CONFIG_QCOM_QSEECOM */
|
||||
|
||||
/**
|
||||
* qcom_scm_qtee_invoke_smc() - Invoke a QTEE object.
|
||||
* @inbuf: start address of memory area used for inbound buffer.
|
||||
* @inbuf_size: size of the memory area used for inbound buffer.
|
||||
* @outbuf: start address of memory area used for outbound buffer.
|
||||
* @outbuf_size: size of the memory area used for outbound buffer.
|
||||
* @result: result of QTEE object invocation.
|
||||
* @response_type: response type returned by QTEE.
|
||||
*
|
||||
* @response_type determines how the contents of @inbuf and @outbuf
|
||||
* should be processed.
|
||||
*
|
||||
* Return: On success, return 0 or <0 on failure.
|
||||
*/
|
||||
int qcom_scm_qtee_invoke_smc(phys_addr_t inbuf, size_t inbuf_size,
|
||||
phys_addr_t outbuf, size_t outbuf_size,
|
||||
u64 *result, u64 *response_type)
|
||||
{
|
||||
struct qcom_scm_desc desc = {
|
||||
.svc = QCOM_SCM_SVC_SMCINVOKE,
|
||||
.cmd = QCOM_SCM_SMCINVOKE_INVOKE,
|
||||
.owner = ARM_SMCCC_OWNER_TRUSTED_OS,
|
||||
.args[0] = inbuf,
|
||||
.args[1] = inbuf_size,
|
||||
.args[2] = outbuf,
|
||||
.args[3] = outbuf_size,
|
||||
.arginfo = QCOM_SCM_ARGS(4, QCOM_SCM_RW, QCOM_SCM_VAL,
|
||||
QCOM_SCM_RW, QCOM_SCM_VAL),
|
||||
};
|
||||
struct qcom_scm_res res;
|
||||
int ret;
|
||||
|
||||
ret = qcom_scm_call(__scm->dev, &desc, &res);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (response_type)
|
||||
*response_type = res.result[0];
|
||||
|
||||
if (result)
|
||||
*result = res.result[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(qcom_scm_qtee_invoke_smc);
|
||||
|
||||
/**
|
||||
* qcom_scm_qtee_callback_response() - Submit response for callback request.
|
||||
* @buf: start address of memory area used for outbound buffer.
|
||||
* @buf_size: size of the memory area used for outbound buffer.
|
||||
* @result: Result of QTEE object invocation.
|
||||
* @response_type: Response type returned by QTEE.
|
||||
*
|
||||
* @response_type determines how the contents of @buf should be processed.
|
||||
*
|
||||
* Return: On success, return 0 or <0 on failure.
|
||||
*/
|
||||
int qcom_scm_qtee_callback_response(phys_addr_t buf, size_t buf_size,
|
||||
u64 *result, u64 *response_type)
|
||||
{
|
||||
struct qcom_scm_desc desc = {
|
||||
.svc = QCOM_SCM_SVC_SMCINVOKE,
|
||||
.cmd = QCOM_SCM_SMCINVOKE_CB_RSP,
|
||||
.owner = ARM_SMCCC_OWNER_TRUSTED_OS,
|
||||
.args[0] = buf,
|
||||
.args[1] = buf_size,
|
||||
.arginfo = QCOM_SCM_ARGS(2, QCOM_SCM_RW, QCOM_SCM_VAL),
|
||||
};
|
||||
struct qcom_scm_res res;
|
||||
int ret;
|
||||
|
||||
ret = qcom_scm_call(__scm->dev, &desc, &res);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (response_type)
|
||||
*response_type = res.result[0];
|
||||
|
||||
if (result)
|
||||
*result = res.result[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(qcom_scm_qtee_callback_response);
|
||||
|
||||
static void qcom_scm_qtee_free(void *data)
|
||||
{
|
||||
struct platform_device *qtee_dev = data;
|
||||
|
||||
platform_device_unregister(qtee_dev);
|
||||
}
|
||||
|
||||
static void qcom_scm_qtee_init(struct qcom_scm *scm)
|
||||
{
|
||||
struct platform_device *qtee_dev;
|
||||
u64 result, response_type;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Probe for smcinvoke support. This will fail due to invalid buffers,
|
||||
* but first, it checks whether the call is supported in QTEE syscall
|
||||
* handler. If it is not supported, -EIO is returned.
|
||||
*/
|
||||
ret = qcom_scm_qtee_invoke_smc(0, 0, 0, 0, &result, &response_type);
|
||||
if (ret == -EIO)
|
||||
return;
|
||||
|
||||
/* Setup QTEE interface device. */
|
||||
qtee_dev = platform_device_register_data(scm->dev, "qcomtee",
|
||||
PLATFORM_DEVID_NONE, NULL, 0);
|
||||
if (IS_ERR(qtee_dev))
|
||||
return;
|
||||
|
||||
devm_add_action_or_reset(scm->dev, qcom_scm_qtee_free, qtee_dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* qcom_scm_is_available() - Checks if SCM is available
|
||||
*/
|
||||
|
|
@ -2325,6 +2445,9 @@ static int qcom_scm_probe(struct platform_device *pdev)
|
|||
ret = qcom_scm_qseecom_init(scm);
|
||||
WARN(ret < 0, "failed to initialize qseecom: %d\n", ret);
|
||||
|
||||
/* Initialize the QTEE object interface. */
|
||||
qcom_scm_qtee_init(scm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -156,6 +156,13 @@ int qcom_scm_shm_bridge_enable(struct device *scm_dev);
|
|||
#define QCOM_SCM_SVC_GPU 0x28
|
||||
#define QCOM_SCM_SVC_GPU_INIT_REGS 0x01
|
||||
|
||||
/* ARM_SMCCC_OWNER_TRUSTED_OS calls */
|
||||
|
||||
#define QCOM_SCM_SVC_SMCINVOKE 0x06
|
||||
#define QCOM_SCM_SMCINVOKE_INVOKE_LEGACY 0x00
|
||||
#define QCOM_SCM_SMCINVOKE_CB_RSP 0x01
|
||||
#define QCOM_SCM_SMCINVOKE_INVOKE 0x02
|
||||
|
||||
/* common error codes */
|
||||
#define QCOM_SCM_V2_EBUSY -12
|
||||
#define QCOM_SCM_ENOMEM -5
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ static bool qcom_tzmem_using_shm_bridge;
|
|||
|
||||
/* List of machines that are known to not support SHM bridge correctly. */
|
||||
static const char *const qcom_tzmem_blacklist[] = {
|
||||
"qcom,sc7180", /* hang in rmtfs memory assignment */
|
||||
"qcom,sc8180x",
|
||||
"qcom,sdm670", /* failure in GPU firmware loading */
|
||||
"qcom,sdm845", /* reset in rmtfs memory assignment */
|
||||
|
|
@ -109,7 +110,19 @@ notsupp:
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int qcom_tzmem_init_area(struct qcom_tzmem_area *area)
|
||||
/**
|
||||
* qcom_tzmem_shm_bridge_create() - Create a SHM bridge.
|
||||
* @paddr: Physical address of the memory to share.
|
||||
* @size: Size of the memory to share.
|
||||
* @handle: Handle to the SHM bridge.
|
||||
*
|
||||
* On platforms that support SHM bridge, this function creates a SHM bridge
|
||||
* for the given memory region with QTEE. The handle returned by this function
|
||||
* must be passed to qcom_tzmem_shm_bridge_delete() to free the SHM bridge.
|
||||
*
|
||||
* Return: On success, returns 0; on failure, returns < 0.
|
||||
*/
|
||||
int qcom_tzmem_shm_bridge_create(phys_addr_t paddr, size_t size, u64 *handle)
|
||||
{
|
||||
u64 pfn_and_ns_perm, ipfn_and_s_perm, size_and_flags;
|
||||
int ret;
|
||||
|
|
@ -117,17 +130,49 @@ static int qcom_tzmem_init_area(struct qcom_tzmem_area *area)
|
|||
if (!qcom_tzmem_using_shm_bridge)
|
||||
return 0;
|
||||
|
||||
pfn_and_ns_perm = (u64)area->paddr | QCOM_SCM_PERM_RW;
|
||||
ipfn_and_s_perm = (u64)area->paddr | QCOM_SCM_PERM_RW;
|
||||
size_and_flags = area->size | (1 << QCOM_SHM_BRIDGE_NUM_VM_SHIFT);
|
||||
pfn_and_ns_perm = paddr | QCOM_SCM_PERM_RW;
|
||||
ipfn_and_s_perm = paddr | QCOM_SCM_PERM_RW;
|
||||
size_and_flags = size | (1 << QCOM_SHM_BRIDGE_NUM_VM_SHIFT);
|
||||
|
||||
ret = qcom_scm_shm_bridge_create(pfn_and_ns_perm, ipfn_and_s_perm,
|
||||
size_and_flags, QCOM_SCM_VMID_HLOS,
|
||||
handle);
|
||||
if (ret) {
|
||||
dev_err(qcom_tzmem_dev,
|
||||
"SHM Bridge failed: ret %d paddr 0x%pa, size %zu\n",
|
||||
ret, &paddr, size);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qcom_tzmem_shm_bridge_create);
|
||||
|
||||
/**
|
||||
* qcom_tzmem_shm_bridge_delete() - Delete a SHM bridge.
|
||||
* @handle: Handle to the SHM bridge.
|
||||
*
|
||||
* On platforms that support SHM bridge, this function deletes the SHM bridge
|
||||
* for the given memory region. The handle must be the same as the one
|
||||
* returned by qcom_tzmem_shm_bridge_create().
|
||||
*/
|
||||
void qcom_tzmem_shm_bridge_delete(u64 handle)
|
||||
{
|
||||
if (qcom_tzmem_using_shm_bridge)
|
||||
qcom_scm_shm_bridge_delete(handle);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qcom_tzmem_shm_bridge_delete);
|
||||
|
||||
static int qcom_tzmem_init_area(struct qcom_tzmem_area *area)
|
||||
{
|
||||
int ret;
|
||||
|
||||
u64 *handle __free(kfree) = kzalloc(sizeof(*handle), GFP_KERNEL);
|
||||
if (!handle)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = qcom_scm_shm_bridge_create(pfn_and_ns_perm, ipfn_and_s_perm,
|
||||
size_and_flags, QCOM_SCM_VMID_HLOS,
|
||||
handle);
|
||||
ret = qcom_tzmem_shm_bridge_create(area->paddr, area->size, handle);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -140,10 +185,7 @@ static void qcom_tzmem_cleanup_area(struct qcom_tzmem_area *area)
|
|||
{
|
||||
u64 *handle = area->priv;
|
||||
|
||||
if (!qcom_tzmem_using_shm_bridge)
|
||||
return;
|
||||
|
||||
qcom_scm_shm_bridge_delete(*handle);
|
||||
qcom_tzmem_shm_bridge_delete(*handle);
|
||||
kfree(handle);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@
|
|||
* Copyright 2020 Google LLC.
|
||||
* Copyright 2024 Linaro Ltd.
|
||||
*/
|
||||
#include <linux/array_size.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/firmware/samsung/exynos-acpm-protocol.h>
|
||||
#include <linux/ktime.h>
|
||||
#include <linux/types.h>
|
||||
|
|
@ -33,6 +35,19 @@ enum exynos_acpm_pmic_func {
|
|||
ACPM_PMIC_BULK_WRITE,
|
||||
};
|
||||
|
||||
static const int acpm_pmic_linux_errmap[] = {
|
||||
[0] = 0, /* ACPM_PMIC_SUCCESS */
|
||||
[1] = -EACCES, /* Read register can't be accessed or issues to access it. */
|
||||
[2] = -EACCES, /* Write register can't be accessed or issues to access it. */
|
||||
};
|
||||
|
||||
static int acpm_pmic_to_linux_err(int err)
|
||||
{
|
||||
if (err >= 0 && err < ARRAY_SIZE(acpm_pmic_linux_errmap))
|
||||
return acpm_pmic_linux_errmap[err];
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static inline u32 acpm_pmic_set_bulk(u32 data, unsigned int i)
|
||||
{
|
||||
return (data & ACPM_PMIC_BULK_MASK) << (ACPM_PMIC_BULK_SHIFT * i);
|
||||
|
|
@ -79,7 +94,7 @@ int acpm_pmic_read_reg(const struct acpm_handle *handle,
|
|||
|
||||
*buf = FIELD_GET(ACPM_PMIC_VALUE, xfer.rxd[1]);
|
||||
|
||||
return FIELD_GET(ACPM_PMIC_RETURN, xfer.rxd[1]);
|
||||
return acpm_pmic_to_linux_err(FIELD_GET(ACPM_PMIC_RETURN, xfer.rxd[1]));
|
||||
}
|
||||
|
||||
static void acpm_pmic_init_bulk_read_cmd(u32 cmd[4], u8 type, u8 reg, u8 chan,
|
||||
|
|
@ -110,7 +125,7 @@ int acpm_pmic_bulk_read(const struct acpm_handle *handle,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = FIELD_GET(ACPM_PMIC_RETURN, xfer.rxd[1]);
|
||||
ret = acpm_pmic_to_linux_err(FIELD_GET(ACPM_PMIC_RETURN, xfer.rxd[1]));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -150,7 +165,7 @@ int acpm_pmic_write_reg(const struct acpm_handle *handle,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
return FIELD_GET(ACPM_PMIC_RETURN, xfer.rxd[1]);
|
||||
return acpm_pmic_to_linux_err(FIELD_GET(ACPM_PMIC_RETURN, xfer.rxd[1]));
|
||||
}
|
||||
|
||||
static void acpm_pmic_init_bulk_write_cmd(u32 cmd[4], u8 type, u8 reg, u8 chan,
|
||||
|
|
@ -190,7 +205,7 @@ int acpm_pmic_bulk_write(const struct acpm_handle *handle,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
return FIELD_GET(ACPM_PMIC_RETURN, xfer.rxd[1]);
|
||||
return acpm_pmic_to_linux_err(FIELD_GET(ACPM_PMIC_RETURN, xfer.rxd[1]));
|
||||
}
|
||||
|
||||
static void acpm_pmic_init_update_cmd(u32 cmd[4], u8 type, u8 reg, u8 chan,
|
||||
|
|
@ -220,5 +235,5 @@ int acpm_pmic_update_reg(const struct acpm_handle *handle,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
return FIELD_GET(ACPM_PMIC_RETURN, xfer.rxd[1]);
|
||||
return acpm_pmic_to_linux_err(FIELD_GET(ACPM_PMIC_RETURN, xfer.rxd[1]));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2015,6 +2015,47 @@ fail:
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ti_sci_cmd_lpm_abort() - Abort entry to LPM by clearing selection of LPM to enter
|
||||
* @dev: Device pointer corresponding to the SCI entity
|
||||
*
|
||||
* Return: 0 if all went well, else returns appropriate error value.
|
||||
*/
|
||||
static int ti_sci_cmd_lpm_abort(struct device *dev)
|
||||
{
|
||||
struct ti_sci_info *info = dev_get_drvdata(dev);
|
||||
struct ti_sci_msg_hdr *req;
|
||||
struct ti_sci_msg_hdr *resp;
|
||||
struct ti_sci_xfer *xfer;
|
||||
int ret = 0;
|
||||
|
||||
xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_LPM_ABORT,
|
||||
TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
|
||||
sizeof(*req), sizeof(*resp));
|
||||
if (IS_ERR(xfer)) {
|
||||
ret = PTR_ERR(xfer);
|
||||
dev_err(dev, "Message alloc failed(%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
req = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
|
||||
|
||||
ret = ti_sci_do_xfer(info, xfer);
|
||||
if (ret) {
|
||||
dev_err(dev, "Mbox send fail %d\n", ret);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
|
||||
|
||||
if (!ti_sci_is_response_ack(resp))
|
||||
ret = -ENODEV;
|
||||
|
||||
fail:
|
||||
ti_sci_put_one_xfer(&info->minfo, xfer);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ti_sci_cmd_core_reboot(const struct ti_sci_handle *handle)
|
||||
{
|
||||
struct ti_sci_info *info;
|
||||
|
|
@ -3739,11 +3780,22 @@ static int __maybe_unused ti_sci_resume_noirq(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void __maybe_unused ti_sci_pm_complete(struct device *dev)
|
||||
{
|
||||
struct ti_sci_info *info = dev_get_drvdata(dev);
|
||||
|
||||
if (info->fw_caps & MSG_FLAG_CAPS_LPM_ABORT) {
|
||||
if (ti_sci_cmd_lpm_abort(dev))
|
||||
dev_err(dev, "LPM clear selection failed.\n");
|
||||
}
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops ti_sci_pm_ops = {
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
.suspend = ti_sci_suspend,
|
||||
.suspend_noirq = ti_sci_suspend_noirq,
|
||||
.resume_noirq = ti_sci_resume_noirq,
|
||||
.complete = ti_sci_pm_complete,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
@ -3876,10 +3928,11 @@ static int ti_sci_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
ti_sci_msg_cmd_query_fw_caps(&info->handle, &info->fw_caps);
|
||||
dev_dbg(dev, "Detected firmware capabilities: %s%s%s\n",
|
||||
dev_dbg(dev, "Detected firmware capabilities: %s%s%s%s\n",
|
||||
info->fw_caps & MSG_FLAG_CAPS_GENERIC ? "Generic" : "",
|
||||
info->fw_caps & MSG_FLAG_CAPS_LPM_PARTIAL_IO ? " Partial-IO" : "",
|
||||
info->fw_caps & MSG_FLAG_CAPS_LPM_DM_MANAGED ? " DM-Managed" : ""
|
||||
info->fw_caps & MSG_FLAG_CAPS_LPM_DM_MANAGED ? " DM-Managed" : "",
|
||||
info->fw_caps & MSG_FLAG_CAPS_LPM_ABORT ? " LPM-Abort" : ""
|
||||
);
|
||||
|
||||
ti_sci_setup_ops(info);
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
#define TI_SCI_MSG_SET_IO_ISOLATION 0x0307
|
||||
#define TI_SCI_MSG_LPM_SET_DEVICE_CONSTRAINT 0x0309
|
||||
#define TI_SCI_MSG_LPM_SET_LATENCY_CONSTRAINT 0x030A
|
||||
#define TI_SCI_MSG_LPM_ABORT 0x0311
|
||||
|
||||
/* Resource Management Requests */
|
||||
#define TI_SCI_MSG_GET_RESOURCE_RANGE 0x1500
|
||||
|
|
@ -147,6 +148,7 @@ struct ti_sci_msg_req_reboot {
|
|||
* MSG_FLAG_CAPS_GENERIC: Generic capability (LPM not supported)
|
||||
* MSG_FLAG_CAPS_LPM_PARTIAL_IO: Partial IO in LPM
|
||||
* MSG_FLAG_CAPS_LPM_DM_MANAGED: LPM can be managed by DM
|
||||
* MSG_FLAG_CAPS_LPM_ABORT: Abort entry to LPM
|
||||
*
|
||||
* Response to a generic message with message type TI_SCI_MSG_QUERY_FW_CAPS
|
||||
* providing currently available SOC/firmware capabilities. SoC that don't
|
||||
|
|
@ -157,6 +159,7 @@ struct ti_sci_msg_resp_query_fw_caps {
|
|||
#define MSG_FLAG_CAPS_GENERIC TI_SCI_MSG_FLAG(0)
|
||||
#define MSG_FLAG_CAPS_LPM_PARTIAL_IO TI_SCI_MSG_FLAG(4)
|
||||
#define MSG_FLAG_CAPS_LPM_DM_MANAGED TI_SCI_MSG_FLAG(5)
|
||||
#define MSG_FLAG_CAPS_LPM_ABORT TI_SCI_MSG_FLAG(9)
|
||||
#define MSG_MASK_CAPS_LPM GENMASK_ULL(4, 1)
|
||||
u64 fw_caps;
|
||||
} __packed;
|
||||
|
|
|
|||
|
|
@ -415,7 +415,7 @@ config I2C_ASPEED
|
|||
|
||||
config I2C_AT91
|
||||
tristate "Atmel AT91 I2C Two-Wire interface (TWI)"
|
||||
depends on ARCH_AT91 || COMPILE_TEST
|
||||
depends on ARCH_MICROCHIP || COMPILE_TEST
|
||||
help
|
||||
This supports the use of the I2C interface on Atmel AT91
|
||||
processors.
|
||||
|
|
|
|||
|
|
@ -870,7 +870,13 @@ static int geni_i2c_probe(struct platform_device *pdev)
|
|||
goto err_clk;
|
||||
}
|
||||
proto = geni_se_read_proto(&gi2c->se);
|
||||
if (proto != GENI_SE_I2C) {
|
||||
if (proto == GENI_SE_INVALID_PROTO) {
|
||||
ret = geni_load_se_firmware(&gi2c->se, GENI_SE_I2C);
|
||||
if (ret) {
|
||||
dev_err_probe(dev, ret, "i2c firmware load failed ret: %d\n", ret);
|
||||
goto err_resources;
|
||||
}
|
||||
} else if (proto != GENI_SE_I2C) {
|
||||
ret = dev_err_probe(dev, -ENXIO, "Invalid proto %d\n", proto);
|
||||
goto err_resources;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -136,8 +136,8 @@ static int venus_load_fw(struct venus_core *core, const char *fwname,
|
|||
ret = qcom_mdt_load(dev, mdt, fwname, VENUS_PAS_ID,
|
||||
mem_va, *mem_phys, *mem_size, NULL);
|
||||
else
|
||||
ret = qcom_mdt_load_no_init(dev, mdt, fwname, VENUS_PAS_ID,
|
||||
mem_va, *mem_phys, *mem_size, NULL);
|
||||
ret = qcom_mdt_load_no_init(dev, mdt, fwname, mem_va,
|
||||
*mem_phys, *mem_size, NULL);
|
||||
|
||||
memunmap(mem_va);
|
||||
err_release_fw:
|
||||
|
|
|
|||
|
|
@ -121,20 +121,18 @@ static int exynos_srom_probe(struct platform_device *pdev)
|
|||
return -ENOMEM;
|
||||
|
||||
srom->dev = dev;
|
||||
srom->reg_base = of_iomap(np, 0);
|
||||
if (!srom->reg_base) {
|
||||
srom->reg_base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(srom->reg_base)) {
|
||||
dev_err(&pdev->dev, "iomap of exynos srom controller failed\n");
|
||||
return -ENOMEM;
|
||||
return PTR_ERR(srom->reg_base);
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, srom);
|
||||
|
||||
srom->reg_offset = exynos_srom_alloc_reg_dump(exynos_srom_offsets,
|
||||
ARRAY_SIZE(exynos_srom_offsets));
|
||||
if (!srom->reg_offset) {
|
||||
iounmap(srom->reg_base);
|
||||
if (!srom->reg_offset)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
for_each_child_of_node(np, child) {
|
||||
if (exynos_srom_configure_bank(srom, child)) {
|
||||
|
|
|
|||
|
|
@ -238,7 +238,7 @@ static int stm32_omm_configure(struct device *dev)
|
|||
if (mux & CR_MUXEN) {
|
||||
ret = of_property_read_u32(dev->of_node, "st,omm-req2ack-ns",
|
||||
&req2ack);
|
||||
if (!ret && !req2ack) {
|
||||
if (!ret && req2ack) {
|
||||
req2ack = DIV_ROUND_UP(req2ack, NSEC_PER_SEC / clk_rate_max) - 1;
|
||||
|
||||
if (req2ack > 256)
|
||||
|
|
|
|||
|
|
@ -9,11 +9,11 @@
|
|||
|
||||
static const struct tegra_mc_client tegra210_mc_clients[] = {
|
||||
{
|
||||
.id = 0x00,
|
||||
.id = TEGRA210_MC_PTCR,
|
||||
.name = "ptcr",
|
||||
.swgroup = TEGRA_SWGROUP_PTC,
|
||||
}, {
|
||||
.id = 0x01,
|
||||
.id = TEGRA210_MC_DISPLAY0A,
|
||||
.name = "display0a",
|
||||
.swgroup = TEGRA_SWGROUP_DC,
|
||||
.regs = {
|
||||
|
|
@ -29,7 +29,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x02,
|
||||
.id = TEGRA210_MC_DISPLAY0AB,
|
||||
.name = "display0ab",
|
||||
.swgroup = TEGRA_SWGROUP_DCB,
|
||||
.regs = {
|
||||
|
|
@ -45,7 +45,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x03,
|
||||
.id = TEGRA210_MC_DISPLAY0B,
|
||||
.name = "display0b",
|
||||
.swgroup = TEGRA_SWGROUP_DC,
|
||||
.regs = {
|
||||
|
|
@ -61,7 +61,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x04,
|
||||
.id = TEGRA210_MC_DISPLAY0BB,
|
||||
.name = "display0bb",
|
||||
.swgroup = TEGRA_SWGROUP_DCB,
|
||||
.regs = {
|
||||
|
|
@ -77,7 +77,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x05,
|
||||
.id = TEGRA210_MC_DISPLAY0C,
|
||||
.name = "display0c",
|
||||
.swgroup = TEGRA_SWGROUP_DC,
|
||||
.regs = {
|
||||
|
|
@ -93,7 +93,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x06,
|
||||
.id = TEGRA210_MC_DISPLAY0CB,
|
||||
.name = "display0cb",
|
||||
.swgroup = TEGRA_SWGROUP_DCB,
|
||||
.regs = {
|
||||
|
|
@ -109,7 +109,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x0e,
|
||||
.id = TEGRA210_MC_AFIR,
|
||||
.name = "afir",
|
||||
.swgroup = TEGRA_SWGROUP_AFI,
|
||||
.regs = {
|
||||
|
|
@ -125,7 +125,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x0f,
|
||||
.id = TEGRA210_MC_AVPCARM7R,
|
||||
.name = "avpcarm7r",
|
||||
.swgroup = TEGRA_SWGROUP_AVPC,
|
||||
.regs = {
|
||||
|
|
@ -141,7 +141,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x10,
|
||||
.id = TEGRA210_MC_DISPLAYHC,
|
||||
.name = "displayhc",
|
||||
.swgroup = TEGRA_SWGROUP_DC,
|
||||
.regs = {
|
||||
|
|
@ -157,7 +157,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x11,
|
||||
.id = TEGRA210_MC_DISPLAYHCB,
|
||||
.name = "displayhcb",
|
||||
.swgroup = TEGRA_SWGROUP_DCB,
|
||||
.regs = {
|
||||
|
|
@ -173,7 +173,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x15,
|
||||
.id = TEGRA210_MC_HDAR,
|
||||
.name = "hdar",
|
||||
.swgroup = TEGRA_SWGROUP_HDA,
|
||||
.regs = {
|
||||
|
|
@ -189,7 +189,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x16,
|
||||
.id = TEGRA210_MC_HOST1XDMAR,
|
||||
.name = "host1xdmar",
|
||||
.swgroup = TEGRA_SWGROUP_HC,
|
||||
.regs = {
|
||||
|
|
@ -205,7 +205,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x17,
|
||||
.id = TEGRA210_MC_HOST1XR,
|
||||
.name = "host1xr",
|
||||
.swgroup = TEGRA_SWGROUP_HC,
|
||||
.regs = {
|
||||
|
|
@ -221,7 +221,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x1c,
|
||||
.id = TEGRA210_MC_NVENCSRD,
|
||||
.name = "nvencsrd",
|
||||
.swgroup = TEGRA_SWGROUP_NVENC,
|
||||
.regs = {
|
||||
|
|
@ -237,7 +237,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x1d,
|
||||
.id = TEGRA210_MC_PPCSAHBDMAR,
|
||||
.name = "ppcsahbdmar",
|
||||
.swgroup = TEGRA_SWGROUP_PPCS,
|
||||
.regs = {
|
||||
|
|
@ -253,7 +253,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x1e,
|
||||
.id = TEGRA210_MC_PPCSAHBSLVR,
|
||||
.name = "ppcsahbslvr",
|
||||
.swgroup = TEGRA_SWGROUP_PPCS,
|
||||
.regs = {
|
||||
|
|
@ -269,7 +269,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x1f,
|
||||
.id = TEGRA210_MC_SATAR,
|
||||
.name = "satar",
|
||||
.swgroup = TEGRA_SWGROUP_SATA,
|
||||
.regs = {
|
||||
|
|
@ -285,7 +285,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x27,
|
||||
.id = TEGRA210_MC_MPCORER,
|
||||
.name = "mpcorer",
|
||||
.swgroup = TEGRA_SWGROUP_MPCORE,
|
||||
.regs = {
|
||||
|
|
@ -297,7 +297,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x2b,
|
||||
.id = TEGRA210_MC_NVENCSWR,
|
||||
.name = "nvencswr",
|
||||
.swgroup = TEGRA_SWGROUP_NVENC,
|
||||
.regs = {
|
||||
|
|
@ -313,7 +313,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x31,
|
||||
.id = TEGRA210_MC_AFIW,
|
||||
.name = "afiw",
|
||||
.swgroup = TEGRA_SWGROUP_AFI,
|
||||
.regs = {
|
||||
|
|
@ -329,7 +329,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x32,
|
||||
.id = TEGRA210_MC_AVPCARM7W,
|
||||
.name = "avpcarm7w",
|
||||
.swgroup = TEGRA_SWGROUP_AVPC,
|
||||
.regs = {
|
||||
|
|
@ -345,7 +345,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x35,
|
||||
.id = TEGRA210_MC_HDAW,
|
||||
.name = "hdaw",
|
||||
.swgroup = TEGRA_SWGROUP_HDA,
|
||||
.regs = {
|
||||
|
|
@ -361,7 +361,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x36,
|
||||
.id = TEGRA210_MC_HOST1XW,
|
||||
.name = "host1xw",
|
||||
.swgroup = TEGRA_SWGROUP_HC,
|
||||
.regs = {
|
||||
|
|
@ -377,7 +377,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x39,
|
||||
.id = TEGRA210_MC_MPCOREW,
|
||||
.name = "mpcorew",
|
||||
.swgroup = TEGRA_SWGROUP_MPCORE,
|
||||
.regs = {
|
||||
|
|
@ -389,7 +389,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x3b,
|
||||
.id = TEGRA210_MC_PPCSAHBDMAW,
|
||||
.name = "ppcsahbdmaw",
|
||||
.swgroup = TEGRA_SWGROUP_PPCS,
|
||||
.regs = {
|
||||
|
|
@ -405,7 +405,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x3c,
|
||||
.id = TEGRA210_MC_PPCSAHBSLVW,
|
||||
.name = "ppcsahbslvw",
|
||||
.swgroup = TEGRA_SWGROUP_PPCS,
|
||||
.regs = {
|
||||
|
|
@ -421,7 +421,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x3d,
|
||||
.id = TEGRA210_MC_SATAW,
|
||||
.name = "sataw",
|
||||
.swgroup = TEGRA_SWGROUP_SATA,
|
||||
.regs = {
|
||||
|
|
@ -437,7 +437,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x44,
|
||||
.id = TEGRA210_MC_ISPRA,
|
||||
.name = "ispra",
|
||||
.swgroup = TEGRA_SWGROUP_ISP2,
|
||||
.regs = {
|
||||
|
|
@ -453,7 +453,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x46,
|
||||
.id = TEGRA210_MC_ISPWA,
|
||||
.name = "ispwa",
|
||||
.swgroup = TEGRA_SWGROUP_ISP2,
|
||||
.regs = {
|
||||
|
|
@ -469,7 +469,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x47,
|
||||
.id = TEGRA210_MC_ISPWB,
|
||||
.name = "ispwb",
|
||||
.swgroup = TEGRA_SWGROUP_ISP2,
|
||||
.regs = {
|
||||
|
|
@ -485,7 +485,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x4a,
|
||||
.id = TEGRA210_MC_XUSB_HOSTR,
|
||||
.name = "xusb_hostr",
|
||||
.swgroup = TEGRA_SWGROUP_XUSB_HOST,
|
||||
.regs = {
|
||||
|
|
@ -501,7 +501,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x4b,
|
||||
.id = TEGRA210_MC_XUSB_HOSTW,
|
||||
.name = "xusb_hostw",
|
||||
.swgroup = TEGRA_SWGROUP_XUSB_HOST,
|
||||
.regs = {
|
||||
|
|
@ -517,7 +517,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x4c,
|
||||
.id = TEGRA210_MC_XUSB_DEVR,
|
||||
.name = "xusb_devr",
|
||||
.swgroup = TEGRA_SWGROUP_XUSB_DEV,
|
||||
.regs = {
|
||||
|
|
@ -533,7 +533,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x4d,
|
||||
.id = TEGRA210_MC_XUSB_DEVW,
|
||||
.name = "xusb_devw",
|
||||
.swgroup = TEGRA_SWGROUP_XUSB_DEV,
|
||||
.regs = {
|
||||
|
|
@ -549,7 +549,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x4e,
|
||||
.id = TEGRA210_MC_ISPRAB,
|
||||
.name = "isprab",
|
||||
.swgroup = TEGRA_SWGROUP_ISP2B,
|
||||
.regs = {
|
||||
|
|
@ -565,7 +565,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x50,
|
||||
.id = TEGRA210_MC_ISPWAB,
|
||||
.name = "ispwab",
|
||||
.swgroup = TEGRA_SWGROUP_ISP2B,
|
||||
.regs = {
|
||||
|
|
@ -581,7 +581,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x51,
|
||||
.id = TEGRA210_MC_ISPWBB,
|
||||
.name = "ispwbb",
|
||||
.swgroup = TEGRA_SWGROUP_ISP2B,
|
||||
.regs = {
|
||||
|
|
@ -597,7 +597,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x54,
|
||||
.id = TEGRA210_MC_TSECSRD,
|
||||
.name = "tsecsrd",
|
||||
.swgroup = TEGRA_SWGROUP_TSEC,
|
||||
.regs = {
|
||||
|
|
@ -613,7 +613,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x55,
|
||||
.id = TEGRA210_MC_TSECSWR,
|
||||
.name = "tsecswr",
|
||||
.swgroup = TEGRA_SWGROUP_TSEC,
|
||||
.regs = {
|
||||
|
|
@ -629,7 +629,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x56,
|
||||
.id = TEGRA210_MC_A9AVPSCR,
|
||||
.name = "a9avpscr",
|
||||
.swgroup = TEGRA_SWGROUP_A9AVP,
|
||||
.regs = {
|
||||
|
|
@ -645,7 +645,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x57,
|
||||
.id = TEGRA210_MC_A9AVPSCW,
|
||||
.name = "a9avpscw",
|
||||
.swgroup = TEGRA_SWGROUP_A9AVP,
|
||||
.regs = {
|
||||
|
|
@ -661,7 +661,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x58,
|
||||
.id = TEGRA210_MC_GPUSRD,
|
||||
.name = "gpusrd",
|
||||
.swgroup = TEGRA_SWGROUP_GPU,
|
||||
.regs = {
|
||||
|
|
@ -678,7 +678,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x59,
|
||||
.id = TEGRA210_MC_GPUSWR,
|
||||
.name = "gpuswr",
|
||||
.swgroup = TEGRA_SWGROUP_GPU,
|
||||
.regs = {
|
||||
|
|
@ -695,7 +695,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x5a,
|
||||
.id = TEGRA210_MC_DISPLAYT,
|
||||
.name = "displayt",
|
||||
.swgroup = TEGRA_SWGROUP_DC,
|
||||
.regs = {
|
||||
|
|
@ -711,7 +711,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x60,
|
||||
.id = TEGRA210_MC_SDMMCRA,
|
||||
.name = "sdmmcra",
|
||||
.swgroup = TEGRA_SWGROUP_SDMMC1A,
|
||||
.regs = {
|
||||
|
|
@ -727,7 +727,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x61,
|
||||
.id = TEGRA210_MC_SDMMCRAA,
|
||||
.name = "sdmmcraa",
|
||||
.swgroup = TEGRA_SWGROUP_SDMMC2A,
|
||||
.regs = {
|
||||
|
|
@ -743,7 +743,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x62,
|
||||
.id = TEGRA210_MC_SDMMCR,
|
||||
.name = "sdmmcr",
|
||||
.swgroup = TEGRA_SWGROUP_SDMMC3A,
|
||||
.regs = {
|
||||
|
|
@ -759,7 +759,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x63,
|
||||
.id = TEGRA210_MC_SDMMCRAB,
|
||||
.swgroup = TEGRA_SWGROUP_SDMMC4A,
|
||||
.name = "sdmmcrab",
|
||||
.regs = {
|
||||
|
|
@ -775,7 +775,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x64,
|
||||
.id = TEGRA210_MC_SDMMCWA,
|
||||
.name = "sdmmcwa",
|
||||
.swgroup = TEGRA_SWGROUP_SDMMC1A,
|
||||
.regs = {
|
||||
|
|
@ -791,7 +791,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x65,
|
||||
.id = TEGRA210_MC_SDMMCWAA,
|
||||
.name = "sdmmcwaa",
|
||||
.swgroup = TEGRA_SWGROUP_SDMMC2A,
|
||||
.regs = {
|
||||
|
|
@ -807,7 +807,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x66,
|
||||
.id = TEGRA210_MC_SDMMCW,
|
||||
.name = "sdmmcw",
|
||||
.swgroup = TEGRA_SWGROUP_SDMMC3A,
|
||||
.regs = {
|
||||
|
|
@ -823,7 +823,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x67,
|
||||
.id = TEGRA210_MC_SDMMCWAB,
|
||||
.name = "sdmmcwab",
|
||||
.swgroup = TEGRA_SWGROUP_SDMMC4A,
|
||||
.regs = {
|
||||
|
|
@ -839,7 +839,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x6c,
|
||||
.id = TEGRA210_MC_VICSRD,
|
||||
.name = "vicsrd",
|
||||
.swgroup = TEGRA_SWGROUP_VIC,
|
||||
.regs = {
|
||||
|
|
@ -855,7 +855,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x6d,
|
||||
.id = TEGRA210_MC_VICSWR,
|
||||
.name = "vicswr",
|
||||
.swgroup = TEGRA_SWGROUP_VIC,
|
||||
.regs = {
|
||||
|
|
@ -871,7 +871,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x72,
|
||||
.id = TEGRA210_MC_VIW,
|
||||
.name = "viw",
|
||||
.swgroup = TEGRA_SWGROUP_VI,
|
||||
.regs = {
|
||||
|
|
@ -887,7 +887,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x73,
|
||||
.id = TEGRA210_MC_DISPLAYD,
|
||||
.name = "displayd",
|
||||
.swgroup = TEGRA_SWGROUP_DC,
|
||||
.regs = {
|
||||
|
|
@ -903,7 +903,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x78,
|
||||
.id = TEGRA210_MC_NVDECSRD,
|
||||
.name = "nvdecsrd",
|
||||
.swgroup = TEGRA_SWGROUP_NVDEC,
|
||||
.regs = {
|
||||
|
|
@ -919,7 +919,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x79,
|
||||
.id = TEGRA210_MC_NVDECSWR,
|
||||
.name = "nvdecswr",
|
||||
.swgroup = TEGRA_SWGROUP_NVDEC,
|
||||
.regs = {
|
||||
|
|
@ -935,7 +935,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x7a,
|
||||
.id = TEGRA210_MC_APER,
|
||||
.name = "aper",
|
||||
.swgroup = TEGRA_SWGROUP_APE,
|
||||
.regs = {
|
||||
|
|
@ -951,7 +951,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x7b,
|
||||
.id = TEGRA210_MC_APEW,
|
||||
.name = "apew",
|
||||
.swgroup = TEGRA_SWGROUP_APE,
|
||||
.regs = {
|
||||
|
|
@ -967,7 +967,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x7e,
|
||||
.id = TEGRA210_MC_NVJPGRD,
|
||||
.name = "nvjpgsrd",
|
||||
.swgroup = TEGRA_SWGROUP_NVJPG,
|
||||
.regs = {
|
||||
|
|
@ -983,7 +983,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x7f,
|
||||
.id = TEGRA210_MC_NVJPGWR,
|
||||
.name = "nvjpgswr",
|
||||
.swgroup = TEGRA_SWGROUP_NVJPG,
|
||||
.regs = {
|
||||
|
|
@ -999,7 +999,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x80,
|
||||
.id = TEGRA210_MC_SESRD,
|
||||
.name = "sesrd",
|
||||
.swgroup = TEGRA_SWGROUP_SE,
|
||||
.regs = {
|
||||
|
|
@ -1015,7 +1015,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x81,
|
||||
.id = TEGRA210_MC_SESRD,
|
||||
.name = "seswr",
|
||||
.swgroup = TEGRA_SWGROUP_SE,
|
||||
.regs = {
|
||||
|
|
@ -1031,7 +1031,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x82,
|
||||
.id = TEGRA210_MC_AXIAPR,
|
||||
.name = "axiapr",
|
||||
.swgroup = TEGRA_SWGROUP_AXIAP,
|
||||
.regs = {
|
||||
|
|
@ -1047,7 +1047,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x83,
|
||||
.id = TEGRA210_MC_AXIAPW,
|
||||
.name = "axiapw",
|
||||
.swgroup = TEGRA_SWGROUP_AXIAP,
|
||||
.regs = {
|
||||
|
|
@ -1063,7 +1063,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x84,
|
||||
.id = TEGRA210_MC_ETRR,
|
||||
.name = "etrr",
|
||||
.swgroup = TEGRA_SWGROUP_ETR,
|
||||
.regs = {
|
||||
|
|
@ -1079,7 +1079,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x85,
|
||||
.id = TEGRA210_MC_ETRR,
|
||||
.name = "etrw",
|
||||
.swgroup = TEGRA_SWGROUP_ETR,
|
||||
.regs = {
|
||||
|
|
@ -1095,7 +1095,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x86,
|
||||
.id = TEGRA210_MC_TSECSRDB,
|
||||
.name = "tsecsrdb",
|
||||
.swgroup = TEGRA_SWGROUP_TSECB,
|
||||
.regs = {
|
||||
|
|
@ -1111,7 +1111,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x87,
|
||||
.id = TEGRA210_MC_TSECSWRB,
|
||||
.name = "tsecswrb",
|
||||
.swgroup = TEGRA_SWGROUP_TSECB,
|
||||
.regs = {
|
||||
|
|
@ -1127,7 +1127,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x88,
|
||||
.id = TEGRA210_MC_GPUSRD2,
|
||||
.name = "gpusrd2",
|
||||
.swgroup = TEGRA_SWGROUP_GPU,
|
||||
.regs = {
|
||||
|
|
@ -1144,7 +1144,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
|
|||
},
|
||||
},
|
||||
}, {
|
||||
.id = 0x89,
|
||||
.id = TEGRA210_MC_GPUSWR2,
|
||||
.name = "gpuswr2",
|
||||
.swgroup = TEGRA_SWGROUP_GPU,
|
||||
.regs = {
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ config MFD_AAT2870_CORE
|
|||
config MFD_AT91_USART
|
||||
tristate "AT91 USART Driver"
|
||||
select MFD_CORE
|
||||
depends on ARCH_AT91 || ARCH_LAN969X || COMPILE_TEST
|
||||
depends on ARCH_MICROCHIP || COMPILE_TEST
|
||||
help
|
||||
Select this to get support for AT91 USART IP. This is a wrapper
|
||||
over at91-usart-serial driver and usart-spi-driver. Only one function
|
||||
|
|
|
|||
|
|
@ -414,7 +414,7 @@ static int ath12k_ahb_power_up(struct ath12k_base *ab)
|
|||
goto err_fw2;
|
||||
}
|
||||
|
||||
ret = qcom_mdt_load_no_init(dev, fw2, fw2_name, pasid, mem_region, mem_phys,
|
||||
ret = qcom_mdt_load_no_init(dev, fw2, fw2_name, mem_region, mem_phys,
|
||||
mem_size, &mem_phys);
|
||||
if (ret) {
|
||||
ath12k_err(ab, "Failed to load MDT segments: %d\n", ret);
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@
|
|||
#include "nvme.h"
|
||||
|
||||
#define APPLE_ANS_BOOT_TIMEOUT USEC_PER_SEC
|
||||
#define APPLE_ANS_MAX_QUEUE_DEPTH 64
|
||||
|
||||
#define APPLE_ANS_COPROC_CPU_CONTROL 0x44
|
||||
#define APPLE_ANS_COPROC_CPU_CONTROL_RUN BIT(4)
|
||||
|
|
@ -75,6 +74,8 @@
|
|||
#define APPLE_NVME_AQ_DEPTH 2
|
||||
#define APPLE_NVME_AQ_MQ_TAG_DEPTH (APPLE_NVME_AQ_DEPTH - 1)
|
||||
|
||||
#define APPLE_NVME_IOSQES 7
|
||||
|
||||
/*
|
||||
* These can be higher, but we need to ensure that any command doesn't
|
||||
* require an sg allocation that needs more than a page of data.
|
||||
|
|
@ -142,6 +143,7 @@ struct apple_nvme_queue {
|
|||
u32 __iomem *sq_db;
|
||||
u32 __iomem *cq_db;
|
||||
|
||||
u16 sq_tail;
|
||||
u16 cq_head;
|
||||
u8 cq_phase;
|
||||
|
||||
|
|
@ -166,11 +168,17 @@ struct apple_nvme_iod {
|
|||
struct scatterlist *sg;
|
||||
};
|
||||
|
||||
struct apple_nvme_hw {
|
||||
bool has_lsq_nvmmu;
|
||||
u32 max_queue_depth;
|
||||
};
|
||||
|
||||
struct apple_nvme {
|
||||
struct device *dev;
|
||||
|
||||
void __iomem *mmio_coproc;
|
||||
void __iomem *mmio_nvme;
|
||||
const struct apple_nvme_hw *hw;
|
||||
|
||||
struct device **pd_dev;
|
||||
struct device_link **pd_link;
|
||||
|
|
@ -215,10 +223,12 @@ static inline struct apple_nvme *queue_to_apple_nvme(struct apple_nvme_queue *q)
|
|||
|
||||
static unsigned int apple_nvme_queue_depth(struct apple_nvme_queue *q)
|
||||
{
|
||||
if (q->is_adminq)
|
||||
struct apple_nvme *anv = queue_to_apple_nvme(q);
|
||||
|
||||
if (q->is_adminq && anv->hw->has_lsq_nvmmu)
|
||||
return APPLE_NVME_AQ_DEPTH;
|
||||
|
||||
return APPLE_ANS_MAX_QUEUE_DEPTH;
|
||||
return anv->hw->max_queue_depth;
|
||||
}
|
||||
|
||||
static void apple_nvme_rtkit_crashed(void *cookie, const void *crashlog, size_t crashlog_size)
|
||||
|
|
@ -280,7 +290,28 @@ static void apple_nvmmu_inval(struct apple_nvme_queue *q, unsigned int tag)
|
|||
"NVMMU TCB invalidation failed\n");
|
||||
}
|
||||
|
||||
static void apple_nvme_submit_cmd(struct apple_nvme_queue *q,
|
||||
static void apple_nvme_submit_cmd_t8015(struct apple_nvme_queue *q,
|
||||
struct nvme_command *cmd)
|
||||
{
|
||||
struct apple_nvme *anv = queue_to_apple_nvme(q);
|
||||
|
||||
spin_lock_irq(&anv->lock);
|
||||
|
||||
if (q->is_adminq)
|
||||
memcpy(&q->sqes[q->sq_tail], cmd, sizeof(*cmd));
|
||||
else
|
||||
memcpy((void *)q->sqes + (q->sq_tail << APPLE_NVME_IOSQES),
|
||||
cmd, sizeof(*cmd));
|
||||
|
||||
if (++q->sq_tail == anv->hw->max_queue_depth)
|
||||
q->sq_tail = 0;
|
||||
|
||||
writel(q->sq_tail, q->sq_db);
|
||||
spin_unlock_irq(&anv->lock);
|
||||
}
|
||||
|
||||
|
||||
static void apple_nvme_submit_cmd_t8103(struct apple_nvme_queue *q,
|
||||
struct nvme_command *cmd)
|
||||
{
|
||||
struct apple_nvme *anv = queue_to_apple_nvme(q);
|
||||
|
|
@ -590,7 +621,8 @@ static inline void apple_nvme_handle_cqe(struct apple_nvme_queue *q,
|
|||
__u16 command_id = READ_ONCE(cqe->command_id);
|
||||
struct request *req;
|
||||
|
||||
apple_nvmmu_inval(q, command_id);
|
||||
if (anv->hw->has_lsq_nvmmu)
|
||||
apple_nvmmu_inval(q, command_id);
|
||||
|
||||
req = nvme_find_rq(apple_nvme_queue_tagset(anv, q), command_id);
|
||||
if (unlikely(!req)) {
|
||||
|
|
@ -685,7 +717,7 @@ static int apple_nvme_create_cq(struct apple_nvme *anv)
|
|||
c.create_cq.opcode = nvme_admin_create_cq;
|
||||
c.create_cq.prp1 = cpu_to_le64(anv->ioq.cq_dma_addr);
|
||||
c.create_cq.cqid = cpu_to_le16(1);
|
||||
c.create_cq.qsize = cpu_to_le16(APPLE_ANS_MAX_QUEUE_DEPTH - 1);
|
||||
c.create_cq.qsize = cpu_to_le16(anv->hw->max_queue_depth - 1);
|
||||
c.create_cq.cq_flags = cpu_to_le16(NVME_QUEUE_PHYS_CONTIG | NVME_CQ_IRQ_ENABLED);
|
||||
c.create_cq.irq_vector = cpu_to_le16(0);
|
||||
|
||||
|
|
@ -713,7 +745,7 @@ static int apple_nvme_create_sq(struct apple_nvme *anv)
|
|||
c.create_sq.opcode = nvme_admin_create_sq;
|
||||
c.create_sq.prp1 = cpu_to_le64(anv->ioq.sq_dma_addr);
|
||||
c.create_sq.sqid = cpu_to_le16(1);
|
||||
c.create_sq.qsize = cpu_to_le16(APPLE_ANS_MAX_QUEUE_DEPTH - 1);
|
||||
c.create_sq.qsize = cpu_to_le16(anv->hw->max_queue_depth - 1);
|
||||
c.create_sq.sq_flags = cpu_to_le16(NVME_QUEUE_PHYS_CONTIG);
|
||||
c.create_sq.cqid = cpu_to_le16(1);
|
||||
|
||||
|
|
@ -765,7 +797,12 @@ static blk_status_t apple_nvme_queue_rq(struct blk_mq_hw_ctx *hctx,
|
|||
}
|
||||
|
||||
nvme_start_request(req);
|
||||
apple_nvme_submit_cmd(q, cmnd);
|
||||
|
||||
if (anv->hw->has_lsq_nvmmu)
|
||||
apple_nvme_submit_cmd_t8103(q, cmnd);
|
||||
else
|
||||
apple_nvme_submit_cmd_t8015(q, cmnd);
|
||||
|
||||
return BLK_STS_OK;
|
||||
|
||||
out_free_cmd:
|
||||
|
|
@ -970,11 +1007,13 @@ static const struct blk_mq_ops apple_nvme_mq_ops = {
|
|||
static void apple_nvme_init_queue(struct apple_nvme_queue *q)
|
||||
{
|
||||
unsigned int depth = apple_nvme_queue_depth(q);
|
||||
struct apple_nvme *anv = queue_to_apple_nvme(q);
|
||||
|
||||
q->cq_head = 0;
|
||||
q->cq_phase = 1;
|
||||
memset(q->tcbs, 0,
|
||||
APPLE_ANS_MAX_QUEUE_DEPTH * sizeof(struct apple_nvmmu_tcb));
|
||||
if (anv->hw->has_lsq_nvmmu)
|
||||
memset(q->tcbs, 0, anv->hw->max_queue_depth
|
||||
* sizeof(struct apple_nvmmu_tcb));
|
||||
memset(q->cqes, 0, depth * sizeof(struct nvme_completion));
|
||||
WRITE_ONCE(q->enabled, true);
|
||||
wmb(); /* ensure the first interrupt sees the initialization */
|
||||
|
|
@ -1069,49 +1108,55 @@ static void apple_nvme_reset_work(struct work_struct *work)
|
|||
|
||||
dma_set_max_seg_size(anv->dev, 0xffffffff);
|
||||
|
||||
/*
|
||||
* Enable NVMMU and linear submission queues.
|
||||
* While we could keep those disabled and pretend this is slightly
|
||||
* more common NVMe controller we'd still need some quirks (e.g.
|
||||
* sq entries will be 128 bytes) and Apple might drop support for
|
||||
* that mode in the future.
|
||||
*/
|
||||
writel(APPLE_ANS_LINEAR_SQ_EN,
|
||||
anv->mmio_nvme + APPLE_ANS_LINEAR_SQ_CTRL);
|
||||
if (anv->hw->has_lsq_nvmmu) {
|
||||
/*
|
||||
* Enable NVMMU and linear submission queues which is required
|
||||
* since T6000.
|
||||
*/
|
||||
writel(APPLE_ANS_LINEAR_SQ_EN,
|
||||
anv->mmio_nvme + APPLE_ANS_LINEAR_SQ_CTRL);
|
||||
|
||||
/* Allow as many pending command as possible for both queues */
|
||||
writel(APPLE_ANS_MAX_QUEUE_DEPTH | (APPLE_ANS_MAX_QUEUE_DEPTH << 16),
|
||||
anv->mmio_nvme + APPLE_ANS_MAX_PEND_CMDS_CTRL);
|
||||
/* Allow as many pending command as possible for both queues */
|
||||
writel(anv->hw->max_queue_depth
|
||||
| (anv->hw->max_queue_depth << 16), anv->mmio_nvme
|
||||
+ APPLE_ANS_MAX_PEND_CMDS_CTRL);
|
||||
|
||||
/* Setup the NVMMU for the maximum admin and IO queue depth */
|
||||
writel(APPLE_ANS_MAX_QUEUE_DEPTH - 1,
|
||||
anv->mmio_nvme + APPLE_NVMMU_NUM_TCBS);
|
||||
/* Setup the NVMMU for the maximum admin and IO queue depth */
|
||||
writel(anv->hw->max_queue_depth - 1,
|
||||
anv->mmio_nvme + APPLE_NVMMU_NUM_TCBS);
|
||||
|
||||
/*
|
||||
* This is probably a chicken bit: without it all commands where any PRP
|
||||
* is set to zero (including those that don't use that field) fail and
|
||||
* the co-processor complains about "completed with err BAD_CMD-" or
|
||||
* a "NULL_PRP_PTR_ERR" in the syslog
|
||||
*/
|
||||
writel(readl(anv->mmio_nvme + APPLE_ANS_UNKNOWN_CTRL) &
|
||||
~APPLE_ANS_PRP_NULL_CHECK,
|
||||
anv->mmio_nvme + APPLE_ANS_UNKNOWN_CTRL);
|
||||
/*
|
||||
* This is probably a chicken bit: without it all commands
|
||||
* where any PRP is set to zero (including those that don't use
|
||||
* that field) fail and the co-processor complains about
|
||||
* "completed with err BAD_CMD-" or a "NULL_PRP_PTR_ERR" in the
|
||||
* syslog
|
||||
*/
|
||||
writel(readl(anv->mmio_nvme + APPLE_ANS_UNKNOWN_CTRL) &
|
||||
~APPLE_ANS_PRP_NULL_CHECK,
|
||||
anv->mmio_nvme + APPLE_ANS_UNKNOWN_CTRL);
|
||||
}
|
||||
|
||||
/* Setup the admin queue */
|
||||
aqa = APPLE_NVME_AQ_DEPTH - 1;
|
||||
if (anv->hw->has_lsq_nvmmu)
|
||||
aqa = APPLE_NVME_AQ_DEPTH - 1;
|
||||
else
|
||||
aqa = anv->hw->max_queue_depth - 1;
|
||||
aqa |= aqa << 16;
|
||||
writel(aqa, anv->mmio_nvme + NVME_REG_AQA);
|
||||
writeq(anv->adminq.sq_dma_addr, anv->mmio_nvme + NVME_REG_ASQ);
|
||||
writeq(anv->adminq.cq_dma_addr, anv->mmio_nvme + NVME_REG_ACQ);
|
||||
|
||||
/* Setup NVMMU for both queues */
|
||||
writeq(anv->adminq.tcb_dma_addr,
|
||||
anv->mmio_nvme + APPLE_NVMMU_ASQ_TCB_BASE);
|
||||
writeq(anv->ioq.tcb_dma_addr,
|
||||
anv->mmio_nvme + APPLE_NVMMU_IOSQ_TCB_BASE);
|
||||
if (anv->hw->has_lsq_nvmmu) {
|
||||
/* Setup NVMMU for both queues */
|
||||
writeq(anv->adminq.tcb_dma_addr,
|
||||
anv->mmio_nvme + APPLE_NVMMU_ASQ_TCB_BASE);
|
||||
writeq(anv->ioq.tcb_dma_addr,
|
||||
anv->mmio_nvme + APPLE_NVMMU_IOSQ_TCB_BASE);
|
||||
}
|
||||
|
||||
anv->ctrl.sqsize =
|
||||
APPLE_ANS_MAX_QUEUE_DEPTH - 1; /* 0's based queue depth */
|
||||
anv->hw->max_queue_depth - 1; /* 0's based queue depth */
|
||||
anv->ctrl.cap = readq(anv->mmio_nvme + NVME_REG_CAP);
|
||||
|
||||
dev_dbg(anv->dev, "Enabling controller now");
|
||||
|
|
@ -1282,8 +1327,9 @@ static int apple_nvme_alloc_tagsets(struct apple_nvme *anv)
|
|||
* both queues. The admin queue gets the first APPLE_NVME_AQ_DEPTH which
|
||||
* must be marked as reserved in the IO queue.
|
||||
*/
|
||||
anv->tagset.reserved_tags = APPLE_NVME_AQ_DEPTH;
|
||||
anv->tagset.queue_depth = APPLE_ANS_MAX_QUEUE_DEPTH - 1;
|
||||
if (anv->hw->has_lsq_nvmmu)
|
||||
anv->tagset.reserved_tags = APPLE_NVME_AQ_DEPTH;
|
||||
anv->tagset.queue_depth = anv->hw->max_queue_depth - 1;
|
||||
anv->tagset.timeout = NVME_IO_TIMEOUT;
|
||||
anv->tagset.numa_node = NUMA_NO_NODE;
|
||||
anv->tagset.cmd_size = sizeof(struct apple_nvme_iod);
|
||||
|
|
@ -1307,6 +1353,7 @@ static int apple_nvme_queue_alloc(struct apple_nvme *anv,
|
|||
struct apple_nvme_queue *q)
|
||||
{
|
||||
unsigned int depth = apple_nvme_queue_depth(q);
|
||||
size_t iosq_size;
|
||||
|
||||
q->cqes = dmam_alloc_coherent(anv->dev,
|
||||
depth * sizeof(struct nvme_completion),
|
||||
|
|
@ -1314,22 +1361,28 @@ static int apple_nvme_queue_alloc(struct apple_nvme *anv,
|
|||
if (!q->cqes)
|
||||
return -ENOMEM;
|
||||
|
||||
q->sqes = dmam_alloc_coherent(anv->dev,
|
||||
depth * sizeof(struct nvme_command),
|
||||
if (anv->hw->has_lsq_nvmmu)
|
||||
iosq_size = depth * sizeof(struct nvme_command);
|
||||
else
|
||||
iosq_size = depth << APPLE_NVME_IOSQES;
|
||||
|
||||
q->sqes = dmam_alloc_coherent(anv->dev, iosq_size,
|
||||
&q->sq_dma_addr, GFP_KERNEL);
|
||||
if (!q->sqes)
|
||||
return -ENOMEM;
|
||||
|
||||
/*
|
||||
* We need the maximum queue depth here because the NVMMU only has a
|
||||
* single depth configuration shared between both queues.
|
||||
*/
|
||||
q->tcbs = dmam_alloc_coherent(anv->dev,
|
||||
APPLE_ANS_MAX_QUEUE_DEPTH *
|
||||
sizeof(struct apple_nvmmu_tcb),
|
||||
&q->tcb_dma_addr, GFP_KERNEL);
|
||||
if (!q->tcbs)
|
||||
return -ENOMEM;
|
||||
if (anv->hw->has_lsq_nvmmu) {
|
||||
/*
|
||||
* We need the maximum queue depth here because the NVMMU only
|
||||
* has a single depth configuration shared between both queues.
|
||||
*/
|
||||
q->tcbs = dmam_alloc_coherent(anv->dev,
|
||||
anv->hw->max_queue_depth *
|
||||
sizeof(struct apple_nvmmu_tcb),
|
||||
&q->tcb_dma_addr, GFP_KERNEL);
|
||||
if (!q->tcbs)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize phase to make sure the allocated and empty memory
|
||||
|
|
@ -1413,6 +1466,12 @@ static struct apple_nvme *apple_nvme_alloc(struct platform_device *pdev)
|
|||
anv->adminq.is_adminq = true;
|
||||
platform_set_drvdata(pdev, anv);
|
||||
|
||||
anv->hw = of_device_get_match_data(&pdev->dev);
|
||||
if (!anv->hw) {
|
||||
ret = -ENODEV;
|
||||
goto put_dev;
|
||||
}
|
||||
|
||||
ret = apple_nvme_attach_genpd(anv);
|
||||
if (ret < 0) {
|
||||
dev_err_probe(dev, ret, "Failed to attach power domains");
|
||||
|
|
@ -1444,10 +1503,17 @@ static struct apple_nvme *apple_nvme_alloc(struct platform_device *pdev)
|
|||
goto put_dev;
|
||||
}
|
||||
|
||||
anv->adminq.sq_db = anv->mmio_nvme + APPLE_ANS_LINEAR_ASQ_DB;
|
||||
anv->adminq.cq_db = anv->mmio_nvme + APPLE_ANS_ACQ_DB;
|
||||
anv->ioq.sq_db = anv->mmio_nvme + APPLE_ANS_LINEAR_IOSQ_DB;
|
||||
anv->ioq.cq_db = anv->mmio_nvme + APPLE_ANS_IOCQ_DB;
|
||||
if (anv->hw->has_lsq_nvmmu) {
|
||||
anv->adminq.sq_db = anv->mmio_nvme + APPLE_ANS_LINEAR_ASQ_DB;
|
||||
anv->adminq.cq_db = anv->mmio_nvme + APPLE_ANS_ACQ_DB;
|
||||
anv->ioq.sq_db = anv->mmio_nvme + APPLE_ANS_LINEAR_IOSQ_DB;
|
||||
anv->ioq.cq_db = anv->mmio_nvme + APPLE_ANS_IOCQ_DB;
|
||||
} else {
|
||||
anv->adminq.sq_db = anv->mmio_nvme + NVME_REG_DBS;
|
||||
anv->adminq.cq_db = anv->mmio_nvme + APPLE_ANS_ACQ_DB;
|
||||
anv->ioq.sq_db = anv->mmio_nvme + NVME_REG_DBS + 8;
|
||||
anv->ioq.cq_db = anv->mmio_nvme + APPLE_ANS_IOCQ_DB;
|
||||
}
|
||||
|
||||
anv->sart = devm_apple_sart_get(dev);
|
||||
if (IS_ERR(anv->sart)) {
|
||||
|
|
@ -1625,8 +1691,19 @@ static int apple_nvme_suspend(struct device *dev)
|
|||
static DEFINE_SIMPLE_DEV_PM_OPS(apple_nvme_pm_ops, apple_nvme_suspend,
|
||||
apple_nvme_resume);
|
||||
|
||||
static const struct apple_nvme_hw apple_nvme_t8015_hw = {
|
||||
.has_lsq_nvmmu = false,
|
||||
.max_queue_depth = 16,
|
||||
};
|
||||
|
||||
static const struct apple_nvme_hw apple_nvme_t8103_hw = {
|
||||
.has_lsq_nvmmu = true,
|
||||
.max_queue_depth = 64,
|
||||
};
|
||||
|
||||
static const struct of_device_id apple_nvme_of_match[] = {
|
||||
{ .compatible = "apple,nvme-ans2" },
|
||||
{ .compatible = "apple,t8015-nvme-ans2", .data = &apple_nvme_t8015_hw },
|
||||
{ .compatible = "apple,nvme-ans2", .data = &apple_nvme_t8103_hw },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, apple_nvme_of_match);
|
||||
|
|
|
|||
|
|
@ -515,6 +515,7 @@ static int apple_gpio_pinctrl_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
static const struct of_device_id apple_gpio_pinctrl_of_match[] = {
|
||||
{ .compatible = "apple,t8103-pinctrl", },
|
||||
{ .compatible = "apple,pinctrl", },
|
||||
{ }
|
||||
};
|
||||
|
|
|
|||
|
|
@ -306,6 +306,7 @@ err_remove:
|
|||
}
|
||||
|
||||
static const struct of_device_id apple_pmgr_ps_of_match[] = {
|
||||
{ .compatible = "apple,t8103-pmgr-pwrstate" },
|
||||
{ .compatible = "apple,pmgr-pwrstate" },
|
||||
{}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -317,7 +317,7 @@ static int adsp_load(struct rproc *rproc, const struct firmware *fw)
|
|||
struct qcom_adsp *adsp = rproc->priv;
|
||||
int ret;
|
||||
|
||||
ret = qcom_mdt_load_no_init(adsp->dev, fw, rproc->firmware, 0,
|
||||
ret = qcom_mdt_load_no_init(adsp->dev, fw, rproc->firmware,
|
||||
adsp->mem_region, adsp->mem_phys,
|
||||
adsp->mem_size, &adsp->mem_reloc);
|
||||
if (ret)
|
||||
|
|
|
|||
|
|
@ -242,9 +242,8 @@ static int qcom_pas_load(struct rproc *rproc, const struct firmware *fw)
|
|||
goto release_dtb_firmware;
|
||||
|
||||
ret = qcom_mdt_load_no_init(pas->dev, pas->dtb_firmware, pas->dtb_firmware_name,
|
||||
pas->dtb_pas_id, pas->dtb_mem_region,
|
||||
pas->dtb_mem_phys, pas->dtb_mem_size,
|
||||
&pas->dtb_mem_reloc);
|
||||
pas->dtb_mem_region, pas->dtb_mem_phys,
|
||||
pas->dtb_mem_size, &pas->dtb_mem_reloc);
|
||||
if (ret)
|
||||
goto release_dtb_metadata;
|
||||
}
|
||||
|
|
@ -307,7 +306,7 @@ static int qcom_pas_start(struct rproc *rproc)
|
|||
if (ret)
|
||||
goto disable_px_supply;
|
||||
|
||||
ret = qcom_mdt_load_no_init(pas->dev, pas->firmware, rproc->firmware, pas->pas_id,
|
||||
ret = qcom_mdt_load_no_init(pas->dev, pas->firmware, rproc->firmware,
|
||||
pas->mem_region, pas->mem_phys, pas->mem_size,
|
||||
&pas->mem_reloc);
|
||||
if (ret)
|
||||
|
|
|
|||
|
|
@ -757,7 +757,7 @@ static int q6v5_wcss_load(struct rproc *rproc, const struct firmware *fw)
|
|||
int ret;
|
||||
|
||||
ret = qcom_mdt_load_no_init(wcss->dev, fw, rproc->firmware,
|
||||
0, wcss->mem_region, wcss->mem_phys,
|
||||
wcss->mem_region, wcss->mem_phys,
|
||||
wcss->mem_size, &wcss->mem_reloc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,13 @@ config RESET_A10SR
|
|||
This option enables support for the external reset functions for
|
||||
peripheral PHYs on the Altera Arria10 System Resource Chip.
|
||||
|
||||
config RESET_ASPEED
|
||||
tristate "ASPEED Reset Driver"
|
||||
depends on ARCH_ASPEED || COMPILE_TEST
|
||||
select AUXILIARY_BUS
|
||||
help
|
||||
This enables the reset controller driver for AST2700.
|
||||
|
||||
config RESET_ATH79
|
||||
bool "AR71xx Reset Driver" if COMPILE_TEST
|
||||
default ATH79
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ obj-y += starfive/
|
|||
obj-y += sti/
|
||||
obj-y += tegra/
|
||||
obj-$(CONFIG_RESET_A10SR) += reset-a10sr.o
|
||||
obj-$(CONFIG_RESET_ASPEED) += reset-aspeed.o
|
||||
obj-$(CONFIG_RESET_ATH79) += reset-ath79.o
|
||||
obj-$(CONFIG_RESET_AXS10X) += reset-axs10x.o
|
||||
obj-$(CONFIG_RESET_BCM6345) += reset-bcm6345.o
|
||||
|
|
|
|||
|
|
@ -0,0 +1,253 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (c) 2024 ASPEED Technology Inc.
|
||||
*/
|
||||
|
||||
#include <linux/auxiliary_bus.h>
|
||||
#include <linux/cleanup.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/reset-controller.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <dt-bindings/reset/aspeed,ast2700-scu.h>
|
||||
|
||||
#define SCU0_RESET_CTRL1 0x200
|
||||
#define SCU0_RESET_CTRL2 0x220
|
||||
#define SCU1_RESET_CTRL1 0x200
|
||||
#define SCU1_RESET_CTRL2 0x220
|
||||
#define SCU1_PCIE3_CTRL 0x908
|
||||
|
||||
struct ast2700_reset_signal {
|
||||
bool dedicated_clr; /* dedicated reset clr offset */
|
||||
u32 offset, bit;
|
||||
};
|
||||
|
||||
struct aspeed_reset_info {
|
||||
unsigned int nr_resets;
|
||||
const struct ast2700_reset_signal *signal;
|
||||
};
|
||||
|
||||
struct aspeed_reset {
|
||||
struct reset_controller_dev rcdev;
|
||||
struct aspeed_reset_info *info;
|
||||
spinlock_t lock; /* Protect read-modify-write cycle */
|
||||
void __iomem *base;
|
||||
};
|
||||
|
||||
static const struct ast2700_reset_signal ast2700_reset0_signals[] = {
|
||||
[SCU0_RESET_SDRAM] = { true, SCU0_RESET_CTRL1, BIT(0) },
|
||||
[SCU0_RESET_DDRPHY] = { true, SCU0_RESET_CTRL1, BIT(1) },
|
||||
[SCU0_RESET_RSA] = { true, SCU0_RESET_CTRL1, BIT(2) },
|
||||
[SCU0_RESET_SHA3] = { true, SCU0_RESET_CTRL1, BIT(3) },
|
||||
[SCU0_RESET_HACE] = { true, SCU0_RESET_CTRL1, BIT(4) },
|
||||
[SCU0_RESET_SOC] = { true, SCU0_RESET_CTRL1, BIT(5) },
|
||||
[SCU0_RESET_VIDEO] = { true, SCU0_RESET_CTRL1, BIT(6) },
|
||||
[SCU0_RESET_2D] = { true, SCU0_RESET_CTRL1, BIT(7) },
|
||||
[SCU0_RESET_PCIS] = { true, SCU0_RESET_CTRL1, BIT(8) },
|
||||
[SCU0_RESET_RVAS0] = { true, SCU0_RESET_CTRL1, BIT(9) },
|
||||
[SCU0_RESET_RVAS1] = { true, SCU0_RESET_CTRL1, BIT(10) },
|
||||
[SCU0_RESET_SM3] = { true, SCU0_RESET_CTRL1, BIT(11) },
|
||||
[SCU0_RESET_SM4] = { true, SCU0_RESET_CTRL1, BIT(12) },
|
||||
[SCU0_RESET_CRT0] = { true, SCU0_RESET_CTRL1, BIT(13) },
|
||||
[SCU0_RESET_ECC] = { true, SCU0_RESET_CTRL1, BIT(14) },
|
||||
[SCU0_RESET_DP_PCI] = { true, SCU0_RESET_CTRL1, BIT(15) },
|
||||
[SCU0_RESET_UFS] = { true, SCU0_RESET_CTRL1, BIT(16) },
|
||||
[SCU0_RESET_EMMC] = { true, SCU0_RESET_CTRL1, BIT(17) },
|
||||
[SCU0_RESET_PCIE1RST] = { true, SCU0_RESET_CTRL1, BIT(18) },
|
||||
[SCU0_RESET_PCIE1RSTOE] = { true, SCU0_RESET_CTRL1, BIT(19) },
|
||||
[SCU0_RESET_PCIE0RST] = { true, SCU0_RESET_CTRL1, BIT(20) },
|
||||
[SCU0_RESET_PCIE0RSTOE] = { true, SCU0_RESET_CTRL1, BIT(21) },
|
||||
[SCU0_RESET_JTAG] = { true, SCU0_RESET_CTRL1, BIT(22) },
|
||||
[SCU0_RESET_MCTP0] = { true, SCU0_RESET_CTRL1, BIT(23) },
|
||||
[SCU0_RESET_MCTP1] = { true, SCU0_RESET_CTRL1, BIT(24) },
|
||||
[SCU0_RESET_XDMA0] = { true, SCU0_RESET_CTRL1, BIT(25) },
|
||||
[SCU0_RESET_XDMA1] = { true, SCU0_RESET_CTRL1, BIT(26) },
|
||||
[SCU0_RESET_H2X1] = { true, SCU0_RESET_CTRL1, BIT(27) },
|
||||
[SCU0_RESET_DP] = { true, SCU0_RESET_CTRL1, BIT(28) },
|
||||
[SCU0_RESET_DP_MCU] = { true, SCU0_RESET_CTRL1, BIT(29) },
|
||||
[SCU0_RESET_SSP] = { true, SCU0_RESET_CTRL1, BIT(30) },
|
||||
[SCU0_RESET_H2X0] = { true, SCU0_RESET_CTRL1, BIT(31) },
|
||||
[SCU0_RESET_PORTA_VHUB] = { true, SCU0_RESET_CTRL2, BIT(0) },
|
||||
[SCU0_RESET_PORTA_PHY3] = { true, SCU0_RESET_CTRL2, BIT(1) },
|
||||
[SCU0_RESET_PORTA_XHCI] = { true, SCU0_RESET_CTRL2, BIT(2) },
|
||||
[SCU0_RESET_PORTB_VHUB] = { true, SCU0_RESET_CTRL2, BIT(3) },
|
||||
[SCU0_RESET_PORTB_PHY3] = { true, SCU0_RESET_CTRL2, BIT(4) },
|
||||
[SCU0_RESET_PORTB_XHCI] = { true, SCU0_RESET_CTRL2, BIT(5) },
|
||||
[SCU0_RESET_PORTA_VHUB_EHCI] = { true, SCU0_RESET_CTRL2, BIT(6) },
|
||||
[SCU0_RESET_PORTB_VHUB_EHCI] = { true, SCU0_RESET_CTRL2, BIT(7) },
|
||||
[SCU0_RESET_UHCI] = { true, SCU0_RESET_CTRL2, BIT(8) },
|
||||
[SCU0_RESET_TSP] = { true, SCU0_RESET_CTRL2, BIT(9) },
|
||||
[SCU0_RESET_E2M0] = { true, SCU0_RESET_CTRL2, BIT(10) },
|
||||
[SCU0_RESET_E2M1] = { true, SCU0_RESET_CTRL2, BIT(11) },
|
||||
[SCU0_RESET_VLINK] = { true, SCU0_RESET_CTRL2, BIT(12) },
|
||||
};
|
||||
|
||||
static const struct ast2700_reset_signal ast2700_reset1_signals[] = {
|
||||
[SCU1_RESET_LPC0] = { true, SCU1_RESET_CTRL1, BIT(0) },
|
||||
[SCU1_RESET_LPC1] = { true, SCU1_RESET_CTRL1, BIT(1) },
|
||||
[SCU1_RESET_MII] = { true, SCU1_RESET_CTRL1, BIT(2) },
|
||||
[SCU1_RESET_PECI] = { true, SCU1_RESET_CTRL1, BIT(3) },
|
||||
[SCU1_RESET_PWM] = { true, SCU1_RESET_CTRL1, BIT(4) },
|
||||
[SCU1_RESET_MAC0] = { true, SCU1_RESET_CTRL1, BIT(5) },
|
||||
[SCU1_RESET_MAC1] = { true, SCU1_RESET_CTRL1, BIT(6) },
|
||||
[SCU1_RESET_MAC2] = { true, SCU1_RESET_CTRL1, BIT(7) },
|
||||
[SCU1_RESET_ADC] = { true, SCU1_RESET_CTRL1, BIT(8) },
|
||||
[SCU1_RESET_SD] = { true, SCU1_RESET_CTRL1, BIT(9) },
|
||||
[SCU1_RESET_ESPI0] = { true, SCU1_RESET_CTRL1, BIT(10) },
|
||||
[SCU1_RESET_ESPI1] = { true, SCU1_RESET_CTRL1, BIT(11) },
|
||||
[SCU1_RESET_JTAG1] = { true, SCU1_RESET_CTRL1, BIT(12) },
|
||||
[SCU1_RESET_SPI0] = { true, SCU1_RESET_CTRL1, BIT(13) },
|
||||
[SCU1_RESET_SPI1] = { true, SCU1_RESET_CTRL1, BIT(14) },
|
||||
[SCU1_RESET_SPI2] = { true, SCU1_RESET_CTRL1, BIT(15) },
|
||||
[SCU1_RESET_I3C0] = { true, SCU1_RESET_CTRL1, BIT(16) },
|
||||
[SCU1_RESET_I3C1] = { true, SCU1_RESET_CTRL1, BIT(17) },
|
||||
[SCU1_RESET_I3C2] = { true, SCU1_RESET_CTRL1, BIT(18) },
|
||||
[SCU1_RESET_I3C3] = { true, SCU1_RESET_CTRL1, BIT(19) },
|
||||
[SCU1_RESET_I3C4] = { true, SCU1_RESET_CTRL1, BIT(20) },
|
||||
[SCU1_RESET_I3C5] = { true, SCU1_RESET_CTRL1, BIT(21) },
|
||||
[SCU1_RESET_I3C6] = { true, SCU1_RESET_CTRL1, BIT(22) },
|
||||
[SCU1_RESET_I3C7] = { true, SCU1_RESET_CTRL1, BIT(23) },
|
||||
[SCU1_RESET_I3C8] = { true, SCU1_RESET_CTRL1, BIT(24) },
|
||||
[SCU1_RESET_I3C9] = { true, SCU1_RESET_CTRL1, BIT(25) },
|
||||
[SCU1_RESET_I3C10] = { true, SCU1_RESET_CTRL1, BIT(26) },
|
||||
[SCU1_RESET_I3C11] = { true, SCU1_RESET_CTRL1, BIT(27) },
|
||||
[SCU1_RESET_I3C12] = { true, SCU1_RESET_CTRL1, BIT(28) },
|
||||
[SCU1_RESET_I3C13] = { true, SCU1_RESET_CTRL1, BIT(29) },
|
||||
[SCU1_RESET_I3C14] = { true, SCU1_RESET_CTRL1, BIT(30) },
|
||||
[SCU1_RESET_I3C15] = { true, SCU1_RESET_CTRL1, BIT(31) },
|
||||
[SCU1_RESET_MCU0] = { true, SCU1_RESET_CTRL2, BIT(0) },
|
||||
[SCU1_RESET_MCU1] = { true, SCU1_RESET_CTRL2, BIT(1) },
|
||||
[SCU1_RESET_H2A_SPI1] = { true, SCU1_RESET_CTRL2, BIT(2) },
|
||||
[SCU1_RESET_H2A_SPI2] = { true, SCU1_RESET_CTRL2, BIT(3) },
|
||||
[SCU1_RESET_UART0] = { true, SCU1_RESET_CTRL2, BIT(4) },
|
||||
[SCU1_RESET_UART1] = { true, SCU1_RESET_CTRL2, BIT(5) },
|
||||
[SCU1_RESET_UART2] = { true, SCU1_RESET_CTRL2, BIT(6) },
|
||||
[SCU1_RESET_UART3] = { true, SCU1_RESET_CTRL2, BIT(7) },
|
||||
[SCU1_RESET_I2C_FILTER] = { true, SCU1_RESET_CTRL2, BIT(8) },
|
||||
[SCU1_RESET_CALIPTRA] = { true, SCU1_RESET_CTRL2, BIT(9) },
|
||||
[SCU1_RESET_XDMA] = { true, SCU1_RESET_CTRL2, BIT(10) },
|
||||
[SCU1_RESET_FSI] = { true, SCU1_RESET_CTRL2, BIT(12) },
|
||||
[SCU1_RESET_CAN] = { true, SCU1_RESET_CTRL2, BIT(13) },
|
||||
[SCU1_RESET_MCTP] = { true, SCU1_RESET_CTRL2, BIT(14) },
|
||||
[SCU1_RESET_I2C] = { true, SCU1_RESET_CTRL2, BIT(15) },
|
||||
[SCU1_RESET_UART6] = { true, SCU1_RESET_CTRL2, BIT(16) },
|
||||
[SCU1_RESET_UART7] = { true, SCU1_RESET_CTRL2, BIT(17) },
|
||||
[SCU1_RESET_UART8] = { true, SCU1_RESET_CTRL2, BIT(18) },
|
||||
[SCU1_RESET_UART9] = { true, SCU1_RESET_CTRL2, BIT(19) },
|
||||
[SCU1_RESET_LTPI0] = { true, SCU1_RESET_CTRL2, BIT(20) },
|
||||
[SCU1_RESET_VGAL] = { true, SCU1_RESET_CTRL2, BIT(21) },
|
||||
[SCU1_RESET_LTPI1] = { true, SCU1_RESET_CTRL2, BIT(22) },
|
||||
[SCU1_RESET_ACE] = { true, SCU1_RESET_CTRL2, BIT(23) },
|
||||
[SCU1_RESET_E2M] = { true, SCU1_RESET_CTRL2, BIT(24) },
|
||||
[SCU1_RESET_UHCI] = { true, SCU1_RESET_CTRL2, BIT(25) },
|
||||
[SCU1_RESET_PORTC_USB2UART] = { true, SCU1_RESET_CTRL2, BIT(26) },
|
||||
[SCU1_RESET_PORTC_VHUB_EHCI] = { true, SCU1_RESET_CTRL2, BIT(27) },
|
||||
[SCU1_RESET_PORTD_USB2UART] = { true, SCU1_RESET_CTRL2, BIT(28) },
|
||||
[SCU1_RESET_PORTD_VHUB_EHCI] = { true, SCU1_RESET_CTRL2, BIT(29) },
|
||||
[SCU1_RESET_H2X] = { true, SCU1_RESET_CTRL2, BIT(30) },
|
||||
[SCU1_RESET_I3CDMA] = { true, SCU1_RESET_CTRL2, BIT(31) },
|
||||
[SCU1_RESET_PCIE2RST] = { false, SCU1_PCIE3_CTRL, BIT(0) },
|
||||
};
|
||||
|
||||
static inline struct aspeed_reset *to_aspeed_reset(struct reset_controller_dev *rcdev)
|
||||
{
|
||||
return container_of(rcdev, struct aspeed_reset, rcdev);
|
||||
}
|
||||
|
||||
static int aspeed_reset_assert(struct reset_controller_dev *rcdev, unsigned long id)
|
||||
{
|
||||
struct aspeed_reset *rc = to_aspeed_reset(rcdev);
|
||||
void __iomem *reg_offset = rc->base + rc->info->signal[id].offset;
|
||||
|
||||
if (rc->info->signal[id].dedicated_clr) {
|
||||
writel(rc->info->signal[id].bit, reg_offset);
|
||||
} else {
|
||||
guard(spinlock_irqsave)(&rc->lock);
|
||||
writel(readl(reg_offset) & ~rc->info->signal[id].bit, reg_offset);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aspeed_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id)
|
||||
{
|
||||
struct aspeed_reset *rc = to_aspeed_reset(rcdev);
|
||||
void __iomem *reg_offset = rc->base + rc->info->signal[id].offset;
|
||||
|
||||
if (rc->info->signal[id].dedicated_clr) {
|
||||
writel(rc->info->signal[id].bit, reg_offset + 0x04);
|
||||
} else {
|
||||
guard(spinlock_irqsave)(&rc->lock);
|
||||
writel(readl(reg_offset) | rc->info->signal[id].bit, reg_offset);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aspeed_reset_status(struct reset_controller_dev *rcdev, unsigned long id)
|
||||
{
|
||||
struct aspeed_reset *rc = to_aspeed_reset(rcdev);
|
||||
void __iomem *reg_offset = rc->base + rc->info->signal[id].offset;
|
||||
|
||||
return (readl(reg_offset) & rc->info->signal[id].bit) ? 1 : 0;
|
||||
}
|
||||
|
||||
static const struct reset_control_ops aspeed_reset_ops = {
|
||||
.assert = aspeed_reset_assert,
|
||||
.deassert = aspeed_reset_deassert,
|
||||
.status = aspeed_reset_status,
|
||||
};
|
||||
|
||||
static int aspeed_reset_probe(struct auxiliary_device *adev,
|
||||
const struct auxiliary_device_id *id)
|
||||
{
|
||||
struct aspeed_reset *reset;
|
||||
struct device *dev = &adev->dev;
|
||||
|
||||
reset = devm_kzalloc(dev, sizeof(*reset), GFP_KERNEL);
|
||||
if (!reset)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&reset->lock);
|
||||
|
||||
reset->info = (struct aspeed_reset_info *)id->driver_data;
|
||||
reset->rcdev.owner = THIS_MODULE;
|
||||
reset->rcdev.nr_resets = reset->info->nr_resets;
|
||||
reset->rcdev.ops = &aspeed_reset_ops;
|
||||
reset->rcdev.of_node = dev->parent->of_node;
|
||||
reset->rcdev.dev = dev;
|
||||
reset->rcdev.of_reset_n_cells = 1;
|
||||
reset->base = (void __iomem *)adev->dev.platform_data;
|
||||
|
||||
return devm_reset_controller_register(dev, &reset->rcdev);
|
||||
}
|
||||
|
||||
static const struct aspeed_reset_info ast2700_reset0_info = {
|
||||
.nr_resets = ARRAY_SIZE(ast2700_reset0_signals),
|
||||
.signal = ast2700_reset0_signals,
|
||||
};
|
||||
|
||||
static const struct aspeed_reset_info ast2700_reset1_info = {
|
||||
.nr_resets = ARRAY_SIZE(ast2700_reset1_signals),
|
||||
.signal = ast2700_reset1_signals,
|
||||
};
|
||||
|
||||
static const struct auxiliary_device_id aspeed_reset_ids[] = {
|
||||
{ .name = "clk_ast2700.reset0", .driver_data = (kernel_ulong_t)&ast2700_reset0_info },
|
||||
{ .name = "clk_ast2700.reset1", .driver_data = (kernel_ulong_t)&ast2700_reset1_info },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(auxiliary, aspeed_reset_ids);
|
||||
|
||||
static struct auxiliary_driver aspeed_reset_driver = {
|
||||
.probe = aspeed_reset_probe,
|
||||
.id_table = aspeed_reset_ids,
|
||||
};
|
||||
|
||||
module_auxiliary_driver(aspeed_reset_driver);
|
||||
|
||||
MODULE_AUTHOR("Ryan Chen <ryan_chen@aspeedtech.com>");
|
||||
MODULE_DESCRIPTION("ASPEED SoC Reset Controller Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
@ -119,6 +119,7 @@ static int bcm6345_reset_probe(struct platform_device *pdev)
|
|||
|
||||
static const struct of_device_id bcm6345_reset_of_match[] = {
|
||||
{ .compatible = "brcm,bcm6345-reset" },
|
||||
{ .compatible = "brcm,bcm63xx-ephy-ctrl" },
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@ static const struct regmap_config intel_rcu_regmap_config = {
|
|||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ static const struct regmap_config pdc_regmap_config = {
|
|||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.max_register = 0x20000,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
static const struct qcom_pdc_reset_map sdm845_pdc_resets[] = {
|
||||
|
|
|
|||
|
|
@ -14,10 +14,20 @@
|
|||
/* register offset in VOSYS_REGMAP */
|
||||
#define TH1520_GPU_RST_CFG 0x0
|
||||
#define TH1520_GPU_RST_CFG_MASK GENMASK(1, 0)
|
||||
#define TH1520_DPU_RST_CFG 0x4
|
||||
#define TH1520_DSI0_RST_CFG 0x8
|
||||
#define TH1520_DSI1_RST_CFG 0xc
|
||||
#define TH1520_HDMI_RST_CFG 0x14
|
||||
|
||||
/* register values */
|
||||
#define TH1520_GPU_SW_GPU_RST BIT(0)
|
||||
#define TH1520_GPU_SW_CLKGEN_RST BIT(1)
|
||||
#define TH1520_DPU_SW_DPU_HRST BIT(0)
|
||||
#define TH1520_DPU_SW_DPU_ARST BIT(1)
|
||||
#define TH1520_DPU_SW_DPU_CRST BIT(2)
|
||||
#define TH1520_DSI_SW_DSI_PRST BIT(0)
|
||||
#define TH1520_HDMI_SW_MAIN_RST BIT(0)
|
||||
#define TH1520_HDMI_SW_PRST BIT(1)
|
||||
|
||||
struct th1520_reset_priv {
|
||||
struct reset_controller_dev rcdev;
|
||||
|
|
@ -37,7 +47,35 @@ static const struct th1520_reset_map th1520_resets[] = {
|
|||
[TH1520_RESET_ID_GPU_CLKGEN] = {
|
||||
.bit = TH1520_GPU_SW_CLKGEN_RST,
|
||||
.reg = TH1520_GPU_RST_CFG,
|
||||
}
|
||||
},
|
||||
[TH1520_RESET_ID_DPU_AHB] = {
|
||||
.bit = TH1520_DPU_SW_DPU_HRST,
|
||||
.reg = TH1520_DPU_RST_CFG,
|
||||
},
|
||||
[TH1520_RESET_ID_DPU_AXI] = {
|
||||
.bit = TH1520_DPU_SW_DPU_ARST,
|
||||
.reg = TH1520_DPU_RST_CFG,
|
||||
},
|
||||
[TH1520_RESET_ID_DPU_CORE] = {
|
||||
.bit = TH1520_DPU_SW_DPU_CRST,
|
||||
.reg = TH1520_DPU_RST_CFG,
|
||||
},
|
||||
[TH1520_RESET_ID_DSI0_APB] = {
|
||||
.bit = TH1520_DSI_SW_DSI_PRST,
|
||||
.reg = TH1520_DSI0_RST_CFG,
|
||||
},
|
||||
[TH1520_RESET_ID_DSI1_APB] = {
|
||||
.bit = TH1520_DSI_SW_DSI_PRST,
|
||||
.reg = TH1520_DSI1_RST_CFG,
|
||||
},
|
||||
[TH1520_RESET_ID_HDMI] = {
|
||||
.bit = TH1520_HDMI_SW_MAIN_RST,
|
||||
.reg = TH1520_HDMI_RST_CFG,
|
||||
},
|
||||
[TH1520_RESET_ID_HDMI_APB] = {
|
||||
.bit = TH1520_HDMI_SW_PRST,
|
||||
.reg = TH1520_HDMI_RST_CFG,
|
||||
},
|
||||
};
|
||||
|
||||
static inline struct th1520_reset_priv *
|
||||
|
|
@ -78,7 +116,6 @@ static const struct regmap_config th1520_reset_regmap_config = {
|
|||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
static int th1520_reset_probe(struct platform_device *pdev)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ config APPLE_MAILBOX
|
|||
tristate "Apple SoC mailboxes"
|
||||
depends on PM
|
||||
depends on ARCH_APPLE || (64BIT && COMPILE_TEST)
|
||||
default ARCH_APPLE
|
||||
help
|
||||
Apple SoCs have various co-processors required for certain
|
||||
peripherals to work (NVMe, display controller, etc.). This
|
||||
|
|
@ -21,7 +20,6 @@ config APPLE_RTKIT
|
|||
tristate "Apple RTKit co-processor IPC protocol"
|
||||
depends on APPLE_MAILBOX
|
||||
depends on ARCH_APPLE || COMPILE_TEST
|
||||
default ARCH_APPLE
|
||||
help
|
||||
Apple SoCs such as the M1 come with various co-processors running
|
||||
their proprietary RTKit operating system. This option enables support
|
||||
|
|
@ -33,7 +31,6 @@ config APPLE_RTKIT
|
|||
config APPLE_SART
|
||||
tristate "Apple SART DMA address filter"
|
||||
depends on ARCH_APPLE || COMPILE_TEST
|
||||
default ARCH_APPLE
|
||||
help
|
||||
Apple SART is a simple DMA address filter used on Apple SoCs such
|
||||
as the M1. It is usually required for the NVMe coprocessor which does
|
||||
|
|
|
|||
|
|
@ -47,6 +47,9 @@
|
|||
#define APPLE_ASC_MBOX_I2A_RECV0 0x830
|
||||
#define APPLE_ASC_MBOX_I2A_RECV1 0x838
|
||||
|
||||
#define APPLE_T8015_MBOX_A2I_CONTROL 0x108
|
||||
#define APPLE_T8015_MBOX_I2A_CONTROL 0x10c
|
||||
|
||||
#define APPLE_M3_MBOX_CONTROL_FULL BIT(16)
|
||||
#define APPLE_M3_MBOX_CONTROL_EMPTY BIT(17)
|
||||
|
||||
|
|
@ -382,6 +385,21 @@ static int apple_mbox_probe(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const struct apple_mbox_hw apple_mbox_t8015_hw = {
|
||||
.control_full = APPLE_ASC_MBOX_CONTROL_FULL,
|
||||
.control_empty = APPLE_ASC_MBOX_CONTROL_EMPTY,
|
||||
|
||||
.a2i_control = APPLE_T8015_MBOX_A2I_CONTROL,
|
||||
.a2i_send0 = APPLE_ASC_MBOX_A2I_SEND0,
|
||||
.a2i_send1 = APPLE_ASC_MBOX_A2I_SEND1,
|
||||
|
||||
.i2a_control = APPLE_T8015_MBOX_I2A_CONTROL,
|
||||
.i2a_recv0 = APPLE_ASC_MBOX_I2A_RECV0,
|
||||
.i2a_recv1 = APPLE_ASC_MBOX_I2A_RECV1,
|
||||
|
||||
.has_irq_controls = false,
|
||||
};
|
||||
|
||||
static const struct apple_mbox_hw apple_mbox_asc_hw = {
|
||||
.control_full = APPLE_ASC_MBOX_CONTROL_FULL,
|
||||
.control_empty = APPLE_ASC_MBOX_CONTROL_EMPTY,
|
||||
|
|
@ -418,6 +436,7 @@ static const struct apple_mbox_hw apple_mbox_m3_hw = {
|
|||
|
||||
static const struct of_device_id apple_mbox_of_match[] = {
|
||||
{ .compatible = "apple,asc-mailbox-v4", .data = &apple_mbox_asc_hw },
|
||||
{ .compatible = "apple,t8015-asc-mailbox", .data = &apple_mbox_t8015_hw },
|
||||
{ .compatible = "apple,m3-mailbox-v2", .data = &apple_mbox_m3_hw },
|
||||
{}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -25,8 +25,17 @@
|
|||
|
||||
#define APPLE_SART_MAX_ENTRIES 16
|
||||
|
||||
/* This is probably a bitfield but the exact meaning of each bit is unknown. */
|
||||
#define APPLE_SART_FLAGS_ALLOW 0xff
|
||||
/* SARTv0 registers */
|
||||
#define APPLE_SART0_CONFIG(idx) (0x00 + 4 * (idx))
|
||||
#define APPLE_SART0_CONFIG_FLAGS GENMASK(28, 24)
|
||||
#define APPLE_SART0_CONFIG_SIZE GENMASK(18, 0)
|
||||
#define APPLE_SART0_CONFIG_SIZE_SHIFT 12
|
||||
#define APPLE_SART0_CONFIG_SIZE_MAX GENMASK(18, 0)
|
||||
|
||||
#define APPLE_SART0_PADDR(idx) (0x40 + 4 * (idx))
|
||||
#define APPLE_SART0_PADDR_SHIFT 12
|
||||
|
||||
#define APPLE_SART0_FLAGS_ALLOW 0xf
|
||||
|
||||
/* SARTv2 registers */
|
||||
#define APPLE_SART2_CONFIG(idx) (0x00 + 4 * (idx))
|
||||
|
|
@ -38,6 +47,8 @@
|
|||
#define APPLE_SART2_PADDR(idx) (0x40 + 4 * (idx))
|
||||
#define APPLE_SART2_PADDR_SHIFT 12
|
||||
|
||||
#define APPLE_SART2_FLAGS_ALLOW 0xff
|
||||
|
||||
/* SARTv3 registers */
|
||||
#define APPLE_SART3_CONFIG(idx) (0x00 + 4 * (idx))
|
||||
|
||||
|
|
@ -48,11 +59,15 @@
|
|||
#define APPLE_SART3_SIZE_SHIFT 12
|
||||
#define APPLE_SART3_SIZE_MAX GENMASK(29, 0)
|
||||
|
||||
#define APPLE_SART3_FLAGS_ALLOW 0xff
|
||||
|
||||
struct apple_sart_ops {
|
||||
void (*get_entry)(struct apple_sart *sart, int index, u8 *flags,
|
||||
phys_addr_t *paddr, size_t *size);
|
||||
void (*set_entry)(struct apple_sart *sart, int index, u8 flags,
|
||||
phys_addr_t paddr_shifted, size_t size_shifted);
|
||||
/* This is probably a bitfield but the exact meaning of each bit is unknown. */
|
||||
unsigned int flags_allow;
|
||||
unsigned int size_shift;
|
||||
unsigned int paddr_shift;
|
||||
size_t size_max;
|
||||
|
|
@ -68,6 +83,39 @@ struct apple_sart {
|
|||
unsigned long used_entries;
|
||||
};
|
||||
|
||||
static void sart0_get_entry(struct apple_sart *sart, int index, u8 *flags,
|
||||
phys_addr_t *paddr, size_t *size)
|
||||
{
|
||||
u32 cfg = readl(sart->regs + APPLE_SART0_CONFIG(index));
|
||||
phys_addr_t paddr_ = readl(sart->regs + APPLE_SART0_PADDR(index));
|
||||
size_t size_ = FIELD_GET(APPLE_SART0_CONFIG_SIZE, cfg);
|
||||
|
||||
*flags = FIELD_GET(APPLE_SART0_CONFIG_FLAGS, cfg);
|
||||
*size = size_ << APPLE_SART0_CONFIG_SIZE_SHIFT;
|
||||
*paddr = paddr_ << APPLE_SART0_PADDR_SHIFT;
|
||||
}
|
||||
|
||||
static void sart0_set_entry(struct apple_sart *sart, int index, u8 flags,
|
||||
phys_addr_t paddr_shifted, size_t size_shifted)
|
||||
{
|
||||
u32 cfg;
|
||||
|
||||
cfg = FIELD_PREP(APPLE_SART0_CONFIG_FLAGS, flags);
|
||||
cfg |= FIELD_PREP(APPLE_SART0_CONFIG_SIZE, size_shifted);
|
||||
|
||||
writel(paddr_shifted, sart->regs + APPLE_SART0_PADDR(index));
|
||||
writel(cfg, sart->regs + APPLE_SART0_CONFIG(index));
|
||||
}
|
||||
|
||||
static struct apple_sart_ops sart_ops_v0 = {
|
||||
.get_entry = sart0_get_entry,
|
||||
.set_entry = sart0_set_entry,
|
||||
.flags_allow = APPLE_SART0_FLAGS_ALLOW,
|
||||
.size_shift = APPLE_SART0_CONFIG_SIZE_SHIFT,
|
||||
.paddr_shift = APPLE_SART0_PADDR_SHIFT,
|
||||
.size_max = APPLE_SART0_CONFIG_SIZE_MAX,
|
||||
};
|
||||
|
||||
static void sart2_get_entry(struct apple_sart *sart, int index, u8 *flags,
|
||||
phys_addr_t *paddr, size_t *size)
|
||||
{
|
||||
|
|
@ -95,6 +143,7 @@ static void sart2_set_entry(struct apple_sart *sart, int index, u8 flags,
|
|||
static struct apple_sart_ops sart_ops_v2 = {
|
||||
.get_entry = sart2_get_entry,
|
||||
.set_entry = sart2_set_entry,
|
||||
.flags_allow = APPLE_SART2_FLAGS_ALLOW,
|
||||
.size_shift = APPLE_SART2_CONFIG_SIZE_SHIFT,
|
||||
.paddr_shift = APPLE_SART2_PADDR_SHIFT,
|
||||
.size_max = APPLE_SART2_CONFIG_SIZE_MAX,
|
||||
|
|
@ -122,6 +171,7 @@ static void sart3_set_entry(struct apple_sart *sart, int index, u8 flags,
|
|||
static struct apple_sart_ops sart_ops_v3 = {
|
||||
.get_entry = sart3_get_entry,
|
||||
.set_entry = sart3_set_entry,
|
||||
.flags_allow = APPLE_SART3_FLAGS_ALLOW,
|
||||
.size_shift = APPLE_SART3_SIZE_SHIFT,
|
||||
.paddr_shift = APPLE_SART3_PADDR_SHIFT,
|
||||
.size_max = APPLE_SART3_SIZE_MAX,
|
||||
|
|
@ -233,7 +283,7 @@ int apple_sart_add_allowed_region(struct apple_sart *sart, phys_addr_t paddr,
|
|||
if (test_and_set_bit(i, &sart->used_entries))
|
||||
continue;
|
||||
|
||||
ret = sart_set_entry(sart, i, APPLE_SART_FLAGS_ALLOW, paddr,
|
||||
ret = sart_set_entry(sart, i, sart->ops->flags_allow, paddr,
|
||||
size);
|
||||
if (ret) {
|
||||
dev_dbg(sart->dev,
|
||||
|
|
@ -314,6 +364,10 @@ static const struct of_device_id apple_sart_of_match[] = {
|
|||
.compatible = "apple,t8103-sart",
|
||||
.data = &sart_ops_v2,
|
||||
},
|
||||
{
|
||||
.compatible = "apple,t8015-sart",
|
||||
.data = &sart_ops_v0,
|
||||
},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, apple_sart_of_match);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include <linux/mm.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_reserved_mem.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/regmap.h>
|
||||
|
|
@ -254,17 +255,8 @@ static int aspeed_lpc_ctrl_probe(struct platform_device *pdev)
|
|||
dev_set_drvdata(&pdev->dev, lpc_ctrl);
|
||||
|
||||
/* If memory-region is described in device tree then store */
|
||||
node = of_parse_phandle(dev->of_node, "memory-region", 0);
|
||||
if (!node) {
|
||||
dev_dbg(dev, "Didn't find reserved memory\n");
|
||||
} else {
|
||||
rc = of_address_to_resource(node, 0, &resm);
|
||||
of_node_put(node);
|
||||
if (rc) {
|
||||
dev_err(dev, "Couldn't address to resource for reserved memory\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
rc = of_reserved_mem_region_to_resource(dev->of_node, 0, &resm);
|
||||
if (!rc) {
|
||||
lpc_ctrl->mem_size = resource_size(&resm);
|
||||
lpc_ctrl->mem_base = resm.start;
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_reserved_mem.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
|
|
@ -334,7 +334,6 @@ static int aspeed_p2a_ctrl_probe(struct platform_device *pdev)
|
|||
struct aspeed_p2a_ctrl *misc_ctrl;
|
||||
struct device *dev;
|
||||
struct resource resm;
|
||||
struct device_node *node;
|
||||
int rc = 0;
|
||||
|
||||
dev = &pdev->dev;
|
||||
|
|
@ -346,15 +345,8 @@ static int aspeed_p2a_ctrl_probe(struct platform_device *pdev)
|
|||
mutex_init(&misc_ctrl->tracking);
|
||||
|
||||
/* optional. */
|
||||
node = of_parse_phandle(dev->of_node, "memory-region", 0);
|
||||
if (node) {
|
||||
rc = of_address_to_resource(node, 0, &resm);
|
||||
of_node_put(node);
|
||||
if (rc) {
|
||||
dev_err(dev, "Couldn't address to resource for reserved memory\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
rc = of_reserved_mem_region_to_resource(dev->of_node, 0, &resm);
|
||||
if (!rc) {
|
||||
misc_ctrl->mem_size = resource_size(&resm);
|
||||
misc_ctrl->mem_base = resm.start;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,10 @@ static struct {
|
|||
{ "AST2620", 0x05010203 },
|
||||
{ "AST2605", 0x05030103 },
|
||||
{ "AST2625", 0x05030403 },
|
||||
/* AST2700 */
|
||||
{ "AST2750", 0x06000003 },
|
||||
{ "AST2700", 0x06000103 },
|
||||
{ "AST2720", 0x06000203 },
|
||||
};
|
||||
|
||||
static const char *siliconid_to_name(u32 siliconid)
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ static int on_all_cpus(int (*fn)(void))
|
|||
{
|
||||
int cpu;
|
||||
|
||||
for_each_cpu(cpu, cpu_online_mask) {
|
||||
for_each_online_cpu(cpu) {
|
||||
struct bstrap bstrap = {
|
||||
.fn = fn,
|
||||
.started = ATOMIC_INIT(0)
|
||||
|
|
|
|||
|
|
@ -12,18 +12,19 @@
|
|||
#include <linux/spinlock.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/gpio/legacy-of-mm-gpiochip.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <soc/fsl/qe/qe.h>
|
||||
|
||||
#define PIN_MASK(gpio) (1UL << (QE_PIO_PINS - 1 - (gpio)))
|
||||
|
||||
struct qe_gpio_chip {
|
||||
struct of_mm_gpio_chip mm_gc;
|
||||
struct gpio_chip gc;
|
||||
void __iomem *regs;
|
||||
spinlock_t lock;
|
||||
|
||||
/* shadowed data register to clear/set bits safely */
|
||||
|
|
@ -33,11 +34,9 @@ struct qe_gpio_chip {
|
|||
struct qe_pio_regs saved_regs;
|
||||
};
|
||||
|
||||
static void qe_gpio_save_regs(struct of_mm_gpio_chip *mm_gc)
|
||||
static void qe_gpio_save_regs(struct qe_gpio_chip *qe_gc)
|
||||
{
|
||||
struct qe_gpio_chip *qe_gc =
|
||||
container_of(mm_gc, struct qe_gpio_chip, mm_gc);
|
||||
struct qe_pio_regs __iomem *regs = mm_gc->regs;
|
||||
struct qe_pio_regs __iomem *regs = qe_gc->regs;
|
||||
|
||||
qe_gc->cpdata = ioread32be(®s->cpdata);
|
||||
qe_gc->saved_regs.cpdata = qe_gc->cpdata;
|
||||
|
|
@ -50,20 +49,19 @@ static void qe_gpio_save_regs(struct of_mm_gpio_chip *mm_gc)
|
|||
|
||||
static int qe_gpio_get(struct gpio_chip *gc, unsigned int gpio)
|
||||
{
|
||||
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
|
||||
struct qe_pio_regs __iomem *regs = mm_gc->regs;
|
||||
u32 pin_mask = 1 << (QE_PIO_PINS - 1 - gpio);
|
||||
struct qe_gpio_chip *qe_gc = gpiochip_get_data(gc);
|
||||
struct qe_pio_regs __iomem *regs = qe_gc->regs;
|
||||
u32 pin_mask = PIN_MASK(gpio);
|
||||
|
||||
return !!(ioread32be(®s->cpdata) & pin_mask);
|
||||
}
|
||||
|
||||
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 qe_gpio_chip *qe_gc = gpiochip_get_data(gc);
|
||||
struct qe_pio_regs __iomem *regs = mm_gc->regs;
|
||||
struct qe_pio_regs __iomem *regs = qe_gc->regs;
|
||||
unsigned long flags;
|
||||
u32 pin_mask = 1 << (QE_PIO_PINS - 1 - gpio);
|
||||
u32 pin_mask = PIN_MASK(gpio);
|
||||
|
||||
spin_lock_irqsave(&qe_gc->lock, flags);
|
||||
|
||||
|
|
@ -82,9 +80,8 @@ static int qe_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
|
|||
static int qe_gpio_set_multiple(struct gpio_chip *gc,
|
||||
unsigned long *mask, unsigned long *bits)
|
||||
{
|
||||
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_pio_regs __iomem *regs = mm_gc->regs;
|
||||
struct qe_pio_regs __iomem *regs = qe_gc->regs;
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
||||
|
|
@ -95,9 +92,9 @@ static int qe_gpio_set_multiple(struct gpio_chip *gc,
|
|||
break;
|
||||
if (__test_and_clear_bit(i, mask)) {
|
||||
if (test_bit(i, bits))
|
||||
qe_gc->cpdata |= (1U << (QE_PIO_PINS - 1 - i));
|
||||
qe_gc->cpdata |= PIN_MASK(i);
|
||||
else
|
||||
qe_gc->cpdata &= ~(1U << (QE_PIO_PINS - 1 - i));
|
||||
qe_gc->cpdata &= ~PIN_MASK(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -110,13 +107,12 @@ static int qe_gpio_set_multiple(struct gpio_chip *gc,
|
|||
|
||||
static int qe_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
|
||||
{
|
||||
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
|
||||
struct qe_gpio_chip *qe_gc = gpiochip_get_data(gc);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&qe_gc->lock, flags);
|
||||
|
||||
__par_io_config_pin(mm_gc->regs, gpio, QE_PIO_DIR_IN, 0, 0, 0);
|
||||
__par_io_config_pin(qe_gc->regs, gpio, QE_PIO_DIR_IN, 0, 0, 0);
|
||||
|
||||
spin_unlock_irqrestore(&qe_gc->lock, flags);
|
||||
|
||||
|
|
@ -125,7 +121,6 @@ static int qe_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
|
|||
|
||||
static int qe_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
|
||||
{
|
||||
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
|
||||
struct qe_gpio_chip *qe_gc = gpiochip_get_data(gc);
|
||||
unsigned long flags;
|
||||
|
||||
|
|
@ -133,7 +128,7 @@ static int qe_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
|
|||
|
||||
spin_lock_irqsave(&qe_gc->lock, flags);
|
||||
|
||||
__par_io_config_pin(mm_gc->regs, gpio, QE_PIO_DIR_OUT, 0, 0, 0);
|
||||
__par_io_config_pin(qe_gc->regs, gpio, QE_PIO_DIR_OUT, 0, 0, 0);
|
||||
|
||||
spin_unlock_irqrestore(&qe_gc->lock, flags);
|
||||
|
||||
|
|
@ -239,7 +234,7 @@ EXPORT_SYMBOL(qe_pin_free);
|
|||
void qe_pin_set_dedicated(struct qe_pin *qe_pin)
|
||||
{
|
||||
struct qe_gpio_chip *qe_gc = qe_pin->controller;
|
||||
struct qe_pio_regs __iomem *regs = qe_gc->mm_gc.regs;
|
||||
struct qe_pio_regs __iomem *regs = qe_gc->regs;
|
||||
struct qe_pio_regs *sregs = &qe_gc->saved_regs;
|
||||
int pin = qe_pin->num;
|
||||
u32 mask1 = 1 << (QE_PIO_PINS - (pin + 1));
|
||||
|
|
@ -268,7 +263,6 @@ void qe_pin_set_dedicated(struct qe_pin *qe_pin)
|
|||
|
||||
iowrite32be(qe_gc->cpdata, ®s->cpdata);
|
||||
qe_clrsetbits_be32(®s->cpodr, mask1, sregs->cpodr & mask1);
|
||||
|
||||
spin_unlock_irqrestore(&qe_gc->lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL(qe_pin_set_dedicated);
|
||||
|
|
@ -283,7 +277,7 @@ EXPORT_SYMBOL(qe_pin_set_dedicated);
|
|||
void qe_pin_set_gpio(struct qe_pin *qe_pin)
|
||||
{
|
||||
struct qe_gpio_chip *qe_gc = qe_pin->controller;
|
||||
struct qe_pio_regs __iomem *regs = qe_gc->mm_gc.regs;
|
||||
struct qe_pio_regs __iomem *regs = qe_gc->regs;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&qe_gc->lock, flags);
|
||||
|
|
@ -295,45 +289,62 @@ void qe_pin_set_gpio(struct qe_pin *qe_pin)
|
|||
}
|
||||
EXPORT_SYMBOL(qe_pin_set_gpio);
|
||||
|
||||
static int __init qe_add_gpiochips(void)
|
||||
static int qe_gpio_probe(struct platform_device *ofdev)
|
||||
{
|
||||
struct device_node *np;
|
||||
struct device *dev = &ofdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct qe_gpio_chip *qe_gc;
|
||||
struct gpio_chip *gc;
|
||||
|
||||
for_each_compatible_node(np, NULL, "fsl,mpc8323-qe-pario-bank") {
|
||||
int ret;
|
||||
struct qe_gpio_chip *qe_gc;
|
||||
struct of_mm_gpio_chip *mm_gc;
|
||||
struct gpio_chip *gc;
|
||||
qe_gc = devm_kzalloc(dev, sizeof(*qe_gc), GFP_KERNEL);
|
||||
if (!qe_gc)
|
||||
return -ENOMEM;
|
||||
|
||||
qe_gc = kzalloc(sizeof(*qe_gc), GFP_KERNEL);
|
||||
if (!qe_gc) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
spin_lock_init(&qe_gc->lock);
|
||||
|
||||
spin_lock_init(&qe_gc->lock);
|
||||
gc = &qe_gc->gc;
|
||||
|
||||
mm_gc = &qe_gc->mm_gc;
|
||||
gc = &mm_gc->gc;
|
||||
gc->base = -1;
|
||||
gc->ngpio = QE_PIO_PINS;
|
||||
gc->direction_input = qe_gpio_dir_in;
|
||||
gc->direction_output = qe_gpio_dir_out;
|
||||
gc->get = qe_gpio_get;
|
||||
gc->set = qe_gpio_set;
|
||||
gc->set_multiple = qe_gpio_set_multiple;
|
||||
gc->parent = dev;
|
||||
gc->owner = THIS_MODULE;
|
||||
|
||||
mm_gc->save_regs = qe_gpio_save_regs;
|
||||
gc->ngpio = QE_PIO_PINS;
|
||||
gc->direction_input = qe_gpio_dir_in;
|
||||
gc->direction_output = qe_gpio_dir_out;
|
||||
gc->get = qe_gpio_get;
|
||||
gc->set = qe_gpio_set;
|
||||
gc->set_multiple = qe_gpio_set_multiple;
|
||||
gc->label = devm_kasprintf(dev, GFP_KERNEL, "%pOF", np);
|
||||
if (!gc->label)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = of_mm_gpiochip_add_data(np, mm_gc, qe_gc);
|
||||
if (ret)
|
||||
goto err;
|
||||
continue;
|
||||
err:
|
||||
pr_err("%pOF: registration failed with status %d\n",
|
||||
np, ret);
|
||||
kfree(qe_gc);
|
||||
/* try others anyway */
|
||||
}
|
||||
return 0;
|
||||
qe_gc->regs = devm_of_iomap(dev, np, 0, NULL);
|
||||
if (IS_ERR(qe_gc->regs))
|
||||
return PTR_ERR(qe_gc->regs);
|
||||
|
||||
qe_gpio_save_regs(qe_gc);
|
||||
|
||||
return devm_gpiochip_add_data(dev, gc, qe_gc);
|
||||
}
|
||||
arch_initcall(qe_add_gpiochips);
|
||||
|
||||
static const struct of_device_id qe_gpio_match[] = {
|
||||
{
|
||||
.compatible = "fsl,mpc8323-qe-pario-bank",
|
||||
},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, qe_gpio_match);
|
||||
|
||||
static struct platform_driver qe_gpio_driver = {
|
||||
.probe = qe_gpio_probe,
|
||||
.driver = {
|
||||
.name = "qe-gpio",
|
||||
.of_match_table = qe_gpio_match,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init qe_gpio_init(void)
|
||||
{
|
||||
return platform_driver_register(&qe_gpio_driver);
|
||||
}
|
||||
arch_initcall(qe_gpio_init);
|
||||
|
|
|
|||
|
|
@ -1464,7 +1464,7 @@ static ssize_t dec_lane_of_type_store(struct kobject *kobj, struct kobj_attribut
|
|||
goto out;
|
||||
if (!all_in_idle) {
|
||||
ret = -EBUSY;
|
||||
dev_err(hdev->dev, "please don't decrese lanes on high load with %s, ret = %d.\n",
|
||||
dev_err(hdev->dev, "please don't decrease lanes on high load with %s, ret = %d.\n",
|
||||
hccs_port_type_to_name(hdev, port_type), ret);
|
||||
goto out;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2165,10 +2165,18 @@ static struct device *svs_add_device_link(struct svs_platform *svsp,
|
|||
return dev;
|
||||
}
|
||||
|
||||
static void svs_put_device(void *_dev)
|
||||
{
|
||||
struct device *dev = _dev;
|
||||
|
||||
put_device(dev);
|
||||
}
|
||||
|
||||
static int svs_mt8192_platform_probe(struct svs_platform *svsp)
|
||||
{
|
||||
struct device *dev;
|
||||
u32 idx;
|
||||
int ret;
|
||||
|
||||
svsp->rst = devm_reset_control_get_optional(svsp->dev, "svs_rst");
|
||||
if (IS_ERR(svsp->rst))
|
||||
|
|
@ -2179,6 +2187,7 @@ static int svs_mt8192_platform_probe(struct svs_platform *svsp)
|
|||
if (IS_ERR(dev))
|
||||
return dev_err_probe(svsp->dev, PTR_ERR(dev),
|
||||
"failed to get lvts device\n");
|
||||
put_device(dev);
|
||||
|
||||
for (idx = 0; idx < svsp->bank_max; idx++) {
|
||||
struct svs_bank *svsb = &svsp->banks[idx];
|
||||
|
|
@ -2188,6 +2197,7 @@ static int svs_mt8192_platform_probe(struct svs_platform *svsp)
|
|||
case SVSB_SWID_CPU_LITTLE:
|
||||
case SVSB_SWID_CPU_BIG:
|
||||
svsb->opp_dev = get_cpu_device(bdata->cpu_id);
|
||||
get_device(svsb->opp_dev);
|
||||
break;
|
||||
case SVSB_SWID_CCI:
|
||||
svsb->opp_dev = svs_add_device_link(svsp, "cci");
|
||||
|
|
@ -2207,6 +2217,11 @@ static int svs_mt8192_platform_probe(struct svs_platform *svsp)
|
|||
return dev_err_probe(svsp->dev, PTR_ERR(svsb->opp_dev),
|
||||
"failed to get OPP device for bank %d\n",
|
||||
idx);
|
||||
|
||||
ret = devm_add_action_or_reset(svsp->dev, svs_put_device,
|
||||
svsb->opp_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -2216,11 +2231,13 @@ static int svs_mt8183_platform_probe(struct svs_platform *svsp)
|
|||
{
|
||||
struct device *dev;
|
||||
u32 idx;
|
||||
int ret;
|
||||
|
||||
dev = svs_add_device_link(svsp, "thermal-sensor");
|
||||
if (IS_ERR(dev))
|
||||
return dev_err_probe(svsp->dev, PTR_ERR(dev),
|
||||
"failed to get thermal device\n");
|
||||
put_device(dev);
|
||||
|
||||
for (idx = 0; idx < svsp->bank_max; idx++) {
|
||||
struct svs_bank *svsb = &svsp->banks[idx];
|
||||
|
|
@ -2230,6 +2247,7 @@ static int svs_mt8183_platform_probe(struct svs_platform *svsp)
|
|||
case SVSB_SWID_CPU_LITTLE:
|
||||
case SVSB_SWID_CPU_BIG:
|
||||
svsb->opp_dev = get_cpu_device(bdata->cpu_id);
|
||||
get_device(svsb->opp_dev);
|
||||
break;
|
||||
case SVSB_SWID_CCI:
|
||||
svsb->opp_dev = svs_add_device_link(svsp, "cci");
|
||||
|
|
@ -2246,6 +2264,11 @@ static int svs_mt8183_platform_probe(struct svs_platform *svsp)
|
|||
return dev_err_probe(svsp->dev, PTR_ERR(svsb->opp_dev),
|
||||
"failed to get OPP device for bank %d\n",
|
||||
idx);
|
||||
|
||||
ret = devm_add_action_or_reset(svsp->dev, svs_put_device,
|
||||
svsb->opp_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -656,6 +656,9 @@ static irqreturn_t bwmon_intr_thread(int irq, void *dev_id)
|
|||
if (IS_ERR(target_opp) && PTR_ERR(target_opp) == -ERANGE)
|
||||
target_opp = dev_pm_opp_find_bw_floor(bwmon->dev, &bw_kbps, 0);
|
||||
|
||||
if (IS_ERR(target_opp))
|
||||
return IRQ_HANDLED;
|
||||
|
||||
bwmon->target_kbps = bw_kbps;
|
||||
|
||||
bw_kbps--;
|
||||
|
|
|
|||
|
|
@ -4409,7 +4409,6 @@ static struct regmap *qcom_llcc_init_mmio(struct platform_device *pdev, u8 index
|
|||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
base = devm_platform_ioremap_resource(pdev, index);
|
||||
|
|
|
|||
|
|
@ -304,7 +304,7 @@ out:
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(qcom_mdt_pas_init);
|
||||
|
||||
static bool qcom_mdt_bins_are_split(const struct firmware *fw, const char *fw_name)
|
||||
static bool qcom_mdt_bins_are_split(const struct firmware *fw)
|
||||
{
|
||||
const struct elf32_phdr *phdrs;
|
||||
const struct elf32_hdr *ehdr;
|
||||
|
|
@ -333,9 +333,9 @@ static bool qcom_mdt_bins_are_split(const struct firmware *fw, const char *fw_na
|
|||
}
|
||||
|
||||
static int __qcom_mdt_load(struct device *dev, const struct firmware *fw,
|
||||
const char *fw_name, int pas_id, void *mem_region,
|
||||
const char *fw_name, void *mem_region,
|
||||
phys_addr_t mem_phys, size_t mem_size,
|
||||
phys_addr_t *reloc_base, bool pas_init)
|
||||
phys_addr_t *reloc_base)
|
||||
{
|
||||
const struct elf32_phdr *phdrs;
|
||||
const struct elf32_phdr *phdr;
|
||||
|
|
@ -355,7 +355,7 @@ static int __qcom_mdt_load(struct device *dev, const struct firmware *fw,
|
|||
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);
|
||||
ehdr = (struct elf32_hdr *)fw->data;
|
||||
phdrs = (struct elf32_phdr *)(fw->data + ehdr->e_phoff);
|
||||
|
||||
|
|
@ -460,8 +460,8 @@ int qcom_mdt_load(struct device *dev, const struct firmware *fw,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
return __qcom_mdt_load(dev, fw, firmware, pas_id, mem_region, mem_phys,
|
||||
mem_size, reloc_base, true);
|
||||
return __qcom_mdt_load(dev, fw, firmware, mem_region, mem_phys,
|
||||
mem_size, reloc_base);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qcom_mdt_load);
|
||||
|
||||
|
|
@ -470,7 +470,6 @@ EXPORT_SYMBOL_GPL(qcom_mdt_load);
|
|||
* @dev: device handle to associate resources with
|
||||
* @fw: firmware object for the mdt file
|
||||
* @firmware: name of the firmware, for construction of segment file names
|
||||
* @pas_id: PAS identifier
|
||||
* @mem_region: allocated memory region to load firmware into
|
||||
* @mem_phys: physical address of allocated memory region
|
||||
* @mem_size: size of the allocated memory region
|
||||
|
|
@ -479,12 +478,11 @@ EXPORT_SYMBOL_GPL(qcom_mdt_load);
|
|||
* Returns 0 on success, negative errno otherwise.
|
||||
*/
|
||||
int qcom_mdt_load_no_init(struct device *dev, const struct firmware *fw,
|
||||
const char *firmware, int pas_id,
|
||||
void *mem_region, phys_addr_t mem_phys,
|
||||
const char *firmware, void *mem_region, phys_addr_t mem_phys,
|
||||
size_t mem_size, phys_addr_t *reloc_base)
|
||||
{
|
||||
return __qcom_mdt_load(dev, fw, firmware, pas_id, mem_region, mem_phys,
|
||||
mem_size, reloc_base, false);
|
||||
return __qcom_mdt_load(dev, fw, firmware, mem_region, mem_phys,
|
||||
mem_size, reloc_base);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qcom_mdt_load_no_init);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,16 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
|
||||
/*
|
||||
* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
/* Disable MMIO tracing to prevent excessive logging of unwanted MMIO traces */
|
||||
#define __DISABLE_TRACE_MMIO__
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/io.h>
|
||||
|
|
@ -110,22 +115,94 @@ struct geni_se_desc {
|
|||
static const char * const icc_path_names[] = {"qup-core", "qup-config",
|
||||
"qup-memory"};
|
||||
|
||||
#define QUP_HW_VER_REG 0x4
|
||||
static const char * const protocol_name[] = { "None", "SPI", "UART", "I2C", "I3C", "SPI SLAVE" };
|
||||
|
||||
/**
|
||||
* struct se_fw_hdr - Serial Engine firmware configuration header
|
||||
*
|
||||
* This structure defines the SE firmware header, which together with the
|
||||
* firmware payload is stored in individual ELF segments.
|
||||
*
|
||||
* @magic: Set to 'SEFW'.
|
||||
* @version: Structure version number.
|
||||
* @core_version: QUPV3 hardware version.
|
||||
* @serial_protocol: Encoded in GENI_FW_REVISION.
|
||||
* @fw_version: Firmware version, from GENI_FW_REVISION.
|
||||
* @cfg_version: Configuration version, from GENI_INIT_CFG_REVISION.
|
||||
* @fw_size_in_items: Number of 32-bit words in GENI_FW_RAM.
|
||||
* @fw_offset: Byte offset to GENI_FW_RAM array.
|
||||
* @cfg_size_in_items: Number of GENI_FW_CFG index/value pairs.
|
||||
* @cfg_idx_offset: Byte offset to GENI_FW_CFG index array.
|
||||
* @cfg_val_offset: Byte offset to GENI_FW_CFG values array.
|
||||
*/
|
||||
struct se_fw_hdr {
|
||||
__le32 magic;
|
||||
__le32 version;
|
||||
__le32 core_version;
|
||||
__le16 serial_protocol;
|
||||
__le16 fw_version;
|
||||
__le16 cfg_version;
|
||||
__le16 fw_size_in_items;
|
||||
__le16 fw_offset;
|
||||
__le16 cfg_size_in_items;
|
||||
__le16 cfg_idx_offset;
|
||||
__le16 cfg_val_offset;
|
||||
};
|
||||
|
||||
/*Magic numbers*/
|
||||
#define SE_MAGIC_NUM 0x57464553
|
||||
|
||||
#define MAX_GENI_CFG_RAMn_CNT 455
|
||||
|
||||
#define MI_PBT_NON_PAGED_SEGMENT 0x0
|
||||
#define MI_PBT_HASH_SEGMENT 0x2
|
||||
#define MI_PBT_NOTUSED_SEGMENT 0x3
|
||||
#define MI_PBT_SHARED_SEGMENT 0x4
|
||||
|
||||
#define MI_PBT_FLAG_PAGE_MODE BIT(20)
|
||||
#define MI_PBT_FLAG_SEGMENT_TYPE GENMASK(26, 24)
|
||||
#define MI_PBT_FLAG_ACCESS_TYPE GENMASK(23, 21)
|
||||
|
||||
#define MI_PBT_PAGE_MODE_VALUE(x) FIELD_GET(MI_PBT_FLAG_PAGE_MODE, x)
|
||||
|
||||
#define MI_PBT_SEGMENT_TYPE_VALUE(x) FIELD_GET(MI_PBT_FLAG_SEGMENT_TYPE, x)
|
||||
|
||||
#define MI_PBT_ACCESS_TYPE_VALUE(x) FIELD_GET(MI_PBT_FLAG_ACCESS_TYPE, x)
|
||||
|
||||
#define M_COMMON_GENI_M_IRQ_EN (GENMASK(6, 1) | \
|
||||
M_IO_DATA_DEASSERT_EN | \
|
||||
M_IO_DATA_ASSERT_EN | M_RX_FIFO_RD_ERR_EN | \
|
||||
M_RX_FIFO_WR_ERR_EN | M_TX_FIFO_RD_ERR_EN | \
|
||||
M_TX_FIFO_WR_ERR_EN)
|
||||
|
||||
/* Common QUPV3 registers */
|
||||
#define QUPV3_HW_VER_REG 0x4
|
||||
#define QUPV3_SE_AHB_M_CFG 0x118
|
||||
#define QUPV3_COMMON_CFG 0x120
|
||||
#define QUPV3_COMMON_CGC_CTRL 0x21c
|
||||
|
||||
/* QUPV3_COMMON_CFG fields */
|
||||
#define FAST_SWITCH_TO_HIGH_DISABLE BIT(0)
|
||||
|
||||
/* QUPV3_SE_AHB_M_CFG fields */
|
||||
#define AHB_M_CLK_CGC_ON BIT(0)
|
||||
|
||||
/* QUPV3_COMMON_CGC_CTRL fields */
|
||||
#define COMMON_CSR_SLV_CLK_CGC_ON BIT(0)
|
||||
|
||||
/* Common SE registers */
|
||||
#define GENI_INIT_CFG_REVISION 0x0
|
||||
#define GENI_S_INIT_CFG_REVISION 0x4
|
||||
#define GENI_OUTPUT_CTRL 0x24
|
||||
#define GENI_CGC_CTRL 0x28
|
||||
#define GENI_CLK_CTRL_RO 0x60
|
||||
#define GENI_FW_S_REVISION_RO 0x6c
|
||||
#define SE_GENI_INIT_CFG_REVISION 0x0
|
||||
#define SE_GENI_S_INIT_CFG_REVISION 0x4
|
||||
#define SE_GENI_CGC_CTRL 0x28
|
||||
#define SE_GENI_CLK_CTRL_RO 0x60
|
||||
#define SE_GENI_FW_S_REVISION_RO 0x6c
|
||||
#define SE_GENI_CFG_REG0 0x100
|
||||
#define SE_GENI_BYTE_GRAN 0x254
|
||||
#define SE_GENI_TX_PACKING_CFG0 0x260
|
||||
#define SE_GENI_TX_PACKING_CFG1 0x264
|
||||
#define SE_GENI_RX_PACKING_CFG0 0x284
|
||||
#define SE_GENI_RX_PACKING_CFG1 0x288
|
||||
#define SE_GENI_M_GP_LENGTH 0x910
|
||||
#define SE_GENI_S_GP_LENGTH 0x914
|
||||
#define SE_GENI_S_IRQ_ENABLE 0x644
|
||||
#define SE_DMA_TX_PTR_L 0xc30
|
||||
#define SE_DMA_TX_PTR_H 0xc34
|
||||
#define SE_DMA_TX_ATTR 0xc38
|
||||
|
|
@ -142,12 +219,20 @@ static const char * const icc_path_names[] = {"qup-core", "qup-config",
|
|||
#define SE_DMA_RX_IRQ_EN 0xd48
|
||||
#define SE_DMA_RX_IRQ_EN_SET 0xd4c
|
||||
#define SE_DMA_RX_IRQ_EN_CLR 0xd50
|
||||
#define SE_DMA_RX_LEN_IN 0xd54
|
||||
#define SE_DMA_RX_MAX_BURST 0xd5c
|
||||
#define SE_DMA_RX_FLUSH 0xd60
|
||||
#define SE_GSI_EVENT_EN 0xe18
|
||||
#define SE_IRQ_EN 0xe1c
|
||||
#define SE_DMA_GENERAL_CFG 0xe30
|
||||
#define SE_GENI_FW_REVISION 0x1000
|
||||
#define SE_GENI_S_FW_REVISION 0x1004
|
||||
#define SE_GENI_CFG_RAMN 0x1010
|
||||
#define SE_GENI_CLK_CTRL 0x2000
|
||||
#define SE_DMA_IF_EN 0x2004
|
||||
#define SE_FIFO_IF_DISABLE 0x2008
|
||||
|
||||
/* GENI_FW_REVISION_RO fields */
|
||||
#define FW_REV_VERSION_MSK GENMASK(7, 0)
|
||||
|
||||
/* GENI_OUTPUT_CTRL fields */
|
||||
#define DEFAULT_IO_OUTPUT_CTRL_MSK GENMASK(6, 0)
|
||||
|
|
@ -179,13 +264,22 @@ static const char * const icc_path_names[] = {"qup-core", "qup-config",
|
|||
/* SE_DMA_GENERAL_CFG */
|
||||
#define DMA_RX_CLK_CGC_ON BIT(0)
|
||||
#define DMA_TX_CLK_CGC_ON BIT(1)
|
||||
#define DMA_AHB_SLV_CFG_ON BIT(2)
|
||||
#define DMA_AHB_SLV_CLK_CGC_ON BIT(2)
|
||||
#define AHB_SEC_SLV_CLK_CGC_ON BIT(3)
|
||||
#define DUMMY_RX_NON_BUFFERABLE BIT(4)
|
||||
#define RX_DMA_ZERO_PADDING_EN BIT(5)
|
||||
#define RX_DMA_IRQ_DELAY_MSK GENMASK(8, 6)
|
||||
#define RX_DMA_IRQ_DELAY_SHFT 6
|
||||
|
||||
/* GENI_CLK_CTRL fields */
|
||||
#define SER_CLK_SEL BIT(0)
|
||||
|
||||
/* GENI_DMA_IF_EN fields */
|
||||
#define DMA_IF_EN BIT(0)
|
||||
|
||||
#define geni_setbits32(_addr, _v) writel(readl(_addr) | (_v), _addr)
|
||||
#define geni_clrbits32(_addr, _v) writel(readl(_addr) & ~(_v), _addr)
|
||||
|
||||
/**
|
||||
* geni_se_get_qup_hw_version() - Read the QUP wrapper Hardware version
|
||||
* @se: Pointer to the corresponding serial engine.
|
||||
|
|
@ -196,7 +290,7 @@ u32 geni_se_get_qup_hw_version(struct geni_se *se)
|
|||
{
|
||||
struct geni_wrapper *wrapper = se->wrapper;
|
||||
|
||||
return readl_relaxed(wrapper->base + QUP_HW_VER_REG);
|
||||
return readl_relaxed(wrapper->base + QUPV3_HW_VER_REG);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(geni_se_get_qup_hw_version);
|
||||
|
||||
|
|
@ -220,12 +314,12 @@ static void geni_se_io_init(void __iomem *base)
|
|||
{
|
||||
u32 val;
|
||||
|
||||
val = readl_relaxed(base + GENI_CGC_CTRL);
|
||||
val = readl_relaxed(base + SE_GENI_CGC_CTRL);
|
||||
val |= DEFAULT_CGC_EN;
|
||||
writel_relaxed(val, base + GENI_CGC_CTRL);
|
||||
writel_relaxed(val, base + SE_GENI_CGC_CTRL);
|
||||
|
||||
val = readl_relaxed(base + SE_DMA_GENERAL_CFG);
|
||||
val |= AHB_SEC_SLV_CLK_CGC_ON | DMA_AHB_SLV_CFG_ON;
|
||||
val |= AHB_SEC_SLV_CLK_CGC_ON | DMA_AHB_SLV_CLK_CGC_ON;
|
||||
val |= DMA_TX_CLK_CGC_ON | DMA_RX_CLK_CGC_ON;
|
||||
writel_relaxed(val, base + SE_DMA_GENERAL_CFG);
|
||||
|
||||
|
|
@ -658,9 +752,12 @@ int geni_se_clk_freq_match(struct geni_se *se, unsigned long req_freq,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(geni_se_clk_freq_match);
|
||||
|
||||
#define GENI_SE_DMA_DONE_EN BIT(0)
|
||||
#define GENI_SE_DMA_EOT_EN BIT(1)
|
||||
#define GENI_SE_DMA_AHB_ERR_EN BIT(2)
|
||||
#define GENI_SE_DMA_DONE_EN BIT(0)
|
||||
#define GENI_SE_DMA_EOT_EN BIT(1)
|
||||
#define GENI_SE_DMA_AHB_ERR_EN BIT(2)
|
||||
#define GENI_SE_DMA_RESET_DONE_EN BIT(3)
|
||||
#define GENI_SE_DMA_FLUSH_DONE BIT(4)
|
||||
|
||||
#define GENI_SE_DMA_EOT_BUF BIT(0)
|
||||
|
||||
/**
|
||||
|
|
@ -891,6 +988,377 @@ int geni_icc_disable(struct geni_se *se)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(geni_icc_disable);
|
||||
|
||||
/**
|
||||
* geni_find_protocol_fw() - Locate and validate SE firmware for a protocol.
|
||||
* @dev: Pointer to the device structure.
|
||||
* @fw: Pointer to the firmware image.
|
||||
* @protocol: Expected serial engine protocol type.
|
||||
*
|
||||
* Identifies the appropriate firmware image or configuration required for a
|
||||
* specific communication protocol instance running on a Qualcomm GENI
|
||||
* controller.
|
||||
*
|
||||
* Return: pointer to a valid 'struct se_fw_hdr' if found, or NULL otherwise.
|
||||
*/
|
||||
static struct se_fw_hdr *geni_find_protocol_fw(struct device *dev, const struct firmware *fw,
|
||||
enum geni_se_protocol_type protocol)
|
||||
{
|
||||
const struct elf32_hdr *ehdr;
|
||||
const struct elf32_phdr *phdrs;
|
||||
const struct elf32_phdr *phdr;
|
||||
struct se_fw_hdr *sefw;
|
||||
u32 fw_end, cfg_idx_end, cfg_val_end;
|
||||
u16 fw_size;
|
||||
int i;
|
||||
|
||||
if (!fw || fw->size < sizeof(struct elf32_hdr))
|
||||
return NULL;
|
||||
|
||||
ehdr = (const struct elf32_hdr *)fw->data;
|
||||
phdrs = (const struct elf32_phdr *)(fw->data + ehdr->e_phoff);
|
||||
|
||||
/*
|
||||
* The firmware is expected to have at least two program headers (segments).
|
||||
* One for metadata and the other for the actual protocol-specific firmware.
|
||||
*/
|
||||
if (ehdr->e_phnum < 2) {
|
||||
dev_err(dev, "Invalid firmware: less than 2 program headers\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < ehdr->e_phnum; i++) {
|
||||
phdr = &phdrs[i];
|
||||
|
||||
if (fw->size < phdr->p_offset + phdr->p_filesz) {
|
||||
dev_err(dev, "Firmware size (%zu) < expected offset (%u) + size (%u)\n",
|
||||
fw->size, phdr->p_offset, phdr->p_filesz);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (phdr->p_type != PT_LOAD || !phdr->p_memsz)
|
||||
continue;
|
||||
|
||||
if (MI_PBT_PAGE_MODE_VALUE(phdr->p_flags) != MI_PBT_NON_PAGED_SEGMENT ||
|
||||
MI_PBT_SEGMENT_TYPE_VALUE(phdr->p_flags) == MI_PBT_HASH_SEGMENT ||
|
||||
MI_PBT_ACCESS_TYPE_VALUE(phdr->p_flags) == MI_PBT_NOTUSED_SEGMENT ||
|
||||
MI_PBT_ACCESS_TYPE_VALUE(phdr->p_flags) == MI_PBT_SHARED_SEGMENT)
|
||||
continue;
|
||||
|
||||
if (phdr->p_filesz < sizeof(struct se_fw_hdr))
|
||||
continue;
|
||||
|
||||
sefw = (struct se_fw_hdr *)(fw->data + phdr->p_offset);
|
||||
fw_size = le16_to_cpu(sefw->fw_size_in_items);
|
||||
fw_end = le16_to_cpu(sefw->fw_offset) + fw_size * sizeof(u32);
|
||||
cfg_idx_end = le16_to_cpu(sefw->cfg_idx_offset) +
|
||||
le16_to_cpu(sefw->cfg_size_in_items) * sizeof(u8);
|
||||
cfg_val_end = le16_to_cpu(sefw->cfg_val_offset) +
|
||||
le16_to_cpu(sefw->cfg_size_in_items) * sizeof(u32);
|
||||
|
||||
if (le32_to_cpu(sefw->magic) != SE_MAGIC_NUM || le32_to_cpu(sefw->version) != 1)
|
||||
continue;
|
||||
|
||||
if (le32_to_cpu(sefw->serial_protocol) != protocol)
|
||||
continue;
|
||||
|
||||
if (fw_size % 2 != 0) {
|
||||
fw_size++;
|
||||
sefw->fw_size_in_items = cpu_to_le16(fw_size);
|
||||
}
|
||||
|
||||
if (fw_size >= MAX_GENI_CFG_RAMn_CNT) {
|
||||
dev_err(dev,
|
||||
"Firmware size (%u) exceeds max allowed RAMn count (%u)\n",
|
||||
fw_size, MAX_GENI_CFG_RAMn_CNT);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fw_end > phdr->p_filesz || cfg_idx_end > phdr->p_filesz ||
|
||||
cfg_val_end > phdr->p_filesz) {
|
||||
dev_err(dev, "Truncated or corrupt SE FW segment found at index %d\n", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
return sefw;
|
||||
}
|
||||
|
||||
dev_err(dev, "Failed to get %s protocol firmware\n", protocol_name[protocol]);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* geni_configure_xfer_mode() - Set the transfer mode.
|
||||
* @se: Pointer to the concerned serial engine.
|
||||
* @mode: SE data transfer mode.
|
||||
*
|
||||
* Set the transfer mode to either FIFO or DMA according to the mode specified
|
||||
* by the protocol driver.
|
||||
*
|
||||
* Return: 0 if successful, otherwise return an error value.
|
||||
*/
|
||||
static int geni_configure_xfer_mode(struct geni_se *se, enum geni_se_xfer_mode mode)
|
||||
{
|
||||
/* Configure SE FIFO, DMA or GSI mode. */
|
||||
switch (mode) {
|
||||
case GENI_GPI_DMA:
|
||||
geni_setbits32(se->base + SE_GENI_DMA_MODE_EN, GENI_DMA_MODE_EN);
|
||||
writel(0x0, se->base + SE_IRQ_EN);
|
||||
writel(DMA_RX_EVENT_EN | DMA_TX_EVENT_EN | GENI_M_EVENT_EN | GENI_S_EVENT_EN,
|
||||
se->base + SE_GSI_EVENT_EN);
|
||||
break;
|
||||
|
||||
case GENI_SE_FIFO:
|
||||
geni_clrbits32(se->base + SE_GENI_DMA_MODE_EN, GENI_DMA_MODE_EN);
|
||||
writel(DMA_RX_IRQ_EN | DMA_TX_IRQ_EN | GENI_M_IRQ_EN | GENI_S_IRQ_EN,
|
||||
se->base + SE_IRQ_EN);
|
||||
writel(0x0, se->base + SE_GSI_EVENT_EN);
|
||||
break;
|
||||
|
||||
case GENI_SE_DMA:
|
||||
geni_setbits32(se->base + SE_GENI_DMA_MODE_EN, GENI_DMA_MODE_EN);
|
||||
writel(DMA_RX_IRQ_EN | DMA_TX_IRQ_EN | GENI_M_IRQ_EN | GENI_S_IRQ_EN,
|
||||
se->base + SE_IRQ_EN);
|
||||
writel(0x0, se->base + SE_GSI_EVENT_EN);
|
||||
break;
|
||||
|
||||
default:
|
||||
dev_err(se->dev, "Invalid geni-se transfer mode: %d\n", mode);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* geni_enable_interrupts() - Enable interrupts.
|
||||
* @se: Pointer to the concerned serial engine.
|
||||
*
|
||||
* Enable the required interrupts during the firmware load process.
|
||||
*/
|
||||
static void geni_enable_interrupts(struct geni_se *se)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
/* Enable required interrupts. */
|
||||
writel(M_COMMON_GENI_M_IRQ_EN, se->base + SE_GENI_M_IRQ_EN);
|
||||
|
||||
val = S_CMD_OVERRUN_EN | S_ILLEGAL_CMD_EN | S_CMD_CANCEL_EN | S_CMD_ABORT_EN |
|
||||
S_GP_IRQ_0_EN | S_GP_IRQ_1_EN | S_GP_IRQ_2_EN | S_GP_IRQ_3_EN |
|
||||
S_RX_FIFO_WR_ERR_EN | S_RX_FIFO_RD_ERR_EN;
|
||||
writel(val, se->base + SE_GENI_S_IRQ_ENABLE);
|
||||
|
||||
/* DMA mode configuration. */
|
||||
val = GENI_SE_DMA_RESET_DONE_EN | GENI_SE_DMA_AHB_ERR_EN | GENI_SE_DMA_DONE_EN;
|
||||
writel(val, se->base + SE_DMA_TX_IRQ_EN_SET);
|
||||
val = GENI_SE_DMA_FLUSH_DONE | GENI_SE_DMA_RESET_DONE_EN | GENI_SE_DMA_AHB_ERR_EN |
|
||||
GENI_SE_DMA_DONE_EN;
|
||||
writel(val, se->base + SE_DMA_RX_IRQ_EN_SET);
|
||||
}
|
||||
|
||||
/**
|
||||
* geni_write_fw_revision() - Write the firmware revision.
|
||||
* @se: Pointer to the concerned serial engine.
|
||||
* @serial_protocol: serial protocol type.
|
||||
* @fw_version: QUP firmware version.
|
||||
*
|
||||
* Write the firmware revision and protocol into the respective register.
|
||||
*/
|
||||
static void geni_write_fw_revision(struct geni_se *se, u16 serial_protocol, u16 fw_version)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
reg = FIELD_PREP(FW_REV_PROTOCOL_MSK, serial_protocol);
|
||||
reg |= FIELD_PREP(FW_REV_VERSION_MSK, fw_version);
|
||||
|
||||
writel(reg, se->base + SE_GENI_FW_REVISION);
|
||||
writel(reg, se->base + SE_GENI_S_FW_REVISION);
|
||||
}
|
||||
|
||||
/**
|
||||
* geni_load_se_fw() - Load Serial Engine specific firmware.
|
||||
* @se: Pointer to the concerned serial engine.
|
||||
* @fw: Pointer to the firmware structure.
|
||||
* @mode: SE data transfer mode.
|
||||
* @protocol: Protocol type to be used with the SE (e.g., UART, SPI, I2C).
|
||||
*
|
||||
* Load the protocol firmware into the IRAM of the Serial Engine.
|
||||
*
|
||||
* Return: 0 if successful, otherwise return an error value.
|
||||
*/
|
||||
static int geni_load_se_fw(struct geni_se *se, const struct firmware *fw,
|
||||
enum geni_se_xfer_mode mode, enum geni_se_protocol_type protocol)
|
||||
{
|
||||
const u32 *fw_data, *cfg_val_arr;
|
||||
const u8 *cfg_idx_arr;
|
||||
u32 i, reg_value;
|
||||
int ret;
|
||||
struct se_fw_hdr *hdr;
|
||||
|
||||
hdr = geni_find_protocol_fw(se->dev, fw, protocol);
|
||||
if (!hdr)
|
||||
return -EINVAL;
|
||||
|
||||
fw_data = (const u32 *)((u8 *)hdr + le16_to_cpu(hdr->fw_offset));
|
||||
cfg_idx_arr = (const u8 *)hdr + le16_to_cpu(hdr->cfg_idx_offset);
|
||||
cfg_val_arr = (const u32 *)((u8 *)hdr + le16_to_cpu(hdr->cfg_val_offset));
|
||||
|
||||
ret = geni_icc_set_bw(se);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = geni_icc_enable(se);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = geni_se_resources_on(se);
|
||||
if (ret)
|
||||
goto out_icc_disable;
|
||||
|
||||
/*
|
||||
* Disable high-priority interrupts until all currently executing
|
||||
* low-priority interrupts have been fully handled.
|
||||
*/
|
||||
geni_setbits32(se->wrapper->base + QUPV3_COMMON_CFG, FAST_SWITCH_TO_HIGH_DISABLE);
|
||||
|
||||
/* Set AHB_M_CLK_CGC_ON to indicate hardware controls se-wrapper cgc clock. */
|
||||
geni_setbits32(se->wrapper->base + QUPV3_SE_AHB_M_CFG, AHB_M_CLK_CGC_ON);
|
||||
|
||||
/* Let hardware to control common cgc. */
|
||||
geni_setbits32(se->wrapper->base + QUPV3_COMMON_CGC_CTRL, COMMON_CSR_SLV_CLK_CGC_ON);
|
||||
|
||||
/*
|
||||
* Setting individual bits in GENI_OUTPUT_CTRL activates corresponding output lines,
|
||||
* allowing the hardware to drive data as configured.
|
||||
*/
|
||||
writel(0x0, se->base + GENI_OUTPUT_CTRL);
|
||||
|
||||
/* Set SCLK and HCLK to program RAM */
|
||||
geni_setbits32(se->base + SE_GENI_CGC_CTRL, PROG_RAM_SCLK_OFF | PROG_RAM_HCLK_OFF);
|
||||
writel(0x0, se->base + SE_GENI_CLK_CTRL);
|
||||
geni_clrbits32(se->base + SE_GENI_CGC_CTRL, PROG_RAM_SCLK_OFF | PROG_RAM_HCLK_OFF);
|
||||
|
||||
/* Enable required clocks for DMA CSR, TX and RX. */
|
||||
reg_value = AHB_SEC_SLV_CLK_CGC_ON | DMA_AHB_SLV_CLK_CGC_ON |
|
||||
DMA_TX_CLK_CGC_ON | DMA_RX_CLK_CGC_ON;
|
||||
geni_setbits32(se->base + SE_DMA_GENERAL_CFG, reg_value);
|
||||
|
||||
/* Let hardware control CGC by default. */
|
||||
writel(DEFAULT_CGC_EN, se->base + SE_GENI_CGC_CTRL);
|
||||
|
||||
/* Set version of the configuration register part of firmware. */
|
||||
writel(le16_to_cpu(hdr->cfg_version), se->base + SE_GENI_INIT_CFG_REVISION);
|
||||
writel(le16_to_cpu(hdr->cfg_version), se->base + SE_GENI_S_INIT_CFG_REVISION);
|
||||
|
||||
/* Configure GENI primitive table. */
|
||||
for (i = 0; i < le16_to_cpu(hdr->cfg_size_in_items); i++)
|
||||
writel(cfg_val_arr[i],
|
||||
se->base + SE_GENI_CFG_REG0 + (cfg_idx_arr[i] * sizeof(u32)));
|
||||
|
||||
/* Configure condition for assertion of RX_RFR_WATERMARK condition. */
|
||||
reg_value = geni_se_get_rx_fifo_depth(se);
|
||||
writel(reg_value - 2, se->base + SE_GENI_RX_RFR_WATERMARK_REG);
|
||||
|
||||
/* Let hardware control CGC */
|
||||
geni_setbits32(se->base + GENI_OUTPUT_CTRL, DEFAULT_IO_OUTPUT_CTRL_MSK);
|
||||
|
||||
ret = geni_configure_xfer_mode(se, mode);
|
||||
if (ret)
|
||||
goto out_resources_off;
|
||||
|
||||
geni_enable_interrupts(se);
|
||||
|
||||
geni_write_fw_revision(se, le16_to_cpu(hdr->serial_protocol), le16_to_cpu(hdr->fw_version));
|
||||
|
||||
/* Program RAM address space. */
|
||||
memcpy_toio(se->base + SE_GENI_CFG_RAMN, fw_data,
|
||||
le16_to_cpu(hdr->fw_size_in_items) * sizeof(u32));
|
||||
|
||||
/* Put default values on GENI's output pads. */
|
||||
writel_relaxed(0x1, se->base + GENI_FORCE_DEFAULT_REG);
|
||||
|
||||
/* Toggle SCLK/HCLK from high to low to finalize RAM programming and apply config. */
|
||||
geni_setbits32(se->base + SE_GENI_CGC_CTRL, PROG_RAM_SCLK_OFF | PROG_RAM_HCLK_OFF);
|
||||
geni_setbits32(se->base + SE_GENI_CLK_CTRL, SER_CLK_SEL);
|
||||
geni_clrbits32(se->base + SE_GENI_CGC_CTRL, PROG_RAM_SCLK_OFF | PROG_RAM_HCLK_OFF);
|
||||
|
||||
/* Serial engine DMA interface is enabled. */
|
||||
geni_setbits32(se->base + SE_DMA_IF_EN, DMA_IF_EN);
|
||||
|
||||
/* Enable or disable FIFO interface of the serial engine. */
|
||||
if (mode == GENI_SE_FIFO)
|
||||
geni_clrbits32(se->base + SE_FIFO_IF_DISABLE, FIFO_IF_DISABLE);
|
||||
else
|
||||
geni_setbits32(se->base + SE_FIFO_IF_DISABLE, FIFO_IF_DISABLE);
|
||||
|
||||
out_resources_off:
|
||||
geni_se_resources_off(se);
|
||||
|
||||
out_icc_disable:
|
||||
geni_icc_disable(se);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* geni_load_se_firmware() - Load firmware for SE based on protocol
|
||||
* @se: Pointer to the concerned serial engine.
|
||||
* @protocol: Protocol type to be used with the SE (e.g., UART, SPI, I2C).
|
||||
*
|
||||
* Retrieves the firmware name from device properties and sets the transfer mode
|
||||
* (FIFO or GSI DMA) based on device tree configuration. Enforces FIFO mode for
|
||||
* UART protocol due to lack of GSI DMA support. Requests the firmware and loads
|
||||
* it into the SE.
|
||||
*
|
||||
* Return: 0 on success, negative error code on failure.
|
||||
*/
|
||||
int geni_load_se_firmware(struct geni_se *se, enum geni_se_protocol_type protocol)
|
||||
{
|
||||
const char *fw_name;
|
||||
const struct firmware *fw;
|
||||
enum geni_se_xfer_mode mode = GENI_SE_FIFO;
|
||||
int ret;
|
||||
|
||||
if (protocol >= ARRAY_SIZE(protocol_name)) {
|
||||
dev_err(se->dev, "Invalid geni-se protocol: %d", protocol);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = device_property_read_string(se->wrapper->dev, "firmware-name", &fw_name);
|
||||
if (ret) {
|
||||
dev_err(se->dev, "Failed to read firmware-name property: %d\n", ret);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (of_property_read_bool(se->dev->of_node, "qcom,enable-gsi-dma"))
|
||||
mode = GENI_GPI_DMA;
|
||||
|
||||
/* GSI mode is not supported by the UART driver; therefore, setting FIFO mode */
|
||||
if (protocol == GENI_SE_UART)
|
||||
mode = GENI_SE_FIFO;
|
||||
|
||||
ret = request_firmware(&fw, fw_name, se->dev);
|
||||
if (ret) {
|
||||
if (ret == -ENOENT)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
dev_err(se->dev, "Failed to request firmware '%s' for protocol %d: ret: %d\n",
|
||||
fw_name, protocol, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = geni_load_se_fw(se, fw, mode, protocol);
|
||||
release_firmware(fw);
|
||||
|
||||
if (ret) {
|
||||
dev_err(se->dev, "Failed to load SE firmware for protocol %d: ret: %d\n",
|
||||
protocol, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_dbg(se->dev, "Firmware load for %s protocol is successful for xfer mode: %d\n",
|
||||
protocol_name[protocol], mode);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(geni_load_se_firmware);
|
||||
|
||||
static int geni_se_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
|
|
|
|||
|
|
@ -584,6 +584,7 @@ static const struct of_device_id qcom_pdm_domains[] __maybe_unused = {
|
|||
{ .compatible = "qcom,sm8450", .data = sm8350_domains, },
|
||||
{ .compatible = "qcom,sm8550", .data = sm8550_domains, },
|
||||
{ .compatible = "qcom,sm8650", .data = sm8550_domains, },
|
||||
{ .compatible = "qcom,sm8750", .data = sm8550_domains, },
|
||||
{ .compatible = "qcom,x1e80100", .data = x1e80100_domains, },
|
||||
{ .compatible = "qcom,x1p42100", .data = x1e80100_domains, },
|
||||
{},
|
||||
|
|
|
|||
|
|
@ -229,7 +229,6 @@ static const struct regmap_config qrc_regmap_config = {
|
|||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.max_register = 0x68,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
static const struct reg_sequence msm8976_cfg_dfs_sid[] = {
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ static int master_stats_probe(struct platform_device *pdev)
|
|||
if (count < 0)
|
||||
return count;
|
||||
|
||||
data = devm_kzalloc(dev, count * sizeof(*data), GFP_KERNEL);
|
||||
data = devm_kcalloc(dev, count, sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
|||
|
|
@ -453,13 +453,10 @@ static irqreturn_t tcs_tx_done(int irq, void *p)
|
|||
|
||||
trace_rpmh_tx_done(drv, i, req);
|
||||
|
||||
/*
|
||||
* If wake tcs was re-purposed for sending active
|
||||
* votes, clear AMC trigger & enable modes and
|
||||
/* Clear AMC trigger & enable modes and
|
||||
* disable interrupt for this TCS
|
||||
*/
|
||||
if (!drv->tcs[ACTIVE_TCS].num_tcs)
|
||||
__tcs_set_trigger(drv, i, false);
|
||||
__tcs_set_trigger(drv, i, false);
|
||||
skip:
|
||||
/* Reclaim the TCS */
|
||||
write_tcs_reg(drv, drv->regs[RSC_DRV_CMD_ENABLE], i, 0);
|
||||
|
|
|
|||
|
|
@ -898,7 +898,7 @@ static u32 qcom_smem_get_item_count(struct qcom_smem *smem)
|
|||
if (IS_ERR_OR_NULL(ptable))
|
||||
return SMEM_ITEM_COUNT;
|
||||
|
||||
info = (struct smem_info *)&ptable->entry[ptable->num_entries];
|
||||
info = (struct smem_info *)&ptable->entry[le32_to_cpu(ptable->num_entries)];
|
||||
if (memcmp(info->magic, SMEM_INFO_MAGIC, sizeof(info->magic)))
|
||||
return SMEM_ITEM_COUNT;
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue