summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/arm/qcom.yaml120
-rw-r--r--Documentation/devicetree/bindings/firmware/qcom,scm.yaml3
-rw-r--r--Documentation/devicetree/bindings/power/qcom,rpmpd.yaml2
-rw-r--r--Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml1
-rw-r--r--Documentation/devicetree/bindings/soc/qcom/qcom,rpmh-rsc.yaml5
-rw-r--r--Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.yaml28
-rw-r--r--Documentation/devicetree/bindings/soc/qcom/qcom,smp2p.yaml2
-rw-r--r--Documentation/devicetree/bindings/soc/qcom/qcom,spm.yaml3
-rw-r--r--drivers/base/power/domain.c26
-rw-r--r--drivers/base/power/domain_governor.c3
-rw-r--r--drivers/soc/qcom/apr.c15
-rw-r--r--drivers/soc/qcom/cmd-db.c2
-rw-r--r--drivers/soc/qcom/llcc-qcom.c2
-rw-r--r--drivers/soc/qcom/pdr_internal.h20
-rw-r--r--drivers/soc/qcom/qcom_stats.c2
-rw-r--r--drivers/soc/qcom/rpmh-internal.h9
-rw-r--r--drivers/soc/qcom/rpmh-rsc.c146
-rw-r--r--drivers/soc/qcom/rpmh.c4
-rw-r--r--drivers/soc/qcom/rpmhpd.c71
-rw-r--r--drivers/soc/qcom/smd-rpm.c3
-rw-r--r--drivers/soc/qcom/smp2p.c2
-rw-r--r--drivers/soc/qcom/socinfo.c271
-rw-r--r--drivers/soc/qcom/spm.c46
-rw-r--r--include/dt-bindings/arm/qcom,ids.h161
-rw-r--r--include/dt-bindings/power/qcom-rpmpd.h16
-rw-r--r--include/linux/pm_domain.h7
-rw-r--r--include/soc/qcom/qcom-spmi-pmic.h17
27 files changed, 817 insertions, 170 deletions
diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml
index 1b5ac6b02bc5..b8341967240b 100644
--- a/Documentation/devicetree/bindings/arm/qcom.yaml
+++ b/Documentation/devicetree/bindings/arm/qcom.yaml
@@ -739,6 +739,126 @@ properties:
- sony,pdx223
- const: qcom,sm8450
+ # Board compatibles go above
+
+ qcom,msm-id:
+ $ref: /schemas/types.yaml#/definitions/uint32-matrix
+ minItems: 1
+ maxItems: 8
+ items:
+ items:
+ - description: |
+ MSM chipset ID - an exact match value consisting of two bitfields::
+ - bits 0-15 - The unique MSM chipset ID
+ - bits 16-31 - Reserved; should be 0
+ - description: |
+ Hardware revision ID - a chipset specific 32-bit ID representing
+ the version of the chipset. It is best a match value - the
+ bootloader will look for the closest possible match.
+ deprecated: true
+ description:
+ The MSM chipset and hardware revision used Qualcomm bootloaders. It
+ can optionally be an array of these to indicate multiple hardware that
+ use the same device tree. It is expected that the bootloader will use
+ this information at boot-up to decide which device tree to use when given
+ multiple device trees, some of which may not be compatible with the
+ actual hardware. It is the bootloader's responsibility to pass the
+ correct device tree to the kernel.
+ The property is deprecated.
+
+ qcom,board-id:
+ $ref: /schemas/types.yaml#/definitions/uint32-matrix
+ minItems: 1
+ maxItems: 8
+ oneOf:
+ - items:
+ - items:
+ - description: |
+ Board ID consisting of three bitfields::
+ - bits 31-24 - Unused
+ - bits 23-16 - Platform Version Major
+ - bits 15-8 - Platform Version Minor
+ - bits 7-0 - Platform Type
+ Platform Type field is an exact match value. The
+ Platform Major/Minor field is a best match. The bootloader will
+ look for the closest possible match.
+ - description: |
+ Subtype ID unique to a Platform Type/Chipset ID. For a given
+ Platform Type, there will typically only be a single board and the
+ subtype_id will be 0. However in some cases board variants may
+ need to be distinguished by different subtype_id values.
+ - items:
+ # OnePlus uses a variant of board-id with four elements:
+ - items:
+ - const: 8
+ - const: 0
+ - description: OnePlus board ID
+ - description: OnePlus subtype ID
+ deprecated: true
+ description:
+ The board type and revision information. It can optionally be an array
+ of these to indicate multiple boards that use the same device tree. It
+ is expected that the bootloader will use this information at boot-up to
+ decide which device tree to use when given multiple device trees, some of
+ which may not be compatible with the actual hardware. It is the
+ bootloader's responsibility to pass the correct device tree to the
+ kernel
+ The property is deprecated.
+
+allOf:
+ # Explicit allow-list for older SoCs. The legacy properties are not allowed
+ # on newer SoCs.
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - qcom,apq8026
+ - qcom,apq8094
+ - qcom,apq8096
+ - qcom,msm8992
+ - qcom,msm8994
+ - qcom,msm8996
+ - qcom,msm8998
+ - qcom,sdm630
+ - qcom,sdm632
+ - qcom,sdm845
+ - qcom,sdx55
+ - qcom,sdx65
+ - qcom,sm6125
+ - qcom,sm6350
+ - qcom,sm7225
+ - qcom,sm8150
+ - qcom,sm8250
+ then:
+ properties:
+ qcom,board-id: true
+ qcom,msm-id: true
+ else:
+ properties:
+ qcom,board-id: false
+ qcom,msm-id: false
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - oneplus,cheeseburger
+ - oneplus,dumpling
+ - oneplus,enchilada
+ - oneplus,fajita
+ then:
+ properties:
+ qcom,board-id:
+ items:
+ minItems: 4
+ else:
+ properties:
+ qcom,board-id:
+ items:
+ maxItems: 2
+
additionalProperties: true
...
diff --git a/Documentation/devicetree/bindings/firmware/qcom,scm.yaml b/Documentation/devicetree/bindings/firmware/qcom,scm.yaml
index c5b76c9f7ad0..25688571ee7c 100644
--- a/Documentation/devicetree/bindings/firmware/qcom,scm.yaml
+++ b/Documentation/devicetree/bindings/firmware/qcom,scm.yaml
@@ -41,12 +41,14 @@ properties:
- qcom,scm-sc7180
- qcom,scm-sc7280
- qcom,scm-sc8280xp
+ - qcom,scm-sdm670
- qcom,scm-sdm845
- qcom,scm-sdx55
- qcom,scm-sdx65
- qcom,scm-sm6115
- qcom,scm-sm6125
- qcom,scm-sm6350
+ - qcom,scm-sm6375
- qcom,scm-sm8150
- qcom,scm-sm8250
- qcom,scm-sm8350
@@ -88,6 +90,7 @@ allOf:
- qcom,scm-apq8064
- qcom,scm-msm8660
- qcom,scm-msm8960
+ - qcom,scm-sm6375
then:
properties:
clock-names:
diff --git a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
index 5b4eda919911..c0bee4e8a9db 100644
--- a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
+++ b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
@@ -28,12 +28,14 @@ properties:
- qcom,msm8998-rpmpd
- qcom,qcm2290-rpmpd
- qcom,qcs404-rpmpd
+ - qcom,qdu1000-rpmhpd
- qcom,sa8540p-rpmhpd
- qcom,sdm660-rpmpd
- qcom,sc7180-rpmhpd
- qcom,sc7280-rpmhpd
- qcom,sc8180x-rpmhpd
- qcom,sc8280xp-rpmhpd
+ - qcom,sdm670-rpmhpd
- qcom,sdm845-rpmhpd
- qcom,sdx55-rpmhpd
- qcom,sdx65-rpmhpd
diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml
index a4eeb7e158e5..da232f8d20d2 100644
--- a/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml
@@ -28,6 +28,7 @@ properties:
- qcom,sc7180-aoss-qmp
- qcom,sc7280-aoss-qmp
- qcom,sc8180x-aoss-qmp
+ - qcom,sc8280xp-aoss-qmp
- qcom,sdm845-aoss-qmp
- qcom,sm6350-aoss-qmp
- qcom,sm8150-aoss-qmp
diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,rpmh-rsc.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,rpmh-rsc.yaml
index 4a50f1d27724..b246500d3d5d 100644
--- a/Documentation/devicetree/bindings/soc/qcom/qcom,rpmh-rsc.yaml
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,rpmh-rsc.yaml
@@ -99,6 +99,9 @@ properties:
- const: drv-2
- const: drv-3
+ power-domains:
+ maxItems: 1
+
bcm-voter:
$ref: /schemas/interconnect/qcom,bcm-voter.yaml#
@@ -151,6 +154,7 @@ examples:
<SLEEP_TCS 3>,
<WAKE_TCS 3>,
<CONTROL_TCS 1>;
+ power-domains = <&CLUSTER_PD>;
};
- |
@@ -197,6 +201,7 @@ examples:
<SLEEP_TCS 3>,
<WAKE_TCS 3>,
<CONTROL_TCS 0>;
+ power-domains = <&CLUSTER_PD>;
clock-controller {
compatible = "qcom,sm8350-rpmh-clk";
diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.yaml
index 09d5bfa920f2..11c0f4dd797c 100644
--- a/Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.yaml
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.yaml
@@ -4,7 +4,7 @@
$id: "http://devicetree.org/schemas/soc/qcom/qcom,smd-rpm.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
-title: Qualcomm Resource Power Manager (RPM) over SMD
+title: Qualcomm Resource Power Manager (RPM) over SMD/GLINK
description: |
This driver is used to interface with the Resource Power Manager (RPM) found
@@ -12,9 +12,9 @@ description: |
to vote for state of the system resources, such as clocks, regulators and bus
frequencies.
- The SMD information for the RPM edge should be filled out. See qcom,smd.yaml
- for the required edge properties. All SMD related properties will reside
- within the RPM node itself.
+ The SMD or GLINK information for the RPM edge should be filled out. See
+ qcom,smd.yaml for the required edge properties. All SMD/GLINK related
+ properties will reside within the RPM node itself.
The RPM exposes resources to its subnodes. The rpm_requests node must be
present and this subnode may contain children that designate regulator
@@ -45,6 +45,7 @@ properties:
- qcom,rpm-sdm660
- qcom,rpm-sm6115
- qcom,rpm-sm6125
+ - qcom,rpm-sm6375
- qcom,rpm-qcm2290
- qcom,rpm-qcs404
@@ -55,12 +56,23 @@ properties:
power-controller:
$ref: /schemas/power/qcom,rpmpd.yaml#
+ qcom,glink-channels:
+ $ref: /schemas/types.yaml#/definitions/string-array
+ description: Channel name used for the RPM communication
+ items:
+ - const: rpm_requests
+
qcom,smd-channels:
$ref: /schemas/types.yaml#/definitions/string-array
description: Channel name used for the RPM communication
items:
- const: rpm_requests
+patternProperties:
+ "^regulators(-[01])?$":
+ $ref: /schemas/regulator/qcom,smd-rpm-regulator.yaml#
+ unevaluatedProperties: false
+
if:
properties:
compatible:
@@ -69,10 +81,18 @@ if:
- qcom,rpm-apq8084
- qcom,rpm-msm8916
- qcom,rpm-msm8974
+ - qcom,rpm-msm8976
- qcom,rpm-msm8953
then:
+ properties:
+ qcom,glink-channels: false
required:
- qcom,smd-channels
+else:
+ properties:
+ qcom,smd-channels: false
+ required:
+ - qcom,glink-channels
required:
- compatible
diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,smp2p.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,smp2p.yaml
index 795bd8cd4104..58500529b90f 100644
--- a/Documentation/devicetree/bindings/soc/qcom/qcom,smp2p.yaml
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,smp2p.yaml
@@ -60,7 +60,7 @@ properties:
Two identifiers of the inbound and outbound smem items used for this edge.
patternProperties:
- "^master-kernel|slave-kernel|ipa-ap-to-modem|ipa-modem-to-ap$":
+ "^master-kernel|slave-kernel|ipa-ap-to-modem|ipa-modem-to-ap|wlan-ap-to-wpss|wlan-wpss-to-ap$":
type: object
description:
Each SMP2P pair contain a set of inbound and outbound entries, these are
diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,spm.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,spm.yaml
index f433e6e0a19f..38818c37c3ea 100644
--- a/Documentation/devicetree/bindings/soc/qcom/qcom,spm.yaml
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,spm.yaml
@@ -24,8 +24,11 @@ properties:
- qcom,msm8998-silver-saw2-v4.1-l2
- qcom,msm8909-saw2-v3.0-cpu
- qcom,msm8916-saw2-v3.0-cpu
+ - qcom,msm8939-saw2-v3.0-cpu
- qcom,msm8226-saw2-v2.1-cpu
- qcom,msm8974-saw2-v2.1-cpu
+ - qcom,msm8976-gold-saw2-v2.3-l2
+ - qcom,msm8976-silver-saw2-v2.3-l2
- qcom,apq8084-saw2-v2.1-cpu
- qcom,apq8064-saw2-v1.1-cpu
- const: qcom,saw2
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index ead135c7044c..c2dec386c72e 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -494,6 +494,31 @@ void dev_pm_genpd_set_next_wakeup(struct device *dev, ktime_t next)
}
EXPORT_SYMBOL_GPL(dev_pm_genpd_set_next_wakeup);
+/**
+ * dev_pm_genpd_get_next_hrtimer - Return the next_hrtimer for the genpd
+ * @dev: A device that is attached to the genpd.
+ *
+ * This routine should typically be called for a device, at the point of when a
+ * GENPD_NOTIFY_PRE_OFF notification has been sent for it.
+ *
+ * Returns the aggregated value of the genpd's next hrtimer or KTIME_MAX if no
+ * valid value have been set.
+ */
+ktime_t dev_pm_genpd_get_next_hrtimer(struct device *dev)
+{
+ struct generic_pm_domain *genpd;
+
+ genpd = dev_to_genpd_safe(dev);
+ if (!genpd)
+ return KTIME_MAX;
+
+ if (genpd->gd)
+ return genpd->gd->next_hrtimer;
+
+ return KTIME_MAX;
+}
+EXPORT_SYMBOL_GPL(dev_pm_genpd_get_next_hrtimer);
+
static int _genpd_power_on(struct generic_pm_domain *genpd, bool timed)
{
unsigned int state_idx = genpd->state_idx;
@@ -1994,6 +2019,7 @@ static int genpd_alloc_data(struct generic_pm_domain *genpd)
gd->max_off_time_ns = -1;
gd->max_off_time_changed = true;
gd->next_wakeup = KTIME_MAX;
+ gd->next_hrtimer = KTIME_MAX;
}
/* Use only one "off" state if there were no states declared */
diff --git a/drivers/base/power/domain_governor.c b/drivers/base/power/domain_governor.c
index 282a3a135827..cc2c3a5a6d35 100644
--- a/drivers/base/power/domain_governor.c
+++ b/drivers/base/power/domain_governor.c
@@ -375,6 +375,9 @@ static bool cpu_power_down_ok(struct dev_pm_domain *pd)
if (idle_duration_ns <= 0)
return false;
+ /* Store the next domain_wakeup to allow consumers to use it. */
+ genpd->gd->next_hrtimer = domain_wakeup;
+
/*
* Find the deepest idle state that has its residency value satisfied
* and by also taking into account the power off latency for the state.
diff --git a/drivers/soc/qcom/apr.c b/drivers/soc/qcom/apr.c
index b4046f393575..cd44f17dad3d 100644
--- a/drivers/soc/qcom/apr.c
+++ b/drivers/soc/qcom/apr.c
@@ -454,11 +454,19 @@ static int apr_add_device(struct device *dev, struct device_node *np,
adev->dev.driver = NULL;
spin_lock(&apr->svcs_lock);
- idr_alloc(&apr->svcs_idr, svc, svc_id, svc_id + 1, GFP_ATOMIC);
+ ret = idr_alloc(&apr->svcs_idr, svc, svc_id, svc_id + 1, GFP_ATOMIC);
spin_unlock(&apr->svcs_lock);
+ if (ret < 0) {
+ dev_err(dev, "idr_alloc failed: %d\n", ret);
+ goto out;
+ }
- of_property_read_string_index(np, "qcom,protection-domain",
- 1, &adev->service_path);
+ ret = of_property_read_string_index(np, "qcom,protection-domain",
+ 1, &adev->service_path);
+ if (ret < 0) {
+ dev_err(dev, "Failed to read second value of qcom,protection-domain\n");
+ goto out;
+ }
dev_info(dev, "Adding APR/GPR dev: %s\n", dev_name(&adev->dev));
@@ -468,6 +476,7 @@ static int apr_add_device(struct device *dev, struct device_node *np,
put_device(&adev->dev);
}
+out:
return ret;
}
diff --git a/drivers/soc/qcom/cmd-db.c b/drivers/soc/qcom/cmd-db.c
index 629a7188b576..33856abd560c 100644
--- a/drivers/soc/qcom/cmd-db.c
+++ b/drivers/soc/qcom/cmd-db.c
@@ -338,6 +338,8 @@ static int cmd_db_dev_probe(struct platform_device *pdev)
debugfs_create_file("cmd-db", 0400, NULL, NULL, &cmd_db_debugfs_ops);
+ device_set_pm_not_required(&pdev->dev);
+
return 0;
}
diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c
index 8b7e8118f3ce..82c3cfdcc560 100644
--- a/drivers/soc/qcom/llcc-qcom.c
+++ b/drivers/soc/qcom/llcc-qcom.c
@@ -849,7 +849,7 @@ static int qcom_llcc_probe(struct platform_device *pdev)
if (ret)
goto err;
- drv_data->ecc_irq = platform_get_irq(pdev, 0);
+ drv_data->ecc_irq = platform_get_irq_optional(pdev, 0);
if (drv_data->ecc_irq >= 0) {
llcc_edac = platform_device_register_data(&pdev->dev,
"qcom_llcc_edac", -1, drv_data,
diff --git a/drivers/soc/qcom/pdr_internal.h b/drivers/soc/qcom/pdr_internal.h
index a30422214943..03c282b7f17e 100644
--- a/drivers/soc/qcom/pdr_internal.h
+++ b/drivers/soc/qcom/pdr_internal.h
@@ -28,7 +28,7 @@ struct servreg_location_entry {
u32 instance;
};
-static struct qmi_elem_info servreg_location_entry_ei[] = {
+static const struct qmi_elem_info servreg_location_entry_ei[] = {
{
.data_type = QMI_STRING,
.elem_len = SERVREG_NAME_LENGTH + 1,
@@ -74,7 +74,7 @@ struct servreg_get_domain_list_req {
u32 domain_offset;
};
-static struct qmi_elem_info servreg_get_domain_list_req_ei[] = {
+static const struct qmi_elem_info servreg_get_domain_list_req_ei[] = {
{
.data_type = QMI_STRING,
.elem_len = SERVREG_NAME_LENGTH + 1,
@@ -116,7 +116,7 @@ struct servreg_get_domain_list_resp {
struct servreg_location_entry domain_list[SERVREG_DOMAIN_LIST_LENGTH];
};
-static struct qmi_elem_info servreg_get_domain_list_resp_ei[] = {
+static const struct qmi_elem_info servreg_get_domain_list_resp_ei[] = {
{
.data_type = QMI_STRUCT,
.elem_len = 1,
@@ -199,7 +199,7 @@ struct servreg_register_listener_req {
char service_path[SERVREG_NAME_LENGTH + 1];
};
-static struct qmi_elem_info servreg_register_listener_req_ei[] = {
+static const struct qmi_elem_info servreg_register_listener_req_ei[] = {
{
.data_type = QMI_UNSIGNED_1_BYTE,
.elem_len = 1,
@@ -227,7 +227,7 @@ struct servreg_register_listener_resp {
enum servreg_service_state curr_state;
};
-static struct qmi_elem_info servreg_register_listener_resp_ei[] = {
+static const struct qmi_elem_info servreg_register_listener_resp_ei[] = {
{
.data_type = QMI_STRUCT,
.elem_len = 1,
@@ -263,7 +263,7 @@ struct servreg_restart_pd_req {
char service_path[SERVREG_NAME_LENGTH + 1];
};
-static struct qmi_elem_info servreg_restart_pd_req_ei[] = {
+static const struct qmi_elem_info servreg_restart_pd_req_ei[] = {
{
.data_type = QMI_STRING,
.elem_len = SERVREG_NAME_LENGTH + 1,
@@ -280,7 +280,7 @@ struct servreg_restart_pd_resp {
struct qmi_response_type_v01 resp;
};
-static struct qmi_elem_info servreg_restart_pd_resp_ei[] = {
+static const struct qmi_elem_info servreg_restart_pd_resp_ei[] = {
{
.data_type = QMI_STRUCT,
.elem_len = 1,
@@ -300,7 +300,7 @@ struct servreg_state_updated_ind {
u16 transaction_id;
};
-static struct qmi_elem_info servreg_state_updated_ind_ei[] = {
+static const struct qmi_elem_info servreg_state_updated_ind_ei[] = {
{
.data_type = QMI_SIGNED_4_BYTE_ENUM,
.elem_len = 1,
@@ -336,7 +336,7 @@ struct servreg_set_ack_req {
u16 transaction_id;
};
-static struct qmi_elem_info servreg_set_ack_req_ei[] = {
+static const struct qmi_elem_info servreg_set_ack_req_ei[] = {
{
.data_type = QMI_STRING,
.elem_len = SERVREG_NAME_LENGTH + 1,
@@ -362,7 +362,7 @@ struct servreg_set_ack_resp {
struct qmi_response_type_v01 resp;
};
-static struct qmi_elem_info servreg_set_ack_resp_ei[] = {
+static const struct qmi_elem_info servreg_set_ack_resp_ei[] = {
{
.data_type = QMI_STRUCT,
.elem_len = 1,
diff --git a/drivers/soc/qcom/qcom_stats.c b/drivers/soc/qcom/qcom_stats.c
index 121ea409fafc..6228af057120 100644
--- a/drivers/soc/qcom/qcom_stats.c
+++ b/drivers/soc/qcom/qcom_stats.c
@@ -217,6 +217,8 @@ static int qcom_stats_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, root);
+ device_set_pm_not_required(&pdev->dev);
+
return 0;
}
diff --git a/drivers/soc/qcom/rpmh-internal.h b/drivers/soc/qcom/rpmh-internal.h
index 344ba687c13b..39f53586f724 100644
--- a/drivers/soc/qcom/rpmh-internal.h
+++ b/drivers/soc/qcom/rpmh-internal.h
@@ -91,13 +91,15 @@ struct rpmh_ctrlr {
* Resource State Coordinator controller (RSC)
*
* @name: Controller identifier.
+ * @base: Start address of the DRV registers in this controller.
* @tcs_base: Start address of the TCS registers in this controller.
* @id: Instance id in the controller (Direct Resource Voter).
* @num_tcs: Number of TCSes in this DRV.
* @rsc_pm: CPU PM notifier for controller.
* Used when solver mode is not present.
* @cpus_in_pm: Number of CPUs not in idle power collapse.
- * Used when solver mode is not present.
+ * Used when solver mode and "power-domains" is not present.
+ * @genpd_nb: PM Domain notifier for cluster genpd notifications.
* @tcs: TCS groups.
* @tcs_in_use: S/W state of the TCS; only set for ACTIVE_ONLY
* transfers, but might show a sleep/wake TCS in use if
@@ -110,25 +112,30 @@ struct rpmh_ctrlr {
* @tcs_wait: Wait queue used to wait for @tcs_in_use to free up a
* slot
* @client: Handle to the DRV's client.
+ * @dev: RSC device.
*/
struct rsc_drv {
const char *name;
+ void __iomem *base;
void __iomem *tcs_base;
int id;
int num_tcs;
struct notifier_block rsc_pm;
+ struct notifier_block genpd_nb;
atomic_t cpus_in_pm;
struct tcs_group tcs[TCS_TYPE_NR];
DECLARE_BITMAP(tcs_in_use, MAX_TCS_NR);
spinlock_t lock;
wait_queue_head_t tcs_wait;
struct rpmh_ctrlr client;
+ struct device *dev;
};
int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg);
int rpmh_rsc_write_ctrl_data(struct rsc_drv *drv,
const struct tcs_request *msg);
void rpmh_rsc_invalidate(struct rsc_drv *drv);
+void rpmh_rsc_write_next_wakeup(struct rsc_drv *drv);
void rpmh_tx_done(const struct tcs_request *msg, int r);
int rpmh_flush(struct rpmh_ctrlr *ctrlr);
diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c
index 01c2f50cb97e..c51567b778ef 100644
--- a/drivers/soc/qcom/rpmh-rsc.c
+++ b/drivers/soc/qcom/rpmh-rsc.c
@@ -12,16 +12,21 @@
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/kernel.h>
+#include <linux/ktime.h>
#include <linux/list.h>
#include <linux/module.h>
+#include <linux/notifier.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/wait.h>
+#include <clocksource/arm_arch_timer.h>
#include <soc/qcom/cmd-db.h>
#include <soc/qcom/tcs.h>
#include <dt-bindings/soc/qcom,rpmh-rsc.h>
@@ -46,6 +51,14 @@
#define DRV_NCPT_MASK 0x1F
#define DRV_NCPT_SHIFT 27
+/* Offsets for CONTROL TCS Registers */
+#define RSC_DRV_CTL_TCS_DATA_HI 0x38
+#define RSC_DRV_CTL_TCS_DATA_HI_MASK 0xFFFFFF
+#define RSC_DRV_CTL_TCS_DATA_HI_VALID BIT(31)
+#define RSC_DRV_CTL_TCS_DATA_LO 0x40
+#define RSC_DRV_CTL_TCS_DATA_LO_MASK 0xFFFFFFFF
+#define RSC_DRV_CTL_TCS_DATA_SIZE 32
+
/* Offsets for common TCS Registers, one bit per TCS */
#define RSC_DRV_IRQ_ENABLE 0x00
#define RSC_DRV_IRQ_STATUS 0x04
@@ -139,6 +152,14 @@
* +---------------------------------------------------+
*/
+#define USECS_TO_CYCLES(time_usecs) \
+ xloops_to_cycles((time_usecs) * 0x10C7UL)
+
+static inline unsigned long xloops_to_cycles(u64 xloops)
+{
+ return (xloops * loops_per_jiffy * HZ) >> 32;
+}
+
static inline void __iomem *
tcs_reg_addr(const struct rsc_drv *drv, int reg, int tcs_id)
{
@@ -754,6 +775,48 @@ static bool rpmh_rsc_ctrlr_is_busy(struct rsc_drv *drv)
}
/**
+ * rpmh_rsc_write_next_wakeup() - Write next wakeup in CONTROL_TCS.
+ * @drv: The controller
+ *
+ * Writes maximum wakeup cycles when called from suspend.
+ * Writes earliest hrtimer wakeup when called from idle.
+ */
+void rpmh_rsc_write_next_wakeup(struct rsc_drv *drv)
+{
+ ktime_t now, wakeup;
+ u64 wakeup_us, wakeup_cycles = ~0;
+ u32 lo, hi;
+
+ if (!drv->tcs[CONTROL_TCS].num_tcs || !drv->genpd_nb.notifier_call)
+ return;
+
+ /* Set highest time when system (timekeeping) is suspended */
+ if (system_state == SYSTEM_SUSPEND)
+ goto exit;
+
+ /* Find the earliest hrtimer wakeup from online cpus */
+ wakeup = dev_pm_genpd_get_next_hrtimer(drv->dev);
+
+ /* Find the relative wakeup in kernel time scale */
+ now = ktime_get();
+ wakeup = ktime_sub(wakeup, now);
+ wakeup_us = ktime_to_us(wakeup);
+
+ /* Convert the wakeup to arch timer scale */
+ wakeup_cycles = USECS_TO_CYCLES(wakeup_us);
+ wakeup_cycles += arch_timer_read_counter();
+
+exit:
+ lo = wakeup_cycles & RSC_DRV_CTL_TCS_DATA_LO_MASK;
+ hi = wakeup_cycles >> RSC_DRV_CTL_TCS_DATA_SIZE;
+ hi &= RSC_DRV_CTL_TCS_DATA_HI_MASK;
+ hi |= RSC_DRV_CTL_TCS_DATA_HI_VALID;
+
+ writel_relaxed(lo, drv->base + RSC_DRV_CTL_TCS_DATA_LO);
+ writel_relaxed(hi, drv->base + RSC_DRV_CTL_TCS_DATA_HI);
+}
+
+/**
* rpmh_rsc_cpu_pm_callback() - Check if any of the AMCs are busy.
* @nfb: Pointer to the notifier block in struct rsc_drv.
* @action: CPU_PM_ENTER, CPU_PM_ENTER_FAILED, or CPU_PM_EXIT.
@@ -834,8 +897,51 @@ static int rpmh_rsc_cpu_pm_callback(struct notifier_block *nfb,
return ret;
}
-static int rpmh_probe_tcs_config(struct platform_device *pdev,
- struct rsc_drv *drv, void __iomem *base)
+/**
+ * rpmh_rsc_pd_callback() - Check if any of the AMCs are busy.
+ * @nfb: Pointer to the genpd notifier block in struct rsc_drv.
+ * @action: GENPD_NOTIFY_PRE_OFF, GENPD_NOTIFY_OFF, GENPD_NOTIFY_PRE_ON or GENPD_NOTIFY_ON.
+ * @v: Unused
+ *
+ * This function is given to dev_pm_genpd_add_notifier() so we can be informed
+ * about when cluster-pd is going down. When cluster go down we know no more active
+ * transfers will be started so we write sleep/wake sets. This function gets
+ * called from cpuidle code paths and also at system suspend time.
+ *
+ * If AMCs are not busy then writes cached sleep and wake messages to TCSes.
+ * The firmware then takes care of triggering them when entering deepest low power modes.
+ *
+ * Return:
+ * * NOTIFY_OK - success
+ * * NOTIFY_BAD - failure
+ */
+static int rpmh_rsc_pd_callback(struct notifier_block *nfb,
+ unsigned long action, void *v)
+{
+ struct rsc_drv *drv = container_of(nfb, struct rsc_drv, genpd_nb);
+
+ /* We don't need to lock as genpd on/off are serialized */
+ if ((action == GENPD_NOTIFY_PRE_OFF) &&
+ (rpmh_rsc_ctrlr_is_busy(drv) || rpmh_flush(&drv->client)))
+ return NOTIFY_BAD;
+
+ return NOTIFY_OK;
+}
+
+static int rpmh_rsc_pd_attach(struct rsc_drv *drv, struct device *dev)
+{
+ int ret;
+
+ pm_runtime_enable(dev);
+ drv->genpd_nb.notifier_call = rpmh_rsc_pd_callback;
+ ret = dev_pm_genpd_add_notifier(dev, &drv->genpd_nb);
+ if (ret)
+ pm_runtime_disable(dev);
+
+ return ret;
+}
+
+static int rpmh_probe_tcs_config(struct platform_device *pdev, struct rsc_drv *drv)
{
struct tcs_type_config {
u32 type;
@@ -849,9 +955,9 @@ static int rpmh_probe_tcs_config(struct platform_device *pdev,
ret = of_property_read_u32(dn, "qcom,tcs-offset", &offset);
if (ret)
return ret;
- drv->tcs_base = base + offset;
+ drv->tcs_base = drv->base + offset;
- config = readl_relaxed(base + DRV_PRNT_CHLD_CONFIG);
+ config = readl_relaxed(drv->base + DRV_PRNT_CHLD_CONFIG);
max_tcs = config;
max_tcs &= DRV_NUM_TCS_MASK << (DRV_NUM_TCS_SHIFT * drv->id);
@@ -913,7 +1019,6 @@ static int rpmh_rsc_probe(struct platform_device *pdev)
char drv_id[10] = {0};
int ret, irq;
u32 solver_config;
- void __iomem *base;
/*
* Even though RPMh doesn't directly use cmd-db, all of its children
@@ -940,11 +1045,11 @@ static int rpmh_rsc_probe(struct platform_device *pdev)
drv->name = dev_name(&pdev->dev);
snprintf(drv_id, ARRAY_SIZE(drv_id), "drv-%d", drv->id);
- base = devm_platform_ioremap_resource_byname(pdev, drv_id);
- if (IS_ERR(base))
- return PTR_ERR(base);
+ drv->base = devm_platform_ioremap_resource_byname(pdev, drv_id);
+ if (IS_ERR(drv->base))
+ return PTR_ERR(drv->base);
- ret = rpmh_probe_tcs_config(pdev, drv, base);
+ ret = rpmh_probe_tcs_config(pdev, drv);
if (ret)
return ret;
@@ -963,16 +1068,22 @@ static int rpmh_rsc_probe(struct platform_device *pdev)
return ret;
/*
- * CPU PM notification are not required for controllers that support
+ * CPU PM/genpd notification are not required for controllers that support
* 'HW solver' mode where they can be in autonomous mode executing low
* power mode to power down.
*/
- solver_config = readl_relaxed(base + DRV_SOLVER_CONFIG);
+ solver_config = readl_relaxed(drv->base + DRV_SOLVER_CONFIG);
solver_config &= DRV_HW_SOLVER_MASK << DRV_HW_SOLVER_SHIFT;
solver_config = solver_config >> DRV_HW_SOLVER_SHIFT;
if (!solver_config) {
- drv->rsc_pm.notifier_call = rpmh_rsc_cpu_pm_callback;
- cpu_pm_register_notifier(&drv->rsc_pm);
+ if (pdev->dev.pm_domain) {
+ ret = rpmh_rsc_pd_attach(drv, &pdev->dev);
+ if (ret)
+ return ret;
+ } else {
+ drv->rsc_pm.notifier_call = rpmh_rsc_cpu_pm_callback;
+ cpu_pm_register_notifier(&drv->rsc_pm);
+ }
}
/* Enable the active TCS to send requests immediately */
@@ -984,8 +1095,15 @@ static int rpmh_rsc_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&drv->client.batch_cache);
dev_set_drvdata(&pdev->dev, drv);
+ drv->dev = &pdev->dev;
- return devm_of_platform_populate(&pdev->dev);
+ ret = devm_of_platform_populate(&pdev->dev);
+ if (ret && pdev->dev.pm_domain) {
+ dev_pm_genpd_remove_notifier(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+ }
+
+ return ret;
}
static const struct of_device_id rpmh_drv_match[] = {
diff --git a/drivers/soc/qcom/rpmh.c b/drivers/soc/qcom/rpmh.c
index 01765ee9cdfb..3a53ed99d03c 100644
--- a/drivers/soc/qcom/rpmh.c
+++ b/drivers/soc/qcom/rpmh.c
@@ -450,7 +450,7 @@ int rpmh_flush(struct rpmh_ctrlr *ctrlr)
if (!ctrlr->dirty) {
pr_debug("Skipping flush, TCS has latest data.\n");
- goto exit;
+ goto write_next_wakeup;
}
/* Invalidate the TCSes first to avoid stale data */
@@ -479,6 +479,8 @@ int rpmh_flush(struct rpmh_ctrlr *ctrlr)
ctrlr->dirty = false;
+write_next_wakeup:
+ rpmh_rsc_write_next_wakeup(ctrlr_to_drv(ctrlr));
exit:
spin_unlock(&ctrlr->cache_lock);
return ret;
diff --git a/drivers/soc/qcom/rpmhpd.c b/drivers/soc/qcom/rpmhpd.c
index 092f6ab09acf..7af68cd720f5 100644
--- a/drivers/soc/qcom/rpmhpd.c
+++ b/drivers/soc/qcom/rpmhpd.c
@@ -39,6 +39,7 @@
* @res_name: Resource name used for cmd-db lookup
* @addr: Resource address as looped up using resource name from
* cmd-db
+ * @state_synced: Indicator that sync_state has been invoked for the rpmhpd resource
*/
struct rpmhpd {
struct device *dev;
@@ -54,6 +55,7 @@ struct rpmhpd {
bool enabled;
const char *res_name;
u32 addr;
+ bool state_synced;
};
struct rpmhpd_desc {
@@ -210,6 +212,23 @@ static const struct rpmhpd_desc sa8540p_desc = {
.num_pds = ARRAY_SIZE(sa8540p_rpmhpds),
};
+/* SDM670 RPMH powerdomains */
+static struct rpmhpd *sdm670_rpmhpds[] = {
+ [SDM670_CX] = &cx_w_mx_parent,
+ [SDM670_CX_AO] = &cx_ao_w_mx_parent,
+ [SDM670_GFX] = &gfx,
+ [SDM670_LCX] = &lcx,
+ [SDM670_LMX] = &lmx,
+ [SDM670_MSS] = &mss,
+ [SDM670_MX] = &mx,
+ [SDM670_MX_AO] = &mx_ao,
+};
+
+static const struct rpmhpd_desc sdm670_desc = {
+ .rpmhpds = sdm670_rpmhpds,
+ .num_pds = ARRAY_SIZE(sdm670_rpmhpds),
+};
+
/* SDM845 RPMH powerdomains */
static struct rpmhpd *sdm845_rpmhpds[] = {
[SDM845_CX] = &cx_w_mx_parent,
@@ -353,6 +372,19 @@ static const struct rpmhpd_desc sm8450_desc = {
.num_pds = ARRAY_SIZE(sm8450_rpmhpds),
};
+/* QDU1000/QRU1000 RPMH powerdomains */
+static struct rpmhpd *qdu1000_rpmhpds[] = {
+ [QDU1000_CX] = &cx,
+ [QDU1000_EBI] = &ebi,
+ [QDU1000_MSS] = &mss,
+ [QDU1000_MX] = &mx,
+};
+
+static const struct rpmhpd_desc qdu1000_desc = {
+ .rpmhpds = qdu1000_rpmhpds,
+ .num_pds = ARRAY_SIZE(qdu1000_rpmhpds),
+};
+
/* SC7180 RPMH powerdomains */
static struct rpmhpd *sc7180_rpmhpds[] = {
[SC7180_CX] = &cx_w_mx_parent,
@@ -430,11 +462,13 @@ static const struct rpmhpd_desc sc8280xp_desc = {
};
static const struct of_device_id rpmhpd_match_table[] = {
+ { .compatible = "qcom,qdu1000-rpmhpd", .data = &qdu1000_desc },
{ .compatible = "qcom,sa8540p-rpmhpd", .data = &sa8540p_desc },
{ .compatible = "qcom,sc7180-rpmhpd", .data = &sc7180_desc },
{ .compatible = "qcom,sc7280-rpmhpd", .data = &sc7280_desc },
{ .compatible = "qcom,sc8180x-rpmhpd", .data = &sc8180x_desc },
{ .compatible = "qcom,sc8280xp-rpmhpd", .data = &sc8280xp_desc },
+ { .compatible = "qcom,sdm670-rpmhpd", .data = &sdm670_desc },
{ .compatible = "qcom,sdm845-rpmhpd", .data = &sdm845_desc },
{ .compatible = "qcom,sdx55-rpmhpd", .data = &sdx55_desc},
{ .compatible = "qcom,sdx65-rpmhpd", .data = &sdx65_desc},
@@ -493,7 +527,13 @@ static int rpmhpd_aggregate_corner(struct rpmhpd *pd, unsigned int corner)
unsigned int this_active_corner = 0, this_sleep_corner = 0;
unsigned int peer_active_corner = 0, peer_sleep_corner = 0;
- to_active_sleep(pd, corner, &this_active_corner, &this_sleep_corner);
+ if (pd->state_synced) {
+ to_active_sleep(pd, corner, &this_active_corner, &this_sleep_corner);
+ } else {
+ /* Clamp to highest corner if sync_state hasn't happened */
+ this_active_corner = pd->level_count - 1;
+ this_sleep_corner = pd->level_count - 1;
+ }
if (peer && peer->enabled)
to_active_sleep(peer, peer->corner, &peer_active_corner,
@@ -708,11 +748,40 @@ static int rpmhpd_probe(struct platform_device *pdev)
return of_genpd_add_provider_onecell(pdev->dev.of_node, data);
}
+static void rpmhpd_sync_state(struct device *dev)
+{
+ const struct rpmhpd_desc *desc = of_device_get_match_data(dev);
+ struct rpmhpd **rpmhpds = desc->rpmhpds;
+ unsigned int corner;
+ struct rpmhpd *pd;
+ unsigned int i;
+ int ret;
+
+ mutex_lock(&rpmhpd_lock);
+ for (i = 0; i < desc->num_pds; i++) {
+ pd = rpmhpds[i];
+ if (!pd)
+ continue;
+
+ pd->state_synced = true;
+ if (pd->enabled)
+ corner = max(pd->corner, pd->enable_corner);
+ else
+ corner = 0;
+
+ ret = rpmhpd_aggregate_corner(pd, corner);
+ if (ret)
+ dev_err(dev, "failed to sync %s\n", pd->res_name);
+ }
+ mutex_unlock(&rpmhpd_lock);
+}
+
static struct platform_driver rpmhpd_driver = {
.driver = {
.name = "qcom-rpmhpd",
.of_match_table = rpmhpd_match_table,
.suppress_bind_attrs = true,
+ .sync_state = rpmhpd_sync_state,
},
.probe = rpmhpd_probe,
};
diff --git a/drivers/soc/qcom/smd-rpm.c b/drivers/soc/qcom/smd-rpm.c
index 413f9f4ae9cd..7e3b6a7ea34c 100644
--- a/drivers/soc/qcom/smd-rpm.c
+++ b/drivers/soc/qcom/smd-rpm.c
@@ -75,7 +75,7 @@ struct qcom_rpm_message {
__le32 length;
union {
__le32 msg_id;
- u8 message[0];
+ DECLARE_FLEX_ARRAY(u8, message);
};
};
@@ -246,6 +246,7 @@ static const struct of_device_id qcom_smd_rpm_of_match[] = {
{ .compatible = "qcom,rpm-sdm660" },
{ .compatible = "qcom,rpm-sm6115" },
{ .compatible = "qcom,rpm-sm6125" },
+ { .compatible = "qcom,rpm-sm6375" },
{ .compatible = "qcom,rpm-qcm2290" },
{ .compatible = "qcom,rpm-qcs404" },
{}
diff --git a/drivers/soc/qcom/smp2p.c b/drivers/soc/qcom/smp2p.c
index d9c28a8a7cbf..e9c8030d50ee 100644
--- a/drivers/soc/qcom/smp2p.c
+++ b/drivers/soc/qcom/smp2p.c
@@ -422,7 +422,7 @@ static int qcom_smp2p_outbound_entry(struct qcom_smp2p *smp2p,
char buf[SMP2P_MAX_ENTRY_NAME] = {};
/* Allocate an entry from the smem item */
- strlcpy(buf, entry->name, SMP2P_MAX_ENTRY_NAME);
+ strscpy(buf, entry->name, SMP2P_MAX_ENTRY_NAME);
memcpy(out->entries[out->valid_entries].name, buf, SMP2P_MAX_ENTRY_NAME);
/* Make the logical entry reference the physical value */
diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c
index aa37e1bad095..545934aead43 100644
--- a/drivers/soc/qcom/socinfo.c
+++ b/drivers/soc/qcom/socinfo.c
@@ -12,11 +12,14 @@
#include <linux/slab.h>
#include <linux/soc/qcom/smem.h>
#include <linux/string.h>
+#include <linux/stringify.h>
#include <linux/sys_soc.h>
#include <linux/types.h>
#include <asm/unaligned.h>
+#include <dt-bindings/arm/qcom,ids.h>
+
/*
* SoC version type with major number in the upper 16 bits and minor
* number in the lower 16 bits.
@@ -25,6 +28,10 @@
#define SOCINFO_MINOR(ver) ((ver) & 0xffff)
#define SOCINFO_VERSION(maj, min) ((((maj) & 0xffff) << 16)|((min) & 0xffff))
+/* Helper macros to create soc_id table */
+#define qcom_board_id(id) QCOM_ID_ ## id, __stringify(id)
+#define qcom_board_id_named(id, name) QCOM_ID_ ## id, (name)
+
#define SMEM_SOCINFO_BUILD_ID_LENGTH 32
#define SMEM_SOCINFO_CHIP_ID_LENGTH 32
@@ -207,135 +214,141 @@ struct soc_id {
};
static const struct soc_id soc_id[] = {
- { 87, "MSM8960" },
- { 109, "APQ8064" },
- { 122, "MSM8660A" },
- { 123, "MSM8260A" },
- { 124, "APQ8060A" },
- { 126, "MSM8974" },
- { 130, "MPQ8064" },
- { 138, "MSM8960AB" },
- { 139, "APQ8060AB" },
- { 140, "MSM8260AB" },
- { 141, "MSM8660AB" },
- { 145, "MSM8626" },
- { 147, "MSM8610" },
- { 153, "APQ8064AB" },
- { 158, "MSM8226" },
- { 159, "MSM8526" },
- { 161, "MSM8110" },
- { 162, "MSM8210" },
- { 163, "MSM8810" },
- { 164, "MSM8212" },
- { 165, "MSM8612" },
- { 166, "MSM8112" },
- { 168, "MSM8225Q" },
- { 169, "MSM8625Q" },
- { 170, "MSM8125Q" },
- { 172, "APQ8064AA" },
- { 178, "APQ8084" },
- { 184, "APQ8074" },
- { 185, "MSM8274" },
- { 186, "MSM8674" },
- { 194, "MSM8974PRO-AC" },
- { 198, "MSM8126" },
- { 199, "APQ8026" },
- { 200, "MSM8926" },
- { 205, "MSM8326" },
- { 206, "MSM8916" },
- { 207, "MSM8994" },
- { 208, "APQ8074PRO-AA" },
- { 209, "APQ8074PRO-AB" },
- { 210, "APQ8074PRO-AC" },
- { 211, "MSM8274PRO-AA" },
- { 212, "MSM8274PRO-AB" },
- { 213, "MSM8274PRO-AC" },
- { 214, "MSM8674PRO-AA" },
- { 215, "MSM8674PRO-AB" },
- { 216, "MSM8674PRO-AC" },
- { 217, "MSM8974PRO-AA" },
- { 218, "MSM8974PRO-AB" },
- { 219, "APQ8028" },
- { 220, "MSM8128" },
- { 221, "MSM8228" },
- { 222, "MSM8528" },
- { 223, "MSM8628" },
- { 224, "MSM8928" },
- { 225, "MSM8510" },
- { 226, "MSM8512" },
- { 233, "MSM8936" },
- { 239, "MSM8939" },
- { 240, "APQ8036" },
- { 241, "APQ8039" },
- { 246, "MSM8996" },
- { 247, "APQ8016" },
- { 248, "MSM8216" },
- { 249, "MSM8116" },
- { 250, "MSM8616" },
- { 251, "MSM8992" },
- { 253, "APQ8094" },
- { 290, "MDM9607" },
- { 291, "APQ8096" },
- { 292, "MSM8998" },
- { 293, "MSM8953" },
- { 296, "MDM8207" },
- { 297, "MDM9207" },
- { 298, "MDM9307" },
- { 299, "MDM9628" },
- { 304, "APQ8053" },
- { 305, "MSM8996SG" },
- { 310, "MSM8996AU" },
- { 311, "APQ8096AU" },
- { 312, "APQ8096SG" },
- { 317, "SDM660" },
- { 318, "SDM630" },
- { 319, "APQ8098" },
- { 321, "SDM845" },
- { 322, "MDM9206" },
- { 323, "IPQ8074" },
- { 324, "SDA660" },
- { 325, "SDM658" },
- { 326, "SDA658" },
- { 327, "SDA630" },
- { 338, "SDM450" },
- { 341, "SDA845" },
- { 342, "IPQ8072" },
- { 343, "IPQ8076" },
- { 344, "IPQ8078" },
- { 345, "SDM636" },
- { 346, "SDA636" },
- { 349, "SDM632" },
- { 350, "SDA632" },
- { 351, "SDA450" },
- { 356, "SM8250" },
- { 375, "IPQ8070" },
- { 376, "IPQ8071" },
- { 389, "IPQ8072A" },
- { 390, "IPQ8074A" },
- { 391, "IPQ8076A" },
- { 392, "IPQ8078A" },
- { 394, "SM6125" },
- { 395, "IPQ8070A" },
- { 396, "IPQ8071A" },
- { 402, "IPQ6018" },
- { 403, "IPQ6028" },
- { 421, "IPQ6000" },
- { 422, "IPQ6010" },
- { 425, "SC7180" },
- { 434, "SM6350" },
- { 439, "SM8350" },
- { 449, "SC8280XP" },
- { 453, "IPQ6005" },
- { 455, "QRB5165" },
- { 457, "SM8450" },
- { 459, "SM7225" },
- { 460, "SA8295P" },
- { 461, "SA8540P" },
- { 480, "SM8450" },
- { 482, "SM8450" },
- { 487, "SC7280" },
- { 495, "SC7180P" },
- { 507, "SM6375" },
+ { qcom_board_id(MSM8960) },
+ { qcom_board_id(APQ8064) },
+ { qcom_board_id(MSM8660A) },
+ { qcom_board_id(MSM8260A) },
+ { qcom_board_id(APQ8060A) },
+ { qcom_board_id(MSM8974) },
+ { qcom_board_id(MPQ8064) },
+ { qcom_board_id(MSM8960AB) },
+ { qcom_board_id(APQ8060AB) },
+ { qcom_board_id(MSM8260AB) },
+ { qcom_board_id(MSM8660AB) },
+ { qcom_board_id(MSM8626) },
+ { qcom_board_id(MSM8610) },
+ { qcom_board_id(APQ8064AB) },
+ { qcom_board_id(MSM8226) },
+ { qcom_board_id(MSM8526) },
+ { qcom_board_id(MSM8110) },
+ { qcom_board_id(MSM8210) },
+ { qcom_board_id(MSM8810) },
+ { qcom_board_id(MSM8212) },
+ { qcom_board_id(MSM8612) },
+ { qcom_board_id(MSM8112) },
+ { qcom_board_id(MSM8225Q) },
+ { qcom_board_id(MSM8625Q) },
+ { qcom_board_id(MSM8125Q) },
+ { qcom_board_id(APQ8064AA) },
+ { qcom_board_id(APQ8084) },
+ { qcom_board_id(APQ8074) },
+ { qcom_board_id(MSM8274) },
+ { qcom_board_id(MSM8674) },
+ { qcom_board_id_named(MSM8974PRO_AC, "MSM8974PRO-AC") },
+ { qcom_board_id(MSM8126) },
+ { qcom_board_id(APQ8026) },
+ { qcom_board_id(MSM8926) },
+ { qcom_board_id(MSM8326) },
+ { qcom_board_id(MSM8916) },
+ { qcom_board_id(MSM8994) },
+ { qcom_board_id_named(APQ8074PRO_AA, "APQ8074PRO-AA") },
+ { qcom_board_id_named(APQ8074PRO_AB, "APQ8074PRO-AB") },
+ { qcom_board_id_named(APQ8074PRO_AC, "APQ8074PRO-AC") },
+ { qcom_board_id_named(MSM8274PRO_AA, "MSM8274PRO-AA") },
+ { qcom_board_id_named(MSM8274PRO_AB, "MSM8274PRO-AB") },
+ { qcom_board_id_named(MSM8274PRO_AC, "MSM8274PRO-AC") },
+ { qcom_board_id_named(MSM8674PRO_AA, "MSM8674PRO-AA") },
+ { qcom_board_id_named(MSM8674PRO_AB, "MSM8674PRO-AB") },
+ { qcom_board_id_named(MSM8674PRO_AC, "MSM8674PRO-AC") },
+ { qcom_board_id_named(MSM8974PRO_AA, "MSM8974PRO-AA") },
+ { qcom_board_id_named(MSM8974PRO_AB, "MSM8974PRO-AB") },
+ { qcom_board_id(APQ8028) },
+ { qcom_board_id(MSM8128) },
+ { qcom_board_id(MSM8228) },
+ { qcom_board_id(MSM8528) },
+ { qcom_board_id(MSM8628) },
+ { qcom_board_id(MSM8928) },
+ { qcom_board_id(MSM8510) },
+ { qcom_board_id(MSM8512) },
+ { qcom_board_id(MSM8936) },
+ { qcom_board_id(MSM8939) },
+ { qcom_board_id(APQ8036) },
+ { qcom_board_id(APQ8039) },
+ { qcom_board_id(MSM8996) },
+ { qcom_board_id(APQ8016) },
+ { qcom_board_id(MSM8216) },
+ { qcom_board_id(MSM8116) },
+ { qcom_board_id(MSM8616) },
+ { qcom_board_id(MSM8992) },
+ { qcom_board_id(APQ8094) },
+ { qcom_board_id(MDM9607) },
+ { qcom_board_id(APQ8096) },
+ { qcom_board_id(MSM8998) },
+ { qcom_board_id(MSM8953) },
+ { qcom_board_id(MDM8207) },
+ { qcom_board_id(MDM9207) },
+ { qcom_board_id(MDM9307) },
+ { qcom_board_id(MDM9628) },
+ { qcom_board_id(APQ8053) },
+ { qcom_board_id(MSM8996SG) },
+ { qcom_board_id(MSM8996AU) },
+ { qcom_board_id(APQ8096AU) },
+ { qcom_board_id(APQ8096SG) },
+ { qcom_board_id(SDM660) },
+ { qcom_board_id(SDM630) },
+ { qcom_board_id(APQ8098) },
+ { qcom_board_id(SDM845) },
+ { qcom_board_id(MDM9206) },
+ { qcom_board_id(IPQ8074) },
+ { qcom_board_id(SDA660) },
+ { qcom_board_id(SDM658) },
+ { qcom_board_id(SDA658) },
+ { qcom_board_id(SDA630) },
+ { qcom_board_id(SDM450) },
+ { qcom_board_id(SDA845) },
+ { qcom_board_id(IPQ8072) },
+ { qcom_board_id(IPQ8076) },
+ { qcom_board_id(IPQ8078) },
+ { qcom_board_id(SDM636) },
+ { qcom_board_id(SDA636) },
+ { qcom_board_id(SDM632) },
+ { qcom_board_id(SDA632) },
+ { qcom_board_id(SDA450) },
+ { qcom_board_id(SM8250) },
+ { qcom_board_id(IPQ8070) },
+ { qcom_board_id(IPQ8071) },
+ { qcom_board_id(IPQ8072A) },
+ { qcom_board_id(IPQ8074A) },
+ { qcom_board_id(IPQ8076A) },
+ { qcom_board_id(IPQ8078A) },
+ { qcom_board_id(SM6125) },
+ { qcom_board_id(IPQ8070A) },
+ { qcom_board_id(IPQ8071A) },
+ { qcom_board_id(IPQ6018) },
+ { qcom_board_id(IPQ6028) },
+ { qcom_board_id(IPQ6000) },
+ { qcom_board_id(IPQ6010) },
+ { qcom_board_id(SC7180) },
+ { qcom_board_id(SM6350) },
+ { qcom_board_id(SM8350) },
+ { qcom_board_id(SC8280XP) },
+ { qcom_board_id(IPQ6005) },
+ { qcom_board_id(QRB5165) },
+ { qcom_board_id(SM8450) },
+ { qcom_board_id(SM7225) },
+ { qcom_board_id(SA8295P) },
+ { qcom_board_id(SA8540P) },
+ { qcom_board_id_named(SM8450_2, "SM8450") },
+ { qcom_board_id_named(SM8450_3, "SM8450") },
+ { qcom_board_id(SC7280) },
+ { qcom_board_id(SC7180P) },
+ { qcom_board_id(SM6375) },
+ { qcom_board_id(QRU1000) },
+ { qcom_board_id(QDU1000) },
+ { qcom_board_id(QDU1010) },
+ { qcom_board_id(QRU1032) },
+ { qcom_board_id(QRU1052) },
+ { qcom_board_id(QRU1062) },
};
static const char *socinfo_machine(struct device *dev, unsigned int id)
diff --git a/drivers/soc/qcom/spm.c b/drivers/soc/qcom/spm.c
index 484b42b7454e..a6cbeb40831b 100644
--- a/drivers/soc/qcom/spm.c
+++ b/drivers/soc/qcom/spm.c
@@ -98,6 +98,46 @@ static const struct spm_reg_data spm_reg_8916_cpu = {
.start_index[PM_SLEEP_MODE_SPC] = 5,
};
+static const struct spm_reg_data spm_reg_8939_cpu = {
+ .reg_offset = spm_reg_offset_v3_0,
+ .spm_cfg = 0x1,
+ .spm_dly = 0x3C102800,
+ .seq = { 0x60, 0x03, 0x60, 0x0B, 0x0F, 0x20, 0x50, 0x1B, 0x10, 0x80,
+ 0x30, 0x90, 0x5B, 0x60, 0x50, 0x03, 0x60, 0x76, 0x76, 0x0B,
+ 0x50, 0x1B, 0x94, 0x5B, 0x80, 0x10, 0x26, 0x30, 0x50, 0x0F },
+ .start_index[PM_SLEEP_MODE_STBY] = 0,
+ .start_index[PM_SLEEP_MODE_SPC] = 5,
+};
+
+static const u16 spm_reg_offset_v2_3[SPM_REG_NR] = {
+ [SPM_REG_CFG] = 0x08,
+ [SPM_REG_SPM_CTL] = 0x30,
+ [SPM_REG_DLY] = 0x34,
+ [SPM_REG_PMIC_DATA_0] = 0x40,
+ [SPM_REG_PMIC_DATA_1] = 0x44,
+};
+
+/* SPM register data for 8976 */
+static const struct spm_reg_data spm_reg_8976_gold_l2 = {
+ .reg_offset = spm_reg_offset_v2_3,
+ .spm_cfg = 0x14,
+ .spm_dly = 0x3c11840a,
+ .pmic_data[0] = 0x03030080,
+ .pmic_data[1] = 0x00030000,
+ .start_index[PM_SLEEP_MODE_STBY] = 0,
+ .start_index[PM_SLEEP_MODE_SPC] = 3,
+};
+
+static const struct spm_reg_data spm_reg_8976_silver_l2 = {
+ .reg_offset = spm_reg_offset_v2_3,
+ .spm_cfg = 0x14,
+ .spm_dly = 0x3c102800,
+ .pmic_data[0] = 0x03030080,
+ .pmic_data[1] = 0x00030000,
+ .start_index[PM_SLEEP_MODE_STBY] = 0,
+ .start_index[PM_SLEEP_MODE_SPC] = 2,
+};
+
static const u16 spm_reg_offset_v2_1[SPM_REG_NR] = {
[SPM_REG_CFG] = 0x08,
[SPM_REG_SPM_CTL] = 0x30,
@@ -211,8 +251,14 @@ static const struct of_device_id spm_match_table[] = {
.data = &spm_reg_8909_cpu },
{ .compatible = "qcom,msm8916-saw2-v3.0-cpu",
.data = &spm_reg_8916_cpu },
+ { .compatible = "qcom,msm8939-saw2-v3.0-cpu",
+ .data = &spm_reg_8939_cpu },
{ .compatible = "qcom,msm8974-saw2-v2.1-cpu",
.data = &spm_reg_8974_8084_cpu },
+ { .compatible = "qcom,msm8976-gold-saw2-v2.3-l2",
+ .data = &spm_reg_8976_gold_l2 },
+ { .compatible = "qcom,msm8976-silver-saw2-v2.3-l2",
+ .data = &spm_reg_8976_silver_l2 },
{ .compatible = "qcom,msm8998-gold-saw2-v4.1-l2",
.data = &spm_reg_8998_gold_l2 },
{ .compatible = "qcom,msm8998-silver-saw2-v4.1-l2",
diff --git a/include/dt-bindings/arm/qcom,ids.h b/include/dt-bindings/arm/qcom,ids.h
new file mode 100644
index 000000000000..8b1a0f43bd93
--- /dev/null
+++ b/include/dt-bindings/arm/qcom,ids.h
@@ -0,0 +1,161 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Linaro Ltd
+ * Author: Krzysztof Kozlowski <krzk@kernel.org> based on previous work of Kumar Gala.
+ */
+#ifndef _DT_BINDINGS_ARM_QCOM_IDS_H
+#define _DT_BINDINGS_ARM_QCOM_IDS_H
+
+/*
+ * The MSM chipset and hardware revision used by Qualcomm bootloaders, DTS for
+ * older chipsets (qcom,msm-id) and in socinfo driver:
+ */
+#define QCOM_ID_MSM8960 87
+#define QCOM_ID_APQ8064 109
+#define QCOM_ID_MSM8660A 122
+#define QCOM_ID_MSM8260A 123
+#define QCOM_ID_APQ8060A 124
+#define QCOM_ID_MSM8974 126
+#define QCOM_ID_MPQ8064 130
+#define QCOM_ID_MSM8960AB 138
+#define QCOM_ID_APQ8060AB 139
+#define QCOM_ID_MSM8260AB 140
+#define QCOM_ID_MSM8660AB 141
+#define QCOM_ID_MSM8626 145
+#define QCOM_ID_MSM8610 147
+#define QCOM_ID_APQ8064AB 153
+#define QCOM_ID_MSM8226 158
+#define QCOM_ID_MSM8526 159
+#define QCOM_ID_MSM8110 161
+#define QCOM_ID_MSM8210 162
+#define QCOM_ID_MSM8810 163
+#define QCOM_ID_MSM8212 164
+#define QCOM_ID_MSM8612 165
+#define QCOM_ID_MSM8112 166
+#define QCOM_ID_MSM8225Q 168
+#define QCOM_ID_MSM8625Q 169
+#define QCOM_ID_MSM8125Q 170
+#define QCOM_ID_APQ8064AA 172
+#define QCOM_ID_APQ8084 178
+#define QCOM_ID_APQ8074 184
+#define QCOM_ID_MSM8274 185
+#define QCOM_ID_MSM8674 186
+#define QCOM_ID_MSM8974PRO_AC 194
+#define QCOM_ID_MSM8126 198
+#define QCOM_ID_APQ8026 199
+#define QCOM_ID_MSM8926 200
+#define QCOM_ID_MSM8326 205
+#define QCOM_ID_MSM8916 206
+#define QCOM_ID_MSM8994 207
+#define QCOM_ID_APQ8074PRO_AA 208
+#define QCOM_ID_APQ8074PRO_AB 209
+#define QCOM_ID_APQ8074PRO_AC 210
+#define QCOM_ID_MSM8274PRO_AA 211
+#define QCOM_ID_MSM8274PRO_AB 212
+#define QCOM_ID_MSM8274PRO_AC 213
+#define QCOM_ID_MSM8674PRO_AA 214
+#define QCOM_ID_MSM8674PRO_AB 215
+#define QCOM_ID_MSM8674PRO_AC 216
+#define QCOM_ID_MSM8974PRO_AA 217
+#define QCOM_ID_MSM8974PRO_AB 218
+#define QCOM_ID_APQ8028 219
+#define QCOM_ID_MSM8128 220
+#define QCOM_ID_MSM8228 221
+#define QCOM_ID_MSM8528 222
+#define QCOM_ID_MSM8628 223
+#define QCOM_ID_MSM8928 224
+#define QCOM_ID_MSM8510 225
+#define QCOM_ID_MSM8512 226
+#define QCOM_ID_MSM8936 233
+#define QCOM_ID_MSM8939 239
+#define QCOM_ID_APQ8036 240
+#define QCOM_ID_APQ8039 241
+#define QCOM_ID_MSM8996 246
+#define QCOM_ID_APQ8016 247
+#define QCOM_ID_MSM8216 248
+#define QCOM_ID_MSM8116 249
+#define QCOM_ID_MSM8616 250
+#define QCOM_ID_MSM8992 251
+#define QCOM_ID_APQ8094 253
+#define QCOM_ID_MDM9607 290
+#define QCOM_ID_APQ8096 291
+#define QCOM_ID_MSM8998 292
+#define QCOM_ID_MSM8953 293
+#define QCOM_ID_MDM8207 296
+#define QCOM_ID_MDM9207 297
+#define QCOM_ID_MDM9307 298
+#define QCOM_ID_MDM9628 299
+#define QCOM_ID_APQ8053 304
+#define QCOM_ID_MSM8996SG 305
+#define QCOM_ID_MSM8996AU 310
+#define QCOM_ID_APQ8096AU 311
+#define QCOM_ID_APQ8096SG 312
+#define QCOM_ID_SDM660 317
+#define QCOM_ID_SDM630 318
+#define QCOM_ID_APQ8098 319
+#define QCOM_ID_SDM845 321
+#define QCOM_ID_MDM9206 322
+#define QCOM_ID_IPQ8074 323
+#define QCOM_ID_SDA660 324
+#define QCOM_ID_SDM658 325
+#define QCOM_ID_SDA658 326
+#define QCOM_ID_SDA630 327
+#define QCOM_ID_SDM450 338
+#define QCOM_ID_SDA845 341
+#define QCOM_ID_IPQ8072 342
+#define QCOM_ID_IPQ8076 343
+#define QCOM_ID_IPQ8078 344
+#define QCOM_ID_SDM636 345
+#define QCOM_ID_SDA636 346
+#define QCOM_ID_SDM632 349
+#define QCOM_ID_SDA632 350
+#define QCOM_ID_SDA450 351
+#define QCOM_ID_SM8250 356
+#define QCOM_ID_IPQ8070 375
+#define QCOM_ID_IPQ8071 376
+#define QCOM_ID_IPQ8072A 389
+#define QCOM_ID_IPQ8074A 390
+#define QCOM_ID_IPQ8076A 391
+#define QCOM_ID_IPQ8078A 392
+#define QCOM_ID_SM6125 394
+#define QCOM_ID_IPQ8070A 395
+#define QCOM_ID_IPQ8071A 396
+#define QCOM_ID_IPQ6018 402
+#define QCOM_ID_IPQ6028 403
+#define QCOM_ID_IPQ6000 421
+#define QCOM_ID_IPQ6010 422
+#define QCOM_ID_SC7180 425
+#define QCOM_ID_SM6350 434
+#define QCOM_ID_SM8350 439
+#define QCOM_ID_SC8280XP 449
+#define QCOM_ID_IPQ6005 453
+#define QCOM_ID_QRB5165 455
+#define QCOM_ID_SM8450 457
+#define QCOM_ID_SM7225 459
+#define QCOM_ID_SA8295P 460
+#define QCOM_ID_SA8540P 461
+#define QCOM_ID_SM8450_2 480
+#define QCOM_ID_SM8450_3 482
+#define QCOM_ID_SC7280 487
+#define QCOM_ID_SC7180P 495
+#define QCOM_ID_SM6375 507
+#define QCOM_ID_QRU1000 539
+#define QCOM_ID_QDU1000 545
+#define QCOM_ID_QDU1010 587
+#define QCOM_ID_QRU1032 588
+#define QCOM_ID_QRU1052 589
+#define QCOM_ID_QRU1062 590
+
+/*
+ * The board type and revision information, used by Qualcomm bootloaders and
+ * DTS for older chipsets (qcom,board-id):
+ */
+#define QCOM_BOARD_ID(a, major, minor) \
+ (((major & 0xff) << 16) | ((minor & 0xff) << 8) | QCOM_BOARD_ID_##a)
+
+#define QCOM_BOARD_ID_MTP 8
+#define QCOM_BOARD_ID_DRAGONBOARD 10
+#define QCOM_BOARD_ID_SBC 24
+
+#endif /* _DT_BINDINGS_ARM_QCOM_IDS_H */
diff --git a/include/dt-bindings/power/qcom-rpmpd.h b/include/dt-bindings/power/qcom-rpmpd.h
index f5f82dde7399..7b2e4b66419a 100644
--- a/include/dt-bindings/power/qcom-rpmpd.h
+++ b/include/dt-bindings/power/qcom-rpmpd.h
@@ -4,6 +4,16 @@
#ifndef _DT_BINDINGS_POWER_QCOM_RPMPD_H
#define _DT_BINDINGS_POWER_QCOM_RPMPD_H
+/* SDM670 Power Domain Indexes */
+#define SDM670_MX 0
+#define SDM670_MX_AO 1
+#define SDM670_CX 2
+#define SDM670_CX_AO 3
+#define SDM670_LMX 4
+#define SDM670_LCX 5
+#define SDM670_GFX 6
+#define SDM670_MSS 7
+
/* SDM845 Power Domain Indexes */
#define SDM845_EBI 0
#define SDM845_MX 1
@@ -103,6 +113,12 @@
#define SM8450_MXC_AO 11
#define SM8450_MSS 12
+/* QDU1000/QRU1000 Power Domain Indexes */
+#define QDU1000_EBI 0
+#define QDU1000_MSS 1
+#define QDU1000_CX 2
+#define QDU1000_MX 3
+
/* SC7180 Power Domain Indexes */
#define SC7180_CX 0
#define SC7180_CX_AO 1
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index ebc351698090..1cd41bdf73cf 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -17,6 +17,7 @@
#include <linux/notifier.h>
#include <linux/spinlock.h>
#include <linux/cpumask.h>
+#include <linux/time64.h>
/*
* Flags to control the behaviour of a genpd.
@@ -95,6 +96,7 @@ struct genpd_governor_data {
s64 max_off_time_ns;
bool max_off_time_changed;
ktime_t next_wakeup;
+ ktime_t next_hrtimer;
bool cached_power_down_ok;
bool cached_power_down_state_idx;
};
@@ -232,6 +234,7 @@ int dev_pm_genpd_set_performance_state(struct device *dev, unsigned int state);
int dev_pm_genpd_add_notifier(struct device *dev, struct notifier_block *nb);
int dev_pm_genpd_remove_notifier(struct device *dev);
void dev_pm_genpd_set_next_wakeup(struct device *dev, ktime_t next);
+ktime_t dev_pm_genpd_get_next_hrtimer(struct device *dev);
extern struct dev_power_governor simple_qos_governor;
extern struct dev_power_governor pm_domain_always_on_gov;
@@ -293,6 +296,10 @@ static inline int dev_pm_genpd_remove_notifier(struct device *dev)
static inline void dev_pm_genpd_set_next_wakeup(struct device *dev, ktime_t next)
{ }
+static inline ktime_t dev_pm_genpd_get_next_hrtimer(struct device *dev)
+{
+ return KTIME_MAX;
+}
#define simple_qos_governor (*(struct dev_power_governor *)(NULL))
#define pm_domain_always_on_gov (*(struct dev_power_governor *)(NULL))
#endif
diff --git a/include/soc/qcom/qcom-spmi-pmic.h b/include/soc/qcom/qcom-spmi-pmic.h
index 72398ff44719..c47cc71a999e 100644
--- a/include/soc/qcom/qcom-spmi-pmic.h
+++ b/include/soc/qcom/qcom-spmi-pmic.h
@@ -26,18 +26,29 @@
#define PM8901_SUBTYPE 0x0f
#define PM8950_SUBTYPE 0x10
#define PMI8950_SUBTYPE 0x11
+#define PMK8001_SUBTYPE 0x12
+#define PMI8996_SUBTYPE 0x13
#define PM8998_SUBTYPE 0x14
#define PMI8998_SUBTYPE 0x15
#define PM8005_SUBTYPE 0x18
-#define PM660L_SUBTYPE 0x1A
-#define PM660_SUBTYPE 0x1B
-#define PM8150_SUBTYPE 0x1E
+#define PM660L_SUBTYPE 0x1a
+#define PM660_SUBTYPE 0x1b
+#define PM8150_SUBTYPE 0x1e
#define PM8150L_SUBTYPE 0x1f
#define PM8150B_SUBTYPE 0x20
#define PMK8002_SUBTYPE 0x21
#define PM8009_SUBTYPE 0x24
+#define PMI632_SUBTYPE 0x25
#define PM8150C_SUBTYPE 0x26
+#define PM6150_SUBTYPE 0x28
#define SMB2351_SUBTYPE 0x29
+#define PM8008_SUBTYPE 0x2c
+#define PM6125_SUBTYPE 0x2d
+#define PM7250B_SUBTYPE 0x2e
+#define PMK8350_SUBTYPE 0x2f
+#define PMR735B_SUBTYPE 0x34
+#define PM6350_SUBTYPE 0x36
+#define PM2250_SUBTYPE 0x37
#define PMI8998_FAB_ID_SMIC 0x11
#define PMI8998_FAB_ID_GF 0x30