More Qualcomm driver updates for 6.3
The qcom_scm.h file is moved into firmware/qcom, to avoid having any Qualcomm-specific files directly in include/linux. Support for PMIC GLINK is introduced, which on newer Qualcomm platforms provides an interface to the firmware implementing battery management and USB Type-C handling. Together with the base driver comes the custom altmode support driver. SMD RPM gains support for IPQ9574, and socinfo is extended with support for revision 17 of the information format and soc_id for IPQ5332 and IPQ8064 are added. The qcom_stats is changes not to fail when not all parts are initialized. -----BEGIN PGP SIGNATURE----- iQJJBAABCAAzFiEEBd4DzF816k8JZtUlCx85Pw2ZrcUFAmPmiz4VHGFuZGVyc3Nv bkBrZXJuZWwub3JnAAoJEAsfOT8Nma3FMZ8QANXJEr7U2KX/yd4riBju6Btn0unl I8TR5XlaQAoBUbyp4yTcCUfCe0mEiNcE/YgJwzSKY3mNxc9vLhn1GgqdF+5RFTZw 0H8GBjUpQiRoCC2+pq3YCEisQ49HYXy9W3ys6t1Y3l8xUDLhw5CkeKOGQCqeBDX7 pCflPy7HFUQwPhGt7AOmpNj8+Kh4GnpJHF3D2ShAMFNOn4+l0v8Gh7zDw62FmhBg gjA7eS2aZS7KmqEJMAC4dEFdmhvvN+a80KaWNOOQn2sdLtD64pRW2hknxinPRN+t dGQKeD+VGFHLfxWO40Lv0nP8P/EWjXiZdhO8HXLmVjHC56G/MG8AW0BkvxW9jPAa QGlzY0TbEbi0MbbAnyCJTy6USGtVUZbEmfcZ8r3rUJX5xO8eszSjueD6fH/nKIgo hDIIG8nSLf5TCY+NJzGr8dKENiElsgsfdNAypoX6kpXCRUCXxkiKlWzy/3oywVcO bKm5xs76YNNaANFf46oO6kts7nrOcegyTAdvauFemy1Q3KSWQuFP4jNpcRvWnVMN 8/BlQ+a5uGofN/wwHS2CPmE1r8njEqlPc7wWNc0ugoRO4kAUtB2UldjjS/ZfaFvH BZiDDXhjScPj8lKk4kzGOb34W5AKkwFbTwSR1oN0ckW9UNDx51pNu72YlU8WLydV VHmzD9ndTkWSmp7W =+KgT -----END PGP SIGNATURE----- gpgsig -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEo6/YBQwIrVS28WGKmmx57+YAGNkFAmPqVbkACgkQmmx57+YA GNnlFRAAuaoe9/7kOAliVks4vkJ8284POk50kuS5llzNAP4BPsQIJakE6dOOiTY1 01qbvTlu5pK+f2ls+3WQYr5Rhgck4BUEFD+t9WcPtOpB1uq0puyWj3fwuErjDFJv S6nKp2P0tpru5VzQFPROyrBCw5Zlkc0U9FID4P1Ub5ulxxDWJ4ODb9Q+C9DtDxJo HuUGRnGPLmAJd4ymKzCtnqcg3gocFdrl9K+msFuJwAgdZ0xB893l3wyOFn2k97Uh 8m8WEI/NbCTfDEjag3+yx9Sl3rZhtav0EnlIqowBHQFvxFaBDnvW6H4QmNRugAog +kH1hVzojj35jDllwL07OJzdjqW497Z9i+MEGz45h/8FvvdqJ+71UTkOwr+vnWKu zuEzEfM+bB434UBCQihJ7emx7eCac3TP3Von/NigDDBIXDu8iqNgUNmB8eNyN+gJ Db1mdatG4TuSEqnzetX4XKLP3eydxG8lkEZDOcWlhRz8CSWx9KkBU7W+hVNCBLdV kdhjvZpb5cRcqc/KsS22hmB3HIoISGkLrBOvqs375+Sg9PFxBGst+q24kf9MEDFz ypj/CRiMzkNq8IBwGF003CVhDHmlloq2afQ7YX0w1sEE0XOCIDE0YWNNb9fcoTAC MeDL9R4VgfjR/8Bj7zgnYOMAt6hRoHXsZ1gtS29doIH5iLdTXVI= =8eLr -----END PGP SIGNATURE----- Merge tag 'qcom-drivers-for-6.3-2' of https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux into soc/drivers More Qualcomm driver updates for 6.3 The qcom_scm.h file is moved into firmware/qcom, to avoid having any Qualcomm-specific files directly in include/linux. Support for PMIC GLINK is introduced, which on newer Qualcomm platforms provides an interface to the firmware implementing battery management and USB Type-C handling. Together with the base driver comes the custom altmode support driver. SMD RPM gains support for IPQ9574, and socinfo is extended with support for revision 17 of the information format and soc_id for IPQ5332 and IPQ8064 are added. The qcom_stats is changes not to fail when not all parts are initialized. * tag 'qcom-drivers-for-6.3-2' of https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux: soc: qcom: socinfo: Add IDs for IPQ5332 and its variant dt-bindings: arm: qcom,ids: Add IDs for IPQ5332 and its variant dt-bindings: power: qcom,rpmpd: add RPMH_REGULATOR_LEVEL_LOW_SVS_L1 firmware: qcom_scm: Move qcom_scm.h to include/linux/firmware/qcom/ MAINTAINERS: Update qcom CPR maintainer entry dt-bindings: firmware: document Qualcomm SM8550 SCM dt-bindings: firmware: qcom,scm: add qcom,scm-sa8775p compatible soc: qcom: socinfo: Add Soc IDs for IPQ8064 and variants dt-bindings: arm: qcom,ids: Add Soc IDs for IPQ8064 and variants soc: qcom: socinfo: Add support for new field in revision 17 soc: qcom: smd-rpm: Add IPQ9574 compatible soc: qcom: pmic_glink: remove redundant calculation of svid soc: qcom: stats: Populate all subsystem debugfs files dt-bindings: soc: qcom,rpmh-rsc: Update to allow for generic nodes soc: qcom: pmic_glink: add CONFIG_NET/CONFIG_OF dependencies soc: qcom: pmic_glink: Introduce altmode support soc: qcom: pmic_glink: Introduce base PMIC GLINK driver dt-bindings: soc: qcom: Introduce PMIC GLINK binding soc: qcom: dcc: Drop driver for now Link: https://lore.kernel.org/r/20230210182242.2023901-1-andersson@kernel.org Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
Коммит
68907175ec
|
@ -39,6 +39,7 @@ properties:
|
|||
- qcom,scm-msm8996
|
||||
- qcom,scm-msm8998
|
||||
- qcom,scm-qdu1000
|
||||
- qcom,scm-sa8775p
|
||||
- qcom,scm-sc7180
|
||||
- qcom,scm-sc7280
|
||||
- qcom,scm-sc8280xp
|
||||
|
@ -54,6 +55,7 @@ properties:
|
|||
- qcom,scm-sm8250
|
||||
- qcom,scm-sm8350
|
||||
- qcom,scm-sm8450
|
||||
- qcom,scm-sm8550
|
||||
- qcom,scm-qcs404
|
||||
- const: qcom,scm
|
||||
|
||||
|
@ -165,6 +167,7 @@ allOf:
|
|||
contains:
|
||||
enum:
|
||||
- qcom,scm-sm8450
|
||||
- qcom,scm-sm8550
|
||||
then:
|
||||
properties:
|
||||
interconnects: false
|
||||
|
@ -177,6 +180,7 @@ allOf:
|
|||
contains:
|
||||
enum:
|
||||
- qcom,scm-sm8450
|
||||
- qcom,scm-sm8550
|
||||
then:
|
||||
properties:
|
||||
interrupts: false
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/soc/qcom/qcom,pmic-glink.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm PMIC GLINK firmware interface for battery management, USB
|
||||
Type-C and other things.
|
||||
|
||||
maintainers:
|
||||
- Bjorn Andersson <andersson@kernel.org>
|
||||
|
||||
description:
|
||||
The PMIC GLINK service, running on a coprocessor on some modern Qualcomm
|
||||
platforms and implement USB Type-C handling and battery management. This
|
||||
binding describes the component in the OS used to communicate with the
|
||||
firmware and connect it's resources to those described in the Devicetree,
|
||||
particularly the USB Type-C controllers relationship with USB and DisplayPort
|
||||
components.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- qcom,sc8180x-pmic-glink
|
||||
- qcom,sc8280xp-pmic-glink
|
||||
- qcom,sm8350-pmic-glink
|
||||
- const: qcom,pmic-glink
|
||||
|
||||
'#address-cells':
|
||||
const: 1
|
||||
|
||||
'#size-cells':
|
||||
const: 0
|
||||
|
||||
patternProperties:
|
||||
'^connector@\d$':
|
||||
$ref: /schemas/connector/usb-connector.yaml#
|
||||
|
||||
properties:
|
||||
reg: true
|
||||
|
||||
required:
|
||||
- reg
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |+
|
||||
pmic-glink {
|
||||
compatible = "qcom,sc8280xp-pmic-glink", "qcom,pmic-glink";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
connector@0 {
|
||||
compatible = "usb-c-connector";
|
||||
reg = <0>;
|
||||
power-role = "dual";
|
||||
data-role = "dual";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
endpoint {
|
||||
remote-endpoint = <&usb_role>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
endpoint {
|
||||
remote-endpoint = <&ss_phy_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@2 {
|
||||
reg = <2>;
|
||||
endpoint {
|
||||
remote-endpoint = <&sbu_mux>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
@ -112,8 +112,9 @@ properties:
|
|||
$ref: /schemas/power/qcom,rpmpd.yaml#
|
||||
|
||||
patternProperties:
|
||||
'-regulators$':
|
||||
'^regulators(-[0-9])?$':
|
||||
$ref: /schemas/regulator/qcom,rpmh-regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
|
11
MAINTAINERS
11
MAINTAINERS
|
@ -5821,14 +5821,6 @@ W: http://lists.twibble.org/mailman/listinfo/dc395x/
|
|||
F: Documentation/scsi/dc395x.rst
|
||||
F: drivers/scsi/dc395x.*
|
||||
|
||||
DCC QTI DRIVER
|
||||
M: Souradeep Chowdhury <quic_schowdhu@quicinc.com>
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/ABI/testing/debugfs-driver-dcc
|
||||
F: Documentation/devicetree/bindings/soc/qcom/qcom,dcc.yaml
|
||||
F: drivers/soc/qcom/dcc.c
|
||||
|
||||
DCCP PROTOCOL
|
||||
L: dccp@vger.kernel.org
|
||||
S: Orphan
|
||||
|
@ -17263,7 +17255,8 @@ F: drivers/clk/qcom/
|
|||
F: include/dt-bindings/clock/qcom,*
|
||||
|
||||
QUALCOMM CORE POWER REDUCTION (CPR) AVS DRIVER
|
||||
M: Niklas Cassel <nks@flawful.org>
|
||||
M: Bjorn Andersson <andersson@kernel.org>
|
||||
M: Konrad Dybcio <konrad.dybcio@linaro.org>
|
||||
L: linux-pm@vger.kernel.org
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
S: Maintained
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include <linux/of_address.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/qcom_scm.h>
|
||||
#include <linux/firmware/qcom/qcom_scm.h>
|
||||
|
||||
#include <asm/smp_plat.h>
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include <linux/platform_device.h>
|
||||
#include <linux/cpuidle.h>
|
||||
#include <linux/cpu_pm.h>
|
||||
#include <linux/qcom_scm.h>
|
||||
#include <linux/firmware/qcom/qcom_scm.h>
|
||||
#include <soc/qcom/spm.h>
|
||||
|
||||
#include <asm/proc-fns.h>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include <linux/mutex.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/qcom_scm.h>
|
||||
#include <linux/firmware/qcom/qcom_scm.h>
|
||||
#include <linux/arm-smccc.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include <linux/mutex.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/qcom_scm.h>
|
||||
#include <linux/firmware/qcom/qcom_scm.h>
|
||||
#include <linux/arm-smccc.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include <linux/interconnect.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/qcom_scm.h>
|
||||
#include <linux/firmware/qcom/qcom_scm.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_irq.h>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/cpumask.h>
|
||||
#include <linux/qcom_scm.h>
|
||||
#include <linux/firmware/qcom/qcom_scm.h>
|
||||
#include <linux/pm_opp.h>
|
||||
#include <linux/nvmem-consumer.h>
|
||||
#include <linux/slab.h>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include <linux/ascii85.h>
|
||||
#include <linux/interconnect.h>
|
||||
#include <linux/qcom_scm.h>
|
||||
#include <linux/firmware/qcom/qcom_scm.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/pm_opp.h>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*/
|
||||
|
||||
#include "hdmi.h"
|
||||
#include <linux/qcom_scm.h>
|
||||
#include <linux/firmware/qcom/qcom_scm.h>
|
||||
|
||||
#define HDCP_REG_ENABLE 0x01
|
||||
#define HDCP_REG_DISABLE 0x00
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/qcom_scm.h>
|
||||
#include <linux/firmware/qcom/qcom_scm.h>
|
||||
#include <linux/ratelimit.h>
|
||||
|
||||
#include "arm-smmu.h"
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include <linux/adreno-smmu-priv.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/qcom_scm.h>
|
||||
#include <linux/firmware/qcom/qcom_scm.h>
|
||||
|
||||
#include "arm-smmu.h"
|
||||
#include "arm-smmu-qcom.h"
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include <linux/platform_device.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/qcom_scm.h>
|
||||
#include <linux/firmware/qcom/qcom_scm.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include <linux/of_address.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/qcom_scm.h>
|
||||
#include <linux/firmware/qcom/qcom_scm.h>
|
||||
#include <linux/sizes.h>
|
||||
#include <linux/soc/qcom/mdt_loader.h>
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include <linux/rpmsg.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/qcom_scm.h>
|
||||
#include <linux/firmware/qcom/qcom_scm.h>
|
||||
#include <uapi/misc/fastrpc.h>
|
||||
#include <linux/of_reserved_mem.h>
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include <linux/pm_opp.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/qcom_scm.h>
|
||||
#include <linux/firmware/qcom/qcom_scm.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/interconnect.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include <linux/of_device.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/qcom_scm.h>
|
||||
#include <linux/firmware/qcom/qcom_scm.h>
|
||||
#include <linux/soc/qcom/mdt_loader.h>
|
||||
|
||||
#include "ipa.h"
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/net.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/qcom_scm.h>
|
||||
#include <linux/firmware/qcom/qcom_scm.h>
|
||||
#include <linux/soc/qcom/smem.h>
|
||||
#include <linux/string.h>
|
||||
#include <net/sock.h>
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/qcom_scm.h>
|
||||
#include <linux/firmware/qcom/qcom_scm.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/slab.h>
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include "qcom_pil_info.h"
|
||||
#include "qcom_q6v5.h"
|
||||
|
||||
#include <linux/qcom_scm.h>
|
||||
#include <linux/firmware/qcom/qcom_scm.h>
|
||||
|
||||
#define MPSS_CRASH_REASON_SMEM 421
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_domain.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/qcom_scm.h>
|
||||
#include <linux/firmware/qcom/qcom_scm.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/remoteproc.h>
|
||||
#include <linux/soc/qcom/mdt_loader.h>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_domain.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/qcom_scm.h>
|
||||
#include <linux/firmware/qcom/qcom_scm.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/remoteproc.h>
|
||||
#include <linux/soc/qcom/mdt_loader.h>
|
||||
|
|
|
@ -70,14 +70,6 @@ config QCOM_LLCC
|
|||
SDM845. This provides interfaces to clients that use the LLCC.
|
||||
Say yes here to enable LLCC slice driver.
|
||||
|
||||
config QCOM_DCC
|
||||
tristate "Qualcomm Technologies, Inc. Data Capture and Compare(DCC) engine driver"
|
||||
depends on ARCH_QCOM || COMPILE_TEST
|
||||
help
|
||||
This option enables driver for Data Capture and Compare engine. DCC
|
||||
driver provides interface to configure DCC block and read back
|
||||
captured data from DCC's internal SRAM.
|
||||
|
||||
config QCOM_KRYO_L2_ACCESSORS
|
||||
bool
|
||||
depends on ARCH_QCOM && ARM64 || COMPILE_TEST
|
||||
|
@ -99,6 +91,24 @@ config QCOM_OCMEM
|
|||
config QCOM_PDR_HELPERS
|
||||
tristate
|
||||
select QCOM_QMI_HELPERS
|
||||
depends on NET
|
||||
|
||||
config QCOM_PMIC_GLINK
|
||||
tristate "Qualcomm PMIC GLINK driver"
|
||||
depends on RPMSG
|
||||
depends on TYPEC
|
||||
depends on DRM
|
||||
depends on NET
|
||||
depends on OF
|
||||
select AUXILIARY_BUS
|
||||
select QCOM_PDR_HELPERS
|
||||
help
|
||||
The Qualcomm PMIC GLINK driver provides access, over GLINK, to the
|
||||
USB and battery firmware running on one of the coprocessors in
|
||||
several modern Qualcomm platforms.
|
||||
|
||||
Say yes here to support USB-C and battery status on modern Qualcomm
|
||||
platforms.
|
||||
|
||||
config QCOM_QMI_HELPERS
|
||||
tristate
|
||||
|
|
|
@ -4,11 +4,12 @@ obj-$(CONFIG_QCOM_AOSS_QMP) += qcom_aoss.o
|
|||
obj-$(CONFIG_QCOM_GENI_SE) += qcom-geni-se.o
|
||||
obj-$(CONFIG_QCOM_COMMAND_DB) += cmd-db.o
|
||||
obj-$(CONFIG_QCOM_CPR) += cpr.o
|
||||
obj-$(CONFIG_QCOM_DCC) += dcc.o
|
||||
obj-$(CONFIG_QCOM_GSBI) += qcom_gsbi.o
|
||||
obj-$(CONFIG_QCOM_MDT_LOADER) += mdt_loader.o
|
||||
obj-$(CONFIG_QCOM_OCMEM) += ocmem.o
|
||||
obj-$(CONFIG_QCOM_PDR_HELPERS) += pdr_interface.o
|
||||
obj-$(CONFIG_QCOM_PMIC_GLINK) += pmic_glink.o
|
||||
obj-$(CONFIG_QCOM_PMIC_GLINK) += pmic_glink_altmode.o
|
||||
obj-$(CONFIG_QCOM_QMI_HELPERS) += qmi_helpers.o
|
||||
qmi_helpers-y += qmi_encdec.o qmi_interface.o
|
||||
obj-$(CONFIG_QCOM_RAMP_CTRL) += ramp_controller.o
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -12,7 +12,7 @@
|
|||
#include <linux/firmware.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/qcom_scm.h>
|
||||
#include <linux/firmware/qcom/qcom_scm.h>
|
||||
#include <linux/sizes.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/soc/qcom/mdt_loader.h>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/qcom_scm.h>
|
||||
#include <linux/firmware/qcom/qcom_scm.h>
|
||||
#include <linux/sizes.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
|
|
|
@ -0,0 +1,336 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022, Linaro Ltd
|
||||
*/
|
||||
#include <linux/auxiliary_bus.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/rpmsg.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/soc/qcom/pdr.h>
|
||||
#include <linux/soc/qcom/pmic_glink.h>
|
||||
|
||||
struct pmic_glink {
|
||||
struct device *dev;
|
||||
struct pdr_handle *pdr;
|
||||
|
||||
struct rpmsg_endpoint *ept;
|
||||
|
||||
struct auxiliary_device altmode_aux;
|
||||
struct auxiliary_device ps_aux;
|
||||
struct auxiliary_device ucsi_aux;
|
||||
|
||||
/* serializing client_state and pdr_state updates */
|
||||
struct mutex state_lock;
|
||||
unsigned int client_state;
|
||||
unsigned int pdr_state;
|
||||
|
||||
/* serializing clients list updates */
|
||||
struct mutex client_lock;
|
||||
struct list_head clients;
|
||||
};
|
||||
|
||||
static struct pmic_glink *__pmic_glink;
|
||||
static DEFINE_MUTEX(__pmic_glink_lock);
|
||||
|
||||
struct pmic_glink_client {
|
||||
struct list_head node;
|
||||
|
||||
struct pmic_glink *pg;
|
||||
unsigned int id;
|
||||
|
||||
void (*cb)(const void *data, size_t len, void *priv);
|
||||
void (*pdr_notify)(void *priv, int state);
|
||||
void *priv;
|
||||
};
|
||||
|
||||
static void _devm_pmic_glink_release_client(struct device *dev, void *res)
|
||||
{
|
||||
struct pmic_glink_client *client = (struct pmic_glink_client *)res;
|
||||
struct pmic_glink *pg = client->pg;
|
||||
|
||||
mutex_lock(&pg->client_lock);
|
||||
list_del(&client->node);
|
||||
mutex_unlock(&pg->client_lock);
|
||||
}
|
||||
|
||||
struct pmic_glink_client *devm_pmic_glink_register_client(struct device *dev,
|
||||
unsigned int id,
|
||||
void (*cb)(const void *, size_t, void *),
|
||||
void (*pdr)(void *, int),
|
||||
void *priv)
|
||||
{
|
||||
struct pmic_glink_client *client;
|
||||
struct pmic_glink *pg = dev_get_drvdata(dev->parent);
|
||||
|
||||
client = devres_alloc(_devm_pmic_glink_release_client, sizeof(*client), GFP_KERNEL);
|
||||
if (!client)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
client->pg = pg;
|
||||
client->id = id;
|
||||
client->cb = cb;
|
||||
client->pdr_notify = pdr;
|
||||
client->priv = priv;
|
||||
|
||||
mutex_lock(&pg->client_lock);
|
||||
list_add(&client->node, &pg->clients);
|
||||
mutex_unlock(&pg->client_lock);
|
||||
|
||||
devres_add(dev, client);
|
||||
|
||||
return client;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_pmic_glink_register_client);
|
||||
|
||||
int pmic_glink_send(struct pmic_glink_client *client, void *data, size_t len)
|
||||
{
|
||||
struct pmic_glink *pg = client->pg;
|
||||
|
||||
return rpmsg_send(pg->ept, data, len);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pmic_glink_send);
|
||||
|
||||
static int pmic_glink_rpmsg_callback(struct rpmsg_device *rpdev, void *data,
|
||||
int len, void *priv, u32 addr)
|
||||
{
|
||||
struct pmic_glink_client *client;
|
||||
struct pmic_glink_hdr *hdr;
|
||||
struct pmic_glink *pg = dev_get_drvdata(&rpdev->dev);
|
||||
|
||||
if (len < sizeof(*hdr)) {
|
||||
dev_warn(pg->dev, "ignoring truncated message\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
hdr = data;
|
||||
|
||||
list_for_each_entry(client, &pg->clients, node) {
|
||||
if (client->id == le32_to_cpu(hdr->owner))
|
||||
client->cb(data, len, client->priv);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pmic_glink_aux_release(struct device *dev) {}
|
||||
|
||||
static int pmic_glink_add_aux_device(struct pmic_glink *pg,
|
||||
struct auxiliary_device *aux,
|
||||
const char *name)
|
||||
{
|
||||
struct device *parent = pg->dev;
|
||||
int ret;
|
||||
|
||||
aux->name = name;
|
||||
aux->dev.parent = parent;
|
||||
aux->dev.release = pmic_glink_aux_release;
|
||||
device_set_of_node_from_dev(&aux->dev, parent);
|
||||
ret = auxiliary_device_init(aux);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = auxiliary_device_add(aux);
|
||||
if (ret)
|
||||
auxiliary_device_uninit(aux);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void pmic_glink_del_aux_device(struct pmic_glink *pg,
|
||||
struct auxiliary_device *aux)
|
||||
{
|
||||
auxiliary_device_delete(aux);
|
||||
auxiliary_device_uninit(aux);
|
||||
}
|
||||
|
||||
static void pmic_glink_state_notify_clients(struct pmic_glink *pg)
|
||||
{
|
||||
struct pmic_glink_client *client;
|
||||
unsigned int new_state = pg->client_state;
|
||||
|
||||
if (pg->client_state != SERVREG_SERVICE_STATE_UP) {
|
||||
if (pg->pdr_state == SERVREG_SERVICE_STATE_UP && pg->ept)
|
||||
new_state = SERVREG_SERVICE_STATE_UP;
|
||||
} else {
|
||||
if (pg->pdr_state == SERVREG_SERVICE_STATE_UP && pg->ept)
|
||||
new_state = SERVREG_SERVICE_STATE_DOWN;
|
||||
}
|
||||
|
||||
if (new_state != pg->client_state) {
|
||||
list_for_each_entry(client, &pg->clients, node)
|
||||
client->pdr_notify(client->priv, new_state);
|
||||
pg->client_state = new_state;
|
||||
}
|
||||
}
|
||||
|
||||
static void pmic_glink_pdr_callback(int state, char *svc_path, void *priv)
|
||||
{
|
||||
struct pmic_glink *pg = priv;
|
||||
|
||||
mutex_lock(&pg->state_lock);
|
||||
pg->pdr_state = state;
|
||||
|
||||
pmic_glink_state_notify_clients(pg);
|
||||
mutex_unlock(&pg->state_lock);
|
||||
}
|
||||
|
||||
static int pmic_glink_rpmsg_probe(struct rpmsg_device *rpdev)
|
||||
{
|
||||
struct pmic_glink *pg = __pmic_glink;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&__pmic_glink_lock);
|
||||
if (!pg) {
|
||||
ret = dev_err_probe(&rpdev->dev, -ENODEV, "no pmic_glink device to attach to\n");
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
dev_set_drvdata(&rpdev->dev, pg);
|
||||
|
||||
mutex_lock(&pg->state_lock);
|
||||
pg->ept = rpdev->ept;
|
||||
pmic_glink_state_notify_clients(pg);
|
||||
mutex_unlock(&pg->state_lock);
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&__pmic_glink_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void pmic_glink_rpmsg_remove(struct rpmsg_device *rpdev)
|
||||
{
|
||||
struct pmic_glink *pg;
|
||||
|
||||
mutex_lock(&__pmic_glink_lock);
|
||||
pg = __pmic_glink;
|
||||
if (!pg)
|
||||
goto out_unlock;
|
||||
|
||||
mutex_lock(&pg->state_lock);
|
||||
pg->ept = NULL;
|
||||
pmic_glink_state_notify_clients(pg);
|
||||
mutex_unlock(&pg->state_lock);
|
||||
out_unlock:
|
||||
mutex_unlock(&__pmic_glink_lock);
|
||||
}
|
||||
|
||||
static const struct rpmsg_device_id pmic_glink_rpmsg_id_match[] = {
|
||||
{ "PMIC_RTR_ADSP_APPS" },
|
||||
{}
|
||||
};
|
||||
|
||||
static struct rpmsg_driver pmic_glink_rpmsg_driver = {
|
||||
.probe = pmic_glink_rpmsg_probe,
|
||||
.remove = pmic_glink_rpmsg_remove,
|
||||
.callback = pmic_glink_rpmsg_callback,
|
||||
.id_table = pmic_glink_rpmsg_id_match,
|
||||
.drv = {
|
||||
.name = "qcom_pmic_glink_rpmsg",
|
||||
},
|
||||
};
|
||||
|
||||
static int pmic_glink_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct pdr_service *service;
|
||||
struct pmic_glink *pg;
|
||||
int ret;
|
||||
|
||||
pg = devm_kzalloc(&pdev->dev, sizeof(*pg), GFP_KERNEL);
|
||||
if (!pg)
|
||||
return -ENOMEM;
|
||||
|
||||
dev_set_drvdata(&pdev->dev, pg);
|
||||
|
||||
pg->dev = &pdev->dev;
|
||||
|
||||
INIT_LIST_HEAD(&pg->clients);
|
||||
mutex_init(&pg->client_lock);
|
||||
mutex_init(&pg->state_lock);
|
||||
|
||||
ret = pmic_glink_add_aux_device(pg, &pg->altmode_aux, "altmode");
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = pmic_glink_add_aux_device(pg, &pg->ps_aux, "power-supply");
|
||||
if (ret)
|
||||
goto out_release_altmode_aux;
|
||||
|
||||
pg->pdr = pdr_handle_alloc(pmic_glink_pdr_callback, pg);
|
||||
if (IS_ERR(pg->pdr)) {
|
||||
ret = dev_err_probe(&pdev->dev, PTR_ERR(pg->pdr), "failed to initialize pdr\n");
|
||||
goto out_release_aux_devices;
|
||||
}
|
||||
|
||||
service = pdr_add_lookup(pg->pdr, "tms/servreg", "msm/adsp/charger_pd");
|
||||
if (IS_ERR(service)) {
|
||||
ret = dev_err_probe(&pdev->dev, PTR_ERR(service),
|
||||
"failed adding pdr lookup for charger_pd\n");
|
||||
goto out_release_pdr_handle;
|
||||
}
|
||||
|
||||
mutex_lock(&__pmic_glink_lock);
|
||||
__pmic_glink = pg;
|
||||
mutex_unlock(&__pmic_glink_lock);
|
||||
|
||||
return 0;
|
||||
|
||||
out_release_pdr_handle:
|
||||
pdr_handle_release(pg->pdr);
|
||||
out_release_aux_devices:
|
||||
pmic_glink_del_aux_device(pg, &pg->ps_aux);
|
||||
out_release_altmode_aux:
|
||||
pmic_glink_del_aux_device(pg, &pg->altmode_aux);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pmic_glink_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct pmic_glink *pg = dev_get_drvdata(&pdev->dev);
|
||||
|
||||
pdr_handle_release(pg->pdr);
|
||||
|
||||
pmic_glink_del_aux_device(pg, &pg->ps_aux);
|
||||
pmic_glink_del_aux_device(pg, &pg->altmode_aux);
|
||||
|
||||
mutex_lock(&__pmic_glink_lock);
|
||||
__pmic_glink = NULL;
|
||||
mutex_unlock(&__pmic_glink_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id pmic_glink_of_match[] = {
|
||||
{ .compatible = "qcom,pmic-glink", },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, pmic_glink_of_match);
|
||||
|
||||
static struct platform_driver pmic_glink_driver = {
|
||||
.probe = pmic_glink_probe,
|
||||
.remove = pmic_glink_remove,
|
||||
.driver = {
|
||||
.name = "qcom_pmic_glink",
|
||||
.of_match_table = pmic_glink_of_match,
|
||||
},
|
||||
};
|
||||
|
||||
static int pmic_glink_init(void)
|
||||
{
|
||||
platform_driver_register(&pmic_glink_driver);
|
||||
register_rpmsg_driver(&pmic_glink_rpmsg_driver);
|
||||
|
||||
return 0;
|
||||
};
|
||||
module_init(pmic_glink_init);
|
||||
|
||||
static void pmic_glink_exit(void)
|
||||
{
|
||||
unregister_rpmsg_driver(&pmic_glink_rpmsg_driver);
|
||||
platform_driver_unregister(&pmic_glink_driver);
|
||||
};
|
||||
module_exit(pmic_glink_exit);
|
||||
|
||||
MODULE_DESCRIPTION("Qualcomm PMIC GLINK driver");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -0,0 +1,478 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022, Linaro Ltd
|
||||
*/
|
||||
#include <linux/auxiliary_bus.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/soc/qcom/pdr.h>
|
||||
#include <drm/drm_bridge.h>
|
||||
|
||||
#include <linux/usb/typec_altmode.h>
|
||||
#include <linux/usb/typec_dp.h>
|
||||
#include <linux/usb/typec_mux.h>
|
||||
|
||||
#include <linux/soc/qcom/pmic_glink.h>
|
||||
|
||||
#define PMIC_GLINK_MAX_PORTS 2
|
||||
|
||||
#define USBC_SC8180X_NOTIFY_IND 0x13
|
||||
#define USBC_CMD_WRITE_REQ 0x15
|
||||
#define USBC_NOTIFY_IND 0x16
|
||||
|
||||
#define ALTMODE_PAN_EN 0x10
|
||||
#define ALTMODE_PAN_ACK 0x11
|
||||
|
||||
struct usbc_write_req {
|
||||
struct pmic_glink_hdr hdr;
|
||||
__le32 cmd;
|
||||
__le32 arg;
|
||||
__le32 reserved;
|
||||
};
|
||||
|
||||
#define NOTIFY_PAYLOAD_SIZE 16
|
||||
struct usbc_notify {
|
||||
struct pmic_glink_hdr hdr;
|
||||
char payload[NOTIFY_PAYLOAD_SIZE];
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct usbc_sc8180x_notify {
|
||||
struct pmic_glink_hdr hdr;
|
||||
__le32 notification;
|
||||
__le32 reserved[2];
|
||||
};
|
||||
|
||||
enum pmic_glink_altmode_pin_assignment {
|
||||
DPAM_HPD_OUT,
|
||||
DPAM_HPD_A,
|
||||
DPAM_HPD_B,
|
||||
DPAM_HPD_C,
|
||||
DPAM_HPD_D,
|
||||
DPAM_HPD_E,
|
||||
DPAM_HPD_F,
|
||||
};
|
||||
|
||||
struct pmic_glink_altmode;
|
||||
|
||||
#define work_to_altmode_port(w) container_of((w), struct pmic_glink_altmode_port, work)
|
||||
|
||||
struct pmic_glink_altmode_port {
|
||||
struct pmic_glink_altmode *altmode;
|
||||
unsigned int index;
|
||||
|
||||
struct typec_switch *typec_switch;
|
||||
struct typec_mux *typec_mux;
|
||||
struct typec_mux_state state;
|
||||
struct typec_altmode dp_alt;
|
||||
|
||||
struct work_struct work;
|
||||
|
||||
struct drm_bridge bridge;
|
||||
|
||||
enum typec_orientation orientation;
|
||||
u16 svid;
|
||||
u8 dp_data;
|
||||
u8 mode;
|
||||
u8 hpd_state;
|
||||
u8 hpd_irq;
|
||||
};
|
||||
|
||||
#define work_to_altmode(w) container_of((w), struct pmic_glink_altmode, enable_work)
|
||||
|
||||
struct pmic_glink_altmode {
|
||||
struct device *dev;
|
||||
|
||||
unsigned int owner_id;
|
||||
|
||||
/* To synchronize WRITE_REQ acks */
|
||||
struct mutex lock;
|
||||
|
||||
struct completion pan_ack;
|
||||
struct pmic_glink_client *client;
|
||||
|
||||
struct work_struct enable_work;
|
||||
|
||||
struct pmic_glink_altmode_port ports[PMIC_GLINK_MAX_PORTS];
|
||||
};
|
||||
|
||||
static int pmic_glink_altmode_request(struct pmic_glink_altmode *altmode, u32 cmd, u32 arg)
|
||||
{
|
||||
struct usbc_write_req req = {};
|
||||
unsigned long left;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* The USBC_CMD_WRITE_REQ ack doesn't identify the request, so wait for
|
||||
* one ack at a time.
|
||||
*/
|
||||
mutex_lock(&altmode->lock);
|
||||
|
||||
req.hdr.owner = cpu_to_le32(altmode->owner_id);
|
||||
req.hdr.type = cpu_to_le32(PMIC_GLINK_REQ_RESP);
|
||||
req.hdr.opcode = cpu_to_le32(USBC_CMD_WRITE_REQ);
|
||||
req.cmd = cpu_to_le32(cmd);
|
||||
req.arg = cpu_to_le32(arg);
|
||||
|
||||
ret = pmic_glink_send(altmode->client, &req, sizeof(req));
|
||||
if (ret) {
|
||||
dev_err(altmode->dev, "failed to send altmode request: %#x (%d)\n", cmd, ret);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
left = wait_for_completion_timeout(&altmode->pan_ack, 5 * HZ);
|
||||
if (!left) {
|
||||
dev_err(altmode->dev, "timeout waiting for altmode request ack for: %#x\n", cmd);
|
||||
ret = -ETIMEDOUT;
|
||||
}
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&altmode->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void pmic_glink_altmode_enable_dp(struct pmic_glink_altmode *altmode,
|
||||
struct pmic_glink_altmode_port *port,
|
||||
u8 mode, bool hpd_state,
|
||||
bool hpd_irq)
|
||||
{
|
||||
struct typec_displayport_data dp_data = {};
|
||||
int ret;
|
||||
|
||||
dp_data.status = DP_STATUS_ENABLED;
|
||||
if (hpd_state)
|
||||
dp_data.status |= DP_STATUS_HPD_STATE;
|
||||
if (hpd_irq)
|
||||
dp_data.status |= DP_STATUS_IRQ_HPD;
|
||||
dp_data.conf = DP_CONF_SET_PIN_ASSIGN(mode);
|
||||
|
||||
port->state.alt = &port->dp_alt;
|
||||
port->state.data = &dp_data;
|
||||
port->state.mode = TYPEC_MODAL_STATE(mode);
|
||||
|
||||
ret = typec_mux_set(port->typec_mux, &port->state);
|
||||
if (ret)
|
||||
dev_err(altmode->dev, "failed to switch mux to DP\n");
|
||||
}
|
||||
|
||||
static void pmic_glink_altmode_enable_usb(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_USB;
|
||||
|
||||
ret = typec_mux_set(port->typec_mux, &port->state);
|
||||
if (ret)
|
||||
dev_err(altmode->dev, "failed to switch mux to USB\n");
|
||||
}
|
||||
|
||||
static void pmic_glink_altmode_worker(struct work_struct *work)
|
||||
{
|
||||
struct pmic_glink_altmode_port *alt_port = work_to_altmode_port(work);
|
||||
struct pmic_glink_altmode *altmode = alt_port->altmode;
|
||||
|
||||
typec_switch_set(alt_port->typec_switch, alt_port->orientation);
|
||||
|
||||
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
|
||||
pmic_glink_altmode_enable_usb(altmode, alt_port);
|
||||
|
||||
if (alt_port->hpd_state)
|
||||
drm_bridge_hpd_notify(&alt_port->bridge, connector_status_connected);
|
||||
else
|
||||
drm_bridge_hpd_notify(&alt_port->bridge, connector_status_disconnected);
|
||||
|
||||
pmic_glink_altmode_request(altmode, ALTMODE_PAN_ACK, alt_port->index);
|
||||
};
|
||||
|
||||
static enum typec_orientation pmic_glink_altmode_orientation(unsigned int orientation)
|
||||
{
|
||||
if (orientation == 0)
|
||||
return TYPEC_ORIENTATION_NORMAL;
|
||||
else if (orientation == 1)
|
||||
return TYPEC_ORIENTATION_REVERSE;
|
||||
else
|
||||
return TYPEC_ORIENTATION_NONE;
|
||||
}
|
||||
|
||||
#define SC8180X_PORT_MASK 0x000000ff
|
||||
#define SC8180X_ORIENTATION_MASK 0x0000ff00
|
||||
#define SC8180X_MUX_MASK 0x00ff0000
|
||||
#define SC8180X_MODE_MASK 0x3f000000
|
||||
#define SC8180X_HPD_STATE_MASK 0x40000000
|
||||
#define SC8180X_HPD_IRQ_MASK 0x80000000
|
||||
|
||||
static void pmic_glink_altmode_sc8180xp_notify(struct pmic_glink_altmode *altmode,
|
||||
const void *data, size_t len)
|
||||
{
|
||||
struct pmic_glink_altmode_port *alt_port;
|
||||
const struct usbc_sc8180x_notify *msg;
|
||||
u32 notification;
|
||||
u8 orientation;
|
||||
u8 hpd_state;
|
||||
u8 hpd_irq;
|
||||
u16 svid;
|
||||
u8 port;
|
||||
u8 mode;
|
||||
u8 mux;
|
||||
|
||||
if (len != sizeof(*msg)) {
|
||||
dev_warn(altmode->dev, "invalid length of USBC_NOTIFY indication: %zd\n", len);
|
||||
return;
|
||||
}
|
||||
|
||||
msg = data;
|
||||
notification = le32_to_cpu(msg->notification);
|
||||
port = FIELD_GET(SC8180X_PORT_MASK, notification);
|
||||
orientation = FIELD_GET(SC8180X_ORIENTATION_MASK, notification);
|
||||
mux = FIELD_GET(SC8180X_MUX_MASK, notification);
|
||||
mode = FIELD_GET(SC8180X_MODE_MASK, notification);
|
||||
hpd_state = FIELD_GET(SC8180X_HPD_STATE_MASK, notification);
|
||||
hpd_irq = FIELD_GET(SC8180X_HPD_IRQ_MASK, notification);
|
||||
|
||||
svid = mux == 2 ? USB_TYPEC_DP_SID : 0;
|
||||
|
||||
if (!altmode->ports[port].altmode) {
|
||||
dev_dbg(altmode->dev, "notification on undefined port %d\n", port);
|
||||
return;
|
||||
}
|
||||
|
||||
alt_port = &altmode->ports[port];
|
||||
alt_port->orientation = pmic_glink_altmode_orientation(orientation);
|
||||
alt_port->svid = svid;
|
||||
alt_port->mode = mode;
|
||||
alt_port->hpd_state = hpd_state;
|
||||
alt_port->hpd_irq = hpd_irq;
|
||||
schedule_work(&alt_port->work);
|
||||
}
|
||||
|
||||
#define SC8280XP_DPAM_MASK 0x3f
|
||||
#define SC8280XP_HPD_STATE_MASK BIT(6)
|
||||
#define SC8280XP_HPD_IRQ_MASK BIT(7)
|
||||
|
||||
static void pmic_glink_altmode_sc8280xp_notify(struct pmic_glink_altmode *altmode,
|
||||
u16 svid, const void *data, size_t len)
|
||||
{
|
||||
struct pmic_glink_altmode_port *alt_port;
|
||||
const struct usbc_notify *notify;
|
||||
u8 orientation;
|
||||
u8 hpd_state;
|
||||
u8 hpd_irq;
|
||||
u8 mode;
|
||||
u8 port;
|
||||
|
||||
if (len != sizeof(*notify)) {
|
||||
dev_warn(altmode->dev, "invalid length USBC_NOTIFY_IND: %zd\n",
|
||||
len);
|
||||
return;
|
||||
}
|
||||
|
||||
notify = data;
|
||||
|
||||
port = notify->payload[0];
|
||||
orientation = notify->payload[1];
|
||||
mode = FIELD_GET(SC8280XP_DPAM_MASK, notify->payload[8]) - DPAM_HPD_A;
|
||||
hpd_state = FIELD_GET(SC8280XP_HPD_STATE_MASK, notify->payload[8]);
|
||||
hpd_irq = FIELD_GET(SC8280XP_HPD_IRQ_MASK, notify->payload[8]);
|
||||
|
||||
if (!altmode->ports[port].altmode) {
|
||||
dev_dbg(altmode->dev, "notification on undefined port %d\n", port);
|
||||
return;
|
||||
}
|
||||
|
||||
alt_port = &altmode->ports[port];
|
||||
alt_port->orientation = pmic_glink_altmode_orientation(orientation);
|
||||
alt_port->svid = svid;
|
||||
alt_port->mode = mode;
|
||||
alt_port->hpd_state = hpd_state;
|
||||
alt_port->hpd_irq = hpd_irq;
|
||||
schedule_work(&alt_port->work);
|
||||
}
|
||||
|
||||
static void pmic_glink_altmode_callback(const void *data, size_t len, void *priv)
|
||||
{
|
||||
struct pmic_glink_altmode *altmode = priv;
|
||||
const struct pmic_glink_hdr *hdr = data;
|
||||
u16 opcode;
|
||||
u16 svid;
|
||||
|
||||
opcode = le32_to_cpu(hdr->opcode) & 0xff;
|
||||
svid = le32_to_cpu(hdr->opcode) >> 16;
|
||||
|
||||
switch (opcode) {
|
||||
case USBC_CMD_WRITE_REQ:
|
||||
complete(&altmode->pan_ack);
|
||||
break;
|
||||
case USBC_NOTIFY_IND:
|
||||
pmic_glink_altmode_sc8280xp_notify(altmode, svid, data, len);
|
||||
break;
|
||||
case USBC_SC8180X_NOTIFY_IND:
|
||||
pmic_glink_altmode_sc8180xp_notify(altmode, data, len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int pmic_glink_altmode_attach(struct drm_bridge *bridge,
|
||||
enum drm_bridge_attach_flags flags)
|
||||
{
|
||||
return flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR ? 0 : -EINVAL;
|
||||
}
|
||||
|
||||
static const struct drm_bridge_funcs pmic_glink_altmode_bridge_funcs = {
|
||||
.attach = pmic_glink_altmode_attach,
|
||||
};
|
||||
|
||||
static void pmic_glink_altmode_put_mux(void *data)
|
||||
{
|
||||
typec_mux_put(data);
|
||||
}
|
||||
|
||||
static void pmic_glink_altmode_put_switch(void *data)
|
||||
{
|
||||
typec_switch_put(data);
|
||||
}
|
||||
|
||||
static void pmic_glink_altmode_enable_worker(struct work_struct *work)
|
||||
{
|
||||
struct pmic_glink_altmode *altmode = work_to_altmode(work);
|
||||
int ret;
|
||||
|
||||
ret = pmic_glink_altmode_request(altmode, ALTMODE_PAN_EN, 0);
|
||||
if (ret)
|
||||
dev_err(altmode->dev, "failed to request altmode notifications\n");
|
||||
}
|
||||
|
||||
static void pmic_glink_altmode_pdr_notify(void *priv, int state)
|
||||
{
|
||||
struct pmic_glink_altmode *altmode = priv;
|
||||
|
||||
if (state == SERVREG_SERVICE_STATE_UP)
|
||||
schedule_work(&altmode->enable_work);
|
||||
}
|
||||
|
||||
static const struct of_device_id pmic_glink_altmode_of_quirks[] = {
|
||||
{ .compatible = "qcom,sc8180x-pmic-glink", .data = (void *)PMIC_GLINK_OWNER_USBC },
|
||||
{}
|
||||
};
|
||||
|
||||
static int pmic_glink_altmode_probe(struct auxiliary_device *adev,
|
||||
const struct auxiliary_device_id *id)
|
||||
{
|
||||
struct pmic_glink_altmode_port *alt_port;
|
||||
struct pmic_glink_altmode *altmode;
|
||||
struct typec_altmode_desc mux_desc = {};
|
||||
const struct of_device_id *match;
|
||||
struct fwnode_handle *fwnode;
|
||||
struct device *dev = &adev->dev;
|
||||
u32 port;
|
||||
int ret;
|
||||
|
||||
altmode = devm_kzalloc(dev, sizeof(*altmode), GFP_KERNEL);
|
||||
if (!altmode)
|
||||
return -ENOMEM;
|
||||
|
||||
altmode->dev = dev;
|
||||
|
||||
match = of_match_device(pmic_glink_altmode_of_quirks, dev->parent);
|
||||
if (match)
|
||||
altmode->owner_id = (unsigned long)match->data;
|
||||
else
|
||||
altmode->owner_id = PMIC_GLINK_OWNER_USBC_PAN;
|
||||
|
||||
INIT_WORK(&altmode->enable_work, pmic_glink_altmode_enable_worker);
|
||||
init_completion(&altmode->pan_ack);
|
||||
mutex_init(&altmode->lock);
|
||||
|
||||
device_for_each_child_node(dev, fwnode) {
|
||||
ret = fwnode_property_read_u32(fwnode, "reg", &port);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "missing reg property of %pOFn\n", fwnode);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (port >= ARRAY_SIZE(altmode->ports)) {
|
||||
dev_warn(dev, "invalid connector number, ignoring\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (altmode->ports[port].altmode) {
|
||||
dev_err(dev, "multiple connector definition for port %u\n", port);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
alt_port = &altmode->ports[port];
|
||||
alt_port->altmode = altmode;
|
||||
alt_port->index = port;
|
||||
INIT_WORK(&alt_port->work, pmic_glink_altmode_worker);
|
||||
|
||||
alt_port->bridge.funcs = &pmic_glink_altmode_bridge_funcs;
|
||||
alt_port->bridge.of_node = to_of_node(fwnode);
|
||||
alt_port->bridge.ops = DRM_BRIDGE_OP_HPD;
|
||||
alt_port->bridge.type = DRM_MODE_CONNECTOR_USB;
|
||||
|
||||
ret = devm_drm_bridge_add(dev, &alt_port->bridge);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
alt_port->dp_alt.svid = USB_TYPEC_DP_SID;
|
||||
alt_port->dp_alt.mode = USB_TYPEC_DP_MODE;
|
||||
alt_port->dp_alt.active = 1;
|
||||
|
||||
mux_desc.svid = USB_TYPEC_DP_SID;
|
||||
mux_desc.mode = USB_TYPEC_DP_MODE;
|
||||
alt_port->typec_mux = fwnode_typec_mux_get(fwnode, &mux_desc);
|
||||
if (IS_ERR(alt_port->typec_mux))
|
||||
return dev_err_probe(dev, PTR_ERR(alt_port->typec_mux),
|
||||
"failed to acquire mode-switch for port: %d\n",
|
||||
port);
|
||||
|
||||
ret = devm_add_action_or_reset(dev, pmic_glink_altmode_put_mux,
|
||||
alt_port->typec_mux);
|
||||
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),
|
||||
"failed to acquire orientation-switch for port: %d\n",
|
||||
port);
|
||||
|
||||
ret = devm_add_action_or_reset(dev, pmic_glink_altmode_put_switch,
|
||||
alt_port->typec_switch);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
altmode->client = devm_pmic_glink_register_client(dev,
|
||||
altmode->owner_id,
|
||||
pmic_glink_altmode_callback,
|
||||
pmic_glink_altmode_pdr_notify,
|
||||
altmode);
|
||||
return PTR_ERR_OR_ZERO(altmode->client);
|
||||
}
|
||||
|
||||
static const struct auxiliary_device_id pmic_glink_altmode_id_table[] = {
|
||||
{ .name = "pmic_glink.altmode", },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(auxiliary, pmic_glink_altmode_id_table);
|
||||
|
||||
static struct auxiliary_driver pmic_glink_altmode_driver = {
|
||||
.name = "pmic_glink_altmode",
|
||||
.probe = pmic_glink_altmode_probe,
|
||||
.id_table = pmic_glink_altmode_id_table,
|
||||
};
|
||||
|
||||
module_auxiliary_driver(pmic_glink_altmode_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Qualcomm PMIC GLINK Altmode driver");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -92,7 +92,7 @@ static int qcom_subsystem_sleep_stats_show(struct seq_file *s, void *unused)
|
|||
/* Items are allocated lazily, so lookup pointer each time */
|
||||
stat = qcom_smem_get(subsystem->pid, subsystem->smem_item, NULL);
|
||||
if (IS_ERR(stat))
|
||||
return -EIO;
|
||||
return 0;
|
||||
|
||||
qcom_print_stats(s, stat);
|
||||
|
||||
|
@ -170,20 +170,14 @@ static void qcom_create_soc_sleep_stat_files(struct dentry *root, void __iomem *
|
|||
static void qcom_create_subsystem_stat_files(struct dentry *root,
|
||||
const struct stats_config *config)
|
||||
{
|
||||
const struct sleep_stats *stat;
|
||||
int i;
|
||||
|
||||
if (!config->subsystem_stats_in_smem)
|
||||
return;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(subsystems); i++) {
|
||||
stat = qcom_smem_get(subsystems[i].pid, subsystems[i].smem_item, NULL);
|
||||
if (IS_ERR(stat))
|
||||
continue;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(subsystems); i++)
|
||||
debugfs_create_file(subsystems[i].name, 0400, root, (void *)&subsystems[i],
|
||||
&qcom_subsystem_sleep_stats_fops);
|
||||
}
|
||||
}
|
||||
|
||||
static int qcom_stats_probe(struct platform_device *pdev)
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/qcom_scm.h>
|
||||
#include <linux/firmware/qcom/qcom_scm.h>
|
||||
|
||||
#define QCOM_RMTFS_MEM_DEV_MAX (MINORMASK + 1)
|
||||
#define NUM_MAX_VMIDS 2
|
||||
|
|
|
@ -233,6 +233,7 @@ static void qcom_smd_rpm_remove(struct rpmsg_device *rpdev)
|
|||
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" },
|
||||
|
|
|
@ -174,6 +174,8 @@ struct socinfo {
|
|||
__le32 pcode;
|
||||
__le32 npartnamemap_offset;
|
||||
__le32 nnum_partname_mapping;
|
||||
/* Version 17 */
|
||||
__le32 oem_variant;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
|
@ -196,6 +198,7 @@ struct socinfo_params {
|
|||
u32 nmodem_supported;
|
||||
u32 feature_code;
|
||||
u32 pcode;
|
||||
u32 oem_variant;
|
||||
};
|
||||
|
||||
struct smem_image_version {
|
||||
|
@ -281,6 +284,10 @@ static const struct soc_id soc_id[] = {
|
|||
{ qcom_board_id(MSM8126) },
|
||||
{ qcom_board_id(APQ8026) },
|
||||
{ qcom_board_id(MSM8926) },
|
||||
{ qcom_board_id(IPQ8062) },
|
||||
{ qcom_board_id(IPQ8064) },
|
||||
{ qcom_board_id(IPQ8066) },
|
||||
{ qcom_board_id(IPQ8068) },
|
||||
{ qcom_board_id(MSM8326) },
|
||||
{ qcom_board_id(MSM8916) },
|
||||
{ qcom_board_id(MSM8994) },
|
||||
|
@ -336,6 +343,8 @@ static const struct soc_id soc_id[] = {
|
|||
{ qcom_board_id(MSM8609) },
|
||||
{ qcom_board_id(APQ8076) },
|
||||
{ qcom_board_id(MSM8976) },
|
||||
{ qcom_board_id(IPQ8065) },
|
||||
{ qcom_board_id(IPQ8069) },
|
||||
{ qcom_board_id(MDM9650) },
|
||||
{ qcom_board_id(MDM9655) },
|
||||
{ qcom_board_id(MDM9250) },
|
||||
|
@ -439,6 +448,8 @@ static const struct soc_id soc_id[] = {
|
|||
{ qcom_board_id(QRU1032) },
|
||||
{ qcom_board_id(QRU1052) },
|
||||
{ qcom_board_id(QRU1062) },
|
||||
{ qcom_board_id(IPQ5332) },
|
||||
{ qcom_board_id(IPQ5322) },
|
||||
};
|
||||
|
||||
static const char *socinfo_machine(struct device *dev, unsigned int id)
|
||||
|
@ -593,6 +604,11 @@ static void socinfo_debugfs_init(struct qcom_socinfo *qcom_socinfo,
|
|||
&qcom_socinfo->info.fmt);
|
||||
|
||||
switch (qcom_socinfo->info.fmt) {
|
||||
case SOCINFO_VERSION(0, 17):
|
||||
qcom_socinfo->info.oem_variant = __le32_to_cpu(info->oem_variant);
|
||||
debugfs_create_u32("oem_variant", 0444, qcom_socinfo->dbg_root,
|
||||
&qcom_socinfo->info.oem_variant);
|
||||
fallthrough;
|
||||
case SOCINFO_VERSION(0, 16):
|
||||
qcom_socinfo->info.feature_code = __le32_to_cpu(info->feature_code);
|
||||
qcom_socinfo->info.pcode = __le32_to_cpu(info->pcode);
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include <linux/platform_device.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/qcom_scm.h>
|
||||
#include <linux/firmware/qcom/qcom_scm.h>
|
||||
|
||||
#define LMH_NODE_DCVS 0x44435653
|
||||
#define LMH_CLUSTER0_NODE_ID 0x6370302D
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/qcom_scm.h>
|
||||
#include <linux/firmware/qcom/qcom_scm.h>
|
||||
|
||||
#include "ufs-qcom.h"
|
||||
|
||||
|
|
|
@ -71,6 +71,10 @@
|
|||
#define QCOM_ID_MSM8126 198
|
||||
#define QCOM_ID_APQ8026 199
|
||||
#define QCOM_ID_MSM8926 200
|
||||
#define QCOM_ID_IPQ8062 201
|
||||
#define QCOM_ID_IPQ8064 202
|
||||
#define QCOM_ID_IPQ8066 203
|
||||
#define QCOM_ID_IPQ8068 204
|
||||
#define QCOM_ID_MSM8326 205
|
||||
#define QCOM_ID_MSM8916 206
|
||||
#define QCOM_ID_MSM8994 207
|
||||
|
@ -127,6 +131,8 @@
|
|||
#define QCOM_ID_APQ8076 277
|
||||
#define QCOM_ID_MSM8976 278
|
||||
#define QCOM_ID_MDM9650 279
|
||||
#define QCOM_ID_IPQ8065 280
|
||||
#define QCOM_ID_IPQ8069 281
|
||||
#define QCOM_ID_MDM9655 283
|
||||
#define QCOM_ID_MDM9250 284
|
||||
#define QCOM_ID_MDM9255 285
|
||||
|
@ -229,6 +235,8 @@
|
|||
#define QCOM_ID_QRU1032 588
|
||||
#define QCOM_ID_QRU1052 589
|
||||
#define QCOM_ID_QRU1062 590
|
||||
#define QCOM_ID_IPQ5332 592
|
||||
#define QCOM_ID_IPQ5322 593
|
||||
|
||||
/*
|
||||
* The board type and revision information, used by Qualcomm bootloaders and
|
||||
|
|
|
@ -210,6 +210,7 @@
|
|||
#define RPMH_REGULATOR_LEVEL_RETENTION 16
|
||||
#define RPMH_REGULATOR_LEVEL_MIN_SVS 48
|
||||
#define RPMH_REGULATOR_LEVEL_LOW_SVS 64
|
||||
#define RPMH_REGULATOR_LEVEL_LOW_SVS_L1 80
|
||||
#define RPMH_REGULATOR_LEVEL_SVS 128
|
||||
#define RPMH_REGULATOR_LEVEL_SVS_L0 144
|
||||
#define RPMH_REGULATOR_LEVEL_SVS_L1 192
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2022, Linaro Ltd
|
||||
*/
|
||||
#ifndef __SOC_QCOM_PMIC_GLINK_H__
|
||||
#define __SOC_QCOM_PMIC_GLINK_H__
|
||||
|
||||
struct pmic_glink;
|
||||
struct pmic_glink_client;
|
||||
|
||||
#define PMIC_GLINK_OWNER_BATTMGR 32778
|
||||
#define PMIC_GLINK_OWNER_USBC 32779
|
||||
#define PMIC_GLINK_OWNER_USBC_PAN 32780
|
||||
|
||||
#define PMIC_GLINK_REQ_RESP 1
|
||||
#define PMIC_GLINK_NOTIFY 2
|
||||
|
||||
struct pmic_glink_hdr {
|
||||
__le32 owner;
|
||||
__le32 type;
|
||||
__le32 opcode;
|
||||
};
|
||||
|
||||
int pmic_glink_send(struct pmic_glink_client *client, void *data, size_t len);
|
||||
|
||||
struct pmic_glink_client *devm_pmic_glink_register_client(struct device *dev,
|
||||
unsigned int id,
|
||||
void (*cb)(const void *, size_t, void *),
|
||||
void (*pdr)(void *, int),
|
||||
void *priv);
|
||||
|
||||
#endif
|
Загрузка…
Ссылка в новой задаче