Qualcomm driver updates for v5.19

This converts a wide range of Qualcomm-related DeviceTree bindings to
 YAML, in order to improve our ability to validate the DeviceTree source.
 
 The RPMh power-domain driver gains support for the modem platform SDX65,
 the compute platform SC8280XP and the automotive platform SA8540p. While
 LLCC gains support for SC8180X and SC8280XP and gains a
 MODULE_DEVICE_TABLE() to make it functional as a module.
 
 It adds a driver for configuring the SSC bus, providing Linux access to
 the hardware blocks in the sensor subsystem.
 
 The socinfo driver gets confusion related to MSM8974 Pro sorted out and
 adds new ids for SM8540 and SC7280.
 
 The SCM driver gains support for MSM8974.
 
 Add missing of_node_put() in smp2p and smsm drivers.
 Stop using iterator after list_for_each_entry() and define static
 definitions as such, in the PDR driver.
 -----BEGIN PGP SIGNATURE-----
 
 iQJPBAABCAA5FiEEBd4DzF816k8JZtUlCx85Pw2ZrcUFAmJ5WsYbHGJqb3JuLmFu
 ZGVyc3NvbkBsaW5hcm8ub3JnAAoJEAsfOT8Nma3FIo8P+wcc78TQQuG67nqPr2gb
 QFqVK8U2mz07XW0H1rnGZKsTSrZxFs/YWRBaw+dYC5OZVJHx/uoZM04Njsyy/DFh
 UaNQgTgsS4+D5+butveh4lBdmk4ja5sreLHw25/azw5VBzeHb9+4HeAd7QMMQ+BO
 /EvIlykPwsgGIZwabzDHkY8w/xt64CPiajps1qGlFDJedSLsdJ8bKHctvcFD03v3
 3utJku3jAc5SZMBQgDttpPwpn7UnHXjCvWxyz8oSFaWDQBROztH0FbiJsZnjMuFI
 9RfRqblgb2PkvaG23W7jv68aJf3yQ6siY8ezPPs3/1F6T6tMQaAKEhwrY93ZQiWc
 gDDx33TvX3YJiRRdC2Gvg1QpL4xMFUERR8o4ooQ0t+b8bG6TkGP44VVg3/n1wrMK
 Q5xdgDigfrNnVZV1b2flQHc4qke4hNoV23SQ7iFWvtSJO09xklVJhXFGQ6mthEkb
 PnBFurLyxglKw6afs1/2P8tplS52K0l19lgNJu6vtUzC6fMOg50cX0mmWP8+rkFb
 njhXlPqCDataECZazyxnn7KORAn3E7zQceJ/LJeV+XZ9i5DJLXup+JkuBCWem4Nd
 ucEeYtQVRel5FCWZZzkXviPCTlWgTB7ya7pJPCzvZpnNFHeSWSjr9YK6xtWwy9rP
 CBRXYrz2gJLV/MGkB1piAwkm
 =/Dqp
 -----END PGP SIGNATURE-----
gpgsig -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEo6/YBQwIrVS28WGKmmx57+YAGNkFAmJ5hB4ACgkQmmx57+YA
 GNksBxAAj09+d2U1sFSJl3HiHTrXyg3MYoG0dA1QK2CRKucdwMf6KBGpEHTQyL6a
 Iqan6URrTqEM3WP4suBsZh8vbv1C8u7KGWwDAMqJ18BkigoGHEV1PyvmHYRvPoT2
 6DSHAkGbYfDglxXZ4JcxNaQk3+t6rZpe5LcRRgQ7JpoKfzlqKxfSJfPFLzYAvhSV
 qThiyd3GvfcgkVHL9noh4BrBrnNRj7wMzUwQnhW5aWebN+DqgG8zlzmmZEQx61uR
 sjMogRZNpGXVAR+4yvPZNoxTGM0plssxlkDQGS4b0XLP1t7ohr22eFPTrWqcsYCi
 h4fa3nXxUIoTDJXQ7nmU04VXp5xVUtQKKe+zXIvQBT98OkM1f6ep5i7rrEh5DZxJ
 TWVdRLuIVpHVsVARqq+qpEnwyDeiF3Hgmope3xPYhEIs1WcIOQzWBjHbNTNeiFdy
 fQMrmAQjirXJBV18ImRSMcAXW+Shc72vnj6fViQcrL5Pzj1HJFMjh/bpPzAhIUYJ
 w9to8mpNgHUpMwnkfMUqQDV6FANVbYPqancK/z4rEPd8mj6bq1z2GEQq2e9+cAfM
 imyD30+g7fm7e4mxp53mv/oxqf4NJExE0eIjXAQY53at0TCk+ngsxJd96Wz3aIpB
 eL9YN5x+y6vXkFC+hsnX2/QdUiVCmfpbrez2QqzoZncSkJ4mjdI=
 =rjVH
 -----END PGP SIGNATURE-----

Merge tag 'qcom-drivers-for-5.19' of git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux into arm/drivers

Qualcomm driver updates for v5.19

This converts a wide range of Qualcomm-related DeviceTree bindings to
YAML, in order to improve our ability to validate the DeviceTree source.

The RPMh power-domain driver gains support for the modem platform SDX65,
the compute platform SC8280XP and the automotive platform SA8540p. While
LLCC gains support for SC8180X and SC8280XP and gains a
MODULE_DEVICE_TABLE() to make it functional as a module.

It adds a driver for configuring the SSC bus, providing Linux access to
the hardware blocks in the sensor subsystem.

The socinfo driver gets confusion related to MSM8974 Pro sorted out and
adds new ids for SM8540 and SC7280.

The SCM driver gains support for MSM8974.

Add missing of_node_put() in smp2p and smsm drivers.
Stop using iterator after list_for_each_entry() and define static
definitions as such, in the PDR driver.

* tag 'qcom-drivers-for-5.19' of git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux: (33 commits)
  soc: qcom: pdr: use static for servreg_* variables
  soc: qcom: llcc: Add sc8180x and sc8280xp configurations
  dt-bindings: arm: msm: Add sc8180x and sc8280xp LLCC compatibles
  soc: qcom: rpmhpd: add sc8280xp & sa8540p rpmh power-domains
  soc: qcom: rpmhpd: Don't warn about sparse rpmhpd arrays
  dt-bindings: power: rpmpd: Add sc8280xp RPMh power-domains
  spi: dt-bindings: qcom,spi-geni-qcom: convert to dtschema
  soc: qcom: socinfo: Sort out 8974PRO names
  dt-bindings: soc: qcom,smp2p: convert to dtschema
  dt-bindings: qcom: geni-se: Update UART schema reference
  dt-bindings: qcom: geni-se: Update I2C schema reference
  dt-bindings: soc: qcom,rpmh-rsc: convert to dtschema
  bus: add driver for initializing the SSC bus on (some) qcom SoCs
  dt-bindings: bus: add device tree bindings for qcom,ssc-block-bus
  dt-bindings: qcom: qcom,geni-se: refer to dtschema for SPI
  dt-bindings: soc: qcom,smd: convert to dtschema
  firmware: qcom_scm: Add compatible for MSM8976 SoC
  dt-bindings: firmware: qcom-scm: Document msm8976 bindings
  soc: qcom: smem: validate fields of shared structures
  soc: qcom: smem: map only partitions used by local HOST
  ...

Link: https://lore.kernel.org/r/20220509181839.316655-1-bjorn.andersson@linaro.org
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
Arnd Bergmann 2022-05-09 23:14:05 +02:00
commit 3f656f2618
39 changed files with 2095 additions and 917 deletions

View File

@ -23,6 +23,8 @@ properties:
enum:
- qcom,sc7180-llcc
- qcom,sc7280-llcc
- qcom,sc8180x-llcc
- qcom,sc8280xp-llcc
- qcom,sdm845-llcc
- qcom,sm6350-llcc
- qcom,sm8150-llcc

View File

@ -39,8 +39,11 @@ description: |
msm8994
msm8996
sa8155p
sa8540p
sc7180
sc7280
sc8180x
sc8280xp
sdm630
sdm632
sdm660
@ -225,6 +228,18 @@ properties:
- google,senor
- const: qcom,sc7280
- items:
- enum:
- lenovo,flex-5g
- microsoft,surface-prox
- qcom,sc8180x-primus
- const: qcom,sc8180x
- items:
- enum:
- qcom,sc8280xp-qrd
- const: qcom,sc8280xp
- items:
- enum:
- fairphone,fp3
@ -258,6 +273,11 @@ properties:
- qcom,sa8155p-adp
- const: qcom,sa8155p
- items:
- enum:
- qcom,sa8295p-adp
- const: qcom,sa8540p
- items:
- enum:
- fairphone,fp4

View File

@ -0,0 +1,147 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/bus/qcom,ssc-block-bus.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: The AHB Bus Providing a Global View of the SSC Block on (some) qcom SoCs
maintainers:
- Michael Srba <Michael.Srba@seznam.cz>
description: |
This binding describes the dependencies (clocks, resets, power domains) which
need to be turned on in a sequence before communication over the AHB bus
becomes possible.
Additionally, the reg property is used to pass to the driver the location of
two sadly undocumented registers which need to be poked as part of the sequence.
The SSC (Snapdragon Sensor Core) block contains a gpio controller, i2c/spi/uart
controllers, a hexagon core, and a clock controller which provides clocks for
the above.
properties:
compatible:
items:
- const: qcom,msm8998-ssc-block-bus
- const: qcom,ssc-block-bus
reg:
description: |
Shall contain the addresses of the SSCAON_CONFIG0 and SSCAON_CONFIG1
registers
minItems: 2
maxItems: 2
reg-names:
items:
- const: mpm_sscaon_config0
- const: mpm_sscaon_config1
'#address-cells':
enum: [ 1, 2 ]
'#size-cells':
enum: [ 1, 2 ]
ranges: true
clocks:
minItems: 6
maxItems: 6
clock-names:
items:
- const: xo
- const: aggre2
- const: gcc_im_sleep
- const: aggre2_north
- const: ssc_xo
- const: ssc_ahbs
power-domains:
description: Power domain phandles for the ssc_cx and ssc_mx power domains
minItems: 2
maxItems: 2
power-domain-names:
items:
- const: ssc_cx
- const: ssc_mx
resets:
description: |
Reset phandles for the ssc_reset and ssc_bcr resets (note: ssc_bcr is the
branch control register associated with the ssc_xo and ssc_ahbs clocks)
minItems: 2
maxItems: 2
reset-names:
items:
- const: ssc_reset
- const: ssc_bcr
qcom,halt-regs:
$ref: /schemas/types.yaml#/definitions/phandle-array
description: describes how to locate the ssc AXI halt register
items:
- items:
- description: Phandle reference to a syscon representing TCSR
- description: offset for the ssc AXI halt register
required:
- compatible
- reg
- reg-names
- '#address-cells'
- '#size-cells'
- ranges
- clocks
- clock-names
- power-domains
- power-domain-names
- resets
- reset-names
- qcom,halt-regs
additionalProperties:
type: object
examples:
- |
#include <dt-bindings/clock/qcom,gcc-msm8998.h>
#include <dt-bindings/clock/qcom,rpmcc.h>
#include <dt-bindings/power/qcom-rpmpd.h>
soc {
#address-cells = <1>;
#size-cells = <1>;
// devices under this node are physically located in the SSC block, connected to an ssc-internal bus;
ssc_ahb_slave: bus@10ac008 {
#address-cells = <1>;
#size-cells = <1>;
ranges;
compatible = "qcom,msm8998-ssc-block-bus", "qcom,ssc-block-bus";
reg = <0x10ac008 0x4>, <0x10ac010 0x4>;
reg-names = "mpm_sscaon_config0", "mpm_sscaon_config1";
clocks = <&xo>,
<&rpmcc RPM_SMD_AGGR2_NOC_CLK>,
<&gcc GCC_IM_SLEEP>,
<&gcc AGGRE2_SNOC_NORTH_AXI>,
<&gcc SSC_XO>,
<&gcc SSC_CNOC_AHBS_CLK>;
clock-names = "xo", "aggre2", "gcc_im_sleep", "aggre2_north", "ssc_xo", "ssc_ahbs";
resets = <&gcc GCC_SSC_RESET>, <&gcc GCC_SSC_BCR>;
reset-names = "ssc_reset", "ssc_bcr";
power-domains = <&rpmpd MSM8998_SSCCX>, <&rpmpd MSM8998_SSCMX>;
power-domain-names = "ssc_cx", "ssc_mx";
qcom,halt-regs = <&tcsr_mutex_regs 0x26000>;
};
};

View File

@ -19,6 +19,7 @@ Required properties:
* "qcom,scm-msm8953"
* "qcom,scm-msm8960"
* "qcom,scm-msm8974"
* "qcom,scm-msm8976"
* "qcom,scm-msm8994"
* "qcom,scm-msm8996"
* "qcom,scm-msm8998"
@ -37,7 +38,7 @@ Required properties:
* core clock required for "qcom,scm-apq8064", "qcom,scm-msm8660" and
"qcom,scm-msm8960"
* core, iface and bus clocks required for "qcom,scm-apq8084",
"qcom,scm-msm8916", "qcom,scm-msm8953" and "qcom,scm-msm8974"
"qcom,scm-msm8916", "qcom,scm-msm8953", "qcom,scm-msm8974" and "qcom,scm-msm8976"
- clock-names: Must contain "core" for the core clock, "iface" for the interface
clock and "bus" for the bus clock per the requirements of the compatible.
- qcom,dload-mode: phandle to the TCSR hardware block and offset of the

View File

