Commit 9eb33dde authored by Arnd Bergmann's avatar Arnd Bergmann

Merge tag 'qcom-drivers-for-6.6' of...

Merge tag 'qcom-drivers-for-6.6' of https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux into soc/drivers

Qualcomm driver updates for v6.6

Compatible and clock handling in the Qualcomm SCM driver is cleaned up,
together with a couple stylistic cleanups and transition to mark
exported symbols GPL only.

An abstraction for the RPM subsystem is introduced, to make align the
structure of the SMD and GLINK nodes thereof with the structure when a
remoteproc is involved. This is done to facilitate associating
additional entities with the RPM subsystem.

The qmp_send() API is modified to not expose hardware requirements onto
the client drivers, and then further extended to allow command
formatting directly in the API, to facilitate this typical use case.

In the Qualcomm Command DB driver, NUL characters previously included in
identifiers are dropped from the debugfs, to facilitate scripting.

The thresholds of the BWMON driver are simplified to avoid hard coded
starting values.

The OCMEM driver is updated with some cleanups and fixes, and addition
of MSM8226 support.

PMIC_GLINK gains support for retimer switches, safe mode is selected
when the cable is disconnected from altmode and the same is enabled for
SM8550.

An off-by-one string length check is corrected in the QMI encoder
decoder library.

The RPMh tracepoints are extended to include the state of the request,
to provide needed context in the traced events.

The series from Ulf creating a genpd framework is integrated, to
facilitate the other changes to the cpr, rpmpd and rpmhpd driver.
SDX75 support is added to the rpmhpd driver, and the rpmpd driver is
extended with the same sync_state logic found in the rpmhpd driver.

The socinfo driver gains knowledge about SM4450 and SM7125, the IPQ5019
platform is dropped.

Clock handling in the GSBI driver is cleaned up with the use of
devm_clk_get_enabled().

The list of VMIDs defined for the SCM assign memory interface is
extended.

* tag 'qcom-drivers-for-6.6' of https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux: (52 commits)
  soc: qcom: aoss: Tidy up qmp_send() callers
  soc: qcom: aoss: Format string in qmp_send()
  soc: qcom: aoss: Move length requirements from caller
  dt-bindings: firmware: qcom: scm: Updating VMID list
  dt-bindings: qcom: Update RPMHPD entries for some SoCs
  soc: qcom: qmi_encdec: Restrict string length in decode
  soc: qcom: smem: Fix incompatible types in comparison
  soc: qcom: ocmem: add missing clk_disable_unprepare() in ocmem_dev_probe()
  soc: qcom: socinfo: Add SoC ID for SM7125
  dt-bindings: arm: qcom,ids: Add SoC ID for SM7125
  dt-bindings: arm: qcom,ids: drop the IPQ5019 SoC ID
  soc: qcom: socinfo: drop the IPQ5019 SoC ID
  soc: qcom: socinfo: add SM4450 ID
  dt-bindings: arm: qcom,ids: add SoC ID for SM4450
  soc: qcom: pmic_glink: enable altmode for SM8550
  soc: qcom: pmic_glink_altmode: add retimer-switch support
  soc: qcom: pmic_glink_altmode: handle safe mode when disconnect
  soc: qcom: rpmhpd: Add SDX75 power domains
  dt-bindings: power: qcom,rpmpd: Add compatible for sdx75
  genpd: Makefile: build imx
  ...

