mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-23 04:34:11 +08:00
Qualcomm driver updates for v5.15
This fixes the "shared memory state machine" (SMSM) interrupt logic to avoid missing transitions happening while the interrupts are masked. SM6115 support is added to smd-rpm and rpmpd. The Qualcomm SCM firmware driver is once again made possible to compile and load as a kernel module. An out-of-bounds error related to the cooling devices of the AOSS driver is corrected. The binding is converted to YAML and a generic compatible is introduced to reduce the driver churn. The GENI wrapper gains a helper function used in I2C and SPI for switching the serial engine hardware to use the wrapper's DMA-engine. Lastly it contains a number of cleanups and smaller fixes for rpmhpd, socinfo, CPR, mdt_loader and the GENI DT binding. -----BEGIN PGP SIGNATURE----- iQJPBAABCAA5FiEEBd4DzF816k8JZtUlCx85Pw2ZrcUFAmEa29wbHGJqb3JuLmFu ZGVyc3NvbkBsaW5hcm8ub3JnAAoJEAsfOT8Nma3FFnMP/A2Od7JYhdjH7sfc3i3B 0zws88lT7XTo9KSMpLFrQg1Qzp3ELDMfVhS2CpsekZn1g7s6RGnbQrh2Mac9Yh4z +7e4YLhoMxEkdbEVvbVRIX4parFWD/KxUdkyXM8gKZntJzOFl6VY5V8aKi+7IO+/ CdWHvELDVXMe2LkBd3lKE1AlS2MjkohXpFKgRwkY4r2nVXwqYTdkfJvXdGdhECGr ld4ZIvIR6ERLmVpGvTxdU5W0z2xsLTbPYDPSv6mPkWqDYSOyXV3zABV1fSkH28ot wIoesHyI3vL4/LNIlHn+tcWj1Ou8hSzxZmxfq7cdKbkfwPLCWE5D8+HEO4kmbFiF 5Dds+oxvKSFpf/wppK7bUSEd9Q+dKsrFt2mdWy/sYRe1EaEv5sFBgE0rV3+c6ykL tptUEFlaB2si7PKSpKje8czHn4Akuc6BwT6xovZZ72K8CNz9D71etSkoNLLXa54d bJibw2eNTT1EOACC/FPBO9AS11Icm6wszn/dcaSwaSPGQ6cR3lvAwHqzDFMGHp+x L+iojgnZoHykFhQjGuGrI3yTHOpp0MCNxRoN7DlFwm7KLKVHqeqg+xHXtV9sJer8 iAhY/uepLRxc1oC5Z+Ejx1gABmKycXtzKQ9ecwTclrk66ampWQBlv5+Bxd5w/hux ZR96mJPmpk1WKOX3FAgdeaaP =88qN -----END PGP SIGNATURE----- gpgsig -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEo6/YBQwIrVS28WGKmmx57+YAGNkFAmEdDA4ACgkQmmx57+YA GNmAmw//WfdprWl2SJGfyojhDeeUq6ZeNesMFBabFss7Ar++szhyFSu3bqlyH6WC ZgPOZOJakKQq2EGKNm7RuEgeR8sEUs9czetNO8AqVy1szlhqnUKhG0OO+uLqRLQn Hvf1fc+uG3xeaFP0/Q/4fuG+GL1fnmXIJWl0nZFUGfWyQ3mxxm5fLq1DM27KAzP1 eKMqtCh3F0qHMWZTJd084LO2XXyUTVVBbXAQKX/IQmH6+BK3Q2YMToo/919HCnZs XfgcdKuB/fOfi1n+PgGNODdTJ/Uy10WkSALZHlzKfr77AUCs9+RWxdkogCmACJBs IhNoZ/6D6a6kCIEuaEjHtNsMAVoG0bYpaB9vFLhJgF4wfdCd+DuOXkCy9B7vI4/8 7/SKArKYrG1sPlhDGFaWZjWEFBCGycDDsHQ4T2ecZ5d3f+Kuimgx7NLYhKRHPI+9 8QVJwNbIGrNXjwIn6S0AeqDLoXIzMmAbNvuX1lFz0OyEkbgDYPSuUPmKYoKh0VL5 +aTPYANbKxfF7nIPxfN580yjQGZmJmctyhkqnavEB6HdNySO2/oM5F2uGRVdVKnv 5HaPLqWZf2PffjAg+bU3O3bBlYRdIpEaKaa1eHFIMTgK7nlcvFESWWtwg+IBKdqY JI3Kkg5PP3jxqxybzgFPE298vI1G6/so2A12HBi0dl28XheK+wM= =dS58 -----END PGP SIGNATURE----- Merge tag 'qcom-drivers-for-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux into arm/drivers Qualcomm driver updates for v5.15 This fixes the "shared memory state machine" (SMSM) interrupt logic to avoid missing transitions happening while the interrupts are masked. SM6115 support is added to smd-rpm and rpmpd. The Qualcomm SCM firmware driver is once again made possible to compile and load as a kernel module. An out-of-bounds error related to the cooling devices of the AOSS driver is corrected. The binding is converted to YAML and a generic compatible is introduced to reduce the driver churn. The GENI wrapper gains a helper function used in I2C and SPI for switching the serial engine hardware to use the wrapper's DMA-engine. Lastly it contains a number of cleanups and smaller fixes for rpmhpd, socinfo, CPR, mdt_loader and the GENI DT binding. * tag 'qcom-drivers-for-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux: soc: qcom: smsm: Fix missed interrupts if state changes while masked soc: qcom: smsm: Implement support for get_irqchip_state soc: qcom: mdt_loader: be more informative on errors dt-bindings: qcom: geni-se: document iommus soc: qcom: smd-rpm: Add SM6115 compatible soc: qcom: geni: Add support for gpi dma soc: qcom: geni: move GENI_IF_DISABLE_RO to common header PM: AVS: qcom-cpr: Use nvmem_cell_read_variable_le_u32() drivers: soc: qcom: rpmpd: Add SM6115 RPM Power Domains dt-bindings: power: rpmpd: Add SM6115 to rpmpd binding dt-bindings: soc: qcom: smd-rpm: Add SM6115 compatible soc: qcom: aoss: Fix the out of bound usage of cooling_devs firmware: qcom_scm: Allow qcom_scm driver to be loadable as a permenent module soc: qcom: socinfo: Don't print anything if nothing found soc: qcom: rpmhpd: Use corner in power_off soc: qcom: aoss: Add generic compatible dt-bindings: soc: qcom: aoss: Convert to YAML dt-bindings: soc: qcom: aoss: Add SC8180X and generic compatible firmware: qcom_scm: remove a duplicative condition firmware: qcom_scm: Mark string array const Link: https://lore.kernel.org/r/20210816214840.581244-1-bjorn.andersson@linaro.org Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
commit
5c785014b6
@ -30,6 +30,7 @@ properties:
|
||||
- qcom,sc8180x-rpmhpd
|
||||
- qcom,sdm845-rpmhpd
|
||||
- qcom,sdx55-rpmhpd
|
||||
- qcom,sm6115-rpmpd
|
||||
- qcom,sm8150-rpmhpd
|
||||
- qcom,sm8250-rpmhpd
|
||||
- qcom,sm8350-rpmhpd
|
||||
|
@ -1,87 +0,0 @@
|
||||
Qualcomm Always-On Subsystem side channel binding
|
||||
|
||||
This binding describes the hardware component responsible for side channel
|
||||
requests to the always-on subsystem (AOSS), used for certain power management
|
||||
requests that is not handled by the standard RPMh interface. Each client in the
|
||||
SoC has it's own block of message RAM and IRQ for communication with the AOSS.
|
||||
The protocol used to communicate in the message RAM is known as Qualcomm
|
||||
Messaging Protocol (QMP)
|
||||
|
||||
The AOSS side channel exposes control over a set of resources, used to control
|
||||
a set of debug related clocks and to affect the low power state of resources
|
||||
related to the secondary subsystems. These resources are exposed as a set of
|
||||
power-domains.
|
||||
|
||||
- compatible:
|
||||
Usage: required
|
||||
Value type: <string>
|
||||
Definition: must be one of:
|
||||
"qcom,sc7180-aoss-qmp"
|
||||
"qcom,sc7280-aoss-qmp"
|
||||
"qcom,sdm845-aoss-qmp"
|
||||
"qcom,sm8150-aoss-qmp"
|
||||
"qcom,sm8250-aoss-qmp"
|
||||
"qcom,sm8350-aoss-qmp"
|
||||
|
||||
- reg:
|
||||
Usage: required
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: the base address and size of the message RAM for this
|
||||
client's communication with the AOSS
|
||||
|
||||
- interrupts:
|
||||
Usage: required
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: should specify the AOSS message IRQ for this client
|
||||
|
||||
- mboxes:
|
||||
Usage: required
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: reference to the mailbox representing the outgoing doorbell
|
||||
in APCS for this client, as described in mailbox/mailbox.txt
|
||||
|
||||
- #clock-cells:
|
||||
Usage: optional
|
||||
Value type: <u32>
|
||||
Definition: must be 0
|
||||
The single clock represents the QDSS clock.
|
||||
|
||||
- #power-domain-cells:
|
||||
Usage: optional
|
||||
Value type: <u32>
|
||||
Definition: must be 1
|
||||
The provided power-domains are:
|
||||
CDSP state (0), LPASS state (1), modem state (2), SLPI
|
||||
state (3), SPSS state (4) and Venus state (5).
|
||||
|
||||
= SUBNODES
|
||||
The AOSS side channel also provides the controls for three cooling devices,
|
||||
these are expressed as subnodes of the QMP node. The name of the node is used
|
||||
to identify the resource and must therefor be "cx", "mx" or "ebi".
|
||||
|
||||
- #cooling-cells:
|
||||
Usage: optional
|
||||
Value type: <u32>
|
||||
Definition: must be 2
|
||||
|
||||
= EXAMPLE
|
||||
|
||||
The following example represents the AOSS side-channel message RAM and the
|
||||
mechanism exposing the power-domains, as found in SDM845.
|
||||
|
||||
aoss_qmp: qmp@c300000 {
|
||||
compatible = "qcom,sdm845-aoss-qmp";
|
||||
reg = <0x0c300000 0x100000>;
|
||||
interrupts = <GIC_SPI 389 IRQ_TYPE_EDGE_RISING>;
|
||||
mboxes = <&apss_shared 0>;
|
||||
|
||||
#power-domain-cells = <1>;
|
||||
|
||||
cx_cdev: cx {
|
||||
#cooling-cells = <2>;
|
||||
};
|
||||
|
||||
mx_cdev: mx {
|
||||
#cooling-cells = <2>;
|
||||
};
|
||||
};
|
114
Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml
Normal file
114
Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml
Normal file
@ -0,0 +1,114 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/soc/qcom/qcom,aoss-qmp.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Always-On Subsystem side channel binding
|
||||
|
||||
maintainers:
|
||||
- Bjorn Andersson <bjorn.andersson@linaro.org>
|
||||
|
||||
description:
|
||||
This binding describes the hardware component responsible for side channel
|
||||
requests to the always-on subsystem (AOSS), used for certain power management
|
||||
requests that is not handled by the standard RPMh interface. Each client in the
|
||||
SoC has it's own block of message RAM and IRQ for communication with the AOSS.
|
||||
The protocol used to communicate in the message RAM is known as Qualcomm
|
||||
Messaging Protocol (QMP)
|
||||
|
||||
The AOSS side channel exposes control over a set of resources, used to control
|
||||
a set of debug related clocks and to affect the low power state of resources
|
||||
related to the secondary subsystems. These resources are exposed as a set of
|
||||
power-domains.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- qcom,sc7180-aoss-qmp
|
||||
- qcom,sc7280-aoss-qmp
|
||||
- qcom,sc8180x-aoss-qmp
|
||||
- qcom,sdm845-aoss-qmp
|
||||
- qcom,sm8150-aoss-qmp
|
||||
- qcom,sm8250-aoss-qmp
|
||||
- qcom,sm8350-aoss-qmp
|
||||
- const: qcom,aoss-qmp
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
description:
|
||||
The base address and size of the message RAM for this client's
|
||||
communication with the AOSS
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
description:
|
||||
Should specify the AOSS message IRQ for this client
|
||||
|
||||
mboxes:
|
||||
maxItems: 1
|
||||
description:
|
||||
Reference to the mailbox representing the outgoing doorbell in APCS for
|
||||
this client, as described in mailbox/mailbox.txt
|
||||
|
||||
"#clock-cells":
|
||||
const: 0
|
||||
description:
|
||||
The single clock represents the QDSS clock.
|
||||
|
||||
"#power-domain-cells":
|
||||
const: 1
|
||||
description: |
|
||||
The provided power-domains are:
|
||||
CDSP state (0), LPASS state (1), modem state (2), SLPI
|
||||
state (3), SPSS state (4) and Venus state (5).
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- mboxes
|
||||
- "#clock-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
patternProperties:
|
||||
"^(cx|mx|ebi)$":
|
||||
type: object
|
||||
description:
|
||||
The AOSS side channel also provides the controls for three cooling devices,
|
||||
these are expressed as subnodes of the QMP node. The name of the node is
|
||||
used to identify the resource and must therefor be "cx", "mx" or "ebi".
|
||||
|
||||
properties:
|
||||
"#cooling-cells":
|
||||
const: 2
|
||||
|
||||
required:
|
||||
- "#cooling-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
aoss_qmp: qmp@c300000 {
|
||||
compatible = "qcom,sdm845-aoss-qmp", "qcom,aoss-qmp";
|
||||
reg = <0x0c300000 0x100000>;
|
||||
interrupts = <GIC_SPI 389 IRQ_TYPE_EDGE_RISING>;
|
||||
mboxes = <&apss_shared 0>;
|
||||
|
||||
#clock-cells = <0>;
|
||||
#power-domain-cells = <1>;
|
||||
|
||||
cx_cdev: cx {
|
||||
#cooling-cells = <2>;
|
||||
};
|
||||
|
||||
mx_cdev: mx {
|
||||
#cooling-cells = <2>;
|
||||
};
|
||||
};
|
||||
...
|
@ -51,6 +51,9 @@ properties:
|
||||
interconnect-names:
|
||||
const: qup-core
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
@ -39,6 +39,7 @@ properties:
|
||||
- qcom,rpm-msm8996
|
||||
- qcom,rpm-msm8998
|
||||
- qcom,rpm-sdm660
|
||||
- qcom,rpm-sm6115
|
||||
- qcom,rpm-sm6125
|
||||
- qcom,rpm-qcs404
|
||||
|
||||
|
@ -203,7 +203,7 @@ config INTEL_STRATIX10_RSU
|
||||
Say Y here if you want Intel RSU support.
|
||||
|
||||
config QCOM_SCM
|
||||
bool
|
||||
tristate "Qcom SCM driver"
|
||||
depends on ARM || ARM64
|
||||
depends on HAVE_ARM_SMCCC
|
||||
select RESET_CONTROLLER
|
||||
|
@ -17,7 +17,8 @@ obj-$(CONFIG_ISCSI_IBFT) += iscsi_ibft.o
|
||||
obj-$(CONFIG_FIRMWARE_MEMMAP) += memmap.o
|
||||
obj-$(CONFIG_RASPBERRYPI_FIRMWARE) += raspberrypi.o
|
||||
obj-$(CONFIG_FW_CFG_SYSFS) += qemu_fw_cfg.o
|
||||
obj-$(CONFIG_QCOM_SCM) += qcom_scm.o qcom_scm-smc.o qcom_scm-legacy.o
|
||||
obj-$(CONFIG_QCOM_SCM) += qcom-scm.o
|
||||
qcom-scm-objs += qcom_scm.o qcom_scm-smc.o qcom_scm-legacy.o
|
||||
obj-$(CONFIG_TI_SCI_PROTOCOL) += ti_sci.o
|
||||
obj-$(CONFIG_TRUSTED_FOUNDATIONS) += trusted_foundations.o
|
||||
obj-$(CONFIG_TURRIS_MOX_RWTM) += turris-mox-rwtm.o
|
||||
|
@ -71,7 +71,7 @@ static struct qcom_scm_wb_entry qcom_scm_wb[] = {
|
||||
{ .flag = QCOM_SCM_FLAG_WARMBOOT_CPU3 },
|
||||
};
|
||||
|
||||
static const char *qcom_scm_convention_names[] = {
|
||||
static const char * const qcom_scm_convention_names[] = {
|
||||
[SMC_CONVENTION_UNKNOWN] = "unknown",
|
||||
[SMC_CONVENTION_ARM_32] = "smc arm 32",
|
||||
[SMC_CONVENTION_ARM_64] = "smc arm 64",
|
||||
@ -331,7 +331,7 @@ int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus)
|
||||
.owner = ARM_SMCCC_OWNER_SIP,
|
||||
};
|
||||
|
||||
if (!cpus || (cpus && cpumask_empty(cpus)))
|
||||
if (!cpus || cpumask_empty(cpus))
|
||||
return -EINVAL;
|
||||
|
||||
for_each_cpu(cpu, cpus) {
|
||||
@ -1299,6 +1299,7 @@ static const struct of_device_id qcom_scm_dt_match[] = {
|
||||
{ .compatible = "qcom,scm" },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, qcom_scm_dt_match);
|
||||
|
||||
static struct platform_driver qcom_scm_driver = {
|
||||
.driver = {
|
||||
@ -1315,3 +1316,6 @@ static int __init qcom_scm_init(void)
|
||||
return platform_driver_register(&qcom_scm_driver);
|
||||
}
|
||||
subsys_initcall(qcom_scm_init);
|
||||
|
||||
MODULE_DESCRIPTION("Qualcomm Technologies, Inc. SCM driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
@ -253,6 +253,7 @@ config SPAPR_TCE_IOMMU
|
||||
config ARM_SMMU
|
||||
tristate "ARM Ltd. System MMU (SMMU) Support"
|
||||
depends on ARM64 || ARM || (COMPILE_TEST && !GENERIC_ATOMIC64)
|
||||
depends on QCOM_SCM || !QCOM_SCM #if QCOM_SCM=m this can't be =y
|
||||
select IOMMU_API
|
||||
select IOMMU_IO_PGTABLE_LPAE
|
||||
select ARM_DMA_USE_IOMMU if ARM
|
||||
@ -382,6 +383,7 @@ config QCOM_IOMMU
|
||||
# Note: iommu drivers cannot (yet?) be built as modules
|
||||
bool "Qualcomm IOMMU Support"
|
||||
depends on ARCH_QCOM || (COMPILE_TEST && !GENERIC_ATOMIC64)
|
||||
depends on QCOM_SCM=y
|
||||
select IOMMU_API
|
||||
select IOMMU_IO_PGTABLE_LPAE
|
||||
select ARM_DMA_USE_IOMMU
|
||||
|
@ -44,6 +44,7 @@ config ATH10K_SNOC
|
||||
tristate "Qualcomm ath10k SNOC support"
|
||||
depends on ATH10K
|
||||
depends on ARCH_QCOM || COMPILE_TEST
|
||||
depends on QCOM_SCM || !QCOM_SCM #if QCOM_SCM=m this can't be =y
|
||||
select QCOM_QMI_HELPERS
|
||||
help
|
||||
This module adds support for integrated WCN3990 chip connected
|
||||
|
@ -801,38 +801,6 @@ unlock:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cpr_read_efuse(struct device *dev, const char *cname, u32 *data)
|
||||
{
|
||||
struct nvmem_cell *cell;
|
||||
ssize_t len;
|
||||
char *ret;
|
||||
int i;
|
||||
|
||||
*data = 0;
|
||||
|
||||
cell = nvmem_cell_get(dev, cname);
|
||||
if (IS_ERR(cell)) {
|
||||
if (PTR_ERR(cell) != -EPROBE_DEFER)
|
||||
dev_err(dev, "undefined cell %s\n", cname);
|
||||
return PTR_ERR(cell);
|
||||
}
|
||||
|
||||
ret = nvmem_cell_read(cell, &len);
|
||||
nvmem_cell_put(cell);
|
||||
if (IS_ERR(ret)) {
|
||||
dev_err(dev, "can't read cell %s\n", cname);
|
||||
return PTR_ERR(ret);
|
||||
}
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
*data |= ret[i] << (8 * i);
|
||||
|
||||
kfree(ret);
|
||||
dev_dbg(dev, "efuse read(%s) = %x, bytes %zd\n", cname, *data, len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
cpr_populate_ring_osc_idx(struct cpr_drv *drv)
|
||||
{
|
||||
@ -843,8 +811,7 @@ cpr_populate_ring_osc_idx(struct cpr_drv *drv)
|
||||
int ret;
|
||||
|
||||
for (; fuse < end; fuse++, fuses++) {
|
||||
ret = cpr_read_efuse(drv->dev, fuses->ring_osc,
|
||||
&data);
|
||||
ret = nvmem_cell_read_variable_le_u32(drv->dev, fuses->ring_osc, &data);
|
||||
if (ret)
|
||||
return ret;
|
||||
fuse->ring_osc_idx = data;
|
||||
@ -863,7 +830,7 @@ static int cpr_read_fuse_uV(const struct cpr_desc *desc,
|
||||
u32 bits = 0;
|
||||
int ret;
|
||||
|
||||
ret = cpr_read_efuse(drv->dev, init_v_efuse, &bits);
|
||||
ret = nvmem_cell_read_variable_le_u32(drv->dev, init_v_efuse, &bits);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -932,7 +899,7 @@ static int cpr_fuse_corner_init(struct cpr_drv *drv)
|
||||
}
|
||||
|
||||
/* Populate target quotient by scaling */
|
||||
ret = cpr_read_efuse(drv->dev, fuses->quotient, &fuse->quot);
|
||||
ret = nvmem_cell_read_variable_le_u32(drv->dev, fuses->quotient, &fuse->quot);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -1001,7 +968,7 @@ static int cpr_calculate_scaling(const char *quot_offset,
|
||||
prev_fuse = fuse - 1;
|
||||
|
||||
if (quot_offset) {
|
||||
ret = cpr_read_efuse(drv->dev, quot_offset, "_diff);
|
||||
ret = nvmem_cell_read_variable_le_u32(drv->dev, quot_offset, "_diff);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -1701,7 +1668,7 @@ static int cpr_probe(struct platform_device *pdev)
|
||||
* initialized after attaching to the power domain,
|
||||
* since it depends on the CPU's OPP table.
|
||||
*/
|
||||
ret = cpr_read_efuse(dev, "cpr_fuse_revision", &cpr_rev);
|
||||
ret = nvmem_cell_read_variable_le_u32(dev, "cpr_fuse_revision", &cpr_rev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -166,6 +166,8 @@ static int __qcom_mdt_load(struct device *dev, const struct firmware *fw,
|
||||
metadata = qcom_mdt_read_metadata(fw, &metadata_len);
|
||||
if (IS_ERR(metadata)) {
|
||||
ret = PTR_ERR(metadata);
|
||||
dev_err(dev, "error %d reading firmware %s metadata\n",
|
||||
ret, fw_name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -173,7 +175,9 @@ static int __qcom_mdt_load(struct device *dev, const struct firmware *fw,
|
||||
|
||||
kfree(metadata);
|
||||
if (ret) {
|
||||
dev_err(dev, "invalid firmware metadata\n");
|
||||
/* Invalid firmware metadata */
|
||||
dev_err(dev, "error %d initializing firmware %s\n",
|
||||
ret, fw_name);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
@ -199,7 +203,9 @@ static int __qcom_mdt_load(struct device *dev, const struct firmware *fw,
|
||||
ret = qcom_scm_pas_mem_setup(pas_id, mem_phys,
|
||||
max_addr - min_addr);
|
||||
if (ret) {
|
||||
dev_err(dev, "unable to setup relocation\n");
|
||||
/* Unable to set up relocation */
|
||||
dev_err(dev, "error %d setting up firmware %s\n",
|
||||
ret, fw_name);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
@ -243,9 +249,8 @@ static int __qcom_mdt_load(struct device *dev, const struct firmware *fw,
|
||||
if (phdr->p_filesz && phdr->p_offset < fw->size) {
|
||||
/* Firmware is large enough to be non-split */
|
||||
if (phdr->p_offset + phdr->p_filesz > fw->size) {
|
||||
dev_err(dev,
|
||||
"failed to load segment %d from truncated file %s\n",
|
||||
i, firmware);
|
||||
dev_err(dev, "file %s segment %d would be truncated\n",
|
||||
fw_name, i);
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
@ -257,7 +262,8 @@ static int __qcom_mdt_load(struct device *dev, const struct firmware *fw,
|
||||
ret = request_firmware_into_buf(&seg_fw, fw_name, dev,
|
||||
ptr, phdr->p_filesz);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to load %s\n", fw_name);
|
||||
dev_err(dev, "error %d loading %s\n",
|
||||
ret, fw_name);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -104,7 +104,6 @@ static const char * const icc_path_names[] = {"qup-core", "qup-config",
|
||||
#define GENI_OUTPUT_CTRL 0x24
|
||||
#define GENI_CGC_CTRL 0x28
|
||||
#define GENI_CLK_CTRL_RO 0x60
|
||||
#define GENI_IF_DISABLE_RO 0x64
|
||||
#define GENI_FW_S_REVISION_RO 0x6c
|
||||
#define SE_GENI_BYTE_GRAN 0x254
|
||||
#define SE_GENI_TX_PACKING_CFG0 0x260
|
||||
@ -322,6 +321,30 @@ static void geni_se_select_dma_mode(struct geni_se *se)
|
||||
writel_relaxed(val, se->base + SE_GENI_DMA_MODE_EN);
|
||||
}
|
||||
|
||||
static void geni_se_select_gpi_mode(struct geni_se *se)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
geni_se_irq_clear(se);
|
||||
|
||||
writel(0, se->base + SE_IRQ_EN);
|
||||
|
||||
val = readl(se->base + SE_GENI_S_IRQ_EN);
|
||||
val &= ~S_CMD_DONE_EN;
|
||||
writel(val, se->base + SE_GENI_S_IRQ_EN);
|
||||
|
||||
val = readl(se->base + SE_GENI_M_IRQ_EN);
|
||||
val &= ~(M_CMD_DONE_EN | M_TX_FIFO_WATERMARK_EN |
|
||||
M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN);
|
||||
writel(val, se->base + SE_GENI_M_IRQ_EN);
|
||||
|
||||
writel(GENI_DMA_MODE_EN, se->base + SE_GENI_DMA_MODE_EN);
|
||||
|
||||
val = readl(se->base + SE_GSI_EVENT_EN);
|
||||
val |= (DMA_RX_EVENT_EN | DMA_TX_EVENT_EN | GENI_M_EVENT_EN | GENI_S_EVENT_EN);
|
||||
writel(val, se->base + SE_GSI_EVENT_EN);
|
||||
}
|
||||
|
||||
/**
|
||||
* geni_se_select_mode() - Select the serial engine transfer mode
|
||||
* @se: Pointer to the concerned serial engine.
|
||||
@ -329,7 +352,7 @@ static void geni_se_select_dma_mode(struct geni_se *se)
|
||||
*/
|
||||
void geni_se_select_mode(struct geni_se *se, enum geni_se_xfer_mode mode)
|
||||
{
|
||||
WARN_ON(mode != GENI_SE_FIFO && mode != GENI_SE_DMA);
|
||||
WARN_ON(mode != GENI_SE_FIFO && mode != GENI_SE_DMA && mode != GENI_GPI_DMA);
|
||||
|
||||
switch (mode) {
|
||||
case GENI_SE_FIFO:
|
||||
@ -338,6 +361,9 @@ void geni_se_select_mode(struct geni_se *se, enum geni_se_xfer_mode mode)
|
||||
case GENI_SE_DMA:
|
||||
geni_se_select_dma_mode(se);
|
||||
break;
|
||||
case GENI_GPI_DMA:
|
||||
geni_se_select_gpi_mode(se);
|
||||
break;
|
||||
case GENI_SE_INVALID:
|
||||
default:
|
||||
break;
|
||||
|
@ -476,12 +476,12 @@ static int qmp_cooling_device_add(struct qmp *qmp,
|
||||
static int qmp_cooling_devices_register(struct qmp *qmp)
|
||||
{
|
||||
struct device_node *np, *child;
|
||||
int count = QMP_NUM_COOLING_RESOURCES;
|
||||
int count = 0;
|
||||
int ret;
|
||||
|
||||
np = qmp->dev->of_node;
|
||||
|
||||
qmp->cooling_devs = devm_kcalloc(qmp->dev, count,
|
||||
qmp->cooling_devs = devm_kcalloc(qmp->dev, QMP_NUM_COOLING_RESOURCES,
|
||||
sizeof(*qmp->cooling_devs),
|
||||
GFP_KERNEL);
|
||||
|
||||
@ -497,12 +497,16 @@ static int qmp_cooling_devices_register(struct qmp *qmp)
|
||||
goto unroll;
|
||||
}
|
||||
|
||||
if (!count)
|
||||
devm_kfree(qmp->dev, qmp->cooling_devs);
|
||||
|
||||
return 0;
|
||||
|
||||
unroll:
|
||||
while (--count >= 0)
|
||||
thermal_cooling_device_unregister
|
||||
(qmp->cooling_devs[count].cdev);
|
||||
devm_kfree(qmp->dev, qmp->cooling_devs);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -602,6 +606,7 @@ static const struct of_device_id qmp_dt_match[] = {
|
||||
{ .compatible = "qcom,sm8150-aoss-qmp", },
|
||||
{ .compatible = "qcom,sm8250-aoss-qmp", },
|
||||
{ .compatible = "qcom,sm8350-aoss-qmp", },
|
||||
{ .compatible = "qcom,aoss-qmp", },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, qmp_dt_match);
|
||||
|
@ -403,12 +403,11 @@ static int rpmhpd_power_on(struct generic_pm_domain *domain)
|
||||
static int rpmhpd_power_off(struct generic_pm_domain *domain)
|
||||
{
|
||||
struct rpmhpd *pd = domain_to_rpmhpd(domain);
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&rpmhpd_lock);
|
||||
|
||||
ret = rpmhpd_aggregate_corner(pd, pd->level[0]);
|
||||
|
||||
ret = rpmhpd_aggregate_corner(pd, 0);
|
||||
if (!ret)
|
||||
pd->enabled = false;
|
||||
|
||||
|
@ -346,6 +346,33 @@ static const struct rpmpd_desc sdm660_desc = {
|
||||
.max_state = RPM_SMD_LEVEL_TURBO,
|
||||
};
|
||||
|
||||
/* sm4250/6115 RPM Power domains */
|
||||
DEFINE_RPMPD_PAIR(sm6115, vddcx, vddcx_ao, RWCX, LEVEL, 0);
|
||||
DEFINE_RPMPD_VFL(sm6115, vddcx_vfl, RWCX, 0);
|
||||
|
||||
DEFINE_RPMPD_PAIR(sm6115, vddmx, vddmx_ao, RWMX, LEVEL, 0);
|
||||
DEFINE_RPMPD_VFL(sm6115, vddmx_vfl, RWMX, 0);
|
||||
|
||||
DEFINE_RPMPD_LEVEL(sm6115, vdd_lpi_cx, RWLC, 0);
|
||||
DEFINE_RPMPD_LEVEL(sm6115, vdd_lpi_mx, RWLM, 0);
|
||||
|
||||
static struct rpmpd *sm6115_rpmpds[] = {
|
||||
[SM6115_VDDCX] = &sm6115_vddcx,
|
||||
[SM6115_VDDCX_AO] = &sm6115_vddcx_ao,
|
||||
[SM6115_VDDCX_VFL] = &sm6115_vddcx_vfl,
|
||||
[SM6115_VDDMX] = &sm6115_vddmx,
|
||||
[SM6115_VDDMX_AO] = &sm6115_vddmx_ao,
|
||||
[SM6115_VDDMX_VFL] = &sm6115_vddmx_vfl,
|
||||
[SM6115_VDD_LPI_CX] = &sm6115_vdd_lpi_cx,
|
||||
[SM6115_VDD_LPI_MX] = &sm6115_vdd_lpi_mx,
|
||||
};
|
||||
|
||||
static const struct rpmpd_desc sm6115_desc = {
|
||||
.rpmpds = sm6115_rpmpds,
|
||||
.num_pds = ARRAY_SIZE(sm6115_rpmpds),
|
||||
.max_state = RPM_SMD_LEVEL_TURBO_NO_CPR,
|
||||
};
|
||||
|
||||
static const struct of_device_id rpmpd_match_table[] = {
|
||||
{ .compatible = "qcom,mdm9607-rpmpd", .data = &mdm9607_desc },
|
||||
{ .compatible = "qcom,msm8916-rpmpd", .data = &msm8916_desc },
|
||||
@ -356,6 +383,7 @@ static const struct of_device_id rpmpd_match_table[] = {
|
||||
{ .compatible = "qcom,msm8998-rpmpd", .data = &msm8998_desc },
|
||||
{ .compatible = "qcom,qcs404-rpmpd", .data = &qcs404_desc },
|
||||
{ .compatible = "qcom,sdm660-rpmpd", .data = &sdm660_desc },
|
||||
{ .compatible = "qcom,sm6115-rpmpd", .data = &sm6115_desc },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, rpmpd_match_table);
|
||||
|
@ -242,6 +242,7 @@ static const struct of_device_id qcom_smd_rpm_of_match[] = {
|
||||
{ .compatible = "qcom,rpm-msm8996" },
|
||||
{ .compatible = "qcom,rpm-msm8998" },
|
||||
{ .compatible = "qcom,rpm-sdm660" },
|
||||
{ .compatible = "qcom,rpm-sm6115" },
|
||||
{ .compatible = "qcom,rpm-sm6125" },
|
||||
{ .compatible = "qcom,rpm-qcs404" },
|
||||
{}
|
||||
|
@ -109,7 +109,7 @@ struct smsm_entry {
|
||||
DECLARE_BITMAP(irq_enabled, 32);
|
||||
DECLARE_BITMAP(irq_rising, 32);
|
||||
DECLARE_BITMAP(irq_falling, 32);
|
||||
u32 last_value;
|
||||
unsigned long last_value;
|
||||
|
||||
u32 *remote_state;
|
||||
u32 *subscription;
|
||||
@ -204,8 +204,7 @@ static irqreturn_t smsm_intr(int irq, void *data)
|
||||
u32 val;
|
||||
|
||||
val = readl(entry->remote_state);
|
||||
changed = val ^ entry->last_value;
|
||||
entry->last_value = val;
|
||||
changed = val ^ xchg(&entry->last_value, val);
|
||||
|
||||
for_each_set_bit(i, entry->irq_enabled, 32) {
|
||||
if (!(changed & BIT(i)))
|
||||
@ -264,6 +263,12 @@ static void smsm_unmask_irq(struct irq_data *irqd)
|
||||
struct qcom_smsm *smsm = entry->smsm;
|
||||
u32 val;
|
||||
|
||||
/* Make sure our last cached state is up-to-date */
|
||||
if (readl(entry->remote_state) & BIT(irq))
|
||||
set_bit(irq, &entry->last_value);
|
||||
else
|
||||
clear_bit(irq, &entry->last_value);
|
||||
|
||||
set_bit(irq, entry->irq_enabled);
|
||||
|
||||
if (entry->subscription) {
|
||||
@ -299,11 +304,28 @@ static int smsm_set_irq_type(struct irq_data *irqd, unsigned int type)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int smsm_get_irqchip_state(struct irq_data *irqd,
|
||||
enum irqchip_irq_state which, bool *state)
|
||||
{
|
||||
struct smsm_entry *entry = irq_data_get_irq_chip_data(irqd);
|
||||
irq_hw_number_t irq = irqd_to_hwirq(irqd);
|
||||
u32 val;
|
||||
|
||||
if (which != IRQCHIP_STATE_LINE_LEVEL)
|
||||
return -EINVAL;
|
||||
|
||||
val = readl(entry->remote_state);
|
||||
*state = !!(val & BIT(irq));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct irq_chip smsm_irq_chip = {
|
||||
.name = "smsm",
|
||||
.irq_mask = smsm_mask_irq,
|
||||
.irq_unmask = smsm_unmask_irq,
|
||||
.irq_set_type = smsm_set_irq_type,
|
||||
.irq_get_irqchip_state = smsm_get_irqchip_state,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -417,8 +417,8 @@ QCOM_OPEN(chip_id, qcom_show_chip_id);
|
||||
static int show_image_##type(struct seq_file *seq, void *p) \
|
||||
{ \
|
||||
struct smem_image_version *image_version = seq->private; \
|
||||
seq_puts(seq, image_version->type); \
|
||||
seq_putc(seq, '\n'); \
|
||||
if (image_version->type[0] != '\0') \
|
||||
seq_printf(seq, "%s\n", image_version->type); \
|
||||
return 0; \
|
||||
} \
|
||||
static int open_image_##type(struct inode *inode, struct file *file) \
|
||||
|
@ -192,6 +192,16 @@
|
||||
#define SDM660_SSCMX 8
|
||||
#define SDM660_SSCMX_VFL 9
|
||||
|
||||
/* SM6115 Power Domains */
|
||||
#define SM6115_VDDCX 0
|
||||
#define SM6115_VDDCX_AO 1
|
||||
#define SM6115_VDDCX_VFL 2
|
||||
#define SM6115_VDDMX 3
|
||||
#define SM6115_VDDMX_AO 4
|
||||
#define SM6115_VDDMX_VFL 5
|
||||
#define SM6115_VDD_LPI_CX 6
|
||||
#define SM6115_VDD_LPI_MX 7
|
||||
|
||||
/* RPM SMD Power Domain performance levels */
|
||||
#define RPM_SMD_LEVEL_RETENTION 16
|
||||
#define RPM_SMD_LEVEL_RETENTION_PLUS 32
|
||||
|
@ -8,11 +8,24 @@
|
||||
|
||||
#include <linux/interconnect.h>
|
||||
|
||||
/* Transfer mode supported by GENI Serial Engines */
|
||||
/**
|
||||
* enum geni_se_xfer_mode: Transfer modes supported by Serial Engines
|
||||
*
|
||||
* @GENI_SE_INVALID: Invalid mode
|
||||
* @GENI_SE_FIFO: FIFO mode. Data is transferred with SE FIFO
|
||||
* by programmed IO method
|
||||
* @GENI_SE_DMA: Serial Engine DMA mode. Data is transferred
|
||||
* with SE by DMAengine internal to SE
|
||||
* @GENI_GPI_DMA: GPI DMA mode. Data is transferred using a DMAengine
|
||||
* configured by a firmware residing on a GSI engine. This DMA name is
|
||||
* interchangeably used as GSI or GPI which seem to imply the same DMAengine
|
||||
*/
|
||||
|
||||
enum geni_se_xfer_mode {
|
||||
GENI_SE_INVALID,
|
||||
GENI_SE_FIFO,
|
||||
GENI_SE_DMA,
|
||||
GENI_GPI_DMA,
|
||||
};
|
||||
|
||||
/* Protocols supported by GENI Serial Engines */
|
||||
@ -63,6 +76,7 @@ struct geni_se {
|
||||
#define SE_GENI_STATUS 0x40
|
||||
#define GENI_SER_M_CLK_CFG 0x48
|
||||
#define GENI_SER_S_CLK_CFG 0x4c
|
||||
#define GENI_IF_DISABLE_RO 0x64
|
||||
#define GENI_FW_REVISION_RO 0x68
|
||||
#define SE_GENI_CLK_SEL 0x7c
|
||||
#define SE_GENI_DMA_MODE_EN 0x258
|
||||
@ -105,6 +119,9 @@ struct geni_se {
|
||||
#define CLK_DIV_MSK GENMASK(15, 4)
|
||||
#define CLK_DIV_SHFT 4
|
||||
|
||||
/* GENI_IF_DISABLE_RO fields */
|
||||
#define FIFO_IF_DISABLE (BIT(0))
|
||||
|
||||
/* GENI_FW_REVISION_RO fields */
|
||||
#define FW_REV_PROTOCOL_MSK GENMASK(15, 8)
|
||||
#define FW_REV_PROTOCOL_SHFT 8
|
||||
|
Loading…
Reference in New Issue
Block a user