@ -45,20 +45,20 @@ additionalProperties: false
examples:
# Example 1: apps bcm_voter on SDM845 SoC should be defined inside &apps_rsc node
# as defined in Documentation/devicetree/bindings/soc/qcom/rpmh-rsc.txt
# as defined in Documentation/devicetree/bindings/soc/qcom/qcom,rpmh-rsc.yaml
- |
apps_bcm_voter: bcm_voter {
apps_bcm_voter: bcm-voter {
compatible = "qcom,bcm-voter";
};
# Example 2: disp bcm_voter on SDM845 should be defined inside &disp_rsc node
# as defined in Documentation/devicetree/bindings/soc/qcom/rpmh-rsc.txt
# as defined in Documentation/devicetree/bindings/soc/qcom/qcom,rpmh-rsc.yaml
- |
#include <dt-bindings/interconnect/qcom,icc.h>
disp_bcm_voter: bcm_voter {
disp_bcm_voter: bcm-voter {
compatible = "qcom,bcm-voter";
qcom,tcs-wait = <QCOM_ICC_TAG_AMC>;
};

View File

@ -27,12 +27,15 @@ properties:
- qcom,msm8998-rpmpd
- qcom,qcm2290-rpmpd
- qcom,qcs404-rpmpd
- qcom,sa8540p-rpmhpd
- qcom,sdm660-rpmpd
- qcom,sc7180-rpmhpd
- qcom,sc7280-rpmhpd
- qcom,sc8180x-rpmhpd
- qcom,sc8280xp-rpmhpd
- qcom,sdm845-rpmhpd
- qcom,sdx55-rpmhpd
- qcom,sdx65-rpmhpd
- qcom,sm6115-rpmpd
- qcom,sm6125-rpmpd
- qcom,sm6350-rpmhpd

View File

@ -12,7 +12,7 @@ description:
resides as a subnode of the SMD. As such, the SMD-RPM regulator requires
that the SMD and RPM nodes be present.
Please refer to Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt for
Please refer to Documentation/devicetree/bindings/soc/qcom/qcom,smd.yaml for
information pertaining to the SMD node.
Please refer to Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.yaml
@ -69,7 +69,8 @@ description:
l12, l13, l14, l15, l16, l17, l18, l19, l20, l21, l22
maintainers:
- Kathiravan T <kathirav@codeaurora.org>
- Andy Gross <agross@kernel.org>
- Bjorn Andersson <bjorn.andersson@linaro.org>
properties:
compatible:

View File

@ -250,7 +250,7 @@ the memory regions used by the Hexagon firmware. Each sub-node must contain:
The Hexagon node may also have an subnode named either "smd-edge" or
"glink-edge" that describes the communication edge, channels and devices
related to the Hexagon. See ../soc/qcom/qcom,smd.txt and
related to the Hexagon. See ../soc/qcom/qcom,smd.yaml and
../soc/qcom/qcom,glink.txt for details on how to describe these.
= EXAMPLE

View File

@ -111,7 +111,7 @@ and its resource dependencies. It is described by the following properties:
The wcnss node can also have an subnode named "smd-edge" that describes the SMD
edge, channels and devices related to the WCNSS.
See ../soc/qcom/qcom,smd.txt for details on how to describe the SMD edge.
See ../soc/qcom/qcom,smd.yaml for details on how to describe the SMD edge.
= EXAMPLE
The following example describes the resources needed to boot control the WCNSS,

View File

@ -64,116 +64,23 @@ required:
- ranges
patternProperties:
"^.*@[0-9a-f]+$":
type: object
description: Common properties for GENI Serial Engine based I2C, SPI and
UART controller.
properties:
reg:
description: GENI Serial Engine register address and length.
maxItems: 1
clock-names:
const: se
clocks:
description: Serial engine core clock needed by the device.
maxItems: 1
interconnects:
minItems: 2
maxItems: 3
interconnect-names:
minItems: 2
items:
- const: qup-core
- const: qup-config
- const: qup-memory
required:
- reg
- clock-names
- clocks
"spi@[0-9a-f]+$":
type: object
description: GENI serial engine based SPI controller. SPI in master mode
supports up to 50MHz, up to four chip selects, programmable
data path from 4 bits to 32 bits and numerous protocol
variants.
$ref: /schemas/spi/spi-controller.yaml#
properties:
compatible:
enum:
- qcom,geni-spi
interrupts:
maxItems: 1
"#address-cells":
const: 1
"#size-cells":
const: 0
required:
- compatible
- interrupts
- "#address-cells"
- "#size-cells"
$ref: /schemas/spi/qcom,spi-geni-qcom.yaml#
"i2c@[0-9a-f]+$":
type: object
description: GENI serial engine based I2C controller.
$ref: /schemas/i2c/i2c-controller.yaml#
properties:
compatible:
enum:
- qcom,geni-i2c
interrupts:
maxItems: 1
"#address-cells":
const: 1
"#size-cells":
const: 0
clock-frequency:
description: Desired I2C bus clock frequency in Hz.
default: 100000
required:
- compatible
- interrupts
- "#address-cells"
- "#size-cells"
$ref: /schemas/i2c/qcom,i2c-geni-qcom.yaml#
"serial@[0-9a-f]+$":
type: object
description: GENI Serial Engine based UART Controller.
$ref: /schemas/serial.yaml#
properties:
compatible:
enum:
- qcom,geni-uart
- qcom,geni-debug-uart
interrupts:
minItems: 1
items:
- description: UART core irq
- description: Wakeup irq (RX GPIO)
required:
- compatible
- interrupts
$ref: /schemas/serial/qcom,serial-geni-qcom.yaml#
additionalProperties: false

View File

@ -1,87 +0,0 @@
QCOM GSBI (General Serial Bus Interface) Driver
The GSBI controller is modeled as a node with zero or more child nodes, each
representing a serial sub-node device that is mux'd as part of the GSBI
configuration settings. The mode setting will govern the input/output mode of
the 4 GSBI IOs.
Required properties:
- compatible: Should contain "qcom,gsbi-v1.0.0"
- cell-index: Should contain the GSBI index
- reg: Address range for GSBI registers
- clocks: required clock
- clock-names: must contain "iface" entry
- qcom,mode : indicates MUX value for configuration of the serial interface.
Please reference dt-bindings/soc/qcom,gsbi.h for valid mux values.
Optional properties:
- qcom,crci : indicates CRCI MUX value for QUP CRCI ports. Please reference
dt-bindings/soc/qcom,gsbi.h for valid CRCI mux values.
- syscon-tcsr: indicates phandle of TCSR syscon node. Required if child uses
dma.
Required properties if child node exists:
- #address-cells: Must be 1
- #size-cells: Must be 1
- ranges: Must be present
Properties for children:
A GSBI controller node can contain 0 or more child nodes representing serial
devices. These serial devices can be a QCOM UART, I2C controller, spi
controller, or some combination of aforementioned devices.
See the following for child node definitions:
Documentation/devicetree/bindings/i2c/qcom,i2c-qup.txt
Documentation/devicetree/bindings/spi/qcom,spi-qup.txt
Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt
Example for APQ8064:
#include <dt-bindings/soc/qcom,gsbi.h>
gsbi4@16300000 {
compatible = "qcom,gsbi-v1.0.0";
cell-index = <4>;
reg = <0x16300000 0x100>;
clocks = <&gcc GSBI4_H_CLK>;
clock-names = "iface";
#address-cells = <1>;
#size-cells = <1>;
ranges;
qcom,mode = <GSBI_PROT_I2C_UART>;
qcom,crci = <GSBI_CRCI_QUP>;
syscon-tcsr = <&tcsr>;
/* child nodes go under here */
i2c_qup4: i2c@16380000 {
compatible = "qcom,i2c-qup-v1.1.1";
reg = <0x16380000 0x1000>;
interrupts = <0 153 0>;
clocks = <&gcc GSBI4_QUP_CLK>, <&gcc GSBI4_H_CLK>;
clock-names = "core", "iface";
clock-frequency = <200000>;
#address-cells = <1>;
#size-cells = <0>;
};
uart4: serial@16340000 {
compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
reg = <0x16340000 0x1000>,
<0x16300000 0x1000>;
interrupts = <0 152 0x0>;
clocks = <&gcc GSBI4_UART_CLK>, <&gcc GSBI4_H_CLK>;
clock-names = "core", "iface";
};
};
tcsr: syscon@1a400000 {
compatible = "qcom,apq8064-tcsr", "syscon";
reg = <0x1a400000 0x100>;
};

View File

@ -0,0 +1,132 @@
# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/soc/qcom/qcom,gsbi.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm General Serial Bus Interface (GSBI)
maintainers:
- Andy Gross <agross@kernel.org>
- Bjorn Andersson <bjorn.andersson@linaro.org>
- Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
description:
The GSBI controller is modeled as a node with zero or more child nodes, each
representing a serial sub-node device that is mux'd as part of the GSBI
configuration settings. The mode setting will govern the input/output mode
of the 4 GSBI IOs.
A GSBI controller node can contain 0 or more child nodes representing serial
devices. These serial devices can be a QCOM UART, I2C controller, spi
controller, or some combination of aforementioned devices.
properties:
compatible:
const: qcom,gsbi-v1.0.0
'#address-cells':
const: 1
cell-index:
$ref: /schemas/types.yaml#/definitions/uint32
description:
The GSBI index.
clocks:
maxItems: 1
clock-names:
const: iface
qcom,crci:
$ref: /schemas/types.yaml#/definitions/uint32
description:
CRCI MUX value for QUP CRCI ports. Please reference
include/dt-bindings/soc/qcom,gsbi.h for valid CRCI mux values.
qcom,mode:
$ref: /schemas/types.yaml#/definitions/uint32
description:
MUX value for configuration of the serial interface. Please reference
include/dt-bindings/soc/qcom,gsbi.h for valid mux values.
'#size-cells':
const: 1
syscon-tcsr:
$ref: /schemas/types.yaml#/definitions/phandle
description:
Phandle of TCSR syscon node.Required if child uses dma.
ranges: true
reg:
maxItems: 1
patternProperties:
"spi@[0-9a-f]+$":
type: object
$ref: /schemas/spi/qcom,spi-qup.yaml#
"i2c@[0-9a-f]+$":
type: object
$ref: /schemas/i2c/qcom,i2c-qup.yaml#
"serial@[0-9a-f]+$":
type: object
$ref: /schemas/serial/qcom,msm-uartdm.yaml#
required:
- compatible
- cell-index
- clocks
- clock-names
- qcom,mode
- reg
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,gcc-msm8960.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/soc/qcom,gsbi.h>
gsbi@12440000 {
compatible = "qcom,gsbi-v1.0.0";
reg = <0x12440000 0x100>;
cell-index = <1>;
clocks = <&gcc GSBI1_H_CLK>;
clock-names = "iface";
#address-cells = <1>;
#size-cells = <1>;
ranges;
syscon-tcsr = <&tcsr>;
qcom,mode = <GSBI_PROT_I2C_UART>;
serial@12450000 {
compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
reg = <0x12450000 0x100>,
<0x12400000 0x03>;
interrupts = <0 193 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GSBI1_UART_CLK>, <&gcc GSBI1_H_CLK>;
clock-names = "core", "iface";
};
i2c@12460000 {
compatible = "qcom,i2c-qup-v1.1.1";
reg = <0x12460000 0x1000>;
pinctrl-0 = <&i2c1_pins>;
pinctrl-1 = <&i2c1_pins_sleep>;
pinctrl-names = "default", "sleep";
interrupts = <0 194 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GSBI1_QUP_CLK>, <&gcc GSBI1_H_CLK>;
clock-names = "core", "iface";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled"; /* UART chosen */
};
};

View File

@ -0,0 +1,272 @@
# SPDX-License-Identifier: GPL-2.0-only
%YAML 1.2
---
$id: http://devicetree.org/schemas/soc/qcom/qcom,rpmh-rsc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm RPMH RSC
maintainers:
- Bjorn Andersson <bjorn.andersson@linaro.org>
description: |
Resource Power Manager Hardened (RPMH) is the mechanism for communicating
with the hardened resource accelerators on Qualcomm SoCs. Requests to the
resources can be written to the Trigger Command Set (TCS) registers and
using a (addr, val) pair and triggered. Messages in the TCS are then sent in
sequence over an internal bus.
The hardware block (Direct Resource Voter or DRV) is a part of the h/w entity
(Resource State Coordinator a.k.a RSC) that can handle multiple sleep and
active/wake resource requests. Multiple such DRVs can exist in a SoC and can
be written to from Linux. The structure of each DRV follows the same template
with a few variations that are captured by the properties here.
A TCS may be triggered from Linux or triggered by the F/W after all the CPUs
have powered off to facilitate idle power saving. TCS could be classified as::
ACTIVE - Triggered by Linux
SLEEP - Triggered by F/W
WAKE - Triggered by F/W
CONTROL - Triggered by F/W
See also:: <dt-bindings/soc/qcom,rpmh-rsc.h>
The order in which they are described in the DT, should match the hardware
configuration.
Requests can be made for the state of a resource, when the subsystem is
active or idle. When all subsystems like Modem, GPU, CPU are idle, the
resource state will be an aggregate of the sleep votes from each of those
subsystems. Clients may request a sleep value for their shared resources in
addition to the active mode requests.
Drivers that want to use the RSC to communicate with RPMH must specify their
bindings as child nodes of the RSC controllers they wish to communicate with.
properties:
compatible:
const: qcom,rpmh-rsc
interrupts:
minItems: 1
maxItems: 4
description:
The interrupt that trips when a message complete/response is received for
this DRV from the accelerators.
Number of interrupts must match number of DRV blocks.
label:
description:
Name for the RSC. The name would be used in trace logs.
qcom,drv-id:
$ref: /schemas/types.yaml#/definitions/uint32
description:
The ID of the DRV in the RSC block that will be used by this controller.
qcom,tcs-config:
$ref: /schemas/types.yaml#/definitions/uint32-matrix
items:
- items:
- description: TCS type
enum: [ 0, 1, 2, 3 ]
- description: Number of TCS
- items:
- description: TCS type
enum: [ 0, 1, 2, 3 ]
- description: Number of TCS
- items:
- description: TCS type
enum: [ 0, 1, 2, 3]
- description: Numbe r of TCS
- items:
- description: TCS type
enum: [ 0, 1, 2, 3 ]
- description: Number of TCS
description: |
The tuple defining the configuration of TCS. Must have two cells which
describe each TCS type. The order of the TCS must match the hardware
configuration.
Cell 1 (TCS Type):: TCS types to be specified::
- ACTIVE_TCS
- SLEEP_TCS
- WAKE_TCS
- CONTROL_TCS
Cell 2 (Number of TCS):: <u32>
qcom,tcs-offset:
$ref: /schemas/types.yaml#/definitions/uint32
description:
The offset of the TCS blocks.
reg:
minItems: 1
maxItems: 4
reg-names:
minItems: 1
items:
- const: drv-0
- const: drv-1
- const: drv-2
- const: drv-3
bcm-voter:
$ref: /schemas/interconnect/qcom,bcm-voter.yaml#
clock-controller:
$ref: /schemas/clock/qcom,rpmhcc.yaml#
power-controller:
$ref: /schemas/power/qcom,rpmpd.yaml#
patternProperties:
'-regulators$':
$ref: /schemas/regulator/qcom,rpmh-regulator.yaml#
required:
- compatible
- interrupts
- qcom,drv-id
- qcom,tcs-config
- qcom,tcs-offset
- reg
- reg-names
additionalProperties: false
examples:
- |
// For a TCS whose RSC base address is 0x179C0000 and is at a DRV id of
// 2, the register offsets for DRV2 start at 0D00, the register
// calculations are like this::
// DRV0: 0x179C0000
// DRV2: 0x179C0000 + 0x10000 = 0x179D0000
// DRV2: 0x179C0000 + 0x10000 * 2 = 0x179E0000
// TCS-OFFSET: 0xD00
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/soc/qcom,rpmh-rsc.h>
rsc@179c0000 {
compatible = "qcom,rpmh-rsc";
reg = <0x179c0000 0x10000>,
<0x179d0000 0x10000>,
<0x179e0000 0x10000>;
reg-names = "drv-0", "drv-1", "drv-2";
interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
label = "apps_rsc";
qcom,tcs-offset = <0xd00>;
qcom,drv-id = <2>;
qcom,tcs-config = <ACTIVE_TCS 2>,
<SLEEP_TCS 3>,
<WAKE_TCS 3>,
<CONTROL_TCS 1>;
};
- |
// For a TCS whose RSC base address is 0xAF20000 and is at DRV id of 0, the
// register offsets for DRV0 start at 01C00, the register calculations are
// like this::
// DRV0: 0xAF20000
// TCS-OFFSET: 0x1C00
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/soc/qcom,rpmh-rsc.h>
rsc@af20000 {
compatible = "qcom,rpmh-rsc";
reg = <0xaf20000 0x10000>;
reg-names = "drv-0";
interrupts = <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>;
label = "disp_rsc";
qcom,tcs-offset = <0x1c00>;
qcom,drv-id = <0>;
qcom,tcs-config = <ACTIVE_TCS 0>,
<SLEEP_TCS 1>,
<WAKE_TCS 1>,
<CONTROL_TCS 0>;
};
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/soc/qcom,rpmh-rsc.h>
#include <dt-bindings/power/qcom-rpmpd.h>
rsc@18200000 {
compatible = "qcom,rpmh-rsc";
reg = <0x18200000 0x10000>,
<0x18210000 0x10000>,
<0x18220000 0x10000>;
reg-names = "drv-0", "drv-1", "drv-2";
interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
label = "apps_rsc";
qcom,tcs-offset = <0xd00>;
qcom,drv-id = <2>;
qcom,tcs-config = <ACTIVE_TCS 2>,
<SLEEP_TCS 3>,
<WAKE_TCS 3>,
<CONTROL_TCS 0>;
clock-controller {
compatible = "qcom,sm8350-rpmh-clk";
#clock-cells = <1>;
clock-names = "xo";
clocks = <&xo_board>;
};
power-controller {
compatible = "qcom,sm8350-rpmhpd";
#power-domain-cells = <1>;
operating-points-v2 = <&rpmhpd_opp_table>;
rpmhpd_opp_table: opp-table {
compatible = "operating-points-v2";
rpmhpd_opp_ret: opp1 {
opp-level = <RPMH_REGULATOR_LEVEL_RETENTION>;
};
rpmhpd_opp_min_svs: opp2 {
opp-level = <RPMH_REGULATOR_LEVEL_MIN_SVS>;
};
rpmhpd_opp_low_svs: opp3 {
opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
};
rpmhpd_opp_svs: opp4 {
opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
};
rpmhpd_opp_svs_l1: opp5 {
opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
};
rpmhpd_opp_nom: opp6 {
opp-level = <RPMH_REGULATOR_LEVEL_NOM>;
};
rpmhpd_opp_nom_l1: opp7 {
opp-level = <RPMH_REGULATOR_LEVEL_NOM_L1>;
};
rpmhpd_opp_nom_l2: opp8 {
opp-level = <RPMH_REGULATOR_LEVEL_NOM_L2>;
};
rpmhpd_opp_turbo: opp9 {
opp-level = <RPMH_REGULATOR_LEVEL_TURBO>;
};
rpmhpd_opp_turbo_l1: opp10 {
opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L1>;
};
};
};
bcm-voter {
compatible = "qcom,bcm-voter";
};
};

View File

@ -12,7 +12,7 @@ description: |
to vote for state of the system resources, such as clocks, regulators and bus
frequencies.
The SMD information for the RPM edge should be filled out. See qcom,smd.txt
The SMD information for the RPM edge should be filled out. See qcom,smd.yaml
for the required edge properties. All SMD related properties will reside
within the RPM node itself.
@ -25,7 +25,8 @@ description: |
rpm_requests.
maintainers:
- Kathiravan T <kathirav@codeaurora.org>
- Andy Gross <agross@kernel.org>
- Bjorn Andersson <bjorn.andersson@linaro.org>
properties:
compatible:
@ -82,7 +83,7 @@ examples:
qcom,ipc = <&apcs 8 0>;
qcom,smd-edge = <15>;
rpm_requests {
rpm-requests {
compatible = "qcom,rpm-msm8974";
qcom,smd-channels = "rpm_requests";

View File

@ -1,98 +0,0 @@
Qualcomm Shared Memory Driver (SMD) binding
This binding describes the Qualcomm Shared Memory Driver, a fifo based
communication channel for sending data between the various subsystems in
Qualcomm platforms.
- compatible:
Usage: required
Value type: <stringlist>
Definition: must be "qcom,smd"
= EDGES
Each subnode of the SMD node represents a remote subsystem or a remote
processor of some sort - or in SMD language an "edge". The name of the edges
are not important.
The edge is described by the following properties:
- interrupts:
Usage: required
Value type: <prop-encoded-array>
Definition: should specify the IRQ used by the remote processor to
signal this processor about communication related updates
- mboxes:
Usage: required
Value type: <prop-encoded-array>
Definition: reference to the associated doorbell in APCS, as described
in mailbox/mailbox.txt
- qcom,ipc:
Usage: required, unless mboxes is specified
Value type: <prop-encoded-array>
Definition: three entries specifying the outgoing ipc bit used for
signaling the remote processor:
- phandle to a syscon node representing the apcs registers
- u32 representing offset to the register within the syscon
- u32 representing the ipc bit within the register
- qcom,smd-edge:
Usage: required
Value type: <u32>
Definition: the identifier of the remote processor in the smd channel
allocation table
- qcom,remote-pid:
Usage: optional
Value type: <u32>
Definition: the identifier for the remote processor as known by the rest
of the system.
- label:
Usage: optional
Value type: <string>
Definition: name of the edge, used for debugging and identification
purposes. The node name will be used if this is not
present.
= SMD DEVICES
In turn, subnodes of the "edges" represent devices tied to SMD channels on that
"edge". The names of the devices are not important. The properties of these
nodes are defined by the individual bindings for the SMD devices - but must
contain the following property:
- qcom,smd-channels:
Usage: required
Value type: <stringlist>
Definition: a list of channels tied to this device, used for matching
the device to channels
= EXAMPLE
The following example represents a smd node, with one edge representing the
"rpm" subsystem. For the "rpm" subsystem we have a device tied to the
"rpm_request" channel.
apcs: syscon@f9011000 {
compatible = "syscon";
reg = <0xf9011000 0x1000>;
};
smd {
compatible = "qcom,smd";
rpm {
interrupts = <0 168 1>;
qcom,ipc = <&apcs 8 0>;
qcom,smd-edge = <15>;
rpm_requests {
compatible = "qcom,rpm-msm8974";
qcom,smd-channels = "rpm_requests";
...
};
};
};

View File

@ -0,0 +1,137 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/soc/qcom/qcom,smd.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Shared Memory Driver
maintainers:
- Andy Gross <agross@kernel.org>
- Bjorn Andersson <bjorn.andersson@linaro.org>
- Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
description:
The Qualcomm Shared Memory Driver is a FIFO based communication channel for
sending data between the various subsystems in Qualcomm platforms.
properties:
compatible:
const: qcom,smd
patternProperties:
"^.*-edge|rpm$":
type: object
description:
Each subnode of the SMD node represents a remote subsystem or a remote
processor of some sort - or in SMD language an "edge". The name of the
edges are not important.
properties:
interrupts:
maxItems: 1
label:
$ref: /schemas/types.yaml#/definitions/string
description:
Name of the edge, used for debugging and identification purposes. The
node name will be used if this is not present.
mboxes:
maxItems: 1
description:
Reference to the mailbox representing the outgoing doorbell in APCS for
this client.
qcom,ipc:
$ref: /schemas/types.yaml#/definitions/phandle-array
items:
- items:
- description: phandle to a syscon node representing the APCS registers
- description: u32 representing offset to the register within the syscon
- description: u32 representing the ipc bit within the register
description:
Three entries specifying the outgoing ipc bit used for signaling the
remote processor.
qcom,smd-edge:
$ref: /schemas/types.yaml#/definitions/uint32
description:
The identifier of the remote processor in the smd channel allocation
table.
qcom,remote-pid:
$ref: /schemas/types.yaml#/definitions/uint32
description:
The identifier for the remote processor as known by the rest of the
system.
# Binding for edge subnodes is not complete
patternProperties:
"^rpm-requests$":
type: object
description:
In turn, subnodes of the "edges" represent devices tied to SMD
channels on that "edge". The names of the devices are not
important. The properties of these nodes are defined by the
individual bindings for the SMD devices.
properties:
qcom,smd-channels:
$ref: /schemas/types.yaml#/definitions/string-array
minItems: 1
maxItems: 32
description:
A list of channels tied to this device, used for matching the
device to channels.
required:
- compatible
- qcom,smd-channels
additionalProperties: true
required:
- interrupts
- qcom,smd-edge
oneOf:
- required:
- mboxes
- required:
- qcom,ipc
additionalProperties: false
required:
- compatible
additionalProperties: false
examples:
# The following example represents a smd node, with one edge representing the
# "rpm" subsystem. For the "rpm" subsystem we have a device tied to the
# "rpm_request" channel.
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
shared-memory {
compatible = "qcom,smd";
rpm {
interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>;
qcom,ipc = <&apcs 8 0>;
qcom,smd-edge = <15>;
rpm-requests {
compatible = "qcom,rpm-msm8974";
qcom,smd-channels = "rpm_requests";
clock-controller {
compatible = "qcom,rpmcc-msm8974", "qcom,rpmcc";
#clock-cells = <1>;
};
};
};
};

View File

@ -1,110 +0,0 @@
Qualcomm Shared Memory Point 2 Point binding
The Shared Memory Point to Point (SMP2P) protocol facilitates communication of
a single 32-bit value between two processors. Each value has a single writer
(the local side) and a single reader (the remote side). Values are uniquely
identified in the system by the directed edge (local processor ID to remote
processor ID) and a string identifier.
- compatible:
Usage: required
Value type: <string>
Definition: must be one of:
"qcom,smp2p"
- interrupts:
Usage: required
Value type: <prop-encoded-array>
Definition: one entry specifying the smp2p notification interrupt
- mboxes:
Usage: required
Value type: <prop-encoded-array>
Definition: reference to the associated doorbell in APCS, as described
in mailbox/mailbox.txt
- qcom,ipc:
Usage: required, unless mboxes is specified
Value type: <prop-encoded-array>
Definition: three entries specifying the outgoing ipc bit used for
signaling the remote end of the smp2p edge:
- phandle to a syscon node representing the apcs registers
- u32 representing offset to the register within the syscon
- u32 representing the ipc bit within the register
- qcom,smem:
Usage: required
Value type: <u32 array>
Definition: two identifiers of the inbound and outbound smem items used
for this edge
- qcom,local-pid:
Usage: required
Value type: <u32>
Definition: specifies the identifier of the local endpoint of this edge
- qcom,remote-pid:
Usage: required
Value type: <u32>
Definition: specifies the identifier of the remote endpoint of this edge
= SUBNODES
Each SMP2P pair contain a set of inbound and outbound entries, these are
described in subnodes of the smp2p device node. The node names are not
important.
- qcom,entry-name:
Usage: required
Value type: <string>
Definition: specifies the name of this entry, for inbound entries this
will be used to match against the remotely allocated entry
and for outbound entries this name is used for allocating
entries
- interrupt-controller:
Usage: required for incoming entries
Value type: <empty>
Definition: marks the entry as inbound; the node should be specified
as a two cell interrupt-controller as defined in
"../interrupt-controller/interrupts.txt"
If not specified this node will denote the outgoing entry
- #interrupt-cells:
Usage: required for incoming entries
Value type: <u32>
Definition: must be 2 - denoting the bit in the entry and IRQ flags
- #qcom,smem-state-cells:
Usage: required for outgoing entries
Value type: <u32>
Definition: must be 1 - denoting the bit in the entry
= EXAMPLE
The following example shows the SMP2P setup with the wireless processor,
defined from the 8974 apps processor's point-of-view. It encompasses one
inbound and one outbound entry:
wcnss-smp2p {
compatible = "qcom,smp2p";
qcom,smem = <431>, <451>;
interrupts = <0 143 1>;
qcom,ipc = <&apcs 8 18>;
qcom,local-pid = <0>;
qcom,remote-pid = <4>;
wcnss_smp2p_out: master-kernel {
qcom,entry-name = "master-kernel";
#qcom,smem-state-cells = <1>;
};
wcnss_smp2p_in: slave-kernel {
qcom,entry-name = "slave-kernel";
interrupt-controller;
#interrupt-cells = <2>;
};
};

View File

@ -0,0 +1,145 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/soc/qcom/qcom,smp2p.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Shared Memory Point 2 Point
maintainers:
- Andy Gross <agross@kernel.org>
- Bjorn Andersson <bjorn.andersson@linaro.org>
- Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
description:
The Shared Memory Point to Point (SMP2P) protocol facilitates communication
of a single 32-bit value between two processors. Each value has a single
writer (the local side) and a single reader (the remote side). Values are
uniquely identified in the system by the directed edge (local processor ID to
remote processor ID) and a string identifier.
properties:
compatible:
const: qcom,smp2p
interrupts:
maxItems: 1
mboxes:
maxItems: 1
description:
Reference to the mailbox representing the outgoing doorbell in APCS for
this client.
qcom,ipc:
$ref: /schemas/types.yaml#/definitions/phandle-array
items:
- items:
- description: phandle to a syscon node representing the APCS registers
- description: u32 representing offset to the register within the syscon
- description: u32 representing the ipc bit within the register
description:
Three entries specifying the outgoing ipc bit used for signaling the
remote end of the smp2p edge.
qcom,local-pid:
$ref: /schemas/types.yaml#/definitions/uint32
description:
The identifier of the local endpoint of this edge.
qcom,remote-pid:
$ref: /schemas/types.yaml#/definitions/uint32
description:
The identifier of the remote endpoint of this edge.
qcom,smem:
$ref: /schemas/types.yaml#/definitions/uint32-array
items:
maxItems: 2
description:
Two identifiers of the inbound and outbound smem items used for this edge.
patternProperties:
"^master-kernel|slave-kernel|ipa-ap-to-modem|ipa-modem-to-ap$":
type: object
description:
Each SMP2P pair contain a set of inbound and outbound entries, these are
described in subnodes of the smp2p device node. The node names are not
important.
properties:
interrupt-controller:
description:
Marks the entry as inbound; the node should be specified as a two
cell interrupt-controller. If not specified this node will denote
the outgoing entry.
'#interrupt-cells':
const: 2
qcom,entry-name:
$ref: /schemas/types.yaml#/definitions/string
description:
The name of this entry, for inbound entries this will be used to
match against the remotely allocated entry and for outbound entries
this name is used for allocating entries.
'#qcom,smem-state-cells':
$ref: /schemas/types.yaml#/definitions/uint32
const: 1
description:
Required for outgoing entries.
required:
- qcom,entry-name
oneOf:
- required:
- interrupt-controller
- '#interrupt-cells'
- required:
- '#qcom,smem-state-cells'
additionalProperties: false
required:
- compatible
- interrupts
- qcom,local-pid
- qcom,remote-pid
- qcom,smem
oneOf:
- required:
- mboxes
- required:
- qcom,ipc
additionalProperties: false
examples:
# The following example shows the SMP2P setup with the wireless processor,
# defined from the 8974 apps processor's point-of-view. It encompasses one
# inbound and one outbound entry.
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
shared-memory {
compatible = "qcom,smp2p";
qcom,smem = <431>, <451>;
interrupts = <GIC_SPI 143 IRQ_TYPE_EDGE_RISING>;
qcom,ipc = <&apcs 8 18>;
qcom,local-pid = <0>;
qcom,remote-pid = <4>;
wcnss_smp2p_out: master-kernel {
qcom,entry-name = "master-kernel";
#qcom,smem-state-cells = <1>;
};
wcnss_smp2p_in: slave-kernel {
qcom,entry-name = "slave-kernel";
interrupt-controller;
#interrupt-cells = <2>;
};
};

View File

@ -1,104 +0,0 @@
Qualcomm Shared Memory State Machine
The Shared Memory State Machine facilitates broadcasting of single bit state
information between the processors in a Qualcomm SoC. Each processor is
assigned 32 bits of state that can be modified. A processor can through a
matrix of bitmaps signal subscription of notifications upon changes to a
certain bit owned by a certain remote processor.
- compatible:
Usage: required
Value type: <string>
Definition: must be one of:
"qcom,smsm"
- qcom,ipc-N:
Usage: required
Value type: <prop-encoded-array>
Definition: three entries specifying the outgoing ipc bit used for
signaling the N:th remote processor
- phandle to a syscon node representing the apcs registers
- u32 representing offset to the register within the syscon
- u32 representing the ipc bit within the register
- qcom,local-host:
Usage: optional
Value type: <u32>
Definition: identifier of the local processor in the list of hosts, or
in other words specifier of the column in the subscription
matrix representing the local processor
defaults to host 0
- #address-cells:
Usage: required
Value type: <u32>
Definition: must be 1
- #size-cells:
Usage: required
Value type: <u32>
Definition: must be 0
= SUBNODES
Each processor's state bits are described by a subnode of the smsm device node.
Nodes can either be flagged as an interrupt-controller to denote a remote
processor's state bits or the local processors bits. The node names are not
important.
- reg:
Usage: required
Value type: <u32>
Definition: specifies the offset, in words, of the first bit for this
entry
- #qcom,smem-state-cells:
Usage: required for local entry
Value type: <u32>
Definition: must be 1 - denotes bit number
- interrupt-controller:
Usage: required for remote entries
Value type: <empty>
Definition: marks the entry as a interrupt-controller and the state bits
to belong to a remote processor
- #interrupt-cells:
Usage: required for remote entries
Value type: <u32>
Definition: must be 2 - denotes bit number and IRQ flags
- interrupts:
Usage: required for remote entries
Value type: <prop-encoded-array>
Definition: one entry specifying remote IRQ used by the remote processor
to signal changes of its state bits
= EXAMPLE
The following example shows the SMEM setup for controlling properties of the
wireless processor, defined from the 8974 apps processor's point-of-view. It
encompasses one outbound entry and the outgoing interrupt for the wireless
processor.
smsm {
compatible = "qcom,smsm";
#address-cells = <1>;
#size-cells = <0>;
qcom,ipc-3 = <&apcs 8 19>;
apps_smsm: apps@0 {
reg = <0>;
#qcom,smem-state-cells = <1>;
};
wcnss_smsm: wcnss@7 {
reg = <7>;
interrupts = <0 144 1>;
interrupt-controller;
#interrupt-cells = <2>;
};
};

View File

@ -0,0 +1,138 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/soc/qcom/qcom,smsm.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Shared Memory State Machine
maintainers:
- Andy Gross <agross@kernel.org>
- Bjorn Andersson <bjorn.andersson@linaro.org>
- Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
description:
The Shared Memory State Machine facilitates broadcasting of single bit state
information between the processors in a Qualcomm SoC. Each processor is
assigned 32 bits of state that can be modified. A processor can through a
matrix of bitmaps signal subscription of notifications upon changes to a
certain bit owned by a certain remote processor.
properties:
compatible:
const: qcom,smsm
'#address-cells':
const: 1
qcom,local-host:
$ref: /schemas/types.yaml#/definitions/uint32
default: 0
description:
Identifier of the local processor in the list of hosts, or in other words
specifier of the column in the subscription matrix representing the local
processor.
'#size-cells':
const: 0
patternProperties:
"^qcom,ipc-[1-4]$":
$ref: /schemas/types.yaml#/definitions/phandle-array
items:
- items:
- description: phandle to a syscon node representing the APCS registers
- description: u32 representing offset to the register within the syscon
- description: u32 representing the ipc bit within the register
description:
Three entries specifying the outgoing ipc bit used for signaling the N:th
remote processor.
"@[0-9a-f]$":
type: object
description:
Each processor's state bits are described by a subnode of the SMSM device
node. Nodes can either be flagged as an interrupt-controller to denote a
remote processor's state bits or the local processors bits. The node
names are not important.
properties:
reg:
maxItems: 1
interrupt-controller:
description:
Marks the entry as a interrupt-controller and the state bits to
belong to a remote processor.
'#interrupt-cells':
const: 2
interrupts:
maxItems: 1
description:
One entry specifying remote IRQ used by the remote processor to
signal changes of its state bits.
'#qcom,smem-state-cells':
$ref: /schemas/types.yaml#/definitions/uint32
const: 1
description:
Required for local entry. Denotes bit number.
required:
- reg
oneOf:
- required:
- '#qcom,smem-state-cells'
- required:
- interrupt-controller
- '#interrupt-cells'
- interrupts
additionalProperties: false
required:
- compatible
- '#address-cells'
- '#size-cells'
anyOf:
- required:
- qcom,ipc-1
- required:
- qcom,ipc-2
- required:
- qcom,ipc-3
- required:
- qcom,ipc-4
additionalProperties: false
examples:
# The following example shows the SMEM setup for controlling properties of
# the wireless processor, defined from the 8974 apps processor's
# point-of-view. It encompasses one outbound entry and the outgoing interrupt
# for the wireless processor.
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
shared-memory {
compatible = "qcom,smsm";
#address-cells = <1>;
#size-cells = <0>;
qcom,ipc-3 = <&apcs 8 19>;
apps_smsm: apps@0 {
reg = <0>;
#qcom,smem-state-cells = <1>;
};
wcnss_smsm: wcnss@7 {
reg = <7>;
interrupts = <GIC_SPI 144 IRQ_TYPE_EDGE_RISING>;
interrupt-controller;
#interrupt-cells = <2>;
};
};

View File

@ -1,131 +0,0 @@
Qualcomm WCNSS Binding
This binding describes the Qualcomm WCNSS hardware. It consists of control
block and a BT, WiFi and FM radio block, all using SMD as command channels.
- compatible:
Usage: required
Value type: <string>
Definition: must be: "qcom,wcnss",
- qcom,smd-channel:
Usage: required
Value type: <string>
Definition: standard SMD property specifying the SMD channel used for
communication with the WiFi firmware.
Should be "WCNSS_CTRL".
- qcom,mmio:
Usage: required
Value type: <prop-encoded-array>
Definition: reference to a node specifying the wcnss "ccu" and "dxe"
register blocks. The node must be compatible with one of
the following:
"qcom,riva",
"qcom,pronto"
- firmware-name:
Usage: optional
Value type: <string>
Definition: specifies the relative firmware image path for the WLAN NV
blob. Defaults to "wlan/prima/WCNSS_qcom_wlan_nv.bin" if
not specified.
= SUBNODES
The subnodes of the wcnss node are optional and describe the individual blocks in
the WCNSS.
== Bluetooth
The following properties are defined to the bluetooth node:
- compatible:
Usage: required
Value type: <string>
Definition: must be:
"qcom,wcnss-bt"
- local-bd-address:
Usage: optional
Value type: <u8 array>
Definition: see Documentation/devicetree/bindings/net/bluetooth.txt
== WiFi
The following properties are defined to the WiFi node:
- compatible:
Usage: required
Value type: <string>
Definition: must be one of:
"qcom,wcnss-wlan",
- interrupts:
Usage: required
Value type: <prop-encoded-array>
Definition: should specify the "rx" and "tx" interrupts
- interrupt-names:
Usage: required
Value type: <stringlist>
Definition: must contain "rx" and "tx"
- qcom,smem-state:
Usage: required
Value type: <prop-encoded-array>
Definition: should reference the tx-enable and tx-rings-empty SMEM states
- qcom,smem-state-names:
Usage: required
Value type: <stringlist>
Definition: must contain "tx-enable" and "tx-rings-empty"
= EXAMPLE
The following example represents a SMD node, with one edge representing the
"pronto" subsystem, with the wcnss device and its wcn3680 BT and WiFi blocks
described; as found on the 8974 platform.
smd {
compatible = "qcom,smd";
pronto-edge {
interrupts = <0 142 1>;
qcom,ipc = <&apcs 8 17>;
qcom,smd-edge = <6>;
wcnss {
compatible = "qcom,wcnss";
qcom,smd-channels = "WCNSS_CTRL";
#address-cells = <1>;
#size-cells = <1>;
qcom,mmio = <&pronto>;
bt {
compatible = "qcom,wcnss-bt";
/* BD address 00:11:22:33:44:55 */
local-bd-address = [ 55 44 33 22 11 00 ];
};
wlan {
compatible = "qcom,wcnss-wlan";
interrupts = <0 145 0>, <0 146 0>;
interrupt-names = "tx", "rx";
qcom,smem-state = <&apps_smsm 10>, <&apps_smsm 9>;
qcom,smem-state-names = "tx-enable", "tx-rings-empty";
};
};
};
};
soc {
pronto: pronto {
compatible = "qcom,pronto";
reg = <0xfb204000 0x2000>, <0xfb202000 0x1000>, <0xfb21b000 0x3000>;
reg-names = "ccu", "dxe", "pmu";
};
};

View File

@ -0,0 +1,137 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/soc/qcom/qcom,wcnss.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm WCNSS
maintainers:
- Andy Gross <agross@kernel.org>
- Bjorn Andersson <bjorn.andersson@linaro.org>
description:
The Qualcomm WCNSS hardware consists of control block and a BT, WiFi and FM
radio block, all using SMD as command channels.
properties:
compatible:
const: qcom,wcnss
firmware-name:
$ref: /schemas/types.yaml#/definitions/string
default: "wlan/prima/WCNSS_qcom_wlan_nv.bin"
description:
Relative firmware image path for the WLAN NV blob.
qcom,mmio:
$ref: /schemas/types.yaml#/definitions/phandle
description: |
Reference to a node specifying the wcnss "ccu" and "dxe" register blocks.
The node must be compatible with one of the following::
- qcom,riva"
- qcom,pronto"
qcom,smd-channels:
$ref: /schemas/types.yaml#/definitions/string
const: WCNSS_CTRL
description:
Standard SMD property specifying the SMD channel used for communication
with the WiFi firmware.
bluetooth:
type: object
additionalProperties: false
properties:
compatible:
const: qcom,wcnss-bt
local-bd-address:
$ref: /schemas/types.yaml#/definitions/uint8-array
maxItems: 6
description:
See Documentation/devicetree/bindings/net/bluetooth.txt
required:
- compatible
wifi:
additionalProperties: false
type: object
properties:
compatible:
const: qcom,wcnss-wlan
interrupts:
maxItems: 2
interrupt-names:
items:
- const: tx
- const: rx
qcom,smem-states:
$ref: /schemas/types.yaml#/definitions/phandle-array
maxItems: 2
description:
Should reference the tx-enable and tx-rings-empty SMEM states.
qcom,smem-state-names:
$ref: /schemas/types.yaml#/definitions/string-array
items:
- const: tx-enable
- const: tx-rings-empty
description:
Names of SMEM states.
required:
- compatible
- interrupts
- interrupt-names
- qcom,smem-states
- qcom,smem-state-names
required:
- compatible
- qcom,mmio
- qcom,smd-channels
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
smd-edge {
interrupts = <GIC_SPI 142 IRQ_TYPE_EDGE_RISING>;
qcom,ipc = <&apcs 8 17>;
qcom,smd-edge = <6>;
qcom,remote-pid = <4>;
label = "pronto";
wcnss {
compatible = "qcom,wcnss";
qcom,smd-channels = "WCNSS_CTRL";
qcom,mmio = <&pronto>;
bluetooth {
compatible = "qcom,wcnss-bt";
/* BD address 00:11:22:33:44:55 */
local-bd-address = [ 55 44 33 22 11 00 ];
};
wifi {
compatible = "qcom,wcnss-wlan";
interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "tx", "rx";
qcom,smem-states = <&apps_smsm 10>, <&apps_smsm 9>;
qcom,smem-state-names = "tx-enable", "tx-rings-empty";
};
};
};

View File

@ -1,137 +0,0 @@
RPMH RSC:
------------
Resource Power Manager Hardened (RPMH) is the mechanism for communicating with
the hardened resource accelerators on Qualcomm SoCs. Requests to the resources
can be written to the Trigger Command Set (TCS) registers and using a (addr,
val) pair and triggered. Messages in the TCS are then sent in sequence over an
internal bus.
The hardware block (Direct Resource Voter or DRV) is a part of the h/w entity
(Resource State Coordinator a.k.a RSC) that can handle multiple sleep and
active/wake resource requests. Multiple such DRVs can exist in a SoC and can
be written to from Linux. The structure of each DRV follows the same template
with a few variations that are captured by the properties here.
A TCS may be triggered from Linux or triggered by the F/W after all the CPUs
have powered off to facilitate idle power saving. TCS could be classified as -
ACTIVE /* Triggered by Linux */
SLEEP /* Triggered by F/W */
WAKE /* Triggered by F/W */
CONTROL /* Triggered by F/W */
The order in which they are described in the DT, should match the hardware
configuration.
Requests can be made for the state of a resource, when the subsystem is active
or idle. When all subsystems like Modem, GPU, CPU are idle, the resource state
will be an aggregate of the sleep votes from each of those subsystems. Clients
may request a sleep value for their shared resources in addition to the active
mode requests.
Properties:
- compatible:
Usage: required
Value type: <string>
Definition: Should be "qcom,rpmh-rsc".
- reg:
Usage: required
Value type: <prop-encoded-array>
Definition: The first register specifies the base address of the
DRV(s). The number of DRVs in the dependent on the RSC.
The tcs-offset specifies the start address of the
TCS in the DRVs.
- reg-names:
Usage: required
Value type: <string>
Definition: Maps the register specified in the reg property. Must be
"drv-0", "drv-1", "drv-2" etc and "tcs-offset". The
- interrupts:
Usage: required
Value type: <prop-encoded-interrupt>
Definition: The interrupt that trips when a message complete/response
is received for this DRV from the accelerators.
- qcom,drv-id:
Usage: required
Value type: <u32>
Definition: The id of the DRV in the RSC block that will be used by
this controller.
- qcom,tcs-config:
Usage: required
Value type: <prop-encoded-array>
Definition: The tuple defining the configuration of TCS.
Must have 2 cells which describe each TCS type.
<type number_of_tcs>.
The order of the TCS must match the hardware
configuration.
- Cell #1 (TCS Type): TCS types to be specified -
ACTIVE_TCS
SLEEP_TCS
WAKE_TCS
CONTROL_TCS
- Cell #2 (Number of TCS): <u32>
- label:
Usage: optional
Value type: <string>
Definition: Name for the RSC. The name would be used in trace logs.
Drivers that want to use the RSC to communicate with RPMH must specify their
bindings as child nodes of the RSC controllers they wish to communicate with.
Example 1:
For a TCS whose RSC base address is is 0x179C0000 and is at a DRV id of 2, the
register offsets for DRV2 start at 0D00, the register calculations are like
this -
DRV0: 0x179C0000
DRV2: 0x179C0000 + 0x10000 = 0x179D0000
DRV2: 0x179C0000 + 0x10000 * 2 = 0x179E0000
TCS-OFFSET: 0xD00
apps_rsc: rsc@179c0000 {
label = "apps_rsc";
compatible = "qcom,rpmh-rsc";
reg = <0x179c0000 0x10000>,
<0x179d0000 0x10000>,
<0x179e0000 0x10000>;
reg-names = "drv-0", "drv-1", "drv-2";
interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
qcom,tcs-offset = <0xd00>;
qcom,drv-id = <2>;
qcom,tcs-config = <ACTIVE_TCS 2>,
<SLEEP_TCS 3>,
<WAKE_TCS 3>,
<CONTROL_TCS 1>;
};
Example 2:
For a TCS whose RSC base address is 0xAF20000 and is at DRV id of 0, the
register offsets for DRV0 start at 01C00, the register calculations are like
this -
DRV0: 0xAF20000
TCS-OFFSET: 0x1C00
disp_rsc: rsc@af20000 {
label = "disp_rsc";
compatible = "qcom,rpmh-rsc";
reg = <0xaf20000 0x10000>;
reg-names = "drv-0";
interrupts = <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>;
qcom,tcs-offset = <0x1c00>;
qcom,drv-id = <0>;
qcom,tcs-config = <ACTIVE_TCS 0>,
<SLEEP_TCS 1>,
<WAKE_TCS 1>,
<CONTROL_TCS 0>;
};

View File

@ -1,39 +0,0 @@
GENI based Qualcomm Universal Peripheral (QUP) Serial Peripheral Interface (SPI)
The QUP v3 core is a GENI based AHB slave that provides a common data path
(an output FIFO and an input FIFO) for serial peripheral interface (SPI)
mini-core.
SPI in master mode supports up to 50MHz, up to four chip selects, programmable
data path from 4 bits to 32 bits and numerous protocol variants.
Required properties:
- compatible: Must contain "qcom,geni-spi".
- reg: Must contain SPI register location and length.
- interrupts: Must contain SPI controller interrupts.
- clock-names: Must contain "se".
- clocks: Serial engine core clock needed by the device.
- #address-cells: Must be <1> to define a chip select address on
the SPI bus.
- #size-cells: Must be <0>.
SPI Controller nodes must be child of GENI based Qualcomm Universal
Peripharal. Please refer GENI based QUP wrapper controller node bindings
described in Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.yaml.
SPI slave nodes must be children of the SPI master node and conform to SPI bus
binding as described in Documentation/devicetree/bindings/spi/spi-bus.txt.
Example:
spi0: spi@a84000 {
compatible = "qcom,geni-spi";
reg = <0xa84000 0x4000>;
interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
clock-names = "se";
clocks = <&clock_gcc GCC_QUPV3_WRAP0_S0_CLK>;
pinctrl-names = "default", "sleep";
pinctrl-0 = <&qup_1_spi_2_active>;
pinctrl-1 = <&qup_1_spi_2_sleep>;
#address-cells = <1>;
#size-cells = <0>;
};

View File

@ -0,0 +1,116 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/spi/qcom,spi-geni-qcom.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: GENI based Qualcomm Universal Peripheral (QUP) Serial Peripheral Interface (SPI)
maintainers:
- Andy Gross <agross@kernel.org>
- Bjorn Andersson <bjorn.andersson@linaro.org>
- Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
description:
The QUP v3 core is a GENI based AHB slave that provides a common data path
(an output FIFO and an input FIFO) for serial peripheral interface (SPI)
mini-core.
SPI in master mode supports up to 50MHz, up to four chip selects,
programmable data path from 4 bits to 32 bits and numerous protocol variants.
SPI Controller nodes must be child of GENI based Qualcomm Universal
Peripharal. Please refer GENI based QUP wrapper controller node bindings
described in Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.yaml.
allOf:
- $ref: /schemas/spi/spi-controller.yaml#
properties:
compatible:
const: qcom,geni-spi
clocks:
maxItems: 1
clock-names:
const: se
dmas:
maxItems: 2
dma-names:
items:
- const: tx
- const: rx
interconnects:
maxItems: 2
interconnect-names:
items:
- const: qup-core
- const: qup-config
interrupts:
maxItems: 1
operating-points-v2: true
power-domains:
maxItems: 1
reg:
maxItems: 1
required:
- compatible
- clocks
- clock-names
- interrupts
- reg
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,gcc-sc7180.h>
#include <dt-bindings/interconnect/qcom,sc7180.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/power/qcom-rpmpd.h>
spi@880000 {
compatible = "qcom,geni-spi";
reg = <0x00880000 0x4000>;
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP0_S0_CLK>;
pinctrl-names = "default";
pinctrl-0 = <&qup_spi0_default>;
interrupts = <GIC_SPI 601 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
power-domains = <&rpmhpd SC7180_CX>;
operating-points-v2 = <&qup_opp_table>;
interconnects = <&qup_virt MASTER_QUP_CORE_0 0 &qup_virt SLAVE_QUP_CORE_0 0>,
<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>;
interconnect-names = "qup-core", "qup-config";
};
- |
#include <dt-bindings/dma/qcom-gpi.h>
spi@884000 {
compatible = "qcom,geni-spi";
reg = <0x00884000 0x4000>;
clock-names = "se";
clocks = <&gcc GCC_QUPV3_WRAP0_S1_CLK>;
dmas = <&gpi_dma0 0 1 QCOM_GPI_SPI>,
<&gpi_dma0 1 1 QCOM_GPI_SPI>;
dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&qup_spi1_default>;
interrupts = <GIC_SPI 602 IRQ_TYPE_LEVEL_HIGH>;
spi-max-frequency = <50000000>;
#address-cells = <1>;
#size-cells = <0>;
};

View File

@ -152,6 +152,17 @@ config QCOM_EBI2
Interface 2, which can be used to connect things like NAND Flash,
SRAM, ethernet adapters, FPGAs and LCD displays.
config QCOM_SSC_BLOCK_BUS
bool "Qualcomm SSC Block Bus Init Driver"
depends on ARCH_QCOM
help
Say y here to enable support for initializing the bus that connects
the SSC block's internal bus to the cNoC (configurantion NoC) on
(some) qcom SoCs.
The SSC (Snapdragon Sensor Core) block contains a gpio controller,
i2c/spi/uart controllers, a hexagon core, and a clock controller
which provides clocks for the above.
config SUN50I_DE2_BUS
bool "Allwinner A64 DE2 Bus Driver"
default ARM64

View File

@ -25,6 +25,7 @@ obj-$(CONFIG_OMAP_INTERCONNECT) += omap_l3_smx.o omap_l3_noc.o
obj-$(CONFIG_OMAP_OCP2SCP) += omap-ocp2scp.o
obj-$(CONFIG_QCOM_EBI2) += qcom-ebi2.o
obj-$(CONFIG_QCOM_SSC_BLOCK_BUS) += qcom-ssc-block-bus.o
obj-$(CONFIG_SUN50I_DE2_BUS) += sun50i-de2.o
obj-$(CONFIG_SUNXI_RSB) += sunxi-rsb.o
obj-$(CONFIG_OF) += simple-pm-bus.o

View File

@ -0,0 +1,389 @@
// SPDX-License-Identifier: GPL-2.0-only
// Copyright (c) 2021, Michael Srba
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/pm_clock.h>
#include <linux/pm_domain.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/reset.h>
/* AXI Halt Register Offsets */
#define AXI_HALTREQ_REG 0x0
#define AXI_HALTACK_REG 0x4
#define AXI_IDLE_REG 0x8
#define SSCAON_CONFIG0_CLAMP_EN_OVRD BIT(4)
#define SSCAON_CONFIG0_CLAMP_EN_OVRD_VAL BIT(5)
static const char *const qcom_ssc_block_pd_names[] = {
"ssc_cx",
"ssc_mx"
};
struct qcom_ssc_block_bus_data {
const char *const *pd_names;
struct device *pds[ARRAY_SIZE(qcom_ssc_block_pd_names)];
char __iomem *reg_mpm_sscaon_config0;
char __iomem *reg_mpm_sscaon_config1;
struct regmap *halt_map;
struct clk *xo_clk;
struct clk *aggre2_clk;
struct clk *gcc_im_sleep_clk;
struct clk *aggre2_north_clk;
struct clk *ssc_xo_clk;
struct clk *ssc_ahbs_clk;
struct reset_control *ssc_bcr;
struct reset_control *ssc_reset;
u32 ssc_axi_halt;
int num_pds;
};
static void reg32_set_bits(char __iomem *reg, u32 value)
{
u32 tmp = ioread32(reg);
iowrite32(tmp | value, reg);
}
static void reg32_clear_bits(char __iomem *reg, u32 value)
{
u32 tmp = ioread32(reg);
iowrite32(tmp & (~value), reg);
}
static int qcom_ssc_block_bus_init(struct device *dev)
{
int ret;
struct qcom_ssc_block_bus_data *data = dev_get_drvdata(dev);
ret = clk_prepare_enable(data->xo_clk);
if (ret) {
dev_err(dev, "error enabling xo_clk: %d\n", ret);
goto err_xo_clk;
}
ret = clk_prepare_enable(data->aggre2_clk);
if (ret) {
dev_err(dev, "error enabling aggre2_clk: %d\n", ret);
goto err_aggre2_clk;
}
ret = clk_prepare_enable(data->gcc_im_sleep_clk);
if (ret) {
dev_err(dev, "error enabling gcc_im_sleep_clk: %d\n", ret);
goto err_gcc_im_sleep_clk;
}
/*
* We need to intervene here because the HW logic driving these signals cannot handle
* initialization after power collapse by itself.
*/
reg32_clear_bits(data->reg_mpm_sscaon_config0,
SSCAON_CONFIG0_CLAMP_EN_OVRD | SSCAON_CONFIG0_CLAMP_EN_OVRD_VAL);
/* override few_ack/rest_ack */
reg32_clear_bits(data->reg_mpm_sscaon_config1, BIT(31));
ret = clk_prepare_enable(data->aggre2_north_clk);
if (ret) {
dev_err(dev, "error enabling aggre2_north_clk: %d\n", ret);
goto err_aggre2_north_clk;
}
ret = reset_control_deassert(data->ssc_reset);
if (ret) {
dev_err(dev, "error deasserting ssc_reset: %d\n", ret);
goto err_ssc_reset;
}
ret = reset_control_deassert(data->ssc_bcr);
if (ret) {
dev_err(dev, "error deasserting ssc_bcr: %d\n", ret);
goto err_ssc_bcr;
}
regmap_write(data->halt_map, data->ssc_axi_halt + AXI_HALTREQ_REG, 0);
ret = clk_prepare_enable(data->ssc_xo_clk);
if (ret) {
dev_err(dev, "error deasserting ssc_xo_clk: %d\n", ret);
goto err_ssc_xo_clk;
}
ret = clk_prepare_enable(data->ssc_ahbs_clk);
if (ret) {
dev_err(dev, "error deasserting ssc_ahbs_clk: %d\n", ret);
goto err_ssc_ahbs_clk;
}
return 0;
err_ssc_ahbs_clk:
clk_disable(data->ssc_xo_clk);
err_ssc_xo_clk:
regmap_write(data->halt_map, data->ssc_axi_halt + AXI_HALTREQ_REG, 1);
reset_control_assert(data->ssc_bcr);
err_ssc_bcr:
reset_control_assert(data->ssc_reset);
err_ssc_reset:
clk_disable(data->aggre2_north_clk);
err_aggre2_north_clk:
reg32_set_bits(data->reg_mpm_sscaon_config0, BIT(4) | BIT(5));
reg32_set_bits(data->reg_mpm_sscaon_config1, BIT(31));
clk_disable(data->gcc_im_sleep_clk);
err_gcc_im_sleep_clk:
clk_disable(data->aggre2_clk);
err_aggre2_clk:
clk_disable(data->xo_clk);
err_xo_clk:
return ret;
}
static void qcom_ssc_block_bus_deinit(struct device *dev)
{
int ret;
struct qcom_ssc_block_bus_data *data = dev_get_drvdata(dev);
clk_disable(data->ssc_xo_clk);
clk_disable(data->ssc_ahbs_clk);
ret = reset_control_assert(data->ssc_bcr);
if (ret)
dev_err(dev, "error asserting ssc_bcr: %d\n", ret);
regmap_write(data->halt_map, data->ssc_axi_halt + AXI_HALTREQ_REG, 1);
reg32_set_bits(data->reg_mpm_sscaon_config1, BIT(31));
reg32_set_bits(data->reg_mpm_sscaon_config0, BIT(4) | BIT(5));
ret = reset_control_assert(data->ssc_reset);
if (ret)
dev_err(dev, "error asserting ssc_reset: %d\n", ret);
clk_disable(data->gcc_im_sleep_clk);
clk_disable(data->aggre2_north_clk);
clk_disable(data->aggre2_clk);
clk_disable(data->xo_clk);
}
static int qcom_ssc_block_bus_pds_attach(struct device *dev, struct device **pds,
const char *const *pd_names, size_t num_pds)
{
int ret;
int i;
for (i = 0; i < num_pds; i++) {
pds[i] = dev_pm_domain_attach_by_name(dev, pd_names[i]);
if (IS_ERR_OR_NULL(pds[i])) {
ret = PTR_ERR(pds[i]) ? : -ENODATA;
goto unroll_attach;
}
}
return num_pds;
unroll_attach:
for (i--; i >= 0; i--)
dev_pm_domain_detach(pds[i], false);
return ret;
};
static void qcom_ssc_block_bus_pds_detach(struct device *dev, struct device **pds, size_t num_pds)
{
int i;
for (i = 0; i < num_pds; i++)
dev_pm_domain_detach(pds[i], false);
}
static int qcom_ssc_block_bus_pds_enable(struct device **pds, size_t num_pds)
{
int ret;
int i;
for (i = 0; i < num_pds; i++) {
dev_pm_genpd_set_performance_state(pds[i], INT_MAX);
ret = pm_runtime_get_sync(pds[i]);
if (ret < 0)
goto unroll_pd_votes;
}
return 0;
unroll_pd_votes:
for (i--; i >= 0; i--) {
dev_pm_genpd_set_performance_state(pds[i], 0);
pm_runtime_put(pds[i]);
}
return ret;
};
static void qcom_ssc_block_bus_pds_disable(struct device **pds, size_t num_pds)
{
int i;
for (i = 0; i < num_pds; i++) {
dev_pm_genpd_set_performance_state(pds[i], 0);
pm_runtime_put(pds[i]);
}
}
static int qcom_ssc_block_bus_probe(struct platform_device *pdev)
{
struct qcom_ssc_block_bus_data *data;
struct device_node *np = pdev->dev.of_node;
struct of_phandle_args halt_args;
struct resource *res;
int ret;
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
platform_set_drvdata(pdev, data);
data->pd_names = qcom_ssc_block_pd_names;
data->num_pds = ARRAY_SIZE(qcom_ssc_block_pd_names);
/* power domains */
ret = qcom_ssc_block_bus_pds_attach(&pdev->dev, data->pds, data->pd_names, data->num_pds);
if (ret < 0)
return dev_err_probe(&pdev->dev, ret, "error when attaching power domains\n");
ret = qcom_ssc_block_bus_pds_enable(data->pds, data->num_pds);
if (ret < 0)
return dev_err_probe(&pdev->dev, ret, "error when enabling power domains\n");
/* low level overrides for when the HW logic doesn't "just work" */
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpm_sscaon_config0");
data->reg_mpm_sscaon_config0 = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(data->reg_mpm_sscaon_config0))
return dev_err_probe(&pdev->dev, PTR_ERR(data->reg_mpm_sscaon_config0),
"Failed to ioremap mpm_sscaon_config0\n");
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpm_sscaon_config1");
data->reg_mpm_sscaon_config1 = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(data->reg_mpm_sscaon_config1))
return dev_err_probe(&pdev->dev, PTR_ERR(data->reg_mpm_sscaon_config1),
"Failed to ioremap mpm_sscaon_config1\n");
/* resets */
data->ssc_bcr = devm_reset_control_get_exclusive(&pdev->dev, "ssc_bcr");
if (IS_ERR(data->ssc_bcr))
return dev_err_probe(&pdev->dev, PTR_ERR(data->ssc_bcr),
"Failed to acquire reset: scc_bcr\n");
data->ssc_reset = devm_reset_control_get_exclusive(&pdev->dev, "ssc_reset");
if (IS_ERR(data->ssc_reset))
return dev_err_probe(&pdev->dev, PTR_ERR(data->ssc_reset),
"Failed to acquire reset: ssc_reset:\n");
/* clocks */
data->xo_clk = devm_clk_get(&pdev->dev, "xo");
if (IS_ERR(data->xo_clk))
return dev_err_probe(&pdev->dev, PTR_ERR(data->xo_clk),
"Failed to get clock: xo\n");
data->aggre2_clk = devm_clk_get(&pdev->dev, "aggre2");
if (IS_ERR(data->aggre2_clk))
return dev_err_probe(&pdev->dev, PTR_ERR(data->aggre2_clk),
"Failed to get clock: aggre2\n");
data->gcc_im_sleep_clk = devm_clk_get(&pdev->dev, "gcc_im_sleep");
if (IS_ERR(data->gcc_im_sleep_clk))
return dev_err_probe(&pdev->dev, PTR_ERR(data->gcc_im_sleep_clk),
"Failed to get clock: gcc_im_sleep\n");
data->aggre2_north_clk = devm_clk_get(&pdev->dev, "aggre2_north");
if (IS_ERR(data->aggre2_north_clk))
return dev_err_probe(&pdev->dev, PTR_ERR(data->aggre2_north_clk),
"Failed to get clock: aggre2_north\n");
data->ssc_xo_clk = devm_clk_get(&pdev->dev, "ssc_xo");
if (IS_ERR(data->ssc_xo_clk))
return dev_err_probe(&pdev->dev, PTR_ERR(data->ssc_xo_clk),
"Failed to get clock: ssc_xo\n");
data->ssc_ahbs_clk = devm_clk_get(&pdev->dev, "ssc_ahbs");
if (IS_ERR(data->ssc_ahbs_clk))
return dev_err_probe(&pdev->dev, PTR_ERR(data->ssc_ahbs_clk),
"Failed to get clock: ssc_ahbs\n");
ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node, "qcom,halt-regs", 1, 0,
&halt_args);
if (ret < 0)
return dev_err_probe(&pdev->dev, ret, "Failed to parse qcom,halt-regs\n");
data->halt_map = syscon_node_to_regmap(halt_args.np);
of_node_put(halt_args.np);
if (IS_ERR(data->halt_map))
return PTR_ERR(data->halt_map);
data->ssc_axi_halt = halt_args.args[0];
qcom_ssc_block_bus_init(&pdev->dev);
of_platform_populate(np, NULL, NULL, &pdev->dev);
return 0;
}
static int qcom_ssc_block_bus_remove(struct platform_device *pdev)
{
struct qcom_ssc_block_bus_data *data = platform_get_drvdata(pdev);
qcom_ssc_block_bus_deinit(&pdev->dev);
iounmap(data->reg_mpm_sscaon_config0);
iounmap(data->reg_mpm_sscaon_config1);
qcom_ssc_block_bus_pds_disable(data->pds, data->num_pds);
qcom_ssc_block_bus_pds_detach(&pdev->dev, data->pds, data->num_pds);
pm_runtime_disable(&pdev->dev);
pm_clk_destroy(&pdev->dev);
return 0;
}
static const struct of_device_id qcom_ssc_block_bus_of_match[] = {
{ .compatible = "qcom,ssc-block-bus", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, qcom_ssc_block_bus_of_match);
static struct platform_driver qcom_ssc_block_bus_driver = {
.probe = qcom_ssc_block_bus_probe,
.remove = qcom_ssc_block_bus_remove,
.driver = {
.name = "qcom-ssc-block-bus",
.of_match_table = qcom_ssc_block_bus_of_match,
},
};
module_platform_driver(qcom_ssc_block_bus_driver);
MODULE_DESCRIPTION("A driver for handling the init sequence needed for accessing the SSC block on (some) qcom SoCs over AHB");
MODULE_AUTHOR("Michael Srba <Michael.Srba@seznam.cz>");
MODULE_LICENSE("GPL v2");

View File

@ -1379,6 +1379,10 @@ static const struct of_device_id qcom_scm_dt_match[] = {
SCM_HAS_IFACE_CLK |
SCM_HAS_BUS_CLK)
},
{ .compatible = "qcom,scm-msm8976", .data = (void *)(SCM_HAS_CORE_CLK |
SCM_HAS_IFACE_CLK |
SCM_HAS_BUS_CLK)
},
{ .compatible = "qcom,scm-msm8994" },
{ .compatible = "qcom,scm-msm8996" },
{ .compatible = "qcom,scm" },

View File

@ -130,6 +130,50 @@ static const struct llcc_slice_config sc7280_data[] = {
{ LLCC_MODPE, 29, 64, 1, 1, 0x3f, 0x0, 0, 0, 0, 1, 0, 0},
};
static const struct llcc_slice_config sc8180x_data[] = {
{ LLCC_CPUSS, 1, 6144, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 1 },
{ LLCC_VIDSC0, 2, 512, 2, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 },
{ LLCC_VIDSC1, 3, 512, 2, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 },
{ LLCC_AUDIO, 6, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 },
{ LLCC_MDMHPGRW, 7, 3072, 1, 1, 0x3ff, 0xc00, 0, 0, 0, 1, 0 },
{ LLCC_MDM, 8, 3072, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 },
{ LLCC_MODHW, 9, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 },
{ LLCC_CMPT, 10, 6144, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 },
{ LLCC_GPUHTW, 11, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 },
{ LLCC_GPU, 12, 5120, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 },
{ LLCC_MMUHWT, 13, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 1 },
{ LLCC_CMPTDMA, 15, 6144, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 },
{ LLCC_DISP, 16, 6144, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 },
{ LLCC_VIDFW, 17, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 },
{ LLCC_MDMHPFX, 20, 1024, 2, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 },
{ LLCC_MDMPNG, 21, 1024, 0, 1, 0xc, 0x0, 0, 0, 0, 1, 0 },
{ LLCC_AUDHW, 22, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 },
{ LLCC_NPU, 23, 6144, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 },
{ LLCC_WLHW, 24, 6144, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0 },
{ LLCC_MODPE, 29, 512, 1, 1, 0xc, 0x0, 0, 0, 0, 1, 0 },
{ LLCC_APTCM, 30, 512, 3, 1, 0x0, 0x1, 1, 0, 0, 1, 0 },
{ LLCC_WRCACHE, 31, 128, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 0 },
};
static const struct llcc_slice_config sc8280xp_data[] = {
{ LLCC_CPUSS, 1, 6144, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 1, 0 },
{ LLCC_VIDSC0, 2, 512, 3, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 },
{ LLCC_AUDIO, 6, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 0, 0 },
{ LLCC_CMPT, 10, 6144, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 0, 0 },
{ LLCC_GPUHTW, 11, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 },
{ LLCC_GPU, 12, 4096, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 1 },
{ LLCC_MMUHWT, 13, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 },
{ LLCC_DISP, 16, 6144, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 },
{ LLCC_AUDHW, 22, 2048, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 },
{ LLCC_DRE, 26, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 },
{ LLCC_CVP, 28, 512, 3, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 },
{ LLCC_APTCM, 30, 1024, 3, 1, 0x0, 0x1, 1, 0, 0, 1, 0, 0 },
{ LLCC_WRCACHE, 31, 1024, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 },
{ LLCC_CVPFW, 32, 512, 1, 0, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 },
{ LLCC_CPUSS1, 33, 2048, 1, 1, 0xfff, 0x0, 0, 0, 0, 1, 0, 0 },
{ LLCC_CPUHWT, 36, 512, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 1, 0 },
};
static const struct llcc_slice_config sdm845_data[] = {
{ LLCC_CPUSS, 1, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 1 },
{ LLCC_VIDSC0, 2, 512, 2, 1, 0x0, 0x0f0, 0, 0, 1, 1, 0 },
@ -276,6 +320,20 @@ static const struct qcom_llcc_config sc7280_cfg = {
.reg_offset = llcc_v1_2_reg_offset,
};
static const struct qcom_llcc_config sc8180x_cfg = {
.sct_data = sc8180x_data,
.size = ARRAY_SIZE(sc8180x_data),
.need_llcc_cfg = true,
.reg_offset = llcc_v1_2_reg_offset,
};
static const struct qcom_llcc_config sc8280xp_cfg = {
.sct_data = sc8280xp_data,
.size = ARRAY_SIZE(sc8280xp_data),
.need_llcc_cfg = true,
.reg_offset = llcc_v1_2_reg_offset,
};
static const struct qcom_llcc_config sdm845_cfg = {
.sct_data = sdm845_data,
.size = ARRAY_SIZE(sdm845_data),
@ -741,6 +799,8 @@ static int qcom_llcc_probe(struct platform_device *pdev)
static const struct of_device_id qcom_llcc_of_match[] = {
{ .compatible = "qcom,sc7180-llcc", .data = &sc7180_cfg },
{ .compatible = "qcom,sc7280-llcc", .data = &sc7280_cfg },
{ .compatible = "qcom,sc8180x-llcc", .data = &sc8180x_cfg },
{ .compatible = "qcom,sc8280xp-llcc", .data = &sc8280xp_cfg },
{ .compatible = "qcom,sdm845-llcc", .data = &sdm845_cfg },
{ .compatible = "qcom,sm6350-llcc", .data = &sm6350_cfg },
{ .compatible = "qcom,sm8150-llcc", .data = &sm8150_cfg },
@ -749,6 +809,7 @@ static const struct of_device_id qcom_llcc_of_match[] = {
{ .compatible = "qcom,sm8450-llcc", .data = &sm8450_cfg },
{ }
};
MODULE_DEVICE_TABLE(of, qcom_llcc_of_match);
static struct platform_driver qcom_llcc_driver = {
.driver = {

View File

@ -304,24 +304,23 @@ static void pdr_indication_cb(struct qmi_handle *qmi,
notifier_hdl);
const struct servreg_state_updated_ind *ind_msg = data;
struct pdr_list_node *ind;
struct pdr_service *pds;
bool found = false;
struct pdr_service *pds = NULL, *iter;
if (!ind_msg || !ind_msg->service_path[0] ||
strlen(ind_msg->service_path) > SERVREG_NAME_LENGTH)
return;
mutex_lock(&pdr->list_lock);
list_for_each_entry(pds, &pdr->lookups, node) {
if (strcmp(pds->service_path, ind_msg->service_path))
list_for_each_entry(iter, &pdr->lookups, node) {
if (strcmp(iter->service_path, ind_msg->service_path))
continue;
found = true;
pds = iter;
break;
}
mutex_unlock(&pdr->list_lock);
if (!found)
if (!pds)
return;
pr_info("PDR: Indication received from %s, state: 0x%x, trans-id: %d\n",

View File

@ -28,7 +28,7 @@ struct servreg_location_entry {
u32 instance;
};
struct qmi_elem_info servreg_location_entry_ei[] = {
static struct qmi_elem_info servreg_location_entry_ei[] = {
{
.data_type = QMI_STRING,
.elem_len = SERVREG_NAME_LENGTH + 1,
@ -74,7 +74,7 @@ struct servreg_get_domain_list_req {
u32 domain_offset;
};
struct qmi_elem_info servreg_get_domain_list_req_ei[] = {
static struct qmi_elem_info servreg_get_domain_list_req_ei[] = {
{
.data_type = QMI_STRING,
.elem_len = SERVREG_NAME_LENGTH + 1,
@ -116,7 +116,7 @@ struct servreg_get_domain_list_resp {
struct servreg_location_entry domain_list[SERVREG_DOMAIN_LIST_LENGTH];
};
struct qmi_elem_info servreg_get_domain_list_resp_ei[] = {
static struct qmi_elem_info servreg_get_domain_list_resp_ei[] = {
{
.data_type = QMI_STRUCT,
.elem_len = 1,
@ -199,7 +199,7 @@ struct servreg_register_listener_req {
char service_path[SERVREG_NAME_LENGTH + 1];
};
struct qmi_elem_info servreg_register_listener_req_ei[] = {
static struct qmi_elem_info servreg_register_listener_req_ei[] = {
{
.data_type = QMI_UNSIGNED_1_BYTE,
.elem_len = 1,
@ -227,7 +227,7 @@ struct servreg_register_listener_resp {
enum servreg_service_state curr_state;
};
struct qmi_elem_info servreg_register_listener_resp_ei[] = {
static struct qmi_elem_info servreg_register_listener_resp_ei[] = {
{
.data_type = QMI_STRUCT,
.elem_len = 1,
@ -263,7 +263,7 @@ struct servreg_restart_pd_req {
char service_path[SERVREG_NAME_LENGTH + 1];
};
struct qmi_elem_info servreg_restart_pd_req_ei[] = {
static struct qmi_elem_info servreg_restart_pd_req_ei[] = {
{
.data_type = QMI_STRING,
.elem_len = SERVREG_NAME_LENGTH + 1,
@ -280,7 +280,7 @@ struct servreg_restart_pd_resp {
struct qmi_response_type_v01 resp;
};
struct qmi_elem_info servreg_restart_pd_resp_ei[] = {
static struct qmi_elem_info servreg_restart_pd_resp_ei[] = {
{
.data_type = QMI_STRUCT,
.elem_len = 1,
@ -300,7 +300,7 @@ struct servreg_state_updated_ind {
u16 transaction_id;
};
struct qmi_elem_info servreg_state_updated_ind_ei[] = {
static struct qmi_elem_info servreg_state_updated_ind_ei[] = {
{
.data_type = QMI_SIGNED_4_BYTE_ENUM,
.elem_len = 1,
@ -336,7 +336,7 @@ struct servreg_set_ack_req {
u16 transaction_id;
};
struct qmi_elem_info servreg_set_ack_req_ei[] = {
static struct qmi_elem_info servreg_set_ack_req_ei[] = {
{
.data_type = QMI_STRING,
.elem_len = SERVREG_NAME_LENGTH + 1,
@ -362,7 +362,7 @@ struct servreg_set_ack_resp {
struct qmi_response_type_v01 resp;
};
struct qmi_elem_info servreg_set_ack_resp_ei[] = {
static struct qmi_elem_info servreg_set_ack_resp_ei[] = {
{
.data_type = QMI_STRUCT,
.elem_len = 1,

View File

@ -180,6 +180,36 @@ static struct rpmhpd mxc_ao = {
.res_name = "mxc.lvl",
};
static struct rpmhpd nsp = {
.pd = { .name = "nsp", },
.res_name = "nsp.lvl",
};
static struct rpmhpd qphy = {
.pd = { .name = "qphy", },
.res_name = "qphy.lvl",
};
/* SA8540P RPMH powerdomains */
static struct rpmhpd *sa8540p_rpmhpds[] = {
[SC8280XP_CX] = &cx,
[SC8280XP_CX_AO] = &cx_ao,
[SC8280XP_EBI] = &ebi,
[SC8280XP_GFX] = &gfx,
[SC8280XP_LCX] = &lcx,
[SC8280XP_LMX] = &lmx,
[SC8280XP_MMCX] = &mmcx,
[SC8280XP_MMCX_AO] = &mmcx_ao,
[SC8280XP_MX] = &mx,
[SC8280XP_MX_AO] = &mx_ao,
[SC8280XP_NSP] = &nsp,
};
static const struct rpmhpd_desc sa8540p_desc = {
.rpmhpds = sa8540p_rpmhpds,
.num_pds = ARRAY_SIZE(sa8540p_rpmhpds),
};
/* SDM845 RPMH powerdomains */
static struct rpmhpd *sdm845_rpmhpds[] = {
[SDM845_CX] = &cx_w_mx_parent,
@ -210,6 +240,21 @@ static const struct rpmhpd_desc sdx55_desc = {
.num_pds = ARRAY_SIZE(sdx55_rpmhpds),
};
/* SDX65 RPMH powerdomains */
static struct rpmhpd *sdx65_rpmhpds[] = {
[SDX65_CX] = &cx_w_mx_parent,
[SDX65_CX_AO] = &cx_ao_w_mx_parent,
[SDX65_MSS] = &mss,
[SDX65_MX] = &mx,
[SDX65_MX_AO] = &mx_ao,
[SDX65_MXC] = &mxc,
};
static const struct rpmhpd_desc sdx65_desc = {
.rpmhpds = sdx65_rpmhpds,
.num_pds = ARRAY_SIZE(sdx65_rpmhpds),
};
/* SM6350 RPMH powerdomains */
static struct rpmhpd *sm6350_rpmhpds[] = {
[SM6350_CX] = &cx_w_mx_parent,
@ -363,12 +408,36 @@ static const struct rpmhpd_desc sc8180x_desc = {
.num_pds = ARRAY_SIZE(sc8180x_rpmhpds),
};
/* SC8280xp RPMH powerdomains */
static struct rpmhpd *sc8280xp_rpmhpds[] = {
[SC8280XP_CX] = &cx,
[SC8280XP_CX_AO] = &cx_ao,
[SC8280XP_EBI] = &ebi,
[SC8280XP_GFX] = &gfx,
[SC8280XP_LCX] = &lcx,
[SC8280XP_LMX] = &lmx,
[SC8280XP_MMCX] = &mmcx,
[SC8280XP_MMCX_AO] = &mmcx_ao,
[SC8280XP_MX] = &mx,
[SC8280XP_MX_AO] = &mx_ao,
[SC8280XP_NSP] = &nsp,
[SC8280XP_QPHY] = &qphy,
};
static const struct rpmhpd_desc sc8280xp_desc = {
.rpmhpds = sc8280xp_rpmhpds,
.num_pds = ARRAY_SIZE(sc8280xp_rpmhpds),
};
static const struct of_device_id rpmhpd_match_table[] = {
{ .compatible = "qcom,sa8540p-rpmhpd", .data = &sa8540p_desc },
{ .compatible = "qcom,sc7180-rpmhpd", .data = &sc7180_desc },
{ .compatible = "qcom,sc7280-rpmhpd", .data = &sc7280_desc },
{ .compatible = "qcom,sc8180x-rpmhpd", .data = &sc8180x_desc },
{ .compatible = "qcom,sc8280xp-rpmhpd", .data = &sc8280xp_desc },
{ .compatible = "qcom,sdm845-rpmhpd", .data = &sdm845_desc },
{ .compatible = "qcom,sdx55-rpmhpd", .data = &sdx55_desc},
{ .compatible = "qcom,sdx65-rpmhpd", .data = &sdx65_desc},
{ .compatible = "qcom,sm6350-rpmhpd", .data = &sm6350_desc },
{ .compatible = "qcom,sm8150-rpmhpd", .data = &sm8150_desc },
{ .compatible = "qcom,sm8250-rpmhpd", .data = &sm8250_desc },
@ -597,10 +666,8 @@ static int rpmhpd_probe(struct platform_device *pdev)
data->num_domains = num_pds;
for (i = 0; i < num_pds; i++) {
if (!rpmhpds[i]) {
dev_warn(dev, "rpmhpds[%d] is empty\n", i);
if (!rpmhpds[i])
continue;
}
rpmhpds[i]->dev = dev;
rpmhpds[i]->addr = cmd_db_read_addr(rpmhpds[i]->res_name);

View File

@ -195,6 +195,20 @@ struct smem_partition_header {
__le32 reserved[3];
};
/**
* struct smem_partition - describes smem partition
* @virt_base: starting virtual address of partition
* @phys_base: starting physical address of partition
* @cacheline: alignment for "cached" entries
* @size: size of partition
*/
struct smem_partition {
void __iomem *virt_base;
phys_addr_t phys_base;
size_t cacheline;
size_t size;
};
static const u8 SMEM_PART_MAGIC[] = { 0x24, 0x50, 0x52, 0x54 };
/**
@ -250,11 +264,9 @@ struct smem_region {
* struct qcom_smem - device data for the smem device
* @dev: device pointer
* @hwlock: reference to a hwspinlock
* @global_partition: pointer to global partition when in use
* @global_cacheline: cacheline size for global partition
* @partitions: list of pointers to partitions affecting the current
* processor/host
* @cacheline: list of cacheline sizes for each host
* @ptable: virtual base of partition table
* @global_partition: describes for global partition when in use
* @partitions: list of partitions of current processor/host
* @item_count: max accepted item number
* @socinfo: platform device pointer
* @num_regions: number of @regions
@ -265,12 +277,11 @@ struct qcom_smem {
struct hwspinlock *hwlock;
struct smem_partition_header *global_partition;
size_t global_cacheline;
struct smem_partition_header *partitions[SMEM_HOST_COUNT];
size_t cacheline[SMEM_HOST_COUNT];
u32 item_count;
struct platform_device *socinfo;
struct smem_ptable *ptable;
struct smem_partition global_partition;
struct smem_partition partitions[SMEM_HOST_COUNT];
unsigned num_regions;
struct smem_region regions[];
@ -348,18 +359,26 @@ static struct qcom_smem *__smem;
#define HWSPINLOCK_TIMEOUT 1000
static int qcom_smem_alloc_private(struct qcom_smem *smem,
struct smem_partition_header *phdr,
struct smem_partition *part,
unsigned item,
size_t size)
{
struct smem_private_entry *hdr, *end;
struct smem_partition_header *phdr;
size_t alloc_size;
void *cached;
void *p_end;
phdr = (struct smem_partition_header __force *)part->virt_base;
p_end = (void *)phdr + part->size;
hdr = phdr_to_first_uncached_entry(phdr);
end = phdr_to_last_uncached_entry(phdr);
cached = phdr_to_last_cached_entry(phdr);
if (WARN_ON((void *)end > p_end || cached > p_end))
return -EINVAL;
while (hdr < end) {
if (hdr->canary != SMEM_PRIVATE_CANARY)
goto bad_canary;
@ -369,6 +388,9 @@ static int qcom_smem_alloc_private(struct qcom_smem *smem,
hdr = uncached_entry_next(hdr);
}
if (WARN_ON((void *)hdr > p_end))
return -EINVAL;
/* Check that we don't grow into the cached region */
alloc_size = sizeof(*hdr) + ALIGN(size, 8);
if ((void *)hdr + alloc_size > cached) {
@ -442,7 +464,7 @@ static int qcom_smem_alloc_global(struct qcom_smem *smem,
*/
int qcom_smem_alloc(unsigned host, unsigned item, size_t size)
{
struct smem_partition_header *phdr;
struct smem_partition *part;
unsigned long flags;
int ret;
@ -464,12 +486,12 @@ int qcom_smem_alloc(unsigned host, unsigned item, size_t size)
if (ret)
return ret;
if (host < SMEM_HOST_COUNT && __smem->partitions[host]) {
phdr = __smem->partitions[host];
ret = qcom_smem_alloc_private(__smem, phdr, item, size);
} else if (__smem->global_partition) {
phdr = __smem->global_partition;
ret = qcom_smem_alloc_private(__smem, phdr, item, size);
if (host < SMEM_HOST_COUNT && __smem->partitions[host].virt_base) {
part = &__smem->partitions[host];
ret = qcom_smem_alloc_private(__smem, part, item, size);
} else if (__smem->global_partition.virt_base) {
part = &__smem->global_partition;
ret = qcom_smem_alloc_private(__smem, part, item, size);
} else {
ret = qcom_smem_alloc_global(__smem, item, size);
}
@ -487,6 +509,8 @@ static void *qcom_smem_get_global(struct qcom_smem *smem,
struct smem_header *header;
struct smem_region *region;
struct smem_global_entry *entry;
u64 entry_offset;
u32 e_size;
u32 aux_base;
unsigned i;
@ -501,9 +525,16 @@ static void *qcom_smem_get_global(struct qcom_smem *smem,
region = &smem->regions[i];
if ((u32)region->aux_base == aux_base || !aux_base) {
e_size = le32_to_cpu(entry->size);
entry_offset = le32_to_cpu(entry->offset);
if (WARN_ON(e_size + entry_offset > region->size))
return ERR_PTR(-EINVAL);
if (size != NULL)
*size = le32_to_cpu(entry->size);
return region->virt_base + le32_to_cpu(entry->offset);
*size = e_size;
return region->virt_base + entry_offset;
}
}
@ -511,12 +542,18 @@ static void *qcom_smem_get_global(struct qcom_smem *smem,
}
static void *qcom_smem_get_private(struct qcom_smem *smem,
struct smem_partition_header *phdr,
size_t cacheline,
struct smem_partition *part,
unsigned item,
size_t *size)
{
struct smem_private_entry *e, *end;
struct smem_partition_header *phdr;
void *item_ptr, *p_end;
u32 padding_data;
u32 e_size;
phdr = (struct smem_partition_header __force *)part->virt_base;
p_end = (void *)phdr + part->size;
e = phdr_to_first_uncached_entry(phdr);
end = phdr_to_last_uncached_entry(phdr);
@ -526,36 +563,65 @@ static void *qcom_smem_get_private(struct qcom_smem *smem,
goto invalid_canary;
if (le16_to_cpu(e->item) == item) {
if (size != NULL)
*size = le32_to_cpu(e->size) -
le16_to_cpu(e->padding_data);
if (size != NULL) {
e_size = le32_to_cpu(e->size);
padding_data = le16_to_cpu(e->padding_data);
return uncached_entry_to_item(e);
if (WARN_ON(e_size > part->size || padding_data > e_size))
return ERR_PTR(-EINVAL);
*size = e_size - padding_data;
}
item_ptr = uncached_entry_to_item(e);
if (WARN_ON(item_ptr > p_end))
return ERR_PTR(-EINVAL);
return item_ptr;
}
e = uncached_entry_next(e);
}
if (WARN_ON((void *)e > p_end))
return ERR_PTR(-EINVAL);
/* Item was not found in the uncached list, search the cached list */
e = phdr_to_first_cached_entry(phdr, cacheline);
e = phdr_to_first_cached_entry(phdr, part->cacheline);
end = phdr_to_last_cached_entry(phdr);
if (WARN_ON((void *)e < (void *)phdr || (void *)end > p_end))
return ERR_PTR(-EINVAL);
while (e > end) {
if (e->canary != SMEM_PRIVATE_CANARY)
goto invalid_canary;
if (le16_to_cpu(e->item) == item) {
if (size != NULL)
*size = le32_to_cpu(e->size) -
le16_to_cpu(e->padding_data);
if (size != NULL) {
e_size = le32_to_cpu(e->size);
padding_data = le16_to_cpu(e->padding_data);
return cached_entry_to_item(e);
if (WARN_ON(e_size > part->size || padding_data > e_size))
return ERR_PTR(-EINVAL);
*size = e_size - padding_data;
}
item_ptr = cached_entry_to_item(e);
if (WARN_ON(item_ptr < (void *)phdr))
return ERR_PTR(-EINVAL);
return item_ptr;
}
e = cached_entry_next(e, cacheline);
e = cached_entry_next(e, part->cacheline);
}
if (WARN_ON((void *)e < (void *)phdr))
return ERR_PTR(-EINVAL);
return ERR_PTR(-ENOENT);
invalid_canary:
@ -576,9 +642,8 @@ static void *qcom_smem_get_private(struct qcom_smem *smem,
*/
void *qcom_smem_get(unsigned host, unsigned item, size_t *size)
{
struct smem_partition_header *phdr;
struct smem_partition *part;
unsigned long flags;
size_t cacheln;
int ret;
void *ptr = ERR_PTR(-EPROBE_DEFER);
@ -594,14 +659,12 @@ void *qcom_smem_get(unsigned host, unsigned item, size_t *size)
if (ret)
return ERR_PTR(ret);
if (host < SMEM_HOST_COUNT && __smem->partitions[host]) {
phdr = __smem->partitions[host];
cacheln = __smem->cacheline[host];
ptr = qcom_smem_get_private(__smem, phdr, cacheln, item, size);
} else if (__smem->global_partition) {
phdr = __smem->global_partition;
cacheln = __smem->global_cacheline;
ptr = qcom_smem_get_private(__smem, phdr, cacheln, item, size);
if (host < SMEM_HOST_COUNT && __smem->partitions[host].virt_base) {
part = &__smem->partitions[host];
ptr = qcom_smem_get_private(__smem, part, item, size);
} else if (__smem->global_partition.virt_base) {
part = &__smem->global_partition;
ptr = qcom_smem_get_private(__smem, part, item, size);
} else {
ptr = qcom_smem_get_global(__smem, item, size);
}
@ -622,6 +685,7 @@ EXPORT_SYMBOL(qcom_smem_get);
*/
int qcom_smem_get_free_space(unsigned host)
{
struct smem_partition *part;
struct smem_partition_header *phdr;
struct smem_header *header;
unsigned ret;
@ -629,23 +693,39 @@ int qcom_smem_get_free_space(unsigned host)
if (!__smem)
return -EPROBE_DEFER;
if (host < SMEM_HOST_COUNT && __smem->partitions[host]) {
phdr = __smem->partitions[host];
if (host < SMEM_HOST_COUNT && __smem->partitions[host].virt_base) {
part = &__smem->partitions[host];
phdr = part->virt_base;
ret = le32_to_cpu(phdr->offset_free_cached) -
le32_to_cpu(phdr->offset_free_uncached);
} else if (__smem->global_partition) {
phdr = __smem->global_partition;
if (ret > le32_to_cpu(part->size))
return -EINVAL;
} else if (__smem->global_partition.virt_base) {
part = &__smem->global_partition;
phdr = part->virt_base;
ret = le32_to_cpu(phdr->offset_free_cached) -
le32_to_cpu(phdr->offset_free_uncached);
if (ret > le32_to_cpu(part->size))
return -EINVAL;
} else {
header = __smem->regions[0].virt_base;
ret = le32_to_cpu(header->available);
if (ret > __smem->regions[0].size)
return -EINVAL;
}
return ret;
}
EXPORT_SYMBOL(qcom_smem_get_free_space);
static bool addr_in_range(void __iomem *base, size_t size, void *addr)
{
return base && (addr >= base && addr < base + size);
}
/**
* qcom_smem_virt_to_phys() - return the physical address associated
* with an smem item pointer (previously returned by qcom_smem_get()
@ -655,17 +735,36 @@ EXPORT_SYMBOL(qcom_smem_get_free_space);
*/
phys_addr_t qcom_smem_virt_to_phys(void *p)
{
unsigned i;
struct smem_partition *part;
struct smem_region *area;
u64 offset;
u32 i;
for (i = 0; i < SMEM_HOST_COUNT; i++) {
part = &__smem->partitions[i];
if (addr_in_range(part->virt_base, part->size, p)) {
offset = p - part->virt_base;
return (phys_addr_t)part->phys_base + offset;
}
}
part = &__smem->global_partition;
if (addr_in_range(part->virt_base, part->size, p)) {
offset = p - part->virt_base;
return (phys_addr_t)part->phys_base + offset;
}
for (i = 0; i < __smem->num_regions; i++) {
struct smem_region *region = &__smem->regions[i];
area = &__smem->regions[i];
if (p < region->virt_base)
continue;
if (p < region->virt_base + region->size) {
u64 offset = p - region->virt_base;
if (addr_in_range(area->virt_base, area->size, p)) {
offset = p - area->virt_base;
return region->aux_base + offset;
return (phys_addr_t)area->aux_base + offset;
}
}
@ -689,7 +788,7 @@ static struct smem_ptable *qcom_smem_get_ptable(struct qcom_smem *smem)
struct smem_ptable *ptable;
u32 version;
ptable = smem->regions[0].virt_base + smem->regions[0].size - SZ_4K;
ptable = smem->ptable;
if (memcmp(ptable->magic, SMEM_PTABLE_MAGIC, sizeof(ptable->magic)))
return ERR_PTR(-ENOENT);
@ -728,9 +827,14 @@ qcom_smem_partition_header(struct qcom_smem *smem,
struct smem_ptable_entry *entry, u16 host0, u16 host1)
{
struct smem_partition_header *header;
u32 phys_addr;
u32 size;
header = smem->regions[0].virt_base + le32_to_cpu(entry->offset);
phys_addr = smem->regions[0].aux_base + le32_to_cpu(entry->offset);
header = devm_ioremap_wc(smem->dev, phys_addr, le32_to_cpu(entry->size));
if (!header)
return NULL;
if (memcmp(header->magic, SMEM_PART_MAGIC, sizeof(header->magic))) {
dev_err(smem->dev, "bad partition magic %4ph\n", header->magic);
@ -772,7 +876,7 @@ static int qcom_smem_set_global_partition(struct qcom_smem *smem)
bool found = false;
int i;
if (smem->global_partition) {
if (smem->global_partition.virt_base) {
dev_err(smem->dev, "Already found the global partition\n");
return -EINVAL;
}
@ -807,8 +911,11 @@ static int qcom_smem_set_global_partition(struct qcom_smem *smem)
if (!header)
return -EINVAL;
smem->global_partition = header;
smem->global_cacheline = le32_to_cpu(entry->cacheline);
smem->global_partition.virt_base = (void __iomem *)header;
smem->global_partition.phys_base = smem->regions[0].aux_base +
le32_to_cpu(entry->offset);
smem->global_partition.size = le32_to_cpu(entry->size);
smem->global_partition.cacheline = le32_to_cpu(entry->cacheline);
return 0;
}
@ -848,7 +955,7 @@ qcom_smem_enumerate_partitions(struct qcom_smem *smem, u16 local_host)
return -EINVAL;
}
if (smem->partitions[remote_host]) {
if (smem->partitions[remote_host].virt_base) {
dev_err(smem->dev, "duplicate host %hu\n", remote_host);
return -EINVAL;
}
@ -857,13 +964,47 @@ qcom_smem_enumerate_partitions(struct qcom_smem *smem, u16 local_host)
if (!header)
return -EINVAL;
smem->partitions[remote_host] = header;
smem->cacheline[remote_host] = le32_to_cpu(entry->cacheline);
smem->partitions[remote_host].virt_base = (void __iomem *)header;
smem->partitions[remote_host].phys_base = smem->regions[0].aux_base +
le32_to_cpu(entry->offset);
smem->partitions[remote_host].size = le32_to_cpu(entry->size);
smem->partitions[remote_host].cacheline = le32_to_cpu(entry->cacheline);
}
return 0;
}
static int qcom_smem_map_toc(struct qcom_smem *smem, struct smem_region *region)
{
u32 ptable_start;
/* map starting 4K for smem header */
region->virt_base = devm_ioremap_wc(smem->dev, region->aux_base, SZ_4K);
ptable_start = region->aux_base + region->size - SZ_4K;
/* map last 4k for toc */
smem->ptable = devm_ioremap_wc(smem->dev, ptable_start, SZ_4K);
if (!region->virt_base || !smem->ptable)
return -ENOMEM;
return 0;
}
static int qcom_smem_map_global(struct qcom_smem *smem, u32 size)
{
u32 phys_addr;
phys_addr = smem->regions[0].aux_base;
smem->regions[0].size = size;
smem->regions[0].virt_base = devm_ioremap_wc(smem->dev, phys_addr, size);
if (!smem->regions[0].virt_base)
return -ENOMEM;
return 0;
}
static int qcom_smem_resolve_mem(struct qcom_smem *smem, const char *name,
struct smem_region *region)
{
@ -894,10 +1035,12 @@ static int qcom_smem_probe(struct platform_device *pdev)
struct smem_header *header;
struct reserved_mem *rmem;
struct qcom_smem *smem;
unsigned long flags;
size_t array_size;
int num_regions;
int hwlock_id;
u32 version;
u32 size;
int ret;
int i;
@ -933,7 +1076,12 @@ static int qcom_smem_probe(struct platform_device *pdev)
return ret;
}
for (i = 0; i < num_regions; i++) {
ret = qcom_smem_map_toc(smem, &smem->regions[0]);
if (ret)
return ret;
for (i = 1; i < num_regions; i++) {
smem->regions[i].virt_base = devm_ioremap_wc(&pdev->dev,
smem->regions[i].aux_base,
smem->regions[i].size);
@ -950,7 +1098,30 @@ static int qcom_smem_probe(struct platform_device *pdev)
return -EINVAL;
}
hwlock_id = of_hwspin_lock_get_id(pdev->dev.of_node, 0);
if (hwlock_id < 0) {
if (hwlock_id != -EPROBE_DEFER)
dev_err(&pdev->dev, "failed to retrieve hwlock\n");
return hwlock_id;
}
smem->hwlock = hwspin_lock_request_specific(hwlock_id);
if (!smem->hwlock)
return -ENXIO;
ret = hwspin_lock_timeout_irqsave(smem->hwlock, HWSPINLOCK_TIMEOUT, &flags);
if (ret)
return ret;
size = readl_relaxed(&header->available) + readl_relaxed(&header->free_offset);
hwspin_unlock_irqrestore(smem->hwlock, &flags);
version = qcom_smem_get_sbl_version(smem);
/*
* smem header mapping is required only in heap version scheme, so unmap
* it here. It will be remapped in qcom_smem_map_global() when whole
* partition is mapped again.
*/
devm_iounmap(smem->dev, smem->regions[0].virt_base);
switch (version >> 16) {
case SMEM_GLOBAL_PART_VERSION:
ret = qcom_smem_set_global_partition(smem);
@ -959,6 +1130,7 @@ static int qcom_smem_probe(struct platform_device *pdev)
smem->item_count = qcom_smem_get_item_count(smem);
break;
case SMEM_GLOBAL_HEAP_VERSION:
qcom_smem_map_global(smem, size);
smem->item_count = SMEM_ITEM_COUNT;
break;
default:
@ -971,17 +1143,6 @@ static int qcom_smem_probe(struct platform_device *pdev)
if (ret < 0 && ret != -ENOENT)
return ret;
hwlock_id = of_hwspin_lock_get_id(pdev->dev.of_node, 0);
if (hwlock_id < 0) {
if (hwlock_id != -EPROBE_DEFER)
dev_err(&pdev->dev, "failed to retrieve hwlock\n");
return hwlock_id;
}
smem->hwlock = hwspin_lock_request_specific(hwlock_id);
if (!smem->hwlock)
return -ENXIO;
__smem = smem;
smem->socinfo = platform_device_register_data(&pdev->dev, "qcom-socinfo",

View File

@ -493,6 +493,7 @@ static int smp2p_parse_ipc(struct qcom_smp2p *smp2p)
}
smp2p->ipc_regmap = syscon_node_to_regmap(syscon);
of_node_put(syscon);
if (IS_ERR(smp2p->ipc_regmap))
return PTR_ERR(smp2p->ipc_regmap);

View File

@ -374,6 +374,7 @@ static int smsm_parse_ipc(struct qcom_smsm *smsm, unsigned host_id)
return 0;
host->ipc_regmap = syscon_node_to_regmap(syscon);
of_node_put(syscon);
if (IS_ERR(host->ipc_regmap))
return PTR_ERR(host->ipc_regmap);

View File

@ -236,24 +236,24 @@ static const struct soc_id soc_id[] = {
{ 184, "APQ8074" },
{ 185, "MSM8274" },
{ 186, "MSM8674" },
{ 194, "MSM8974PRO" },
{ 194, "MSM8974PRO-AC" },
{ 198, "MSM8126" },
{ 199, "APQ8026" },
{ 200, "MSM8926" },
{ 205, "MSM8326" },
{ 206, "MSM8916" },
{ 207, "MSM8994" },
{ 208, "APQ8074-AA" },
{ 209, "APQ8074-AB" },
{ 210, "APQ8074PRO" },
{ 211, "MSM8274-AA" },
{ 212, "MSM8274-AB" },
{ 213, "MSM8274PRO" },
{ 214, "MSM8674-AA" },
{ 215, "MSM8674-AB" },
{ 216, "MSM8674PRO" },
{ 217, "MSM8974-AA" },
{ 218, "MSM8974-AB" },
{ 208, "APQ8074PRO-AA" },
{ 209, "APQ8074PRO-AB" },
{ 210, "APQ8074PRO-AC" },
{ 211, "MSM8274PRO-AA" },
{ 212, "MSM8274PRO-AB" },
{ 213, "MSM8274PRO-AC" },
{ 214, "MSM8674PRO-AA" },
{ 215, "MSM8674PRO-AB" },
{ 216, "MSM8674PRO-AC" },
{ 217, "MSM8974PRO-AA" },
{ 218, "MSM8974PRO-AB" },
{ 219, "APQ8028" },
{ 220, "MSM8128" },
{ 221, "MSM8228" },
@ -330,6 +330,8 @@ static const struct soc_id soc_id[] = {
{ 459, "SM7225" },
{ 460, "SA8540P" },
{ 480, "SM8450" },
{ 482, "SM8450" },
{ 487, "SC7280" },
};
static const char *socinfo_machine(struct device *dev, unsigned int id)

View File

@ -20,6 +20,14 @@
#define SDX55_MX 1
#define SDX55_CX 2
/* SDX65 Power Domain Indexes */
#define SDX65_MSS 0
#define SDX65_MX 1
#define SDX65_MX_AO 2
#define SDX65_CX 3
#define SDX65_CX_AO 4
#define SDX65_MXC 5
/* SM6350 Power Domain Indexes */
#define SM6350_CX 0
#define SM6350_GFX 1
@ -117,6 +125,24 @@
#define SC8180X_MX 9
#define SC8180X_MX_AO 10
/* SC8280XP Power Domain Indexes */
#define SC8280XP_CX 0
#define SC8280XP_CX_AO 1
#define SC8280XP_DDR 2
#define SC8280XP_EBI 3
#define SC8280XP_GFX 4
#define SC8280XP_LCX 5
#define SC8280XP_LMX 6
#define SC8280XP_MMCX 7
#define SC8280XP_MMCX_AO 8
#define SC8280XP_MSS 9
#define SC8280XP_MX 10
#define SC8280XP_MXC 12
#define SC8280XP_MX_AO 11
#define SC8280XP_NSP 13
#define SC8280XP_QPHY 14
#define SC8280XP_XO 15
/* SDM845 Power Domain performance levels */
#define RPMH_REGULATOR_LEVEL_RETENTION 16
#define RPMH_REGULATOR_LEVEL_MIN_SVS 48

View File

@ -29,6 +29,8 @@
#define LLCC_AUDHW 22
#define LLCC_NPU 23
#define LLCC_WLHW 24
#define LLCC_PIMEM 25
#define LLCC_DRE 26
#define LLCC_CVP 28
#define LLCC_MODPE 29
#define LLCC_APTCM 30