Link: https://lore.kernel.org/r/20230818023338.2484467-1-andersson@kernel.orgSigned-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parents d4692f6c b4f63bbf
......@@ -82,7 +82,7 @@ additionalProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/power/qcom-rpmpd.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
clock-controller@af00000 {
compatible = "qcom,sm8250-dispcc";
reg = <0x0af00000 0x10000>;
......@@ -103,7 +103,7 @@ examples:
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
power-domains = <&rpmhpd SM8250_MMCX>;
power-domains = <&rpmhpd RPMHPD_MMCX>;
required-opps = <&rpmhpd_opp_low_svs>;
};
...
......@@ -51,7 +51,7 @@ unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/power/qcom-rpmpd.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
clock-controller@abf0000 {
compatible = "qcom,sm8350-videocc";
......@@ -59,7 +59,7 @@ examples:
clocks = <&rpmhcc RPMH_CXO_CLK>,
<&rpmhcc RPMH_CXO_CLK_A>,
<&sleep_clk>;
power-domains = <&rpmhpd SM8350_MMCX>;
power-domains = <&rpmhpd RPMHPD_MMCX>;
required-opps = <&rpmhpd_opp_low_svs>;
#clock-cells = <1>;
#reset-cells = <1>;
......
......@@ -64,7 +64,7 @@ examples:
- |
#include <dt-bindings/clock/qcom,gcc-sm8450.h>
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/power/qcom-rpmpd.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
clock-controller@ade0000 {
compatible = "qcom,sm8450-camcc";
reg = <0xade0000 0x20000>;
......@@ -72,7 +72,7 @@ examples:
<&rpmhcc RPMH_CXO_CLK>,
<&rpmhcc RPMH_CXO_CLK_A>,
<&sleep_clk>;
power-domains = <&rpmhpd SM8450_MMCX>;
power-domains = <&rpmhpd RPMHPD_MMCX>;
required-opps = <&rpmhpd_opp_low_svs>;
#clock-cells = <1>;
#reset-cells = <1>;
......
......@@ -76,7 +76,7 @@ examples:
- |
#include <dt-bindings/clock/qcom,gcc-sm8450.h>
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/power/qcom-rpmpd.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
clock-controller@af00000 {
compatible = "qcom,sm8450-dispcc";
reg = <0x0af00000 0x10000>;
......@@ -91,7 +91,7 @@ examples:
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
power-domains = <&rpmhpd SM8450_MMCX>;
power-domains = <&rpmhpd RPMHPD_MMCX>;
required-opps = <&rpmhpd_opp_low_svs>;
};
...
......@@ -64,13 +64,13 @@ examples:
- |
#include <dt-bindings/clock/qcom,gcc-sm8450.h>
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/power/qcom-rpmpd.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
videocc: clock-controller@aaf0000 {
compatible = "qcom,sm8450-videocc";
reg = <0x0aaf0000 0x10000>;
clocks = <&rpmhcc RPMH_CXO_CLK>,
<&gcc GCC_VIDEO_AHB_CLK>;
power-domains = <&rpmhpd SM8450_MMCX>;
power-domains = <&rpmhpd RPMHPD_MMCX>;
required-opps = <&rpmhpd_opp_low_svs>;
#clock-cells = <1>;
#reset-cells = <1>;
......
......@@ -76,7 +76,7 @@ examples:
- |
#include <dt-bindings/clock/qcom,sm8550-gcc.h>
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/power/qcom-rpmpd.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
clock-controller@af00000 {
compatible = "qcom,sm8550-dispcc";
reg = <0x0af00000 0x10000>;
......@@ -99,7 +99,7 @@ examples:
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
power-domains = <&rpmhpd SM8550_MMCX>;
power-domains = <&rpmhpd RPMHPD_MMCX>;
required-opps = <&rpmhpd_opp_low_svs>;
};
...
......@@ -124,7 +124,7 @@ additionalProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/power/qcom-rpmpd.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
clock-controller@ab00000 {
compatible = "qcom,sdm845-videocc";
reg = <0x0ab00000 0x10000>;
......@@ -133,7 +133,7 @@ examples:
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
power-domains = <&rpmhpd SM8250_MMCX>;
power-domains = <&rpmhpd RPMHPD_MMCX>;
required-opps = <&rpmhpd_opp_low_svs>;
};
...
......@@ -54,7 +54,7 @@ examples:
#include <dt-bindings/clock/qcom,gcc-sm8250.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interconnect/qcom,sm8250.h>
#include <dt-bindings/power/qcom-rpmpd.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
display-controller@ae01000 {
compatible = "qcom,sm8250-dpu";
......@@ -72,7 +72,7 @@ examples:
assigned-clock-rates = <19200000>;
operating-points-v2 = <&mdp_opp_table>;
power-domains = <&rpmhpd SM8250_MMCX>;
power-domains = <&rpmhpd RPMHPD_MMCX>;
interrupt-parent = <&mdss>;
interrupts = <0>;
......
......@@ -76,7 +76,7 @@ examples:
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interconnect/qcom,sm8250.h>
#include <dt-bindings/power/qcom-rpmpd.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
display-subsystem@ae00000 {
compatible = "qcom,sm8250-mdss";
......@@ -121,7 +121,7 @@ examples:
assigned-clock-rates = <19200000>;
operating-points-v2 = <&mdp_opp_table>;
power-domains = <&rpmhpd SM8250_MMCX>;
power-domains = <&rpmhpd RPMHPD_MMCX>;
interrupt-parent = <&mdss>;
interrupts = <0>;
......@@ -196,7 +196,7 @@ examples:
assigned-clock-parents = <&dsi0_phy 0>, <&dsi0_phy 1>;
operating-points-v2 = <&dsi_opp_table>;
power-domains = <&rpmhpd SM8250_MMCX>;
power-domains = <&rpmhpd RPMHPD_MMCX>;
phys = <&dsi0_phy>;
phy-names = "dsi";
......@@ -286,7 +286,7 @@ examples:
assigned-clock-parents = <&dsi1_phy 0>, <&dsi1_phy 1>;
operating-points-v2 = <&dsi_opp_table>;
power-domains = <&rpmhpd SM8250_MMCX>;
power-domains = <&rpmhpd RPMHPD_MMCX>;
phys = <&dsi1_phy>;
phy-names = "dsi";
......
......@@ -51,7 +51,7 @@ examples:
#include <dt-bindings/clock/qcom,gcc-sm8350.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interconnect/qcom,sm8350.h>
#include <dt-bindings/power/qcom-rpmpd.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
display-controller@ae01000 {
compatible = "qcom,sm8350-dpu";
......@@ -76,7 +76,7 @@ examples:
assigned-clock-rates = <19200000>;
operating-points-v2 = <&mdp_opp_table>;
power-domains = <&rpmhpd SM8350_MMCX>;
power-domains = <&rpmhpd RPMHPD_MMCX>;
interrupt-parent = <&mdss>;
interrupts = <0>;
......
......@@ -75,7 +75,7 @@ examples:
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interconnect/qcom,sm8350.h>
#include <dt-bindings/power/qcom-rpmpd.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
display-subsystem@ae00000 {
compatible = "qcom,sm8350-mdss";
......@@ -128,7 +128,7 @@ examples:
assigned-clock-rates = <19200000>;
operating-points-v2 = <&mdp_opp_table>;
power-domains = <&rpmhpd SM8350_MMCX>;
power-domains = <&rpmhpd RPMHPD_MMCX>;
interrupt-parent = <&mdss>;
interrupts = <0>;
......@@ -197,7 +197,7 @@ examples:
<&mdss_dsi0_phy 1>;
operating-points-v2 = <&dsi_opp_table>;
power-domains = <&rpmhpd SM8350_MMCX>;
power-domains = <&rpmhpd RPMHPD_MMCX>;
phys = <&mdss_dsi0_phy>;
......
......@@ -58,7 +58,7 @@ examples:
#include <dt-bindings/clock/qcom,gcc-sm8450.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interconnect/qcom,sm8450.h>
#include <dt-bindings/power/qcom-rpmpd.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
display-controller@ae01000 {
compatible = "qcom,sm8450-dpu";
......@@ -83,7 +83,7 @@ examples:
assigned-clock-rates = <19200000>;
operating-points-v2 = <&mdp_opp_table>;
power-domains = <&rpmhpd SM8450_MMCX>;
power-domains = <&rpmhpd RPMHPD_MMCX>;
interrupt-parent = <&mdss>;
interrupts = <0>;
......
......@@ -68,7 +68,7 @@ examples:
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interconnect/qcom,sm8450.h>
#include <dt-bindings/power/qcom-rpmpd.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
display-subsystem@ae00000 {
compatible = "qcom,sm8450-mdss";
......@@ -122,7 +122,7 @@ examples:
assigned-clock-rates = <19200000>;
operating-points-v2 = <&mdp_opp_table>;
power-domains = <&rpmhpd SM8450_MMCX>;
power-domains = <&rpmhpd RPMHPD_MMCX>;
interrupt-parent = <&mdss>;
interrupts = <0>;
......@@ -202,7 +202,7 @@ examples:
assigned-clock-parents = <&dsi0_phy 0>, <&dsi0_phy 1>;
operating-points-v2 = <&dsi_opp_table>;
power-domains = <&rpmhpd SM8450_MMCX>;
power-domains = <&rpmhpd RPMHPD_MMCX>;
phys = <&dsi0_phy>;
phy-names = "dsi";
......@@ -297,7 +297,7 @@ examples:
assigned-clock-parents = <&dsi1_phy 0>, <&dsi1_phy 1>;
operating-points-v2 = <&dsi_opp_table>;
power-domains = <&rpmhpd SM8450_MMCX>;
power-domains = <&rpmhpd RPMHPD_MMCX>;
phys = <&dsi1_phy>;
phy-names = "dsi";
......
......@@ -57,7 +57,7 @@ examples:
#include <dt-bindings/clock/qcom,sm8550-dispcc.h>
#include <dt-bindings/clock/qcom,sm8550-gcc.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/power/qcom-rpmpd.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
display-controller@ae01000 {
compatible = "qcom,sm8550-dpu";
......@@ -82,7 +82,7 @@ examples:
assigned-clock-rates = <19200000>;
operating-points-v2 = <&mdp_opp_table>;
power-domains = <&rpmhpd SM8550_MMCX>;
power-domains = <&rpmhpd RPMHPD_MMCX>;
interrupt-parent = <&mdss>;
interrupts = <0>;
......
......@@ -68,7 +68,7 @@ examples:
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interconnect/qcom,sm8550-rpmh.h>
#include <dt-bindings/power/qcom-rpmpd.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
display-subsystem@ae00000 {
compatible = "qcom,sm8550-mdss";
......@@ -122,7 +122,7 @@ examples:
assigned-clock-rates = <19200000>;
operating-points-v2 = <&mdp_opp_table>;
power-domains = <&rpmhpd SM8550_MMCX>;
power-domains = <&rpmhpd RPMHPD_MMCX>;
interrupt-parent = <&mdss>;
interrupts = <0>;
......@@ -197,7 +197,7 @@ examples:
assigned-clock-parents = <&dsi0_phy 0>, <&dsi0_phy 1>;
operating-points-v2 = <&dsi_opp_table>;
power-domains = <&rpmhpd SM8550_MMCX>;
power-domains = <&rpmhpd RPMHPD_MMCX>;
phys = <&dsi0_phy>;
phy-names = "dsi";
......@@ -286,7 +286,7 @@ examples:
assigned-clock-parents = <&dsi1_phy 0>, <&dsi1_phy 1>;
operating-points-v2 = <&dsi_opp_table>;
power-domains = <&rpmhpd SM8550_MMCX>;
power-domains = <&rpmhpd RPMHPD_MMCX>;
phys = <&dsi1_phy>;
phy-names = "dsi";
......
......@@ -176,6 +176,7 @@ allOf:
contains:
enum:
- qcom,scm-qdu1000
- qcom,scm-sc8280xp
- qcom,scm-sm8450
- qcom,scm-sm8550
then:
......
......@@ -106,7 +106,7 @@ examples:
#include <dt-bindings/clock/qcom,videocc-sm8250.h>
#include <dt-bindings/interconnect/qcom,sm8250.h>
#include <dt-bindings/clock/qcom,gcc-sm8250.h>
#include <dt-bindings/power/qcom-rpmpd.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
venus: video-codec@aa00000 {
compatible = "qcom,sm8250-venus";
......@@ -114,7 +114,7 @@ examples:
interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
power-domains = <&videocc MVS0C_GDSC>,
<&videocc MVS0_GDSC>,
<&rpmhpd SM8250_MX>;
<&rpmhpd RPMHPD_MX>;
power-domain-names = "venus", "vcodec0", "mx";
clocks = <&gcc GCC_VIDEO_AXI0_CLK>,
......
......@@ -215,7 +215,7 @@ examples:
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/qcom,gcc-sm8250.h>
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/power/qcom-rpmpd.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
sdhc_2: mmc@8804000 {
compatible = "qcom,sm8250-sdhci", "qcom,sdhci-msm-v5";
......@@ -232,7 +232,7 @@ examples:
iommus = <&apps_smmu 0x4a0 0x0>;
qcom,dll-config = <0x0007642c>;
qcom,ddr-config = <0x80040868>;
power-domains = <&rpmhpd SM8250_CX>;
power-domains = <&rpmhpd RPMHPD_CX>;
operating-points-v2 = <&sdhc2_opp_table>;
......
......@@ -41,6 +41,7 @@ properties:
- qcom,sdm845-rpmhpd
- qcom,sdx55-rpmhpd
- qcom,sdx65-rpmhpd
- qcom,sdx75-rpmhpd
- qcom,sm6115-rpmpd
- qcom,sm6125-rpmpd
- qcom,sm6350-rpmhpd
......
......@@ -14,9 +14,6 @@ description:
related to the remote processor.
properties:
$nodename:
const: glink-edge
apr:
$ref: /schemas/soc/qcom/qcom,apr.yaml#
required:
......
......@@ -84,7 +84,7 @@ examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
rpm-glink {
glink-edge {
compatible = "qcom,glink-rpm";
interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>;
mboxes = <&apcs_glb 0>;
......
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/remoteproc/qcom,rpm-proc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Resource Power Manager (RPM) Processor/Subsystem
maintainers:
- Bjorn Andersson <andersson@kernel.org>
- Konrad Dybcio <konrad.dybcio@linaro.org>
- Stephan Gerhold <stephan@gerhold.net>
description: |
Resource Power Manager (RPM) subsystem found in various Qualcomm platforms:
+--------------------------------------------+
| RPM subsystem (qcom,rpm-proc) |
| |
reset | +---------------+ +-----+ +-----+ |
--------->| | | MPM | | CPR | ... |
IPC interrupts | | ARM Cortex-M3 |--- +-----+ +-----+ |
----------------->| | | | | |
| +---------------+ |---------------------- |
| +---------------+ | |
| | Code RAM |--| +------------------+ |
| +---------------+ | | | |
| +---------------+ |--| Message RAM | |
| | Data RAM |--| | | |
| +---------------+ | +------------------+ |
+--------------------|-----------------------+
v
NoC
The firmware running on the processor inside the RPM subsystem allows each
component in the system to vote for state of the system resources, such as
clocks, regulators and bus frequencies. It implements multiple separate
communication interfaces that are described in subnodes, e.g. SMD and MPM:
+------------------------------+
| ARM Cortex-M3 |
| | +------------------------------+
| +--------------------------+ | | Message RAM |
| | RPM firmware | | | |
IPC IRQ 0 | | +----------------------+ | | | +--------------------------+ |
-------------->| SMD server |<------->| SMD data structures | |
| | | +--------------+ | | | | | +--------------+ | |
| | | | rpm_requests | ... | | | | | | rpm_requests | ... | |
| | | +--------------+ | | | | | +--------------+ | |
IPC IRQ 1 | | +----------------------+ | | | +--------------------------+ |
-------------->| MPM virtualization |<--------| MPM register copy (vMPM) | |
| | +----------------------+ | | | +--------------------------+ |
| | ... | | | | ... |
| +--------------------|-----+ | +------------------------------+
+----------------------|-------+
v
+--------------+
| MPM Hardware |
+--------------+
The services provided by the firmware are only available after the firmware
has been loaded and the processor has been released from reset. Usually this
happens early in the boot process before the operating system is started.
properties:
compatible:
items:
- enum:
- qcom,apq8084-rpm-proc
- qcom,ipq6018-rpm-proc
- qcom,ipq9574-rpm-proc
- qcom,mdm9607-rpm-proc
- qcom,msm8226-rpm-proc
- qcom,msm8610-rpm-proc
- qcom,msm8909-rpm-proc
- qcom,msm8916-rpm-proc
- qcom,msm8917-rpm-proc
- qcom,msm8936-rpm-proc
- qcom,msm8937-rpm-proc
- qcom,msm8952-rpm-proc
- qcom,msm8953-rpm-proc
- qcom,msm8974-rpm-proc
- qcom,msm8976-rpm-proc
- qcom,msm8994-rpm-proc
- qcom,msm8996-rpm-proc
- qcom,msm8998-rpm-proc
- qcom,qcm2290-rpm-proc
- qcom,qcs404-rpm-proc
- qcom,sdm660-rpm-proc
- qcom,sm6115-rpm-proc
- qcom,sm6125-rpm-proc
- qcom,sm6375-rpm-proc
- const: qcom,rpm-proc
smd-edge:
$ref: /schemas/remoteproc/qcom,smd-edge.yaml#
description:
Qualcomm Shared Memory subnode which represents communication edge,
channels and devices related to the RPM subsystem.
glink-edge:
$ref: /schemas/remoteproc/qcom,glink-rpm-edge.yaml#
description:
Qualcomm G-Link subnode which represents communication edge,
channels and devices related to the RPM subsystem.
interrupt-controller:
type: object
$ref: /schemas/interrupt-controller/qcom,mpm.yaml#
description:
MSM Power Manager (MPM) interrupt controller that monitors interrupts
when the system is asleep.
master-stats:
$ref: /schemas/soc/qcom/qcom,rpm-master-stats.yaml#
description:
Subsystem-level low-power mode statistics provided by RPM.
required:
- compatible
oneOf:
- required:
- smd-edge
- required:
- glink-edge
additionalProperties: false
examples:
# SMD
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interrupt-controller/irq.h>
remoteproc {
compatible = "qcom,msm8916-rpm-proc", "qcom,rpm-proc";
smd-edge {
interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>;
qcom,ipc = <&apcs 8 0>;
qcom,smd-edge = <15>;
rpm-requests {
compatible = "qcom,rpm-msm8916";
qcom,smd-channels = "rpm_requests";
/* ... */
};
};
};
# GLINK
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interrupt-controller/irq.h>
remoteproc {
compatible = "qcom,qcm2290-rpm-proc", "qcom,rpm-proc";
glink-edge {
compatible = "qcom,glink-rpm";
interrupts = <GIC_SPI 194 IRQ_TYPE_EDGE_RISING>;
qcom,rpm-msg-ram = <&rpm_msg_ram>;
mboxes = <&apcs_glb 0>;
rpm-requests {
compatible = "qcom,rpm-qcm2290";
qcom,glink-channels = "rpm_requests";
/* ... */
};
};
};
......@@ -139,7 +139,7 @@ examples:
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/mailbox/qcom-ipcc.h>
#include <dt-bindings/power/qcom-rpmpd.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
remoteproc@30000000 {
compatible = "qcom,sm8450-adsp-pas";
......@@ -160,8 +160,8 @@ examples:
memory-region = <&adsp_mem>;
power-domains = <&rpmhpd SM8450_LCX>,
<&rpmhpd SM8450_LMX>;
power-domains = <&rpmhpd RPMHPD_LCX>,
<&rpmhpd RPMHPD_LMX>;
power-domain-names = "lcx", "lmx";
qcom,qmp = <&aoss_qmp>;
......
......@@ -34,22 +34,27 @@ properties:
- qcom,rpm-apq8084
- qcom,rpm-ipq6018
- qcom,rpm-ipq9574
- qcom,rpm-mdm9607
- qcom,rpm-msm8226
- qcom,rpm-msm8610
- qcom,rpm-msm8909
- qcom,rpm-msm8916
- qcom,rpm-msm8917
- qcom,rpm-msm8936
- qcom,rpm-msm8937
- qcom,rpm-msm8952
- qcom,rpm-msm8953
- qcom,rpm-msm8974
- qcom,rpm-msm8976
- qcom,rpm-msm8994
- qcom,rpm-msm8996
- qcom,rpm-msm8998
- qcom,rpm-qcm2290
- qcom,rpm-qcs404
- qcom,rpm-sdm660
- qcom,rpm-sm6115
- qcom,rpm-sm6125
- qcom,rpm-sm6375
- qcom,rpm-qcm2290
- qcom,rpm-qcs404
clock-controller:
$ref: /schemas/clock/qcom,rpmcc.yaml#
......@@ -81,12 +86,18 @@ if:
contains:
enum:
- qcom,rpm-apq8084
- qcom,rpm-mdm9607
- qcom,rpm-msm8226
- qcom,rpm-msm8610
- qcom,rpm-msm8909
- qcom,rpm-msm8916
- qcom,rpm-msm8917
- qcom,rpm-msm8936
- qcom,rpm-msm8937
- qcom,rpm-msm8952
- qcom,rpm-msm8953
- qcom,rpm-msm8974
- qcom,rpm-msm8976
- qcom,rpm-msm8953
- qcom,rpm-msm8994
then:
properties:
......@@ -109,10 +120,10 @@ examples:
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interrupt-controller/irq.h>
smd {
compatible = "qcom,smd";
remoteproc {
compatible = "qcom,msm8916-rpm-proc", "qcom,rpm-proc";
rpm {
smd-edge {
interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>;
qcom,ipc = <&apcs 8 0>;
qcom,smd-edge = <15>;
......
......@@ -15,6 +15,12 @@ description:
The Qualcomm Shared Memory Driver is a FIFO based communication channel for
sending data between the various subsystems in Qualcomm platforms.
Using the top-level SMD node is deprecated. Instead, the SMD edges are defined
directly below the device node representing the respective remote subsystem
or remote processor.
deprecated: true
properties:
compatible:
const: qcom,smd
......@@ -37,6 +43,7 @@ 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.
# NOTE: This is deprecated, represent the RPM using "qcom,rpm-proc" instead.
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
......
......@@ -15,7 +15,9 @@ description: |
properties:
compatible:
const: qcom,msm8974-ocmem
enum:
- qcom,msm8226-ocmem # v1.1.0
- qcom,msm8974-ocmem # v1.4.0
reg:
items:
......@@ -28,11 +30,13 @@ properties:
- const: mem
clocks:
minItems: 1
items:
- description: Core clock
- description: Interface clock
clock-names:
minItems: 1
items:
- const: core
- const: iface
......@@ -58,6 +62,26 @@ required:
additionalProperties: false
allOf:
- if:
properties:
compatible:
contains:
enum:
- qcom,msm8974-ocmem
then:
properties:
clocks:
minItems: 2
clock-names:
minItems: 2
else:
properties:
clocks:
minItems: 1
clock-names:
minItems: 1
patternProperties:
"-sram@[0-9a-f]+$":
type: object
......
This diff is collapsed.
......@@ -3,6 +3,7 @@ obj-y += actions/
obj-y += amlogic/
obj-y += apple/
obj-y += bcm/
obj-y += imx/
obj-y += mediatek/
obj-y += qcom/
obj-y += renesas/
......
......@@ -15,7 +15,6 @@
#include <linux/bitops.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm_domain.h>
#include <linux/pm_opp.h>
......
......@@ -9,12 +9,12 @@
#include <linux/pm_domain.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm_opp.h>
#include <soc/qcom/cmd-db.h>
#include <soc/qcom/rpmh.h>
#include <dt-bindings/power/qcom-rpmpd.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
#define domain_to_rpmhpd(domain) container_of(domain, struct rpmhpd, pd)
......@@ -307,6 +307,21 @@ static const struct rpmhpd_desc sdx65_desc = {
.num_pds = ARRAY_SIZE(sdx65_rpmhpds),
};
/* SDX75 RPMH powerdomains */
static struct rpmhpd *sdx75_rpmhpds[] = {
[RPMHPD_CX] = &cx,
[RPMHPD_CX_AO] = &cx_ao,
[RPMHPD_MSS] = &mss,
[RPMHPD_MX] = &mx,
[RPMHPD_MX_AO] = &mx_ao,
[RPMHPD_MXC] = &mxc,
};
static const struct rpmhpd_desc sdx75_desc = {
.rpmhpds = sdx75_rpmhpds,
.num_pds = ARRAY_SIZE(sdx75_rpmhpds),
};
/* SM6350 RPMH powerdomains */
static struct rpmhpd *sm6350_rpmhpds[] = {
[SM6350_CX] = &cx_w_mx_parent,
......@@ -359,16 +374,16 @@ static const struct rpmhpd_desc sa8155p_desc = {
/* SM8250 RPMH powerdomains */
static struct rpmhpd *sm8250_rpmhpds[] = {
[SM8250_CX] = &cx_w_mx_parent,
[SM8250_CX_AO] = &cx_ao_w_mx_parent,
[SM8250_EBI] = &ebi,
[SM8250_GFX] = &gfx,
[SM8250_LCX] = &lcx,
[SM8250_LMX] = &lmx,
[SM8250_MMCX] = &mmcx,
[SM8250_MMCX_AO] = &mmcx_ao,
[SM8250_MX] = &mx,
[SM8250_MX_AO] = &mx_ao,
[RPMHPD_CX] = &cx_w_mx_parent,
[RPMHPD_CX_AO] = &cx_ao_w_mx_parent,
[RPMHPD_EBI] = &ebi,
[RPMHPD_GFX] = &gfx,
[RPMHPD_LCX] = &lcx,
[RPMHPD_LMX] = &lmx,
[RPMHPD_MMCX] = &mmcx,
[RPMHPD_MMCX_AO] = &mmcx_ao,
[RPMHPD_MX] = &mx,
[RPMHPD_MX_AO] = &mx_ao,
};
static const struct rpmhpd_desc sm8250_desc = {
......@@ -378,19 +393,19 @@ static const struct rpmhpd_desc sm8250_desc = {
/* SM8350 Power domains */
static struct rpmhpd *sm8350_rpmhpds[] = {
[SM8350_CX] = &cx_w_mx_parent,
[SM8350_CX_AO] = &cx_ao_w_mx_parent,
[SM8350_EBI] = &ebi,
[SM8350_GFX] = &gfx,
[SM8350_LCX] = &lcx,
[SM8350_LMX] = &lmx,
[SM8350_MMCX] = &mmcx,
[SM8350_MMCX_AO] = &mmcx_ao,
[SM8350_MSS] = &mss,
[SM8350_MX] = &mx,
[SM8350_MX_AO] = &mx_ao,
[SM8350_MXC] = &mxc,
[SM8350_MXC_AO] = &mxc_ao,
[RPMHPD_CX] = &cx_w_mx_parent,
[RPMHPD_CX_AO] = &cx_ao_w_mx_parent,
[RPMHPD_EBI] = &ebi,
[RPMHPD_GFX] = &gfx,
[RPMHPD_LCX] = &lcx,
[RPMHPD_LMX] = &lmx,
[RPMHPD_MMCX] = &mmcx,
[RPMHPD_MMCX_AO] = &mmcx_ao,
[RPMHPD_MSS] = &mss,
[RPMHPD_MX] = &mx,
[RPMHPD_MX_AO] = &mx_ao,
[RPMHPD_MXC] = &mxc,
[RPMHPD_MXC_AO] = &mxc_ao,
};
static const struct rpmhpd_desc sm8350_desc = {
......@@ -400,19 +415,19 @@ static const struct rpmhpd_desc sm8350_desc = {
/* SM8450 RPMH powerdomains */
static struct rpmhpd *sm8450_rpmhpds[] = {
[SM8450_CX] = &cx,
[SM8450_CX_AO] = &cx_ao,
[SM8450_EBI] = &ebi,
[SM8450_GFX] = &gfx,
[SM8450_LCX] = &lcx,
[SM8450_LMX] = &lmx,
[SM8450_MMCX] = &mmcx_w_cx_parent,
[SM8450_MMCX_AO] = &mmcx_ao_w_cx_parent,
[SM8450_MSS] = &mss,
[SM8450_MX] = &mx,
[SM8450_MX_AO] = &mx_ao,
[SM8450_MXC] = &mxc,
[SM8450_MXC_AO] = &mxc_ao,
[RPMHPD_CX] = &cx,
[RPMHPD_CX_AO] = &cx_ao,
[RPMHPD_EBI] = &ebi,
[RPMHPD_GFX] = &gfx,
[RPMHPD_LCX] = &lcx,
[RPMHPD_LMX] = &lmx,
[RPMHPD_MMCX] = &mmcx_w_cx_parent,
[RPMHPD_MMCX_AO] = &mmcx_ao_w_cx_parent,
[RPMHPD_MSS] = &mss,
[RPMHPD_MX] = &mx,
[RPMHPD_MX_AO] = &mx_ao,
[RPMHPD_MXC] = &mxc,
[RPMHPD_MXC_AO] = &mxc_ao,
};
static const struct rpmhpd_desc sm8450_desc = {
......@@ -422,20 +437,20 @@ static const struct rpmhpd_desc sm8450_desc = {
/* SM8550 RPMH powerdomains */
static struct rpmhpd *sm8550_rpmhpds[] = {
[SM8550_CX] = &cx,
[SM8550_CX_AO] = &cx_ao,
[SM8550_EBI] = &ebi,
[SM8550_GFX] = &gfx,
[SM8550_LCX] = &lcx,
[SM8550_LMX] = &lmx,
[SM8550_MMCX] = &mmcx_w_cx_parent,
[SM8550_MMCX_AO] = &mmcx_ao_w_cx_parent,
[SM8550_MSS] = &mss,
[SM8550_MX] = &mx,
[SM8550_MX_AO] = &mx_ao,
[SM8550_MXC] = &mxc,
[SM8550_MXC_AO] = &mxc_ao,
[SM8550_NSP] = &nsp,
[RPMHPD_CX] = &cx,
[RPMHPD_CX_AO] = &cx_ao,
[RPMHPD_EBI] = &ebi,
[RPMHPD_GFX] = &gfx,
[RPMHPD_LCX] = &lcx,
[RPMHPD_LMX] = &lmx,
[RPMHPD_MMCX] = &mmcx_w_cx_parent,
[RPMHPD_MMCX_AO] = &mmcx_ao_w_cx_parent,
[RPMHPD_MSS] = &mss,
[RPMHPD_MX] = &mx,
[RPMHPD_MX_AO] = &mx_ao,
[RPMHPD_MXC] = &mxc,
[RPMHPD_MXC_AO] = &mxc_ao,
[RPMHPD_NSP] = &nsp,
};
static const struct rpmhpd_desc sm8550_desc = {
......@@ -545,6 +560,7 @@ static const struct of_device_id rpmhpd_match_table[] = {
{ .compatible = "qcom,sdm845-rpmhpd", .data = &sdm845_desc },
{ .compatible = "qcom,sdx55-rpmhpd", .data = &sdx55_desc},
{ .compatible = "qcom,sdx65-rpmhpd", .data = &sdx65_desc},
{ .compatible = "qcom,sdx75-rpmhpd", .data = &sdx75_desc},
{ .compatible = "qcom,sm6350-rpmhpd", .data = &sm6350_desc },
{ .compatible = "qcom,sm8150-rpmhpd", .data = &sm8150_desc },
{ .compatible = "qcom,sm8250-rpmhpd", .data = &sm8250_desc },
......
......@@ -8,7 +8,6 @@
#include <linux/mutex.h>
#include <linux/pm_domain.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm_opp.h>
#include <linux/soc/qcom/smd-rpm.h>
......@@ -58,6 +57,7 @@ struct rpmpd {
struct qcom_smd_rpm *rpm;
unsigned int max_state;
__le32 key;
bool state_synced;
};
struct rpmpd_desc {
......@@ -823,7 +823,11 @@ static int rpmpd_aggregate_corner(struct rpmpd *pd)
unsigned int this_active_corner = 0, this_sleep_corner = 0;
unsigned int peer_active_corner = 0, peer_sleep_corner = 0;
to_active_sleep(pd, pd->corner, &this_active_corner, &this_sleep_corner);
/* Clamp to the highest corner/level if sync_state isn't done yet */
if (!pd->state_synced)
this_active_corner = this_sleep_corner = pd->max_state - 1;
else
to_active_sleep(pd, pd->corner, &this_active_corner, &this_sleep_corner);
if (peer && peer->enabled)
to_active_sleep(peer, peer->corner, &peer_active_corner,
......@@ -973,11 +977,38 @@ static int rpmpd_probe(struct platform_device *pdev)
return of_genpd_add_provider_onecell(pdev->dev.of_node, data);
}
static void rpmpd_sync_state(struct device *dev)
{
const struct rpmpd_desc *desc = of_device_get_match_data(dev);
struct rpmpd **rpmpds = desc->rpmpds;
struct rpmpd *pd;
unsigned int i;
int ret;
mutex_lock(&rpmpd_lock);
for (i = 0; i < desc->num_pds; i++) {
pd = rpmpds[i];
if (!pd)
continue;
pd->state_synced = true;
if (!pd->enabled)
pd->corner = 0;
ret = rpmpd_aggregate_corner(pd);
if (ret)
dev_err(dev, "failed to sync %s: %d\n", pd->pd.name, ret);
}
mutex_unlock(&rpmpd_lock);
}
static struct platform_driver rpmpd_driver = {
.driver = {
.name = "qcom-rpmpd",
.of_match_table = rpmpd_match_table,
.suppress_bind_attrs = true,
.sync_state = rpmpd_sync_state,
},
.probe = rpmpd_probe,
};
......
......@@ -324,15 +324,12 @@ void ipa_power_retention(struct ipa *ipa, bool enable)
{
static const char fmt[] = "{ class: bcm, res: ipa_pc, val: %c }";
struct ipa_power *power = ipa->power;
char buf[36]; /* Exactly enough for fmt[]; size a multiple of 4 */
int ret;
if (!power->qmp)
return; /* Not needed on this platform */
(void)snprintf(buf, sizeof(buf), fmt, enable ? '1' : '0');
ret = qmp_send(power->qmp, buf, sizeof(buf));
ret = qmp_send(power->qmp, fmt, enable ? '1' : '0');
if (ret)
dev_err(power->dev, "error %d sending QMP %sable request\n",
ret, enable ? "en" : "dis");
......
......@@ -23,19 +23,13 @@
static int q6v5_load_state_toggle(struct qcom_q6v5 *q6v5, bool enable)
{
char buf[Q6V5_LOAD_STATE_MSG_LEN];
int ret;
if (!q6v5->qmp)
return 0;
ret = snprintf(buf, sizeof(buf),
"{class: image, res: load_state, name: %s, val: %s}",
ret = qmp_send(q6v5->qmp, "{class: image, res: load_state, name: %s, val: %s}",
q6v5->load_state, enable ? "on" : "off");
WARN_ON(ret >= Q6V5_LOAD_STATE_MSG_LEN);
ret = qmp_send(q6v5->qmp, buf, sizeof(buf));
if (ret)
dev_err(q6v5->dev, "failed to toggle load state\n");
......
......@@ -1479,6 +1479,9 @@ struct qcom_smd_edge *qcom_smd_register_edge(struct device *parent,
struct qcom_smd_edge *edge;
int ret;
if (!qcom_smem_is_available())
return ERR_PTR(-EPROBE_DEFER);
edge = kzalloc(sizeof(*edge), GFP_KERNEL);
if (!edge)
return ERR_PTR(-ENOMEM);
......@@ -1553,12 +1556,9 @@ EXPORT_SYMBOL(qcom_smd_unregister_edge);
static int qcom_smd_probe(struct platform_device *pdev)
{
struct device_node *node;
void *p;
/* Wait for smem */
p = qcom_smem_get(QCOM_SMEM_HOST_ANY, smem_items[0].alloc_tbl_id, NULL);
if (PTR_ERR(p) == -EPROBE_DEFER)
return PTR_ERR(p);
if (!qcom_smem_is_available())
return -EPROBE_DEFER;
for_each_available_child_of_node(pdev->dev.of_node, node)
qcom_smd_register_edge(&pdev->dev, node);
......
......@@ -191,6 +191,7 @@ config QCOM_SMD_RPM
tristate "Qualcomm Resource Power Manager (RPM) over SMD"
depends on ARCH_QCOM || COMPILE_TEST
depends on RPMSG
depends on RPMSG_QCOM_SMD || RPMSG_QCOM_SMD=n
help
If you say yes to this option, support will be included for the
Resource Power Manager system found in the Qualcomm 8974 based
......
......@@ -17,7 +17,7 @@ obj-$(CONFIG_QCOM_RPM_MASTER_STATS) += rpm_master_stats.o
obj-$(CONFIG_QCOM_RPMH) += qcom_rpmh.o
qcom_rpmh-y += rpmh-rsc.o
qcom_rpmh-y += rpmh.o
obj-$(CONFIG_QCOM_SMD_RPM) += smd-rpm.o
obj-$(CONFIG_QCOM_SMD_RPM) += rpm-proc.o smd-rpm.o
obj-$(CONFIG_QCOM_SMEM) += smem.o
obj-$(CONFIG_QCOM_SMEM_STATE) += smem_state.o
obj-$(CONFIG_QCOM_SMP2P) += smp2p.o
......
......@@ -284,7 +284,7 @@ static int cmd_db_debugfs_dump(struct seq_file *seq, void *p)
ent = rsc_to_entry_header(rsc);
for (j = 0; j < le16_to_cpu(rsc->cnt); j++, ent++) {
seq_printf(seq, "0x%05x: %*pEp", le32_to_cpu(ent->addr),
(int)sizeof(ent->id), ent->id);
(int)strnlen(ent->id, sizeof(ent->id)), ent->id);
len = le16_to_cpu(ent->len);
if (len) {
......
......@@ -12,7 +12,7 @@
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_opp.h>
#include <linux/regmap.h>
......@@ -165,9 +165,6 @@ enum bwmon_fields {
struct icc_bwmon_data {
unsigned int sample_ms;
unsigned int count_unit_kb; /* kbytes */
unsigned int default_highbw_kbps;
unsigned int default_medbw_kbps;
unsigned int default_lowbw_kbps;
u8 zone1_thres_count;
u8 zone3_thres_count;
unsigned int quirks;
......@@ -564,20 +561,21 @@ static void bwmon_set_threshold(struct icc_bwmon *bwmon,
static void bwmon_start(struct icc_bwmon *bwmon)
{
const struct icc_bwmon_data *data = bwmon->data;
u32 bw_low = 0;
int window;
/* No need to check for errors, as this must have succeeded before. */
dev_pm_opp_find_bw_ceil(bwmon->dev, &bw_low, 0);
bwmon_clear_counters(bwmon, true);
window = mult_frac(bwmon->data->sample_ms, HW_TIMER_HZ, MSEC_PER_SEC);
/* Maximum sampling window: 0xffffff for v4 and 0xfffff for v5 */
regmap_field_write(bwmon->regs[F_SAMPLE_WINDOW], window);
bwmon_set_threshold(bwmon, bwmon->regs[F_THRESHOLD_HIGH],
data->default_highbw_kbps);
bwmon_set_threshold(bwmon, bwmon->regs[F_THRESHOLD_MED],
data->default_medbw_kbps);
bwmon_set_threshold(bwmon, bwmon->regs[F_THRESHOLD_LOW],
data->default_lowbw_kbps);
bwmon_set_threshold(bwmon, bwmon->regs[F_THRESHOLD_HIGH], bw_low);
bwmon_set_threshold(bwmon, bwmon->regs[F_THRESHOLD_MED], bw_low);
bwmon_set_threshold(bwmon, bwmon->regs[F_THRESHOLD_LOW], 0);
regmap_field_write(bwmon->regs[F_THRESHOLD_COUNT_ZONE0],
BWMON_THRESHOLD_COUNT_ZONE0_DEFAULT);
......@@ -807,9 +805,6 @@ static int bwmon_remove(struct platform_device *pdev)
static const struct icc_bwmon_data msm8998_bwmon_data = {
.sample_ms = 4,
.count_unit_kb = 1024,
.default_highbw_kbps = 4800 * 1024, /* 4.8 GBps */
.default_medbw_kbps = 512 * 1024, /* 512 MBps */
.default_lowbw_kbps = 0,
.zone1_thres_count = 16,
.zone3_thres_count = 1,
.quirks = BWMON_HAS_GLOBAL_IRQ,
......@@ -822,9 +817,6 @@ static const struct icc_bwmon_data msm8998_bwmon_data = {
static const struct icc_bwmon_data sdm845_cpu_bwmon_data = {
.sample_ms = 4,
.count_unit_kb = 64,
.default_highbw_kbps = 4800 * 1024, /* 4.8 GBps */
.default_medbw_kbps = 512 * 1024, /* 512 MBps */
.default_lowbw_kbps = 0,
.zone1_thres_count = 16,
.zone3_thres_count = 1,
.quirks = BWMON_HAS_GLOBAL_IRQ,
......@@ -835,9 +827,6 @@ static const struct icc_bwmon_data sdm845_cpu_bwmon_data = {
static const struct icc_bwmon_data sdm845_llcc_bwmon_data = {
.sample_ms = 4,
.count_unit_kb = 1024,
.default_highbw_kbps = 800 * 1024, /* 800 MBps */
.default_medbw_kbps = 256 * 1024, /* 256 MBps */
.default_lowbw_kbps = 0,
.zone1_thres_count = 16,
.zone3_thres_count = 1,
.regmap_fields = sdm845_llcc_bwmon_reg_fields,
......@@ -847,9 +836,6 @@ static const struct icc_bwmon_data sdm845_llcc_bwmon_data = {
static const struct icc_bwmon_data sc7280_llcc_bwmon_data = {
.sample_ms = 4,
.count_unit_kb = 64,
.default_highbw_kbps = 800 * 1024, /* 800 MBps */
.default_medbw_kbps = 256 * 1024, /* 256 MBps */
.default_lowbw_kbps = 0,
.zone1_thres_count = 16,
.zone3_thres_count = 1,
.quirks = BWMON_NEEDS_FORCE_CLEAR,
......
......@@ -11,7 +11,9 @@
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/iopoll.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/firmware/qcom/qcom_scm.h>
......
......@@ -13,7 +13,6 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/regmap.h>
#include <linux/sizes.h>
#include <linux/slab.h>
......
......@@ -14,7 +14,8 @@
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/firmware/qcom/qcom_scm.h>
#include <linux/sizes.h>
......@@ -54,6 +55,8 @@ struct ocmem {
const struct ocmem_config *config;
struct resource *memory;
void __iomem *mmio;
struct clk *core_clk;
struct clk *iface_clk;
unsigned int num_ports;
unsigned int num_macros;
bool interleaved;
......@@ -80,8 +83,8 @@ struct ocmem {
#define OCMEM_HW_VERSION_MINOR(val) FIELD_GET(GENMASK(27, 16), val)
#define OCMEM_HW_VERSION_STEP(val) FIELD_GET(GENMASK(15, 0), val)
#define OCMEM_HW_PROFILE_NUM_PORTS(val) FIELD_PREP(0x0000000f, (val))
#define OCMEM_HW_PROFILE_NUM_MACROS(val) FIELD_PREP(0x00003f00, (val))
#define OCMEM_HW_PROFILE_NUM_PORTS(val) FIELD_GET(0x0000000f, (val))
#define OCMEM_HW_PROFILE_NUM_MACROS(val) FIELD_GET(0x00003f00, (val))
#define OCMEM_HW_PROFILE_LAST_REGN_HALFSIZE 0x00010000
#define OCMEM_HW_PROFILE_INTERLEAVING 0x00020000
......@@ -95,16 +98,6 @@ struct ocmem {
#define OCMEM_PSGSC_CTL_MACRO2_MODE(val) FIELD_PREP(0x00000700, (val))
#define OCMEM_PSGSC_CTL_MACRO3_MODE(val) FIELD_PREP(0x00007000, (val))
#define OCMEM_CLK_CORE_IDX 0
static struct clk_bulk_data ocmem_clks[] = {
{
.id = "core",
},
{
.id = "iface",
},
};
static inline void ocmem_write(struct ocmem *ocmem, u32 reg, u32 data)
{
writel(data, ocmem->mmio + reg);
......@@ -320,19 +313,20 @@ static int ocmem_dev_probe(struct platform_device *pdev)
ocmem->dev = dev;
ocmem->config = device_get_match_data(dev);
ret = devm_clk_bulk_get(dev, ARRAY_SIZE(ocmem_clks), ocmem_clks);
if (ret) {
if (ret != -EPROBE_DEFER)
dev_err(dev, "Unable to get clocks\n");
ocmem->core_clk = devm_clk_get(dev, "core");
if (IS_ERR(ocmem->core_clk))
return dev_err_probe(dev, PTR_ERR(ocmem->core_clk),
"Unable to get core clock\n");
return ret;
}
ocmem->iface_clk = devm_clk_get_optional(dev, "iface");
if (IS_ERR(ocmem->iface_clk))
return dev_err_probe(dev, PTR_ERR(ocmem->iface_clk),
"Unable to get iface clock\n");
ocmem->mmio = devm_platform_ioremap_resource_byname(pdev, "ctrl");
if (IS_ERR(ocmem->mmio)) {
dev_err(&pdev->dev, "Failed to ioremap ocmem_ctrl resource\n");
return PTR_ERR(ocmem->mmio);
}
if (IS_ERR(ocmem->mmio))
return dev_err_probe(&pdev->dev, PTR_ERR(ocmem->mmio),
"Failed to ioremap ocmem_ctrl resource\n");
ocmem->memory = platform_get_resource_byname(pdev, IORESOURCE_MEM,
"mem");
......@@ -342,19 +336,23 @@ static int ocmem_dev_probe(struct platform_device *pdev)
}
/* The core clock is synchronous with graphics */
WARN_ON(clk_set_rate(ocmem_clks[OCMEM_CLK_CORE_IDX].clk, 1000) < 0);
WARN_ON(clk_set_rate(ocmem->core_clk, 1000) < 0);
ret = clk_prepare_enable(ocmem->core_clk);
if (ret)
return dev_err_probe(ocmem->dev, ret, "Failed to enable core clock\n");
ret = clk_bulk_prepare_enable(ARRAY_SIZE(ocmem_clks), ocmem_clks);
ret = clk_prepare_enable(ocmem->iface_clk);
if (ret) {
dev_info(ocmem->dev, "Failed to enable clocks\n");
return ret;
clk_disable_unprepare(ocmem->core_clk);
return dev_err_probe(ocmem->dev, ret, "Failed to enable iface clock\n");
}
if (qcom_scm_restore_sec_cfg_available()) {
dev_dbg(dev, "configuring scm\n");
ret = qcom_scm_restore_sec_cfg(QCOM_SCM_OCMEM_DEV_ID, 0);
if (ret) {
dev_err(dev, "Could not enable secure configuration\n");
dev_err_probe(dev, ret, "Could not enable secure configuration\n");
goto err_clk_disable;
}
}
......@@ -413,23 +411,33 @@ static int ocmem_dev_probe(struct platform_device *pdev)
return 0;
err_clk_disable:
clk_bulk_disable_unprepare(ARRAY_SIZE(ocmem_clks), ocmem_clks);
clk_disable_unprepare(ocmem->core_clk);
clk_disable_unprepare(ocmem->iface_clk);
return ret;
}
static int ocmem_dev_remove(struct platform_device *pdev)
{
clk_bulk_disable_unprepare(ARRAY_SIZE(ocmem_clks), ocmem_clks);
struct ocmem *ocmem = platform_get_drvdata(pdev);
clk_disable_unprepare(ocmem->core_clk);
clk_disable_unprepare(ocmem->iface_clk);
return 0;
}
static const struct ocmem_config ocmem_8226_config = {
.num_regions = 1,
.macro_size = SZ_128K,
};
static const struct ocmem_config ocmem_8974_config = {
.num_regions = 3,
.macro_size = SZ_128K,
};
static const struct of_device_id ocmem_of_match[] = {
{ .compatible = "qcom,msm8226-ocmem", .data = &ocmem_8226_config },
{ .compatible = "qcom,msm8974-ocmem", .data = &ocmem_8974_config },
{ }
};
......
......@@ -4,8 +4,8 @@
* Copyright (c) 2022, Linaro Ltd
*/
#include <linux/auxiliary_bus.h>
#include <linux/of_device.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/rpmsg.h>
#include <linux/slab.h>
......@@ -342,13 +342,9 @@ static const unsigned long pmic_glink_sm8450_client_mask = BIT(PMIC_GLINK_CLIENT
BIT(PMIC_GLINK_CLIENT_ALTMODE) |
BIT(PMIC_GLINK_CLIENT_UCSI);
/* Do not handle altmode for now on those platforms */
static const unsigned long pmic_glink_sm8550_client_mask = BIT(PMIC_GLINK_CLIENT_BATT) |
BIT(PMIC_GLINK_CLIENT_UCSI);
static const struct of_device_id pmic_glink_of_match[] = {
{ .compatible = "qcom,sm8450-pmic-glink", .data = &pmic_glink_sm8450_client_mask },
{ .compatible = "qcom,sm8550-pmic-glink", .data = &pmic_glink_sm8550_client_mask },
{ .compatible = "qcom,sm8550-pmic-glink", .data = &pmic_glink_sm8450_client_mask },
{ .compatible = "qcom,pmic-glink" },
{}
};
......
......@@ -6,6 +6,7 @@
#include <linux/auxiliary_bus.h>
#include <linux/bitfield.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/mutex.h>
#include <linux/property.h>
......@@ -15,6 +16,7 @@
#include <linux/usb/typec_altmode.h>
#include <linux/usb/typec_dp.h>
#include <linux/usb/typec_mux.h>
#include <linux/usb/typec_retimer.h>
#include <linux/soc/qcom/pmic_glink.h>
......@@ -68,6 +70,8 @@ struct pmic_glink_altmode_port {
struct typec_switch *typec_switch;
struct typec_mux *typec_mux;
struct typec_mux_state state;
struct typec_retimer *typec_retimer;
struct typec_retimer_state retimer_state;
struct typec_altmode dp_alt;
struct work_struct work;
......@@ -157,6 +161,14 @@ static void pmic_glink_altmode_enable_dp(struct pmic_glink_altmode *altmode,
ret = typec_mux_set(port->typec_mux, &port->state);
if (ret)
dev_err(altmode->dev, "failed to switch mux to DP\n");
port->retimer_state.alt = &port->dp_alt;
port->retimer_state.data = &dp_data;
port->retimer_state.mode = TYPEC_MODAL_STATE(mode);
ret = typec_retimer_set(port->typec_retimer, &port->retimer_state);
if (ret)
dev_err(altmode->dev, "failed to setup retimer to DP\n");
}
static void pmic_glink_altmode_enable_usb(struct pmic_glink_altmode *altmode,
......@@ -171,6 +183,36 @@ static void pmic_glink_altmode_enable_usb(struct pmic_glink_altmode *altmode,
ret = typec_mux_set(port->typec_mux, &port->state);
if (ret)
dev_err(altmode->dev, "failed to switch mux to USB\n");
port->retimer_state.alt = NULL;
port->retimer_state.data = NULL;
port->retimer_state.mode = TYPEC_STATE_USB;
ret = typec_retimer_set(port->typec_retimer, &port->retimer_state);
if (ret)
dev_err(altmode->dev, "failed to setup retimer to USB\n");
}
static void pmic_glink_altmode_safe(struct pmic_glink_altmode *altmode,
struct pmic_glink_altmode_port *port)
{
int ret;
port->state.alt = NULL;
port->state.data = NULL;
port->state.mode = TYPEC_STATE_SAFE;
ret = typec_mux_set(port->typec_mux, &port->state);
if (ret)
dev_err(altmode->dev, "failed to switch mux to safe mode\n");
port->retimer_state.alt = NULL;
port->retimer_state.data = NULL;
port->retimer_state.mode = TYPEC_STATE_SAFE;
ret = typec_retimer_set(port->typec_retimer, &port->retimer_state);
if (ret)
dev_err(altmode->dev, "failed to setup retimer to USB\n");
}
static void pmic_glink_altmode_worker(struct work_struct *work)
......@@ -180,7 +222,9 @@ static void pmic_glink_altmode_worker(struct work_struct *work)
typec_switch_set(alt_port->typec_switch, alt_port->orientation);
if (alt_port->svid == USB_TYPEC_DP_SID)
if (alt_port->svid == USB_TYPEC_DP_SID && alt_port->mode == 0xff)
pmic_glink_altmode_safe(altmode, alt_port);
else if (alt_port->svid == USB_TYPEC_DP_SID)
pmic_glink_altmode_enable_dp(altmode, alt_port, alt_port->mode,
alt_port->hpd_state, alt_port->hpd_irq);
else
......@@ -331,6 +375,11 @@ static const struct drm_bridge_funcs pmic_glink_altmode_bridge_funcs = {
.attach = pmic_glink_altmode_attach,
};
static void pmic_glink_altmode_put_retimer(void *data)
{
typec_retimer_put(data);
}
static void pmic_glink_altmode_put_mux(void *data)
{
typec_mux_put(data);
......@@ -437,6 +486,17 @@ static int pmic_glink_altmode_probe(struct auxiliary_device *adev,
if (ret)
return ret;
alt_port->typec_retimer = fwnode_typec_retimer_get(fwnode);
if (IS_ERR(alt_port->typec_retimer))
return dev_err_probe(dev, PTR_ERR(alt_port->typec_retimer),
"failed to acquire retimer-switch for port: %d\n",
port);
ret = devm_add_action_or_reset(dev, pmic_glink_altmode_put_retimer,
alt_port->typec_retimer);
if (ret)
return ret;
alt_port->typec_switch = fwnode_typec_switch_get(fwnode);
if (IS_ERR(alt_port->typec_switch))
return dev_err_probe(dev, PTR_ERR(alt_port->typec_switch),
......
......@@ -205,37 +205,42 @@ static bool qmp_message_empty(struct qmp *qmp)
/**
* qmp_send() - send a message to the AOSS
* @qmp: qmp context
* @data: message to be sent
* @len: length of the message
* @fmt: format string for message to be sent
* @...: arguments for the format string
*
* Transmit @data to AOSS and wait for the AOSS to acknowledge the message.
* @len must be a multiple of 4 and not longer than the mailbox size. Access is
* synchronized by this implementation.
* Transmit message to AOSS and wait for the AOSS to acknowledge the message.
* data must not be longer than the mailbox size. Access is synchronized by
* this implementation.
*
* Return: 0 on success, negative errno on failure
*/
int qmp_send(struct qmp *qmp, const void *data, size_t len)
int qmp_send(struct qmp *qmp, const char *fmt, ...)
{
char buf[QMP_MSG_LEN];
long time_left;
va_list args;
int len;
int ret;
if (WARN_ON(IS_ERR_OR_NULL(qmp) || !data))
if (WARN_ON(IS_ERR_OR_NULL(qmp) || !fmt))
return -EINVAL;
if (WARN_ON(len + sizeof(u32) > qmp->size))
return -EINVAL;
memset(buf, 0, sizeof(buf));
va_start(args, fmt);
len = vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
if (WARN_ON(len % sizeof(u32)))
if (WARN_ON(len >= sizeof(buf)))
return -EINVAL;
mutex_lock(&qmp->tx_lock);
/* The message RAM only implements 32-bit accesses */
__iowrite32_copy(qmp->msgram + qmp->offset + sizeof(u32),
data, len / sizeof(u32));
writel(len, qmp->msgram + qmp->offset);
buf, sizeof(buf) / sizeof(u32));
writel(sizeof(buf), qmp->msgram + qmp->offset);
/* Read back len to confirm data written in message RAM */
/* Read back length to confirm data written in message RAM */
readl(qmp->msgram + qmp->offset);
qmp_kick(qmp);
......@@ -259,18 +264,18 @@ EXPORT_SYMBOL(qmp_send);
static int qmp_qdss_clk_prepare(struct clk_hw *hw)
{
static const char buf[QMP_MSG_LEN] = "{class: clock, res: qdss, val: 1}";
static const char *buf = "{class: clock, res: qdss, val: 1}";
struct qmp *qmp = container_of(hw, struct qmp, qdss_clk);
return qmp_send(qmp, buf, sizeof(buf));
return qmp_send(qmp, buf);
}
static void qmp_qdss_clk_unprepare(struct clk_hw *hw)
{
static const char buf[QMP_MSG_LEN] = "{class: clock, res: qdss, val: 0}";
static const char *buf = "{class: clock, res: qdss, val: 0}";
struct qmp *qmp = container_of(hw, struct qmp, qdss_clk);
qmp_send(qmp, buf, sizeof(buf));
qmp_send(qmp, buf);
}
static const struct clk_ops qmp_qdss_clk_ops = {
......@@ -329,7 +334,6 @@ static int qmp_cdev_set_cur_state(struct thermal_cooling_device *cdev,
unsigned long state)
{
struct qmp_cooling_device *qmp_cdev = cdev->devdata;
char buf[QMP_MSG_LEN] = {};
bool cdev_state;
int ret;
......@@ -339,13 +343,8 @@ static int qmp_cdev_set_cur_state(struct thermal_cooling_device *cdev,
if (qmp_cdev->state == state)
return 0;
snprintf(buf, sizeof(buf),
"{class: volt_flr, event:zero_temp, res:%s, value:%s}",
qmp_cdev->name,
cdev_state ? "on" : "off");
ret = qmp_send(qmp_cdev->qmp, buf, sizeof(buf));
ret = qmp_send(qmp_cdev->qmp, "{class: volt_flr, event:zero_temp, res:%s, value:%s}",
qmp_cdev->name, cdev_state ? "on" : "off");
if (!ret)
qmp_cdev->state = cdev_state;
......
......@@ -129,7 +129,7 @@ static int gsbi_probe(struct platform_device *pdev)
const struct of_device_id *match;
void __iomem *base;
struct gsbi_info *gsbi;
int i, ret;
int i;
u32 mask, gsbi_num;
const struct crci_config *config = NULL;
......@@ -178,12 +178,10 @@ static int gsbi_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "GSBI port protocol: %d crci: %d\n",
gsbi->mode, gsbi->crci);
gsbi->hclk = devm_clk_get(&pdev->dev, "iface");
gsbi->hclk = devm_clk_get_enabled(&pdev->dev, "iface");
if (IS_ERR(gsbi->hclk))
return PTR_ERR(gsbi->hclk);
clk_prepare_enable(gsbi->hclk);
writel_relaxed((gsbi->mode << GSBI_PROTOCOL_SHIFT) | gsbi->crci,
base + GSBI_CTRL_REG);
......@@ -211,10 +209,7 @@ static int gsbi_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, gsbi);
ret = of_platform_populate(node, NULL, NULL, &pdev->dev);
if (ret)
clk_disable_unprepare(gsbi->hclk);
return ret;
return of_platform_populate(node, NULL, NULL, &pdev->dev);
}
static int gsbi_remove(struct platform_device *pdev)
......
......@@ -534,8 +534,8 @@ static int qmi_decode_string_elem(const struct qmi_elem_info *ei_array,
decoded_bytes += rc;
}
if (string_len > temp_ei->elem_len) {
pr_err("%s: String len %d > Max Len %d\n",
if (string_len >= temp_ei->elem_len) {
pr_err("%s: String len %d >= Max Len %d\n",
__func__, string_len, temp_ei->elem_len);
return -ETOOSMALL;
} else if (string_len > tlv_len) {
......
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2021-2023, Stephan Gerhold <stephan@gerhold.net> */
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/rpmsg/qcom_smd.h>
static int rpm_proc_probe(struct platform_device *pdev)
{
struct qcom_smd_edge *edge = NULL;
struct device *dev = &pdev->dev;
struct device_node *edge_node;
int ret;
edge_node = of_get_child_by_name(dev->of_node, "smd-edge");
if (edge_node) {
edge = qcom_smd_register_edge(dev, edge_node);
of_node_put(edge_node);
if (IS_ERR(edge))
return dev_err_probe(dev, PTR_ERR(edge),
"Failed to register smd-edge\n");
}
ret = devm_of_platform_populate(dev);
if (ret) {
dev_err(dev, "Failed to populate child devices: %d\n", ret);
goto err;
}
platform_set_drvdata(pdev, edge);
return 0;
err:
if (edge)
qcom_smd_unregister_edge(edge);
return ret;
}
static void rpm_proc_remove(struct platform_device *pdev)
{
struct qcom_smd_edge *edge = platform_get_drvdata(pdev);
if (edge)
qcom_smd_unregister_edge(edge);
}
static const struct of_device_id rpm_proc_of_match[] = {
{ .compatible = "qcom,rpm-proc", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, rpm_proc_of_match);
static struct platform_driver rpm_proc_driver = {
.probe = rpm_proc_probe,
.remove_new = rpm_proc_remove,
.driver = {
.name = "qcom-rpm-proc",
.of_match_table = rpm_proc_of_match,
},
};
static int __init rpm_proc_init(void)
{
return platform_driver_register(&rpm_proc_driver);
}
arch_initcall(rpm_proc_init);
static void __exit rpm_proc_exit(void)
{
platform_driver_unregister(&rpm_proc_driver);
}
module_exit(rpm_proc_exit);
MODULE_DESCRIPTION("Qualcomm RPM processor/subsystem driver");
MODULE_AUTHOR("Stephan Gerhold <stephan@gerhold.net>");
MODULE_LICENSE("GPL");
......@@ -516,7 +516,7 @@ static void __tcs_buffer_write(struct rsc_drv *drv, int tcs_id, int cmd_id,
write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_MSGID], tcs_id, j, msgid);
write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_ADDR], tcs_id, j, cmd->addr);
write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_DATA], tcs_id, j, cmd->data);
trace_rpmh_send_msg(drv, tcs_id, j, msgid, cmd);
trace_rpmh_send_msg(drv, tcs_id, msg->state, j, msgid, cmd);
}
cmd_enable |= read_tcs_reg(drv, drv->regs[RSC_DRV_CMD_ENABLE], tcs_id);
......
......@@ -199,6 +199,9 @@ static int qcom_smd_rpm_probe(struct rpmsg_device *rpdev)
struct qcom_smd_rpm *rpm;
int ret;
if (!rpdev->dev.of_node)
return -EINVAL;
rpm = devm_kzalloc(&rpdev->dev, sizeof(*rpm), GFP_KERNEL);
if (!rpm)
return -ENOMEM;
......@@ -230,38 +233,18 @@ static void qcom_smd_rpm_remove(struct rpmsg_device *rpdev)
of_platform_depopulate(&rpdev->dev);
}
static const struct of_device_id qcom_smd_rpm_of_match[] = {
{ .compatible = "qcom,rpm-apq8084" },
{ .compatible = "qcom,rpm-ipq6018" },
{ .compatible = "qcom,rpm-ipq9574" },
{ .compatible = "qcom,rpm-msm8226" },
{ .compatible = "qcom,rpm-msm8909" },
{ .compatible = "qcom,rpm-msm8916" },
{ .compatible = "qcom,rpm-msm8936" },
{ .compatible = "qcom,rpm-msm8953" },
{ .compatible = "qcom,rpm-msm8974" },
{ .compatible = "qcom,rpm-msm8976" },
{ .compatible = "qcom,rpm-msm8994" },
{ .compatible = "qcom,rpm-msm8996" },
{ .compatible = "qcom,rpm-msm8998" },
{ .compatible = "qcom,rpm-sdm660" },
{ .compatible = "qcom,rpm-sm6115" },
{ .compatible = "qcom,rpm-sm6125" },
{ .compatible = "qcom,rpm-sm6375" },
{ .compatible = "qcom,rpm-qcm2290" },
{ .compatible = "qcom,rpm-qcs404" },
{}
static const struct rpmsg_device_id qcom_smd_rpm_id_table[] = {
{ .name = "rpm_requests", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, qcom_smd_rpm_of_match);
MODULE_DEVICE_TABLE(rpmsg, qcom_smd_rpm_id_table);
static struct rpmsg_driver qcom_smd_rpm_driver = {
.probe = qcom_smd_rpm_probe,
.remove = qcom_smd_rpm_remove,
.callback = qcom_smd_rpm_callback,
.drv = {
.name = "qcom_smd_rpm",
.of_match_table = qcom_smd_rpm_of_match,
},
.id_table = qcom_smd_rpm_id_table,
.drv.name = "qcom_smd_rpm",
};
static int __init qcom_smd_rpm_init(void)
......
......@@ -359,6 +359,17 @@ static struct qcom_smem *__smem;
/* Timeout (ms) for the trylock of remote spinlocks */
#define HWSPINLOCK_TIMEOUT 1000
/**
* qcom_smem_is_available() - Check if SMEM is available
*
* Return: true if SMEM is available, false otherwise.
*/
bool qcom_smem_is_available(void)
{
return !!__smem;
}
EXPORT_SYMBOL(qcom_smem_is_available);
static int qcom_smem_alloc_private(struct qcom_smem *smem,
struct smem_partition *part,
unsigned item,
......@@ -724,7 +735,7 @@ EXPORT_SYMBOL_GPL(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);
return base && ((void __iomem *)addr >= base && (void __iomem *)addr < base + size);
}
/**
......@@ -1059,7 +1070,6 @@ static int qcom_smem_probe(struct platform_device *pdev)
struct reserved_mem *rmem;
struct qcom_smem *smem;
unsigned long flags;
size_t array_size;
int num_regions;
int hwlock_id;
u32 version;
......@@ -1071,8 +1081,8 @@ static int qcom_smem_probe(struct platform_device *pdev)
if (of_property_present(pdev->dev.of_node, "qcom,rpm-msg-ram"))
num_regions++;
array_size = num_regions * sizeof(struct smem_region);
smem = devm_kzalloc(&pdev->dev, sizeof(*smem) + array_size, GFP_KERNEL);
smem = devm_kzalloc(&pdev->dev, struct_size(smem, regions, num_regions),
GFP_KERNEL);
if (!smem)
return -ENOMEM;
......
......@@ -371,6 +371,7 @@ static const struct soc_id soc_id[] = {
{ qcom_board_id(SDA429W) },
{ qcom_board_id(SM8350) },
{ qcom_board_id(QCM2290) },
{ qcom_board_id(SM7125) },
{ qcom_board_id(SM6115) },
{ qcom_board_id(IPQ5010) },
{ qcom_board_id(IPQ5018) },
......@@ -405,8 +406,8 @@ static const struct soc_id soc_id[] = {
{ qcom_board_id(SA8775P) },
{ qcom_board_id(QRU1000) },
{ qcom_board_id(QDU1000) },
{ qcom_board_id(SM4450) },
{ qcom_board_id(QDU1010) },
{ qcom_board_id(IPQ5019) },
{ qcom_board_id(QRU1032) },
{ qcom_board_id(QRU1052) },
{ qcom_board_id(QRU1062) },
......
......@@ -12,8 +12,6 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <soc/qcom/spm.h>
......@@ -275,15 +273,13 @@ static int spm_dev_probe(struct platform_device *pdev)
{
const struct of_device_id *match_id;
struct spm_driver_data *drv;
struct resource *res;
void __iomem *addr;
drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
if (!drv)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
drv->reg_base = devm_ioremap_resource(&pdev->dev, res);
drv->reg_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(drv->reg_base))
return PTR_ERR(drv->reg_base);
......
......@@ -38,14 +38,15 @@ TRACE_EVENT(rpmh_tx_done,
TRACE_EVENT(rpmh_send_msg,
TP_PROTO(struct rsc_drv *d, int m, int n, u32 h,
TP_PROTO(struct rsc_drv *d, int m, enum rpmh_state state, int n, u32 h,
const struct tcs_cmd *c),
TP_ARGS(d, m, n, h, c),
TP_ARGS(d, m, state, n, h, c),
TP_STRUCT__entry(
__string(name, d->name)
__field(int, m)
__field(u32, state)
__field(int, n)
__field(u32, hdr)
__field(u32, addr)
......@@ -56,6 +57,7 @@ TRACE_EVENT(rpmh_send_msg,
TP_fast_assign(
__assign_str(name, d->name);
__entry->m = m;
__entry->state = state;
__entry->n = n;
__entry->hdr = h;
__entry->addr = c->addr;
......@@ -63,8 +65,14 @@ TRACE_EVENT(rpmh_send_msg,
__entry->wait = c->wait;
),
TP_printk("%s: send-msg: tcs(m): %d cmd(n): %d msgid: %#x addr: %#x data: %#x complete: %d",
__get_str(name), __entry->m, __entry->n, __entry->hdr,
TP_printk("%s: tcs(m): %d [%s] cmd(n): %d msgid: %#x addr: %#x data: %#x complete: %d",
__get_str(name), __entry->m,
__print_symbolic(__entry->state,
{ RPMH_SLEEP_STATE, "sleep" },
{ RPMH_WAKE_ONLY_STATE, "wake" },
{ RPMH_ACTIVE_ONLY_STATE, "active" }),
__entry->n,
__entry->hdr,
__entry->addr, __entry->data, __entry->wait)
);
......
......@@ -7,6 +7,7 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/rpmsg.h>
......
......@@ -215,6 +215,7 @@
#define QCOM_ID_SDA429W 437
#define QCOM_ID_SM8350 439
#define QCOM_ID_QCM2290 441
#define QCOM_ID_SM7125 443
#define QCOM_ID_SM6115 444
#define QCOM_ID_IPQ5010 446
#define QCOM_ID_IPQ5018 447
......@@ -249,8 +250,8 @@
#define QCOM_ID_SA8775P 534
#define QCOM_ID_QRU1000 539
#define QCOM_ID_QDU1000 545
#define QCOM_ID_SM4450 568
#define QCOM_ID_QDU1010 587
#define QCOM_ID_IPQ5019 569
#define QCOM_ID_QRU1032 588
#define QCOM_ID_QRU1052 589
#define QCOM_ID_QRU1062 590
......
......@@ -2,17 +2,38 @@
/*
* Copyright (c) 2010-2015, 2018-2019 The Linux Foundation. All rights reserved.
* Copyright (C) 2015 Linaro Ltd.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _DT_BINDINGS_FIRMWARE_QCOM_SCM_H
#define _DT_BINDINGS_FIRMWARE_QCOM_SCM_H
#define QCOM_SCM_VMID_TZ 0x1
#define QCOM_SCM_VMID_HLOS 0x3
#define QCOM_SCM_VMID_SSC_Q6 0x5
#define QCOM_SCM_VMID_ADSP_Q6 0x6
#define QCOM_SCM_VMID_CP_TOUCH 0x8
#define QCOM_SCM_VMID_CP_BITSTREAM 0x9
#define QCOM_SCM_VMID_CP_PIXEL 0xA
#define QCOM_SCM_VMID_CP_NON_PIXEL 0xB
#define QCOM_SCM_VMID_CP_CAMERA 0xD
#define QCOM_SCM_VMID_HLOS_FREE 0xE
#define QCOM_SCM_VMID_MSS_MSA 0xF
#define QCOM_SCM_VMID_MSS_NONMSA 0x10
#define QCOM_SCM_VMID_CP_SEC_DISPLAY 0x11
#define QCOM_SCM_VMID_CP_APP 0x12
#define QCOM_SCM_VMID_LPASS 0x16
#define QCOM_SCM_VMID_WLAN 0x18
#define QCOM_SCM_VMID_WLAN_CE 0x19
#define QCOM_SCM_VMID_CP_SPSS_SP 0x1A
#define QCOM_SCM_VMID_CP_CAMERA_PREVIEW 0x1D
#define QCOM_SCM_VMID_CDSP 0x1E
#define QCOM_SCM_VMID_CP_SPSS_SP_SHARED 0x22
#define QCOM_SCM_VMID_CP_SPSS_HLOS_SHARED 0x24
#define QCOM_SCM_VMID_ADSP_HEAP 0x25
#define QCOM_SCM_VMID_CP_CDSP 0x2A
#define QCOM_SCM_VMID_NAV 0x2B
#define QCOM_SCM_VMID_TVM 0x2D
#define QCOM_SCM_VMID_OEMVM 0x31
#endif
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
/*
* Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _DT_BINDINGS_POWER_QCOM_RPMHPD_H
#define _DT_BINDINGS_POWER_QCOM_RPMHPD_H
/* Generic RPMH Power Domain Indexes */
#define RPMHPD_CX 0
#define RPMHPD_CX_AO 1
#define RPMHPD_EBI 2
#define RPMHPD_GFX 3
#define RPMHPD_LCX 4
#define RPMHPD_LMX 5
#define RPMHPD_MMCX 6
#define RPMHPD_MMCX_AO 7
#define RPMHPD_MX 8
#define RPMHPD_MX_AO 9
#define RPMHPD_MXC 10
#define RPMHPD_MXC_AO 11
#define RPMHPD_MSS 12
#define RPMHPD_NSP 13
#define RPMHPD_NSP0 14
#define RPMHPD_NSP1 15
#define RPMHPD_QPHY 16
#define RPMHPD_DDR 17
#define RPMHPD_XO 18
#endif
......@@ -75,7 +75,7 @@ struct qcom_scm_pas_metadata {
extern int qcom_scm_pas_init_image(u32 peripheral, const void *metadata,
size_t size,
struct qcom_scm_pas_metadata *ctx);
void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx);
extern void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx);
extern int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr,
phys_addr_t size);
extern int qcom_scm_pas_auth_and_reset(u32 peripheral);
......
......@@ -13,13 +13,13 @@ struct qmp;
#if IS_ENABLED(CONFIG_QCOM_AOSS_QMP)
int qmp_send(struct qmp *qmp, const void *data, size_t len);
int qmp_send(struct qmp *qmp, const char *fmt, ...);
struct qmp *qmp_get(struct device *dev);
void qmp_put(struct qmp *qmp);
#else
static inline int qmp_send(struct qmp *qmp, const void *data, size_t len)
static inline int qmp_send(struct qmp *qmp, const char *fmt, ...)
{
return -ENODEV;
}
......
......@@ -4,6 +4,7 @@
#define QCOM_SMEM_HOST_ANY -1
bool qcom_smem_is_available(void);
int qcom_smem_alloc(unsigned host, unsigned item, size_t size);
void *qcom_smem_get(unsigned host, unsigned item, size_t *size);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment